@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,6 +4,142 @@ import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
4
4
 
5
5
  import { cn } from "@/lib/utils";
6
6
 
7
+ // ============================================================================
8
+ // Documentation Props Types (Internal - Not exported)
9
+ // ============================================================================
10
+
11
+ /**
12
+ * Props for DropdownMenu (Documentation only - NOT used in component implementation)
13
+ * These types are for documentation generation and should not replace Radix inferred types
14
+ */
15
+ // eslint-disable-next-line unused-imports/no-unused-vars
16
+ type DropdownMenuDocsProps = {
17
+ /** Whether the dropdown is initially open (uncontrolled mode) @default false */
18
+ defaultOpen?: boolean;
19
+ /** Whether the dropdown is open (controlled mode) */
20
+ open?: boolean;
21
+ /** Callback fired when the open state changes */
22
+ onOpenChange?: (open: boolean) => void;
23
+ /** Whether the dropdown should be modal (blocks interaction with outside elements) @default true */
24
+ modal?: boolean;
25
+ /** The reading direction of the dropdown menu @default "ltr" */
26
+ dir?: "ltr" | "rtl";
27
+ /** Child elements - typically DropdownMenuTrigger and DropdownMenuContent */
28
+ children?: React.ReactNode;
29
+ } & React.ComponentProps<typeof DropdownMenuPrimitive.Root>;
30
+
31
+ /** Props for DropdownMenuTrigger (Documentation only) */
32
+ // eslint-disable-next-line unused-imports/no-unused-vars
33
+ type DropdownMenuTriggerDocsProps = {
34
+ /** Merge props onto the immediate child instead of rendering a wrapper element @default false */
35
+ asChild?: boolean;
36
+ /** Child element that will trigger the dropdown menu */
37
+ children?: React.ReactNode;
38
+ } & React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>;
39
+
40
+ /** Props for DropdownMenuContent (Documentation only) */
41
+ // eslint-disable-next-line unused-imports/no-unused-vars
42
+ type DropdownMenuContentDocsProps = {
43
+ /** Merge props onto the immediate child instead of rendering a wrapper element @default false */
44
+ asChild?: boolean;
45
+ /** When true, keyboard navigation will loop from last to first item and vice versa @default false */
46
+ loop?: boolean;
47
+ /** The preferred side of the trigger to render against @default "bottom" */
48
+ side?: "top" | "right" | "bottom" | "left";
49
+ /** Distance in pixels from the trigger @default 4 */
50
+ sideOffset?: number;
51
+ /** The preferred alignment against the trigger @default "center" */
52
+ align?: "start" | "center" | "end";
53
+ /** Distance in pixels from the align point @default 0 */
54
+ alignOffset?: number;
55
+ /** Whether to avoid collisions with viewport boundaries @default true */
56
+ avoidCollisions?: boolean;
57
+ /** Element positioning behavior relative to the viewport */
58
+ sticky?: "partial" | "always";
59
+ /** Whether to hide the content when the reference element is fully occluded @default false */
60
+ hideWhenDetached?: boolean;
61
+ /** CSS class name for custom styling */
62
+ className?: string;
63
+ /** Child menu items, labels, separators, and groups */
64
+ children?: React.ReactNode;
65
+ } & React.ComponentProps<typeof DropdownMenuPrimitive.Content>;
66
+
67
+ /** Props for DropdownMenuItem (Documentation only) */
68
+ // eslint-disable-next-line unused-imports/no-unused-vars
69
+ type DropdownMenuItemDocsProps = {
70
+ /** Whether the item is disabled and cannot be selected @default false */
71
+ disabled?: boolean;
72
+ /** Callback fired when the item is selected via click or keyboard */
73
+ onSelect?: (event: Event) => void;
74
+ /** Optional text value used for typeahead search functionality */
75
+ textValue?: string;
76
+ /** Whether to add extra left padding to align with items that have icons @default false */
77
+ inset?: boolean;
78
+ /** Visual variant of the menu item for semantic distinction @default "default" */
79
+ variant?: "default" | "destructive";
80
+ /** CSS class name for custom styling */
81
+ className?: string;
82
+ /** Item content - text, icons, or other React elements */
83
+ children?: React.ReactNode;
84
+ } & React.ComponentProps<typeof DropdownMenuPrimitive.Item>;
85
+
86
+ /** Props for DropdownMenuCheckboxItem (Documentation only) */
87
+ // eslint-disable-next-line unused-imports/no-unused-vars
88
+ type DropdownMenuCheckboxItemDocsProps = {
89
+ /** The checked state of the checkbox item */
90
+ checked?: boolean | "indeterminate";
91
+ /** Callback fired when the checked state changes */
92
+ onCheckedChange?: (checked: boolean) => void;
93
+ /** Whether the item is disabled and cannot be interacted with @default false */
94
+ disabled?: boolean;
95
+ /** Callback fired when the item is selected via click or keyboard */
96
+ onSelect?: (event: Event) => void;
97
+ /** Optional text value used for typeahead search functionality */
98
+ textValue?: string;
99
+ /** Whether to add extra left padding to align with items that have icons @default false */
100
+ inset?: boolean;
101
+ /** CSS class name for custom styling */
102
+ className?: string;
103
+ /** Item content - automatically includes checkbox indicator */
104
+ children?: React.ReactNode;
105
+ } & React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>;
106
+
107
+ /** Props for DropdownMenuRadioGroup (Documentation only) */
108
+ // eslint-disable-next-line unused-imports/no-unused-vars
109
+ type DropdownMenuRadioGroupDocsProps = {
110
+ /** The currently selected value in the radio group */
111
+ value?: string;
112
+ /** Callback fired when the selection changes to a different value */
113
+ onValueChange?: (value: string) => void;
114
+ /** Whether the entire radio group is disabled @default false */
115
+ disabled?: boolean;
116
+ /** Radio item children within the group */
117
+ children?: React.ReactNode;
118
+ } & React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>;
119
+
120
+ /** Props for DropdownMenuRadioItem (Documentation only) */
121
+ // eslint-disable-next-line unused-imports/no-unused-vars
122
+ type DropdownMenuRadioItemDocsProps = {
123
+ /** The unique value this radio item represents */
124
+ value: string;
125
+ /** Whether the item is disabled and cannot be selected @default false */
126
+ disabled?: boolean;
127
+ /** Callback fired when the item is selected via click or keyboard */
128
+ onSelect?: (event: Event) => void;
129
+ /** Optional text value used for typeahead search functionality */
130
+ textValue?: string;
131
+ /** Whether to add extra left padding to align with items that have icons @default false */
132
+ inset?: boolean;
133
+ /** CSS class name for custom styling */
134
+ className?: string;
135
+ /** Item content - automatically includes radio indicator */
136
+ children?: React.ReactNode;
137
+ } & React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>;
138
+
139
+ // ============================================================================
140
+ // Main Component
141
+ // ============================================================================
142
+
7
143
  /**
8
144
  * A versatile dropdown menu component built on Radix UI primitives
9
145
  *
@@ -11,10 +147,15 @@ import { cn } from "@/lib/utils";
11
147
  * They're typically triggered by a button and appear as a floating panel with full
12
148
  * keyboard navigation support, submenus, and various interactive item types.
13
149
  *
14
- * Based on the shadcn/ui dropdown-menu component with additional enhancements for
15
- * better integration with design systems and improved accessibility.
150
+ * Built on Radix UI's DropdownMenu primitive with enhanced styling and type safety.
151
+ * Follows the WAI-ARIA Menu Button pattern for accessibility compliance.
152
+ *
153
+ * @param defaultOpen - Whether the dropdown is initially open (uncontrolled mode)
154
+ * @param open - Whether the dropdown is open (controlled mode)
155
+ * @param onOpenChange - Callback fired when the open state changes
156
+ * @param modal - Whether the dropdown should be modal (blocks interaction with outside elements)
157
+ * @param dir - The reading direction of the dropdown menu
16
158
  *
17
- * @component
18
159
  * @example
19
160
  * ```tsx
20
161
  * // Basic dropdown menu
@@ -33,8 +174,10 @@ import { cn } from "@/lib/utils";
33
174
  *
34
175
  * @example
35
176
  * ```tsx
36
- * // Context menu with alignment and destructive actions
37
- * <DropdownMenu>
177
+ * // Controlled dropdown with alignment
178
+ * const [open, setOpen] = useState(false);
179
+ *
180
+ * <DropdownMenu open={open} onOpenChange={setOpen}>
38
181
  * <DropdownMenuTrigger asChild>
39
182
  * <Button variant="ghost" size="icon">
40
183
  * <MoreHorizontal />
@@ -52,6 +195,9 @@ import { cn } from "@/lib/utils";
52
195
  * @example
53
196
  * ```tsx
54
197
  * // Complex menu with checkboxes, radio groups, and submenus
198
+ * const [showPanel, setShowPanel] = useState(true);
199
+ * const [position, setPosition] = useState("top");
200
+ *
55
201
  * <DropdownMenu>
56
202
  * <DropdownMenuTrigger asChild>
57
203
  * <Button>Advanced Menu</Button>
@@ -82,17 +228,19 @@ import { cn } from "@/lib/utils";
82
228
  * @accessibility
83
229
  * - Full keyboard navigation with arrow keys (Up/Down for navigation)
84
230
  * - Enter/Space to activate items
85
- * - Escape key closes the menu and restores focus
231
+ * - Escape key closes the menu and restores focus to the trigger
86
232
  * - Home/End keys navigate to first/last item
87
233
  * - Type-ahead search to jump to items by first letter
88
234
  * - Left/Right arrow keys for submenu navigation
89
235
  * - Proper ARIA roles (menu, menuitem, menuitemcheckbox, menuitemradio)
90
236
  * - Focus management with focus trapping and restoration
91
237
  * - Screen reader announcements for state changes
238
+ * - Supports roving tabindex for focus movement
92
239
  *
93
240
  * @see {@link ContextMenu} - For right-click context menus
94
241
  * @see {@link Popover} - For rich content overlays
95
242
  * @see {@link Select} - For single selection dropdowns
243
+ * @see {@link https://www.radix-ui.com/primitives/docs/components/dropdown-menu} - Radix UI documentation
96
244
  * @see {@link https://ui.shadcn.com/docs/components/dropdown-menu} - shadcn/ui documentation
97
245
  * @since 1.0.0
98
246
  */
