@itwin/itwinui-react 5.0.0-alpha.0 → 5.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +6 -6
  3. package/dist/DEV/bricks/Anchor.js +16 -23
  4. package/dist/DEV/bricks/Avatar.js +24 -0
  5. package/dist/DEV/bricks/Badge.js +22 -0
  6. package/dist/DEV/bricks/Button.js +25 -16
  7. package/dist/DEV/bricks/Checkbox.js +26 -16
  8. package/dist/DEV/bricks/Chip.js +42 -0
  9. package/dist/DEV/bricks/Description.js +29 -0
  10. package/dist/DEV/bricks/Divider.js +16 -17
  11. package/dist/DEV/bricks/DropdownMenu.js +143 -48
  12. package/dist/DEV/bricks/Field.js +120 -20
  13. package/dist/DEV/bricks/Icon.js +108 -45
  14. package/dist/DEV/bricks/IconButton.js +31 -18
  15. package/dist/DEV/bricks/Kbd.internal.js +19 -0
  16. package/dist/DEV/bricks/Kbd.js +32 -17
  17. package/dist/DEV/bricks/Label.js +13 -10
  18. package/dist/DEV/bricks/ProgressBar.js +25 -0
  19. package/dist/DEV/bricks/Radio.js +19 -11
  20. package/dist/DEV/bricks/Root.js +78 -45
  21. package/dist/DEV/bricks/Select.js +61 -0
  22. package/dist/DEV/bricks/Skeleton.js +24 -0
  23. package/dist/DEV/bricks/Spinner.js +40 -0
  24. package/dist/DEV/bricks/Switch.js +27 -17
  25. package/dist/DEV/bricks/Table.js +114 -0
  26. package/dist/DEV/bricks/Tabs.js +19 -20
  27. package/dist/DEV/bricks/Text.js +20 -0
  28. package/dist/DEV/bricks/TextBox.js +95 -50
  29. package/dist/DEV/bricks/Tooltip.js +58 -58
  30. package/dist/DEV/bricks/Tree.js +16 -102
  31. package/dist/DEV/bricks/TreeItem.js +224 -0
  32. package/dist/DEV/bricks/VisuallyHidden.js +7 -5
  33. package/dist/DEV/bricks/index.js +20 -0
  34. package/dist/DEV/bricks/styles.css.js +2 -2
  35. package/dist/DEV/bricks/~hooks.js +55 -3
  36. package/dist/DEV/bricks/~utils.GhostAligner.js +13 -0
  37. package/dist/DEV/bricks/~utils.ListItem.js +49 -0
  38. package/dist/DEV/bricks/~utils.js +3 -0
  39. package/dist/DEV/foundations/styles.css.js +2 -2
  40. package/dist/bricks/Anchor.d.ts +12 -3
  41. package/dist/bricks/Anchor.js +16 -23
  42. package/dist/bricks/Avatar.d.ts +47 -0
  43. package/dist/bricks/Avatar.js +23 -0
  44. package/dist/bricks/Badge.d.ts +28 -0
  45. package/dist/bricks/Badge.js +21 -0
  46. package/dist/bricks/Button.d.ts +27 -4
  47. package/dist/bricks/Button.js +25 -16
  48. package/dist/bricks/Checkbox.d.ts +19 -5
  49. package/dist/bricks/Checkbox.js +26 -16
  50. package/dist/bricks/Chip.d.ts +31 -0
  51. package/dist/bricks/Chip.js +41 -0
  52. package/dist/bricks/Description.d.ts +19 -0
  53. package/dist/bricks/Description.js +29 -0
  54. package/dist/bricks/Divider.d.ts +5 -6
  55. package/dist/bricks/Divider.js +16 -17
  56. package/dist/bricks/DropdownMenu.d.ts +92 -15
  57. package/dist/bricks/DropdownMenu.js +138 -46
  58. package/dist/bricks/Field.d.ts +45 -3
  59. package/dist/bricks/Field.js +120 -20
  60. package/dist/bricks/Icon.d.ts +38 -7
  61. package/dist/bricks/Icon.js +105 -44
  62. package/dist/bricks/IconButton.d.ts +20 -4
  63. package/dist/bricks/IconButton.js +31 -18
  64. package/dist/bricks/Kbd.d.ts +17 -3
  65. package/dist/bricks/Kbd.internal.d.ts +17 -0
  66. package/dist/bricks/Kbd.internal.js +19 -0
  67. package/dist/bricks/Kbd.js +25 -17
  68. package/dist/bricks/Label.d.ts +22 -3
  69. package/dist/bricks/Label.js +13 -10
  70. package/dist/bricks/ProgressBar.d.ts +31 -0
  71. package/dist/bricks/ProgressBar.js +24 -0
  72. package/dist/bricks/Radio.d.ts +19 -5
  73. package/dist/bricks/Radio.js +19 -11
  74. package/dist/bricks/Root.d.ts +11 -2
  75. package/dist/bricks/Root.js +78 -45
  76. package/dist/bricks/Select.d.ts +51 -0
  77. package/dist/bricks/Select.js +61 -0
  78. package/dist/bricks/Skeleton.d.ts +25 -0
  79. package/dist/bricks/Skeleton.js +23 -0
  80. package/dist/bricks/Spinner.d.ts +31 -0
  81. package/dist/bricks/Spinner.js +39 -0
  82. package/dist/bricks/Switch.d.ts +19 -5
  83. package/dist/bricks/Switch.js +27 -17
  84. package/dist/bricks/Table.d.ts +115 -0
  85. package/dist/bricks/Table.js +108 -0
  86. package/dist/bricks/Tabs.d.ts +69 -8
  87. package/dist/bricks/Tabs.js +19 -20
  88. package/dist/bricks/Text.d.ts +22 -0
  89. package/dist/bricks/Text.js +19 -0
  90. package/dist/bricks/TextBox.d.ts +62 -11
  91. package/dist/bricks/TextBox.js +94 -50
  92. package/dist/bricks/Tooltip.d.ts +13 -6
  93. package/dist/bricks/Tooltip.js +58 -58
  94. package/dist/bricks/Tree.d.ts +20 -21
  95. package/dist/bricks/Tree.js +15 -97
  96. package/dist/bricks/TreeItem.d.ts +123 -0
  97. package/dist/bricks/TreeItem.js +219 -0
  98. package/dist/bricks/VisuallyHidden.d.ts +15 -3
  99. package/dist/bricks/VisuallyHidden.js +7 -5
  100. package/dist/bricks/index.d.ts +10 -0
  101. package/dist/bricks/index.js +20 -0
  102. package/dist/bricks/styles.css.js +2 -2
  103. package/dist/bricks/~hooks.d.ts +55 -0
  104. package/dist/bricks/~hooks.js +55 -3
  105. package/dist/bricks/~utils.GhostAligner.d.ts +22 -0
  106. package/dist/bricks/~utils.GhostAligner.js +13 -0
  107. package/dist/bricks/~utils.ListItem.d.ts +14 -0
  108. package/dist/bricks/~utils.ListItem.js +46 -0
  109. package/dist/bricks/~utils.d.ts +26 -3
  110. package/dist/bricks/~utils.js +3 -0
  111. package/dist/foundations/styles.css.js +2 -2
  112. package/package.json +14 -13
  113. package/dist/DEV/bricks/ListItem.js +0 -33
  114. package/dist/DEV/bricks/Textarea.js +0 -28
  115. package/dist/bricks/ListItem.d.ts +0 -11
  116. package/dist/bricks/ListItem.js +0 -31
  117. package/dist/bricks/Textarea.d.ts +0 -14
  118. package/dist/bricks/Textarea.js +0 -27
