@underverse-ui/underverse 1.0.161 → 1.0.163

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.d.cts CHANGED
@@ -2559,7 +2559,32 @@ type DataTableColumn<T> = {
2559
2559
  /** Advanced: Override auto-calculated colspan (defaults to number of leaf descendants) */
2560
2560
  colSpan?: number;
2561
2561
  /** Advanced: Override auto-calculated rowspan (defaults based on depth) */
2562
+ /** Advanced: Override auto-calculated rowspan (defaults based on depth) */
2562
2563
  rowSpan?: number;
2564
+ /**
2565
+ * Color tag for this column (hex or rgb string, e.g. "#3b82f6").
2566
+ * - Header cell gets a darker tinted background
2567
+ * - Body cells get a lighter tinted background
2568
+ * - Columns with the same colorTag are grouped together in the visibility dropdown
2569
+ */
2570
+ colorTag?: string;
2571
+ };
2572
+ /** Configuration for a column color group in the visibility dropdown */
2573
+ type ColumnColorGroup = {
2574
+ /** Display label for this group (e.g. "Bắt buộc", "Tùy chọn") */
2575
+ label: string;
2576
+ /**
2577
+ * Optional override for the header cell text color of columns in this group.
2578
+ * Accepts any valid CSS color (hex, rgb, rgba, color-mix, var(--token), ...).
2579
+ * When omitted, the table picks a readable foreground (black or white) based
2580
+ * on the perceived luminance of the column's `colorTag` via WCAG formula.
2581
+ *
2582
+ * Useful when:
2583
+ * - the auto-picker doesn't match your brand palette
2584
+ * - you want a fixed color that survives light/dark theme swaps
2585
+ * (e.g., a CSS var like `var(--foreground)`)
2586
+ */
2587
+ headerTextColor?: string;
2563
2588
  };
