@byyuurin/ui 0.1.0 → 0.2.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.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/components/Accordion.vue +2 -2
- package/dist/runtime/components/Badge.vue +3 -3
- package/dist/runtime/components/Breadcrumb.vue +4 -4
- package/dist/runtime/components/Button.vue +3 -3
- package/dist/runtime/components/Calendar.vue +6 -8
- package/dist/runtime/components/Carousel.vue +19 -0
- package/dist/runtime/components/Checkbox.vue +1 -1
- package/dist/runtime/components/CheckboxGroup.vue +131 -0
- package/dist/runtime/components/CheckboxGroup.vue.d.ts +89 -0
- package/dist/runtime/components/DropdownMenuContent.vue +11 -11
- package/dist/runtime/components/FormField.vue +1 -1
- package/dist/runtime/components/Input.vue +3 -3
- package/dist/runtime/components/InputNumber.vue +2 -4
- package/dist/runtime/components/InputNumber.vue.d.ts +0 -5
- package/dist/runtime/components/InputTags.vue +155 -0
- package/dist/runtime/components/InputTags.vue.d.ts +85 -0
- package/dist/runtime/components/Marquee.vue +38 -0
- package/dist/runtime/components/Marquee.vue.d.ts +54 -0
- package/dist/runtime/components/NavigationMenu.vue +46 -37
- package/dist/runtime/components/NavigationMenu.vue.d.ts +44 -9
- package/dist/runtime/components/RadioGroup.vue.d.ts +2 -2
- package/dist/runtime/components/Select.vue +11 -11
- package/dist/runtime/components/Slider.vue +1 -1
- package/dist/runtime/components/Table.vue +54 -32
- package/dist/runtime/components/Table.vue.d.ts +14 -14
- package/dist/runtime/components/Tabs.vue +3 -3
- package/dist/runtime/components/Textarea.vue +3 -3
- package/dist/runtime/components/Timeline.vue +102 -0
- package/dist/runtime/components/Timeline.vue.d.ts +74 -0
- package/dist/runtime/types/index.d.ts +5 -0
- package/dist/runtime/types/index.js +5 -0
- package/dist/runtime/types/utils.d.ts +6 -3
- package/dist/shared/{ui.DSyJHSTk.mjs → ui.DLOxhmP0.mjs} +523 -68
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import theme from "#build/ui/input-tags";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
import { reactivePick } from "@vueuse/core";
|
|
7
|
+
import { TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot, useForwardPropsEmits } from "reka-ui";
|
|
8
|
+
import { computed, onMounted, shallowRef, toRaw, toRef } from "vue";
|
|
9
|
+
import { useAppConfig } from "#imports";
|
|
10
|
+
import { useComponentIcons } from "../composables/useComponentIcons";
|
|
11
|
+
import { useFieldGroup } from "../composables/useFieldGroup";
|
|
12
|
+
import { useFormField } from "../composables/useFormField";
|
|
13
|
+
import { cv, merge } from "../utils/style";
|
|
14
|
+
import Avatar from "./Avatar.vue";
|
|
15
|
+
import Icon from "./Icon.vue";
|
|
16
|
+
defineOptions({ inheritAttrs: false });
|
|
17
|
+
const props = defineProps({
|
|
18
|
+
as: { type: null, required: false },
|
|
19
|
+
placeholder: { type: String, required: false },
|
|
20
|
+
maxLength: { type: Number, required: false },
|
|
21
|
+
color: { type: null, required: false },
|
|
22
|
+
variant: { type: null, required: false },
|
|
23
|
+
size: { type: null, required: false },
|
|
24
|
+
autofocus: { type: Boolean, required: false },
|
|
25
|
+
autofocusDelay: { type: Number, required: false, default: 0 },
|
|
26
|
+
deleteIcon: { type: [String, Object], required: false },
|
|
27
|
+
highlight: { type: Boolean, required: false },
|
|
28
|
+
ui: { type: null, required: false },
|
|
29
|
+
class: { type: [Object, String, Number, Boolean, null, Array], required: false, skipCheck: true },
|
|
30
|
+
modelValue: { type: [Array, null], required: false },
|
|
31
|
+
defaultValue: { type: Array, required: false },
|
|
32
|
+
addOnPaste: { type: Boolean, required: false },
|
|
33
|
+
addOnTab: { type: Boolean, required: false },
|
|
34
|
+
addOnBlur: { type: Boolean, required: false },
|
|
35
|
+
duplicate: { type: Boolean, required: false },
|
|
36
|
+
disabled: { type: Boolean, required: false },
|
|
37
|
+
delimiter: { type: null, required: false },
|
|
38
|
+
max: { type: Number, required: false },
|
|
39
|
+
id: { type: String, required: false },
|
|
40
|
+
convertValue: { type: Function, required: false },
|
|
41
|
+
displayValue: { type: Function, required: false },
|
|
42
|
+
name: { type: String, required: false },
|
|
43
|
+
required: { type: Boolean, required: false },
|
|
44
|
+
icon: { type: [String, Object], required: false },
|
|
45
|
+
avatar: { type: Object, required: false },
|
|
46
|
+
leading: { type: Boolean, required: false },
|
|
47
|
+
leadingIcon: { type: [String, Object], required: false },
|
|
48
|
+
trailing: { type: Boolean, required: false },
|
|
49
|
+
trailingIcon: { type: [String, Object], required: false },
|
|
50
|
+
loading: { type: Boolean, required: false },
|
|
51
|
+
loadingIcon: { type: [String, Object], required: false }
|
|
52
|
+
});
|
|
53
|
+
const emit = defineEmits(["change", "blur", "focus", "update:modelValue", "invalid", "addTag", "removeTag"]);
|
|
54
|
+
const slots = defineSlots();
|
|
55
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, "as", "addOnPaste", "addOnTab", "addOnBlur", "duplicate", "delimiter", "max", "convertValue", "displayValue", "required"), emit);
|
|
56
|
+
const { id, name, size: formFieldSize, color, highlight, disabled, ariaAttrs, emitFormBlur, emitFormInput, emitFormChange, emitFormFocus } = useFormField(props);
|
|
57
|
+
const { orientation, size: fieldGroupSize } = useFieldGroup(props);
|
|
58
|
+
const { isLeading, leadingIconName, isTrailing, trailingIconName } = useComponentIcons(props);
|
|
59
|
+
const appConfig = useAppConfig();
|
|
60
|
+
const ui = computed(() => {
|
|
61
|
+
const styler = cv(merge(theme, appConfig.ui.inputTags));
|
|
62
|
+
return styler({
|
|
63
|
+
...props,
|
|
64
|
+
color: color.value,
|
|
65
|
+
size: fieldGroupSize.value || formFieldSize.value,
|
|
66
|
+
highlight: highlight.value,
|
|
67
|
+
leading: isLeading.value || !!props.avatar || !!slots.leading,
|
|
68
|
+
trailing: isTrailing.value || !!slots.trailing,
|
|
69
|
+
fieldGroup: orientation.value
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
const inputRef = shallowRef(null);
|
|
73
|
+
function onUpdate(value) {
|
|
74
|
+
if (toRaw(props.modelValue) === value)
|
|
75
|
+
return;
|
|
76
|
+
const event = new Event("change", { target: { value } });
|
|
77
|
+
emit("change", event);
|
|
78
|
+
emitFormChange();
|
|
79
|
+
emitFormInput();
|
|
80
|
+
}
|
|
81
|
+
function onBlur(event) {
|
|
82
|
+
emit("blur", event);
|
|
83
|
+
emitFormBlur();
|
|
84
|
+
}
|
|
85
|
+
function onFocus(event) {
|
|
86
|
+
emit("focus", event);
|
|
87
|
+
emitFormFocus();
|
|
88
|
+
}
|
|
89
|
+
function autoFocus() {
|
|
90
|
+
if (props.autofocus)
|
|
91
|
+
inputRef.value?.$el?.focus();
|
|
92
|
+
}
|
|
93
|
+
onMounted(() => {
|
|
94
|
+
setTimeout(() => autoFocus(), props.autofocusDelay);
|
|
95
|
+
});
|
|
96
|
+
defineExpose({
|
|
97
|
+
inputRef: toRef(() => inputRef.value?.$el)
|
|
98
|
+
});
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<template>
|
|
102
|
+
<TagsInputRoot
|
|
103
|
+
v-slot="{ modelValue: tags }"
|
|
104
|
+
:model-value="props.modelValue"
|
|
105
|
+
:default-value="props.defaultValue"
|
|
106
|
+
:class="ui.root({ class: [ui.base({ class: props.ui?.base }), props.ui?.root, props.class] })"
|
|
107
|
+
v-bind="{ ...rootProps, id, name, disabled }"
|
|
108
|
+
data-part="root"
|
|
109
|
+
@update:model-value="onUpdate"
|
|
110
|
+
>
|
|
111
|
+
<TagsInputItem
|
|
112
|
+
v-for="(item, index) in tags"
|
|
113
|
+
:key="index"
|
|
114
|
+
:value="item"
|
|
115
|
+
:class="ui.item({ class: props.ui?.item })"
|
|
116
|
+
data-part="item"
|
|
117
|
+
>
|
|
118
|
+
<TagsInputItemText :class="ui.itemText({ class: props.ui?.itemText })" data-part="itemText">
|
|
119
|
+
<slot name="item-text" :item="item" :index="index" :ui="ui"></slot>
|
|
120
|
+
</TagsInputItemText>
|
|
121
|
+
|
|
122
|
+
<TagsInputItemDelete :disabled="disabled" :class="ui.itemDelete({ class: props.ui?.itemDelete })" data-part="itemDelete">
|
|
123
|
+
<slot name="item-delete" :item="item" :index="index" :ui="ui">
|
|
124
|
+
<Icon :name="props.deleteIcon || appConfig.ui.icons.close" :class="ui.itemDeleteIcon({ class: props.ui?.itemDeleteIcon })" data-part="itemDeleteIcon" />
|
|
125
|
+
</slot>
|
|
126
|
+
</TagsInputItemDelete>
|
|
127
|
+
</TagsInputItem>
|
|
128
|
+
|
|
129
|
+
<TagsInputInput
|
|
130
|
+
ref="inputRef"
|
|
131
|
+
v-bind="{ ...$attrs, ...ariaAttrs }"
|
|
132
|
+
:placeholder="props.placeholder"
|
|
133
|
+
:max-length="props.maxLength"
|
|
134
|
+
:class="ui.input({ class: props.ui?.input })"
|
|
135
|
+
data-part="input"
|
|
136
|
+
@blur="onBlur"
|
|
137
|
+
@focus="onFocus"
|
|
138
|
+
/>
|
|
139
|
+
|
|
140
|
+
<span v-if="isLeading || props.avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })" data-part="leading">
|
|
141
|
+
<slot name="leading" :ui="ui">
|
|
142
|
+
<Icon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" data-part="leadingIcon" />
|
|
143
|
+
<Avatar v-else-if="props.avatar" :size="props.ui?.leadingAvatarSize || ui.leadingAvatarSize()" v-bind="props.avatar" :class="ui.leadingAvatar({ class: props.ui?.leadingAvatar })" data-part="leadingAvatar" />
|
|
144
|
+
</slot>
|
|
145
|
+
</span>
|
|
146
|
+
|
|
147
|
+
<slot :ui="ui"></slot>
|
|
148
|
+
|
|
149
|
+
<span v-if="isTrailing || !!slots.trailing" :class="ui.trailing({ class: props.ui?.trailing })" data-part="trailing">
|
|
150
|
+
<slot name="trailing" :ui="ui">
|
|
151
|
+
<Icon v-if="trailingIconName" :name="trailingIconName" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" data-part="trailingIcon" />
|
|
152
|
+
</slot>
|
|
153
|
+
</span>
|
|
154
|
+
</TagsInputRoot>
|
|
155
|
+
</template>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { VariantProps } from '@byyuurin/ui-kit';
|
|
2
|
+
import type { AcceptableInputValue, TagsInputRootEmits, TagsInputRootProps } from 'reka-ui';
|
|
3
|
+
import theme from '#build/ui/input-tags';
|
|
4
|
+
import type { UseComponentIconsProps } from '../composables/useComponentIcons';
|
|
5
|
+
import type { ComponentBaseProps, ComponentStyler, ComponentUIProps, IconProps } from '../types';
|
|
6
|
+
import type { StaticSlot } from '../types/utils';
|
|
7
|
+
type ThemeVariants = VariantProps<typeof theme>;
|
|
8
|
+
export type InputTagsItem = AcceptableInputValue;
|
|
9
|
+
export interface InputTagsProps<T extends InputTagsItem = InputTagsItem> extends ComponentBaseProps, Pick<TagsInputRootProps<T>, 'modelValue' | 'defaultValue' | 'addOnPaste' | 'addOnTab' | 'addOnBlur' | 'duplicate' | 'disabled' | 'delimiter' | 'max' | 'id' | 'convertValue' | 'displayValue' | 'name' | 'required'>, UseComponentIconsProps {
|
|
10
|
+
/**
|
|
11
|
+
* The element or component this component should render as.
|
|
12
|
+
* @default "div"
|
|
13
|
+
*/
|
|
14
|
+
as?: TagsInputRootProps<T>['as'];
|
|
15
|
+
/** The placeholder text when the input is empty. */
|
|
16
|
+
placeholder?: string;
|
|
17
|
+
/** The maximum number of character allowed. */
|
|
18
|
+
maxLength?: number;
|
|
19
|
+
/** @default "primary" */
|
|
20
|
+
color?: ThemeVariants['color'];
|
|
21
|
+
/** @default "outline" */
|
|
22
|
+
variant?: ThemeVariants['variant'];
|
|
23
|
+
/** @default "md" */
|
|
24
|
+
size?: ThemeVariants['size'];
|
|
25
|
+
autofocus?: boolean;
|
|
26
|
+
autofocusDelay?: number;
|
|
27
|
+
/**
|
|
28
|
+
* The icon displayed to delete a tag.
|
|
29
|
+
* @default appConfig.ui.icons.close
|
|
30
|
+
*/
|
|
31
|
+
deleteIcon?: IconProps['name'];
|
|
32
|
+
/** Highlight the ring color like a focus state. */
|
|
33
|
+
highlight?: boolean;
|
|
34
|
+
ui?: ComponentUIProps<typeof theme>;
|
|
35
|
+
}
|
|
36
|
+
export interface InputTagsEmits<T extends InputTagsItem> extends TagsInputRootEmits<T> {
|
|
37
|
+
change: [event: Event];
|
|
38
|
+
blur: [event: FocusEvent];
|
|
39
|
+
focus: [event: FocusEvent];
|
|
40
|
+
}
|
|
41
|
+
export interface InputTagsSlots<T extends InputTagsItem = InputTagsItem> {
|
|
42
|
+
'leading': StaticSlot<{
|
|
43
|
+
ui: ComponentStyler<typeof theme>;
|
|
44
|
+
}>;
|
|
45
|
+
'default': StaticSlot<{
|
|
46
|
+
ui: ComponentStyler<typeof theme>;
|
|
47
|
+
}>;
|
|
48
|
+
'trailing': StaticSlot<{
|
|
49
|
+
ui: ComponentStyler<typeof theme>;
|
|
50
|
+
}>;
|
|
51
|
+
'item-text': StaticSlot<{
|
|
52
|
+
item: T;
|
|
53
|
+
index: number;
|
|
54
|
+
ui: ComponentStyler<typeof theme>;
|
|
55
|
+
}>;
|
|
56
|
+
'item-delete': StaticSlot<{
|
|
57
|
+
item: T;
|
|
58
|
+
index: number;
|
|
59
|
+
ui: ComponentStyler<typeof theme>;
|
|
60
|
+
}>;
|
|
61
|
+
}
|
|
62
|
+
declare const __VLS_export: <T extends InputTagsItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
63
|
+
props: __VLS_PrettifyLocal<InputTagsProps<AcceptableInputValue> & {
|
|
64
|
+
onChange?: ((event: Event) => any) | undefined;
|
|
65
|
+
onBlur?: ((event: FocusEvent) => any) | undefined;
|
|
66
|
+
onFocus?: ((event: FocusEvent) => any) | undefined;
|
|
67
|
+
onInvalid?: ((payload: T) => any) | undefined;
|
|
68
|
+
"onUpdate:modelValue"?: ((payload: T[]) => any) | undefined;
|
|
69
|
+
onAddTag?: ((payload: T) => any) | undefined;
|
|
70
|
+
onRemoveTag?: ((payload: T) => any) | undefined;
|
|
71
|
+
}> & import("vue").PublicProps;
|
|
72
|
+
expose: (exposed: import("vue").ShallowUnwrapRef<{
|
|
73
|
+
inputRef: Readonly<import("vue").Ref<HTMLInputElement, HTMLInputElement>>;
|
|
74
|
+
}>) => void;
|
|
75
|
+
attrs: any;
|
|
76
|
+
slots: InputTagsSlots<T>;
|
|
77
|
+
emit: ((evt: "change", event: Event) => void) & ((evt: "blur", event: FocusEvent) => void) & ((evt: "focus", event: FocusEvent) => void) & ((evt: "invalid", payload: T) => void) & ((evt: "update:modelValue", payload: T[]) => void) & ((evt: "addTag", payload: T) => void) & ((evt: "removeTag", payload: T) => void);
|
|
78
|
+
}>) => import("vue").VNode & {
|
|
79
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
80
|
+
};
|
|
81
|
+
declare const _default: typeof __VLS_export;
|
|
82
|
+
export default _default;
|
|
83
|
+
type __VLS_PrettifyLocal<T> = {
|
|
84
|
+
[K in keyof T as K]: T[K];
|
|
85
|
+
} & {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import theme from "#build/ui/marquee";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
import { Primitive } from "reka-ui";
|
|
7
|
+
import { computed } from "vue";
|
|
8
|
+
import { useAppConfig } from "#imports";
|
|
9
|
+
import { cv, merge } from "../utils/style";
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
as: { type: null, required: false },
|
|
12
|
+
pauseOnHover: { type: Boolean, required: false },
|
|
13
|
+
reverse: { type: Boolean, required: false },
|
|
14
|
+
orientation: { type: null, required: false, default: "horizontal" },
|
|
15
|
+
repeat: { type: Number, required: false, default: 4 },
|
|
16
|
+
overlay: { type: Boolean, required: false, default: true },
|
|
17
|
+
ui: { type: null, required: false },
|
|
18
|
+
class: { type: [Object, String, Number, Boolean, null, Array], required: false, skipCheck: true }
|
|
19
|
+
});
|
|
20
|
+
defineSlots();
|
|
21
|
+
const appConfig = useAppConfig();
|
|
22
|
+
const ui = computed(() => {
|
|
23
|
+
const styler = cv(merge(theme, appConfig.ui.marquee));
|
|
24
|
+
return styler(props);
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<Primitive :as="props.as" :data-orientation="props.orientation" :class="ui.root({ class: [props.ui?.root, props.class] })" data-part="root">
|
|
30
|
+
<div v-for="i in props.repeat" :key="i" :class="ui.content({ class: props.ui?.content })" data-part="content">
|
|
31
|
+
<slot></slot>
|
|
32
|
+
</div>
|
|
33
|
+
</Primitive>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<style>
|
|
37
|
+
@keyframes marquee{0%{transform:translateZ(0)}to{transform:translate3d(calc(-100% - var(--gap)),0,0)}}@keyframes marquee-rtl{0%{transform:translateZ(0)}to{transform:translate3d(calc(100% + var(--gap)),0,0)}}@keyframes marquee-vertical{0%{transform:translateZ(0)}to{transform:translate3d(0,calc(-100% - var(--gap)),0)}}@keyframes marquee-vertical-rtl{0%{transform:translate3d(0,calc(-100% - var(--gap)),0)}to{transform:translate3d(0,calc(-100%*var(--gap)),0)}}
|
|
38
|
+
</style>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { VariantProps } from '@byyuurin/ui-kit';
|
|
2
|
+
import type { PrimitiveProps } from 'reka-ui';
|
|
3
|
+
import theme from '#build/ui/marquee';
|
|
4
|
+
import type { ComponentBaseProps, ComponentStyler } from '../types';
|
|
5
|
+
import type { StaticSlot } from '../types/utils';
|
|
6
|
+
type ThemeVariants = VariantProps<typeof theme>;
|
|
7
|
+
export interface MarqueeProps extends ComponentBaseProps {
|
|
8
|
+
/**
|
|
9
|
+
* The element or component this component should render as.
|
|
10
|
+
* @default "div"
|
|
11
|
+
*/
|
|
12
|
+
as?: PrimitiveProps['as'];
|
|
13
|
+
/**
|
|
14
|
+
* Pause the marquee on hover.
|
|
15
|
+
* @default false
|
|
16
|
+
*/
|
|
17
|
+
pauseOnHover?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Reverse the direction of the marquee.
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
reverse?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The orientation of the marquee.
|
|
25
|
+
* @default "horizontal"
|
|
26
|
+
*/
|
|
27
|
+
orientation?: ThemeVariants['orientation'];
|
|
28
|
+
/**
|
|
29
|
+
* The number of times the marquee should repeat.
|
|
30
|
+
* @default 4
|
|
31
|
+
*/
|
|
32
|
+
repeat?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Display an overlay on the marquee.
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
overlay?: boolean;
|
|
38
|
+
ui?: ComponentStyler<typeof theme>;
|
|
39
|
+
}
|
|
40
|
+
export interface MarqueeSlots {
|
|
41
|
+
default: StaticSlot;
|
|
42
|
+
}
|
|
43
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<MarqueeProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<MarqueeProps> & Readonly<{}>, {
|
|
44
|
+
overlay: boolean;
|
|
45
|
+
repeat: number;
|
|
46
|
+
orientation: "horizontal" | "vertical";
|
|
47
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, MarqueeSlots>;
|
|
48
|
+
declare const _default: typeof __VLS_export;
|
|
49
|
+
export default _default;
|
|
50
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
51
|
+
new (): {
|
|
52
|
+
$slots: S;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
@@ -20,6 +20,9 @@ import Tooltip from "./Tooltip.vue";
|
|
|
20
20
|
defineOptions({ inheritAttrs: false });
|
|
21
21
|
const props = defineProps({
|
|
22
22
|
as: { type: null, required: false },
|
|
23
|
+
type: { type: null, required: false, default: "multiple" },
|
|
24
|
+
modelValue: { type: null, required: false },
|
|
25
|
+
defaultValue: { type: null, required: false },
|
|
23
26
|
trailingIcon: { type: [String, Object], required: false },
|
|
24
27
|
externalIcon: { type: [Boolean, String, Object], required: false, default: true },
|
|
25
28
|
items: { type: null, required: false },
|
|
@@ -37,8 +40,6 @@ const props = defineProps({
|
|
|
37
40
|
labelKey: { type: null, required: false, default: "label" },
|
|
38
41
|
ui: { type: null, required: false },
|
|
39
42
|
class: { type: [Object, String, Number, Boolean, null, Array], required: false, skipCheck: true },
|
|
40
|
-
modelValue: { type: String, required: false },
|
|
41
|
-
defaultValue: { type: String, required: false },
|
|
42
43
|
delayDuration: { type: Number, required: false, default: 0 },
|
|
43
44
|
disableClickTrigger: { type: Boolean, required: false },
|
|
44
45
|
disableHoverTrigger: { type: Boolean, required: false },
|
|
@@ -46,15 +47,12 @@ const props = defineProps({
|
|
|
46
47
|
disablePointerLeaveClose: { type: Boolean, required: false },
|
|
47
48
|
unmountOnHide: { type: Boolean, required: false, default: true },
|
|
48
49
|
disabled: { type: Boolean, required: false },
|
|
49
|
-
type: { type: String, required: false, default: "multiple" },
|
|
50
50
|
collapsible: { type: Boolean, required: false, default: true }
|
|
51
51
|
});
|
|
52
52
|
const emit = defineEmits(["update:modelValue"]);
|
|
53
53
|
const slots = defineSlots();
|
|
54
54
|
const rootProps = useForwardPropsEmits(computed(() => ({
|
|
55
55
|
as: props.as,
|
|
56
|
-
modelValue: props.modelValue,
|
|
57
|
-
defaultValue: props.defaultValue,
|
|
58
56
|
delayDuration: props.delayDuration,
|
|
59
57
|
skipDelayDuration: props.skipDelayDuration,
|
|
60
58
|
orientation: props.orientation,
|
|
@@ -106,20 +104,20 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
106
104
|
:size="item.ui?.linkLeadingAvatarSize || props.ui?.linkLeadingAvatarSize || ui.linkLeadingAvatarSize()"
|
|
107
105
|
v-bind="item.avatar"
|
|
108
106
|
:class="ui.linkLeadingAvatar({ class: [props.ui?.linkLeadingAvatar, item.ui?.linkLeadingAvatar], active, disabled: item.disabled })"
|
|
109
|
-
data-part="
|
|
107
|
+
data-part="linkLeadingAvatar"
|
|
110
108
|
/>
|
|
111
109
|
<Icon
|
|
112
110
|
v-else-if="item.icon"
|
|
113
111
|
:name="item.icon"
|
|
114
112
|
:class="ui.linkLeadingIcon({ class: [props.ui?.linkLeadingIcon, item.ui?.linkLeadingIcon], active, disabled: !!item.disabled })"
|
|
115
|
-
data-part="
|
|
113
|
+
data-part="linkLeadingIcon"
|
|
116
114
|
/>
|
|
117
115
|
</slot>
|
|
118
116
|
|
|
119
117
|
<span
|
|
120
|
-
v-if="
|
|
118
|
+
v-if="get(item, props.labelKey) || slots[`${item.slot || 'item'}-label`]"
|
|
121
119
|
:class="ui.linkLabel({ class: [props.ui?.linkLabel, item.ui?.linkLabel] })"
|
|
122
|
-
data-part="
|
|
120
|
+
data-part="linkLabel"
|
|
123
121
|
>
|
|
124
122
|
<slot :name="`${item.slot || 'item'}-label`" :item="item" :active="active" :index="index">
|
|
125
123
|
{{ get(item, props.labelKey) }}
|
|
@@ -129,16 +127,16 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
129
127
|
v-if="item.target === '_blank' && props.externalIcon !== false"
|
|
130
128
|
:name="typeof props.externalIcon === 'string' ? props.externalIcon : appConfig.ui.icons.external"
|
|
131
129
|
:class="ui.linkLabelExternalIcon({ class: [props.ui?.linkLabelExternalIcon, item.ui?.linkLabelExternalIcon], active })"
|
|
132
|
-
data-part="
|
|
130
|
+
data-part="linkLabelExternalIcon"
|
|
133
131
|
/>
|
|
134
132
|
</span>
|
|
135
133
|
|
|
136
134
|
<component
|
|
137
135
|
:is="props.orientation === 'vertical' && item.children?.length && !props.collapsed ? AccordionTrigger : 'span'"
|
|
138
|
-
v-if="
|
|
136
|
+
v-if="item.badge !== void 0 || orientation === 'horizontal' && (item.children?.length || !!slots[`${item.slot || 'item'}-content`]) || orientation === 'vertical' && item.children?.length || item.trailingIcon || !!slots[`${item.slot || 'item'}-trailing`]"
|
|
139
137
|
as="span"
|
|
140
138
|
:class="ui.linkTrailing({ class: [props.ui?.linkTrailing, item.ui?.linkTrailing] })"
|
|
141
|
-
data-part="
|
|
139
|
+
data-part="linkTrailing"
|
|
142
140
|
@click.stop.prevent
|
|
143
141
|
>
|
|
144
142
|
<slot :name="`${item.slot || 'item'}-trailing`" :item="item" :active="active" :index="index" :ui="ui">
|
|
@@ -149,20 +147,20 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
149
147
|
:size="item.ui?.linkTrailingBadgeSize || props.ui?.linkTrailingBadgeSize || ui.linkTrailingBadgeSize()"
|
|
150
148
|
v-bind="typeof item.badge === 'string' || typeof item.badge === 'number' ? { label: item.badge } : item.badge"
|
|
151
149
|
:class="ui.linkTrailingBadge({ class: [props.ui?.linkTrailingBadge, item.ui?.linkTrailingBadge] })"
|
|
152
|
-
data-part="
|
|
150
|
+
data-part="linkTrailingBadge"
|
|
153
151
|
/>
|
|
154
152
|
|
|
155
153
|
<Icon
|
|
156
154
|
v-if="orientation === 'horizontal' && (item.children?.length || !!slots[`${item.slot || 'item'}-content`]) || orientation === 'vertical' && item.children?.length"
|
|
157
155
|
:name="item.trailingIcon || props.trailingIcon || appConfig.ui.icons.chevronDown"
|
|
158
156
|
:class="ui.linkTrailingIcon({ class: [props.ui?.linkTrailingIcon, item.ui?.linkTrailingIcon], active })"
|
|
159
|
-
data-part="
|
|
157
|
+
data-part="linkTrailingIcon"
|
|
160
158
|
/>
|
|
161
159
|
<Icon
|
|
162
160
|
v-else-if="item.trailingIcon"
|
|
163
161
|
:name="item.trailingIcon"
|
|
164
162
|
:class="ui.linkTrailingIcon({ class: [props.ui?.linkTrailingIcon, item.ui?.linkTrailingIcon], active })"
|
|
165
|
-
data-part="
|
|
163
|
+
data-part="linkTrailingIcon"
|
|
166
164
|
/>
|
|
167
165
|
</slot>
|
|
168
166
|
</component>
|
|
@@ -186,7 +184,7 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
186
184
|
>
|
|
187
185
|
<component
|
|
188
186
|
:is="
|
|
189
|
-
props.orientation === 'horizontal' && (item.children?.length || slots[`${item.slot || 'item'}-content`]) ? NavigationMenuTrigger : orientation === 'vertical' && item.children?.length && !collapsed && !slotProps.href ? AccordionTrigger : NavigationMenuLink
|
|
187
|
+
props.orientation === 'horizontal' && (item.children?.length || slots[`${item.slot || 'item'}-content`]) ? NavigationMenuTrigger : orientation === 'vertical' && item.children?.length && !props.collapsed && !slotProps.href ? AccordionTrigger : NavigationMenuLink
|
|
190
188
|
"
|
|
191
189
|
:active="active || item.active"
|
|
192
190
|
:disabled="item.disabled"
|
|
@@ -214,20 +212,20 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
214
212
|
|
|
215
213
|
<template #content="{ close }">
|
|
216
214
|
<slot :name="`${item.slot || 'item'}-content`" :item="item" :active="active || item.active" :index="index" :ui="ui" :close="close">
|
|
217
|
-
<ul :class="ui.childList({ class: [props.ui?.childList, item.ui?.childList] })" data-part="
|
|
218
|
-
<li :class="ui.childLabel({ class: [props.ui?.childLabel, item.ui?.childLabel] })" data-part="
|
|
215
|
+
<ul :class="ui.childList({ class: [props.ui?.childList, item.ui?.childList] })" data-part="childList">
|
|
216
|
+
<li :class="ui.childLabel({ class: [props.ui?.childLabel, item.ui?.childLabel] })" data-part="childLabel">
|
|
219
217
|
{{ get(item, props.labelKey) }}
|
|
220
218
|
</li>
|
|
221
|
-
<li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: [props.ui?.childItem, item.ui?.childItem] })" data-part="
|
|
219
|
+
<li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: [props.ui?.childItem, item.ui?.childItem] })" data-part="childItem">
|
|
222
220
|
<Link v-slot="{ active: childActive, ...childSlotProps }" v-bind="pickLinkProps(childItem)" custom>
|
|
223
221
|
<NavigationMenuLink :active="childActive" as-child @select="childItem.onSelect">
|
|
224
|
-
<LinkBase v-bind="childSlotProps" :class="ui.childLink({ class: [props.ui?.childLink, item.ui?.childLink, childItem.class], active: childActive })" data-part="
|
|
225
|
-
<Icon v-if="childItem.icon" :name="childItem.icon" :class="ui.childLinkIcon({ class: [props.ui?.childLinkIcon, item.ui?.childLinkIcon], active: childActive })" data-part="
|
|
222
|
+
<LinkBase v-bind="childSlotProps" :class="ui.childLink({ class: [props.ui?.childLink, item.ui?.childLink, childItem.class], active: childActive })" data-part="childLink">
|
|
223
|
+
<Icon v-if="childItem.icon" :name="childItem.icon" :class="ui.childLinkIcon({ class: [props.ui?.childLinkIcon, item.ui?.childLinkIcon], active: childActive })" data-part="childLinkIcon" />
|
|
226
224
|
|
|
227
|
-
<span :class="ui.childLinkLabel({ class: [props.ui?.childLinkLabel, item.ui?.childLinkLabel], active: childActive })" data-part="
|
|
225
|
+
<span :class="ui.childLinkLabel({ class: [props.ui?.childLinkLabel, item.ui?.childLinkLabel], active: childActive })" data-part="childLinkLabel">
|
|
228
226
|
{{ get(childItem, props.labelKey) }}
|
|
229
227
|
|
|
230
|
-
<Icon v-if="childItem.target === '_blank' && props.externalIcon !== false" :name="typeof props.externalIcon === 'string' ? props.externalIcon : appConfig.ui.icons.external" :class="ui.childLinkLabelExternalIcon({ class: [props.ui?.childLinkLabelExternalIcon, item.ui?.childLinkLabelExternalIcon], active: childActive })" data-part="
|
|
228
|
+
<Icon v-if="childItem.target === '_blank' && props.externalIcon !== false" :name="typeof props.externalIcon === 'string' ? props.externalIcon : appConfig.ui.icons.external" :class="ui.childLinkLabelExternalIcon({ class: [props.ui?.childLinkLabelExternalIcon, item.ui?.childLinkLabelExternalIcon], active: childActive })" data-part="childLinkLabelExternalIcon" />
|
|
231
229
|
</span>
|
|
232
230
|
</LinkBase>
|
|
233
231
|
</NavigationMenuLink>
|
|
@@ -254,20 +252,20 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
254
252
|
data-part="content"
|
|
255
253
|
>
|
|
256
254
|
<slot :name="`${item.slot || 'item'}-content`" :item="item" :active="active" :index="index" :ui="ui">
|
|
257
|
-
<ul :class="ui.childList({ class: [props.ui?.childList, item.ui?.childList] })" data-part="
|
|
258
|
-
<li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: [props.ui?.childItem, item.ui?.childItem] })" data-part="
|
|
255
|
+
<ul :class="ui.childList({ class: [props.ui?.childList, item.ui?.childList] })" data-part="childList">
|
|
256
|
+
<li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: [props.ui?.childItem, item.ui?.childItem] })" data-part="childItem">
|
|
259
257
|
<Link v-slot="{ active: childActive, ...childSlotProps }" v-bind="pickLinkProps(childItem)" custom>
|
|
260
258
|
<NavigationMenuLink :active="childActive" as-child @select="childItem.onSelect">
|
|
261
|
-
<LinkBase v-bind="childSlotProps" :class="ui.childLink({ class: [props.ui?.childLink, item.ui?.childLink, childItem.class], active: childActive })" data-part="
|
|
262
|
-
<Icon v-if="childItem.icon" :name="childItem.icon" :class="ui.childLinkIcon({ class: [props.ui?.childLinkIcon, item.ui?.childLinkIcon], active: childActive })" data-part="
|
|
259
|
+
<LinkBase v-bind="childSlotProps" :class="ui.childLink({ class: [props.ui?.childLink, item.ui?.childLink, childItem.class], active: childActive })" data-part="childLink">
|
|
260
|
+
<Icon v-if="childItem.icon" :name="childItem.icon" :class="ui.childLinkIcon({ class: [props.ui?.childLinkIcon, item.ui?.childLinkIcon], active: childActive })" data-part="childLinkIcon" />
|
|
263
261
|
|
|
264
|
-
<div :class="ui.childLinkWrapper({ class: [props.ui?.childLinkWrapper, item.ui?.childLinkWrapper] })" data-part="
|
|
265
|
-
<p :class="ui.childLinkLabel({ class: [props.ui?.childLinkLabel, item.ui?.childLinkLabel], active: childActive })" data-part="
|
|
262
|
+
<div :class="ui.childLinkWrapper({ class: [props.ui?.childLinkWrapper, item.ui?.childLinkWrapper] })" data-part="childLinkWrapper">
|
|
263
|
+
<p :class="ui.childLinkLabel({ class: [props.ui?.childLinkLabel, item.ui?.childLinkLabel], active: childActive })" data-part="childLinkLabel">
|
|
266
264
|
{{ get(childItem, props.labelKey) }}
|
|
267
265
|
|
|
268
|
-
<Icon v-if="childItem.target === '_blank' && props.externalIcon !== false" :name="typeof props.externalIcon === 'string' ? props.externalIcon : appConfig.ui.icons.external" :class="ui.childLinkLabelExternalIcon({ class: [props.ui?.childLinkLabelExternalIcon, item.ui?.childLinkLabelExternalIcon], active: childActive })" data-part="
|
|
266
|
+
<Icon v-if="childItem.target === '_blank' && props.externalIcon !== false" :name="typeof props.externalIcon === 'string' ? props.externalIcon : appConfig.ui.icons.external" :class="ui.childLinkLabelExternalIcon({ class: [props.ui?.childLinkLabelExternalIcon, item.ui?.childLinkLabelExternalIcon], active: childActive })" data-part="childLinkLabelExternalIcon" />
|
|
269
267
|
</p>
|
|
270
|
-
<p v-if="childItem.description" :class="ui.childLinkDescription({ class: [props.ui?.childLinkDescription, item.ui?.childLinkDescription], active: childActive })" data-part="
|
|
268
|
+
<p v-if="childItem.description" :class="ui.childLinkDescription({ class: [props.ui?.childLinkDescription, item.ui?.childLinkDescription], active: childActive })" data-part="childLinkDescription">
|
|
271
269
|
{{ childItem.description }}
|
|
272
270
|
</p>
|
|
273
271
|
</div>
|
|
@@ -285,7 +283,7 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
285
283
|
v-bind="{ ...accordionProps, defaultValue: getAccordionDefaultValue(item.children, level + 1) }"
|
|
286
284
|
as="ul"
|
|
287
285
|
:class="ui.childList({ class: [props.ui?.childList, item.ui?.childList] })"
|
|
288
|
-
data-part="
|
|
286
|
+
data-part="childList"
|
|
289
287
|
>
|
|
290
288
|
<ReuseItemTemplate
|
|
291
289
|
v-for="(childItem, childIndex) in item.children"
|
|
@@ -294,7 +292,7 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
294
292
|
:index="childIndex"
|
|
295
293
|
:level="level + 1"
|
|
296
294
|
:class="ui.childItem({ class: [props.ui?.childItem, item.ui?.childItem] })"
|
|
297
|
-
data-part="
|
|
295
|
+
data-part="childItem"
|
|
298
296
|
/>
|
|
299
297
|
</AccordionRoot>
|
|
300
298
|
</AccordionContent>
|
|
@@ -302,7 +300,14 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
302
300
|
</DefineItemTemplate>
|
|
303
301
|
|
|
304
302
|
<NavigationMenuRoot
|
|
305
|
-
v-bind="{
|
|
303
|
+
v-bind="{
|
|
304
|
+
...rootProps,
|
|
305
|
+
...props.orientation === 'horizontal' ? {
|
|
306
|
+
modelValue: props.modelValue,
|
|
307
|
+
defaultValue: props.defaultValue
|
|
308
|
+
} : {},
|
|
309
|
+
...$attrs
|
|
310
|
+
}"
|
|
306
311
|
:class="ui.root({ class: [props.ui?.root, props.class] })"
|
|
307
312
|
:data-collapsed="props.collapsed"
|
|
308
313
|
data-part="root"
|
|
@@ -311,8 +316,12 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
311
316
|
|
|
312
317
|
<template v-for="(list, listIndex) in lists" :key="`list-${listIndex}`">
|
|
313
318
|
<component
|
|
314
|
-
v-bind="props.orientation === 'vertical' && !props.collapsed ? {
|
|
315
|
-
|
|
319
|
+
v-bind="props.orientation === 'vertical' && !props.collapsed ? {
|
|
320
|
+
...accordionProps,
|
|
321
|
+
modelValue: props.modelValue,
|
|
322
|
+
defaultValue: props.defaultValue ?? getAccordionDefaultValue(list)
|
|
323
|
+
} : {}"
|
|
324
|
+
:is="props.orientation === 'vertical' ? AccordionRoot : NavigationMenuList"
|
|
316
325
|
as="ul"
|
|
317
326
|
:class="ui.list({ class: props.ui?.list })"
|
|
318
327
|
data-part="list"
|
|
@@ -325,7 +334,7 @@ function getAccordionDefaultValue(list, level = 0) {
|
|
|
325
334
|
|
|
326
335
|
<slot name="list-trailing"></slot>
|
|
327
336
|
|
|
328
|
-
<div v-if="props.orientation === 'horizontal'" :class="ui.viewportWrapper({ class: props.ui?.viewportWrapper })" data-part="
|
|
337
|
+
<div v-if="props.orientation === 'horizontal'" :class="ui.viewportWrapper({ class: props.ui?.viewportWrapper })" data-part="viewportWrapper">
|
|
329
338
|
<NavigationMenuIndicator v-if="props.arrow" :class="ui.indicator({ class: props.ui?.indicator })" data-part="indicator">
|
|
330
339
|
<div :class="ui.arrow({ class: props.ui?.arrow })" data-part="arrow"></div>
|
|
331
340
|
</NavigationMenuIndicator>
|