@@ -11,7 +11,7 @@ interface IconButtonBaseProps extends Omit<React.ComponentProps<typeof Button>,
11
11
  /**
12
12
  * Icon to be displayed inside the button.
13
13
  *
14
- * Can be a URL of an SVG from the `kiwi-icons` package,
14
+ * Can be a URL of an SVG from the `@itwin/itwinui-icons` package,
15
15
  * or a custom JSX icon.
16
16
  */
17
17
  icon: string | React.JSX.Element;
@@ -24,15 +24,30 @@ interface IconButtonBaseProps extends Omit<React.ComponentProps<typeof Button>,
24
24
  * @default "tooltip"
25
25
  */
26
26
  labelVariant?: "tooltip" | "visually-hidden";
27
+ /**
28
+ * A small dot displayed in the corner of the icon.
29
+ *
30
+ * The value of this prop gets used as the button's "accessible description".
31
+ *
32
+ * Example:
33
+ * ```tsx
34
+ * <IconButton
35
+ * label="Messages"
36
+ * dot="You have unread messages"
37
+ * icon={…}
38
+ * />
39
+ * ```
40
+ */
41
+ dot?: string;
27
42
  }
28
43
  /**
29
44
  * An icon-only button, with a required accessible name.
30
45
  *
31
- * The icon can be a URL from the `kiwi-icons` package:
46
+ * The icon can be a URL from the `@itwin/itwinui-icons` package:
32
47
  * ```tsx
33
48
  * <IconButton
34
49
  * label="Reveal full content"
35
- * icon={new URL("@itwin/itwinui-icons/icons/arrow.svg", import.meta.url).href}
50
+ * icon={new URL("@itwin/itwinui-icons/arrow.svg", import.meta.url).href}
36
51
  * />
37
52
  * ```
38
53
  *
@@ -55,6 +70,7 @@ interface IconButtonBaseProps extends Omit<React.ComponentProps<typeof Button>,
55
70
  * isActive={isActive}
56
71
  * onClick={() => setIsActive(!isActive)}
57
72
  * />
73
+ * ```
58
74
  */
