twico-ui 1.33.1 → 1.35.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
@@ -8383,6 +8383,16 @@ var DT_CSS = `
8383
8383
  .twc-dt__group-sub span { font-variant-numeric: tabular-nums; }
8384
8384
  .twc-dt__group-sub span b { color: var(--color-text); }
8385
8385
 
8386
+ /* #350: expandable row detail (renderRowDetail) \u2014 leading chevron column + full-width detail row */
8387
+ .twc-dt__expand-cell { text-align: center; padding-inline: 0; }
8388
+ .twc-dt__expand-btn { display: inline-grid; place-items: center; width: 24px; height: 24px; border: none; padding: 0; background: transparent; color: var(--color-text-subtle); cursor: pointer; border-radius: var(--radius-sm); }
8389
+ .twc-dt__expand-btn:hover { color: var(--color-text); background: color-mix(in srgb, currentColor 12%, transparent); }
8390
+ .twc-dt__expand-btn:focus-visible { outline: none; box-shadow: var(--ring); }
8391
+ .twc-dt__expand-chev { display: inline-flex; transform: rotate(-90deg); transition: transform var(--duration-base) var(--ease-spring); }
8392
+ .twc-dt__expand-chev[data-open] { transform: rotate(0deg); color: var(--color-primary); }
8393
+ .twc-dt__expand-chev svg { width: 16px; height: 16px; }
8394
+ .twc-dt__detail-cell { box-sizing: border-box; background: var(--color-surface-sunken); border-bottom: var(--border-thin) solid var(--color-divider); padding: 12px 16px; }
8395
+
8386
8396
  /* Pivot view */
8387
8397
  .twc-dt__pivot { table-layout: auto; width: 100%; }
8388
8398
  .twc-dt__pivot th, .twc-dt__pivot td { white-space: nowrap; }
@@ -9330,6 +9340,20 @@ function Datatable({
9330
9340
  virtualized = false,
9331
9341
  overscan = 8,
9332
9342
  rowHeight,
9343
+ // #350 (first pass): expandable/collapsible rows. `renderRowDetail(row)` returns the detail panel for a
9344
+ // row (return null/undefined ⇒ that row isn't expandable). Presence of the fn enables a leading chevron
9345
+ // column + a full-width detail <tr> under each expanded row. Expansion is uncontrolled unless
9346
+ // `expandedRowIds` is supplied; `onExpandedRowsChange` fires the next expanded-key array on every toggle.
9347
+ renderRowDetail,
9348
+ expandedRowIds,
9349
+ onExpandedRowsChange,
9350
+ // #359: server-mode lazy row-tree — `getRowCanExpand(row)` draws the same leading chevron on parent DATA
9351
+ // rows (independent of renderRowDetail); expanding reveals CHILD data rows in the SAME columns rather than a
9352
+ // panel. In server mode the host returns children inline (the expanded set is folded into onServerChange);
9353
+ // in client mode `getSubRows(row)` supplies them. `getRowDepth(row)` indents nested rows so they read as a tree.
9354
+ getRowCanExpand,
9355
+ getRowDepth,
9356
+ getSubRows,
9333
9357
  className = "",
9334
9358
  ...rest
9335
9359
  }) {
@@ -9536,6 +9560,13 @@ function Datatable({
9536
9560
  const gridRef = React51__namespace.default.useRef(null);
9537
9561
  const [groupBy, setGroupBy] = React51__namespace.default.useState(rowGrouping || []);
9538
9562
  const [collapsed, setCollapsed] = React51__namespace.default.useState(() => /* @__PURE__ */ new Set());
9563
+ const [internalExpanded, setInternalExpanded] = React51__namespace.default.useState(() => /* @__PURE__ */ new Set());
9564
+ const expandControlled = expandedRowIds !== void 0;
9565
+ const expandedSet = React51__namespace.default.useMemo(
9566
+ () => new Set(expandControlled ? expandedRowIds : internalExpanded),
9567
+ [expandControlled, expandedRowIds, internalExpanded]
9568
+ );
9569
+ const expandedKey = React51__namespace.default.useMemo(() => JSON.stringify([...expandedSet].sort()), [expandedSet]);
9539
9570
  const [pinnedRows, setPinnedRows] = React51__namespace.default.useState({ top: [], bottom: [] });
9540
9571
  const [headH, setHeadH] = React51__namespace.default.useState(41);
9541
9572
  const theadRef = React51__namespace.default.useRef(null);
@@ -9937,7 +9968,12 @@ function Datatable({
9937
9968
  }, [pins, effectiveHidden, visibleCols, colByField, order]);
9938
9969
  const NUM_W = 56;
9939
9970
  const CHK_W = checkboxSelection ? rowReorder ? 68 : 44 : 0;
9940
- const numLeft = CHK_W;
9971
+ const hasRowDetail = typeof renderRowDetail === "function";
9972
+ const hasRowTree = typeof getRowCanExpand === "function";
9973
+ const hasExpandCol = hasRowDetail || hasRowTree;
9974
+ const treeExpandedKey = hasRowTree ? expandedKey : "";
9975
+ const EXP_W = hasExpandCol ? 44 : 0;
9976
+ const numLeft = EXP_W + CHK_W;
9941
9977
  const leadW = numLeft + (showRowNum ? NUM_W : 0);
9942
9978
  const visLeft = React51__namespace.default.useMemo(() => pins.left.filter((f) => colByField[f] && !effectiveHidden.has(f)), [pins.left, colByField, effectiveHidden]);
9943
9979
  const visRight = React51__namespace.default.useMemo(() => pins.right.filter((f) => colByField[f] && !effectiveHidden.has(f)), [pins.right, colByField, effectiveHidden]);
@@ -10009,6 +10045,40 @@ function Datatable({
10009
10045
  React51__namespace.default.useEffect(() => {
10010
10046
  if (pageVal > totalPages - 1) commitPage(0);
10011
10047
  }, [totalPages]);
10048
+ const treeRows = React51__namespace.default.useMemo(() => {
10049
+ if (serverMode || typeof getSubRows !== "function") return null;
10050
+ const out = [];
10051
+ const seen2 = /* @__PURE__ */ new Set();
10052
+ const walk = (r2, d) => {
10053
+ const key = keyOf(r2);
10054
+ if (seen2.has(key)) return;
10055
+ seen2.add(key);
10056
+ out.push({ row: r2, depth: d });
10057
+ if (expandedSet.has(key)) for (const c of getSubRows(r2) || []) walk(c, d + 1);
10058
+ };
10059
+ for (const r2 of paged) walk(r2, 0);
10060
+ return out;
10061
+ }, [serverMode, getSubRows, paged, expandedSet, keyOf]);
10062
+ const depthByKey = React51__namespace.default.useMemo(() => {
10063
+ const m = /* @__PURE__ */ new Map();
10064
+ if (treeRows) for (const t of treeRows) m.set(keyOf(t.row), t.depth);
10065
+ return m;
10066
+ }, [treeRows, keyOf]);
10067
+ const treeSeqByKey = React51__namespace.default.useMemo(() => {
10068
+ if (!treeRows) return null;
10069
+ const m = /* @__PURE__ */ new Map();
10070
+ const seen2 = /* @__PURE__ */ new Set();
10071
+ let n = 0;
10072
+ const walk = (r2) => {
10073
+ const key = keyOf(r2);
10074
+ if (seen2.has(key)) return;
10075
+ seen2.add(key);
10076
+ m.set(key, n++);
10077
+ if (expandedSet.has(key)) for (const c of getSubRows(r2) || []) walk(c);
10078
+ };
10079
+ for (const r2 of processed) walk(r2);
10080
+ return m;
10081
+ }, [treeRows, processed, expandedSet, getSubRows, keyOf]);
10012
10082
  const activeGroupBy = React51__namespace.default.useMemo(() => groupBy.filter((f) => colByField[f]), [groupBy, colByField]);
10013
10083
  function subtotalText(rowsIn) {
10014
10084
  const parts = [];
@@ -10059,7 +10129,7 @@ function Datatable({
10059
10129
  };
10060
10130
  return build(paged, 0, "");
10061
10131
  }, [activeGroupBy, collapsed, paged, ordered, aggOn]);
10062
- const leafRows = displayItems ? displayItems.filter((i) => i.kind === "leaf").map((i) => i.row) : paged;
10132
+ const leafRows = displayItems ? displayItems.filter((i) => i.kind === "leaf").map((i) => i.row) : treeRows ? treeRows.map((t) => t.row) : paged;
10063
10133
  function toggleGroup(key) {
10064
10134
  setCollapsed((s) => {
10065
10135
  const n = new Set(s);
@@ -10311,12 +10381,14 @@ function Datatable({
10311
10381
  // #303: "and" (default) | "or" — the server groups its WHERE accordingly
10312
10382
  quickFilter: quick.trim(),
10313
10383
  visibleColumns,
10314
- hiddenColumns
10384
+ hiddenColumns,
10315
10385
  // #191: server can project only the visible columns
10386
+ ...hasRowTree ? { expanded: [...expandedSet] } : null
10387
+ // #359: only a row-tree folds expanded parents in
10316
10388
  });
10317
10389
  }, 250);
10318
10390
  return () => clearTimeout(t);
10319
- }, [serverMode, pageVal, sizeVal, sort, filters, filterLogic, quick, visibleColumns, hiddenColumns]);
10391
+ }, [serverMode, pageVal, sizeVal, sort, filters, filterLogic, quick, visibleColumns, hiddenColumns, treeExpandedKey]);
10320
10392
  const onColVisRef = React51__namespace.default.useRef(onColumnVisibilityChange);
10321
10393
  onColVisRef.current = onColumnVisibilityChange;
10322
10394
  const lastVisibleKey = React51__namespace.default.useRef(null);
@@ -10532,6 +10604,12 @@ function Datatable({
10532
10604
  return n;
10533
10605
  });
10534
10606
  }
10607
+ function toggleRowDetail(k) {
10608
+ const n = new Set(expandedSet);
10609
+ n.has(k) ? n.delete(k) : n.add(k);
10610
+ onExpandedRowsChange?.([...n]);
10611
+ if (!expandControlled) setInternalExpanded(n);
10612
+ }
10535
10613
  function handleRowClick(e, k, row) {
10536
10614
  if (selectionMode === "none") return;
10537
10615
  if (e.target.closest("button, a, input, select, .twc-dt__check, .twc-dt__editor-wrap")) return;
@@ -10684,12 +10762,12 @@ function Datatable({
10684
10762
  next = next === "" ? null : Number(next);
10685
10763
  if (Number.isNaN(next)) next = null;
10686
10764
  }
10687
- const row = paged.find((r2, i) => keyOf(r2, i) === editing.key);
10765
+ const row = leafRows.find((r2, i) => keyOf(r2, i) === editing.key);
10688
10766
  setEditing(null);
10689
10767
  if (!row || row[editing.field] === next) return;
10690
10768
  const updated = { ...row, [editing.field]: next };
10691
10769
  onRowUpdate?.(updated, row, editing.field);
10692
- if (onRowsChange) {
10770
+ if (onRowsChange && rows.some((r2, i) => keyOf(r2, i) === editing.key)) {
10693
10771
  onRowsChange(rows.map((r2, i) => keyOf(r2, i) === editing.key ? updated : r2));
10694
10772
  }
10695
10773
  }
@@ -10818,20 +10896,25 @@ function Datatable({
10818
10896
  };
10819
10897
  const writeCellPatches = (patchByKey) => {
10820
10898
  if (!patchByKey.size) return 0;
10821
- const changed = [];
10822
- const nextAll = rows.map((r2, i) => {
10823
- const k = keyOf(r2, i);
10824
- const patch = patchByKey.get(k);
10825
- if (!patch) return r2;
10899
+ let count = 0;
10900
+ leafRows.forEach((r2, i) => {
10901
+ const patch = patchByKey.get(keyOf(r2, i));
10902
+ if (!patch) return;
10826
10903
  const updated = { ...r2, ...patch };
10827
- changed.push([updated, r2, patch]);
10828
- return updated;
10829
- });
10830
- changed.forEach(([updated, orig, patch]) => {
10831
- for (const f of Object.keys(patch)) onRowUpdate?.(updated, orig, f);
10904
+ for (const f of Object.keys(patch)) onRowUpdate?.(updated, r2, f);
10905
+ count++;
10832
10906
  });
10833
- if (onRowsChange && changed.length) onRowsChange(nextAll);
10834
- return changed.length;
10907
+ if (onRowsChange) {
10908
+ let anyTop = false;
10909
+ const nextAll = rows.map((r2, i) => {
10910
+ const patch = patchByKey.get(keyOf(r2, i));
10911
+ if (!patch) return r2;
10912
+ anyTop = true;
10913
+ return { ...r2, ...patch };
10914
+ });
10915
+ if (anyTop) onRowsChange(nextAll);
10916
+ }
10917
+ return count;
10835
10918
  };
10836
10919
  const rectCells = () => {
10837
10920
  if (!cellRect) return null;
@@ -11378,7 +11461,7 @@ function Datatable({
11378
11461
  const manageableCols = cols.filter((c) => c.field !== "__pinactions__");
11379
11462
  const visibleColCount = manageableCols.filter((c) => !effectiveHidden.has(c.field)).length;
11380
11463
  const rppOptions = Array.from(new Set([...pageSizeOptions || [], pageSize].filter((n) => n > 0))).sort((a, b) => a - b).map((n) => ({ value: String(n), label: String(n) }));
11381
- const totalCols = ordered.length + (checkboxSelection ? 1 : 0) + (showRowNum ? 1 : 0);
11464
+ const totalCols = ordered.length + (checkboxSelection ? 1 : 0) + (showRowNum ? 1 : 0) + (hasExpandCol ? 1 : 0);
11382
11465
  function renderGroupRow(item) {
11383
11466
  const subs = aggOn ? subtotalText(item.rows) : [];
11384
11467
  return /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "twc-dt__group-row", role: "row", children: /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "twc-dt__group-cell", role: "gridcell", colSpan: totalCols, style: { maxWidth: "none" }, children: [
@@ -11432,6 +11515,11 @@ function Datatable({
11432
11515
  function renderLeaf(row, ri, pinSide, midIdx) {
11433
11516
  const k = keyOf(row, ri);
11434
11517
  const sel = selected.has(k);
11518
+ const detail = hasRowDetail && !pinSide ? renderRowDetail(row) : null;
11519
+ const canTreeExpand = hasRowTree && !pinSide && !!getRowCanExpand(row);
11520
+ const expandable = detail != null || canTreeExpand;
11521
+ const open = expandable && expandedSet.has(k);
11522
+ const depth = getRowDepth ? getRowDepth(row) || 0 : depthByKey.get(k) || 0;
11435
11523
  const rowActive = selectionMode === "row" && activeRowVal === k;
11436
11524
  const stickyStyle = pinSide === "top" ? { position: "sticky", top: headH, zIndex: 5 } : pinSide === "bottom" ? { position: "sticky", bottom: 0, zIndex: 5 } : void 0;
11437
11525
  const h = rowHeights[k];
@@ -11439,159 +11527,165 @@ function Datatable({
11439
11527
  const reorderable = canReorderRows && !pinSide;
11440
11528
  const grabbed = rowGrab && rowGrab.key === k;
11441
11529
  const grabTarget = rowGrab && !grabbed && midIdx != null && rowGrab.index === midIdx ? rowGrab.index >= keyIndexMid.get(rowGrab.key) ? "after" : "before" : void 0;
11442
- return /* @__PURE__ */ jsxRuntime.jsxs(
11443
- "tr",
11444
- {
11445
- className: "twc-dt__row",
11446
- role: "row",
11447
- "aria-rowindex": (paginated && !serverMode ? pageVal * sizeVal : 0) + ri + 2,
11448
- "aria-selected": (checkboxSelection ? sel : rowActive) || void 0,
11449
- "data-op": row.__diffop || void 0,
11450
- "data-selected": sel || void 0,
11451
- "data-active": rowActive || void 0,
11452
- "data-pinned-row": pinSide || void 0,
11453
- "data-reorderable": reorderable || void 0,
11454
- "data-row-dragging": rowDrag.from === k || void 0,
11455
- "data-row-grabbed": grabbed || void 0,
11456
- "data-row-grabtarget": grabTarget,
11457
- "data-row-dropbefore": reorderable && rowDrag.over === k && !rowDrag.after || void 0,
11458
- "data-row-dropafter": reorderable && rowDrag.over === k && rowDrag.after || void 0,
11459
- "data-vrow": virtualizing && midIdx != null ? String(k) : void 0,
11460
- "data-selectable": selectionMode !== "none" || void 0,
11461
- style: Object.keys(rowStyle).length ? rowStyle : void 0,
11462
- draggable: reorderable || void 0,
11463
- onDragStart: reorderable ? (e) => {
11464
- setRowDrag({ from: k, over: null, after: false });
11465
- e.dataTransfer.effectAllowed = "move";
11466
- e.dataTransfer.setData("text/plain", String(k));
11467
- } : void 0,
11468
- onDragOver: reorderable && rowDrag.from != null ? (e) => {
11469
- e.preventDefault();
11470
- const r2 = e.currentTarget.getBoundingClientRect();
11471
- const after = e.clientY > r2.top + r2.height / 2;
11472
- setRowDrag((d) => d.over === k && d.after === after ? d : { ...d, over: k, after });
11473
- } : void 0,
11474
- onDrop: reorderable && rowDrag.from != null ? (e) => {
11475
- e.preventDefault();
11476
- onRowDrop(k);
11477
- } : void 0,
11478
- onDragEnd: reorderable ? () => setRowDrag({ from: null, over: null, after: false }) : void 0,
11479
- onClick: (e) => handleRowClick(e, k, row),
11480
- children: [
11481
- checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: 0, width: CHK_W }, children: [
11482
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 4 }, children: [
11483
- reorderable ? rowHandle(k, midIdx, row) : null,
11484
- /* @__PURE__ */ jsxRuntime.jsx(
11485
- "span",
11530
+ return /* @__PURE__ */ jsxRuntime.jsxs(React51__namespace.default.Fragment, { children: [
11531
+ /* @__PURE__ */ jsxRuntime.jsxs(
11532
+ "tr",
11533
+ {
11534
+ className: "twc-dt__row",
11535
+ role: "row",
11536
+ "aria-rowindex": treeSeqByKey ? treeSeqByKey.get(k) + 2 : (paginated && !serverMode ? pageVal * sizeVal : 0) + ri + 2,
11537
+ "aria-selected": (checkboxSelection ? sel : rowActive) || void 0,
11538
+ "data-op": row.__diffop || void 0,
11539
+ "data-selected": sel || void 0,
11540
+ "data-active": rowActive || void 0,
11541
+ "data-pinned-row": pinSide || void 0,
11542
+ "data-reorderable": reorderable || void 0,
11543
+ "data-row-dragging": rowDrag.from === k || void 0,
11544
+ "data-row-grabbed": grabbed || void 0,
11545
+ "data-row-grabtarget": grabTarget,
11546
+ "data-row-dropbefore": reorderable && rowDrag.over === k && !rowDrag.after || void 0,
11547
+ "data-row-dropafter": reorderable && rowDrag.over === k && rowDrag.after || void 0,
11548
+ "data-vrow": virtualizing && midIdx != null ? String(k) : void 0,
11549
+ "data-selectable": selectionMode !== "none" || void 0,
11550
+ style: Object.keys(rowStyle).length ? rowStyle : void 0,
11551
+ draggable: reorderable || void 0,
11552
+ onDragStart: reorderable ? (e) => {
11553
+ setRowDrag({ from: k, over: null, after: false });
11554
+ e.dataTransfer.effectAllowed = "move";
11555
+ e.dataTransfer.setData("text/plain", String(k));
11556
+ } : void 0,
11557
+ onDragOver: reorderable && rowDrag.from != null ? (e) => {
11558
+ e.preventDefault();
11559
+ const r2 = e.currentTarget.getBoundingClientRect();
11560
+ const after = e.clientY > r2.top + r2.height / 2;
11561
+ setRowDrag((d) => d.over === k && d.after === after ? d : { ...d, over: k, after });
11562
+ } : void 0,
11563
+ onDrop: reorderable && rowDrag.from != null ? (e) => {
11564
+ e.preventDefault();
11565
+ onRowDrop(k);
11566
+ } : void 0,
11567
+ onDragEnd: reorderable ? () => setRowDrag({ from: null, over: null, after: false }) : void 0,
11568
+ onClick: (e) => handleRowClick(e, k, row),
11569
+ children: [
11570
+ hasExpandCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__expand-cell", role: "gridcell", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W }, children: expandable ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-dt__expand-btn", "aria-expanded": open, "aria-controls": open && detail != null ? `${gridId}-detail-${ri}` : void 0, "aria-label": open ? "Collapse row" : "Expand row", onClick: (e) => {
11571
+ e.stopPropagation();
11572
+ toggleRowDetail(k);
11573
+ }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__expand-chev", "data-open": open || void 0, children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.chevDown }) }) }) : null }) : null,
11574
+ checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: EXP_W, width: CHK_W }, children: [
11575
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 4 }, children: [
11576
+ reorderable ? rowHandle(k, midIdx, row) : null,
11577
+ /* @__PURE__ */ jsxRuntime.jsx(
11578
+ "span",
11579
+ {
11580
+ className: "twc-dt__check",
11581
+ "data-checked": sel || void 0,
11582
+ onClick: () => toggleRow(k),
11583
+ role: "checkbox",
11584
+ "aria-checked": sel,
11585
+ "aria-label": "Select row",
11586
+ tabIndex: 0,
11587
+ onKeyDown: (e) => {
11588
+ if (e.key === " " || e.key === "Enter") {
11589
+ e.preventDefault();
11590
+ toggleRow(k);
11591
+ }
11592
+ },
11593
+ children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.check })
11594
+ }
11595
+ )
11596
+ ] }),
11597
+ 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
11598
+ ] }) : null,
11599
+ showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": visLeft.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: treeSeqByKey ? treeSeqByKey.get(k) + 1 : typeof ri === "number" ? (paginated || serverMode ? pageVal * sizeVal : 0) + ri + 1 : "" }) : null,
11600
+ ordered.map((c, ci) => {
11601
+ const st = stickyOf(c.field);
11602
+ const val = getColVal(c, row);
11603
+ const isActions = c.type === "actions";
11604
+ const editable = isColEditable(c);
11605
+ const isEditing = editing && editing.key === k && editing.field === c.field;
11606
+ const cellActive = selectionMode === "cell" && activeCell && activeCell.key === k && activeCell.field === c.field;
11607
+ const cellSelected = selectionMode === "cell" && cellRect && ri >= cellRect.r0 && ri <= cellRect.r1 && ci >= cellRect.c0 && ci <= cellRect.c1;
11608
+ const cellFlash = clipFx && clipFx.rect && ri >= clipFx.rect.r0 && ri <= clipFx.rect.r1 && ci >= clipFx.rect.c0 && ci <= clipFx.rect.c1;
11609
+ const cellId = selectionMode === "cell" ? `${gridId}-${ri}-${ci}` : void 0;
11610
+ const display = c.valueFormatter ? c.valueFormatter(val, row) : val;
11611
+ const cellTitle = !isActions && !c.renderCell && !isEditing && (typeof display === "string" || typeof display === "number") ? String(display) : void 0;
11612
+ const cellClass = c.cellClassName ? c.cellClassName(val, row) : void 0;
11613
+ const cellSty = c.cellStyle ? c.cellStyle(val, row) : void 0;
11614
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11615
+ "td",
11486
11616
  {
11487
- className: "twc-dt__check",
11488
- "data-checked": sel || void 0,
11489
- onClick: () => toggleRow(k),
11490
- role: "checkbox",
11491
- "aria-checked": sel,
11492
- "aria-label": "Select row",
11493
- tabIndex: 0,
11494
- onKeyDown: (e) => {
11495
- if (e.key === " " || e.key === "Enter") {
11496
- e.preventDefault();
11497
- toggleRow(k);
11498
- }
11499
- },
11500
- children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.check })
11501
- }
11502
- )
11503
- ] }),
11504
- 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
11505
- ] }) : null,
11506
- showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": visLeft.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W }, children: typeof ri === "number" ? (paginated || serverMode ? pageVal * sizeVal : 0) + ri + 1 : "" }) : null,
11507
- ordered.map((c, ci) => {
11508
- const st = stickyOf(c.field);
11509
- const val = getColVal(c, row);
11510
- const isActions = c.type === "actions";
11511
- const editable = isColEditable(c);
11512
- const isEditing = editing && editing.key === k && editing.field === c.field;
11513
- const cellActive = selectionMode === "cell" && activeCell && activeCell.key === k && activeCell.field === c.field;
11514
- const cellSelected = selectionMode === "cell" && cellRect && ri >= cellRect.r0 && ri <= cellRect.r1 && ci >= cellRect.c0 && ci <= cellRect.c1;
11515
- const cellFlash = clipFx && clipFx.rect && ri >= clipFx.rect.r0 && ri <= clipFx.rect.r1 && ci >= clipFx.rect.c0 && ci <= clipFx.rect.c1;
11516
- const cellId = selectionMode === "cell" ? `${gridId}-${ri}-${ci}` : void 0;
11517
- const display = c.valueFormatter ? c.valueFormatter(val, row) : val;
11518
- const cellTitle = !isActions && !c.renderCell && !isEditing && (typeof display === "string" || typeof display === "number") ? String(display) : void 0;
11519
- const cellClass = c.cellClassName ? c.cellClassName(val, row) : void 0;
11520
- const cellSty = c.cellStyle ? c.cellStyle(val, row) : void 0;
11521
- return /* @__PURE__ */ jsxRuntime.jsxs(
11522
- "td",
11523
- {
11524
- id: cellId,
11525
- className: cellClass ? `twc-dt__td ${cellClass}` : "twc-dt__td",
11526
- role: "gridcell",
11527
- "data-r": ri,
11528
- "data-c": ci,
11529
- "aria-colindex": ci + 1 + (checkboxSelection ? 1 : 0),
11530
- tabIndex: focus.r === ri && focus.c === ci ? 0 : -1,
11531
- "aria-selected": cellSelected || void 0,
11532
- "data-num": c.type === "number" || void 0,
11533
- "data-actions": isActions || void 0,
11534
- "data-editable": editable && !isEditing || void 0,
11535
- "data-editing": isEditing || void 0,
11536
- "data-cell-active": cellActive || void 0,
11537
- "data-cell-selected": cellSelected || void 0,
11538
- "data-copied": cellFlash || void 0,
11539
- "data-wrap": effectiveWrapped.has(c.field) || void 0,
11540
- "data-pin": st.pin,
11541
- "data-pin-edge": st.edge,
11542
- style: { width: widthOf(c), ...cellSty, ...st.style, ...st.pin ? { position: "sticky", zIndex: 2 } : null },
11543
- "data-ovtext": cellTitle,
11544
- onClick: selectionMode === "cell" ? (e) => handleCellClick(e, k, row, c) : void 0,
11545
- onFocus: () => setFocus((f) => f.r === ri && f.c === ci ? f : { r: ri, c: ci }),
11546
- onDoubleClick: editable ? () => beginEdit(k, c, row) : void 0,
11547
- children: [
11548
- !checkboxSelection && reorderable && ci === 0 && !isEditing ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 6, maxWidth: "100%" }, children: [
11549
- rowHandle(k, midIdx, row),
11550
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: isActions ? renderActions(c, row) : c.renderCell ? c.renderCell(val, row) : display })
11551
- ] }) : isEditing ? c.renderEditCell ? (
11552
- // #236: full escape hatch — the host drops in its own editor (searchable/creatable/
11553
- // async Combobox, …) and drives the lifecycle via commit/cancel. Wrapped in
11554
- // .twc-dt__editor-wrap so inline clicks (and any .twc-pop portal dropdown) don't
11555
- // trip the outside-click auto-cancel.
11556
- // #273: the wrapper handles Escape → cancel so it works for every custom editor without
11557
- // each having to wire a keydown (they only get commit/cancel). A custom control that
11558
- // wants Escape itself (e.g. to close its own open dropdown) stops propagation first.
11559
- /* @__PURE__ */ jsxRuntime.jsx(
11560
- "div",
11617
+ id: cellId,
11618
+ className: cellClass ? `twc-dt__td ${cellClass}` : "twc-dt__td",
11619
+ role: "gridcell",
11620
+ "data-r": ri,
11621
+ "data-c": ci,
11622
+ "aria-colindex": ci + 1 + (checkboxSelection ? 1 : 0) + (hasExpandCol ? 1 : 0),
11623
+ tabIndex: focus.r === ri && focus.c === ci ? 0 : -1,
11624
+ "aria-selected": cellSelected || void 0,
11625
+ "data-num": c.type === "number" || void 0,
11626
+ "data-actions": isActions || void 0,
11627
+ "data-editable": editable && !isEditing || void 0,
11628
+ "data-editing": isEditing || void 0,
11629
+ "data-cell-active": cellActive || void 0,
11630
+ "data-cell-selected": cellSelected || void 0,
11631
+ "data-copied": cellFlash || void 0,
11632
+ "data-wrap": effectiveWrapped.has(c.field) || void 0,
11633
+ "data-pin": st.pin,
11634
+ "data-pin-edge": st.edge,
11635
+ style: { width: widthOf(c), ...cellSty, ...st.style, ...st.pin ? { position: "sticky", zIndex: 2 } : null, ...ci === 0 && depth ? { paddingInlineStart: `calc(12px + ${depth * 20}px)` } : null },
11636
+ "data-ovtext": cellTitle,
11637
+ onClick: selectionMode === "cell" ? (e) => handleCellClick(e, k, row, c) : void 0,
11638
+ onFocus: () => setFocus((f) => f.r === ri && f.c === ci ? f : { r: ri, c: ci }),
11639
+ onDoubleClick: editable ? () => beginEdit(k, c, row) : void 0,
11640
+ children: [
11641
+ !checkboxSelection && reorderable && ci === 0 && !isEditing ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 6, maxWidth: "100%" }, children: [
11642
+ rowHandle(k, midIdx, row),
11643
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: isActions ? renderActions(c, row) : c.renderCell ? c.renderCell(val, row) : display })
11644
+ ] }) : isEditing ? c.renderEditCell ? (
11645
+ // #236: full escape hatch — the host drops in its own editor (searchable/creatable/
11646
+ // async Combobox, …) and drives the lifecycle via commit/cancel. Wrapped in
11647
+ // .twc-dt__editor-wrap so inline clicks (and any .twc-pop portal dropdown) don't
11648
+ // trip the outside-click auto-cancel.
11649
+ // #273: the wrapper handles Escape → cancel so it works for every custom editor without
11650
+ // each having to wire a keydown (they only get commit/cancel). A custom control that
11651
+ // wants Escape itself (e.g. to close its own open dropdown) stops propagation first.
11652
+ /* @__PURE__ */ jsxRuntime.jsx(
11653
+ "div",
11654
+ {
11655
+ className: "twc-dt__editor-wrap",
11656
+ onKeyDown: (e) => {
11657
+ if (e.key === "Escape") {
11658
+ e.stopPropagation();
11659
+ cancelEdit();
11660
+ }
11661
+ },
11662
+ children: c.renderEditCell({ value: editing.value, row, field: c.field, commit: (v) => commitEdit(v), cancel: cancelEdit })
11663
+ }
11664
+ )
11665
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
11666
+ EditCell,
11561
11667
  {
11562
- className: "twc-dt__editor-wrap",
11563
- onKeyDown: (e) => {
11564
- if (e.key === "Escape") {
11565
- e.stopPropagation();
11566
- cancelEdit();
11567
- }
11568
- },
11569
- children: c.renderEditCell({ value: editing.value, row, field: c.field, commit: (v) => commitEdit(v), cancel: cancelEdit })
11668
+ col: c,
11669
+ value: editing.value,
11670
+ options: c.valueOptions ? optionsForField(c.field) : null,
11671
+ onChange: (v) => setEditing((e) => ({ ...e, value: v })),
11672
+ onCommit: () => commitEdit(),
11673
+ onCommitValue: (v) => commitEdit(v),
11674
+ onCancel: cancelEdit,
11675
+ onKeyDown: onEditKey
11570
11676
  }
11571
- )
11572
- ) : /* @__PURE__ */ jsxRuntime.jsx(
11573
- EditCell,
11574
- {
11575
- col: c,
11576
- value: editing.value,
11577
- options: c.valueOptions ? optionsForField(c.field) : null,
11578
- onChange: (v) => setEditing((e) => ({ ...e, value: v })),
11579
- onCommit: () => commitEdit(),
11580
- onCommitValue: (v) => commitEdit(v),
11581
- onCancel: cancelEdit,
11582
- onKeyDown: onEditKey
11583
- }
11584
- ) : isActions ? renderActions(c, row) : c.renderCell ? c.renderCell(val, row) : display,
11585
- editable && !isEditing ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__edit-hint", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.pencil }) }) : null
11586
- ]
11587
- },
11588
- c.field
11589
- );
11590
- })
11591
- ]
11592
- },
11593
- (pinSide ? "p-" : "") + k
11594
- );
11677
+ ) : isActions ? renderActions(c, row) : c.renderCell ? c.renderCell(val, row) : display,
11678
+ editable && !isEditing ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__edit-hint", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.pencil }) }) : null
11679
+ ]
11680
+ },
11681
+ c.field
11682
+ );
11683
+ })
11684
+ ]
11685
+ }
11686
+ ),
11687
+ open && detail != null ? /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "twc-dt__detail-row", role: "row", children: /* @__PURE__ */ jsxRuntime.jsx("td", { id: `${gridId}-detail-${ri}`, className: "twc-dt__detail-cell", role: "gridcell", colSpan: totalCols, style: { maxWidth: "none" }, children: detail }) }) : null
11688
+ ] }, (pinSide ? "p-" : "") + k);
11595
11689
  }
11596
11690
  function renderPivot() {
11597
11691
  const rFields = pivotConfig.rows, cFields = pivotConfig.columns || [], values = pivotConfig.values;
@@ -11927,15 +12021,16 @@ function Datatable({
11927
12021
  ref: gridRef,
11928
12022
  role: "grid",
11929
12023
  "aria-label": ariaLabelAttr || ariaLabel,
11930
- "aria-rowcount": totalRows + 1,
11931
- "aria-colcount": ordered.length + (checkboxSelection ? 1 : 0),
12024
+ "aria-rowcount": (treeSeqByKey ? treeSeqByKey.size : totalRows) + 1,
12025
+ "aria-colcount": ordered.length + (checkboxSelection ? 1 : 0) + (hasExpandCol ? 1 : 0),
11932
12026
  "aria-multiselectable": selectionMode === "cell" || void 0,
11933
12027
  "aria-activedescendant": activeCellId,
11934
12028
  "aria-busy": loading || void 0,
11935
12029
  onKeyDown: onGridKeyDown,
11936
12030
  children: [
11937
12031
  /* @__PURE__ */ jsxRuntime.jsx("thead", { ref: theadRef, children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", "aria-rowindex": 1, children: [
11938
- checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th", role: "columnheader", "aria-label": "Select", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: 0, width: CHK_W, minWidth: CHK_W }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__th-inner", style: { justifyContent: "center", padding: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
12032
+ hasExpandCol ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th twc-dt__expand-cell", role: "columnheader", "aria-label": "Expand", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W, minWidth: EXP_W } }) : null,
12033
+ checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("th", { className: "twc-dt__th", role: "columnheader", "aria-label": "Select", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: EXP_W, width: CHK_W, minWidth: CHK_W }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-dt__th-inner", style: { justifyContent: "center", padding: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
11939
12034
  "span",
11940
12035
  {
11941
12036
  className: "twc-dt__check",
@@ -12111,7 +12206,8 @@ function Datatable({
12111
12206
  })
12112
12207
  ] }) }),
12113
12208
  /* @__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: [
12114
- checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", style: { insetInlineStart: 0, width: CHK_W }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__sk", "aria-hidden": "true", style: { "--_w": "18px", height: 18, borderRadius: 4 } }) }) : null,
12209
+ hasExpandCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td twc-dt__expand-cell", role: "gridcell", "data-pin": "left", style: { insetInlineStart: 0, width: EXP_W } }) : null,
12210
+ checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__td", role: "gridcell", "data-pin": "left", style: { insetInlineStart: EXP_W, width: CHK_W }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__sk", "aria-hidden": "true", style: { "--_w": "18px", height: 18, borderRadius: 4 } }) }) : null,
12115
12211
  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,
12116
12212
  ordered.map((c, ci) => {
12117
12213
  const st = stickyOf(c.field);
@@ -12133,7 +12229,8 @@ function Datatable({
12133
12229
  pinnedBottomRows.map((row) => renderLeaf(row, keyIndex.get(keyOf(row)), "bottom"))
12134
12230
  ] }) }),
12135
12231
  hasAggregation && aggOn && !loading && paged.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("tfoot", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", children: [
12136
- checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: 0, width: CHK_W } }) : null,
12232
+ hasExpandCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge": checkboxSelection || showRowNum || visLeft.length ? void 0 : "left", style: { insetInlineStart: 0, width: EXP_W } }) : null,
12233
+ checkboxSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "data-pin": "left", "data-pin-edge": visLeft.length || showRowNum ? void 0 : "left", style: { insetInlineStart: EXP_W, width: CHK_W } }) : null,
12137
12234
  showRowNum ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "twc-dt__rownum", role: "gridcell", "aria-hidden": "true", "data-pin": "left", "data-pin-edge": visLeft.length ? void 0 : "left", style: { insetInlineStart: numLeft, width: NUM_W } }) : null,
12138
12235
  ordered.map((c) => {
12139
12236
  const st = stickyOf(c.field);
@@ -17168,6 +17265,18 @@ var SLIDER_CSS = `
17168
17265
  transition: opacity var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-spring);
