@itwin/itwinui-react 5.0.0-alpha.11 → 5.0.0-alpha.13
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/CHANGELOG.md +28 -0
- package/README.md +13 -2
- package/dist/DEV/bricks/Checkbox.js +7 -14
- package/dist/DEV/bricks/Description.js +7 -14
- package/dist/DEV/bricks/DropdownMenu.js +68 -21
- package/dist/DEV/bricks/ErrorRegion.js +137 -0
- package/dist/DEV/bricks/Field.internal.js +47 -0
- package/dist/DEV/bricks/Field.js +120 -85
- package/dist/DEV/bricks/Icon.js +57 -0
- package/dist/DEV/bricks/IconButton.js +2 -5
- package/dist/DEV/bricks/Label.js +4 -10
- package/dist/DEV/bricks/Radio.js +7 -14
- package/dist/DEV/bricks/Select.js +9 -15
- package/dist/DEV/bricks/Switch.js +8 -15
- package/dist/DEV/bricks/Table.js +71 -37
- package/dist/DEV/bricks/Tabs.js +4 -29
- package/dist/DEV/bricks/TextBox.js +23 -37
- package/dist/DEV/bricks/Toolbar.js +25 -0
- package/dist/DEV/bricks/TreeItem.js +114 -42
- package/dist/DEV/bricks/index.js +9 -3
- package/dist/DEV/bricks/styles.css.js +1 -1
- package/dist/DEV/bricks/~utils.Dot.js +22 -0
- package/dist/DEV/foundations/styles.css.js +1 -1
- package/dist/bricks/Checkbox.d.ts +13 -5
- package/dist/bricks/Checkbox.js +7 -14
- package/dist/bricks/Description.d.ts +2 -6
- package/dist/bricks/Description.js +7 -14
- package/dist/bricks/DropdownMenu.d.ts +11 -9
- package/dist/bricks/DropdownMenu.js +67 -20
- package/dist/bricks/ErrorRegion.d.ts +88 -0
- package/dist/bricks/ErrorRegion.js +135 -0
- package/dist/bricks/Field.d.ts +69 -27
- package/dist/bricks/Field.internal.d.ts +33 -0
- package/dist/bricks/Field.internal.js +47 -0
- package/dist/bricks/Field.js +115 -84
- package/dist/bricks/Icon.d.ts +6 -0
- package/dist/bricks/Icon.js +55 -0
- package/dist/bricks/IconButton.js +2 -5
- package/dist/bricks/Label.d.ts +5 -12
- package/dist/bricks/Label.js +4 -10
- package/dist/bricks/ProgressBar.d.ts +7 -1
- package/dist/bricks/Radio.d.ts +14 -5
- package/dist/bricks/Radio.js +7 -14
- package/dist/bricks/Select.d.ts +29 -12
- package/dist/bricks/Select.js +9 -15
- package/dist/bricks/Switch.d.ts +12 -5
- package/dist/bricks/Switch.js +8 -15
- package/dist/bricks/Table.d.ts +94 -37
- package/dist/bricks/Table.js +69 -36
- package/dist/bricks/Tabs.d.ts +3 -4
- package/dist/bricks/Tabs.js +4 -29
- package/dist/bricks/TextBox.d.ts +42 -19
- package/dist/bricks/TextBox.js +23 -37
- package/dist/bricks/Toolbar.d.ts +35 -0
- package/dist/bricks/Toolbar.js +23 -0
- package/dist/bricks/TreeItem.d.ts +63 -9
- package/dist/bricks/TreeItem.js +103 -41
- package/dist/bricks/index.d.ts +5 -2
- package/dist/bricks/index.js +9 -3
- package/dist/bricks/styles.css.js +1 -1
- package/dist/bricks/~hooks.d.ts +1 -1
- package/dist/bricks/~utils.Dot.d.ts +11 -0
- package/dist/bricks/~utils.Dot.js +21 -0
- package/dist/foundations/styles.css.js +1 -1
- package/package.json +1 -1
|
@@ -24,8 +24,8 @@ interface DropdownMenuProps extends Pick<MenuProviderProps, "children" | "placem
|
|
|
24
24
|
*
|
|
25
25
|
* **Note**: `DropdownMenu` should not be used for navigation; it is only intended for actions.
|
|
26
26
|
*/
|
|
27
|
-
declare function
|
|
28
|
-
declare namespace
|
|
27
|
+
declare function DropdownMenuRoot(props: DropdownMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
declare namespace DropdownMenuRoot {
|
|
29
29
|
var displayName: string;
|
|
30
30
|
}
|
|
31
31
|
interface DropdownMenuContentProps extends FocusableProps {
|
|
@@ -56,9 +56,11 @@ interface DropdownMenuButtonProps extends FocusableProps<"button"> {
|
|
|
56
56
|
* ```
|
|
57
57
|
*/
|
|
58
58
|
declare const DropdownMenuButton: React.ForwardRefExoticComponent<DropdownMenuButtonProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
|
|
59
|
-
interface DropdownMenuItemProps extends Omit<FocusableProps
|
|
59
|
+
interface DropdownMenuItemProps extends Omit<FocusableProps<"button">, "children">, Partial<Pick<DropdownMenuItemShortcutsProps, "shortcuts"> & Pick<DropdownMenuIconProps, "icon">> {
|
|
60
60
|
/** The primary text label for the menu-item. */
|
|
61
61
|
label: React.ReactNode;
|
|
62
|
+
/** Dot shown on the right end of the menu-item. Value will be used as accessible description. */
|
|
63
|
+
unstable_dot?: string;
|
|
62
64
|
}
|
|
63
65
|
/**
|
|
64
66
|
* A single menu item within the dropdown menu. Should be used as a child of `DropdownMenu.Content`.
|
|
@@ -69,8 +71,8 @@ interface DropdownMenuItemProps extends Omit<FocusableProps, "children">, Partia
|
|
|
69
71
|
* <DropdownMenu.Item label="Edit" />
|
|
70
72
|
* ```
|
|
71
73
|
*/
|
|
72
|
-
declare const DropdownMenuItem: React.ForwardRefExoticComponent<DropdownMenuItemProps & React.RefAttributes<HTMLElement |
|
|
73
|
-
interface DropdownMenuItemShortcutsProps extends BaseProps {
|
|
74
|
+
declare const DropdownMenuItem: React.ForwardRefExoticComponent<DropdownMenuItemProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
|
|
75
|
+
interface DropdownMenuItemShortcutsProps extends Omit<BaseProps<"span">, "children"> {
|
|
74
76
|
/**
|
|
75
77
|
* A string defining the keyboard shortcut(s) associated with the menu item.
|
|
76
78
|
*
|
|
@@ -87,7 +89,7 @@ interface DropdownMenuItemShortcutsProps extends BaseProps {
|
|
|
87
89
|
*/
|
|
88
90
|
shortcuts: AnyString | `${PredefinedSymbol}+${AnyString}`;
|
|
89
91
|
}
|
|
90
|
-
interface DropdownMenuIconProps extends BaseProps {
|
|
92
|
+
interface DropdownMenuIconProps extends BaseProps<"svg"> {
|
|
91
93
|
/**
|
|
92
94
|
* An optional icon displayed before the menu-item label.
|
|
93
95
|
*
|
|
@@ -96,7 +98,7 @@ interface DropdownMenuIconProps extends BaseProps {
|
|
|
96
98
|
*/
|
|
97
99
|
icon?: string | React.JSX.Element;
|
|
98
100
|
}
|
|
99
|
-
interface DropdownMenuCheckboxItemProps extends Omit<FocusableProps
|
|
101
|
+
interface DropdownMenuCheckboxItemProps extends Omit<FocusableProps<"button">, "onChange" | "children" | "name">, Pick<MenuItemCheckboxProps, "defaultChecked" | "checked" | "onChange" | "name" | "value">, Pick<DropdownMenuItemProps, "label" | "icon"> {
|
|
100
102
|
}
|
|
101
103
|
/**
|
|
102
104
|
* A single menu item within the dropdown menu. Should be used as a child of `DropdownMenu.Content`.
|
|
@@ -107,5 +109,5 @@ interface DropdownMenuCheckboxItemProps extends Omit<FocusableProps, "onChange"
|
|
|
107
109
|
* <DropdownMenu.CheckboxItem name="edit" label="Edit" />
|
|
108
110
|
* ```
|
|
109
111
|
*/
|
|
110
|
-
declare const DropdownMenuCheckboxItem: React.ForwardRefExoticComponent<DropdownMenuCheckboxItemProps & React.RefAttributes<HTMLElement |
|
|
111
|
-
export {
|
|
112
|
+
declare const DropdownMenuCheckboxItem: React.ForwardRefExoticComponent<DropdownMenuCheckboxItemProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
|
|
113
|
+
export { DropdownMenuRoot as Root, DropdownMenuButton as Button, DropdownMenuContent as Content, DropdownMenuItem as Item, DropdownMenuCheckboxItem as CheckboxItem, };
|
|
@@ -3,6 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import cx from "classnames";
|
|
4
4
|
import * as ListItem from "./~utils.ListItem.js";
|
|
5
5
|
import { Button } from "./Button.js";
|
|
6
|
+
import { Button as ButtonAk } from "@ariakit/react/button";
|
|
6
7
|
import { Kbd } from "./Kbd.js";
|
|
7
8
|
import { Checkmark, DisclosureArrow, Icon } from "./Icon.js";
|
|
8
9
|
import {
|
|
@@ -19,7 +20,9 @@ import {
|
|
|
19
20
|
} from "@ariakit/react/menu";
|
|
20
21
|
import { useStoreState } from "@ariakit/react/store";
|
|
21
22
|
import { predefinedSymbols } from "./Kbd.internal.js";
|
|
22
|
-
|
|
23
|
+
import { usePopoverContext } from "@ariakit/react/popover";
|
|
24
|
+
import { Dot } from "./~utils.Dot.js";
|
|
25
|
+
function DropdownMenuRoot(props) {
|
|
23
26
|
const {
|
|
24
27
|
children,
|
|
25
28
|
placement,
|
|
@@ -34,6 +37,7 @@ function DropdownMenu(props) {
|
|
|
34
37
|
defaultOpen: defaultOpenProp,
|
|
35
38
|
open: openProp,
|
|
36
39
|
setOpen: setOpenProp,
|
|
40
|
+
popover: usePopoverContext(),
|
|
37
41
|
children
|
|
38
42
|
}
|
|
39
43
|
);
|
|
@@ -78,19 +82,37 @@ const DropdownMenuButton = forwardRef(
|
|
|
78
82
|
);
|
|
79
83
|
const DropdownMenuItem = forwardRef(
|
|
80
84
|
(props, forwardedRef) => {
|
|
81
|
-
const { label, shortcuts, icon, ...rest } = props;
|
|
85
|
+
const { label, shortcuts, icon, unstable_dot, ...rest } = props;
|
|
86
|
+
const dotId = React.useId();
|
|
82
87
|
return /* @__PURE__ */ jsxs(
|
|
83
88
|
MenuItem,
|
|
84
89
|
{
|
|
85
90
|
accessibleWhenDisabled: true,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
render: /* @__PURE__ */ jsx(
|
|
92
|
+
ListItem.Root,
|
|
93
|
+
{
|
|
94
|
+
render: /* @__PURE__ */ jsx(
|
|
95
|
+
ButtonAk,
|
|
96
|
+
{
|
|
97
|
+
accessibleWhenDisabled: true,
|
|
98
|
+
"aria-describedby": dotId,
|
|
99
|
+
...rest,
|
|
100
|
+
className: cx("\u{1F95D}-dropdown-menu-item", props.className),
|
|
101
|
+
ref: forwardedRef
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
),
|
|
90
106
|
children: [
|
|
91
107
|
icon ? /* @__PURE__ */ jsx(DropdownMenuIcon, { icon }) : null,
|
|
92
|
-
/* @__PURE__ */ jsx(ListItem.Content, { children: label }),
|
|
93
|
-
shortcuts ? /* @__PURE__ */ jsx(DropdownMenuItemShortcuts, { shortcuts }) : null
|
|
108
|
+
/* @__PURE__ */ jsx(ListItem.Content, { render: /* @__PURE__ */ jsx("span", {}), children: label }),
|
|
109
|
+
shortcuts ? /* @__PURE__ */ jsx(DropdownMenuItemShortcuts, { shortcuts }) : null,
|
|
110
|
+
unstable_dot ? /* @__PURE__ */ jsx(
|
|
111
|
+
ListItem.Decoration,
|
|
112
|
+
{
|
|
113
|
+
render: /* @__PURE__ */ jsx(Dot, { id: dotId, className: "\u{1F95D}-dropdown-menu-item-dot", children: unstable_dot })
|
|
114
|
+
}
|
|
115
|
+
) : null
|
|
94
116
|
]
|
|
95
117
|
}
|
|
96
118
|
);
|
|
@@ -107,6 +129,7 @@ const DropdownMenuItemShortcuts = forwardRef((props, forwardedRef) => {
|
|
|
107
129
|
return /* @__PURE__ */ jsx(
|
|
108
130
|
ListItem.Decoration,
|
|
109
131
|
{
|
|
132
|
+
render: /* @__PURE__ */ jsx("span", {}),
|
|
110
133
|
...rest,
|
|
111
134
|
className: cx("\u{1F95D}-dropdown-menu-item-shortcuts", props.className),
|
|
112
135
|
ref: forwardedRef,
|
|
@@ -136,29 +159,53 @@ const DropdownMenuIcon = forwardRef(
|
|
|
136
159
|
Icon,
|
|
137
160
|
{
|
|
138
161
|
href: typeof icon === "string" ? icon : void 0,
|
|
139
|
-
render: React.isValidElement(icon) ? icon : void 0
|
|
162
|
+
render: React.isValidElement(icon) ? icon : void 0,
|
|
163
|
+
...rest,
|
|
164
|
+
ref: forwardedRef
|
|
140
165
|
}
|
|
141
|
-
)
|
|
142
|
-
...rest,
|
|
143
|
-
ref: forwardedRef
|
|
166
|
+
)
|
|
144
167
|
}
|
|
145
168
|
);
|
|
146
169
|
}
|
|
147
170
|
);
|
|
148
171
|
const DropdownMenuCheckboxItem = forwardRef((props, forwardedRef) => {
|
|
149
|
-
const {
|
|
172
|
+
const {
|
|
173
|
+
label,
|
|
174
|
+
icon,
|
|
175
|
+
defaultChecked,
|
|
176
|
+
checked,
|
|
177
|
+
onChange,
|
|
178
|
+
name,
|
|
179
|
+
value = defaultChecked ? "on" : void 0,
|
|
180
|
+
// For defaultChecked to work
|
|
181
|
+
...rest
|
|
182
|
+
} = props;
|
|
150
183
|
return /* @__PURE__ */ jsxs(
|
|
151
184
|
MenuItemCheckbox,
|
|
152
185
|
{
|
|
153
186
|
accessibleWhenDisabled: true,
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
187
|
+
defaultChecked,
|
|
188
|
+
checked,
|
|
189
|
+
name,
|
|
190
|
+
value,
|
|
191
|
+
onChange,
|
|
192
|
+
render: /* @__PURE__ */ jsx(
|
|
193
|
+
ListItem.Root,
|
|
194
|
+
{
|
|
195
|
+
render: /* @__PURE__ */ jsx(
|
|
196
|
+
ButtonAk,
|
|
197
|
+
{
|
|
198
|
+
accessibleWhenDisabled: true,
|
|
199
|
+
...rest,
|
|
200
|
+
className: cx("\u{1F95D}-dropdown-menu-item", props.className),
|
|
201
|
+
ref: forwardedRef
|
|
202
|
+
}
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
),
|
|
159
206
|
children: [
|
|
160
207
|
icon ? /* @__PURE__ */ jsx(DropdownMenuIcon, { icon }) : null,
|
|
161
|
-
/* @__PURE__ */ jsx(ListItem.Content, { children: label }),
|
|
208
|
+
/* @__PURE__ */ jsx(ListItem.Content, { render: /* @__PURE__ */ jsx("span", {}), children: label }),
|
|
162
209
|
/* @__PURE__ */ jsx(
|
|
163
210
|
ListItem.Decoration,
|
|
164
211
|
{
|
|
@@ -174,5 +221,5 @@ export {
|
|
|
174
221
|
DropdownMenuCheckboxItem as CheckboxItem,
|
|
175
222
|
DropdownMenuContent as Content,
|
|
176
223
|
DropdownMenuItem as Item,
|
|
177
|
-
|
|
224
|
+
DropdownMenuRoot as Root
|
|
178
225
|
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type BaseProps } from "./~utils.js";
|
|
3
|
+
interface ErrorRegionRootProps extends Omit<BaseProps, "children"> {
|
|
4
|
+
/**
|
|
5
|
+
* Label for the error header, usually indicating the number of errors displayed.
|
|
6
|
+
* By default this is used as a name of the region navigational landmark, however an explicit `aria-label` or `aria-labelledby` is strongly suggested.
|
|
7
|
+
*
|
|
8
|
+
* Use `undefined` if you don't want to display errors rather than conditionally rendering the component.
|
|
9
|
+
*/
|
|
10
|
+
label?: React.ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* A list of error items where each item describes an individual error. Must be a list of `ErrorRegion.Item` components.
|
|
13
|
+
*/
|
|
14
|
+
items?: React.ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* The controlled expanded state of the error.
|
|
17
|
+
*/
|
|
18
|
+
expanded?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Callback fired when the error is expanded.
|
|
21
|
+
*
|
|
22
|
+
* Should be used with the `expanded` prop.
|
|
23
|
+
*/
|
|
24
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A collapsible region that displays a list of error messages, which might originate from another
|
|
28
|
+
* component, such as `Tree`.
|
|
29
|
+
*
|
|
30
|
+
* This component is rendered as a [region landmark](https://www.w3.org/WAI/ARIA/apg/patterns/landmarks/examples/region.html)
|
|
31
|
+
* and should be labelled either using `label` or `aria-label`/`aria-labelledby`. Changes to the `label` prop will be
|
|
32
|
+
* announced communicated using a [live region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions).
|
|
33
|
+
*
|
|
34
|
+
* Example:
|
|
35
|
+
* ```tsx
|
|
36
|
+
* <ErrorRegion.Root
|
|
37
|
+
* label="3 issues found"
|
|
38
|
+
* items={
|
|
39
|
+
* <>
|
|
40
|
+
* <ErrorRegion.Item message="…" />
|
|
41
|
+
* <ErrorRegion.Item message="…" />
|
|
42
|
+
* <ErrorRegion.Item message="…" />
|
|
43
|
+
* </>
|
|
44
|
+
* }
|
|
45
|
+
* />
|
|
46
|
+
*/
|
|
47
|
+
declare const ErrorRegionRoot: React.ForwardRefExoticComponent<ErrorRegionRootProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
|
|
48
|
+
interface ErrorRegionItemProps extends Omit<BaseProps, "children"> {
|
|
49
|
+
/**
|
|
50
|
+
* The error message. Consumers might consider using `Anchor` component to link to the associated element in the UI.
|
|
51
|
+
*/
|
|
52
|
+
message?: React.ReactNode;
|
|
53
|
+
/**
|
|
54
|
+
* The `id` of the message node which can be used to semantically associate the error item with the related UI item i.e. `Tree.Item`.
|
|
55
|
+
*/
|
|
56
|
+
messageId?: string;
|
|
57
|
+
/**
|
|
58
|
+
* The actions available for this item. Must be a list of anchors, each rendered as a button using `<Anchor render={<button />} />`.
|
|
59
|
+
*/
|
|
60
|
+
actions?: React.ReactNode;
|
|
61
|
+
/**
|
|
62
|
+
* Callback fired when the error item is dismissed.
|
|
63
|
+
*/
|
|
64
|
+
onDismiss?: () => void;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* An individual error item within the `ErrorRegion` component. It displays an error message and optional actions.
|
|
68
|
+
*
|
|
69
|
+
* The `messageId` prop can be used to semantically associate the error item with the related UI item, such as a `Tree.Item`.
|
|
70
|
+
*
|
|
71
|
+
* Example:
|
|
72
|
+
* ```tsx
|
|
73
|
+
* <ErrorRegion.Item
|
|
74
|
+
* message={<>Something went wrong with <Anchor href="item-10001">Item 10001</Anchor>.</>}
|
|
75
|
+
* messageId="item-10001-error"
|
|
76
|
+
* actions={<Button>Retry</Button>}
|
|
77
|
+
* onDismiss={() => {}}
|
|
78
|
+
* />
|
|
79
|
+
*
|
|
80
|
+
* <Tree.Item
|
|
81
|
+
* id="item-10001"
|
|
82
|
+
* label="Item 10001"
|
|
83
|
+
* error="item-10001-error"
|
|
84
|
+
* />
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
declare const ErrorRegionItem: React.ForwardRefExoticComponent<ErrorRegionItemProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
|
|
88
|
+
export { ErrorRegionRoot as Root, ErrorRegionItem as Item };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import cx from "classnames";
|
|
4
|
+
import {
|
|
5
|
+
DialogProvider,
|
|
6
|
+
DialogDisclosure,
|
|
7
|
+
Dialog
|
|
8
|
+
} from "@ariakit/react/dialog";
|
|
9
|
+
import { Role } from "@ariakit/react/role";
|
|
10
|
+
import { forwardRef } from "./~utils.js";
|
|
11
|
+
import { ChevronDown, Dismiss, StatusWarning } from "./Icon.js";
|
|
12
|
+
import { Text } from "./Text.js";
|
|
13
|
+
import { IconButton } from "./IconButton.js";
|
|
14
|
+
import { Button } from "./Button.js";
|
|
15
|
+
import { useControlledState } from "./~hooks.js";
|
|
16
|
+
import { VisuallyHidden } from "./VisuallyHidden.js";
|
|
17
|
+
const ErrorRegionRoot = forwardRef(
|
|
18
|
+
(props, forwardedRef) => {
|
|
19
|
+
const { label, items, expanded, onExpandedChange, ...rest } = props;
|
|
20
|
+
const labelId = React.useId();
|
|
21
|
+
const sectionLabelledBy = props["aria-labelledby"] ?? (props["aria-label"] ? void 0 : labelId);
|
|
22
|
+
const [open, setOpen] = useControlledState(
|
|
23
|
+
false,
|
|
24
|
+
expanded,
|
|
25
|
+
onExpandedChange
|
|
26
|
+
);
|
|
27
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "polite", "aria-atomic": true, children: label }),
|
|
29
|
+
/* @__PURE__ */ jsx(DialogProvider, { open, setOpen, children: /* @__PURE__ */ jsx(
|
|
30
|
+
Role.section,
|
|
31
|
+
{
|
|
32
|
+
...rest,
|
|
33
|
+
"aria-labelledby": sectionLabelledBy,
|
|
34
|
+
className: cx("\u{1F95D}-error-region", props.className),
|
|
35
|
+
"data-kiwi-visible": !!label,
|
|
36
|
+
"data-kiwi-expanded": open,
|
|
37
|
+
ref: forwardedRef,
|
|
38
|
+
children: /* @__PURE__ */ jsxs("div", { className: "\u{1F95D}-error-region-container", children: [
|
|
39
|
+
/* @__PURE__ */ jsxs(
|
|
40
|
+
DialogDisclosure,
|
|
41
|
+
{
|
|
42
|
+
className: "\u{1F95D}-error-region-header",
|
|
43
|
+
render: /* @__PURE__ */ jsx(Button, { variant: "ghost" }),
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx(StatusWarning, { className: "\u{1F95D}-error-region-icon" }),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
Text,
|
|
48
|
+
{
|
|
49
|
+
id: labelId,
|
|
50
|
+
className: "\u{1F95D}-error-region-label",
|
|
51
|
+
variant: "body-sm",
|
|
52
|
+
children: label
|
|
53
|
+
}
|
|
54
|
+
),
|
|
55
|
+
/* @__PURE__ */ jsx(
|
|
56
|
+
IconButton,
|
|
57
|
+
{
|
|
58
|
+
inert: true,
|
|
59
|
+
render: /* @__PURE__ */ jsx("span", {}),
|
|
60
|
+
role: void 0,
|
|
61
|
+
label: "",
|
|
62
|
+
icon: /* @__PURE__ */ jsx(ChevronDown, {}),
|
|
63
|
+
variant: "ghost"
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
/* @__PURE__ */ jsx(
|
|
70
|
+
Dialog,
|
|
71
|
+
{
|
|
72
|
+
className: "\u{1F95D}-error-region-dialog",
|
|
73
|
+
portal: false,
|
|
74
|
+
modal: false,
|
|
75
|
+
autoFocusOnShow: false,
|
|
76
|
+
"aria-labelledby": labelId,
|
|
77
|
+
children: /* @__PURE__ */ jsx("div", { className: "\u{1F95D}-error-region-items", role: "list", children: items })
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
] })
|
|
81
|
+
}
|
|
82
|
+
) })
|
|
83
|
+
] });
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
const ErrorRegionItem = forwardRef(
|
|
87
|
+
(props, forwardedRef) => {
|
|
88
|
+
const generatedId = React.useId();
|
|
89
|
+
const {
|
|
90
|
+
message,
|
|
91
|
+
messageId = `${generatedId}-message`,
|
|
92
|
+
actions,
|
|
93
|
+
onDismiss,
|
|
94
|
+
...rest
|
|
95
|
+
} = props;
|
|
96
|
+
const dismissButtonId = `${generatedId}-dismiss`;
|
|
97
|
+
return /* @__PURE__ */ jsxs(
|
|
98
|
+
Role.div,
|
|
99
|
+
{
|
|
100
|
+
...rest,
|
|
101
|
+
role: "listitem",
|
|
102
|
+
className: cx("\u{1F95D}-error-region-item", props.className),
|
|
103
|
+
ref: forwardedRef,
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ jsx(
|
|
106
|
+
Text,
|
|
107
|
+
{
|
|
108
|
+
id: messageId,
|
|
109
|
+
variant: "body-sm",
|
|
110
|
+
className: "\u{1F95D}-error-region-item-message",
|
|
111
|
+
children: message
|
|
112
|
+
}
|
|
113
|
+
),
|
|
114
|
+
onDismiss && /* @__PURE__ */ jsx(
|
|
115
|
+
IconButton,
|
|
116
|
+
{
|
|
117
|
+
id: dismissButtonId,
|
|
118
|
+
className: "\u{1F95D}-error-region-item-dismiss",
|
|
119
|
+
variant: "ghost",
|
|
120
|
+
label: "Dismiss",
|
|
121
|
+
"aria-labelledby": `${dismissButtonId} ${messageId}`,
|
|
122
|
+
icon: /* @__PURE__ */ jsx(Dismiss, {}),
|
|
123
|
+
onClick: onDismiss
|
|
124
|
+
}
|
|
125
|
+
),
|
|
126
|
+
/* @__PURE__ */ jsx("div", { className: "\u{1F95D}-error-region-item-actions", children: actions })
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
export {
|
|
133
|
+
ErrorRegionItem as Item,
|
|
134
|
+
ErrorRegionRoot as Root
|
|
135
|
+
};
|
package/dist/bricks/Field.d.ts
CHANGED
|
@@ -1,53 +1,95 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { type CollectionItemProps } from "@ariakit/react/collection";
|
|
3
3
|
import { type BaseProps } from "./~utils.js";
|
|
4
|
-
interface
|
|
4
|
+
interface FieldRootProps extends BaseProps {
|
|
5
5
|
/**
|
|
6
6
|
* Allows overriding the default block layout for text controls.
|
|
7
7
|
*/
|
|
8
8
|
layout?: "inline";
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* A container for form controls. It manages ID associations provides a
|
|
11
|
+
* A container for form controls. It manages ID associations, and provides a
|
|
12
|
+
* consistent layout and spacing.
|
|
12
13
|
*
|
|
13
14
|
* Example:
|
|
14
15
|
* ```tsx
|
|
15
|
-
* <Field>
|
|
16
|
-
* <Label>Label</Label>
|
|
17
|
-
* <TextBox.Input />
|
|
18
|
-
* </Field>
|
|
16
|
+
* <Field.Root>
|
|
17
|
+
* <Field.Label>Label</Field.Label>
|
|
18
|
+
* <Field.Control render={<TextBox.Input />} />
|
|
19
|
+
* </Field.Root>
|
|
19
20
|
* ```
|
|
20
21
|
*
|
|
21
|
-
* Supports a `layout` prop, which can be set to `inline` to align the label and
|
|
22
|
+
* Supports a `layout` prop, which can be set to `inline` to align the label and
|
|
23
|
+
* control horizontally.
|
|
22
24
|
*
|
|
23
|
-
* Should contain a `Label` component paired with a form control.
|
|
25
|
+
* Should contain a `Field.Label` component paired with a form control.
|
|
26
|
+
*
|
|
27
|
+
* Supported form controls include:
|
|
24
28
|
* - `TextBox.Input`
|
|
25
29
|
* - `TextBox.Textarea`
|
|
26
30
|
* - `Checkbox`
|
|
27
31
|
* - `Radio`
|
|
28
32
|
* - `Switch`
|
|
29
33
|
*/
|
|
30
|
-
|
|
31
|
-
type CollectionStoreItem = NonNullable<ReturnType<ReturnType<typeof useCollectionStore>["item"]>>;
|
|
32
|
-
interface FieldCollectionStoreItem extends CollectionStoreItem {
|
|
33
|
-
/** The type of field element being tracked */
|
|
34
|
-
elementType: "label" | "control" | "description";
|
|
35
|
-
/** If a control, the type of control. */
|
|
36
|
-
controlType?: "textlike" | "checkable";
|
|
37
|
-
}
|
|
38
|
-
interface FieldCollectionItemControlProps extends Pick<CollectionItemProps, "render" | "id"> {
|
|
39
|
-
type: FieldCollectionStoreItem["controlType"];
|
|
40
|
-
}
|
|
34
|
+
declare const FieldRoot: React.ForwardRefExoticComponent<FieldRootProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
|
|
41
35
|
/**
|
|
42
|
-
*
|
|
36
|
+
* A label for the field’s control element. This is automatically associated
|
|
37
|
+
* with the control’s `id`.
|
|
43
38
|
*/
|
|
44
|
-
|
|
39
|
+
declare const FieldLabel: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
|
|
45
40
|
/**
|
|
46
|
-
*
|
|
41
|
+
* A description for the field’s control element. This is automatically
|
|
42
|
+
* associated with the control.
|
|
43
|
+
*
|
|
44
|
+
* Should not include content without an adequate text alternative (e.g.
|
|
45
|
+
* interactive elements).
|
|
47
46
|
*/
|
|
48
|
-
|
|
47
|
+
declare const FieldDescription: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
|
|
48
|
+
interface FieldCollectionItemControlProps extends Pick<CollectionItemProps, "render" | "id"> {
|
|
49
|
+
}
|
|
49
50
|
/**
|
|
50
|
-
*
|
|
51
|
+
* The control component for the field.
|
|
52
|
+
*
|
|
53
|
+
* Use the `render` prop to render the control component.
|
|
54
|
+
*
|
|
55
|
+
* ```tsx
|
|
56
|
+
* <Field.Control render={<TextBox.Input />} />
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* If the rendered component uses a compositional API, then use a function
|
|
60
|
+
* within `render` to apply the `controlProps` to the correct sub-component:
|
|
61
|
+
*
|
|
62
|
+
* ```tsx
|
|
63
|
+
* <Field.Control
|
|
64
|
+
* render={(controlProps) => (
|
|
65
|
+
* <TextBox.Root>
|
|
66
|
+
* <TextBox.Icon href={placeholder} />
|
|
67
|
+
* <TextBox.Input {...controlProps} />
|
|
68
|
+
* </TextBox.Root>
|
|
69
|
+
* )}
|
|
70
|
+
* />
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* If you need a custom `id` set for the control, set it on this component
|
|
74
|
+
* instead of the control component within `render`.
|
|
75
|
+
*
|
|
76
|
+
* ```tsx
|
|
77
|
+
* <Field.Control id="custom" render={<TextBox.Input />} />
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
declare const FieldControl: React.ForwardRefExoticComponent<FieldCollectionItemControlProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
|
|
81
|
+
/**
|
|
82
|
+
* An associated error message for a field. When used within `<Field.Root>`, the
|
|
83
|
+
* associated form control will be rendered with `aria-invalid="true"`.
|
|
84
|
+
*
|
|
85
|
+
* Example:
|
|
86
|
+
* ```tsx
|
|
87
|
+
* <Field.Root>
|
|
88
|
+
* <Field.Label>Label</Field.Label>
|
|
89
|
+
* <Field.Control render={<TextBox.Input />} />
|
|
90
|
+
* <Field.ErrorMessage>Something is wrong!</Field.ErrorMessage>
|
|
91
|
+
* </Field.Root>
|
|
92
|
+
* ```
|
|
51
93
|
*/
|
|
52
|
-
|
|
53
|
-
export {};
|
|
94
|
+
declare const FieldErrorMessage: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
|
|
95
|
+
export { FieldRoot as Root, FieldControl as Control, FieldLabel as Label, FieldDescription as Description, FieldErrorMessage as ErrorMessage, };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useCollectionStore, type CollectionProps } from "@ariakit/react/collection";
|
|
3
|
+
/**
|
|
4
|
+
* Ariakit’s unexported `CollectionStoreItem` type inferred.
|
|
5
|
+
* @private
|
|
6
|
+
*/
|
|
7
|
+
export type CollectionStoreItem = NonNullable<ReturnType<ReturnType<typeof useCollectionStore>["item"]>>;
|
|
8
|
+
/**
|
|
9
|
+
* An extension of `CollectionStoreItem` to track element and control types.
|
|
10
|
+
* @private
|
|
11
|
+
*/
|
|
12
|
+
export interface FieldCollectionStoreItem extends CollectionStoreItem {
|
|
13
|
+
/** The type of field element being tracked */
|
|
14
|
+
elementType: "label" | "control" | "description" | "error";
|
|
15
|
+
/** If a control, the type of control. */
|
|
16
|
+
controlType?: "textlike" | "checkable";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A collection that tracks labels, controls, and descriptions which provides
|
|
20
|
+
* information about IDs, placement of labels, and control types.
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
export declare function FieldCollection(props: Pick<CollectionProps, "render">): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
/**
|
|
25
|
+
* Control type context for the field.
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
export declare const FieldControlTypeContext: React.Context<React.Dispatch<React.SetStateAction<"textlike" | "checkable" | undefined>> | undefined>;
|
|
29
|
+
/**
|
|
30
|
+
* Sets the control type for the field. Necessary for layout.
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
export declare function useFieldControlType(controlType: NonNullable<FieldCollectionStoreItem["controlType"]>): void;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import {
|
|
4
|
+
useCollectionStore,
|
|
5
|
+
Collection
|
|
6
|
+
} from "@ariakit/react/collection";
|
|
7
|
+
import { useStoreState } from "@ariakit/react/store";
|
|
8
|
+
function FieldCollection(props) {
|
|
9
|
+
const fieldElementCollection = useCollectionStore({
|
|
10
|
+
defaultItems: []
|
|
11
|
+
});
|
|
12
|
+
const renderedItems = useStoreState(fieldElementCollection, "renderedItems");
|
|
13
|
+
const [controlType, controlIndex] = React.useMemo(() => {
|
|
14
|
+
const controlIndex2 = renderedItems.findIndex(
|
|
15
|
+
(item) => item.elementType === "control"
|
|
16
|
+
);
|
|
17
|
+
return [renderedItems[controlIndex2]?.controlType, controlIndex2];
|
|
18
|
+
}, [renderedItems]);
|
|
19
|
+
const labelPlacement = React.useMemo(() => {
|
|
20
|
+
const labelIndex = renderedItems.findIndex(
|
|
21
|
+
(item) => item.elementType === "label"
|
|
22
|
+
);
|
|
23
|
+
if (controlIndex === -1 || labelIndex === -1) return;
|
|
24
|
+
return labelIndex < controlIndex ? "before" : "after";
|
|
25
|
+
}, [renderedItems, controlIndex]);
|
|
26
|
+
return /* @__PURE__ */ jsx(
|
|
27
|
+
Collection,
|
|
28
|
+
{
|
|
29
|
+
...props,
|
|
30
|
+
store: fieldElementCollection,
|
|
31
|
+
"data-kiwi-label-placement": labelPlacement,
|
|
32
|
+
"data-kiwi-control-type": controlType
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
const FieldControlTypeContext = React.createContext(void 0);
|
|
37
|
+
function useFieldControlType(controlType) {
|
|
38
|
+
const setControlType = React.useContext(FieldControlTypeContext);
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
setControlType?.(controlType);
|
|
41
|
+
}, [controlType, setControlType]);
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
FieldCollection,
|
|
45
|
+
FieldControlTypeContext,
|
|
46
|
+
useFieldControlType
|
|
47
|
+
};
|