59
75
  export declare const IconButton: React.ForwardRefExoticComponent<(Omit<IconButtonBaseProps & {
60
76
  variant: "ghost";
@@ -75,5 +91,5 @@ export declare const IconButton: React.ForwardRefExoticComponent<(Omit<IconButto
75
91
  }, "ref"> | Omit<IconButtonBaseProps & {
76
92
  variant?: Omit<React.ComponentProps<typeof Button>["variant"], "ghost">;
77
93
  isActive?: never;
78
- }, "ref">) & React.RefAttributes<HTMLButtonElement>>;
94
+ }, "ref">) & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
79
95
  export {};
@@ -1,30 +1,43 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import cx from "classnames";
4
+ import { useToolbarContext, ToolbarItem } from "@ariakit/react/toolbar";
4
5
  import { Button } from "./Button.js";
5
6
  import { VisuallyHidden } from "./VisuallyHidden.js";
6
7
  import { Icon } from "./Icon.js";
7
8
  import { Tooltip } from "./Tooltip.js";
8
- const IconButton = React.forwardRef((props, forwardedRef) => {
9
- const { label, icon, isActive, labelVariant, ...rest } = props;
10
- const button = /* @__PURE__ */ jsxs(
11
- Button,
12
- {
13
- "aria-pressed": isActive,
14
- ...rest,
15
- className: cx("\u{1F95D}-icon-button", props.className),
16
- ref: forwardedRef,
17
- children: [
18
- /* @__PURE__ */ jsx(VisuallyHidden, { children: label }),
19
- typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { href: icon }) : icon
20
- ]
9
+ import { forwardRef } from "./~utils.js";
10
+ const IconButton = forwardRef(
11
+ (props, forwardedRef) => {
12
+ const { label, icon, isActive, labelVariant, dot, ...rest } = props;
13
+ const baseId = React.useId();
14
+ const labelId = `${baseId}-label`;
15
+ const dotId = `${baseId}-dot`;
16
+ const toolbar = useToolbarContext();
17
+ const button = /* @__PURE__ */ jsxs(
18
+ Button,
19
+ {
20
+ "aria-pressed": isActive,
21
+ "aria-labelledby": labelId,
22
+ "aria-describedby": dot ? dotId : void 0,
23
+ ...rest,
24
+ "data-kiwi-dot": dot ? "true" : void 0,
25
+ render: toolbar ? /* @__PURE__ */ jsx(ToolbarItem, { render: props.render }) : props.render,
26
+ className: cx("\u{1F95D}-icon-button", props.className),
27
+ ref: forwardedRef,
28
+ children: [
29
+ /* @__PURE__ */ jsx(VisuallyHidden, { id: labelId, children: label }),
30
+ typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { href: icon }) : icon,
31
+ dot ? /* @__PURE__ */ jsx(VisuallyHidden, { id: dotId, "aria-hidden": "true", children: dot }) : null
32
+ ]
33
+ }
34
+ );
35
+ if (labelVariant === "visually-hidden") {
36
+ return button;
21
37
  }
22
- );
23
- if (labelVariant === "visually-hidden") {
24
- return button;
38
+ return /* @__PURE__ */ jsx(Tooltip, { content: label, type: "none", children: button });
25
39
  }
26
- return /* @__PURE__ */ jsx(Tooltip, { content: label, type: "none", children: button });
27
- });
40
+ );
28
41
  export {
29
42
  IconButton
30
43
  };
