@primitiv-ui/react 0.1.0 → 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 (207) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +2 -1
  3. package/src/AccessibleIcon/AccessibleIcon.tsx +6 -2
  4. package/src/AccessibleIcon/__tests__/AccessibleIcon.test.tsx +1 -1
  5. package/src/AccessibleIcon/types.ts +4 -0
  6. package/src/Accordion/Accordion.tsx +34 -12
  7. package/src/Accordion/AccordionContext.ts +1 -1
  8. package/src/Accordion/__tests__/Accordion.reading-direction.test.tsx +1 -1
  9. package/src/Accordion/hooks/useAccordionItem.ts +1 -1
  10. package/src/Accordion/hooks/useAccordionRoot.ts +1 -1
  11. package/src/Accordion/hooks/useAccordionTrigger.ts +2 -2
  12. package/src/Accordion/index.ts +2 -1
  13. package/src/Accordion/types.ts +55 -13
  14. package/src/Alert/Alert.tsx +9 -2
  15. package/src/Alert/__tests__/Alert.test.tsx +1 -1
  16. package/src/Alert/types.ts +1 -0
  17. package/src/Avatar/Avatar.tsx +20 -7
  18. package/src/Avatar/AvatarContext.ts +12 -6
  19. package/src/Breadcrumb/Breadcrumb.tsx +32 -10
  20. package/src/Button/Button.tsx +5 -2
  21. package/src/Button/types.ts +4 -0
  22. package/src/Carousel/Carousel.tsx +30 -14
  23. package/src/Carousel/CarouselContext.ts +7 -3
  24. package/src/Carousel/__tests__/Carousel.asChild.test.tsx +1 -1
  25. package/src/Carousel/__tests__/Carousel.auto-play.test.tsx +1 -1
  26. package/src/Carousel/__tests__/Carousel.basic-rendering.test.tsx +1 -1
  27. package/src/Carousel/__tests__/Carousel.controlled-state.test.tsx +1 -1
  28. package/src/Carousel/__tests__/Carousel.error-handling.test.tsx +1 -1
  29. package/src/Carousel/__tests__/Carousel.ids.test.tsx +1 -1
  30. package/src/Carousel/__tests__/Carousel.imperative-api.test.tsx +2 -2
  31. package/src/Carousel/__tests__/Carousel.indicators.test.tsx +1 -1
  32. package/src/Carousel/__tests__/Carousel.intersection-observer.test.tsx +2 -2
  33. package/src/Carousel/__tests__/Carousel.keyboard-navigation.test.tsx +1 -1
  34. package/src/Carousel/__tests__/Carousel.play-pause.test.tsx +1 -1
  35. package/src/Carousel/__tests__/Carousel.prev-next.test.tsx +1 -1
  36. package/src/Carousel/__tests__/Carousel.reduced-motion.test.tsx +1 -1
  37. package/src/Carousel/__tests__/Carousel.refresh-progress.test.tsx +2 -2
  38. package/src/Carousel/__tests__/Carousel.scroll-snap-change.test.tsx +1 -1
  39. package/src/Carousel/__tests__/Carousel.scroll-sync.test.tsx +1 -1
  40. package/src/Carousel/__tests__/Carousel.slides-per-move.test.tsx +1 -1
  41. package/src/Carousel/__tests__/Carousel.slides-per-page.test.tsx +1 -1
  42. package/src/Carousel/__tests__/Carousel.touch-interaction.test.tsx +1 -1
  43. package/src/Carousel/__tests__/Carousel.transition-modes.test.tsx +1 -1
  44. package/src/Carousel/__tests__/Carousel.translations.test.tsx +1 -1
  45. package/src/Carousel/__tests__/Carousel.uncontrolled-state.test.tsx +1 -1
  46. package/src/Carousel/types.ts +8 -0
  47. package/src/Checkbox/Checkbox.tsx +11 -6
  48. package/src/Checkbox/CheckboxContext.ts +1 -1
  49. package/src/Checkbox/hooks/useCheckboxRoot.ts +1 -1
  50. package/src/Checkbox/index.ts +1 -0
  51. package/src/Checkbox/types.ts +30 -3
  52. package/src/CheckboxCard/CheckboxCard.tsx +13 -11
  53. package/src/CheckboxCard/CheckboxCardContext.ts +19 -6
  54. package/src/CheckboxCard/hooks/useCheckboxCardRoot.ts +2 -2
  55. package/src/CheckboxCard/types.ts +21 -5
  56. package/src/Collapsible/Collapsible.tsx +37 -21
  57. package/src/Collapsible/CollapsibleContext.ts +1 -1
  58. package/src/Collapsible/hooks/useCollapsibleRoot.ts +1 -1
  59. package/src/Collapsible/hooks/useCollapsibleTrigger.ts +1 -1
  60. package/src/Collapsible/index.ts +1 -0
  61. package/src/Collapsible/types.ts +45 -12
  62. package/src/ContextMenu/ContextMenu.tsx +60 -34
  63. package/src/ContextMenu/ContextMenuContext.ts +2 -2
  64. package/src/ContextMenu/ContextMenuSubContext.ts +1 -1
  65. package/src/ContextMenu/__tests__/ContextMenu.reading-direction.test.tsx +1 -1
  66. package/src/ContextMenu/index.ts +2 -1
  67. package/src/ContextMenu/types.ts +160 -17
  68. package/src/DirectionProvider/DirectionProvider.tsx +7 -1
  69. package/src/DirectionProvider/__tests__/DirectionProvider.test.tsx +1 -1
  70. package/src/DirectionProvider/types.ts +1 -0
  71. package/src/Divider/Divider.tsx +4 -1
  72. package/src/Divider/__tests__/Divider.test.tsx +1 -1
  73. package/src/Divider/index.ts +2 -1
  74. package/src/Divider/types.ts +5 -0
  75. package/src/Dropdown/Dropdown.tsx +60 -34
  76. package/src/Dropdown/DropdownContext.ts +2 -2
  77. package/src/Dropdown/DropdownSubContext.ts +1 -1
  78. package/src/Dropdown/__tests__/Dropdown.reading-direction.test.tsx +1 -1
  79. package/src/Dropdown/hooks/useDropdownContent.ts +1 -1
  80. package/src/Dropdown/hooks/useDropdownItem.ts +1 -1
  81. package/src/Dropdown/hooks/useDropdownRoot.ts +2 -2
  82. package/src/Dropdown/hooks/useDropdownTrigger.ts +1 -1
  83. package/src/Dropdown/index.ts +2 -1
  84. package/src/Dropdown/types.ts +153 -25
  85. package/src/EmptyState/EmptyState.tsx +34 -20
  86. package/src/EmptyState/__tests__/EmptyState.Actions.test.tsx +1 -1
  87. package/src/EmptyState/__tests__/EmptyState.Description.test.tsx +1 -1
  88. package/src/EmptyState/__tests__/EmptyState.Media.test.tsx +1 -1
  89. package/src/EmptyState/__tests__/EmptyState.Root.test.tsx +1 -1
  90. package/src/EmptyState/__tests__/EmptyState.Title.test.tsx +1 -1
  91. package/src/EmptyState/types.ts +2 -1
  92. package/src/Field/Field.tsx +24 -10
  93. package/src/Field/FieldContext.ts +1 -1
  94. package/src/Field/types.ts +4 -0
  95. package/src/Fieldset/Fieldset.tsx +26 -10
  96. package/src/Fieldset/types.ts +2 -0
  97. package/src/Input/Input.tsx +6 -3
  98. package/src/Input/__tests__/Input.field-integration.test.tsx +1 -1
  99. package/src/Input/types.ts +4 -0
  100. package/src/InputGroup/InputGroup.tsx +15 -8
  101. package/src/InputGroup/types.ts +9 -0
  102. package/src/MillerColumns/MillerColumns.tsx +28 -8
  103. package/src/MillerColumns/MillerColumnsContext.ts +1 -1
  104. package/src/MillerColumns/hooks/useMillerColumnsItem.ts +2 -2
  105. package/src/MillerColumns/hooks/useMillerColumnsRoot.ts +0 -0
  106. package/src/MillerColumns/index.ts +1 -1
  107. package/src/MillerColumns/types.ts +67 -14
  108. package/src/MillerColumns/useMillerColumnsSelection.ts +1 -1
  109. package/src/Modal/Modal.tsx +25 -11
  110. package/src/Modal/ModalContext.ts +14 -7
  111. package/src/Modal/hooks/useModalRoot.ts +1 -1
  112. package/src/Modal/hooks/useModalTrigger.ts +2 -2
  113. package/src/Modal/types.ts +51 -2
  114. package/src/Portal/Portal.tsx +3 -1
  115. package/src/Portal/types.ts +4 -0
  116. package/src/Progress/Progress.tsx +12 -7
  117. package/src/Progress/ProgressContext.ts +18 -6
  118. package/src/RadioCard/RadioCard.tsx +17 -11
  119. package/src/RadioCard/RadioCardContext.ts +17 -5
  120. package/src/RadioCard/RadioCardItemContext.ts +18 -5
  121. package/src/RadioCard/__tests__/RadioCard.reading-direction.test.tsx +1 -1
  122. package/src/RadioCard/hooks/useRadioCardRoot.ts +1 -1
  123. package/src/RadioCard/types.ts +24 -3
  124. package/src/RadioGroup/RadioGroup.tsx +17 -11
  125. package/src/RadioGroup/RadioGroupContext.ts +1 -1
  126. package/src/RadioGroup/RadioGroupItemContext.ts +1 -1
  127. package/src/RadioGroup/__tests__/RadioGroup.reading-direction.test.tsx +1 -1
  128. package/src/RadioGroup/hooks/useRadioGroupRoot.ts +1 -1
  129. package/src/RadioGroup/index.ts +1 -0
  130. package/src/RadioGroup/types.ts +34 -3
  131. package/src/Select/Select.tsx +23 -8
  132. package/src/Select/__tests__/Select.field-integration.test.tsx +1 -1
  133. package/src/Select/index.ts +1 -1
  134. package/src/Select/types.ts +18 -3
  135. package/src/SkipNav/SkipNav.tsx +7 -2
  136. package/src/SkipNav/__tests__/SkipNav.ids.test.tsx +1 -1
  137. package/src/Slider/Slider.tsx +26 -11
  138. package/src/Slider/SliderContext.ts +13 -6
  139. package/src/Slider/__tests__/Slider.reading-direction.test.tsx +1 -1
  140. package/src/Slider/hooks/useSliderRoot.ts +1 -1
  141. package/src/Slider/types.ts +12 -3
  142. package/src/Status/Status.tsx +9 -2
  143. package/src/Status/__tests__/Status.test.tsx +1 -1
  144. package/src/Status/types.ts +4 -0
  145. package/src/Switch/Switch.tsx +16 -6
  146. package/src/Switch/SwitchContext.ts +13 -5
  147. package/src/Switch/hooks/useSwitchRoot.ts +1 -1
  148. package/src/Switch/types.ts +24 -3
  149. package/src/Table/Table.tsx +51 -25
  150. package/src/Table/__tests__/Table.Body.test.tsx +1 -1
  151. package/src/Table/__tests__/Table.Caption.test.tsx +1 -1
  152. package/src/Table/__tests__/Table.Cell.test.tsx +1 -1
  153. package/src/Table/__tests__/Table.Footer.test.tsx +1 -1
  154. package/src/Table/__tests__/Table.Head.test.tsx +1 -1
  155. package/src/Table/__tests__/Table.Header.test.tsx +1 -1
  156. package/src/Table/__tests__/Table.Root.test.tsx +1 -1
  157. package/src/Table/__tests__/Table.Row.test.tsx +1 -1
  158. package/src/Table/__tests__/Table.ScrollArea.test.tsx +1 -1
  159. package/src/Table/index.ts +2 -1
  160. package/src/Tabs/Tabs.tsx +30 -10
  161. package/src/Tabs/TabsContext.ts +15 -7
  162. package/src/Tabs/__tests__/Tabs.asChild.test.tsx +1 -1
  163. package/src/Tabs/__tests__/Tabs.basic-rendering.test.tsx +1 -1
  164. package/src/Tabs/__tests__/Tabs.change-event-callbacks.test.tsx +1 -1
  165. package/src/Tabs/__tests__/Tabs.controlled-state.test.tsx +1 -1
  166. package/src/Tabs/__tests__/Tabs.error-handling.test.tsx +1 -1
  167. package/src/Tabs/__tests__/Tabs.imperative-api.test.tsx +1 -1
  168. package/src/Tabs/__tests__/Tabs.keyboard-interaction.test.tsx +1 -1
  169. package/src/Tabs/__tests__/Tabs.lazy-mount.test.tsx +1 -1
  170. package/src/Tabs/__tests__/Tabs.mouse-interaction.test.tsx +1 -1
  171. package/src/Tabs/__tests__/Tabs.reading-direction.test.tsx +1 -1
  172. package/src/Tabs/__tests__/Tabs.uncontrolled-state.test.tsx +1 -1
  173. package/src/Tabs/hooks/useTabsContent.ts +1 -1
  174. package/src/Tabs/hooks/useTabsRoot.ts +1 -1
  175. package/src/Tabs/hooks/useTabsTrigger.ts +1 -1
  176. package/src/Tabs/types.ts +35 -1
  177. package/src/Tabs/utils.ts +1 -1
  178. package/src/Textarea/Textarea.tsx +6 -3
  179. package/src/Textarea/__tests__/Textarea.field-integration.test.tsx +1 -1
  180. package/src/Textarea/types.ts +4 -0
  181. package/src/Toggle/Toggle.tsx +11 -4
  182. package/src/Toggle/types.ts +7 -3
  183. package/src/ToggleGroup/ToggleGroup.tsx +23 -13
  184. package/src/ToggleGroup/ToggleGroupContext.ts +1 -1
  185. package/src/ToggleGroup/__tests__/ToggleGroup.reading-direction.test.tsx +1 -1
  186. package/src/ToggleGroup/hooks/useToggleGroupRoot.ts +1 -1
  187. package/src/ToggleGroup/types.ts +45 -5
  188. package/src/Tooltip/Tooltip.tsx +46 -15
  189. package/src/Tooltip/TooltipContext.ts +1 -1
  190. package/src/Tooltip/hooks/useTooltipContent.ts +1 -1
  191. package/src/Tooltip/hooks/useTooltipRoot.ts +1 -1
  192. package/src/Tooltip/hooks/useTooltipTrigger.ts +1 -1
  193. package/src/Tooltip/index.ts +1 -0
  194. package/src/Tooltip/types.ts +50 -2
  195. package/src/Tree/Tree.tsx +58 -12
  196. package/src/Tree/TreeContext.ts +1 -1
  197. package/src/Tree/__tests__/Tree.selection-path.test.tsx +2 -2
  198. package/src/Tree/hooks/useTreeItemKeyboard.ts +1 -1
  199. package/src/Tree/hooks/useTreeRoot.ts +1 -1
  200. package/src/Tree/index.ts +1 -1
  201. package/src/Tree/types.ts +39 -7
  202. package/src/VisuallyHidden/VisuallyHidden.tsx +4 -2
  203. package/src/VisuallyHidden/__tests__/VisuallyHidden.test.tsx +1 -1
  204. package/src/VisuallyHidden/types.ts +4 -0
  205. package/src/index.ts +39 -38
  206. package/src/types.ts +1 -0
  207. package/src/utils/createStrictContext.ts +9 -5
