Accordion on the left, swappable media surface on the right. Each row picks its own media kind: image, video, or live registry-component asset.
Two-column feature section: a single-open shadcn Accordion of capability rows on the left, and a media surface on the right that swaps to show whichever row is currently expanded. Each row's media slot follows the Media Slot Standard, so it can hold a static image, a looping video, or a live registry-piece asset rendered inline.
Free block
This block is free. No license or account is required: install it with the CLI and use it in unlimited projects.
Radix flavor
npx shadcn add "https://ui.beste.co/r/feature1"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/feature1"This installs the block to components/beste/block/feature1.tsx, the shadcn/ui accordion and badge components it depends on, and the ai43, automation1, automation2, automation8, and automation10 pieces it embeds as media-slot fillers (installed to components/beste/piece/{name}.tsx).
The installed file exports feature1Demo alongside the block: the exact props behind the preview above. Spread it to get a working accordion-with-media section in one line.
import { Feature1, feature1Demo } from "@/components/beste/block/feature1";
export default function Page() {
return <Feature1 {...feature1Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup mixing an image row and a live-asset row looks like this:
import { Automation1 } from "@/components/beste/piece/automation1";
import { Feature1 } from "@/components/beste/block/feature1";
export default function Page() {
return (
<Feature1
badge={{ label: "Automations", variant: "secondary" }}
heading="Pick a capability, see the surface"
description="Open any row to expand its story."
features={[
{
title: "See the finished layout",
description: "A static preview of the dashboard your team ships to.",
media: {
type: "image",
src: "https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=1200&h=900&fit=crop",
alt: "Analytics dashboard on a laptop",
},
},
{
title: "Trigger meets action, in one tile",
description: "Two apps, two events, an arrow tells the story.",
media: {
type: "component",
component: (
<Automation1
trigger={{ src: "https://oud.pics/sm/l/stripe.jpeg", alt: "Stripe", event: "Payment received" }}
action={{ src: "https://oud.pics/sm/l/slack.svg", alt: "Slack", event: "Send #revenue alert" }}
/>
),
},
},
]}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string; variant?: "default" | "secondary" | "outline" } | – | Badge above the heading |
heading | string | – | Section heading |
description | string | – | Section intro text |
features | FeatureItem[] | [] | Accordion rows; each pairs a title/description with a media slot |
className | string | – | Extra classes for the outer <section> |
type FeatureItem = {
title: string;
description: string;
media: FeatureMedia;
};
type FeatureMedia =
| { type: "image"; src: string; alt?: string }
| { type: "video"; src: string; alt?: string }
| {
type: "component";
component: React.ReactNode;
background?: ComponentBackground;
};
type ComponentBackground =
| { type: "dots" }
| { type: "none" }
| { type: "image"; src: string; alt?: string }
| { type: "video"; src: string; alt?: string };item-0 by default and local activeIndex state starts at 0, so the first row and its media are visible before any interaction.onValueChange parses the numeric index out of the accordion's item-N value string to update activeIndex. Collapsing the open item drives value to an empty string, which the handler's if (!value) return; guard ignores, so the right-side media keeps showing the last opened row instead of clearing when a row is collapsed.hidden md:block. Below md, each row instead renders its own copy of the media inline inside its AccordionContent (mt-4 md:hidden), so the same media element has two separate render paths depending on breakpoint.component media variant to embed automation and AI pieces; the image/video variants are supported by the FeatureMedia type but not exercised by the shipped demo data.feature229
Interactive feature section with an eyebrow, big heading and description above a two-column layout: a single-collapsible accordion of feature items on the left and a sticky image on the right that swaps to the active item's image on click.
feature2
Hero header with a CTA, then alternating image-left / image-right rows. Each row's media slot accepts an image, video, or live registry-component asset.
feature208
Horizontal expanding accordion of services with vertical labels, expanding to reveal image, description and tag pills.
feature53
Expandable accordion sections with category headers and checkmark-style feature lists in a two-column grid. Perfect for organized feature overviews and pricing page inclusions.