@vueye-table/headless 3.0.0-beta.1 → 3.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +61 -59
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +106 -49
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { injectDataGrid, injectDataTable, provideDataGrid, provideDataTable, useDataGrid, useVirtualColumns, useVirtualRows } from "@vueye-table/vue";
|
|
1
|
+
import { injectDataGrid, injectDataTable, provideDataGrid, provideDataTable, useDataGrid, useTableLocale, useVirtualColumns, useVirtualRows } from "@vueye-table/vue";
|
|
2
2
|
import { Fragment, computed, defineComponent, h, inject, nextTick, onMounted, onScopeDispose, provide, ref, shallowRef, useId, watch } from "vue";
|
|
3
3
|
import { formatValue, getRowItemKey, gridCommand } from "@vueye-table/core";
|
|
4
4
|
|
|
@@ -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,
|
|
@@ -1593,6 +1640,7 @@ const DataTableRowActions = defineComponent({
|
|
|
1593
1640
|
},
|
|
1594
1641
|
setup(props) {
|
|
1595
1642
|
const table = injectDataTable("<DataTableRowActions>");
|
|
1643
|
+
const locale = useTableLocale();
|
|
1596
1644
|
const context = inject(editingKey, void 0);
|
|
1597
1645
|
const id = useEditorId();
|
|
1598
1646
|
const element = shallowRef();
|
|
@@ -1601,31 +1649,33 @@ const DataTableRowActions = defineComponent({
|
|
|
1601
1649
|
if (previous && !active && !context?.draft && target?.closest("tr")?.contains(target.ownerDocument.activeElement)) nextTick(() => target.querySelector("button[data-edit-row]")?.focus());
|
|
1602
1650
|
});
|
|
1603
1651
|
return () => {
|
|
1652
|
+
const { messages } = locale();
|
|
1653
|
+
const rowName = String(props.row.key);
|
|
1604
1654
|
const draft = context?.draft?.rowKey === props.row.key ? context.draft : void 0;
|
|
1605
1655
|
const issues = [...new Map(draft?.issues.map((problem) => [problem.message, problem])).values()];
|
|
1606
|
-
const button = (label, action, disabled = false) => h("button", {
|
|
1656
|
+
const button = (label, action, disabled = false, role) => h("button", {
|
|
1607
1657
|
type: "button",
|
|
1608
1658
|
disabled,
|
|
1609
|
-
"aria-label":
|
|
1610
|
-
"data-edit-row":
|
|
1611
|
-
...
|
|
1659
|
+
"aria-label": messages.actionOnRow(label, rowName),
|
|
1660
|
+
"data-edit-row": role === "edit" ? "" : void 0,
|
|
1661
|
+
...role === "save" ? issueAttrs(id, issues, !!draft?.pending) : {},
|
|
1612
1662
|
onClick: action
|
|
1613
1663
|
}, label);
|
|
1614
1664
|
return h("div", {
|
|
1615
1665
|
ref: element,
|
|
1616
1666
|
"data-row-actions": "",
|
|
1617
1667
|
role: "group",
|
|
1618
|
-
"aria-label":
|
|
1668
|
+
"aria-label": messages.rowActionsFor(rowName),
|
|
1619
1669
|
"aria-busy": draft?.pending ? "true" : void 0
|
|
1620
1670
|
}, [
|
|
1621
|
-
...context?.mode === "row" && props.editable ? draft ? [button(
|
|
1671
|
+
...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
1672
|
h("details", { onToggle: (event) => {
|
|
1623
1673
|
const menu = event.currentTarget;
|
|
1624
1674
|
if (menu.open) nextTick(() => menu.scrollIntoView?.({
|
|
1625
1675
|
block: "nearest",
|
|
1626
1676
|
inline: "nearest"
|
|
1627
1677
|
}));
|
|
1628
|
-
} }, [h("summary", { "aria-label":
|
|
1678
|
+
} }, [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
1679
|
editorIssues(id, issues, !!draft?.pending)
|
|
1630
1680
|
]);
|
|
1631
1681
|
};
|
|
@@ -1739,7 +1789,14 @@ const DataGridRoot = defineComponent({
|
|
|
1739
1789
|
event.preventDefault();
|
|
1740
1790
|
return;
|
|
1741
1791
|
}
|
|
1742
|
-
if (grid.handleKey(
|
|
1792
|
+
if (grid.handleKey({
|
|
1793
|
+
key: event.key,
|
|
1794
|
+
shiftKey: event.shiftKey,
|
|
1795
|
+
ctrlKey: event.ctrlKey,
|
|
1796
|
+
metaKey: event.metaKey,
|
|
1797
|
+
altKey: event.altKey,
|
|
1798
|
+
direction: directionOf(event.currentTarget)
|
|
1799
|
+
})) event.preventDefault();
|
|
1743
1800
|
};
|
|
1744
1801
|
const onCopy = (event, cut = false) => {
|
|
1745
1802
|
if (grid.editor || !grid.range || !event.clipboardData) return;
|