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

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 (69) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +13 -2
  3. package/dist/DEV/bricks/Checkbox.js +7 -14
  4. package/dist/DEV/bricks/Description.js +7 -14
  5. package/dist/DEV/bricks/DropdownMenu.js +58 -20
  6. package/dist/DEV/bricks/Field.internal.js +47 -0
  7. package/dist/DEV/bricks/Field.js +116 -85
  8. package/dist/DEV/bricks/Icon.js +144 -7
  9. package/dist/DEV/bricks/Label.js +4 -10
  10. package/dist/DEV/bricks/Radio.js +7 -14
  11. package/dist/DEV/bricks/Root.internal.js +17 -0
  12. package/dist/DEV/bricks/Root.js +73 -27
  13. package/dist/DEV/bricks/Select.js +9 -15
  14. package/dist/DEV/bricks/Spinner.js +23 -8
  15. package/dist/DEV/bricks/Switch.js +8 -15
  16. package/dist/DEV/bricks/Table.js +71 -37
  17. package/dist/DEV/bricks/Tabs.js +4 -29
  18. package/dist/DEV/bricks/TextBox.js +23 -37
  19. package/dist/DEV/bricks/Tooltip.js +1 -1
  20. package/dist/DEV/bricks/TreeItem.js +92 -10
  21. package/dist/DEV/bricks/index.js +3 -1
  22. package/dist/DEV/bricks/styles.css.js +1 -1
  23. package/dist/DEV/bricks/~hooks.js +3 -1
  24. package/dist/DEV/bricks/~utils.js +17 -0
  25. package/dist/DEV/foundations/styles.css.js +1 -1
  26. package/dist/bricks/Badge.d.ts +1 -1
  27. package/dist/bricks/Checkbox.d.ts +13 -5
  28. package/dist/bricks/Checkbox.js +7 -14
  29. package/dist/bricks/Description.d.ts +2 -6
  30. package/dist/bricks/Description.js +7 -14
  31. package/dist/bricks/DropdownMenu.d.ts +9 -9
  32. package/dist/bricks/DropdownMenu.js +57 -19
  33. package/dist/bricks/Field.d.ts +63 -27
  34. package/dist/bricks/Field.internal.d.ts +33 -0
  35. package/dist/bricks/Field.internal.js +47 -0
  36. package/dist/bricks/Field.js +111 -84
  37. package/dist/bricks/Icon.d.ts +12 -1
  38. package/dist/bricks/Icon.js +142 -7
  39. package/dist/bricks/Label.d.ts +5 -12
  40. package/dist/bricks/Label.js +4 -10
  41. package/dist/bricks/Radio.d.ts +14 -5
  42. package/dist/bricks/Radio.js +7 -14
  43. package/dist/bricks/Root.d.ts +12 -0
  44. package/dist/bricks/Root.internal.d.ts +6 -0
  45. package/dist/bricks/Root.internal.js +17 -0
  46. package/dist/bricks/Root.js +73 -27
  47. package/dist/bricks/Select.d.ts +29 -12
  48. package/dist/bricks/Select.js +9 -15
  49. package/dist/bricks/Spinner.js +23 -8
  50. package/dist/bricks/Switch.d.ts +12 -5
  51. package/dist/bricks/Switch.js +8 -15
  52. package/dist/bricks/Table.d.ts +94 -37
  53. package/dist/bricks/Table.js +69 -36
  54. package/dist/bricks/Tabs.d.ts +3 -4
  55. package/dist/bricks/Tabs.js +4 -29
  56. package/dist/bricks/TextBox.d.ts +42 -19
  57. package/dist/bricks/TextBox.js +23 -37
  58. package/dist/bricks/Tooltip.js +1 -1
  59. package/dist/bricks/TreeItem.d.ts +53 -9
  60. package/dist/bricks/TreeItem.js +81 -10
  61. package/dist/bricks/index.d.ts +2 -1
  62. package/dist/bricks/index.js +3 -1
  63. package/dist/bricks/styles.css.js +1 -1
  64. package/dist/bricks/~hooks.d.ts +8 -0
  65. package/dist/bricks/~hooks.js +3 -1
  66. package/dist/bricks/~utils.d.ts +8 -0
  67. package/dist/bricks/~utils.js +17 -0
  68. package/dist/foundations/styles.css.js +1 -1
  69. package/package.json +1 -1
