@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
@@ -4,12 +4,92 @@ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
4
4
  import { cn } from "@/lib/utils";
5
5
 
6
6
  /**
7
- * ScrollArea component provides cross-browser custom scrollbar styling
7
+ * Props for ScrollArea (Documentation only - NOT used in component implementation)
8
+ * These types are for documentation generation and should not replace Radix inferred types
9
+ */
10
+ // eslint-disable-next-line unused-imports/no-unused-vars
11
+ type ScrollAreaDocsProps = {
12
+ /** Additional CSS classes for styling */
13
+ className?: string;
14
+ /** Child elements to be rendered inside the scrollable area */
15
+ children?: React.ReactNode;
16
+ /** Describes the nature of scrollbar visibility @default "hover" */
17
+ type?: "auto" | "always" | "scroll" | "hover";
18
+ /** Time in milliseconds before scrollbars hide when type is "hover" @default 600 */
19
+ scrollHideDelay?: number;
20
+ /** Text direction for internationalization */
21
+ dir?: "ltr" | "rtl";
22
+ /** Nonce attribute for Content Security Policy */
23
+ nonce?: string;
24
+ /** Whether to render as its child element instead @default false */
25
+ asChild?: boolean;
26
+ } & React.HTMLAttributes<HTMLDivElement>;
27
+
28
+ /**
29
+ * Props for ScrollBar (Documentation only - NOT used in component implementation)
30
+ * These types are for documentation generation and should not replace Radix inferred types
31
+ */
32
+ // eslint-disable-next-line unused-imports/no-unused-vars
33
+ type ScrollBarDocsProps = {
34
+ /** Scrollbar orientation, controls which axis the scrollbar appears on @default "vertical" */
35
+ orientation?: "vertical" | "horizontal";
36
+ /** Forces the scrollbar to remain mounted even when not needed */
37
+ forceMount?: true;
38
+ /** Whether to render as its child element instead @default false */
39
+ asChild?: boolean;
40
+ /** Additional CSS classes for styling */
41
+ className?: string;
42
+ } & React.HTMLAttributes<HTMLDivElement>;
43
+
44
+ /**
45
+ * Props for ScrollAreaViewport (Documentation only - NOT used in component implementation)
46
+ * These types are for documentation generation and should not replace Radix inferred types
47
+ */
48
+ // eslint-disable-next-line unused-imports/no-unused-vars
49
+ type ScrollAreaViewportDocsProps = {
50
+ /** Whether to render as its child element instead @default false */
51
+ asChild?: boolean;
52
+ /** Additional CSS classes for styling */
53
+ className?: string;
54
+ /** Child elements to be rendered inside the viewport */
55
+ children?: React.ReactNode;
56
+ } & React.HTMLAttributes<HTMLDivElement>;
57
+
58
+ /**
59
+ * Props for ScrollAreaThumb (Documentation only - NOT used in component implementation)
60
+ * These types are for documentation generation and should not replace Radix inferred types
61
+ */
62
+ // eslint-disable-next-line unused-imports/no-unused-vars
63
+ type ScrollAreaThumbDocsProps = {
64
+ /** Whether to render as its child element instead @default false */
65
+ asChild?: boolean;
66
+ /** Additional CSS classes for styling */
67
+ className?: string;
68
+ } & React.HTMLAttributes<HTMLDivElement>;
69
+
70
+ /**
71
+ * Props for ScrollAreaCorner (Documentation only - NOT used in component implementation)
72
+ * These types are for documentation generation and should not replace Radix inferred types
73
+ */
74
+ // eslint-disable-next-line unused-imports/no-unused-vars
75
+ type ScrollAreaCornerDocsProps = {
76
+ /** Whether to render as its child element instead @default false */
77
+ asChild?: boolean;
78
+ /** Additional CSS classes for styling */
79
+ className?: string;
80
+ } & React.HTMLAttributes<HTMLDivElement>;
81
+
82
+ /**
83
+ * ScrollArea - Custom scrollable area with cross-browser styling
8
84
  *
9
85
  * Augments native scroll functionality for custom, cross-browser styling with enhanced
10
86
  * scrolling experience. Built on Radix UI's ScrollArea primitive for accessibility
11
87
  * and keyboard navigation support. Provides consistent scrollbar appearance across
12
- * different browsers while maintaining native scroll behavior.
88
+ * different browsers while maintaining native scroll behavior and performance.
89
+ *
90
+ * The component automatically handles vertical scrolling and can be extended with
91
+ * horizontal scrolling using the ScrollBar component. Supports programmatic control
92
+ * via refs and maintains all native scrolling behaviors including touch gestures.
13
93
  *
14
94
  * @example
15
95
  * ```tsx
@@ -42,91 +122,322 @@ import { cn } from "@/lib/utils";
42
122
  *
43
123
  * @example
44
124
  * ```tsx
45
- * // Both scrollbars for large content
46
- * <ScrollArea className="h-96 w-80 rounded-md border">
125
+ * // Both scrollbars for large content with always-visible scrollbars
126
+ * <ScrollArea className="h-96 w-80 rounded-md border" type="always">
47
127
  * <div className="w-[600px] p-4">
48
- * // Wide content with vertical overflow
128
+ * <div className="space-y-4">
129
+ * {largeDataSet.map((item) => (
130
+ * <div key={item.id} className="min-w-max">
131
+ * {item.wideContent}
132
+ * </div>
133
+ * ))}
134
+ * </div>
49
135
  * </div>
50
136
  * <ScrollBar orientation="horizontal" />
51
137
  * </ScrollArea>
52
138
  * ```
53
139
  *
54
- * @param className - Additional CSS classes for styling
55
- * @param children - Content to be rendered inside the scrollable area
140
+ * @example
141
+ * ```tsx
142
+ * // Programmatic scrolling with ref
143
+ * function ProgrammaticScroll() {
144
+ * const viewportRef = useRef<HTMLDivElement>(null);
145
+ *
146
+ * const scrollToTop = () => {
147
+ * viewportRef.current?.scrollTo({ top: 0, behavior: 'smooth' });
148
+ * };
149
+ *
150
+ * return (
151
+ * <ScrollArea className="h-72 w-96">
152
+ * <ScrollAreaViewport ref={viewportRef}>
153
+ * <div className="p-4">
154
+ * // Long content here
155
+ * <button onClick={scrollToTop}>Scroll to top</button>
156
+ * </div>
157
+ * </ScrollAreaViewport>
158
+ * </ScrollArea>
159
+ * );
160
+ * }
161
+ * ```
162
+ *
163
+ * @accessibility
164
+ * - Maintains native keyboard scrolling (Arrow keys, Page Up/Down, Home/End)
165
+ * - Preserves focus management and tab order within scrollable content
166
+ * - Screen readers can navigate content naturally using standard commands
167
+ * - Supports touch gestures and momentum scrolling on mobile devices
168
+ * - Scrollbars automatically receive appropriate ARIA attributes
169
+ * - Respects user preferences for reduced motion
56
170
  *
57
- * @see {@link https://ui.shadcn.com/docs/components/scroll-area} - shadcn/ui ScrollArea documentation
171
+ * @see {@link ScrollBar} Companion scrollbar component for explicit horizontal scrolling
172
+ * @see {@link https://www.radix-ui.com/primitives/docs/components/scroll-area} Radix UI ScrollArea Primitive
173
+ * @see {@link https://ui.shadcn.com/docs/components/scroll-area} shadcn/ui ScrollArea Documentation
58
174
  * @since 1.0.0
59
- * @see {@link ScrollBar} - Companion scrollbar component for horizontal scrolling
60
175
  */
