@neynar/ui 1.0.1 → 1.0.2
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/context7.json +17 -0
- package/llm/components/accordion.llm.md +205 -0
- package/llm/components/alert-dialog.llm.md +289 -0
- package/llm/components/alert.llm.md +310 -0
- package/llm/components/aspect-ratio.llm.md +110 -0
- package/llm/components/avatar.llm.md +282 -0
- package/llm/components/badge.llm.md +185 -0
- package/llm/components/blockquote.llm.md +86 -0
- package/llm/components/breadcrumb.llm.md +245 -0
- package/llm/components/button-group.llm.md +248 -0
- package/llm/components/button.llm.md +247 -0
- package/llm/components/calendar.llm.md +252 -0
- package/llm/components/card.llm.md +356 -0
- package/llm/components/carousel.llm.md +281 -0
- package/llm/components/chart.llm.md +278 -0
- package/llm/components/checkbox.llm.md +234 -0
- package/llm/components/code.llm.md +75 -0
- package/llm/components/collapsible.llm.md +271 -0
- package/llm/components/color-mode.llm.md +196 -0
- package/llm/components/combobox.llm.md +346 -0
- package/llm/components/command.llm.md +353 -0
- package/llm/components/context-menu.llm.md +368 -0
- package/llm/components/dialog.llm.md +283 -0
- package/llm/components/drawer.llm.md +326 -0
- package/llm/components/dropdown-menu.llm.md +404 -0
- package/llm/components/empty.llm.md +282 -0
- package/llm/components/field.llm.md +303 -0
- package/llm/components/first-light.llm.md +129 -0
- package/llm/components/hover-card.llm.md +278 -0
- package/llm/components/input-group.llm.md +334 -0
- package/llm/components/input-otp.llm.md +270 -0
- package/llm/components/input.llm.md +197 -0
- package/llm/components/item.llm.md +347 -0
- package/llm/components/kbd.llm.md +221 -0
- package/llm/components/label.llm.md +219 -0
- package/llm/components/menubar.llm.md +378 -0
- package/llm/components/navigation-menu.llm.md +320 -0
- package/llm/components/pagination.llm.md +337 -0
- package/llm/components/popover.llm.md +278 -0
- package/llm/components/progress.llm.md +259 -0
- package/llm/components/radio-group.llm.md +269 -0
- package/llm/components/resizable.llm.md +222 -0
- package/llm/components/scroll-area.llm.md +290 -0
- package/llm/components/select.llm.md +338 -0
- package/llm/components/separator.llm.md +129 -0
- package/llm/components/sheet.llm.md +275 -0
- package/llm/components/sidebar.llm.md +528 -0
- package/llm/components/skeleton.llm.md +140 -0
- package/llm/components/slider.llm.md +213 -0
- package/llm/components/sonner.llm.md +299 -0
- package/llm/components/spinner.llm.md +187 -0
- package/llm/components/switch.llm.md +258 -0
- package/llm/components/table.llm.md +334 -0
- package/llm/components/tabs.llm.md +245 -0
- package/llm/components/text.llm.md +108 -0
- package/llm/components/textarea.llm.md +236 -0
- package/llm/components/title.llm.md +88 -0
- package/llm/components/toggle-group.llm.md +228 -0
- package/llm/components/toggle.llm.md +235 -0
- package/llm/components/tooltip.llm.md +191 -0
- package/llm/contributing.llm.md +273 -0
- package/llm/hooks.llm.md +91 -0
- package/llm/index.llm.md +178 -0
- package/llm/theming.llm.md +381 -0
- package/llm/utilities.llm.md +97 -0
- package/llms-full.txt +15995 -0
- package/llms.txt +182 -0
- package/package.json +5 -1
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Input
|
|
2
|
+
|
|
3
|
+
Text input field with support for all HTML input types.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Input } from "@neynar/ui/input"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Input type="text" placeholder="Enter text..." />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Props
|
|
18
|
+
|
|
19
|
+
All standard HTML input attributes are supported via `React.ComponentProps<"input">`:
|
|
20
|
+
|
|
21
|
+
| Prop | Type | Default | Description |
|
|
22
|
+
|------|------|---------|-------------|
|
|
23
|
+
| type | string | "text" | HTML input type (text, email, password, number, tel, url, search, date, time, file, etc.) |
|
|
24
|
+
| placeholder | string | - | Placeholder text |
|
|
25
|
+
| value | string | - | Controlled input value |
|
|
26
|
+
| defaultValue | string | - | Uncontrolled default value |
|
|
27
|
+
| disabled | boolean | false | Disable the input |
|
|
28
|
+
| readOnly | boolean | false | Make input read-only |
|
|
29
|
+
| required | boolean | false | Mark as required field |
|
|
30
|
+
| aria-invalid | boolean | false | Show validation error styling |
|
|
31
|
+
| className | string | - | Additional CSS classes |
|
|
32
|
+
|
|
33
|
+
### Validation Styling
|
|
34
|
+
|
|
35
|
+
Set `aria-invalid="true"` to show error state with red border and ring:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
<Input aria-invalid="true" />
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Data Attributes
|
|
42
|
+
|
|
43
|
+
| Attribute | When Present |
|
|
44
|
+
|-----------|--------------|
|
|
45
|
+
| data-slot | Always "input" for styling hooks |
|
|
46
|
+
|
|
47
|
+
## Examples
|
|
48
|
+
|
|
49
|
+
### Basic Text Input
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
<div className="space-y-2">
|
|
53
|
+
<Label htmlFor="name">Name</Label>
|
|
54
|
+
<Input id="name" placeholder="Enter your name" />
|
|
55
|
+
</div>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Email Input with Validation
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
function EmailInput() {
|
|
62
|
+
const [email, setEmail] = useState("")
|
|
63
|
+
const [error, setError] = useState(false)
|
|
64
|
+
|
|
65
|
+
const handleBlur = () => {
|
|
66
|
+
if (email && !email.includes("@")) {
|
|
67
|
+
setError(true)
|
|
68
|
+
} else {
|
|
69
|
+
setError(false)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div className="space-y-2">
|
|
75
|
+
<Label htmlFor="email">Email</Label>
|
|
76
|
+
<Input
|
|
77
|
+
id="email"
|
|
78
|
+
type="email"
|
|
79
|
+
placeholder="your@email.com"
|
|
80
|
+
value={email}
|
|
81
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
82
|
+
onBlur={handleBlur}
|
|
83
|
+
aria-invalid={error}
|
|
84
|
+
/>
|
|
85
|
+
{error && (
|
|
86
|
+
<p className="text-sm text-destructive">
|
|
87
|
+
Please enter a valid email address
|
|
88
|
+
</p>
|
|
89
|
+
)}
|
|
90
|
+
</div>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Number Input
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<div className="space-y-2">
|
|
99
|
+
<Label htmlFor="engagement">Min Engagement</Label>
|
|
100
|
+
<Input
|
|
101
|
+
id="engagement"
|
|
102
|
+
type="number"
|
|
103
|
+
placeholder="e.g., 100"
|
|
104
|
+
min="0"
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Password Input
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
<div className="space-y-2">
|
|
113
|
+
<Label htmlFor="password">Password</Label>
|
|
114
|
+
<Input
|
|
115
|
+
id="password"
|
|
116
|
+
type="password"
|
|
117
|
+
placeholder="••••••••"
|
|
118
|
+
/>
|
|
119
|
+
</div>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Date Input
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
<div className="space-y-2">
|
|
126
|
+
<Label htmlFor="start-date">Start Date</Label>
|
|
127
|
+
<Input
|
|
128
|
+
id="start-date"
|
|
129
|
+
type="date"
|
|
130
|
+
/>
|
|
131
|
+
</div>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### File Upload
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
<div className="space-y-2">
|
|
138
|
+
<Label htmlFor="file">Upload File</Label>
|
|
139
|
+
<Input
|
|
140
|
+
id="file"
|
|
141
|
+
type="file"
|
|
142
|
+
accept="image/*"
|
|
143
|
+
multiple
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Disabled State
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
<Input placeholder="Disabled input" disabled />
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Read Only State
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<Input defaultValue="Read only value" readOnly />
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### With Helper Text
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
<div className="space-y-2">
|
|
164
|
+
<Label htmlFor="username">Username</Label>
|
|
165
|
+
<Input id="username" placeholder="Enter username" />
|
|
166
|
+
<p className="text-sm text-muted-foreground">
|
|
167
|
+
Choose a unique username
|
|
168
|
+
</p>
|
|
169
|
+
</div>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Keyboard
|
|
173
|
+
|
|
174
|
+
Standard HTML input keyboard behavior:
|
|
175
|
+
|
|
176
|
+
| Key | Action |
|
|
177
|
+
|-----|--------|
|
|
178
|
+
| Tab | Move focus to next field |
|
|
179
|
+
| Shift+Tab | Move focus to previous field |
|
|
180
|
+
| Enter | Submit form (if in form) |
|
|
181
|
+
| Escape | Clear value (browser default) |
|
|
182
|
+
|
|
183
|
+
## Accessibility
|
|
184
|
+
|
|
185
|
+
- Wraps Base UI `Input` component with full keyboard and screen reader support
|
|
186
|
+
- Use with `Label` component for proper associations via `htmlFor` and `id`
|
|
187
|
+
- Set `aria-invalid="true"` for validation errors
|
|
188
|
+
- Use `required` attribute for required fields
|
|
189
|
+
- Include helper text with validation messages below the input
|
|
190
|
+
|
|
191
|
+
## Related
|
|
192
|
+
|
|
193
|
+
- [InputGroup](./input-group.llm.md) - For inputs with icons, buttons, or text addons
|
|
194
|
+
- [Label](./label.llm.md) - For accessible input labels
|
|
195
|
+
- [Textarea](./textarea.llm.md) - For multi-line text input
|
|
196
|
+
- [Select](./select.llm.md) - For dropdown selection
|
|
197
|
+
- [Combobox](./combobox.llm.md) - For searchable select with autocomplete
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
# Item
|
|
2
|
+
|
|
3
|
+
Flexible compound component system for building structured list items with media, content, and actions.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import {
|
|
9
|
+
Item,
|
|
10
|
+
ItemGroup,
|
|
11
|
+
ItemSeparator,
|
|
12
|
+
ItemMedia,
|
|
13
|
+
ItemContent,
|
|
14
|
+
ItemTitle,
|
|
15
|
+
ItemDescription,
|
|
16
|
+
ItemActions,
|
|
17
|
+
ItemHeader,
|
|
18
|
+
ItemFooter,
|
|
19
|
+
} from "@neynar/ui/item"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Anatomy
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
<ItemGroup>
|
|
26
|
+
<Item>
|
|
27
|
+
<ItemMedia variant="icon">
|
|
28
|
+
<Icon />
|
|
29
|
+
</ItemMedia>
|
|
30
|
+
<ItemContent>
|
|
31
|
+
<ItemTitle>Title</ItemTitle>
|
|
32
|
+
<ItemDescription>Description text</ItemDescription>
|
|
33
|
+
</ItemContent>
|
|
34
|
+
<ItemActions>
|
|
35
|
+
<Button />
|
|
36
|
+
</ItemActions>
|
|
37
|
+
</Item>
|
|
38
|
+
</ItemGroup>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Components
|
|
42
|
+
|
|
43
|
+
| Component | Description |
|
|
44
|
+
|-----------|-------------|
|
|
45
|
+
| ItemGroup | Container for organizing related items in a vertical list |
|
|
46
|
+
| Item | Root item component, supports `render` prop for custom elements |
|
|
47
|
+
| ItemSeparator | Horizontal divider between items |
|
|
48
|
+
| ItemMedia | Container for icons, images, or avatars |
|
|
49
|
+
| ItemContent | Main content area that flexes to fill space |
|
|
50
|
+
| ItemTitle | Medium-weight title text with badge support |
|
|
51
|
+
| ItemDescription | Secondary description text (truncates at 2 lines) |
|
|
52
|
+
| ItemActions | Container for buttons or controls |
|
|
53
|
+
| ItemHeader | Full-width header for complex layouts |
|
|
54
|
+
| ItemFooter | Full-width footer for additional info |
|
|
55
|
+
|
|
56
|
+
## Props
|
|
57
|
+
|
|
58
|
+
### Item
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Description |
|
|
61
|
+
|------|------|---------|-------------|
|
|
62
|
+
| variant | "default" \| "outline" \| "muted" | "default" | Visual style variant |
|
|
63
|
+
| size | "default" \| "sm" \| "xs" | "default" | Size affecting padding and spacing |
|
|
64
|
+
| render | ReactNode | - | Custom element to render as (e.g., `<a>`, `<button>`) |
|
|
65
|
+
|
|
66
|
+
### ItemMedia
|
|
67
|
+
|
|
68
|
+
| Prop | Type | Default | Description |
|
|
69
|
+
|------|------|---------|-------------|
|
|
70
|
+
| variant | "default" \| "icon" \| "image" | "default" | Media type determining sizing and layout |
|
|
71
|
+
|
|
72
|
+
**Behavior**: Automatically aligns to top when `ItemDescription` is present using CSS container queries.
|
|
73
|
+
|
|
74
|
+
### ItemGroup
|
|
75
|
+
|
|
76
|
+
Container with `role="list"` that automatically adjusts gap based on child item sizes:
|
|
77
|
+
- `size="default"`: gap-4
|
|
78
|
+
- `size="sm"`: gap-2.5
|
|
79
|
+
- `size="xs"`: gap-2
|
|
80
|
+
|
|
81
|
+
### render Prop (Item)
|
|
82
|
+
|
|
83
|
+
Customize the underlying HTML element:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
// Render as link
|
|
87
|
+
<Item render={<a href="/profile" />}>
|
|
88
|
+
<ItemContent>
|
|
89
|
+
<ItemTitle>View Profile</ItemTitle>
|
|
90
|
+
</ItemContent>
|
|
91
|
+
</Item>
|
|
92
|
+
|
|
93
|
+
// Render as button
|
|
94
|
+
<Item render={<button onClick={handleClick} />}>
|
|
95
|
+
<ItemContent>
|
|
96
|
+
<ItemTitle>Clickable Item</ItemTitle>
|
|
97
|
+
</ItemContent>
|
|
98
|
+
</Item>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Data Attributes
|
|
102
|
+
|
|
103
|
+
| Attribute | When Present | Used By |
|
|
104
|
+
|-----------|--------------|---------|
|
|
105
|
+
| data-slot="item" | Always | Item component |
|
|
106
|
+
| data-slot="item-media" | Always | ItemMedia component |
|
|
107
|
+
| data-slot="item-content" | Always | ItemContent component |
|
|
108
|
+
| data-slot="item-title" | Always | ItemTitle component |
|
|
109
|
+
| data-slot="item-description" | Always | ItemDescription component |
|
|
110
|
+
| data-slot="item-actions" | Always | ItemActions component |
|
|
111
|
+
| data-slot="item-header" | Always | ItemHeader component |
|
|
112
|
+
| data-slot="item-footer" | Always | ItemFooter component |
|
|
113
|
+
| data-slot="item-separator" | Always | ItemSeparator component |
|
|
114
|
+
| data-variant | Always | ItemMedia (icon/image/default) |
|
|
115
|
+
|
|
116
|
+
## Variants
|
|
117
|
+
|
|
118
|
+
### Visual Variants
|
|
119
|
+
|
|
120
|
+
| Variant | Description |
|
|
121
|
+
|---------|-------------|
|
|
122
|
+
| default | Clean appearance with transparent border |
|
|
123
|
+
| outline | Visible border for clear separation |
|
|
124
|
+
| muted | Subtle background (bg-muted/50) for grouped items |
|
|
125
|
+
|
|
126
|
+
### Size Variants
|
|
127
|
+
|
|
128
|
+
| Size | Padding | Gap | Use Case |
|
|
129
|
+
|------|---------|-----|----------|
|
|
130
|
+
| default | py-3.5 px-4 | gap-3.5 | Regular content, standard lists |
|
|
131
|
+
| sm | py-2.5 px-3 | gap-2.5 | Compact layouts, sidebars |
|
|
132
|
+
| xs | py-2 px-2.5 | gap-2 | Dense lists, activity feeds |
|
|
133
|
+
|
|
134
|
+
### Media Variants
|
|
135
|
+
|
|
136
|
+
| Variant | Size | Description |
|
|
137
|
+
|---------|------|-------------|
|
|
138
|
+
| default | auto | Transparent background, flex container |
|
|
139
|
+
| icon | auto | Auto-sizes SVG icons to size-4 |
|
|
140
|
+
| image | size-10 (default) | Fixed container with rounded corners, scales to size-8 (sm) and size-6 (xs) |
|
|
141
|
+
|
|
142
|
+
## Examples
|
|
143
|
+
|
|
144
|
+
### Basic List Item
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
<ItemGroup>
|
|
148
|
+
<Item variant="outline">
|
|
149
|
+
<ItemMedia variant="icon">
|
|
150
|
+
<KeyIcon />
|
|
151
|
+
</ItemMedia>
|
|
152
|
+
<ItemContent>
|
|
153
|
+
<ItemTitle>API Key</ItemTitle>
|
|
154
|
+
<ItemDescription>Production key created 3 months ago</ItemDescription>
|
|
155
|
+
</ItemContent>
|
|
156
|
+
<ItemActions>
|
|
157
|
+
<Button variant="ghost" size="icon-sm">
|
|
158
|
+
<CopyIcon />
|
|
159
|
+
</Button>
|
|
160
|
+
</ItemActions>
|
|
161
|
+
</Item>
|
|
162
|
+
</ItemGroup>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### With Status Badge
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<Item variant="outline">
|
|
169
|
+
<ItemMedia variant="icon">
|
|
170
|
+
<WebhookIcon className="text-green-500" />
|
|
171
|
+
</ItemMedia>
|
|
172
|
+
<ItemContent>
|
|
173
|
+
<ItemTitle>
|
|
174
|
+
Production Webhook
|
|
175
|
+
<Badge variant="secondary">Active</Badge>
|
|
176
|
+
</ItemTitle>
|
|
177
|
+
<ItemDescription>https://api.example.com/webhooks/neynar</ItemDescription>
|
|
178
|
+
</ItemContent>
|
|
179
|
+
<ItemActions>
|
|
180
|
+
<Button variant="ghost">Test</Button>
|
|
181
|
+
</ItemActions>
|
|
182
|
+
</Item>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Complex Layout with Header/Footer
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
<Item variant="muted">
|
|
189
|
+
<ItemMedia variant="icon">
|
|
190
|
+
<WebhookIcon />
|
|
191
|
+
</ItemMedia>
|
|
192
|
+
<ItemContent>
|
|
193
|
+
<ItemHeader>
|
|
194
|
+
<div className="flex flex-col gap-1">
|
|
195
|
+
<ItemTitle>
|
|
196
|
+
Staging Webhook
|
|
197
|
+
<Badge variant="destructive">Failed</Badge>
|
|
198
|
+
</ItemTitle>
|
|
199
|
+
<ItemDescription>https://staging.example.com/webhooks</ItemDescription>
|
|
200
|
+
</div>
|
|
201
|
+
<ItemActions>
|
|
202
|
+
<Button variant="ghost">Retry</Button>
|
|
203
|
+
</ItemActions>
|
|
204
|
+
</ItemHeader>
|
|
205
|
+
<ItemFooter className="border-border w-full border-t pt-2">
|
|
206
|
+
<div className="flex items-center gap-2 text-sm">
|
|
207
|
+
<XCircleIcon className="text-red-500 size-4" />
|
|
208
|
+
<span className="text-muted-foreground">Last failure: Connection timeout (5xx)</span>
|
|
209
|
+
</div>
|
|
210
|
+
</ItemFooter>
|
|
211
|
+
</ItemContent>
|
|
212
|
+
</Item>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Team Member with Avatar
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
<Item>
|
|
219
|
+
<ItemMedia variant="icon">
|
|
220
|
+
<div className="bg-primary/10 text-primary flex size-10 items-center justify-center rounded-full text-sm font-semibold">
|
|
221
|
+
JD
|
|
222
|
+
</div>
|
|
223
|
+
</ItemMedia>
|
|
224
|
+
<ItemContent>
|
|
225
|
+
<ItemTitle>
|
|
226
|
+
Jane Doe
|
|
227
|
+
<Badge variant="outline">Owner</Badge>
|
|
228
|
+
</ItemTitle>
|
|
229
|
+
<ItemDescription>jane.doe@example.com • Full access to all resources</ItemDescription>
|
|
230
|
+
</ItemContent>
|
|
231
|
+
<ItemActions>
|
|
232
|
+
<Button variant="ghost" size="icon-sm">
|
|
233
|
+
<MoreHorizontalIcon />
|
|
234
|
+
</Button>
|
|
235
|
+
</ItemActions>
|
|
236
|
+
</Item>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Activity Feed (Compact)
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
<ItemGroup>
|
|
243
|
+
<Item size="xs">
|
|
244
|
+
<ItemMedia variant="icon">
|
|
245
|
+
<CheckCircle2Icon className="text-green-500 size-4" />
|
|
246
|
+
</ItemMedia>
|
|
247
|
+
<ItemContent>
|
|
248
|
+
<ItemTitle>API key created</ItemTitle>
|
|
249
|
+
<ItemDescription>Production key created by jane.doe@example.com</ItemDescription>
|
|
250
|
+
</ItemContent>
|
|
251
|
+
<ItemContent>
|
|
252
|
+
<div className="text-muted-foreground flex items-center gap-1 text-xs">
|
|
253
|
+
<ClockIcon className="size-3" />
|
|
254
|
+
2 hours ago
|
|
255
|
+
</div>
|
|
256
|
+
</ItemContent>
|
|
257
|
+
</Item>
|
|
258
|
+
</ItemGroup>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Document List with Images
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
<Item variant="outline">
|
|
265
|
+
<ItemMedia variant="image">
|
|
266
|
+
<div className="bg-gradient-to-br from-purple-500 to-pink-500 flex size-full items-center justify-center">
|
|
267
|
+
<FileIcon className="text-white size-6" />
|
|
268
|
+
</div>
|
|
269
|
+
</ItemMedia>
|
|
270
|
+
<ItemContent>
|
|
271
|
+
<ItemTitle>API Documentation.pdf</ItemTitle>
|
|
272
|
+
<ItemDescription>Last modified 3 days ago • 2.4 MB</ItemDescription>
|
|
273
|
+
</ItemContent>
|
|
274
|
+
<ItemActions>
|
|
275
|
+
<Button variant="ghost">Download</Button>
|
|
276
|
+
<Button variant="ghost" size="icon-sm">
|
|
277
|
+
<ChevronRightIcon />
|
|
278
|
+
</Button>
|
|
279
|
+
</ItemActions>
|
|
280
|
+
</Item>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### List with Separators
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
<ItemGroup>
|
|
287
|
+
<Item variant="muted">
|
|
288
|
+
<ItemContent>
|
|
289
|
+
<ItemTitle>First Item</ItemTitle>
|
|
290
|
+
</ItemContent>
|
|
291
|
+
</Item>
|
|
292
|
+
|
|
293
|
+
<ItemSeparator />
|
|
294
|
+
|
|
295
|
+
<Item variant="muted">
|
|
296
|
+
<ItemContent>
|
|
297
|
+
<ItemTitle>Second Item</ItemTitle>
|
|
298
|
+
</ItemContent>
|
|
299
|
+
</Item>
|
|
300
|
+
</ItemGroup>
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Accessibility
|
|
304
|
+
|
|
305
|
+
- ItemGroup renders with `role="list"` for semantic list structure
|
|
306
|
+
- Focus ring styles on Item when using `render` prop with interactive elements
|
|
307
|
+
- ItemDescription automatically truncates with `line-clamp-2` to prevent excessive text
|
|
308
|
+
- Links within ItemDescription receive underline and hover styles
|
|
309
|
+
- All interactive elements maintain proper focus indicators
|
|
310
|
+
|
|
311
|
+
## Composition Patterns
|
|
312
|
+
|
|
313
|
+
### Multiple Content Areas
|
|
314
|
+
|
|
315
|
+
Use multiple `ItemContent` components for side-by-side content sections:
|
|
316
|
+
|
|
317
|
+
```tsx
|
|
318
|
+
<Item>
|
|
319
|
+
<ItemContent>
|
|
320
|
+
<ItemTitle>Main Content</ItemTitle>
|
|
321
|
+
<ItemDescription>Primary description</ItemDescription>
|
|
322
|
+
</ItemContent>
|
|
323
|
+
<ItemContent>
|
|
324
|
+
<div className="text-muted-foreground text-xs">2 hours ago</div>
|
|
325
|
+
</ItemContent>
|
|
326
|
+
</Item>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
The first `ItemContent` flexes to fill space, subsequent ones use `flex-none`.
|
|
330
|
+
|
|
331
|
+
### Icon with Background
|
|
332
|
+
|
|
333
|
+
Wrap icons in colored containers for visual emphasis:
|
|
334
|
+
|
|
335
|
+
```tsx
|
|
336
|
+
<ItemMedia variant="icon">
|
|
337
|
+
<div className="bg-primary/10 text-primary rounded-md p-2">
|
|
338
|
+
<KeyIcon className="size-5" />
|
|
339
|
+
</div>
|
|
340
|
+
</ItemMedia>
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Related
|
|
344
|
+
|
|
345
|
+
- [Button](/components/button) - For ItemActions controls
|
|
346
|
+
- [Badge](/components/badge) - For status indicators in titles
|
|
347
|
+
- [Separator](/components/separator) - Used by ItemSeparator
|