twico-ui 1.37.2 → 1.38.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.38.0](https://github.com/EncryptionL/twico-ui/compare/v1.37.2...v1.38.0) (2026-09-22)
6
+
7
+
8
+ ### Features
9
+
10
+ * **datatable,tooltip:** toolbar/group-bar controls + rich tooltip labels ([#385](https://github.com/EncryptionL/twico-ui/issues/385), [#386](https://github.com/EncryptionL/twico-ui/issues/386), [#387](https://github.com/EncryptionL/twico-ui/issues/387)) ([a89fb1f](https://github.com/EncryptionL/twico-ui/commit/a89fb1f4885bc51f2383b4c3437eb502aa574a37))
11
+
5
12
  ## [1.37.2](https://github.com/EncryptionL/twico-ui/compare/v1.37.1...v1.37.2) (2026-09-18)
6
13
 
7
14
 
package/dist/index.cjs CHANGED
@@ -7979,7 +7979,11 @@ var TOOLTIP_CSS = `
7979
7979
  (opacity:0) nor a shown bubble can block neighbouring cells/buttons (matches MUI/Radix tooltips). */
7980
7980
  pointer-events: none;
7981
7981
  padding: 6px 10px; border-radius: var(--radius-md);
7982
- background: var(--color-text); color: var(--color-surface);
7982
+ /* #385: capture the ink as the bubble bg via a private var BEFORE the content wrapper re-scopes
7983
+ --color-text, so a token-driven child (Text/Heading) reads the bubble's fg \u2014 not the page ink,
7984
+ which is this very background \u2014 and the re-scope can't feed back into the bg. */
7985
+ --_tt-bg: var(--color-text); --_tt-fg: var(--color-surface);
7986
+ background: var(--_tt-bg); color: var(--_tt-fg);
7983
7987
  font-family: var(--font-sans); font-size: var(--text-xs); font-weight: var(--font-medium);
7984
7988
  line-height: 1.3; white-space: normal;
7985
7989
  /* Grow horizontally to max-width, then wrap. max-content sizes to the content (capped by
@@ -7995,7 +7999,13 @@ var TOOLTIP_CSS = `
7995
7999
  .twc-tooltip[data-place="left"] { transform-origin: right center; translate: 0 -50%; }
7996
8000
  .twc-tooltip[data-place="right"] { transform-origin: left center; translate: 0 -50%; }
7997
8001
  .twc-tooltip[data-show="true"][data-place="top"], .twc-tooltip[data-show="true"][data-place="bottom"] { transform: scale(1); }
7998
- .twc-tooltip__arrow { position: absolute; width: 7px; height: 7px; background: var(--color-text); transform: rotate(45deg); }
8002
+ .twc-tooltip__arrow { position: absolute; width: 7px; height: 7px; background: var(--_tt-bg); transform: rotate(45deg); }
8003
+ /* #385: re-scope token ink for the label subtree so Text/Heading (which set --color-text as an inline
8004
+ style) render in the bubble's fg instead of the page ink. display:contents adds no box, so the label's
8005
+ own flex/block layout is unchanged; custom properties still inherit through it. */
8006
+ .twc-tooltip__content { display: contents; --color-text: var(--_tt-fg);
8007
+ --color-text-muted: color-mix(in srgb, var(--_tt-fg) 72%, var(--_tt-bg));
8008
+ --color-text-subtle: color-mix(in srgb, var(--_tt-fg) 55%, var(--_tt-bg)); }
7999
8009
  /* Arrow tracks the trigger via --_tw-arrow-x/y (px from the tooltip edge) instead of being
8000
8010
  locked to the centre, so it still points at the trigger when the bubble is clamped near a
8001
8011
  viewport edge. Falls back to 50% before measurement / SSR. */
@@ -8120,7 +8130,7 @@ function Tooltip({
8120
8130
  "--_tw-arrow-y": coords.arrowY != null ? `${coords.arrowY}px` : void 0
8121
8131
  },
8122
8132
  children: [
8123
- label,
8133
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-tooltip__content", children: label }),
8124
8134
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-tooltip__arrow", "aria-hidden": "true" })
8125
8135
  ]
8126
8136
  }
@@ -9300,6 +9310,8 @@ function Datatable({
9300
9310
  showExport = false,
9301
9311
  showDensity = false,
9302
9312
  showPivot = false,
9313
+ showColumns,
9314
+ showFilters,
9303
9315
  exportFilename = "export",
9304
9316
  aggregationValues = null,
9305
9317
  disableColumnReorder = false,
@@ -9331,6 +9343,8 @@ function Datatable({
9331
9343
  ariaLabel = "Data table",
9332
9344
  "aria-label": ariaLabelAttr,
9333
9345
  rowGrouping = [],
9346
+ showGroupBar = true,
9347
+ renderGroupLabel,
9334
9348
  rowNumbers = false,
9335
9349
  searchFields = null,
9336
9350
  searchable = true,
@@ -11110,6 +11124,8 @@ function Datatable({
11110
11124
  }
11111
11125
  const tableMinWidth = leadW + ordered.reduce((a, c) => a + widthOf(c), 0);
11112
11126
  const filterableCols = React51__namespace.default.useMemo(() => cols.filter((c) => c.filterable), [cols]);
11127
+ const columnsShown = showColumns !== void 0 ? showColumns : cols.some((c) => c.hideable) || rowNumbers;
11128
+ const filtersShown = showFilters !== void 0 ? showFilters : filterableCols.length > 0;
11113
11129
  React51__namespace.default.useEffect(() => {
11114
11130
  const el = filterPanelRef.current;
11115
11131
  if (panel !== "filters" || !el || typeof document === "undefined") return void 0;
@@ -11496,6 +11512,7 @@ function Datatable({
11496
11512
  const totalCols = ordered.length + (checkboxSelection ? 1 : 0) + (showRowNum ? 1 : 0) + (hasExpandCol ? 1 : 0);
11497
11513
  function renderGroupRow(item) {
11498
11514
  const subs = aggOn ? subtotalText(item.rows) : [];
11515
+ const custom = renderGroupLabel ? renderGroupLabel({ field: item.field, value: item.value, count: item.count, rows: item.rows }) : null;
11499
11516
  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: [
11500
11517
  /* @__PURE__ */ jsxRuntime.jsxs(
11501
11518
  "button",
@@ -11507,12 +11524,14 @@ function Datatable({
11507
11524
  onClick: () => toggleGroup(item.key),
11508
11525
  children: [
11509
11526
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__group-chev", "data-open": !item.collapsed || void 0, children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.chevDown }) }),
11510
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-dt__group-name", children: [
11511
- fieldLabel(item.field),
11512
- ":"
11513
- ] }),
11514
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__group-val", children: String(item.value) }),
11515
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__group-count", children: item.count })
11527
+ renderGroupLabel ? custom : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11528
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-dt__group-name", children: [
11529
+ fieldLabel(item.field),
11530
+ ":"
11531
+ ] }),
11532
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__group-val", children: String(item.value) }),
11533
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__group-count", children: item.count })
11534
+ ] })
11516
11535
  ]
11517
11536
  }
11518
11537
  ),
@@ -11877,11 +11896,12 @@ function Datatable({
11877
11896
  /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: diffOnly, onChange: (e) => setDiffOnly(e.target.checked) }),
11878
11897
  diff.toggleLabel != null ? diff.toggleLabel : "Only changed"
11879
11898
  ] }) : null,
11880
- /* @__PURE__ */ jsxRuntime.jsxs(
11899
+ columnsShown ? /* @__PURE__ */ jsxRuntime.jsxs(
11881
11900
  "button",
11882
11901
  {
11883
11902
  type: "button",
11884
11903
  className: "twc-dt__tbtn",
11904
+ "data-tbtn": "columns",
11885
11905
  "data-active": panel === "columns" || void 0,
11886
11906
  "data-tip": "Show or hide columns",
11887
11907
  onClick: (e) => {
@@ -11901,12 +11921,13 @@ function Datatable({
11901
11921
  hidden.size ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__tbadge", children: cols.length - hidden.size }) : null
11902
11922
  ]
11903
11923
  }
11904
- ),
11905
- /* @__PURE__ */ jsxRuntime.jsxs(
11924
+ ) : null,
11925
+ filtersShown ? /* @__PURE__ */ jsxRuntime.jsxs(
11906
11926
  "button",
11907
11927
  {
11908
11928
  type: "button",
11909
11929
  className: "twc-dt__tbtn",
11930
+ "data-tbtn": "filters",
11910
11931
  "data-active": panel === "filters" || void 0,
11911
11932
  "data-tip": "Filter rows",
11912
11933
  onClick: (e) => {
@@ -11925,7 +11946,7 @@ function Datatable({
11925
11946
  filters.length ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__tbadge", children: filters.length }) : null
11926
11947
  ]
11927
11948
  }
11928
- ),
11949
+ ) : null,
11929
11950
  showDensity ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "twc-dt__tbtn", "data-tip": "Change row density", onClick: () => setDensity((d) => d === "compact" ? "standard" : d === "standard" ? "comfortable" : "compact"), children: [
11930
11951
  /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.density }),
11931
11952
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__tlabel", children: density[0].toUpperCase() + density.slice(1) })
@@ -12022,7 +12043,7 @@ function Datatable({
12022
12043
  }, children: /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.x }) }) : null
12023
12044
  ] }) : null