61
- function ScrollArea({
62
- className,
63
- children,
64
- ...props
65
- }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
66
- return (
67
- <ScrollAreaPrimitive.Root
68
- data-slot="scroll-area"
69
- className={cn("relative", className)}
70
- {...props}
71
- >
72
- <ScrollAreaPrimitive.Viewport
73
- data-slot="scroll-area-viewport"
74
- className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
176
+ const ScrollArea = React.forwardRef<
177
+ React.ElementRef<typeof ScrollAreaPrimitive.Root>,
178
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
179
+ >(
180
+ (
181
+ {
182
+ className,
183
+ children,
184
+ type = "hover",
185
+ scrollHideDelay = 600,
186
+ dir,
187
+ nonce,
188
+ asChild = false,
189
+ ...props
190
+ },
191
+ ref,
192
+ ) => {
193
+ return (
194
+ <ScrollAreaPrimitive.Root
195
+ ref={ref}
196
+ data-slot="scroll-area"
197
+ className={cn("relative", className)}
198
+ type={type}
199
+ scrollHideDelay={scrollHideDelay}
200
+ dir={dir}
201
+ nonce={nonce}
202
+ asChild={asChild}
203
+ {...props}
75
204
  >
76
- {children}
77
- </ScrollAreaPrimitive.Viewport>
78
- <ScrollBar />
79
- <ScrollAreaPrimitive.Corner />
80
- </ScrollAreaPrimitive.Root>
81
- );
82
- }
205
+ <ScrollAreaViewport>{children}</ScrollAreaViewport>
206
+ <ScrollBar />
207
+ <ScrollAreaCorner />
208
+ </ScrollAreaPrimitive.Root>
209
+ );
210
+ },
211
+ );
212
+ ScrollArea.displayName = "ScrollArea";
83
213
 
