@ornery/ui-grid-vanilla 0.1.9 → 1.0.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 (63) hide show
  1. package/README.md +196 -0
  2. package/demo/index.html +3 -3
  3. package/demo/main.ts +1 -1
  4. package/dist/index.d.mts +584 -55
  5. package/dist/index.d.ts +584 -55
  6. package/dist/index.js +4887 -1404
  7. package/dist/index.mjs +5056 -1526
  8. package/package.json +11 -8
  9. package/scss-plugin.ts +65 -0
  10. package/src/adopt-styles.ts +39 -0
  11. package/src/attribute-bridge.ts +291 -0
  12. package/src/auto-height.test.ts +142 -0
  13. package/src/auto-resize.test.ts +206 -0
  14. package/src/cell-nav.test.ts +262 -0
  15. package/src/components/grid-body-cell/grid-body-cell.ts +23 -0
  16. package/src/components/grid-body-cell/index.ts +1 -0
  17. package/src/components/grid-cell-editor/grid-cell-editor.ts +104 -0
  18. package/src/components/grid-cell-editor/index.ts +1 -0
  19. package/src/components/grid-filter-cell/grid-filter-cell.scss +14 -0
  20. package/src/components/grid-filter-cell/grid-filter-cell.template.ts +20 -0
  21. package/src/components/grid-filter-cell/grid-filter-cell.ts +121 -0
  22. package/src/components/grid-filter-cell/index.ts +1 -0
  23. package/src/components/grid-group-row/grid-group-row.scss +24 -0
  24. package/src/components/grid-group-row/grid-group-row.template.ts +23 -0
  25. package/src/components/grid-group-row/grid-group-row.ts +94 -0
  26. package/src/components/grid-group-row/index.ts +1 -0
  27. package/src/components/grid-header-cell/grid-header-cell.ts +17 -0
  28. package/src/components/grid-header-cell/index.ts +1 -0
  29. package/src/components/grid-pagination/grid-pagination.scss +39 -0
  30. package/src/components/grid-pagination/grid-pagination.template.ts +40 -0
  31. package/src/components/grid-pagination/grid-pagination.ts +204 -0
  32. package/src/components/grid-pagination/index.ts +1 -0
  33. package/src/components/grid-template/grid-template.ts +166 -0
  34. package/src/components/grid-template/index.ts +1 -0
  35. package/src/events.ts +815 -0
  36. package/src/exporter.test.ts +186 -0
  37. package/src/focus.ts +353 -0
  38. package/src/framework-slots.ts +440 -0
  39. package/src/grid-controller.ts +1431 -20
  40. package/src/icons.ts +88 -0
  41. package/src/importer.test.ts +147 -0
  42. package/src/index.integration.test.ts +2 -2
  43. package/src/index.ts +9 -0
  44. package/src/infinite-scroll.test.ts +220 -0
  45. package/src/keyboard-navigation.test.ts +579 -0
  46. package/src/patch.ts +722 -0
  47. package/src/render.ts +465 -0
  48. package/src/row-edit.test.ts +191 -0
  49. package/src/row-selection.test.ts +550 -0
  50. package/src/save-state.test.ts +235 -0
  51. package/src/scss.d.ts +4 -0
  52. package/src/templates/index.ts +62 -0
  53. package/src/test-setup.ts +23 -0
  54. package/src/ui-grid-empty.template.ts +23 -0
  55. package/src/ui-grid-shell.scss +25 -0
  56. package/src/ui-grid-shell.template.ts +45 -0
  57. package/src/ui-grid-standalone.element.ts +751 -1032
  58. package/src/utils/cell-class.ts +70 -0
  59. package/src/utils/display-items.ts +15 -0
  60. package/src/utils/dom.ts +64 -0
  61. package/src/validate.test.ts +170 -0
  62. package/tsup.config.ts +10 -0
  63. package/vite.config.ts +10 -1
