@nuxt/ui 4.5.1 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.d.mts +7 -0
- package/dist/module.json +2 -2
- package/dist/module.mjs +78 -67
- package/dist/runtime/components/Avatar.vue +10 -12
- package/dist/runtime/components/Banner.vue +1 -1
- package/dist/runtime/components/BlogPost.vue +3 -2
- package/dist/runtime/components/Calendar.d.vue.ts +4 -4
- package/dist/runtime/components/Calendar.vue.d.ts +4 -4
- package/dist/runtime/components/ChangelogVersion.vue +3 -2
- package/dist/runtime/components/ChangelogVersions.vue +1 -1
- package/dist/runtime/components/ChatMessage.d.vue.ts +4 -1
- package/dist/runtime/components/ChatMessage.vue +5 -0
- package/dist/runtime/components/ChatMessage.vue.d.ts +4 -1
- package/dist/runtime/components/ChatReasoning.d.vue.ts +78 -0
- package/dist/runtime/components/ChatReasoning.vue +162 -0
- package/dist/runtime/components/ChatReasoning.vue.d.ts +78 -0
- package/dist/runtime/components/ChatShimmer.d.vue.ts +34 -0
- package/dist/runtime/components/ChatShimmer.vue +37 -0
- package/dist/runtime/components/ChatShimmer.vue.d.ts +34 -0
- package/dist/runtime/components/ChatTool.d.vue.ts +88 -0
- package/dist/runtime/components/ChatTool.vue +105 -0
- package/dist/runtime/components/ChatTool.vue.d.ts +88 -0
- package/dist/runtime/components/Checkbox.d.vue.ts +22 -19
- package/dist/runtime/components/Checkbox.vue +9 -8
- package/dist/runtime/components/Checkbox.vue.d.ts +22 -19
- package/dist/runtime/components/DashboardGroup.d.vue.ts +1 -1
- package/dist/runtime/components/DashboardGroup.vue.d.ts +1 -1
- package/dist/runtime/components/DashboardSearchButton.vue +2 -2
- package/dist/runtime/components/Drawer.vue +1 -1
- package/dist/runtime/components/DropdownMenu.d.vue.ts +29 -3
- package/dist/runtime/components/DropdownMenu.vue +9 -0
- package/dist/runtime/components/DropdownMenu.vue.d.ts +29 -3
- package/dist/runtime/components/DropdownMenuContent.d.vue.ts +9 -3
- package/dist/runtime/components/DropdownMenuContent.vue +62 -9
- package/dist/runtime/components/DropdownMenuContent.vue.d.ts +9 -3
- package/dist/runtime/components/EditorDragHandle.d.vue.ts +4 -4
- package/dist/runtime/components/EditorDragHandle.vue.d.ts +4 -4
- package/dist/runtime/components/Error.vue +5 -5
- package/dist/runtime/components/FileUpload.d.vue.ts +6 -0
- package/dist/runtime/components/FileUpload.vue +11 -7
- package/dist/runtime/components/FileUpload.vue.d.ts +6 -0
- package/dist/runtime/components/Icon.d.vue.ts +2 -1
- package/dist/runtime/components/Icon.vue +1 -1
- package/dist/runtime/components/Icon.vue.d.ts +2 -1
- package/dist/runtime/components/InputDate.d.vue.ts +4 -4
- package/dist/runtime/components/InputDate.vue.d.ts +4 -4
- package/dist/runtime/components/InputMenu.d.vue.ts +7 -1
- package/dist/runtime/components/InputMenu.vue +67 -48
- package/dist/runtime/components/InputMenu.vue.d.ts +7 -1
- package/dist/runtime/components/InputTime.d.vue.ts +53 -27
- package/dist/runtime/components/InputTime.vue +52 -27
- package/dist/runtime/components/InputTime.vue.d.ts +53 -27
- package/dist/runtime/components/Kbd.vue +1 -1
- package/dist/runtime/components/Modal.vue +1 -1
- package/dist/runtime/components/NavigationMenu.vue +1 -0
- package/dist/runtime/components/Popover.vue +1 -1
- package/dist/runtime/components/Progress.d.vue.ts +1 -1
- package/dist/runtime/components/Progress.vue.d.ts +1 -1
- package/dist/runtime/components/SelectMenu.d.vue.ts +1 -1
- package/dist/runtime/components/SelectMenu.vue +1 -1
- package/dist/runtime/components/SelectMenu.vue.d.ts +1 -1
- package/dist/runtime/components/Sidebar.d.vue.ts +131 -0
- package/dist/runtime/components/Sidebar.vue +222 -0
- package/dist/runtime/components/Sidebar.vue.d.ts +131 -0
- package/dist/runtime/components/Slideover.vue +1 -1
- package/dist/runtime/components/Switch.d.vue.ts +22 -19
- package/dist/runtime/components/Switch.vue +7 -6
- package/dist/runtime/components/Switch.vue.d.ts +22 -19
- package/dist/runtime/components/Table.d.vue.ts +1 -1
- package/dist/runtime/components/Table.vue +12 -4
- package/dist/runtime/components/Table.vue.d.ts +1 -1
- package/dist/runtime/components/Tooltip.d.vue.ts +2 -0
- package/dist/runtime/components/Tooltip.vue +3 -2
- package/dist/runtime/components/Tooltip.vue.d.ts +2 -0
- package/dist/runtime/components/color-mode/ColorModeSelect.d.vue.ts +1 -1
- package/dist/runtime/components/color-mode/ColorModeSelect.vue.d.ts +1 -1
- package/dist/runtime/components/color-mode/ColorModeSwitch.vue +3 -1
- package/dist/runtime/components/content/ContentNavigation.vue +9 -2
- package/dist/runtime/components/content/ContentSurround.vue +6 -2
- package/dist/runtime/components/content/ContentToc.d.vue.ts +5 -0
- package/dist/runtime/components/content/ContentToc.vue +57 -11
- package/dist/runtime/components/content/ContentToc.vue.d.ts +5 -0
- package/dist/runtime/components/locale/LocaleSelect.d.vue.ts +1 -1
- package/dist/runtime/components/locale/LocaleSelect.vue.d.ts +1 -1
- package/dist/runtime/components/prose/Pre.vue +0 -4
- package/dist/runtime/composables/index.d.ts +11 -0
- package/dist/runtime/composables/index.js +11 -0
- package/dist/runtime/composables/useEditorMenu.js +1 -1
- package/dist/runtime/composables/useFileUpload.d.ts +2 -2
- package/dist/runtime/composables/useFileUpload.js +3 -3
- package/dist/runtime/composables/{internal/useFilter.js → useFilter.js} +1 -1
- package/dist/runtime/composables/useScrollShadow.d.ts +23 -0
- package/dist/runtime/composables/useScrollShadow.js +36 -0
- package/dist/runtime/index.css +1 -1
- package/dist/runtime/keyframes.css +1 -1
- package/dist/runtime/locale/ar.js +13 -0
- package/dist/runtime/locale/az.js +13 -0
- package/dist/runtime/locale/be.js +13 -0
- package/dist/runtime/locale/bg.js +13 -0
- package/dist/runtime/locale/bn.js +13 -0
- package/dist/runtime/locale/ca.js +13 -0
- package/dist/runtime/locale/ckb.js +13 -0
- package/dist/runtime/locale/cs.js +13 -0
- package/dist/runtime/locale/da.js +13 -0
- package/dist/runtime/locale/de.js +13 -0
- package/dist/runtime/locale/de_ch.js +13 -0
- package/dist/runtime/locale/el.js +13 -0
- package/dist/runtime/locale/en.js +13 -0
- package/dist/runtime/locale/es.js +13 -0
- package/dist/runtime/locale/et.js +13 -0
- package/dist/runtime/locale/eu.js +13 -0
- package/dist/runtime/locale/fa_ir.js +13 -0
- package/dist/runtime/locale/fi.js +13 -0
- package/dist/runtime/locale/fr.js +13 -0
- package/dist/runtime/locale/gl.js +13 -0
- package/dist/runtime/locale/he.js +13 -0
- package/dist/runtime/locale/hi.js +13 -0
- package/dist/runtime/locale/hr.js +13 -0
- package/dist/runtime/locale/hu.js +13 -0
- package/dist/runtime/locale/hy.js +13 -0
- package/dist/runtime/locale/id.js +13 -0
- package/dist/runtime/locale/index.d.ts +1 -0
- package/dist/runtime/locale/index.js +1 -0
- package/dist/runtime/locale/is.d.ts +3 -0
- package/dist/runtime/locale/is.js +142 -0
- package/dist/runtime/locale/it.js +13 -0
- package/dist/runtime/locale/ja.js +13 -0
- package/dist/runtime/locale/ka.js +13 -0
- package/dist/runtime/locale/kk.js +13 -0
- package/dist/runtime/locale/km.js +13 -0
- package/dist/runtime/locale/ko.js +13 -0
- package/dist/runtime/locale/ky.js +13 -0
- package/dist/runtime/locale/lb.js +13 -0
- package/dist/runtime/locale/lo.js +13 -0
- package/dist/runtime/locale/lt.js +13 -0
- package/dist/runtime/locale/mn.js +13 -0
- package/dist/runtime/locale/ms.js +13 -0
- package/dist/runtime/locale/nb_no.js +13 -0
- package/dist/runtime/locale/nl.js +13 -0
- package/dist/runtime/locale/pl.js +13 -0
- package/dist/runtime/locale/pt.js +13 -0
- package/dist/runtime/locale/pt_br.js +13 -0
- package/dist/runtime/locale/ro.js +13 -0
- package/dist/runtime/locale/ru.js +13 -0
- package/dist/runtime/locale/sk.js +13 -0
- package/dist/runtime/locale/sl.js +13 -0
- package/dist/runtime/locale/sq.js +13 -0
- package/dist/runtime/locale/sv.js +13 -0
- package/dist/runtime/locale/th.js +13 -0
- package/dist/runtime/locale/tj.js +13 -0
- package/dist/runtime/locale/tr.js +13 -0
- package/dist/runtime/locale/ug_cn.js +13 -0
- package/dist/runtime/locale/uk.js +13 -0
- package/dist/runtime/locale/ur.js +13 -0
- package/dist/runtime/locale/uz.js +13 -0
- package/dist/runtime/locale/vi.js +13 -0
- package/dist/runtime/locale/zh_cn.js +13 -0
- package/dist/runtime/locale/zh_tw.js +13 -0
- package/dist/runtime/types/index.d.ts +4 -0
- package/dist/runtime/types/index.js +4 -0
- package/dist/runtime/types/locale.d.ts +13 -0
- package/dist/runtime/utils/ai.d.ts +18 -0
- package/dist/runtime/utils/ai.js +13 -0
- package/dist/runtime/utils/editor.js +17 -5
- package/dist/runtime/vue/components/Icon.d.vue.ts +1 -4
- package/dist/runtime/vue/components/Icon.vue +28 -3
- package/dist/runtime/vue/components/Icon.vue.d.ts +1 -4
- package/dist/runtime/vue/components/color-mode/ColorModeSelect.d.vue.ts +1 -1
- package/dist/runtime/vue/components/color-mode/ColorModeSelect.vue.d.ts +1 -1
- package/dist/runtime/vue/components/color-mode/ColorModeSwitch.vue +3 -1
- package/dist/shared/{ui.DI_ypO2T.mjs → ui.DJUbBpE2.mjs} +298 -39
- package/dist/unplugin.d.mts +15 -5
- package/dist/unplugin.mjs +53 -30
- package/dist/vite.d.mts +1 -0
- package/dist/vite.mjs +1 -1
- package/package.json +49 -46
- /package/dist/runtime/composables/{internal/useFilter.d.ts → useFilter.d.ts} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CheckboxRootProps } from 'reka-ui';
|
|
1
|
+
import type { CheckboxRootProps, CheckboxRootEmits } from 'reka-ui';
|
|
2
2
|
import type { VNode } from 'vue';
|
|
3
3
|
import type { AppConfig } from '@nuxt/schema';
|
|
4
4
|
import theme from '#build/ui/checkbox';
|
|
@@ -6,7 +6,7 @@ import type { IconProps } from '../types';
|
|
|
6
6
|
import type { ButtonHTMLAttributes } from '../types/html';
|
|
7
7
|
import type { ComponentConfig } from '../types/tv';
|
|
8
8
|
type Checkbox = ComponentConfig<typeof theme, AppConfig, 'checkbox'>;
|
|
9
|
-
export interface CheckboxProps extends Pick<CheckboxRootProps
|
|
9
|
+
export interface CheckboxProps<T = boolean> extends Pick<CheckboxRootProps<T>, 'disabled' | 'required' | 'name' | 'value' | 'id' | 'defaultValue' | 'modelValue' | 'trueValue' | 'falseValue'>, /** @vue-ignore */ Omit<ButtonHTMLAttributes, 'type' | 'disabled' | 'name'> {
|
|
10
10
|
/**
|
|
11
11
|
* The element or component this component should render as.
|
|
12
12
|
* @defaultValue 'div'
|
|
@@ -46,9 +46,9 @@ export interface CheckboxProps extends Pick<CheckboxRootProps, 'disabled' | 'req
|
|
|
46
46
|
class?: any;
|
|
47
47
|
ui?: Checkbox['slots'];
|
|
48
48
|
}
|
|
49
|
-
export
|
|
49
|
+
export interface CheckboxEmits<T = boolean> extends CheckboxRootEmits<T> {
|
|
50
50
|
change: [event: Event];
|
|
51
|
-
}
|
|
51
|
+
}
|
|
52
52
|
export interface CheckboxSlots {
|
|
53
53
|
label?(props: {
|
|
54
54
|
label: string | undefined;
|
|
@@ -59,19 +59,22 @@ export interface CheckboxSlots {
|
|
|
59
59
|
}
|
|
60
60
|
declare const _default: typeof __VLS_export;
|
|
61
61
|
export default _default;
|
|
62
|
-
declare const __VLS_export:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
$slots: S;
|
|
76
|
-
};
|
|
62
|
+
declare const __VLS_export: <T = boolean>(__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<{
|
|
63
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<CheckboxProps<T> & {
|
|
64
|
+
onChange?: ((event: Event) => any) | undefined;
|
|
65
|
+
"onUpdate:modelValue"?: ((value: "indeterminate" | T) => any) | undefined;
|
|
66
|
+
}> & (typeof globalThis extends {
|
|
67
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
68
|
+
} ? P : {});
|
|
69
|
+
expose: (exposed: {}) => void;
|
|
70
|
+
attrs: any;
|
|
71
|
+
slots: CheckboxSlots;
|
|
72
|
+
emit: ((evt: "change", event: Event) => void) & ((evt: "update:modelValue", value: "indeterminate" | T) => void);
|
|
73
|
+
}>) => import("vue").VNode & {
|
|
74
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
77
75
|
};
|
|
76
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
77
|
+
[K in keyof T]: T[K];
|
|
78
|
+
} : {
|
|
79
|
+
[K in keyof T as K]: T[K];
|
|
80
|
+
}) & {};
|
|
@@ -4,7 +4,7 @@ import theme from "#build/ui/checkbox";
|
|
|
4
4
|
|
|
5
5
|
<script setup>
|
|
6
6
|
import { computed, useAttrs, useId } from "vue";
|
|
7
|
-
import { Primitive, CheckboxRoot, CheckboxIndicator, Label,
|
|
7
|
+
import { Primitive, CheckboxRoot, CheckboxIndicator, Label, useForwardPropsEmits } from "reka-ui";
|
|
8
8
|
import { reactivePick } from "@vueuse/core";
|
|
9
9
|
import { useAppConfig } from "#imports";
|
|
10
10
|
import { useComponentUI } from "../composables/useComponentUI";
|
|
@@ -29,14 +29,16 @@ const props = defineProps({
|
|
|
29
29
|
name: { type: String, required: false },
|
|
30
30
|
value: { type: null, required: false },
|
|
31
31
|
id: { type: String, required: false },
|
|
32
|
-
defaultValue: { type:
|
|
32
|
+
defaultValue: { type: null, required: false },
|
|
33
|
+
modelValue: { type: null, required: false },
|
|
34
|
+
trueValue: { type: null, required: false },
|
|
35
|
+
falseValue: { type: null, required: false }
|
|
33
36
|
});
|
|
34
37
|
const slots = defineSlots();
|
|
35
|
-
const emits = defineEmits(["change"]);
|
|
36
|
-
const modelValue = defineModel({ type: [Boolean, String], ...{ default: void 0 } });
|
|
38
|
+
const emits = defineEmits(["change", "update:modelValue"]);
|
|
37
39
|
const appConfig = useAppConfig();
|
|
38
40
|
const uiProp = useComponentUI("checkbox", props);
|
|
39
|
-
const rootProps =
|
|
41
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, "required", "value", "defaultValue", "modelValue", "trueValue", "falseValue"), emits);
|
|
40
42
|
const { id: _id, emitFormChange, emitFormInput, size, color, name, disabled, ariaAttrs } = useFormField(props);
|
|
41
43
|
const id = _id.value ?? useId();
|
|
42
44
|
const attrs = useAttrs();
|
|
@@ -66,16 +68,15 @@ function onUpdate(value) {
|
|
|
66
68
|
<CheckboxRoot
|
|
67
69
|
:id="id"
|
|
68
70
|
v-bind="{ ...rootProps, ...forwardedAttrs, ...ariaAttrs }"
|
|
69
|
-
v-model="modelValue"
|
|
70
71
|
:name="name"
|
|
71
72
|
:disabled="disabled"
|
|
72
73
|
data-slot="base"
|
|
73
74
|
:class="ui.base({ class: uiProp?.base })"
|
|
74
75
|
@update:model-value="onUpdate"
|
|
75
76
|
>
|
|
76
|
-
<template #default="{
|
|
77
|
+
<template #default="{ state }">
|
|
77
78
|
<CheckboxIndicator data-slot="indicator" :class="ui.indicator({ class: uiProp?.indicator })">
|
|
78
|
-
<UIcon v-if="
|
|
79
|
+
<UIcon v-if="state === 'indeterminate'" :name="indeterminateIcon || appConfig.ui.icons.minus" data-slot="icon" :class="ui.icon({ class: uiProp?.icon })" />
|
|
79
80
|
<UIcon v-else :name="icon || appConfig.ui.icons.check" data-slot="icon" :class="ui.icon({ class: uiProp?.icon })" />
|
|
80
81
|
</CheckboxIndicator>
|
|
81
82
|
</template>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CheckboxRootProps } from 'reka-ui';
|
|
1
|
+
import type { CheckboxRootProps, CheckboxRootEmits } from 'reka-ui';
|
|
2
2
|
import type { VNode } from 'vue';
|
|
3
3
|
import type { AppConfig } from '@nuxt/schema';
|
|
4
4
|
import theme from '#build/ui/checkbox';
|
|
@@ -6,7 +6,7 @@ import type { IconProps } from '../types';
|
|
|
6
6
|
import type { ButtonHTMLAttributes } from '../types/html';
|
|
7
7
|
import type { ComponentConfig } from '../types/tv';
|
|
8
8
|
type Checkbox = ComponentConfig<typeof theme, AppConfig, 'checkbox'>;
|
|
9
|
-
export interface CheckboxProps extends Pick<CheckboxRootProps
|
|
9
|
+
export interface CheckboxProps<T = boolean> extends Pick<CheckboxRootProps<T>, 'disabled' | 'required' | 'name' | 'value' | 'id' | 'defaultValue' | 'modelValue' | 'trueValue' | 'falseValue'>, /** @vue-ignore */ Omit<ButtonHTMLAttributes, 'type' | 'disabled' | 'name'> {
|
|
10
10
|
/**
|
|
11
11
|
* The element or component this component should render as.
|
|
12
12
|
* @defaultValue 'div'
|
|
@@ -46,9 +46,9 @@ export interface CheckboxProps extends Pick<CheckboxRootProps, 'disabled' | 'req
|
|
|
46
46
|
class?: any;
|
|
47
47
|
ui?: Checkbox['slots'];
|
|
48
48
|
}
|
|
49
|
-
export
|
|
49
|
+
export interface CheckboxEmits<T = boolean> extends CheckboxRootEmits<T> {
|
|
50
50
|
change: [event: Event];
|
|
51
|
-
}
|
|
51
|
+
}
|
|
52
52
|
export interface CheckboxSlots {
|
|
53
53
|
label?(props: {
|
|
54
54
|
label: string | undefined;
|
|
@@ -59,19 +59,22 @@ export interface CheckboxSlots {
|
|
|
59
59
|
}
|
|
60
60
|
declare const _default: typeof __VLS_export;
|
|
61
61
|
export default _default;
|
|
62
|
-
declare const __VLS_export:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
$slots: S;
|
|
76
|
-
};
|
|
62
|
+
declare const __VLS_export: <T = boolean>(__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<{
|
|
63
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<CheckboxProps<T> & {
|
|
64
|
+
onChange?: ((event: Event) => any) | undefined;
|
|
65
|
+
"onUpdate:modelValue"?: ((value: "indeterminate" | T) => any) | undefined;
|
|
66
|
+
}> & (typeof globalThis extends {
|
|
67
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
68
|
+
} ? P : {});
|
|
69
|
+
expose: (exposed: {}) => void;
|
|
70
|
+
attrs: any;
|
|
71
|
+
slots: CheckboxSlots;
|
|
72
|
+
emit: ((evt: "change", event: Event) => void) & ((evt: "update:modelValue", value: "indeterminate" | T) => void);
|
|
73
|
+
}>) => import("vue").VNode & {
|
|
74
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
77
75
|
};
|
|
76
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
77
|
+
[K in keyof T]: T[K];
|
|
78
|
+
} : {
|
|
79
|
+
[K in keyof T as K]: T[K];
|
|
80
|
+
}) & {};
|
|
@@ -18,9 +18,9 @@ declare const _default: typeof __VLS_export;
|
|
|
18
18
|
export default _default;
|
|
19
19
|
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<DashboardGroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<DashboardGroupProps> & Readonly<{}>, {
|
|
20
20
|
storage: "cookie" | "local";
|
|
21
|
+
unit: "%" | "rem" | "px";
|
|
21
22
|
storageKey: string;
|
|
22
23
|
persistent: boolean;
|
|
23
|
-
unit: "%" | "rem" | "px";
|
|
24
24
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, DashboardGroupSlots>;
|
|
25
25
|
type __VLS_WithSlots<T, S> = T & {
|
|
26
26
|
new (): {
|
|
@@ -18,9 +18,9 @@ declare const _default: typeof __VLS_export;
|
|
|
18
18
|
export default _default;
|
|
19
19
|
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<DashboardGroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<DashboardGroupProps> & Readonly<{}>, {
|
|
20
20
|
storage: "cookie" | "local";
|
|
21
|
+
unit: "%" | "rem" | "px";
|
|
21
22
|
storageKey: string;
|
|
22
23
|
persistent: boolean;
|
|
23
|
-
unit: "%" | "rem" | "px";
|
|
24
24
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, DashboardGroupSlots>;
|
|
25
25
|
type __VLS_WithSlots<T, S> = T & {
|
|
26
26
|
new (): {
|
|
@@ -85,13 +85,13 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.dashboardSear
|
|
|
85
85
|
</template>
|
|
86
86
|
|
|
87
87
|
<template #trailing="{ ui: uiProxy }">
|
|
88
|
-
<
|
|
88
|
+
<span data-slot="trailing" :class="ui.trailing({ class: uiProp?.trailing })">
|
|
89
89
|
<slot name="trailing" :ui="uiProxy">
|
|
90
90
|
<template v-if="kbds?.length">
|
|
91
91
|
<UKbd v-for="(kbd, index) in kbds" :key="index" variant="subtle" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
|
|
92
92
|
</template>
|
|
93
93
|
</slot>
|
|
94
|
-
</
|
|
94
|
+
</span>
|
|
95
95
|
</template>
|
|
96
96
|
</UButton>
|
|
97
97
|
</DefineButtonTemplate>
|
|
@@ -49,7 +49,7 @@ const portalProps = usePortal(toRef(() => props.portal));
|
|
|
49
49
|
const contentProps = toRef(() => props.content);
|
|
50
50
|
const contentEvents = computed(() => {
|
|
51
51
|
if (!props.dismissible) {
|
|
52
|
-
const events = ["
|
|
52
|
+
const events = ["interactOutside", "escapeKeyDown"];
|
|
53
53
|
return events.reduce((acc, curr) => {
|
|
54
54
|
acc[curr] = (e) => {
|
|
55
55
|
e.preventDefault();
|
|
@@ -2,7 +2,7 @@ import type { DropdownMenuRootProps, DropdownMenuRootEmits, DropdownMenuContentP
|
|
|
2
2
|
import type { VNode } from 'vue';
|
|
3
3
|
import type { AppConfig } from '@nuxt/schema';
|
|
4
4
|
import theme from '#build/ui/dropdown-menu';
|
|
5
|
-
import type { AvatarProps, IconProps, KbdProps, LinkProps } from '../types';
|
|
5
|
+
import type { AvatarProps, IconProps, InputProps, KbdProps, LinkProps } from '../types';
|
|
6
6
|
import type { ArrayOrNested, DynamicSlots, GetItemKeys, MergeTypes, NestedItem, EmitsToProps } from '../types/utils';
|
|
7
7
|
import type { ComponentConfig } from '../types/tv';
|
|
8
8
|
type DropdownMenu = ComponentConfig<typeof theme, AppConfig, 'dropdownMenu'>;
|
|
@@ -30,6 +30,9 @@ export interface DropdownMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'cust
|
|
|
30
30
|
checked?: boolean;
|
|
31
31
|
open?: boolean;
|
|
32
32
|
defaultOpen?: boolean;
|
|
33
|
+
filter?: boolean | Omit<InputProps, 'modelValue' | 'defaultValue'>;
|
|
34
|
+
filterFields?: string[];
|
|
35
|
+
ignoreFilter?: boolean;
|
|
33
36
|
children?: ArrayOrNested<DropdownMenuItem>;
|
|
34
37
|
onSelect?: (e: Event) => void;
|
|
35
38
|
onUpdateChecked?: (checked: boolean) => void;
|
|
@@ -88,6 +91,23 @@ export interface DropdownMenuProps<T extends ArrayOrNested<DropdownMenuItem> = A
|
|
|
88
91
|
* @defaultValue 'description'
|
|
89
92
|
*/
|
|
90
93
|
descriptionKey?: GetItemKeys<T>;
|
|
94
|
+
/**
|
|
95
|
+
* Whether to display a filter input or not.
|
|
96
|
+
* Can be an object to pass additional props to the input.
|
|
97
|
+
* `{ placeholder: 'Search...', variant: 'none' }`{lang="ts-type"}
|
|
98
|
+
* @defaultValue false
|
|
99
|
+
*/
|
|
100
|
+
filter?: boolean | Omit<InputProps, 'modelValue' | 'defaultValue'>;
|
|
101
|
+
/**
|
|
102
|
+
* The fields to filter by.
|
|
103
|
+
* @defaultValue [labelKey]
|
|
104
|
+
*/
|
|
105
|
+
filterFields?: string[];
|
|
106
|
+
/**
|
|
107
|
+
* When `true`, items will not be filtered which is useful for custom filtering.
|
|
108
|
+
* @defaultValue false
|
|
109
|
+
*/
|
|
110
|
+
ignoreFilter?: boolean;
|
|
91
111
|
disabled?: boolean;
|
|
92
112
|
class?: any;
|
|
93
113
|
ui?: DropdownMenu['slots'];
|
|
@@ -117,6 +137,9 @@ export type DropdownMenuSlots<A extends ArrayOrNested<DropdownMenuItem> = ArrayO
|
|
|
117
137
|
index: number;
|
|
118
138
|
}) => VNode[];
|
|
119
139
|
'item-trailing'?: SlotProps<T>;
|
|
140
|
+
'empty'?(props: {
|
|
141
|
+
searchTerm: string;
|
|
142
|
+
}): VNode[];
|
|
120
143
|
'content-top'?: (props: {
|
|
121
144
|
sub: boolean;
|
|
122
145
|
}) => VNode[];
|
|
@@ -134,15 +157,18 @@ export type DropdownMenuSlots<A extends ArrayOrNested<DropdownMenuItem> = ArrayO
|
|
|
134
157
|
declare const _default: typeof __VLS_export;
|
|
135
158
|
export default _default;
|
|
136
159
|
declare const __VLS_export: <T extends ArrayOrNested<DropdownMenuItem>>(__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<{
|
|
137
|
-
props: import("vue").PublicProps & __VLS_PrettifyLocal<DropdownMenuProps<T> & {
|
|
160
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<(DropdownMenuProps<T> & {
|
|
161
|
+
searchTerm?: string;
|
|
162
|
+
}) & {
|
|
138
163
|
"onUpdate:open"?: ((payload: boolean) => any) | undefined;
|
|
164
|
+
"onUpdate:searchTerm"?: ((value: string) => any) | undefined;
|
|
139
165
|
}> & (typeof globalThis extends {
|
|
140
166
|
__VLS_PROPS_FALLBACK: infer P;
|
|
141
167
|
} ? P : {});
|
|
142
168
|
expose: (exposed: {}) => void;
|
|
143
169
|
attrs: any;
|
|
144
170
|
slots: DropdownMenuSlots<T, NestedItem<T>>;
|
|
145
|
-
emit: (evt: "update:open", payload: boolean) => void;
|
|
171
|
+
emit: ((evt: "update:open", payload: boolean) => void) & ((event: "update:searchTerm", value: string) => void);
|
|
146
172
|
}>) => import("vue").VNode & {
|
|
147
173
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
148
174
|
};
|
|
@@ -23,6 +23,9 @@ const props = defineProps({
|
|
|
23
23
|
portal: { type: [Boolean, String], required: false, skipCheck: true, default: true },
|
|
24
24
|
labelKey: { type: null, required: false, default: "label" },
|
|
25
25
|
descriptionKey: { type: null, required: false, default: "description" },
|
|
26
|
+
filter: { type: [Boolean, Object], required: false, default: false },
|
|
27
|
+
filterFields: { type: Array, required: false },
|
|
28
|
+
ignoreFilter: { type: Boolean, required: false, default: false },
|
|
26
29
|
disabled: { type: Boolean, required: false },
|
|
27
30
|
class: { type: null, required: false },
|
|
28
31
|
ui: { type: Object, required: false },
|
|
@@ -32,6 +35,7 @@ const props = defineProps({
|
|
|
32
35
|
});
|
|
33
36
|
const emits = defineEmits(["update:open"]);
|
|
34
37
|
const slots = defineSlots();
|
|
38
|
+
const searchTerm = defineModel("searchTerm", { type: String, ...{ default: "" } });
|
|
35
39
|
const appConfig = useAppConfig();
|
|
36
40
|
const uiProp = useComponentUI("dropdownMenu", props);
|
|
37
41
|
const rootProps = useForwardPropsEmits(reactivePick(props, "defaultOpen", "open", "modal"), emits);
|
|
@@ -50,6 +54,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.dropdownMenu
|
|
|
50
54
|
</DropdownMenuTrigger>
|
|
51
55
|
|
|
52
56
|
<UDropdownMenuContent
|
|
57
|
+
v-model:search-term="searchTerm"
|
|
53
58
|
:class="ui.content({ class: [!slots.default && props.class, uiProp?.content] })"
|
|
54
59
|
:ui="ui"
|
|
55
60
|
:ui-override="uiProp"
|
|
@@ -61,6 +66,10 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.dropdownMenu
|
|
|
61
66
|
:checked-icon="checkedIcon"
|
|
62
67
|
:loading-icon="loadingIcon"
|
|
63
68
|
:external-icon="externalIcon"
|
|
69
|
+
:size="size"
|
|
70
|
+
:filter="filter"
|
|
71
|
+
:filter-fields="filterFields"
|
|
72
|
+
:ignore-filter="ignoreFilter"
|
|
64
73
|
>
|
|
65
74
|
<template v-for="(_, name) in getProxySlots()" #[name]="slotData">
|
|
66
75
|
<slot :name="name" v-bind="slotData" />
|
|
@@ -2,7 +2,7 @@ import type { DropdownMenuRootProps, DropdownMenuRootEmits, DropdownMenuContentP
|
|
|
2
2
|
import type { VNode } from 'vue';
|
|
3
3
|
import type { AppConfig } from '@nuxt/schema';
|
|
4
4
|
import theme from '#build/ui/dropdown-menu';
|
|
5
|
-
import type { AvatarProps, IconProps, KbdProps, LinkProps } from '../types';
|
|
5
|
+
import type { AvatarProps, IconProps, InputProps, KbdProps, LinkProps } from '../types';
|
|
6
6
|
import type { ArrayOrNested, DynamicSlots, GetItemKeys, MergeTypes, NestedItem, EmitsToProps } from '../types/utils';
|
|
7
7
|
import type { ComponentConfig } from '../types/tv';
|
|
8
8
|
type DropdownMenu = ComponentConfig<typeof theme, AppConfig, 'dropdownMenu'>;
|
|
@@ -30,6 +30,9 @@ export interface DropdownMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'cust
|
|
|
30
30
|
checked?: boolean;
|
|
31
31
|
open?: boolean;
|
|
32
32
|
defaultOpen?: boolean;
|
|
33
|
+
filter?: boolean | Omit<InputProps, 'modelValue' | 'defaultValue'>;
|
|
34
|
+
filterFields?: string[];
|
|
35
|
+
ignoreFilter?: boolean;
|
|
33
36
|
children?: ArrayOrNested<DropdownMenuItem>;
|
|
34
37
|
onSelect?: (e: Event) => void;
|
|
35
38
|
onUpdateChecked?: (checked: boolean) => void;
|
|
@@ -88,6 +91,23 @@ export interface DropdownMenuProps<T extends ArrayOrNested<DropdownMenuItem> = A
|
|
|
88
91
|
* @defaultValue 'description'
|
|
89
92
|
*/
|
|
90
93
|
descriptionKey?: GetItemKeys<T>;
|
|
94
|
+
/**
|
|
95
|
+
* Whether to display a filter input or not.
|
|
96
|
+
* Can be an object to pass additional props to the input.
|
|
97
|
+
* `{ placeholder: 'Search...', variant: 'none' }`{lang="ts-type"}
|
|
98
|
+
* @defaultValue false
|
|
99
|
+
*/
|
|
100
|
+
filter?: boolean | Omit<InputProps, 'modelValue' | 'defaultValue'>;
|
|
101
|
+
/**
|
|
102
|
+
* The fields to filter by.
|
|
103
|
+
* @defaultValue [labelKey]
|
|
104
|
+
*/
|
|
105
|
+
filterFields?: string[];
|
|
106
|
+
/**
|
|
107
|
+
* When `true`, items will not be filtered which is useful for custom filtering.
|
|
108
|
+
* @defaultValue false
|
|
109
|
+
*/
|
|
110
|
+
ignoreFilter?: boolean;
|
|
91
111
|
disabled?: boolean;
|
|
92
112
|
class?: any;
|
|
93
113
|
ui?: DropdownMenu['slots'];
|
|
@@ -117,6 +137,9 @@ export type DropdownMenuSlots<A extends ArrayOrNested<DropdownMenuItem> = ArrayO
|
|
|
117
137
|
index: number;
|
|
118
138
|
}) => VNode[];
|
|
119
139
|
'item-trailing'?: SlotProps<T>;
|
|
140
|
+
'empty'?(props: {
|
|
141
|
+
searchTerm: string;
|
|
142
|
+
}): VNode[];
|
|
120
143
|
'content-top'?: (props: {
|
|
121
144
|
sub: boolean;
|
|
122
145
|
}) => VNode[];
|
|
@@ -134,15 +157,18 @@ export type DropdownMenuSlots<A extends ArrayOrNested<DropdownMenuItem> = ArrayO
|
|
|
134
157
|
declare const _default: typeof __VLS_export;
|
|
135
158
|
export default _default;
|
|
136
159
|
declare const __VLS_export: <T extends ArrayOrNested<DropdownMenuItem>>(__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<{
|
|
137
|
-
props: import("vue").PublicProps & __VLS_PrettifyLocal<DropdownMenuProps<T> & {
|
|
160
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<(DropdownMenuProps<T> & {
|
|
161
|
+
searchTerm?: string;
|
|
162
|
+
}) & {
|
|
138
163
|
"onUpdate:open"?: ((payload: boolean) => any) | undefined;
|
|
164
|
+
"onUpdate:searchTerm"?: ((value: string) => any) | undefined;
|
|
139
165
|
}> & (typeof globalThis extends {
|
|
140
166
|
__VLS_PROPS_FALLBACK: infer P;
|
|
141
167
|
} ? P : {});
|
|
142
168
|
expose: (exposed: {}) => void;
|
|
143
169
|
attrs: any;
|
|
144
170
|
slots: DropdownMenuSlots<T, NestedItem<T>>;
|
|
145
|
-
emit: (evt: "update:open", payload: boolean) => void;
|
|
171
|
+
emit: ((evt: "update:open", payload: boolean) => void) & ((event: "update:searchTerm", value: string) => void);
|
|
146
172
|
}>) => import("vue").VNode & {
|
|
147
173
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
148
174
|
};
|
|
@@ -3,7 +3,7 @@ import type { DropdownMenuContentProps as RekaDropdownMenuContentProps } from 'r
|
|
|
3
3
|
import type { VNode } from 'vue';
|
|
4
4
|
import type { AppConfig } from '@nuxt/schema';
|
|
5
5
|
import type theme from '#build/ui/dropdown-menu';
|
|
6
|
-
import type { DropdownMenuItem, DropdownMenuSlots, IconProps } from '../types';
|
|
6
|
+
import type { DropdownMenuItem, DropdownMenuSlots, IconProps, InputProps } from '../types';
|
|
7
7
|
import type { ArrayOrNested, GetItemKeys, NestedItem, DynamicSlots, MergeTypes } from '../types/utils';
|
|
8
8
|
import type { ComponentConfig } from '../types/tv';
|
|
9
9
|
type DropdownMenu = ComponentConfig<typeof theme, AppConfig, 'dropdownMenu'>;
|
|
@@ -25,11 +25,16 @@ interface DropdownMenuContentProps<T extends ArrayOrNested<DropdownMenuItem>> ex
|
|
|
25
25
|
* @IconifyIcon
|
|
26
26
|
*/
|
|
27
27
|
externalIcon?: boolean | IconProps['name'];
|
|
28
|
+
size?: DropdownMenu['variants']['size'];
|
|
29
|
+
filter?: boolean | Omit<InputProps, 'modelValue' | 'defaultValue'>;
|
|
30
|
+
filterFields?: string[];
|
|
31
|
+
ignoreFilter?: boolean;
|
|
32
|
+
searchTerm?: string;
|
|
28
33
|
class?: any;
|
|
29
34
|
ui: DropdownMenu['ui'];
|
|
30
35
|
uiOverride?: DropdownMenu['slots'];
|
|
31
36
|
}
|
|
32
|
-
type DropdownMenuContentSlots<A extends ArrayOrNested<DropdownMenuItem> = ArrayOrNested<DropdownMenuItem>, T extends NestedItem<A> = NestedItem<A>> = Pick<DropdownMenuSlots<A>, 'item' | 'item-leading' | 'item-label' | 'item-description' | 'item-trailing' | 'content-top' | 'content-bottom'> & {
|
|
37
|
+
type DropdownMenuContentSlots<A extends ArrayOrNested<DropdownMenuItem> = ArrayOrNested<DropdownMenuItem>, T extends NestedItem<A> = NestedItem<A>> = Pick<DropdownMenuSlots<A>, 'item' | 'item-leading' | 'item-label' | 'item-description' | 'item-trailing' | 'empty' | 'content-top' | 'content-bottom'> & {
|
|
33
38
|
default?(props?: {}): VNode[];
|
|
34
39
|
} & DynamicSlots<MergeTypes<T>, 'label' | 'description', {
|
|
35
40
|
active: boolean;
|
|
@@ -44,6 +49,7 @@ export default _default;
|
|
|
44
49
|
declare const __VLS_export: <T extends ArrayOrNested<DropdownMenuItem>>(__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<{
|
|
45
50
|
props: import("vue").PublicProps & __VLS_PrettifyLocal<DropdownMenuContentProps<T> & {
|
|
46
51
|
onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
|
|
52
|
+
"onUpdate:searchTerm"?: ((value: string) => any) | undefined;
|
|
47
53
|
onPointerDownOutside?: ((event: import("reka-ui").PointerDownOutsideEvent) => any) | undefined;
|
|
48
54
|
onFocusOutside?: ((event: import("reka-ui").FocusOutsideEvent) => any) | undefined;
|
|
49
55
|
onInteractOutside?: ((event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any) | undefined;
|
|
@@ -54,7 +60,7 @@ declare const __VLS_export: <T extends ArrayOrNested<DropdownMenuItem>>(__VLS_pr
|
|
|
54
60
|
expose: (exposed: {}) => void;
|
|
55
61
|
attrs: any;
|
|
56
62
|
slots: DropdownMenuContentSlots<T, NestedItem<T>>;
|
|
57
|
-
emit: ((evt: "escapeKeyDown", event: KeyboardEvent) => void) & ((evt: "pointerDownOutside", event: import("reka-ui").PointerDownOutsideEvent) => void) & ((evt: "focusOutside", event: import("reka-ui").FocusOutsideEvent) => void) & ((evt: "interactOutside", event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => void) & ((evt: "closeAutoFocus", event: Event) => void);
|
|
63
|
+
emit: ((evt: "escapeKeyDown", event: KeyboardEvent) => void) & ((evt: "update:searchTerm", value: string) => void) & ((evt: "pointerDownOutside", event: import("reka-ui").PointerDownOutsideEvent) => void) & ((evt: "focusOutside", event: import("reka-ui").FocusOutsideEvent) => void) & ((evt: "interactOutside", event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => void) & ((evt: "closeAutoFocus", event: Event) => void);
|
|
58
64
|
}>) => import("vue").VNode & {
|
|
59
65
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
60
66
|
};
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<script setup>
|
|
6
|
-
import { computed, toRef } from "vue";
|
|
6
|
+
import { computed, ref, toRef } from "vue";
|
|
7
|
+
import { defu } from "defu";
|
|
7
8
|
import { DropdownMenu } from "reka-ui/namespaced";
|
|
8
9
|
import { useForwardPropsEmits } from "reka-ui";
|
|
9
10
|
import { reactiveOmit, createReusableTemplate } from "@vueuse/core";
|
|
10
11
|
import { useAppConfig } from "#imports";
|
|
12
|
+
import { useFilter } from "../composables/useFilter";
|
|
11
13
|
import { useLocale } from "../composables/useLocale";
|
|
12
14
|
import { usePortal } from "../composables/usePortal";
|
|
13
15
|
import { omit, get, isArrayOfArray } from "../utils";
|
|
@@ -16,6 +18,7 @@ import ULinkBase from "./LinkBase.vue";
|
|
|
16
18
|
import ULink from "./Link.vue";
|
|
17
19
|
import UAvatar from "./Avatar.vue";
|
|
18
20
|
import UIcon from "./Icon.vue";
|
|
21
|
+
import UInput from "./Input.vue";
|
|
19
22
|
import UKbd from "./Kbd.vue";
|
|
20
23
|
import UDropdownMenuContent from "./DropdownMenuContent.vue";
|
|
21
24
|
const props = defineProps({
|
|
@@ -27,6 +30,11 @@ const props = defineProps({
|
|
|
27
30
|
checkedIcon: { type: null, required: false },
|
|
28
31
|
loadingIcon: { type: null, required: false },
|
|
29
32
|
externalIcon: { type: [Boolean, String], required: false, skipCheck: true },
|
|
33
|
+
size: { type: null, required: false },
|
|
34
|
+
filter: { type: [Boolean, Object], required: false },
|
|
35
|
+
filterFields: { type: Array, required: false },
|
|
36
|
+
ignoreFilter: { type: Boolean, required: false },
|
|
37
|
+
searchTerm: { type: String, required: false },
|
|
30
38
|
class: { type: null, required: false },
|
|
31
39
|
ui: { type: null, required: true },
|
|
32
40
|
uiOverride: { type: null, required: false },
|
|
@@ -50,18 +58,41 @@ const props = defineProps({
|
|
|
50
58
|
prioritizePosition: { type: Boolean, required: false },
|
|
51
59
|
reference: { type: null, required: false }
|
|
52
60
|
});
|
|
53
|
-
const emits = defineEmits(["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "closeAutoFocus"]);
|
|
61
|
+
const emits = defineEmits(["update:searchTerm", "escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "closeAutoFocus"]);
|
|
54
62
|
const slots = defineSlots();
|
|
55
|
-
const { dir } = useLocale();
|
|
63
|
+
const { t, dir } = useLocale();
|
|
56
64
|
const appConfig = useAppConfig();
|
|
65
|
+
const { filterGroups } = useFilter();
|
|
66
|
+
const _searchTerm = ref("");
|
|
67
|
+
const searchTerm = computed({
|
|
68
|
+
get: () => props.searchTerm ?? _searchTerm.value,
|
|
69
|
+
set: (value) => {
|
|
70
|
+
_searchTerm.value = value;
|
|
71
|
+
emits("update:searchTerm", value);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
const inputProps = toRef(() => defu(props.filter, { placeholder: t("dropdownMenu.search"), variant: "none" }));
|
|
57
75
|
const portalProps = usePortal(toRef(() => props.portal));
|
|
58
|
-
const contentProps = useForwardPropsEmits(reactiveOmit(props, "sub", "items", "portal", "labelKey", "descriptionKey", "checkedIcon", "loadingIcon", "externalIcon", "class", "ui", "uiOverride"), emits);
|
|
76
|
+
const contentProps = useForwardPropsEmits(reactiveOmit(props, "sub", "items", "portal", "labelKey", "descriptionKey", "checkedIcon", "loadingIcon", "externalIcon", "size", "filter", "filterFields", "ignoreFilter", "searchTerm", "class", "ui", "uiOverride"), emits);
|
|
59
77
|
const getProxySlots = () => omit(slots, ["default"]);
|
|
60
78
|
const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate();
|
|
61
79
|
const childrenIcon = computed(() => dir.value === "rtl" ? appConfig.ui.icons.chevronLeft : appConfig.ui.icons.chevronRight);
|
|
62
|
-
const groups = computed(
|
|
63
|
-
(
|
|
64
|
-
);
|
|
80
|
+
const groups = computed(() => {
|
|
81
|
+
if (!props.items?.length) return [];
|
|
82
|
+
return isArrayOfArray(props.items) ? props.items : [props.items];
|
|
83
|
+
});
|
|
84
|
+
const isStructuralItem = (item) => !!item.type && ["label", "separator"].includes(item.type);
|
|
85
|
+
const filteredGroups = computed(() => {
|
|
86
|
+
if (!props.filter || props.ignoreFilter || !searchTerm.value) {
|
|
87
|
+
return groups.value;
|
|
88
|
+
}
|
|
89
|
+
const fields = Array.isArray(props.filterFields) && props.filterFields.length ? props.filterFields : [props.labelKey];
|
|
90
|
+
return filterGroups(groups.value, searchTerm.value, {
|
|
91
|
+
fields,
|
|
92
|
+
isStructural: isStructuralItem
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
const hasFilteredItems = computed(() => filteredGroups.value.some((group) => group.some((item) => !isStructuralItem(item))));
|
|
65
96
|
</script>
|
|
66
97
|
|
|
67
98
|
<template>
|
|
@@ -106,10 +137,22 @@ const groups = computed(
|
|
|
106
137
|
|
|
107
138
|
<DropdownMenu.Portal v-bind="portalProps">
|
|
108
139
|
<component :is="sub ? DropdownMenu.SubContent : DropdownMenu.Content" data-slot="content" :class="ui.content({ class: [uiOverride?.content, props.class] })" v-bind="contentProps">
|
|
140
|
+
<DropdownMenu.Filter v-if="!!filter" v-model="searchTerm" as-child>
|
|
141
|
+
<UInput
|
|
142
|
+
autofocus
|
|
143
|
+
autocomplete="off"
|
|
144
|
+
:size="size"
|
|
145
|
+
v-bind="inputProps"
|
|
146
|
+
data-slot="input"
|
|
147
|
+
:class="ui.input({ class: uiOverride?.input })"
|
|
148
|
+
@change.stop
|
|
149
|
+
/>
|
|
150
|
+
</DropdownMenu.Filter>
|
|
151
|
+
|
|
109
152
|
<slot name="content-top" :sub="sub ?? false" />
|
|
110
153
|
|
|
111
|
-
<div role="presentation" data-slot="viewport" :class="ui.viewport({ class: uiOverride?.viewport })">
|
|
112
|
-
<DropdownMenu.Group v-for="(group, groupIndex) in
|
|
154
|
+
<div v-if="!searchTerm || hasFilteredItems" role="presentation" data-slot="viewport" :class="ui.viewport({ class: uiOverride?.viewport })">
|
|
155
|
+
<DropdownMenu.Group v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" data-slot="group" :class="ui.group({ class: uiOverride?.group })">
|
|
113
156
|
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
|
114
157
|
<DropdownMenu.Label v-if="item.type === 'label'" data-slot="label" :class="ui.label({ class: [uiOverride?.label, item.ui?.label, item.class] })">
|
|
115
158
|
<ReuseItemTemplate :item="item" :index="index" />
|
|
@@ -142,6 +185,10 @@ const groups = computed(
|
|
|
142
185
|
:checked-icon="checkedIcon"
|
|
143
186
|
:loading-icon="loadingIcon"
|
|
144
187
|
:external-icon="externalIcon"
|
|
188
|
+
:size="size"
|
|
189
|
+
:filter="item.filter"
|
|
190
|
+
:filter-fields="item.filterFields || filterFields"
|
|
191
|
+
:ignore-filter="item.ignoreFilter ?? ignoreFilter"
|
|
145
192
|
v-bind="item.content"
|
|
146
193
|
>
|
|
147
194
|
<template v-for="(_, name) in getProxySlots()" #[name]="slotData">
|
|
@@ -177,6 +224,12 @@ const groups = computed(
|
|
|
177
224
|
</DropdownMenu.Group>
|
|
178
225
|
</div>
|
|
179
226
|
|
|
227
|
+
<div v-if="searchTerm && !hasFilteredItems" data-slot="empty" :class="ui.empty({ class: uiOverride?.empty })">
|
|
228
|
+
<slot name="empty" :search-term="searchTerm">
|
|
229
|
+
{{ t("dropdownMenu.noMatch", { searchTerm }) }}
|
|
230
|
+
</slot>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
180
233
|
<slot />
|
|
181
234
|
|
|
182
235
|
<slot name="content-bottom" :sub="sub ?? false" />
|