@stratakit/structures 0.4.4 → 0.5.0

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 CHANGED
@@ -1,5 +1,51 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Breaking changes
6
+
7
+ - [#1036](https://github.com/iTwin/design-system/pull/1036): Changed `items` prop type of `ErrorRegion.Root` component from `ReactNode` to `ReactNode[]`.
8
+
9
+ `items` prop is used to determine error region visibility.
10
+
11
+ - [#1038](https://github.com/iTwin/design-system/pull/1038): Removed unintentionally exposed `TreeItem` [subpath export](https://nodejs.org/api/packages.html#subpath-exports). Tree item components are available under the `Tree` subpath or the main entry point of the package.
12
+
13
+ ```diff
14
+ - import * as TreeItem from "@stratakit/structures/TreeItem";
15
+ + import * as Tree from "@stratakit/structures/Tree";
16
+
17
+ - <TreeItem.Root />
18
+ + <Tree.Item />
19
+
20
+ - <TreeItem.Action />
21
+ + <Tree.ItemAction />
22
+ ```
23
+
24
+ - [#1037](https://github.com/iTwin/design-system/pull/1037): Require `aria-label` or `aria-labelledby` prop in `ErrorRegion.Root` component.
25
+
26
+ ### Non-breaking changes
27
+
28
+ - [#1003](https://github.com/iTwin/design-system/pull/1003): Enabled React Compiler for production build. In React 18 apps, `react-compiler-runtime` dependency will be used.
29
+ - Updated dependencies:
30
+ - @stratakit/bricks@0.5.0
31
+ - @stratakit/foundations@0.4.0
32
+
33
+ ## 0.4.5
34
+
35
+ - `unstable_NavigationRail` changes:
36
+ - [#962](https://github.com/iTwin/design-system/pull/962): Added `expanded` and `setExpanded` props for controlling the expanded/collapsed state.
37
+ - [#962](https://github.com/iTwin/design-system/pull/962): Added `defaultExpanded` prop for specifying the _initial_ expanded/collapsed state.
38
+ - `unstable_ErrorRegion` changes:
39
+ - [#963](https://github.com/iTwin/design-system/pull/963): Avoid attempting to set the default accessible name of the [`<section>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/section) when `label={undefined}`.
40
+ - [#979](https://github.com/iTwin/design-system/pull/979): Updated the visibility logic to be based on the `items` array. Previously recommended `label={undefined}` pattern is now deprecated.
41
+ - [#978](https://github.com/iTwin/design-system/pull/978): Log a console warning if `aria-label` or `aria-labelledby` is not provided to `ErrorRegion.Root`.
42
+ - [#979](https://github.com/iTwin/design-system/pull/979): Log a console warning if `items` prop is not an array. Previously supported `ReactNode` type is now deprecated.
43
+ - [#953](https://github.com/iTwin/design-system/pull/953): Changed the default value of `Tabs.Provider`'s `selectOnMove` prop to `false`.
44
+ - [#969](https://github.com/iTwin/design-system/pull/969): Fixed an issue where `unstable_Banner` would not track changes to the `tone` prop.
45
+ - Updated dependencies:
46
+ - @stratakit/bricks@0.4.5
47
+ - @stratakit/foundations@0.3.5
48
+
3
49
  ## 0.4.4
4
50
 
5
51
  - [#954](https://github.com/iTwin/design-system/pull/954): Added "popup indicator" styling to `Toolbar.Item`.
@@ -228,7 +228,7 @@ declare const AccordionItemMarker: import("react").ForwardRefExoticComponent<Pic
228
228
  * ```
229
229
  */
230
230
  declare const AccordionItemContent: import("react").ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & import("react").RefAttributes<HTMLDivElement | HTMLElement>>;
231
- interface AccordionItemHeadingProps extends BaseProps {
231
+ interface AccordionItemHeadingProps extends Omit<BaseProps, "render"> {
232
232
  render: NonNullable<BaseProps["render"]>;
233
233
  }
234
234
  /**
@@ -1,133 +1,76 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import {
3
- Disclosure,
4
- DisclosureContent,
5
- DisclosureProvider
6
- } from "@ariakit/react/disclosure";
2
+ import { Disclosure, DisclosureContent, DisclosureProvider } from "@ariakit/react/disclosure";
7
3
  import { Role } from "@ariakit/react/role";
8
4
  import { Text } from "@stratakit/bricks";
9
- import {
10
- GhostAligner,
11
- IconButtonPresentation
12
- } from "@stratakit/bricks/secret-internals";
13
- import {
14
- forwardRef,
15
- useControlledState
16
- } from "@stratakit/foundations/secret-internals";
5
+ import { GhostAligner, IconButtonPresentation } from "@stratakit/bricks/secret-internals";
6
+ import { forwardRef, useControlledState } from "@stratakit/foundations/secret-internals";
17
7
  import cx from "classnames";
18
8
  import { ChevronDown } from "./~utils.icons.js";
19
- const AccordionItemRoot = forwardRef(
20
- (props, forwardedRef) => {
21
- const {
22
- defaultOpen,
23
- open: openProp,
24
- setOpen: setOpenProp,
25
- ...rest
26
- } = props;
27
- const [open, setOpen] = useControlledState(
28
- defaultOpen ?? false,
29
- openProp,
30
- setOpenProp
31
- );
32
- return /* @__PURE__ */ jsx(
33
- DisclosureProvider,
34
- {
35
- defaultOpen,
36
- open,
37
- setOpen,
38
- children: /* @__PURE__ */ jsx(
39
- Role,
40
- {
41
- ...rest,
42
- className: cx("\u{1F95D}AccordionItem", props.className),
43
- "data-_sk-open": open,
44
- ref: forwardedRef
45
- }
46
- )
47
- }
48
- );
49
- }
50
- );
51
- const AccordionItemHeader = forwardRef(
52
- (props, forwardedRef) => /* @__PURE__ */ jsx(GhostAligner, { align: "block", children: /* @__PURE__ */ jsx(
53
- Role,
54
- {
55
- ...props,
56
- className: cx("\u{1F95D}AccordionItemHeader", props.className),
9
+ const AccordionItemRoot = forwardRef((props, forwardedRef) => {
10
+ const {
11
+ defaultOpen,
12
+ open: openProp,
13
+ setOpen: setOpenProp,
14
+ ...rest
15
+ } = props;
16
+ const [open, setOpen] = useControlledState(defaultOpen ?? false, openProp, setOpenProp);
17
+ return /* @__PURE__ */ jsx(DisclosureProvider, {
18
+ defaultOpen,
19
+ open,
20
+ setOpen,
21
+ children: /* @__PURE__ */ jsx(Role, {
22
+ ...rest,
23
+ className: cx("\u{1F95D}AccordionItem", props.className),
24
+ "data-_sk-open": open,
57
25
  ref: forwardedRef
58
- }
59
- ) })
60
- );
61
- const AccordionItemButton = forwardRef(
62
- (props, forwardedRef) => /* @__PURE__ */ jsx(
63
- Disclosure,
64
- {
65
- ...props,
66
- className: cx("\u{1F95D}AccordionItemButton", props.className),
67
- ref: forwardedRef
68
- }
69
- )
70
- );
71
- const AccordionItemLabel = forwardRef(
72
- (props, forwardedRef) => /* @__PURE__ */ jsx(
73
- Text,
74
- {
75
- ...props,
76
- variant: "body-sm",
77
- className: cx("\u{1F95D}AccordionItemLabel", props.className),
78
- ref: forwardedRef
79
- }
80
- )
81
- );
82
- const AccordionItemDecoration = forwardRef(
83
- (props, forwardedRef) => /* @__PURE__ */ jsx(
84
- Role,
85
- {
86
- ...props,
87
- className: cx("\u{1F95D}AccordionItemDecoration", props.className),
88
- ref: forwardedRef
89
- }
90
- )
91
- );
92
- const AccordionItemMarker = forwardRef(
93
- (props, forwardedRef) => /* @__PURE__ */ jsx(
94
- IconButtonPresentation,
95
- {
96
- ...props,
97
- variant: "ghost",
98
- className: cx("\u{1F95D}AccordionItemMarker", props.className),
99
- ref: forwardedRef,
100
- children: props.children ?? /* @__PURE__ */ jsx(
101
- ChevronDown,
102
- {
103
- "aria-hidden": "true",
104
- className: "\u{1F95D}AccordionItemMarkerChevron"
105
- }
106
- )
107
- }
108
- )
109
- );
110
- const AccordionItemContent = forwardRef(
111
- (props, forwardedRef) => /* @__PURE__ */ jsx(
112
- DisclosureContent,
113
- {
114
- ...props,
115
- className: cx("\u{1F95D}AccordionItemContent", props.className),
116
- ref: forwardedRef
117
- }
118
- )
119
- );
120
- const AccordionItemHeading = forwardRef(
121
- (props, forwardedRef) => /* @__PURE__ */ jsx(
122
- Text,
123
- {
124
- ...props,
125
- variant: "body-sm",
126
- className: cx("\u{1F95D}AccordionItemHeading", props.className),
127
- ref: forwardedRef
128
- }
129
- )
130
- );
26
+ })
27
+ });
28
+ });
29
+ const AccordionItemHeader = forwardRef((props, forwardedRef) => /* @__PURE__ */ jsx(GhostAligner, {
30
+ align: "block",
31
+ children: /* @__PURE__ */ jsx(Role, {
32
+ ...props,
33
+ className: cx("\u{1F95D}AccordionItemHeader", props.className),
34
+ ref: forwardedRef
35
+ })
36
+ }));
37
+ const AccordionItemButton = forwardRef((props, forwardedRef) => /* @__PURE__ */ jsx(Disclosure, {
38
+ ...props,
39
+ className: cx("\u{1F95D}AccordionItemButton", props.className),
40
+ ref: forwardedRef
41
+ }));
42
+ const AccordionItemLabel = forwardRef((props, forwardedRef) => /* @__PURE__ */ jsx(Text, {
43
+ ...props,
44
+ variant: "body-sm",
45
+ className: cx("\u{1F95D}AccordionItemLabel", props.className),
46
+ ref: forwardedRef
47
+ }));
48
+ const AccordionItemDecoration = forwardRef((props, forwardedRef) => /* @__PURE__ */ jsx(Role, {
49
+ ...props,
50
+ className: cx("\u{1F95D}AccordionItemDecoration", props.className),
51
+ ref: forwardedRef
52
+ }));
53
+ const AccordionItemMarker = forwardRef((props, forwardedRef) => /* @__PURE__ */ jsx(IconButtonPresentation, {
54
+ ...props,
55
+ variant: "ghost",
56
+ className: cx("\u{1F95D}AccordionItemMarker", props.className),
57
+ ref: forwardedRef,
58
+ children: props.children ?? /* @__PURE__ */ jsx(ChevronDown, {
59
+ "aria-hidden": "true",
60
+ className: "\u{1F95D}AccordionItemMarkerChevron"
61
+ })
62
+ }));
63
+ const AccordionItemContent = forwardRef((props, forwardedRef) => /* @__PURE__ */ jsx(DisclosureContent, {
64
+ ...props,
65
+ className: cx("\u{1F95D}AccordionItemContent", props.className),
66
+ ref: forwardedRef
67
+ }));
68
+ const AccordionItemHeading = forwardRef((props, forwardedRef) => /* @__PURE__ */ jsx(Text, {
69
+ ...props,
70
+ variant: "body-sm",
71
+ className: cx("\u{1F95D}AccordionItemHeading", props.className),
72
+ ref: forwardedRef
73
+ }));
131
74
  export {
132
75
  AccordionItemButton as Button,
133
76
  AccordionItemContent as Content,
package/dist/Banner.js CHANGED
@@ -1,138 +1,165 @@
1
+ import { c as _c } from "react-compiler-runtime";
1
2
  import { jsx, jsxs } from "react/jsx-runtime";
2
3
  import * as React from "react";
3
4
  import { Role } from "@ariakit/react/role";
4
5
  import { IconButton, Text } from "@stratakit/bricks";
5
6
  import { GhostAligner } from "@stratakit/bricks/secret-internals";
6
7
  import { Icon } from "@stratakit/foundations";
7
- import {
8
- forwardRef,
9
- useSafeContext
10
- } from "@stratakit/foundations/secret-internals";
8
+ import { forwardRef, useSafeContext } from "@stratakit/foundations/secret-internals";
11
9
  import cx from "classnames";
12
10
  import { createStore, useStore } from "zustand";
13
11
  import { combine } from "zustand/middleware";
14
12
  import { Dismiss, StatusIcon } from "./~utils.icons.js";
15
13
  function createBannerStore(initialState) {
16
- return createStore(
17
- combine(initialState, (set, _, store) => ({
18
- setLabelId: (labelId) => {
19
- set({ labelId: labelId || store.getInitialState().labelId });
20
- }
21
- }))
22
- );
14
+ return createStore(combine(initialState, (set, _, store) => ({
15
+ setLabelId: (labelId) => {
16
+ set({
17
+ labelId: labelId || store.getInitialState().labelId
18
+ });
19
+ }
20
+ })));
23
21
  }
24
22
  const BannerContext = React.createContext(void 0);
25
23
  function BannerProvider(props) {
26
- const [store] = React.useState(
27
- () => createBannerStore({
28
- tone: props.tone
29
- })
30
- );
31
- return /* @__PURE__ */ jsx(BannerContext.Provider, { value: store, children: props.children });
24
+ const $ = _c(9);
25
+ const {
26
+ tone
27
+ } = props;
28
+ let t0;
29
+ if ($[0] !== tone) {
30
+ t0 = () => createBannerStore({
31
+ tone
32
+ });
33
+ $[0] = tone;
34
+ $[1] = t0;
35
+ } else {
36
+ t0 = $[1];
37
+ }
38
+ const [store] = React.useState(t0);
39
+ let t1;
40
+ let t2;
41
+ if ($[2] !== store || $[3] !== tone) {
42
+ t1 = function synchronizeWithProps() {
43
+ store.setState({
44
+ tone
45
+ });
46
+ };
47
+ t2 = [store, tone];
48
+ $[2] = store;
49
+ $[3] = tone;
50
+ $[4] = t1;
51
+ $[5] = t2;
52
+ } else {
53
+ t1 = $[4];
54
+ t2 = $[5];
55
+ }
56
+ React.useEffect(t1, t2);
57
+ let t3;
58
+ if ($[6] !== props.children || $[7] !== store) {
59
+ t3 = jsx(BannerContext.Provider, {
60
+ value: store,
61
+ children: props.children
62
+ });
63
+ $[6] = props.children;
64
+ $[7] = store;
65
+ $[8] = t3;
66
+ } else {
67
+ t3 = $[8];
68
+ }
69
+ return t3;
32
70
  }
33
71
  function useBannerState(selectorFn) {
34
72
  const store = useSafeContext(BannerContext);
35
73
  return useStore(store, selectorFn);
36
74
  }
37
75
  const BannerRoot = forwardRef((props, forwardedRef) => {
38
- const { tone = "neutral", variant = "outline", ...rest } = props;
39
- return /* @__PURE__ */ jsx(BannerProvider, { tone, children: /* @__PURE__ */ jsx(
40
- Role,
41
- {
76
+ const {
77
+ tone = "neutral",
78
+ variant = "outline",
79
+ ...rest
80
+ } = props;
81
+ return /* @__PURE__ */ jsx(BannerProvider, {
82
+ tone,
83
+ children: /* @__PURE__ */ jsx(Role, {
42
84
  ...rest,
43
85
  "data-_sk-tone": tone,
44
86
  "data-_sk-variant": variant,
45
87
  className: cx("\u{1F95D}Banner", props.className),
46
88
  ref: forwardedRef
47
- }
48
- ) });
89
+ })
90
+ });
49
91
  });
50
92
  const BannerIcon = forwardRef((props, forwardedRef) => {
51
93
  const tone = useBannerState((state) => state.tone);
52
94
  const hasDefaultIcon = props.href === void 0 && tone !== "neutral";
53
95
  const {
54
- render = hasDefaultIcon ? /* @__PURE__ */ jsx(StatusIcon, { tone }) : void 0,
96
+ render = hasDefaultIcon ? /* @__PURE__ */ jsx(StatusIcon, {
97
+ tone
98
+ }) : void 0,
55
99
  ...rest
56
100
  } = props;
57
- return /* @__PURE__ */ jsx(
58
- Icon,
59
- {
101
+ return /* @__PURE__ */ jsx(Icon, {
102
+ ...rest,
103
+ render,
104
+ className: cx("\u{1F95D}BannerIcon", props.className),
105
+ ref: forwardedRef
106
+ });
107
+ });
108
+ const BannerLabel = forwardRef((props, forwardedRef) => {
109
+ const defaultLabelId = React.useId();
110
+ const labelId = useBannerState((state) => state.labelId);
111
+ const setLabelId = useBannerState((state_0) => state_0.setLabelId);
112
+ const id = props.id ?? defaultLabelId;
113
+ React.useEffect(() => {
114
+ setLabelId(id);
115
+ return () => setLabelId(void 0);
116
+ }, [setLabelId, id]);
117
+ return /* @__PURE__ */ jsx(Text, {
118
+ id: labelId,
119
+ render: /* @__PURE__ */ jsx("span", {}),
120
+ ...props,
121
+ className: cx("\u{1F95D}BannerLabel", props.className),
122
+ variant: "body-sm",
123
+ ref: forwardedRef
124
+ });
125
+ });
126
+ const BannerMessage = forwardRef((props, forwardedRef) => {
127
+ return /* @__PURE__ */ jsx(Text, {
128
+ ...props,
129
+ variant: "body-sm",
130
+ className: cx("\u{1F95D}BannerMessage", props.className),
131
+ ref: forwardedRef
132
+ });
133
+ });
134
+ const BannerActions = forwardRef((props, forwardedRef) => {
135
+ return /* @__PURE__ */ jsx(Role.div, {
136
+ ...props,
137
+ className: cx("\u{1F95D}BannerActions", props.className),
138
+ ref: forwardedRef
139
+ });
140
+ });
141
+ const BannerDismissButton = forwardRef((props, forwardedRef) => {
142
+ const {
143
+ label = "Dismiss",
144
+ ...rest
145
+ } = props;
146
+ const labelId = useBannerState((state) => state.labelId);
147
+ const defaultId = React.useId();
148
+ const id = props.id ?? defaultId;
149
+ return /* @__PURE__ */ jsx(GhostAligner, {
150
+ align: "block",
151
+ children: /* @__PURE__ */ jsx(IconButton, {
60
152
  ...rest,
61
- render,
62
- className: cx("\u{1F95D}BannerIcon", props.className),
153
+ id,
154
+ className: cx("\u{1F95D}BannerDismissButton", props.className),
155
+ variant: "ghost",
156
+ label,
157
+ "aria-labelledby": `${id} ${labelId || ""}`,
158
+ icon: /* @__PURE__ */ jsx(Dismiss, {}),
63
159
  ref: forwardedRef
64
- }
65
- );
160
+ })
161
+ });
66
162
  });
67
- const BannerLabel = forwardRef(
68
- (props, forwardedRef) => {
69
- const defaultLabelId = React.useId();
70
- const labelId = useBannerState((state) => state.labelId);
71
- const setLabelId = useBannerState((state) => state.setLabelId);
72
- const id = props.id ?? defaultLabelId;
73
- React.useEffect(() => {
74
- setLabelId(id);
75
- return () => setLabelId(void 0);
76
- }, [setLabelId, id]);
77
- return /* @__PURE__ */ jsx(
78
- Text,
79
- {
80
- id: labelId,
81
- render: /* @__PURE__ */ jsx("span", {}),
82
- ...props,
83
- className: cx("\u{1F95D}BannerLabel", props.className),
84
- variant: "body-sm",
85
- ref: forwardedRef
86
- }
87
- );
88
- }
89
- );
90
- const BannerMessage = forwardRef(
91
- (props, forwardedRef) => {
92
- return /* @__PURE__ */ jsx(
93
- Text,
94
- {
95
- ...props,
96
- variant: "body-sm",
97
- className: cx("\u{1F95D}BannerMessage", props.className),
98
- ref: forwardedRef
99
- }
100
- );
101
- }
102
- );
103
- const BannerActions = forwardRef(
104
- (props, forwardedRef) => {
105
- return /* @__PURE__ */ jsx(
106
- Role.div,
107
- {
108
- ...props,
109
- className: cx("\u{1F95D}BannerActions", props.className),
110
- ref: forwardedRef
111
- }
112
- );
113
- }
114
- );
115
- const BannerDismissButton = forwardRef(
116
- (props, forwardedRef) => {
117
- const { label = "Dismiss", ...rest } = props;
118
- const labelId = useBannerState((state) => state.labelId);
119
- const defaultId = React.useId();
120
- const id = props.id ?? defaultId;
121
- return /* @__PURE__ */ jsx(GhostAligner, { align: "block", children: /* @__PURE__ */ jsx(
122
- IconButton,
123
- {
124
- ...rest,
125
- id,
126
- className: cx("\u{1F95D}BannerDismissButton", props.className),
127
- variant: "ghost",
128
- label,
129
- "aria-labelledby": `${id} ${labelId || ""}`,
130
- icon: /* @__PURE__ */ jsx(Dismiss, {}),
131
- ref: forwardedRef
132
- }
133
- ) });
134
- }
135
- );
136
163
  const Banner = forwardRef((props, forwardedRef) => {
137
164
  const {
138
165
  message,
@@ -143,23 +170,25 @@ const Banner = forwardRef((props, forwardedRef) => {
143
170
  tone = "neutral",
144
171
  ...rest
145
172
  } = props;
146
- const shouldRenderIcon = React.useMemo(
147
- () => icon !== void 0 || tone !== "neutral",
148
- [icon, tone]
149
- );
150
- return /* @__PURE__ */ jsxs(BannerRoot, { tone, ...rest, ref: forwardedRef, children: [
151
- shouldRenderIcon ? /* @__PURE__ */ jsx(
152
- BannerIcon,
153
- {
154
- href: typeof icon === "string" ? icon : void 0,
155
- render: React.isValidElement(icon) ? icon : void 0
156
- }
157
- ) : null,
158
- /* @__PURE__ */ jsx(BannerLabel, { render: React.isValidElement(label) ? label : void 0, children: label }),
159
- /* @__PURE__ */ jsx(BannerMessage, { children: message }),
160
- actions != null ? /* @__PURE__ */ jsx(BannerActions, { children: actions }) : null,
161
- onDismiss ? /* @__PURE__ */ jsx(BannerDismissButton, { onClick: onDismiss }) : null
162
- ] });
173
+ const shouldRenderIcon = React.useMemo(() => icon !== void 0 || tone !== "neutral", [icon, tone]);
174
+ return /* @__PURE__ */ jsxs(BannerRoot, {
175
+ tone,
176
+ ...rest,
177
+ ref: forwardedRef,
178
+ children: [shouldRenderIcon ? /* @__PURE__ */ jsx(BannerIcon, {
179
+ href: typeof icon === "string" ? icon : void 0,
180
+ render: React.isValidElement(icon) ? icon : void 0
181
+ }) : null, /* @__PURE__ */ jsx(BannerLabel, {
182
+ render: React.isValidElement(label) ? label : void 0,
183
+ children: label
184
+ }), /* @__PURE__ */ jsx(BannerMessage, {
185
+ children: message
186
+ }), actions != null ? /* @__PURE__ */ jsx(BannerActions, {
187
+ children: actions
188
+ }) : null, onDismiss ? /* @__PURE__ */ jsx(BannerDismissButton, {
189
+ onClick: onDismiss
190
+ }) : null]
191
+ });
163
192
  });
164
193
  var Banner_default = Banner;
165
194
  export {