@vueye-table/headless 3.0.0-beta.1 → 3.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +116 -62
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +144 -57
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { injectDataGrid, injectDataTable, provideDataGrid, provideDataTable, useDataGrid, useVirtualColumns, useVirtualRows } from "@vueye-table/vue";
|
|
2
|
-
import { Fragment, computed, defineComponent, h, inject, nextTick, onMounted, onScopeDispose, provide, ref, shallowRef, useId, watch } from "vue";
|
|
1
|
+
import { injectDataGrid, injectDataTable, provideDataGrid, provideDataTable, useDataGrid, useTableLocale, useVirtualColumns, useVirtualRows } from "@vueye-table/vue";
|
|
2
|
+
import { Fragment, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, onScopeDispose, provide, ref, shallowRef, useId, watch } from "vue";
|
|
3
3
|
import { formatValue, getRowItemKey, gridCommand } from "@vueye-table/core";
|
|
4
4
|
|
|
5
5
|
//#region src/shared.ts
|
|
@@ -32,6 +32,13 @@ const rowProp = {
|
|
|
32
32
|
function flag(value) {
|
|
33
33
|
return value ? "" : void 0;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* The direction an element is laid out in, read from the nearest `dir` attribute, so keyboard
|
|
37
|
+
* arrows can follow what the reader sees. Without one, left to right.
|
|
38
|
+
*/
|
|
39
|
+
function directionOf(element) {
|
|
40
|
+
return element?.closest("[dir]")?.getAttribute("dir")?.toLowerCase() === "rtl" ? "rtl" : "ltr";
|
|
41
|
+
}
|
|
35
42
|
|
|
36
43
|
//#endregion
|
|
37
44
|
//#region src/controls.ts
|
|
@@ -55,10 +62,11 @@ const DataTableSelectAll = defineComponent({
|
|
|
55
62
|
slots: Object,
|
|
56
63
|
props: { label: {
|
|
57
64
|
type: String,
|
|
58
|
-
default:
|
|
65
|
+
default: void 0
|
|
59
66
|
} },
|
|
60
67
|
setup(props, { slots }) {
|
|
61
68
|
const table = injectDataTable("<DataTableSelectAll>");
|
|
69
|
+
const locale = useTableLocale();
|
|
62
70
|
return () => {
|
|
63
71
|
const state = table.allSelection;
|
|
64
72
|
const toggle = () => table.toggleAll();
|
|
@@ -68,7 +76,7 @@ const DataTableSelectAll = defineComponent({
|
|
|
68
76
|
}) ?? checkbox({
|
|
69
77
|
checked: state === "all",
|
|
70
78
|
indeterminate: state === "some",
|
|
71
|
-
label: props.label,
|
|
79
|
+
label: props.label ?? locale().messages.selectAllRows,
|
|
72
80
|
disabled: table.selectionMode !== "multiple" || table.rows.length === 0,
|
|
73
81
|
onChange: toggle
|
|
74
82
|
});
|
|
@@ -81,13 +89,19 @@ const DataTableSelectRow = defineComponent({
|
|
|
81
89
|
slots: Object,
|
|
82
90
|
props: {
|
|
83
91
|
row: rowProp,
|
|
92
|
+
/** Defaults to the locale's "Select row 3", the row's place in the table as shown. */
|
|
84
93
|
label: {
|
|
85
94
|
type: String,
|
|
86
|
-
default:
|
|
95
|
+
default: void 0
|
|
87
96
|
}
|
|
88
97
|
},
|
|
89
98
|
setup(props, { slots }) {
|
|
90
99
|
const table = injectDataTable("<DataTableSelectRow>");
|
|
100
|
+
const locale = useTableLocale();
|
|
101
|
+
const position = () => {
|
|
102
|
+
const index = table.rows.indexOf(props.row);
|
|
103
|
+
return index < 0 ? props.row.index + 1 : Math.max(1, table.pageStart) + index;
|
|
104
|
+
};
|
|
91
105
|
return () => {
|
|
92
106
|
const selected = table.tree ? props.row.selection === "all" : table.isSelected(props.row.key);
|
|
93
107
|
const indeterminate = table.tree && props.row.selection === "some";
|
|
@@ -99,7 +113,7 @@ const DataTableSelectRow = defineComponent({
|
|
|
99
113
|
}) ?? checkbox({
|
|
100
114
|
checked: selected,
|
|
101
115
|
indeterminate,
|
|
102
|
-
label: props.label,
|
|
116
|
+
label: props.label ?? locale().messages.selectRow({ position: locale().count(position()) }),
|
|
103
117
|
disabled: table.selectionMode === "none",
|
|
104
118
|
onChange: toggle
|
|
105
119
|
});
|
|
@@ -119,7 +133,7 @@ const DataTableSearch = defineComponent({
|
|
|
119
133
|
},
|
|
120
134
|
label: {
|
|
121
135
|
type: String,
|
|
122
|
-
default:
|
|
136
|
+
default: void 0
|
|
123
137
|
},
|
|
124
138
|
placeholder: {
|
|
125
139
|
type: String,
|
|
@@ -128,13 +142,14 @@ const DataTableSearch = defineComponent({
|
|
|
128
142
|
},
|
|
129
143
|
setup(props) {
|
|
130
144
|
const table = injectDataTable("<DataTableSearch>");
|
|
145
|
+
const locale = useTableLocale();
|
|
131
146
|
let timer;
|
|
132
147
|
onScopeDispose(() => clearTimeout(timer));
|
|
133
148
|
return () => h("input", {
|
|
134
149
|
type: "search",
|
|
135
150
|
value: table.state.search,
|
|
136
151
|
placeholder: props.placeholder,
|
|
137
|
-
"aria-label": props.label,
|
|
152
|
+
"aria-label": props.label ?? locale().messages.search,
|
|
138
153
|
onInput: (event) => {
|
|
139
154
|
const { value } = event.target;
|
|
140
155
|
clearTimeout(timer);
|
|
@@ -155,12 +170,14 @@ const DataTablePagination = defineComponent({
|
|
|
155
170
|
as: asProp("nav"),
|
|
156
171
|
label: {
|
|
157
172
|
type: String,
|
|
158
|
-
default:
|
|
173
|
+
default: void 0
|
|
159
174
|
}
|
|
160
175
|
},
|
|
161
176
|
setup(props, { slots }) {
|
|
162
177
|
const table = injectDataTable("<DataTablePagination>");
|
|
178
|
+
const locale = useTableLocale();
|
|
163
179
|
return () => {
|
|
180
|
+
const { messages, count } = locale();
|
|
164
181
|
const slotProps = {
|
|
165
182
|
page: table.page,
|
|
166
183
|
pageCount: table.pageCount,
|
|
@@ -179,14 +196,14 @@ const DataTablePagination = defineComponent({
|
|
|
179
196
|
"data-current": flag(current),
|
|
180
197
|
onClick
|
|
181
198
|
}, content);
|
|
182
|
-
return h(props.as, { "aria-label": props.label }, slots.default?.(slotProps) ?? [
|
|
183
|
-
button(
|
|
199
|
+
return h(props.as, { "aria-label": props.label ?? messages.pagination }, slots.default?.(slotProps) ?? [
|
|
200
|
+
button(messages.previousPage, "‹", !table.canPreviousPage, table.previousPage),
|
|
184
201
|
...table.pageItems.map((item) => item.type === "gap" ? h("span", {
|
|
185
202
|
key: item.key,
|
|
186
203
|
"aria-hidden": "true",
|
|
187
204
|
"data-gap": ""
|
|
188
|
-
}, "…") : button(
|
|
189
|
-
button(
|
|
205
|
+
}, "…") : button(messages.page(count(item.page)), count(item.page).text, false, () => table.goToPage(item.page), item.current)),
|
|
206
|
+
button(messages.nextPage, "›", !table.canNextPage, table.nextPage)
|
|
190
207
|
]);
|
|
191
208
|
};
|
|
192
209
|
}
|
|
@@ -206,22 +223,23 @@ const DataTablePageSize = defineComponent({
|
|
|
206
223
|
},
|
|
207
224
|
label: {
|
|
208
225
|
type: String,
|
|
209
|
-
default:
|
|
226
|
+
default: void 0
|
|
210
227
|
}
|
|
211
228
|
},
|
|
212
229
|
setup(props) {
|
|
213
230
|
const table = injectDataTable("<DataTablePageSize>");
|
|
231
|
+
const locale = useTableLocale();
|
|
214
232
|
return () => {
|
|
215
233
|
const sizes = props.options.includes(table.pageSize) ? props.options : [...props.options, table.pageSize].toSorted((left, right) => left - right);
|
|
216
234
|
return h("select", {
|
|
217
235
|
value: table.pageSize,
|
|
218
|
-
"aria-label": props.label,
|
|
236
|
+
"aria-label": props.label ?? locale().messages.rowsPerPage,
|
|
219
237
|
onChange: (event) => table.setPageSize(Number(event.target.value))
|
|
220
238
|
}, sizes.map((size) => h("option", {
|
|
221
239
|
key: size,
|
|
222
240
|
value: size,
|
|
223
241
|
selected: size === table.pageSize
|
|
224
|
-
},
|
|
242
|
+
}, locale().count(size).text)));
|
|
225
243
|
};
|
|
226
244
|
}
|
|
227
245
|
});
|
|
@@ -233,11 +251,12 @@ const DataTableColumnVisibility = defineComponent({
|
|
|
233
251
|
as: asProp("fieldset"),
|
|
234
252
|
legend: {
|
|
235
253
|
type: String,
|
|
236
|
-
default:
|
|
254
|
+
default: void 0
|
|
237
255
|
}
|
|
238
256
|
},
|
|
239
257
|
setup(props, { slots }) {
|
|
240
258
|
const table = injectDataTable("<DataTableColumnVisibility>");
|
|
259
|
+
const locale = useTableLocale();
|
|
241
260
|
return () => {
|
|
242
261
|
const hidden = new Set(table.state.hiddenColumns);
|
|
243
262
|
const columns = table.allColumns.map((column) => ({
|
|
@@ -247,7 +266,7 @@ const DataTableColumnVisibility = defineComponent({
|
|
|
247
266
|
return h(props.as, slots.default?.({
|
|
248
267
|
columns,
|
|
249
268
|
toggle: table.toggleColumn
|
|
250
|
-
}) ?? [props.as === "fieldset" ? h("legend", props.legend) : null, ...columns.map(({ column, visible }) => h("label", {
|
|
269
|
+
}) ?? [props.as === "fieldset" ? h("legend", props.legend ?? locale().messages.columns) : null, ...columns.map(({ column, visible }) => h("label", {
|
|
251
270
|
key: column.id,
|
|
252
271
|
"data-column": column.id
|
|
253
272
|
}, [h("input", {
|
|
@@ -265,7 +284,9 @@ const DataTableStatus = defineComponent({
|
|
|
265
284
|
props: { as: asProp("p") },
|
|
266
285
|
setup(props, { slots }) {
|
|
267
286
|
const table = injectDataTable("<DataTableStatus>");
|
|
287
|
+
const locale = useTableLocale();
|
|
268
288
|
return () => {
|
|
289
|
+
const { messages, count } = locale();
|
|
269
290
|
const slotProps = {
|
|
270
291
|
start: table.pageStart,
|
|
271
292
|
end: table.pageEnd,
|
|
@@ -281,12 +302,23 @@ const DataTableStatus = defineComponent({
|
|
|
281
302
|
loadingChildrenCount: table.tree ? table.processedRows.filter((row) => row.childStatus === "loading").length : 0,
|
|
282
303
|
childErrorCount: table.tree ? table.processedRows.filter((row) => row.childStatus === "error").length : 0
|
|
283
304
|
};
|
|
284
|
-
const
|
|
285
|
-
|
|
305
|
+
const text = table.loadingMode ? messages.loadedStatus({
|
|
306
|
+
loaded: count(table.loadedRowCount),
|
|
307
|
+
state: table.loadState
|
|
308
|
+
}) : table.rowCount === 0 ? messages.noRows : messages.rangeStatus({
|
|
309
|
+
start: count(table.pageStart),
|
|
310
|
+
end: count(table.pageEnd),
|
|
311
|
+
total: count(table.rowCount),
|
|
312
|
+
selected: count(table.selectedCount)
|
|
313
|
+
});
|
|
286
314
|
return h(props.as, {
|
|
287
315
|
role: "status",
|
|
288
316
|
"aria-live": "polite"
|
|
289
|
-
}, slots.default?.(slotProps) ??
|
|
317
|
+
}, slots.default?.(slotProps) ?? [
|
|
318
|
+
text,
|
|
319
|
+
slotProps.loadingChildrenCount ? messages.loadingChildren : "",
|
|
320
|
+
slotProps.childErrorCount ? messages.childrenError : ""
|
|
321
|
+
].filter((part) => part !== "").join(" "));
|
|
290
322
|
};
|
|
291
323
|
}
|
|
292
324
|
});
|
|
@@ -294,7 +326,7 @@ const DataTableStatus = defineComponent({
|
|
|
294
326
|
//#endregion
|
|
295
327
|
//#region src/loading.ts
|
|
296
328
|
/** Keep this visual sentinel out of the live region and logical data-row count. */
|
|
297
|
-
function loadSentinel(table, colspan) {
|
|
329
|
+
function loadSentinel(table, colspan, locale) {
|
|
298
330
|
return table.loadingMode === "cursor" && table.loadedRowCount > 0 && (table.loadState === "loading" || table.loadState === "streaming") ? h("tr", {
|
|
299
331
|
key: "vt-load-sentinel",
|
|
300
332
|
"data-load-sentinel": "",
|
|
@@ -302,7 +334,7 @@ function loadSentinel(table, colspan) {
|
|
|
302
334
|
}, [h("td", {
|
|
303
335
|
colspan: Math.max(1, colspan),
|
|
304
336
|
class: "vt-load-sentinel"
|
|
305
|
-
}, "Loading more rows…")]) : void 0;
|
|
337
|
+
}, locale?.messages.loadingMoreRows ?? "Loading more rows…")]) : void 0;
|
|
306
338
|
}
|
|
307
339
|
/** A keyboard-accessible alternative to automatic virtual-end loading, with error recovery. */
|
|
308
340
|
const DataTableLoadMore = defineComponent({
|
|
@@ -310,29 +342,30 @@ const DataTableLoadMore = defineComponent({
|
|
|
310
342
|
props: {
|
|
311
343
|
label: {
|
|
312
344
|
type: String,
|
|
313
|
-
default:
|
|
345
|
+
default: void 0
|
|
314
346
|
},
|
|
315
347
|
retryLabel: {
|
|
316
348
|
type: String,
|
|
317
|
-
default:
|
|
349
|
+
default: void 0
|
|
318
350
|
},
|
|
319
351
|
loadingLabel: {
|
|
320
352
|
type: String,
|
|
321
|
-
default:
|
|
353
|
+
default: void 0
|
|
322
354
|
}
|
|
323
355
|
},
|
|
324
356
|
setup(props) {
|
|
325
357
|
const table = injectDataTable("<DataTableLoadMore>");
|
|
358
|
+
const locale = useTableLocale();
|
|
326
359
|
return () => table.loadState === "error" ? h("button", {
|
|
327
360
|
type: "button",
|
|
328
361
|
onClick: () => table.retry()
|
|
329
|
-
}, props.retryLabel) : table.loadingMode === "cursor" && table.loadState !== "done" ? h("button", {
|
|
362
|
+
}, props.retryLabel ?? locale().messages.retryLoading) : table.loadingMode === "cursor" && table.loadState !== "done" ? h("button", {
|
|
330
363
|
type: "button",
|
|
331
364
|
disabled: !table.canLoadMore,
|
|
332
365
|
onClick: () => {
|
|
333
366
|
table.loadNext();
|
|
334
367
|
}
|
|
335
|
-
}, table.loadState === "loading" || table.loadState === "streaming" ? props.loadingLabel : props.label) : null;
|
|
368
|
+
}, table.loadState === "loading" || table.loadState === "streaming" ? props.loadingLabel ?? locale().messages.loadingRows : props.label ?? locale().messages.loadMoreRows) : null;
|
|
336
369
|
}
|
|
337
370
|
});
|
|
338
371
|
|
|
@@ -375,6 +408,7 @@ const DataCellEditor = defineComponent({
|
|
|
375
408
|
name: "DataCellEditor",
|
|
376
409
|
props: cellEditorProps,
|
|
377
410
|
setup(props) {
|
|
411
|
+
const locale = useTableLocale();
|
|
378
412
|
const field = ref();
|
|
379
413
|
const query = ref("");
|
|
380
414
|
const options = props.spec.options ?? [];
|
|
@@ -418,9 +452,10 @@ const DataCellEditor = defineComponent({
|
|
|
418
452
|
};
|
|
419
453
|
return () => {
|
|
420
454
|
const { editor, spec } = props;
|
|
455
|
+
const { messages, count } = locale();
|
|
421
456
|
const attrs = {
|
|
422
457
|
...editor.attrs,
|
|
423
|
-
"aria-label":
|
|
458
|
+
"aria-label": messages.editCell(editor.column.header),
|
|
424
459
|
"data-editor": "",
|
|
425
460
|
disabled: editor.pending,
|
|
426
461
|
onKeydown: keydown
|
|
@@ -437,7 +472,7 @@ const DataCellEditor = defineComponent({
|
|
|
437
472
|
ref: field,
|
|
438
473
|
type: "search",
|
|
439
474
|
value: query.value,
|
|
440
|
-
"aria-label":
|
|
475
|
+
"aria-label": messages.searchOptions(editor.column.header),
|
|
441
476
|
disabled: editor.pending,
|
|
442
477
|
onInput: (event) => {
|
|
443
478
|
query.value = event.target.value;
|
|
@@ -460,11 +495,11 @@ const DataCellEditor = defineComponent({
|
|
|
460
495
|
}, shown.map(({ value, index }) => h("option", {
|
|
461
496
|
key: index,
|
|
462
497
|
value: index
|
|
463
|
-
},
|
|
498
|
+
}, value === null || value === void 0 ? messages.emptyOption : String(value)))),
|
|
464
499
|
h("span", {
|
|
465
500
|
role: "status",
|
|
466
501
|
"data-editor-hint": ""
|
|
467
|
-
}, matches.value.length === 0 ?
|
|
502
|
+
}, matches.value.length === 0 ? messages.noMatchingOptions : matches.value.length > 50 ? messages.firstMatchesOnly(count(50)) : messages.optionCount(count(matches.value.length)))
|
|
468
503
|
]);
|
|
469
504
|
}
|
|
470
505
|
return h("input", {
|
|
@@ -825,7 +860,14 @@ function treeKeydown(event, context, virtual) {
|
|
|
825
860
|
const index = table.rows.findIndex((row) => getRowItemKey(row.key) === key);
|
|
826
861
|
const row = table.rows[index];
|
|
827
862
|
if (!row) return;
|
|
828
|
-
const command = gridCommand(
|
|
863
|
+
const command = gridCommand({
|
|
864
|
+
key: event.key,
|
|
865
|
+
shiftKey: event.shiftKey,
|
|
866
|
+
ctrlKey: event.ctrlKey,
|
|
867
|
+
metaKey: event.metaKey,
|
|
868
|
+
altKey: event.altKey,
|
|
869
|
+
direction: directionOf(target)
|
|
870
|
+
}, {
|
|
829
871
|
canExpand: row.canExpand,
|
|
830
872
|
expanded: row.isExpanded
|
|
831
873
|
});
|
|
@@ -853,11 +895,11 @@ const expandToggleProps = {
|
|
|
853
895
|
},
|
|
854
896
|
expandLabel: {
|
|
855
897
|
type: String,
|
|
856
|
-
default:
|
|
898
|
+
default: void 0
|
|
857
899
|
},
|
|
858
900
|
collapseLabel: {
|
|
859
901
|
type: String,
|
|
860
|
-
default:
|
|
902
|
+
default: void 0
|
|
861
903
|
}
|
|
862
904
|
};
|
|
863
905
|
const treeCellProps = {
|
|
@@ -872,13 +914,15 @@ const DataTableExpandToggle = defineComponent({
|
|
|
872
914
|
const table = injectDataTable("<DataTableExpandToggle>");
|
|
873
915
|
const context = injectHierarchy();
|
|
874
916
|
const grid = injectDataGrid();
|
|
917
|
+
const locale = useTableLocale();
|
|
918
|
+
const label = () => props.row.isExpanded ? props.collapseLabel ?? locale().messages.collapseRow : props.expandLabel ?? locale().messages.expandRow;
|
|
875
919
|
return () => props.row.canExpand ? h("button", {
|
|
876
920
|
type: "button",
|
|
877
921
|
"data-expand-toggle": "",
|
|
878
922
|
tabindex: table.tree ? -1 : void 0,
|
|
879
923
|
"aria-expanded": String(props.row.isExpanded),
|
|
880
924
|
"aria-controls": props.controls ?? (!table.tree ? itemId(context, props.row, true) : props.row.isExpanded ? table.rows.filter((row) => row.parentKey === props.row.key).map((row) => itemId(context, row)).filter(Boolean).join(" ") || void 0 : void 0),
|
|
881
|
-
"aria-label":
|
|
925
|
+
"aria-label": label(),
|
|
882
926
|
onMousedown: (event) => event.stopPropagation(),
|
|
883
927
|
onDblclick: (event) => event.stopPropagation(),
|
|
884
928
|
onClick: (event) => {
|
|
@@ -893,7 +937,7 @@ const DataTableExpandToggle = defineComponent({
|
|
|
893
937
|
}, slots.default?.({
|
|
894
938
|
row: props.row,
|
|
895
939
|
expanded: props.row.isExpanded
|
|
896
|
-
}) ?? (
|
|
940
|
+
}) ?? label()) : null;
|
|
897
941
|
}
|
|
898
942
|
});
|
|
899
943
|
const DataTableTreeCell = defineComponent({
|
|
@@ -904,6 +948,7 @@ const DataTableTreeCell = defineComponent({
|
|
|
904
948
|
const table = injectDataTable("<DataTableTreeCell>");
|
|
905
949
|
const context = injectHierarchy();
|
|
906
950
|
const grid = injectDataGrid();
|
|
951
|
+
const locale = useTableLocale();
|
|
907
952
|
return () => h(props.as, {
|
|
908
953
|
class: "vt-tree-cell",
|
|
909
954
|
"data-tree-cell": "",
|
|
@@ -911,8 +956,8 @@ const DataTableTreeCell = defineComponent({
|
|
|
911
956
|
}, [
|
|
912
957
|
h("span", { class: "vt-tree-toggle" }, slots.toggle?.({ row: props.row }) ?? h(DataTableExpandToggle, { row: props.row })),
|
|
913
958
|
h("span", { class: "vt-tree-label" }, [slots.default?.()]),
|
|
914
|
-
props.row.childStatus === "loading" ? h("span", { class: "vt-tree-loading" },
|
|
915
|
-
props.row.childStatus === "error" ? h("span", { class: "vt-tree-error" }, [
|
|
959
|
+
props.row.childStatus === "loading" ? h("span", { class: "vt-tree-loading" }, locale().messages.loadingChildren) : null,
|
|
960
|
+
props.row.childStatus === "error" ? h("span", { class: "vt-tree-error" }, [`${locale().messages.childrenError} `, h("button", {
|
|
916
961
|
type: "button",
|
|
917
962
|
class: "vt-tree-retry",
|
|
918
963
|
onMousedown: (event) => event.stopPropagation(),
|
|
@@ -929,7 +974,7 @@ const DataTableTreeCell = defineComponent({
|
|
|
929
974
|
else element?.ownerDocument.getElementById(itemId(context, props.row) ?? "")?.focus();
|
|
930
975
|
});
|
|
931
976
|
}
|
|
932
|
-
},
|
|
977
|
+
}, locale().messages.retryChildren)]) : null
|
|
933
978
|
]);
|
|
934
979
|
}
|
|
935
980
|
});
|
|
@@ -1155,13 +1200,14 @@ const DataTableSortButton = defineComponent({
|
|
|
1155
1200
|
},
|
|
1156
1201
|
setup(props, { slots }) {
|
|
1157
1202
|
const table = injectDataTable("<DataTableSortButton>");
|
|
1203
|
+
const locale = useTableLocale();
|
|
1158
1204
|
return () => {
|
|
1159
1205
|
const sort = table.getSort(props.column.id);
|
|
1160
1206
|
const next = !sort ? "ascending" : sort.direction === "asc" ? "descending" : "unsorted";
|
|
1161
1207
|
return h(props.as, {
|
|
1162
1208
|
type: props.as === "button" ? "button" : void 0,
|
|
1163
1209
|
"data-sort": sort?.direction,
|
|
1164
|
-
"aria-label":
|
|
1210
|
+
"aria-label": locale().messages.sortBy(props.column.header, next),
|
|
1165
1211
|
onClick: (event) => table.toggleSort(props.column.id, { multi: event.shiftKey })
|
|
1166
1212
|
}, [slots.default?.({ sort }) ?? props.column.header, slots.indicator?.({ sort })]);
|
|
1167
1213
|
};
|
|
@@ -1184,6 +1230,7 @@ const DataTableBody = defineComponent({
|
|
|
1184
1230
|
},
|
|
1185
1231
|
setup(props, { slots }) {
|
|
1186
1232
|
const table = injectDataTable("<DataTableBody>");
|
|
1233
|
+
const locale = useTableLocale();
|
|
1187
1234
|
const virtual = injectVirtual();
|
|
1188
1235
|
const details = createDetails(table, () => slots.detail, () => props.colspan ?? table.columns.length);
|
|
1189
1236
|
return () => {
|
|
@@ -1197,7 +1244,7 @@ const DataTableBody = defineComponent({
|
|
|
1197
1244
|
}) : details.render(item.row, item.rowIndex));
|
|
1198
1245
|
const visibleDetails = new Set(table.renderItems.filter((item) => item.kind === "detail").map((item) => item.row.key));
|
|
1199
1246
|
const retained = slots.default ? [] : details.retained(visibleDetails);
|
|
1200
|
-
const sentinel = loadSentinel(table, props.colspan ?? table.columns.length);
|
|
1247
|
+
const sentinel = loadSentinel(table, props.colspan ?? table.columns.length, locale());
|
|
1201
1248
|
return h(props.as, [
|
|
1202
1249
|
...Array.isArray(content) ? content : content ? [content] : [],
|
|
1203
1250
|
...retained,
|
|
@@ -1256,6 +1303,14 @@ const DataTableRow = defineComponent({
|
|
|
1256
1303
|
rowIndex: {
|
|
1257
1304
|
type: Number,
|
|
1258
1305
|
default: void 0
|
|
1306
|
+
},
|
|
1307
|
+
/**
|
|
1308
|
+
* A page's own attributes for the row, from `rowAttributes`. They come before the row's own,
|
|
1309
|
+
* so `data-key`, selection, tree, and focus attributes always win; class and style merge.
|
|
1310
|
+
*/
|
|
1311
|
+
attributes: {
|
|
1312
|
+
type: Object,
|
|
1313
|
+
default: void 0
|
|
1259
1314
|
}
|
|
1260
1315
|
},
|
|
1261
1316
|
setup(props, { slots }) {
|
|
@@ -1267,7 +1322,7 @@ const DataTableRow = defineComponent({
|
|
|
1267
1322
|
const selected = table.isSelected(row.key);
|
|
1268
1323
|
const item = virtual ? virtualRow(virtual, row) : void 0;
|
|
1269
1324
|
const position = props.rowIndex ?? item?.renderItem.rowIndex ?? table.rows.indexOf(row);
|
|
1270
|
-
return h(props.as, {
|
|
1325
|
+
return h(props.as, mergeProps(props.attributes ?? {}, {
|
|
1271
1326
|
"aria-rowindex": position === -1 ? void 0 : table.pageStart + position + 1,
|
|
1272
1327
|
"aria-selected": table.selectionMode === "none" ? void 0 : String(selected),
|
|
1273
1328
|
"data-selected": flag(selected),
|
|
@@ -1282,7 +1337,7 @@ const DataTableRow = defineComponent({
|
|
|
1282
1337
|
ref: (element) => virtual.rows.measureElement(element, item.key),
|
|
1283
1338
|
"data-virtual-row": ""
|
|
1284
1339
|
} : {}
|
|
1285
|
-
}, slots.default?.({
|
|
1340
|
+
}), slots.default?.({
|
|
1286
1341
|
row,
|
|
1287
1342
|
selected,
|
|
1288
1343
|
columns: table.columns
|
|
@@ -1593,6 +1648,7 @@ const DataTableRowActions = defineComponent({
|
|
|
1593
1648
|
},
|
|
1594
1649
|
setup(props) {
|
|
1595
1650
|
const table = injectDataTable("<DataTableRowActions>");
|
|
1651
|
+
const locale = useTableLocale();
|
|
1596
1652
|
const context = inject(editingKey, void 0);
|
|
1597
1653
|
const id = useEditorId();
|
|
1598
1654
|
const element = shallowRef();
|
|
@@ -1601,37 +1657,56 @@ const DataTableRowActions = defineComponent({
|
|
|
1601
1657
|
if (previous && !active && !context?.draft && target?.closest("tr")?.contains(target.ownerDocument.activeElement)) nextTick(() => target.querySelector("button[data-edit-row]")?.focus());
|
|
1602
1658
|
});
|
|
1603
1659
|
return () => {
|
|
1660
|
+
const { messages } = locale();
|
|
1661
|
+
const rowName = String(props.row.key);
|
|
1604
1662
|
const draft = context?.draft?.rowKey === props.row.key ? context.draft : void 0;
|
|
1605
1663
|
const issues = [...new Map(draft?.issues.map((problem) => [problem.message, problem])).values()];
|
|
1606
|
-
const button = (label, action, disabled = false) => h("button", {
|
|
1664
|
+
const button = (label, action, disabled = false, role) => h("button", {
|
|
1607
1665
|
type: "button",
|
|
1608
1666
|
disabled,
|
|
1609
|
-
"aria-label":
|
|
1610
|
-
"data-edit-row":
|
|
1611
|
-
...
|
|
1667
|
+
"aria-label": messages.actionOnRow(label, rowName),
|
|
1668
|
+
"data-edit-row": role === "edit" ? "" : void 0,
|
|
1669
|
+
...role === "save" ? issueAttrs(id, issues, !!draft?.pending) : {},
|
|
1612
1670
|
onClick: action
|
|
1613
1671
|
}, label);
|
|
1614
1672
|
return h("div", {
|
|
1615
1673
|
ref: element,
|
|
1616
1674
|
"data-row-actions": "",
|
|
1617
1675
|
role: "group",
|
|
1618
|
-
"aria-label":
|
|
1676
|
+
"aria-label": messages.rowActionsFor(rowName),
|
|
1619
1677
|
"aria-busy": draft?.pending ? "true" : void 0
|
|
1620
1678
|
}, [
|
|
1621
|
-
...context?.mode === "row" && props.editable ? draft ? [button(
|
|
1679
|
+
...context?.mode === "row" && props.editable ? draft ? [button(messages.saveRow, () => context.save(), draft.pending, "save"), button(messages.cancel, () => context.cancel(props.row.key), draft.pending)] : [button(messages.editRow, () => context.start(props.row), false, "edit")] : [],
|
|
1622
1680
|
h("details", { onToggle: (event) => {
|
|
1623
1681
|
const menu = event.currentTarget;
|
|
1624
1682
|
if (menu.open) nextTick(() => menu.scrollIntoView?.({
|
|
1625
1683
|
block: "nearest",
|
|
1626
1684
|
inline: "nearest"
|
|
1627
1685
|
}));
|
|
1628
|
-
} }, [h("summary", { "aria-label":
|
|
1686
|
+
} }, [h("summary", { "aria-label": messages.actionsForRow(rowName) }, messages.actions), h("div", { "data-row-menu": "" }, [button(messages.revertRow, () => table.revert([props.row.key]), !props.row.isDirty || !!draft), props.removable ? button(messages.removeRow, () => table.removeRows([props.row.key]), !!draft) : null])]),
|
|
1629
1687
|
editorIssues(id, issues, !!draft?.pending)
|
|
1630
1688
|
]);
|
|
1631
1689
|
};
|
|
1632
1690
|
}
|
|
1633
1691
|
});
|
|
1634
1692
|
|
|
1693
|
+
//#endregion
|
|
1694
|
+
//#region src/row-attrs.ts
|
|
1695
|
+
function accepted(name) {
|
|
1696
|
+
return name === "class" || name === "style" || name.startsWith("data-") || name.startsWith("aria-");
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* The attributes `attrs` gives `row`, keeping only a class, a style, and `data-*` and `aria-*`
|
|
1700
|
+
* attributes. Merge them before the row's own so the row's win.
|
|
1701
|
+
*/
|
|
1702
|
+
function rowAttributes(attrs, row) {
|
|
1703
|
+
const given = attrs?.(row.original, row);
|
|
1704
|
+
if (!given) return {};
|
|
1705
|
+
const kept = {};
|
|
1706
|
+
for (const [name, value] of Object.entries(given)) if (accepted(name)) kept[name] = value;
|
|
1707
|
+
return kept;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1635
1710
|
//#endregion
|
|
1636
1711
|
//#region src/grid.ts
|
|
1637
1712
|
const gridContextKey = Symbol("vueye-table-grid-context");
|
|
@@ -1739,7 +1814,14 @@ const DataGridRoot = defineComponent({
|
|
|
1739
1814
|
event.preventDefault();
|
|
1740
1815
|
return;
|
|
1741
1816
|
}
|
|
1742
|
-
if (grid.handleKey(
|
|
1817
|
+
if (grid.handleKey({
|
|
1818
|
+
key: event.key,
|
|
1819
|
+
shiftKey: event.shiftKey,
|
|
1820
|
+
ctrlKey: event.ctrlKey,
|
|
1821
|
+
metaKey: event.metaKey,
|
|
1822
|
+
altKey: event.altKey,
|
|
1823
|
+
direction: directionOf(event.currentTarget)
|
|
1824
|
+
})) event.preventDefault();
|
|
1743
1825
|
};
|
|
1744
1826
|
const onCopy = (event, cut = false) => {
|
|
1745
1827
|
if (grid.editor || !grid.range || !event.clipboardData) return;
|
|
@@ -1815,6 +1897,11 @@ const DataGridBody = defineComponent({
|
|
|
1815
1897
|
treeCell: {
|
|
1816
1898
|
type: Boolean,
|
|
1817
1899
|
default: true
|
|
1900
|
+
},
|
|
1901
|
+
/** A page's own attributes for each row; the row's own always win. */
|
|
1902
|
+
rowAttrs: {
|
|
1903
|
+
type: Function,
|
|
1904
|
+
default: void 0
|
|
1818
1905
|
}
|
|
1819
1906
|
},
|
|
1820
1907
|
setup(props, { slots }) {
|
|
@@ -1846,7 +1933,7 @@ const DataGridBody = defineComponent({
|
|
|
1846
1933
|
editor: slots.editor,
|
|
1847
1934
|
$stable: true
|
|
1848
1935
|
}), "td");
|
|
1849
|
-
return h("tr", {
|
|
1936
|
+
return h("tr", mergeProps(rowAttributes(props.rowAttrs, row), {
|
|
1850
1937
|
key: item.key,
|
|
1851
1938
|
role: "row",
|
|
1852
1939
|
"aria-rowindex": table.pageStart + rowIndex + 1,
|
|
@@ -1855,7 +1942,7 @@ const DataGridBody = defineComponent({
|
|
|
1855
1942
|
...hierarchyRowAttrs(table, row, hierarchy),
|
|
1856
1943
|
"data-virtual-row": "",
|
|
1857
1944
|
ref: (target) => binding.rows.measureElement(target, item.key)
|
|
1858
|
-
}, [slots.rowHeader?.({
|
|
1945
|
+
}), [slots.rowHeader?.({
|
|
1859
1946
|
row,
|
|
1860
1947
|
index: rowIndex
|
|
1861
1948
|
}), ...columns]);
|
|
@@ -1865,14 +1952,14 @@ const DataGridBody = defineComponent({
|
|
|
1865
1952
|
]);
|
|
1866
1953
|
const content = slots.default?.({ rows: table.rows }) ?? table.renderItems.map((item) => item.kind === "detail" ? details.render(item.row, item.rowIndex) : (() => {
|
|
1867
1954
|
const { row, rowIndex } = item;
|
|
1868
|
-
return h("tr", {
|
|
1955
|
+
return h("tr", mergeProps(rowAttributes(props.rowAttrs, row), {
|
|
1869
1956
|
key: item.key,
|
|
1870
1957
|
role: "row",
|
|
1871
1958
|
"aria-rowindex": rowIndex + 2,
|
|
1872
1959
|
"data-key": String(row.key),
|
|
1873
1960
|
"data-dirty": flag(row.isDirty),
|
|
1874
1961
|
...hierarchyRowAttrs(table, row, hierarchy)
|
|
1875
|
-
}, [slots.rowHeader?.({
|
|
1962
|
+
}), [slots.rowHeader?.({
|
|
1876
1963
|
row,
|
|
1877
1964
|
index: rowIndex
|
|
1878
1965
|
}), ...table.columns.map((column, columnIndex) => h(DataGridCell, {
|
|
@@ -2040,5 +2127,5 @@ const DataGridCell = defineComponent({
|
|
|
2040
2127
|
});
|
|
2041
2128
|
|
|
2042
2129
|
//#endregion
|
|
2043
|
-
export { DataCellEditor, DataGridBody, DataGridCell, DataGridRoot, DataTableBody, DataTableCaption, DataTableCell, DataTableColumnVisibility, DataTableDetailRow, DataTableEditCell, DataTableEditRoot, DataTableEmpty, DataTableExpandToggle, DataTableHeader, DataTableHeaderCell, DataTableHeaderRow, DataTableLoadMore, DataTablePageSize, DataTablePagination, DataTableRoot, DataTableRow, DataTableRowActions, DataTableSearch, DataTableSelectAll, DataTableSelectRow, DataTableSortButton, DataTableStatus, DataTableTreeCell, DataTableViewport, DataTableVirtualColumns, cellEditorProps, cellId, columnStyle, expandToggleProps, hierarchyProps, injectVirtual as injectVirtualRenderer, resolveTreeColumn, treeCellProps, virtualProps };
|
|
2130
|
+
export { DataCellEditor, DataGridBody, DataGridCell, DataGridRoot, DataTableBody, DataTableCaption, DataTableCell, DataTableColumnVisibility, DataTableDetailRow, DataTableEditCell, DataTableEditRoot, DataTableEmpty, DataTableExpandToggle, DataTableHeader, DataTableHeaderCell, DataTableHeaderRow, DataTableLoadMore, DataTablePageSize, DataTablePagination, DataTableRoot, DataTableRow, DataTableRowActions, DataTableSearch, DataTableSelectAll, DataTableSelectRow, DataTableSortButton, DataTableStatus, DataTableTreeCell, DataTableViewport, DataTableVirtualColumns, cellEditorProps, cellId, columnStyle, expandToggleProps, hierarchyProps, injectVirtual as injectVirtualRenderer, resolveTreeColumn, rowAttributes, treeCellProps, virtualProps };
|
|
2044
2131
|
//# sourceMappingURL=index.js.map
|