harebear-ui 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/AGENTS.md +19 -2
  2. package/README.md +108 -36
  3. package/bin/harebear-ui.mjs +66 -3
  4. package/dist/components/admin/status.d.ts +3 -1
  5. package/dist/components/admin/status.js +5 -2
  6. package/dist/components/ai/approval.d.ts +3 -1
  7. package/dist/components/ai/approval.js +6 -3
  8. package/dist/components/ai/chat.d.ts +5 -2
  9. package/dist/components/ai/chat.js +1 -1
  10. package/dist/components/ai/code-block.d.ts +5 -1
  11. package/dist/components/ai/code-block.js +5 -3
  12. package/dist/components/ai/conversation-list.d.ts +16 -2
  13. package/dist/components/ai/conversation-list.js +88 -37
  14. package/dist/components/ai/model-picker.d.ts +6 -1
  15. package/dist/components/ai/model-picker.js +43 -23
  16. package/dist/components/layout/media-item.d.ts +13 -0
  17. package/dist/components/layout/media-item.js +54 -0
  18. package/dist/components/layout/metric.d.ts +15 -0
  19. package/dist/components/layout/metric.js +51 -0
  20. package/dist/components/layout/show-more.d.ts +17 -0
  21. package/dist/components/layout/show-more.js +30 -0
  22. package/dist/components/layout/stack.d.ts +39 -0
  23. package/dist/components/layout/stack.js +114 -0
  24. package/dist/components/layout/text.d.ts +37 -0
  25. package/dist/components/layout/text.js +52 -0
  26. package/dist/components/theme/theme-toggle.d.ts +4 -1
  27. package/dist/components/theme/theme-toggle.js +11 -6
  28. package/dist/components/ui/badge.d.ts +4 -1
  29. package/dist/components/ui/badge.js +10 -1
  30. package/dist/components/ui/button.d.ts +3 -1
  31. package/dist/components/ui/button.js +13 -3
  32. package/dist/components/ui/empty.d.ts +4 -1
  33. package/dist/components/ui/empty.js +3 -2
  34. package/dist/components/ui/item.d.ts +4 -1
  35. package/dist/components/ui/item.js +7 -2
  36. package/dist/index.d.ts +8 -3
  37. package/dist/index.js +7 -2
  38. package/docs/COMPONENTS.md +96 -71
  39. package/docs/guides/agents.md +75 -0
  40. package/docs/guides/getting-started.md +217 -0
  41. package/docs/guides/theming.md +98 -0
  42. package/llms.txt +6 -1
  43. package/package.json +2 -1
  44. package/skills/harebear-ui/SKILL.md +1 -1
