@vii7/div-table-widget 1.1.0 → 1.2.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/README.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # DivTable Widget
2
2
 
3
+ **v1.2.0** — 2026-02-01
4
+
5
+ **What's new:**
6
+
7
+ - Fixed `.div-table-body` max-height calculation (now uses widget height minus toolbar and header)
8
+ - Row heights between fixed and scroll sections are now always synchronized to the tallest row
9
+ - No more cell overflow: the tallest cell in a row (including composite cells) sets the row height for both fixed and scroll sections
10
+
11
+
3
12
  A modern, flexible table widget built with CSS Grid and Flexbox instead of HTML tables, featuring Monaco Editor integration for advanced query capabilities.
4
13
 
5
14
  ![alt](demo.gif)
@@ -19,6 +28,7 @@ A modern, flexible table widget built with CSS Grid and Flexbox instead of HTML
19
28
  - **Keyboard Navigation**: Full keyboard accessibility with arrow key navigation
20
29
  - **Responsive Design**: Adaptive column sizing and mobile-friendly layout
21
30
  - **Composite Columns**: Stack multiple fields in one column or create two-line headers
31
+ - **Dark Mode Support**: Built-in dark mode with a single class toggle
22
32
 
23
33
  ## Installation
24
34
 
@@ -26,6 +36,193 @@ A modern, flexible table widget built with CSS Grid and Flexbox instead of HTML
26
36
  npm install @vii7/div-table-widget monaco-editor
