nuxt-ui-tools 0.1.0 → 0.1.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 (164) hide show
  1. package/dist/module.d.mts +4 -0
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +30 -15
  4. package/dist/runtime/form/components/actions/FormActions.d.vue.ts +0 -2
  5. package/dist/runtime/form/components/actions/FormActions.vue +5 -8
  6. package/dist/runtime/form/components/actions/FormActions.vue.d.ts +0 -2
  7. package/dist/runtime/form/components/layout/DrawerLayout.vue +5 -1
  8. package/dist/runtime/form/components/layout/ModalLayout.vue +5 -1
  9. package/dist/runtime/form/components/renderer/FormCompositeControl.d.vue.ts +15 -0
  10. package/dist/runtime/form/components/renderer/FormCompositeControl.vue +13 -0
  11. package/dist/runtime/form/components/renderer/FormCompositeControl.vue.d.ts +15 -0
  12. package/dist/runtime/form/components/renderer/FormFieldRenderer.d.vue.ts +1 -0
  13. package/dist/runtime/form/components/renderer/FormFieldRenderer.vue +19 -3
  14. package/dist/runtime/form/components/renderer/FormFieldRenderer.vue.d.ts +1 -0
  15. package/dist/runtime/form/components/renderer/FormFieldShell.d.vue.ts +4 -4
  16. package/dist/runtime/form/components/renderer/FormFieldShell.vue +15 -1
  17. package/dist/runtime/form/components/renderer/FormFieldShell.vue.d.ts +4 -4
  18. package/dist/runtime/form/components/root/Form.vue +5 -3
  19. package/dist/runtime/form/composables/use-field-control.d.ts +1 -1
  20. package/dist/runtime/form/composables/use-field-control.js +4 -0
  21. package/dist/runtime/form/composables/use-field-options.d.ts +1 -1
  22. package/dist/runtime/form/composables/use-field-options.js +75 -31
  23. package/dist/runtime/form/composables/use-form-field-chrome.d.ts +3 -0
  24. package/dist/runtime/form/composables/use-form-field-chrome.js +9 -0
  25. package/dist/runtime/form/composables/use-form-runtime.js +17 -5
  26. package/dist/runtime/form/fields/array-list/component.vue +4 -1
  27. package/dist/runtime/form/fields/auto-complete/component.vue +23 -16
  28. package/dist/runtime/form/fields/checkbox-card/component.vue +28 -29
  29. package/dist/runtime/form/fields/checkbox-group/component.vue +28 -29
  30. package/dist/runtime/form/fields/color-picker/component.vue +4 -2
  31. package/dist/runtime/form/fields/date-family/component.vue +9 -4
  32. package/dist/runtime/form/fields/hierarchy/SelectionCheckbox.d.vue.ts +13 -0
  33. package/dist/runtime/form/fields/hierarchy/SelectionCheckbox.vue +24 -0
  34. package/dist/runtime/form/fields/hierarchy/SelectionCheckbox.vue.d.ts +13 -0
  35. package/dist/runtime/form/fields/hierarchy/SelectionRadio.d.vue.ts +14 -0
  36. package/dist/runtime/form/fields/hierarchy/SelectionRadio.vue +27 -0
  37. package/dist/runtime/form/fields/hierarchy/SelectionRadio.vue.d.ts +14 -0
  38. package/dist/runtime/form/fields/hierarchy/component.vue +257 -142
  39. package/dist/runtime/form/fields/hierarchy/utils.d.ts +9 -0
  40. package/dist/runtime/form/fields/hierarchy/utils.js +32 -0
  41. package/dist/runtime/form/fields/input-group/component.vue +7 -30
  42. package/dist/runtime/form/fields/matrix/component.vue +9 -3
  43. package/dist/runtime/form/fields/phone-number/component.vue +7 -2
  44. package/dist/runtime/form/fields/rating/component.vue +25 -2
  45. package/dist/runtime/form/fields/select/component.vue +29 -21
  46. package/dist/runtime/form/fields/switch-group/component.vue +8 -3
  47. package/dist/runtime/form/fields/time/component.vue +7 -5
  48. package/dist/runtime/form/fields/upload/component.vue +5 -3
  49. package/dist/runtime/form/types/api.d.ts +9 -3
  50. package/dist/runtime/form/types/field-base.d.ts +3 -1
  51. package/dist/runtime/form/types/runtime.d.ts +2 -0
  52. package/dist/runtime/form/types/ui.d.ts +1 -0
  53. package/dist/runtime/form/utils/api.js +3 -0
  54. package/dist/runtime/form/utils/options.d.ts +11 -2
  55. package/dist/runtime/form/utils/options.js +57 -9
  56. package/dist/runtime/form/utils/state.js +10 -2
  57. package/dist/runtime/i18n/locales/en.js +38 -0
  58. package/dist/runtime/i18n/locales/fr.js +38 -0
  59. package/dist/runtime/i18n/types.d.ts +38 -0
  60. package/dist/runtime/i18n/use-locale.d.ts +2 -2
  61. package/dist/runtime/i18n/use-locale.js +3 -3
  62. package/dist/runtime/table/components/DataList.d.vue.ts +2 -0
  63. package/dist/runtime/table/components/DataList.vue.d.ts +2 -0
  64. package/dist/runtime/table/components/actions/RowActions.d.vue.ts +4 -2
  65. package/dist/runtime/table/components/actions/RowActions.vue +2 -0
  66. package/dist/runtime/table/components/actions/RowActions.vue.d.ts +4 -2
  67. package/dist/runtime/table/components/data-list/DataListAddFilter.d.vue.ts +5 -3
  68. package/dist/runtime/table/components/data-list/DataListAddFilter.vue +6 -1
  69. package/dist/runtime/table/components/data-list/DataListAddFilter.vue.d.ts +5 -3
  70. package/dist/runtime/table/components/data-list/DataListContent.d.vue.ts +24 -17
  71. package/dist/runtime/table/components/data-list/DataListContent.vue +70 -17
  72. package/dist/runtime/table/components/data-list/DataListContent.vue.d.ts +24 -17
  73. package/dist/runtime/table/components/data-list/DataListDefault.d.vue.ts +2 -0
  74. package/dist/runtime/table/components/data-list/DataListDefault.vue.d.ts +2 -0
  75. package/dist/runtime/table/components/data-list/DataListFilterTags.d.vue.ts +2 -0
  76. package/dist/runtime/table/components/data-list/DataListFilterTags.vue.d.ts +2 -0
  77. package/dist/runtime/table/components/data-list/DataListLayoutSwitch.vue +17 -11
  78. package/dist/runtime/table/components/data-list/DataListRoot.vue +2 -46
  79. package/dist/runtime/table/components/data-list/DataListSortMenu.vue +6 -0
  80. package/dist/runtime/table/components/filters/shared/DynamicFilterPicker.d.vue.ts +5 -0
  81. package/dist/runtime/table/components/filters/shared/DynamicFilterPicker.vue +182 -59
  82. package/dist/runtime/table/components/filters/shared/DynamicFilterPicker.vue.d.ts +5 -0
  83. package/dist/runtime/table/components/filters/shared/FilterMatchModeButton.d.vue.ts +3 -1
  84. package/dist/runtime/table/components/filters/shared/FilterMatchModeButton.vue +29 -5
  85. package/dist/runtime/table/components/filters/shared/FilterMatchModeButton.vue.d.ts +3 -1
  86. package/dist/runtime/table/components/filters/shared/FilterMatchModePanel.d.vue.ts +17 -0
  87. package/dist/runtime/table/components/filters/shared/FilterMatchModePanel.vue +47 -0
  88. package/dist/runtime/table/components/filters/shared/FilterMatchModePanel.vue.d.ts +17 -0
  89. package/dist/runtime/table/components/filters/shared/FilterOptionMultipleList.d.vue.ts +3 -1
  90. package/dist/runtime/table/components/filters/shared/FilterOptionMultipleList.vue +12 -3
  91. package/dist/runtime/table/components/filters/shared/FilterOptionMultipleList.vue.d.ts +3 -1
  92. package/dist/runtime/table/components/filters/shared/FilterOptionPickerContent.d.vue.ts +3 -0
  93. package/dist/runtime/table/components/filters/shared/FilterOptionPickerContent.vue +11 -1
  94. package/dist/runtime/table/components/filters/shared/FilterOptionPickerContent.vue.d.ts +3 -0
  95. package/dist/runtime/table/components/filters/shared/FilterOptionRow.d.vue.ts +3 -0
  96. package/dist/runtime/table/components/filters/shared/FilterOptionRow.vue +48 -9
  97. package/dist/runtime/table/components/filters/shared/FilterOptionRow.vue.d.ts +3 -0
  98. package/dist/runtime/table/components/filters/shared/FilterOptionSingleList.d.vue.ts +3 -0
  99. package/dist/runtime/table/components/filters/shared/FilterOptionSingleList.vue +35 -9
  100. package/dist/runtime/table/components/filters/shared/FilterOptionSingleList.vue.d.ts +3 -0
  101. package/dist/runtime/table/components/filters/shared/FilterOptionTreeContent.d.vue.ts +3 -0
  102. package/dist/runtime/table/components/filters/shared/FilterOptionTreeContent.vue +77 -20
  103. package/dist/runtime/table/components/filters/shared/FilterOptionTreeContent.vue.d.ts +3 -0
  104. package/dist/runtime/table/components/filters/shared/FilterPopoverShell.d.vue.ts +27 -0
  105. package/dist/runtime/table/components/filters/shared/FilterPopoverShell.vue +36 -0
  106. package/dist/runtime/table/components/filters/shared/FilterPopoverShell.vue.d.ts +27 -0
  107. package/dist/runtime/table/components/filters/shared/FilterSearchablePanel.d.vue.ts +3 -0
  108. package/dist/runtime/table/components/filters/shared/FilterSearchablePanel.vue +40 -10
  109. package/dist/runtime/table/components/filters/shared/FilterSearchablePanel.vue.d.ts +3 -0
  110. package/dist/runtime/table/components/filters/shared/FilterStageTransition.d.vue.ts +23 -0
  111. package/dist/runtime/table/components/filters/shared/FilterStageTransition.vue +21 -0
  112. package/dist/runtime/table/components/filters/shared/FilterStageTransition.vue.d.ts +23 -0
  113. package/dist/runtime/table/components/filters/shared/FilterTriggerTag.d.vue.ts +3 -2
  114. package/dist/runtime/table/components/filters/shared/FilterTriggerTag.vue +26 -25
  115. package/dist/runtime/table/components/filters/shared/FilterTriggerTag.vue.d.ts +3 -2
  116. package/dist/runtime/table/components/filters/tags/BooleanFilterTag.d.vue.ts +1 -1
  117. package/dist/runtime/table/components/filters/tags/BooleanFilterTag.vue +75 -22
  118. package/dist/runtime/table/components/filters/tags/BooleanFilterTag.vue.d.ts +1 -1
  119. package/dist/runtime/table/components/filters/tags/DateFilterTag.d.vue.ts +3 -1
  120. package/dist/runtime/table/components/filters/tags/DateFilterTag.vue +254 -160
  121. package/dist/runtime/table/components/filters/tags/DateFilterTag.vue.d.ts +3 -1
  122. package/dist/runtime/table/components/filters/tags/FilterTagsBar.d.vue.ts +7 -6
  123. package/dist/runtime/table/components/filters/tags/FilterTagsBar.vue +12 -27
  124. package/dist/runtime/table/components/filters/tags/FilterTagsBar.vue.d.ts +7 -6
  125. package/dist/runtime/table/components/filters/tags/NumberFilterTag.d.vue.ts +3 -2
  126. package/dist/runtime/table/components/filters/tags/NumberFilterTag.vue +192 -106
  127. package/dist/runtime/table/components/filters/tags/NumberFilterTag.vue.d.ts +3 -2
  128. package/dist/runtime/table/components/filters/tags/OptionFilterTag.d.vue.ts +3 -2
  129. package/dist/runtime/table/components/filters/tags/OptionFilterTag.vue +110 -48
  130. package/dist/runtime/table/components/filters/tags/OptionFilterTag.vue.d.ts +3 -2
  131. package/dist/runtime/table/components/filters/tags/TextFilterTag.d.vue.ts +3 -2
  132. package/dist/runtime/table/components/filters/tags/TextFilterTag.vue +120 -57
  133. package/dist/runtime/table/components/filters/tags/TextFilterTag.vue.d.ts +3 -2
  134. package/dist/runtime/table/components/grid/GridRenderer.vue +1 -1
  135. package/dist/runtime/table/components/layout/TableFooter.vue +1 -0
  136. package/dist/runtime/table/components/table/TableRenderer.vue +18 -9
  137. package/dist/runtime/table/composables/use-filter-tag-session.d.ts +3 -4
  138. package/dist/runtime/table/composables/use-filter-tag-session.js +12 -32
  139. package/dist/runtime/table/composables/use-query-state.d.ts +3 -3
  140. package/dist/runtime/table/composables/use-query-state.js +7 -32
  141. package/dist/runtime/table/composables/use-table-api.js +2 -2
  142. package/dist/runtime/table/composables/use-table-columns.d.ts +1 -11
  143. package/dist/runtime/table/composables/use-table-filter-presentation.d.ts +0 -3
  144. package/dist/runtime/table/composables/use-table-filter-presentation.js +0 -9
  145. package/dist/runtime/table/composables/use-table-filters.js +18 -7
  146. package/dist/runtime/table/composables/use-table-internals.d.ts +3 -42
  147. package/dist/runtime/table/types/actions.d.ts +1 -1
  148. package/dist/runtime/table/types/data-list.d.ts +41 -8
  149. package/dist/runtime/table/types/filters.d.ts +4 -0
  150. package/dist/runtime/table/utils/actions.d.ts +1 -1
  151. package/dist/runtime/table/utils/columns/menu.d.ts +2 -11
  152. package/dist/runtime/table/utils/columns/render.d.ts +2 -9
  153. package/dist/runtime/table/utils/columns/render.js +4 -4
  154. package/dist/runtime/table/utils/data-list-ui.d.ts +3 -1
  155. package/dist/runtime/table/utils/data-list-ui.js +45 -0
  156. package/dist/runtime/table/utils/filters/editor-size.d.ts +11 -0
  157. package/dist/runtime/table/utils/filters/editor-size.js +45 -0
  158. package/dist/runtime/table/utils/filters/index.d.ts +1 -1
  159. package/dist/runtime/table/utils/filters/index.js +1 -1
  160. package/dist/runtime/table/utils/query-state.d.ts +18 -1
  161. package/dist/runtime/table/utils/query-state.js +109 -0
  162. package/package.json +4 -2
  163. package/dist/runtime/table/utils/filters/operators.d.ts +0 -4
  164. package/dist/runtime/table/utils/filters/operators.js +0 -6
