@primitiv-ui/react 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/package.json +2 -1
- package/src/AccessibleIcon/AccessibleIcon.tsx +1 -0
- package/src/AccessibleIcon/types.ts +4 -0
- package/src/Accordion/Accordion.tsx +23 -0
- package/src/Accordion/index.ts +2 -1
- package/src/Accordion/types.ts +55 -13
- package/src/Alert/Alert.tsx +1 -0
- package/src/Alert/types.ts +1 -0
- package/src/Avatar/Avatar.tsx +8 -4
- package/src/Avatar/AvatarContext.ts +2 -0
- package/src/Breadcrumb/Breadcrumb.tsx +15 -7
- package/src/Button/Button.tsx +1 -0
- package/src/Button/types.ts +4 -0
- package/src/Carousel/Carousel.tsx +9 -0
- package/src/Carousel/CarouselContext.ts +5 -2
- package/src/Carousel/types.ts +8 -0
- package/src/Checkbox/Checkbox.tsx +7 -3
- package/src/Checkbox/index.ts +1 -0
- package/src/Checkbox/types.ts +30 -3
- package/src/CheckboxCard/CheckboxCard.tsx +9 -8
- package/src/CheckboxCard/CheckboxCardContext.ts +9 -1
- package/src/CheckboxCard/hooks/useCheckboxCardRoot.ts +1 -1
- package/src/CheckboxCard/types.ts +21 -5
- package/src/Collapsible/Collapsible.tsx +15 -0
- package/src/Collapsible/index.ts +1 -0
- package/src/Collapsible/types.ts +45 -12
- package/src/ContextMenu/ContextMenu.tsx +40 -15
- package/src/ContextMenu/index.ts +2 -1
- package/src/ContextMenu/types.ts +159 -16
- package/src/DirectionProvider/DirectionProvider.tsx +1 -0
- package/src/DirectionProvider/types.ts +1 -0
- package/src/Divider/Divider.tsx +1 -0
- package/src/Divider/index.ts +2 -1
- package/src/Divider/types.ts +5 -0
- package/src/Dropdown/Dropdown.tsx +40 -15
- package/src/Dropdown/index.ts +2 -1
- package/src/Dropdown/types.ts +152 -24
- package/src/EmptyState/EmptyState.tsx +26 -14
- package/src/EmptyState/types.ts +2 -1
- package/src/Field/Field.tsx +14 -5
- package/src/Field/types.ts +4 -0
- package/src/Fieldset/Fieldset.tsx +17 -10
- package/src/Fieldset/types.ts +2 -0
- package/src/Input/Input.tsx +1 -0
- package/src/Input/types.ts +4 -0
- package/src/InputGroup/InputGroup.tsx +9 -4
- package/src/InputGroup/types.ts +9 -0
- package/src/MillerColumns/MillerColumns.tsx +19 -0
- package/src/MillerColumns/index.ts +1 -1
- package/src/MillerColumns/types.ts +67 -14
- package/src/Modal/Modal.tsx +1 -0
- package/src/Modal/ModalContext.ts +5 -2
- package/src/Modal/types.ts +51 -2
- package/src/Portal/Portal.tsx +1 -0
- package/src/Portal/types.ts +4 -0
- package/src/Progress/Progress.tsx +7 -3
- package/src/Progress/ProgressContext.ts +7 -0
- package/src/RadioCard/RadioCard.tsx +9 -4
- package/src/RadioCard/RadioCardContext.ts +7 -0
- package/src/RadioCard/RadioCardItemContext.ts +8 -0
- package/src/RadioCard/types.ts +24 -3
- package/src/RadioGroup/RadioGroup.tsx +9 -4
- package/src/RadioGroup/index.ts +1 -0
- package/src/RadioGroup/types.ts +34 -3
- package/src/Select/Select.tsx +16 -5
- package/src/Select/index.ts +1 -1
- package/src/Select/types.ts +18 -3
- package/src/Slider/Slider.tsx +10 -5
- package/src/Slider/SliderContext.ts +3 -0
- package/src/Slider/types.ts +12 -3
- package/src/Status/Status.tsx +1 -0
- package/src/Status/types.ts +4 -0
- package/src/Switch/Switch.tsx +8 -3
- package/src/Switch/SwitchContext.ts +4 -0
- package/src/Switch/types.ts +24 -3
- package/src/Table/Table.tsx +44 -24
- package/src/Table/index.ts +2 -1
- package/src/Tabs/Tabs.tsx +7 -2
- package/src/Tabs/TabsContext.ts +7 -2
- package/src/Tabs/types.ts +35 -1
- package/src/Textarea/Textarea.tsx +1 -0
- package/src/Textarea/types.ts +4 -0
- package/src/Toggle/Toggle.tsx +1 -0
- package/src/Toggle/types.ts +7 -3
- package/src/ToggleGroup/ToggleGroup.tsx +9 -3
- package/src/ToggleGroup/types.ts +45 -5
- package/src/Tooltip/Tooltip.tsx +25 -7
- package/src/Tooltip/index.ts +1 -0
- package/src/Tooltip/types.ts +50 -2
- package/src/Tree/Tree.tsx +46 -1
- package/src/Tree/index.ts +1 -1
- package/src/Tree/types.ts +39 -7
- package/src/VisuallyHidden/VisuallyHidden.tsx +1 -0
- package/src/VisuallyHidden/types.ts +4 -0
- package/src/index.ts +1 -0
- package/src/types.ts +1 -0
|
@@ -36,7 +36,7 @@ import { InputGroupAdornmentProps, InputGroupRootProps } from "./types";
|
|
|
36
36
|
* </InputGroup>
|
|
37
37
|
* ```
|
|
38
38
|
*/
|
|
39
|
-
function InputGroupRoot({
|
|
39
|
+
export function InputGroupRoot({
|
|
40
40
|
asChild = false,
|
|
41
41
|
children,
|
|
42
42
|
ref,
|
|
@@ -55,6 +55,7 @@ function InputGroupRoot({
|
|
|
55
55
|
return <div {...rootProps}>{children}</div>;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/** @internal */
|
|
58
59
|
InputGroupRoot.displayName = "InputGroupRoot";
|
|
59
60
|
|
|
60
61
|
/**
|
|
@@ -91,7 +92,7 @@ InputGroupRoot.displayName = "InputGroupRoot";
|
|
|
91
92
|
* </InputGroup.LeadingAdornment>
|
|
92
93
|
* ```
|
|
93
94
|
*/
|
|
94
|
-
function InputGroupLeadingAdornment({
|
|
95
|
+
export function InputGroupLeadingAdornment({
|
|
95
96
|
asChild = false,
|
|
96
97
|
children,
|
|
97
98
|
ref,
|
|
@@ -110,6 +111,7 @@ function InputGroupLeadingAdornment({
|
|
|
110
111
|
return <span {...adornmentProps}>{children}</span>;
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
/** @internal */
|
|
113
115
|
InputGroupLeadingAdornment.displayName = "InputGroupLeadingAdornment";
|
|
114
116
|
|
|
115
117
|
/**
|
|
@@ -138,7 +140,7 @@ InputGroupLeadingAdornment.displayName = "InputGroupLeadingAdornment";
|
|
|
138
140
|
* </InputGroup.TrailingAdornment>
|
|
139
141
|
* ```
|
|
140
142
|
*/
|
|
141
|
-
function InputGroupTrailingAdornment({
|
|
143
|
+
export function InputGroupTrailingAdornment({
|
|
142
144
|
asChild = false,
|
|
143
145
|
children,
|
|
144
146
|
ref,
|
|
@@ -157,9 +159,11 @@ function InputGroupTrailingAdornment({
|
|
|
157
159
|
return <span {...adornmentProps}>{children}</span>;
|
|
158
160
|
}
|
|
159
161
|
|
|
162
|
+
/** @internal */
|
|
160
163
|
InputGroupTrailingAdornment.displayName = "InputGroupTrailingAdornment";
|
|
161
164
|
|
|
162
|
-
|
|
165
|
+
/** Type of the {@link InputGroup} compound: the root callable plus its attached sub-components. */
|
|
166
|
+
export type TInputGroupCompound = typeof InputGroupRoot & {
|
|
163
167
|
Root: typeof InputGroupRoot;
|
|
164
168
|
LeadingAdornment: typeof InputGroupLeadingAdornment;
|
|
165
169
|
TrailingAdornment: typeof InputGroupTrailingAdornment;
|
|
@@ -225,6 +229,7 @@ const InputGroupCompound: TInputGroupCompound = Object.assign(InputGroupRoot, {
|
|
|
225
229
|
TrailingAdornment: InputGroupTrailingAdornment,
|
|
226
230
|
});
|
|
227
231
|
|
|
232
|
+
/** @internal */
|
|
228
233
|
InputGroupCompound.displayName = "InputGroup";
|
|
229
234
|
|
|
230
235
|
export { InputGroupCompound as InputGroup };
|
package/src/InputGroup/types.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode, Ref } from "react";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Props for {@link InputGroup.Root} — all `<div>` attributes plus the
|
|
5
|
+
* `asChild` escape hatch and a typed `ref`.
|
|
6
|
+
*/
|
|
3
7
|
export type InputGroupRootProps = ComponentProps<"div"> & {
|
|
4
8
|
asChild?: boolean;
|
|
5
9
|
ref?: Ref<HTMLDivElement>;
|
|
6
10
|
children?: ReactNode;
|
|
7
11
|
};
|
|
8
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Props for {@link InputGroup.LeadingAdornment} and
|
|
15
|
+
* {@link InputGroup.TrailingAdornment} — all `<span>` attributes plus the
|
|
16
|
+
* `asChild` escape hatch and a typed `ref`.
|
|
17
|
+
*/
|
|
9
18
|
export type InputGroupAdornmentProps = ComponentProps<"span"> & {
|
|
10
19
|
asChild?: boolean;
|
|
11
20
|
ref?: Ref<HTMLSpanElement>;
|
|
@@ -81,6 +81,7 @@ export function MillerColumnsRoot({
|
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/** @internal */
|
|
84
85
|
MillerColumnsRoot.displayName = "MillerColumnsRoot";
|
|
85
86
|
|
|
86
87
|
/**
|
|
@@ -123,6 +124,7 @@ export function MillerColumnsColumn({
|
|
|
123
124
|
);
|
|
124
125
|
}
|
|
125
126
|
|
|
127
|
+
/** @internal */
|
|
126
128
|
MillerColumnsColumn.displayName = "MillerColumnsColumn";
|
|
127
129
|
|
|
128
130
|
/**
|
|
@@ -186,6 +188,7 @@ export function MillerColumnsItem<T extends HTMLElement = HTMLDivElement>({
|
|
|
186
188
|
);
|
|
187
189
|
}
|
|
188
190
|
|
|
191
|
+
/** @internal */
|
|
189
192
|
MillerColumnsItem.displayName = "MillerColumnsItem";
|
|
190
193
|
|
|
191
194
|
/**
|
|
@@ -232,6 +235,7 @@ export function MillerColumnsItemIndicator({
|
|
|
232
235
|
);
|
|
233
236
|
}
|
|
234
237
|
|
|
238
|
+
/** @internal */
|
|
235
239
|
MillerColumnsItemIndicator.displayName = "MillerColumnsItemIndicator";
|
|
236
240
|
|
|
237
241
|
/**
|
|
@@ -259,6 +263,7 @@ export function MillerColumnsResizeHandle(
|
|
|
259
263
|
return <div {...handleProps} />;
|
|
260
264
|
}
|
|
261
265
|
|
|
266
|
+
/** @internal */
|
|
262
267
|
MillerColumnsResizeHandle.displayName = "MillerColumnsResizeHandle";
|
|
263
268
|
|
|
264
269
|
/**
|
|
@@ -302,17 +307,31 @@ export function MillerColumnsPreviewPanel({
|
|
|
302
307
|
);
|
|
303
308
|
}
|
|
304
309
|
|
|
310
|
+
/** @internal */
|
|
305
311
|
MillerColumnsPreviewPanel.displayName = "MillerColumnsPreviewPanel";
|
|
306
312
|
|
|
313
|
+
/** Type of the {@link MillerColumns} compound — the Root callable plus its sub-components. */
|
|
307
314
|
type MillerColumnsCompound = typeof MillerColumnsRoot & {
|
|
315
|
+
/** The root strip, owning selection state and portal slots. */
|
|
308
316
|
Root: typeof MillerColumnsRoot;
|
|
317
|
+
/** A single vertical list within the strip. */
|
|
309
318
|
Column: typeof MillerColumnsColumn;
|
|
319
|
+
/** A selectable node within a column. */
|
|
310
320
|
Item: typeof MillerColumnsItem;
|
|
321
|
+
/** The branch-item chevron affordance. */
|
|
311
322
|
ItemIndicator: typeof MillerColumnsItemIndicator;
|
|
323
|
+
/** The drag-to-resize separator. */
|
|
312
324
|
ResizeHandle: typeof MillerColumnsResizeHandle;
|
|
325
|
+
/** The trailing preview pane. */
|
|
313
326
|
PreviewPanel: typeof MillerColumnsPreviewPanel;
|
|
314
327
|
};
|
|
315
328
|
|
|
329
|
+
/**
|
|
330
|
+
* MillerColumns — a horizontal strip of vertical lists where selecting a
|
|
331
|
+
* node reveals its children in the next column. Use as a namespace
|
|
332
|
+
* (`MillerColumns.Root`, `MillerColumns.Column`, `MillerColumns.Item`, …);
|
|
333
|
+
* the default export is also callable as the Root.
|
|
334
|
+
*/
|
|
316
335
|
const MillerColumnsCompound: MillerColumnsCompound = Object.assign(
|
|
317
336
|
MillerColumnsRoot,
|
|
318
337
|
{
|
|
@@ -1,51 +1,80 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode, Ref } from "react";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/** Props common to both controlled and uncontrolled `MillerColumns.Root` modes. */
|
|
4
|
+
export type MillerColumnsRootBaseProps = Omit<ComponentProps<"div">, "ref"> & {
|
|
5
|
+
/** The columns and panels that make up the strip. */
|
|
4
6
|
children: ReactNode;
|
|
5
7
|
};
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Props for `MillerColumns.Root` in uncontrolled mode — the component owns the
|
|
11
|
+
* selection path. Pass `defaultValue` to set the initial path.
|
|
12
|
+
*/
|
|
13
|
+
export type MillerColumnsRootUncontrolledProps = MillerColumnsRootBaseProps & {
|
|
14
|
+
/** Initial selection path when uncontrolled. */
|
|
8
15
|
defaultValue?: string[];
|
|
16
|
+
/** Forbidden in uncontrolled mode. */
|
|
9
17
|
value?: never;
|
|
18
|
+
/** Forbidden in uncontrolled mode. */
|
|
10
19
|
onValueChange?: never;
|
|
11
20
|
};
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Props for `MillerColumns.Root` in controlled mode — the parent owns the
|
|
24
|
+
* selection path. Pass `value` and `onValueChange` together.
|
|
25
|
+
*/
|
|
26
|
+
export type MillerColumnsRootControlledProps = MillerColumnsRootBaseProps & {
|
|
27
|
+
/** Forbidden in controlled mode. */
|
|
14
28
|
defaultValue?: never;
|
|
29
|
+
/** The controlled selection path, root column first. */
|
|
15
30
|
value: string[];
|
|
31
|
+
/** Called with the new path whenever the selection changes. */
|
|
16
32
|
onValueChange: (path: string[]) => void;
|
|
17
33
|
};
|
|
18
34
|
|
|
35
|
+
/** Props for `MillerColumns.Root` — discriminated controlled/uncontrolled union. */
|
|
19
36
|
export type MillerColumnsRootProps =
|
|
20
37
|
| MillerColumnsRootUncontrolledProps
|
|
21
38
|
| MillerColumnsRootControlledProps;
|
|
22
39
|
|
|
40
|
+
/** Props for `MillerColumns.Column`, a single vertical list within the strip. */
|
|
23
41
|
export type MillerColumnsColumnProps = ComponentProps<"div"> & {
|
|
42
|
+
/** The items (and optional resize handle) of this column. */
|
|
24
43
|
children: ReactNode;
|
|
25
44
|
};
|
|
26
45
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
/** Props for `MillerColumns.Item`, a single selectable node within a column. */
|
|
47
|
+
export type MillerColumnsItemProps<T extends HTMLElement = HTMLDivElement> =
|
|
48
|
+
Omit<ComponentProps<"div">, "ref"> & {
|
|
49
|
+
/** Stable identifier used to match this item against the selection path. */
|
|
50
|
+
value: string;
|
|
51
|
+
/** When `true`, the item cannot be selected or focused. */
|
|
52
|
+
disabled?: boolean;
|
|
53
|
+
/** Render the child element instead of the default `<div>`. */
|
|
54
|
+
asChild?: boolean;
|
|
55
|
+
/** Cell content and, for a branch, a nested `<MillerColumns.Column>`. */
|
|
56
|
+
children: ReactNode;
|
|
57
|
+
/** Ref to the rendered element. Defaults to `HTMLDivElement`; when using
|
|
58
|
+
* `asChild`, specify the child's element type. */
|
|
59
|
+
ref?: Ref<T>;
|
|
60
|
+
};
|
|
38
61
|
|
|
62
|
+
/** Props for `MillerColumns.ItemIndicator`, the branch chevron affordance. */
|
|
39
63
|
export type MillerColumnsItemIndicatorProps = ComponentProps<"span"> & {
|
|
64
|
+
/** The glyph to render (defaults to none). */
|
|
40
65
|
children?: ReactNode;
|
|
41
66
|
};
|
|
42
67
|
|
|
68
|
+
/** Props for `MillerColumns.ResizeHandle`, the drag-to-resize separator. */
|
|
43
69
|
export type MillerColumnsResizeHandleProps = ComponentProps<"div">;
|
|
44
70
|
|
|
71
|
+
/** Props for `MillerColumns.PreviewPanel`, the trailing preview pane. */
|
|
45
72
|
export type MillerColumnsPreviewPanelProps = ComponentProps<"div"> & {
|
|
73
|
+
/** The preview content for the current selection. */
|
|
46
74
|
children?: ReactNode;
|
|
47
75
|
};
|
|
48
76
|
|
|
77
|
+
/** The current selection, as returned by `useMillerColumnsSelection`. */
|
|
49
78
|
export type MillerColumnsSelection = {
|
|
50
79
|
/** The full active path — selected item ids, root column first. */
|
|
51
80
|
path: string[];
|
|
@@ -53,41 +82,65 @@ export type MillerColumnsSelection = {
|
|
|
53
82
|
selectedValue: string | undefined;
|
|
54
83
|
};
|
|
55
84
|
|
|
85
|
+
/** Metadata recorded for each registered item, used for column navigation. */
|
|
56
86
|
export type MillerColumnsItemMeta = {
|
|
87
|
+
/** The item's stable identifier. */
|
|
57
88
|
value: string;
|
|
89
|
+
/** Whether the item is disabled. */
|
|
58
90
|
disabled: boolean;
|
|
59
91
|
};
|
|
60
92
|
|
|
93
|
+
/** A depth + value pair locating an item within the strip. */
|
|
61
94
|
export type MillerColumnsItemAddress = {
|
|
95
|
+
/** The zero-based column depth. */
|
|
62
96
|
depth: number;
|
|
97
|
+
/** The item's stable identifier. */
|
|
63
98
|
value: string;
|
|
64
99
|
};
|
|
65
100
|
|
|
101
|
+
/** Value shared through the root MillerColumns context. */
|
|
66
102
|
export type MillerColumnsContextValue = {
|
|
103
|
+
/** Portal slots keyed by column depth. */
|
|
67
104
|
slots: Map<number, HTMLElement>;
|
|
105
|
+
/** Per-depth column widths set via the resize handle. */
|
|
68
106
|
columnWidths: Map<number, number>;
|
|
107
|
+
/** Record a column's width at the given depth. */
|
|
69
108
|
setColumnWidth: (depth: number, width: number) => void;
|
|
109
|
+
/** The active selection path. */
|
|
70
110
|
activePath: string[];
|
|
111
|
+
/** Select the item at the given depth and value. */
|
|
71
112
|
select: (depth: number, value: string) => void;
|
|
113
|
+
/** Register (or unregister, with a `null` element) an item. */
|
|
72
114
|
registerItem: (
|
|
73
115
|
depth: number,
|
|
74
116
|
value: string,
|
|
75
117
|
element: HTMLElement | null,
|
|
76
118
|
disabled: boolean,
|
|
77
119
|
) => void;
|
|
120
|
+
/** Get the registered items for a column. */
|
|
78
121
|
getColumnItems: (depth: number) => MillerColumnsItemMeta[];
|
|
122
|
+
/** Move focus to the given item. */
|
|
79
123
|
focusItem: (depth: number, value: string) => void;
|
|
124
|
+
/** Focus the first item in a column; returns whether one was focused. */
|
|
80
125
|
focusFirstInColumn: (depth: number) => boolean;
|
|
126
|
+
/** Request that focus move into the given column. */
|
|
81
127
|
requestColumnFocus: (depth: number) => void;
|
|
128
|
+
/** The currently active (focused) item, if any. */
|
|
82
129
|
activeItem: MillerColumnsItemAddress | null;
|
|
130
|
+
/** Set the active (focused) item. */
|
|
83
131
|
setActiveItem: (item: MillerColumnsItemAddress) => void;
|
|
84
132
|
};
|
|
85
133
|
|
|
134
|
+
/** Value shared through a column's context. */
|
|
86
135
|
export type MillerColumnsColumnContextValue = {
|
|
136
|
+
/** The column's zero-based depth. */
|
|
87
137
|
depth: number;
|
|
88
138
|
};
|
|
89
139
|
|
|
140
|
+
/** Value shared through an item's context. */
|
|
90
141
|
export type MillerColumnsItemContextValue = {
|
|
142
|
+
/** Whether this item is on the active path. */
|
|
91
143
|
selected: boolean;
|
|
144
|
+
/** Whether this item has a nested child column. */
|
|
92
145
|
hasChildren: boolean;
|
|
93
146
|
};
|
package/src/Modal/Modal.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Context } from "react";
|
|
1
|
+
import type { Context, Provider } from "react";
|
|
2
2
|
import { createStrictContext } from "../utils/index.ts";
|
|
3
3
|
|
|
4
4
|
import { ModalContextValue } from "./types";
|
|
@@ -8,10 +8,13 @@ const modalContextPair = createStrictContext<ModalContextValue>(
|
|
|
8
8
|
"ModalContext",
|
|
9
9
|
);
|
|
10
10
|
|
|
11
|
+
/** React context carrying the shared {@link ModalContextValue} for a modal. */
|
|
11
12
|
export const ModalContext: Context<ModalContextValue | null> =
|
|
12
13
|
modalContextPair[0];
|
|
14
|
+
/** Hook returning the nearest {@link ModalContextValue}; throws outside `Modal.Root`. */
|
|
13
15
|
export const useModalContext: () => ModalContextValue = modalContextPair[1];
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
/** Context provider for {@link ModalContext}, rendered internally by `Modal.Root`. */
|
|
18
|
+
const ModalProvider: Provider<ModalContextValue | null> = ModalContext.Provider;
|
|
16
19
|
|
|
17
20
|
export { ModalProvider };
|
package/src/Modal/types.ts
CHANGED
|
@@ -6,71 +6,120 @@ import {
|
|
|
6
6
|
RefObject,
|
|
7
7
|
} from "react";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Imperative handle exposed on `Modal.Root`'s `ref`, letting callers open
|
|
11
|
+
* and close the modal programmatically.
|
|
12
|
+
*/
|
|
9
13
|
export type ModalImperativeApi = {
|
|
14
|
+
/** Opens the modal. */
|
|
10
15
|
open: () => void;
|
|
16
|
+
/** Closes the modal. */
|
|
11
17
|
close: () => void;
|
|
12
18
|
};
|
|
13
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Optional escape-hatch callbacks accepted by `Modal.Content` for
|
|
22
|
+
* intercepting dismissal gestures.
|
|
23
|
+
*/
|
|
14
24
|
export type ModalContentCallbacks = {
|
|
25
|
+
/** Fires when the user presses Escape; call `preventDefault` to keep the modal open. */
|
|
15
26
|
onEscapeKeyDown?: (event: Event) => void;
|
|
27
|
+
/** Fires on a pointer-down outside the content; call `preventDefault` to keep the modal open. */
|
|
16
28
|
onPointerDownOutside?: (event: PointerEvent) => void;
|
|
17
29
|
};
|
|
18
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Shared context value published by `Modal.Root` and consumed by every
|
|
33
|
+
* sub-component to coordinate open state, ids, and ARIA wiring.
|
|
34
|
+
*/
|
|
19
35
|
export type ModalContextValue = {
|
|
36
|
+
/** Whether the modal is currently open. */
|
|
20
37
|
open: boolean;
|
|
38
|
+
/** Sets the open state. */
|
|
21
39
|
setOpen: (open: boolean) => void;
|
|
40
|
+
/** Generated id of the dialog content element. */
|
|
22
41
|
contentId: string;
|
|
42
|
+
/** Mutable ref holding the current content callbacks. */
|
|
23
43
|
contentCallbacksRef: RefObject<ModalContentCallbacks>;
|
|
44
|
+
/** Id of the registered title, or `undefined` when none is rendered. */
|
|
24
45
|
titleId: string | undefined;
|
|
46
|
+
/** Id of the registered description, or `undefined` when none is rendered. */
|
|
25
47
|
descriptionId: string | undefined;
|
|
48
|
+
/** Registers (or clears) the title id for `aria-labelledby`. */
|
|
26
49
|
registerTitle: (id: string | undefined) => void;
|
|
50
|
+
/** Registers (or clears) the description id for `aria-describedby`. */
|
|
27
51
|
registerDescription: (id: string | undefined) => void;
|
|
28
52
|
};
|
|
29
53
|
|
|
54
|
+
/** Props for `Modal.Content` — native `<dialog>` props plus dismissal callbacks. */
|
|
30
55
|
export type ModalContentProps = ComponentProps<"dialog"> &
|
|
31
56
|
ModalContentCallbacks;
|
|
32
57
|
|
|
33
|
-
|
|
58
|
+
/** `Modal.Root` props for the uncontrolled (self-managed) open state. */
|
|
59
|
+
export type UncontrolledModalRootProps = {
|
|
60
|
+
/** Initial open state when uncontrolled. */
|
|
34
61
|
defaultOpen?: boolean;
|
|
35
62
|
open?: never;
|
|
63
|
+
/** Called whenever the open state changes. */
|
|
36
64
|
onOpenChange?: (open: boolean) => void;
|
|
37
65
|
};
|
|
38
66
|
|
|
39
|
-
|
|
67
|
+
/** `Modal.Root` props for the controlled open state. */
|
|
68
|
+
export type ControlledModalRootProps = {
|
|
69
|
+
/** Controlled open state. */
|
|
40
70
|
open: boolean;
|
|
71
|
+
/** Called whenever the modal requests an open-state change. */
|
|
41
72
|
onOpenChange: (open: boolean) => void;
|
|
42
73
|
defaultOpen?: never;
|
|
43
74
|
};
|
|
44
75
|
|
|
76
|
+
/** Props for `Modal.Root`, in either the controlled or uncontrolled mode. */
|
|
45
77
|
export type ModalRootProps = {
|
|
78
|
+
/** Modal sub-components. */
|
|
46
79
|
children?: ReactNode;
|
|
47
80
|
} & (UncontrolledModalRootProps | ControlledModalRootProps) & {
|
|
81
|
+
/** Ref receiving the imperative open/close handle. */
|
|
48
82
|
ref?: Ref<ModalImperativeApi>;
|
|
49
83
|
};
|
|
50
84
|
|
|
85
|
+
/** Props for `Modal.Trigger` — a `<button>` that opens the modal. */
|
|
51
86
|
export type ModalTriggerProps = ComponentProps<"button"> & {
|
|
87
|
+
/** Render into the consumer's own element instead of a `<button>`. */
|
|
52
88
|
asChild?: boolean;
|
|
53
89
|
};
|
|
54
90
|
|
|
91
|
+
/** Props for `Modal.Close` — a `<button>` that closes the modal. */
|
|
55
92
|
export type ModalCloseProps = ComponentProps<"button"> & {
|
|
93
|
+
/** Render into the consumer's own element instead of a `<button>`. */
|
|
56
94
|
asChild?: boolean;
|
|
57
95
|
};
|
|
58
96
|
|
|
97
|
+
/** Props for `Modal.Portal` — renders its children into `container`. */
|
|
59
98
|
export type ModalPortalProps = {
|
|
99
|
+
/** Content to portal. */
|
|
60
100
|
children?: ReactNode;
|
|
101
|
+
/** Target element to portal into. Defaults to `document.body`. */
|
|
61
102
|
container?: HTMLElement;
|
|
103
|
+
/** Keep the portal mounted even while the modal is closed. */
|
|
62
104
|
forceMount?: boolean;
|
|
63
105
|
};
|
|
64
106
|
|
|
107
|
+
/** Props for `Modal.Overlay` — the click-outside backdrop. */
|
|
65
108
|
export type ModalOverlayProps = ComponentProps<"div"> & {
|
|
109
|
+
/** Render into the consumer's own element instead of a `<div>`. */
|
|
66
110
|
asChild?: boolean;
|
|
111
|
+
/** Keep the overlay mounted even while the modal is closed. */
|
|
67
112
|
forceMount?: boolean;
|
|
68
113
|
};
|
|
69
114
|
|
|
115
|
+
/** Props for `Modal.Title` — supplies the dialog's accessible name. */
|
|
70
116
|
export type ModalTitleProps = HTMLAttributes<HTMLElement> & {
|
|
117
|
+
/** Render into the consumer's own element instead of an `<h2>`. */
|
|
71
118
|
asChild?: boolean;
|
|
72
119
|
};
|
|
73
120
|
|
|
121
|
+
/** Props for `Modal.Description` — supplies the dialog's accessible description. */
|
|
74
122
|
export type ModalDescriptionProps = HTMLAttributes<HTMLElement> & {
|
|
123
|
+
/** Render into the consumer's own element instead of a `<p>`. */
|
|
75
124
|
asChild?: boolean;
|
|
76
125
|
};
|
package/src/Portal/Portal.tsx
CHANGED
package/src/Portal/types.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Props for {@link Portal} — the `children` to teleport and an optional
|
|
5
|
+
* `container` to render into (defaults to `document.body`).
|
|
6
|
+
*/
|
|
3
7
|
export type PortalProps = {
|
|
4
8
|
children?: ReactNode;
|
|
5
9
|
container?: HTMLElement;
|
|
@@ -47,7 +47,7 @@ function defaultGetValueLabel(value: number, max: number): string {
|
|
|
47
47
|
* </Progress.Root>
|
|
48
48
|
* ```
|
|
49
49
|
*/
|
|
50
|
-
function ProgressRoot({
|
|
50
|
+
export function ProgressRoot({
|
|
51
51
|
value,
|
|
52
52
|
max,
|
|
53
53
|
getValueLabel = defaultGetValueLabel,
|
|
@@ -93,6 +93,7 @@ function ProgressRoot({
|
|
|
93
93
|
);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
/** @internal */
|
|
96
97
|
ProgressRoot.displayName = "ProgressRoot";
|
|
97
98
|
|
|
98
99
|
/**
|
|
@@ -117,7 +118,7 @@ ProgressRoot.displayName = "ProgressRoot";
|
|
|
117
118
|
*
|
|
118
119
|
* @throws if rendered outside a `Progress.Root`.
|
|
119
120
|
*/
|
|
120
|
-
function ProgressIndicator({
|
|
121
|
+
export function ProgressIndicator({
|
|
121
122
|
asChild = false,
|
|
122
123
|
children,
|
|
123
124
|
...rest
|
|
@@ -135,9 +136,11 @@ function ProgressIndicator({
|
|
|
135
136
|
return <div {...indicatorProps}>{children}</div>;
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
/** @internal */
|
|
138
140
|
ProgressIndicator.displayName = "ProgressIndicator";
|
|
139
141
|
|
|
140
|
-
|
|
142
|
+
/** Type of the {@link Progress} compound: the root callable plus its attached sub-components. */
|
|
143
|
+
export type TProgressCompound = typeof ProgressRoot & {
|
|
141
144
|
Root: typeof ProgressRoot;
|
|
142
145
|
Indicator: typeof ProgressIndicator;
|
|
143
146
|
};
|
|
@@ -174,6 +177,7 @@ const ProgressCompound: TProgressCompound = Object.assign(ProgressRoot, {
|
|
|
174
177
|
Indicator: ProgressIndicator,
|
|
175
178
|
});
|
|
176
179
|
|
|
180
|
+
/** @internal */
|
|
177
181
|
ProgressCompound.displayName = "Progress";
|
|
178
182
|
|
|
179
183
|
export { ProgressCompound as Progress };
|
|
@@ -3,6 +3,11 @@ import { createStrictContext } from "../utils/index.ts";
|
|
|
3
3
|
|
|
4
4
|
import { ProgressState } from "./types";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Context value published by {@link Progress.Root} and consumed by
|
|
8
|
+
* {@link Progress.Indicator} — the current `value` (or `null` while
|
|
9
|
+
* indeterminate), the `max`, and the derived loading `state`.
|
|
10
|
+
*/
|
|
6
11
|
export type ProgressContextValue = {
|
|
7
12
|
value: number | null;
|
|
8
13
|
max: number;
|
|
@@ -14,7 +19,9 @@ const progressContextPair = createStrictContext<ProgressContextValue>(
|
|
|
14
19
|
"ProgressContext",
|
|
15
20
|
);
|
|
16
21
|
|
|
22
|
+
/** React context carrying the {@link ProgressContextValue}; `null` when no provider is present. */
|
|
17
23
|
export const ProgressContext: Context<ProgressContextValue | null> =
|
|
18
24
|
progressContextPair[0];
|
|
25
|
+
/** Reads the {@link ProgressContextValue}; throws if used outside a {@link Progress.Root}. */
|
|
19
26
|
export const useProgressContext: () => ProgressContextValue =
|
|
20
27
|
progressContextPair[1];
|
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
* </RadioCard.Root>
|
|
74
74
|
* ```
|
|
75
75
|
*/
|
|
76
|
-
function RadioCardRoot({
|
|
76
|
+
export function RadioCardRoot({
|
|
77
77
|
defaultValue,
|
|
78
78
|
value: controlledValue,
|
|
79
79
|
onValueChange,
|
|
@@ -129,6 +129,7 @@ function RadioCardRoot({
|
|
|
129
129
|
);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
/** @internal */
|
|
132
133
|
RadioCardRoot.displayName = "RadioCardRoot";
|
|
133
134
|
|
|
134
135
|
/**
|
|
@@ -158,7 +159,7 @@ RadioCardRoot.displayName = "RadioCardRoot";
|
|
|
158
159
|
*
|
|
159
160
|
* @throws if rendered outside a `RadioCard.Root`.
|
|
160
161
|
*/
|
|
161
|
-
function RadioCardItem({
|
|
162
|
+
export function RadioCardItem({
|
|
162
163
|
value,
|
|
163
164
|
children,
|
|
164
165
|
onClick,
|
|
@@ -232,6 +233,7 @@ function RadioCardItem({
|
|
|
232
233
|
);
|
|
233
234
|
}
|
|
234
235
|
|
|
236
|
+
/** @internal */
|
|
235
237
|
RadioCardItem.displayName = "RadioCardItem";
|
|
236
238
|
|
|
237
239
|
/**
|
|
@@ -260,7 +262,7 @@ RadioCardItem.displayName = "RadioCardItem";
|
|
|
260
262
|
*
|
|
261
263
|
* @throws if rendered outside a `RadioCard.Item`.
|
|
262
264
|
*/
|
|
263
|
-
function RadioCardIndicator({
|
|
265
|
+
export function RadioCardIndicator({
|
|
264
266
|
children,
|
|
265
267
|
forceMount,
|
|
266
268
|
asChild = false,
|
|
@@ -279,9 +281,12 @@ function RadioCardIndicator({
|
|
|
279
281
|
return <span {...indicatorProps}>{children}</span>;
|
|
280
282
|
}
|
|
281
283
|
|
|
284
|
+
/** @internal */
|
|
282
285
|
RadioCardIndicator.displayName = "RadioCardIndicator";
|
|
283
286
|
|
|
284
|
-
|
|
287
|
+
/** Type of the {@link RadioCard} compound: the callable `RadioCard.Root`
|
|
288
|
+
* component augmented with its sub-components as static properties. */
|
|
289
|
+
export type TRadioCardCompound = typeof RadioCardRoot & {
|
|
285
290
|
Root: typeof RadioCardRoot;
|
|
286
291
|
Item: typeof RadioCardItem;
|
|
287
292
|
Indicator: typeof RadioCardIndicator;
|
|
@@ -3,6 +3,9 @@ import { createStrictContext } from "../utils/index.ts";
|
|
|
3
3
|
|
|
4
4
|
import { RadioCardOrientation, RadioCardReadingDirection } from "./types";
|
|
5
5
|
|
|
6
|
+
/** The value shared by `RadioCard.Root` with its items through context: the
|
|
7
|
+
* current selection and setter, the item registry used for roving focus and
|
|
8
|
+
* keyboard navigation, and the resolved orientation/direction. */
|
|
6
9
|
export type RadioCardContextValue = {
|
|
7
10
|
value: string | undefined;
|
|
8
11
|
select: (value: string) => void;
|
|
@@ -22,7 +25,11 @@ const radioCardContextPair = createStrictContext<RadioCardContextValue>(
|
|
|
22
25
|
"RadioCard sub-components must be rendered inside a <RadioCard.Root>.",
|
|
23
26
|
);
|
|
24
27
|
|
|
28
|
+
/** Strict React context carrying the {@link RadioCardContextValue} from
|
|
29
|
+
* `RadioCard.Root` to its items. `null` when read outside a `RadioCard.Root`. */
|
|
25
30
|
export const RadioCardContext: Context<RadioCardContextValue | null> =
|
|
26
31
|
radioCardContextPair[0];
|
|
32
|
+
/** Reads the {@link RadioCardContextValue}; throws when used outside a
|
|
33
|
+
* `RadioCard.Root`. */
|
|
27
34
|
export const useRadioCardContext: () => RadioCardContextValue =
|
|
28
35
|
radioCardContextPair[1];
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { Context } from "react";
|
|
2
2
|
import { createStrictContext } from "../utils/index.ts";
|
|
3
3
|
|
|
4
|
+
/** The value shared by `RadioCard.Item` with its `RadioCard.Indicator`,
|
|
5
|
+
* exposing whether the item is currently selected. */
|
|
4
6
|
export type RadioCardItemContextValue = {
|
|
7
|
+
/** Whether the enclosing item is the selected card. */
|
|
5
8
|
checked: boolean;
|
|
6
9
|
};
|
|
7
10
|
|
|
@@ -9,7 +12,12 @@ const radioCardItemContextPair = createStrictContext<RadioCardItemContextValue>(
|
|
|
9
12
|
"RadioCard.Indicator must be rendered inside a <RadioCard.Item>.",
|
|
10
13
|
);
|
|
11
14
|
|
|
15
|
+
/** Strict React context carrying the {@link RadioCardItemContextValue} from
|
|
16
|
+
* `RadioCard.Item` to its indicator. `null` when read outside a
|
|
17
|
+
* `RadioCard.Item`. */
|
|
12
18
|
export const RadioCardItemContext: Context<RadioCardItemContextValue | null> =
|
|
13
19
|
radioCardItemContextPair[0];
|
|
20
|
+
/** Reads the {@link RadioCardItemContextValue}; throws when used outside a
|
|
21
|
+
* `RadioCard.Item`. */
|
|
14
22
|
export const useRadioCardItemContext: () => RadioCardItemContextValue =
|
|
15
23
|
radioCardItemContextPair[1];
|