@@ -38,70 +38,70 @@ Full working screens that combine these live in the repo under `playground/scree
38
38
 
39
39
  Every component in the shadcn registry is included. (shadcn's `form` item is an empty placeholder in the `radix-nova` style; use `Field`.) These are the shadcn/ui `radix-nova` components, restyled to the harebear tokens. API docs: https://ui.shadcn.com/docs/components. harebear-specific changes are noted.
40
40
 
41
- | Family | Exports | harebear notes |
42
- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
43
- | Accordion | `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` | |
44
- | Alert | `Alert`, `AlertTitle`, `AlertDescription`, `AlertAction` | harebear adds `variant` `warning`, `success`, `info` (tinted, borderless). Descriptions wrap long words. |
45
- | Alert dialog | `AlertDialog`, `AlertDialogTrigger`, `AlertDialogContent`, `AlertDialogHeader`, `AlertDialogFooter`, `AlertDialogTitle`, `AlertDialogDescription`, `AlertDialogAction`, `AlertDialogCancel`, `AlertDialogMedia`, `AlertDialogOverlay`, `AlertDialogPortal` | Use for destructive confirmations. |
46
- | Aspect ratio | `AspectRatio` | |
47
- | Attachment | `Attachment`, `AttachmentGroup`, `AttachmentMedia`, `AttachmentContent`, `AttachmentTitle`, `AttachmentDescription`, `AttachmentActions`, `AttachmentAction`, `AttachmentTrigger` | File/image chips on messages and composers. `size`: `default`, `sm`, `xs`; `orientation`: `horizontal`, `vertical`. |
48
- | Avatar | `Avatar`, `AvatarImage`, `AvatarFallback`, `AvatarGroup`, `AvatarGroupCount`, `AvatarBadge` | `size`: `sm` 28px, `default` 36px, `lg` 56px. Fallback is tinted initials. |
49
- | Badge | `Badge`, `badgeVariants` | 24px pill. `variant`: `default` (primary), `secondary` (neutral, the common one), `soft` (tinted primary), `outline`, `success`, `warning`, `destructive`, `ghost`, `link`. harebear adds `size="lg"` (32px, lines up with sm buttons). |
50
- | Bubble | `Bubble`, `BubbleGroup`, `BubbleContent`, `BubbleReactions` | Chat bubble. `variant`: `default` (primary), `secondary`, `muted`, `tinted`, `outline`, `ghost`, `destructive`; `align`: `start`, `end`. |
51
- | Breadcrumb | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` | |
52
- | Button | `Button`, `buttonVariants` | 40px default. `variant`: `default`, `secondary`, `outline`, `ghost`, `soft`, `dashed`, `destructive`, `link`. `size`: `xs`, `sm` (32px), `default`, `lg`, `icon`, `icon-xs`, `icon-sm`, `icon-lg`. `shape`: `default`, `pill`. Icon-only buttons need `aria-label`. |
53
- | Button group | `ButtonGroup`, `ButtonGroupSeparator`, `ButtonGroupText`, `buttonGroupVariants` | |
54
- | Calendar | `Calendar`, `CalendarDayButton` | react-day-picker v10. Combine with `Popover` for a date picker. |
55
- | Card | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter` | Bordered, elevated (`shadow-card`), `rounded-xl`, 24px padding. `size="sm"` for 16px. `CardAction` puts a control top-right of the header. |
56
- | Code block | `CodeBlock`, `CodeBlockHeader`, `CodeBlockTitle`, `CodeBlockActions`, `CodeBlockCopyButton`, `CodeBlockContent`, `CodeBlockLine`, `CodeBlockFooter` | Composable code panel (muted fill). `CodeBlockContent` takes `lineNumbers`, `wrap`, `startLine`; `CodeBlockLine variant`: `added`, `removed`, `highlighted`. Pair with `useHighlightedCode` for shiki, or use `CodeSnippet`. |
57
- | Carousel | `Carousel`, `CarouselContent`, `CarouselItem`, `CarouselPrevious`, `CarouselNext`, `useCarousel`, type `CarouselApi` | embla. |
58
- | Chart | `ChartContainer`, `ChartTooltip`, `ChartTooltipContent`, `ChartLegend`, `ChartLegendContent`, `ChartStyle` | Recharts wrappers. Prefer `TrendChart` for line/area; use these for custom charts. |
59
- | Checkbox | `Checkbox` | |
60
- | Collapsible | `Collapsible`, `CollapsibleTrigger`, `CollapsibleContent` | |
61
- | Combobox | `Combobox`, `ComboboxInput`, `ComboboxContent`, `ComboboxList`, `ComboboxItem`, `ComboboxGroup`, `ComboboxLabel`, `ComboboxCollection`, `ComboboxEmpty`, `ComboboxSeparator`, `ComboboxChips`, `ComboboxChip`, `ComboboxChipsInput`, `ComboboxTrigger`, `ComboboxValue`, `useComboboxAnchor` | Searchable select (Base UI). `<Combobox items={list}>` + `<ComboboxList>{(item) => <ComboboxItem value={item}>…}</ComboboxList>`. Chips for multi-select. |
62
- | Command | `Command`, `CommandDialog`, `CommandInput`, `CommandList`, `CommandEmpty`, `CommandGroup`, `CommandItem`, `CommandShortcut`, `CommandSeparator` | Use for ⌘K palettes. |
63
- | Direction | `DirectionProvider`, `useDirection` | RTL/LTR context for Radix components. |
64
- | Context menu | `ContextMenu`, `ContextMenuTrigger`, `ContextMenuContent`, `ContextMenuItem`, `ContextMenuCheckboxItem`, `ContextMenuRadioItem`, `ContextMenuRadioGroup`, `ContextMenuLabel`, `ContextMenuSeparator`, `ContextMenuShortcut`, `ContextMenuGroup`, `ContextMenuPortal`, `ContextMenuSub`, `ContextMenuSubContent`, `ContextMenuSubTrigger` | |
65
- | Dialog | `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter`, `DialogTitle`, `DialogDescription`, `DialogClose`, `DialogOverlay`, `DialogPortal` | |
66
- | Drawer | `Drawer`, `DrawerTrigger`, `DrawerContent`, `DrawerHeader`, `DrawerFooter`, `DrawerTitle`, `DrawerDescription`, `DrawerClose`, `DrawerOverlay`, `DrawerPortal` | vaul. Mobile bottom sheets. |
67
- | Dropdown menu | `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`, `DropdownMenuItem`, `DropdownMenuCheckboxItem`, `DropdownMenuRadioGroup`, `DropdownMenuRadioItem`, `DropdownMenuLabel`, `DropdownMenuSeparator`, `DropdownMenuShortcut`, `DropdownMenuGroup`, `DropdownMenuPortal`, `DropdownMenuSub`, `DropdownMenuSubTrigger`, `DropdownMenuSubContent` | |
68
- | Empty state | `Empty`, `EmptyHeader`, `EmptyMedia`, `EmptyTitle`, `EmptyDescription`, `EmptyContent` | Use for zero-data screens. |
69
- | Field | `Field`, `FieldLabel`, `FieldDescription`, `FieldError`, `FieldGroup`, `FieldLegend`, `FieldSeparator`, `FieldSet`, `FieldContent`, `FieldTitle` | Form layout. Works with react-hook-form or plain state. |
70
- | Hover card | `HoverCard`, `HoverCardTrigger`, `HoverCardContent` | |
71
- | Input | `Input` | 40px, filled `bg-muted`, turns `bg-card` with a primary ring on focus. |
72
- | Input group | `InputGroup`, `InputGroupAddon`, `InputGroupButton`, `InputGroupText`, `InputGroupInput`, `InputGroupTextarea` | Inputs with icons, prefixes, buttons. |
73
- | Input OTP | `InputOTP`, `InputOTPGroup`, `InputOTPSlot`, `InputOTPSeparator` | |
74
- | Item | `Item`, `ItemMedia`, `ItemContent`, `ItemTitle`, `ItemDescription`, `ItemActions`, `ItemGroup`, `ItemSeparator`, `ItemHeader`, `ItemFooter` | Generic list rows. harebear fix: `ItemTitle` clamps to one line (long words break), `ItemContent` has `min-w-0`. |
75
- | Kbd | `Kbd`, `KbdGroup` | Mono keycap. |
76
- | Marker | `Marker`, `MarkerIcon`, `MarkerContent`, `markerVariants` | Inline status line in a thread ("Conversation saved"). `variant`: `default`, `separator` (date dividers), `border`. |
77
- | Label | `Label` | |
78
- | Menubar | `Menubar`, `MenubarMenu`, `MenubarTrigger`, `MenubarContent`, `MenubarItem`, `MenubarCheckboxItem`, `MenubarRadioGroup`, `MenubarRadioItem`, `MenubarLabel`, `MenubarSeparator`, `MenubarShortcut`, `MenubarGroup`, `MenubarPortal`, `MenubarSub`, `MenubarSubTrigger`, `MenubarSubContent` | |
79
- | Message | `Message`, `MessageGroup`, `MessageAvatar`, `MessageContent`, `MessageHeader`, `MessageFooter` | Chat message layout primitive. `align`: `start`, `end`. Put `Bubble`s inside `MessageContent`. |
80
- | Message scroller | `MessageScrollerProvider`, `MessageScroller`, `MessageScrollerViewport`, `MessageScrollerContent`, `MessageScrollerItem`, `MessageScrollerButton`, `useMessageScroller`, `useMessageScrollerScrollable`, `useMessageScrollerVisibility` | Stick-to-bottom scroll container with a jump-to-latest button. `ChatThread` is the simpler alternative. |
81
- | Navigation menu | `NavigationMenu`, `NavigationMenuList`, `NavigationMenuItem`, `NavigationMenuTrigger`, `NavigationMenuContent`, `NavigationMenuLink`, `NavigationMenuIndicator`, `NavigationMenuViewport`, `navigationMenuTriggerStyle` | Marketing-style top nav. |
82
- | Native select | `NativeSelect`, `NativeSelectOption`, `NativeSelectOptGroup` | Styled `<select>`; same filled look as `Input`. Use on mobile-heavy forms. |
83
- | Pagination | `Pagination`, `PaginationContent`, `PaginationItem`, `PaginationLink`, `PaginationPrevious`, `PaginationNext`, `PaginationEllipsis` | `DataTable` has its own pager. |
84
- | Popover | `Popover`, `PopoverTrigger`, `PopoverContent`, `PopoverAnchor`, `PopoverHeader`, `PopoverTitle`, `PopoverDescription` | |
85
- | Progress | `Progress` | 8px rounded meter. `UsageMeter` adds a label row. |
86
- | Questionnaire | `Questionnaire`, `QuestionnaireProgress`, `QuestionnaireItem`, `QuestionnaireTitle`, `QuestionnaireDescription`, `QuestionnaireChoices`, `QuestionnaireChoice`, `QuestionnaireChoiceDescription`, `QuestionnaireInput`, `QuestionnaireError`, `QuestionnaireActions`, `QuestionnairePrevious`, `QuestionnaireNext`, `QuestionnaireSkip`, `QuestionnaireSubmit` | Step-by-step multiple choice or input, one question at a time (e.g. an agent asking clarifying questions). `Questionnaire items={[{ name, required }]}`, each `QuestionnaireItem name` matches. |
87
- | Radio group | `RadioGroup`, `RadioGroupItem` | |
88
- | Resizable | `ResizablePanelGroup`, `ResizablePanel`, `ResizableHandle` | |
89
- | Scroll area | `ScrollArea`, `ScrollBar` | |
90
- | Select | `Select`, `SelectTrigger`, `SelectValue`, `SelectContent`, `SelectItem`, `SelectGroup`, `SelectLabel`, `SelectSeparator`, `SelectScrollUpButton`, `SelectScrollDownButton` | |
91
- | Separator | `Separator` | |
92
- | Sheet | `Sheet`, `SheetTrigger`, `SheetContent`, `SheetHeader`, `SheetFooter`, `SheetTitle`, `SheetDescription`, `SheetClose` | Side panels. |
93
- | Sidebar | `SidebarProvider`, `Sidebar`, `SidebarHeader`, `SidebarContent`, `SidebarFooter`, `SidebarGroup`, `SidebarGroupLabel`, `SidebarGroupAction`, `SidebarGroupContent`, `SidebarMenu`, `SidebarMenuItem`, `SidebarMenuButton`, `SidebarMenuAction`, `SidebarMenuBadge`, `SidebarMenuSkeleton`, `SidebarMenuSub`, `SidebarMenuSubItem`, `SidebarMenuSubButton`, `SidebarInput`, `SidebarInset`, `SidebarRail`, `SidebarSeparator`, `SidebarTrigger`, `useSidebar` | Active item is a raised card. Prefer `AppShell` unless you need a custom layout. harebear: no border by default (add `border-r` if you want one); in `collapsible="icon"` the content keeps its width while the rail widens. `useSidebarOptional()` returns null outside a provider. |
94
- | Skeleton | `Skeleton` | Loading placeholders. |
95
- | Slider | `Slider` | |
96
- | Spinner | `Spinner` | |
97
- | Switch | `Switch` | |
98
- | Table | `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption` | Borderless rows with rounded hover; quiet 12px headers. `data-state="selected"` tints a row. |
99
- | Tabs | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`, `tabsListVariants` | `TabsList variant`: `default` (segmented control), `pill` (rounded top-level nav), `line`. Use `Tabs` as a segmented filter too (date ranges, status filters). |
100
- | Textarea | `Textarea` | Same filled style as `Input`, auto-grows. |
101
- | Toast | `Toaster` | sonner. Mount once; call `toast("Saved")` from `sonner`. Follows the theme mode. |
102
- | Toggle | `Toggle`, `toggleVariants`, `ToggleGroup`, `ToggleGroupItem` | |
103
- | Tooltip | `TooltipProvider`, `Tooltip`, `TooltipTrigger`, `TooltipContent` | Mount `TooltipProvider` once near the root. |
104
- | Trace | `Trace`, `TraceLine`, `TraceIcon`, `TraceTitle`, `TraceDescription`, `TraceCollapsible`, `TraceCollapsibleTrigger`, `TraceCollapsibleContent` | Agent step log (searched, read, ran). `TraceLine status`: `running` (shimmer), `error`, `pending`. |
41
+ | Family | Exports | harebear notes |
42
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
43
+ | Accordion | `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` | |
44
+ | Alert | `Alert`, `AlertTitle`, `AlertDescription`, `AlertAction` | harebear adds `variant` `warning`, `success`, `info` (tinted, borderless). Descriptions wrap long words. |
45
+ | Alert dialog | `AlertDialog`, `AlertDialogTrigger`, `AlertDialogContent`, `AlertDialogHeader`, `AlertDialogFooter`, `AlertDialogTitle`, `AlertDialogDescription`, `AlertDialogAction`, `AlertDialogCancel`, `AlertDialogMedia`, `AlertDialogOverlay`, `AlertDialogPortal` | Use for destructive confirmations. |
46
+ | Aspect ratio | `AspectRatio` | |
47
+ | Attachment | `Attachment`, `AttachmentGroup`, `AttachmentMedia`, `AttachmentContent`, `AttachmentTitle`, `AttachmentDescription`, `AttachmentActions`, `AttachmentAction`, `AttachmentTrigger` | File/image chips on messages and composers. `size`: `default`, `sm`, `xs`; `orientation`: `horizontal`, `vertical`. |
48
+ | Avatar | `Avatar`, `AvatarImage`, `AvatarFallback`, `AvatarGroup`, `AvatarGroupCount`, `AvatarBadge` | `size`: `sm` 28px, `default` 36px, `lg` 56px. Fallback is tinted initials. |
49
+ | Badge | `Badge`, `badgeVariants` | 24px pill. `variant`: `default` (primary), `secondary` (neutral, the common one), `soft` (tinted primary), `outline`, `success`, `warning`, `destructive`, `ghost`, `link`. harebear adds `size="lg"` (32px, lines up with sm buttons) and `tone` (`success \| warning \| danger \| info \| neutral`, the StatusBadge words; wins over `variant`). |
50
+ | Bubble | `Bubble`, `BubbleGroup`, `BubbleContent`, `BubbleReactions` | Chat bubble. `variant`: `default` (primary), `secondary`, `muted`, `tinted`, `outline`, `ghost`, `destructive`; `align`: `start`, `end`. |
51
+ | Breadcrumb | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` | |
52
+ | Button | `Button`, `buttonVariants` | 40px default. `variant`: `default`, `secondary`, `outline`, `ghost`, `soft`, `dashed`, `destructive`, `link`. `size`: `xs`, `sm` (32px), `default`, `lg`, `icon`, `icon-xs`, `icon-sm`, `icon-lg`. `shape`: `default`, `pill`. harebear adds `loading` (spinner, disabled, `aria-busy`; icon buttons swap the icon for the spinner). Icon-only buttons need `aria-label`. |
53
+ | Button group | `ButtonGroup`, `ButtonGroupSeparator`, `ButtonGroupText`, `buttonGroupVariants` | |
54
+ | Calendar | `Calendar`, `CalendarDayButton` | react-day-picker v10. Combine with `Popover` for a date picker. |
55
+ | Card | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter` | Bordered, elevated (`shadow-card`), `rounded-xl`, 24px padding. `size="sm"` for 16px. `CardAction` puts a control top-right of the header. |
56
+ | Code block | `CodeBlock`, `CodeBlockHeader`, `CodeBlockTitle`, `CodeBlockActions`, `CodeBlockCopyButton`, `CodeBlockContent`, `CodeBlockLine`, `CodeBlockFooter` | Composable code panel (muted fill). `CodeBlockContent` takes `lineNumbers`, `wrap`, `startLine`; `CodeBlockLine variant`: `added`, `removed`, `highlighted`. Pair with `useHighlightedCode` for shiki, or use `CodeSnippet`. |
57
+ | Carousel | `Carousel`, `CarouselContent`, `CarouselItem`, `CarouselPrevious`, `CarouselNext`, `useCarousel`, type `CarouselApi` | embla. |
58
+ | Chart | `ChartContainer`, `ChartTooltip`, `ChartTooltipContent`, `ChartLegend`, `ChartLegendContent`, `ChartStyle` | Recharts wrappers. Prefer `TrendChart` for line/area; use these for custom charts. |
59
+ | Checkbox | `Checkbox` | |
60
+ | Collapsible | `Collapsible`, `CollapsibleTrigger`, `CollapsibleContent` | |
61
+ | Combobox | `Combobox`, `ComboboxInput`, `ComboboxContent`, `ComboboxList`, `ComboboxItem`, `ComboboxGroup`, `ComboboxLabel`, `ComboboxCollection`, `ComboboxEmpty`, `ComboboxSeparator`, `ComboboxChips`, `ComboboxChip`, `ComboboxChipsInput`, `ComboboxTrigger`, `ComboboxValue`, `useComboboxAnchor` | Searchable select (Base UI). `<Combobox items={list}>` + `<ComboboxList>{(item) => <ComboboxItem value={item}>…}</ComboboxList>`. Chips for multi-select. |
62
+ | Command | `Command`, `CommandDialog`, `CommandInput`, `CommandList`, `CommandEmpty`, `CommandGroup`, `CommandItem`, `CommandShortcut`, `CommandSeparator` | Use for ⌘K palettes. |
63
+ | Direction | `DirectionProvider`, `useDirection` | RTL/LTR context for Radix components. |
64
+ | Context menu | `ContextMenu`, `ContextMenuTrigger`, `ContextMenuContent`, `ContextMenuItem`, `ContextMenuCheckboxItem`, `ContextMenuRadioItem`, `ContextMenuRadioGroup`, `ContextMenuLabel`, `ContextMenuSeparator`, `ContextMenuShortcut`, `ContextMenuGroup`, `ContextMenuPortal`, `ContextMenuSub`, `ContextMenuSubContent`, `ContextMenuSubTrigger` | |
65
+ | Dialog | `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter`, `DialogTitle`, `DialogDescription`, `DialogClose`, `DialogOverlay`, `DialogPortal` | |
66
+ | Drawer | `Drawer`, `DrawerTrigger`, `DrawerContent`, `DrawerHeader`, `DrawerFooter`, `DrawerTitle`, `DrawerDescription`, `DrawerClose`, `DrawerOverlay`, `DrawerPortal` | vaul. Mobile bottom sheets. |
67
+ | Dropdown menu | `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`, `DropdownMenuItem`, `DropdownMenuCheckboxItem`, `DropdownMenuRadioGroup`, `DropdownMenuRadioItem`, `DropdownMenuLabel`, `DropdownMenuSeparator`, `DropdownMenuShortcut`, `DropdownMenuGroup`, `DropdownMenuPortal`, `DropdownMenuSub`, `DropdownMenuSubTrigger`, `DropdownMenuSubContent` | |
68
+ | Empty state | `Empty`, `EmptyHeader`, `EmptyMedia`, `EmptyTitle`, `EmptyDescription`, `EmptyContent` | Use for zero-data screens. harebear adds `size="sm"`: compact, no flex-grow, for empties inside cards and panels. |
69
+ | Field | `Field`, `FieldLabel`, `FieldDescription`, `FieldError`, `FieldGroup`, `FieldLegend`, `FieldSeparator`, `FieldSet`, `FieldContent`, `FieldTitle` | Form layout. Works with react-hook-form or plain state. |
70
+ | Hover card | `HoverCard`, `HoverCardTrigger`, `HoverCardContent` | |
71
+ | Input | `Input` | 40px, filled `bg-muted`, turns `bg-card` with a primary ring on focus. |
72
+ | Input group | `InputGroup`, `InputGroupAddon`, `InputGroupButton`, `InputGroupText`, `InputGroupInput`, `InputGroupTextarea` | Inputs with icons, prefixes, buttons. |
73
+ | Input OTP | `InputOTP`, `InputOTPGroup`, `InputOTPSlot`, `InputOTPSeparator` | |
74
+ | Item | `Item`, `ItemMedia`, `ItemContent`, `ItemTitle`, `ItemDescription`, `ItemActions`, `ItemGroup`, `ItemSeparator`, `ItemHeader`, `ItemFooter` | Generic list rows. harebear fix: `ItemTitle` clamps to one line (long words break) and shows the full text as a tooltip when clamped, `ItemContent` has `min-w-0`. harebear adds `ItemTitle mono` for commands, paths and IDs. |
75
+ | Kbd | `Kbd`, `KbdGroup` | Mono keycap. |
76
+ | Marker | `Marker`, `MarkerIcon`, `MarkerContent`, `markerVariants` | Inline status line in a thread ("Conversation saved"). `variant`: `default`, `separator` (date dividers), `border`. |
77
+ | Label | `Label` | |
78
+ | Menubar | `Menubar`, `MenubarMenu`, `MenubarTrigger`, `MenubarContent`, `MenubarItem`, `MenubarCheckboxItem`, `MenubarRadioGroup`, `MenubarRadioItem`, `MenubarLabel`, `MenubarSeparator`, `MenubarShortcut`, `MenubarGroup`, `MenubarPortal`, `MenubarSub`, `MenubarSubTrigger`, `MenubarSubContent` | |
79
+ | Message | `Message`, `MessageGroup`, `MessageAvatar`, `MessageContent`, `MessageHeader`, `MessageFooter` | Chat message layout primitive. `align`: `start`, `end`. Put `Bubble`s inside `MessageContent`. |
80
+ | Message scroller | `MessageScrollerProvider`, `MessageScroller`, `MessageScrollerViewport`, `MessageScrollerContent`, `MessageScrollerItem`, `MessageScrollerButton`, `useMessageScroller`, `useMessageScrollerScrollable`, `useMessageScrollerVisibility` | Stick-to-bottom scroll container with a jump-to-latest button. `ChatThread` is the simpler alternative. |
81
+ | Navigation menu | `NavigationMenu`, `NavigationMenuList`, `NavigationMenuItem`, `NavigationMenuTrigger`, `NavigationMenuContent`, `NavigationMenuLink`, `NavigationMenuIndicator`, `NavigationMenuViewport`, `navigationMenuTriggerStyle` | Marketing-style top nav. |
82
+ | Native select | `NativeSelect`, `NativeSelectOption`, `NativeSelectOptGroup` | Styled `<select>`; same filled look as `Input`. Use on mobile-heavy forms. |
83
+ | Pagination | `Pagination`, `PaginationContent`, `PaginationItem`, `PaginationLink`, `PaginationPrevious`, `PaginationNext`, `PaginationEllipsis` | `DataTable` has its own pager. |
84
+ | Popover | `Popover`, `PopoverTrigger`, `PopoverContent`, `PopoverAnchor`, `PopoverHeader`, `PopoverTitle`, `PopoverDescription` | |
85
+ | Progress | `Progress` | 8px rounded meter. `UsageMeter` adds a label row. |
86
+ | Questionnaire | `Questionnaire`, `QuestionnaireProgress`, `QuestionnaireItem`, `QuestionnaireTitle`, `QuestionnaireDescription`, `QuestionnaireChoices`, `QuestionnaireChoice`, `QuestionnaireChoiceDescription`, `QuestionnaireInput`, `QuestionnaireError`, `QuestionnaireActions`, `QuestionnairePrevious`, `QuestionnaireNext`, `QuestionnaireSkip`, `QuestionnaireSubmit` | Step-by-step multiple choice or input, one question at a time (e.g. an agent asking clarifying questions). `Questionnaire items={[{ name, required }]}`, each `QuestionnaireItem name` matches. |
87
+ | Radio group | `RadioGroup`, `RadioGroupItem` | |
88
+ | Resizable | `ResizablePanelGroup`, `ResizablePanel`, `ResizableHandle` | |
89
+ | Scroll area | `ScrollArea`, `ScrollBar` | |
90
+ | Select | `Select`, `SelectTrigger`, `SelectValue`, `SelectContent`, `SelectItem`, `SelectGroup`, `SelectLabel`, `SelectSeparator`, `SelectScrollUpButton`, `SelectScrollDownButton` | |
91
+ | Separator | `Separator` | |
92
+ | Sheet | `Sheet`, `SheetTrigger`, `SheetContent`, `SheetHeader`, `SheetFooter`, `SheetTitle`, `SheetDescription`, `SheetClose` | Side panels. |
93
+ | Sidebar | `SidebarProvider`, `Sidebar`, `SidebarHeader`, `SidebarContent`, `SidebarFooter`, `SidebarGroup`, `SidebarGroupLabel`, `SidebarGroupAction`, `SidebarGroupContent`, `SidebarMenu`, `SidebarMenuItem`, `SidebarMenuButton`, `SidebarMenuAction`, `SidebarMenuBadge`, `SidebarMenuSkeleton`, `SidebarMenuSub`, `SidebarMenuSubItem`, `SidebarMenuSubButton`, `SidebarInput`, `SidebarInset`, `SidebarRail`, `SidebarSeparator`, `SidebarTrigger`, `useSidebar` | Active item is a raised card. Prefer `AppShell` unless you need a custom layout. harebear: no border by default (add `border-r` if you want one); in `collapsible="icon"` the content keeps its width while the rail widens. `useSidebarOptional()` returns null outside a provider. |
94
+ | Skeleton | `Skeleton` | Loading placeholders. |
95
+ | Slider | `Slider` | |
96
+ | Spinner | `Spinner` | |
97
+ | Switch | `Switch` | |
98
+ | Table | `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption` | Borderless rows with rounded hover; quiet 12px headers. `data-state="selected"` tints a row. |
99
+ | Tabs | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`, `tabsListVariants` | `TabsList variant`: `default` (segmented control), `pill` (rounded top-level nav), `line`. Use `Tabs` as a segmented filter too (date ranges, status filters). |
100
+ | Textarea | `Textarea` | Same filled style as `Input`, auto-grows. |
101
+ | Toast | `Toaster` | sonner. Mount once; call `toast("Saved")` from `sonner`. Follows the theme mode. |
102
+ | Toggle | `Toggle`, `toggleVariants`, `ToggleGroup`, `ToggleGroupItem` | |
103
+ | Tooltip | `TooltipProvider`, `Tooltip`, `TooltipTrigger`, `TooltipContent` | Mount `TooltipProvider` once near the root. |
104
+ | Trace | `Trace`, `TraceLine`, `TraceIcon`, `TraceTitle`, `TraceDescription`, `TraceCollapsible`, `TraceCollapsibleTrigger`, `TraceCollapsibleContent` | Agent step log (searched, read, ran). `TraceLine status`: `running` (shimmer), `error`, `pending`. |
105
105
 
106
106
  ## Admin and layout
107
107
 
@@ -191,7 +191,7 @@ Search field with icon. Props: all `<input>` props, `shortcut?` (display-only ke
191
191
 
192
192
  ### `StatusDot`, `StatusBadge`
193
193
 
194
- Dot or pill for status. Prop `tone`: `success | warning | danger | info | neutral`; `pulse` animates the dot for live states. `StatusBadge` takes Badge props (`variant="outline"` for a white pill, `size="lg"` in headers).
194
+ Dot or pill for status. Prop `tone`: `success | warning | danger | info | neutral`; `pulse` animates the dot for live states. `StatusBadge` takes Badge props (`variant="outline"` for a white pill, `size="lg"` in headers) and `compact` (below 640px only the dot shows; the label stays for screen readers).
195
195
 
196
196
  ### `UsageMeter`
197
197
 
@@ -242,6 +242,30 @@ Quiet note with an icon (sparkle by default). Props: `icon?`, `tone?` (`"muted"
242
242
 
