@primitiv-ui/react 0.1.27 → 0.1.29

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 (307) hide show
  1. package/README.md +4 -0
  2. package/package.json +6 -1
  3. package/src/AccessibleIcon/AccessibleIcon.tsx +32 -9
  4. package/src/AccessibleIcon/__tests__/AccessibleIcon.test.tsx +5 -0
  5. package/src/AccessibleIcon/types.ts +15 -2
  6. package/src/Accordion/Accordion.tsx +25 -4
  7. package/src/Accordion/__tests__/Accordion.asChild.test.tsx +46 -0
  8. package/src/Accordion/__tests__/Accordion.basic-rendering.test.tsx +15 -0
  9. package/src/Accordion/__tests__/Accordion.disabled-items.test.tsx +42 -0
  10. package/src/Accordion/__tests__/Accordion.error-handling.test.tsx +33 -0
  11. package/src/Accordion/hooks/useAccordionRoot.ts +44 -7
  12. package/src/Accordion/hooks/useAccordionTrigger.ts +9 -1
  13. package/src/Accordion/types.ts +72 -21
  14. package/src/Alert/Alert.tsx +36 -7
  15. package/src/Alert/__tests__/Alert.test.tsx +5 -0
  16. package/src/Alert/types.ts +18 -2
  17. package/src/Avatar/Avatar.tsx +99 -15
  18. package/src/Avatar/__tests__/Avatar.basic-rendering.test.tsx +10 -0
  19. package/src/Avatar/__tests__/Avatar.fallback.test.tsx +30 -0
  20. package/src/Avatar/__tests__/Avatar.image-loading.test.tsx +35 -0
  21. package/src/Avatar/hooks/useAvatarImage.ts +16 -0
  22. package/src/Avatar/types.ts +15 -3
  23. package/src/Breadcrumb/Breadcrumb.tsx +136 -18
  24. package/src/Breadcrumb/README.md +47 -0
  25. package/src/Breadcrumb/__tests__/Breadcrumb.basic-rendering.test.tsx +11 -0
  26. package/src/Breadcrumb/__tests__/Breadcrumb.ellipsis.test.tsx +110 -0
  27. package/src/Breadcrumb/types.ts +73 -7
  28. package/src/Button/Button.tsx +2 -0
  29. package/src/Button/__tests__/Button.basic-rendering.test.tsx +6 -0
  30. package/src/Button/types.ts +21 -0
  31. package/src/Carousel/Carousel.tsx +263 -15
  32. package/src/Carousel/README.md +749 -72
  33. package/src/Carousel/__tests__/Carousel.autoplay-status.test.tsx +239 -0
  34. package/src/Carousel/__tests__/Carousel.drag-status.test.tsx +292 -0
  35. package/src/Carousel/__tests__/Carousel.dynamic-slides.test.tsx +38 -0
  36. package/src/Carousel/__tests__/Carousel.indicators.test.tsx +101 -0
  37. package/src/Carousel/__tests__/Carousel.infinite.test.tsx +1453 -0
  38. package/src/Carousel/__tests__/Carousel.instant-scroll.test.tsx +124 -0
  39. package/src/Carousel/__tests__/Carousel.intersection-observer.test.tsx +88 -0
  40. package/src/Carousel/__tests__/Carousel.loop.test.tsx +163 -0
  41. package/src/Carousel/__tests__/Carousel.loopEngine.test.ts +77 -0
  42. package/src/Carousel/__tests__/Carousel.mouse-drag.test.tsx +504 -0
  43. package/src/Carousel/__tests__/Carousel.multi-slide-bounds.test.tsx +91 -0
  44. package/src/Carousel/__tests__/Carousel.orientation.test.tsx +207 -0
  45. package/src/Carousel/__tests__/Carousel.overscroll.test.tsx +532 -0
  46. package/src/Carousel/__tests__/Carousel.page-snap-points.test.tsx +50 -0
  47. package/src/Carousel/__tests__/Carousel.progress-text.test.tsx +76 -0
  48. package/src/Carousel/__tests__/Carousel.reduced-motion.test.tsx +3 -6
  49. package/src/Carousel/__tests__/Carousel.refresh-progress.test.tsx +2 -5
  50. package/src/Carousel/__tests__/Carousel.scroll-margin.test.tsx +167 -0
  51. package/src/Carousel/__tests__/Carousel.scroll-progress.test.tsx +518 -0
  52. package/src/Carousel/__tests__/Carousel.scroll-snap-change.test.tsx +32 -11
  53. package/src/Carousel/__tests__/Carousel.scroll-sync.test.tsx +237 -24
  54. package/src/Carousel/__tests__/Carousel.scroll-to-index.test.tsx +115 -0
  55. package/src/Carousel/__tests__/Carousel.slide-snap.test.tsx +172 -0
  56. package/src/Carousel/__tests__/Carousel.slides-per-move.test.tsx +179 -1
  57. package/src/Carousel/__tests__/Carousel.slides-per-page.test.tsx +91 -7
  58. package/src/Carousel/__tests__/Carousel.snap-type.test.tsx +35 -0
  59. package/src/Carousel/__tests__/Carousel.transition-modes.test.tsx +30 -5
  60. package/src/Carousel/__tests__/Carousel.translations.test.tsx +23 -0
  61. package/src/Carousel/__tests__/Carousel.wheel.test.tsx +160 -0
  62. package/src/Carousel/hooks/index.ts +1 -0
  63. package/src/Carousel/hooks/useCarouselLoop.ts +869 -0
  64. package/src/Carousel/hooks/useCarouselRoot.ts +338 -42
  65. package/src/Carousel/hooks/useCarouselSlide.ts +44 -9
  66. package/src/Carousel/hooks/useCarouselViewport.ts +649 -46
  67. package/src/Carousel/loopEngine.ts +54 -0
  68. package/src/Carousel/types.ts +457 -35
  69. package/src/Checkbox/Checkbox.tsx +9 -1
  70. package/src/Checkbox/__tests__/Checkbox.basic-rendering.test.tsx +14 -0
  71. package/src/Checkbox/hooks/useCheckboxInput.ts +4 -0
  72. package/src/Checkbox/types.ts +19 -0
  73. package/src/CheckboxCard/CheckboxCard.tsx +13 -4
  74. package/src/CheckboxCard/__tests__/CheckboxCard.basic-rendering.test.tsx +7 -0
  75. package/src/CheckboxCard/types.ts +65 -17
  76. package/src/Collapsible/Collapsible.tsx +49 -3
  77. package/src/Collapsible/README.md +40 -0
  78. package/src/Collapsible/__tests__/Collapsible.asChild.test.tsx +89 -0
  79. package/src/Collapsible/__tests__/Collapsible.basic-rendering.test.tsx +27 -0
  80. package/src/Collapsible/__tests__/Collapsible.collapsedHeight.test.tsx +140 -0
  81. package/src/Collapsible/hooks/useCollapsibleTrigger.ts +3 -1
  82. package/src/Collapsible/types.ts +89 -22
  83. package/src/ContextMenu/ContextMenu.tsx +270 -4
  84. package/src/ContextMenu/types.ts +148 -6
  85. package/src/DirectionProvider/DirectionProvider.tsx +41 -9
  86. package/src/DirectionProvider/__tests__/DirectionProvider.test.tsx +5 -0
  87. package/src/DirectionProvider/types.ts +28 -3
  88. package/src/Divider/Divider.tsx +24 -10
  89. package/src/Divider/__tests__/Divider.test.tsx +5 -0
  90. package/src/Divider/types.ts +10 -3
  91. package/src/Drawer/Drawer.tsx +315 -0
  92. package/src/Drawer/README.md +124 -0
  93. package/src/Drawer/__tests__/Drawer.behavior.test.tsx +100 -0
  94. package/src/Drawer/__tests__/Drawer.focus-trap.test.tsx +55 -0
  95. package/src/Drawer/__tests__/Drawer.rendering.test.tsx +111 -0
  96. package/src/Drawer/__tests__/Drawer.side.test.tsx +69 -0
  97. package/src/Drawer/__tests__/dialog-polyfill.ts +39 -0
  98. package/src/Drawer/index.ts +2 -0
  99. package/src/Drawer/types.ts +66 -0
  100. package/src/Dropdown/Dropdown.tsx +117 -0
  101. package/src/Dropdown/types.ts +241 -11
  102. package/src/EmptyState/EmptyState.tsx +74 -4
  103. package/src/EmptyState/__tests__/EmptyState.Actions.test.tsx +7 -2
  104. package/src/EmptyState/__tests__/EmptyState.Description.test.tsx +3 -1
  105. package/src/EmptyState/__tests__/EmptyState.Root.test.tsx +10 -0
  106. package/src/EmptyState/__tests__/EmptyState.Title.test.tsx +3 -1
  107. package/src/EmptyState/types.ts +49 -6
  108. package/src/Field/Field.tsx +23 -0
  109. package/src/Field/__tests__/Field.basic-rendering.test.tsx +11 -0
  110. package/src/Field/__tests__/Field.error-handling.test.tsx +23 -0
  111. package/src/Field/__tests__/Field.state-cascade.test.tsx +21 -0
  112. package/src/Field/hooks/__tests__/useFieldProps.test.tsx +104 -9
  113. package/src/Field/types.ts +60 -12
  114. package/src/Fieldset/Fieldset.tsx +54 -18
  115. package/src/Fieldset/__tests__/Fieldset.basic-rendering.test.tsx +9 -0
  116. package/src/Fieldset/types.ts +20 -2
  117. package/src/Input/Input.tsx +14 -9
  118. package/src/Input/__tests__/Input.basic-rendering.test.tsx +5 -0
  119. package/src/Input/types.ts +19 -2
  120. package/src/InputGroup/InputGroup.tsx +11 -3
  121. package/src/InputGroup/__tests__/InputGroup.basic-rendering.test.tsx +14 -0
  122. package/src/InputGroup/types.ts +26 -5
  123. package/src/MillerColumns/MillerColumns.tsx +86 -19
  124. package/src/MillerColumns/types.ts +83 -27
  125. package/src/Modal/Modal.tsx +31 -4
  126. package/src/Modal/README.md +19 -10
  127. package/src/Modal/__tests__/Modal.focus-trap.test.tsx +162 -0
  128. package/src/Modal/hooks/useModalContent.ts +32 -0
  129. package/src/Modal/types.ts +110 -29
  130. package/src/NavigationMenu/NavigationMenu.tsx +890 -0
  131. package/src/NavigationMenu/NavigationMenuContext.ts +67 -0
  132. package/src/NavigationMenu/README.md +355 -0
  133. package/src/NavigationMenu/__tests__/NavigationMenu.anchor-positioning.test.tsx +132 -0
  134. package/src/NavigationMenu/__tests__/NavigationMenu.asChild.test.tsx +73 -0
  135. package/src/NavigationMenu/__tests__/NavigationMenu.basic-rendering.test.tsx +92 -0
  136. package/src/NavigationMenu/__tests__/NavigationMenu.contract.test.tsx +45 -0
  137. package/src/NavigationMenu/__tests__/NavigationMenu.controlled-state.test.tsx +134 -0
  138. package/src/NavigationMenu/__tests__/NavigationMenu.error-handling.test.tsx +62 -0
  139. package/src/NavigationMenu/__tests__/NavigationMenu.fixtures.tsx +79 -0
  140. package/src/NavigationMenu/__tests__/NavigationMenu.forceMount.test.tsx +52 -0
  141. package/src/NavigationMenu/__tests__/NavigationMenu.hover-interaction.test.tsx +254 -0
  142. package/src/NavigationMenu/__tests__/NavigationMenu.indicator.test.tsx +252 -0
  143. package/src/NavigationMenu/__tests__/NavigationMenu.keyboard-interaction.test.tsx +294 -0
  144. package/src/NavigationMenu/__tests__/NavigationMenu.keyboard-navigation.test.tsx +126 -0
  145. package/src/NavigationMenu/__tests__/NavigationMenu.link.test.tsx +139 -0
  146. package/src/NavigationMenu/__tests__/NavigationMenu.motion.test.tsx +568 -0
  147. package/src/NavigationMenu/__tests__/NavigationMenu.mouse-interaction.test.tsx +76 -0
  148. package/src/NavigationMenu/__tests__/NavigationMenu.uncontrolled-state.test.tsx +30 -0
  149. package/src/NavigationMenu/__tests__/NavigationMenu.viewport.test.tsx +113 -0
  150. package/src/NavigationMenu/constants.ts +5 -0
  151. package/src/NavigationMenu/hooks/index.ts +7 -0
  152. package/src/NavigationMenu/hooks/useNavigationMenuEntry.ts +33 -0
  153. package/src/NavigationMenu/hooks/useNavigationMenuIndicator.ts +70 -0
  154. package/src/NavigationMenu/hooks/useNavigationMenuLink.ts +72 -0
  155. package/src/NavigationMenu/hooks/useNavigationMenuRoot.ts +301 -0
  156. package/src/NavigationMenu/hooks/useNavigationMenuTopLevelEntry.ts +65 -0
  157. package/src/NavigationMenu/hooks/useNavigationMenuTrigger.ts +158 -0
  158. package/src/NavigationMenu/hooks/useNavigationMenuViewport.ts +101 -0
  159. package/src/NavigationMenu/index.ts +3 -0
  160. package/src/NavigationMenu/types.ts +259 -0
  161. package/src/NavigationMenu/utils.ts +89 -0
  162. package/src/Popover/Popover.tsx +427 -0
  163. package/src/Popover/PopoverContext.ts +13 -0
  164. package/src/Popover/README.md +106 -0
  165. package/src/Popover/__tests__/Popover.anchor.test.tsx +38 -0
  166. package/src/Popover/__tests__/Popover.asChild.test.tsx +160 -0
  167. package/src/Popover/__tests__/Popover.basic-rendering.test.tsx +106 -0
  168. package/src/Popover/__tests__/Popover.click-outside.test.tsx +149 -0
  169. package/src/Popover/__tests__/Popover.close.test.tsx +70 -0
  170. package/src/Popover/__tests__/Popover.content.test.tsx +58 -0
  171. package/src/Popover/__tests__/Popover.controlled-state.test.tsx +45 -0
  172. package/src/Popover/__tests__/Popover.error-handling.test.tsx +51 -0
  173. package/src/Popover/__tests__/Popover.focus.test.tsx +43 -0
  174. package/src/Popover/__tests__/Popover.keyboard-interaction.test.tsx +71 -0
  175. package/src/Popover/__tests__/Popover.mouse-interaction.test.tsx +69 -0
  176. package/src/Popover/__tests__/Popover.uncontrolled-state.test.tsx +44 -0
  177. package/src/Popover/hooks/index.ts +3 -0
  178. package/src/Popover/hooks/usePopoverContent.ts +98 -0
  179. package/src/Popover/hooks/usePopoverRoot.ts +84 -0
  180. package/src/Popover/hooks/usePopoverTrigger.ts +33 -0
  181. package/src/Popover/index.ts +2 -0
  182. package/src/Popover/types.ts +197 -0
  183. package/src/Portal/Portal.tsx +50 -10
  184. package/src/Portal/__tests__/Portal.basic-rendering.test.tsx +5 -0
  185. package/src/Portal/types.ts +5 -0
  186. package/src/Progress/Progress.tsx +33 -1
  187. package/src/Progress/__tests__/Progress.basic-rendering.test.tsx +10 -0
  188. package/src/Progress/__tests__/Progress.value.test.tsx +21 -0
  189. package/src/Progress/types.ts +20 -4
  190. package/src/Radio/Radio.tsx +9 -1
  191. package/src/Radio/__tests__/Radio.basic-rendering.test.tsx +14 -0
  192. package/src/Radio/hooks/useRadioRoot.ts +3 -0
  193. package/src/Radio/types.ts +20 -0
  194. package/src/RadioCard/RadioCard.tsx +11 -0
  195. package/src/RadioCard/__tests__/RadioCard.basic-rendering.test.tsx +8 -0
  196. package/src/RadioCard/__tests__/RadioCard.disabled-items.test.tsx +27 -0
  197. package/src/RadioCard/__tests__/RadioCard.keyboard-interaction.test.tsx +53 -0
  198. package/src/RadioCard/__tests__/RadioCard.ref-forwarding.test.tsx +54 -0
  199. package/src/RadioCard/__tests__/RadioCard.uncontrolled-state.test.tsx +21 -0
  200. package/src/RadioCard/hooks/useRadioCardRoot.ts +11 -0
  201. package/src/RadioCard/types.ts +95 -22
  202. package/src/RadioGroup/RadioGroup.tsx +11 -0
  203. package/src/RadioGroup/__tests__/RadioGroup.basic-rendering.test.tsx +8 -0
  204. package/src/RadioGroup/__tests__/RadioGroup.disabled.test.tsx +27 -0
  205. package/src/RadioGroup/__tests__/RadioGroup.ref-forwarding.test.tsx +29 -0
  206. package/src/RadioGroup/__tests__/RadioGroup.roving-tabindex.test.tsx +31 -0
  207. package/src/RadioGroup/hooks/useRadioGroupRoot.ts +11 -0
  208. package/src/RadioGroup/types.ts +73 -9
  209. package/src/SegmentedControl/README.md +154 -0
  210. package/src/SegmentedControl/SegmentedControl.tsx +309 -0
  211. package/src/SegmentedControl/SegmentedControlContext.ts +28 -0
  212. package/src/SegmentedControl/__tests__/SegmentedControl.asChild.test.tsx +50 -0
  213. package/src/SegmentedControl/__tests__/SegmentedControl.basic-rendering.test.tsx +100 -0
  214. package/src/SegmentedControl/__tests__/SegmentedControl.controlled-state.test.tsx +107 -0
  215. package/src/SegmentedControl/__tests__/SegmentedControl.disabled-keydown-guards.test.tsx +62 -0
  216. package/src/SegmentedControl/__tests__/SegmentedControl.disabled.test.tsx +151 -0
  217. package/src/SegmentedControl/__tests__/SegmentedControl.error-handling.test.tsx +17 -0
  218. package/src/SegmentedControl/__tests__/SegmentedControl.keyboard-interaction.test.tsx +117 -0
  219. package/src/SegmentedControl/__tests__/SegmentedControl.orientation.test.tsx +54 -0
  220. package/src/SegmentedControl/__tests__/SegmentedControl.reading-direction.test.tsx +56 -0
  221. package/src/SegmentedControl/__tests__/SegmentedControl.ref-forwarding.test.tsx +45 -0
  222. package/src/SegmentedControl/__tests__/SegmentedControl.roving-tabindex.test.tsx +104 -0
  223. package/src/SegmentedControl/__tests__/SegmentedControl.uncontrolled-state.test.tsx +94 -0
  224. package/src/SegmentedControl/hooks/index.ts +2 -0
  225. package/src/SegmentedControl/hooks/useSegmentedControlContext.ts +1 -0
  226. package/src/SegmentedControl/hooks/useSegmentedControlRoot.ts +86 -0
  227. package/src/SegmentedControl/index.ts +2 -0
  228. package/src/SegmentedControl/types.ts +138 -0
  229. package/src/Select/README.md +122 -157
  230. package/src/Select/Select.tsx +595 -68
  231. package/src/Select/SelectContext.ts +38 -0
  232. package/src/Select/SelectItemIndicatorContext.ts +29 -0
  233. package/src/Select/__tests__/Select.asChild.test.tsx +2 -2
  234. package/src/Select/__tests__/Select.basic-rendering.test.tsx +22 -3
  235. package/src/Select/__tests__/Select.controlled-state.test.tsx +6 -6
  236. package/src/Select/__tests__/Select.data-attributes.test.tsx +4 -4
  237. package/src/Select/__tests__/Select.field-integration.test.tsx +11 -11
  238. package/src/Select/__tests__/Select.form.test.tsx +38 -0
  239. package/src/Select/__tests__/Select.group.test.tsx +6 -6
  240. package/src/Select/__tests__/Select.keyboard-edge.test.tsx +95 -0
  241. package/src/Select/__tests__/Select.keyboard.test.tsx +124 -0
  242. package/src/Select/__tests__/Select.mutation-hardening.test.tsx +317 -0
  243. package/src/Select/__tests__/Select.native-item.test.tsx +30 -0
  244. package/src/Select/__tests__/Select.open-close.test.tsx +57 -0
  245. package/src/Select/__tests__/Select.placeholder.test.tsx +4 -4
  246. package/src/Select/__tests__/Select.rich-asChild.test.tsx +60 -0
  247. package/src/Select/__tests__/Select.rich-mode.test.tsx +16 -0
  248. package/src/Select/__tests__/Select.selection.test.tsx +104 -0
  249. package/src/Select/__tests__/Select.separator.test.tsx +71 -0
  250. package/src/Select/__tests__/Select.strict-context.test.tsx +36 -0
  251. package/src/Select/__tests__/Select.typeahead.test.tsx +156 -0
  252. package/src/Select/__tests__/Select.value-mirror.test.tsx +240 -0
  253. package/src/Select/constants.ts +8 -0
  254. package/src/Select/hooks/index.ts +2 -0
  255. package/src/Select/hooks/useSelectContent.ts +149 -0
  256. package/src/Select/hooks/useSelectRoot.ts +149 -0
  257. package/src/Select/types.ts +199 -31
  258. package/src/SkipNav/SkipNav.tsx +69 -29
  259. package/src/SkipNav/__tests__/SkipNav.basic-rendering.test.tsx +6 -0
  260. package/src/SkipNav/types.ts +17 -9
  261. package/src/Slider/Slider.tsx +33 -1
  262. package/src/Slider/SliderContext.ts +28 -1
  263. package/src/Slider/types.ts +157 -9
  264. package/src/Slot/Slot.tsx +94 -19
  265. package/src/Slot/__tests__/Slot.test.tsx +110 -0
  266. package/src/Slot/composeEventHandlers.ts +26 -2
  267. package/src/Slot/types.ts +16 -0
  268. package/src/Status/Status.tsx +36 -15
  269. package/src/Status/__tests__/Status.test.tsx +5 -0
  270. package/src/Status/types.ts +12 -1
  271. package/src/Switch/Switch.tsx +15 -2
  272. package/src/Switch/__tests__/Switch.basic-rendering.test.tsx +7 -0
  273. package/src/Switch/hooks/useSwitchRoot.ts +3 -0
  274. package/src/Switch/types.ts +49 -22
  275. package/src/Table/Table.tsx +44 -10
  276. package/src/Table/types.ts +66 -17
  277. package/src/Tabs/Tabs.tsx +8 -0
  278. package/src/Tabs/types.ts +29 -4
  279. package/src/Textarea/Textarea.tsx +9 -1
  280. package/src/Textarea/__tests__/Textarea.basic-rendering.test.tsx +5 -0
  281. package/src/Textarea/types.ts +20 -3
  282. package/src/Toggle/Toggle.tsx +51 -13
  283. package/src/Toggle/__tests__/Toggle.basic-rendering.test.tsx +5 -0
  284. package/src/Toggle/types.ts +54 -4
  285. package/src/ToggleGroup/ToggleGroup.tsx +14 -1
  286. package/src/ToggleGroup/__tests__/ToggleGroup.asChild.test.tsx +20 -0
  287. package/src/ToggleGroup/__tests__/ToggleGroup.basic-rendering.test.tsx +9 -0
  288. package/src/ToggleGroup/__tests__/ToggleGroup.dynamic-items.test.tsx +70 -0
  289. package/src/ToggleGroup/__tests__/ToggleGroup.error-handling.test.tsx +23 -0
  290. package/src/ToggleGroup/__tests__/ToggleGroup.keyboard-interaction.test.tsx +23 -1
  291. package/src/ToggleGroup/__tests__/ToggleGroup.ref-forwarding.test.tsx +58 -0
  292. package/src/ToggleGroup/hooks/useToggleGroupRoot.ts +21 -1
  293. package/src/ToggleGroup/types.ts +55 -2
  294. package/src/Tooltip/Tooltip.tsx +98 -20
  295. package/src/Tooltip/hooks/__tests__/useTooltipProvider.test.tsx +40 -0
  296. package/src/Tooltip/hooks/useTooltipProvider.ts +13 -1
  297. package/src/Tooltip/types.ts +89 -8
  298. package/src/Tree/Tree.tsx +187 -33
  299. package/src/Tree/types.ts +54 -12
  300. package/src/VisuallyHidden/VisuallyHidden.tsx +33 -8
  301. package/src/VisuallyHidden/__tests__/VisuallyHidden.test.tsx +15 -1
  302. package/src/VisuallyHidden/types.ts +11 -1
  303. package/src/index.ts +4 -0
  304. package/src/test/intersectionObserverPolyfill.ts +7 -0
  305. package/src/test/resizeObserverPolyfill.ts +80 -0
  306. package/src/utils/focusable.ts +15 -0
  307. package/src/utils/index.ts +1 -0
