@create-ui/cli 0.5.8 → 0.5.9
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.
- package/dist/{chunk-RMTTHCB3.js → chunk-2ELKDGGM.js} +3 -3
- package/dist/{chunk-RMTTHCB3.js.map → chunk-2ELKDGGM.js.map} +1 -1
- package/dist/chunk-643QI2I2.js +102 -0
- package/dist/chunk-643QI2I2.js.map +1 -0
- package/dist/{chunk-NQFMXHMH.js → chunk-KQTXDVKV.js} +3 -3
- package/dist/chunk-KQTXDVKV.js.map +1 -0
- package/dist/index.d.ts +360 -360
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/registry/index.d.ts +2 -2
- package/dist/registry/index.js +1 -1
- package/dist/schema/index.d.ts +715 -715
- package/dist/skills/createui/SKILL.md +201 -177
- package/dist/skills/createui/agents/openai.yml +1 -1
- package/dist/skills/createui/cli.md +42 -42
- package/dist/skills/createui/customization.md +20 -15
- package/dist/skills/createui/evals/evals.json +68 -5
- package/dist/skills/createui/mcp.md +14 -5
- package/dist/skills/createui/reference/accordion.md +127 -0
- package/dist/skills/createui/reference/app-store-badge.md +88 -0
- package/dist/skills/createui/reference/aspect-ratio.md +52 -0
- package/dist/skills/createui/reference/avatar.md +230 -0
- package/dist/skills/createui/reference/badge.md +110 -0
- package/dist/skills/createui/reference/breadcrumb.md +153 -0
- package/dist/skills/createui/reference/button-group.md +116 -0
- package/dist/skills/createui/reference/button.md +104 -0
- package/dist/skills/createui/reference/checkbox-group.md +118 -0
- package/dist/skills/createui/reference/checkbox.md +79 -0
- package/dist/skills/createui/reference/chip.md +115 -0
- package/dist/skills/createui/reference/close-button.md +83 -0
- package/dist/skills/createui/reference/command.md +69 -0
- package/dist/skills/createui/reference/country-flag.md +109 -0
- package/dist/skills/createui/reference/credit-card-input.md +76 -0
- package/dist/skills/createui/reference/date-input.md +71 -0
- package/dist/skills/createui/reference/dropdown-menu.md +164 -0
- package/dist/skills/createui/reference/field.md +186 -0
- package/dist/skills/createui/reference/info-tooltip.md +110 -0
- package/dist/skills/createui/reference/inline-alert.md +146 -0
- package/dist/skills/createui/reference/input-group.md +171 -0
- package/dist/skills/createui/reference/input-otp.md +130 -0
- package/dist/skills/createui/reference/input-stepper.md +120 -0
- package/dist/skills/createui/reference/input.md +118 -0
- package/dist/skills/createui/reference/label.md +121 -0
- package/dist/skills/createui/reference/pagination.md +157 -0
- package/dist/skills/createui/reference/password-strength.md +70 -0
- package/dist/skills/createui/reference/phone-input.md +77 -0
- package/dist/skills/createui/reference/progress.md +158 -0
- package/dist/skills/createui/reference/radio-group.md +133 -0
- package/dist/skills/createui/reference/radio.md +79 -0
- package/dist/skills/createui/reference/scroll-area.md +212 -0
- package/dist/skills/createui/reference/segmented-control.md +146 -0
- package/dist/skills/createui/reference/select.md +204 -0
- package/dist/skills/createui/reference/separator.md +99 -0
- package/dist/skills/createui/reference/social-login-button.md +130 -0
- package/dist/skills/createui/reference/spinner.md +68 -0
- package/dist/skills/createui/reference/status-badge.md +89 -0
- package/dist/skills/createui/reference/switch-group.md +122 -0
- package/dist/skills/createui/reference/switch.md +75 -0
- package/dist/skills/createui/reference/tab-menu.md +165 -0
- package/dist/skills/createui/reference/text-link.md +84 -0
- package/dist/skills/createui/reference/textarea.md +50 -0
- package/dist/skills/createui/reference/toast.md +162 -0
- package/dist/skills/createui/reference/tooltip.md +63 -0
- package/dist/skills/createui/rules/composition.md +41 -25
- package/dist/skills/createui/rules/design.md +266 -0
- package/dist/skills/createui/rules/forms.md +44 -15
- package/dist/skills/createui/rules/icons.md +64 -18
- package/dist/skills/createui/rules/styling.md +53 -14
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-M5DYT2NE.js +0 -64
- package/dist/chunk-M5DYT2NE.js.map +0 -1
- package/dist/chunk-NQFMXHMH.js.map +0 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<!-- GENERATED FILE - do not edit. Source: registry/ui/accordion.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/accordion.md -->
|
|
2
|
+
|
|
3
|
+
# accordion
|
|
4
|
+
|
|
5
|
+
Vertically stacked disclosure panels for FAQs and settings; six appearances from ghost-default to filled-rounded
|
|
6
|
+
|
|
7
|
+
Install: `npx @create-ui/cli add accordion`
|
|
8
|
+
|
|
9
|
+
## Import
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "@/components/ui/accordion"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Accordion props
|
|
16
|
+
|
|
17
|
+
| Prop | Type | Default |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| appearance | `ghost-default \| ghost-underline \| ghost-rounded \| outline-rounded \| outline-sharp \| filled-rounded` (Set on the root Accordion only; it cascades to Item/Trigger/Content via React context. Subcomponents have no appearance prop.) | `ghost-default` |
|
|
20
|
+
|
|
21
|
+
Extends `React.ComponentProps<typeof AccordionPrimitive.Root>`.
|
|
22
|
+
|
|
23
|
+
## AccordionTrigger props
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Default |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| icon | `ReactNode` (Leading icon only (wrapper auto-sizes the svg to size-5); it does NOT replace the built-in trailing chevron.) | - |
|
|
28
|
+
|
|
29
|
+
Extends `React.ComponentProps< typeof AccordionPrimitive.Trigger >`.
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
From `accordion-demo`:
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import {
|
|
37
|
+
Accordion,
|
|
38
|
+
AccordionContent,
|
|
39
|
+
AccordionItem,
|
|
40
|
+
AccordionTrigger,
|
|
41
|
+
} from "@/components/ui/accordion"
|
|
42
|
+
|
|
43
|
+
export default function AccordionDemo() {
|
|
44
|
+
return (
|
|
45
|
+
<Accordion
|
|
46
|
+
type="single"
|
|
47
|
+
collapsible
|
|
48
|
+
appearance="filled-rounded"
|
|
49
|
+
defaultValue="accessible"
|
|
50
|
+
className="w-full max-w-[560px]"
|
|
51
|
+
>
|
|
52
|
+
<AccordionItem value="accessible">
|
|
53
|
+
<AccordionTrigger>Is it accessible?</AccordionTrigger>
|
|
54
|
+
<AccordionContent>
|
|
55
|
+
Yes. It follows the WAI-ARIA disclosure pattern.
|
|
56
|
+
</AccordionContent>
|
|
57
|
+
</AccordionItem>
|
|
58
|
+
<AccordionItem value="animated">
|
|
59
|
+
<AccordionTrigger>Is it animated?</AccordionTrigger>
|
|
60
|
+
<AccordionContent>
|
|
61
|
+
Yes. Expand, collapse, and chevron rotation are animated.
|
|
62
|
+
</AccordionContent>
|
|
63
|
+
</AccordionItem>
|
|
64
|
+
</Accordion>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
From `accordion-with-trailing-content`:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { RiAlertFill, RiBankCardFill } from "@create-ui/assets/icons"
|
|
73
|
+
|
|
74
|
+
import {
|
|
75
|
+
Accordion,
|
|
76
|
+
AccordionContent,
|
|
77
|
+
AccordionItem,
|
|
78
|
+
AccordionTrigger,
|
|
79
|
+
} from "@/components/ui/accordion"
|
|
80
|
+
import { Badge } from "@/components/ui/badge"
|
|
81
|
+
|
|
82
|
+
export default function AccordionWithTrailingContent() {
|
|
83
|
+
return (
|
|
84
|
+
<Accordion type="single" collapsible className="w-full max-w-[560px]">
|
|
85
|
+
<AccordionItem value="payment">
|
|
86
|
+
<AccordionTrigger icon={<RiBankCardFill />}>
|
|
87
|
+
Why isn’t my payment going through?
|
|
88
|
+
<Badge
|
|
89
|
+
variant="warning"
|
|
90
|
+
appearance="soft"
|
|
91
|
+
size="sm"
|
|
92
|
+
leadingIcon={<RiAlertFill />}
|
|
93
|
+
className="ml-auto"
|
|
94
|
+
>
|
|
95
|
+
Issue
|
|
96
|
+
</Badge>
|
|
97
|
+
</AccordionTrigger>
|
|
98
|
+
<AccordionContent>
|
|
99
|
+
Usually caused by incorrect card details, insufficient funds, or a
|
|
100
|
+
temporary block from your bank.
|
|
101
|
+
</AccordionContent>
|
|
102
|
+
</AccordionItem>
|
|
103
|
+
</Accordion>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
More: `npx @create-ui/cli view accordion` or MCP `get_item_examples_from_registries` with "accordion-demo" / "accordion-example".
|
|
109
|
+
|
|
110
|
+
## When to use
|
|
111
|
+
A vertical stack of same-shaped disclosure rows: FAQs, settings groups, expandable lists. Do NOT use it for switching between sibling views (use TabMenu or SegmentedControl) or for blocking overlay content (there is no dialog/modal component; the only modal surface is CommandDialog - surface such flows inline or on a route). There is no separate Collapsible component; for one standalone show/hide region use a single-item Accordion with type="single" collapsible.
|
|
112
|
+
|
|
113
|
+
## Gotchas
|
|
114
|
+
- `appearance` lives only on the root and flows down via context. An `AccordionItem`/`AccordionTrigger`/`AccordionContent` rendered outside an `Accordion` silently falls back to `ghost-default` styling.
|
|
115
|
+
- The rotating chevron is built in and always trailing; never add your own. Trailing badges/status go in trigger `children` with `ml-auto` (children render inside a `flex-1` label slot that sits before the chevron):
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<AccordionTrigger icon={<RiBankCardFill />}>
|
|
119
|
+
Why is my payment failing?
|
|
120
|
+
<Badge variant="warning" size="sm" className="ml-auto">Issue</Badge>
|
|
121
|
+
</AccordionTrigger>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- `AccordionContent`'s `className` merges onto the inner padding wrapper, not the outer animated Radix element; the expand/collapse animation and `overflow-hidden` cannot be overridden there. The inner wrapper already supplies `flex flex-col gap-4`, so direct children stack; do not add your own stack wrapper.
|
|
125
|
+
- `AccordionItem`s must be direct siblings: `ghost-underline` uses `border-b last:border-b-0` and `outline-sharp` collapses borders with `-mt-px first:mt-0`. Wrapping items in extra divs breaks separators and border collapsing.
|
|
126
|
+
- The focus-visible ring is drawn on `AccordionItem` (via a `has-[[data-slot=accordion-trigger]:focus-visible]` selector); the trigger base is `outline-hidden`. Restyle the focus ring on the Item, not the trigger.
|
|
127
|
+
- The root bakes in `min-w-90` (360px); in narrower containers override it via `className` on `Accordion`.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<!-- GENERATED FILE - do not edit. Source: registry/ui/app-store-badge.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/app-store-badge.md -->
|
|
2
|
+
|
|
3
|
+
# app-store-badge
|
|
4
|
+
|
|
5
|
+
Marketplace download link badge covering 12 brands like App Store and Google Play; variant black/white, iconOnly option
|
|
6
|
+
|
|
7
|
+
Install: `npx @create-ui/cli add app-store-badge`
|
|
8
|
+
|
|
9
|
+
## Import
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { AppStoreBadge } from "@/components/ui/app-store-badge"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Also exported: `appStoreBadgeVariants`
|
|
16
|
+
|
|
17
|
+
## AppStoreBadge props
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| variant | `black \| white` (Pick by the surface the badge sits on, not the app theme; filled colors are literal neutrals that never flip in dark mode) | `black` |
|
|
22
|
+
| appearance | `filled \| outline` | `filled` |
|
|
23
|
+
| iconOnly | `boolean` (Removes all visible text and the SVGs carry no title, so the link has no accessible name - always add an aria-label) | `false` |
|
|
24
|
+
| brand | `app-store \| google-play \| galaxy-store \| shopify-store \| spotify \| add-on \| chrome-web-store \| app-gallery \| windows \| amazon-store \| microsoft \| youtube-music` (Required; selects glyph, subtitle, and title from a fixed preset - the copy is not customizable) | - |
|
|
25
|
+
| asChild | `boolean` (The child element's own children are replaced with the badge content; the child only supplies the wrapper element and its props) | `false` |
|
|
26
|
+
|
|
27
|
+
Extends `React.ComponentProps<"a">`.
|
|
28
|
+
|
|
29
|
+
## Icons
|
|
30
|
+
|
|
31
|
+
Icons go through icon props - never as children next to text, and never with sizing classes (the component sizes icons per `size`): `AppStoreBadge` (). Import icons from `@create-ui/assets/icons` (Remix `Ri*`).
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
From `app-store-badge-demo`:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { AppStoreBadge } from "@/components/ui/app-store-badge"
|
|
39
|
+
|
|
40
|
+
export default function AppStoreBadgeDemo() {
|
|
41
|
+
return (
|
|
42
|
+
<div className="flex flex-wrap items-center gap-2 rounded-2xl bg-white p-4">
|
|
43
|
+
<AppStoreBadge brand="app-store" href="#" />
|
|
44
|
+
<AppStoreBadge brand="google-play" href="#" />
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
From `app-store-badge-in-surface`:
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { AppStoreBadge } from "@/components/ui/app-store-badge"
|
|
54
|
+
|
|
55
|
+
export default function AppStoreBadgeInSurface() {
|
|
56
|
+
return (
|
|
57
|
+
<div className="flex flex-col items-start gap-4 rounded-lg bg-black p-6">
|
|
58
|
+
<div className="flex flex-col gap-1">
|
|
59
|
+
<p className="text-base font-medium text-neutral-50">Get the app</p>
|
|
60
|
+
<p className="text-sm text-neutral-400">
|
|
61
|
+
Take Create UI with you, on any device.
|
|
62
|
+
</p>
|
|
63
|
+
</div>
|
|
64
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
65
|
+
<AppStoreBadge brand="app-store" variant="white" href="#" />
|
|
66
|
+
<AppStoreBadge brand="google-play" variant="white" href="#" />
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
More: `npx @create-ui/cli view app-store-badge` or MCP `get_item_examples_from_registries` with "app-store-badge-demo" / "app-store-badge-example".
|
|
74
|
+
|
|
75
|
+
## When to use
|
|
76
|
+
Branded download CTA linking to an external storefront (App Store, Google Play, Chrome Web Store, Spotify, etc.) on landing pages, footers, and CTA panels. It renders an `<a>` by default; pass `href` directly. Do NOT use it for generic in-product actions (use `Button`), for passive status/count labels (use `Badge`), or for "sign in with provider" buttons (use `SocialLoginButton`).
|
|
77
|
+
## Gotchas
|
|
78
|
+
- Children are silently discarded in normal usage: the icon + subtitle + title are generated entirely from `brand`. You cannot customize the copy via children or any prop.
|
|
79
|
+
- With `asChild`, the single child element's own children are also replaced (`cloneElement(child, undefined, content)`). The child is only the wrapper, e.g. an anchor or Next.js `Link` with `href` and `aria-label`, never text content:
|
|
80
|
+
```tsx
|
|
81
|
+
<AppStoreBadge asChild brand="app-store">
|
|
82
|
+
<a href="https://apps.apple.com" aria-label="Download on the App Store" />
|
|
83
|
+
</AppStoreBadge>
|
|
84
|
+
```
|
|
85
|
+
- There are no `leadingIcon`/`trailingIcon` props on this component; ignore any generic icon-prop guidance. The glyph is auto-selected from `brand` + `variant` + `appearance`: full-color for `filled`, monochrome black/white for `outline`. The monochrome brands (`app-store`, `amazon-store`) flip to the contrast glyph on filled with pinned literal colors so dark mode cannot recolor them.
|
|
86
|
+
- Filled backgrounds are literal `bg-neutral-950`/`bg-neutral-50` and intentionally do not respond to dark mode; only the `outline` appearance uses theme tokens. Choose `variant` by the actual surface color (white variant on dark panels) and do not "fix" contrast via `className` color overrides.
|
|
87
|
+
- `iconOnly` drops the text entirely, leaving the anchor with no accessible name; pair it with an `aria-label` naming the destination (e.g. "Download on the App Store").
|
|
88
|
+
- Hover feedback is opacity-based and built in (`hover:opacity-90`); do not add your own hover background classes.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!-- GENERATED FILE - do not edit. Source: registry/ui/aspect-ratio.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/aspect-ratio.md -->
|
|
2
|
+
|
|
3
|
+
# aspect-ratio
|
|
4
|
+
|
|
5
|
+
Constrains children like images or video embeds to a fixed width-to-height ratio via the ratio prop
|
|
6
|
+
|
|
7
|
+
Install: `npx @create-ui/cli add aspect-ratio`
|
|
8
|
+
|
|
9
|
+
## Import
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { AspectRatio } from "@/components/ui/aspect-ratio"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Examples
|
|
16
|
+
|
|
17
|
+
From `aspect-ratio-demo`:
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { AspectRatio } from "@/components/ui/aspect-ratio"
|
|
21
|
+
|
|
22
|
+
export default function AspectRatioDemo() {
|
|
23
|
+
return (
|
|
24
|
+
<div className="w-full max-w-[480px]">
|
|
25
|
+
<AspectRatio
|
|
26
|
+
ratio={16 / 9}
|
|
27
|
+
className="from-light to-weak rounded-lg bg-gradient-to-br"
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
More: `npx @create-ui/cli view aspect-ratio` or MCP `get_item_examples_from_registries` with "aspect-ratio-demo" / "aspect-ratio-example".
|
|
35
|
+
|
|
36
|
+
## When to use
|
|
37
|
+
Reserve a fixed width-to-height slot for media: image thumbnails in grids, video or iframe embeds, cover photos. Do NOT use it for circular user portraits; that is Avatar's job in Create UI. It is a layout-only wrapper with no visual styling of its own.
|
|
38
|
+
|
|
39
|
+
## Gotchas
|
|
40
|
+
- It has no width of its own and stretches to its parent, so wrap it in a width-constrained container; aspect-ratio-demo wraps it in `<div className="w-full max-w-[480px]">`.
|
|
41
|
+
- It only reserves the box; it never crops or stretches the child. The registry examples pair it with next/image `fill` plus `h-full w-full object-cover` on the image.
|
|
42
|
+
- Rounding the AspectRatio does not clip the child: the registry examples repeat `rounded-lg` on both the AspectRatio and the inner Image.
|
|
43
|
+
- The source is a bare pass-through of Radix `AspectRatio.Root` plus `data-slot="aspect-ratio"`: no CVA variants, no size prop, no `cn()`, no Field/InputGroup context participation. Nothing cascades into or out of it.
|
|
44
|
+
- Children are optional: aspect-ratio-demo renders a self-closing `<AspectRatio />` with only gradient background classes as a placeholder slot.
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
<div className="w-full max-w-[480px]">
|
|
48
|
+
<AspectRatio ratio={16 / 9} className="bg-weak rounded-lg">
|
|
49
|
+
<Image src="/photo.jpg" alt="Photo" fill className="h-full w-full rounded-lg object-cover" />
|
|
50
|
+
</AspectRatio>
|
|
51
|
+
</div>
|
|
52
|
+
```
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
<!-- GENERATED FILE - do not edit. Source: registry/ui/avatar.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/avatar.md -->
|
|
2
|
+
|
|
3
|
+
# avatar
|
|
4
|
+
|
|
5
|
+
Avatar with AvatarImage, AvatarText initials fallback, AvatarIcon, AvatarBadge and AvatarGroup; 55 color variants
|
|
6
|
+
|
|
7
|
+
Install: `npx @create-ui/cli add avatar`
|
|
8
|
+
|
|
9
|
+
## Import
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { Avatar, AvatarImage, AvatarText, AvatarIcon, AvatarRing, AvatarBadge, AvatarBadgeText, AvatarBadgeIcon, AvatarBadgeFlag, AvatarBadgeLogo, AvatarBadgePolygon, AvatarBadgeStatus, AvatarGroup, AvatarGroupAction } from "@/components/ui/avatar"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Also exported: `avatarVariants`, `badgeTextVariants`, `badgeIconVariants`, `badgeFlagVariants`, `badgeLogoVariants`, `badgePolygonVariants`, `avatarGroupVariants`, `avatarGroupActionVariants`
|
|
16
|
+
|
|
17
|
+
## Avatar props
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| size | `2xs \| xs \| sm \| md \| lg \| xl \| 2xl` | `md` |
|
|
22
|
+
| shape | `circle \| rounded` | `circle` |
|
|
23
|
+
| variant | `{gradient\|strong\|base\|weak\|alpha}-{inverse\|neutral\|red\|green\|orange\|blue\|sky\|indigo\|fuchsia\|yellow\|stable} (55 values)` (color recipe {style}-{hue}; e.g. weak-blue for initials, gradient-indigo for showcases) | - |
|
|
24
|
+
| background | `boolean` (set false when AvatarImage always loads) | `true` |
|
|
25
|
+
| stroke | `boolean` (hairline outline; defaults ON for a standalone Avatar, OFF inside AvatarGroup) | - |
|
|
26
|
+
|
|
27
|
+
Extends `React.ComponentProps<"div">`.
|
|
28
|
+
|
|
29
|
+
## AvatarIcon props
|
|
30
|
+
|
|
31
|
+
| Prop | Type | Default |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| variant | `{base\|weak\|strong}-{inverse\|neutral\|red\|green\|orange\|blue\|sky\|indigo\|fuchsia\|yellow\|stable} (33 values)` (color recipe {style}-{hue}; e.g. weak-blue for initials, gradient-indigo for showcases) | - |
|
|
34
|
+
|
|
35
|
+
Extends `React.ComponentProps<"span">`.
|
|
36
|
+
|
|
37
|
+
## AvatarRing props
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| variant | `full \| progress \| loading` (color recipe {style}-{hue}; e.g. weak-blue for initials, gradient-indigo for showcases) | `full` |
|
|
42
|
+
| value | `number` | `100` |
|
|
43
|
+
| color | `strongest \| static \| error \| success \| info \| away \| linear-1 \| linear-2 \| linear-3` | `info` |
|
|
44
|
+
| strokeWidth | `number` | - |
|
|
45
|
+
| gap | `number` | - |
|
|
46
|
+
| size | `2xs \| xs \| sm \| md \| lg \| xl \| 2xl` | - |
|
|
47
|
+
|
|
48
|
+
Extends `React.ComponentProps<"div">`.
|
|
49
|
+
|
|
50
|
+
## AvatarBadge props
|
|
51
|
+
|
|
52
|
+
| Prop | Type | Default |
|
|
53
|
+
| --- | --- | --- |
|
|
54
|
+
| position | `top \| bottom` | `bottom` |
|
|
55
|
+
|
|
56
|
+
Extends `React.ComponentProps<"span">`.
|
|
57
|
+
|
|
58
|
+
## AvatarBadgeText props
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default |
|
|
61
|
+
| --- | --- | --- |
|
|
62
|
+
| size | `xs \| sm \| md \| lg` | `lg` |
|
|
63
|
+
| color | `rose \| blue` | `rose` |
|
|
64
|
+
|
|
65
|
+
Extends `React.ComponentProps<"span">`.
|
|
66
|
+
|
|
67
|
+
## AvatarBadgeIcon props
|
|
68
|
+
|
|
69
|
+
| Prop | Type | Default |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| size | `xs \| sm \| md \| lg` | `lg` |
|
|
72
|
+
| shape | `circle \| rounded` | `circle` |
|
|
73
|
+
| color | `yellow \| green \| violet \| blue \| sky \| red \| amber \| heavy \| strongest \| light \| static-white` | `blue` |
|
|
74
|
+
|
|
75
|
+
Extends `React.ComponentProps<"span">`.
|
|
76
|
+
|
|
77
|
+
## AvatarBadgeFlag props
|
|
78
|
+
|
|
79
|
+
| Prop | Type | Default |
|
|
80
|
+
| --- | --- | --- |
|
|
81
|
+
| size | `xs \| sm \| md \| lg` | `lg` |
|
|
82
|
+
| shape | `circle \| rounded` | `circle` |
|
|
83
|
+
|
|
84
|
+
Extends `React.ComponentProps<"span">`.
|
|
85
|
+
|
|
86
|
+
## AvatarBadgeLogo props
|
|
87
|
+
|
|
88
|
+
| Prop | Type | Default |
|
|
89
|
+
| --- | --- | --- |
|
|
90
|
+
| size | `xs \| sm \| md \| lg` | `lg` |
|
|
91
|
+
| shape | `circle \| rounded` | `circle` |
|
|
92
|
+
|
|
93
|
+
Extends `React.ComponentProps<"span">`.
|
|
94
|
+
|
|
95
|
+
## AvatarBadgePolygon props
|
|
96
|
+
|
|
97
|
+
| Prop | Type | Default |
|
|
98
|
+
| --- | --- | --- |
|
|
99
|
+
| size | `xs \| sm \| md \| lg` | `lg` |
|
|
100
|
+
| color | `sky \| yellow \| neutral-100 \| neutral-700 \| light` | `sky` |
|
|
101
|
+
|
|
102
|
+
Extends `React.ComponentProps<"span">`.
|
|
103
|
+
|
|
104
|
+
## AvatarBadgeStatus props
|
|
105
|
+
|
|
106
|
+
| Prop | Type | Default |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| variant | `invisible \| online \| busy \| offline \| away \| do-not-disturb \| recording \| typing` (color recipe {style}-{hue}; e.g. weak-blue for initials, gradient-indigo for showcases) | `online` |
|
|
109
|
+
| size | `xs \| sm \| md \| lg` | - |
|
|
110
|
+
| shape | `circle \| rounded` | `circle` |
|
|
111
|
+
|
|
112
|
+
Extends `React.ComponentProps<"span">`.
|
|
113
|
+
|
|
114
|
+
## AvatarGroup props
|
|
115
|
+
|
|
116
|
+
| Prop | Type | Default |
|
|
117
|
+
| --- | --- | --- |
|
|
118
|
+
| size | `2xs \| xs \| sm \| md \| lg \| xl \| 2xl` | `md` |
|
|
119
|
+
| shape | `circle \| rounded` | `circle` |
|
|
120
|
+
| variant | `{gradient\|strong\|base\|weak\|alpha}-{inverse\|neutral\|red\|green\|orange\|blue\|sky\|indigo\|fuchsia\|yellow\|stable} (55 values)` (color recipe {style}-{hue}; e.g. weak-blue for initials, gradient-indigo for showcases) | - |
|
|
121
|
+
|
|
122
|
+
Extends `React.ComponentProps<"div">`.
|
|
123
|
+
|
|
124
|
+
## AvatarGroupAction props
|
|
125
|
+
|
|
126
|
+
| Prop | Type | Default |
|
|
127
|
+
| --- | --- | --- |
|
|
128
|
+
| size | `2xs \| xs \| sm \| md \| lg \| xl \| 2xl` | `md` |
|
|
129
|
+
| shape | `circle \| rounded` | `circle` |
|
|
130
|
+
|
|
131
|
+
Extends `React.ComponentProps<"span">`.
|
|
132
|
+
|
|
133
|
+
## Examples
|
|
134
|
+
|
|
135
|
+
From `avatar-demo`:
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
import {
|
|
139
|
+
Avatar,
|
|
140
|
+
AvatarBadge,
|
|
141
|
+
AvatarBadgeStatus,
|
|
142
|
+
AvatarImage,
|
|
143
|
+
AvatarText,
|
|
144
|
+
} from "@/components/ui/avatar"
|
|
145
|
+
|
|
146
|
+
export default function AvatarDemo() {
|
|
147
|
+
return (
|
|
148
|
+
<div className="flex flex-wrap items-center gap-4">
|
|
149
|
+
<Avatar stroke={false}>
|
|
150
|
+
<AvatarImage
|
|
151
|
+
src="https://createui.co/avatars/ayla-karagoz.webp"
|
|
152
|
+
alt="Ayla Karagöz"
|
|
153
|
+
/>
|
|
154
|
+
</Avatar>
|
|
155
|
+
<Avatar stroke={false}>
|
|
156
|
+
<AvatarImage
|
|
157
|
+
src="https://createui.co/avatars/luca-moretti.webp"
|
|
158
|
+
alt="Luca Moretti"
|
|
159
|
+
/>
|
|
160
|
+
<AvatarBadge>
|
|
161
|
+
<AvatarBadgeStatus variant="online" />
|
|
162
|
+
</AvatarBadge>
|
|
163
|
+
</Avatar>
|
|
164
|
+
<Avatar variant="weak-blue" stroke={false}>
|
|
165
|
+
<AvatarText>YT</AvatarText>
|
|
166
|
+
</Avatar>
|
|
167
|
+
</div>
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
From `avatar-group`:
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
import { Avatar, AvatarGroup, AvatarImage } from "@/components/ui/avatar"
|
|
176
|
+
|
|
177
|
+
const people = [
|
|
178
|
+
{
|
|
179
|
+
src: "https://createui.co/avatars/ayla-karagoz.webp",
|
|
180
|
+
name: "Ayla Karagöz",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
src: "https://createui.co/avatars/luca-moretti.webp",
|
|
184
|
+
name: "Luca Moretti",
|
|
185
|
+
},
|
|
186
|
+
{ src: "https://createui.co/avatars/yuki-tanaka.webp", name: "Yuki Tanaka" },
|
|
187
|
+
{ src: "https://createui.co/avatars/sofia-reis.webp", name: "Sofia Reis" },
|
|
188
|
+
]
|
|
189
|
+
|
|
190
|
+
const sizes = ["sm", "md", "lg"] as const
|
|
191
|
+
|
|
192
|
+
export default function AvatarGroupExample() {
|
|
193
|
+
return (
|
|
194
|
+
<div className="flex flex-col gap-6">
|
|
195
|
+
{sizes.map((size) => (
|
|
196
|
+
<AvatarGroup key={size} size={size}>
|
|
197
|
+
{people.map((person) => (
|
|
198
|
+
<Avatar key={person.name}>
|
|
199
|
+
<AvatarImage src={person.src} alt={person.name} />
|
|
200
|
+
</Avatar>
|
|
201
|
+
))}
|
|
202
|
+
</AvatarGroup>
|
|
203
|
+
))}
|
|
204
|
+
</div>
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
More: `npx @create-ui/cli view avatar` or MCP `get_item_examples_from_registries` with "avatar-demo" / "avatar-example".
|
|
210
|
+
|
|
211
|
+
## When to use
|
|
212
|
+
|
|
213
|
+
Identity thumbnail for a person, team, or brand: image, initials (`AvatarText`), or built-in person glyph (`AvatarIcon`), plus `AvatarRing` / `AvatarBadge` overlays and `AvatarGroup` stacks. Not for textual status or count labels (use `Badge`) or standalone presence dots with no portrait (use `StatusBadge`).
|
|
214
|
+
|
|
215
|
+
## Gotchas
|
|
216
|
+
|
|
217
|
+
- `AvatarFallback` does NOT exist; the fallback slot is `AvatarText`, placed as a sibling of `AvatarImage`. The image stays invisible until it reports loaded, and `AvatarText`/`AvatarIcon` auto-unmount once it does; an image avatar without an `AvatarText` shows only the background shape while loading or on error. Avatar has NO default `variant` (and no background fill without one), so whenever `AvatarText` is present - standalone initials or image fallback - always set a `variant` (e.g. `weak-neutral`, `weak-blue`), or the initials float on a transparent circle.
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
<Avatar variant="weak-blue">
|
|
221
|
+
<AvatarImage src="/u.png" alt="User" />
|
|
222
|
+
<AvatarText>JD</AvatarText>
|
|
223
|
+
</Avatar>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
- `AvatarIcon` takes NO children; it draws its own built-in person glyph. Its own `variant` tints the glyph independently of the root `variant` (e.g. `base-red` icon on a `weak-red` avatar).
|
|
227
|
+
- `AvatarGroup` separates children with its own white ring and paints a gradient placeholder background on every child avatar; child `stroke` switches off automatically inside it.
|
|
228
|
+
- `AvatarGroup` cascades `size`/`shape`/`variant` to nested `Avatar`s (and `size`/`shape` to `AvatarGroupAction`) via context: set them once on the group, never per child.
|
|
229
|
+
- `AvatarBadge*` content components must sit inside `AvatarBadge` (it does the corner positioning) and auto-size from the surrounding avatar's size (2xs/xs -> xs, sm/md -> sm, lg/xl -> md, 2xl -> lg); pass `size` only to break that pairing.
|
|
230
|
+
- `AvatarRing` draws OUTSIDE the avatar's box via negative margin (stroke and gap scale with the avatar's size), so leave layout room around it; `variant="full"` ignores `value`, and `progress` clamps `value` to 0-100.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<!-- GENERATED FILE - do not edit. Source: registry/ui/badge.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/badge.md -->
|
|
2
|
+
|
|
3
|
+
# badge
|
|
4
|
+
|
|
5
|
+
Passive non-interactive label for statuses and counts; leadingIcon, trailingIcon, iconOnly and numberOnly props
|
|
6
|
+
|
|
7
|
+
Install: `npx @create-ui/cli add badge`
|
|
8
|
+
|
|
9
|
+
## Import
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { Badge } from "@/components/ui/badge"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Also exported: `badgeVariants`
|
|
16
|
+
|
|
17
|
+
## Badge props
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| variant | `primary \| neutral \| neutral-static \| danger \| success \| warning \| info \| verified \| highlighted \| away \| inverse \| inverse-static` | `primary` |
|
|
22
|
+
| appearance | `solid \| outline \| soft \| ghost` | `soft` |
|
|
23
|
+
| size | `xs \| sm \| md` | `sm` |
|
|
24
|
+
| shape | `rounded \| pill` | `rounded` |
|
|
25
|
+
| iconOnly | `boolean` (square badge; the icon is the children (NOT leadingIcon); pair with aria-label) | `false` |
|
|
26
|
+
| numberOnly | `boolean` (count style with per-size min-width; children is the numeral) | `false` |
|
|
27
|
+
| asChild | `boolean` (child renders as-is: icon props and the badge-label wrapper are dropped, root classes stay) | `false` |
|
|
28
|
+
| disabled | `boolean` (visual only via data-disabled (muted text, pointer-events-none); renders a span, no HTML disabled attribute) | `false` |
|
|
29
|
+
| leadingIcon | `ReactNode` | - |
|
|
30
|
+
| trailingIcon | `ReactNode` | - |
|
|
31
|
+
|
|
32
|
+
Extends `React.ComponentProps<"span">`.
|
|
33
|
+
|
|
34
|
+
## Icons
|
|
35
|
+
|
|
36
|
+
Icons go through icon props - never as children next to text, and never with sizing classes (the component sizes icons per `size`): `Badge` (`leadingIcon` / `trailingIcon`). Import icons from `@create-ui/assets/icons` (Remix `Ri*`).
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
From `badge-demo`:
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { RiCheckLine, RiSparklingFill } from "@create-ui/assets/icons"
|
|
44
|
+
|
|
45
|
+
import { Badge } from "@/components/ui/badge"
|
|
46
|
+
|
|
47
|
+
export default function BadgeDemo() {
|
|
48
|
+
return (
|
|
49
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
50
|
+
<Badge>New</Badge>
|
|
51
|
+
<Badge variant="success" leadingIcon={<RiCheckLine />}>
|
|
52
|
+
Verified
|
|
53
|
+
</Badge>
|
|
54
|
+
<Badge variant="warning">Pending</Badge>
|
|
55
|
+
<Badge variant="danger" appearance="solid">
|
|
56
|
+
Down
|
|
57
|
+
</Badge>
|
|
58
|
+
<Badge variant="primary" iconOnly aria-label="Sparkle">
|
|
59
|
+
<RiSparklingFill />
|
|
60
|
+
</Badge>
|
|
61
|
+
<Badge variant="danger" numberOnly>
|
|
62
|
+
12
|
|
63
|
+
</Badge>
|
|
64
|
+
</div>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
From `badge-with-icon`:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { RiArrowRightLine, RiSparklingFill } from "@create-ui/assets/icons"
|
|
73
|
+
|
|
74
|
+
import { Badge } from "@/components/ui/badge"
|
|
75
|
+
|
|
76
|
+
export default function BadgeWithIcon() {
|
|
77
|
+
return (
|
|
78
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
79
|
+
<Badge variant="primary" leadingIcon={<RiSparklingFill />}>
|
|
80
|
+
Leading
|
|
81
|
+
</Badge>
|
|
82
|
+
<Badge variant="primary" trailingIcon={<RiArrowRightLine />}>
|
|
83
|
+
Trailing
|
|
84
|
+
</Badge>
|
|
85
|
+
<Badge
|
|
86
|
+
variant="primary"
|
|
87
|
+
leadingIcon={<RiSparklingFill />}
|
|
88
|
+
trailingIcon={<RiArrowRightLine />}
|
|
89
|
+
>
|
|
90
|
+
Both
|
|
91
|
+
</Badge>
|
|
92
|
+
</div>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
More: `npx @create-ui/cli view badge` or MCP `get_item_examples_from_registries` with "badge-demo" / "badge-example".
|
|
98
|
+
|
|
99
|
+
## When to use
|
|
100
|
+
|
|
101
|
+
Passive, non-interactive labels: statuses, counts, metadata. Interactive or removable tags are `Chip`; bare presence dots are `StatusBadge`; anything clickable is `Button`; callouts with title and body are `InlineAlert`.
|
|
102
|
+
|
|
103
|
+
## Gotchas
|
|
104
|
+
|
|
105
|
+
- Color and fill are separate axes, unlike shadcn: `variant` is color only, `appearance` is fill. shadcn's `variant="outline"` is `appearance="outline"` here, and `variant="destructive"` is `variant="danger"`; there is no `secondary`.
|
|
106
|
+
- With text, icons go ONLY through `leadingIcon` / `trailingIcon`, never as children. `iconOnly` inverts this: the icon IS the children (same convention as Button).
|
|
107
|
+
- `iconOnly` and `numberOnly` render children only; any `leadingIcon` / `trailingIcon` passed alongside them is silently ignored.
|
|
108
|
+
- `asChild` skips the content pipeline (icon props, the `badge-label` wrapper); the styled root classes still apply, so the child element must carry its full content itself.
|
|
109
|
+
- The root is `w-fit`, so it never stretches in a flex column. Need full width? That is almost always the wrong component.
|
|
110
|
+
- `appearance="ghost"` strips both the background and the horizontal padding (`px-0`), so it sits flush with surrounding content.
|