twico-ui 1.7.0 → 1.8.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/dist/index.mjs CHANGED
@@ -1,32 +1,36 @@
1
1
  "use client";
2
- import * as React36 from 'react';
3
- import React36__default from 'react';
2
+ import * as React37 from 'react';
3
+ import React37__default from 'react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
  import { createPortal } from 'react-dom';
6
6
 
7
7
  // components/TwicoProvider.jsx
8
- var SUPPORTS_STYLE_HOIST = parseInt(String(React36.version), 10) >= 19;
9
- var NonceContext = React36.createContext(void 0);
8
+ var SUPPORTS_STYLE_HOIST = parseInt(String(React37.version), 10) >= 19;
9
+ var NonceContext = React37.createContext(void 0);
10
10
  function useScopedStyles(id, css) {
11
- const nonce = React36.useContext(NonceContext);
12
- React36.useInsertionEffect(() => {
11
+ const nonce = React37.useContext(NonceContext);
12
+ React37.useInsertionEffect(() => {
13
13
  if (SUPPORTS_STYLE_HOIST) return;
14
- if (typeof document === "undefined" || document.getElementById(id)) return;
15
- const el = document.createElement("style");
16
- el.id = id;
17
- if (nonce) {
18
- el.setAttribute("nonce", nonce);
19
- el.nonce = nonce;
20
- }
21
- el.textContent = css;
22
- document.head.appendChild(el);
14
+ if (typeof document === "undefined") return;
15
+ if (!css) return;
16
+ let el = document.getElementById(id);
17
+ if (!el) {
18
+ el = document.createElement("style");
19
+ el.id = id;
20
+ if (nonce) {
21
+ el.setAttribute("nonce", nonce);
22
+ el.nonce = nonce;
23
+ }
24
+ document.head.appendChild(el);
25
+ }
26
+ if (el.textContent !== css) el.textContent = css;
23
27
  }, [id, css, nonce]);
24
- return SUPPORTS_STYLE_HOIST ? React36.createElement("style", { href: id, precedence: "twc-ui", nonce }, css) : null;
28
+ return SUPPORTS_STYLE_HOIST && css ? React37.createElement("style", { href: id, precedence: "twc-ui", nonce }, css) : null;
25
29
  }
26
30
 
27
31
  // components/TwicoProvider.jsx
28
32
  function TwicoProvider({ nonce, children }) {
29
- return React36__default.createElement(NonceContext.Provider, { value: nonce }, children);
33
+ return React37__default.createElement(NonceContext.Provider, { value: nonce }, children);
30
34
  }
31
35
  var GROUPS = { colors: "color", space: "space", radius: "radius", font: "font", shadow: "shadow", motion: "" };
32
36
  function createTheme(partial = {}) {
@@ -46,8 +50,8 @@ function toVars(theme) {
46
50
  return Object.keys(theme).some((k) => k.startsWith("--")) ? theme : createTheme(theme);
47
51
  }
48
52
  function ThemeProvider({ theme, mode = "inline", className = "", style, children, ...rest }) {
49
- const vars = React36__default.useMemo(() => toVars(theme), [theme]);
50
- const uid = React36__default.useId();
53
+ const vars = React37__default.useMemo(() => toVars(theme), [theme]);
54
+ const uid = React37__default.useId();
51
55
  const scopeId = `twc-theme-${uid.replace(/[^a-zA-Z0-9]/g, "")}`;
52
56
  const css = mode === "stylesheet" ? `[data-twc-theme="${scopeId}"] { ${Object.entries(vars).map(([k, v]) => `${k}: ${v};`).join(" ")} }` : "";
53
57
  const __twcStyles = useScopedStyles(mode === "stylesheet" ? scopeId : "twc-theme-noop", css);
@@ -69,7 +73,7 @@ var FORM_CSS = `
69
73
  .twc-form { display: flex; flex-direction: column; gap: var(--space-4); font-family: var(--font-sans); }
70
74
  .twc-form__fieldset { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: inherit; }
71
75
  `;
72
- var Form = React36__default.forwardRef(function Form2({
76
+ var Form = React37__default.forwardRef(function Form2({
73
77
  onSubmit,
74
78
  preventDefault = true,
75
79
  loading = false,
@@ -104,7 +108,7 @@ Form.displayName = "Form";
104
108
  var VH_CSS = `
105
109
  .twc-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
106
110
  `;
107
- var VisuallyHidden = React36__default.forwardRef(function VisuallyHidden2({ as: Tag2 = "span", className = "", children, ...rest }, ref) {
111
+ var VisuallyHidden = React37__default.forwardRef(function VisuallyHidden2({ as: Tag2 = "span", className = "", children, ...rest }, ref) {
108
112
  const __twcStyles = useScopedStyles("twc-visually-hidden-styles", VH_CSS);
109
113
  return /* @__PURE__ */ jsxs(Tag2, { ref, className: `twc-visually-hidden ${className}`.trim(), ...rest, children: [
110
114
  __twcStyles,
@@ -113,10 +117,10 @@ var VisuallyHidden = React36__default.forwardRef(function VisuallyHidden2({ as:
113
117
  });
114
118
  VisuallyHidden.displayName = "VisuallyHidden";
115
119
  var canUseDOM = typeof window !== "undefined" && typeof document !== "undefined";
116
- var useIsoLayoutEffect = canUseDOM ? React36__default.useLayoutEffect : React36__default.useEffect;
120
+ var useIsoLayoutEffect = canUseDOM ? React37__default.useLayoutEffect : React37__default.useEffect;
117
121
  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"])';
118
122
  function useFocusTrap(ref, active = true, { restoreFocus = true, initialFocus } = {}) {
119
- React36__default.useEffect(() => {
123
+ React37__default.useEffect(() => {
120
124
  if (!active || !canUseDOM) return void 0;
121
125
  const node = ref.current;
122
126
  if (!node) return void 0;
@@ -127,7 +131,7 @@ function useFocusTrap(ref, active = true, { restoreFocus = true, initialFocus }
127
131
  if (restoreFocus && prevFocused && typeof prevFocused.focus === "function") prevFocused.focus();
128
132
  };
129
133
  }, [active]);
130
- React36__default.useEffect(() => {
134
+ React37__default.useEffect(() => {
131
135
  if (!active || !canUseDOM) return void 0;
132
136
  const node = ref.current;
133
137
  const onKey = (e) => {
@@ -154,7 +158,7 @@ function useFocusTrap(ref, active = true, { restoreFocus = true, initialFocus }
154
158
  }, [active]);
155
159
  }
156
160
  function usePortal() {
157
- return React36__default.useCallback((node) => {
161
+ return React37__default.useCallback((node) => {
158
162
  if (typeof document === "undefined") return null;
159
163
  return typeof createPortal === "function" ? createPortal(node, document.body) : node;
160
164
  }, []);
@@ -182,7 +186,7 @@ function useScrollLock(locked = true) {
182
186
  }, [locked]);
183
187
  }
184
188
  function useInertBackground(ref, active) {
185
- React36__default.useEffect(() => {
189
+ React37__default.useEffect(() => {
186
190
  if (!active || !canUseDOM) return void 0;
187
191
  const node = ref.current;
188
192
  if (!node) return void 0;
@@ -214,7 +218,7 @@ function getColorSchemeScript({ storageKey = "twico-theme", attribute = "class",
214
218
  return `(function(){try{var k=${k},a=${a},d=${d},t=localStorage.getItem(k);if(t!=='light'){if(t!=='dark'){t=d?d:(window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light');}}if(a==='class'){document.documentElement.classList.toggle('dark',t==='dark');}else{document.documentElement.setAttribute(a,t);}}catch(e){}})();`;
215
219
  }
216
220
  function ColorSchemeScript({ storageKey = "twico-theme", attribute = "class", nonce, defaultScheme }) {
217
- return React36__default.createElement("script", { nonce }, getColorSchemeScript({ storageKey, attribute, defaultScheme }));
221
+ return React37__default.createElement("script", { nonce }, getColorSchemeScript({ storageKey, attribute, defaultScheme }));
218
222
  }
219
223
  var KBD_CSS = `
220
224
  .twc-kbd { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; padding: 2px 6px;
@@ -222,7 +226,7 @@ var KBD_CSS = `
222
226
  background: var(--color-surface-sunken); border: var(--border-thin) solid var(--color-border);
223
227
  border-bottom-width: 2px; border-radius: var(--radius-sm); }
224
228
  `;
225
- var Kbd = React36__default.forwardRef(function Kbd2({ className = "", children, ...rest }, ref) {
229
+ var Kbd = React37__default.forwardRef(function Kbd2({ className = "", children, ...rest }, ref) {
226
230
  const __twcStyles = useScopedStyles("twc-kbd-styles", KBD_CSS);
227
231
  return /* @__PURE__ */ jsxs("kbd", { ref, className: `twc-kbd ${className}`.trim(), ...rest, children: [
228
232
  __twcStyles,
@@ -237,7 +241,7 @@ var PRE_CSS = `
237
241
  border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-lg);
238
242
  white-space: pre; -webkit-overflow-scrolling: touch; }
239
243
  `;
240
- var Pre = React36__default.forwardRef(function Pre2({ className = "", children, ...rest }, ref) {
244
+ var Pre = React37__default.forwardRef(function Pre2({ className = "", children, ...rest }, ref) {
241
245
  const __twcStyles = useScopedStyles("twc-pre-styles", PRE_CSS);
242
246
  return /* @__PURE__ */ jsxs("pre", { ref, className: `twc-pre ${className}`.trim(), ...rest, children: [
243
247
  __twcStyles,
@@ -257,7 +261,7 @@ function safeHref(url) {
257
261
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
258
262
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
259
263
  }
260
- var Anchor = React36__default.forwardRef(function Anchor2({ as: Tag2 = "a", href, external = false, className = "", children, ...rest }, ref) {
264
+ var Anchor = React37__default.forwardRef(function Anchor2({ as: Tag2 = "a", href, external = false, className = "", children, ...rest }, ref) {
261
265
  const __twcStyles = useScopedStyles("twc-anchor-styles", ANCHOR_CSS);
262
266
  const extra = external ? { target: "_blank", rel: "noopener noreferrer" } : {};
263
267
  return /* @__PURE__ */ jsxs(Tag2, { ref, className: `twc-anchor ${className}`.trim(), href: Tag2 === "a" ? safeHref(href) : href, ...extra, ...rest, children: [
@@ -273,7 +277,7 @@ var LABEL_CSS = `
273
277
  .twc-label[data-size="lg"] { font-size: var(--text-base); }
274
278
  .twc-label__req { color: var(--color-danger); }
275
279
  `;
276
- var Label = React36__default.forwardRef(function Label2({ htmlFor, required = false, size = "md", className = "", children, ...rest }, ref) {
280
+ var Label = React37__default.forwardRef(function Label2({ htmlFor, required = false, size = "md", className = "", children, ...rest }, ref) {
277
281
  const __twcStyles = useScopedStyles("twc-label-styles", LABEL_CSS);
278
282
  return /* @__PURE__ */ jsxs("label", { ref, htmlFor, className: `twc-label ${className}`.trim(), "data-size": size, ...rest, children: [
279
283
  __twcStyles,
@@ -286,7 +290,7 @@ var IMAGE_CSS = `
286
290
  .twc-image { display: block; max-width: 100%; }
287
291
  .twc-image[data-fit] { width: 100%; height: 100%; }
288
292
  `;
289
- var Image = React36__default.forwardRef(function Image2({
293
+ var Image = React37__default.forwardRef(function Image2({
290
294
  src,
291
295
  alt,
292
296
  fit,
@@ -300,7 +304,7 @@ var Image = React36__default.forwardRef(function Image2({
300
304
  ...rest
301
305
  }, ref) {
302
306
  const __twcStyles = useScopedStyles("twc-image-styles", IMAGE_CSS);
303
- const [failed, setFailed] = React36__default.useState(false);
307
+ const [failed, setFailed] = React37__default.useState(false);
304
308
  const shownSrc = failed && fallback ? fallback : src;
305
309
  const s = {
306
310
  objectFit: fit,
@@ -369,10 +373,10 @@ function Accordion({
369
373
  ...rest
370
374
  }) {
371
375
  const __twcStyles = useScopedStyles("twc-accordion-styles", ACCORDION_CSS);
372
- const rootRef = React36__default.useRef(null);
373
- const [internal, setInternal] = React36__default.useState(() => new Set(defaultOpen));
376
+ const rootRef = React37__default.useRef(null);
377
+ const [internal, setInternal] = React37__default.useState(() => new Set(defaultOpen));
374
378
  const open = openProp !== void 0 ? new Set(openProp) : internal;
375
- const baseId = React36__default.useId();
379
+ const baseId = React37__default.useId();
376
380
  function toggle(val) {
377
381
  const item = items.find((x) => x.value === val);
378
382
  if (item?.disabled) return;
@@ -558,7 +562,7 @@ function Avatar({
558
562
  ...rest
559
563
  }) {
560
564
  const __twcStyles = useScopedStyles("twc-avatar-styles", AVATAR_CSS);
561
- const [errored, setErrored] = React36__default.useState(false);
565
+ const [errored, setErrored] = React37__default.useState(false);
562
566
  const cleanSrc = safeSrc(src);
563
567
  const showImg = cleanSrc && !errored;
564
568
  const _statusLabel = status ? statusLabel ?? statusLabels?.[status] ?? STATUS_LABELS[status] : void 0;
@@ -636,25 +640,25 @@ function Menu({
636
640
  ...rest
637
641
  }) {
638
642
  const __twcStyles = useScopedStyles("twc-menu-styles", MENU_CSS);
639
- const [openState, setOpenState] = React36__default.useState(defaultOpen);
640
- const [render, setRender] = React36__default.useState(false);
641
- const [pos, setPos] = React36__default.useState(null);
642
- const [active, setActive] = React36__default.useState(-1);
643
- const wrapRef = React36__default.useRef(null);
644
- const menuRef = React36__default.useRef(null);
645
- const typeBufRef = React36__default.useRef("");
646
- const typeTimerRef = React36__default.useRef(null);
647
- const menuId = React36__default.useId();
643
+ const [openState, setOpenState] = React37__default.useState(defaultOpen);
644
+ const [render, setRender] = React37__default.useState(false);
645
+ const [pos, setPos] = React37__default.useState(null);
646
+ const [active, setActive] = React37__default.useState(-1);
647
+ const wrapRef = React37__default.useRef(null);
648
+ const menuRef = React37__default.useRef(null);
649
+ const typeBufRef = React37__default.useRef("");
650
+ const typeTimerRef = React37__default.useRef(null);
651
+ const menuId = React37__default.useId();
648
652
  const headerId = `${menuId}-header`;
649
653
  const controlled = openProp !== void 0;
650
654
  const open = controlled ? !!openProp : openState;
651
- const openRef = React36__default.useRef(open);
655
+ const openRef = React37__default.useRef(open);
652
656
  openRef.current = open;
653
- const controlledRef = React36__default.useRef(controlled);
657
+ const controlledRef = React37__default.useRef(controlled);
654
658
  controlledRef.current = controlled;
655
- const onOpenChangeRef = React36__default.useRef(onOpenChange);
659
+ const onOpenChangeRef = React37__default.useRef(onOpenChange);
656
660
  onOpenChangeRef.current = onOpenChange;
657
- const setOpen = React36__default.useCallback((next) => {
661
+ const setOpen = React37__default.useCallback((next) => {
658
662
  const value = typeof next === "function" ? next(openRef.current) : next;
659
663
  if (value === openRef.current) return;
660
664
  if (!controlledRef.current) setOpenState(value);
@@ -662,7 +666,7 @@ function Menu({
662
666
  }, []);
663
667
  const RD = { createPortal: typeof createPortal === "function" ? createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
664
668
  const interactiveIdx = items.map((it, i) => !it.separator && !it.heading ? i : -1).filter((i) => i >= 0);
665
- const place = React36__default.useCallback(() => {
669
+ const place = React37__default.useCallback(() => {
666
670
  const t = wrapRef.current;
667
671
  if (!t) return;
668
672
  const r = t.getBoundingClientRect();
@@ -677,7 +681,7 @@ function Menu({
677
681
  const avail = (flip ? r.top : vh - r.bottom) - gap - M;
678
682
  setPos({ top, bottom, left, width: w, flip, maxHeight: Math.max(120, avail) });
679
683
  }, [align, width]);
680
- React36__default.useEffect(() => {
684
+ React37__default.useEffect(() => {
681
685
  if (!open) return;
682
686
  place();
683
687
  const onMove = () => place();
@@ -695,7 +699,7 @@ function Menu({
695
699
  document.removeEventListener("mousedown", onDown);
696
700
  };
697
701
  }, [open, place]);
698
- React36__default.useEffect(() => {
702
+ React37__default.useEffect(() => {
699
703
  if (open) {
700
704
  setRender(true);
701
705
  return;
@@ -818,7 +822,7 @@ function Menu({
818
822
  }
819
823
  ) : null;
820
824
  const activeDescId = open && active >= 0 ? `${menuId}-item-${active}` : void 0;
821
- const triggerEl = React36__default.isValidElement(trigger) ? React36__default.cloneElement(trigger, {
825
+ const triggerEl = React37__default.isValidElement(trigger) ? React37__default.cloneElement(trigger, {
822
826
  onClick: (e) => {
823
827
  trigger.props.onClick?.(e);
824
828
  toggle();
@@ -983,7 +987,7 @@ function Breadcrumb({
983
987
  ...rest
984
988
  }) {
985
989
  const __twcStyles = useScopedStyles("twc-breadcrumb-styles", BREADCRUMB_CSS);
986
- const [expanded, setExpanded] = React36__default.useState(false);
990
+ const [expanded, setExpanded] = React37__default.useState(false);
987
991
  const sep = separator || /* @__PURE__ */ jsx(ChevronSep, {});
988
992
  let display = items;
989
993
  if (maxItems > 0 && items.length > maxItems && !expanded) {
@@ -996,7 +1000,7 @@ function Breadcrumb({
996
1000
  __twcStyles,
997
1001
  display.map((it, i) => {
998
1002
  const last = i === display.length - 1;
999
- return /* @__PURE__ */ jsxs(React36__default.Fragment, { children: [
1003
+ return /* @__PURE__ */ jsxs(React37__default.Fragment, { children: [
1000
1004
  it.ellipsis ? /* @__PURE__ */ jsx("button", { className: "twc-breadcrumb__ellipsis", "aria-label": "Show more", onClick: () => setExpanded(true), children: "\u2026" }) : last ? /* @__PURE__ */ jsxs(
1001
1005
  "span",
1002
1006
  {
@@ -1138,7 +1142,7 @@ function Button({
1138
1142
  ...rest
1139
1143
  }) {
1140
1144
  const __twcStyles = useScopedStyles("twc-btn-styles", CSS2);
1141
- const [ripples, setRipples] = React36__default.useState([]);
1145
+ const [ripples, setRipples] = React37__default.useState([]);
1142
1146
  const Tag2 = as;
1143
1147
  const inert = Tag2 === "a" && (disabled || loading);
1144
1148
  function handleClick(e) {
@@ -1193,6 +1197,122 @@ function Button({
1193
1197
  }
1194
1198
  );
1195
1199
  }
1200
+ var UNITLESS = /* @__PURE__ */ new Set([
1201
+ "animationIterationCount",
1202
+ "aspectRatio",
1203
+ "borderImageOutset",
1204
+ "borderImageSlice",
1205
+ "borderImageWidth",
1206
+ "boxFlex",
1207
+ "boxFlexGroup",
1208
+ "boxOrdinalGroup",
1209
+ "columnCount",
1210
+ "columns",
1211
+ "flex",
1212
+ "flexGrow",
1213
+ "flexShrink",
1214
+ "flexPositive",
1215
+ "flexNegative",
1216
+ "flexOrder",
1217
+ "gridArea",
1218
+ "gridRow",
1219
+ "gridRowEnd",
1220
+ "gridRowSpan",
1221
+ "gridRowStart",
1222
+ "gridColumn",
1223
+ "gridColumnEnd",
1224
+ "gridColumnSpan",
1225
+ "gridColumnStart",
1226
+ "fontWeight",
1227
+ "lineClamp",
1228
+ "lineHeight",
1229
+ "opacity",
1230
+ "order",
1231
+ "orphans",
1232
+ "tabSize",
1233
+ "widows",
1234
+ "zIndex",
1235
+ "zoom",
1236
+ "fillOpacity",
1237
+ "floodOpacity",
1238
+ "stopOpacity",
1239
+ "strokeDasharray",
1240
+ "strokeDashoffset",
1241
+ "strokeMiterlimit",
1242
+ "strokeOpacity",
1243
+ "strokeWidth",
1244
+ "scale"
1245
+ ]);
1246
+ var isObject = (v) => v != null && typeof v === "object" && !Array.isArray(v);
1247
+ var isNestedKey = (k, v) => isObject(v) || k.charCodeAt(0) === 38 || k.charCodeAt(0) === 64 || k.charCodeAt(0) === 58;
1248
+ function kebab(prop) {
1249
+ if (prop.startsWith("--")) return prop;
1250
+ return prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
1251
+ }
1252
+ function cssValue(key, value) {
1253
+ if (typeof value !== "number") return String(value);
1254
+ if (value === 0 || key.startsWith("--") || UNITLESS.has(key)) return String(value);
1255
+ return `${value}px`;
1256
+ }
1257
+ function resolveSelector(key, scope) {
1258
+ if (key.includes("&")) return key.replace(/&/g, scope);
1259
+ if (key.charCodeAt(0) === 58) return `${scope}${key}`;
1260
+ return `${scope} ${key}`;
1261
+ }
1262
+ function compileSx(obj, selector) {
1263
+ if (!isObject(obj)) return "";
1264
+ let decls = "";
1265
+ let rules = "";
1266
+ for (const key of Object.keys(obj)) {
1267
+ const value = obj[key];
1268
+ if (isNestedKey(key, value)) {
1269
+ if (!isObject(value)) continue;
1270
+ if (key.charCodeAt(0) === 64) {
1271
+ const inner = compileSx(value, selector);
1272
+ if (inner) rules += `${key} { ${inner.trim()} }
1273
+ `;
1274
+ } else {
1275
+ rules += compileSx(value, resolveSelector(key, selector));
1276
+ }
1277
+ } else {
1278
+ decls += `${kebab(key)}: ${cssValue(key, value)}; `;
1279
+ }
1280
+ }
1281
+ let out = "";
1282
+ if (decls) out += `${selector} { ${decls.trimEnd()} }
1283
+ `;
1284
+ out += rules;
1285
+ return out;
1286
+ }
1287
+ function buildSx(sx, uid) {
1288
+ if (!isObject(sx)) return { flatStyle: void 0, css: "" };
1289
+ const scope = `[data-twc-sx="${uid}"]`;
1290
+ let flatStyle;
1291
+ let css = "";
1292
+ for (const key of Object.keys(sx)) {
1293
+ const value = sx[key];
1294
+ if (isNestedKey(key, value)) {
1295
+ if (!isObject(value)) continue;
1296
+ if (key.charCodeAt(0) === 64) {
1297
+ const inner = compileSx(value, scope);
1298
+ if (inner) css += `${key} { ${inner.trim()} }
1299
+ `;
1300
+ } else {
1301
+ css += compileSx(value, resolveSelector(key, scope));
1302
+ }
1303
+ } else {
1304
+ (flatStyle || (flatStyle = {}))[key] = value;
1305
+ }
1306
+ }
1307
+ return { flatStyle, css };
1308
+ }
1309
+ function useSx(sx) {
1310
+ const rawId = React37__default.useId();
1311
+ const uid = `sx${rawId.replace(/[^a-zA-Z0-9]/g, "")}`;
1312
+ const { flatStyle, css } = React37__default.useMemo(() => buildSx(sx, uid), [sx, uid]);
1313
+ const styleNode = useScopedStyles(`twc-sx-${uid}`, css);
1314
+ return { flatStyle, styleNode, sxAttr: css ? uid : void 0 };
1315
+ }
1196
1316
  var CARD_CSS = `
1197
1317
  .twc-card {
1198
1318
  display: flex; flex-direction: column;
@@ -1232,10 +1352,13 @@ function Card({
1232
1352
  padding = "md",
1233
1353
  interactive = false,
1234
1354
  fullHeight = false,
1355
+ sx,
1235
1356
  className = "",
1357
+ style,
1236
1358
  ...rest
1237
1359
  }) {
1238
1360
  const __twcStyles = useScopedStyles("twc-card-styles", CARD_CSS);
1361
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
1239
1362
  return /* @__PURE__ */ jsxs(
1240
1363
  "div",
1241
1364
  {
@@ -1244,9 +1367,12 @@ function Card({
1244
1367
  "data-pad": padding,
1245
1368
  "data-interactive": interactive || void 0,
1246
1369
  "data-full": fullHeight || void 0,
1370
+ "data-twc-sx": sxAttr,
1371
+ style: style || flatStyle ? { ...style, ...flatStyle } : void 0,
1247
1372
  ...rest,
1248
1373
  children: [
1249
1374
  __twcStyles,
1375
+ styleNode,
1250
1376
  title || subtitle || actions ? /* @__PURE__ */ jsxs("div", { className: "twc-card__header", children: [
1251
1377
  /* @__PURE__ */ jsxs("div", { className: "twc-card__heading", children: [
1252
1378
  title ? /* @__PURE__ */ jsx("div", { className: "twc-card__title", children: title }) : null,
@@ -1312,14 +1438,14 @@ function Carousel({
1312
1438
  ...rest
1313
1439
  }) {
1314
1440
  const __twcStyles = useScopedStyles("twc-carousel-styles", CAROUSEL_CSS);
1315
- const slides = React36__default.Children.toArray(children);
1441
+ const slides = React37__default.Children.toArray(children);
1316
1442
  const count = slides.length;
1317
- const [internal, setInternal] = React36__default.useState(defaultIndex);
1443
+ const [internal, setInternal] = React37__default.useState(defaultIndex);
1318
1444
  const index = indexProp !== void 0 ? indexProp : internal;
1319
- const [paused, setPaused] = React36__default.useState(false);
1320
- const [userPaused, setUserPaused] = React36__default.useState(false);
1321
- const [prefersReduced, setPrefersReduced] = React36__default.useState(false);
1322
- React36__default.useEffect(() => {
1445
+ const [paused, setPaused] = React37__default.useState(false);
1446
+ const [userPaused, setUserPaused] = React37__default.useState(false);
1447
+ const [prefersReduced, setPrefersReduced] = React37__default.useState(false);
1448
+ React37__default.useEffect(() => {
1323
1449
  if (typeof window === "undefined" || !window.matchMedia) return void 0;
1324
1450
  const mql = window.matchMedia("(prefers-reduced-motion: reduce)");
1325
1451
  const on = () => setPrefersReduced(mql.matches);
@@ -1327,15 +1453,15 @@ function Carousel({
1327
1453
  mql.addEventListener("change", on);
1328
1454
  return () => mql.removeEventListener("change", on);
1329
1455
  }, []);
1330
- const setIndex = React36__default.useCallback((i) => {
1456
+ const setIndex = React37__default.useCallback((i) => {
1331
1457
  if (indexProp === void 0) setInternal(i);
1332
1458
  onIndexChange?.(i);
1333
1459
  }, [indexProp, onIndexChange]);
1334
- const go = React36__default.useCallback((i) => {
1460
+ const go = React37__default.useCallback((i) => {
1335
1461
  setIndex(loop ? (i + count) % count : Math.min(Math.max(i, 0), count - 1));
1336
1462
  }, [count, loop, setIndex]);
1337
1463
  const autoRotating = autoPlay && !paused && !userPaused && !prefersReduced && count > 1;
1338
- React36__default.useEffect(() => {
1464
+ React37__default.useEffect(() => {
1339
1465
  if (!autoRotating) return void 0;
1340
1466
  const t = setInterval(() => {
1341
1467
  const next = loop ? (index + 1) % count : index + 1 >= count ? index : index + 1;
@@ -1430,7 +1556,7 @@ function Chart({
1430
1556
  ...rest
1431
1557
  }) {
1432
1558
  const __twcStyles = useScopedStyles("twc-chart-styles", CHART_CSS);
1433
- const uid = React36__default.useId();
1559
+ const uid = React37__default.useId();
1434
1560
  const tableId = tableFallback ? `${uid}-table` : void 0;
1435
1561
  const keys = series || ["value"];
1436
1562
  const palette = colors && colors.length ? colors : SERIES_COLORS;
@@ -1586,13 +1712,13 @@ function Checkbox({
1586
1712
  .twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
1587
1713
  .twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
1588
1714
  `);
1589
- const autoId = React36__default.useId();
1715
+ const autoId = React37__default.useId();
1590
1716
  const fieldId = id || autoId;
1591
1717
  const errId = `${fieldId}-error`;
1592
1718
  const invalid = Boolean(error);
1593
- const ref = React36__default.useRef(null);
1719
+ const ref = React37__default.useRef(null);
1594
1720
  const mixed = indeterminate && !checked;
1595
- React36__default.useEffect(() => {
1721
+ React37__default.useEffect(() => {
1596
1722
  if (ref.current) ref.current.indeterminate = mixed;
1597
1723
  }, [mixed]);
1598
1724
  if (process.env.NODE_ENV !== "production" && !label && !description && !rest["aria-label"] && !rest["aria-labelledby"]) {
@@ -1665,6 +1791,10 @@ var COLORPICKER_CSS = `
1665
1791
  .twc-cp__hue { position: relative; height: 12px; margin-top: var(--space-3); border-radius: var(--radius-full); cursor: pointer; touch-action: none;
1666
1792
  background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); }
1667
1793
  .twc-cp__hue-knob { position: absolute; top: 50%; width: 16px; height: 16px; border-radius: var(--radius-full); background: #fff; box-shadow: var(--shadow-sm), inset 0 0 0 1px rgb(0 0 0 / 0.2); transform: translate(-50%, -50%); pointer-events: none; }
1794
+ .twc-cp__alpha { position: relative; height: 12px; margin-top: var(--space-2); border-radius: var(--radius-full); cursor: pointer; touch-action: none;
1795
+ background-image: linear-gradient(to right, transparent, var(--_solid, #000)), conic-gradient(#c8c8c8 0 25%, #fff 0 50%, #c8c8c8 0 75%, #fff 0);
1796
+ background-size: 100% 100%, 10px 10px; }
1797
+ .twc-cp__alpha:focus-visible { outline: none; box-shadow: var(--ring); }
1668
1798
  .twc-cp__foot { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-3); }
1669
1799
  .twc-cp__hex { flex: 1; min-width: 0; height: 32px; padding: 0 8px; font-family: var(--font-mono); font-size: var(--text-xs); text-transform: uppercase;
1670
1800
  color: var(--color-text); background: var(--color-surface); border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-sm); outline: none; }
@@ -1702,11 +1832,17 @@ function rgbToHex(r, g, b) {
1702
1832
  function hsvToHex(h, s, v) {
1703
1833
  return rgbToHex(...hsvToRgb(h, s, v));
1704
1834
  }
1835
+ function hsvaToHex8(h, s, v, a) {
1836
+ return rgbToHex(...hsvToRgb(h, s, v)) + Math.round(Math.min(1, Math.max(0, a)) * 255).toString(16).padStart(2, "0");
1837
+ }
1705
1838
  function hexToHsv(hex) {
1706
- const m = /^#?([0-9a-f]{6})$/i.exec(hex || "");
1839
+ let str = String(hex || "").replace(/^#/, "");
1840
+ if (/^[0-9a-f]{3}$/i.test(str)) str = str.split("").map((c) => c + c).join("");
1841
+ const m = /^([0-9a-f]{6})([0-9a-f]{2})?$/i.exec(str);
1707
1842
  if (!m) return null;
1708
1843
  const int = parseInt(m[1], 16);
1709
1844
  const r = (int >> 16) / 255, g = (int >> 8 & 255) / 255, b = (int & 255) / 255;
1845
+ const a = m[2] != null ? parseInt(m[2], 16) / 255 : 1;
1710
1846
  const max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min;
1711
1847
  let h = 0;
1712
1848
  if (d) {
@@ -1716,7 +1852,7 @@ function hexToHsv(hex) {
1716
1852
  h *= 60;
1717
1853
  if (h < 0) h += 360;
1718
1854
  }
1719
- return { h, s: max ? d / max * 100 : 0, v: max * 100 };
1855
+ return { h, s: max ? d / max * 100 : 0, v: max * 100, a };
1720
1856
  }
1721
1857
  var DEFAULT_PRESETS = ["#6366F1", "#0EA5E9", "#14B8A6", "#22C55E", "#F59E0B", "#F43F5E", "#8B5CF6", "#0F172A"];
1722
1858
  function ColorPicker({
@@ -1728,6 +1864,7 @@ function ColorPicker({
1728
1864
  defaultValue = "#6366F1",
1729
1865
  presets = DEFAULT_PRESETS,
1730
1866
  disabled = false,
1867
+ alpha = false,
1731
1868
  tone = "primary",
1732
1869
  onChange,
1733
1870
  className = "",
@@ -1735,20 +1872,22 @@ function ColorPicker({
1735
1872
  }) {
1736
1873
  const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS);
1737
1874
  const __twcStyles1 = useScopedStyles("twc-colorpicker-styles", COLORPICKER_CSS);
1738
- const [internal, setInternal] = React36__default.useState(defaultValue);
1875
+ const [internal, setInternal] = React37__default.useState(defaultValue);
1739
1876
  const hex = (value !== void 0 ? value : internal) || "#000000";
1740
- const lastValidRef = React36__default.useRef(hex);
1741
- if (/^#[0-9a-f]{6}$/i.test(hex)) lastValidRef.current = hex;
1742
- const [open, setOpen] = React36__default.useState(false);
1743
- const [hsv, setHsv] = React36__default.useState(() => hexToHsv(hex) || { h: 239, s: 60, v: 94 });
1744
- const [coords, setCoords] = React36__default.useState(null);
1745
- const wrapRef = React36__default.useRef(null);
1746
- const triggerRef = React36__default.useRef(null);
1747
- const popRef = React36__default.useRef(null);
1748
- const areaRef = React36__default.useRef(null);
1749
- const hueRef = React36__default.useRef(null);
1877
+ const hexRe = alpha ? /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i : /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
1878
+ const lastValidRef = React37__default.useRef(hex);
1879
+ if (hexRe.test(hex)) lastValidRef.current = hex;
1880
+ const [open, setOpen] = React37__default.useState(false);
1881
+ const [hsv, setHsv] = React37__default.useState(() => hexToHsv(hex) || { h: 239, s: 60, v: 94, a: 1 });
1882
+ const [coords, setCoords] = React37__default.useState(null);
1883
+ const wrapRef = React37__default.useRef(null);
1884
+ const triggerRef = React37__default.useRef(null);
1885
+ const popRef = React37__default.useRef(null);
1886
+ const areaRef = React37__default.useRef(null);
1887
+ const hueRef = React37__default.useRef(null);
1888
+ const alphaRef = React37__default.useRef(null);
1750
1889
  const POP_W = 240;
1751
- const place = React36__default.useCallback(() => {
1890
+ const place = React37__default.useCallback(() => {
1752
1891
  const el = triggerRef.current;
1753
1892
  if (!el) return;
1754
1893
  const r = el.getBoundingClientRect();
@@ -1759,7 +1898,7 @@ function ColorPicker({
1759
1898
  left = Math.max(8, left);
1760
1899
  setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
1761
1900
  }, []);
1762
- React36__default.useEffect(() => {
1901
+ React37__default.useEffect(() => {
1763
1902
  if (!open) return void 0;
1764
1903
  place();
1765
1904
  const onMove = () => place();
@@ -1770,17 +1909,17 @@ function ColorPicker({
1770
1909
  window.removeEventListener("resize", onMove);
1771
1910
  };
1772
1911
  }, [open, place]);
1773
- const labelId = React36__default.useId();
1912
+ const labelId = React37__default.useId();
1774
1913
  const descId = `${labelId}-desc`;
1775
1914
  const invalid = Boolean(error);
1776
- React36__default.useEffect(() => {
1915
+ React37__default.useEffect(() => {
1777
1916
  if (disabled) setOpen(false);
1778
1917
  }, [disabled]);
1779
- React36__default.useEffect(() => {
1918
+ React37__default.useEffect(() => {
1780
1919
  const v = hexToHsv(hex);
1781
1920
  if (v && hsvToHex(v.h, v.s, v.v).toLowerCase() !== hsvToHex(hsv.h, hsv.s, hsv.v).toLowerCase()) setHsv(v);
1782
1921
  }, [hex]);
1783
- React36__default.useEffect(() => {
1922
+ React37__default.useEffect(() => {
1784
1923
  if (!open) return;
1785
1924
  const onDown = (e) => {
1786
1925
  if (wrapRef.current && wrapRef.current.contains(e.target)) return;
@@ -1799,10 +1938,10 @@ function ColorPicker({
1799
1938
  }, [open]);
1800
1939
  useFocusTrap(popRef, open && !!coords, { initialFocus: areaRef });
1801
1940
  const commit = (next) => {
1802
- const h = hsvToHex(next.h, next.s, next.v);
1941
+ const out = alpha ? hsvaToHex8(next.h, next.s, next.v, next.a ?? 1) : hsvToHex(next.h, next.s, next.v);
1803
1942
  setHsv(next);
1804
- if (value === void 0) setInternal(h);
1805
- onChange?.(h);
1943
+ if (value === void 0) setInternal(out);
1944
+ onChange?.(out);
1806
1945
  };
1807
1946
  const dragArea = (e) => {
1808
1947
  const r = areaRef.current.getBoundingClientRect();
@@ -1846,6 +1985,21 @@ function ColorPicker({
1846
1985
  e.preventDefault();
1847
1986
  commit({ ...hsv, h });
1848
1987
  };
1988
+ const dragAlpha = (e) => {
1989
+ const r = alphaRef.current.getBoundingClientRect();
1990
+ const a = Math.min(1, Math.max(0, (e.clientX - r.left) / r.width));
1991
+ commit({ ...hsv, a });
1992
+ };
1993
+ const onAlphaKeyDown = (e) => {
1994
+ let a = hsv.a ?? 1;
1995
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") a = Math.min(1, a + 0.01);
1996
+ else if (e.key === "ArrowLeft" || e.key === "ArrowDown") a = Math.max(0, a - 0.01);
1997
+ else if (e.key === "Home") a = 0;
1998
+ else if (e.key === "End") a = 1;
1999
+ else return;
2000
+ e.preventDefault();
2001
+ commit({ ...hsv, a: Math.round(a * 100) / 100 });
2002
+ };
1849
2003
  return /* @__PURE__ */ jsxs("div", { className: `twc-cp twc-field ${className}`, ref: wrapRef, ...rest, children: [
1850
2004
  __twcStyles0,
1851
2005
  __twcStyles1,
@@ -1932,6 +2086,23 @@ function ColorPicker({
1932
2086
  children: /* @__PURE__ */ jsx("span", { className: "twc-cp__hue-knob", style: { left: `${hsv.h / 360 * 100}%` } })
1933
2087
  }
1934
2088
  ),
2089
+ alpha ? /* @__PURE__ */ jsx(
2090
+ "div",
2091
+ {
2092
+ className: "twc-cp__alpha",
2093
+ ref: alphaRef,
2094
+ onPointerDown: startDrag(dragAlpha),
2095
+ role: "slider",
2096
+ tabIndex: 0,
2097
+ "aria-label": "Alpha",
2098
+ "aria-valuemin": 0,
2099
+ "aria-valuemax": 100,
2100
+ "aria-valuenow": Math.round((hsv.a ?? 1) * 100),
2101
+ onKeyDown: onAlphaKeyDown,
2102
+ style: { "--_solid": hsvToHex(hsv.h, hsv.s, hsv.v) },
2103
+ children: /* @__PURE__ */ jsx("span", { className: "twc-cp__hue-knob", style: { left: `${(hsv.a ?? 1) * 100}%` } })
2104
+ }
2105
+ ) : null,
1935
2106
  /* @__PURE__ */ jsxs("div", { className: "twc-cp__foot", children: [
1936
2107
  /* @__PURE__ */ jsx("span", { className: "twc-cp__swatch", style: { background: hex } }),
1937
2108
  /* @__PURE__ */ jsx(
@@ -1940,10 +2111,10 @@ function ColorPicker({
1940
2111
  className: "twc-cp__hex",
1941
2112
  "data-tone": tone,
1942
2113
  value: hex,
1943
- maxLength: 7,
2114
+ maxLength: alpha ? 9 : 7,
1944
2115
  "aria-label": "Hex color",
1945
- "aria-invalid": !/^#[0-9a-f]{6}$/i.test(hex) || void 0,
1946
- "data-invalid": !/^#[0-9a-f]{6}$/i.test(hex) || void 0,
2116
+ "aria-invalid": !hexRe.test(hex) || void 0,
2117
+ "data-invalid": !hexRe.test(hex) || void 0,
1947
2118
  onChange: (e) => {
1948
2119
  let v = e.target.value;
1949
2120
  if (!v.startsWith("#")) v = "#" + v;
@@ -1953,7 +2124,7 @@ function ColorPicker({
1953
2124
  if (p) setHsv(p);
1954
2125
  },
1955
2126
  onBlur: () => {
1956
- if (/^#[0-9a-f]{6}$/i.test(hex)) return;
2127
+ if (hexRe.test(hex)) return;
1957
2128
  const revert = lastValidRef.current;
1958
2129
  if (revert === hex) return;
1959
2130
  if (value === void 0) setInternal(revert);
@@ -2111,6 +2282,8 @@ function Combobox({
2111
2282
  loading = false,
2112
2283
  emptyText = "No results found",
2113
2284
  name,
2285
+ virtualized = false,
2286
+ overscan = 8,
2114
2287
  id,
2115
2288
  className = "",
2116
2289
  onFocus,
@@ -2118,29 +2291,51 @@ function Combobox({
2118
2291
  ...rest
2119
2292
  }) {
2120
2293
  const __twcStyles = useScopedStyles("twc-combo-styles", COMBO_CSS);
2121
- const groups = React36__default.useMemo(() => normalizeGroups(options), [options]);
2122
- const flat = React36__default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
2123
- const autoId = React36__default.useId();
2294
+ const groups = React37__default.useMemo(() => normalizeGroups(options), [options]);
2295
+ const flat = React37__default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
2296
+ const autoId = React37__default.useId();
2124
2297
  const fieldId = id || autoId;
2125
- const [internal, setInternal] = React36__default.useState(defaultValue);
2298
+ const [internal, setInternal] = React37__default.useState(defaultValue);
2126
2299
  const current = value !== void 0 ? value : internal;
2127
2300
  const selected = flat.find((o) => o.value === current);
2128
- const [open, setOpen] = React36__default.useState(false);
2129
- const [query, setQuery] = React36__default.useState("");
2130
- const [active, setActive] = React36__default.useState(0);
2131
- const [coords, setCoords] = React36__default.useState(null);
2132
- const wrapRef = React36__default.useRef(null);
2133
- const controlRef = React36__default.useRef(null);
2134
- const inputRef = React36__default.useRef(null);
2135
- const popRef = React36__default.useRef(null);
2136
- const listRef = React36__default.useRef(null);
2137
- const activeRef = React36__default.useRef(null);
2138
- const fGroups = React36__default.useMemo(() => {
2301
+ const [open, setOpen] = React37__default.useState(false);
2302
+ const [query, setQuery] = React37__default.useState("");
2303
+ const [active, setActive] = React37__default.useState(0);
2304
+ const [coords, setCoords] = React37__default.useState(null);
2305
+ const [scrollTop, setScrollTop] = React37__default.useState(0);
2306
+ const [listH, setListH] = React37__default.useState(260);
2307
+ const wrapRef = React37__default.useRef(null);
2308
+ const controlRef = React37__default.useRef(null);
2309
+ const inputRef = React37__default.useRef(null);
2310
+ const popRef = React37__default.useRef(null);
2311
+ const listRef = React37__default.useRef(null);
2312
+ const activeRef = React37__default.useRef(null);
2313
+ const fGroups = React37__default.useMemo(() => {
2139
2314
  const q = query.trim();
2140
2315
  const fn = filter === false ? null : typeof filter === "function" ? filter : matches;
2141
2316
  return groups.map((g) => ({ group: g.group, options: fn ? g.options.filter((o) => fn(o, q)) : g.options })).filter((g) => g.options.length);
2142
2317
  }, [groups, query, filter]);
2143
- const visible = React36__default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
2318
+ const visible = React37__default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
2319
+ const rowH = React37__default.useMemo(() => visible.some((o) => o.description) ? 48 : 36, [visible]);
2320
+ const GROUP_H = 30;
2321
+ const { rows, totalH } = React37__default.useMemo(() => {
2322
+ if (!virtualized) return { rows: [], totalH: 0 };
2323
+ const rows2 = [];
2324
+ let off = 0;
2325
+ let optIdx = -1;
2326
+ fGroups.forEach((g, gi) => {
2327
+ if (g.group) {
2328
+ rows2.push({ kind: "group", gi, label: g.group, top: off, h: GROUP_H });
2329
+ off += GROUP_H;
2330
+ }
2331
+ g.options.forEach((o) => {
2332
+ optIdx += 1;
2333
+ rows2.push({ kind: "option", o, idx: optIdx, top: off, h: rowH });
2334
+ off += rowH;
2335
+ });
2336
+ });
2337
+ return { rows: rows2, totalH: off };
2338
+ }, [virtualized, fGroups, rowH]);
2144
2339
  const nextEnabled = (from, dir) => {
2145
2340
  let i = from + dir;
2146
2341
  while (i >= 0 && i < visible.length) {
@@ -2149,7 +2344,7 @@ function Combobox({
2149
2344
  }
2150
2345
  return from;
2151
2346
  };
2152
- const place = React36__default.useCallback(() => {
2347
+ const place = React37__default.useCallback(() => {
2153
2348
  const el = controlRef.current;
2154
2349
  if (!el) return;
2155
2350
  const r = el.getBoundingClientRect();
@@ -2164,7 +2359,7 @@ function Combobox({
2164
2359
  flip
2165
2360
  });
2166
2361
  }, [placement, minWidth]);
2167
- React36__default.useEffect(() => {
2362
+ React37__default.useEffect(() => {
2168
2363
  if (!open || !portal) return;
2169
2364
  place();
2170
2365
  const onMove = () => place();
@@ -2175,7 +2370,7 @@ function Combobox({
2175
2370
  window.removeEventListener("resize", onMove);
2176
2371
  };
2177
2372
  }, [open, portal, place]);
2178
- React36__default.useEffect(() => {
2373
+ React37__default.useEffect(() => {
2179
2374
  if (!open) return;
2180
2375
  const onDown = (e) => {
2181
2376
  if (wrapRef.current && wrapRef.current.contains(e.target)) return;
@@ -2185,17 +2380,36 @@ function Combobox({
2185
2380
  document.addEventListener("mousedown", onDown);
2186
2381
  return () => document.removeEventListener("mousedown", onDown);
2187
2382
  }, [open]);
2188
- React36__default.useEffect(() => {
2383
+ React37__default.useEffect(() => {
2189
2384
  setActive(0);
2190
2385
  }, [query]);
2191
- React36__default.useEffect(() => {
2386
+ React37__default.useEffect(() => {
2192
2387
  if (!open) return;
2193
2388
  const idx = flat.findIndex((o) => o.value === current);
2194
2389
  setActive(idx >= 0 ? idx : 0);
2195
2390
  }, [open]);
2196
- React36__default.useEffect(() => {
2197
- if (open) ensureVisible(listRef.current, activeRef.current);
2198
- }, [active, open]);
2391
+ React37__default.useEffect(() => {
2392
+ if (!open || !virtualized) return;
2393
+ const el = listRef.current;
2394
+ if (el && el.clientHeight) setListH(el.clientHeight);
2395
+ }, [open, virtualized]);
2396
+ React37__default.useEffect(() => {
2397
+ if (!open) return;
2398
+ if (!virtualized) {
2399
+ ensureVisible(listRef.current, activeRef.current);
2400
+ return;
2401
+ }
2402
+ const el = listRef.current;
2403
+ if (!el) return;
2404
+ const row = rows.find((r) => r.kind === "option" && r.idx === active);
2405
+ if (!row) return;
2406
+ const vh = el.clientHeight || listH;
2407
+ let next = el.scrollTop;
2408
+ if (row.top < el.scrollTop) next = row.top;
2409
+ else if (row.top + row.h > el.scrollTop + vh) next = row.top + row.h - vh;
2410
+ if (next !== el.scrollTop) el.scrollTop = next;
2411
+ setScrollTop(next);
2412
+ }, [active, open, virtualized, rows, listH]);
2199
2413
  function openMenu() {
2200
2414
  if (disabled) return;
2201
2415
  setQuery("");
@@ -2240,45 +2454,60 @@ function Combobox({
2240
2454
  const activeId = open && visible[active] ? optionId(active) : void 0;
2241
2455
  const descId = `${fieldId}-desc`;
2242
2456
  const describedBy = error || hint ? descId : void 0;
2457
+ const renderOption = (o, idx) => {
2458
+ const isSel = o.value === current;
2459
+ return /* @__PURE__ */ jsxs(
2460
+ "button",
2461
+ {
2462
+ id: optionId(idx),
2463
+ type: "button",
2464
+ className: "twc-opt",
2465
+ role: "option",
2466
+ "aria-selected": isSel,
2467
+ ref: idx === active ? activeRef : null,
2468
+ disabled: o.disabled || void 0,
2469
+ "aria-disabled": o.disabled || void 0,
2470
+ "data-disabled": o.disabled || void 0,
2471
+ "data-selected": isSel || void 0,
2472
+ "data-active": idx === active || void 0,
2473
+ onMouseEnter: () => {
2474
+ if (!o.disabled) setActive(idx);
2475
+ },
2476
+ onMouseDown: (e) => e.preventDefault(),
2477
+ onClick: () => commit(o.value),
2478
+ children: [
2479
+ /* @__PURE__ */ jsxs("span", { className: "twc-opt__main", children: [
2480
+ /* @__PURE__ */ jsx("span", { className: "twc-opt__label", children: o.label }),
2481
+ o.description ? /* @__PURE__ */ jsx("span", { className: "twc-opt__desc", children: o.description }) : null
2482
+ ] }),
2483
+ isSel ? /* @__PURE__ */ jsx("span", { className: "twc-opt__check", "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.6", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null
2484
+ ]
2485
+ },
2486
+ o.value
2487
+ );
2488
+ };
2489
+ let vTop = 0, vBottom = 0, vShown = rows;
2490
+ if (virtualized && rows.length) {
2491
+ const winTop = scrollTop - overscan * rowH;
2492
+ const winBottom = scrollTop + listH + overscan * rowH;
2493
+ vShown = rows.filter((r) => r.top + r.h > winTop && r.top < winBottom);
2494
+ vTop = vShown.length ? vShown[0].top : 0;
2495
+ vBottom = vShown.length ? totalH - (vShown[vShown.length - 1].top + vShown[vShown.length - 1].h) : totalH;
2496
+ }
2243
2497
  let counter = -1;
2244
- const popInner = /* @__PURE__ */ jsx("div", { className: "twc-pop__list", ref: listRef, children: loading ? /* @__PURE__ */ jsxs("div", { className: "twc-pop__loading", role: "status", children: [
2498
+ const popInner = /* @__PURE__ */ jsx("div", { className: "twc-pop__list", ref: listRef, onScroll: virtualized ? (e) => setScrollTop(e.currentTarget.scrollTop) : void 0, children: loading ? /* @__PURE__ */ jsxs("div", { className: "twc-pop__loading", role: "status", children: [
2245
2499
  /* @__PURE__ */ jsx("span", { className: "twc-pop__spinner", "aria-hidden": "true" }),
2246
2500
  "Loading\u2026"
2247
- ] }) : visible.length === 0 ? /* @__PURE__ */ jsx("div", { className: "twc-pop__empty", children: emptyText }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxs(React36__default.Fragment, { children: [
2501
+ ] }) : visible.length === 0 ? /* @__PURE__ */ jsx("div", { className: "twc-pop__empty", children: emptyText }) : virtualized ? /* @__PURE__ */ jsxs(Fragment, { children: [
2502
+ vTop > 0 ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { height: vTop } }) : null,
2503
+ vShown.map((r) => r.kind === "group" ? /* @__PURE__ */ jsx("div", { className: "twc-pop__group", children: r.label }, `g${r.gi}`) : renderOption(r.o, r.idx)),
2504
+ vBottom > 0 ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { height: vBottom } }) : null
2505
+ ] }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxs(React37__default.Fragment, { children: [
2248
2506
  g.group ? /* @__PURE__ */ jsx("div", { className: "twc-pop__group", children: g.group }) : null,
2249
2507
  g.options.map((o) => {
2250
2508
  counter += 1;
2251
2509
  const idx = counter;
2252
- const isSel = o.value === current;
2253
- return /* @__PURE__ */ jsxs(
2254
- "button",
2255
- {
2256
- id: optionId(idx),
2257
- type: "button",
2258
- className: "twc-opt",
2259
- role: "option",
2260
- "aria-selected": isSel,
2261
- ref: idx === active ? activeRef : null,
2262
- disabled: o.disabled || void 0,
2263
- "aria-disabled": o.disabled || void 0,
2264
- "data-disabled": o.disabled || void 0,
2265
- "data-selected": isSel || void 0,
2266
- "data-active": idx === active || void 0,
2267
- onMouseEnter: () => {
2268
- if (!o.disabled) setActive(idx);
2269
- },
2270
- onMouseDown: (e) => e.preventDefault(),
2271
- onClick: () => commit(o.value),
2272
- children: [
2273
- /* @__PURE__ */ jsxs("span", { className: "twc-opt__main", children: [
2274
- /* @__PURE__ */ jsx("span", { className: "twc-opt__label", children: o.label }),
2275
- o.description ? /* @__PURE__ */ jsx("span", { className: "twc-opt__desc", children: o.description }) : null
2276
- ] }),
2277
- isSel ? /* @__PURE__ */ jsx("span", { className: "twc-opt__check", "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.6", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null
2278
- ]
2279
- },
2280
- o.value
2281
- );
2510
+ return renderOption(o, idx);
2282
2511
  })
2283
2512
  ] }, gi)) });
2284
2513
  const RD = { createPortal: typeof createPortal === "function" ? createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
@@ -2436,14 +2665,14 @@ function CommandPalette({
2436
2665
  }) {
2437
2666
  const __twcStyles = useScopedStyles("twc-cmdk-styles", COMMAND_CSS);
2438
2667
  const renderPortal = usePortal();
2439
- const [query, setQuery] = React36__default.useState("");
2440
- const [active, setActive] = React36__default.useState(0);
2441
- const inputRef = React36__default.useRef(null);
2442
- const listRef = React36__default.useRef(null);
2443
- const paletteRef = React36__default.useRef(null);
2444
- const baseId = React36__default.useId();
2445
- const [mounted, setMounted] = React36__default.useState(open);
2446
- React36__default.useEffect(() => {
2668
+ const [query, setQuery] = React37__default.useState("");
2669
+ const [active, setActive] = React37__default.useState(0);
2670
+ const inputRef = React37__default.useRef(null);
2671
+ const listRef = React37__default.useRef(null);
2672
+ const paletteRef = React37__default.useRef(null);
2673
+ const baseId = React37__default.useId();
2674
+ const [mounted, setMounted] = React37__default.useState(open);
2675
+ React37__default.useEffect(() => {
2447
2676
  if (open) {
2448
2677
  setMounted(true);
2449
2678
  return;
@@ -2452,14 +2681,14 @@ function CommandPalette({
2452
2681
  return () => clearTimeout(t);
2453
2682
  }, [open]);
2454
2683
  useScrollLock(open);
2455
- React36__default.useEffect(() => {
2684
+ React37__default.useEffect(() => {
2456
2685
  if (open) {
2457
2686
  setQuery("");
2458
2687
  setActive(0);
2459
2688
  }
2460
2689
  }, [open]);
2461
2690
  useFocusTrap(paletteRef, open && mounted);
2462
- React36__default.useEffect(() => {
2691
+ React37__default.useEffect(() => {
2463
2692
  if (!open) return void 0;
2464
2693
  const onKey = (e) => {
2465
2694
  if (e.key === "Escape") {
@@ -2471,7 +2700,7 @@ function CommandPalette({
2471
2700
  return () => document.removeEventListener("keydown", onKey);
2472
2701
  }, [open, onClose]);
2473
2702
  const q = query.trim().toLowerCase();
2474
- const filtered = React36__default.useMemo(() => commands.filter(
2703
+ const filtered = React37__default.useMemo(() => commands.filter(
2475
2704
  (c) => !q || c.label.toLowerCase().includes(q) || (c.keywords || "").toLowerCase().includes(q) || (c.group || "").toLowerCase().includes(q)
2476
2705
  ), [commands, q]);
2477
2706
  const groups = [];
@@ -2486,7 +2715,7 @@ function CommandPalette({
2486
2715
  g.items.push(c);
2487
2716
  flat.push(c);
2488
2717
  });
2489
- React36__default.useEffect(() => {
2718
+ React37__default.useEffect(() => {
2490
2719
  setActive(0);
2491
2720
  }, [query]);
2492
2721
  const run = (cmd) => {
@@ -2506,7 +2735,7 @@ function CommandPalette({
2506
2735
  if (cmd) run(cmd);
2507
2736
  }
2508
2737
  }
2509
- React36__default.useEffect(() => {
2738
+ React37__default.useEffect(() => {
2510
2739
  const node = listRef.current?.querySelector('[data-active="true"]');
2511
2740
  if (node) node.scrollIntoView({ block: "nearest" });
2512
2741
  }, [active]);
@@ -2682,13 +2911,13 @@ function Currency({
2682
2911
  const prec = precision != null ? precision : meta.precision;
2683
2912
  const sym = symbol != null ? symbol : meta.symbol;
2684
2913
  const cur = code != null ? code : meta.code;
2685
- const autoId = React36__default.useId();
2914
+ const autoId = React37__default.useId();
2686
2915
  const fieldId = id || autoId;
2687
2916
  const invalid = Boolean(error);
2688
2917
  const controlled = value !== void 0;
2689
- const [internal, setInternal] = React36__default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
2918
+ const [internal, setInternal] = React37__default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
2690
2919
  const shown = controlled ? clampPrecision(String(value ?? ""), prec) : internal;
2691
- React36__default.useEffect(() => {
2920
+ React37__default.useEffect(() => {
2692
2921
  if (!controlled) return;
2693
2922
  const raw = String(value ?? "");
2694
2923
  if (shown !== raw) {
@@ -2875,6 +3104,8 @@ function Select({
2875
3104
  loading = false,
2876
3105
  emptyText = "No results found",
2877
3106
  name,
3107
+ virtualized = false,
3108
+ overscan = 8,
2878
3109
  id,
2879
3110
  className = "",
2880
3111
  onClick,
@@ -2882,32 +3113,54 @@ function Select({
2882
3113
  ...rest
2883
3114
  }) {
2884
3115
  const __twcStyles = useScopedStyles("twc-select-styles", SELECT_CSS);
2885
- const bufferRef = React36__default.useRef("");
2886
- const bufferTimerRef = React36__default.useRef(null);
2887
- const groups = React36__default.useMemo(() => normalizeGroups2(options), [options]);
2888
- const flat = React36__default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
2889
- const autoId = React36__default.useId();
3116
+ const bufferRef = React37__default.useRef("");
3117
+ const bufferTimerRef = React37__default.useRef(null);
3118
+ const groups = React37__default.useMemo(() => normalizeGroups2(options), [options]);
3119
+ const flat = React37__default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
3120
+ const autoId = React37__default.useId();
2890
3121
  const fieldId = id || autoId;
2891
- const [internal, setInternal] = React36__default.useState(defaultValue);
3122
+ const [internal, setInternal] = React37__default.useState(defaultValue);
2892
3123
  const current = value !== void 0 ? value : internal;
2893
- const [open, setOpen] = React36__default.useState(false);
2894
- const [render, setRender] = React36__default.useState(false);
2895
- const [active, setActive] = React36__default.useState(0);
2896
- const [coords, setCoords] = React36__default.useState(null);
2897
- const [query, setQuery] = React36__default.useState("");
2898
- const wrapRef = React36__default.useRef(null);
2899
- const triggerRef = React36__default.useRef(null);
2900
- const popRef = React36__default.useRef(null);
2901
- const listRef = React36__default.useRef(null);
2902
- const activeRef = React36__default.useRef(null);
2903
- const searchRef = React36__default.useRef(null);
3124
+ const [open, setOpen] = React37__default.useState(false);
3125
+ const [render, setRender] = React37__default.useState(false);
3126
+ const [active, setActive] = React37__default.useState(0);
3127
+ const [coords, setCoords] = React37__default.useState(null);
3128
+ const [query, setQuery] = React37__default.useState("");
3129
+ const [scrollTop, setScrollTop] = React37__default.useState(0);
3130
+ const [listH, setListH] = React37__default.useState(260);
3131
+ const wrapRef = React37__default.useRef(null);
3132
+ const triggerRef = React37__default.useRef(null);
3133
+ const popRef = React37__default.useRef(null);
3134
+ const listRef = React37__default.useRef(null);
3135
+ const activeRef = React37__default.useRef(null);
3136
+ const searchRef = React37__default.useRef(null);
2904
3137
  const showSearch = searchable === void 0 ? flat.length > 5 : searchable;
2905
- const fGroups = React36__default.useMemo(() => {
3138
+ const fGroups = React37__default.useMemo(() => {
2906
3139
  const q = query.trim().toLowerCase();
2907
3140
  if (!q) return groups;
2908
3141
  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);
2909
3142
  }, [groups, query]);
2910
- const visible = React36__default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
3143
+ const visible = React37__default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
3144
+ const rowH = React37__default.useMemo(() => visible.some((o) => o.description) ? 48 : 36, [visible]);
3145
+ const GROUP_H = 30;
3146
+ const { rows, totalH } = React37__default.useMemo(() => {
3147
+ if (!virtualized) return { rows: [], totalH: 0 };
3148
+ const rows2 = [];
3149
+ let off = 0;
3150
+ let optIdx = -1;
3151
+ fGroups.forEach((g, gi) => {
3152
+ if (g.group) {
3153
+ rows2.push({ kind: "group", gi, label: g.group, top: off, h: GROUP_H });
3154
+ off += GROUP_H;
3155
+ }
3156
+ g.options.forEach((o) => {
3157
+ optIdx += 1;
3158
+ rows2.push({ kind: "option", o, idx: optIdx, top: off, h: rowH });
3159
+ off += rowH;
3160
+ });
3161
+ });
3162
+ return { rows: rows2, totalH: off };
3163
+ }, [virtualized, fGroups, rowH]);
2911
3164
  const selected = flat.find((o) => o.value === current);
2912
3165
  const nextEnabled = (from, dir) => {
2913
3166
  let i = from + dir;
@@ -2917,7 +3170,7 @@ function Select({
2917
3170
  }
2918
3171
  return from;
2919
3172
  };
2920
- const place = React36__default.useCallback(() => {
3173
+ const place = React37__default.useCallback(() => {
2921
3174
  const el = triggerRef.current;
2922
3175
  if (!el) return;
2923
3176
  const r = el.getBoundingClientRect();
@@ -2933,7 +3186,7 @@ function Select({
2933
3186
  flip
2934
3187
  });
2935
3188
  }, [placement, minWidth, matchTriggerWidth]);
2936
- React36__default.useEffect(() => {
3189
+ React37__default.useEffect(() => {
2937
3190
  if (!open || !portal) return;
2938
3191
  place();
2939
3192
  const onMove = () => place();
@@ -2944,7 +3197,7 @@ function Select({
2944
3197
  window.removeEventListener("resize", onMove);
2945
3198
  };
2946
3199
  }, [open, portal, place]);
2947
- React36__default.useEffect(() => {
3200
+ React37__default.useEffect(() => {
2948
3201
  if (!open) return;
2949
3202
  const idx = flat.findIndex((o) => o.value === current);
2950
3203
  setActive(idx >= 0 ? idx : 0);
@@ -2960,13 +3213,32 @@ function Select({
2960
3213
  document.addEventListener("mousedown", onDown);
2961
3214
  return () => document.removeEventListener("mousedown", onDown);
2962
3215
  }, [open]);
2963
- React36__default.useEffect(() => {
3216
+ React37__default.useEffect(() => {
2964
3217
  setActive(0);
2965
3218
  }, [query]);
2966
- React36__default.useEffect(() => {
2967
- if (open) ensureVisible2(listRef.current, activeRef.current);
2968
- }, [active, open]);
2969
- React36__default.useEffect(() => {
3219
+ React37__default.useEffect(() => {
3220
+ if (!open || !virtualized) return;
3221
+ const el = listRef.current;
3222
+ if (el && el.clientHeight) setListH(el.clientHeight);
3223
+ }, [open, virtualized, render]);
3224
+ React37__default.useEffect(() => {
3225
+ if (!open) return;
3226
+ if (!virtualized) {
3227
+ ensureVisible2(listRef.current, activeRef.current);
3228
+ return;
3229
+ }
3230
+ const el = listRef.current;
3231
+ if (!el) return;
3232
+ const row = rows.find((r) => r.kind === "option" && r.idx === active);
3233
+ if (!row) return;
3234
+ const vh = el.clientHeight || listH;
3235
+ let next = el.scrollTop;
3236
+ if (row.top < el.scrollTop) next = row.top;
3237
+ else if (row.top + row.h > el.scrollTop + vh) next = row.top + row.h - vh;
3238
+ if (next !== el.scrollTop) el.scrollTop = next;
3239
+ setScrollTop(next);
3240
+ }, [active, open, virtualized, rows, listH]);
3241
+ React37__default.useEffect(() => {
2970
3242
  if (open) {
2971
3243
  setRender(true);
2972
3244
  return;
@@ -2974,8 +3246,8 @@ function Select({
2974
3246
  const t = setTimeout(() => setRender(false), 170);
2975
3247
  return () => clearTimeout(t);
2976
3248
  }, [open]);
2977
- const prevOpen = React36__default.useRef(false);
2978
- React36__default.useEffect(() => {
3249
+ const prevOpen = React37__default.useRef(false);
3250
+ React37__default.useEffect(() => {
2979
3251
  if (prevOpen.current && !open) {
2980
3252
  const ae = typeof document !== "undefined" ? document.activeElement : null;
2981
3253
  if (popRef.current && ae && popRef.current.contains(ae)) triggerRef.current?.focus();
@@ -3039,6 +3311,45 @@ function Select({
3039
3311
  const activeId = open && visible[active] ? optionId(active) : void 0;
3040
3312
  const descId = `${fieldId}-desc`;
3041
3313
  const describedBy = error || hint ? descId : void 0;
3314
+ const renderOption = (o, idx) => {
3315
+ const isSel = o.value === current;
3316
+ return /* @__PURE__ */ jsxs(
3317
+ "button",
3318
+ {
3319
+ id: optionId(idx),
3320
+ type: "button",
3321
+ className: "twc-opt",
3322
+ role: "option",
3323
+ "aria-selected": isSel,
3324
+ ref: idx === active ? activeRef : null,
3325
+ disabled: o.disabled || void 0,
3326
+ "aria-disabled": o.disabled || void 0,
3327
+ "data-disabled": o.disabled || void 0,
3328
+ "data-selected": isSel || void 0,
3329
+ "data-active": idx === active || void 0,
3330
+ onMouseEnter: () => {
3331
+ if (!o.disabled) setActive(idx);
3332
+ },
3333
+ onClick: () => commit(o.value),
3334
+ children: [
3335
+ /* @__PURE__ */ jsxs("span", { className: "twc-opt__main", children: [
3336
+ /* @__PURE__ */ jsx("span", { className: "twc-opt__label", children: o.label }),
3337
+ o.description ? /* @__PURE__ */ jsx("span", { className: "twc-opt__desc", children: o.description }) : null
3338
+ ] }),
3339
+ isSel ? /* @__PURE__ */ jsx("span", { className: "twc-opt__check", "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.6", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null
3340
+ ]
3341
+ },
3342
+ o.value
3343
+ );
3344
+ };
3345
+ let vTop = 0, vBottom = 0, vShown = rows;
3346
+ if (virtualized && rows.length) {
3347
+ const winTop = scrollTop - overscan * rowH;
3348
+ const winBottom = scrollTop + listH + overscan * rowH;
3349
+ vShown = rows.filter((r) => r.top + r.h > winTop && r.top < winBottom);
3350
+ vTop = vShown.length ? vShown[0].top : 0;
3351
+ vBottom = vShown.length ? totalH - (vShown[vShown.length - 1].top + vShown[vShown.length - 1].h) : totalH;
3352
+ }
3042
3353
  let counter = -1;
3043
3354
  const popInner = /* @__PURE__ */ jsxs(Fragment, { children: [
3044
3355
  showSearch ? /* @__PURE__ */ jsxs("div", { className: "twc-pop__search", children: [
@@ -3066,43 +3377,19 @@ function Select({
3066
3377
  searchRef.current?.focus();
3067
3378
  }, children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
3068
3379
  ] }) : null,
3069
- /* @__PURE__ */ jsx("div", { className: "twc-pop__list", ref: listRef, children: loading ? /* @__PURE__ */ jsxs("div", { className: "twc-pop__loading", role: "status", children: [
3380
+ /* @__PURE__ */ jsx("div", { className: "twc-pop__list", ref: listRef, onScroll: virtualized ? (e) => setScrollTop(e.currentTarget.scrollTop) : void 0, children: loading ? /* @__PURE__ */ jsxs("div", { className: "twc-pop__loading", role: "status", children: [
3070
3381
  /* @__PURE__ */ jsx("span", { className: "twc-pop__spinner", "aria-hidden": "true" }),
3071
3382
  "Loading\u2026"
3072
- ] }) : visible.length === 0 ? /* @__PURE__ */ jsx("div", { className: "twc-pop__empty", children: emptyText }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxs(React36__default.Fragment, { children: [
3383
+ ] }) : visible.length === 0 ? /* @__PURE__ */ jsx("div", { className: "twc-pop__empty", children: emptyText }) : virtualized ? /* @__PURE__ */ jsxs(Fragment, { children: [
3384
+ vTop > 0 ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { height: vTop } }) : null,
3385
+ vShown.map((r) => r.kind === "group" ? /* @__PURE__ */ jsx("div", { className: "twc-pop__group", children: r.label }, `g${r.gi}`) : renderOption(r.o, r.idx)),
3386
+ vBottom > 0 ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { height: vBottom } }) : null
3387
+ ] }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxs(React37__default.Fragment, { children: [
3073
3388
  g.group ? /* @__PURE__ */ jsx("div", { className: "twc-pop__group", children: g.group }) : null,
3074
3389
  g.options.map((o) => {
3075
3390
  counter += 1;
3076
3391
  const idx = counter;
3077
- const isSel = o.value === current;
3078
- return /* @__PURE__ */ jsxs(
3079
- "button",
3080
- {
3081
- id: optionId(idx),
3082
- type: "button",
3083
- className: "twc-opt",
3084
- role: "option",
3085
- "aria-selected": isSel,
3086
- ref: idx === active ? activeRef : null,
3087
- disabled: o.disabled || void 0,
3088
- "aria-disabled": o.disabled || void 0,
3089
- "data-disabled": o.disabled || void 0,
3090
- "data-selected": isSel || void 0,
3091
- "data-active": idx === active || void 0,
3092
- onMouseEnter: () => {
3093
- if (!o.disabled) setActive(idx);
3094
- },
3095
- onClick: () => commit(o.value),
3096
- children: [
3097
- /* @__PURE__ */ jsxs("span", { className: "twc-opt__main", children: [
3098
- /* @__PURE__ */ jsx("span", { className: "twc-opt__label", children: o.label }),
3099
- o.description ? /* @__PURE__ */ jsx("span", { className: "twc-opt__desc", children: o.description }) : null
3100
- ] }),
3101
- isSel ? /* @__PURE__ */ jsx("span", { className: "twc-opt__check", "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.6", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null
3102
- ]
3103
- },
3104
- o.value
3105
- );
3392
+ return renderOption(o, idx);
3106
3393
  })
3107
3394
  ] }, gi)) }),
3108
3395
  /* @__PURE__ */ jsx("div", { className: "twc-sel__sr", role: "status", "aria-live": "polite", children: loading ? "Loading\u2026" : visible.length === 0 ? emptyText : `${visible.length} result${visible.length === 1 ? "" : "s"}` })
@@ -3252,21 +3539,21 @@ function CurrencyField({
3252
3539
  ...rest
3253
3540
  }) {
3254
3541
  const __twcStyles = useScopedStyles("twc-curf-styles", CURF_CSS);
3255
- const autoId = React36__default.useId();
3542
+ const autoId = React37__default.useId();
3256
3543
  const fieldId = id || autoId;
3257
3544
  const invalid = Boolean(error);
3258
3545
  const curControlled = currency !== void 0;
3259
- const [curInternal, setCurInternal] = React36__default.useState(defaultCurrency);
3546
+ const [curInternal, setCurInternal] = React37__default.useState(defaultCurrency);
3260
3547
  const cur = curControlled ? currency : curInternal;
3261
3548
  const meta = CURRENCIES[cur] || CURRENCIES.USD;
3262
3549
  const prec = meta.precision;
3263
3550
  const valControlled = value !== void 0;
3264
- const [valInternal, setValInternal] = React36__default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
3551
+ const [valInternal, setValInternal] = React37__default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
3265
3552
  const shown = valControlled ? clampPrecision(String(value ?? ""), prec) : valInternal;
3266
3553
  const descId = `${fieldId}-desc`;
3267
3554
  const describedBy = [error || hint ? descId : null, rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
3268
3555
  const ariaInvalid = invalid ? true : rest["aria-invalid"] ?? void 0;
3269
- React36__default.useEffect(() => {
3556
+ React37__default.useEffect(() => {
3270
3557
  if (!valControlled) {
3271
3558
  const clamped = clampPrecision(valInternal, prec);
3272
3559
  if (clamped !== valInternal) {
@@ -3282,7 +3569,7 @@ function CurrencyField({
3282
3569
  }
3283
3570
  }
3284
3571
  }, [prec, cur, shown, value, valControlled, valInternal]);
3285
- const options = React36__default.useMemo(() => {
3572
+ const options = React37__default.useMemo(() => {
3286
3573
  if (!currencies) return CURRENCY_OPTIONS;
3287
3574
  return currencies.map((c) => typeof c === "string" ? { value: c, label: `${c} \u2014 ${(CURRENCIES[c] || {}).label || c}` } : c);
3288
3575
  }, [currencies]);
@@ -3436,13 +3723,13 @@ function Input({
3436
3723
  }) {
3437
3724
  const __twcStyles = useScopedStyles("twc-field-styles", FIELD_CSS2);
3438
3725
  const __twcExtra = useScopedStyles("twc-input-extra-styles", INPUT_EXTRA_CSS);
3439
- const autoId = React36__default.useId();
3726
+ const autoId = React37__default.useId();
3440
3727
  const fieldId = id || autoId;
3441
3728
  const descId = `${fieldId}-desc`;
3442
3729
  const countId = `${fieldId}-count`;
3443
3730
  const invalid = Boolean(error);
3444
3731
  const countControlled = rest.value !== void 0;
3445
- const [len2, setLen] = React36__default.useState(() => String(rest.defaultValue ?? "").length);
3732
+ const [len2, setLen] = React37__default.useState(() => String(rest.defaultValue ?? "").length);
3446
3733
  const count = countControlled ? String(rest.value ?? "").length : len2;
3447
3734
  const max = rest.maxLength;
3448
3735
  const showCounter = showCount && max != null;
@@ -3454,7 +3741,7 @@ function Input({
3454
3741
  const ariaInvalid = invalid ? true : rest["aria-invalid"] ?? void 0;
3455
3742
  const describedBy = [error || hint ? descId : null, showCounter ? countId : null, rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
3456
3743
  const isPassword = type === "password";
3457
- const [revealed, setRevealed] = React36__default.useState(false);
3744
+ const [revealed, setRevealed] = React37__default.useState(false);
3458
3745
  const effectiveType = isPassword && revealed ? "text" : type;
3459
3746
  const suffix = rightIcon ? /* @__PURE__ */ jsx("span", { className: "twc-input__affix", children: rightIcon }) : isPassword ? /* @__PURE__ */ jsx(
3460
3747
  "button",
@@ -3648,6 +3935,8 @@ function MultiSelect({
3648
3935
  name,
3649
3936
  max,
3650
3937
  maxTagCount,
3938
+ virtualized = false,
3939
+ overscan = 8,
3651
3940
  id,
3652
3941
  className = "",
3653
3942
  onFocus,
@@ -3655,27 +3944,49 @@ function MultiSelect({
3655
3944
  ...rest
3656
3945
  }) {
3657
3946
  const __twcStyles = useScopedStyles("twc-ms-styles", MULTI_CSS);
3658
- const groups = React36__default.useMemo(() => normalizeGroups3(options), [options]);
3659
- const flat = React36__default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
3660
- const autoId = React36__default.useId();
3947
+ const groups = React37__default.useMemo(() => normalizeGroups3(options), [options]);
3948
+ const flat = React37__default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
3949
+ const autoId = React37__default.useId();
3661
3950
  const fieldId = id || autoId;
3662
- const [internal, setInternal] = React36__default.useState(defaultValue);
3951
+ const [internal, setInternal] = React37__default.useState(defaultValue);
3663
3952
  const selected = value !== void 0 ? value : internal;
3664
- const [open, setOpen] = React36__default.useState(false);
3665
- const [query, setQuery] = React36__default.useState("");
3666
- const [active, setActive] = React36__default.useState(0);
3667
- const [coords, setCoords] = React36__default.useState(null);
3668
- const wrapRef = React36__default.useRef(null);
3669
- const controlRef = React36__default.useRef(null);
3670
- const inputRef = React36__default.useRef(null);
3671
- const popRef = React36__default.useRef(null);
3672
- const listRef = React36__default.useRef(null);
3673
- const activeRef = React36__default.useRef(null);
3674
- const fGroups = React36__default.useMemo(
3953
+ const [open, setOpen] = React37__default.useState(false);
3954
+ const [query, setQuery] = React37__default.useState("");
3955
+ const [active, setActive] = React37__default.useState(0);
3956
+ const [coords, setCoords] = React37__default.useState(null);
3957
+ const [scrollTop, setScrollTop] = React37__default.useState(0);
3958
+ const [listH, setListH] = React37__default.useState(260);
3959
+ const wrapRef = React37__default.useRef(null);
3960
+ const controlRef = React37__default.useRef(null);
3961
+ const inputRef = React37__default.useRef(null);
3962
+ const popRef = React37__default.useRef(null);
3963
+ const listRef = React37__default.useRef(null);
3964
+ const activeRef = React37__default.useRef(null);
3965
+ const fGroups = React37__default.useMemo(
3675
3966
  () => groups.map((g) => ({ group: g.group, options: g.options.filter((o) => matches2(o, query.trim())) })).filter((g) => g.options.length),
3676
3967
  [groups, query]
3677
3968
  );
3678
- const visible = React36__default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
3969
+ const visible = React37__default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
3970
+ const rowH = React37__default.useMemo(() => visible.some((o) => o.description) ? 48 : 36, [visible]);
3971
+ const GROUP_H = 30;
3972
+ const { rows, totalH } = React37__default.useMemo(() => {
3973
+ if (!virtualized) return { rows: [], totalH: 0 };
3974
+ const rows2 = [];
3975
+ let off = 0;
3976
+ let optIdx = -1;
3977
+ fGroups.forEach((g, gi) => {
3978
+ if (g.group) {
3979
+ rows2.push({ kind: "group", gi, label: g.group, top: off, h: GROUP_H });
3980
+ off += GROUP_H;
3981
+ }
3982
+ g.options.forEach((o) => {
3983
+ optIdx += 1;
3984
+ rows2.push({ kind: "option", o, idx: optIdx, top: off, h: rowH });
3985
+ off += rowH;
3986
+ });
3987
+ });
3988
+ return { rows: rows2, totalH: off };
3989
+ }, [virtualized, fGroups, rowH]);
3679
3990
  const capReached = max != null && (value !== void 0 ? value : internal).length >= max;
3680
3991
  const isOptDisabled = (o) => o.disabled || capReached && !(value !== void 0 ? value : internal).includes(o.value);
3681
3992
  const nextEnabled = (from, dir) => {
@@ -3686,7 +3997,7 @@ function MultiSelect({
3686
3997
  }
3687
3998
  return from;
3688
3999
  };
3689
- const place = React36__default.useCallback(() => {
4000
+ const place = React37__default.useCallback(() => {
3690
4001
  const el = controlRef.current;
3691
4002
  if (!el) return;
3692
4003
  const r = el.getBoundingClientRect();
@@ -3701,7 +4012,7 @@ function MultiSelect({
3701
4012
  flip
3702
4013
  });
3703
4014
  }, [placement, minWidth]);
3704
- React36__default.useEffect(() => {
4015
+ React37__default.useEffect(() => {
3705
4016
  if (!open || !portal) return;
3706
4017
  place();
3707
4018
  const onMove = () => place();
@@ -3712,7 +4023,7 @@ function MultiSelect({
3712
4023
  window.removeEventListener("resize", onMove);
3713
4024
  };
3714
4025
  }, [open, portal, place]);
3715
- React36__default.useEffect(() => {
4026
+ React37__default.useEffect(() => {
3716
4027
  if (!open) return;
3717
4028
  const onDown = (e) => {
3718
4029
  if (wrapRef.current && wrapRef.current.contains(e.target)) return;
@@ -3723,12 +4034,31 @@ function MultiSelect({
3723
4034
  document.addEventListener("mousedown", onDown);
3724
4035
  return () => document.removeEventListener("mousedown", onDown);
3725
4036
  }, [open]);
3726
- React36__default.useEffect(() => {
4037
+ React37__default.useEffect(() => {
3727
4038
  setActive(0);
3728
4039
  }, [query]);
3729
- React36__default.useEffect(() => {
3730
- if (open) ensureVisible3(listRef.current, activeRef.current);
3731
- }, [active, open]);
4040
+ React37__default.useEffect(() => {
4041
+ if (!open || !virtualized) return;
4042
+ const el = listRef.current;
4043
+ if (el && el.clientHeight) setListH(el.clientHeight);
4044
+ }, [open, virtualized]);
4045
+ React37__default.useEffect(() => {
4046
+ if (!open) return;
4047
+ if (!virtualized) {
4048
+ ensureVisible3(listRef.current, activeRef.current);
4049
+ return;
4050
+ }
4051
+ const el = listRef.current;
4052
+ if (!el) return;
4053
+ const row = rows.find((r) => r.kind === "option" && r.idx === active);
4054
+ if (!row) return;
4055
+ const vh = el.clientHeight || listH;
4056
+ let next = el.scrollTop;
4057
+ if (row.top < el.scrollTop) next = row.top;
4058
+ else if (row.top + row.h > el.scrollTop + vh) next = row.top + row.h - vh;
4059
+ if (next !== el.scrollTop) el.scrollTop = next;
4060
+ setScrollTop(next);
4061
+ }, [active, open, virtualized, rows, listH]);
3732
4062
  function commit(next) {
3733
4063
  if (value === void 0) setInternal(next);
3734
4064
  onChange?.(next);
@@ -3765,48 +4095,74 @@ function MultiSelect({
3765
4095
  const activeId = open && visible[active] ? optionId(active) : void 0;
3766
4096
  const descId = `${fieldId}-desc`;
3767
4097
  const describedBy = error || hint ? descId : void 0;
3768
- let counter = -1;
3769
- const popInner = /* @__PURE__ */ jsx("div", { className: "twc-pop__list", id: listboxId, ref: listRef, role: "listbox", "aria-multiselectable": "true", children: loading ? /* @__PURE__ */ jsxs("div", { className: "twc-pop__loading", role: "status", children: [
3770
- /* @__PURE__ */ jsx("span", { className: "twc-pop__spinner", "aria-hidden": "true" }),
3771
- "Loading\u2026"
3772
- ] }) : visible.length === 0 ? /* @__PURE__ */ jsx("div", { className: "twc-pop__empty", children: emptyText }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxs(React36__default.Fragment, { children: [
3773
- g.group ? /* @__PURE__ */ jsx("div", { className: "twc-pop__group", children: g.group }) : null,
3774
- g.options.map((o) => {
3775
- counter += 1;
3776
- const idx = counter;
3777
- const isSel = selected.includes(o.value);
3778
- const optDisabled = isOptDisabled(o);
3779
- return /* @__PURE__ */ jsxs(
3780
- "button",
3781
- {
3782
- id: optionId(idx),
3783
- type: "button",
3784
- className: "twc-opt",
3785
- role: "option",
3786
- "aria-selected": isSel,
3787
- ref: idx === active ? activeRef : null,
3788
- disabled: optDisabled || void 0,
3789
- "aria-disabled": optDisabled || void 0,
3790
- "data-disabled": optDisabled || void 0,
3791
- "data-selected": isSel || void 0,
3792
- "data-active": idx === active || void 0,
3793
- onMouseEnter: () => {
3794
- if (!optDisabled) setActive(idx);
3795
- },
3796
- onMouseDown: (e) => e.preventDefault(),
3797
- onClick: () => toggle(o.value),
3798
- children: [
3799
- /* @__PURE__ */ jsx("span", { className: "twc-opt__box", "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) }) }),
3800
- /* @__PURE__ */ jsxs("span", { className: "twc-opt__main", children: [
3801
- /* @__PURE__ */ jsx("span", { className: "twc-opt__label", children: o.label }),
3802
- o.description ? /* @__PURE__ */ jsx("span", { className: "twc-opt__desc", children: o.description }) : null
3803
- ] })
3804
- ]
4098
+ const renderOption = (o, idx) => {
4099
+ const isSel = selected.includes(o.value);
4100
+ const optDisabled = isOptDisabled(o);
4101
+ return /* @__PURE__ */ jsxs(
4102
+ "button",
4103
+ {
4104
+ id: optionId(idx),
4105
+ type: "button",
4106
+ className: "twc-opt",
4107
+ role: "option",
4108
+ "aria-selected": isSel,
4109
+ ref: idx === active ? activeRef : null,
4110
+ disabled: optDisabled || void 0,
4111
+ "aria-disabled": optDisabled || void 0,
4112
+ "data-disabled": optDisabled || void 0,
4113
+ "data-selected": isSel || void 0,
4114
+ "data-active": idx === active || void 0,
4115
+ onMouseEnter: () => {
4116
+ if (!optDisabled) setActive(idx);
3805
4117
  },
3806
- o.value
3807
- );
3808
- })
3809
- ] }, gi)) });
4118
+ onMouseDown: (e) => e.preventDefault(),
4119
+ onClick: () => toggle(o.value),
4120
+ children: [
4121
+ /* @__PURE__ */ jsx("span", { className: "twc-opt__box", "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) }) }),
4122
+ /* @__PURE__ */ jsxs("span", { className: "twc-opt__main", children: [
4123
+ /* @__PURE__ */ jsx("span", { className: "twc-opt__label", children: o.label }),
4124
+ o.description ? /* @__PURE__ */ jsx("span", { className: "twc-opt__desc", children: o.description }) : null
4125
+ ] })
4126
+ ]
4127
+ },
4128
+ o.value
4129
+ );
4130
+ };
4131
+ let vTop = 0, vBottom = 0, vShown = rows;
4132
+ if (virtualized && rows.length) {
4133
+ const winTop = scrollTop - overscan * rowH;
4134
+ const winBottom = scrollTop + listH + overscan * rowH;
4135
+ vShown = rows.filter((r) => r.top + r.h > winTop && r.top < winBottom);
4136
+ vTop = vShown.length ? vShown[0].top : 0;
4137
+ vBottom = vShown.length ? totalH - (vShown[vShown.length - 1].top + vShown[vShown.length - 1].h) : totalH;
4138
+ }
4139
+ let counter = -1;
4140
+ const popInner = /* @__PURE__ */ jsx(
4141
+ "div",
4142
+ {
4143
+ className: "twc-pop__list",
4144
+ id: listboxId,
4145
+ ref: listRef,
4146
+ role: "listbox",
4147
+ "aria-multiselectable": "true",
4148
+ onScroll: virtualized ? (e) => setScrollTop(e.currentTarget.scrollTop) : void 0,
4149
+ children: loading ? /* @__PURE__ */ jsxs("div", { className: "twc-pop__loading", role: "status", children: [
4150
+ /* @__PURE__ */ jsx("span", { className: "twc-pop__spinner", "aria-hidden": "true" }),
4151
+ "Loading\u2026"
4152
+ ] }) : visible.length === 0 ? /* @__PURE__ */ jsx("div", { className: "twc-pop__empty", children: emptyText }) : virtualized ? /* @__PURE__ */ jsxs(Fragment, { children: [
4153
+ vTop > 0 ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { height: vTop } }) : null,
4154
+ vShown.map((r) => r.kind === "group" ? /* @__PURE__ */ jsx("div", { className: "twc-pop__group", children: r.label }, `g${r.gi}`) : renderOption(r.o, r.idx)),
4155
+ vBottom > 0 ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { height: vBottom } }) : null
4156
+ ] }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxs(React37__default.Fragment, { children: [
4157
+ g.group ? /* @__PURE__ */ jsx("div", { className: "twc-pop__group", children: g.group }) : null,
4158
+ g.options.map((o) => {
4159
+ counter += 1;
4160
+ const idx = counter;
4161
+ return renderOption(o, idx);
4162
+ })
4163
+ ] }, gi))
4164
+ }
4165
+ );
3810
4166
  const RD = { createPortal: typeof createPortal === "function" ? createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
3811
4167
  const canPortal = portal && RD && RD.createPortal;
3812
4168
  let popEl = null;
@@ -3999,7 +4355,7 @@ function Pagination({
3999
4355
  }
4000
4356
  const jumperEnabled = showPageJumper ?? showJumper;
4001
4357
  const __twcStyles = useScopedStyles("twc-pagination-styles", PAGINATION_CSS);
4002
- const [internal, setInternal] = React36__default.useState(defaultPage);
4358
+ const [internal, setInternal] = React37__default.useState(defaultPage);
4003
4359
  const page = pageProp !== void 0 ? pageProp : internal;
4004
4360
  const pages = buildPages(page, total, siblings, boundaries);
4005
4361
  const go = (p) => {
@@ -4007,7 +4363,7 @@ function Pagination({
4007
4363
  if (pageProp === void 0) setInternal(p);
4008
4364
  onChange?.(p);
4009
4365
  };
4010
- const [jump, setJump] = React36__default.useState("");
4366
+ const [jump, setJump] = React37__default.useState("");
4011
4367
  const submitJump = () => {
4012
4368
  const n = parseInt(jump, 10);
4013
4369
  if (!Number.isNaN(n)) go(Math.min(Math.max(n, 1), total));
@@ -4090,13 +4446,13 @@ function Tooltip({
4090
4446
  ...rest
4091
4447
  }) {
4092
4448
  const __twcStyles = useScopedStyles("twc-tooltip-styles", TOOLTIP_CSS);
4093
- const id = React36__default.useId();
4094
- const [show, setShow] = React36__default.useState(false);
4095
- const [coords, setCoords] = React36__default.useState(null);
4096
- const timer = React36__default.useRef(null);
4097
- const closeTimer = React36__default.useRef(null);
4098
- const wrapRef = React36__default.useRef(null);
4099
- const tipRef = React36__default.useRef(null);
4449
+ const id = React37__default.useId();
4450
+ const [show, setShow] = React37__default.useState(false);
4451
+ const [coords, setCoords] = React37__default.useState(null);
4452
+ const timer = React37__default.useRef(null);
4453
+ const closeTimer = React37__default.useRef(null);
4454
+ const wrapRef = React37__default.useRef(null);
4455
+ const tipRef = React37__default.useRef(null);
4100
4456
  const open = () => {
4101
4457
  clearTimeout(closeTimer.current);
4102
4458
  clearTimeout(timer.current);
@@ -4110,11 +4466,11 @@ function Tooltip({
4110
4466
  const cancelClose = () => {
4111
4467
  clearTimeout(closeTimer.current);
4112
4468
  };
4113
- React36__default.useEffect(() => () => {
4469
+ React37__default.useEffect(() => () => {
4114
4470
  clearTimeout(timer.current);
4115
4471
  clearTimeout(closeTimer.current);
4116
4472
  }, []);
4117
- const place = React36__default.useCallback(() => {
4473
+ const place = React37__default.useCallback(() => {
4118
4474
  const el = wrapRef.current;
4119
4475
  if (!el) return;
4120
4476
  const r = el.getBoundingClientRect();
@@ -4137,10 +4493,10 @@ function Tooltip({
4137
4493
  else if (side === "right") setCoords({ ...base, top: clampY(cy), left: Math.round(r.right + gap) });
4138
4494
  else setCoords({ ...base, left: clampX(cx), bottom: Math.round(vh - r.top + gap) });
4139
4495
  }, [placement]);
4140
- React36__default.useEffect(() => {
4496
+ React37__default.useEffect(() => {
4141
4497
  place();
4142
4498
  }, [place]);
4143
- React36__default.useEffect(() => {
4499
+ React37__default.useEffect(() => {
4144
4500
  if (!show) return void 0;
4145
4501
  place();
4146
4502
  const onMove = () => place();
@@ -4151,7 +4507,7 @@ function Tooltip({
4151
4507
  window.removeEventListener("resize", onMove);
4152
4508
  };
4153
4509
  }, [show, place]);
4154
- React36__default.useEffect(() => {
4510
+ React37__default.useEffect(() => {
4155
4511
  if (!show) return;
4156
4512
  const onKeyDown = (e) => {
4157
4513
  if (e.key === "Escape") {
@@ -4163,7 +4519,7 @@ function Tooltip({
4163
4519
  return () => document.removeEventListener("keydown", onKeyDown);
4164
4520
  }, [show]);
4165
4521
  const describedBy = show ? id : void 0;
4166
- const trigger = React36__default.isValidElement(children) && children.type !== React36__default.Fragment ? React36__default.cloneElement(children, {
4522
+ const trigger = React37__default.isValidElement(children) && children.type !== React37__default.Fragment ? React37__default.cloneElement(children, {
4167
4523
  "aria-describedby": [children.props["aria-describedby"], describedBy].filter(Boolean).join(" ") || void 0
4168
4524
  }) : /* @__PURE__ */ jsx("span", { "aria-describedby": describedBy, children });
4169
4525
  return /* @__PURE__ */ jsxs(
@@ -4767,9 +5123,9 @@ function runDatatableQuery(rows, query, options = {}) {
4767
5123
  return { rows: page, total, filtered: out };
4768
5124
  }
4769
5125
  function useFloating() {
4770
- const [pos, setPos] = React36__default.useState(null);
4771
- const cfg = React36__default.useRef(null);
4772
- const place = React36__default.useCallback(() => {
5126
+ const [pos, setPos] = React37__default.useState(null);
5127
+ const cfg = React37__default.useRef(null);
5128
+ const place = React37__default.useCallback(() => {
4773
5129
  const c = cfg.current;
4774
5130
  if (!c || !c.el || !c.el.isConnected) return null;
4775
5131
  const r = c.el.getBoundingClientRect();
@@ -4780,17 +5136,17 @@ function useFloating() {
4780
5136
  const top = r.bottom + 6;
4781
5137
  return { top, left, width: c.width, anchorX: r.left + r.width / 2, maxHeight: Math.max(180, vh - top - M) };
4782
5138
  }, []);
4783
- const open = React36__default.useCallback((el, align = "left", width = 220) => {
5139
+ const open = React37__default.useCallback((el, align = "left", width = 220) => {
4784
5140
  cfg.current = { el, align, width };
4785
5141
  const p = place();
4786
5142
  if (p) setPos(p);
4787
5143
  }, [place]);
4788
- const close = React36__default.useCallback(() => {
5144
+ const close = React37__default.useCallback(() => {
4789
5145
  cfg.current = null;
4790
5146
  setPos(null);
4791
5147
  }, []);
4792
5148
  const isOpen = pos != null;
4793
- React36__default.useEffect(() => {
5149
+ React37__default.useEffect(() => {
4794
5150
  if (!isOpen) return void 0;
4795
5151
  const update = () => {
4796
5152
  const p = place();
@@ -4814,9 +5170,9 @@ function Caret({ pos }) {
4814
5170
  return /* @__PURE__ */ jsx("span", { className: "twc-dt__caret", style: { left } });
4815
5171
  }
4816
5172
  function EditCell({ col, value, options, onChange, onCommit, onCommitValue, onCancel, onKeyDown }) {
4817
- const ref = React36__default.useRef(null);
5173
+ const ref = React37__default.useRef(null);
4818
5174
  const isSelect = col.editType === "select" || options && col.editType !== "text";
4819
- React36__default.useEffect(() => {
5175
+ React37__default.useEffect(() => {
4820
5176
  if (isSelect) {
4821
5177
  const t = setTimeout(() => ref.current?.querySelector(".twc-sel__trigger")?.click(), 0);
4822
5178
  return () => clearTimeout(t);
@@ -4980,6 +5336,9 @@ function Datatable({
4980
5336
  density: densityProp = "comfortable",
4981
5337
  pageSize = 10,
4982
5338
  pageSizeOptions = [5, 10, 25, 50],
5339
+ page,
5340
+ onPageChange,
5341
+ onPageSizeChange,
4983
5342
  height = 440,
4984
5343
  serverMode = false,
4985
5344
  rowCount,
@@ -5021,7 +5380,7 @@ function Datatable({
5021
5380
  ...rest
5022
5381
  }) {
5023
5382
  const __twcStyles = useScopedStyles("twc-dt-styles", DT_CSS);
5024
- const cols = React36__default.useMemo(() => {
5383
+ const cols = React37__default.useMemo(() => {
5025
5384
  const out = columns.map((c) => {
5026
5385
  const isActions = c.type === "actions";
5027
5386
  return {
@@ -5056,7 +5415,7 @@ function Datatable({
5056
5415
  }
5057
5416
  return out;
5058
5417
  }, [columns, rowPinning]);
5059
- const _autoKey = React36__default.useRef();
5418
+ const _autoKey = React37__default.useRef();
5060
5419
  if (!_autoKey.current) _autoKey.current = { map: /* @__PURE__ */ new WeakMap(), n: 0 };
5061
5420
  const keyOf = rowKey || ((r, i) => {
5062
5421
  if (r != null && r.id != null) return r.id;
@@ -5071,17 +5430,17 @@ function Datatable({
5071
5430
  }
5072
5431
  return i;
5073
5432
  });
5074
- const [sort, setSort] = React36__default.useState(null);
5075
- const [filters, setFilters] = React36__default.useState([]);
5076
- const [hidden, setHidden] = React36__default.useState(() => /* @__PURE__ */ new Set());
5077
- const [showRowNum, setShowRowNum] = React36__default.useState(rowNumbers);
5078
- const [wrapped, setWrapped] = React36__default.useState(() => new Set((columns || []).filter((c) => c.wrapText).map((c) => c.field)));
5433
+ const [sort, setSort] = React37__default.useState(null);
5434
+ const [filters, setFilters] = React37__default.useState([]);
5435
+ const [hidden, setHidden] = React37__default.useState(() => /* @__PURE__ */ new Set());
5436
+ const [showRowNum, setShowRowNum] = React37__default.useState(rowNumbers);
5437
+ const [wrapped, setWrapped] = React37__default.useState(() => new Set((columns || []).filter((c) => c.wrapText).map((c) => c.field)));
5079
5438
  const toggleWrap = (field) => setWrapped((w) => {
5080
5439
  const n = new Set(w);
5081
5440
  n.has(field) ? n.delete(field) : n.add(field);
5082
5441
  return n;
5083
5442
  });
5084
- const [pins, setPins] = React36__default.useState(() => {
5443
+ const [pins, setPins] = React37__default.useState(() => {
5085
5444
  const left = [], right = [];
5086
5445
  columns.forEach((c) => {
5087
5446
  if (c.pinned === "left") left.push(c.field);
@@ -5089,34 +5448,47 @@ function Datatable({
5089
5448
  });
5090
5449
  return { left, right };
5091
5450
  });
5092
- const [density, setDensity] = React36__default.useState(densityProp);
5093
- const [quick, setQuick] = React36__default.useState("");
5094
- const [selected, setSelected] = React36__default.useState(() => /* @__PURE__ */ new Set());
5095
- const [activeRow, setActiveRow] = React36__default.useState(null);
5096
- const [activeCell, setActiveCell] = React36__default.useState(null);
5097
- const [page, setPage] = React36__default.useState(0);
5098
- const [rowsPerPage, setRowsPerPage] = React36__default.useState(pageSize > 0 ? pageSize : 10);
5099
- const [colQuery, setColQuery] = React36__default.useState("");
5100
- const [widths, setWidths] = React36__default.useState({});
5101
- const [order, setOrder] = React36__default.useState(() => columns.map((c) => c.field));
5102
- const [drag, setDrag] = React36__default.useState({ from: null, over: null, after: false });
5103
- const [aggOn, setAggOn] = React36__default.useState(showAggregation);
5104
- const [focus, setFocus] = React36__default.useState({ r: 0, c: 0 });
5105
- const gridRef = React36__default.useRef(null);
5106
- const [groupBy, setGroupBy] = React36__default.useState(rowGrouping || []);
5107
- const [collapsed, setCollapsed] = React36__default.useState(() => /* @__PURE__ */ new Set());
5108
- const [pinnedRows, setPinnedRows] = React36__default.useState({ top: [], bottom: [] });
5109
- const [headH, setHeadH] = React36__default.useState(41);
5110
- const theadRef = React36__default.useRef(null);
5111
- const [rowOrder, setRowOrder] = React36__default.useState(null);
5112
- const [rowHeights, setRowHeights] = React36__default.useState({});
5113
- const [rowDrag, setRowDrag] = React36__default.useState({ from: null, over: null, after: false });
5114
- const [rowGrab, setRowGrab] = React36__default.useState(null);
5115
- const [reorderMsg, setReorderMsg] = React36__default.useState("");
5116
- const rowFocusRef = React36__default.useRef(null);
5117
- const rootRef = React36__default.useRef(null);
5118
- const [compact, setCompact] = React36__default.useState(false);
5119
- React36__default.useEffect(() => {
5451
+ const [density, setDensity] = React37__default.useState(densityProp);
5452
+ const [quick, setQuick] = React37__default.useState("");
5453
+ const [selected, setSelected] = React37__default.useState(() => /* @__PURE__ */ new Set());
5454
+ const [activeRow, setActiveRow] = React37__default.useState(null);
5455
+ const [activeCell, setActiveCell] = React37__default.useState(null);
5456
+ const [internalPage, setInternalPage] = React37__default.useState(0);
5457
+ const [internalRpp, setInternalRpp] = React37__default.useState(pageSize > 0 ? pageSize : 10);
5458
+ const pageControlled = page !== void 0;
5459
+ const pageSizeControlled = onPageSizeChange !== void 0;
5460
+ const pageVal = pageControlled ? page : internalPage;
5461
+ const sizeVal = pageSizeControlled ? pageSize > 0 ? pageSize : 10 : internalRpp;
5462
+ const commitPage = (next) => {
5463
+ onPageChange?.(next);
5464
+ if (!pageControlled) setInternalPage(next);
5465
+ };
5466
+ const commitPageSize = (next) => {
5467
+ onPageSizeChange?.(next);
5468
+ if (!pageSizeControlled) setInternalRpp(next);
5469
+ commitPage(0);
5470
+ };
5471
+ const [colQuery, setColQuery] = React37__default.useState("");
5472
+ const [widths, setWidths] = React37__default.useState({});
5473
+ const [order, setOrder] = React37__default.useState(() => columns.map((c) => c.field));
5474
+ const [drag, setDrag] = React37__default.useState({ from: null, over: null, after: false });
5475
+ const [aggOn, setAggOn] = React37__default.useState(showAggregation);
5476
+ const [focus, setFocus] = React37__default.useState({ r: 0, c: 0 });
5477
+ const gridRef = React37__default.useRef(null);
5478
+ const [groupBy, setGroupBy] = React37__default.useState(rowGrouping || []);
5479
+ const [collapsed, setCollapsed] = React37__default.useState(() => /* @__PURE__ */ new Set());
5480
+ const [pinnedRows, setPinnedRows] = React37__default.useState({ top: [], bottom: [] });
5481
+ const [headH, setHeadH] = React37__default.useState(41);
5482
+ const theadRef = React37__default.useRef(null);
5483
+ const [rowOrder, setRowOrder] = React37__default.useState(null);
5484
+ const [rowHeights, setRowHeights] = React37__default.useState({});
5485
+ const [rowDrag, setRowDrag] = React37__default.useState({ from: null, over: null, after: false });
5486
+ const [rowGrab, setRowGrab] = React37__default.useState(null);
5487
+ const [reorderMsg, setReorderMsg] = React37__default.useState("");
5488
+ const rowFocusRef = React37__default.useRef(null);
5489
+ const rootRef = React37__default.useRef(null);
5490
+ const [compact, setCompact] = React37__default.useState(false);
5491
+ React37__default.useEffect(() => {
5120
5492
  const el = rootRef.current;
5121
5493
  if (!el) return void 0;
5122
5494
  const measure = () => setCompact((el.clientWidth || 0) < 720);
@@ -5129,11 +5501,11 @@ function Datatable({
5129
5501
  else if (typeof window !== "undefined") window.removeEventListener("resize", measure);
5130
5502
  };
5131
5503
  }, []);
5132
- const scrollRef = React36__default.useRef(null);
5133
- const [scrollTop, setScrollTop] = React36__default.useState(0);
5134
- const [viewportH, setViewportH] = React36__default.useState(0);
5135
- const [pivotOn, setPivotOn] = React36__default.useState(pivotMode);
5136
- const [aggConfig, setAggConfig] = React36__default.useState(() => {
5504
+ const scrollRef = React37__default.useRef(null);
5505
+ const [scrollTop, setScrollTop] = React37__default.useState(0);
5506
+ const [viewportH, setViewportH] = React37__default.useState(0);
5507
+ const [pivotOn, setPivotOn] = React37__default.useState(pivotMode);
5508
+ const [aggConfig, setAggConfig] = React37__default.useState(() => {
5137
5509
  const m = {};
5138
5510
  (columns || []).forEach((c) => {
5139
5511
  if (typeof c.aggregation === "string") m[c.field] = c.aggregation;
@@ -5141,13 +5513,13 @@ function Datatable({
5141
5513
  return m;
5142
5514
  });
5143
5515
  const aggOf = (c) => aggConfig[c.field] || (typeof c.aggregation === "function" ? c.aggregation : null);
5144
- const [pivotConfig, setPivotConfig] = React36__default.useState(() => ({
5516
+ const [pivotConfig, setPivotConfig] = React37__default.useState(() => ({
5145
5517
  rows: pivot && pivot.rows || [],
5146
5518
  columns: pivot && pivot.columns || [],
5147
5519
  values: pivot && pivot.values || []
5148
5520
  }));
5149
5521
  const pivotActive = pivotOn && pivotConfig.rows.length > 0 && pivotConfig.values.length > 0;
5150
- React36__default.useEffect(() => {
5522
+ React37__default.useEffect(() => {
5151
5523
  setOrder((prev) => {
5152
5524
  const fields = columns.map((c) => c.field);
5153
5525
  const kept = prev.filter((f) => fields.includes(f));
@@ -5155,32 +5527,37 @@ function Datatable({
5155
5527
  return [...kept, ...added];
5156
5528
  });
5157
5529
  }, [columns]);
5158
- React36__default.useEffect(() => {
5530
+ React37__default.useEffect(() => {
5159
5531
  setDensity(densityProp);
5160
5532
  }, [densityProp]);
5161
- React36__default.useEffect(() => {
5533
+ React37__default.useEffect(() => {
5162
5534
  setAggOn(showAggregation);
5163
5535
  }, [showAggregation]);
5536
+ React37__default.useEffect(() => {
5537
+ if (pageSizeControlled) return;
5538
+ setInternalRpp(pageSize > 0 ? pageSize : 10);
5539
+ setInternalPage(0);
5540
+ }, [pageSize]);
5164
5541
  const rowGroupingKey = (rowGrouping || []).join("\0");
5165
- const rowGroupingKeyRef = React36__default.useRef(rowGroupingKey);
5166
- React36__default.useEffect(() => {
5542
+ const rowGroupingKeyRef = React37__default.useRef(rowGroupingKey);
5543
+ React37__default.useEffect(() => {
5167
5544
  if (rowGroupingKeyRef.current === rowGroupingKey) return;
5168
5545
  rowGroupingKeyRef.current = rowGroupingKey;
5169
5546
  setGroupBy(rowGrouping || []);
5170
5547
  }, [rowGroupingKey]);
5171
5548
  const widthOf = (c) => widths[c.field] ?? c.width ?? 160;
5172
- const [colMenu, setColMenu] = React36__default.useState(null);
5549
+ const [colMenu, setColMenu] = React37__default.useState(null);
5173
5550
  const [menuPos, openMenu, closeMenu] = useFloating();
5174
- const [panel, setPanel] = React36__default.useState(null);
5551
+ const [panel, setPanel] = React37__default.useState(null);
5175
5552
  const [panelPos, openPanel, closePanel] = useFloating();
5176
- const [rowMenu, setRowMenu] = React36__default.useState(null);
5553
+ const [rowMenu, setRowMenu] = React37__default.useState(null);
5177
5554
  const [rowMenuPos, openRowMenu, closeRowMenu] = useFloating();
5178
- const [exportOpen, setExportOpen] = React36__default.useState(false);
5555
+ const [exportOpen, setExportOpen] = React37__default.useState(false);
5179
5556
  const [exportPos, openExport, closeExport] = useFloating();
5180
- const menuTriggerRef = React36__default.useRef(null);
5181
- const colMenuRef = React36__default.useRef(null);
5182
- const rowMenuRef = React36__default.useRef(null);
5183
- const exportMenuRef = React36__default.useRef(null);
5557
+ const menuTriggerRef = React37__default.useRef(null);
5558
+ const colMenuRef = React37__default.useRef(null);
5559
+ const rowMenuRef = React37__default.useRef(null);
5560
+ const exportMenuRef = React37__default.useRef(null);
5184
5561
  function focusFirstItem(container) {
5185
5562
  if (!container) return;
5186
5563
  const first = container.querySelector('[role="menuitem"]:not([disabled])');
@@ -5219,16 +5596,16 @@ function Datatable({
5219
5596
  restoreTriggerFocus();
5220
5597
  }
5221
5598
  }
5222
- React36__default.useEffect(() => {
5599
+ React37__default.useEffect(() => {
5223
5600
  if (colMenu) focusFirstItem(colMenuRef.current);
5224
5601
  }, [colMenu]);
5225
- React36__default.useEffect(() => {
5602
+ React37__default.useEffect(() => {
5226
5603
  if (rowMenu) focusFirstItem(rowMenuRef.current);
5227
5604
  }, [rowMenu]);
5228
- React36__default.useEffect(() => {
5605
+ React37__default.useEffect(() => {
5229
5606
  if (exportOpen) focusFirstItem(exportMenuRef.current);
5230
5607
  }, [exportOpen]);
5231
- React36__default.useEffect(() => {
5608
+ React37__default.useEffect(() => {
5232
5609
  if (!colMenu && !panel && !rowMenu) return;
5233
5610
  const closeAll = () => {
5234
5611
  setColMenu(null);
@@ -5251,7 +5628,7 @@ function Datatable({
5251
5628
  document.removeEventListener("keydown", onKey);
5252
5629
  };
5253
5630
  }, [colMenu, panel, rowMenu]);
5254
- React36__default.useEffect(() => {
5631
+ React37__default.useEffect(() => {
5255
5632
  if (!exportOpen) return;
5256
5633
  const close = () => {
5257
5634
  setExportOpen(false);
@@ -5270,9 +5647,9 @@ function Datatable({
5270
5647
  document.removeEventListener("keydown", onKey);
5271
5648
  };
5272
5649
  }, [exportOpen]);
5273
- const colByField = React36__default.useMemo(() => Object.fromEntries(cols.map((c) => [c.field, c])), [cols]);
5650
+ const colByField = React37__default.useMemo(() => Object.fromEntries(cols.map((c) => [c.field, c])), [cols]);
5274
5651
  const visibleCols = cols.filter((c) => !hidden.has(c.field));
5275
- const ordered = React36__default.useMemo(() => {
5652
+ const ordered = React37__default.useMemo(() => {
5276
5653
  const orderIdx = (f) => {
5277
5654
  const i = order.indexOf(f);
5278
5655
  return i === -1 ? 9999 : i;
@@ -5307,7 +5684,7 @@ function Datatable({
5307
5684
  }
5308
5685
  return {};
5309
5686
  };
5310
- const processed = React36__default.useMemo(() => {
5687
+ const processed = React37__default.useMemo(() => {
5311
5688
  if (serverMode) {
5312
5689
  if (rowOrder) {
5313
5690
  const idx = new Map(rowOrder.map((k, i) => [k, i]));
@@ -5344,12 +5721,12 @@ function Datatable({
5344
5721
  const paginated = pageSize > 0;
5345
5722
  const serverTotal = rowCount == null ? processed.length : rowCount;
5346
5723
  const totalRows = serverMode ? serverTotal : processed.length;
5347
- const totalPages = paginated ? Math.max(1, Math.ceil(totalRows / rowsPerPage)) : 1;
5348
- const paged = !paginated || serverMode ? processed : processed.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
5349
- React36__default.useEffect(() => {
5350
- if (page > totalPages - 1) setPage(0);
5724
+ const totalPages = paginated ? Math.max(1, Math.ceil(totalRows / sizeVal)) : 1;
5725
+ const paged = !paginated || serverMode ? processed : processed.slice(pageVal * sizeVal, pageVal * sizeVal + sizeVal);
5726
+ React37__default.useEffect(() => {
5727
+ if (pageVal > totalPages - 1) commitPage(0);
5351
5728
  }, [totalPages]);
5352
- const activeGroupBy = React36__default.useMemo(() => groupBy.filter((f) => colByField[f]), [groupBy, colByField]);
5729
+ const activeGroupBy = React37__default.useMemo(() => groupBy.filter((f) => colByField[f]), [groupBy, colByField]);
5353
5730
  function subtotalText(rowsIn) {
5354
5731
  const parts = [];
5355
5732
  for (const c of ordered) {
@@ -5376,7 +5753,7 @@ function Datatable({
5376
5753
  if (agg === "max") return Math.max(...nums);
5377
5754
  return null;
5378
5755
  }
5379
- const displayItems = React36__default.useMemo(() => {
5756
+ const displayItems = React37__default.useMemo(() => {
5380
5757
  if (!activeGroupBy.length) return null;
5381
5758
  const build = (rowsIn, depth, prefix) => {
5382
5759
  if (depth >= activeGroupBy.length) return rowsIn.map((row) => ({ kind: "leaf", row }));
@@ -5418,7 +5795,7 @@ function Datatable({
5418
5795
  return { top, bottom };
5419
5796
  });
5420
5797
  }
5421
- React36__default.useEffect(() => {
5798
+ React37__default.useEffect(() => {
5422
5799
  if (!rowPinning) return;
5423
5800
  const measure = () => {
5424
5801
  if (theadRef.current) setHeadH(theadRef.current.offsetHeight || 41);
@@ -5432,12 +5809,12 @@ function Datatable({
5432
5809
  const pinnedTopRows = canPinRows ? pinnedRows.top.map((k) => leafRows.find((r, i) => keyOf(r, i) === k)).filter(Boolean) : [];
5433
5810
  const pinnedBottomRows = canPinRows ? pinnedRows.bottom.map((k) => leafRows.find((r, i) => keyOf(r, i) === k)).filter(Boolean) : [];
5434
5811
  const middleRows = canPinRows ? leafRows.filter((r, i) => !pinSideOf(keyOf(r, i))) : leafRows;
5435
- const keyIndex = React36__default.useMemo(() => {
5812
+ const keyIndex = React37__default.useMemo(() => {
5436
5813
  const m = /* @__PURE__ */ new Map();
5437
5814
  leafRows.forEach((r, i) => m.set(keyOf(r, i), i));
5438
5815
  return m;
5439
5816
  }, [leafRows]);
5440
- const keyIndexMid = React36__default.useMemo(() => {
5817
+ const keyIndexMid = React37__default.useMemo(() => {
5441
5818
  const m = /* @__PURE__ */ new Map();
5442
5819
  middleRows.forEach((r, i) => m.set(keyOf(r, keyIndex.get(keyOf(r)) ?? i), i));
5443
5820
  return m;
@@ -5522,7 +5899,7 @@ function Datatable({
5522
5899
  setReorderMsg("Reorder cancelled.");
5523
5900
  }
5524
5901
  }
5525
- React36__default.useEffect(() => {
5902
+ React37__default.useEffect(() => {
5526
5903
  if (rowFocusRef.current == null) return;
5527
5904
  const key = rowFocusRef.current;
5528
5905
  rowFocusRef.current = null;
@@ -5534,7 +5911,7 @@ function Datatable({
5534
5911
  });
5535
5912
  const estRowH = rowHeight ?? (density === "compact" ? 36 : density === "comfortable" ? 56 : 44);
5536
5913
  const virtualizing = virtualized && !paginated && !activeGroupBy.length && !loading;
5537
- React36__default.useEffect(() => {
5914
+ React37__default.useEffect(() => {
5538
5915
  if (!virtualizing) return;
5539
5916
  const el = scrollRef.current;
5540
5917
  if (!el) return;
@@ -5544,13 +5921,13 @@ function Datatable({
5544
5921
  if (ro) ro.observe(el);
5545
5922
  return () => ro && ro.disconnect();
5546
5923
  }, [virtualizing, height]);
5547
- const onScrollVirtual = React36__default.useCallback((e) => {
5924
+ const onScrollVirtual = React37__default.useCallback((e) => {
5548
5925
  setScrollTop(e.currentTarget.scrollTop);
5549
5926
  }, []);
5550
5927
  const vh = viewportH || (typeof height === "number" ? height : 440);
5551
- const rowHRef = React36__default.useRef(/* @__PURE__ */ new Map());
5552
- const [measureTick, setMeasureTick] = React36__default.useState(0);
5553
- const offsets = React36__default.useMemo(() => {
5928
+ const rowHRef = React37__default.useRef(/* @__PURE__ */ new Map());
5929
+ const [measureTick, setMeasureTick] = React37__default.useState(0);
5930
+ const offsets = React37__default.useMemo(() => {
5554
5931
  if (!virtualizing) return null;
5555
5932
  const total = middleRows.length;
5556
5933
  const arr = new Float64Array(total + 1);
@@ -5560,7 +5937,7 @@ function Datatable({
5560
5937
  }
5561
5938
  return arr;
5562
5939
  }, [virtualizing, middleRows, estRowH, measureTick]);
5563
- const vWindow = React36__default.useMemo(() => {
5940
+ const vWindow = React37__default.useMemo(() => {
5564
5941
  if (!virtualizing || !offsets) return null;
5565
5942
  const total = middleRows.length;
5566
5943
  const totalH = offsets[total];
@@ -5589,7 +5966,7 @@ function Datatable({
5589
5966
  if (start > end) start = end;
5590
5967
  return { start, end, padTop: offsets[start], padBottom: Math.max(0, totalH - offsets[end]) };
5591
5968
  }, [virtualizing, offsets, middleRows.length, vh, scrollTop, overscan]);
5592
- React36__default.useLayoutEffect(() => {
5969
+ React37__default.useLayoutEffect(() => {
5593
5970
  if (!virtualizing) return;
5594
5971
  const el = scrollRef.current;
5595
5972
  if (!el) return;
@@ -5604,21 +5981,21 @@ function Datatable({
5604
5981
  }
5605
5982
  if (changed) setMeasureTick((t) => t + 1);
5606
5983
  });
5607
- const onServerChangeRef = React36__default.useRef(onServerChange);
5984
+ const onServerChangeRef = React37__default.useRef(onServerChange);
5608
5985
  onServerChangeRef.current = onServerChange;
5609
- React36__default.useEffect(() => {
5986
+ React37__default.useEffect(() => {
5610
5987
  if (!serverMode) return;
5611
5988
  const t = setTimeout(() => {
5612
5989
  onServerChangeRef.current?.({
5613
- page,
5614
- pageSize: rowsPerPage,
5990
+ page: pageVal,
5991
+ pageSize: sizeVal,
5615
5992
  sort,
5616
5993
  filters: filters.map(({ id, ...f }) => f),
5617
5994
  quickFilter: quick.trim()
5618
5995
  });
5619
5996
  }, 250);
5620
5997
  return () => clearTimeout(t);
5621
- }, [serverMode, page, rowsPerPage, sort, filters, quick]);
5998
+ }, [serverMode, pageVal, sizeVal, sort, filters, quick]);
5622
5999
  function cycleSort(field) {
5623
6000
  setSort((s) => !s || s.field !== field ? { field, dir: "asc" } : s.dir === "asc" ? { field, dir: "desc" } : null);
5624
6001
  }
@@ -5641,7 +6018,7 @@ function Datatable({
5641
6018
  return n;
5642
6019
  });
5643
6020
  }
5644
- const movableMidFields = React36__default.useMemo(
6021
+ const movableMidFields = React37__default.useMemo(
5645
6022
  () => ordered.filter((c) => !pins.left.includes(c.field) && !pins.right.includes(c.field) && c.reorderable !== false).map((c) => c.field),
5646
6023
  [ordered, pins]
5647
6024
  );
@@ -5672,7 +6049,7 @@ function Datatable({
5672
6049
  }
5673
6050
  return [...set].sort((a, b) => a.localeCompare(b)).map((v) => ({ value: v, label: v }));
5674
6051
  }
5675
- const [resizing, setResizing] = React36__default.useState(false);
6052
+ const [resizing, setResizing] = React37__default.useState(false);
5676
6053
  function startResize(e, field) {
5677
6054
  e.preventDefault();
5678
6055
  e.stopPropagation();
@@ -5779,7 +6156,7 @@ function Datatable({
5779
6156
  if (!agg) return null;
5780
6157
  if (aggregationValues && col.field in aggregationValues) {
5781
6158
  const pre = aggregationValues[col.field];
5782
- if (pre && typeof pre === "object" && !React36__default.isValidElement(pre)) {
6159
+ if (pre && typeof pre === "object" && !React37__default.isValidElement(pre)) {
5783
6160
  if (typeof agg === "string" && agg in pre) return pre[agg];
5784
6161
  } else {
5785
6162
  return pre;
@@ -5897,14 +6274,14 @@ function Datatable({
5897
6274
  focusCell(r, c);
5898
6275
  }
5899
6276
  }
5900
- React36__default.useEffect(() => {
6277
+ React37__default.useEffect(() => {
5901
6278
  setFocus((f) => ({ r: Math.min(f.r, Math.max(0, leafRows.length - 1)), c: Math.min(f.c, Math.max(0, ordered.length - 1)) }));
5902
- }, [leafRows.length, ordered.length, page]);
5903
- const selectedRows = React36__default.useMemo(() => rows.filter((r, i) => selected.has(keyOf(r, i))), [rows, selected]);
6279
+ }, [leafRows.length, ordered.length, pageVal]);
6280
+ const selectedRows = React37__default.useMemo(() => rows.filter((r, i) => selected.has(keyOf(r, i))), [rows, selected]);
5904
6281
  function clearSelection() {
5905
6282
  setSelected(/* @__PURE__ */ new Set());
5906
6283
  }
5907
- const [editing, setEditing] = React36__default.useState(null);
6284
+ const [editing, setEditing] = React37__default.useState(null);
5908
6285
  const isColEditable = (c) => c.type !== "actions" && (c.editable ?? (editMode && c.editable !== false));
5909
6286
  function beginEdit(rowK, col, row) {
5910
6287
  if (!isColEditable(col)) return;
@@ -5939,17 +6316,17 @@ function Datatable({
5939
6316
  cancelEdit();
5940
6317
  }
5941
6318
  }
5942
- const batchEditableCols = React36__default.useMemo(
6319
+ const batchEditableCols = React37__default.useMemo(
5943
6320
  () => cols.filter((c) => c.type !== "actions" && (c.editable ?? (editMode && c.editable !== false))),
5944
6321
  [cols, editMode]
5945
6322
  );
5946
- const [batchEdit, setBatchEdit] = React36__default.useState(null);
6323
+ const [batchEdit, setBatchEdit] = React37__default.useState(null);
5947
6324
  const [batchEditPos, openBatchEdit, closeBatchEdit] = useFloating();
5948
6325
  function openBatchEditor(el) {
5949
6326
  setBatchEdit({ fields: {}, values: {} });
5950
6327
  openBatchEdit(el, "left", 320);
5951
6328
  }
5952
- React36__default.useEffect(() => {
6329
+ React37__default.useEffect(() => {
5953
6330
  if (!batchEdit) return;
5954
6331
  const close = () => {
5955
6332
  setBatchEdit(null);
@@ -5968,7 +6345,7 @@ function Datatable({
5968
6345
  document.removeEventListener("keydown", onKey);
5969
6346
  };
5970
6347
  }, [batchEdit]);
5971
- React36__default.useEffect(() => {
6348
+ React37__default.useEffect(() => {
5972
6349
  if (batchEdit && selected.size === 0) {
5973
6350
  setBatchEdit(null);
5974
6351
  closeBatchEdit();
@@ -6005,7 +6382,7 @@ function Datatable({
6005
6382
  setBatchEdit(null);
6006
6383
  closeBatchEdit();
6007
6384
  }
6008
- React36__default.useEffect(() => {
6385
+ React37__default.useEffect(() => {
6009
6386
  if (!editing) return;
6010
6387
  const onDown = (e) => {
6011
6388
  if (e.target.closest(".twc-dt__editor-wrap") || e.target.closest(".twc-pop")) return;
@@ -6144,7 +6521,7 @@ function Datatable({
6144
6521
  {
6145
6522
  className: "twc-dt__row",
6146
6523
  role: "row",
6147
- "aria-rowindex": (paginated && !serverMode ? page * rowsPerPage : 0) + ri + 2,
6524
+ "aria-rowindex": (paginated && !serverMode ? pageVal * sizeVal : 0) + ri + 2,
6148
6525
  "aria-selected": (checkboxSelection ? sel : rowActive) || void 0,
6149
6526
  "data-selected": sel || void 0,
6150
6527
  "data-active": rowActive || void 0,
@@ -6202,7 +6579,7 @@ function Datatable({
6202
6579
  ] }),
6203
6580
  rowResize && !pinSide ? /* @__PURE__ */ jsx("span", { className: "twc-dt__row-resizer", title: "Drag to resize row", onPointerDown: (e) => startRowResize(e, k, e.currentTarget.closest("tr")), onClick: (e) => e.stopPropagation() }) : null
6204
6581
  ] }) : null,
6205
- showRowNum ? /* @__PURE__ */ jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": pins.left.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: typeof ri === "number" ? (paginated || serverMode ? page * rowsPerPage : 0) + ri + 1 : "" }) : null,
6582
+ showRowNum ? /* @__PURE__ */ jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": pins.left.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: typeof ri === "number" ? (paginated || serverMode ? pageVal * sizeVal : 0) + ri + 1 : "" }) : null,
6206
6583
  ordered.map((c, ci) => {
6207
6584
  const st = stickyOf(c.field);
6208
6585
  const val = row[c.field];
@@ -6530,7 +6907,7 @@ function Datatable({
6530
6907
  /* @__PURE__ */ jsx(Svg, { d: I.search }),
6531
6908
  /* @__PURE__ */ jsx("input", { placeholder: "Search\u2026", "aria-label": "Search rows", value: quick, onChange: (e) => {
6532
6909
  setQuick(e.target.value);
6533
- setPage(0);
6910
+ commitPage(0);
6534
6911
  } })
6535
6912
  ] })
6536
6913
  ] }),
@@ -6732,7 +7109,7 @@ function Datatable({
6732
7109
  );
6733
7110
  })
6734
7111
  ] }) }),
6735
- /* @__PURE__ */ jsx("tbody", { children: loading ? Array.from({ length: paginated ? Math.min(rowsPerPage, 8) : 8 }).map((_, ri) => /* @__PURE__ */ jsxs("tr", { className: "twc-dt__row", role: "row", children: [
7112
+ /* @__PURE__ */ jsx("tbody", { children: loading ? Array.from({ length: paginated ? Math.min(sizeVal, 8) : 8 }).map((_, ri) => /* @__PURE__ */ jsxs("tr", { className: "twc-dt__row", role: "row", children: [
6736
7113
  checkboxSelection ? /* @__PURE__ */ jsx("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", style: { insetInlineStart: 0, width: 44 }, children: /* @__PURE__ */ jsx("span", { className: "twc-dt__sk", "aria-hidden": "true", style: { "--_w": "18px", height: 18, borderRadius: 4 } }) }) : null,
6737
7114
  showRowNum ? /* @__PURE__ */ jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: /* @__PURE__ */ jsx("span", { className: "twc-dt__sk", "aria-hidden": "true", style: { "--_w": "16px", height: 14, borderRadius: 4 } }) }) : null,
6738
7115
  ordered.map((c, ci) => {
@@ -6776,7 +7153,7 @@ function Datatable({
6776
7153
  const nf = (n) => n.toLocaleString();
6777
7154
  if (totalRows === 0) return "No rows";
6778
7155
  const shown = paged.length;
6779
- const start = paginated ? page * rowsPerPage + 1 : 1;
7156
+ const start = paginated ? pageVal * sizeVal + 1 : 1;
6780
7157
  const end = paginated ? start + shown - 1 : shown;
6781
7158
  return /* @__PURE__ */ jsxs(Fragment, { children: [
6782
7159
  paginated ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -6804,13 +7181,10 @@ function Datatable({
6804
7181
  })() }),
6805
7182
  paginated ? /* @__PURE__ */ jsxs("div", { className: "twc-dt__rpp", children: [
6806
7183
  /* @__PURE__ */ jsx("span", { className: "twc-dt__rpp-label", children: "Rows per page" }),
6807
- /* @__PURE__ */ jsx("div", { style: { width: 78 }, children: /* @__PURE__ */ jsx(Select, { size: "sm", portal: true, searchable: false, value: String(rowsPerPage), options: rppOptions, placement: "top", onChange: (v) => {
6808
- setRowsPerPage(Number(v));
6809
- setPage(0);
6810
- } }) })
7184
+ /* @__PURE__ */ jsx("div", { style: { width: 78 }, children: /* @__PURE__ */ jsx(Select, { size: "sm", portal: true, searchable: false, value: String(sizeVal), options: rppOptions, placement: "top", onChange: (v) => commitPageSize(Number(v)) }) })
6811
7185
  ] }) : null
6812
7186
  ] }),
6813
- paginated ? /* @__PURE__ */ jsx("div", { className: "twc-dt__footer-row", "data-pager": "true", children: /* @__PURE__ */ jsx(Pagination, { size: "sm", page: page + 1, total: totalPages, boundaries: 3, showPageJumper: showPageJumper && totalPages > 5, onChange: (p) => setPage(p - 1) }) }) : null
7187
+ paginated ? /* @__PURE__ */ jsx("div", { className: "twc-dt__footer-row", "data-pager": "true", children: /* @__PURE__ */ jsx(Pagination, { size: "sm", page: pageVal + 1, total: totalPages, boundaries: 3, showPageJumper: showPageJumper && totalPages > 5, onChange: (p) => commitPage(p - 1) }) }) : null
6814
7188
  ] }) : null,
6815
7189
  exportOpen && exportPos ? /* @__PURE__ */ jsxs(
6816
7190
  "div",
@@ -7459,6 +7833,18 @@ var DATEPICKER_CSS = `
7459
7833
  .twc-dp__clear { position: absolute; inset-inline-end: 10px; top: 50%; transform: translateY(-50%); display: inline-grid; place-items: center; width: 20px; height: 20px; border: none; background: transparent; color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-full); }
7460
7834
  .twc-dp__clear:hover { background: var(--color-surface-sunken); color: var(--color-text); }
7461
7835
  .twc-dp__clear svg { width: 14px; height: 14px; }
7836
+ /* #105: editable (typed entry) variant \u2014 the control wraps a real text input + a trailing toggle. */
7837
+ .twc-dp__control--editable { cursor: text; gap: 0; padding-inline-end: var(--space-1); }
7838
+ .twc-dp__input { flex: 1; min-width: 0; height: 100%; border: none; background: transparent; outline: none; padding: 0;
7839
+ font-family: inherit; font-size: var(--text-sm); color: var(--color-text); }
7840
+ .twc-dp__input::placeholder { color: var(--color-text-subtle); }
7841
+ .twc-dp__input:disabled { cursor: not-allowed; }
7842
+ .twc-dp__clear--inline { position: static; transform: none; flex: none; }
7843
+ .twc-dp__toggle { flex: none; display: inline-grid; place-items: center; width: 26px; height: 26px; border: none; background: transparent;
7844
+ color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-md); transition: background-color var(--duration-fast), color var(--duration-fast); }
7845
+ .twc-dp__toggle:hover:not(:disabled) { background: var(--color-surface-sunken); color: var(--color-text); }
7846
+ .twc-dp__toggle:disabled { cursor: not-allowed; }
7847
+ .twc-dp__toggle svg { width: 17px; height: 17px; }
7462
7848
 
7463
7849
  .twc-dp__pop {
7464
7850
  position: fixed; z-index: var(--z-popover); width: 280px;
@@ -7518,6 +7904,8 @@ function DatePicker({
7518
7904
  disabled = false,
7519
7905
  tone = "primary",
7520
7906
  clearable = true,
7907
+ editable = false,
7908
+ parse,
7521
7909
  format,
7522
7910
  locale,
7523
7911
  weekStartsOn = 0,
@@ -7528,24 +7916,25 @@ function DatePicker({
7528
7916
  }) {
7529
7917
  const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS3);
7530
7918
  const __twcStyles1 = useScopedStyles("twc-datepicker-styles", DATEPICKER_CSS);
7531
- const autoId = React36__default.useId();
7919
+ const autoId = React37__default.useId();
7532
7920
  const fieldId = id || autoId;
7533
7921
  const descId = `${fieldId}-desc`;
7534
7922
  const invalid = Boolean(error);
7535
- const [internal, setInternal] = React36__default.useState(defaultValue);
7923
+ const [internal, setInternal] = React37__default.useState(defaultValue);
7536
7924
  const selected = value !== void 0 ? value : internal;
7537
- const [open, setOpen] = React36__default.useState(false);
7538
- const [view, setView] = React36__default.useState(selected || /* @__PURE__ */ new Date());
7539
- const [mode, setMode] = React36__default.useState("days");
7540
- const [focusDate, setFocusDate] = React36__default.useState(null);
7541
- const [focusMonth, setFocusMonth] = React36__default.useState(null);
7542
- const [coords, setCoords] = React36__default.useState(null);
7543
- const wrapRef = React36__default.useRef(null);
7544
- const triggerRef = React36__default.useRef(null);
7545
- const popRef = React36__default.useRef(null);
7546
- const gridRef = React36__default.useRef(null);
7925
+ const [open, setOpen] = React37__default.useState(false);
7926
+ const [view, setView] = React37__default.useState(selected || /* @__PURE__ */ new Date());
7927
+ const [mode, setMode] = React37__default.useState("days");
7928
+ const [focusDate, setFocusDate] = React37__default.useState(null);
7929
+ const [focusMonth, setFocusMonth] = React37__default.useState(null);
7930
+ const [editText, setEditText] = React37__default.useState(null);
7931
+ const [coords, setCoords] = React37__default.useState(null);
7932
+ const wrapRef = React37__default.useRef(null);
7933
+ const triggerRef = React37__default.useRef(null);
7934
+ const popRef = React37__default.useRef(null);
7935
+ const gridRef = React37__default.useRef(null);
7547
7936
  const POP_W = 280;
7548
- const place = React36__default.useCallback(() => {
7937
+ const place = React37__default.useCallback(() => {
7549
7938
  const el = triggerRef.current;
7550
7939
  if (!el) return;
7551
7940
  const r = el.getBoundingClientRect();
@@ -7556,7 +7945,7 @@ function DatePicker({
7556
7945
  left = Math.max(8, left);
7557
7946
  setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
7558
7947
  }, []);
7559
- React36__default.useEffect(() => {
7948
+ React37__default.useEffect(() => {
7560
7949
  if (!open) return void 0;
7561
7950
  place();
7562
7951
  const onMove = () => place();
@@ -7567,7 +7956,7 @@ function DatePicker({
7567
7956
  window.removeEventListener("resize", onMove);
7568
7957
  };
7569
7958
  }, [open, place]);
7570
- React36__default.useEffect(() => {
7959
+ React37__default.useEffect(() => {
7571
7960
  if (!open) return;
7572
7961
  setView(selected || /* @__PURE__ */ new Date());
7573
7962
  setMode("days");
@@ -7588,9 +7977,9 @@ function DatePicker({
7588
7977
  };
7589
7978
  }, [open]);
7590
7979
  useFocusTrap(popRef, open && !!coords, { initialFocus: () => gridRef.current?.querySelector('[tabindex="0"]') });
7591
- const months = React36__default.useMemo(() => locale === void 0 ? MONTHS : monthNames(locale), [locale]);
7592
- const monthsShort = React36__default.useMemo(() => locale === void 0 ? MONTHS.map((n) => n.slice(0, 3)) : monthShortNames(locale), [locale]);
7593
- const dows = React36__default.useMemo(
7980
+ const months = React37__default.useMemo(() => locale === void 0 ? MONTHS : monthNames(locale), [locale]);
7981
+ const monthsShort = React37__default.useMemo(() => locale === void 0 ? MONTHS.map((n) => n.slice(0, 3)) : monthShortNames(locale), [locale]);
7982
+ const dows = React37__default.useMemo(
7594
7983
  () => locale === void 0 ? Array.from({ length: 7 }, (_, i) => DOW[(i + weekStartsOn) % 7]) : weekdayNames(locale, weekStartsOn),
7595
7984
  [locale, weekStartsOn]
7596
7985
  );
@@ -7602,8 +7991,33 @@ function DatePicker({
7602
7991
  const pick = (d) => {
7603
7992
  if (value === void 0) setInternal(d);
7604
7993
  onChange?.(d);
7994
+ setEditText(null);
7605
7995
  setOpen(false);
7606
7996
  };
7997
+ const parseTyped = (s) => {
7998
+ const str = s.trim();
7999
+ if (str === "") return null;
8000
+ if (parse) {
8001
+ const d = parse(str);
8002
+ return d instanceof Date && !Number.isNaN(d.getTime()) ? d : void 0;
8003
+ }
8004
+ const t = Date.parse(str);
8005
+ return Number.isNaN(t) ? void 0 : new Date(t);
8006
+ };
8007
+ const commitText = () => {
8008
+ if (editText == null) return;
8009
+ const parsed = parseTyped(editText);
8010
+ if (parsed === null) {
8011
+ setEditText(null);
8012
+ if (selected) pick(null);
8013
+ return;
8014
+ }
8015
+ if (parsed === void 0 || outOfRange(parsed)) {
8016
+ setEditText(null);
8017
+ return;
8018
+ }
8019
+ pick(parsed);
8020
+ };
7607
8021
  const y = view.getFullYear(), m = view.getMonth();
7608
8022
  const first = new Date(y, m, 1);
7609
8023
  const startOffset = (first.getDay() - weekStartsOn + 7) % 7;
@@ -7618,11 +8032,11 @@ function DatePicker({
7618
8032
  };
7619
8033
  const cells = Array.from({ length: 42 }, (_, i) => new Date(gridStart.getFullYear(), gridStart.getMonth(), gridStart.getDate() + i));
7620
8034
  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);
7621
- React36__default.useEffect(() => {
8035
+ React37__default.useEffect(() => {
7622
8036
  if (!open || mode !== "days" || !focusDate) return;
7623
8037
  gridRef.current?.querySelector(`[data-key="${keyOf(focusDate)}"]`)?.focus();
7624
8038
  }, [focusDate, open, mode]);
7625
- React36__default.useEffect(() => {
8039
+ React37__default.useEffect(() => {
7626
8040
  if (!open || mode !== "months" || focusMonth == null) return;
7627
8041
  gridRef.current?.querySelector(`[data-mo="${focusMonth}"]`)?.focus();
7628
8042
  }, [focusMonth, open, mode]);
@@ -7679,7 +8093,82 @@ function DatePicker({
7679
8093
  label,
7680
8094
  required ? /* @__PURE__ */ jsx("span", { className: "twc-field__req", children: "*" }) : null
7681
8095
  ] }) : null,
7682
- /* @__PURE__ */ jsxs("div", { className: "twc-dp__field", children: [
8096
+ /* @__PURE__ */ jsx("div", { className: "twc-dp__field", children: editable ? (
8097
+ // #105: typed entry — the trigger is a real text input with a trailing
8098
+ // calendar toggle button; typing commits via `parse` on Enter/blur.
8099
+ /* @__PURE__ */ jsxs(
8100
+ "div",
8101
+ {
8102
+ className: "twc-dp__control twc-dp__control--editable",
8103
+ "data-open": open || void 0,
8104
+ "data-disabled": disabled || void 0,
8105
+ "data-tone": tone,
8106
+ "data-invalid": invalid || void 0,
8107
+ children: [
8108
+ /* @__PURE__ */ jsx(
8109
+ "input",
8110
+ {
8111
+ ref: triggerRef,
8112
+ className: "twc-dp__input",
8113
+ id: fieldId,
8114
+ type: "text",
8115
+ inputMode: "numeric",
8116
+ autoComplete: "off",
8117
+ disabled,
8118
+ placeholder,
8119
+ value: editText != null ? editText : selected ? fmt(selected) : "",
8120
+ "aria-haspopup": "dialog",
8121
+ "aria-expanded": open,
8122
+ "aria-labelledby": label ? `${fieldId}-label` : void 0,
8123
+ "aria-invalid": invalid || void 0,
8124
+ "aria-describedby": error || hint ? descId : void 0,
8125
+ onChange: (e) => setEditText(e.target.value),
8126
+ onKeyDown: (e) => {
8127
+ if (e.key === "Enter") {
8128
+ e.preventDefault();
8129
+ commitText();
8130
+ } else if (e.key === "ArrowDown" && (e.altKey || !open)) {
8131
+ e.preventDefault();
8132
+ setOpen(true);
8133
+ } else if (e.key === "Escape" && open) setOpen(false);
8134
+ },
8135
+ onBlur: (e) => {
8136
+ if (popRef.current && popRef.current.contains(e.relatedTarget)) return;
8137
+ commitText();
8138
+ }
8139
+ }
8140
+ ),
8141
+ clearable && selected && !disabled ? /* @__PURE__ */ jsx(
8142
+ "button",
8143
+ {
8144
+ type: "button",
8145
+ className: "twc-dp__clear twc-dp__clear--inline",
8146
+ "aria-label": "Clear",
8147
+ tabIndex: -1,
8148
+ onMouseDown: (e) => e.preventDefault(),
8149
+ onClick: () => pick(null),
8150
+ children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
8151
+ }
8152
+ ) : null,
8153
+ /* @__PURE__ */ jsx(
8154
+ "button",
8155
+ {
8156
+ type: "button",
8157
+ className: "twc-dp__toggle",
8158
+ "aria-label": "Open calendar",
8159
+ tabIndex: -1,
8160
+ disabled,
8161
+ onClick: () => !disabled && setOpen((o) => !o),
8162
+ children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
8163
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
8164
+ /* @__PURE__ */ jsx("path", { d: "M16 2v4M8 2v4M3 10h18" })
8165
+ ] })
8166
+ }
8167
+ )
8168
+ ]
8169
+ }
8170
+ )
8171
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
7683
8172
  /* @__PURE__ */ jsxs(
7684
8173
  "div",
7685
8174
  {
@@ -7718,7 +8207,7 @@ function DatePicker({
7718
8207
  e.stopPropagation();
7719
8208
  pick(null);
7720
8209
  }, children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
7721
- ] }),
8210
+ ] }) }),
7722
8211
  open && coords ? createPortal(
7723
8212
  /* @__PURE__ */ jsxs(
7724
8213
  "div",
@@ -7817,6 +8306,17 @@ var RANGE_CSS = `
7817
8306
  .twc-drp__ic svg { width: 17px; height: 17px; }
7818
8307
  .twc-drp__text { flex: 1; font-size: var(--text-sm); color: var(--color-text); white-space: nowrap; }
7819
8308
  .twc-drp__text[data-placeholder="true"] { color: var(--color-text-subtle); }
8309
+ /* #105: editable (typed entry) variant. */
8310
+ .twc-drp__control--editable { cursor: text; gap: 0; padding-inline-end: var(--space-1); }
8311
+ .twc-drp__input { flex: 1; min-width: 0; height: 100%; border: none; background: transparent; outline: none; padding: 0;
8312
+ font-family: inherit; font-size: var(--text-sm); color: var(--color-text); }
8313
+ .twc-drp__input::placeholder { color: var(--color-text-subtle); }
8314
+ .twc-drp__input:disabled { cursor: not-allowed; }
8315
+ .twc-drp__toggle { flex: none; display: inline-grid; place-items: center; width: 26px; height: 26px; border: none; background: transparent;
8316
+ color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-md); transition: background-color var(--duration-fast), color var(--duration-fast); }
8317
+ .twc-drp__toggle:hover:not(:disabled) { background: var(--color-surface-sunken); color: var(--color-text); }
8318
+ .twc-drp__toggle:disabled { cursor: not-allowed; }
8319
+ .twc-drp__toggle svg { width: 17px; height: 17px; }
7820
8320
  .twc-drp__pop { position: fixed; z-index: var(--z-popover); display: flex;
7821
8321
  background: var(--color-surface-raised); border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-lg);
7822
8322
  box-shadow: var(--shadow-lg); animation: twico-scale-in var(--duration-fast) var(--ease-spring); transform-origin: top; }
@@ -7871,31 +8371,34 @@ function DateRangePicker({
7871
8371
  disabledDate,
7872
8372
  disabled = false,
7873
8373
  tone = "primary",
8374
+ editable = false,
8375
+ parse,
7874
8376
  onChange,
7875
8377
  className = "",
7876
8378
  ...rest
7877
8379
  }) {
7878
8380
  const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS4);
7879
8381
  const __twcStyles1 = useScopedStyles("twc-drp-styles", RANGE_CSS);
7880
- const [internal, setInternal] = React36__default.useState(defaultValue);
8382
+ const [internal, setInternal] = React37__default.useState(defaultValue);
7881
8383
  const range = value !== void 0 ? value : internal;
7882
- const [open, setOpen] = React36__default.useState(false);
7883
- const [view, setView] = React36__default.useState(range.start || /* @__PURE__ */ new Date());
7884
- const [hover, setHover] = React36__default.useState(null);
7885
- const [focusDate, setFocusDate] = React36__default.useState(null);
7886
- const [coords, setCoords] = React36__default.useState(null);
7887
- const wrapRef = React36__default.useRef(null);
7888
- const triggerRef = React36__default.useRef(null);
7889
- const popRef = React36__default.useRef(null);
7890
- const gridRef = React36__default.useRef(null);
7891
- const labelId = React36__default.useId();
8384
+ const [open, setOpen] = React37__default.useState(false);
8385
+ const [view, setView] = React37__default.useState(range.start || /* @__PURE__ */ new Date());
8386
+ const [hover, setHover] = React37__default.useState(null);
8387
+ const [focusDate, setFocusDate] = React37__default.useState(null);
8388
+ const [editText, setEditText] = React37__default.useState(null);
8389
+ const [coords, setCoords] = React37__default.useState(null);
8390
+ const wrapRef = React37__default.useRef(null);
8391
+ const triggerRef = React37__default.useRef(null);
8392
+ const popRef = React37__default.useRef(null);
8393
+ const gridRef = React37__default.useRef(null);
8394
+ const labelId = React37__default.useId();
7892
8395
  const descId = `${labelId}-desc`;
7893
8396
  const invalid = Boolean(error);
7894
- React36__default.useEffect(() => {
8397
+ React37__default.useEffect(() => {
7895
8398
  if (disabled) setOpen(false);
7896
8399
  }, [disabled]);
7897
8400
  const POP_W = 420;
7898
- const place = React36__default.useCallback(() => {
8401
+ const place = React37__default.useCallback(() => {
7899
8402
  const el = triggerRef.current;
7900
8403
  if (!el) return;
7901
8404
  const r = el.getBoundingClientRect();
@@ -7906,7 +8409,7 @@ function DateRangePicker({
7906
8409
  left = Math.max(8, left);
7907
8410
  setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
7908
8411
  }, []);
7909
- React36__default.useEffect(() => {
8412
+ React37__default.useEffect(() => {
7910
8413
  if (!open) return void 0;
7911
8414
  place();
7912
8415
  const onMove = () => place();
@@ -7917,7 +8420,7 @@ function DateRangePicker({
7917
8420
  window.removeEventListener("resize", onMove);
7918
8421
  };
7919
8422
  }, [open, place]);
7920
- React36__default.useEffect(() => {
8423
+ React37__default.useEffect(() => {
7921
8424
  if (!open) return;
7922
8425
  const onDown = (e) => {
7923
8426
  if (wrapRef.current && wrapRef.current.contains(e.target)) return;
@@ -7938,6 +8441,40 @@ function DateRangePicker({
7938
8441
  if (value === void 0) setInternal(r);
7939
8442
  onChange?.(r);
7940
8443
  };
8444
+ const parseOne = (s) => {
8445
+ const str = s.trim();
8446
+ if (str === "") return null;
8447
+ if (parse) {
8448
+ const d = parse(str);
8449
+ return d instanceof Date && !Number.isNaN(d.getTime()) ? d : void 0;
8450
+ }
8451
+ const t = Date.parse(str);
8452
+ return Number.isNaN(t) ? void 0 : new Date(t);
8453
+ };
8454
+ const commitText = () => {
8455
+ if (editText == null) return;
8456
+ const raw = editText.trim();
8457
+ if (raw === "") {
8458
+ setEditText(null);
8459
+ if (range.start || range.end) set({ start: null, end: null });
8460
+ return;
8461
+ }
8462
+ const parts = raw.split(/\s*(?:–|—|\bto\b|\.\.+)\s*/i).map((p) => p.trim());
8463
+ let a = parseOne(parts[0] || "");
8464
+ let b = parts.length > 1 ? parseOne(parts[1] || "") : null;
8465
+ if (a === void 0 || b === void 0 || a && outOfRange(a) || b && outOfRange(b)) {
8466
+ setEditText(null);
8467
+ return;
8468
+ }
8469
+ if (a && b && ymd(b) < ymd(a)) {
8470
+ const t = a;
8471
+ a = b;
8472
+ b = t;
8473
+ }
8474
+ set({ start: a || null, end: b || null });
8475
+ setEditText(null);
8476
+ setOpen(false);
8477
+ };
7941
8478
  useFocusTrap(popRef, open && !!coords, { initialFocus: () => gridRef.current?.querySelector('[tabindex="0"]') });
7942
8479
  const outOfRange = (d) => min && ymd(d) < ymd(min) || max && ymd(d) > ymd(max) || Boolean(disabledDate && disabledDate(d));
7943
8480
  const sameDay2 = (a, b) => a && b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
@@ -7947,13 +8484,13 @@ function DateRangePicker({
7947
8484
  const last = new Date(d.getFullYear(), d.getMonth() + n + 1, 0);
7948
8485
  return new Date(last.getFullYear(), last.getMonth(), Math.min(d.getDate(), last.getDate()));
7949
8486
  };
7950
- React36__default.useEffect(() => {
8487
+ React37__default.useEffect(() => {
7951
8488
  if (!open) {
7952
8489
  setFocusDate(null);
7953
8490
  setHover(null);
7954
8491
  }
7955
8492
  }, [open]);
7956
- React36__default.useEffect(() => {
8493
+ React37__default.useEffect(() => {
7957
8494
  if (!open || !focusDate) return;
7958
8495
  gridRef.current?.querySelector(`[data-key="${keyOf(focusDate)}"]`)?.focus();
7959
8496
  }, [focusDate, open]);
@@ -8002,8 +8539,8 @@ function DateRangePicker({
8002
8539
  setView(start);
8003
8540
  setOpen(false);
8004
8541
  };
8005
- const months = React36__default.useMemo(() => locale === void 0 ? MONTHS2 : monthNames2(locale), [locale]);
8006
- const dows = React36__default.useMemo(
8542
+ const months = React37__default.useMemo(() => locale === void 0 ? MONTHS2 : monthNames2(locale), [locale]);
8543
+ const dows = React37__default.useMemo(
8007
8544
  () => locale === void 0 ? Array.from({ length: 7 }, (_, i) => DOW2[(i + weekStartsOn) % 7]) : weekdayNames2(locale, weekStartsOn),
8008
8545
  [locale, weekStartsOn]
8009
8546
  );
@@ -8033,7 +8570,57 @@ function DateRangePicker({
8033
8570
  label,
8034
8571
  required ? /* @__PURE__ */ jsx("span", { className: "twc-field__req", children: "*" }) : null
8035
8572
  ] }) : null,
8036
- /* @__PURE__ */ jsxs(
8573
+ editable ? (
8574
+ // #105: typed entry — a text input accepting "start – end"; commits via `parse` on Enter/blur.
8575
+ /* @__PURE__ */ jsxs("div", { className: "twc-drp__control twc-drp__control--editable", "data-open": open || void 0, "data-disabled": disabled || void 0, "data-invalid": invalid || void 0, "data-tone": tone, children: [
8576
+ /* @__PURE__ */ jsx(
8577
+ "input",
8578
+ {
8579
+ ref: triggerRef,
8580
+ className: "twc-drp__input",
8581
+ type: "text",
8582
+ autoComplete: "off",
8583
+ disabled,
8584
+ placeholder,
8585
+ value: editText != null ? editText : text,
8586
+ "aria-haspopup": "dialog",
8587
+ "aria-expanded": open,
8588
+ "aria-labelledby": label ? labelId : void 0,
8589
+ "aria-invalid": invalid || void 0,
8590
+ "aria-describedby": error || hint ? descId : void 0,
8591
+ onChange: (e) => setEditText(e.target.value),
8592
+ onKeyDown: (e) => {
8593
+ if (e.key === "Enter") {
8594
+ e.preventDefault();
8595
+ commitText();
8596
+ } else if (e.key === "ArrowDown" && (e.altKey || !open)) {
8597
+ e.preventDefault();
8598
+ setOpen(true);
8599
+ } else if (e.key === "Escape" && open) setOpen(false);
8600
+ },
8601
+ onBlur: (e) => {
8602
+ if (popRef.current && popRef.current.contains(e.relatedTarget)) return;
8603
+ commitText();
8604
+ }
8605
+ }
8606
+ ),
8607
+ /* @__PURE__ */ jsx(
8608
+ "button",
8609
+ {
8610
+ type: "button",
8611
+ className: "twc-drp__toggle",
8612
+ "aria-label": "Open calendar",
8613
+ tabIndex: -1,
8614
+ disabled,
8615
+ onClick: () => !disabled && setOpen((o) => !o),
8616
+ children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
8617
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
8618
+ /* @__PURE__ */ jsx("path", { d: "M16 2v4M8 2v4M3 10h18" })
8619
+ ] })
8620
+ }
8621
+ )
8622
+ ] })
8623
+ ) : /* @__PURE__ */ jsxs(
8037
8624
  "div",
8038
8625
  {
8039
8626
  ref: triggerRef,
@@ -8193,14 +8780,14 @@ function Dialog({
8193
8780
  className = "",
8194
8781
  ...rest
8195
8782
  }) {
8196
- const autoId = React36__default.useId();
8783
+ const autoId = React37__default.useId();
8197
8784
  const titleId = `${autoId}-title`;
8198
8785
  const descId = `${autoId}-desc`;
8199
- const dialogRef = React36__default.useRef(null);
8786
+ const dialogRef = React37__default.useRef(null);
8200
8787
  const __twcStyles = useScopedStyles("twc-dialog-styles", DIALOG_CSS);
8201
8788
  const renderPortal = usePortal();
8202
- const [mounted, setMounted] = React36__default.useState(open);
8203
- React36__default.useEffect(() => {
8789
+ const [mounted, setMounted] = React37__default.useState(open);
8790
+ React37__default.useEffect(() => {
8204
8791
  if (open) {
8205
8792
  setMounted(true);
8206
8793
  return;
@@ -8211,7 +8798,7 @@ function Dialog({
8211
8798
  useScrollLock(open);
8212
8799
  useInertBackground(dialogRef, open && mounted);
8213
8800
  useFocusTrap(dialogRef, open && mounted);
8214
- React36__default.useEffect(() => {
8801
+ React37__default.useEffect(() => {
8215
8802
  if (!open) return void 0;
8216
8803
  const onKey = (e) => {
8217
8804
  if (e.key === "Escape") {
@@ -8358,14 +8945,14 @@ function Drawer({
8358
8945
  style,
8359
8946
  ...rest
8360
8947
  }) {
8361
- const autoId = React36__default.useId();
8948
+ const autoId = React37__default.useId();
8362
8949
  const titleId = `${autoId}-title`;
8363
8950
  const descId = `${autoId}-desc`;
8364
- const panelRef = React36__default.useRef(null);
8951
+ const panelRef = React37__default.useRef(null);
8365
8952
  const __twcStyles = useScopedStyles("twc-drawer-styles", DRAWER_CSS);
8366
8953
  const renderPortal = usePortal();
8367
- const [mounted, setMounted] = React36__default.useState(open);
8368
- React36__default.useEffect(() => {
8954
+ const [mounted, setMounted] = React37__default.useState(open);
8955
+ React37__default.useEffect(() => {
8369
8956
  if (open) {
8370
8957
  setMounted(true);
8371
8958
  return;
@@ -8376,7 +8963,7 @@ function Drawer({
8376
8963
  useScrollLock(open);
8377
8964
  useInertBackground(panelRef, open && mounted);
8378
8965
  useFocusTrap(panelRef, open && mounted);
8379
- React36__default.useEffect(() => {
8966
+ React37__default.useEffect(() => {
8380
8967
  if (!open) return void 0;
8381
8968
  const onKey = (e) => {
8382
8969
  if (e.key === "Escape") {
@@ -8465,11 +9052,11 @@ function Field({
8465
9052
  ...rest
8466
9053
  }) {
8467
9054
  const __twcStyles = useScopedStyles("twc-field-styles", FIELD_CSS5);
8468
- const autoId = React36__default.useId();
9055
+ const autoId = React37__default.useId();
8469
9056
  const fieldId = id || autoId;
8470
9057
  const descId = `${fieldId}-desc`;
8471
9058
  const hasMsg = Boolean(error || hint);
8472
- const control = React36__default.isValidElement(children) ? React36__default.cloneElement(children, {
9059
+ const control = React37__default.isValidElement(children) ? React37__default.cloneElement(children, {
8473
9060
  "aria-describedby": [children.props["aria-describedby"], hasMsg ? descId : null].filter(Boolean).join(" ") || void 0,
8474
9061
  "aria-invalid": children.props["aria-invalid"] !== void 0 ? children.props["aria-invalid"] : error ? true : void 0
8475
9062
  }) : children;
@@ -8561,11 +9148,11 @@ function FileUpload({
8561
9148
  ...rest
8562
9149
  }) {
8563
9150
  const __twcStyles = useScopedStyles("twc-upload-styles", UPLOAD_CSS);
8564
- const [internal, setInternal] = React36__default.useState(defaultValue);
9151
+ const [internal, setInternal] = React37__default.useState(defaultValue);
8565
9152
  const files = value !== void 0 ? value : internal;
8566
- const [drag, setDrag] = React36__default.useState(false);
8567
- const inputRef = React36__default.useRef(null);
8568
- const autoId = React36__default.useId();
9153
+ const [drag, setDrag] = React37__default.useState(false);
9154
+ const inputRef = React37__default.useRef(null);
9155
+ const autoId = React37__default.useId();
8569
9156
  const fieldId = id || autoId;
8570
9157
  const descId = `${fieldId}-desc`;
8571
9158
  const invalid = Boolean(error);
@@ -8788,15 +9375,15 @@ function Kanban({
8788
9375
  ...rest
8789
9376
  }) {
8790
9377
  const __twcStyles = useScopedStyles("twc-kanban-styles", KANBAN_CSS);
8791
- const [internal, setInternal] = React36__default.useState(cards ?? defaultCards ?? []);
9378
+ const [internal, setInternal] = React37__default.useState(cards ?? defaultCards ?? []);
8792
9379
  const items = cards !== void 0 ? cards : internal;
8793
- const [drag, setDrag] = React36__default.useState(null);
8794
- const [overCol, setOverCol] = React36__default.useState(null);
8795
- const [grab, setGrab] = React36__default.useState(null);
8796
- const [announce, setAnnounce] = React36__default.useState("");
8797
- const rootRef = React36__default.useRef(null);
8798
- const focusIdRef = React36__default.useRef(null);
8799
- React36__default.useEffect(() => {
9380
+ const [drag, setDrag] = React37__default.useState(null);
9381
+ const [overCol, setOverCol] = React37__default.useState(null);
9382
+ const [grab, setGrab] = React37__default.useState(null);
9383
+ const [announce, setAnnounce] = React37__default.useState("");
9384
+ const rootRef = React37__default.useRef(null);
9385
+ const focusIdRef = React37__default.useRef(null);
9386
+ React37__default.useEffect(() => {
8800
9387
  if (focusIdRef.current == null) return void 0;
8801
9388
  const raf = requestAnimationFrame(() => {
8802
9389
  const id = focusIdRef.current;
@@ -9106,21 +9693,21 @@ function Popover({
9106
9693
  ...rest
9107
9694
  }) {
9108
9695
  const __twcStyles = useScopedStyles("twc-popover-styles", POPOVER_CSS);
9109
- const [openState, setOpenState] = React36__default.useState(defaultOpen);
9110
- const [render, setRender] = React36__default.useState(false);
9111
- const [pos, setPos] = React36__default.useState(null);
9112
- const wrapRef = React36__default.useRef(null);
9113
- const popRef = React36__default.useRef(null);
9114
- const popId = React36__default.useId();
9696
+ const [openState, setOpenState] = React37__default.useState(defaultOpen);
9697
+ const [render, setRender] = React37__default.useState(false);
9698
+ const [pos, setPos] = React37__default.useState(null);
9699
+ const wrapRef = React37__default.useRef(null);
9700
+ const popRef = React37__default.useRef(null);
9701
+ const popId = React37__default.useId();
9115
9702
  const controlled = openProp !== void 0;
9116
9703
  const open = controlled ? !!openProp : openState;
9117
- const openRef = React36__default.useRef(open);
9704
+ const openRef = React37__default.useRef(open);
9118
9705
  openRef.current = open;
9119
- const controlledRef = React36__default.useRef(controlled);
9706
+ const controlledRef = React37__default.useRef(controlled);
9120
9707
  controlledRef.current = controlled;
9121
- const onOpenChangeRef = React36__default.useRef(onOpenChange);
9708
+ const onOpenChangeRef = React37__default.useRef(onOpenChange);
9122
9709
  onOpenChangeRef.current = onOpenChange;
9123
- const setOpen = React36__default.useCallback((next) => {
9710
+ const setOpen = React37__default.useCallback((next) => {
9124
9711
  const value = typeof next === "function" ? next(openRef.current) : next;
9125
9712
  if (value === openRef.current) return;
9126
9713
  if (!controlledRef.current) setOpenState(value);
@@ -9128,7 +9715,7 @@ function Popover({
9128
9715
  }, []);
9129
9716
  const toggle = () => setOpen((o) => !o);
9130
9717
  const RD = { createPortal: typeof createPortal === "function" ? createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
9131
- const place = React36__default.useCallback(() => {
9718
+ const place = React37__default.useCallback(() => {
9132
9719
  const t = wrapRef.current;
9133
9720
  if (!t) return;
9134
9721
  const r = t.getBoundingClientRect();
@@ -9165,7 +9752,7 @@ function Popover({
9165
9752
  arrow = { top: Math.min(Math.max(cy - top - 5.5, 8), ph - 18), [onRight ? "left" : "right"]: -6 };
9166
9753
  setPos({ top, left, width: w, flip: false, arrow });
9167
9754
  }, [placement, align, width]);
9168
- React36__default.useEffect(() => {
9755
+ React37__default.useEffect(() => {
9169
9756
  if (!open) return;
9170
9757
  place();
9171
9758
  const onMove = () => place();
@@ -9188,7 +9775,7 @@ function Popover({
9188
9775
  document.removeEventListener("keydown", onKey);
9189
9776
  };
9190
9777
  }, [open, place]);
9191
- React36__default.useEffect(() => {
9778
+ React37__default.useEffect(() => {
9192
9779
  if (open) {
9193
9780
  setRender(true);
9194
9781
  return;
@@ -9196,12 +9783,12 @@ function Popover({
9196
9783
  const t = setTimeout(() => setRender(false), 170);
9197
9784
  return () => clearTimeout(t);
9198
9785
  }, [open]);
9199
- React36__default.useEffect(() => {
9786
+ React37__default.useEffect(() => {
9200
9787
  if (render && open) place();
9201
9788
  }, [render, place]);
9202
- const restoreRef = React36__default.useRef(null);
9203
- const needFocusRef = React36__default.useRef(false);
9204
- React36__default.useEffect(() => {
9789
+ const restoreRef = React37__default.useRef(null);
9790
+ const needFocusRef = React37__default.useRef(false);
9791
+ React37__default.useEffect(() => {
9205
9792
  if (open) {
9206
9793
  restoreRef.current = document.activeElement;
9207
9794
  needFocusRef.current = true;
@@ -9236,7 +9823,7 @@ function Popover({
9236
9823
  ]
9237
9824
  }
9238
9825
  ) : null;
9239
- const triggerEl = React36__default.isValidElement(trigger) ? React36__default.cloneElement(trigger, {
9826
+ const triggerEl = React37__default.isValidElement(trigger) ? React37__default.cloneElement(trigger, {
9240
9827
  onClick: (e) => {
9241
9828
  trigger.props.onClick?.(e);
9242
9829
  toggle();
@@ -9279,7 +9866,7 @@ function Progress({
9279
9866
  className = "",
9280
9867
  ...rest
9281
9868
  }) {
9282
- const labelId = React36__default.useId();
9869
+ const labelId = React37__default.useId();
9283
9870
  const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...restProps } = rest;
9284
9871
  const __twcStyles = useScopedStyles("twc-progress-styles", `
9285
9872
  .twc-progress-wrap { display: flex; flex-direction: column; gap: 6px; font-family: var(--font-sans); }
@@ -9402,7 +9989,7 @@ function Radio({
9402
9989
  .twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
9403
9990
  .twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
9404
9991
  `);
9405
- const autoId = React36__default.useId();
9992
+ const autoId = React37__default.useId();
9406
9993
  const fieldId = id || autoId;
9407
9994
  const errId = `${fieldId}-error`;
9408
9995
  const invalid = Boolean(error);
@@ -9472,13 +10059,13 @@ function RadioGroup({
9472
10059
  ...rest
9473
10060
  }) {
9474
10061
  const __twcStyles = useScopedStyles("twc-radio-group-styles", RADIO_GROUP_CSS);
9475
- const autoId = React36__default.useId();
10062
+ const autoId = React37__default.useId();
9476
10063
  const fieldId = id || autoId;
9477
10064
  const labelId = `${fieldId}-label`;
9478
10065
  const descId = `${fieldId}-desc`;
9479
10066
  const groupName = name || `${fieldId}-name`;
9480
10067
  const invalid = Boolean(error);
9481
- const [internal, setInternal] = React36__default.useState(defaultValue);
10068
+ const [internal, setInternal] = React37__default.useState(defaultValue);
9482
10069
  const current = value !== void 0 ? value : internal;
9483
10070
  const select = (v) => {
9484
10071
  if (value === void 0) setInternal(v);
@@ -9499,10 +10086,10 @@ function RadioGroup({
9499
10086
  tone
9500
10087
  },
9501
10088
  o.value
9502
- )) : React36__default.Children.map(children, (child) => {
9503
- if (!React36__default.isValidElement(child)) return child;
10089
+ )) : React37__default.Children.map(children, (child) => {
10090
+ if (!React37__default.isValidElement(child)) return child;
9504
10091
  const v = child.props.value;
9505
- return React36__default.cloneElement(child, {
10092
+ return React37__default.cloneElement(child, {
9506
10093
  name: child.props.name ?? groupName,
9507
10094
  checked: child.props.checked ?? current === v,
9508
10095
  onChange: child.props.onChange ?? (() => select(v)),
@@ -9582,12 +10169,12 @@ function Rating({
9582
10169
  ...rest
9583
10170
  }) {
9584
10171
  const __twcStyles = useScopedStyles("twc-rating-styles", RATING_CSS);
9585
- const [internal, setInternal] = React36__default.useState(defaultValue);
9586
- const [hover, setHover] = React36__default.useState(0);
10172
+ const [internal, setInternal] = React37__default.useState(defaultValue);
10173
+ const [hover, setHover] = React37__default.useState(0);
9587
10174
  const val = value !== void 0 ? value : internal;
9588
10175
  const shown = hover || val;
9589
10176
  const interactive = !readOnly && !disabled;
9590
- const btnRefs = React36__default.useRef([]);
10177
+ const btnRefs = React37__default.useRef([]);
9591
10178
  const tabStar = Math.min(count, Math.max(1, Math.round(val) || 1));
9592
10179
  const fmt = (v) => format ? format(v) : Number.isInteger(v) ? String(v) : v.toFixed(1);
9593
10180
  if (process.env.NODE_ENV !== "production" && interactive && !Number.isInteger(val)) {
@@ -9774,24 +10361,24 @@ function Sidebar({
9774
10361
  ...rest
9775
10362
  }) {
9776
10363
  const __twcStyles = useScopedStyles("twc-sidebar-styles", SIDEBAR_CSS);
9777
- const navId = React36__default.useId();
9778
- const panelRef = React36__default.useRef(null);
10364
+ const navId = React37__default.useId();
10365
+ const panelRef = React37__default.useRef(null);
9779
10366
  const renderPortal = usePortal();
9780
- const [internal, setInternal] = React36__default.useState(defaultCollapsed);
10367
+ const [internal, setInternal] = React37__default.useState(defaultCollapsed);
9781
10368
  const collapsed = collapsedProp !== void 0 ? collapsedProp : internal;
9782
10369
  const toggle = () => {
9783
10370
  const next = !collapsed;
9784
10371
  if (collapsedProp === void 0) setInternal(next);
9785
10372
  onCollapsedChange?.(next);
9786
10373
  };
9787
- const [openInternal, setOpenInternal] = React36__default.useState(defaultOpen);
10374
+ const [openInternal, setOpenInternal] = React37__default.useState(defaultOpen);
9788
10375
  const open = openProp !== void 0 ? openProp : openInternal;
9789
10376
  const setOpen = (next) => {
9790
10377
  if (openProp === void 0) setOpenInternal(next);
9791
10378
  onOpenChange?.(next);
9792
10379
  };
9793
- const [mounted, setMounted] = React36__default.useState(open);
9794
- React36__default.useEffect(() => {
10380
+ const [mounted, setMounted] = React37__default.useState(open);
10381
+ React37__default.useEffect(() => {
9795
10382
  if (!overlay) return void 0;
9796
10383
  if (open) {
9797
10384
  setMounted(true);
@@ -9800,7 +10387,7 @@ function Sidebar({
9800
10387
  const t = setTimeout(() => setMounted(false), 170);
9801
10388
  return () => clearTimeout(t);
9802
10389
  }, [overlay, open]);
9803
- React36__default.useEffect(() => {
10390
+ React37__default.useEffect(() => {
9804
10391
  if (!overlay || !open) return void 0;
9805
10392
  const prev = document.body.style.overflow;
9806
10393
  document.body.style.overflow = "hidden";
@@ -9809,7 +10396,7 @@ function Sidebar({
9809
10396
  };
9810
10397
  }, [overlay, open]);
9811
10398
  useFocusTrap(panelRef, overlay && open && mounted);
9812
- React36__default.useEffect(() => {
10399
+ React37__default.useEffect(() => {
9813
10400
  if (!overlay || !open) return void 0;
9814
10401
  const onKey = (e) => {
9815
10402
  if (e.key === "Escape") {
@@ -9861,7 +10448,7 @@ function Sidebar({
9861
10448
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
9862
10449
  __twcStyles,
9863
10450
  brand ? /* @__PURE__ */ jsx("div", { className: "twc-sidebar__head", children: /* @__PURE__ */ jsx("span", { className: "twc-sidebar__brand", children: brand }) }) : null,
9864
- /* @__PURE__ */ jsx("nav", { id: navId, className: "twc-sidebar__nav", "aria-label": navLabel, children: groups.map((g, gi) => /* @__PURE__ */ jsxs(React36__default.Fragment, { children: [
10451
+ /* @__PURE__ */ jsx("nav", { id: navId, className: "twc-sidebar__nav", "aria-label": navLabel, children: groups.map((g, gi) => /* @__PURE__ */ jsxs(React37__default.Fragment, { children: [
9865
10452
  g.section != null ? /* @__PURE__ */ jsx("div", { className: "twc-sidebar__section", id: g.sid, children: g.section }) : null,
9866
10453
  /* @__PURE__ */ jsx("ul", { className: "twc-sidebar__list", ...g.section != null ? { "aria-labelledby": g.sid } : {}, children: g.entries.map(({ it, i }) => /* @__PURE__ */ jsx("li", { children: renderItem(it) }, i)) })
9867
10454
  ] }, gi)) }),
@@ -10030,10 +10617,10 @@ function Slider({
10030
10617
  return Math.min(max, Math.max(min, Math.round(stepped * 1e6) / 1e6));
10031
10618
  };
10032
10619
  const __twcStyles = useScopedStyles("twc-slider-styles", SLIDER_CSS);
10033
- const autoId = React36__default.useId();
10620
+ const autoId = React37__default.useId();
10034
10621
  const fieldId = id || autoId;
10035
10622
  const isRange = range || Array.isArray(value) || Array.isArray(defaultValue);
10036
- const [internal, setInternal] = React36__default.useState(() => {
10623
+ const [internal, setInternal] = React37__default.useState(() => {
10037
10624
  if (isRange) {
10038
10625
  const dv = Array.isArray(defaultValue) ? defaultValue : [min, max];
10039
10626
  return [clampSnap(dv[0]), clampSnap(dv[1])];
@@ -10043,8 +10630,8 @@ function Slider({
10043
10630
  const rawVal = value !== void 0 ? value : internal;
10044
10631
  const clampedVals = (isRange ? [Number(rawVal[0]), Number(rawVal[1])] : [Number(rawVal)]).map((v) => Math.min(max, Math.max(min, Number.isFinite(v) ? v : min)));
10045
10632
  const indices = isRange ? [0, 1] : [0];
10046
- const trackRef = React36__default.useRef(null);
10047
- const [dragging, setDragging] = React36__default.useState(false);
10633
+ const trackRef = React37__default.useRef(null);
10634
+ const [dragging, setDragging] = React37__default.useState(false);
10048
10635
  const fmt = (v) => formatValue ? formatValue(v) : v.toFixed(decimals);
10049
10636
  const valueTextFor = (v) => {
10050
10637
  if (getAriaValueText) return getAriaValueText(v);
@@ -10075,8 +10662,8 @@ function Slider({
10075
10662
  const ratio = Math.min(1, Math.max(0, (clientX - r.left) / r.width));
10076
10663
  return clampSnap(min + ratio * (max - min));
10077
10664
  };
10078
- const dragCleanupRef = React36__default.useRef(null);
10079
- React36__default.useEffect(() => () => dragCleanupRef.current?.(), []);
10665
+ const dragCleanupRef = React37__default.useRef(null);
10666
+ React37__default.useEffect(() => () => dragCleanupRef.current?.(), []);
10080
10667
  function onPointerDown(e) {
10081
10668
  if (disabled) return;
10082
10669
  e.preventDefault();
@@ -10307,7 +10894,7 @@ function Stepper({
10307
10894
  ...rest
10308
10895
  }) {
10309
10896
  const __twcStyles = useScopedStyles("twc-stepper-styles", STEPPER_CSS);
10310
- const [activeInternal, setActiveInternal] = React36__default.useState(defaultActive);
10897
+ const [activeInternal, setActiveInternal] = React37__default.useState(defaultActive);
10311
10898
  const active = activeProp !== void 0 ? activeProp : activeInternal;
10312
10899
  const handleStep = (i) => {
10313
10900
  if (activeProp === void 0) setActiveInternal(i);
@@ -10439,7 +11026,7 @@ function Switch({
10439
11026
  .twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
10440
11027
  .twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
10441
11028
  `);
10442
- const autoId = React36__default.useId();
11029
+ const autoId = React37__default.useId();
10443
11030
  const fieldId = id || autoId;
10444
11031
  const errId = `${fieldId}-error`;
10445
11032
  const invalid = Boolean(error);
@@ -10542,14 +11129,14 @@ function Table({
10542
11129
  ...rest
10543
11130
  }) {
10544
11131
  const __twcStyles = useScopedStyles("twc-table-styles", TABLE_CSS);
10545
- const cols = React36__default.useMemo(
11132
+ const cols = React37__default.useMemo(
10546
11133
  () => (columns || []).map((c) => ({ ...c, header: c.headerName, render: c.renderCell })),
10547
11134
  [columns]
10548
11135
  );
10549
11136
  const dataRows = rowsProp || [];
10550
- const [internalSort, setInternalSort] = React36__default.useState(defaultSort || { field: null, dir: "asc" });
11137
+ const [internalSort, setInternalSort] = React37__default.useState(defaultSort || { field: null, dir: "asc" });
10551
11138
  const sort = (sortProp !== void 0 ? sortProp : internalSort) || { field: null, dir: "asc" };
10552
- const rows = React36__default.useMemo(() => {
11139
+ const rows = React37__default.useMemo(() => {
10553
11140
  if (!sortable || !sort.field) return dataRows;
10554
11141
  const col = cols.find((c) => c.field === sort.field);
10555
11142
  if (!col) return dataRows;
@@ -10696,15 +11283,15 @@ function Tabs({
10696
11283
  }) {
10697
11284
  const vertical = orientation === "vertical";
10698
11285
  const __twcStyles = useScopedStyles("twc-tabs-styles", TABS_CSS);
10699
- const [internal, setInternal] = React36__default.useState(defaultValue ?? items[0]?.value);
11286
+ const [internal, setInternal] = React37__default.useState(defaultValue ?? items[0]?.value);
10700
11287
  const active = value ?? internal;
10701
- const listRef = React36__default.useRef(null);
10702
- const [ind, setInd] = React36__default.useState({ left: 0, width: 0, top: 0, height: 0 });
10703
- const baseId = React36__default.useId();
11288
+ const listRef = React37__default.useRef(null);
11289
+ const [ind, setInd] = React37__default.useState({ left: 0, width: 0, top: 0, height: 0 });
11290
+ const baseId = React37__default.useId();
10704
11291
  const tabIdAt = (i) => `${baseId}-tab-${i}`;
10705
11292
  const panelId = `${baseId}-panel`;
10706
11293
  const activeIndex = items.findIndex((it) => it.value === active);
10707
- const updateIndicator = React36__default.useCallback(() => {
11294
+ const updateIndicator = React37__default.useCallback(() => {
10708
11295
  const list = listRef.current;
10709
11296
  if (!list) return;
10710
11297
  const el = list.querySelector('[data-active="true"]');
@@ -10713,10 +11300,10 @@ function Tabs({
10713
11300
  if (!vertical) el.scrollIntoView?.({ inline: "nearest", block: "nearest" });
10714
11301
  }
10715
11302
  }, [vertical]);
10716
- React36__default.useEffect(() => {
11303
+ React37__default.useEffect(() => {
10717
11304
  updateIndicator();
10718
11305
  }, [active, updateIndicator, items, orientation]);
10719
- React36__default.useEffect(() => {
11306
+ React37__default.useEffect(() => {
10720
11307
  const r = () => updateIndicator();
10721
11308
  window.addEventListener("resize", r);
10722
11309
  if (typeof document !== "undefined" && document.fonts && document.fonts.ready) {
@@ -10861,7 +11448,7 @@ function Tag({
10861
11448
  }, "aria-label": _removeLabel, type: "button", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
10862
11449
  ] });
10863
11450
  }
10864
- var useIso = typeof document !== "undefined" ? React36__default.useLayoutEffect : React36__default.useEffect;
11451
+ var useIso = typeof document !== "undefined" ? React37__default.useLayoutEffect : React37__default.useEffect;
10865
11452
  var TEXTAREA_CSS = `
10866
11453
  .twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
10867
11454
  .twc-field__label { font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--color-text); display: flex; gap: 4px; align-items: center; }
@@ -10897,7 +11484,7 @@ var TEXTAREA_CSS = `
10897
11484
  .twc-field__count { margin-inline-start: auto; font-size: var(--text-xs); color: var(--color-text-muted); font-variant-numeric: tabular-nums; flex: none; }
10898
11485
  .twc-field__count[data-danger="true"] { color: var(--color-danger-subtle-fg); }
10899
11486
  `;
10900
- var Textarea = React36__default.forwardRef(function Textarea2({
11487
+ var Textarea = React37__default.forwardRef(function Textarea2({
10901
11488
  label,
10902
11489
  hint,
10903
11490
  error,
@@ -10915,19 +11502,19 @@ var Textarea = React36__default.forwardRef(function Textarea2({
10915
11502
  ...rest
10916
11503
  }, ref) {
10917
11504
  const __twcStyles = useScopedStyles("twc-textarea-styles", TEXTAREA_CSS);
10918
- const autoId = React36__default.useId();
11505
+ const autoId = React37__default.useId();
10919
11506
  const fieldId = id || autoId;
10920
11507
  const descId = `${fieldId}-desc`;
10921
11508
  const countId = `${fieldId}-count`;
10922
11509
  const invalid = Boolean(error);
10923
- const innerRef = React36__default.useRef(null);
11510
+ const innerRef = React37__default.useRef(null);
10924
11511
  const setRef = (el) => {
10925
11512
  innerRef.current = el;
10926
11513
  if (typeof ref === "function") ref(el);
10927
11514
  else if (ref) ref.current = el;
10928
11515
  };
10929
11516
  const countControlled = rest.value !== void 0;
10930
- const [len2, setLen] = React36__default.useState(() => String(rest.defaultValue ?? "").length);
11517
+ const [len2, setLen] = React37__default.useState(() => String(rest.defaultValue ?? "").length);
10931
11518
  const count = countControlled ? String(rest.value ?? "").length : len2;
10932
11519
  const max = rest.maxLength;
10933
11520
  const showCounter = showCount && max != null;
@@ -11105,19 +11692,19 @@ function Toast({
11105
11692
  }) {
11106
11693
  const resolvedTone = tone === "neutral" ? "default" : tone;
11107
11694
  const __twcStyles = useScopedStyles("twc-toast-styles", TOAST_CSS);
11108
- const onCloseRef = React36__default.useRef(onClose);
11109
- React36__default.useEffect(() => {
11695
+ const onCloseRef = React37__default.useRef(onClose);
11696
+ React37__default.useEffect(() => {
11110
11697
  onCloseRef.current = onClose;
11111
11698
  }, [onClose]);
11112
- const timer = React36__default.useRef();
11113
- const stop = React36__default.useCallback(() => clearTimeout(timer.current), []);
11114
- const start = React36__default.useCallback(() => {
11699
+ const timer = React37__default.useRef();
11700
+ const stop = React37__default.useCallback(() => clearTimeout(timer.current), []);
11701
+ const start = React37__default.useCallback(() => {
11115
11702
  stop();
11116
11703
  if (duration && duration !== Infinity && onCloseRef.current) {
11117
11704
  timer.current = setTimeout(() => onCloseRef.current && onCloseRef.current(), duration);
11118
11705
  }
11119
11706
  }, [duration, stop]);
11120
- React36__default.useEffect(() => {
11707
+ React37__default.useEffect(() => {
11121
11708
  start();
11122
11709
  return stop;
11123
11710
  }, [start, stop]);
@@ -11162,30 +11749,30 @@ function Toast({
11162
11749
  }
11163
11750
  function ToastViewport({ children, limit, className = "", ...rest }) {
11164
11751
  const __twcStyles = useScopedStyles("twc-toast-styles", TOAST_CSS);
11165
- const shown = limit && limit > 0 ? React36__default.Children.toArray(children).slice(-limit) : children;
11752
+ const shown = limit && limit > 0 ? React37__default.Children.toArray(children).slice(-limit) : children;
11166
11753
  return /* @__PURE__ */ jsxs("div", { className: `twc-toast-viewport ${className}`, role: "region", "aria-label": "Notifications", ...rest, children: [
11167
11754
  __twcStyles,
11168
11755
  shown
11169
11756
  ] });
11170
11757
  }
11171
- var ToastContext = React36__default.createContext(null);
11758
+ var ToastContext = React37__default.createContext(null);
11172
11759
  function useToast() {
11173
- const ctx = React36__default.useContext(ToastContext);
11760
+ const ctx = React37__default.useContext(ToastContext);
11174
11761
  if (!ctx) throw new Error("useToast must be used within a <ToastProvider>.");
11175
11762
  return ctx;
11176
11763
  }
11177
11764
  function ToastProvider({ children, limit = 4, duration = 4500, ...viewportProps }) {
11178
- const [toasts, setToasts] = React36__default.useState([]);
11179
- const idRef = React36__default.useRef(0);
11180
- const limitRef = React36__default.useRef(limit);
11181
- React36__default.useEffect(() => {
11765
+ const [toasts, setToasts] = React37__default.useState([]);
11766
+ const idRef = React37__default.useRef(0);
11767
+ const limitRef = React37__default.useRef(limit);
11768
+ React37__default.useEffect(() => {
11182
11769
  limitRef.current = limit;
11183
11770
  }, [limit]);
11184
- const dismiss = React36__default.useCallback((id) => {
11771
+ const dismiss = React37__default.useCallback((id) => {
11185
11772
  setToasts((s) => s.filter((t) => t.id !== id));
11186
11773
  }, []);
11187
- const clear = React36__default.useCallback(() => setToasts([]), []);
11188
- const api = React36__default.useMemo(() => {
11774
+ const clear = React37__default.useCallback(() => setToasts([]), []);
11775
+ const api = React37__default.useMemo(() => {
11189
11776
  const push = (opts) => {
11190
11777
  const id = idRef.current += 1;
11191
11778
  const next = typeof opts === "string" ? { title: opts } : opts && typeof opts === "object" ? opts : {};
@@ -11206,7 +11793,7 @@ function ToastProvider({ children, limit = 4, duration = 4500, ...viewportProps
11206
11793
  toast.show = withTone("default");
11207
11794
  return { toast, dismiss, clear };
11208
11795
  }, [dismiss, clear]);
11209
- const value = React36__default.useMemo(() => ({ ...api, toasts }), [api, toasts]);
11796
+ const value = React37__default.useMemo(() => ({ ...api, toasts }), [api, toasts]);
11210
11797
  return /* @__PURE__ */ jsxs(ToastContext.Provider, { value, children: [
11211
11798
  children,
11212
11799
  /* @__PURE__ */ jsx(ToastViewport, { limit, ...viewportProps, children: toasts.map((t) => /* @__PURE__ */ jsx(
@@ -11314,13 +11901,13 @@ function TreeView({
11314
11901
  }) {
11315
11902
  const nodes = items;
11316
11903
  const __twcStyles = useScopedStyles("twc-tree-styles", TREE_CSS);
11317
- const [expInternal, setExpInternal] = React36__default.useState(() => new Set(defaultExpanded));
11904
+ const [expInternal, setExpInternal] = React37__default.useState(() => new Set(defaultExpanded));
11318
11905
  const expanded = expandedProp !== void 0 ? new Set(expandedProp) : expInternal;
11319
- const [selInternal, setSelInternal] = React36__default.useState(defaultSelectedId);
11906
+ const [selInternal, setSelInternal] = React37__default.useState(defaultSelectedId);
11320
11907
  const selectedId = selectedProp !== void 0 ? selectedProp : selInternal;
11321
- const [focusId, setFocusId] = React36__default.useState(null);
11322
- const rowRefs = React36__default.useRef(/* @__PURE__ */ new Map());
11323
- const taRef = React36__default.useRef({ str: "", t: 0 });
11908
+ const [focusId, setFocusId] = React37__default.useState(null);
11909
+ const rowRefs = React37__default.useRef(/* @__PURE__ */ new Map());
11910
+ const taRef = React37__default.useRef({ str: "", t: 0 });
11324
11911
  const toggle = (id) => {
11325
11912
  const n = new Set(expanded);
11326
11913
  n.has(id) ? n.delete(id) : n.add(id);
@@ -11452,7 +12039,7 @@ function AppShell({
11452
12039
  ...rest
11453
12040
  }) {
11454
12041
  const __twcStyles = useScopedStyles("twc-shell-styles", SHELL_CSS);
11455
- const wiredSidebar = React36__default.isValidElement(sidebar) && (sidebarOpen !== void 0 || onSidebarOpenChange !== void 0) ? React36__default.cloneElement(sidebar, {
12042
+ const wiredSidebar = React37__default.isValidElement(sidebar) && (sidebarOpen !== void 0 || onSidebarOpenChange !== void 0) ? React37__default.cloneElement(sidebar, {
11456
12043
  overlay: sidebar.props.overlay !== void 0 ? sidebar.props.overlay : true,
11457
12044
  open: sidebar.props.open !== void 0 ? sidebar.props.open : sidebarOpen,
11458
12045
  onOpenChange: sidebar.props.onOpenChange !== void 0 ? sidebar.props.onOpenChange : onSidebarOpenChange
@@ -11487,7 +12074,7 @@ function safeHref6(url) {
11487
12074
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11488
12075
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11489
12076
  }
11490
- var Box = React36__default.forwardRef(function Box2({
12077
+ var Box = React37__default.forwardRef(function Box2({
11491
12078
  as: Tag2 = "div",
11492
12079
  p,
11493
12080
  px,
@@ -11507,11 +12094,13 @@ var Box = React36__default.forwardRef(function Box2({
11507
12094
  border = false,
11508
12095
  radius,
11509
12096
  shadow,
12097
+ sx,
11510
12098
  className = "",
11511
12099
  style,
11512
12100
  children,
11513
12101
  ...rest
11514
12102
  }, ref) {
12103
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11515
12104
  const s = {
11516
12105
  paddingTop: sp(pt ?? py ?? p),
11517
12106
  paddingRight: sp(pr ?? px ?? p),
@@ -11525,10 +12114,14 @@ var Box = React36__default.forwardRef(function Box2({
11525
12114
  border: border ? "var(--border-thin, 1px) solid var(--color-border)" : void 0,
11526
12115
  borderRadius: radius ? `var(--radius-${radius})` : void 0,
11527
12116
  boxShadow: shadow ? `var(--shadow-${shadow})` : void 0,
11528
- ...style
12117
+ ...style,
12118
+ ...flatStyle
11529
12119
  };
11530
12120
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref6(rest.href);
11531
- return /* @__PURE__ */ jsx(Tag2, { ref, className: `twc-box ${className}`.trim(), style: s, ...rest, children });
12121
+ return /* @__PURE__ */ jsxs(Tag2, { ref, className: `twc-box ${className}`.trim(), style: s, "data-twc-sx": sxAttr, ...rest, children: [
12122
+ styleNode,
12123
+ children
12124
+ ] });
11532
12125
  });
11533
12126
  Box.displayName = "Box";
11534
12127
  var SIZES = { sm: 640, md: 768, lg: 1024, xl: 1280, full: "100%" };
@@ -11537,31 +12130,38 @@ function safeHref7(url) {
11537
12130
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11538
12131
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11539
12132
  }
11540
- var Container = React36__default.forwardRef(function Container2({
12133
+ var Container = React37__default.forwardRef(function Container2({
11541
12134
  as: Tag2 = "div",
11542
12135
  size = "lg",
11543
12136
  padded = true,
12137
+ sx,
11544
12138
  className = "",
11545
12139
  style,
11546
12140
  children,
11547
12141
  ...rest
11548
12142
  }, ref) {
12143
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11549
12144
  const max = SIZES[size] ?? size;
11550
12145
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref7(rest.href);
11551
- return /* @__PURE__ */ jsx(
12146
+ return /* @__PURE__ */ jsxs(
11552
12147
  Tag2,
11553
12148
  {
11554
12149
  ref,
11555
12150
  className: `twc-container ${className}`.trim(),
12151
+ "data-twc-sx": sxAttr,
11556
12152
  style: {
11557
12153
  width: "100%",
11558
12154
  maxWidth: typeof max === "number" ? `${max}px` : max,
11559
12155
  marginInline: "auto",
11560
12156
  paddingInline: padded ? "var(--space-5)" : void 0,
11561
- ...style
12157
+ ...style,
12158
+ ...flatStyle
11562
12159
  },
11563
12160
  ...rest,
11564
- children
12161
+ children: [
12162
+ styleNode,
12163
+ children
12164
+ ]
11565
12165
  }
11566
12166
  );
11567
12167
  });
@@ -11580,7 +12180,7 @@ function safeHref8(url) {
11580
12180
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11581
12181
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11582
12182
  }
11583
- var Grid = React36__default.forwardRef(function Grid2({
12183
+ var Grid = React37__default.forwardRef(function Grid2({
11584
12184
  as: Tag2 = "div",
11585
12185
  columns,
11586
12186
  minChildWidth,
@@ -11591,13 +12191,15 @@ var Grid = React36__default.forwardRef(function Grid2({
11591
12191
  justify,
11592
12192
  alignContent,
11593
12193
  justifyContent,
12194
+ sx,
11594
12195
  className = "",
11595
12196
  style,
11596
12197
  children,
11597
12198
  ...rest
11598
12199
  }, ref) {
12200
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11599
12201
  const responsive = columns != null && typeof columns === "object";
11600
- const uid = React36__default.useId();
12202
+ const uid = React37__default.useId();
11601
12203
  const gridId = responsive ? `g${uid.replace(/[^a-zA-Z0-9]/g, "")}` : null;
11602
12204
  let css = "";
11603
12205
  if (responsive) {
@@ -11618,6 +12220,7 @@ var Grid = React36__default.forwardRef(function Grid2({
11618
12220
  ref,
11619
12221
  className: `twc-grid ${className}`.trim(),
11620
12222
  "data-twc-grid-id": gridId || void 0,
12223
+ "data-twc-sx": sxAttr,
11621
12224
  style: {
11622
12225
  display: "grid",
11623
12226
  gridTemplateColumns: templateColumns,
@@ -11627,11 +12230,13 @@ var Grid = React36__default.forwardRef(function Grid2({
11627
12230
  justifyItems: justify,
11628
12231
  alignContent,
11629
12232
  justifyContent,
11630
- ...style
12233
+ ...style,
12234
+ ...flatStyle
11631
12235
  },
11632
12236
  ...rest,
11633
12237
  children: [
11634
12238
  responsive ? __twcStyles : null,
12239
+ styleNode,
11635
12240
  children
11636
12241
  ]
11637
12242
  }
@@ -11648,7 +12253,7 @@ function safeHref9(url) {
11648
12253
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11649
12254
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11650
12255
  }
11651
- var Stack = React36__default.forwardRef(function Stack2({
12256
+ var Stack = React37__default.forwardRef(function Stack2({
11652
12257
  as: Tag2 = "div",
11653
12258
  direction = "column",
11654
12259
  gap = 4,
@@ -11664,18 +12269,21 @@ var Stack = React36__default.forwardRef(function Stack2({
11664
12269
  pb,
11665
12270
  pl,
11666
12271
  divider,
12272
+ sx,
11667
12273
  className = "",
11668
12274
  style,
11669
12275
  children,
11670
12276
  ...rest
11671
12277
  }, ref) {
12278
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11672
12279
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref9(rest.href);
11673
- const kids = divider != null ? React36__default.Children.toArray(children).flatMap((child, i, arr) => i < arr.length - 1 ? [child, /* @__PURE__ */ jsx(React36__default.Fragment, { children: divider }, `twc-stack-div-${i}`)] : [child]) : children;
11674
- return /* @__PURE__ */ jsx(
12280
+ const kids = divider != null ? React37__default.Children.toArray(children).flatMap((child, i, arr) => i < arr.length - 1 ? [child, /* @__PURE__ */ jsx(React37__default.Fragment, { children: divider }, `twc-stack-div-${i}`)] : [child]) : children;
12281
+ return /* @__PURE__ */ jsxs(
11675
12282
  Tag2,
11676
12283
  {
11677
12284
  ref,
11678
12285
  className: `twc-stack ${className}`.trim(),
12286
+ "data-twc-sx": sxAttr,
11679
12287
  style: {
11680
12288
  display: inline ? "inline-flex" : "flex",
11681
12289
  flexDirection: direction,
@@ -11688,10 +12296,14 @@ var Stack = React36__default.forwardRef(function Stack2({
11688
12296
  paddingBottom: space2(pb ?? py ?? p),
11689
12297
  paddingLeft: space2(pl ?? px ?? p),
11690
12298
  minWidth: 0,
11691
- ...style
12299
+ ...style,
12300
+ ...flatStyle
11692
12301
  },
11693
12302
  ...rest,
11694
- children: kids
12303
+ children: [
12304
+ styleNode,
12305
+ kids
12306
+ ]
11695
12307
  }
11696
12308
  );
11697
12309
  });
@@ -11737,10 +12349,10 @@ function Code({
11737
12349
  const __twcStyles = useScopedStyles("twc-code-styles", CODE_CSS);
11738
12350
  const Tag2 = as ?? (block ? "pre" : "code");
11739
12351
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref10(rest.href);
11740
- const rootRef = React36__default.useRef(null);
11741
- const [copied, setCopied] = React36__default.useState(false);
11742
- const timerRef = React36__default.useRef(null);
11743
- React36__default.useEffect(() => () => clearTimeout(timerRef.current), []);
12352
+ const rootRef = React37__default.useRef(null);
12353
+ const [copied, setCopied] = React37__default.useState(false);
12354
+ const timerRef = React37__default.useRef(null);
12355
+ React37__default.useEffect(() => () => clearTimeout(timerRef.current), []);
11744
12356
  const doCopy = () => {
11745
12357
  if (typeof navigator === "undefined" || !navigator.clipboard) return;
11746
12358
  const text = typeof children === "string" ? children : rootRef.current?.textContent ?? "";
@@ -11766,7 +12378,7 @@ function safeHref11(url) {
11766
12378
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11767
12379
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11768
12380
  }
11769
- var Heading = React36__default.forwardRef(function Heading2({
12381
+ var Heading = React37__default.forwardRef(function Heading2({
11770
12382
  as,
11771
12383
  level = 2,
11772
12384
  size,
@@ -11774,19 +12386,22 @@ var Heading = React36__default.forwardRef(function Heading2({
11774
12386
  align,
11775
12387
  truncate,
11776
12388
  lineClamp,
12389
+ sx,
11777
12390
  className = "",
11778
12391
  style,
11779
12392
  children,
11780
12393
  ...rest
11781
12394
  }, ref) {
12395
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11782
12396
  const Tag2 = as || `h${level}`;
11783
12397
  const sz = size || (display ? "display" : LEVEL_SIZE[level]) || "2xl";
11784
12398
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref11(rest.href);
11785
- return /* @__PURE__ */ jsx(
12399
+ return /* @__PURE__ */ jsxs(
11786
12400
  Tag2,
11787
12401
  {
11788
12402
  ref,
11789
12403
  className: `twc-heading ${className}`.trim(),
12404
+ "data-twc-sx": sxAttr,
11790
12405
  style: {
11791
12406
  margin: 0,
11792
12407
  fontFamily: "var(--font-sans)",
@@ -11797,10 +12412,14 @@ var Heading = React36__default.forwardRef(function Heading2({
11797
12412
  fontSize: `var(--text-${sz})`,
11798
12413
  textAlign: align,
11799
12414
  ...lineClamp != null ? { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: lineClamp, overflow: "hidden" } : truncate ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 } : null,
11800
- ...style
12415
+ ...style,
12416
+ ...flatStyle
11801
12417
  },
11802
12418
  ...rest,
11803
- children
12419
+ children: [
12420
+ styleNode,
12421
+ children
12422
+ ]
11804
12423
  }
11805
12424
  );
11806
12425
  });
@@ -11825,7 +12444,7 @@ function safeHref12(url) {
11825
12444
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11826
12445
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11827
12446
  }
11828
- var Text = React36__default.forwardRef(function Text2({
12447
+ var Text = React37__default.forwardRef(function Text2({
11829
12448
  as: Tag2 = "p",
11830
12449
  size = "base",
11831
12450
  tone = "default",
@@ -11833,18 +12452,21 @@ var Text = React36__default.forwardRef(function Text2({
11833
12452
  align,
11834
12453
  truncate,
11835
12454
  lineClamp,
12455
+ sx,
11836
12456
  className = "",
11837
12457
  style,
11838
12458
  children,
11839
12459
  ...rest
11840
12460
  }, ref) {
12461
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11841
12462
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref12(rest.href);
11842
12463
  const toneToken = TONE[tone] || TONE.default;
11843
- return /* @__PURE__ */ jsx(
12464
+ return /* @__PURE__ */ jsxs(
11844
12465
  Tag2,
11845
12466
  {
11846
12467
  ref,
11847
12468
  className: `twc-text ${className}`.trim(),
12469
+ "data-twc-sx": sxAttr,
11848
12470
  style: {
11849
12471
  margin: 0,
11850
12472
  fontFamily: "var(--font-sans)",
@@ -11854,54 +12476,58 @@ var Text = React36__default.forwardRef(function Text2({
11854
12476
  fontWeight: weight ? `var(--font-${weight})` : void 0,
11855
12477
  textAlign: align,
11856
12478
  ...lineClamp != null ? { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: lineClamp, overflow: "hidden" } : truncate ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 } : null,
11857
- ...style
12479
+ ...style,
12480
+ ...flatStyle
11858
12481
  },
11859
12482
  ...rest,
11860
- children
12483
+ children: [
12484
+ styleNode,
12485
+ children
12486
+ ]
11861
12487
  }
11862
12488
  );
11863
12489
  });
11864
12490
  Text.displayName = "Text";
11865
12491
  var canUseDOM2 = typeof window !== "undefined" && typeof document !== "undefined";
11866
- var useIsomorphicLayoutEffect = canUseDOM2 ? React36__default.useLayoutEffect : React36__default.useEffect;
12492
+ var useIsomorphicLayoutEffect = canUseDOM2 ? React37__default.useLayoutEffect : React37__default.useEffect;
11867
12493
  function useMounted() {
11868
- const [mounted, setMounted] = React36__default.useState(false);
11869
- React36__default.useEffect(() => {
12494
+ const [mounted, setMounted] = React37__default.useState(false);
12495
+ React37__default.useEffect(() => {
11870
12496
  setMounted(true);
11871
12497
  }, []);
11872
12498
  return mounted;
11873
12499
  }
11874
12500
  function usePrevious(value) {
11875
- const ref = React36__default.useRef(void 0);
11876
- React36__default.useEffect(() => {
12501
+ const ref = React37__default.useRef(void 0);
12502
+ React37__default.useEffect(() => {
11877
12503
  ref.current = value;
11878
12504
  }, [value]);
11879
12505
  return ref.current;
11880
12506
  }
11881
12507
  function useToggle(initial = false) {
11882
- const [on, setOn] = React36__default.useState(initial);
11883
- const toggle = React36__default.useCallback((next) => {
12508
+ const [on, setOn] = React37__default.useState(initial);
12509
+ const toggle = React37__default.useCallback((next) => {
11884
12510
  setOn((prev) => typeof next === "boolean" ? next : !prev);
11885
12511
  }, []);
11886
12512
  return [on, toggle, setOn];
11887
12513
  }
11888
12514
  function useDisclosure(initial = false) {
11889
- const [open, setOpen] = React36__default.useState(initial);
11890
- const onOpen = React36__default.useCallback(() => setOpen(true), []);
11891
- const onClose = React36__default.useCallback(() => setOpen(false), []);
11892
- const onToggle = React36__default.useCallback(() => setOpen((p) => !p), []);
12515
+ const [open, setOpen] = React37__default.useState(initial);
12516
+ const onOpen = React37__default.useCallback(() => setOpen(true), []);
12517
+ const onClose = React37__default.useCallback(() => setOpen(false), []);
12518
+ const onToggle = React37__default.useCallback(() => setOpen((p) => !p), []);
11893
12519
  return { open, onOpen, onClose, onToggle, setOpen };
11894
12520
  }
11895
12521
  function useControllableState({ value, defaultValue, onChange } = {}) {
11896
12522
  const isControlled = value !== void 0;
11897
- const [uncontrolled, setUncontrolled] = React36__default.useState(defaultValue);
12523
+ const [uncontrolled, setUncontrolled] = React37__default.useState(defaultValue);
11898
12524
  const current = isControlled ? value : uncontrolled;
11899
- const ref = React36__default.useRef({ current, isControlled, onChange });
12525
+ const ref = React37__default.useRef({ current, isControlled, onChange });
11900
12526
  useIsomorphicLayoutEffect(() => {
11901
12527
  ref.current = { current, isControlled, onChange };
11902
12528
  });
11903
- const wasControlled = React36__default.useRef(isControlled);
11904
- React36__default.useEffect(() => {
12529
+ const wasControlled = React37__default.useRef(isControlled);
12530
+ React37__default.useEffect(() => {
11905
12531
  if (wasControlled.current !== isControlled) {
11906
12532
  warnOnce(
11907
12533
  "useControllableState:switch",
@@ -11910,7 +12536,7 @@ function useControllableState({ value, defaultValue, onChange } = {}) {
11910
12536
  wasControlled.current = isControlled;
11911
12537
  }
11912
12538
  });
11913
- const setValue = React36__default.useCallback((next) => {
12539
+ const setValue = React37__default.useCallback((next) => {
11914
12540
  const { current: cur, isControlled: ctrl, onChange: cb } = ref.current;
11915
12541
  const resolved = typeof next === "function" ? next(cur) : next;
11916
12542
  if (resolved === cur) return;
@@ -11921,7 +12547,7 @@ function useControllableState({ value, defaultValue, onChange } = {}) {
11921
12547
  }
11922
12548
  function useMediaQuery(query, { defaultValue = false, initializeWithValue = false } = {}) {
11923
12549
  const get = () => canUseDOM2 ? window.matchMedia(query).matches : defaultValue;
11924
- const [matches3, setMatches] = React36__default.useState(initializeWithValue ? get : defaultValue);
12550
+ const [matches3, setMatches] = React37__default.useState(initializeWithValue ? get : defaultValue);
11925
12551
  useIsomorphicLayoutEffect(() => {
11926
12552
  if (!canUseDOM2) return void 0;
11927
12553
  const mql = window.matchMedia(query);
@@ -11937,7 +12563,7 @@ function usePrefersReducedMotion() {
11937
12563
  }
11938
12564
  function useColorScheme({ storageKey = "twico-theme", attribute = "class", element, disableTransitionsOnChange = true } = {}) {
11939
12565
  const getTarget = () => element || (canUseDOM2 ? document.documentElement : null);
11940
- const firstApply = React36__default.useRef(true);
12566
+ const firstApply = React37__default.useRef(true);
11941
12567
  const read = () => {
11942
12568
  if (!canUseDOM2) return "light";
11943
12569
  try {
@@ -11947,8 +12573,8 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
11947
12573
  }
11948
12574
  return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
11949
12575
  };
11950
- const [theme, setThemeState] = React36__default.useState(read);
11951
- const apply = React36__default.useCallback(
12576
+ const [theme, setThemeState] = React37__default.useState(read);
12577
+ const apply = React37__default.useCallback(
11952
12578
  (t) => {
11953
12579
  const target = getTarget();
11954
12580
  if (!target) return;
@@ -11974,11 +12600,11 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
11974
12600
  useIsomorphicLayoutEffect(() => {
11975
12601
  apply(theme);
11976
12602
  }, [theme, apply]);
11977
- const themeRef = React36__default.useRef(theme);
12603
+ const themeRef = React37__default.useRef(theme);
11978
12604
  useIsomorphicLayoutEffect(() => {
11979
12605
  themeRef.current = theme;
11980
12606
  }, [theme]);
11981
- const setTheme = React36__default.useCallback(
12607
+ const setTheme = React37__default.useCallback(
11982
12608
  (t) => {
11983
12609
  setThemeState(t);
11984
12610
  try {
@@ -11989,10 +12615,10 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
11989
12615
  },
11990
12616
  [storageKey]
11991
12617
  );
11992
- const toggle = React36__default.useCallback(() => {
12618
+ const toggle = React37__default.useCallback(() => {
11993
12619
  setTheme(themeRef.current === "dark" ? "light" : "dark");
11994
12620
  }, [setTheme]);
11995
- React36__default.useEffect(() => {
12621
+ React37__default.useEffect(() => {
11996
12622
  if (!canUseDOM2) return void 0;
11997
12623
  const sync = () => setThemeState(read());
11998
12624
  const onStorage = (e) => {
@@ -12008,14 +12634,14 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
12008
12634
  return { theme, setTheme, toggle, isDark: theme === "dark" };
12009
12635
  }
12010
12636
  function useEventListener(eventName, handler, element, options) {
12011
- const saved = React36__default.useRef(handler);
12637
+ const saved = React37__default.useRef(handler);
12012
12638
  useIsomorphicLayoutEffect(() => {
12013
12639
  saved.current = handler;
12014
12640
  }, [handler]);
12015
12641
  const capture = typeof options === "boolean" ? options : options && options.capture;
12016
12642
  const passive = typeof options === "object" && options ? options.passive : void 0;
12017
12643
  const once = typeof options === "object" && options ? options.once : void 0;
12018
- React36__default.useEffect(() => {
12644
+ React37__default.useEffect(() => {
12019
12645
  const target = element && element.current || element || (canUseDOM2 ? window : null);
12020
12646
  if (!target || !target.addEventListener) return void 0;
12021
12647
  const opts = typeof options === "boolean" ? options : { capture, passive, once };
@@ -12025,11 +12651,11 @@ function useEventListener(eventName, handler, element, options) {
12025
12651
  }, [eventName, element, capture, passive, once]);
12026
12652
  }
12027
12653
  function useClickOutside(ref, handler, events = ["mousedown", "touchstart"]) {
12028
- const saved = React36__default.useRef(handler);
12654
+ const saved = React37__default.useRef(handler);
12029
12655
  useIsomorphicLayoutEffect(() => {
12030
12656
  saved.current = handler;
12031
12657
  }, [handler]);
12032
- React36__default.useEffect(() => {
12658
+ React37__default.useEffect(() => {
12033
12659
  if (!canUseDOM2) return void 0;
12034
12660
  const listener = (e) => {
12035
12661
  const el = ref && ref.current;
@@ -12064,8 +12690,8 @@ function useLocalStorage(key, initialValue) {
12064
12690
  return initialValue;
12065
12691
  }
12066
12692
  };
12067
- const [stored, setStored] = React36__default.useState(read);
12068
- const setValue = React36__default.useCallback(
12693
+ const [stored, setStored] = React37__default.useState(read);
12694
+ const setValue = React37__default.useCallback(
12069
12695
  (value) => {
12070
12696
  setStored((prev) => {
12071
12697
  const next = typeof value === "function" ? value(prev) : value;
@@ -12081,8 +12707,8 @@ function useLocalStorage(key, initialValue) {
12081
12707
  return [stored, setValue];
12082
12708
  }
12083
12709
  function useCopyToClipboard(timeout = 1500) {
12084
- const [copied, setCopied] = React36__default.useState(false);
12085
- const copy = React36__default.useCallback(async (text) => {
12710
+ const [copied, setCopied] = React37__default.useState(false);
12711
+ const copy = React37__default.useCallback(async (text) => {
12086
12712
  if (!canUseDOM2 || !navigator.clipboard) {
12087
12713
  setCopied(false);
12088
12714
  return false;
@@ -12096,7 +12722,7 @@ function useCopyToClipboard(timeout = 1500) {
12096
12722
  return false;
12097
12723
  }
12098
12724
  }, []);
12099
- React36__default.useEffect(() => {
12725
+ React37__default.useEffect(() => {
12100
12726
  if (!copied) return void 0;
12101
12727
  const t = setTimeout(() => setCopied(false), timeout);
12102
12728
  return () => clearTimeout(t);
@@ -12104,23 +12730,23 @@ function useCopyToClipboard(timeout = 1500) {
12104
12730
  return { copied, copy };
12105
12731
  }
12106
12732
  function useDebouncedValue(value, delay = 200) {
12107
- const [debounced, setDebounced] = React36__default.useState(value);
12108
- React36__default.useEffect(() => {
12733
+ const [debounced, setDebounced] = React37__default.useState(value);
12734
+ React37__default.useEffect(() => {
12109
12735
  const t = setTimeout(() => setDebounced(value), delay);
12110
12736
  return () => clearTimeout(t);
12111
12737
  }, [value, delay]);
12112
12738
  return debounced;
12113
12739
  }
12114
12740
  function useDebouncedCallback(callback, delay = 200) {
12115
- const saved = React36__default.useRef(callback);
12116
- const timer = React36__default.useRef(null);
12741
+ const saved = React37__default.useRef(callback);
12742
+ const timer = React37__default.useRef(null);
12117
12743
  useIsomorphicLayoutEffect(() => {
12118
12744
  saved.current = callback;
12119
12745
  }, [callback]);
12120
- React36__default.useEffect(() => () => {
12746
+ React37__default.useEffect(() => () => {
12121
12747
  if (timer.current) clearTimeout(timer.current);
12122
12748
  }, []);
12123
- return React36__default.useCallback(
12749
+ return React37__default.useCallback(
12124
12750
  (...args) => {
12125
12751
  if (timer.current) clearTimeout(timer.current);
12126
12752
  timer.current = setTimeout(() => saved.current(...args), delay);
@@ -12129,33 +12755,33 @@ function useDebouncedCallback(callback, delay = 200) {
12129
12755
  );
12130
12756
  }
12131
12757
  function useInterval(callback, delay) {
12132
- const saved = React36__default.useRef(callback);
12758
+ const saved = React37__default.useRef(callback);
12133
12759
  useIsomorphicLayoutEffect(() => {
12134
12760
  saved.current = callback;
12135
12761
  }, [callback]);
12136
- React36__default.useEffect(() => {
12762
+ React37__default.useEffect(() => {
12137
12763
  if (delay == null) return void 0;
12138
12764
  const id = setInterval(() => saved.current(), delay);
12139
12765
  return () => clearInterval(id);
12140
12766
  }, [delay]);
12141
12767
  }
12142
12768
  function useTimeout(callback, delay) {
12143
- const saved = React36__default.useRef(callback);
12769
+ const saved = React37__default.useRef(callback);
12144
12770
  useIsomorphicLayoutEffect(() => {
12145
12771
  saved.current = callback;
12146
12772
  }, [callback]);
12147
- React36__default.useEffect(() => {
12773
+ React37__default.useEffect(() => {
12148
12774
  if (delay == null) return void 0;
12149
12775
  const id = setTimeout(() => saved.current(), delay);
12150
12776
  return () => clearTimeout(id);
12151
12777
  }, [delay]);
12152
12778
  }
12153
12779
  function useWindowSize() {
12154
- const [size, setSize] = React36__default.useState(() => ({
12780
+ const [size, setSize] = React37__default.useState(() => ({
12155
12781
  width: canUseDOM2 ? window.innerWidth : 0,
12156
12782
  height: canUseDOM2 ? window.innerHeight : 0
12157
12783
  }));
12158
- React36__default.useEffect(() => {
12784
+ React37__default.useEffect(() => {
12159
12785
  if (!canUseDOM2) return void 0;
12160
12786
  const onResize = () => setSize({ width: window.innerWidth, height: window.innerHeight });
12161
12787
  onResize();
@@ -12165,8 +12791,8 @@ function useWindowSize() {
12165
12791
  return size;
12166
12792
  }
12167
12793
  function useHover(ref) {
12168
- const [hovered, setHovered] = React36__default.useState(false);
12169
- React36__default.useEffect(() => {
12794
+ const [hovered, setHovered] = React37__default.useState(false);
12795
+ React37__default.useEffect(() => {
12170
12796
  const el = ref && ref.current;
12171
12797
  if (!el) return void 0;
12172
12798
  const on = () => setHovered(true);
@@ -12182,8 +12808,8 @@ function useHover(ref) {
12182
12808
  }
12183
12809
  function useIntersectionObserver(ref, options = {}) {
12184
12810
  const { root = null, rootMargin = "0px", threshold = 0 } = options;
12185
- const [entry, setEntry] = React36__default.useState(null);
12186
- React36__default.useEffect(() => {
12811
+ const [entry, setEntry] = React37__default.useState(null);
12812
+ React37__default.useEffect(() => {
12187
12813
  const el = ref && ref.current;
12188
12814
  if (!canUseDOM2 || !el || typeof IntersectionObserver === "undefined") return void 0;
12189
12815
  const obs = new IntersectionObserver(([e]) => setEntry(e), { root, rootMargin, threshold });
@@ -12193,7 +12819,7 @@ function useIntersectionObserver(ref, options = {}) {
12193
12819
  return entry;
12194
12820
  }
12195
12821
  function useId(prefix = "twc") {
12196
- const raw = React36__default.useId();
12822
+ const raw = React37__default.useId();
12197
12823
  return prefix ? `${prefix}-${raw.replace(/:/g, "")}` : raw;
12198
12824
  }
12199
12825
  var useFocusTrap2 = useFocusTrap;