@@ -1,8 +1,18 @@
1
- import * as React from "react";
2
- import type { BaseProps } from "./~utils.js";
1
+ import { type BaseProps } from "./~utils.js";
2
+ import { type PredefinedSymbol } from "./Kbd.internal.js";
3
3
  interface KbdProps extends BaseProps<"kbd"> {
4
4
  /** @default "solid" */
5
5
  variant?: "solid" | "muted" | "ghost";
6
+ /**
7
+ * Display a specific key symbol from a predefined list. This is useful for
8
+ * displaying modifier keys or special keys, such as `Control`, `Shift`, `Enter`, etc.
9
+ *
10
+ * Example:
11
+ * ```tsx
12
+ * <Kbd symbol="Control" />
13
+ * ```
14
+ */
15
+ symbol?: PredefinedSymbol;
6
16
  }
7
17
  /**
8
18
  * A styled wrapper over the HTML `<kbd>` element. This is typically
@@ -11,6 +21,10 @@ interface KbdProps extends BaseProps<"kbd"> {
11
21
  * ```tsx
12
22
  * <Kbd>Ctrl</Kbd> <Kbd>S</Kbd>
13
23
  * ```
24
+ *
25
+ * ```tsx
26
+ * <Kbd symbol="Control" />
27
+ * ```
14
28
  */
15
- export declare const Kbd: React.ForwardRefExoticComponent<KbdProps & React.RefAttributes<HTMLElement>>;
29
+ export declare const Kbd: import("react").ForwardRefExoticComponent<KbdProps & import("react").RefAttributes<HTMLElement>>;
16
30
  export {};
@@ -0,0 +1,17 @@
1
+ export type PredefinedSymbol = keyof typeof predefinedSymbols;
2
+ export declare const predefinedSymbols: {
3
+ readonly Backspace: "⌫";
4
+ readonly Command: "⌘";
5
+ readonly Control: "Ctrl";
6
+ readonly Down: "↓";
7
+ readonly Eject: "⏏";
8
+ readonly Enter: "↵";
9
+ readonly Escape: "Esc";
10
+ readonly Left: "←";
11
+ readonly Option: "⌥";
12
+ readonly Right: "→";
13
+ readonly Shift: "⇧";
14
+ readonly Space: "␣";
15
+ readonly Tab: "Tab";
16
+ readonly Up: "↑";
17
+ };
@@ -0,0 +1,19 @@
1
+ const predefinedSymbols = {
2
+ Backspace: "\u232B",
3
+ Command: "\u2318",
4
+ Control: "Ctrl",
5
+ Down: "\u2193",
6
+ Eject: "\u23CF",
7
+ Enter: "\u21B5",
8
+ Escape: "Esc",
9
+ Left: "\u2190",
10
+ Option: "\u2325",
11
+ Right: "\u2192",
12
+ Shift: "\u21E7",
13
+ Space: "\u2423",
14
+ Tab: "Tab",
15
+ Up: "\u2191"
16
+ };
17
+ export {
18
+ predefinedSymbols
19
+ };
@@ -1,22 +1,30 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import * as React from "react";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
2
  import cx from "classnames";
4
- import * as Ariakit from "@ariakit/react";
5
- const Kbd = React.forwardRef(
6
- (props, forwardedRef) => {
7
- const { variant = "solid", ...rest } = props;
8
- return /* @__PURE__ */ jsx(
9
- Ariakit.Role,
10
- {
11
- "data-kiwi-variant": variant,
12
- ...rest,
13
- className: cx("\u{1F95D}-kbd", props.className),
14
- render: props.render || /* @__PURE__ */ jsx("kbd", {}),
15
- ref: forwardedRef
16
- }
17
- );
3
+ import { Role } from "@ariakit/react/role";
4
+ import { forwardRef } from "./~utils.js";
5
+ import { VisuallyHidden } from "./VisuallyHidden.js";
6
+ import { predefinedSymbols } from "./Kbd.internal.js";
7
+ const Kbd = forwardRef((props, forwardedRef) => {
8
+ const { variant = "solid", symbol, children, ...rest } = props;
9
+ let content = children;
10
+ if (symbol) {
11
+ content = /* @__PURE__ */ jsxs(Fragment, { children: [
12
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: predefinedSymbols[symbol] }),
13
+ children || /* @__PURE__ */ jsx(VisuallyHidden, { children: symbol })
14
+ ] });
18
15
  }
19
- );
16
+ return /* @__PURE__ */ jsx(
17
+ Role,
18
+ {
19
+ ...rest,
20
+ "data-kiwi-variant": variant,
21
+ className: cx("\u{1F95D}-kbd", props.className),
22
+ render: props.render || /* @__PURE__ */ jsx("kbd", {}),
23
+ ref: forwardedRef,
24
+ children: content
25
+ }
26
+ );
27
+ });
20
28
  export {
21
29
  Kbd
22
30
  };
