@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.
Files changed (38) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +1 -1
  3. package/dist/runtime/components/Accordion.vue +2 -2
  4. package/dist/runtime/components/Badge.vue +3 -3
  5. package/dist/runtime/components/Breadcrumb.vue +4 -4
  6. package/dist/runtime/components/Button.vue +3 -3
  7. package/dist/runtime/components/Calendar.vue +6 -8
  8. package/dist/runtime/components/Carousel.vue +19 -0
  9. package/dist/runtime/components/Checkbox.vue +1 -1
  10. package/dist/runtime/components/CheckboxGroup.vue +131 -0
  11. package/dist/runtime/components/CheckboxGroup.vue.d.ts +89 -0
  12. package/dist/runtime/components/DropdownMenuContent.vue +11 -11
  13. package/dist/runtime/components/FormField.vue +1 -1
  14. package/dist/runtime/components/Input.vue +3 -3
  15. package/dist/runtime/components/InputNumber.vue +2 -4
  16. package/dist/runtime/components/InputNumber.vue.d.ts +0 -5
  17. package/dist/runtime/components/InputTags.vue +155 -0
  18. package/dist/runtime/components/InputTags.vue.d.ts +85 -0
  19. package/dist/runtime/components/Marquee.vue +38 -0
  20. package/dist/runtime/components/Marquee.vue.d.ts +54 -0
  21. package/dist/runtime/components/NavigationMenu.vue +46 -37
  22. package/dist/runtime/components/NavigationMenu.vue.d.ts +44 -9
  23. package/dist/runtime/components/RadioGroup.vue.d.ts +2 -2
  24. package/dist/runtime/components/Select.vue +11 -11
  25. package/dist/runtime/components/Slider.vue +1 -1
  26. package/dist/runtime/components/Table.vue +54 -32
  27. package/dist/runtime/components/Table.vue.d.ts +14 -14
  28. package/dist/runtime/components/Tabs.vue +3 -3
  29. package/dist/runtime/components/Textarea.vue +3 -3
  30. package/dist/runtime/components/Timeline.vue +102 -0
  31. package/dist/runtime/components/Timeline.vue.d.ts +74 -0
  32. package/dist/runtime/types/index.d.ts +5 -0
  33. package/dist/runtime/types/index.js +5 -0
  34. package/dist/runtime/types/utils.d.ts +6 -3
  35. package/dist/shared/{ui.DSyJHSTk.mjs → ui.DLOxhmP0.mjs} +523 -68
  36. package/dist/unplugin.mjs +1 -1
  37. package/dist/vite.mjs +1 -1
  38. 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="link-leading-avatar"
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="link-leading-icon"
113
+ data-part="linkLeadingIcon"
116
114
  />
117
115
  </slot>
118
116
 
119
117
  <span
120
- v-if="(!props.collapsed || props.orientation !== 'vertical') && (get(item, props.labelKey) || slots[`${item.slot || 'item'}-label`])"
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="link-label"
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="link-label-external-icon"
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="(!props.collapsed || props.orientation !== 'vertical') && (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`])"
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="link-trailing"
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="link-trailing-badge"
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="link-trailing-icon"
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="link-trailing-icon"
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="child-list">
218
- <li :class="ui.childLabel({ class: [props.ui?.childLabel, item.ui?.childLabel] })" data-part="child-label">
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="child-item">
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="child-link">
225
- <Icon v-if="childItem.icon" :name="childItem.icon" :class="ui.childLinkIcon({ class: [props.ui?.childLinkIcon, item.ui?.childLinkIcon], active: childActive })" data-part="child-link-icon" />
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="child-link-label">
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="child-link-label-external-icon" />
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="child-list">
258
- <li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: [props.ui?.childItem, item.ui?.childItem] })" data-part="child-item">
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="child-link">
262
- <Icon v-if="childItem.icon" :name="childItem.icon" :class="ui.childLinkIcon({ class: [props.ui?.childLinkIcon, item.ui?.childLinkIcon], active: childActive })" data-part="child-link-icon" />
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="child-link-wrapper">
265
- <p :class="ui.childLinkLabel({ class: [props.ui?.childLinkLabel, item.ui?.childLinkLabel], active: childActive })" data-part="child-link-label">
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="child-link-label-external-icon" />
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="child-link-description">
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="child-list"
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="child-item"
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="{ ...rootProps, ...$attrs }"
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 ? { ...accordionProps, defaultValue: getAccordionDefaultValue(list) } : {}"
315
- :is="props.orientation === 'vertical' && !props.collapsed ? AccordionRoot : NavigationMenuList"
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="viewport-wrapper">
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>