nuxt-ui-tools 1.4.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.
Files changed (97) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +3 -1
  3. package/dist/runtime/dashboard/composables/use-dashboard-remote-options.js +8 -3
  4. package/dist/runtime/dashboard/types/filters.d.ts +7 -1
  5. package/dist/runtime/dashboard/utils/builders/dashboard-filters.js +19 -2
  6. package/dist/runtime/form/composables/use-field-options.js +19 -0
  7. package/dist/runtime/form/composables/use-remote-field-options.js +21 -2
  8. package/dist/runtime/form/types/options.d.ts +22 -2
  9. package/dist/runtime/i18n/locales/en.js +23 -2
  10. package/dist/runtime/i18n/locales/fr.js +23 -2
  11. package/dist/runtime/i18n/types.d.ts +21 -0
  12. package/dist/runtime/shared/index.d.ts +1 -0
  13. package/dist/runtime/shared/index.js +1 -0
  14. package/dist/runtime/shared/types/query.d.ts +5 -1
  15. package/dist/runtime/shared/types/remote-options.d.ts +56 -0
  16. package/dist/runtime/shared/utils/define-remote-options.d.ts +23 -0
  17. package/dist/runtime/shared/utils/define-remote-options.js +24 -0
  18. package/dist/runtime/shared/utils/remote-options-query.d.ts +6 -0
  19. package/dist/runtime/shared/utils/remote-options-query.js +18 -0
  20. package/dist/runtime/table/components/data-list/data-list-content.vue +7 -1
  21. package/dist/runtime/table/components/data-list/data-list-error-state.d.vue.ts +18 -1
  22. package/dist/runtime/table/components/data-list/data-list-error-state.vue +65 -41
  23. package/dist/runtime/table/components/data-list/data-list-error-state.vue.d.ts +18 -1
  24. package/dist/runtime/table/components/data-list/data-list-filter-tags.d.vue.ts +1 -1
  25. package/dist/runtime/table/components/data-list/data-list-filter-tags.vue +1 -1
  26. package/dist/runtime/table/components/data-list/data-list-filter-tags.vue.d.ts +1 -1
  27. package/dist/runtime/table/components/data-list/sort-menu-panel.vue +33 -25
  28. package/dist/runtime/table/components/drawers/column-panel.vue +19 -6
  29. package/dist/runtime/table/components/filters/panel/filter-panel.vue +14 -2
  30. package/dist/runtime/table/components/filters/shared/dynamic-filter-picker.vue +1 -1
  31. package/dist/runtime/table/components/filters/shared/filter-editor-header.d.vue.ts +16 -0
  32. package/dist/runtime/table/components/filters/shared/filter-editor-header.vue +46 -0
  33. package/dist/runtime/table/components/filters/shared/filter-editor-header.vue.d.ts +16 -0
  34. package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.d.vue.ts +3 -1
  35. package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue +6 -5
  36. package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue.d.ts +3 -1
  37. package/dist/runtime/table/components/filters/shared/filter-option-picker-content.vue +4 -1
  38. package/dist/runtime/table/components/filters/shared/filter-option-single-list.vue +4 -4
  39. package/dist/runtime/table/components/filters/shared/filter-option-tree-content.vue +12 -8
  40. package/dist/runtime/table/components/filters/shared/filter-popover-shell.vue +10 -1
  41. package/dist/runtime/table/components/filters/shared/filter-searchable-panel.vue +14 -6
  42. package/dist/runtime/table/components/filters/shared/filter-trigger-tag.vue +12 -2
  43. package/dist/runtime/table/components/filters/tags/boolean-filter-tag.d.vue.ts +6 -1
  44. package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue +19 -5
  45. package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue.d.ts +6 -1
  46. package/dist/runtime/table/components/filters/tags/date-filter-tag.d.vue.ts +6 -1
  47. package/dist/runtime/table/components/filters/tags/date-filter-tag.vue +65 -29
  48. package/dist/runtime/table/components/filters/tags/date-filter-tag.vue.d.ts +6 -1
  49. package/dist/runtime/table/components/filters/tags/number-filter-tag.d.vue.ts +6 -1
  50. package/dist/runtime/table/components/filters/tags/number-filter-tag.vue +66 -18
  51. package/dist/runtime/table/components/filters/tags/number-filter-tag.vue.d.ts +6 -1
  52. package/dist/runtime/table/components/filters/tags/option-filter-tag.d.vue.ts +2 -2
  53. package/dist/runtime/table/components/filters/tags/option-filter-tag.vue +10 -34
  54. package/dist/runtime/table/components/filters/tags/option-filter-tag.vue.d.ts +2 -2
  55. package/dist/runtime/table/components/filters/tags/text-filter-tag.d.vue.ts +6 -1
  56. package/dist/runtime/table/components/filters/tags/text-filter-tag.vue +39 -14
  57. package/dist/runtime/table/components/filters/tags/text-filter-tag.vue.d.ts +6 -1
  58. package/dist/runtime/table/components/grid/grid-renderer.d.vue.ts +8 -2
  59. package/dist/runtime/table/components/grid/grid-renderer.vue +47 -115
  60. package/dist/runtime/table/components/grid/grid-renderer.vue.d.ts +8 -2
  61. package/dist/runtime/table/components/layout/progress-line.d.vue.ts +9 -0
  62. package/dist/runtime/table/components/layout/progress-line.vue +43 -0
  63. package/dist/runtime/table/components/layout/progress-line.vue.d.ts +9 -0
  64. package/dist/runtime/table/components/table/table-empty-state.d.vue.ts +1 -1
  65. package/dist/runtime/table/components/table/table-empty-state.vue +1 -1
  66. package/dist/runtime/table/components/table/table-empty-state.vue.d.ts +1 -1
  67. package/dist/runtime/table/components/table/table-layout.d.ts +57 -0
  68. package/dist/runtime/table/components/table/table-layout.js +23 -0
  69. package/dist/runtime/table/components/table/table-renderer.d.vue.ts +8 -16
  70. package/dist/runtime/table/components/table/table-renderer.vue +180 -274
  71. package/dist/runtime/table/components/table/table-renderer.vue.d.ts +8 -16
  72. package/dist/runtime/table/components/table/table-row.d.vue.ts +19 -0
  73. package/dist/runtime/table/components/table/table-row.vue +51 -0
  74. package/dist/runtime/table/components/table/table-row.vue.d.ts +19 -0
  75. package/dist/runtime/table/components/table/table-skeleton-cell.d.ts +9 -0
  76. package/dist/runtime/table/components/table/table-skeleton-cell.js +104 -0
  77. package/dist/runtime/table/components/utils/search-query-input.vue +27 -1
  78. package/dist/runtime/table/composables/use-deferred-commit.d.ts +20 -0
  79. package/dist/runtime/table/composables/use-deferred-commit.js +31 -0
  80. package/dist/runtime/table/composables/use-table-data.d.ts +5 -1
  81. package/dist/runtime/table/composables/use-table-data.js +20 -2
  82. package/dist/runtime/table/composables/use-table-filter-selected-options.js +16 -1
  83. package/dist/runtime/table/composables/use-table-summaries.js +10 -1
  84. package/dist/runtime/table/types/columns.d.ts +15 -1
  85. package/dist/runtime/table/types/data-list.d.ts +1 -0
  86. package/dist/runtime/table/types/filters.d.ts +7 -0
  87. package/dist/runtime/table/types/remote-options.d.ts +3 -16
  88. package/dist/runtime/table/utils/columns/defs.js +1 -1
  89. package/dist/runtime/table/utils/filters/date.d.ts +6 -0
  90. package/dist/runtime/table/utils/filters/date.js +26 -2
  91. package/dist/runtime/table/utils/filters/index.d.ts +1 -0
  92. package/dist/runtime/table/utils/filters/index.js +1 -0
  93. package/dist/runtime/table/utils/filters/number.d.ts +5 -0
  94. package/dist/runtime/table/utils/filters/number.js +11 -0
  95. package/dist/runtime/table/utils/filters/ui.js +5 -5
  96. package/dist/runtime/table/utils/remote-table-options.js +37 -37
  97. 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, onMounted, ref, useTemplateRef, watch } from "vue";
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-animated="animationsReady"
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 items-center justify-center px-4 py-10',
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
- <div
235
- :class="
236
- mergeDataListUiClass(
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
- icon="i-lucide-refresh-cw"
264
- :ui="{ base: ui?.retry }"
265
- @click="refreshData"
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
- <TransitionGroup
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
- </TransitionGroup>
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
- <Transition name="nut-dl-grid-progress">
357
- <div
358
- v-if="showRefreshing"
359
- :class="
299
+ <ProgressLine
300
+ :active="showRefreshing"
301
+ :restart-key="internals.queryContent.refreshes.value"
302
+ :class="
360
303
  mergeDataListUiClass(
361
- 'nut-dl-grid__progress pointer-events-none absolute inset-x-0 top-0 z-10 h-0.5 overflow-hidden',
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
- aria-hidden="true"
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 .2s ease both;animation-delay:calc(var(--nut-dl-i, 0)*30ms)}.nut-dl-grid__viewport{overflow-anchor:none;scrollbar-width:thin}.nut-dl-grid[data-animated=true] .nut-dl-grid__item{animation:nut-dl-grid-in .22s cubic-bezier(.2,.9,.3,1) both}.nut-dl-grid__item--moving{transition:transform .24s cubic-bezier(.2,.9,.3,1)}.nut-dl-grid__item--entering{transition:opacity .18s ease,transform .24s cubic-bezier(.2,.9,.3,1)}.nut-dl-grid__item--leaving{position:absolute;transition:opacity .14s ease,transform .14s ease}.nut-dl-grid__item--from{opacity:0;transform:translateY(6px)}@keyframes nut-dl-grid-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}.nut-dl-grid__progress-bar{animation:nut-dl-grid-progress 1s ease-in-out infinite;background:linear-gradient(90deg,transparent,var(--ui-primary),transparent);background-size:40% 100%}@keyframes nut-dl-grid-progress{0%{background-position:-40% 0}to{background-position:140% 0}}.nut-dl-grid-progress-enter-active,.nut-dl-grid-progress-leave-active{transition:opacity .16s ease}.nut-dl-grid-progress-enter-from,.nut-dl-grid-progress-leave-to{opacity:0}@media (prefers-reduced-motion:reduce){.nut-dl-grid[data-animated=true] .nut-dl-grid__item,.nut-dl-grid__progress-bar{animation:none}.nut-dl-grid__item--entering,.nut-dl-grid__item--leaving,.nut-dl-grid__item--moving{transition:none}}
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 var __VLS_19: {};
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
- empty?: (props: typeof __VLS_19) => any;
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;
@@ -1,6 +1,6 @@
1
1
  import type { DataListControlSize } from '../../types/index.js';
