@create-ui/cli 0.5.8 → 0.6.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 (72) hide show
  1. package/dist/{chunk-RMTTHCB3.js → chunk-2ELKDGGM.js} +3 -3
  2. package/dist/{chunk-RMTTHCB3.js.map → chunk-2ELKDGGM.js.map} +1 -1
  3. package/dist/chunk-643QI2I2.js +102 -0
  4. package/dist/chunk-643QI2I2.js.map +1 -0
  5. package/dist/{chunk-NQFMXHMH.js → chunk-KQTXDVKV.js} +3 -3
  6. package/dist/chunk-KQTXDVKV.js.map +1 -0
  7. package/dist/index.d.ts +360 -360
  8. package/dist/index.js +26 -26
  9. package/dist/index.js.map +1 -1
  10. package/dist/mcp/index.js +1 -1
  11. package/dist/registry/index.d.ts +2 -2
  12. package/dist/registry/index.js +1 -1
  13. package/dist/schema/index.d.ts +715 -715
  14. package/dist/skills/createui/SKILL.md +199 -177
  15. package/dist/skills/createui/agents/openai.yml +1 -1
  16. package/dist/skills/createui/cli.md +42 -42
  17. package/dist/skills/createui/customization.md +20 -15
  18. package/dist/skills/createui/evals/evals.json +68 -5
  19. package/dist/skills/createui/mcp.md +14 -5
  20. package/dist/skills/createui/reference/accordion.md +127 -0
  21. package/dist/skills/createui/reference/app-store-badge.md +88 -0
  22. package/dist/skills/createui/reference/aspect-ratio.md +52 -0
  23. package/dist/skills/createui/reference/avatar.md +230 -0
  24. package/dist/skills/createui/reference/badge.md +110 -0
  25. package/dist/skills/createui/reference/breadcrumb.md +153 -0
  26. package/dist/skills/createui/reference/button-group.md +116 -0
  27. package/dist/skills/createui/reference/button.md +104 -0
  28. package/dist/skills/createui/reference/checkbox-group.md +118 -0
  29. package/dist/skills/createui/reference/checkbox.md +79 -0
  30. package/dist/skills/createui/reference/chip.md +115 -0
  31. package/dist/skills/createui/reference/close-button.md +83 -0
  32. package/dist/skills/createui/reference/country-flag.md +109 -0
  33. package/dist/skills/createui/reference/credit-card-input.md +76 -0
  34. package/dist/skills/createui/reference/date-input.md +71 -0
  35. package/dist/skills/createui/reference/dropdown-menu.md +164 -0
  36. package/dist/skills/createui/reference/field.md +186 -0
  37. package/dist/skills/createui/reference/info-tooltip.md +110 -0
  38. package/dist/skills/createui/reference/inline-alert.md +146 -0
  39. package/dist/skills/createui/reference/input-group.md +171 -0
  40. package/dist/skills/createui/reference/input-otp.md +130 -0
  41. package/dist/skills/createui/reference/input-stepper.md +120 -0
  42. package/dist/skills/createui/reference/input.md +118 -0
  43. package/dist/skills/createui/reference/label.md +121 -0
  44. package/dist/skills/createui/reference/pagination.md +157 -0
  45. package/dist/skills/createui/reference/phone-input.md +77 -0
  46. package/dist/skills/createui/reference/progress.md +158 -0
  47. package/dist/skills/createui/reference/radio-group.md +133 -0
  48. package/dist/skills/createui/reference/radio.md +79 -0
  49. package/dist/skills/createui/reference/scroll-area.md +212 -0
  50. package/dist/skills/createui/reference/segmented-control.md +146 -0
  51. package/dist/skills/createui/reference/select.md +204 -0
  52. package/dist/skills/createui/reference/separator.md +99 -0
  53. package/dist/skills/createui/reference/social-login-button.md +130 -0
  54. package/dist/skills/createui/reference/spinner.md +68 -0
  55. package/dist/skills/createui/reference/status-badge.md +89 -0
  56. package/dist/skills/createui/reference/switch-group.md +122 -0
  57. package/dist/skills/createui/reference/switch.md +75 -0
  58. package/dist/skills/createui/reference/tab-menu.md +165 -0
  59. package/dist/skills/createui/reference/text-link.md +84 -0
  60. package/dist/skills/createui/reference/textarea.md +50 -0
  61. package/dist/skills/createui/reference/toast.md +162 -0
  62. package/dist/skills/createui/reference/tooltip.md +63 -0
  63. package/dist/skills/createui/rules/composition.md +41 -25
  64. package/dist/skills/createui/rules/design.md +266 -0
  65. package/dist/skills/createui/rules/forms.md +44 -15
  66. package/dist/skills/createui/rules/icons.md +64 -18
  67. package/dist/skills/createui/rules/styling.md +53 -14
  68. package/dist/utils/index.js +1 -1
  69. package/package.json +1 -1
  70. package/dist/chunk-M5DYT2NE.js +0 -64
  71. package/dist/chunk-M5DYT2NE.js.map +0 -1
  72. package/dist/chunk-NQFMXHMH.js.map +0 -1
