@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.
- package/LICENSE +21 -0
- package/package.json +2 -1
- package/src/AccessibleIcon/AccessibleIcon.tsx +6 -2
- package/src/AccessibleIcon/__tests__/AccessibleIcon.test.tsx +1 -1
- package/src/AccessibleIcon/types.ts +4 -0
- package/src/Accordion/Accordion.tsx +34 -12
- package/src/Accordion/AccordionContext.ts +1 -1
- package/src/Accordion/__tests__/Accordion.reading-direction.test.tsx +1 -1
- package/src/Accordion/hooks/useAccordionItem.ts +1 -1
- package/src/Accordion/hooks/useAccordionRoot.ts +1 -1
- package/src/Accordion/hooks/useAccordionTrigger.ts +2 -2
- package/src/Accordion/index.ts +2 -1
- package/src/Accordion/types.ts +55 -13
- package/src/Alert/Alert.tsx +9 -2
- package/src/Alert/__tests__/Alert.test.tsx +1 -1
- package/src/Alert/types.ts +1 -0
- package/src/Avatar/Avatar.tsx +20 -7
- package/src/Avatar/AvatarContext.ts +12 -6
- package/src/Breadcrumb/Breadcrumb.tsx +32 -10
- package/src/Button/Button.tsx +5 -2
- package/src/Button/types.ts +4 -0
- package/src/Carousel/Carousel.tsx +30 -14
- package/src/Carousel/CarouselContext.ts +7 -3
- package/src/Carousel/__tests__/Carousel.asChild.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.auto-play.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.basic-rendering.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.controlled-state.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.error-handling.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.ids.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.imperative-api.test.tsx +2 -2
- package/src/Carousel/__tests__/Carousel.indicators.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.intersection-observer.test.tsx +2 -2
- package/src/Carousel/__tests__/Carousel.keyboard-navigation.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.play-pause.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.prev-next.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.reduced-motion.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.refresh-progress.test.tsx +2 -2
- package/src/Carousel/__tests__/Carousel.scroll-snap-change.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.scroll-sync.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.slides-per-move.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.slides-per-page.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.touch-interaction.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.transition-modes.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.translations.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.uncontrolled-state.test.tsx +1 -1
- package/src/Carousel/types.ts +8 -0
- package/src/Checkbox/Checkbox.tsx +11 -6
- package/src/Checkbox/CheckboxContext.ts +1 -1
- package/src/Checkbox/hooks/useCheckboxRoot.ts +1 -1
- package/src/Checkbox/index.ts +1 -0
- package/src/Checkbox/types.ts +30 -3
- package/src/CheckboxCard/CheckboxCard.tsx +13 -11
- package/src/CheckboxCard/CheckboxCardContext.ts +19 -6
- package/src/CheckboxCard/hooks/useCheckboxCardRoot.ts +2 -2
- package/src/CheckboxCard/types.ts +21 -5
- package/src/Collapsible/Collapsible.tsx +37 -21
- package/src/Collapsible/CollapsibleContext.ts +1 -1
- package/src/Collapsible/hooks/useCollapsibleRoot.ts +1 -1
- package/src/Collapsible/hooks/useCollapsibleTrigger.ts +1 -1
- package/src/Collapsible/index.ts +1 -0
- package/src/Collapsible/types.ts +45 -12
- package/src/ContextMenu/ContextMenu.tsx +60 -34
- package/src/ContextMenu/ContextMenuContext.ts +2 -2
- package/src/ContextMenu/ContextMenuSubContext.ts +1 -1
- package/src/ContextMenu/__tests__/ContextMenu.reading-direction.test.tsx +1 -1
- package/src/ContextMenu/index.ts +2 -1
- package/src/ContextMenu/types.ts +160 -17
- package/src/DirectionProvider/DirectionProvider.tsx +7 -1
- package/src/DirectionProvider/__tests__/DirectionProvider.test.tsx +1 -1
- package/src/DirectionProvider/types.ts +1 -0
- package/src/Divider/Divider.tsx +4 -1
- package/src/Divider/__tests__/Divider.test.tsx +1 -1
- package/src/Divider/index.ts +2 -1
- package/src/Divider/types.ts +5 -0
- package/src/Dropdown/Dropdown.tsx +60 -34
- package/src/Dropdown/DropdownContext.ts +2 -2
- package/src/Dropdown/DropdownSubContext.ts +1 -1
- package/src/Dropdown/__tests__/Dropdown.reading-direction.test.tsx +1 -1
- package/src/Dropdown/hooks/useDropdownContent.ts +1 -1
- package/src/Dropdown/hooks/useDropdownItem.ts +1 -1
- package/src/Dropdown/hooks/useDropdownRoot.ts +2 -2
- package/src/Dropdown/hooks/useDropdownTrigger.ts +1 -1
- package/src/Dropdown/index.ts +2 -1
- package/src/Dropdown/types.ts +153 -25
- package/src/EmptyState/EmptyState.tsx +34 -20
- package/src/EmptyState/__tests__/EmptyState.Actions.test.tsx +1 -1
- package/src/EmptyState/__tests__/EmptyState.Description.test.tsx +1 -1
- package/src/EmptyState/__tests__/EmptyState.Media.test.tsx +1 -1
- package/src/EmptyState/__tests__/EmptyState.Root.test.tsx +1 -1
- package/src/EmptyState/__tests__/EmptyState.Title.test.tsx +1 -1
- package/src/EmptyState/types.ts +2 -1
- package/src/Field/Field.tsx +24 -10
- package/src/Field/FieldContext.ts +1 -1
- package/src/Field/types.ts +4 -0
- package/src/Fieldset/Fieldset.tsx +26 -10
- package/src/Fieldset/types.ts +2 -0
- package/src/Input/Input.tsx +6 -3
- package/src/Input/__tests__/Input.field-integration.test.tsx +1 -1
- package/src/Input/types.ts +4 -0
- package/src/InputGroup/InputGroup.tsx +15 -8
- package/src/InputGroup/types.ts +9 -0
- package/src/MillerColumns/MillerColumns.tsx +28 -8
- package/src/MillerColumns/MillerColumnsContext.ts +1 -1
- package/src/MillerColumns/hooks/useMillerColumnsItem.ts +2 -2
- package/src/MillerColumns/hooks/useMillerColumnsRoot.ts +0 -0
- package/src/MillerColumns/index.ts +1 -1
- package/src/MillerColumns/types.ts +67 -14
- package/src/MillerColumns/useMillerColumnsSelection.ts +1 -1
- package/src/Modal/Modal.tsx +25 -11
- package/src/Modal/ModalContext.ts +14 -7
- package/src/Modal/hooks/useModalRoot.ts +1 -1
- package/src/Modal/hooks/useModalTrigger.ts +2 -2
- package/src/Modal/types.ts +51 -2
- package/src/Portal/Portal.tsx +3 -1
- package/src/Portal/types.ts +4 -0
- package/src/Progress/Progress.tsx +12 -7
- package/src/Progress/ProgressContext.ts +18 -6
- package/src/RadioCard/RadioCard.tsx +17 -11
- package/src/RadioCard/RadioCardContext.ts +17 -5
- package/src/RadioCard/RadioCardItemContext.ts +18 -5
- package/src/RadioCard/__tests__/RadioCard.reading-direction.test.tsx +1 -1
- package/src/RadioCard/hooks/useRadioCardRoot.ts +1 -1
- package/src/RadioCard/types.ts +24 -3
- package/src/RadioGroup/RadioGroup.tsx +17 -11
- package/src/RadioGroup/RadioGroupContext.ts +1 -1
- package/src/RadioGroup/RadioGroupItemContext.ts +1 -1
- package/src/RadioGroup/__tests__/RadioGroup.reading-direction.test.tsx +1 -1
- package/src/RadioGroup/hooks/useRadioGroupRoot.ts +1 -1
- package/src/RadioGroup/index.ts +1 -0
- package/src/RadioGroup/types.ts +34 -3
- package/src/Select/Select.tsx +23 -8
- package/src/Select/__tests__/Select.field-integration.test.tsx +1 -1
- package/src/Select/index.ts +1 -1
- package/src/Select/types.ts +18 -3
- package/src/SkipNav/SkipNav.tsx +7 -2
- package/src/SkipNav/__tests__/SkipNav.ids.test.tsx +1 -1
- package/src/Slider/Slider.tsx +26 -11
- package/src/Slider/SliderContext.ts +13 -6
- package/src/Slider/__tests__/Slider.reading-direction.test.tsx +1 -1
- package/src/Slider/hooks/useSliderRoot.ts +1 -1
- package/src/Slider/types.ts +12 -3
- package/src/Status/Status.tsx +9 -2
- package/src/Status/__tests__/Status.test.tsx +1 -1
- package/src/Status/types.ts +4 -0
- package/src/Switch/Switch.tsx +16 -6
- package/src/Switch/SwitchContext.ts +13 -5
- package/src/Switch/hooks/useSwitchRoot.ts +1 -1
- package/src/Switch/types.ts +24 -3
- package/src/Table/Table.tsx +51 -25
- package/src/Table/__tests__/Table.Body.test.tsx +1 -1
- package/src/Table/__tests__/Table.Caption.test.tsx +1 -1
- package/src/Table/__tests__/Table.Cell.test.tsx +1 -1
- package/src/Table/__tests__/Table.Footer.test.tsx +1 -1
- package/src/Table/__tests__/Table.Head.test.tsx +1 -1
- package/src/Table/__tests__/Table.Header.test.tsx +1 -1
- package/src/Table/__tests__/Table.Root.test.tsx +1 -1
- package/src/Table/__tests__/Table.Row.test.tsx +1 -1
- package/src/Table/__tests__/Table.ScrollArea.test.tsx +1 -1
- package/src/Table/index.ts +2 -1
- package/src/Tabs/Tabs.tsx +30 -10
- package/src/Tabs/TabsContext.ts +15 -7
- package/src/Tabs/__tests__/Tabs.asChild.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.basic-rendering.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.change-event-callbacks.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.controlled-state.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.error-handling.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.imperative-api.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.keyboard-interaction.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.lazy-mount.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.mouse-interaction.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.reading-direction.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.uncontrolled-state.test.tsx +1 -1
- package/src/Tabs/hooks/useTabsContent.ts +1 -1
- package/src/Tabs/hooks/useTabsRoot.ts +1 -1
- package/src/Tabs/hooks/useTabsTrigger.ts +1 -1
- package/src/Tabs/types.ts +35 -1
- package/src/Tabs/utils.ts +1 -1
- package/src/Textarea/Textarea.tsx +6 -3
- package/src/Textarea/__tests__/Textarea.field-integration.test.tsx +1 -1
- package/src/Textarea/types.ts +4 -0
- package/src/Toggle/Toggle.tsx +11 -4
- package/src/Toggle/types.ts +7 -3
- package/src/ToggleGroup/ToggleGroup.tsx +23 -13
- package/src/ToggleGroup/ToggleGroupContext.ts +1 -1
- package/src/ToggleGroup/__tests__/ToggleGroup.reading-direction.test.tsx +1 -1
- package/src/ToggleGroup/hooks/useToggleGroupRoot.ts +1 -1
- package/src/ToggleGroup/types.ts +45 -5
- package/src/Tooltip/Tooltip.tsx +46 -15
- package/src/Tooltip/TooltipContext.ts +1 -1
- package/src/Tooltip/hooks/useTooltipContent.ts +1 -1
- package/src/Tooltip/hooks/useTooltipRoot.ts +1 -1
- package/src/Tooltip/hooks/useTooltipTrigger.ts +1 -1
- package/src/Tooltip/index.ts +1 -0
- package/src/Tooltip/types.ts +50 -2
- package/src/Tree/Tree.tsx +58 -12
- package/src/Tree/TreeContext.ts +1 -1
- package/src/Tree/__tests__/Tree.selection-path.test.tsx +2 -2
- package/src/Tree/hooks/useTreeItemKeyboard.ts +1 -1
- package/src/Tree/hooks/useTreeRoot.ts +1 -1
- package/src/Tree/index.ts +1 -1
- package/src/Tree/types.ts +39 -7
- package/src/VisuallyHidden/VisuallyHidden.tsx +4 -2
- package/src/VisuallyHidden/__tests__/VisuallyHidden.test.tsx +1 -1
- package/src/VisuallyHidden/types.ts +4 -0
- package/src/index.ts +39 -38
- package/src/types.ts +1 -0
- 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
|
-
|
|
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,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", () => {
|
package/src/ContextMenu/index.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "./ContextMenu";
|
|
2
|
+
export * from "./types";
|