@neynar/ui 0.1.1 → 0.1.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 (173) hide show
  1. package/dist/components/ui/accordion.d.ts +1 -25
  2. package/dist/components/ui/accordion.d.ts.map +1 -1
  3. package/dist/components/ui/alert-dialog.d.ts +240 -46
  4. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  5. package/dist/components/ui/alert.d.ts +73 -11
  6. package/dist/components/ui/alert.d.ts.map +1 -1
  7. package/dist/components/ui/aspect-ratio.d.ts +44 -10
  8. package/dist/components/ui/aspect-ratio.d.ts.map +1 -1
  9. package/dist/components/ui/avatar.d.ts +117 -33
  10. package/dist/components/ui/avatar.d.ts.map +1 -1
  11. package/dist/components/ui/badge.d.ts +50 -71
  12. package/dist/components/ui/badge.d.ts.map +1 -1
  13. package/dist/components/ui/breadcrumb.d.ts +231 -49
  14. package/dist/components/ui/breadcrumb.d.ts.map +1 -1
  15. package/dist/components/ui/button.d.ts +189 -71
  16. package/dist/components/ui/button.d.ts.map +1 -1
  17. package/dist/components/ui/calendar.d.ts +197 -40
  18. package/dist/components/ui/calendar.d.ts.map +1 -1
  19. package/dist/components/ui/card.d.ts +7 -22
  20. package/dist/components/ui/card.d.ts.map +1 -1
  21. package/dist/components/ui/carousel.d.ts +369 -99
  22. package/dist/components/ui/carousel.d.ts.map +1 -1
  23. package/dist/components/ui/chart.d.ts.map +1 -1
  24. package/dist/components/ui/checkbox.d.ts +110 -38
  25. package/dist/components/ui/checkbox.d.ts.map +1 -1
  26. package/dist/components/ui/collapsible.d.ts +246 -61
  27. package/dist/components/ui/collapsible.d.ts.map +1 -1
  28. package/dist/components/ui/combobox.d.ts +207 -159
  29. package/dist/components/ui/combobox.d.ts.map +1 -1
  30. package/dist/components/ui/command.d.ts +336 -67
  31. package/dist/components/ui/command.d.ts.map +1 -1
  32. package/dist/components/ui/container.d.ts +159 -64
  33. package/dist/components/ui/container.d.ts.map +1 -1
  34. package/dist/components/ui/context-menu.d.ts +321 -39
  35. package/dist/components/ui/context-menu.d.ts.map +1 -1
  36. package/dist/components/ui/date-picker.d.ts +113 -86
  37. package/dist/components/ui/date-picker.d.ts.map +1 -1
  38. package/dist/components/ui/dialog.d.ts +106 -25
  39. package/dist/components/ui/dialog.d.ts.map +1 -1
  40. package/dist/components/ui/drawer.d.ts +388 -59
  41. package/dist/components/ui/drawer.d.ts.map +1 -1
  42. package/dist/components/ui/dropdown-menu.d.ts +521 -74
  43. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  44. package/dist/components/ui/empty-state.d.ts +148 -76
  45. package/dist/components/ui/empty-state.d.ts.map +1 -1
  46. package/dist/components/ui/hover-card.d.ts +253 -34
  47. package/dist/components/ui/hover-card.d.ts.map +1 -1
  48. package/dist/components/ui/input.d.ts +143 -44
  49. package/dist/components/ui/input.d.ts.map +1 -1
  50. package/dist/components/ui/label.d.ts +0 -8
  51. package/dist/components/ui/label.d.ts.map +1 -1
  52. package/dist/components/ui/menubar.d.ts +288 -46
  53. package/dist/components/ui/menubar.d.ts.map +1 -1
  54. package/dist/components/ui/navigation-menu.d.ts +444 -127
  55. package/dist/components/ui/navigation-menu.d.ts.map +1 -1
  56. package/dist/components/ui/pagination.d.ts +342 -66
  57. package/dist/components/ui/pagination.d.ts.map +1 -1
  58. package/dist/components/ui/popover.d.ts +0 -8
  59. package/dist/components/ui/popover.d.ts.map +1 -1
  60. package/dist/components/ui/progress.d.ts +88 -30
  61. package/dist/components/ui/progress.d.ts.map +1 -1
  62. package/dist/components/ui/radio-group.d.ts +189 -45
  63. package/dist/components/ui/radio-group.d.ts.map +1 -1
  64. package/dist/components/ui/resizable.d.ts +178 -62
  65. package/dist/components/ui/resizable.d.ts.map +1 -1
  66. package/dist/components/ui/scroll-area.d.ts +180 -21
  67. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  68. package/dist/components/ui/select.d.ts +382 -60
  69. package/dist/components/ui/select.d.ts.map +1 -1
  70. package/dist/components/ui/separator.d.ts +52 -39
  71. package/dist/components/ui/separator.d.ts.map +1 -1
  72. package/dist/components/ui/sheet.d.ts +144 -27
  73. package/dist/components/ui/sheet.d.ts.map +1 -1
  74. package/dist/components/ui/sidebar.d.ts +81 -31
  75. package/dist/components/ui/sidebar.d.ts.map +1 -1
  76. package/dist/components/ui/skeleton.d.ts +94 -32
  77. package/dist/components/ui/skeleton.d.ts.map +1 -1
  78. package/dist/components/ui/slider.d.ts +37 -31
  79. package/dist/components/ui/slider.d.ts.map +1 -1
  80. package/dist/components/ui/sonner.d.ts +280 -46
  81. package/dist/components/ui/sonner.d.ts.map +1 -1
  82. package/dist/components/ui/stack.d.ts +289 -148
  83. package/dist/components/ui/stack.d.ts.map +1 -1
  84. package/dist/components/ui/stories/aspect-ratio.stories.d.ts +1 -2
  85. package/dist/components/ui/stories/aspect-ratio.stories.d.ts.map +1 -1
  86. package/dist/components/ui/stories/container.stories.d.ts +2 -3
  87. package/dist/components/ui/stories/container.stories.d.ts.map +1 -1
  88. package/dist/components/ui/stories/empty-state.stories.d.ts +2 -2
  89. package/dist/components/ui/stories/scroll-area.stories.d.ts +1 -2
  90. package/dist/components/ui/stories/scroll-area.stories.d.ts.map +1 -1
  91. package/dist/components/ui/stories/stack.stories.d.ts +1 -1
  92. package/dist/components/ui/stories/text-field.stories.d.ts +7 -1
  93. package/dist/components/ui/stories/text-field.stories.d.ts.map +1 -1
  94. package/dist/components/ui/switch.d.ts +44 -38
  95. package/dist/components/ui/switch.d.ts.map +1 -1
  96. package/dist/components/ui/table.d.ts +33 -0
  97. package/dist/components/ui/table.d.ts.map +1 -1
  98. package/dist/components/ui/tabs.d.ts +4 -22
  99. package/dist/components/ui/tabs.d.ts.map +1 -1
  100. package/dist/components/ui/text-field.d.ts +170 -84
  101. package/dist/components/ui/text-field.d.ts.map +1 -1
  102. package/dist/components/ui/textarea.d.ts +106 -29
  103. package/dist/components/ui/textarea.d.ts.map +1 -1
  104. package/dist/components/ui/theme-toggle.d.ts +190 -65
  105. package/dist/components/ui/theme-toggle.d.ts.map +1 -1
  106. package/dist/components/ui/theme.d.ts +107 -23
  107. package/dist/components/ui/theme.d.ts.map +1 -1
  108. package/dist/components/ui/toggle-group.d.ts +143 -67
  109. package/dist/components/ui/toggle-group.d.ts.map +1 -1
  110. package/dist/components/ui/toggle.d.ts +118 -30
  111. package/dist/components/ui/toggle.d.ts.map +1 -1
  112. package/dist/components/ui/tooltip.d.ts +152 -28
  113. package/dist/components/ui/tooltip.d.ts.map +1 -1
  114. package/dist/components/ui/typography.d.ts +452 -134
  115. package/dist/components/ui/typography.d.ts.map +1 -1
  116. package/dist/index.js +9388 -8281
  117. package/dist/index.js.map +1 -1
  118. package/dist/tsconfig.tsbuildinfo +1 -1
  119. package/llms.txt +173 -3
  120. package/package.json +5 -2
  121. package/src/components/ui/accordion.tsx +112 -27
  122. package/src/components/ui/alert-dialog.tsx +401 -46
  123. package/src/components/ui/alert.tsx +114 -11
  124. package/src/components/ui/aspect-ratio.tsx +69 -14
  125. package/src/components/ui/avatar.tsx +179 -33
  126. package/src/components/ui/badge.tsx +74 -75
  127. package/src/components/ui/breadcrumb.tsx +335 -50
  128. package/src/components/ui/button.tsx +198 -90
  129. package/src/components/ui/calendar.tsx +867 -43
  130. package/src/components/ui/card.tsx +140 -33
  131. package/src/components/ui/carousel.tsx +529 -98
  132. package/src/components/ui/chart.tsx +222 -1
  133. package/src/components/ui/checkbox.tsx +176 -38
  134. package/src/components/ui/collapsible.tsx +321 -67
  135. package/src/components/ui/combobox.tsx +284 -83
  136. package/src/components/ui/command.tsx +527 -67
  137. package/src/components/ui/container.tsx +217 -65
  138. package/src/components/ui/context-menu.tsx +716 -51
  139. package/src/components/ui/date-picker.tsx +228 -38
  140. package/src/components/ui/dialog.tsx +270 -33
  141. package/src/components/ui/drawer.tsx +546 -67
  142. package/src/components/ui/dropdown-menu.tsx +657 -74
  143. package/src/components/ui/empty-state.tsx +241 -82
  144. package/src/components/ui/hover-card.tsx +328 -39
  145. package/src/components/ui/input.tsx +207 -44
  146. package/src/components/ui/label.tsx +98 -8
  147. package/src/components/ui/menubar.tsx +587 -54
  148. package/src/components/ui/navigation-menu.tsx +557 -128
  149. package/src/components/ui/pagination.tsx +561 -79
  150. package/src/components/ui/popover.tsx +119 -8
  151. package/src/components/ui/progress.tsx +131 -29
  152. package/src/components/ui/radio-group.tsx +260 -51
  153. package/src/components/ui/resizable.tsx +289 -63
  154. package/src/components/ui/scroll-area.tsx +377 -66
  155. package/src/components/ui/select.tsx +545 -60
  156. package/src/components/ui/separator.tsx +146 -40
  157. package/src/components/ui/sheet.tsx +348 -31
  158. package/src/components/ui/sidebar.tsx +471 -29
  159. package/src/components/ui/skeleton.tsx +114 -32
  160. package/src/components/ui/slider.tsx +77 -31
  161. package/src/components/ui/sonner.tsx +574 -46
  162. package/src/components/ui/stack.tsx +423 -101
  163. package/src/components/ui/switch.tsx +78 -39
  164. package/src/components/ui/table.tsx +170 -4
  165. package/src/components/ui/tabs.tsx +108 -22
  166. package/src/components/ui/text-field.tsx +226 -81
  167. package/src/components/ui/textarea.tsx +180 -29
  168. package/src/components/ui/theme-toggle.tsx +313 -65
  169. package/src/components/ui/theme.tsx +117 -23
  170. package/src/components/ui/toggle-group.tsx +280 -69
  171. package/src/components/ui/toggle.tsx +124 -35
  172. package/src/components/ui/tooltip.tsx +239 -29
  173. package/src/components/ui/typography.tsx +1115 -165