243
243
  Muted tile that lifts on hover, for service launchers. Props: `title`, `subtitle?` (mono), `icon?`, `status?: { tone; label }`, `href`, or `asChild` with your router `<Link>` as the only child.
244
244
 
245
+ ## Layout and text
246
+
247
+ Props instead of class names, for blocks that should look right without styling (dashboard widgets, generated UI). Every class string is a literal, so Tailwind finds them.
248
+
249
+ ### `Stack`, `Row`, `Grid`
250
+
251
+ `Stack` stacks children vertically, `Row` lays them out horizontally (`align`, `justify`, `wrap`). Both take a named `gap`: `none | xs | sm | md | lg | xl`. `Grid` makes equal columns: `cols={3}` or `cols={{ base: 1, sm: 2, md: 3 }}`. With `query="container"` the breakpoints measure the nearest `@container` ancestor (sm 28rem, md 42rem, lg 56rem) instead of the screen, for blocks that sit in cards of any width.
252
+
253
+ ### `Text`, `Heading`
254
+
255
+ `Text` takes `size` (`xs | sm | base | lg | xl | 2xl`), `tone` (`default | muted | success | warning | danger | info`), `weight`, `mono`, `truncate`, `lines` (1 to 3) and `tabular`, and renders `as` a span, p or div. `Heading` is a card section title (`level={3}`) or a small uppercase group label (`level={4}`).
256
+
257
+ ### `Metric`, `MetricGroup`
258
+
259
+ A number with `value`, `unit`, `label` and an optional `delta` in percent, green when it improves (`lowerIsBetter` for latency and the like). `MetricGroup` sets metrics side by side, evenly spaced.
260
+
261
+ ### `MediaItem`
262
+
263
+ Thumbnail (`image`, `imageShape`: `poster | square | wide`), a two-line `title` (linked when `href` is set, new tab), a `meta` line and a two-line `description`.
264
+
265
+ ### `ShowMore`
266
+
267
+ Shows the first `initial` children (default 5) and a "Show N more" button for the rest.
268
+
245
269
  ## Data display
