A feature with a heading column that sticks while three labelled groups of checked capabilities scroll past it, closing on a footnote under a hairline.
A feature with a heading column that sticks while three labelled groups of checked capabilities scroll past it, closing on a footnote under a hairline.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/feature264?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/feature264?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/feature264.tsx plus the badge23 and button21 components it uses for the eyebrow and the action.
The installed file exports feature264Demo alongside the block: the exact props behind the preview above. Spread it to get a working list in one line.
import { Feature264, feature264Demo } from "@/components/beste/block/feature264";
export default function Page() {
return <Feature264 {...feature264Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Feature264 } from "@/components/beste/block/feature264";
export default function Page() {
return (
<Feature264
badge={{ label: "What is included" }}
heading="The whole list, not the marketing selection"
description="Every plan ships with all of it. There is no tier where audit logging suddenly costs more."
button={{ label: "Compare plans", href: "/pricing" }}
groups={[
{
label: "Scheduling",
items: [
"Multi-site rota with room allocation",
"Automatic waiting list backfill",
"Reminders by email and text",
],
},
{
label: "Records",
items: [
"One member record across sites",
"Structured notes with templates",
"Complete change history",
],
},
]}
footnote="If something on this list turns out not to work the way you read it, tell us."
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow at the top of the sticky column |
heading | string | – | Section heading in the sticky column |
description | string | – | Supporting paragraph, capped at max-w-md |
button | { label: string; href: string } | – | Outline action under the paragraph |
groups | CapabilityGroup[] | [] | Labelled groups of checked capabilities |
footnote | string | – | Closing paragraph under the last group's hairline |
className | string | – | Extra classes for the outer section |
type ActionLink = {
label: string;
href: string;
};
type CapabilityGroup = {
label: string;
items: string[];
};lg:sticky lg:top-24 lg:self-start. The self-start is required: without it the column stretches to the full grid row height and sticky positioning has nothing to travel within, so nothing sticks.top-24 assumes a fixed header of roughly six rem. Change that value to match your own navbar height, otherwise the heading will slide under it.lg and above only. On smaller screens the heading scrolls away normally, which is what you want when the list is stacked underneath it rather than beside it.border-t pt-6 with first:border-t-0 first:pt-0, so rules appear only between groups and never above the first one.sm, filling column by column, so a five-item group leaves the gap at the bottom of the second column rather than in the middle of the list.aria-hidden and the text carries the meaning, so a screen reader hears a plain list.1fr to 2fr split, giving the list twice the width of the heading, which is what lets the items sit two-up without cramping.feature227
Sticky left intro paired with a stacked, numbered list of feature blocks, each with a title, description, and small image.
feature209
Sticky intro column beside a scrollable stack of numbered service blocks.