package/README.md ADDED
@@ -0,0 +1,196 @@
1
+ # @ornery/ui-grid-vanilla
2
+
3
+ A vanilla Web Components wrapper for `@ornery/ui-grid-core`. Renders a high-performance data grid as a custom element with no framework dependency.
4
+
5
+ ## Architecture
6
+
7
+ The grid is built as a composition of autonomous custom elements, each following the `@ornery/web-components` pattern:
8
+
9
+ ```
10
+ <ui-grid-element> ← main grid element (shadow DOM)
11
+ ├── ui-grid-shell.html ← declarative grid layout template
12
+ ├── ui-grid-empty.html ← empty/no-options state template
13
+ │
14
+ ├── <ui-grid-header-cell> ← column header (sort, group, pin, resize)
15
+ ├── <ui-grid-filter-cell> ← column filter input (shadow DOM + .html template)
16
+ ├── <ui-grid-body-cell> ← data cell (class-managed, perf-optimized)
17
+ ├── <ui-grid-group-row> ← grouping disclosure row (shadow DOM + .html template)
18
+ ├── <ui-grid-pagination> ← pagination controls (shadow DOM + .html template)
19
+ └── <ui-grid-template> ← declarative reusable template factory
20
+ ```
21
+
22
+ ### Component Pattern
23
+
24
+ Components follow the standard `@ornery/web-components` lifecycle:
25
+
26
+ ```js
27
+ import template from './my-component.html';
28
+
29
+ class MyComponent extends HTMLElement {
30
+ // 1. Attach shadow DOM in constructor
31
+ constructor() {
32
+ super();
33
+ this.attachShadow({ mode: 'open' });
34
+ }
35
+
36
+ // 2. Declare instance properties as template context
37
+ myProp = 'default';
38
+
39
+ // 3. Render in connectedCallback
40
+ connectedCallback() {
41
+ this.myProp = this.getAttribute('data-my-prop') ?? 'default';
42
+ template(this).connect(); // auto-renders into shadowRoot
43
+ }
44
+ }
45
+ ```
46
+
47
+ The `.html` template uses ES6 template literal syntax:
48
+ ```html
49
+ <div class="my-class">${this.myProp}</div>
50
+ ```
51
+
52
+ Templates are compiled at build time by `@ornery/web-components/vite` (or `/webpack`, `/esbuild`, `/rollup`).
53
+
54
+ ### Performance Strategy
55
+
56
+ - **Hot-path components** (`ui-grid-body-cell`, `ui-grid-header-cell`) skip `template().connect()` entirely — the parent pre-renders innerHTML as a string, and the component only manages CSS classes via `attributeChangedCallback`. This avoids DOM construction overhead per cell.
57
+ - **Low-frequency components** (`ui-grid-filter-cell`, `ui-grid-group-row`, `ui-grid-pagination`) use full `template(this).connect()` with shadow DOM for encapsulation and declarative rendering.
58
+
59
+ ### Template Bindings
60
+
61
+ Cell and row slot templates support dual binding syntax:
62
+
63
+ | Syntax | Example | Description |
64
+ |--------|---------|-------------|
65
+ | `{{ }}` | `{{value}}` | Mustache-style, original grid syntax |
66
+ | `${ }` | `${this.value}` | ES6 template literal, `@ornery/web-components` native |
67
+
68
+ Both resolve against the same context: `{ $implicit, value, valueText, row, column, rowIndex }`.
69
+
70
+ ## Installation
71
+
72
+ ```bash
73
+ npm install @ornery/ui-grid-vanilla @ornery/ui-grid-core
74
+ ```
75
+
76
+ ## Usage
77
+
78
+ ### Imperative (JavaScript)
79
+
80
+ ```js
81
+ import { mountVanillaUiGrid } from '@ornery/ui-grid-vanilla';
82
+
83
+ const grid = await mountVanillaUiGrid(document.getElementById('grid'), {
84
+ id: 'my-grid',
85
+ columnDefs: [
86
+ { name: 'name', field: 'name', displayName: 'Name' },
87
+ { name: 'age', field: 'age', displayName: 'Age', align: 'end' },
88
+ ],
89
+ data: [
90
+ { name: 'Alice', age: 30 },
91
+ { name: 'Bob', age: 25 },
92
+ ],
93
+ enableSorting: true,
94
+ enableFiltering: true,
95
+ });
96
+ ```
97
+
98
+ ### Declarative (HTML attributes)
99
+
100
+ ```html
101
+ <ui-grid-element
102
+ grid-id="my-grid"
103
+ enable-sorting
104
+ enable-filtering
105
+ column-defs='[{"name":"name","field":"name"},{"name":"age","field":"age","align":"end"}]'
106
+ data='[{"name":"Alice","age":30},{"name":"Bob","age":25}]'>
107
+ </ui-grid-element>
108
+ ```
109
+
110
+ ### Custom Cell Templates (slots)
111
+
112
+ ```html
113
+ <ui-grid-element id="grid">
114
+ <!-- Mustache syntax -->
115
+ <template slot="cell-name">
116
+ <strong>{{value}}</strong>
117
+ </template>
118
+
119
+ <!-- ES6 syntax -->
120
+ <template slot="cell-age">
121
+ <span style="color: ${this.value > 30 ? 'red' : 'green'}">${this.value}</span>
122
+ </template>
123
+ </ui-grid-element>
124
+ ```
125
+
126
+ ### Declarative Reusable Templates
127
+
128
+ Define reusable components from HTML alone with `<template is="ui-grid-template">`:
129
+
130
+ ```html
131
+ <!-- Define a badge component -->
132
+ <template is="ui-grid-template" name="ui-status-badge" status="unknown">
133
+ <style>
134
+ :host { display: inline-block; }
135
+ .badge { padding: 2px 8px; border-radius: 4px; }
136
+ .badge-active { background: #d1fae5; color: #065f46; }
137
+ .badge-inactive { background: #fee2e2; color: #991b1b; }
138
+ </style>
139
+ <span class="badge badge-${this.status}">${this.status}</span>
140
+ </template>
141
+
142
+ <!-- Use it in a grid cell slot -->
143
+ <ui-grid-element>
144
+ <template slot="cell-status">
145
+ <ui-status-badge status="{{value}}"></ui-status-badge>
146
+ </template>
147
+ </ui-grid-element>
148
+ ```
149
+
150
+ ## Bundler Setup
151
+
152
+ ### Vite
153
+
154
+ ```js
155
+ import { defineConfig } from 'vite';
156
+ import webComponents from '@ornery/web-components/vite';
157
+
158
+ export default defineConfig({
159
+ plugins: [webComponents()]
160
+ });
161
+ ```
162
+
163
+ ### Webpack 5
164
+
165
+ ```js
166
+ import webComponents from '@ornery/web-components/webpack';
167
+
168
+ export default {
169
+ plugins: [webComponents()]
170
+ };
171
+ ```
172
+
173
+ ### tsup (esbuild)
174
+
175
+ ```ts
176
+ import { defineConfig } from 'tsup';
177
+ import webComponents from '@ornery/web-components/esbuild';
178
+
179
+ export default defineConfig({
180
+ esbuildPlugins: [webComponents()],
181
+ });
182
+ ```
183
+
184
+ ## API
185
+
186
+ ### `mountVanillaUiGrid(target, options, rustModule?, tagName?)`
187
+ Mount a grid into a target element. Returns the grid element.
188
+
189
+ ### `defineStandaloneUiGridElement(tagName?)`
190
+ Register the `<ui-grid-element>` custom element (and all sub-components).
191
+
192
+ ### `UIGridTemplate`
193
+ Exported class for the `<template is="ui-grid-template">` element. Auto-registered when the grid is defined.
194
+
195
+ ### Grid Element Properties
196
+ See `VanillaUiGridElement` type — all `GridOptions` fields are available as both HTML attributes and JS properties.
package/demo/index.html CHANGED
@@ -179,7 +179,7 @@
179
179
  <p>
