@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.
Files changed (68) hide show
  1. package/context7.json +17 -0
  2. package/llm/components/accordion.llm.md +205 -0
  3. package/llm/components/alert-dialog.llm.md +289 -0
  4. package/llm/components/alert.llm.md +310 -0
  5. package/llm/components/aspect-ratio.llm.md +110 -0
  6. package/llm/components/avatar.llm.md +282 -0
  7. package/llm/components/badge.llm.md +185 -0
  8. package/llm/components/blockquote.llm.md +86 -0
  9. package/llm/components/breadcrumb.llm.md +245 -0
  10. package/llm/components/button-group.llm.md +248 -0
  11. package/llm/components/button.llm.md +247 -0
  12. package/llm/components/calendar.llm.md +252 -0
  13. package/llm/components/card.llm.md +356 -0
  14. package/llm/components/carousel.llm.md +281 -0
  15. package/llm/components/chart.llm.md +278 -0
  16. package/llm/components/checkbox.llm.md +234 -0
  17. package/llm/components/code.llm.md +75 -0
  18. package/llm/components/collapsible.llm.md +271 -0
  19. package/llm/components/color-mode.llm.md +196 -0
  20. package/llm/components/combobox.llm.md +346 -0
  21. package/llm/components/command.llm.md +353 -0
  22. package/llm/components/context-menu.llm.md +368 -0
  23. package/llm/components/dialog.llm.md +283 -0
  24. package/llm/components/drawer.llm.md +326 -0
  25. package/llm/components/dropdown-menu.llm.md +404 -0
  26. package/llm/components/empty.llm.md +282 -0
  27. package/llm/components/field.llm.md +303 -0
  28. package/llm/components/first-light.llm.md +129 -0
  29. package/llm/components/hover-card.llm.md +278 -0
  30. package/llm/components/input-group.llm.md +334 -0
  31. package/llm/components/input-otp.llm.md +270 -0
  32. package/llm/components/input.llm.md +197 -0
  33. package/llm/components/item.llm.md +347 -0
  34. package/llm/components/kbd.llm.md +221 -0
  35. package/llm/components/label.llm.md +219 -0
  36. package/llm/components/menubar.llm.md +378 -0
  37. package/llm/components/navigation-menu.llm.md +320 -0
  38. package/llm/components/pagination.llm.md +337 -0
  39. package/llm/components/popover.llm.md +278 -0
  40. package/llm/components/progress.llm.md +259 -0
  41. package/llm/components/radio-group.llm.md +269 -0
  42. package/llm/components/resizable.llm.md +222 -0
  43. package/llm/components/scroll-area.llm.md +290 -0
  44. package/llm/components/select.llm.md +338 -0
  45. package/llm/components/separator.llm.md +129 -0
  46. package/llm/components/sheet.llm.md +275 -0
  47. package/llm/components/sidebar.llm.md +528 -0
  48. package/llm/components/skeleton.llm.md +140 -0
  49. package/llm/components/slider.llm.md +213 -0
  50. package/llm/components/sonner.llm.md +299 -0
  51. package/llm/components/spinner.llm.md +187 -0
  52. package/llm/components/switch.llm.md +258 -0
  53. package/llm/components/table.llm.md +334 -0
  54. package/llm/components/tabs.llm.md +245 -0
  55. package/llm/components/text.llm.md +108 -0
  56. package/llm/components/textarea.llm.md +236 -0
  57. package/llm/components/title.llm.md +88 -0
  58. package/llm/components/toggle-group.llm.md +228 -0
  59. package/llm/components/toggle.llm.md +235 -0
  60. package/llm/components/tooltip.llm.md +191 -0
  61. package/llm/contributing.llm.md +273 -0
  62. package/llm/hooks.llm.md +91 -0
  63. package/llm/index.llm.md +178 -0
  64. package/llm/theming.llm.md +381 -0
  65. package/llm/utilities.llm.md +97 -0
  66. package/llms-full.txt +15995 -0
  67. package/llms.txt +182 -0
  68. package/package.json +5 -1