@@ -14,6 +14,8 @@ declare var __VLS_1: {
14
14
  close: () => void;
15
15
  toggle: () => void;
16
16
  openState: boolean;
17
+ stage: "editor" | "match-mode" | "picker";
18
+ definition: import("../../types/index.js").TableUiFilterDefinition | undefined;
17
19
  triggerProps: {
18
20
  type: string;
19
21
  'aria-expanded': boolean;
@@ -14,6 +14,8 @@ declare var __VLS_1: {
14
14
  close: () => void;
15
15
  toggle: () => void;
16
16
  openState: boolean;
17
+ stage: "editor" | "match-mode" | "picker";
18
+ definition: import("../../types/index.js").TableUiFilterDefinition | undefined;
17
19
  triggerProps: {
18
20
  type: string;
19
21
  'aria-expanded': boolean;
@@ -1,6 +1,7 @@
1
1
  <script setup>
2
2
  import UButton from "@nuxt/ui/components/Button.vue";
3
3
  import UFieldGroup from "@nuxt/ui/components/FieldGroup.vue";
4
+ import UTooltip from "@nuxt/ui/components/Tooltip.vue";
4
5
  import { computed } from "vue";
5
6
  import { useUiToolsLocale } from "#ui-tools/i18n";
6
7
  import { useDataListUi } from "../../composables/use-data-list-ui";
@@ -37,24 +38,29 @@ function setLayout(layout) {
37
38
  :size="resolvedSize"
38
39
  :class="resolvedUi.root"
39
40
  >
40
- <UButton
41
+ <UTooltip
41
42
  v-for="layout in order"
42
43
  :key="layout"
43
- color="neutral"
44
- :variant="internals.controls.tableLayout.value === layout ? 'subtle' : 'outline'"
45
- :size="resolvedSize"
46
- :icon="layout === 'table' ? 'i-lucide-table-properties' : 'i-lucide-layout-grid'"
47
- :label="labels ? layout === 'table' ? 'Table' : 'Grid' : void 0"
48
- :aria-label="layout === 'table' ? t('table.header.tableView') : t('table.header.gridView')"
49
- :title="layout === 'table' ? t('table.header.tableView') : t('table.header.gridView')"
50
- :ui="{
44
+ :text="layout === 'table' ? t('table.header.tableView') : t('table.header.gridView')"
45
+ >
46
+ <UButton
47
+ color="neutral"
48
+ :variant="internals.controls.tableLayout.value === layout ? 'subtle' : 'outline'"
49
+ :size="resolvedSize"
50
+ :icon="layout === 'table' ? 'i-lucide-table-properties' : 'i-lucide-layout-grid'"
51
+ :label="labels ? layout === 'table' ? 'Table' : 'Grid' : void 0"
52
+ :aria-label="
53
+ layout === 'table' ? t('table.header.tableView') : t('table.header.gridView')
54
+ "
55
+ :ui="{
51
56
  base: resolvedUi.trigger,
52
57
  label: resolvedUi.triggerLabel,
53
58
  leadingIcon: resolvedUi.triggerLeadingIcon,
54
59
  trailingIcon: resolvedUi.triggerTrailingIcon
55
60
  }"
56
- @click="setLayout(layout)"
57
- />
61
+ @click="setLayout(layout)"
62
+ />
63
+ </UTooltip>
58
64
  </UFieldGroup>
59
65
  </slot>
60
66
  </template>
@@ -4,6 +4,7 @@ import { computed, onBeforeUnmount, onMounted } from "vue";
4
4
  import { provideUiToolsLocale, useUiToolsLocaleRef } from "#ui-tools/i18n";
5
5
  import { provideDataListUi } from "../../composables/use-data-list-ui";
6
6
  import { provideTableInternals } from "../../composables/use-table-internals";
7
+ import { mergeDataListUiConfig } from "../../utils";
7
8
  const props = defineProps({
8
9
  table: { type: Object, required: true },
9
10
  locale: { type: Object, required: false },
@@ -15,7 +16,7 @@ provideTableInternals(props.table.__internals);
15
16
  provideUiToolsLocale(useUiToolsLocaleRef(computed(() => props.locale)));
16
17
  provideDataListUi(
17
18
  computed(
18
- () => mergeDataListUi(resolveAppDataListUi(appConfig), props.ui, props.density)
19
+ () => mergeDataListUiConfig(resolveAppDataListUi(appConfig), props.ui, props.density)
19
20
  )
20
21
  );
21
22
  onMounted(() => props.table.__internals.startup.scheduleStart());
@@ -29,51 +30,6 @@ function resolveAppDataListUi(config) {
29
30
  function isDataListUiConfig(value) {
30
31
  return Boolean(value) && typeof value === "object";
31
32
  }
32
- function mergeDataListUi(appUi, componentUi, density) {
33
- return {
34
- ...appUi,
35
- ...componentUi,
36
- density: density ?? componentUi?.density ?? appUi?.density,
37
- control: { ...appUi?.control, ...componentUi?.control },
38
- default: mergeUiConfig(appUi?.default, componentUi?.default),
39
- search: mergeSearchConfig(appUi?.search, componentUi?.search),
40
- filterTags: mergePartConfig(appUi?.filterTags, componentUi?.filterTags),
41
- addFilter: mergePartConfig(appUi?.addFilter, componentUi?.addFilter),
42
- filterPanel: mergePartConfig(appUi?.filterPanel, componentUi?.filterPanel),
43
- clearFilters: mergePartConfig(appUi?.clearFilters, componentUi?.clearFilters),
44
- resultCount: mergeUiConfig(appUi?.resultCount, componentUi?.resultCount),
45
- columnPanel: mergePartConfig(appUi?.columnPanel, componentUi?.columnPanel),
46
- sortMenu: mergePartConfig(appUi?.sortMenu, componentUi?.sortMenu),
47
- layoutSwitch: mergePartConfig(appUi?.layoutSwitch, componentUi?.layoutSwitch),
48
- refresh: mergePartConfig(appUi?.refresh, componentUi?.refresh),
49
- content: mergeUiConfig(appUi?.content, componentUi?.content),
50
- table: mergeUiConfig(appUi?.table, componentUi?.table),
51
- grid: mergeUiConfig(appUi?.grid, componentUi?.grid),
52
- pagination: mergePartConfig(appUi?.pagination, componentUi?.pagination),
53
- infiniteLoader: mergePartConfig(appUi?.infiniteLoader, componentUi?.infiniteLoader)
54
- };
55
- }
56
- function mergeUiConfig(appDefaults, componentConfig) {
57
- return {
58
- ...appDefaults,
59
- ...componentConfig,
60
- ui: { ...appDefaults?.ui, ...componentConfig?.ui }
61
- };
62
- }
63
- function mergePartConfig(appDefaults, componentConfig) {
64
- return {
65
- ...appDefaults,
66
- ...componentConfig,
67
- ui: { ...appDefaults?.ui, ...componentConfig?.ui }
68
- };
69
- }
70
- function mergeSearchConfig(appDefaults, componentConfig) {
71
- return {
72
- ...appDefaults,
73
- ...componentConfig,
74
- ui: { ...appDefaults?.ui, ...componentConfig?.ui }
75
- };
76
- }
77
33
  </script>
78
34
 
79
35
  <template>
@@ -33,6 +33,10 @@ const sortLabels = computed(() => {
33
33
  return labels;
34
34
  });
35
35
  const activeKey = computed(() => internals.tableColumns.sortingState.value.key);
36
+ const activeDirection = computed(() => internals.tableColumns.sortingState.value.dir);
37
+ const directionIcon = computed(
38
+ () => activeDirection.value === "asc" ? "i-lucide-arrow-up-narrow-wide" : "i-lucide-arrow-down-wide-narrow"
39
+ );
36
40
  const sortKeys = computed(() => [
37
41
  .../* @__PURE__ */ new Set([
38
42
  ...internals.tableColumns.sortKeys.value,
@@ -68,6 +72,7 @@ function humanize(value) {
68
72
 
69
73
  <template>
70
74
  <UDropdownMenu
75
+ :size="resolvedSize"
71
76
  :items="items"
72
77
  :content="{ align: 'end', sideOffset: 8 }"
73
78
  :ui="{
@@ -91,6 +96,7 @@ function humanize(value) {
91
96
  variant="outline"
92
97
  :size="resolvedSize"
93
98
  :label="`${label ?? t('table.controls.sort')}${activeLabel ? `: ${activeLabel}` : ''}`"
99
+ :icon="directionIcon"
94
100
  trailing-icon="i-lucide-chevron-down"
95
101
  :ui="{
96
102
  base: resolvedUi.trigger,
@@ -1,6 +1,7 @@
1
1
  import type { DataListAddFilterUi, DataListControlSize, TableUiFilterDefinition } from '../../../types/index.js';
2
2
  type __VLS_Props = {
3
3
  definitions: TableUiFilterDefinition[];
4
+ sessionDefinition?: TableUiFilterDefinition;
4
5
  getLabel: (definition: TableUiFilterDefinition) => string;
5
6
  size?: DataListControlSize;
6
7
  ui?: DataListAddFilterUi;
@@ -13,6 +14,8 @@ declare var __VLS_10: {
13
14
  close: typeof close;
14
15
  toggle: typeof toggle;
15
16
  openState: boolean;
17
+ stage: "editor" | "match-mode" | "picker";
18
+ definition: TableUiFilterDefinition | undefined;
16
19
  triggerProps: {
17
20
  type: string;
18
21
  'aria-expanded': boolean;
@@ -23,8 +26,10 @@ type __VLS_Slots = {} & {
23
26
  };
24
27
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
25
28
  select: (key: string) => any;
29
+ release: (key: string) => any;
26
30
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
27
31
  onSelect?: ((key: string) => any) | undefined;
32
+ onRelease?: ((key: string) => any) | undefined;
28
33
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
29
34
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
30
35
  declare const _default: typeof __VLS_export;
@@ -2,22 +2,50 @@
2
2
  import UButton from "@nuxt/ui/components/Button.vue";
3
3
  import UIcon from "@nuxt/ui/components/Icon.vue";
4
4
  import UPopover from "@nuxt/ui/components/Popover.vue";
5
- import { computed, ref } from "vue";
5
+ import { computed, nextTick, ref } from "vue";
6
6
  import { useUiToolsLocale } from "#ui-tools/i18n";
7
7
  import { useDataListUi } from "../../../composables/use-data-list-ui";
8
- import { mergeDataListUiClass, resolveFilterTriggerIcon } from "../../../utils";
8
+ import { useTableInternals } from "../../../composables/use-table-internals";
9
+ import {
10
+ mergeDataListUiClass,
11
+ resolveFilterEditorSizeClasses,
12
+ resolveFilterTriggerIcon
13
+ } from "../../../utils";
14
+ import { resolveFilterTagComponent } from "../tags/registry";
15
+ import FilterMatchModePanel from "./FilterMatchModePanel.vue";
9
16
  import FilterSearchablePanel from "./FilterSearchablePanel.vue";
17
+ import FilterStageTransition from "./FilterStageTransition.vue";
10
18
  const props = defineProps({
11
19
  definitions: { type: Array, required: true },
20
+ sessionDefinition: { type: null, required: false },
12
21
  getLabel: { type: Function, required: true },
13
22
  size: { type: String, required: false },
14
23
  ui: { type: Object, required: false }
15
24
  });
16
- const emit = defineEmits(["select"]);
25
+ const emit = defineEmits(["select", "release"]);
17
26
  const { t } = useUiToolsLocale();
27
+ const internals = useTableInternals();
18
28
  const dataListUi = useDataListUi();
19
29
  const isOpen = ref(false);
20
30
  const searchQuery = ref("");
31
+ const selectedKey = ref(null);
32
+ const pendingOperator = ref();
33
+ const stage = ref("picker");
34
+ const stageDirection = ref("forward");
35
+ const stageTransitioning = ref(false);
36
+ let releaseAfterCommit = false;
37
+ const size = computed(
38
+ () => props.size ?? dataListUi.ui.value.filterTags?.size ?? dataListUi.controlSize.value
39
+ );
40
+ const sizeClasses = computed(() => resolveFilterEditorSizeClasses(size.value));
41
+ const selectedDefinition = computed(() => {
42
+ if (selectedKey.value == null) return void 0;
43
+ if (props.sessionDefinition?.key === selectedKey.value) return props.sessionDefinition;
44
+ return props.definitions.find((definition) => definition.key === selectedKey.value);
45
+ });
46
+ const operatorItems = computed(
47
+ () => selectedKey.value == null ? [] : internals.filters.getFilterOperatorOptions({ key: selectedKey.value })
48
+ );
21
49
  const filteredDefinitions = computed(() => {
22
50
  const search = searchQuery.value.trim().toLowerCase();
23
51
  if (!search) return props.definitions;
@@ -25,19 +53,65 @@ const filteredDefinitions = computed(() => {
25
53
  (definition) => props.getLabel(definition).toLowerCase().includes(search)
26
54
  );
27
55
  });
28
- function handleSelect(key) {
56
+ async function handleSelect(key) {
57
+ selectedKey.value = key;
58
+ searchQuery.value = "";
59
+ const items = internals.filters.getFilterOperatorOptions({ key });
60
+ if (items.length > 1) {
61
+ pendingOperator.value = internals.filters.getFilterOperator({ key });
62
+ stageDirection.value = "forward";
63
+ stageTransitioning.value = true;
64
+ stage.value = "match-mode";
65
+ return;
66
+ }
67
+ const defaultOperator = items[0]?.value;
68
+ if (!defaultOperator) return;
69
+ await openEditor(defaultOperator);
70
+ }
71
+ async function openEditor(operator) {
72
+ const key = selectedKey.value;
73
+ if (!key) return;
74
+ pendingOperator.value = operator;
29
75
  emit("select", key);
76
+ await nextTick();
77
+ stageDirection.value = "forward";
78
+ stageTransitioning.value = true;
79
+ stage.value = "editor";
80
+ }
81
+ function handleFocusOutside(event) {
82
+ if (stageTransitioning.value) event.preventDefault();
83
+ }
84
+ function handleOpenChange(nextOpen) {
85
+ isOpen.value = nextOpen;
86
+ if (!nextOpen && !releaseAfterCommit) releaseSession();
87
+ }
88
+ function handleSessionClosed() {
30
89
  isOpen.value = false;
90
+ releaseAfterCommit = true;
91
+ queueMicrotask(() => {
92
+ releaseSession();
93
+ releaseAfterCommit = false;
94
+ });
95
+ }
96
+ function releaseSession() {
97
+ const key = selectedKey.value;
98
+ selectedKey.value = null;
99
+ pendingOperator.value = void 0;
31
100
  searchQuery.value = "";
101
+ stage.value = "picker";
102
+ stageDirection.value = "backward";
103
+ if (key) emit("release", key);
32
104
  }
33
105
  function open() {
34
106
  isOpen.value = true;
35
107
  }
36
108
  function close() {
37
109
  isOpen.value = false;
110
+ releaseSession();
38
111
  }
39
112
  function toggle() {
40
- isOpen.value = !isOpen.value;
113
+ if (isOpen.value) close();
114
+ else open();
41
115
  }
42
116
  </script>
43
117
 
@@ -45,89 +119,138 @@ function toggle() {
45
119
  <UPopover
46
120
  :open="isOpen"
47
121
  mode="click"
48
- :content="{ side: 'bottom', align: 'start', sideOffset: 8 }"
122
+ :content="{
123
+ side: 'bottom',
124
+ align: 'start',
125
+ sideOffset: 8,
126
+ onFocusOutside: handleFocusOutside
127
+ }"
49
128
  :ui="{
50
129
  content: mergeDataListUiClass(
51
- 'w-fit max-w-[calc(100vw-1rem)] overflow-hidden p-0 shadow-none',
130
+ 'w-fit max-w-[calc(100vw-1rem)] overflow-hidden p-0',
52
131
  void 0,
53
132
  ui?.popoverContent
54
133
  )
55
134
  }"
56
- @update:open="isOpen = $event"
135
+ @update:open="handleOpenChange"
57
136
  >
58
137
  <slot
138
+ v-if="$slots.trigger"
59
139
  name="trigger"
60
140
  :open="open"
61
141
  :close="close"
62
142
  :toggle="toggle"
63
143
  :open-state="isOpen"
64
- :trigger-props="{ type: 'button', 'aria-expanded': isOpen }"
65
- >
66
- <UButton
67
- color="neutral"
68
- variant="outline"
69
- :size="props.size ?? dataListUi.ui.value.filterTags?.size ?? dataListUi.controlSize.value"
70
- icon="i-lucide-plus"
71
- :label="t('table.controls.addFilter')"
72
- :ui="{
73
- base: mergeDataListUiClass('shrink-0 border-dashed', void 0, ui?.trigger)
144
+ :stage="stage"
145
+ :definition="selectedDefinition"
146
+ :trigger-props="{
147
+ type: 'button',
148
+ 'aria-expanded': isOpen
149
+ }"
150
+ />
151
+ <UButton
152
+ v-else
153
+ color="neutral"
154
+ variant="outline"
155
+ :size="size"
156
+ :icon="selectedDefinition ? resolveFilterTriggerIcon(selectedDefinition) : 'i-lucide-plus'"
157
+ :label="selectedDefinition ? getLabel(selectedDefinition) : t('table.controls.addFilter')"
158
+ :ui="{
159
+ base: mergeDataListUiClass(
160
+ `shrink-0 ${selectedDefinition ? '' : 'border-dashed'}`,
161
+ void 0,
162
+ ui?.trigger
163
+ )
74
164
  }"
75
- />
76
- </slot>
165
+ />
77
166
 
78
167
  <template #content>
79
- <div
80
- :class="
168
+ <FilterStageTransition
169
+ :stage-key="`${stage}:${selectedKey ?? ''}:${pendingOperator ?? ''}`"
170
+ :direction="stageDirection"
171
+ @settled="stageTransitioning = false"
172
+ >
173
+ <div
174
+ v-if="stage === 'picker'"
175
+ :class="mergeDataListUiClass(sizeClasses.editor, void 0, ui?.panel)"
176
+ >
177
+ <FilterSearchablePanel
178
+ v-model:search-query="searchQuery"
179
+ searchable
180
+ autofocus
181
+ :search-placeholder="t('table.controls.searchFilters')"
182
+ :show-empty="!filteredDefinitions.length"
183
+ :empty-label="t('table.controls.noMatchingFilters')"
184
+ max-height-class="max-h-72"
185
+ :size="size"
186
+ :ui="ui"
187
+ >
188
+ <button
189
+ v-for="definition in filteredDefinitions"
190
+ :key="definition.key"
191
+ type="button"
192
+ :class="
81
193
  mergeDataListUiClass(
82
- 'w-fit min-w-[18rem] max-w-[min(24rem,calc(100vw-1rem))]',
194
+ `flex min-w-0 items-center rounded-md text-left transition-colors hover:bg-elevated/70 ${sizeClasses.option}`,
83
195
  void 0,
84
- ui?.panel
196
+ ui?.option
85
197
  )
86
198
  "
87
- >
88
- <FilterSearchablePanel
89
- v-model:search-query="searchQuery"
90
- searchable
91
- autofocus
92
- :search-placeholder="t('table.controls.searchFilters')"
93
- :show-empty="!filteredDefinitions.length"
94
- :empty-label="t('table.controls.noMatchingFilters')"
95
- max-height-class="max-h-72"
96
- >
97
- <button
98
- v-for="definition in filteredDefinitions"
99
- :key="definition.key"
100
- type="button"
101
- :class="
199
+ @click="handleSelect(definition.key)"
200
+ >
201
+ <UIcon
202
+ :name="resolveFilterTriggerIcon(definition)"
203
+ :class="
102
204
  mergeDataListUiClass(
103
- 'flex min-w-0 items-center gap-3 rounded-md px-3 py-2 text-left transition-colors hover:bg-elevated/70',
205
+ `${sizeClasses.optionIcon} shrink-0 text-muted`,
104
206
  void 0,
105
- ui?.option
207
+ ui?.optionIcon
106
208
  )
107
209
  "
108
- @click="handleSelect(definition.key)"
109
- >
110
- <UIcon
111
- :name="resolveFilterTriggerIcon(definition)"
112
- :class="mergeDataListUiClass('size-4 shrink-0 text-muted', void 0, ui?.optionIcon)"
113
- />
114
- <span
115
- :class="
210
+ />
211
+ <span
212
+ :class="
116
213
  mergeDataListUiClass(
117
- 'min-w-0 flex-1 truncate text-sm text-default',
214
+ `min-w-0 flex-1 truncate text-default ${sizeClasses.optionLabel}`,
118
215
  void 0,
119
216
  ui?.optionLabel
120
217
  )
121
218
  "
122
- >
123
- {{ getLabel(definition) }}
124
- </span>
125
- <span :class="mergeDataListUiClass('text-muted', void 0, ui?.optionTrailingIcon)">
126
- <UIcon name="i-lucide-arrow-right" class="size-4" />
127
- </span>
128
- </button>
129
- </FilterSearchablePanel>
130
- </div>
219
+ >
220
+ {{ getLabel(definition) }}
221
+ </span>
222
+ <span :class="mergeDataListUiClass('text-muted', void 0, ui?.optionTrailingIcon)">
223
+ <UIcon name="i-lucide-arrow-right" class="size-4" />
224
+ </span>
225
+ </button>
226
+ </FilterSearchablePanel>
227
+ </div>
228
+
229
+ <div
230
+ v-else-if="stage === 'match-mode'"
231
+ :class="mergeDataListUiClass(sizeClasses.editor, void 0, ui?.panel)"
232
+ >
233
+ <FilterMatchModePanel
234
+ :items="operatorItems"
235
+ :selected="pendingOperator"
236
+ :size="size"
237
+ :ui="ui"
238
+ @select="openEditor"
239
+ />
240
+ </div>
241
+
242
+ <component
243
+ :is="resolveFilterTagComponent(sessionDefinition)"
244
+ v-else-if="stage === 'editor' && sessionDefinition"
245
+ :definition="sessionDefinition"
246
+ dynamic
247
+ session
248
+ embedded
249
+ :initial-operator="pendingOperator"
250
+ @dismiss="handleSessionClosed"
251
+ @session-closed="handleSessionClosed"
252
+ />
253
+ </FilterStageTransition>
131
254
  </template>
132
255
  </UPopover>
133
256
  </template>
@@ -1,6 +1,7 @@
1
1
  import type { DataListAddFilterUi, DataListControlSize, TableUiFilterDefinition } from '../../../types/index.js';
2
2
  type __VLS_Props = {
3
3
  definitions: TableUiFilterDefinition[];
4
+ sessionDefinition?: TableUiFilterDefinition;
4
5
  getLabel: (definition: TableUiFilterDefinition) => string;
5
6
  size?: DataListControlSize;
6
7
  ui?: DataListAddFilterUi;
@@ -13,6 +14,8 @@ declare var __VLS_10: {
13
14
  close: typeof close;
14
15
  toggle: typeof toggle;
15
16
  openState: boolean;
17
+ stage: "editor" | "match-mode" | "picker";
18
+ definition: TableUiFilterDefinition | undefined;
16
19
  triggerProps: {
17
20
  type: string;
18
21
  'aria-expanded': boolean;
@@ -23,8 +26,10 @@ type __VLS_Slots = {} & {
23
26
  };
24
27
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
25
28
  select: (key: string) => any;
29
+ release: (key: string) => any;
26
30
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
27
31
  onSelect?: ((key: string) => any) | undefined;
32
+ onRelease?: ((key: string) => any) | undefined;
28
33
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
29
34
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
30
35
  declare const _default: typeof __VLS_export;
@@ -1,4 +1,4 @@
1
- import type { TableFilterOperator } from '../../../types/index.js';
1
+ import type { DataListControlSize, DataListFilterEditorUi, TableFilterOperator } from '../../../types/index.js';
2
2
  type __VLS_Props = {
3
3
  label: string;
4
4
  items?: Array<{
@@ -6,6 +6,8 @@ type __VLS_Props = {
6
6
  value: TableFilterOperator;
7
7
  }>;
8
8
  variant?: 'default' | 'compact';
9
+ size?: DataListControlSize;
10
+ ui?: DataListFilterEditorUi;
9
11
  };
10
12
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
13
  select: (value: TableFilterOperator) => any;
@@ -1,16 +1,30 @@
1
1
  <script setup>
2
2
  import UButton from "@nuxt/ui/components/Button.vue";
3
3
  import UDropdownMenu from "@nuxt/ui/components/DropdownMenu.vue";
4
- defineProps({
4
+ import { computed } from "vue";
5
+ import { useDataListUi } from "../../../composables/use-data-list-ui";
6
+ import { mergeDataListUiClass } from "../../../utils";
7
+ const props = defineProps({
5
8
  label: { type: String, required: true },
6
9
  items: { type: Array, required: false, default: () => [] },
7
- variant: { type: String, required: false, default: "default" }
10
+ variant: { type: String, required: false, default: "default" },
11
+ size: { type: String, required: false },
12
+ ui: { type: Object, required: false }
8
13
  });
14
+ const dataListUi = useDataListUi();
15
+ const inheritedPart = computed(
16
+ () => props.variant === "compact" ? dataListUi.ui.value.filterPanel : dataListUi.ui.value.filterTags
17
+ );
18
+ const resolvedSize = computed(
19
+ () => props.size ?? inheritedPart.value?.size ?? dataListUi.controlSize.value
20
+ );
21
+ const resolvedUi = computed(() => ({ ...inheritedPart.value?.ui, ...props.ui }));
9
22
  const emit = defineEmits(["select"]);
10
23
  </script>
11
24
 
12
25
  <template>
13
26
  <UDropdownMenu
27
+ :size="resolvedSize"
14
28
  :items="[
15
29
  items.map((item) => ({
16
30
  label: item.label,
@@ -18,15 +32,25 @@ const emit = defineEmits(["select"]);
18
32
  }))
19
33
  ]"
20
34
  :content="{ side: 'bottom', align: 'end', sideOffset: 6 }"
21
- :ui="{ content: 'w-fit p-1 shadow-none' }"
35
+ :ui="{
36
+ content: mergeDataListUiClass('w-fit p-1', void 0, resolvedUi.operatorContent),
37
+ item: resolvedUi.operatorItem,
38
+ itemLabel: resolvedUi.operatorLabel
39
+ }"
22
40
  >
23
41
  <UButton
24
42
  color="neutral"
25
43
  :variant="variant === 'compact' ? 'ghost' : 'outline'"
26
- :size="variant === 'compact' ? 'sm' : 'md'"
44
+ :size="resolvedSize"
27
45
  :label="label"
28
46
  trailing-icon="i-lucide-chevron-down"
29
- :class="variant === 'compact' ? 'px-2.5' : void 0"
47
+ :ui="{
48
+ base: mergeDataListUiClass(
49
+ variant === 'compact' ? 'px-2.5' : void 0,
50
+ void 0,
51
+ resolvedUi.operatorTrigger
52
+ )
53
+ }"
30
54
  @pointerdown.stop
31
55
  @click.stop
32
56
  />
@@ -1,4 +1,4 @@
1
- import type { TableFilterOperator } from '../../../types/index.js';
1
+ import type { DataListControlSize, DataListFilterEditorUi, TableFilterOperator } from '../../../types/index.js';
2
2
  type __VLS_Props = {
3
3
  label: string;
4
4
  items?: Array<{
@@ -6,6 +6,8 @@ type __VLS_Props = {
6
6
  value: TableFilterOperator;
7
7
  }>;
8
8
  variant?: 'default' | 'compact';
9
+ size?: DataListControlSize;
10
+ ui?: DataListFilterEditorUi;
9
11
  };
10
12
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
13
  select: (value: TableFilterOperator) => any;
@@ -0,0 +1,17 @@
1
+ import type { DataListControlSize, DataListFilterEditorUi, TableFilterOperator } from '../../../types/index.js';
2
+ type __VLS_Props = {
3
+ items: Array<{
4
+ label: string;
5
+ value: TableFilterOperator;
6
+ }>;
7
+ selected?: TableFilterOperator;
8
+ size?: DataListControlSize;
9
+ ui?: DataListFilterEditorUi;
10
+ };
11
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
12
+ select: (value: TableFilterOperator) => any;
13
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
14
+ onSelect?: ((value: TableFilterOperator) => any) | undefined;
15
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;