@@ -3,12 +3,20 @@ import { cva, type VariantProps } from "class-variance-authority";
3
3
 
4
4
  import { cn } from "@/lib/utils";
5
5
 
6
+ /**
7
+ * Alert variant styles configuration with semantic color schemes
8
+ *
9
+ * @variant default - Standard informational alert with neutral colors
10
+ * @variant destructive - Error or warning alert with red color scheme for critical messages
11
+ */
6
12
  const alertVariants = cva(
7
13
  "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
8
14
  {
9
15
  variants: {
10
16
  variant: {
17
+ /** Standard informational alert with neutral card background and foreground colors */
11
18
  default: "bg-card text-card-foreground",
19
+ /** Error or destructive action alert with destructive color scheme and enhanced contrast */
12
20
  destructive:
13
21
  "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
14
22
  },
@@ -19,6 +27,42 @@ const alertVariants = cva(
19
27
  },
20
28
  );
21
29
 
30
+ /**
31
+ * Props for Alert component (Documentation only - NOT used in component implementation)
32
+ * These types are for documentation generation and should not replace CVA/Radix inferred types
33
+ */
34
+ // eslint-disable-next-line unused-imports/no-unused-vars
35
+ type AlertDocsProps = {
36
+ /** Visual style variant determining colors and emphasis @default "default" */
37
+ variant?: "default" | "destructive";
38
+ /** Additional CSS classes to merge with default alert styles */
39
+ className?: string;
40
+ /** Alert content including optional icons, titles, and descriptions */
41
+ children?: React.ReactNode;
42
+ } & React.HTMLAttributes<HTMLDivElement>;
43
+
44
+ /**
45
+ * Props for AlertTitle component (Documentation only)
46
+ */
47
+ // eslint-disable-next-line unused-imports/no-unused-vars
48
+ type AlertTitleDocsProps = {
49
+ /** Additional CSS classes for custom styling */
50
+ className?: string;
51
+ /** Title text or rich content to display */
52
+ children?: React.ReactNode;
53
+ } & React.HTMLAttributes<HTMLDivElement>;
54
+
55
+ /**
56
+ * Props for AlertDescription component (Documentation only)
57
+ */
58
+ // eslint-disable-next-line unused-imports/no-unused-vars
59
+ type AlertDescriptionDocsProps = {
60
+ /** Additional CSS classes for custom styling */
61
+ className?: string;
62
+ /** Description text or rich content (supports paragraphs, links, etc.) */
63
+ children?: React.ReactNode;
64
+ } & React.HTMLAttributes<HTMLDivElement>;
65
+
22
66
  /**
23
67
  * Alert - Display important messages and notifications to users
24
68
  *
@@ -131,7 +175,7 @@ function Alert({
131
175
  className,
132
176
  variant,
133
177
  ...props
134
- }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
178
+ }: React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>) {
135
179
  return (
136
180
  <div
137
181
  data-slot="alert"
@@ -188,7 +232,10 @@ function Alert({
188
232
  * @see {@link AlertDescription} - Companion description component
189
233
  * @since 1.0.0
190
234
  */
191
- function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
235
+ function AlertTitle({
236
+ className,
237
+ ...props
238
+ }: React.HTMLAttributes<HTMLDivElement>) {
192
239
  return (
193
240
  <div
194
241
  data-slot="alert-title"
@@ -202,32 +249,88 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
202
249
  }
203
250
 
204
251
  /**
205
- * AlertDescription - Detailed description text for an alert
252
+ * AlertDescription - Detailed description text content for alerts
206
253
  *
207
- * Provides additional context or instructions related to the alert.
208
- * Supports multiple paragraphs and rich text content.
254
+ * The body content area of an alert that provides detailed information, context,
255
+ * or instructions related to the alert message. Automatically styled with muted
256
+ * text color and proper grid positioning. Supports rich content including
257
+ * paragraphs, links, and inline formatting.
258
+ *
259
+ * ## Features
260
+ * - Muted foreground color for visual hierarchy
261
+ * - Proper grid positioning (col-start-2) for icon layout compatibility
262
+ * - Support for multiple paragraphs with relaxed line height
263
+ * - Grid layout with start justification for text alignment
264
+ * - Semantic HTML structure with data-slot attribute
265
+ * - Small text size (text-sm) for readability
266
+ * - Responsive gap spacing between content elements
267
+ *
268
+ * @example
269
+ * ```tsx
270
+ * // Basic description with simple text
271
+ * <Alert>
272
+ * <AlertTitle>Success</AlertTitle>
273
+ * <AlertDescription>
274
+ * Your account has been created successfully.
275
+ * </AlertDescription>
276
+ * </Alert>
277
+ * ```
278
+ *
279
+ * @example
280
+ * ```tsx
281
+ * // Description with multiple paragraphs
282
+ * <Alert variant="destructive">
283
+ * <AlertCircle className="size-4" />
284
+ * <AlertTitle>Connection Error</AlertTitle>
285
+ * <AlertDescription>
286
+ * <p>Unable to connect to the server. This could be due to:</p>
287
+ * <p>• Network connectivity issues</p>
288
+ * <p>• Server maintenance</p>
289
+ * <p>Please try again in a few minutes.</p>
290
+ * </AlertDescription>
291
+ * </Alert>
292
+ * ```
209
293
  *
210
- * @component
211
294
  * @example
212
295
  * ```tsx
296
+ * // Description with links and rich content
213
297
  * <Alert>
214
- * <AlertTitle>Note</AlertTitle>
298
+ * <Info className="size-4" />
299
+ * <AlertTitle>Update Available</AlertTitle>
215
300
  * <AlertDescription>
216
- * Your changes have been saved. You can continue editing or publish when ready.
301
+ * A new version is available. <a href="/changelog" className="underline">View changelog</a> or
302
+ * <button className="ml-1 underline">update now</button>.
303
+ * </AlertDescription>
304
+ * </Alert>
305
+ * ```
306
+ *
307
+ * @example
308
+ * ```tsx
309
+ * // Custom styled description
310
+ * <Alert>
311
+ * <AlertTitle>Custom Alert</AlertTitle>
312
+ * <AlertDescription className="text-sm font-medium text-foreground">
313
+ * This description uses custom styling to override the default muted appearance.
217
314
  * </AlertDescription>
218
315
  * </Alert>
219
316
  * ```
220
317
  *
221
318
  * @accessibility
222
- * - Uses appropriate text color for readability
223
- * - Supports paragraph spacing for long content
319
+ * - Properly associated with the alert container via DOM structure
320
+ * - Uses muted text color while maintaining sufficient contrast ratios
321
+ * - Supports paragraph spacing and line height for readability
322
+ * - Screen readers announce description content as part of the alert
323
+ * - Rich content like links and buttons remain keyboard accessible
324
+ * - Works with dark mode via CSS custom properties
224
325
  *
326
+ * @see {@link Alert} - Parent alert container component
327
+ * @see {@link AlertTitle} - Companion title component for headers
225
328
  * @since 1.0.0
226
329
  */
227
330
  function AlertDescription({
228
331
  className,
229
332
  ...props
230
- }: React.ComponentProps<"div">) {
333
+ }: React.HTMLAttributes<HTMLDivElement>) {
231
334
  return (
232
335
  <div
233
336
  data-slot="alert-description"
@@ -1,7 +1,24 @@
1
+ import * as React from "react";
1
2
  import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
2
3
 
3
4
  /**
4
- * AspectRatio component for maintaining consistent width-to-height ratios
5
+ * Props for AspectRatio (Documentation only - NOT used in component implementation)
6
+ * These types are for documentation generation and should not replace Radix inferred types
7
+ */
8
+ // eslint-disable-next-line unused-imports/no-unused-vars
9
+ type AspectRatioDocsProps = {
10
+ /** The desired aspect ratio as width divided by height (e.g., 16/9, 4/3, 1) @default 1 */
11
+ ratio?: number;
12
+ /** Child elements to be constrained within the aspect ratio container */
13
+ children?: React.ReactNode;
14
+ /** Additional CSS class names for custom styling */
15
+ className?: string;
16
+ /** Change the default rendered element for the one passed as a child, merging their props and behavior @default false */
17
+ asChild?: boolean;
18
+ } & React.HTMLAttributes<HTMLDivElement>;
19
+
20
+ /**
21
+ * AspectRatio - Maintains consistent width-to-height ratios for content
5
22
  *
6
23
  * A foundational layout component that preserves specific aspect ratios regardless
7
24
  * of container size. Essential for responsive images, videos, and media content that
@@ -10,7 +27,8 @@ import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
10
27
  *
11
28
  * This component creates a CSS-based aspect ratio container using the modern
12
29
  * `aspect-ratio` property, ensuring content maintains its intended proportions
13
- * without layout shifts or JavaScript calculations.
30
+ * without layout shifts or JavaScript calculations. The component acts as a
31
+ * constraint wrapper that forces its children to maintain the specified ratio.
14
32
  *
15
33
  * @example Basic image with 16:9 aspect ratio
16
34
  * ```tsx
@@ -36,7 +54,7 @@ import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
36
54
  * </AspectRatio>
37
55
  * ```
38
56
  *
39
- * @example Video player container
57
+ * @example Video player with 16:9 widescreen ratio
40
58
  * ```tsx
41
59
  * <div className="w-full max-w-2xl">
42
60
  * <AspectRatio ratio={16 / 9}>
@@ -49,7 +67,7 @@ import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
49
67
  * </div>
50
68
  * ```
51
69
  *
52
- * @example Responsive image gallery with portrait orientation
70
+ * @example Portrait orientation for image galleries
53
71
  * ```tsx
54
72
  * <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
55
73
  * {images.map((image) => (
@@ -76,24 +94,61 @@ import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
76
94
  * </AspectRatio>
77
95
  * ```
78
96
  *
97
+ * @example Using asChild for composition
98
+ * ```tsx
99
+ * <AspectRatio ratio={16 / 9} asChild>
100
+ * <div className="bg-gradient-to-br from-blue-400 to-purple-600 rounded-lg p-6">
101
+ * <h3 className="text-white text-xl font-bold">Custom Content</h3>
102
+ * </div>
103
+ * </AspectRatio>
104
+ * ```
105
+ *
106
+ * @example Common aspect ratios for different use cases
107
+ * ```tsx
108
+ * // Square (social media posts, avatars)
109
+ * <AspectRatio ratio={1}>Content</AspectRatio>
110
+ *
111
+ * // 16:9 (videos, hero images, banners)
112
+ * <AspectRatio ratio={16 / 9}>Content</AspectRatio>
113
+ *
114
+ * // 4:3 (traditional photos, tablets)
115
+ * <AspectRatio ratio={4 / 3}>Content</AspectRatio>
116
+ *
117
+ * // 3:2 (35mm photos, DSLR images)
118
+ * <AspectRatio ratio={3 / 2}>Content</AspectRatio>
119
+ *
120
+ * // 9:16 (mobile stories, vertical videos)
121
+ * <AspectRatio ratio={9 / 16}>Content</AspectRatio>
122
+ * ```
123
+ *
79
124
  * @param ratio - The desired aspect ratio as width/height (e.g., 16/9, 4/3, 1)
80
125
  * @param children - Content to be constrained within the aspect ratio
81
126
  * @param className - Additional CSS classes for styling
127
+ * @param asChild - Merge props with child element instead of wrapping
128
+ * @param ref - React ref forwarded to the container element
82
129
  *
83
130
  * @accessibility
84
131
  * - Inherits all accessibility features from Radix UI AspectRatio primitive
85
- * - Preserves semantic meaning of child content
86
- * - Does not interfere with screen reader navigation
87
- * - Maintains keyboard navigation for interactive child elements
132
+ * - Preserves semantic meaning and structure of child content
133
+ * - Does not interfere with screen reader navigation or content reading
134
+ * - Maintains proper keyboard navigation for interactive child elements
135
+ * - Supports ARIA attributes passed through props
136
+ * - Container is semantically neutral and doesn't affect focus management
88
137
  *
89
- * @see {@link https://ui.shadcn.com/docs/components/aspect-ratio} shadcn/ui documentation
90
- * @since 1.0.0
138
+ * @see {@link https://ui.shadcn.com/docs/components/aspect-ratio} shadcn/ui AspectRatio
91
139
  * @see {@link https://www.radix-ui.com/primitives/docs/components/aspect-ratio} Radix UI AspectRatio
140
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio} CSS aspect-ratio property
141
+ * @since 1.0.0
92
142
  */
93
- function AspectRatio({
94
- ...props
95
- }: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
96
- return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />;
97
- }
143
+ const AspectRatio = React.forwardRef<
144
+ React.ElementRef<typeof AspectRatioPrimitive.Root>,
145
+ React.ComponentPropsWithoutRef<typeof AspectRatioPrimitive.Root>
146
+ >((props, ref) => {
147
+ return (
148
+ <AspectRatioPrimitive.Root ref={ref} data-slot="aspect-ratio" {...props} />
149
+ );
150
+ });
151
+
152
+ AspectRatio.displayName = "AspectRatio";
98
153
 
99
154
  export { AspectRatio };
@@ -3,6 +3,68 @@ import * as AvatarPrimitive from "@radix-ui/react-avatar";
3
3
 
4
4
  import { cn } from "@/lib/utils";
5
5
 
6
+ // ============================================================================
7
+ // DOCUMENTATION-ONLY PROP TYPES (Internal - Not exported)
8
+ // ============================================================================
9
+
10
+ /**
11
+ * Props for Avatar (Documentation only - NOT used in component implementation)
12
+ * These types are for documentation generation and should not replace Radix inferred types
13
+ */
14
+ // eslint-disable-next-line unused-imports/no-unused-vars
15
+ type AvatarDocsProps = {
16
+ /** Additional CSS classes for styling. Common patterns include size utilities (size-6, size-8, size-10, size-12, size-16) and border radius overrides (rounded-lg, rounded-md, rounded-none) */
17
+ className?: string;
18
+ /** Should contain AvatarImage and AvatarFallback components for proper functionality */
19
+ children?: React.ReactNode;
20
+ /** Change the default rendered element for the one passed as a child, merging their props and behavior
21
+ * @default false
22
+ */
23
+ asChild?: boolean;
24
+ } & React.HTMLAttributes<HTMLSpanElement>;
25
+
26
+ /**
27
+ * Props for AvatarImage (Documentation only - NOT used in component implementation)
28
+ * These types are for documentation generation and should not replace Radix inferred types
29
+ */
30
+ // eslint-disable-next-line unused-imports/no-unused-vars
31
+ type AvatarImageDocsProps = {
32
+ /** The URL of the image to display. Can be relative or absolute URL */
33
+ src?: string;
34
+ /** Descriptive alternative text for the image. Should describe the person or entity, not just "avatar" or "profile picture" */
35
+ alt?: string;
36
+ /** Additional CSS classes to apply to the image element */
37
+ className?: string;
38
+ /** Optional callback fired when the loading status changes
39
+ * @param status The current loading status: "idle" | "loading" | "loaded" | "error"
40
+ */
41
+ onLoadingStatusChange?: (
42
+ status: "idle" | "loading" | "loaded" | "error",
43
+ ) => void;
44
+ /** Change the default rendered element for the one passed as a child, merging their props and behavior
45
+ * @default false
46
+ */
47
+ asChild?: boolean;
48
+ } & React.ImgHTMLAttributes<HTMLImageElement>;
49
+
50
+ /**
51
+ * Props for AvatarFallback (Documentation only - NOT used in component implementation)
52
+ * These types are for documentation generation and should not replace Radix inferred types
53
+ */
54
+ // eslint-disable-next-line unused-imports/no-unused-vars
55
+ type AvatarFallbackDocsProps = {
56
+ /** The fallback content to display. Common patterns include user initials (2-3 characters), icons, or loading indicators */
57
+ children?: React.ReactNode;
58
+ /** Additional CSS classes. Use for custom background colors, text styling, or animations */
59
+ className?: string;
60
+ /** Optional delay in milliseconds before showing the fallback (Radix UI feature). Useful for delaying rendering so it only appears for those with slower connections */
61
+ delayMs?: number;
62
+ /** Change the default rendered element for the one passed as a child, merging their props and behavior
63
+ * @default false
64
+ */
65
+ asChild?: boolean;
66
+ } & React.HTMLAttributes<HTMLSpanElement>;
67
+
6
68
  /**
7
69
  * Avatar - A flexible container for displaying user profile images with graceful fallback support
8
70
  *
@@ -20,6 +82,7 @@ import { cn } from "@/lib/utils";
20
82
  * - **Shape variants**: Circular by default with support for rounded corners
21
83
  * - **Accessibility first**: Built-in ARIA attributes and keyboard navigation
22
84
  * - **Composable design**: Works with AvatarImage and AvatarFallback sub-components
85
+ * - **Polymorphic rendering**: Supports asChild prop for custom element rendering
23
86
  *
24
87
  * ## Common Use Cases
25
88
  * - User profile displays in headers and navigation
@@ -88,8 +151,20 @@ import { cn } from "@/lib/utils";
88
151
  * </div>
89
152
  * ```
90
153
  *
154
+ * @example Using asChild for custom elements
155
+ * ```tsx
156
+ * <Avatar asChild>
157
+ * <button onClick={handleClick}>
158
+ * <AvatarImage src="/user.jpg" alt="User Profile" />
159
+ * <AvatarFallback>UP</AvatarFallback>
160
+ * </button>
161
+ * </Avatar>
162
+ * ```
163
+ *
91
164
  * @param className Additional CSS classes for styling. Common patterns include size utilities (size-6, size-8, size-10, size-12, size-16) and border radius overrides (rounded-lg, rounded-md, rounded-none)
92
165
  * @param children Should contain AvatarImage and AvatarFallback components for proper functionality
166
+ * @param asChild Change the default rendered element for the one passed as a child, merging their props and behavior
167
+ * @default false
93
168
  *
94
169
  * @accessibility
95
170
  * - Automatically manages focus and ARIA attributes through Radix UI
@@ -98,6 +173,7 @@ import { cn } from "@/lib/utils";
98
173
  * - Ensure sufficient color contrast for fallback text (minimum 4.5:1 ratio)
99
174
  * - Component supports keyboard navigation and screen reader announcements
100
175
  * - Status indicators should include appropriate ARIA labels
176
+ * - When using asChild with interactive elements, ensure proper focus management
101
177
  *
102
178
  * @see {@link AvatarImage} The image component for displaying avatar pictures
103
179
  * @see {@link AvatarFallback} The fallback component for displaying initials or icons when images fail
@@ -130,16 +206,23 @@ function Avatar({
130
206
  * and the AvatarFallback will be displayed instead.
131
207
  *
132
208
  * ## Key Features
133
- * - Automatic image loading state management
134
- * - Graceful error handling for broken image URLs
135
- * - Proper aspect ratio maintenance (square by default)
136
- * - Inherits parent Avatar's size and border radius
137
- * - Accessible image implementation
209
+ * - **Automatic loading state management**: Handles "idle", "loading", "loaded", and "error" states
210
+ * - **Graceful error handling**: Automatically falls back when images fail to load
211
+ * - **Proper aspect ratio maintenance**: Square aspect ratio maintained by default
212
+ * - **Flexible rendering**: Supports asChild for custom element composition
213
+ * - **Loading status callbacks**: Provides onLoadingStatusChange for custom loading logic
214
+ * - **Accessible implementation**: Proper alt text handling and ARIA support
215
+ *
216
+ * ## Loading States
217
+ * The component automatically manages these states:
218
+ * - **idle**: Initial state before loading begins
219
+ * - **loading**: Image is currently being loaded
220
+ * - **loaded**: Image has loaded successfully and is displayed
221
+ * - **error**: Image failed to load, fallback will be shown
138
222
  *
139
223
  * @component
140
- * @example
224
+ * @example Basic usage with remote image
141
225
  * ```tsx
142
- * // Basic usage with remote image
143
226
  * <Avatar>
144
227
  * <AvatarImage
145
228
  * src="https://github.com/username.png"
@@ -149,9 +232,8 @@ function Avatar({
149
232
  * </Avatar>
150
233
  * ```
151
234
  *
152
- * @example
235
+ * @example Local image with descriptive alt text
153
236
  * ```tsx
154
- * // Local image with descriptive alt text
155
237
  * <Avatar>
156
238
  * <AvatarImage
157
239
  * src="/uploads/user-avatar.jpg"
@@ -161,19 +243,51 @@ function Avatar({
161
243
  * </Avatar>
162
244
  * ```
163
245
  *
164
- * @param src - The URL of the image to display. Can be relative or absolute URL
165
- * @param alt - Descriptive alternative text for the image. Should describe the person or entity, not just "avatar" or "profile picture"
166
- * @param className - Additional CSS classes to apply to the image element
167
- * @param onLoadingStatusChange - Optional callback fired when the loading status changes
246
+ * @example With loading status callback
247
+ * ```tsx
248
+ * <Avatar>
249
+ * <AvatarImage
250
+ * src="/large-image.jpg"
251
+ * alt="High resolution avatar"
252
+ * onLoadingStatusChange={(status) => {
253
+ * if (status === 'loading') {
254
+ * console.log('Image is loading...');
255
+ * } else if (status === 'error') {
256
+ * console.log('Failed to load image');
257
+ * }
258
+ * }}
259
+ * />
260
+ * <AvatarFallback>HR</AvatarFallback>
261
+ * </Avatar>
262
+ * ```
263
+ *
264
+ * @example Using asChild for custom image elements
265
+ * ```tsx
266
+ * <Avatar>
267
+ * <AvatarImage src="/user.jpg" alt="User" asChild>
268
+ * <img loading="lazy" decoding="async" />
269
+ * </AvatarImage>
270
+ * <AvatarFallback>U</AvatarFallback>
271
+ * </Avatar>
272
+ * ```
273
+ *
274
+ * @param src The URL of the image to display. Can be relative or absolute URL. When src changes, loading will restart
275
+ * @param alt Descriptive alternative text for the image. Should describe the person or entity, not just "avatar" or "profile picture"
276
+ * @param className Additional CSS classes to apply to the image element. Applied to the img element or asChild component
277
+ * @param onLoadingStatusChange Optional callback fired when the loading status changes. Receives status: "idle" | "loading" | "loaded" | "error"
278
+ * @param asChild Change the default rendered element for the one passed as a child, merging their props and behavior
279
+ * @default false
168
280
  *
169
281
  * @accessibility
170
282
  * - Always provide descriptive alt text that identifies the person or entity
171
283
  * - The image is automatically hidden from assistive technologies when loading or failed
172
284
  * - Use meaningful descriptions like "John Doe's profile picture" rather than generic terms
173
285
  * - The component handles ARIA attributes automatically via Radix UI
286
+ * - Loading and error states are communicated to screen readers appropriately
174
287
  *
175
- * @see {@link Avatar} - The parent container component
176
- * @see {@link AvatarFallback} - The fallback component shown when image is unavailable
288
+ * @see {@link Avatar} The parent container component
289
+ * @see {@link AvatarFallback} The fallback component shown when image is unavailable
290
+ * @see {@link https://www.radix-ui.com/docs/primitives/components/avatar#image} Radix UI Avatar.Image API
177
291
  * @since 1.0.0
178
292
  */
179
293
  function AvatarImage({
@@ -196,32 +310,39 @@ function AvatarImage({
196
310
  * or is not provided. It's built on Radix UI's Avatar.Fallback primitive and provides a
197
311
  * visually appealing placeholder that maintains the avatar's design consistency.
198
312
  *
313
+ * ## When AvatarFallback is Shown
314
+ * The fallback is automatically displayed in these scenarios:
315
+ * - **Image loading**: While the AvatarImage is being loaded
316
+ * - **Image error**: When the AvatarImage fails to load (broken URL, network error)
317
+ * - **No image**: When no AvatarImage component is provided
318
+ * - **Empty src**: When AvatarImage has no src prop or empty src
319
+ *
199
320
  * ## Common Use Cases
200
- * - User initials (most common pattern)
201
- * - Generic user icons
202
- * - Company/brand initials for organization avatars
203
- * - Loading states with animations
204
- * - Placeholder content for new users
321
+ * - **User initials**: Most common pattern (2-3 characters)
322
+ * - **Generic icons**: User, person, or company icons
323
+ * - **Brand initials**: For organization avatars
324
+ * - **Loading states**: With animations or loading indicators
325
+ * - **Placeholder content**: For new or anonymous users
326
+ * - **Custom graphics**: SVG icons or other visual elements
205
327
  *
206
328
  * ## Design Considerations
207
329
  * - Uses muted background color for subtle appearance
208
330
  * - Automatically centers content both horizontally and vertically
209
331
  * - Inherits size and border radius from parent Avatar
210
332
  * - Should complement the overall design system
333
+ * - Supports delay to prevent flash during fast image loads
211
334
  *
212
335
  * @component
213
- * @example
336
+ * @example User initials (recommended pattern)
214
337
  * ```tsx
215
- * // User initials (recommended pattern)
216
338
  * <Avatar>
217
339
  * <AvatarImage src="/avatar.jpg" alt="John Doe" />
218
340
  * <AvatarFallback>JD</AvatarFallback>
219
341
  * </Avatar>
220
342
  * ```
221
343
  *
222
- * @example
344
+ * @example Icon fallback for unknown users
223
345
  * ```tsx
224
- * // Icon fallback for unknown users
225
346
  * import { User } from "lucide-react";
226
347
  *
227
348
  * <Avatar>
@@ -232,9 +353,8 @@ function AvatarImage({
232
353
  * </Avatar>
233
354
  * ```
234
355
  *
235
- * @example
356
+ * @example Custom colored fallback
236
357
  * ```tsx
237
- * // Custom colored fallback
238
358
  * <Avatar>
239
359
  * <AvatarImage src="/user.jpg" alt="Jane Smith" />
240
360
  * <AvatarFallback className="bg-blue-500 text-white">
@@ -243,9 +363,8 @@ function AvatarImage({
243
363
  * </Avatar>
244
364
  * ```
245
365
  *
246
- * @example
366
+ * @example Loading state with animation
247
367
  * ```tsx
248
- * // Loading state with animation
249
368
  * <Avatar>
250
369
  * <AvatarImage src="/loading-image.jpg" alt="Loading" />
251
370
  * <AvatarFallback className="animate-pulse">
@@ -254,9 +373,34 @@ function AvatarImage({
254
373
  * </Avatar>
255
374
  * ```
256
375
  *
257
- * @param children - The fallback content to display. Common patterns include user initials (2-3 characters), icons, or loading indicators
258
- * @param className - Additional CSS classes. Use for custom background colors, text styling, or animations
259
- * @param delayMs - Optional delay in milliseconds before showing the fallback (Radix UI feature)
376
+ * @example With delay to prevent flash
377
+ * ```tsx
378
+ * <Avatar>
379
+ * <AvatarImage src="/slow-loading-image.jpg" alt="User" />
380
+ * <AvatarFallback delayMs={600}>
381
+ * UN
382
+ * </AvatarFallback>
383
+ * </Avatar>
384
+ * ```
385
+ *
386
+ * @example Using asChild for custom elements
387
+ * ```tsx
388
+ * <Avatar>
389
+ * <AvatarImage src="/user.jpg" alt="User" />
390
+ * <AvatarFallback asChild>
391
+ * <div className="bg-gradient-to-br from-blue-400 to-purple-600">
392
+ * <span className="text-white font-semibold">UN</span>
393
+ * </div>
394
+ * </AvatarFallback>
395
+ * </Avatar>
396
+ * ```
397
+ *
398
+ * @param children The fallback content to display. Common patterns include user initials (2-3 characters), icons, or loading indicators
399
+ * @param className Additional CSS classes. Use for custom background colors, text styling, or animations
400
+ * @param delayMs Optional delay in milliseconds before showing the fallback. Useful for delaying rendering so it only appears for those with slower connections
401
+ * @default undefined
402
+ * @param asChild Change the default rendered element for the one passed as a child, merging their props and behavior
403
+ * @default false
260
404
  *
261
405
  * @accessibility
262
406
  * - Content should be meaningful and descriptive
@@ -264,9 +408,11 @@ function AvatarImage({
264
408
  * - Keep text concise - typically 1-3 characters for initials
265
409
  * - Icons should have appropriate sizing relative to the avatar
266
410
  * - The component is automatically accessible via Radix UI implementation
411
+ * - Consider adding aria-label for complex fallback content
267
412
  *
268
- * @see {@link Avatar} - The parent container component
269
- * @see {@link AvatarImage} - The image component that this component provides fallback for
413
+ * @see {@link Avatar} The parent container component
414
+ * @see {@link AvatarImage} The image component that this component provides fallback for
415
+ * @see {@link https://www.radix-ui.com/docs/primitives/components/avatar#fallback} Radix UI Avatar.Fallback API
270
416
  * @since 1.0.0
271
417
  */
272
418
  function AvatarFallback({