@gridstorm/vue 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +209 -0
- package/dist/index.cjs +468 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +556 -0
- package/dist/index.d.ts +556 -0
- package/dist/index.js +458 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
package/README.md
ADDED
|
@@ -0,0 +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
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vue = require('vue');
|
|
4
|
+
var core = require('@gridstorm/core');
|
|
5
|
+
var domRenderer = require('@gridstorm/dom-renderer');
|
|
6
|
+
|
|
7
|
+
// src/GridStorm.ts
|
|
8
|
+
|
|
9
|
+
// src/types.ts
|
|
10
|
+
var gridStormPropDefs = {
|
|
11
|
+
columns: {
|
|
12
|
+
type: Array,
|
|
13
|
+
required: true
|
|
14
|
+
},
|
|
15
|
+
rowData: {
|
|
16
|
+
type: Array,
|
|
17
|
+
required: true
|
|
18
|
+
},
|
|
19
|
+
plugins: {
|
|
20
|
+
type: Array,
|
|
21
|
+
default: () => []
|
|
22
|
+
},
|
|
23
|
+
getRowId: {
|
|
24
|
+
type: Function,
|
|
25
|
+
default: void 0
|
|
26
|
+
},
|
|
27
|
+
rowHeight: {
|
|
28
|
+
type: Number,
|
|
29
|
+
default: 40
|
|
30
|
+
},
|
|
31
|
+
headerHeight: {
|
|
32
|
+
type: Number,
|
|
33
|
+
default: void 0
|
|
34
|
+
},
|
|
35
|
+
theme: {
|
|
36
|
+
type: String,
|
|
37
|
+
default: "light"
|
|
38
|
+
},
|
|
39
|
+
density: {
|
|
40
|
+
type: String,
|
|
41
|
+
default: "normal"
|
|
42
|
+
},
|
|
43
|
+
defaultColDef: {
|
|
44
|
+
type: Object,
|
|
45
|
+
default: void 0
|
|
46
|
+
},
|
|
47
|
+
paginationPageSize: {
|
|
48
|
+
type: Number,
|
|
49
|
+
default: void 0
|
|
50
|
+
},
|
|
51
|
+
pagination: {
|
|
52
|
+
type: Boolean,
|
|
53
|
+
default: void 0
|
|
54
|
+
},
|
|
55
|
+
rowSelection: {
|
|
56
|
+
type: [String, Boolean],
|
|
57
|
+
default: void 0
|
|
58
|
+
},
|
|
59
|
+
editType: {
|
|
60
|
+
type: String,
|
|
61
|
+
default: void 0
|
|
62
|
+
},
|
|
63
|
+
ariaLabel: {
|
|
64
|
+
type: String,
|
|
65
|
+
default: void 0
|
|
66
|
+
},
|
|
67
|
+
height: {
|
|
68
|
+
type: [Number, String],
|
|
69
|
+
default: "100%"
|
|
70
|
+
},
|
|
71
|
+
width: {
|
|
72
|
+
type: [Number, String],
|
|
73
|
+
default: "100%"
|
|
74
|
+
},
|
|
75
|
+
containerClass: {
|
|
76
|
+
type: String,
|
|
77
|
+
default: void 0
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var GRID_CONTEXT_KEY = /* @__PURE__ */ Symbol("gridstorm-context");
|
|
81
|
+
function useGridContext() {
|
|
82
|
+
const context = vue.inject(GRID_CONTEXT_KEY, null);
|
|
83
|
+
if (!context) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
"[GridStorm] Composable must be used within a <GridStorm> component."
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return context;
|
|
89
|
+
}
|
|
90
|
+
function useStoreRef(context, selector) {
|
|
91
|
+
const value = vue.ref();
|
|
92
|
+
let unsubscribe = null;
|
|
93
|
+
function subscribe(ctx) {
|
|
94
|
+
if (unsubscribe) {
|
|
95
|
+
unsubscribe();
|
|
96
|
+
unsubscribe = null;
|
|
97
|
+
}
|
|
98
|
+
if (!ctx) {
|
|
99
|
+
value.value = void 0;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
value.value = selector(ctx.engine);
|
|
103
|
+
unsubscribe = ctx.engine.store.subscribe(() => {
|
|
104
|
+
value.value = selector(ctx.engine);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
vue.watch(context, (newCtx) => subscribe(newCtx), { immediate: true });
|
|
108
|
+
vue.onUnmounted(() => {
|
|
109
|
+
if (unsubscribe) {
|
|
110
|
+
unsubscribe();
|
|
111
|
+
unsubscribe = null;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
116
|
+
function useGridApi() {
|
|
117
|
+
const context = useGridContext();
|
|
118
|
+
return vue.computed(() => context.value?.api);
|
|
119
|
+
}
|
|
120
|
+
function useGridEngine() {
|
|
121
|
+
const context = useGridContext();
|
|
122
|
+
return vue.computed(() => context.value?.engine);
|
|
123
|
+
}
|
|
124
|
+
function useGridSort() {
|
|
125
|
+
const context = useGridContext();
|
|
126
|
+
const sortModel = useStoreRef(
|
|
127
|
+
context,
|
|
128
|
+
(engine) => engine.store.getState().sortModel
|
|
129
|
+
);
|
|
130
|
+
const isSorted = vue.computed(() => (sortModel.value?.length ?? 0) > 0);
|
|
131
|
+
function setSortModel(model) {
|
|
132
|
+
context.value?.api.setSortModel(model);
|
|
133
|
+
}
|
|
134
|
+
function toggleSort(colId, multiSort = false) {
|
|
135
|
+
context.value?.engine.commandBus.dispatch("sort:toggle", {
|
|
136
|
+
colId,
|
|
137
|
+
multiSort
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function clearSort() {
|
|
141
|
+
context.value?.api.setSortModel([]);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
sortModel,
|
|
145
|
+
isSorted,
|
|
146
|
+
setSortModel,
|
|
147
|
+
toggleSort,
|
|
148
|
+
clearSort
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function useGridFilter() {
|
|
152
|
+
const context = useGridContext();
|
|
153
|
+
const filterModel = useStoreRef(
|
|
154
|
+
context,
|
|
155
|
+
(engine) => engine.store.getState().filterModel
|
|
156
|
+
);
|
|
157
|
+
const quickFilterText = useStoreRef(
|
|
158
|
+
context,
|
|
159
|
+
(engine) => engine.store.getState().quickFilterText
|
|
160
|
+
);
|
|
161
|
+
const isFiltered = vue.computed(() => {
|
|
162
|
+
const hasColumnFilters = Object.keys(filterModel.value ?? {}).length > 0;
|
|
163
|
+
const hasQuickFilter = (quickFilterText.value ?? "").length > 0;
|
|
164
|
+
return hasColumnFilters || hasQuickFilter;
|
|
165
|
+
});
|
|
166
|
+
function setFilterModel(model) {
|
|
167
|
+
context.value?.api.setFilterModel(model);
|
|
168
|
+
}
|
|
169
|
+
function setQuickFilter(text) {
|
|
170
|
+
context.value?.api.setQuickFilter(text);
|
|
171
|
+
}
|
|
172
|
+
function clearFilters() {
|
|
173
|
+
context.value?.api.setFilterModel({});
|
|
174
|
+
context.value?.api.setQuickFilter("");
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
filterModel,
|
|
178
|
+
quickFilterText,
|
|
179
|
+
isFiltered,
|
|
180
|
+
setFilterModel,
|
|
181
|
+
setQuickFilter,
|
|
182
|
+
clearFilters
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function useGridSelection() {
|
|
186
|
+
const context = useGridContext();
|
|
187
|
+
const selectedRowIds = useStoreRef(
|
|
188
|
+
context,
|
|
189
|
+
(engine) => engine.store.getState().selection.selectedRowIds
|
|
190
|
+
);
|
|
191
|
+
const selectedCount = vue.computed(() => selectedRowIds.value?.size ?? 0);
|
|
192
|
+
function getSelectedRows() {
|
|
193
|
+
return context.value?.api.getSelectedRows() ?? [];
|
|
194
|
+
}
|
|
195
|
+
function getSelectedNodes() {
|
|
196
|
+
return context.value?.api.getSelectedNodes() ?? [];
|
|
197
|
+
}
|
|
198
|
+
function isRowSelected(rowId) {
|
|
199
|
+
return selectedRowIds.value?.has(rowId) ?? false;
|
|
200
|
+
}
|
|
201
|
+
function selectAll() {
|
|
202
|
+
context.value?.api.selectAll();
|
|
203
|
+
}
|
|
204
|
+
function deselectAll() {
|
|
205
|
+
context.value?.api.deselectAll();
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
selectedRowIds,
|
|
209
|
+
selectedCount,
|
|
210
|
+
getSelectedRows,
|
|
211
|
+
getSelectedNodes,
|
|
212
|
+
isRowSelected,
|
|
213
|
+
selectAll,
|
|
214
|
+
deselectAll
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function useGridPagination() {
|
|
218
|
+
const context = useGridContext();
|
|
219
|
+
const paginationState = useStoreRef(
|
|
220
|
+
context,
|
|
221
|
+
(engine) => engine.store.getState().pagination
|
|
222
|
+
);
|
|
223
|
+
const currentPage = vue.computed(() => paginationState.value?.currentPage ?? 0);
|
|
224
|
+
const pageSize = vue.computed(() => paginationState.value?.pageSize ?? 100);
|
|
225
|
+
const totalRows = vue.computed(() => paginationState.value?.totalRows ?? 0);
|
|
226
|
+
const totalPages = vue.computed(
|
|
227
|
+
() => Math.max(1, Math.ceil(totalRows.value / pageSize.value))
|
|
228
|
+
);
|
|
229
|
+
const hasNextPage = vue.computed(() => currentPage.value < totalPages.value - 1);
|
|
230
|
+
const hasPreviousPage = vue.computed(() => currentPage.value > 0);
|
|
231
|
+
function goToPage(page) {
|
|
232
|
+
context.value?.api.paginationGoToPage(page);
|
|
233
|
+
}
|
|
234
|
+
function nextPage() {
|
|
235
|
+
if (hasNextPage.value) {
|
|
236
|
+
context.value?.api.paginationGoToPage(currentPage.value + 1);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function previousPage() {
|
|
240
|
+
if (hasPreviousPage.value) {
|
|
241
|
+
context.value?.api.paginationGoToPage(currentPage.value - 1);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function firstPage() {
|
|
245
|
+
context.value?.api.paginationGoToPage(0);
|
|
246
|
+
}
|
|
247
|
+
function lastPage() {
|
|
248
|
+
context.value?.api.paginationGoToPage(totalPages.value - 1);
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
currentPage,
|
|
252
|
+
totalPages,
|
|
253
|
+
pageSize,
|
|
254
|
+
totalRows,
|
|
255
|
+
hasNextPage,
|
|
256
|
+
hasPreviousPage,
|
|
257
|
+
goToPage,
|
|
258
|
+
nextPage,
|
|
259
|
+
previousPage,
|
|
260
|
+
firstPage,
|
|
261
|
+
lastPage
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function useGridEvent(event, handler) {
|
|
265
|
+
const context = useGridContext();
|
|
266
|
+
let unsubscribe = null;
|
|
267
|
+
vue.watch(
|
|
268
|
+
context,
|
|
269
|
+
(ctx) => {
|
|
270
|
+
if (unsubscribe) {
|
|
271
|
+
unsubscribe();
|
|
272
|
+
unsubscribe = null;
|
|
273
|
+
}
|
|
274
|
+
if (ctx) {
|
|
275
|
+
unsubscribe = ctx.engine.eventBus.on(event, handler);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
{ immediate: true }
|
|
279
|
+
);
|
|
280
|
+
vue.onUnmounted(() => {
|
|
281
|
+
if (unsubscribe) {
|
|
282
|
+
unsubscribe();
|
|
283
|
+
unsubscribe = null;
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// src/GridStorm.ts
|
|
289
|
+
var GridStorm = vue.defineComponent({
|
|
290
|
+
name: "GridStorm",
|
|
291
|
+
props: gridStormPropDefs,
|
|
292
|
+
emits: [
|
|
293
|
+
"gridReady",
|
|
294
|
+
"rowDataChanged",
|
|
295
|
+
"selectionChanged",
|
|
296
|
+
"sortChanged",
|
|
297
|
+
"filterChanged",
|
|
298
|
+
"cellValueChanged",
|
|
299
|
+
"cellClicked",
|
|
300
|
+
"cellDoubleClicked",
|
|
301
|
+
"rowClicked",
|
|
302
|
+
"paginationChanged",
|
|
303
|
+
"columnResized"
|
|
304
|
+
],
|
|
305
|
+
setup(props, { emit, expose }) {
|
|
306
|
+
const containerRef = vue.ref(null);
|
|
307
|
+
let engine = null;
|
|
308
|
+
let renderer = null;
|
|
309
|
+
const eventUnsubscribers = [];
|
|
310
|
+
function buildConfig() {
|
|
311
|
+
return {
|
|
312
|
+
columns: props.columns,
|
|
313
|
+
rowData: props.rowData,
|
|
314
|
+
plugins: props.plugins,
|
|
315
|
+
getRowId: props.getRowId,
|
|
316
|
+
rowHeight: props.rowHeight,
|
|
317
|
+
headerHeight: props.headerHeight,
|
|
318
|
+
defaultColDef: props.defaultColDef,
|
|
319
|
+
paginationPageSize: props.paginationPageSize,
|
|
320
|
+
pagination: props.pagination,
|
|
321
|
+
rowSelection: props.rowSelection,
|
|
322
|
+
editType: props.editType,
|
|
323
|
+
ariaLabel: props.ariaLabel
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function subscribeToEvents() {
|
|
327
|
+
if (!engine) return;
|
|
328
|
+
const eb = engine.eventBus;
|
|
329
|
+
eventUnsubscribers.push(
|
|
330
|
+
eb.on("rowData:changed", (e) => emit("rowDataChanged", e))
|
|
331
|
+
);
|
|
332
|
+
eventUnsubscribers.push(
|
|
333
|
+
eb.on("selection:changed", (e) => emit("selectionChanged", e))
|
|
334
|
+
);
|
|
335
|
+
eventUnsubscribers.push(
|
|
336
|
+
eb.on("column:sort:changed", (e) => emit("sortChanged", e))
|
|
337
|
+
);
|
|
338
|
+
eventUnsubscribers.push(
|
|
339
|
+
eb.on("filter:changed", (e) => emit("filterChanged", e))
|
|
340
|
+
);
|
|
341
|
+
eventUnsubscribers.push(
|
|
342
|
+
eb.on("cell:valueChanged", (e) => emit("cellValueChanged", e))
|
|
343
|
+
);
|
|
344
|
+
eventUnsubscribers.push(
|
|
345
|
+
eb.on("cell:clicked", (e) => emit("cellClicked", e))
|
|
346
|
+
);
|
|
347
|
+
eventUnsubscribers.push(
|
|
348
|
+
eb.on("cell:doubleClicked", (e) => emit("cellDoubleClicked", e))
|
|
349
|
+
);
|
|
350
|
+
eventUnsubscribers.push(
|
|
351
|
+
eb.on("row:clicked", (e) => emit("rowClicked", e))
|
|
352
|
+
);
|
|
353
|
+
eventUnsubscribers.push(
|
|
354
|
+
eb.on("pagination:changed", (e) => emit("paginationChanged", e))
|
|
355
|
+
);
|
|
356
|
+
eventUnsubscribers.push(
|
|
357
|
+
eb.on("column:resized", (e) => emit("columnResized", e))
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
const gridContext = vue.shallowRef(null);
|
|
361
|
+
vue.provide(GRID_CONTEXT_KEY, gridContext);
|
|
362
|
+
function initGrid() {
|
|
363
|
+
if (!containerRef.value) return;
|
|
364
|
+
const config = buildConfig();
|
|
365
|
+
engine = core.createGrid(config);
|
|
366
|
+
gridContext.value = {
|
|
367
|
+
engine,
|
|
368
|
+
api: engine.api
|
|
369
|
+
};
|
|
370
|
+
renderer = new domRenderer.DomRenderer({
|
|
371
|
+
container: containerRef.value,
|
|
372
|
+
engine
|
|
373
|
+
});
|
|
374
|
+
renderer.mount();
|
|
375
|
+
subscribeToEvents();
|
|
376
|
+
emit("gridReady", engine.api);
|
|
377
|
+
}
|
|
378
|
+
function destroyGrid() {
|
|
379
|
+
for (const unsub of eventUnsubscribers) {
|
|
380
|
+
unsub();
|
|
381
|
+
}
|
|
382
|
+
eventUnsubscribers.length = 0;
|
|
383
|
+
renderer?.destroy();
|
|
384
|
+
renderer = null;
|
|
385
|
+
engine?.destroy();
|
|
386
|
+
engine = null;
|
|
387
|
+
gridContext.value = null;
|
|
388
|
+
}
|
|
389
|
+
vue.onMounted(() => {
|
|
390
|
+
initGrid();
|
|
391
|
+
});
|
|
392
|
+
vue.onBeforeUnmount(() => {
|
|
393
|
+
destroyGrid();
|
|
394
|
+
});
|
|
395
|
+
vue.watch(
|
|
396
|
+
() => props.rowData,
|
|
397
|
+
(newData) => {
|
|
398
|
+
if (engine && newData) {
|
|
399
|
+
engine.api.setRowData(newData);
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
{ deep: false }
|
|
403
|
+
);
|
|
404
|
+
vue.watch(
|
|
405
|
+
() => props.columns,
|
|
406
|
+
(newCols) => {
|
|
407
|
+
if (engine && newCols) {
|
|
408
|
+
engine.api.setColumnDefs(newCols);
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
{ deep: false }
|
|
412
|
+
);
|
|
413
|
+
vue.watch(
|
|
414
|
+
() => props.theme,
|
|
415
|
+
(newTheme) => {
|
|
416
|
+
if (containerRef.value && newTheme) {
|
|
417
|
+
containerRef.value.setAttribute("data-theme", newTheme);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
);
|
|
421
|
+
vue.watch(
|
|
422
|
+
() => props.density,
|
|
423
|
+
(newDensity) => {
|
|
424
|
+
if (containerRef.value && newDensity) {
|
|
425
|
+
containerRef.value.setAttribute("data-density", newDensity);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
);
|
|
429
|
+
expose({
|
|
430
|
+
/**
|
|
431
|
+
* Get the GridApi instance.
|
|
432
|
+
* Returns undefined if the grid has not been initialized yet.
|
|
433
|
+
*/
|
|
434
|
+
getApi: () => engine?.api,
|
|
435
|
+
/**
|
|
436
|
+
* Get the GridEngine instance.
|
|
437
|
+
* Returns undefined if the grid has not been initialized yet.
|
|
438
|
+
*/
|
|
439
|
+
getEngine: () => engine
|
|
440
|
+
});
|
|
441
|
+
return () => {
|
|
442
|
+
const heightStyle = typeof props.height === "number" ? `${props.height}px` : props.height;
|
|
443
|
+
const widthStyle = typeof props.width === "number" ? `${props.width}px` : props.width;
|
|
444
|
+
return vue.h("div", {
|
|
445
|
+
ref: containerRef,
|
|
446
|
+
class: ["gridstorm-wrapper", props.containerClass].filter(Boolean).join(" "),
|
|
447
|
+
"data-theme": props.theme,
|
|
448
|
+
"data-density": props.density,
|
|
449
|
+
style: {
|
|
450
|
+
width: widthStyle,
|
|
451
|
+
height: heightStyle
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
exports.GRID_CONTEXT_KEY = GRID_CONTEXT_KEY;
|
|
459
|
+
exports.GridStorm = GridStorm;
|
|
460
|
+
exports.useGridApi = useGridApi;
|
|
461
|
+
exports.useGridEngine = useGridEngine;
|
|
462
|
+
exports.useGridEvent = useGridEvent;
|
|
463
|
+
exports.useGridFilter = useGridFilter;
|
|
464
|
+
exports.useGridPagination = useGridPagination;
|
|
465
|
+
exports.useGridSelection = useGridSelection;
|
|
466
|
+
exports.useGridSort = useGridSort;
|
|
467
|
+
//# sourceMappingURL=index.cjs.map
|
|
468
|
+
//# sourceMappingURL=index.cjs.map
|