@toolbox-web/grid 1.6.0 → 1.6.2

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.
Files changed (49) hide show
  1. package/all.js +561 -471
  2. package/all.js.map +1 -1
  3. package/index.js +3 -3
  4. package/index.js.map +1 -1
  5. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +11 -0
  6. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
  7. package/lib/plugins/context-menu/index.js +136 -77
  8. package/lib/plugins/context-menu/index.js.map +1 -1
  9. package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
  10. package/lib/plugins/filtering/index.js +246 -250
  11. package/lib/plugins/filtering/index.js.map +1 -1
  12. package/lib/plugins/multi-sort/index.js +11 -11
  13. package/lib/plugins/pivot/PivotPlugin.d.ts +2 -0
  14. package/lib/plugins/pivot/PivotPlugin.d.ts.map +1 -1
  15. package/lib/plugins/pivot/index.js +29 -27
  16. package/lib/plugins/pivot/index.js.map +1 -1
  17. package/lib/plugins/print/index.js +1 -1
  18. package/lib/plugins/print/index.js.map +1 -1
  19. package/lib/plugins/row-reorder/RowReorderPlugin.d.ts +18 -0
  20. package/lib/plugins/row-reorder/RowReorderPlugin.d.ts.map +1 -1
  21. package/lib/plugins/row-reorder/index.js +132 -72
  22. package/lib/plugins/row-reorder/index.js.map +1 -1
  23. package/lib/plugins/selection/index.js +1 -1
  24. package/lib/plugins/visibility/index.js +7 -7
  25. package/package.json +1 -1
  26. package/themes/dg-theme-bootstrap.css +60 -33
  27. package/themes/dg-theme-material.css +83 -52
  28. package/themes/dg-theme-standard.css +80 -12
  29. package/themes/dg-theme-vibrant.css +78 -9
  30. package/umd/grid.all.umd.js +17 -17
  31. package/umd/grid.all.umd.js.map +1 -1
  32. package/umd/grid.umd.js +1 -1
  33. package/umd/grid.umd.js.map +1 -1
  34. package/umd/plugins/context-menu.umd.js +1 -1
  35. package/umd/plugins/context-menu.umd.js.map +1 -1
  36. package/umd/plugins/filtering.umd.js +1 -1
  37. package/umd/plugins/filtering.umd.js.map +1 -1
  38. package/umd/plugins/multi-sort.umd.js +1 -1
  39. package/umd/plugins/multi-sort.umd.js.map +1 -1
  40. package/umd/plugins/pivot.umd.js +1 -1
  41. package/umd/plugins/pivot.umd.js.map +1 -1
  42. package/umd/plugins/print.umd.js +1 -1
  43. package/umd/plugins/print.umd.js.map +1 -1
  44. package/umd/plugins/row-reorder.umd.js +1 -1
  45. package/umd/plugins/row-reorder.umd.js.map +1 -1
  46. package/umd/plugins/selection.umd.js +1 -1
  47. package/umd/plugins/selection.umd.js.map +1 -1
  48. package/umd/plugins/visibility.umd.js +1 -1
  49. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -381,7 +381,7 @@ function w(r, e) {
381
381
  const t = u(r), s = u(e);
382
382
  return t.startRow === s.startRow && t.startCol === s.startCol && t.endRow === s.endRow && t.endCol === s.endCol;
383
383
  }
