@tinisoftin/tsdatagrid 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1272 -0
- package/dist/components/TSDataGrid.vue.d.ts +1285 -0
- package/dist/components/TSDataGrid.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridActiveFilters.vue.d.ts +24 -0
- package/dist/components/TSDataGridActiveFilters.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridBody.vue.d.ts +259 -0
- package/dist/components/TSDataGridBody.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridCell.vue.d.ts +83 -0
- package/dist/components/TSDataGridCell.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridColumnChooser.vue.d.ts +56 -0
- package/dist/components/TSDataGridColumnChooser.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridContextMenu.vue.d.ts +46 -0
- package/dist/components/TSDataGridContextMenu.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridFilter.vue.d.ts +92 -0
- package/dist/components/TSDataGridFilter.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridFooter.vue.d.ts +95 -0
- package/dist/components/TSDataGridFooter.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridGroupPanel.vue.d.ts +47 -0
- package/dist/components/TSDataGridGroupPanel.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridHeader.vue.d.ts +221 -0
- package/dist/components/TSDataGridHeader.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridRow.vue.d.ts +83 -0
- package/dist/components/TSDataGridRow.vue.d.ts.map +1 -0
- package/dist/components/TSDataGridToolbar.vue.d.ts +139 -0
- package/dist/components/TSDataGridToolbar.vue.d.ts.map +1 -0
- package/dist/composables/index.d.ts +28 -0
- package/dist/composables/index.d.ts.map +1 -0
- package/dist/composables/useClipboard.d.ts +863 -0
- package/dist/composables/useClipboard.d.ts.map +1 -0
- package/dist/composables/useColumnChooser.d.ts +36 -0
- package/dist/composables/useColumnChooser.d.ts.map +1 -0
- package/dist/composables/useColumnReorder.d.ts +40 -0
- package/dist/composables/useColumnReorder.d.ts.map +1 -0
- package/dist/composables/useColumnResize.d.ts +36 -0
- package/dist/composables/useColumnResize.d.ts.map +1 -0
- package/dist/composables/useContextMenu.d.ts +55 -0
- package/dist/composables/useContextMenu.d.ts.map +1 -0
- package/dist/composables/useDataSource.d.ts +1770 -0
- package/dist/composables/useDataSource.d.ts.map +1 -0
- package/dist/composables/useEditing.d.ts +54 -0
- package/dist/composables/useEditing.d.ts.map +1 -0
- package/dist/composables/useExport.d.ts +72 -0
- package/dist/composables/useExport.d.ts.map +1 -0
- package/dist/composables/useFiltering.d.ts +42 -0
- package/dist/composables/useFiltering.d.ts.map +1 -0
- package/dist/composables/useGridApi.d.ts +85 -0
- package/dist/composables/useGridApi.d.ts.map +1 -0
- package/dist/composables/useGrouping.d.ts +879 -0
- package/dist/composables/useGrouping.d.ts.map +1 -0
- package/dist/composables/useInfiniteScroll.d.ts +49 -0
- package/dist/composables/useInfiniteScroll.d.ts.map +1 -0
- package/dist/composables/useKeyboardNavigation.d.ts +47 -0
- package/dist/composables/useKeyboardNavigation.d.ts.map +1 -0
- package/dist/composables/useLoadingState.d.ts +36 -0
- package/dist/composables/useLoadingState.d.ts.map +1 -0
- package/dist/composables/usePagination.d.ts +45 -0
- package/dist/composables/usePagination.d.ts.map +1 -0
- package/dist/composables/useRowExpansion.d.ts +47 -0
- package/dist/composables/useRowExpansion.d.ts.map +1 -0
- package/dist/composables/useSearch.d.ts +97 -0
- package/dist/composables/useSearch.d.ts.map +1 -0
- package/dist/composables/useSelection.d.ts +32 -0
- package/dist/composables/useSelection.d.ts.map +1 -0
- package/dist/composables/useSorting.d.ts +859 -0
- package/dist/composables/useSorting.d.ts.map +1 -0
- package/dist/composables/useStatePersistence.d.ts +26 -0
- package/dist/composables/useStatePersistence.d.ts.map +1 -0
- package/dist/composables/useSummary.d.ts +49 -0
- package/dist/composables/useSummary.d.ts.map +1 -0
- package/dist/composables/useUndo.d.ts +27 -0
- package/dist/composables/useUndo.d.ts.map +1 -0
- package/dist/composables/useVirtualization.d.ts +40 -0
- package/dist/composables/useVirtualization.d.ts.map +1 -0
- package/dist/html2canvas.esm-1a1724a1.js +4886 -0
- package/dist/index-541cb5f8.js +38398 -0
- package/dist/index.d.ts +108 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es-713282db.js +5771 -0
- package/dist/plugin.d.ts +22 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/purify.es-35a15df8.js +480 -0
- package/dist/style.css +1 -0
- package/dist/tsdatagrid.es.js +358 -0
- package/dist/tsdatagrid.umd.js +450 -0
- package/dist/types/core/base.d.ts +143 -0
- package/dist/types/core/base.d.ts.map +1 -0
- package/dist/types/core/column.d.ts +354 -0
- package/dist/types/core/column.d.ts.map +1 -0
- package/dist/types/core/datasource.d.ts +247 -0
- package/dist/types/core/datasource.d.ts.map +1 -0
- package/dist/types/core/events.d.ts +297 -0
- package/dist/types/core/events.d.ts.map +1 -0
- package/dist/types/core/models.d.ts +74 -0
- package/dist/types/core/models.d.ts.map +1 -0
- package/dist/types/features/accessibility.d.ts +75 -0
- package/dist/types/features/accessibility.d.ts.map +1 -0
- package/dist/types/features/editing.d.ts +185 -0
- package/dist/types/features/editing.d.ts.map +1 -0
- package/dist/types/features/export.d.ts +145 -0
- package/dist/types/features/export.d.ts.map +1 -0
- package/dist/types/features/filtering.d.ts +193 -0
- package/dist/types/features/filtering.d.ts.map +1 -0
- package/dist/types/features/grouping.d.ts +148 -0
- package/dist/types/features/grouping.d.ts.map +1 -0
- package/dist/types/features/keyboard.d.ts +126 -0
- package/dist/types/features/keyboard.d.ts.map +1 -0
- package/dist/types/features/pagination.d.ts +85 -0
- package/dist/types/features/pagination.d.ts.map +1 -0
- package/dist/types/features/searching.d.ts +90 -0
- package/dist/types/features/searching.d.ts.map +1 -0
- package/dist/types/features/selection.d.ts +99 -0
- package/dist/types/features/selection.d.ts.map +1 -0
- package/dist/types/features/sorting.d.ts +81 -0
- package/dist/types/features/sorting.d.ts.map +1 -0
- package/dist/types/features/summary.d.ts +99 -0
- package/dist/types/features/summary.d.ts.map +1 -0
- package/dist/types/features/virtualization.d.ts +88 -0
- package/dist/types/features/virtualization.d.ts.map +1 -0
- package/dist/types/index.d.ts +60 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/state/grid-state.d.ts +70 -0
- package/dist/types/state/grid-state.d.ts.map +1 -0
- package/dist/types/state/persistence.d.ts +65 -0
- package/dist/types/state/persistence.d.ts.map +1 -0
- package/dist/types/ui/styling.d.ts +72 -0
- package/dist/types/ui/styling.d.ts.map +1 -0
- package/dist/types/ui/templates.d.ts +80 -0
- package/dist/types/ui/templates.d.ts.map +1 -0
- package/dist/types/ui/toolbar.d.ts +63 -0
- package/dist/types/ui/toolbar.d.ts.map +1 -0
- package/dist/types/validation/validators.d.ts +134 -0
- package/dist/types/validation/validators.d.ts.map +1 -0
- package/dist/utils/accessibility.d.ts +35 -0
- package/dist/utils/accessibility.d.ts.map +1 -0
- package/dist/utils/array.d.ts +88 -0
- package/dist/utils/array.d.ts.map +1 -0
- package/dist/utils/cache.d.ts +92 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/clipboard.d.ts +25 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/column-searcher.d.ts +44 -0
- package/dist/utils/column-searcher.d.ts.map +1 -0
- package/dist/utils/constants.d.ts +76 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/date.d.ts +101 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/dom.d.ts +128 -0
- package/dist/utils/dom.d.ts.map +1 -0
- package/dist/utils/error-handling.d.ts +190 -0
- package/dist/utils/error-handling.d.ts.map +1 -0
- package/dist/utils/export.d.ts +37 -0
- package/dist/utils/export.d.ts.map +1 -0
- package/dist/utils/formatters.d.ts +60 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/index.d.ts +25 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/keyboard.d.ts +58 -0
- package/dist/utils/keyboard.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/number.d.ts +77 -0
- package/dist/utils/number.d.ts.map +1 -0
- package/dist/utils/object.d.ts +101 -0
- package/dist/utils/object.d.ts.map +1 -0
- package/dist/utils/odata.d.ts +87 -0
- package/dist/utils/odata.d.ts.map +1 -0
- package/dist/utils/performance.d.ts +75 -0
- package/dist/utils/performance.d.ts.map +1 -0
- package/dist/utils/storage.d.ts +83 -0
- package/dist/utils/storage.d.ts.map +1 -0
- package/dist/utils/string.d.ts +105 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/validators.d.ts +60 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/package.json +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,1272 @@
|
|
|
1
|
+
# TSDataGrid
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/tsdatagrid)
|
|
6
|
+
[](https://www.npmjs.com/package/tsdatagrid)
|
|
7
|
+
[](https://github.com/yourusername/tsdatagrid/blob/main/LICENSE)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://vuejs.org/)
|
|
10
|
+
|
|
11
|
+
**Advanced, feature-rich data grid component for Vue 3 with TypeScript support**
|
|
12
|
+
|
|
13
|
+
[Features](#features) β’ [Installation](#installation) β’ [Quick Start](#quick-start) β’ [Documentation](#documentation) β’ [Examples](#examples)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## π Features
|
|
20
|
+
|
|
21
|
+
### Core Features
|
|
22
|
+
- β
**Vue 3 & TypeScript** - Built with Vue 3 Composition API and full TypeScript support
|
|
23
|
+
- π **Data Sources** - Support for local arrays and OData endpoints
|
|
24
|
+
- π¨ **Theming** - Multiple built-in themes (default, material, dark)
|
|
25
|
+
- π± **Responsive** - Works seamlessly on desktop and mobile devices
|
|
26
|
+
- β‘ **Performance** - Virtual scrolling for large datasets (1M+ rows)
|
|
27
|
+
|
|
28
|
+
### Data Management
|
|
29
|
+
- π **Advanced Filtering** - Column filters with unique value selection and multiple operators
|
|
30
|
+
- π **Multi-Sort** - Sort by multiple columns simultaneously
|
|
31
|
+
- π **Pagination** - Built-in pagination with customizable page sizes
|
|
32
|
+
- π **Global Search** - Search across all searchable columns with highlighting
|
|
33
|
+
- π **Grouping** - Hierarchical data grouping with expand/collapse and group summaries
|
|
34
|
+
- βΎοΈ **Infinite Scroll** - Load data on-demand as user scrolls
|
|
35
|
+
|
|
36
|
+
### User Experience
|
|
37
|
+
- βοΈ **Inline Editing** - Multiple editor types (text, number, date, select, checkbox)
|
|
38
|
+
- β©οΈ **Undo/Redo** - Full undo/redo support with keyboard shortcuts (Ctrl+Z/Y)
|
|
39
|
+
- βοΈ **Row Selection** - Single or multiple row selection with checkboxes
|
|
40
|
+
- π― **Column Chooser** - Show/hide columns with drag-and-drop reordering
|
|
41
|
+
- π **Column Resizing** - Resize columns by dragging or auto-fit content
|
|
42
|
+
- π **Column Reordering** - Drag and drop column reordering in header or chooser
|
|
43
|
+
- π **Locked Columns** - Pin important columns to prevent hiding
|
|
44
|
+
- π±οΈ **Context Menu** - Right-click context menus on rows and headers
|
|
45
|
+
- β¨οΈ **Keyboard Navigation** - Navigate cells with arrow keys, Tab, Enter, Esc
|
|
46
|
+
|
|
47
|
+
### Export & Integration
|
|
48
|
+
- π€ **Export** - Export to CSV, Excel, PDF, and JSON formats
|
|
49
|
+
- π **Clipboard** - Copy/cut/paste with Ctrl+C/X/V support
|
|
50
|
+
- π **OData Support** - Full OData v4 query protocol support
|
|
51
|
+
- πΎ **State Persistence** - Save and restore grid state to localStorage
|
|
52
|
+
- π¨ **Custom Formatters** - Format cell values with custom functions
|
|
53
|
+
- β
**Validation** - Built-in and custom validators for editing
|
|
54
|
+
|
|
55
|
+
### Advanced Features
|
|
56
|
+
- π **Summary Row** - Calculate sum, avg, min, max, count (page and total)
|
|
57
|
+
- π¨ **Custom Cell Rendering** - Render custom components via slots
|
|
58
|
+
- π§ **Toolbar Actions** - Customizable toolbar with custom actions
|
|
59
|
+
- π¨ **Conditional Styling** - Apply styles based on cell values
|
|
60
|
+
- π **Plugin System** - Extend functionality with composables
|
|
61
|
+
- π **Row Expansion** - Expandable detail rows with custom templates
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## π¦ Installation
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# npm
|
|
69
|
+
npm install tsdatagrid
|
|
70
|
+
|
|
71
|
+
# yarn
|
|
72
|
+
yarn add tsdatagrid
|
|
73
|
+
|
|
74
|
+
# pnpm
|
|
75
|
+
pnpm add tsdatagrid
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Peer Dependencies:**
|
|
79
|
+
```bash
|
|
80
|
+
npm install vue@^3.3.4
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Optional Dependencies (for full feature support):**
|
|
84
|
+
```bash
|
|
85
|
+
npm install jspdf jspdf-autotable papaparse xlsx
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## π Quick Start
|
|
91
|
+
|
|
92
|
+
### 1. Global Registration (Recommended)
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// main.ts
|
|
96
|
+
import { createApp } from 'vue'
|
|
97
|
+
import App from './App.vue'
|
|
98
|
+
import TSDataGridPlugin from 'tsdatagrid'
|
|
99
|
+
import 'tsdatagrid/dist/style.css'
|
|
100
|
+
|
|
101
|
+
const app = createApp(App)
|
|
102
|
+
app.use(TSDataGridPlugin)
|
|
103
|
+
app.mount('#app')
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 2. Basic Usage
|
|
107
|
+
|
|
108
|
+
```vue
|
|
109
|
+
<template>
|
|
110
|
+
<TSDataGrid
|
|
111
|
+
:columns="columns"
|
|
112
|
+
:data-source="dataSource"
|
|
113
|
+
:allow-sorting="true"
|
|
114
|
+
:allow-filtering="true"
|
|
115
|
+
:allow-paging="true"
|
|
116
|
+
:page-size="20"
|
|
117
|
+
/>
|
|
118
|
+
</template>
|
|
119
|
+
|
|
120
|
+
<script setup lang="ts">
|
|
121
|
+
import { ref } from 'vue'
|
|
122
|
+
import type { ColumnDefinition, DataSourceConfig } from 'tsdatagrid'
|
|
123
|
+
import { ColumnType, Alignment, DataSourceType } from 'tsdatagrid'
|
|
124
|
+
|
|
125
|
+
const columns = ref<ColumnDefinition[]>([
|
|
126
|
+
{
|
|
127
|
+
field: 'id',
|
|
128
|
+
title: 'ID',
|
|
129
|
+
type: ColumnType.Number,
|
|
130
|
+
width: 80,
|
|
131
|
+
alignment: Alignment.Right
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
field: 'name',
|
|
135
|
+
title: 'Name',
|
|
136
|
+
type: ColumnType.String,
|
|
137
|
+
width: 200,
|
|
138
|
+
searchable: true
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
field: 'email',
|
|
142
|
+
title: 'Email',
|
|
143
|
+
type: ColumnType.String,
|
|
144
|
+
width: 250,
|
|
145
|
+
searchable: true
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
field: 'salary',
|
|
149
|
+
title: 'Salary',
|
|
150
|
+
type: ColumnType.Number,
|
|
151
|
+
width: 120,
|
|
152
|
+
alignment: Alignment.Right,
|
|
153
|
+
formatter: (value) => `$${Number(value).toLocaleString()}`
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
field: 'hireDate',
|
|
157
|
+
title: 'Hire Date',
|
|
158
|
+
type: ColumnType.Date,
|
|
159
|
+
width: 130,
|
|
160
|
+
formatter: (value) => new Date(value).toLocaleDateString()
|
|
161
|
+
}
|
|
162
|
+
])
|
|
163
|
+
|
|
164
|
+
const dataSource = ref<DataSourceConfig>({
|
|
165
|
+
type: DataSourceType.Local,
|
|
166
|
+
data: [
|
|
167
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com', salary: 75000, hireDate: '2020-01-15' },
|
|
168
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', salary: 85000, hireDate: '2019-03-22' },
|
|
169
|
+
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', salary: 95000, hireDate: '2018-07-10' }
|
|
170
|
+
]
|
|
171
|
+
})
|
|
172
|
+
</script>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## π Documentation
|
|
178
|
+
|
|
179
|
+
### Column Definition
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
interface ColumnDefinition {
|
|
183
|
+
field: string // Field name in data
|
|
184
|
+
title: string // Column header text
|
|
185
|
+
type?: ColumnType // Column data type
|
|
186
|
+
width?: number | string // Column width
|
|
187
|
+
minWidth?: number // Minimum width
|
|
188
|
+
maxWidth?: number // Maximum width
|
|
189
|
+
alignment?: Alignment // Text alignment
|
|
190
|
+
|
|
191
|
+
// Features
|
|
192
|
+
sortable?: boolean // Enable sorting (default: true)
|
|
193
|
+
filterable?: boolean // Enable filtering (default: true)
|
|
194
|
+
groupable?: boolean // Enable grouping
|
|
195
|
+
editable?: boolean // Enable editing
|
|
196
|
+
resizable?: boolean // Enable resizing (default: true)
|
|
197
|
+
searchable?: boolean // Include in global search
|
|
198
|
+
locked?: boolean // Prevent hiding/reordering
|
|
199
|
+
|
|
200
|
+
// Display
|
|
201
|
+
visible?: boolean // Show/hide column (default: true)
|
|
202
|
+
cssClass?: string // Custom CSS class
|
|
203
|
+
|
|
204
|
+
// Custom rendering
|
|
205
|
+
formatter?: (value: any, row: any, column: ColumnDefinition) => string | number
|
|
206
|
+
|
|
207
|
+
// Editing
|
|
208
|
+
editor?: EditorConfig
|
|
209
|
+
validator?: (value: any) => boolean | string
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Column Types
|
|
213
|
+
enum ColumnType {
|
|
214
|
+
String = 'string',
|
|
215
|
+
Number = 'number',
|
|
216
|
+
Date = 'date',
|
|
217
|
+
DateTime = 'datetime',
|
|
218
|
+
Boolean = 'boolean'
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Alignment
|
|
222
|
+
enum Alignment {
|
|
223
|
+
Left = 'left',
|
|
224
|
+
Center = 'center',
|
|
225
|
+
Right = 'right'
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Editor Configuration
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
interface EditorConfig {
|
|
233
|
+
type: EditorType
|
|
234
|
+
placeholder?: string
|
|
235
|
+
options?: any[] | { value: any; label: string }[]
|
|
236
|
+
min?: number
|
|
237
|
+
max?: number
|
|
238
|
+
step?: number
|
|
239
|
+
maxLength?: number
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
enum EditorType {
|
|
243
|
+
Text = 'text',
|
|
244
|
+
Number = 'number',
|
|
245
|
+
Date = 'date',
|
|
246
|
+
Select = 'select',
|
|
247
|
+
Checkbox = 'checkbox'
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Data Source Configuration
|
|
252
|
+
|
|
253
|
+
#### Local Data Source
|
|
254
|
+
```typescript
|
|
255
|
+
const dataSource: DataSourceConfig = {
|
|
256
|
+
type: DataSourceType.Local,
|
|
257
|
+
data: [
|
|
258
|
+
{ id: 1, name: 'Product 1', price: 100 },
|
|
259
|
+
{ id: 2, name: 'Product 2', price: 200 }
|
|
260
|
+
]
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### OData Data Source
|
|
265
|
+
```typescript
|
|
266
|
+
const dataSource: DataSourceConfig = {
|
|
267
|
+
type: DataSourceType.OData,
|
|
268
|
+
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Products',
|
|
269
|
+
serverPaging: true,
|
|
270
|
+
serverSorting: true,
|
|
271
|
+
serverFiltering: true,
|
|
272
|
+
pageSize: 20
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Props
|
|
277
|
+
|
|
278
|
+
| Prop | Type | Default | Description |
|
|
279
|
+
|------|------|---------|-------------|
|
|
280
|
+
| `dataSource` | `DataSourceConfig` | **required** | Data source configuration |
|
|
281
|
+
| `columns` | `ColumnDefinition[]` | **required** | Column definitions |
|
|
282
|
+
| `keyField` | `string` | `'id'` | Unique key field name |
|
|
283
|
+
| `allowSorting` | `boolean` | `true` | Enable column sorting |
|
|
284
|
+
| `allowFiltering` | `boolean` | `true` | Enable column filtering |
|
|
285
|
+
| `allowPaging` | `boolean` | `true` | Enable pagination |
|
|
286
|
+
| `allowSelection` | `boolean` | `false` | Enable row selection |
|
|
287
|
+
| `allowEditing` | `boolean` | `false` | Enable inline editing |
|
|
288
|
+
| `allowAdding` | `boolean` | `false` | Enable adding new rows |
|
|
289
|
+
| `allowDeleting` | `boolean` | `false` | Enable deleting rows |
|
|
290
|
+
| `allowGrouping` | `boolean` | `false` | Enable data grouping |
|
|
291
|
+
| `allowExport` | `boolean` | `false` | Enable data export |
|
|
292
|
+
| `allowRowExpansion` | `boolean` | `false` | Enable expandable detail rows |
|
|
293
|
+
| `allowColumnReordering` | `boolean` | `true` | Enable column drag-drop reordering |
|
|
294
|
+
| `allowColumnResizing` | `boolean` | `true` | Enable column resizing |
|
|
295
|
+
| `allowInfiniteScroll` | `boolean` | `false` | Enable infinite scroll loading |
|
|
296
|
+
| `enableVirtualization` | `boolean` | `false` | Enable virtual scrolling |
|
|
297
|
+
| `enableKeyboardNavigation` | `boolean` | `true` | Enable keyboard navigation |
|
|
298
|
+
| `showToolbar` | `boolean` | `true` | Show toolbar |
|
|
299
|
+
| `showSearch` | `boolean` | `true` | Show global search |
|
|
300
|
+
| `showColumnChooser` | `boolean` | `true` | Show column chooser button |
|
|
301
|
+
| `showGroupPanel` | `boolean` | `false` | Show group panel |
|
|
302
|
+
| `showPagination` | `boolean` | `true` | Show pagination footer |
|
|
303
|
+
| `showPaginationInfo` | `boolean` | `true` | Show pagination info text |
|
|
304
|
+
| `showPageSizes` | `boolean` | `true` | Show page size dropdown |
|
|
305
|
+
| `showSummary` | `boolean` | `false` | Show summary row |
|
|
306
|
+
| `showGroupSummary` | `boolean` | `false` | Show summaries for groups |
|
|
307
|
+
| `pageSize` | `number` | `20` | Records per page |
|
|
308
|
+
| `pageSizes` | `number[]` | `[10,20,50,100]` | Available page sizes |
|
|
309
|
+
| `rowHeight` | `number` | `40` | Height of each row (px) |
|
|
310
|
+
| `maxHeight` | `number \| string` | `'auto'` | Maximum grid height |
|
|
311
|
+
| `theme` | `string` | `'default'` | Theme name (default, material, dark) |
|
|
312
|
+
| `stateKey` | `string` | `''` | Key for state persistence |
|
|
313
|
+
| `selectionMode` | `SelectionMode` | `{ mode: 'none' }` | Selection configuration |
|
|
314
|
+
| `summary` | `SummaryConfig[]` | `[]` | Summary configurations |
|
|
315
|
+
|
|
316
|
+
### Selection Mode
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
interface SelectionMode {
|
|
320
|
+
mode: SelectionModeType
|
|
321
|
+
checkboxes?: boolean
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
enum SelectionModeType {
|
|
325
|
+
None = 'none',
|
|
326
|
+
Single = 'single',
|
|
327
|
+
Multiple = 'multiple'
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Example
|
|
331
|
+
const selectionMode: SelectionMode = {
|
|
332
|
+
mode: SelectionModeType.Multiple,
|
|
333
|
+
checkboxes: true
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Events
|
|
338
|
+
|
|
339
|
+
| Event | Payload | Description |
|
|
340
|
+
|-------|---------|-------------|
|
|
341
|
+
| `row-click` | `(row: any)` | Row clicked |
|
|
342
|
+
| `row-dblclick` | `(row: any)` | Row double-clicked |
|
|
343
|
+
| `cell-click` | `(row: any, column: ColumnDefinition)` | Cell clicked |
|
|
344
|
+
| `selection-changed` | `(selectedRows: any[])` | Selection changed |
|
|
345
|
+
| `data-loaded` | `(data: any[])` | Data loaded |
|
|
346
|
+
| `sort-changed` | `(descriptors: SortDescriptor[])` | Sorting changed |
|
|
347
|
+
| `filter-changed` | `(filters: FilterCondition[])` | Filters changed |
|
|
348
|
+
| `group-changed` | `(descriptors: any[])` | Grouping changed |
|
|
349
|
+
| `page-changed` | `(page: number, pageSize: number)` | Page changed |
|
|
350
|
+
| `edit-saved` | `(change: Change, mode: string)` | Edit saved |
|
|
351
|
+
| `column-reordered` | `(order: string[])` | Columns reordered |
|
|
352
|
+
| `column-resized` | `(column: ColumnDefinition, width: number)` | Column resized |
|
|
353
|
+
| `column-visibility-changed` | `(visibleColumns: string[])` | Column visibility changed |
|
|
354
|
+
| `row-expansion-changed` | `(payload: ExpansionPayload)` | Row expansion changed |
|
|
355
|
+
| `key-down` | `(payload: KeyboardPayload)` | Key pressed |
|
|
356
|
+
| `data-error` | `(error: Error)` | Data loading error |
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## π Examples
|
|
361
|
+
|
|
362
|
+
### Example 1: Basic Grid with Selection
|
|
363
|
+
|
|
364
|
+
```vue
|
|
365
|
+
<template>
|
|
366
|
+
<TSDataGrid
|
|
367
|
+
ref="gridRef"
|
|
368
|
+
:columns="columns"
|
|
369
|
+
:data-source="dataSource"
|
|
370
|
+
key-field="id"
|
|
371
|
+
|
|
372
|
+
<!-- Core Features -->
|
|
373
|
+
:allow-sorting="true"
|
|
374
|
+
:allow-filtering="true"
|
|
375
|
+
:allow-paging="true"
|
|
376
|
+
|
|
377
|
+
<!-- Selection -->
|
|
378
|
+
:allow-selection="true"
|
|
379
|
+
:selection-mode="selectionMode"
|
|
380
|
+
|
|
381
|
+
<!-- UI -->
|
|
382
|
+
:show-toolbar="true"
|
|
383
|
+
:show-search="true"
|
|
384
|
+
:max-height="600"
|
|
385
|
+
:page-size="20"
|
|
386
|
+
|
|
387
|
+
@selection-changed="handleSelectionChanged"
|
|
388
|
+
@row-click="handleRowClick"
|
|
389
|
+
/>
|
|
390
|
+
</template>
|
|
391
|
+
|
|
392
|
+
<script setup lang="ts">
|
|
393
|
+
import { ref } from 'vue'
|
|
394
|
+
import { SelectionModeType, type SelectionMode } from 'tsdatagrid'
|
|
395
|
+
|
|
396
|
+
const gridRef = ref()
|
|
397
|
+
|
|
398
|
+
const selectionMode: SelectionMode = {
|
|
399
|
+
mode: SelectionModeType.Multiple,
|
|
400
|
+
checkboxes: true
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const handleSelectionChanged = (selectedRows: any[]) => {
|
|
404
|
+
console.log('Selected:', selectedRows.length, 'rows')
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const handleRowClick = (row: any) => {
|
|
408
|
+
console.log('Clicked:', row.name)
|
|
409
|
+
}
|
|
410
|
+
</script>
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Example 2: Inline Editing with Undo/Redo
|
|
414
|
+
|
|
415
|
+
```vue
|
|
416
|
+
<template>
|
|
417
|
+
<div>
|
|
418
|
+
<!-- Undo/Redo Controls -->
|
|
419
|
+
<div class="toolbar">
|
|
420
|
+
<button @click="handleUndo" :disabled="!canUndo">
|
|
421
|
+
β©οΈ Undo (Ctrl+Z)
|
|
422
|
+
</button>
|
|
423
|
+
<button @click="handleRedo" :disabled="!canRedo">
|
|
424
|
+
βͺοΈ Redo (Ctrl+Y)
|
|
425
|
+
</button>
|
|
426
|
+
</div>
|
|
427
|
+
|
|
428
|
+
<TSDataGrid
|
|
429
|
+
ref="gridRef"
|
|
430
|
+
:columns="columns"
|
|
431
|
+
:data-source="dataSource"
|
|
432
|
+
|
|
433
|
+
:allow-editing="true"
|
|
434
|
+
:allow-adding="true"
|
|
435
|
+
:allow-deleting="true"
|
|
436
|
+
|
|
437
|
+
@edit-saved="handleEditSaved"
|
|
438
|
+
@state-changed="handleStateChanged"
|
|
439
|
+
/>
|
|
440
|
+
</div>
|
|
441
|
+
</template>
|
|
442
|
+
|
|
443
|
+
<script setup lang="ts">
|
|
444
|
+
import { ref } from 'vue'
|
|
445
|
+
import { ColumnType, Alignment, type EditorType } from 'tsdatagrid'
|
|
446
|
+
|
|
447
|
+
const gridRef = ref()
|
|
448
|
+
const canUndo = ref(false)
|
|
449
|
+
const canRedo = ref(false)
|
|
450
|
+
|
|
451
|
+
const columns = [
|
|
452
|
+
{
|
|
453
|
+
field: 'name',
|
|
454
|
+
title: 'Name',
|
|
455
|
+
type: ColumnType.String,
|
|
456
|
+
editable: true,
|
|
457
|
+
editor: {
|
|
458
|
+
type: 'text' as EditorType,
|
|
459
|
+
placeholder: 'Enter name'
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
field: 'salary',
|
|
464
|
+
title: 'Salary',
|
|
465
|
+
type: ColumnType.Number,
|
|
466
|
+
editable: true,
|
|
467
|
+
editor: {
|
|
468
|
+
type: 'number' as EditorType,
|
|
469
|
+
min: 0,
|
|
470
|
+
max: 500000,
|
|
471
|
+
step: 1000
|
|
472
|
+
},
|
|
473
|
+
alignment: Alignment.Right,
|
|
474
|
+
formatter: (value) => `$${Number(value).toLocaleString()}`
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
field: 'department',
|
|
478
|
+
title: 'Department',
|
|
479
|
+
editable: true,
|
|
480
|
+
editor: {
|
|
481
|
+
type: 'select' as EditorType,
|
|
482
|
+
options: ['IT', 'HR', 'Sales', 'Marketing']
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
field: 'hireDate',
|
|
487
|
+
title: 'Hire Date',
|
|
488
|
+
type: ColumnType.Date,
|
|
489
|
+
editable: true,
|
|
490
|
+
editor: {
|
|
491
|
+
type: 'date' as EditorType
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
]
|
|
495
|
+
|
|
496
|
+
const handleStateChanged = (state: any) => {
|
|
497
|
+
if (state.canUndo !== undefined) {
|
|
498
|
+
canUndo.value = state.canUndo
|
|
499
|
+
}
|
|
500
|
+
if (state.canRedo !== undefined) {
|
|
501
|
+
canRedo.value = state.canRedo
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
const handleUndo = () => {
|
|
506
|
+
if (gridRef.value && canUndo.value) {
|
|
507
|
+
gridRef.value.undo()
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
const handleRedo = () => {
|
|
512
|
+
if (gridRef.value && canRedo.value) {
|
|
513
|
+
gridRef.value.redo()
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const handleEditSaved = (change: any, mode: string) => {
|
|
518
|
+
console.log('Edit:', change.type, change.field, change.newValue)
|
|
519
|
+
}
|
|
520
|
+
</script>
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Example 3: Export
|
|
524
|
+
|
|
525
|
+
```vue
|
|
526
|
+
<template>
|
|
527
|
+
<div>
|
|
528
|
+
<div class="toolbar">
|
|
529
|
+
<button @click="exportToCsv">π Export CSV</button>
|
|
530
|
+
<button @click="exportToExcel">π Export Excel</button>
|
|
531
|
+
<button @click="exportToPdf">π Export PDF</button>
|
|
532
|
+
<button @click="exportSelected" :disabled="selectedCount === 0">
|
|
533
|
+
π€ Export Selected
|
|
534
|
+
</button>
|
|
535
|
+
</div>
|
|
536
|
+
|
|
537
|
+
<TSDataGrid
|
|
538
|
+
ref="gridRef"
|
|
539
|
+
:columns="columns"
|
|
540
|
+
:data-source="dataSource"
|
|
541
|
+
|
|
542
|
+
:allow-export="true"
|
|
543
|
+
:allow-selection="true"
|
|
544
|
+
:selection-mode="{ mode: SelectionModeType.Multiple, checkboxes: true }"
|
|
545
|
+
/>
|
|
546
|
+
</div>
|
|
547
|
+
</template>
|
|
548
|
+
|
|
549
|
+
<script setup lang="ts">
|
|
550
|
+
import { ref } from 'vue'
|
|
551
|
+
import { SelectionModeType } from 'tsdatagrid'
|
|
552
|
+
|
|
553
|
+
const gridRef = ref()
|
|
554
|
+
const selectedCount = ref(0)
|
|
555
|
+
|
|
556
|
+
const exportToCsv = () => {
|
|
557
|
+
gridRef.value?.exportData('csv')
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
const exportToExcel = () => {
|
|
561
|
+
gridRef.value?.exportData('excel')
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const exportToPdf = () => {
|
|
565
|
+
gridRef.value?.exportData('pdf')
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const exportSelected = () => {
|
|
569
|
+
gridRef.value?.exportData('csv')
|
|
570
|
+
}
|
|
571
|
+
</script>
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Example 4: Grouping with Summaries
|
|
575
|
+
|
|
576
|
+
```vue
|
|
577
|
+
<template>
|
|
578
|
+
<TSDataGrid
|
|
579
|
+
:columns="columns"
|
|
580
|
+
:data-source="dataSource"
|
|
581
|
+
|
|
582
|
+
:allow-grouping="true"
|
|
583
|
+
:show-group-panel="true"
|
|
584
|
+
:show-summary="true"
|
|
585
|
+
:show-group-summary="true"
|
|
586
|
+
:summary="summaryConfig"
|
|
587
|
+
|
|
588
|
+
@group-changed="handleGroupChanged"
|
|
589
|
+
/>
|
|
590
|
+
</template>
|
|
591
|
+
|
|
592
|
+
<script setup lang="ts">
|
|
593
|
+
import { ref } from 'vue'
|
|
594
|
+
import type { SummaryConfig } from 'tsdatagrid'
|
|
595
|
+
|
|
596
|
+
const summaryConfig = ref<SummaryConfig[]>([
|
|
597
|
+
{ field: 'salary', type: 'sum', label: 'Total Salary' },
|
|
598
|
+
{ field: 'salary', type: 'avg', label: 'Average Salary' },
|
|
599
|
+
{ field: 'id', type: 'count', label: 'Employee Count' }
|
|
600
|
+
])
|
|
601
|
+
|
|
602
|
+
const handleGroupChanged = (descriptors: any[]) => {
|
|
603
|
+
console.log('Grouped by:', descriptors.map(d => d.field))
|
|
604
|
+
}
|
|
605
|
+
</script>
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### Example 5: Virtual Scrolling (Large Datasets)
|
|
609
|
+
|
|
610
|
+
```vue
|
|
611
|
+
<template>
|
|
612
|
+
<TSDataGrid
|
|
613
|
+
:columns="columns"
|
|
614
|
+
:data-source="dataSource"
|
|
615
|
+
|
|
616
|
+
:enable-virtualization="true"
|
|
617
|
+
:virtual-row-height="40"
|
|
618
|
+
:virtual-row-buffer="5"
|
|
619
|
+
:max-height="600"
|
|
620
|
+
|
|
621
|
+
:allow-sorting="true"
|
|
622
|
+
:allow-filtering="true"
|
|
623
|
+
/>
|
|
624
|
+
</template>
|
|
625
|
+
|
|
626
|
+
<script setup lang="ts">
|
|
627
|
+
// Generate large dataset
|
|
628
|
+
const generateLargeDataset = (count: number) => {
|
|
629
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
630
|
+
id: i + 1,
|
|
631
|
+
name: `Employee ${i + 1}`,
|
|
632
|
+
email: `employee${i + 1}@example.com`,
|
|
633
|
+
salary: Math.floor(Math.random() * 100000) + 30000,
|
|
634
|
+
}))
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const dataSource = {
|
|
638
|
+
type: DataSourceType.Local,
|
|
639
|
+
data: generateLargeDataset(100000) // 100K rows
|
|
640
|
+
}
|
|
641
|
+
</script>
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
## π§ Grid API Reference
|
|
647
|
+
|
|
648
|
+
Access grid methods via template ref:
|
|
649
|
+
|
|
650
|
+
```typescript
|
|
651
|
+
// Data Operations
|
|
652
|
+
gridRef.value?.refresh() // Reload data
|
|
653
|
+
gridRef.value?.getData() // Get raw data
|
|
654
|
+
gridRef.value?.getProcessedData() // Get filtered/sorted data
|
|
655
|
+
|
|
656
|
+
// Selection
|
|
657
|
+
gridRef.value?.selectAll() // Select all rows
|
|
658
|
+
gridRef.value?.clearSelection() // Clear selection
|
|
659
|
+
gridRef.value?.getSelectedRows() // Get selected rows
|
|
660
|
+
gridRef.value?.selectByKeys([1,2,3]) // Select by keys
|
|
661
|
+
|
|
662
|
+
// Filtering
|
|
663
|
+
gridRef.value?.clearFilters() // Clear all filters
|
|
664
|
+
gridRef.value?.applyFilter('name', FilterOperator.Contains, 'John')
|
|
665
|
+
gridRef.value?.removeFilter('name')
|
|
666
|
+
|
|
667
|
+
// Grouping
|
|
668
|
+
gridRef.value?.groupBy('department') // Group by field
|
|
669
|
+
gridRef.value?.groupBy(['dept', 'pos']) // Multiple groups
|
|
670
|
+
gridRef.value?.clearGrouping() // Clear groups
|
|
671
|
+
|
|
672
|
+
// Columns
|
|
673
|
+
gridRef.value?.showColumn('email') // Show column
|
|
674
|
+
gridRef.value?.hideColumn('phone') // Hide column
|
|
675
|
+
gridRef.value?.setColumnWidth('name', 250)
|
|
676
|
+
gridRef.value?.autoSizeColumn('name')
|
|
677
|
+
gridRef.value?.autoSizeAllColumns()
|
|
678
|
+
gridRef.value?.resetColumnWidths()
|
|
679
|
+
|
|
680
|
+
// Export
|
|
681
|
+
gridRef.value?.exportData('csv') // Export CSV
|
|
682
|
+
gridRef.value?.exportData('excel') // Export Excel
|
|
683
|
+
gridRef.value?.exportData('pdf') // Export PDF
|
|
684
|
+
|
|
685
|
+
// Clipboard
|
|
686
|
+
gridRef.value?.copySelectedRows() // Copy selection
|
|
687
|
+
gridRef.value?.cutSelectedRows() // Cut selection
|
|
688
|
+
gridRef.value?.pasteRows() // Paste
|
|
689
|
+
|
|
690
|
+
// Undo/Redo
|
|
691
|
+
gridRef.value?.undo() // Undo last change
|
|
692
|
+
gridRef.value?.redo() // Redo last undo
|
|
693
|
+
gridRef.value?.canUndo() // Check if can undo
|
|
694
|
+
gridRef.value?.canRedo() // Check if can redo
|
|
695
|
+
gridRef.value?.clearUndoHistory() // Clear history
|
|
696
|
+
|
|
697
|
+
// Row Expansion
|
|
698
|
+
gridRef.value?.expandRow(rowKey) // Expand row
|
|
699
|
+
gridRef.value?.collapseRow(rowKey) // Collapse row
|
|
700
|
+
gridRef.value?.expandAllRows() // Expand all
|
|
701
|
+
gridRef.value?.collapseAllRows() // Collapse all
|
|
702
|
+
|
|
703
|
+
// Keyboard Navigation
|
|
704
|
+
gridRef.value?.setFocus(rowKey, columnField)
|
|
705
|
+
gridRef.value?.moveFocus('down') // Move focus
|
|
706
|
+
gridRef.value?.moveToFirstCell() // Focus first cell
|
|
707
|
+
gridRef.value?.clearFocus() // Clear focus
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
---
|
|
711
|
+
|
|
712
|
+
## π¨ Theming
|
|
713
|
+
|
|
714
|
+
TSDataGrid comes with three built-in themes:
|
|
715
|
+
|
|
716
|
+
```vue
|
|
717
|
+
<!-- Default theme -->
|
|
718
|
+
<TSDataGrid theme="default" ... />
|
|
719
|
+
|
|
720
|
+
<!-- Material theme -->
|
|
721
|
+
<TSDataGrid theme="material" ... />
|
|
722
|
+
|
|
723
|
+
<!-- Dark theme -->
|
|
724
|
+
<TSDataGrid theme="dark" ... />
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### Custom Styling
|
|
728
|
+
|
|
729
|
+
Override CSS variables for custom styling:
|
|
730
|
+
|
|
731
|
+
```css
|
|
732
|
+
:root {
|
|
733
|
+
--tsdatagrid-primary-color: #1976d2;
|
|
734
|
+
--tsdatagrid-header-bg: #f5f5f5;
|
|
735
|
+
--tsdatagrid-row-hover-bg: #f0f0f0;
|
|
736
|
+
--tsdatagrid-border-color: #e0e0e0;
|
|
737
|
+
--tsdatagrid-font-family: 'Roboto', sans-serif;
|
|
738
|
+
--tsdatagrid-header-height: 48px;
|
|
739
|
+
--tsdatagrid-row-height: 40px;
|
|
740
|
+
--tsdatagrid-selection-bg: #e3f2fd;
|
|
741
|
+
--tsdatagrid-focus-border: #2196f3;
|
|
742
|
+
}
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
---
|
|
746
|
+
|
|
747
|
+
## β¨οΈ Keyboard Shortcuts
|
|
748
|
+
|
|
749
|
+
TSDataGrid supports extensive keyboard navigation:
|
|
750
|
+
|
|
751
|
+
| Shortcut | Action |
|
|
752
|
+
|----------|--------|
|
|
753
|
+
| Arrow Keys | Navigate between cells |
|
|
754
|
+
| Tab | Move to next cell |
|
|
755
|
+
| Shift + Tab | Move to previous cell |
|
|
756
|
+
| Home | Move to first cell in row |
|
|
757
|
+
| End | Move to last cell in row |
|
|
758
|
+
| Ctrl + Home | Move to first cell in grid |
|
|
759
|
+
| Ctrl + End | Move to last cell in grid |
|
|
760
|
+
| Page Up | Scroll up one page |
|
|
761
|
+
| Page Down | Scroll down one page |
|
|
762
|
+
| Enter | Start editing / Save edit |
|
|
763
|
+
| Esc | Cancel editing |
|
|
764
|
+
| F2 | Start editing focused cell |
|
|
765
|
+
| Space | Toggle row selection |
|
|
766
|
+
| Ctrl + A | Select all rows |
|
|
767
|
+
| Shift + Arrow | Extend selection |
|
|
768
|
+
| Ctrl + C | Copy selected rows |
|
|
769
|
+
| Ctrl + X | Cut selected rows |
|
|
770
|
+
| Ctrl + V | Paste rows |
|
|
771
|
+
| Ctrl + Z | Undo last change |
|
|
772
|
+
| Ctrl + Y | Redo last undo |
|
|
773
|
+
| Delete | Delete selected rows |
|
|
774
|
+
|
|
775
|
+
---
|
|
776
|
+
|
|
777
|
+
## π― Custom Templates
|
|
778
|
+
|
|
779
|
+
TSDataGrid supports extensive customization via slots.
|
|
780
|
+
|
|
781
|
+
### Cell Templates
|
|
782
|
+
|
|
783
|
+
```vue
|
|
784
|
+
<template>
|
|
785
|
+
<TSDataGrid :columns="columns" :data-source="dataSource">
|
|
786
|
+
<!-- Custom cell template -->
|
|
787
|
+
<template #cell-status="{ value, row }">
|
|
788
|
+
<span :class="['badge', `badge-${value.toLowerCase()}`]">
|
|
789
|
+
{{ value }}
|
|
790
|
+
</span>
|
|
791
|
+
</template>
|
|
792
|
+
|
|
793
|
+
<!-- Custom actions column -->
|
|
794
|
+
<template #cell-actions="{ row }">
|
|
795
|
+
<button @click="editRow(row)">Edit</button>
|
|
796
|
+
<button @click="deleteRow(row)">Delete</button>
|
|
797
|
+
</template>
|
|
798
|
+
</TSDataGrid>
|
|
799
|
+
</template>
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
### Header Templates
|
|
803
|
+
|
|
804
|
+
```vue
|
|
805
|
+
<template>
|
|
806
|
+
<TSDataGrid :columns="columns" :data-source="dataSource">
|
|
807
|
+
<!-- Custom header template -->
|
|
808
|
+
<template #header-name="{ column }">
|
|
809
|
+
<div class="custom-header">
|
|
810
|
+
<span class="icon">π€</span>
|
|
811
|
+
{{ column.title }}
|
|
812
|
+
</div>
|
|
813
|
+
</template>
|
|
814
|
+
</TSDataGrid>
|
|
815
|
+
</template>
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
### Detail Row Template
|
|
819
|
+
|
|
820
|
+
```vue
|
|
821
|
+
<template>
|
|
822
|
+
<TSDataGrid
|
|
823
|
+
:columns="columns"
|
|
824
|
+
:data-source="dataSource"
|
|
825
|
+
:allow-row-expansion="true"
|
|
826
|
+
>
|
|
827
|
+
<!-- Expandable detail row -->
|
|
828
|
+
<template #detail="{ row }">
|
|
829
|
+
<div class="detail-panel">
|
|
830
|
+
<h3>{{ row.name }} - Details</h3>
|
|
831
|
+
<div class="detail-content">
|
|
832
|
+
<p><strong>Email:</strong> {{ row.email }}</p>
|
|
833
|
+
<p><strong>Phone:</strong> {{ row.phone }}</p>
|
|
834
|
+
</div>
|
|
835
|
+
</div>
|
|
836
|
+
</template>
|
|
837
|
+
</TSDataGrid>
|
|
838
|
+
</template>
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Empty State Template
|
|
842
|
+
|
|
843
|
+
```vue
|
|
844
|
+
<template>
|
|
845
|
+
<TSDataGrid :columns="columns" :data-source="dataSource">
|
|
846
|
+
<!-- Custom empty state -->
|
|
847
|
+
<template #empty>
|
|
848
|
+
<div class="empty-state">
|
|
849
|
+
<img src="/empty-icon.svg" alt="No data" />
|
|
850
|
+
<h3>No Employees Found</h3>
|
|
851
|
+
<p>Add your first employee to get started</p>
|
|
852
|
+
<button @click="addEmployee">Add Employee</button>
|
|
853
|
+
</div>
|
|
854
|
+
</template>
|
|
855
|
+
</TSDataGrid>
|
|
856
|
+
</template>
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
---
|
|
860
|
+
|
|
861
|
+
## π Advanced Features
|
|
862
|
+
|
|
863
|
+
### OData Integration
|
|
864
|
+
|
|
865
|
+
Full OData v4 support for server-side operations:
|
|
866
|
+
|
|
867
|
+
```typescript
|
|
868
|
+
const dataSource: DataSourceConfig = {
|
|
869
|
+
type: DataSourceType.OData,
|
|
870
|
+
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Products',
|
|
871
|
+
|
|
872
|
+
// Enable server-side operations
|
|
873
|
+
serverPaging: true,
|
|
874
|
+
serverSorting: true,
|
|
875
|
+
serverFiltering: true,
|
|
876
|
+
serverGrouping: true,
|
|
877
|
+
|
|
878
|
+
// Configuration
|
|
879
|
+
pageSize: 20,
|
|
880
|
+
|
|
881
|
+
// Custom headers (optional)
|
|
882
|
+
headers: {
|
|
883
|
+
'Authorization': 'Bearer token'
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
### Validation
|
|
889
|
+
|
|
890
|
+
Add validators to editable columns:
|
|
891
|
+
|
|
892
|
+
```typescript
|
|
893
|
+
const columns: ColumnDefinition[] = [
|
|
894
|
+
{
|
|
895
|
+
field: 'email',
|
|
896
|
+
title: 'Email',
|
|
897
|
+
editable: true,
|
|
898
|
+
validator: (value: string) => {
|
|
899
|
+
if (!value) return 'Email is required'
|
|
900
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
|
|
901
|
+
return 'Invalid email format'
|
|
902
|
+
}
|
|
903
|
+
return true
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
]
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
### Summary Calculations
|
|
910
|
+
|
|
911
|
+
Configure aggregations for footer row:
|
|
912
|
+
|
|
913
|
+
```typescript
|
|
914
|
+
import type { SummaryConfig } from 'tsdatagrid'
|
|
915
|
+
|
|
916
|
+
const summaryConfig: SummaryConfig[] = [
|
|
917
|
+
{
|
|
918
|
+
field: 'salary',
|
|
919
|
+
type: 'sum',
|
|
920
|
+
label: 'Total Salary',
|
|
921
|
+
scope: 'all',
|
|
922
|
+
formatter: (value) => `${value.toLocaleString()}`,
|
|
923
|
+
precision: 2
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
field: 'salary',
|
|
927
|
+
type: 'avg',
|
|
928
|
+
label: 'Average Salary',
|
|
929
|
+
scope: 'page'
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
field: 'id',
|
|
933
|
+
type: 'count',
|
|
934
|
+
label: 'Total Employees'
|
|
935
|
+
}
|
|
936
|
+
]
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
### Custom Cell Styling
|
|
940
|
+
|
|
941
|
+
Apply conditional styles:
|
|
942
|
+
|
|
943
|
+
```typescript
|
|
944
|
+
const columns: ColumnDefinition[] = [
|
|
945
|
+
{
|
|
946
|
+
field: 'status',
|
|
947
|
+
title: 'Status',
|
|
948
|
+
cssClass: 'status-column',
|
|
949
|
+
cellCssClass: (row: any) => {
|
|
950
|
+
return `status-${row.status.toLowerCase()}`
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
]
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
### State Persistence
|
|
957
|
+
|
|
958
|
+
Automatically save and restore grid state:
|
|
959
|
+
|
|
960
|
+
```vue
|
|
961
|
+
<template>
|
|
962
|
+
<TSDataGrid
|
|
963
|
+
:columns="columns"
|
|
964
|
+
:data-source="dataSource"
|
|
965
|
+
state-key="employee-grid"
|
|
966
|
+
/>
|
|
967
|
+
</template>
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
Saved state includes: column visibility, column order, column widths, sorting, filtering, grouping, pagination, selection, and expanded groups/rows.
|
|
971
|
+
|
|
972
|
+
---
|
|
973
|
+
|
|
974
|
+
## π Performance Tips
|
|
975
|
+
|
|
976
|
+
- **Virtual Scrolling**: Enable for datasets > 1000 rows
|
|
977
|
+
```typescript
|
|
978
|
+
:enable-virtualization="true"
|
|
979
|
+
:max-height="600"
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
- **Server-Side Operations**: Offload sorting/filtering/paging to server
|
|
983
|
+
```typescript
|
|
984
|
+
const dataSource: DataSourceConfig = {
|
|
985
|
+
type: DataSourceType.OData,
|
|
986
|
+
serverPaging: true,
|
|
987
|
+
serverSorting: true,
|
|
988
|
+
serverFiltering: true
|
|
989
|
+
}
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
- **Optimize Formatters**: Avoid heavy computations in formatters
|
|
993
|
+
```typescript
|
|
994
|
+
// β
Good - memoize values
|
|
995
|
+
const memoizedValues = new Map()
|
|
996
|
+
formatter: (value) => {
|
|
997
|
+
if (!memoizedValues.has(value)) {
|
|
998
|
+
memoizedValues.set(value, expensiveCalculation(value))
|
|
999
|
+
}
|
|
1000
|
+
return memoizedValues.get(value)
|
|
1001
|
+
}
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
- **Limit Visible Columns**: Show only essential columns by default
|
|
1005
|
+
```typescript
|
|
1006
|
+
const columns: ColumnDefinition[] = [
|
|
1007
|
+
{ field: 'id', visible: true },
|
|
1008
|
+
{ field: 'name', visible: true },
|
|
1009
|
+
{ field: 'optional1', visible: false }
|
|
1010
|
+
]
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
- **Use Key Field**: Always specify a unique key field
|
|
1014
|
+
```typescript
|
|
1015
|
+
<TSDataGrid key-field="id" ... />
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
---
|
|
1019
|
+
|
|
1020
|
+
## π Troubleshooting
|
|
1021
|
+
|
|
1022
|
+
### Grid Not Displaying
|
|
1023
|
+
|
|
1024
|
+
**Problem**: Grid appears empty or doesn't render
|
|
1025
|
+
|
|
1026
|
+
**Solutions**:
|
|
1027
|
+
- Ensure CSS is imported: `import 'tsdatagrid/dist/style.css'`
|
|
1028
|
+
- Check data structure: `console.log('Data:', dataSource.data)`
|
|
1029
|
+
- Verify key field exists in data
|
|
1030
|
+
|
|
1031
|
+
### Editing Not Working
|
|
1032
|
+
|
|
1033
|
+
**Problem**: Can't edit cells
|
|
1034
|
+
|
|
1035
|
+
**Solutions**:
|
|
1036
|
+
- Enable editing: `:allow-editing="true"`
|
|
1037
|
+
- Mark columns as editable: `{ field: 'name', editable: true }`
|
|
1038
|
+
- Provide editor config: `{ editor: { type: 'text' as EditorType } }`
|
|
1039
|
+
|
|
1040
|
+
### Selection Not Working
|
|
1041
|
+
|
|
1042
|
+
**Problem**: Can't select rows
|
|
1043
|
+
|
|
1044
|
+
**Solutions**:
|
|
1045
|
+
- Enable selection: `:allow-selection="true"`
|
|
1046
|
+
- Configure selection mode: `:selection-mode="{ mode: SelectionModeType.Multiple, checkboxes: true }"`
|
|
1047
|
+
- Import enum: `import { SelectionModeType } from 'tsdatagrid'`
|
|
1048
|
+
|
|
1049
|
+
### Virtual Scroll Issues
|
|
1050
|
+
|
|
1051
|
+
**Problem**: Virtual scrolling not working or jumpy
|
|
1052
|
+
|
|
1053
|
+
**Solutions**:
|
|
1054
|
+
- Set max-height: `:max-height="600"`
|
|
1055
|
+
- Consistent row height: `:virtual-row-height="40"`
|
|
1056
|
+
- Wait for data to load before initializing
|
|
1057
|
+
|
|
1058
|
+
### OData Errors
|
|
1059
|
+
|
|
1060
|
+
**Problem**: OData requests failing
|
|
1061
|
+
|
|
1062
|
+
**Solutions**:
|
|
1063
|
+
- Check CORS configuration on server
|
|
1064
|
+
- Verify OData URL is correct
|
|
1065
|
+
- Check network tab for error details
|
|
1066
|
+
|
|
1067
|
+
### Type Errors
|
|
1068
|
+
|
|
1069
|
+
**Problem**: TypeScript compilation errors
|
|
1070
|
+
|
|
1071
|
+
**Solutions**:
|
|
1072
|
+
```typescript
|
|
1073
|
+
// Import types explicitly
|
|
1074
|
+
import type {
|
|
1075
|
+
ColumnDefinition,
|
|
1076
|
+
DataSourceConfig
|
|
1077
|
+
} from 'tsdatagrid'
|
|
1078
|
+
|
|
1079
|
+
import {
|
|
1080
|
+
ColumnType,
|
|
1081
|
+
SelectionModeType,
|
|
1082
|
+
DataSourceType
|
|
1083
|
+
} from 'tsdatagrid'
|
|
1084
|
+
|
|
1085
|
+
// Use enums for type-safe values
|
|
1086
|
+
type: ColumnType.Number // β
Correct
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
---
|
|
1090
|
+
|
|
1091
|
+
## π Migration Guide
|
|
1092
|
+
|
|
1093
|
+
### From Version 1.x to 2.x
|
|
1094
|
+
|
|
1095
|
+
**Breaking Changes**:
|
|
1096
|
+
|
|
1097
|
+
Import changes:
|
|
1098
|
+
```typescript
|
|
1099
|
+
// β
New (v2.x)
|
|
1100
|
+
import TSDataGrid from 'tsdatagrid'
|
|
1101
|
+
import 'tsdatagrid/dist/style.css'
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
Enum updates:
|
|
1105
|
+
```typescript
|
|
1106
|
+
// β
New
|
|
1107
|
+
import { SelectionModeType } from 'tsdatagrid'
|
|
1108
|
+
selectionMode: { mode: SelectionModeType.Multiple, checkboxes: true }
|
|
1109
|
+
```
|
|
1110
|
+
|
|
1111
|
+
Editor configuration:
|
|
1112
|
+
```typescript
|
|
1113
|
+
// β
New
|
|
1114
|
+
import type { EditorType } from 'tsdatagrid'
|
|
1115
|
+
editor: { type: 'text' as EditorType }
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
Data source type:
|
|
1119
|
+
```typescript
|
|
1120
|
+
// β
New
|
|
1121
|
+
import { DataSourceType } from 'tsdatagrid'
|
|
1122
|
+
dataSource: { type: DataSourceType.Local, data: [] }
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
---
|
|
1126
|
+
|
|
1127
|
+
## π€ Contributing
|
|
1128
|
+
|
|
1129
|
+
Contributions are welcome! Please follow these steps:
|
|
1130
|
+
|
|
1131
|
+
1. Fork the repository
|
|
1132
|
+
```bash
|
|
1133
|
+
git clone https://github.com/yourusername/tsdatagrid.git
|
|
1134
|
+
cd tsdatagrid
|
|
1135
|
+
```
|
|
1136
|
+
|
|
1137
|
+
2. Install dependencies
|
|
1138
|
+
```bash
|
|
1139
|
+
npm install
|
|
1140
|
+
```
|
|
1141
|
+
|
|
1142
|
+
3. Create feature branch
|
|
1143
|
+
```bash
|
|
1144
|
+
git checkout -b feature/amazing-feature
|
|
1145
|
+
```
|
|
1146
|
+
|
|
1147
|
+
4. Make changes and test
|
|
1148
|
+
```bash
|
|
1149
|
+
npm run dev # Start dev server
|
|
1150
|
+
npm run test # Run tests
|
|
1151
|
+
npm run lint # Check linting
|
|
1152
|
+
```
|
|
1153
|
+
|
|
1154
|
+
5. Commit changes
|
|
1155
|
+
```bash
|
|
1156
|
+
git commit -m 'Add amazing feature'
|
|
1157
|
+
```
|
|
1158
|
+
|
|
1159
|
+
6. Push and create PR
|
|
1160
|
+
```bash
|
|
1161
|
+
git push origin feature/amazing-feature
|
|
1162
|
+
```
|
|
1163
|
+
|
|
1164
|
+
### Development Setup
|
|
1165
|
+
|
|
1166
|
+
```bash
|
|
1167
|
+
# Install dependencies
|
|
1168
|
+
npm install
|
|
1169
|
+
|
|
1170
|
+
# Run dev server with examples
|
|
1171
|
+
npm run dev
|
|
1172
|
+
|
|
1173
|
+
# Build library
|
|
1174
|
+
npm run build
|
|
1175
|
+
|
|
1176
|
+
# Run tests
|
|
1177
|
+
npm run test
|
|
1178
|
+
|
|
1179
|
+
# Run tests in watch mode
|
|
1180
|
+
npm run test:watch
|
|
1181
|
+
|
|
1182
|
+
# Lint code
|
|
1183
|
+
npm run lint
|
|
1184
|
+
|
|
1185
|
+
# Format code
|
|
1186
|
+
npm run format
|
|
1187
|
+
```
|
|
1188
|
+
|
|
1189
|
+
---
|
|
1190
|
+
|
|
1191
|
+
## π License
|
|
1192
|
+
|
|
1193
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
1194
|
+
|
|
1195
|
+
---
|
|
1196
|
+
|
|
1197
|
+
## π Acknowledgments
|
|
1198
|
+
|
|
1199
|
+
- Built with Vue 3
|
|
1200
|
+
- Powered by TypeScript
|
|
1201
|
+
- Export functionality using jsPDF, jsPDF-AutoTable, PapaParse, and SheetJS
|
|
1202
|
+
|
|
1203
|
+
---
|
|
1204
|
+
|
|
1205
|
+
## π Support
|
|
1206
|
+
|
|
1207
|
+
- π« Email: support@tsdatagrid.com
|
|
1208
|
+
- π Issues: GitHub Issues
|
|
1209
|
+
- π¬ Discussions: GitHub Discussions
|
|
1210
|
+
- π Documentation: Full Docs
|
|
1211
|
+
- π‘ Stack Overflow: Tag with tsdatagrid
|
|
1212
|
+
|
|
1213
|
+
---
|
|
1214
|
+
|
|
1215
|
+
## πΊοΈ Roadmap
|
|
1216
|
+
|
|
1217
|
+
### Version 2.1 (Q1 2025)
|
|
1218
|
+
- β
Undo/Redo functionality
|
|
1219
|
+
- β
Clipboard operations (copy/cut/paste)
|
|
1220
|
+
- β
Context menus
|
|
1221
|
+
- β
Keyboard navigation
|
|
1222
|
+
- Frozen columns (left/right)
|
|
1223
|
+
- Cell merging
|
|
1224
|
+
- Advanced filtering UI
|
|
1225
|
+
|
|
1226
|
+
### Version 2.2 (Q2 2025)
|
|
1227
|
+
- Tree data support
|
|
1228
|
+
- Master-detail grids
|
|
1229
|
+
- Column templates
|
|
1230
|
+
- Row templates
|
|
1231
|
+
- Touch gestures for mobile
|
|
1232
|
+
- Accessibility improvements (WCAG 2.1 AA)
|
|
1233
|
+
|
|
1234
|
+
### Version 3.0 (Q3 2025)
|
|
1235
|
+
- React adapter
|
|
1236
|
+
- Angular adapter
|
|
1237
|
+
- Pivot table mode
|
|
1238
|
+
- Chart integration
|
|
1239
|
+
- Real-time data updates (WebSocket)
|
|
1240
|
+
- More built-in themes
|
|
1241
|
+
|
|
1242
|
+
---
|
|
1243
|
+
|
|
1244
|
+
## π Browser Support
|
|
1245
|
+
|
|
1246
|
+
| Browser | Version |
|
|
1247
|
+
|---------|---------|
|
|
1248
|
+
| Chrome | Latest 2 versions |
|
|
1249
|
+
| Firefox | Latest 2 versions |
|
|
1250
|
+
| Safari | Latest 2 versions |
|
|
1251
|
+
| Edge | Latest 2 versions |
|
|
1252
|
+
| Opera | Latest version |
|
|
1253
|
+
|
|
1254
|
+
**Note**: IE11 is not supported due to Vue 3 requirements.
|
|
1255
|
+
|
|
1256
|
+
---
|
|
1257
|
+
|
|
1258
|
+
## π Useful Links
|
|
1259
|
+
|
|
1260
|
+
- [Live Demos](https://tsdatagrid.com/examples)
|
|
1261
|
+
- [API Reference](https://tsdatagrid.com/api)
|
|
1262
|
+
- [Changelog](CHANGELOG.md)
|
|
1263
|
+
- [Contributing Guide](CONTRIBUTING.md)
|
|
1264
|
+
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
1265
|
+
|
|
1266
|
+
---
|
|
1267
|
+
|
|
1268
|
+
<div align="center">
|
|
1269
|
+
Made with β€οΈ by the TSDataGrid Team
|
|
1270
|
+
β Star us on GitHub β it helps!
|
|
1271
|
+
β¬ back to top
|
|
1272
|
+
</div>
|