@@ -0,0 +1,162 @@
1
+ <!-- GENERATED FILE - do not edit. Source: registry/ui/toast.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/toast.md -->
2
+
3
+ # toast
4
+
5
+ Notification card with icon, action and close slots plus ToastProgress countdown; seven variants by four appearances
6
+
7
+ Install: `npx @create-ui/cli add toast`
8
+
9
+ ## Import
10
+
11
+ ```tsx
12
+ import { Toast, ToastBody, ToastIcon, ToastContent, ToastTitle, ToastDescription, ToastAction, ToastClose, ToastProgress } from "@/components/ui/toast"
13
+ ```
14
+
15
+ Also exported: `toastVariants`, `useToastContext`
16
+
17
+ ## Toast props
18
+
19
+ | Prop | Type | Default |
20
+ | --- | --- | --- |
21
+ | variant | `primary \| neutral \| danger \| success \| warning \| info \| away` | `primary` |
22
+ | appearance | `solid \| soft \| outline \| default` (solid = filled, soft/outline/default = quieter surfaces) | `solid` |
23
+
24
+ Extends `React.ComponentProps<"div">`.
25
+
26
+ ## ToastProgress props
27
+
28
+ | Prop | Type | Default |
29
+ | --- | --- | --- |
30
+ | value | `number` | - |
31
+ | duration | `number` (CSS tween duration per value change (default 150ms); for a lifetime countdown set it to the toast's full lifetime in ms) | `150` |
32
+
33
+ Extends `React.ComponentProps<"div">`.
34
+
35
+ ## Examples
36
+
37
+ From `toast-demo`:
38
+
39
+ ```tsx
40
+ import { RiInformationFill } from "@create-ui/assets/icons"
41
+
42
+ import {
43
+ Toast,
44
+ ToastBody,
45
+ ToastContent,
46
+ ToastDescription,
47
+ ToastIcon,
48
+ ToastTitle,
49
+ } from "@/components/ui/toast"
50
+
51
+ export default function ToastDemo() {
52
+ return (
53
+ <Toast>
54
+ <ToastBody>
55
+ <ToastIcon>
56
+ <RiInformationFill />
57
+ </ToastIcon>
58
+ <ToastContent>
59
+ <ToastTitle>New update available</ToastTitle>
60
+ <ToastDescription>Version 2.1 is ready to install.</ToastDescription>
61
+ </ToastContent>
62
+ </ToastBody>
63
+ </Toast>
64
+ )
65
+ }
66
+ ```
67
+
68
+ From `toast-with-progress`:
69
+
70
+ ```tsx
71
+ "use client"
72
+
73
+ import * as React from "react"
74
+ import { RiInformationFill } from "@create-ui/assets/icons"
75
+
76
+ import { Button } from "@/components/ui/button"
77
+ import {
78
+ Toast,
79
+ ToastBody,
80
+ ToastContent,
81
+ ToastDescription,
82
+ ToastIcon,
83
+ ToastProgress,
84
+ ToastTitle,
85
+ } from "@/components/ui/toast"
86
+
87
+ const DURATION_MS = 5000
88
+
89
+ export default function ToastWithProgress() {
90
+ const [visible, setVisible] = React.useState(true)
91
+ const [progress, setProgress] = React.useState(0)
92
+
93
+ React.useEffect(() => {
94
+ if (!visible) return
95
+
96
+ const raf = requestAnimationFrame(() => setProgress(100))
97
+ const timeout = setTimeout(() => setVisible(false), DURATION_MS)
98
+
99
+ return () => {
100
+ cancelAnimationFrame(raf)
101
+ clearTimeout(timeout)
102
+ }
103
+ }, [visible])
104
+
105
+ if (!visible) {
106
+ return (
107
+ <Button
108
+ variant="neutral-light"
109
+ appearance="outline"
110
+ onClick={() => {
111
+ setProgress(0)
112
+ setVisible(true)
113
+ }}
114
+ >
115
+ Show toast again
116
+ </Button>
117
+ )
118
+ }
119
+
120
+ return (
121
+ <Toast variant="info" appearance="soft">
122
+ <ToastBody>
123
+ <ToastIcon>
124
+ <RiInformationFill />
125
+ </ToastIcon>
126
+ <ToastContent>
127
+ <ToastTitle>Auto-dismissing in 5s</ToastTitle>
128
+ <ToastDescription>
129
+ The progress bar tracks the remaining lifetime of this toast.
130
+ </ToastDescription>
131
+ </ToastContent>
132
+ </ToastBody>
133
+ <ToastProgress value={progress} duration={DURATION_MS} />
134
+ </Toast>
135
+ )
136
+ }
137
+ ```
138
+
139
+ More: `npx @create-ui/cli view toast` or MCP `get_item_examples_from_registries` with "toast-demo" / "toast-example".
140
+
141
+ ## When to use
142
+
143
+ Ephemeral, floating confirmation of an action ("Draft saved", "Copied"); render it in a screen-level fixed container. Not for status that belongs to a section (use `InlineAlert`), blocking confirm/cancel decisions (use `Dialog`), or per-field validation (use `Field` helper/error text).
144
+
145
+ ## Gotchas
146
+
147
+ - There is no `toast()` function, no `Toaster`, no app-level provider, no portal, no queue or positioning system. `Toast` is just the card; render active toasts from your own state into a fixed container. Do NOT install or import `sonner`.
148
+ - Dismiss lifecycle: `ToastClose` starts a 300ms fade/scale exit; the root's `onDismiss` fires only after the transition ends, then the component renders `null`. Remove the toast from your list in `onDismiss`, not in `ToastClose`'s `onClick`. Once dismissed it stays hidden; re-showing requires a remount (state toggle or new `key`).
149
+ - `ToastProgress` never ticks by itself and is `aria-hidden` (purely visual). For an auto-dismissing toast, set `duration` to the lifetime, flip `value` from 0 to 100 inside `requestAnimationFrame`, and pair it with a `setTimeout` that actually hides the toast:
150
+
151
+ ```tsx
152
+ React.useEffect(() => {
153
+ const raf = requestAnimationFrame(() => setProgress(100))
154
+ const timeout = setTimeout(() => setVisible(false), DURATION_MS)
155
+ return () => { cancelAnimationFrame(raf); clearTimeout(timeout) }
156
+ }, [])
157
+ // <ToastProgress value={progress} duration={DURATION_MS} />
158
+ ```
159
+
160
+ - `ToastIcon`, `ToastDescription`, `ToastAction`, `ToastClose`, and `ToastProgress` read the Toast context, so they only style correctly inside `<Toast>`. Don't hand-set Button variants on `ToastAction`/`ToastClose` (the appearance-matched pairing is automatic) or color/size classes on the icon (the svg is auto-sized `size-5` and colored per variant/appearance).
161
+ - The root is hard-coded `w-[410px] min-w-[300px]`; override the width via `className` for narrow viewports.
162
+ - The root renders `role="status"` (polite live region); pass `role="alert"` for urgent messages. No Escape-key handling is wired; dismissal happens only through `ToastClose` (or `useToastContext().dismiss`).
@@ -0,0 +1,63 @@
1
+ <!-- GENERATED FILE - do not edit. Source: registry/ui/tooltip.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/tooltip.md -->
2
+
3
+ # tooltip
4
+
5
+ Radix hover tooltip for any trigger element; five color variants, optional arrow, side and offset control
6
+
7
+ Install: `npx @create-ui/cli add tooltip`
8
+
9
+ ## Import
10
+
11
+ ```tsx
12
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
13
+ ```
14
+
15
+ Also exported: `tooltipContentVariants`
16
+
17
+ ## TooltipContent props
18
+
19
+ | Prop | Type | Default |
20
+ | --- | --- | --- |
21
+ | children | `ReactNode` | - |
22
+ | className | `string` | - |
23
+ | variant | `primary \| neutral \| inverse \| danger \| info` | `primary` |
24
+ | showArrow | `boolean` (effective offset = sideOffset when true; sideOffset + 5 when false, so the chip keeps a visible gap without the caret) | `false` |
25
+ | side | `top \| bottom \| left \| right` (defaults to bottom; shadcn/Radix default to top, do not assume top) | `bottom` |
26
+ | sideOffset | `number` | `2.5` |
27
+
28
+ Extends `React.ComponentProps<typeof TooltipPrimitive.Content>`.
29
+
30
+ ## Examples
31
+
32
+ From `tooltip-demo`:
33
+
34
+ ```tsx
35
+ "use client"
36
+
37
+ import { Button } from "@/components/ui/button"
38
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
39
+
40
+ export default function TooltipDemo() {
41
+ return (
42
+ <Tooltip defaultOpen>
43
+ <TooltipTrigger asChild>
44
+ <Button appearance="outline" size="sm">
45
+ Hover me
46
+ </Button>
47
+ </TooltipTrigger>
48
+ <TooltipContent showArrow>Add to library</TooltipContent>
49
+ </Tooltip>
50
+ )
51
+ }
52
+ ```
53
+
54
+ More: `npx @create-ui/cli view tooltip` or MCP `get_item_examples_from_registries` with "tooltip-demo" / "tooltip-example".
55
+
56
+ ## When to use
57
+ Tooltip is a short hover/focus hint for icon-only buttons, truncated labels, and similar read-only context. Content must stay brief: the chip caps at max-w-[200px] and wraps. For content with links, buttons, or inputs there is no popover component - put it inline; for a help icon next to a label use InfoTooltip; for post-action messages use Toast; for a persistent in-flow note use InlineAlert.
58
+ ## Gotchas
59
+ - Tooltip self-provides its Radix Provider and passes delayDuration (default 0) explicitly to both Provider and Root, so an ancestor TooltipProvider's delayDuration never reaches it. Set delay per instance: `<Tooltip delayDuration={400}>`. The exported TooltipProvider only matters for raw TooltipPrimitive.Root subtrees.
60
+ - align is hardcoded to "center" and Omit-ed from the passthrough type; it cannot be overridden.
61
+ - TooltipTrigger should use asChild wrapping a focusable registry element (Button, link); the trigger always gets an `inline-flex` class so the wrapped child lays out consistently.
62
+ - TooltipArrow is internal and not exported; the only way to render the caret is `showArrow` on TooltipContent, and its fill auto-matches the chosen variant. Never try to style or compose the arrow separately.
63
+ - InfoTooltip is a separate ready-made component for inline "what is this" affordances; do not hand-compose Tooltip around an info icon.
@@ -1,6 +1,6 @@
1
1
  # Component Composition
2
2
 
3
- How Create UI components fit together. Compose primitives never reroll a `<select>`, a custom callout, or a hand-styled loading button when a component already exists. Every component name below is in the `@createui` registry; add any of them with `npx @create-ui/cli add <name>`.
3
+ How Create UI components fit together. Compose primitives - never reroll a `<select>`, a custom callout, or a hand-styled loading button when a component already exists. Every component name below is in the `@createui` registry; add any of them with `npx @create-ui/cli add <name>`.
4
4
 
5
5
  ## Contents
6
6
 
@@ -8,16 +8,16 @@ How Create UI components fit together. Compose primitives — never reroll a `<s
8
8
  - Callouts use InlineAlert
9
9
  - Toasts use the Toast component
10
10
  - Choosing between overlay components
11
- - Button has a `loading` prop never hand-build a spinner button
11
+ - Button has a `loading` prop - never hand-build a spinner button
12
12
  - Tabbed navigation uses TabMenu
13
- - Avatar always needs AvatarFallback
13
+ - Avatar composition (AvatarText, not AvatarFallback)
14
14
  - Use existing components instead of custom markup
15
15
 
16
16
  ---
17
17
 
18
18
  ## Items always inside their Group component
19
19
 
20
- Never render menu/list items directly inside the content container always wrap them in the matching `*Group`.
20
+ Never render menu/list items directly inside the content container - always wrap them in the matching `*Group`.
21
21
 
22
22
  **Incorrect:**
23
23
 
@@ -42,17 +42,17 @@ Never render menu/list items directly inside the content container — always wr
42
42
 
43
43
  This applies to every group-based component:
44
44
 
45
- | Item | Group |
46
- |------|-------|
47
- | `SelectItem`, `SelectLabel` | `SelectGroup` |
48
- | `DropdownMenuItem`, `DropdownMenuLabel` | `DropdownMenuGroup` |
49
- | `CommandItem` | `CommandGroup` |
45
+ | Item | Group | Requirement |
46
+ |------|-------|-------------|
47
+ | `SelectItem`, `SelectLabel` | `SelectGroup` | Structural - always wrap |
48
+ | `CommandItem` | `CommandGroup` | Structural - always wrap |
49
+ | `DropdownMenuItem`, `DropdownMenuLabel` | `DropdownMenuGroup` | Semantic - group related items (with `DropdownMenuLabel` / `DropdownMenuSeparator`); a lone item may sit directly in `DropdownMenuContent` |
50
50
 
51
51
  ---
52
52
 
53
53
  ## Callouts use InlineAlert
54
54
 
55
- Use `InlineAlert` for callouts. Don't hand-roll a styled `<div>` and don't look for a shadcn-style generic alert (or a page-banner) component; `InlineAlert` is the callout primitive.
55
+ Use `InlineAlert` for callouts. Don't hand-roll a styled `<div>` - and don't look for a shadcn-style generic alert (or a page-banner) component; `InlineAlert` is the callout primitive.
56
56
 
57
57
  **Incorrect:**
58
58
 
@@ -94,13 +94,13 @@ import {
94
94
  </InlineAlert>
95
95
  ```
96
96
 
97
- `InlineAlert` takes `variant` (`primary` | `neutral` | `danger` | `success` | `warning` | `info` | `away`) and `appearance` (`default` | `solid` | `soft` | `outline`). For a dismissible callout, add `<InlineAlertClose />` as a direct child and handle `onDismiss` on the root. For a full-width page banner, place an `InlineAlert` in a full-width container there is no separate banner component.
97
+ `InlineAlert` takes `variant` (`primary` | `neutral` | `danger` | `success` | `warning` | `info` | `away`) and `appearance` (`default` | `solid` | `soft` | `outline`). For a dismissible callout, add `<InlineAlertClose />` as a direct child and handle `onDismiss` on the root. For a full-width page banner, place an `InlineAlert` in a full-width container - there is no separate banner component.
98
98
 
99
99
  ---
100
100
 
101
101
  ## Toasts use the Toast component
102
102
 
103
- Toasts are the registry's own `toast` component **not `sonner`**. There is no `toast()` function to import; compose the `Toast` parts and render it from your notification state.
103
+ Toasts are the registry's own `toast` component - **not `sonner`**. There is no `toast()` function to import; compose the `Toast` parts and render it from your notification state.
104
104
 
105
105
  **Incorrect:**
106
106
 
@@ -140,7 +140,7 @@ import {
140
140
 
141
141
  `Toast` takes `variant` (`primary` | `neutral` | `danger` | `success` | `warning` | `info` | `away`) and `appearance` (`solid` | `soft` | `outline` | `default`), plus an `onDismiss` callback. Add `<ToastClose />` for an explicit close affordance and `<ToastProgress />` for an auto-dismiss countdown bar.
142
142
 
143
- There is no provider, queue, or stacking system you own the notification state and the placement. Render active toasts from your state into a fixed container:
143
+ There is no provider, queue, or stacking system - you own the notification state and the placement. Render active toasts from your state into a fixed container:
144
144
 
145
145
  ```tsx
146
146
  const [toasts, setToasts] = React.useState<AppToast[]>([])
@@ -168,7 +168,7 @@ const [toasts, setToasts] = React.useState<AppToast[]>([])
168
168
 
169
169
  ## Choosing between overlay components
170
170
 
171
- Pick the overlay that matches the interaction these are the overlays that exist.
171
+ Pick the overlay that matches the interaction - these are the overlays that exist.
172
172
 
173
173
  | Use case | Component |
174
174
  |----------|-----------|
@@ -177,13 +177,13 @@ Pick the overlay that matches the interaction — these are the overlays that ex
177
177
  | Action menu on a trigger | `DropdownMenu` |
178
178
  | Command palette / quick switcher | `Command` (inline) / `CommandDialog` (modal) |
179
179
 
180
- There is **no dialog, popover, sheet, drawer, alert-dialog, or hover-card component**. The only modal surface is `CommandDialog` (shipped with `command`). For other modal or contextual-panel needs, don't invent a lookalike from raw markup surface the flow inline (e.g. an expanding section, a dedicated route, or an `InlineAlert` confirmation) or ask the user before hand-rolling an overlay.
180
+ There is **no dialog, popover, sheet, drawer, alert-dialog, or hover-card component**. The only modal surface is `CommandDialog` (shipped with `command`). For other modal or contextual-panel needs, don't invent a lookalike from raw markup - surface the flow inline (e.g. an expanding section, a dedicated route, or an `InlineAlert` confirmation) or ask the user before hand-rolling an overlay.
181
181
 
182
182
  ---
183
183
 
184
- ## Button has a `loading` prop never hand-build a spinner button
184
+ ## Button has a `loading` prop - never hand-build a spinner button
185
185
 
186
- `Button` ships a real `loading` prop. It renders the `Spinner` and disables interaction for you do not compose a `Spinner` + `disabled` button by hand.
186
+ `Button` ships a real `loading` prop. It renders the `Spinner` and disables interaction for you - do not compose a `Spinner` + `disabled` button by hand.
187
187
 
188
188
  **Incorrect:**
189
189
 
@@ -200,7 +200,7 @@ There is **no dialog, popover, sheet, drawer, alert-dialog, or hover-card compon
200
200
  <Button loading>Saving…</Button>
201
201
  ```
202
202
 
203
- For icons, use the `leadingIcon` / `trailingIcon` props (or `iconOnly` for an icon-only button) never wrap raw `<svg>` children or add sizing classes; the component sizes the icon per `size`.
203
+ For icons, use the `leadingIcon` / `trailingIcon` props (or `iconOnly` for an icon-only button) - never wrap raw `<svg>` children or add sizing classes; the component sizes the icon per `size`.
204
204
 
205
205
  ```tsx
206
206
  import { RiSearchLine } from "@create-ui/assets/icons"
@@ -209,13 +209,13 @@ import { RiSearchLine } from "@create-ui/assets/icons"
209
209
  <Button iconOnly aria-label="Search" leadingIcon={<RiSearchLine />} />
210
210
  ```
211
211
 
212
- Remember the Button API: `variant` is `primary | neutral-solid | neutral-light | danger | success | inverse-solid | inverse-light`, and the outlined/ghost looks come from `appearance` (`solid | outline | ghost | soft`). There is no outline or destructive `variant` value use `appearance="outline"` for the outlined look and `variant="danger"` for destructive actions. See `rules/styling.md` for the full variant/appearance reference.
212
+ Remember the Button API: `variant` is `primary | neutral-solid | neutral-light | danger | success | inverse-solid | inverse-light`, and the outlined/ghost looks come from `appearance` (`solid | outline | ghost | soft`). There is no outline or destructive `variant` value - use `appearance="outline"` for the outlined look and `variant="danger"` for destructive actions. See `rules/styling.md` for the full variant/appearance reference.
213
213
 
214
214
  ---
215
215
 
216
216
  ## Tabbed navigation uses TabMenu
217
217
 
218
- Tabs are the `tab-menu` component there is no shadcn-style tabs / tabs-list / tabs-trigger set. `TabMenu` wraps `TabMenuItem`s and owns the selection (`defaultValue`, or controlled `value` / `onValueChange`). It renders the menu only render the active panel yourself from the value; there is no content component.
218
+ Tabs are the `tab-menu` component - there is no shadcn-style tabs / tabs-list / tabs-trigger set. `TabMenu` wraps `TabMenuItem`s and owns the selection (`defaultValue`, or controlled `value` / `onValueChange`). It renders the menu only - render the active panel yourself from the value; there is no content component.
219
219
 
220
220
  ```tsx
221
221
  import { TabMenu, TabMenuItem } from "@/components/ui/tab-menu"
@@ -234,27 +234,43 @@ const [tab, setTab] = React.useState("overview")
234
234
 
235
235
  ---
236
236
 
237
- ## Avatar always needs AvatarFallback
237
+ ## Avatar composition (AvatarText, not AvatarFallback)
238
238
 
239
- Always include `AvatarFallback` so something renders when the image is missing or fails to load.
239
+ **`AvatarFallback` does not exist in Create UI** - the fallback/initials slot is `AvatarText`. It renders only while the sibling `AvatarImage` has not loaded (or when there is no image), so an image avatar should always carry one:
240
240
 
241
241
  ```tsx
242
+ import { Avatar, AvatarImage, AvatarText } from "@/components/ui/avatar"
243
+
244
+ <Avatar>
245
+ <AvatarImage src="/avatar.png" alt="User" />
246
+ <AvatarText>JD</AvatarText>
247
+ </Avatar>
248
+ ```
249
+
250
+ Initials-only avatars pick a real color `variant`; presence comes from `AvatarBadge` + `AvatarBadgeStatus`; stacks are `AvatarGroup` (+ `AvatarGroupAction` for the "+5" affordance):
251
+
252
+ ```tsx
253
+ <Avatar variant="weak-blue"><AvatarText>YT</AvatarText></Avatar>
254
+
242
255
  <Avatar>
243
256
  <AvatarImage src="/avatar.png" alt="User" />
244
- <AvatarFallback>JD</AvatarFallback>
257
+ <AvatarText>JD</AvatarText>
258
+ <AvatarBadge><AvatarBadgeStatus variant="online" /></AvatarBadge>
245
259
  </Avatar>
246
260
  ```
247
261
 
262
+ See `reference/avatar.md` for the full prop tables (`size` `2xs`–`2xl`, `shape`, 55 color variants, `AvatarIcon`, `AvatarRing`).
263
+
248
264
  ---
249
265
 
250
266
  ## Use existing components instead of custom markup
251
267
 
252
- If a primitive already covers the job, use it don't reach for raw elements or utility-class fakes.
268
+ If a primitive already covers the job, use it - don't reach for raw elements or utility-class fakes.
253
269
 
254
270
  | Instead of | Use |
255
271
  |---|---|
256
272
  | `<hr>` or `<div className="border-t">` | `<Separator />` |
257
273
  | `<span className="rounded-full bg-green-100 …">` | `<Badge variant="success">Active</Badge>` |
258
- | A status dot built from a styled `<span>` | `<StatusBadge variant="success" />` (it renders the dot only put the label next to it). `variant`: `primary`, `danger`, `success`, `warning`, `info`, `highlighted`, `away`, `verified`, `cyan`, `lime`, `neutral`, `white` note `danger`, not `error` |
274
+ | A status dot built from a styled `<span>` | `<StatusBadge variant="success" />` (it renders the dot only - put the label next to it). `variant`: `primary`, `danger`, `success`, `warning`, `info`, `highlighted`, `away`, `verified`, `cyan`, `lime`, `neutral`, `white` - note `danger`, not `error` |
259
275
  | A removable tag built from `<span>` + `<button>` | `<Chip onClose={…}>…</Chip>` |
260
276
  | A hand-rolled `animate-spin` loading indicator | `<Spinner />` |