@itwin/itwinui-react 5.0.0-alpha.10 → 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.
- package/CHANGELOG.md +116 -0
- package/dist/DEV/bricks/DropdownMenu.js +1 -1
- package/dist/DEV/bricks/Icon.js +112 -7
- package/dist/DEV/bricks/Root.internal.js +17 -0
- package/dist/DEV/bricks/Root.js +73 -27
- package/dist/DEV/bricks/Spinner.js +23 -8
- package/dist/DEV/bricks/Tooltip.js +1 -1
- package/dist/DEV/bricks/TreeItem.js +6 -3
- package/dist/DEV/bricks/styles.css.js +1 -1
- package/dist/DEV/bricks/~hooks.js +3 -1
- package/dist/DEV/bricks/~utils.js +17 -0
- package/dist/bricks/Badge.d.ts +1 -1
- package/dist/bricks/DropdownMenu.js +1 -1
- package/dist/bricks/Icon.d.ts +9 -1
- package/dist/bricks/Icon.js +111 -7
- package/dist/bricks/Root.d.ts +12 -0
- package/dist/bricks/Root.internal.d.ts +6 -0
- package/dist/bricks/Root.internal.js +17 -0
- package/dist/bricks/Root.js +73 -27
- package/dist/bricks/Spinner.js +23 -8
- package/dist/bricks/Tooltip.js +1 -1
- package/dist/bricks/TreeItem.d.ts +7 -1
- package/dist/bricks/TreeItem.js +6 -3
- package/dist/bricks/styles.css.js +1 -1
- package/dist/bricks/~hooks.d.ts +8 -0
- package/dist/bricks/~hooks.js +3 -1
- package/dist/bricks/~utils.d.ts +8 -0
- package/dist/bricks/~utils.js +17 -0
- package/package.json +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 5.0.0-alpha.11
|
|
4
|
+
|
|
5
|
+
- Added `error` prop to `<Tree.Item>`.
|
|
6
|
+
- Implemented fallback strategy for `<Icon>`, so that non-HTTP URLs are fetched at runtime.
|
|
7
|
+
- Added `unstable_htmlSanitizer` prop to `<Root>`.
|
|
8
|
+
- Added `tone="accent"` support to `<Badge>`.
|
|
9
|
+
- Adjusted `DropdownMenu` and `Tooltip` to be portaled by default.
|
|
10
|
+
- Styling changes:
|
|
11
|
+
- Added shimmer animation to `<Skeleton>`.
|
|
12
|
+
- Updated `<Spinner>` visuals and animation to match `<ProgressBar>`.
|
|
13
|
+
- Bug fixes:
|
|
14
|
+
- Fixed styles not unloading when `<Root>` is unmounted.
|
|
15
|
+
- Fixed `<Anchor>` underline not showing when rendered as a `<button>`.
|
|
16
|
+
- Fixed `<Tree.ItemAction visible>` affecting the visibility of all actions.
|
|
17
|
+
- Fixed vertical centering in `<Tab.TabList>`.
|
|
18
|
+
- Fixed `Tab` active stripe positioning and animation.
|
|
19
|
+
- Fixed `<Button variant="solid" tone="accent">` icon fill in pressed state.
|
|
20
|
+
|
|
21
|
+
## 5.0.0-alpha.10
|
|
22
|
+
|
|
23
|
+
- Added initial `<Skeleton>` component.
|
|
24
|
+
- Added initial `<ProgressBar>` component.
|
|
25
|
+
- Fixed various UX and accessibility issues related to `<Tree.Item>` actions visibility.
|
|
26
|
+
- Actions no longer get stuck.
|
|
27
|
+
- Tooltips can now be hovered.
|
|
28
|
+
- Focus correctly returns to actions after menu closes.
|
|
29
|
+
- Keyboard events no longer affect the main treeitem.
|
|
30
|
+
- Reduced `<Field>` spacing.
|
|
31
|
+
- Experimental changes in `<Icon>` component's `href` handling.
|
|
32
|
+
|
|
33
|
+
## 5.0.0-alpha.9
|
|
34
|
+
|
|
35
|
+
- Added `dot` prop to `<IconButton>` for showing a small "dot" next to the icon.
|
|
36
|
+
- Added `unstable_decorations` prop to `<Tree.Item>` for showing multiple decorations (e.g. icons).
|
|
37
|
+
- **breaking**: Replaced `<DropdownMenu.Item>` children with new `label` prop (see [#423](https://github.com/iTwin/design-system/pull/423)).
|
|
38
|
+
- Added `icon` prop to `<DropdownMenu.Item>` and `<DropdownMenu.CheckboxItem>`.
|
|
39
|
+
- Updated the `shortcuts` prop of `<DropdownMenu.Item>` to recognize predefined "symbols" (e.g. modifier keys).
|
|
40
|
+
- Updated `<Anchor>` and `<Badge>` visuals to match the latest design.
|
|
41
|
+
- Fixed forced-colors mode styling for `DropdownMenu`.
|
|
42
|
+
|
|
43
|
+
## 5.0.0-alpha.8
|
|
44
|
+
|
|
45
|
+
- Added `description` prop to `<Tree.Item>` component for showing "sublabels".
|
|
46
|
+
- **breaking**: Updated `<Text>` component to require `variant` prop.
|
|
47
|
+
- (soft breaking) Removed `children` from `<Tree.Item>` prop types.
|
|
48
|
+
- Updated `DropdownMenu` padding.
|
|
49
|
+
|
|
50
|
+
## 5.0.0-alpha.7
|
|
51
|
+
|
|
52
|
+
- Added new `<Avatar>` component.
|
|
53
|
+
- Added new `<Badge>` component.
|
|
54
|
+
- Added `alt` prop to `<Icon>` component.
|
|
55
|
+
- Fixed all color tokens to use the correct `oklch` values.
|
|
56
|
+
- Fixed an issue where `<Tree.Item>` was not respecting its `style` prop.
|
|
57
|
+
|
|
58
|
+
## 5.0.0-alpha.6
|
|
59
|
+
|
|
60
|
+
- **breaking**: All CSS variables have been renamed to use the `--ids` prefix. See [#369](https://github.com/iTwin/kiwi/pull/369).
|
|
61
|
+
- **breaking**: Some CSS variables were renamed further. See [#368](https://github.com/iTwin/kiwi/pull/368).
|
|
62
|
+
- Notably, the "surface" backgrounds have been split into two different "page" and "elevation" scales.
|
|
63
|
+
- Background colors have been updated to match the latest design.
|
|
64
|
+
- All styles are now loaded into `@layer itwinui`. The one exception is the CSS reset which remains in `@layer reset`.
|
|
65
|
+
- `<Field>` now respects the order of `<Description>`s when creating associations.
|
|
66
|
+
|
|
67
|
+
## 5.0.0-alpha.5
|
|
68
|
+
|
|
69
|
+
- **breaking**: `Tree` API has changed to require flat structure, with explicit ARIA props (see [#300](https://github.com/iTwin/kiwi/pull/300)). `<Tree.Item>` no longer allows passing `children`.
|
|
70
|
+
- **breaking**: `Tree.Item`s `action` prop now requires a list of `<Tree.ItemAction>` components (see [#355](https://github.com/iTwin/kiwi/pull/355) and [#362](https://github.com/iTwin/kiwi/pull/362)).
|
|
71
|
+
- **breaking**: Replaced `<Chip>` children with new `label` prop (see [#349](https://github.com/iTwin/kiwi/pull/349)).
|
|
72
|
+
- Added `<Tree.ItemAction>` component with `visible` prop for more granular control over action visibility.
|
|
73
|
+
- Updated the layout of `<Field>` so that `<Description>` is placed in the best spot according on the label position and control type.
|
|
74
|
+
- `<Field>` now considers the presence of explicit control `id`s when creating associations.
|
|
75
|
+
|
|
76
|
+
## 5.0.0-alpha.4
|
|
77
|
+
|
|
78
|
+
- Added `onDismiss` prop and dismiss button to `<Chip>`.
|
|
79
|
+
- Fixed a rare issue where `TextBox` was still editable when `disabled`.
|
|
80
|
+
- Fixed "forced colors" mode styling for `<Button>` and `<IconButton>`.
|
|
81
|
+
- Explicitly set typography styles on `<Root>` to improve compatibility with iTwinUI theme bridge.
|
|
82
|
+
- Updated `DropdownMenu` visuals.
|
|
83
|
+
|
|
84
|
+
## 5.0.0-alpha.3
|
|
85
|
+
|
|
86
|
+
- Added `<DropdownMenu.CheckboxItem>` component for rendering menu items with a checkable state.
|
|
87
|
+
- Added `variant` prop to `<Select.HtmlSelect>` component for displaying different visual variants of the component.
|
|
88
|
+
- Updated event handling of `Tree` components to avoid firing `onClick` event of the `<Tree.Item>` component when the expander or one of the actions is clicked.
|
|
89
|
+
- Updated `Tree` components to implement a tree view pattern instead of the previously used nested list approach.
|
|
90
|
+
- Updated size and spacing of `<Tree.Item>`, `<DropdownMenu.Item>` and `<Select>` components.
|
|
91
|
+
- Fixed `<Label>` component alignment with `TextBox` components.
|
|
92
|
+
- Fixed action rendering of `<Tree.Item>` component.
|
|
93
|
+
- Fixed `<Checkbox>` component styling, which caused the mixed checkbox to be displayed as unchecked in the light theme.
|
|
94
|
+
|
|
95
|
+
## 5.0.0-alpha.2
|
|
96
|
+
|
|
97
|
+
- Added initial `Tree` component, exposed as `<Tree.Root>` and `<Tree.Item>` subcomponents.
|
|
98
|
+
- Added initial `<Spinner>` component for indicating quick, indeterminate progress.
|
|
99
|
+
- Added `<Description>` component to be used within a `<Field>`.
|
|
100
|
+
- Added initial `<Chip>` component.
|
|
101
|
+
- Added `symbol` prop to `<Kbd>` for displaying predefined symbols.
|
|
102
|
+
- Added `focusable` prop to `<Tabs.TabPanel>` component.
|
|
103
|
+
- Fixed a visual issue where light color-scheme was using dark shadows.
|
|
104
|
+
|
|
105
|
+
## 5.0.0-alpha.1
|
|
106
|
+
|
|
107
|
+
- Added `<Text>` component with a `variant` prop to support all text styles from Figma.
|
|
108
|
+
- Added `Select` component built on top of the HTML `<select>` element. Exposed as `<Select.Root>` and `<Select.HtmlSelect>`.
|
|
109
|
+
- Added `shortcuts` prop to `<DropdownMenu.Item>`.
|
|
110
|
+
- Added JSDoc comments to all components for inline IDE hints.
|
|
111
|
+
- Fixed `<Kbd>` component using the wrong font.
|
|
112
|
+
- Fixed some visual issues.
|
|
113
|
+
|
|
114
|
+
## 5.0.0-alpha.0
|
|
115
|
+
|
|
116
|
+
Initial release 🥳
|
package/dist/DEV/bricks/Icon.js
CHANGED
|
@@ -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 {
|
|
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:
|
|
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(
|
|
25
|
-
const separator =
|
|
35
|
+
function toIconHref(hrefBase, size) {
|
|
36
|
+
const separator = hrefBase.includes("#") ? "--" : "#";
|
|
26
37
|
const suffix = toIconId(size);
|
|
27
|
-
return `${
|
|
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,41 @@ 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";
|
|
119
223
|
export {
|
|
120
224
|
Checkmark,
|
|
121
225
|
DisclosureArrow,
|
|
122
226
|
Dismiss,
|
|
123
|
-
Icon
|
|
227
|
+
Icon,
|
|
228
|
+
StatusWarning
|
|
124
229
|
};
|
|
@@ -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
|
+
};
|
package/dist/DEV/bricks/Root.js
CHANGED
|
@@ -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 {
|
|
10
|
-
|
|
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 {
|
|
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 (!
|
|
78
|
-
const destination =
|
|
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 =
|
|
103
|
-
|
|
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(
|
|
127
|
+
if (!supportsAdoptedStylesheets && !rootNode.querySelector(`style[data-kiwi="${key}"]`)) {
|
|
110
128
|
const styleElement = ownerDocument.createElement("style");
|
|
111
|
-
styleElement.dataset.kiwi =
|
|
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
|
};
|
|
@@ -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__ */
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
}
|
|
@@ -43,6 +43,7 @@ const Tooltip = forwardRef(
|
|
|
43
43
|
AkTooltip.Tooltip,
|
|
44
44
|
{
|
|
45
45
|
"aria-hidden": "true",
|
|
46
|
+
portal: true,
|
|
46
47
|
...rest,
|
|
47
48
|
unmountOnHide,
|
|
48
49
|
className: cx("\u{1F95D}-tooltip", props.className),
|
|
@@ -53,7 +54,6 @@ const Tooltip = forwardRef(
|
|
|
53
54
|
...props.style
|
|
54
55
|
},
|
|
55
56
|
wrapperProps: popover.wrapperProps,
|
|
56
|
-
portal: popover.portal,
|
|
57
57
|
children: content
|
|
58
58
|
}
|
|
59
59
|
)
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { Toolbar } from "@ariakit/react/toolbar";
|
|
9
9
|
import * as ListItem from "./~utils.ListItem.js";
|
|
10
10
|
import { IconButton } from "./IconButton.js";
|
|
11
|
-
import { Icon } from "./Icon.js";
|
|
11
|
+
import { Icon, StatusWarning } from "./Icon.js";
|
|
12
12
|
import { forwardRef } from "./~utils.js";
|
|
13
13
|
import { useEventHandlers } from "./~hooks.js";
|
|
14
14
|
import { GhostAligner, useGhostAlignment } from "./~utils.GhostAligner.js";
|
|
@@ -19,11 +19,12 @@ const TreeItemRoot = forwardRef(
|
|
|
19
19
|
"aria-level": level,
|
|
20
20
|
selected,
|
|
21
21
|
expanded,
|
|
22
|
-
icon,
|
|
22
|
+
icon: iconProp,
|
|
23
23
|
unstable_decorations,
|
|
24
24
|
label,
|
|
25
25
|
description,
|
|
26
26
|
actions,
|
|
27
|
+
error,
|
|
27
28
|
onSelectedChange,
|
|
28
29
|
onExpandedChange,
|
|
29
30
|
onClick: onClickProp,
|
|
@@ -48,6 +49,7 @@ const TreeItemRoot = forwardRef(
|
|
|
48
49
|
const labelId = React.useId();
|
|
49
50
|
const descriptionId = React.useId();
|
|
50
51
|
const decorationId = React.useId();
|
|
52
|
+
const icon = error ? /* @__PURE__ */ jsx(StatusWarning, {}) : iconProp;
|
|
51
53
|
const describedBy = React.useMemo(() => {
|
|
52
54
|
const idRefs = [];
|
|
53
55
|
if (description) idRefs.push(descriptionId);
|
|
@@ -90,6 +92,7 @@ const TreeItemRoot = forwardRef(
|
|
|
90
92
|
{
|
|
91
93
|
"data-kiwi-expanded": expanded,
|
|
92
94
|
"data-kiwi-selected": selected,
|
|
95
|
+
"data-kiwi-error": error ? true : void 0,
|
|
93
96
|
className: "\u{1F95D}-tree-item-node",
|
|
94
97
|
style: { "--\u{1F95D}tree-item-level": level },
|
|
95
98
|
role: void 0,
|
|
@@ -146,7 +149,7 @@ const TreeItemActions = forwardRef((props, forwardedRef) => {
|
|
|
146
149
|
...props,
|
|
147
150
|
onClick: useEventHandlers(props.onClick, (e) => e.stopPropagation()),
|
|
148
151
|
onKeyDown: useEventHandlers(props.onKeyDown, (e) => e.stopPropagation()),
|
|
149
|
-
className: cx("\u{1F95D}-tree-item-actions", props.className),
|
|
152
|
+
className: cx("\u{1F95D}-tree-item-actions-container", props.className),
|
|
150
153
|
ref: forwardedRef,
|
|
151
154
|
children: props.children
|
|
152
155
|
}
|