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
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
import UButton from "@nuxt/ui/components/Button.vue";
|
|
3
3
|
import UIcon from "@nuxt/ui/components/Icon.vue";
|
|
4
4
|
import { useVirtualizer } from "@tanstack/vue-virtual";
|
|
5
|
-
import { computed, nextTick,
|
|
5
|
+
import { computed, nextTick, useTemplateRef, watch } from "vue";
|
|
6
6
|
import { useUiToolsLocale } from "#ui-tools/i18n";
|
|
7
7
|
import { useDataListUi } from "../../composables/use-data-list-ui";
|
|
8
8
|
import { useTableInternals } from "../../composables/use-table-internals";
|
|
9
9
|
import { GRID_DEFAULTS } from "../../constants/grid";
|
|
10
10
|
import { mergeDataListUiClass, resolveTableRowId } from "../../utils";
|
|
11
|
+
import DataListErrorState from "../data-list/data-list-error-state.vue";
|
|
12
|
+
import ProgressLine from "../layout/progress-line.vue";
|
|
11
13
|
import TableEmptyState from "../table/table-empty-state.vue";
|
|
12
14
|
import GridCard from "./grid-card.vue";
|
|
13
15
|
import GridSkeleton from "./grid-skeleton.vue";
|
|
@@ -25,49 +27,9 @@ const resolvedSize = computed(
|
|
|
25
27
|
);
|
|
26
28
|
const gap = computed(() => dataListUi.ui.value.grid?.gap ?? 16);
|
|
27
29
|
const viewportRef = useTemplateRef("viewportRef");
|
|
28
|
-
const animationsReady = ref(false);
|
|
29
30
|
const isContained = computed(() => internals.grid.mode.value === "contained");
|
|
30
31
|
const rowChunks = computed(() => internals.grid.rowChunks.value);
|
|
31
32
|
const tableRows = computed(() => internals.grid.rows.value);
|
|
32
|
-
const flipPositions = /* @__PURE__ */ new Map();
|
|
33
|
-
watch(
|
|
34
|
-
tableRows,
|
|
35
|
-
() => {
|
|
36
|
-
flipPositions.clear();
|
|
37
|
-
if (!isContained.value) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
const items = viewportRef.value?.querySelectorAll(".nut-dl-grid__item[data-row-id]") ?? [];
|
|
41
|
-
for (const item of items) {
|
|
42
|
-
const rect = item.getBoundingClientRect();
|
|
43
|
-
flipPositions.set(item.dataset.rowId ?? "", { left: rect.left, top: rect.top });
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
{ flush: "pre" }
|
|
47
|
-
);
|
|
48
|
-
watch(tableRows, () => nextTick().then(flipCards), { flush: "post" });
|
|
49
|
-
function flipCards() {
|
|
50
|
-
if (!flipPositions.size) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const items = viewportRef.value?.querySelectorAll(".nut-dl-grid__item[data-row-id]") ?? [];
|
|
54
|
-
for (const item of items) {
|
|
55
|
-
const previous = flipPositions.get(item.dataset.rowId ?? "");
|
|
56
|
-
if (!previous) {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
const rect = item.getBoundingClientRect();
|
|
60
|
-
const dx = previous.left - rect.left;
|
|
61
|
-
const dy = previous.top - rect.top;
|
|
62
|
-
if (Math.abs(dx) > 1 || Math.abs(dy) > 1) {
|
|
63
|
-
item.animate([{ transform: `translate(${dx}px, ${dy}px)` }, { transform: "none" }], {
|
|
64
|
-
duration: 240,
|
|
65
|
-
easing: "cubic-bezier(0.2, 0.9, 0.3, 1)"
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
flipPositions.clear();
|
|
70
|
-
}
|
|
71
33
|
const status = computed(() => internals.queryContent.status.value);
|
|
72
34
|
const gridTemplateColumns = computed(
|
|
73
35
|
() => `repeat(${internals.grid.columnCount.value}, minmax(0, 1fr))`
|
|
@@ -81,6 +43,7 @@ const showInitialLoading = computed(
|
|
|
81
43
|
const showRefreshing = computed(
|
|
82
44
|
() => !internals.queryContent.error.value && tableRows.value.length > 0 && (status.value.isFetching || status.value.isRefreshing || status.value.isRevalidating)
|
|
83
45
|
);
|
|
46
|
+
const replacing = computed(() => tableRows.value.length > 0 && status.value.isReplacing);
|
|
84
47
|
const showError = computed(() => Boolean(internals.queryContent.error.value));
|
|
85
48
|
const showEmpty = computed(
|
|
86
49
|
() => !showInitialLoading.value && !showError.value && tableRows.value.length === 0
|
|
@@ -101,15 +64,6 @@ const rowVirtualizer = useVirtualizer(
|
|
|
101
64
|
);
|
|
102
65
|
const virtualRows = computed(() => rowVirtualizer.value.getVirtualItems());
|
|
103
66
|
const totalSize = computed(() => rowVirtualizer.value.getTotalSize());
|
|
104
|
-
onMounted(() => {
|
|
105
|
-
nextTick().then(() => {
|
|
106
|
-
animationsReady.value = true;
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
watch(
|
|
110
|
-
() => internals.pagination.currentPage.value,
|
|
111
|
-
() => scrollToTop()
|
|
112
|
-
);
|
|
113
67
|
watch(
|
|
114
68
|
() => internals.controls.tableLayout.value,
|
|
115
69
|
(layout) => {
|
|
@@ -149,6 +103,29 @@ const loadingMore = computed(
|
|
|
149
103
|
() => cursorMode.value && internals.pagination.state.value.isLoadingMore
|
|
150
104
|
);
|
|
151
105
|
const hasNextPage = computed(() => cursorMode.value && internals.pagination.state.value.hasNextPage);
|
|
106
|
+
let scrollResetPending = false;
|
|
107
|
+
watch(
|
|
108
|
+
() => [
|
|
109
|
+
internals.pagination.currentPage.value,
|
|
110
|
+
internals.pagination.pageSize.value,
|
|
111
|
+
JSON.stringify(internals.tableColumns.sortingState.value),
|
|
112
|
+
JSON.stringify(internals.queryState.filters.value),
|
|
113
|
+
internals.filters.searchQuery.value
|
|
114
|
+
],
|
|
115
|
+
() => {
|
|
116
|
+
if (!cursorMode.value) scrollResetPending = true;
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
function resetScroll() {
|
|
120
|
+
if (!scrollResetPending) return;
|
|
121
|
+
scrollResetPending = false;
|
|
122
|
+
scrollToTop();
|
|
123
|
+
}
|
|
124
|
+
watch(tableRows, resetScroll);
|
|
125
|
+
watch(
|
|
126
|
+
() => status.value.isFetching,
|
|
127
|
+
(fetching) => !fetching && resetScroll()
|
|
128
|
+
);
|
|
152
129
|
watch(
|
|
153
130
|
() => [
|
|
154
131
|
virtualRows.value.at(-1)?.index ?? -1,
|
|
@@ -193,7 +170,7 @@ function refreshData() {
|
|
|
193
170
|
"
|
|
194
171
|
:style="{ '--nut-dl-grid-gap': `${gap}px`, height: !fill && height ? height : void 0 }"
|
|
195
172
|
:data-loading="showInitialLoading"
|
|
196
|
-
:data-
|
|
173
|
+
:data-replacing="replacing"
|
|
197
174
|
>
|
|
198
175
|
<div
|
|
199
176
|
ref="viewportRef"
|
|
@@ -225,48 +202,20 @@ function refreshData() {
|
|
|
225
202
|
v-else-if="showError"
|
|
226
203
|
:class="
|
|
227
204
|
mergeDataListUiClass(
|
|
228
|
-
'nut-dl-grid__state flex
|
|
205
|
+
'nut-dl-grid__state flex h-full flex-col items-stretch justify-center',
|
|
229
206
|
void 0,
|
|
230
207
|
ui?.error
|
|
231
208
|
)
|
|
232
209
|
"
|
|
233
210
|
>
|
|
234
|
-
<
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
'grid max-w-md justify-items-center gap-3 rounded-lg border border-default bg-default px-6 py-8 text-center',
|
|
238
|
-
void 0,
|
|
239
|
-
ui?.errorCard
|
|
240
|
-
)
|
|
241
|
-
"
|
|
242
|
-
>
|
|
243
|
-
<UIcon
|
|
244
|
-
name="i-lucide-cloud-alert"
|
|
245
|
-
:class="mergeDataListUiClass('size-5 text-error', void 0, ui?.errorIcon)"
|
|
246
|
-
/>
|
|
247
|
-
<div :class="mergeDataListUiClass('grid gap-1', void 0, ui?.errorCopy)">
|
|
248
|
-
<div
|
|
249
|
-
:class="
|
|
250
|
-
mergeDataListUiClass('font-medium text-highlighted', void 0, ui?.errorTitle)
|
|
251
|
-
"
|
|
252
|
-
>
|
|
253
|
-
{{ t("table.states.gridError.title") }}
|
|
254
|
-
</div>
|
|
255
|
-
<p :class="mergeDataListUiClass('text-sm text-muted', void 0, ui?.errorDescription)">
|
|
256
|
-
{{ t("table.states.gridError.description") }}
|
|
257
|
-
</p>
|
|
258
|
-
</div>
|
|
259
|
-
<UButton
|
|
260
|
-
color="neutral"
|
|
261
|
-
variant="outline"
|
|
211
|
+
<slot name="error" :error="internals.queryContent.error.value" :retry="refreshData">
|
|
212
|
+
<DataListErrorState
|
|
213
|
+
:min-height="fill ? void 0 : '16rem'"
|
|
262
214
|
:size="resolvedSize"
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
{{ t("table.states.gridError.action") }}
|
|
268
|
-
</UButton>
|
|
269
|
-
</div>
|
|
215
|
+
class="flex-1"
|
|
216
|
+
@retry="refreshData"
|
|
217
|
+
/>
|
|
218
|
+
</slot>
|
|
270
219
|
</div>
|
|
271
220
|
|
|
272
221
|
<div
|
|
@@ -280,7 +229,7 @@ function refreshData() {
|
|
|
280
229
|
"
|
|
281
230
|
>
|
|
282
231
|
<slot name="empty">
|
|
283
|
-
<TableEmptyState min-height="24rem" :size="resolvedSize" />
|
|
232
|
+
<TableEmptyState :min-height="fill ? void 0 : '24rem'" :size="resolvedSize" />
|
|
284
233
|
</slot>
|
|
285
234
|
</div>
|
|
286
235
|
|
|
@@ -320,16 +269,10 @@ function refreshData() {
|
|
|
320
269
|
</div>
|
|
321
270
|
</div>
|
|
322
271
|
|
|
323
|
-
<
|
|
272
|
+
<div
|
|
324
273
|
v-else
|
|
325
|
-
tag="div"
|
|
326
274
|
:class="mergeDataListUiClass('nut-dl-grid__flow grid', void 0, ui?.flow)"
|
|
327
275
|
:style="{ gridTemplateColumns, gap: `${gap}px` }"
|
|
328
|
-
move-class="nut-dl-grid__item--moving"
|
|
329
|
-
enter-active-class="nut-dl-grid__item--entering"
|
|
330
|
-
enter-from-class="nut-dl-grid__item--from"
|
|
331
|
-
leave-active-class="nut-dl-grid__item--leaving"
|
|
332
|
-
leave-to-class="nut-dl-grid__item--from"
|
|
333
276
|
>
|
|
334
277
|
<div
|
|
335
278
|
v-for="(row, index) in tableRows"
|
|
@@ -339,7 +282,7 @@ function refreshData() {
|
|
|
339
282
|
>
|
|
340
283
|
<GridCard :row-index="index" />
|
|
341
284
|
</div>
|
|
342
|
-
</
|
|
285
|
+
</div>
|
|
343
286
|
</div>
|
|
344
287
|
|
|
345
288
|
<div
|
|
@@ -353,32 +296,21 @@ function refreshData() {
|
|
|
353
296
|
<span>{{ t("table.controls.loadingMore") }}</span>
|
|
354
297
|
</div>
|
|
355
298
|
|
|
356
|
-
<
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
299
|
+
<ProgressLine
|
|
300
|
+
:active="showRefreshing"
|
|
301
|
+
:restart-key="internals.queryContent.refreshes.value"
|
|
302
|
+
:class="
|
|
360
303
|
mergeDataListUiClass(
|
|
361
|
-
'nut-dl-grid__progress
|
|
304
|
+
'nut-dl-grid__progress absolute inset-x-0 top-0 z-10',
|
|
362
305
|
void 0,
|
|
363
306
|
ui?.refreshing
|
|
364
307
|
)
|
|
365
308
|
"
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
<span
|
|
369
|
-
:class="
|
|
370
|
-
mergeDataListUiClass(
|
|
371
|
-
'nut-dl-grid__progress-bar block h-full w-full',
|
|
372
|
-
void 0,
|
|
373
|
-
ui?.refreshingLine
|
|
374
|
-
)
|
|
375
|
-
"
|
|
376
|
-
/>
|
|
377
|
-
</div>
|
|
378
|
-
</Transition>
|
|
309
|
+
:bar-class="mergeDataListUiClass('nut-dl-grid__progress-bar', void 0, ui?.refreshingLine)"
|
|
310
|
+
/>
|
|
379
311
|
</div>
|
|
380
312
|
</template>
|
|
381
313
|
|
|
382
314
|
<style>
|
|
383
|
-
.nut-dl-grid__skeleton{animation:nut-dl-grid-in .
|
|
315
|
+
.nut-dl-grid__skeleton{animation:nut-dl-grid-in .18s ease .12s both}.nut-dl-grid__viewport{overflow-anchor:none;scrollbar-width:thin}.nut-dl-grid__canvas,.nut-dl-grid__flow{transition:opacity .16s ease-out}.nut-dl-grid[data-replacing=true] .nut-dl-grid__canvas,.nut-dl-grid[data-replacing=true] .nut-dl-grid__flow{opacity:.55;transition:opacity .2s ease-in .18s}@keyframes nut-dl-grid-in{0%{opacity:0}to{opacity:1}}@media (prefers-reduced-motion:reduce){.nut-dl-grid__skeleton{animation:none}.nut-dl-grid__canvas,.nut-dl-grid__flow{transition:none}}
|
|
384
316
|
</style>
|
|
@@ -5,9 +5,15 @@ type __VLS_Props = {
|
|
|
5
5
|
fill?: boolean;
|
|
6
6
|
ui?: DataListGridUi;
|
|
7
7
|
};
|
|
8
|
-
declare
|
|
8
|
+
declare function refreshData(): void;
|
|
9
|
+
declare var __VLS_6: {
|
|
10
|
+
error: unknown;
|
|
11
|
+
retry: typeof refreshData;
|
|
12
|
+
}, __VLS_15: {};
|
|
9
13
|
type __VLS_Slots = {} & {
|
|
10
|
-
|
|
14
|
+
error?: (props: typeof __VLS_6) => any;
|
|
15
|
+
} & {
|
|
16
|
+
empty?: (props: typeof __VLS_15) => any;
|
|
11
17
|
};
|
|
12
18
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
19
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
active: boolean;
|
|
3
|
+
/** Changes on every refresh request, so the sweep restarts even while a request is running. */
|
|
4
|
+
restartKey?: number;
|
|
5
|
+
barClass?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { onBeforeUnmount, ref, watch } from "vue";
|
|
3
|
+
const MIN_VISIBLE_MS = 600;
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
active: { type: Boolean, required: true },
|
|
6
|
+
restartKey: { type: Number, required: false },
|
|
7
|
+
barClass: { type: String, required: false }
|
|
8
|
+
});
|
|
9
|
+
const visible = ref(props.active);
|
|
10
|
+
const sweep = ref(0);
|
|
11
|
+
let shownAt = Date.now();
|
|
12
|
+
let hideTimer;
|
|
13
|
+
watch([() => props.active, () => props.restartKey], ([active, key], [wasActive, previousKey]) => {
|
|
14
|
+
clearTimeout(hideTimer);
|
|
15
|
+
if (active) {
|
|
16
|
+
if (!wasActive || key !== previousKey) {
|
|
17
|
+
sweep.value += 1;
|
|
18
|
+
shownAt = Date.now();
|
|
19
|
+
}
|
|
20
|
+
visible.value = true;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
hideTimer = setTimeout(
|
|
24
|
+
() => visible.value = false,
|
|
25
|
+
Math.max(0, MIN_VISIBLE_MS - (Date.now() - shownAt))
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
onBeforeUnmount(() => clearTimeout(hideTimer));
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<div
|
|
33
|
+
class="nut-dl-progress pointer-events-none h-0.5 overflow-hidden"
|
|
34
|
+
:data-active="visible"
|
|
35
|
+
aria-hidden="true"
|
|
36
|
+
>
|
|
37
|
+
<span :key="sweep" class="nut-dl-progress__bar block h-full" :class="barClass" />
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<style>
|
|
42
|
+
.nut-dl-progress{opacity:0;transition:opacity .24s ease-out}.nut-dl-progress[data-active=true]{opacity:1;transition-duration:.12s}.nut-dl-progress__bar{animation:nut-dl-progress-slide .8s cubic-bezier(.65,0,.35,1) infinite paused;background:var(--nut-dl-progress-color,var(--ui-primary));border-radius:999px;width:34%}.nut-dl-progress[data-active=true] .nut-dl-progress__bar{animation-play-state:running}@keyframes nut-dl-progress-slide{0%{transform:translateX(-100%)}to{transform:translateX(300%)}}@media (prefers-reduced-motion:reduce){.nut-dl-progress__bar{animation:none;width:100%}}
|
|
43
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
active: boolean;
|
|
3
|
+
/** Changes on every refresh request, so the sweep restarts even while a request is running. */
|
|
4
|
+
restartKey?: number;
|
|
5
|
+
barClass?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -7,7 +7,7 @@ import { useDataListUi } from "../../composables/use-data-list-ui";
|
|
|
7
7
|
import { useTableInternals } from "../../composables/use-table-internals";
|
|
8
8
|
import { mergeDataListUiClass } from "../../utils";
|
|
9
9
|
const props = defineProps({
|
|
10
|
-
minHeight: { type: String, required:
|
|
10
|
+
minHeight: { type: String, required: false },
|
|
11
11
|
size: { type: String, required: false }
|
|
12
12
|
});
|
|
13
13
|
const { t } = useUiToolsLocale();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { HTMLAttributes, StyleValue } from 'vue';
|
|
2
|
+
import type { DataListColumnMeta } from '../../utils/columns/types.js';
|
|
3
|
+
/** One position in the rendered column window: a column, a spacer for virtualized columns, or the filler. */
|
|
4
|
+
export type TableColumnSlot = {
|
|
5
|
+
kind: 'column';
|
|
6
|
+
columnId: string;
|
|
7
|
+
key: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'spacer';
|
|
10
|
+
colSpan: number;
|
|
11
|
+
key: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'fill';
|
|
14
|
+
key: string;
|
|
15
|
+
};
|
|
16
|
+
/** Cell classes, styles and renderer of one column, computed once per layout change for every row. */
|
|
17
|
+
export declare function columnCellLayout(params: {
|
|
18
|
+
meta?: DataListColumnMeta;
|
|
19
|
+
pinned: false | 'start' | 'end';
|
|
20
|
+
lastStart: boolean;
|
|
21
|
+
firstEnd: boolean;
|
|
22
|
+
offset: StyleValue;
|
|
23
|
+
tdClass: HTMLAttributes['class'];
|
|
24
|
+
}): {
|
|
25
|
+
class: import("vue").ClassValue[];
|
|
26
|
+
innerClass: string;
|
|
27
|
+
render: ((params: {
|
|
28
|
+
row: import("../../types/index.js").GenericObject;
|
|
29
|
+
index: number;
|
|
30
|
+
}) => import("vue").VNodeChild) | undefined;
|
|
31
|
+
style: StyleValue[];
|
|
32
|
+
};
|
|
33
|
+
/** The column window with each column's cell layout attached, shared by every rendered row. */
|
|
34
|
+
export declare function tableRowCells(params: {
|
|
35
|
+
slots: TableColumnSlot[];
|
|
36
|
+
layouts: Map<string, ReturnType<typeof columnCellLayout>>;
|
|
37
|
+
}): ({
|
|
38
|
+
kind: "spacer";
|
|
39
|
+
colSpan: number;
|
|
40
|
+
key: string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "fill";
|
|
43
|
+
key: string;
|
|
44
|
+
} | {
|
|
45
|
+
layout: {
|
|
46
|
+
class: import("vue").ClassValue[];
|
|
47
|
+
innerClass: string;
|
|
48
|
+
render: ((params: {
|
|
49
|
+
row: import("../../types/index.js").GenericObject;
|
|
50
|
+
index: number;
|
|
51
|
+
}) => import("vue").VNodeChild) | undefined;
|
|
52
|
+
style: StyleValue[];
|
|
53
|
+
} | undefined;
|
|
54
|
+
kind: "column";
|
|
55
|
+
columnId: string;
|
|
56
|
+
key: string;
|
|
57
|
+
})[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function columnCellLayout(params) {
|
|
2
|
+
const { meta } = params;
|
|
3
|
+
return {
|
|
4
|
+
class: [
|
|
5
|
+
params.pinned === "start" ? "nut-dl-pin nut-dl-pin--start z-[2]" : "",
|
|
6
|
+
params.pinned === "end" ? "nut-dl-pin nut-dl-pin--end z-[2]" : "",
|
|
7
|
+
params.lastStart ? "nut-dl-pin--last-start" : "",
|
|
8
|
+
params.firstEnd ? "nut-dl-pin--first-end" : "",
|
|
9
|
+
meta?.align === "right" ? "text-right" : meta?.align === "center" ? "text-center" : "",
|
|
10
|
+
meta?.internal ? `nut-dl-td--${meta.internal}` : "",
|
|
11
|
+
meta?.ellipsis ? "nut-dl-td--ellipsis" : "",
|
|
12
|
+
params.tdClass
|
|
13
|
+
],
|
|
14
|
+
innerClass: meta?.align === "right" ? "justify-end" : meta?.align === "center" ? "justify-center" : "",
|
|
15
|
+
render: meta?.render,
|
|
16
|
+
style: [params.offset, meta?.lines ? { "--nut-dl-lines": meta.lines } : void 0]
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function tableRowCells(params) {
|
|
20
|
+
return params.slots.map(
|
|
21
|
+
(slot) => slot.kind === "column" ? { ...slot, layout: params.layouts.get(slot.columnId) } : slot
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DataListControlSize, DataListTableUi } from '../../types/index.js';
|
|
2
|
+
import type { TableColumnSlot } from './table-layout.js';
|
|
2
3
|
type __VLS_Props = {
|
|
3
4
|
gutter?: number;
|
|
4
5
|
height?: string;
|
|
@@ -7,17 +8,8 @@ type __VLS_Props = {
|
|
|
7
8
|
ui?: DataListTableUi;
|
|
8
9
|
};
|
|
9
10
|
declare function refresh(): void;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
columnId: string;
|
|
13
|
-
key: string;
|
|
14
|
-
} | {
|
|
15
|
-
kind: 'spacer';
|
|
16
|
-
colSpan: number;
|
|
17
|
-
key: string;
|
|
18
|
-
};
|
|
19
|
-
declare var __VLS_34: {
|
|
20
|
-
columnSlots: ColumnSlot[];
|
|
11
|
+
declare var __VLS_28: {
|
|
12
|
+
columnSlots: TableColumnSlot[];
|
|
21
13
|
leafColumns: import("@tanstack/table-core").Column<{
|
|
22
14
|
columnPinningFeature: import("@tanstack/table-core").TableFeature;
|
|
23
15
|
columnResizingFeature: import("@tanstack/table-core").TableFeature;
|
|
@@ -26,16 +18,16 @@ declare var __VLS_34: {
|
|
|
26
18
|
coreRowModel: (table: import("@tanstack/table-core").Table<any, any>) => () => import("@tanstack/table-core").RowModel<any, any>;
|
|
27
19
|
columnMeta: import("../../utils/index.js").DataListColumnMeta;
|
|
28
20
|
}, object, unknown>[];
|
|
29
|
-
},
|
|
21
|
+
}, __VLS_30: {
|
|
30
22
|
error: {};
|
|
31
23
|
retry: typeof refresh;
|
|
32
|
-
},
|
|
24
|
+
}, __VLS_39: {};
|
|
33
25
|
type __VLS_Slots = {} & {
|
|
34
|
-
footer?: (props: typeof
|
|
26
|
+
footer?: (props: typeof __VLS_28) => any;
|
|
35
27
|
} & {
|
|
36
|
-
error?: (props: typeof
|
|
28
|
+
error?: (props: typeof __VLS_30) => any;
|
|
37
29
|
} & {
|
|
38
|
-
empty?: (props: typeof
|
|
30
|
+
empty?: (props: typeof __VLS_39) => any;
|
|
39
31
|
};
|
|
40
32
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
41
33
|
resetColumnSizing: () => void;
|