@toolbox-web/grid 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.
Files changed (75) hide show
  1. package/all.js +694 -525
  2. package/all.js.map +1 -1
  3. package/index.js +1468 -1449
  4. package/index.js.map +1 -1
  5. package/lib/core/grid.d.ts +2 -1
  6. package/lib/core/grid.d.ts.map +1 -1
  7. package/lib/core/internal/sanitize.d.ts.map +1 -1
  8. package/lib/core/internal/validate-config.d.ts.map +1 -1
  9. package/lib/core/types.d.ts +9 -1
  10. package/lib/core/types.d.ts.map +1 -1
  11. package/lib/plugins/clipboard/index.js.map +1 -1
  12. package/lib/plugins/column-virtualization/index.js.map +1 -1
  13. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
  14. package/lib/plugins/context-menu/index.js +1 -1
  15. package/lib/plugins/context-menu/index.js.map +1 -1
  16. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  17. package/lib/plugins/editing/editors.d.ts.map +1 -1
  18. package/lib/plugins/editing/index.d.ts +1 -1
  19. package/lib/plugins/editing/index.d.ts.map +1 -1
  20. package/lib/plugins/editing/index.js +187 -170
  21. package/lib/plugins/editing/index.js.map +1 -1
  22. package/lib/plugins/editing/types.d.ts +44 -0
  23. package/lib/plugins/editing/types.d.ts.map +1 -1
  24. package/lib/plugins/export/index.js.map +1 -1
  25. package/lib/plugins/filtering/index.js +9 -9
  26. package/lib/plugins/filtering/index.js.map +1 -1
  27. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +8 -1
  28. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
  29. package/lib/plugins/grouping-columns/index.js +59 -60
  30. package/lib/plugins/grouping-columns/index.js.map +1 -1
  31. package/lib/plugins/grouping-rows/index.js.map +1 -1
  32. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +7 -0
  33. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
  34. package/lib/plugins/master-detail/index.js +185 -145
  35. package/lib/plugins/master-detail/index.js.map +1 -1
  36. package/lib/plugins/multi-sort/index.js.map +1 -1
  37. package/lib/plugins/pinned-columns/index.js.map +1 -1
  38. package/lib/plugins/pinned-rows/index.js.map +1 -1
  39. package/lib/plugins/pivot/index.js.map +1 -1
  40. package/lib/plugins/print/index.js.map +1 -1
  41. package/lib/plugins/reorder/index.js.map +1 -1
  42. package/lib/plugins/responsive/index.js +40 -39
  43. package/lib/plugins/responsive/index.js.map +1 -1
  44. package/lib/plugins/row-reorder/index.js.map +1 -1
  45. package/lib/plugins/selection/SelectionPlugin.d.ts +51 -0
  46. package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
  47. package/lib/plugins/selection/index.js +325 -131
  48. package/lib/plugins/selection/index.js.map +1 -1
  49. package/lib/plugins/selection/types.d.ts +18 -0
  50. package/lib/plugins/selection/types.d.ts.map +1 -1
  51. package/lib/plugins/server-side/index.js.map +1 -1
  52. package/lib/plugins/tree/index.js.map +1 -1
  53. package/lib/plugins/undo-redo/index.js.map +1 -1
  54. package/lib/plugins/visibility/index.js.map +1 -1
  55. package/package.json +1 -1
  56. package/public.d.ts +2 -0
  57. package/public.d.ts.map +1 -1
  58. package/themes/dg-theme-bootstrap.css +192 -8
  59. package/themes/dg-theme-material.css +243 -0
  60. package/umd/grid.all.umd.js +43 -43
  61. package/umd/grid.all.umd.js.map +1 -1
  62. package/umd/grid.umd.js +19 -19
  63. package/umd/grid.umd.js.map +1 -1
  64. package/umd/plugins/context-menu.umd.js +1 -1
  65. package/umd/plugins/context-menu.umd.js.map +1 -1
  66. package/umd/plugins/editing.umd.js +1 -1
  67. package/umd/plugins/editing.umd.js.map +1 -1
  68. package/umd/plugins/filtering.umd.js +1 -1
  69. package/umd/plugins/filtering.umd.js.map +1 -1
  70. package/umd/plugins/grouping-columns.umd.js +1 -1
  71. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  72. package/umd/plugins/master-detail.umd.js +1 -1
  73. package/umd/plugins/master-detail.umd.js.map +1 -1
  74. package/umd/plugins/selection.umd.js +2 -2
  75. package/umd/plugins/selection.umd.js.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolbox-web/grid",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
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",
package/public.d.ts CHANGED
@@ -96,6 +96,8 @@ export declare const DGEvents: {
96
96
  readonly CELL_CHANGE: "cell-change";
97
97
  readonly CELL_COMMIT: "cell-commit";
98
98
  readonly ROW_COMMIT: "row-commit";
99
+ readonly EDIT_OPEN: "edit-open";
100
+ readonly EDIT_CLOSE: "edit-close";
99
101
  readonly CHANGED_ROWS_RESET: "changed-rows-reset";
100
102
  readonly MOUNT_EXTERNAL_VIEW: "mount-external-view";
101
103
  readonly MOUNT_EXTERNAL_EDITOR: "mount-external-editor";
package/public.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../libs/grid/src/public.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../libs/grid/src/public.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,eAAe,EAAE,eAAe,IAAI,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAElF;;;;;;;;;;;GAWG;AACH,YAAY,EAAE,eAAe,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAG,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAMpG;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAG,OAAO,EACtC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,UAAqB,GAC5B,eAAe,CAAC,IAAI,CAAC,GAAG,IAAI,CAE9B;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,QAAQ;IACnB,8CAA8C;;;;;;;;;;;;IAY9C,0DAA0D;;;;CAIlD,CAAC;AAEX;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;CA+Bf,CAAC;AAEX;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAG/E,YAAY;AACV,iDAAiD;AACjD,kBAAkB,EAClB,aAAa,EAEb,eAAe,EACf,aAAa,EACb,cAAc,EACd,gBAAgB,EAEhB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,mBAAmB,EAEnB,gBAAgB,EAChB,kBAAkB,EAElB,eAAe,EACf,WAAW,EAEX,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,IAAI,wBAAwB,EAC3C,gBAAgB,EAChB,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,OAAO,EAEP,gBAAgB,EAChB,eAAe,EAEf,UAAU,EAEV,SAAS,EAET,UAAU,EAEV,iBAAiB,EAEjB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,SAAS,EAET,oBAAoB,EAEpB,cAAc,EACd,eAAe,EACf,WAAW,EACX,mBAAmB,EAEnB,UAAU,EAEV,gBAAgB,EAChB,cAAc,EAEd,oBAAoB,EAEpB,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAEhB,WAAW,EACX,SAAS,EACT,wBAAwB,EACxB,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,YAAY,GACb,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG7F,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAK7E,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnE,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC9F,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAUpF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;GAKG;AACH,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;GAIG;AACH,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;;;GAKG;AACH,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;GAIG;AACH,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;GAIG;AACH,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;GAIG;AACH,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;GAIG;AACH,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD;;;;GAIG;AACH,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;GAKG;AACH,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;;;GAKG;AACH,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,OAAO,IAAI,OAAO,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AAErF;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC"}
@@ -49,10 +49,11 @@
49
49
  --tbw-header-letter-spacing: normal;
50
50
 
51
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;
52
+ /* Bootstrap .table uses 0.5rem cell padding */
53
+ --tbw-cell-padding: 0.5rem 0.75rem;
54
+ --tbw-cell-padding-header: 0.5rem 0.75rem;
55
+ --tbw-row-height: 37px;
56
+ --tbw-header-height: 41px;
56
57
 
57
58
  /* Bootstrap uses rectangular tables */
58
59
  --tbw-border-radius: 0.375rem;
@@ -64,10 +65,10 @@
64
65
  --tbw-animation-easing: ease-in-out;
65
66
 
66
67
  /* ========== 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;
68
+ /* Bootstrap's focus ring style (outline syntax, not box-shadow) */
69
+ --tbw-focus-outline: 3px solid rgba(from var(--tbw-color-accent) r g b / 40%);
70
+ --tbw-focus-outline-offset: -3px;
71
+ --tbw-focus-background: light-dark(rgba(13, 110, 253, 0.08), rgba(110, 168, 254, 0.12));
71
72
 
72
73
  --tbw-range-border-color: var(--tbw-color-accent);
73
74
  --tbw-range-selection-bg: rgba(from var(--tbw-color-accent) r g b / 12%);
@@ -96,5 +97,188 @@
96
97
 
97
98
  /* ========== Row Animations ========== */
98
99
  --tbw-row-change-color: rgba(from var(--tbw-color-accent) r g b / 20%);
100
+
101
+ /* ========== Header Icons ========== */
102
+ /* Scale icons to match Bootstrap's 1rem base font */
103
+ .header-row .cell > span[part~='sort-indicator'] {
104
+ font-size: 14px;
105
+ }
106
+
107
+ .header-row .cell .tbw-filter-btn {
108
+ font-size: 14px;
109
+
110
+ > * {
111
+ width: 1em;
112
+ height: 1em;
113
+ }
114
+ }
115
+
116
+ /* ========== Bootstrap 5 Form Inputs ========== */
117
+ /* Standard Bootstrap form-control styling for editing cells */
118
+ .data-grid-row > .cell.editing input:not([type='checkbox']),
119
+ .data-grid-row > .cell.editing select,
120
+ .data-grid-row > .cell.editing textarea {
121
+ background: var(--tbw-color-bg);
122
+ color: var(--tbw-color-fg);
123
+ border: 1px solid light-dark(#ced4da, #495057);
124
+ border-radius: 0.375rem;
125
+ padding: 0.375rem 0.75rem;
126
+ font-family: var(--tbw-font-family);
127
+ font-size: var(--tbw-font-size);
128
+ outline: none;
129
+ transition:
130
+ border-color 0.15s ease-in-out,
131
+ box-shadow 0.15s ease-in-out;
132
+
133
+ &:focus {
134
+ border-color: light-dark(#86b7fe, #6ea8fe);
135
+ box-shadow: 0 0 0 0.25rem rgba(from var(--tbw-color-accent) r g b / 25%);
136
+ }
137
+ }
138
+
139
+ /* Bootstrap select caret */
140
+ .data-grid-row > .cell.editing select {
141
+ appearance: none;
142
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
143
+ background-repeat: no-repeat;
144
+ background-position: right 0.75rem center;
145
+ background-size: 16px 12px;
146
+ padding-right: 2.25rem;
147
+ }
148
+ }
149
+
150
+ tbw-grid,
151
+ .tbw-filter-panel {
152
+ /* ========== Bootstrap 5 Checkboxes ========== */
153
+ /* Matches Bootstrap's .form-check-input styling */
154
+ input[type='checkbox'] {
155
+ appearance: none;
156
+ -webkit-appearance: none;
157
+ width: 1.125em;
158
+ height: 1.125em;
159
+ border: 1px solid light-dark(#dee2e6, #495057);
160
+ border-radius: 0.25em;
161
+ background-color: light-dark(#ffffff, #212529);
162
+ background-repeat: no-repeat;
163
+ background-position: center;
164
+ background-size: contain;
165
+ cursor: pointer;
166
+ outline: none;
167
+ vertical-align: middle;
168
+ flex-shrink: 0;
169
+ transition:
170
+ background-color 0.15s ease-in-out,
171
+ border-color 0.15s ease-in-out,
172
+ box-shadow 0.15s ease-in-out;
173
+
174
+ &:checked {
175
+ background-color: var(--tbw-color-accent);
176
+ border-color: var(--tbw-color-accent);
177
+ /* Bootstrap SVG checkmark */
178
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E");
179
+ }
180
+
181
+ &:indeterminate {
182
+ background-color: var(--tbw-color-accent);
183
+ border-color: var(--tbw-color-accent);
184
+ /* Bootstrap SVG dash */
185
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3E%3C/svg%3E");
186
+ }
187
+
188
+ &:focus {
189
+ border-color: light-dark(#86b7fe, #6ea8fe);
190
+ box-shadow: 0 0 0 0.25rem rgba(from var(--tbw-color-accent) r g b / 25%);
191
+ }
192
+ }
193
+
194
+ /* ========== Bootstrap 5 Buttons ========== */
195
+ /* Standard Bootstrap .btn base styling */
196
+ button {
197
+ border-radius: 0.375rem;
198
+ font-weight: 400;
199
+ letter-spacing: normal;
200
+ transition:
201
+ color 0.15s ease-in-out,
202
+ background-color 0.15s ease-in-out,
203
+ border-color 0.15s ease-in-out,
204
+ box-shadow 0.15s ease-in-out;
205
+
206
+ &:focus-visible {
207
+ box-shadow: 0 0 0 0.25rem rgba(from var(--tbw-color-accent) r g b / 50%);
208
+ }
209
+ }
210
+ }
211
+
212
+ .tbw-filter-panel {
213
+ /* Provide --tbw-* values for filter panel (rendered outside tbw-grid) */
214
+ --tbw-color-accent: light-dark(#0d6efd, #6ea8fe);
215
+ --tbw-color-bg: light-dark(#ffffff, #212529);
216
+ --tbw-color-fg: light-dark(#212529, #dee2e6);
217
+ --tbw-color-border: light-dark(#dee2e6, #495057);
218
+ --tbw-color-border-strong: light-dark(#adb5bd, #6c757d);
219
+ --tbw-color-panel-bg: light-dark(#f8f9fa, #2b3035);
220
+ --tbw-color-row-hover: light-dark(rgba(0, 0, 0, 0.075), rgba(255, 255, 255, 0.05));
221
+ --tbw-filter-item-height: 32px;
222
+
223
+ /* Bootstrap card-like panel */
224
+ border-radius: 0.375rem;
225
+ font-family:
226
+ system-ui,
227
+ -apple-system,
228
+ 'Segoe UI',
229
+ Roboto,
230
+ 'Helvetica Neue',
231
+ Arial,
232
+ sans-serif;
233
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
234
+
235
+ /* Bootstrap form-control inputs */
236
+ .tbw-filter-search-input,
237
+ .tbw-filter-range-input,
238
+ .tbw-filter-date-input {
239
+ background: var(--tbw-color-bg);
240
+ border: 1px solid var(--tbw-color-border);
241
+ border-radius: 0.375rem;
242
+ height: 32px;
243
+ padding: 0.25rem 0.5rem;
244
+ font-family: inherit;
245
+ font-size: 0.875rem;
246
+ transition:
247
+ border-color 0.15s ease-in-out,
248
+ box-shadow 0.15s ease-in-out;
249
+
250
+ &:focus {
251
+ border-color: light-dark(#86b7fe, #6ea8fe);
252
+ box-shadow: 0 0 0 0.25rem rgba(from var(--tbw-color-accent) r g b / 25%);
253
+ }
254
+ }
255
+
256
+ /* Value items with Bootstrap hover */
257
+ .tbw-filter-value-item {
258
+ border-radius: 0.25rem;
259
+ transition: background 0.15s ease-in-out;
260
+
261
+ &:hover {
262
+ background: var(--tbw-color-row-hover);
263
+ }
264
+ }
265
+
266
+ /* Bootstrap primary button (Apply) */
267
+ .tbw-filter-apply-btn {
268
+ &:hover {
269
+ filter: brightness(0.9);
270
+ }
271
+ }
272
+
273
+ /* Bootstrap outline button (Clear) */
274
+ .tbw-filter-clear-btn {
275
+ color: var(--tbw-color-accent);
276
+ border-color: var(--tbw-color-accent);
277
+
278
+ &:hover {
279
+ color: #fff;
280
+ background: var(--tbw-color-accent);
281
+ }
282
+ }
99
283
  }
100
284
  } /* End @layer tbw-theme */
@@ -98,5 +98,248 @@
98
98
 
99
99
  /* ========== Row Animations ========== */
100
100
  --tbw-row-change-color: rgba(from var(--tbw-color-accent) r g b / 20%);
101
+
102
+ /* ========== M3 Header Icons ========== */
103
+ /* M3 uses larger, bolder icons (18px vs default 12px) */
104
+ --tbw-icon-size: 18px;
105
+ --tbw-icon-size-sm: 16px;
106
+
107
+ /* Sort indicator — larger for M3, works with any icon type */
108
+ .header-row .cell > span[part~='sort-indicator'] {
109
+ font-size: var(--tbw-icon-size-sm);
110
+
111
+ > * {
112
+ width: 1em;
113
+ height: 1em;
114
+ }
115
+ }
116
+
117
+ /* Filter button — larger for M3, works with any icon type */
118
+ .header-row .cell .tbw-filter-btn {
119
+ font-size: var(--tbw-icon-size-sm);
120
+
121
+ > * {
122
+ width: 1em;
123
+ height: 1em;
124
+ }
125
+ }
126
+
127
+ /* ========== M3 Filled Text Fields ========== */
128
+ /* Material Design 3 filled text field: tinted background, bottom border, accent on focus */
129
+ .data-grid-row > .cell.editing input:not([type='checkbox']),
130
+ .data-grid-row > .cell.editing select,
131
+ .data-grid-row > .cell.editing textarea {
132
+ background: var(--tbw-color-panel-bg);
133
+ color: var(--tbw-color-fg);
134
+ border: none;
135
+ border-bottom: 1px solid var(--tbw-color-border-strong);
136
+ border-radius: 4px 4px 0 0;
137
+ padding: 8px 12px;
138
+ font-family: var(--tbw-font-family);
139
+ font-size: var(--tbw-font-size);
140
+ caret-color: var(--tbw-color-accent);
141
+ outline: none;
142
+ transition: border-color 150ms var(--tbw-transition-ease);
143
+
144
+ &:focus {
145
+ border-bottom: 2px solid var(--tbw-color-accent);
146
+ padding-bottom: 7px; /* compensate for thicker border */
147
+ }
148
+ }
149
+
150
+ /* M3 select dropdown caret */
151
+ .data-grid-row > .cell.editing select {
152
+ appearance: none;
153
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2379747e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
154
+ background-repeat: no-repeat;
155
+ background-position: right 10px center;
156
+ padding-right: 28px;
157
+ }
158
+
159
+ /* ========== M3 Editing border override ========== */
160
+ --tbw-editing-border: none;
161
+ --tbw-editing-row-outline-width: 2px;
162
+ }
163
+
164
+ tbw-grid,
165
+ .tbw-filter-panel {
166
+ /* ========== M3 Checkboxes ========== */
167
+ /* Material Design 3 styled checkboxes for all grid & filter panel checkboxes */
168
+ input[type='checkbox'] {
169
+ appearance: none;
170
+ -webkit-appearance: none;
171
+ width: 18px;
172
+ height: 18px;
173
+ border: 2px solid var(--tbw-color-border-strong);
174
+ border-radius: 2px;
175
+ background: transparent;
176
+ position: relative;
177
+ transition:
178
+ background-color 100ms cubic-bezier(0.2, 0, 0, 1),
179
+ border-color 100ms cubic-bezier(0.2, 0, 0, 1);
180
+ cursor: pointer;
181
+ outline: none;
182
+ vertical-align: middle;
183
+ flex-shrink: 0;
184
+
185
+ &::after {
186
+ content: '';
187
+ position: absolute;
188
+ display: none;
189
+ left: 4px;
190
+ top: 0;
191
+ width: 5px;
192
+ height: 10px;
193
+ border: solid var(--tbw-color-accent-fg);
194
+ border-width: 0 2px 2px 0;
195
+ transform: rotate(45deg);
196
+ }
197
+
198
+ &:checked {
199
+ background-color: var(--tbw-color-accent);
200
+ border-color: var(--tbw-color-accent);
201
+
202
+ &::after {
203
+ display: block;
204
+ }
205
+ }
206
+
207
+ &:indeterminate {
208
+ background-color: var(--tbw-color-accent);
209
+ border-color: var(--tbw-color-accent);
210
+
211
+ &::after {
212
+ display: block;
213
+ left: 3px;
214
+ top: 6px;
215
+ width: 8px;
216
+ height: 0;
217
+ border-width: 0 0 2px 0;
218
+ transform: none;
219
+ }
220
+ }
221
+
222
+ &:hover::before {
223
+ content: '';
224
+ position: absolute;
225
+ inset: -10px;
226
+ border-radius: 50%;
227
+ background: rgba(from var(--tbw-color-accent) r g b / 8%);
228
+ }
229
+
230
+ &:focus-visible::before {
231
+ content: '';
232
+ position: absolute;
233
+ inset: -10px;
234
+ border-radius: 50%;
235
+ background: rgba(from var(--tbw-color-accent) r g b / 12%);
236
+ }
237
+ }
238
+
239
+ /* ========== M3 Checkboxes ========== */
240
+ /* Material Design 3 buttons */
241
+ button {
242
+ font-weight: 500;
243
+ letter-spacing: 0.01em;
244
+ min-height: 36px;
245
+ border-radius: 20px;
246
+ transition:
247
+ filter 150ms var(--tbw-transition-ease),
248
+ box-shadow 150ms var(--tbw-transition-ease);
249
+ }
250
+ }
251
+
252
+ .tbw-filter-panel {
253
+ /* Provide --tbw-* values for filter panel (rendered outside tbw-grid) */
254
+ --tbw-color-accent: light-dark(#6750a4, #d0bcff);
255
+ --tbw-color-accent-fg: light-dark(#fff, #381e72);
256
+ --tbw-color-border-strong: light-dark(#79747e, #938f99);
257
+ --tbw-color-panel-bg: light-dark(#f7f2fa, #2b2930);
258
+ --tbw-color-row-hover: light-dark(rgba(103, 80, 164, 0.08), rgba(208, 188, 255, 0.08));
259
+ --tbw-transition-ease: cubic-bezier(0.2, 0, 0, 1);
260
+ --tbw-filter-item-height: 36px;
261
+
262
+ /* M3 surface container with tonal elevation */
263
+ border-radius: 12px;
264
+ font-family: 'Roboto Flex', 'Roboto', system-ui, sans-serif;
265
+ box-shadow:
266
+ 0 1px 3px 0 rgba(0, 0, 0, 0.3),
267
+ 0 4px 8px 3px rgba(0, 0, 0, 0.15);
268
+
269
+ /* M3 filled text fields — shared base for all text inputs */
270
+ .tbw-filter-search-input,
271
+ .tbw-filter-range-input,
272
+ .tbw-filter-date-input {
273
+ background: var(--tbw-color-panel-bg);
274
+ border: none;
275
+ border-bottom: 1px solid var(--tbw-color-border-strong);
276
+ border-radius: 4px 4px 0 0;
277
+ height: 36px;
278
+ padding: 8px 12px;
279
+ font-family: inherit;
280
+ caret-color: var(--tbw-color-accent);
281
+ transition: border-color 150ms var(--tbw-transition-ease);
282
+
283
+ &:focus {
284
+ border-bottom: 2px solid var(--tbw-color-accent);
285
+ padding-bottom: 7px;
286
+ box-shadow: none;
287
+ }
288
+ }
289
+
290
+ /* M3 value items with ripple-like hover */
291
+ .tbw-filter-value-item {
292
+ border-radius: 8px;
293
+ transition: background 150ms var(--tbw-transition-ease);
294
+
295
+ &:hover {
296
+ background: var(--tbw-color-row-hover);
297
+ }
298
+ }
299
+
300
+ /* M3 buttons — shared base */
301
+
302
+ /* Filled button (Apply) */
303
+ .tbw-filter-apply-btn {
304
+ &:hover {
305
+ filter: brightness(1.08);
306
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
307
+ }
308
+ }
309
+
310
+ /* Outlined button (Clear) */
311
+ .tbw-filter-clear-btn {
312
+ color: var(--tbw-color-accent);
313
+ border-color: var(--tbw-color-border-strong);
314
+
315
+ &:hover {
316
+ background: var(--tbw-color-row-hover);
317
+ }
318
+ }
319
+
320
+ /* M3 range slider */
321
+ .tbw-filter-range-track,
322
+ .tbw-filter-range-fill {
323
+ height: 4px;
324
+ border-radius: 2px;
325
+ }
326
+
327
+ .tbw-filter-range-thumb::-webkit-slider-thumb {
328
+ width: 20px;
329
+ height: 20px;
330
+ border: none;
331
+ box-shadow:
332
+ 0 1px 3px rgba(0, 0, 0, 0.2),
333
+ 0 1px 2px rgba(0, 0, 0, 0.1);
334
+ }
335
+
336
+ .tbw-filter-range-thumb::-moz-range-thumb {
337
+ width: 20px;
338
+ height: 20px;
339
+ border: none;
340
+ box-shadow:
341
+ 0 1px 3px rgba(0, 0, 0, 0.2),
342
+ 0 1px 2px rgba(0, 0, 0, 0.1);
343
+ }
101
344
  }
102
345
  } /* End @layer tbw-theme */