@@ -1,6 +1,25 @@
1
- import * as React from "react";
2
- import type { BaseProps } from "./~utils.js";
1
+ import { type BaseProps } from "./~utils.js";
3
2
  interface LabelProps extends BaseProps<"label"> {
4
3
  }
5
- export declare const Label: React.ForwardRefExoticComponent<LabelProps & React.RefAttributes<HTMLLabelElement>>;
4
+ /**
5
+ * A styled wrapper over the HTML `<label>` element, used for labelling form controls.
6
+ *
7
+ * Can be used standalone:
8
+
9
+ * ```tsx
10
+ * <Label htmlFor="my-input">Label</Label>
11
+ * <TextBox.Input id="my-input" />
12
+ * ```
13
+ *
14
+ * Or within a `Field` component to automatically manage ID associations:
15
+ *
16
+ * ```tsx
17
+ * <Field>
18
+ * <Label>Label</Label>
19
+ * <TextBox.Input />
20
+ * </Field>
21
+ * ```
22
+ *
23
+ */
24
+ export declare const Label: import("react").ForwardRefExoticComponent<LabelProps & import("react").RefAttributes<HTMLElement | HTMLLabelElement>>;
6
25
  export {};
@@ -1,17 +1,20 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import * as React from "react";
3
2
  import cx from "classnames";