@@ -0,0 +1,381 @@
1
+ # Theming
2
+
3
+ @neynar/ui theming system using CSS custom properties and Tailwind CSS.
4
+
5
+ ## Quick Start
6
+
7
+ **Important:** Styles must be imported via CSS `@import`, not JS imports. This is because the CSS uses `@import "tailwindcss"` which requires Tailwind CSS v4 processing.
8
+
9
+ ```css
10
+ /* In your global CSS file (e.g., globals.css, index.css) */
11
+ @import "@neynar/ui/styles";
12
+ @import "@neynar/ui/themes/purple-dawn";
13
+ ```
14
+
15
+ Then import the CSS file in your app entry:
16
+
17
+ ```tsx
18
+ // main.tsx or layout.tsx
19
+ import "./index.css"; // or "./globals.css"
20
+ ```
21
+
22
+ **Prerequisite:** Tailwind CSS v4 must be configured. See [llms.txt](../llms.txt) for Vite/Next.js setup.
23
+
24
+ ## Concepts
25
+
26
+ - **Theme** = Visual aesthetic (purple-dawn, first-light) - imported via CSS
27
+ - **Color Mode** = Light or dark variant - controlled at runtime via `.dark` class
28
+
29
+ ## Available Themes
30
+
31
+ | Theme | Import | Description |
32
+ |-------|--------|-------------|
33
+ | Purple Dawn | `@neynar/ui/themes/purple-dawn` | Default. Elegant translucent surfaces with purple tint |
34
+ | First Light | `@neynar/ui/themes/first-light` | Hand-drawn sketch aesthetic with wobbly edges |
35
+
36
+ ## Architecture
37
+
38
+ ### base.css (Infrastructure)
39
+
40
+ Shared by all themes. Contains:
41
+ - Tailwind CSS imports (`tailwindcss`, `tw-animate-css`)
42
+ - `@theme` block mapping CSS variables to Tailwind utilities
43
+ - `@source` directive for component class scanning
44
+ - Base layer styles (borders, body background)
45
+ - Surface blur rules for overlay components via `[data-slot]` selectors
46
+
47
+ **Do NOT import base.css directly.** Always import a theme.
48
+
49
+ ### Theme Files
50
+
51
+ Each theme defines CSS custom properties for:
52
+ - Colors (background, foreground, semantic colors)
53
+ - Typography (font-family)
54
+ - Spacing (radius, surface-blur)
55
+ - Both light (`:root`) and dark (`.dark`) modes
56
+
57
+ ## CSS Variables
58
+
59
+ ### Core Colors
60
+
61
+ | Variable | Usage |
62
+ |----------|-------|
63
+ | `--background` | Page background |
64
+ | `--foreground` | Default text |
65
+ | `--card` / `--card-foreground` | Card surfaces |
66
+ | `--popover` / `--popover-foreground` | Dropdown/dialog surfaces |
67
+ | `--primary` / `--primary-foreground` | Primary buttons, links |
68
+ | `--secondary` / `--secondary-foreground` | Secondary actions |
69
+ | `--muted` / `--muted-foreground` | Subtle backgrounds, helper text |
70
+ | `--subtle-foreground` | Even lighter text (40% opacity) |
71
+ | `--accent` / `--accent-foreground` | Hover states |
72
+ | `--border` | Border colors |
73
+ | `--input` | Input borders |
74
+ | `--ring` | Focus ring |
75
+
76
+ ### Semantic Colors
77
+
78
+ | Variable | Usage |
79
+ |----------|-------|
80
+ | `--destructive` | Errors, delete actions |
81
+ | `--success` | Success states |
82
+ | `--warning` | Warning states |
83
+ | `--info` | Informational states |
84
+
85
+ ### Chart Colors
86
+
87
+ `--chart-1` through `--chart-5` for data visualization.
88
+
89
+ ### Sidebar Colors
90
+
91
+ `--sidebar`, `--sidebar-foreground`, `--sidebar-primary`, `--sidebar-primary-foreground`, `--sidebar-accent`, `--sidebar-accent-foreground`, `--sidebar-border`, `--sidebar-ring`
92
+
93
+ ### Theme-Specific Variables
94
+
95
+ | Variable | Theme | Usage |
96
+ |----------|-------|-------|
97
+ | `--surface-blur` | All | Backdrop blur amount (12px default, 4px for First Light) |
98
+ | `--font-family` | All | Primary font family |
99
+ | `--radius` | All | Border radius base (0.625rem default, 0 for First Light) |
100
+ | `--first-light-shadow` | First Light | Offset shadow effect (3px 3px) |
101
+ | `--first-light-shadow-hover` | First Light | Hover shadow (2px 2px) |
102
+ | `--first-light-shadow-active` | First Light | Active/pressed shadow (0px 0px) |
103
+
104
+ ## Radius Utilities
105
+
106
+ The `--radius` variable is used to calculate multiple radius sizes via `@theme inline`:
107
+
108
+ ```css
109
+ --radius-sm: calc(var(--radius) - 4px);
110
+ --radius-md: calc(var(--radius) - 2px);
111
+ --radius-lg: var(--radius);
112
+ --radius-xl: calc(var(--radius) + 4px);
113
+ --radius-2xl: calc(var(--radius) + 8px);
114
+ --radius-3xl: calc(var(--radius) + 12px);
115
+ --radius-4xl: calc(var(--radius) + 16px);
116
+ ```
117
+
118
+ ## Dark Mode
119
+
120
+ Add `.dark` class to `<html>` or a parent element:
121
+
122
+ ```tsx
123
+ <html className="dark">
124
+ ```
125
+
126
+ Themes define both light (`:root`) and dark (`.dark`) variants.
127
+
128
+ ### Setup with ColorModeInitializer
129
+
130
+ To prevent flash of incorrect color mode:
131
+
132
+ ```tsx
133
+ import { ColorModeInitializer } from "@neynar/ui/color-mode";
134
+
135
+ <html suppressHydrationWarning>
136
+ <head>
137
+ <ColorModeInitializer />
138
+ </head>
139
+ <body>{children}</body>
140
+ </html>
141
+ ```
142
+
143
+ ### Color Mode API
144
+
145
+ ```tsx
146
+ // Get current mode
147
+ const isDark = document.documentElement.classList.contains('dark');
148
+
149
+ // Set mode programmatically
150
+ document.documentElement.classList.remove('light', 'dark');
151
+ document.documentElement.classList.add('dark');
152
+
153
+ // Persist preference
154
+ document.cookie = 'color-mode={"preference":"dark","mode":"dark"}; path=/; max-age=31536000';
155
+ ```
156
+
157
+ ## Runtime Theme Switching
158
+
159
+ For Storybook or dynamic switching, add theme class to `<html>`:
160
+
161
+ ```tsx
162
+ // Switch to First Light theme
163
+ document.documentElement.classList.add("theme-first-light")
164
+ document.documentElement.classList.remove("theme-purple-dawn")
165
+
166
+ // Switch to Purple Dawn theme
167
+ document.documentElement.classList.add("theme-purple-dawn")
168
+ document.documentElement.classList.remove("theme-first-light")
169
+ ```
170
+
171
+ ## Purple Dawn Theme
172
+
173
+ The default theme with elegant translucent surfaces.
174
+
175
+ ### Characteristics
176
+
177
+ - **Font**: Figtree Variable (sans-serif)
178
+ - **Radius**: 0.625rem (10px)
179
+ - **Surface Blur**: 12px
180
+ - **Color Tint**: Purple (hue 290)
181
+ - **Surface Opacity**: 75% for cards and popovers
182
+
183
+ ### Light Mode Colors
184
+
185
+ ```css
186
+ --background: oklch(0.96 0.06 290); /* Light purple-tinted white */
187
+ --foreground: oklch(0.18 0.08 290); /* Dark purple-tinted black */
188
+ --card: oklch(0.93 0.08 290 / 75%); /* Translucent purple */
189
+ --primary: oklch(0.3 0.09 290); /* Dark purple */
190
+ --border: oklch(0.18 0.08 290 / 20%); /* 20% opacity border */
191
+ ```
192
+
193
+ ### Dark Mode Colors
194
+
195
+ ```css
196
+ --background: oklch(0.145 0.02 290); /* Very dark purple */
197
+ --foreground: oklch(0.985 0.01 290); /* Near-white */
198
+ --card: oklch(0.205 0.03 290 / 75%); /* Translucent dark purple */
199
+ --primary: oklch(0.87 0.02 290); /* Light purple */
200
+ --border: oklch(0.985 0.01 290 / 15%); /* 15% opacity border */
201
+ ```
202
+
203
+ ## First Light Theme
204
+
205
+ Hand-drawn wireframe aesthetic with wobbly SVG filters.
206
+
207
+ ### Setup
208
+
209
+ First Light requires an SVG filter component for the wobbly edge effect:
210
+
211
+ ```tsx
212
+ import "@neynar/ui/themes/first-light"
213
+ import { FirstLightFilters } from "@neynar/ui/first-light"
214
+
215
+ // Add once in your root layout
216
+ export function Layout({ children }) {
217
+ return (
218
+ <>
219
+ <FirstLightFilters />
220
+ {children}
221
+ </>
222
+ )
223
+ }
224
+ ```
225
+
226
+ ### Characteristics
227
+
228
+ - **Font**: Architects Daughter (handwriting)
229
+ - **Radius**: 0 (sharp corners)
230
+ - **Surface Blur**: 4px (minimal)
231
+ - **Color Style**: High contrast black/white with strong borders
232
+ - **Special Effect**: SVG turbulence filter for wobbly edges
233
+
234
+ ### Light Mode (Paper)
235
+
236
+ ```css
237
+ --background: #fafaf8; /* Warm white paper */
238
+ --foreground: #1a1a1a; /* Pencil black */
239
+ --border: rgba(0, 0, 0, 0.7); /* Strong black border */
240
+ --accent: #fff3b0; /* Highlighter yellow */
241
+ ```
242
+
243
+ ### Dark Mode (Chalkboard)
244
+
245
+ ```css
246
+ --background: #1e2a1e; /* Green-tinted chalkboard */
247
+ --foreground: #e8e8e8; /* Chalk white */
248
+ --border: rgba(255, 255, 255, 0.6); /* White chalk border */
249
+ --accent: #e8d44d; /* Yellow chalk */
250
+ ```
251
+
252
+ ### First Light Utility Classes
253
+
254
+ | Class | Effect |
255
+ |-------|--------|
256
+ | `.first-light-paper` | Grid paper background (20px grid) |
257
+ | `.first-light-lined` | Lined paper background (28px lines) |
258
+ | `.first-light-highlight` | Yellow highlighter effect |
259
+ | `.first-light-underline` | Hand-drawn underline (slightly rotated) |
260
+ | `.first-light-scribble` | Dashed underline effect |
261
+ | `.first-light-light` | Lighter wobble filter intensity |
262
+ | `.first-light-heavy` | Heavier wobble filter intensity |
263
+
264
+ ### SVG Filter Details
265
+
266
+ The `FirstLightFilters` component provides three filter intensities:
267
+
268
+ | Filter ID | Base Frequency | Octaves | Scale | Use Case |
269
+ |-----------|----------------|---------|-------|----------|
270
+ | `#first-light-filter` | 0.015 | 2 | 1.5 | Default wobble |
271
+ | `#first-light-filter-light` | 0.006 | 1 | 0.4 | Subtle wobble |
272
+ | `#first-light-filter-heavy` | 0.012 | 3 | 1.5 | Pronounced wobble |
273
+
274
+ ## Frosted Glass Effect
275
+
276
+ Cards, popovers, dialogs, sheets, and menus use translucent backgrounds with backdrop blur:
277
+
278
+ - **Surface Opacity**: 75% on `--card` and `--popover`
279
+ - **Backdrop Blur**: Via `--surface-blur` variable (applied to `[data-slot]` elements)
280
+ - **Transparent Borders**: 10-20% opacity
281
+
282
+ Components that receive the blur effect (via `base.css`):
283
+ - `[data-slot="card"]`
284
+ - `[data-slot="popover-content"]`
285
+ - `[data-slot="hover-card-content"]`
286
+ - `[data-slot="dialog-content"]`
287
+ - `[data-slot="alert-dialog-content"]`
288
+ - `[data-slot="sheet-content"]`
289
+ - `[data-slot="drawer-content"]`
290
+ - `[data-slot="dropdown-menu-content"]`
291
+ - `[data-slot="context-menu-content"]`
292
+ - `[data-slot="menubar-content"]`
293
+ - `[data-slot="navigation-menu-popup"]`
294
+ - `[data-slot="combobox-content"]`
295
+ - `[data-slot="select-content"]`
296
+ - `[data-slot="command"]`
297
+
298
+ ## Creating Custom Themes
299
+
300
+ 1. Create a new CSS file importing base.css
301
+ 2. Define CSS variables in `:root` and `.dark`
302
+ 3. Optionally add `.theme-{name}` selector for runtime switching
303
+
304
+ ```css
305
+ @import "../base.css";
306
+
307
+ :root,
308
+ html.theme-custom {
309
+ --font-family: "Inter", sans-serif;
310
+ --radius: 0.5rem;
311
+ --surface-blur: 8px;
312
+ --background: oklch(0.98 0 0);
313
+ --foreground: oklch(0.1 0 0);
314
+ /* ... rest of variables */
315
+ }
316
+
317
+ .dark,
318
+ html.theme-custom.dark {
319
+ --background: oklch(0.1 0 0);
320
+ --foreground: oklch(0.98 0 0);
321
+ /* ... dark mode overrides */
322
+ }
323
+ ```
324
+
325
+ ## Color Format
326
+
327
+ Themes use **oklch()** for perceptually uniform colors:
328
+
329
+ ```css
330
+ --primary: oklch(0.5 0.18 290);
331
+ /* L C H
332
+ | | +-- Hue (0-360)
333
+ | +------- Chroma (0-0.37)
334
+ +------------ Lightness (0-1)
335
+ */
336
+ ```
337
+
338
+ Benefits:
339
+ - Consistent perceived brightness across hues
340
+ - Easy to create harmonious palettes
341
+ - Supports relative color syntax for derived colors
342
+
343
+ ### Relative Color Syntax
344
+
345
+ First Light theme uses relative color syntax for toast colors:
346
+
347
+ ```css
348
+ --success-bg: oklch(from var(--success) 0.92 0.05 h / 90%);
349
+ --success-text: oklch(from var(--success) 0.25 c h);
350
+ ```
351
+
352
+ This derives new colors from the base `--success` color, preserving hue while adjusting lightness and chroma.
353
+
354
+ ## Using Theme Tokens in Tailwind
355
+
356
+ All CSS variables are mapped to Tailwind utilities via `@theme inline` in base.css:
357
+
358
+ ```tsx
359
+ <div className="bg-background text-foreground">
360
+ <button className="bg-primary text-primary-foreground hover:bg-accent">
361
+ Click
362
+ </button>
363
+ </div>
364
+ ```
365
+
366
+ Available color utilities: `bg-{token}`, `text-{token}`, `border-{token}`, etc.
367
+
368
+ ## Customization
369
+
370
+ Override any token in your CSS:
371
+
372
+ ```css
373
+ :root {
374
+ --primary: oklch(0.6 0.25 260); /* Custom purple */
375
+ --radius: 0.5rem; /* Smaller corners */
376
+ }
377
+
378
+ .dark {
379
+ --primary: oklch(0.7 0.2 260);
380
+ }
381
+ ```
@@ -0,0 +1,97 @@
1
+ # Utilities
2
+
3
+ Helper functions provided by @neynar/ui.
4
+
5
+ ## cn()
6
+
7
+ Merges class names with Tailwind CSS conflict resolution.
8
+
9
+ ### Import
10
+
11
+ ```tsx
12
+ import { cn } from "@neynar/ui/utils"
13
+ ```
14
+
15
+ ### Signature
16
+
17
+ ```tsx
18
+ function cn(...inputs: ClassValue[]): string
19
+ ```
20
+
21
+ ### How It Works
22
+
23
+ 1. **clsx** - Handles conditionals, arrays, and objects
24
+ 2. **tailwind-merge** - Resolves Tailwind conflicts (last class wins)
25
+
26
+ ### Examples
27
+
28
+ ```tsx
29
+ // Conditional classes
30
+ cn("px-4", isActive && "bg-primary")
31
+
32
+ // Merge with className prop
33
+ cn("rounded-lg border", className)
34
+
35
+ // Tailwind conflict resolution
36
+ cn("text-red-500", "text-blue-500") // → "text-blue-500"
37
+ cn("px-4 py-2", "px-8") // → "px-8 py-2"
38
+
39
+ // Objects and arrays
40
+ cn({ "opacity-50": disabled }, ["flex", "items-center"])
41
+ ```
42
+
43
+ ### Common Patterns
44
+
45
+ ```tsx
46
+ // Component with className prop
47
+ function Card({ className, ...props }) {
48
+ return (
49
+ <div className={cn("rounded-lg border bg-card", className)} {...props} />
50
+ )
51
+ }
52
+
53
+ // Conditional styling
54
+ <Button className={cn(isLoading && "opacity-50 cursor-wait")}>
55
+ Submit
56
+ </Button>
57
+
58
+ // Variant-based styling
59
+ <div className={cn(
60
+ "p-4",
61
+ variant === "destructive" && "bg-destructive text-destructive-foreground",
62
+ variant === "success" && "bg-success text-success-foreground"
63
+ )}>
64
+ {children}
65
+ </div>
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Internal Utilities
71
+
72
+ The following utilities are used internally by components but are **not exported**:
73
+
74
+ ### CVA Variants (lib/variants.ts)
75
+
76
+ Internal variant definitions for consistent styling across components:
77
+
78
+ - **menuItemVariants** - Styling for DropdownMenuItem, ContextMenuItem, MenubarItem
79
+ - **typographyColorVariants** - Color options for Title, Text, Code, Blockquote
80
+ - **titleVariants** - Size and weight options for Title
81
+ - **textVariants** - Size, weight, alignment for Text
82
+
83
+ These are exposed via component props rather than direct imports:
84
+
85
+ ```tsx
86
+ // Use component props (correct)
87
+ <Text color="muted" size="sm">Helper text</Text>
88
+ <DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
89
+
90
+ // Don't try to import variants directly (not exported)
91
+ // import { menuItemVariants } from "@neynar/ui/lib/variants" // ❌
92
+ ```
93
+
94
+ ## Related
95
+
96
+ - [Theming](./theming.llm.md) - CSS variables and themes
97
+ - [Hooks](./hooks.llm.md) - React hooks