nuxt-ui-tools 1.5.0 → 1.6.1

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 (76) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +1 -0
  3. package/dist/runtime/i18n/locales/en.js +23 -2
  4. package/dist/runtime/i18n/locales/fr.js +23 -2
  5. package/dist/runtime/i18n/types.d.ts +21 -0
  6. package/dist/runtime/table/components/data-list/data-list-content.vue +7 -1
  7. package/dist/runtime/table/components/data-list/data-list-error-state.d.vue.ts +18 -1
  8. package/dist/runtime/table/components/data-list/data-list-error-state.vue +65 -41
  9. package/dist/runtime/table/components/data-list/data-list-error-state.vue.d.ts +18 -1
  10. package/dist/runtime/table/components/data-list/sort-menu-panel.vue +33 -25
  11. package/dist/runtime/table/components/drawers/column-panel.vue +19 -6
  12. package/dist/runtime/table/components/filters/shared/dynamic-filter-picker.vue +1 -1
  13. package/dist/runtime/table/components/filters/shared/filter-editor-header.d.vue.ts +16 -0
  14. package/dist/runtime/table/components/filters/shared/filter-editor-header.vue +46 -0
  15. package/dist/runtime/table/components/filters/shared/filter-editor-header.vue.d.ts +16 -0
  16. package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.d.vue.ts +3 -1
  17. package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue +5 -4
  18. package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue.d.ts +3 -1
  19. package/dist/runtime/table/components/filters/shared/filter-option-picker-content.vue +4 -1
  20. package/dist/runtime/table/components/filters/shared/filter-option-single-list.vue +3 -3
  21. package/dist/runtime/table/components/filters/shared/filter-option-tree-content.vue +7 -3
  22. package/dist/runtime/table/components/filters/shared/filter-popover-shell.vue +10 -1
  23. package/dist/runtime/table/components/filters/shared/filter-searchable-panel.vue +14 -6
  24. package/dist/runtime/table/components/filters/shared/filter-trigger-tag.vue +5 -1
  25. package/dist/runtime/table/components/filters/tags/boolean-filter-tag.d.vue.ts +6 -1
  26. package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue +19 -5
  27. package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue.d.ts +6 -1
  28. package/dist/runtime/table/components/filters/tags/date-filter-tag.d.vue.ts +6 -1
  29. package/dist/runtime/table/components/filters/tags/date-filter-tag.vue +65 -29
  30. package/dist/runtime/table/components/filters/tags/date-filter-tag.vue.d.ts +6 -1
  31. package/dist/runtime/table/components/filters/tags/number-filter-tag.d.vue.ts +6 -1
  32. package/dist/runtime/table/components/filters/tags/number-filter-tag.vue +66 -18
  33. package/dist/runtime/table/components/filters/tags/number-filter-tag.vue.d.ts +6 -1
  34. package/dist/runtime/table/components/filters/tags/option-filter-tag.d.vue.ts +2 -2
  35. package/dist/runtime/table/components/filters/tags/option-filter-tag.vue +10 -34
  36. package/dist/runtime/table/components/filters/tags/option-filter-tag.vue.d.ts +2 -2
  37. package/dist/runtime/table/components/filters/tags/text-filter-tag.d.vue.ts +6 -1
  38. package/dist/runtime/table/components/filters/tags/text-filter-tag.vue +39 -14
  39. package/dist/runtime/table/components/filters/tags/text-filter-tag.vue.d.ts +6 -1
  40. package/dist/runtime/table/components/grid/grid-renderer.d.vue.ts +8 -2
  41. package/dist/runtime/table/components/grid/grid-renderer.vue +47 -115
  42. package/dist/runtime/table/components/grid/grid-renderer.vue.d.ts +8 -2
  43. package/dist/runtime/table/components/layout/progress-line.d.vue.ts +9 -0
  44. package/dist/runtime/table/components/layout/progress-line.vue +43 -0
  45. package/dist/runtime/table/components/layout/progress-line.vue.d.ts +9 -0
  46. package/dist/runtime/table/components/table/table-empty-state.d.vue.ts +1 -1
  47. package/dist/runtime/table/components/table/table-empty-state.vue +1 -1
  48. package/dist/runtime/table/components/table/table-empty-state.vue.d.ts +1 -1
  49. package/dist/runtime/table/components/table/table-layout.d.ts +57 -0
  50. package/dist/runtime/table/components/table/table-layout.js +23 -0
  51. package/dist/runtime/table/components/table/table-renderer.d.vue.ts +8 -16
  52. package/dist/runtime/table/components/table/table-renderer.vue +180 -274
  53. package/dist/runtime/table/components/table/table-renderer.vue.d.ts +8 -16
  54. package/dist/runtime/table/components/table/table-row.d.vue.ts +19 -0
  55. package/dist/runtime/table/components/table/table-row.vue +51 -0
  56. package/dist/runtime/table/components/table/table-row.vue.d.ts +19 -0
  57. package/dist/runtime/table/components/table/table-skeleton-cell.d.ts +9 -0
  58. package/dist/runtime/table/components/table/table-skeleton-cell.js +104 -0
  59. package/dist/runtime/table/components/utils/search-query-input.vue +27 -1
  60. package/dist/runtime/table/composables/use-deferred-commit.d.ts +20 -0
  61. package/dist/runtime/table/composables/use-deferred-commit.js +31 -0
  62. package/dist/runtime/table/composables/use-table-data.d.ts +5 -1
  63. package/dist/runtime/table/composables/use-table-data.js +20 -2
  64. package/dist/runtime/table/composables/use-table-summaries.js +10 -1
  65. package/dist/runtime/table/types/columns.d.ts +18 -3
  66. package/dist/runtime/table/types/data-list.d.ts +1 -0
  67. package/dist/runtime/table/types/layout.d.ts +1 -1
  68. package/dist/runtime/table/utils/columns/defs.js +1 -1
  69. package/dist/runtime/table/utils/filters/date.d.ts +6 -0
  70. package/dist/runtime/table/utils/filters/date.js +26 -2
  71. package/dist/runtime/table/utils/filters/index.d.ts +1 -0
  72. package/dist/runtime/table/utils/filters/index.js +1 -0
  73. package/dist/runtime/table/utils/filters/number.d.ts +5 -0
  74. package/dist/runtime/table/utils/filters/number.js +11 -0
  75. package/dist/runtime/table/utils/filters/ui.js +5 -5
  76. package/package.json +1 -1