384
- const k = "@layer tbw-plugins{tbw-grid.selecting .data-grid-row>.cell{-webkit-user-select:none;user-select:none}tbw-grid[data-has-focus] .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%))}tbw-grid[data-selection-mode=row] .cell-focus{outline:none}tbw-grid .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg)}tbw-grid .data-grid-row>.cell.selected.top{border-top:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row[data-selectable=false].row-focus{background-color:var(--tbw-color-row-alt)}tbw-grid .data-grid-row>.cell[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row>.cell[data-selectable=false].selected{background-color:var(--tbw-color-warning-bg, rgba(255, 243, 205, .5))}tbw-grid .tbw-selection-summary{font-size:var(--tbw-font-size-sm, .8125rem);color:var(--tbw-color-fg-muted);white-space:nowrap}}";
384
+ const k = "@layer tbw-plugins{tbw-grid.selecting .data-grid-row>.cell{-webkit-user-select:none;user-select:none}tbw-grid[data-has-focus] .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%))}tbw-grid[data-selection-mode=row] .cell-focus{outline:none}tbw-grid .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg)}tbw-grid .data-grid-row>.cell.selected.top{border-top:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row[data-selectable=false].row-focus{background-color:var(--tbw-color-row-alt)}tbw-grid .data-grid-row>.cell[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row>.cell[data-selectable=false].selected{background-color:var(--tbw-selection-warning-bg, rgba(from var(--tbw-color-error) r g b / 50%))}tbw-grid .tbw-selection-summary{font-size:var(--tbw-font-size-sm, .8125rem);color:var(--tbw-color-fg-muted);white-space:nowrap}}";
385
385
  function K(r, e, t) {
386
386
  if (r === "cell" && e.selectedCell)
387
387
  return {
@@ -311,8 +311,8 @@ class C {
311
311
  }
312
312
  // #endregion
313
313
  }
314
- const y = '@layer tbw-plugins{.tbw-visibility-content{display:flex;flex-direction:column;height:100%}.tbw-visibility-list{flex:1;overflow-y:auto;padding:var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem))}.tbw-visibility-row{display:flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));padding:var(--tbw-menu-item-padding, .375rem .25rem);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem);border-radius:var(--tbw-border-radius, .25rem);position:relative}.tbw-visibility-row:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}.tbw-visibility-row input[type=checkbox]{cursor:pointer}.tbw-visibility-row.locked span{color:var(--tbw-color-fg-muted, #888)}.tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted, #888);font-size:var(--tbw-font-size-2xs, .625rem);letter-spacing:-2px;-webkit-user-select:none;user-select:none;flex-shrink:0}.tbw-visibility-row.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg, #1f2937)}.tbw-visibility-label{display:flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));flex:1;cursor:pointer}.tbw-visibility-row.dragging{opacity:.5;cursor:grabbing}.tbw-visibility-row.drop-before:before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-row.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-show-all{margin:var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem));padding:var(--tbw-button-padding, .5rem .75rem);border:1px solid var(--tbw-visibility-border, var(--tbw-color-border, #e5e7eb));border-radius:var(--tbw-border-radius, .25rem);background:var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg, #f9fafb));color:var(--tbw-color-fg, #1f2937);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem)}.tbw-visibility-show-all:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}}';
315
- function f(b) {
314
+ const y = '@layer tbw-plugins{.tbw-visibility-content{display:flex;flex-direction:column;height:100%}.tbw-visibility-list{flex:1;overflow-y:auto;padding:var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem))}.tbw-visibility-row{display:flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));padding:var(--tbw-menu-item-padding, .375rem .25rem);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem);border-radius:var(--tbw-border-radius, .25rem);position:relative}.tbw-visibility-row:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover))}.tbw-visibility-row input[type=checkbox]{cursor:pointer}.tbw-visibility-row.locked span{color:var(--tbw-color-fg-muted)}.tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted);font-size:var(--tbw-font-size-2xs, .625rem);letter-spacing:-2px;-webkit-user-select:none;user-select:none;flex-shrink:0}.tbw-visibility-row.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg)}.tbw-visibility-label{display:flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));flex:1;cursor:pointer}.tbw-visibility-row.dragging{opacity:.5;cursor:grabbing}.tbw-visibility-row.drop-before:before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--tbw-visibility-indicator, var(--tbw-color-accent))}.tbw-visibility-row.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-visibility-indicator, var(--tbw-color-accent))}.tbw-visibility-show-all{margin:var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem));padding:var(--tbw-button-padding, .5rem .75rem);border:1px solid var(--tbw-visibility-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius, .25rem);background:var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg));color:var(--tbw-color-fg);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem)}.tbw-visibility-show-all:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover))}}';
315
+ function p(b) {
316
316
  const e = b.meta ?? {};
317
317
  return e.lockPosition !== !0 && e.suppressMovable !== !0;
318
318
  }
@@ -508,7 +508,7 @@ class g extends C {
508
508
  const r = this.grid.getAllColumns().filter((s) => !s.utility);
509
509
  for (let s = 0; s < r.length; s++) {
510
510
  const i = r[s], a = i.header || i.field, n = document.createElement("div");
511
- n.className = i.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", n.setAttribute("data-field", i.field), n.setAttribute("data-index", String(s)), t && f(i) && (n.draggable = !0, n.classList.add("reorderable"), this.setupDragListeners(n, i.field, s, e));
511
+ n.className = i.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", n.setAttribute("data-field", i.field), n.setAttribute("data-index", String(s)), t && p(i) && (n.draggable = !0, n.classList.add("reorderable"), this.setupDragListeners(n, i.field, s, e));
512
512
  const l = document.createElement("label");
513
513
  l.className = "tbw-visibility-label";
514
514
  const o = document.createElement("input");
@@ -516,7 +516,7 @@ class g extends C {
516
516
  this.grid.toggleColumnVisibility(i.field), setTimeout(() => this.rebuildToggles(e), 0);
517
517
  });
518
518
  const d = document.createElement("span");
519
- if (d.textContent = a, l.appendChild(o), l.appendChild(d), t && f(i)) {
519
+ if (d.textContent = a, l.appendChild(o), l.appendChild(d), t && p(i)) {
520
520
  const c = document.createElement("span");
521
521
  c.className = "tbw-visibility-handle", this.setIcon(c, this.resolveIcon("dragHandle")), c.title = "Drag to reorder", n.appendChild(c);
522
522
  }
@@ -547,13 +547,13 @@ class g extends C {
547
547
  return;
548
548
  const o = l > n ? l - 1 : l;
549
549
  if (o !== n) {
550
- const d = this.grid.getAllColumns(), h = d.filter((u) => !u.utility)[o]?.field, p = h ? d.findIndex((u) => u.field === h) : d.length, v = {
550
+ const d = this.grid.getAllColumns(), h = d.filter((u) => !u.utility)[o]?.field, v = h ? d.findIndex((u) => u.field === h) : d.length, f = {
551
551
  field: a,
552
552
  fromIndex: n,
553
553
  // Not used by ReorderPlugin, just for info
554
- toIndex: p
554
+ toIndex: v
555
555
  };
556
- this.emit("column-reorder-request", v), setTimeout(() => {
556
+ this.emit("column-reorder-request", f), setTimeout(() => {
557
557
  this.rebuildToggles(s);
558
558
  }, 0);
559
559
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolbox-web/grid",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "Zero-dependency, framework-agnostic data grid web component with virtualization, sorting, filtering, editing, and 20+ plugins. Works in vanilla JS, React, Vue, Angular, and any framework.",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -1,13 +1,13 @@
1
1
  /*
2
- * Bootstrap 5 Table Theme
3
- * Matches the look of Bootstrap's .table component
2
+ * Bootstrap 5 Theme
3
+ * Matches the look of Bootstrap 5's table component with enhanced interactions.
4
4
  * https://getbootstrap.com/docs/5.3/content/tables/
5
5
  */
6
6
  @layer tbw-theme {
7
7
  tbw-grid {
8
- /* Bootstrap surface colors */
8
+ /* ========== Core Palette ========== */
9
9
  --tbw-color-bg: light-dark(#ffffff, #212529);
10
- --tbw-color-panel-bg: light-dark(#ffffff, #212529);
10
+ --tbw-color-panel-bg: light-dark(#f8f9fa, #2b3035);
11
11
  --tbw-color-fg: light-dark(#212529, #dee2e6);
12
12
  --tbw-color-fg-muted: light-dark(#6c757d, #adb5bd);
13
13
 
@@ -23,51 +23,78 @@
23
23
  /* Bootstrap primary (blue) */
24
24
  --tbw-color-accent: light-dark(#0d6efd, #6ea8fe);
25
25
  --tbw-color-accent-fg: #ffffff;
26
+ --tbw-color-success: light-dark(#198754, #75b798);
27
+ --tbw-color-error: light-dark(#dc3545, #ea868f);
26
28
 
27
- /* Selection & interaction - Bootstrap's table-active */
28
- --tbw-color-selection: light-dark(rgba(0, 0, 0, 0.075), rgba(255, 255, 255, 0.075));
29
- --tbw-color-row-alt: light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.05)); /* Striped rows */
30
- --tbw-color-row-hover: light-dark(rgba(0, 0, 0, 0.075), rgba(255, 255, 255, 0.075));
31
- --tbw-color-active-row-bg: light-dark(rgba(13, 110, 253, 0.1), rgba(110, 168, 254, 0.15));
29
+ /* Selection & interaction */
30
+ --tbw-color-selection: light-dark(rgba(13, 110, 253, 0.1), rgba(110, 168, 254, 0.15));
31
+ --tbw-color-row-alt: light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.03));
32
+ --tbw-color-row-hover: light-dark(rgba(0, 0, 0, 0.075), rgba(255, 255, 255, 0.05));
33
+ --tbw-color-active-row-bg: light-dark(rgba(13, 110, 253, 0.12), rgba(110, 168, 254, 0.18));
32
34
 
33
- /* Header - slightly darker background */
35
+ /* Header */
34
36
  --tbw-color-header-bg: light-dark(#f8f9fa, #343a40);
35
37
  --tbw-color-header-fg: light-dark(#212529, #dee2e6);
38
+ --tbw-color-header-separator: light-dark(#adb5bd, #495057);
36
39
 
37
- /* No border radius - Bootstrap tables are rectangular */
38
- --tbw-border-radius: 0;
39
-
40
- /* Focus styling */
41
- --tbw-focus-outline: 3px solid light-dark(rgba(13, 110, 253, 0.25), rgba(110, 168, 254, 0.5));
42
- --tbw-focus-outline-offset: -3px;
43
- --tbw-resize-handle-color-hover: var(--tbw-color-accent);
40
+ /* Shadow for modals/panels */
41
+ --tbw-color-shadow: light-dark(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.3));
44
42
 
45
- /* Bootstrap typography */
43
+ /* ========== Typography ========== */
46
44
  --tbw-font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
47
45
  --tbw-font-size: 1rem;
48
46
  --tbw-font-size-header: 1rem;
49
- --tbw-font-weight-header: bold;
47
+ --tbw-font-weight-header: 600;
50
48
  --tbw-header-text-transform: none;
49
+ --tbw-header-letter-spacing: normal;
50
+
51
+ /* ========== Dimensions ========== */
52
+ --tbw-cell-padding: 8px 12px;
53
+ --tbw-cell-padding-header: 8px 12px;
54
+ --tbw-row-height: 44px;
55
+ --tbw-header-height: 48px;
56
+
57
+ /* Bootstrap uses rectangular tables */
58
+ --tbw-border-radius: 0.375rem;
59
+
60
+ /* ========== Motion ========== */
61
+ --tbw-transition-duration: 150ms;
62
+ --tbw-transition-ease: ease-in-out;
63
+ --tbw-animation-duration: 200ms;
64
+ --tbw-animation-easing: ease-in-out;
65
+
66
+ /* ========== Focus & Selection ========== */
67
+ /* Bootstrap's focus ring style */
68
+ --tbw-focus-outline: 0 0 0 0.25rem rgba(from var(--tbw-color-accent) r g b / 25%);
69
+ --tbw-focus-outline-offset: 0;
70
+ --tbw-focus-background: transparent;
51
71
 
52
- /* Bootstrap table padding */
53
- --tbw-cell-padding: 8px 8px;
54
- --tbw-cell-padding-header: 8px 8px;
55
- --tbw-row-height: 40px;
56
- --tbw-header-height: 44px;
72
+ --tbw-range-border-color: var(--tbw-color-accent);
73
+ --tbw-range-selection-bg: rgba(from var(--tbw-color-accent) r g b / 12%);
57
74
 
58
- /* Sort indicator */
75
+ /* ========== Resize Handle ========== */
76
+ --tbw-resize-handle-color: transparent;
77
+ --tbw-resize-handle-color-hover: var(--tbw-color-accent);
78
+
79
+ /* ========== Sort Indicators ========== */
59
80
  --tbw-sort-indicator-color: light-dark(#6c757d, #adb5bd);
60
81
  --tbw-sort-indicator-active-color: light-dark(#212529, #dee2e6);
61
82
 
62
- /* Header border - thicker bottom border like Bootstrap */
63
- --tbw-border-header: 2px solid light-dark(#212529, #dee2e6);
64
-
65
- /* Input styling */
83
+ /* ========== Borders ========== */
84
+ /* Bootstrap's thicker header bottom border */
85
+ --tbw-border-header: 2px solid light-dark(currentColor, #dee2e6);
66
86
  --tbw-border-input: 1px solid light-dark(#ced4da, #495057);
67
- --tbw-editing-bg: light-dark(#ffffff, #212529);
68
- --tbw-editing-border: 1px solid var(--tbw-color-accent);
87
+ --tbw-editing-border: 2px solid var(--tbw-color-accent);
69
88
 
70
- /* Success color for checkmarks etc */
71
- --tbw-color-success: light-dark(#198754, #75b798);
89
+ /* ========== Scrollbar ========== */
90
+ --tbw-scrollbar-thumb: light-dark(#adb5bd, #495057);
91
+ --tbw-scrollbar-track: transparent;
92
+
93
+ /* ========== Tool Panel ========== */
94
+ --tbw-tool-panel-bg: light-dark(#f8f9fa, #2b3035);
95
+ --tbw-shell-header-bg: light-dark(#f8f9fa, #343a40);
96
+
97
+ /* ========== Row Animations ========== */
98
+ --tbw-row-change-color: rgba(from var(--tbw-color-accent) r g b / 20%);
72
99
  }
73
100
  } /* End @layer tbw-theme */
@@ -1,71 +1,102 @@
1
1
  /*
2
- * Angular Material Table Theme
3
- * Matches the clean, minimal look of Angular Material's mat-table
4
- * https://material.angular.io/components/table/overview
2
+ * Material Design 3 Theme
3
+ * Inspired by Material Design 3 / Material You with modern polish.
4
+ * Clean surfaces, subtle elevation, smooth motion, and refined typography.
5
+ * https://m3.material.io/
5
6
  */
6
7
  @layer tbw-theme {
7
8
  tbw-grid {
8
- /* Clean white/dark surface - no tinting */
9
- --tbw-color-bg: light-dark(#ffffff, #272727);
10
- --tbw-color-panel-bg: light-dark(#ffffff, #272727);
11
- --tbw-color-fg: light-dark(rgba(0, 0, 0, 0.87), #ffffff);
12
- --tbw-color-fg-muted: light-dark(rgba(0, 0, 0, 0.54), rgba(255, 255, 255, 0.7));
13
-
14
- /* Minimal borders - only horizontal row dividers */
15
- --tbw-color-border: light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.12));
16
- --tbw-color-border-strong: light-dark(rgba(0, 0, 0, 0.42), rgba(255, 255, 255, 0.5));
17
- --tbw-color-border-cell: transparent; /* No vertical cell borders */
18
- --tbw-color-border-header: light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.12));
19
-
20
- /* Row divider - thin horizontal line only */
21
- --tbw-row-divider: 1px solid light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.12));
22
-
23
- /* Angular Material accent colors */
24
- --tbw-color-accent: light-dark(#3f51b5, #7986cb); /* Indigo primary */
25
- --tbw-color-accent-fg: #ffffff;
26
-
27
- /* Selection & interaction */
28
- --tbw-color-selection: light-dark(rgba(63, 81, 181, 0.08), rgba(121, 134, 203, 0.16));
29
- --tbw-color-row-alt: transparent; /* No zebra striping in Material */
30
- --tbw-color-row-hover: light-dark(rgba(0, 0, 0, 0.04), rgba(255, 255, 255, 0.04));
31
- --tbw-color-active-row-bg: light-dark(rgba(63, 81, 181, 0.08), rgba(121, 134, 203, 0.16));
32
-
33
- /* Header - same as body, no distinct background */
34
- --tbw-color-header-bg: light-dark(#ffffff, #272727);
35
- --tbw-color-header-fg: light-dark(rgba(0, 0, 0, 0.54), rgba(255, 255, 255, 0.7));
36
-
37
- /* No outer border or radius - clean rectangular look */
38
- --tbw-border-radius: 0;
39
-
40
- /* Focus styling */
41
- --tbw-focus-outline: 2px solid var(--tbw-color-accent);
42
- --tbw-focus-outline-offset: -2px;
43
- --tbw-resize-handle-color-hover: var(--tbw-color-accent);
9
+ /* ========== Core Palette ========== */
10
+ /* M3 surface colors with subtle tonal variation */
11
+ --tbw-color-bg: light-dark(#fffbff, #1c1b1f);
12
+ --tbw-color-panel-bg: light-dark(#f7f2fa, #2b2930);
13
+ --tbw-color-fg: light-dark(#1c1b1f, #e6e1e5);
14
+ --tbw-color-fg-muted: light-dark(#49454f, #cac4d0);
15
+
16
+ /* Subtle borders for clean look */
17
+ --tbw-color-border: light-dark(#e7e0ec, #49454f);
18
+ --tbw-color-border-strong: light-dark(#79747e, #938f99);
19
+ --tbw-color-border-cell: transparent;
20
+ --tbw-color-border-header: light-dark(#e7e0ec, #49454f);
21
+
22
+ /* Row divider - subtle horizontal line */
23
+ --tbw-row-divider: 1px solid light-dark(#e7e0ec, #49454f);
24
+
25
+ /* M3 Primary - Purple/Violet */
26
+ --tbw-color-accent: light-dark(#6750a4, #d0bcff);
27
+ --tbw-color-accent-fg: light-dark(#ffffff, #381e72);
28
+ --tbw-color-success: light-dark(#146c2e, #6dd58c);
29
+ --tbw-color-error: light-dark(#b3261e, #f2b8b5);
44
30
 
45
- /* Roboto typography - Material standard */
46
- --tbw-font-family: 'Roboto', 'Helvetica Neue', sans-serif;
31
+ /* Selection & interaction with tonal surfaces */
32
+ --tbw-color-selection: light-dark(#e8def8, #4a4458);
33
+ --tbw-color-row-alt: transparent;
34
+ --tbw-color-row-hover: light-dark(rgba(103, 80, 164, 0.08), rgba(208, 188, 255, 0.08));
35
+ --tbw-color-active-row-bg: light-dark(rgba(103, 80, 164, 0.12), rgba(208, 188, 255, 0.12));
36
+
37
+ /* Header with subtle surface tint */
38
+ --tbw-color-header-bg: light-dark(#fffbff, #1c1b1f);
39
+ --tbw-color-header-fg: light-dark(#49454f, #cac4d0);
40
+
41
+ /* Elevation shadow for panels */
42
+ --tbw-color-shadow: light-dark(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.3));
43
+
44
+ /* ========== Typography ========== */
45
+ --tbw-font-family: 'Roboto Flex', 'Roboto', system-ui, sans-serif;
47
46
  --tbw-font-size: 14px;
48
47
  --tbw-font-size-header: 12px;
49
48
  --tbw-font-weight-header: 500;
50
49
  --tbw-header-text-transform: none;
51
- --tbw-header-letter-spacing: normal;
50
+ --tbw-header-letter-spacing: 0.01em;
52
51
 
53
- /* Generous padding like Material tables */
52
+ /* ========== Spacing & Dimensions ========== */
53
+ /* M3 uses generous whitespace */
54
54
  --tbw-cell-padding: 4px 16px;
55
55
  --tbw-cell-padding-header: 4px 16px;
56
- --tbw-row-height: 48px;
56
+ --tbw-row-height: 52px;
57
57
  --tbw-header-height: 56px;
58
58
 
59
- /* Sort indicator styling */
60
- --tbw-sort-indicator-color: light-dark(rgba(0, 0, 0, 0.54), rgba(255, 255, 255, 0.7));
61
- --tbw-sort-indicator-active-color: light-dark(rgba(0, 0, 0, 0.87), #ffffff);
59
+ /* M3 uses larger corner radii */
60
+ --tbw-border-radius: 12px;
62
61
 
63
- /* Header border - only bottom */
64
- --tbw-border-header: 1px solid light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.12));
62
+ /* ========== Motion ========== */
63
+ /* M3 emphasizing motion - smooth, intentional transitions */
64
+ --tbw-transition-duration: 200ms;
65
+ --tbw-transition-ease: cubic-bezier(0.2, 0, 0, 1);
66
+ --tbw-animation-duration: 300ms;
67
+ --tbw-animation-easing: cubic-bezier(0.2, 0, 0, 1);
65
68
 
66
- /* Input styling for editing */
67
- --tbw-border-input: 1px solid light-dark(rgba(0, 0, 0, 0.42), rgba(255, 255, 255, 0.5));
68
- --tbw-editing-bg: transparent;
69
+ /* ========== Focus & Selection ========== */
70
+ --tbw-focus-outline: 2px solid var(--tbw-color-accent);
71
+ --tbw-focus-outline-offset: 2px;
72
+ --tbw-focus-background: rgba(from var(--tbw-color-accent) r g b / 12%);
73
+
74
+ --tbw-range-border-color: var(--tbw-color-accent);
75
+ --tbw-range-selection-bg: rgba(from var(--tbw-color-accent) r g b / 12%);
76
+
77
+ /* ========== Resize Handle ========== */
78
+ --tbw-resize-handle-color: transparent;
79
+ --tbw-resize-handle-color-hover: var(--tbw-color-accent);
80
+ --tbw-resize-handle-border-radius: 4px;
81
+
82
+ /* ========== Sort Indicators ========== */
83
+ --tbw-sort-indicator-color: light-dark(#49454f, #cac4d0);
84
+ --tbw-sort-indicator-active-color: var(--tbw-color-accent);
85
+
86
+ /* ========== Borders ========== */
87
+ --tbw-border-header: 1px solid light-dark(#e7e0ec, #49454f);
88
+ --tbw-border-input: 1px solid light-dark(#79747e, #938f99);
69
89
  --tbw-editing-border: 2px solid var(--tbw-color-accent);
90
+
91
+ /* ========== Scrollbar ========== */
92
+ --tbw-scrollbar-thumb: light-dark(#d0d0d8, #49454f);
93
+ --tbw-scrollbar-track: transparent;
94
+
95
+ /* ========== Tool Panel ========== */
96
+ --tbw-tool-panel-bg: light-dark(#f7f2fa, #2b2930);
97
+ --tbw-shell-header-bg: light-dark(#fffbff, #1c1b1f);
98
+
99
+ /* ========== Row Animations ========== */
100
+ --tbw-row-change-color: rgba(from var(--tbw-color-accent) r g b / 20%);
70
101
  }
71
102
  } /* End @layer tbw-theme */
@@ -1,20 +1,88 @@
1
- /* Standard balanced theme with light-dark() adaptive palette */
1
+ /*
2
+ * Standard Theme
3
+ * A polished, balanced theme suitable for most applications.
4
+ * Clean lines, subtle depth, and professional aesthetics.
5
+ */
2
6
  @layer tbw-theme {
3
7
  tbw-grid {
4
- --tbw-color-bg: light-dark(#ffffff, #1f2125);
5
- --tbw-color-fg: light-dark(#1f2329, #e5e7eb);
6
- --tbw-color-fg-muted: light-dark(#586069, #9ca3af);
7
- --tbw-color-border: light-dark(#d0d4d9, #3a3d44);
8
- --tbw-color-border-strong: light-dark(#888d94, #5a5f66);
8
+ /* ========== Core Palette ========== */
9
+ --tbw-color-bg: light-dark(#ffffff, #1a1c20);
10
+ --tbw-color-panel-bg: light-dark(#f8f9fa, #232528);
11
+ --tbw-color-fg: light-dark(#1f2937, #e5e7eb);
12
+ --tbw-color-fg-muted: light-dark(#6b7280, #9ca3af);
13
+
14
+ /* Refined borders */
15
+ --tbw-color-border: light-dark(#e5e7eb, #374151);
16
+ --tbw-color-border-strong: light-dark(#9ca3af, #6b7280);
17
+ --tbw-color-border-cell: light-dark(#f3f4f6, #2d3138);
18
+ --tbw-color-border-header: light-dark(#d1d5db, #3f4550);
19
+
20
+ /* Row divider */
21
+ --tbw-row-divider: 1px solid light-dark(#e5e7eb, #2d3138);
22
+
23
+ /* Modern blue accent */
9
24
  --tbw-color-accent: light-dark(#2563eb, #3b82f6);
10
25
  --tbw-color-accent-fg: #ffffff;
11
- --tbw-color-selection: light-dark(#fff7d6, #374151);
12
- --tbw-color-row-alt: light-dark(#f8f9fa, #252830);
13
- --tbw-color-row-hover: light-dark(#eef6ff, #2d313b);
14
- --tbw-color-header-bg: light-dark(#f5f6f8, #262a30);
15
- --tbw-color-border-cell: light-dark(#eee, #333);
16
- --tbw-color-border-header: light-dark(#ccc, #444);
26
+ --tbw-color-success: light-dark(#059669, #34d399);
27
+ --tbw-color-error: light-dark(#dc2626, #f87171);
28
+
29
+ /* Selection & interaction */
30
+ --tbw-color-selection: light-dark(#eff6ff, #1e3a5f);
31
+ --tbw-color-row-alt: light-dark(#f9fafb, #1f2225);
32
+ --tbw-color-row-hover: light-dark(#f0f7ff, #252a32);
33
+ --tbw-color-active-row-bg: light-dark(#dbeafe, #1e3a5f);
34
+
35
+ /* Header with subtle distinction */
36
+ --tbw-color-header-bg: light-dark(#f8fafc, #21242a);
37
+ --tbw-color-header-fg: light-dark(#374151, #d1d5db);
38
+ --tbw-color-header-separator: light-dark(#d1d5db, #3f4550);
39
+
40
+ /* Subtle shadow for depth */
41
+ --tbw-color-shadow: light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.25));
42
+
43
+ /* ========== Typography ========== */
44
+ --tbw-font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
45
+ --tbw-font-weight-header: 600;
46
+ --tbw-header-text-transform: none;
47
+ --tbw-header-letter-spacing: -0.01em;
48
+
49
+ /* ========== Visual Polish ========== */
50
+ --tbw-border-radius: 0.375em;
51
+
52
+ /* Smooth transitions */
53
+ --tbw-transition-duration: 150ms;
54
+ --tbw-transition-ease: cubic-bezier(0.4, 0, 0.2, 1);
55
+ --tbw-animation-duration: 200ms;
56
+ --tbw-animation-easing: ease-out;
57
+
58
+ /* ========== Focus & Selection ========== */
59
+ --tbw-focus-outline: 2px solid var(--tbw-color-accent);
60
+ --tbw-focus-outline-offset: -2px;
61
+ --tbw-focus-background: rgba(from var(--tbw-color-accent) r g b / 8%);
62
+
63
+ --tbw-range-border-color: var(--tbw-color-accent);
64
+ --tbw-range-selection-bg: rgba(from var(--tbw-color-accent) r g b / 10%);
65
+
66
+ /* ========== Resize Handle ========== */
67
+ --tbw-resize-handle-color: transparent;
17
68
  --tbw-resize-handle-color-hover: var(--tbw-color-accent);
69
+
70
+ /* ========== Sort Indicators ========== */
71
+ --tbw-sort-indicator-color: var(--tbw-color-fg-muted);
72
+ --tbw-sort-indicator-active-color: var(--tbw-color-accent);
73
+
74
+ /* ========== Scrollbar ========== */
75
+ --tbw-scrollbar-thumb: light-dark(#c5c8ce, #4b5058);
76
+ --tbw-scrollbar-track: transparent;
77
+
78
+ /* ========== Tool Panel ========== */
79
+ --tbw-tool-panel-bg: light-dark(#f8f9fa, #232528);
80
+ --tbw-shell-header-bg: light-dark(#f8fafc, #21242a);
81
+
82
+ /* ========== Column Header Groups ========== */
18
83
  --tbw-align-header-group: center;
84
+
85
+ /* ========== Row Animations ========== */
86
+ --tbw-row-change-color: rgba(from var(--tbw-color-accent) r g b / 20%);
19
87
  }
20
88
  } /* End @layer tbw-theme */
@@ -1,17 +1,86 @@
1
- /* Vibrant colorful theme (keeps good contrast) */
1
+ /*
2
+ * Vibrant Theme
3
+ * A bold, colorful theme with rich purples and smooth interactions.
4
+ * Features subtle gradients, glowing accents, and polished transitions.
5
+ */
2
6
  @layer tbw-theme {
3
7
  tbw-grid {
4
- --tbw-color-bg: light-dark(#fcfcff, #1a1c24);
8
+ /* ========== Core Palette ========== */
9
+ --tbw-color-bg: light-dark(#fafaff, #12141c);
10
+ --tbw-color-panel-bg: light-dark(#f0f0ff, #1a1d28);
5
11
  --tbw-color-fg: light-dark(#1e2430, #f1f5f9);
6
12
  --tbw-color-fg-muted: light-dark(#5d6473, #9ba4b4);
7
- --tbw-color-border: light-dark(#d6daf2, #3a4153);
8
- --tbw-color-border-strong: light-dark(#8a93b5, #596380);
9
- --tbw-color-accent: light-dark(#6366f1, #818cf8);
13
+ --tbw-color-border: light-dark(#ddddf8, #2e3344);
14
+ --tbw-color-border-strong: light-dark(#9093c5, #505878);
15
+ --tbw-color-border-cell: light-dark(#e8e8f8, #252838);
16
+ --tbw-color-border-header: light-dark(#d0d0ec, #3a3f55);
17
+
18
+ /* Vibrant purple accent with glow potential */
19
+ --tbw-color-accent: light-dark(#7c3aed, #a78bfa);
10
20
  --tbw-color-accent-fg: #ffffff;
11
- --tbw-color-selection: light-dark(#edeaff, #374062);
12
- --tbw-color-row-alt: light-dark(#f4f3ff, #232a3a);
13
- --tbw-color-row-hover: light-dark(#eef2ff, #2b3447);
14
- --tbw-color-header-bg: light-dark(#eff1ff, #242b3b);
21
+ --tbw-color-success: light-dark(#059669, #34d399);
22
+ --tbw-color-error: light-dark(#dc2626, #f87171);
23
+
24
+ /* Selection & interaction - subtle purple tint */
25
+ --tbw-color-selection: light-dark(#ede9fe, #312e5a);
26
+ --tbw-color-row-alt: light-dark(#f8f7ff, #1e2130);
27
+ --tbw-color-row-hover: light-dark(#f0edff, #262a40);
28
+ --tbw-color-active-row-bg: light-dark(#e9e4ff, #352f5c);
29
+
30
+ /* Header with subtle gradient feel */
31
+ --tbw-color-header-bg: light-dark(#f5f3ff, #1f2235);
32
+ --tbw-color-header-fg: light-dark(#3730a3, #c4b5fd);
33
+ --tbw-color-header-separator: light-dark(#c7c3f0, #3d4260);
34
+
35
+ /* Enhanced shadows for depth */
36
+ --tbw-color-shadow: light-dark(rgba(124, 58, 237, 0.12), rgba(0, 0, 0, 0.4));
37
+
38
+ /* ========== Typography ========== */
39
+ --tbw-font-family: 'Inter', system-ui, -apple-system, sans-serif;
40
+ --tbw-font-weight-header: 600;
41
+ --tbw-header-text-transform: none;
42
+ --tbw-header-letter-spacing: -0.01em;
43
+
44
+ /* ========== Visual Polish ========== */
45
+ --tbw-border-radius: 0.5em;
46
+
47
+ /* Smooth, refined transitions */
48
+ --tbw-transition-duration: 150ms;
49
+ --tbw-transition-ease: cubic-bezier(0.4, 0, 0.2, 1);
50
+ --tbw-animation-duration: 250ms;
51
+ --tbw-animation-easing: cubic-bezier(0.4, 0, 0.2, 1);
52
+
53
+ /* ========== Focus & Selection Styling ========== */
54
+ --tbw-focus-outline: 2px solid var(--tbw-color-accent);
55
+ --tbw-focus-outline-offset: -2px;
56
+ --tbw-focus-background: rgba(from var(--tbw-color-accent) r g b / 10%);
57
+
58
+ /* Range selection with accent glow */
59
+ --tbw-range-border-color: var(--tbw-color-accent);
60
+ --tbw-range-selection-bg: rgba(from var(--tbw-color-accent) r g b / 15%);
61
+
62
+ /* Subtle hover outline for rows */
63
+ --tbw-row-hover-outline: 1px solid rgba(from var(--tbw-color-accent) r g b / 20%);
64
+ --tbw-active-row-outline: 2px solid rgba(from var(--tbw-color-accent) r g b / 40%);
65
+
66
+ /* ========== Resize Handle ========== */
67
+ --tbw-resize-handle-color: transparent;
15
68
  --tbw-resize-handle-color-hover: var(--tbw-color-accent);
69
+ --tbw-resize-handle-border-radius: 2px;
70
+ --tbw-resize-indicator-color: var(--tbw-color-accent);
71
+
72
+ /* ========== Sorting Indicators ========== */
73
+ --tbw-sort-indicator-color: light-dark(#a5a8c8, #6b7094);
74
+ --tbw-sort-indicator-active-color: var(--tbw-color-accent);
75
+
76
+ /* ========== Scrollbar ========== */
77
+ --tbw-scrollbar-thumb: light-dark(#c4c3e8, #3d4260);
78
+ --tbw-scrollbar-track: var(--tbw-color-bg);
79
+
80
+ /* ========== Tool Panel ========== */
81
+ --tbw-tool-panel-bg: light-dark(#f8f7ff, #181a24);
82
+
83
+ /* ========== Row Animations ========== */
84
+ --tbw-row-change-color: rgba(from var(--tbw-color-accent) r g b / 30%);
16
85
  }
17
86
  } /* End @layer tbw-theme */