v-nuxt-ui 0.2.19 → 0.2.22

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 (33) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/AsyncSelect.vue +9 -7
  3. package/dist/runtime/components/AsyncTreeSelect.vue +2 -1
  4. package/dist/runtime/components/Select.d.vue.ts +25 -0
  5. package/dist/runtime/components/Select.vue +67 -0
  6. package/dist/runtime/components/Select.vue.d.ts +25 -0
  7. package/dist/runtime/components/button/Dropdown.d.vue.ts +6 -7
  8. package/dist/runtime/components/button/Dropdown.vue +15 -86
  9. package/dist/runtime/components/button/Dropdown.vue.d.ts +6 -7
  10. package/dist/runtime/components/form/field/AsyncObjectSelect.vue +2 -1
  11. package/dist/runtime/components/form/field/AsyncSelect.vue +2 -1
  12. package/dist/runtime/components/form/field/AsyncTreeSelect.vue +2 -1
  13. package/dist/runtime/components/form/field/Select.d.vue.ts +19 -12
  14. package/dist/runtime/components/form/field/Select.vue +11 -6
  15. package/dist/runtime/components/form/field/Select.vue.d.ts +19 -12
  16. package/dist/runtime/components/form/field/index.vue +1 -7
  17. package/dist/runtime/components/sys/user/Table.vue +1 -5
  18. package/dist/runtime/components/table/query/where/Newer.vue +12 -21
  19. package/dist/runtime/components/table/query/where/simple/item/ColumnPicker.vue +12 -20
  20. package/dist/runtime/components/table/query/where/simple/item/OprPicker.vue +10 -16
  21. package/dist/runtime/components/table/query/where/simple/item/opr/AsyncSelect.vue +3 -1
  22. package/dist/runtime/components/table/query/where/simple/item/opr/Select.d.vue.ts +2 -7
  23. package/dist/runtime/components/table/query/where/simple/item/opr/Select.vue +20 -40
  24. package/dist/runtime/components/table/query/where/simple/item/opr/Select.vue.d.ts +2 -7
  25. package/dist/runtime/components/table/query/where/simple/item/opr/index.vue +1 -3
  26. package/dist/runtime/types/components/async-select.d.ts +1 -0
  27. package/dist/runtime/types/components/form/field.d.ts +4 -9
  28. package/dist/runtime/types/components/index.d.ts +1 -0
  29. package/dist/runtime/types/components/index.js +1 -0
  30. package/dist/runtime/types/components/select.d.ts +14 -0
  31. package/dist/runtime/types/components/select.js +0 -0
  32. package/dist/runtime/types/components/table/column.d.ts +3 -5
  33. package/package.json +2 -2
package/dist/module.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "dependencies": [
8
8
  "@nuxt/ui"
9
9
  ],
10
- "version": "0.2.19",
10
+ "version": "0.2.22",
11
11
  "builder": {
12
12
  "@nuxt/module-builder": "1.0.2",
13
13
  "unbuild": "3.6.1"
@@ -25,7 +25,8 @@ const props = defineProps({
25
25
  afterSelect: { type: Function, required: false },
26
26
  canCreate: { type: Boolean, required: false },
27
27
  createModalComponent: { type: null, required: false },
28
- createModalOpenProps: { type: Object, required: false }
28
+ createModalOpenProps: { type: Object, required: false },
29
+ roundedNone: { type: Boolean, required: false }
29
30
  });
30
31
  const overlay = useOverlay();
31
32
  const modelValue = defineModel("modelValue", { type: Object, ...{ required: true } });
@@ -117,6 +118,12 @@ const onSelect = (values) => {
117
118
  };
118
119
  }
119
120
  };
121
+ const ui = computed(() => ({
122
+ root: ["min-w-32", props.roundedNone && "rounded-none"].filter(Boolean).join(" "),
123
+ base: "peer",
124
+ content: "min-w-fit",
125
+ tagsInput: "min-w-4 w-0"
126
+ }));
120
127
  const dropdownOpen = ref(false);
121
128
  const searchTerm = ref("");
122
129
  const onDebounceFetchItems = useDebounceFn(onFetchItems, 512);
@@ -158,12 +165,7 @@ defineExpose({
158
165
  open-on-focus
159
166
  trailing
160
167
  ignore-filter
161
- :ui="{
162
- root: 'min-w-32',
163
- base: 'peer',
164
- content: 'min-w-fit',
165
- tagsInput: 'min-w-4 w-0'
166
- }"
168
+ :ui="ui"
167
169
  :content="{
168
170
  align: 'start'
169
171
  }"
@@ -27,7 +27,8 @@ const props = defineProps({
27
27
  afterSelect: { type: Function, required: false },
28
28
  canCreate: { type: Boolean, required: false },
29
29
  createModalComponent: { type: null, required: false },
30
- createModalOpenProps: { type: Object, required: false }
30
+ createModalOpenProps: { type: Object, required: false },
31
+ roundedNone: { type: Boolean, required: false }
31
32
  });
32
33
  const modelValue = defineModel("modelValue", { type: Object, ...{ required: true } });
33
34
  const treeModelValue = computed(() => allModels.value.filter((item) => item[props.valueField] === modelValue.value));