84
214
  /**
85
- * ScrollBar component for custom scrollbar styling
215
+ * ScrollBar - Custom styled scrollbar for ScrollArea
86
216
  *
87
217
  * Companion component to ScrollArea that renders styled scrollbars with
88
- * support for both vertical and horizontal orientations. Usually used
89
- * when explicit horizontal scrolling is needed.
218
+ * support for both vertical and horizontal orientations. The vertical
219
+ * scrollbar is automatically included in ScrollArea, but horizontal
220
+ * scrollbars must be explicitly added when needed.
90
221
  *
91
- * @param className - Additional CSS classes for scrollbar styling
92
- * @param orientation - Scrollbar orientation, defaults to "vertical"
222
+ * The scrollbar automatically shows/hides based on content overflow and
223
+ * user interaction. Supports touch interactions and provides visual
224
+ * feedback during scroll operations.
93
225
  *
94
226
  * @example
95
227
  * ```tsx
96
- * // Horizontal scrollbar (vertical is automatic)
97
- * <ScrollArea className="w-full">
98
- * <div className="flex gap-4 p-4">
99
- * // Wide content
228
+ * // Explicit horizontal scrollbar for wide content
229
+ * <ScrollArea className="w-full max-w-md">
230
+ * <div className="flex gap-4 p-4 min-w-max">
231
+ * {items.map((item) => (
232
+ * <div key={item.id} className="w-48 flex-none">
233
+ * {item.content}
234
+ * </div>
235
+ * ))}
100
236
  * </div>
101
237
  * <ScrollBar orientation="horizontal" />
102
238
  * </ScrollArea>
103
239
  * ```
240
+ *
241
+ * @example
242
+ * ```tsx
243
+ * // Both scrollbars with custom styling
244
+ * <ScrollArea className="h-64 w-64 border">
245
+ * <div className="w-96 h-96 p-4">
246
+ * Large content that overflows both axes
247
+ * </div>
248
+ * <ScrollBar orientation="vertical" className="bg-slate-100" />
249
+ * <ScrollBar orientation="horizontal" className="bg-slate-100" />
250
+ * </ScrollArea>
251
+ * ```
252
+ *
253
+ * @example
254
+ * ```tsx
255
+ * // Force-mounted scrollbar that always shows
256
+ * <ScrollArea className="h-48 w-full">
257
+ * <div className="p-4">
258
+ * Content that may or may not overflow
259
+ * </div>
260
+ * <ScrollBar orientation="horizontal" forceMount />
261
+ * </ScrollArea>
262
+ * ```
263
+ *
264
+ * @accessibility
265
+ * - Scrollbar thumb responds to keyboard interactions when focused
266
+ * - Supports drag operations for precise scrolling control
267
+ * - Automatically receives appropriate ARIA attributes for orientation
268
+ * - Visual feedback during hover and active states
269
+ * - Respects user preferences for scrollbar width and behavior
270
+ *
271
+ * @see {@link ScrollArea} Main scrollable container component
272
+ * @since 1.0.0
273
+ */
274
+ const ScrollBar = React.forwardRef<
275
+ React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
276
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
277
+ >(
278
+ (
279
+ {
280
+ className,
281
+ orientation = "vertical",
282
+ forceMount,
283
+ asChild = false,
284
+ ...props
285
+ },
286
+ ref,
287
+ ) => {
288
+ return (
289
+ <ScrollAreaPrimitive.ScrollAreaScrollbar
290
+ ref={ref}
291
+ data-slot="scroll-area-scrollbar"
292
+ orientation={orientation}
293
+ forceMount={forceMount}
294
+ asChild={asChild}
295
+ className={cn(
296
+ "flex touch-none p-px transition-colors select-none",
297
+ orientation === "vertical" &&
298
+ "h-full w-2.5 border-l border-l-transparent",
299
+ orientation === "horizontal" &&
300
+ "h-2.5 flex-col border-t border-t-transparent",
301
+ className,
302
+ )}
303
+ {...props}
304
+ >
305
+ <ScrollAreaThumb />
306
+ </ScrollAreaPrimitive.ScrollAreaScrollbar>
307
+ );
308
+ },
309
+ );
310
+ ScrollBar.displayName = "ScrollBar";
311
+
312
+ /**
313
+ * ScrollAreaViewport - The viewport area of the scroll area
314
+ *
315
+ * Contains the scrollable content and handles the actual scrolling behavior.
316
+ * This is the element that receives focus and handles keyboard navigation.
317
+ * Use refs on this component for programmatic scrolling control.
318
+ *
319
+ * @example
320
+ * ```tsx
321
+ * // Accessing viewport for programmatic scrolling
322
+ * const ScrollWithButton = () => {
323
+ * const viewportRef = useRef<HTMLDivElement>(null);
324
+ *
325
+ * const scrollToBottom = () => {
326
+ * const viewport = viewportRef.current;
327
+ * if (viewport) {
328
+ * viewport.scrollTop = viewport.scrollHeight;
329
+ * }
330
+ * };
331
+ *
332
+ * return (
333
+ * <ScrollArea className="h-64 w-96">
334
+ * <ScrollAreaViewport ref={viewportRef}>
335
+ * <div className="p-4">
336
+ * // Content here
337
+ * <button onClick={scrollToBottom}>Scroll to bottom</button>
338
+ * </div>
339
+ * </ScrollAreaViewport>
340
+ * </ScrollArea>
341
+ * );
342
+ * };
343
+ * ```
344
+ *
345
+ * @see {@link ScrollArea} Main scrollable container component
346
+ * @since 1.0.0
347
+ */
348
+ const ScrollAreaViewport = React.forwardRef<
349
+ React.ElementRef<typeof ScrollAreaPrimitive.Viewport>,
350
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Viewport>
351
+ >(({ className, children, asChild = false, ...props }, ref) => (
352
+ <ScrollAreaPrimitive.Viewport
353
+ ref={ref}
354
+ data-slot="scroll-area-viewport"
355
+ className={cn(
356
+ "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1",
357
+ className,
358
+ )}
359
+ asChild={asChild}
360
+ {...props}
361
+ >
362
+ {children}
363
+ </ScrollAreaPrimitive.Viewport>
364
+ ));
365
+ ScrollAreaViewport.displayName = "ScrollAreaViewport";
366
+
367
+ /**
368
+ * ScrollAreaThumb - The draggable thumb element within the scrollbar
369
+ *
370
+ * Represents the current scroll position and can be dragged to scroll content.
371
+ * Usually styled automatically as part of the ScrollBar component, but can
372
+ * be customized for specific design requirements.
373
+ *
374
+ * @example
375
+ * ```tsx
376
+ * // Custom scrollbar with styled thumb
377
+ * const CustomScrollbar = ({ orientation = "vertical" }) => (
378
+ * <ScrollAreaPrimitive.ScrollAreaScrollbar orientation={orientation}>
379
+ * <ScrollAreaThumb className="bg-blue-500 hover:bg-blue-600 active:bg-blue-700" />
380
+ * </ScrollAreaPrimitive.ScrollAreaScrollbar>
381
+ * );
382
+ * ```
383
+ *
384
+ * @see {@link ScrollBar} Parent scrollbar component
385
+ * @since 1.0.0
386
+ */
387
+ const ScrollAreaThumb = React.forwardRef<
388
+ React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaThumb>,
389
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaThumb>
390
+ >(({ className, asChild = false, ...props }, ref) => (
391
+ <ScrollAreaPrimitive.ScrollAreaThumb
392
+ ref={ref}
393
+ data-slot="scroll-area-thumb"
394
+ className={cn("bg-border relative flex-1 rounded-full", className)}
395
+ asChild={asChild}
396
+ {...props}
397
+ />
398
+ ));
399
+ ScrollAreaThumb.displayName = "ScrollAreaThumb";
400
+
401
+ /**
402
+ * ScrollAreaCorner - The corner element where horizontal and vertical scrollbars meet
403
+ *
404
+ * Appears when both horizontal and vertical scrollbars are present. Usually
405
+ * handled automatically by the ScrollArea component but can be customized
406
+ * for specific layout requirements.
407
+ *
408
+ * @example
409
+ * ```tsx
410
+ * // Custom corner styling
411
+ * <ScrollArea className="h-64 w-64">
412
+ * <div className="w-96 h-96 p-4">
413
+ * Content that overflows both axes
414
+ * </div>
415
+ * <ScrollBar orientation="horizontal" />
416
+ * <ScrollAreaCorner className="bg-gray-100" />
417
+ * </ScrollArea>
418
+ * ```
419
+ *
420
+ * @see {@link ScrollArea} Main scrollable container component
421
+ * @since 1.0.0
104
422
  */
