- {group.items.map((component) => (
-
+ {group.items.map((component) => {
+ const meta = metadata_map[component.name];
+ const storyCount = meta?.stories?.length ?? 0;
+
+ return (
-
{component.title}
-
-
-
-
+
+
+ {component.title}
+
+ {meta?.description ? (
+
+ {meta.description}
+
+ ) : null}
-
-
-
- {component.title}
-
-
-
- ))}
+
+
+ {storyCount > 0
+ ? `${storyCount} ${storyCount === 1 ? "story" : "stories"}`
+ : "No preview"}
+
+
+
+ );
+ })}
))}
diff --git a/apps/registry/components/component-preview/component-preview.tsx b/apps/registry/components/component-preview/component-preview.tsx
deleted file mode 100644
index df7c939..0000000
--- a/apps/registry/components/component-preview/component-preview.tsx
+++ /dev/null
@@ -1,1714 +0,0 @@
-"use client";
-
-import * as React from "react";
-
-import {
- Accordion,
- AccordionContent,
- AccordionItem,
- AccordionTrigger,
- Alert,
- AlertDescription,
- AlertDialog,
- AlertDialogAction,
- AlertDialogCancel,
- AlertDialogContent,
- AlertDialogDescription,
- AlertDialogFooter,
- AlertDialogHeader,
- AlertDialogTitle,
- AlertDialogTrigger,
- AlertTitle,
- AspectRatio,
- Avatar,
- AvatarFallback,
- AvatarImage,
- Badge,
- Breadcrumb,
- Button,
- Calendar,
- Callout,
- Card,
- CardContent,
- CardDescription,
- CardFooter,
- CardHeader,
- CardTitle,
- Carousel,
- CarouselContent,
- CarouselItem,
- CarouselNext,
- CarouselPrevious,
- CategoryFilter,
- Checkbox,
- Checklist,
- CodeBlock,
- CodePlayground,
- Collapsible,
- CollapsibleContent,
- CollapsibleTrigger,
- CommandDialog,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
- CommandList,
- CommonMistake,
- Comparison,
- ContentCard,
- ContextMenu,
- ContextMenuContent,
- ContextMenuItem,
- ContextMenuTrigger,
- Dialog,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogTitle,
- DialogTrigger,
- Drawer,
- DrawerClose,
- DrawerContent,
- DrawerDescription,
- DrawerFooter,
- DrawerHeader,
- DrawerTitle,
- DrawerTrigger,
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
- Exercise,
- FAQ,
- FAQItem,
- FloatingActionButton,
- Glossary,
- HorizontalScrollRow,
- HoverCard,
- HoverCardContent,
- HoverCardTrigger,
- InlineInput,
- Input,
- InputOTP,
- InputOTPGroup,
- InputOTPSlot,
- KeyboardShortcutsHelp,
- KeyConcept,
- LangProvider,
- LearningObjectives,
- Menubar,
- MenubarContent,
- MenubarItem,
- MenubarMenu,
- MenubarSeparator,
- MenubarTrigger,
- NavigationMenu,
- NavigationMenuContent,
- NavigationMenuItem,
- NavigationMenuLink,
- NavigationMenuList,
- NavigationMenuTrigger,
- Pagination,
- Popover,
- PopoverContent,
- PopoverTrigger,
- Prerequisites,
- ProfileSection,
- ProgressBar,
- ProTip,
- Quiz,
- RadioGroup,
- RadioGroupItem,
- ResizableHandle,
- ResizablePanel,
- ResizablePanelGroup,
- ScrollArea,
- SearchBar,
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
- Separator,
- ShareSection,
- Sheet,
- SheetClose,
- SheetContent,
- SheetDescription,
- SheetFooter,
- SheetHeader,
- SheetTitle,
- SheetTrigger,
- Sidebar,
- SidebarProvider,
- SidebarToggle,
- Skeleton,
- Slider,
- Spinner,
- Step,
- StepByStep,
- StepNavigation,
- Summary,
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableOfContents,
- TableRow,
- Tabs,
- TabsContent,
- TabsList,
- TabsTrigger,
- Terminal,
- Textarea,
- ThemeProvider,
- ThemeToggle,
- ThinkingBlock,
- TLDRSection,
- Toast,
- ToastDescription,
- ToastTitle,
- Toggle,
- ToggleGroup,
- ToggleGroupItem,
- Tooltip,
- TooltipContent,
- TooltipProvider,
- TooltipTrigger,
- TutorialCard,
- VideoEmbed,
- ViewSwitcher,
-} from "@vllnt/ui";
-import {
- Bold,
- ChevronsUpDown,
- Italic,
- Plus,
- Terminal as TerminalIcon,
- Underline,
-} from "lucide-react";
-
-type ComponentPreviewProps = {
- componentName: string;
-};
-
-// Simple text-based preview for components that need complex context
-function SimplePreview({ description }: { description: string }) {
- return (
-
- );
-}
-
-function ButtonPreview() {
- return (
-
-
-
-
-
-
-
-
- );
-}
-
-function BadgePreview() {
- return (
-
- Default
- Secondary
- Destructive
- Outline
-
- );
-}
-
-function CardPreview() {
- return (
-
-
- Card Title
- Card description goes here.
-
-
- Card content
-
-
-
-
-
- );
-}
-
-function InputPreview() {
- return (
-
-
-
-
- );
-}
-
-function BreadcrumbPreview() {
- return (
-
- );
-}
-
-function DropdownMenuPreview() {
- return (
-
-
-
-
-
- Profile
- Settings
- Logout
-
-
- );
-}
-
-function ToastPreview() {
- return (
-
-
- Toast Title
- Toast description goes here.
-
-
- );
-}
-
-function TLDRSectionPreview() {
- return (
-
- This is a collapsible section with a loading animation. When you first
- expand it, you'll see a shimmer effect before the content appears.
-
- );
-}
-
-function DialogPreview() {
- return (
-
- );
-}
-
-function CodeBlockPreview() {
- return (
-
- {`function greet(name: string) {
- return \`Hello, \${name}!\`
-}`}
-
- );
-}
-
-function ProfileSectionPreview() {
- return (
-
- );
-}
-
-function ThemeTogglePreview() {
- return (
-
- );
-}
-
-function LangProviderPreview() {
- return (
-
-
-
- Sets the HTML lang attribute.
-
-
- );
-}
-
-function ThemeProviderPreview() {
- return (
-
-
-
- Theme Provider wraps your app for theme support.
-
-
-
- );
-}
-
-function CommandPreview() {
- const [open, setOpen] = React.useState(false);
- return (
-
-
-
-
-
- No results found.
-
- Calendar
- Settings
-
-
-
-
- );
-}
-
-function TabsPreview() {
- return (
-
-
- Account
- Password
-
-
-
- Manage your account here.
-
-
-
-
- Change your password here.
-
-
-
- );
-}
-
-function CalloutPreview() {
- return (
-
- This is an informational callout.
- This is a warning callout.
- This is a helpful tip.
- This is a danger callout.
-
- );
-}
-
-function CheckboxPreview() {
- return (
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-function TerminalPreview() {
- return (
-
- );
-}
-
-// New real previews
-
-function FAQPreview() {
- return (
- // eslint-disable-next-line react/jsx-pascal-case -- FAQ is an acronym
-
-
- A collapsible FAQ component for displaying questions and answers.
-
-
- Wrap FAQItem components inside the FAQ component.
-
-
- );
-}
-
-function QuizPreview() {
- return (
-
Paris has been France's capital since the 12th century.
- }
- hint="It's known as the City of Light"
- options={[
- { label: "London" },
- { correct: true, label: "Paris" },
- { label: "Berlin" },
- ]}
- question="What is the capital of France?"
- />
- );
-}
-
-function ChecklistPreview() {
- return (
-
- );
-}
-
-function StepByStepPreview() {
- return (
-
- Run npm install to install dependencies.
- Set up your configuration files.
- Build your application for production.
-
- );
-}
-
-function ProTipPreview() {
- return (
-
-
- Use TypeScript for better developer experience.
-
-
Always add unique keys to list items.}
- title="Forgetting keys"
- >
- Rendering lists without keys causes issues.
-
-
- );
-}
-
-function ProgressBarPreview() {
- return (
-
- );
-}
-
-function KeyConceptPreview() {
- return (
-
-
- A reusable piece of UI that encapsulates structure and behavior.
-
-
-
- Data passed from parent to child components.
-
-
- Data that changes over time within a component.
-
-
-
- );
-}
-
-function LearningObjectivesPreview() {
- return (
-
-
-
-
- We covered the basics of React components.
-
-
- );
-}
-
-function ComparisonPreview() {
- return (
-
- );
-}
-
-function ExercisePreview() {
- return (
- const [count, setCount] = useState(0)
- }
- title="Create a Counter"
- >
- Create a component that displays and increments a number.
-
- );
-}
-
-function SidebarTogglePreview() {
- const [open, setOpen] = React.useState(false);
- return (
-
- {
- setOpen(!open);
- }}
- open={open}
- />
-
- Sidebar is {open ? "open" : "closed"}
-
-
- );
-}
-
-function ThinkingBlockPreview() {
- return (
-
- );
-}
-
-function InlineInputPreview() {
- const [value, setValue] = React.useState("Click to edit");
- return (
-
-
Click the input to edit:
-
{
- setValue(v);
- }}
- value={value}
- />
-
- );
-}
-
-function VideoEmbedPreview() {
- return (
-
-
-
- );
-}
-
-function BlogCardPreview() {
- return (
-
- );
-}
-
-function CategoryFilterPreview() {
- return (
-
- );
-}
-
-function PaginationPreview() {
- return ;
-}
-
-function SearchBarPreview() {
- return (
-
-
-
-
- }
- >
-