@@ -0,0 +1,25 @@
1
+ import type { VSelectProps } from '#v/types';
2
+ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<(VSelectProps<T> & {
4
+ modelValue: string | number | string[] | number[] | undefined;
5
+ }) & {
6
+ "onUpdate:modelValue"?: ((value: string | number | string[] | number[] | undefined) => any) | undefined;
7
+ }> & (typeof globalThis extends {
8
+ __VLS_PROPS_FALLBACK: infer P;
9
+ } ? P : {});
10
+ expose: (exposed: import("vue").ShallowUnwrapRef<{
11
+ focus: () => void;
12
+ }>) => void;
13
+ attrs: any;
14
+ slots: {};
15
+ emit: (event: "update:modelValue", value: string | number | string[] | number[] | undefined) => void;
16
+ }>) => import("vue").VNode & {
17
+ __ctx?: Awaited<typeof __VLS_setup>;
18
+ };
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
21
+ type __VLS_PrettifyLocal<T> = (T extends any ? {
22
+ [K in keyof T]: T[K];
23
+ } : {
24
+ [K in keyof T as K]: T[K];
25
+ }) & {};
@@ -0,0 +1,67 @@
1
+ <script setup>
2
+ import { computed, ref, useTemplateRef } from "vue";
3
+ const props = defineProps({
4
+ label: { type: String, required: false },
5
+ floatingPlaceholder: { type: Boolean, required: false },
6
+ disabled: { type: Boolean, required: false },
7
+ placeholder: { type: String, required: false },
8
+ size: { type: null, required: false },
9
+ icon: { type: null, required: false },
10
+ enableEmptyOption: { type: Boolean, required: false },
11
+ items: { type: Array, required: true },
12
+ multiple: { type: Boolean, required: false },
13
+ afterSelect: { type: Function, required: false },
14
+ roundedNone: { type: Boolean, required: false }
15
+ });
16
+ const modelValue = defineModel("modelValue", { type: null, ...{ required: true } });
17
+ const searchTerm = ref("");
18
+ const getItemLabel = (item) => {
19
+ if (typeof item === "string" || typeof item === "number" || typeof item === "boolean" || typeof item === "bigint") {
20
+ return String(item);
21
+ }
22
+ return String(item?.label ?? "");
23
+ };
24
+ const filteredItems = computed(() => {
25
+ if (!searchTerm.value) {
26
+ return props.items;
27
+ }
28
+ return props.items.filter((item) => getItemLabel(item).toLowerCase().includes(searchTerm.value.toLowerCase()));
29
+ });
30
+ const ui = computed(() => ({
31
+ root: ["min-w-32", props.roundedNone && "rounded-none"].filter(Boolean).join(" "),
32
+ base: "peer",
33
+ content: "min-w-fit",
34
+ tagsInput: "min-w-4 w-0"
35
+ }));
36
+ const inputMenuRef = useTemplateRef("inputMenu");
37
+ defineExpose({
38
+ focus: () => {
39
+ inputMenuRef.value?.inputRef.focus();
40
+ }
41
+ });
42
+ </script>
43
+
44
+ <template>
45
+ <UInputMenu
46
+ ref="inputMenu"
47
+ v-model:search-term="searchTerm"
48
+ v-model="modelValue"
49
+ :items="filteredItems"
50
+ :placeholder="placeholder"
51
+ :multiple="multiple ?? false"
52
+ :size="size"
53
+ color="neutral"
54
+ delete-icon="i-lucide-trash"
55
+ value-key="value"
56
+ clear
57
+ clear-icon="i-lucide-circle-x"
58
+ :icon="icon"
59
+ :disabled="disabled"
60
+ open-on-focus
61
+ trailing
62
+ :ui="ui"
63
+ :content="{
64
+ align: 'start'
65
+ }"
66
+ />
67
+ </template>
@@ -0,0 +1,25 @@
1
+ import type { VSelectProps } from '#v/types';
2
+ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<(VSelectProps<T> & {
4
+ modelValue: string | number | string[] | number[] | undefined;
5
+ }) & {
6
+ "onUpdate:modelValue"?: ((value: string | number | string[] | number[] | undefined) => any) | undefined;
7
+ }> & (typeof globalThis extends {
8
+ __VLS_PROPS_FALLBACK: infer P;
9
+ } ? P : {});
10
+ expose: (exposed: import("vue").ShallowUnwrapRef<{
11
+ focus: () => void;
12
+ }>) => void;
13
+ attrs: any;
14
+ slots: {};
15
+ emit: (event: "update:modelValue", value: string | number | string[] | number[] | undefined) => void;
16
+ }>) => import("vue").VNode & {
17
+ __ctx?: Awaited<typeof __VLS_setup>;
18
+ };
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
21
+ type __VLS_PrettifyLocal<T> = (T extends any ? {
22
+ [K in keyof T]: T[K];
23
+ } : {
24
+ [K in keyof T as K]: T[K];
25
+ }) & {};
@@ -1,13 +1,12 @@
1
- import type { CommandPaletteGroup, CommandPaletteProps } from '@nuxt/ui';
1
+ import type { ListboxItem, ListboxProps } from '@nuxt/ui';
2
2
  type __VLS_Props = {
3
- groups: CommandPaletteGroup[];
4
- multiple?: CommandPaletteProps['multiple'];
5
- enableFooterToolbar?: boolean;
3
+ items: ListboxItem[];
4
+ multiple?: ListboxProps['multiple'];
6
5
  onOpen?: () => Promise<void>;
7
6
  onSearch?: (searchTerm: string) => Promise<void>;
8
7
  };
