twico-ui 1.4.0 → 1.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/README.md +1 -0
- package/dist/index.cjs +1084 -683
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +384 -146
- package/dist/index.d.ts +384 -146
- package/dist/index.mjs +1083 -684
- package/dist/index.mjs.map +1 -1
- package/llms.txt +32 -9
- package/package.json +3 -1
- package/styles/twico-ui.css +15 -5
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var React24 = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
|
|
@@ -23,12 +23,12 @@ function _interopNamespace(e) {
|
|
|
23
23
|
return Object.freeze(n);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
var
|
|
26
|
+
var React24__namespace = /*#__PURE__*/_interopNamespace(React24);
|
|
27
27
|
|
|
28
28
|
// components/navigation/Accordion.jsx
|
|
29
|
-
var SUPPORTS_STYLE_HOIST = parseInt(String(
|
|
29
|
+
var SUPPORTS_STYLE_HOIST = parseInt(String(React24__namespace.version), 10) >= 19;
|
|
30
30
|
function useScopedStyles(id, css) {
|
|
31
|
-
|
|
31
|
+
React24__namespace.useInsertionEffect(() => {
|
|
32
32
|
if (SUPPORTS_STYLE_HOIST) return;
|
|
33
33
|
if (typeof document === "undefined" || document.getElementById(id)) return;
|
|
34
34
|
const el = document.createElement("style");
|
|
@@ -36,7 +36,7 @@ function useScopedStyles(id, css) {
|
|
|
36
36
|
el.textContent = css;
|
|
37
37
|
document.head.appendChild(el);
|
|
38
38
|
}, [id, css]);
|
|
39
|
-
return SUPPORTS_STYLE_HOIST ?
|
|
39
|
+
return SUPPORTS_STYLE_HOIST ? React24__namespace.createElement("style", { href: id, precedence: "twc-ui" }, css) : null;
|
|
40
40
|
}
|
|
41
41
|
var ACCORDION_CSS = `
|
|
42
42
|
.twc-accordion { display: flex; flex-direction: column; font-family: var(--font-sans);
|
|
@@ -50,7 +50,9 @@ var ACCORDION_CSS = `
|
|
|
50
50
|
color: var(--color-text); text-align: start;
|
|
51
51
|
transition: background-color var(--duration-fast) var(--ease-standard);
|
|
52
52
|
}
|
|
53
|
-
.twc-
|
|
53
|
+
.twc-accordion__heading { margin: 0; font: inherit; }
|
|
54
|
+
.twc-accordion__trigger:hover:not(:disabled) { background: var(--color-surface-sunken); }
|
|
55
|
+
.twc-accordion__trigger:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
54
56
|
.twc-accordion__trigger:focus-visible { outline: none; box-shadow: var(--ring); }
|
|
55
57
|
.twc-accordion__label { flex: 1; }
|
|
56
58
|
.twc-accordion__chevron { flex: none; color: var(--color-text-subtle); transition: transform var(--duration-base) var(--ease-spring); }
|
|
@@ -69,14 +71,19 @@ function Accordion({
|
|
|
69
71
|
defaultOpen = [],
|
|
70
72
|
open: openProp,
|
|
71
73
|
onOpenChange,
|
|
74
|
+
headingLevel = 3,
|
|
72
75
|
className = "",
|
|
76
|
+
onKeyDown: onKeyDownProp,
|
|
73
77
|
...rest
|
|
74
78
|
}) {
|
|
75
79
|
const __twcStyles = useScopedStyles("twc-accordion-styles", ACCORDION_CSS);
|
|
76
|
-
const
|
|
80
|
+
const rootRef = React24__namespace.default.useRef(null);
|
|
81
|
+
const [internal, setInternal] = React24__namespace.default.useState(() => new Set(defaultOpen));
|
|
77
82
|
const open = openProp !== void 0 ? new Set(openProp) : internal;
|
|
78
|
-
const baseId =
|
|
83
|
+
const baseId = React24__namespace.default.useId();
|
|
79
84
|
function toggle(val) {
|
|
85
|
+
const item = items.find((x) => x.value === val);
|
|
86
|
+
if (item?.disabled) return;
|
|
80
87
|
const next = new Set(open);
|
|
81
88
|
if (next.has(val)) next.delete(val);
|
|
82
89
|
else {
|
|
@@ -86,18 +93,47 @@ function Accordion({
|
|
|
86
93
|
if (openProp === void 0) setInternal(next);
|
|
87
94
|
onOpenChange?.([...next]);
|
|
88
95
|
}
|
|
89
|
-
|
|
96
|
+
function handleKeyDown(e) {
|
|
97
|
+
onKeyDownProp?.(e);
|
|
98
|
+
if (!(e.target instanceof HTMLElement) || !e.target.classList.contains("twc-accordion__trigger")) return;
|
|
99
|
+
const triggers = Array.from(rootRef.current.querySelectorAll(".twc-accordion__trigger")).filter((b) => !b.disabled);
|
|
100
|
+
const i = triggers.indexOf(e.target);
|
|
101
|
+
if (i < 0) return;
|
|
102
|
+
const len2 = triggers.length;
|
|
103
|
+
let next;
|
|
104
|
+
switch (e.key) {
|
|
105
|
+
case "ArrowDown":
|
|
106
|
+
next = (i + 1) % len2;
|
|
107
|
+
break;
|
|
108
|
+
case "ArrowUp":
|
|
109
|
+
next = (i - 1 + len2) % len2;
|
|
110
|
+
break;
|
|
111
|
+
case "Home":
|
|
112
|
+
next = 0;
|
|
113
|
+
break;
|
|
114
|
+
case "End":
|
|
115
|
+
next = len2 - 1;
|
|
116
|
+
break;
|
|
117
|
+
default:
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
triggers[next].focus();
|
|
122
|
+
}
|
|
123
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, className: `twc-accordion ${className}`, onKeyDown: handleKeyDown, ...rest, children: [
|
|
90
124
|
__twcStyles,
|
|
91
125
|
items.map((it, i) => {
|
|
92
126
|
const isOpen = open.has(it.value);
|
|
93
127
|
const triggerId = `${baseId}-trigger-${i}`;
|
|
94
128
|
const panelId = `${baseId}-panel-${i}`;
|
|
129
|
+
const lvl = Math.min(6, Math.max(1, it.headingLevel ?? headingLevel));
|
|
130
|
+
const Heading2 = `h${lvl}`;
|
|
95
131
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-accordion__item", children: [
|
|
96
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", id: triggerId, className: "twc-accordion__trigger", "data-open": isOpen || void 0, "aria-expanded": isOpen, "aria-controls": panelId, onClick: () => toggle(it.value), children: [
|
|
132
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading2, { className: "twc-accordion__heading", children: /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", id: triggerId, className: "twc-accordion__trigger", "data-open": isOpen || void 0, disabled: it.disabled || void 0, "aria-disabled": it.disabled || void 0, "data-disabled": it.disabled || void 0, "aria-expanded": isOpen, "aria-controls": panelId, onClick: () => toggle(it.value), children: [
|
|
97
133
|
it.icon,
|
|
98
134
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-accordion__label", children: it.label }),
|
|
99
135
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-accordion__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" }) }) })
|
|
100
|
-
] }),
|
|
136
|
+
] }) }),
|
|
101
137
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-accordion__panel", id: panelId, role: "region", "aria-labelledby": triggerId, "data-open": isOpen || void 0, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-accordion__panel-inner", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-accordion__content", children: it.content }) }) })
|
|
102
138
|
] }, it.value);
|
|
103
139
|
})
|
|
@@ -153,11 +189,15 @@ function Alert({
|
|
|
153
189
|
title,
|
|
154
190
|
icon,
|
|
155
191
|
onClose,
|
|
192
|
+
live,
|
|
193
|
+
closeLabel = "Dismiss",
|
|
156
194
|
className = "",
|
|
157
195
|
...rest
|
|
158
196
|
}) {
|
|
159
197
|
const __twcStyles = useScopedStyles("twc-alert-styles", ALERT_CSS);
|
|
160
|
-
|
|
198
|
+
const resolvedLive = live ?? (tone === "danger" || tone === "warning" ? "assertive" : tone === "success" || tone === "info" ? "polite" : "off");
|
|
199
|
+
const liveProps = resolvedLive === "assertive" ? { role: "alert" } : resolvedLive === "polite" ? { role: "status" } : {};
|
|
200
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-alert ${className}`, "data-tone": tone, "data-variant": variant, ...liveProps, ...rest, children: [
|
|
161
201
|
__twcStyles,
|
|
162
202
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-alert__icon", "aria-hidden": "true", children: icon || /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
163
203
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
@@ -167,7 +207,7 @@ function Alert({
|
|
|
167
207
|
title ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-alert__title", children: title }) : null,
|
|
168
208
|
children ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-alert__desc", children }) : null
|
|
169
209
|
] }),
|
|
170
|
-
onClose ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-alert__close", onClick: onClose, "aria-label":
|
|
210
|
+
onClose ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-alert__close", onClick: onClose, "aria-label": closeLabel, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
|
|
171
211
|
] });
|
|
172
212
|
}
|
|
173
213
|
var AVATAR_CSS = `
|
|
@@ -212,20 +252,25 @@ function safeSrc(url) {
|
|
|
212
252
|
if (s.startsWith("data:") && !s.startsWith("data:image/")) return void 0;
|
|
213
253
|
return url;
|
|
214
254
|
}
|
|
255
|
+
var STATUS_LABELS = { online: "Online", busy: "Busy", away: "Away", offline: "Offline" };
|
|
215
256
|
function Avatar({
|
|
216
257
|
src,
|
|
217
258
|
name,
|
|
218
259
|
size = "md",
|
|
219
260
|
square = false,
|
|
220
261
|
status,
|
|
262
|
+
statusLabel,
|
|
263
|
+
statusLabels,
|
|
221
264
|
ring = false,
|
|
222
265
|
className = "",
|
|
223
266
|
...rest
|
|
224
267
|
}) {
|
|
225
268
|
const __twcStyles = useScopedStyles("twc-avatar-styles", AVATAR_CSS);
|
|
226
|
-
const [errored, setErrored] =
|
|
269
|
+
const [errored, setErrored] = React24__namespace.default.useState(false);
|
|
227
270
|
const cleanSrc = safeSrc(src);
|
|
228
271
|
const showImg = cleanSrc && !errored;
|
|
272
|
+
const _statusLabel = status ? statusLabel ?? statusLabels?.[status] ?? STATUS_LABELS[status] : void 0;
|
|
273
|
+
const baseName = name || "avatar";
|
|
229
274
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
230
275
|
"span",
|
|
231
276
|
{
|
|
@@ -233,12 +278,12 @@ function Avatar({
|
|
|
233
278
|
"data-size": size,
|
|
234
279
|
"data-square": square || void 0,
|
|
235
280
|
role: "img",
|
|
236
|
-
"aria-label":
|
|
281
|
+
"aria-label": _statusLabel ? `${baseName}, ${_statusLabel}` : baseName,
|
|
237
282
|
...rest,
|
|
238
283
|
children: [
|
|
239
284
|
__twcStyles,
|
|
240
285
|
showImg ? /* @__PURE__ */ jsxRuntime.jsx("img", { className: "twc-avatar__img", src: cleanSrc, alt: name || "", onError: () => setErrored(true) }, cleanSrc) : initials(name),
|
|
241
|
-
status ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-avatar__status", "data-status": status }) : null
|
|
286
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-avatar__status", "data-status": status, title: _statusLabel }) : null
|
|
242
287
|
]
|
|
243
288
|
}
|
|
244
289
|
);
|
|
@@ -279,6 +324,11 @@ var MENU_CSS = `
|
|
|
279
324
|
.twc-menu__item-label { flex: 1 1 auto; min-width: 0; }
|
|
280
325
|
.twc-menu__shortcut { margin-inline-start: auto; padding-inline-start: var(--space-3); font-size: var(--text-xs); color: var(--color-text-subtle); font-family: var(--font-mono); }
|
|
281
326
|
`;
|
|
327
|
+
var safeHref = (url) => {
|
|
328
|
+
if (url == null) return void 0;
|
|
329
|
+
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
330
|
+
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
331
|
+
};
|
|
282
332
|
function Menu({
|
|
283
333
|
trigger,
|
|
284
334
|
items,
|
|
@@ -288,26 +338,29 @@ function Menu({
|
|
|
288
338
|
open: openProp,
|
|
289
339
|
defaultOpen = false,
|
|
290
340
|
onOpenChange,
|
|
341
|
+
"aria-label": ariaLabel,
|
|
342
|
+
"aria-labelledby": ariaLabelledby,
|
|
291
343
|
className = "",
|
|
292
344
|
...rest
|
|
293
345
|
}) {
|
|
294
346
|
const __twcStyles = useScopedStyles("twc-menu-styles", MENU_CSS);
|
|
295
|
-
const [openState, setOpenState] =
|
|
296
|
-
const [render, setRender] =
|
|
297
|
-
const [pos, setPos] =
|
|
298
|
-
const [active, setActive] =
|
|
299
|
-
const wrapRef =
|
|
300
|
-
const menuRef =
|
|
301
|
-
const menuId =
|
|
347
|
+
const [openState, setOpenState] = React24__namespace.default.useState(defaultOpen);
|
|
348
|
+
const [render, setRender] = React24__namespace.default.useState(false);
|
|
349
|
+
const [pos, setPos] = React24__namespace.default.useState(null);
|
|
350
|
+
const [active, setActive] = React24__namespace.default.useState(-1);
|
|
351
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
352
|
+
const menuRef = React24__namespace.default.useRef(null);
|
|
353
|
+
const menuId = React24__namespace.default.useId();
|
|
354
|
+
const headerId = `${menuId}-header`;
|
|
302
355
|
const controlled = openProp !== void 0;
|
|
303
356
|
const open = controlled ? !!openProp : openState;
|
|
304
|
-
const openRef =
|
|
357
|
+
const openRef = React24__namespace.default.useRef(open);
|
|
305
358
|
openRef.current = open;
|
|
306
|
-
const controlledRef =
|
|
359
|
+
const controlledRef = React24__namespace.default.useRef(controlled);
|
|
307
360
|
controlledRef.current = controlled;
|
|
308
|
-
const onOpenChangeRef =
|
|
361
|
+
const onOpenChangeRef = React24__namespace.default.useRef(onOpenChange);
|
|
309
362
|
onOpenChangeRef.current = onOpenChange;
|
|
310
|
-
const setOpen =
|
|
363
|
+
const setOpen = React24__namespace.default.useCallback((next) => {
|
|
311
364
|
const value = typeof next === "function" ? next(openRef.current) : next;
|
|
312
365
|
if (value === openRef.current) return;
|
|
313
366
|
if (!controlledRef.current) setOpenState(value);
|
|
@@ -315,7 +368,7 @@ function Menu({
|
|
|
315
368
|
}, []);
|
|
316
369
|
const RD = { createPortal: typeof reactDom.createPortal === "function" ? reactDom.createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
|
|
317
370
|
const interactiveIdx = items.map((it, i) => !it.separator && !it.heading ? i : -1).filter((i) => i >= 0);
|
|
318
|
-
const place =
|
|
371
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
319
372
|
const t = wrapRef.current;
|
|
320
373
|
if (!t) return;
|
|
321
374
|
const r = t.getBoundingClientRect();
|
|
@@ -330,7 +383,7 @@ function Menu({
|
|
|
330
383
|
const avail = (flip ? r.top : vh - r.bottom) - gap - M;
|
|
331
384
|
setPos({ top, bottom, left, width: w, flip, maxHeight: Math.max(120, avail) });
|
|
332
385
|
}, [align, width]);
|
|
333
|
-
|
|
386
|
+
React24__namespace.default.useEffect(() => {
|
|
334
387
|
if (!open) return;
|
|
335
388
|
place();
|
|
336
389
|
const onMove = () => place();
|
|
@@ -348,7 +401,7 @@ function Menu({
|
|
|
348
401
|
document.removeEventListener("mousedown", onDown);
|
|
349
402
|
};
|
|
350
403
|
}, [open, place]);
|
|
351
|
-
|
|
404
|
+
React24__namespace.default.useEffect(() => {
|
|
352
405
|
if (open) {
|
|
353
406
|
setRender(true);
|
|
354
407
|
return;
|
|
@@ -394,8 +447,12 @@ function Menu({
|
|
|
394
447
|
e.preventDefault();
|
|
395
448
|
const it = items[active];
|
|
396
449
|
if (it && !it.disabled) {
|
|
397
|
-
|
|
398
|
-
|
|
450
|
+
const el = typeof document !== "undefined" ? document.getElementById(`${menuId}-item-${active}`) : null;
|
|
451
|
+
if (el && el.tagName === "A") el.click();
|
|
452
|
+
else {
|
|
453
|
+
it.onClick?.();
|
|
454
|
+
setOpen(false);
|
|
455
|
+
}
|
|
399
456
|
}
|
|
400
457
|
}
|
|
401
458
|
}
|
|
@@ -409,29 +466,32 @@ function Menu({
|
|
|
409
466
|
"data-align": align,
|
|
410
467
|
"data-flip": pos.flip || void 0,
|
|
411
468
|
role: "menu",
|
|
469
|
+
"aria-label": ariaLabel,
|
|
470
|
+
"aria-labelledby": ariaLabelledby ?? (ariaLabel ? void 0 : header ? headerId : void 0),
|
|
412
471
|
style: { top: pos.top, bottom: pos.bottom, left: pos.left, minWidth: pos.width, width: pos.width, maxHeight: pos.maxHeight },
|
|
413
472
|
children: [
|
|
414
473
|
__twcStyles,
|
|
415
|
-
header ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-menu__header", children: header }) : null,
|
|
474
|
+
header ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-menu__header", id: headerId, children: header }) : null,
|
|
416
475
|
items.map((it, i) => {
|
|
417
476
|
if (it.separator) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-menu__sep", role: "separator" }, `s${i}`);
|
|
418
477
|
if (it.label && it.heading) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-menu__label", children: it.label }, `h${i}`);
|
|
478
|
+
const href = !it.disabled ? safeHref(it.href) : void 0;
|
|
479
|
+
const Tag2 = href ? "a" : "button";
|
|
419
480
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
420
|
-
|
|
481
|
+
Tag2,
|
|
421
482
|
{
|
|
422
|
-
type: "button",
|
|
423
483
|
id: `${menuId}-item-${i}`,
|
|
424
484
|
className: "twc-menu__item",
|
|
425
485
|
role: "menuitem",
|
|
426
486
|
tabIndex: -1,
|
|
427
487
|
"data-danger": it.danger || void 0,
|
|
428
488
|
"data-active": active === i || void 0,
|
|
429
|
-
disabled: it.disabled,
|
|
430
489
|
onMouseEnter: () => setActive(i),
|
|
431
490
|
onClick: () => {
|
|
432
491
|
it.onClick?.();
|
|
433
492
|
setOpen(false);
|
|
434
493
|
},
|
|
494
|
+
...Tag2 === "button" ? { type: "button", disabled: it.disabled } : { href, target: it.target, rel: it.rel },
|
|
435
495
|
children: [
|
|
436
496
|
it.icon,
|
|
437
497
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-menu__item-label", children: it.label }),
|
|
@@ -445,7 +505,7 @@ function Menu({
|
|
|
445
505
|
}
|
|
446
506
|
) : null;
|
|
447
507
|
const activeDescId = open && active >= 0 ? `${menuId}-item-${active}` : void 0;
|
|
448
|
-
const triggerEl =
|
|
508
|
+
const triggerEl = React24__namespace.default.isValidElement(trigger) ? React24__namespace.default.cloneElement(trigger, {
|
|
449
509
|
onClick: (e) => {
|
|
450
510
|
trigger.props.onClick?.(e);
|
|
451
511
|
toggle();
|
|
@@ -528,7 +588,7 @@ function AvatarMenu({
|
|
|
528
588
|
]
|
|
529
589
|
}
|
|
530
590
|
);
|
|
531
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Menu, { className, trigger, items, header, align, width: 240, ...rest });
|
|
591
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Menu, { className, trigger, items, header, align, width: 240, "aria-label": `${name || "Account"} menu`, ...rest });
|
|
532
592
|
}
|
|
533
593
|
var BADGE_CSS = `
|
|
534
594
|
.twc-badge {
|
|
@@ -595,7 +655,7 @@ var BREADCRUMB_CSS = `
|
|
|
595
655
|
.twc-breadcrumb__ellipsis { border: none; background: transparent; cursor: pointer; color: var(--color-text-subtle); padding: 3px 7px; border-radius: var(--radius-sm); font: inherit; }
|
|
596
656
|
.twc-breadcrumb__ellipsis:hover { background: var(--color-surface-sunken); color: var(--color-text); }
|
|
597
657
|
`;
|
|
598
|
-
function
|
|
658
|
+
function safeHref2(url) {
|
|
599
659
|
if (url == null) return void 0;
|
|
600
660
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
601
661
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -609,7 +669,7 @@ function Breadcrumb({
|
|
|
609
669
|
...rest
|
|
610
670
|
}) {
|
|
611
671
|
const __twcStyles = useScopedStyles("twc-breadcrumb-styles", BREADCRUMB_CSS);
|
|
612
|
-
const [expanded, setExpanded] =
|
|
672
|
+
const [expanded, setExpanded] = React24__namespace.default.useState(false);
|
|
613
673
|
const sep = separator || /* @__PURE__ */ jsxRuntime.jsx(ChevronSep, {});
|
|
614
674
|
let display = items;
|
|
615
675
|
if (maxItems > 0 && items.length > maxItems && !expanded) {
|
|
@@ -622,7 +682,7 @@ function Breadcrumb({
|
|
|
622
682
|
__twcStyles,
|
|
623
683
|
display.map((it, i) => {
|
|
624
684
|
const last = i === display.length - 1;
|
|
625
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
685
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React24__namespace.default.Fragment, { children: [
|
|
626
686
|
it.ellipsis ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-breadcrumb__ellipsis", "aria-label": "Show more", onClick: () => setExpanded(true), children: "\u2026" }) : last ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
627
687
|
"span",
|
|
628
688
|
{
|
|
@@ -638,7 +698,7 @@ function Breadcrumb({
|
|
|
638
698
|
"a",
|
|
639
699
|
{
|
|
640
700
|
className: "twc-breadcrumb__item",
|
|
641
|
-
href:
|
|
701
|
+
href: safeHref2(it.href) || "#",
|
|
642
702
|
onClick: it.onClick,
|
|
643
703
|
children: [
|
|
644
704
|
it.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: { display: "inline-flex" }, children: it.icon }) : null,
|
|
@@ -741,7 +801,7 @@ var CSS2 = `
|
|
|
741
801
|
animation: twico-ripple var(--duration-slow) var(--ease-out) forwards;
|
|
742
802
|
}
|
|
743
803
|
`;
|
|
744
|
-
function
|
|
804
|
+
function safeHref3(url) {
|
|
745
805
|
if (url == null) return void 0;
|
|
746
806
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
747
807
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -763,7 +823,7 @@ function Button({
|
|
|
763
823
|
...rest
|
|
764
824
|
}) {
|
|
765
825
|
const __twcStyles = useScopedStyles("twc-btn-styles", CSS2);
|
|
766
|
-
const [ripples, setRipples] =
|
|
826
|
+
const [ripples, setRipples] = React24__namespace.default.useState([]);
|
|
767
827
|
const Tag2 = as;
|
|
768
828
|
const inert = Tag2 === "a" && (disabled || loading);
|
|
769
829
|
function handleClick(e) {
|
|
@@ -792,7 +852,7 @@ function Button({
|
|
|
792
852
|
"data-block": fullWidth || void 0,
|
|
793
853
|
disabled: Tag2 === "button" ? disabled || loading : void 0,
|
|
794
854
|
type: Tag2 === "button" ? "button" : void 0,
|
|
795
|
-
href: inert ? void 0 :
|
|
855
|
+
href: inert ? void 0 : safeHref3(href),
|
|
796
856
|
"aria-disabled": inert || void 0,
|
|
797
857
|
tabIndex: inert ? -1 : void 0,
|
|
798
858
|
"aria-busy": loading || void 0,
|
|
@@ -900,6 +960,15 @@ var CAROUSEL_CSS = `
|
|
|
900
960
|
.twc-carousel__dot { width: 8px; height: 8px; border-radius: var(--radius-full); border: none; padding: 0; cursor: pointer;
|
|
901
961
|
background: var(--color-border-strong); transition: width var(--duration-base) var(--ease-spring), background-color var(--duration-fast); }
|
|
902
962
|
.twc-carousel__dot[data-active="true"] { width: 22px; background: var(--color-primary); }
|
|
963
|
+
.twc-carousel__pause { position: absolute; top: 12px; inset-inline-end: 12px; z-index: 2;
|
|
964
|
+
display: grid; place-items: center; width: 34px; height: 34px; border-radius: var(--radius-full);
|
|
965
|
+
background: color-mix(in srgb, var(--color-surface) 88%, transparent); color: var(--color-text);
|
|
966
|
+
border: var(--border-thin) solid var(--color-border); box-shadow: var(--shadow-sm); cursor: pointer;
|
|
967
|
+
backdrop-filter: blur(6px); transition: background-color var(--duration-fast) var(--ease-standard); }
|
|
968
|
+
.twc-carousel__pause:hover { background: var(--color-surface); }
|
|
969
|
+
.twc-carousel__pause svg { width: 15px; height: 15px; display: block; }
|
|
970
|
+
.twc-carousel__live { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
|
971
|
+
overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
|
|
903
972
|
`;
|
|
904
973
|
function Carousel({
|
|
905
974
|
children,
|
|
@@ -908,35 +977,76 @@ function Carousel({
|
|
|
908
977
|
onIndexChange,
|
|
909
978
|
showArrows = true,
|
|
910
979
|
showDots = true,
|
|
980
|
+
showPauseButton = true,
|
|
911
981
|
loop = true,
|
|
912
982
|
autoPlay = false,
|
|
913
983
|
interval = 4e3,
|
|
984
|
+
label,
|
|
985
|
+
pauseLabel = "Pause",
|
|
986
|
+
playLabel = "Play",
|
|
914
987
|
className = "",
|
|
988
|
+
onKeyDown: onKeyDownProp,
|
|
989
|
+
"aria-label": ariaLabelProp,
|
|
990
|
+
"aria-labelledby": ariaLabelledbyProp,
|
|
915
991
|
...rest
|
|
916
992
|
}) {
|
|
917
993
|
const __twcStyles = useScopedStyles("twc-carousel-styles", CAROUSEL_CSS);
|
|
918
|
-
const slides =
|
|
994
|
+
const slides = React24__namespace.default.Children.toArray(children);
|
|
919
995
|
const count = slides.length;
|
|
920
|
-
const [internal, setInternal] =
|
|
996
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultIndex);
|
|
921
997
|
const index = indexProp !== void 0 ? indexProp : internal;
|
|
922
|
-
const [paused, setPaused] =
|
|
923
|
-
const
|
|
998
|
+
const [paused, setPaused] = React24__namespace.default.useState(false);
|
|
999
|
+
const [userPaused, setUserPaused] = React24__namespace.default.useState(false);
|
|
1000
|
+
const [prefersReduced, setPrefersReduced] = React24__namespace.default.useState(false);
|
|
1001
|
+
React24__namespace.default.useEffect(() => {
|
|
1002
|
+
if (typeof window === "undefined" || !window.matchMedia) return void 0;
|
|
1003
|
+
const mql = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
1004
|
+
const on = () => setPrefersReduced(mql.matches);
|
|
1005
|
+
on();
|
|
1006
|
+
mql.addEventListener("change", on);
|
|
1007
|
+
return () => mql.removeEventListener("change", on);
|
|
1008
|
+
}, []);
|
|
1009
|
+
const setIndex = React24__namespace.default.useCallback((i) => {
|
|
924
1010
|
if (indexProp === void 0) setInternal(i);
|
|
925
1011
|
onIndexChange?.(i);
|
|
926
1012
|
}, [indexProp, onIndexChange]);
|
|
927
|
-
const go =
|
|
1013
|
+
const go = React24__namespace.default.useCallback((i) => {
|
|
928
1014
|
setIndex(loop ? (i + count) % count : Math.min(Math.max(i, 0), count - 1));
|
|
929
1015
|
}, [count, loop, setIndex]);
|
|
930
|
-
|
|
931
|
-
|
|
1016
|
+
const autoRotating = autoPlay && !paused && !userPaused && !prefersReduced && count > 1;
|
|
1017
|
+
React24__namespace.default.useEffect(() => {
|
|
1018
|
+
if (!autoRotating) return void 0;
|
|
932
1019
|
const t = setInterval(() => {
|
|
933
1020
|
const next = loop ? (index + 1) % count : index + 1 >= count ? index : index + 1;
|
|
934
1021
|
if (next !== index) setIndex(next);
|
|
935
1022
|
}, interval);
|
|
936
1023
|
return () => clearInterval(t);
|
|
937
|
-
}, [
|
|
1024
|
+
}, [autoRotating, count, interval, loop, index, setIndex]);
|
|
938
1025
|
const atStart = !loop && index === 0;
|
|
939
1026
|
const atEnd = !loop && index === count - 1;
|
|
1027
|
+
const handleKeyDown = (e) => {
|
|
1028
|
+
onKeyDownProp?.(e);
|
|
1029
|
+
if (e.defaultPrevented) return;
|
|
1030
|
+
if (e.target.closest && e.target.closest('input, textarea, select, [contenteditable="true"]')) return;
|
|
1031
|
+
switch (e.key) {
|
|
1032
|
+
case "ArrowLeft":
|
|
1033
|
+
go(index - 1);
|
|
1034
|
+
break;
|
|
1035
|
+
case "ArrowRight":
|
|
1036
|
+
go(index + 1);
|
|
1037
|
+
break;
|
|
1038
|
+
case "Home":
|
|
1039
|
+
go(0);
|
|
1040
|
+
break;
|
|
1041
|
+
case "End":
|
|
1042
|
+
go(count - 1);
|
|
1043
|
+
break;
|
|
1044
|
+
default:
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
e.preventDefault();
|
|
1048
|
+
};
|
|
1049
|
+
const ariaLabel = ariaLabelledbyProp ? void 0 : ariaLabelProp ?? label ?? "Carousel";
|
|
940
1050
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
941
1051
|
"div",
|
|
942
1052
|
{
|
|
@@ -945,12 +1055,17 @@ function Carousel({
|
|
|
945
1055
|
onMouseLeave: () => setPaused(false),
|
|
946
1056
|
onFocusCapture: () => setPaused(true),
|
|
947
1057
|
onBlurCapture: () => setPaused(false),
|
|
1058
|
+
onKeyDown: handleKeyDown,
|
|
948
1059
|
role: "region",
|
|
949
1060
|
"aria-roledescription": "carousel",
|
|
1061
|
+
"aria-label": ariaLabel,
|
|
1062
|
+
"aria-labelledby": ariaLabelledbyProp,
|
|
950
1063
|
...rest,
|
|
951
1064
|
children: [
|
|
952
1065
|
__twcStyles,
|
|
953
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-carousel__viewport", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-carousel__track", style: { transform: `translateX(-${index * 100}%)` }, children: slides.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-carousel__slide", role: "group", "aria-roledescription": "slide", "aria-label": `${i + 1} of ${count}`, "aria-hidden": i !== index || void 0, inert: i !== index || void 0, children: s }, i)) }) }),
|
|
1066
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-carousel__viewport", tabIndex: 0, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-carousel__track", style: { transform: `translateX(-${index * 100}%)` }, children: slides.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-carousel__slide", role: "group", "aria-roledescription": "slide", "aria-label": `${i + 1} of ${count}`, "aria-hidden": i !== index || void 0, inert: i !== index || void 0, children: s }, i)) }) }),
|
|
1067
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-carousel__live", "aria-live": autoRotating ? "off" : "polite", "aria-atomic": "true", children: count > 1 ? `Slide ${index + 1} of ${count}` : null }),
|
|
1068
|
+
autoPlay && showPauseButton && count > 1 ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-carousel__pause", "aria-label": userPaused ? playLabel : pauseLabel, onClick: () => setUserPaused((v) => !v), children: userPaused ? /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 5v14l11-7z" }) }) : /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 5h4v14H6zM14 5h4v14h-4z" }) }) }) : null,
|
|
954
1069
|
showArrows && count > 1 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
955
1070
|
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-carousel__arrow", "data-dir": "prev", "aria-label": "Previous", disabled: atStart, onClick: () => go(index - 1), children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m15 18-6-6 6-6" }) }) }),
|
|
956
1071
|
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-carousel__arrow", "data-dir": "next", "aria-label": "Next", disabled: atEnd, onClick: () => go(index + 1), children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" }) }) })
|
|
@@ -973,6 +1088,7 @@ var CHART_CSS = `
|
|
|
973
1088
|
.twc-chart__leg { display: inline-flex; align-items: center; gap: 6px; }
|
|
974
1089
|
.twc-chart__leg-sw { width: 10px; height: 10px; border-radius: 3px; }
|
|
975
1090
|
@keyframes twc-chart-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }
|
|
1091
|
+
.twc-chart__sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
976
1092
|
`;
|
|
977
1093
|
var SERIES_COLORS = ["var(--brand-500)", "var(--sky-500)", "var(--emerald-500)", "var(--amber-500)", "var(--rose-500)"];
|
|
978
1094
|
function Chart({
|
|
@@ -987,10 +1103,14 @@ function Chart({
|
|
|
987
1103
|
valueFormat,
|
|
988
1104
|
ariaLabel,
|
|
989
1105
|
"aria-label": ariaLabelProp,
|
|
1106
|
+
tableFallback = true,
|
|
1107
|
+
caption,
|
|
990
1108
|
className = "",
|
|
991
1109
|
...rest
|
|
992
1110
|
}) {
|
|
993
1111
|
const __twcStyles = useScopedStyles("twc-chart-styles", CHART_CSS);
|
|
1112
|
+
const uid = React24__namespace.default.useId();
|
|
1113
|
+
const tableId = tableFallback ? `${uid}-table` : void 0;
|
|
994
1114
|
const keys = series || ["value"];
|
|
995
1115
|
const palette = colors && colors.length ? colors : SERIES_COLORS;
|
|
996
1116
|
const W = 600, H = height, padL = showAxis ? 40 : 8, padR = 8, padT = 12, padB = showAxis ? 26 : 8;
|
|
@@ -1003,7 +1123,7 @@ function Chart({
|
|
|
1003
1123
|
const svgAriaLabel = ariaLabelProp ?? ariaLabel ?? `${type} chart`;
|
|
1004
1124
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-chart ${className}`, ...rest, children: [
|
|
1005
1125
|
__twcStyles,
|
|
1006
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: `0 0 ${W} ${H}`, role: "img", "aria-label": svgAriaLabel, preserveAspectRatio: "none", children: [
|
|
1126
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: `0 0 ${W} ${H}`, role: "img", "aria-label": svgAriaLabel, "aria-describedby": tableId, preserveAspectRatio: "none", children: [
|
|
1007
1127
|
showGrid ? Array.from({ length: ticks + 1 }).map((_, i) => {
|
|
1008
1128
|
const gy = padT + innerH / ticks * i;
|
|
1009
1129
|
return /* @__PURE__ */ jsxRuntime.jsx("line", { className: "twc-chart__grid", x1: padL, y1: gy, x2: W - padR, y2: gy }, i);
|
|
@@ -1053,6 +1173,17 @@ function Chart({
|
|
|
1053
1173
|
return /* @__PURE__ */ jsxRuntime.jsx("text", { className: "twc-chart__axis", x: cx, y: H - 8, textAnchor: "middle", children: d.label }, i);
|
|
1054
1174
|
}) : null
|
|
1055
1175
|
] }),
|
|
1176
|
+
tableFallback ? /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "twc-chart__sr", id: tableId, children: [
|
|
1177
|
+
/* @__PURE__ */ jsxRuntime.jsx("caption", { children: caption ?? svgAriaLabel }),
|
|
1178
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1179
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col" }),
|
|
1180
|
+
keys.map((k) => /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: k }, k))
|
|
1181
|
+
] }) }),
|
|
1182
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: data.map((d, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1183
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "row", children: d.label }),
|
|
1184
|
+
keys.map((k) => /* @__PURE__ */ jsxRuntime.jsx("td", { children: fmt(Number(d[k]) || 0) }, k))
|
|
1185
|
+
] }, i)) })
|
|
1186
|
+
] }) : null,
|
|
1056
1187
|
showLegend && keys.length > 1 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-chart__legend", children: keys.map((k, si) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-chart__leg", children: [
|
|
1057
1188
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-chart__leg-sw", style: { background: palette[si % palette.length] } }),
|
|
1058
1189
|
k
|
|
@@ -1125,12 +1256,12 @@ function Checkbox({
|
|
|
1125
1256
|
.twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
|
|
1126
1257
|
.twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
|
|
1127
1258
|
`);
|
|
1128
|
-
const autoId =
|
|
1259
|
+
const autoId = React24__namespace.default.useId();
|
|
1129
1260
|
const fieldId = id || autoId;
|
|
1130
1261
|
const errId = `${fieldId}-error`;
|
|
1131
1262
|
const invalid = Boolean(error);
|
|
1132
|
-
const ref =
|
|
1133
|
-
|
|
1263
|
+
const ref = React24__namespace.default.useRef(null);
|
|
1264
|
+
React24__namespace.default.useEffect(() => {
|
|
1134
1265
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
1135
1266
|
}, [indeterminate]);
|
|
1136
1267
|
const describedBy = [rest["aria-describedby"], error ? errId : null].filter(Boolean).join(" ") || void 0;
|
|
@@ -1267,20 +1398,20 @@ function ColorPicker({
|
|
|
1267
1398
|
}) {
|
|
1268
1399
|
const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS);
|
|
1269
1400
|
const __twcStyles1 = useScopedStyles("twc-colorpicker-styles", COLORPICKER_CSS);
|
|
1270
|
-
const [internal, setInternal] =
|
|
1401
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
1271
1402
|
const hex = (value !== void 0 ? value : internal) || "#000000";
|
|
1272
|
-
const lastValidRef =
|
|
1403
|
+
const lastValidRef = React24__namespace.default.useRef(hex);
|
|
1273
1404
|
if (/^#[0-9a-f]{6}$/i.test(hex)) lastValidRef.current = hex;
|
|
1274
|
-
const [open, setOpen] =
|
|
1275
|
-
const [hsv, setHsv] =
|
|
1276
|
-
const [coords, setCoords] =
|
|
1277
|
-
const wrapRef =
|
|
1278
|
-
const triggerRef =
|
|
1279
|
-
const popRef =
|
|
1280
|
-
const areaRef =
|
|
1281
|
-
const hueRef =
|
|
1405
|
+
const [open, setOpen] = React24__namespace.default.useState(false);
|
|
1406
|
+
const [hsv, setHsv] = React24__namespace.default.useState(() => hexToHsv(hex) || { h: 239, s: 60, v: 94 });
|
|
1407
|
+
const [coords, setCoords] = React24__namespace.default.useState(null);
|
|
1408
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
1409
|
+
const triggerRef = React24__namespace.default.useRef(null);
|
|
1410
|
+
const popRef = React24__namespace.default.useRef(null);
|
|
1411
|
+
const areaRef = React24__namespace.default.useRef(null);
|
|
1412
|
+
const hueRef = React24__namespace.default.useRef(null);
|
|
1282
1413
|
const POP_W = 240;
|
|
1283
|
-
const place =
|
|
1414
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
1284
1415
|
const el = triggerRef.current;
|
|
1285
1416
|
if (!el) return;
|
|
1286
1417
|
const r = el.getBoundingClientRect();
|
|
@@ -1291,7 +1422,7 @@ function ColorPicker({
|
|
|
1291
1422
|
left = Math.max(8, left);
|
|
1292
1423
|
setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
|
|
1293
1424
|
}, []);
|
|
1294
|
-
|
|
1425
|
+
React24__namespace.default.useEffect(() => {
|
|
1295
1426
|
if (!open) return void 0;
|
|
1296
1427
|
place();
|
|
1297
1428
|
const onMove = () => place();
|
|
@@ -1302,17 +1433,17 @@ function ColorPicker({
|
|
|
1302
1433
|
window.removeEventListener("resize", onMove);
|
|
1303
1434
|
};
|
|
1304
1435
|
}, [open, place]);
|
|
1305
|
-
const labelId =
|
|
1436
|
+
const labelId = React24__namespace.default.useId();
|
|
1306
1437
|
const descId = `${labelId}-desc`;
|
|
1307
1438
|
const invalid = Boolean(error);
|
|
1308
|
-
|
|
1439
|
+
React24__namespace.default.useEffect(() => {
|
|
1309
1440
|
if (disabled) setOpen(false);
|
|
1310
1441
|
}, [disabled]);
|
|
1311
|
-
|
|
1442
|
+
React24__namespace.default.useEffect(() => {
|
|
1312
1443
|
const v = hexToHsv(hex);
|
|
1313
1444
|
if (v && hsvToHex(v.h, v.s, v.v).toLowerCase() !== hsvToHex(hsv.h, hsv.s, hsv.v).toLowerCase()) setHsv(v);
|
|
1314
1445
|
}, [hex]);
|
|
1315
|
-
|
|
1446
|
+
React24__namespace.default.useEffect(() => {
|
|
1316
1447
|
if (!open) return;
|
|
1317
1448
|
const onDown = (e) => {
|
|
1318
1449
|
if (wrapRef.current && wrapRef.current.contains(e.target)) return;
|
|
@@ -1329,8 +1460,8 @@ function ColorPicker({
|
|
|
1329
1460
|
document.removeEventListener("keydown", onKey);
|
|
1330
1461
|
};
|
|
1331
1462
|
}, [open]);
|
|
1332
|
-
const prevOpen =
|
|
1333
|
-
|
|
1463
|
+
const prevOpen = React24__namespace.default.useRef(false);
|
|
1464
|
+
React24__namespace.default.useEffect(() => {
|
|
1334
1465
|
let id;
|
|
1335
1466
|
if (!prevOpen.current && open) {
|
|
1336
1467
|
id = setTimeout(() => areaRef.current?.focus({ preventScroll: true }), 20);
|
|
@@ -1650,29 +1781,29 @@ function Combobox({
|
|
|
1650
1781
|
...rest
|
|
1651
1782
|
}) {
|
|
1652
1783
|
const __twcStyles = useScopedStyles("twc-combo-styles", COMBO_CSS);
|
|
1653
|
-
const groups =
|
|
1654
|
-
const flat =
|
|
1655
|
-
const autoId =
|
|
1784
|
+
const groups = React24__namespace.default.useMemo(() => normalizeGroups(options), [options]);
|
|
1785
|
+
const flat = React24__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
|
|
1786
|
+
const autoId = React24__namespace.default.useId();
|
|
1656
1787
|
const fieldId = id || autoId;
|
|
1657
|
-
const [internal, setInternal] =
|
|
1788
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
1658
1789
|
const current = value !== void 0 ? value : internal;
|
|
1659
1790
|
const selected = flat.find((o) => o.value === current);
|
|
1660
|
-
const [open, setOpen] =
|
|
1661
|
-
const [query, setQuery] =
|
|
1662
|
-
const [active, setActive] =
|
|
1663
|
-
const [coords, setCoords] =
|
|
1664
|
-
const wrapRef =
|
|
1665
|
-
const controlRef =
|
|
1666
|
-
const inputRef =
|
|
1667
|
-
const popRef =
|
|
1668
|
-
const listRef =
|
|
1669
|
-
const activeRef =
|
|
1670
|
-
const fGroups =
|
|
1791
|
+
const [open, setOpen] = React24__namespace.default.useState(false);
|
|
1792
|
+
const [query, setQuery] = React24__namespace.default.useState("");
|
|
1793
|
+
const [active, setActive] = React24__namespace.default.useState(0);
|
|
1794
|
+
const [coords, setCoords] = React24__namespace.default.useState(null);
|
|
1795
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
1796
|
+
const controlRef = React24__namespace.default.useRef(null);
|
|
1797
|
+
const inputRef = React24__namespace.default.useRef(null);
|
|
1798
|
+
const popRef = React24__namespace.default.useRef(null);
|
|
1799
|
+
const listRef = React24__namespace.default.useRef(null);
|
|
1800
|
+
const activeRef = React24__namespace.default.useRef(null);
|
|
1801
|
+
const fGroups = React24__namespace.default.useMemo(
|
|
1671
1802
|
() => groups.map((g) => ({ group: g.group, options: g.options.filter((o) => matches(o, query.trim())) })).filter((g) => g.options.length),
|
|
1672
1803
|
[groups, query]
|
|
1673
1804
|
);
|
|
1674
|
-
const visible =
|
|
1675
|
-
const place =
|
|
1805
|
+
const visible = React24__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
|
|
1806
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
1676
1807
|
const el = controlRef.current;
|
|
1677
1808
|
if (!el) return;
|
|
1678
1809
|
const r = el.getBoundingClientRect();
|
|
@@ -1687,7 +1818,7 @@ function Combobox({
|
|
|
1687
1818
|
flip
|
|
1688
1819
|
});
|
|
1689
1820
|
}, [placement, minWidth]);
|
|
1690
|
-
|
|
1821
|
+
React24__namespace.default.useEffect(() => {
|
|
1691
1822
|
if (!open || !portal) return;
|
|
1692
1823
|
place();
|
|
1693
1824
|
const onMove = () => place();
|
|
@@ -1698,7 +1829,7 @@ function Combobox({
|
|
|
1698
1829
|
window.removeEventListener("resize", onMove);
|
|
1699
1830
|
};
|
|
1700
1831
|
}, [open, portal, place]);
|
|
1701
|
-
|
|
1832
|
+
React24__namespace.default.useEffect(() => {
|
|
1702
1833
|
if (!open) return;
|
|
1703
1834
|
const onDown = (e) => {
|
|
1704
1835
|
if (wrapRef.current && wrapRef.current.contains(e.target)) return;
|
|
@@ -1708,10 +1839,10 @@ function Combobox({
|
|
|
1708
1839
|
document.addEventListener("mousedown", onDown);
|
|
1709
1840
|
return () => document.removeEventListener("mousedown", onDown);
|
|
1710
1841
|
}, [open]);
|
|
1711
|
-
|
|
1842
|
+
React24__namespace.default.useEffect(() => {
|
|
1712
1843
|
setActive(0);
|
|
1713
1844
|
}, [query]);
|
|
1714
|
-
|
|
1845
|
+
React24__namespace.default.useEffect(() => {
|
|
1715
1846
|
if (open) ensureVisible(listRef.current, activeRef.current);
|
|
1716
1847
|
}, [active, open]);
|
|
1717
1848
|
function openMenu() {
|
|
@@ -1754,7 +1885,7 @@ function Combobox({
|
|
|
1754
1885
|
const descId = `${fieldId}-desc`;
|
|
1755
1886
|
const describedBy = error || hint ? descId : void 0;
|
|
1756
1887
|
let counter = -1;
|
|
1757
|
-
const popInner = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: "No results found" }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1888
|
+
const popInner = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: "No results found" }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React24__namespace.default.Fragment, { children: [
|
|
1758
1889
|
g.group ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: g.group }) : null,
|
|
1759
1890
|
g.options.map((o) => {
|
|
1760
1891
|
counter += 1;
|
|
@@ -1892,6 +2023,52 @@ function Combobox({
|
|
|
1892
2023
|
error ? /* @__PURE__ */ jsxRuntime.jsx("span", { id: descId, className: "twc-field__error", children: error }) : hint ? /* @__PURE__ */ jsxRuntime.jsx("span", { id: descId, className: "twc-field__hint", children: hint }) : null
|
|
1893
2024
|
] });
|
|
1894
2025
|
}
|
|
2026
|
+
var canUseDOM = typeof window !== "undefined" && typeof document !== "undefined";
|
|
2027
|
+
var FOCUSABLE = 'a[href]:not([tabindex="-1"]), button:not([disabled]):not([tabindex="-1"]), textarea:not([disabled]):not([tabindex="-1"]), input:not([disabled]):not([tabindex="-1"]), select:not([disabled]):not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])';
|
|
2028
|
+
function useFocusTrap(ref, active = true, { restoreFocus = true } = {}) {
|
|
2029
|
+
React24__namespace.default.useEffect(() => {
|
|
2030
|
+
if (!active || !canUseDOM) return void 0;
|
|
2031
|
+
const node = ref.current;
|
|
2032
|
+
if (!node) return void 0;
|
|
2033
|
+
const prevFocused = document.activeElement;
|
|
2034
|
+
const first = node.querySelector(FOCUSABLE);
|
|
2035
|
+
(first || node).focus();
|
|
2036
|
+
return () => {
|
|
2037
|
+
if (restoreFocus && prevFocused && typeof prevFocused.focus === "function") prevFocused.focus();
|
|
2038
|
+
};
|
|
2039
|
+
}, [active]);
|
|
2040
|
+
React24__namespace.default.useEffect(() => {
|
|
2041
|
+
if (!active || !canUseDOM) return void 0;
|
|
2042
|
+
const node = ref.current;
|
|
2043
|
+
const onKey = (e) => {
|
|
2044
|
+
if (e.key !== "Tab" || !node) return;
|
|
2045
|
+
const f = Array.from(node.querySelectorAll(FOCUSABLE)).filter((el) => el.offsetParent !== null);
|
|
2046
|
+
if (!f.length) {
|
|
2047
|
+
e.preventDefault();
|
|
2048
|
+
node.focus();
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
const first = f[0], last = f[f.length - 1], ae = document.activeElement;
|
|
2052
|
+
if (e.shiftKey) {
|
|
2053
|
+
if (ae === first || ae === node || !node.contains(ae)) {
|
|
2054
|
+
e.preventDefault();
|
|
2055
|
+
last.focus();
|
|
2056
|
+
}
|
|
2057
|
+
} else if (ae === last || !node.contains(ae)) {
|
|
2058
|
+
e.preventDefault();
|
|
2059
|
+
first.focus();
|
|
2060
|
+
}
|
|
2061
|
+
};
|
|
2062
|
+
document.addEventListener("keydown", onKey);
|
|
2063
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
2064
|
+
}, [active]);
|
|
2065
|
+
}
|
|
2066
|
+
function usePortal() {
|
|
2067
|
+
return React24__namespace.default.useCallback((node) => {
|
|
2068
|
+
if (typeof document === "undefined") return null;
|
|
2069
|
+
return typeof reactDom.createPortal === "function" ? reactDom.createPortal(node, document.body) : node;
|
|
2070
|
+
}, []);
|
|
2071
|
+
}
|
|
1895
2072
|
var COMMAND_CSS = `
|
|
1896
2073
|
.twc-cmdk__overlay { position: fixed; inset: 0; z-index: var(--z-modal); background: var(--color-overlay); backdrop-filter: blur(3px);
|
|
1897
2074
|
display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; }
|
|
@@ -1937,14 +2114,15 @@ function CommandPalette({
|
|
|
1937
2114
|
...rest
|
|
1938
2115
|
}) {
|
|
1939
2116
|
const __twcStyles = useScopedStyles("twc-cmdk-styles", COMMAND_CSS);
|
|
1940
|
-
const
|
|
1941
|
-
const [
|
|
1942
|
-
const
|
|
1943
|
-
const
|
|
1944
|
-
const
|
|
1945
|
-
const
|
|
1946
|
-
const
|
|
1947
|
-
|
|
2117
|
+
const renderPortal = usePortal();
|
|
2118
|
+
const [query, setQuery] = React24__namespace.default.useState("");
|
|
2119
|
+
const [active, setActive] = React24__namespace.default.useState(0);
|
|
2120
|
+
const inputRef = React24__namespace.default.useRef(null);
|
|
2121
|
+
const listRef = React24__namespace.default.useRef(null);
|
|
2122
|
+
const paletteRef = React24__namespace.default.useRef(null);
|
|
2123
|
+
const baseId = React24__namespace.default.useId();
|
|
2124
|
+
const [mounted, setMounted] = React24__namespace.default.useState(open);
|
|
2125
|
+
React24__namespace.default.useEffect(() => {
|
|
1948
2126
|
if (open) {
|
|
1949
2127
|
setMounted(true);
|
|
1950
2128
|
return;
|
|
@@ -1952,7 +2130,7 @@ function CommandPalette({
|
|
|
1952
2130
|
const t = setTimeout(() => setMounted(false), 170);
|
|
1953
2131
|
return () => clearTimeout(t);
|
|
1954
2132
|
}, [open]);
|
|
1955
|
-
|
|
2133
|
+
React24__namespace.default.useEffect(() => {
|
|
1956
2134
|
if (!open) return void 0;
|
|
1957
2135
|
const prev = document.body.style.overflow;
|
|
1958
2136
|
document.body.style.overflow = "hidden";
|
|
@@ -1960,58 +2138,26 @@ function CommandPalette({
|
|
|
1960
2138
|
document.body.style.overflow = prev;
|
|
1961
2139
|
};
|
|
1962
2140
|
}, [open]);
|
|
1963
|
-
|
|
2141
|
+
React24__namespace.default.useEffect(() => {
|
|
1964
2142
|
if (open) {
|
|
1965
2143
|
setQuery("");
|
|
1966
2144
|
setActive(0);
|
|
1967
|
-
const t = setTimeout(() => inputRef.current?.focus(), 30);
|
|
1968
|
-
return () => clearTimeout(t);
|
|
1969
2145
|
}
|
|
1970
2146
|
}, [open]);
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
return () => {
|
|
1975
|
-
if (prevFocused && typeof prevFocused.focus === "function") prevFocused.focus();
|
|
1976
|
-
};
|
|
1977
|
-
}, [open]);
|
|
1978
|
-
React23__namespace.default.useEffect(() => {
|
|
1979
|
-
if (!open) return;
|
|
1980
|
-
const focusables = (node) => node ? Array.from(
|
|
1981
|
-
node.querySelectorAll(
|
|
1982
|
-
'a[href]:not([tabindex="-1"]), button:not([disabled]):not([tabindex="-1"]), textarea:not([disabled]):not([tabindex="-1"]), input:not([disabled]):not([tabindex="-1"]), select:not([disabled]):not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])'
|
|
1983
|
-
)
|
|
1984
|
-
).filter((el) => el.offsetParent !== null) : [];
|
|
2147
|
+
useFocusTrap(paletteRef, open && mounted);
|
|
2148
|
+
React24__namespace.default.useEffect(() => {
|
|
2149
|
+
if (!open) return void 0;
|
|
1985
2150
|
const onKey = (e) => {
|
|
1986
2151
|
if (e.key === "Escape") {
|
|
1987
2152
|
e.preventDefault();
|
|
1988
2153
|
onClose?.();
|
|
1989
|
-
return;
|
|
1990
|
-
}
|
|
1991
|
-
if (e.key !== "Tab") return;
|
|
1992
|
-
const node = paletteRef.current;
|
|
1993
|
-
const f = focusables(node);
|
|
1994
|
-
if (!f.length) {
|
|
1995
|
-
e.preventDefault();
|
|
1996
|
-
node?.focus();
|
|
1997
|
-
return;
|
|
1998
|
-
}
|
|
1999
|
-
const first = f[0], last = f[f.length - 1], ae = document.activeElement;
|
|
2000
|
-
if (e.shiftKey) {
|
|
2001
|
-
if (ae === first || ae === node || !node.contains(ae)) {
|
|
2002
|
-
e.preventDefault();
|
|
2003
|
-
last.focus();
|
|
2004
|
-
}
|
|
2005
|
-
} else if (ae === last || !node.contains(ae)) {
|
|
2006
|
-
e.preventDefault();
|
|
2007
|
-
first.focus();
|
|
2008
2154
|
}
|
|
2009
2155
|
};
|
|
2010
2156
|
document.addEventListener("keydown", onKey);
|
|
2011
2157
|
return () => document.removeEventListener("keydown", onKey);
|
|
2012
2158
|
}, [open, onClose]);
|
|
2013
2159
|
const q = query.trim().toLowerCase();
|
|
2014
|
-
const filtered =
|
|
2160
|
+
const filtered = React24__namespace.default.useMemo(() => commands.filter(
|
|
2015
2161
|
(c) => !q || c.label.toLowerCase().includes(q) || (c.keywords || "").toLowerCase().includes(q) || (c.group || "").toLowerCase().includes(q)
|
|
2016
2162
|
), [commands, q]);
|
|
2017
2163
|
const groups = [];
|
|
@@ -2026,7 +2172,7 @@ function CommandPalette({
|
|
|
2026
2172
|
g.items.push(c);
|
|
2027
2173
|
flat.push(c);
|
|
2028
2174
|
});
|
|
2029
|
-
|
|
2175
|
+
React24__namespace.default.useEffect(() => {
|
|
2030
2176
|
setActive(0);
|
|
2031
2177
|
}, [query]);
|
|
2032
2178
|
const run = (cmd) => {
|
|
@@ -2046,11 +2192,11 @@ function CommandPalette({
|
|
|
2046
2192
|
if (cmd) run(cmd);
|
|
2047
2193
|
}
|
|
2048
2194
|
}
|
|
2049
|
-
|
|
2195
|
+
React24__namespace.default.useEffect(() => {
|
|
2050
2196
|
const node = listRef.current?.querySelector('[data-active="true"]');
|
|
2051
2197
|
if (node) node.scrollIntoView({ block: "nearest" });
|
|
2052
2198
|
}, [active]);
|
|
2053
|
-
if (!mounted
|
|
2199
|
+
if (!mounted) return null;
|
|
2054
2200
|
const state = open ? "open" : "closed";
|
|
2055
2201
|
const listId = `${baseId}-list`;
|
|
2056
2202
|
const optionId = (i) => `${baseId}-opt-${i}`;
|
|
@@ -2116,8 +2262,7 @@ function CommandPalette({
|
|
|
2116
2262
|
] }, g.key || "_")) })
|
|
2117
2263
|
] })
|
|
2118
2264
|
] });
|
|
2119
|
-
|
|
2120
|
-
return RD ? RD(overlay, document.body) : overlay;
|
|
2265
|
+
return renderPortal(overlay);
|
|
2121
2266
|
}
|
|
2122
2267
|
var CURRENCIES = {
|
|
2123
2268
|
USD: { code: "USD", symbol: "$", precision: 2, label: "US Dollar" },
|
|
@@ -2220,11 +2365,11 @@ function Currency({
|
|
|
2220
2365
|
const prec = precision != null ? precision : meta.precision;
|
|
2221
2366
|
const sym = symbol != null ? symbol : meta.symbol;
|
|
2222
2367
|
const cur = code != null ? code : meta.code;
|
|
2223
|
-
const autoId =
|
|
2368
|
+
const autoId = React24__namespace.default.useId();
|
|
2224
2369
|
const fieldId = id || autoId;
|
|
2225
2370
|
const invalid = Boolean(error);
|
|
2226
2371
|
const controlled = value !== void 0;
|
|
2227
|
-
const [internal, setInternal] =
|
|
2372
|
+
const [internal, setInternal] = React24__namespace.default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
|
|
2228
2373
|
const shown = controlled ? clampPrecision(String(value ?? ""), prec) : internal;
|
|
2229
2374
|
const describedBy = [error ? `${fieldId}-error` : hint ? `${fieldId}-hint` : null, rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
|
|
2230
2375
|
function handleChange(e) {
|
|
@@ -2398,32 +2543,32 @@ function Select({
|
|
|
2398
2543
|
...rest
|
|
2399
2544
|
}) {
|
|
2400
2545
|
const __twcStyles = useScopedStyles("twc-select-styles", SELECT_CSS);
|
|
2401
|
-
const groups =
|
|
2402
|
-
const flat =
|
|
2403
|
-
const autoId =
|
|
2546
|
+
const groups = React24__namespace.default.useMemo(() => normalizeGroups2(options), [options]);
|
|
2547
|
+
const flat = React24__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
|
|
2548
|
+
const autoId = React24__namespace.default.useId();
|
|
2404
2549
|
const fieldId = id || autoId;
|
|
2405
|
-
const [internal, setInternal] =
|
|
2550
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
2406
2551
|
const current = value !== void 0 ? value : internal;
|
|
2407
|
-
const [open, setOpen] =
|
|
2408
|
-
const [render, setRender] =
|
|
2409
|
-
const [active, setActive] =
|
|
2410
|
-
const [coords, setCoords] =
|
|
2411
|
-
const [query, setQuery] =
|
|
2412
|
-
const wrapRef =
|
|
2413
|
-
const triggerRef =
|
|
2414
|
-
const popRef =
|
|
2415
|
-
const listRef =
|
|
2416
|
-
const activeRef =
|
|
2417
|
-
const searchRef =
|
|
2552
|
+
const [open, setOpen] = React24__namespace.default.useState(false);
|
|
2553
|
+
const [render, setRender] = React24__namespace.default.useState(false);
|
|
2554
|
+
const [active, setActive] = React24__namespace.default.useState(0);
|
|
2555
|
+
const [coords, setCoords] = React24__namespace.default.useState(null);
|
|
2556
|
+
const [query, setQuery] = React24__namespace.default.useState("");
|
|
2557
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
2558
|
+
const triggerRef = React24__namespace.default.useRef(null);
|
|
2559
|
+
const popRef = React24__namespace.default.useRef(null);
|
|
2560
|
+
const listRef = React24__namespace.default.useRef(null);
|
|
2561
|
+
const activeRef = React24__namespace.default.useRef(null);
|
|
2562
|
+
const searchRef = React24__namespace.default.useRef(null);
|
|
2418
2563
|
const showSearch = searchable === void 0 ? flat.length > 5 : searchable;
|
|
2419
|
-
const fGroups =
|
|
2564
|
+
const fGroups = React24__namespace.default.useMemo(() => {
|
|
2420
2565
|
const q = query.trim().toLowerCase();
|
|
2421
2566
|
if (!q) return groups;
|
|
2422
2567
|
return groups.map((g) => ({ group: g.group, options: g.options.filter((o) => o.label.toLowerCase().includes(q) || o.description && o.description.toLowerCase().includes(q)) })).filter((g) => g.options.length);
|
|
2423
2568
|
}, [groups, query]);
|
|
2424
|
-
const visible =
|
|
2569
|
+
const visible = React24__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
|
|
2425
2570
|
const selected = flat.find((o) => o.value === current);
|
|
2426
|
-
const place =
|
|
2571
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
2427
2572
|
const el = triggerRef.current;
|
|
2428
2573
|
if (!el) return;
|
|
2429
2574
|
const r = el.getBoundingClientRect();
|
|
@@ -2438,7 +2583,7 @@ function Select({
|
|
|
2438
2583
|
flip
|
|
2439
2584
|
});
|
|
2440
2585
|
}, [placement, minWidth]);
|
|
2441
|
-
|
|
2586
|
+
React24__namespace.default.useEffect(() => {
|
|
2442
2587
|
if (!open || !portal) return;
|
|
2443
2588
|
place();
|
|
2444
2589
|
const onMove = () => place();
|
|
@@ -2449,7 +2594,7 @@ function Select({
|
|
|
2449
2594
|
window.removeEventListener("resize", onMove);
|
|
2450
2595
|
};
|
|
2451
2596
|
}, [open, portal, place]);
|
|
2452
|
-
|
|
2597
|
+
React24__namespace.default.useEffect(() => {
|
|
2453
2598
|
if (!open) return;
|
|
2454
2599
|
const idx = flat.findIndex((o) => o.value === current);
|
|
2455
2600
|
setActive(idx >= 0 ? idx : 0);
|
|
@@ -2465,13 +2610,13 @@ function Select({
|
|
|
2465
2610
|
document.addEventListener("mousedown", onDown);
|
|
2466
2611
|
return () => document.removeEventListener("mousedown", onDown);
|
|
2467
2612
|
}, [open]);
|
|
2468
|
-
|
|
2613
|
+
React24__namespace.default.useEffect(() => {
|
|
2469
2614
|
setActive(0);
|
|
2470
2615
|
}, [query]);
|
|
2471
|
-
|
|
2616
|
+
React24__namespace.default.useEffect(() => {
|
|
2472
2617
|
if (open) ensureVisible2(listRef.current, activeRef.current);
|
|
2473
2618
|
}, [active, open]);
|
|
2474
|
-
|
|
2619
|
+
React24__namespace.default.useEffect(() => {
|
|
2475
2620
|
if (open) {
|
|
2476
2621
|
setRender(true);
|
|
2477
2622
|
return;
|
|
@@ -2479,8 +2624,8 @@ function Select({
|
|
|
2479
2624
|
const t = setTimeout(() => setRender(false), 170);
|
|
2480
2625
|
return () => clearTimeout(t);
|
|
2481
2626
|
}, [open]);
|
|
2482
|
-
const prevOpen =
|
|
2483
|
-
|
|
2627
|
+
const prevOpen = React24__namespace.default.useRef(false);
|
|
2628
|
+
React24__namespace.default.useEffect(() => {
|
|
2484
2629
|
if (prevOpen.current && !open) {
|
|
2485
2630
|
const ae = typeof document !== "undefined" ? document.activeElement : null;
|
|
2486
2631
|
if (popRef.current && ae && popRef.current.contains(ae)) triggerRef.current?.focus();
|
|
@@ -2553,7 +2698,7 @@ function Select({
|
|
|
2553
2698
|
}
|
|
2554
2699
|
)
|
|
2555
2700
|
] }) : null,
|
|
2556
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: "No results found" }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2701
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: "No results found" }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React24__namespace.default.Fragment, { children: [
|
|
2557
2702
|
g.group ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: g.group }) : null,
|
|
2558
2703
|
g.options.map((o) => {
|
|
2559
2704
|
counter += 1;
|
|
@@ -2727,19 +2872,19 @@ function CurrencyField({
|
|
|
2727
2872
|
...rest
|
|
2728
2873
|
}) {
|
|
2729
2874
|
const __twcStyles = useScopedStyles("twc-curf-styles", CURF_CSS);
|
|
2730
|
-
const autoId =
|
|
2875
|
+
const autoId = React24__namespace.default.useId();
|
|
2731
2876
|
const fieldId = id || autoId;
|
|
2732
2877
|
const invalid = Boolean(error);
|
|
2733
2878
|
const curControlled = currency !== void 0;
|
|
2734
|
-
const [curInternal, setCurInternal] =
|
|
2879
|
+
const [curInternal, setCurInternal] = React24__namespace.default.useState(defaultCurrency);
|
|
2735
2880
|
const cur = curControlled ? currency : curInternal;
|
|
2736
2881
|
const meta = CURRENCIES[cur] || CURRENCIES.USD;
|
|
2737
2882
|
const prec = meta.precision;
|
|
2738
2883
|
const valControlled = value !== void 0;
|
|
2739
|
-
const [valInternal, setValInternal] =
|
|
2884
|
+
const [valInternal, setValInternal] = React24__namespace.default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
|
|
2740
2885
|
const shown = valControlled ? clampPrecision(String(value ?? ""), prec) : valInternal;
|
|
2741
2886
|
const describedBy = [error ? `${fieldId}-error` : hint ? `${fieldId}-hint` : null, rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
|
|
2742
|
-
const options =
|
|
2887
|
+
const options = React24__namespace.default.useMemo(() => {
|
|
2743
2888
|
if (!currencies) return CURRENCY_OPTIONS;
|
|
2744
2889
|
return currencies.map((c) => typeof c === "string" ? { value: c, label: `${c} \u2014 ${(CURRENCIES[c] || {}).label || c}` } : c);
|
|
2745
2890
|
}, [currencies]);
|
|
@@ -2874,12 +3019,12 @@ function Input({
|
|
|
2874
3019
|
...rest
|
|
2875
3020
|
}) {
|
|
2876
3021
|
const __twcStyles = useScopedStyles("twc-field-styles", FIELD_CSS2);
|
|
2877
|
-
const autoId =
|
|
3022
|
+
const autoId = React24__namespace.default.useId();
|
|
2878
3023
|
const fieldId = id || autoId;
|
|
2879
3024
|
const descId = `${fieldId}-desc`;
|
|
2880
3025
|
const invalid = Boolean(error);
|
|
2881
3026
|
const isPassword = type === "password";
|
|
2882
|
-
const [revealed, setRevealed] =
|
|
3027
|
+
const [revealed, setRevealed] = React24__namespace.default.useState(false);
|
|
2883
3028
|
const effectiveType = isPassword && revealed ? "text" : type;
|
|
2884
3029
|
const suffix = rightIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-input__affix", children: rightIcon }) : isPassword ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2885
3030
|
"button",
|
|
@@ -3060,28 +3205,28 @@ function MultiSelect({
|
|
|
3060
3205
|
...rest
|
|
3061
3206
|
}) {
|
|
3062
3207
|
const __twcStyles = useScopedStyles("twc-ms-styles", MULTI_CSS);
|
|
3063
|
-
const groups =
|
|
3064
|
-
const flat =
|
|
3065
|
-
const autoId =
|
|
3208
|
+
const groups = React24__namespace.default.useMemo(() => normalizeGroups3(options), [options]);
|
|
3209
|
+
const flat = React24__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
|
|
3210
|
+
const autoId = React24__namespace.default.useId();
|
|
3066
3211
|
const fieldId = id || autoId;
|
|
3067
|
-
const [internal, setInternal] =
|
|
3212
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
3068
3213
|
const selected = value !== void 0 ? value : internal;
|
|
3069
|
-
const [open, setOpen] =
|
|
3070
|
-
const [query, setQuery] =
|
|
3071
|
-
const [active, setActive] =
|
|
3072
|
-
const [coords, setCoords] =
|
|
3073
|
-
const wrapRef =
|
|
3074
|
-
const controlRef =
|
|
3075
|
-
const inputRef =
|
|
3076
|
-
const popRef =
|
|
3077
|
-
const listRef =
|
|
3078
|
-
const activeRef =
|
|
3079
|
-
const fGroups =
|
|
3214
|
+
const [open, setOpen] = React24__namespace.default.useState(false);
|
|
3215
|
+
const [query, setQuery] = React24__namespace.default.useState("");
|
|
3216
|
+
const [active, setActive] = React24__namespace.default.useState(0);
|
|
3217
|
+
const [coords, setCoords] = React24__namespace.default.useState(null);
|
|
3218
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
3219
|
+
const controlRef = React24__namespace.default.useRef(null);
|
|
3220
|
+
const inputRef = React24__namespace.default.useRef(null);
|
|
3221
|
+
const popRef = React24__namespace.default.useRef(null);
|
|
3222
|
+
const listRef = React24__namespace.default.useRef(null);
|
|
3223
|
+
const activeRef = React24__namespace.default.useRef(null);
|
|
3224
|
+
const fGroups = React24__namespace.default.useMemo(
|
|
3080
3225
|
() => groups.map((g) => ({ group: g.group, options: g.options.filter((o) => matches2(o, query.trim())) })).filter((g) => g.options.length),
|
|
3081
3226
|
[groups, query]
|
|
3082
3227
|
);
|
|
3083
|
-
const visible =
|
|
3084
|
-
const place =
|
|
3228
|
+
const visible = React24__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
|
|
3229
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
3085
3230
|
const el = controlRef.current;
|
|
3086
3231
|
if (!el) return;
|
|
3087
3232
|
const r = el.getBoundingClientRect();
|
|
@@ -3096,7 +3241,7 @@ function MultiSelect({
|
|
|
3096
3241
|
flip
|
|
3097
3242
|
});
|
|
3098
3243
|
}, [placement, minWidth]);
|
|
3099
|
-
|
|
3244
|
+
React24__namespace.default.useEffect(() => {
|
|
3100
3245
|
if (!open || !portal) return;
|
|
3101
3246
|
place();
|
|
3102
3247
|
const onMove = () => place();
|
|
@@ -3107,7 +3252,7 @@ function MultiSelect({
|
|
|
3107
3252
|
window.removeEventListener("resize", onMove);
|
|
3108
3253
|
};
|
|
3109
3254
|
}, [open, portal, place]);
|
|
3110
|
-
|
|
3255
|
+
React24__namespace.default.useEffect(() => {
|
|
3111
3256
|
if (!open) return;
|
|
3112
3257
|
const onDown = (e) => {
|
|
3113
3258
|
if (wrapRef.current && wrapRef.current.contains(e.target)) return;
|
|
@@ -3118,10 +3263,10 @@ function MultiSelect({
|
|
|
3118
3263
|
document.addEventListener("mousedown", onDown);
|
|
3119
3264
|
return () => document.removeEventListener("mousedown", onDown);
|
|
3120
3265
|
}, [open]);
|
|
3121
|
-
|
|
3266
|
+
React24__namespace.default.useEffect(() => {
|
|
3122
3267
|
setActive(0);
|
|
3123
3268
|
}, [query]);
|
|
3124
|
-
|
|
3269
|
+
React24__namespace.default.useEffect(() => {
|
|
3125
3270
|
if (open) ensureVisible3(listRef.current, activeRef.current);
|
|
3126
3271
|
}, [active, open]);
|
|
3127
3272
|
function commit(next) {
|
|
@@ -3158,7 +3303,7 @@ function MultiSelect({
|
|
|
3158
3303
|
const descId = `${fieldId}-desc`;
|
|
3159
3304
|
const describedBy = error || hint ? descId : void 0;
|
|
3160
3305
|
let counter = -1;
|
|
3161
|
-
const popInner = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", id: listboxId, ref: listRef, role: "listbox", "aria-multiselectable": "true", children: visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: "No results found" }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3306
|
+
const popInner = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", id: listboxId, ref: listRef, role: "listbox", "aria-multiselectable": "true", children: visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: "No results found" }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React24__namespace.default.Fragment, { children: [
|
|
3162
3307
|
g.group ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: g.group }) : null,
|
|
3163
3308
|
g.options.map((o) => {
|
|
3164
3309
|
counter += 1;
|
|
@@ -3302,6 +3447,15 @@ function MultiSelect({
|
|
|
3302
3447
|
error ? /* @__PURE__ */ jsxRuntime.jsx("span", { id: descId, className: "twc-field__error", children: error }) : hint ? /* @__PURE__ */ jsxRuntime.jsx("span", { id: descId, className: "twc-field__hint", children: hint }) : null
|
|
3303
3448
|
] });
|
|
3304
3449
|
}
|
|
3450
|
+
|
|
3451
|
+
// components/_warn.js
|
|
3452
|
+
var seen = /* @__PURE__ */ new Set();
|
|
3453
|
+
function warnOnce(key, message) {
|
|
3454
|
+
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV === "production") return;
|
|
3455
|
+
if (seen.has(key)) return;
|
|
3456
|
+
seen.add(key);
|
|
3457
|
+
if (typeof console !== "undefined" && console.warn) console.warn(message);
|
|
3458
|
+
}
|
|
3305
3459
|
var PAGINATION_CSS = `
|
|
3306
3460
|
.twc-pagination { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-sans); }
|
|
3307
3461
|
.twc-page {
|
|
@@ -3364,15 +3518,18 @@ function Pagination({
|
|
|
3364
3518
|
siblings = 1,
|
|
3365
3519
|
boundaries = 1,
|
|
3366
3520
|
size = "md",
|
|
3367
|
-
showJumper
|
|
3521
|
+
showJumper,
|
|
3368
3522
|
showPageJumper,
|
|
3369
3523
|
jumperLabel = "Go to",
|
|
3370
3524
|
className = "",
|
|
3371
3525
|
...rest
|
|
3372
3526
|
}) {
|
|
3527
|
+
if (process.env.NODE_ENV !== "production" && showJumper !== void 0 && showPageJumper === void 0) {
|
|
3528
|
+
warnOnce("Pagination.showJumper", "Pagination: `showJumper` is deprecated and will be removed in 2.0 \u2014 use `showPageJumper`.");
|
|
3529
|
+
}
|
|
3373
3530
|
const jumperEnabled = showPageJumper ?? showJumper;
|
|
3374
3531
|
const __twcStyles = useScopedStyles("twc-pagination-styles", PAGINATION_CSS);
|
|
3375
|
-
const [internal, setInternal] =
|
|
3532
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultPage);
|
|
3376
3533
|
const page = pageProp !== void 0 ? pageProp : internal;
|
|
3377
3534
|
const pages = buildPages(page, total, siblings, boundaries);
|
|
3378
3535
|
const go = (p) => {
|
|
@@ -3380,7 +3537,7 @@ function Pagination({
|
|
|
3380
3537
|
if (pageProp === void 0) setInternal(p);
|
|
3381
3538
|
onChange?.(p);
|
|
3382
3539
|
};
|
|
3383
|
-
const [jump, setJump] =
|
|
3540
|
+
const [jump, setJump] = React24__namespace.default.useState("");
|
|
3384
3541
|
const submitJump = () => {
|
|
3385
3542
|
const n = parseInt(jump, 10);
|
|
3386
3543
|
if (!Number.isNaN(n)) go(Math.min(Math.max(n, 1), total));
|
|
@@ -3991,9 +4148,9 @@ function runDatatableQuery(rows, query, options = {}) {
|
|
|
3991
4148
|
return { rows: page, total, filtered: out };
|
|
3992
4149
|
}
|
|
3993
4150
|
function useFloating() {
|
|
3994
|
-
const [pos, setPos] =
|
|
3995
|
-
const cfg =
|
|
3996
|
-
const place =
|
|
4151
|
+
const [pos, setPos] = React24__namespace.default.useState(null);
|
|
4152
|
+
const cfg = React24__namespace.default.useRef(null);
|
|
4153
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
3997
4154
|
const c = cfg.current;
|
|
3998
4155
|
if (!c || !c.el || !c.el.isConnected) return null;
|
|
3999
4156
|
const r = c.el.getBoundingClientRect();
|
|
@@ -4004,17 +4161,17 @@ function useFloating() {
|
|
|
4004
4161
|
const top = r.bottom + 6;
|
|
4005
4162
|
return { top, left, width: c.width, anchorX: r.left + r.width / 2, maxHeight: Math.max(180, vh - top - M) };
|
|
4006
4163
|
}, []);
|
|
4007
|
-
const open =
|
|
4164
|
+
const open = React24__namespace.default.useCallback((el, align = "left", width = 220) => {
|
|
4008
4165
|
cfg.current = { el, align, width };
|
|
4009
4166
|
const p = place();
|
|
4010
4167
|
if (p) setPos(p);
|
|
4011
4168
|
}, [place]);
|
|
4012
|
-
const close =
|
|
4169
|
+
const close = React24__namespace.default.useCallback(() => {
|
|
4013
4170
|
cfg.current = null;
|
|
4014
4171
|
setPos(null);
|
|
4015
4172
|
}, []);
|
|
4016
4173
|
const isOpen = pos != null;
|
|
4017
|
-
|
|
4174
|
+
React24__namespace.default.useEffect(() => {
|
|
4018
4175
|
if (!isOpen) return void 0;
|
|
4019
4176
|
const update = () => {
|
|
4020
4177
|
const p = place();
|
|
@@ -4038,9 +4195,9 @@ function Caret({ pos }) {
|
|
|
4038
4195
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__caret", style: { left } });
|
|
4039
4196
|
}
|
|
4040
4197
|
function EditCell({ col, value, options, onChange, onCommit, onCommitValue, onCancel, onKeyDown }) {
|
|
4041
|
-
const ref =
|
|
4198
|
+
const ref = React24__namespace.default.useRef(null);
|
|
4042
4199
|
const isSelect = col.editType === "select" || options && col.editType !== "text";
|
|
4043
|
-
|
|
4200
|
+
React24__namespace.default.useEffect(() => {
|
|
4044
4201
|
if (isSelect) {
|
|
4045
4202
|
const t = setTimeout(() => ref.current?.querySelector(".twc-sel__trigger")?.click(), 0);
|
|
4046
4203
|
return () => clearTimeout(t);
|
|
@@ -4243,7 +4400,7 @@ function Datatable({
|
|
|
4243
4400
|
...rest
|
|
4244
4401
|
}) {
|
|
4245
4402
|
const __twcStyles = useScopedStyles("twc-dt-styles", DT_CSS);
|
|
4246
|
-
const cols =
|
|
4403
|
+
const cols = React24__namespace.default.useMemo(() => {
|
|
4247
4404
|
const out = columns.map((c) => {
|
|
4248
4405
|
const isActions = c.type === "actions";
|
|
4249
4406
|
return {
|
|
@@ -4278,7 +4435,7 @@ function Datatable({
|
|
|
4278
4435
|
}
|
|
4279
4436
|
return out;
|
|
4280
4437
|
}, [columns, rowPinning]);
|
|
4281
|
-
const _autoKey =
|
|
4438
|
+
const _autoKey = React24__namespace.default.useRef();
|
|
4282
4439
|
if (!_autoKey.current) _autoKey.current = { map: /* @__PURE__ */ new WeakMap(), n: 0 };
|
|
4283
4440
|
const keyOf = rowKey || ((r, i) => {
|
|
4284
4441
|
if (r != null && r.id != null) return r.id;
|
|
@@ -4293,17 +4450,17 @@ function Datatable({
|
|
|
4293
4450
|
}
|
|
4294
4451
|
return i;
|
|
4295
4452
|
});
|
|
4296
|
-
const [sort, setSort] =
|
|
4297
|
-
const [filters, setFilters] =
|
|
4298
|
-
const [hidden, setHidden] =
|
|
4299
|
-
const [showRowNum, setShowRowNum] =
|
|
4300
|
-
const [wrapped, setWrapped] =
|
|
4453
|
+
const [sort, setSort] = React24__namespace.default.useState(null);
|
|
4454
|
+
const [filters, setFilters] = React24__namespace.default.useState([]);
|
|
4455
|
+
const [hidden, setHidden] = React24__namespace.default.useState(() => /* @__PURE__ */ new Set());
|
|
4456
|
+
const [showRowNum, setShowRowNum] = React24__namespace.default.useState(rowNumbers);
|
|
4457
|
+
const [wrapped, setWrapped] = React24__namespace.default.useState(() => new Set((columns || []).filter((c) => c.wrapText).map((c) => c.field)));
|
|
4301
4458
|
const toggleWrap = (field) => setWrapped((w) => {
|
|
4302
4459
|
const n = new Set(w);
|
|
4303
4460
|
n.has(field) ? n.delete(field) : n.add(field);
|
|
4304
4461
|
return n;
|
|
4305
4462
|
});
|
|
4306
|
-
const [pins, setPins] =
|
|
4463
|
+
const [pins, setPins] = React24__namespace.default.useState(() => {
|
|
4307
4464
|
const left = [], right = [];
|
|
4308
4465
|
columns.forEach((c) => {
|
|
4309
4466
|
if (c.pinned === "left") left.push(c.field);
|
|
@@ -4311,34 +4468,34 @@ function Datatable({
|
|
|
4311
4468
|
});
|
|
4312
4469
|
return { left, right };
|
|
4313
4470
|
});
|
|
4314
|
-
const [density, setDensity] =
|
|
4315
|
-
const [quick, setQuick] =
|
|
4316
|
-
const [selected, setSelected] =
|
|
4317
|
-
const [activeRow, setActiveRow] =
|
|
4318
|
-
const [activeCell, setActiveCell] =
|
|
4319
|
-
const [page, setPage] =
|
|
4320
|
-
const [rowsPerPage, setRowsPerPage] =
|
|
4321
|
-
const [colQuery, setColQuery] =
|
|
4322
|
-
const [widths, setWidths] =
|
|
4323
|
-
const [order, setOrder] =
|
|
4324
|
-
const [drag, setDrag] =
|
|
4325
|
-
const [aggOn, setAggOn] =
|
|
4326
|
-
const [focus, setFocus] =
|
|
4327
|
-
const gridRef =
|
|
4328
|
-
const [groupBy, setGroupBy] =
|
|
4329
|
-
const [collapsed, setCollapsed] =
|
|
4330
|
-
const [pinnedRows, setPinnedRows] =
|
|
4331
|
-
const [headH, setHeadH] =
|
|
4332
|
-
const theadRef =
|
|
4333
|
-
const [rowOrder, setRowOrder] =
|
|
4334
|
-
const [rowHeights, setRowHeights] =
|
|
4335
|
-
const [rowDrag, setRowDrag] =
|
|
4336
|
-
const [rowGrab, setRowGrab] =
|
|
4337
|
-
const [reorderMsg, setReorderMsg] =
|
|
4338
|
-
const rowFocusRef =
|
|
4339
|
-
const rootRef =
|
|
4340
|
-
const [compact, setCompact] =
|
|
4341
|
-
|
|
4471
|
+
const [density, setDensity] = React24__namespace.default.useState(densityProp);
|
|
4472
|
+
const [quick, setQuick] = React24__namespace.default.useState("");
|
|
4473
|
+
const [selected, setSelected] = React24__namespace.default.useState(() => /* @__PURE__ */ new Set());
|
|
4474
|
+
const [activeRow, setActiveRow] = React24__namespace.default.useState(null);
|
|
4475
|
+
const [activeCell, setActiveCell] = React24__namespace.default.useState(null);
|
|
4476
|
+
const [page, setPage] = React24__namespace.default.useState(0);
|
|
4477
|
+
const [rowsPerPage, setRowsPerPage] = React24__namespace.default.useState(pageSize > 0 ? pageSize : 10);
|
|
4478
|
+
const [colQuery, setColQuery] = React24__namespace.default.useState("");
|
|
4479
|
+
const [widths, setWidths] = React24__namespace.default.useState({});
|
|
4480
|
+
const [order, setOrder] = React24__namespace.default.useState(() => columns.map((c) => c.field));
|
|
4481
|
+
const [drag, setDrag] = React24__namespace.default.useState({ from: null, over: null, after: false });
|
|
4482
|
+
const [aggOn, setAggOn] = React24__namespace.default.useState(showAggregation);
|
|
4483
|
+
const [focus, setFocus] = React24__namespace.default.useState({ r: 0, c: 0 });
|
|
4484
|
+
const gridRef = React24__namespace.default.useRef(null);
|
|
4485
|
+
const [groupBy, setGroupBy] = React24__namespace.default.useState(rowGrouping || []);
|
|
4486
|
+
const [collapsed, setCollapsed] = React24__namespace.default.useState(() => /* @__PURE__ */ new Set());
|
|
4487
|
+
const [pinnedRows, setPinnedRows] = React24__namespace.default.useState({ top: [], bottom: [] });
|
|
4488
|
+
const [headH, setHeadH] = React24__namespace.default.useState(41);
|
|
4489
|
+
const theadRef = React24__namespace.default.useRef(null);
|
|
4490
|
+
const [rowOrder, setRowOrder] = React24__namespace.default.useState(null);
|
|
4491
|
+
const [rowHeights, setRowHeights] = React24__namespace.default.useState({});
|
|
4492
|
+
const [rowDrag, setRowDrag] = React24__namespace.default.useState({ from: null, over: null, after: false });
|
|
4493
|
+
const [rowGrab, setRowGrab] = React24__namespace.default.useState(null);
|
|
4494
|
+
const [reorderMsg, setReorderMsg] = React24__namespace.default.useState("");
|
|
4495
|
+
const rowFocusRef = React24__namespace.default.useRef(null);
|
|
4496
|
+
const rootRef = React24__namespace.default.useRef(null);
|
|
4497
|
+
const [compact, setCompact] = React24__namespace.default.useState(false);
|
|
4498
|
+
React24__namespace.default.useEffect(() => {
|
|
4342
4499
|
const el = rootRef.current;
|
|
4343
4500
|
if (!el) return void 0;
|
|
4344
4501
|
const measure = () => setCompact((el.clientWidth || 0) < 720);
|
|
@@ -4351,11 +4508,11 @@ function Datatable({
|
|
|
4351
4508
|
else if (typeof window !== "undefined") window.removeEventListener("resize", measure);
|
|
4352
4509
|
};
|
|
4353
4510
|
}, []);
|
|
4354
|
-
const scrollRef =
|
|
4355
|
-
const [scrollTop, setScrollTop] =
|
|
4356
|
-
const [viewportH, setViewportH] =
|
|
4357
|
-
const [pivotOn, setPivotOn] =
|
|
4358
|
-
const [aggConfig, setAggConfig] =
|
|
4511
|
+
const scrollRef = React24__namespace.default.useRef(null);
|
|
4512
|
+
const [scrollTop, setScrollTop] = React24__namespace.default.useState(0);
|
|
4513
|
+
const [viewportH, setViewportH] = React24__namespace.default.useState(0);
|
|
4514
|
+
const [pivotOn, setPivotOn] = React24__namespace.default.useState(pivotMode);
|
|
4515
|
+
const [aggConfig, setAggConfig] = React24__namespace.default.useState(() => {
|
|
4359
4516
|
const m = {};
|
|
4360
4517
|
(columns || []).forEach((c) => {
|
|
4361
4518
|
if (typeof c.aggregation === "string") m[c.field] = c.aggregation;
|
|
@@ -4363,13 +4520,13 @@ function Datatable({
|
|
|
4363
4520
|
return m;
|
|
4364
4521
|
});
|
|
4365
4522
|
const aggOf = (c) => aggConfig[c.field] || (typeof c.aggregation === "function" ? c.aggregation : null);
|
|
4366
|
-
const [pivotConfig, setPivotConfig] =
|
|
4523
|
+
const [pivotConfig, setPivotConfig] = React24__namespace.default.useState(() => ({
|
|
4367
4524
|
rows: pivot && pivot.rows || [],
|
|
4368
4525
|
columns: pivot && pivot.columns || [],
|
|
4369
4526
|
values: pivot && pivot.values || []
|
|
4370
4527
|
}));
|
|
4371
4528
|
const pivotActive = pivotOn && pivotConfig.rows.length > 0 && pivotConfig.values.length > 0;
|
|
4372
|
-
|
|
4529
|
+
React24__namespace.default.useEffect(() => {
|
|
4373
4530
|
setOrder((prev) => {
|
|
4374
4531
|
const fields = columns.map((c) => c.field);
|
|
4375
4532
|
const kept = prev.filter((f) => fields.includes(f));
|
|
@@ -4377,32 +4534,32 @@ function Datatable({
|
|
|
4377
4534
|
return [...kept, ...added];
|
|
4378
4535
|
});
|
|
4379
4536
|
}, [columns]);
|
|
4380
|
-
|
|
4537
|
+
React24__namespace.default.useEffect(() => {
|
|
4381
4538
|
setDensity(densityProp);
|
|
4382
4539
|
}, [densityProp]);
|
|
4383
|
-
|
|
4540
|
+
React24__namespace.default.useEffect(() => {
|
|
4384
4541
|
setAggOn(showAggregation);
|
|
4385
4542
|
}, [showAggregation]);
|
|
4386
4543
|
const rowGroupingKey = (rowGrouping || []).join("\0");
|
|
4387
|
-
const rowGroupingKeyRef =
|
|
4388
|
-
|
|
4544
|
+
const rowGroupingKeyRef = React24__namespace.default.useRef(rowGroupingKey);
|
|
4545
|
+
React24__namespace.default.useEffect(() => {
|
|
4389
4546
|
if (rowGroupingKeyRef.current === rowGroupingKey) return;
|
|
4390
4547
|
rowGroupingKeyRef.current = rowGroupingKey;
|
|
4391
4548
|
setGroupBy(rowGrouping || []);
|
|
4392
4549
|
}, [rowGroupingKey]);
|
|
4393
4550
|
const widthOf = (c) => widths[c.field] ?? c.width ?? 160;
|
|
4394
|
-
const [colMenu, setColMenu] =
|
|
4551
|
+
const [colMenu, setColMenu] = React24__namespace.default.useState(null);
|
|
4395
4552
|
const [menuPos, openMenu, closeMenu] = useFloating();
|
|
4396
|
-
const [panel, setPanel] =
|
|
4553
|
+
const [panel, setPanel] = React24__namespace.default.useState(null);
|
|
4397
4554
|
const [panelPos, openPanel, closePanel] = useFloating();
|
|
4398
|
-
const [rowMenu, setRowMenu] =
|
|
4555
|
+
const [rowMenu, setRowMenu] = React24__namespace.default.useState(null);
|
|
4399
4556
|
const [rowMenuPos, openRowMenu, closeRowMenu] = useFloating();
|
|
4400
|
-
const [exportOpen, setExportOpen] =
|
|
4557
|
+
const [exportOpen, setExportOpen] = React24__namespace.default.useState(false);
|
|
4401
4558
|
const [exportPos, openExport, closeExport] = useFloating();
|
|
4402
|
-
const menuTriggerRef =
|
|
4403
|
-
const colMenuRef =
|
|
4404
|
-
const rowMenuRef =
|
|
4405
|
-
const exportMenuRef =
|
|
4559
|
+
const menuTriggerRef = React24__namespace.default.useRef(null);
|
|
4560
|
+
const colMenuRef = React24__namespace.default.useRef(null);
|
|
4561
|
+
const rowMenuRef = React24__namespace.default.useRef(null);
|
|
4562
|
+
const exportMenuRef = React24__namespace.default.useRef(null);
|
|
4406
4563
|
function focusFirstItem(container) {
|
|
4407
4564
|
if (!container) return;
|
|
4408
4565
|
const first = container.querySelector('[role="menuitem"]:not([disabled])');
|
|
@@ -4441,16 +4598,16 @@ function Datatable({
|
|
|
4441
4598
|
restoreTriggerFocus();
|
|
4442
4599
|
}
|
|
4443
4600
|
}
|
|
4444
|
-
|
|
4601
|
+
React24__namespace.default.useEffect(() => {
|
|
4445
4602
|
if (colMenu) focusFirstItem(colMenuRef.current);
|
|
4446
4603
|
}, [colMenu]);
|
|
4447
|
-
|
|
4604
|
+
React24__namespace.default.useEffect(() => {
|
|
4448
4605
|
if (rowMenu) focusFirstItem(rowMenuRef.current);
|
|
4449
4606
|
}, [rowMenu]);
|
|
4450
|
-
|
|
4607
|
+
React24__namespace.default.useEffect(() => {
|
|
4451
4608
|
if (exportOpen) focusFirstItem(exportMenuRef.current);
|
|
4452
4609
|
}, [exportOpen]);
|
|
4453
|
-
|
|
4610
|
+
React24__namespace.default.useEffect(() => {
|
|
4454
4611
|
if (!colMenu && !panel && !rowMenu) return;
|
|
4455
4612
|
const closeAll = () => {
|
|
4456
4613
|
setColMenu(null);
|
|
@@ -4473,7 +4630,7 @@ function Datatable({
|
|
|
4473
4630
|
document.removeEventListener("keydown", onKey);
|
|
4474
4631
|
};
|
|
4475
4632
|
}, [colMenu, panel, rowMenu]);
|
|
4476
|
-
|
|
4633
|
+
React24__namespace.default.useEffect(() => {
|
|
4477
4634
|
if (!exportOpen) return;
|
|
4478
4635
|
const close = () => {
|
|
4479
4636
|
setExportOpen(false);
|
|
@@ -4492,9 +4649,9 @@ function Datatable({
|
|
|
4492
4649
|
document.removeEventListener("keydown", onKey);
|
|
4493
4650
|
};
|
|
4494
4651
|
}, [exportOpen]);
|
|
4495
|
-
const colByField =
|
|
4652
|
+
const colByField = React24__namespace.default.useMemo(() => Object.fromEntries(cols.map((c) => [c.field, c])), [cols]);
|
|
4496
4653
|
const visibleCols = cols.filter((c) => !hidden.has(c.field));
|
|
4497
|
-
const ordered =
|
|
4654
|
+
const ordered = React24__namespace.default.useMemo(() => {
|
|
4498
4655
|
const orderIdx = (f) => {
|
|
4499
4656
|
const i = order.indexOf(f);
|
|
4500
4657
|
return i === -1 ? 9999 : i;
|
|
@@ -4529,7 +4686,7 @@ function Datatable({
|
|
|
4529
4686
|
}
|
|
4530
4687
|
return {};
|
|
4531
4688
|
};
|
|
4532
|
-
const processed =
|
|
4689
|
+
const processed = React24__namespace.default.useMemo(() => {
|
|
4533
4690
|
if (serverMode) {
|
|
4534
4691
|
if (rowOrder) {
|
|
4535
4692
|
const idx = new Map(rowOrder.map((k, i) => [k, i]));
|
|
@@ -4568,10 +4725,10 @@ function Datatable({
|
|
|
4568
4725
|
const totalRows = serverMode ? serverTotal : processed.length;
|
|
4569
4726
|
const totalPages = paginated ? Math.max(1, Math.ceil(totalRows / rowsPerPage)) : 1;
|
|
4570
4727
|
const paged = !paginated || serverMode ? processed : processed.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
|
|
4571
|
-
|
|
4728
|
+
React24__namespace.default.useEffect(() => {
|
|
4572
4729
|
if (page > totalPages - 1) setPage(0);
|
|
4573
4730
|
}, [totalPages]);
|
|
4574
|
-
const activeGroupBy =
|
|
4731
|
+
const activeGroupBy = React24__namespace.default.useMemo(() => groupBy.filter((f) => colByField[f]), [groupBy, colByField]);
|
|
4575
4732
|
function subtotalText(rowsIn) {
|
|
4576
4733
|
const parts = [];
|
|
4577
4734
|
for (const c of ordered) {
|
|
@@ -4598,7 +4755,7 @@ function Datatable({
|
|
|
4598
4755
|
if (agg === "max") return Math.max(...nums);
|
|
4599
4756
|
return null;
|
|
4600
4757
|
}
|
|
4601
|
-
const displayItems =
|
|
4758
|
+
const displayItems = React24__namespace.default.useMemo(() => {
|
|
4602
4759
|
if (!activeGroupBy.length) return null;
|
|
4603
4760
|
const build = (rowsIn, depth, prefix) => {
|
|
4604
4761
|
if (depth >= activeGroupBy.length) return rowsIn.map((row) => ({ kind: "leaf", row }));
|
|
@@ -4640,7 +4797,7 @@ function Datatable({
|
|
|
4640
4797
|
return { top, bottom };
|
|
4641
4798
|
});
|
|
4642
4799
|
}
|
|
4643
|
-
|
|
4800
|
+
React24__namespace.default.useEffect(() => {
|
|
4644
4801
|
if (!rowPinning) return;
|
|
4645
4802
|
const measure = () => {
|
|
4646
4803
|
if (theadRef.current) setHeadH(theadRef.current.offsetHeight || 41);
|
|
@@ -4654,12 +4811,12 @@ function Datatable({
|
|
|
4654
4811
|
const pinnedTopRows = canPinRows ? pinnedRows.top.map((k) => leafRows.find((r, i) => keyOf(r, i) === k)).filter(Boolean) : [];
|
|
4655
4812
|
const pinnedBottomRows = canPinRows ? pinnedRows.bottom.map((k) => leafRows.find((r, i) => keyOf(r, i) === k)).filter(Boolean) : [];
|
|
4656
4813
|
const middleRows = canPinRows ? leafRows.filter((r, i) => !pinSideOf(keyOf(r, i))) : leafRows;
|
|
4657
|
-
const keyIndex =
|
|
4814
|
+
const keyIndex = React24__namespace.default.useMemo(() => {
|
|
4658
4815
|
const m = /* @__PURE__ */ new Map();
|
|
4659
4816
|
leafRows.forEach((r, i) => m.set(keyOf(r, i), i));
|
|
4660
4817
|
return m;
|
|
4661
4818
|
}, [leafRows]);
|
|
4662
|
-
const keyIndexMid =
|
|
4819
|
+
const keyIndexMid = React24__namespace.default.useMemo(() => {
|
|
4663
4820
|
const m = /* @__PURE__ */ new Map();
|
|
4664
4821
|
middleRows.forEach((r, i) => m.set(keyOf(r, keyIndex.get(keyOf(r)) ?? i), i));
|
|
4665
4822
|
return m;
|
|
@@ -4744,7 +4901,7 @@ function Datatable({
|
|
|
4744
4901
|
setReorderMsg("Reorder cancelled.");
|
|
4745
4902
|
}
|
|
4746
4903
|
}
|
|
4747
|
-
|
|
4904
|
+
React24__namespace.default.useEffect(() => {
|
|
4748
4905
|
if (rowFocusRef.current == null) return;
|
|
4749
4906
|
const key = rowFocusRef.current;
|
|
4750
4907
|
rowFocusRef.current = null;
|
|
@@ -4756,7 +4913,7 @@ function Datatable({
|
|
|
4756
4913
|
});
|
|
4757
4914
|
const estRowH = rowHeight ?? (density === "compact" ? 36 : density === "comfortable" ? 56 : 44);
|
|
4758
4915
|
const virtualizing = virtualized && !paginated && !activeGroupBy.length && !loading;
|
|
4759
|
-
|
|
4916
|
+
React24__namespace.default.useEffect(() => {
|
|
4760
4917
|
if (!virtualizing) return;
|
|
4761
4918
|
const el = scrollRef.current;
|
|
4762
4919
|
if (!el) return;
|
|
@@ -4766,13 +4923,13 @@ function Datatable({
|
|
|
4766
4923
|
if (ro) ro.observe(el);
|
|
4767
4924
|
return () => ro && ro.disconnect();
|
|
4768
4925
|
}, [virtualizing, height]);
|
|
4769
|
-
const onScrollVirtual =
|
|
4926
|
+
const onScrollVirtual = React24__namespace.default.useCallback((e) => {
|
|
4770
4927
|
setScrollTop(e.currentTarget.scrollTop);
|
|
4771
4928
|
}, []);
|
|
4772
4929
|
const vh = viewportH || (typeof height === "number" ? height : 440);
|
|
4773
|
-
const rowHRef =
|
|
4774
|
-
const [measureTick, setMeasureTick] =
|
|
4775
|
-
const offsets =
|
|
4930
|
+
const rowHRef = React24__namespace.default.useRef(/* @__PURE__ */ new Map());
|
|
4931
|
+
const [measureTick, setMeasureTick] = React24__namespace.default.useState(0);
|
|
4932
|
+
const offsets = React24__namespace.default.useMemo(() => {
|
|
4776
4933
|
if (!virtualizing) return null;
|
|
4777
4934
|
const total = middleRows.length;
|
|
4778
4935
|
const arr = new Float64Array(total + 1);
|
|
@@ -4782,7 +4939,7 @@ function Datatable({
|
|
|
4782
4939
|
}
|
|
4783
4940
|
return arr;
|
|
4784
4941
|
}, [virtualizing, middleRows, estRowH, measureTick]);
|
|
4785
|
-
const vWindow =
|
|
4942
|
+
const vWindow = React24__namespace.default.useMemo(() => {
|
|
4786
4943
|
if (!virtualizing || !offsets) return null;
|
|
4787
4944
|
const total = middleRows.length;
|
|
4788
4945
|
const totalH = offsets[total];
|
|
@@ -4811,7 +4968,7 @@ function Datatable({
|
|
|
4811
4968
|
if (start > end) start = end;
|
|
4812
4969
|
return { start, end, padTop: offsets[start], padBottom: Math.max(0, totalH - offsets[end]) };
|
|
4813
4970
|
}, [virtualizing, offsets, middleRows.length, vh, scrollTop, overscan]);
|
|
4814
|
-
|
|
4971
|
+
React24__namespace.default.useLayoutEffect(() => {
|
|
4815
4972
|
if (!virtualizing) return;
|
|
4816
4973
|
const el = scrollRef.current;
|
|
4817
4974
|
if (!el) return;
|
|
@@ -4826,9 +4983,9 @@ function Datatable({
|
|
|
4826
4983
|
}
|
|
4827
4984
|
if (changed) setMeasureTick((t) => t + 1);
|
|
4828
4985
|
});
|
|
4829
|
-
const onServerChangeRef =
|
|
4986
|
+
const onServerChangeRef = React24__namespace.default.useRef(onServerChange);
|
|
4830
4987
|
onServerChangeRef.current = onServerChange;
|
|
4831
|
-
|
|
4988
|
+
React24__namespace.default.useEffect(() => {
|
|
4832
4989
|
if (!serverMode) return;
|
|
4833
4990
|
const t = setTimeout(() => {
|
|
4834
4991
|
onServerChangeRef.current?.({
|
|
@@ -4863,7 +5020,7 @@ function Datatable({
|
|
|
4863
5020
|
return n;
|
|
4864
5021
|
});
|
|
4865
5022
|
}
|
|
4866
|
-
const movableMidFields =
|
|
5023
|
+
const movableMidFields = React24__namespace.default.useMemo(
|
|
4867
5024
|
() => ordered.filter((c) => !pins.left.includes(c.field) && !pins.right.includes(c.field)).map((c) => c.field),
|
|
4868
5025
|
[ordered, pins]
|
|
4869
5026
|
);
|
|
@@ -4894,7 +5051,7 @@ function Datatable({
|
|
|
4894
5051
|
}
|
|
4895
5052
|
return [...set].sort((a, b) => a.localeCompare(b)).map((v) => ({ value: v, label: v }));
|
|
4896
5053
|
}
|
|
4897
|
-
const [resizing, setResizing] =
|
|
5054
|
+
const [resizing, setResizing] = React24__namespace.default.useState(false);
|
|
4898
5055
|
function startResize(e, field) {
|
|
4899
5056
|
e.preventDefault();
|
|
4900
5057
|
e.stopPropagation();
|
|
@@ -5001,7 +5158,7 @@ function Datatable({
|
|
|
5001
5158
|
if (!agg) return null;
|
|
5002
5159
|
if (aggregationValues && col.field in aggregationValues) {
|
|
5003
5160
|
const pre = aggregationValues[col.field];
|
|
5004
|
-
if (pre && typeof pre === "object" && !
|
|
5161
|
+
if (pre && typeof pre === "object" && !React24__namespace.default.isValidElement(pre)) {
|
|
5005
5162
|
if (typeof agg === "string" && agg in pre) return pre[agg];
|
|
5006
5163
|
} else {
|
|
5007
5164
|
return pre;
|
|
@@ -5119,14 +5276,14 @@ function Datatable({
|
|
|
5119
5276
|
focusCell(r, c);
|
|
5120
5277
|
}
|
|
5121
5278
|
}
|
|
5122
|
-
|
|
5279
|
+
React24__namespace.default.useEffect(() => {
|
|
5123
5280
|
setFocus((f) => ({ r: Math.min(f.r, Math.max(0, leafRows.length - 1)), c: Math.min(f.c, Math.max(0, ordered.length - 1)) }));
|
|
5124
5281
|
}, [leafRows.length, ordered.length, page]);
|
|
5125
|
-
const selectedRows =
|
|
5282
|
+
const selectedRows = React24__namespace.default.useMemo(() => rows.filter((r, i) => selected.has(keyOf(r, i))), [rows, selected]);
|
|
5126
5283
|
function clearSelection() {
|
|
5127
5284
|
setSelected(/* @__PURE__ */ new Set());
|
|
5128
5285
|
}
|
|
5129
|
-
const [editing, setEditing] =
|
|
5286
|
+
const [editing, setEditing] = React24__namespace.default.useState(null);
|
|
5130
5287
|
const isColEditable = (c) => c.type !== "actions" && (c.editable ?? (editMode && c.editable !== false));
|
|
5131
5288
|
function beginEdit(rowK, col, row) {
|
|
5132
5289
|
if (!isColEditable(col)) return;
|
|
@@ -5161,17 +5318,17 @@ function Datatable({
|
|
|
5161
5318
|
cancelEdit();
|
|
5162
5319
|
}
|
|
5163
5320
|
}
|
|
5164
|
-
const batchEditableCols =
|
|
5321
|
+
const batchEditableCols = React24__namespace.default.useMemo(
|
|
5165
5322
|
() => cols.filter((c) => c.type !== "actions" && (c.editable ?? (editMode && c.editable !== false))),
|
|
5166
5323
|
[cols, editMode]
|
|
5167
5324
|
);
|
|
5168
|
-
const [batchEdit, setBatchEdit] =
|
|
5325
|
+
const [batchEdit, setBatchEdit] = React24__namespace.default.useState(null);
|
|
5169
5326
|
const [batchEditPos, openBatchEdit, closeBatchEdit] = useFloating();
|
|
5170
5327
|
function openBatchEditor(el) {
|
|
5171
5328
|
setBatchEdit({ fields: {}, values: {} });
|
|
5172
5329
|
openBatchEdit(el, "left", 320);
|
|
5173
5330
|
}
|
|
5174
|
-
|
|
5331
|
+
React24__namespace.default.useEffect(() => {
|
|
5175
5332
|
if (!batchEdit) return;
|
|
5176
5333
|
const close = () => {
|
|
5177
5334
|
setBatchEdit(null);
|
|
@@ -5190,7 +5347,7 @@ function Datatable({
|
|
|
5190
5347
|
document.removeEventListener("keydown", onKey);
|
|
5191
5348
|
};
|
|
5192
5349
|
}, [batchEdit]);
|
|
5193
|
-
|
|
5350
|
+
React24__namespace.default.useEffect(() => {
|
|
5194
5351
|
if (batchEdit && selected.size === 0) {
|
|
5195
5352
|
setBatchEdit(null);
|
|
5196
5353
|
closeBatchEdit();
|
|
@@ -5227,7 +5384,7 @@ function Datatable({
|
|
|
5227
5384
|
setBatchEdit(null);
|
|
5228
5385
|
closeBatchEdit();
|
|
5229
5386
|
}
|
|
5230
|
-
|
|
5387
|
+
React24__namespace.default.useEffect(() => {
|
|
5231
5388
|
if (!editing) return;
|
|
5232
5389
|
const onDown = (e) => {
|
|
5233
5390
|
if (e.target.closest(".twc-dt__editor-wrap") || e.target.closest(".twc-pop")) return;
|
|
@@ -5499,12 +5656,12 @@ function Datatable({
|
|
|
5499
5656
|
const vlabel = (v) => v.label || (colByField[v.field]?.headerName || v.field);
|
|
5500
5657
|
const rowFieldLabel = rFields.map((f) => colByField[f]?.headerName || f).join(" / ");
|
|
5501
5658
|
const leafPaths = [];
|
|
5502
|
-
const
|
|
5659
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
5503
5660
|
for (const r of rows) {
|
|
5504
5661
|
const path = colPathOf(r);
|
|
5505
5662
|
const key = path.join("\0");
|
|
5506
|
-
if (!
|
|
5507
|
-
|
|
5663
|
+
if (!seen2.has(key)) {
|
|
5664
|
+
seen2.add(key);
|
|
5508
5665
|
leafPaths.push(path);
|
|
5509
5666
|
}
|
|
5510
5667
|
}
|
|
@@ -6032,7 +6189,7 @@ function Datatable({
|
|
|
6032
6189
|
} }) })
|
|
6033
6190
|
] }) : null
|
|
6034
6191
|
] }),
|
|
6035
|
-
paginated ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__footer-row", "data-pager": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Pagination, { size: "sm", page: page + 1, total: totalPages, boundaries: 3,
|
|
6192
|
+
paginated ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__footer-row", "data-pager": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Pagination, { size: "sm", page: page + 1, total: totalPages, boundaries: 3, showPageJumper: showPageJumper && totalPages > 5, onChange: (p) => setPage(p - 1) }) }) : null
|
|
6036
6193
|
] }) : null,
|
|
6037
6194
|
exportOpen && exportPos ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6038
6195
|
"div",
|
|
@@ -6749,23 +6906,23 @@ function DatePicker({
|
|
|
6749
6906
|
}) {
|
|
6750
6907
|
const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS3);
|
|
6751
6908
|
const __twcStyles1 = useScopedStyles("twc-datepicker-styles", DATEPICKER_CSS);
|
|
6752
|
-
const autoId =
|
|
6909
|
+
const autoId = React24__namespace.default.useId();
|
|
6753
6910
|
const fieldId = id || autoId;
|
|
6754
6911
|
const descId = `${fieldId}-desc`;
|
|
6755
6912
|
const invalid = Boolean(error);
|
|
6756
|
-
const [internal, setInternal] =
|
|
6913
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
6757
6914
|
const selected = value !== void 0 ? value : internal;
|
|
6758
|
-
const [open, setOpen] =
|
|
6759
|
-
const [view, setView] =
|
|
6760
|
-
const [mode, setMode] =
|
|
6761
|
-
const [focusDate, setFocusDate] =
|
|
6762
|
-
const [coords, setCoords] =
|
|
6763
|
-
const wrapRef =
|
|
6764
|
-
const triggerRef =
|
|
6765
|
-
const popRef =
|
|
6766
|
-
const gridRef =
|
|
6915
|
+
const [open, setOpen] = React24__namespace.default.useState(false);
|
|
6916
|
+
const [view, setView] = React24__namespace.default.useState(selected || /* @__PURE__ */ new Date());
|
|
6917
|
+
const [mode, setMode] = React24__namespace.default.useState("days");
|
|
6918
|
+
const [focusDate, setFocusDate] = React24__namespace.default.useState(null);
|
|
6919
|
+
const [coords, setCoords] = React24__namespace.default.useState(null);
|
|
6920
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
6921
|
+
const triggerRef = React24__namespace.default.useRef(null);
|
|
6922
|
+
const popRef = React24__namespace.default.useRef(null);
|
|
6923
|
+
const gridRef = React24__namespace.default.useRef(null);
|
|
6767
6924
|
const POP_W = 280;
|
|
6768
|
-
const place =
|
|
6925
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
6769
6926
|
const el = triggerRef.current;
|
|
6770
6927
|
if (!el) return;
|
|
6771
6928
|
const r = el.getBoundingClientRect();
|
|
@@ -6776,7 +6933,7 @@ function DatePicker({
|
|
|
6776
6933
|
left = Math.max(8, left);
|
|
6777
6934
|
setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
|
|
6778
6935
|
}, []);
|
|
6779
|
-
|
|
6936
|
+
React24__namespace.default.useEffect(() => {
|
|
6780
6937
|
if (!open) return void 0;
|
|
6781
6938
|
place();
|
|
6782
6939
|
const onMove = () => place();
|
|
@@ -6787,7 +6944,7 @@ function DatePicker({
|
|
|
6787
6944
|
window.removeEventListener("resize", onMove);
|
|
6788
6945
|
};
|
|
6789
6946
|
}, [open, place]);
|
|
6790
|
-
|
|
6947
|
+
React24__namespace.default.useEffect(() => {
|
|
6791
6948
|
if (!open) return;
|
|
6792
6949
|
setView(selected || /* @__PURE__ */ new Date());
|
|
6793
6950
|
setMode("days");
|
|
@@ -6807,8 +6964,8 @@ function DatePicker({
|
|
|
6807
6964
|
document.removeEventListener("keydown", onKey);
|
|
6808
6965
|
};
|
|
6809
6966
|
}, [open]);
|
|
6810
|
-
const prevOpen =
|
|
6811
|
-
|
|
6967
|
+
const prevOpen = React24__namespace.default.useRef(false);
|
|
6968
|
+
React24__namespace.default.useEffect(() => {
|
|
6812
6969
|
let id2;
|
|
6813
6970
|
if (!prevOpen.current && open) {
|
|
6814
6971
|
id2 = setTimeout(() => gridRef.current?.querySelector('[tabindex="0"]')?.focus({ preventScroll: true }), 30);
|
|
@@ -6819,9 +6976,9 @@ function DatePicker({
|
|
|
6819
6976
|
prevOpen.current = open;
|
|
6820
6977
|
return () => clearTimeout(id2);
|
|
6821
6978
|
}, [open]);
|
|
6822
|
-
const months =
|
|
6823
|
-
const monthsShort =
|
|
6824
|
-
const dows =
|
|
6979
|
+
const months = React24__namespace.default.useMemo(() => locale === void 0 ? MONTHS : monthNames(locale), [locale]);
|
|
6980
|
+
const monthsShort = React24__namespace.default.useMemo(() => locale === void 0 ? MONTHS.map((n) => n.slice(0, 3)) : monthShortNames(locale), [locale]);
|
|
6981
|
+
const dows = React24__namespace.default.useMemo(
|
|
6825
6982
|
() => locale === void 0 ? Array.from({ length: 7 }, (_, i) => DOW[(i + weekStartsOn) % 7]) : weekdayNames(locale, weekStartsOn),
|
|
6826
6983
|
[locale, weekStartsOn]
|
|
6827
6984
|
);
|
|
@@ -6849,7 +7006,7 @@ function DatePicker({
|
|
|
6849
7006
|
};
|
|
6850
7007
|
const cells = Array.from({ length: 42 }, (_, i) => new Date(gridStart.getFullYear(), gridStart.getMonth(), gridStart.getDate() + i));
|
|
6851
7008
|
const tabbableDate = (focusDate && cells.some((c) => sameDay(c, focusDate)) ? focusDate : null) || (selected && cells.some((c) => sameDay(c, selected)) ? selected : null) || (cells.some((c) => sameDay(c, today)) ? today : null) || new Date(y, m, 1);
|
|
6852
|
-
|
|
7009
|
+
React24__namespace.default.useEffect(() => {
|
|
6853
7010
|
if (!open || mode !== "days" || !focusDate) return;
|
|
6854
7011
|
gridRef.current?.querySelector(`[data-key="${keyOf(focusDate)}"]`)?.focus();
|
|
6855
7012
|
}, [focusDate, open, mode]);
|
|
@@ -7072,23 +7229,23 @@ function DateRangePicker({
|
|
|
7072
7229
|
}) {
|
|
7073
7230
|
const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS4);
|
|
7074
7231
|
const __twcStyles1 = useScopedStyles("twc-drp-styles", RANGE_CSS);
|
|
7075
|
-
const [internal, setInternal] =
|
|
7232
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
7076
7233
|
const range = value !== void 0 ? value : internal;
|
|
7077
|
-
const [open, setOpen] =
|
|
7078
|
-
const [view, setView] =
|
|
7079
|
-
const [hover, setHover] =
|
|
7080
|
-
const [coords, setCoords] =
|
|
7081
|
-
const wrapRef =
|
|
7082
|
-
const triggerRef =
|
|
7083
|
-
const popRef =
|
|
7084
|
-
const labelId =
|
|
7234
|
+
const [open, setOpen] = React24__namespace.default.useState(false);
|
|
7235
|
+
const [view, setView] = React24__namespace.default.useState(range.start || /* @__PURE__ */ new Date());
|
|
7236
|
+
const [hover, setHover] = React24__namespace.default.useState(null);
|
|
7237
|
+
const [coords, setCoords] = React24__namespace.default.useState(null);
|
|
7238
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
7239
|
+
const triggerRef = React24__namespace.default.useRef(null);
|
|
7240
|
+
const popRef = React24__namespace.default.useRef(null);
|
|
7241
|
+
const labelId = React24__namespace.default.useId();
|
|
7085
7242
|
const descId = `${labelId}-desc`;
|
|
7086
7243
|
const invalid = Boolean(error);
|
|
7087
|
-
|
|
7244
|
+
React24__namespace.default.useEffect(() => {
|
|
7088
7245
|
if (disabled) setOpen(false);
|
|
7089
7246
|
}, [disabled]);
|
|
7090
7247
|
const POP_W = 420;
|
|
7091
|
-
const place =
|
|
7248
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
7092
7249
|
const el = triggerRef.current;
|
|
7093
7250
|
if (!el) return;
|
|
7094
7251
|
const r = el.getBoundingClientRect();
|
|
@@ -7099,7 +7256,7 @@ function DateRangePicker({
|
|
|
7099
7256
|
left = Math.max(8, left);
|
|
7100
7257
|
setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
|
|
7101
7258
|
}, []);
|
|
7102
|
-
|
|
7259
|
+
React24__namespace.default.useEffect(() => {
|
|
7103
7260
|
if (!open) return void 0;
|
|
7104
7261
|
place();
|
|
7105
7262
|
const onMove = () => place();
|
|
@@ -7110,7 +7267,7 @@ function DateRangePicker({
|
|
|
7110
7267
|
window.removeEventListener("resize", onMove);
|
|
7111
7268
|
};
|
|
7112
7269
|
}, [open, place]);
|
|
7113
|
-
|
|
7270
|
+
React24__namespace.default.useEffect(() => {
|
|
7114
7271
|
if (!open) return;
|
|
7115
7272
|
const onDown = (e) => {
|
|
7116
7273
|
if (wrapRef.current && wrapRef.current.contains(e.target)) return;
|
|
@@ -7148,8 +7305,8 @@ function DateRangePicker({
|
|
|
7148
7305
|
setView(start);
|
|
7149
7306
|
setOpen(false);
|
|
7150
7307
|
};
|
|
7151
|
-
const months =
|
|
7152
|
-
const dows =
|
|
7308
|
+
const months = React24__namespace.default.useMemo(() => locale === void 0 ? MONTHS2 : monthNames2(locale), [locale]);
|
|
7309
|
+
const dows = React24__namespace.default.useMemo(
|
|
7153
7310
|
() => locale === void 0 ? Array.from({ length: 7 }, (_, i) => DOW2[(i + weekStartsOn) % 7]) : weekdayNames2(locale, weekStartsOn),
|
|
7154
7311
|
[locale, weekStartsOn]
|
|
7155
7312
|
);
|
|
@@ -7330,13 +7487,14 @@ function Dialog({
|
|
|
7330
7487
|
className = "",
|
|
7331
7488
|
...rest
|
|
7332
7489
|
}) {
|
|
7333
|
-
const autoId =
|
|
7490
|
+
const autoId = React24__namespace.default.useId();
|
|
7334
7491
|
const titleId = `${autoId}-title`;
|
|
7335
7492
|
const descId = `${autoId}-desc`;
|
|
7336
|
-
const dialogRef =
|
|
7493
|
+
const dialogRef = React24__namespace.default.useRef(null);
|
|
7337
7494
|
const __twcStyles = useScopedStyles("twc-dialog-styles", DIALOG_CSS);
|
|
7338
|
-
const
|
|
7339
|
-
|
|
7495
|
+
const renderPortal = usePortal();
|
|
7496
|
+
const [mounted, setMounted] = React24__namespace.default.useState(open);
|
|
7497
|
+
React24__namespace.default.useEffect(() => {
|
|
7340
7498
|
if (open) {
|
|
7341
7499
|
setMounted(true);
|
|
7342
7500
|
return;
|
|
@@ -7344,7 +7502,7 @@ function Dialog({
|
|
|
7344
7502
|
const t = setTimeout(() => setMounted(false), 170);
|
|
7345
7503
|
return () => clearTimeout(t);
|
|
7346
7504
|
}, [open]);
|
|
7347
|
-
|
|
7505
|
+
React24__namespace.default.useEffect(() => {
|
|
7348
7506
|
if (!open) return void 0;
|
|
7349
7507
|
const prev = document.body.style.overflow;
|
|
7350
7508
|
document.body.style.overflow = "hidden";
|
|
@@ -7352,48 +7510,13 @@ function Dialog({
|
|
|
7352
7510
|
document.body.style.overflow = prev;
|
|
7353
7511
|
};
|
|
7354
7512
|
}, [open]);
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
const prevFocused = document.activeElement;
|
|
7359
|
-
const first = node?.querySelector(
|
|
7360
|
-
'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
7361
|
-
);
|
|
7362
|
-
(first || node)?.focus();
|
|
7363
|
-
return () => {
|
|
7364
|
-
if (prevFocused && typeof prevFocused.focus === "function") prevFocused.focus();
|
|
7365
|
-
};
|
|
7366
|
-
}, [open, mounted]);
|
|
7367
|
-
React23__namespace.default.useEffect(() => {
|
|
7368
|
-
if (!open) return;
|
|
7369
|
-
const node = dialogRef.current;
|
|
7370
|
-
const focusables = () => node ? Array.from(
|
|
7371
|
-
node.querySelectorAll(
|
|
7372
|
-
'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
7373
|
-
)
|
|
7374
|
-
).filter((el) => el.offsetParent !== null) : [];
|
|
7513
|
+
useFocusTrap(dialogRef, open && mounted);
|
|
7514
|
+
React24__namespace.default.useEffect(() => {
|
|
7515
|
+
if (!open) return void 0;
|
|
7375
7516
|
const onKey = (e) => {
|
|
7376
7517
|
if (e.key === "Escape") {
|
|
7377
7518
|
e.preventDefault();
|
|
7378
7519
|
onClose?.();
|
|
7379
|
-
return;
|
|
7380
|
-
}
|
|
7381
|
-
if (e.key !== "Tab") return;
|
|
7382
|
-
const f = focusables();
|
|
7383
|
-
if (!f.length) {
|
|
7384
|
-
e.preventDefault();
|
|
7385
|
-
node?.focus();
|
|
7386
|
-
return;
|
|
7387
|
-
}
|
|
7388
|
-
const first = f[0], last = f[f.length - 1], ae = document.activeElement;
|
|
7389
|
-
if (e.shiftKey) {
|
|
7390
|
-
if (ae === first || ae === node || !node.contains(ae)) {
|
|
7391
|
-
e.preventDefault();
|
|
7392
|
-
last.focus();
|
|
7393
|
-
}
|
|
7394
|
-
} else if (ae === last || !node.contains(ae)) {
|
|
7395
|
-
e.preventDefault();
|
|
7396
|
-
first.focus();
|
|
7397
7520
|
}
|
|
7398
7521
|
};
|
|
7399
7522
|
document.addEventListener("keydown", onKey);
|
|
@@ -7417,9 +7540,7 @@ function Dialog({
|
|
|
7417
7540
|
footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dialog__footer", children: footer }) : null
|
|
7418
7541
|
] })
|
|
7419
7542
|
] });
|
|
7420
|
-
|
|
7421
|
-
const RD = typeof reactDom.createPortal === "function" ? reactDom.createPortal : null;
|
|
7422
|
-
return RD ? RD(overlay, document.body) : overlay;
|
|
7543
|
+
return renderPortal(overlay);
|
|
7423
7544
|
}
|
|
7424
7545
|
var DIVIDER_CSS = `
|
|
7425
7546
|
.twc-divider { border: none; background: var(--color-divider); }
|
|
@@ -7434,6 +7555,10 @@ var DIVIDER_CSS = `
|
|
|
7434
7555
|
so ::before/::after land on the correct inline edge under RTL \u2014 no physical override needed. */
|
|
7435
7556
|
.twc-divider-label[data-align="start"]::before { flex: 0 0 var(--space-6); }
|
|
7436
7557
|
.twc-divider-label[data-align="end"]::after { flex: 0 0 var(--space-6); }
|
|
7558
|
+
/* Vertical labeled divider: stack the two segments above/below the label. */
|
|
7559
|
+
.twc-divider-label[data-orientation="vertical"] { flex-direction: column; align-self: stretch; min-height: 1em; margin: 0 var(--space-3); }
|
|
7560
|
+
.twc-divider-label[data-orientation="vertical"]::before,
|
|
7561
|
+
.twc-divider-label[data-orientation="vertical"]::after { width: 1px; height: auto; flex: 1; }
|
|
7437
7562
|
`;
|
|
7438
7563
|
function Divider({
|
|
7439
7564
|
orientation = "horizontal",
|
|
@@ -7446,7 +7571,7 @@ function Divider({
|
|
|
7446
7571
|
const __twcStyles = useScopedStyles("twc-divider-styles", DIVIDER_CSS);
|
|
7447
7572
|
const resolvedAlign = align === "left" ? "start" : align === "right" ? "end" : align;
|
|
7448
7573
|
if (children) {
|
|
7449
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-divider-label ${className}`, "data-align": resolvedAlign, role: "separator", ...rest, children: [
|
|
7574
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-divider-label ${className}`, "data-align": resolvedAlign, "data-orientation": orientation, role: "separator", "aria-orientation": orientation, ...rest, children: [
|
|
7450
7575
|
__twcStyles,
|
|
7451
7576
|
children
|
|
7452
7577
|
] });
|
|
@@ -7533,13 +7658,14 @@ function Drawer({
|
|
|
7533
7658
|
style,
|
|
7534
7659
|
...rest
|
|
7535
7660
|
}) {
|
|
7536
|
-
const autoId =
|
|
7661
|
+
const autoId = React24__namespace.default.useId();
|
|
7537
7662
|
const titleId = `${autoId}-title`;
|
|
7538
7663
|
const descId = `${autoId}-desc`;
|
|
7539
|
-
const panelRef =
|
|
7664
|
+
const panelRef = React24__namespace.default.useRef(null);
|
|
7540
7665
|
const __twcStyles = useScopedStyles("twc-drawer-styles", DRAWER_CSS);
|
|
7541
|
-
const
|
|
7542
|
-
|
|
7666
|
+
const renderPortal = usePortal();
|
|
7667
|
+
const [mounted, setMounted] = React24__namespace.default.useState(open);
|
|
7668
|
+
React24__namespace.default.useEffect(() => {
|
|
7543
7669
|
if (open) {
|
|
7544
7670
|
setMounted(true);
|
|
7545
7671
|
return;
|
|
@@ -7547,7 +7673,7 @@ function Drawer({
|
|
|
7547
7673
|
const t = setTimeout(() => setMounted(false), 170);
|
|
7548
7674
|
return () => clearTimeout(t);
|
|
7549
7675
|
}, [open]);
|
|
7550
|
-
|
|
7676
|
+
React24__namespace.default.useEffect(() => {
|
|
7551
7677
|
if (!open) return void 0;
|
|
7552
7678
|
const prev = document.body.style.overflow;
|
|
7553
7679
|
document.body.style.overflow = "hidden";
|
|
@@ -7555,48 +7681,13 @@ function Drawer({
|
|
|
7555
7681
|
document.body.style.overflow = prev;
|
|
7556
7682
|
};
|
|
7557
7683
|
}, [open]);
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
const prevFocused = document.activeElement;
|
|
7562
|
-
const first = node?.querySelector(
|
|
7563
|
-
'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
7564
|
-
);
|
|
7565
|
-
(first || node)?.focus();
|
|
7566
|
-
return () => {
|
|
7567
|
-
if (prevFocused && typeof prevFocused.focus === "function") prevFocused.focus();
|
|
7568
|
-
};
|
|
7569
|
-
}, [open, mounted]);
|
|
7570
|
-
React23__namespace.default.useEffect(() => {
|
|
7571
|
-
if (!open) return;
|
|
7572
|
-
const node = panelRef.current;
|
|
7573
|
-
const focusables = () => node ? Array.from(
|
|
7574
|
-
node.querySelectorAll(
|
|
7575
|
-
'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
7576
|
-
)
|
|
7577
|
-
).filter((el) => el.offsetParent !== null) : [];
|
|
7684
|
+
useFocusTrap(panelRef, open && mounted);
|
|
7685
|
+
React24__namespace.default.useEffect(() => {
|
|
7686
|
+
if (!open) return void 0;
|
|
7578
7687
|
const onKey = (e) => {
|
|
7579
7688
|
if (e.key === "Escape") {
|
|
7580
7689
|
e.preventDefault();
|
|
7581
7690
|
onClose?.();
|
|
7582
|
-
return;
|
|
7583
|
-
}
|
|
7584
|
-
if (e.key !== "Tab") return;
|
|
7585
|
-
const f = focusables();
|
|
7586
|
-
if (!f.length) {
|
|
7587
|
-
e.preventDefault();
|
|
7588
|
-
node?.focus();
|
|
7589
|
-
return;
|
|
7590
|
-
}
|
|
7591
|
-
const first = f[0], last = f[f.length - 1], ae = document.activeElement;
|
|
7592
|
-
if (e.shiftKey) {
|
|
7593
|
-
if (ae === first || ae === node || !node.contains(ae)) {
|
|
7594
|
-
e.preventDefault();
|
|
7595
|
-
last.focus();
|
|
7596
|
-
}
|
|
7597
|
-
} else if (ae === last || !node.contains(ae)) {
|
|
7598
|
-
e.preventDefault();
|
|
7599
|
-
first.focus();
|
|
7600
7691
|
}
|
|
7601
7692
|
};
|
|
7602
7693
|
document.addEventListener("keydown", onKey);
|
|
@@ -7624,9 +7715,7 @@ function Drawer({
|
|
|
7624
7715
|
footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-drawer__footer", children: footer }) : null
|
|
7625
7716
|
] })
|
|
7626
7717
|
] });
|
|
7627
|
-
|
|
7628
|
-
const RD = typeof reactDom.createPortal === "function" ? reactDom.createPortal : null;
|
|
7629
|
-
return RD ? RD(overlay, document.body) : overlay;
|
|
7718
|
+
return renderPortal(overlay);
|
|
7630
7719
|
}
|
|
7631
7720
|
var EMPTY_CSS = `
|
|
7632
7721
|
.twc-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--space-3);
|
|
@@ -7644,11 +7733,14 @@ function EmptyState({
|
|
|
7644
7733
|
title,
|
|
7645
7734
|
description,
|
|
7646
7735
|
actions,
|
|
7647
|
-
bordered
|
|
7736
|
+
bordered,
|
|
7648
7737
|
border,
|
|
7649
7738
|
className = "",
|
|
7650
7739
|
...rest
|
|
7651
7740
|
}) {
|
|
7741
|
+
if (process.env.NODE_ENV !== "production" && bordered !== void 0 && border === void 0) {
|
|
7742
|
+
warnOnce("EmptyState.bordered", "EmptyState: `bordered` is deprecated and will be removed in 2.0 \u2014 use `border`.");
|
|
7743
|
+
}
|
|
7652
7744
|
const hasBorder = border ?? bordered;
|
|
7653
7745
|
const __twcStyles = useScopedStyles("twc-empty-styles", EMPTY_CSS);
|
|
7654
7746
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-empty ${className}`, "data-bordered": hasBorder || void 0, ...rest, children: [
|
|
@@ -7679,7 +7771,7 @@ function Field({
|
|
|
7679
7771
|
...rest
|
|
7680
7772
|
}) {
|
|
7681
7773
|
const __twcStyles = useScopedStyles("twc-field-styles", FIELD_CSS5);
|
|
7682
|
-
const autoId =
|
|
7774
|
+
const autoId = React24__namespace.default.useId();
|
|
7683
7775
|
const fieldId = id || autoId;
|
|
7684
7776
|
const descId = `${fieldId}-desc`;
|
|
7685
7777
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-field ${className}`, "data-size": size, ...rest, children: [
|
|
@@ -7759,11 +7851,11 @@ function FileUpload({
|
|
|
7759
7851
|
...rest
|
|
7760
7852
|
}) {
|
|
7761
7853
|
const __twcStyles = useScopedStyles("twc-upload-styles", UPLOAD_CSS);
|
|
7762
|
-
const [internal, setInternal] =
|
|
7854
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
7763
7855
|
const files = value !== void 0 ? value : internal;
|
|
7764
|
-
const [drag, setDrag] =
|
|
7765
|
-
const inputRef =
|
|
7766
|
-
const autoId =
|
|
7856
|
+
const [drag, setDrag] = React24__namespace.default.useState(false);
|
|
7857
|
+
const inputRef = React24__namespace.default.useRef(null);
|
|
7858
|
+
const autoId = React24__namespace.default.useId();
|
|
7767
7859
|
const fieldId = id || autoId;
|
|
7768
7860
|
const descId = `${fieldId}-desc`;
|
|
7769
7861
|
const invalid = Boolean(error);
|
|
@@ -7961,19 +8053,20 @@ function Kanban({
|
|
|
7961
8053
|
defaultCards,
|
|
7962
8054
|
onCardMove,
|
|
7963
8055
|
renderCard,
|
|
8056
|
+
getCardLabel,
|
|
7964
8057
|
className = "",
|
|
7965
8058
|
...rest
|
|
7966
8059
|
}) {
|
|
7967
8060
|
const __twcStyles = useScopedStyles("twc-kanban-styles", KANBAN_CSS);
|
|
7968
|
-
const [internal, setInternal] =
|
|
8061
|
+
const [internal, setInternal] = React24__namespace.default.useState(cards ?? defaultCards ?? []);
|
|
7969
8062
|
const items = cards !== void 0 ? cards : internal;
|
|
7970
|
-
const [drag, setDrag] =
|
|
7971
|
-
const [overCol, setOverCol] =
|
|
7972
|
-
const [grab, setGrab] =
|
|
7973
|
-
const [announce, setAnnounce] =
|
|
7974
|
-
const rootRef =
|
|
7975
|
-
const focusIdRef =
|
|
7976
|
-
|
|
8063
|
+
const [drag, setDrag] = React24__namespace.default.useState(null);
|
|
8064
|
+
const [overCol, setOverCol] = React24__namespace.default.useState(null);
|
|
8065
|
+
const [grab, setGrab] = React24__namespace.default.useState(null);
|
|
8066
|
+
const [announce, setAnnounce] = React24__namespace.default.useState("");
|
|
8067
|
+
const rootRef = React24__namespace.default.useRef(null);
|
|
8068
|
+
const focusIdRef = React24__namespace.default.useRef(null);
|
|
8069
|
+
React24__namespace.default.useEffect(() => {
|
|
7977
8070
|
if (focusIdRef.current == null) return void 0;
|
|
7978
8071
|
const raf = requestAnimationFrame(() => {
|
|
7979
8072
|
const id = focusIdRef.current;
|
|
@@ -8025,7 +8118,7 @@ function Kanban({
|
|
|
8025
8118
|
}
|
|
8026
8119
|
};
|
|
8027
8120
|
const keyTargetCol = grab ? columns[grab.targetIdx]?.id : null;
|
|
8028
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-kanban ${className}`, ref: rootRef, ...rest, children: [
|
|
8121
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-kanban ${className}`, ref: rootRef, role: "group", "aria-label": "Board", ...rest, children: [
|
|
8029
8122
|
__twcStyles,
|
|
8030
8123
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-kanban__sr", role: "status", "aria-live": "polite", children: announce }),
|
|
8031
8124
|
columns.map((col, colIdx) => {
|
|
@@ -8035,7 +8128,7 @@ function Kanban({
|
|
|
8035
8128
|
{
|
|
8036
8129
|
className: "twc-kanban__col",
|
|
8037
8130
|
role: "group",
|
|
8038
|
-
"aria-label":
|
|
8131
|
+
"aria-label": col.ariaLabel ?? colTitle(col),
|
|
8039
8132
|
"data-over": overCol === col.id || keyTargetCol === col.id || void 0,
|
|
8040
8133
|
onDragOver: (e) => {
|
|
8041
8134
|
e.preventDefault();
|
|
@@ -8066,6 +8159,8 @@ function Kanban({
|
|
|
8066
8159
|
tabIndex: 0,
|
|
8067
8160
|
"aria-roledescription": "draggable card",
|
|
8068
8161
|
"data-card-id": card.id,
|
|
8162
|
+
"aria-label": getCardLabel?.(card) ?? (typeof card.ariaLabel === "string" ? card.ariaLabel : cardTitle(card)),
|
|
8163
|
+
"aria-pressed": grab && grab.id === card.id || void 0,
|
|
8069
8164
|
"data-grabbed": grab && grab.id === card.id || void 0,
|
|
8070
8165
|
onKeyDown: (e) => handleCardKey(e, card, colIdx),
|
|
8071
8166
|
onBlur: () => {
|
|
@@ -8119,7 +8214,7 @@ var LIST_CSS = `
|
|
|
8119
8214
|
`;
|
|
8120
8215
|
function List({ items, plain = false, className = "", ...rest }) {
|
|
8121
8216
|
const __twcStyles = useScopedStyles("twc-list-styles", LIST_CSS);
|
|
8122
|
-
const
|
|
8217
|
+
const safeHref12 = (url) => {
|
|
8123
8218
|
if (url == null) return void 0;
|
|
8124
8219
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
8125
8220
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -8127,7 +8222,7 @@ function List({ items, plain = false, className = "", ...rest }) {
|
|
|
8127
8222
|
return /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: `twc-list ${className}`, "data-plain": plain || void 0, ...rest, children: [
|
|
8128
8223
|
__twcStyles,
|
|
8129
8224
|
items.map((it, i) => {
|
|
8130
|
-
const href =
|
|
8225
|
+
const href = safeHref12(it.href);
|
|
8131
8226
|
const interactive = Boolean(it.onClick || href);
|
|
8132
8227
|
const Tag2 = href ? "a" : interactive ? "button" : "div";
|
|
8133
8228
|
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -8181,7 +8276,7 @@ button.twc-navbar__brand, a.twc-navbar__brand { cursor: pointer; }
|
|
|
8181
8276
|
.twc-navbar__menu-btn { display: inline-grid; }
|
|
8182
8277
|
}
|
|
8183
8278
|
`;
|
|
8184
|
-
function
|
|
8279
|
+
function safeHref4(url) {
|
|
8185
8280
|
if (url == null) return void 0;
|
|
8186
8281
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
8187
8282
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -8194,16 +8289,19 @@ function Navbar({
|
|
|
8194
8289
|
actions,
|
|
8195
8290
|
sticky = true,
|
|
8196
8291
|
onMenuClick,
|
|
8292
|
+
menuOpen,
|
|
8293
|
+
menuControls,
|
|
8294
|
+
navLabel = "Primary",
|
|
8197
8295
|
className = "",
|
|
8198
8296
|
...rest
|
|
8199
8297
|
}) {
|
|
8200
8298
|
const __twcStyles = useScopedStyles("twc-navbar-styles", NAVBAR_CSS);
|
|
8201
8299
|
return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: `twc-navbar ${className}`, "data-sticky": sticky || void 0, ...rest, children: [
|
|
8202
8300
|
__twcStyles,
|
|
8203
|
-
onMenuClick ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-navbar__menu-btn", "aria-label": "Open menu", onClick: onMenuClick, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 6h16M4 12h16M4 18h16" }) }) }) : null,
|
|
8204
|
-
brand ? brandHref ? /* @__PURE__ */ jsxRuntime.jsx("a", { className: "twc-navbar__brand", href:
|
|
8205
|
-
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "twc-navbar__links", children: links.map((l, i) => {
|
|
8206
|
-
const href =
|
|
8301
|
+
onMenuClick ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-navbar__menu-btn", "aria-expanded": menuOpen, "aria-controls": menuControls, "aria-label": menuOpen ? "Close menu" : "Open menu", onClick: onMenuClick, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 6h16M4 12h16M4 18h16" }) }) }) : null,
|
|
8302
|
+
brand ? brandHref ? /* @__PURE__ */ jsxRuntime.jsx("a", { className: "twc-navbar__brand", href: safeHref4(brandHref), children: brand }) : onBrandClick ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-navbar__brand", onClick: onBrandClick, children: brand }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-navbar__brand", children: brand }) : null,
|
|
8303
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "twc-navbar__links", "aria-label": navLabel, children: links.map((l, i) => {
|
|
8304
|
+
const href = safeHref4(l.href);
|
|
8207
8305
|
const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8208
8306
|
l.icon,
|
|
8209
8307
|
l.label
|
|
@@ -8271,21 +8369,21 @@ function Popover({
|
|
|
8271
8369
|
...rest
|
|
8272
8370
|
}) {
|
|
8273
8371
|
const __twcStyles = useScopedStyles("twc-popover-styles", POPOVER_CSS);
|
|
8274
|
-
const [openState, setOpenState] =
|
|
8275
|
-
const [render, setRender] =
|
|
8276
|
-
const [pos, setPos] =
|
|
8277
|
-
const wrapRef =
|
|
8278
|
-
const popRef =
|
|
8279
|
-
const popId =
|
|
8372
|
+
const [openState, setOpenState] = React24__namespace.default.useState(defaultOpen);
|
|
8373
|
+
const [render, setRender] = React24__namespace.default.useState(false);
|
|
8374
|
+
const [pos, setPos] = React24__namespace.default.useState(null);
|
|
8375
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
8376
|
+
const popRef = React24__namespace.default.useRef(null);
|
|
8377
|
+
const popId = React24__namespace.default.useId();
|
|
8280
8378
|
const controlled = openProp !== void 0;
|
|
8281
8379
|
const open = controlled ? !!openProp : openState;
|
|
8282
|
-
const openRef =
|
|
8380
|
+
const openRef = React24__namespace.default.useRef(open);
|
|
8283
8381
|
openRef.current = open;
|
|
8284
|
-
const controlledRef =
|
|
8382
|
+
const controlledRef = React24__namespace.default.useRef(controlled);
|
|
8285
8383
|
controlledRef.current = controlled;
|
|
8286
|
-
const onOpenChangeRef =
|
|
8384
|
+
const onOpenChangeRef = React24__namespace.default.useRef(onOpenChange);
|
|
8287
8385
|
onOpenChangeRef.current = onOpenChange;
|
|
8288
|
-
const setOpen =
|
|
8386
|
+
const setOpen = React24__namespace.default.useCallback((next) => {
|
|
8289
8387
|
const value = typeof next === "function" ? next(openRef.current) : next;
|
|
8290
8388
|
if (value === openRef.current) return;
|
|
8291
8389
|
if (!controlledRef.current) setOpenState(value);
|
|
@@ -8293,7 +8391,7 @@ function Popover({
|
|
|
8293
8391
|
}, []);
|
|
8294
8392
|
const toggle = () => setOpen((o) => !o);
|
|
8295
8393
|
const RD = { createPortal: typeof reactDom.createPortal === "function" ? reactDom.createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
|
|
8296
|
-
const place =
|
|
8394
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
8297
8395
|
const t = wrapRef.current;
|
|
8298
8396
|
if (!t) return;
|
|
8299
8397
|
const r = t.getBoundingClientRect();
|
|
@@ -8324,7 +8422,7 @@ function Popover({
|
|
|
8324
8422
|
arrow = { top: Math.min(Math.max(cy - top - 5.5, 8), ph - 18), [onRight ? "left" : "right"]: -6 };
|
|
8325
8423
|
setPos({ top, left, width: w, flip: false, arrow });
|
|
8326
8424
|
}, [placement, align, width]);
|
|
8327
|
-
|
|
8425
|
+
React24__namespace.default.useEffect(() => {
|
|
8328
8426
|
if (!open) return;
|
|
8329
8427
|
place();
|
|
8330
8428
|
const onMove = () => place();
|
|
@@ -8347,7 +8445,7 @@ function Popover({
|
|
|
8347
8445
|
document.removeEventListener("keydown", onKey);
|
|
8348
8446
|
};
|
|
8349
8447
|
}, [open, place]);
|
|
8350
|
-
|
|
8448
|
+
React24__namespace.default.useEffect(() => {
|
|
8351
8449
|
if (open) {
|
|
8352
8450
|
setRender(true);
|
|
8353
8451
|
return;
|
|
@@ -8355,12 +8453,12 @@ function Popover({
|
|
|
8355
8453
|
const t = setTimeout(() => setRender(false), 170);
|
|
8356
8454
|
return () => clearTimeout(t);
|
|
8357
8455
|
}, [open]);
|
|
8358
|
-
|
|
8456
|
+
React24__namespace.default.useEffect(() => {
|
|
8359
8457
|
if (render && open) place();
|
|
8360
8458
|
}, [render, place]);
|
|
8361
|
-
const restoreRef =
|
|
8362
|
-
const needFocusRef =
|
|
8363
|
-
|
|
8459
|
+
const restoreRef = React24__namespace.default.useRef(null);
|
|
8460
|
+
const needFocusRef = React24__namespace.default.useRef(false);
|
|
8461
|
+
React24__namespace.default.useEffect(() => {
|
|
8364
8462
|
if (open) {
|
|
8365
8463
|
restoreRef.current = document.activeElement;
|
|
8366
8464
|
needFocusRef.current = true;
|
|
@@ -8371,7 +8469,7 @@ function Popover({
|
|
|
8371
8469
|
needFocusRef.current = false;
|
|
8372
8470
|
if (prev && typeof prev.focus === "function" && popRef.current?.contains(document.activeElement)) prev.focus();
|
|
8373
8471
|
}, [open]);
|
|
8374
|
-
|
|
8472
|
+
React24__namespace.default.useEffect(() => {
|
|
8375
8473
|
if (open && render && pos && needFocusRef.current) {
|
|
8376
8474
|
needFocusRef.current = false;
|
|
8377
8475
|
popRef.current?.focus({ preventScroll: true });
|
|
@@ -8399,7 +8497,7 @@ function Popover({
|
|
|
8399
8497
|
]
|
|
8400
8498
|
}
|
|
8401
8499
|
) : null;
|
|
8402
|
-
const triggerEl =
|
|
8500
|
+
const triggerEl = React24__namespace.default.isValidElement(trigger) ? React24__namespace.default.cloneElement(trigger, {
|
|
8403
8501
|
onClick: (e) => {
|
|
8404
8502
|
trigger.props.onClick?.(e);
|
|
8405
8503
|
toggle();
|
|
@@ -8438,9 +8536,12 @@ function Progress({
|
|
|
8438
8536
|
size = "md",
|
|
8439
8537
|
indeterminate = false,
|
|
8440
8538
|
showLabel = false,
|
|
8539
|
+
label,
|
|
8441
8540
|
className = "",
|
|
8442
8541
|
...rest
|
|
8443
8542
|
}) {
|
|
8543
|
+
const labelId = React24__namespace.default.useId();
|
|
8544
|
+
const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...restProps } = rest;
|
|
8444
8545
|
const __twcStyles = useScopedStyles("twc-progress-styles", `
|
|
8445
8546
|
.twc-progress-wrap { display: flex; flex-direction: column; gap: 6px; font-family: var(--font-sans); }
|
|
8446
8547
|
.twc-progress {
|
|
@@ -8479,14 +8580,14 @@ function Progress({
|
|
|
8479
8580
|
return (
|
|
8480
8581
|
// Single-root contract: className and ...rest (style, id, handlers, …) share the outer
|
|
8481
8582
|
// wrapper; role="progressbar" + aria-value* stay on the inner track.
|
|
8482
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-progress-wrap ${className}`, ...
|
|
8583
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-progress-wrap ${className}`, ...restProps, children: [
|
|
8483
8584
|
__twcStyles,
|
|
8484
|
-
showLabel && !indeterminate ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-progress__meta", children: [
|
|
8485
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Progress" }),
|
|
8486
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
8585
|
+
(showLabel || label != null) && !indeterminate ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-progress__meta", children: [
|
|
8586
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { id: labelId, children: label ?? "Progress" }),
|
|
8587
|
+
showLabel ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
8487
8588
|
Math.round(pct),
|
|
8488
8589
|
"%"
|
|
8489
|
-
] })
|
|
8590
|
+
] }) : null
|
|
8490
8591
|
] }) : null,
|
|
8491
8592
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8492
8593
|
"div",
|
|
@@ -8499,6 +8600,8 @@ function Progress({
|
|
|
8499
8600
|
"aria-valuenow": indeterminate ? void 0 : Math.round(pct),
|
|
8500
8601
|
"aria-valuemin": 0,
|
|
8501
8602
|
"aria-valuemax": 100,
|
|
8603
|
+
"aria-label": ariaLabel,
|
|
8604
|
+
"aria-labelledby": ariaLabelledby ?? (label != null ? labelId : void 0),
|
|
8502
8605
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-progress__bar", style: indeterminate ? void 0 : { width: `${pct}%` } })
|
|
8503
8606
|
}
|
|
8504
8607
|
)
|
|
@@ -8560,7 +8663,7 @@ function Radio({
|
|
|
8560
8663
|
.twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
|
|
8561
8664
|
.twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
|
|
8562
8665
|
`);
|
|
8563
|
-
const autoId =
|
|
8666
|
+
const autoId = React24__namespace.default.useId();
|
|
8564
8667
|
const fieldId = id || autoId;
|
|
8565
8668
|
const errId = `${fieldId}-error`;
|
|
8566
8669
|
const invalid = Boolean(error);
|
|
@@ -8638,12 +8741,12 @@ function Rating({
|
|
|
8638
8741
|
...rest
|
|
8639
8742
|
}) {
|
|
8640
8743
|
const __twcStyles = useScopedStyles("twc-rating-styles", RATING_CSS);
|
|
8641
|
-
const [internal, setInternal] =
|
|
8642
|
-
const [hover, setHover] =
|
|
8744
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
8745
|
+
const [hover, setHover] = React24__namespace.default.useState(0);
|
|
8643
8746
|
const val = value !== void 0 ? value : internal;
|
|
8644
8747
|
const shown = hover || val;
|
|
8645
8748
|
const interactive = !readOnly && !disabled;
|
|
8646
|
-
const btnRefs =
|
|
8749
|
+
const btnRefs = React24__namespace.default.useRef([]);
|
|
8647
8750
|
const tabStar = Math.min(count, Math.max(1, Math.round(val) || 1));
|
|
8648
8751
|
const set = (v) => {
|
|
8649
8752
|
if (!interactive) return;
|
|
@@ -8737,12 +8840,12 @@ function Tooltip({
|
|
|
8737
8840
|
...rest
|
|
8738
8841
|
}) {
|
|
8739
8842
|
const __twcStyles = useScopedStyles("twc-tooltip-styles", TOOLTIP_CSS);
|
|
8740
|
-
const id =
|
|
8741
|
-
const [show, setShow] =
|
|
8742
|
-
const [coords, setCoords] =
|
|
8743
|
-
const timer =
|
|
8744
|
-
const wrapRef =
|
|
8745
|
-
const tipRef =
|
|
8843
|
+
const id = React24__namespace.default.useId();
|
|
8844
|
+
const [show, setShow] = React24__namespace.default.useState(false);
|
|
8845
|
+
const [coords, setCoords] = React24__namespace.default.useState(null);
|
|
8846
|
+
const timer = React24__namespace.default.useRef(null);
|
|
8847
|
+
const wrapRef = React24__namespace.default.useRef(null);
|
|
8848
|
+
const tipRef = React24__namespace.default.useRef(null);
|
|
8746
8849
|
const open = () => {
|
|
8747
8850
|
clearTimeout(timer.current);
|
|
8748
8851
|
timer.current = setTimeout(() => setShow(true), delay);
|
|
@@ -8751,8 +8854,8 @@ function Tooltip({
|
|
|
8751
8854
|
clearTimeout(timer.current);
|
|
8752
8855
|
setShow(false);
|
|
8753
8856
|
};
|
|
8754
|
-
|
|
8755
|
-
const place =
|
|
8857
|
+
React24__namespace.default.useEffect(() => () => clearTimeout(timer.current), []);
|
|
8858
|
+
const place = React24__namespace.default.useCallback(() => {
|
|
8756
8859
|
const el = wrapRef.current;
|
|
8757
8860
|
if (!el) return;
|
|
8758
8861
|
const r = el.getBoundingClientRect();
|
|
@@ -8768,10 +8871,10 @@ function Tooltip({
|
|
|
8768
8871
|
else if (placement === "right") setCoords({ ...base, top: clampY(cy), left: Math.round(r.right + gap) });
|
|
8769
8872
|
else setCoords({ ...base, left: clampX(cx), bottom: Math.round(vh - r.top + gap) });
|
|
8770
8873
|
}, [placement]);
|
|
8771
|
-
|
|
8874
|
+
React24__namespace.default.useEffect(() => {
|
|
8772
8875
|
place();
|
|
8773
8876
|
}, [place]);
|
|
8774
|
-
|
|
8877
|
+
React24__namespace.default.useEffect(() => {
|
|
8775
8878
|
if (!show) return void 0;
|
|
8776
8879
|
place();
|
|
8777
8880
|
const onMove = () => place();
|
|
@@ -8782,7 +8885,7 @@ function Tooltip({
|
|
|
8782
8885
|
window.removeEventListener("resize", onMove);
|
|
8783
8886
|
};
|
|
8784
8887
|
}, [show, place]);
|
|
8785
|
-
|
|
8888
|
+
React24__namespace.default.useEffect(() => {
|
|
8786
8889
|
if (!show) return;
|
|
8787
8890
|
const onKeyDown = (e) => {
|
|
8788
8891
|
if (e.key === "Escape") {
|
|
@@ -8794,7 +8897,7 @@ function Tooltip({
|
|
|
8794
8897
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
8795
8898
|
}, [show]);
|
|
8796
8899
|
const describedBy = show ? id : void 0;
|
|
8797
|
-
const trigger =
|
|
8900
|
+
const trigger = React24__namespace.default.isValidElement(children) && children.type !== React24__namespace.default.Fragment ? React24__namespace.default.cloneElement(children, {
|
|
8798
8901
|
"aria-describedby": [children.props["aria-describedby"], describedBy].filter(Boolean).join(" ") || void 0
|
|
8799
8902
|
}) : /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-describedby": describedBy, children });
|
|
8800
8903
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -8850,6 +8953,7 @@ var SIDEBAR_CSS = `
|
|
|
8850
8953
|
.twc-sidebar__brand { display: inline-flex; align-items: center; gap: var(--space-2-5); font-weight: var(--font-extrabold); font-size: var(--text-lg); letter-spacing: -0.02em; color: var(--color-text); white-space: nowrap; overflow: hidden; min-width: 0;
|
|
8851
8954
|
transition: font-size var(--duration-base) var(--ease-standard), gap var(--duration-base) var(--ease-standard); }
|
|
8852
8955
|
.twc-sidebar__nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: var(--space-3); display: flex; flex-direction: column; gap: 2px; }
|
|
8956
|
+
.twc-sidebar__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
8853
8957
|
.twc-sidebar__section { font-size: 10px; font-weight: var(--font-bold); letter-spacing: var(--tracking-wider); text-transform: uppercase; color: var(--color-text-subtle); padding: var(--space-3) var(--space-3) var(--space-1); white-space: nowrap; overflow: hidden; max-height: 2.5rem; opacity: 1; visibility: visible;
|
|
8854
8958
|
transition: max-height var(--duration-base) var(--ease-standard), padding var(--duration-base) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard) var(--duration-fast), visibility 0s; }
|
|
8855
8959
|
.twc-sidebar[data-collapsed="true"] .twc-sidebar__section { max-height: 0; padding-top: 0; padding-bottom: 0; opacity: 0; visibility: hidden;
|
|
@@ -8891,6 +8995,23 @@ var SIDEBAR_CSS = `
|
|
|
8891
8995
|
.twc-sidebar[data-collapsed="true"] .twc-sidebar__foot { display: flex; flex-direction: column; align-items: center; padding: var(--space-2) 0; }
|
|
8892
8996
|
.twc-sidebar[data-collapsed="true"] .twc-sidebar__collapse { width: auto; padding: 11px; gap: 0; margin: 0; }
|
|
8893
8997
|
.twc-sidebar[data-collapsed="true"] .twc-sidebar__collapse span { display: none; }
|
|
8998
|
+
|
|
8999
|
+
/* Off-canvas overlay mode (mobile): the rail becomes a slide-over drawer behind a
|
|
9000
|
+
scrim, mirroring Drawer.jsx. Logical inset + a --_off var slide it in from the
|
|
9001
|
+
inline-start edge (mirrored under dir="rtl"). */
|
|
9002
|
+
.twc-sidebar__overlay { position: fixed; inset: 0; z-index: var(--z-modal); background: var(--color-overlay); backdrop-filter: blur(2px); }
|
|
9003
|
+
.twc-sidebar__overlay[data-state="open"] { animation: twico-fade-in var(--duration-base) var(--ease-out); }
|
|
9004
|
+
.twc-sidebar__overlay[data-state="closed"] { animation: twc-sidebar-fade-out var(--duration-exit) var(--ease-in) forwards; pointer-events: none; }
|
|
9005
|
+
@keyframes twc-sidebar-fade-out { from { opacity: 1; } to { opacity: 0; } }
|
|
9006
|
+
.twc-sidebar--overlay { position: fixed; inset-block: 0; inset-inline-start: 0; height: 100%; max-width: 92vw; z-index: var(--z-modal); box-shadow: var(--shadow-xl); --_off: -100%; }
|
|
9007
|
+
[dir="rtl"] .twc-sidebar--overlay { inset-inline-start: auto; inset-inline-end: 0; --_off: 100%; }
|
|
9008
|
+
.twc-sidebar--overlay[data-state="open"] { animation: twc-sidebar-in var(--duration-base) var(--ease-out); }
|
|
9009
|
+
.twc-sidebar--overlay[data-state="closed"] { animation: twc-sidebar-out var(--duration-exit) var(--ease-in) forwards; }
|
|
9010
|
+
@keyframes twc-sidebar-in { from { transform: translateX(var(--_off)); } to { transform: translateX(0); } }
|
|
9011
|
+
@keyframes twc-sidebar-out { from { transform: translateX(0); } to { transform: translateX(var(--_off)); } }
|
|
9012
|
+
@media (prefers-reduced-motion: reduce) {
|
|
9013
|
+
.twc-sidebar__overlay[data-state], .twc-sidebar--overlay[data-state] { animation-duration: 1ms; }
|
|
9014
|
+
}
|
|
8894
9015
|
`;
|
|
8895
9016
|
function Sidebar({
|
|
8896
9017
|
brand,
|
|
@@ -8900,63 +9021,149 @@ function Sidebar({
|
|
|
8900
9021
|
defaultCollapsed = false,
|
|
8901
9022
|
collapsible = true,
|
|
8902
9023
|
onCollapsedChange,
|
|
9024
|
+
overlay = false,
|
|
9025
|
+
open: openProp,
|
|
9026
|
+
defaultOpen = false,
|
|
9027
|
+
onOpenChange,
|
|
9028
|
+
navLabel = "Main",
|
|
8903
9029
|
className = "",
|
|
8904
9030
|
...rest
|
|
8905
9031
|
}) {
|
|
8906
9032
|
const __twcStyles = useScopedStyles("twc-sidebar-styles", SIDEBAR_CSS);
|
|
8907
|
-
const
|
|
9033
|
+
const navId = React24__namespace.default.useId();
|
|
9034
|
+
const panelRef = React24__namespace.default.useRef(null);
|
|
9035
|
+
const renderPortal = usePortal();
|
|
9036
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultCollapsed);
|
|
8908
9037
|
const collapsed = collapsedProp !== void 0 ? collapsedProp : internal;
|
|
8909
9038
|
const toggle = () => {
|
|
8910
9039
|
const next = !collapsed;
|
|
8911
9040
|
if (collapsedProp === void 0) setInternal(next);
|
|
8912
9041
|
onCollapsedChange?.(next);
|
|
8913
9042
|
};
|
|
8914
|
-
const
|
|
9043
|
+
const [openInternal, setOpenInternal] = React24__namespace.default.useState(defaultOpen);
|
|
9044
|
+
const open = openProp !== void 0 ? openProp : openInternal;
|
|
9045
|
+
const setOpen = (next) => {
|
|
9046
|
+
if (openProp === void 0) setOpenInternal(next);
|
|
9047
|
+
onOpenChange?.(next);
|
|
9048
|
+
};
|
|
9049
|
+
const [mounted, setMounted] = React24__namespace.default.useState(open);
|
|
9050
|
+
React24__namespace.default.useEffect(() => {
|
|
9051
|
+
if (!overlay) return void 0;
|
|
9052
|
+
if (open) {
|
|
9053
|
+
setMounted(true);
|
|
9054
|
+
return void 0;
|
|
9055
|
+
}
|
|
9056
|
+
const t = setTimeout(() => setMounted(false), 170);
|
|
9057
|
+
return () => clearTimeout(t);
|
|
9058
|
+
}, [overlay, open]);
|
|
9059
|
+
React24__namespace.default.useEffect(() => {
|
|
9060
|
+
if (!overlay || !open) return void 0;
|
|
9061
|
+
const prev = document.body.style.overflow;
|
|
9062
|
+
document.body.style.overflow = "hidden";
|
|
9063
|
+
return () => {
|
|
9064
|
+
document.body.style.overflow = prev;
|
|
9065
|
+
};
|
|
9066
|
+
}, [overlay, open]);
|
|
9067
|
+
useFocusTrap(panelRef, overlay && open && mounted);
|
|
9068
|
+
React24__namespace.default.useEffect(() => {
|
|
9069
|
+
if (!overlay || !open) return void 0;
|
|
9070
|
+
const onKey = (e) => {
|
|
9071
|
+
if (e.key === "Escape") {
|
|
9072
|
+
e.preventDefault();
|
|
9073
|
+
if (openProp === void 0) setOpenInternal(false);
|
|
9074
|
+
onOpenChange?.(false);
|
|
9075
|
+
}
|
|
9076
|
+
};
|
|
9077
|
+
document.addEventListener("keydown", onKey);
|
|
9078
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
9079
|
+
}, [overlay, open, openProp, onOpenChange]);
|
|
9080
|
+
const safeHref12 = (url) => {
|
|
8915
9081
|
if (url == null) return void 0;
|
|
8916
9082
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
8917
9083
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
8918
9084
|
};
|
|
8919
|
-
|
|
9085
|
+
const renderItem = (it, i) => {
|
|
9086
|
+
const href = safeHref12(it.href);
|
|
9087
|
+
const labelStr = typeof it.label === "string" ? it.label : void 0;
|
|
9088
|
+
const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
9089
|
+
it.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__ic", "aria-hidden": "true", children: it.icon }) : labelStr != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__ic twc-sidebar__ic--initial", "aria-hidden": "true", children: labelStr.charAt(0) }) : null,
|
|
9090
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__label", children: it.label }),
|
|
9091
|
+
it.badge != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__badge", children: it.badge }) : null
|
|
9092
|
+
] });
|
|
9093
|
+
const common = {
|
|
9094
|
+
className: "twc-sidebar__item",
|
|
9095
|
+
"data-active": it.active || void 0,
|
|
9096
|
+
"aria-current": it.active ? "page" : void 0,
|
|
9097
|
+
onClick: it.onClick,
|
|
9098
|
+
"aria-label": collapsed && labelStr != null ? labelStr : void 0
|
|
9099
|
+
};
|
|
9100
|
+
const node = href != null ? /* @__PURE__ */ jsxRuntime.jsx("a", { href, ...common, children: inner }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", ...common, children: inner });
|
|
9101
|
+
return collapsed && labelStr != null ? /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { label: labelStr, placement: "right", style: { display: "block" }, children: node }) : node;
|
|
9102
|
+
};
|
|
9103
|
+
const groups = [];
|
|
9104
|
+
let group = { sid: null, section: null, entries: [] };
|
|
9105
|
+
let secN = 0;
|
|
9106
|
+
for (let i = 0; i < items.length; i++) {
|
|
9107
|
+
const it = items[i];
|
|
9108
|
+
if (it.section) {
|
|
9109
|
+
if (group.entries.length || group.section != null) groups.push(group);
|
|
9110
|
+
secN += 1;
|
|
9111
|
+
group = { sid: `${navId}-sec-${secN}`, section: it.section, entries: [] };
|
|
9112
|
+
} else {
|
|
9113
|
+
group.entries.push({ it, i });
|
|
9114
|
+
}
|
|
9115
|
+
}
|
|
9116
|
+
if (group.entries.length || group.section != null) groups.push(group);
|
|
9117
|
+
const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8920
9118
|
__twcStyles,
|
|
8921
9119
|
brand ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-sidebar__head", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__brand", children: brand }) }) : null,
|
|
8922
|
-
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "twc-sidebar__nav", children:
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8927
|
-
it.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__ic", "aria-hidden": "true", children: it.icon }) : labelStr != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__ic twc-sidebar__ic--initial", "aria-hidden": "true", children: labelStr.charAt(0) }) : null,
|
|
8928
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__label", children: it.label }),
|
|
8929
|
-
it.badge != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__badge", children: it.badge }) : null
|
|
8930
|
-
] });
|
|
8931
|
-
const common = {
|
|
8932
|
-
className: "twc-sidebar__item",
|
|
8933
|
-
"data-active": it.active || void 0,
|
|
8934
|
-
"aria-current": it.active ? "page" : void 0,
|
|
8935
|
-
onClick: it.onClick,
|
|
8936
|
-
"aria-label": collapsed && labelStr != null ? labelStr : void 0
|
|
8937
|
-
};
|
|
8938
|
-
const node = href != null ? /* @__PURE__ */ jsxRuntime.jsx("a", { href, ...common, children: inner }, i) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", ...common, children: inner }, i);
|
|
8939
|
-
return collapsed && labelStr != null ? /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { label: labelStr, placement: "right", style: { display: "block" }, children: node }, i) : node;
|
|
8940
|
-
})()
|
|
8941
|
-
) }),
|
|
9120
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { id: navId, className: "twc-sidebar__nav", "aria-label": navLabel, children: groups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React24__namespace.default.Fragment, { children: [
|
|
9121
|
+
g.section != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-sidebar__section", id: g.sid, children: g.section }) : null,
|
|
9122
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "twc-sidebar__list", ...g.section != null ? { "aria-labelledby": g.sid } : {}, children: g.entries.map(({ it, i }) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: renderItem(it) }, i)) })
|
|
9123
|
+
] }, gi)) }),
|
|
8942
9124
|
footer || collapsible ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-sidebar__foot", children: [
|
|
8943
9125
|
footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-sidebar__foot-user", children: footer }) : null,
|
|
8944
|
-
collapsible ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "twc-sidebar__collapse", onClick: toggle, "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar", children: [
|
|
9126
|
+
collapsible ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "twc-sidebar__collapse", onClick: toggle, "aria-expanded": !collapsed, "aria-controls": navId, "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar", children: [
|
|
8945
9127
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m15 18-6-6 6-6" }) }),
|
|
8946
9128
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Collapse" })
|
|
8947
9129
|
] }) : null
|
|
8948
9130
|
] }) : null
|
|
8949
9131
|
] });
|
|
9132
|
+
if (!overlay) {
|
|
9133
|
+
return /* @__PURE__ */ jsxRuntime.jsx("aside", { className: `twc-sidebar ${className}`, "data-collapsed": collapsed || void 0, ...rest, children: body });
|
|
9134
|
+
}
|
|
9135
|
+
if (!mounted) return null;
|
|
9136
|
+
const state = open ? "open" : "closed";
|
|
9137
|
+
const drawer = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-sidebar__overlay", "data-state": state, onMouseDown: (e) => {
|
|
9138
|
+
if (e.target === e.currentTarget) setOpen(false);
|
|
9139
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9140
|
+
"aside",
|
|
9141
|
+
{
|
|
9142
|
+
ref: panelRef,
|
|
9143
|
+
className: `twc-sidebar twc-sidebar--overlay ${className}`,
|
|
9144
|
+
"data-state": state,
|
|
9145
|
+
"data-collapsed": collapsed || void 0,
|
|
9146
|
+
role: "dialog",
|
|
9147
|
+
"aria-modal": "true",
|
|
9148
|
+
tabIndex: -1,
|
|
9149
|
+
"aria-label": navLabel || "Navigation",
|
|
9150
|
+
...rest,
|
|
9151
|
+
children: body
|
|
9152
|
+
}
|
|
9153
|
+
) });
|
|
9154
|
+
return renderPortal(drawer);
|
|
8950
9155
|
}
|
|
8951
9156
|
function Skeleton({
|
|
8952
9157
|
variant = "text",
|
|
8953
9158
|
width,
|
|
8954
9159
|
height,
|
|
8955
9160
|
lines = 1,
|
|
9161
|
+
label,
|
|
8956
9162
|
className = "",
|
|
8957
9163
|
style,
|
|
8958
9164
|
...rest
|
|
8959
9165
|
}) {
|
|
9166
|
+
const a11y = label != null ? { role: "status", "aria-live": "polite", "aria-busy": true } : { "aria-hidden": true };
|
|
8960
9167
|
const __twcStyles = useScopedStyles("twc-skeleton-styles", `
|
|
8961
9168
|
.twc-skeleton {
|
|
8962
9169
|
position: relative; overflow: hidden;
|
|
@@ -8972,25 +9179,31 @@ function Skeleton({
|
|
|
8972
9179
|
.twc-skeleton[data-variant="rect"] { border-radius: var(--radius-md); }
|
|
8973
9180
|
.twc-skeleton__group { display: flex; flex-direction: column; gap: 8px; }
|
|
8974
9181
|
.twc-skeleton__group .twc-skeleton:last-child { width: 70%; }
|
|
9182
|
+
.twc-skeleton__sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
8975
9183
|
/* The shimmer signals loading \u2014 keep it animating even under reduced motion. */
|
|
8976
9184
|
@media (prefers-reduced-motion: reduce) {
|
|
8977
9185
|
.twc-skeleton::after { animation-duration: 1.4s !important; animation-iteration-count: infinite !important; }
|
|
8978
9186
|
}
|
|
8979
9187
|
`);
|
|
8980
9188
|
if (variant === "text" && lines > 1) {
|
|
8981
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-skeleton__group ${className}`, style: { height, ...style }, ...rest, children: [
|
|
9189
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-skeleton__group ${className}`, style: { height, ...style }, ...a11y, ...rest, children: [
|
|
8982
9190
|
__twcStyles,
|
|
9191
|
+
label != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-skeleton__sr", children: label }) : null,
|
|
8983
9192
|
Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-skeleton", "data-variant": "text", style: { width: width || "100%" } }, i))
|
|
8984
9193
|
] });
|
|
8985
9194
|
}
|
|
8986
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
9195
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8987
9196
|
"span",
|
|
8988
9197
|
{
|
|
8989
9198
|
className: `twc-skeleton ${className}`,
|
|
8990
9199
|
"data-variant": variant,
|
|
8991
9200
|
style: { width, height, ...style },
|
|
9201
|
+
...a11y,
|
|
8992
9202
|
...rest,
|
|
8993
|
-
children:
|
|
9203
|
+
children: [
|
|
9204
|
+
__twcStyles,
|
|
9205
|
+
label != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-skeleton__sr", children: label }) : null
|
|
9206
|
+
]
|
|
8994
9207
|
}
|
|
8995
9208
|
);
|
|
8996
9209
|
}
|
|
@@ -9057,12 +9270,12 @@ function Slider({
|
|
|
9057
9270
|
const max = Number.isFinite(maxProp) && maxProp > min ? maxProp : min + 1;
|
|
9058
9271
|
const step = Number.isFinite(stepProp) && stepProp > 0 ? stepProp : 1;
|
|
9059
9272
|
const __twcStyles = useScopedStyles("twc-slider-styles", SLIDER_CSS);
|
|
9060
|
-
const autoId =
|
|
9273
|
+
const autoId = React24__namespace.default.useId();
|
|
9061
9274
|
const fieldId = id || autoId;
|
|
9062
|
-
const [internal, setInternal] =
|
|
9275
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue);
|
|
9063
9276
|
const val = value !== void 0 ? value : internal;
|
|
9064
|
-
const trackRef =
|
|
9065
|
-
const [dragging, setDragging] =
|
|
9277
|
+
const trackRef = React24__namespace.default.useRef(null);
|
|
9278
|
+
const [dragging, setDragging] = React24__namespace.default.useState(false);
|
|
9066
9279
|
const pct = (val - min) / (max - min) * 100;
|
|
9067
9280
|
const fmt = (v) => formatValue ? formatValue(v) : v;
|
|
9068
9281
|
const clampSnap = (raw) => {
|
|
@@ -9080,8 +9293,8 @@ function Slider({
|
|
|
9080
9293
|
const ratio = Math.min(1, Math.max(0, (clientX - r.left) / r.width));
|
|
9081
9294
|
return clampSnap(min + ratio * (max - min));
|
|
9082
9295
|
};
|
|
9083
|
-
const dragCleanupRef =
|
|
9084
|
-
|
|
9296
|
+
const dragCleanupRef = React24__namespace.default.useRef(null);
|
|
9297
|
+
React24__namespace.default.useEffect(() => () => dragCleanupRef.current?.(), []);
|
|
9085
9298
|
function onPointerDown(e) {
|
|
9086
9299
|
if (disabled) return;
|
|
9087
9300
|
e.preventDefault();
|
|
@@ -9156,12 +9369,15 @@ function Slider({
|
|
|
9156
9369
|
function Spinner({
|
|
9157
9370
|
size = "md",
|
|
9158
9371
|
color,
|
|
9159
|
-
tone
|
|
9372
|
+
tone,
|
|
9160
9373
|
label = "Loading",
|
|
9161
9374
|
className = "",
|
|
9162
9375
|
...rest
|
|
9163
9376
|
}) {
|
|
9164
|
-
|
|
9377
|
+
if (process.env.NODE_ENV !== "production" && tone !== void 0 && color === void 0) {
|
|
9378
|
+
warnOnce("Spinner.tone", "Spinner: `tone` is deprecated and will be removed in 2.0 \u2014 use `color`.");
|
|
9379
|
+
}
|
|
9380
|
+
const resolvedColor = color ?? tone ?? "current";
|
|
9165
9381
|
const __twcStyles = useScopedStyles("twc-spinner-styles", `
|
|
9166
9382
|
.twc-spinner {
|
|
9167
9383
|
--_sz: 24px; --_bw: 2.5px;
|
|
@@ -9277,6 +9493,7 @@ var STEPPER_CSS = `
|
|
|
9277
9493
|
.twc-stepper[data-orientation="vertical"] .twc-step__col { display: flex; flex-direction: column; align-items: center; }
|
|
9278
9494
|
.twc-step[data-state="complete"] .twc-step__connector, .twc-step[data-state="active"] .twc-step__connector { background: var(--_accent); }
|
|
9279
9495
|
.twc-stepper[data-orientation="vertical"] .twc-step__vbody { padding-bottom: var(--space-2); }
|
|
9496
|
+
.twc-step__sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
9280
9497
|
`;
|
|
9281
9498
|
var CheckIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) });
|
|
9282
9499
|
var BangIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 8v5M12 17h.01" }) });
|
|
@@ -9292,7 +9509,7 @@ function Stepper({
|
|
|
9292
9509
|
...rest
|
|
9293
9510
|
}) {
|
|
9294
9511
|
const __twcStyles = useScopedStyles("twc-stepper-styles", STEPPER_CSS);
|
|
9295
|
-
const [activeInternal, setActiveInternal] =
|
|
9512
|
+
const [activeInternal, setActiveInternal] = React24__namespace.default.useState(defaultActive);
|
|
9296
9513
|
const active = activeProp !== void 0 ? activeProp : activeInternal;
|
|
9297
9514
|
const handleStep = (i) => {
|
|
9298
9515
|
if (activeProp === void 0) setActiveInternal(i);
|
|
@@ -9304,11 +9521,12 @@ function Stepper({
|
|
|
9304
9521
|
if (i === active) return "active";
|
|
9305
9522
|
return "upcoming";
|
|
9306
9523
|
};
|
|
9307
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-stepper ${className}`, "data-orientation": orientation, "data-tone": tone, ...rest, children: [
|
|
9524
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-stepper ${className}`, "data-orientation": orientation, "data-tone": tone, role: "group", "aria-label": "Progress", ...rest, children: [
|
|
9308
9525
|
__twcStyles,
|
|
9309
9526
|
steps.map((step, i) => {
|
|
9310
9527
|
const state = stateOf(i, step);
|
|
9311
9528
|
const last = i === steps.length - 1;
|
|
9529
|
+
const srText = `Step ${i + 1} of ${steps.length}${state === "complete" ? ", completed" : state === "error" ? ", error" : state === "active" ? ", current" : ", upcoming"}. `;
|
|
9312
9530
|
const isClickable = clickable && i <= active;
|
|
9313
9531
|
const interactive = isClickable ? {
|
|
9314
9532
|
role: "button",
|
|
@@ -9330,8 +9548,10 @@ function Stepper({
|
|
|
9330
9548
|
"data-state": state,
|
|
9331
9549
|
"data-clickable": isClickable || void 0,
|
|
9332
9550
|
"aria-current": state === "active" ? "step" : void 0,
|
|
9551
|
+
"aria-invalid": state === "error" ? "true" : void 0,
|
|
9333
9552
|
...interactive,
|
|
9334
9553
|
children: [
|
|
9554
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-step__sr", children: srText }),
|
|
9335
9555
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-step__col", children: [
|
|
9336
9556
|
indicator,
|
|
9337
9557
|
!last ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-step__connector" }) : null
|
|
@@ -9352,8 +9572,10 @@ function Stepper({
|
|
|
9352
9572
|
"data-state": state,
|
|
9353
9573
|
"data-clickable": isClickable || void 0,
|
|
9354
9574
|
"aria-current": state === "active" ? "step" : void 0,
|
|
9575
|
+
"aria-invalid": state === "error" ? "true" : void 0,
|
|
9355
9576
|
...interactive,
|
|
9356
9577
|
children: [
|
|
9578
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-step__sr", children: srText }),
|
|
9357
9579
|
indicator,
|
|
9358
9580
|
!last ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-step__connector" }) : null,
|
|
9359
9581
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-step__body", children: [
|
|
@@ -9419,7 +9641,7 @@ function Switch({
|
|
|
9419
9641
|
.twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
|
|
9420
9642
|
.twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
|
|
9421
9643
|
`);
|
|
9422
|
-
const autoId =
|
|
9644
|
+
const autoId = React24__namespace.default.useId();
|
|
9423
9645
|
const fieldId = id || autoId;
|
|
9424
9646
|
const errId = `${fieldId}-error`;
|
|
9425
9647
|
const invalid = Boolean(error);
|
|
@@ -9503,14 +9725,14 @@ function Table({
|
|
|
9503
9725
|
...rest
|
|
9504
9726
|
}) {
|
|
9505
9727
|
const __twcStyles = useScopedStyles("twc-table-styles", TABLE_CSS);
|
|
9506
|
-
const cols =
|
|
9728
|
+
const cols = React24__namespace.default.useMemo(
|
|
9507
9729
|
() => (columns || []).map((c) => ({ ...c, header: c.headerName, render: c.renderCell })),
|
|
9508
9730
|
[columns]
|
|
9509
9731
|
);
|
|
9510
9732
|
const dataRows = rowsProp || [];
|
|
9511
|
-
const [internalSort, setInternalSort] =
|
|
9733
|
+
const [internalSort, setInternalSort] = React24__namespace.default.useState(defaultSort || { field: null, dir: "asc" });
|
|
9512
9734
|
const sort = (sortProp !== void 0 ? sortProp : internalSort) || { field: null, dir: "asc" };
|
|
9513
|
-
const rows =
|
|
9735
|
+
const rows = React24__namespace.default.useMemo(() => {
|
|
9514
9736
|
if (!sortable || !sort.field) return dataRows;
|
|
9515
9737
|
const col = cols.find((c) => c.field === sort.field);
|
|
9516
9738
|
if (!col) return dataRows;
|
|
@@ -9602,6 +9824,13 @@ var TABS_CSS = `
|
|
|
9602
9824
|
.twc-tabs[data-variant="pill"] .twc-tabs__indicator {
|
|
9603
9825
|
top: 4px; bottom: 4px; height: auto; background: var(--color-surface); box-shadow: var(--shadow-sm); border-radius: var(--radius-md);
|
|
9604
9826
|
}
|
|
9827
|
+
.twc-tab[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }
|
|
9828
|
+
/* Horizontal tablist scrolls when tabs overflow (vertical orientation untouched). Making
|
|
9829
|
+
overflow-x non-visible makes overflow-y compute to auto, which would clip the bottom:-1px
|
|
9830
|
+
indicator \u2014 so pin the horizontal indicator to bottom:0 (the list border-bottom is the baseline). */
|
|
9831
|
+
.twc-tabs:not([data-orientation="vertical"]) .twc-tabs__list { overflow-x: auto; scrollbar-width: none; }
|
|
9832
|
+
.twc-tabs:not([data-orientation="vertical"]) .twc-tabs__list::-webkit-scrollbar { display: none; }
|
|
9833
|
+
.twc-tabs:not([data-orientation="vertical"]) .twc-tabs__indicator { bottom: 0; }
|
|
9605
9834
|
.twc-tabs__panel { padding-top: var(--space-4); }
|
|
9606
9835
|
|
|
9607
9836
|
/* Vertical orientation */
|
|
@@ -9636,24 +9865,27 @@ function Tabs({
|
|
|
9636
9865
|
}) {
|
|
9637
9866
|
const vertical = orientation === "vertical";
|
|
9638
9867
|
const __twcStyles = useScopedStyles("twc-tabs-styles", TABS_CSS);
|
|
9639
|
-
const [internal, setInternal] =
|
|
9868
|
+
const [internal, setInternal] = React24__namespace.default.useState(defaultValue ?? items[0]?.value);
|
|
9640
9869
|
const active = value ?? internal;
|
|
9641
|
-
const listRef =
|
|
9642
|
-
const [ind, setInd] =
|
|
9643
|
-
const baseId =
|
|
9870
|
+
const listRef = React24__namespace.default.useRef(null);
|
|
9871
|
+
const [ind, setInd] = React24__namespace.default.useState({ left: 0, width: 0, top: 0, height: 0 });
|
|
9872
|
+
const baseId = React24__namespace.default.useId();
|
|
9644
9873
|
const tabIdAt = (i) => `${baseId}-tab-${i}`;
|
|
9645
9874
|
const panelId = `${baseId}-panel`;
|
|
9646
9875
|
const activeIndex = items.findIndex((it) => it.value === active);
|
|
9647
|
-
const updateIndicator =
|
|
9876
|
+
const updateIndicator = React24__namespace.default.useCallback(() => {
|
|
9648
9877
|
const list = listRef.current;
|
|
9649
9878
|
if (!list) return;
|
|
9650
9879
|
const el = list.querySelector('[data-active="true"]');
|
|
9651
|
-
if (el)
|
|
9652
|
-
|
|
9653
|
-
|
|
9880
|
+
if (el) {
|
|
9881
|
+
setInd({ left: el.offsetLeft, width: el.offsetWidth, top: el.offsetTop, height: el.offsetHeight });
|
|
9882
|
+
if (!vertical) el.scrollIntoView?.({ inline: "nearest", block: "nearest" });
|
|
9883
|
+
}
|
|
9884
|
+
}, [vertical]);
|
|
9885
|
+
React24__namespace.default.useEffect(() => {
|
|
9654
9886
|
updateIndicator();
|
|
9655
9887
|
}, [active, updateIndicator, items, orientation]);
|
|
9656
|
-
|
|
9888
|
+
React24__namespace.default.useEffect(() => {
|
|
9657
9889
|
const r = () => updateIndicator();
|
|
9658
9890
|
window.addEventListener("resize", r);
|
|
9659
9891
|
if (typeof document !== "undefined" && document.fonts && document.fonts.ready) {
|
|
@@ -9674,20 +9906,32 @@ function Tabs({
|
|
|
9674
9906
|
const keys = [prevKey, nextKey, "Home", "End"];
|
|
9675
9907
|
if (!keys.includes(e.key)) return;
|
|
9676
9908
|
const n = items.length;
|
|
9677
|
-
if (!n) return;
|
|
9909
|
+
if (!n || items.every((it2) => it2.disabled)) return;
|
|
9678
9910
|
e.preventDefault();
|
|
9679
9911
|
let i = activeIndex < 0 ? 0 : activeIndex;
|
|
9680
|
-
if (e.key === "Home") i =
|
|
9681
|
-
else if (e.key === "End")
|
|
9682
|
-
|
|
9912
|
+
if (e.key === "Home") i = items.findIndex((it2) => !it2.disabled);
|
|
9913
|
+
else if (e.key === "End") {
|
|
9914
|
+
for (let k = n - 1; k >= 0; k--) {
|
|
9915
|
+
if (!items[k].disabled) {
|
|
9916
|
+
i = k;
|
|
9917
|
+
break;
|
|
9918
|
+
}
|
|
9919
|
+
}
|
|
9920
|
+
} else {
|
|
9683
9921
|
const dir = e.key === nextKey ? 1 : -1;
|
|
9684
|
-
|
|
9922
|
+
let guard = 0;
|
|
9923
|
+
do {
|
|
9924
|
+
i = (i + dir + n) % n;
|
|
9925
|
+
} while (items[i]?.disabled && ++guard <= n);
|
|
9685
9926
|
}
|
|
9686
9927
|
const it = items[i];
|
|
9687
|
-
if (!it) return;
|
|
9928
|
+
if (!it || it.disabled) return;
|
|
9688
9929
|
select(it.value);
|
|
9689
9930
|
const btns = listRef.current?.querySelectorAll('[role="tab"]');
|
|
9690
|
-
if (btns && btns[i])
|
|
9931
|
+
if (btns && btns[i]) {
|
|
9932
|
+
btns[i].focus();
|
|
9933
|
+
btns[i].scrollIntoView?.({ inline: "nearest", block: "nearest" });
|
|
9934
|
+
}
|
|
9691
9935
|
}
|
|
9692
9936
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-tabs ${className}`, "data-variant": variant, "data-tone": tone, "data-orientation": orientation, ...rest, children: [
|
|
9693
9937
|
__twcStyles,
|
|
@@ -9700,10 +9944,14 @@ function Tabs({
|
|
|
9700
9944
|
className: "twc-tab",
|
|
9701
9945
|
role: "tab",
|
|
9702
9946
|
"aria-selected": it.value === active,
|
|
9947
|
+
"aria-disabled": it.disabled || void 0,
|
|
9948
|
+
disabled: it.disabled || void 0,
|
|
9703
9949
|
"aria-controls": it.value === active && panelRendered ? panelId : void 0,
|
|
9704
|
-
tabIndex: it.value === active ? 0 : -1,
|
|
9950
|
+
tabIndex: it.value === active && !it.disabled ? 0 : -1,
|
|
9705
9951
|
"data-active": it.value === active || void 0,
|
|
9706
|
-
onClick: () =>
|
|
9952
|
+
onClick: () => {
|
|
9953
|
+
if (!it.disabled) select(it.value);
|
|
9954
|
+
},
|
|
9707
9955
|
children: [
|
|
9708
9956
|
it.icon,
|
|
9709
9957
|
it.label,
|
|
@@ -9766,10 +10014,12 @@ function Tag({
|
|
|
9766
10014
|
leftIcon,
|
|
9767
10015
|
tone = "neutral",
|
|
9768
10016
|
variant = "soft",
|
|
10017
|
+
removeLabel,
|
|
9769
10018
|
className = "",
|
|
9770
10019
|
...rest
|
|
9771
10020
|
}) {
|
|
9772
10021
|
const __twcStyles = useScopedStyles("twc-tag-styles", TAG_CSS);
|
|
10022
|
+
const _removeLabel = removeLabel ?? (typeof children === "string" ? `Remove ${children}` : "Remove");
|
|
9773
10023
|
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `twc-tag ${className}`, "data-tone": tone, "data-variant": variant, "data-no-remove": !onRemove || void 0, ...rest, children: [
|
|
9774
10024
|
__twcStyles,
|
|
9775
10025
|
leftIcon,
|
|
@@ -9777,7 +10027,7 @@ function Tag({
|
|
|
9777
10027
|
onRemove ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-tag__remove", onClick: (e) => {
|
|
9778
10028
|
e.stopPropagation();
|
|
9779
10029
|
onRemove(e);
|
|
9780
|
-
}, "aria-label":
|
|
10030
|
+
}, "aria-label": _removeLabel, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
|
|
9781
10031
|
] });
|
|
9782
10032
|
}
|
|
9783
10033
|
function Textarea({
|
|
@@ -9823,7 +10073,7 @@ function Textarea({
|
|
|
9823
10073
|
.twc-textarea__el[aria-invalid="true"] { border-color: var(--color-danger); }
|
|
9824
10074
|
.twc-textarea__el:disabled { background: var(--color-surface-sunken); opacity: 0.7; cursor: not-allowed; }
|
|
9825
10075
|
`);
|
|
9826
|
-
const autoId =
|
|
10076
|
+
const autoId = React24__namespace.default.useId();
|
|
9827
10077
|
const fieldId = id || autoId;
|
|
9828
10078
|
const descId = `${fieldId}-desc`;
|
|
9829
10079
|
const invalid = Boolean(error);
|
|
@@ -9961,19 +10211,19 @@ function Toast({
|
|
|
9961
10211
|
}) {
|
|
9962
10212
|
const resolvedTone = tone === "neutral" ? "default" : tone;
|
|
9963
10213
|
const __twcStyles = useScopedStyles("twc-toast-styles", TOAST_CSS);
|
|
9964
|
-
const onCloseRef =
|
|
9965
|
-
|
|
10214
|
+
const onCloseRef = React24__namespace.default.useRef(onClose);
|
|
10215
|
+
React24__namespace.default.useEffect(() => {
|
|
9966
10216
|
onCloseRef.current = onClose;
|
|
9967
10217
|
}, [onClose]);
|
|
9968
|
-
const timer =
|
|
9969
|
-
const stop =
|
|
9970
|
-
const start =
|
|
10218
|
+
const timer = React24__namespace.default.useRef();
|
|
10219
|
+
const stop = React24__namespace.default.useCallback(() => clearTimeout(timer.current), []);
|
|
10220
|
+
const start = React24__namespace.default.useCallback(() => {
|
|
9971
10221
|
stop();
|
|
9972
10222
|
if (duration && duration !== Infinity && onCloseRef.current) {
|
|
9973
10223
|
timer.current = setTimeout(() => onCloseRef.current && onCloseRef.current(), duration);
|
|
9974
10224
|
}
|
|
9975
10225
|
}, [duration, stop]);
|
|
9976
|
-
|
|
10226
|
+
React24__namespace.default.useEffect(() => {
|
|
9977
10227
|
start();
|
|
9978
10228
|
return stop;
|
|
9979
10229
|
}, [start, stop]);
|
|
@@ -10017,30 +10267,30 @@ function Toast({
|
|
|
10017
10267
|
}
|
|
10018
10268
|
function ToastViewport({ children, limit, className = "", ...rest }) {
|
|
10019
10269
|
const __twcStyles = useScopedStyles("twc-toast-styles", TOAST_CSS);
|
|
10020
|
-
const shown = limit && limit > 0 ?
|
|
10270
|
+
const shown = limit && limit > 0 ? React24__namespace.default.Children.toArray(children).slice(-limit) : children;
|
|
10021
10271
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-toast-viewport ${className}`, ...rest, children: [
|
|
10022
10272
|
__twcStyles,
|
|
10023
10273
|
shown
|
|
10024
10274
|
] });
|
|
10025
10275
|
}
|
|
10026
|
-
var ToastContext =
|
|
10276
|
+
var ToastContext = React24__namespace.default.createContext(null);
|
|
10027
10277
|
function useToast() {
|
|
10028
|
-
const ctx =
|
|
10278
|
+
const ctx = React24__namespace.default.useContext(ToastContext);
|
|
10029
10279
|
if (!ctx) throw new Error("useToast must be used within a <ToastProvider>.");
|
|
10030
10280
|
return ctx;
|
|
10031
10281
|
}
|
|
10032
10282
|
function ToastProvider({ children, limit = 4, duration = 4500, ...viewportProps }) {
|
|
10033
|
-
const [toasts, setToasts] =
|
|
10034
|
-
const idRef =
|
|
10035
|
-
const limitRef =
|
|
10036
|
-
|
|
10283
|
+
const [toasts, setToasts] = React24__namespace.default.useState([]);
|
|
10284
|
+
const idRef = React24__namespace.default.useRef(0);
|
|
10285
|
+
const limitRef = React24__namespace.default.useRef(limit);
|
|
10286
|
+
React24__namespace.default.useEffect(() => {
|
|
10037
10287
|
limitRef.current = limit;
|
|
10038
10288
|
}, [limit]);
|
|
10039
|
-
const dismiss =
|
|
10289
|
+
const dismiss = React24__namespace.default.useCallback((id) => {
|
|
10040
10290
|
setToasts((s) => s.filter((t) => t.id !== id));
|
|
10041
10291
|
}, []);
|
|
10042
|
-
const clear =
|
|
10043
|
-
const api =
|
|
10292
|
+
const clear = React24__namespace.default.useCallback(() => setToasts([]), []);
|
|
10293
|
+
const api = React24__namespace.default.useMemo(() => {
|
|
10044
10294
|
const push = (opts) => {
|
|
10045
10295
|
const id = idRef.current += 1;
|
|
10046
10296
|
const next = typeof opts === "string" ? { title: opts } : opts && typeof opts === "object" ? opts : {};
|
|
@@ -10061,7 +10311,7 @@ function ToastProvider({ children, limit = 4, duration = 4500, ...viewportProps
|
|
|
10061
10311
|
toast.show = withTone("default");
|
|
10062
10312
|
return { toast, dismiss, clear };
|
|
10063
10313
|
}, [dismiss, clear]);
|
|
10064
|
-
const value =
|
|
10314
|
+
const value = React24__namespace.default.useMemo(() => ({ ...api, toasts }), [api, toasts]);
|
|
10065
10315
|
return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value, children: [
|
|
10066
10316
|
children,
|
|
10067
10317
|
/* @__PURE__ */ jsxRuntime.jsx(ToastViewport, { limit, ...viewportProps, children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10101,7 +10351,7 @@ var TREE_CSS = `
|
|
|
10101
10351
|
.twc-tree__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
10102
10352
|
.twc-tree__badge { flex: none; font-size: 11px; color: var(--color-text-subtle); }
|
|
10103
10353
|
`;
|
|
10104
|
-
function Node({ node, depth, expanded, selectedId, tabbableId, rowRefs, onToggle, onSelect, onRowFocus }) {
|
|
10354
|
+
function Node({ node, depth, posInSet, setSize, expanded, selectedId, tabbableId, rowRefs, onToggle, onSelect, onRowFocus }) {
|
|
10105
10355
|
const hasChildren = Array.isArray(node.children) && node.children.length > 0;
|
|
10106
10356
|
const open = expanded.has(node.id);
|
|
10107
10357
|
return /* @__PURE__ */ jsxRuntime.jsxs("li", { role: "none", children: [
|
|
@@ -10112,6 +10362,8 @@ function Node({ node, depth, expanded, selectedId, tabbableId, rowRefs, onToggle
|
|
|
10112
10362
|
className: "twc-tree__row",
|
|
10113
10363
|
role: "treeitem",
|
|
10114
10364
|
"aria-level": depth + 1,
|
|
10365
|
+
"aria-posinset": posInSet,
|
|
10366
|
+
"aria-setsize": setSize,
|
|
10115
10367
|
"aria-selected": selectedId === node.id,
|
|
10116
10368
|
"data-selected": selectedId === node.id || void 0,
|
|
10117
10369
|
"data-tree-id": node.id,
|
|
@@ -10135,11 +10387,13 @@ function Node({ node, depth, expanded, selectedId, tabbableId, rowRefs, onToggle
|
|
|
10135
10387
|
]
|
|
10136
10388
|
}
|
|
10137
10389
|
),
|
|
10138
|
-
hasChildren && open ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "twc-tree__group twc-tree__group--child", role: "group", children: node.children.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
10390
|
+
hasChildren && open ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "twc-tree__group twc-tree__group--child", role: "group", children: node.children.map((c, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
10139
10391
|
Node,
|
|
10140
10392
|
{
|
|
10141
10393
|
node: c,
|
|
10142
10394
|
depth: depth + 1,
|
|
10395
|
+
posInSet: i + 1,
|
|
10396
|
+
setSize: node.children.length,
|
|
10143
10397
|
expanded,
|
|
10144
10398
|
selectedId,
|
|
10145
10399
|
tabbableId,
|
|
@@ -10165,12 +10419,13 @@ function TreeView({
|
|
|
10165
10419
|
}) {
|
|
10166
10420
|
const nodes = items;
|
|
10167
10421
|
const __twcStyles = useScopedStyles("twc-tree-styles", TREE_CSS);
|
|
10168
|
-
const [expInternal, setExpInternal] =
|
|
10422
|
+
const [expInternal, setExpInternal] = React24__namespace.default.useState(() => new Set(defaultExpanded));
|
|
10169
10423
|
const expanded = expandedProp !== void 0 ? new Set(expandedProp) : expInternal;
|
|
10170
|
-
const [selInternal, setSelInternal] =
|
|
10424
|
+
const [selInternal, setSelInternal] = React24__namespace.default.useState(defaultSelectedId);
|
|
10171
10425
|
const selectedId = selectedProp !== void 0 ? selectedProp : selInternal;
|
|
10172
|
-
const [focusId, setFocusId] =
|
|
10173
|
-
const rowRefs =
|
|
10426
|
+
const [focusId, setFocusId] = React24__namespace.default.useState(null);
|
|
10427
|
+
const rowRefs = React24__namespace.default.useRef(/* @__PURE__ */ new Map());
|
|
10428
|
+
const taRef = React24__namespace.default.useRef({ str: "", t: 0 });
|
|
10174
10429
|
const toggle = (id) => {
|
|
10175
10430
|
const n = new Set(expanded);
|
|
10176
10431
|
n.has(id) ? n.delete(id) : n.add(id);
|
|
@@ -10184,10 +10439,12 @@ function TreeView({
|
|
|
10184
10439
|
const visible = [];
|
|
10185
10440
|
const parentOf = /* @__PURE__ */ new Map();
|
|
10186
10441
|
const hasKids = /* @__PURE__ */ new Map();
|
|
10442
|
+
const labelText = /* @__PURE__ */ new Map();
|
|
10187
10443
|
const walk = (nodes2, parentId) => {
|
|
10188
10444
|
for (const n of nodes2) {
|
|
10189
10445
|
visible.push(n.id);
|
|
10190
10446
|
parentOf.set(n.id, parentId);
|
|
10447
|
+
if (typeof n.label === "string") labelText.set(n.id, n.label);
|
|
10191
10448
|
const kids = Array.isArray(n.children) && n.children.length > 0;
|
|
10192
10449
|
hasKids.set(n.id, kids);
|
|
10193
10450
|
if (kids && expanded.has(n.id)) walk(n.children, n.id);
|
|
@@ -10225,17 +10482,36 @@ function TreeView({
|
|
|
10225
10482
|
return;
|
|
10226
10483
|
}
|
|
10227
10484
|
next = parentOf.get(id);
|
|
10485
|
+
} else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && /\S/.test(e.key)) {
|
|
10486
|
+
const now = Date.now();
|
|
10487
|
+
taRef.current.str = now - taRef.current.t > 500 ? e.key : taRef.current.str + e.key;
|
|
10488
|
+
taRef.current.t = now;
|
|
10489
|
+
const q = taRef.current.str.toLowerCase();
|
|
10490
|
+
const single = q.length > 1 && [...q].every((c) => c === q[0]);
|
|
10491
|
+
const needle = single ? q[0] : q;
|
|
10492
|
+
for (let k = 1; k <= visible.length; k++) {
|
|
10493
|
+
const cand = visible[(i + k) % visible.length];
|
|
10494
|
+
const lbl = labelText.get(cand);
|
|
10495
|
+
if (lbl && lbl.toLowerCase().startsWith(needle)) {
|
|
10496
|
+
e.preventDefault();
|
|
10497
|
+
focusRow(cand);
|
|
10498
|
+
break;
|
|
10499
|
+
}
|
|
10500
|
+
}
|
|
10501
|
+
return;
|
|
10228
10502
|
} else return;
|
|
10229
10503
|
e.preventDefault();
|
|
10230
10504
|
if (next != null) focusRow(next);
|
|
10231
10505
|
};
|
|
10232
10506
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-tree ${className}`, role: "tree", onKeyDown, ...rest, children: [
|
|
10233
10507
|
__twcStyles,
|
|
10234
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "twc-tree__group", role: "none", children: nodes.map((n) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
10508
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "twc-tree__group", role: "none", children: nodes.map((n, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
10235
10509
|
Node,
|
|
10236
10510
|
{
|
|
10237
10511
|
node: n,
|
|
10238
10512
|
depth: 0,
|
|
10513
|
+
posInSet: i + 1,
|
|
10514
|
+
setSize: nodes.length,
|
|
10239
10515
|
expanded,
|
|
10240
10516
|
selectedId,
|
|
10241
10517
|
tabbableId,
|
|
@@ -10249,12 +10525,22 @@ function TreeView({
|
|
|
10249
10525
|
] });
|
|
10250
10526
|
}
|
|
10251
10527
|
var SHELL_CSS = `
|
|
10252
|
-
.twc-shell { display: flex; overflow: hidden; background: var(--color-bg); color: var(--color-text); font-family: var(--font-sans); }
|
|
10528
|
+
.twc-shell { position: relative; display: flex; overflow: hidden; background: var(--color-bg); color: var(--color-text); font-family: var(--font-sans); }
|
|
10529
|
+
.twc-shell__skip { position: absolute; inset-inline-start: var(--space-3); inset-block-start: var(--space-3); z-index: 100;
|
|
10530
|
+
padding: var(--space-2) var(--space-4); background: var(--color-surface); color: var(--color-text);
|
|
10531
|
+
border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-md); font-family: var(--font-sans);
|
|
10532
|
+
transform: translateY(-200%); transition: transform var(--duration-fast) var(--ease-standard); }
|
|
10533
|
+
.twc-shell__skip:focus-visible { transform: translateY(0); outline: none; box-shadow: var(--ring); }
|
|
10253
10534
|
.twc-shell__main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; height: 100%; }
|
|
10254
10535
|
.twc-shell__header { flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
|
|
10255
10536
|
min-height: 60px; padding-inline: var(--space-5); border-bottom: var(--border-thin) solid var(--color-border); background: var(--color-surface); }
|
|
10256
10537
|
.twc-shell__content { flex: 1 1 auto; min-height: 0; overflow: auto; }
|
|
10257
10538
|
.twc-shell__content[data-padded="true"] { padding: var(--space-6) var(--space-5); }
|
|
10539
|
+
/* Mobile: stack the shell so the sidebar (rendered as an off-canvas overlay) no
|
|
10540
|
+
longer reserves a column \u2014 the main content spans the full width. */
|
|
10541
|
+
@media (max-width: 720px) {
|
|
10542
|
+
.twc-shell { flex-direction: column; }
|
|
10543
|
+
}
|
|
10258
10544
|
`;
|
|
10259
10545
|
function AppShell({
|
|
10260
10546
|
sidebar,
|
|
@@ -10262,17 +10548,27 @@ function AppShell({
|
|
|
10262
10548
|
children,
|
|
10263
10549
|
height = "100dvh",
|
|
10264
10550
|
padded = true,
|
|
10551
|
+
mainId = "twc-main",
|
|
10552
|
+
skipLinkLabel = "Skip to content",
|
|
10553
|
+
sidebarOpen,
|
|
10554
|
+
onSidebarOpenChange,
|
|
10265
10555
|
className = "",
|
|
10266
10556
|
style,
|
|
10267
10557
|
...rest
|
|
10268
10558
|
}) {
|
|
10269
10559
|
const __twcStyles = useScopedStyles("twc-shell-styles", SHELL_CSS);
|
|
10560
|
+
const wiredSidebar = React24__namespace.default.isValidElement(sidebar) && (sidebarOpen !== void 0 || onSidebarOpenChange !== void 0) ? React24__namespace.default.cloneElement(sidebar, {
|
|
10561
|
+
overlay: sidebar.props.overlay !== void 0 ? sidebar.props.overlay : true,
|
|
10562
|
+
open: sidebar.props.open !== void 0 ? sidebar.props.open : sidebarOpen,
|
|
10563
|
+
onOpenChange: sidebar.props.onOpenChange !== void 0 ? sidebar.props.onOpenChange : onSidebarOpenChange
|
|
10564
|
+
}) : sidebar;
|
|
10270
10565
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-shell ${className}`.trim(), style: { height, ...style }, ...rest, children: [
|
|
10271
10566
|
__twcStyles,
|
|
10272
|
-
|
|
10567
|
+
skipLinkLabel != null && skipLinkLabel !== false ? /* @__PURE__ */ jsxRuntime.jsx("a", { className: "twc-shell__skip", href: `#${mainId}`, children: skipLinkLabel }) : null,
|
|
10568
|
+
wiredSidebar,
|
|
10273
10569
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-shell__main", children: [
|
|
10274
10570
|
header != null ? /* @__PURE__ */ jsxRuntime.jsx("header", { className: "twc-shell__header", children: header }) : null,
|
|
10275
|
-
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "twc-shell__content", "data-padded": padded ? "true" : void 0, children })
|
|
10571
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "twc-shell__content", id: mainId, tabIndex: -1, "data-padded": padded ? "true" : void 0, children })
|
|
10276
10572
|
] })
|
|
10277
10573
|
] });
|
|
10278
10574
|
}
|
|
@@ -10291,7 +10587,7 @@ function bgValue(bg) {
|
|
|
10291
10587
|
if (BG[bg]) return `var(${BG[bg]})`;
|
|
10292
10588
|
return String(bg).startsWith("--") ? `var(${bg})` : bg;
|
|
10293
10589
|
}
|
|
10294
|
-
function
|
|
10590
|
+
function safeHref5(url) {
|
|
10295
10591
|
if (url == null) return void 0;
|
|
10296
10592
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
10297
10593
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -10336,11 +10632,11 @@ function Box({
|
|
|
10336
10632
|
boxShadow: shadow ? `var(--shadow-${shadow})` : void 0,
|
|
10337
10633
|
...style
|
|
10338
10634
|
};
|
|
10339
|
-
if (Tag2 === "a" && rest.href != null) rest.href =
|
|
10635
|
+
if (Tag2 === "a" && rest.href != null) rest.href = safeHref5(rest.href);
|
|
10340
10636
|
return /* @__PURE__ */ jsxRuntime.jsx(Tag2, { className: `twc-box ${className}`.trim(), style: s, ...rest, children });
|
|
10341
10637
|
}
|
|
10342
10638
|
var SIZES = { sm: 640, md: 768, lg: 1024, xl: 1280, full: "100%" };
|
|
10343
|
-
function
|
|
10639
|
+
function safeHref6(url) {
|
|
10344
10640
|
if (url == null) return void 0;
|
|
10345
10641
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
10346
10642
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -10355,7 +10651,7 @@ function Container({
|
|
|
10355
10651
|
...rest
|
|
10356
10652
|
}) {
|
|
10357
10653
|
const max = SIZES[size] ?? size;
|
|
10358
|
-
if (Tag2 === "a" && rest.href != null) rest.href =
|
|
10654
|
+
if (Tag2 === "a" && rest.href != null) rest.href = safeHref6(rest.href);
|
|
10359
10655
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10360
10656
|
Tag2,
|
|
10361
10657
|
{
|
|
@@ -10380,7 +10676,8 @@ function space(v) {
|
|
|
10380
10676
|
function len(v) {
|
|
10381
10677
|
return typeof v === "number" ? `${v}px` : v;
|
|
10382
10678
|
}
|
|
10383
|
-
|
|
10679
|
+
var BP = { sm: 640, md: 768, lg: 1024, xl: 1280 };
|
|
10680
|
+
function safeHref7(url) {
|
|
10384
10681
|
if (url == null) return void 0;
|
|
10385
10682
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
10386
10683
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -10390,29 +10687,54 @@ function Grid({
|
|
|
10390
10687
|
columns,
|
|
10391
10688
|
minChildWidth,
|
|
10392
10689
|
gap = 4,
|
|
10690
|
+
rowGap,
|
|
10691
|
+
columnGap,
|
|
10393
10692
|
align,
|
|
10394
10693
|
justify,
|
|
10694
|
+
alignContent,
|
|
10695
|
+
justifyContent,
|
|
10395
10696
|
className = "",
|
|
10396
10697
|
style,
|
|
10397
10698
|
children,
|
|
10398
10699
|
...rest
|
|
10399
10700
|
}) {
|
|
10400
|
-
const
|
|
10401
|
-
|
|
10402
|
-
|
|
10701
|
+
const responsive = columns != null && typeof columns === "object";
|
|
10702
|
+
const uid = React24__namespace.default.useId();
|
|
10703
|
+
const gridId = responsive ? `g${uid.replace(/[^a-zA-Z0-9]/g, "")}` : null;
|
|
10704
|
+
let css = "";
|
|
10705
|
+
if (responsive) {
|
|
10706
|
+
const base = columns.base ?? 1;
|
|
10707
|
+
const sel = `[data-twc-grid-id="${gridId}"]`;
|
|
10708
|
+
css = `${sel} { --twc-grid-cols: ${base}; }`;
|
|
10709
|
+
for (const bp of ["sm", "md", "lg", "xl"]) {
|
|
10710
|
+
if (columns[bp] != null) css += `
|
|
10711
|
+
@media (min-width: ${BP[bp]}px) { ${sel} { --twc-grid-cols: ${columns[bp]}; } }`;
|
|
10712
|
+
}
|
|
10713
|
+
}
|
|
10714
|
+
const __twcStyles = useScopedStyles(gridId ? `twc-grid-${gridId}` : "twc-grid", css);
|
|
10715
|
+
const templateColumns = minChildWidth ? `repeat(auto-fill, minmax(min(${len(minChildWidth)}, 100%), 1fr))` : responsive ? `repeat(var(--twc-grid-cols, ${columns.base ?? 1}), minmax(0, 1fr))` : `repeat(${columns || 1}, minmax(0, 1fr))`;
|
|
10716
|
+
if (Tag2 === "a" && rest.href != null) rest.href = safeHref7(rest.href);
|
|
10717
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10403
10718
|
Tag2,
|
|
10404
10719
|
{
|
|
10405
10720
|
className: `twc-grid ${className}`.trim(),
|
|
10721
|
+
"data-twc-grid-id": gridId || void 0,
|
|
10406
10722
|
style: {
|
|
10407
10723
|
display: "grid",
|
|
10408
10724
|
gridTemplateColumns: templateColumns,
|
|
10409
|
-
|
|
10725
|
+
rowGap: space(rowGap ?? gap),
|
|
10726
|
+
columnGap: space(columnGap ?? gap),
|
|
10410
10727
|
alignItems: align,
|
|
10411
10728
|
justifyItems: justify,
|
|
10729
|
+
alignContent,
|
|
10730
|
+
justifyContent,
|
|
10412
10731
|
...style
|
|
10413
10732
|
},
|
|
10414
10733
|
...rest,
|
|
10415
|
-
children
|
|
10734
|
+
children: [
|
|
10735
|
+
responsive ? __twcStyles : null,
|
|
10736
|
+
children
|
|
10737
|
+
]
|
|
10416
10738
|
}
|
|
10417
10739
|
);
|
|
10418
10740
|
}
|
|
@@ -10421,7 +10743,7 @@ function space2(v) {
|
|
|
10421
10743
|
if (typeof v === "number") return `var(--space-${String(v).replace(".", "-")})`;
|
|
10422
10744
|
return v;
|
|
10423
10745
|
}
|
|
10424
|
-
function
|
|
10746
|
+
function safeHref8(url) {
|
|
10425
10747
|
if (url == null) return void 0;
|
|
10426
10748
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
10427
10749
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -10434,12 +10756,21 @@ function Stack({
|
|
|
10434
10756
|
justify,
|
|
10435
10757
|
wrap = false,
|
|
10436
10758
|
inline = false,
|
|
10759
|
+
p,
|
|
10760
|
+
px,
|
|
10761
|
+
py,
|
|
10762
|
+
pt,
|
|
10763
|
+
pr,
|
|
10764
|
+
pb,
|
|
10765
|
+
pl,
|
|
10766
|
+
divider,
|
|
10437
10767
|
className = "",
|
|
10438
10768
|
style,
|
|
10439
10769
|
children,
|
|
10440
10770
|
...rest
|
|
10441
10771
|
}) {
|
|
10442
|
-
if (Tag2 === "a" && rest.href != null) rest.href =
|
|
10772
|
+
if (Tag2 === "a" && rest.href != null) rest.href = safeHref8(rest.href);
|
|
10773
|
+
const kids = divider != null ? React24__namespace.default.Children.toArray(children).flatMap((child, i, arr) => i < arr.length - 1 ? [child, /* @__PURE__ */ jsxRuntime.jsx(React24__namespace.default.Fragment, { children: divider }, `twc-stack-div-${i}`)] : [child]) : children;
|
|
10443
10774
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10444
10775
|
Tag2,
|
|
10445
10776
|
{
|
|
@@ -10451,11 +10782,15 @@ function Stack({
|
|
|
10451
10782
|
alignItems: align,
|
|
10452
10783
|
justifyContent: justify,
|
|
10453
10784
|
flexWrap: wrap ? "wrap" : void 0,
|
|
10785
|
+
paddingTop: space2(pt ?? py ?? p),
|
|
10786
|
+
paddingRight: space2(pr ?? px ?? p),
|
|
10787
|
+
paddingBottom: space2(pb ?? py ?? p),
|
|
10788
|
+
paddingLeft: space2(pl ?? px ?? p),
|
|
10454
10789
|
minWidth: 0,
|
|
10455
10790
|
...style
|
|
10456
10791
|
},
|
|
10457
10792
|
...rest,
|
|
10458
|
-
children
|
|
10793
|
+
children: kids
|
|
10459
10794
|
}
|
|
10460
10795
|
);
|
|
10461
10796
|
}
|
|
@@ -10467,22 +10802,64 @@ var CODE_CSS = `
|
|
|
10467
10802
|
border: var(--border-thin) solid var(--color-border);
|
|
10468
10803
|
white-space: normal; overflow-wrap: anywhere; word-break: break-word;
|
|
10469
10804
|
}
|
|
10805
|
+
.twc-code[data-block="true"] {
|
|
10806
|
+
display: block; position: relative; white-space: pre; overflow-x: auto;
|
|
10807
|
+
padding: 12px 14px; padding-inline-end: 40px; line-height: 1.6; font-size: 0.8125em;
|
|
10808
|
+
overflow-wrap: normal; word-break: normal;
|
|
10809
|
+
}
|
|
10810
|
+
.twc-code__copy {
|
|
10811
|
+
position: absolute; top: 6px; inset-inline-end: 6px; display: inline-grid; place-items: center;
|
|
10812
|
+
width: 26px; height: 26px; border: none; border-radius: var(--radius-sm);
|
|
10813
|
+
background: var(--color-surface); color: var(--color-text-subtle); cursor: pointer;
|
|
10814
|
+
transition: color var(--duration-fast), background-color var(--duration-fast);
|
|
10815
|
+
}
|
|
10816
|
+
.twc-code__copy:hover { color: var(--color-text); }
|
|
10817
|
+
.twc-code__copy:focus-visible { outline: none; box-shadow: var(--ring); }
|
|
10818
|
+
.twc-code__copy svg { width: 15px; height: 15px; display: block; }
|
|
10470
10819
|
`;
|
|
10471
|
-
function
|
|
10820
|
+
function safeHref9(url) {
|
|
10472
10821
|
if (url == null) return void 0;
|
|
10473
10822
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
10474
10823
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
10475
10824
|
}
|
|
10476
|
-
function Code({
|
|
10825
|
+
function Code({
|
|
10826
|
+
as,
|
|
10827
|
+
block = false,
|
|
10828
|
+
copyable = false,
|
|
10829
|
+
copyLabel = "Copy code",
|
|
10830
|
+
copiedLabel = "Copied",
|
|
10831
|
+
className = "",
|
|
10832
|
+
children,
|
|
10833
|
+
...rest
|
|
10834
|
+
}) {
|
|
10477
10835
|
const __twcStyles = useScopedStyles("twc-code-styles", CODE_CSS);
|
|
10478
|
-
|
|
10479
|
-
|
|
10836
|
+
const Tag2 = as ?? (block ? "pre" : "code");
|
|
10837
|
+
if (Tag2 === "a" && rest.href != null) rest.href = safeHref9(rest.href);
|
|
10838
|
+
const rootRef = React24__namespace.default.useRef(null);
|
|
10839
|
+
const [copied, setCopied] = React24__namespace.default.useState(false);
|
|
10840
|
+
const timerRef = React24__namespace.default.useRef(null);
|
|
10841
|
+
React24__namespace.default.useEffect(() => () => clearTimeout(timerRef.current), []);
|
|
10842
|
+
const doCopy = () => {
|
|
10843
|
+
if (typeof navigator === "undefined" || !navigator.clipboard) return;
|
|
10844
|
+
const text = typeof children === "string" ? children : rootRef.current?.textContent ?? "";
|
|
10845
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
10846
|
+
setCopied(true);
|
|
10847
|
+
clearTimeout(timerRef.current);
|
|
10848
|
+
timerRef.current = setTimeout(() => setCopied(false), 2e3);
|
|
10849
|
+
}).catch(() => {
|
|
10850
|
+
});
|
|
10851
|
+
};
|
|
10852
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Tag2, { ref: rootRef, className: `twc-code ${className}`.trim(), "data-block": block || void 0, ...rest, children: [
|
|
10480
10853
|
__twcStyles,
|
|
10854
|
+
copyable ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-code__copy", "aria-label": copied ? copiedLabel : copyLabel, onClick: doCopy, children: copied ? /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m20 6-11 11-5-5" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
10855
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
|
|
10856
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
10857
|
+
] }) }) : null,
|
|
10481
10858
|
children
|
|
10482
10859
|
] });
|
|
10483
10860
|
}
|
|
10484
10861
|
var LEVEL_SIZE = { 1: "4xl", 2: "2xl", 3: "xl", 4: "lg", 5: "base", 6: "sm" };
|
|
10485
|
-
function
|
|
10862
|
+
function safeHref10(url) {
|
|
10486
10863
|
if (url == null) return void 0;
|
|
10487
10864
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
10488
10865
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -10491,15 +10868,18 @@ function Heading({
|
|
|
10491
10868
|
as,
|
|
10492
10869
|
level = 2,
|
|
10493
10870
|
size,
|
|
10871
|
+
display = false,
|
|
10494
10872
|
align,
|
|
10873
|
+
truncate,
|
|
10874
|
+
lineClamp,
|
|
10495
10875
|
className = "",
|
|
10496
10876
|
style,
|
|
10497
10877
|
children,
|
|
10498
10878
|
...rest
|
|
10499
10879
|
}) {
|
|
10500
10880
|
const Tag2 = as || `h${level}`;
|
|
10501
|
-
const sz = size || LEVEL_SIZE[level] || "2xl";
|
|
10502
|
-
if (Tag2 === "a" && rest.href != null) rest.href =
|
|
10881
|
+
const sz = size || (display ? "display" : LEVEL_SIZE[level]) || "2xl";
|
|
10882
|
+
if (Tag2 === "a" && rest.href != null) rest.href = safeHref10(rest.href);
|
|
10503
10883
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10504
10884
|
Tag2,
|
|
10505
10885
|
{
|
|
@@ -10513,6 +10893,7 @@ function Heading({
|
|
|
10513
10893
|
letterSpacing: "-0.02em",
|
|
10514
10894
|
fontSize: `var(--text-${sz})`,
|
|
10515
10895
|
textAlign: align,
|
|
10896
|
+
...lineClamp != null ? { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: lineClamp, overflow: "hidden" } : truncate ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 } : null,
|
|
10516
10897
|
...style
|
|
10517
10898
|
},
|
|
10518
10899
|
...rest,
|
|
@@ -10531,9 +10912,11 @@ var TONE = {
|
|
|
10531
10912
|
success: "--color-success",
|
|
10532
10913
|
warning: "--color-warning-subtle-fg",
|
|
10533
10914
|
info: "--color-info-subtle-fg",
|
|
10534
|
-
neutral: "--color-text-muted"
|
|
10915
|
+
neutral: "--color-text-muted",
|
|
10916
|
+
// Adopt the surrounding color (e.g. inside a solid Button/Badge/Alert or a link).
|
|
10917
|
+
inherit: "inherit"
|
|
10535
10918
|
};
|
|
10536
|
-
function
|
|
10919
|
+
function safeHref11(url) {
|
|
10537
10920
|
if (url == null) return void 0;
|
|
10538
10921
|
const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
|
|
10539
10922
|
return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
|
|
@@ -10544,12 +10927,15 @@ function Text({
|
|
|
10544
10927
|
tone = "default",
|
|
10545
10928
|
weight,
|
|
10546
10929
|
align,
|
|
10930
|
+
truncate,
|
|
10931
|
+
lineClamp,
|
|
10547
10932
|
className = "",
|
|
10548
10933
|
style,
|
|
10549
10934
|
children,
|
|
10550
10935
|
...rest
|
|
10551
10936
|
}) {
|
|
10552
|
-
if (Tag2 === "a" && rest.href != null) rest.href =
|
|
10937
|
+
if (Tag2 === "a" && rest.href != null) rest.href = safeHref11(rest.href);
|
|
10938
|
+
const toneToken = TONE[tone] || TONE.default;
|
|
10553
10939
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10554
10940
|
Tag2,
|
|
10555
10941
|
{
|
|
@@ -10559,9 +10945,10 @@ function Text({
|
|
|
10559
10945
|
fontFamily: "var(--font-sans)",
|
|
10560
10946
|
lineHeight: 1.6,
|
|
10561
10947
|
fontSize: `var(--text-${size})`,
|
|
10562
|
-
color: `var(${
|
|
10948
|
+
color: toneToken.startsWith("--") ? `var(${toneToken})` : toneToken,
|
|
10563
10949
|
fontWeight: weight ? `var(--font-${weight})` : void 0,
|
|
10564
10950
|
textAlign: align,
|
|
10951
|
+
...lineClamp != null ? { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: lineClamp, overflow: "hidden" } : truncate ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 } : null,
|
|
10565
10952
|
...style
|
|
10566
10953
|
},
|
|
10567
10954
|
...rest,
|
|
@@ -10569,58 +10956,68 @@ function Text({
|
|
|
10569
10956
|
}
|
|
10570
10957
|
);
|
|
10571
10958
|
}
|
|
10572
|
-
var
|
|
10573
|
-
var useIsomorphicLayoutEffect =
|
|
10959
|
+
var canUseDOM2 = typeof window !== "undefined" && typeof document !== "undefined";
|
|
10960
|
+
var useIsomorphicLayoutEffect = canUseDOM2 ? React24__namespace.default.useLayoutEffect : React24__namespace.default.useEffect;
|
|
10574
10961
|
function useMounted() {
|
|
10575
|
-
const [mounted, setMounted] =
|
|
10576
|
-
|
|
10962
|
+
const [mounted, setMounted] = React24__namespace.default.useState(false);
|
|
10963
|
+
React24__namespace.default.useEffect(() => {
|
|
10577
10964
|
setMounted(true);
|
|
10578
10965
|
}, []);
|
|
10579
10966
|
return mounted;
|
|
10580
10967
|
}
|
|
10581
10968
|
function usePrevious(value) {
|
|
10582
|
-
const ref =
|
|
10583
|
-
|
|
10969
|
+
const ref = React24__namespace.default.useRef(void 0);
|
|
10970
|
+
React24__namespace.default.useEffect(() => {
|
|
10584
10971
|
ref.current = value;
|
|
10585
10972
|
}, [value]);
|
|
10586
10973
|
return ref.current;
|
|
10587
10974
|
}
|
|
10588
10975
|
function useToggle(initial = false) {
|
|
10589
|
-
const [on, setOn] =
|
|
10590
|
-
const toggle =
|
|
10976
|
+
const [on, setOn] = React24__namespace.default.useState(initial);
|
|
10977
|
+
const toggle = React24__namespace.default.useCallback((next) => {
|
|
10591
10978
|
setOn((prev) => typeof next === "boolean" ? next : !prev);
|
|
10592
10979
|
}, []);
|
|
10593
10980
|
return [on, toggle, setOn];
|
|
10594
10981
|
}
|
|
10595
10982
|
function useDisclosure(initial = false) {
|
|
10596
|
-
const [open, setOpen] =
|
|
10597
|
-
const onOpen =
|
|
10598
|
-
const onClose =
|
|
10599
|
-
const onToggle =
|
|
10983
|
+
const [open, setOpen] = React24__namespace.default.useState(initial);
|
|
10984
|
+
const onOpen = React24__namespace.default.useCallback(() => setOpen(true), []);
|
|
10985
|
+
const onClose = React24__namespace.default.useCallback(() => setOpen(false), []);
|
|
10986
|
+
const onToggle = React24__namespace.default.useCallback(() => setOpen((p) => !p), []);
|
|
10600
10987
|
return { open, onOpen, onClose, onToggle, setOpen };
|
|
10601
10988
|
}
|
|
10602
10989
|
function useControllableState({ value, defaultValue, onChange } = {}) {
|
|
10603
10990
|
const isControlled = value !== void 0;
|
|
10604
|
-
const [uncontrolled, setUncontrolled] =
|
|
10991
|
+
const [uncontrolled, setUncontrolled] = React24__namespace.default.useState(defaultValue);
|
|
10605
10992
|
const current = isControlled ? value : uncontrolled;
|
|
10606
|
-
const ref =
|
|
10993
|
+
const ref = React24__namespace.default.useRef({ current, isControlled, onChange });
|
|
10607
10994
|
useIsomorphicLayoutEffect(() => {
|
|
10608
10995
|
ref.current = { current, isControlled, onChange };
|
|
10609
10996
|
});
|
|
10610
|
-
const
|
|
10997
|
+
const wasControlled = React24__namespace.default.useRef(isControlled);
|
|
10998
|
+
React24__namespace.default.useEffect(() => {
|
|
10999
|
+
if (wasControlled.current !== isControlled) {
|
|
11000
|
+
warnOnce(
|
|
11001
|
+
"useControllableState:switch",
|
|
11002
|
+
`useControllableState: a value is switching from ${wasControlled.current ? "controlled" : "uncontrolled"} to ${isControlled ? "controlled" : "uncontrolled"}. Decide between controlled (\`value\`) and uncontrolled (\`defaultValue\`) for the component's lifetime.`
|
|
11003
|
+
);
|
|
11004
|
+
wasControlled.current = isControlled;
|
|
11005
|
+
}
|
|
11006
|
+
});
|
|
11007
|
+
const setValue = React24__namespace.default.useCallback((next) => {
|
|
10611
11008
|
const { current: cur, isControlled: ctrl, onChange: cb } = ref.current;
|
|
10612
11009
|
const resolved = typeof next === "function" ? next(cur) : next;
|
|
10613
11010
|
if (resolved === cur) return;
|
|
10614
11011
|
if (!ctrl) setUncontrolled(resolved);
|
|
10615
11012
|
if (cb) cb(resolved);
|
|
10616
11013
|
}, []);
|
|
10617
|
-
return [current, setValue];
|
|
11014
|
+
return [current, setValue, isControlled];
|
|
10618
11015
|
}
|
|
10619
|
-
function useMediaQuery(query) {
|
|
10620
|
-
const get = () =>
|
|
10621
|
-
const [matches3, setMatches] =
|
|
10622
|
-
|
|
10623
|
-
if (!
|
|
11016
|
+
function useMediaQuery(query, { defaultValue = false, initializeWithValue = false } = {}) {
|
|
11017
|
+
const get = () => canUseDOM2 ? window.matchMedia(query).matches : defaultValue;
|
|
11018
|
+
const [matches3, setMatches] = React24__namespace.default.useState(initializeWithValue ? get : defaultValue);
|
|
11019
|
+
useIsomorphicLayoutEffect(() => {
|
|
11020
|
+
if (!canUseDOM2) return void 0;
|
|
10624
11021
|
const mql = window.matchMedia(query);
|
|
10625
11022
|
const onChange = () => setMatches(mql.matches);
|
|
10626
11023
|
onChange();
|
|
@@ -10633,10 +11030,10 @@ function usePrefersReducedMotion() {
|
|
|
10633
11030
|
return useMediaQuery("(prefers-reduced-motion: reduce)");
|
|
10634
11031
|
}
|
|
10635
11032
|
function useColorScheme({ storageKey = "twico-theme", attribute = "class", element, disableTransitionsOnChange = true } = {}) {
|
|
10636
|
-
const getTarget = () => element || (
|
|
10637
|
-
const firstApply =
|
|
11033
|
+
const getTarget = () => element || (canUseDOM2 ? document.documentElement : null);
|
|
11034
|
+
const firstApply = React24__namespace.default.useRef(true);
|
|
10638
11035
|
const read = () => {
|
|
10639
|
-
if (!
|
|
11036
|
+
if (!canUseDOM2) return "light";
|
|
10640
11037
|
try {
|
|
10641
11038
|
const stored = window.localStorage.getItem(storageKey);
|
|
10642
11039
|
if (stored === "light" || stored === "dark") return stored;
|
|
@@ -10644,12 +11041,12 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
|
|
|
10644
11041
|
}
|
|
10645
11042
|
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
10646
11043
|
};
|
|
10647
|
-
const [theme, setThemeState] =
|
|
10648
|
-
const apply =
|
|
11044
|
+
const [theme, setThemeState] = React24__namespace.default.useState(read);
|
|
11045
|
+
const apply = React24__namespace.default.useCallback(
|
|
10649
11046
|
(t) => {
|
|
10650
11047
|
const target = getTarget();
|
|
10651
11048
|
if (!target) return;
|
|
10652
|
-
const skip = firstApply.current || !disableTransitionsOnChange || !
|
|
11049
|
+
const skip = firstApply.current || !disableTransitionsOnChange || !canUseDOM2;
|
|
10653
11050
|
firstApply.current = false;
|
|
10654
11051
|
let css;
|
|
10655
11052
|
if (!skip) {
|
|
@@ -10671,26 +11068,26 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
|
|
|
10671
11068
|
useIsomorphicLayoutEffect(() => {
|
|
10672
11069
|
apply(theme);
|
|
10673
11070
|
}, [theme, apply]);
|
|
10674
|
-
const themeRef =
|
|
11071
|
+
const themeRef = React24__namespace.default.useRef(theme);
|
|
10675
11072
|
useIsomorphicLayoutEffect(() => {
|
|
10676
11073
|
themeRef.current = theme;
|
|
10677
11074
|
}, [theme]);
|
|
10678
|
-
const setTheme =
|
|
11075
|
+
const setTheme = React24__namespace.default.useCallback(
|
|
10679
11076
|
(t) => {
|
|
10680
11077
|
setThemeState(t);
|
|
10681
11078
|
try {
|
|
10682
|
-
if (
|
|
11079
|
+
if (canUseDOM2) window.localStorage.setItem(storageKey, t);
|
|
10683
11080
|
} catch (e) {
|
|
10684
11081
|
}
|
|
10685
|
-
if (
|
|
11082
|
+
if (canUseDOM2) window.dispatchEvent(new Event("twico:colorscheme"));
|
|
10686
11083
|
},
|
|
10687
11084
|
[storageKey]
|
|
10688
11085
|
);
|
|
10689
|
-
const toggle =
|
|
11086
|
+
const toggle = React24__namespace.default.useCallback(() => {
|
|
10690
11087
|
setTheme(themeRef.current === "dark" ? "light" : "dark");
|
|
10691
11088
|
}, [setTheme]);
|
|
10692
|
-
|
|
10693
|
-
if (!
|
|
11089
|
+
React24__namespace.default.useEffect(() => {
|
|
11090
|
+
if (!canUseDOM2) return void 0;
|
|
10694
11091
|
const sync = () => setThemeState(read());
|
|
10695
11092
|
const onStorage = (e) => {
|
|
10696
11093
|
if (e.key === storageKey) sync();
|
|
@@ -10705,15 +11102,15 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
|
|
|
10705
11102
|
return { theme, setTheme, toggle, isDark: theme === "dark" };
|
|
10706
11103
|
}
|
|
10707
11104
|
function useEventListener(eventName, handler, element, options) {
|
|
10708
|
-
const saved =
|
|
11105
|
+
const saved = React24__namespace.default.useRef(handler);
|
|
10709
11106
|
useIsomorphicLayoutEffect(() => {
|
|
10710
11107
|
saved.current = handler;
|
|
10711
11108
|
}, [handler]);
|
|
10712
11109
|
const capture = typeof options === "boolean" ? options : options && options.capture;
|
|
10713
11110
|
const passive = typeof options === "object" && options ? options.passive : void 0;
|
|
10714
11111
|
const once = typeof options === "object" && options ? options.once : void 0;
|
|
10715
|
-
|
|
10716
|
-
const target = element && element.current || element || (
|
|
11112
|
+
React24__namespace.default.useEffect(() => {
|
|
11113
|
+
const target = element && element.current || element || (canUseDOM2 ? window : null);
|
|
10717
11114
|
if (!target || !target.addEventListener) return void 0;
|
|
10718
11115
|
const opts = typeof options === "boolean" ? options : { capture, passive, once };
|
|
10719
11116
|
const listener = (e) => saved.current(e);
|
|
@@ -10722,12 +11119,12 @@ function useEventListener(eventName, handler, element, options) {
|
|
|
10722
11119
|
}, [eventName, element, capture, passive, once]);
|
|
10723
11120
|
}
|
|
10724
11121
|
function useClickOutside(ref, handler, events = ["mousedown", "touchstart"]) {
|
|
10725
|
-
const saved =
|
|
11122
|
+
const saved = React24__namespace.default.useRef(handler);
|
|
10726
11123
|
useIsomorphicLayoutEffect(() => {
|
|
10727
11124
|
saved.current = handler;
|
|
10728
11125
|
}, [handler]);
|
|
10729
|
-
|
|
10730
|
-
if (!
|
|
11126
|
+
React24__namespace.default.useEffect(() => {
|
|
11127
|
+
if (!canUseDOM2) return void 0;
|
|
10731
11128
|
const listener = (e) => {
|
|
10732
11129
|
const el = ref && ref.current;
|
|
10733
11130
|
if (!el || el.contains(e.target)) return;
|
|
@@ -10753,7 +11150,7 @@ function useKeyPress(key, handler, options = {}) {
|
|
|
10753
11150
|
}
|
|
10754
11151
|
function useLocalStorage(key, initialValue) {
|
|
10755
11152
|
const read = () => {
|
|
10756
|
-
if (!
|
|
11153
|
+
if (!canUseDOM2) return initialValue;
|
|
10757
11154
|
try {
|
|
10758
11155
|
const item = window.localStorage.getItem(key);
|
|
10759
11156
|
return item ? JSON.parse(item) : initialValue;
|
|
@@ -10761,13 +11158,13 @@ function useLocalStorage(key, initialValue) {
|
|
|
10761
11158
|
return initialValue;
|
|
10762
11159
|
}
|
|
10763
11160
|
};
|
|
10764
|
-
const [stored, setStored] =
|
|
10765
|
-
const setValue =
|
|
11161
|
+
const [stored, setStored] = React24__namespace.default.useState(read);
|
|
11162
|
+
const setValue = React24__namespace.default.useCallback(
|
|
10766
11163
|
(value) => {
|
|
10767
11164
|
setStored((prev) => {
|
|
10768
11165
|
const next = typeof value === "function" ? value(prev) : value;
|
|
10769
11166
|
try {
|
|
10770
|
-
if (
|
|
11167
|
+
if (canUseDOM2) window.localStorage.setItem(key, JSON.stringify(next));
|
|
10771
11168
|
} catch (e) {
|
|
10772
11169
|
}
|
|
10773
11170
|
return next;
|
|
@@ -10778,9 +11175,9 @@ function useLocalStorage(key, initialValue) {
|
|
|
10778
11175
|
return [stored, setValue];
|
|
10779
11176
|
}
|
|
10780
11177
|
function useCopyToClipboard(timeout = 1500) {
|
|
10781
|
-
const [copied, setCopied] =
|
|
10782
|
-
const copy =
|
|
10783
|
-
if (!
|
|
11178
|
+
const [copied, setCopied] = React24__namespace.default.useState(false);
|
|
11179
|
+
const copy = React24__namespace.default.useCallback(async (text) => {
|
|
11180
|
+
if (!canUseDOM2 || !navigator.clipboard) {
|
|
10784
11181
|
setCopied(false);
|
|
10785
11182
|
return false;
|
|
10786
11183
|
}
|
|
@@ -10793,7 +11190,7 @@ function useCopyToClipboard(timeout = 1500) {
|
|
|
10793
11190
|
return false;
|
|
10794
11191
|
}
|
|
10795
11192
|
}, []);
|
|
10796
|
-
|
|
11193
|
+
React24__namespace.default.useEffect(() => {
|
|
10797
11194
|
if (!copied) return void 0;
|
|
10798
11195
|
const t = setTimeout(() => setCopied(false), timeout);
|
|
10799
11196
|
return () => clearTimeout(t);
|
|
@@ -10801,23 +11198,23 @@ function useCopyToClipboard(timeout = 1500) {
|
|
|
10801
11198
|
return { copied, copy };
|
|
10802
11199
|
}
|
|
10803
11200
|
function useDebouncedValue(value, delay = 200) {
|
|
10804
|
-
const [debounced, setDebounced] =
|
|
10805
|
-
|
|
11201
|
+
const [debounced, setDebounced] = React24__namespace.default.useState(value);
|
|
11202
|
+
React24__namespace.default.useEffect(() => {
|
|
10806
11203
|
const t = setTimeout(() => setDebounced(value), delay);
|
|
10807
11204
|
return () => clearTimeout(t);
|
|
10808
11205
|
}, [value, delay]);
|
|
10809
11206
|
return debounced;
|
|
10810
11207
|
}
|
|
10811
11208
|
function useDebouncedCallback(callback, delay = 200) {
|
|
10812
|
-
const saved =
|
|
10813
|
-
const timer =
|
|
11209
|
+
const saved = React24__namespace.default.useRef(callback);
|
|
11210
|
+
const timer = React24__namespace.default.useRef(null);
|
|
10814
11211
|
useIsomorphicLayoutEffect(() => {
|
|
10815
11212
|
saved.current = callback;
|
|
10816
11213
|
}, [callback]);
|
|
10817
|
-
|
|
11214
|
+
React24__namespace.default.useEffect(() => () => {
|
|
10818
11215
|
if (timer.current) clearTimeout(timer.current);
|
|
10819
11216
|
}, []);
|
|
10820
|
-
return
|
|
11217
|
+
return React24__namespace.default.useCallback(
|
|
10821
11218
|
(...args) => {
|
|
10822
11219
|
if (timer.current) clearTimeout(timer.current);
|
|
10823
11220
|
timer.current = setTimeout(() => saved.current(...args), delay);
|
|
@@ -10826,34 +11223,34 @@ function useDebouncedCallback(callback, delay = 200) {
|
|
|
10826
11223
|
);
|
|
10827
11224
|
}
|
|
10828
11225
|
function useInterval(callback, delay) {
|
|
10829
|
-
const saved =
|
|
11226
|
+
const saved = React24__namespace.default.useRef(callback);
|
|
10830
11227
|
useIsomorphicLayoutEffect(() => {
|
|
10831
11228
|
saved.current = callback;
|
|
10832
11229
|
}, [callback]);
|
|
10833
|
-
|
|
11230
|
+
React24__namespace.default.useEffect(() => {
|
|
10834
11231
|
if (delay == null) return void 0;
|
|
10835
11232
|
const id = setInterval(() => saved.current(), delay);
|
|
10836
11233
|
return () => clearInterval(id);
|
|
10837
11234
|
}, [delay]);
|
|
10838
11235
|
}
|
|
10839
11236
|
function useTimeout(callback, delay) {
|
|
10840
|
-
const saved =
|
|
11237
|
+
const saved = React24__namespace.default.useRef(callback);
|
|
10841
11238
|
useIsomorphicLayoutEffect(() => {
|
|
10842
11239
|
saved.current = callback;
|
|
10843
11240
|
}, [callback]);
|
|
10844
|
-
|
|
11241
|
+
React24__namespace.default.useEffect(() => {
|
|
10845
11242
|
if (delay == null) return void 0;
|
|
10846
11243
|
const id = setTimeout(() => saved.current(), delay);
|
|
10847
11244
|
return () => clearTimeout(id);
|
|
10848
11245
|
}, [delay]);
|
|
10849
11246
|
}
|
|
10850
11247
|
function useWindowSize() {
|
|
10851
|
-
const [size, setSize] =
|
|
10852
|
-
width:
|
|
10853
|
-
height:
|
|
11248
|
+
const [size, setSize] = React24__namespace.default.useState(() => ({
|
|
11249
|
+
width: canUseDOM2 ? window.innerWidth : 0,
|
|
11250
|
+
height: canUseDOM2 ? window.innerHeight : 0
|
|
10854
11251
|
}));
|
|
10855
|
-
|
|
10856
|
-
if (!
|
|
11252
|
+
React24__namespace.default.useEffect(() => {
|
|
11253
|
+
if (!canUseDOM2) return void 0;
|
|
10857
11254
|
const onResize = () => setSize({ width: window.innerWidth, height: window.innerHeight });
|
|
10858
11255
|
onResize();
|
|
10859
11256
|
window.addEventListener("resize", onResize);
|
|
@@ -10862,8 +11259,8 @@ function useWindowSize() {
|
|
|
10862
11259
|
return size;
|
|
10863
11260
|
}
|
|
10864
11261
|
function useHover(ref) {
|
|
10865
|
-
const [hovered, setHovered] =
|
|
10866
|
-
|
|
11262
|
+
const [hovered, setHovered] = React24__namespace.default.useState(false);
|
|
11263
|
+
React24__namespace.default.useEffect(() => {
|
|
10867
11264
|
const el = ref && ref.current;
|
|
10868
11265
|
if (!el) return void 0;
|
|
10869
11266
|
const on = () => setHovered(true);
|
|
@@ -10879,10 +11276,10 @@ function useHover(ref) {
|
|
|
10879
11276
|
}
|
|
10880
11277
|
function useIntersectionObserver(ref, options = {}) {
|
|
10881
11278
|
const { root = null, rootMargin = "0px", threshold = 0 } = options;
|
|
10882
|
-
const [entry, setEntry] =
|
|
10883
|
-
|
|
11279
|
+
const [entry, setEntry] = React24__namespace.default.useState(null);
|
|
11280
|
+
React24__namespace.default.useEffect(() => {
|
|
10884
11281
|
const el = ref && ref.current;
|
|
10885
|
-
if (!
|
|
11282
|
+
if (!canUseDOM2 || !el || typeof IntersectionObserver === "undefined") return void 0;
|
|
10886
11283
|
const obs = new IntersectionObserver(([e]) => setEntry(e), { root, rootMargin, threshold });
|
|
10887
11284
|
obs.observe(el);
|
|
10888
11285
|
return () => obs.disconnect();
|
|
@@ -10893,7 +11290,7 @@ var __scrollLockCount = 0;
|
|
|
10893
11290
|
var __scrollLockSaved = "";
|
|
10894
11291
|
function useScrollLock(locked = true) {
|
|
10895
11292
|
useIsomorphicLayoutEffect(() => {
|
|
10896
|
-
if (!
|
|
11293
|
+
if (!canUseDOM2 || !locked) return void 0;
|
|
10897
11294
|
if (__scrollLockCount === 0) {
|
|
10898
11295
|
__scrollLockSaved = document.body.style.overflow;
|
|
10899
11296
|
document.body.style.overflow = "hidden";
|
|
@@ -10908,9 +11305,11 @@ function useScrollLock(locked = true) {
|
|
|
10908
11305
|
}, [locked]);
|
|
10909
11306
|
}
|
|
10910
11307
|
function useId(prefix = "twc") {
|
|
10911
|
-
const raw =
|
|
11308
|
+
const raw = React24__namespace.default.useId();
|
|
10912
11309
|
return prefix ? `${prefix}-${raw.replace(/:/g, "")}` : raw;
|
|
10913
11310
|
}
|
|
11311
|
+
var useFocusTrap2 = useFocusTrap;
|
|
11312
|
+
var usePortal2 = usePortal;
|
|
10914
11313
|
|
|
10915
11314
|
exports.Accordion = Accordion;
|
|
10916
11315
|
exports.Alert = Alert;
|
|
@@ -10984,6 +11383,7 @@ exports.useDebouncedCallback = useDebouncedCallback;
|
|
|
10984
11383
|
exports.useDebouncedValue = useDebouncedValue;
|
|
10985
11384
|
exports.useDisclosure = useDisclosure;
|
|
10986
11385
|
exports.useEventListener = useEventListener;
|
|
11386
|
+
exports.useFocusTrap = useFocusTrap2;
|
|
10987
11387
|
exports.useHover = useHover;
|
|
10988
11388
|
exports.useId = useId;
|
|
10989
11389
|
exports.useIntersectionObserver = useIntersectionObserver;
|
|
@@ -10993,6 +11393,7 @@ exports.useKeyPress = useKeyPress;
|
|
|
10993
11393
|
exports.useLocalStorage = useLocalStorage;
|
|
10994
11394
|
exports.useMediaQuery = useMediaQuery;
|
|
10995
11395
|
exports.useMounted = useMounted;
|
|
11396
|
+
exports.usePortal = usePortal2;
|
|
10996
11397
|
exports.usePrefersReducedMotion = usePrefersReducedMotion;
|
|
10997
11398
|
exports.usePrevious = usePrevious;
|
|
10998
11399
|
exports.useScrollLock = useScrollLock;
|