nuxt-ui-tools 1.5.0 → 1.6.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/dist/module.json +1 -1
- package/dist/module.mjs +1 -0
- package/dist/runtime/i18n/locales/en.js +23 -2
- package/dist/runtime/i18n/locales/fr.js +23 -2
- package/dist/runtime/i18n/types.d.ts +21 -0
- package/dist/runtime/table/components/data-list/data-list-content.vue +7 -1
- package/dist/runtime/table/components/data-list/data-list-error-state.d.vue.ts +18 -1
- package/dist/runtime/table/components/data-list/data-list-error-state.vue +65 -41
- package/dist/runtime/table/components/data-list/data-list-error-state.vue.d.ts +18 -1
- package/dist/runtime/table/components/data-list/sort-menu-panel.vue +33 -25
- package/dist/runtime/table/components/drawers/column-panel.vue +19 -6
- package/dist/runtime/table/components/filters/shared/dynamic-filter-picker.vue +1 -1
- package/dist/runtime/table/components/filters/shared/filter-editor-header.d.vue.ts +16 -0
- package/dist/runtime/table/components/filters/shared/filter-editor-header.vue +46 -0
- package/dist/runtime/table/components/filters/shared/filter-editor-header.vue.d.ts +16 -0
- package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.d.vue.ts +3 -1
- package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue +5 -4
- package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue.d.ts +3 -1
- package/dist/runtime/table/components/filters/shared/filter-option-picker-content.vue +4 -1
- package/dist/runtime/table/components/filters/shared/filter-option-single-list.vue +3 -3
- package/dist/runtime/table/components/filters/shared/filter-option-tree-content.vue +7 -3
- package/dist/runtime/table/components/filters/shared/filter-popover-shell.vue +10 -1
- package/dist/runtime/table/components/filters/shared/filter-searchable-panel.vue +14 -6
- package/dist/runtime/table/components/filters/shared/filter-trigger-tag.vue +5 -1
- package/dist/runtime/table/components/filters/tags/boolean-filter-tag.d.vue.ts +6 -1
- package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue +19 -5
- package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue.d.ts +6 -1
- package/dist/runtime/table/components/filters/tags/date-filter-tag.d.vue.ts +6 -1
- package/dist/runtime/table/components/filters/tags/date-filter-tag.vue +65 -29
- package/dist/runtime/table/components/filters/tags/date-filter-tag.vue.d.ts +6 -1
- package/dist/runtime/table/components/filters/tags/number-filter-tag.d.vue.ts +6 -1
- package/dist/runtime/table/components/filters/tags/number-filter-tag.vue +66 -18
- package/dist/runtime/table/components/filters/tags/number-filter-tag.vue.d.ts +6 -1
- package/dist/runtime/table/components/filters/tags/option-filter-tag.d.vue.ts +2 -2
- package/dist/runtime/table/components/filters/tags/option-filter-tag.vue +10 -34
- package/dist/runtime/table/components/filters/tags/option-filter-tag.vue.d.ts +2 -2
- package/dist/runtime/table/components/filters/tags/text-filter-tag.d.vue.ts +6 -1
- package/dist/runtime/table/components/filters/tags/text-filter-tag.vue +39 -14
- package/dist/runtime/table/components/filters/tags/text-filter-tag.vue.d.ts +6 -1
- package/dist/runtime/table/components/grid/grid-renderer.d.vue.ts +8 -2
- package/dist/runtime/table/components/grid/grid-renderer.vue +47 -115
- package/dist/runtime/table/components/grid/grid-renderer.vue.d.ts +8 -2
- package/dist/runtime/table/components/layout/progress-line.d.vue.ts +9 -0
- package/dist/runtime/table/components/layout/progress-line.vue +43 -0
- package/dist/runtime/table/components/layout/progress-line.vue.d.ts +9 -0
- package/dist/runtime/table/components/table/table-empty-state.d.vue.ts +1 -1
- package/dist/runtime/table/components/table/table-empty-state.vue +1 -1
- package/dist/runtime/table/components/table/table-empty-state.vue.d.ts +1 -1
- package/dist/runtime/table/components/table/table-layout.d.ts +57 -0
- package/dist/runtime/table/components/table/table-layout.js +23 -0
- package/dist/runtime/table/components/table/table-renderer.d.vue.ts +8 -16
- package/dist/runtime/table/components/table/table-renderer.vue +180 -274
- package/dist/runtime/table/components/table/table-renderer.vue.d.ts +8 -16
- package/dist/runtime/table/components/table/table-row.d.vue.ts +19 -0
- package/dist/runtime/table/components/table/table-row.vue +51 -0
- package/dist/runtime/table/components/table/table-row.vue.d.ts +19 -0
- package/dist/runtime/table/components/table/table-skeleton-cell.d.ts +9 -0
- package/dist/runtime/table/components/table/table-skeleton-cell.js +104 -0
- package/dist/runtime/table/components/utils/search-query-input.vue +27 -1
- package/dist/runtime/table/composables/use-deferred-commit.d.ts +20 -0
- package/dist/runtime/table/composables/use-deferred-commit.js +31 -0
- package/dist/runtime/table/composables/use-table-data.d.ts +5 -1
- package/dist/runtime/table/composables/use-table-data.js +20 -2
- package/dist/runtime/table/composables/use-table-summaries.js +10 -1
- package/dist/runtime/table/types/columns.d.ts +15 -1
- package/dist/runtime/table/types/data-list.d.ts +1 -0
- package/dist/runtime/table/utils/columns/defs.js +1 -1
- package/dist/runtime/table/utils/filters/date.d.ts +6 -0
- package/dist/runtime/table/utils/filters/date.js +26 -2
- package/dist/runtime/table/utils/filters/index.d.ts +1 -0
- package/dist/runtime/table/utils/filters/index.js +1 -0
- package/dist/runtime/table/utils/filters/number.d.ts +5 -0
- package/dist/runtime/table/utils/filters/number.js +11 -0
- package/dist/runtime/table/utils/filters/ui.js +5 -5
- package/package.json +1 -1
|
@@ -1,19 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useVirtualizer } from "@tanstack/vue-virtual";
|
|
3
|
-
import {
|
|
4
|
-
computed,
|
|
5
|
-
h,
|
|
6
|
-
nextTick,
|
|
7
|
-
onBeforeUnmount,
|
|
8
|
-
onMounted,
|
|
9
|
-
ref,
|
|
10
|
-
shallowRef,
|
|
11
|
-
TransitionGroup,
|
|
12
|
-
useTemplateRef,
|
|
13
|
-
watch
|
|
14
|
-
} from "vue";
|
|
3
|
+
import { computed, h, nextTick, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from "vue";
|
|
15
4
|
import { useUiToolsLocale } from "#ui-tools/i18n";
|
|
16
|
-
import {
|
|
5
|
+
import { isFunction, isNumber, isObject } from "../../../shared/utils/predicate";
|
|
17
6
|
import { useDataListUi } from "../../composables/use-data-list-ui";
|
|
18
7
|
import { useTableInternals } from "../../composables/use-table-internals";
|
|
19
8
|
import { useTanstackTable } from "../../composables/use-tanstack-table";
|
|
@@ -24,16 +13,20 @@ import {
|
|
|
24
13
|
SELECT_COLUMN_WIDTH
|
|
25
14
|
} from "../../utils/columns/types";
|
|
26
15
|
import DataListErrorState from "../data-list/data-list-error-state.vue";
|
|
16
|
+
import ProgressLine from "../layout/progress-line.vue";
|
|
27
17
|
import TableCell from "./table-cell";
|
|
28
18
|
import TableColumnHeader from "./table-column-header.vue";
|
|
29
19
|
import TableEmptyState from "./table-empty-state.vue";
|
|
20
|
+
import { columnCellLayout, tableRowCells } from "./table-layout";
|
|
30
21
|
import TableOverlayScrollbars from "./table-overlay-scrollbars.vue";
|
|
22
|
+
import TableRow from "./table-row.vue";
|
|
23
|
+
import TableSkeletonCell from "./table-skeleton-cell";
|
|
31
24
|
const LOAD_MORE_THRESHOLD = 6;
|
|
32
25
|
const PREFETCH_VIEWPORTS = 3;
|
|
33
26
|
const VIRTUALIZE_ROW_THRESHOLD = 40;
|
|
34
27
|
const VIRTUALIZE_CELL_THRESHOLD = 240;
|
|
35
|
-
const VIRTUALIZE_COLUMN_THRESHOLD =
|
|
36
|
-
const
|
|
28
|
+
const VIRTUALIZE_COLUMN_THRESHOLD = 12;
|
|
29
|
+
const APPEND_WINDOW = 400;
|
|
37
30
|
const SKELETON_MIN_ROWS = 6;
|
|
38
31
|
const SIZE_TOKENS = {
|
|
39
32
|
lg: { font: 13.5, head: 46, row: 52, x: 16 },
|
|
@@ -59,11 +52,12 @@ const { status } = internals.queryContent;
|
|
|
59
52
|
const rowsMounted = ref(false);
|
|
60
53
|
let rowMountFrame = 0;
|
|
61
54
|
const isFirstLoad = computed(
|
|
62
|
-
() => status.value.isBooting || (status.value.isPending || status.value.isFetching) && rows.value.length === 0
|
|
55
|
+
() => status.value.isBooting || (status.value.isPending || status.value.isFetching) && rows.value.length === 0
|
|
63
56
|
);
|
|
64
57
|
const refreshing = computed(
|
|
65
58
|
() => rows.value.length > 0 && (status.value.isFetching || status.value.isRefreshing || status.value.isRevalidating)
|
|
66
59
|
);
|
|
60
|
+
const replacing = computed(() => rows.value.length > 0 && status.value.isReplacing);
|
|
67
61
|
const error = computed(() => rows.value.length === 0 ? internals.queryContent.error.value : null);
|
|
68
62
|
const empty = computed(() => !isFirstLoad.value && !error.value && rows.value.length === 0);
|
|
69
63
|
function refresh() {
|
|
@@ -125,13 +119,18 @@ const virtualized = computed(
|
|
|
125
119
|
);
|
|
126
120
|
const scrollRef = useTemplateRef("scrollRef");
|
|
127
121
|
const rowHeights = /* @__PURE__ */ new Map();
|
|
128
|
-
function measureRowHeight(element) {
|
|
122
|
+
function measureRowHeight(element, entry) {
|
|
129
123
|
const key = element instanceof HTMLElement ? element.dataset.rowId : void 0;
|
|
130
|
-
const
|
|
124
|
+
const known = key === void 0 ? void 0 : rowHeights.get(key);
|
|
125
|
+
const box = entry?.borderBoxSize?.[0];
|
|
126
|
+
if (!box) {
|
|
127
|
+
return known ?? rowHeight.value;
|
|
128
|
+
}
|
|
129
|
+
const height = box.blockSize;
|
|
131
130
|
if (key === void 0) {
|
|
132
131
|
return height;
|
|
133
132
|
}
|
|
134
|
-
const next = Math.max(
|
|
133
|
+
const next = Math.max(known ?? 0, height);
|
|
135
134
|
rowHeights.set(key, next);
|
|
136
135
|
return next;
|
|
137
136
|
}
|
|
@@ -141,20 +140,17 @@ const rowVirtualizer = useVirtualizer(
|
|
|
141
140
|
estimateSize: () => rowHeight.value,
|
|
142
141
|
getItemKey: (index) => renderRows.value[index] ? getRowId(renderRows.value[index], index) : index,
|
|
143
142
|
getScrollElement: () => scrollRef.value ?? null,
|
|
144
|
-
measureElement: (element) => measureRowHeight(element),
|
|
145
|
-
overscan:
|
|
143
|
+
measureElement: (element, entry) => measureRowHeight(element, entry),
|
|
144
|
+
overscan: 16
|
|
146
145
|
}))
|
|
147
146
|
);
|
|
148
147
|
const virtualRows = computed(
|
|
149
148
|
() => virtualized.value ? rowVirtualizer.value.getVirtualItems() : []
|
|
150
149
|
);
|
|
151
|
-
const materializedRows = computed(
|
|
152
|
-
() => virtualized.value ? virtualRows.value.map((item) => renderRows.value[item.index]).filter(isDefined) : renderRows.value
|
|
153
|
-
);
|
|
154
150
|
const { table, resetColumnSizing } = useTanstackTable({
|
|
155
151
|
columnSizing,
|
|
156
152
|
columns: columnDefs,
|
|
157
|
-
data:
|
|
153
|
+
data: renderRows,
|
|
158
154
|
getRowId,
|
|
159
155
|
pinned
|
|
160
156
|
});
|
|
@@ -186,6 +182,20 @@ const columnVirtualizer = useVirtualizer(
|
|
|
186
182
|
}))
|
|
187
183
|
);
|
|
188
184
|
const virtualColumns = computed(() => columnVirtualizer.value.getVirtualItems());
|
|
185
|
+
const filled = computed(
|
|
186
|
+
() => !columnsOverflow.value && bodyWidth.value > 0 && table.getTotalSize() < bodyWidth.value
|
|
187
|
+
);
|
|
188
|
+
const tableCols = computed(() => {
|
|
189
|
+
const cols = leafColumns.value.map((leaf) => ({
|
|
190
|
+
key: leaf.id,
|
|
191
|
+
width: `${leaf.getSize()}px`
|
|
192
|
+
}));
|
|
193
|
+
if (filled.value) {
|
|
194
|
+
cols.splice(cols.length - table.getEndVisibleLeafColumns().length, 0, { key: "fill" });
|
|
195
|
+
}
|
|
196
|
+
return cols;
|
|
197
|
+
});
|
|
198
|
+
const columnCount = computed(() => tableCols.value.length);
|
|
189
199
|
const columnSlots = computed(() => {
|
|
190
200
|
function asSlot(column) {
|
|
191
201
|
return {
|
|
@@ -196,7 +206,11 @@ const columnSlots = computed(() => {
|
|
|
196
206
|
}
|
|
197
207
|
const slots = table.getStartVisibleLeafColumns().map(asSlot);
|
|
198
208
|
if (!columnsOverflow.value) {
|
|
199
|
-
slots.push(...centerColumns.value.map(asSlot)
|
|
209
|
+
slots.push(...centerColumns.value.map(asSlot));
|
|
210
|
+
if (filled.value) {
|
|
211
|
+
slots.push({ key: "fill", kind: "fill" });
|
|
212
|
+
}
|
|
213
|
+
slots.push(...table.getEndVisibleLeafColumns().map(asSlot));
|
|
200
214
|
return slots;
|
|
201
215
|
}
|
|
202
216
|
const first = virtualColumns.value[0];
|
|
@@ -217,23 +231,33 @@ const columnSlots = computed(() => {
|
|
|
217
231
|
slots.push(...table.getEndVisibleLeafColumns().map(asSlot));
|
|
218
232
|
return slots;
|
|
219
233
|
});
|
|
220
|
-
function rowColumnSlots(row) {
|
|
221
|
-
const cells = new Map(row.getVisibleCells().map((cell) => [cell.column.id, cell]));
|
|
222
|
-
const slots = [];
|
|
223
|
-
for (const slot of columnSlots.value) {
|
|
224
|
-
if (slot.kind === "spacer") {
|
|
225
|
-
slots.push(slot);
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
const cell = cells.get(slot.columnId);
|
|
229
|
-
if (cell) {
|
|
230
|
-
slots.push({ cell, key: cell.id, kind: "cell" });
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return slots;
|
|
234
|
-
}
|
|
235
234
|
const headers = computed(() => table.getHeaderGroups()[0]?.headers ?? []);
|
|
236
235
|
const headerByColumnId = computed(() => new Map(headers.value.map((h2) => [h2.column.id, h2])));
|
|
236
|
+
const headerCellProps = computed(
|
|
237
|
+
() => new Map(
|
|
238
|
+
headers.value.map((header) => {
|
|
239
|
+
const { column } = header;
|
|
240
|
+
const meta = column.columnDef.meta;
|
|
241
|
+
return [
|
|
242
|
+
column.id,
|
|
243
|
+
{
|
|
244
|
+
align: meta?.align,
|
|
245
|
+
icon: meta?.icon,
|
|
246
|
+
items: internals.tableColumns.getMenuItems({ columnId: column.id }),
|
|
247
|
+
label: meta?.label ?? "",
|
|
248
|
+
pinned: Boolean(internals.tableColumns.getPinnedState({ columnId: column.id })),
|
|
249
|
+
resetSize: () => column.resetSize(),
|
|
250
|
+
resizable: column.getCanResize(),
|
|
251
|
+
resize: header.getResizeHandler(),
|
|
252
|
+
resizing: column.getIsResizing(),
|
|
253
|
+
sortState: internals.tableColumns.getSortState({ columnId: column.id }),
|
|
254
|
+
sortable: meta?.sortable
|
|
255
|
+
}
|
|
256
|
+
];
|
|
257
|
+
})
|
|
258
|
+
)
|
|
259
|
+
);
|
|
260
|
+
const HEADER_ROW = {};
|
|
237
261
|
const virtualPaddingTop = computed(() => virtualRows.value[0]?.start ?? 0);
|
|
238
262
|
const virtualPaddingBottom = computed(() => {
|
|
239
263
|
if (!virtualized.value || !virtualRows.value.length) {
|
|
@@ -241,26 +265,36 @@ const virtualPaddingBottom = computed(() => {
|
|
|
241
265
|
}
|
|
242
266
|
return rowVirtualizer.value.getTotalSize() - (virtualRows.value.at(-1)?.end ?? 0);
|
|
243
267
|
});
|
|
244
|
-
const virtualRowByKey = computed(() => {
|
|
245
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
246
|
-
for (const item of virtualRows.value) {
|
|
247
|
-
const row = renderRows.value[item.index];
|
|
248
|
-
if (row) {
|
|
249
|
-
byKey.set(getRowId(row, item.index), { index: item.index, key: String(item.key) });
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return byKey;
|
|
253
|
-
});
|
|
254
268
|
const renderedRows = computed(() => {
|
|
255
269
|
if (!virtualized.value) {
|
|
256
270
|
return tableRows.value.map((row, index) => ({ row, virtual: { index, key: String(row.id) } }));
|
|
257
271
|
}
|
|
258
|
-
return
|
|
259
|
-
const
|
|
260
|
-
return
|
|
261
|
-
})
|
|
272
|
+
return virtualRows.value.flatMap((item) => {
|
|
273
|
+
const row = tableRows.value[item.index];
|
|
274
|
+
return row ? [{ row, virtual: { index: item.index, key: String(item.key) } }] : [];
|
|
275
|
+
});
|
|
262
276
|
});
|
|
263
|
-
|
|
277
|
+
const rowCells = computed(
|
|
278
|
+
() => tableRowCells({
|
|
279
|
+
layouts: new Map(
|
|
280
|
+
leafColumns.value.map((column) => [
|
|
281
|
+
column.id,
|
|
282
|
+
columnCellLayout({
|
|
283
|
+
firstEnd: isFirstEnd(column),
|
|
284
|
+
lastStart: isLastStart(column),
|
|
285
|
+
meta: column.columnDef.meta,
|
|
286
|
+
offset: pinnedOffset(column),
|
|
287
|
+
pinned: column.getIsPinned(),
|
|
288
|
+
tdClass: mergeDataListUiClass(void 0, void 0, props.ui?.td)
|
|
289
|
+
})
|
|
290
|
+
])
|
|
291
|
+
),
|
|
292
|
+
slots: columnSlots.value
|
|
293
|
+
})
|
|
294
|
+
);
|
|
295
|
+
const rowClass = computed(() => mergeDataListUiClass(void 0, void 0, props.ui?.tr));
|
|
296
|
+
function measureRow(target) {
|
|
297
|
+
const element = target instanceof Element ? target : target?.$el;
|
|
264
298
|
if (!(element instanceof HTMLElement)) {
|
|
265
299
|
return;
|
|
266
300
|
}
|
|
@@ -335,8 +369,11 @@ const summaryLabel = computed(() => {
|
|
|
335
369
|
if (label) {
|
|
336
370
|
return isFunction(label) ? String(label()) : String(label);
|
|
337
371
|
}
|
|
338
|
-
return t("table.summaries.total");
|
|
372
|
+
return summaries.scope.value === "filtered" ? t("table.summaries.total") : t(`table.summaries.${summaries.scope.value}`);
|
|
339
373
|
});
|
|
374
|
+
const summaryUnit = computed(
|
|
375
|
+
() => t(summaries.count.value === 1 ? "table.summaries.rowOne" : "table.summaries.rowOther")
|
|
376
|
+
);
|
|
340
377
|
function formatNumber(value) {
|
|
341
378
|
return isNumber(value) ? new Intl.NumberFormat(locale.value.code).format(value).replaceAll("\u202F", "\xA0") : String(value ?? "");
|
|
342
379
|
}
|
|
@@ -354,52 +391,9 @@ function renderSummary(columnId) {
|
|
|
354
391
|
const value = summaries.format(columnId);
|
|
355
392
|
return () => h("span", formatNumber(value));
|
|
356
393
|
}
|
|
357
|
-
const
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
const flipPositions = /* @__PURE__ */ new Map();
|
|
361
|
-
watch(
|
|
362
|
-
rows,
|
|
363
|
-
() => {
|
|
364
|
-
previousIds.value = new Set(rows.value.map((row, index) => getRowId(row, index)));
|
|
365
|
-
flipPositions.clear();
|
|
366
|
-
const elements = scrollRef.value?.querySelectorAll("tr.nut-dl-row[data-row-id]") ?? [];
|
|
367
|
-
for (const element of elements) {
|
|
368
|
-
flipPositions.set(element.dataset.rowId ?? "", element.getBoundingClientRect().top);
|
|
369
|
-
}
|
|
370
|
-
},
|
|
371
|
-
{ flush: "pre" }
|
|
372
|
-
);
|
|
373
|
-
watch(rows, () => nextTick().then(flipRows), { flush: "post" });
|
|
374
|
-
function flipRows() {
|
|
375
|
-
if (!flipPositions.size) {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
const elements = scrollRef.value?.querySelectorAll("tr.nut-dl-row[data-row-id]") ?? [];
|
|
379
|
-
for (const element of elements) {
|
|
380
|
-
const previous = flipPositions.get(element.dataset.rowId ?? "");
|
|
381
|
-
if (previous === void 0) {
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
const delta = previous - element.getBoundingClientRect().top;
|
|
385
|
-
if (Math.abs(delta) > 1) {
|
|
386
|
-
element.animate([{ transform: `translateY(${delta}px)` }, { transform: "none" }], {
|
|
387
|
-
duration: 240,
|
|
388
|
-
easing: "cubic-bezier(0.2, 0.9, 0.3, 1)"
|
|
389
|
-
});
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
flipPositions.clear();
|
|
393
|
-
}
|
|
394
|
-
let animateTimer = 0;
|
|
395
|
-
function armAnimation(from = Number.POSITIVE_INFINITY) {
|
|
396
|
-
enterFrom.value = from;
|
|
397
|
-
animateEpoch.value = true;
|
|
398
|
-
window.clearTimeout(animateTimer);
|
|
399
|
-
animateTimer = window.setTimeout(() => {
|
|
400
|
-
animateEpoch.value = false;
|
|
401
|
-
}, ANIMATION_WINDOW);
|
|
402
|
-
}
|
|
394
|
+
const appendedFrom = ref(Number.POSITIVE_INFINITY);
|
|
395
|
+
const scrollResetPending = ref(false);
|
|
396
|
+
let appendTimer = 0;
|
|
403
397
|
watch(
|
|
404
398
|
() => [
|
|
405
399
|
internals.pagination.currentPage.value,
|
|
@@ -409,75 +403,38 @@ watch(
|
|
|
409
403
|
internals.filters.searchQuery.value
|
|
410
404
|
],
|
|
411
405
|
() => {
|
|
412
|
-
if (!rowsMounted.value || cursorMode.value)
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
406
|
+
if (!rowsMounted.value || cursorMode.value) return;
|
|
415
407
|
rowHeights.clear();
|
|
416
|
-
|
|
417
|
-
scrollRef.value?.scrollTo({ top: 0 });
|
|
408
|
+
scrollResetPending.value = true;
|
|
418
409
|
}
|
|
419
410
|
);
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
function renderSkeletonCell(columnId, rowIndex) {
|
|
425
|
-
const meta = headerByColumnId.value.get(columnId)?.column.columnDef.meta;
|
|
426
|
-
const kind = meta?.internal === "selection" ? "check" : meta?.internal ? "none" : meta?.skeleton ?? "text";
|
|
427
|
-
const seed = rowIndex * 7 + columnId.length;
|
|
428
|
-
function line(width, extra = "") {
|
|
429
|
-
return h("span", {
|
|
430
|
-
class: `nut-dl-skeleton block h-3 rounded ${extra}`,
|
|
431
|
-
style: { width: `${width}%` }
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
return () => {
|
|
435
|
-
if (kind === "none") {
|
|
436
|
-
return null;
|
|
437
|
-
}
|
|
438
|
-
if (kind === "check") {
|
|
439
|
-
return h("span", { class: "nut-dl-skeleton block size-4 rounded-[4px]" });
|
|
440
|
-
}
|
|
441
|
-
if (kind === "dot") {
|
|
442
|
-
return h("span", { class: "flex items-center gap-2" }, [
|
|
443
|
-
h("span", { class: "nut-dl-skeleton size-[7px] rounded-full" }),
|
|
444
|
-
line(skeletonWidth(seed) - 10)
|
|
445
|
-
]);
|
|
446
|
-
}
|
|
447
|
-
if (kind === "avatar") {
|
|
448
|
-
return h("span", { class: "flex items-center gap-2.5" }, [
|
|
449
|
-
h("span", { class: "nut-dl-skeleton size-7 shrink-0 rounded-md" }),
|
|
450
|
-
h("span", { class: "grid flex-1 gap-1.5" }, [
|
|
451
|
-
line(skeletonWidth(seed)),
|
|
452
|
-
line(skeletonWidth(seed + 3) - 20, "h-2.5")
|
|
453
|
-
])
|
|
454
|
-
]);
|
|
455
|
-
}
|
|
456
|
-
if (kind === "badge") {
|
|
457
|
-
return h("span", { class: "nut-dl-skeleton inline-block h-5 w-16 rounded-full" });
|
|
458
|
-
}
|
|
459
|
-
if (kind === "number") {
|
|
460
|
-
return h("span", {
|
|
461
|
-
class: "nut-dl-skeleton ml-auto block h-3 rounded",
|
|
462
|
-
style: { width: "36%" }
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
return line(skeletonWidth(seed));
|
|
466
|
-
};
|
|
411
|
+
function resetScroll() {
|
|
412
|
+
if (!scrollResetPending.value) return;
|
|
413
|
+
scrollResetPending.value = false;
|
|
414
|
+
scrollRef.value?.scrollTo({ top: 0 });
|
|
467
415
|
}
|
|
468
|
-
watch(
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
416
|
+
watch(rows, resetScroll);
|
|
417
|
+
watch(
|
|
418
|
+
() => status.value.isFetching,
|
|
419
|
+
(fetching) => !fetching && resetScroll()
|
|
420
|
+
);
|
|
473
421
|
watch(
|
|
474
422
|
() => rows.value.length,
|
|
475
423
|
(next, previous) => {
|
|
476
|
-
if (cursorMode.value
|
|
477
|
-
|
|
478
|
-
|
|
424
|
+
if (!cursorMode.value || previous === 0 || next <= previous) return;
|
|
425
|
+
appendedFrom.value = previous;
|
|
426
|
+
window.clearTimeout(appendTimer);
|
|
427
|
+
appendTimer = window.setTimeout(() => {
|
|
428
|
+
appendedFrom.value = Number.POSITIVE_INFINITY;
|
|
429
|
+
}, APPEND_WINDOW);
|
|
479
430
|
}
|
|
480
431
|
);
|
|
432
|
+
function skeletonColumn(columnId) {
|
|
433
|
+
const meta = headerByColumnId.value.get(columnId)?.column.columnDef.meta;
|
|
434
|
+
if (meta?.internal === "selection") return { align: meta.align, skeleton: "check" };
|
|
435
|
+
if (meta?.internal) return { align: meta.align, skeleton: "none" };
|
|
436
|
+
return { align: meta?.align, skeleton: meta?.skeleton };
|
|
437
|
+
}
|
|
481
438
|
const cursorMode = computed(() => internals.pagination.mode.value === "cursor");
|
|
482
439
|
const loadingMore = computed(
|
|
483
440
|
() => cursorMode.value && internals.pagination.state.value.isLoadingMore
|
|
@@ -539,7 +496,7 @@ defineExpose({ resetColumnSizing });
|
|
|
539
496
|
ref="scrollRef"
|
|
540
497
|
class="nut-dl-table__scroll relative min-h-0 overflow-auto overscroll-x-contain bg-[var(--nut-dl-surface)]"
|
|
541
498
|
:class="[
|
|
542
|
-
fill || height ? 'flex-1' : '',
|
|
499
|
+
fill || height ? 'flex flex-1 flex-col' : '',
|
|
543
500
|
mergeDataListUiClass(void 0, void 0, ui?.root)
|
|
544
501
|
]"
|
|
545
502
|
@scroll.passive="onScrollLoadMore"
|
|
@@ -551,16 +508,21 @@ defineExpose({ resetColumnSizing });
|
|
|
551
508
|
>
|
|
552
509
|
<colgroup>
|
|
553
510
|
<col
|
|
554
|
-
v-for="
|
|
555
|
-
:key="
|
|
556
|
-
:style="{ width:
|
|
511
|
+
v-for="col in tableCols"
|
|
512
|
+
:key="col.key"
|
|
513
|
+
:style="col.width ? { width: col.width } : void 0"
|
|
557
514
|
/>
|
|
558
515
|
</colgroup>
|
|
559
516
|
<thead :class="mergeDataListUiClass('nut-dl-table__head', void 0, ui?.thead)">
|
|
560
517
|
<tr class="nut-dl-table__head-row">
|
|
561
518
|
<template v-for="slot in columnSlots" :key="slot.key">
|
|
562
519
|
<th
|
|
563
|
-
v-if="slot.kind === '
|
|
520
|
+
v-if="slot.kind === 'fill'"
|
|
521
|
+
class="nut-dl-table__fill sticky top-0 z-[3] p-0"
|
|
522
|
+
aria-hidden="true"
|
|
523
|
+
/>
|
|
524
|
+
<th
|
|
525
|
+
v-else-if="slot.kind === 'spacer'"
|
|
564
526
|
:colspan="slot.colSpan"
|
|
565
527
|
class="nut-dl-table__spacer sticky top-0 z-[3] p-0"
|
|
566
528
|
aria-hidden="true"
|
|
@@ -593,53 +555,27 @@ defineExpose({ resetColumnSizing });
|
|
|
593
555
|
headerByColumnId.get(slot.columnId).column.columnDef.meta?.renderHeader
|
|
594
556
|
"
|
|
595
557
|
:render="
|
|
596
|
-
|
|
558
|
+
headerByColumnId.get(slot.columnId).column.columnDef.meta.renderHeader
|
|
597
559
|
"
|
|
598
|
-
:row="
|
|
560
|
+
:row="HEADER_ROW"
|
|
599
561
|
:index="-1"
|
|
600
562
|
/>
|
|
601
563
|
</div>
|
|
602
564
|
</template>
|
|
603
565
|
<TableColumnHeader
|
|
604
566
|
v-else
|
|
567
|
+
v-bind="headerCellProps.get(slot.columnId)"
|
|
605
568
|
:open="openMenuId === slot.columnId"
|
|
606
|
-
:label="headerByColumnId.get(slot.columnId).column.columnDef.meta.label"
|
|
607
|
-
:icon="headerByColumnId.get(slot.columnId).column.columnDef.meta.icon"
|
|
608
|
-
:align="headerByColumnId.get(slot.columnId).column.columnDef.meta.align"
|
|
609
|
-
:sortable="headerByColumnId.get(slot.columnId).column.columnDef.meta.sortable"
|
|
610
|
-
:sort-state="internals.tableColumns.getSortState({ columnId: slot.columnId })"
|
|
611
|
-
:pinned="
|
|
612
|
-
Boolean(internals.tableColumns.getPinnedState({ columnId: slot.columnId }))
|
|
613
|
-
"
|
|
614
|
-
:items="internals.tableColumns.getMenuItems({ columnId: slot.columnId })"
|
|
615
|
-
:resizable="headerByColumnId.get(slot.columnId).column.getCanResize()"
|
|
616
|
-
:resizing="headerByColumnId.get(slot.columnId).column.getIsResizing()"
|
|
617
|
-
:reset-size="() => headerByColumnId.get(slot.columnId).column.resetSize()"
|
|
618
|
-
:resize="headerByColumnId.get(slot.columnId).getResizeHandler()"
|
|
619
569
|
@update:open="openMenuId = $event ? slot.columnId : null"
|
|
620
570
|
/>
|
|
621
571
|
</th>
|
|
622
572
|
</template>
|
|
623
573
|
</tr>
|
|
624
|
-
<tr class="nut-dl-progress" :data-active="refreshing" aria-hidden="true">
|
|
625
|
-
<th
|
|
626
|
-
:colspan="leafColumns.length"
|
|
627
|
-
class="sticky top-[var(--nut-dl-head-h)] z-[3] h-0 p-0"
|
|
628
|
-
>
|
|
629
|
-
<span />
|
|
630
|
-
</th>
|
|
631
|
-
</tr>
|
|
632
574
|
</thead>
|
|
633
575
|
|
|
634
|
-
<
|
|
635
|
-
:is="virtualized ? 'tbody' : TransitionGroup"
|
|
636
|
-
:key="virtualized ? 'virtual' : 'rows'"
|
|
637
|
-
:tag="virtualized ? void 0 : 'tbody'"
|
|
576
|
+
<tbody
|
|
638
577
|
:class="mergeDataListUiClass('nut-dl-table__body', void 0, ui?.tbody)"
|
|
639
|
-
:
|
|
640
|
-
:enter-active-class="virtualized ? void 0 : 'nut-dl-row--settling'"
|
|
641
|
-
:enter-from-class="virtualized ? void 0 : 'nut-dl-row--from'"
|
|
642
|
-
:leave-active-class="virtualized ? void 0 : 'hidden'"
|
|
578
|
+
:data-replacing="replacing"
|
|
643
579
|
>
|
|
644
580
|
<tr
|
|
645
581
|
v-if="virtualPaddingTop"
|
|
@@ -647,70 +583,21 @@ defineExpose({ resetColumnSizing });
|
|
|
647
583
|
:style="{ height: `${virtualPaddingTop}px` }"
|
|
648
584
|
aria-hidden="true"
|
|
649
585
|
>
|
|
650
|
-
<td :colspan="
|
|
586
|
+
<td :colspan="columnCount" class="p-0" />
|
|
651
587
|
</tr>
|
|
652
588
|
|
|
653
|
-
<
|
|
589
|
+
<TableRow
|
|
654
590
|
v-for="{ row, virtual } in renderedRows"
|
|
655
591
|
:key="virtual.key"
|
|
656
592
|
:ref="measureRow"
|
|
657
|
-
|
|
658
|
-
:
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
:
|
|
663
|
-
:
|
|
664
|
-
|
|
665
|
-
virtualized && animateEpoch && (virtual.index >= enterFrom || !previousIds.has(String(row.id))) ? {
|
|
666
|
-
'--nut-dl-i': Math.min(
|
|
667
|
-
virtual.index - Math.max(enterFrom, virtualRows[0]?.index ?? 0),
|
|
668
|
-
24
|
|
669
|
-
)
|
|
670
|
-
} : void 0
|
|
671
|
-
"
|
|
672
|
-
>
|
|
673
|
-
<template v-for="slot in rowColumnSlots(row)" :key="slot.key">
|
|
674
|
-
<td
|
|
675
|
-
v-if="slot.kind === 'spacer'"
|
|
676
|
-
:colspan="slot.colSpan"
|
|
677
|
-
class="nut-dl-table__spacer p-0"
|
|
678
|
-
aria-hidden="true"
|
|
679
|
-
/>
|
|
680
|
-
<td
|
|
681
|
-
v-else
|
|
682
|
-
class="nut-dl-td h-[var(--nut-dl-row-h)] py-0 align-middle"
|
|
683
|
-
:class="[
|
|
684
|
-
slot.cell.column.getIsPinned() === 'start' ? 'nut-dl-pin nut-dl-pin--start z-[2]' : '',
|
|
685
|
-
slot.cell.column.getIsPinned() === 'end' ? 'nut-dl-pin nut-dl-pin--end z-[2]' : '',
|
|
686
|
-
isLastStart(slot.cell.column) ? 'nut-dl-pin--last-start' : '',
|
|
687
|
-
isFirstEnd(slot.cell.column) ? 'nut-dl-pin--first-end' : '',
|
|
688
|
-
slot.cell.column.columnDef.meta?.align === 'right' ? 'text-right' : slot.cell.column.columnDef.meta?.align === 'center' ? 'text-center' : '',
|
|
689
|
-
slot.cell.column.columnDef.meta?.internal ? `nut-dl-td--${slot.cell.column.columnDef.meta.internal}` : '',
|
|
690
|
-
slot.cell.column.columnDef.meta?.ellipsis ? 'nut-dl-td--ellipsis' : '',
|
|
691
|
-
mergeDataListUiClass(void 0, void 0, ui?.td)
|
|
692
|
-
]"
|
|
693
|
-
:data-col="slot.cell.column.id"
|
|
694
|
-
:style="[
|
|
695
|
-
pinnedOffset(slot.cell.column),
|
|
696
|
-
slot.cell.column.columnDef.meta?.lines ? { '--nut-dl-lines': slot.cell.column.columnDef.meta.lines } : void 0
|
|
697
|
-
]"
|
|
698
|
-
>
|
|
699
|
-
<div
|
|
700
|
-
class="nut-dl-td__inner min-w-0"
|
|
701
|
-
:class="
|
|
702
|
-
slot.cell.column.columnDef.meta?.align === 'right' ? 'justify-end' : slot.cell.column.columnDef.meta?.align === 'center' ? 'justify-center' : ''
|
|
703
|
-
"
|
|
704
|
-
>
|
|
705
|
-
<TableCell
|
|
706
|
-
:index="virtual.index"
|
|
707
|
-
:render="slot.cell.column.columnDef.meta.render"
|
|
708
|
-
:row="row.original"
|
|
709
|
-
/>
|
|
710
|
-
</div>
|
|
711
|
-
</td>
|
|
712
|
-
</template>
|
|
713
|
-
</tr>
|
|
593
|
+
:row-id="String(row.id)"
|
|
594
|
+
:original="row.original"
|
|
595
|
+
:index="virtual.index"
|
|
596
|
+
:cells="rowCells"
|
|
597
|
+
:selected="internals.selection.isRowSelected({ rowId: String(row.id) })"
|
|
598
|
+
:appended="virtual.index >= appendedFrom"
|
|
599
|
+
:row-class="rowClass"
|
|
600
|
+
/>
|
|
714
601
|
|
|
715
602
|
<tr
|
|
716
603
|
v-if="virtualPaddingBottom"
|
|
@@ -718,7 +605,7 @@ defineExpose({ resetColumnSizing });
|
|
|
718
605
|
:style="{ height: `${virtualPaddingBottom}px` }"
|
|
719
606
|
aria-hidden="true"
|
|
720
607
|
>
|
|
721
|
-
<td :colspan="
|
|
608
|
+
<td :colspan="columnCount" class="p-0" />
|
|
722
609
|
</tr>
|
|
723
610
|
<tr
|
|
724
611
|
v-if="loadingMore"
|
|
@@ -726,10 +613,7 @@ defineExpose({ resetColumnSizing });
|
|
|
726
613
|
class="nut-dl-row nut-dl-row--loading-more"
|
|
727
614
|
aria-hidden="true"
|
|
728
615
|
>
|
|
729
|
-
<td
|
|
730
|
-
:colspan="leafColumns.length"
|
|
731
|
-
class="nut-dl-td h-[var(--nut-dl-row-h)] py-0 align-middle"
|
|
732
|
-
>
|
|
616
|
+
<td :colspan="columnCount" class="nut-dl-td h-[var(--nut-dl-row-h)] py-0 align-middle">
|
|
733
617
|
<div
|
|
734
618
|
class="nut-dl-loading-more flex items-center gap-2.5 px-[var(--nut-dl-gutter)] text-[12.5px] text-muted"
|
|
735
619
|
>
|
|
@@ -745,11 +629,11 @@ defineExpose({ resetColumnSizing });
|
|
|
745
629
|
v-for="placeholder in isFirstLoad ? skeletonRows : 0"
|
|
746
630
|
:key="`skeleton-${placeholder}`"
|
|
747
631
|
class="nut-dl-row nut-dl-row--skeleton"
|
|
748
|
-
:style="{ '--nut-dl-i': placeholder }"
|
|
749
632
|
aria-hidden="true"
|
|
750
633
|
>
|
|
751
634
|
<template v-for="slot in columnSlots" :key="slot.key">
|
|
752
|
-
<td v-if="slot.kind === '
|
|
635
|
+
<td v-if="slot.kind === 'fill'" class="nut-dl-table__fill p-0" />
|
|
636
|
+
<td v-else-if="slot.kind === 'spacer'" :colspan="slot.colSpan" class="p-0" />
|
|
753
637
|
<td
|
|
754
638
|
v-else
|
|
755
639
|
class="nut-dl-td h-[var(--nut-dl-row-h)] py-0 align-middle"
|
|
@@ -762,11 +646,14 @@ defineExpose({ resetColumnSizing });
|
|
|
762
646
|
headerByColumnId.get(slot.columnId) ? pinnedOffset(headerByColumnId.get(slot.columnId).column) : void 0
|
|
763
647
|
"
|
|
764
648
|
>
|
|
765
|
-
<
|
|
649
|
+
<TableSkeletonCell
|
|
650
|
+
v-bind="skeletonColumn(slot.columnId)"
|
|
651
|
+
:seed="placeholder * 7 + slot.columnId.length"
|
|
652
|
+
/>
|
|
766
653
|
</td>
|
|
767
654
|
</template>
|
|
768
655
|
</tr>
|
|
769
|
-
</
|
|
656
|
+
</tbody>
|
|
770
657
|
|
|
771
658
|
<tfoot
|
|
772
659
|
v-if="summaries.enabled.value && !isFirstLoad && !empty"
|
|
@@ -775,7 +662,12 @@ defineExpose({ resetColumnSizing });
|
|
|
775
662
|
<tr class="nut-dl-table__foot-row">
|
|
776
663
|
<template v-for="slot in columnSlots" :key="`foot-${slot.key}`">
|
|
777
664
|
<td
|
|
778
|
-
v-if="slot.kind === '
|
|
665
|
+
v-if="slot.kind === 'fill'"
|
|
666
|
+
class="nut-dl-table__fill nut-dl-tf sticky bottom-0 z-[3] p-0"
|
|
667
|
+
aria-hidden="true"
|
|
668
|
+
/>
|
|
669
|
+
<td
|
|
670
|
+
v-else-if="slot.kind === 'spacer'"
|
|
779
671
|
:colspan="slot.colSpan"
|
|
780
672
|
class="nut-dl-table__spacer nut-dl-tf sticky bottom-0 z-[3] p-0"
|
|
781
673
|
aria-hidden="true"
|
|
@@ -806,6 +698,9 @@ defineExpose({ resetColumnSizing });
|
|
|
806
698
|
<span class="nut-dl-tf__count tabular-nums">{{
|
|
807
699
|
formatNumber(summaries.count.value)
|
|
808
700
|
}}</span>
|
|
701
|
+
<span class="nut-dl-tf__unit -ml-1 font-normal text-muted">{{
|
|
702
|
+
summaryUnit
|
|
703
|
+
}}</span>
|
|
809
704
|
</div>
|
|
810
705
|
<template v-else-if="summaryColumnIds.has(slot.columnId)">
|
|
811
706
|
<span
|
|
@@ -831,26 +726,37 @@ defineExpose({ resetColumnSizing });
|
|
|
831
726
|
|
|
832
727
|
<div
|
|
833
728
|
v-if="error"
|
|
834
|
-
class="nut-dl-table__error sticky left-0 w-full"
|
|
835
|
-
:
|
|
729
|
+
class="nut-dl-table__error sticky left-0 flex w-full flex-col"
|
|
730
|
+
:class="fill || height ? 'min-h-0 flex-1' : ''"
|
|
836
731
|
>
|
|
837
732
|
<slot name="error" :error="error" :retry="refresh">
|
|
838
733
|
<DataListErrorState
|
|
839
|
-
:min-height="fill ?
|
|
734
|
+
:min-height="fill || height ? void 0 : '16rem'"
|
|
840
735
|
:size="resolvedSize"
|
|
736
|
+
class="flex-1"
|
|
841
737
|
@retry="refresh"
|
|
842
738
|
/>
|
|
843
739
|
</slot>
|
|
844
740
|
</div>
|
|
845
|
-
<div
|
|
741
|
+
<div
|
|
742
|
+
v-else-if="empty"
|
|
743
|
+
class="nut-dl-table__empty sticky left-0 flex w-full flex-col"
|
|
744
|
+
:class="fill || height ? 'min-h-0 flex-1' : ''"
|
|
745
|
+
>
|
|
846
746
|
<slot name="empty">
|
|
847
747
|
<TableEmptyState
|
|
848
|
-
:min-height="fill ?
|
|
748
|
+
:min-height="fill || height ? void 0 : '16rem'"
|
|
849
749
|
:size="resolvedSize"
|
|
750
|
+
class="flex-1"
|
|
850
751
|
/>
|
|
851
752
|
</slot>
|
|
852
753
|
</div>
|
|
853
754
|
</div>
|
|
755
|
+
<ProgressLine
|
|
756
|
+
:active="refreshing"
|
|
757
|
+
:restart-key="internals.queryContent.refreshes.value"
|
|
758
|
+
class="absolute inset-x-0 top-[calc(var(--nut-dl-head-h)-1px)] z-[6]"
|
|
759
|
+
/>
|
|
854
760
|
<TableOverlayScrollbars ref="scrollbarsRef" :target="scrollRef" />
|
|
855
761
|
</div>
|
|
856
762
|
</template>
|
|
@@ -858,5 +764,5 @@ defineExpose({ resetColumnSizing });
|
|
|
858
764
|
<style>
|
|
859
765
|
.nut-dl-table{--nut-dl-surface:var(--nut-dl-table-surface,var(--ui-bg-elevated));--nut-dl-line:var(--nut-dl-table-line,var(--ui-border));--nut-dl-line-soft:var(--nut-dl-table-line-soft,var(--ui-border-muted));--nut-dl-head-bg:var(--nut-dl-table-head-bg,var(--ui-bg-muted));--nut-dl-head-fg:var(--nut-dl-table-head-fg,var(--ui-text-muted));--nut-dl-head-font:var(--nut-dl-table-head-font,11px);--nut-dl-head-weight:var(--nut-dl-table-head-weight,600);--nut-dl-head-tracking:var(--nut-dl-table-head-tracking,0.04em);--nut-dl-head-transform:var(--nut-dl-table-head-transform,none);--nut-dl-row-hover:var(--nut-dl-table-row-hover,var(--ui-bg-muted));--nut-dl-row-selected:var(
|
|
860
766
|
--nut-dl-table-row-selected,color-mix(in srgb,var(--ui-primary) 10%,var(--nut-dl-surface))
|
|
861
|
-
);--nut-dl-accent:var(--ui-primary);--nut-dl-cell-fg:var(--nut-dl-table-cell-fg,var(--ui-text-toned));--nut-dl-pin-line:var(--nut-dl-table-pin-line,var(--nut-dl-line))}.nut-dl-table__scroll{overflow-anchor:none;scrollbar-width:none}.nut-dl-table__scroll::-webkit-scrollbar{display:none}.nut-dl-th{color:var(--nut-dl-head-fg);font-size:var(--nut-dl-head-font);font-weight:var(--nut-dl-head-weight);letter-spacing:var(--nut-dl-head-tracking);text-transform:var(--nut-dl-head-transform);-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.nut-dl-table__spacer,.nut-dl-th{border-bottom:1px solid var(--nut-dl-line)}.nut-dl-
|
|
767
|
+
);--nut-dl-accent:var(--ui-primary);--nut-dl-cell-fg:var(--nut-dl-table-cell-fg,var(--ui-text-toned));--nut-dl-pin-line:var(--nut-dl-table-pin-line,var(--nut-dl-line))}.nut-dl-table__scroll{overflow-anchor:none;scrollbar-width:none}.nut-dl-table__scroll::-webkit-scrollbar{display:none}.nut-dl-th{color:var(--nut-dl-head-fg);font-size:var(--nut-dl-head-font);font-weight:var(--nut-dl-head-weight);letter-spacing:var(--nut-dl-head-tracking);text-transform:var(--nut-dl-head-transform);-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.nut-dl-table__fill,.nut-dl-table__spacer,.nut-dl-th{background:var(--nut-dl-head-bg);border-bottom:1px solid var(--nut-dl-line)}.nut-dl-tf{background:var(--nut-dl-head-bg);border-top:1px solid var(--nut-dl-line);color:var(--ui-text-highlighted);font-weight:var(--nut-dl-table-foot-weight,500);white-space:nowrap}tfoot .nut-dl-table__fill,tfoot .nut-dl-table__spacer{border-bottom:0;border-top:1px solid var(--nut-dl-line)}.nut-dl-spinner{animation:nut-dl-spin .8s linear infinite}@keyframes nut-dl-spin{to{transform:rotate(1turn)}}tbody .nut-dl-table__spacer{background:var(--nut-dl-surface);border-bottom:1px solid var(--nut-dl-line-soft)}tbody .nut-dl-table__fill{background:inherit;border-bottom:1px solid var(--nut-dl-line-soft)}.nut-dl-th__btn--open{background:color-mix(in srgb,var(--nut-dl-head-fg) 8%,transparent)}.nut-dl-rz:after{background:var(--ui-border-accented);bottom:10px;content:"";opacity:0;position:absolute;right:0;top:10px;transition:opacity .12s;width:1px}.nut-dl-rz:hover:after,.nut-dl-th:hover .nut-dl-rz:after{opacity:1}.nut-dl-rz--active:after,.nut-dl-rz:hover:after{background:var(--nut-dl-accent);bottom:6px;left:2.5px;opacity:1;top:6px;width:2px}.nut-dl-row{background:var(--nut-dl-surface);transition:background-color .1s}.nut-dl-row:hover{background:var(--nut-dl-row-hover)}.nut-dl-row--selected,.nut-dl-row--selected:hover{background:var(--nut-dl-row-selected)}.nut-dl-td,.nut-dl-tf[data-col],.nut-dl-th__btn,.nut-dl-th__static{padding-left:var(--nut-dl-cell-l,var(--nut-dl-cell-x));padding-right:var(--nut-dl-cell-r,var(--nut-dl-cell-x))}.nut-dl-row>.nut-dl-td:first-child,.nut-dl-table__foot-row>.nut-dl-tf:first-child,.nut-dl-table__head-row>.nut-dl-th:first-child{--nut-dl-cell-l:var(--nut-dl-gutter)}.nut-dl-row>.nut-dl-td:last-child,.nut-dl-table__foot-row>.nut-dl-tf:last-child,.nut-dl-table__head-row>.nut-dl-th:last-child{--nut-dl-cell-r:var(--nut-dl-gutter)}.nut-dl-row>.nut-dl-td--actions:last-child,.nut-dl-table__foot-row>.nut-dl-tf--actions:last-child,.nut-dl-table__head-row>.nut-dl-th--actions:last-child,.nut-dl-td--actions,.nut-dl-tf--actions{--nut-dl-cell-l:var(--nut-dl-cell-x);--nut-dl-cell-r:var(--nut-dl-cell-x)}.nut-dl-td--actions .nut-dl-td__inner{justify-content:flex-end}.nut-dl-td{background:inherit;border-bottom:1px solid var(--nut-dl-line-soft);box-sizing:border-box;color:var(--nut-dl-cell-fg);contain:paint;overflow:hidden;overflow-wrap:anywhere;padding-block:var(--nut-dl-cell-y,6px);white-space:normal}.nut-dl-td__inner{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--nut-dl-lines,3);line-clamp:var(--nut-dl-lines,3);max-height:calc(var(--nut-dl-lines, 3)*1.5em);overflow:hidden}.nut-dl-td--ellipsis{--nut-dl-lines:1;white-space:nowrap}.nut-dl-td--ellipsis .nut-dl-td__inner{display:block;text-overflow:ellipsis}.nut-dl-td--actions .nut-dl-td__inner,.nut-dl-td--selection .nut-dl-td__inner{align-items:center;display:flex}.nut-dl-td--actions,.nut-dl-td--selection{white-space:nowrap}.nut-dl-td--actions .nut-dl-td__inner>*{opacity:.55;transition:opacity .12s}.nut-dl-row:hover .nut-dl-td--actions .nut-dl-td__inner>*{opacity:1}.nut-dl-pin{position:sticky}.nut-dl-pin--first-end:before,.nut-dl-pin--last-start:after{background:var(--nut-dl-line);bottom:0;content:"";pointer-events:none;position:absolute;top:0;width:1px}.nut-dl-pin--last-start:after{right:0}.nut-dl-pin--first-end:before{left:0}.nut-dl-pin--first-end:before,.nut-dl-pin--last-start:after{background:var(--nut-dl-pin-line)}.nut-dl-td--actions.nut-dl-pin--first-end:before,.nut-dl-th--actions.nut-dl-pin--first-end:before{display:none}.nut-dl-skeleton{animation:nut-dl-shimmer 1.6s ease-in-out infinite;animation-delay:calc(var(--nut-dl-i, 0)*-90ms);background:linear-gradient(90deg,var(--ui-bg-accented) 0,var(--ui-bg-muted) 45%,var(--ui-bg-accented) 100%);background-size:200% 100%}.nut-dl-row--skeleton{animation:nut-dl-fade-in .18s ease .12s both}.nut-dl-row--appended{animation:nut-dl-fade-in .2s ease both}.nut-dl-table__body{transition:opacity .16s ease-out}.nut-dl-table__body[data-replacing=true]{opacity:.55;transition:opacity .2s ease-in .18s}@keyframes nut-dl-fade-in{0%{opacity:0}to{opacity:1}}@keyframes nut-dl-shimmer{0%{background-position:100% 0}to{background-position:-100% 0}}@media (prefers-reduced-motion:reduce){.nut-dl-row,.nut-dl-table__body{transition:none}.nut-dl-row--appended,.nut-dl-row--skeleton,.nut-dl-skeleton{animation:none}}
|
|
862
768
|
</style>
|