27
37
  ```
28
38
 
39
+ ## Usage Options
40
+
41
+ ## CDN Setup
42
+
43
+ You can use DivTable Widget directly from a CDN for quick prototyping or embedding in static sites. The latest version is available via [jsDelivr](https://www.jsdelivr.com/package/npm/@vii7/div-table-widget).
44
+
45
+ **Example (CDN):**
46
+
47
+ ```html
48
+ <!DOCTYPE html>
49
+ <html>
50
+ <head>
51
+ <!-- DivTable CSS from CDN -->
52
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@vii7/div-table-widget@latest/src/div-table.css">
53
+ <!-- Monaco Editor (from CDN) -->
54
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/loader.min.js"></script>
55
+ <!-- DivTable Query Engine (from CDN) -->
56
+ <script src="https://cdn.jsdelivr.net/npm/@vii7/div-table-widget@latest/src/query.js"></script>
57
+ <!-- DivTable Widget JS (from CDN) -->
58
+ <script src="https://cdn.jsdelivr.net/npm/@vii7/div-table-widget@latest/src/div-table.js"></script>
59
+ </head>
60
+ <body>
61
+ <div id="table-container"></div>
62
+ <script>
63
+ require.config({ paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs' }});
64
+ require(['vs/editor/editor.main'], function() {
65
+ const divTable = new DivTable(monaco, {
66
+ tableWidgetElement: document.getElementById('table-container'),
67
+ columns: [
68
+ { field: 'id', label: 'ID', primaryKey: true },
69
+ { field: 'name', label: 'Name' },
70
+ { field: 'email', label: 'Email' },
71
+ { field: 'status', label: 'Status' }
72
+ ],
73
+ data: [
74
+ { id: 1, name: 'John Doe', email: 'john@example.com', status: 'active' },
75
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com', status: 'inactive' }
76
+ ]
77
+ });
78
+ });
79
+ </script>
80
+ </body>
81
+ </html>
82
+ ```
83
+
84
+ This setup requires no build step—just copy and paste into your HTML file. Always use the latest version by referencing `@latest` in the CDN URL, or pin to a specific version for production stability.
85
+
86
+
87
+ ## Theming & Customization
88
+
89
+ DivTable supports customizable themes via CSS variables. The base (light) theme is included by default; additional themes like dark mode can be enabled by including a theme CSS file and applying a class.
90
+
91
+ ### Available Themes
92
+
93
+ | Theme | File | Class | Description |
94
+ |-------|------|-------|-------------|
95
+ | Light (default) | `div-table.css` | (none) | Default light theme, included automatically |
96
+ | Dark | `div-table-theme-dark.css` | `.theme-dark` or `.dark` | Dark theme for low-light environments |
97
+
98
+ ### Enabling Dark Mode
99
+
100
+ **Option 1: Static (include theme CSS file)**
101
+
102
+ Include the dark theme CSS after the base CSS:
103
+
104
+ ```html
105
+ <link rel="stylesheet" href="node_modules/@vii7/div-table-widget/dist/divtable.min.css">
106
+ <link rel="stylesheet" href="node_modules/@vii7/div-table-widget/dist/divtable-theme-dark.min.css">
107
+ <body class="theme-dark">
108
+ ...
109
+ </body>
110
+ ```
111
+
112
+ **Option 2: Dynamic (toggle via JavaScript)**
113
+
114
+ You can toggle dark mode dynamically by adding or removing the theme class with JavaScript:
115
+
116
+ ```js
117
+ // Enable dark mode
118
+ document.body.classList.add('theme-dark');
119
+
120
+ // Toggle dark mode
121
+ document.body.classList.toggle('theme-dark');
122
+
123
+ // Remove dark mode (back to light)
124
+ document.body.classList.remove('theme-dark');
125
+ ```
126
+
127
+ **CDN Example (Dark Mode):**
128
+
129
+ ```html
130
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@vii7/div-table-widget@latest/src/div-table.css">
131
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@vii7/div-table-widget@latest/src/div-table-theme-dark.css">
132
+ <body class="theme-dark">
133
+ ...
134
+ </body>
135
+ ```
136
+
137
+ ### Creating Custom Themes
138
+
139
+ You can create your own theme by overriding CSS variables. Copy the dark theme file as a starting point and customize the values:
140
+
141
+ ```css
142
+ /* my-custom-theme.css */
143
+ .theme-custom {
144
+ --dt-primary: #8b5cf6;
145
+ --dt-primary-hover: #7c3aed;
146
+ --dt-bg-base: #1e1b2e;
147
+ --dt-bg-light: #2d2a3e;
148
+ --dt-text-primary: #e2e0f0;
149
+ /* ... override more variables as needed */
150
+ }
151
+ ```
152
+
153
+ Then include and activate your custom theme:
154
+
155
+ ```html
156
+ <link rel="stylesheet" href="div-table.css">
157
+ <link rel="stylesheet" href="my-custom-theme.css">
158
+ <body class="theme-custom">
159
+ ...
160
+ </body>
161
+ ```
162
+
163
+ ### CSS Variables Reference
164
+
165
+ All theme colors are defined as CSS custom properties (variables) in `:root`. Override these in your custom theme class:
166
+
167
+ | Variable | Description |
168
+ |----------|-------------|
169
+ | `--dt-primary` | Primary/accent color |
170
+ | `--dt-bg-base` | Base background color |
171
+ | `--dt-bg-light` | Light background (header, toolbar) |
172
+ | `--dt-bg-hover` | Row hover background |
173
+ | `--dt-bg-selected` | Selected row background |
174
+ | `--dt-border-light` | Light border color |
175
+ | `--dt-border-medium` | Medium border color |
176
+ | `--dt-text-primary` | Primary text color |
177
+ | `--dt-text-secondary` | Secondary text color |
178
+ | `--dt-text-muted` | Muted/disabled text |
179
+ | `--dt-button-bg` | Button background |
180
+ | `--dt-button-text` | Button text color |
181
+ | `--dt-error` | Error state color |
182
+ | `--dt-success` | Success state color |
183
+ | `--dt-warning` | Warning state color |
184
+ | `--dt-info` | Info state color |
185
+
186
+ See `src/div-table.css` for the full list of available variables.
187
+
188
+ ### Option 1: Minified (Production)
189
+
190
+ ```html
191
+ <!-- CSS -->
192
+ <link rel="stylesheet" href="node_modules/@vii7/div-table-widget/dist/divtable.min.css">
193
+
194
+ <!-- Monaco Editor (from CDN) -->
195
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/loader.min.js"></script>
196
+
197
+ <!-- DivTable Widget -->
198
+ <script src="node_modules/@vii7/div-table-widget/src/query.js"></script>
199
+ <script src="node_modules/@vii7/div-table-widget/dist/divtable.min.js"></script>
200
+ ```
201
+
202
+ ### Option 2: Source (Development/Debugging)
203
+
204
+ ```html
205
+ <!-- CSS -->
206
+ <link rel="stylesheet" href="node_modules/@vii7/div-table-widget/src/div-table.css">
207
+
208
+ <!-- Monaco Editor (from CDN) -->
209
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/loader.min.js"></script>
210
+
211
+ <!-- DivTable Widget -->
212
+ <script src="node_modules/@vii7/div-table-widget/src/query.js"></script>
213
+ <script src="node_modules/@vii7/div-table-widget/src/div-table.js"></script>
214
+ ```
215
+
216
+ | File | Size | Description |
217
+ |------|------|-------------|
218
+ | `dist/divtable.min.js` | ~98KB | Minified JavaScript |
219
+ | `dist/divtable.min.css` | ~22KB | Minified CSS (base theme) |
220
+ | `dist/divtable-theme-dark.min.css` | ~2KB | Minified dark theme (optional) |
221
+ | `src/div-table.js` | ~220KB | Source JavaScript |
222
+ | `src/div-table.css` | ~33KB | Source CSS (with CSS variables) |
223
+ | `src/div-table-theme-dark.css` | ~3KB | Source dark theme (optional) |
224
+ | `src/query.js` | ~78KB | Query language engine (required) |
225
+
29
226
  ## Quick Start
30
227
 
31
228
  ### Basic Usage
@@ -34,14 +231,14 @@ npm install @vii7/div-table-widget monaco-editor
34
231
  <!DOCTYPE html>
35
232
  <html>
36
233
  <head>
37
- <link rel="stylesheet" href="node_modules/divtable-widget/src/div-table.css">
234
+ <link rel="stylesheet" href="node_modules/@vii7/div-table-widget/dist/divtable.min.css">
38
235
  <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/loader.min.js"></script>
39
236
  </head>
40
237
  <body>
41
238
  <div id="table-container"></div>
42
239
 
43
- <script src="node_modules/divtable-widget/src/query.js"></script>
44
- <script src="node_modules/divtable-widget/src/div-table.js"></script>
240
+ <script src="node_modules/@vii7/div-table-widget/src/query.js"></script>
241
+ <script src="node_modules/@vii7/div-table-widget/dist/divtable.min.js"></script>
45
242
  <script>
46
243
  // Initialize Monaco Editor
47
244
  require.config({ paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs' }});
@@ -49,10 +246,10 @@ npm install @vii7/div-table-widget monaco-editor
49
246
  const divTable = new DivTable(monaco, {
50
247
  tableWidgetElement: document.getElementById('table-container'),
51
248
  columns: [
52
- { field: 'id', header: 'ID', primaryKey: true },
53
- { field: 'name', header: 'Name' },
54
- { field: 'email', header: 'Email' },
55
- { field: 'status', header: 'Status' }
249
+ { field: 'id', label: 'ID', primaryKey: true },
250
+ { field: 'name', label: 'Name' },
251
+ { field: 'email', label: 'Email' },
252
+ { field: 'status', label: 'Status' }
56
253
  ],
57
254
  data: [
58
255
  { id: 1, name: 'John Doe', email: 'john@example.com', status: 'active' },
@@ -79,9 +276,9 @@ npm install @vii7/div-table-widget monaco-editor
79
276
  const divTable = new DivTable(monaco, {
80
277
  tableWidgetElement: document.getElementById('table-container'),
81
278
  columns: [
82
- { field: 'id', header: 'ID', primaryKey: true },
83
- { field: 'name', header: 'Name' },
84
- { field: 'age', header: 'Age' }
279
+ { field: 'id', label: 'ID', primaryKey: true },
280
+ { field: 'name', label: 'Name' },
281
+ { field: 'age', label: 'Age' }
85
282
  ],
86
283
  virtualScrolling: true,
87
284
  pageSize: 100,
@@ -295,11 +492,11 @@ Keep the first N columns fixed (frozen) on the left side while scrolling horizon
295
492
  const divTable = new DivTable(monaco, {
296
493
  tableWidgetElement: document.getElementById('table-container'),
297
494
  columns: [
298
- { field: 'id', header: 'ID', primaryKey: true },
299
- { field: 'name', header: 'Name' },
300
- { field: 'email', header: 'Email' },
301
- { field: 'department', header: 'Department' },
302
- { field: 'status', header: 'Status' }
495
+ { field: 'id', label: 'ID', primaryKey: true },
496
+ { field: 'name', label: 'Name' },
497
+ { field: 'email', label: 'Email' },
498
+ { field: 'department', label: 'Department' },
499
+ { field: 'status', label: 'Status' }
303
500
  ],
304
501
  data: myData,
305
502
  fixedColumns: 2 // Freeze first 2 columns (ID and Name)
@@ -483,19 +680,100 @@ The widget automatically detects and handles different data types based on the d
483
680
  - **Booleans**: True/false values with = operator
484
681
  - **Arrays**: Array values are joined with commas for display
485
682
 
486
- ## Styling
683
+ ## Styling & Customization
684
+
685
+ The widget uses CSS custom properties (variables) for easy theming. Override these variables in your stylesheet to customize colors:
686
+
687
+ ### CSS Variables Reference
688
+
689
+ ```css
690
+ :root {
691
+ /* Primary/Accent Colors */
692
+ --dt-primary: #007bff; /* Main accent color */
693
+ --dt-primary-hover: #0056b3; /* Accent hover state */
694
+
695
+ /* Background Colors */
696
+ --dt-bg-base: #ffffff; /* Base background */
697
+ --dt-bg-light: #f9f9f7; /* Light background */
698
+ --dt-bg-hover: rgb(240, 247, 255); /* Row hover background */
699
+ --dt-bg-selected: rgba(0, 123, 255, 0.1); /* Selected row background */
700
+ --dt-bg-header: #f9f9f7; /* Header background */
701
+ --dt-bg-summary: #f8f9fa; /* Summary row background */
702
+
703
+ /* Border Colors */
704
+ --dt-border-light: #e9ecef; /* Light borders */
705
+ --dt-border-medium: #e1e5e9; /* Medium borders */
706
+ --dt-border-dark: #ced4da; /* Dark borders */
707
+ --dt-border-row: #f1f3f4; /* Row separator */
708
+
709
+ /* Text Colors */
710
+ --dt-text-primary: #374151; /* Primary text */
711
+ --dt-text-secondary: #495057; /* Secondary text */
712
+ --dt-text-muted: #6b7280; /* Muted/subtle text */
713
+ --dt-text-light: #666666; /* Light text */
714
+ --dt-text-disabled: #999999; /* Disabled text */
715
+
716
+ /* Shadow */
717
+ --dt-shadow: rgba(0, 0, 0, 0.1); /* Standard shadow */
718
+
719
+ /* State Colors */
720
+ --dt-error: #dc3545; /* Error color */
721
+ --dt-success: #28a745; /* Success color */
722
+ --dt-warning: #ffc107; /* Warning color */
723
+ --dt-info: #0ea5e9; /* Info color */
724
+ }
725
+ ```
487
726
 
488
- The widget uses CSS variables for easy customization:
727
+ ### Example: Dark Theme
489
728
 
490
729
  ```css
491
- .div-table-widget {
492
- --table-border-color: #e0e0e0;
493
- --header-bg-color: #f5f5f5;
494
- --row-hover-color: #f9f9f9;
495
- --selected-row-color: #e3f2fd;
730
+ /* custom-theme.css */
731
+ :root {
732
+ --dt-primary: #60a5fa;
733
+ --dt-primary-hover: #3b82f6;
734
+
735
+ --dt-bg-base: #1f2937;
736
+ --dt-bg-light: #374151;
737
+ --dt-bg-hover: #4b5563;
738
+ --dt-bg-selected: rgba(96, 165, 250, 0.2);
739
+ --dt-bg-header: #374151;
740
+ --dt-bg-summary: #374151;
741
+
742
+ --dt-border-light: #4b5563;
743
+ --dt-border-medium: #6b7280;
744
+ --dt-border-dark: #9ca3af;
745
+ --dt-border-row: #374151;
746
+
747
+ --dt-text-primary: #f9fafb;
748
+ --dt-text-secondary: #e5e7eb;
749
+ --dt-text-muted: #9ca3af;
750
+ --dt-text-light: #d1d5db;
751
+ --dt-text-disabled: #6b7280;
752
+ --dt-text-inverse: #1f2937;
753
+
754
+ --dt-shadow: rgba(0, 0, 0, 0.3);
755
+
756
+ --dt-button-bg: #4b5563;
757
+ --dt-button-bg-hover: #6b7280;
758
+ --dt-button-text: #f9fafb;
759
+
760
+ --dt-scrollbar-track: #374151;
761
+ --dt-scrollbar-thumb: #6b7280;
762
+ --dt-scrollbar-thumb-hover: #9ca3af;
496
763
  }
497
764
  ```
498
765
 
766
+ ### Variable Categories
767
+
768
+ | Category | Variables | Description |
769
+ |----------|-----------|-------------|
770
+ | Primary | `--dt-primary`, `--dt-primary-hover` | Brand/accent colors |
771
+ | Background | `--dt-bg-*` | Surface and container backgrounds |
772
+ | Border | `--dt-border-*` | Border and separator colors |
773
+ | Text | `--dt-text-*` | Typography colors |
774
+ | State | `--dt-error`, `--dt-success`, `--dt-warning`, `--dt-info` | Status indicator colors |
775
+ | UI | `--dt-button-*`, `--dt-scrollbar-*` | Button and scrollbar styling |
776
+
499
777
  ## Browser Support
500
778
 
501
779
  - Chrome/Edge: Latest 2 versions
@@ -0,0 +1 @@
1
+ .dark,.theme-dark{--dt-primary:#ffa200;--dt-primary-hover:#cc8100;--dt-primary-light:rgba(255,162,0,.12);--dt-primary-lighter:rgba(255,162,0,.07);--dt-focus-ring:rgba(255,162,0,.18);--dt-bg-base:#171717;--dt-bg-light:#242424;--dt-bg-hover:#2e2e2e;--dt-bg-selected:rgba(255,162,0,.12);--dt-bg-header:#1f1f1f;--dt-bg-summary:#1f1f1f;--dt-bg-disabled:#333;--dt-border-light:#383838;--dt-border-medium:#333;--dt-border-dark:#2e2e2e;--dt-border-row:#383838;--dt-border-focus:#ffa200;--dt-border-hover:#ffa200;--dt-text-primary:#fafafa;--dt-text-secondary:#e6e6e6;--dt-text-muted:#999;--dt-text-light:#e6e6e6;--dt-text-disabled:#8c8c8c;--dt-text-inverse:#171717;--dt-shadow:rgba(0,0,0,.4);--dt-shadow-medium:rgba(0,0,0,.5);--dt-shadow-heavy:rgba(0,0,0,.6);--dt-error:#ef4343;--dt-error-light:rgba(239,67,67,.6);--dt-error-hover:#7c1d1d;--dt-error-active:#531313;--dt-error-bg:#2e1919;--dt-error-border:#f37272;--dt-error-text:#f15b5b;--dt-error-border-hover:rgba(239,67,67,.6);--dt-error-focus-ring:rgba(239,67,67,.25);--dt-success:#24db6a;--dt-success-bg:#1d3024;--dt-success-bg-hover:#2a4635;--dt-warning:#ffb700;--dt-warning-bg:#302a1d;--dt-warning-bg-hover:#463e2a;--dt-info:#3ebdf4;--dt-info-bg:#1d2a30;--dt-info-bg-hover:#2a3e46;--dt-button-bg:#242424;--dt-button-bg-hover:#2e2e2e;--dt-button-text:#fafafa;--dt-scrollbar-track:#242424;--dt-scrollbar-thumb:#383838;--dt-scrollbar-thumb-hover:#474747;--dt-spinner-track:#333;--dt-spinner-active:#e6e6e6;--dt-skeleton-base:#242424;--dt-skeleton-shine:#333;--dt-group-bg:rgba(36,36,36,.5);--dt-summary-border:#2e2e2e}
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.DivTable=t():e.DivTable=t()}(this,()=>(()=>{"use strict";var e={r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};return e.r(t),t})());
@@ -0,0 +1 @@
1
+ :root{--dt-primary:#007bff;--dt-primary-hover:#0056b3;--dt-primary-light:rgba(0,123,255,.1);--dt-primary-lighter:rgba(0,123,255,.05);--dt-focus-ring:rgba(3,102,214,.1);--dt-bg-base:#fff;--dt-bg-light:#f9f9f7;--dt-bg-hover:#f0f7ff;--dt-bg-selected:rgba(0,123,255,.1);--dt-bg-header:#f9f9f7;--dt-bg-summary:#f9f9f7;--dt-bg-disabled:#f0f0f0;--dt-border-light:#e9ecef;--dt-border-medium:#e1e5e9;--dt-border-dark:#ced4da;--dt-border-row:#f1f3f4;--dt-border-focus:#123a67;--dt-border-hover:#b0b8c1;--dt-text-primary:#374151;--dt-text-secondary:#495057;--dt-text-muted:#6b7280;--dt-text-light:#666;--dt-text-disabled:#999;--dt-text-inverse:#fff;--dt-shadow:rgba(0,0,0,.1);--dt-shadow-medium:rgba(0,0,0,.12);--dt-shadow-heavy:rgba(0,0,0,.15);--dt-error:#dc3545;--dt-error-light:rgba(220,53,69,.6);--dt-error-hover:#c82333;--dt-error-active:#bd2130;--dt-error-bg:#fff5f5;--dt-error-border:#fed7d7;--dt-error-text:#c53030;--dt-error-border-hover:rgba(200,35,51,.6);--dt-error-focus-ring:rgba(220,53,69,.25);--dt-success:#28a745;--dt-success-bg:#e8f5e9;--dt-success-bg-hover:#c8e6c9;--dt-warning:#ffc107;--dt-warning-bg:#fff8e1;--dt-warning-bg-hover:#ffecb3;--dt-info:#0ea5e9;--dt-info-bg:#e0f2fe;--dt-info-bg-hover:#bae6fd;--dt-button-bg:#f0f0f0;--dt-button-bg-hover:#e0e0e0;--dt-button-text:#333;--dt-scrollbar-track:#f1f1f1;--dt-scrollbar-thumb:#c1c1c1;--dt-scrollbar-thumb-hover:#a8a8a8;--dt-spinner-track:#e3e3e3;--dt-spinner-active:#666;--dt-skeleton-base:#e9ecef;--dt-skeleton-shine:#f8f9fa;--dt-group-bg:hsla(60,14%,97%,.5);--dt-summary-border:#adb5bd}.div-table-widget{background:var(--dt-bg-base);border-radius:8px;box-shadow:0 2px 8px var(--dt-shadow);box-sizing:border-box;display:flex;flex-direction:column;height:100%;overflow:hidden;width:100%}.div-table-toolbar{align-items:center;background:var(--dt-bg-light);border-bottom:1px solid var(--dt-border-light);display:flex;flex-shrink:0;gap:10px;padding:16px}.query-inputfield{background:var(--dt-bg-base);border:2px solid var(--dt-border-medium);border-radius:8px;box-shadow:0 1px 3px var(--dt-shadow);flex:1;min-width:50%;overflow:hidden;padding:10px 5px 4px 10px;transition:all .2s ease-in-out}.query-inputfield:hover{border-color:var(--dt-border-hover);box-shadow:0 2px 4px var(--dt-shadow-medium)}.query-inputfield.focused{border-color:var(--dt-border-focus);box-shadow:0 0 0 3px var(--dt-focus-ring),0 1px 3px var(--dt-shadow);outline:none}.query-inputfield.error{border-color:var(--dt-error-light)}.query-inputfield.error:hover{border-color:var(--dt-error-border-hover)}.query-inputfield.error.focused{border-color:var(--dt-error-light);box-shadow:0 0 0 3px var(--dt-error-focus-ring),0 1px 3px var(--dt-shadow)}.query-inputfield .monaco-editor{height:22px!important;--vscode-focusBorder:transparent}.div-table-toolbar select{appearance:none;-webkit-appearance:none;-moz-appearance:none;background:var(--dt-bg-base);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right 8px center;background-repeat:no-repeat;background-size:16px;border:2px solid var(--dt-border-medium);border-radius:8px;box-shadow:0 1px 3px var(--dt-shadow);color:var(--dt-text-secondary);cursor:pointer;font-size:14px;min-width:150px;padding:10px 32px 10px 12px;transition:all .2s ease-in-out}.div-table-toolbar select:hover{border-color:var(--dt-border-hover);box-shadow:0 2px 4px var(--dt-shadow-medium)}.div-table-toolbar select:focus{border-color:var(--dt-border-focus);box-shadow:0 0 0 3px var(--dt-focus-ring),0 1px 3px var(--dt-shadow);outline:none}.div-table-toolbar select:disabled{background-color:var(--dt-bg-light);border-color:var(--dt-border-light);color:var(--dt-text-muted);cursor:not-allowed}.info-section{color:var(--dt-text-light);display:flex;flex-direction:column;font-size:.9em;gap:0;margin-left:auto;min-width:200px;padding:0;text-align:right}.info-line-container{gap:8px}.info-line,.info-line-container{align-items:center;display:flex;justify-content:flex-end}.info-line.secondary{color:var(--dt-text-disabled);font-size:.8em}.refresh-button{align-items:center;background:none;border:none;border-radius:3px;color:var(--dt-text-light);cursor:pointer;display:flex;flex-shrink:0;height:22px;justify-content:center;min-height:22px;min-width:22px;padding:4px;transition:all .2s ease;width:22px}.refresh-button:hover{background-color:var(--dt-button-bg);color:var(--dt-button-text)}.refresh-button:active{background-color:var(--dt-button-bg-hover)}.refresh-button.refreshing{color:var(--dt-primary)}.refresh-button.refreshing svg{animation:spin 1s linear infinite}.refresh-button svg{height:14px;transition:transform .2s ease;width:14px}.auto-fetch-button{align-items:center;background:none;border:none;border-radius:3px;color:var(--dt-text-light);cursor:pointer;display:flex;flex-shrink:0;height:22px;justify-content:center;margin-left:4px;min-height:22px;min-width:22px;padding:4px;transition:all .2s ease;width:22px}.auto-fetch-button:hover{background-color:var(--dt-button-bg);color:var(--dt-button-text)}.auto-fetch-button:active{background-color:var(--dt-button-bg-hover)}.auto-fetch-button.active{background-color:var(--dt-success-bg);color:var(--dt-success)}.auto-fetch-button.active:hover{background-color:var(--dt-success-bg-hover)}.auto-fetch-button.paused{background-color:var(--dt-warning-bg);color:var(--dt-warning)}.auto-fetch-button.paused:hover{background-color:var(--dt-warning-bg-hover)}.auto-fetch-button:disabled{cursor:not-allowed;opacity:.5}.auto-fetch-button svg{height:14px;transition:transform .2s ease;width:14px}.filter-selected-only-toggle-button{align-items:center;background:none;border:none;border-radius:3px;color:var(--dt-text-light);cursor:pointer;display:flex;flex-shrink:0;height:22px;justify-content:center;margin-right:6px;min-height:22px;min-width:22px;padding:4px;transition:all .2s ease;width:22px}.filter-selected-only-toggle-button:hover{background-color:var(--dt-button-bg);color:var(--dt-button-text)}.filter-selected-only-toggle-button:active{background-color:var(--dt-button-bg-hover)}.filter-selected-only-toggle-button.active{background-color:var(--dt-info-bg);color:var(--dt-info)}.filter-selected-only-toggle-button.active:hover{background-color:var(--dt-info-bg-hover)}.filter-selected-only-toggle-button svg{height:14px;transition:transform .2s ease;width:14px}.info-selection{font-weight:600}.info-stats{color:var(--dt-text-light)}.progress-line{align-items:center;display:flex;justify-content:flex-end;margin-top:2px}.loading-progress{background:var(--dt-border-light);border-radius:2px;height:4px;overflow:hidden;position:relative;width:120px}.progress-segment{border-radius:2px;height:100%;position:absolute;top:0;transition:width .3s ease,left .3s ease}.filtered-segment{background:var(--dt-error);z-index:3}.loaded-segment{background:var(--dt-text-secondary);z-index:2}.loading-segment{background:var(--dt-primary);z-index:1}.loading-segment:after{animation:loading-shimmer 1.5s infinite;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.8),transparent);bottom:0;content:"";left:0;position:absolute;right:0;top:0}.loading-progress[data-state=filtered-loading],.loading-progress[data-state=sequential-loading]{position:relative}.loading-progress[data-state=filtered] .loaded-segment{background:var(--dt-text-light)}.loading-progress-bar{background:var(--dt-text-secondary);border-radius:2px;height:100%;position:relative;transition:width .3s ease}.loading-progress-bar.loading:after{animation:loading-shimmer 1.5s infinite;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.8),transparent);bottom:0;content:"";left:0;position:absolute;right:0;top:0}.loading-progress[data-state=filtered] .loading-progress-bar{background:var(--dt-text-light)}.loading-progress[data-state=filtered] .loading-progress-bar.loading:after{animation:filtered-shimmer 2s infinite;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.4),transparent)}.loading-progress[data-state=loading] .loading-progress-bar{background:var(--dt-text-secondary)}@keyframes loading-shimmer{0%{transform:translateX(-100%)}to{transform:translateX(100%)}}@keyframes filtered-shimmer{0%{transform:translateX(-100%)}to{transform:translateX(100%)}}.div-table-container{background:var(--dt-bg-base);display:flex;flex:1;flex-direction:column;min-height:0;overflow:hidden;width:100%}.div-table-header{align-items:auto;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);background:var(--dt-bg-header);border-bottom:1px solid var(--dt-border-light);color:var(--dt-text-primary);display:grid;flex-shrink:0;min-height:48px;position:sticky;top:0;transition:box-shadow .3s cubic-bezier(.4,0,.2,1);z-index:10}.scrollbar-spacer{background:transparent;pointer-events:none}.div-table-header.scrolled{box-shadow:0 2px 8px var(--dt-shadow)}.div-table-body{background:var(--dt-bg-base);flex:1;min-height:0;overflow-y:auto}.div-table-row{align-items:stretch;border-bottom:1px solid var(--dt-border-row);box-sizing:border-box;color:var(--dt-text-primary);cursor:pointer;display:grid;gap:0;min-height:40px;transition:all .2s ease}.div-table-row:hover{background-color:var(--dt-bg-hover)}.div-table-row:last-child{border-bottom:none}.div-table-cell{box-sizing:border-box;min-width:0;text-overflow:ellipsis;white-space:nowrap}.div-table-cell,.div-table-header-cell{align-items:flex-start;display:flex;overflow:hidden;padding:8px 12px}.div-table-header-cell{color:var(--dt-text-primary);cursor:pointer;justify-content:space-between;transition:background-color .2s ease;user-select:none}.header-left-content{align-items:center;display:flex;flex:1 1 auto;font-weight:600;gap:0;min-width:0;overflow:hidden}.header-left-content>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header-right-content{align-items:center;display:flex;flex:0 0 auto;gap:4px;margin-left:8px}.div-table-header-cell:hover{background-color:var(--dt-shadow)}.group-indicator{align-items:center;display:inline-flex;font-size:12px;height:20px;justify-content:center;opacity:0;transition:opacity .2s ease;width:14px}.div-table-header-cell:hover .group-indicator{opacity:.5}.group-indicator:hover{opacity:1!important}.group-indicator.grouped{color:inherit;opacity:1!important}.sort-indicator{align-items:center;display:inline-flex;height:20px;justify-content:center;opacity:0;transition:opacity .2s ease;width:14px}.div-table-header-cell:hover .sort-indicator{opacity:.5}.sort-indicator.active{opacity:1!important}.header-right-content>span:last-child:not(.group-indicator):not(.sort-indicator){opacity:0;transition:opacity .2s ease}.div-table-header-cell:hover .header-right-content>span:last-child:not(.group-indicator):not(.sort-indicator){opacity:.5}.div-table-header-cell.sorted .header-right-content>span:last-child:not(.sort-indicator){opacity:1!important}.sub-sort-indicator{align-items:center;display:inline-flex;height:20px;justify-content:center;opacity:0;transition:opacity .2s ease;width:14px}.composite-header:hover .sub-sort-indicator,.composite-sub-header:hover .sub-sort-indicator{opacity:.5}.sub-sort-indicator.active{opacity:1!important}.div-table-cell.checkbox-column,.div-table-header-cell.checkbox-column{justify-content:center;max-width:40px;min-width:40px;padding:8px 4px;width:40px}.div-table-cell.checkbox-column input[type=checkbox],.div-table-header-cell.checkbox-column input[type=checkbox]{accent-color:var(--dt-primary);cursor:pointer;height:15px;margin:0;width:15px}input[type=checkbox]:indeterminate{background-color:var(--dt-primary);border-color:var(--dt-primary);position:relative}input[type=checkbox]:indeterminate:after{color:var(--dt-text-inverse);content:"━";font-size:10px;font-weight:700;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.div-table-header-cell.checkbox-column input[type=checkbox]:indeterminate{background-color:var(--dt-primary);border-color:var(--dt-primary)}.div-table-row.selected{background-color:var(--dt-bg-selected)!important}.div-table-row.focused{background-color:var(--dt-bg-base);box-shadow:inset 3px 0 0 var(--dt-primary)}.div-table-row.focused:hover{background-color:var(--dt-primary-lighter)!important}.div-table-row.group-header.focused{background-color:var(--dt-bg-base)!important;box-shadow:inset 3px 0 0 var(--dt-primary)!important}.div-table-row.group-header.focused:hover{background-color:var(--dt-bg-hover)!important}.div-table-row.group-header{background:var(--dt-bg-base);border-bottom:1px solid var(--dt-border-row);border-top:1px solid var(--dt-border-row);box-shadow:none;color:var(--dt-text-secondary);font-weight:400;isolation:isolate;position:sticky;top:0;z-index:9}.div-table-row.group-header:first-of-type{border-top:none}.div-table-row.group-header:hover{background-color:var(--dt-bg-hover)}.div-table-row.group-header:first-of-type{box-shadow:0 2px 8px var(--dt-shadow-heavy)}.div-table-row.group-header .div-table-cell span{font-weight:600}.div-table-row.group-header .checkbox-column{align-items:center;display:flex;justify-content:center}.div-table-row.group-header .checkbox-column input[type=checkbox]{accent-color:var(--dt-primary);cursor:pointer;height:15px;width:15px}.div-table-row.group-header .checkbox-column input[type=checkbox]:indeterminate{background-color:var(--dt-primary)}.group-toggle,.group-toggle-all{align-items:center;border-radius:3px;cursor:pointer;display:inline-flex;font-size:.9em;justify-content:center;min-height:20px;min-width:20px;padding:2px;transform:rotate(90deg);transition:transform .2s ease}.group-toggle-all.collapsed,.group-toggle.collapsed{transform:rotate(0deg)}.group-toggle-all{font-size:1em;font-weight:700;margin-right:6px}.group-toggle-all:hover,.group-toggle:hover{background-color:var(--dt-shadow);opacity:.7}.div-table-cell.grouped-column{color:var(--dt-text-disabled);font-style:italic}.div-table-cell.composite-column{align-items:flex-start;display:flex;flex-direction:column;gap:2px;padding:6px 12px;white-space:normal}.composite-sub{color:var(--dt-text-muted);line-height:1.2}.div-table-cell.composite-cell{align-items:stretch;display:flex;flex-direction:column;gap:0;padding:8px 12px}.composite-sub-cell{align-items:center;display:flex;min-width:0;overflow:hidden}.composite-sub-cell:first-child{margin-bottom:4px}.composite-sub-cell:not(:first-child){color:var(--dt-text-muted)}.div-table-header-cell.composite-header{flex-direction:column;gap:4px;justify-content:flex-start;padding:8px 12px}.composite-sub-header{border-radius:4px;cursor:pointer;min-width:0;padding:0;transition:background-color .2s ease;user-select:none;width:100%}.composite-sub-header:first-child{color:var(--dt-text-primary);font-weight:600;margin-bottom:4px}.composite-main-header{color:var(--dt-text-primary)}.composite-sub-header:hover{background-color:var(--dt-bg-disabled)}.composite-toggle{cursor:pointer;display:inline-block;font-size:.9em;transition:transform .2s ease;user-select:none}.composite-toggle:hover{opacity:.7}.div-table-row.group-collapsed{display:none}.col-fixed-narrow{grid-column:span 1;max-width:80px;min-width:60px}.col-fixed-medium{grid-column:span 1;max-width:140px;min-width:100px}.col-flexible-small{flex:1;grid-column:span 1;min-width:120px}.col-flexible-medium{flex:2;grid-column:span 2;min-width:150px}.col-flexible-large{flex:3;grid-column:span 3;min-width:200px}.div-table-header.grid-5-cols,.div-table-row.grid-5-cols{grid-template-columns:40px 1fr 100px 200px 100px}.div-table-header.grid-4-cols,.div-table-row.grid-4-cols{grid-template-columns:40px 2fr 200px 100px}.div-table-header,.div-table-row{grid-template-columns:repeat(auto-fit,minmax(100px,1fr))}@media (max-width:768px){.div-table-toolbar{align-items:stretch;flex-direction:column;gap:8px}.query-inputfield{max-width:100%;width:100%}.div-table-cell.hidden-mobile,.div-table-header-cell.hidden-mobile{display:none}.div-table-header.grid-4-cols,.div-table-header.grid-5-cols,.div-table-row.grid-4-cols,.div-table-row.grid-5-cols{grid-template-columns:40px 2fr 1fr}}@media (max-width:480px){.div-table-cell.hidden-small,.div-table-header-cell.hidden-small{display:none}.div-table-header.grid-4-cols,.div-table-header.grid-5-cols,.div-table-row.grid-4-cols,.div-table-row.grid-5-cols{grid-template-columns:40px 1fr}}.div-table-widget.no-checkboxes .checkbox-column{display:none}.div-table-widget.no-checkboxes .div-table-header.grid-5-cols,.div-table-widget.no-checkboxes .div-table-row.grid-5-cols{grid-template-columns:1fr 2fr 2fr 1fr}.div-table-widget.no-checkboxes .div-table-header.grid-4-cols,.div-table-widget.no-checkboxes .div-table-row.grid-4-cols{grid-template-columns:2fr 2fr 1fr}.div-table-body::-webkit-scrollbar{width:8px}.div-table-body::-webkit-scrollbar-track{background:var(--dt-scrollbar-track);border-radius:4px}.div-table-body::-webkit-scrollbar-thumb{background:var(--dt-scrollbar-thumb);border-radius:4px}.div-table-body::-webkit-scrollbar-thumb:hover{background:var(--dt-scrollbar-thumb-hover)}.div-table-empty{color:var(--dt-text-disabled)}.div-table-empty,.div-table-loading{align-items:center;display:flex;font-style:italic;justify-content:center;min-height:200px}.div-table-loading{color:var(--dt-text-light);position:relative}.div-table-loading:before{animation:spin 1s linear infinite;border-top:2px solid var(--dt-spinner-track);border:2px solid var(--dt-spinner-track);border-radius:50%;border-top-color:var(--dt-spinner-active);content:"";height:20px;margin-right:10px;width:20px}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.error-indicator{align-items:center;background:var(--dt-error-bg);border:1px solid var(--dt-error-border);border-radius:3px;color:var(--dt-error-text);display:none;font-size:14px;gap:10px;justify-content:center;margin:10px 0;padding:15px}.div-table-row.loading-placeholder{background:var(--dt-group-bg);border-bottom:1px solid var(--dt-border-row);cursor:default;pointer-events:none}.div-table-row.loading-placeholder:hover{background:var(--dt-group-bg)!important}.div-table-cell.loading-cell{align-items:center;display:flex;padding:8px 12px}.loading-shimmer-content{animation:loading-shimmer 1.5s infinite;background:linear-gradient(90deg,var(--dt-skeleton-base) 25%,var(--dt-skeleton-shine) 50%,var(--dt-skeleton-base) 75%);background-size:200% 100%;border-radius:4px;height:16px}.retry-button{align-items:stretch;background:var(--dt-error);border:none;border-radius:4px;color:var(--dt-text-inverse);flex-direction:column;gap:0;padding:8px 12px}.div-table-cell.composite-cell .composite-sub-cell{align-items:flex-start}.retry-button:hover{background:var(--dt-error-hover)}.retry-button:active{background:var(--dt-error-active)}.div-table-container.has-fixed-columns{display:flex;flex-direction:column;overflow:hidden}.div-table-columns-wrapper{display:flex;flex:1;min-height:0;overflow:hidden}.div-table-fixed-section{background:var(--dt-bg-base);border-right:1px solid var(--dt-border-light);display:flex;flex:0 0 auto;flex-direction:column;z-index:5}.div-table-fixed-section.has-scroll-shadow{box-shadow:2px 0 8px var(--dt-shadow)}.div-table-scroll-section{display:flex;flex:1 1 auto;flex-direction:column;min-width:0;overflow:hidden}.div-table-fixed-header{display:grid;z-index:11}.div-table-fixed-header,.div-table-scroll-header{box-sizing:border-box;flex-shrink:0;position:relative}.div-table-scroll-header{overflow-x:scroll;overflow-y:hidden;scrollbar-width:none;z-index:10;-ms-overflow-style:none}.div-table-scroll-header::-webkit-scrollbar{display:none}.div-table-scroll-header-inner{display:grid;min-width:100%;width:max-content}.div-table-fixed-body{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto}.div-table-fixed-body::-webkit-scrollbar{display:none}.div-table-fixed-body{-ms-overflow-style:none;scrollbar-width:none}.div-table-scroll-body{flex:1;min-height:0;overflow:auto;overflow-x:overlay;overflow-y:overlay}@supports (scrollbar-gutter:stable){.div-table-scroll-body{overflow-x:auto;overflow-y:auto}.div-table-fixed-body,.div-table-scroll-body{scrollbar-gutter:stable}}.div-table-fixed-row,.div-table-scroll-row{align-items:flex-start;box-sizing:border-box;min-height:40px}.div-table-fixed-row,.div-table-scroll-row{background:var(--dt-bg-base);display:grid}.div-table-row.hover,.div-table-row:hover{background-color:var(--dt-bg-hover)}.div-table-fixed-row.selected,.div-table-scroll-row.selected{background-color:var(--dt-bg-selected)!important}.div-table-fixed-row.focused,.div-table-scroll-row.focused{background-color:var(--dt-bg-base);box-shadow:inset 3px 0 0 var(--dt-primary)}.div-table-fixed-row.focused.hover,.div-table-fixed-row.focused:hover,.div-table-scroll-row.focused.hover,.div-table-scroll-row.focused:hover{background-color:var(--dt-primary-lighter)!important}.div-table-fixed-row.group-header,.div-table-scroll-row.group-header{background:var(--dt-bg-base);border-bottom:1px solid var(--dt-border-row);border-top:1px solid var(--dt-border-row);position:sticky;top:0;z-index:4}.div-table-fixed-row.group-header.focused,.div-table-scroll-row.group-header.focused{background-color:var(--dt-bg-base)!important;box-shadow:inset 3px 0 0 var(--dt-primary)!important}.div-table-scroll-section .div-table-cell{overflow:visible;text-overflow:clip;white-space:nowrap}.div-table-scroll-section .div-table-header-cell,.div-table-scroll-section .header-left-content{overflow:visible}.div-table-scroll-section .header-left-content>span{overflow:visible;text-overflow:clip;white-space:nowrap}.div-table-scroll-row{min-width:100%;width:max-content}@media (max-width:768px){.div-table-container.has-fixed-columns{display:flex;flex-direction:column}.div-table-columns-wrapper{flex-direction:column}.div-table-fixed-section{border-bottom:1px solid var(--dt-border-light);border-right:none;box-shadow:0 2px 8px var(--dt-shadow);flex:0 0 auto}.div-table-scroll-section{flex:1 1 auto}}.div-table-row.summary-row{background-color:var(--dt-bg-base);border-bottom:2px solid var(--dt-border-dark);font-weight:600;min-height:32px}.div-table-row.header-summary{background-color:var(--dt-bg-summary);border-bottom:1px solid var(--dt-summary-border);position:sticky;top:0;z-index:2}.div-table-row.group-summary{border-bottom:1px solid var(--dt-summary-border);font-size:.95em;font-weight:500}.div-table-cell.summary-cell{color:var(--dt-text-secondary);padding:8px 12px}.aggregate-value{color:var(--dt-text-primary);font-variant-numeric:tabular-nums;font-weight:700}.div-table-row.summary-row:hover{background-color:var(--dt-bg-summary)}.div-table-fixed-row.summary-row{background-color:var(--dt-bg-base);min-height:32px}.div-table-fixed-row.header-summary{background-color:var(--dt-bg-summary)}.div-table-cell.summary-cell:empty{min-height:1em}