@acronis-platform/ui-react 0.58.0 → 0.61.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/README.md +5 -5
- package/dist/components/ui/app-shell/app-shell.js.map +1 -1
- package/dist/components/ui/area-chart/area-chart.js +210 -119
- package/dist/components/ui/area-chart/area-chart.js.map +1 -1
- package/dist/components/ui/avatar/avatar.js +26 -23
- package/dist/components/ui/avatar/avatar.js.map +1 -1
- package/dist/components/ui/bar-chart/bar-chart.js +595 -149
- package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
- package/dist/components/ui/calendar/calendar.js +17 -15
- package/dist/components/ui/calendar/calendar.js.map +1 -1
- package/dist/components/ui/carousel-dialog/carousel-dialog.js +87 -0
- package/dist/components/ui/carousel-dialog/carousel-dialog.js.map +1 -0
- package/dist/components/ui/category-bar/category-bar.js +147 -0
- package/dist/components/ui/category-bar/category-bar.js.map +1 -0
- package/dist/components/ui/chart/chart-format.js +170 -0
- package/dist/components/ui/chart/chart-format.js.map +1 -0
- package/dist/components/ui/chart/chart.js +204 -150
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/composed-chart/composed-chart.js +423 -98
- package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
- package/dist/components/ui/confidence-cone/confidence-cone.js +306 -172
- package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
- package/dist/components/ui/dialog/dialog.js +29 -29
- package/dist/components/ui/dialog/dialog.js.map +1 -1
- package/dist/components/ui/dialog-footer-carousel/dialog-footer-carousel.js +57 -0
- package/dist/components/ui/dialog-footer-carousel/dialog-footer-carousel.js.map +1 -0
- package/dist/components/ui/dialog-footer-default/dialog-footer-default.js +1 -1
- package/dist/components/ui/dialog-footer-default/dialog-footer-default.js.map +1 -1
- package/dist/components/ui/dialog-welcome/dialog-welcome.js +272 -0
- package/dist/components/ui/dialog-welcome/dialog-welcome.js.map +1 -0
- package/dist/components/ui/funnel-chart/funnel-chart.js +245 -51
- package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
- package/dist/components/ui/histogram/histogram.js +96 -64
- package/dist/components/ui/histogram/histogram.js.map +1 -1
- package/dist/components/ui/input/input.js.map +1 -1
- package/dist/components/ui/line-chart/line-chart.js +230 -159
- package/dist/components/ui/line-chart/line-chart.js.map +1 -1
- package/dist/components/ui/metric/metric.js +88 -70
- package/dist/components/ui/metric/metric.js.map +1 -1
- package/dist/components/ui/pie-chart/pie-chart.js +234 -80
- package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
- package/dist/components/ui/radar-chart/radar-chart.js +210 -57
- package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +358 -50
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
- package/dist/components/ui/sankey-chart/sankey-chart.js +199 -0
- package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -0
- package/dist/components/ui/scatter-chart/scatter-chart.js +86 -50
- package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
- package/dist/components/ui/timeline/timeline.js +206 -142
- package/dist/components/ui/timeline/timeline.js.map +1 -1
- package/dist/components/ui/toolbar/toolbar.js +82 -92
- package/dist/components/ui/toolbar/toolbar.js.map +1 -1
- package/dist/components/ui/treemap/treemap.js +183 -59
- package/dist/components/ui/treemap/treemap.js.map +1 -1
- package/dist/index.js +481 -439
- package/dist/index.js.map +1 -1
- package/dist/lib/breakpoints.js +9 -6
- package/dist/lib/breakpoints.js.map +1 -1
- package/dist/node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js +25 -0
- package/dist/node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js.map +1 -0
- package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js +36 -0
- package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js.map +1 -0
- package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js +1205 -0
- package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js.map +1 -0
- package/dist/react.js +481 -439
- package/dist/react.js.map +1 -1
- package/dist/src/components/ui/area-chart/area-chart.d.ts +52 -17
- package/dist/src/components/ui/area-chart/index.d.ts +1 -1
- package/dist/src/components/ui/avatar/avatar.d.ts +1 -1
- package/dist/src/components/ui/bar-chart/bar-chart.d.ts +152 -29
- package/dist/src/components/ui/bar-chart/index.d.ts +1 -1
- package/dist/src/components/ui/button/button.d.ts +1 -1
- package/dist/src/components/ui/button-menu/button-menu.d.ts +1 -1
- package/dist/src/components/ui/carousel-dialog/carousel-dialog.d.ts +28 -0
- package/dist/src/components/ui/carousel-dialog/index.d.ts +1 -0
- package/dist/src/components/ui/category-bar/category-bar.d.ts +51 -0
- package/dist/src/components/ui/category-bar/index.d.ts +1 -0
- package/dist/src/components/ui/chart/__tests__/chart-format.test.d.ts +1 -0
- package/dist/src/components/ui/chart/__tests__/chart-layout.d.ts +63 -0
- package/dist/src/components/ui/chart/__tests__/chart-layout.test.d.ts +1 -0
- package/dist/src/components/ui/chart/chart-format.d.ts +526 -0
- package/dist/src/components/ui/chart/chart.d.ts +11 -3
- package/dist/src/components/ui/chart/index.d.ts +3 -1
- package/dist/src/components/ui/composed-chart/composed-chart.d.ts +154 -20
- package/dist/src/components/ui/composed-chart/index.d.ts +1 -1
- package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +138 -37
- package/dist/src/components/ui/confidence-cone/index.d.ts +1 -1
- package/dist/src/components/ui/dialog-footer-carousel/dialog-footer-carousel.d.ts +9 -0
- package/dist/src/components/ui/dialog-footer-carousel/index.d.ts +1 -0
- package/dist/src/components/ui/dialog-welcome/dialog-welcome.d.ts +54 -0
- package/dist/src/components/ui/dialog-welcome/dialog-welcome.docs.d.ts +55 -0
- package/dist/src/components/ui/dialog-welcome/index.d.ts +1 -0
- package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +201 -3
- package/dist/src/components/ui/funnel-chart/index.d.ts +1 -1
- package/dist/src/components/ui/histogram/histogram.d.ts +2 -17
- package/dist/src/components/ui/line-chart/index.d.ts +1 -1
- package/dist/src/components/ui/line-chart/line-chart.d.ts +50 -17
- package/dist/src/components/ui/pie-chart/index.d.ts +1 -1
- package/dist/src/components/ui/pie-chart/pie-chart.d.ts +145 -4
- package/dist/src/components/ui/radar-chart/index.d.ts +1 -1
- package/dist/src/components/ui/radar-chart/radar-chart.d.ts +219 -6
- package/dist/src/components/ui/radial-bar-chart/index.d.ts +1 -1
- package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +215 -9
- package/dist/src/components/ui/sankey-chart/index.d.ts +2 -0
- package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +69 -0
- package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +2 -17
- package/dist/src/components/ui/timeline/index.d.ts +1 -1
- package/dist/src/components/ui/timeline/timeline.d.ts +79 -20
- package/dist/src/components/ui/treemap/index.d.ts +1 -1
- package/dist/src/components/ui/treemap/treemap.d.ts +68 -8
- package/dist/src/index.d.ts +5 -1
- package/dist/ui-react.css +1 -1
- package/package.json +5 -4
- package/dist/components/ui/search-global/search-global.js +0 -60
- package/dist/components/ui/search-global/search-global.js.map +0 -1
- package/dist/src/components/ui/search-global/index.d.ts +0 -1
- package/dist/src/components/ui/search-global/search-global.d.ts +0 -7
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import * as
|
|
3
|
-
import { Toolbar as
|
|
1
|
+
import { jsx as l, jsxs as C } from "react/jsx-runtime";
|
|
2
|
+
import * as i from "react";
|
|
3
|
+
import { Toolbar as R } from "@base-ui/react/toolbar";
|
|
4
4
|
import { cn as T } from "../../../lib/utils.js";
|
|
5
|
-
import { Button as
|
|
6
|
-
import { DropdownMenu as
|
|
5
|
+
import { Button as E } from "../button/button.js";
|
|
6
|
+
import { DropdownMenu as _, DropdownMenuTrigger as F, DropdownMenuContent as I, DropdownMenuItem as P } from "../dropdown-menu/dropdown-menu.js";
|
|
7
7
|
import { ButtonMenu as A } from "../button-menu/button-menu.js";
|
|
8
|
-
const j =
|
|
9
|
-
({ className: r,
|
|
8
|
+
const k = i.createContext(!1), j = i.forwardRef(
|
|
9
|
+
({ className: r, disabled: t, ...n }, c) => /* @__PURE__ */ l(k.Provider, { value: !!t, children: /* @__PURE__ */ l(
|
|
10
10
|
"fieldset",
|
|
11
11
|
{
|
|
12
|
-
ref:
|
|
12
|
+
ref: c,
|
|
13
13
|
className: T(
|
|
14
14
|
"m-0 flex min-w-0 items-center gap-4 border-0 p-0",
|
|
15
15
|
r
|
|
16
16
|
),
|
|
17
|
-
|
|
17
|
+
disabled: t,
|
|
18
|
+
...n
|
|
18
19
|
}
|
|
19
|
-
)
|
|
20
|
+
) })
|
|
20
21
|
);
|
|
21
22
|
j.displayName = "Toolbar";
|
|
22
|
-
const
|
|
23
|
-
({ className: r, ...t }, n) => /* @__PURE__ */
|
|
23
|
+
const X = i.forwardRef(
|
|
24
|
+
({ className: r, ...t }, n) => /* @__PURE__ */ l(
|
|
24
25
|
"div",
|
|
25
26
|
{
|
|
26
27
|
ref: n,
|
|
@@ -32,21 +33,21 @@ const P = l.forwardRef(
|
|
|
32
33
|
}
|
|
33
34
|
)
|
|
34
35
|
);
|
|
35
|
-
|
|
36
|
+
X.displayName = "ToolbarActions";
|
|
36
37
|
const M = 16;
|
|
37
|
-
function
|
|
38
|
+
function G(r, t, n, c) {
|
|
38
39
|
const d = r.length;
|
|
39
40
|
if (d === 0) return 0;
|
|
40
|
-
if (r.reduce((
|
|
41
|
+
if (r.reduce((u, p) => u + p, 0) + n * (d - 1) <= c) return d;
|
|
41
42
|
let o = t, s = 0;
|
|
42
|
-
for (let
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
45
|
-
o =
|
|
43
|
+
for (let u = 0; u < d; u++) {
|
|
44
|
+
const p = o + r[u] + n;
|
|
45
|
+
if (p > c) break;
|
|
46
|
+
o = p, s++;
|
|
46
47
|
}
|
|
47
48
|
return s;
|
|
48
49
|
}
|
|
49
|
-
function
|
|
50
|
+
function V(r) {
|
|
50
51
|
const t = Array.from(r.childNodes).filter(
|
|
51
52
|
(o) => {
|
|
52
53
|
var s;
|
|
@@ -54,74 +55,63 @@ function G(r) {
|
|
|
54
55
|
}
|
|
55
56
|
);
|
|
56
57
|
if (t.length === 0) return r.getBoundingClientRect().width;
|
|
57
|
-
const n = getComputedStyle(r),
|
|
58
|
+
const n = getComputedStyle(r), c = parseFloat(n.columnGap) || 0, d = (parseFloat(n.paddingLeft) || 0) + (parseFloat(n.paddingRight) || 0) + (parseFloat(n.borderLeftWidth) || 0) + (parseFloat(n.borderRightWidth) || 0);
|
|
58
59
|
return t.map((o) => {
|
|
59
60
|
if (o.nodeType === Node.TEXT_NODE) {
|
|
60
61
|
const s = document.createRange();
|
|
61
62
|
return s.selectNodeContents(o), s.getBoundingClientRect().width;
|
|
62
63
|
}
|
|
63
64
|
return o.getBoundingClientRect().width;
|
|
64
|
-
}).reduce((o, s) => o + s, 0) +
|
|
65
|
+
}).reduce((o, s) => o + s, 0) + c * (t.length - 1) + d;
|
|
65
66
|
}
|
|
66
|
-
function
|
|
67
|
+
function z(...r) {
|
|
67
68
|
return (t) => {
|
|
68
69
|
for (const n of r)
|
|
69
70
|
n && (typeof n == "function" ? n(t) : n.current = t);
|
|
70
71
|
};
|
|
71
72
|
}
|
|
72
|
-
const
|
|
73
|
-
({ className: r, actions: t, moreActionsLabel: n = "More actions", ...
|
|
74
|
-
const
|
|
73
|
+
const $ = i.forwardRef(
|
|
74
|
+
({ className: r, actions: t, moreActionsLabel: n = "More actions", ...c }, d) => {
|
|
75
|
+
const f = i.useRef(null), o = i.useRef(
|
|
75
76
|
/* @__PURE__ */ new Map()
|
|
76
|
-
), s =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
attributeFilter: ["disabled"]
|
|
87
|
-
}), () => f.disconnect();
|
|
88
|
-
}, []), l.useEffect(() => {
|
|
89
|
-
g && C(!1);
|
|
90
|
-
}, [g]);
|
|
91
|
-
const y = l.useCallback(() => {
|
|
92
|
-
var E;
|
|
93
|
-
const e = u.current, i = e == null ? void 0 : e.parentElement;
|
|
94
|
-
if (!e || !i) return;
|
|
95
|
-
const f = Array.from(i.children).filter((b) => b !== e).reduce((b, w) => b + G(w), 0), p = Math.max(i.children.length - 1, 0), O = i.clientWidth - f - M * p, S = t.map(
|
|
96
|
-
(b) => {
|
|
77
|
+
), s = i.useRef(null), [u, p] = i.useState(t.length), [B, v] = i.useState(!1), m = i.useContext(k), D = B && !m;
|
|
78
|
+
i.useEffect(() => {
|
|
79
|
+
m && v(!1);
|
|
80
|
+
}, [m]);
|
|
81
|
+
const y = i.useCallback(() => {
|
|
82
|
+
var x;
|
|
83
|
+
const e = f.current, a = e == null ? void 0 : e.parentElement;
|
|
84
|
+
if (!e || !a) return;
|
|
85
|
+
const g = Array.from(a.children).filter((h) => h !== e).reduce((h, w) => h + V(w), 0), b = Math.max(a.children.length - 1, 0), W = a.clientWidth - g - M * b, L = t.map(
|
|
86
|
+
(h) => {
|
|
97
87
|
var w;
|
|
98
|
-
return ((w = o.current.get(
|
|
88
|
+
return ((w = o.current.get(h.key)) == null ? void 0 : w.getBoundingClientRect().width) ?? 0;
|
|
99
89
|
}
|
|
100
|
-
),
|
|
101
|
-
|
|
102
|
-
|
|
90
|
+
), S = ((x = s.current) == null ? void 0 : x.getBoundingClientRect().width) ?? 0;
|
|
91
|
+
p(
|
|
92
|
+
G(
|
|
93
|
+
L,
|
|
103
94
|
S,
|
|
104
|
-
W,
|
|
105
95
|
M,
|
|
106
|
-
|
|
96
|
+
W
|
|
107
97
|
)
|
|
108
98
|
);
|
|
109
99
|
}, [t]);
|
|
110
|
-
|
|
111
|
-
var
|
|
100
|
+
i.useLayoutEffect(() => {
|
|
101
|
+
var g;
|
|
112
102
|
y();
|
|
113
|
-
const e = (
|
|
103
|
+
const e = (g = f.current) == null ? void 0 : g.parentElement;
|
|
114
104
|
if (!e) return;
|
|
115
|
-
const
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
}), () =>
|
|
105
|
+
const a = new ResizeObserver(y);
|
|
106
|
+
return a.observe(e), Array.from(e.children).forEach((b) => {
|
|
107
|
+
b !== f.current && a.observe(b);
|
|
108
|
+
}), () => a.disconnect();
|
|
119
109
|
}, [y, t]);
|
|
120
|
-
const
|
|
121
|
-
return /* @__PURE__ */
|
|
122
|
-
|
|
110
|
+
const O = t.slice(0, u), N = t.slice(u);
|
|
111
|
+
return /* @__PURE__ */ C(
|
|
112
|
+
R.Root,
|
|
123
113
|
{
|
|
124
|
-
ref:
|
|
114
|
+
ref: z(f, d),
|
|
125
115
|
className: T(
|
|
126
116
|
// `overflow-hidden` clips the invisible measurement clone below —
|
|
127
117
|
// it's `position: absolute` + `visibility: hidden`, which keeps
|
|
@@ -133,40 +123,40 @@ const z = l.forwardRef(
|
|
|
133
123
|
"relative flex min-w-0 flex-nowrap items-center gap-4 overflow-hidden",
|
|
134
124
|
r
|
|
135
125
|
),
|
|
136
|
-
...
|
|
126
|
+
...c,
|
|
137
127
|
children: [
|
|
138
|
-
|
|
139
|
-
|
|
128
|
+
O.map((e) => /* @__PURE__ */ l(
|
|
129
|
+
R.Button,
|
|
140
130
|
{
|
|
141
131
|
disabled: e.disabled,
|
|
142
132
|
focusableWhenDisabled: !e.disabled,
|
|
143
133
|
onClick: e.onSelect,
|
|
144
|
-
render: /* @__PURE__ */
|
|
134
|
+
render: /* @__PURE__ */ l(E, { variant: "ghost", children: e.label })
|
|
145
135
|
},
|
|
146
136
|
e.key
|
|
147
137
|
)),
|
|
148
|
-
N.length > 0 && /* @__PURE__ */
|
|
149
|
-
|
|
138
|
+
N.length > 0 && /* @__PURE__ */ C(
|
|
139
|
+
_,
|
|
150
140
|
{
|
|
151
|
-
open:
|
|
152
|
-
onOpenChange:
|
|
153
|
-
disabled:
|
|
141
|
+
open: D,
|
|
142
|
+
onOpenChange: v,
|
|
143
|
+
disabled: m,
|
|
154
144
|
children: [
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
|
|
145
|
+
/* @__PURE__ */ l(
|
|
146
|
+
R.Button,
|
|
157
147
|
{
|
|
158
|
-
render: /* @__PURE__ */
|
|
159
|
-
|
|
148
|
+
render: /* @__PURE__ */ l(
|
|
149
|
+
F,
|
|
160
150
|
{
|
|
161
|
-
render: /* @__PURE__ */
|
|
151
|
+
render: /* @__PURE__ */ l(A, { variant: "secondary", children: n })
|
|
162
152
|
}
|
|
163
153
|
)
|
|
164
154
|
}
|
|
165
155
|
),
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
|
|
156
|
+
/* @__PURE__ */ l(I, { align: "start", children: N.map((e) => /* @__PURE__ */ l(
|
|
157
|
+
P,
|
|
168
158
|
{
|
|
169
|
-
disabled: e.disabled ||
|
|
159
|
+
disabled: e.disabled || m,
|
|
170
160
|
onClick: e.onSelect,
|
|
171
161
|
children: e.label
|
|
172
162
|
},
|
|
@@ -175,18 +165,18 @@ const z = l.forwardRef(
|
|
|
175
165
|
]
|
|
176
166
|
}
|
|
177
167
|
),
|
|
178
|
-
/* @__PURE__ */
|
|
168
|
+
/* @__PURE__ */ C(
|
|
179
169
|
"div",
|
|
180
170
|
{
|
|
181
171
|
"aria-hidden": !0,
|
|
182
172
|
inert: !0,
|
|
183
173
|
className: "pointer-events-none invisible absolute start-0 top-0 flex items-center gap-4",
|
|
184
174
|
children: [
|
|
185
|
-
t.map((e) => /* @__PURE__ */
|
|
186
|
-
|
|
175
|
+
t.map((e) => /* @__PURE__ */ l(
|
|
176
|
+
E,
|
|
187
177
|
{
|
|
188
|
-
ref: (
|
|
189
|
-
o.current.set(e.key,
|
|
178
|
+
ref: (a) => {
|
|
179
|
+
o.current.set(e.key, a);
|
|
190
180
|
},
|
|
191
181
|
variant: "ghost",
|
|
192
182
|
tabIndex: -1,
|
|
@@ -194,7 +184,7 @@ const z = l.forwardRef(
|
|
|
194
184
|
},
|
|
195
185
|
e.key
|
|
196
186
|
)),
|
|
197
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ l(A, { ref: s, variant: "secondary", tabIndex: -1, children: n })
|
|
198
188
|
]
|
|
199
189
|
}
|
|
200
190
|
)
|
|
@@ -203,12 +193,12 @@ const z = l.forwardRef(
|
|
|
203
193
|
);
|
|
204
194
|
}
|
|
205
195
|
);
|
|
206
|
-
|
|
196
|
+
$.displayName = "ToolbarActionList";
|
|
207
197
|
export {
|
|
208
198
|
j as Toolbar,
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
199
|
+
$ as ToolbarActionList,
|
|
200
|
+
X as ToolbarActions,
|
|
201
|
+
G as computeVisibleActionCount,
|
|
202
|
+
V as measureNaturalWidth
|
|
213
203
|
};
|
|
214
204
|
//# sourceMappingURL=toolbar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.js","sources":["../../../../src/components/ui/toolbar/toolbar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Toolbar as ToolbarPrimitive } from '@base-ui/react/toolbar';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '../button';\nimport { ButtonMenu } from '../button-menu';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../dropdown-menu';\n\n// Mirrors the Figma \"Toolbar\" component (node 3897:7199): a horizontal action\n// row — list actions, an optional overflow control (e.g. a `ButtonMenu`), and\n// an optional trailing area (`ToolbarActions`: a status text or a selection\n// counter + action) — typically shown above/below a list or table when rows\n// are selected or bulk actions are available. Every action is an existing\n// `Button`/`ButtonMenu` instance in Figma, so this component only lays them\n// out and carries no dedicated `--ui-toolbar-*` token tier; the 16px\n// inter-item gap is the Figma `gap/gap-16` semantic token, left un-tokenized —\n// same precedent as `FilterSearch`'s identical gap.\n//\n// The Figma `state: active | disabled` variant is the native `disabled`\n// attribute here: the root renders as a `<fieldset>` (reset to look like a\n// flex row) so every nested `Button`/`ButtonMenu` disables via the platform's\n// own fieldset-disables-descendants behavior — no prop-drilling into\n// arbitrary children required.\n//\n// `min-w-0` is required, not cosmetic: browsers give `<fieldset>` an\n// intrinsic `min-width: min-content` that Tailwind's reset doesn't touch, so\n// without it the fieldset refuses to shrink below its content's natural\n// width. `ToolbarActionList`'s collapse math reads this fieldset's own\n// `clientWidth` as \"available space\" — without `min-w-0` the fieldset\n// balloons to fit every action before that measurement ever runs, so it\n// always measures \"everything fits\" and the row never collapses.\n\nexport type ToolbarProps = React.ComponentPropsWithoutRef<'fieldset'>;\n\nconst Toolbar = React.forwardRef<HTMLFieldSetElement, ToolbarProps>(\n ({ className, ...props }, ref) => (\n <fieldset\n ref={ref}\n className={cn(\n 'm-0 flex min-w-0 items-center gap-4 border-0 p-0',\n className\n )}\n {...props}\n />\n )\n);\nToolbar.displayName = 'Toolbar';\n\n// Trailing, right-aligned area — a status text (e.g. \"25 of 1250 items\n// loaded\") or a selection counter + action (e.g. \"6 items selected: Deselect\").\n// 8px inter-child gap matches the Figma Counter part's own gap. `whitespace-nowrap`\n// is required, not cosmetic: the Figma \"Counter\" part is always single-line, but a\n// plain-text child (e.g. a `<span>`) defaults to `white-space: normal` — without\n// this, the text wraps mid-phrase once the row shrinks below its content's natural\n// width (`white-space` is inherited, so it cascades to children without them\n// needing their own override).\n//\n// `grow shrink-0` (not `flex-1`, which also shrinks): this area must grow to fill\n// leftover space so `justify-end` can right-align it, but must never shrink below\n// its own content's natural width. `ToolbarActionList`'s auto-collapse math reads\n// this element's *rendered* width as the space it needs to reserve — if it could\n// shrink, that measurement would be a moving target (less room reserved than the\n// content actually needs), so the actions row would under-collapse and this area's\n// (nowrap, unshrinkable) content would overflow past its own box instead.\nexport type ToolbarActionsProps = React.ComponentPropsWithoutRef<'div'>;\n\nconst ToolbarActions = React.forwardRef<HTMLDivElement, ToolbarActionsProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex grow shrink-0 items-center justify-end gap-2 whitespace-nowrap',\n className\n )}\n {...props}\n />\n )\n);\nToolbarActions.displayName = 'ToolbarActions';\n\n// Matches the `gap-4` utility used on both this component's row and\n// Toolbar's own root — keep in sync if either class changes.\nconst ACTION_LIST_GAP_PX = 16;\n\n// Pure so the collapse math is unit-testable without mocking layout/ResizeObserver.\n// Greedily fits as many leading items as possible into `availableWidth`; the\n// instant not everything fits, reserves `moreWidth` (+ one gap) for the\n// overflow trigger before fitting items.\nexport function computeVisibleActionCount(\n itemWidths: number[],\n moreWidth: number,\n gap: number,\n availableWidth: number\n): number {\n const total = itemWidths.length;\n if (total === 0) return 0;\n\n const fullWidth =\n itemWidths.reduce((sum, width) => sum + width, 0) + gap * (total - 1);\n if (fullWidth <= availableWidth) return total;\n\n let used = moreWidth;\n let count = 0;\n for (let i = 0; i < total; i++) {\n const next = used + itemWidths[i] + gap;\n if (next > availableWidth) break;\n used = next;\n count++;\n }\n return count;\n}\n\n// A grown sibling's own `getBoundingClientRect()` reflects its flex-grown\n// box, not the space its content actually needs — reading that would make\n// `measure()`'s \"available space\" calculation self-referential (see below),\n// so this reads the sibling's *content nodes* instead: normal (non-growing)\n// flex children report their natural width regardless of how large the\n// parent's box has grown to fill leftover row space. Bare text (e.g.\n// `<ToolbarActions>25 selected</ToolbarActions>` with no wrapping element)\n// renders as a `Text` node rather than an `Element`, so `children` alone\n// would miss it and fall through to the self-referential branch this\n// function exists to avoid — a `Range` measures that text's own rendered\n// width the same way `getBoundingClientRect()` does for an element.\n//\n// The sibling's own padding/border don't grow with flex-grow (only the free\n// space between content and box edge does), so they're safe to add back on\n// top of the content sum — unlike the box's own `getBoundingClientRect()`,\n// which is self-referential.\n//\n// Exported (like `computeVisibleActionCount`) so this is unit-testable\n// without mocking layout/ResizeObserver.\nexport function measureNaturalWidth(el: Element): number {\n const nodes = Array.from(el.childNodes).filter(\n (node): node is ChildNode =>\n node.nodeType === Node.ELEMENT_NODE ||\n (node.nodeType === Node.TEXT_NODE && !!node.textContent?.trim())\n );\n if (nodes.length === 0) return el.getBoundingClientRect().width;\n\n const style = getComputedStyle(el);\n const gap = parseFloat(style.columnGap) || 0;\n const ownPaddingAndBorder =\n (parseFloat(style.paddingLeft) || 0) +\n (parseFloat(style.paddingRight) || 0) +\n (parseFloat(style.borderLeftWidth) || 0) +\n (parseFloat(style.borderRightWidth) || 0);\n const widths = nodes.map((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const range = document.createRange();\n range.selectNodeContents(node);\n return range.getBoundingClientRect().width;\n }\n return (node as Element).getBoundingClientRect().width;\n });\n\n return (\n widths.reduce((sum, width) => sum + width, 0) +\n gap * (nodes.length - 1) +\n ownPaddingAndBorder\n );\n}\n\nfunction mergeRefs<T>(\n ...refs: Array<React.Ref<T> | undefined>\n): React.RefCallback<T> {\n return (node) => {\n for (const ref of refs) {\n if (!ref) continue;\n if (typeof ref === 'function') ref(node);\n else (ref as React.RefObject<T | null>).current = node;\n }\n };\n}\n\nexport interface ToolbarActionListItem {\n /** Stable identity — used as the React key in both the row and the overflow menu. */\n key: string;\n /** Rendered as the visible ghost Button's label, and the overflow menu item's label. */\n label: React.ReactNode;\n onSelect?: () => void;\n disabled?: boolean;\n}\n\nexport interface ToolbarActionListProps\n extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {\n /** Ordered list of actions; trailing ones collapse into \"More actions\" first. */\n actions: ToolbarActionListItem[];\n /** Label for the overflow trigger. */\n moreActionsLabel?: React.ReactNode;\n}\n\n// Mirrors the Figma \"ListActions\" part, but drives its `hasMoreActions`\n// overflow menu from measured available width instead of a static boolean —\n// the breakpoints spec (node 6262:28276) requires that \"if there is no space\n// for all Toolbar actions, then last actions must be hidden under More\n// actions.\" Renders every action as a ghost Button until they no longer fit\n// the row, then moves the trailing ones into a ButtonMenu + DropdownMenu\n// (same trigger Figma's `hasMoreActions` variant shows). An invisible clone\n// of every action + the trigger is kept mounted purely to measure natural\n// widths, since a hidden item can't report its own size.\n//\n// The root and each visible action/trigger are Base UI's `Toolbar.Root`/\n// `Toolbar.Button` (`@base-ui/react/toolbar`), giving the row the WAI-ARIA\n// toolbar pattern for free: one Tab stop, arrow-key roving-tabindex between\n// actions and into the overflow trigger. Base UI's `Toolbar.Root` does not\n// forward `enableHomeAndEndKeys` to its underlying composite, so Home/End\n// are not supported here — this is a Base UI limitation, not a choice made\n// in this component. `Toolbar.Button` composes\n// via `render` the same way `DropdownMenuTrigger`/`ButtonMenu` already do\n// below — it merges its own composite/keydown/disabled props onto whatever\n// element you pass. `focusableWhenDisabled={!action.disabled}` opts a\n// disabled action out of Base UI's default APG toolbar treatment (disabled\n// items normally stay focusable via `aria-disabled`, skippable with Tab) so\n// it matches every other disabled `Button` in this library: a real native\n// `disabled` button, unreachable via Tab or arrow keys. This MUST stay\n// conditional on `action.disabled` — `Toolbar.Root` builds its\n// `disabledIndices` list from `focusableWhenDisabled` alone, regardless of\n// the item's actual disabled state, so passing a bare `false` here disables\n// every index and silently breaks arrow-key navigation for the whole row.\n//\n// The invisible measurement clones stay plain `Button`/`ButtonMenu` (not\n// `Toolbar.Button`): registering them too would double-count hidden items in\n// the roving-tabindex list. This is scoped to the action list only —\n// `Toolbar`'s own `<fieldset>` disabled-cascade (see above) is\n// intentionally untouched; Base UI's `Fieldset.Root` strips the native\n// `disabled` attribute in favor of a context other Base UI Field-aware\n// components consume, which `Button`/`ButtonMenu` don't, so it would silently\n// break the \"disabling the toolbar disables every nested control\" guarantee.\nconst ToolbarActionList = React.forwardRef<\n HTMLDivElement,\n ToolbarActionListProps\n>(\n (\n { className, actions, moreActionsLabel = 'More actions', ...props },\n forwardedRef\n ) => {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const itemRefs = React.useRef<Map<string, HTMLButtonElement | null>>(\n new Map()\n );\n const moreRef = React.useRef<HTMLButtonElement>(null);\n const [visibleCount, setVisibleCount] = React.useState(actions.length);\n const [moreMenuOpen, setMoreMenuOpen] = React.useState(false);\n // The overflow menu renders in a portal, outside the ancestor\n // `<fieldset>`'s DOM subtree, so the native disabled-cascade (see\n // `Toolbar` above) never reaches its items. Tracked separately here so a\n // menu already open when the fieldset becomes disabled gets closed, and\n // its items stay disabled even if forced open again (e.g. via a ref).\n const [ancestorDisabled, setAncestorDisabled] = React.useState(false);\n\n React.useEffect(() => {\n const fieldset = containerRef.current?.closest('fieldset');\n if (!fieldset) return;\n const sync = () => setAncestorDisabled(fieldset.disabled);\n sync();\n const observer = new MutationObserver(sync);\n observer.observe(fieldset, {\n attributes: true,\n attributeFilter: ['disabled'],\n });\n return () => observer.disconnect();\n }, []);\n\n React.useEffect(() => {\n if (ancestorDisabled) setMoreMenuOpen(false);\n }, [ancestorDisabled]);\n\n const measure = React.useCallback(() => {\n const container = containerRef.current;\n const parent = container?.parentElement;\n if (!container || !parent) return;\n\n const siblingsWidth = Array.from(parent.children)\n .filter((child) => child !== container)\n .reduce((sum, el) => sum + measureNaturalWidth(el), 0);\n const gapCount = Math.max(parent.children.length - 1, 0);\n const available =\n parent.clientWidth - siblingsWidth - ACTION_LIST_GAP_PX * gapCount;\n\n // Keyed by `action.key`, not index — an index-keyed array would keep\n // stale entries (and a stale length) when `actions` shrinks, since\n // React only nulls out the removed clones' refs without truncating it.\n const itemWidths = actions.map(\n (action) =>\n itemRefs.current.get(action.key)?.getBoundingClientRect().width ?? 0\n );\n const moreWidth = moreRef.current?.getBoundingClientRect().width ?? 0;\n\n setVisibleCount(\n computeVisibleActionCount(\n itemWidths,\n moreWidth,\n ACTION_LIST_GAP_PX,\n available\n )\n );\n }, [actions]);\n\n React.useLayoutEffect(() => {\n measure();\n const parent = containerRef.current?.parentElement;\n if (!parent) return;\n const observer = new ResizeObserver(measure);\n observer.observe(parent);\n // A sibling like `ToolbarActions` is `shrink-0`, so its own border-box\n // grows with its content (e.g. a \"6 items selected\" counter ticking\n // up) even while `parent`'s box stays fixed — a ResizeObserver bound\n // only to `parent` never fires for that case, so `measure()` goes\n // stale and the row silently overflows instead of collapsing further.\n // Observing every sibling directly catches that box-size change too.\n Array.from(parent.children).forEach((sibling) => {\n if (sibling !== containerRef.current) observer.observe(sibling);\n });\n return () => observer.disconnect();\n }, [measure, actions]);\n\n const visibleActions = actions.slice(0, visibleCount);\n const hiddenActions = actions.slice(visibleCount);\n\n return (\n <ToolbarPrimitive.Root\n ref={mergeRefs(containerRef, forwardedRef)}\n className={cn(\n // `overflow-hidden` clips the invisible measurement clone below —\n // it's `position: absolute` + `visibility: hidden`, which keeps\n // contributing to this element's scrollable overflow (and thus a\n // real horizontal scrollbar on a narrow container/page) unless\n // something in the ancestor chain clips it. Visible content is\n // already sized to fit `availableWidth` by the collapse math, so\n // clipping never affects anything actually shown.\n 'relative flex min-w-0 flex-nowrap items-center gap-4 overflow-hidden',\n className\n )}\n {...props}\n >\n {visibleActions.map((action) => (\n <ToolbarPrimitive.Button\n key={action.key}\n disabled={action.disabled}\n focusableWhenDisabled={!action.disabled}\n onClick={action.onSelect}\n render={<Button variant=\"ghost\">{action.label}</Button>}\n />\n ))}\n {hiddenActions.length > 0 && (\n <DropdownMenu\n open={moreMenuOpen}\n onOpenChange={setMoreMenuOpen}\n disabled={ancestorDisabled}\n >\n <ToolbarPrimitive.Button\n render={\n <DropdownMenuTrigger\n render={\n <ButtonMenu variant=\"secondary\">\n {moreActionsLabel}\n </ButtonMenu>\n }\n />\n }\n />\n <DropdownMenuContent align=\"start\">\n {hiddenActions.map((action) => (\n <DropdownMenuItem\n key={action.key}\n disabled={action.disabled || ancestorDisabled}\n onClick={action.onSelect}\n >\n {action.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <div\n aria-hidden\n inert\n className=\"pointer-events-none invisible absolute start-0 top-0 flex items-center gap-4\"\n >\n {actions.map((action) => (\n <Button\n key={action.key}\n ref={(el) => {\n itemRefs.current.set(action.key, el);\n }}\n variant=\"ghost\"\n tabIndex={-1}\n >\n {action.label}\n </Button>\n ))}\n <ButtonMenu ref={moreRef} variant=\"secondary\" tabIndex={-1}>\n {moreActionsLabel}\n </ButtonMenu>\n </div>\n </ToolbarPrimitive.Root>\n );\n }\n);\nToolbarActionList.displayName = 'ToolbarActionList';\n\nexport { Toolbar, ToolbarActions, ToolbarActionList };\n"],"names":["Toolbar","React","className","props","ref","jsx","cn","ToolbarActions","ACTION_LIST_GAP_PX","computeVisibleActionCount","itemWidths","moreWidth","gap","availableWidth","total","sum","width","used","count","i","next","measureNaturalWidth","el","nodes","node","_a","style","ownPaddingAndBorder","range","mergeRefs","refs","ToolbarActionList","actions","moreActionsLabel","forwardedRef","containerRef","itemRefs","moreRef","visibleCount","setVisibleCount","moreMenuOpen","setMoreMenuOpen","ancestorDisabled","setAncestorDisabled","fieldset","sync","observer","measure","container","parent","siblingsWidth","child","gapCount","available","action","sibling","visibleActions","hiddenActions","jsxs","ToolbarPrimitive","Button","DropdownMenu","DropdownMenuTrigger","ButtonMenu","DropdownMenuContent","DropdownMenuItem"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toolbar.js","sources":["../../../../src/components/ui/toolbar/toolbar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Toolbar as ToolbarPrimitive } from '@base-ui/react/toolbar';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '../button';\nimport { ButtonMenu } from '../button-menu';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../dropdown-menu';\n\n// Mirrors the Figma \"Toolbar\" component (node 3897:7199): a horizontal action\n// row — list actions, an optional overflow control (e.g. a `ButtonMenu`), and\n// an optional trailing area (`ToolbarActions`: a status text or a selection\n// counter + action) — typically shown above/below a list or table when rows\n// are selected or bulk actions are available. Every action is an existing\n// `Button`/`ButtonMenu` instance in Figma, so this component only lays them\n// out and carries no dedicated `--ui-toolbar-*` token tier; the 16px\n// inter-item gap is the Figma `gap/gap-16` semantic token, left un-tokenized —\n// same precedent as `FilterSearch`'s identical gap.\n//\n// The Figma `state: active | disabled` variant is the native `disabled`\n// attribute here: the root renders as a `<fieldset>` (reset to look like a\n// flex row) so every nested `Button`/`ButtonMenu` disables via the platform's\n// own fieldset-disables-descendants behavior — no prop-drilling into\n// arbitrary children required.\n//\n// `min-w-0` is required, not cosmetic: browsers give `<fieldset>` an\n// intrinsic `min-width: min-content` that Tailwind's reset doesn't touch, so\n// without it the fieldset refuses to shrink below its content's natural\n// width. `ToolbarActionList`'s collapse math reads this fieldset's own\n// `clientWidth` as \"available space\" — without `min-w-0` the fieldset\n// balloons to fit every action before that measurement ever runs, so it\n// always measures \"everything fits\" and the row never collapses.\n\n// The fieldset cascade only reaches descendants, so anything a nested part\n// renders in a portal (see `ToolbarActionList`'s overflow menu) has to learn\n// the disabled state another way. This carries it in React, deliberately\n// rather than reading the fieldset's `disabled` attribute back out of the DOM:\n// an out-of-React side channel (a MutationObserver on the attribute) resolves\n// one render *after* the fact, so the portal renders enabled for a beat, and\n// its `setState` lands outside React's own scheduling — which under React 19's\n// act environment is intermittently never flushed at all, leaving the portal\n// enabled forever.\nconst ToolbarDisabledContext = React.createContext(false);\n\nexport type ToolbarProps = React.ComponentPropsWithoutRef<'fieldset'>;\n\nconst Toolbar = React.forwardRef<HTMLFieldSetElement, ToolbarProps>(\n ({ className, disabled, ...props }, ref) => (\n <ToolbarDisabledContext.Provider value={!!disabled}>\n <fieldset\n ref={ref}\n className={cn(\n 'm-0 flex min-w-0 items-center gap-4 border-0 p-0',\n className\n )}\n disabled={disabled}\n {...props}\n />\n </ToolbarDisabledContext.Provider>\n )\n);\nToolbar.displayName = 'Toolbar';\n\n// Trailing, right-aligned area — a status text (e.g. \"25 of 1250 items\n// loaded\") or a selection counter + action (e.g. \"6 items selected: Deselect\").\n// 8px inter-child gap matches the Figma Counter part's own gap. `whitespace-nowrap`\n// is required, not cosmetic: the Figma \"Counter\" part is always single-line, but a\n// plain-text child (e.g. a `<span>`) defaults to `white-space: normal` — without\n// this, the text wraps mid-phrase once the row shrinks below its content's natural\n// width (`white-space` is inherited, so it cascades to children without them\n// needing their own override).\n//\n// `grow shrink-0` (not `flex-1`, which also shrinks): this area must grow to fill\n// leftover space so `justify-end` can right-align it, but must never shrink below\n// its own content's natural width. `ToolbarActionList`'s auto-collapse math reads\n// this element's *rendered* width as the space it needs to reserve — if it could\n// shrink, that measurement would be a moving target (less room reserved than the\n// content actually needs), so the actions row would under-collapse and this area's\n// (nowrap, unshrinkable) content would overflow past its own box instead.\nexport type ToolbarActionsProps = React.ComponentPropsWithoutRef<'div'>;\n\nconst ToolbarActions = React.forwardRef<HTMLDivElement, ToolbarActionsProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex grow shrink-0 items-center justify-end gap-2 whitespace-nowrap',\n className\n )}\n {...props}\n />\n )\n);\nToolbarActions.displayName = 'ToolbarActions';\n\n// Matches the `gap-4` utility used on both this component's row and\n// Toolbar's own root — keep in sync if either class changes.\nconst ACTION_LIST_GAP_PX = 16;\n\n// Pure so the collapse math is unit-testable without mocking layout/ResizeObserver.\n// Greedily fits as many leading items as possible into `availableWidth`; the\n// instant not everything fits, reserves `moreWidth` (+ one gap) for the\n// overflow trigger before fitting items.\nexport function computeVisibleActionCount(\n itemWidths: number[],\n moreWidth: number,\n gap: number,\n availableWidth: number\n): number {\n const total = itemWidths.length;\n if (total === 0) return 0;\n\n const fullWidth =\n itemWidths.reduce((sum, width) => sum + width, 0) + gap * (total - 1);\n if (fullWidth <= availableWidth) return total;\n\n let used = moreWidth;\n let count = 0;\n for (let i = 0; i < total; i++) {\n const next = used + itemWidths[i] + gap;\n if (next > availableWidth) break;\n used = next;\n count++;\n }\n return count;\n}\n\n// A grown sibling's own `getBoundingClientRect()` reflects its flex-grown\n// box, not the space its content actually needs — reading that would make\n// `measure()`'s \"available space\" calculation self-referential (see below),\n// so this reads the sibling's *content nodes* instead: normal (non-growing)\n// flex children report their natural width regardless of how large the\n// parent's box has grown to fill leftover row space. Bare text (e.g.\n// `<ToolbarActions>25 selected</ToolbarActions>` with no wrapping element)\n// renders as a `Text` node rather than an `Element`, so `children` alone\n// would miss it and fall through to the self-referential branch this\n// function exists to avoid — a `Range` measures that text's own rendered\n// width the same way `getBoundingClientRect()` does for an element.\n//\n// The sibling's own padding/border don't grow with flex-grow (only the free\n// space between content and box edge does), so they're safe to add back on\n// top of the content sum — unlike the box's own `getBoundingClientRect()`,\n// which is self-referential.\n//\n// Exported (like `computeVisibleActionCount`) so this is unit-testable\n// without mocking layout/ResizeObserver.\nexport function measureNaturalWidth(el: Element): number {\n const nodes = Array.from(el.childNodes).filter(\n (node): node is ChildNode =>\n node.nodeType === Node.ELEMENT_NODE ||\n (node.nodeType === Node.TEXT_NODE && !!node.textContent?.trim())\n );\n if (nodes.length === 0) return el.getBoundingClientRect().width;\n\n const style = getComputedStyle(el);\n const gap = parseFloat(style.columnGap) || 0;\n const ownPaddingAndBorder =\n (parseFloat(style.paddingLeft) || 0) +\n (parseFloat(style.paddingRight) || 0) +\n (parseFloat(style.borderLeftWidth) || 0) +\n (parseFloat(style.borderRightWidth) || 0);\n const widths = nodes.map((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const range = document.createRange();\n range.selectNodeContents(node);\n return range.getBoundingClientRect().width;\n }\n return (node as Element).getBoundingClientRect().width;\n });\n\n return (\n widths.reduce((sum, width) => sum + width, 0) +\n gap * (nodes.length - 1) +\n ownPaddingAndBorder\n );\n}\n\nfunction mergeRefs<T>(\n ...refs: Array<React.Ref<T> | undefined>\n): React.RefCallback<T> {\n return (node) => {\n for (const ref of refs) {\n if (!ref) continue;\n if (typeof ref === 'function') ref(node);\n else (ref as React.RefObject<T | null>).current = node;\n }\n };\n}\n\nexport interface ToolbarActionListItem {\n /** Stable identity — used as the React key in both the row and the overflow menu. */\n key: string;\n /** Rendered as the visible ghost Button's label, and the overflow menu item's label. */\n label: React.ReactNode;\n onSelect?: () => void;\n disabled?: boolean;\n}\n\nexport interface ToolbarActionListProps\n extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {\n /** Ordered list of actions; trailing ones collapse into \"More actions\" first. */\n actions: ToolbarActionListItem[];\n /** Label for the overflow trigger. */\n moreActionsLabel?: React.ReactNode;\n}\n\n// Mirrors the Figma \"ListActions\" part, but drives its `hasMoreActions`\n// overflow menu from measured available width instead of a static boolean —\n// the breakpoints spec (node 6262:28276) requires that \"if there is no space\n// for all Toolbar actions, then last actions must be hidden under More\n// actions.\" Renders every action as a ghost Button until they no longer fit\n// the row, then moves the trailing ones into a ButtonMenu + DropdownMenu\n// (same trigger Figma's `hasMoreActions` variant shows). An invisible clone\n// of every action + the trigger is kept mounted purely to measure natural\n// widths, since a hidden item can't report its own size.\n//\n// The root and each visible action/trigger are Base UI's `Toolbar.Root`/\n// `Toolbar.Button` (`@base-ui/react/toolbar`), giving the row the WAI-ARIA\n// toolbar pattern for free: one Tab stop, arrow-key roving-tabindex between\n// actions and into the overflow trigger. Base UI's `Toolbar.Root` does not\n// forward `enableHomeAndEndKeys` to its underlying composite, so Home/End\n// are not supported here — this is a Base UI limitation, not a choice made\n// in this component. `Toolbar.Button` composes\n// via `render` the same way `DropdownMenuTrigger`/`ButtonMenu` already do\n// below — it merges its own composite/keydown/disabled props onto whatever\n// element you pass. `focusableWhenDisabled={!action.disabled}` opts a\n// disabled action out of Base UI's default APG toolbar treatment (disabled\n// items normally stay focusable via `aria-disabled`, skippable with Tab) so\n// it matches every other disabled `Button` in this library: a real native\n// `disabled` button, unreachable via Tab or arrow keys. This MUST stay\n// conditional on `action.disabled` — `Toolbar.Root` builds its\n// `disabledIndices` list from `focusableWhenDisabled` alone, regardless of\n// the item's actual disabled state, so passing a bare `false` here disables\n// every index and silently breaks arrow-key navigation for the whole row.\n//\n// The invisible measurement clones stay plain `Button`/`ButtonMenu` (not\n// `Toolbar.Button`): registering them too would double-count hidden items in\n// the roving-tabindex list. This is scoped to the action list only —\n// `Toolbar`'s own `<fieldset>` disabled-cascade (see above) is\n// intentionally untouched; Base UI's `Fieldset.Root` strips the native\n// `disabled` attribute in favor of a context other Base UI Field-aware\n// components consume, which `Button`/`ButtonMenu` don't, so it would silently\n// break the \"disabling the toolbar disables every nested control\" guarantee.\nconst ToolbarActionList = React.forwardRef<\n HTMLDivElement,\n ToolbarActionListProps\n>(\n (\n { className, actions, moreActionsLabel = 'More actions', ...props },\n forwardedRef\n ) => {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const itemRefs = React.useRef<Map<string, HTMLButtonElement | null>>(\n new Map()\n );\n const moreRef = React.useRef<HTMLButtonElement>(null);\n const [visibleCount, setVisibleCount] = React.useState(actions.length);\n const [moreMenuOpen, setMoreMenuOpen] = React.useState(false);\n // The overflow menu renders in a portal, outside the ancestor\n // `<fieldset>`'s DOM subtree, so the native disabled-cascade (see\n // `Toolbar` above) never reaches its items — they read the state off\n // context instead, so a menu already open when the toolbar becomes\n // disabled gets closed, and its items stay disabled even if forced open\n // again (e.g. via a ref).\n const ancestorDisabled = React.useContext(ToolbarDisabledContext);\n\n // Gating the `open` prop (rather than only resetting the state below)\n // closes the menu in the very commit the toolbar becomes disabled — an\n // effect would leave it open for one frame.\n const menuOpen = moreMenuOpen && !ancestorDisabled;\n\n // Still clear the stored state, or re-enabling the toolbar would pop the\n // menu back open on its own.\n React.useEffect(() => {\n if (ancestorDisabled) setMoreMenuOpen(false);\n }, [ancestorDisabled]);\n\n const measure = React.useCallback(() => {\n const container = containerRef.current;\n const parent = container?.parentElement;\n if (!container || !parent) return;\n\n const siblingsWidth = Array.from(parent.children)\n .filter((child) => child !== container)\n .reduce((sum, el) => sum + measureNaturalWidth(el), 0);\n const gapCount = Math.max(parent.children.length - 1, 0);\n const available =\n parent.clientWidth - siblingsWidth - ACTION_LIST_GAP_PX * gapCount;\n\n // Keyed by `action.key`, not index — an index-keyed array would keep\n // stale entries (and a stale length) when `actions` shrinks, since\n // React only nulls out the removed clones' refs without truncating it.\n const itemWidths = actions.map(\n (action) =>\n itemRefs.current.get(action.key)?.getBoundingClientRect().width ?? 0\n );\n const moreWidth = moreRef.current?.getBoundingClientRect().width ?? 0;\n\n setVisibleCount(\n computeVisibleActionCount(\n itemWidths,\n moreWidth,\n ACTION_LIST_GAP_PX,\n available\n )\n );\n }, [actions]);\n\n React.useLayoutEffect(() => {\n measure();\n const parent = containerRef.current?.parentElement;\n if (!parent) return;\n const observer = new ResizeObserver(measure);\n observer.observe(parent);\n // A sibling like `ToolbarActions` is `shrink-0`, so its own border-box\n // grows with its content (e.g. a \"6 items selected\" counter ticking\n // up) even while `parent`'s box stays fixed — a ResizeObserver bound\n // only to `parent` never fires for that case, so `measure()` goes\n // stale and the row silently overflows instead of collapsing further.\n // Observing every sibling directly catches that box-size change too.\n Array.from(parent.children).forEach((sibling) => {\n if (sibling !== containerRef.current) observer.observe(sibling);\n });\n return () => observer.disconnect();\n }, [measure, actions]);\n\n const visibleActions = actions.slice(0, visibleCount);\n const hiddenActions = actions.slice(visibleCount);\n\n return (\n <ToolbarPrimitive.Root\n ref={mergeRefs(containerRef, forwardedRef)}\n className={cn(\n // `overflow-hidden` clips the invisible measurement clone below —\n // it's `position: absolute` + `visibility: hidden`, which keeps\n // contributing to this element's scrollable overflow (and thus a\n // real horizontal scrollbar on a narrow container/page) unless\n // something in the ancestor chain clips it. Visible content is\n // already sized to fit `availableWidth` by the collapse math, so\n // clipping never affects anything actually shown.\n 'relative flex min-w-0 flex-nowrap items-center gap-4 overflow-hidden',\n className\n )}\n {...props}\n >\n {visibleActions.map((action) => (\n <ToolbarPrimitive.Button\n key={action.key}\n disabled={action.disabled}\n focusableWhenDisabled={!action.disabled}\n onClick={action.onSelect}\n render={<Button variant=\"ghost\">{action.label}</Button>}\n />\n ))}\n {hiddenActions.length > 0 && (\n <DropdownMenu\n open={menuOpen}\n onOpenChange={setMoreMenuOpen}\n disabled={ancestorDisabled}\n >\n <ToolbarPrimitive.Button\n render={\n <DropdownMenuTrigger\n render={\n <ButtonMenu variant=\"secondary\">\n {moreActionsLabel}\n </ButtonMenu>\n }\n />\n }\n />\n <DropdownMenuContent align=\"start\">\n {hiddenActions.map((action) => (\n <DropdownMenuItem\n key={action.key}\n disabled={action.disabled || ancestorDisabled}\n onClick={action.onSelect}\n >\n {action.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <div\n aria-hidden\n inert\n className=\"pointer-events-none invisible absolute start-0 top-0 flex items-center gap-4\"\n >\n {actions.map((action) => (\n <Button\n key={action.key}\n ref={(el) => {\n itemRefs.current.set(action.key, el);\n }}\n variant=\"ghost\"\n tabIndex={-1}\n >\n {action.label}\n </Button>\n ))}\n <ButtonMenu ref={moreRef} variant=\"secondary\" tabIndex={-1}>\n {moreActionsLabel}\n </ButtonMenu>\n </div>\n </ToolbarPrimitive.Root>\n );\n }\n);\nToolbarActionList.displayName = 'ToolbarActionList';\n\nexport { Toolbar, ToolbarActions, ToolbarActionList };\n"],"names":["ToolbarDisabledContext","React","Toolbar","className","disabled","props","ref","jsx","cn","ToolbarActions","ACTION_LIST_GAP_PX","computeVisibleActionCount","itemWidths","moreWidth","gap","availableWidth","total","sum","width","used","count","i","next","measureNaturalWidth","el","nodes","node","_a","style","ownPaddingAndBorder","range","mergeRefs","refs","ToolbarActionList","actions","moreActionsLabel","forwardedRef","containerRef","itemRefs","moreRef","visibleCount","setVisibleCount","moreMenuOpen","setMoreMenuOpen","ancestorDisabled","menuOpen","measure","container","parent","siblingsWidth","child","gapCount","available","action","observer","sibling","visibleActions","hiddenActions","jsxs","ToolbarPrimitive","Button","DropdownMenu","DropdownMenuTrigger","ButtonMenu","DropdownMenuContent","DropdownMenuItem"],"mappings":"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"}
|