@itwin/itwinui-react 5.0.0-alpha.1 → 5.0.0-alpha.11

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 (116) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/LICENSE.md +1 -1
  3. package/README.md +6 -6
  4. package/dist/DEV/bricks/Anchor.js +5 -10
  5. package/dist/DEV/bricks/Avatar.js +24 -0
  6. package/dist/DEV/bricks/Badge.js +22 -0
  7. package/dist/DEV/bricks/Button.js +11 -4
  8. package/dist/DEV/bricks/Checkbox.js +17 -9
  9. package/dist/DEV/bricks/Chip.js +42 -0
  10. package/dist/DEV/bricks/Description.js +29 -0
  11. package/dist/DEV/bricks/Divider.js +3 -2
  12. package/dist/DEV/bricks/DropdownMenu.js +109 -30
  13. package/dist/DEV/bricks/Field.js +115 -14
  14. package/dist/DEV/bricks/Icon.js +177 -10
  15. package/dist/DEV/bricks/IconButton.js +14 -3
  16. package/dist/DEV/bricks/Kbd.internal.js +19 -0
  17. package/dist/DEV/bricks/Kbd.js +23 -6
  18. package/dist/DEV/bricks/Label.js +11 -8
  19. package/dist/DEV/bricks/ProgressBar.js +25 -0
  20. package/dist/DEV/bricks/Radio.js +17 -9
  21. package/dist/DEV/bricks/Root.internal.js +17 -0
  22. package/dist/DEV/bricks/Root.js +103 -26
  23. package/dist/DEV/bricks/Select.js +17 -11
  24. package/dist/DEV/bricks/Skeleton.js +24 -0
  25. package/dist/DEV/bricks/Spinner.js +55 -0
  26. package/dist/DEV/bricks/Switch.js +18 -10
  27. package/dist/DEV/bricks/Table.js +114 -0
  28. package/dist/DEV/bricks/Tabs.js +6 -6
  29. package/dist/DEV/bricks/Text.js +2 -2
  30. package/dist/DEV/bricks/TextBox.js +54 -16
  31. package/dist/DEV/bricks/Tooltip.js +17 -25
  32. package/dist/DEV/bricks/Tree.js +15 -107
  33. package/dist/DEV/bricks/TreeItem.js +227 -0
  34. package/dist/DEV/bricks/VisuallyHidden.js +2 -2
  35. package/dist/DEV/bricks/index.js +16 -0
  36. package/dist/DEV/bricks/styles.css.js +2 -2
  37. package/dist/DEV/bricks/~hooks.js +57 -3
  38. package/dist/DEV/bricks/~utils.GhostAligner.js +13 -0
  39. package/dist/DEV/bricks/{ListItem.js → ~utils.ListItem.js} +19 -3
  40. package/dist/DEV/bricks/~utils.js +17 -0
  41. package/dist/DEV/foundations/styles.css.js +2 -2
  42. package/dist/bricks/Anchor.js +5 -10
  43. package/dist/bricks/Avatar.d.ts +47 -0
  44. package/dist/bricks/Avatar.js +23 -0
  45. package/dist/bricks/Badge.d.ts +28 -0
  46. package/dist/bricks/Badge.js +21 -0
  47. package/dist/bricks/Button.js +11 -4
  48. package/dist/bricks/Checkbox.d.ts +2 -2
  49. package/dist/bricks/Checkbox.js +17 -9
  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 +2 -2
  55. package/dist/bricks/Divider.js +3 -2
  56. package/dist/bricks/DropdownMenu.d.ts +41 -14
  57. package/dist/bricks/DropdownMenu.js +106 -30
  58. package/dist/bricks/Field.d.ts +23 -1
  59. package/dist/bricks/Field.js +115 -14
  60. package/dist/bricks/Icon.d.ts +43 -4
  61. package/dist/bricks/Icon.js +174 -10
  62. package/dist/bricks/IconButton.d.ts +20 -4
  63. package/dist/bricks/IconButton.js +14 -3
  64. package/dist/bricks/Kbd.d.ts +15 -0
  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 +16 -6
  68. package/dist/bricks/Label.js +11 -8
  69. package/dist/bricks/ProgressBar.d.ts +31 -0
  70. package/dist/bricks/ProgressBar.js +24 -0
  71. package/dist/bricks/Radio.d.ts +2 -2
  72. package/dist/bricks/Radio.js +17 -9
  73. package/dist/bricks/Root.d.ts +12 -0
  74. package/dist/bricks/Root.internal.d.ts +6 -0
  75. package/dist/bricks/Root.internal.js +17 -0
  76. package/dist/bricks/Root.js +103 -26
  77. package/dist/bricks/Select.d.ts +9 -3
  78. package/dist/bricks/Select.js +17 -11
  79. package/dist/bricks/Skeleton.d.ts +25 -0
  80. package/dist/bricks/Skeleton.js +23 -0
  81. package/dist/bricks/Spinner.d.ts +31 -0
  82. package/dist/bricks/Spinner.js +54 -0
  83. package/dist/bricks/Switch.d.ts +2 -2
  84. package/dist/bricks/Switch.js +18 -10
  85. package/dist/bricks/Table.d.ts +115 -0
  86. package/dist/bricks/Table.js +108 -0
  87. package/dist/bricks/Tabs.d.ts +4 -4
  88. package/dist/bricks/Tabs.js +6 -6
  89. package/dist/bricks/Text.d.ts +1 -1
  90. package/dist/bricks/Text.js +2 -2
  91. package/dist/bricks/TextBox.d.ts +23 -2
  92. package/dist/bricks/TextBox.js +53 -16
  93. package/dist/bricks/Tooltip.d.ts +2 -2
  94. package/dist/bricks/Tooltip.js +17 -25
  95. package/dist/bricks/Tree.d.ts +19 -20
  96. package/dist/bricks/Tree.js +14 -102
  97. package/dist/bricks/TreeItem.d.ts +129 -0
  98. package/dist/bricks/TreeItem.js +222 -0
  99. package/dist/bricks/VisuallyHidden.js +2 -2
  100. package/dist/bricks/index.d.ts +8 -0
  101. package/dist/bricks/index.js +16 -0
  102. package/dist/bricks/styles.css.js +2 -2
  103. package/dist/bricks/~hooks.d.ts +63 -0
  104. package/dist/bricks/~hooks.js +57 -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/{ListItem.js → ~utils.ListItem.js} +18 -3
  109. package/dist/bricks/~utils.d.ts +14 -3
  110. package/dist/bricks/~utils.js +17 -0
  111. package/dist/foundations/styles.css.js +2 -2
  112. package/package.json +14 -13
  113. package/dist/DEV/bricks/Textarea.js +0 -30
  114. package/dist/bricks/ListItem.d.ts +0 -10
  115. package/dist/bricks/Textarea.d.ts +0 -24
  116. package/dist/bricks/Textarea.js +0 -29