9
8
  type __VLS_ModelProps = {
10
- 'modelValue'?: string | number | undefined | null | (string | number)[];
9
+ 'modelValue'?: string | number | undefined | (string | number)[];
11
10
  };
12
11
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
13
12
  declare var __VLS_8: {};
@@ -17,9 +16,9 @@ type __VLS_Slots = {} & {
17
16
  declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
18
17
  focus: () => Promise<void>;
19
18
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
- "update:modelValue": (value: string | number | (string | number)[] | null | undefined) => any;
19
+ "update:modelValue": (value: string | number | (string | number)[] | undefined) => any;
21
20
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
22
- "onUpdate:modelValue"?: ((value: string | number | (string | number)[] | null | undefined) => any) | undefined;
21
+ "onUpdate:modelValue"?: ((value: string | number | (string | number)[] | undefined) => any) | undefined;
23
22
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
24
23
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
25
24
  declare const _default: typeof __VLS_export;
@@ -1,59 +1,12 @@
1
1
  <script setup>
2
- import { computed, ref, watch } from "vue";
2
+ import { ref, watch } from "vue";
3
3
  const props = defineProps({
4
- groups: { type: Array, required: true },
4
+ items: { type: Array, required: true },
5
5
  multiple: { type: Boolean, required: false },
6
- enableFooterToolbar: { type: Boolean, required: false },
7
6
  onOpen: { type: Function, required: false },
8
7
  onSearch: { type: Function, required: false }
9
8
  });
10
9
  const modelValue = defineModel("modelValue", { type: null, ...{ required: false } });
11
- const commandPaletteModelValue = computed({
12
- get() {
13
- if (props.multiple) {
14
- const values = [];
15
- for (const group of props.groups) {
16
- for (const item of group.items) {
17
- if (Array.isArray(modelValue.value) && modelValue.value.includes(item.value)) {
18
- values.push(item);
19
- }
20
- }
21
- }
22
- return values;
23
- }
24
- for (const group of props.groups) {
25
- for (const item of group.items) {
26
- if (item.value === modelValue.value) {
27
- const newItem = { ...item };
28
- delete newItem.onSelect;
29
- return newItem;
30
- }
31
- }
32
- }
33
- return {};
34
- },
35
- set(newValue) {
36
- if (props.multiple) {
37
- modelValue.value = newValue.map((item) => item.value);
38
- } else {
39
- modelValue.value = newValue.value;
40
- }
41
- }
42
- });
43
- const footerActions = [
44
- {
45
- label: "\u5168\u9009",
46
- fn: () => modelValue.value = props.groups.flatMap((group) => group.items.map((item) => item.value))
47
- },
48
- {
49
- label: "\u53CD\u9009",
50
- fn: () => modelValue.value = props.groups.flatMap((group) => group.items.map((item) => item.value)).filter((value) => !(Array.isArray(modelValue.value) ? modelValue.value.includes(value) : modelValue.value === value))
51
- },
52
- {
53
- label: "\u6E05\u7A7A",
54
- fn: () => modelValue.value = []
55
- }
56
- ];
57
10
  const searchTerm = ref("");
58
11
  const popoverOpen = ref(false);
59
12
  watch(popoverOpen, async (newOpen) => {
@@ -82,46 +35,22 @@ defineExpose({
82
35
  <slot />
83
36
 
84
37
  <template #content>
85
- <UCommandPalette
86
- :model-value="commandPaletteModelValue"
87
- :selection-behavior="multiple ? 'toggle' : 'replace'"
88
- :groups="groups"
38
+ <UListbox
39
+ v-model="modelValue"
40
+ v-model:search-term="searchTerm"
41
+ autofocus
89
42
  size="sm"
90
- :multiple="multiple"
91
- :ui="{
92
- input: '[&>input]:h-7',
93
- itemLeadingIcon: 'size-3 self-center'
43
+ value-key="value"
44
+ :filter="{
45
+ placeholder: '\u641C\u7D22...',
46
+ icon: 'i-lucide-search'
94
47
  }"
95
- placeholder="搜索"
96
- :search-term="searchTerm"
97
- @update:model-value="(newValue) => {
98
- commandPaletteModelValue = newValue;
99
- if (!multiple) {
100
- popoverOpen = false;
101
- }
102
- }"
103
- @update:search-term="async (newSearchTerm) => {
104
- searchTerm = newSearchTerm;
105
- await onSearch?.(newSearchTerm);
48
+ :ui="{
49
+ root: 'ring-0'
106
50
  }"
107
- >
108
- <template v-if="enableFooterToolbar && multiple" #footer>
109
- <div class="flex">
110
- <UFieldGroup class="flex items-center ml-auto">
111
- <UButton
112
- v-for="action in footerActions"
113
- :key="action.label"
114
- :label="action.label"
115
- size="xs"
116
- color="neutral"
117
- variant="ghost"
118
- class="text-muted font-normal"
119
- @click="action.fn"
120
- />
121
- </UFieldGroup>
122
- </div>
123
- </template>
124
- </UCommandPalette>
51
+ :items="props.items"
52
+ :multiple="props.multiple"
53
+ />
125
54
  </template>
126
55
  </UPopover>
127
56
  </template>
@@ -1,13 +1,12 @@
1
- import type { CommandPaletteGroup, CommandPaletteProps } from '@nuxt/ui';
1
+ import type { ListboxItem, ListboxProps } from '@nuxt/ui';
2
2
  type __VLS_Props = {
3
- groups: CommandPaletteGroup[];
4
- multiple?: CommandPaletteProps['multiple'];
5
- enableFooterToolbar?: boolean;
3
+ items: ListboxItem[];
4
+ multiple?: ListboxProps['multiple'];
6
5
  onOpen?: () => Promise<void>;
7
6
  onSearch?: (searchTerm: string) => Promise<void>;
8
7
  };
9
8
  type __VLS_ModelProps = {
10
- 'modelValue'?: string | number | undefined | null | (string | number)[];
9
+ 'modelValue'?: string | number | undefined | (string | number)[];
11
10
  };
12
11
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
13
12
  declare var __VLS_8: {};
@@ -17,9 +16,9 @@ type __VLS_Slots = {} & {
17
16
  declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
18
17
  focus: () => Promise<void>;
19
18
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
- "update:modelValue": (value: string | number | (string | number)[] | null | undefined) => any;
19
+ "update:modelValue": (value: string | number | (string | number)[] | undefined) => any;
21
20
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
22
- "onUpdate:modelValue"?: ((value: string | number | (string | number)[] | null | undefined) => any) | undefined;
21
+ "onUpdate:modelValue"?: ((value: string | number | (string | number)[] | undefined) => any) | undefined;
23
22
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
24
23
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
25
24
  declare const _default: typeof __VLS_export;
@@ -23,7 +23,8 @@ const props = defineProps({
23
23
  afterSelect: { type: Function, required: false },
24
24
  canCreate: { type: Boolean, required: false },
25
25
  createModalComponent: { type: null, required: false },
26
- createModalOpenProps: { type: Object, required: false }
26
+ createModalOpenProps: { type: Object, required: false },
27
+ roundedNone: { type: Boolean, required: false }
27
28
  });
28
29
  const modelValue = defineModel("modelValue", { type: null, ...{ required: true } });
29
30
  const modelValueWithValueField = ref(modelValue.value?.map((item) => item[props.valueField]));
@@ -28,7 +28,8 @@ const props = defineProps({
28
28
  afterSelect: { type: Function, required: false },
29
29
  canCreate: { type: Boolean, required: false },
30
30
  createModalComponent: { type: null, required: false },
31
- createModalOpenProps: { type: Object, required: false }
31
+ createModalOpenProps: { type: Object, required: false },
32
+ roundedNone: { type: Boolean, required: false }
32
33
  });
33
34
  const modelValue = defineModel("modelValue", { type: null, ...{ required: true } });
34
35
  const asyncSelectModelValue = computed({
@@ -27,7 +27,8 @@ const props = defineProps({
27
27
  afterSelect: { type: Function, required: false },
28
28
  canCreate: { type: Boolean, required: false },
29
29
  createModalComponent: { type: null, required: false },
30
- createModalOpenProps: { type: Object, required: false }
30
+ createModalOpenProps: { type: Object, required: false },
31
+ roundedNone: { type: Boolean, required: false }
31
32
  });
32
33
  const modelValue = defineModel("modelValue", { type: null, ...{ required: true } });
33
34
  const asyncTreeSelectModelValue = computed({
@@ -1,16 +1,23 @@
1
1
  import type { VFormFieldSelectProps } from '#v/types';
2
- type __VLS_Props = {
3
- disabled?: boolean;
4
- icon?: string;
5
- } & VFormFieldSelectProps;
6
- type __VLS_ModelProps = {
7
- 'modelValue': string | null | undefined;
2
+ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<(VFormFieldSelectProps<T> & {
4
+ modelValue: string | number | string[] | number[] | undefined;
5
+ }) & {
6
+ "onUpdate:modelValue"?: ((value: string | number | string[] | number[] | undefined) => any) | undefined;
7
+ }> & (typeof globalThis extends {
8
+ __VLS_PROPS_FALLBACK: infer P;
9
+ } ? P : {});
10
+ expose: (exposed: {}) => void;
11
+ attrs: any;
12
+ slots: {};
13
+ emit: (event: "update:modelValue", value: string | number | string[] | number[] | undefined) => void;
14
+ }>) => import("vue").VNode & {
15
+ __ctx?: Awaited<typeof __VLS_setup>;
8
16
  };
9
- type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
10
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
- "update:modelValue": (value: string | null | undefined) => any;
12
- }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
13
- "onUpdate:modelValue"?: ((value: string | null | undefined) => any) | undefined;
14
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
17
  declare const _default: typeof __VLS_export;
16
18
  export default _default;
19
+ type __VLS_PrettifyLocal<T> = (T extends any ? {
20
+ [K in keyof T]: T[K];
21
+ } : {
22
+ [K in keyof T as K]: T[K];
23
+ }) & {};
@@ -1,13 +1,18 @@
1
1
  <script setup>
2
2
  import { computed } from "vue";
3
+ import VSelect from "#v/components/Select.vue";
3
4
  const props = defineProps({
5
+ label: { type: String, required: false },
6
+ floatingPlaceholder: { type: Boolean, required: false },
4
7
  disabled: { type: Boolean, required: false },
5
- icon: { type: String, required: false },
8
+ placeholder: { type: String, required: false },
9
+ size: { type: null, required: false },
10
+ icon: { type: null, required: false },
11
+ enableEmptyOption: { type: Boolean, required: false },
6
12
  items: { type: Array, required: true },
7
- searchable: { type: Boolean, required: false },
8
13
  multiple: { type: Boolean, required: false },
9
- enableEmptyOption: { type: Boolean, required: false },
10
- placeholder: { type: String, required: false }
14
+ afterSelect: { type: Function, required: false },
15
+ roundedNone: { type: Boolean, required: false }
11
16
  });
12
17
  const modelValue = defineModel("modelValue", { type: null, ...{ required: true } });
13
18
  const selectItems = computed(
@@ -16,10 +21,10 @@ const selectItems = computed(
16
21
  </script>
17
22
 
18
23
  <template>
19
- <USelectMenu
24
+ <VSelect
20
25
  v-model="modelValue"
26
+ v-bind="props"
21
27
  :items="selectItems"
22
- :search-input="searchable ?? false"
23
28
  :icon="icon ? icon : multiple ? 'i-lucide-list-todo' : void 0"
24
29
  :placeholder="placeholder"
25
30
  value-key="value"
@@ -1,16 +1,23 @@
1
1
  import type { VFormFieldSelectProps } from '#v/types';
2
- type __VLS_Props = {
3
- disabled?: boolean;
4
- icon?: string;
5
- } & VFormFieldSelectProps;
6
- type __VLS_ModelProps = {
7
- 'modelValue': string | null | undefined;
2
+ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<(VFormFieldSelectProps<T> & {
4
+ modelValue: string | number | string[] | number[] | undefined;
5
+ }) & {
6
+ "onUpdate:modelValue"?: ((value: string | number | string[] | number[] | undefined) => any) | undefined;
7
+ }> & (typeof globalThis extends {
8
+ __VLS_PROPS_FALLBACK: infer P;
9
+ } ? P : {});
10
+ expose: (exposed: {}) => void;
11
+ attrs: any;
12
+ slots: {};
13
+ emit: (event: "update:modelValue", value: string | number | string[] | number[] | undefined) => void;
14
+ }>) => import("vue").VNode & {
15
+ __ctx?: Awaited<typeof __VLS_setup>;
8
16
  };
9
- type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
10
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
- "update:modelValue": (value: string | null | undefined) => any;
12
- }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
13
- "onUpdate:modelValue"?: ((value: string | null | undefined) => any) | undefined;
14
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
17
  declare const _default: typeof __VLS_export;
16
18
  export default _default;
19
+ type __VLS_PrettifyLocal<T> = (T extends any ? {
20
+ [K in keyof T]: T[K];
21
+ } : {
22
+ [K in keyof T as K]: T[K];
23
+ }) & {};
@@ -110,13 +110,7 @@ const fieldModelValue = computed({
110
110
  <FormFieldSelect
111
111
  v-else-if="field.type === 'select'"
112
112
  v-model="fieldModelValue"
113
- :items="field.items"
114
- :searchable="field.searchable ?? false"
115
- :icon="field.icon ? field.icon : field.multiple ? 'i-lucide-list-todo' : void 0"
116
- :enable-empty-option="field.enableEmptyOption"
117
- :placeholder="field.placeholder"
118
- value-key="value"
119
- :disabled="field.disabled"
113
+ v-bind="field"
120
114
  />
121
115
  <USelectMenu
122
116
  v-else-if="field.type === 'multiple-select-string'"
@@ -129,6 +129,7 @@ const columns = [
129
129
  filterOption: {
130
130
  type: "select",
131
131
  items: genderOptions,
132
+ multiple: true,
132
133
  empty: {
133
134
  label: "\u672A\u77E5",
134
135
  variant: "outline",
@@ -192,11 +193,6 @@ const columns = [
192
193
  :extra-order-query-options="[
193
194
  { field: 'createdAt', label: '\u521B\u5EFA\u65F6\u95F4', defaultOpr: 'desc' }
194
195
  ]"
195
- :extra-where-query-init-values="{
196
- items: [
197
- { field: 'isAdmin', opr: 'eq', value: false }
198
- ]
199
- }"
200
196
  @edit-row-from-modal="async (row) => await createModal.open({ model: row }).result"
201
197
  />
202
198
  </template>
@@ -10,32 +10,23 @@ const props = defineProps({
10
10
  });
11
11
  const emit = defineEmits(["new"]);
12
12
  const popoverOpen = ref(false);
13
- const unselectedOptions = computed(() => {
14
- const options = [
15
- {
16
- id: "unselected-fields",
17
- label: "\u65B0\u589E\u67E5\u8BE2\u5B57\u6BB5",
18
- items: props.unselectedFields.map((field) => {
19
- const option = props.options.find((option2) => option2.field === field);
20
- const column = props.bizColumns.find((column2) => column2["accessorKey"] === field);
21
- return {
22
- label: column?.header || option?.label || field,
23
- icon: tableWhereQueryItemIconMap.get(option?.type ?? "unknown") || "field",
24
- onSelect: () => {
25
- emit("new", field);
26
- popoverOpen.value = false;
27
- }
28
- };
29
- })
13
+ const unselectedOptions = computed(() => props.unselectedFields.map((field) => {
14
+ const option = props.options.find((option2) => option2.field === field);
15
+ const column = props.bizColumns.find((column2) => column2["accessorKey"] === field);
16
+ return {
17
+ label: column?.header || option?.label || field,
18
+ icon: tableWhereQueryItemIconMap.get(option?.type ?? "unknown") || "field",
19
+ onSelect: () => {
20
+ emit("new", field);
21
+ popoverOpen.value = false;
30
22
  }
31
- ];
32
- return options;
33
- });
23
+ };
24
+ }));
34
25
  </script>
35
26
 
36
27
  <template>
37
28
  <!-- NOTE: 自己实现DropdownMenu, 原生DropdownMenu的Focus有问题,会让查询字段打开的Popover关闭 -->
38
- <ButtonDropdown :groups="unselectedOptions">
29
+ <ButtonDropdown :items="unselectedOptions">
39
30
  <UButton
40
31
  label="新增"
41
32
  :size="size"
@@ -9,25 +9,17 @@ const props = defineProps({
9
9
  focus: { type: Function, required: false }
10
10
  });
11
11
  const whereQueryItem = defineModel("whereQueryItem", { type: Object, ...{ required: true } });
12
- const items = computed(() => {
13
- return [
14
- {
15
- id: "query-fields",
16
- label: "\u67E5\u8BE2\u5B57\u6BB5",
17
- items: props.options.map((option) => ({
18
- label: option.label,
19
- value: option.field,
20
- icon: tableWhereQueryItemIconMap.get(option.type) || "field",
21
- onSelect: () => {
22
- modelValue.value = option.field;
23
- nextTick(() => {
24
- props.focus?.();
25
- });
26
- }
27
- }))
28
- }
29
- ];
30
- });
12
+ const items = computed(() => props.options.map((option) => ({
13
+ label: option.label,
14
+ value: option.field,
15
+ icon: tableWhereQueryItemIconMap.get(option.type) || "field",
16
+ onSelect: () => {
17
+ modelValue.value = option.field;
18
+ nextTick(() => {
19
+ props.focus?.();
20
+ });
21
+ }
22
+ })));
31
23
  const modelValue = computed({
32
24
  get() {
33
25
  return whereQueryItem.value.field;
@@ -53,7 +45,7 @@ const currentOption = computed(() => {
53
45
  <template>
54
46
  <ButtonDropdown
55
47
  v-model="modelValue"
56
- :groups="items"
48
+ :items="items"
57
49
  >
58
50
  <UButton
59
51
  :size="'sm'"
@@ -16,22 +16,16 @@ const items = computed(() => {
16
16
  console.error("Cannot find field option or missing type for field:", whereQueryItem.value.field);
17
17
  return [];
18
18
  }
19
- return [
20
- {
21
- id: "operators",
22
- label: "\u64CD\u4F5C\u7B26",
23
- items: useTableOpr().getOprNameOptionsByType(option.value.type).map((option2) => ({
24
- label: option2.label,
25
- value: option2.value,
26
- onSelect: () => {
27
- modelValue.value = option2.value;
28
- nextTick(() => {
29
- props.focus?.();
30
- });
31
- }
32
- }))
19
+ return useTableOpr().getOprNameOptionsByType(option.value.type).map((option2) => ({
20
+ label: option2.label,
21
+ value: option2.value,
22
+ onSelect: () => {
23
+ modelValue.value = option2.value;
24
+ nextTick(() => {
25
+ props.focus?.();
26
+ });
33
27
  }
34
- ];
28
+ }));
35
29
  });
36
30
  const modelValue = computed({
37
31
  get() {
@@ -55,7 +49,7 @@ const currentLabel = computed(() => {
55
49
  <!-- NOTE: 自己实现DropdownMenu, 原生DropdownMenu的Focus有问题,会让查询字段打开的Popover关闭 -->
56
50
  <ButtonDropdown
57
51
  v-model="modelValue"
58
- :groups="items"
52
+ :items="items"
59
53
  >
60
54
  <UButton
61
55
  size="sm"
@@ -21,7 +21,8 @@ const props = defineProps({
21
21
  afterSelect: { type: Function, required: false },
22
22
  canCreate: { type: Boolean, required: false },
23
23
  createModalComponent: { type: null, required: false },
24
- createModalOpenProps: { type: Object, required: false }
24
+ createModalOpenProps: { type: Object, required: false },
25
+ roundedNone: { type: Boolean, required: false }
25
26
  });
26
27
  const whereQueryItem = defineModel("whereQueryItem", { type: Object, ...{ required: true } });
27
28
  const modelValue = computed({
@@ -53,5 +54,6 @@ defineExpose({
53
54
  v-bind="props"
54
55
  v-model="modelValue"
55
56
  :placeholder="`\u8BF7\u9009\u62E9${label ?? ''}`"
57
+ rounded-none
56
58
  />
57
59
  </template>
@@ -1,11 +1,6 @@
1
- import type { WhereQueryItem } from '#v/types';
2
- import type { InputMenuItem, InputMenuProps } from '@nuxt/ui';
1
+ import type { VSelectProps, WhereQueryItem } from '#v/types';
3
2
  declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
- props: import("vue").PublicProps & __VLS_PrettifyLocal<({
5
- disabled?: boolean;
6
- items: InputMenuItem[];
7
- placeholder?: InputMenuProps["placeholder"];
8
- } & {
3
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<(VSelectProps<T> & {
9
4
  whereQueryItem: WhereQueryItem<T>;
10
5
  }) & {
11
6
  "onUpdate:whereQueryItem"?: ((value: WhereQueryItem<T>) => any) | undefined;
@@ -1,12 +1,21 @@
1
1
  <script setup>
2
- import { computed, ref, useTemplateRef } from "vue";
2
+ import { computed, useTemplateRef } from "vue";
3
+ import VSelect from "#v/components/Select.vue";
3
4
  const props = defineProps({
5
+ label: { type: String, required: false },
6
+ floatingPlaceholder: { type: Boolean, required: false },
4
7
  disabled: { type: Boolean, required: false },
8
+ placeholder: { type: String, required: false },
9
+ size: { type: null, required: false, default: "sm" },
10
+ icon: { type: null, required: false },
11
+ enableEmptyOption: { type: Boolean, required: false },
5
12
  items: { type: Array, required: true },
6
- placeholder: { type: String, required: false }
13
+ multiple: { type: Boolean, required: false },
14
+ afterSelect: { type: Function, required: false },
15
+ roundedNone: { type: Boolean, required: false }
7
16
  });
8
17
  const whereQueryItem = defineModel("whereQueryItem", { type: Object, ...{ required: true } });
9
- const inputMenuValue = computed({
18
+ const modelValue = computed({
10
19
  get() {
11
20
  return whereQueryItem.value.value;
12
21
  },
@@ -14,49 +23,20 @@ const inputMenuValue = computed({
14
23
  whereQueryItem.value = { ...whereQueryItem.value, value: newValue };
15
24
  }
16
25
  });
17
- const searchTerm = ref("");
18
- const filteredItems = computed(() => {
19
- if (!searchTerm.value) {
20
- return props.items;
21
- }
22
- return props.items.filter((item) => item?.label.toLowerCase().includes(searchTerm.value.toLowerCase()));
23
- });
24
- const inputMenuRef = useTemplateRef("inputMenu");
26
+ const selectRef = useTemplateRef("select");
25
27
  defineExpose({
26
28
  focus: () => {
27
- inputMenuRef.value?.inputRef.focus();
29
+ selectRef.value?.focus();
28
30
  }
29
31
  });
30
32
  </script>
31
33
 
32
34
  <template>
33
- <UInputMenu
34
- ref="inputMenu"
35
- v-model:search-term="searchTerm"
36
- v-model="inputMenuValue"
37
- :items="filteredItems"
38
- :placeholder="placeholder"
39
- multiple
40
- color="neutral"
41
- delete-icon="i-lucide-trash"
42
- value-key="value"
43
- clear
44
- clear-icon="i-lucide-circle-x"
45
- icon=""
46
- :disabled="disabled"
47
- open-on-focus
48
- trailing
49
- :ui="{
50
- root: 'rounded-none min-w-32',
51
- // TODO: 不然有rounded,这个应该是个bug
52
- content: 'min-w-fit',
53
- tagsInput: 'min-w-4 w-0'
54
- }"
55
- :content="{
56
- align: 'start'
57
- }"
58
- @update:model-value="() => {
59
- inputMenuRef?.inputRef.focus();
60
- }"
35
+ <VSelect
36
+ ref="select"
37
+ v-bind="props"
38
+ v-model="modelValue"
39
+ :placeholder="`\u8BF7\u9009\u62E9${label ?? ''}`"
40
+ rounded-none
61
41
  />
62
42
  </template>
@@ -1,11 +1,6 @@
1
- import type { WhereQueryItem } from '#v/types';
2
- import type { InputMenuItem, InputMenuProps } from '@nuxt/ui';
1
+ import type { VSelectProps, WhereQueryItem } from '#v/types';
3
2
  declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
- props: import("vue").PublicProps & __VLS_PrettifyLocal<({
5
- disabled?: boolean;
6
- items: InputMenuItem[];
7
- placeholder?: InputMenuProps["placeholder"];
8
- } & {
3
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<(VSelectProps<T> & {
9
4
  whereQueryItem: WhereQueryItem<T>;
10
5
  }) & {
11
6
  "onUpdate:whereQueryItem"?: ((value: WhereQueryItem<T>) => any) | undefined;
@@ -48,8 +48,7 @@ defineExpose({
48
48
  ref="item"
49
49
  v-model:where-query-item="whereQueryItem"
50
50
  :disabled="fetching"
51
- :items="option.items || []"
52
- :placeholder="option.placeholder"
51
+ v-bind="option"
53
52
  />
54
53
  <TableQueryWhereSimpleItemOprDatePicker
55
54
  v-else-if="option.type === 'date-picker'"
@@ -62,7 +61,6 @@ defineExpose({
62
61
  ref="item"
63
62
  v-model:where-query-item="whereQueryItem"
64
63
  :disabled="fetching"
65
- :trigger-fetching="triggerFetching"
66
64
  v-bind="option"
67
65
  />
68
66
  </template>
@@ -22,6 +22,7 @@ export type VAsyncSelectProps<T> = {
22
22
  canCreate?: boolean;
23
23
  createModalComponent?: Component;
24
24
  createModalOpenProps?: Record<string, any>;
25
+ roundedNone?: boolean;
25
26
  };
26
27
  export type AsyncSelectValue = string[] | number[] | string | number | undefined;
27
28
  export type AsyncSelectCombinedValue = {
@@ -1,7 +1,7 @@
1
1
  import type { VNode } from 'vue';
2
- import type { ButtonProps, FormFieldProps, InputProps, RadioGroupProps, SelectMenuItem, SelectProps, TreeItem } from '@nuxt/ui';
2
+ import type { ButtonProps, FormFieldProps, InputProps, RadioGroupProps, SelectMenuItem, TreeItem } from '@nuxt/ui';
3
3
  import type { ZodType } from 'zod';
4
- import type { VAsyncSelectProps } from '#v/types';
4
+ import type { VAsyncSelectProps, VSelectProps } from '#v/types';
5
5
  export type VFormFieldAsyncSelectProps<T> = {
6
6
  initModel?: any | any[];
7
7
  onUpdateInitModel?(model: any | any[] | undefined): void;
@@ -16,12 +16,7 @@ export type VFormFieldTreeSelectTransferProps = {
16
16
  onUpdateTargetTreeItems: (val: TreeItem[]) => void;
17
17
  disabled?: boolean;
18
18
  };
19
- export type VFormFieldSelectProps = {
20
- items: SelectMenuItem[];
21
- searchable?: boolean;
22
- multiple?: SelectProps['multiple'];
23
- enableEmptyOption?: boolean;
24
- } & Pick<SelectProps, 'placeholder'>;
19
+ export type VFormFieldSelectProps<T> = {} & VSelectProps<T>;
25
20
  export type VFormFieldDynamicObjectInputProps = {
26
21
  objectFields: Array<{
27
22
  key: string;
@@ -66,7 +61,7 @@ export type VFormFieldProps = FormFieldProps & {
66
61
  peerButtons?: ButtonProps[];
67
62
  } | {
68
63
  type: 'select';
69
- } & VFormFieldSelectProps | {
64
+ } & VFormFieldSelectProps<any> | {
70
65
  type: 'multiple-select-string';
71
66
  items: SelectMenuItem[];
72
67
  searchable?: boolean;
@@ -3,3 +3,4 @@ export * from './form/index.js';
3
3
  export * from './date.js';
4
4
  export * from './dnd.js';
5
5
  export * from './async-select.js';
6
+ export * from './select.js';
@@ -3,3 +3,4 @@ export * from "./form/index.js";
3
3
  export * from "./date.js";
4
4
  export * from "./dnd.js";
5
5
  export * from "./async-select.js";
6
+ export * from "./select.js";
@@ -0,0 +1,14 @@
1
+ import type { InputMenuItem, InputMenuProps } from '@nuxt/ui';
2
+ export type VSelectProps<T> = {
3
+ label?: string;
4
+ floatingPlaceholder?: boolean;
5
+ disabled?: InputMenuProps['disabled'];
6
+ placeholder?: InputMenuProps['placeholder'];
7
+ size?: InputMenuProps['size'];
8
+ icon?: InputMenuProps['icon'];
9
+ enableEmptyOption?: boolean;
10
+ items: InputMenuItem[];
11
+ multiple?: boolean;
12
+ afterSelect?(selected: T | T[] | undefined): void;
13
+ roundedNone?: boolean;
14
+ };
File without changes
@@ -1,6 +1,6 @@
1
1
  import type { OrderQueryOpr, WhereQueryOpr } from '../../query.js';
2
- import type { TableColumn, BadgeProps, InputMenuProps } from '@nuxt/ui';
3
- import type { SelectOption, VAsyncSelectProps } from '../../index.js';
2
+ import type { BadgeProps, TableColumn } from '@nuxt/ui';
3
+ import type { VAsyncSelectProps, VSelectProps } from '../../index.js';
4
4
  export type WhereQueryType = 'input' | 'input-number' | 'date-picker' | 'select' | 'async-select' | 'unknown';
5
5
  export type WhereQueryColumnOption<T> = {
6
6
  defaultOpr?: WhereQueryOpr;
@@ -17,10 +17,8 @@ export type WhereQueryColumnOption<T> = {
17
17
  } | {
18
18
  type: 'select';
19
19
  variant?: BadgeProps['variant'];
20
- items: SelectOption[];
21
20
  empty?: BadgeProps;
22
- placeholder?: InputMenuProps['placeholder'];
23
- } | {
21
+ } & VSelectProps<T> | {
24
22
  type: 'async-select';
25
23
  } & VAsyncSelectProps<T> | {
26
24
  type: 'unknown';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "v-nuxt-ui",
3
- "version": "0.2.19",
3
+ "version": "0.2.22",
4
4
  "description": "Veken UI Component Library - Reusable Nuxt UI components, composables, and utilities for enterprise applications",
5
5
  "type": "module",
6
6
  "style": "./dist/runtime/index.css",
@@ -71,7 +71,7 @@
71
71
  "@nuxt/eslint-config": "^1.15.2",
72
72
  "@nuxt/fonts": "^0.12.1",
73
73
  "@nuxt/module-builder": "^1.0.2",
74
- "@nuxt/ui": "^4.6.1",
74
+ "@nuxt/ui": "^4.7.0",
75
75
  "@nuxtjs/i18n": "^10.2.4",
76
76
  "@nuxtjs/mdc": "^0.20.2",
77
77
  "@tanstack/table-core": "^8.21.3",