246
270
 
247
271
  ### `DataTable`
@@ -327,7 +351,7 @@ Scrollable log that sticks to the bottom as content streams in (unless the user
327
351
 
328
352
  ### `ChatMessage`
329
353
 
330
- One turn. Props: `role: "user" | "assistant"` (matches AI SDK message roles), `avatar?` (assistant only, defaults to `AssistantAvatar`), `actions?` (assistant only, under the content), `variant?` (user bubble: `"muted"` default or `"soft"` accent tint), `children`. Long words wrap.
354
+ One turn. Props: `role: "user" | "assistant"` (matches AI SDK message roles), `avatar?` (assistant only, defaults to `AssistantAvatar`; `false` for none and full-width content, for agent threads where one turn is many blocks), `actions?` (assistant only, under the content), `variant?` (user bubble: `"muted"` default or `"soft"` accent tint), `children`. Long words wrap.
331
355
  User turns render as a right-aligned bubble with preserved newlines. Assistant turns render free-flowing: put `Prose`, `CodeBlock`, `ToolCall`, `TypingIndicator` inside.
332
356
 
333
357
  ```tsx
@@ -374,14 +398,15 @@ Composer chip that picks one mode from a menu (permission level, agent vs. ask).
374
398
 
375
399
  ### `ModelPicker`
376
400
 
377
- Pill showing the active model with a status dot, opening a menu. Props: `models: { id; label?; description?; status? }[]`, `value`, `onValueChange`, `label?`, `disabled?`.
401
+ Pill showing the active model with a status dot, opening a menu. Props: `models: { id; label?; description?; status?; group? }[]` (`group`, e.g. the provider, sections the menu), `value` (listed and checked even when missing from `models`), `onValueChange`, `label?`, `disabled?`.
378
402
 
379
403
  ### `ConversationList`
380
404
 
381
- Grouped thread list. Props: `groups: { label; items: Conversation[] }[]`, `activeId?`, `onSelect?(id)`, `renderAction?(conversation)` (trailing control, e.g. a delete button; on desktop it shows on hover/focus), `empty?`.
382
- `Conversation = { id; title; description?; tone?; pulse? }`: `description` is the second line (time, or a live state with a `tone` dot).
405
+ Grouped thread list. Props: `groups: { label; items: Conversation[] }[]`, `activeId?`, `onSelect?(id)`, `onDelete?(conversation)` (adds a delete button per row that confirms first; `deleteDescription?` is the confirmation body), `renderAction?(conversation)` (any other trailing control; wins over `onDelete`; on desktop it shows on hover/focus), `empty?`.
406
+ `Conversation = { id; title; description?; tone?; pulse?; deleteDisabled? }`: `description` is the second line (time, or a live state with a `tone` dot); `deleteDisabled` blocks delete for that row (a string is the reason, shown as the tooltip).
383
407
  Inside a `Sidebar` it closes the mobile sheet on select and hides in the icon rail.
384
408
  `groupByDate(items, getDate, toConversation, now?)` buckets items into Today / Yesterday / Previous 7 days / Earlier, newest first.
409
+ `formatWhen(date, now?, locale?)`: short timestamp for rows and headers: the time today ("9:41 AM"), the date this year ("Nov 3"), else with the year.
385
410
 
386
411
  ### `NewConversationButton`
387
412
 
@@ -410,13 +435,13 @@ Agent tool calls as a bordered, collapsible card. `ToolStatus = "queued" | "wait
410
435
 
411
436
  ### `ApprovalCard`, `ApprovalResult`
412
437
 
413
- `ApprovalCard`: warning-ringed card for anything the agent waits on the user for. Props: `title`, `description?`, `icon?` (default shield, `null` for none), `code?` + `codeLabel?` (wrapped code block with copy), `actions?` (buttons), `footer?`, `children` (body, e.g. the reason).
438
+ `ApprovalCard`: warning-ringed card for anything the agent waits on the user for. Props: `title`, `description?`, `icon?` (default shield, `null` for none), `reason?` (shown first after a bold "Why:"), `code?` + `codeLabel?` (wrapped code block with copy), `actions?` (buttons), `footer?`, `children` (more body).
414
439
  `ApprovalResult`: one-line record in the thread. Props: `decision: "approved" | "denied"`, `time?`, `children`.
415
440
 
416
441
  ### `CodeSnippet`, `InlineCode`, `Prose`
417
442
 
418
443
  `CodeSnippet`: one-prop code panel with language label, copy button and shiki syntax highlighting (each language loads on first use). Props: `code`, `language?` (`bash`, `tsx`, `ts`, `js`, `json`, `python`, `sql`, `yaml`, `css`, `html`, `markdown`, `diff`; others render plain), `highlight?` (default true), `lineNumbers?`, `hideCopy?`. Built on the `CodeBlock` primitives; drop to those for diffs or highlighted lines.
419
- `InlineCode`: monospace span.
444
+ `InlineCode`: monospace span. `truncate?: number` cuts longer string children with an ellipsis and puts the full text in the tooltip.
420
445
  `Prose`: typography for model output and markdown. Styles plain `p, ul, ol, li, strong, a, code, pre, h1-h4, blockquote, table` children, so it works with `react-markdown`.
421
446
 
422
447
  ### Chat primitives vs. composites
@@ -0,0 +1,75 @@
1
+ # Working with AI agents
2
+
3
+ harebear-ui is built to be used by coding agents (Claude Code, Codex, Cursor, Copilot and the like). The package ships its own instructions, so an agent in your repo knows which components exist, how to style them, and how to check its work, without you pasting docs into the prompt.
4
+
5
+ ![What init sets up for your agent](../../.github/assets/agents.webp)
6
+
7
+ ## What ships in the package
8
+
9
+ | File (in `node_modules/harebear-ui/`) | What it is |
10
+ | ------------------------------------- | --------------------------------------------------------------------------------------------- |
11
+ | `llms.txt` | Short index: setup, the styling rules, every export by group. Small enough to paste anywhere. |
12
+ | `docs/COMPONENTS.md` | The catalog: every export with props, variants and examples. A test keeps it complete. |
13
+ | `docs/guides/` | These guides: setup per framework, theming, agents. |
14
+ | `skills/harebear-ui/SKILL.md` | A Claude Code skill that loads whenever the agent builds or changes UI. |
15
+ | `AGENTS.md` | Instructions for agents working on harebear-ui itself (not needed in your app). |
16
+
17
+ ## Set up your repo
18
+
19
+ ```bash
20
+ npx harebear-ui init
21
+ ```
22
+
23
+ This writes two things your agent reads automatically:
24
+
25
+ 1. **A harebear-ui section in `AGENTS.md`** (or in `CLAUDE.md` if that file exists and `AGENTS.md` does not). It points at the catalog and states the rules: import from the package root, tokens only, check light and dark mode and phone width. The section sits between `<!-- harebear-ui:start -->` and `<!-- harebear-ui:end -->` markers, and running `init` again after an upgrade replaces it in place.
26
+ 2. **A Claude Code skill** at `.claude/skills/harebear-ui/SKILL.md`. Claude Code loads it on UI tasks; it adds the composition rules (which composite to use for which screen) and the visual checks.
27
+
28
+ Commit both. Re-run `npx harebear-ui init` after upgrading harebear-ui to refresh them.
29
+
30
+ ### Per tool
31
+
32
+ | Tool | What it reads |
33
+ | ------------- | -------------------------------------------------------------------------------------------------------------------- |
34
+ | Claude Code | `CLAUDE.md` and `.claude/skills/`. If your instructions live in `AGENTS.md`, add a line `@AGENTS.md` to `CLAUDE.md`. |
35
+ | Codex, Cursor | `AGENTS.md`. See [agents.md](https://agents.md) for the tools that follow the convention. |
36
+ | Anything else | Point it at `node_modules/harebear-ui/llms.txt` in your own instructions file. |
37
+
38
+ ## Look things up instead of reading everything
39
+
40
+ The full catalog is long. Agents (and you) can pull just the entries a task needs:
41
+
42
+ ```bash
43
+ npx harebear-ui docs DataTable # one export
44
+ npx harebear-ui docs DataTable StatCard # several
45
+ npx harebear-ui docs Prompt # every export starting with "Prompt"
46
+ npx harebear-ui docs Tokens # a whole section: Theme, Tokens, Auth, "AI and chat", ...
47
+ npx harebear-ui docs # everything
48
+ ```
49
+
50
+ A lookup prints the matching `###` sections, or the primitive's table row with its header. It exits with status 1 when nothing matches, so an agent notices a wrong name instead of guessing.
51
+
52
+ ## Prompts that work well
53
+
54
+ The instructions already cover style rules, so prompts can stay about the product:
55
+
56
+ - "Build a settings page with a profile card, a notifications card with switches, and a danger zone with a delete-account ConfirmDialog."
57
+ - "Turn `orders.json` into an orders screen: DataTable with status badges, a detail panel when a row is clicked, and a KPI row above it."
58
+ - "Make a chat UI for our support bot with a conversation list, tool calls shown as ToolSteps and approval prompts for refunds."
59
+ - "Start from the admin reference screen and adapt it to our metrics endpoint."
60
+
61
+ Pointing at a reference screen is the fastest way to a good result. The playground has six, built only from public exports: [`playground/screens/`](https://github.com/HMilbradt/harebear-ui/tree/main/playground/screens) (admin dashboard, AI chat, agent with approvals, records table with detail panel, status home, auth).
62
+
63
+ ## Review what the agent built
64
+
65
+ Things to check before you accept a UI change:
66
+
67
+ - **Both modes.** Toggle light and dark. Anything that only works in one used a palette color instead of a token.
68
+ - **Phone width.** At 375px rows wrap, tables scroll inside their card, and the sidebar becomes a sheet.
69
+ - **No forks.** The agent imported from `harebear-ui` rather than copying component source into the app.
70
+ - **No color overrides.** `className` on harebear components is for layout. A `bg-*` or `text-*` color override on a library component means the agent hit a gap; ask it to report the gap instead.
71
+ - **Accessible icons.** Icon-only buttons have an `aria-label`.
72
+
73
+ ## Working on harebear-ui itself
74
+
75
+ Agents contributing to this repo should read [AGENTS.md](../../AGENTS.md) at the repo root. It covers the layout, the conventions for new components, the checks (`pnpm check`), and how to regenerate the README images (`pnpm shots`).