@@ -1,17 +1,20 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
- import * as Ariakit from "@ariakit/react";
4
- import { useFieldId } from "./Field.js";
3
+ import { Role } from "@ariakit/react/role";
5
4
  import { forwardRef } from "./~utils.js";
5
+ import { FieldLabel } from "./Field.js";
6
6
  const Label = forwardRef((props, forwardedRef) => {
7
- const fieldId = useFieldId();
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,7 +1,7 @@
1
- import * as Ariakit from "@ariakit/react";
1
+ import { type RadioProps as AkRadioProps } from "@ariakit/react/radio";
2
2
  import { type FocusableProps } from "./~utils.js";
3
3
  type InputBaseProps = Omit<FocusableProps<"input">, "defaultValue" | "value">;
4
- type RadioOwnProps = Pick<Ariakit.RadioProps, "value" | "checked" | "onChange">;
4
+ type RadioOwnProps = Pick<AkRadioProps, "value" | "checked" | "onChange">;
5
5
  interface RadioProps extends InputBaseProps, RadioOwnProps {
6
6
  }
7
7
  /**
@@ -1,18 +1,26 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
- import * as Ariakit from "@ariakit/react";
4
- import { useFieldId } from "./Field.js";
3
+ import {
4
+ Radio as AkRadio
5
+ } from "@ariakit/react/radio";
6
+ import { FieldControl } from "./Field.js";
5
7
  import { forwardRef } from "./~utils.js";
6
8
  const Radio = forwardRef((props, forwardedRef) => {
7
- const fieldId = useFieldId();
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
  });
@@ -17,6 +17,18 @@ interface RootProps extends BaseProps {
17
17
  * The density to use for all components under the Root.
18
18
  */
19
19
  density: "dense";
20
+ /**
21
+ * An HTML sanitizer function that will be used across all components wherever DOM elements
22
+ * are created from HTML strings.
23
+ *
24
+ * When this prop is not passed, sanitization will be skipped.
25
+ *
26
+ * Example:
27
+ * ```tsx
28
+ * unstablized_htmlSanitizer={DOMPurify.sanitize}
29
+ * ```
30
+ */
31
+ unstable_htmlSanitizer?: (html: string) => string;
20
32
  }
21
33
  /**
22
34
  * Component to be used at the root of your application. It ensures that kiwi styles and fonts are loaded
@@ -0,0 +1,6 @@
1
+ import * as React from "react";
2
+ export declare const RootNodeContext: React.Context<Document | ShadowRoot | null>;
3
+ /** Returns the closest [rootNode](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode). */
4
+ export declare function useRootNode(): Document | ShadowRoot | null | undefined;
5
+ export declare const spriteSheetId = "\uD83E\uDD5D-inline-sprites";
6
+ export declare const HtmlSanitizerContext: React.Context<((html: string) => string) | undefined>;
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+ import { useIsClient } from "./~hooks.js";
3
+ const RootNodeContext = React.createContext(null);
4
+ function useRootNode() {
5
+ const maybeRootNode = React.useContext(RootNodeContext);
6
+ const isClient = useIsClient();
7
+ if (!isClient) return void 0;
8
+ return maybeRootNode;
9
+ }
10
+ const spriteSheetId = "\u{1F95D}-inline-sprites";
11
+ const HtmlSanitizerContext = React.createContext(void 0);
12
+ export {
13
+ HtmlSanitizerContext,
14
+ RootNodeContext,
15
+ spriteSheetId,
16
+ useRootNode
17
+ };
@@ -1,25 +1,50 @@
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 { forwardRef, isBrowser } from "./~utils.js";
8
- import { useMergedRefs } from "./~hooks.js";
9
+ import {
10
+ forwardRef,
11
+ getOwnerDocument,
12
+ identity,
13
+ isBrowser,
14
+ isDocument
15
+ } from "./~utils.js";
16
+ import { useLayoutEffect, useMergedRefs } from "./~hooks.js";
17
+ import {
18
+ HtmlSanitizerContext,
19
+ RootNodeContext,
20
+ spriteSheetId,
21
+ useRootNode
22
+ } from "./Root.internal.js";
9
23
  const css = foundationsCss + bricksCss;
10
24
  const Root = forwardRef((props, forwardedRef) => {
11
- const { children, synchronizeColorScheme = false, ...rest } = props;
25
+ const {
26
+ children,
27
+ synchronizeColorScheme = false,
28
+ unstable_htmlSanitizer = identity,
29
+ ...rest
30
+ } = props;
31
+ const [portalContainer, setPortalContainer] = React.useState(null);
12
32
  return /* @__PURE__ */ jsxs(RootInternal, { ...rest, ref: forwardedRef, children: [
13
33
  /* @__PURE__ */ jsx(Styles, {}),
14
34
  /* @__PURE__ */ jsx(Fonts, {}),
35
+ /* @__PURE__ */ jsx(InlineSpriteSheet, {}),
15
36
  synchronizeColorScheme ? /* @__PURE__ */ jsx(SynchronizeColorScheme, { colorScheme: props.colorScheme }) : null,
16
- children
37
+ /* @__PURE__ */ jsx(
38
+ PortalContainer,
39
+ {
40
+ colorScheme: props.colorScheme,
41
+ density: props.density,
42
+ ref: setPortalContainer
43
+ }
44
+ ),
45
+ /* @__PURE__ */ jsx(PortalContext.Provider, { value: portalContainer, children: /* @__PURE__ */ jsx(HtmlSanitizerContext.Provider, { value: unstable_htmlSanitizer, children }) })
17
46
  ] });
18
47
  });
19
- const RootNodeContext = React.createContext(null);
20
- function useRootNode() {
21
- return React.useContext(RootNodeContext);
22
- }
23
48
  const RootInternal = forwardRef(
24
49
  (props, forwardedRef) => {
25
50
  const { children, colorScheme, density, ...rest } = props;
@@ -31,7 +56,7 @@ const RootInternal = forwardRef(
31
56
  setRootNode(rootNode2);
32
57
  }, []);
33
58
  return /* @__PURE__ */ jsx(
34
- Ariakit.Role,
59
+ Role,
35
60
  {
36
61
  ...rest,
37
62
  className: cx("\u{1F95D}-root", props.className),
@@ -59,39 +84,69 @@ function SynchronizeColorScheme({
59
84
  }, [rootNode, colorScheme]);
60
85
  return null;
61
86
  }
87
+ const PortalContainer = forwardRef((props, forwardedRef) => {
88
+ const rootNode = useRootNode();
89
+ if (!rootNode) return null;
90
+ const destination = isDocument(rootNode) ? rootNode.body : rootNode;
91
+ if (!destination) return null;
92
+ return ReactDOM.createPortal(
93
+ /* @__PURE__ */ jsx(
94
+ "div",
95
+ {
96
+ className: "\u{1F95D}-root",
97
+ "data-kiwi-theme": props.colorScheme,
98
+ "data-kiwi-density": props.density,
99
+ style: { display: "contents" },
100
+ ref: forwardedRef
101
+ }
102
+ ),
103
+ destination
104
+ );
105
+ });
62
106
  function Styles() {
63
107
  const rootNode = useRootNode();
64
108
  useLayoutEffect(() => {
65
109
  if (!rootNode) return;
66
- loadStyles(rootNode, { css });
110
+ const { cleanup } = loadStyles(rootNode, { css });
111
+ return cleanup;
67
112
  }, [rootNode]);
68
113
  return null;
69
114
  }
70
- const styleSheets = /* @__PURE__ */ new WeakMap();
71
- function loadStyles(rootNode, { css: css2 }) {
115
+ const styleSheets = new Map(
116
+ Object.entries({ default: /* @__PURE__ */ new WeakMap() })
117
+ );
118
+ function loadStyles(rootNode, { css: css2, key = "default" }) {
119
+ let cleanup = () => {
120
+ };
72
121
  const loaded = (() => {
73
122
  if (!isBrowser) return false;
74
123
  const ownerDocument = getOwnerDocument(rootNode);
75
124
  const _window = getWindow(rootNode);
76
125
  if (!ownerDocument || !_window) return false;
77
- if (!supportsAdoptedStylesheets && !rootNode.querySelector("style[data-kiwi]")) {
126
+ if (!supportsAdoptedStylesheets && !rootNode.querySelector(`style[data-kiwi="${key}"]`)) {
78
127
  const styleElement = ownerDocument.createElement("style");
79
- styleElement.dataset.kiwi = "true";
128
+ styleElement.dataset.kiwi = key;
80
129
  styleElement.textContent = css2;
81
130
  (rootNode.head || rootNode).appendChild(styleElement);
131
+ cleanup = () => styleElement.remove();
82
132
  return true;
83
133
  }
84
- const styleSheet = styleSheets.get(_window) || new _window.CSSStyleSheet();
85
- if (!styleSheets.has(_window)) {
86
- styleSheets.set(_window, styleSheet);
134
+ const styleSheet = styleSheets.get(key)?.get(_window) || new _window.CSSStyleSheet();
135
+ if (!styleSheets.get(key)?.has(_window)) {
136
+ styleSheets.get(key)?.set(_window, styleSheet);
87
137
  }
88
138
  styleSheet.replaceSync(css2);
89
139
  if (!rootNode.adoptedStyleSheets.includes(styleSheet)) {
90
140
  rootNode.adoptedStyleSheets.push(styleSheet);
141
+ cleanup = () => {
142
+ rootNode.adoptedStyleSheets = rootNode.adoptedStyleSheets.filter(
143
+ (sheet) => sheet !== styleSheet
144
+ );
145
+ };
91
146
  }
92
147
  return true;
93
148
  })();
94
- return { loaded };
149
+ return { loaded, cleanup };
95
150
  }
96
151
  function Fonts() {
97
152
  const rootNode = useRootNode();
@@ -101,6 +156,35 @@ function Fonts() {
101
156
  }, [rootNode]);
102
157
  return null;
103
158
  }
159
+ function InlineSpriteSheet() {
160
+ const rootNode = useRootNode();
161
+ React.useEffect(
162
+ function maybeCreateSpriteSheet() {
163
+ const ownerDocument = getOwnerDocument(rootNode);
164
+ if (!ownerDocument) return;
165
+ const spriteSheet = ownerDocument?.getElementById(spriteSheetId);
166
+ if (spriteSheet) return;
167
+ const svg = ownerDocument.createElementNS(
168
+ "http://www.w3.org/2000/svg",
169
+ "svg"
170
+ );
171
+ svg.id = spriteSheetId;
172
+ svg.style.display = "none";
173
+ Object.defineProperty(svg, Symbol.for("\u{1F95D}"), {
174
+ value: { icons: /* @__PURE__ */ new Map() }
175
+ // Map of icon URLs that have already been inlined.
176
+ });
177
+ ownerDocument.body.appendChild(svg);
178
+ return () => {
179
+ if (svg.isConnected) {
180
+ ownerDocument.body.removeChild(svg);
181
+ }
182
+ };
183
+ },
184
+ [rootNode]
185
+ );
186
+ return null;
187
+ }
104
188
  function loadFonts(rootNode) {
105
189
  const ownerWindow = getWindow(rootNode);
106
190
  if (!ownerWindow || Array.from(ownerWindow.document.fonts).some(
@@ -129,17 +213,10 @@ const supportsAdoptedStylesheets = isBrowser && "adoptedStyleSheets" in Document
129
213
  function isShadow(node) {
130
214
  return node instanceof ShadowRoot || node?.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !!node?.host;
131
215
  }
132
- function isDocument(node) {
133
- return node?.nodeType === Node.DOCUMENT_NODE;
134
- }
135
- function getOwnerDocument(node) {
136
- return (isDocument(node) ? node : node.ownerDocument) || null;
137
- }
138
216
  function getWindow(node) {
139
217
  const ownerDocument = getOwnerDocument(node);
140
218
  return ownerDocument?.defaultView || null;
141
219
  }
142
- const useLayoutEffect = isBrowser ? React.useLayoutEffect : React.useEffect;
143
220
  export {
144
221
  Root
145
222
  };
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import * as Ariakit from "@ariakit/react";
3
2
  import { type FocusableProps } from "./~utils.js";
4
3
  /**
5
4
  * Compound component for a select element, which allows the user to select a value from a list of options.
@@ -20,8 +19,15 @@ import { type FocusableProps } from "./~utils.js";
20
19
  * </Field>
21
20
  * ```
22
21
  */
23
- declare const SelectRoot: React.ForwardRefExoticComponent<Pick<Ariakit.RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
24
- interface HtmlSelectProps extends Omit<FocusableProps<"select">, "multiple" | "size"> {
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";
25
31
  }
26
32
  /**
27
33
  * The actual select element to be used inside `Select.Root`. This is a wrapper around the
@@ -1,20 +1,20 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import cx from "classnames";
4
- import * as Ariakit from "@ariakit/react";
4
+ import { Role } from "@ariakit/react/role";
5
5
  import {
6
6
  forwardRef,
7
7
  isBrowser
8
8
  } from "./~utils.js";
9
9
  import { DisclosureArrow } from "./Icon.js";
10
- import { useFieldId } from "./Field.js";
10
+ import { FieldControl } from "./Field.js";
11
11
  const supportsHas = isBrowser && CSS?.supports?.("selector(:has(+ *))");
12
12
  const HtmlSelectContext = React.createContext(() => {
13
13
  });
14
14
  const SelectRoot = forwardRef((props, forwardedRef) => {
15
15
  const [isHtmlSelect, setIsHtmlSelect] = React.useState(false);
16
16
  return /* @__PURE__ */ jsx(HtmlSelectContext.Provider, { value: setIsHtmlSelect, children: /* @__PURE__ */ jsx(
17
- Ariakit.Role.div,
17
+ Role.div,
18
18
  {
19
19
  ...props,
20
20
  className: cx("\u{1F95D}-select-root", props.className),
@@ -25,8 +25,8 @@ const SelectRoot = forwardRef((props, forwardedRef) => {
25
25
  });
26
26
  const HtmlSelect = forwardRef(
27
27
  (props, forwardedRef) => {
28
+ const { id, variant = "solid", ...rest } = props;
28
29
  const setIsHtmlSelect = React.useContext(HtmlSelectContext);
29
- const fieldId = useFieldId();
30
30
  React.useEffect(
31
31
  function updateContext() {
32
32
  setIsHtmlSelect(true);
@@ -35,14 +35,20 @@ const HtmlSelect = forwardRef(
35
35
  );
36
36
  return /* @__PURE__ */ jsxs(Fragment, { children: [
37
37
  /* @__PURE__ */ jsx(
38
- Ariakit.Role.select,
38
+ FieldControl,
39
39
  {
40
- id: fieldId,
41
- ...props,
42
- className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
43
- "data-kiwi-tone": "neutral",
44
- "data-kiwi-variant": "solid",
45
- ref: forwardedRef
40
+ type: "textlike",
41
+ id,
42
+ render: /* @__PURE__ */ jsx(
43
+ Role.select,
44
+ {
45
+ ...rest,
46
+ className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
47
+ "data-kiwi-tone": "neutral",
48
+ "data-kiwi-variant": variant,
49
+ ref: forwardedRef
50
+ }
51
+ )
46
52
  }
47
53
  ),
48
54
  /* @__PURE__ */ jsx(DisclosureArrow, { className: "\u{1F95D}-select-arrow" })
@@ -0,0 +1,25 @@
1
+ import { type BaseProps } from "./~utils.js";
2
+ interface SkeletonPropsBase extends Omit<BaseProps, "children"> {
3
+ }
4
+ /**
5
+ * Represents the loaded content before it finishes loading.
6
+ *
7
+ * Example:
8
+ * ```tsx
9
+ * <Skeleton variant="object" size="small" shape="square" />
10
+ * <Skeleton variant="text" size="medium" />
11
+ * ```
12
+ */
13
+ export declare const Skeleton: import("react").ForwardRefExoticComponent<SkeletonPropsBase & {
14
+ /**
15
+ * The type of the skeleton item. Available variants: `text`, `object`.
16
+ * @default "text"
17
+ */
18
+ variant?: "text" | "object";
19
+ /**
20
+ * The size of the skeleton item. Available sizes: `xsmall`, `small`, `medium`, `large`, `xlarge`
21
+ * @default "medium"
22
+ */
23
+ size?: "xsmall" | "small" | "medium" | "large" | "xlarge";
24
+ } & import("react").RefAttributes<HTMLElement | HTMLDivElement>>;
25
+ export {};
@@ -0,0 +1,23 @@
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 Skeleton = forwardRef(
6
+ (props, forwardedRef) => {
7
+ const { variant = "text", size = "medium", ...rest } = props;
8
+ return /* @__PURE__ */ jsx(
9
+ Role.div,
10
+ {
11
+ ...rest,
12
+ ref: forwardedRef,
13
+ className: cx("\u{1F95D}-skeleton", props.className),
14
+ "data-kiwi-variant": variant,
15
+ "data-kiwi-size": size,
16
+ "aria-hidden": true
17
+ }
18
+ );
19
+ }
20
+ );
21
+ export {
22
+ Skeleton
23
+ };
@@ -0,0 +1,31 @@
1
+ import { type BaseProps } from "./~utils.js";
2
+ interface SpinnerProps extends BaseProps {
3
+ /**
4
+ * A text alternative for the spinner.
5
+ * @default "Loading…"
6
+ */
7
+ alt?: string;
8
+ /**
9
+ * The size of the spinner.
10
+ * @default "medium"
11
+ */
12
+ size?: "small" | "medium" | "large" | "xlarge";
13
+ /**
14
+ * The tone of the spinner.
15
+ * @default "neutral"
16
+ */
17
+ tone?: "neutral" | "accent";
18
+ }
19
+ /**
20
+ * A loading spinner.
21
+ *
22
+ * Example:
23
+ * ```tsx
24
+ * <Spinner />
25
+ * ```
26
+ *
27
+ * Supports a `tone` prop to change the tone (color) of the spinner.
28
+ * Supports a `size` prop to change the size of the spinner.
29
+ */
30
+ export declare const Spinner: import("react").ForwardRefExoticComponent<SpinnerProps & import("react").RefAttributes<HTMLElement | HTMLDivElement>>;
31
+ export {};
@@ -0,0 +1,54 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Role } from "@ariakit/react/role";
3
+ import cx from "classnames";
4
+ import { VisuallyHidden } from "./VisuallyHidden.js";
5
+ import { forwardRef } from "./~utils.js";
6
+ const Spinner = forwardRef(
7
+ (props, forwardedRef) => {
8
+ const {
9
+ alt = "Loading\u2026",
10
+ size = "medium",
11
+ tone = "neutral",
12
+ ...rest
13
+ } = props;
14
+ return /* @__PURE__ */ jsxs(
15
+ Role,
16
+ {
17
+ ...rest,
18
+ "data-kiwi-size": size,
19
+ "data-kiwi-tone": tone,
20
+ "data-kiwi-variant": "indeterminate",
21
+ className: cx("\u{1F95D}-spinner", props.className),
22
+ ref: forwardedRef,
23
+ children: [
24
+ /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", className: "\u{1F95D}-spinner-svg", viewBox: "0 0 16 16", children: [
25
+ /* @__PURE__ */ jsx(
26
+ "circle",
27
+ {
28
+ pathLength: "100",
29
+ className: "\u{1F95D}-spinner-svg-track",
30
+ cx: "8",
31
+ cy: "8",
32
+ r: "6.5"
33
+ }
34
+ ),
35
+ /* @__PURE__ */ jsx(
36
+ "circle",
37
+ {
38
+ pathLength: "100",
39
+ className: "\u{1F95D}-spinner-svg-fill",
40
+ cx: "8",
41
+ cy: "8",
42
+ r: "6.5"
43
+ }
44
+ )
45
+ ] }),
46
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: alt })
47
+ ]
48
+ }
49
+ );
50
+ }
51
+ );
52
+ export {
53
+ Spinner
54
+ };
@@ -1,7 +1,7 @@
1
- import * as Ariakit from "@ariakit/react";
1
+ import { type CheckboxProps as AkCheckboxProps } from "@ariakit/react/checkbox";
2
2
  import { type FocusableProps } from "./~utils.js";
3
3
  type InputBaseProps = Omit<FocusableProps<"input">, "defaultValue" | "value">;
4
- type CheckboxOwnProps = Pick<Ariakit.CheckboxProps, "value" | "defaultChecked" | "checked" | "onChange">;
4
+ type CheckboxOwnProps = Pick<AkCheckboxProps, "value" | "defaultChecked" | "checked" | "onChange">;
5
5
  interface SwitchProps extends InputBaseProps, CheckboxOwnProps {
6
6
  /** The default checked state of the toggle switch. */
7
7
  defaultChecked?: boolean;
@@ -1,20 +1,28 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
- import * as Ariakit from "@ariakit/react";
4
- import { useFieldId } from "./Field.js";
3
+ import {
4
+ Checkbox as AkCheckbox
5
+ } from "@ariakit/react/checkbox";
6
+ import { FieldControl } from "./Field.js";
5
7
  import { forwardRef } from "./~utils.js";
6
8
  const Switch = forwardRef(
7
9
  (props, forwardedRef) => {
8
- const fieldId = useFieldId();
10
+ const { id, ...rest } = props;
9
11
  return /* @__PURE__ */ jsx(
10
- Ariakit.Checkbox,
12
+ FieldControl,
11
13
  {
12
- accessibleWhenDisabled: true,
13
- id: fieldId,
14
- ...props,
15
- className: cx("\u{1F95D}-switch", props.className),
16
- role: "switch",
17
- ref: forwardedRef
14
+ type: "checkable",
15
+ id,
16
+ render: /* @__PURE__ */ jsx(
17
+ AkCheckbox,
18
+ {
19
+ accessibleWhenDisabled: true,
20
+ ...rest,
21
+ className: cx("\u{1F95D}-switch", props.className),
22
+ role: "switch",
23
+ ref: forwardedRef
24
+ }
25
+ )
18
26
  }
19
27
  );
20
28
  }