@@ -2,10 +2,21 @@ import { jsx } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import cx from "classnames";
4
4
  import { Role } from "@ariakit/react/role";
5
- import { forwardRef } from "./~utils.js";
5
+ import {
6
+ forwardRef,
7
+ getOwnerDocument,
8
+ parseDOM
9
+ } from "./~utils.js";
10
+ import {
11
+ HtmlSanitizerContext,
12
+ spriteSheetId,
13
+ useRootNode
14
+ } from "./Root.internal.js";
15
+ import { useLatestRef, useSafeContext } from "./~hooks.js";
6
16
  const Icon = forwardRef((props, forwardedRef) => {
7
- const { href, size, alt, ...rest } = props;
17
+ const { href: hrefProp, size, alt, ...rest } = props;
8
18
  const isDecorative = !alt;
19
+ const hrefBase = useNormalizedHrefBase(hrefProp);
9
20
  return /* @__PURE__ */ jsx(
10
21
  Role.svg,
11
22
  {
@@ -16,20 +27,82 @@ const Icon = forwardRef((props, forwardedRef) => {
16
27
  "data-kiwi-size": size,
17
28
  className: cx("\u{1F95D}-icon", props.className),
18
29
  ref: forwardedRef,
19
- children: href ? /* @__PURE__ */ jsx("use", { href: toIconHref(href, size) }) : null
30
+ children: hrefBase ? /* @__PURE__ */ jsx("use", { href: toIconHref(hrefBase, size) }) : null
20
31
  }
21
32
  );
22
33
  });
23
34
  DEV: Icon.displayName = "Icon";
24
- function toIconHref(href, size) {
25
- const separator = href.includes("#") ? "--" : "#";
35
+ function toIconHref(hrefBase, size) {
36
+ const separator = hrefBase.includes("#") ? "--" : "#";
26
37
  const suffix = toIconId(size);
27
- return `${href}${separator}${suffix}`;
38
+ return `${hrefBase}${separator}${suffix}`;
28
39
  }
29
40
  function toIconId(size) {
30
41
  if (size === "large") return "icon-large";
31
42
  return "icon";
32
43
  }
44
+ function useNormalizedHrefBase(rawHref) {
45
+ const generatedId = React.useId();
46
+ const sanitizeHtml = useLatestRef(useSafeContext(HtmlSanitizerContext));
47
+ const rootNode = useRootNode();
48
+ const inlineHref = React.useRef(void 0);
49
+ const getClientSnapshot = () => {
50
+ const ownerDocument = getOwnerDocument(rootNode);
51
+ if (!rawHref || !ownerDocument) return void 0;
52
+ if (isHttpProtocol(rawHref, ownerDocument)) return rawHref;
53
+ return inlineHref.current;
54
+ };
55
+ const subscribe = React.useCallback(
56
+ (notify) => {
57
+ const ownerDocument = getOwnerDocument(rootNode);
58
+ const spriteSheet = ownerDocument?.getElementById(spriteSheetId);
59
+ if (!rawHref || !ownerDocument || !spriteSheet) return () => {
60
+ };
61
+ if (isHttpProtocol(rawHref, ownerDocument)) return () => {
62
+ };
63
+ const cache = spriteSheet[Symbol.for("\u{1F95D}")]?.icons;
64
+ if (!cache) return () => {
65
+ };
66
+ const prefix = `\u{1F95D}${generatedId}`;
67
+ if (cache.has(rawHref)) {
68
+ inlineHref.current = cache.get(rawHref);
69
+ notify();
70
+ return () => {
71
+ };
72
+ }
73
+ const abortController = new AbortController();
74
+ const { signal } = abortController;
75
+ (async () => {
76
+ const response = await fetch(rawHref, { signal });
77
+ if (!response.ok) throw new Error(`Failed to fetch ${rawHref}`);
78
+ const fetchedSvgString = sanitizeHtml.current(await response.text());
79
+ const parsedSvgContent = parseDOM(fetchedSvgString, {
80
+ ownerDocument
81
+ });
82
+ const symbols = parsedSvgContent.querySelectorAll("symbol");
83
+ for (const symbol of symbols) {
84
+ symbol.id = `${prefix}--${symbol.id}`;
85
+ if (ownerDocument.getElementById(symbol.id)) continue;
86
+ spriteSheet.appendChild(symbol.cloneNode(true));
87
+ }
88
+ inlineHref.current = `#${prefix}`;
89
+ cache.set(rawHref, inlineHref.current);
90
+ if (!signal.aborted) notify();
91
+ })();
92
+ return () => abortController.abort();
93
+ },
94
+ [rawHref, rootNode, sanitizeHtml, generatedId]
95
+ );
96
+ return React.useSyncExternalStore(
97
+ subscribe,
98
+ getClientSnapshot,
99
+ () => rawHref
100
+ );
101
+ }
102
+ function isHttpProtocol(url, ownerDocument) {
103
+ const { protocol } = new URL(url, ownerDocument.baseURI);
104
+ return ["http:", "https:"].includes(protocol);
105
+ }
33
106
  const DisclosureArrow = forwardRef(
34
107
  (props, forwardedRef) => {
35
108
  const { direction = "down", ...rest } = props;
@@ -116,9 +189,73 @@ const Dismiss = forwardRef(
116
189
  }
117
190
  );
118
191
  DEV: Dismiss.displayName = "Dismiss";
192
+ const StatusWarning = forwardRef(
193
+ (props, forwardedRef) => {
194
+ return /* @__PURE__ */ jsx(
195
+ Icon,
196
+ {
197
+ ...props,
198
+ render: /* @__PURE__ */ jsx(
199
+ Role.svg,
200
+ {
201
+ width: "16",
202
+ height: "16",
203
+ fill: "currentColor",
204
+ viewBox: "0 0 16 16",
205
+ render: props.render,
206
+ children: /* @__PURE__ */ jsx(
207
+ "path",
208
+ {
209
+ fill: "currentColor",
210
+ fillRule: "evenodd",
211
+ d: "M8.354 2.06a.5.5 0 0 0-.708 0L2.061 7.647a.5.5 0 0 0 0 .707l5.585 5.586a.5.5 0 0 0 .708 0l5.585-5.586a.5.5 0 0 0 0-.707L8.354 2.061Zm-1.415-.707a1.5 1.5 0 0 1 2.122 0l5.585 5.586a1.5 1.5 0 0 1 0 2.122l-5.585 5.585a1.5 1.5 0 0 1-2.122 0L1.354 9.061a1.5 1.5 0 0 1 0-2.122l5.585-5.586ZM8.75 10.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM8.5 8.5v-3a.5.5 0 0 0-1 0v3a.5.5 0 0 0 1 0Z",
212
+ clipRule: "evenodd"
213
+ }
214
+ )
215
+ }
216
+ ),
217
+ ref: forwardedRef
218
+ }
219
+ );
220
+ }
221
+ );
222
+ DEV: StatusWarning.displayName = "StatusWarning";
223
+ const MoreHorizontal = forwardRef(
224
+ (props, forwardedRef) => {
225
+ return /* @__PURE__ */ jsx(
226
+ Icon,
227
+ {
228
+ ...props,
229
+ render: /* @__PURE__ */ jsx(
230
+ Role.svg,
231
+ {
232
+ width: "16",
233
+ height: "16",
234
+ viewBox: "0 0 16 16",
235
+ fill: "none",
236
+ render: props.render,
237
+ children: /* @__PURE__ */ jsx(
238
+ "path",
239
+ {
240
+ fill: "currentColor",
241
+ fillRule: "evenodd",
242
+ d: "M3 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm6-1a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm5 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z",
243
+ clipRule: "evenodd"
244
+ }
245
+ )
246
+ }
247
+ ),
248
+ ref: forwardedRef
249
+ }
250
+ );
251
+ }
252
+ );
253
+ DEV: MoreHorizontal.displayName = "MoreHorizontal";
119
254
  export {
120
255
  Checkmark,
121
256
  DisclosureArrow,
122
257
  Dismiss,
123
- Icon
258
+ Icon,
259
+ MoreHorizontal,
260
+ StatusWarning
124
261
  };
@@ -2,19 +2,13 @@ import { jsx } from "react/jsx-runtime";
2
2
  import cx from "classnames";
3
3
  import { Role } from "@ariakit/react/role";
4
4
  import { forwardRef } from "./~utils.js";
5
- import { FieldLabel } from "./Field.js";
6
5
  const Label = forwardRef((props, forwardedRef) => {
7
6
  return /* @__PURE__ */ jsx(
8
- FieldLabel,
7
+ Role.label,
9
8
  {
10
- render: /* @__PURE__ */ jsx(
11
- Role.label,
12
- {
13
- ...props,
14
- className: cx("\u{1F95D}-label", props.className),
15
- ref: forwardedRef
16
- }
17
- )
9
+ ...props,
10
+ className: cx("\u{1F95D}-label", props.className),
11
+ ref: forwardedRef
18
12
  }
19
13
  );
20
14
  });
@@ -3,24 +3,17 @@ import cx from "classnames";
3
3
  import {
4
4
  Radio as AkRadio
5
5
  } from "@ariakit/react/radio";
6
- import { FieldControl } from "./Field.js";
7
6
  import { forwardRef } from "./~utils.js";
7
+ import { useFieldControlType } from "./Field.internal.js";
8
8
  const Radio = forwardRef((props, forwardedRef) => {
9
- const { id, ...rest } = props;
9
+ useFieldControlType("checkable");
10
10
  return /* @__PURE__ */ jsx(
11
- FieldControl,
11
+ AkRadio,
12
12
  {
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
- )
13
+ accessibleWhenDisabled: true,
14
+ ...props,
15
+ className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
16
+ ref: forwardedRef
24
17
  }
25
18
  );
26
19
  });
@@ -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
+ };
@@ -6,15 +6,33 @@ import { PortalContext } from "@ariakit/react/portal";
6
6
  import cx from "classnames";
7
7
  import foundationsCss from "../foundations/styles.css.js";
8
8
  import bricksCss from "./styles.css.js";
9
- import { forwardRef, isBrowser } from "./~utils.js";
10
- import { useIsClient, 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";
11
23
  const css = foundationsCss + bricksCss;
12
24
  const Root = forwardRef((props, forwardedRef) => {
13
- const { children, synchronizeColorScheme = false, ...rest } = props;
25
+ const {
26
+ children,
27
+ synchronizeColorScheme = false,
28
+ unstable_htmlSanitizer = identity,
29
+ ...rest
30
+ } = props;
14
31
  const [portalContainer, setPortalContainer] = React.useState(null);
15
32
  return /* @__PURE__ */ jsxs(RootInternal, { ...rest, ref: forwardedRef, children: [
16
33
  /* @__PURE__ */ jsx(Styles, {}),
17
34
  /* @__PURE__ */ jsx(Fonts, {}),
35
+ /* @__PURE__ */ jsx(InlineSpriteSheet, {}),
18
36
  synchronizeColorScheme ? /* @__PURE__ */ jsx(SynchronizeColorScheme, { colorScheme: props.colorScheme }) : null,
19
37
  /* @__PURE__ */ jsx(
20
38
  PortalContainer,
@@ -24,14 +42,10 @@ const Root = forwardRef((props, forwardedRef) => {
24
42
  ref: setPortalContainer
25
43
  }
26
44
  ),
27
- /* @__PURE__ */ jsx(PortalContext.Provider, { value: portalContainer, children })
45
+ /* @__PURE__ */ jsx(PortalContext.Provider, { value: portalContainer, children: /* @__PURE__ */ jsx(HtmlSanitizerContext.Provider, { value: unstable_htmlSanitizer, children }) })
28
46
  ] });
29
47
  });
30
48
  DEV: Root.displayName = "Root";
31
- const RootNodeContext = React.createContext(null);
32
- function useRootNode() {
33
- return React.useContext(RootNodeContext);
34
- }
35
49
  const RootInternal = forwardRef(
36
50
  (props, forwardedRef) => {
37
51
  const { children, colorScheme, density, ...rest } = props;
@@ -72,10 +86,9 @@ function SynchronizeColorScheme({
72
86
  return null;
73
87
  }
74
88
  const PortalContainer = forwardRef((props, forwardedRef) => {
75
- const isClient = useIsClient();
76
89
  const rootNode = useRootNode();
77
- if (!isClient) return null;
78
- const destination = rootNode && isDocument(rootNode) ? rootNode.body : rootNode;
90
+ if (!rootNode) return null;
91
+ const destination = isDocument(rootNode) ? rootNode.body : rootNode;
79
92
  if (!destination) return null;
80
93
  return ReactDOM.createPortal(
81
94
  /* @__PURE__ */ jsx(
@@ -95,35 +108,46 @@ function Styles() {
95
108
  const rootNode = useRootNode();
96
109
  useLayoutEffect(() => {
97
110
  if (!rootNode) return;
98
- loadStyles(rootNode, { css });
111
+ const { cleanup } = loadStyles(rootNode, { css });
112
+ return cleanup;
99
113
  }, [rootNode]);
100
114
  return null;
101
115
  }
102
- const styleSheets = /* @__PURE__ */ new WeakMap();
103
- function loadStyles(rootNode, { css: css2 }) {
116
+ const styleSheets = new Map(
117
+ Object.entries({ default: /* @__PURE__ */ new WeakMap() })
118
+ );
119
+ function loadStyles(rootNode, { css: css2, key = "default" }) {
120
+ let cleanup = () => {
121
+ };
104
122
  const loaded = (() => {
105
123
  if (!isBrowser) return false;
106
124
  const ownerDocument = getOwnerDocument(rootNode);
107
125
  const _window = getWindow(rootNode);
108
126
  if (!ownerDocument || !_window) return false;
109
- if (!supportsAdoptedStylesheets && !rootNode.querySelector("style[data-kiwi]")) {
127
+ if (!supportsAdoptedStylesheets && !rootNode.querySelector(`style[data-kiwi="${key}"]`)) {
110
128
  const styleElement = ownerDocument.createElement("style");
111
- styleElement.dataset.kiwi = "true";
129
+ styleElement.dataset.kiwi = key;
112
130
  styleElement.textContent = css2;
113
131
  (rootNode.head || rootNode).appendChild(styleElement);
132
+ cleanup = () => styleElement.remove();
114
133
  return true;
115
134
  }
116
- const styleSheet = styleSheets.get(_window) || new _window.CSSStyleSheet();
117
- if (!styleSheets.has(_window)) {
118
- styleSheets.set(_window, styleSheet);
135
+ const styleSheet = styleSheets.get(key)?.get(_window) || new _window.CSSStyleSheet();
136
+ if (!styleSheets.get(key)?.has(_window)) {
137
+ styleSheets.get(key)?.set(_window, styleSheet);
119
138
  }
120
139
  styleSheet.replaceSync(css2);
121
140
  if (!rootNode.adoptedStyleSheets.includes(styleSheet)) {
122
141
  rootNode.adoptedStyleSheets.push(styleSheet);
142
+ cleanup = () => {
143
+ rootNode.adoptedStyleSheets = rootNode.adoptedStyleSheets.filter(
144
+ (sheet) => sheet !== styleSheet
145
+ );
146
+ };
123
147
  }
124
148
  return true;
125
149
  })();
126
- return { loaded };
150
+ return { loaded, cleanup };
127
151
  }
128
152
  function Fonts() {
129
153
  const rootNode = useRootNode();
@@ -133,6 +157,35 @@ function Fonts() {
133
157
  }, [rootNode]);
134
158
  return null;
135
159
  }
160
+ function InlineSpriteSheet() {
161
+ const rootNode = useRootNode();
162
+ React.useEffect(
163
+ function maybeCreateSpriteSheet() {
164
+ const ownerDocument = getOwnerDocument(rootNode);
165
+ if (!ownerDocument) return;
166
+ const spriteSheet = ownerDocument?.getElementById(spriteSheetId);
167
+ if (spriteSheet) return;
168
+ const svg = ownerDocument.createElementNS(
169
+ "http://www.w3.org/2000/svg",
170
+ "svg"
171
+ );
172
+ svg.id = spriteSheetId;
173
+ svg.style.display = "none";
174
+ Object.defineProperty(svg, Symbol.for("\u{1F95D}"), {
175
+ value: { icons: /* @__PURE__ */ new Map() }
176
+ // Map of icon URLs that have already been inlined.
177
+ });
178
+ ownerDocument.body.appendChild(svg);
179
+ return () => {
180
+ if (svg.isConnected) {
181
+ ownerDocument.body.removeChild(svg);
182
+ }
183
+ };
184
+ },
185
+ [rootNode]
186
+ );
187
+ return null;
188
+ }
136
189
  function loadFonts(rootNode) {
137
190
  const ownerWindow = getWindow(rootNode);
138
191
  if (!ownerWindow || Array.from(ownerWindow.document.fonts).some(
@@ -161,17 +214,10 @@ const supportsAdoptedStylesheets = isBrowser && "adoptedStyleSheets" in Document
161
214
  function isShadow(node) {
162
215
  return node instanceof ShadowRoot || node?.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !!node?.host;
163
216
  }
164
- function isDocument(node) {
165
- return node?.nodeType === Node.DOCUMENT_NODE;
166
- }
167
- function getOwnerDocument(node) {
168
- return (isDocument(node) ? node : node.ownerDocument) || null;
169
- }
170
217
  function getWindow(node) {
171
218
  const ownerDocument = getOwnerDocument(node);
172
219
  return ownerDocument?.defaultView || null;
173
220
  }
174
- const useLayoutEffect = isBrowser ? React.useLayoutEffect : React.useEffect;
175
221
  export {
176
222
  Root
177
223
  };
@@ -7,11 +7,12 @@ import {
7
7
  isBrowser
8
8
  } from "./~utils.js";
9
9
  import { DisclosureArrow } from "./Icon.js";
10
- import { FieldControl } from "./Field.js";
10
+ import { useFieldControlType } from "./Field.internal.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
+ useFieldControlType("textlike");
15
16
  const [isHtmlSelect, setIsHtmlSelect] = React.useState(false);
16
17
  return /* @__PURE__ */ jsx(HtmlSelectContext.Provider, { value: setIsHtmlSelect, children: /* @__PURE__ */ jsx(
17
18
  Role.div,
@@ -25,7 +26,7 @@ const SelectRoot = forwardRef((props, forwardedRef) => {
25
26
  });
26
27
  const HtmlSelect = forwardRef(
27
28
  (props, forwardedRef) => {
28
- const { id, variant = "solid", ...rest } = props;
29
+ const { variant = "solid", ...rest } = props;
29
30
  const setIsHtmlSelect = React.useContext(HtmlSelectContext);
30
31
  React.useEffect(
31
32
  function updateContext() {
@@ -35,20 +36,13 @@ const HtmlSelect = forwardRef(
35
36
  );
36
37
  return /* @__PURE__ */ jsxs(Fragment, { children: [
37
38
  /* @__PURE__ */ jsx(
38
- FieldControl,
39
+ Role.select,
39
40
  {
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
- )
41
+ ...rest,
42
+ className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
43
+ "data-kiwi-tone": "neutral",
44
+ "data-kiwi-variant": variant,
45
+ ref: forwardedRef
52
46
  }
53
47
  ),
54
48
  /* @__PURE__ */ jsx(DisclosureArrow, { className: "\u{1F95D}-select-arrow" })
@@ -17,17 +17,32 @@ const Spinner = forwardRef(
17
17
  ...rest,
18
18
  "data-kiwi-size": size,
19
19
  "data-kiwi-tone": tone,
20
+ "data-kiwi-variant": "indeterminate",
20
21
  className: cx("\u{1F95D}-spinner", props.className),
21
22
  ref: forwardedRef,
22
23
  children: [
23
- /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "\u{1F95D}-spinner-svg", viewBox: "0 0 16 16", children: /* @__PURE__ */ jsx(
24
- "path",
25
- {
26
- stroke: "currentColor",
27
- strokeLinecap: "round",
28
- d: "M9.5 1.674a6.503 6.503 0 0 1 0 12.652m-3-12.652a6.503 6.503 0 0 0 0 12.652"
29
- }
30
- ) }),
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
+ ] }),
31
46
  /* @__PURE__ */ jsx(VisuallyHidden, { children: alt })
32
47
  ]
33
48
  }
@@ -3,26 +3,19 @@ import cx from "classnames";
3
3
  import {
4
4
  Checkbox as AkCheckbox
5
5
  } from "@ariakit/react/checkbox";
6
- import { FieldControl } from "./Field.js";
7
6
  import { forwardRef } from "./~utils.js";
7
+ import { useFieldControlType } from "./Field.internal.js";
8
8
  const Switch = forwardRef(
9
9
  (props, forwardedRef) => {
10
- const { id, ...rest } = props;
10
+ useFieldControlType("checkable");
11
11
  return /* @__PURE__ */ jsx(
12
- FieldControl,
12
+ AkCheckbox,
13
13
  {
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
- )
14
+ accessibleWhenDisabled: true,
15
+ ...props,
16
+ className: cx("\u{1F95D}-switch", props.className),
17
+ role: "switch",
18
+ ref: forwardedRef
26
19
  }
27
20
  );
28
21
  }