2564
2589
  type Sorter = {
2565
2590
  key: string;
@@ -2583,6 +2608,8 @@ type DataTableLabels = {
2583
2608
  alignRight?: string;
2584
2609
  noData?: string;
2585
2610
  sortBy?: string;
2611
+ selectAll?: string;
2612
+ default?: string;
2586
2613
  };
2587
2614
  /** Public props for the `DataTable` component. */
2588
2615
  interface DataTableProps<T> {
@@ -2597,6 +2624,12 @@ interface DataTableProps<T> {
2597
2624
  onQueryChange?: (q: DataTableQuery) => void;
2598
2625
  caption?: React__default.ReactNode;
2599
2626
  toolbar?: React__default.ReactNode;
2627
+ /**
2628
+ * Define color groups for the column visibility dropdown legend.
2629
+ * Key = color value used in column's `colorTag` (e.g. "#1e40af").
2630
+ * If not provided, columns with colorTag still get colored but won't be grouped in dropdown.
2631
+ */
2632
+ columnColorGroups?: Record<string, ColumnColorGroup>;
2600
2633
  /** Visual size preset. Maps to component scales in the table UI. */
2601
2634
  size?: DataTableSize;
2602
2635
  enableColumnVisibilityToggle?: boolean;
@@ -2634,7 +2667,7 @@ interface DataTableProps<T> {
2634
2667
  labels?: DataTableLabels;
2635
2668
  }
2636
2669
 
2637
- declare function DataTable<T extends Record<string, any>>({ columns, data, rowKey, loading, total, page, pageSize, pageSizeOptions, onQueryChange, caption, toolbar, size, enableColumnVisibilityToggle, enableDensityToggle, enableHeaderAlignToggle, striped, columnDividers, className, storageKey, stickyHeader, maxHeight, horizontalMode, overflowHidden, useOverlayScrollbar, virtualizedRows, estimatedRowHeight, overscan, enableHeaderAutoFit, labels, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
2670
+ declare function DataTable<T extends Record<string, any>>({ columns, data, rowKey, loading, total, page, pageSize, pageSizeOptions, onQueryChange, caption, toolbar, size, enableColumnVisibilityToggle, enableDensityToggle, enableHeaderAlignToggle, striped, columnDividers, className, storageKey, stickyHeader, maxHeight, horizontalMode, overflowHidden, useOverlayScrollbar, virtualizedRows, estimatedRowHeight, overscan, enableHeaderAutoFit, labels, columnColorGroups, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
2638
2671
 
2639
2672
  /** Public props for the `Table` component. */
2640
2673
  interface TableProps extends React__default.HTMLAttributes<HTMLTableElement> {
@@ -3375,6 +3408,9 @@ declare const underverseMessages: {
3375
3408
  loading: string;
3376
3409
  noData: string;
3377
3410
  clearFilter: string;
3411
+ selectAll: string;
3412
+ default: string;
3413
+ other: string;
3378
3414
  headerAlign: string;
3379
3415
  alignLeft: string;
3380
3416
  alignCenter: string;
@@ -3768,6 +3804,9 @@ declare const underverseMessages: {
3768
3804
  loading: string;
3769
3805
  noData: string;
3770
3806
  clearFilter: string;
3807
+ selectAll: string;
3808
+ default: string;
3809
+ other: string;
3771
3810
  headerAlign: string;
3772
3811
  alignLeft: string;
3773
3812
  alignCenter: string;
@@ -4161,6 +4200,9 @@ declare const underverseMessages: {
4161
4200
  loading: string;
4162
4201
  noData: string;
4163
4202
  clearFilter: string;
4203
+ selectAll: string;
4204
+ default: string;
4205
+ other: string;
4164
4206
  headerAlign: string;
4165
4207
  alignLeft: string;
4166
4208
  alignCenter: string;
@@ -4554,6 +4596,9 @@ declare const underverseMessages: {
4554
4596
  loading: string;
4555
4597
  noData: string;
4556
4598
  clearFilter: string;
4599
+ selectAll: string;
4600
+ default: string;
4601
+ other: string;
4557
4602
  headerAlign: string;
4558
4603
  alignLeft: string;
4559
4604
  alignCenter: string;
@@ -4950,6 +4995,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
4950
4995
  loading: string;
4951
4996
  noData: string;
4952
4997
  clearFilter: string;
4998
+ selectAll: string;
4999
+ default: string;
5000
+ other: string;
4953
5001
  headerAlign: string;
4954
5002
  alignLeft: string;
4955
5003
  alignCenter: string;
@@ -5342,6 +5390,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5342
5390
  loading: string;
5343
5391
  noData: string;
5344
5392
  clearFilter: string;
5393
+ selectAll: string;
5394
+ default: string;
5395
+ other: string;
5345
5396
  headerAlign: string;
5346
5397
  alignLeft: string;
5347
5398
  alignCenter: string;
@@ -5734,6 +5785,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5734
5785
  loading: string;
5735
5786
  noData: string;
5736
5787
  clearFilter: string;
5788
+ selectAll: string;
5789
+ default: string;
5790
+ other: string;
5737
5791
  headerAlign: string;
5738
5792
  alignLeft: string;
5739
5793
  alignCenter: string;
@@ -6126,6 +6180,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
6126
6180
  loading: string;
6127
6181
  noData: string;
6128
6182
  clearFilter: string;
6183
+ selectAll: string;
6184
+ default: string;
6185
+ other: string;
6129
6186
  headerAlign: string;
6130
6187
  alignLeft: string;
6131
6188
  alignCenter: string;
package/dist/index.d.ts CHANGED
@@ -2559,7 +2559,32 @@ type DataTableColumn<T> = {
2559
2559
  /** Advanced: Override auto-calculated colspan (defaults to number of leaf descendants) */
2560
2560
  colSpan?: number;
2561
2561
  /** Advanced: Override auto-calculated rowspan (defaults based on depth) */
2562
+ /** Advanced: Override auto-calculated rowspan (defaults based on depth) */
2562
2563
  rowSpan?: number;
2564
+ /**
2565
+ * Color tag for this column (hex or rgb string, e.g. "#3b82f6").
2566
+ * - Header cell gets a darker tinted background
2567
+ * - Body cells get a lighter tinted background
2568
+ * - Columns with the same colorTag are grouped together in the visibility dropdown
2569
+ */
2570
+ colorTag?: string;
2571
+ };
2572
+ /** Configuration for a column color group in the visibility dropdown */
2573
+ type ColumnColorGroup = {
2574
+ /** Display label for this group (e.g. "Bắt buộc", "Tùy chọn") */
2575
+ label: string;
2576
+ /**
2577
+ * Optional override for the header cell text color of columns in this group.
2578
+ * Accepts any valid CSS color (hex, rgb, rgba, color-mix, var(--token), ...).
2579
+ * When omitted, the table picks a readable foreground (black or white) based
2580
+ * on the perceived luminance of the column's `colorTag` via WCAG formula.
2581
+ *
2582
+ * Useful when:
2583
+ * - the auto-picker doesn't match your brand palette
2584
+ * - you want a fixed color that survives light/dark theme swaps
2585
+ * (e.g., a CSS var like `var(--foreground)`)
2586
+ */
2587
+ headerTextColor?: string;
2563
2588
  };
2564
2589
  type Sorter = {
2565
2590
  key: string;
@@ -2583,6 +2608,8 @@ type DataTableLabels = {
2583
2608
  alignRight?: string;
2584
2609
  noData?: string;
2585
2610
  sortBy?: string;
2611
+ selectAll?: string;
2612
+ default?: string;
2586
2613
  };
2587
2614
  /** Public props for the `DataTable` component. */
2588
2615
  interface DataTableProps<T> {
@@ -2597,6 +2624,12 @@ interface DataTableProps<T> {
2597
2624
  onQueryChange?: (q: DataTableQuery) => void;
2598
2625
  caption?: React__default.ReactNode;
2599
2626
  toolbar?: React__default.ReactNode;
2627
+ /**
2628
+ * Define color groups for the column visibility dropdown legend.
2629
+ * Key = color value used in column's `colorTag` (e.g. "#1e40af").
2630
+ * If not provided, columns with colorTag still get colored but won't be grouped in dropdown.
2631
+ */
2632
+ columnColorGroups?: Record<string, ColumnColorGroup>;
2600
2633
  /** Visual size preset. Maps to component scales in the table UI. */
2601
2634
  size?: DataTableSize;
2602
2635
  enableColumnVisibilityToggle?: boolean;
@@ -2634,7 +2667,7 @@ interface DataTableProps<T> {
2634
2667
  labels?: DataTableLabels;
2635
2668
  }
2636
2669
 
2637
- declare function DataTable<T extends Record<string, any>>({ columns, data, rowKey, loading, total, page, pageSize, pageSizeOptions, onQueryChange, caption, toolbar, size, enableColumnVisibilityToggle, enableDensityToggle, enableHeaderAlignToggle, striped, columnDividers, className, storageKey, stickyHeader, maxHeight, horizontalMode, overflowHidden, useOverlayScrollbar, virtualizedRows, estimatedRowHeight, overscan, enableHeaderAutoFit, labels, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
2670
+ declare function DataTable<T extends Record<string, any>>({ columns, data, rowKey, loading, total, page, pageSize, pageSizeOptions, onQueryChange, caption, toolbar, size, enableColumnVisibilityToggle, enableDensityToggle, enableHeaderAlignToggle, striped, columnDividers, className, storageKey, stickyHeader, maxHeight, horizontalMode, overflowHidden, useOverlayScrollbar, virtualizedRows, estimatedRowHeight, overscan, enableHeaderAutoFit, labels, columnColorGroups, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
2638
2671
 
2639
2672
  /** Public props for the `Table` component. */
2640
2673
  interface TableProps extends React__default.HTMLAttributes<HTMLTableElement> {
@@ -3375,6 +3408,9 @@ declare const underverseMessages: {
3375
3408
  loading: string;
3376
3409
  noData: string;
3377
3410
  clearFilter: string;
3411
+ selectAll: string;
3412
+ default: string;
3413
+ other: string;
3378
3414
  headerAlign: string;
3379
3415
  alignLeft: string;
3380
3416
  alignCenter: string;
@@ -3768,6 +3804,9 @@ declare const underverseMessages: {
3768
3804
  loading: string;
3769
3805
  noData: string;
3770
3806
  clearFilter: string;
3807
+ selectAll: string;
3808
+ default: string;
3809
+ other: string;
3771
3810
  headerAlign: string;
3772
3811
  alignLeft: string;
3773
3812
  alignCenter: string;
@@ -4161,6 +4200,9 @@ declare const underverseMessages: {
4161
4200
  loading: string;
4162
4201
  noData: string;
4163
4202
  clearFilter: string;
4203
+ selectAll: string;
4204
+ default: string;
4205
+ other: string;
4164
4206
  headerAlign: string;
4165
4207
  alignLeft: string;
4166
4208
  alignCenter: string;
@@ -4554,6 +4596,9 @@ declare const underverseMessages: {
4554
4596
  loading: string;
4555
4597
  noData: string;
4556
4598
  clearFilter: string;
4599
+ selectAll: string;
4600
+ default: string;
4601
+ other: string;
4557
4602
  headerAlign: string;
4558
4603
  alignLeft: string;
4559
4604
  alignCenter: string;
@@ -4950,6 +4995,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
4950
4995
  loading: string;
4951
4996
  noData: string;
4952
4997
  clearFilter: string;
4998
+ selectAll: string;
4999
+ default: string;
5000
+ other: string;
4953
5001
  headerAlign: string;
4954
5002
  alignLeft: string;
4955
5003
  alignCenter: string;
@@ -5342,6 +5390,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5342
5390
  loading: string;
5343
5391
  noData: string;
5344
5392
  clearFilter: string;
5393
+ selectAll: string;
5394
+ default: string;
5395
+ other: string;
5345
5396
  headerAlign: string;
5346
5397
  alignLeft: string;
5347
5398
  alignCenter: string;
@@ -5734,6 +5785,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5734
5785
  loading: string;
5735
5786
  noData: string;
5736
5787
  clearFilter: string;
5788
+ selectAll: string;
5789
+ default: string;
5790
+ other: string;
5737
5791
  headerAlign: string;
5738
5792
  alignLeft: string;
5739
5793
  alignCenter: string;
@@ -6126,6 +6180,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
6126
6180
  loading: string;
6127
6181
  noData: string;
6128
6182
  clearFilter: string;
6183
+ selectAll: string;
6184
+ default: string;
6185
+ other: string;
6129
6186
  headerAlign: string;
6130
6187
  alignLeft: string;
6131
6188
  alignCenter: string;
package/dist/index.js CHANGED
@@ -585,6 +585,9 @@ var en_default = {
585
585
  loading: "Loading",
586
586
  noData: "No data",
587
587
  clearFilter: "Clear filter",
588
+ selectAll: "Select all",
589
+ default: "Default",
590
+ other: "Other",
588
591
  headerAlign: "Header alignment",
589
592
  alignLeft: "Align left",
590
593
  alignCenter: "Align center",
@@ -980,6 +983,9 @@ var vi_default = {
980
983
  loading: "\u0110ang t\u1EA3i",
981
984
  noData: "Kh\xF4ng c\xF3 d\u1EEF li\u1EC7u",
982
985
  clearFilter: "X\xF3a b\u1ED9 l\u1ECDc",
986
+ selectAll: "Ch\u1ECDn t\u1EA5t c\u1EA3",
987
+ default: "M\u1EB7c \u0111\u1ECBnh",
988
+ other: "Kh\xE1c",
983
989
  headerAlign: "C\u0103n ch\u1EC9nh ti\xEAu \u0111\u1EC1",
984
990
  alignLeft: "C\u0103n tr\xE1i",
985
991
  alignCenter: "C\u0103n gi\u1EEFa",
@@ -1375,6 +1381,9 @@ var ko_default = {
1375
1381
  loading: "\uB85C\uB529 \uC911",
1376
1382
  noData: "\uB370\uC774\uD130 \uC5C6\uC74C",
1377
1383
  clearFilter: "\uD544\uD130 \uC9C0\uC6B0\uAE30",
1384
+ selectAll: "\uC804\uCCB4 \uC120\uD0DD",
1385
+ default: "\uAE30\uBCF8\uAC12",
1386
+ other: "\uAE30\uD0C0",
1378
1387
  headerAlign: "\uD5E4\uB354 \uC815\uB82C",
1379
1388
  alignLeft: "\uC67C\uCABD \uC815\uB82C",
1380
1389
  alignCenter: "\uAC00\uC6B4\uB370 \uC815\uB82C",
@@ -1770,6 +1779,9 @@ var ja_default = {
1770
1779
  loading: "\u8AAD\u307F\u8FBC\u307F\u4E2D",
1771
1780
  noData: "\u30C7\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093",
1772
1781
  clearFilter: "\u30D5\u30A3\u30EB\u30BF\u30FC\u3092\u30AF\u30EA\u30A2",
1782
+ selectAll: "\u3059\u3079\u3066\u9078\u629E",
1783
+ default: "\u30C7\u30D5\u30A9\u30EB\u30C8",
1784
+ other: "\u305D\u306E\u4ED6",
1773
1785
  headerAlign: "\u30D8\u30C3\u30C0\u30FC\u914D\u7F6E",
1774
1786
  alignLeft: "\u5DE6\u63C3\u3048",
1775
1787
  alignCenter: "\u4E2D\u592E\u63C3\u3048",
@@ -22925,6 +22937,88 @@ function DataTableBodyRows({
22925
22937
  // src/components/DataTable/components/DataTableHeader.tsx
22926
22938
  import React56 from "react";
22927
22939
  import { Filter as FilterIcon } from "lucide-react";
22940
+
22941
+ // src/components/DataTable/utils/colorTag.ts
22942
+ function parseColor(color) {
22943
+ if (!color) return null;
22944
+ const c = color.trim().toLowerCase();
22945
+ if (c.startsWith("#")) {
22946
+ let hex = c.substring(1);
22947
+ if (hex.length === 3) {
22948
+ hex = hex.split("").map((char) => char + char).join("");
22949
+ }
22950
+ if (hex.length === 6) {
22951
+ const r = parseInt(hex.substring(0, 2), 16);
22952
+ const g = parseInt(hex.substring(2, 4), 16);
22953
+ const b = parseInt(hex.substring(4, 6), 16);
22954
+ if (!isNaN(r) && !isNaN(g) && !isNaN(b)) {
22955
+ return [r, g, b];
22956
+ }
22957
+ }
22958
+ return null;
22959
+ }
22960
+ if (c.startsWith("rgb")) {
22961
+ const match = c.match(/rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
22962
+ if (match) {
22963
+ const r = parseInt(match[1], 10);
22964
+ const g = parseInt(match[2], 10);
22965
+ const b = parseInt(match[3], 10);
22966
+ if (!isNaN(r) && !isNaN(g) && !isNaN(b)) {
22967
+ return [r, g, b];
22968
+ }
22969
+ }
22970
+ return null;
22971
+ }
22972
+ return null;
22973
+ }
22974
+ function toRgba(r, g, b, alpha) {
22975
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
22976
+ }
22977
+ function getHeaderBgColor(colorTag) {
22978
+ const rgb = parseColor(colorTag);
22979
+ if (!rgb) return colorTag;
22980
+ return toRgba(rgb[0], rgb[1], rgb[2], 1);
22981
+ }
22982
+ function getReadableForeground(colorTag) {
22983
+ const rgb = parseColor(colorTag);
22984
+ if (!rgb) return void 0;
22985
+ const toLinear = (c) => {
22986
+ const s = c / 255;
22987
+ return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
22988
+ };
22989
+ const L = 0.2126 * toLinear(rgb[0]) + 0.7152 * toLinear(rgb[1]) + 0.0722 * toLinear(rgb[2]);
22990
+ return L > 0.5 ? "rgba(15, 23, 42, 0.92)" : "rgba(255, 255, 255, 0.95)";
22991
+ }
22992
+ function groupColumnsByColorTag(leafCols, colorGroups) {
22993
+ const groupsMap = /* @__PURE__ */ new Map();
22994
+ const ungrouped = [];
22995
+ for (const col of leafCols) {
22996
+ if (col.colorTag && colorGroups && colorGroups[col.colorTag]) {
22997
+ const tag = col.colorTag;
22998
+ if (!groupsMap.has(tag)) {
22999
+ groupsMap.set(tag, []);
23000
+ }
23001
+ groupsMap.get(tag).push(col);
23002
+ } else {
23003
+ ungrouped.push(col);
23004
+ }
23005
+ }
23006
+ const groups = [];
23007
+ if (colorGroups) {
23008
+ for (const [tag, groupConfig] of Object.entries(colorGroups)) {
23009
+ if (groupsMap.has(tag)) {
23010
+ groups.push({
23011
+ colorTag: tag,
23012
+ label: groupConfig.label,
23013
+ columns: groupsMap.get(tag)
23014
+ });
23015
+ }
23016
+ }
23017
+ }
23018
+ return { groups, ungrouped };
23019
+ }
23020
+
23021
+ // src/components/DataTable/components/DataTableHeader.tsx
22928
23022
  import { Fragment as Fragment24, jsx as jsx65, jsxs as jsxs53 } from "react/jsx-runtime";
22929
23023
  function getColumnLabel(title) {
22930
23024
  if (typeof title === "string" || typeof title === "number") {
@@ -22956,7 +23050,8 @@ function DataTableHeader({
22956
23050
  getStickyHeaderClass,
22957
23051
  getStickyHeaderCellStyle,
22958
23052
  sortByLabel,
22959
- t
23053
+ t,
23054
+ columnColorGroups
22960
23055
  }) {
22961
23056
  const gi18n = useGlobalI18n();
22962
23057
  const renderFilterControl = React56.useCallback(
@@ -23105,7 +23200,7 @@ function DataTableHeader({
23105
23200
  title: gi18n.filterByColumn ? gi18n.filterByColumn(columnLabel) : `Filter by ${columnLabel}`,
23106
23201
  className: cn(
23107
23202
  "p-1.5 rounded-lg transition-all duration-200 hover:bg-accent",
23108
- filters[col.key] ? "bg-accent text-primary" : "text-muted-foreground"
23203
+ filters[col.key] ? "bg-accent opacity-100" : "opacity-60 hover:opacity-100"
23109
23204
  ),
23110
23205
  "aria-label": gi18n.filterByColumn ? gi18n.filterByColumn(columnLabel) : `Filter by ${columnLabel}`,
23111
23206
  children: /* @__PURE__ */ jsx65(FilterIcon, { className: "w-4 h-4" })
@@ -23173,6 +23268,8 @@ function DataTableHeader({
23173
23268
  const isAfterFixedLeft = prevCol?.fixed === "left";
23174
23269
  const showBorderLeft = columnDividers && cellIndex > 0 && !isAfterFixedLeft && !col.fixed;
23175
23270
  const isLastCell = cellIndex === row.length - 1;
23271
+ const headerBackgroundColor = isLeaf && col.colorTag ? getHeaderBgColor(col.colorTag) : "var(--muted)";
23272
+ const headerColor = isLeaf && col.colorTag ? columnColorGroups?.[col.colorTag]?.headerTextColor ?? getReadableForeground(col.colorTag) : void 0;
23176
23273
  return /* @__PURE__ */ jsxs53(
23177
23274
  TableHead,
23178
23275
  {
@@ -23181,6 +23278,8 @@ function DataTableHeader({
23181
23278
  "data-underverse-column-key": isLeaf ? col.key : void 0,
23182
23279
  style: {
23183
23280
  width: col.width,
23281
+ backgroundColor: headerBackgroundColor,
23282
+ color: headerColor,
23184
23283
  ...getStickyHeaderCellStyle(headerCell)
23185
23284
  },
23186
23285
  className: cn(
@@ -23257,7 +23356,6 @@ function DataTablePagination({
23257
23356
  result.push(totalPages);
23258
23357
  return result;
23259
23358
  }, [curPage, totalPages]);
23260
- if (!(totalItems > 0 && totalPages > 1)) return null;
23261
23359
  const controlButtonSize = size === "lg" ? "md" : "sm";
23262
23360
  const navBtnClass = size === "sm" ? "h-6 w-6 p-0 rounded-full" : size === "lg" ? "h-8 w-8 p-0 rounded-full" : "h-7 w-7 p-0 rounded-full";
23263
23361
  const navIconClass = size === "sm" ? "h-3.5 w-3.5" : size === "lg" ? "h-5 w-5" : "h-4 w-4";
@@ -23439,13 +23537,18 @@ function DataTableToolbar({
23439
23537
  setDensity,
23440
23538
  setHeaderAlign,
23441
23539
  labels,
23442
- t
23540
+ t,
23541
+ columnColorGroups,
23542
+ defaultVisibleKeys
23443
23543
  }) {
23444
23544
  const controlButtonSize = size === "lg" ? "md" : "sm";
23445
23545
  const controlButtonClass = size === "sm" ? "h-7 px-2 text-xs" : size === "lg" ? "h-9 px-3 text-sm" : "h-8 px-2";
23446
23546
  const iconClass = size === "sm" ? "w-3.5 h-3.5 mr-1" : "w-4 h-4 mr-1";
23447
23547
  const captionClass = size === "sm" ? "text-xs" : size === "lg" ? "text-sm" : "text-sm";
23448
23548
  const leafCols = React58.useMemo(() => getLeafColumns(columns), [columns]);
23549
+ const { groups, ungrouped } = React58.useMemo(() => groupColumnsByColorTag(leafCols, columnColorGroups), [leafCols, columnColorGroups]);
23550
+ const handleSelectAll = () => setVisibleCols(leafCols.map((c) => c.key));
23551
+ const handleDefault = () => setVisibleCols(defaultVisibleKeys);
23449
23552
  return /* @__PURE__ */ jsxs55("div", { className: "flex items-center justify-between gap-4 mb-1", children: [
23450
23553
  /* @__PURE__ */ jsx67("div", { className: captionClass + " text-muted-foreground", children: caption }),
23451
23554
  /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-2", children: [
@@ -23463,7 +23566,7 @@ function DataTableToolbar({
23463
23566
  ]
23464
23567
  }
23465
23568
  ),
23466
- enableColumnVisibilityToggle && /* @__PURE__ */ jsx67(
23569
+ enableColumnVisibilityToggle && /* @__PURE__ */ jsxs55(
23467
23570
  DropdownMenu_default,
23468
23571
  {
23469
23572
  trigger: /* @__PURE__ */ jsxs55(Button_default, { variant: "ghost", size: controlButtonSize, className: controlButtonClass, children: [
@@ -23478,19 +23581,49 @@ function DataTableToolbar({
23478
23581
  ) }),
23479
23582
  labels?.columns || t("columns")
23480
23583
  ] }),
23481
- children: leafCols.map((c) => /* @__PURE__ */ jsxs55(
23482
- DropdownMenuItem,
23483
- {
23484
- onClick: () => {
23485
- setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
23486
- },
23487
- children: [
23488
- /* @__PURE__ */ jsx67("input", { type: "checkbox", className: "mr-2 rounded-md border-border/50", readOnly: true, checked: visibleCols.includes(c.key) }),
23489
- /* @__PURE__ */ jsx67("span", { className: "truncate", children: c.title })
23490
- ]
23491
- },
23492
- c.key
23493
- ))
23584
+ children: [
23585
+ /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-2 px-2 py-1.5 mb-1", children: [
23586
+ /* @__PURE__ */ jsx67(Button_default, { variant: "outline", size: "sm", className: "h-7 text-xs flex-1", onClick: handleSelectAll, children: labels?.selectAll || t("selectAll") || "Select All" }),
23587
+ /* @__PURE__ */ jsx67(Button_default, { variant: "outline", size: "sm", className: "h-7 text-xs flex-1", onClick: handleDefault, children: labels?.default || t("default") || "Default" })
23588
+ ] }),
23589
+ /* @__PURE__ */ jsxs55("div", { className: "max-h-80 overflow-y-auto min-w-50", children: [
23590
+ groups.length > 0 && groups.map((group) => /* @__PURE__ */ jsxs55(React58.Fragment, { children: [
23591
+ /* @__PURE__ */ jsxs55("div", { className: "px-3 py-1.5 text-[11px] font-semibold uppercase text-muted-foreground flex items-center gap-2 mt-1 bg-accent/30 sticky top-0 z-10 backdrop-blur-sm", children: [
23592
+ /* @__PURE__ */ jsx67("span", { className: "w-2.5 h-2.5 rounded-full shadow-sm", style: { backgroundColor: group.colorTag } }),
23593
+ group.label
23594
+ ] }),
23595
+ group.columns.map((c) => /* @__PURE__ */ jsxs55(
23596
+ DropdownMenuItem,
23597
+ {
23598
+ onClick: () => {
23599
+ setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
23600
+ },
23601
+ closeOnSelect: false,
23602
+ children: [
23603
+ /* @__PURE__ */ jsx67("input", { type: "checkbox", className: "mr-2 rounded-md border-border/50", readOnly: true, checked: visibleCols.includes(c.key) }),
23604
+ /* @__PURE__ */ jsx67("span", { className: "truncate", children: c.title })
23605
+ ]
23606
+ },
23607
+ c.key
23608
+ ))
23609
+ ] }, group.colorTag)),
23610
+ groups.length > 0 && ungrouped.length > 0 && /* @__PURE__ */ jsx67("div", { className: "px-3 py-1.5 text-[11px] font-semibold uppercase text-muted-foreground mt-1 bg-accent/30 sticky top-0 z-10 backdrop-blur-sm", children: t("other") || "Other" }),
23611
+ ungrouped.map((c) => /* @__PURE__ */ jsxs55(
23612
+ DropdownMenuItem,
23613
+ {
23614
+ onClick: () => {
23615
+ setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
23616
+ },
23617
+ closeOnSelect: false,
23618
+ children: [
23619
+ /* @__PURE__ */ jsx67("input", { type: "checkbox", className: "mr-2 rounded-md border-border/50", readOnly: true, checked: visibleCols.includes(c.key) }),
23620
+ /* @__PURE__ */ jsx67("span", { className: "truncate", children: c.title })
23621
+ ]
23622
+ },
23623
+ c.key
23624
+ ))
23625
+ ] })
23626
+ ]
23494
23627
  }
23495
23628
  ),
23496
23629
  enableHeaderAlignToggle && /* @__PURE__ */ jsx67(
@@ -23786,7 +23919,7 @@ function useStickyColumns(visibleColumns) {
23786
23919
  const getStickyHeaderClass = React63.useCallback(
23787
23920
  (col) => {
23788
23921
  if (!col.fixed) return "";
23789
- return cn("sticky", col.fixed === "left" && "left-0", col.fixed === "right" && "right-0", getBoundaryShadowClass(col), "z-50 !bg-muted");
23922
+ return cn("sticky", col.fixed === "left" && "left-0", col.fixed === "right" && "right-0", getBoundaryShadowClass(col), "z-50");
23790
23923
  },
23791
23924
  [getBoundaryShadowClass]
23792
23925
  );
@@ -23991,7 +24124,8 @@ function DataTable({
23991
24124
  estimatedRowHeight,
23992
24125
  overscan = 8,
23993
24126
  enableHeaderAutoFit = true,
23994
- labels
24127
+ labels,
24128
+ columnColorGroups
23995
24129
  }) {
23996
24130
  const t = useSmartTranslations("Common");
23997
24131
  const [columnWidthOverrides, setColumnWidthOverrides] = React64.useState({});
@@ -23999,6 +24133,9 @@ function DataTable({
23999
24133
  () => applyColumnWidthOverrides(columns, columnWidthOverrides),
24000
24134
  [columnWidthOverrides, columns]
24001
24135
  );
24136
+ const defaultVisibleKeys = React64.useMemo(() => {
24137
+ return getLeafColumns(columnsWithWidthOverrides).filter((col) => col.visible !== false).map((col) => col.key);
24138
+ }, [columnsWithWidthOverrides]);
24002
24139
  const {
24003
24140
  headerAlign,
24004
24141
  setHeaderAlign,
@@ -24139,7 +24276,9 @@ function DataTable({
24139
24276
  setDensity,
24140
24277
  setHeaderAlign,
24141
24278
  labels,
24142
- t
24279
+ t,
24280
+ columnColorGroups,
24281
+ defaultVisibleKeys
24143
24282
  }
24144
24283
  ),
24145
24284
  /* @__PURE__ */ jsx68(
@@ -24188,7 +24327,8 @@ function DataTable({
24188
24327
  getStickyHeaderClass,
24189
24328
  getStickyHeaderCellStyle,
24190
24329
  sortByLabel: labels?.sortBy,
24191
- t
24330
+ t,
24331
+ columnColorGroups
24192
24332
  }
24193
24333
  ) }),
24194
24334
  /* @__PURE__ */ jsx68(
@@ -24793,7 +24933,7 @@ var CalloutView = ({ node, updateAttributes, selected }) => {
24793
24933
  children: currentEmoji
24794
24934
  }
24795
24935
  ),
24796
- children: /* @__PURE__ */ jsxs62("div", { className: "flex flex-col gap-3 w-64 max-h-[360px] overflow-y-auto p-1", children: [
24936
+ children: /* @__PURE__ */ jsxs62("div", { className: "flex flex-col gap-3 w-64 max-h-90 overflow-y-auto p-1", children: [
24797
24937
  /* @__PURE__ */ jsx76("div", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1", children: t("callout.selectEmoji") }),
24798
24938
  /* @__PURE__ */ jsx76("div", { className: "h-44 overflow-y-auto border border-border/40 rounded-lg", children: /* @__PURE__ */ jsx76(EmojiPicker2, { onSelect: (emoji) => updateAttributes({ emoji }) }) }),
24799
24939
  /* @__PURE__ */ jsxs62("div", { className: "border-t border-border/50 pt-2 mt-1", children: [
@@ -24977,7 +25117,7 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
24977
25117
  /* @__PURE__ */ jsx77("div", { className: "h-4 w-5/6 bg-muted-foreground/20 rounded" })
24978
25118
  ] }),
24979
25119
  /* @__PURE__ */ jsx77("div", { className: "h-20 w-32 bg-muted-foreground/20 rounded-lg flex-shrink-0" })
24980
- ] }) : /* @__PURE__ */ jsxs63("div", { className: "flex flex-col sm:flex-row items-stretch justify-between min-h-[100px]", children: [
25120
+ ] }) : /* @__PURE__ */ jsxs63("div", { className: "flex flex-col sm:flex-row items-stretch justify-between min-h-25", children: [
24981
25121
  /* @__PURE__ */ jsxs63("div", { className: "flex-1 p-4 flex flex-col justify-between gap-1 min-w-0", children: [
24982
25122
  /* @__PURE__ */ jsxs63("div", { className: "flex flex-col gap-1 min-w-0", children: [
24983
25123
  /* @__PURE__ */ jsxs63("span", { className: "text-xs text-muted-foreground font-medium flex items-center gap-1.5 truncate", children: [
@@ -25260,7 +25400,7 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25260
25400
  /* @__PURE__ */ jsxs64("div", { className: "text-xs text-muted-foreground flex items-center gap-2 mt-0.5", children: [
25261
25401
  fileSize ? /* @__PURE__ */ jsx78("span", { children: formatBytes(fileSize) }) : null,
25262
25402
  isUploading && /* @__PURE__ */ jsx78("span", { className: cn(
25263
- "font-medium truncate max-w-[200px]",
25403
+ "font-medium truncate max-w-50",
25264
25404
  uploadError ? "text-destructive" : "text-primary animate-pulse"
25265
25405
  ), children: uploadError ? `${t("fileCard.uploadFailed") || "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"}: ${uploadError}` : t("fileCard.uploading") }),
25266
25406
  isUploading && uploadError && /* @__PURE__ */ jsxs64(
@@ -32125,7 +32265,7 @@ var LinkPreviewContent = ({ editor, onEdit }) => {
32125
32265
  editor.chain().focus().unsetLink().run();
32126
32266
  };
32127
32267
  return /* @__PURE__ */ jsxs73("div", { className: "flex items-center gap-1 p-1 max-w-sm", children: [
32128
- /* @__PURE__ */ jsx87("span", { className: "text-xs text-muted-foreground font-mono px-2 truncate max-w-[180px]", children: url }),
32268
+ /* @__PURE__ */ jsx87("span", { className: "text-xs text-muted-foreground font-mono px-2 truncate max-w-45", children: url }),
32129
32269
  /* @__PURE__ */ jsx87("div", { className: "w-px h-6 bg-border/50 mx-1" }),
32130
32270
  /* @__PURE__ */ jsx87(ToolbarButton, { onClick: handleOpen, title: t("linkPreview.open") || "Open link", children: /* @__PURE__ */ jsx87(ExternalLink3, { className: "w-4 h-4" }) }),
32131
32271
  /* @__PURE__ */ jsx87(ToolbarButton, { onClick: onEdit, title: t("linkPreview.edit") || "Edit link", children: /* @__PURE__ */ jsx87(Edit2, { className: "w-4 h-4" }) }),