@@ -7,12 +7,13 @@ import {
7
7
  useRef,
8
8
  useState,
9
9
  } from "react";
10
+ import type { ReactElement } from "react";
10
11
 
11
- import { useCheckboxRoot } from "../Checkbox/hooks";
12
- import { useDirection } from "../DirectionProvider";
13
- import { useRadioGroupRoot } from "../RadioGroup/hooks";
14
- import { useControllableState } from "../hooks";
15
- import { Slot, composeEventHandlers } from "../Slot";
12
+ import { useCheckboxRoot } from "../Checkbox/hooks/index.ts";
13
+ import { useDirection } from "../DirectionProvider/index.ts";
14
+ import { useRadioGroupRoot } from "../RadioGroup/hooks/index.ts";
15
+ import { useControllableState } from "../hooks/index.ts";
16
+ import { Slot, composeEventHandlers } from "../Slot/index.ts";
16
17
 
17
18
  import {
18
19
  ContextMenuContext,
@@ -67,13 +68,13 @@ import { MENUITEM_SELECTOR, TYPEAHEAD_RESET_MS } from "./constants";
67
68
  * keys (`ArrowRight` ↔ `ArrowLeft`). When omitted, the component reads
68
69
  * the inherited {@link DirectionProvider} value, falling back to `"ltr"`.
69
70
  */
70
- function ContextMenuRoot({
71
+ export function ContextMenuRoot({
71
72
  defaultOpen = false,
72
73
  open: controlledOpen,
73
74
  onOpenChange,
74
75
  dir,
75
76
  children,
76
- }: ContextMenuRootProps) {
77
+ }: ContextMenuRootProps): ReactElement {
77
78
  const contentId = useId();
78
79
  const triggerRef = useRef<HTMLElement | null>(null);
79
80
  const [position, setPosition] = useState<ContextMenuPosition | null>(null);
@@ -118,6 +119,7 @@ function ContextMenuRoot({
118
119
  );
119
120
  }
120
121
 
122
+ /** @internal */
121
123
  ContextMenuRoot.displayName = "ContextMenuRoot";
122
124
 
123
125
  /**
@@ -140,13 +142,13 @@ function useCloseSiblingSub() {
140
142
  * the native menu is suppressed and the ContextMenu opens, positioned at
141
143
  * the pointer.
142
144
  */
143
- function ContextMenuTrigger({
145
+ export function ContextMenuTrigger({
144
146
  children,
145
147
  onContextMenu,
146
148
  asChild = false,
147
149
  disabled,
148
150
  ...rest
149
- }: ContextMenuTriggerProps) {
151
+ }: ContextMenuTriggerProps): ReactElement {
150
152
  const { setOpen, setPosition, triggerRef } = useContextMenuContext();
151
153
 
152
154
  const handleContextMenu = (event: React.MouseEvent<HTMLElement>) => {
@@ -171,6 +173,7 @@ function ContextMenuTrigger({
171
173
  return <span {...triggerProps}>{children}</span>;
172
174
  }
173
175
 
176
+ /** @internal */
174
177
  ContextMenuTrigger.displayName = "ContextMenuTrigger";
175
178
 
176
179
  /**
@@ -195,13 +198,13 @@ ContextMenuTrigger.displayName = "ContextMenuTrigger";
195
198
  * that flip the menu to the opposite side when it would overflow the
196
199
  * viewport. Pass `asChild` to render any element with menu semantics.
197
200
  */
198
- function ContextMenuContent({
201
+ export function ContextMenuContent({
199
202
  children,
200
203
  style,
201
204
  onKeyDown,
202
205
  asChild = false,
203
206
  ...rest
204
- }: ContextMenuContentProps) {
207
+ }: ContextMenuContentProps): ReactElement {
205
208
  const { open, setOpen, position, contentId, triggerRef } =
206
209
  useContextMenuContext();
207
210
  const menuRef = useRef<HTMLMenuElement | null>(null);
@@ -373,6 +376,7 @@ function ContextMenuContent({
373
376
  );
374
377
  }
375
378
 
379
+ /** @internal */
376
380
  ContextMenuContent.displayName = "ContextMenuContent";
377
381
 
378
382
  /**
@@ -386,14 +390,14 @@ ContextMenuContent.displayName = "ContextMenuContent";
386
390
  *
387
391
  * Disabled items receive `aria-disabled="true"` and no-op on activation.
388
392
  */
389
- function ContextMenuItem({
393
+ export function ContextMenuItem({
390
394
  children,
391
395
  onClick,
392
396
  onSelect,
393
397
  disabled,
394
398
  asChild = false,
395
399
  ...rest
396
- }: ContextMenuItemProps) {
400
+ }: ContextMenuItemProps): ReactElement {
397
401
  const { setOpen } = useContextMenuContext();
398
402
  const closeSiblingSub = useCloseSiblingSub();
399
403
  const [highlighted, setHighlighted] = useState(false);
@@ -430,6 +434,7 @@ function ContextMenuItem({
430
434
  return <li {...itemProps}>{children}</li>;
431
435
  }
432
436
 
437
+ /** @internal */
433
438
  ContextMenuItem.displayName = "ContextMenuItem";
434
439
 
435
440
  /**
@@ -437,11 +442,11 @@ ContextMenuItem.displayName = "ContextMenuItem";
437
442
  * by default. Non-interactive — skipped by focus, arrow navigation, and
438
443
  * typeahead.
439
444
  */
440
- function ContextMenuSeparator({
445
+ export function ContextMenuSeparator({
441
446
  asChild = false,
442
447
  children,
443
448
  ...rest
444
- }: ContextMenuSeparatorProps) {
449
+ }: ContextMenuSeparatorProps): ReactElement {
445
450
  const separatorProps = { ...rest, role: "separator" as const };
446
451
 
447
452
  if (asChild) {
@@ -451,6 +456,7 @@ function ContextMenuSeparator({
451
456
  return <li {...separatorProps} />;
452
457
  }
453
458
 
459
+ /** @internal */
454
460
  ContextMenuSeparator.displayName = "ContextMenuSeparator";
455
461
 
456
462
  /**
@@ -461,11 +467,11 @@ ContextMenuSeparator.displayName = "ContextMenuSeparator";
461
467
  * Generates a stable id for its accompanying {@link ContextMenuLabel |
462
468
  * `ContextMenu.Label`}, wired automatically via `aria-labelledby`.
463
469
  */
464
- function ContextMenuGroup({
470
+ export function ContextMenuGroup({
465
471
  children,
466
472
  asChild = false,
467
473
  ...rest
468
- }: ContextMenuGroupProps) {
474
+ }: ContextMenuGroupProps): ReactElement {
469
475
  const labelId = useId();
470
476
  const contextValue = useMemo(() => ({ labelId }), [labelId]);
471
477
  const groupProps = {
@@ -487,6 +493,7 @@ function ContextMenuGroup({
487
493
  );
488
494
  }
489
495
 
496
+ /** @internal */
490
497
  ContextMenuGroup.displayName = "ContextMenuGroup";
491
498
 
492
499
  /**
@@ -496,12 +503,12 @@ ContextMenuGroup.displayName = "ContextMenuGroup";
496
503
  * consumers don't need to thread ids manually. A caller-supplied `id` takes
497
504
  * precedence over the auto-generated one.
498
505
  */
499
- function ContextMenuLabel({
506
+ export function ContextMenuLabel({
500
507
  id,
501
508
  children,
502
509
  asChild = false,
503
510
  ...rest
504
- }: ContextMenuLabelProps) {
511
+ }: ContextMenuLabelProps): ReactElement {
505
512
  const group = useContext(ContextMenuGroupContext);
506
513
  const labelProps = { ...rest, id: id ?? group?.labelId };
507
514
 
@@ -512,6 +519,7 @@ function ContextMenuLabel({
512
519
  return <li {...labelProps}>{children}</li>;
513
520
  }
514
521
 
522
+ /** @internal */
515
523
  ContextMenuLabel.displayName = "ContextMenuLabel";
516
524
 
517
525
  /**
@@ -526,7 +534,7 @@ ContextMenuLabel.displayName = "ContextMenuLabel";
526
534
  *
527
535
  * Disabled items receive `aria-disabled="true"` and no-op on activation.
528
536
  */
529
- function ContextMenuCheckboxItem({
537
+ export function ContextMenuCheckboxItem({
530
538
  children,
531
539
  onClick,
532
540
  onSelect,
@@ -536,7 +544,7 @@ function ContextMenuCheckboxItem({
536
544
  onCheckedChange,
537
545
  asChild = false,
538
546
  ...rest
539
- }: ContextMenuCheckboxItemProps) {
547
+ }: ContextMenuCheckboxItemProps): ReactElement {
540
548
  const { setOpen } = useContextMenuContext();
541
549
  const closeSiblingSub = useCloseSiblingSub();
542
550
  const [highlighted, setHighlighted] = useState(false);
@@ -589,6 +597,7 @@ function ContextMenuCheckboxItem({
589
597
  );
590
598
  }
591
599
 
600
+ /** @internal */
592
601
  ContextMenuCheckboxItem.displayName = "ContextMenuCheckboxItem";
593
602
 
594
603
  /**
@@ -604,12 +613,12 @@ ContextMenuCheckboxItem.displayName = "ContextMenuCheckboxItem";
604
613
  * {@link ContextMenuItemIndicatorProps.forceMount | `forceMount`} to keep
605
614
  * the DOM node mounted in both states for animation use cases.
606
615
  */
607
- function ContextMenuItemIndicator({
616
+ export function ContextMenuItemIndicator({
608
617
  children,
609
618
  asChild = false,
610
619
  forceMount = false,
611
620
  ...rest
612
- }: ContextMenuItemIndicatorProps) {
621
+ }: ContextMenuItemIndicatorProps): ReactElement | null {
613
622
  const context = useContext(ContextMenuItemIndicatorContext);
614
623
  if (!context) {
615
624
  throw new Error(
@@ -636,6 +645,7 @@ function ContextMenuItemIndicator({
636
645
  return <span {...indicatorProps}>{children}</span>;
637
646
  }
638
647
 
648
+ /** @internal */
639
649
  ContextMenuItemIndicator.displayName = "ContextMenuItemIndicator";
640
650
 
641
651
  /**
@@ -643,14 +653,14 @@ ContextMenuItemIndicator.displayName = "ContextMenuItemIndicator";
643
653
  * {@link ContextMenuRadioItem | `ContextMenu.RadioItem`} elements. Renders a
644
654
  * `<li role="group">` wrapping `<ul role="none">`.
645
655
  */
646
- function ContextMenuRadioGroup({
656
+ export function ContextMenuRadioGroup({
647
657
  defaultValue,
648
658
  value: controlledValue,
649
659
  onValueChange,
650
660
  children,
651
661
  asChild = false,
652
662
  ...rest
653
- }: ContextMenuRadioGroupProps) {
663
+ }: ContextMenuRadioGroupProps): ReactElement {
654
664
  const { value, select } = useRadioGroupRoot({
655
665
  defaultValue,
656
666
  value: controlledValue,
@@ -672,6 +682,7 @@ function ContextMenuRadioGroup({
672
682
  );
673
683
  }
674
684
 
685
+ /** @internal */
675
686
  ContextMenuRadioGroup.displayName = "ContextMenuRadioGroup";
676
687
 
677
688
  /**
@@ -686,7 +697,7 @@ ContextMenuRadioGroup.displayName = "ContextMenuRadioGroup";
686
697
  * {@link ContextMenuRadioItemProps.onSelect | `onSelect`} with a cancellable
687
698
  * `Event`. Call `event.preventDefault()` to keep the menu open.
688
699
  */
689
- function ContextMenuRadioItem({
700
+ export function ContextMenuRadioItem({
690
701
  children,
691
702
  onClick,
692
703
  onSelect,
@@ -694,7 +705,7 @@ function ContextMenuRadioItem({
694
705
  value: itemValue,
695
706
  asChild = false,
696
707
  ...rest
697
- }: ContextMenuRadioItemProps) {
708
+ }: ContextMenuRadioItemProps): ReactElement {
698
709
  const { setOpen } = useContextMenuContext();
699
710
  const closeSiblingSub = useCloseSiblingSub();
700
711
  const [highlighted, setHighlighted] = useState(false);
@@ -747,6 +758,7 @@ function ContextMenuRadioItem({
747
758
  );
748
759
  }
749
760
 
761
+ /** @internal */
750
762
  ContextMenuRadioItem.displayName = "ContextMenuRadioItem";
751
763
 
752
764
  /**
@@ -756,12 +768,12 @@ ContextMenuRadioItem.displayName = "ContextMenuRadioItem";
756
768
  * menu. Supports uncontrolled (`defaultOpen`) and controlled (`open` +
757
769
  * `onOpenChange`) modes.
758
770
  */
759
- function ContextMenuSub({
771
+ export function ContextMenuSub({
760
772
  defaultOpen,
761
773
  open: controlledOpen,
762
774
  onOpenChange,
763
775
  children,
764
- }: ContextMenuSubProps) {
776
+ }: ContextMenuSubProps): ReactElement {
765
777
  const contentId = useId();
766
778
  const triggerRef = useRef<HTMLLIElement | null>(null);
767
779
  const [open, setOpenBase] = useControllableState<boolean>(
@@ -812,6 +824,7 @@ function ContextMenuSub({
812
824
  );
813
825
  }
814
826
 
827
+ /** @internal */
815
828
  ContextMenuSub.displayName = "ContextMenuSub";
816
829
 
817
830
  /**
@@ -827,14 +840,14 @@ ContextMenuSub.displayName = "ContextMenuSub";
827
840
  * `ArrowRight` in `"ltr"`, `ArrowLeft` in `"rtl"`. Disabled triggers
828
841
  * ignore both click and the open arrow key.
829
842
  */
830
- function ContextMenuSubTrigger({
843
+ export function ContextMenuSubTrigger({
831
844
  children,
832
845
  onClick,
833
846
  onKeyDown,
834
847
  disabled,
835
848
  asChild = false,
836
849
  ...rest
837
- }: ContextMenuSubTriggerProps) {
850
+ }: ContextMenuSubTriggerProps): ReactElement {
838
851
  const sub = useContextMenuSubContext();
839
852
  const { dir } = useContextMenuContext();
840
853
  const openKey = dir === "rtl" ? "ArrowLeft" : "ArrowRight";
@@ -878,6 +891,7 @@ function ContextMenuSubTrigger({
878
891
  return <li {...subTriggerProps}>{children}</li>;
879
892
  }
880
893
 
894
+ /** @internal */
881
895
  ContextMenuSubTrigger.displayName = "ContextMenuSubTrigger";
882
896
 
883
897
  /**
@@ -889,12 +903,12 @@ ContextMenuSubTrigger.displayName = "ContextMenuSubTrigger";
889
903
  * key closes the submenu and returns focus to the SubTrigger —
890
904
  * `ArrowLeft` in `"ltr"`, `ArrowRight` in `"rtl"`.
891
905
  */
892
- function ContextMenuSubContent({
906
+ export function ContextMenuSubContent({
893
907
  children,
894
908
  onKeyDown,
895
909
  asChild = false,
896
910
  ...rest
897
- }: ContextMenuSubContentProps) {
911
+ }: ContextMenuSubContentProps): ReactElement {
898
912
  const sub = useContextMenuSubContext();
899
913
  const { dir } = useContextMenuContext();
900
914
  const closeKey = dir === "rtl" ? "ArrowRight" : "ArrowLeft";
@@ -960,9 +974,11 @@ function ContextMenuSubContent({
960
974
  );
961
975
  }
962
976
 
977
+ /** @internal */
963
978
  ContextMenuSubContent.displayName = "ContextMenuSubContent";
964
979
 
965
- type TContextMenuCompound = typeof ContextMenuRoot & {
980
+ /** Type of the {@link ContextMenu} compound: the root callable plus its attached sub-components. */
981
+ export type TContextMenuCompound = typeof ContextMenuRoot & {
966
982
  Root: typeof ContextMenuRoot;
967
983
  Trigger: typeof ContextMenuTrigger;
968
984
  Content: typeof ContextMenuContent;
@@ -979,6 +995,15 @@ type TContextMenuCompound = typeof ContextMenuRoot & {
979
995
  SubContent: typeof ContextMenuSubContent;
980
996
  };
981
997
 
998
+ /**
999
+ * Headless, accessible **ContextMenu** — a compound component implementing the
1000
+ * [WAI-ARIA menu pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menu/) opened
1001
+ * by a right-click (or long-press) on its trigger, with submenus, checkbox and
1002
+ * radio items, groups, labels and separators. Zero styles ship.
1003
+ *
1004
+ * The default export is the `Root`; sub-components are attached as static
1005
+ * properties (`ContextMenu.Trigger`, `ContextMenu.Content`, …).
1006
+ */
982
1007
  const ContextMenuCompound: TContextMenuCompound = Object.assign(
983
1008
  ContextMenuRoot,
984
1009
  {
@@ -999,6 +1024,7 @@ const ContextMenuCompound: TContextMenuCompound = Object.assign(
999
1024
  },
1000
1025
  );
1001
1026
 
1027
+ /** @internal */
1002
1028
  ContextMenuCompound.displayName = "ContextMenu";
1003
1029
 
1004
1030
  export { ContextMenuCompound as ContextMenu };
@@ -1,7 +1,7 @@
1
1
  import { RefObject } from "react";
2
2
 
3
- import { Direction } from "../DirectionProvider";
4
- import { createStrictContext } from "../utils";
3
+ import { Direction } from "../DirectionProvider/index.ts";
4
+ import { createStrictContext } from "../utils/index.ts";
5
5
 
6
6
  export type ContextMenuPosition = { x: number; y: number };
7
7
 
@@ -1,6 +1,6 @@
1
1
  import { RefObject } from "react";
2
2
 
3
- import { createStrictContext } from "../utils";
3
+ import { createStrictContext } from "../utils/index.ts";
4
4
 
5
5
  export type ContextMenuSubContextValue = {
6
6
  open: boolean;
@@ -1,7 +1,7 @@
1
1
  import { render, screen } from "@testing-library/react";
2
2
  import userEvent from "@testing-library/user-event";
3
3
 
4
- import { DirectionProvider } from "../../DirectionProvider";
4
+ import { DirectionProvider } from "../../DirectionProvider/index.ts";
5
5
  import { ContextMenu } from "../ContextMenu";
6
6
 
7
7
  describe("ContextMenu reading direction", () => {
@@ -1 +1,2 @@
1
- export { ContextMenu } from "./ContextMenu";
1
+ export * from "./ContextMenu";
2
+ export * from "./types";