package/dist/module.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "configKey": "nuxtUiTools",
6
6
  "docs": "https://ui.nuxt.com/docs/getting-started/installation/nuxt",
7
7
  "name": "nuxt-ui-tools",
8
- "version": "1.5.0",
8
+ "version": "1.6.1",
9
9
  "builder": {
10
10
  "@nuxt/module-builder": "1.0.3",
11
11
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -36,6 +36,7 @@ function getPublicComponents(runtimeDir, options) {
36
36
  "SortMenu",
37
37
  "LayoutSwitch",
38
38
  "Content",
39
+ "ErrorState",
39
40
  "Table",
40
41
  "Grid",
41
42
  "Pagination",
@@ -369,6 +369,7 @@ export default defineUiToolsLocale({
369
369
  loadMore: "Load more",
370
370
  loadingMore: "Loading\u2026",
371
371
  noMatchingFilters: "No matching filters.",
372
+ clearSearch: "Clear search",
372
373
  resetColumns: "Default",
373
374
  resetFilters: "Reset",
374
375
  searchColumns: "Search columns...",
@@ -422,6 +423,24 @@ export default defineUiToolsLocale({
422
423
  done: "Done",
423
424
  order: "Order",
424
425
  sortBy: "Sort by"
426
+ },
427
+ date: {
428
+ custom: "Custom range",
429
+ end: "End",
430
+ presets: {
431
+ last30Days: "Last 30 days",
432
+ last7Days: "Last 7 days",
433
+ lastMonth: "Last month",
434
+ sevenDaysAgo: "7 days ago",
435
+ startOfMonth: "Start of month",
436
+ startOfYear: "Start of year",
437
+ thisMonth: "This month",
438
+ today: "Today",
439
+ yearToDate: "Year to date",
440
+ yesterday: "Yesterday"
441
+ },
442
+ range: "Date range",
443
+ start: "Start"
425
444
  }
426
445
  },
427
446
  footer: {
@@ -463,8 +482,8 @@ export default defineUiToolsLocale({
463
482
  },
464
483
  gridError: {
465
484
  action: "Retry",
466
- description: "The latest request failed. Try again once the data source is available.",
467
- title: "Unable to load this grid"
485
+ description: "The last request failed. Try again in a moment.",
486
+ title: "This list could not be loaded"
468
487
  },
469
488
  loaded: "{count} loaded",
470
489
  loadingMore: "Loading more\u2026"
@@ -472,6 +491,8 @@ export default defineUiToolsLocale({
472
491
  summaries: {
473
492
  filtered: "Filtered",
474
493
  page: "Page",
494
+ rowOne: "row",
495
+ rowOther: "rows",
475
496
  selection: "Selection",
476
497
  total: "Total"
477
498
  }
@@ -369,6 +369,7 @@ export default defineUiToolsLocale({
369
369
  loadMore: "Charger plus",
370
370
  loadingMore: "Chargement\u2026",
371
371
  noMatchingFilters: "Aucun filtre correspondant.",
372
+ clearSearch: "Effacer la recherche",
372
373
  resetColumns: "Par d\xE9faut",
373
374
  resetFilters: "R\xE9initialiser",
374
375
  searchColumns: "Rechercher des colonnes...",
@@ -422,6 +423,24 @@ export default defineUiToolsLocale({
422
423
  done: "Termin\xE9",
423
424
  order: "Ordre",
424
425
  sortBy: "Trier par"
426
+ },
427
+ date: {
428
+ custom: "P\xE9riode personnalis\xE9e",
429
+ end: "Fin",
430
+ presets: {
431
+ last30Days: "30 derniers jours",
432
+ last7Days: "7 derniers jours",
433
+ lastMonth: "Le mois dernier",
434
+ sevenDaysAgo: "Il y a 7 jours",
435
+ startOfMonth: "D\xE9but du mois",
436
+ startOfYear: "D\xE9but de l'ann\xE9e",
437
+ thisMonth: "Ce mois-ci",
438
+ today: "Aujourd'hui",
439
+ yearToDate: "Depuis le d\xE9but de l'ann\xE9e",
440
+ yesterday: "Hier"
441
+ },
442
+ range: "P\xE9riode",
443
+ start: "D\xE9but"
425
444
  }
426
445
  },
427
446
  footer: {
@@ -463,8 +482,8 @@ export default defineUiToolsLocale({
463
482
  },
464
483
  gridError: {
465
484
  action: "R\xE9essayer",
466
- description: "La derni\xE8re requ\xEAte a \xE9chou\xE9. R\xE9essayez une fois la source de donn\xE9es disponible.",
467
- title: "Impossible de charger cette grille"
485
+ description: "La derni\xE8re requ\xEAte a \xE9chou\xE9. R\xE9essayez dans un instant.",
486
+ title: "Impossible de charger cette liste"
468
487
  },
469
488
  loaded: "{count} charg\xE9s",
470
489
  loadingMore: "Chargement en cours\u2026"
@@ -472,6 +491,8 @@ export default defineUiToolsLocale({
472
491
  summaries: {
473
492
  filtered: "Filtr\xE9s",
474
493
  page: "Page",
494
+ rowOne: "ligne",
495
+ rowOther: "lignes",
475
496
  selection: "S\xE9lection",
476
497
  total: "Total"
477
498
  }
@@ -21,6 +21,7 @@ export interface UiToolsTableMessages {
21
21
  };
22
22
  controls: {
23
23
  addFilter: string;
24
+ clearSearch: string;
24
25
  resetFilters: string;
25
26
  columnsCount: string;
26
27
  close: string;
@@ -46,6 +47,8 @@ export interface UiToolsTableMessages {
46
47
  page: string;
47
48
  filtered: string;
48
49
  selection: string;
50
+ rowOne: string;
51
+ rowOther: string;
49
52
  };
50
53
  columnsMenu: {
51
54
  sortAsc: string;
@@ -66,6 +69,24 @@ export interface UiToolsTableMessages {
66
69
  sortBy: string;
67
70
  order: string;
68
71
  };
72
+ date: {
73
+ range: string;
74
+ custom: string;
75
+ start: string;
76
+ end: string;
77
+ presets: {
78
+ today: string;
79
+ yesterday: string;
80
+ sevenDaysAgo: string;
81
+ startOfMonth: string;
82
+ startOfYear: string;
83
+ last7Days: string;
84
+ last30Days: string;
85
+ thisMonth: string;
86
+ lastMonth: string;
87
+ yearToDate: string;
88
+ };
89
+ };
69
90
  panel: {
70
91
  trigger: string;
71
92
  clearAll: string;
@@ -104,7 +104,13 @@ watch(
104
104
  :error="error"
105
105
  :retry="refresh"
106
106
  >
107
- <DataListErrorState min-height="16rem" :size="resolvedSize" :ui="ui" @retry="refresh" />
107
+ <DataListErrorState
108
+ :min-height="fit === 'content' ? '16rem' : void 0"
109
+ :class="fit === 'content' ? '' : 'min-h-0 flex-1'"
110
+ :size="resolvedSize"
111
+ :ui="ui"
112
+ @retry="refresh"
113
+ />
108
114
  </slot>
109
115
  <slot
110
116
  v-else-if="empty && $slots.empty"
@@ -3,11 +3,28 @@ type __VLS_Props = {
3
3
  minHeight?: string;
4
4
  size?: DataListControlSize;
5
5
  ui?: DataListContentUi;
6
+ /** Replaces the localized default title. */
7
+ title?: string;
8
+ /** Replaces the localized default description. */
9
+ description?: string;
10
+ /** Support reference shown under the description, such as a request identifier. */
11
+ reference?: string;
12
+ icon?: string;
6
13
  };
7
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
+ declare var __VLS_14: {};
15
+ type __VLS_Slots = {} & {
16
+ actions?: (props: typeof __VLS_14) => any;
17
+ };
18
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
19
  retry: () => any;
9
20
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
21
  onRetry?: (() => any) | undefined;
11
22
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
24
  declare const _default: typeof __VLS_export;
13
25
  export default _default;
26
+ type __VLS_WithSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -4,11 +4,15 @@ import UIcon from "@nuxt/ui/components/Icon.vue";
4
4
  import { computed } from "vue";
5
5
  import { useUiToolsLocale } from "#ui-tools/i18n";
6
6
  import { useDataListUi } from "../../composables/use-data-list-ui";
7
- import { mergeDataListUiClass, resolveDataListControlGeometry } from "../../utils";
7
+ import { mergeDataListUiClass } from "../../utils";
8
8
  const props = defineProps({
9
9
  minHeight: { type: String, required: false },
10
10
  size: { type: String, required: false },
11
- ui: { type: Object, required: false }
11
+ ui: { type: Object, required: false },
12
+ title: { type: String, required: false },
13
+ description: { type: String, required: false },
14
+ reference: { type: String, required: false },
15
+ icon: { type: String, required: false }
12
16
  });
13
17
  const emit = defineEmits(["retry"]);
14
18
  const dataListUi = useDataListUi();
@@ -17,75 +21,95 @@ const rootUi = computed(() => dataListUi.ui.value.content?.ui);
17
21
  const resolvedSize = computed(
18
22
  () => props.size ?? dataListUi.ui.value.content?.size ?? dataListUi.controlSize.value
19
23
  );
20
- const geometry = computed(() => resolveDataListControlGeometry(resolvedSize.value));
24
+ const resolvedTitle = computed(() => props.title ?? t("table.states.gridError.title"));
25
+ const resolvedDescription = computed(
26
+ () => props.description ?? t("table.states.gridError.description")
27
+ );
21
28
  </script>
22
29
 
23
30
  <template>
24
31
  <div
25
32
  :class="
26
33
  mergeDataListUiClass(
27
- 'grid place-items-center px-4 py-10 text-center',
34
+ 'nut-dl-error flex w-full flex-col items-center justify-center px-6 py-12 text-center',
28
35
  rootUi?.error,
29
36
  ui?.error
30
37
  )
31
38
  "
32
39
  :style="{ minHeight }"
40
+ role="alert"
33
41
  >
34
42
  <div
35
43
  :class="
36
44
  mergeDataListUiClass(
37
- `flex max-w-md items-start text-left ${geometry.toolbarGap}`,
38
- rootUi?.errorBody,
39
- ui?.errorBody
45
+ 'nut-dl-error__art relative mb-4 flex size-14 items-center justify-center',
46
+ rootUi?.errorIcon,
47
+ ui?.errorIcon
40
48
  )
41
49
  "
42
50
  >
43
51
  <span
52
+ class="nut-dl-error__ring absolute inset-0 rounded-2xl bg-error/10 ring ring-inset ring-error/15"
53
+ />
54
+ <span
55
+ class="nut-dl-error__ring nut-dl-error__ring--back absolute inset-1.5 -z-10 -rotate-6 rounded-xl bg-error/5"
56
+ />
57
+ <UIcon :name="icon ?? 'i-lucide-cloud-alert'" class="relative size-5 text-error" />
58
+ </div>
59
+ <div :class="mergeDataListUiClass('min-w-0 max-w-md', rootUi?.errorCopy, ui?.errorCopy)">
60
+ <div
44
61
  :class="
45
62
  mergeDataListUiClass(
46
- 'grid size-9 shrink-0 place-items-center rounded-md bg-error/10 text-error',
47
- rootUi?.errorIcon,
48
- ui?.errorIcon
63
+ 'nut-dl-error__title text-[14px] font-medium text-highlighted',
64
+ rootUi?.errorTitle,
65
+ ui?.errorTitle
49
66
  )
50
67
  "
51
68
  >
52
- <UIcon name="i-lucide-cloud-alert" class="size-4" />
53
- </span>
54
- <div
69
+ {{ resolvedTitle }}
70
+ </div>
71
+ <p
55
72
  :class="
56
- mergeDataListUiClass(`min-w-0 flex-1 ${geometry.text}`, rootUi?.errorCopy, ui?.errorCopy)
57
- "
58
- >
59
- <div
60
- :class="
61
- mergeDataListUiClass('font-medium text-highlighted', rootUi?.errorTitle, ui?.errorTitle)
62
- "
63
- >
64
- {{ t("table.states.gridError.title") }}
65
- </div>
66
- <p
67
- :class="
68
73
  mergeDataListUiClass(
69
- 'mt-0.5 leading-5 text-muted',
74
+ 'nut-dl-error__description mx-auto mt-1 max-w-[40ch] text-[12.5px] leading-relaxed text-muted',
70
75
  rootUi?.errorDescription,
71
76
  ui?.errorDescription
72
77
  )
73
78
  "
74
- >
75
- {{ t("table.states.gridError.description") }}
76
- </p>
77
- <UButton
78
- color="neutral"
79
- variant="soft"
80
- :size="resolvedSize"
81
- icon="i-lucide-refresh-cw"
82
- class="mt-3"
83
- :ui="{ base: mergeDataListUiClass(rootUi?.retry, ui?.retry) }"
84
- @click="emit('retry')"
85
- >
86
- {{ t("table.states.gridError.action") }}
87
- </UButton>
88
- </div>
79
+ >
80
+ {{ resolvedDescription }}
81
+ </p>
82
+ <code
83
+ v-if="reference"
84
+ class="nut-dl-error__reference mt-2.5 inline-block rounded-md bg-elevated px-2 py-1 font-mono text-[11.5px] text-muted select-all"
85
+ >
86
+ {{ reference }}
87
+ </code>
88
+ </div>
89
+ <div
90
+ :class="
91
+ mergeDataListUiClass(
92
+ 'nut-dl-error__actions mt-4 flex items-center gap-2',
93
+ rootUi?.errorBody,
94
+ ui?.errorBody
95
+ )
96
+ "
97
+ >
98
+ <UButton
99
+ color="neutral"
100
+ variant="outline"
101
+ :size="resolvedSize"
102
+ icon="i-lucide-refresh-cw"
103
+ :ui="{ base: mergeDataListUiClass(rootUi?.retry, ui?.retry) }"
104
+ @click="emit('retry')"
105
+ >
106
+ {{ t("table.states.gridError.action") }}
107
+ </UButton>
108
+ <slot name="actions" />
89
109
  </div>
90
110
  </div>
91
111
  </template>
112
+
113
+ <style>
114
+ .nut-dl-error{animation:nut-dl-error-in .24s cubic-bezier(.2,.9,.3,1) both}@keyframes nut-dl-error-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){.nut-dl-error{animation:none}}
115
+ </style>
@@ -3,11 +3,28 @@ type __VLS_Props = {
3
3
  minHeight?: string;
4
4
  size?: DataListControlSize;
5
5
  ui?: DataListContentUi;
6
+ /** Replaces the localized default title. */
7
+ title?: string;
8
+ /** Replaces the localized default description. */
9
+ description?: string;
10
+ /** Support reference shown under the description, such as a request identifier. */
11
+ reference?: string;
12
+ icon?: string;
6
13
  };
7
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
+ declare var __VLS_14: {};
15
+ type __VLS_Slots = {} & {
16
+ actions?: (props: typeof __VLS_14) => any;
17
+ };
18
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
19
  retry: () => any;
9
20
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
21
  onRetry?: (() => any) | undefined;
11
22
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
24
  declare const _default: typeof __VLS_export;
13
25
  export default _default;
26
+ type __VLS_WithSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -31,7 +31,7 @@ function humanize(value) {
31
31
  v-for="key in keys"
32
32
  :key="key"
33
33
  type="button"
34
- class="nut-dl-sort__row flex w-full items-center gap-[10px] rounded-lg text-left transition-colors hover:bg-elevated active:bg-elevated"
34
+ class="nut-dl-sort__row flex w-full items-center gap-[10px] rounded-lg text-left outline-none transition-colors hover:bg-elevated focus-visible:ring-2 focus-visible:ring-primary/40 active:bg-elevated"
35
35
  :class="[
36
36
  compact ? 'h-8 px-2.5 text-[13px]' : 'h-[46px] px-[10px] text-[15px]',
37
37
  activeKey === key ? 'nut-dl-sort__row--active font-semibold text-highlighted' : 'text-default'
@@ -52,35 +52,43 @@ function humanize(value) {
52
52
  />
53
53
  </button>
54
54
  </div>
55
- <div
56
- class="nut-dl-sort__caption border-t border-default font-semibold tracking-[0.06em] text-dimmed uppercase"
57
- :class="
58
- compact ? 'mx-1 mt-1.5 px-1.5 pt-2 pb-1 text-[10.5px]' : 'mt-2 px-5 pt-4 pb-2 text-[11px]'
59
- "
60
- >
61
- {{ t("table.filters.sheet.order") }}
55
+ <div class="w-full min-w-0" :class="compact ? 'mt-1.5 px-1' : 'mt-2'">
56
+ <div
57
+ class="nut-dl-sort__caption border-t border-default font-semibold tracking-[0.06em] text-dimmed uppercase"
58
+ :class="compact ? 'px-1.5 pt-2 pb-1 text-[10.5px]' : 'px-5 pt-4 pb-2 text-[11px]'"
59
+ >
60
+ {{ t("table.filters.sheet.order") }}
61
+ </div>
62
62
  </div>
63
63
  <div
64
- class="nut-dl-sort__dir grid grid-cols-[repeat(2,minmax(0,1fr))] gap-0.5 overflow-hidden rounded-md bg-elevated p-0.5"
65
- :class="compact ? 'mx-2.5 mb-2.5' : 'mx-4 mb-5'"
64
+ class="nut-dl-sort__dir-wrap w-full min-w-0"
65
+ :class="compact ? 'px-2.5 pb-2.5' : 'px-4 pb-5'"
66
66
  >
67
- <button
68
- v-for="dir in ['asc', 'desc']"
69
- :key="dir"
70
- type="button"
71
- class="flex min-w-0 items-center justify-center gap-1.5 rounded-[5px] px-1 font-medium whitespace-nowrap"
72
- :class="[
67
+ <div
68
+ class="nut-dl-sort__dir grid w-full min-w-0 grid-cols-[repeat(2,minmax(0,1fr))] gap-0.5 overflow-hidden rounded-md bg-elevated p-0.5"
69
+ role="radiogroup"
70
+ :aria-label="t('table.filters.sheet.order')"
71
+ >
72
+ <button
73
+ v-for="dir in ['asc', 'desc']"
74
+ :key="dir"
75
+ type="button"
76
+ role="radio"
77
+ :aria-checked="activeDirection === dir"
78
+ class="flex min-w-0 items-center justify-center gap-1.5 overflow-hidden rounded-[5px] px-1 font-medium whitespace-nowrap outline-none transition-colors focus-visible:ring-2 focus-visible:ring-primary/40"
79
+ :class="[
73
80
  compact ? 'h-7 text-[12px]' : 'h-8 text-[12.5px]',
74
- activeDirection === dir ? 'nut-dl-sort__dir--active bg-default text-highlighted shadow-[0_0_0_1px_var(--ui-border)]' : 'text-muted'
81
+ activeDirection === dir ? 'nut-dl-sort__dir--active bg-default text-highlighted shadow-[0_0_0_1px_var(--ui-border)]' : 'text-muted hover:text-default'
75
82
  ]"
76
- @click="emit('selectDirection', dir)"
77
- >
78
- <UIcon
79
- :name="dir === 'asc' ? 'i-lucide-arrow-up' : 'i-lucide-arrow-down'"
80
- class="size-3.5"
81
- />
82
- {{ dir === "asc" ? "A \u2192 Z" : "Z \u2192 A" }}
83
- </button>
83
+ @click="emit('selectDirection', dir)"
84
+ >
85
+ <UIcon
86
+ :name="dir === 'asc' ? 'i-lucide-arrow-up' : 'i-lucide-arrow-down'"
87
+ class="size-3.5 shrink-0"
88
+ />
89
+ <span class="truncate">{{ dir === "asc" ? "A \u2192 Z" : "Z \u2192 A" }}</span>
90
+ </button>
91
+ </div>
84
92
  </div>
85
93
  </div>
86
94
  </template>
@@ -124,6 +124,15 @@ function toggleColumn(columnId) {
124
124
  const isVisible2 = internals.tableColumns.tableState.value.columnVisibility?.[columnId] !== false;
125
125
  internals.tableColumns.setVisibility({ columnId, visible: !isVisible2 });
126
126
  }
127
+ function toggleRow(event, column) {
128
+ if (event.target instanceof Element && event.target.closest('button, input, [role="checkbox"]')) {
129
+ return;
130
+ }
131
+ if (isRequired(column)) {
132
+ return;
133
+ }
134
+ toggleColumn(column.id);
135
+ }
127
136
  function open() {
128
137
  internals.controls.columnsPanelOpen.value = true;
129
138
  }
@@ -226,7 +235,7 @@ function toggle() {
226
235
  <div
227
236
  :class="
228
237
  mergeDataListUiClass(
229
- 'nut-dl-colpanel__list grid max-h-80 gap-px overflow-y-auto px-2 py-1',
238
+ 'nut-dl-colpanel__list grid max-h-80 grid-cols-1 gap-px overflow-y-auto px-2 py-1',
230
239
  void 0,
231
240
  ui.list
232
241
  )
@@ -238,11 +247,12 @@ function toggle() {
238
247
  :key="column.id"
239
248
  :class="
240
249
  mergeDataListUiClass(
241
- 'nut-dl-colpanel__row group/col flex h-8 items-center gap-2.5 rounded-md px-2 hover:bg-elevated',
250
+ 'nut-dl-colpanel__row group/col flex h-8 cursor-pointer items-center gap-2.5 rounded-md px-2 hover:bg-elevated',
242
251
  void 0,
243
252
  ui.row
244
253
  )
245
254
  "
255
+ @click="toggleRow($event, column)"
246
256
  >
247
257
  <UCheckbox
248
258
  v-bind="checkboxProps"
@@ -278,18 +288,19 @@ function toggle() {
278
288
  ghost-class="column-panel-row-ghost"
279
289
  chosen-class="column-panel-row-chosen"
280
290
  drag-class="column-panel-row-dragging"
281
- :class="mergeDataListUiClass('grid gap-px', void 0, ui.section)"
291
+ :class="mergeDataListUiClass('grid grid-cols-1 gap-px', void 0, ui.section)"
282
292
  >
283
293
  <div
284
294
  v-for="column in draggableColumns"
285
295
  :key="column.id"
286
296
  :class="
287
297
  mergeDataListUiClass(
288
- 'nut-dl-colpanel__row group/col flex h-8 items-center gap-2.5 rounded-md px-2 hover:bg-elevated',
298
+ 'nut-dl-colpanel__row group/col flex h-8 cursor-pointer items-center gap-2.5 rounded-md px-2 hover:bg-elevated',
289
299
  void 0,
290
300
  ui.row
291
301
  )
292
302
  "
303
+ @click="toggleRow($event, column)"
293
304
  >
294
305
  <UCheckbox
295
306
  v-bind="checkboxProps"
@@ -328,11 +339,12 @@ function toggle() {
328
339
  :key="column.id"
329
340
  :class="
330
341
  mergeDataListUiClass(
331
- 'nut-dl-colpanel__row group/col flex h-8 items-center gap-2.5 rounded-md px-2 hover:bg-elevated',
342
+ 'nut-dl-colpanel__row group/col flex h-8 cursor-pointer items-center gap-2.5 rounded-md px-2 hover:bg-elevated',
332
343
  void 0,
333
344
  ui.row
334
345
  )
335
346
  "
347
+ @click="toggleRow($event, column)"
336
348
  >
337
349
  <UCheckbox
338
350
  v-bind="checkboxProps"
@@ -365,11 +377,12 @@ function toggle() {
365
377
  :key="column.id"
366
378
  :class="
367
379
  mergeDataListUiClass(
368
- 'nut-dl-colpanel__row flex h-8 items-center gap-2.5 rounded-md px-2 hover:bg-elevated',
380
+ 'nut-dl-colpanel__row flex h-8 cursor-pointer items-center gap-2.5 rounded-md px-2 hover:bg-elevated',
369
381
  void 0,
370
382
  ui.row
371
383
  )
372
384
  "
385
+ @click="toggleRow($event, column)"
373
386
  >
374
387
  <UCheckbox
375
388
  v-bind="checkboxProps"
@@ -203,7 +203,7 @@ function toggle() {
203
203
  "
204
204
  :ui="{
205
205
  base: mergeDataListUiClass(
206
- `nut-dl-tag nut-dl-tag--add shrink-0 ${selectedDefinition ? '' : 'border border-dashed border-[var(--ui-border-accented)] text-muted hover:text-default hover:border-[var(--ui-text-dimmed)]'}`,
206
+ 'nut-dl-tag nut-dl-tag--add shrink-0 border border-dashed border-[var(--ui-border-accented)] text-muted hover:text-default hover:border-[var(--ui-text-dimmed)]',
207
207
  void 0,
208
208
  ui?.trigger
209
209
  ),
@@ -0,0 +1,16 @@
1
+ import type { DataListFilterEditorUi } from '../../../types/index.js';
2
+ type __VLS_Props = {
3
+ label: string;
4
+ active?: boolean;
5
+ embedded?: boolean;
6
+ ui?: DataListFilterEditorUi;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ clear: () => any;
10
+ back: () => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ onClear?: (() => any) | undefined;
13
+ onBack?: (() => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -0,0 +1,46 @@
1
+ <script setup>
2
+ import UIcon from "@nuxt/ui/components/Icon.vue";
3
+ import { useUiToolsLocale } from "#ui-tools/i18n";
4
+ import { mergeDataListUiClass } from "../../../utils";
5
+ defineProps({
6
+ label: { type: String, required: true },
7
+ active: { type: Boolean, required: false },
8
+ embedded: { type: Boolean, required: false },
9
+ ui: { type: Object, required: false }
10
+ });
11
+ const emit = defineEmits(["back", "clear"]);
12
+ const { t } = useUiToolsLocale();
13
+ </script>
14
+
15
+ <template>
16
+ <div
17
+ :class="
18
+ mergeDataListUiClass(
19
+ 'nut-dl-editor__head flex items-center gap-2 border-b border-default py-2 pr-3',
20
+ embedded ? 'pl-1.5' : 'pl-3',
21
+ ui?.editorHeader
22
+ )
23
+ "
24
+ >
25
+ <button
26
+ v-if="embedded"
27
+ type="button"
28
+ class="nut-dl-editor__back flex size-6 items-center justify-center rounded-md text-muted outline-none hover:bg-elevated hover:text-default focus-visible:ring-2 focus-visible:ring-primary/40"
29
+ :aria-label="t('table.filters.sheet.back')"
30
+ @click="emit('back')"
31
+ >
32
+ <UIcon name="i-lucide-arrow-left" class="size-4" />
33
+ </button>
34
+ <span class="min-w-0 flex-1 truncate text-[12.5px] font-semibold text-highlighted">
35
+ {{ label }}
36
+ </span>
37
+ <button
38
+ type="button"
39
+ class="nut-dl-editor__clear rounded text-[12.5px] font-semibold text-primary outline-none focus-visible:ring-2 focus-visible:ring-primary/40 disabled:opacity-40"
40
+ :disabled="!active"
41
+ @click="emit('clear')"
42
+ >
43
+ {{ t("table.filters.editor.clear") }}
44
+ </button>
45
+ </div>
46
+ </template>
@@ -0,0 +1,16 @@
1
+ import type { DataListFilterEditorUi } from '../../../types/index.js';
2
+ type __VLS_Props = {
3
+ label: string;
4
+ active?: boolean;
5
+ embedded?: boolean;
6
+ ui?: DataListFilterEditorUi;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ clear: () => any;
10
+ back: () => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ onClear?: (() => any) | undefined;
13
+ onBack?: (() => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;