180
180
  Familiar <code>gridOptions</code> and <code>onRegisterApi</code>, rebuilt as a
181
181
  framework-neutral custom element with the Rust-backed pipeline, grouping, sorting,
182
- filtering, and virtualization.
182
+ filtering, Excel-style column resizing, and virtualization.
183
183
  </p>
184
184
  </div>
185
185
  <div class="grid-demo-actions">
@@ -210,8 +210,8 @@
210
210
  <div class="grid-demo-toolbar">
211
211
  <div><strong id="visible-rows-inline">0</strong> of <span id="total-rows-value">0</span> rows</div>
212
212
  <p>
213
- <code>gridOptions</code> compatibility layer: sorting, filtering, grouping, templating,
214
- and virtualized rendering.
213
+ <code>gridOptions</code> compatibility layer: sorting, filtering, grouping, column resizing,
214
+ templating, and virtualized rendering.
215
215
  </p>
216
216
  </div>
217
217
 
package/demo/main.ts CHANGED
@@ -24,10 +24,10 @@ const options: GridOptions = {
24
24
  title: 'UI Grid Vanilla Demo',
25
25
  emptyMessage: 'No rows match the current filters.',
26
26
  rowHeight: 48,
27
- viewportHeight: 620,
28
27
  enableSorting: true,
29
28
  enableFiltering: true,
30
29
  enableGrouping: true,
30
+ enableColumnResizing: true,
31
31
  enableVirtualization: true,
32
32
  virtualizationThreshold: 25,
33
33
  grouping: { groupBy: ['status'] },