twico-ui 1.32.0 → 1.33.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/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to Twico UI are documented here (newest first). This file is generated automatically on each release by [semantic-release](https://semantic-release.gitbook.io/) from [Conventional Commits](https://www.conventionalcommits.org/) — do not edit it by hand. The same notes appear on each [GitHub Release](https://github.com/EncryptionL/twico-ui/releases).
4
4
 
5
+ # [1.33.0](https://github.com/EncryptionL/twico-ui/compare/v1.32.1...v1.33.0) (2026-08-11)
6
+
7
+
8
+ ### Features
9
+
10
+ * **datatable:** per-cell cellClassName/cellStyle hooks on DatatableColumn ([ac58410](https://github.com/EncryptionL/twico-ui/commit/ac58410109b9a67ed7cb78717a3a98a8b8639cb1)), closes [#242](https://github.com/EncryptionL/twico-ui/issues/242) [#345](https://github.com/EncryptionL/twico-ui/issues/345)
11
+
12
+ ## [1.32.1](https://github.com/EncryptionL/twico-ui/compare/v1.32.0...v1.32.1) (2026-08-11)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **inputs:** suppress clear affordances on disabled controls; ignore datatable keys from editable cells ([e54909f](https://github.com/EncryptionL/twico-ui/commit/e54909fa32fdcb33cbd068b91ddd9f62f098aa08)), closes [#342](https://github.com/EncryptionL/twico-ui/issues/342) [#343](https://github.com/EncryptionL/twico-ui/issues/343) [#342](https://github.com/EncryptionL/twico-ui/issues/342) [#343](https://github.com/EncryptionL/twico-ui/issues/343)
18
+
5
19
  # [1.32.0](https://github.com/EncryptionL/twico-ui/compare/v1.31.1...v1.32.0) (2026-08-06)
6
20
 
7
21
 
package/dist/index.cjs CHANGED
@@ -5888,6 +5888,7 @@ function Combobox({
5888
5888
  setQuery("");
5889
5889
  }
5890
5890
  function commit(v) {
5891
+ if (disabled) return;
5891
5892
  const o = flat.find((x) => x.value === v);
5892
5893
  if (o && o.disabled) return;
5893
5894
  if (value === void 0) setInternal(v);
@@ -6064,7 +6065,7 @@ function Combobox({
6064
6065
  ...rest
6065
6066
  }
6066
6067
  ),
6067
- clearable && selected && !open ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-cb__clear", "aria-label": "Clear", onClick: (e) => {
6068
+ clearable && selected && !open && !disabled ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "twc-cb__clear", "aria-label": "Clear", onClick: (e) => {
6068
6069
  e.stopPropagation();
6069
6070
  commit(null);
6070
6071
  }, 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,
@@ -7354,6 +7355,7 @@ var MULTI_CSS = `
7354
7355
  background: var(--_accent-subtle); color: var(--_accent-subtle-fg);
7355
7356
  border-radius: var(--radius-full); font-size: var(--text-xs); font-weight: var(--font-semibold);
7356
7357
  }
7358
+ .twc-ms__control[data-disabled="true"] .twc-ms__chip { padding-inline-end: 9px; } /* #342: no \u2715 \u2192 symmetric pad */
7357
7359
  .twc-ms__chip-x { display: inline-grid; place-items: center; width: 16px; height: 16px; border: none; padding: 0; background: transparent; color: inherit; cursor: pointer; border-radius: var(--radius-full); opacity: 0.7; }
7358
7360
  .twc-ms__chip-x:hover { opacity: 1; background: color-mix(in srgb, currentColor 18%, transparent); }
7359
7361
  .twc-ms__chip-x svg { width: 12px; height: 12px; }
@@ -7596,6 +7598,7 @@ function MultiSelect({
7596
7598
  setScrollTop(next);
7597
7599
  }, [active, open, virtualized, rows, listH]);
7598
7600
  function commit(next) {
7601
+ if (disabled) return;
7599
7602
  if (value === void 0) setInternal(next);
7600
7603
  onChange?.(next);
7601
7604
  }
@@ -7752,10 +7755,10 @@ function MultiSelect({
7752
7755
  children: [
7753
7756
  (maxTagCount != null ? selectedOpts.slice(0, maxTagCount) : selectedOpts).map((o) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-ms__chip", children: [
7754
7757
  o.label,
7755
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", tabIndex: -1, className: "twc-ms__chip-x", "aria-label": `Remove ${o.label}`, onClick: (e) => {
7758
+ !disabled ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", tabIndex: -1, className: "twc-ms__chip-x", "aria-label": `Remove ${o.label}`, onClick: (e) => {
7756
7759
  e.stopPropagation();
7757
7760
  toggle(o.value);
7758
- }, 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: "M18 6 6 18M6 6l12 12" }) }) })
7761
+ }, 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: "M18 6 6 18M6 6l12 12" }) }) }) : null
7759
7762
  ] }, o.value)),
7760
7763
  maxTagCount != null && selectedOpts.length > maxTagCount ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-ms__more", title: selectedOpts.slice(maxTagCount).map((o) => o.label).join(", "), children: [
7761
7764
  "+",
@@ -7808,8 +7811,10 @@ function MultiSelect({
7808
7811
  tabIndex: -1,
7809
7812
  onClick: (e) => {
7810
7813
  e.stopPropagation();
7811
- setOpen((o) => !o);
7812
- inputRef.current?.focus();
7814
+ if (!disabled) {
7815
+ setOpen((o) => !o);
7816
+ inputRef.current?.focus();
7817
+ }
7813
7818
  },
7814
7819
  children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" }) })
7815
7820
  }
@@ -10554,6 +10559,7 @@ function Datatable({
10554
10559
  if (el) el.focus();
10555
10560
  }
10556
10561
  function onGridKeyDown(e) {
10562
+ if (e.target.closest("input, textarea, select, [contenteditable='true']")) return;
10557
10563
  if (editing) return;
10558
10564
  const td = e.target.closest(".twc-dt__td[data-r]");
10559
10565
  if (!td) return;
@@ -11513,11 +11519,13 @@ function Datatable({
11513
11519
  const cellId = selectionMode === "cell" ? `${gridId}-${ri}-${ci}` : void 0;
11514
11520
  const display = c.valueFormatter ? c.valueFormatter(val, row) : val;
11515
11521
  const cellTitle = !isActions && !c.renderCell && !isEditing && (typeof display === "string" || typeof display === "number") ? String(display) : void 0;
11522
+ const cellClass = c.cellClassName ? c.cellClassName(val, row) : void 0;
11523
+ const cellSty = c.cellStyle ? c.cellStyle(val, row) : void 0;
11516
11524
  return /* @__PURE__ */ jsxRuntime.jsxs(
11517
11525
  "td",
11518
11526
  {
11519
11527
  id: cellId,
11520
- className: "twc-dt__td",
11528
+ className: cellClass ? `twc-dt__td ${cellClass}` : "twc-dt__td",
11521
11529
  role: "gridcell",
11522
11530
  "data-r": ri,
11523
11531
  "data-c": ci,
@@ -11534,7 +11542,7 @@ function Datatable({
11534
11542
  "data-wrap": effectiveWrapped.has(c.field) || void 0,
11535
11543
  "data-pin": st.pin,
11536
11544
  "data-pin-edge": st.edge,
11537
- style: { width: widthOf(c), ...st.style },
11545
+ style: { width: widthOf(c), ...cellSty, ...st.style, ...st.pin ? { position: "sticky", zIndex: 2 } : null },
11538
11546
  "data-ovtext": cellTitle,
11539
11547
  onClick: selectionMode === "cell" ? (e) => handleCellClick(e, k, row, c) : void 0,
11540
11548
  onFocus: () => setFocus((f) => f.r === ri && f.c === ci ? f : { r: ri, c: ci }),
@@ -15749,6 +15757,7 @@ function FileUpload({
15749
15757
  } else if (accepted.length) set(accepted.slice(0, 1));
15750
15758
  }
15751
15759
  function remove(i) {
15760
+ if (disabled) return;
15752
15761
  set(files.filter((_, idx) => idx !== i));
15753
15762
  }
15754
15763
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-upload ${className}`, "data-size": size, ...rest, children: [
@@ -15819,7 +15828,7 @@ function FileUpload({
15819
15828
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-upload__file-name", children: f.name }),
15820
15829
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-upload__file-size", children: fmtSize(f.size) })
15821
15830
  ] }),
15822
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-upload__file-x", "aria-label": `Remove ${f.name}`, onClick: () => remove(i), 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" }) }) })
15831
+ !disabled ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: "twc-upload__file-x", "aria-label": `Remove ${f.name}`, onClick: () => remove(i), 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
15823
15832
  ] }, fileKey(f))) }) : null,
15824
15833
  error ? /* @__PURE__ */ jsxRuntime.jsx("span", { id: descId, className: "twc-field__error", children: error }) : null
15825
15834
  ] });