twico-ui 1.12.0 → 1.13.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,13 @@
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.13.0](https://github.com/EncryptionL/twico-ui/compare/v1.12.0...v1.13.0) (2026-07-13)
6
+
7
+
8
+ ### Features
9
+
10
+ * **data-display:** narrow-column sizing + menu gating; fix Move-menu & CardGrid sort clipping ([a4f4937](https://github.com/EncryptionL/twico-ui/commit/a4f4937d00c4c3c9be0b199c8eac98d0d60f5572)), closes [#228](https://github.com/EncryptionL/twico-ui/issues/228) [#226](https://github.com/EncryptionL/twico-ui/issues/226) [#227](https://github.com/EncryptionL/twico-ui/issues/227) [#228](https://github.com/EncryptionL/twico-ui/issues/228)
11
+
5
12
  # [1.12.0](https://github.com/EncryptionL/twico-ui/compare/v1.11.1...v1.12.0) (2026-07-10)
6
13
 
7
14
 
package/dist/index.cjs CHANGED
@@ -9024,7 +9024,19 @@ function Datatable({
9024
9024
  rowGroupingKeyRef.current = rowGroupingKey;
9025
9025
  setGroupBy(rowGrouping || []);
9026
9026
  }, [rowGroupingKey]);
9027
- const widthOf = (c) => widths[c.field] ?? c.width ?? 160;
9027
+ const AUTO_CHROME = 74;
9028
+ const autoWidth = (c) => {
9029
+ const label = typeof c.headerName === "string" ? c.headerName : String(c.field ?? "");
9030
+ return AUTO_CHROME + Math.ceil(label.length * 8);
9031
+ };
9032
+ const clampWidth = (w, c) => {
9033
+ let x = w;
9034
+ if (typeof c.maxWidth === "number") x = Math.min(x, c.maxWidth);
9035
+ if (typeof c.minWidth === "number") x = Math.max(x, c.minWidth);
9036
+ return Math.max(40, x);
9037
+ };
9038
+ const intrinsicWidth = (c) => c.width === "auto" ? autoWidth(c) : typeof c.width === "number" ? c.width : 160;
9039
+ const widthOf = (c) => clampWidth(widths[c.field] ?? intrinsicWidth(c), c);
9028
9040
  const [colMenu, setColMenu] = React51__namespace.default.useState(null);
9029
9041
  const [menuPos, openMenu, closeMenu] = useFloating();
9030
9042
  const [panel, setPanel] = React51__namespace.default.useState(null);
@@ -10612,7 +10624,7 @@ function Datatable({
10612
10624
  e.preventDefault();
10613
10625
  e.stopPropagation();
10614
10626
  const delta = e.key === "ArrowRight" ? 10 : -10;
10615
- setWidths((m) => ({ ...m, [c.field]: Math.max(72, (m[c.field] ?? c.width ?? 160) + delta) }));
10627
+ setWidths((m) => ({ ...m, [c.field]: Math.max(72, (m[c.field] ?? intrinsicWidth(c)) + delta) }));
10616
10628
  },
10617
10629
  title: "Drag to resize \xB7 double-click to fit content"
10618
10630
  }
@@ -10855,10 +10867,10 @@ function Datatable({
10855
10867
  " ",
10856
10868
  groupBy.includes(c.field) ? "Stop grouping" : "Group by this column"
10857
10869
  ] }) : null,
10858
- !disableColumnReorder && c.type !== "actions" && !pins.left.includes(c.field) && !pins.right.includes(c.field) ? (() => {
10870
+ !disableColumnReorder && c.reorderable !== false && c.type !== "actions" && !pins.left.includes(c.field) && !pins.right.includes(c.field) && movableMidFields.length > 1 ? (() => {
10859
10871
  const midIdx = movableMidFields.indexOf(c.field);
10860
- const atFirst = midIdx <= 0;
10861
- const atLast = midIdx === -1 || midIdx >= movableMidFields.length - 1;
10872
+ const atFirst = midIdx === 0;
10873
+ const atLast = midIdx === movableMidFields.length - 1;
10862
10874
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10863
10875
  /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", role: "menuitem", className: "twc-dt__mi", disabled: atFirst, "aria-disabled": atFirst || void 0, onClick: () => {
10864
10876
  moveCol(c.field, -1);
@@ -10894,7 +10906,7 @@ function Datatable({
10894
10906
  pins.right.includes(c.field) ? "Unpin" : "Pin to right"
10895
10907
  ] })
10896
10908
  ] }) : null,
10897
- c.type !== "actions" ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", role: "menuitem", className: "twc-dt__mi", "data-active": wrapped.has(c.field) || void 0, onClick: () => {
10909
+ c.type !== "actions" && c.wrappable !== false ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", role: "menuitem", className: "twc-dt__mi", "data-active": wrapped.has(c.field) || void 0, onClick: () => {
10898
10910
  toggleWrap(c.field);
10899
10911
  close();
10900
10912
  }, children: [
@@ -11398,7 +11410,7 @@ var CARDGRID_CSS = `
11398
11410
  .twc-cardgrid__toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
11399
11411
  .twc-cardgrid__search { flex: 1 1 200px; min-width: 160px; }
11400
11412
  .twc-cardgrid__spacer { flex: 1 1 auto; }
11401
- .twc-cardgrid__sort { display: inline-flex; align-items: center; gap: var(--space-1); }
11413
+ .twc-cardgrid__sort { display: inline-flex; align-items: center; gap: var(--space-1); flex: none; }
11402
11414
  .twc-cardgrid__dir { display: inline-grid; place-items: center; width: 32px; height: 32px; border: var(--border-thin) solid var(--color-border); background: var(--color-surface); color: var(--color-text-muted); cursor: pointer; border-radius: var(--radius-md); transition: background-color var(--duration-fast), color var(--duration-fast); }
11403
11415
  .twc-cardgrid__dir:hover { background: var(--color-surface-sunken); color: var(--color-text); }
11404
11416
  .twc-cardgrid__dir svg { width: 16px; height: 16px; transition: transform var(--duration-fast) var(--ease-standard); }
@@ -11446,6 +11458,7 @@ function CardGrid({
11446
11458
  defaultSort = null,
11447
11459
  onSortChange,
11448
11460
  sortOptions,
11461
+ sortMinWidth,
11449
11462
  // slots / states
11450
11463
  toolbar,
11451
11464
  emptyState = "No results.",
@@ -11517,6 +11530,8 @@ function CardGrid({
11517
11530
  const to = paginated ? Math.min((pageVal + 1) * sizeVal, total) : total;
11518
11531
  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) }));
11519
11532
  const sortSelectOptions = sortOptions ? [{ value: "", label: "Sort by\u2026" }, ...sortOptions.map((o) => ({ value: o.field, label: o.label || o.field }))] : null;
11533
+ const sortAutoWidth = sortSelectOptions ? Math.min(300, Math.max(120, Math.ceil(Math.max(...sortSelectOptions.map((o) => String(o.label).length)) * 7.2) + 46)) : void 0;
11534
+ const sortWidth = sortMinWidth != null ? sortMinWidth : sortAutoWidth;
11520
11535
  const hasToolbar = searchable || sortSelectOptions || toolbar;
11521
11536
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `twc-cardgrid ${className}`, id: fieldId, ...rest, children: [
11522
11537
  styles,
@@ -11544,6 +11559,7 @@ function CardGrid({
11544
11559
  value: sortVal?.field || "",
11545
11560
  options: sortSelectOptions,
11546
11561
  placeholder: "Sort by\u2026",
11562
+ style: { minWidth: sortWidth },
11547
11563
  "aria-label": "Sort by",
11548
11564
  onChange: (field) => commitSort(field ? { field, dir: sortVal?.dir || "asc" } : null)
11549
11565
  }