@beeblock/svelar-datatable 0.1.6 → 0.1.8
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/package.json +5 -1
- package/src/export/ExportManager.ts +30 -0
- package/src/export/clipboard.ts +14 -0
- package/src/export/csv.ts +36 -0
- package/src/export/excel.ts +44 -0
- package/src/export/index.ts +6 -0
- package/src/export/pdf.ts +9 -0
- package/src/export/print.ts +42 -0
- package/src/index.ts +22 -0
- package/src/state/DataTableStore.ts +599 -0
- package/src/state/ServerDataTableStore.ts +168 -0
- package/src/state/index.ts +2 -0
- package/src/types.ts +241 -0
- package/src/ui/DataTable.svelte +3 -3
- package/src/ui/DataTableBody.svelte +1 -1
- package/src/ui/DataTableBubbleEditor.svelte +1 -1
- package/src/ui/DataTableButtons.svelte +2 -2
- package/src/ui/DataTableCell.svelte +1 -1
- package/src/ui/DataTableColumnToggle.svelte +1 -1
- package/src/ui/DataTableEditor.svelte +1 -1
- package/src/ui/DataTableEditorField.svelte +1 -1
- package/src/ui/DataTableEditorForm.svelte +1 -1
- package/src/ui/DataTableFooter.svelte +1 -1
- package/src/ui/DataTableHead.svelte +1 -1
- package/src/ui/DataTableModalEditor.svelte +1 -1
- package/src/ui/DataTablePagination.svelte +1 -1
- package/src/ui/DataTableRow.svelte +1 -1
- package/src/ui/DataTableSearch.svelte +1 -1
- package/src/ui/DataTableToolbar.svelte +1 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { DataTableConfig, DataTableRequest, DataTableResponse, DataTableState, FilterState, SortState } from '../types.js';
|
|
2
|
+
import { DataTableStore } from './DataTableStore.js';
|
|
3
|
+
|
|
4
|
+
function getCsrfToken(cookieName = 'XSRF-TOKEN'): string | null {
|
|
5
|
+
if (typeof document === 'undefined') return null;
|
|
6
|
+
const escaped = cookieName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
7
|
+
const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${escaped}=([^;]*)`));
|
|
8
|
+
return match ? decodeURIComponent(match[1]) : null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class ServerDataTableStore<T = any> extends DataTableStore<T> {
|
|
12
|
+
private _serverUrl: string;
|
|
13
|
+
private _serverMethod: 'GET' | 'POST';
|
|
14
|
+
private _drawCounter = 0;
|
|
15
|
+
private _abortController: AbortController | null = null;
|
|
16
|
+
private _fetchDebounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
17
|
+
private _serverColumns: { data: string; name: string; searchable: boolean; orderable: boolean }[];
|
|
18
|
+
private _csrfCookieName: string;
|
|
19
|
+
private _csrfHeaderName: string;
|
|
20
|
+
|
|
21
|
+
constructor(config: DataTableConfig<T>) {
|
|
22
|
+
super(config);
|
|
23
|
+
this._serverUrl = config.serverUrl!;
|
|
24
|
+
this._serverMethod = config.serverMethod ?? 'GET';
|
|
25
|
+
this._csrfCookieName = config.csrfCookieName ?? 'XSRF-TOKEN';
|
|
26
|
+
this._csrfHeaderName = config.csrfHeaderName ?? 'X-CSRF-Token';
|
|
27
|
+
this._serverColumns = config.columns.map((c) => ({
|
|
28
|
+
data: c.key,
|
|
29
|
+
name: c.key,
|
|
30
|
+
searchable: c.searchable !== false,
|
|
31
|
+
orderable: c.sortable !== false,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private _buildHeaders(extra: Record<string, string> = {}): Record<string, string> {
|
|
36
|
+
const headers: Record<string, string> = { ...extra };
|
|
37
|
+
const token = getCsrfToken(this._csrfCookieName);
|
|
38
|
+
if (token) {
|
|
39
|
+
headers[this._csrfHeaderName] = token;
|
|
40
|
+
}
|
|
41
|
+
return headers;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override setSort(sort: SortState[]) {
|
|
45
|
+
const state = this.getState();
|
|
46
|
+
// Update sort in state without recomputing locally
|
|
47
|
+
(this as any)._state = { ...state, sort, pagination: { ...state.pagination, page: 1 } };
|
|
48
|
+
this._debouncedFetch();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
override setGlobalSearch(search: string) {
|
|
52
|
+
const state = this.getState();
|
|
53
|
+
(this as any)._state = { ...state, globalSearch: search, pagination: { ...state.pagination, page: 1 } };
|
|
54
|
+
this._debouncedFetch();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
override setFilters(filters: FilterState[]) {
|
|
58
|
+
const state = this.getState();
|
|
59
|
+
(this as any)._state = { ...state, filters, pagination: { ...state.pagination, page: 1 } };
|
|
60
|
+
this._debouncedFetch();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override setPage(page: number) {
|
|
64
|
+
const state = this.getState();
|
|
65
|
+
(this as any)._state = { ...state, pagination: { ...state.pagination, page } };
|
|
66
|
+
this._fetchFromServer();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
override setPerPage(perPage: number) {
|
|
70
|
+
const state = this.getState();
|
|
71
|
+
(this as any)._state = { ...state, pagination: { ...state.pagination, perPage, page: 1 } };
|
|
72
|
+
this._fetchFromServer();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private _debouncedFetch() {
|
|
76
|
+
if (this._fetchDebounceTimer) clearTimeout(this._fetchDebounceTimer);
|
|
77
|
+
this._fetchDebounceTimer = setTimeout(() => this._fetchFromServer(), 300);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async _fetchFromServer() {
|
|
81
|
+
if (this._abortController) this._abortController.abort();
|
|
82
|
+
this._abortController = new AbortController();
|
|
83
|
+
|
|
84
|
+
const state = this.getState();
|
|
85
|
+
this.setLoading(true);
|
|
86
|
+
this.setError(null);
|
|
87
|
+
|
|
88
|
+
const draw = ++this._drawCounter;
|
|
89
|
+
const request: DataTableRequest = {
|
|
90
|
+
draw,
|
|
91
|
+
start: (state.pagination.page - 1) * state.pagination.perPage,
|
|
92
|
+
length: state.pagination.perPage,
|
|
93
|
+
search: { value: state.globalSearch, regex: false },
|
|
94
|
+
order: state.sort.map((s) => ({
|
|
95
|
+
column: this._serverColumns.findIndex((c) => c.data === s.column),
|
|
96
|
+
dir: s.direction,
|
|
97
|
+
})),
|
|
98
|
+
columns: this._serverColumns.map((col) => ({
|
|
99
|
+
...col,
|
|
100
|
+
search: {
|
|
101
|
+
value: state.filters.find((f) => f.column === col.data)?.value ?? '',
|
|
102
|
+
regex: false,
|
|
103
|
+
},
|
|
104
|
+
})),
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
let response: Response;
|
|
109
|
+
|
|
110
|
+
if (this._serverMethod === 'POST') {
|
|
111
|
+
response = await fetch(this._serverUrl, {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
headers: this._buildHeaders({ 'Content-Type': 'application/json' }),
|
|
114
|
+
body: JSON.stringify(request),
|
|
115
|
+
signal: this._abortController.signal,
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
const params = new URLSearchParams();
|
|
119
|
+
params.set('draw', String(request.draw));
|
|
120
|
+
params.set('start', String(request.start));
|
|
121
|
+
params.set('length', String(request.length));
|
|
122
|
+
params.set('search[value]', request.search.value);
|
|
123
|
+
params.set('search[regex]', String(request.search.regex));
|
|
124
|
+
|
|
125
|
+
request.order.forEach((o, i) => {
|
|
126
|
+
params.set(`order[${i}][column]`, String(o.column));
|
|
127
|
+
params.set(`order[${i}][dir]`, o.dir);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
request.columns.forEach((c, i) => {
|
|
131
|
+
params.set(`columns[${i}][data]`, c.data);
|
|
132
|
+
params.set(`columns[${i}][name]`, c.name);
|
|
133
|
+
params.set(`columns[${i}][searchable]`, String(c.searchable));
|
|
134
|
+
params.set(`columns[${i}][orderable]`, String(c.orderable));
|
|
135
|
+
params.set(`columns[${i}][search][value]`, c.search.value);
|
|
136
|
+
params.set(`columns[${i}][search][regex]`, String(c.search.regex));
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const url = `${this._serverUrl}?${params.toString()}`;
|
|
140
|
+
response = await fetch(url, { signal: this._abortController.signal });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
throw new Error(`Server responded with ${response.status}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const json: DataTableResponse<T> = await response.json();
|
|
148
|
+
|
|
149
|
+
// Only accept if this is the latest draw
|
|
150
|
+
if (json.draw === draw) {
|
|
151
|
+
this.setServerResponse(json);
|
|
152
|
+
}
|
|
153
|
+
} catch (err: any) {
|
|
154
|
+
if (err.name === 'AbortError') return;
|
|
155
|
+
this.setLoading(false);
|
|
156
|
+
this.setError(err.message ?? 'Failed to fetch data');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async initialFetch() {
|
|
161
|
+
await this._fetchFromServer();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
destroy() {
|
|
165
|
+
if (this._abortController) this._abortController.abort();
|
|
166
|
+
if (this._fetchDebounceTimer) clearTimeout(this._fetchDebounceTimer);
|
|
167
|
+
}
|
|
168
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import type { Component } from 'svelte';
|
|
2
|
+
|
|
3
|
+
// Column definition
|
|
4
|
+
export type ColumnType = 'string' | 'number' | 'date' | 'boolean' | 'html' | 'custom';
|
|
5
|
+
export type FilterOperator = '=' | '!=' | '>' | '<' | '>=' | '<=' | 'like' | 'not_like' | 'in' | 'between' | 'null' | 'not_null';
|
|
6
|
+
export type SelectionMode = 'none' | 'single' | 'multi';
|
|
7
|
+
export type EditorMode = 'inline' | 'bubble' | 'modal' | 'excel';
|
|
8
|
+
export type FieldType = 'text' | 'textarea' | 'number' | 'select' | 'multi-select' | 'checkbox' | 'radio' | 'date' | 'datetime' | 'upload' | 'hidden' | 'readonly';
|
|
9
|
+
export type ExportFormat = 'csv' | 'excel' | 'pdf' | 'clipboard' | 'print';
|
|
10
|
+
|
|
11
|
+
export interface ColumnDef<T = any> {
|
|
12
|
+
key: string;
|
|
13
|
+
header: string;
|
|
14
|
+
type?: ColumnType;
|
|
15
|
+
sortable?: boolean;
|
|
16
|
+
searchable?: boolean;
|
|
17
|
+
filterable?: boolean;
|
|
18
|
+
visible?: boolean;
|
|
19
|
+
width?: string;
|
|
20
|
+
minWidth?: string;
|
|
21
|
+
maxWidth?: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
headerClassName?: string;
|
|
24
|
+
orderable?: boolean;
|
|
25
|
+
defaultSort?: 'asc' | 'desc';
|
|
26
|
+
// Footer
|
|
27
|
+
footer?: string | ((rows: T[]) => string | number);
|
|
28
|
+
// Editor
|
|
29
|
+
editable?: boolean;
|
|
30
|
+
editorField?: EditorFieldDef;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface SortState {
|
|
34
|
+
column: string;
|
|
35
|
+
direction: 'asc' | 'desc';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface FilterState {
|
|
39
|
+
column: string;
|
|
40
|
+
value: any;
|
|
41
|
+
operator: FilterOperator;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface PaginationState {
|
|
45
|
+
page: number;
|
|
46
|
+
perPage: number;
|
|
47
|
+
total: number;
|
|
48
|
+
lastPage: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Server-side protocol (compatible with jQuery DataTables wire protocol)
|
|
52
|
+
export interface DataTableRequest {
|
|
53
|
+
draw: number;
|
|
54
|
+
start: number;
|
|
55
|
+
length: number;
|
|
56
|
+
search: { value: string; regex: boolean };
|
|
57
|
+
order: { column: number; dir: 'asc' | 'desc' }[];
|
|
58
|
+
columns: {
|
|
59
|
+
data: string;
|
|
60
|
+
name: string;
|
|
61
|
+
searchable: boolean;
|
|
62
|
+
orderable: boolean;
|
|
63
|
+
search: { value: string; regex: boolean };
|
|
64
|
+
}[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface DataTableResponse<T = any> {
|
|
68
|
+
draw: number;
|
|
69
|
+
recordsTotal: number;
|
|
70
|
+
recordsFiltered: number;
|
|
71
|
+
data: T[];
|
|
72
|
+
error?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Editor
|
|
76
|
+
export interface EditorFieldDef {
|
|
77
|
+
name: string;
|
|
78
|
+
type: FieldType;
|
|
79
|
+
label: string;
|
|
80
|
+
placeholder?: string;
|
|
81
|
+
options?: { label: string; value: any }[];
|
|
82
|
+
multiple?: boolean;
|
|
83
|
+
required?: boolean;
|
|
84
|
+
disabled?: boolean;
|
|
85
|
+
className?: string;
|
|
86
|
+
dependsOn?: string;
|
|
87
|
+
dependsOnValue?: any;
|
|
88
|
+
showWhen?: (formData: Record<string, any>) => boolean;
|
|
89
|
+
defaultValue?: any;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Buttons
|
|
93
|
+
export interface ButtonDef {
|
|
94
|
+
key: string;
|
|
95
|
+
label: string;
|
|
96
|
+
icon?: Component<any>;
|
|
97
|
+
action?: string | ((selectedRows: any[], allData: any[]) => void | Promise<void>);
|
|
98
|
+
variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost';
|
|
99
|
+
disabled?: boolean | ((selectedRows: any[]) => boolean);
|
|
100
|
+
collection?: ButtonDef[];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// CSS class overrides for full Tailwind customization
|
|
104
|
+
export interface DataTableClassNames {
|
|
105
|
+
container?: string;
|
|
106
|
+
toolbar?: string;
|
|
107
|
+
toolbarLeft?: string;
|
|
108
|
+
toolbarRight?: string;
|
|
109
|
+
searchInput?: string;
|
|
110
|
+
table?: string;
|
|
111
|
+
thead?: string;
|
|
112
|
+
th?: string;
|
|
113
|
+
thSortable?: string;
|
|
114
|
+
tbody?: string;
|
|
115
|
+
tr?: string;
|
|
116
|
+
trSelected?: string;
|
|
117
|
+
trEven?: string;
|
|
118
|
+
td?: string;
|
|
119
|
+
tfoot?: string;
|
|
120
|
+
tf?: string;
|
|
121
|
+
pagination?: string;
|
|
122
|
+
paginationInfo?: string;
|
|
123
|
+
paginationControls?: string;
|
|
124
|
+
pageButton?: string;
|
|
125
|
+
pageButtonActive?: string;
|
|
126
|
+
perPageSelect?: string;
|
|
127
|
+
btn?: string;
|
|
128
|
+
btnCreate?: string;
|
|
129
|
+
btnEdit?: string;
|
|
130
|
+
btnDelete?: string;
|
|
131
|
+
editorModal?: string;
|
|
132
|
+
editorBackdrop?: string;
|
|
133
|
+
editorField?: string;
|
|
134
|
+
editorInput?: string;
|
|
135
|
+
editorLabel?: string;
|
|
136
|
+
loading?: string;
|
|
137
|
+
empty?: string;
|
|
138
|
+
error?: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Full config
|
|
142
|
+
export interface DataTableConfig<T = any> {
|
|
143
|
+
// Data source
|
|
144
|
+
data?: T[];
|
|
145
|
+
serverUrl?: string;
|
|
146
|
+
serverMethod?: 'GET' | 'POST';
|
|
147
|
+
// CSRF token config (defaults to Svelar conventions)
|
|
148
|
+
csrfCookieName?: string;
|
|
149
|
+
csrfHeaderName?: string;
|
|
150
|
+
// Columns
|
|
151
|
+
columns: ColumnDef<T>[];
|
|
152
|
+
// Features
|
|
153
|
+
sortable?: boolean;
|
|
154
|
+
searchable?: boolean;
|
|
155
|
+
paginate?: boolean;
|
|
156
|
+
selectable?: SelectionMode;
|
|
157
|
+
// Pagination
|
|
158
|
+
perPage?: number;
|
|
159
|
+
perPageOptions?: number[];
|
|
160
|
+
// Search
|
|
161
|
+
searchDebounceMs?: number;
|
|
162
|
+
// State
|
|
163
|
+
stateSaveKey?: string;
|
|
164
|
+
// Row identity
|
|
165
|
+
rowId?: string | ((row: T) => string | number);
|
|
166
|
+
// Row classes
|
|
167
|
+
rowClass?: string | ((row: T, index: number) => string);
|
|
168
|
+
// Buttons
|
|
169
|
+
buttons?: (ButtonDef | ExportFormat)[];
|
|
170
|
+
// Editor
|
|
171
|
+
editorMode?: EditorMode;
|
|
172
|
+
editorFields?: EditorFieldDef[];
|
|
173
|
+
// Callbacks
|
|
174
|
+
onSort?: (sort: SortState[]) => void;
|
|
175
|
+
onFilter?: (filters: FilterState[]) => void;
|
|
176
|
+
onPageChange?: (page: number, perPage: number) => void;
|
|
177
|
+
onSelect?: (selectedRows: T[]) => void;
|
|
178
|
+
onRowClick?: (row: T, event: MouseEvent) => void;
|
|
179
|
+
onEdit?: (row: T, data: Record<string, any>) => void | Promise<void>;
|
|
180
|
+
onCellEdit?: (row: T, columnKey: string, newValue: any, oldValue: any) => void | Promise<void>;
|
|
181
|
+
onCreate?: (data: Record<string, any>) => void | Promise<void>;
|
|
182
|
+
onDelete?: (rows: T[]) => void | Promise<void>;
|
|
183
|
+
// Virtual scroll
|
|
184
|
+
virtualScroll?: boolean;
|
|
185
|
+
virtualRowHeight?: number;
|
|
186
|
+
// Responsive
|
|
187
|
+
responsive?: boolean;
|
|
188
|
+
// Row grouping
|
|
189
|
+
groupBy?: string;
|
|
190
|
+
// Detail/child rows
|
|
191
|
+
expandable?: boolean;
|
|
192
|
+
// Empty state
|
|
193
|
+
emptyText?: string;
|
|
194
|
+
// Loading
|
|
195
|
+
loadingText?: string;
|
|
196
|
+
// CSS
|
|
197
|
+
className?: string;
|
|
198
|
+
compact?: boolean;
|
|
199
|
+
striped?: boolean;
|
|
200
|
+
hover?: boolean;
|
|
201
|
+
bordered?: boolean;
|
|
202
|
+
// Tailwind / custom class overrides
|
|
203
|
+
classNames?: DataTableClassNames;
|
|
204
|
+
// Unstyled mode — disables all built-in CSS
|
|
205
|
+
unstyled?: boolean;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Store state shape
|
|
209
|
+
export interface DataTableState<T = any> {
|
|
210
|
+
// Source data
|
|
211
|
+
allRows: T[];
|
|
212
|
+
// Derived
|
|
213
|
+
filteredRows: T[];
|
|
214
|
+
sortedRows: T[];
|
|
215
|
+
paginatedRows: T[];
|
|
216
|
+
// State
|
|
217
|
+
sort: SortState[];
|
|
218
|
+
filters: FilterState[];
|
|
219
|
+
globalSearch: string;
|
|
220
|
+
pagination: PaginationState;
|
|
221
|
+
// Selection
|
|
222
|
+
selectedIds: Set<string | number>;
|
|
223
|
+
// Column state
|
|
224
|
+
columnVisibility: Record<string, boolean>;
|
|
225
|
+
columnOrder: string[];
|
|
226
|
+
// Loading
|
|
227
|
+
loading: boolean;
|
|
228
|
+
error: string | null;
|
|
229
|
+
// Editor
|
|
230
|
+
editingRowId: string | number | null;
|
|
231
|
+
editingColumn: string | null;
|
|
232
|
+
editorMode: EditorMode | null;
|
|
233
|
+
formData: Record<string, any>;
|
|
234
|
+
validationErrors: Record<string, string>;
|
|
235
|
+
// Server draw
|
|
236
|
+
draw: number;
|
|
237
|
+
// Excel mode
|
|
238
|
+
excelFocusedCell: { rowIndex: number; columnKey: string } | null;
|
|
239
|
+
excelEditingCell: { rowIndex: number; columnKey: string } | null;
|
|
240
|
+
excelEditValue: string;
|
|
241
|
+
}
|
package/src/ui/DataTable.svelte
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { DataTableConfig, DataTableClassNames, ColumnDef, EditorFieldDef } from '../types.
|
|
4
|
-
import { DataTableStore } from '../state/DataTableStore.
|
|
5
|
-
import { ServerDataTableStore } from '../state/ServerDataTableStore.
|
|
3
|
+
import type { DataTableConfig, DataTableClassNames, ColumnDef, EditorFieldDef } from '../types.ts';
|
|
4
|
+
import { DataTableStore } from '../state/DataTableStore.ts';
|
|
5
|
+
import { ServerDataTableStore } from '../state/ServerDataTableStore.ts';
|
|
6
6
|
import DataTableToolbar from './DataTableToolbar.svelte';
|
|
7
7
|
import DataTableHead from './DataTableHead.svelte';
|
|
8
8
|
import DataTableBody from './DataTableBody.svelte';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { ColumnDef, DataTableStore, SelectionMode, EditorMode, DataTableClassNames } from '../index.
|
|
2
|
+
import type { ColumnDef, DataTableStore, SelectionMode, EditorMode, DataTableClassNames } from '../index.ts';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
4
|
import DataTableRow from './DataTableRow.svelte';
|
|
5
5
|
import DataTableLoading from './DataTableLoading.svelte';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { EditorFieldDef, DataTableStore, DataTableClassNames } from '../index.
|
|
2
|
+
import type { EditorFieldDef, DataTableStore, DataTableClassNames } from '../index.ts';
|
|
3
3
|
import DataTableEditorForm from './DataTableEditorForm.svelte';
|
|
4
4
|
import { tick } from 'svelte';
|
|
5
5
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { ButtonDef, ExportFormat, DataTableStore, ColumnDef } from '../index.
|
|
3
|
-
import { ExportManager } from '../export/ExportManager.
|
|
2
|
+
import type { ButtonDef, ExportFormat, DataTableStore, ColumnDef } from '../index.ts';
|
|
3
|
+
import { ExportManager } from '../export/ExportManager.ts';
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
buttons: (ButtonDef | ExportFormat)[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { EditorFieldDef, DataTableStore, DataTableClassNames } from '../index.
|
|
2
|
+
import type { EditorFieldDef, DataTableStore, DataTableClassNames } from '../index.ts';
|
|
3
3
|
import DataTableModalEditor from './DataTableModalEditor.svelte';
|
|
4
4
|
import DataTableBubbleEditor from './DataTableBubbleEditor.svelte';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { EditorFieldDef, DataTableStore, DataTableClassNames } from '../index.
|
|
2
|
+
import type { EditorFieldDef, DataTableStore, DataTableClassNames } from '../index.ts';
|
|
3
3
|
import DataTableEditorForm from './DataTableEditorForm.svelte';
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { ColumnDef, DataTableStore, SelectionMode, EditorMode, DataTableClassNames } from '../index.
|
|
2
|
+
import type { ColumnDef, DataTableStore, SelectionMode, EditorMode, DataTableClassNames } from '../index.ts';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
4
|
import DataTableCell from './DataTableCell.svelte';
|
|
5
5
|
import DataTableExpandedRow from './DataTableExpandedRow.svelte';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { ColumnDef, ButtonDef, ExportFormat, DataTableStore, EditorMode, DataTableClassNames } from '../index.
|
|
2
|
+
import type { ColumnDef, ButtonDef, ExportFormat, DataTableStore, EditorMode, DataTableClassNames } from '../index.ts';
|
|
3
3
|
import DataTableSearch from './DataTableSearch.svelte';
|
|
4
4
|
import DataTableColumnToggle from './DataTableColumnToggle.svelte';
|
|
5
5
|
import DataTableButtons from './DataTableButtons.svelte';
|