@@ -107,10 +255,18 @@ function DropdownMenu({
107
255
  *
108
256
  * Renders dropdown content outside of the normal DOM hierarchy to avoid
109
257
  * z-index and overflow issues. Automatically used by DropdownMenuContent
110
- * but can be used explicitly for submenus.
258
+ * but can be used explicitly for advanced positioning scenarios.
259
+ *
260
+ * @param container - Optional container element for portal rendering. If not provided, portals to document.body
111
261
  *
112
- * @component
113
- * @param container - Optional container element for portal rendering
262
+ * @example
263
+ * ```tsx
264
+ * <DropdownMenuPortal container={customContainer}>
265
+ * <DropdownMenuContent>
266
+ * <DropdownMenuItem>Item</DropdownMenuItem>
267
+ * </DropdownMenuContent>
268
+ * </DropdownMenuPortal>
269
+ * ```
114
270
  * @since 1.0.0
115
271
  */
116
272
  function DropdownMenuPortal({
@@ -122,13 +278,29 @@ function DropdownMenuPortal({
122
278
  }
123
279
 
124
280
  /**
125
- * DropdownMenuTrigger - The element that triggers the dropdown menu
281
+ * The element that triggers the dropdown menu
282
+ *
283
+ * Renders the interactive element that opens and closes the dropdown menu.
284
+ * Typically wraps a button or other interactive element using the asChild prop.
285
+ * Automatically receives proper ARIA attributes and keyboard event handlers.
286
+ *
287
+ * @param asChild - Merge props onto the immediate child instead of rendering a wrapper element
288
+ *
289
+ * @example
290
+ * ```tsx
291
+ * // Basic trigger with button
292
+ * <DropdownMenuTrigger asChild>
293
+ * <Button variant="outline">Open Menu</Button>
294
+ * </DropdownMenuTrigger>
295
+ * ```
126
296
  *
127
- * @component
128
297
  * @example
129
298
  * ```tsx
299
+ * // Icon button trigger
130
300
  * <DropdownMenuTrigger asChild>
131
- * <Button>Menu</Button>
301
+ * <Button variant="ghost" size="icon" aria-label="More options">
302
+ * <MoreVertical className="h-4 w-4" />
303
+ * </Button>
132
304
  * </DropdownMenuTrigger>
133
305
  * ```
134
306
  * @since 1.0.0
@@ -145,13 +317,44 @@ function DropdownMenuTrigger({
145
317
  }
146
318
 
147
319
  /**
148
- * DropdownMenuContent - The content container for dropdown menu items
320
+ * The content container for dropdown menu items
321
+ *
322
+ * Contains all menu items and handles positioning relative to the trigger.
323
+ * Automatically portals content to avoid z-index issues and includes sophisticated
324
+ * collision detection to keep the menu visible within viewport boundaries.
325
+ *
326
+ * @param side - The preferred side of the trigger to render against
327
+ * @param sideOffset - Distance in pixels from the trigger
328
+ * @param align - The preferred alignment against the trigger
329
+ * @param alignOffset - Distance in pixels from the align point
330
+ * @param avoidCollisions - Whether to avoid collisions with viewport boundaries
331
+ * @param loop - When true, keyboard navigation will loop from last to first item
332
+ * @param sticky - Element positioning behavior relative to the viewport
333
+ * @param hideWhenDetached - Whether to hide the content when the reference element is fully occluded
149
334
  *
150
- * @component
151
335
  * @example
152
336
  * ```tsx
153
- * <DropdownMenuContent align="end" sideOffset={5}>
154
- * <DropdownMenuItem>Item 1</DropdownMenuItem>
337
+ * // Basic content with default positioning
338
+ * <DropdownMenuContent>
339
+ * <DropdownMenuItem>Profile</DropdownMenuItem>
340
+ * <DropdownMenuItem>Settings</DropdownMenuItem>
341
+ * </DropdownMenuContent>
342
+ * ```
343
+ *
344
+ * @example
345
+ * ```tsx
346
+ * // Content with custom alignment and offset
347
+ * <DropdownMenuContent align="end" sideOffset={8}>
348
+ * <DropdownMenuItem>Edit</DropdownMenuItem>
349
+ * <DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
350
+ * </DropdownMenuContent>
351
+ * ```
352
+ *
353
+ * @example
354
+ * ```tsx
355
+ * // Content with collision avoidance disabled
356
+ * <DropdownMenuContent avoidCollisions={false} side="top">
357
+ * <DropdownMenuItem>Always above trigger</DropdownMenuItem>
155
358
  * </DropdownMenuContent>
156
359
  * ```
157
360
  * @since 1.0.0
@@ -160,7 +363,9 @@ function DropdownMenuContent({
160
363
  className,
161
364
  sideOffset = 4,
162
365
  ...props
163
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
366
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content> & {
367
+ className?: string;
368
+ }) {
164
369
  return (
165
370
  <DropdownMenuPrimitive.Portal>
166
371
  <DropdownMenuPrimitive.Content
@@ -181,15 +386,23 @@ function DropdownMenuContent({
181
386
  *
182
387
  * Used to create logical groupings of menu items, typically separated by
183
388
  * DropdownMenuSeparator components. Helps with semantic organization and
184
- * keyboard navigation.
389
+ * improves accessibility by providing proper group semantics to screen readers.
390
+ *
391
+ * @param asChild - Merge props onto the immediate child instead of rendering a wrapper element
185
392
  *
186
- * @component
187
393
  * @example
188
394
  * ```tsx
189
- * <DropdownMenuGroup>
190
- * <DropdownMenuItem>Profile</DropdownMenuItem>
191
- * <DropdownMenuItem>Settings</DropdownMenuItem>
192
- * </DropdownMenuGroup>
395
+ * <DropdownMenuContent>
396
+ * <DropdownMenuGroup>
397
+ * <DropdownMenuItem>Profile</DropdownMenuItem>
398
+ * <DropdownMenuItem>Account Settings</DropdownMenuItem>
399
+ * </DropdownMenuGroup>
400
+ * <DropdownMenuSeparator />
401
+ * <DropdownMenuGroup>
402
+ * <DropdownMenuItem>Help</DropdownMenuItem>
403
+ * <DropdownMenuItem>Support</DropdownMenuItem>
404
+ * </DropdownMenuGroup>
405
+ * </DropdownMenuContent>
193
406
  * ```
194
407
  * @since 1.0.0
195
408
  */
@@ -202,16 +415,51 @@ function DropdownMenuGroup({
202
415
  }
203
416
 
204
417
  /**
205
- * DropdownMenuItem - A single item in the dropdown menu
418
+ * A single interactive item in the dropdown menu
419
+ *
420
+ * Renders a clickable menu item with proper focus management and keyboard navigation.
421
+ * Supports different visual variants for semantic meaning (e.g., destructive actions).
422
+ * Includes built-in styling for icons, disabled states, and focus indicators.
423
+ *
424
+ * @param disabled - Whether the item is disabled and cannot be selected
425
+ * @param onSelect - Callback fired when the item is selected via click or keyboard
426
+ * @param textValue - Optional text value used for typeahead search functionality
427
+ * @param inset - Whether to add extra left padding to align with items that have icons
428
+ * @param variant - Visual variant of the menu item for semantic distinction
429
+ *
430
+ * @example
431
+ * ```tsx
432
+ * // Basic menu item with click handler
433
+ * <DropdownMenuItem onSelect={() => console.log('Profile clicked')}>
434
+ * <User className="mr-2 h-4 w-4" />
435
+ * Profile
436
+ * </DropdownMenuItem>
437
+ * ```
438
+ *
439
+ * @example
440
+ * ```tsx
441
+ * // Destructive action item
442
+ * <DropdownMenuItem variant="destructive" onSelect={handleDelete}>
443
+ * <Trash className="mr-2 h-4 w-4" />
444
+ * Delete Account
445
+ * </DropdownMenuItem>
446
+ * ```
206
447
  *
207
- * @component
208
448
  * @example
209
449
  * ```tsx
210
- * <DropdownMenuItem onClick={handleClick}>
211
- * Edit
450
+ * // Disabled item
451
+ * <DropdownMenuItem disabled>
452
+ * <Settings className="mr-2 h-4 w-4" />
453
+ * Settings (Coming Soon)
212
454
  * </DropdownMenuItem>
213
- * <DropdownMenuItem variant="destructive">
214
- * Delete
455
+ * ```
456
+ *
457
+ * @example
458
+ * ```tsx
459
+ * // Item with keyboard shortcut
460
+ * <DropdownMenuItem onSelect={handleSave}>
461
+ * Save Document
462
+ * <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
215
463
  * </DropdownMenuItem>
216
464
  * ```
217
465
  * @since 1.0.0
@@ -224,6 +472,7 @@ function DropdownMenuItem({
224
472
  }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
225
473
  inset?: boolean;
226
474
  variant?: "default" | "destructive";
475
+ className?: string;
227
476
  }) {
228
477
  return (
229
478
  <DropdownMenuPrimitive.Item
@@ -243,25 +492,64 @@ function DropdownMenuItem({
243
492
  * A checkable menu item with visual state indication
244
493
  *
245
494
  * Displays a checkbox that can be toggled on/off. The checked state is
246
- * visually indicated with a checkmark icon. Useful for menu options that
247
- * represent toggleable settings or features.
495
+ * visually indicated with a checkmark icon. Supports indeterminate state
496
+ * for partial selections. Ideal for menu options that represent toggleable
497
+ * settings, features, or multi-selection scenarios.
248
498
  *
249
- * @component
250
- * @param checked - Whether the checkbox is checked
251
- * @param onCheckedChange - Callback when the checked state changes
252
- * @param disabled - Whether the item is disabled
499
+ * @param checked - The checked state of the checkbox item (boolean or "indeterminate")
500
+ * @param onCheckedChange - Callback fired when the checked state changes
501
+ * @param disabled - Whether the item is disabled and cannot be interacted with
502
+ * @param onSelect - Callback fired when the item is selected via click or keyboard
503
+ * @param textValue - Optional text value used for typeahead search functionality
504
+ * @param inset - Whether to add extra left padding to align with items that have icons
253
505
  *
254
506
  * @example
255
507
  * ```tsx
508
+ * // Basic checkbox item with state
256
509
  * const [showSidebar, setShowSidebar] = useState(true);
257
510
  *
258
511
  * <DropdownMenuCheckboxItem
259
512
  * checked={showSidebar}
260
513
  * onCheckedChange={setShowSidebar}
261
514
  * >
515
+ * <Sidebar className="mr-2 h-4 w-4" />
262
516
  * Show Sidebar
263
517
  * </DropdownMenuCheckboxItem>
264
518
  * ```
519
+ *
520
+ * @example
521
+ * ```tsx
522
+ * // Multiple checkbox items for feature toggles
523
+ * const [features, setFeatures] = useState({
524
+ * notifications: true,
525
+ * autoSave: false,
526
+ * darkMode: true
527
+ * });
528
+ *
529
+ * <DropdownMenuCheckboxItem
530
+ * checked={features.notifications}
531
+ * onCheckedChange={(checked) => setFeatures(prev => ({ ...prev, notifications: checked }))}
532
+ * >
533
+ * Enable Notifications
534
+ * </DropdownMenuCheckboxItem>
535
+ * <DropdownMenuCheckboxItem
536
+ * checked={features.autoSave}
537
+ * onCheckedChange={(checked) => setFeatures(prev => ({ ...prev, autoSave: checked }))}
538
+ * >
539
+ * Auto-save Changes
540
+ * </DropdownMenuCheckboxItem>
541
+ * ```
542
+ *
543
+ * @example
544
+ * ```tsx
545
+ * // Indeterminate state for partial selections
546
+ * <DropdownMenuCheckboxItem
547
+ * checked="indeterminate"
548
+ * onCheckedChange={handleSelectAll}
549
+ * >
550
+ * Select All Items (Some selected)
551
+ * </DropdownMenuCheckboxItem>
552
+ * ```
265
553
  * @since 1.0.0
266
554
  */
267
555
  function DropdownMenuCheckboxItem({
@@ -269,7 +557,9 @@ function DropdownMenuCheckboxItem({
269
557
  children,
270
558
  checked,
271
559
  ...props
272
- }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
560
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
561
+ className?: string;
562
+ }) {
273
563
  return (
274
564
  <DropdownMenuPrimitive.CheckboxItem
275
565
  data-slot="dropdown-menu-checkbox-item"
@@ -294,20 +584,44 @@ function DropdownMenuCheckboxItem({
294
584
  * Groups radio items for single selection
295
585
  *
296
586
  * Creates a group where only one radio item can be selected at a time.
297
- * Use with DropdownMenuRadioItem components to create single-choice options.
587
+ * Manages the selection state and ensures mutual exclusivity between options.
588
+ * Use with DropdownMenuRadioItem components to create single-choice scenarios
589
+ * like theme selection, sorting options, or view modes.
298
590
  *
299
- * @component
300
- * @param value - Currently selected value
301
- * @param onValueChange - Callback when selection changes
591
+ * @param value - The currently selected value in the radio group
592
+ * @param onValueChange - Callback fired when the selection changes to a different value
593
+ * @param disabled - Whether the entire radio group is disabled
302
594
  *
303
595
  * @example
304
596
  * ```tsx
597
+ * // Theme selection with radio group
305
598
  * const [theme, setTheme] = useState("light");
306
599
  *
307
600
  * <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
308
- * <DropdownMenuRadioItem value="light">Light</DropdownMenuRadioItem>
309
- * <DropdownMenuRadioItem value="dark">Dark</DropdownMenuRadioItem>
310
- * <DropdownMenuRadioItem value="system">System</DropdownMenuRadioItem>
601
+ * <DropdownMenuRadioItem value="light">
602
+ * <Sun className="mr-2 h-4 w-4" />
603
+ * Light Theme
604
+ * </DropdownMenuRadioItem>
605
+ * <DropdownMenuRadioItem value="dark">
606
+ * <Moon className="mr-2 h-4 w-4" />
607
+ * Dark Theme
608
+ * </DropdownMenuRadioItem>
609
+ * <DropdownMenuRadioItem value="system">
610
+ * <Monitor className="mr-2 h-4 w-4" />
611
+ * System Theme
612
+ * </DropdownMenuRadioItem>
613
+ * </DropdownMenuRadioGroup>
614
+ * ```
615
+ *
616
+ * @example
617
+ * ```tsx
618
+ * // Sorting options
619
+ * const [sortBy, setSortBy] = useState("name");
620
+ *
621
+ * <DropdownMenuRadioGroup value={sortBy} onValueChange={setSortBy}>
622
+ * <DropdownMenuRadioItem value="name">Sort by Name</DropdownMenuRadioItem>
623
+ * <DropdownMenuRadioItem value="date">Sort by Date</DropdownMenuRadioItem>
624
+ * <DropdownMenuRadioItem value="size">Sort by Size</DropdownMenuRadioItem>
311
625
  * </DropdownMenuRadioGroup>
312
626
  * ```
313
627
  * @since 1.0.0
@@ -327,21 +641,44 @@ function DropdownMenuRadioGroup({
327
641
  * A radio button menu item for single selection within a group
328
642
  *
329
643
  * Must be used within a DropdownMenuRadioGroup. Shows a filled circle
330
- * indicator when selected. Only one radio item can be selected per group.
644
+ * indicator when selected. Only one radio item can be selected per group,
645
+ * ensuring mutually exclusive selection behavior.
331
646
  *
332
- * @component
333
- * @param value - The value this radio item represents
334
- * @param disabled - Whether the item is disabled
647
+ * @param value - The unique value this radio item represents
648
+ * @param disabled - Whether the item is disabled and cannot be selected
649
+ * @param onSelect - Callback fired when the item is selected via click or keyboard
650
+ * @param textValue - Optional text value used for typeahead search functionality
651
+ * @param inset - Whether to add extra left padding to align with items that have icons
335
652
  *
336
653
  * @example
337
654
  * ```tsx
655
+ * // Basic radio group for theme selection
338
656
  * <DropdownMenuRadioGroup value={selectedTheme} onValueChange={setSelectedTheme}>
339
657
  * <DropdownMenuRadioItem value="light">
658
+ * <Sun className="mr-2 h-4 w-4" />
340
659
  * Light Theme
341
660
  * </DropdownMenuRadioItem>
342
661
  * <DropdownMenuRadioItem value="dark">
662
+ * <Moon className="mr-2 h-4 w-4" />
343
663
  * Dark Theme
344
664
  * </DropdownMenuRadioItem>
665
+ * <DropdownMenuRadioItem value="system">
666
+ * <Monitor className="mr-2 h-4 w-4" />
667
+ * System Theme
668
+ * </DropdownMenuRadioItem>
669
+ * </DropdownMenuRadioGroup>
670
+ * ```
671
+ *
672
+ * @example
673
+ * ```tsx
674
+ * // Priority selection with disabled option
675
+ * <DropdownMenuRadioGroup value={priority} onValueChange={setPriority}>
676
+ * <DropdownMenuRadioItem value="low">Low Priority</DropdownMenuRadioItem>
677
+ * <DropdownMenuRadioItem value="medium">Medium Priority</DropdownMenuRadioItem>
678
+ * <DropdownMenuRadioItem value="high">High Priority</DropdownMenuRadioItem>
679
+ * <DropdownMenuRadioItem value="urgent" disabled>
680
+ * Urgent (Premium Only)
681
+ * </DropdownMenuRadioItem>
345
682
  * </DropdownMenuRadioGroup>
346
683
  * ```
347
684
  * @since 1.0.0
@@ -350,7 +687,9 @@ function DropdownMenuRadioItem({
350
687
  className,
351
688
  children,
352
689
  ...props
353
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
690
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
691
+ className?: string;
692
+ }) {
354
693
  return (
355
694
  <DropdownMenuPrimitive.RadioItem
356
695
  data-slot="dropdown-menu-radio-item"
@@ -371,12 +710,45 @@ function DropdownMenuRadioItem({
371
710
  }
372
711
 
373
712
  /**
374
- * DropdownMenuLabel - A label for grouping menu items
713
+ * A non-interactive label for grouping and organizing menu items
714
+ *
715
+ * Used to provide semantic headers for groups of related menu items.
716
+ * Labels are not focusable and serve as visual and accessibility landmarks
717
+ * within the menu structure. Helps users understand the organization of menu options.
718
+ *
719
+ * @param asChild - Merge props onto the immediate child instead of rendering a wrapper element
720
+ * @param inset - Whether to add extra left padding to align with items that have icons
721
+ *
722
+ * @example
723
+ * ```tsx
724
+ * // Basic label for menu section
725
+ * <DropdownMenuContent>
726
+ * <DropdownMenuLabel>Account Actions</DropdownMenuLabel>
727
+ * <DropdownMenuSeparator />
728
+ * <DropdownMenuItem>View Profile</DropdownMenuItem>
729
+ * <DropdownMenuItem>Account Settings</DropdownMenuItem>
730
+ *
731
+ * <DropdownMenuSeparator />
732
+ * <DropdownMenuLabel>Preferences</DropdownMenuLabel>
733
+ * <DropdownMenuItem>Theme Settings</DropdownMenuItem>
734
+ * <DropdownMenuItem>Notification Settings</DropdownMenuItem>
735
+ * </DropdownMenuContent>
736
+ * ```
375
737
  *
376
- * @component
377
738
  * @example
378
739
  * ```tsx
379
- * <DropdownMenuLabel>Actions</DropdownMenuLabel>
740
+ * // Label with inset alignment
741
+ * <DropdownMenuContent>
742
+ * <DropdownMenuLabel inset>File Operations</DropdownMenuLabel>
743
+ * <DropdownMenuItem>
744
+ * <Download className="mr-2 h-4 w-4" />
745
+ * Download
746
+ * </DropdownMenuItem>
747
+ * <DropdownMenuItem>
748
+ * <Upload className="mr-2 h-4 w-4" />
749
+ * Upload
750
+ * </DropdownMenuItem>
751
+ * </DropdownMenuContent>
380
752
  * ```
381
753
  * @since 1.0.0
382
754
  */
@@ -386,6 +758,7 @@ function DropdownMenuLabel({
386
758
  ...props
387
759
  }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
388
760
  inset?: boolean;
761
+ className?: string;
389
762
  }) {
390
763
  return (
391
764
  <DropdownMenuPrimitive.Label
@@ -401,15 +774,49 @@ function DropdownMenuLabel({
401
774
  }
402
775
 
403
776
  /**
404
- * DropdownMenuSeparator - A visual separator between menu items
777
+ * A visual separator between menu items or groups
778
+ *
779
+ * Renders a thin horizontal line to visually separate different sections
780
+ * of menu items. Improves visual hierarchy and helps users understand
781
+ * the logical grouping of menu options. Commonly used after labels
782
+ * or between different types of actions.
783
+ *
784
+ * @param asChild - Merge props onto the immediate child instead of rendering a wrapper element
405
785
  *
406
- * @component
786
+ * @example
787
+ * ```tsx
788
+ * // Separating different action groups
789
+ * <DropdownMenuContent>
790
+ * <DropdownMenuItem>View</DropdownMenuItem>
791
+ * <DropdownMenuItem>Edit</DropdownMenuItem>
792
+ * <DropdownMenuSeparator />
793
+ * <DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
794
+ * </DropdownMenuContent>
795
+ * ```
796
+ *
797
+ * @example
798
+ * ```tsx
799
+ * // Separating sections with labels
800
+ * <DropdownMenuContent>
801
+ * <DropdownMenuLabel>User Actions</DropdownMenuLabel>
802
+ * <DropdownMenuSeparator />
803
+ * <DropdownMenuItem>Profile</DropdownMenuItem>
804
+ * <DropdownMenuItem>Settings</DropdownMenuItem>
805
+ *
806
+ * <DropdownMenuSeparator />
807
+ * <DropdownMenuLabel>System</DropdownMenuLabel>
808
+ * <DropdownMenuSeparator />
809
+ * <DropdownMenuItem>Logout</DropdownMenuItem>
810
+ * </DropdownMenuContent>
811
+ * ```
407
812
  * @since 1.0.0
408
813
  */
409
814
  function DropdownMenuSeparator({
410
815
  className,
411
816
  ...props
412
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
817
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator> & {
818
+ className?: string;
819
+ }) {
413
820
  return (
414
821
  <DropdownMenuPrimitive.Separator
415
822
  data-slot="dropdown-menu-separator"
@@ -423,23 +830,64 @@ function DropdownMenuSeparator({
423
830
  * Displays keyboard shortcut hints in menu items
424
831
  *
425
832
  * Shows keyboard shortcut text aligned to the right side of menu items.
426
- * Purely visual - does not implement the actual keyboard functionality.
427
- * Use standard keyboard shortcut notation (⌘, ⌃, ⌥, ).
833
+ * Purely visual component - does not implement the actual keyboard functionality.
834
+ * Use standard keyboard shortcut notation and symbols (⌘, ⌃, ⌥, ⇧, Ctrl, Alt, Shift).
835
+ * Helps users discover and remember keyboard shortcuts for menu actions.
428
836
  *
429
- * @component
430
837
  * @example
431
838
  * ```tsx
432
- * <DropdownMenuItem>
839
+ * // macOS style shortcuts
840
+ * <DropdownMenuItem onSelect={handleSave}>
433
841
  * Save Document
434
842
  * <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
435
843
  * </DropdownMenuItem>
436
844
  * ```
845
+ *
846
+ * @example
847
+ * ```tsx
848
+ * // Windows/Linux style shortcuts
849
+ * <DropdownMenuItem onSelect={handleCopy}>
850
+ * Copy
851
+ * <DropdownMenuShortcut>Ctrl+C</DropdownMenuShortcut>
852
+ * </DropdownMenuItem>
853
+ * ```
854
+ *
855
+ * @example
856
+ * ```tsx
857
+ * // Complex shortcuts with multiple modifiers
858
+ * <DropdownMenuItem onSelect={handleForceRefresh}>
859
+ * Force Refresh
860
+ * <DropdownMenuShortcut>⌘⇧R</DropdownMenuShortcut>
861
+ * </DropdownMenuItem>
862
+ * ```
863
+ *
864
+ * @example
865
+ * ```tsx
866
+ * // Multiple menu items with shortcuts
867
+ * <DropdownMenuContent>
868
+ * <DropdownMenuItem>
869
+ * New File <DropdownMenuShortcut>⌘N</DropdownMenuShortcut>
870
+ * </DropdownMenuItem>
871
+ * <DropdownMenuItem>
872
+ * Open File <DropdownMenuShortcut>⌘O</DropdownMenuShortcut>
873
+ * </DropdownMenuItem>
874
+ * <DropdownMenuSeparator />
875
+ * <DropdownMenuItem>
876
+ * Save <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
877
+ * </DropdownMenuItem>
878
+ * <DropdownMenuItem>
879
+ * Save As <DropdownMenuShortcut>⌘⇧S</DropdownMenuShortcut>
880
+ * </DropdownMenuItem>
881
+ * </DropdownMenuContent>
882
+ * ```
437
883
  * @since 1.0.0
438
884
  */
439
885
  function DropdownMenuShortcut({
440
886
  className,
441
887
  ...props
442
- }: React.ComponentProps<"span">) {
888
+ }: React.ComponentProps<"span"> & {
889
+ className?: string;
890
+ }) {
443
891
  return (
444
892
  <span
445
893
  data-slot="dropdown-menu-shortcut"
@@ -456,19 +904,66 @@ function DropdownMenuShortcut({
456
904
  * Container for creating nested submenus
457
905
  *
458
906
  * Wraps a submenu trigger and content to create hierarchical menu structures.
459
- * Use with DropdownMenuSubTrigger and DropdownMenuSubContent.
907
+ * Enables multi-level navigation within dropdown menus. Use with
908
+ * DropdownMenuSubTrigger and DropdownMenuSubContent to build complex
909
+ * menu hierarchies with proper focus management and keyboard navigation.
910
+ *
911
+ * @param defaultOpen - Whether the submenu is initially open (uncontrolled mode)
912
+ * @param open - Whether the submenu is open (controlled mode)
913
+ * @param onOpenChange - Callback fired when the submenu open state changes
460
914
  *
461
- * @component
462
915
  * @example
463
916
  * ```tsx
917
+ * // Basic submenu structure
464
918
  * <DropdownMenuSub>
919
+ * <DropdownMenuSubTrigger>
920
+ * <Share className="mr-2 h-4 w-4" />
921
+ * Share Options
922
+ * </DropdownMenuSubTrigger>
923
+ * <DropdownMenuSubContent>
924
+ * <DropdownMenuItem>Email Link</DropdownMenuItem>
925
+ * <DropdownMenuItem>Copy to Clipboard</DropdownMenuItem>
926
+ * <DropdownMenuItem>Generate QR Code</DropdownMenuItem>
927
+ * </DropdownMenuSubContent>
928
+ * </DropdownMenuSub>
929
+ * ```
930
+ *
931
+ * @example
932
+ * ```tsx
933
+ * // Controlled submenu with state management
934
+ * const [isShareOpen, setIsShareOpen] = useState(false);
935
+ *
936
+ * <DropdownMenuSub open={isShareOpen} onOpenChange={setIsShareOpen}>
465
937
  * <DropdownMenuSubTrigger>Share</DropdownMenuSubTrigger>
466
938
  * <DropdownMenuSubContent>
467
- * <DropdownMenuItem>Email</DropdownMenuItem>
468
- * <DropdownMenuItem>Copy Link</DropdownMenuItem>
939
+ * <DropdownMenuItem onSelect={() => handleShare('email')}>Email</DropdownMenuItem>
940
+ * <DropdownMenuItem onSelect={() => handleShare('link')}>Copy Link</DropdownMenuItem>
469
941
  * </DropdownMenuSubContent>
470
942
  * </DropdownMenuSub>
471
943
  * ```
944
+ *
945
+ * @example
946
+ * ```tsx
947
+ * // Complex nested menu structure
948
+ * <DropdownMenuContent>
949
+ * <DropdownMenuItem>Edit</DropdownMenuItem>
950
+ * <DropdownMenuSeparator />
951
+ * <DropdownMenuSub>
952
+ * <DropdownMenuSubTrigger>Export</DropdownMenuSubTrigger>
953
+ * <DropdownMenuSubContent>
954
+ * <DropdownMenuItem>Export as PDF</DropdownMenuItem>
955
+ * <DropdownMenuItem>Export as PNG</DropdownMenuItem>
956
+ * <DropdownMenuSub>
957
+ * <DropdownMenuSubTrigger>Advanced Export</DropdownMenuSubTrigger>
958
+ * <DropdownMenuSubContent>
959
+ * <DropdownMenuItem>Custom Resolution</DropdownMenuItem>
960
+ * <DropdownMenuItem>Batch Export</DropdownMenuItem>
961
+ * </DropdownMenuSubContent>
962
+ * </DropdownMenuSub>
963
+ * </DropdownMenuSubContent>
964
+ * </DropdownMenuSub>
965
+ * </DropdownMenuContent>
966
+ * ```
472
967
  * @since 1.0.0
473
968
  */
474
969
  function DropdownMenuSub({
@@ -480,25 +975,57 @@ function DropdownMenuSub({
480
975
  /**
481
976
  * Trigger element for opening a submenu
482
977
  *
483
- * Displays an arrow indicator and opens the associated submenu on hover or click.
484
- * Must be used within a DropdownMenuSub component.
978
+ * Displays an arrow indicator and opens the associated submenu on hover or keyboard
979
+ * navigation. Must be used within a DropdownMenuSub component. Automatically
980
+ * includes a chevron icon to indicate submenu availability and handles focus states.
485
981
  *
486
- * @component
982
+ * @param asChild - Merge props onto the immediate child instead of rendering a wrapper element
983
+ * @param disabled - Whether the trigger is disabled and cannot open the submenu
984
+ * @param textValue - Optional text value used for typeahead search functionality
487
985
  * @param inset - Whether to add left padding to align with items that have icons
488
986
  *
489
987
  * @example
490
988
  * ```tsx
989
+ * // Basic submenu trigger with icon
491
990
  * <DropdownMenuSub>
492
991
  * <DropdownMenuSubTrigger>
493
992
  * <Share className="mr-2 h-4 w-4" />
494
993
  * Share Options
495
994
  * </DropdownMenuSubTrigger>
496
995
  * <DropdownMenuSubContent>
497
- * <DropdownMenuItem>Email</DropdownMenuItem>
498
- * <DropdownMenuItem>Copy Link</DropdownMenuItem>
996
+ * <DropdownMenuItem>Email Link</DropdownMenuItem>
997
+ * <DropdownMenuItem>Copy to Clipboard</DropdownMenuItem>
499
998
  * </DropdownMenuSubContent>
500
999
  * </DropdownMenuSub>
501
1000
  * ```
1001
+ *
1002
+ * @example
1003
+ * ```tsx
1004
+ * // Submenu trigger with inset alignment
1005
+ * <DropdownMenuContent>
1006
+ * <DropdownMenuItem>
1007
+ * <FileText className="mr-2 h-4 w-4" />
1008
+ * Open File
1009
+ * </DropdownMenuItem>
1010
+ * <DropdownMenuSub>
1011
+ * <DropdownMenuSubTrigger inset>
1012
+ * Recent Files
1013
+ * </DropdownMenuSubTrigger>
1014
+ * <DropdownMenuSubContent>
1015
+ * <DropdownMenuItem>Document.pdf</DropdownMenuItem>
1016
+ * <DropdownMenuItem>Presentation.pptx</DropdownMenuItem>
1017
+ * </DropdownMenuSubContent>
1018
+ * </DropdownMenuSub>
1019
+ * </DropdownMenuContent>
1020
+ * ```
1021
+ *
1022
+ * @example
1023
+ * ```tsx
1024
+ * // Disabled submenu trigger
1025
+ * <DropdownMenuSubTrigger disabled>
1026
+ * Advanced Options (Pro Only)
1027
+ * </DropdownMenuSubTrigger>
1028
+ * ```
502
1029
  * @since 1.0.0
503
1030
  */
504
1031
  function DropdownMenuSubTrigger({
@@ -508,6 +1035,7 @@ function DropdownMenuSubTrigger({
508
1035
  ...props
509
1036
  }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
510
1037
  inset?: boolean;
1038
+ className?: string;
511
1039
  }) {
512
1040
  return (
513
1041
  <DropdownMenuPrimitive.SubTrigger
@@ -529,16 +1057,69 @@ function DropdownMenuSubTrigger({
529
1057
  * Content container for submenu items
530
1058
  *
531
1059
  * Contains the items displayed when a submenu is opened. Positioned relative
532
- * to the trigger and supports the same item types as the main menu.
1060
+ * to the submenu trigger with intelligent collision detection. Supports all
1061
+ * the same item types as the main menu content, enabling complex nested
1062
+ * menu structures with consistent behavior and styling.
1063
+ *
1064
+ * @param asChild - Merge props onto the immediate child instead of rendering a wrapper element
1065
+ * @param loop - When true, keyboard navigation will loop from last to first item
1066
+ * @param side - The preferred side of the trigger to render against
1067
+ * @param sideOffset - Distance in pixels from the trigger
1068
+ * @param align - The preferred alignment against the trigger
1069
+ * @param alignOffset - Distance in pixels from the align point
1070
+ * @param avoidCollisions - Whether to avoid collisions with viewport boundaries
1071
+ * @param sticky - Element positioning behavior relative to the viewport
1072
+ * @param hideWhenDetached - Whether to hide content when reference element is occluded
533
1073
  *
534
- * @component
535
1074
  * @example
536
1075
  * ```tsx
1076
+ * // Basic submenu content with various item types
537
1077
  * <DropdownMenuSubContent>
538
- * <DropdownMenuItem>Submenu Item 1</DropdownMenuItem>
539
- * <DropdownMenuItem>Submenu Item 2</DropdownMenuItem>
1078
+ * <DropdownMenuItem>
1079
+ * <Mail className="mr-2 h-4 w-4" />
1080
+ * Send via Email
1081
+ * </DropdownMenuItem>
1082
+ * <DropdownMenuItem>
1083
+ * <Link className="mr-2 h-4 w-4" />
1084
+ * Copy Share Link
1085
+ * </DropdownMenuItem>
540
1086
  * <DropdownMenuSeparator />
541
- * <DropdownMenuItem>Submenu Item 3</DropdownMenuItem>
1087
+ * <DropdownMenuItem>
1088
+ * <QrCode className="mr-2 h-4 w-4" />
1089
+ * Generate QR Code
1090
+ * </DropdownMenuItem>
1091
+ * </DropdownMenuSubContent>
1092
+ * ```
1093
+ *
1094
+ * @example
1095
+ * ```tsx
1096
+ * // Submenu with checkbox items for multi-selection
1097
+ * <DropdownMenuSubContent>
1098
+ * <DropdownMenuLabel>Export Options</DropdownMenuLabel>
1099
+ * <DropdownMenuSeparator />
1100
+ * <DropdownMenuCheckboxItem checked={includeMetadata} onCheckedChange={setIncludeMetadata}>
1101
+ * Include Metadata
1102
+ * </DropdownMenuCheckboxItem>
1103
+ * <DropdownMenuCheckboxItem checked={compressFile} onCheckedChange={setCompressFile}>
1104
+ * Compress File
1105
+ * </DropdownMenuCheckboxItem>
1106
+ * <DropdownMenuSeparator />
1107
+ * <DropdownMenuItem>Export Now</DropdownMenuItem>
1108
+ * </DropdownMenuSubContent>
1109
+ * ```
1110
+ *
1111
+ * @example
1112
+ * ```tsx
1113
+ * // Nested submenu structure
1114
+ * <DropdownMenuSubContent>
1115
+ * <DropdownMenuItem>Basic Export</DropdownMenuItem>
1116
+ * <DropdownMenuSub>
1117
+ * <DropdownMenuSubTrigger>Advanced Settings</DropdownMenuSubTrigger>
1118
+ * <DropdownMenuSubContent>
1119
+ * <DropdownMenuItem>High Quality</DropdownMenuItem>
1120
+ * <DropdownMenuItem>Custom Resolution</DropdownMenuItem>
1121
+ * </DropdownMenuSubContent>
1122
+ * </DropdownMenuSub>
542
1123
  * </DropdownMenuSubContent>
543
1124
  * ```
544
1125
  * @since 1.0.0
@@ -546,7 +1127,9 @@ function DropdownMenuSubTrigger({
546
1127
  function DropdownMenuSubContent({
547
1128
  className,
548
1129
  ...props
549
- }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
1130
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent> & {
1131
+ className?: string;
1132
+ }) {
550
1133
  return (
551
1134
  <DropdownMenuPrimitive.SubContent
552
1135
  data-slot="dropdown-menu-sub-content"