12024
12045
  ] }),
12025
- !pivotActive && activeGroupBy.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__groupbar", children: [
12046
+ !pivotActive && activeGroupBy.length && showGroupBar ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twc-dt__groupbar", children: [
12026
12047
  /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.group }),
12027
12048
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "twc-dt__groupbar-label", children: "Grouped by" }),
12028
12049
  activeGroupBy.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "twc-dt__groupchip", children: [
@@ -12497,13 +12518,13 @@ function Datatable({
12497
12518
  " Sort descending"
12498
12519
  ] })
12499
12520
  ] }) : null,
12500
- c.filterable ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", role: "menuitem", className: "twc-dt__mi", onClick: (e) => {
12521
+ c.filterable && filtersShown ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", role: "menuitem", className: "twc-dt__mi", onClick: (e) => {
12501
12522
  addFilter(c.field);
12502
12523
  setColMenu(null);
12503
12524
  closeMenu();
12504
12525
  restoreTriggerFocus();
12505
12526
  setPanel("filters");
12506
- openPanel(document.querySelector(".twc-dt__toolbar .twc-dt__tbtn:nth-child(2)"), "left", DT_FILTER_PANEL_W);
12527
+ openPanel(document.querySelector('.twc-dt__toolbar .twc-dt__tbtn[data-tbtn="filters"]'), "left", DT_FILTER_PANEL_W);
12507
12528
  }, children: [
12508
12529
  /* @__PURE__ */ jsxRuntime.jsx(Svg, { d: I.filter }),
12509
12530
  " Filter"
@@ -12576,7 +12597,7 @@ function Datatable({
12576
12597
  " ",
12577
12598
  wrapped.has(c.field) ? "Unwrap text" : "Wrap text"
12578
12599
  ] }) : null,
12579
- c.hideable ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", role: "menuitem", className: "twc-dt__mi", onClick: () => {
12600
+ c.hideable && columnsShown ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", role: "menuitem", className: "twc-dt__mi", onClick: () => {
12580
12601
  setHidden((h) => new Set(h).add(c.field));
12581
12602
  close();
12582
12603
  }, children: [