17169
17266
  }
17170
17267
  .twc-slider__track[data-show-bubble="true"] .twc-slider__bubble { opacity: 1; transform: translateX(-50%) scale(1); }
17268
+ /* #351: editable numeric inputs (manual entry, synced with the thumbs) */
17269
+ .twc-slider__inputs { display: inline-flex; align-items: center; gap: var(--space-1-5); }
17270
+ .twc-slider__input-sep { color: var(--color-text-muted); font-weight: var(--font-semibold); }
17271
+ .twc-slider__input {
17272
+ min-width: 0; text-align: end; font-family: inherit; font-size: var(--text-sm); font-weight: var(--font-semibold);
17273
+ color: var(--_accent); font-variant-numeric: tabular-nums;
17274
+ padding: 2px 6px; border: var(--border-thin) solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-surface);
17275
+ transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
17276
+ }
17277
+ .twc-slider__input:hover:not(:disabled) { border-color: var(--color-border-strong); }
17278
+ .twc-slider__input:focus-visible { outline: none; border-color: var(--_accent); box-shadow: var(--ring); }
17279
+ .twc-slider[data-disabled="true"] .twc-slider__input { cursor: not-allowed; }
17171
17280
  `;
17172
17281
  function Slider({
17173
17282
  label,
@@ -17186,6 +17295,7 @@ function Slider({
17186
17295
  range: range2 = false,
17187
17296
  showValue = true,
17188
17297
  showTicks = false,
17298
+ editable = false,
17189
17299
  formatValue,
17190
17300
  getAriaValueText,
17191
17301
  name,
@@ -17224,6 +17334,7 @@ function Slider({
17224
17334
  const indices = isRange ? [0, 1] : [0];
17225
17335
  const trackRef = React51__namespace.default.useRef(null);
17226
17336
  const [dragging, setDragging] = React51__namespace.default.useState(false);
17337
+ const [typed, setTyped] = React51__namespace.default.useState({});
17227
17338
  const fmt = (v) => formatValue ? formatValue(v) : v.toFixed(decimals);
17228
17339
  const valueTextFor = (v) => {
17229
17340
  if (getAriaValueText) return getAriaValueText(v);
@@ -17247,6 +17358,27 @@ function Slider({
17247
17358
  }
17248
17359
  commit(next);
17249
17360
  };
17361
+ const commitInput = (i) => {
17362
+ const s = typed[i];
17363
+ setTyped((t) => {
17364
+ const n = { ...t };
17365
+ delete n[i];
17366
+ return n;
17367
+ });
17368
+ if (s == null || String(s).trim() === "") return;
17369
+ const num = parseFloat(s);
17370
+ if (Number.isFinite(num)) setThumb(i, num);
17371
+ };
17372
+ const stepInput = (i, dir) => {
17373
+ const base = typed[i] != null && Number.isFinite(parseFloat(typed[i])) ? parseFloat(typed[i]) : clampedVals[i];
17374
+ setTyped((t) => {
17375
+ const n = { ...t };
17376
+ delete n[i];
17377
+ return n;
17378
+ });
17379
+ setThumb(i, base + dir * step);
17380
+ };
17381
+ const inputSize = Math.max(String(min).length, String(max).length, decimals > 0 ? decimals + 2 : 1) + 1;
17250
17382
  const fromClientX = (clientX) => {
17251
17383
  const node = trackRef.current;
17252
17384
  if (!node) return clampedVals[0];
@@ -17302,9 +17434,40 @@ function Slider({
17302
17434
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-slider ${className}`, "data-tone": tone, "data-size": size, "data-disabled": disabled || void 0, ...rest, children: [
17303
17435
  __twcStyles,
17304
17436
  name ? clampedVals.map((v, i) => /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: v, disabled: disabled || void 0 }, i)) : null,
