@neynar/ui 1.0.0 → 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.
Files changed (69) hide show
  1. package/README.md +1 -1
  2. package/context7.json +17 -0
  3. package/llm/components/accordion.llm.md +205 -0
  4. package/llm/components/alert-dialog.llm.md +289 -0
  5. package/llm/components/alert.llm.md +310 -0
  6. package/llm/components/aspect-ratio.llm.md +110 -0
  7. package/llm/components/avatar.llm.md +282 -0
  8. package/llm/components/badge.llm.md +185 -0
  9. package/llm/components/blockquote.llm.md +86 -0
  10. package/llm/components/breadcrumb.llm.md +245 -0
  11. package/llm/components/button-group.llm.md +248 -0
  12. package/llm/components/button.llm.md +247 -0
  13. package/llm/components/calendar.llm.md +252 -0
  14. package/llm/components/card.llm.md +356 -0
  15. package/llm/components/carousel.llm.md +281 -0
  16. package/llm/components/chart.llm.md +278 -0
  17. package/llm/components/checkbox.llm.md +234 -0
  18. package/llm/components/code.llm.md +75 -0
  19. package/llm/components/collapsible.llm.md +271 -0
  20. package/llm/components/color-mode.llm.md +196 -0
  21. package/llm/components/combobox.llm.md +346 -0
  22. package/llm/components/command.llm.md +353 -0
  23. package/llm/components/context-menu.llm.md +368 -0
  24. package/llm/components/dialog.llm.md +283 -0
  25. package/llm/components/drawer.llm.md +326 -0
  26. package/llm/components/dropdown-menu.llm.md +404 -0
  27. package/llm/components/empty.llm.md +282 -0
  28. package/llm/components/field.llm.md +303 -0
  29. package/llm/components/first-light.llm.md +129 -0
  30. package/llm/components/hover-card.llm.md +278 -0
  31. package/llm/components/input-group.llm.md +334 -0
  32. package/llm/components/input-otp.llm.md +270 -0
  33. package/llm/components/input.llm.md +197 -0
  34. package/llm/components/item.llm.md +347 -0
  35. package/llm/components/kbd.llm.md +221 -0
  36. package/llm/components/label.llm.md +219 -0
  37. package/llm/components/menubar.llm.md +378 -0
  38. package/llm/components/navigation-menu.llm.md +320 -0
  39. package/llm/components/pagination.llm.md +337 -0
  40. package/llm/components/popover.llm.md +278 -0
  41. package/llm/components/progress.llm.md +259 -0
  42. package/llm/components/radio-group.llm.md +269 -0
  43. package/llm/components/resizable.llm.md +222 -0
  44. package/llm/components/scroll-area.llm.md +290 -0
  45. package/llm/components/select.llm.md +338 -0
  46. package/llm/components/separator.llm.md +129 -0
  47. package/llm/components/sheet.llm.md +275 -0
  48. package/llm/components/sidebar.llm.md +528 -0
  49. package/llm/components/skeleton.llm.md +140 -0
  50. package/llm/components/slider.llm.md +213 -0
  51. package/llm/components/sonner.llm.md +299 -0
  52. package/llm/components/spinner.llm.md +187 -0
  53. package/llm/components/switch.llm.md +258 -0
  54. package/llm/components/table.llm.md +334 -0
  55. package/llm/components/tabs.llm.md +245 -0
  56. package/llm/components/text.llm.md +108 -0
  57. package/llm/components/textarea.llm.md +236 -0
  58. package/llm/components/title.llm.md +88 -0
  59. package/llm/components/toggle-group.llm.md +228 -0
  60. package/llm/components/toggle.llm.md +235 -0
  61. package/llm/components/tooltip.llm.md +191 -0
  62. package/llm/contributing.llm.md +273 -0
  63. package/llm/hooks.llm.md +91 -0
  64. package/llm/index.llm.md +178 -0
  65. package/llm/theming.llm.md +381 -0
  66. package/llm/utilities.llm.md +97 -0
  67. package/llms-full.txt +15995 -0
  68. package/llms.txt +182 -0
  69. package/package.json +6 -2