2
2
  type __VLS_Props = {
3
- minHeight: string;
3
+ minHeight?: string;
4
4
  size?: DataListControlSize;
5
5
  };
6
6
  declare var __VLS_6: {};
@@ -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: true },
10
+ minHeight: { type: String, required: false },
11
11
  size: { type: String, required: false }
12
12
  });
13
13
  const { t } = useUiToolsLocale();
@@ -1,6 +1,6 @@
1
1
  import type { DataListControlSize } from '../../types/index.js';
2
2
  type __VLS_Props = {
3
- minHeight: string;
3
+ minHeight?: string;
4
4
  size?: DataListControlSize;
5
5
  };
6
6
  declare var __VLS_6: {};
@@ -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
- type ColumnSlot = {
11
- kind: 'column';
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
- }, __VLS_36: {
21
+ }, __VLS_30: {
30
22
  error: {};
31
23
  retry: typeof refresh;
32
- }, __VLS_45: {};
24
+ }, __VLS_39: {};
33
25
  type __VLS_Slots = {} & {
34
- footer?: (props: typeof __VLS_34) => any;
26
+ footer?: (props: typeof __VLS_28) => any;
35
27
  } & {
36
- error?: (props: typeof __VLS_36) => any;
28
+ error?: (props: typeof __VLS_30) => any;
37
29
  } & {
38
- empty?: (props: typeof __VLS_45) => any;
30
+ empty?: (props: typeof __VLS_39) => any;
39
31
  };
40
32
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
41
33
  resetColumnSizing: () => void;