17305
- label || showValue ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-slider__head", children: [
17437
+ label || showValue || editable ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-slider__head", children: [
17306
17438
  label ? /* @__PURE__ */ jsxRuntime.jsx("label", { className: "twc-slider__label", id: labelId, children: label }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
17307
- showValue ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-slider__value", children: headValue }) : null
17439
+ editable ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-slider__inputs", children: indices.map((i) => /* @__PURE__ */ jsxRuntime.jsxs(React51__namespace.default.Fragment, { children: [
17440
+ i > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-slider__input-sep", "aria-hidden": "true", children: "\u2013" }) : null,
17441
+ /* @__PURE__ */ jsxRuntime.jsx(
17442
+ "input",
17443
+ {
17444
+ className: "twc-slider__input",
17445
+ type: "text",
17446
+ inputMode: min < 0 ? "text" : "decimal",
17447
+ size: inputSize,
17448
+ value: typed[i] != null ? typed[i] : String(clampedVals[i]),
17449
+ disabled: disabled || void 0,
17450
+ "aria-labelledby": isRange ? void 0 : labelId,
17451
+ "aria-label": isRange ? i === 0 ? "Minimum value" : "Maximum value" : labelId ? void 0 : "Value",
17452
+ onChange: (e) => setTyped((t) => ({ ...t, [i]: e.target.value })),
17453
+ onBlur: () => commitInput(i),
17454
+ onKeyDown: (e) => {
17455
+ if (e.key === "Enter") {
17456
+ if (typed[i] != null) {
17457
+ e.preventDefault();
17458
+ commitInput(i);
17459
+ }
17460
+ } else if (e.key === "ArrowUp") {
17461
+ e.preventDefault();
17462
+ stepInput(i, 1);
17463
+ } else if (e.key === "ArrowDown") {
17464
+ e.preventDefault();
17465
+ stepInput(i, -1);
17466
+ }
17467
+ }
17468
+ }
17469
+ )
17470
+ ] }, i)) }) : showValue ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-slider__value", children: headValue }) : null
17308
17471
  ] }) : null,
17309
17472
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-slider__track", ref: trackRef, "data-show-bubble": dragging || void 0, onPointerDown, children: [
17310
17473
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twc-slider__rail" }),