4
- import * as Ariakit from "@ariakit/react";
5
- import { useFieldId } from "./Field.js";
6
- const Label = React.forwardRef((props, forwardedRef) => {
7
- const fieldId = useFieldId();
3
+ import { Role } from "@ariakit/react/role";
4
+ import { forwardRef } from "./~utils.js";
5
+ import { FieldLabel } from "./Field.js";
6
+ const Label = forwardRef((props, forwardedRef) => {
8
7
  return /* @__PURE__ */ jsx(
9
- Ariakit.Role.label,
8
+ FieldLabel,
10
9
  {
11
- htmlFor: fieldId,
12
- ...props,
13
- className: cx("\u{1F95D}-label", props.className),
14
- ref: forwardedRef
10
+ render: /* @__PURE__ */ jsx(
11
+ Role.label,
12
+ {
13
+ ...props,
14
+ className: cx("\u{1F95D}-label", props.className),
15
+ ref: forwardedRef
16
+ }
17
+ )
15
18
  }
16
19
  );
17
20
  });
@@ -0,0 +1,31 @@
1
+ import { type BaseProps } from "./~utils.js";
2
+ interface ProgressBarProps extends Omit<BaseProps, "aria-labelledby">, Required<Pick<BaseProps, "aria-labelledby">> {
3
+ /**
4
+ * The size of the progress bar.
5
+ * @default "medium"
6
+ */
7
+ size?: "small" | "medium" | "large";
8
+ /**
9
+ * The tone of the progress bar.
10
+ * @default "neutral"
11
+ */
12
+ tone?: "neutral" | "accent";
13
+ }
14
+ /**
15
+ * A linear progress bar for indicating progress of an operation (or loading of data).
16
+ * This component maps to the [ARIA `progressbar` role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/progressbar_role)
17
+ * and must be labelled using `aria-labelledby`.
18
+ *
19
+ * Example:
20
+ * ```tsx
21
+ * <ProgressBar aria-labelledby={…} />
22
+ * ```
23
+ *
24
+ * Supports a `tone` prop to change the tone (color) of the progress bar.
25
+ * Supports a `size` prop to change the size of the progress bar.
26
+ *
27
+ * Note: This component currently only supports indeterminate progress, and should
28
+ * only be used for indicating the progress of short operations (i.e. less than 5 seconds).
29
+ */
30
+ export declare const ProgressBar: import("react").ForwardRefExoticComponent<ProgressBarProps & import("react").RefAttributes<HTMLElement | HTMLDivElement>>;
31
+ export {};
@@ -0,0 +1,24 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Role } from "@ariakit/react/role";
3
+ import cx from "classnames";
4
+ import { forwardRef } from "./~utils.js";
5
+ const ProgressBar = forwardRef(
6
+ (props, forwardedRef) => {
7
+ const { size = "medium", tone = "neutral", ...rest } = props;
8
+ return /* @__PURE__ */ jsx(
9
+ Role,
10
+ {
11
+ role: "progressbar",
12
+ ...rest,
13
+ "data-kiwi-size": size,
14
+ "data-kiwi-tone": tone,
15
+ "data-kiwi-variant": "indeterminate",
16
+ className: cx("\u{1F95D}-progress-bar", props.className),
17
+ ref: forwardedRef
18
+ }
19
+ );
20
+ }
21
+ );
22
+ export {
23
+ ProgressBar
24
+ };
@@ -1,9 +1,23 @@
1
- import * as React from "react";
2
- import * as Ariakit from "@ariakit/react";
3
- import type { FocusableProps } from "./~utils.js";
1
+ import { type RadioProps as AkRadioProps } from "@ariakit/react/radio";
2
+ import { type FocusableProps } from "./~utils.js";
4
3
  type InputBaseProps = Omit<FocusableProps<"input">, "defaultValue" | "value">;
5
- type RadioOwnProps = Pick<Ariakit.RadioProps, "value" | "checked" | "onChange">;
4
+ type RadioOwnProps = Pick<AkRadioProps, "value" | "checked" | "onChange">;
6
5
  interface RadioProps extends InputBaseProps, RadioOwnProps {
7
6
  }
8
- export declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLInputElement>>;
7
+ /**
8
+ * A styled radio input element, typically used for selecting a single option from a list.
9
+ *
10
+ * Works well with the `Field` and `Label` components.
11
+ *
12
+ * ```tsx
13
+ * <Field>
14
+ * <Label>Choose one</Label>
15
+ * <Radio />
16
+ * </Field>
17
+ * ```
18
+ *
19
+ * Underneath, it's an HTML radio input, i.e. `<input type="radio">`, so it supports the same props,
20
+ * including `value`, `defaultChecked`, `checked`, and `onChange`.
21
+ */
22
+ export declare const Radio: import("react").ForwardRefExoticComponent<RadioProps & import("react").RefAttributes<HTMLElement | HTMLInputElement>>;
9
23
  export {};
@@ -1,18 +1,26 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import * as React from "react";
3
2
  import cx from "classnames";
4
- import * as Ariakit from "@ariakit/react";
5
- import { useFieldId } from "./Field.js";
6
- const Radio = React.forwardRef((props, forwardedRef) => {
7
- const fieldId = useFieldId();
3
+ import {
4
+ Radio as AkRadio
5
+ } from "@ariakit/react/radio";
6
+ import { FieldControl } from "./Field.js";
7
+ import { forwardRef } from "./~utils.js";
8
+ const Radio = forwardRef((props, forwardedRef) => {
9
+ const { id, ...rest } = props;
8
10
  return /* @__PURE__ */ jsx(
9
- Ariakit.Radio,
11
+ FieldControl,
10
12
  {
11
- accessibleWhenDisabled: true,
12
- id: fieldId,
13
- ...props,
14
- className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
15
- ref: forwardedRef
13
+ type: "checkable",
14
+ id,
15
+ render: /* @__PURE__ */ jsx(
16
+ AkRadio,
17
+ {
18
+ accessibleWhenDisabled: true,
19
+ ...rest,
20
+ className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
21
+ ref: forwardedRef
22
+ }
23
+ )
16
24
  }
17
25
  );
18
26
  });
@@ -19,8 +19,17 @@ interface RootProps extends BaseProps {
19
19
  density: "dense";
20
20
  }
21
21
  /**
22
- * Component to be used at the root of your application. It ensures that kiwi styles are loaded
22
+ * Component to be used at the root of your application. It ensures that kiwi styles and fonts are loaded
23
23
  * and automatically applied to the current page or the encompassing shadow-root.
24
+ *
25
+ * Make sure to specify the `colorScheme` and `density` props.
26
+ *
27
+ * Example:
28
+ * ```tsx
29
+ * <Root colorScheme="dark" density="dense">
30
+ * <App />
31
+ * </Root>
32
+ * ```
24
33
  */
25
- export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLDivElement>>;
34
+ export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
26
35
  export {};
@@ -1,50 +1,59 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
- import * as Ariakit from "@ariakit/react";
3
+ import * as ReactDOM from "react-dom";
4
+ import { Role } from "@ariakit/react/role";
5
+ import { PortalContext } from "@ariakit/react/portal";
4
6
  import cx from "classnames";
5
7
  import foundationsCss from "../foundations/styles.css.js";
6
8
  import bricksCss from "./styles.css.js";
7
- import { isBrowser } from "./~utils.js";
8
- import { useMergedRefs } from "./~hooks.js";
9
+ import { forwardRef, isBrowser } from "./~utils.js";
10
+ import { useIsClient, useMergedRefs } from "./~hooks.js";
9
11
  const css = foundationsCss + bricksCss;
10
- const Root = React.forwardRef(
11
- (props, forwardedRef) => {
12
- const { children, synchronizeColorScheme = false, ...rest } = props;
13
- return /* @__PURE__ */ jsxs(RootInternal, { ...rest, ref: forwardedRef, children: [
14
- /* @__PURE__ */ jsx(Styles, {}),
15
- /* @__PURE__ */ jsx(Fonts, {}),
16
- synchronizeColorScheme ? /* @__PURE__ */ jsx(SynchronizeColorScheme, { colorScheme: props.colorScheme }) : null,
17
- children
18
- ] });
19
- }
20
- );
12
+ const Root = forwardRef((props, forwardedRef) => {
13
+ const { children, synchronizeColorScheme = false, ...rest } = props;
14
+ const [portalContainer, setPortalContainer] = React.useState(null);
15
+ return /* @__PURE__ */ jsxs(RootInternal, { ...rest, ref: forwardedRef, children: [
16
+ /* @__PURE__ */ jsx(Styles, {}),
17
+ /* @__PURE__ */ jsx(Fonts, {}),
18
+ synchronizeColorScheme ? /* @__PURE__ */ jsx(SynchronizeColorScheme, { colorScheme: props.colorScheme }) : null,
19
+ /* @__PURE__ */ jsx(
20
+ PortalContainer,
21
+ {
22
+ colorScheme: props.colorScheme,
23
+ density: props.density,
24
+ ref: setPortalContainer
25
+ }
26
+ ),
27
+ /* @__PURE__ */ jsx(PortalContext.Provider, { value: portalContainer, children })
28
+ ] });
29
+ });
21
30
  const RootNodeContext = React.createContext(null);
22
31
  function useRootNode() {
23
32
  return React.useContext(RootNodeContext);
24
33
  }
25
- const RootInternal = React.forwardRef((props, forwardedRef) => {
26
- const { children, colorScheme, density, ...rest } = props;
27
- const [rootNode, setRootNode] = React.useState(
28
- null
29
- );
30
- const findRootNodeFromRef = React.useCallback((element) => {
31
- if (!element) return;
32
- const rootNode2 = element.getRootNode();
33
- if (!isDocument(rootNode2) && !isShadow(rootNode2)) return;
34
- setRootNode(rootNode2);
35
- }, []);
36
- return /* @__PURE__ */ jsx(
37
- Ariakit.Role,
38
- {
39
- ...rest,
40
- className: cx("\u{1F95D}-root", props.className),
41
- "data-kiwi-theme": colorScheme,
42
- "data-kiwi-density": density,
43
- ref: useMergedRefs(forwardedRef, findRootNodeFromRef),
44
- children: /* @__PURE__ */ jsx(RootNodeContext.Provider, { value: rootNode, children })
45
- }
46
- );
47
- });
34
+ const RootInternal = forwardRef(
35
+ (props, forwardedRef) => {
36
+ const { children, colorScheme, density, ...rest } = props;
37
+ const [rootNode, setRootNode] = React.useState(null);
38
+ const findRootNodeFromRef = React.useCallback((element) => {
39
+ if (!element) return;
40
+ const rootNode2 = element.getRootNode();
41
+ if (!isDocument(rootNode2) && !isShadow(rootNode2)) return;
42
+ setRootNode(rootNode2);
43
+ }, []);
44
+ return /* @__PURE__ */ jsx(
45
+ Role,
46
+ {
47
+ ...rest,
48
+ className: cx("\u{1F95D}-root", props.className),
49
+ "data-kiwi-theme": colorScheme,
50
+ "data-kiwi-density": density,
51
+ ref: useMergedRefs(forwardedRef, findRootNodeFromRef),
52
+ children: /* @__PURE__ */ jsx(RootNodeContext.Provider, { value: rootNode, children })
53
+ }
54
+ );
55
+ }
56
+ );
48
57
  function SynchronizeColorScheme({
49
58
  colorScheme
50
59
  }) {
@@ -61,6 +70,26 @@ function SynchronizeColorScheme({
61
70
  }, [rootNode, colorScheme]);
62
71
  return null;
63
72
  }
73
+ const PortalContainer = forwardRef((props, forwardedRef) => {
74
+ const isClient = useIsClient();
75
+ const rootNode = useRootNode();
76
+ if (!isClient) return null;
77
+ const destination = rootNode && isDocument(rootNode) ? rootNode.body : rootNode;
78
+ if (!destination) return null;
79
+ return ReactDOM.createPortal(
80
+ /* @__PURE__ */ jsx(
81
+ "div",
82
+ {
83
+ className: "\u{1F95D}-root",
84
+ "data-kiwi-theme": props.colorScheme,
85
+ "data-kiwi-density": props.density,
86
+ style: { display: "contents" },
87
+ ref: forwardedRef
88
+ }
89
+ ),
90
+ destination
91
+ );
92
+ });
64
93
  function Styles() {
65
94
  const rootNode = useRootNode();
66
95
  useLayoutEffect(() => {
@@ -104,8 +133,8 @@ function Fonts() {
104
133
  return null;
105
134
  }
106
135
  function loadFonts(rootNode) {
107
- const ownerDocument = getOwnerDocument(rootNode);
108
- if (!ownerDocument || Array.from(ownerDocument.fonts).some(
136
+ const ownerWindow = getWindow(rootNode);
137
+ if (!ownerWindow || Array.from(ownerWindow.document.fonts).some(
109
138
  (font) => font.family === "InterVariable"
110
139
  )) {
111
140
  return;
@@ -115,12 +144,16 @@ function loadFonts(rootNode) {
115
144
  italic: "https://rsms.me/inter/font-files/InterVariable-Italic.woff2?v=4.1"
116
145
  };
117
146
  for (const [style, url] of Object.entries(interStyles)) {
118
- const font = new FontFace("InterVariable", `url(${url}) format("woff2")`, {
119
- display: "swap",
120
- weight: "100 900",
121
- style
122
- });
123
- ownerDocument.fonts.add(font);
147
+ const font = new ownerWindow.FontFace(
148
+ "InterVariable",
149
+ `url(${url}) format("woff2")`,
150
+ {
151
+ display: "swap",
152
+ weight: "100 900",
153
+ style
154
+ }
155
+ );
156
+ ownerWindow.document.fonts.add(font);
124
157
  }
125
158
  }
126
159
  const supportsAdoptedStylesheets = isBrowser && "adoptedStyleSheets" in Document.prototype;
@@ -0,0 +1,51 @@
1
+ import * as React from "react";
2
+ import { type FocusableProps } from "./~utils.js";
3
+ /**
4
+ * Compound component for a select element, which allows the user to select a value from a list of options.
5
+ *
6
+ * Works well with the `Field` and `Label` components.
7
+ *
8
+ * Example usage:
9
+ * ```tsx
10
+ * <Field>
11
+ * <Label>Select an option</Label>
12
+ * <Select.Root>
13
+ * <Select.HtmlSelect>
14
+ * <option value="1">Option 1</option>
15
+ * <option value="2">Option 2</option>
16
+ * <option value="3">Option 3</option>
17
+ * </Select.HtmlSelect>
18
+ * </Select.Root>
19
+ * </Field>
20
+ * ```
21
+ */
22
+ declare const SelectRoot: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
23
+ type HtmlSelectBaseProps = Omit<FocusableProps<"select">, "multiple" | "size">;
24
+ interface HtmlSelectProps extends HtmlSelectBaseProps {
25
+ /**
26
+ * The variant of the `HtmlSelect`, i.e. solid, outline, or ghost.
27
+ *
28
+ * @default "solid"
29
+ */
30
+ variant?: "solid" | "outline" | "ghost";
31
+ }
32
+ /**
33
+ * The actual select element to be used inside `Select.Root`. This is a wrapper around the
34
+ * HTML `<select>` element and should render HTML `<option>` elements as children.
35
+ *
36
+ * Example usage:
37
+ * ```tsx
38
+ * <Select.HtmlSelect>
39
+ * <option value="1">Option 1</option>
40
+ * <option value="2">Option 2</option>
41
+ * <option value="3">Option 3</option>
42
+ * </Select.HtmlSelect>
43
+ * ```
44
+ *
45
+ * The usage of this component largely mirrors how the `<select>` element would be used in React.
46
+ * You can use the same familiar props, including `name`, `defaultValue`, `value`, `onChange`, etc.
47
+ *
48
+ * @see https://react.dev/reference/react-dom/components/select
49
+ */
50
+ declare const HtmlSelect: React.ForwardRefExoticComponent<HtmlSelectProps & React.RefAttributes<HTMLElement | HTMLSelectElement>>;
51
+ export { SelectRoot as Root, HtmlSelect };