@azrico/reactgrid 1.3.52 → 1.4.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,3 +1,198 @@
1
1
  **DISCLAIMER :**
2
2
  DO NOT USE THIS PACKAGE FOR ANY REASON
3
3
  THIS IS A PRIVATE PACKAGE
4
+
5
+ ## Grid themes
6
+
7
+ `AzGrid` always uses Inovua's `default-light` base for layout and icons. Its
8
+ token stylesheet is optional and shipped in `dist/src/themes`. Import it once
9
+ in your host's entry point to enable the variable theme; without it the grid
10
+ uses Inovua's default-light appearance. The old dark/amber theme stylesheets
11
+ are no longer imported by the package.
12
+ Use `theme="light"` (default), `theme="dark"`, or any custom name such as
13
+ `theme="deco"`. The actual grid root and its surrounding scope receive
14
+ `azgrid-theme-<name>`. `theme` takes precedence over the deprecated `dark` boolean;
15
+ `dark={true}` still selects dark and `dark={false}` selects light.
16
+ `gridOptions.theme` is ignored to keep one consistent base for layout.
17
+
18
+ Set public `--azgrid-*` variables on `:root`, a wrapper, or the theme class.
19
+ Different wrappers can theme multiple grids independently. Neutral light/dark
20
+ presets set only internal `--azgrid-preset-*` fallbacks, so grid defaults
21
+ never mask variables inherited from your wrapper. Custom names use light
22
+ fallbacks for unspecified tokens; set the complete palette for a custom dark theme.
23
+ No daisyUI dependency or variables are required.
24
+
25
+ ```tsx
26
+ import { AzGrid } from '@azrico/reactgrid';
27
+ import '@azrico/reactgrid/dist/src/themes/azgrid-theme.css';
28
+
29
+ <div className="my-grid">
30
+ <AzGrid theme="light" columns={columns} dataSource={rows} />
31
+ </div>
32
+ ```
33
+
34
+ ```css
35
+ .my-grid {
36
+ --azgrid-accent: #345b93;
37
+ --azgrid-header-bg: #edf2f8;
38
+ --azgrid-row-bg-hover: #e4ecf7;
39
+ }
40
+ ```
41
+
42
+ ### Public variables
43
+
44
+ Every use has a neutral preset fallback. Values can be any valid CSS value for
45
+ the indicated property. Fallbacks expressed using another token follow host
46
+ overrides of that token. `--azgrid-preset-*` variables are internal implementation
47
+ details and should not be overridden.
48
+
49
+ <!-- azgrid-tokens -->
50
+ | Variable | Controls | Light / dark fallback |
51
+ | --- | --- | --- |
52
+ | `--azgrid-bg` | Grid background | `#fff` / `#313943` |
53
+ | `--azgrid-fg` | Grid text | `#555e68` / `#c5cae9` |
54
+ | `--azgrid-border` | Grid border and separators | `#e4e3e2` / `#4f575f` |
55
+ | `--azgrid-font-family` | Grid and control font family | `'Nunito Sans', 'Iran Sans', sans-serif` |
56
+ | `--azgrid-radius` | Grid, input and menu corner radius | `0` |
57
+ | `--azgrid-accent` | Focus indicators, sort arrows, checkboxes and selection handles | `#7986cb` / `#caae53` |
58
+ | `--azgrid-transparent` | Transparent structural surfaces | `transparent` |
59
+ | `--azgrid-muted-fg` | Disabled text and secondary icons | `#99a1aa` / `#9ca6b0` |
60
+ | `--azgrid-shadow-color` | Menu and input shadow colour | `rgba(0, 0, 0, .2)` / `rgba(0, 0, 0, .4)` |
61
+ | `--azgrid-header-bg` | Header and grouped header background | `#fff` / `#3b444f` |
62
+ | `--azgrid-header-fg` | Header text | `var(--azgrid-fg, var(--azgrid-preset-fg))` |
63
+ | `--azgrid-header-border` | Header separators | `var(--azgrid-border, var(--azgrid-preset-border))` |
64
+ | `--azgrid-header-font-size` | Header font size | `14px` |
65
+ | `--azgrid-header-text-transform` | Header text transform | `none` |
66
+ | `--azgrid-header-letter-spacing` | Header letter spacing | `normal` |
67
+ | `--azgrid-header-font-weight` | Header font weight | `500` |
68
+ | `--azgrid-row-bg-even` | Even and non-zebra rows | `var(--azgrid-bg, var(--azgrid-preset-bg))` |
69
+ | `--azgrid-row-bg-odd` | Odd rows | `#fafafa` / `#353e48` |
70
+ | `--azgrid-row-bg-hover` | Hovered rows and cells | `#ebedf7` / `#454f5b` |
71
+ | `--azgrid-row-fg-hover` | Hovered row text | `var(--azgrid-fg, var(--azgrid-preset-fg))` / `#ececec` |
72
+ | `--azgrid-row-bg-selected` | Selected rows and cells | `#dce0f2` / `#655c3e` |
73
+ | `--azgrid-row-fg-selected` | Selected row text | `var(--azgrid-fg, var(--azgrid-preset-fg))` / `#fff` |
74
+ | `--azgrid-row-bg-active` | Active rows | `#ebedf7` / `#4f575f` |
75
+ | `--azgrid-cell-border` | Cell borders | `rgba(1, 1, 1, .1)` / `#4f575f` |
76
+ | `--azgrid-cell-border-width` | Cell border width | `0.1px` |
77
+ | `--azgrid-cell-padding` | Ordinary data cell padding; expand/reorder tools keep their layout | `0 8px` |
78
+ | `--azgrid-filter-bg` | Filter row and input background, also editors and search | `var(--azgrid-bg, var(--azgrid-preset-bg))` |
79
+ | `--azgrid-filter-fg` | Filter input and editor text | `var(--azgrid-fg, var(--azgrid-preset-fg))` |
80
+ | `--azgrid-filter-border` | Filter input borders | `var(--azgrid-border, var(--azgrid-preset-border))` |
81
+ | `--azgrid-filter-placeholder` | Input placeholder text | `var(--azgrid-muted-fg, var(--azgrid-preset-muted-fg))` |
82
+ | `--azgrid-filter-focus-ring` | Focused input border and ring | `var(--azgrid-accent, var(--azgrid-preset-accent))` |
83
+ | `--azgrid-pagination-bg` | Pagination toolbar, page number and page size controls | `var(--azgrid-bg, var(--azgrid-preset-bg))` |
84
+ | `--azgrid-pagination-fg` | Pagination text and icons | `var(--azgrid-fg, var(--azgrid-preset-fg))` |
85
+ | `--azgrid-pagination-border` | Pagination control borders | `var(--azgrid-border, var(--azgrid-preset-border))` |
86
+ | `--azgrid-menu-bg` | Column, filter, context, select menus and date pickers | `var(--azgrid-bg, var(--azgrid-preset-bg))` |
87
+ | `--azgrid-menu-fg` | Menu text and icons | `var(--azgrid-fg, var(--azgrid-preset-fg))` |
88
+ | `--azgrid-menu-border` | Menu borders and separators | `var(--azgrid-border, var(--azgrid-preset-border))` |
89
+ | `--azgrid-menu-bg-hover` | Hovered/focused menu entries | `var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover))` |
90
+ | `--azgrid-scrollbar-track` | Native and Inovua scrollbar tracks | `#f1f1f1` / `#313943` |
91
+ | `--azgrid-scrollbar-thumb` | Native and Inovua scrollbar thumbs | `#b5b5b5` / `#697582` |
92
+ | `--azgrid-empty-bg` | Empty state background | `var(--azgrid-bg, var(--azgrid-preset-bg))` |
93
+ | `--azgrid-empty-fg` | No records text | `var(--azgrid-fg, var(--azgrid-preset-fg))` |
94
+ | `--azgrid-loading-bg` | Loading overlay background | `rgba(255, 255, 255, .8)` / `rgba(49, 57, 67, .8)` |
95
+ | `--azgrid-loading-fg` | Loading text and spinner | `var(--azgrid-fg, var(--azgrid-preset-fg))` |
96
+ | `--azgrid-tree-bg` | Tree/group row background | `var(--azgrid-row-bg-even, var(--azgrid-preset-row-bg-even))` |
97
+ | `--azgrid-tree-fg` | Tree/group text and expand icons | `var(--azgrid-fg, var(--azgrid-preset-fg))` |
98
+ | `--azgrid-details-bg` | Row details background | `var(--azgrid-bg, var(--azgrid-preset-bg))` |
99
+ | `--azgrid-locked-column-shadow` | Locked column separator shadow (complete CSS box-shadow value) | `0 0 5px rgba(0, 0, 0, .2)` / `0 0 5px rgba(0, 0, 0, .5)` |
100
+ <!-- /azgrid-tokens -->
101
+
102
+ ### Dark Art Deco host preset
103
+
104
+ Square corners, obsidian surfaces, gold accents and uppercase widely spaced
105
+ headers are host choices, separate from the neutral theme. Set variables on
106
+ `.azgrid-theme-deco` to support `theme="deco"`, or on a host wrapper.
107
+
108
+ ```tsx
109
+ <AzGrid theme="deco" columns={columns} dataSource={rows} />
110
+ ```
111
+
112
+ <!-- azgrid-deco -->
113
+ ```css
114
+ /* Example host preset; separate from the neutral grid theme. */
115
+ .azgrid-example-deco, .azgrid-theme-deco {
116
+ --azgrid-bg: #0A0A0A;
117
+ --azgrid-fg: #eee7d6;
118
+ --azgrid-border: #6b5824;
119
+ --azgrid-accent: #D4AF37;
120
+ --azgrid-muted-fg: #9b8a5b;
121
+ --azgrid-radius: 0;
122
+ --azgrid-font-family: Georgia, serif;
123
+ --azgrid-header-bg: #0A0A0A;
124
+ --azgrid-header-fg: #D4AF37;
125
+ --azgrid-header-border: #6b5824;
126
+ --azgrid-header-text-transform: uppercase;
127
+ --azgrid-header-letter-spacing: .1em;
128
+ --azgrid-header-font-weight: 600;
129
+ --azgrid-row-bg-even: #0A0A0A;
130
+ --azgrid-row-bg-odd: #12110e;
131
+ --azgrid-row-bg-hover: #282211;
132
+ --azgrid-row-fg-hover: #fff6dc;
133
+ --azgrid-row-bg-selected: #423619;
134
+ --azgrid-row-fg-selected: #fff6dc;
135
+ --azgrid-row-bg-active: #332a15;
136
+ --azgrid-cell-border: #6b5824;
137
+ --azgrid-cell-border-width: 1px;
138
+ --azgrid-cell-padding: 0 10px;
139
+ --azgrid-filter-bg: #12110e;
140
+ --azgrid-filter-fg: #eee7d6;
141
+ --azgrid-filter-border: #6b5824;
142
+ --azgrid-filter-placeholder: #9b8a5b;
143
+ --azgrid-filter-focus-ring: #D4AF37;
144
+ --azgrid-pagination-bg: #0A0A0A;
145
+ --azgrid-pagination-fg: #D4AF37;
146
+ --azgrid-pagination-border: #6b5824;
147
+ --azgrid-menu-bg: #12110e;
148
+ --azgrid-menu-fg: #eee7d6;
149
+ --azgrid-menu-border: #6b5824;
150
+ --azgrid-menu-bg-hover: #282211;
151
+ --azgrid-scrollbar-track: #0A0A0A;
152
+ --azgrid-scrollbar-thumb: #6b5824;
153
+ --azgrid-empty-bg: #0A0A0A;
154
+ --azgrid-empty-fg: #9b8a5b;
155
+ --azgrid-loading-bg: rgba(10, 10, 10, .85);
156
+ --azgrid-loading-fg: #D4AF37;
157
+ --azgrid-tree-bg: #12110e;
158
+ --azgrid-tree-fg: #D4AF37;
159
+ --azgrid-details-bg: #12110e;
160
+ --azgrid-shadow-color: rgba(0, 0, 0, .6);
161
+ --azgrid-locked-column-shadow: 0 0 5px #6b5824;
162
+ }
163
+
164
+ ```
165
+ <!-- /azgrid-deco -->
166
+
167
+ `src/example.tsx` renders light, dark and this host palette together, with
168
+ filter inputs, editable cells, tree rows, selection, context menus and pagination.
169
+
170
+ ### Scope and maintenance
171
+
172
+ The wrapper's MUI context menu portal stays inside the owning theme scope.
173
+ Inovua's default column/filter menus and page-size dropdown render in
174
+ the grid. If you explicitly use `gridOptions.menuPortalContainer` or
175
+ `gridOptions.renderInPortal` to move UI elsewhere, that external container must
176
+ also carry `azgrid-scope`, the owning `azgrid-theme-<name>` class and host
177
+ variables. Arbitrary custom cell,
178
+ editor, menu and row-detail content must use these variables in its own CSS;
179
+ the package cannot replace colours deliberately supplied by a host renderer or
180
+ inline `gridOptions.style`/column styles.
181
+
182
+ Inovua's base layout, animations, icon geometry and state selectors remain
183
+ intact. `config/generate-theme.cjs` extracts only colour/font declarations and
184
+ adds scope specificity. Run `node config/generate-theme.cjs` after an Inovua
185
+ upgrade and inspect selector changes. Run `yarn check:theme` to audit upstream
186
+ colour coverage, token defaults/documentation and commented important rules.
187
+ `config/theme-extras.css` handles surfaces
188
+ without upstream colour declarations. The only colour-related upstream
189
+ `!important` rules are footer cell border colour and first-row cell top border;
190
+ our matching overrides explain each use. Native scrollbar presentation remains
191
+ subject to browser/OS support.
192
+
193
+ ### Styling dependencies
194
+
195
+ `@azrico/controls` 1.6.1 provides the context menu. MUI's default styled engine
196
+ uses `@emotion/react` and `@emotion/styled` for those components; the grid does
197
+ not use Emotion to implement its CSS variable theme. Removing Emotion requires
198
+ replacing the MUI menu or configuring another supported MUI styling engine.
@@ -0,0 +1,37 @@
1
+ const fs = require('fs');
2
+ const assert = require('assert');
3
+ const postcss = require('postcss');
4
+ const cssTree = require('css-tree');
5
+ const css = fs.readFileSync('src/themes/azgrid-theme.css', 'utf8');
6
+ cssTree.parse(css);
7
+ const theme = postcss.parse(css);
8
+ const presets = new Set();
9
+ const used = new Set();
10
+ let important = [];
11
+ theme.walkDecls(d => {
12
+ if(d.prop.startsWith('--azgrid-preset-')) presets.add(d.prop.slice('--azgrid-preset-'.length));
13
+ else {
14
+ assert(!/#[\da-f]{3,8}\b|rgba?\(|hsla?\(/i.test(d.value), 'literal outside presets: '+d);
15
+ for(const match of d.value.matchAll(/var\(--azgrid-(?!preset-)([\w-]+)/g)) used.add(match[1]);
16
+ }
17
+ if(d.important) { assert(d.prev().type === 'comment', 'comment required for !important'); important.push(d.parent.selector); }
18
+ });
19
+ for(const name of presets) assert(used.has(name), 'unused public token '+name);
20
+ for(const name of used) assert(presets.has(name), 'missing fallback '+name);
21
+ const readme = fs.readFileSync('README.md','utf8');
22
+ for(const name of used) assert(readme.includes('`--azgrid-'+name+'`'), 'undocumented '+name);
23
+ assert.equal(important.length,2);
24
+ // Every literal paint declaration in Inovua must have a scoped override.
25
+ const upstream = postcss.parse(fs.readFileSync('node_modules/@inovua/reactdatagrid-enterprise/index.css','utf8'));
26
+ let count = 0;
27
+ upstream.walkRules(r => {
28
+ const colour = r.nodes.some(d => /^(color|background.*|.*border.*|outline.*|fill|stroke|.*shadow)$/.test(d.prop) && /#[\da-f]{3,8}\b|rgba?\(|hsla?\(|\b(?:transparent|white|black|grey|gray|red|blue|silver)\b/i.test(d.value));
29
+ if(!colour || r.parent.type === 'atrule') return;
30
+ for(const selector of r.selectors) {
31
+ const scoped = selector.startsWith('.InovuaReactDataGrid--') || /^\.InovuaReactDataGrid(?=[\s.:#>]|$)/.test(selector) ? '.azgrid'+selector : '.azgrid-scope '+selector;
32
+ assert(theme.nodes.some(n=>n.type==='rule' && n.selectors.includes(scoped)), 'missing selector '+selector);
33
+ }
34
+ count++;
35
+ });
36
+ console.log('PASS:',used.size,'documented tokens;',count,'upstream paint rules covered; only two commented !important selectors');
37
+ console.log(important.join('\n'));
@@ -0,0 +1,132 @@
1
+ // Regenerate after upgrading Inovua: node config/generate-theme.cjs
2
+ // Keep upstream layout, icon geometry, state specificity and selector order.
3
+ const fs = require('fs');
4
+ const postcss = require('postcss');
5
+
6
+ // [light fallback, dark fallback, description]. Presets define fallback tokens,
7
+ // never public tokens: variables inherited from a host wrapper must win.
8
+ const tokens = {
9
+ bg: ['#fff', '#313943', 'Grid background'],
10
+ fg: ['#555e68', '#c5cae9', 'Grid text'],
11
+ border: ['#e4e3e2', '#4f575f', 'Grid border and separators'],
12
+ 'font-family': ["'Nunito Sans', 'Iran Sans', sans-serif", "'Nunito Sans', 'Iran Sans', sans-serif", 'Grid and control font family'],
13
+ radius: ['0', '0', 'Grid, input and menu corner radius'],
14
+ accent: ['#7986cb', '#caae53', 'Focus indicators, sort arrows, checkboxes and selection handles'],
15
+ transparent: ['transparent', 'transparent', 'Transparent structural surfaces'],
16
+ 'muted-fg': ['#99a1aa', '#9ca6b0', 'Disabled text and secondary icons'],
17
+ 'shadow-color': ['rgba(0, 0, 0, .2)', 'rgba(0, 0, 0, .4)', 'Menu and input shadow colour'],
18
+ 'header-bg': ['#fff', '#3b444f', 'Header and grouped header background'],
19
+ 'header-fg': ['var(--azgrid-fg, var(--azgrid-preset-fg))', 'var(--azgrid-fg, var(--azgrid-preset-fg))', 'Header text'],
20
+ 'header-border': ['var(--azgrid-border, var(--azgrid-preset-border))', 'var(--azgrid-border, var(--azgrid-preset-border))', 'Header separators'],
21
+ 'header-font-size': ['14px', '14px', 'Header font size'],
22
+ 'header-text-transform': ['none', 'none', 'Header text transform'],
23
+ 'header-letter-spacing': ['normal', 'normal', 'Header letter spacing'],
24
+ 'header-font-weight': ['500', '500', 'Header font weight'],
25
+ 'row-bg-even': ['var(--azgrid-bg, var(--azgrid-preset-bg))', 'var(--azgrid-bg, var(--azgrid-preset-bg))', 'Even and non-zebra rows'],
26
+ 'row-bg-odd': ['#fafafa', '#353e48', 'Odd rows'],
27
+ 'row-bg-hover': ['#ebedf7', '#454f5b', 'Hovered rows and cells'],
28
+ 'row-fg-hover': ['var(--azgrid-fg, var(--azgrid-preset-fg))', '#ececec', 'Hovered row text'],
29
+ 'row-bg-selected': ['#dce0f2', '#655c3e', 'Selected rows and cells'],
30
+ 'row-fg-selected': ['var(--azgrid-fg, var(--azgrid-preset-fg))', '#fff', 'Selected row text'],
31
+ 'row-bg-active': ['#ebedf7', '#4f575f', 'Active rows'],
32
+ 'cell-border': ['rgba(1, 1, 1, .1)', '#4f575f', 'Cell borders'],
33
+ 'cell-border-width': ['0.1px', '0.1px', 'Cell border width'],
34
+ 'cell-padding': ['0 8px', '0 8px', 'Ordinary data cell padding; expand/reorder tools keep their layout'],
35
+ 'filter-bg': ['var(--azgrid-bg, var(--azgrid-preset-bg))', 'var(--azgrid-bg, var(--azgrid-preset-bg))', 'Filter row and input background, also editors and search'],
36
+ 'filter-fg': ['var(--azgrid-fg, var(--azgrid-preset-fg))', 'var(--azgrid-fg, var(--azgrid-preset-fg))', 'Filter input and editor text'],
37
+ 'filter-border': ['var(--azgrid-border, var(--azgrid-preset-border))', 'var(--azgrid-border, var(--azgrid-preset-border))', 'Filter input borders'],
38
+ 'filter-placeholder': ['var(--azgrid-muted-fg, var(--azgrid-preset-muted-fg))', 'var(--azgrid-muted-fg, var(--azgrid-preset-muted-fg))', 'Input placeholder text'],
39
+ 'filter-focus-ring': ['var(--azgrid-accent, var(--azgrid-preset-accent))', 'var(--azgrid-accent, var(--azgrid-preset-accent))', 'Focused input border and ring'],
40
+ 'pagination-bg': ['var(--azgrid-bg, var(--azgrid-preset-bg))', 'var(--azgrid-bg, var(--azgrid-preset-bg))', 'Pagination toolbar, page number and page size controls'],
41
+ 'pagination-fg': ['var(--azgrid-fg, var(--azgrid-preset-fg))', 'var(--azgrid-fg, var(--azgrid-preset-fg))', 'Pagination text and icons'],
42
+ 'pagination-border': ['var(--azgrid-border, var(--azgrid-preset-border))', 'var(--azgrid-border, var(--azgrid-preset-border))', 'Pagination control borders'],
43
+ 'menu-bg': ['var(--azgrid-bg, var(--azgrid-preset-bg))', 'var(--azgrid-bg, var(--azgrid-preset-bg))', 'Column, filter, context, select menus and date pickers'],
44
+ 'menu-fg': ['var(--azgrid-fg, var(--azgrid-preset-fg))', 'var(--azgrid-fg, var(--azgrid-preset-fg))', 'Menu text and icons'],
45
+ 'menu-border': ['var(--azgrid-border, var(--azgrid-preset-border))', 'var(--azgrid-border, var(--azgrid-preset-border))', 'Menu borders and separators'],
46
+ 'menu-bg-hover': ['var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover))', 'var(--azgrid-row-bg-hover, var(--azgrid-preset-row-bg-hover))', 'Hovered/focused menu entries'],
47
+ 'scrollbar-track': ['#f1f1f1', '#313943', 'Native and Inovua scrollbar tracks'],
48
+ 'scrollbar-thumb': ['#b5b5b5', '#697582', 'Native and Inovua scrollbar thumbs'],
49
+ 'empty-bg': ['var(--azgrid-bg, var(--azgrid-preset-bg))', 'var(--azgrid-bg, var(--azgrid-preset-bg))', 'Empty state background'],
50
+ 'empty-fg': ['var(--azgrid-fg, var(--azgrid-preset-fg))', 'var(--azgrid-fg, var(--azgrid-preset-fg))', 'No records text'],
51
+ 'loading-bg': ['rgba(255, 255, 255, .8)', 'rgba(49, 57, 67, .8)', 'Loading overlay background'],
52
+ 'loading-fg': ['var(--azgrid-fg, var(--azgrid-preset-fg))', 'var(--azgrid-fg, var(--azgrid-preset-fg))', 'Loading text and spinner'],
53
+ 'tree-bg': ['var(--azgrid-row-bg-even, var(--azgrid-preset-row-bg-even))', 'var(--azgrid-row-bg-even, var(--azgrid-preset-row-bg-even))', 'Tree/group row background'],
54
+ 'tree-fg': ['var(--azgrid-fg, var(--azgrid-preset-fg))', 'var(--azgrid-fg, var(--azgrid-preset-fg))', 'Tree/group text and expand icons'],
55
+ 'details-bg': ['var(--azgrid-bg, var(--azgrid-preset-bg))', 'var(--azgrid-bg, var(--azgrid-preset-bg))', 'Row details background'],
56
+ 'locked-column-shadow': ['0 0 5px rgba(0, 0, 0, .2)', '0 0 5px rgba(0, 0, 0, .5)', 'Locked column separator shadow (complete CSS box-shadow value)'],
57
+ };
58
+ const variable = name => `var(--azgrid-${name}, var(--azgrid-preset-${name}))`;
59
+ const colour = /#[\da-f]{3,8}\b|(?:rgba?|hsla?)\([^)]*\)|\b(?:transparent|white|black|grey|gray|red|blue|silver)\b/gi;
60
+ function tokenFor(selector, prop, literal) {
61
+ const bg = /background/.test(prop);
62
+ const border = /border|outline/.test(prop);
63
+ if (literal === 'transparent') return 'transparent';
64
+ if (/shadow/.test(prop)) return 'shadow-color';
65
+ if (/scroll.*(?:thumb)|(?:thumb).*scroll/.test(selector)) return 'scrollbar-thumb';
66
+ if (/scroll.*(?:track)|scrollbar/.test(selector)) return 'scrollbar-track';
67
+ if (/loader-spinner/.test(selector)) return literal === '#7986cb' ? 'accent' : 'muted-fg';
68
+ if (/loader-loadbar/.test(selector)) return 'loading-fg';
69
+ if (/load-mask|loading/.test(selector)) return bg ? 'loading-bg' : 'loading-fg';
70
+ if (/empty/.test(selector)) return bg ? 'empty-bg' : 'empty-fg';
71
+ if (/placeholder/.test(selector)) return 'filter-placeholder';
72
+ if (/sort-icon|selection-dragger|active-borders|checkbox/.test(selector)) {
73
+ if (/unchecked|disabled/.test(selector)) return 'muted-fg';
74
+ if (prop === 'stroke') return 'bg';
75
+ return /color/.test(prop) ? 'fg' : 'accent';
76
+ }
77
+ if (/cell__selection/.test(selector)) return bg ? 'row-bg-selected' : 'accent';
78
+ if (/menu|combo-box__list|calendar|date-input__picker/.test(selector) && !/column-header__menu-tool/.test(selector)) {
79
+ return border ? 'menu-border' : bg ? (/over|hover|focused|selected|active/.test(selector) ? 'menu-bg-hover' : 'menu-bg') : 'menu-fg';
80
+ }
81
+ if (/pagination/.test(selector)) return border ? 'pagination-border' : bg ? 'pagination-bg' : 'pagination-fg';
82
+ if (/focused|:focus/.test(selector) && border) return 'filter-focus-ring';
83
+ if (/filter|text-input|number-input|numeric-input|date-input|combo-box|editor/.test(selector)) return border ? 'filter-border' : bg ? 'filter-bg' : 'filter-fg';
84
+ if (/row-details/.test(selector)) return border ? 'border' : bg ? 'details-bg' : 'fg';
85
+ if (border) return /header/.test(selector) ? 'header-border' : /cell/.test(selector) ? 'cell-border' : 'border';
86
+ if (/row.*(?:selected)|cell--cell-selected/.test(selector)) return bg ? 'row-bg-selected' : 'row-fg-selected';
87
+ if (/hover|--over/.test(selector)) return bg ? 'row-bg-hover' : 'row-fg-hover';
88
+ if (/row--active|cell--cell-active/.test(selector)) return bg ? 'row-bg-active' : 'fg';
89
+ if (/header/.test(selector)) return bg ? 'header-bg' : 'header-fg';
90
+ if (/group-row|node-tool|tree/.test(selector)) return bg ? 'tree-bg' : 'tree-fg';
91
+ if (/row--odd/.test(selector)) return bg ? 'row-bg-odd' : 'fg';
92
+ if (/row--even|row--no-zebra/.test(selector)) return bg ? 'row-bg-even' : 'fg';
93
+ return bg ? 'bg' : /fill|stroke/.test(prop) ? 'muted-fg' : 'fg';
94
+ }
95
+ let css = '/* Token overrides for Inovua 5.10.2. Generated by config/generate-theme.cjs.\n * index.css retains layout and icons. Public tokens are inherited; preset tokens\n * are fallback implementation details. Do not set public defaults on the root. */\n';
96
+ for (const [index, selector] of [[0, '.azgrid-scope, .azgrid, .azgrid-theme-light'], [1, '.azgrid-theme-dark']]) {
97
+ css += `${selector} {\n`;
98
+ for (const [name, values] of Object.entries(tokens)) css += `\t--azgrid-preset-${name}: ${values[index]};\n`;
99
+ css += '}\n\n';
100
+ }
101
+ const upstream = postcss.parse(fs.readFileSync('node_modules/@inovua/reactdatagrid-enterprise/index.css', 'utf8'));
102
+ upstream.walkRules(rule => {
103
+ if (!rule.selector || rule.parent.type === 'atrule') return;
104
+ const declarations = [];
105
+ for (const d of rule.nodes) {
106
+ // The configurable first-row border is supplied in theme-extras.css.
107
+ if (/__row--first /.test(rule.selector) && d.prop === 'border-top') continue;
108
+ if (d.type !== 'decl' || !/^(color|background.*|.*border.*|outline.*|fill|stroke|.*shadow|font-family)$/.test(d.prop)) continue;
109
+ let value = d.value.replace(colour, literal => variable(tokenFor(rule.selector, d.prop, literal.toLowerCase())));
110
+ if (/^border(?:-(?:top|right|bottom|left))?$|^border.*width$/.test(d.prop)
111
+ && /\.InovuaReactDataGrid__cell(?=[\s.:]|$)/.test(rule.selector)
112
+ && !/selection/.test(rule.selector)) {
113
+ value = value.replace(/\b\d*\.?\d+(?:px|em|rem)\b/g, variable('cell-border-width'));
114
+ }
115
+ if (d.prop === 'font-family') value = variable('font-family');
116
+ if (value === d.value) continue;
117
+ if (d.important) declarations.push('\t/* Inovua declares this border !important; specificity cannot override it. */');
118
+ declarations.push(`\t${d.prop}: ${value}${d.important ? ' !important' : ''};`);
119
+ }
120
+ if (!declarations.length) return;
121
+ const selectors = rule.selectors.map(selector => selector.startsWith('.InovuaReactDataGrid--') || /^\.InovuaReactDataGrid(?=[\s.:#>]|$)/.test(selector)
122
+ ? '.azgrid' + selector : '.azgrid-scope ' + selector);
123
+ css += `${selectors.join(',\n')} {\n${declarations.join('\n')}\n}\n\n`;
124
+ });
125
+ css += fs.readFileSync('config/theme-extras.css', 'utf8');
126
+ fs.writeFileSync('src/themes/azgrid-theme.css', css);
127
+ // The same manifest supplies the complete public API table in the README.
128
+ const readme = fs.readFileSync('README.md', 'utf8');
129
+ const table = '| Variable | Controls | Light / dark fallback |\n| --- | --- | --- |\n' + Object.entries(tokens).map(([name, values]) => `| \`--azgrid-${name}\` | ${values[2]} | ${values[0] === values[1] ? `\`${values[0]}\`` : `\`${values[0]}\` / \`${values[1]}\``} |`).join('\n');
130
+ fs.writeFileSync('README.md', readme
131
+ .replace(/<!-- azgrid-tokens -->[\s\S]*?<!-- \/azgrid-tokens -->/, `<!-- azgrid-tokens -->\n${table}\n<!-- /azgrid-tokens -->`)
132
+ .replace(/<!-- azgrid-deco -->[\s\S]*?<!-- \/azgrid-deco -->/, '<!-- azgrid-deco -->\n```css\n' + fs.readFileSync('src/themes/example-palettes.css', 'utf8') + '\n```\n<!-- /azgrid-deco -->'));
@@ -0,0 +1,107 @@
1
+ /* Additional surfaces and typography not assigned colours by Inovua. */
2
+ .azgrid.InovuaReactDataGrid.InovuaReactDataGrid--theme-default-light .InovuaReactDataGrid__row--active:not(.InovuaReactDataGrid__row--selected) .InovuaReactDataGrid__cell:not(.InovuaReactDataGrid__cell--no-background) {
3
+ background: var(--azgrid-row-bg-active, var(--azgrid-preset-row-bg-active));
4
+ }
5
+ .azgrid.azgrid-tree .InovuaReactDataGrid__row:not(.InovuaReactDataGrid__row--selected):not(.InovuaReactDataGrid__row--active) .InovuaReactDataGrid__row-hover-target:not(:hover),
6
+ .azgrid .InovuaReactDataGrid__row--group-row:not(.InovuaReactDataGrid__row--selected):not(.InovuaReactDataGrid__row--active) .InovuaReactDataGrid__row-hover-target:not(:hover) {
7
+ background: var(--azgrid-tree-bg, var(--azgrid-preset-tree-bg));
8
+ color: var(--azgrid-tree-fg, var(--azgrid-preset-tree-fg));
9
+ }
10
+ .azgrid.azgrid-tree .InovuaReactDataGrid__cell__content > svg,
11
+ .azgrid .InovuaReactDataGrid__cell--group-expand-cell svg {
12
+ fill: var(--azgrid-tree-fg, var(--azgrid-preset-tree-fg));
13
+ }
14
+ .azgrid.InovuaReactDataGrid {
15
+ background: var(--azgrid-bg, var(--azgrid-preset-bg));
16
+ color: var(--azgrid-fg, var(--azgrid-preset-fg));
17
+ border-color: var(--azgrid-border, var(--azgrid-preset-border));
18
+ border-radius: var(--azgrid-radius, var(--azgrid-preset-radius));
19
+ font-family: var(--azgrid-font-family, var(--azgrid-preset-font-family));
20
+ }
21
+ .azgrid .InovuaReactDataGrid__column-header__content,
22
+ .azgrid .InovuaReactDataGrid__header-group__title {
23
+ color: var(--azgrid-header-fg, var(--azgrid-preset-header-fg));
24
+ font-size: var(--azgrid-header-font-size, var(--azgrid-preset-header-font-size));
25
+ font-weight: var(--azgrid-header-font-weight, var(--azgrid-preset-header-font-weight));
26
+ text-transform: var(--azgrid-header-text-transform, var(--azgrid-preset-header-text-transform));
27
+ letter-spacing: var(--azgrid-header-letter-spacing, var(--azgrid-preset-header-letter-spacing));
28
+ }
29
+ .azgrid.InovuaReactDataGrid--theme-default-light .InovuaReactDataGrid__cell {
30
+ border: var(--azgrid-cell-border-width, var(--azgrid-preset-cell-border-width)) solid var(--azgrid-cell-border, var(--azgrid-preset-cell-border));
31
+ }
32
+ .azgrid.InovuaReactDataGrid--theme-default-light .InovuaReactDataGrid__row--first .InovuaReactDataGrid__cell {
33
+ /* Inovua's first-row border-top is !important. Keep the same border API on this row. */
34
+ border-top: var(--azgrid-cell-border-width, var(--azgrid-preset-cell-border-width)) solid var(--azgrid-cell-border, var(--azgrid-preset-cell-border)) !important;
35
+ }
36
+ .azgrid.InovuaReactDataGrid--theme-default-light .InovuaReactDataGrid__cell:not(.InovuaReactDataGrid__cell--group-expand-cell):not(.InovuaReactDataGrid__cell--expand-cell):not(.InovuaReactDataGrid__cell--reorder) {
37
+ padding: var(--azgrid-cell-padding, var(--azgrid-preset-cell-padding));
38
+ }
39
+ .azgrid .InovuaReactDataGrid__empty-wrapper {
40
+ background: var(--azgrid-empty-bg, var(--azgrid-preset-empty-bg));
41
+ color: var(--azgrid-empty-fg, var(--azgrid-preset-empty-fg));
42
+ }
43
+ .azgrid.InovuaReactDataGrid--theme-default-light .InovuaReactDataGrid__row-details {
44
+ background: var(--azgrid-details-bg, var(--azgrid-preset-details-bg));
45
+ }
46
+ .azgrid .InovuaReactDataGrid__cell--locked-start.InovuaReactDataGrid__cell--last-in-section:after,
47
+ .azgrid .InovuaReactDataGrid__cell--locked-end.InovuaReactDataGrid__cell--first-in-section:after {
48
+ box-shadow: var(--azgrid-locked-column-shadow, var(--azgrid-preset-locked-column-shadow));
49
+ }
50
+ .azgrid-scope input,
51
+ .azgrid-scope select,
52
+ .azgrid-scope .azgrid-searcharea {
53
+ color: var(--azgrid-filter-fg, var(--azgrid-preset-filter-fg));
54
+ background-color: var(--azgrid-filter-bg, var(--azgrid-preset-filter-bg));
55
+ border-color: var(--azgrid-filter-border, var(--azgrid-preset-filter-border));
56
+ border-radius: var(--azgrid-radius, var(--azgrid-preset-radius));
57
+ font-family: var(--azgrid-font-family, var(--azgrid-preset-font-family));
58
+ }
59
+ .azgrid-scope input::placeholder {
60
+ color: var(--azgrid-filter-placeholder, var(--azgrid-preset-filter-placeholder));
61
+ }
62
+ .azgrid-scope input:focus-visible,
63
+ .azgrid-scope select:focus-visible {
64
+ outline: 1px solid var(--azgrid-filter-focus-ring, var(--azgrid-preset-filter-focus-ring));
65
+ }
66
+ .azgrid-scope .inovua-react-pagination-toolbar input,
67
+ .azgrid-scope .inovua-react-pagination-toolbar select {
68
+ background: var(--azgrid-pagination-bg, var(--azgrid-preset-pagination-bg));
69
+ color: var(--azgrid-pagination-fg, var(--azgrid-preset-pagination-fg));
70
+ border-color: var(--azgrid-pagination-border, var(--azgrid-preset-pagination-border));
71
+ }
72
+ .azgrid-scope .inovua-react-toolkit-text-input,
73
+ .azgrid-scope .inovua-react-toolkit-combo-box,
74
+ .azgrid-scope .inovua-react-toolkit-menu {
75
+ border-radius: var(--azgrid-radius, var(--azgrid-preset-radius));
76
+ }
77
+ /* Three classes exceed MUI's generated Paper/MenuItem selector specificity. */
78
+ .azgrid-scope .azgrid-context-menu.MuiPaper-root {
79
+ background: var(--azgrid-menu-bg, var(--azgrid-preset-menu-bg));
80
+ color: var(--azgrid-menu-fg, var(--azgrid-preset-menu-fg));
81
+ border: 1px solid var(--azgrid-menu-border, var(--azgrid-preset-menu-border));
82
+ border-radius: var(--azgrid-radius, var(--azgrid-preset-radius));
83
+ box-shadow: 0 3px 8px var(--azgrid-shadow-color, var(--azgrid-preset-shadow-color));
84
+ font-family: var(--azgrid-font-family, var(--azgrid-preset-font-family));
85
+ }
86
+ .azgrid-scope .azgrid-context-menu .MuiTypography-root,
87
+ .azgrid-scope .azgrid-context-menu .MuiMenuItem-root {
88
+ color: inherit;
89
+ font-family: inherit;
90
+ }
91
+ .azgrid-scope .azgrid-context-menu .MuiMenuItem-root:hover,
92
+ .azgrid-scope .azgrid-context-menu .MuiMenuItem-root.Mui-focusVisible {
93
+ background: var(--azgrid-menu-bg-hover, var(--azgrid-preset-menu-bg-hover));
94
+ }
95
+ .azgrid-scope, .azgrid-scope * {
96
+ accent-color: var(--azgrid-accent, var(--azgrid-preset-accent));
97
+ scrollbar-color: var(--azgrid-scrollbar-thumb, var(--azgrid-preset-scrollbar-thumb)) var(--azgrid-scrollbar-track, var(--azgrid-preset-scrollbar-track));
98
+ }
99
+ .azgrid-scope ::-webkit-scrollbar-track {
100
+ background: var(--azgrid-scrollbar-track, var(--azgrid-preset-scrollbar-track));
101
+ }
102
+ .azgrid-scope ::-webkit-scrollbar-thumb {
103
+ background: var(--azgrid-scrollbar-thumb, var(--azgrid-preset-scrollbar-thumb));
104
+ }
105
+ .azgrid .InovuaReactDataGrid__row.deleted:after {
106
+ border-color: var(--azgrid-muted-fg, var(--azgrid-preset-muted-fg));
107
+ }
@@ -1,4 +1,6 @@
1
1
  export * from './views/DataGrid';
2
2
  import React from 'react';
3
+ import './themes/azgrid-theme.css';
4
+ import './themes/example-palettes.css';
3
5
  export declare function ExampleGrid(): React.JSX.Element;
4
6
  export default ExampleGrid;
@@ -21,9 +21,10 @@ Object.keys(_DataGrid).forEach(function (key) {
21
21
  });
22
22
  });
23
23
  var _react = _interopRequireDefault(require("react"));
24
+ require("./themes/azgrid-theme.css");
25
+ require("./themes/example-palettes.css");
24
26
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
25
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
26
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
27
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
27
28
  const columns = [{
28
29
  name: 'name',
29
30
  title: 'Name',
@@ -139,9 +140,24 @@ function ExampleGrid() {
139
140
  content: product.name
140
141
  }];
141
142
  }, []);
142
- return _react.default.createElement(_DataGrid.default, {
143
+ return _react.default.createElement("div", {
144
+ style: {
145
+ display: 'grid',
146
+ gap: 20,
147
+ height: '100%',
148
+ overflow: 'auto'
149
+ }
150
+ }, ['light', 'dark', 'deco'].map(theme => _react.default.createElement("section", {
151
+ key: theme,
152
+ className: theme === 'deco' ? 'azgrid-example-deco' : undefined,
153
+ style: {
154
+ height: 360,
155
+ display: 'flex',
156
+ flexDirection: 'column'
157
+ }
158
+ }, _react.default.createElement("h3", null, theme === 'deco' ? 'Art Deco (host variables)' : `Default ${theme}`), _react.default.createElement(_DataGrid.default, {
159
+ theme: theme,
143
160
  delayedSize: true,
144
- dark: true,
145
161
  // details_dataSource={details_dataSource}
146
162
  dataSource: dataSource,
147
163
  details_columns: columns,
@@ -159,6 +175,17 @@ function ExampleGrid() {
159
175
  advancedFilterFields: ['name'],
160
176
  // leftColumns={leftColumns}
161
177
  gridOptions: {
178
+ defaultFilterValue: [{
179
+ name: 'name',
180
+ operator: 'contains',
181
+ type: 'string',
182
+ value: ''
183
+ }],
184
+ pagination: 'local',
185
+ defaultLimit: 10,
186
+ pageSizes: [10, 25, 50],
187
+ checkboxColumn: true,
188
+ multiSelect: true
162
189
  // defaultFilterValue: filterValue,
163
190
  // remoteFilter: false,
164
191
  // multiSelect: true,
@@ -169,6 +196,6 @@ function ExampleGrid() {
169
196
  // rowIndexColumn: true,
170
197
  // checkboxColumn: true,
171
198
  }
172
- });
199
+ }))));
173
200
  }
174
201
  var _default = exports.default = ExampleGrid;
package/dist/src/index.js CHANGED
@@ -59,17 +59,18 @@ Object.keys(_types).forEach(function (key) {
59
59
  });
60
60
  });
61
61
  var _func_grid = require("./func/func_grid");
62
- var _example = _interopRequireDefault(require("./example"));
63
62
  var _react = _interopRequireDefault(require("react"));
64
63
  var _client = _interopRequireDefault(require("react-dom/client"));
65
64
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
66
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
67
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
65
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
68
66
  /* -------------------------------------------------------------------------- */
69
67
  //
70
68
  var _default = exports.default = _DataGrid.default;
71
- const testroot = document.getElementById('testroot');
69
+ const testroot = typeof document === 'undefined' ? null : document.getElementById('testroot');
72
70
  if (testroot) {
73
- const root = _client.default.createRoot(document.getElementById('testroot'));
74
- root.render(_react.default.createElement(_example.default, null));
71
+ const root = _client.default.createRoot(testroot);
72
+ // Example styles, including the optional token theme, load only for the demo.
73
+ Promise.resolve().then(() => _interopRequireWildcard(require('./example'))).then(({
74
+ default: ExampleGrid
75
+ }) => root.render(_react.default.createElement(ExampleGrid, null)));
75
76
  }