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.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React36 = require('react');
4
+ var React37 = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var reactDom = require('react-dom');
7
7
 
@@ -23,31 +23,35 @@ function _interopNamespace(e) {
23
23
  return Object.freeze(n);
24
24
  }
25
25
 
26
- var React36__namespace = /*#__PURE__*/_interopNamespace(React36);
26
+ var React37__namespace = /*#__PURE__*/_interopNamespace(React37);
27
27
 
28
28
  // components/TwicoProvider.jsx
29
- var SUPPORTS_STYLE_HOIST = parseInt(String(React36__namespace.version), 10) >= 19;
30
- var NonceContext = React36__namespace.createContext(void 0);
29
+ var SUPPORTS_STYLE_HOIST = parseInt(String(React37__namespace.version), 10) >= 19;
30
+ var NonceContext = React37__namespace.createContext(void 0);
31
31
  function useScopedStyles(id, css) {
32
- const nonce = React36__namespace.useContext(NonceContext);
33
- React36__namespace.useInsertionEffect(() => {
32
+ const nonce = React37__namespace.useContext(NonceContext);
33
+ React37__namespace.useInsertionEffect(() => {
34
34
  if (SUPPORTS_STYLE_HOIST) return;
35
- if (typeof document === "undefined" || document.getElementById(id)) return;
36
- const el = document.createElement("style");
37
- el.id = id;
38
- if (nonce) {
39
- el.setAttribute("nonce", nonce);
40
- el.nonce = nonce;
41
- }
42
- el.textContent = css;
43
- document.head.appendChild(el);
35
+ if (typeof document === "undefined") return;
36
+ if (!css) return;
37
+ let el = document.getElementById(id);
38
+ if (!el) {
39
+ el = document.createElement("style");
40
+ el.id = id;
41
+ if (nonce) {
42
+ el.setAttribute("nonce", nonce);
43
+ el.nonce = nonce;
44
+ }
45
+ document.head.appendChild(el);
46
+ }
47
+ if (el.textContent !== css) el.textContent = css;
44
48
  }, [id, css, nonce]);
45
- return SUPPORTS_STYLE_HOIST ? React36__namespace.createElement("style", { href: id, precedence: "twc-ui", nonce }, css) : null;
49
+ return SUPPORTS_STYLE_HOIST && css ? React37__namespace.createElement("style", { href: id, precedence: "twc-ui", nonce }, css) : null;
46
50
  }
47
51
 
48
52
  // components/TwicoProvider.jsx
49
53
  function TwicoProvider({ nonce, children }) {
50
- return React36__namespace.default.createElement(NonceContext.Provider, { value: nonce }, children);
54
+ return React37__namespace.default.createElement(NonceContext.Provider, { value: nonce }, children);
51
55
  }
52
56
  var GROUPS = { colors: "color", space: "space", radius: "radius", font: "font", shadow: "shadow", motion: "" };
53
57
  function createTheme(partial = {}) {
@@ -67,8 +71,8 @@ function toVars(theme) {
67
71
  return Object.keys(theme).some((k) => k.startsWith("--")) ? theme : createTheme(theme);
68
72
  }
69
73
  function ThemeProvider({ theme, mode = "inline", className = "", style, children, ...rest }) {
70
- const vars = React36__namespace.default.useMemo(() => toVars(theme), [theme]);
71
- const uid = React36__namespace.default.useId();
74
+ const vars = React37__namespace.default.useMemo(() => toVars(theme), [theme]);
75
+ const uid = React37__namespace.default.useId();
72
76
  const scopeId = `twc-theme-${uid.replace(/[^a-zA-Z0-9]/g, "")}`;
73
77
  const css = mode === "stylesheet" ? `[data-twc-theme="${scopeId}"] { ${Object.entries(vars).map(([k, v]) => `${k}: ${v};`).join(" ")} }` : "";
74
78
  const __twcStyles = useScopedStyles(mode === "stylesheet" ? scopeId : "twc-theme-noop", css);
@@ -90,7 +94,7 @@ var FORM_CSS = `
90
94
  .twc-form { display: flex; flex-direction: column; gap: var(--space-4); font-family: var(--font-sans); }
91
95
  .twc-form__fieldset { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: inherit; }
92
96
  `;
93
- var Form = React36__namespace.default.forwardRef(function Form2({
97
+ var Form = React37__namespace.default.forwardRef(function Form2({
94
98
  onSubmit,
95
99
  preventDefault = true,
96
100
  loading = false,
@@ -125,7 +129,7 @@ Form.displayName = "Form";
125
129
  var VH_CSS = `
126
130
  .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; }
127
131
  `;
128
- var VisuallyHidden = React36__namespace.default.forwardRef(function VisuallyHidden2({ as: Tag2 = "span", className = "", children, ...rest }, ref) {
132
+ var VisuallyHidden = React37__namespace.default.forwardRef(function VisuallyHidden2({ as: Tag2 = "span", className = "", children, ...rest }, ref) {
129
133
  const __twcStyles = useScopedStyles("twc-visually-hidden-styles", VH_CSS);
130
134
  return /* @__PURE__ */ jsxRuntime.jsxs(Tag2, { ref, className: `twc-visually-hidden ${className}`.trim(), ...rest, children: [
131
135
  __twcStyles,
@@ -134,10 +138,10 @@ var VisuallyHidden = React36__namespace.default.forwardRef(function VisuallyHidd
134
138
  });
135
139
  VisuallyHidden.displayName = "VisuallyHidden";
136
140
  var canUseDOM = typeof window !== "undefined" && typeof document !== "undefined";
137
- var useIsoLayoutEffect = canUseDOM ? React36__namespace.default.useLayoutEffect : React36__namespace.default.useEffect;
141
+ var useIsoLayoutEffect = canUseDOM ? React37__namespace.default.useLayoutEffect : React37__namespace.default.useEffect;
138
142
  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"])';
139
143
  function useFocusTrap(ref, active = true, { restoreFocus = true, initialFocus } = {}) {
140
- React36__namespace.default.useEffect(() => {
144
+ React37__namespace.default.useEffect(() => {
141
145
  if (!active || !canUseDOM) return void 0;
142
146
  const node = ref.current;
143
147
  if (!node) return void 0;
@@ -148,7 +152,7 @@ function useFocusTrap(ref, active = true, { restoreFocus = true, initialFocus }
148
152
  if (restoreFocus && prevFocused && typeof prevFocused.focus === "function") prevFocused.focus();
149
153
  };
150
154
  }, [active]);
151
- React36__namespace.default.useEffect(() => {
155
+ React37__namespace.default.useEffect(() => {
152
156
  if (!active || !canUseDOM) return void 0;
153
157
  const node = ref.current;
154
158
  const onKey = (e) => {
@@ -175,7 +179,7 @@ function useFocusTrap(ref, active = true, { restoreFocus = true, initialFocus }
175
179
  }, [active]);
176
180
  }
177
181
  function usePortal() {
178
- return React36__namespace.default.useCallback((node) => {
182
+ return React37__namespace.default.useCallback((node) => {
179
183
  if (typeof document === "undefined") return null;
180
184
  return typeof reactDom.createPortal === "function" ? reactDom.createPortal(node, document.body) : node;
181
185
  }, []);
@@ -203,7 +207,7 @@ function useScrollLock(locked = true) {
203
207
  }, [locked]);
204
208
  }
205
209
  function useInertBackground(ref, active) {
206
- React36__namespace.default.useEffect(() => {
210
+ React37__namespace.default.useEffect(() => {
207
211
  if (!active || !canUseDOM) return void 0;
208
212
  const node = ref.current;
209
213
  if (!node) return void 0;
@@ -235,7 +239,7 @@ function getColorSchemeScript({ storageKey = "twico-theme", attribute = "class",
235
239
  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){}})();`;
236
240
  }
237
241
  function ColorSchemeScript({ storageKey = "twico-theme", attribute = "class", nonce, defaultScheme }) {
238
- return React36__namespace.default.createElement("script", { nonce }, getColorSchemeScript({ storageKey, attribute, defaultScheme }));
242
+ return React37__namespace.default.createElement("script", { nonce }, getColorSchemeScript({ storageKey, attribute, defaultScheme }));
239
243
  }
240
244
  var KBD_CSS = `
241
245
  .twc-kbd { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; padding: 2px 6px;
@@ -243,7 +247,7 @@ var KBD_CSS = `
243
247
  background: var(--color-surface-sunken); border: var(--border-thin) solid var(--color-border);
244
248
  border-bottom-width: 2px; border-radius: var(--radius-sm); }
245
249
  `;
246
- var Kbd = React36__namespace.default.forwardRef(function Kbd2({ className = "", children, ...rest }, ref) {
250
+ var Kbd = React37__namespace.default.forwardRef(function Kbd2({ className = "", children, ...rest }, ref) {
247
251
  const __twcStyles = useScopedStyles("twc-kbd-styles", KBD_CSS);
248
252
  return /* @__PURE__ */ jsxRuntime.jsxs("kbd", { ref, className: `twc-kbd ${className}`.trim(), ...rest, children: [
249
253
  __twcStyles,
@@ -258,7 +262,7 @@ var PRE_CSS = `
258
262
  border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-lg);
259
263
  white-space: pre; -webkit-overflow-scrolling: touch; }
260
264
  `;
261
- var Pre = React36__namespace.default.forwardRef(function Pre2({ className = "", children, ...rest }, ref) {
265
+ var Pre = React37__namespace.default.forwardRef(function Pre2({ className = "", children, ...rest }, ref) {
262
266
  const __twcStyles = useScopedStyles("twc-pre-styles", PRE_CSS);
263
267
  return /* @__PURE__ */ jsxRuntime.jsxs("pre", { ref, className: `twc-pre ${className}`.trim(), ...rest, children: [
264
268
  __twcStyles,
@@ -278,7 +282,7 @@ function safeHref(url) {
278
282
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
279
283
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
280
284
  }
281
- var Anchor = React36__namespace.default.forwardRef(function Anchor2({ as: Tag2 = "a", href, external = false, className = "", children, ...rest }, ref) {
285
+ var Anchor = React37__namespace.default.forwardRef(function Anchor2({ as: Tag2 = "a", href, external = false, className = "", children, ...rest }, ref) {
282
286
  const __twcStyles = useScopedStyles("twc-anchor-styles", ANCHOR_CSS);
283
287
  const extra = external ? { target: "_blank", rel: "noopener noreferrer" } : {};
284
288
  return /* @__PURE__ */ jsxRuntime.jsxs(Tag2, { ref, className: `twc-anchor ${className}`.trim(), href: Tag2 === "a" ? safeHref(href) : href, ...extra, ...rest, children: [
@@ -294,7 +298,7 @@ var LABEL_CSS = `
294
298
  .twc-label[data-size="lg"] { font-size: var(--text-base); }
295
299
  .twc-label__req { color: var(--color-danger); }
296
300
  `;
297
- var Label = React36__namespace.default.forwardRef(function Label2({ htmlFor, required = false, size = "md", className = "", children, ...rest }, ref) {
301
+ var Label = React37__namespace.default.forwardRef(function Label2({ htmlFor, required = false, size = "md", className = "", children, ...rest }, ref) {
298
302
  const __twcStyles = useScopedStyles("twc-label-styles", LABEL_CSS);
299
303
  return /* @__PURE__ */ jsxRuntime.jsxs("label", { ref, htmlFor, className: `twc-label ${className}`.trim(), "data-size": size, ...rest, children: [
300
304
  __twcStyles,
@@ -307,7 +311,7 @@ var IMAGE_CSS = `
307
311
  .twc-image { display: block; max-width: 100%; }
308
312
  .twc-image[data-fit] { width: 100%; height: 100%; }
309
313
  `;
310
- var Image = React36__namespace.default.forwardRef(function Image2({
314
+ var Image = React37__namespace.default.forwardRef(function Image2({
311
315
  src,
312
316
  alt,
313
317
  fit,
@@ -321,7 +325,7 @@ var Image = React36__namespace.default.forwardRef(function Image2({
321
325
  ...rest
322
326
  }, ref) {
323
327
  const __twcStyles = useScopedStyles("twc-image-styles", IMAGE_CSS);
324
- const [failed, setFailed] = React36__namespace.default.useState(false);
328
+ const [failed, setFailed] = React37__namespace.default.useState(false);
325
329
  const shownSrc = failed && fallback ? fallback : src;
326
330
  const s = {
327
331
  objectFit: fit,
@@ -390,10 +394,10 @@ function Accordion({
390
394
  ...rest
391
395
  }) {
392
396
  const __twcStyles = useScopedStyles("twc-accordion-styles", ACCORDION_CSS);
393
- const rootRef = React36__namespace.default.useRef(null);
394
- const [internal, setInternal] = React36__namespace.default.useState(() => new Set(defaultOpen));
397
+ const rootRef = React37__namespace.default.useRef(null);
398
+ const [internal, setInternal] = React37__namespace.default.useState(() => new Set(defaultOpen));
395
399
  const open = openProp !== void 0 ? new Set(openProp) : internal;
396
- const baseId = React36__namespace.default.useId();
400
+ const baseId = React37__namespace.default.useId();
397
401
  function toggle(val) {
398
402
  const item = items.find((x) => x.value === val);
399
403
  if (item?.disabled) return;
@@ -579,7 +583,7 @@ function Avatar({
579
583
  ...rest
580
584
  }) {
581
585
  const __twcStyles = useScopedStyles("twc-avatar-styles", AVATAR_CSS);
582
- const [errored, setErrored] = React36__namespace.default.useState(false);
586
+ const [errored, setErrored] = React37__namespace.default.useState(false);
583
587
  const cleanSrc = safeSrc(src);
584
588
  const showImg = cleanSrc && !errored;
585
589
  const _statusLabel = status ? statusLabel ?? statusLabels?.[status] ?? STATUS_LABELS[status] : void 0;
@@ -657,25 +661,25 @@ function Menu({
657
661
  ...rest
658
662
  }) {
659
663
  const __twcStyles = useScopedStyles("twc-menu-styles", MENU_CSS);
660
- const [openState, setOpenState] = React36__namespace.default.useState(defaultOpen);
661
- const [render, setRender] = React36__namespace.default.useState(false);
662
- const [pos, setPos] = React36__namespace.default.useState(null);
663
- const [active, setActive] = React36__namespace.default.useState(-1);
664
- const wrapRef = React36__namespace.default.useRef(null);
665
- const menuRef = React36__namespace.default.useRef(null);
666
- const typeBufRef = React36__namespace.default.useRef("");
667
- const typeTimerRef = React36__namespace.default.useRef(null);
668
- const menuId = React36__namespace.default.useId();
664
+ const [openState, setOpenState] = React37__namespace.default.useState(defaultOpen);
665
+ const [render, setRender] = React37__namespace.default.useState(false);
666
+ const [pos, setPos] = React37__namespace.default.useState(null);
667
+ const [active, setActive] = React37__namespace.default.useState(-1);
668
+ const wrapRef = React37__namespace.default.useRef(null);
669
+ const menuRef = React37__namespace.default.useRef(null);
670
+ const typeBufRef = React37__namespace.default.useRef("");
671
+ const typeTimerRef = React37__namespace.default.useRef(null);
672
+ const menuId = React37__namespace.default.useId();
669
673
  const headerId = `${menuId}-header`;
670
674
  const controlled = openProp !== void 0;
671
675
  const open = controlled ? !!openProp : openState;
672
- const openRef = React36__namespace.default.useRef(open);
676
+ const openRef = React37__namespace.default.useRef(open);
673
677
  openRef.current = open;
674
- const controlledRef = React36__namespace.default.useRef(controlled);
678
+ const controlledRef = React37__namespace.default.useRef(controlled);
675
679
  controlledRef.current = controlled;
676
- const onOpenChangeRef = React36__namespace.default.useRef(onOpenChange);
680
+ const onOpenChangeRef = React37__namespace.default.useRef(onOpenChange);
677
681
  onOpenChangeRef.current = onOpenChange;
678
- const setOpen = React36__namespace.default.useCallback((next) => {
682
+ const setOpen = React37__namespace.default.useCallback((next) => {
679
683
  const value = typeof next === "function" ? next(openRef.current) : next;
680
684
  if (value === openRef.current) return;
681
685
  if (!controlledRef.current) setOpenState(value);
@@ -683,7 +687,7 @@ function Menu({
683
687
  }, []);
684
688
  const RD = { createPortal: typeof reactDom.createPortal === "function" ? reactDom.createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
685
689
  const interactiveIdx = items.map((it, i) => !it.separator && !it.heading ? i : -1).filter((i) => i >= 0);
686
- const place = React36__namespace.default.useCallback(() => {
690
+ const place = React37__namespace.default.useCallback(() => {
687
691
  const t = wrapRef.current;
688
692
  if (!t) return;
689
693
  const r = t.getBoundingClientRect();
@@ -698,7 +702,7 @@ function Menu({
698
702
  const avail = (flip ? r.top : vh - r.bottom) - gap - M;
699
703
  setPos({ top, bottom, left, width: w, flip, maxHeight: Math.max(120, avail) });
700
704
  }, [align, width]);
701
- React36__namespace.default.useEffect(() => {
705
+ React37__namespace.default.useEffect(() => {
702
706
  if (!open) return;
703
707
  place();
704
708
  const onMove = () => place();
@@ -716,7 +720,7 @@ function Menu({
716
720
  document.removeEventListener("mousedown", onDown);
717
721
  };
718
722
  }, [open, place]);
719
- React36__namespace.default.useEffect(() => {
723
+ React37__namespace.default.useEffect(() => {
720
724
  if (open) {
721
725
  setRender(true);
722
726
  return;
@@ -839,7 +843,7 @@ function Menu({
839
843
  }
840
844
  ) : null;
841
845
  const activeDescId = open && active >= 0 ? `${menuId}-item-${active}` : void 0;
842
- const triggerEl = React36__namespace.default.isValidElement(trigger) ? React36__namespace.default.cloneElement(trigger, {
846
+ const triggerEl = React37__namespace.default.isValidElement(trigger) ? React37__namespace.default.cloneElement(trigger, {
843
847
  onClick: (e) => {
844
848
  trigger.props.onClick?.(e);
845
849
  toggle();
@@ -1004,7 +1008,7 @@ function Breadcrumb({
1004
1008
  ...rest
1005
1009
  }) {
1006
1010
  const __twcStyles = useScopedStyles("twc-breadcrumb-styles", BREADCRUMB_CSS);
1007
- const [expanded, setExpanded] = React36__namespace.default.useState(false);
1011
+ const [expanded, setExpanded] = React37__namespace.default.useState(false);
1008
1012
  const sep = separator || /* @__PURE__ */ jsxRuntime.jsx(ChevronSep, {});
1009
1013
  let display = items;
1010
1014
  if (maxItems > 0 && items.length > maxItems && !expanded) {
@@ -1017,7 +1021,7 @@ function Breadcrumb({
1017
1021
  __twcStyles,
1018
1022
  display.map((it, i) => {
1019
1023
  const last = i === display.length - 1;
1020
- return /* @__PURE__ */ jsxRuntime.jsxs(React36__namespace.default.Fragment, { children: [
1024
+ return /* @__PURE__ */ jsxRuntime.jsxs(React37__namespace.default.Fragment, { children: [
1021
1025
  it.ellipsis ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-breadcrumb__ellipsis", "aria-label": "Show more", onClick: () => setExpanded(true), children: "\u2026" }) : last ? /* @__PURE__ */ jsxRuntime.jsxs(
1022
1026
  "span",
1023
1027
  {
@@ -1159,7 +1163,7 @@ function Button({
1159
1163
  ...rest
1160
1164
  }) {
1161
1165
  const __twcStyles = useScopedStyles("twc-btn-styles", CSS2);
1162
- const [ripples, setRipples] = React36__namespace.default.useState([]);
1166
+ const [ripples, setRipples] = React37__namespace.default.useState([]);
1163
1167
  const Tag2 = as;
1164
1168
  const inert = Tag2 === "a" && (disabled || loading);
1165
1169
  function handleClick(e) {
@@ -1214,6 +1218,122 @@ function Button({
1214
1218
  }
1215
1219
  );
1216
1220
  }
1221
+ var UNITLESS = /* @__PURE__ */ new Set([
1222
+ "animationIterationCount",
1223
+ "aspectRatio",
1224
+ "borderImageOutset",
1225
+ "borderImageSlice",
1226
+ "borderImageWidth",
1227
+ "boxFlex",
1228
+ "boxFlexGroup",
1229
+ "boxOrdinalGroup",
1230
+ "columnCount",
1231
+ "columns",
1232
+ "flex",
1233
+ "flexGrow",
1234
+ "flexShrink",
1235
+ "flexPositive",
1236
+ "flexNegative",
1237
+ "flexOrder",
1238
+ "gridArea",
1239
+ "gridRow",
1240
+ "gridRowEnd",
1241
+ "gridRowSpan",
1242
+ "gridRowStart",
1243
+ "gridColumn",
1244
+ "gridColumnEnd",
1245
+ "gridColumnSpan",
1246
+ "gridColumnStart",
1247
+ "fontWeight",
1248
+ "lineClamp",
1249
+ "lineHeight",
1250
+ "opacity",
1251
+ "order",
1252
+ "orphans",
1253
+ "tabSize",
1254
+ "widows",
1255
+ "zIndex",
1256
+ "zoom",
1257
+ "fillOpacity",
1258
+ "floodOpacity",
1259
+ "stopOpacity",
1260
+ "strokeDasharray",
1261
+ "strokeDashoffset",
1262
+ "strokeMiterlimit",
1263
+ "strokeOpacity",
1264
+ "strokeWidth",
1265
+ "scale"
1266
+ ]);
1267
+ var isObject = (v) => v != null && typeof v === "object" && !Array.isArray(v);
1268
+ var isNestedKey = (k, v) => isObject(v) || k.charCodeAt(0) === 38 || k.charCodeAt(0) === 64 || k.charCodeAt(0) === 58;
1269
+ function kebab(prop) {
1270
+ if (prop.startsWith("--")) return prop;
1271
+ return prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
1272
+ }
1273
+ function cssValue(key, value) {
1274
+ if (typeof value !== "number") return String(value);
1275
+ if (value === 0 || key.startsWith("--") || UNITLESS.has(key)) return String(value);
1276
+ return `${value}px`;
1277
+ }
1278
+ function resolveSelector(key, scope) {
1279
+ if (key.includes("&")) return key.replace(/&/g, scope);
1280
+ if (key.charCodeAt(0) === 58) return `${scope}${key}`;
1281
+ return `${scope} ${key}`;
1282
+ }
1283
+ function compileSx(obj, selector) {
1284
+ if (!isObject(obj)) return "";
1285
+ let decls = "";
1286
+ let rules = "";
1287
+ for (const key of Object.keys(obj)) {
1288
+ const value = obj[key];
1289
+ if (isNestedKey(key, value)) {
1290
+ if (!isObject(value)) continue;
1291
+ if (key.charCodeAt(0) === 64) {
1292
+ const inner = compileSx(value, selector);
1293
+ if (inner) rules += `${key} { ${inner.trim()} }
1294
+ `;
1295
+ } else {
1296
+ rules += compileSx(value, resolveSelector(key, selector));
1297
+ }
1298
+ } else {
1299
+ decls += `${kebab(key)}: ${cssValue(key, value)}; `;
1300
+ }
1301
+ }
1302
+ let out = "";
1303
+ if (decls) out += `${selector} { ${decls.trimEnd()} }
1304
+ `;
1305
+ out += rules;
1306
+ return out;
1307
+ }
1308
+ function buildSx(sx, uid) {
1309
+ if (!isObject(sx)) return { flatStyle: void 0, css: "" };
1310
+ const scope = `[data-twc-sx="${uid}"]`;
1311
+ let flatStyle;
1312
+ let css = "";
1313
+ for (const key of Object.keys(sx)) {
1314
+ const value = sx[key];
1315
+ if (isNestedKey(key, value)) {
1316
+ if (!isObject(value)) continue;
1317
+ if (key.charCodeAt(0) === 64) {
1318
+ const inner = compileSx(value, scope);
1319
+ if (inner) css += `${key} { ${inner.trim()} }
1320
+ `;
1321
+ } else {
1322
+ css += compileSx(value, resolveSelector(key, scope));
1323
+ }
1324
+ } else {
1325
+ (flatStyle || (flatStyle = {}))[key] = value;
1326
+ }
1327
+ }
1328
+ return { flatStyle, css };
1329
+ }
1330
+ function useSx(sx) {
1331
+ const rawId = React37__namespace.default.useId();
1332
+ const uid = `sx${rawId.replace(/[^a-zA-Z0-9]/g, "")}`;
1333
+ const { flatStyle, css } = React37__namespace.default.useMemo(() => buildSx(sx, uid), [sx, uid]);
1334
+ const styleNode = useScopedStyles(`twc-sx-${uid}`, css);
1335
+ return { flatStyle, styleNode, sxAttr: css ? uid : void 0 };
1336
+ }
1217
1337
  var CARD_CSS = `
1218
1338
  .twc-card {
1219
1339
  display: flex; flex-direction: column;
@@ -1253,10 +1373,13 @@ function Card({
1253
1373
  padding = "md",
1254
1374
  interactive = false,
1255
1375
  fullHeight = false,
1376
+ sx,
1256
1377
  className = "",
1378
+ style,
1257
1379
  ...rest
1258
1380
  }) {
1259
1381
  const __twcStyles = useScopedStyles("twc-card-styles", CARD_CSS);
1382
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
1260
1383
  return /* @__PURE__ */ jsxRuntime.jsxs(
1261
1384
  "div",
1262
1385
  {
@@ -1265,9 +1388,12 @@ function Card({
1265
1388
  "data-pad": padding,
1266
1389
  "data-interactive": interactive || void 0,
1267
1390
  "data-full": fullHeight || void 0,
1391
+ "data-twc-sx": sxAttr,
1392
+ style: style || flatStyle ? { ...style, ...flatStyle } : void 0,
1268
1393
  ...rest,
1269
1394
  children: [
1270
1395
  __twcStyles,
1396
+ styleNode,
1271
1397
  title || subtitle || actions ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-card__header", children: [
1272
1398
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-card__heading", children: [
1273
1399
  title ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-card__title", children: title }) : null,
@@ -1333,14 +1459,14 @@ function Carousel({
1333
1459
  ...rest
1334
1460
  }) {
1335
1461
  const __twcStyles = useScopedStyles("twc-carousel-styles", CAROUSEL_CSS);
1336
- const slides = React36__namespace.default.Children.toArray(children);
1462
+ const slides = React37__namespace.default.Children.toArray(children);
1337
1463
  const count = slides.length;
1338
- const [internal, setInternal] = React36__namespace.default.useState(defaultIndex);
1464
+ const [internal, setInternal] = React37__namespace.default.useState(defaultIndex);
1339
1465
  const index = indexProp !== void 0 ? indexProp : internal;
1340
- const [paused, setPaused] = React36__namespace.default.useState(false);
1341
- const [userPaused, setUserPaused] = React36__namespace.default.useState(false);
1342
- const [prefersReduced, setPrefersReduced] = React36__namespace.default.useState(false);
1343
- React36__namespace.default.useEffect(() => {
1466
+ const [paused, setPaused] = React37__namespace.default.useState(false);
1467
+ const [userPaused, setUserPaused] = React37__namespace.default.useState(false);
1468
+ const [prefersReduced, setPrefersReduced] = React37__namespace.default.useState(false);
1469
+ React37__namespace.default.useEffect(() => {
1344
1470
  if (typeof window === "undefined" || !window.matchMedia) return void 0;
1345
1471
  const mql = window.matchMedia("(prefers-reduced-motion: reduce)");
1346
1472
  const on = () => setPrefersReduced(mql.matches);
@@ -1348,15 +1474,15 @@ function Carousel({
1348
1474
  mql.addEventListener("change", on);
1349
1475
  return () => mql.removeEventListener("change", on);
1350
1476
  }, []);
1351
- const setIndex = React36__namespace.default.useCallback((i) => {
1477
+ const setIndex = React37__namespace.default.useCallback((i) => {
1352
1478
  if (indexProp === void 0) setInternal(i);
1353
1479
  onIndexChange?.(i);
1354
1480
  }, [indexProp, onIndexChange]);
1355
- const go = React36__namespace.default.useCallback((i) => {
1481
+ const go = React37__namespace.default.useCallback((i) => {
1356
1482
  setIndex(loop ? (i + count) % count : Math.min(Math.max(i, 0), count - 1));
1357
1483
  }, [count, loop, setIndex]);
1358
1484
  const autoRotating = autoPlay && !paused && !userPaused && !prefersReduced && count > 1;
1359
- React36__namespace.default.useEffect(() => {
1485
+ React37__namespace.default.useEffect(() => {
1360
1486
  if (!autoRotating) return void 0;
1361
1487
  const t = setInterval(() => {
1362
1488
  const next = loop ? (index + 1) % count : index + 1 >= count ? index : index + 1;
@@ -1451,7 +1577,7 @@ function Chart({
1451
1577
  ...rest
1452
1578
  }) {
1453
1579
  const __twcStyles = useScopedStyles("twc-chart-styles", CHART_CSS);
1454
- const uid = React36__namespace.default.useId();
1580
+ const uid = React37__namespace.default.useId();
1455
1581
  const tableId = tableFallback ? `${uid}-table` : void 0;
1456
1582
  const keys = series || ["value"];
1457
1583
  const palette = colors && colors.length ? colors : SERIES_COLORS;
@@ -1607,13 +1733,13 @@ function Checkbox({
1607
1733
  .twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
1608
1734
  .twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
1609
1735
  `);
1610
- const autoId = React36__namespace.default.useId();
1736
+ const autoId = React37__namespace.default.useId();
1611
1737
  const fieldId = id || autoId;
1612
1738
  const errId = `${fieldId}-error`;
1613
1739
  const invalid = Boolean(error);
1614
- const ref = React36__namespace.default.useRef(null);
1740
+ const ref = React37__namespace.default.useRef(null);
1615
1741
  const mixed = indeterminate && !checked;
1616
- React36__namespace.default.useEffect(() => {
1742
+ React37__namespace.default.useEffect(() => {
1617
1743
  if (ref.current) ref.current.indeterminate = mixed;
1618
1744
  }, [mixed]);
1619
1745
  if (process.env.NODE_ENV !== "production" && !label && !description && !rest["aria-label"] && !rest["aria-labelledby"]) {
@@ -1686,6 +1812,10 @@ var COLORPICKER_CSS = `
1686
1812
  .twc-cp__hue { position: relative; height: 12px; margin-top: var(--space-3); border-radius: var(--radius-full); cursor: pointer; touch-action: none;
1687
1813
  background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); }
1688
1814
  .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; }
1815
+ .twc-cp__alpha { position: relative; height: 12px; margin-top: var(--space-2); border-radius: var(--radius-full); cursor: pointer; touch-action: none;
1816
+ background-image: linear-gradient(to right, transparent, var(--_solid, #000)), conic-gradient(#c8c8c8 0 25%, #fff 0 50%, #c8c8c8 0 75%, #fff 0);
1817
+ background-size: 100% 100%, 10px 10px; }
1818
+ .twc-cp__alpha:focus-visible { outline: none; box-shadow: var(--ring); }
1689
1819
  .twc-cp__foot { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-3); }
1690
1820
  .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;
1691
1821
  color: var(--color-text); background: var(--color-surface); border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-sm); outline: none; }
@@ -1723,11 +1853,17 @@ function rgbToHex(r, g, b) {
1723
1853
  function hsvToHex(h, s, v) {
1724
1854
  return rgbToHex(...hsvToRgb(h, s, v));
1725
1855
  }
1856
+ function hsvaToHex8(h, s, v, a) {
1857
+ return rgbToHex(...hsvToRgb(h, s, v)) + Math.round(Math.min(1, Math.max(0, a)) * 255).toString(16).padStart(2, "0");
1858
+ }
1726
1859
  function hexToHsv(hex) {
1727
- const m = /^#?([0-9a-f]{6})$/i.exec(hex || "");
1860
+ let str = String(hex || "").replace(/^#/, "");
1861
+ if (/^[0-9a-f]{3}$/i.test(str)) str = str.split("").map((c) => c + c).join("");
1862
+ const m = /^([0-9a-f]{6})([0-9a-f]{2})?$/i.exec(str);
1728
1863
  if (!m) return null;
1729
1864
  const int = parseInt(m[1], 16);
1730
1865
  const r = (int >> 16) / 255, g = (int >> 8 & 255) / 255, b = (int & 255) / 255;
1866
+ const a = m[2] != null ? parseInt(m[2], 16) / 255 : 1;
1731
1867
  const max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min;
1732
1868
  let h = 0;
1733
1869
  if (d) {
@@ -1737,7 +1873,7 @@ function hexToHsv(hex) {
1737
1873
  h *= 60;
1738
1874
  if (h < 0) h += 360;
1739
1875
  }
1740
- return { h, s: max ? d / max * 100 : 0, v: max * 100 };
1876
+ return { h, s: max ? d / max * 100 : 0, v: max * 100, a };
1741
1877
  }
1742
1878
  var DEFAULT_PRESETS = ["#6366F1", "#0EA5E9", "#14B8A6", "#22C55E", "#F59E0B", "#F43F5E", "#8B5CF6", "#0F172A"];
1743
1879
  function ColorPicker({
@@ -1749,6 +1885,7 @@ function ColorPicker({
1749
1885
  defaultValue = "#6366F1",
1750
1886
  presets = DEFAULT_PRESETS,
1751
1887
  disabled = false,
1888
+ alpha = false,
1752
1889
  tone = "primary",
1753
1890
  onChange,
1754
1891
  className = "",
@@ -1756,20 +1893,22 @@ function ColorPicker({
1756
1893
  }) {
1757
1894
  const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS);
1758
1895
  const __twcStyles1 = useScopedStyles("twc-colorpicker-styles", COLORPICKER_CSS);
1759
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
1896
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
1760
1897
  const hex = (value !== void 0 ? value : internal) || "#000000";
1761
- const lastValidRef = React36__namespace.default.useRef(hex);
1762
- if (/^#[0-9a-f]{6}$/i.test(hex)) lastValidRef.current = hex;
1763
- const [open, setOpen] = React36__namespace.default.useState(false);
1764
- const [hsv, setHsv] = React36__namespace.default.useState(() => hexToHsv(hex) || { h: 239, s: 60, v: 94 });
1765
- const [coords, setCoords] = React36__namespace.default.useState(null);
1766
- const wrapRef = React36__namespace.default.useRef(null);
1767
- const triggerRef = React36__namespace.default.useRef(null);
1768
- const popRef = React36__namespace.default.useRef(null);
1769
- const areaRef = React36__namespace.default.useRef(null);
1770
- const hueRef = React36__namespace.default.useRef(null);
1898
+ 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;
1899
+ const lastValidRef = React37__namespace.default.useRef(hex);
1900
+ if (hexRe.test(hex)) lastValidRef.current = hex;
1901
+ const [open, setOpen] = React37__namespace.default.useState(false);
1902
+ const [hsv, setHsv] = React37__namespace.default.useState(() => hexToHsv(hex) || { h: 239, s: 60, v: 94, a: 1 });
1903
+ const [coords, setCoords] = React37__namespace.default.useState(null);
1904
+ const wrapRef = React37__namespace.default.useRef(null);
1905
+ const triggerRef = React37__namespace.default.useRef(null);
1906
+ const popRef = React37__namespace.default.useRef(null);
1907
+ const areaRef = React37__namespace.default.useRef(null);
1908
+ const hueRef = React37__namespace.default.useRef(null);
1909
+ const alphaRef = React37__namespace.default.useRef(null);
1771
1910
  const POP_W = 240;
1772
- const place = React36__namespace.default.useCallback(() => {
1911
+ const place = React37__namespace.default.useCallback(() => {
1773
1912
  const el = triggerRef.current;
1774
1913
  if (!el) return;
1775
1914
  const r = el.getBoundingClientRect();
@@ -1780,7 +1919,7 @@ function ColorPicker({
1780
1919
  left = Math.max(8, left);
1781
1920
  setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
1782
1921
  }, []);
1783
- React36__namespace.default.useEffect(() => {
1922
+ React37__namespace.default.useEffect(() => {
1784
1923
  if (!open) return void 0;
1785
1924
  place();
1786
1925
  const onMove = () => place();
@@ -1791,17 +1930,17 @@ function ColorPicker({
1791
1930
  window.removeEventListener("resize", onMove);
1792
1931
  };
1793
1932
  }, [open, place]);
1794
- const labelId = React36__namespace.default.useId();
1933
+ const labelId = React37__namespace.default.useId();
1795
1934
  const descId = `${labelId}-desc`;
1796
1935
  const invalid = Boolean(error);
1797
- React36__namespace.default.useEffect(() => {
1936
+ React37__namespace.default.useEffect(() => {
1798
1937
  if (disabled) setOpen(false);
1799
1938
  }, [disabled]);
1800
- React36__namespace.default.useEffect(() => {
1939
+ React37__namespace.default.useEffect(() => {
1801
1940
  const v = hexToHsv(hex);
1802
1941
  if (v && hsvToHex(v.h, v.s, v.v).toLowerCase() !== hsvToHex(hsv.h, hsv.s, hsv.v).toLowerCase()) setHsv(v);
1803
1942
  }, [hex]);
1804
- React36__namespace.default.useEffect(() => {
1943
+ React37__namespace.default.useEffect(() => {
1805
1944
  if (!open) return;
1806
1945
  const onDown = (e) => {
1807
1946
  if (wrapRef.current && wrapRef.current.contains(e.target)) return;
@@ -1820,10 +1959,10 @@ function ColorPicker({
1820
1959
  }, [open]);
1821
1960
  useFocusTrap(popRef, open && !!coords, { initialFocus: areaRef });
1822
1961
  const commit = (next) => {
1823
- const h = hsvToHex(next.h, next.s, next.v);
1962
+ const out = alpha ? hsvaToHex8(next.h, next.s, next.v, next.a ?? 1) : hsvToHex(next.h, next.s, next.v);
1824
1963
  setHsv(next);
1825
- if (value === void 0) setInternal(h);
1826
- onChange?.(h);
1964
+ if (value === void 0) setInternal(out);
1965
+ onChange?.(out);
1827
1966
  };
1828
1967
  const dragArea = (e) => {
1829
1968
  const r = areaRef.current.getBoundingClientRect();
@@ -1867,6 +2006,21 @@ function ColorPicker({
1867
2006
  e.preventDefault();
1868
2007
  commit({ ...hsv, h });
1869
2008
  };
2009
+ const dragAlpha = (e) => {
2010
+ const r = alphaRef.current.getBoundingClientRect();
2011
+ const a = Math.min(1, Math.max(0, (e.clientX - r.left) / r.width));
2012
+ commit({ ...hsv, a });
2013
+ };
2014
+ const onAlphaKeyDown = (e) => {
2015
+ let a = hsv.a ?? 1;
2016
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") a = Math.min(1, a + 0.01);
2017
+ else if (e.key === "ArrowLeft" || e.key === "ArrowDown") a = Math.max(0, a - 0.01);
2018
+ else if (e.key === "Home") a = 0;
2019
+ else if (e.key === "End") a = 1;
2020
+ else return;
2021
+ e.preventDefault();
2022
+ commit({ ...hsv, a: Math.round(a * 100) / 100 });
2023
+ };
1870
2024
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-cp twc-field ${className}`, ref: wrapRef, ...rest, children: [
1871
2025
  __twcStyles0,
1872
2026
  __twcStyles1,
@@ -1953,6 +2107,23 @@ function ColorPicker({
1953
2107
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-cp__hue-knob", style: { left: `${hsv.h / 360 * 100}%` } })
1954
2108
  }
1955
2109
  ),
2110
+ alpha ? /* @__PURE__ */ jsxRuntime.jsx(
2111
+ "div",
2112
+ {
2113
+ className: "twc-cp__alpha",
2114
+ ref: alphaRef,
2115
+ onPointerDown: startDrag(dragAlpha),
2116
+ role: "slider",
2117
+ tabIndex: 0,
2118
+ "aria-label": "Alpha",
2119
+ "aria-valuemin": 0,
2120
+ "aria-valuemax": 100,
2121
+ "aria-valuenow": Math.round((hsv.a ?? 1) * 100),
2122
+ onKeyDown: onAlphaKeyDown,
2123
+ style: { "--_solid": hsvToHex(hsv.h, hsv.s, hsv.v) },
2124
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-cp__hue-knob", style: { left: `${(hsv.a ?? 1) * 100}%` } })
2125
+ }
2126
+ ) : null,
1956
2127
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-cp__foot", children: [
1957
2128
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-cp__swatch", style: { background: hex } }),
1958
2129
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1961,10 +2132,10 @@ function ColorPicker({
1961
2132
  className: "twc-cp__hex",
1962
2133
  "data-tone": tone,
1963
2134
  value: hex,
1964
- maxLength: 7,
2135
+ maxLength: alpha ? 9 : 7,
1965
2136
  "aria-label": "Hex color",
1966
- "aria-invalid": !/^#[0-9a-f]{6}$/i.test(hex) || void 0,
1967
- "data-invalid": !/^#[0-9a-f]{6}$/i.test(hex) || void 0,
2137
+ "aria-invalid": !hexRe.test(hex) || void 0,
2138
+ "data-invalid": !hexRe.test(hex) || void 0,
1968
2139
  onChange: (e) => {
1969
2140
  let v = e.target.value;
1970
2141
  if (!v.startsWith("#")) v = "#" + v;
@@ -1974,7 +2145,7 @@ function ColorPicker({
1974
2145
  if (p) setHsv(p);
1975
2146
  },
1976
2147
  onBlur: () => {
1977
- if (/^#[0-9a-f]{6}$/i.test(hex)) return;
2148
+ if (hexRe.test(hex)) return;
1978
2149
  const revert = lastValidRef.current;
1979
2150
  if (revert === hex) return;
1980
2151
  if (value === void 0) setInternal(revert);
@@ -2132,6 +2303,8 @@ function Combobox({
2132
2303
  loading = false,
2133
2304
  emptyText = "No results found",
2134
2305
  name,
2306
+ virtualized = false,
2307
+ overscan = 8,
2135
2308
  id,
2136
2309
  className = "",
2137
2310
  onFocus,
@@ -2139,29 +2312,51 @@ function Combobox({
2139
2312
  ...rest
2140
2313
  }) {
2141
2314
  const __twcStyles = useScopedStyles("twc-combo-styles", COMBO_CSS);
2142
- const groups = React36__namespace.default.useMemo(() => normalizeGroups(options), [options]);
2143
- const flat = React36__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
2144
- const autoId = React36__namespace.default.useId();
2315
+ const groups = React37__namespace.default.useMemo(() => normalizeGroups(options), [options]);
2316
+ const flat = React37__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
2317
+ const autoId = React37__namespace.default.useId();
2145
2318
  const fieldId = id || autoId;
2146
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
2319
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
2147
2320
  const current = value !== void 0 ? value : internal;
2148
2321
  const selected = flat.find((o) => o.value === current);
2149
- const [open, setOpen] = React36__namespace.default.useState(false);
2150
- const [query, setQuery] = React36__namespace.default.useState("");
2151
- const [active, setActive] = React36__namespace.default.useState(0);
2152
- const [coords, setCoords] = React36__namespace.default.useState(null);
2153
- const wrapRef = React36__namespace.default.useRef(null);
2154
- const controlRef = React36__namespace.default.useRef(null);
2155
- const inputRef = React36__namespace.default.useRef(null);
2156
- const popRef = React36__namespace.default.useRef(null);
2157
- const listRef = React36__namespace.default.useRef(null);
2158
- const activeRef = React36__namespace.default.useRef(null);
2159
- const fGroups = React36__namespace.default.useMemo(() => {
2322
+ const [open, setOpen] = React37__namespace.default.useState(false);
2323
+ const [query, setQuery] = React37__namespace.default.useState("");
2324
+ const [active, setActive] = React37__namespace.default.useState(0);
2325
+ const [coords, setCoords] = React37__namespace.default.useState(null);
2326
+ const [scrollTop, setScrollTop] = React37__namespace.default.useState(0);
2327
+ const [listH, setListH] = React37__namespace.default.useState(260);
2328
+ const wrapRef = React37__namespace.default.useRef(null);
2329
+ const controlRef = React37__namespace.default.useRef(null);
2330
+ const inputRef = React37__namespace.default.useRef(null);
2331
+ const popRef = React37__namespace.default.useRef(null);
2332
+ const listRef = React37__namespace.default.useRef(null);
2333
+ const activeRef = React37__namespace.default.useRef(null);
2334
+ const fGroups = React37__namespace.default.useMemo(() => {
2160
2335
  const q = query.trim();
2161
2336
  const fn = filter === false ? null : typeof filter === "function" ? filter : matches;
2162
2337
  return groups.map((g) => ({ group: g.group, options: fn ? g.options.filter((o) => fn(o, q)) : g.options })).filter((g) => g.options.length);
2163
2338
  }, [groups, query, filter]);
2164
- const visible = React36__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
2339
+ const visible = React37__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
2340
+ const rowH = React37__namespace.default.useMemo(() => visible.some((o) => o.description) ? 48 : 36, [visible]);
2341
+ const GROUP_H = 30;
2342
+ const { rows, totalH } = React37__namespace.default.useMemo(() => {
2343
+ if (!virtualized) return { rows: [], totalH: 0 };
2344
+ const rows2 = [];
2345
+ let off = 0;
2346
+ let optIdx = -1;
2347
+ fGroups.forEach((g, gi) => {
2348
+ if (g.group) {
2349
+ rows2.push({ kind: "group", gi, label: g.group, top: off, h: GROUP_H });
2350
+ off += GROUP_H;
2351
+ }
2352
+ g.options.forEach((o) => {
2353
+ optIdx += 1;
2354
+ rows2.push({ kind: "option", o, idx: optIdx, top: off, h: rowH });
2355
+ off += rowH;
2356
+ });
2357
+ });
2358
+ return { rows: rows2, totalH: off };
2359
+ }, [virtualized, fGroups, rowH]);
2165
2360
  const nextEnabled = (from, dir) => {
2166
2361
  let i = from + dir;
2167
2362
  while (i >= 0 && i < visible.length) {
@@ -2170,7 +2365,7 @@ function Combobox({
2170
2365
  }
2171
2366
  return from;
2172
2367
  };
2173
- const place = React36__namespace.default.useCallback(() => {
2368
+ const place = React37__namespace.default.useCallback(() => {
2174
2369
  const el = controlRef.current;
2175
2370
  if (!el) return;
2176
2371
  const r = el.getBoundingClientRect();
@@ -2185,7 +2380,7 @@ function Combobox({
2185
2380
  flip
2186
2381
  });
2187
2382
  }, [placement, minWidth]);
2188
- React36__namespace.default.useEffect(() => {
2383
+ React37__namespace.default.useEffect(() => {
2189
2384
  if (!open || !portal) return;
2190
2385
  place();
2191
2386
  const onMove = () => place();
@@ -2196,7 +2391,7 @@ function Combobox({
2196
2391
  window.removeEventListener("resize", onMove);
2197
2392
  };
2198
2393
  }, [open, portal, place]);
2199
- React36__namespace.default.useEffect(() => {
2394
+ React37__namespace.default.useEffect(() => {
2200
2395
  if (!open) return;
2201
2396
  const onDown = (e) => {
2202
2397
  if (wrapRef.current && wrapRef.current.contains(e.target)) return;
@@ -2206,17 +2401,36 @@ function Combobox({
2206
2401
  document.addEventListener("mousedown", onDown);
2207
2402
  return () => document.removeEventListener("mousedown", onDown);
2208
2403
  }, [open]);
2209
- React36__namespace.default.useEffect(() => {
2404
+ React37__namespace.default.useEffect(() => {
2210
2405
  setActive(0);
2211
2406
  }, [query]);
2212
- React36__namespace.default.useEffect(() => {
2407
+ React37__namespace.default.useEffect(() => {
2213
2408
  if (!open) return;
2214
2409
  const idx = flat.findIndex((o) => o.value === current);
2215
2410
  setActive(idx >= 0 ? idx : 0);
2216
2411
  }, [open]);
2217
- React36__namespace.default.useEffect(() => {
2218
- if (open) ensureVisible(listRef.current, activeRef.current);
2219
- }, [active, open]);
2412
+ React37__namespace.default.useEffect(() => {
2413
+ if (!open || !virtualized) return;
2414
+ const el = listRef.current;
2415
+ if (el && el.clientHeight) setListH(el.clientHeight);
2416
+ }, [open, virtualized]);
2417
+ React37__namespace.default.useEffect(() => {
2418
+ if (!open) return;
2419
+ if (!virtualized) {
2420
+ ensureVisible(listRef.current, activeRef.current);
2421
+ return;
2422
+ }
2423
+ const el = listRef.current;
2424
+ if (!el) return;
2425
+ const row = rows.find((r) => r.kind === "option" && r.idx === active);
2426
+ if (!row) return;
2427
+ const vh = el.clientHeight || listH;
2428
+ let next = el.scrollTop;
2429
+ if (row.top < el.scrollTop) next = row.top;
2430
+ else if (row.top + row.h > el.scrollTop + vh) next = row.top + row.h - vh;
2431
+ if (next !== el.scrollTop) el.scrollTop = next;
2432
+ setScrollTop(next);
2433
+ }, [active, open, virtualized, rows, listH]);
2220
2434
  function openMenu() {
2221
2435
  if (disabled) return;
2222
2436
  setQuery("");
@@ -2261,45 +2475,60 @@ function Combobox({
2261
2475
  const activeId = open && visible[active] ? optionId(active) : void 0;
2262
2476
  const descId = `${fieldId}-desc`;
2263
2477
  const describedBy = error || hint ? descId : void 0;
2478
+ const renderOption = (o, idx) => {
2479
+ const isSel = o.value === current;
2480
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2481
+ "button",
2482
+ {
2483
+ id: optionId(idx),
2484
+ type: "button",
2485
+ className: "twc-opt",
2486
+ role: "option",
2487
+ "aria-selected": isSel,
2488
+ ref: idx === active ? activeRef : null,
2489
+ disabled: o.disabled || void 0,
2490
+ "aria-disabled": o.disabled || void 0,
2491
+ "data-disabled": o.disabled || void 0,
2492
+ "data-selected": isSel || void 0,
2493
+ "data-active": idx === active || void 0,
2494
+ onMouseEnter: () => {
2495
+ if (!o.disabled) setActive(idx);
2496
+ },
2497
+ onMouseDown: (e) => e.preventDefault(),
2498
+ onClick: () => commit(o.value),
2499
+ children: [
2500
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-opt__main", children: [
2501
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__label", children: o.label }),
2502
+ o.description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__desc", children: o.description }) : null
2503
+ ] }),
2504
+ isSel ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__check", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.6", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null
2505
+ ]
2506
+ },
2507
+ o.value
2508
+ );
2509
+ };
2510
+ let vTop = 0, vBottom = 0, vShown = rows;
2511
+ if (virtualized && rows.length) {
2512
+ const winTop = scrollTop - overscan * rowH;
2513
+ const winBottom = scrollTop + listH + overscan * rowH;
2514
+ vShown = rows.filter((r) => r.top + r.h > winTop && r.top < winBottom);
2515
+ vTop = vShown.length ? vShown[0].top : 0;
2516
+ vBottom = vShown.length ? totalH - (vShown[vShown.length - 1].top + vShown[vShown.length - 1].h) : totalH;
2517
+ }
2264
2518
  let counter = -1;
2265
- const popInner = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", ref: listRef, children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-pop__loading", role: "status", children: [
2519
+ const popInner = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", ref: listRef, onScroll: virtualized ? (e) => setScrollTop(e.currentTarget.scrollTop) : void 0, children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-pop__loading", role: "status", children: [
2266
2520
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-pop__spinner", "aria-hidden": "true" }),
2267
2521
  "Loading\u2026"
2268
- ] }) : visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: emptyText }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React36__namespace.default.Fragment, { children: [
2522
+ ] }) : visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: emptyText }) : virtualized ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2523
+ vTop > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", style: { height: vTop } }) : null,
2524
+ vShown.map((r) => r.kind === "group" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: r.label }, `g${r.gi}`) : renderOption(r.o, r.idx)),
2525
+ vBottom > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", style: { height: vBottom } }) : null
2526
+ ] }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React37__namespace.default.Fragment, { children: [
2269
2527
  g.group ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: g.group }) : null,
2270
2528
  g.options.map((o) => {
2271
2529
  counter += 1;
2272
2530
  const idx = counter;
2273
- const isSel = o.value === current;
2274
- return /* @__PURE__ */ jsxRuntime.jsxs(
2275
- "button",
2276
- {
2277
- id: optionId(idx),
2278
- type: "button",
2279
- className: "twc-opt",
2280
- role: "option",
2281
- "aria-selected": isSel,
2282
- ref: idx === active ? activeRef : null,
2283
- disabled: o.disabled || void 0,
2284
- "aria-disabled": o.disabled || void 0,
2285
- "data-disabled": o.disabled || void 0,
2286
- "data-selected": isSel || void 0,
2287
- "data-active": idx === active || void 0,
2288
- onMouseEnter: () => {
2289
- if (!o.disabled) setActive(idx);
2290
- },
2291
- onMouseDown: (e) => e.preventDefault(),
2292
- onClick: () => commit(o.value),
2293
- children: [
2294
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-opt__main", children: [
2295
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__label", children: o.label }),
2296
- o.description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__desc", children: o.description }) : null
2297
- ] }),
2298
- isSel ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__check", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.6", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null
2299
- ]
2300
- },
2301
- o.value
2302
- );
2531
+ return renderOption(o, idx);
2303
2532
  })
2304
2533
  ] }, gi)) });
2305
2534
  const RD = { createPortal: typeof reactDom.createPortal === "function" ? reactDom.createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
@@ -2457,14 +2686,14 @@ function CommandPalette({
2457
2686
  }) {
2458
2687
  const __twcStyles = useScopedStyles("twc-cmdk-styles", COMMAND_CSS);
2459
2688
  const renderPortal = usePortal();
2460
- const [query, setQuery] = React36__namespace.default.useState("");
2461
- const [active, setActive] = React36__namespace.default.useState(0);
2462
- const inputRef = React36__namespace.default.useRef(null);
2463
- const listRef = React36__namespace.default.useRef(null);
2464
- const paletteRef = React36__namespace.default.useRef(null);
2465
- const baseId = React36__namespace.default.useId();
2466
- const [mounted, setMounted] = React36__namespace.default.useState(open);
2467
- React36__namespace.default.useEffect(() => {
2689
+ const [query, setQuery] = React37__namespace.default.useState("");
2690
+ const [active, setActive] = React37__namespace.default.useState(0);
2691
+ const inputRef = React37__namespace.default.useRef(null);
2692
+ const listRef = React37__namespace.default.useRef(null);
2693
+ const paletteRef = React37__namespace.default.useRef(null);
2694
+ const baseId = React37__namespace.default.useId();
2695
+ const [mounted, setMounted] = React37__namespace.default.useState(open);
2696
+ React37__namespace.default.useEffect(() => {
2468
2697
  if (open) {
2469
2698
  setMounted(true);
2470
2699
  return;
@@ -2473,14 +2702,14 @@ function CommandPalette({
2473
2702
  return () => clearTimeout(t);
2474
2703
  }, [open]);
2475
2704
  useScrollLock(open);
2476
- React36__namespace.default.useEffect(() => {
2705
+ React37__namespace.default.useEffect(() => {
2477
2706
  if (open) {
2478
2707
  setQuery("");
2479
2708
  setActive(0);
2480
2709
  }
2481
2710
  }, [open]);
2482
2711
  useFocusTrap(paletteRef, open && mounted);
2483
- React36__namespace.default.useEffect(() => {
2712
+ React37__namespace.default.useEffect(() => {
2484
2713
  if (!open) return void 0;
2485
2714
  const onKey = (e) => {
2486
2715
  if (e.key === "Escape") {
@@ -2492,7 +2721,7 @@ function CommandPalette({
2492
2721
  return () => document.removeEventListener("keydown", onKey);
2493
2722
  }, [open, onClose]);
2494
2723
  const q = query.trim().toLowerCase();
2495
- const filtered = React36__namespace.default.useMemo(() => commands.filter(
2724
+ const filtered = React37__namespace.default.useMemo(() => commands.filter(
2496
2725
  (c) => !q || c.label.toLowerCase().includes(q) || (c.keywords || "").toLowerCase().includes(q) || (c.group || "").toLowerCase().includes(q)
2497
2726
  ), [commands, q]);
2498
2727
  const groups = [];
@@ -2507,7 +2736,7 @@ function CommandPalette({
2507
2736
  g.items.push(c);
2508
2737
  flat.push(c);
2509
2738
  });
2510
- React36__namespace.default.useEffect(() => {
2739
+ React37__namespace.default.useEffect(() => {
2511
2740
  setActive(0);
2512
2741
  }, [query]);
2513
2742
  const run = (cmd) => {
@@ -2527,7 +2756,7 @@ function CommandPalette({
2527
2756
  if (cmd) run(cmd);
2528
2757
  }
2529
2758
  }
2530
- React36__namespace.default.useEffect(() => {
2759
+ React37__namespace.default.useEffect(() => {
2531
2760
  const node = listRef.current?.querySelector('[data-active="true"]');
2532
2761
  if (node) node.scrollIntoView({ block: "nearest" });
2533
2762
  }, [active]);
@@ -2703,13 +2932,13 @@ function Currency({
2703
2932
  const prec = precision != null ? precision : meta.precision;
2704
2933
  const sym = symbol != null ? symbol : meta.symbol;
2705
2934
  const cur = code != null ? code : meta.code;
2706
- const autoId = React36__namespace.default.useId();
2935
+ const autoId = React37__namespace.default.useId();
2707
2936
  const fieldId = id || autoId;
2708
2937
  const invalid = Boolean(error);
2709
2938
  const controlled = value !== void 0;
2710
- const [internal, setInternal] = React36__namespace.default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
2939
+ const [internal, setInternal] = React37__namespace.default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
2711
2940
  const shown = controlled ? clampPrecision(String(value ?? ""), prec) : internal;
2712
- React36__namespace.default.useEffect(() => {
2941
+ React37__namespace.default.useEffect(() => {
2713
2942
  if (!controlled) return;
2714
2943
  const raw = String(value ?? "");
2715
2944
  if (shown !== raw) {
@@ -2896,6 +3125,8 @@ function Select({
2896
3125
  loading = false,
2897
3126
  emptyText = "No results found",
2898
3127
  name,
3128
+ virtualized = false,
3129
+ overscan = 8,
2899
3130
  id,
2900
3131
  className = "",
2901
3132
  onClick,
@@ -2903,32 +3134,54 @@ function Select({
2903
3134
  ...rest
2904
3135
  }) {
2905
3136
  const __twcStyles = useScopedStyles("twc-select-styles", SELECT_CSS);
2906
- const bufferRef = React36__namespace.default.useRef("");
2907
- const bufferTimerRef = React36__namespace.default.useRef(null);
2908
- const groups = React36__namespace.default.useMemo(() => normalizeGroups2(options), [options]);
2909
- const flat = React36__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
2910
- const autoId = React36__namespace.default.useId();
3137
+ const bufferRef = React37__namespace.default.useRef("");
3138
+ const bufferTimerRef = React37__namespace.default.useRef(null);
3139
+ const groups = React37__namespace.default.useMemo(() => normalizeGroups2(options), [options]);
3140
+ const flat = React37__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
3141
+ const autoId = React37__namespace.default.useId();
2911
3142
  const fieldId = id || autoId;
2912
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
3143
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
2913
3144
  const current = value !== void 0 ? value : internal;
2914
- const [open, setOpen] = React36__namespace.default.useState(false);
2915
- const [render, setRender] = React36__namespace.default.useState(false);
2916
- const [active, setActive] = React36__namespace.default.useState(0);
2917
- const [coords, setCoords] = React36__namespace.default.useState(null);
2918
- const [query, setQuery] = React36__namespace.default.useState("");
2919
- const wrapRef = React36__namespace.default.useRef(null);
2920
- const triggerRef = React36__namespace.default.useRef(null);
2921
- const popRef = React36__namespace.default.useRef(null);
2922
- const listRef = React36__namespace.default.useRef(null);
2923
- const activeRef = React36__namespace.default.useRef(null);
2924
- const searchRef = React36__namespace.default.useRef(null);
3145
+ const [open, setOpen] = React37__namespace.default.useState(false);
3146
+ const [render, setRender] = React37__namespace.default.useState(false);
3147
+ const [active, setActive] = React37__namespace.default.useState(0);
3148
+ const [coords, setCoords] = React37__namespace.default.useState(null);
3149
+ const [query, setQuery] = React37__namespace.default.useState("");
3150
+ const [scrollTop, setScrollTop] = React37__namespace.default.useState(0);
3151
+ const [listH, setListH] = React37__namespace.default.useState(260);
3152
+ const wrapRef = React37__namespace.default.useRef(null);
3153
+ const triggerRef = React37__namespace.default.useRef(null);
3154
+ const popRef = React37__namespace.default.useRef(null);
3155
+ const listRef = React37__namespace.default.useRef(null);
3156
+ const activeRef = React37__namespace.default.useRef(null);
3157
+ const searchRef = React37__namespace.default.useRef(null);
2925
3158
  const showSearch = searchable === void 0 ? flat.length > 5 : searchable;
2926
- const fGroups = React36__namespace.default.useMemo(() => {
3159
+ const fGroups = React37__namespace.default.useMemo(() => {
2927
3160
  const q = query.trim().toLowerCase();
2928
3161
  if (!q) return groups;
2929
3162
  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);
2930
3163
  }, [groups, query]);
2931
- const visible = React36__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
3164
+ const visible = React37__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
3165
+ const rowH = React37__namespace.default.useMemo(() => visible.some((o) => o.description) ? 48 : 36, [visible]);
3166
+ const GROUP_H = 30;
3167
+ const { rows, totalH } = React37__namespace.default.useMemo(() => {
3168
+ if (!virtualized) return { rows: [], totalH: 0 };
3169
+ const rows2 = [];
3170
+ let off = 0;
3171
+ let optIdx = -1;
3172
+ fGroups.forEach((g, gi) => {
3173
+ if (g.group) {
3174
+ rows2.push({ kind: "group", gi, label: g.group, top: off, h: GROUP_H });
3175
+ off += GROUP_H;
3176
+ }
3177
+ g.options.forEach((o) => {
3178
+ optIdx += 1;
3179
+ rows2.push({ kind: "option", o, idx: optIdx, top: off, h: rowH });
3180
+ off += rowH;
3181
+ });
3182
+ });
3183
+ return { rows: rows2, totalH: off };
3184
+ }, [virtualized, fGroups, rowH]);
2932
3185
  const selected = flat.find((o) => o.value === current);
2933
3186
  const nextEnabled = (from, dir) => {
2934
3187
  let i = from + dir;
@@ -2938,7 +3191,7 @@ function Select({
2938
3191
  }
2939
3192
  return from;
2940
3193
  };
2941
- const place = React36__namespace.default.useCallback(() => {
3194
+ const place = React37__namespace.default.useCallback(() => {
2942
3195
  const el = triggerRef.current;
2943
3196
  if (!el) return;
2944
3197
  const r = el.getBoundingClientRect();
@@ -2954,7 +3207,7 @@ function Select({
2954
3207
  flip
2955
3208
  });
2956
3209
  }, [placement, minWidth, matchTriggerWidth]);
2957
- React36__namespace.default.useEffect(() => {
3210
+ React37__namespace.default.useEffect(() => {
2958
3211
  if (!open || !portal) return;
2959
3212
  place();
2960
3213
  const onMove = () => place();
@@ -2965,7 +3218,7 @@ function Select({
2965
3218
  window.removeEventListener("resize", onMove);
2966
3219
  };
2967
3220
  }, [open, portal, place]);
2968
- React36__namespace.default.useEffect(() => {
3221
+ React37__namespace.default.useEffect(() => {
2969
3222
  if (!open) return;
2970
3223
  const idx = flat.findIndex((o) => o.value === current);
2971
3224
  setActive(idx >= 0 ? idx : 0);
@@ -2981,13 +3234,32 @@ function Select({
2981
3234
  document.addEventListener("mousedown", onDown);
2982
3235
  return () => document.removeEventListener("mousedown", onDown);
2983
3236
  }, [open]);
2984
- React36__namespace.default.useEffect(() => {
3237
+ React37__namespace.default.useEffect(() => {
2985
3238
  setActive(0);
2986
3239
  }, [query]);
2987
- React36__namespace.default.useEffect(() => {
2988
- if (open) ensureVisible2(listRef.current, activeRef.current);
2989
- }, [active, open]);
2990
- React36__namespace.default.useEffect(() => {
3240
+ React37__namespace.default.useEffect(() => {
3241
+ if (!open || !virtualized) return;
3242
+ const el = listRef.current;
3243
+ if (el && el.clientHeight) setListH(el.clientHeight);
3244
+ }, [open, virtualized, render]);
3245
+ React37__namespace.default.useEffect(() => {
3246
+ if (!open) return;
3247
+ if (!virtualized) {
3248
+ ensureVisible2(listRef.current, activeRef.current);
3249
+ return;
3250
+ }
3251
+ const el = listRef.current;
3252
+ if (!el) return;
3253
+ const row = rows.find((r) => r.kind === "option" && r.idx === active);
3254
+ if (!row) return;
3255
+ const vh = el.clientHeight || listH;
3256
+ let next = el.scrollTop;
3257
+ if (row.top < el.scrollTop) next = row.top;
3258
+ else if (row.top + row.h > el.scrollTop + vh) next = row.top + row.h - vh;
3259
+ if (next !== el.scrollTop) el.scrollTop = next;
3260
+ setScrollTop(next);
3261
+ }, [active, open, virtualized, rows, listH]);
3262
+ React37__namespace.default.useEffect(() => {
2991
3263
  if (open) {
2992
3264
  setRender(true);
2993
3265
  return;
@@ -2995,8 +3267,8 @@ function Select({
2995
3267
  const t = setTimeout(() => setRender(false), 170);
2996
3268
  return () => clearTimeout(t);
2997
3269
  }, [open]);
2998
- const prevOpen = React36__namespace.default.useRef(false);
2999
- React36__namespace.default.useEffect(() => {
3270
+ const prevOpen = React37__namespace.default.useRef(false);
3271
+ React37__namespace.default.useEffect(() => {
3000
3272
  if (prevOpen.current && !open) {
3001
3273
  const ae = typeof document !== "undefined" ? document.activeElement : null;
3002
3274
  if (popRef.current && ae && popRef.current.contains(ae)) triggerRef.current?.focus();
@@ -3060,6 +3332,45 @@ function Select({
3060
3332
  const activeId = open && visible[active] ? optionId(active) : void 0;
3061
3333
  const descId = `${fieldId}-desc`;
3062
3334
  const describedBy = error || hint ? descId : void 0;
3335
+ const renderOption = (o, idx) => {
3336
+ const isSel = o.value === current;
3337
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3338
+ "button",
3339
+ {
3340
+ id: optionId(idx),
3341
+ type: "button",
3342
+ className: "twc-opt",
3343
+ role: "option",
3344
+ "aria-selected": isSel,
3345
+ ref: idx === active ? activeRef : null,
3346
+ disabled: o.disabled || void 0,
3347
+ "aria-disabled": o.disabled || void 0,
3348
+ "data-disabled": o.disabled || void 0,
3349
+ "data-selected": isSel || void 0,
3350
+ "data-active": idx === active || void 0,
3351
+ onMouseEnter: () => {
3352
+ if (!o.disabled) setActive(idx);
3353
+ },
3354
+ onClick: () => commit(o.value),
3355
+ children: [
3356
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-opt__main", children: [
3357
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__label", children: o.label }),
3358
+ o.description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__desc", children: o.description }) : null
3359
+ ] }),
3360
+ isSel ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__check", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.6", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null
3361
+ ]
3362
+ },
3363
+ o.value
3364
+ );
3365
+ };
3366
+ let vTop = 0, vBottom = 0, vShown = rows;
3367
+ if (virtualized && rows.length) {
3368
+ const winTop = scrollTop - overscan * rowH;
3369
+ const winBottom = scrollTop + listH + overscan * rowH;
3370
+ vShown = rows.filter((r) => r.top + r.h > winTop && r.top < winBottom);
3371
+ vTop = vShown.length ? vShown[0].top : 0;
3372
+ vBottom = vShown.length ? totalH - (vShown[vShown.length - 1].top + vShown[vShown.length - 1].h) : totalH;
3373
+ }
3063
3374
  let counter = -1;
3064
3375
  const popInner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3065
3376
  showSearch ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-pop__search", children: [
@@ -3087,43 +3398,19 @@ function Select({
3087
3398
  searchRef.current?.focus();
3088
3399
  }, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
3089
3400
  ] }) : null,
3090
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", ref: listRef, children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-pop__loading", role: "status", children: [
3401
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", ref: listRef, onScroll: virtualized ? (e) => setScrollTop(e.currentTarget.scrollTop) : void 0, children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-pop__loading", role: "status", children: [
3091
3402
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-pop__spinner", "aria-hidden": "true" }),
3092
3403
  "Loading\u2026"
3093
- ] }) : visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: emptyText }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React36__namespace.default.Fragment, { children: [
3404
+ ] }) : visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: emptyText }) : virtualized ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3405
+ vTop > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", style: { height: vTop } }) : null,
3406
+ vShown.map((r) => r.kind === "group" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: r.label }, `g${r.gi}`) : renderOption(r.o, r.idx)),
3407
+ vBottom > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", style: { height: vBottom } }) : null
3408
+ ] }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React37__namespace.default.Fragment, { children: [
3094
3409
  g.group ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: g.group }) : null,
3095
3410
  g.options.map((o) => {
3096
3411
  counter += 1;
3097
3412
  const idx = counter;
3098
- const isSel = o.value === current;
3099
- return /* @__PURE__ */ jsxRuntime.jsxs(
3100
- "button",
3101
- {
3102
- id: optionId(idx),
3103
- type: "button",
3104
- className: "twc-opt",
3105
- role: "option",
3106
- "aria-selected": isSel,
3107
- ref: idx === active ? activeRef : null,
3108
- disabled: o.disabled || void 0,
3109
- "aria-disabled": o.disabled || void 0,
3110
- "data-disabled": o.disabled || void 0,
3111
- "data-selected": isSel || void 0,
3112
- "data-active": idx === active || void 0,
3113
- onMouseEnter: () => {
3114
- if (!o.disabled) setActive(idx);
3115
- },
3116
- onClick: () => commit(o.value),
3117
- children: [
3118
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-opt__main", children: [
3119
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__label", children: o.label }),
3120
- o.description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__desc", children: o.description }) : null
3121
- ] }),
3122
- isSel ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__check", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.6", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null
3123
- ]
3124
- },
3125
- o.value
3126
- );
3413
+ return renderOption(o, idx);
3127
3414
  })
3128
3415
  ] }, gi)) }),
3129
3416
  /* @__PURE__ */ jsxRuntime.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"}` })
@@ -3273,21 +3560,21 @@ function CurrencyField({
3273
3560
  ...rest
3274
3561
  }) {
3275
3562
  const __twcStyles = useScopedStyles("twc-curf-styles", CURF_CSS);
3276
- const autoId = React36__namespace.default.useId();
3563
+ const autoId = React37__namespace.default.useId();
3277
3564
  const fieldId = id || autoId;
3278
3565
  const invalid = Boolean(error);
3279
3566
  const curControlled = currency !== void 0;
3280
- const [curInternal, setCurInternal] = React36__namespace.default.useState(defaultCurrency);
3567
+ const [curInternal, setCurInternal] = React37__namespace.default.useState(defaultCurrency);
3281
3568
  const cur = curControlled ? currency : curInternal;
3282
3569
  const meta = CURRENCIES[cur] || CURRENCIES.USD;
3283
3570
  const prec = meta.precision;
3284
3571
  const valControlled = value !== void 0;
3285
- const [valInternal, setValInternal] = React36__namespace.default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
3572
+ const [valInternal, setValInternal] = React37__namespace.default.useState(() => clampPrecision(String(defaultValue ?? ""), prec));
3286
3573
  const shown = valControlled ? clampPrecision(String(value ?? ""), prec) : valInternal;
3287
3574
  const descId = `${fieldId}-desc`;
3288
3575
  const describedBy = [error || hint ? descId : null, rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
3289
3576
  const ariaInvalid = invalid ? true : rest["aria-invalid"] ?? void 0;
3290
- React36__namespace.default.useEffect(() => {
3577
+ React37__namespace.default.useEffect(() => {
3291
3578
  if (!valControlled) {
3292
3579
  const clamped = clampPrecision(valInternal, prec);
3293
3580
  if (clamped !== valInternal) {
@@ -3303,7 +3590,7 @@ function CurrencyField({
3303
3590
  }
3304
3591
  }
3305
3592
  }, [prec, cur, shown, value, valControlled, valInternal]);
3306
- const options = React36__namespace.default.useMemo(() => {
3593
+ const options = React37__namespace.default.useMemo(() => {
3307
3594
  if (!currencies) return CURRENCY_OPTIONS;
3308
3595
  return currencies.map((c) => typeof c === "string" ? { value: c, label: `${c} \u2014 ${(CURRENCIES[c] || {}).label || c}` } : c);
3309
3596
  }, [currencies]);
@@ -3457,13 +3744,13 @@ function Input({
3457
3744
  }) {
3458
3745
  const __twcStyles = useScopedStyles("twc-field-styles", FIELD_CSS2);
3459
3746
  const __twcExtra = useScopedStyles("twc-input-extra-styles", INPUT_EXTRA_CSS);
3460
- const autoId = React36__namespace.default.useId();
3747
+ const autoId = React37__namespace.default.useId();
3461
3748
  const fieldId = id || autoId;
3462
3749
  const descId = `${fieldId}-desc`;
3463
3750
  const countId = `${fieldId}-count`;
3464
3751
  const invalid = Boolean(error);
3465
3752
  const countControlled = rest.value !== void 0;
3466
- const [len2, setLen] = React36__namespace.default.useState(() => String(rest.defaultValue ?? "").length);
3753
+ const [len2, setLen] = React37__namespace.default.useState(() => String(rest.defaultValue ?? "").length);
3467
3754
  const count = countControlled ? String(rest.value ?? "").length : len2;
3468
3755
  const max = rest.maxLength;
3469
3756
  const showCounter = showCount && max != null;
@@ -3475,7 +3762,7 @@ function Input({
3475
3762
  const ariaInvalid = invalid ? true : rest["aria-invalid"] ?? void 0;
3476
3763
  const describedBy = [error || hint ? descId : null, showCounter ? countId : null, rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
3477
3764
  const isPassword = type === "password";
3478
- const [revealed, setRevealed] = React36__namespace.default.useState(false);
3765
+ const [revealed, setRevealed] = React37__namespace.default.useState(false);
3479
3766
  const effectiveType = isPassword && revealed ? "text" : type;
3480
3767
  const suffix = rightIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-input__affix", children: rightIcon }) : isPassword ? /* @__PURE__ */ jsxRuntime.jsx(
3481
3768
  "button",
@@ -3669,6 +3956,8 @@ function MultiSelect({
3669
3956
  name,
3670
3957
  max,
3671
3958
  maxTagCount,
3959
+ virtualized = false,
3960
+ overscan = 8,
3672
3961
  id,
3673
3962
  className = "",
3674
3963
  onFocus,
@@ -3676,27 +3965,49 @@ function MultiSelect({
3676
3965
  ...rest
3677
3966
  }) {
3678
3967
  const __twcStyles = useScopedStyles("twc-ms-styles", MULTI_CSS);
3679
- const groups = React36__namespace.default.useMemo(() => normalizeGroups3(options), [options]);
3680
- const flat = React36__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
3681
- const autoId = React36__namespace.default.useId();
3968
+ const groups = React37__namespace.default.useMemo(() => normalizeGroups3(options), [options]);
3969
+ const flat = React37__namespace.default.useMemo(() => groups.flatMap((g) => g.options), [groups]);
3970
+ const autoId = React37__namespace.default.useId();
3682
3971
  const fieldId = id || autoId;
3683
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
3972
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
3684
3973
  const selected = value !== void 0 ? value : internal;
3685
- const [open, setOpen] = React36__namespace.default.useState(false);
3686
- const [query, setQuery] = React36__namespace.default.useState("");
3687
- const [active, setActive] = React36__namespace.default.useState(0);
3688
- const [coords, setCoords] = React36__namespace.default.useState(null);
3689
- const wrapRef = React36__namespace.default.useRef(null);
3690
- const controlRef = React36__namespace.default.useRef(null);
3691
- const inputRef = React36__namespace.default.useRef(null);
3692
- const popRef = React36__namespace.default.useRef(null);
3693
- const listRef = React36__namespace.default.useRef(null);
3694
- const activeRef = React36__namespace.default.useRef(null);
3695
- const fGroups = React36__namespace.default.useMemo(
3974
+ const [open, setOpen] = React37__namespace.default.useState(false);
3975
+ const [query, setQuery] = React37__namespace.default.useState("");
3976
+ const [active, setActive] = React37__namespace.default.useState(0);
3977
+ const [coords, setCoords] = React37__namespace.default.useState(null);
3978
+ const [scrollTop, setScrollTop] = React37__namespace.default.useState(0);
3979
+ const [listH, setListH] = React37__namespace.default.useState(260);
3980
+ const wrapRef = React37__namespace.default.useRef(null);
3981
+ const controlRef = React37__namespace.default.useRef(null);
3982
+ const inputRef = React37__namespace.default.useRef(null);
3983
+ const popRef = React37__namespace.default.useRef(null);
3984
+ const listRef = React37__namespace.default.useRef(null);
3985
+ const activeRef = React37__namespace.default.useRef(null);
3986
+ const fGroups = React37__namespace.default.useMemo(
3696
3987
  () => groups.map((g) => ({ group: g.group, options: g.options.filter((o) => matches2(o, query.trim())) })).filter((g) => g.options.length),
3697
3988
  [groups, query]
3698
3989
  );
3699
- const visible = React36__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
3990
+ const visible = React37__namespace.default.useMemo(() => fGroups.flatMap((g) => g.options), [fGroups]);
3991
+ const rowH = React37__namespace.default.useMemo(() => visible.some((o) => o.description) ? 48 : 36, [visible]);
3992
+ const GROUP_H = 30;
3993
+ const { rows, totalH } = React37__namespace.default.useMemo(() => {
3994
+ if (!virtualized) return { rows: [], totalH: 0 };
3995
+ const rows2 = [];
3996
+ let off = 0;
3997
+ let optIdx = -1;
3998
+ fGroups.forEach((g, gi) => {
3999
+ if (g.group) {
4000
+ rows2.push({ kind: "group", gi, label: g.group, top: off, h: GROUP_H });
4001
+ off += GROUP_H;
4002
+ }
4003
+ g.options.forEach((o) => {
4004
+ optIdx += 1;
4005
+ rows2.push({ kind: "option", o, idx: optIdx, top: off, h: rowH });
4006
+ off += rowH;
4007
+ });
4008
+ });
4009
+ return { rows: rows2, totalH: off };
4010
+ }, [virtualized, fGroups, rowH]);
3700
4011
  const capReached = max != null && (value !== void 0 ? value : internal).length >= max;
3701
4012
  const isOptDisabled = (o) => o.disabled || capReached && !(value !== void 0 ? value : internal).includes(o.value);
3702
4013
  const nextEnabled = (from, dir) => {
@@ -3707,7 +4018,7 @@ function MultiSelect({
3707
4018
  }
3708
4019
  return from;
3709
4020
  };
3710
- const place = React36__namespace.default.useCallback(() => {
4021
+ const place = React37__namespace.default.useCallback(() => {
3711
4022
  const el = controlRef.current;
3712
4023
  if (!el) return;
3713
4024
  const r = el.getBoundingClientRect();
@@ -3722,7 +4033,7 @@ function MultiSelect({
3722
4033
  flip
3723
4034
  });
3724
4035
  }, [placement, minWidth]);
3725
- React36__namespace.default.useEffect(() => {
4036
+ React37__namespace.default.useEffect(() => {
3726
4037
  if (!open || !portal) return;
3727
4038
  place();
3728
4039
  const onMove = () => place();
@@ -3733,7 +4044,7 @@ function MultiSelect({
3733
4044
  window.removeEventListener("resize", onMove);
3734
4045
  };
3735
4046
  }, [open, portal, place]);
3736
- React36__namespace.default.useEffect(() => {
4047
+ React37__namespace.default.useEffect(() => {
3737
4048
  if (!open) return;
3738
4049
  const onDown = (e) => {
3739
4050
  if (wrapRef.current && wrapRef.current.contains(e.target)) return;
@@ -3744,12 +4055,31 @@ function MultiSelect({
3744
4055
  document.addEventListener("mousedown", onDown);
3745
4056
  return () => document.removeEventListener("mousedown", onDown);
3746
4057
  }, [open]);
3747
- React36__namespace.default.useEffect(() => {
4058
+ React37__namespace.default.useEffect(() => {
3748
4059
  setActive(0);
3749
4060
  }, [query]);
3750
- React36__namespace.default.useEffect(() => {
3751
- if (open) ensureVisible3(listRef.current, activeRef.current);
3752
- }, [active, open]);
4061
+ React37__namespace.default.useEffect(() => {
4062
+ if (!open || !virtualized) return;
4063
+ const el = listRef.current;
4064
+ if (el && el.clientHeight) setListH(el.clientHeight);
4065
+ }, [open, virtualized]);
4066
+ React37__namespace.default.useEffect(() => {
4067
+ if (!open) return;
4068
+ if (!virtualized) {
4069
+ ensureVisible3(listRef.current, activeRef.current);
4070
+ return;
4071
+ }
4072
+ const el = listRef.current;
4073
+ if (!el) return;
4074
+ const row = rows.find((r) => r.kind === "option" && r.idx === active);
4075
+ if (!row) return;
4076
+ const vh = el.clientHeight || listH;
4077
+ let next = el.scrollTop;
4078
+ if (row.top < el.scrollTop) next = row.top;
4079
+ else if (row.top + row.h > el.scrollTop + vh) next = row.top + row.h - vh;
4080
+ if (next !== el.scrollTop) el.scrollTop = next;
4081
+ setScrollTop(next);
4082
+ }, [active, open, virtualized, rows, listH]);
3753
4083
  function commit(next) {
3754
4084
  if (value === void 0) setInternal(next);
3755
4085
  onChange?.(next);
@@ -3786,48 +4116,74 @@ function MultiSelect({
3786
4116
  const activeId = open && visible[active] ? optionId(active) : void 0;
3787
4117
  const descId = `${fieldId}-desc`;
3788
4118
  const describedBy = error || hint ? descId : void 0;
3789
- let counter = -1;
3790
- const popInner = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__list", id: listboxId, ref: listRef, role: "listbox", "aria-multiselectable": "true", children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-pop__loading", role: "status", children: [
3791
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-pop__spinner", "aria-hidden": "true" }),
3792
- "Loading\u2026"
3793
- ] }) : visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: emptyText }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React36__namespace.default.Fragment, { children: [
3794
- g.group ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: g.group }) : null,
3795
- g.options.map((o) => {
3796
- counter += 1;
3797
- const idx = counter;
3798
- const isSel = selected.includes(o.value);
3799
- const optDisabled = isOptDisabled(o);
3800
- return /* @__PURE__ */ jsxRuntime.jsxs(
3801
- "button",
3802
- {
3803
- id: optionId(idx),
3804
- type: "button",
3805
- className: "twc-opt",
3806
- role: "option",
3807
- "aria-selected": isSel,
3808
- ref: idx === active ? activeRef : null,
3809
- disabled: optDisabled || void 0,
3810
- "aria-disabled": optDisabled || void 0,
3811
- "data-disabled": optDisabled || void 0,
3812
- "data-selected": isSel || void 0,
3813
- "data-active": idx === active || void 0,
3814
- onMouseEnter: () => {
3815
- if (!optDisabled) setActive(idx);
3816
- },
3817
- onMouseDown: (e) => e.preventDefault(),
3818
- onClick: () => toggle(o.value),
3819
- children: [
3820
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__box", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) }) }),
3821
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-opt__main", children: [
3822
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__label", children: o.label }),
3823
- o.description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__desc", children: o.description }) : null
3824
- ] })
3825
- ]
4119
+ const renderOption = (o, idx) => {
4120
+ const isSel = selected.includes(o.value);
4121
+ const optDisabled = isOptDisabled(o);
4122
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4123
+ "button",
4124
+ {
4125
+ id: optionId(idx),
4126
+ type: "button",
4127
+ className: "twc-opt",
4128
+ role: "option",
4129
+ "aria-selected": isSel,
4130
+ ref: idx === active ? activeRef : null,
4131
+ disabled: optDisabled || void 0,
4132
+ "aria-disabled": optDisabled || void 0,
4133
+ "data-disabled": optDisabled || void 0,
4134
+ "data-selected": isSel || void 0,
4135
+ "data-active": idx === active || void 0,
4136
+ onMouseEnter: () => {
4137
+ if (!optDisabled) setActive(idx);
3826
4138
  },
3827
- o.value
3828
- );
3829
- })
3830
- ] }, gi)) });
4139
+ onMouseDown: (e) => e.preventDefault(),
4140
+ onClick: () => toggle(o.value),
4141
+ children: [
4142
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__box", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) }) }),
4143
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-opt__main", children: [
4144
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__label", children: o.label }),
4145
+ o.description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-opt__desc", children: o.description }) : null
4146
+ ] })
4147
+ ]
4148
+ },
4149
+ o.value
4150
+ );
4151
+ };
4152
+ let vTop = 0, vBottom = 0, vShown = rows;
4153
+ if (virtualized && rows.length) {
4154
+ const winTop = scrollTop - overscan * rowH;
4155
+ const winBottom = scrollTop + listH + overscan * rowH;
4156
+ vShown = rows.filter((r) => r.top + r.h > winTop && r.top < winBottom);
4157
+ vTop = vShown.length ? vShown[0].top : 0;
4158
+ vBottom = vShown.length ? totalH - (vShown[vShown.length - 1].top + vShown[vShown.length - 1].h) : totalH;
4159
+ }
4160
+ let counter = -1;
4161
+ const popInner = /* @__PURE__ */ jsxRuntime.jsx(
4162
+ "div",
4163
+ {
4164
+ className: "twc-pop__list",
4165
+ id: listboxId,
4166
+ ref: listRef,
4167
+ role: "listbox",
4168
+ "aria-multiselectable": "true",
4169
+ onScroll: virtualized ? (e) => setScrollTop(e.currentTarget.scrollTop) : void 0,
4170
+ children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-pop__loading", role: "status", children: [
4171
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-pop__spinner", "aria-hidden": "true" }),
4172
+ "Loading\u2026"
4173
+ ] }) : visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__empty", children: emptyText }) : virtualized ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4174
+ vTop > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", style: { height: vTop } }) : null,
4175
+ vShown.map((r) => r.kind === "group" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: r.label }, `g${r.gi}`) : renderOption(r.o, r.idx)),
4176
+ vBottom > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", style: { height: vBottom } }) : null
4177
+ ] }) : fGroups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React37__namespace.default.Fragment, { children: [
4178
+ g.group ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-pop__group", children: g.group }) : null,
4179
+ g.options.map((o) => {
4180
+ counter += 1;
4181
+ const idx = counter;
4182
+ return renderOption(o, idx);
4183
+ })
4184
+ ] }, gi))
4185
+ }
4186
+ );
3831
4187
  const RD = { createPortal: typeof reactDom.createPortal === "function" ? reactDom.createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
3832
4188
  const canPortal = portal && RD && RD.createPortal;
3833
4189
  let popEl = null;
@@ -4020,7 +4376,7 @@ function Pagination({
4020
4376
  }
4021
4377
  const jumperEnabled = showPageJumper ?? showJumper;
4022
4378
  const __twcStyles = useScopedStyles("twc-pagination-styles", PAGINATION_CSS);
4023
- const [internal, setInternal] = React36__namespace.default.useState(defaultPage);
4379
+ const [internal, setInternal] = React37__namespace.default.useState(defaultPage);
4024
4380
  const page = pageProp !== void 0 ? pageProp : internal;
4025
4381
  const pages = buildPages(page, total, siblings, boundaries);
4026
4382
  const go = (p) => {
@@ -4028,7 +4384,7 @@ function Pagination({
4028
4384
  if (pageProp === void 0) setInternal(p);
4029
4385
  onChange?.(p);
4030
4386
  };
4031
- const [jump, setJump] = React36__namespace.default.useState("");
4387
+ const [jump, setJump] = React37__namespace.default.useState("");
4032
4388
  const submitJump = () => {
4033
4389
  const n = parseInt(jump, 10);
4034
4390
  if (!Number.isNaN(n)) go(Math.min(Math.max(n, 1), total));
@@ -4111,13 +4467,13 @@ function Tooltip({
4111
4467
  ...rest
4112
4468
  }) {
4113
4469
  const __twcStyles = useScopedStyles("twc-tooltip-styles", TOOLTIP_CSS);
4114
- const id = React36__namespace.default.useId();
4115
- const [show, setShow] = React36__namespace.default.useState(false);
4116
- const [coords, setCoords] = React36__namespace.default.useState(null);
4117
- const timer = React36__namespace.default.useRef(null);
4118
- const closeTimer = React36__namespace.default.useRef(null);
4119
- const wrapRef = React36__namespace.default.useRef(null);
4120
- const tipRef = React36__namespace.default.useRef(null);
4470
+ const id = React37__namespace.default.useId();
4471
+ const [show, setShow] = React37__namespace.default.useState(false);
4472
+ const [coords, setCoords] = React37__namespace.default.useState(null);
4473
+ const timer = React37__namespace.default.useRef(null);
4474
+ const closeTimer = React37__namespace.default.useRef(null);
4475
+ const wrapRef = React37__namespace.default.useRef(null);
4476
+ const tipRef = React37__namespace.default.useRef(null);
4121
4477
  const open = () => {
4122
4478
  clearTimeout(closeTimer.current);
4123
4479
  clearTimeout(timer.current);
@@ -4131,11 +4487,11 @@ function Tooltip({
4131
4487
  const cancelClose = () => {
4132
4488
  clearTimeout(closeTimer.current);
4133
4489
  };
4134
- React36__namespace.default.useEffect(() => () => {
4490
+ React37__namespace.default.useEffect(() => () => {
4135
4491
  clearTimeout(timer.current);
4136
4492
  clearTimeout(closeTimer.current);
4137
4493
  }, []);
4138
- const place = React36__namespace.default.useCallback(() => {
4494
+ const place = React37__namespace.default.useCallback(() => {
4139
4495
  const el = wrapRef.current;
4140
4496
  if (!el) return;
4141
4497
  const r = el.getBoundingClientRect();
@@ -4158,10 +4514,10 @@ function Tooltip({
4158
4514
  else if (side === "right") setCoords({ ...base, top: clampY(cy), left: Math.round(r.right + gap) });
4159
4515
  else setCoords({ ...base, left: clampX(cx), bottom: Math.round(vh - r.top + gap) });
4160
4516
  }, [placement]);
4161
- React36__namespace.default.useEffect(() => {
4517
+ React37__namespace.default.useEffect(() => {
4162
4518
  place();
4163
4519
  }, [place]);
4164
- React36__namespace.default.useEffect(() => {
4520
+ React37__namespace.default.useEffect(() => {
4165
4521
  if (!show) return void 0;
4166
4522
  place();
4167
4523
  const onMove = () => place();
@@ -4172,7 +4528,7 @@ function Tooltip({
4172
4528
  window.removeEventListener("resize", onMove);
4173
4529
  };
4174
4530
  }, [show, place]);
4175
- React36__namespace.default.useEffect(() => {
4531
+ React37__namespace.default.useEffect(() => {
4176
4532
  if (!show) return;
4177
4533
  const onKeyDown = (e) => {
4178
4534
  if (e.key === "Escape") {
@@ -4184,7 +4540,7 @@ function Tooltip({
4184
4540
  return () => document.removeEventListener("keydown", onKeyDown);
4185
4541
  }, [show]);
4186
4542
  const describedBy = show ? id : void 0;
4187
- const trigger = React36__namespace.default.isValidElement(children) && children.type !== React36__namespace.default.Fragment ? React36__namespace.default.cloneElement(children, {
4543
+ const trigger = React37__namespace.default.isValidElement(children) && children.type !== React37__namespace.default.Fragment ? React37__namespace.default.cloneElement(children, {
4188
4544
  "aria-describedby": [children.props["aria-describedby"], describedBy].filter(Boolean).join(" ") || void 0
4189
4545
  }) : /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-describedby": describedBy, children });
4190
4546
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -4788,9 +5144,9 @@ function runDatatableQuery(rows, query, options = {}) {
4788
5144
  return { rows: page, total, filtered: out };
4789
5145
  }
4790
5146
  function useFloating() {
4791
- const [pos, setPos] = React36__namespace.default.useState(null);
4792
- const cfg = React36__namespace.default.useRef(null);
4793
- const place = React36__namespace.default.useCallback(() => {
5147
+ const [pos, setPos] = React37__namespace.default.useState(null);
5148
+ const cfg = React37__namespace.default.useRef(null);
5149
+ const place = React37__namespace.default.useCallback(() => {
4794
5150
  const c = cfg.current;
4795
5151
  if (!c || !c.el || !c.el.isConnected) return null;
4796
5152
  const r = c.el.getBoundingClientRect();
@@ -4801,17 +5157,17 @@ function useFloating() {
4801
5157
  const top = r.bottom + 6;
4802
5158
  return { top, left, width: c.width, anchorX: r.left + r.width / 2, maxHeight: Math.max(180, vh - top - M) };
4803
5159
  }, []);
4804
- const open = React36__namespace.default.useCallback((el, align = "left", width = 220) => {
5160
+ const open = React37__namespace.default.useCallback((el, align = "left", width = 220) => {
4805
5161
  cfg.current = { el, align, width };
4806
5162
  const p = place();
4807
5163
  if (p) setPos(p);
4808
5164
  }, [place]);
4809
- const close = React36__namespace.default.useCallback(() => {
5165
+ const close = React37__namespace.default.useCallback(() => {
4810
5166
  cfg.current = null;
4811
5167
  setPos(null);
4812
5168
  }, []);
4813
5169
  const isOpen = pos != null;
4814
- React36__namespace.default.useEffect(() => {
5170
+ React37__namespace.default.useEffect(() => {
4815
5171
  if (!isOpen) return void 0;
4816
5172
  const update = () => {
4817
5173
  const p = place();
@@ -4835,9 +5191,9 @@ function Caret({ pos }) {
4835
5191
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__caret", style: { left } });
4836
5192
  }
4837
5193
  function EditCell({ col, value, options, onChange, onCommit, onCommitValue, onCancel, onKeyDown }) {
4838
- const ref = React36__namespace.default.useRef(null);
5194
+ const ref = React37__namespace.default.useRef(null);
4839
5195
  const isSelect = col.editType === "select" || options && col.editType !== "text";
4840
- React36__namespace.default.useEffect(() => {
5196
+ React37__namespace.default.useEffect(() => {
4841
5197
  if (isSelect) {
4842
5198
  const t = setTimeout(() => ref.current?.querySelector(".twc-sel__trigger")?.click(), 0);
4843
5199
  return () => clearTimeout(t);
@@ -5001,6 +5357,9 @@ function Datatable({
5001
5357
  density: densityProp = "comfortable",
5002
5358
  pageSize = 10,
5003
5359
  pageSizeOptions = [5, 10, 25, 50],
5360
+ page,
5361
+ onPageChange,
5362
+ onPageSizeChange,
5004
5363
  height = 440,
5005
5364
  serverMode = false,
5006
5365
  rowCount,
@@ -5042,7 +5401,7 @@ function Datatable({
5042
5401
  ...rest
5043
5402
  }) {
5044
5403
  const __twcStyles = useScopedStyles("twc-dt-styles", DT_CSS);
5045
- const cols = React36__namespace.default.useMemo(() => {
5404
+ const cols = React37__namespace.default.useMemo(() => {
5046
5405
  const out = columns.map((c) => {
5047
5406
  const isActions = c.type === "actions";
5048
5407
  return {
@@ -5077,7 +5436,7 @@ function Datatable({
5077
5436
  }
5078
5437
  return out;
5079
5438
  }, [columns, rowPinning]);
5080
- const _autoKey = React36__namespace.default.useRef();
5439
+ const _autoKey = React37__namespace.default.useRef();
5081
5440
  if (!_autoKey.current) _autoKey.current = { map: /* @__PURE__ */ new WeakMap(), n: 0 };
5082
5441
  const keyOf = rowKey || ((r, i) => {
5083
5442
  if (r != null && r.id != null) return r.id;
@@ -5092,17 +5451,17 @@ function Datatable({
5092
5451
  }
5093
5452
  return i;
5094
5453
  });
5095
- const [sort, setSort] = React36__namespace.default.useState(null);
5096
- const [filters, setFilters] = React36__namespace.default.useState([]);
5097
- const [hidden, setHidden] = React36__namespace.default.useState(() => /* @__PURE__ */ new Set());
5098
- const [showRowNum, setShowRowNum] = React36__namespace.default.useState(rowNumbers);
5099
- const [wrapped, setWrapped] = React36__namespace.default.useState(() => new Set((columns || []).filter((c) => c.wrapText).map((c) => c.field)));
5454
+ const [sort, setSort] = React37__namespace.default.useState(null);
5455
+ const [filters, setFilters] = React37__namespace.default.useState([]);
5456
+ const [hidden, setHidden] = React37__namespace.default.useState(() => /* @__PURE__ */ new Set());
5457
+ const [showRowNum, setShowRowNum] = React37__namespace.default.useState(rowNumbers);
5458
+ const [wrapped, setWrapped] = React37__namespace.default.useState(() => new Set((columns || []).filter((c) => c.wrapText).map((c) => c.field)));
5100
5459
  const toggleWrap = (field) => setWrapped((w) => {
5101
5460
  const n = new Set(w);
5102
5461
  n.has(field) ? n.delete(field) : n.add(field);
5103
5462
  return n;
5104
5463
  });
5105
- const [pins, setPins] = React36__namespace.default.useState(() => {
5464
+ const [pins, setPins] = React37__namespace.default.useState(() => {
5106
5465
  const left = [], right = [];
5107
5466
  columns.forEach((c) => {
5108
5467
  if (c.pinned === "left") left.push(c.field);
@@ -5110,34 +5469,47 @@ function Datatable({
5110
5469
  });
5111
5470
  return { left, right };
5112
5471
  });
5113
- const [density, setDensity] = React36__namespace.default.useState(densityProp);
5114
- const [quick, setQuick] = React36__namespace.default.useState("");
5115
- const [selected, setSelected] = React36__namespace.default.useState(() => /* @__PURE__ */ new Set());
5116
- const [activeRow, setActiveRow] = React36__namespace.default.useState(null);
5117
- const [activeCell, setActiveCell] = React36__namespace.default.useState(null);
5118
- const [page, setPage] = React36__namespace.default.useState(0);
5119
- const [rowsPerPage, setRowsPerPage] = React36__namespace.default.useState(pageSize > 0 ? pageSize : 10);
5120
- const [colQuery, setColQuery] = React36__namespace.default.useState("");
5121
- const [widths, setWidths] = React36__namespace.default.useState({});
5122
- const [order, setOrder] = React36__namespace.default.useState(() => columns.map((c) => c.field));
5123
- const [drag, setDrag] = React36__namespace.default.useState({ from: null, over: null, after: false });
5124
- const [aggOn, setAggOn] = React36__namespace.default.useState(showAggregation);
5125
- const [focus, setFocus] = React36__namespace.default.useState({ r: 0, c: 0 });
5126
- const gridRef = React36__namespace.default.useRef(null);
5127
- const [groupBy, setGroupBy] = React36__namespace.default.useState(rowGrouping || []);
5128
- const [collapsed, setCollapsed] = React36__namespace.default.useState(() => /* @__PURE__ */ new Set());
5129
- const [pinnedRows, setPinnedRows] = React36__namespace.default.useState({ top: [], bottom: [] });
5130
- const [headH, setHeadH] = React36__namespace.default.useState(41);
5131
- const theadRef = React36__namespace.default.useRef(null);
5132
- const [rowOrder, setRowOrder] = React36__namespace.default.useState(null);
5133
- const [rowHeights, setRowHeights] = React36__namespace.default.useState({});
5134
- const [rowDrag, setRowDrag] = React36__namespace.default.useState({ from: null, over: null, after: false });
5135
- const [rowGrab, setRowGrab] = React36__namespace.default.useState(null);
5136
- const [reorderMsg, setReorderMsg] = React36__namespace.default.useState("");
5137
- const rowFocusRef = React36__namespace.default.useRef(null);
5138
- const rootRef = React36__namespace.default.useRef(null);
5139
- const [compact, setCompact] = React36__namespace.default.useState(false);
5140
- React36__namespace.default.useEffect(() => {
5472
+ const [density, setDensity] = React37__namespace.default.useState(densityProp);
5473
+ const [quick, setQuick] = React37__namespace.default.useState("");
5474
+ const [selected, setSelected] = React37__namespace.default.useState(() => /* @__PURE__ */ new Set());
5475
+ const [activeRow, setActiveRow] = React37__namespace.default.useState(null);
5476
+ const [activeCell, setActiveCell] = React37__namespace.default.useState(null);
5477
+ const [internalPage, setInternalPage] = React37__namespace.default.useState(0);
5478
+ const [internalRpp, setInternalRpp] = React37__namespace.default.useState(pageSize > 0 ? pageSize : 10);
5479
+ const pageControlled = page !== void 0;
5480
+ const pageSizeControlled = onPageSizeChange !== void 0;
5481
+ const pageVal = pageControlled ? page : internalPage;
5482
+ const sizeVal = pageSizeControlled ? pageSize > 0 ? pageSize : 10 : internalRpp;
5483
+ const commitPage = (next) => {
5484
+ onPageChange?.(next);
5485
+ if (!pageControlled) setInternalPage(next);
5486
+ };
5487
+ const commitPageSize = (next) => {
5488
+ onPageSizeChange?.(next);
5489
+ if (!pageSizeControlled) setInternalRpp(next);
5490
+ commitPage(0);
5491
+ };
5492
+ const [colQuery, setColQuery] = React37__namespace.default.useState("");
5493
+ const [widths, setWidths] = React37__namespace.default.useState({});
5494
+ const [order, setOrder] = React37__namespace.default.useState(() => columns.map((c) => c.field));
5495
+ const [drag, setDrag] = React37__namespace.default.useState({ from: null, over: null, after: false });
5496
+ const [aggOn, setAggOn] = React37__namespace.default.useState(showAggregation);
5497
+ const [focus, setFocus] = React37__namespace.default.useState({ r: 0, c: 0 });
5498
+ const gridRef = React37__namespace.default.useRef(null);
5499
+ const [groupBy, setGroupBy] = React37__namespace.default.useState(rowGrouping || []);
5500
+ const [collapsed, setCollapsed] = React37__namespace.default.useState(() => /* @__PURE__ */ new Set());
5501
+ const [pinnedRows, setPinnedRows] = React37__namespace.default.useState({ top: [], bottom: [] });
5502
+ const [headH, setHeadH] = React37__namespace.default.useState(41);
5503
+ const theadRef = React37__namespace.default.useRef(null);
5504
+ const [rowOrder, setRowOrder] = React37__namespace.default.useState(null);
5505
+ const [rowHeights, setRowHeights] = React37__namespace.default.useState({});
5506
+ const [rowDrag, setRowDrag] = React37__namespace.default.useState({ from: null, over: null, after: false });
5507
+ const [rowGrab, setRowGrab] = React37__namespace.default.useState(null);
5508
+ const [reorderMsg, setReorderMsg] = React37__namespace.default.useState("");
5509
+ const rowFocusRef = React37__namespace.default.useRef(null);
5510
+ const rootRef = React37__namespace.default.useRef(null);
5511
+ const [compact, setCompact] = React37__namespace.default.useState(false);
5512
+ React37__namespace.default.useEffect(() => {
5141
5513
  const el = rootRef.current;
5142
5514
  if (!el) return void 0;
5143
5515
  const measure = () => setCompact((el.clientWidth || 0) < 720);
@@ -5150,11 +5522,11 @@ function Datatable({
5150
5522
  else if (typeof window !== "undefined") window.removeEventListener("resize", measure);
5151
5523
  };
5152
5524
  }, []);
5153
- const scrollRef = React36__namespace.default.useRef(null);
5154
- const [scrollTop, setScrollTop] = React36__namespace.default.useState(0);
5155
- const [viewportH, setViewportH] = React36__namespace.default.useState(0);
5156
- const [pivotOn, setPivotOn] = React36__namespace.default.useState(pivotMode);
5157
- const [aggConfig, setAggConfig] = React36__namespace.default.useState(() => {
5525
+ const scrollRef = React37__namespace.default.useRef(null);
5526
+ const [scrollTop, setScrollTop] = React37__namespace.default.useState(0);
5527
+ const [viewportH, setViewportH] = React37__namespace.default.useState(0);
5528
+ const [pivotOn, setPivotOn] = React37__namespace.default.useState(pivotMode);
5529
+ const [aggConfig, setAggConfig] = React37__namespace.default.useState(() => {
5158
5530
  const m = {};
5159
5531
  (columns || []).forEach((c) => {
5160
5532
  if (typeof c.aggregation === "string") m[c.field] = c.aggregation;
@@ -5162,13 +5534,13 @@ function Datatable({
5162
5534
  return m;
5163
5535
  });
5164
5536
  const aggOf = (c) => aggConfig[c.field] || (typeof c.aggregation === "function" ? c.aggregation : null);
5165
- const [pivotConfig, setPivotConfig] = React36__namespace.default.useState(() => ({
5537
+ const [pivotConfig, setPivotConfig] = React37__namespace.default.useState(() => ({
5166
5538
  rows: pivot && pivot.rows || [],
5167
5539
  columns: pivot && pivot.columns || [],
5168
5540
  values: pivot && pivot.values || []
5169
5541
  }));
5170
5542
  const pivotActive = pivotOn && pivotConfig.rows.length > 0 && pivotConfig.values.length > 0;
5171
- React36__namespace.default.useEffect(() => {
5543
+ React37__namespace.default.useEffect(() => {
5172
5544
  setOrder((prev) => {
5173
5545
  const fields = columns.map((c) => c.field);
5174
5546
  const kept = prev.filter((f) => fields.includes(f));
@@ -5176,32 +5548,37 @@ function Datatable({
5176
5548
  return [...kept, ...added];
5177
5549
  });
5178
5550
  }, [columns]);
5179
- React36__namespace.default.useEffect(() => {
5551
+ React37__namespace.default.useEffect(() => {
5180
5552
  setDensity(densityProp);
5181
5553
  }, [densityProp]);
5182
- React36__namespace.default.useEffect(() => {
5554
+ React37__namespace.default.useEffect(() => {
5183
5555
  setAggOn(showAggregation);
5184
5556
  }, [showAggregation]);
5557
+ React37__namespace.default.useEffect(() => {
5558
+ if (pageSizeControlled) return;
5559
+ setInternalRpp(pageSize > 0 ? pageSize : 10);
5560
+ setInternalPage(0);
5561
+ }, [pageSize]);
5185
5562
  const rowGroupingKey = (rowGrouping || []).join("\0");
5186
- const rowGroupingKeyRef = React36__namespace.default.useRef(rowGroupingKey);
5187
- React36__namespace.default.useEffect(() => {
5563
+ const rowGroupingKeyRef = React37__namespace.default.useRef(rowGroupingKey);
5564
+ React37__namespace.default.useEffect(() => {
5188
5565
  if (rowGroupingKeyRef.current === rowGroupingKey) return;
5189
5566
  rowGroupingKeyRef.current = rowGroupingKey;
5190
5567
  setGroupBy(rowGrouping || []);
5191
5568
  }, [rowGroupingKey]);
5192
5569
  const widthOf = (c) => widths[c.field] ?? c.width ?? 160;
5193
- const [colMenu, setColMenu] = React36__namespace.default.useState(null);
5570
+ const [colMenu, setColMenu] = React37__namespace.default.useState(null);
5194
5571
  const [menuPos, openMenu, closeMenu] = useFloating();
5195
- const [panel, setPanel] = React36__namespace.default.useState(null);
5572
+ const [panel, setPanel] = React37__namespace.default.useState(null);
5196
5573
  const [panelPos, openPanel, closePanel] = useFloating();
5197
- const [rowMenu, setRowMenu] = React36__namespace.default.useState(null);
5574
+ const [rowMenu, setRowMenu] = React37__namespace.default.useState(null);
5198
5575
  const [rowMenuPos, openRowMenu, closeRowMenu] = useFloating();
5199
- const [exportOpen, setExportOpen] = React36__namespace.default.useState(false);
5576
+ const [exportOpen, setExportOpen] = React37__namespace.default.useState(false);
5200
5577
  const [exportPos, openExport, closeExport] = useFloating();
5201
- const menuTriggerRef = React36__namespace.default.useRef(null);
5202
- const colMenuRef = React36__namespace.default.useRef(null);
5203
- const rowMenuRef = React36__namespace.default.useRef(null);
5204
- const exportMenuRef = React36__namespace.default.useRef(null);
5578
+ const menuTriggerRef = React37__namespace.default.useRef(null);
5579
+ const colMenuRef = React37__namespace.default.useRef(null);
5580
+ const rowMenuRef = React37__namespace.default.useRef(null);
5581
+ const exportMenuRef = React37__namespace.default.useRef(null);
5205
5582
  function focusFirstItem(container) {
5206
5583
  if (!container) return;
5207
5584
  const first = container.querySelector('[role="menuitem"]:not([disabled])');
@@ -5240,16 +5617,16 @@ function Datatable({
5240
5617
  restoreTriggerFocus();
5241
5618
  }
5242
5619
  }
5243
- React36__namespace.default.useEffect(() => {
5620
+ React37__namespace.default.useEffect(() => {
5244
5621
  if (colMenu) focusFirstItem(colMenuRef.current);
5245
5622
  }, [colMenu]);
5246
- React36__namespace.default.useEffect(() => {
5623
+ React37__namespace.default.useEffect(() => {
5247
5624
  if (rowMenu) focusFirstItem(rowMenuRef.current);
5248
5625
  }, [rowMenu]);
5249
- React36__namespace.default.useEffect(() => {
5626
+ React37__namespace.default.useEffect(() => {
5250
5627
  if (exportOpen) focusFirstItem(exportMenuRef.current);
5251
5628
  }, [exportOpen]);
5252
- React36__namespace.default.useEffect(() => {
5629
+ React37__namespace.default.useEffect(() => {
5253
5630
  if (!colMenu && !panel && !rowMenu) return;
5254
5631
  const closeAll = () => {
5255
5632
  setColMenu(null);
@@ -5272,7 +5649,7 @@ function Datatable({
5272
5649
  document.removeEventListener("keydown", onKey);
5273
5650
  };
5274
5651
  }, [colMenu, panel, rowMenu]);
5275
- React36__namespace.default.useEffect(() => {
5652
+ React37__namespace.default.useEffect(() => {
5276
5653
  if (!exportOpen) return;
5277
5654
  const close = () => {
5278
5655
  setExportOpen(false);
@@ -5291,9 +5668,9 @@ function Datatable({
5291
5668
  document.removeEventListener("keydown", onKey);
5292
5669
  };
5293
5670
  }, [exportOpen]);
5294
- const colByField = React36__namespace.default.useMemo(() => Object.fromEntries(cols.map((c) => [c.field, c])), [cols]);
5671
+ const colByField = React37__namespace.default.useMemo(() => Object.fromEntries(cols.map((c) => [c.field, c])), [cols]);
5295
5672
  const visibleCols = cols.filter((c) => !hidden.has(c.field));
5296
- const ordered = React36__namespace.default.useMemo(() => {
5673
+ const ordered = React37__namespace.default.useMemo(() => {
5297
5674
  const orderIdx = (f) => {
5298
5675
  const i = order.indexOf(f);
5299
5676
  return i === -1 ? 9999 : i;
@@ -5328,7 +5705,7 @@ function Datatable({
5328
5705
  }
5329
5706
  return {};
5330
5707
  };
5331
- const processed = React36__namespace.default.useMemo(() => {
5708
+ const processed = React37__namespace.default.useMemo(() => {
5332
5709
  if (serverMode) {
5333
5710
  if (rowOrder) {
5334
5711
  const idx = new Map(rowOrder.map((k, i) => [k, i]));
@@ -5365,12 +5742,12 @@ function Datatable({
5365
5742
  const paginated = pageSize > 0;
5366
5743
  const serverTotal = rowCount == null ? processed.length : rowCount;
5367
5744
  const totalRows = serverMode ? serverTotal : processed.length;
5368
- const totalPages = paginated ? Math.max(1, Math.ceil(totalRows / rowsPerPage)) : 1;
5369
- const paged = !paginated || serverMode ? processed : processed.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
5370
- React36__namespace.default.useEffect(() => {
5371
- if (page > totalPages - 1) setPage(0);
5745
+ const totalPages = paginated ? Math.max(1, Math.ceil(totalRows / sizeVal)) : 1;
5746
+ const paged = !paginated || serverMode ? processed : processed.slice(pageVal * sizeVal, pageVal * sizeVal + sizeVal);
5747
+ React37__namespace.default.useEffect(() => {
5748
+ if (pageVal > totalPages - 1) commitPage(0);
5372
5749
  }, [totalPages]);
5373
- const activeGroupBy = React36__namespace.default.useMemo(() => groupBy.filter((f) => colByField[f]), [groupBy, colByField]);
5750
+ const activeGroupBy = React37__namespace.default.useMemo(() => groupBy.filter((f) => colByField[f]), [groupBy, colByField]);
5374
5751
  function subtotalText(rowsIn) {
5375
5752
  const parts = [];
5376
5753
  for (const c of ordered) {
@@ -5397,7 +5774,7 @@ function Datatable({
5397
5774
  if (agg === "max") return Math.max(...nums);
5398
5775
  return null;
5399
5776
  }
5400
- const displayItems = React36__namespace.default.useMemo(() => {
5777
+ const displayItems = React37__namespace.default.useMemo(() => {
5401
5778
  if (!activeGroupBy.length) return null;
5402
5779
  const build = (rowsIn, depth, prefix) => {
5403
5780
  if (depth >= activeGroupBy.length) return rowsIn.map((row) => ({ kind: "leaf", row }));
@@ -5439,7 +5816,7 @@ function Datatable({
5439
5816
  return { top, bottom };
5440
5817
  });
5441
5818
  }
5442
- React36__namespace.default.useEffect(() => {
5819
+ React37__namespace.default.useEffect(() => {
5443
5820
  if (!rowPinning) return;
5444
5821
  const measure = () => {
5445
5822
  if (theadRef.current) setHeadH(theadRef.current.offsetHeight || 41);
@@ -5453,12 +5830,12 @@ function Datatable({
5453
5830
  const pinnedTopRows = canPinRows ? pinnedRows.top.map((k) => leafRows.find((r, i) => keyOf(r, i) === k)).filter(Boolean) : [];
5454
5831
  const pinnedBottomRows = canPinRows ? pinnedRows.bottom.map((k) => leafRows.find((r, i) => keyOf(r, i) === k)).filter(Boolean) : [];
5455
5832
  const middleRows = canPinRows ? leafRows.filter((r, i) => !pinSideOf(keyOf(r, i))) : leafRows;
5456
- const keyIndex = React36__namespace.default.useMemo(() => {
5833
+ const keyIndex = React37__namespace.default.useMemo(() => {
5457
5834
  const m = /* @__PURE__ */ new Map();
5458
5835
  leafRows.forEach((r, i) => m.set(keyOf(r, i), i));
5459
5836
  return m;
5460
5837
  }, [leafRows]);
5461
- const keyIndexMid = React36__namespace.default.useMemo(() => {
5838
+ const keyIndexMid = React37__namespace.default.useMemo(() => {
5462
5839
  const m = /* @__PURE__ */ new Map();
5463
5840
  middleRows.forEach((r, i) => m.set(keyOf(r, keyIndex.get(keyOf(r)) ?? i), i));
5464
5841
  return m;
@@ -5543,7 +5920,7 @@ function Datatable({
5543
5920
  setReorderMsg("Reorder cancelled.");
5544
5921
  }
5545
5922
  }
5546
- React36__namespace.default.useEffect(() => {
5923
+ React37__namespace.default.useEffect(() => {
5547
5924
  if (rowFocusRef.current == null) return;
5548
5925
  const key = rowFocusRef.current;
5549
5926
  rowFocusRef.current = null;
@@ -5555,7 +5932,7 @@ function Datatable({
5555
5932
  });
5556
5933
  const estRowH = rowHeight ?? (density === "compact" ? 36 : density === "comfortable" ? 56 : 44);
5557
5934
  const virtualizing = virtualized && !paginated && !activeGroupBy.length && !loading;
5558
- React36__namespace.default.useEffect(() => {
5935
+ React37__namespace.default.useEffect(() => {
5559
5936
  if (!virtualizing) return;
5560
5937
  const el = scrollRef.current;
5561
5938
  if (!el) return;
@@ -5565,13 +5942,13 @@ function Datatable({
5565
5942
  if (ro) ro.observe(el);
5566
5943
  return () => ro && ro.disconnect();
5567
5944
  }, [virtualizing, height]);
5568
- const onScrollVirtual = React36__namespace.default.useCallback((e) => {
5945
+ const onScrollVirtual = React37__namespace.default.useCallback((e) => {
5569
5946
  setScrollTop(e.currentTarget.scrollTop);
5570
5947
  }, []);
5571
5948
  const vh = viewportH || (typeof height === "number" ? height : 440);
5572
- const rowHRef = React36__namespace.default.useRef(/* @__PURE__ */ new Map());
5573
- const [measureTick, setMeasureTick] = React36__namespace.default.useState(0);
5574
- const offsets = React36__namespace.default.useMemo(() => {
5949
+ const rowHRef = React37__namespace.default.useRef(/* @__PURE__ */ new Map());
5950
+ const [measureTick, setMeasureTick] = React37__namespace.default.useState(0);
5951
+ const offsets = React37__namespace.default.useMemo(() => {
5575
5952
  if (!virtualizing) return null;
5576
5953
  const total = middleRows.length;
5577
5954
  const arr = new Float64Array(total + 1);
@@ -5581,7 +5958,7 @@ function Datatable({
5581
5958
  }
5582
5959
  return arr;
5583
5960
  }, [virtualizing, middleRows, estRowH, measureTick]);
5584
- const vWindow = React36__namespace.default.useMemo(() => {
5961
+ const vWindow = React37__namespace.default.useMemo(() => {
5585
5962
  if (!virtualizing || !offsets) return null;
5586
5963
  const total = middleRows.length;
5587
5964
  const totalH = offsets[total];
@@ -5610,7 +5987,7 @@ function Datatable({
5610
5987
  if (start > end) start = end;
5611
5988
  return { start, end, padTop: offsets[start], padBottom: Math.max(0, totalH - offsets[end]) };
5612
5989
  }, [virtualizing, offsets, middleRows.length, vh, scrollTop, overscan]);
5613
- React36__namespace.default.useLayoutEffect(() => {
5990
+ React37__namespace.default.useLayoutEffect(() => {
5614
5991
  if (!virtualizing) return;
5615
5992
  const el = scrollRef.current;
5616
5993
  if (!el) return;
@@ -5625,21 +6002,21 @@ function Datatable({
5625
6002
  }
5626
6003
  if (changed) setMeasureTick((t) => t + 1);
5627
6004
  });
5628
- const onServerChangeRef = React36__namespace.default.useRef(onServerChange);
6005
+ const onServerChangeRef = React37__namespace.default.useRef(onServerChange);
5629
6006
  onServerChangeRef.current = onServerChange;
5630
- React36__namespace.default.useEffect(() => {
6007
+ React37__namespace.default.useEffect(() => {
5631
6008
  if (!serverMode) return;
5632
6009
  const t = setTimeout(() => {
5633
6010
  onServerChangeRef.current?.({
5634
- page,
5635
- pageSize: rowsPerPage,
6011
+ page: pageVal,
6012
+ pageSize: sizeVal,
5636
6013
  sort,
5637
6014
  filters: filters.map(({ id, ...f }) => f),
5638
6015
  quickFilter: quick.trim()
5639
6016
  });
5640
6017
  }, 250);
5641
6018
  return () => clearTimeout(t);
5642
- }, [serverMode, page, rowsPerPage, sort, filters, quick]);
6019
+ }, [serverMode, pageVal, sizeVal, sort, filters, quick]);
5643
6020
  function cycleSort(field) {
5644
6021
  setSort((s) => !s || s.field !== field ? { field, dir: "asc" } : s.dir === "asc" ? { field, dir: "desc" } : null);
5645
6022
  }
@@ -5662,7 +6039,7 @@ function Datatable({
5662
6039
  return n;
5663
6040
  });
5664
6041
  }
5665
- const movableMidFields = React36__namespace.default.useMemo(
6042
+ const movableMidFields = React37__namespace.default.useMemo(
5666
6043
  () => ordered.filter((c) => !pins.left.includes(c.field) && !pins.right.includes(c.field) && c.reorderable !== false).map((c) => c.field),
5667
6044
  [ordered, pins]
5668
6045
  );
@@ -5693,7 +6070,7 @@ function Datatable({
5693
6070
  }
5694
6071
  return [...set].sort((a, b) => a.localeCompare(b)).map((v) => ({ value: v, label: v }));
5695
6072
  }
5696
- const [resizing, setResizing] = React36__namespace.default.useState(false);
6073
+ const [resizing, setResizing] = React37__namespace.default.useState(false);
5697
6074
  function startResize(e, field) {
5698
6075
  e.preventDefault();
5699
6076
  e.stopPropagation();
@@ -5800,7 +6177,7 @@ function Datatable({
5800
6177
  if (!agg) return null;
5801
6178
  if (aggregationValues && col.field in aggregationValues) {
5802
6179
  const pre = aggregationValues[col.field];
5803
- if (pre && typeof pre === "object" && !React36__namespace.default.isValidElement(pre)) {
6180
+ if (pre && typeof pre === "object" && !React37__namespace.default.isValidElement(pre)) {
5804
6181
  if (typeof agg === "string" && agg in pre) return pre[agg];
5805
6182
  } else {
5806
6183
  return pre;
@@ -5918,14 +6295,14 @@ function Datatable({
5918
6295
  focusCell(r, c);
5919
6296
  }
5920
6297
  }
5921
- React36__namespace.default.useEffect(() => {
6298
+ React37__namespace.default.useEffect(() => {
5922
6299
  setFocus((f) => ({ r: Math.min(f.r, Math.max(0, leafRows.length - 1)), c: Math.min(f.c, Math.max(0, ordered.length - 1)) }));
5923
- }, [leafRows.length, ordered.length, page]);
5924
- const selectedRows = React36__namespace.default.useMemo(() => rows.filter((r, i) => selected.has(keyOf(r, i))), [rows, selected]);
6300
+ }, [leafRows.length, ordered.length, pageVal]);
6301
+ const selectedRows = React37__namespace.default.useMemo(() => rows.filter((r, i) => selected.has(keyOf(r, i))), [rows, selected]);
5925
6302
  function clearSelection() {
5926
6303
  setSelected(/* @__PURE__ */ new Set());
5927
6304
  }
5928
- const [editing, setEditing] = React36__namespace.default.useState(null);
6305
+ const [editing, setEditing] = React37__namespace.default.useState(null);
5929
6306
  const isColEditable = (c) => c.type !== "actions" && (c.editable ?? (editMode && c.editable !== false));
5930
6307
  function beginEdit(rowK, col, row) {
5931
6308
  if (!isColEditable(col)) return;
@@ -5960,17 +6337,17 @@ function Datatable({
5960
6337
  cancelEdit();
5961
6338
  }
5962
6339
  }
5963
- const batchEditableCols = React36__namespace.default.useMemo(
6340
+ const batchEditableCols = React37__namespace.default.useMemo(
5964
6341
  () => cols.filter((c) => c.type !== "actions" && (c.editable ?? (editMode && c.editable !== false))),
5965
6342
  [cols, editMode]
5966
6343
  );
5967
- const [batchEdit, setBatchEdit] = React36__namespace.default.useState(null);
6344
+ const [batchEdit, setBatchEdit] = React37__namespace.default.useState(null);
5968
6345
  const [batchEditPos, openBatchEdit, closeBatchEdit] = useFloating();
5969
6346
  function openBatchEditor(el) {
5970
6347
  setBatchEdit({ fields: {}, values: {} });
5971
6348
  openBatchEdit(el, "left", 320);
5972
6349
  }
5973
- React36__namespace.default.useEffect(() => {
6350
+ React37__namespace.default.useEffect(() => {
5974
6351
  if (!batchEdit) return;
5975
6352
  const close = () => {
5976
6353
  setBatchEdit(null);
@@ -5989,7 +6366,7 @@ function Datatable({
5989
6366
  document.removeEventListener("keydown", onKey);
5990
6367
  };
5991
6368
  }, [batchEdit]);
5992
- React36__namespace.default.useEffect(() => {
6369
+ React37__namespace.default.useEffect(() => {
5993
6370
  if (batchEdit && selected.size === 0) {
5994
6371
  setBatchEdit(null);
5995
6372
  closeBatchEdit();
@@ -6026,7 +6403,7 @@ function Datatable({
6026
6403
  setBatchEdit(null);
6027
6404
  closeBatchEdit();
6028
6405
  }
6029
- React36__namespace.default.useEffect(() => {
6406
+ React37__namespace.default.useEffect(() => {
6030
6407
  if (!editing) return;
6031
6408
  const onDown = (e) => {
6032
6409
  if (e.target.closest(".twc-dt__editor-wrap") || e.target.closest(".twc-pop")) return;
@@ -6165,7 +6542,7 @@ function Datatable({
6165
6542
  {
6166
6543
  className: "twc-dt__row",
6167
6544
  role: "row",
6168
- "aria-rowindex": (paginated && !serverMode ? page * rowsPerPage : 0) + ri + 2,
6545
+ "aria-rowindex": (paginated && !serverMode ? pageVal * sizeVal : 0) + ri + 2,
6169
6546
  "aria-selected": (checkboxSelection ? sel : rowActive) || void 0,
6170
6547
  "data-selected": sel || void 0,
6171
6548
  "data-active": rowActive || void 0,
@@ -6223,7 +6600,7 @@ function Datatable({
6223
6600
  ] }),
6224
6601
  rowResize && !pinSide ? /* @__PURE__ */ jsxRuntime.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
6225
6602
  ] }) : null,
6226
- showRowNum ? /* @__PURE__ */ jsxRuntime.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,
6603
+ showRowNum ? /* @__PURE__ */ jsxRuntime.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,
6227
6604
  ordered.map((c, ci) => {
6228
6605
  const st = stickyOf(c.field);
6229
6606
  const val = row[c.field];
@@ -6551,7 +6928,7 @@ function Datatable({
6551
6928
  /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.search }),
6552
6929
  /* @__PURE__ */ jsxRuntime.jsx("input", { placeholder: "Search\u2026", "aria-label": "Search rows", value: quick, onChange: (e) => {
6553
6930
  setQuick(e.target.value);
6554
- setPage(0);
6931
+ commitPage(0);
6555
6932
  } })
6556
6933
  ] })
6557
6934
  ] }),
@@ -6753,7 +7130,7 @@ function Datatable({
6753
7130
  );
6754
7131
  })
6755
7132
  ] }) }),
6756
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: loading ? Array.from({ length: paginated ? Math.min(rowsPerPage, 8) : 8 }).map((_, ri) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "twc-dt__row", role: "row", children: [
7133
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: loading ? Array.from({ length: paginated ? Math.min(sizeVal, 8) : 8 }).map((_, ri) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "twc-dt__row", role: "row", children: [
6757
7134
  checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", style: { insetInlineStart: 0, width: 44 }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__sk", "aria-hidden": "true", style: { "--_w": "18px", height: 18, borderRadius: 4 } }) }) : null,
6758
7135
  showRowNum ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("span", { className: "twc-dt__sk", "aria-hidden": "true", style: { "--_w": "16px", height: 14, borderRadius: 4 } }) }) : null,
6759
7136
  ordered.map((c, ci) => {
@@ -6797,7 +7174,7 @@ function Datatable({
6797
7174
  const nf = (n) => n.toLocaleString();
6798
7175
  if (totalRows === 0) return "No rows";
6799
7176
  const shown = paged.length;
6800
- const start = paginated ? page * rowsPerPage + 1 : 1;
7177
+ const start = paginated ? pageVal * sizeVal + 1 : 1;
6801
7178
  const end = paginated ? start + shown - 1 : shown;
6802
7179
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6803
7180
  paginated ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -6825,13 +7202,10 @@ function Datatable({
6825
7202
  })() }),
6826
7203
  paginated ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__rpp", children: [
6827
7204
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__rpp-label", children: "Rows per page" }),
6828
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: 78 }, children: /* @__PURE__ */ jsxRuntime.jsx(Select, { size: "sm", portal: true, searchable: false, value: String(rowsPerPage), options: rppOptions, placement: "top", onChange: (v) => {
6829
- setRowsPerPage(Number(v));
6830
- setPage(0);
6831
- } }) })
7205
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: 78 }, children: /* @__PURE__ */ jsxRuntime.jsx(Select, { size: "sm", portal: true, searchable: false, value: String(sizeVal), options: rppOptions, placement: "top", onChange: (v) => commitPageSize(Number(v)) }) })
6832
7206
  ] }) : null
6833
7207
  ] }),
6834
- paginated ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__footer-row", "data-pager": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Pagination, { size: "sm", page: page + 1, total: totalPages, boundaries: 3, showPageJumper: showPageJumper && totalPages > 5, onChange: (p) => setPage(p - 1) }) }) : null
7208
+ paginated ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__footer-row", "data-pager": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Pagination, { size: "sm", page: pageVal + 1, total: totalPages, boundaries: 3, showPageJumper: showPageJumper && totalPages > 5, onChange: (p) => commitPage(p - 1) }) }) : null
6835
7209
  ] }) : null,
6836
7210
  exportOpen && exportPos ? /* @__PURE__ */ jsxRuntime.jsxs(
6837
7211
  "div",
@@ -7480,6 +7854,18 @@ var DATEPICKER_CSS = `
7480
7854
  .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); }
7481
7855
  .twc-dp__clear:hover { background: var(--color-surface-sunken); color: var(--color-text); }
7482
7856
  .twc-dp__clear svg { width: 14px; height: 14px; }
7857
+ /* #105: editable (typed entry) variant \u2014 the control wraps a real text input + a trailing toggle. */
7858
+ .twc-dp__control--editable { cursor: text; gap: 0; padding-inline-end: var(--space-1); }
7859
+ .twc-dp__input { flex: 1; min-width: 0; height: 100%; border: none; background: transparent; outline: none; padding: 0;
7860
+ font-family: inherit; font-size: var(--text-sm); color: var(--color-text); }
7861
+ .twc-dp__input::placeholder { color: var(--color-text-subtle); }
7862
+ .twc-dp__input:disabled { cursor: not-allowed; }
7863
+ .twc-dp__clear--inline { position: static; transform: none; flex: none; }
7864
+ .twc-dp__toggle { flex: none; display: inline-grid; place-items: center; width: 26px; height: 26px; border: none; background: transparent;
7865
+ color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-md); transition: background-color var(--duration-fast), color var(--duration-fast); }
7866
+ .twc-dp__toggle:hover:not(:disabled) { background: var(--color-surface-sunken); color: var(--color-text); }
7867
+ .twc-dp__toggle:disabled { cursor: not-allowed; }
7868
+ .twc-dp__toggle svg { width: 17px; height: 17px; }
7483
7869
 
7484
7870
  .twc-dp__pop {
7485
7871
  position: fixed; z-index: var(--z-popover); width: 280px;
@@ -7539,6 +7925,8 @@ function DatePicker({
7539
7925
  disabled = false,
7540
7926
  tone = "primary",
7541
7927
  clearable = true,
7928
+ editable = false,
7929
+ parse,
7542
7930
  format,
7543
7931
  locale,
7544
7932
  weekStartsOn = 0,
@@ -7549,24 +7937,25 @@ function DatePicker({
7549
7937
  }) {
7550
7938
  const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS3);
7551
7939
  const __twcStyles1 = useScopedStyles("twc-datepicker-styles", DATEPICKER_CSS);
7552
- const autoId = React36__namespace.default.useId();
7940
+ const autoId = React37__namespace.default.useId();
7553
7941
  const fieldId = id || autoId;
7554
7942
  const descId = `${fieldId}-desc`;
7555
7943
  const invalid = Boolean(error);
7556
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
7944
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
7557
7945
  const selected = value !== void 0 ? value : internal;
7558
- const [open, setOpen] = React36__namespace.default.useState(false);
7559
- const [view, setView] = React36__namespace.default.useState(selected || /* @__PURE__ */ new Date());
7560
- const [mode, setMode] = React36__namespace.default.useState("days");
7561
- const [focusDate, setFocusDate] = React36__namespace.default.useState(null);
7562
- const [focusMonth, setFocusMonth] = React36__namespace.default.useState(null);
7563
- const [coords, setCoords] = React36__namespace.default.useState(null);
7564
- const wrapRef = React36__namespace.default.useRef(null);
7565
- const triggerRef = React36__namespace.default.useRef(null);
7566
- const popRef = React36__namespace.default.useRef(null);
7567
- const gridRef = React36__namespace.default.useRef(null);
7946
+ const [open, setOpen] = React37__namespace.default.useState(false);
7947
+ const [view, setView] = React37__namespace.default.useState(selected || /* @__PURE__ */ new Date());
7948
+ const [mode, setMode] = React37__namespace.default.useState("days");
7949
+ const [focusDate, setFocusDate] = React37__namespace.default.useState(null);
7950
+ const [focusMonth, setFocusMonth] = React37__namespace.default.useState(null);
7951
+ const [editText, setEditText] = React37__namespace.default.useState(null);
7952
+ const [coords, setCoords] = React37__namespace.default.useState(null);
7953
+ const wrapRef = React37__namespace.default.useRef(null);
7954
+ const triggerRef = React37__namespace.default.useRef(null);
7955
+ const popRef = React37__namespace.default.useRef(null);
7956
+ const gridRef = React37__namespace.default.useRef(null);
7568
7957
  const POP_W = 280;
7569
- const place = React36__namespace.default.useCallback(() => {
7958
+ const place = React37__namespace.default.useCallback(() => {
7570
7959
  const el = triggerRef.current;
7571
7960
  if (!el) return;
7572
7961
  const r = el.getBoundingClientRect();
@@ -7577,7 +7966,7 @@ function DatePicker({
7577
7966
  left = Math.max(8, left);
7578
7967
  setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
7579
7968
  }, []);
7580
- React36__namespace.default.useEffect(() => {
7969
+ React37__namespace.default.useEffect(() => {
7581
7970
  if (!open) return void 0;
7582
7971
  place();
7583
7972
  const onMove = () => place();
@@ -7588,7 +7977,7 @@ function DatePicker({
7588
7977
  window.removeEventListener("resize", onMove);
7589
7978
  };
7590
7979
  }, [open, place]);
7591
- React36__namespace.default.useEffect(() => {
7980
+ React37__namespace.default.useEffect(() => {
7592
7981
  if (!open) return;
7593
7982
  setView(selected || /* @__PURE__ */ new Date());
7594
7983
  setMode("days");
@@ -7609,9 +7998,9 @@ function DatePicker({
7609
7998
  };
7610
7999
  }, [open]);
7611
8000
  useFocusTrap(popRef, open && !!coords, { initialFocus: () => gridRef.current?.querySelector('[tabindex="0"]') });
7612
- const months = React36__namespace.default.useMemo(() => locale === void 0 ? MONTHS : monthNames(locale), [locale]);
7613
- const monthsShort = React36__namespace.default.useMemo(() => locale === void 0 ? MONTHS.map((n) => n.slice(0, 3)) : monthShortNames(locale), [locale]);
7614
- const dows = React36__namespace.default.useMemo(
8001
+ const months = React37__namespace.default.useMemo(() => locale === void 0 ? MONTHS : monthNames(locale), [locale]);
8002
+ const monthsShort = React37__namespace.default.useMemo(() => locale === void 0 ? MONTHS.map((n) => n.slice(0, 3)) : monthShortNames(locale), [locale]);
8003
+ const dows = React37__namespace.default.useMemo(
7615
8004
  () => locale === void 0 ? Array.from({ length: 7 }, (_, i) => DOW[(i + weekStartsOn) % 7]) : weekdayNames(locale, weekStartsOn),
7616
8005
  [locale, weekStartsOn]
7617
8006
  );
@@ -7623,8 +8012,33 @@ function DatePicker({
7623
8012
  const pick = (d) => {
7624
8013
  if (value === void 0) setInternal(d);
7625
8014
  onChange?.(d);
8015
+ setEditText(null);
7626
8016
  setOpen(false);
7627
8017
  };
8018
+ const parseTyped = (s) => {
8019
+ const str = s.trim();
8020
+ if (str === "") return null;
8021
+ if (parse) {
8022
+ const d = parse(str);
8023
+ return d instanceof Date && !Number.isNaN(d.getTime()) ? d : void 0;
8024
+ }
8025
+ const t = Date.parse(str);
8026
+ return Number.isNaN(t) ? void 0 : new Date(t);
8027
+ };
8028
+ const commitText = () => {
8029
+ if (editText == null) return;
8030
+ const parsed = parseTyped(editText);
8031
+ if (parsed === null) {
8032
+ setEditText(null);
8033
+ if (selected) pick(null);
8034
+ return;
8035
+ }
8036
+ if (parsed === void 0 || outOfRange(parsed)) {
8037
+ setEditText(null);
8038
+ return;
8039
+ }
8040
+ pick(parsed);
8041
+ };
7628
8042
  const y = view.getFullYear(), m = view.getMonth();
7629
8043
  const first = new Date(y, m, 1);
7630
8044
  const startOffset = (first.getDay() - weekStartsOn + 7) % 7;
@@ -7639,11 +8053,11 @@ function DatePicker({
7639
8053
  };
7640
8054
  const cells = Array.from({ length: 42 }, (_, i) => new Date(gridStart.getFullYear(), gridStart.getMonth(), gridStart.getDate() + i));
7641
8055
  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);
7642
- React36__namespace.default.useEffect(() => {
8056
+ React37__namespace.default.useEffect(() => {
7643
8057
  if (!open || mode !== "days" || !focusDate) return;
7644
8058
  gridRef.current?.querySelector(`[data-key="${keyOf(focusDate)}"]`)?.focus();
7645
8059
  }, [focusDate, open, mode]);
7646
- React36__namespace.default.useEffect(() => {
8060
+ React37__namespace.default.useEffect(() => {
7647
8061
  if (!open || mode !== "months" || focusMonth == null) return;
7648
8062
  gridRef.current?.querySelector(`[data-mo="${focusMonth}"]`)?.focus();
7649
8063
  }, [focusMonth, open, mode]);
@@ -7700,7 +8114,82 @@ function DatePicker({
7700
8114
  label,
7701
8115
  required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-field__req", children: "*" }) : null
7702
8116
  ] }) : null,
7703
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dp__field", children: [
8117
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dp__field", children: editable ? (
8118
+ // #105: typed entry — the trigger is a real text input with a trailing
8119
+ // calendar toggle button; typing commits via `parse` on Enter/blur.
8120
+ /* @__PURE__ */ jsxRuntime.jsxs(
8121
+ "div",
8122
+ {
8123
+ className: "twc-dp__control twc-dp__control--editable",
8124
+ "data-open": open || void 0,
8125
+ "data-disabled": disabled || void 0,
8126
+ "data-tone": tone,
8127
+ "data-invalid": invalid || void 0,
8128
+ children: [
8129
+ /* @__PURE__ */ jsxRuntime.jsx(
8130
+ "input",
8131
+ {
8132
+ ref: triggerRef,
8133
+ className: "twc-dp__input",
8134
+ id: fieldId,
8135
+ type: "text",
8136
+ inputMode: "numeric",
8137
+ autoComplete: "off",
8138
+ disabled,
8139
+ placeholder,
8140
+ value: editText != null ? editText : selected ? fmt(selected) : "",
8141
+ "aria-haspopup": "dialog",
8142
+ "aria-expanded": open,
8143
+ "aria-labelledby": label ? `${fieldId}-label` : void 0,
8144
+ "aria-invalid": invalid || void 0,
8145
+ "aria-describedby": error || hint ? descId : void 0,
8146
+ onChange: (e) => setEditText(e.target.value),
8147
+ onKeyDown: (e) => {
8148
+ if (e.key === "Enter") {
8149
+ e.preventDefault();
8150
+ commitText();
8151
+ } else if (e.key === "ArrowDown" && (e.altKey || !open)) {
8152
+ e.preventDefault();
8153
+ setOpen(true);
8154
+ } else if (e.key === "Escape" && open) setOpen(false);
8155
+ },
8156
+ onBlur: (e) => {
8157
+ if (popRef.current && popRef.current.contains(e.relatedTarget)) return;
8158
+ commitText();
8159
+ }
8160
+ }
8161
+ ),
8162
+ clearable && selected && !disabled ? /* @__PURE__ */ jsxRuntime.jsx(
8163
+ "button",
8164
+ {
8165
+ type: "button",
8166
+ className: "twc-dp__clear twc-dp__clear--inline",
8167
+ "aria-label": "Clear",
8168
+ tabIndex: -1,
8169
+ onMouseDown: (e) => e.preventDefault(),
8170
+ onClick: () => pick(null),
8171
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
8172
+ }
8173
+ ) : null,
8174
+ /* @__PURE__ */ jsxRuntime.jsx(
8175
+ "button",
8176
+ {
8177
+ type: "button",
8178
+ className: "twc-dp__toggle",
8179
+ "aria-label": "Open calendar",
8180
+ tabIndex: -1,
8181
+ disabled,
8182
+ onClick: () => !disabled && setOpen((o) => !o),
8183
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
8184
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
8185
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 2v4M8 2v4M3 10h18" })
8186
+ ] })
8187
+ }
8188
+ )
8189
+ ]
8190
+ }
8191
+ )
8192
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7704
8193
  /* @__PURE__ */ jsxRuntime.jsxs(
7705
8194
  "div",
7706
8195
  {
@@ -7739,7 +8228,7 @@ function DatePicker({
7739
8228
  e.stopPropagation();
7740
8229
  pick(null);
7741
8230
  }, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
7742
- ] }),
8231
+ ] }) }),
7743
8232
  open && coords ? reactDom.createPortal(
7744
8233
  /* @__PURE__ */ jsxRuntime.jsxs(
7745
8234
  "div",
@@ -7838,6 +8327,17 @@ var RANGE_CSS = `
7838
8327
  .twc-drp__ic svg { width: 17px; height: 17px; }
7839
8328
  .twc-drp__text { flex: 1; font-size: var(--text-sm); color: var(--color-text); white-space: nowrap; }
7840
8329
  .twc-drp__text[data-placeholder="true"] { color: var(--color-text-subtle); }
8330
+ /* #105: editable (typed entry) variant. */
8331
+ .twc-drp__control--editable { cursor: text; gap: 0; padding-inline-end: var(--space-1); }
8332
+ .twc-drp__input { flex: 1; min-width: 0; height: 100%; border: none; background: transparent; outline: none; padding: 0;
8333
+ font-family: inherit; font-size: var(--text-sm); color: var(--color-text); }
8334
+ .twc-drp__input::placeholder { color: var(--color-text-subtle); }
8335
+ .twc-drp__input:disabled { cursor: not-allowed; }
8336
+ .twc-drp__toggle { flex: none; display: inline-grid; place-items: center; width: 26px; height: 26px; border: none; background: transparent;
8337
+ color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-md); transition: background-color var(--duration-fast), color var(--duration-fast); }
8338
+ .twc-drp__toggle:hover:not(:disabled) { background: var(--color-surface-sunken); color: var(--color-text); }
8339
+ .twc-drp__toggle:disabled { cursor: not-allowed; }
8340
+ .twc-drp__toggle svg { width: 17px; height: 17px; }
7841
8341
  .twc-drp__pop { position: fixed; z-index: var(--z-popover); display: flex;
7842
8342
  background: var(--color-surface-raised); border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-lg);
7843
8343
  box-shadow: var(--shadow-lg); animation: twico-scale-in var(--duration-fast) var(--ease-spring); transform-origin: top; }
@@ -7892,31 +8392,34 @@ function DateRangePicker({
7892
8392
  disabledDate,
7893
8393
  disabled = false,
7894
8394
  tone = "primary",
8395
+ editable = false,
8396
+ parse,
7895
8397
  onChange,
7896
8398
  className = "",
7897
8399
  ...rest
7898
8400
  }) {
7899
8401
  const __twcStyles0 = useScopedStyles("twc-field-styles", FIELD_CSS4);
7900
8402
  const __twcStyles1 = useScopedStyles("twc-drp-styles", RANGE_CSS);
7901
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
8403
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
7902
8404
  const range = value !== void 0 ? value : internal;
7903
- const [open, setOpen] = React36__namespace.default.useState(false);
7904
- const [view, setView] = React36__namespace.default.useState(range.start || /* @__PURE__ */ new Date());
7905
- const [hover, setHover] = React36__namespace.default.useState(null);
7906
- const [focusDate, setFocusDate] = React36__namespace.default.useState(null);
7907
- const [coords, setCoords] = React36__namespace.default.useState(null);
7908
- const wrapRef = React36__namespace.default.useRef(null);
7909
- const triggerRef = React36__namespace.default.useRef(null);
7910
- const popRef = React36__namespace.default.useRef(null);
7911
- const gridRef = React36__namespace.default.useRef(null);
7912
- const labelId = React36__namespace.default.useId();
8405
+ const [open, setOpen] = React37__namespace.default.useState(false);
8406
+ const [view, setView] = React37__namespace.default.useState(range.start || /* @__PURE__ */ new Date());
8407
+ const [hover, setHover] = React37__namespace.default.useState(null);
8408
+ const [focusDate, setFocusDate] = React37__namespace.default.useState(null);
8409
+ const [editText, setEditText] = React37__namespace.default.useState(null);
8410
+ const [coords, setCoords] = React37__namespace.default.useState(null);
8411
+ const wrapRef = React37__namespace.default.useRef(null);
8412
+ const triggerRef = React37__namespace.default.useRef(null);
8413
+ const popRef = React37__namespace.default.useRef(null);
8414
+ const gridRef = React37__namespace.default.useRef(null);
8415
+ const labelId = React37__namespace.default.useId();
7913
8416
  const descId = `${labelId}-desc`;
7914
8417
  const invalid = Boolean(error);
7915
- React36__namespace.default.useEffect(() => {
8418
+ React37__namespace.default.useEffect(() => {
7916
8419
  if (disabled) setOpen(false);
7917
8420
  }, [disabled]);
7918
8421
  const POP_W = 420;
7919
- const place = React36__namespace.default.useCallback(() => {
8422
+ const place = React37__namespace.default.useCallback(() => {
7920
8423
  const el = triggerRef.current;
7921
8424
  if (!el) return;
7922
8425
  const r = el.getBoundingClientRect();
@@ -7927,7 +8430,7 @@ function DateRangePicker({
7927
8430
  left = Math.max(8, left);
7928
8431
  setCoords({ left, top: flip ? void 0 : Math.round(r.bottom + 6), bottom: flip ? Math.round(vh - r.top + 6) : void 0 });
7929
8432
  }, []);
7930
- React36__namespace.default.useEffect(() => {
8433
+ React37__namespace.default.useEffect(() => {
7931
8434
  if (!open) return void 0;
7932
8435
  place();
7933
8436
  const onMove = () => place();
@@ -7938,7 +8441,7 @@ function DateRangePicker({
7938
8441
  window.removeEventListener("resize", onMove);
7939
8442
  };
7940
8443
  }, [open, place]);
7941
- React36__namespace.default.useEffect(() => {
8444
+ React37__namespace.default.useEffect(() => {
7942
8445
  if (!open) return;
7943
8446
  const onDown = (e) => {
7944
8447
  if (wrapRef.current && wrapRef.current.contains(e.target)) return;
@@ -7959,6 +8462,40 @@ function DateRangePicker({
7959
8462
  if (value === void 0) setInternal(r);
7960
8463
  onChange?.(r);
7961
8464
  };
8465
+ const parseOne = (s) => {
8466
+ const str = s.trim();
8467
+ if (str === "") return null;
8468
+ if (parse) {
8469
+ const d = parse(str);
8470
+ return d instanceof Date && !Number.isNaN(d.getTime()) ? d : void 0;
8471
+ }
8472
+ const t = Date.parse(str);
8473
+ return Number.isNaN(t) ? void 0 : new Date(t);
8474
+ };
8475
+ const commitText = () => {
8476
+ if (editText == null) return;
8477
+ const raw = editText.trim();
8478
+ if (raw === "") {
8479
+ setEditText(null);
8480
+ if (range.start || range.end) set({ start: null, end: null });
8481
+ return;
8482
+ }
8483
+ const parts = raw.split(/\s*(?:–|—|\bto\b|\.\.+)\s*/i).map((p) => p.trim());
8484
+ let a = parseOne(parts[0] || "");
8485
+ let b = parts.length > 1 ? parseOne(parts[1] || "") : null;
8486
+ if (a === void 0 || b === void 0 || a && outOfRange(a) || b && outOfRange(b)) {
8487
+ setEditText(null);
8488
+ return;
8489
+ }
8490
+ if (a && b && ymd(b) < ymd(a)) {
8491
+ const t = a;
8492
+ a = b;
8493
+ b = t;
8494
+ }
8495
+ set({ start: a || null, end: b || null });
8496
+ setEditText(null);
8497
+ setOpen(false);
8498
+ };
7962
8499
  useFocusTrap(popRef, open && !!coords, { initialFocus: () => gridRef.current?.querySelector('[tabindex="0"]') });
7963
8500
  const outOfRange = (d) => min && ymd(d) < ymd(min) || max && ymd(d) > ymd(max) || Boolean(disabledDate && disabledDate(d));
7964
8501
  const sameDay2 = (a, b) => a && b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
@@ -7968,13 +8505,13 @@ function DateRangePicker({
7968
8505
  const last = new Date(d.getFullYear(), d.getMonth() + n + 1, 0);
7969
8506
  return new Date(last.getFullYear(), last.getMonth(), Math.min(d.getDate(), last.getDate()));
7970
8507
  };
7971
- React36__namespace.default.useEffect(() => {
8508
+ React37__namespace.default.useEffect(() => {
7972
8509
  if (!open) {
7973
8510
  setFocusDate(null);
7974
8511
  setHover(null);
7975
8512
  }
7976
8513
  }, [open]);
7977
- React36__namespace.default.useEffect(() => {
8514
+ React37__namespace.default.useEffect(() => {
7978
8515
  if (!open || !focusDate) return;
7979
8516
  gridRef.current?.querySelector(`[data-key="${keyOf(focusDate)}"]`)?.focus();
7980
8517
  }, [focusDate, open]);
@@ -8023,8 +8560,8 @@ function DateRangePicker({
8023
8560
  setView(start);
8024
8561
  setOpen(false);
8025
8562
  };
8026
- const months = React36__namespace.default.useMemo(() => locale === void 0 ? MONTHS2 : monthNames2(locale), [locale]);
8027
- const dows = React36__namespace.default.useMemo(
8563
+ const months = React37__namespace.default.useMemo(() => locale === void 0 ? MONTHS2 : monthNames2(locale), [locale]);
8564
+ const dows = React37__namespace.default.useMemo(
8028
8565
  () => locale === void 0 ? Array.from({ length: 7 }, (_, i) => DOW2[(i + weekStartsOn) % 7]) : weekdayNames2(locale, weekStartsOn),
8029
8566
  [locale, weekStartsOn]
8030
8567
  );
@@ -8054,7 +8591,57 @@ function DateRangePicker({
8054
8591
  label,
8055
8592
  required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-field__req", children: "*" }) : null
8056
8593
  ] }) : null,
8057
- /* @__PURE__ */ jsxRuntime.jsxs(
8594
+ editable ? (
8595
+ // #105: typed entry — a text input accepting "start – end"; commits via `parse` on Enter/blur.
8596
+ /* @__PURE__ */ jsxRuntime.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: [
8597
+ /* @__PURE__ */ jsxRuntime.jsx(
8598
+ "input",
8599
+ {
8600
+ ref: triggerRef,
8601
+ className: "twc-drp__input",
8602
+ type: "text",
8603
+ autoComplete: "off",
8604
+ disabled,
8605
+ placeholder,
8606
+ value: editText != null ? editText : text,
8607
+ "aria-haspopup": "dialog",
8608
+ "aria-expanded": open,
8609
+ "aria-labelledby": label ? labelId : void 0,
8610
+ "aria-invalid": invalid || void 0,
8611
+ "aria-describedby": error || hint ? descId : void 0,
8612
+ onChange: (e) => setEditText(e.target.value),
8613
+ onKeyDown: (e) => {
8614
+ if (e.key === "Enter") {
8615
+ e.preventDefault();
8616
+ commitText();
8617
+ } else if (e.key === "ArrowDown" && (e.altKey || !open)) {
8618
+ e.preventDefault();
8619
+ setOpen(true);
8620
+ } else if (e.key === "Escape" && open) setOpen(false);
8621
+ },
8622
+ onBlur: (e) => {
8623
+ if (popRef.current && popRef.current.contains(e.relatedTarget)) return;
8624
+ commitText();
8625
+ }
8626
+ }
8627
+ ),
8628
+ /* @__PURE__ */ jsxRuntime.jsx(
8629
+ "button",
8630
+ {
8631
+ type: "button",
8632
+ className: "twc-drp__toggle",
8633
+ "aria-label": "Open calendar",
8634
+ tabIndex: -1,
8635
+ disabled,
8636
+ onClick: () => !disabled && setOpen((o) => !o),
8637
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
8638
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
8639
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 2v4M8 2v4M3 10h18" })
8640
+ ] })
8641
+ }
8642
+ )
8643
+ ] })
8644
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
8058
8645
  "div",
8059
8646
  {
8060
8647
  ref: triggerRef,
@@ -8214,14 +8801,14 @@ function Dialog({
8214
8801
  className = "",
8215
8802
  ...rest
8216
8803
  }) {
8217
- const autoId = React36__namespace.default.useId();
8804
+ const autoId = React37__namespace.default.useId();
8218
8805
  const titleId = `${autoId}-title`;
8219
8806
  const descId = `${autoId}-desc`;
8220
- const dialogRef = React36__namespace.default.useRef(null);
8807
+ const dialogRef = React37__namespace.default.useRef(null);
8221
8808
  const __twcStyles = useScopedStyles("twc-dialog-styles", DIALOG_CSS);
8222
8809
  const renderPortal = usePortal();
8223
- const [mounted, setMounted] = React36__namespace.default.useState(open);
8224
- React36__namespace.default.useEffect(() => {
8810
+ const [mounted, setMounted] = React37__namespace.default.useState(open);
8811
+ React37__namespace.default.useEffect(() => {
8225
8812
  if (open) {
8226
8813
  setMounted(true);
8227
8814
  return;
@@ -8232,7 +8819,7 @@ function Dialog({
8232
8819
  useScrollLock(open);
8233
8820
  useInertBackground(dialogRef, open && mounted);
8234
8821
  useFocusTrap(dialogRef, open && mounted);
8235
- React36__namespace.default.useEffect(() => {
8822
+ React37__namespace.default.useEffect(() => {
8236
8823
  if (!open) return void 0;
8237
8824
  const onKey = (e) => {
8238
8825
  if (e.key === "Escape") {
@@ -8379,14 +8966,14 @@ function Drawer({
8379
8966
  style,
8380
8967
  ...rest
8381
8968
  }) {
8382
- const autoId = React36__namespace.default.useId();
8969
+ const autoId = React37__namespace.default.useId();
8383
8970
  const titleId = `${autoId}-title`;
8384
8971
  const descId = `${autoId}-desc`;
8385
- const panelRef = React36__namespace.default.useRef(null);
8972
+ const panelRef = React37__namespace.default.useRef(null);
8386
8973
  const __twcStyles = useScopedStyles("twc-drawer-styles", DRAWER_CSS);
8387
8974
  const renderPortal = usePortal();
8388
- const [mounted, setMounted] = React36__namespace.default.useState(open);
8389
- React36__namespace.default.useEffect(() => {
8975
+ const [mounted, setMounted] = React37__namespace.default.useState(open);
8976
+ React37__namespace.default.useEffect(() => {
8390
8977
  if (open) {
8391
8978
  setMounted(true);
8392
8979
  return;
@@ -8397,7 +8984,7 @@ function Drawer({
8397
8984
  useScrollLock(open);
8398
8985
  useInertBackground(panelRef, open && mounted);
8399
8986
  useFocusTrap(panelRef, open && mounted);
8400
- React36__namespace.default.useEffect(() => {
8987
+ React37__namespace.default.useEffect(() => {
8401
8988
  if (!open) return void 0;
8402
8989
  const onKey = (e) => {
8403
8990
  if (e.key === "Escape") {
@@ -8486,11 +9073,11 @@ function Field({
8486
9073
  ...rest
8487
9074
  }) {
8488
9075
  const __twcStyles = useScopedStyles("twc-field-styles", FIELD_CSS5);
8489
- const autoId = React36__namespace.default.useId();
9076
+ const autoId = React37__namespace.default.useId();
8490
9077
  const fieldId = id || autoId;
8491
9078
  const descId = `${fieldId}-desc`;
8492
9079
  const hasMsg = Boolean(error || hint);
8493
- const control = React36__namespace.default.isValidElement(children) ? React36__namespace.default.cloneElement(children, {
9080
+ const control = React37__namespace.default.isValidElement(children) ? React37__namespace.default.cloneElement(children, {
8494
9081
  "aria-describedby": [children.props["aria-describedby"], hasMsg ? descId : null].filter(Boolean).join(" ") || void 0,
8495
9082
  "aria-invalid": children.props["aria-invalid"] !== void 0 ? children.props["aria-invalid"] : error ? true : void 0
8496
9083
  }) : children;
@@ -8582,11 +9169,11 @@ function FileUpload({
8582
9169
  ...rest
8583
9170
  }) {
8584
9171
  const __twcStyles = useScopedStyles("twc-upload-styles", UPLOAD_CSS);
8585
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
9172
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
8586
9173
  const files = value !== void 0 ? value : internal;
8587
- const [drag, setDrag] = React36__namespace.default.useState(false);
8588
- const inputRef = React36__namespace.default.useRef(null);
8589
- const autoId = React36__namespace.default.useId();
9174
+ const [drag, setDrag] = React37__namespace.default.useState(false);
9175
+ const inputRef = React37__namespace.default.useRef(null);
9176
+ const autoId = React37__namespace.default.useId();
8590
9177
  const fieldId = id || autoId;
8591
9178
  const descId = `${fieldId}-desc`;
8592
9179
  const invalid = Boolean(error);
@@ -8809,15 +9396,15 @@ function Kanban({
8809
9396
  ...rest
8810
9397
  }) {
8811
9398
  const __twcStyles = useScopedStyles("twc-kanban-styles", KANBAN_CSS);
8812
- const [internal, setInternal] = React36__namespace.default.useState(cards ?? defaultCards ?? []);
9399
+ const [internal, setInternal] = React37__namespace.default.useState(cards ?? defaultCards ?? []);
8813
9400
  const items = cards !== void 0 ? cards : internal;
8814
- const [drag, setDrag] = React36__namespace.default.useState(null);
8815
- const [overCol, setOverCol] = React36__namespace.default.useState(null);
8816
- const [grab, setGrab] = React36__namespace.default.useState(null);
8817
- const [announce, setAnnounce] = React36__namespace.default.useState("");
8818
- const rootRef = React36__namespace.default.useRef(null);
8819
- const focusIdRef = React36__namespace.default.useRef(null);
8820
- React36__namespace.default.useEffect(() => {
9401
+ const [drag, setDrag] = React37__namespace.default.useState(null);
9402
+ const [overCol, setOverCol] = React37__namespace.default.useState(null);
9403
+ const [grab, setGrab] = React37__namespace.default.useState(null);
9404
+ const [announce, setAnnounce] = React37__namespace.default.useState("");
9405
+ const rootRef = React37__namespace.default.useRef(null);
9406
+ const focusIdRef = React37__namespace.default.useRef(null);
9407
+ React37__namespace.default.useEffect(() => {
8821
9408
  if (focusIdRef.current == null) return void 0;
8822
9409
  const raf = requestAnimationFrame(() => {
8823
9410
  const id = focusIdRef.current;
@@ -9127,21 +9714,21 @@ function Popover({
9127
9714
  ...rest
9128
9715
  }) {
9129
9716
  const __twcStyles = useScopedStyles("twc-popover-styles", POPOVER_CSS);
9130
- const [openState, setOpenState] = React36__namespace.default.useState(defaultOpen);
9131
- const [render, setRender] = React36__namespace.default.useState(false);
9132
- const [pos, setPos] = React36__namespace.default.useState(null);
9133
- const wrapRef = React36__namespace.default.useRef(null);
9134
- const popRef = React36__namespace.default.useRef(null);
9135
- const popId = React36__namespace.default.useId();
9717
+ const [openState, setOpenState] = React37__namespace.default.useState(defaultOpen);
9718
+ const [render, setRender] = React37__namespace.default.useState(false);
9719
+ const [pos, setPos] = React37__namespace.default.useState(null);
9720
+ const wrapRef = React37__namespace.default.useRef(null);
9721
+ const popRef = React37__namespace.default.useRef(null);
9722
+ const popId = React37__namespace.default.useId();
9136
9723
  const controlled = openProp !== void 0;
9137
9724
  const open = controlled ? !!openProp : openState;
9138
- const openRef = React36__namespace.default.useRef(open);
9725
+ const openRef = React37__namespace.default.useRef(open);
9139
9726
  openRef.current = open;
9140
- const controlledRef = React36__namespace.default.useRef(controlled);
9727
+ const controlledRef = React37__namespace.default.useRef(controlled);
9141
9728
  controlledRef.current = controlled;
9142
- const onOpenChangeRef = React36__namespace.default.useRef(onOpenChange);
9729
+ const onOpenChangeRef = React37__namespace.default.useRef(onOpenChange);
9143
9730
  onOpenChangeRef.current = onOpenChange;
9144
- const setOpen = React36__namespace.default.useCallback((next) => {
9731
+ const setOpen = React37__namespace.default.useCallback((next) => {
9145
9732
  const value = typeof next === "function" ? next(openRef.current) : next;
9146
9733
  if (value === openRef.current) return;
9147
9734
  if (!controlledRef.current) setOpenState(value);
@@ -9149,7 +9736,7 @@ function Popover({
9149
9736
  }, []);
9150
9737
  const toggle = () => setOpen((o) => !o);
9151
9738
  const RD = { createPortal: typeof reactDom.createPortal === "function" ? reactDom.createPortal : typeof window !== "undefined" && window.ReactDOM && window.ReactDOM.createPortal };
9152
- const place = React36__namespace.default.useCallback(() => {
9739
+ const place = React37__namespace.default.useCallback(() => {
9153
9740
  const t = wrapRef.current;
9154
9741
  if (!t) return;
9155
9742
  const r = t.getBoundingClientRect();
@@ -9186,7 +9773,7 @@ function Popover({
9186
9773
  arrow = { top: Math.min(Math.max(cy - top - 5.5, 8), ph - 18), [onRight ? "left" : "right"]: -6 };
9187
9774
  setPos({ top, left, width: w, flip: false, arrow });
9188
9775
  }, [placement, align, width]);
9189
- React36__namespace.default.useEffect(() => {
9776
+ React37__namespace.default.useEffect(() => {
9190
9777
  if (!open) return;
9191
9778
  place();
9192
9779
  const onMove = () => place();
@@ -9209,7 +9796,7 @@ function Popover({
9209
9796
  document.removeEventListener("keydown", onKey);
9210
9797
  };
9211
9798
  }, [open, place]);
9212
- React36__namespace.default.useEffect(() => {
9799
+ React37__namespace.default.useEffect(() => {
9213
9800
  if (open) {
9214
9801
  setRender(true);
9215
9802
  return;
@@ -9217,12 +9804,12 @@ function Popover({
9217
9804
  const t = setTimeout(() => setRender(false), 170);
9218
9805
  return () => clearTimeout(t);
9219
9806
  }, [open]);
9220
- React36__namespace.default.useEffect(() => {
9807
+ React37__namespace.default.useEffect(() => {
9221
9808
  if (render && open) place();
9222
9809
  }, [render, place]);
9223
- const restoreRef = React36__namespace.default.useRef(null);
9224
- const needFocusRef = React36__namespace.default.useRef(false);
9225
- React36__namespace.default.useEffect(() => {
9810
+ const restoreRef = React37__namespace.default.useRef(null);
9811
+ const needFocusRef = React37__namespace.default.useRef(false);
9812
+ React37__namespace.default.useEffect(() => {
9226
9813
  if (open) {
9227
9814
  restoreRef.current = document.activeElement;
9228
9815
  needFocusRef.current = true;
@@ -9257,7 +9844,7 @@ function Popover({
9257
9844
  ]
9258
9845
  }
9259
9846
  ) : null;
9260
- const triggerEl = React36__namespace.default.isValidElement(trigger) ? React36__namespace.default.cloneElement(trigger, {
9847
+ const triggerEl = React37__namespace.default.isValidElement(trigger) ? React37__namespace.default.cloneElement(trigger, {
9261
9848
  onClick: (e) => {
9262
9849
  trigger.props.onClick?.(e);
9263
9850
  toggle();
@@ -9300,7 +9887,7 @@ function Progress({
9300
9887
  className = "",
9301
9888
  ...rest
9302
9889
  }) {
9303
- const labelId = React36__namespace.default.useId();
9890
+ const labelId = React37__namespace.default.useId();
9304
9891
  const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...restProps } = rest;
9305
9892
  const __twcStyles = useScopedStyles("twc-progress-styles", `
9306
9893
  .twc-progress-wrap { display: flex; flex-direction: column; gap: 6px; font-family: var(--font-sans); }
@@ -9423,7 +10010,7 @@ function Radio({
9423
10010
  .twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
9424
10011
  .twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
9425
10012
  `);
9426
- const autoId = React36__namespace.default.useId();
10013
+ const autoId = React37__namespace.default.useId();
9427
10014
  const fieldId = id || autoId;
9428
10015
  const errId = `${fieldId}-error`;
9429
10016
  const invalid = Boolean(error);
@@ -9493,13 +10080,13 @@ function RadioGroup({
9493
10080
  ...rest
9494
10081
  }) {
9495
10082
  const __twcStyles = useScopedStyles("twc-radio-group-styles", RADIO_GROUP_CSS);
9496
- const autoId = React36__namespace.default.useId();
10083
+ const autoId = React37__namespace.default.useId();
9497
10084
  const fieldId = id || autoId;
9498
10085
  const labelId = `${fieldId}-label`;
9499
10086
  const descId = `${fieldId}-desc`;
9500
10087
  const groupName = name || `${fieldId}-name`;
9501
10088
  const invalid = Boolean(error);
9502
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
10089
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
9503
10090
  const current = value !== void 0 ? value : internal;
9504
10091
  const select = (v) => {
9505
10092
  if (value === void 0) setInternal(v);
@@ -9520,10 +10107,10 @@ function RadioGroup({
9520
10107
  tone
9521
10108
  },
9522
10109
  o.value
9523
- )) : React36__namespace.default.Children.map(children, (child) => {
9524
- if (!React36__namespace.default.isValidElement(child)) return child;
10110
+ )) : React37__namespace.default.Children.map(children, (child) => {
10111
+ if (!React37__namespace.default.isValidElement(child)) return child;
9525
10112
  const v = child.props.value;
9526
- return React36__namespace.default.cloneElement(child, {
10113
+ return React37__namespace.default.cloneElement(child, {
9527
10114
  name: child.props.name ?? groupName,
9528
10115
  checked: child.props.checked ?? current === v,
9529
10116
  onChange: child.props.onChange ?? (() => select(v)),
@@ -9603,12 +10190,12 @@ function Rating({
9603
10190
  ...rest
9604
10191
  }) {
9605
10192
  const __twcStyles = useScopedStyles("twc-rating-styles", RATING_CSS);
9606
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue);
9607
- const [hover, setHover] = React36__namespace.default.useState(0);
10193
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue);
10194
+ const [hover, setHover] = React37__namespace.default.useState(0);
9608
10195
  const val = value !== void 0 ? value : internal;
9609
10196
  const shown = hover || val;
9610
10197
  const interactive = !readOnly && !disabled;
9611
- const btnRefs = React36__namespace.default.useRef([]);
10198
+ const btnRefs = React37__namespace.default.useRef([]);
9612
10199
  const tabStar = Math.min(count, Math.max(1, Math.round(val) || 1));
9613
10200
  const fmt = (v) => format ? format(v) : Number.isInteger(v) ? String(v) : v.toFixed(1);
9614
10201
  if (process.env.NODE_ENV !== "production" && interactive && !Number.isInteger(val)) {
@@ -9795,24 +10382,24 @@ function Sidebar({
9795
10382
  ...rest
9796
10383
  }) {
9797
10384
  const __twcStyles = useScopedStyles("twc-sidebar-styles", SIDEBAR_CSS);
9798
- const navId = React36__namespace.default.useId();
9799
- const panelRef = React36__namespace.default.useRef(null);
10385
+ const navId = React37__namespace.default.useId();
10386
+ const panelRef = React37__namespace.default.useRef(null);
9800
10387
  const renderPortal = usePortal();
9801
- const [internal, setInternal] = React36__namespace.default.useState(defaultCollapsed);
10388
+ const [internal, setInternal] = React37__namespace.default.useState(defaultCollapsed);
9802
10389
  const collapsed = collapsedProp !== void 0 ? collapsedProp : internal;
9803
10390
  const toggle = () => {
9804
10391
  const next = !collapsed;
9805
10392
  if (collapsedProp === void 0) setInternal(next);
9806
10393
  onCollapsedChange?.(next);
9807
10394
  };
9808
- const [openInternal, setOpenInternal] = React36__namespace.default.useState(defaultOpen);
10395
+ const [openInternal, setOpenInternal] = React37__namespace.default.useState(defaultOpen);
9809
10396
  const open = openProp !== void 0 ? openProp : openInternal;
9810
10397
  const setOpen = (next) => {
9811
10398
  if (openProp === void 0) setOpenInternal(next);
9812
10399
  onOpenChange?.(next);
9813
10400
  };
9814
- const [mounted, setMounted] = React36__namespace.default.useState(open);
9815
- React36__namespace.default.useEffect(() => {
10401
+ const [mounted, setMounted] = React37__namespace.default.useState(open);
10402
+ React37__namespace.default.useEffect(() => {
9816
10403
  if (!overlay) return void 0;
9817
10404
  if (open) {
9818
10405
  setMounted(true);
@@ -9821,7 +10408,7 @@ function Sidebar({
9821
10408
  const t = setTimeout(() => setMounted(false), 170);
9822
10409
  return () => clearTimeout(t);
9823
10410
  }, [overlay, open]);
9824
- React36__namespace.default.useEffect(() => {
10411
+ React37__namespace.default.useEffect(() => {
9825
10412
  if (!overlay || !open) return void 0;
9826
10413
  const prev = document.body.style.overflow;
9827
10414
  document.body.style.overflow = "hidden";
@@ -9830,7 +10417,7 @@ function Sidebar({
9830
10417
  };
9831
10418
  }, [overlay, open]);
9832
10419
  useFocusTrap(panelRef, overlay && open && mounted);
9833
- React36__namespace.default.useEffect(() => {
10420
+ React37__namespace.default.useEffect(() => {
9834
10421
  if (!overlay || !open) return void 0;
9835
10422
  const onKey = (e) => {
9836
10423
  if (e.key === "Escape") {
@@ -9882,7 +10469,7 @@ function Sidebar({
9882
10469
  const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9883
10470
  __twcStyles,
9884
10471
  brand ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-sidebar__head", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-sidebar__brand", children: brand }) }) : null,
9885
- /* @__PURE__ */ jsxRuntime.jsx("nav", { id: navId, className: "twc-sidebar__nav", "aria-label": navLabel, children: groups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React36__namespace.default.Fragment, { children: [
10472
+ /* @__PURE__ */ jsxRuntime.jsx("nav", { id: navId, className: "twc-sidebar__nav", "aria-label": navLabel, children: groups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React37__namespace.default.Fragment, { children: [
9886
10473
  g.section != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-sidebar__section", id: g.sid, children: g.section }) : null,
9887
10474
  /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "twc-sidebar__list", ...g.section != null ? { "aria-labelledby": g.sid } : {}, children: g.entries.map(({ it, i }) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: renderItem(it) }, i)) })
9888
10475
  ] }, gi)) }),
@@ -10051,10 +10638,10 @@ function Slider({
10051
10638
  return Math.min(max, Math.max(min, Math.round(stepped * 1e6) / 1e6));
10052
10639
  };
10053
10640
  const __twcStyles = useScopedStyles("twc-slider-styles", SLIDER_CSS);
10054
- const autoId = React36__namespace.default.useId();
10641
+ const autoId = React37__namespace.default.useId();
10055
10642
  const fieldId = id || autoId;
10056
10643
  const isRange = range || Array.isArray(value) || Array.isArray(defaultValue);
10057
- const [internal, setInternal] = React36__namespace.default.useState(() => {
10644
+ const [internal, setInternal] = React37__namespace.default.useState(() => {
10058
10645
  if (isRange) {
10059
10646
  const dv = Array.isArray(defaultValue) ? defaultValue : [min, max];
10060
10647
  return [clampSnap(dv[0]), clampSnap(dv[1])];
@@ -10064,8 +10651,8 @@ function Slider({
10064
10651
  const rawVal = value !== void 0 ? value : internal;
10065
10652
  const clampedVals = (isRange ? [Number(rawVal[0]), Number(rawVal[1])] : [Number(rawVal)]).map((v) => Math.min(max, Math.max(min, Number.isFinite(v) ? v : min)));
10066
10653
  const indices = isRange ? [0, 1] : [0];
10067
- const trackRef = React36__namespace.default.useRef(null);
10068
- const [dragging, setDragging] = React36__namespace.default.useState(false);
10654
+ const trackRef = React37__namespace.default.useRef(null);
10655
+ const [dragging, setDragging] = React37__namespace.default.useState(false);
10069
10656
  const fmt = (v) => formatValue ? formatValue(v) : v.toFixed(decimals);
10070
10657
  const valueTextFor = (v) => {
10071
10658
  if (getAriaValueText) return getAriaValueText(v);
@@ -10096,8 +10683,8 @@ function Slider({
10096
10683
  const ratio = Math.min(1, Math.max(0, (clientX - r.left) / r.width));
10097
10684
  return clampSnap(min + ratio * (max - min));
10098
10685
  };
10099
- const dragCleanupRef = React36__namespace.default.useRef(null);
10100
- React36__namespace.default.useEffect(() => () => dragCleanupRef.current?.(), []);
10686
+ const dragCleanupRef = React37__namespace.default.useRef(null);
10687
+ React37__namespace.default.useEffect(() => () => dragCleanupRef.current?.(), []);
10101
10688
  function onPointerDown(e) {
10102
10689
  if (disabled) return;
10103
10690
  e.preventDefault();
@@ -10328,7 +10915,7 @@ function Stepper({
10328
10915
  ...rest
10329
10916
  }) {
10330
10917
  const __twcStyles = useScopedStyles("twc-stepper-styles", STEPPER_CSS);
10331
- const [activeInternal, setActiveInternal] = React36__namespace.default.useState(defaultActive);
10918
+ const [activeInternal, setActiveInternal] = React37__namespace.default.useState(defaultActive);
10332
10919
  const active = activeProp !== void 0 ? activeProp : activeInternal;
10333
10920
  const handleStep = (i) => {
10334
10921
  if (activeProp === void 0) setActiveInternal(i);
@@ -10460,7 +11047,7 @@ function Switch({
10460
11047
  .twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
10461
11048
  .twc-field__error { font-size: var(--text-xs); color: var(--color-danger-subtle-fg); font-weight: var(--font-medium); }
10462
11049
  `);
10463
- const autoId = React36__namespace.default.useId();
11050
+ const autoId = React37__namespace.default.useId();
10464
11051
  const fieldId = id || autoId;
10465
11052
  const errId = `${fieldId}-error`;
10466
11053
  const invalid = Boolean(error);
@@ -10563,14 +11150,14 @@ function Table({
10563
11150
  ...rest
10564
11151
  }) {
10565
11152
  const __twcStyles = useScopedStyles("twc-table-styles", TABLE_CSS);
10566
- const cols = React36__namespace.default.useMemo(
11153
+ const cols = React37__namespace.default.useMemo(
10567
11154
  () => (columns || []).map((c) => ({ ...c, header: c.headerName, render: c.renderCell })),
10568
11155
  [columns]
10569
11156
  );
10570
11157
  const dataRows = rowsProp || [];
10571
- const [internalSort, setInternalSort] = React36__namespace.default.useState(defaultSort || { field: null, dir: "asc" });
11158
+ const [internalSort, setInternalSort] = React37__namespace.default.useState(defaultSort || { field: null, dir: "asc" });
10572
11159
  const sort = (sortProp !== void 0 ? sortProp : internalSort) || { field: null, dir: "asc" };
10573
- const rows = React36__namespace.default.useMemo(() => {
11160
+ const rows = React37__namespace.default.useMemo(() => {
10574
11161
  if (!sortable || !sort.field) return dataRows;
10575
11162
  const col = cols.find((c) => c.field === sort.field);
10576
11163
  if (!col) return dataRows;
@@ -10717,15 +11304,15 @@ function Tabs({
10717
11304
  }) {
10718
11305
  const vertical = orientation === "vertical";
10719
11306
  const __twcStyles = useScopedStyles("twc-tabs-styles", TABS_CSS);
10720
- const [internal, setInternal] = React36__namespace.default.useState(defaultValue ?? items[0]?.value);
11307
+ const [internal, setInternal] = React37__namespace.default.useState(defaultValue ?? items[0]?.value);
10721
11308
  const active = value ?? internal;
10722
- const listRef = React36__namespace.default.useRef(null);
10723
- const [ind, setInd] = React36__namespace.default.useState({ left: 0, width: 0, top: 0, height: 0 });
10724
- const baseId = React36__namespace.default.useId();
11309
+ const listRef = React37__namespace.default.useRef(null);
11310
+ const [ind, setInd] = React37__namespace.default.useState({ left: 0, width: 0, top: 0, height: 0 });
11311
+ const baseId = React37__namespace.default.useId();
10725
11312
  const tabIdAt = (i) => `${baseId}-tab-${i}`;
10726
11313
  const panelId = `${baseId}-panel`;
10727
11314
  const activeIndex = items.findIndex((it) => it.value === active);
10728
- const updateIndicator = React36__namespace.default.useCallback(() => {
11315
+ const updateIndicator = React37__namespace.default.useCallback(() => {
10729
11316
  const list = listRef.current;
10730
11317
  if (!list) return;
10731
11318
  const el = list.querySelector('[data-active="true"]');
@@ -10734,10 +11321,10 @@ function Tabs({
10734
11321
  if (!vertical) el.scrollIntoView?.({ inline: "nearest", block: "nearest" });
10735
11322
  }
10736
11323
  }, [vertical]);
10737
- React36__namespace.default.useEffect(() => {
11324
+ React37__namespace.default.useEffect(() => {
10738
11325
  updateIndicator();
10739
11326
  }, [active, updateIndicator, items, orientation]);
10740
- React36__namespace.default.useEffect(() => {
11327
+ React37__namespace.default.useEffect(() => {
10741
11328
  const r = () => updateIndicator();
10742
11329
  window.addEventListener("resize", r);
10743
11330
  if (typeof document !== "undefined" && document.fonts && document.fonts.ready) {
@@ -10882,7 +11469,7 @@ function Tag({
10882
11469
  }, "aria-label": _removeLabel, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
10883
11470
  ] });
10884
11471
  }
10885
- var useIso = typeof document !== "undefined" ? React36__namespace.default.useLayoutEffect : React36__namespace.default.useEffect;
11472
+ var useIso = typeof document !== "undefined" ? React37__namespace.default.useLayoutEffect : React37__namespace.default.useEffect;
10886
11473
  var TEXTAREA_CSS = `
10887
11474
  .twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
10888
11475
  .twc-field__label { font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--color-text); display: flex; gap: 4px; align-items: center; }
@@ -10918,7 +11505,7 @@ var TEXTAREA_CSS = `
10918
11505
  .twc-field__count { margin-inline-start: auto; font-size: var(--text-xs); color: var(--color-text-muted); font-variant-numeric: tabular-nums; flex: none; }
10919
11506
  .twc-field__count[data-danger="true"] { color: var(--color-danger-subtle-fg); }
10920
11507
  `;
10921
- var Textarea = React36__namespace.default.forwardRef(function Textarea2({
11508
+ var Textarea = React37__namespace.default.forwardRef(function Textarea2({
10922
11509
  label,
10923
11510
  hint,
10924
11511
  error,
@@ -10936,19 +11523,19 @@ var Textarea = React36__namespace.default.forwardRef(function Textarea2({
10936
11523
  ...rest
10937
11524
  }, ref) {
10938
11525
  const __twcStyles = useScopedStyles("twc-textarea-styles", TEXTAREA_CSS);
10939
- const autoId = React36__namespace.default.useId();
11526
+ const autoId = React37__namespace.default.useId();
10940
11527
  const fieldId = id || autoId;
10941
11528
  const descId = `${fieldId}-desc`;
10942
11529
  const countId = `${fieldId}-count`;
10943
11530
  const invalid = Boolean(error);
10944
- const innerRef = React36__namespace.default.useRef(null);
11531
+ const innerRef = React37__namespace.default.useRef(null);
10945
11532
  const setRef = (el) => {
10946
11533
  innerRef.current = el;
10947
11534
  if (typeof ref === "function") ref(el);
10948
11535
  else if (ref) ref.current = el;
10949
11536
  };
10950
11537
  const countControlled = rest.value !== void 0;
10951
- const [len2, setLen] = React36__namespace.default.useState(() => String(rest.defaultValue ?? "").length);
11538
+ const [len2, setLen] = React37__namespace.default.useState(() => String(rest.defaultValue ?? "").length);
10952
11539
  const count = countControlled ? String(rest.value ?? "").length : len2;
10953
11540
  const max = rest.maxLength;
10954
11541
  const showCounter = showCount && max != null;
@@ -11126,19 +11713,19 @@ function Toast({
11126
11713
  }) {
11127
11714
  const resolvedTone = tone === "neutral" ? "default" : tone;
11128
11715
  const __twcStyles = useScopedStyles("twc-toast-styles", TOAST_CSS);
11129
- const onCloseRef = React36__namespace.default.useRef(onClose);
11130
- React36__namespace.default.useEffect(() => {
11716
+ const onCloseRef = React37__namespace.default.useRef(onClose);
11717
+ React37__namespace.default.useEffect(() => {
11131
11718
  onCloseRef.current = onClose;
11132
11719
  }, [onClose]);
11133
- const timer = React36__namespace.default.useRef();
11134
- const stop = React36__namespace.default.useCallback(() => clearTimeout(timer.current), []);
11135
- const start = React36__namespace.default.useCallback(() => {
11720
+ const timer = React37__namespace.default.useRef();
11721
+ const stop = React37__namespace.default.useCallback(() => clearTimeout(timer.current), []);
11722
+ const start = React37__namespace.default.useCallback(() => {
11136
11723
  stop();
11137
11724
  if (duration && duration !== Infinity && onCloseRef.current) {
11138
11725
  timer.current = setTimeout(() => onCloseRef.current && onCloseRef.current(), duration);
11139
11726
  }
11140
11727
  }, [duration, stop]);
11141
- React36__namespace.default.useEffect(() => {
11728
+ React37__namespace.default.useEffect(() => {
11142
11729
  start();
11143
11730
  return stop;
11144
11731
  }, [start, stop]);
@@ -11183,30 +11770,30 @@ function Toast({
11183
11770
  }
11184
11771
  function ToastViewport({ children, limit, className = "", ...rest }) {
11185
11772
  const __twcStyles = useScopedStyles("twc-toast-styles", TOAST_CSS);
11186
- const shown = limit && limit > 0 ? React36__namespace.default.Children.toArray(children).slice(-limit) : children;
11773
+ const shown = limit && limit > 0 ? React37__namespace.default.Children.toArray(children).slice(-limit) : children;
11187
11774
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-toast-viewport ${className}`, role: "region", "aria-label": "Notifications", ...rest, children: [
11188
11775
  __twcStyles,
11189
11776
  shown
11190
11777
  ] });
11191
11778
  }
11192
- var ToastContext = React36__namespace.default.createContext(null);
11779
+ var ToastContext = React37__namespace.default.createContext(null);
11193
11780
  function useToast() {
11194
- const ctx = React36__namespace.default.useContext(ToastContext);
11781
+ const ctx = React37__namespace.default.useContext(ToastContext);
11195
11782
  if (!ctx) throw new Error("useToast must be used within a <ToastProvider>.");
11196
11783
  return ctx;
11197
11784
  }
11198
11785
  function ToastProvider({ children, limit = 4, duration = 4500, ...viewportProps }) {
11199
- const [toasts, setToasts] = React36__namespace.default.useState([]);
11200
- const idRef = React36__namespace.default.useRef(0);
11201
- const limitRef = React36__namespace.default.useRef(limit);
11202
- React36__namespace.default.useEffect(() => {
11786
+ const [toasts, setToasts] = React37__namespace.default.useState([]);
11787
+ const idRef = React37__namespace.default.useRef(0);
11788
+ const limitRef = React37__namespace.default.useRef(limit);
11789
+ React37__namespace.default.useEffect(() => {
11203
11790
  limitRef.current = limit;
11204
11791
  }, [limit]);
11205
- const dismiss = React36__namespace.default.useCallback((id) => {
11792
+ const dismiss = React37__namespace.default.useCallback((id) => {
11206
11793
  setToasts((s) => s.filter((t) => t.id !== id));
11207
11794
  }, []);
11208
- const clear = React36__namespace.default.useCallback(() => setToasts([]), []);
11209
- const api = React36__namespace.default.useMemo(() => {
11795
+ const clear = React37__namespace.default.useCallback(() => setToasts([]), []);
11796
+ const api = React37__namespace.default.useMemo(() => {
11210
11797
  const push = (opts) => {
11211
11798
  const id = idRef.current += 1;
11212
11799
  const next = typeof opts === "string" ? { title: opts } : opts && typeof opts === "object" ? opts : {};
@@ -11227,7 +11814,7 @@ function ToastProvider({ children, limit = 4, duration = 4500, ...viewportProps
11227
11814
  toast.show = withTone("default");
11228
11815
  return { toast, dismiss, clear };
11229
11816
  }, [dismiss, clear]);
11230
- const value = React36__namespace.default.useMemo(() => ({ ...api, toasts }), [api, toasts]);
11817
+ const value = React37__namespace.default.useMemo(() => ({ ...api, toasts }), [api, toasts]);
11231
11818
  return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value, children: [
11232
11819
  children,
11233
11820
  /* @__PURE__ */ jsxRuntime.jsx(ToastViewport, { limit, ...viewportProps, children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -11335,13 +11922,13 @@ function TreeView({
11335
11922
  }) {
11336
11923
  const nodes = items;
11337
11924
  const __twcStyles = useScopedStyles("twc-tree-styles", TREE_CSS);
11338
- const [expInternal, setExpInternal] = React36__namespace.default.useState(() => new Set(defaultExpanded));
11925
+ const [expInternal, setExpInternal] = React37__namespace.default.useState(() => new Set(defaultExpanded));
11339
11926
  const expanded = expandedProp !== void 0 ? new Set(expandedProp) : expInternal;
11340
- const [selInternal, setSelInternal] = React36__namespace.default.useState(defaultSelectedId);
11927
+ const [selInternal, setSelInternal] = React37__namespace.default.useState(defaultSelectedId);
11341
11928
  const selectedId = selectedProp !== void 0 ? selectedProp : selInternal;
11342
- const [focusId, setFocusId] = React36__namespace.default.useState(null);
11343
- const rowRefs = React36__namespace.default.useRef(/* @__PURE__ */ new Map());
11344
- const taRef = React36__namespace.default.useRef({ str: "", t: 0 });
11929
+ const [focusId, setFocusId] = React37__namespace.default.useState(null);
11930
+ const rowRefs = React37__namespace.default.useRef(/* @__PURE__ */ new Map());
11931
+ const taRef = React37__namespace.default.useRef({ str: "", t: 0 });
11345
11932
  const toggle = (id) => {
11346
11933
  const n = new Set(expanded);
11347
11934
  n.has(id) ? n.delete(id) : n.add(id);
@@ -11473,7 +12060,7 @@ function AppShell({
11473
12060
  ...rest
11474
12061
  }) {
11475
12062
  const __twcStyles = useScopedStyles("twc-shell-styles", SHELL_CSS);
11476
- const wiredSidebar = React36__namespace.default.isValidElement(sidebar) && (sidebarOpen !== void 0 || onSidebarOpenChange !== void 0) ? React36__namespace.default.cloneElement(sidebar, {
12063
+ const wiredSidebar = React37__namespace.default.isValidElement(sidebar) && (sidebarOpen !== void 0 || onSidebarOpenChange !== void 0) ? React37__namespace.default.cloneElement(sidebar, {
11477
12064
  overlay: sidebar.props.overlay !== void 0 ? sidebar.props.overlay : true,
11478
12065
  open: sidebar.props.open !== void 0 ? sidebar.props.open : sidebarOpen,
11479
12066
  onOpenChange: sidebar.props.onOpenChange !== void 0 ? sidebar.props.onOpenChange : onSidebarOpenChange
@@ -11508,7 +12095,7 @@ function safeHref6(url) {
11508
12095
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11509
12096
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11510
12097
  }
11511
- var Box = React36__namespace.default.forwardRef(function Box2({
12098
+ var Box = React37__namespace.default.forwardRef(function Box2({
11512
12099
  as: Tag2 = "div",
11513
12100
  p,
11514
12101
  px,
@@ -11528,11 +12115,13 @@ var Box = React36__namespace.default.forwardRef(function Box2({
11528
12115
  border = false,
11529
12116
  radius,
11530
12117
  shadow,
12118
+ sx,
11531
12119
  className = "",
11532
12120
  style,
11533
12121
  children,
11534
12122
  ...rest
11535
12123
  }, ref) {
12124
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11536
12125
  const s = {
11537
12126
  paddingTop: sp(pt ?? py ?? p),
11538
12127
  paddingRight: sp(pr ?? px ?? p),
@@ -11546,10 +12135,14 @@ var Box = React36__namespace.default.forwardRef(function Box2({
11546
12135
  border: border ? "var(--border-thin, 1px) solid var(--color-border)" : void 0,
11547
12136
  borderRadius: radius ? `var(--radius-${radius})` : void 0,
11548
12137
  boxShadow: shadow ? `var(--shadow-${shadow})` : void 0,
11549
- ...style
12138
+ ...style,
12139
+ ...flatStyle
11550
12140
  };
11551
12141
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref6(rest.href);
11552
- return /* @__PURE__ */ jsxRuntime.jsx(Tag2, { ref, className: `twc-box ${className}`.trim(), style: s, ...rest, children });
12142
+ return /* @__PURE__ */ jsxRuntime.jsxs(Tag2, { ref, className: `twc-box ${className}`.trim(), style: s, "data-twc-sx": sxAttr, ...rest, children: [
12143
+ styleNode,
12144
+ children
12145
+ ] });
11553
12146
  });
11554
12147
  Box.displayName = "Box";
11555
12148
  var SIZES = { sm: 640, md: 768, lg: 1024, xl: 1280, full: "100%" };
@@ -11558,31 +12151,38 @@ function safeHref7(url) {
11558
12151
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11559
12152
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11560
12153
  }
11561
- var Container = React36__namespace.default.forwardRef(function Container2({
12154
+ var Container = React37__namespace.default.forwardRef(function Container2({
11562
12155
  as: Tag2 = "div",
11563
12156
  size = "lg",
11564
12157
  padded = true,
12158
+ sx,
11565
12159
  className = "",
11566
12160
  style,
11567
12161
  children,
11568
12162
  ...rest
11569
12163
  }, ref) {
12164
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11570
12165
  const max = SIZES[size] ?? size;
11571
12166
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref7(rest.href);
11572
- return /* @__PURE__ */ jsxRuntime.jsx(
12167
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11573
12168
  Tag2,
11574
12169
  {
11575
12170
  ref,
11576
12171
  className: `twc-container ${className}`.trim(),
12172
+ "data-twc-sx": sxAttr,
11577
12173
  style: {
11578
12174
  width: "100%",
11579
12175
  maxWidth: typeof max === "number" ? `${max}px` : max,
11580
12176
  marginInline: "auto",
11581
12177
  paddingInline: padded ? "var(--space-5)" : void 0,
11582
- ...style
12178
+ ...style,
12179
+ ...flatStyle
11583
12180
  },
11584
12181
  ...rest,
11585
- children
12182
+ children: [
12183
+ styleNode,
12184
+ children
12185
+ ]
11586
12186
  }
11587
12187
  );
11588
12188
  });
@@ -11601,7 +12201,7 @@ function safeHref8(url) {
11601
12201
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11602
12202
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11603
12203
  }
11604
- var Grid = React36__namespace.default.forwardRef(function Grid2({
12204
+ var Grid = React37__namespace.default.forwardRef(function Grid2({
11605
12205
  as: Tag2 = "div",
11606
12206
  columns,
11607
12207
  minChildWidth,
@@ -11612,13 +12212,15 @@ var Grid = React36__namespace.default.forwardRef(function Grid2({
11612
12212
  justify,
11613
12213
  alignContent,
11614
12214
  justifyContent,
12215
+ sx,
11615
12216
  className = "",
11616
12217
  style,
11617
12218
  children,
11618
12219
  ...rest
11619
12220
  }, ref) {
12221
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11620
12222
  const responsive = columns != null && typeof columns === "object";
11621
- const uid = React36__namespace.default.useId();
12223
+ const uid = React37__namespace.default.useId();
11622
12224
  const gridId = responsive ? `g${uid.replace(/[^a-zA-Z0-9]/g, "")}` : null;
11623
12225
  let css = "";
11624
12226
  if (responsive) {
@@ -11639,6 +12241,7 @@ var Grid = React36__namespace.default.forwardRef(function Grid2({
11639
12241
  ref,
11640
12242
  className: `twc-grid ${className}`.trim(),
11641
12243
  "data-twc-grid-id": gridId || void 0,
12244
+ "data-twc-sx": sxAttr,
11642
12245
  style: {
11643
12246
  display: "grid",
11644
12247
  gridTemplateColumns: templateColumns,
@@ -11648,11 +12251,13 @@ var Grid = React36__namespace.default.forwardRef(function Grid2({
11648
12251
  justifyItems: justify,
11649
12252
  alignContent,
11650
12253
  justifyContent,
11651
- ...style
12254
+ ...style,
12255
+ ...flatStyle
11652
12256
  },
11653
12257
  ...rest,
11654
12258
  children: [
11655
12259
  responsive ? __twcStyles : null,
12260
+ styleNode,
11656
12261
  children
11657
12262
  ]
11658
12263
  }
@@ -11669,7 +12274,7 @@ function safeHref9(url) {
11669
12274
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11670
12275
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11671
12276
  }
11672
- var Stack = React36__namespace.default.forwardRef(function Stack2({
12277
+ var Stack = React37__namespace.default.forwardRef(function Stack2({
11673
12278
  as: Tag2 = "div",
11674
12279
  direction = "column",
11675
12280
  gap = 4,
@@ -11685,18 +12290,21 @@ var Stack = React36__namespace.default.forwardRef(function Stack2({
11685
12290
  pb,
11686
12291
  pl,
11687
12292
  divider,
12293
+ sx,
11688
12294
  className = "",
11689
12295
  style,
11690
12296
  children,
11691
12297
  ...rest
11692
12298
  }, ref) {
12299
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11693
12300
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref9(rest.href);
11694
- const kids = divider != null ? React36__namespace.default.Children.toArray(children).flatMap((child, i, arr) => i < arr.length - 1 ? [child, /* @__PURE__ */ jsxRuntime.jsx(React36__namespace.default.Fragment, { children: divider }, `twc-stack-div-${i}`)] : [child]) : children;
11695
- return /* @__PURE__ */ jsxRuntime.jsx(
12301
+ const kids = divider != null ? React37__namespace.default.Children.toArray(children).flatMap((child, i, arr) => i < arr.length - 1 ? [child, /* @__PURE__ */ jsxRuntime.jsx(React37__namespace.default.Fragment, { children: divider }, `twc-stack-div-${i}`)] : [child]) : children;
12302
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11696
12303
  Tag2,
11697
12304
  {
11698
12305
  ref,
11699
12306
  className: `twc-stack ${className}`.trim(),
12307
+ "data-twc-sx": sxAttr,
11700
12308
  style: {
11701
12309
  display: inline ? "inline-flex" : "flex",
11702
12310
  flexDirection: direction,
@@ -11709,10 +12317,14 @@ var Stack = React36__namespace.default.forwardRef(function Stack2({
11709
12317
  paddingBottom: space2(pb ?? py ?? p),
11710
12318
  paddingLeft: space2(pl ?? px ?? p),
11711
12319
  minWidth: 0,
11712
- ...style
12320
+ ...style,
12321
+ ...flatStyle
11713
12322
  },
11714
12323
  ...rest,
11715
- children: kids
12324
+ children: [
12325
+ styleNode,
12326
+ kids
12327
+ ]
11716
12328
  }
11717
12329
  );
11718
12330
  });
@@ -11758,10 +12370,10 @@ function Code({
11758
12370
  const __twcStyles = useScopedStyles("twc-code-styles", CODE_CSS);
11759
12371
  const Tag2 = as ?? (block ? "pre" : "code");
11760
12372
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref10(rest.href);
11761
- const rootRef = React36__namespace.default.useRef(null);
11762
- const [copied, setCopied] = React36__namespace.default.useState(false);
11763
- const timerRef = React36__namespace.default.useRef(null);
11764
- React36__namespace.default.useEffect(() => () => clearTimeout(timerRef.current), []);
12373
+ const rootRef = React37__namespace.default.useRef(null);
12374
+ const [copied, setCopied] = React37__namespace.default.useState(false);
12375
+ const timerRef = React37__namespace.default.useRef(null);
12376
+ React37__namespace.default.useEffect(() => () => clearTimeout(timerRef.current), []);
11765
12377
  const doCopy = () => {
11766
12378
  if (typeof navigator === "undefined" || !navigator.clipboard) return;
11767
12379
  const text = typeof children === "string" ? children : rootRef.current?.textContent ?? "";
@@ -11787,7 +12399,7 @@ function safeHref11(url) {
11787
12399
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11788
12400
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11789
12401
  }
11790
- var Heading = React36__namespace.default.forwardRef(function Heading2({
12402
+ var Heading = React37__namespace.default.forwardRef(function Heading2({
11791
12403
  as,
11792
12404
  level = 2,
11793
12405
  size,
@@ -11795,19 +12407,22 @@ var Heading = React36__namespace.default.forwardRef(function Heading2({
11795
12407
  align,
11796
12408
  truncate,
11797
12409
  lineClamp,
12410
+ sx,
11798
12411
  className = "",
11799
12412
  style,
11800
12413
  children,
11801
12414
  ...rest
11802
12415
  }, ref) {
12416
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11803
12417
  const Tag2 = as || `h${level}`;
11804
12418
  const sz = size || (display ? "display" : LEVEL_SIZE[level]) || "2xl";
11805
12419
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref11(rest.href);
11806
- return /* @__PURE__ */ jsxRuntime.jsx(
12420
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11807
12421
  Tag2,
11808
12422
  {
11809
12423
  ref,
11810
12424
  className: `twc-heading ${className}`.trim(),
12425
+ "data-twc-sx": sxAttr,
11811
12426
  style: {
11812
12427
  margin: 0,
11813
12428
  fontFamily: "var(--font-sans)",
@@ -11818,10 +12433,14 @@ var Heading = React36__namespace.default.forwardRef(function Heading2({
11818
12433
  fontSize: `var(--text-${sz})`,
11819
12434
  textAlign: align,
11820
12435
  ...lineClamp != null ? { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: lineClamp, overflow: "hidden" } : truncate ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 } : null,
11821
- ...style
12436
+ ...style,
12437
+ ...flatStyle
11822
12438
  },
11823
12439
  ...rest,
11824
- children
12440
+ children: [
12441
+ styleNode,
12442
+ children
12443
+ ]
11825
12444
  }
11826
12445
  );
11827
12446
  });
@@ -11846,7 +12465,7 @@ function safeHref12(url) {
11846
12465
  const s = String(url).replace(/[\x00-\x20]+/g, "").toLowerCase();
11847
12466
  return s.startsWith("javascript:") || s.startsWith("data:") || s.startsWith("vbscript:") ? void 0 : url;
11848
12467
  }
11849
- var Text = React36__namespace.default.forwardRef(function Text2({
12468
+ var Text = React37__namespace.default.forwardRef(function Text2({
11850
12469
  as: Tag2 = "p",
11851
12470
  size = "base",
11852
12471
  tone = "default",
@@ -11854,18 +12473,21 @@ var Text = React36__namespace.default.forwardRef(function Text2({
11854
12473
  align,
11855
12474
  truncate,
11856
12475
  lineClamp,
12476
+ sx,
11857
12477
  className = "",
11858
12478
  style,
11859
12479
  children,
11860
12480
  ...rest
11861
12481
  }, ref) {
12482
+ const { flatStyle, styleNode, sxAttr } = useSx(sx);
11862
12483
  if (Tag2 === "a" && rest.href != null) rest.href = safeHref12(rest.href);
11863
12484
  const toneToken = TONE[tone] || TONE.default;
11864
- return /* @__PURE__ */ jsxRuntime.jsx(
12485
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11865
12486
  Tag2,
11866
12487
  {
11867
12488
  ref,
11868
12489
  className: `twc-text ${className}`.trim(),
12490
+ "data-twc-sx": sxAttr,
11869
12491
  style: {
11870
12492
  margin: 0,
11871
12493
  fontFamily: "var(--font-sans)",
@@ -11875,54 +12497,58 @@ var Text = React36__namespace.default.forwardRef(function Text2({
11875
12497
  fontWeight: weight ? `var(--font-${weight})` : void 0,
11876
12498
  textAlign: align,
11877
12499
  ...lineClamp != null ? { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: lineClamp, overflow: "hidden" } : truncate ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 } : null,
11878
- ...style
12500
+ ...style,
12501
+ ...flatStyle
11879
12502
  },
11880
12503
  ...rest,
11881
- children
12504
+ children: [
12505
+ styleNode,
12506
+ children
12507
+ ]
11882
12508
  }
11883
12509
  );
11884
12510
  });
11885
12511
  Text.displayName = "Text";
11886
12512
  var canUseDOM2 = typeof window !== "undefined" && typeof document !== "undefined";
11887
- var useIsomorphicLayoutEffect = canUseDOM2 ? React36__namespace.default.useLayoutEffect : React36__namespace.default.useEffect;
12513
+ var useIsomorphicLayoutEffect = canUseDOM2 ? React37__namespace.default.useLayoutEffect : React37__namespace.default.useEffect;
11888
12514
  function useMounted() {
11889
- const [mounted, setMounted] = React36__namespace.default.useState(false);
11890
- React36__namespace.default.useEffect(() => {
12515
+ const [mounted, setMounted] = React37__namespace.default.useState(false);
12516
+ React37__namespace.default.useEffect(() => {
11891
12517
  setMounted(true);
11892
12518
  }, []);
11893
12519
  return mounted;
11894
12520
  }
11895
12521
  function usePrevious(value) {
11896
- const ref = React36__namespace.default.useRef(void 0);
11897
- React36__namespace.default.useEffect(() => {
12522
+ const ref = React37__namespace.default.useRef(void 0);
12523
+ React37__namespace.default.useEffect(() => {
11898
12524
  ref.current = value;
11899
12525
  }, [value]);
11900
12526
  return ref.current;
11901
12527
  }
11902
12528
  function useToggle(initial = false) {
11903
- const [on, setOn] = React36__namespace.default.useState(initial);
11904
- const toggle = React36__namespace.default.useCallback((next) => {
12529
+ const [on, setOn] = React37__namespace.default.useState(initial);
12530
+ const toggle = React37__namespace.default.useCallback((next) => {
11905
12531
  setOn((prev) => typeof next === "boolean" ? next : !prev);
11906
12532
  }, []);
11907
12533
  return [on, toggle, setOn];
11908
12534
  }
11909
12535
  function useDisclosure(initial = false) {
11910
- const [open, setOpen] = React36__namespace.default.useState(initial);
11911
- const onOpen = React36__namespace.default.useCallback(() => setOpen(true), []);
11912
- const onClose = React36__namespace.default.useCallback(() => setOpen(false), []);
11913
- const onToggle = React36__namespace.default.useCallback(() => setOpen((p) => !p), []);
12536
+ const [open, setOpen] = React37__namespace.default.useState(initial);
12537
+ const onOpen = React37__namespace.default.useCallback(() => setOpen(true), []);
12538
+ const onClose = React37__namespace.default.useCallback(() => setOpen(false), []);
12539
+ const onToggle = React37__namespace.default.useCallback(() => setOpen((p) => !p), []);
11914
12540
  return { open, onOpen, onClose, onToggle, setOpen };
11915
12541
  }
11916
12542
  function useControllableState({ value, defaultValue, onChange } = {}) {
11917
12543
  const isControlled = value !== void 0;
11918
- const [uncontrolled, setUncontrolled] = React36__namespace.default.useState(defaultValue);
12544
+ const [uncontrolled, setUncontrolled] = React37__namespace.default.useState(defaultValue);
11919
12545
  const current = isControlled ? value : uncontrolled;
11920
- const ref = React36__namespace.default.useRef({ current, isControlled, onChange });
12546
+ const ref = React37__namespace.default.useRef({ current, isControlled, onChange });
11921
12547
  useIsomorphicLayoutEffect(() => {
11922
12548
  ref.current = { current, isControlled, onChange };
11923
12549
  });
11924
- const wasControlled = React36__namespace.default.useRef(isControlled);
11925
- React36__namespace.default.useEffect(() => {
12550
+ const wasControlled = React37__namespace.default.useRef(isControlled);
12551
+ React37__namespace.default.useEffect(() => {
11926
12552
  if (wasControlled.current !== isControlled) {
11927
12553
  warnOnce(
11928
12554
  "useControllableState:switch",
@@ -11931,7 +12557,7 @@ function useControllableState({ value, defaultValue, onChange } = {}) {
11931
12557
  wasControlled.current = isControlled;
11932
12558
  }
11933
12559
  });
11934
- const setValue = React36__namespace.default.useCallback((next) => {
12560
+ const setValue = React37__namespace.default.useCallback((next) => {
11935
12561
  const { current: cur, isControlled: ctrl, onChange: cb } = ref.current;
11936
12562
  const resolved = typeof next === "function" ? next(cur) : next;
11937
12563
  if (resolved === cur) return;
@@ -11942,7 +12568,7 @@ function useControllableState({ value, defaultValue, onChange } = {}) {
11942
12568
  }
11943
12569
  function useMediaQuery(query, { defaultValue = false, initializeWithValue = false } = {}) {
11944
12570
  const get = () => canUseDOM2 ? window.matchMedia(query).matches : defaultValue;
11945
- const [matches3, setMatches] = React36__namespace.default.useState(initializeWithValue ? get : defaultValue);
12571
+ const [matches3, setMatches] = React37__namespace.default.useState(initializeWithValue ? get : defaultValue);
11946
12572
  useIsomorphicLayoutEffect(() => {
11947
12573
  if (!canUseDOM2) return void 0;
11948
12574
  const mql = window.matchMedia(query);
@@ -11958,7 +12584,7 @@ function usePrefersReducedMotion() {
11958
12584
  }
11959
12585
  function useColorScheme({ storageKey = "twico-theme", attribute = "class", element, disableTransitionsOnChange = true } = {}) {
11960
12586
  const getTarget = () => element || (canUseDOM2 ? document.documentElement : null);
11961
- const firstApply = React36__namespace.default.useRef(true);
12587
+ const firstApply = React37__namespace.default.useRef(true);
11962
12588
  const read = () => {
11963
12589
  if (!canUseDOM2) return "light";
11964
12590
  try {
@@ -11968,8 +12594,8 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
11968
12594
  }
11969
12595
  return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
11970
12596
  };
11971
- const [theme, setThemeState] = React36__namespace.default.useState(read);
11972
- const apply = React36__namespace.default.useCallback(
12597
+ const [theme, setThemeState] = React37__namespace.default.useState(read);
12598
+ const apply = React37__namespace.default.useCallback(
11973
12599
  (t) => {
11974
12600
  const target = getTarget();
11975
12601
  if (!target) return;
@@ -11995,11 +12621,11 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
11995
12621
  useIsomorphicLayoutEffect(() => {
11996
12622
  apply(theme);
11997
12623
  }, [theme, apply]);
11998
- const themeRef = React36__namespace.default.useRef(theme);
12624
+ const themeRef = React37__namespace.default.useRef(theme);
11999
12625
  useIsomorphicLayoutEffect(() => {
12000
12626
  themeRef.current = theme;
12001
12627
  }, [theme]);
12002
- const setTheme = React36__namespace.default.useCallback(
12628
+ const setTheme = React37__namespace.default.useCallback(
12003
12629
  (t) => {
12004
12630
  setThemeState(t);
12005
12631
  try {
@@ -12010,10 +12636,10 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
12010
12636
  },
12011
12637
  [storageKey]
12012
12638
  );
12013
- const toggle = React36__namespace.default.useCallback(() => {
12639
+ const toggle = React37__namespace.default.useCallback(() => {
12014
12640
  setTheme(themeRef.current === "dark" ? "light" : "dark");
12015
12641
  }, [setTheme]);
12016
- React36__namespace.default.useEffect(() => {
12642
+ React37__namespace.default.useEffect(() => {
12017
12643
  if (!canUseDOM2) return void 0;
12018
12644
  const sync = () => setThemeState(read());
12019
12645
  const onStorage = (e) => {
@@ -12029,14 +12655,14 @@ function useColorScheme({ storageKey = "twico-theme", attribute = "class", eleme
12029
12655
  return { theme, setTheme, toggle, isDark: theme === "dark" };
12030
12656
  }
12031
12657
  function useEventListener(eventName, handler, element, options) {
12032
- const saved = React36__namespace.default.useRef(handler);
12658
+ const saved = React37__namespace.default.useRef(handler);
12033
12659
  useIsomorphicLayoutEffect(() => {
12034
12660
  saved.current = handler;
12035
12661
  }, [handler]);
12036
12662
  const capture = typeof options === "boolean" ? options : options && options.capture;
12037
12663
  const passive = typeof options === "object" && options ? options.passive : void 0;
12038
12664
  const once = typeof options === "object" && options ? options.once : void 0;
12039
- React36__namespace.default.useEffect(() => {
12665
+ React37__namespace.default.useEffect(() => {
12040
12666
  const target = element && element.current || element || (canUseDOM2 ? window : null);
12041
12667
  if (!target || !target.addEventListener) return void 0;
12042
12668
  const opts = typeof options === "boolean" ? options : { capture, passive, once };
@@ -12046,11 +12672,11 @@ function useEventListener(eventName, handler, element, options) {
12046
12672
  }, [eventName, element, capture, passive, once]);
12047
12673
  }
12048
12674
  function useClickOutside(ref, handler, events = ["mousedown", "touchstart"]) {
12049
- const saved = React36__namespace.default.useRef(handler);
12675
+ const saved = React37__namespace.default.useRef(handler);
12050
12676
  useIsomorphicLayoutEffect(() => {
12051
12677
  saved.current = handler;
12052
12678
  }, [handler]);
12053
- React36__namespace.default.useEffect(() => {
12679
+ React37__namespace.default.useEffect(() => {
12054
12680
  if (!canUseDOM2) return void 0;
12055
12681
  const listener = (e) => {
12056
12682
  const el = ref && ref.current;
@@ -12085,8 +12711,8 @@ function useLocalStorage(key, initialValue) {
12085
12711
  return initialValue;
12086
12712
  }
12087
12713
  };
12088
- const [stored, setStored] = React36__namespace.default.useState(read);
12089
- const setValue = React36__namespace.default.useCallback(
12714
+ const [stored, setStored] = React37__namespace.default.useState(read);
12715
+ const setValue = React37__namespace.default.useCallback(
12090
12716
  (value) => {
12091
12717
  setStored((prev) => {
12092
12718
  const next = typeof value === "function" ? value(prev) : value;
@@ -12102,8 +12728,8 @@ function useLocalStorage(key, initialValue) {
12102
12728
  return [stored, setValue];
12103
12729
  }
12104
12730
  function useCopyToClipboard(timeout = 1500) {
12105
- const [copied, setCopied] = React36__namespace.default.useState(false);
12106
- const copy = React36__namespace.default.useCallback(async (text) => {
12731
+ const [copied, setCopied] = React37__namespace.default.useState(false);
12732
+ const copy = React37__namespace.default.useCallback(async (text) => {
12107
12733
  if (!canUseDOM2 || !navigator.clipboard) {
12108
12734
  setCopied(false);
12109
12735
  return false;
@@ -12117,7 +12743,7 @@ function useCopyToClipboard(timeout = 1500) {
12117
12743
  return false;
12118
12744
  }
12119
12745
  }, []);
12120
- React36__namespace.default.useEffect(() => {
12746
+ React37__namespace.default.useEffect(() => {
12121
12747
  if (!copied) return void 0;
12122
12748
  const t = setTimeout(() => setCopied(false), timeout);
12123
12749
  return () => clearTimeout(t);
@@ -12125,23 +12751,23 @@ function useCopyToClipboard(timeout = 1500) {
12125
12751
  return { copied, copy };
12126
12752
  }
12127
12753
  function useDebouncedValue(value, delay = 200) {
12128
- const [debounced, setDebounced] = React36__namespace.default.useState(value);
12129
- React36__namespace.default.useEffect(() => {
12754
+ const [debounced, setDebounced] = React37__namespace.default.useState(value);
12755
+ React37__namespace.default.useEffect(() => {
12130
12756
  const t = setTimeout(() => setDebounced(value), delay);
12131
12757
  return () => clearTimeout(t);
12132
12758
  }, [value, delay]);
12133
12759
  return debounced;
12134
12760
  }
12135
12761
  function useDebouncedCallback(callback, delay = 200) {
12136
- const saved = React36__namespace.default.useRef(callback);
12137
- const timer = React36__namespace.default.useRef(null);
12762
+ const saved = React37__namespace.default.useRef(callback);
12763
+ const timer = React37__namespace.default.useRef(null);
12138
12764
  useIsomorphicLayoutEffect(() => {
12139
12765
  saved.current = callback;
12140
12766
  }, [callback]);
12141
- React36__namespace.default.useEffect(() => () => {
12767
+ React37__namespace.default.useEffect(() => () => {
12142
12768
  if (timer.current) clearTimeout(timer.current);
12143
12769
  }, []);
12144
- return React36__namespace.default.useCallback(
12770
+ return React37__namespace.default.useCallback(
12145
12771
  (...args) => {
12146
12772
  if (timer.current) clearTimeout(timer.current);
12147
12773
  timer.current = setTimeout(() => saved.current(...args), delay);
@@ -12150,33 +12776,33 @@ function useDebouncedCallback(callback, delay = 200) {
12150
12776
  );
12151
12777
  }
12152
12778
  function useInterval(callback, delay) {
12153
- const saved = React36__namespace.default.useRef(callback);
12779
+ const saved = React37__namespace.default.useRef(callback);
12154
12780
  useIsomorphicLayoutEffect(() => {
12155
12781
  saved.current = callback;
12156
12782
  }, [callback]);
12157
- React36__namespace.default.useEffect(() => {
12783
+ React37__namespace.default.useEffect(() => {
12158
12784
  if (delay == null) return void 0;
12159
12785
  const id = setInterval(() => saved.current(), delay);
12160
12786
  return () => clearInterval(id);
12161
12787
  }, [delay]);
12162
12788
  }
12163
12789
  function useTimeout(callback, delay) {
12164
- const saved = React36__namespace.default.useRef(callback);
12790
+ const saved = React37__namespace.default.useRef(callback);
12165
12791
  useIsomorphicLayoutEffect(() => {
12166
12792
  saved.current = callback;
12167
12793
  }, [callback]);
12168
- React36__namespace.default.useEffect(() => {
12794
+ React37__namespace.default.useEffect(() => {
12169
12795
  if (delay == null) return void 0;
12170
12796
  const id = setTimeout(() => saved.current(), delay);
12171
12797
  return () => clearTimeout(id);
12172
12798
  }, [delay]);
12173
12799
  }
12174
12800
  function useWindowSize() {
12175
- const [size, setSize] = React36__namespace.default.useState(() => ({
12801
+ const [size, setSize] = React37__namespace.default.useState(() => ({
12176
12802
  width: canUseDOM2 ? window.innerWidth : 0,
12177
12803
  height: canUseDOM2 ? window.innerHeight : 0
12178
12804
  }));
12179
- React36__namespace.default.useEffect(() => {
12805
+ React37__namespace.default.useEffect(() => {
12180
12806
  if (!canUseDOM2) return void 0;
12181
12807
  const onResize = () => setSize({ width: window.innerWidth, height: window.innerHeight });
12182
12808
  onResize();
@@ -12186,8 +12812,8 @@ function useWindowSize() {
12186
12812
  return size;
12187
12813
  }
12188
12814
  function useHover(ref) {
12189
- const [hovered, setHovered] = React36__namespace.default.useState(false);
12190
- React36__namespace.default.useEffect(() => {
12815
+ const [hovered, setHovered] = React37__namespace.default.useState(false);
12816
+ React37__namespace.default.useEffect(() => {
12191
12817
  const el = ref && ref.current;
12192
12818
  if (!el) return void 0;
12193
12819
  const on = () => setHovered(true);
@@ -12203,8 +12829,8 @@ function useHover(ref) {
12203
12829
  }
12204
12830
  function useIntersectionObserver(ref, options = {}) {
12205
12831
  const { root = null, rootMargin = "0px", threshold = 0 } = options;
12206
- const [entry, setEntry] = React36__namespace.default.useState(null);
12207
- React36__namespace.default.useEffect(() => {
12832
+ const [entry, setEntry] = React37__namespace.default.useState(null);
12833
+ React37__namespace.default.useEffect(() => {
12208
12834
  const el = ref && ref.current;
12209
12835
  if (!canUseDOM2 || !el || typeof IntersectionObserver === "undefined") return void 0;
12210
12836
  const obs = new IntersectionObserver(([e]) => setEntry(e), { root, rootMargin, threshold });
@@ -12214,7 +12840,7 @@ function useIntersectionObserver(ref, options = {}) {
12214
12840
  return entry;
12215
12841
  }
12216
12842
  function useId(prefix = "twc") {
12217
- const raw = React36__namespace.default.useId();
12843
+ const raw = React37__namespace.default.useId();
12218
12844
  return prefix ? `${prefix}-${raw.replace(/:/g, "")}` : raw;
12219
12845
  }
12220
12846
  var useFocusTrap2 = useFocusTrap;