105
- function ScrollBar({
106
- className,
107
- orientation = "vertical",
108
- ...props
109
- }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
110
- return (
111
- <ScrollAreaPrimitive.ScrollAreaScrollbar
112
- data-slot="scroll-area-scrollbar"
113
- orientation={orientation}
114
- className={cn(
115
- "flex touch-none p-px transition-colors select-none",
116
- orientation === "vertical" &&
117
- "h-full w-2.5 border-l border-l-transparent",
118
- orientation === "horizontal" &&
119
- "h-2.5 flex-col border-t border-t-transparent",
120
- className,
121
- )}
122
- {...props}
123
- >
124
- <ScrollAreaPrimitive.ScrollAreaThumb
125
- data-slot="scroll-area-thumb"
126
- className="bg-border relative flex-1 rounded-full"
127
- />
128
- </ScrollAreaPrimitive.ScrollAreaScrollbar>
129
- );
130
- }
423
+ const ScrollAreaCorner = React.forwardRef<
424
+ React.ElementRef<typeof ScrollAreaPrimitive.Corner>,
425
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Corner>
426
+ >(({ className, asChild = false, ...props }, ref) => (
427
+ <ScrollAreaPrimitive.Corner
428
+ ref={ref}
429
+ data-slot="scroll-area-corner"
430
+ className={className}
431
+ asChild={asChild}
432
+ {...props}
433
+ />
434
+ ));
435
+ ScrollAreaCorner.displayName = "ScrollAreaCorner";
131
436
 
132
- export { ScrollArea, ScrollBar };
437
+ export {
438
+ ScrollArea,
439
+ ScrollBar,
440
+ ScrollAreaViewport,
441
+ ScrollAreaThumb,
442
+ ScrollAreaCorner,
443
+ };