
Bento explaining install: a lead tile with the shadcn add command and the files it writes, beside five indexed tiles on dependencies, aliases, npm packages, tokens and runtime.
@hirael
registry/hirael/bases/radix/blocks/feature-03/feature-03.tsx
// Feature 03 from Hirael <https://hirael.com/blocks/features/feature-03>
// MIT · Mohammad Shehadeh · https://github.com/MohammadShehadeh/hirael
import type * as React from 'react';
import { cn } from '@/lib/utils';
const ENTER =
'animate-in fade-in slide-in-from-bottom-4 duration-500 ease-[cubic-bezier(0.22,1,0.36,1)] fill-mode-both motion-reduce:animate-none';
const stagger = (index: number, step = 60, offset = 0): React.CSSProperties => ({
animationDelay: `${offset + index * step}ms`,
});
const formatIndex = (index: number) => String(index + 1).padStart(2, '0');
interface Tile {
title: string;
body: string;
swatches?: boolean;
}
const TILES: readonly Tile[] = [
{
title: 'Primitives come first',
body: 'If the item needs a Button or a Popover you do not have yet, the CLI adds it from shadcn/ui before anything else.',
},
{
title: 'Imports match your aliases',
body: 'Paths are rewritten to the folders in your components.json, so nothing points at a folder you do not have.',
},
{
title: 'npm packages are listed',
body: 'Anything the item imports from npm, like lucide-react, is installed with your package manager in the same run.',
},
{
title: 'Your tokens do the styling',
body: 'Files use the CSS variables your theme already defines, so new components match on the first render.',
swatches: true,
},
{
title: 'Nothing left at runtime',
body: 'There is no Hirael package in your bundle. Delete a file and the component is gone.',
},
];
const COMMAND = 'npx shadcn add https://hirael.com/r/combobox.json';
const OUTPUT = [
{ state: 'done', text: 'Checking registry dependencies' },
{ state: 'done', text: 'Installing button, popover, command' },
{ state: 'done', text: 'Installing lucide-react' },
{ state: 'done', text: 'Created 4 files:' },
] as const;
const WRITTEN_FILES = [
'components/ui/button.tsx',
'components/ui/popover.tsx',
'components/ui/command.tsx',
'components/combobox.tsx',
] as const;
const SWATCHES = ['bg-foreground', 'bg-muted-foreground', 'bg-primary', 'bg-primary', 'bg-background'] as const;
const Feature03 = () => {
return (
<section data-slot="feature" className="bg-background py-20 sm:py-28">
<div className="mx-auto w-full max-w-6xl px-6 md:px-10">
<div data-slot="feature-header" className="flex max-w-2xl flex-col gap-5">
<span className={cn(ENTER, 'text-xs text-muted-foreground uppercase')}>How install works</span>
<h2
style={stagger(1)}
className={cn(ENTER, 'font-serif text-4xl leading-[1.04] font-medium tracking-tight sm:text-5xl')}
>
One command, a few plain files
</h2>
<p style={stagger(2)} className={cn(ENTER, 'text-base text-muted-foreground sm:text-lg')}>
Here is what the shadcn CLI does when you add a Hirael item, and what it leaves in your repo afterwards.
</p>
</div>
<div data-slot="feature-bento" className="mt-14 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-6">
<div
data-slot="feature-tile"
style={stagger(0, 60, 180)}
className={cn(
ENTER,
'relative flex flex-col justify-between gap-8 overflow-hidden rounded-xl border border-border bg-card p-6 sm:col-span-2 lg:col-span-4 lg:row-span-2',
)}
>
<div
aria-hidden
className="pointer-events-none absolute inset-0 bg-[radial-gradient(90%_70%_at_100%_0%,color-mix(in_oklch,var(--primary)_10%,transparent),transparent_60%)]"
/>
<div className="relative z-10 flex flex-col gap-2">
<span className="text-xs text-muted-foreground uppercase">Source you own</span>
<h3 className="max-w-md text-2xl leading-[1.1] font-semibold tracking-[-0.02em] sm:text-3xl">
The CLI writes TSX into your repo and steps away
</h3>
<p className="max-w-md text-sm text-muted-foreground">
You review the diff and commit it like code a teammate wrote. From then on, every edit is yours to make.
</p>
</div>
<div
data-slot="feature-terminal"
dir="ltr"
className="relative z-10 -mx-6 -mb-6 border-t border-border bg-background px-6 py-5 text-start text-xs leading-relaxed tabular-nums"
>
<p className="text-foreground">
<span className="text-muted-foreground select-none">$ </span>
{COMMAND}
</p>
<ul className="mt-3 flex flex-col text-muted-foreground">
{OUTPUT.map((line) => (
<li key={line.text} className="flex items-center gap-2">
<svg
aria-hidden
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2.5"
strokeLinecap="round"
strokeLinejoin="round"
className="size-3.5 shrink-0 text-foreground"
>
<path d="M20 6 9 17l-5-5" />
</svg>
{line.text}
</li>
))}
{WRITTEN_FILES.map((file) => (
<li key={file} className="ps-5.5 text-foreground">
- {file}
</li>
))}
</ul>
</div>
</div>
{TILES.map((tile, index) => (
<div
key={tile.title}
data-slot="feature-tile"
style={stagger(index + 1, 60, 180)}
className={cn(ENTER, 'flex flex-col gap-3 rounded-xl border border-border bg-card p-6 lg:col-span-2')}
>
<span dir="ltr" className="self-start text-xs text-muted-foreground tabular-nums">
<span className="text-foreground">{formatIndex(index)}</span>
<span className="mx-1.5 text-border">|</span>
{formatIndex(TILES.length - 1)}
</span>
<div className="flex flex-col gap-1.5">
<h3 className="text-base font-semibold tracking-[-0.01em]">{tile.title}</h3>
<p className="text-sm text-pretty text-muted-foreground">{tile.body}</p>
</div>
{tile.swatches ? (
<div aria-hidden className="mt-auto flex items-center gap-1.5 pt-2">
{SWATCHES.map((swatch) => (
<span key={swatch} className={cn('size-5 rounded-md border border-border', swatch)} />
))}
</div>
) : null}
</div>
))}
</div>
</div>
</section>
);
};
export default Feature03;


























