@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
package/src/Dropdown/types.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode, Ref } from "react";
|
|
2
2
|
|
|
3
3
|
import { CheckedState } from "../Checkbox/types";
|
|
4
|
-
import { Direction } from "../DirectionProvider";
|
|
4
|
+
import { Direction } from "../DirectionProvider/index.ts";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Shared base for both {@link DropdownRootProps} variants — `children` plus
|
|
8
|
+
* the reading-direction control.
|
|
9
|
+
*/
|
|
10
|
+
export type DropdownRootBaseProps = {
|
|
7
11
|
children?: ReactNode;
|
|
8
12
|
/**
|
|
9
13
|
* Reading direction for the menu. Affects which arrow key opens / closes
|
|
@@ -14,22 +18,42 @@ type DropdownRootBaseProps = {
|
|
|
14
18
|
dir?: Direction;
|
|
15
19
|
};
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Uncontrolled variant of {@link DropdownRootProps}: the component owns the
|
|
23
|
+
* open state. Pass `defaultOpen` (or omit it); `onOpenChange` is optional
|
|
24
|
+
* and `open` is forbidden.
|
|
25
|
+
*/
|
|
26
|
+
export type DropdownRootUncontrolledProps = DropdownRootBaseProps & {
|
|
18
27
|
defaultOpen?: boolean;
|
|
19
28
|
open?: never;
|
|
20
29
|
onOpenChange?: (open: boolean) => void;
|
|
21
30
|
};
|
|
22
31
|
|
|
23
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Controlled variant of {@link DropdownRootProps}: the parent owns the open
|
|
34
|
+
* state. Pass `open` and `onOpenChange` together; `defaultOpen` is
|
|
35
|
+
* forbidden.
|
|
36
|
+
*/
|
|
37
|
+
export type DropdownRootControlledProps = DropdownRootBaseProps & {
|
|
24
38
|
defaultOpen?: never;
|
|
25
39
|
open: boolean;
|
|
26
40
|
onOpenChange: (open: boolean) => void;
|
|
27
41
|
};
|
|
28
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Props for {@link Dropdown.Root} — the controlled/uncontrolled discriminated
|
|
45
|
+
* union pairing {@link DropdownRootUncontrolledProps} with
|
|
46
|
+
* {@link DropdownRootControlledProps}, plus the shared `children` and `dir`.
|
|
47
|
+
*/
|
|
29
48
|
export type DropdownRootProps =
|
|
30
49
|
| DropdownRootUncontrolledProps
|
|
31
50
|
| DropdownRootControlledProps;
|
|
32
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Props for {@link Dropdown.Trigger} — the button that opens the menu. Extends
|
|
54
|
+
* the native `<button>` props (minus the ARIA attributes Dropdown owns) and
|
|
55
|
+
* adds `asChild` for rendering a custom element.
|
|
56
|
+
*/
|
|
33
57
|
export type DropdownTriggerProps = Omit<
|
|
34
58
|
ComponentProps<"button">,
|
|
35
59
|
"aria-haspopup" | "aria-expanded" | "aria-controls"
|
|
@@ -39,6 +63,11 @@ export type DropdownTriggerProps = Omit<
|
|
|
39
63
|
asChild?: boolean;
|
|
40
64
|
};
|
|
41
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Props for {@link Dropdown.Content} — the popover menu surface. Extends the
|
|
68
|
+
* native `<menu>` props (minus the `role`/`popover`/`id` Dropdown manages) and
|
|
69
|
+
* adds `asChild` for rendering a custom element.
|
|
70
|
+
*/
|
|
42
71
|
export type DropdownContentProps = Omit<
|
|
43
72
|
ComponentProps<"menu">,
|
|
44
73
|
"role" | "popover" | "id"
|
|
@@ -48,6 +77,11 @@ export type DropdownContentProps = Omit<
|
|
|
48
77
|
asChild?: boolean;
|
|
49
78
|
};
|
|
50
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Props for {@link Dropdown.Item} — a selectable menu item. Extends the native
|
|
82
|
+
* `<li>` props and adds `disabled`, `asChild`, and an `onSelect` callback that
|
|
83
|
+
* fires on activation (click, Enter, or Space).
|
|
84
|
+
*/
|
|
51
85
|
export type DropdownItemProps = Omit<
|
|
52
86
|
ComponentProps<"li">,
|
|
53
87
|
"role" | "tabIndex" | "onSelect"
|
|
@@ -64,12 +98,21 @@ export type DropdownItemProps = Omit<
|
|
|
64
98
|
onSelect?: (event: Event) => void;
|
|
65
99
|
};
|
|
66
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Props for {@link Dropdown.Separator} — a non-interactive divider between
|
|
103
|
+
* groups of items. Extends the native `<li>` props and adds `asChild`.
|
|
104
|
+
*/
|
|
67
105
|
export type DropdownSeparatorProps = Omit<ComponentProps<"li">, "role"> & {
|
|
68
106
|
children?: ReactNode;
|
|
69
107
|
ref?: Ref<HTMLLIElement>;
|
|
70
108
|
asChild?: boolean;
|
|
71
109
|
};
|
|
72
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Props for {@link Dropdown.ItemIndicator} — the check/dot rendered inside a
|
|
113
|
+
* checkbox or radio item. Extends the native `<span>` props and adds
|
|
114
|
+
* `forceMount` to keep it mounted while unchecked for enter/exit animation.
|
|
115
|
+
*/
|
|
73
116
|
export type DropdownItemIndicatorProps = ComponentProps<"span"> & {
|
|
74
117
|
children?: ReactNode;
|
|
75
118
|
ref?: Ref<HTMLSpanElement>;
|
|
@@ -83,19 +126,31 @@ export type DropdownItemIndicatorProps = ComponentProps<"span"> & {
|
|
|
83
126
|
forceMount?: boolean;
|
|
84
127
|
};
|
|
85
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Props for {@link Dropdown.Group} — a labelled grouping of related items.
|
|
131
|
+
* Extends the native `<li>` props and adds `asChild`.
|
|
132
|
+
*/
|
|
86
133
|
export type DropdownGroupProps = Omit<ComponentProps<"li">, "role"> & {
|
|
87
134
|
children?: ReactNode;
|
|
88
135
|
ref?: Ref<HTMLLIElement>;
|
|
89
136
|
asChild?: boolean;
|
|
90
137
|
};
|
|
91
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Props for {@link Dropdown.Label} — an accessible label for a
|
|
141
|
+
* {@link Dropdown.Group}. Extends the native `<li>` props and adds `asChild`.
|
|
142
|
+
*/
|
|
92
143
|
export type DropdownLabelProps = ComponentProps<"li"> & {
|
|
93
144
|
children?: ReactNode;
|
|
94
145
|
ref?: Ref<HTMLLIElement>;
|
|
95
146
|
asChild?: boolean;
|
|
96
147
|
};
|
|
97
148
|
|
|
98
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Shared base for both {@link DropdownCheckboxItemProps} variants — the native
|
|
151
|
+
* `<li>` props plus `disabled`, `asChild`, and the `onSelect` callback.
|
|
152
|
+
*/
|
|
153
|
+
export type DropdownCheckboxItemBaseProps = Omit<
|
|
99
154
|
ComponentProps<"li">,
|
|
100
155
|
"role" | "tabIndex" | "aria-checked" | "defaultChecked" | "onSelect"
|
|
101
156
|
> & {
|
|
@@ -110,44 +165,88 @@ type DropdownCheckboxItemBaseProps = Omit<
|
|
|
110
165
|
onSelect?: (event: Event) => void;
|
|
111
166
|
};
|
|
112
167
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
168
|
+
/**
|
|
169
|
+
* Uncontrolled variant of {@link DropdownCheckboxItemProps}: the component owns
|
|
170
|
+
* the checked state. Pass `defaultChecked` (or omit it); `onCheckedChange` is
|
|
171
|
+
* optional and the controlled `checked` prop is forbidden.
|
|
172
|
+
*/
|
|
173
|
+
export type DropdownCheckboxItemUncontrolledProps =
|
|
174
|
+
DropdownCheckboxItemBaseProps & {
|
|
175
|
+
defaultChecked?: CheckedState;
|
|
176
|
+
checked?: never;
|
|
177
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
178
|
+
};
|
|
118
179
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Controlled variant of {@link DropdownCheckboxItemProps}: the parent owns the
|
|
182
|
+
* checked state. Pass `checked` and `onCheckedChange` together;
|
|
183
|
+
* `defaultChecked` is forbidden.
|
|
184
|
+
*/
|
|
185
|
+
export type DropdownCheckboxItemControlledProps =
|
|
186
|
+
DropdownCheckboxItemBaseProps & {
|
|
187
|
+
defaultChecked?: never;
|
|
188
|
+
checked: CheckedState;
|
|
189
|
+
onCheckedChange: (checked: boolean) => void;
|
|
190
|
+
};
|
|
124
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Props for {@link Dropdown.CheckboxItem} — a togglable menu item. The
|
|
194
|
+
* controlled/uncontrolled discriminated union pairing
|
|
195
|
+
* {@link DropdownCheckboxItemUncontrolledProps} with
|
|
196
|
+
* {@link DropdownCheckboxItemControlledProps}.
|
|
197
|
+
*/
|
|
125
198
|
export type DropdownCheckboxItemProps =
|
|
126
199
|
| DropdownCheckboxItemUncontrolledProps
|
|
127
200
|
| DropdownCheckboxItemControlledProps;
|
|
128
201
|
|
|
129
|
-
|
|
202
|
+
/**
|
|
203
|
+
* Shared base for both {@link DropdownRadioGroupProps} variants — the native
|
|
204
|
+
* `<li>` props plus `asChild`.
|
|
205
|
+
*/
|
|
206
|
+
export type DropdownRadioGroupBaseProps = Omit<ComponentProps<"li">, "role"> & {
|
|
130
207
|
children?: ReactNode;
|
|
131
208
|
ref?: Ref<HTMLLIElement>;
|
|
132
209
|
asChild?: boolean;
|
|
133
210
|
};
|
|
134
211
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Uncontrolled variant of {@link DropdownRadioGroupProps}: the component owns
|
|
214
|
+
* the selected value. Pass `defaultValue` (or omit it); `onValueChange` is
|
|
215
|
+
* optional and the controlled `value` prop is forbidden.
|
|
216
|
+
*/
|
|
217
|
+
export type DropdownRadioGroupUncontrolledProps =
|
|
218
|
+
DropdownRadioGroupBaseProps & {
|
|
219
|
+
defaultValue?: string;
|
|
220
|
+
value?: never;
|
|
221
|
+
onValueChange?: (value: string) => void;
|
|
222
|
+
};
|
|
140
223
|
|
|
141
|
-
|
|
224
|
+
/**
|
|
225
|
+
* Controlled variant of {@link DropdownRadioGroupProps}: the parent owns the
|
|
226
|
+
* selected value. Pass `value` and `onValueChange` together; `defaultValue` is
|
|
227
|
+
* forbidden.
|
|
228
|
+
*/
|
|
229
|
+
export type DropdownRadioGroupControlledProps = DropdownRadioGroupBaseProps & {
|
|
142
230
|
defaultValue?: never;
|
|
143
231
|
value: string;
|
|
144
232
|
onValueChange: (value: string) => void;
|
|
145
233
|
};
|
|
146
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Props for {@link Dropdown.RadioGroup} — a single-select group of radio items.
|
|
237
|
+
* The controlled/uncontrolled discriminated union pairing
|
|
238
|
+
* {@link DropdownRadioGroupUncontrolledProps} with
|
|
239
|
+
* {@link DropdownRadioGroupControlledProps}.
|
|
240
|
+
*/
|
|
147
241
|
export type DropdownRadioGroupProps =
|
|
148
242
|
| DropdownRadioGroupUncontrolledProps
|
|
149
243
|
| DropdownRadioGroupControlledProps;
|
|
150
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Props for {@link Dropdown.RadioItem} — one option within a
|
|
247
|
+
* {@link Dropdown.RadioGroup}. Extends the native `<li>` props and adds the
|
|
248
|
+
* required `value`, plus `disabled`, `asChild`, and `onSelect`.
|
|
249
|
+
*/
|
|
151
250
|
export type DropdownRadioItemProps = Omit<
|
|
152
251
|
ComponentProps<"li">,
|
|
153
252
|
"role" | "tabIndex" | "aria-checked" | "onSelect"
|
|
@@ -160,26 +259,50 @@ export type DropdownRadioItemProps = Omit<
|
|
|
160
259
|
onSelect?: (event: Event) => void;
|
|
161
260
|
};
|
|
162
261
|
|
|
163
|
-
|
|
262
|
+
/**
|
|
263
|
+
* Shared base for both {@link DropdownSubProps} variants — just the submenu
|
|
264
|
+
* `children`.
|
|
265
|
+
*/
|
|
266
|
+
export type DropdownSubBaseProps = {
|
|
164
267
|
children?: ReactNode;
|
|
165
268
|
};
|
|
166
269
|
|
|
167
|
-
|
|
270
|
+
/**
|
|
271
|
+
* Uncontrolled variant of {@link DropdownSubProps}: the component owns the
|
|
272
|
+
* submenu open state. Pass `defaultOpen` (or omit it); `onOpenChange` is
|
|
273
|
+
* optional and the controlled `open` prop is forbidden.
|
|
274
|
+
*/
|
|
275
|
+
export type DropdownSubUncontrolledProps = DropdownSubBaseProps & {
|
|
168
276
|
defaultOpen?: boolean;
|
|
169
277
|
open?: never;
|
|
170
278
|
onOpenChange?: (open: boolean) => void;
|
|
171
279
|
};
|
|
172
280
|
|
|
173
|
-
|
|
281
|
+
/**
|
|
282
|
+
* Controlled variant of {@link DropdownSubProps}: the parent owns the submenu
|
|
283
|
+
* open state. Pass `open` and `onOpenChange` together; `defaultOpen` is
|
|
284
|
+
* forbidden.
|
|
285
|
+
*/
|
|
286
|
+
export type DropdownSubControlledProps = DropdownSubBaseProps & {
|
|
174
287
|
defaultOpen?: never;
|
|
175
288
|
open: boolean;
|
|
176
289
|
onOpenChange: (open: boolean) => void;
|
|
177
290
|
};
|
|
178
291
|
|
|
292
|
+
/**
|
|
293
|
+
* Props for {@link Dropdown.Sub} — the root of a nested submenu. The
|
|
294
|
+
* controlled/uncontrolled discriminated union pairing
|
|
295
|
+
* {@link DropdownSubUncontrolledProps} with {@link DropdownSubControlledProps}.
|
|
296
|
+
*/
|
|
179
297
|
export type DropdownSubProps =
|
|
180
298
|
| DropdownSubUncontrolledProps
|
|
181
299
|
| DropdownSubControlledProps;
|
|
182
300
|
|
|
301
|
+
/**
|
|
302
|
+
* Props for {@link Dropdown.SubTrigger} — the item that opens a submenu.
|
|
303
|
+
* Extends the native `<li>` props (minus the ARIA attributes Dropdown owns) and
|
|
304
|
+
* adds `disabled` and `asChild`.
|
|
305
|
+
*/
|
|
183
306
|
export type DropdownSubTriggerProps = Omit<
|
|
184
307
|
ComponentProps<"li">,
|
|
185
308
|
"role" | "tabIndex" | "aria-haspopup" | "aria-expanded" | "aria-controls"
|
|
@@ -190,6 +313,11 @@ export type DropdownSubTriggerProps = Omit<
|
|
|
190
313
|
disabled?: boolean;
|
|
191
314
|
};
|
|
192
315
|
|
|
316
|
+
/**
|
|
317
|
+
* Props for {@link Dropdown.SubContent} — the popover surface of a submenu.
|
|
318
|
+
* Extends the native `<menu>` props (minus the `role`/`popover`/`id` Dropdown
|
|
319
|
+
* manages) and adds `asChild`.
|
|
320
|
+
*/
|
|
193
321
|
export type DropdownSubContentProps = Omit<
|
|
194
322
|
ComponentProps<"menu">,
|
|
195
323
|
"role" | "popover" | "id"
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
|
|
3
|
+
import { Slot } from "../Slot/index.ts";
|
|
2
4
|
import {
|
|
3
5
|
EmptyStateActionsProps,
|
|
4
6
|
EmptyStateDescriptionProps,
|
|
@@ -34,11 +36,11 @@ import {
|
|
|
34
36
|
* )}
|
|
35
37
|
* ```
|
|
36
38
|
*/
|
|
37
|
-
function EmptyStateRoot({
|
|
39
|
+
export function EmptyStateRoot({
|
|
38
40
|
asChild = false,
|
|
39
41
|
children,
|
|
40
42
|
...rest
|
|
41
|
-
}: EmptyStateRootProps) {
|
|
43
|
+
}: EmptyStateRootProps): ReactElement {
|
|
42
44
|
const rootProps = { role: "status", ...rest };
|
|
43
45
|
|
|
44
46
|
if (asChild) {
|
|
@@ -48,6 +50,7 @@ function EmptyStateRoot({
|
|
|
48
50
|
return <div {...rootProps}>{children}</div>;
|
|
49
51
|
}
|
|
50
52
|
|
|
53
|
+
/** @internal */
|
|
51
54
|
EmptyStateRoot.displayName = "EmptyStateRoot";
|
|
52
55
|
|
|
53
56
|
/**
|
|
@@ -72,11 +75,11 @@ EmptyStateRoot.displayName = "EmptyStateRoot";
|
|
|
72
75
|
* </EmptyState.Media>
|
|
73
76
|
* ```
|
|
74
77
|
*/
|
|
75
|
-
function EmptyStateMedia({
|
|
78
|
+
export function EmptyStateMedia({
|
|
76
79
|
asChild = false,
|
|
77
80
|
children,
|
|
78
81
|
...rest
|
|
79
|
-
}: EmptyStateMediaProps) {
|
|
82
|
+
}: EmptyStateMediaProps): ReactElement {
|
|
80
83
|
const mediaProps = { "aria-hidden": true, ...rest };
|
|
81
84
|
|
|
82
85
|
if (asChild) {
|
|
@@ -86,6 +89,7 @@ function EmptyStateMedia({
|
|
|
86
89
|
return <div {...mediaProps}>{children}</div>;
|
|
87
90
|
}
|
|
88
91
|
|
|
92
|
+
/** @internal */
|
|
89
93
|
EmptyStateMedia.displayName = "EmptyStateMedia";
|
|
90
94
|
|
|
91
95
|
/**
|
|
@@ -107,11 +111,11 @@ EmptyStateMedia.displayName = "EmptyStateMedia";
|
|
|
107
111
|
* </EmptyState.Title>
|
|
108
112
|
* ```
|
|
109
113
|
*/
|
|
110
|
-
function EmptyStateTitle({
|
|
114
|
+
export function EmptyStateTitle({
|
|
111
115
|
asChild = false,
|
|
112
116
|
children,
|
|
113
117
|
...rest
|
|
114
|
-
}: EmptyStateTitleProps) {
|
|
118
|
+
}: EmptyStateTitleProps): ReactElement {
|
|
115
119
|
if (asChild) {
|
|
116
120
|
return <Slot {...rest}>{children}</Slot>;
|
|
117
121
|
}
|
|
@@ -119,6 +123,7 @@ function EmptyStateTitle({
|
|
|
119
123
|
return <p {...rest}>{children}</p>;
|
|
120
124
|
}
|
|
121
125
|
|
|
126
|
+
/** @internal */
|
|
122
127
|
EmptyStateTitle.displayName = "EmptyStateTitle";
|
|
123
128
|
|
|
124
129
|
/**
|
|
@@ -137,11 +142,11 @@ EmptyStateTitle.displayName = "EmptyStateTitle";
|
|
|
137
142
|
* <EmptyState.Description>Try adjusting your filters.</EmptyState.Description>
|
|
138
143
|
* ```
|
|
139
144
|
*/
|
|
140
|
-
function EmptyStateDescription({
|
|
145
|
+
export function EmptyStateDescription({
|
|
141
146
|
asChild = false,
|
|
142
147
|
children,
|
|
143
148
|
...rest
|
|
144
|
-
}: EmptyStateDescriptionProps) {
|
|
149
|
+
}: EmptyStateDescriptionProps): ReactElement {
|
|
145
150
|
if (asChild) {
|
|
146
151
|
return <Slot {...rest}>{children}</Slot>;
|
|
147
152
|
}
|
|
@@ -149,6 +154,7 @@ function EmptyStateDescription({
|
|
|
149
154
|
return <p {...rest}>{children}</p>;
|
|
150
155
|
}
|
|
151
156
|
|
|
157
|
+
/** @internal */
|
|
152
158
|
EmptyStateDescription.displayName = "EmptyStateDescription";
|
|
153
159
|
|
|
154
160
|
/**
|
|
@@ -171,11 +177,11 @@ EmptyStateDescription.displayName = "EmptyStateDescription";
|
|
|
171
177
|
* </EmptyState.Actions>
|
|
172
178
|
* ```
|
|
173
179
|
*/
|
|
174
|
-
function EmptyStateActions({
|
|
180
|
+
export function EmptyStateActions({
|
|
175
181
|
asChild = false,
|
|
176
182
|
children,
|
|
177
183
|
...rest
|
|
178
|
-
}: EmptyStateActionsProps) {
|
|
184
|
+
}: EmptyStateActionsProps): ReactElement {
|
|
179
185
|
if (asChild) {
|
|
180
186
|
return <Slot {...rest}>{children}</Slot>;
|
|
181
187
|
}
|
|
@@ -183,24 +189,23 @@ function EmptyStateActions({
|
|
|
183
189
|
return <div {...rest}>{children}</div>;
|
|
184
190
|
}
|
|
185
191
|
|
|
192
|
+
/** @internal */
|
|
186
193
|
EmptyStateActions.displayName = "EmptyStateActions";
|
|
187
194
|
|
|
188
|
-
|
|
195
|
+
/** Type of the {@link EmptyState} compound — the Root callable plus its sub-components. */
|
|
196
|
+
export type EmptyStateCompound = typeof EmptyStateRoot & {
|
|
197
|
+
/** The `<div role="status">` live region wrapping the placeholder. */
|
|
189
198
|
Root: typeof EmptyStateRoot;
|
|
199
|
+
/** The decorative icon/illustration slot. */
|
|
190
200
|
Media: typeof EmptyStateMedia;
|
|
201
|
+
/** The headline. */
|
|
191
202
|
Title: typeof EmptyStateTitle;
|
|
203
|
+
/** The supporting copy. */
|
|
192
204
|
Description: typeof EmptyStateDescription;
|
|
205
|
+
/** The recovery-action slot. */
|
|
193
206
|
Actions: typeof EmptyStateActions;
|
|
194
207
|
};
|
|
195
208
|
|
|
196
|
-
const EmptyState: EmptyStateCompound = Object.assign(EmptyStateRoot, {
|
|
197
|
-
Root: EmptyStateRoot,
|
|
198
|
-
Media: EmptyStateMedia,
|
|
199
|
-
Title: EmptyStateTitle,
|
|
200
|
-
Description: EmptyStateDescription,
|
|
201
|
-
Actions: EmptyStateActions,
|
|
202
|
-
});
|
|
203
|
-
|
|
204
209
|
/**
|
|
205
210
|
* Headless, accessible **Empty State** — a stateless compound component for
|
|
206
211
|
* the placeholder shown when a collection, search, or view has no content.
|
|
@@ -240,6 +245,15 @@ const EmptyState: EmptyStateCompound = Object.assign(EmptyStateRoot, {
|
|
|
240
245
|
* )}
|
|
241
246
|
* ```
|
|
242
247
|
*/
|
|
248
|
+
const EmptyState: EmptyStateCompound = Object.assign(EmptyStateRoot, {
|
|
249
|
+
Root: EmptyStateRoot,
|
|
250
|
+
Media: EmptyStateMedia,
|
|
251
|
+
Title: EmptyStateTitle,
|
|
252
|
+
Description: EmptyStateDescription,
|
|
253
|
+
Actions: EmptyStateActions,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
/** @internal */
|
|
243
257
|
EmptyState.displayName = "EmptyState";
|
|
244
258
|
|
|
245
259
|
export { EmptyState };
|
package/src/EmptyState/types.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ComponentProps } from "react";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/** Mixin adding the `asChild` opt-in to a sub-component's props. */
|
|
4
|
+
export type WithAsChild = {
|
|
4
5
|
/** Render the consumer's own element instead of the default, via `Slot`. */
|
|
5
6
|
asChild?: boolean;
|
|
6
7
|
};
|
package/src/Field/Field.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { useId, useMemo } from "react";
|
|
2
|
+
import type { ReactElement } from "react";
|
|
2
3
|
|
|
3
|
-
import { Slot } from "../Slot";
|
|
4
|
+
import { Slot } from "../Slot/index.ts";
|
|
4
5
|
import { FieldContext } from "./FieldContext";
|
|
5
|
-
import { useFieldContext } from "./hooks";
|
|
6
|
+
import { useFieldContext } from "./hooks/index.ts";
|
|
6
7
|
import {
|
|
7
8
|
FieldDescriptionProps,
|
|
8
9
|
FieldErrorTextProps,
|
|
@@ -45,7 +46,7 @@ import {
|
|
|
45
46
|
* </Field.Root>
|
|
46
47
|
* ```
|
|
47
48
|
*/
|
|
48
|
-
function FieldRoot({
|
|
49
|
+
export function FieldRoot({
|
|
49
50
|
id: idProp,
|
|
50
51
|
invalid = false,
|
|
51
52
|
disabled = false,
|
|
@@ -53,7 +54,7 @@ function FieldRoot({
|
|
|
53
54
|
asChild = false,
|
|
54
55
|
children,
|
|
55
56
|
...rest
|
|
56
|
-
}: FieldRootProps) {
|
|
57
|
+
}: FieldRootProps): ReactElement {
|
|
57
58
|
const autoId = useId();
|
|
58
59
|
const id = idProp ?? autoId;
|
|
59
60
|
const descriptionId = `${id}-description`;
|
|
@@ -83,6 +84,7 @@ function FieldRoot({
|
|
|
83
84
|
);
|
|
84
85
|
}
|
|
85
86
|
|
|
87
|
+
/** @internal */
|
|
86
88
|
FieldRoot.displayName = "FieldRoot";
|
|
87
89
|
|
|
88
90
|
/**
|
|
@@ -94,7 +96,11 @@ FieldRoot.displayName = "FieldRoot";
|
|
|
94
96
|
*
|
|
95
97
|
* @throws If rendered outside a `<Field.Root>`.
|
|
96
98
|
*/
|
|
97
|
-
function FieldLabel({
|
|
99
|
+
export function FieldLabel({
|
|
100
|
+
asChild = false,
|
|
101
|
+
children,
|
|
102
|
+
...rest
|
|
103
|
+
}: FieldLabelProps): ReactElement {
|
|
98
104
|
const { id } = useFieldContext();
|
|
99
105
|
const labelProps = { ...rest, htmlFor: id };
|
|
100
106
|
|
|
@@ -104,6 +110,7 @@ function FieldLabel({ asChild = false, children, ...rest }: FieldLabelProps) {
|
|
|
104
110
|
return <label {...labelProps}>{children}</label>;
|
|
105
111
|
}
|
|
106
112
|
|
|
113
|
+
/** @internal */
|
|
107
114
|
FieldLabel.displayName = "FieldLabel";
|
|
108
115
|
|
|
109
116
|
/**
|
|
@@ -117,11 +124,11 @@ FieldLabel.displayName = "FieldLabel";
|
|
|
117
124
|
*
|
|
118
125
|
* @throws If rendered outside a `<Field.Root>`.
|
|
119
126
|
*/
|
|
120
|
-
function FieldDescription({
|
|
127
|
+
export function FieldDescription({
|
|
121
128
|
asChild = false,
|
|
122
129
|
children,
|
|
123
130
|
...rest
|
|
124
|
-
}: FieldDescriptionProps) {
|
|
131
|
+
}: FieldDescriptionProps): ReactElement {
|
|
125
132
|
const { descriptionId } = useFieldContext();
|
|
126
133
|
const descriptionProps = { ...rest, id: descriptionId };
|
|
127
134
|
|
|
@@ -131,6 +138,7 @@ function FieldDescription({
|
|
|
131
138
|
return <div {...descriptionProps}>{children}</div>;
|
|
132
139
|
}
|
|
133
140
|
|
|
141
|
+
/** @internal */
|
|
134
142
|
FieldDescription.displayName = "FieldDescription";
|
|
135
143
|
|
|
136
144
|
/**
|
|
@@ -151,11 +159,11 @@ FieldDescription.displayName = "FieldDescription";
|
|
|
151
159
|
*
|
|
152
160
|
* @throws If rendered outside a `<Field.Root>`.
|
|
153
161
|
*/
|
|
154
|
-
function FieldErrorText({
|
|
162
|
+
export function FieldErrorText({
|
|
155
163
|
asChild = false,
|
|
156
164
|
children,
|
|
157
165
|
...rest
|
|
158
|
-
}: FieldErrorTextProps) {
|
|
166
|
+
}: FieldErrorTextProps): ReactElement | null {
|
|
159
167
|
const { errorId, invalid } = useFieldContext();
|
|
160
168
|
if (!invalid) return null;
|
|
161
169
|
const errorProps = { ...rest, id: errorId, role: "alert" as const };
|
|
@@ -166,12 +174,18 @@ function FieldErrorText({
|
|
|
166
174
|
return <div {...errorProps}>{children}</div>;
|
|
167
175
|
}
|
|
168
176
|
|
|
177
|
+
/** @internal */
|
|
169
178
|
FieldErrorText.displayName = "FieldErrorText";
|
|
170
179
|
|
|
171
|
-
|
|
180
|
+
/** Type of the {@link Field} compound — the Root callable plus its sub-components. */
|
|
181
|
+
export type TFieldCompound = typeof FieldRoot & {
|
|
182
|
+
/** The wrapper that owns shared field state and context. */
|
|
172
183
|
Root: typeof FieldRoot;
|
|
184
|
+
/** The field's label. */
|
|
173
185
|
Label: typeof FieldLabel;
|
|
186
|
+
/** The field's supporting helper text. */
|
|
174
187
|
Description: typeof FieldDescription;
|
|
188
|
+
/** The error message shown when invalid. */
|
|
175
189
|
ErrorText: typeof FieldErrorText;
|
|
176
190
|
};
|
|
177
191
|
|
package/src/Field/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode } from "react";
|
|
2
2
|
|
|
3
|
+
/** Props for `Field.Root`, the wrapper that owns shared field state. */
|
|
3
4
|
export type FieldRootProps = ComponentProps<"div"> & {
|
|
4
5
|
/** Stable id wired to the control via {@link FieldLabel}'s `htmlFor`. Auto-generated via `useId` when omitted. */
|
|
5
6
|
id?: string;
|
|
@@ -14,18 +15,21 @@ export type FieldRootProps = ComponentProps<"div"> & {
|
|
|
14
15
|
children?: ReactNode;
|
|
15
16
|
};
|
|
16
17
|
|
|
18
|
+
/** Props for `Field.Label`, the field's `<label>`. */
|
|
17
19
|
export type FieldLabelProps = ComponentProps<"label"> & {
|
|
18
20
|
/** Renders the consumer element instead of `<label>` via Slot. */
|
|
19
21
|
asChild?: boolean;
|
|
20
22
|
children?: ReactNode;
|
|
21
23
|
};
|
|
22
24
|
|
|
25
|
+
/** Props for `Field.Description`, the field's supporting helper text. */
|
|
23
26
|
export type FieldDescriptionProps = ComponentProps<"div"> & {
|
|
24
27
|
/** Renders the consumer element instead of `<div>` via Slot. */
|
|
25
28
|
asChild?: boolean;
|
|
26
29
|
children?: ReactNode;
|
|
27
30
|
};
|
|
28
31
|
|
|
32
|
+
/** Props for `Field.ErrorText`, the error message shown when invalid. */
|
|
29
33
|
export type FieldErrorTextProps = ComponentProps<"div"> & {
|
|
30
34
|
/** Renders the consumer element instead of `<div>` via Slot. */
|
|
31
35
|
asChild?: boolean;
|