@@ -9,7 +9,9 @@ export function useCollapsibleTrigger({
9
9
  ref,
10
10
  onClick,
11
11
  onKeyDown,
12
- asChild = false,
12
+ // No default: the `CollapsibleTrigger` component always supplies a resolved
13
+ // `asChild` boolean, so a default here would be unreachable (dead) code.
14
+ asChild,
13
15
  ...rest
14
16
  }: Omit<CollapsibleTriggerProps, "children">) {
15
17
  const { open, disabled, toggle, triggerId, contentId } =
@@ -1,68 +1,135 @@
1
1
  import { ComponentProps, ReactNode, Ref } from "react";
2
2
 
3
- /** Props common to both controlled and uncontrolled `Collapsible.Root` modes. */
3
+ /**
4
+ * Shared base for both {@link CollapsibleRootProps} variants — the native
5
+ * `<div>` attributes (minus the conflicting `onChange`) plus the `disabled`
6
+ * flag common to both state modes.
7
+ */
4
8
  export type CollapsibleRootBaseProps = Omit<
5
9
  ComponentProps<"div">,
6
10
  "onChange"
7
11
  > & {
8
- /** When `true`, disables the widget and short-circuits trigger activation. */
12
+ /**
13
+ * When `true`, disables the widget: the {@link CollapsibleTriggerProps |
14
+ * Trigger} renders `aria-disabled="true"` (staying focusable) and both
15
+ * click and keyboard activation are short-circuited. Mirrored as
16
+ * `data-disabled` onto Root, Trigger, and Content.
17
+ * @default false
18
+ */
9
19
  disabled?: boolean;
10
20
  };
11
21
 
12
22
  /**
13
- * Props for `Collapsible.Root` in uncontrolled mode — the component owns the
14
- * open state. Pass `defaultOpen` to set the initial value; `open` is forbidden.
23
+ * Uncontrolled variant of {@link CollapsibleRootProps}: the component owns
24
+ * the open state. Pass `defaultOpen` (or omit it); `open` is forbidden.
15
25
  */
16
26
  export type CollapsibleRootUncontrolledProps = CollapsibleRootBaseProps & {
17
- /** Initial open state when uncontrolled. Defaults to `false`. */
27
+ /**
28
+ * Initial open state on first render. The component owns the value
29
+ * thereafter.
30
+ * @default false
31
+ */
18
32
  defaultOpen?: boolean;
19
- /** Forbidden in uncontrolled mode. */
33
+ /** Forbidden in uncontrolled mode — use `defaultOpen` instead. */
20
34
  open?: never;
21
- /** Called whenever the open state changes. */
35
+ /** Called with the new open state on every toggle. Optional in
36
+ * uncontrolled mode (Collapsible fires it in both modes). */
22
37
  onOpenChange?: (open: boolean) => void;
23
38
  };
24
39
 
25
40
  /**
26
- * Props for `Collapsible.Root` in controlled mode — the parent owns the open
27
- * value. Pass `open` and `onOpenChange` together; `defaultOpen` is forbidden.
41
+ * Controlled variant of {@link CollapsibleRootProps}: the parent owns the
42
+ * open value. Pass `open` and `onOpenChange` together; `defaultOpen` is
43
+ * forbidden.
28
44
  */
29
45
  export type CollapsibleRootControlledProps = CollapsibleRootBaseProps & {
30
- /** The controlled open state. */
46
+ /** The controlled open state. Must be kept in sync by the parent via
47
+ * `onOpenChange`. */
31
48
  open: boolean;
32
- /** Called whenever the component requests an open-state change. */
49
+ /** Called with the requested open state on every toggle. Required in
50
+ * controlled mode. */
33
51
  onOpenChange: (open: boolean) => void;
34
- /** Forbidden in controlled mode. */
52
+ /** Forbidden in controlled mode — use `open` instead. */
35
53
  defaultOpen?: never;
36
54
  };
37
55
 
38
- /** Props for `Collapsible.Root` — discriminated controlled/uncontrolled union. */
56
+ /**
57
+ * Props for {@link CollapsibleRoot | `Collapsible.Root`}.
58
+ *
59
+ * Resolves to either {@link CollapsibleRootUncontrolledProps} or
60
+ * {@link CollapsibleRootControlledProps} — only one shape is accepted by
61
+ * TypeScript at a time.
62
+ */
39
63
  export type CollapsibleRootProps =
40
64
  | CollapsibleRootUncontrolledProps
41
65
  | CollapsibleRootControlledProps;
42
66
 
43
- /** Props for `Collapsible.Trigger`, the button that toggles the panel. */
67
+ /**
68
+ * Props for {@link CollapsibleTrigger | `Collapsible.Trigger`}, the button
69
+ * that toggles the panel.
70
+ *
71
+ * Generic over the rendered element type so `asChild` consumers can type
72
+ * the forwarded `ref` (e.g. `Collapsible.Trigger<HTMLAnchorElement>`).
73
+ */
44
74
  export type CollapsibleTriggerProps<T extends HTMLElement = HTMLButtonElement> =
45
75
  Omit<ComponentProps<"button">, "ref"> & {
46
- /** Trigger content (label, icon, etc.). */
76
+ /** Trigger content (label, and optionally a
77
+ * {@link CollapsibleTriggerIconProps | TriggerIcon}). */
47
78
  children: ReactNode;
48
- /** Render the child element instead of the default `<button>`. */
79
+ /**
80
+ * Render a single consumer-supplied child element instead of the default
81
+ * `<button>`, merging the Trigger's ARIA, handlers, and ref onto it via
82
+ * the {@link Slot} pattern. When `asChild` and the Root is `disabled`,
83
+ * `role="button"` is injected so `aria-disabled` is semantically valid.
84
+ * @default false
85
+ */
49
86
  asChild?: boolean;
50
- /** Ref to the rendered element. Defaults to `HTMLButtonElement`; when using
51
- * `asChild`, specify the child's element type (e.g. `HTMLAnchorElement`). */
87
+ /** Forwarded to the rendered element. Defaults to `HTMLButtonElement`;
88
+ * when using `asChild`, specify the child's element type (e.g.
89
+ * `HTMLAnchorElement`). Composed with the library's internal ref. */
52
90
  ref?: Ref<T>;
53
91
  };
54
92
 
55
- /** Props for `Collapsible.Content`, the panel revealed when open. */
93
+ /**
94
+ * Props for {@link CollapsibleContent | `Collapsible.Content`}, the panel
95
+ * revealed when open.
96
+ */
56
97
  export type CollapsibleContentProps = ComponentProps<"div"> & {
57
98
  /** Panel content. */
58
99
  children: ReactNode;
59
- /** Keep the panel mounted when closed so transitions can be CSS-driven. */
100
+ /**
101
+ * Keep the panel mounted (and in the DOM) even when closed, so open/close
102
+ * transitions can be CSS-driven. When closed under `forceMount`, the panel
103
+ * gets `aria-hidden="true"` instead of the `hidden` attribute. Consumers
104
+ * may override `aria-hidden` explicitly.
105
+ * @default false
106
+ */
60
107
  forceMount?: boolean;
108
+ /**
109
+ * Show a **clamped preview** of the panel while closed instead of hiding it
110
+ * entirely — the "collapsed height" / read-more pattern. A `number` is taken
111
+ * as pixels; a string is used verbatim as a CSS length (e.g. `"4rem"`,
112
+ * `"20cqi"`). When set:
113
+ *
114
+ * - the panel is always mounted and never gets the `hidden` attribute or
115
+ * `aria-hidden` (the preview is real, readable content), so `forceMount` is
116
+ * implied;
117
+ * - the value is emitted as the `--primitiv-collapsible-collapsed-height`
118
+ * custom property on the panel, which the styling layer clamps the closed
119
+ * height to (e.g. `max-block-size`) and anchors a bottom fade-shadow to,
120
+ * keyed off `data-state="closed"`.
121
+ *
122
+ * Leave unset for the default fully-hidden / grid-collapse behaviour.
123
+ */
124
+ collapsedHeight?: number | string;
61
125
  };
62
126
 
63
- /** Props for `Collapsible.TriggerIcon`, the aria-hidden icon wrapper. */
127
+ /**
128
+ * Props for {@link CollapsibleTriggerIcon | `Collapsible.TriggerIcon`}, the
129
+ * `aria-hidden` icon wrapper carrying an open/closed `data-state` hook.
130
+ */
64
131
  export type CollapsibleTriggerIconProps = ComponentProps<"span"> & {
65
- /** The icon to render (inline SVG or icon component). */
132
+ /** The icon to render (inline SVG or an icon component). */
66
133
  children: ReactNode;
67
134
  };
68
135
 
@@ -67,6 +67,30 @@ import { MENUITEM_SELECTOR, TYPEAHEAD_RESET_MS } from "./constants";
67
67
  * set `"ltr"` or `"rtl"`, which inverts the submenu open / close arrow
68
68
  * keys (`ArrowRight` ↔ `ArrowLeft`). When omitted, the component reads
69
69
  * the inherited {@link DirectionProvider} value, falling back to `"ltr"`.
70
+ *
71
+ * Renders no DOM of its own — no extended host element — it is purely a
72
+ * context provider around its `children`.
73
+ *
74
+ * @example Uncontrolled
75
+ * ```tsx
76
+ * <ContextMenu.Root>
77
+ * <ContextMenu.Trigger>
78
+ * <div className="canvas">Right-click here</div>
79
+ * </ContextMenu.Trigger>
80
+ * <ContextMenu.Content>
81
+ * <ContextMenu.Item onSelect={paste}>Paste</ContextMenu.Item>
82
+ * </ContextMenu.Content>
83
+ * </ContextMenu.Root>
84
+ * ```
85
+ *
86
+ * @example Controlled
87
+ * ```tsx
88
+ * const [open, setOpen] = useState(false);
89
+ *
90
+ * <ContextMenu.Root open={open} onOpenChange={setOpen}>
91
+ * …
92
+ * </ContextMenu.Root>
93
+ * ```
70
94
  */
71
95
  export function ContextMenuRoot({
72
96
  defaultOpen = false,
@@ -141,6 +165,26 @@ function useCloseSiblingSub() {
141
165
  * right-click, long-press on touch, or the keyboard context-menu key),
142
166
  * the native menu is suppressed and the ContextMenu opens, positioned at
143
167
  * the pointer.
168
+ *
169
+ * A `disabled` Trigger ignores the gesture entirely, letting the native
170
+ * browser menu through. `data-disabled=""` and `data-state="closed"` are
171
+ * exposed for styling.
172
+ *
173
+ * @extends HTMLSpanElement
174
+ *
175
+ * @example Default `<span>` host
176
+ * ```tsx
177
+ * <ContextMenu.Trigger>
178
+ * <div className="canvas">Right-click anywhere</div>
179
+ * </ContextMenu.Trigger>
180
+ * ```
181
+ *
182
+ * @example asChild — attach the gesture to any element
183
+ * ```tsx
184
+ * <ContextMenu.Trigger asChild>
185
+ * <ImageCard src="…" alt="…" />
186
+ * </ContextMenu.Trigger>
187
+ * ```
144
188
  */
145
189
  export function ContextMenuTrigger({
146
190
  children,
@@ -197,6 +241,27 @@ ContextMenuTrigger.displayName = "ContextMenuTrigger";
197
241
  * custom properties so consumer CSS can write `@position-try` fallbacks
198
242
  * that flip the menu to the opposite side when it would overflow the
199
243
  * viewport. Pass `asChild` to render any element with menu semantics.
244
+ *
245
+ * **Focus & keyboard.** On open, focus moves to the first enabled item.
246
+ * `ArrowDown` / `ArrowUp` move between items (wrapping), `Home` / `End`
247
+ * jump to the first / last, `Enter` / `Space` activate the focused item,
248
+ * `Escape` closes and returns focus to the Trigger, and any printable
249
+ * character starts a typeahead search (accumulated within a 500 ms window;
250
+ * repeating a character cycles items sharing that first letter). Disabled
251
+ * items are skipped throughout. `data-state="open" | "closed"` is exposed
252
+ * for state-driven styling.
253
+ *
254
+ * @extends HTMLMenuElement
255
+ *
256
+ * @example
257
+ * ```tsx
258
+ * <ContextMenu.Content>
259
+ * <ContextMenu.Item onSelect={cut}>Cut</ContextMenu.Item>
260
+ * <ContextMenu.Item onSelect={copy}>Copy</ContextMenu.Item>
261
+ * <ContextMenu.Separator />
262
+ * <ContextMenu.Item disabled>Archive</ContextMenu.Item>
263
+ * </ContextMenu.Content>
264
+ * ```
200
265
  */
201
266
  export function ContextMenuContent({
202
267
  children,
@@ -388,7 +453,24 @@ ContextMenuContent.displayName = "ContextMenuContent";
388
453
  * `Event`. The menu auto-closes after selection; call
389
454
  * `event.preventDefault()` inside `onSelect` to keep it open.
390
455
  *
391
- * Disabled items receive `aria-disabled="true"` and no-op on activation.
456
+ * Disabled items receive `aria-disabled="true"` and no-op on activation;
457
+ * arrow navigation and typeahead skip them. `data-highlighted=""` is
458
+ * present while the pointer hovers the item.
459
+ *
460
+ * @extends HTMLLIElement
461
+ *
462
+ * @example
463
+ * ```tsx
464
+ * <ContextMenu.Item onSelect={() => rename()}>Rename</ContextMenu.Item>
465
+ * <ContextMenu.Item disabled>Archive (coming soon)</ContextMenu.Item>
466
+ * ```
467
+ *
468
+ * @example asChild — render a link with menuitem semantics
469
+ * ```tsx
470
+ * <ContextMenu.Item asChild>
471
+ * <a href="/rename">Rename</a>
472
+ * </ContextMenu.Item>
473
+ * ```
392
474
  */
393
475
  export function ContextMenuItem({
394
476
  children,
@@ -441,6 +523,15 @@ ContextMenuItem.displayName = "ContextMenuItem";
441
523
  * A visual separator between groups of items. Renders a `<li role="separator">`
442
524
  * by default. Non-interactive — skipped by focus, arrow navigation, and
443
525
  * typeahead.
526
+ *
527
+ * @extends HTMLLIElement
528
+ *
529
+ * @example
530
+ * ```tsx
531
+ * <ContextMenu.Item>Copy</ContextMenu.Item>
532
+ * <ContextMenu.Separator />
533
+ * <ContextMenu.Item>Delete</ContextMenu.Item>
534
+ * ```
444
535
  */
445
536
  export function ContextMenuSeparator({
446
537
  asChild = false,
@@ -466,6 +557,17 @@ ContextMenuSeparator.displayName = "ContextMenuSeparator";
466
557
  *
467
558
  * Generates a stable id for its accompanying {@link ContextMenuLabel |
468
559
  * `ContextMenu.Label`}, wired automatically via `aria-labelledby`.
560
+ *
561
+ * @extends HTMLLIElement
562
+ *
563
+ * @example
564
+ * ```tsx
565
+ * <ContextMenu.Group>
566
+ * <ContextMenu.Label>Edit</ContextMenu.Label>
567
+ * <ContextMenu.Item>Undo</ContextMenu.Item>
568
+ * <ContextMenu.Item>Redo</ContextMenu.Item>
569
+ * </ContextMenu.Group>
570
+ * ```
469
571
  */
470
572
  export function ContextMenuGroup({
471
573
  children,
@@ -502,6 +604,16 @@ ContextMenuGroup.displayName = "ContextMenuGroup";
502
604
  * a group, the label's `id` is auto-wired to the group's `aria-labelledby` —
503
605
  * consumers don't need to thread ids manually. A caller-supplied `id` takes
504
606
  * precedence over the auto-generated one.
607
+ *
608
+ * @extends HTMLLIElement
609
+ *
610
+ * @example
611
+ * ```tsx
612
+ * <ContextMenu.Group>
613
+ * <ContextMenu.Label>View</ContextMenu.Label>
614
+ * <ContextMenu.CheckboxItem>Show grid</ContextMenu.CheckboxItem>
615
+ * </ContextMenu.Group>
616
+ * ```
505
617
  */
506
618
  export function ContextMenuLabel({
507
619
  id,
@@ -532,7 +644,36 @@ ContextMenuLabel.displayName = "ContextMenuLabel";
532
644
  * {@link ContextMenuCheckboxItemProps.onSelect | `onSelect`} with a
533
645
  * cancellable `Event`. Call `event.preventDefault()` to keep the menu open.
534
646
  *
647
+ * Supports both state modes: uncontrolled via
648
+ * {@link ContextMenuCheckboxItemUncontrolledProps.defaultChecked | `defaultChecked`},
649
+ * or controlled via
650
+ * {@link ContextMenuCheckboxItemControlledProps.checked | `checked`} +
651
+ * {@link ContextMenuCheckboxItemControlledProps.onCheckedChange | `onCheckedChange`}.
652
+ * Render a {@link ContextMenuItemIndicator | `ContextMenu.ItemIndicator`}
653
+ * inside it for the visible mark.
654
+ *
535
655
  * Disabled items receive `aria-disabled="true"` and no-op on activation.
656
+ *
657
+ * @extends HTMLLIElement
658
+ *
659
+ * @example Uncontrolled, with an indicator
660
+ * ```tsx
661
+ * <ContextMenu.CheckboxItem defaultChecked>
662
+ * <ContextMenu.ItemIndicator><CheckIcon /></ContextMenu.ItemIndicator>
663
+ * Show grid
664
+ * </ContextMenu.CheckboxItem>
665
+ * ```
666
+ *
667
+ * @example Controlled, kept open for rapid toggling
668
+ * ```tsx
669
+ * <ContextMenu.CheckboxItem
670
+ * checked={showRuler}
671
+ * onCheckedChange={setShowRuler}
672
+ * onSelect={(event) => event.preventDefault()}
673
+ * >
674
+ * Show ruler
675
+ * </ContextMenu.CheckboxItem>
676
+ * ```
536
677
  */
537
678
  export function ContextMenuCheckboxItem({
538
679
  children,
@@ -612,6 +753,25 @@ ContextMenuCheckboxItem.displayName = "ContextMenuCheckboxItem";
612
753
  * By default the indicator unmounts when its parent is unchecked. Pass
613
754
  * {@link ContextMenuItemIndicatorProps.forceMount | `forceMount`} to keep
614
755
  * the DOM node mounted in both states for animation use cases.
756
+ *
757
+ * @extends HTMLSpanElement
758
+ *
759
+ * @example Compose onto an icon
760
+ * ```tsx
761
+ * <ContextMenu.CheckboxItem checked={bookmarked} onCheckedChange={setBookmarked}>
762
+ * <ContextMenu.ItemIndicator asChild>
763
+ * <CheckIcon aria-hidden />
764
+ * </ContextMenu.ItemIndicator>
765
+ * Bookmark
766
+ * </ContextMenu.CheckboxItem>
767
+ * ```
768
+ *
769
+ * @example forceMount for CSS-driven transitions
770
+ * ```tsx
771
+ * <ContextMenu.ItemIndicator forceMount>
772
+ * <CheckIcon />
773
+ * </ContextMenu.ItemIndicator>
774
+ * ```
615
775
  */
616
776
  export function ContextMenuItemIndicator({
617
777
  children,
@@ -652,6 +812,23 @@ ContextMenuItemIndicator.displayName = "ContextMenuItemIndicator";
652
812
  * A single-selection group of menu items. Children must be
653
813
  * {@link ContextMenuRadioItem | `ContextMenu.RadioItem`} elements. Renders a
654
814
  * `<li role="group">` wrapping `<ul role="none">`.
815
+ *
816
+ * Owns the selected value: uncontrolled via
817
+ * {@link ContextMenuRadioGroupUncontrolledProps.defaultValue | `defaultValue`},
818
+ * or controlled via
819
+ * {@link ContextMenuRadioGroupControlledProps.value | `value`} +
820
+ * {@link ContextMenuRadioGroupControlledProps.onValueChange | `onValueChange`}.
821
+ *
822
+ * @extends HTMLLIElement
823
+ *
824
+ * @example
825
+ * ```tsx
826
+ * <ContextMenu.RadioGroup defaultValue="system">
827
+ * <ContextMenu.RadioItem value="light">Light</ContextMenu.RadioItem>
828
+ * <ContextMenu.RadioItem value="dark">Dark</ContextMenu.RadioItem>
829
+ * <ContextMenu.RadioItem value="system">Match system</ContextMenu.RadioItem>
830
+ * </ContextMenu.RadioGroup>
831
+ * ```
655
832
  */
656
833
  export function ContextMenuRadioGroup({
657
834
  defaultValue,
@@ -696,6 +873,18 @@ ContextMenuRadioGroup.displayName = "ContextMenuRadioGroup";
696
873
  * Activation (click) selects this item, updating the group's value, then fires
697
874
  * {@link ContextMenuRadioItemProps.onSelect | `onSelect`} with a cancellable
698
875
  * `Event`. Call `event.preventDefault()` to keep the menu open.
876
+ *
877
+ * Disabled items receive `aria-disabled="true"` and no-op on activation.
878
+ *
879
+ * @extends HTMLLIElement
880
+ *
881
+ * @example
882
+ * ```tsx
883
+ * <ContextMenu.RadioItem value="dark">
884
+ * <ContextMenu.ItemIndicator><DotIcon /></ContextMenu.ItemIndicator>
885
+ * Dark
886
+ * </ContextMenu.RadioItem>
887
+ * ```
699
888
  */
700
889
  export function ContextMenuRadioItem({
701
890
  children,
@@ -767,6 +956,20 @@ ContextMenuRadioItem.displayName = "ContextMenuRadioItem";
767
956
  * `ContextMenu.Sub` to establish an independent open state for the nested
768
957
  * menu. Supports uncontrolled (`defaultOpen`) and controlled (`open` +
769
958
  * `onOpenChange`) modes.
959
+ *
960
+ * Renders no DOM of its own — no extended host element — it is purely a
961
+ * context boundary around the SubTrigger / SubContent pair.
962
+ *
963
+ * @example
964
+ * ```tsx
965
+ * <ContextMenu.Sub>
966
+ * <ContextMenu.SubTrigger>Share</ContextMenu.SubTrigger>
967
+ * <ContextMenu.SubContent>
968
+ * <ContextMenu.Item>Email</ContextMenu.Item>
969
+ * <ContextMenu.Item>Copy link</ContextMenu.Item>
970
+ * </ContextMenu.SubContent>
971
+ * </ContextMenu.Sub>
972
+ * ```
770
973
  */
771
974
  export function ContextMenuSub({
772
975
  defaultOpen,
@@ -838,7 +1041,18 @@ ContextMenuSub.displayName = "ContextMenuSub";
838
1041
  * Opens the submenu on click, the inline-forward arrow key, or pointer
839
1042
  * hover. The open key follows the resolved reading direction —
840
1043
  * `ArrowRight` in `"ltr"`, `ArrowLeft` in `"rtl"`. Disabled triggers
841
- * ignore both click and the open arrow key.
1044
+ * ignore both click and the open arrow key. `data-highlighted=""` is
1045
+ * present while hovered or while its submenu is open.
1046
+ *
1047
+ * @extends HTMLLIElement
1048
+ *
1049
+ * @example
1050
+ * ```tsx
1051
+ * <ContextMenu.Sub>
1052
+ * <ContextMenu.SubTrigger>More tools</ContextMenu.SubTrigger>
1053
+ * <ContextMenu.SubContent>…</ContextMenu.SubContent>
1054
+ * </ContextMenu.Sub>
1055
+ * ```
842
1056
  */
843
1057
  export function ContextMenuSubTrigger({
844
1058
  children,
@@ -902,6 +1116,20 @@ ContextMenuSubTrigger.displayName = "ContextMenuSubTrigger";
902
1116
  * opens, focus moves to its first enabled item. The inline-backward arrow
903
1117
  * key closes the submenu and returns focus to the SubTrigger —
904
1118
  * `ArrowLeft` in `"ltr"`, `ArrowRight` in `"rtl"`.
1119
+ *
1120
+ * Unlike {@link ContextMenuContent | `ContextMenu.Content`}, the submenu
1121
+ * panel uses `popover="auto"` — it is opened programmatically and nests
1122
+ * inside the already-open manual root popover.
1123
+ *
1124
+ * @extends HTMLMenuElement
1125
+ *
1126
+ * @example
1127
+ * ```tsx
1128
+ * <ContextMenu.SubContent>
1129
+ * <ContextMenu.Item>Email</ContextMenu.Item>
1130
+ * <ContextMenu.Item>Copy link</ContextMenu.Item>
1131
+ * </ContextMenu.SubContent>
1132
+ * ```
905
1133
  */
906
1134
  export function ContextMenuSubContent({
907
1135
  children,
@@ -1001,8 +1229,46 @@ export type TContextMenuCompound = typeof ContextMenuRoot & {
1001
1229
  * by a right-click (or long-press) on its trigger, with submenus, checkbox and
1002
1230
  * radio items, groups, labels and separators. Zero styles ship.
1003
1231
  *
1004
- * The default export is the `Root`; sub-components are attached as static
1005
- * properties (`ContextMenu.Trigger`, `ContextMenu.Content`, …).
1232
+ * `ContextMenu` is both callable (it is an alias of
1233
+ * {@link ContextMenuRoot | `ContextMenu.Root`}) and carries its
1234
+ * sub-components as static properties. Prefer the namespaced form in
1235
+ * application code for readability and grep-ability:
1236
+ *
1237
+ * - {@link ContextMenuRoot | `ContextMenu.Root`} — open-state owner and direction provider (no DOM).
1238
+ * - {@link ContextMenuTrigger | `ContextMenu.Trigger`} — the right-click target (`<span>`).
1239
+ * - {@link ContextMenuContent | `ContextMenu.Content`} — the `role="menu"` popover panel.
1240
+ * - {@link ContextMenuItem | `ContextMenu.Item`} — a `role="menuitem"` row.
1241
+ * - {@link ContextMenuCheckboxItem | `ContextMenu.CheckboxItem`} — a tri-state `role="menuitemcheckbox"`.
1242
+ * - {@link ContextMenuRadioGroup | `ContextMenu.RadioGroup`} — single-selection container.
1243
+ * - {@link ContextMenuRadioItem | `ContextMenu.RadioItem`} — a `role="menuitemradio"` choice.
1244
+ * - {@link ContextMenuItemIndicator | `ContextMenu.ItemIndicator`} — the checked-state mark.
1245
+ * - {@link ContextMenuGroup | `ContextMenu.Group`} — a `role="group"` of related items.
1246
+ * - {@link ContextMenuLabel | `ContextMenu.Label`} — a non-interactive group caption.
1247
+ * - {@link ContextMenuSeparator | `ContextMenu.Separator`} — a `role="separator"` divider.
1248
+ * - {@link ContextMenuSub | `ContextMenu.Sub`} — a submenu boundary (no DOM).
1249
+ * - {@link ContextMenuSubTrigger | `ContextMenu.SubTrigger`} — opens a submenu.
1250
+ * - {@link ContextMenuSubContent | `ContextMenu.SubContent`} — the submenu panel.
1251
+ *
1252
+ * @example Minimal usage
1253
+ * ```tsx
1254
+ * import { ContextMenu } from "@primitiv-ui/react";
1255
+ *
1256
+ * <ContextMenu.Root>
1257
+ * <ContextMenu.Trigger>
1258
+ * <div className="canvas">Right-click anywhere</div>
1259
+ * </ContextMenu.Trigger>
1260
+ * <ContextMenu.Content>
1261
+ * <ContextMenu.Item onSelect={paste}>Paste</ContextMenu.Item>
1262
+ * <ContextMenu.Separator />
1263
+ * <ContextMenu.Item disabled>Archive</ContextMenu.Item>
1264
+ * </ContextMenu.Content>
1265
+ * </ContextMenu.Root>
1266
+ * ```
1267
+ *
1268
+ * @see {@link ContextMenuRoot} for state modes and reading direction.
1269
+ * @see {@link ContextMenuContent} for the popover, positioning, and keyboard model.
1270
+ * @see {@link ContextMenuCheckboxItem} and {@link ContextMenuRadioGroup} for stateful items.
1271
+ * @see {@link ContextMenuSub} for submenus.
1006
1272
  */
1007
1273
  const ContextMenuCompound: TContextMenuCompound = Object.assign(
1008
1274
  ContextMenuRoot,