@gridstorm/vue 0.1.2 → 0.1.3
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/LICENSE.md +21 -0
- package/README.md +209 -209
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GridStorm Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
# @gridstorm/vue
|
|
2
|
-
|
|
3
|
-
Vue 3 adapter for [GridStorm](https://grid-data-analytics-explorer.vercel.app/) -- a high-performance, headless data grid engine.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pnpm add @gridstorm/vue @gridstorm/core @gridstorm/dom-renderer
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Basic Usage
|
|
12
|
-
|
|
13
|
-
```vue
|
|
14
|
-
<script setup lang="ts">
|
|
15
|
-
import { ref } from 'vue';
|
|
16
|
-
import { GridStorm } from '@gridstorm/vue';
|
|
17
|
-
import type { ColumnDef, GridApi } from '@gridstorm/vue';
|
|
18
|
-
import { sortingPlugin } from '@gridstorm/plugin-sorting';
|
|
19
|
-
import { filterPlugin } from '@gridstorm/plugin-filtering';
|
|
20
|
-
|
|
21
|
-
interface Employee {
|
|
22
|
-
id: number;
|
|
23
|
-
name: string;
|
|
24
|
-
department: string;
|
|
25
|
-
salary: number;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const columns: ColumnDef<Employee>[] = [
|
|
29
|
-
{ field: 'name', headerName: 'Name', sortable: true },
|
|
30
|
-
{ field: 'department', headerName: 'Department', filter: true },
|
|
31
|
-
{ field: 'salary', headerName: 'Salary', width: 120 },
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
const rowData = ref<Employee[]>([
|
|
35
|
-
{ id: 1, name: 'Alice', department: 'Engineering', salary: 95000 },
|
|
36
|
-
{ id: 2, name: 'Bob', department: 'Marketing', salary: 72000 },
|
|
37
|
-
{ id: 3, name: 'Charlie', department: 'Engineering', salary: 88000 },
|
|
38
|
-
]);
|
|
39
|
-
|
|
40
|
-
const gridRef = ref<InstanceType<typeof GridStorm>>();
|
|
41
|
-
|
|
42
|
-
function onGridReady(api: GridApi<Employee>) {
|
|
43
|
-
console.log('Grid ready!', api.getDisplayedRowCount(), 'rows');
|
|
44
|
-
}
|
|
45
|
-
</script>
|
|
46
|
-
|
|
47
|
-
<template>
|
|
48
|
-
<GridStorm
|
|
49
|
-
ref="gridRef"
|
|
50
|
-
:columns="columns"
|
|
51
|
-
:row-data="rowData"
|
|
52
|
-
:plugins="[sortingPlugin(), filterPlugin()]"
|
|
53
|
-
:get-row-id="(params) => String(params.data.id)"
|
|
54
|
-
:row-height="40"
|
|
55
|
-
theme="light"
|
|
56
|
-
height="400px"
|
|
57
|
-
@grid-ready="onGridReady"
|
|
58
|
-
@sort-changed="(e) => console.log('Sort:', e)"
|
|
59
|
-
/>
|
|
60
|
-
</template>
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Composables
|
|
64
|
-
|
|
65
|
-
All composables must be used within a child component of `<GridStorm>`.
|
|
66
|
-
|
|
67
|
-
### useGridApi
|
|
68
|
-
|
|
69
|
-
Access the GridApi instance.
|
|
70
|
-
|
|
71
|
-
```vue
|
|
72
|
-
<script setup lang="ts">
|
|
73
|
-
import { useGridApi } from '@gridstorm/vue';
|
|
74
|
-
|
|
75
|
-
const api = useGridApi();
|
|
76
|
-
|
|
77
|
-
function refresh() {
|
|
78
|
-
api.value?.refreshCells();
|
|
79
|
-
}
|
|
80
|
-
</script>
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### useGridSort
|
|
84
|
-
|
|
85
|
-
Reactive sort model and sort actions.
|
|
86
|
-
|
|
87
|
-
```vue
|
|
88
|
-
<script setup lang="ts">
|
|
89
|
-
import { useGridSort } from '@gridstorm/vue';
|
|
90
|
-
|
|
91
|
-
const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();
|
|
92
|
-
</script>
|
|
93
|
-
|
|
94
|
-
<template>
|
|
95
|
-
<button @click="toggleSort('name')">Sort by Name</button>
|
|
96
|
-
<button v-if="isSorted" @click="clearSort()">Clear Sort</button>
|
|
97
|
-
</template>
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### useGridFilter
|
|
101
|
-
|
|
102
|
-
Reactive filter model and filter actions.
|
|
103
|
-
|
|
104
|
-
```vue
|
|
105
|
-
<script setup lang="ts">
|
|
106
|
-
import { useGridFilter } from '@gridstorm/vue';
|
|
107
|
-
|
|
108
|
-
const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();
|
|
109
|
-
</script>
|
|
110
|
-
|
|
111
|
-
<template>
|
|
112
|
-
<input
|
|
113
|
-
placeholder="Search..."
|
|
114
|
-
@input="(e) => setQuickFilter((e.target as HTMLInputElement).value)"
|
|
115
|
-
/>
|
|
116
|
-
<button v-if="isFiltered" @click="clearFilters()">Clear</button>
|
|
117
|
-
</template>
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### useGridSelection
|
|
121
|
-
|
|
122
|
-
Reactive selection state and selection actions.
|
|
123
|
-
|
|
124
|
-
```vue
|
|
125
|
-
<script setup lang="ts">
|
|
126
|
-
import { useGridSelection } from '@gridstorm/vue';
|
|
127
|
-
|
|
128
|
-
const { selectedCount, selectAll, deselectAll } = useGridSelection();
|
|
129
|
-
</script>
|
|
130
|
-
|
|
131
|
-
<template>
|
|
132
|
-
<p>{{ selectedCount }} rows selected</p>
|
|
133
|
-
<button @click="selectAll()">Select All</button>
|
|
134
|
-
<button @click="deselectAll()">Deselect All</button>
|
|
135
|
-
</template>
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### useGridPagination
|
|
139
|
-
|
|
140
|
-
Reactive pagination state and navigation.
|
|
141
|
-
|
|
142
|
-
```vue
|
|
143
|
-
<script setup lang="ts">
|
|
144
|
-
import { useGridPagination } from '@gridstorm/vue';
|
|
145
|
-
|
|
146
|
-
const {
|
|
147
|
-
currentPage,
|
|
148
|
-
totalPages,
|
|
149
|
-
hasNextPage,
|
|
150
|
-
hasPreviousPage,
|
|
151
|
-
nextPage,
|
|
152
|
-
previousPage,
|
|
153
|
-
} = useGridPagination();
|
|
154
|
-
</script>
|
|
155
|
-
|
|
156
|
-
<template>
|
|
157
|
-
<div class="pagination">
|
|
158
|
-
<button :disabled="!hasPreviousPage" @click="previousPage()">Prev</button>
|
|
159
|
-
<span>Page {{ currentPage + 1 }} of {{ totalPages }}</span>
|
|
160
|
-
<button :disabled="!hasNextPage" @click="nextPage()">Next</button>
|
|
161
|
-
</div>
|
|
162
|
-
</template>
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### useGridEvent
|
|
166
|
-
|
|
167
|
-
Subscribe to grid events with automatic cleanup.
|
|
168
|
-
|
|
169
|
-
```vue
|
|
170
|
-
<script setup lang="ts">
|
|
171
|
-
import { useGridEvent } from '@gridstorm/vue';
|
|
172
|
-
|
|
173
|
-
useGridEvent('selection:changed', (e) => {
|
|
174
|
-
console.log('Selection changed:', e.selectedNodes);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
useGridEvent('cell:clicked', (e) => {
|
|
178
|
-
console.log('Cell clicked:', e.colId, e.value);
|
|
179
|
-
});
|
|
180
|
-
</script>
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## Template Ref API
|
|
184
|
-
|
|
185
|
-
Access the grid API via a template ref:
|
|
186
|
-
|
|
187
|
-
```vue
|
|
188
|
-
<script setup lang="ts">
|
|
189
|
-
import { ref } from 'vue';
|
|
190
|
-
import { GridStorm } from '@gridstorm/vue';
|
|
191
|
-
|
|
192
|
-
const gridRef = ref<InstanceType<typeof GridStorm>>();
|
|
193
|
-
|
|
194
|
-
function exportSelected() {
|
|
195
|
-
const api = gridRef.value?.getApi();
|
|
196
|
-
const rows = api?.getSelectedRows() ?? [];
|
|
197
|
-
console.log('Selected rows:', rows);
|
|
198
|
-
}
|
|
199
|
-
</script>
|
|
200
|
-
|
|
201
|
-
<template>
|
|
202
|
-
<GridStorm ref="gridRef" :columns="columns" :row-data="rowData" />
|
|
203
|
-
<button @click="exportSelected">Export Selected</button>
|
|
204
|
-
</template>
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
## License
|
|
208
|
-
|
|
209
|
-
MIT
|
|
1
|
+
# @gridstorm/vue
|
|
2
|
+
|
|
3
|
+
Vue 3 adapter for [GridStorm](https://grid-data-analytics-explorer.vercel.app/) -- a high-performance, headless data grid engine.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @gridstorm/vue @gridstorm/core @gridstorm/dom-renderer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```vue
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { ref } from 'vue';
|
|
16
|
+
import { GridStorm } from '@gridstorm/vue';
|
|
17
|
+
import type { ColumnDef, GridApi } from '@gridstorm/vue';
|
|
18
|
+
import { sortingPlugin } from '@gridstorm/plugin-sorting';
|
|
19
|
+
import { filterPlugin } from '@gridstorm/plugin-filtering';
|
|
20
|
+
|
|
21
|
+
interface Employee {
|
|
22
|
+
id: number;
|
|
23
|
+
name: string;
|
|
24
|
+
department: string;
|
|
25
|
+
salary: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const columns: ColumnDef<Employee>[] = [
|
|
29
|
+
{ field: 'name', headerName: 'Name', sortable: true },
|
|
30
|
+
{ field: 'department', headerName: 'Department', filter: true },
|
|
31
|
+
{ field: 'salary', headerName: 'Salary', width: 120 },
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const rowData = ref<Employee[]>([
|
|
35
|
+
{ id: 1, name: 'Alice', department: 'Engineering', salary: 95000 },
|
|
36
|
+
{ id: 2, name: 'Bob', department: 'Marketing', salary: 72000 },
|
|
37
|
+
{ id: 3, name: 'Charlie', department: 'Engineering', salary: 88000 },
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
const gridRef = ref<InstanceType<typeof GridStorm>>();
|
|
41
|
+
|
|
42
|
+
function onGridReady(api: GridApi<Employee>) {
|
|
43
|
+
console.log('Grid ready!', api.getDisplayedRowCount(), 'rows');
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<template>
|
|
48
|
+
<GridStorm
|
|
49
|
+
ref="gridRef"
|
|
50
|
+
:columns="columns"
|
|
51
|
+
:row-data="rowData"
|
|
52
|
+
:plugins="[sortingPlugin(), filterPlugin()]"
|
|
53
|
+
:get-row-id="(params) => String(params.data.id)"
|
|
54
|
+
:row-height="40"
|
|
55
|
+
theme="light"
|
|
56
|
+
height="400px"
|
|
57
|
+
@grid-ready="onGridReady"
|
|
58
|
+
@sort-changed="(e) => console.log('Sort:', e)"
|
|
59
|
+
/>
|
|
60
|
+
</template>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Composables
|
|
64
|
+
|
|
65
|
+
All composables must be used within a child component of `<GridStorm>`.
|
|
66
|
+
|
|
67
|
+
### useGridApi
|
|
68
|
+
|
|
69
|
+
Access the GridApi instance.
|
|
70
|
+
|
|
71
|
+
```vue
|
|
72
|
+
<script setup lang="ts">
|
|
73
|
+
import { useGridApi } from '@gridstorm/vue';
|
|
74
|
+
|
|
75
|
+
const api = useGridApi();
|
|
76
|
+
|
|
77
|
+
function refresh() {
|
|
78
|
+
api.value?.refreshCells();
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### useGridSort
|
|
84
|
+
|
|
85
|
+
Reactive sort model and sort actions.
|
|
86
|
+
|
|
87
|
+
```vue
|
|
88
|
+
<script setup lang="ts">
|
|
89
|
+
import { useGridSort } from '@gridstorm/vue';
|
|
90
|
+
|
|
91
|
+
const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();
|
|
92
|
+
</script>
|
|
93
|
+
|
|
94
|
+
<template>
|
|
95
|
+
<button @click="toggleSort('name')">Sort by Name</button>
|
|
96
|
+
<button v-if="isSorted" @click="clearSort()">Clear Sort</button>
|
|
97
|
+
</template>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### useGridFilter
|
|
101
|
+
|
|
102
|
+
Reactive filter model and filter actions.
|
|
103
|
+
|
|
104
|
+
```vue
|
|
105
|
+
<script setup lang="ts">
|
|
106
|
+
import { useGridFilter } from '@gridstorm/vue';
|
|
107
|
+
|
|
108
|
+
const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
<template>
|
|
112
|
+
<input
|
|
113
|
+
placeholder="Search..."
|
|
114
|
+
@input="(e) => setQuickFilter((e.target as HTMLInputElement).value)"
|
|
115
|
+
/>
|
|
116
|
+
<button v-if="isFiltered" @click="clearFilters()">Clear</button>
|
|
117
|
+
</template>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### useGridSelection
|
|
121
|
+
|
|
122
|
+
Reactive selection state and selection actions.
|
|
123
|
+
|
|
124
|
+
```vue
|
|
125
|
+
<script setup lang="ts">
|
|
126
|
+
import { useGridSelection } from '@gridstorm/vue';
|
|
127
|
+
|
|
128
|
+
const { selectedCount, selectAll, deselectAll } = useGridSelection();
|
|
129
|
+
</script>
|
|
130
|
+
|
|
131
|
+
<template>
|
|
132
|
+
<p>{{ selectedCount }} rows selected</p>
|
|
133
|
+
<button @click="selectAll()">Select All</button>
|
|
134
|
+
<button @click="deselectAll()">Deselect All</button>
|
|
135
|
+
</template>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### useGridPagination
|
|
139
|
+
|
|
140
|
+
Reactive pagination state and navigation.
|
|
141
|
+
|
|
142
|
+
```vue
|
|
143
|
+
<script setup lang="ts">
|
|
144
|
+
import { useGridPagination } from '@gridstorm/vue';
|
|
145
|
+
|
|
146
|
+
const {
|
|
147
|
+
currentPage,
|
|
148
|
+
totalPages,
|
|
149
|
+
hasNextPage,
|
|
150
|
+
hasPreviousPage,
|
|
151
|
+
nextPage,
|
|
152
|
+
previousPage,
|
|
153
|
+
} = useGridPagination();
|
|
154
|
+
</script>
|
|
155
|
+
|
|
156
|
+
<template>
|
|
157
|
+
<div class="pagination">
|
|
158
|
+
<button :disabled="!hasPreviousPage" @click="previousPage()">Prev</button>
|
|
159
|
+
<span>Page {{ currentPage + 1 }} of {{ totalPages }}</span>
|
|
160
|
+
<button :disabled="!hasNextPage" @click="nextPage()">Next</button>
|
|
161
|
+
</div>
|
|
162
|
+
</template>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### useGridEvent
|
|
166
|
+
|
|
167
|
+
Subscribe to grid events with automatic cleanup.
|
|
168
|
+
|
|
169
|
+
```vue
|
|
170
|
+
<script setup lang="ts">
|
|
171
|
+
import { useGridEvent } from '@gridstorm/vue';
|
|
172
|
+
|
|
173
|
+
useGridEvent('selection:changed', (e) => {
|
|
174
|
+
console.log('Selection changed:', e.selectedNodes);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
useGridEvent('cell:clicked', (e) => {
|
|
178
|
+
console.log('Cell clicked:', e.colId, e.value);
|
|
179
|
+
});
|
|
180
|
+
</script>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Template Ref API
|
|
184
|
+
|
|
185
|
+
Access the grid API via a template ref:
|
|
186
|
+
|
|
187
|
+
```vue
|
|
188
|
+
<script setup lang="ts">
|
|
189
|
+
import { ref } from 'vue';
|
|
190
|
+
import { GridStorm } from '@gridstorm/vue';
|
|
191
|
+
|
|
192
|
+
const gridRef = ref<InstanceType<typeof GridStorm>>();
|
|
193
|
+
|
|
194
|
+
function exportSelected() {
|
|
195
|
+
const api = gridRef.value?.getApi();
|
|
196
|
+
const rows = api?.getSelectedRows() ?? [];
|
|
197
|
+
console.log('Selected rows:', rows);
|
|
198
|
+
}
|
|
199
|
+
</script>
|
|
200
|
+
|
|
201
|
+
<template>
|
|
202
|
+
<GridStorm ref="gridRef" :columns="columns" :row-data="rowData" />
|
|
203
|
+
<button @click="exportSelected">Export Selected</button>
|
|
204
|
+
</template>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -386,8 +386,19 @@ var GridStorm = vue.defineComponent({
|
|
|
386
386
|
engine = null;
|
|
387
387
|
gridContext.value = null;
|
|
388
388
|
}
|
|
389
|
+
const error = vue.ref(null);
|
|
390
|
+
vue.onErrorCaptured((err) => {
|
|
391
|
+
error.value = err;
|
|
392
|
+
console.error("[GridStorm Vue] Error captured:", err);
|
|
393
|
+
return false;
|
|
394
|
+
});
|
|
389
395
|
vue.onMounted(() => {
|
|
390
|
-
|
|
396
|
+
try {
|
|
397
|
+
initGrid();
|
|
398
|
+
} catch (err) {
|
|
399
|
+
error.value = err instanceof Error ? err : new Error(String(err));
|
|
400
|
+
console.error("[GridStorm Vue] Initialization error:", err);
|
|
401
|
+
}
|
|
391
402
|
});
|
|
392
403
|
vue.onBeforeUnmount(() => {
|
|
393
404
|
destroyGrid();
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/composables.ts","../src/GridStorm.ts"],"names":["inject","ref","watch","onUnmounted","computed","defineComponent","shallowRef","provide","createGrid","DomRenderer","onMounted","onBeforeUnmount","h"],"mappings":"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","file":"index.cjs","sourcesContent":["// ─── Vue Adapter Types ───\n// Central type definitions for all Vue-specific interfaces.\n\nimport type {\n ColumnDef,\n GridApi,\n GridConfig,\n GridEngine,\n GridEventMap,\n GridPlugin,\n SortModelItem,\n FilterModel,\n RowNode,\n} from '@gridstorm/core';\nimport type { PropType } from 'vue';\n\n// ── Grid Context ──\n\n/**\n * Context value provided to child composables via Vue provide/inject.\n */\nexport interface GridContextValue<TData = any> {\n /** The grid engine instance. */\n engine: GridEngine<TData>;\n /** The public grid API. */\n api: GridApi<TData>;\n}\n\n// ── Component Props ──\n\n/**\n * Props interface for the GridStorm Vue component.\n *\n * @typeParam TData - The type of each row data object.\n */\nexport interface GridStormProps<TData = any> {\n /** Column definitions. */\n columns: ColumnDef<TData>[];\n /** Row data array. */\n rowData: TData[];\n /** Plugins to install. */\n plugins?: GridPlugin<TData>[];\n /** Row ID getter function. */\n getRowId?: GridConfig<TData>['getRowId'];\n /** Row height in pixels. */\n rowHeight?: number;\n /** Header height in pixels. */\n headerHeight?: number;\n /** Theme identifier (e.g., 'light', 'dark'). */\n theme?: string;\n /** Density mode (e.g., 'compact', 'normal', 'comfortable'). */\n density?: string;\n /** Default column definition applied to all columns. */\n defaultColDef?: Partial<ColumnDef<TData>>;\n /** Number of rows per page when pagination is enabled. */\n paginationPageSize?: number;\n /** Enable client-side pagination. */\n pagination?: boolean;\n /** Row selection mode. */\n rowSelection?: 'single' | 'multiple' | false;\n /** Edit type mode. */\n editType?: 'cell' | 'fullRow';\n /** ARIA label for the grid root element. */\n ariaLabel?: string;\n /** Container height. Default: '100%'. */\n height?: number | string;\n /** Container width. Default: '100%'. */\n width?: number | string;\n /** Additional CSS class for the container. */\n containerClass?: string;\n}\n\n/**\n * Vue prop definitions for the GridStorm component.\n * Used with defineComponent's props option.\n */\nexport const gridStormPropDefs = {\n columns: {\n type: Array as PropType<ColumnDef[]>,\n required: true as const,\n },\n rowData: {\n type: Array as PropType<any[]>,\n required: true as const,\n },\n plugins: {\n type: Array as PropType<GridPlugin[]>,\n default: () => [],\n },\n getRowId: {\n type: Function as PropType<GridConfig['getRowId']>,\n default: undefined,\n },\n rowHeight: {\n type: Number,\n default: 40,\n },\n headerHeight: {\n type: Number,\n default: undefined,\n },\n theme: {\n type: String,\n default: 'light',\n },\n density: {\n type: String,\n default: 'normal',\n },\n defaultColDef: {\n type: Object as PropType<Partial<ColumnDef>>,\n default: undefined,\n },\n paginationPageSize: {\n type: Number,\n default: undefined,\n },\n pagination: {\n type: Boolean,\n default: undefined,\n },\n rowSelection: {\n type: [String, Boolean] as PropType<'single' | 'multiple' | false>,\n default: undefined,\n },\n editType: {\n type: String as PropType<'cell' | 'fullRow'>,\n default: undefined,\n },\n ariaLabel: {\n type: String,\n default: undefined,\n },\n height: {\n type: [Number, String] as PropType<number | string>,\n default: '100%',\n },\n width: {\n type: [Number, String] as PropType<number | string>,\n default: '100%',\n },\n containerClass: {\n type: String,\n default: undefined,\n },\n} as const;\n\n// ── Event Types ──\n\n/**\n * All events emitted by the GridStorm Vue component.\n */\nexport interface GridStormEmits<TData = any> {\n /** Fired when the grid engine is ready and the API is available. */\n gridReady: [api: GridApi<TData>];\n /** Fired when row data changes. */\n rowDataChanged: [event: GridEventMap<TData>['rowData:changed']];\n /** Fired when the selection changes. */\n selectionChanged: [event: GridEventMap<TData>['selection:changed']];\n /** Fired when the sort model changes. */\n sortChanged: [event: GridEventMap<TData>['column:sort:changed']];\n /** Fired when the filter model changes. */\n filterChanged: [event: GridEventMap<TData>['filter:changed']];\n /** Fired when a cell value is changed via editing. */\n cellValueChanged: [event: GridEventMap<TData>['cell:valueChanged']];\n /** Fired when a cell is clicked. */\n cellClicked: [event: GridEventMap<TData>['cell:clicked']];\n /** Fired when a cell is double-clicked. */\n cellDoubleClicked: [event: GridEventMap<TData>['cell:doubleClicked']];\n /** Fired when a row is clicked. */\n rowClicked: [event: GridEventMap<TData>['row:clicked']];\n /** Fired when pagination state changes. */\n paginationChanged: [event: GridEventMap<TData>['pagination:changed']];\n /** Fired when a column is resized. */\n columnResized: [event: GridEventMap<TData>['column:resized']];\n}\n\n// ── Exposed API ──\n\n/**\n * Public methods exposed by the GridStorm component via template refs.\n *\n * @typeParam TData - The type of each row data object.\n */\nexport interface GridStormExposed<TData = any> {\n /** Get the GridApi instance. */\n getApi(): GridApi<TData> | undefined;\n /** Get the GridEngine instance. */\n getEngine(): GridEngine<TData> | undefined;\n}\n\n// ── Composable Return Types ──\n\n/**\n * Return type for the useGridSort composable.\n */\nexport interface GridSortResult {\n /** Current sort model (reactive). */\n sortModel: SortModelItem[];\n /** Whether any sort is active (reactive). */\n isSorted: boolean;\n /** Set the sort model directly. */\n setSortModel: (model: SortModelItem[]) => void;\n /** Toggle sort on a column. */\n toggleSort: (colId: string, multiSort?: boolean) => void;\n /** Clear all sorting. */\n clearSort: () => void;\n}\n\n/**\n * Return type for the useGridFilter composable.\n */\nexport interface GridFilterResult {\n /** Current filter model keyed by column ID (reactive). */\n filterModel: Record<string, FilterModel>;\n /** Current quick filter text (reactive). */\n quickFilterText: string;\n /** Whether any filter is active (reactive). */\n isFiltered: boolean;\n /** Set the filter model. */\n setFilterModel: (model: Record<string, FilterModel>) => void;\n /** Set quick filter text. */\n setQuickFilter: (text: string) => void;\n /** Clear all filters. */\n clearFilters: () => void;\n}\n\n/**\n * Return type for the useGridSelection composable.\n */\nexport interface GridSelectionResult<TData = any> {\n /** Set of selected row IDs (reactive). */\n selectedRowIds: Set<string>;\n /** Number of selected rows (reactive). */\n selectedCount: number;\n /** Get selected row data objects. */\n getSelectedRows: () => TData[];\n /** Get selected RowNode objects. */\n getSelectedNodes: () => RowNode<TData>[];\n /** Check if a specific row is selected. */\n isRowSelected: (rowId: string) => boolean;\n /** Select all visible rows. */\n selectAll: () => void;\n /** Deselect all rows. */\n deselectAll: () => void;\n}\n\n/**\n * Return type for the useGridPagination composable.\n */\nexport interface GridPaginationResult {\n /** Current page (0-indexed, reactive). */\n currentPage: number;\n /** Total number of pages (reactive). */\n totalPages: number;\n /** Rows per page (reactive). */\n pageSize: number;\n /** Total row count after filtering (reactive). */\n totalRows: number;\n /** Whether there is a next page (reactive). */\n hasNextPage: boolean;\n /** Whether there is a previous page (reactive). */\n hasPreviousPage: boolean;\n /** Go to a specific page. */\n goToPage: (page: number) => void;\n /** Go to next page. */\n nextPage: () => void;\n /** Go to previous page. */\n previousPage: () => void;\n /** Go to first page. */\n firstPage: () => void;\n /** Go to last page. */\n lastPage: () => void;\n}\n","// ─── Vue 3 Composables for GridStorm ───\n// Provide/inject-based composables that mirror the React hooks API.\n// All composables must be called inside a component that is a child of <GridStorm>.\n\nimport {\n inject,\n ref,\n onUnmounted,\n computed,\n watch,\n type InjectionKey,\n type Ref,\n type ShallowRef,\n} from 'vue';\nimport type { GridApi, GridEngine, SortModelItem, FilterModel, RowNode } from '@gridstorm/core';\nimport type { GridContextValue } from './types';\n\n// ── Context Key ──\n\n/**\n * Injection key used internally to provide/inject the grid context.\n * Uses ShallowRef to avoid deep reactive unwrapping of GridEngine internals\n * (the Store class has private fields incompatible with Vue's deep proxy typing).\n */\nexport const GRID_CONTEXT_KEY: InjectionKey<ShallowRef<GridContextValue | null>> =\n Symbol('gridstorm-context');\n\n// ── Internal helper ──\n\n/**\n * Internal helper to get the grid context with validation.\n * Throws if called outside a <GridStorm> component hierarchy.\n */\nfunction useGridContext<TData = any>(): ShallowRef<GridContextValue<TData> | null> {\n const context = inject(GRID_CONTEXT_KEY, null);\n if (!context) {\n throw new Error(\n '[GridStorm] Composable must be used within a <GridStorm> component.',\n );\n }\n return context as ShallowRef<GridContextValue<TData> | null>;\n}\n\n/**\n * Subscribe to the grid store and keep a reactive ref in sync.\n * Returns the reactive ref and automatically unsubscribes on unmount.\n */\nfunction useStoreRef<T>(\n context: ShallowRef<GridContextValue | null>,\n selector: (engine: GridEngine) => T,\n): Ref<T | undefined> {\n const value = ref<T | undefined>() as Ref<T | undefined>;\n let unsubscribe: (() => void) | null = null;\n\n function subscribe(ctx: GridContextValue | null) {\n // Clean up previous subscription\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n\n if (!ctx) {\n value.value = undefined;\n return;\n }\n\n // Set initial value\n value.value = selector(ctx.engine);\n\n // Subscribe to store changes\n unsubscribe = ctx.engine.store.subscribe(() => {\n value.value = selector(ctx.engine);\n });\n }\n\n // Watch for context changes (grid initialization/destruction)\n watch(context, (newCtx) => subscribe(newCtx), { immediate: true });\n\n onUnmounted(() => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n });\n\n return value;\n}\n\n// ── Public Composables ──\n\n/**\n * Access the GridApi instance from a parent GridStorm component.\n *\n * Returns a computed ref that resolves to the GridApi once the grid is initialized.\n * The ref will be undefined until the grid has mounted.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridApi } from '@gridstorm/vue';\n *\n * const api = useGridApi();\n *\n * function exportData() {\n * const rows = api.value?.getSelectedRows() ?? [];\n * console.log('Selected:', rows);\n * }\n * </script>\n * ```\n */\nexport function useGridApi<TData = any>(): Ref<GridApi<TData> | undefined> {\n const context = useGridContext<TData>();\n return computed(() => context.value?.api);\n}\n\n/**\n * Access the GridEngine instance from a parent GridStorm component.\n *\n * Primarily useful for advanced use cases that need direct access to\n * the store, event bus, or command bus.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridEngine } from '@gridstorm/vue';\n *\n * const engine = useGridEngine();\n * </script>\n * ```\n */\nexport function useGridEngine<TData = any>(): Ref<GridEngine<TData> | undefined> {\n const context = useGridContext<TData>();\n return computed(() => context.value?.engine);\n}\n\n/**\n * Reactive sort model state and sort actions.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridSort } from '@gridstorm/vue';\n *\n * const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();\n * </script>\n *\n * <template>\n * <button @click=\"toggleSort('name')\">Sort by Name</button>\n * <button v-if=\"isSorted\" @click=\"clearSort()\">Clear Sort</button>\n * <pre>{{ sortModel }}</pre>\n * </template>\n * ```\n */\nexport function useGridSort(): {\n sortModel: Ref<SortModelItem[]>;\n isSorted: Ref<boolean>;\n setSortModel: (model: SortModelItem[]) => void;\n toggleSort: (colId: string, multiSort?: boolean) => void;\n clearSort: () => void;\n} {\n const context = useGridContext();\n\n const sortModel = useStoreRef(context, (engine) =>\n engine.store.getState().sortModel,\n );\n\n const isSorted = computed(() => (sortModel.value?.length ?? 0) > 0);\n\n function setSortModel(model: SortModelItem[]): void {\n context.value?.api.setSortModel(model);\n }\n\n function toggleSort(colId: string, multiSort = false): void {\n context.value?.engine.commandBus.dispatch('sort:toggle', {\n colId,\n multiSort,\n });\n }\n\n function clearSort(): void {\n context.value?.api.setSortModel([]);\n }\n\n return {\n sortModel: sortModel as Ref<SortModelItem[]>,\n isSorted,\n setSortModel,\n toggleSort,\n clearSort,\n };\n}\n\n/**\n * Reactive filter model state and filter actions.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridFilter } from '@gridstorm/vue';\n *\n * const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();\n * </script>\n *\n * <template>\n * <input @input=\"(e) => setQuickFilter((e.target as HTMLInputElement).value)\" />\n * <button v-if=\"isFiltered\" @click=\"clearFilters()\">Clear Filters</button>\n * </template>\n * ```\n */\nexport function useGridFilter(): {\n filterModel: Ref<Record<string, FilterModel>>;\n quickFilterText: Ref<string>;\n isFiltered: Ref<boolean>;\n setFilterModel: (model: Record<string, FilterModel>) => void;\n setQuickFilter: (text: string) => void;\n clearFilters: () => void;\n} {\n const context = useGridContext();\n\n const filterModel = useStoreRef(context, (engine) =>\n engine.store.getState().filterModel,\n );\n\n const quickFilterText = useStoreRef(context, (engine) =>\n engine.store.getState().quickFilterText,\n );\n\n const isFiltered = computed(() => {\n const hasColumnFilters = Object.keys(filterModel.value ?? {}).length > 0;\n const hasQuickFilter = (quickFilterText.value ?? '').length > 0;\n return hasColumnFilters || hasQuickFilter;\n });\n\n function setFilterModel(model: Record<string, FilterModel>): void {\n context.value?.api.setFilterModel(model);\n }\n\n function setQuickFilter(text: string): void {\n context.value?.api.setQuickFilter(text);\n }\n\n function clearFilters(): void {\n context.value?.api.setFilterModel({});\n context.value?.api.setQuickFilter('');\n }\n\n return {\n filterModel: filterModel as Ref<Record<string, FilterModel>>,\n quickFilterText: quickFilterText as Ref<string>,\n isFiltered,\n setFilterModel,\n setQuickFilter,\n clearFilters,\n };\n}\n\n/**\n * Reactive selection state and selection actions.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridSelection } from '@gridstorm/vue';\n *\n * const { selectedCount, selectAll, deselectAll, isRowSelected } = useGridSelection();\n * </script>\n *\n * <template>\n * <p>{{ selectedCount }} rows selected</p>\n * <button @click=\"selectAll()\">Select All</button>\n * <button @click=\"deselectAll()\">Deselect All</button>\n * </template>\n * ```\n */\nexport function useGridSelection<TData = any>(): {\n selectedRowIds: Ref<Set<string>>;\n selectedCount: Ref<number>;\n getSelectedRows: () => TData[];\n getSelectedNodes: () => RowNode<TData>[];\n isRowSelected: (rowId: string) => boolean;\n selectAll: () => void;\n deselectAll: () => void;\n} {\n const context = useGridContext<TData>();\n\n const selectedRowIds = useStoreRef(context, (engine) =>\n engine.store.getState().selection.selectedRowIds,\n );\n\n const selectedCount = computed(() => selectedRowIds.value?.size ?? 0);\n\n function getSelectedRows(): TData[] {\n return context.value?.api.getSelectedRows() ?? [];\n }\n\n function getSelectedNodes(): RowNode<TData>[] {\n return context.value?.api.getSelectedNodes() ?? [];\n }\n\n function isRowSelected(rowId: string): boolean {\n return selectedRowIds.value?.has(rowId) ?? false;\n }\n\n function selectAll(): void {\n context.value?.api.selectAll();\n }\n\n function deselectAll(): void {\n context.value?.api.deselectAll();\n }\n\n return {\n selectedRowIds: selectedRowIds as Ref<Set<string>>,\n selectedCount,\n getSelectedRows,\n getSelectedNodes,\n isRowSelected,\n selectAll,\n deselectAll,\n };\n}\n\n/**\n * Reactive pagination state and navigation actions.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridPagination } from '@gridstorm/vue';\n *\n * const {\n * currentPage,\n * totalPages,\n * hasNextPage,\n * hasPreviousPage,\n * nextPage,\n * previousPage,\n * } = useGridPagination();\n * </script>\n *\n * <template>\n * <div class=\"pagination\">\n * <button :disabled=\"!hasPreviousPage\" @click=\"previousPage()\">Prev</button>\n * <span>Page {{ currentPage + 1 }} of {{ totalPages }}</span>\n * <button :disabled=\"!hasNextPage\" @click=\"nextPage()\">Next</button>\n * </div>\n * </template>\n * ```\n */\nexport function useGridPagination(): {\n currentPage: Ref<number>;\n totalPages: Ref<number>;\n pageSize: Ref<number>;\n totalRows: Ref<number>;\n hasNextPage: Ref<boolean>;\n hasPreviousPage: Ref<boolean>;\n goToPage: (page: number) => void;\n nextPage: () => void;\n previousPage: () => void;\n firstPage: () => void;\n lastPage: () => void;\n} {\n const context = useGridContext();\n\n const paginationState = useStoreRef(context, (engine) =>\n engine.store.getState().pagination,\n );\n\n const currentPage = computed(() => paginationState.value?.currentPage ?? 0);\n const pageSize = computed(() => paginationState.value?.pageSize ?? 100);\n const totalRows = computed(() => paginationState.value?.totalRows ?? 0);\n const totalPages = computed(() =>\n Math.max(1, Math.ceil(totalRows.value / pageSize.value)),\n );\n const hasNextPage = computed(() => currentPage.value < totalPages.value - 1);\n const hasPreviousPage = computed(() => currentPage.value > 0);\n\n function goToPage(page: number): void {\n context.value?.api.paginationGoToPage(page);\n }\n\n function nextPage(): void {\n if (hasNextPage.value) {\n context.value?.api.paginationGoToPage(currentPage.value + 1);\n }\n }\n\n function previousPage(): void {\n if (hasPreviousPage.value) {\n context.value?.api.paginationGoToPage(currentPage.value - 1);\n }\n }\n\n function firstPage(): void {\n context.value?.api.paginationGoToPage(0);\n }\n\n function lastPage(): void {\n context.value?.api.paginationGoToPage(totalPages.value - 1);\n }\n\n return {\n currentPage,\n totalPages,\n pageSize,\n totalRows,\n hasNextPage,\n hasPreviousPage,\n goToPage,\n nextPage,\n previousPage,\n firstPage,\n lastPage,\n };\n}\n\n/**\n * Listen to a specific grid event with automatic cleanup on unmount.\n *\n * @param event - The event name from GridEventMap.\n * @param handler - Callback function invoked when the event fires.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridEvent } from '@gridstorm/vue';\n *\n * useGridEvent('selection:changed', (e) => {\n * console.log('Selection changed:', e.selectedNodes);\n * });\n * </script>\n * ```\n */\nexport function useGridEvent<TData = any>(\n event: string,\n handler: (payload: any) => void,\n): void {\n const context = useGridContext<TData>();\n let unsubscribe: (() => void) | null = null;\n\n watch(\n context,\n (ctx) => {\n // Clean up previous listener\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n\n if (ctx) {\n unsubscribe = ctx.engine.eventBus.on(event as any, handler);\n }\n },\n { immediate: true },\n );\n\n onUnmounted(() => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n });\n}\n","// ─── GridStorm Vue 3 Component ───\n// Production-grade Vue wrapper around the headless core engine.\n// Uses defineComponent with a render function (no .vue SFC) for tsup compatibility.\n// Supports event emission, reactive prop watching, and composable injection.\n\nimport {\n defineComponent,\n ref,\n shallowRef,\n onMounted,\n onBeforeUnmount,\n watch,\n provide,\n h,\n} from 'vue';\nimport type { GridEngine } from '@gridstorm/core';\nimport { createGrid } from '@gridstorm/core';\nimport { DomRenderer } from '@gridstorm/dom-renderer';\nimport { gridStormPropDefs } from './types';\nimport type { GridContextValue } from './types';\nimport { GRID_CONTEXT_KEY } from './composables';\n\n/**\n * GridStorm Vue 3 component.\n *\n * Wraps the headless GridStorm core engine and DOM renderer into a Vue component\n * with reactive prop watching, event emission, and provide/inject context for\n * child composables.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { GridStorm } from '@gridstorm/vue';\n * import { sortingPlugin } from '@gridstorm/plugin-sorting';\n *\n * const columns = [\n * { field: 'name', headerName: 'Name', sortable: true },\n * { field: 'age', headerName: 'Age', width: 100 },\n * ];\n * const rowData = [\n * { name: 'Alice', age: 30 },\n * { name: 'Bob', age: 25 },\n * ];\n * </script>\n *\n * <template>\n * <GridStorm\n * :columns=\"columns\"\n * :row-data=\"rowData\"\n * :plugins=\"[sortingPlugin()]\"\n * @grid-ready=\"(api) => console.log('Grid ready!', api)\"\n * />\n * </template>\n * ```\n */\nexport const GridStorm = defineComponent({\n name: 'GridStorm',\n\n props: gridStormPropDefs,\n\n emits: [\n 'gridReady',\n 'rowDataChanged',\n 'selectionChanged',\n 'sortChanged',\n 'filterChanged',\n 'cellValueChanged',\n 'cellClicked',\n 'cellDoubleClicked',\n 'rowClicked',\n 'paginationChanged',\n 'columnResized',\n ],\n\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLElement | null>(null);\n let engine: GridEngine | null = null;\n let renderer: DomRenderer | null = null;\n const eventUnsubscribers: Array<() => void> = [];\n\n // ── Build GridConfig from props ──\n function buildConfig() {\n return {\n columns: props.columns as any,\n rowData: props.rowData as any,\n plugins: props.plugins as any,\n getRowId: props.getRowId as any,\n rowHeight: props.rowHeight,\n headerHeight: props.headerHeight,\n defaultColDef: props.defaultColDef as any,\n paginationPageSize: props.paginationPageSize,\n pagination: props.pagination,\n rowSelection: props.rowSelection as any,\n editType: props.editType as any,\n ariaLabel: props.ariaLabel,\n };\n }\n\n // ── Subscribe to engine events and bridge to Vue emits ──\n function subscribeToEvents() {\n if (!engine) return;\n\n const eb = engine.eventBus;\n\n eventUnsubscribers.push(\n eb.on('rowData:changed', (e) => emit('rowDataChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('selection:changed', (e) => emit('selectionChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('column:sort:changed', (e) => emit('sortChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('filter:changed', (e) => emit('filterChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('cell:valueChanged', (e) => emit('cellValueChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('cell:clicked', (e) => emit('cellClicked', e)),\n );\n eventUnsubscribers.push(\n eb.on('cell:doubleClicked', (e) => emit('cellDoubleClicked', e)),\n );\n eventUnsubscribers.push(\n eb.on('row:clicked', (e) => emit('rowClicked', e)),\n );\n eventUnsubscribers.push(\n eb.on('pagination:changed', (e) => emit('paginationChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('column:resized', (e) => emit('columnResized', e)),\n );\n }\n\n // ── Provide context for composables ──\n // Use shallowRef to avoid deep unwrapping of GridEngine internals\n // (Store class has private fields that break Vue's deep reactive proxy typing)\n const gridContext = shallowRef<GridContextValue | null>(null);\n\n provide(GRID_CONTEXT_KEY, gridContext);\n\n // ── Initialize grid engine and renderer ──\n function initGrid() {\n if (!containerRef.value) return;\n\n const config = buildConfig();\n engine = createGrid(config);\n\n // Update context for composables\n gridContext.value = {\n engine,\n api: engine.api,\n };\n\n // Mount DOM renderer\n renderer = new DomRenderer({\n container: containerRef.value,\n engine,\n });\n renderer.mount();\n\n // Subscribe to events\n subscribeToEvents();\n\n // Emit gridReady\n emit('gridReady', engine.api);\n }\n\n // ── Teardown ──\n function destroyGrid() {\n // Unsubscribe from all events\n for (const unsub of eventUnsubscribers) {\n unsub();\n }\n eventUnsubscribers.length = 0;\n\n renderer?.destroy();\n renderer = null;\n\n engine?.destroy();\n engine = null;\n\n gridContext.value = null;\n }\n\n // ── Lifecycle ──\n onMounted(() => {\n initGrid();\n });\n\n onBeforeUnmount(() => {\n destroyGrid();\n });\n\n // ── Watch for rowData changes ──\n watch(\n () => props.rowData,\n (newData) => {\n if (engine && newData) {\n engine.api.setRowData(newData as any);\n }\n },\n { deep: false },\n );\n\n // ── Watch for column changes ──\n watch(\n () => props.columns,\n (newCols) => {\n if (engine && newCols) {\n engine.api.setColumnDefs(newCols as any);\n }\n },\n { deep: false },\n );\n\n // ── Watch for theme changes ──\n watch(\n () => props.theme,\n (newTheme) => {\n if (containerRef.value && newTheme) {\n containerRef.value.setAttribute('data-theme', newTheme);\n }\n },\n );\n\n // ── Watch for density changes ──\n watch(\n () => props.density,\n (newDensity) => {\n if (containerRef.value && newDensity) {\n containerRef.value.setAttribute('data-density', newDensity);\n }\n },\n );\n\n // ── Expose public API via template refs ──\n expose({\n /**\n * Get the GridApi instance.\n * Returns undefined if the grid has not been initialized yet.\n */\n getApi: () => engine?.api,\n\n /**\n * Get the GridEngine instance.\n * Returns undefined if the grid has not been initialized yet.\n */\n getEngine: () => engine,\n });\n\n // ── Render function ──\n return () => {\n const heightStyle =\n typeof props.height === 'number' ? `${props.height}px` : props.height;\n const widthStyle =\n typeof props.width === 'number' ? `${props.width}px` : props.width;\n\n return h('div', {\n ref: containerRef,\n class: ['gridstorm-wrapper', props.containerClass].filter(Boolean).join(' '),\n 'data-theme': props.theme,\n 'data-density': props.density,\n style: {\n width: widthStyle,\n height: heightStyle,\n },\n });\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/composables.ts","../src/GridStorm.ts"],"names":["inject","ref","watch","onUnmounted","computed","defineComponent","shallowRef","provide","createGrid","DomRenderer","onErrorCaptured","onMounted","onBeforeUnmount","h"],"mappings":";;;;;;;;;AA4EO,IAAM,iBAAA,GAAoB;AAAA,EAC/B,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,OAAA,EAAS,MAAM;AAAC,GAClB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,QAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,SAAA,EAAW;AAAA,IACT,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,aAAA,EAAe;AAAA,IACb,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,kBAAA,EAAoB;AAAA,IAClB,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,OAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,IAAA,EAAM,CAAC,MAAA,EAAQ,OAAO,CAAA;AAAA,IACtB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,SAAA,EAAW;AAAA,IACT,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,CAAC,MAAA,EAAQ,MAAM,CAAA;AAAA,IACrB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,CAAC,MAAA,EAAQ,MAAM,CAAA;AAAA,IACrB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS;AAAA;AAEb,CAAA;ACzHO,IAAM,gBAAA,0BACJ,mBAAmB;AAQ5B,SAAS,cAAA,GAA0E;AACjF,EAAA,MAAM,OAAA,GAAUA,UAAA,CAAO,gBAAA,EAAkB,IAAI,CAAA;AAC7C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAMA,SAAS,WAAA,CACP,SACA,QAAA,EACoB;AACpB,EAAA,MAAM,QAAQC,OAAA,EAAmB;AACjC,EAAA,IAAI,WAAA,GAAmC,IAAA;AAEvC,EAAA,SAAS,UAAU,GAAA,EAA8B;AAE/C,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,WAAA,EAAY;AACZ,MAAA,WAAA,GAAc,IAAA;AAAA,IAChB;AAEA,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,KAAA,CAAM,KAAA,GAAQ,MAAA;AACd,MAAA;AAAA,IACF;AAGA,IAAA,KAAA,CAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA;AAGjC,IAAA,WAAA,GAAc,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,MAAM;AAC7C,MAAA,KAAA,CAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAGA,EAAAC,SAAA,CAAM,OAAA,EAAS,CAAC,MAAA,KAAW,SAAA,CAAU,MAAM,CAAA,EAAG,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAEjE,EAAAC,eAAA,CAAY,MAAM;AAChB,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,WAAA,EAAY;AACZ,MAAA,WAAA,GAAc,IAAA;AAAA,IAChB;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,KAAA;AACT;AAwBO,SAAS,UAAA,GAA2D;AACzE,EAAA,MAAM,UAAU,cAAA,EAAsB;AACtC,EAAA,OAAOC,YAAA,CAAS,MAAM,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAC1C;AAiBO,SAAS,aAAA,GAAiE;AAC/E,EAAA,MAAM,UAAU,cAAA,EAAsB;AACtC,EAAA,OAAOA,YAAA,CAAS,MAAM,OAAA,CAAQ,KAAA,EAAO,MAAM,CAAA;AAC7C;AAoBO,SAAS,WAAA,GAMd;AACA,EAAA,MAAM,UAAU,cAAA,EAAe;AAE/B,EAAA,MAAM,SAAA,GAAY,WAAA;AAAA,IAAY,OAAA;AAAA,IAAS,CAAC,MAAA,KACtC,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE;AAAA,GAC1B;AAEA,EAAA,MAAM,WAAWA,YAAA,CAAS,MAAA,CAAO,UAAU,KAAA,EAAO,MAAA,IAAU,KAAK,CAAC,CAAA;AAElE,EAAA,SAAS,aAAa,KAAA,EAA8B;AAClD,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,YAAA,CAAa,KAAK,CAAA;AAAA,EACvC;AAEA,EAAA,SAAS,UAAA,CAAW,KAAA,EAAe,SAAA,GAAY,KAAA,EAAa;AAC1D,IAAA,OAAA,CAAQ,KAAA,EAAO,MAAA,CAAO,UAAA,CAAW,QAAA,CAAS,aAAA,EAAe;AAAA,MACvD,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,SAAS,SAAA,GAAkB;AACzB,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,YAAA,CAAa,EAAE,CAAA;AAAA,EACpC;AAEA,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAmBO,SAAS,aAAA,GAOd;AACA,EAAA,MAAM,UAAU,cAAA,EAAe;AAE/B,EAAA,MAAM,WAAA,GAAc,WAAA;AAAA,IAAY,OAAA;AAAA,IAAS,CAAC,MAAA,KACxC,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE;AAAA,GAC1B;AAEA,EAAA,MAAM,eAAA,GAAkB,WAAA;AAAA,IAAY,OAAA;AAAA,IAAS,CAAC,MAAA,KAC5C,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE;AAAA,GAC1B;AAEA,EAAA,MAAM,UAAA,GAAaA,aAAS,MAAM;AAChC,IAAA,MAAM,gBAAA,GAAmB,OAAO,IAAA,CAAK,WAAA,CAAY,SAAS,EAAE,EAAE,MAAA,GAAS,CAAA;AACvE,IAAA,MAAM,cAAA,GAAA,CAAkB,eAAA,CAAgB,KAAA,IAAS,EAAA,EAAI,MAAA,GAAS,CAAA;AAC9D,IAAA,OAAO,gBAAA,IAAoB,cAAA;AAAA,EAC7B,CAAC,CAAA;AAED,EAAA,SAAS,eAAe,KAAA,EAA0C;AAChE,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,cAAA,CAAe,KAAK,CAAA;AAAA,EACzC;AAEA,EAAA,SAAS,eAAe,IAAA,EAAoB;AAC1C,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,cAAA,CAAe,IAAI,CAAA;AAAA,EACxC;AAEA,EAAA,SAAS,YAAA,GAAqB;AAC5B,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,cAAA,CAAe,EAAE,CAAA;AACpC,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,cAAA,CAAe,EAAE,CAAA;AAAA,EACtC;AAEA,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,eAAA;AAAA,IACA,UAAA;AAAA,IACA,cAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACF;AACF;AAoBO,SAAS,gBAAA,GAQd;AACA,EAAA,MAAM,UAAU,cAAA,EAAsB;AAEtC,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IAAY,OAAA;AAAA,IAAS,CAAC,MAAA,KAC3C,MAAA,CAAO,KAAA,CAAM,QAAA,GAAW,SAAA,CAAU;AAAA,GACpC;AAEA,EAAA,MAAM,gBAAgBA,YAAA,CAAS,MAAM,cAAA,CAAe,KAAA,EAAO,QAAQ,CAAC,CAAA;AAEpE,EAAA,SAAS,eAAA,GAA2B;AAClC,IAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,eAAA,MAAqB,EAAC;AAAA,EAClD;AAEA,EAAA,SAAS,gBAAA,GAAqC;AAC5C,IAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,gBAAA,MAAsB,EAAC;AAAA,EACnD;AAEA,EAAA,SAAS,cAAc,KAAA,EAAwB;AAC7C,IAAA,OAAO,cAAA,CAAe,KAAA,EAAO,GAAA,CAAI,KAAK,CAAA,IAAK,KAAA;AAAA,EAC7C;AAEA,EAAA,SAAS,SAAA,GAAkB;AACzB,IAAA,OAAA,CAAQ,KAAA,EAAO,IAAI,SAAA,EAAU;AAAA,EAC/B;AAEA,EAAA,SAAS,WAAA,GAAoB;AAC3B,IAAA,OAAA,CAAQ,KAAA,EAAO,IAAI,WAAA,EAAY;AAAA,EACjC;AAEA,EAAA,OAAO;AAAA,IACL,cAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;AA6BO,SAAS,iBAAA,GAYd;AACA,EAAA,MAAM,UAAU,cAAA,EAAe;AAE/B,EAAA,MAAM,eAAA,GAAkB,WAAA;AAAA,IAAY,OAAA;AAAA,IAAS,CAAC,MAAA,KAC5C,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE;AAAA,GAC1B;AAEA,EAAA,MAAM,cAAcA,YAAA,CAAS,MAAM,eAAA,CAAgB,KAAA,EAAO,eAAe,CAAC,CAAA;AAC1E,EAAA,MAAM,WAAWA,YAAA,CAAS,MAAM,eAAA,CAAgB,KAAA,EAAO,YAAY,GAAG,CAAA;AACtE,EAAA,MAAM,YAAYA,YAAA,CAAS,MAAM,eAAA,CAAgB,KAAA,EAAO,aAAa,CAAC,CAAA;AACtE,EAAA,MAAM,UAAA,GAAaA,YAAA;AAAA,IAAS,MAC1B,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAK,SAAA,CAAU,KAAA,GAAQ,QAAA,CAAS,KAAK,CAAC;AAAA,GACzD;AACA,EAAA,MAAM,cAAcA,YAAA,CAAS,MAAM,YAAY,KAAA,GAAQ,UAAA,CAAW,QAAQ,CAAC,CAAA;AAC3E,EAAA,MAAM,eAAA,GAAkBA,YAAA,CAAS,MAAM,WAAA,CAAY,QAAQ,CAAC,CAAA;AAE5D,EAAA,SAAS,SAAS,IAAA,EAAoB;AACpC,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,kBAAA,CAAmB,IAAI,CAAA;AAAA,EAC5C;AAEA,EAAA,SAAS,QAAA,GAAiB;AACxB,IAAA,IAAI,YAAY,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,kBAAA,CAAmB,WAAA,CAAY,QAAQ,CAAC,CAAA;AAAA,IAC7D;AAAA,EACF;AAEA,EAAA,SAAS,YAAA,GAAqB;AAC5B,IAAA,IAAI,gBAAgB,KAAA,EAAO;AACzB,MAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,kBAAA,CAAmB,WAAA,CAAY,QAAQ,CAAC,CAAA;AAAA,IAC7D;AAAA,EACF;AAEA,EAAA,SAAS,SAAA,GAAkB;AACzB,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,kBAAA,CAAmB,CAAC,CAAA;AAAA,EACzC;AAEA,EAAA,SAAS,QAAA,GAAiB;AACxB,IAAA,OAAA,CAAQ,KAAA,EAAO,GAAA,CAAI,kBAAA,CAAmB,UAAA,CAAW,QAAQ,CAAC,CAAA;AAAA,EAC5D;AAEA,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,eAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;AAmBO,SAAS,YAAA,CACd,OACA,OAAA,EACM;AACN,EAAA,MAAM,UAAU,cAAA,EAAsB;AACtC,EAAA,IAAI,WAAA,GAAmC,IAAA;AAEvC,EAAAF,SAAA;AAAA,IACE,OAAA;AAAA,IACA,CAAC,GAAA,KAAQ;AAEP,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,WAAA,EAAY;AACZ,QAAA,WAAA,GAAc,IAAA;AAAA,MAChB;AAEA,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,WAAA,GAAc,GAAA,CAAI,MAAA,CAAO,QAAA,CAAS,EAAA,CAAG,OAAc,OAAO,CAAA;AAAA,MAC5D;AAAA,IACF,CAAA;AAAA,IACA,EAAE,WAAW,IAAA;AAAK,GACpB;AAEA,EAAAC,eAAA,CAAY,MAAM;AAChB,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,WAAA,EAAY;AACZ,MAAA,WAAA,GAAc,IAAA;AAAA,IAChB;AAAA,EACF,CAAC,CAAA;AACH;;;ACtZO,IAAM,YAAYE,mBAAA,CAAgB;AAAA,EACvC,IAAA,EAAM,WAAA;AAAA,EAEN,KAAA,EAAO,iBAAA;AAAA,EAEP,KAAA,EAAO;AAAA,IACL,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,YAAA;AAAA,IACA,mBAAA;AAAA,IACA;AAAA,GACF;AAAA,EAEA,KAAA,CAAM,KAAA,EAAO,EAAE,IAAA,EAAM,QAAO,EAAG;AAC7B,IAAA,MAAM,YAAA,GAAeJ,QAAwB,IAAI,CAAA;AACjD,IAAA,IAAI,MAAA,GAA4B,IAAA;AAChC,IAAA,IAAI,QAAA,GAA+B,IAAA;AACnC,IAAA,MAAM,qBAAwC,EAAC;AAG/C,IAAA,SAAS,WAAA,GAAc;AACrB,MAAA,OAAO;AAAA,QACL,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,cAAc,KAAA,CAAM,YAAA;AAAA,QACpB,eAAe,KAAA,CAAM,aAAA;AAAA,QACrB,oBAAoB,KAAA,CAAM,kBAAA;AAAA,QAC1B,YAAY,KAAA,CAAM,UAAA;AAAA,QAClB,cAAc,KAAA,CAAM,YAAA;AAAA,QACpB,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,WAAW,KAAA,CAAM;AAAA,OACnB;AAAA,IACF;AAGA,IAAA,SAAS,iBAAA,GAAoB;AAC3B,MAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,MAAA,MAAM,KAAK,MAAA,CAAO,QAAA;AAElB,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,iBAAA,EAAmB,CAAC,MAAM,IAAA,CAAK,gBAAA,EAAkB,CAAC,CAAC;AAAA,OAC3D;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,mBAAA,EAAqB,CAAC,MAAM,IAAA,CAAK,kBAAA,EAAoB,CAAC,CAAC;AAAA,OAC/D;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,qBAAA,EAAuB,CAAC,MAAM,IAAA,CAAK,aAAA,EAAe,CAAC,CAAC;AAAA,OAC5D;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,gBAAA,EAAkB,CAAC,MAAM,IAAA,CAAK,eAAA,EAAiB,CAAC,CAAC;AAAA,OACzD;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,mBAAA,EAAqB,CAAC,MAAM,IAAA,CAAK,kBAAA,EAAoB,CAAC,CAAC;AAAA,OAC/D;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,cAAA,EAAgB,CAAC,MAAM,IAAA,CAAK,aAAA,EAAe,CAAC,CAAC;AAAA,OACrD;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,oBAAA,EAAsB,CAAC,MAAM,IAAA,CAAK,mBAAA,EAAqB,CAAC,CAAC;AAAA,OACjE;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,aAAA,EAAe,CAAC,MAAM,IAAA,CAAK,YAAA,EAAc,CAAC,CAAC;AAAA,OACnD;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,oBAAA,EAAsB,CAAC,MAAM,IAAA,CAAK,mBAAA,EAAqB,CAAC,CAAC;AAAA,OACjE;AACA,MAAA,kBAAA,CAAmB,IAAA;AAAA,QACjB,EAAA,CAAG,GAAG,gBAAA,EAAkB,CAAC,MAAM,IAAA,CAAK,eAAA,EAAiB,CAAC,CAAC;AAAA,OACzD;AAAA,IACF;AAKA,IAAA,MAAM,WAAA,GAAcK,eAAoC,IAAI,CAAA;AAE5D,IAAAC,WAAA,CAAQ,kBAAkB,WAAW,CAAA;AAGrC,IAAA,SAAS,QAAA,GAAW;AAClB,MAAA,IAAI,CAAC,aAAa,KAAA,EAAO;AAEzB,MAAA,MAAM,SAAS,WAAA,EAAY;AAC3B,MAAA,MAAA,GAASC,gBAAW,MAAM,CAAA;AAG1B,MAAA,WAAA,CAAY,KAAA,GAAQ;AAAA,QAClB,MAAA;AAAA,QACA,KAAK,MAAA,CAAO;AAAA,OACd;AAGA,MAAA,QAAA,GAAW,IAAIC,uBAAA,CAAY;AAAA,QACzB,WAAW,YAAA,CAAa,KAAA;AAAA,QACxB;AAAA,OACD,CAAA;AACD,MAAA,QAAA,CAAS,KAAA,EAAM;AAGf,MAAA,iBAAA,EAAkB;AAGlB,MAAA,IAAA,CAAK,WAAA,EAAa,OAAO,GAAG,CAAA;AAAA,IAC9B;AAGA,IAAA,SAAS,WAAA,GAAc;AAErB,MAAA,KAAA,MAAW,SAAS,kBAAA,EAAoB;AACtC,QAAA,KAAA,EAAM;AAAA,MACR;AACA,MAAA,kBAAA,CAAmB,MAAA,GAAS,CAAA;AAE5B,MAAA,QAAA,EAAU,OAAA,EAAQ;AAClB,MAAA,QAAA,GAAW,IAAA;AAEX,MAAA,MAAA,EAAQ,OAAA,EAAQ;AAChB,MAAA,MAAA,GAAS,IAAA;AAET,MAAA,WAAA,CAAY,KAAA,GAAQ,IAAA;AAAA,IACtB;AAGA,IAAA,MAAM,KAAA,GAAQR,QAAkB,IAAI,CAAA;AAEpC,IAAAS,mBAAA,CAAgB,CAAC,GAAA,KAAe;AAC9B,MAAA,KAAA,CAAM,KAAA,GAAQ,GAAA;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,mCAAmC,GAAG,CAAA;AAEpD,MAAA,OAAO,KAAA;AAAA,IACT,CAAC,CAAA;AAGD,IAAAC,aAAA,CAAU,MAAM;AACd,MAAA,IAAI;AACF,QAAA,QAAA,EAAS;AAAA,MACX,SAAS,GAAA,EAAK;AACZ,QAAA,KAAA,CAAM,KAAA,GAAQ,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAChE,QAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,GAAG,CAAA;AAAA,MAC5D;AAAA,IACF,CAAC,CAAA;AAED,IAAAC,mBAAA,CAAgB,MAAM;AACpB,MAAA,WAAA,EAAY;AAAA,IACd,CAAC,CAAA;AAGD,IAAAV,SAAAA;AAAA,MACE,MAAM,KAAA,CAAM,OAAA;AAAA,MACZ,CAAC,OAAA,KAAY;AACX,QAAA,IAAI,UAAU,OAAA,EAAS;AACrB,UAAA,MAAA,CAAO,GAAA,CAAI,WAAW,OAAc,CAAA;AAAA,QACtC;AAAA,MACF,CAAA;AAAA,MACA,EAAE,MAAM,KAAA;AAAM,KAChB;AAGA,IAAAA,SAAAA;AAAA,MACE,MAAM,KAAA,CAAM,OAAA;AAAA,MACZ,CAAC,OAAA,KAAY;AACX,QAAA,IAAI,UAAU,OAAA,EAAS;AACrB,UAAA,MAAA,CAAO,GAAA,CAAI,cAAc,OAAc,CAAA;AAAA,QACzC;AAAA,MACF,CAAA;AAAA,MACA,EAAE,MAAM,KAAA;AAAM,KAChB;AAGA,IAAAA,SAAAA;AAAA,MACE,MAAM,KAAA,CAAM,KAAA;AAAA,MACZ,CAAC,QAAA,KAAa;AACZ,QAAA,IAAI,YAAA,CAAa,SAAS,QAAA,EAAU;AAClC,UAAA,YAAA,CAAa,KAAA,CAAM,YAAA,CAAa,YAAA,EAAc,QAAQ,CAAA;AAAA,QACxD;AAAA,MACF;AAAA,KACF;AAGA,IAAAA,SAAAA;AAAA,MACE,MAAM,KAAA,CAAM,OAAA;AAAA,MACZ,CAAC,UAAA,KAAe;AACd,QAAA,IAAI,YAAA,CAAa,SAAS,UAAA,EAAY;AACpC,UAAA,YAAA,CAAa,KAAA,CAAM,YAAA,CAAa,cAAA,EAAgB,UAAU,CAAA;AAAA,QAC5D;AAAA,MACF;AAAA,KACF;AAGA,IAAA,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKL,MAAA,EAAQ,MAAM,MAAA,EAAQ,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMtB,WAAW,MAAM;AAAA,KAClB,CAAA;AAGD,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,WAAA,GACJ,OAAO,KAAA,CAAM,MAAA,KAAW,WAAW,CAAA,EAAG,KAAA,CAAM,MAAM,CAAA,EAAA,CAAA,GAAO,KAAA,CAAM,MAAA;AACjE,MAAA,MAAM,UAAA,GACJ,OAAO,KAAA,CAAM,KAAA,KAAU,WAAW,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,EAAA,CAAA,GAAO,KAAA,CAAM,KAAA;AAE/D,MAAA,OAAOW,MAAE,KAAA,EAAO;AAAA,QACd,GAAA,EAAK,YAAA;AAAA,QACL,KAAA,EAAO,CAAC,mBAAA,EAAqB,KAAA,CAAM,cAAc,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,QAC3E,cAAc,KAAA,CAAM,KAAA;AAAA,QACpB,gBAAgB,KAAA,CAAM,OAAA;AAAA,QACtB,KAAA,EAAO;AAAA,UACL,KAAA,EAAO,UAAA;AAAA,UACP,MAAA,EAAQ;AAAA;AACV,OACD,CAAA;AAAA,IACH,CAAA;AAAA,EACF;AACF,CAAC","file":"index.cjs","sourcesContent":["// ─── Vue Adapter Types ───\r\n// Central type definitions for all Vue-specific interfaces.\r\n\r\nimport type {\r\n ColumnDef,\r\n GridApi,\r\n GridConfig,\r\n GridEngine,\r\n GridEventMap,\r\n GridPlugin,\r\n SortModelItem,\r\n FilterModel,\r\n RowNode,\r\n} from '@gridstorm/core';\r\nimport type { PropType } from 'vue';\r\n\r\n// ── Grid Context ──\r\n\r\n/**\r\n * Context value provided to child composables via Vue provide/inject.\r\n */\r\nexport interface GridContextValue<TData = any> {\r\n /** The grid engine instance. */\r\n engine: GridEngine<TData>;\r\n /** The public grid API. */\r\n api: GridApi<TData>;\r\n}\r\n\r\n// ── Component Props ──\r\n\r\n/**\r\n * Props interface for the GridStorm Vue component.\r\n *\r\n * @typeParam TData - The type of each row data object.\r\n */\r\nexport interface GridStormProps<TData = any> {\r\n /** Column definitions. */\r\n columns: ColumnDef<TData>[];\r\n /** Row data array. */\r\n rowData: TData[];\r\n /** Plugins to install. */\r\n plugins?: GridPlugin<TData>[];\r\n /** Row ID getter function. */\r\n getRowId?: GridConfig<TData>['getRowId'];\r\n /** Row height in pixels. */\r\n rowHeight?: number;\r\n /** Header height in pixels. */\r\n headerHeight?: number;\r\n /** Theme identifier (e.g., 'light', 'dark'). */\r\n theme?: string;\r\n /** Density mode (e.g., 'compact', 'normal', 'comfortable'). */\r\n density?: string;\r\n /** Default column definition applied to all columns. */\r\n defaultColDef?: Partial<ColumnDef<TData>>;\r\n /** Number of rows per page when pagination is enabled. */\r\n paginationPageSize?: number;\r\n /** Enable client-side pagination. */\r\n pagination?: boolean;\r\n /** Row selection mode. */\r\n rowSelection?: 'single' | 'multiple' | false;\r\n /** Edit type mode. */\r\n editType?: 'cell' | 'fullRow';\r\n /** ARIA label for the grid root element. */\r\n ariaLabel?: string;\r\n /** Container height. Default: '100%'. */\r\n height?: number | string;\r\n /** Container width. Default: '100%'. */\r\n width?: number | string;\r\n /** Additional CSS class for the container. */\r\n containerClass?: string;\r\n}\r\n\r\n/**\r\n * Vue prop definitions for the GridStorm component.\r\n * Used with defineComponent's props option.\r\n */\r\nexport const gridStormPropDefs = {\r\n columns: {\r\n type: Array as PropType<ColumnDef[]>,\r\n required: true as const,\r\n },\r\n rowData: {\r\n type: Array as PropType<any[]>,\r\n required: true as const,\r\n },\r\n plugins: {\r\n type: Array as PropType<GridPlugin[]>,\r\n default: () => [],\r\n },\r\n getRowId: {\r\n type: Function as PropType<GridConfig['getRowId']>,\r\n default: undefined,\r\n },\r\n rowHeight: {\r\n type: Number,\r\n default: 40,\r\n },\r\n headerHeight: {\r\n type: Number,\r\n default: undefined,\r\n },\r\n theme: {\r\n type: String,\r\n default: 'light',\r\n },\r\n density: {\r\n type: String,\r\n default: 'normal',\r\n },\r\n defaultColDef: {\r\n type: Object as PropType<Partial<ColumnDef>>,\r\n default: undefined,\r\n },\r\n paginationPageSize: {\r\n type: Number,\r\n default: undefined,\r\n },\r\n pagination: {\r\n type: Boolean,\r\n default: undefined,\r\n },\r\n rowSelection: {\r\n type: [String, Boolean] as PropType<'single' | 'multiple' | false>,\r\n default: undefined,\r\n },\r\n editType: {\r\n type: String as PropType<'cell' | 'fullRow'>,\r\n default: undefined,\r\n },\r\n ariaLabel: {\r\n type: String,\r\n default: undefined,\r\n },\r\n height: {\r\n type: [Number, String] as PropType<number | string>,\r\n default: '100%',\r\n },\r\n width: {\r\n type: [Number, String] as PropType<number | string>,\r\n default: '100%',\r\n },\r\n containerClass: {\r\n type: String,\r\n default: undefined,\r\n },\r\n} as const;\r\n\r\n// ── Event Types ──\r\n\r\n/**\r\n * All events emitted by the GridStorm Vue component.\r\n */\r\nexport interface GridStormEmits<TData = any> {\r\n /** Fired when the grid engine is ready and the API is available. */\r\n gridReady: [api: GridApi<TData>];\r\n /** Fired when row data changes. */\r\n rowDataChanged: [event: GridEventMap<TData>['rowData:changed']];\r\n /** Fired when the selection changes. */\r\n selectionChanged: [event: GridEventMap<TData>['selection:changed']];\r\n /** Fired when the sort model changes. */\r\n sortChanged: [event: GridEventMap<TData>['column:sort:changed']];\r\n /** Fired when the filter model changes. */\r\n filterChanged: [event: GridEventMap<TData>['filter:changed']];\r\n /** Fired when a cell value is changed via editing. */\r\n cellValueChanged: [event: GridEventMap<TData>['cell:valueChanged']];\r\n /** Fired when a cell is clicked. */\r\n cellClicked: [event: GridEventMap<TData>['cell:clicked']];\r\n /** Fired when a cell is double-clicked. */\r\n cellDoubleClicked: [event: GridEventMap<TData>['cell:doubleClicked']];\r\n /** Fired when a row is clicked. */\r\n rowClicked: [event: GridEventMap<TData>['row:clicked']];\r\n /** Fired when pagination state changes. */\r\n paginationChanged: [event: GridEventMap<TData>['pagination:changed']];\r\n /** Fired when a column is resized. */\r\n columnResized: [event: GridEventMap<TData>['column:resized']];\r\n}\r\n\r\n// ── Exposed API ──\r\n\r\n/**\r\n * Public methods exposed by the GridStorm component via template refs.\r\n *\r\n * @typeParam TData - The type of each row data object.\r\n */\r\nexport interface GridStormExposed<TData = any> {\r\n /** Get the GridApi instance. */\r\n getApi(): GridApi<TData> | undefined;\r\n /** Get the GridEngine instance. */\r\n getEngine(): GridEngine<TData> | undefined;\r\n}\r\n\r\n// ── Composable Return Types ──\r\n\r\n/**\r\n * Return type for the useGridSort composable.\r\n */\r\nexport interface GridSortResult {\r\n /** Current sort model (reactive). */\r\n sortModel: SortModelItem[];\r\n /** Whether any sort is active (reactive). */\r\n isSorted: boolean;\r\n /** Set the sort model directly. */\r\n setSortModel: (model: SortModelItem[]) => void;\r\n /** Toggle sort on a column. */\r\n toggleSort: (colId: string, multiSort?: boolean) => void;\r\n /** Clear all sorting. */\r\n clearSort: () => void;\r\n}\r\n\r\n/**\r\n * Return type for the useGridFilter composable.\r\n */\r\nexport interface GridFilterResult {\r\n /** Current filter model keyed by column ID (reactive). */\r\n filterModel: Record<string, FilterModel>;\r\n /** Current quick filter text (reactive). */\r\n quickFilterText: string;\r\n /** Whether any filter is active (reactive). */\r\n isFiltered: boolean;\r\n /** Set the filter model. */\r\n setFilterModel: (model: Record<string, FilterModel>) => void;\r\n /** Set quick filter text. */\r\n setQuickFilter: (text: string) => void;\r\n /** Clear all filters. */\r\n clearFilters: () => void;\r\n}\r\n\r\n/**\r\n * Return type for the useGridSelection composable.\r\n */\r\nexport interface GridSelectionResult<TData = any> {\r\n /** Set of selected row IDs (reactive). */\r\n selectedRowIds: Set<string>;\r\n /** Number of selected rows (reactive). */\r\n selectedCount: number;\r\n /** Get selected row data objects. */\r\n getSelectedRows: () => TData[];\r\n /** Get selected RowNode objects. */\r\n getSelectedNodes: () => RowNode<TData>[];\r\n /** Check if a specific row is selected. */\r\n isRowSelected: (rowId: string) => boolean;\r\n /** Select all visible rows. */\r\n selectAll: () => void;\r\n /** Deselect all rows. */\r\n deselectAll: () => void;\r\n}\r\n\r\n/**\r\n * Return type for the useGridPagination composable.\r\n */\r\nexport interface GridPaginationResult {\r\n /** Current page (0-indexed, reactive). */\r\n currentPage: number;\r\n /** Total number of pages (reactive). */\r\n totalPages: number;\r\n /** Rows per page (reactive). */\r\n pageSize: number;\r\n /** Total row count after filtering (reactive). */\r\n totalRows: number;\r\n /** Whether there is a next page (reactive). */\r\n hasNextPage: boolean;\r\n /** Whether there is a previous page (reactive). */\r\n hasPreviousPage: boolean;\r\n /** Go to a specific page. */\r\n goToPage: (page: number) => void;\r\n /** Go to next page. */\r\n nextPage: () => void;\r\n /** Go to previous page. */\r\n previousPage: () => void;\r\n /** Go to first page. */\r\n firstPage: () => void;\r\n /** Go to last page. */\r\n lastPage: () => void;\r\n}\r\n","// ─── Vue 3 Composables for GridStorm ───\r\n// Provide/inject-based composables that mirror the React hooks API.\r\n// All composables must be called inside a component that is a child of <GridStorm>.\r\n\r\nimport {\r\n inject,\r\n ref,\r\n onUnmounted,\r\n computed,\r\n watch,\r\n type InjectionKey,\r\n type Ref,\r\n type ShallowRef,\r\n} from 'vue';\r\nimport type { GridApi, GridEngine, SortModelItem, FilterModel, RowNode } from '@gridstorm/core';\r\nimport type { GridContextValue } from './types';\r\n\r\n// ── Context Key ──\r\n\r\n/**\r\n * Injection key used internally to provide/inject the grid context.\r\n * Uses ShallowRef to avoid deep reactive unwrapping of GridEngine internals\r\n * (the Store class has private fields incompatible with Vue's deep proxy typing).\r\n */\r\nexport const GRID_CONTEXT_KEY: InjectionKey<ShallowRef<GridContextValue | null>> =\r\n Symbol('gridstorm-context');\r\n\r\n// ── Internal helper ──\r\n\r\n/**\r\n * Internal helper to get the grid context with validation.\r\n * Throws if called outside a <GridStorm> component hierarchy.\r\n */\r\nfunction useGridContext<TData = any>(): ShallowRef<GridContextValue<TData> | null> {\r\n const context = inject(GRID_CONTEXT_KEY, null);\r\n if (!context) {\r\n throw new Error(\r\n '[GridStorm] Composable must be used within a <GridStorm> component.',\r\n );\r\n }\r\n return context as ShallowRef<GridContextValue<TData> | null>;\r\n}\r\n\r\n/**\r\n * Subscribe to the grid store and keep a reactive ref in sync.\r\n * Returns the reactive ref and automatically unsubscribes on unmount.\r\n */\r\nfunction useStoreRef<T>(\r\n context: ShallowRef<GridContextValue | null>,\r\n selector: (engine: GridEngine) => T,\r\n): Ref<T | undefined> {\r\n const value = ref<T | undefined>() as Ref<T | undefined>;\r\n let unsubscribe: (() => void) | null = null;\r\n\r\n function subscribe(ctx: GridContextValue | null) {\r\n // Clean up previous subscription\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n\r\n if (!ctx) {\r\n value.value = undefined;\r\n return;\r\n }\r\n\r\n // Set initial value\r\n value.value = selector(ctx.engine);\r\n\r\n // Subscribe to store changes\r\n unsubscribe = ctx.engine.store.subscribe(() => {\r\n value.value = selector(ctx.engine);\r\n });\r\n }\r\n\r\n // Watch for context changes (grid initialization/destruction)\r\n watch(context, (newCtx) => subscribe(newCtx), { immediate: true });\r\n\r\n onUnmounted(() => {\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n });\r\n\r\n return value;\r\n}\r\n\r\n// ── Public Composables ──\r\n\r\n/**\r\n * Access the GridApi instance from a parent GridStorm component.\r\n *\r\n * Returns a computed ref that resolves to the GridApi once the grid is initialized.\r\n * The ref will be undefined until the grid has mounted.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridApi } from '@gridstorm/vue';\r\n *\r\n * const api = useGridApi();\r\n *\r\n * function exportData() {\r\n * const rows = api.value?.getSelectedRows() ?? [];\r\n * console.log('Selected:', rows);\r\n * }\r\n * </script>\r\n * ```\r\n */\r\nexport function useGridApi<TData = any>(): Ref<GridApi<TData> | undefined> {\r\n const context = useGridContext<TData>();\r\n return computed(() => context.value?.api);\r\n}\r\n\r\n/**\r\n * Access the GridEngine instance from a parent GridStorm component.\r\n *\r\n * Primarily useful for advanced use cases that need direct access to\r\n * the store, event bus, or command bus.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridEngine } from '@gridstorm/vue';\r\n *\r\n * const engine = useGridEngine();\r\n * </script>\r\n * ```\r\n */\r\nexport function useGridEngine<TData = any>(): Ref<GridEngine<TData> | undefined> {\r\n const context = useGridContext<TData>();\r\n return computed(() => context.value?.engine);\r\n}\r\n\r\n/**\r\n * Reactive sort model state and sort actions.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridSort } from '@gridstorm/vue';\r\n *\r\n * const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();\r\n * </script>\r\n *\r\n * <template>\r\n * <button @click=\"toggleSort('name')\">Sort by Name</button>\r\n * <button v-if=\"isSorted\" @click=\"clearSort()\">Clear Sort</button>\r\n * <pre>{{ sortModel }}</pre>\r\n * </template>\r\n * ```\r\n */\r\nexport function useGridSort(): {\r\n sortModel: Ref<SortModelItem[]>;\r\n isSorted: Ref<boolean>;\r\n setSortModel: (model: SortModelItem[]) => void;\r\n toggleSort: (colId: string, multiSort?: boolean) => void;\r\n clearSort: () => void;\r\n} {\r\n const context = useGridContext();\r\n\r\n const sortModel = useStoreRef(context, (engine) =>\r\n engine.store.getState().sortModel,\r\n );\r\n\r\n const isSorted = computed(() => (sortModel.value?.length ?? 0) > 0);\r\n\r\n function setSortModel(model: SortModelItem[]): void {\r\n context.value?.api.setSortModel(model);\r\n }\r\n\r\n function toggleSort(colId: string, multiSort = false): void {\r\n context.value?.engine.commandBus.dispatch('sort:toggle', {\r\n colId,\r\n multiSort,\r\n });\r\n }\r\n\r\n function clearSort(): void {\r\n context.value?.api.setSortModel([]);\r\n }\r\n\r\n return {\r\n sortModel: sortModel as Ref<SortModelItem[]>,\r\n isSorted,\r\n setSortModel,\r\n toggleSort,\r\n clearSort,\r\n };\r\n}\r\n\r\n/**\r\n * Reactive filter model state and filter actions.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridFilter } from '@gridstorm/vue';\r\n *\r\n * const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();\r\n * </script>\r\n *\r\n * <template>\r\n * <input @input=\"(e) => setQuickFilter((e.target as HTMLInputElement).value)\" />\r\n * <button v-if=\"isFiltered\" @click=\"clearFilters()\">Clear Filters</button>\r\n * </template>\r\n * ```\r\n */\r\nexport function useGridFilter(): {\r\n filterModel: Ref<Record<string, FilterModel>>;\r\n quickFilterText: Ref<string>;\r\n isFiltered: Ref<boolean>;\r\n setFilterModel: (model: Record<string, FilterModel>) => void;\r\n setQuickFilter: (text: string) => void;\r\n clearFilters: () => void;\r\n} {\r\n const context = useGridContext();\r\n\r\n const filterModel = useStoreRef(context, (engine) =>\r\n engine.store.getState().filterModel,\r\n );\r\n\r\n const quickFilterText = useStoreRef(context, (engine) =>\r\n engine.store.getState().quickFilterText,\r\n );\r\n\r\n const isFiltered = computed(() => {\r\n const hasColumnFilters = Object.keys(filterModel.value ?? {}).length > 0;\r\n const hasQuickFilter = (quickFilterText.value ?? '').length > 0;\r\n return hasColumnFilters || hasQuickFilter;\r\n });\r\n\r\n function setFilterModel(model: Record<string, FilterModel>): void {\r\n context.value?.api.setFilterModel(model);\r\n }\r\n\r\n function setQuickFilter(text: string): void {\r\n context.value?.api.setQuickFilter(text);\r\n }\r\n\r\n function clearFilters(): void {\r\n context.value?.api.setFilterModel({});\r\n context.value?.api.setQuickFilter('');\r\n }\r\n\r\n return {\r\n filterModel: filterModel as Ref<Record<string, FilterModel>>,\r\n quickFilterText: quickFilterText as Ref<string>,\r\n isFiltered,\r\n setFilterModel,\r\n setQuickFilter,\r\n clearFilters,\r\n };\r\n}\r\n\r\n/**\r\n * Reactive selection state and selection actions.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridSelection } from '@gridstorm/vue';\r\n *\r\n * const { selectedCount, selectAll, deselectAll, isRowSelected } = useGridSelection();\r\n * </script>\r\n *\r\n * <template>\r\n * <p>{{ selectedCount }} rows selected</p>\r\n * <button @click=\"selectAll()\">Select All</button>\r\n * <button @click=\"deselectAll()\">Deselect All</button>\r\n * </template>\r\n * ```\r\n */\r\nexport function useGridSelection<TData = any>(): {\r\n selectedRowIds: Ref<Set<string>>;\r\n selectedCount: Ref<number>;\r\n getSelectedRows: () => TData[];\r\n getSelectedNodes: () => RowNode<TData>[];\r\n isRowSelected: (rowId: string) => boolean;\r\n selectAll: () => void;\r\n deselectAll: () => void;\r\n} {\r\n const context = useGridContext<TData>();\r\n\r\n const selectedRowIds = useStoreRef(context, (engine) =>\r\n engine.store.getState().selection.selectedRowIds,\r\n );\r\n\r\n const selectedCount = computed(() => selectedRowIds.value?.size ?? 0);\r\n\r\n function getSelectedRows(): TData[] {\r\n return context.value?.api.getSelectedRows() ?? [];\r\n }\r\n\r\n function getSelectedNodes(): RowNode<TData>[] {\r\n return context.value?.api.getSelectedNodes() ?? [];\r\n }\r\n\r\n function isRowSelected(rowId: string): boolean {\r\n return selectedRowIds.value?.has(rowId) ?? false;\r\n }\r\n\r\n function selectAll(): void {\r\n context.value?.api.selectAll();\r\n }\r\n\r\n function deselectAll(): void {\r\n context.value?.api.deselectAll();\r\n }\r\n\r\n return {\r\n selectedRowIds: selectedRowIds as Ref<Set<string>>,\r\n selectedCount,\r\n getSelectedRows,\r\n getSelectedNodes,\r\n isRowSelected,\r\n selectAll,\r\n deselectAll,\r\n };\r\n}\r\n\r\n/**\r\n * Reactive pagination state and navigation actions.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridPagination } from '@gridstorm/vue';\r\n *\r\n * const {\r\n * currentPage,\r\n * totalPages,\r\n * hasNextPage,\r\n * hasPreviousPage,\r\n * nextPage,\r\n * previousPage,\r\n * } = useGridPagination();\r\n * </script>\r\n *\r\n * <template>\r\n * <div class=\"pagination\">\r\n * <button :disabled=\"!hasPreviousPage\" @click=\"previousPage()\">Prev</button>\r\n * <span>Page {{ currentPage + 1 }} of {{ totalPages }}</span>\r\n * <button :disabled=\"!hasNextPage\" @click=\"nextPage()\">Next</button>\r\n * </div>\r\n * </template>\r\n * ```\r\n */\r\nexport function useGridPagination(): {\r\n currentPage: Ref<number>;\r\n totalPages: Ref<number>;\r\n pageSize: Ref<number>;\r\n totalRows: Ref<number>;\r\n hasNextPage: Ref<boolean>;\r\n hasPreviousPage: Ref<boolean>;\r\n goToPage: (page: number) => void;\r\n nextPage: () => void;\r\n previousPage: () => void;\r\n firstPage: () => void;\r\n lastPage: () => void;\r\n} {\r\n const context = useGridContext();\r\n\r\n const paginationState = useStoreRef(context, (engine) =>\r\n engine.store.getState().pagination,\r\n );\r\n\r\n const currentPage = computed(() => paginationState.value?.currentPage ?? 0);\r\n const pageSize = computed(() => paginationState.value?.pageSize ?? 100);\r\n const totalRows = computed(() => paginationState.value?.totalRows ?? 0);\r\n const totalPages = computed(() =>\r\n Math.max(1, Math.ceil(totalRows.value / pageSize.value)),\r\n );\r\n const hasNextPage = computed(() => currentPage.value < totalPages.value - 1);\r\n const hasPreviousPage = computed(() => currentPage.value > 0);\r\n\r\n function goToPage(page: number): void {\r\n context.value?.api.paginationGoToPage(page);\r\n }\r\n\r\n function nextPage(): void {\r\n if (hasNextPage.value) {\r\n context.value?.api.paginationGoToPage(currentPage.value + 1);\r\n }\r\n }\r\n\r\n function previousPage(): void {\r\n if (hasPreviousPage.value) {\r\n context.value?.api.paginationGoToPage(currentPage.value - 1);\r\n }\r\n }\r\n\r\n function firstPage(): void {\r\n context.value?.api.paginationGoToPage(0);\r\n }\r\n\r\n function lastPage(): void {\r\n context.value?.api.paginationGoToPage(totalPages.value - 1);\r\n }\r\n\r\n return {\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n };\r\n}\r\n\r\n/**\r\n * Listen to a specific grid event with automatic cleanup on unmount.\r\n *\r\n * @param event - The event name from GridEventMap.\r\n * @param handler - Callback function invoked when the event fires.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridEvent } from '@gridstorm/vue';\r\n *\r\n * useGridEvent('selection:changed', (e) => {\r\n * console.log('Selection changed:', e.selectedNodes);\r\n * });\r\n * </script>\r\n * ```\r\n */\r\nexport function useGridEvent<TData = any>(\r\n event: string,\r\n handler: (payload: any) => void,\r\n): void {\r\n const context = useGridContext<TData>();\r\n let unsubscribe: (() => void) | null = null;\r\n\r\n watch(\r\n context,\r\n (ctx) => {\r\n // Clean up previous listener\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n\r\n if (ctx) {\r\n unsubscribe = ctx.engine.eventBus.on(event as any, handler);\r\n }\r\n },\r\n { immediate: true },\r\n );\r\n\r\n onUnmounted(() => {\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n });\r\n}\r\n","// ─── GridStorm Vue 3 Component ───\r\n// Production-grade Vue wrapper around the headless core engine.\r\n// Uses defineComponent with a render function (no .vue SFC) for tsup compatibility.\r\n// Supports event emission, reactive prop watching, and composable injection.\r\n\r\nimport {\r\n defineComponent,\r\n ref,\r\n shallowRef,\r\n onMounted,\r\n onBeforeUnmount,\r\n onErrorCaptured,\r\n watch,\r\n provide,\r\n h,\r\n} from 'vue';\r\nimport type { GridEngine } from '@gridstorm/core';\r\nimport { createGrid } from '@gridstorm/core';\r\nimport { DomRenderer } from '@gridstorm/dom-renderer';\r\nimport { gridStormPropDefs } from './types';\r\nimport type { GridContextValue } from './types';\r\nimport { GRID_CONTEXT_KEY } from './composables';\r\n\r\n/**\r\n * GridStorm Vue 3 component.\r\n *\r\n * Wraps the headless GridStorm core engine and DOM renderer into a Vue component\r\n * with reactive prop watching, event emission, and provide/inject context for\r\n * child composables.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { GridStorm } from '@gridstorm/vue';\r\n * import { sortingPlugin } from '@gridstorm/plugin-sorting';\r\n *\r\n * const columns = [\r\n * { field: 'name', headerName: 'Name', sortable: true },\r\n * { field: 'age', headerName: 'Age', width: 100 },\r\n * ];\r\n * const rowData = [\r\n * { name: 'Alice', age: 30 },\r\n * { name: 'Bob', age: 25 },\r\n * ];\r\n * </script>\r\n *\r\n * <template>\r\n * <GridStorm\r\n * :columns=\"columns\"\r\n * :row-data=\"rowData\"\r\n * :plugins=\"[sortingPlugin()]\"\r\n * @grid-ready=\"(api) => console.log('Grid ready!', api)\"\r\n * />\r\n * </template>\r\n * ```\r\n */\r\nexport const GridStorm = defineComponent({\r\n name: 'GridStorm',\r\n\r\n props: gridStormPropDefs,\r\n\r\n emits: [\r\n 'gridReady',\r\n 'rowDataChanged',\r\n 'selectionChanged',\r\n 'sortChanged',\r\n 'filterChanged',\r\n 'cellValueChanged',\r\n 'cellClicked',\r\n 'cellDoubleClicked',\r\n 'rowClicked',\r\n 'paginationChanged',\r\n 'columnResized',\r\n ],\r\n\r\n setup(props, { emit, expose }) {\r\n const containerRef = ref<HTMLElement | null>(null);\r\n let engine: GridEngine | null = null;\r\n let renderer: DomRenderer | null = null;\r\n const eventUnsubscribers: Array<() => void> = [];\r\n\r\n // ── Build GridConfig from props ──\r\n function buildConfig() {\r\n return {\r\n columns: props.columns as any,\r\n rowData: props.rowData as any,\r\n plugins: props.plugins as any,\r\n getRowId: props.getRowId as any,\r\n rowHeight: props.rowHeight,\r\n headerHeight: props.headerHeight,\r\n defaultColDef: props.defaultColDef as any,\r\n paginationPageSize: props.paginationPageSize,\r\n pagination: props.pagination,\r\n rowSelection: props.rowSelection as any,\r\n editType: props.editType as any,\r\n ariaLabel: props.ariaLabel,\r\n };\r\n }\r\n\r\n // ── Subscribe to engine events and bridge to Vue emits ──\r\n function subscribeToEvents() {\r\n if (!engine) return;\r\n\r\n const eb = engine.eventBus;\r\n\r\n eventUnsubscribers.push(\r\n eb.on('rowData:changed', (e) => emit('rowDataChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('selection:changed', (e) => emit('selectionChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('column:sort:changed', (e) => emit('sortChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('filter:changed', (e) => emit('filterChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('cell:valueChanged', (e) => emit('cellValueChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('cell:clicked', (e) => emit('cellClicked', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('cell:doubleClicked', (e) => emit('cellDoubleClicked', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('row:clicked', (e) => emit('rowClicked', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('pagination:changed', (e) => emit('paginationChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('column:resized', (e) => emit('columnResized', e)),\r\n );\r\n }\r\n\r\n // ── Provide context for composables ──\r\n // Use shallowRef to avoid deep unwrapping of GridEngine internals\r\n // (Store class has private fields that break Vue's deep reactive proxy typing)\r\n const gridContext = shallowRef<GridContextValue | null>(null);\r\n\r\n provide(GRID_CONTEXT_KEY, gridContext);\r\n\r\n // ── Initialize grid engine and renderer ──\r\n function initGrid() {\r\n if (!containerRef.value) return;\r\n\r\n const config = buildConfig();\r\n engine = createGrid(config);\r\n\r\n // Update context for composables\r\n gridContext.value = {\r\n engine,\r\n api: engine.api,\r\n };\r\n\r\n // Mount DOM renderer\r\n renderer = new DomRenderer({\r\n container: containerRef.value,\r\n engine,\r\n });\r\n renderer.mount();\r\n\r\n // Subscribe to events\r\n subscribeToEvents();\r\n\r\n // Emit gridReady\r\n emit('gridReady', engine.api);\r\n }\r\n\r\n // ── Teardown ──\r\n function destroyGrid() {\r\n // Unsubscribe from all events\r\n for (const unsub of eventUnsubscribers) {\r\n unsub();\r\n }\r\n eventUnsubscribers.length = 0;\r\n\r\n renderer?.destroy();\r\n renderer = null;\r\n\r\n engine?.destroy();\r\n engine = null;\r\n\r\n gridContext.value = null;\r\n }\r\n\r\n // ── Error Boundary ──\r\n const error = ref<Error | null>(null);\r\n\r\n onErrorCaptured((err: Error) => {\r\n error.value = err;\r\n console.error('[GridStorm Vue] Error captured:', err);\r\n // Return false to stop the error from propagating further\r\n return false;\r\n });\r\n\r\n // ── Lifecycle ──\r\n onMounted(() => {\r\n try {\r\n initGrid();\r\n } catch (err) {\r\n error.value = err instanceof Error ? err : new Error(String(err));\r\n console.error('[GridStorm Vue] Initialization error:', err);\r\n }\r\n });\r\n\r\n onBeforeUnmount(() => {\r\n destroyGrid();\r\n });\r\n\r\n // ── Watch for rowData changes ──\r\n watch(\r\n () => props.rowData,\r\n (newData) => {\r\n if (engine && newData) {\r\n engine.api.setRowData(newData as any);\r\n }\r\n },\r\n { deep: false },\r\n );\r\n\r\n // ── Watch for column changes ──\r\n watch(\r\n () => props.columns,\r\n (newCols) => {\r\n if (engine && newCols) {\r\n engine.api.setColumnDefs(newCols as any);\r\n }\r\n },\r\n { deep: false },\r\n );\r\n\r\n // ── Watch for theme changes ──\r\n watch(\r\n () => props.theme,\r\n (newTheme) => {\r\n if (containerRef.value && newTheme) {\r\n containerRef.value.setAttribute('data-theme', newTheme);\r\n }\r\n },\r\n );\r\n\r\n // ── Watch for density changes ──\r\n watch(\r\n () => props.density,\r\n (newDensity) => {\r\n if (containerRef.value && newDensity) {\r\n containerRef.value.setAttribute('data-density', newDensity);\r\n }\r\n },\r\n );\r\n\r\n // ── Expose public API via template refs ──\r\n expose({\r\n /**\r\n * Get the GridApi instance.\r\n * Returns undefined if the grid has not been initialized yet.\r\n */\r\n getApi: () => engine?.api,\r\n\r\n /**\r\n * Get the GridEngine instance.\r\n * Returns undefined if the grid has not been initialized yet.\r\n */\r\n getEngine: () => engine,\r\n });\r\n\r\n // ── Render function ──\r\n return () => {\r\n const heightStyle =\r\n typeof props.height === 'number' ? `${props.height}px` : props.height;\r\n const widthStyle =\r\n typeof props.width === 'number' ? `${props.width}px` : props.width;\r\n\r\n return h('div', {\r\n ref: containerRef,\r\n class: ['gridstorm-wrapper', props.containerClass].filter(Boolean).join(' '),\r\n 'data-theme': props.theme,\r\n 'data-density': props.density,\r\n style: {\r\n width: widthStyle,\r\n height: heightStyle,\r\n },\r\n });\r\n };\r\n },\r\n});\r\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -190,19 +190,19 @@ declare const GridStorm: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
190
190
|
onPaginationChanged?: ((...args: any[]) => any) | undefined;
|
|
191
191
|
onColumnResized?: ((...args: any[]) => any) | undefined;
|
|
192
192
|
}>, {
|
|
193
|
-
readonly getRowId: ((params: _gridstorm_core.GetRowIdParams<any>) => string) | undefined;
|
|
194
193
|
readonly width: string | number;
|
|
194
|
+
readonly getRowId: ((params: _gridstorm_core.GetRowIdParams<any>) => string) | undefined;
|
|
195
195
|
readonly plugins: _gridstorm_core.GridPlugin<any>[];
|
|
196
|
+
readonly defaultColDef: Partial<_gridstorm_core.ColumnDef<any, any>>;
|
|
196
197
|
readonly rowHeight: number;
|
|
197
198
|
readonly headerHeight: number;
|
|
198
|
-
readonly theme: string;
|
|
199
|
-
readonly density: string;
|
|
200
|
-
readonly defaultColDef: Partial<_gridstorm_core.ColumnDef<any, any>>;
|
|
201
|
-
readonly paginationPageSize: number;
|
|
202
|
-
readonly pagination: boolean;
|
|
203
199
|
readonly rowSelection: false | "single" | "multiple";
|
|
204
200
|
readonly editType: "cell" | "fullRow";
|
|
201
|
+
readonly pagination: boolean;
|
|
202
|
+
readonly paginationPageSize: number;
|
|
205
203
|
readonly ariaLabel: string;
|
|
204
|
+
readonly theme: string;
|
|
205
|
+
readonly density: string;
|
|
206
206
|
readonly height: string | number;
|
|
207
207
|
readonly containerClass: string;
|
|
208
208
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
package/dist/index.d.ts
CHANGED
|
@@ -190,19 +190,19 @@ declare const GridStorm: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
190
190
|
onPaginationChanged?: ((...args: any[]) => any) | undefined;
|
|
191
191
|
onColumnResized?: ((...args: any[]) => any) | undefined;
|
|
192
192
|
}>, {
|
|
193
|
-
readonly getRowId: ((params: _gridstorm_core.GetRowIdParams<any>) => string) | undefined;
|
|
194
193
|
readonly width: string | number;
|
|
194
|
+
readonly getRowId: ((params: _gridstorm_core.GetRowIdParams<any>) => string) | undefined;
|
|
195
195
|
readonly plugins: _gridstorm_core.GridPlugin<any>[];
|
|
196
|
+
readonly defaultColDef: Partial<_gridstorm_core.ColumnDef<any, any>>;
|
|
196
197
|
readonly rowHeight: number;
|
|
197
198
|
readonly headerHeight: number;
|
|
198
|
-
readonly theme: string;
|
|
199
|
-
readonly density: string;
|
|
200
|
-
readonly defaultColDef: Partial<_gridstorm_core.ColumnDef<any, any>>;
|
|
201
|
-
readonly paginationPageSize: number;
|
|
202
|
-
readonly pagination: boolean;
|
|
203
199
|
readonly rowSelection: false | "single" | "multiple";
|
|
204
200
|
readonly editType: "cell" | "fullRow";
|
|
201
|
+
readonly pagination: boolean;
|
|
202
|
+
readonly paginationPageSize: number;
|
|
205
203
|
readonly ariaLabel: string;
|
|
204
|
+
readonly theme: string;
|
|
205
|
+
readonly density: string;
|
|
206
206
|
readonly height: string | number;
|
|
207
207
|
readonly containerClass: string;
|
|
208
208
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, ref, shallowRef, provide, onMounted, onBeforeUnmount, watch, h, computed, onUnmounted, inject } from 'vue';
|
|
1
|
+
import { defineComponent, ref, shallowRef, provide, onErrorCaptured, onMounted, onBeforeUnmount, watch, h, computed, onUnmounted, inject } from 'vue';
|
|
2
2
|
import { createGrid } from '@gridstorm/core';
|
|
3
3
|
import { DomRenderer } from '@gridstorm/dom-renderer';
|
|
4
4
|
|
|
@@ -384,8 +384,19 @@ var GridStorm = defineComponent({
|
|
|
384
384
|
engine = null;
|
|
385
385
|
gridContext.value = null;
|
|
386
386
|
}
|
|
387
|
+
const error = ref(null);
|
|
388
|
+
onErrorCaptured((err) => {
|
|
389
|
+
error.value = err;
|
|
390
|
+
console.error("[GridStorm Vue] Error captured:", err);
|
|
391
|
+
return false;
|
|
392
|
+
});
|
|
387
393
|
onMounted(() => {
|
|
388
|
-
|
|
394
|
+
try {
|
|
395
|
+
initGrid();
|
|
396
|
+
} catch (err) {
|
|
397
|
+
error.value = err instanceof Error ? err : new Error(String(err));
|
|
398
|
+
console.error("[GridStorm Vue] Initialization error:", err);
|
|
399
|
+
}
|
|
389
400
|
});
|
|
390
401
|
onBeforeUnmount(() => {
|
|
391
402
|
destroyGrid();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/composables.ts","../src/GridStorm.ts"],"names":["ref","watch"],"mappings":"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","file":"index.js","sourcesContent":["// ─── Vue Adapter Types ───\n// Central type definitions for all Vue-specific interfaces.\n\nimport type {\n ColumnDef,\n GridApi,\n GridConfig,\n GridEngine,\n GridEventMap,\n GridPlugin,\n SortModelItem,\n FilterModel,\n RowNode,\n} from '@gridstorm/core';\nimport type { PropType } from 'vue';\n\n// ── Grid Context ──\n\n/**\n * Context value provided to child composables via Vue provide/inject.\n */\nexport interface GridContextValue<TData = any> {\n /** The grid engine instance. */\n engine: GridEngine<TData>;\n /** The public grid API. */\n api: GridApi<TData>;\n}\n\n// ── Component Props ──\n\n/**\n * Props interface for the GridStorm Vue component.\n *\n * @typeParam TData - The type of each row data object.\n */\nexport interface GridStormProps<TData = any> {\n /** Column definitions. */\n columns: ColumnDef<TData>[];\n /** Row data array. */\n rowData: TData[];\n /** Plugins to install. */\n plugins?: GridPlugin<TData>[];\n /** Row ID getter function. */\n getRowId?: GridConfig<TData>['getRowId'];\n /** Row height in pixels. */\n rowHeight?: number;\n /** Header height in pixels. */\n headerHeight?: number;\n /** Theme identifier (e.g., 'light', 'dark'). */\n theme?: string;\n /** Density mode (e.g., 'compact', 'normal', 'comfortable'). */\n density?: string;\n /** Default column definition applied to all columns. */\n defaultColDef?: Partial<ColumnDef<TData>>;\n /** Number of rows per page when pagination is enabled. */\n paginationPageSize?: number;\n /** Enable client-side pagination. */\n pagination?: boolean;\n /** Row selection mode. */\n rowSelection?: 'single' | 'multiple' | false;\n /** Edit type mode. */\n editType?: 'cell' | 'fullRow';\n /** ARIA label for the grid root element. */\n ariaLabel?: string;\n /** Container height. Default: '100%'. */\n height?: number | string;\n /** Container width. Default: '100%'. */\n width?: number | string;\n /** Additional CSS class for the container. */\n containerClass?: string;\n}\n\n/**\n * Vue prop definitions for the GridStorm component.\n * Used with defineComponent's props option.\n */\nexport const gridStormPropDefs = {\n columns: {\n type: Array as PropType<ColumnDef[]>,\n required: true as const,\n },\n rowData: {\n type: Array as PropType<any[]>,\n required: true as const,\n },\n plugins: {\n type: Array as PropType<GridPlugin[]>,\n default: () => [],\n },\n getRowId: {\n type: Function as PropType<GridConfig['getRowId']>,\n default: undefined,\n },\n rowHeight: {\n type: Number,\n default: 40,\n },\n headerHeight: {\n type: Number,\n default: undefined,\n },\n theme: {\n type: String,\n default: 'light',\n },\n density: {\n type: String,\n default: 'normal',\n },\n defaultColDef: {\n type: Object as PropType<Partial<ColumnDef>>,\n default: undefined,\n },\n paginationPageSize: {\n type: Number,\n default: undefined,\n },\n pagination: {\n type: Boolean,\n default: undefined,\n },\n rowSelection: {\n type: [String, Boolean] as PropType<'single' | 'multiple' | false>,\n default: undefined,\n },\n editType: {\n type: String as PropType<'cell' | 'fullRow'>,\n default: undefined,\n },\n ariaLabel: {\n type: String,\n default: undefined,\n },\n height: {\n type: [Number, String] as PropType<number | string>,\n default: '100%',\n },\n width: {\n type: [Number, String] as PropType<number | string>,\n default: '100%',\n },\n containerClass: {\n type: String,\n default: undefined,\n },\n} as const;\n\n// ── Event Types ──\n\n/**\n * All events emitted by the GridStorm Vue component.\n */\nexport interface GridStormEmits<TData = any> {\n /** Fired when the grid engine is ready and the API is available. */\n gridReady: [api: GridApi<TData>];\n /** Fired when row data changes. */\n rowDataChanged: [event: GridEventMap<TData>['rowData:changed']];\n /** Fired when the selection changes. */\n selectionChanged: [event: GridEventMap<TData>['selection:changed']];\n /** Fired when the sort model changes. */\n sortChanged: [event: GridEventMap<TData>['column:sort:changed']];\n /** Fired when the filter model changes. */\n filterChanged: [event: GridEventMap<TData>['filter:changed']];\n /** Fired when a cell value is changed via editing. */\n cellValueChanged: [event: GridEventMap<TData>['cell:valueChanged']];\n /** Fired when a cell is clicked. */\n cellClicked: [event: GridEventMap<TData>['cell:clicked']];\n /** Fired when a cell is double-clicked. */\n cellDoubleClicked: [event: GridEventMap<TData>['cell:doubleClicked']];\n /** Fired when a row is clicked. */\n rowClicked: [event: GridEventMap<TData>['row:clicked']];\n /** Fired when pagination state changes. */\n paginationChanged: [event: GridEventMap<TData>['pagination:changed']];\n /** Fired when a column is resized. */\n columnResized: [event: GridEventMap<TData>['column:resized']];\n}\n\n// ── Exposed API ──\n\n/**\n * Public methods exposed by the GridStorm component via template refs.\n *\n * @typeParam TData - The type of each row data object.\n */\nexport interface GridStormExposed<TData = any> {\n /** Get the GridApi instance. */\n getApi(): GridApi<TData> | undefined;\n /** Get the GridEngine instance. */\n getEngine(): GridEngine<TData> | undefined;\n}\n\n// ── Composable Return Types ──\n\n/**\n * Return type for the useGridSort composable.\n */\nexport interface GridSortResult {\n /** Current sort model (reactive). */\n sortModel: SortModelItem[];\n /** Whether any sort is active (reactive). */\n isSorted: boolean;\n /** Set the sort model directly. */\n setSortModel: (model: SortModelItem[]) => void;\n /** Toggle sort on a column. */\n toggleSort: (colId: string, multiSort?: boolean) => void;\n /** Clear all sorting. */\n clearSort: () => void;\n}\n\n/**\n * Return type for the useGridFilter composable.\n */\nexport interface GridFilterResult {\n /** Current filter model keyed by column ID (reactive). */\n filterModel: Record<string, FilterModel>;\n /** Current quick filter text (reactive). */\n quickFilterText: string;\n /** Whether any filter is active (reactive). */\n isFiltered: boolean;\n /** Set the filter model. */\n setFilterModel: (model: Record<string, FilterModel>) => void;\n /** Set quick filter text. */\n setQuickFilter: (text: string) => void;\n /** Clear all filters. */\n clearFilters: () => void;\n}\n\n/**\n * Return type for the useGridSelection composable.\n */\nexport interface GridSelectionResult<TData = any> {\n /** Set of selected row IDs (reactive). */\n selectedRowIds: Set<string>;\n /** Number of selected rows (reactive). */\n selectedCount: number;\n /** Get selected row data objects. */\n getSelectedRows: () => TData[];\n /** Get selected RowNode objects. */\n getSelectedNodes: () => RowNode<TData>[];\n /** Check if a specific row is selected. */\n isRowSelected: (rowId: string) => boolean;\n /** Select all visible rows. */\n selectAll: () => void;\n /** Deselect all rows. */\n deselectAll: () => void;\n}\n\n/**\n * Return type for the useGridPagination composable.\n */\nexport interface GridPaginationResult {\n /** Current page (0-indexed, reactive). */\n currentPage: number;\n /** Total number of pages (reactive). */\n totalPages: number;\n /** Rows per page (reactive). */\n pageSize: number;\n /** Total row count after filtering (reactive). */\n totalRows: number;\n /** Whether there is a next page (reactive). */\n hasNextPage: boolean;\n /** Whether there is a previous page (reactive). */\n hasPreviousPage: boolean;\n /** Go to a specific page. */\n goToPage: (page: number) => void;\n /** Go to next page. */\n nextPage: () => void;\n /** Go to previous page. */\n previousPage: () => void;\n /** Go to first page. */\n firstPage: () => void;\n /** Go to last page. */\n lastPage: () => void;\n}\n","// ─── Vue 3 Composables for GridStorm ───\n// Provide/inject-based composables that mirror the React hooks API.\n// All composables must be called inside a component that is a child of <GridStorm>.\n\nimport {\n inject,\n ref,\n onUnmounted,\n computed,\n watch,\n type InjectionKey,\n type Ref,\n type ShallowRef,\n} from 'vue';\nimport type { GridApi, GridEngine, SortModelItem, FilterModel, RowNode } from '@gridstorm/core';\nimport type { GridContextValue } from './types';\n\n// ── Context Key ──\n\n/**\n * Injection key used internally to provide/inject the grid context.\n * Uses ShallowRef to avoid deep reactive unwrapping of GridEngine internals\n * (the Store class has private fields incompatible with Vue's deep proxy typing).\n */\nexport const GRID_CONTEXT_KEY: InjectionKey<ShallowRef<GridContextValue | null>> =\n Symbol('gridstorm-context');\n\n// ── Internal helper ──\n\n/**\n * Internal helper to get the grid context with validation.\n * Throws if called outside a <GridStorm> component hierarchy.\n */\nfunction useGridContext<TData = any>(): ShallowRef<GridContextValue<TData> | null> {\n const context = inject(GRID_CONTEXT_KEY, null);\n if (!context) {\n throw new Error(\n '[GridStorm] Composable must be used within a <GridStorm> component.',\n );\n }\n return context as ShallowRef<GridContextValue<TData> | null>;\n}\n\n/**\n * Subscribe to the grid store and keep a reactive ref in sync.\n * Returns the reactive ref and automatically unsubscribes on unmount.\n */\nfunction useStoreRef<T>(\n context: ShallowRef<GridContextValue | null>,\n selector: (engine: GridEngine) => T,\n): Ref<T | undefined> {\n const value = ref<T | undefined>() as Ref<T | undefined>;\n let unsubscribe: (() => void) | null = null;\n\n function subscribe(ctx: GridContextValue | null) {\n // Clean up previous subscription\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n\n if (!ctx) {\n value.value = undefined;\n return;\n }\n\n // Set initial value\n value.value = selector(ctx.engine);\n\n // Subscribe to store changes\n unsubscribe = ctx.engine.store.subscribe(() => {\n value.value = selector(ctx.engine);\n });\n }\n\n // Watch for context changes (grid initialization/destruction)\n watch(context, (newCtx) => subscribe(newCtx), { immediate: true });\n\n onUnmounted(() => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n });\n\n return value;\n}\n\n// ── Public Composables ──\n\n/**\n * Access the GridApi instance from a parent GridStorm component.\n *\n * Returns a computed ref that resolves to the GridApi once the grid is initialized.\n * The ref will be undefined until the grid has mounted.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridApi } from '@gridstorm/vue';\n *\n * const api = useGridApi();\n *\n * function exportData() {\n * const rows = api.value?.getSelectedRows() ?? [];\n * console.log('Selected:', rows);\n * }\n * </script>\n * ```\n */\nexport function useGridApi<TData = any>(): Ref<GridApi<TData> | undefined> {\n const context = useGridContext<TData>();\n return computed(() => context.value?.api);\n}\n\n/**\n * Access the GridEngine instance from a parent GridStorm component.\n *\n * Primarily useful for advanced use cases that need direct access to\n * the store, event bus, or command bus.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridEngine } from '@gridstorm/vue';\n *\n * const engine = useGridEngine();\n * </script>\n * ```\n */\nexport function useGridEngine<TData = any>(): Ref<GridEngine<TData> | undefined> {\n const context = useGridContext<TData>();\n return computed(() => context.value?.engine);\n}\n\n/**\n * Reactive sort model state and sort actions.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridSort } from '@gridstorm/vue';\n *\n * const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();\n * </script>\n *\n * <template>\n * <button @click=\"toggleSort('name')\">Sort by Name</button>\n * <button v-if=\"isSorted\" @click=\"clearSort()\">Clear Sort</button>\n * <pre>{{ sortModel }}</pre>\n * </template>\n * ```\n */\nexport function useGridSort(): {\n sortModel: Ref<SortModelItem[]>;\n isSorted: Ref<boolean>;\n setSortModel: (model: SortModelItem[]) => void;\n toggleSort: (colId: string, multiSort?: boolean) => void;\n clearSort: () => void;\n} {\n const context = useGridContext();\n\n const sortModel = useStoreRef(context, (engine) =>\n engine.store.getState().sortModel,\n );\n\n const isSorted = computed(() => (sortModel.value?.length ?? 0) > 0);\n\n function setSortModel(model: SortModelItem[]): void {\n context.value?.api.setSortModel(model);\n }\n\n function toggleSort(colId: string, multiSort = false): void {\n context.value?.engine.commandBus.dispatch('sort:toggle', {\n colId,\n multiSort,\n });\n }\n\n function clearSort(): void {\n context.value?.api.setSortModel([]);\n }\n\n return {\n sortModel: sortModel as Ref<SortModelItem[]>,\n isSorted,\n setSortModel,\n toggleSort,\n clearSort,\n };\n}\n\n/**\n * Reactive filter model state and filter actions.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridFilter } from '@gridstorm/vue';\n *\n * const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();\n * </script>\n *\n * <template>\n * <input @input=\"(e) => setQuickFilter((e.target as HTMLInputElement).value)\" />\n * <button v-if=\"isFiltered\" @click=\"clearFilters()\">Clear Filters</button>\n * </template>\n * ```\n */\nexport function useGridFilter(): {\n filterModel: Ref<Record<string, FilterModel>>;\n quickFilterText: Ref<string>;\n isFiltered: Ref<boolean>;\n setFilterModel: (model: Record<string, FilterModel>) => void;\n setQuickFilter: (text: string) => void;\n clearFilters: () => void;\n} {\n const context = useGridContext();\n\n const filterModel = useStoreRef(context, (engine) =>\n engine.store.getState().filterModel,\n );\n\n const quickFilterText = useStoreRef(context, (engine) =>\n engine.store.getState().quickFilterText,\n );\n\n const isFiltered = computed(() => {\n const hasColumnFilters = Object.keys(filterModel.value ?? {}).length > 0;\n const hasQuickFilter = (quickFilterText.value ?? '').length > 0;\n return hasColumnFilters || hasQuickFilter;\n });\n\n function setFilterModel(model: Record<string, FilterModel>): void {\n context.value?.api.setFilterModel(model);\n }\n\n function setQuickFilter(text: string): void {\n context.value?.api.setQuickFilter(text);\n }\n\n function clearFilters(): void {\n context.value?.api.setFilterModel({});\n context.value?.api.setQuickFilter('');\n }\n\n return {\n filterModel: filterModel as Ref<Record<string, FilterModel>>,\n quickFilterText: quickFilterText as Ref<string>,\n isFiltered,\n setFilterModel,\n setQuickFilter,\n clearFilters,\n };\n}\n\n/**\n * Reactive selection state and selection actions.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridSelection } from '@gridstorm/vue';\n *\n * const { selectedCount, selectAll, deselectAll, isRowSelected } = useGridSelection();\n * </script>\n *\n * <template>\n * <p>{{ selectedCount }} rows selected</p>\n * <button @click=\"selectAll()\">Select All</button>\n * <button @click=\"deselectAll()\">Deselect All</button>\n * </template>\n * ```\n */\nexport function useGridSelection<TData = any>(): {\n selectedRowIds: Ref<Set<string>>;\n selectedCount: Ref<number>;\n getSelectedRows: () => TData[];\n getSelectedNodes: () => RowNode<TData>[];\n isRowSelected: (rowId: string) => boolean;\n selectAll: () => void;\n deselectAll: () => void;\n} {\n const context = useGridContext<TData>();\n\n const selectedRowIds = useStoreRef(context, (engine) =>\n engine.store.getState().selection.selectedRowIds,\n );\n\n const selectedCount = computed(() => selectedRowIds.value?.size ?? 0);\n\n function getSelectedRows(): TData[] {\n return context.value?.api.getSelectedRows() ?? [];\n }\n\n function getSelectedNodes(): RowNode<TData>[] {\n return context.value?.api.getSelectedNodes() ?? [];\n }\n\n function isRowSelected(rowId: string): boolean {\n return selectedRowIds.value?.has(rowId) ?? false;\n }\n\n function selectAll(): void {\n context.value?.api.selectAll();\n }\n\n function deselectAll(): void {\n context.value?.api.deselectAll();\n }\n\n return {\n selectedRowIds: selectedRowIds as Ref<Set<string>>,\n selectedCount,\n getSelectedRows,\n getSelectedNodes,\n isRowSelected,\n selectAll,\n deselectAll,\n };\n}\n\n/**\n * Reactive pagination state and navigation actions.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridPagination } from '@gridstorm/vue';\n *\n * const {\n * currentPage,\n * totalPages,\n * hasNextPage,\n * hasPreviousPage,\n * nextPage,\n * previousPage,\n * } = useGridPagination();\n * </script>\n *\n * <template>\n * <div class=\"pagination\">\n * <button :disabled=\"!hasPreviousPage\" @click=\"previousPage()\">Prev</button>\n * <span>Page {{ currentPage + 1 }} of {{ totalPages }}</span>\n * <button :disabled=\"!hasNextPage\" @click=\"nextPage()\">Next</button>\n * </div>\n * </template>\n * ```\n */\nexport function useGridPagination(): {\n currentPage: Ref<number>;\n totalPages: Ref<number>;\n pageSize: Ref<number>;\n totalRows: Ref<number>;\n hasNextPage: Ref<boolean>;\n hasPreviousPage: Ref<boolean>;\n goToPage: (page: number) => void;\n nextPage: () => void;\n previousPage: () => void;\n firstPage: () => void;\n lastPage: () => void;\n} {\n const context = useGridContext();\n\n const paginationState = useStoreRef(context, (engine) =>\n engine.store.getState().pagination,\n );\n\n const currentPage = computed(() => paginationState.value?.currentPage ?? 0);\n const pageSize = computed(() => paginationState.value?.pageSize ?? 100);\n const totalRows = computed(() => paginationState.value?.totalRows ?? 0);\n const totalPages = computed(() =>\n Math.max(1, Math.ceil(totalRows.value / pageSize.value)),\n );\n const hasNextPage = computed(() => currentPage.value < totalPages.value - 1);\n const hasPreviousPage = computed(() => currentPage.value > 0);\n\n function goToPage(page: number): void {\n context.value?.api.paginationGoToPage(page);\n }\n\n function nextPage(): void {\n if (hasNextPage.value) {\n context.value?.api.paginationGoToPage(currentPage.value + 1);\n }\n }\n\n function previousPage(): void {\n if (hasPreviousPage.value) {\n context.value?.api.paginationGoToPage(currentPage.value - 1);\n }\n }\n\n function firstPage(): void {\n context.value?.api.paginationGoToPage(0);\n }\n\n function lastPage(): void {\n context.value?.api.paginationGoToPage(totalPages.value - 1);\n }\n\n return {\n currentPage,\n totalPages,\n pageSize,\n totalRows,\n hasNextPage,\n hasPreviousPage,\n goToPage,\n nextPage,\n previousPage,\n firstPage,\n lastPage,\n };\n}\n\n/**\n * Listen to a specific grid event with automatic cleanup on unmount.\n *\n * @param event - The event name from GridEventMap.\n * @param handler - Callback function invoked when the event fires.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useGridEvent } from '@gridstorm/vue';\n *\n * useGridEvent('selection:changed', (e) => {\n * console.log('Selection changed:', e.selectedNodes);\n * });\n * </script>\n * ```\n */\nexport function useGridEvent<TData = any>(\n event: string,\n handler: (payload: any) => void,\n): void {\n const context = useGridContext<TData>();\n let unsubscribe: (() => void) | null = null;\n\n watch(\n context,\n (ctx) => {\n // Clean up previous listener\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n\n if (ctx) {\n unsubscribe = ctx.engine.eventBus.on(event as any, handler);\n }\n },\n { immediate: true },\n );\n\n onUnmounted(() => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n });\n}\n","// ─── GridStorm Vue 3 Component ───\n// Production-grade Vue wrapper around the headless core engine.\n// Uses defineComponent with a render function (no .vue SFC) for tsup compatibility.\n// Supports event emission, reactive prop watching, and composable injection.\n\nimport {\n defineComponent,\n ref,\n shallowRef,\n onMounted,\n onBeforeUnmount,\n watch,\n provide,\n h,\n} from 'vue';\nimport type { GridEngine } from '@gridstorm/core';\nimport { createGrid } from '@gridstorm/core';\nimport { DomRenderer } from '@gridstorm/dom-renderer';\nimport { gridStormPropDefs } from './types';\nimport type { GridContextValue } from './types';\nimport { GRID_CONTEXT_KEY } from './composables';\n\n/**\n * GridStorm Vue 3 component.\n *\n * Wraps the headless GridStorm core engine and DOM renderer into a Vue component\n * with reactive prop watching, event emission, and provide/inject context for\n * child composables.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { GridStorm } from '@gridstorm/vue';\n * import { sortingPlugin } from '@gridstorm/plugin-sorting';\n *\n * const columns = [\n * { field: 'name', headerName: 'Name', sortable: true },\n * { field: 'age', headerName: 'Age', width: 100 },\n * ];\n * const rowData = [\n * { name: 'Alice', age: 30 },\n * { name: 'Bob', age: 25 },\n * ];\n * </script>\n *\n * <template>\n * <GridStorm\n * :columns=\"columns\"\n * :row-data=\"rowData\"\n * :plugins=\"[sortingPlugin()]\"\n * @grid-ready=\"(api) => console.log('Grid ready!', api)\"\n * />\n * </template>\n * ```\n */\nexport const GridStorm = defineComponent({\n name: 'GridStorm',\n\n props: gridStormPropDefs,\n\n emits: [\n 'gridReady',\n 'rowDataChanged',\n 'selectionChanged',\n 'sortChanged',\n 'filterChanged',\n 'cellValueChanged',\n 'cellClicked',\n 'cellDoubleClicked',\n 'rowClicked',\n 'paginationChanged',\n 'columnResized',\n ],\n\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLElement | null>(null);\n let engine: GridEngine | null = null;\n let renderer: DomRenderer | null = null;\n const eventUnsubscribers: Array<() => void> = [];\n\n // ── Build GridConfig from props ──\n function buildConfig() {\n return {\n columns: props.columns as any,\n rowData: props.rowData as any,\n plugins: props.plugins as any,\n getRowId: props.getRowId as any,\n rowHeight: props.rowHeight,\n headerHeight: props.headerHeight,\n defaultColDef: props.defaultColDef as any,\n paginationPageSize: props.paginationPageSize,\n pagination: props.pagination,\n rowSelection: props.rowSelection as any,\n editType: props.editType as any,\n ariaLabel: props.ariaLabel,\n };\n }\n\n // ── Subscribe to engine events and bridge to Vue emits ──\n function subscribeToEvents() {\n if (!engine) return;\n\n const eb = engine.eventBus;\n\n eventUnsubscribers.push(\n eb.on('rowData:changed', (e) => emit('rowDataChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('selection:changed', (e) => emit('selectionChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('column:sort:changed', (e) => emit('sortChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('filter:changed', (e) => emit('filterChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('cell:valueChanged', (e) => emit('cellValueChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('cell:clicked', (e) => emit('cellClicked', e)),\n );\n eventUnsubscribers.push(\n eb.on('cell:doubleClicked', (e) => emit('cellDoubleClicked', e)),\n );\n eventUnsubscribers.push(\n eb.on('row:clicked', (e) => emit('rowClicked', e)),\n );\n eventUnsubscribers.push(\n eb.on('pagination:changed', (e) => emit('paginationChanged', e)),\n );\n eventUnsubscribers.push(\n eb.on('column:resized', (e) => emit('columnResized', e)),\n );\n }\n\n // ── Provide context for composables ──\n // Use shallowRef to avoid deep unwrapping of GridEngine internals\n // (Store class has private fields that break Vue's deep reactive proxy typing)\n const gridContext = shallowRef<GridContextValue | null>(null);\n\n provide(GRID_CONTEXT_KEY, gridContext);\n\n // ── Initialize grid engine and renderer ──\n function initGrid() {\n if (!containerRef.value) return;\n\n const config = buildConfig();\n engine = createGrid(config);\n\n // Update context for composables\n gridContext.value = {\n engine,\n api: engine.api,\n };\n\n // Mount DOM renderer\n renderer = new DomRenderer({\n container: containerRef.value,\n engine,\n });\n renderer.mount();\n\n // Subscribe to events\n subscribeToEvents();\n\n // Emit gridReady\n emit('gridReady', engine.api);\n }\n\n // ── Teardown ──\n function destroyGrid() {\n // Unsubscribe from all events\n for (const unsub of eventUnsubscribers) {\n unsub();\n }\n eventUnsubscribers.length = 0;\n\n renderer?.destroy();\n renderer = null;\n\n engine?.destroy();\n engine = null;\n\n gridContext.value = null;\n }\n\n // ── Lifecycle ──\n onMounted(() => {\n initGrid();\n });\n\n onBeforeUnmount(() => {\n destroyGrid();\n });\n\n // ── Watch for rowData changes ──\n watch(\n () => props.rowData,\n (newData) => {\n if (engine && newData) {\n engine.api.setRowData(newData as any);\n }\n },\n { deep: false },\n );\n\n // ── Watch for column changes ──\n watch(\n () => props.columns,\n (newCols) => {\n if (engine && newCols) {\n engine.api.setColumnDefs(newCols as any);\n }\n },\n { deep: false },\n );\n\n // ── Watch for theme changes ──\n watch(\n () => props.theme,\n (newTheme) => {\n if (containerRef.value && newTheme) {\n containerRef.value.setAttribute('data-theme', newTheme);\n }\n },\n );\n\n // ── Watch for density changes ──\n watch(\n () => props.density,\n (newDensity) => {\n if (containerRef.value && newDensity) {\n containerRef.value.setAttribute('data-density', newDensity);\n }\n },\n );\n\n // ── Expose public API via template refs ──\n expose({\n /**\n * Get the GridApi instance.\n * Returns undefined if the grid has not been initialized yet.\n */\n getApi: () => engine?.api,\n\n /**\n * Get the GridEngine instance.\n * Returns undefined if the grid has not been initialized yet.\n */\n getEngine: () => engine,\n });\n\n // ── Render function ──\n return () => {\n const heightStyle =\n typeof props.height === 'number' ? `${props.height}px` : props.height;\n const widthStyle =\n typeof props.width === 'number' ? `${props.width}px` : props.width;\n\n return h('div', {\n ref: containerRef,\n class: ['gridstorm-wrapper', props.containerClass].filter(Boolean).join(' '),\n 'data-theme': props.theme,\n 'data-density': props.density,\n style: {\n width: widthStyle,\n height: heightStyle,\n },\n });\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/composables.ts","../src/GridStorm.ts"],"names":["ref","watch"],"mappings":"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","file":"index.js","sourcesContent":["// ─── Vue Adapter Types ───\r\n// Central type definitions for all Vue-specific interfaces.\r\n\r\nimport type {\r\n ColumnDef,\r\n GridApi,\r\n GridConfig,\r\n GridEngine,\r\n GridEventMap,\r\n GridPlugin,\r\n SortModelItem,\r\n FilterModel,\r\n RowNode,\r\n} from '@gridstorm/core';\r\nimport type { PropType } from 'vue';\r\n\r\n// ── Grid Context ──\r\n\r\n/**\r\n * Context value provided to child composables via Vue provide/inject.\r\n */\r\nexport interface GridContextValue<TData = any> {\r\n /** The grid engine instance. */\r\n engine: GridEngine<TData>;\r\n /** The public grid API. */\r\n api: GridApi<TData>;\r\n}\r\n\r\n// ── Component Props ──\r\n\r\n/**\r\n * Props interface for the GridStorm Vue component.\r\n *\r\n * @typeParam TData - The type of each row data object.\r\n */\r\nexport interface GridStormProps<TData = any> {\r\n /** Column definitions. */\r\n columns: ColumnDef<TData>[];\r\n /** Row data array. */\r\n rowData: TData[];\r\n /** Plugins to install. */\r\n plugins?: GridPlugin<TData>[];\r\n /** Row ID getter function. */\r\n getRowId?: GridConfig<TData>['getRowId'];\r\n /** Row height in pixels. */\r\n rowHeight?: number;\r\n /** Header height in pixels. */\r\n headerHeight?: number;\r\n /** Theme identifier (e.g., 'light', 'dark'). */\r\n theme?: string;\r\n /** Density mode (e.g., 'compact', 'normal', 'comfortable'). */\r\n density?: string;\r\n /** Default column definition applied to all columns. */\r\n defaultColDef?: Partial<ColumnDef<TData>>;\r\n /** Number of rows per page when pagination is enabled. */\r\n paginationPageSize?: number;\r\n /** Enable client-side pagination. */\r\n pagination?: boolean;\r\n /** Row selection mode. */\r\n rowSelection?: 'single' | 'multiple' | false;\r\n /** Edit type mode. */\r\n editType?: 'cell' | 'fullRow';\r\n /** ARIA label for the grid root element. */\r\n ariaLabel?: string;\r\n /** Container height. Default: '100%'. */\r\n height?: number | string;\r\n /** Container width. Default: '100%'. */\r\n width?: number | string;\r\n /** Additional CSS class for the container. */\r\n containerClass?: string;\r\n}\r\n\r\n/**\r\n * Vue prop definitions for the GridStorm component.\r\n * Used with defineComponent's props option.\r\n */\r\nexport const gridStormPropDefs = {\r\n columns: {\r\n type: Array as PropType<ColumnDef[]>,\r\n required: true as const,\r\n },\r\n rowData: {\r\n type: Array as PropType<any[]>,\r\n required: true as const,\r\n },\r\n plugins: {\r\n type: Array as PropType<GridPlugin[]>,\r\n default: () => [],\r\n },\r\n getRowId: {\r\n type: Function as PropType<GridConfig['getRowId']>,\r\n default: undefined,\r\n },\r\n rowHeight: {\r\n type: Number,\r\n default: 40,\r\n },\r\n headerHeight: {\r\n type: Number,\r\n default: undefined,\r\n },\r\n theme: {\r\n type: String,\r\n default: 'light',\r\n },\r\n density: {\r\n type: String,\r\n default: 'normal',\r\n },\r\n defaultColDef: {\r\n type: Object as PropType<Partial<ColumnDef>>,\r\n default: undefined,\r\n },\r\n paginationPageSize: {\r\n type: Number,\r\n default: undefined,\r\n },\r\n pagination: {\r\n type: Boolean,\r\n default: undefined,\r\n },\r\n rowSelection: {\r\n type: [String, Boolean] as PropType<'single' | 'multiple' | false>,\r\n default: undefined,\r\n },\r\n editType: {\r\n type: String as PropType<'cell' | 'fullRow'>,\r\n default: undefined,\r\n },\r\n ariaLabel: {\r\n type: String,\r\n default: undefined,\r\n },\r\n height: {\r\n type: [Number, String] as PropType<number | string>,\r\n default: '100%',\r\n },\r\n width: {\r\n type: [Number, String] as PropType<number | string>,\r\n default: '100%',\r\n },\r\n containerClass: {\r\n type: String,\r\n default: undefined,\r\n },\r\n} as const;\r\n\r\n// ── Event Types ──\r\n\r\n/**\r\n * All events emitted by the GridStorm Vue component.\r\n */\r\nexport interface GridStormEmits<TData = any> {\r\n /** Fired when the grid engine is ready and the API is available. */\r\n gridReady: [api: GridApi<TData>];\r\n /** Fired when row data changes. */\r\n rowDataChanged: [event: GridEventMap<TData>['rowData:changed']];\r\n /** Fired when the selection changes. */\r\n selectionChanged: [event: GridEventMap<TData>['selection:changed']];\r\n /** Fired when the sort model changes. */\r\n sortChanged: [event: GridEventMap<TData>['column:sort:changed']];\r\n /** Fired when the filter model changes. */\r\n filterChanged: [event: GridEventMap<TData>['filter:changed']];\r\n /** Fired when a cell value is changed via editing. */\r\n cellValueChanged: [event: GridEventMap<TData>['cell:valueChanged']];\r\n /** Fired when a cell is clicked. */\r\n cellClicked: [event: GridEventMap<TData>['cell:clicked']];\r\n /** Fired when a cell is double-clicked. */\r\n cellDoubleClicked: [event: GridEventMap<TData>['cell:doubleClicked']];\r\n /** Fired when a row is clicked. */\r\n rowClicked: [event: GridEventMap<TData>['row:clicked']];\r\n /** Fired when pagination state changes. */\r\n paginationChanged: [event: GridEventMap<TData>['pagination:changed']];\r\n /** Fired when a column is resized. */\r\n columnResized: [event: GridEventMap<TData>['column:resized']];\r\n}\r\n\r\n// ── Exposed API ──\r\n\r\n/**\r\n * Public methods exposed by the GridStorm component via template refs.\r\n *\r\n * @typeParam TData - The type of each row data object.\r\n */\r\nexport interface GridStormExposed<TData = any> {\r\n /** Get the GridApi instance. */\r\n getApi(): GridApi<TData> | undefined;\r\n /** Get the GridEngine instance. */\r\n getEngine(): GridEngine<TData> | undefined;\r\n}\r\n\r\n// ── Composable Return Types ──\r\n\r\n/**\r\n * Return type for the useGridSort composable.\r\n */\r\nexport interface GridSortResult {\r\n /** Current sort model (reactive). */\r\n sortModel: SortModelItem[];\r\n /** Whether any sort is active (reactive). */\r\n isSorted: boolean;\r\n /** Set the sort model directly. */\r\n setSortModel: (model: SortModelItem[]) => void;\r\n /** Toggle sort on a column. */\r\n toggleSort: (colId: string, multiSort?: boolean) => void;\r\n /** Clear all sorting. */\r\n clearSort: () => void;\r\n}\r\n\r\n/**\r\n * Return type for the useGridFilter composable.\r\n */\r\nexport interface GridFilterResult {\r\n /** Current filter model keyed by column ID (reactive). */\r\n filterModel: Record<string, FilterModel>;\r\n /** Current quick filter text (reactive). */\r\n quickFilterText: string;\r\n /** Whether any filter is active (reactive). */\r\n isFiltered: boolean;\r\n /** Set the filter model. */\r\n setFilterModel: (model: Record<string, FilterModel>) => void;\r\n /** Set quick filter text. */\r\n setQuickFilter: (text: string) => void;\r\n /** Clear all filters. */\r\n clearFilters: () => void;\r\n}\r\n\r\n/**\r\n * Return type for the useGridSelection composable.\r\n */\r\nexport interface GridSelectionResult<TData = any> {\r\n /** Set of selected row IDs (reactive). */\r\n selectedRowIds: Set<string>;\r\n /** Number of selected rows (reactive). */\r\n selectedCount: number;\r\n /** Get selected row data objects. */\r\n getSelectedRows: () => TData[];\r\n /** Get selected RowNode objects. */\r\n getSelectedNodes: () => RowNode<TData>[];\r\n /** Check if a specific row is selected. */\r\n isRowSelected: (rowId: string) => boolean;\r\n /** Select all visible rows. */\r\n selectAll: () => void;\r\n /** Deselect all rows. */\r\n deselectAll: () => void;\r\n}\r\n\r\n/**\r\n * Return type for the useGridPagination composable.\r\n */\r\nexport interface GridPaginationResult {\r\n /** Current page (0-indexed, reactive). */\r\n currentPage: number;\r\n /** Total number of pages (reactive). */\r\n totalPages: number;\r\n /** Rows per page (reactive). */\r\n pageSize: number;\r\n /** Total row count after filtering (reactive). */\r\n totalRows: number;\r\n /** Whether there is a next page (reactive). */\r\n hasNextPage: boolean;\r\n /** Whether there is a previous page (reactive). */\r\n hasPreviousPage: boolean;\r\n /** Go to a specific page. */\r\n goToPage: (page: number) => void;\r\n /** Go to next page. */\r\n nextPage: () => void;\r\n /** Go to previous page. */\r\n previousPage: () => void;\r\n /** Go to first page. */\r\n firstPage: () => void;\r\n /** Go to last page. */\r\n lastPage: () => void;\r\n}\r\n","// ─── Vue 3 Composables for GridStorm ───\r\n// Provide/inject-based composables that mirror the React hooks API.\r\n// All composables must be called inside a component that is a child of <GridStorm>.\r\n\r\nimport {\r\n inject,\r\n ref,\r\n onUnmounted,\r\n computed,\r\n watch,\r\n type InjectionKey,\r\n type Ref,\r\n type ShallowRef,\r\n} from 'vue';\r\nimport type { GridApi, GridEngine, SortModelItem, FilterModel, RowNode } from '@gridstorm/core';\r\nimport type { GridContextValue } from './types';\r\n\r\n// ── Context Key ──\r\n\r\n/**\r\n * Injection key used internally to provide/inject the grid context.\r\n * Uses ShallowRef to avoid deep reactive unwrapping of GridEngine internals\r\n * (the Store class has private fields incompatible with Vue's deep proxy typing).\r\n */\r\nexport const GRID_CONTEXT_KEY: InjectionKey<ShallowRef<GridContextValue | null>> =\r\n Symbol('gridstorm-context');\r\n\r\n// ── Internal helper ──\r\n\r\n/**\r\n * Internal helper to get the grid context with validation.\r\n * Throws if called outside a <GridStorm> component hierarchy.\r\n */\r\nfunction useGridContext<TData = any>(): ShallowRef<GridContextValue<TData> | null> {\r\n const context = inject(GRID_CONTEXT_KEY, null);\r\n if (!context) {\r\n throw new Error(\r\n '[GridStorm] Composable must be used within a <GridStorm> component.',\r\n );\r\n }\r\n return context as ShallowRef<GridContextValue<TData> | null>;\r\n}\r\n\r\n/**\r\n * Subscribe to the grid store and keep a reactive ref in sync.\r\n * Returns the reactive ref and automatically unsubscribes on unmount.\r\n */\r\nfunction useStoreRef<T>(\r\n context: ShallowRef<GridContextValue | null>,\r\n selector: (engine: GridEngine) => T,\r\n): Ref<T | undefined> {\r\n const value = ref<T | undefined>() as Ref<T | undefined>;\r\n let unsubscribe: (() => void) | null = null;\r\n\r\n function subscribe(ctx: GridContextValue | null) {\r\n // Clean up previous subscription\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n\r\n if (!ctx) {\r\n value.value = undefined;\r\n return;\r\n }\r\n\r\n // Set initial value\r\n value.value = selector(ctx.engine);\r\n\r\n // Subscribe to store changes\r\n unsubscribe = ctx.engine.store.subscribe(() => {\r\n value.value = selector(ctx.engine);\r\n });\r\n }\r\n\r\n // Watch for context changes (grid initialization/destruction)\r\n watch(context, (newCtx) => subscribe(newCtx), { immediate: true });\r\n\r\n onUnmounted(() => {\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n });\r\n\r\n return value;\r\n}\r\n\r\n// ── Public Composables ──\r\n\r\n/**\r\n * Access the GridApi instance from a parent GridStorm component.\r\n *\r\n * Returns a computed ref that resolves to the GridApi once the grid is initialized.\r\n * The ref will be undefined until the grid has mounted.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridApi } from '@gridstorm/vue';\r\n *\r\n * const api = useGridApi();\r\n *\r\n * function exportData() {\r\n * const rows = api.value?.getSelectedRows() ?? [];\r\n * console.log('Selected:', rows);\r\n * }\r\n * </script>\r\n * ```\r\n */\r\nexport function useGridApi<TData = any>(): Ref<GridApi<TData> | undefined> {\r\n const context = useGridContext<TData>();\r\n return computed(() => context.value?.api);\r\n}\r\n\r\n/**\r\n * Access the GridEngine instance from a parent GridStorm component.\r\n *\r\n * Primarily useful for advanced use cases that need direct access to\r\n * the store, event bus, or command bus.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridEngine } from '@gridstorm/vue';\r\n *\r\n * const engine = useGridEngine();\r\n * </script>\r\n * ```\r\n */\r\nexport function useGridEngine<TData = any>(): Ref<GridEngine<TData> | undefined> {\r\n const context = useGridContext<TData>();\r\n return computed(() => context.value?.engine);\r\n}\r\n\r\n/**\r\n * Reactive sort model state and sort actions.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridSort } from '@gridstorm/vue';\r\n *\r\n * const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();\r\n * </script>\r\n *\r\n * <template>\r\n * <button @click=\"toggleSort('name')\">Sort by Name</button>\r\n * <button v-if=\"isSorted\" @click=\"clearSort()\">Clear Sort</button>\r\n * <pre>{{ sortModel }}</pre>\r\n * </template>\r\n * ```\r\n */\r\nexport function useGridSort(): {\r\n sortModel: Ref<SortModelItem[]>;\r\n isSorted: Ref<boolean>;\r\n setSortModel: (model: SortModelItem[]) => void;\r\n toggleSort: (colId: string, multiSort?: boolean) => void;\r\n clearSort: () => void;\r\n} {\r\n const context = useGridContext();\r\n\r\n const sortModel = useStoreRef(context, (engine) =>\r\n engine.store.getState().sortModel,\r\n );\r\n\r\n const isSorted = computed(() => (sortModel.value?.length ?? 0) > 0);\r\n\r\n function setSortModel(model: SortModelItem[]): void {\r\n context.value?.api.setSortModel(model);\r\n }\r\n\r\n function toggleSort(colId: string, multiSort = false): void {\r\n context.value?.engine.commandBus.dispatch('sort:toggle', {\r\n colId,\r\n multiSort,\r\n });\r\n }\r\n\r\n function clearSort(): void {\r\n context.value?.api.setSortModel([]);\r\n }\r\n\r\n return {\r\n sortModel: sortModel as Ref<SortModelItem[]>,\r\n isSorted,\r\n setSortModel,\r\n toggleSort,\r\n clearSort,\r\n };\r\n}\r\n\r\n/**\r\n * Reactive filter model state and filter actions.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridFilter } from '@gridstorm/vue';\r\n *\r\n * const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();\r\n * </script>\r\n *\r\n * <template>\r\n * <input @input=\"(e) => setQuickFilter((e.target as HTMLInputElement).value)\" />\r\n * <button v-if=\"isFiltered\" @click=\"clearFilters()\">Clear Filters</button>\r\n * </template>\r\n * ```\r\n */\r\nexport function useGridFilter(): {\r\n filterModel: Ref<Record<string, FilterModel>>;\r\n quickFilterText: Ref<string>;\r\n isFiltered: Ref<boolean>;\r\n setFilterModel: (model: Record<string, FilterModel>) => void;\r\n setQuickFilter: (text: string) => void;\r\n clearFilters: () => void;\r\n} {\r\n const context = useGridContext();\r\n\r\n const filterModel = useStoreRef(context, (engine) =>\r\n engine.store.getState().filterModel,\r\n );\r\n\r\n const quickFilterText = useStoreRef(context, (engine) =>\r\n engine.store.getState().quickFilterText,\r\n );\r\n\r\n const isFiltered = computed(() => {\r\n const hasColumnFilters = Object.keys(filterModel.value ?? {}).length > 0;\r\n const hasQuickFilter = (quickFilterText.value ?? '').length > 0;\r\n return hasColumnFilters || hasQuickFilter;\r\n });\r\n\r\n function setFilterModel(model: Record<string, FilterModel>): void {\r\n context.value?.api.setFilterModel(model);\r\n }\r\n\r\n function setQuickFilter(text: string): void {\r\n context.value?.api.setQuickFilter(text);\r\n }\r\n\r\n function clearFilters(): void {\r\n context.value?.api.setFilterModel({});\r\n context.value?.api.setQuickFilter('');\r\n }\r\n\r\n return {\r\n filterModel: filterModel as Ref<Record<string, FilterModel>>,\r\n quickFilterText: quickFilterText as Ref<string>,\r\n isFiltered,\r\n setFilterModel,\r\n setQuickFilter,\r\n clearFilters,\r\n };\r\n}\r\n\r\n/**\r\n * Reactive selection state and selection actions.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridSelection } from '@gridstorm/vue';\r\n *\r\n * const { selectedCount, selectAll, deselectAll, isRowSelected } = useGridSelection();\r\n * </script>\r\n *\r\n * <template>\r\n * <p>{{ selectedCount }} rows selected</p>\r\n * <button @click=\"selectAll()\">Select All</button>\r\n * <button @click=\"deselectAll()\">Deselect All</button>\r\n * </template>\r\n * ```\r\n */\r\nexport function useGridSelection<TData = any>(): {\r\n selectedRowIds: Ref<Set<string>>;\r\n selectedCount: Ref<number>;\r\n getSelectedRows: () => TData[];\r\n getSelectedNodes: () => RowNode<TData>[];\r\n isRowSelected: (rowId: string) => boolean;\r\n selectAll: () => void;\r\n deselectAll: () => void;\r\n} {\r\n const context = useGridContext<TData>();\r\n\r\n const selectedRowIds = useStoreRef(context, (engine) =>\r\n engine.store.getState().selection.selectedRowIds,\r\n );\r\n\r\n const selectedCount = computed(() => selectedRowIds.value?.size ?? 0);\r\n\r\n function getSelectedRows(): TData[] {\r\n return context.value?.api.getSelectedRows() ?? [];\r\n }\r\n\r\n function getSelectedNodes(): RowNode<TData>[] {\r\n return context.value?.api.getSelectedNodes() ?? [];\r\n }\r\n\r\n function isRowSelected(rowId: string): boolean {\r\n return selectedRowIds.value?.has(rowId) ?? false;\r\n }\r\n\r\n function selectAll(): void {\r\n context.value?.api.selectAll();\r\n }\r\n\r\n function deselectAll(): void {\r\n context.value?.api.deselectAll();\r\n }\r\n\r\n return {\r\n selectedRowIds: selectedRowIds as Ref<Set<string>>,\r\n selectedCount,\r\n getSelectedRows,\r\n getSelectedNodes,\r\n isRowSelected,\r\n selectAll,\r\n deselectAll,\r\n };\r\n}\r\n\r\n/**\r\n * Reactive pagination state and navigation actions.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridPagination } from '@gridstorm/vue';\r\n *\r\n * const {\r\n * currentPage,\r\n * totalPages,\r\n * hasNextPage,\r\n * hasPreviousPage,\r\n * nextPage,\r\n * previousPage,\r\n * } = useGridPagination();\r\n * </script>\r\n *\r\n * <template>\r\n * <div class=\"pagination\">\r\n * <button :disabled=\"!hasPreviousPage\" @click=\"previousPage()\">Prev</button>\r\n * <span>Page {{ currentPage + 1 }} of {{ totalPages }}</span>\r\n * <button :disabled=\"!hasNextPage\" @click=\"nextPage()\">Next</button>\r\n * </div>\r\n * </template>\r\n * ```\r\n */\r\nexport function useGridPagination(): {\r\n currentPage: Ref<number>;\r\n totalPages: Ref<number>;\r\n pageSize: Ref<number>;\r\n totalRows: Ref<number>;\r\n hasNextPage: Ref<boolean>;\r\n hasPreviousPage: Ref<boolean>;\r\n goToPage: (page: number) => void;\r\n nextPage: () => void;\r\n previousPage: () => void;\r\n firstPage: () => void;\r\n lastPage: () => void;\r\n} {\r\n const context = useGridContext();\r\n\r\n const paginationState = useStoreRef(context, (engine) =>\r\n engine.store.getState().pagination,\r\n );\r\n\r\n const currentPage = computed(() => paginationState.value?.currentPage ?? 0);\r\n const pageSize = computed(() => paginationState.value?.pageSize ?? 100);\r\n const totalRows = computed(() => paginationState.value?.totalRows ?? 0);\r\n const totalPages = computed(() =>\r\n Math.max(1, Math.ceil(totalRows.value / pageSize.value)),\r\n );\r\n const hasNextPage = computed(() => currentPage.value < totalPages.value - 1);\r\n const hasPreviousPage = computed(() => currentPage.value > 0);\r\n\r\n function goToPage(page: number): void {\r\n context.value?.api.paginationGoToPage(page);\r\n }\r\n\r\n function nextPage(): void {\r\n if (hasNextPage.value) {\r\n context.value?.api.paginationGoToPage(currentPage.value + 1);\r\n }\r\n }\r\n\r\n function previousPage(): void {\r\n if (hasPreviousPage.value) {\r\n context.value?.api.paginationGoToPage(currentPage.value - 1);\r\n }\r\n }\r\n\r\n function firstPage(): void {\r\n context.value?.api.paginationGoToPage(0);\r\n }\r\n\r\n function lastPage(): void {\r\n context.value?.api.paginationGoToPage(totalPages.value - 1);\r\n }\r\n\r\n return {\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n };\r\n}\r\n\r\n/**\r\n * Listen to a specific grid event with automatic cleanup on unmount.\r\n *\r\n * @param event - The event name from GridEventMap.\r\n * @param handler - Callback function invoked when the event fires.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { useGridEvent } from '@gridstorm/vue';\r\n *\r\n * useGridEvent('selection:changed', (e) => {\r\n * console.log('Selection changed:', e.selectedNodes);\r\n * });\r\n * </script>\r\n * ```\r\n */\r\nexport function useGridEvent<TData = any>(\r\n event: string,\r\n handler: (payload: any) => void,\r\n): void {\r\n const context = useGridContext<TData>();\r\n let unsubscribe: (() => void) | null = null;\r\n\r\n watch(\r\n context,\r\n (ctx) => {\r\n // Clean up previous listener\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n\r\n if (ctx) {\r\n unsubscribe = ctx.engine.eventBus.on(event as any, handler);\r\n }\r\n },\r\n { immediate: true },\r\n );\r\n\r\n onUnmounted(() => {\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n });\r\n}\r\n","// ─── GridStorm Vue 3 Component ───\r\n// Production-grade Vue wrapper around the headless core engine.\r\n// Uses defineComponent with a render function (no .vue SFC) for tsup compatibility.\r\n// Supports event emission, reactive prop watching, and composable injection.\r\n\r\nimport {\r\n defineComponent,\r\n ref,\r\n shallowRef,\r\n onMounted,\r\n onBeforeUnmount,\r\n onErrorCaptured,\r\n watch,\r\n provide,\r\n h,\r\n} from 'vue';\r\nimport type { GridEngine } from '@gridstorm/core';\r\nimport { createGrid } from '@gridstorm/core';\r\nimport { DomRenderer } from '@gridstorm/dom-renderer';\r\nimport { gridStormPropDefs } from './types';\r\nimport type { GridContextValue } from './types';\r\nimport { GRID_CONTEXT_KEY } from './composables';\r\n\r\n/**\r\n * GridStorm Vue 3 component.\r\n *\r\n * Wraps the headless GridStorm core engine and DOM renderer into a Vue component\r\n * with reactive prop watching, event emission, and provide/inject context for\r\n * child composables.\r\n *\r\n * @example\r\n * ```vue\r\n * <script setup lang=\"ts\">\r\n * import { GridStorm } from '@gridstorm/vue';\r\n * import { sortingPlugin } from '@gridstorm/plugin-sorting';\r\n *\r\n * const columns = [\r\n * { field: 'name', headerName: 'Name', sortable: true },\r\n * { field: 'age', headerName: 'Age', width: 100 },\r\n * ];\r\n * const rowData = [\r\n * { name: 'Alice', age: 30 },\r\n * { name: 'Bob', age: 25 },\r\n * ];\r\n * </script>\r\n *\r\n * <template>\r\n * <GridStorm\r\n * :columns=\"columns\"\r\n * :row-data=\"rowData\"\r\n * :plugins=\"[sortingPlugin()]\"\r\n * @grid-ready=\"(api) => console.log('Grid ready!', api)\"\r\n * />\r\n * </template>\r\n * ```\r\n */\r\nexport const GridStorm = defineComponent({\r\n name: 'GridStorm',\r\n\r\n props: gridStormPropDefs,\r\n\r\n emits: [\r\n 'gridReady',\r\n 'rowDataChanged',\r\n 'selectionChanged',\r\n 'sortChanged',\r\n 'filterChanged',\r\n 'cellValueChanged',\r\n 'cellClicked',\r\n 'cellDoubleClicked',\r\n 'rowClicked',\r\n 'paginationChanged',\r\n 'columnResized',\r\n ],\r\n\r\n setup(props, { emit, expose }) {\r\n const containerRef = ref<HTMLElement | null>(null);\r\n let engine: GridEngine | null = null;\r\n let renderer: DomRenderer | null = null;\r\n const eventUnsubscribers: Array<() => void> = [];\r\n\r\n // ── Build GridConfig from props ──\r\n function buildConfig() {\r\n return {\r\n columns: props.columns as any,\r\n rowData: props.rowData as any,\r\n plugins: props.plugins as any,\r\n getRowId: props.getRowId as any,\r\n rowHeight: props.rowHeight,\r\n headerHeight: props.headerHeight,\r\n defaultColDef: props.defaultColDef as any,\r\n paginationPageSize: props.paginationPageSize,\r\n pagination: props.pagination,\r\n rowSelection: props.rowSelection as any,\r\n editType: props.editType as any,\r\n ariaLabel: props.ariaLabel,\r\n };\r\n }\r\n\r\n // ── Subscribe to engine events and bridge to Vue emits ──\r\n function subscribeToEvents() {\r\n if (!engine) return;\r\n\r\n const eb = engine.eventBus;\r\n\r\n eventUnsubscribers.push(\r\n eb.on('rowData:changed', (e) => emit('rowDataChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('selection:changed', (e) => emit('selectionChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('column:sort:changed', (e) => emit('sortChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('filter:changed', (e) => emit('filterChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('cell:valueChanged', (e) => emit('cellValueChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('cell:clicked', (e) => emit('cellClicked', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('cell:doubleClicked', (e) => emit('cellDoubleClicked', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('row:clicked', (e) => emit('rowClicked', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('pagination:changed', (e) => emit('paginationChanged', e)),\r\n );\r\n eventUnsubscribers.push(\r\n eb.on('column:resized', (e) => emit('columnResized', e)),\r\n );\r\n }\r\n\r\n // ── Provide context for composables ──\r\n // Use shallowRef to avoid deep unwrapping of GridEngine internals\r\n // (Store class has private fields that break Vue's deep reactive proxy typing)\r\n const gridContext = shallowRef<GridContextValue | null>(null);\r\n\r\n provide(GRID_CONTEXT_KEY, gridContext);\r\n\r\n // ── Initialize grid engine and renderer ──\r\n function initGrid() {\r\n if (!containerRef.value) return;\r\n\r\n const config = buildConfig();\r\n engine = createGrid(config);\r\n\r\n // Update context for composables\r\n gridContext.value = {\r\n engine,\r\n api: engine.api,\r\n };\r\n\r\n // Mount DOM renderer\r\n renderer = new DomRenderer({\r\n container: containerRef.value,\r\n engine,\r\n });\r\n renderer.mount();\r\n\r\n // Subscribe to events\r\n subscribeToEvents();\r\n\r\n // Emit gridReady\r\n emit('gridReady', engine.api);\r\n }\r\n\r\n // ── Teardown ──\r\n function destroyGrid() {\r\n // Unsubscribe from all events\r\n for (const unsub of eventUnsubscribers) {\r\n unsub();\r\n }\r\n eventUnsubscribers.length = 0;\r\n\r\n renderer?.destroy();\r\n renderer = null;\r\n\r\n engine?.destroy();\r\n engine = null;\r\n\r\n gridContext.value = null;\r\n }\r\n\r\n // ── Error Boundary ──\r\n const error = ref<Error | null>(null);\r\n\r\n onErrorCaptured((err: Error) => {\r\n error.value = err;\r\n console.error('[GridStorm Vue] Error captured:', err);\r\n // Return false to stop the error from propagating further\r\n return false;\r\n });\r\n\r\n // ── Lifecycle ──\r\n onMounted(() => {\r\n try {\r\n initGrid();\r\n } catch (err) {\r\n error.value = err instanceof Error ? err : new Error(String(err));\r\n console.error('[GridStorm Vue] Initialization error:', err);\r\n }\r\n });\r\n\r\n onBeforeUnmount(() => {\r\n destroyGrid();\r\n });\r\n\r\n // ── Watch for rowData changes ──\r\n watch(\r\n () => props.rowData,\r\n (newData) => {\r\n if (engine && newData) {\r\n engine.api.setRowData(newData as any);\r\n }\r\n },\r\n { deep: false },\r\n );\r\n\r\n // ── Watch for column changes ──\r\n watch(\r\n () => props.columns,\r\n (newCols) => {\r\n if (engine && newCols) {\r\n engine.api.setColumnDefs(newCols as any);\r\n }\r\n },\r\n { deep: false },\r\n );\r\n\r\n // ── Watch for theme changes ──\r\n watch(\r\n () => props.theme,\r\n (newTheme) => {\r\n if (containerRef.value && newTheme) {\r\n containerRef.value.setAttribute('data-theme', newTheme);\r\n }\r\n },\r\n );\r\n\r\n // ── Watch for density changes ──\r\n watch(\r\n () => props.density,\r\n (newDensity) => {\r\n if (containerRef.value && newDensity) {\r\n containerRef.value.setAttribute('data-density', newDensity);\r\n }\r\n },\r\n );\r\n\r\n // ── Expose public API via template refs ──\r\n expose({\r\n /**\r\n * Get the GridApi instance.\r\n * Returns undefined if the grid has not been initialized yet.\r\n */\r\n getApi: () => engine?.api,\r\n\r\n /**\r\n * Get the GridEngine instance.\r\n * Returns undefined if the grid has not been initialized yet.\r\n */\r\n getEngine: () => engine,\r\n });\r\n\r\n // ── Render function ──\r\n return () => {\r\n const heightStyle =\r\n typeof props.height === 'number' ? `${props.height}px` : props.height;\r\n const widthStyle =\r\n typeof props.width === 'number' ? `${props.width}px` : props.width;\r\n\r\n return h('div', {\r\n ref: containerRef,\r\n class: ['gridstorm-wrapper', props.containerClass].filter(Boolean).join(' '),\r\n 'data-theme': props.theme,\r\n 'data-density': props.density,\r\n style: {\r\n width: widthStyle,\r\n height: heightStyle,\r\n },\r\n });\r\n };\r\n },\r\n});\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridstorm/vue",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "GridStorm Vue 3 adapter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"vue": "^3.3.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"vue": "^3.5.
|
|
40
|
+
"vue": "^3.5.31",
|
|
41
41
|
"tsup": "^8.2.0",
|
|
42
42
|
"typescript": "^5.5.0"
|
|
43
43
|
},
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
"bugs": {
|
|
64
64
|
"url": "https://github.com/007krcs/grid-data/issues"
|
|
65
65
|
},
|
|
66
|
-
"homepage": "https://
|
|
66
|
+
"homepage": "https://gridstorm.tekivex.com",
|
|
67
67
|
"author": {
|
|
68
68
|
"name": "GridStorm",
|
|
69
|
-
"url": "https://
|
|
69
|
+
"url": "https://gridstorm.tekivex.com/"
|
|
70
70
|
},
|
|
71
71
|
"funding": {
|
|
72
72
|
"type": "github",
|