@@ -0,0 +1,245 @@
1
+ # Tabs
2
+
3
+ Organize content into multiple panels with tab navigation, supporting both horizontal and vertical layouts.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Tabs, TabsList, TabsTrigger, TabsContent } from "@neynar/ui/tabs"
9
+ ```
10
+
11
+ ## Anatomy
12
+
13
+ ```tsx
14
+ <Tabs defaultValue="tab1">
15
+ <TabsList>
16
+ <TabsTrigger value="tab1">Tab 1</TabsTrigger>
17
+ <TabsTrigger value="tab2">Tab 2</TabsTrigger>
18
+ </TabsList>
19
+ <TabsContent value="tab1">Content 1</TabsContent>
20
+ <TabsContent value="tab2">Content 2</TabsContent>
21
+ </Tabs>
22
+ ```
23
+
24
+ ## Components
25
+
26
+ | Component | Description |
27
+ |-----------|-------------|
28
+ | Tabs | Root container, manages active tab state and orientation |
29
+ | TabsList | Groups tab triggers, controls visual variant |
30
+ | TabsTrigger | Individual tab button with value identifier |
31
+ | TabsContent | Content panel shown when corresponding tab is active |
32
+
33
+ ## Props
34
+
35
+ ### Tabs
36
+
37
+ | Prop | Type | Default | Description |
38
+ |------|------|---------|-------------|
39
+ | defaultValue | string \| number \| null | `0` | Initial active tab (uncontrolled) |
40
+ | value | string \| number \| null | - | Controlled active tab value |
41
+ | onValueChange | (value, eventDetails) => void | - | Called when active tab changes |
42
+ | orientation | "horizontal" \| "vertical" | "horizontal" | Layout direction |
43
+
44
+ When `value` is `null`, no tab will be active.
45
+
46
+ ### TabsList
47
+
48
+ | Prop | Type | Default | Description |
49
+ |------|------|---------|-------------|
50
+ | variant | "default" \| "line" | "default" | Visual style of tab list |
51
+ | activateOnFocus | boolean | - | Auto-activate tab on arrow key focus |
52
+ | loopFocus | boolean | - | Loop keyboard focus at list ends |
53
+
54
+ **Variants:**
55
+ - `default` - Tabs with muted background and active highlight
56
+ - `line` - Minimal tabs with underline indicator on active tab
57
+
58
+ ### TabsTrigger
59
+
60
+ | Prop | Type | Default | Description |
61
+ |------|------|---------|-------------|
62
+ | value | string \| number | - | Identifier matching TabsContent value |
63
+ | disabled | boolean | - | Prevents tab activation |
64
+
65
+ Supports nested icons and badges as children.
66
+
67
+ ### TabsContent
68
+
69
+ | Prop | Type | Default | Description |
70
+ |------|------|---------|-------------|
71
+ | value | string \| number | - | Identifier matching TabsTrigger value |
72
+ | keepMounted | boolean | false | Keep DOM element when hidden |
73
+
74
+ ## Data Attributes
75
+
76
+ ### Tabs, TabsList
77
+
78
+ | Attribute | When Present |
79
+ |-----------|--------------|
80
+ | data-orientation | "horizontal" or "vertical" |
81
+ | data-activation-direction | "left", "right", "up", "down", or "none" |
82
+
83
+ ### TabsTrigger
84
+
85
+ | Attribute | When Present |
86
+ |-----------|--------------|
87
+ | data-active | Tab is currently active |
88
+ | data-disabled | Tab is disabled |
89
+
90
+ ### TabsContent
91
+
92
+ | Attribute | When Present |
93
+ |-----------|--------------|
94
+ | data-hidden | Panel is not active |
95
+ | data-index | Panel index number |
96
+
97
+ ## Examples
98
+
99
+ ### Basic Usage
100
+
101
+ ```tsx
102
+ <Tabs defaultValue="account">
103
+ <TabsList>
104
+ <TabsTrigger value="account">Account</TabsTrigger>
105
+ <TabsTrigger value="password">Password</TabsTrigger>
106
+ </TabsList>
107
+ <TabsContent value="account">
108
+ Manage your account settings.
109
+ </TabsContent>
110
+ <TabsContent value="password">
111
+ Change your password here.
112
+ </TabsContent>
113
+ </Tabs>
114
+ ```
115
+
116
+ ### Controlled State
117
+
118
+ ```tsx
119
+ function ControlledTabs() {
120
+ const [activeTab, setActiveTab] = useState("webhooks")
121
+
122
+ return (
123
+ <Tabs value={activeTab} onValueChange={setActiveTab}>
124
+ <TabsList>
125
+ <TabsTrigger value="webhooks">Webhooks</TabsTrigger>
126
+ <TabsTrigger value="keys">API Keys</TabsTrigger>
127
+ <TabsTrigger value="logs">Logs</TabsTrigger>
128
+ </TabsList>
129
+ <TabsContent value="webhooks">...</TabsContent>
130
+ <TabsContent value="keys">...</TabsContent>
131
+ <TabsContent value="logs">...</TabsContent>
132
+ </Tabs>
133
+ )
134
+ }
135
+ ```
136
+
137
+ ### With Icons and Badges
138
+
139
+ ```tsx
140
+ <Tabs defaultValue="inbox">
141
+ <TabsList variant="line">
142
+ <TabsTrigger value="inbox">
143
+ <MailIcon />
144
+ Inbox
145
+ <Badge variant="default" className="ml-1.5">12</Badge>
146
+ </TabsTrigger>
147
+ <TabsTrigger value="drafts">
148
+ <FileTextIcon />
149
+ Drafts
150
+ <Badge variant="secondary" className="ml-1.5">3</Badge>
151
+ </TabsTrigger>
152
+ <TabsTrigger value="sent">
153
+ <SendIcon />
154
+ Sent
155
+ </TabsTrigger>
156
+ </TabsList>
157
+ <TabsContent value="inbox">12 unread messages</TabsContent>
158
+ <TabsContent value="drafts">3 draft messages</TabsContent>
159
+ <TabsContent value="sent">Sent messages</TabsContent>
160
+ </Tabs>
161
+ ```
162
+
163
+ ### Line Variant
164
+
165
+ ```tsx
166
+ <Tabs defaultValue="all">
167
+ <TabsList variant="line">
168
+ <TabsTrigger value="all">All</TabsTrigger>
169
+ <TabsTrigger value="active">Active</TabsTrigger>
170
+ <TabsTrigger value="completed">Completed</TabsTrigger>
171
+ </TabsList>
172
+ <TabsContent value="all">All items</TabsContent>
173
+ <TabsContent value="active">Active items</TabsContent>
174
+ <TabsContent value="completed">Completed items</TabsContent>
175
+ </Tabs>
176
+ ```
177
+
178
+ ### Vertical Orientation
179
+
180
+ ```tsx
181
+ <Tabs defaultValue="profile" orientation="vertical" className="w-[600px]">
182
+ <TabsList>
183
+ <TabsTrigger value="profile">
184
+ <UserIcon />
185
+ Profile
186
+ </TabsTrigger>
187
+ <TabsTrigger value="account">
188
+ <KeyIcon />
189
+ Account
190
+ </TabsTrigger>
191
+ <TabsTrigger value="notifications">
192
+ <BellIcon />
193
+ Notifications
194
+ </TabsTrigger>
195
+ </TabsList>
196
+ <TabsContent value="profile">Profile settings</TabsContent>
197
+ <TabsContent value="account">Account security</TabsContent>
198
+ <TabsContent value="notifications">Notification preferences</TabsContent>
199
+ </Tabs>
200
+ ```
201
+
202
+ ### Disabled Tabs
203
+
204
+ ```tsx
205
+ <Tabs defaultValue="general">
206
+ <TabsList>
207
+ <TabsTrigger value="general">General</TabsTrigger>
208
+ <TabsTrigger value="privacy">Privacy</TabsTrigger>
209
+ <TabsTrigger value="billing" disabled>
210
+ Billing
211
+ </TabsTrigger>
212
+ <TabsTrigger value="team" disabled>
213
+ Team
214
+ <Badge variant="outline" className="ml-1.5">Pro</Badge>
215
+ </TabsTrigger>
216
+ </TabsList>
217
+ <TabsContent value="general">General settings</TabsContent>
218
+ <TabsContent value="privacy">Privacy settings</TabsContent>
219
+ </Tabs>
220
+ ```
221
+
222
+ ## Keyboard
223
+
224
+ | Key | Action |
225
+ |-----|--------|
226
+ | Tab | Move focus to next focusable element |
227
+ | ArrowLeft / ArrowRight | Navigate between tabs (horizontal) |
228
+ | ArrowUp / ArrowDown | Navigate between tabs (vertical) |
229
+ | Enter / Space | Activate focused tab (when activateOnFocus is false) |
230
+ | Home | Focus first tab |
231
+ | End | Focus last tab |
232
+
233
+ ## Accessibility
234
+
235
+ - Uses `role="tablist"`, `role="tab"`, and `role="tabpanel"` for proper semantic structure
236
+ - Active tab marked with `aria-selected="true"`
237
+ - Tab panels linked via `aria-labelledby` and `aria-controls`
238
+ - Keyboard navigation follows ARIA Authoring Practices Guide
239
+ - Focus management automatically handled when switching tabs
240
+
241
+ ## Related
242
+
243
+ - [Button](./button.llm.md) - For tab-like actions
244
+ - [Badge](./badge.llm.md) - For counts in tabs
245
+ - [Card](./card.llm.md) - For content panels
@@ -0,0 +1,108 @@
1
+ # Text
2
+
3
+ Paragraph text component with size, weight, color, alignment, and truncation options.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Text, Caption, Overline } from "@neynar/ui/typography"
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ <Text>Default paragraph text</Text>
15
+ <Text size="lg" weight="semibold">Large semibold text</Text>
16
+ <Text color="muted">Secondary text</Text>
17
+ ```
18
+
19
+ ## Props
20
+
21
+ | Prop | Type | Default | Description |
22
+ |------|------|---------|-------------|
23
+ | size | "xs" \| "sm" \| "base" \| "lg" \| "xl" \| "2xl" | "base" | Text size |
24
+ | weight | "normal" \| "medium" \| "semibold" \| "bold" | - | Font weight |
25
+ | color | "default" \| "muted" \| "subtle" \| "destructive" \| "success" \| "warning" \| "info" | "default" | Text color |
26
+ | align | "left" \| "center" \| "right" | - | Text alignment |
27
+ | transform | "uppercase" \| "lowercase" \| "capitalize" | - | Text transform |
28
+ | wrap | "pretty" \| "balance" | - | Text wrapping strategy |
29
+ | lineClamp | 1 \| 2 \| 3 \| 4 \| 5 \| 6 | - | Truncate after N lines |
30
+ | as | React.ElementType | "p" | Change rendered element |
31
+ | render | React.ReactElement | - | Advanced polymorphism |
32
+
33
+ ## Convenience Components
34
+
35
+ ### Caption
36
+
37
+ Small muted text for metadata, timestamps, secondary info.
38
+
39
+ ```tsx
40
+ <Caption>Posted 3 hours ago</Caption>
41
+ // Equivalent to: <Text size="xs" color="muted">
42
+ ```
43
+
44
+ ### Overline
45
+
46
+ Uppercase label text for categories and section headers.
47
+
48
+ ```tsx
49
+ <Overline>Featured Article</Overline>
50
+ // Equivalent to: <Text size="xs" transform="uppercase">
51
+ ```
52
+
53
+ ## Examples
54
+
55
+ ### Sizes
56
+
57
+ ```tsx
58
+ <Text size="xs">Extra small</Text>
59
+ <Text size="sm">Small</Text>
60
+ <Text size="base">Base (default)</Text>
61
+ <Text size="lg">Large</Text>
62
+ <Text size="xl">Extra large</Text>
63
+ ```
64
+
65
+ ### Colors
66
+
67
+ ```tsx
68
+ <Text color="default">Default text</Text>
69
+ <Text color="muted">Muted helper text</Text>
70
+ <Text color="destructive">Error message</Text>
71
+ <Text color="success">Success message</Text>
72
+ ```
73
+
74
+ ### Truncation
75
+
76
+ ```tsx
77
+ <Text lineClamp={2}>
78
+ This long text will be truncated after two lines with an ellipsis...
79
+ </Text>
80
+ ```
81
+
82
+ ### Text Wrapping
83
+
84
+ ```tsx
85
+ <Text wrap="balance">
86
+ Balanced text distributes words evenly across lines
87
+ </Text>
88
+ <Text wrap="pretty">
89
+ Pretty text avoids orphaned words on the last line
90
+ </Text>
91
+ ```
92
+
93
+ ### Polymorphism
94
+
95
+ ```tsx
96
+ // Simple: change element
97
+ <Text as="span">Inline text</Text>
98
+ <Text as="label">Label text</Text>
99
+
100
+ // Advanced: render prop
101
+ <Text render={<a href="/link" />}>Link text</Text>
102
+ ```
103
+
104
+ ## Related
105
+
106
+ - [Title](./title.llm.md) - Heading component
107
+ - [Code](./code.llm.md) - Inline code
108
+ - [Blockquote](./blockquote.llm.md) - Quoted content
@@ -0,0 +1,236 @@
1
+ # Textarea
2
+
3
+ Multi-line text input with automatic vertical growth and comprehensive validation states.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Textarea } from "@neynar/ui/textarea"
9
+ ```
10
+
11
+ ## Anatomy
12
+
13
+ ```tsx
14
+ <Textarea placeholder="Enter text..." />
15
+ ```
16
+
17
+ ## Props
18
+
19
+ Extends all native `<textarea>` HTML props including:
20
+
21
+ | Prop | Type | Default | Description |
22
+ |------|------|---------|-------------|
23
+ | rows | number | - | Initial number of visible text rows |
24
+ | cols | number | - | Width in average character widths |
25
+ | disabled | boolean | false | Disables the textarea |
26
+ | aria-invalid | boolean | false | Shows error state with red border and ring |
27
+ | placeholder | string | - | Placeholder text |
28
+ | value | string | - | Controlled value |
29
+ | onChange | (e: ChangeEvent) => void | - | Change handler |
30
+ | className | string | - | Additional CSS classes |
31
+
32
+ All standard textarea attributes are supported (maxLength, autoFocus, readOnly, etc.)
33
+
34
+ ## Auto-Grow Behavior
35
+
36
+ Textarea uses `field-sizing-content` to automatically grow vertically based on content:
37
+
38
+ ```tsx
39
+ // Auto-grows from min-h-16 as content expands
40
+ <Textarea
41
+ placeholder="Start typing and watch this grow..."
42
+ className="min-h-16"
43
+ />
44
+ ```
45
+
46
+ The component has a default `min-h-16` (64px minimum height).
47
+
48
+ ## Resize Control
49
+
50
+ Override the default resize behavior via className:
51
+
52
+ ```tsx
53
+ // Disable resize handles
54
+ <Textarea className="resize-none" />
55
+
56
+ // Vertical resize only (default browser behavior)
57
+ <Textarea className="resize-y" />
58
+
59
+ // Both directions
60
+ <Textarea className="resize" />
61
+ ```
62
+
63
+ ## States
64
+
65
+ ### Error State
66
+
67
+ Use `aria-invalid` for validation errors:
68
+
69
+ ```tsx
70
+ <Textarea
71
+ aria-invalid={hasError}
72
+ placeholder="Required field..."
73
+ />
74
+ ```
75
+
76
+ Error styling:
77
+ - Red border (`border-destructive`)
78
+ - Red focus ring (`ring-destructive/20`, darker in dark mode)
79
+ - Works with Label component error state
80
+
81
+ ### Disabled State
82
+
83
+ ```tsx
84
+ <Textarea
85
+ disabled
86
+ value="Cannot edit this content"
87
+ />
88
+ ```
89
+
90
+ Disabled styling:
91
+ - 50% opacity
92
+ - No pointer cursor
93
+ - Not focusable
94
+
95
+ ## Data Attributes
96
+
97
+ | Attribute | Purpose |
98
+ |-----------|---------|
99
+ | data-slot="textarea" | Component identifier for styling and testing |
100
+
101
+ ## Examples
102
+
103
+ ### Basic with Label
104
+
105
+ ```tsx
106
+ import { Label } from "@neynar/ui/label"
107
+
108
+ <div className="space-y-2">
109
+ <Label htmlFor="description">Description</Label>
110
+ <Textarea
111
+ id="description"
112
+ placeholder="Enter a description..."
113
+ rows={3}
114
+ />
115
+ </div>
116
+ ```
117
+
118
+ ### Controlled with Character Count
119
+
120
+ ```tsx
121
+ function CommentForm() {
122
+ const [value, setValue] = useState("")
123
+ const maxLength = 280
124
+ const remaining = maxLength - value.length
125
+ const isOverLimit = remaining < 0
126
+
127
+ return (
128
+ <div className="space-y-2">
129
+ <Textarea
130
+ value={value}
131
+ onChange={(e) => setValue(e.target.value)}
132
+ aria-invalid={isOverLimit}
133
+ placeholder="What's on your mind?"
134
+ />
135
+ <p className={isOverLimit ? "text-destructive" : "text-muted-foreground"}>
136
+ {remaining} characters remaining
137
+ </p>
138
+ </div>
139
+ )
140
+ }
141
+ ```
142
+
143
+ ### Code/JSON Input
144
+
145
+ ```tsx
146
+ <Textarea
147
+ className="font-mono text-sm"
148
+ placeholder="Paste JSON here..."
149
+ rows={8}
150
+ defaultValue={`{\n "event": "cast.created",\n "data": { ... }\n}`}
151
+ />
152
+ ```
153
+
154
+ ### With Validation Error
155
+
156
+ ```tsx
157
+ function FeedbackForm() {
158
+ const [feedback, setFeedback] = useState("")
159
+ const [error, setError] = useState("")
160
+
161
+ const validate = () => {
162
+ if (feedback.length < 10) {
163
+ setError("Feedback must be at least 10 characters")
164
+ }
165
+ }
166
+
167
+ return (
168
+ <div className="space-y-2">
169
+ <Label htmlFor="feedback" className={error ? "text-destructive" : ""}>
170
+ Feedback
171
+ </Label>
172
+ <Textarea
173
+ id="feedback"
174
+ value={feedback}
175
+ onChange={(e) => setFeedback(e.target.value)}
176
+ onBlur={validate}
177
+ aria-invalid={!!error}
178
+ />
179
+ {error && (
180
+ <p className="text-destructive text-sm">{error}</p>
181
+ )}
182
+ </div>
183
+ )
184
+ }
185
+ ```
186
+
187
+ ### Webhook Payload Editor
188
+
189
+ ```tsx
190
+ <div className="space-y-2">
191
+ <Label>Request Body (JSON)</Label>
192
+ <Textarea
193
+ className="font-mono text-sm"
194
+ rows={8}
195
+ defaultValue={webhookPayload}
196
+ />
197
+ <Button size="sm">
198
+ <SendIcon data-icon="inline-start" />
199
+ Send Test Request
200
+ </Button>
201
+ </div>
202
+ ```
203
+
204
+ ## Keyboard
205
+
206
+ Standard textarea keyboard behavior:
207
+
208
+ | Key | Action |
209
+ |-----|--------|
210
+ | Tab | Move focus (can be prevented) |
211
+ | Enter | New line |
212
+ | Ctrl/Cmd + A | Select all |
213
+ | Ctrl/Cmd + Z | Undo |
214
+
215
+ ## Accessibility
216
+
217
+ - Semantic `<textarea>` element
218
+ - Works with Label component via htmlFor/id
219
+ - Error state communicated via `aria-invalid`
220
+ - Placeholder provides input hint (not a replacement for label)
221
+ - Disabled state prevents focus and interaction
222
+ - Full keyboard navigation support
223
+
224
+ ## Styling Notes
225
+
226
+ The component includes comprehensive focus and error states:
227
+ - **Focus**: Blue ring (`ring-ring/50`) with 3px width
228
+ - **Error**: Red border and ring in both light/dark modes
229
+ - **Dark mode**: Subtle background tint (`bg-input/30`)
230
+ - **Transitions**: Smooth color and shadow changes
231
+
232
+ ## Related
233
+
234
+ - **[Label](/components/label.llm.md)** - Accessible form labels
235
+ - **[Input](/components/input.llm.md)** - Single-line text input
236
+ - **[Form](/components/form.llm.md)** - Form validation patterns
@@ -0,0 +1,88 @@
1
+ # Title
2
+
3
+ Semantic heading component (h1-h6) with independent visual sizing.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Title } from "@neynar/ui/typography"
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ <Title>Default h2 heading</Title>
15
+ <Title order={1}>Page title (h1)</Title>
16
+ <Title order={3} size="xl">Visually large h3</Title>
17
+ ```
18
+
19
+ ## Props
20
+
21
+ | Prop | Type | Default | Description |
22
+ |------|------|---------|-------------|
23
+ | order | 1 \| 2 \| 3 \| 4 \| 5 \| 6 | 2 | Semantic heading level (h1-h6) |
24
+ | size | "xs" \| "sm" \| "base" \| "lg" \| "xl" \| "2xl" \| "3xl" \| "4xl" \| "5xl" \| "6xl" | auto | Visual size (overrides order default) |
25
+ | weight | "normal" \| "medium" \| "semibold" \| "bold" | auto | Font weight (overrides order default) |
26
+ | color | "default" \| "muted" \| "subtle" \| "destructive" \| "success" \| "warning" \| "info" | "default" | Text color |
27
+ | as | React.ElementType | auto | Change rendered element |
28
+ | render | React.ReactElement | - | Advanced polymorphism |
29
+
30
+ ## Order Defaults
31
+
32
+ Each order has default size and weight:
33
+
34
+ | Order | Element | Default Size | Default Weight |
35
+ |-------|---------|--------------|----------------|
36
+ | 1 | h1 | 4xl | bold |
37
+ | 2 | h2 | 3xl | bold |
38
+ | 3 | h3 | 2xl | semibold |
39
+ | 4 | h4 | xl | semibold |
40
+ | 5 | h5 | lg | medium |
41
+ | 6 | h6 | base | medium |
42
+
43
+ ## Examples
44
+
45
+ ### Semantic Headings
46
+
47
+ ```tsx
48
+ <Title order={1}>Page Title</Title>
49
+ <Title order={2}>Section Heading</Title>
50
+ <Title order={3}>Subsection</Title>
51
+ ```
52
+
53
+ ### Visual Override
54
+
55
+ ```tsx
56
+ // Semantic h3, but visually as large as h1
57
+ <Title order={3} size="4xl">
58
+ SEO-friendly h3 with hero styling
59
+ </Title>
60
+ ```
61
+
62
+ ### Colors
63
+
64
+ ```tsx
65
+ <Title color="muted">Secondary heading</Title>
66
+ <Title color="destructive">Error heading</Title>
67
+ ```
68
+
69
+ ### Polymorphism
70
+
71
+ ```tsx
72
+ // Render as different element
73
+ <Title as="div">Non-semantic title styling</Title>
74
+
75
+ // Advanced: render prop
76
+ <Title render={<a href="/section" />}>Linked heading</Title>
77
+ ```
78
+
79
+ ## Accessibility
80
+
81
+ - Use `order` for semantic structure (screen readers)
82
+ - Use `size` for visual presentation
83
+ - Don't skip heading levels (h1 → h3)
84
+
85
+ ## Related
86
+
87
+ - [Text](./text.llm.md) - Paragraph text
88
+ - [Code](./code.llm.md) - Inline code