@bitrix24/b24ui-nuxt 2.1.4 → 2.1.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitrix24/b24ui-nuxt",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
4
4
  "docs": "https://bitrix24.github.io/b24ui/guide/installation-nuxt-app.html",
5
5
  "configKey": "b24ui",
6
6
  "compatibility": {
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defu } from 'defu';
2
2
  import { defineNuxtModule, createResolver, addPlugin, hasNuxtModule, addComponentsDir, addImportsDir, installModule } from '@nuxt/kit';
3
- import { d as defaultOptions, v as version, n as name, a as getDefaultConfig, b as addTemplates } from './shared/b24ui-nuxt.Bs0V9FLV.mjs';
3
+ import { d as defaultOptions, v as version, n as name, a as getDefaultConfig, b as addTemplates } from './shared/b24ui-nuxt.DwYJyZL6.mjs';
4
4
  import 'node:url';
5
5
  import 'scule';
6
6
  import 'knitwork';
@@ -45,7 +45,8 @@ const b24ui = computed(() => tv({ extend: theme, ...appConfig.b24ui?.checkboxGro
45
45
  required: props.required,
46
46
  orientation: props.orientation,
47
47
  color: props.color,
48
- variant: props.variant
48
+ variant: props.variant,
49
+ disabled: disabled.value
49
50
  }));
50
51
  function normalizeItem(item) {
51
52
  if (item === null) {
@@ -113,7 +114,7 @@ function onUpdate(value) {
113
114
  :disabled="item.disabled || disabled"
114
115
  :b24ui="{ ...props.b24ui ? omit(props.b24ui, ['root']) : void 0, ...item.b24ui || {} }"
115
116
  data-slot="item"
116
- :class="b24ui.item({ class: [props.b24ui?.item, item.b24ui?.item, item.class] })"
117
+ :class="b24ui.item({ class: [props.b24ui?.item, item.b24ui?.item, item.class], disabled: item.disabled || disabled })"
117
118
  >
118
119
  <template v-for="(_, name) in getProxySlots()" #[name]>
119
120
  <slot :name="name" :item="item" />
@@ -75,7 +75,9 @@ const { t } = useLocale();
75
75
  const appConfig = useAppConfig();
76
76
  const { toggleSearch } = useDashboard({ toggleSearch: () => {
77
77
  } });
78
- const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.dashboardSearchButton || {} })());
78
+ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.dashboardSearchButton || {} })({
79
+ collapsed: props.collapsed
80
+ }));
79
81
  </script>
80
82
 
81
83
  <template>
@@ -86,7 +88,6 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.dashboa
86
88
  v-bind="{
87
89
  ...buttonProps,
88
90
  ...collapsed ? {
89
- 'label': void 0,
90
91
  'aria-label': label || t('dashboardSearchButton.label')
91
92
  } : {
92
93
  color: 'air-secondary-no-accent'
@@ -102,7 +103,7 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.dashboa
102
103
  <slot :name="name" v-bind="slotData" />
103
104
  </template>
104
105
 
105
- <template v-if="!collapsed" #trailing="{ b24ui: b24uiProxy }">
106
+ <template #trailing="{ b24ui: b24uiProxy }">
106
107
  <div data-slot="trailing" :class="b24ui.trailing({ class: props.b24ui?.trailing })">
107
108
  <slot name="trailing" :b24ui="b24uiProxy">
108
109
  <template v-if="kbds?.length">
@@ -1,6 +1,56 @@
1
- import type { NuxtLinkProps } from '#app';
1
+ import type { RouterLinkProps, RouteLocationRaw } from 'vue-router';
2
2
  import type { ButtonHTMLAttributes, AnchorHTMLAttributes } from '../types/html';
3
- export interface LinkProps extends Omit<NuxtLinkProps, 'custom'>, /** @vue-ignore */ Omit<ButtonHTMLAttributes, 'type' | 'disabled'>, /** @vue-ignore */ Omit<AnchorHTMLAttributes, 'href' | 'target' | 'rel' | 'type'> {
3
+ interface NuxtLinkProps extends Omit<RouterLinkProps, 'to'> {
4
+ /**
5
+ * Route Location the link should navigate to when clicked on.
6
+ */
7
+ to?: RouteLocationRaw;
8
+ /**
9
+ * An alias for `to`. If used with `to`, `href` will be ignored
10
+ */
11
+ href?: NuxtLinkProps['to'];
12
+ /**
13
+ * Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases
14
+ */
15
+ external?: boolean;
16
+ /**
17
+ * Where to display the linked URL, as the name for a browsing context.
18
+ */
19
+ target?: '_blank' | '_parent' | '_self' | '_top' | (string & {}) | null;
20
+ /**
21
+ * A rel attribute value to apply on the link. Defaults to "noopener noreferrer" for external links.
22
+ */
23
+ rel?: 'noopener' | 'noreferrer' | 'nofollow' | 'sponsored' | 'ugc' | (string & {}) | null;
24
+ /**
25
+ * If set to true, no rel attribute will be added to the link
26
+ */
27
+ noRel?: boolean;
28
+ /**
29
+ * A class to apply to links that have been prefetched.
30
+ */
31
+ prefetchedClass?: string;
32
+ /**
33
+ * When enabled will prefetch middleware, layouts and payloads of links in the viewport.
34
+ */
35
+ prefetch?: boolean;
36
+ /**
37
+ * Allows controlling when to prefetch links. By default, prefetch is triggered only on visibility.
38
+ */
39
+ prefetchOn?: 'visibility' | 'interaction' | Partial<{
40
+ visibility: boolean;
41
+ interaction: boolean;
42
+ }>;
43
+ /**
44
+ * Escape hatch to disable `prefetch` attribute.
45
+ */
46
+ noPrefetch?: boolean;
47
+ /**
48
+ * An option to either add or remove trailing slashes in the `href` for this specific link.
49
+ * Overrides the global `trailingSlash` option if provided.
50
+ */
51
+ trailingSlash?: 'append' | 'remove';
52
+ }
53
+ export interface LinkProps extends NuxtLinkProps, /** @vue-ignore */ Omit<ButtonHTMLAttributes, 'type' | 'disabled'>, /** @vue-ignore */ Omit<AnchorHTMLAttributes, 'href' | 'target' | 'rel' | 'type'> {
4
54
  /**
5
55
  * The element or component this component should render as when not a link.
6
56
  * @defaultValue 'button'
@@ -1,6 +1,56 @@
1
- import type { NuxtLinkProps } from '#app';
1
+ import type { RouterLinkProps, RouteLocationRaw } from 'vue-router';
2
2
  import type { ButtonHTMLAttributes, AnchorHTMLAttributes } from '../types/html';
3
- export interface LinkProps extends Omit<NuxtLinkProps, 'custom'>, /** @vue-ignore */ Omit<ButtonHTMLAttributes, 'type' | 'disabled'>, /** @vue-ignore */ Omit<AnchorHTMLAttributes, 'href' | 'target' | 'rel' | 'type'> {
3
+ interface NuxtLinkProps extends Omit<RouterLinkProps, 'to'> {
4
+ /**
5
+ * Route Location the link should navigate to when clicked on.
6
+ */
7
+ to?: RouteLocationRaw;
8
+ /**
9
+ * An alias for `to`. If used with `to`, `href` will be ignored
10
+ */
11
+ href?: NuxtLinkProps['to'];
12
+ /**
13
+ * Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases
14
+ */
15
+ external?: boolean;
16
+ /**
17
+ * Where to display the linked URL, as the name for a browsing context.
18
+ */
19
+ target?: '_blank' | '_parent' | '_self' | '_top' | (string & {}) | null;
20
+ /**
21
+ * A rel attribute value to apply on the link. Defaults to "noopener noreferrer" for external links.
22
+ */
23
+ rel?: 'noopener' | 'noreferrer' | 'nofollow' | 'sponsored' | 'ugc' | (string & {}) | null;
24
+ /**
25
+ * If set to true, no rel attribute will be added to the link
26
+ */
27
+ noRel?: boolean;
28
+ /**
29
+ * A class to apply to links that have been prefetched.
30
+ */
31
+ prefetchedClass?: string;
32
+ /**
33
+ * When enabled will prefetch middleware, layouts and payloads of links in the viewport.
34
+ */
35
+ prefetch?: boolean;
36
+ /**
37
+ * Allows controlling when to prefetch links. By default, prefetch is triggered only on visibility.
38
+ */
39
+ prefetchOn?: 'visibility' | 'interaction' | Partial<{
40
+ visibility: boolean;
41
+ interaction: boolean;
42
+ }>;
43
+ /**
44
+ * Escape hatch to disable `prefetch` attribute.
45
+ */
46
+ noPrefetch?: boolean;
47
+ /**
48
+ * An option to either add or remove trailing slashes in the `href` for this specific link.
49
+ * Overrides the global `trailingSlash` option if provided.
50
+ */
51
+ trailingSlash?: 'append' | 'remove';
52
+ }
53
+ export interface LinkProps extends NuxtLinkProps, /** @vue-ignore */ Omit<ButtonHTMLAttributes, 'type' | 'disabled'>, /** @vue-ignore */ Omit<AnchorHTMLAttributes, 'href' | 'target' | 'rel' | 'type'> {
4
54
  /**
5
55
  * The element or component this component should render as when not a link.
6
56
  * @defaultValue 'button'
@@ -1,4 +1,4 @@
1
- import type { NavigationMenuRootProps, NavigationMenuRootEmits, NavigationMenuContentProps, NavigationMenuContentEmits, AccordionRootProps } from 'reka-ui';
1
+ import type { NavigationMenuRootProps, NavigationMenuContentProps, NavigationMenuContentEmits, AccordionRootProps } from 'reka-ui';
2
2
  import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/b24ui/navigation-menu';
4
4
  import type { AvatarProps, BadgeProps, IconComponent, LinkProps, PopoverProps, TooltipProps } from '../types';
@@ -75,6 +75,9 @@ export interface NavigationMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'cu
75
75
  b24ui?: Pick<NavigationMenu['slots'], 'item' | 'linkLeadingAvatarSize' | 'linkLeadingAvatar' | 'linkLeadingIcon' | 'linkLabel' | 'linkLabelExternalIcon' | 'linkTrailing' | 'linkLeadingHint' | 'linkLeadingBadgeSize' | 'linkLeadingBadge' | 'linkTrailingIcon' | 'label' | 'link' | 'content' | 'childList' | 'childLabel' | 'childItem' | 'childLink' | 'childLinkIcon' | 'childLinkHint' | 'childLinkBadgeSize' | 'childLinkBadge' | 'childLinkWrapper' | 'childLinkLabel' | 'childLinkLabelExternalIcon' | 'popoverWrapper'>;
76
76
  [key: string]: any;
77
77
  }
78
+ type SingleOrMultipleType = 'single' | 'multiple';
79
+ type Orientation = NavigationMenuRootProps['orientation'];
80
+ type NavigationMenuModelValue<K extends SingleOrMultipleType = SingleOrMultipleType, O extends Orientation = Orientation> = O extends 'horizontal' ? string : K extends 'single' ? string : K extends 'multiple' ? string[] : string | string[];
78
81
  /**
79
82
  * @memo remove contentOrientation
80
83
  * @memo remove highlight
@@ -83,12 +86,37 @@ export interface NavigationMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'cu
83
86
  * @memo remove color
84
87
  * @memo remove variant (link) -> use variant.pill
85
88
  */
86
- export interface NavigationMenuProps<T extends ArrayOrNested<NavigationMenuItem> = ArrayOrNested<NavigationMenuItem>> extends Pick<NavigationMenuRootProps, 'modelValue' | 'defaultValue' | 'delayDuration' | 'disableClickTrigger' | 'disableHoverTrigger' | 'skipDelayDuration' | 'disablePointerLeaveClose' | 'unmountOnHide'>, Pick<AccordionRootProps, 'disabled' | 'type' | 'collapsible'> {
89
+ export interface NavigationMenuProps<T extends ArrayOrNested<NavigationMenuItem> = ArrayOrNested<NavigationMenuItem>, K extends SingleOrMultipleType = SingleOrMultipleType, O extends Orientation = Orientation> extends Pick<NavigationMenuRootProps, 'delayDuration' | 'disableClickTrigger' | 'disableHoverTrigger' | 'skipDelayDuration' | 'disablePointerLeaveClose' | 'unmountOnHide'>, Pick<AccordionRootProps, 'disabled' | 'collapsible'> {
87
90
  /**
88
91
  * The element or component this component should render as.
89
92
  * @defaultValue 'div'
90
93
  */
91
94
  as?: any;
95
+ /**
96
+ * Determines whether a "single" or "multiple" items can be selected at a time.
97
+ *
98
+ * Only works when `orientation` is `vertical`.
99
+ * @defaultValue 'multiple'
100
+ */
101
+ type?: K;
102
+ /**
103
+ * The controlled value of the active item(s).
104
+ * - In horizontal orientation: always `string`
105
+ * - In vertical orientation with `type="single"`: `string`
106
+ * - In vertical orientation with `type="multiple"`: `string[]`
107
+ *
108
+ * Use this when you need to control the state of the items. Can be binded with `v-model`
109
+ */
110
+ modelValue?: NavigationMenuModelValue<K, O>;
111
+ /**
112
+ * The default active value of the item(s).
113
+ * - In horizontal orientation: always `string`
114
+ * - In vertical orientation with `type="single"`: `string`
115
+ * - In vertical orientation with `type="multiple"`: `string[]`
116
+ *
117
+ * Use when you do not need to control the state of the item(s).
118
+ */
119
+ defaultValue?: NavigationMenuModelValue<K, O>;
92
120
  /**
93
121
  * The icon displayed to open the menu.
94
122
  * @defaultValue icons.chevronDown
@@ -107,7 +135,7 @@ export interface NavigationMenuProps<T extends ArrayOrNested<NavigationMenuItem>
107
135
  * The orientation of the menu.
108
136
  * @defaultValue 'horizontal'
109
137
  */
110
- orientation?: NavigationMenuRootProps['orientation'];
138
+ orientation?: O;
111
139
  /**
112
140
  * Collapse the navigation menu to only show icons.
113
141
  * Only works when `orientation` is `vertical`.
@@ -138,8 +166,15 @@ export interface NavigationMenuProps<T extends ArrayOrNested<NavigationMenuItem>
138
166
  class?: any;
139
167
  b24ui?: NavigationMenu['slots'];
140
168
  }
141
- export interface NavigationMenuEmits extends NavigationMenuRootEmits {
142
- }
169
+ export type NavigationMenuEmits<K extends SingleOrMultipleType = SingleOrMultipleType, O extends Orientation = Orientation> = {
170
+ /**
171
+ * Event handler called when the value changes.
172
+ * - In horizontal orientation: emits `string`
173
+ * - In vertical orientation with `type="single"`: emits `string | undefined`
174
+ * - In vertical orientation with `type="multiple"`: emits `string[] | undefined`
175
+ */
176
+ 'update:modelValue': [value: NavigationMenuModelValue<K, O> | undefined];
177
+ };
143
178
  type SlotProps<T extends NavigationMenuItem> = (props: {
144
179
  item: T;
145
180
  index: number;
@@ -169,14 +204,14 @@ export type NavigationMenuSlots<A extends ArrayOrNested<NavigationMenuItem> = Ar
169
204
  active?: boolean;
170
205
  b24ui: NavigationMenu['b24ui'];
171
206
  }>;
172
- declare const __VLS_export: <T extends ArrayOrNested<NavigationMenuItem>>(__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<{
173
- props: __VLS_PrettifyLocal<NavigationMenuProps<T> & {
174
- "onUpdate:modelValue"?: ((value: string) => any) | undefined;
207
+ declare const __VLS_export: <T extends ArrayOrNested<NavigationMenuItem>, K extends SingleOrMultipleType = SingleOrMultipleType, O extends Orientation = Orientation>(__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<{
208
+ props: __VLS_PrettifyLocal<NavigationMenuProps<T, K, O> & {
209
+ "onUpdate:modelValue"?: ((value: NavigationMenuModelValue<K, O> | undefined) => any) | undefined;
175
210
  }> & import("vue").PublicProps;
176
211
  expose: (exposed: {}) => void;
177
212
  attrs: any;
178
213
  slots: NavigationMenuSlots<T, NestedItem<T>>;
179
- emit: (evt: "update:modelValue", value: string) => void;
214
+ emit: (evt: "update:modelValue", value: NavigationMenuModelValue<K, O> | undefined) => void;
180
215
  }>) => import("vue").VNode & {
181
216
  __ctx?: Awaited<typeof __VLS_setup>;
182
217
  };
@@ -21,6 +21,9 @@ import B24Tooltip from "./Tooltip.vue";
21
21
  defineOptions({ inheritAttrs: false });
22
22
  const props = defineProps({
23
23
  as: { type: null, required: false },
24
+ type: { type: null, required: false, default: "multiple" },
25
+ modelValue: { type: null, required: false },
26
+ defaultValue: { type: null, required: false },
24
27
  trailingIcon: { type: [Function, Object], required: false },
25
28
  externalIcon: { type: [Boolean, Function, Object], required: false, default: true },
26
29
  items: { type: null, required: false },
@@ -32,8 +35,6 @@ const props = defineProps({
32
35
  labelKey: { type: null, required: false, default: "label" },
33
36
  class: { type: null, required: false },
34
37
  b24ui: { type: null, required: false },
35
- modelValue: { type: String, required: false },
36
- defaultValue: { type: String, required: false },
37
38
  delayDuration: { type: Number, required: false, default: 0 },
38
39
  disableClickTrigger: { type: Boolean, required: false },
39
40
  disableHoverTrigger: { type: Boolean, required: false },
@@ -41,7 +42,6 @@ const props = defineProps({
41
42
  disablePointerLeaveClose: { type: Boolean, required: false },
42
43
  unmountOnHide: { type: Boolean, required: false, default: true },
43
44
  disabled: { type: Boolean, required: false },
44
- type: { type: String, required: false, default: "multiple" },
45
45
  collapsible: { type: Boolean, required: false, default: true }
46
46
  });
47
47
  const emits = defineEmits(["update:modelValue"]);
@@ -49,8 +49,6 @@ const slots = defineSlots();
49
49
  const appConfig = useAppConfig();
50
50
  const rootProps = useForwardPropsEmits(computed(() => ({
51
51
  as: props.as,
52
- modelValue: props.modelValue,
53
- defaultValue: props.defaultValue,
54
52
  delayDuration: props.delayDuration,
55
53
  skipDelayDuration: props.skipDelayDuration,
56
54
  orientation: props.orientation,
@@ -133,7 +131,7 @@ function getAccordionDefaultValue(list, level = 0) {
133
131
  </slot>
134
132
 
135
133
  <span
136
- v-if="(!collapsed || orientation !== 'vertical') && (get(item, props.labelKey) || !!slots[item.slot ? `${item.slot}-label` : 'item-label'])"
134
+ v-if="get(item, props.labelKey) || !!slots[item.slot ? `${item.slot}-label` : 'item-label']"
137
135
  data-slot="linkLabel"
138
136
  :class="b24ui.linkLabel({ class: [props.b24ui?.linkLabel, item.b24ui?.linkLabel], active })"
139
137
  >
@@ -151,8 +149,10 @@ function getAccordionDefaultValue(list, level = 0) {
151
149
 
152
150
  <component
153
151
  :is="orientation === 'vertical' && item.children?.length && !collapsed ? AccordionTrigger : 'span'"
154
- v-if="(!collapsed || orientation !== 'vertical') && /* (item.badge || item.badge === 0) || */
155
- (orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content']) || orientation === 'vertical' && item.children?.length || item.trailingIcon || !!slots[item.slot ? `${item.slot}-trailing` : 'item-trailing'])"
152
+ v-if="
153
+ /* (item.badge || item.badge === 0) || */
154
+ orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content']) || orientation === 'vertical' && item.children?.length || item.trailingIcon || !!slots[item.slot ? `${item.slot}-trailing` : 'item-trailing']
155
+ "
156
156
  as="span"
157
157
  data-slot="linkTrailing"
158
158
  :class="b24ui.linkTrailing({ class: [props.b24ui?.linkTrailing, item.b24ui?.linkTrailing] })"
@@ -421,7 +421,14 @@ function getAccordionDefaultValue(list, level = 0) {
421
421
  </DefineItemTemplate>
422
422
 
423
423
  <NavigationMenuRoot
424
- v-bind="{ ...rootProps, ...$attrs }"
424
+ v-bind="{
425
+ ...rootProps,
426
+ ...orientation === 'horizontal' ? {
427
+ modelValue,
428
+ defaultValue
429
+ } : {},
430
+ ...$attrs
431
+ }"
425
432
  :data-collapsed="collapsed"
426
433
  data-component="section"
427
434
  data-slot="root"
@@ -433,9 +440,10 @@ function getAccordionDefaultValue(list, level = 0) {
433
440
  <component
434
441
  v-bind="orientation === 'vertical' && !collapsed ? {
435
442
  ...accordionProps,
436
- defaultValue: getAccordionDefaultValue(list)
443
+ modelValue,
444
+ defaultValue: defaultValue ?? getAccordionDefaultValue(list)
437
445
  } : {}"
438
- :is="orientation === 'vertical' && !collapsed ? AccordionRoot : NavigationMenuList"
446
+ :is="orientation === 'vertical' ? AccordionRoot : NavigationMenuList"
439
447
  as="ul"
440
448
  data-slot="list"
441
449
  :class="b24ui.list({ class: props.b24ui?.list })"
@@ -1,4 +1,4 @@
1
- import type { NavigationMenuRootProps, NavigationMenuRootEmits, NavigationMenuContentProps, NavigationMenuContentEmits, AccordionRootProps } from 'reka-ui';
1
+ import type { NavigationMenuRootProps, NavigationMenuContentProps, NavigationMenuContentEmits, AccordionRootProps } from 'reka-ui';
2
2
  import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/b24ui/navigation-menu';
4
4
  import type { AvatarProps, BadgeProps, IconComponent, LinkProps, PopoverProps, TooltipProps } from '../types';
@@ -75,6 +75,9 @@ export interface NavigationMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'cu
75
75
  b24ui?: Pick<NavigationMenu['slots'], 'item' | 'linkLeadingAvatarSize' | 'linkLeadingAvatar' | 'linkLeadingIcon' | 'linkLabel' | 'linkLabelExternalIcon' | 'linkTrailing' | 'linkLeadingHint' | 'linkLeadingBadgeSize' | 'linkLeadingBadge' | 'linkTrailingIcon' | 'label' | 'link' | 'content' | 'childList' | 'childLabel' | 'childItem' | 'childLink' | 'childLinkIcon' | 'childLinkHint' | 'childLinkBadgeSize' | 'childLinkBadge' | 'childLinkWrapper' | 'childLinkLabel' | 'childLinkLabelExternalIcon' | 'popoverWrapper'>;
76
76
  [key: string]: any;
77
77
  }
78
+ type SingleOrMultipleType = 'single' | 'multiple';
79
+ type Orientation = NavigationMenuRootProps['orientation'];
80
+ type NavigationMenuModelValue<K extends SingleOrMultipleType = SingleOrMultipleType, O extends Orientation = Orientation> = O extends 'horizontal' ? string : K extends 'single' ? string : K extends 'multiple' ? string[] : string | string[];
78
81
  /**
79
82
  * @memo remove contentOrientation
80
83
  * @memo remove highlight
@@ -83,12 +86,37 @@ export interface NavigationMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'cu
83
86
  * @memo remove color
84
87
  * @memo remove variant (link) -> use variant.pill
85
88
  */
86
- export interface NavigationMenuProps<T extends ArrayOrNested<NavigationMenuItem> = ArrayOrNested<NavigationMenuItem>> extends Pick<NavigationMenuRootProps, 'modelValue' | 'defaultValue' | 'delayDuration' | 'disableClickTrigger' | 'disableHoverTrigger' | 'skipDelayDuration' | 'disablePointerLeaveClose' | 'unmountOnHide'>, Pick<AccordionRootProps, 'disabled' | 'type' | 'collapsible'> {
89
+ export interface NavigationMenuProps<T extends ArrayOrNested<NavigationMenuItem> = ArrayOrNested<NavigationMenuItem>, K extends SingleOrMultipleType = SingleOrMultipleType, O extends Orientation = Orientation> extends Pick<NavigationMenuRootProps, 'delayDuration' | 'disableClickTrigger' | 'disableHoverTrigger' | 'skipDelayDuration' | 'disablePointerLeaveClose' | 'unmountOnHide'>, Pick<AccordionRootProps, 'disabled' | 'collapsible'> {
87
90
  /**
88
91
  * The element or component this component should render as.
89
92
  * @defaultValue 'div'
90
93
  */
91
94
  as?: any;
95
+ /**
96
+ * Determines whether a "single" or "multiple" items can be selected at a time.
97
+ *
98
+ * Only works when `orientation` is `vertical`.
99
+ * @defaultValue 'multiple'
100
+ */
101
+ type?: K;
102
+ /**
103
+ * The controlled value of the active item(s).
104
+ * - In horizontal orientation: always `string`
105
+ * - In vertical orientation with `type="single"`: `string`
106
+ * - In vertical orientation with `type="multiple"`: `string[]`
107
+ *
108
+ * Use this when you need to control the state of the items. Can be binded with `v-model`
109
+ */
110
+ modelValue?: NavigationMenuModelValue<K, O>;
111
+ /**
112
+ * The default active value of the item(s).
113
+ * - In horizontal orientation: always `string`
114
+ * - In vertical orientation with `type="single"`: `string`
115
+ * - In vertical orientation with `type="multiple"`: `string[]`
116
+ *
117
+ * Use when you do not need to control the state of the item(s).
118
+ */
119
+ defaultValue?: NavigationMenuModelValue<K, O>;
92
120
  /**
93
121
  * The icon displayed to open the menu.
94
122
  * @defaultValue icons.chevronDown
@@ -107,7 +135,7 @@ export interface NavigationMenuProps<T extends ArrayOrNested<NavigationMenuItem>
107
135
  * The orientation of the menu.
108
136
  * @defaultValue 'horizontal'
109
137
  */
110
- orientation?: NavigationMenuRootProps['orientation'];
138
+ orientation?: O;
111
139
  /**
112
140
  * Collapse the navigation menu to only show icons.
113
141
  * Only works when `orientation` is `vertical`.
@@ -138,8 +166,15 @@ export interface NavigationMenuProps<T extends ArrayOrNested<NavigationMenuItem>
138
166
  class?: any;
139
167
  b24ui?: NavigationMenu['slots'];
140
168
  }
141
- export interface NavigationMenuEmits extends NavigationMenuRootEmits {
142
- }
169
+ export type NavigationMenuEmits<K extends SingleOrMultipleType = SingleOrMultipleType, O extends Orientation = Orientation> = {
170
+ /**
171
+ * Event handler called when the value changes.
172
+ * - In horizontal orientation: emits `string`
173
+ * - In vertical orientation with `type="single"`: emits `string | undefined`
174
+ * - In vertical orientation with `type="multiple"`: emits `string[] | undefined`
175
+ */
176
+ 'update:modelValue': [value: NavigationMenuModelValue<K, O> | undefined];
177
+ };
143
178
  type SlotProps<T extends NavigationMenuItem> = (props: {
144
179
  item: T;
145
180
  index: number;
@@ -169,14 +204,14 @@ export type NavigationMenuSlots<A extends ArrayOrNested<NavigationMenuItem> = Ar
169
204
  active?: boolean;
170
205
  b24ui: NavigationMenu['b24ui'];
171
206
  }>;
172
- declare const __VLS_export: <T extends ArrayOrNested<NavigationMenuItem>>(__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<{
173
- props: __VLS_PrettifyLocal<NavigationMenuProps<T> & {
174
- "onUpdate:modelValue"?: ((value: string) => any) | undefined;
207
+ declare const __VLS_export: <T extends ArrayOrNested<NavigationMenuItem>, K extends SingleOrMultipleType = SingleOrMultipleType, O extends Orientation = Orientation>(__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<{
208
+ props: __VLS_PrettifyLocal<NavigationMenuProps<T, K, O> & {
209
+ "onUpdate:modelValue"?: ((value: NavigationMenuModelValue<K, O> | undefined) => any) | undefined;
175
210
  }> & import("vue").PublicProps;
176
211
  expose: (exposed: {}) => void;
177
212
  attrs: any;
178
213
  slots: NavigationMenuSlots<T, NestedItem<T>>;
179
- emit: (evt: "update:modelValue", value: string) => void;
214
+ emit: (evt: "update:modelValue", value: NavigationMenuModelValue<K, O> | undefined) => void;
180
215
  }>) => import("vue").VNode & {
181
216
  __ctx?: Awaited<typeof __VLS_setup>;
182
217
  };
@@ -111,15 +111,15 @@ function onUpdate(value) {
111
111
  v-for="item in normalizedItems"
112
112
  :key="item.value"
113
113
  data-slot="item"
114
- :class="b24ui.item({ class: [props.b24ui?.item, item.b24ui?.item, item.class] })"
114
+ :class="b24ui.item({ class: [props.b24ui?.item, item.b24ui?.item, item.class], disabled: item.disabled || disabled })"
115
115
  >
116
116
  <div data-slot="container" :class="b24ui.container({ class: [props.b24ui?.container, item.b24ui?.container] })">
117
117
  <RRadioGroupItem
118
118
  :id="item.id"
119
119
  :value="item.value"
120
- :disabled="item.disabled"
120
+ :disabled="item.disabled || disabled"
121
121
  data-slot="base"
122
- :class="b24ui.base({ class: [props.b24ui?.base, item.b24ui?.base], disabled: item.disabled })"
122
+ :class="b24ui.base({ class: [props.b24ui?.base, item.b24ui?.base], disabled: item.disabled || disabled })"
123
123
  >
124
124
  <RadioGroupIndicator data-slot="indicator" :class="b24ui.indicator({ class: [props.b24ui?.indicator, item.b24ui?.indicator] })" />
125
125
  </RRadioGroupItem>
@@ -135,7 +135,7 @@ function onUpdate(value) {
135
135
  v-if="item.label || !!slots.label"
136
136
  :for="item.id"
137
137
  data-slot="label"
138
- :class="b24ui.label({ class: [props.b24ui?.label, item.b24ui?.label] })"
138
+ :class="b24ui.label({ class: [props.b24ui?.label, item.b24ui?.label], disabled: item.disabled || disabled })"
139
139
  >
140
140
  <slot name="label" :item="item" :model-value="modelValue">
141
141
  {{ item.label }}
@@ -144,7 +144,7 @@ function onUpdate(value) {
144
144
  <p
145
145
  v-if="item.description || !!slots.description"
146
146
  data-slot="description"
147
- :class="b24ui.description({ class: [props.b24ui?.description, item.b24ui?.description] })"
147
+ :class="b24ui.description({ class: [props.b24ui?.description, item.b24ui?.description], disabled: item.disabled || disabled })"
148
148
  >
149
149
  <slot name="description" :item="item" :model-value="modelValue">
150
150
  {{ item.description }}
@@ -74,7 +74,9 @@ const tooltipProps = toRef(() => defu(typeof props.tooltip === "boolean" ? {} :
74
74
  const { t } = useLocale();
75
75
  const { open } = useContentSearch();
76
76
  const appConfig = useAppConfig();
77
- const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.contentSearchButton || {} })());
77
+ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.contentSearchButton || {} })({
78
+ collapsed: props.collapsed
79
+ }));
78
80
  </script>
79
81
 
80
82
  <template>
@@ -85,7 +87,6 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.content
85
87
  v-bind="{
86
88
  ...buttonProps,
87
89
  ...collapsed ? {
88
- 'label': void 0,
89
90
  'aria-label': label || t('contentSearchButton.label')
90
91
  } : {
91
92
  color: 'air-secondary-no-accent'
@@ -101,7 +102,7 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.content
101
102
  <slot :name="name" v-bind="slotData" />
102
103
  </template>
103
104
 
104
- <template v-if="!collapsed" #trailing="{ b24ui: b24uiProxy }">
105
+ <template #trailing="{ b24ui: b24uiProxy }">
105
106
  <div data-slot="trailing" :class="b24ui.trailing({ class: props.b24ui?.trailing })">
106
107
  <slot name="trailing" :b24ui="b24uiProxy">
107
108
  <template v-if="kbds?.length">
@@ -27,6 +27,10 @@ export interface LinkProps extends Partial<Omit<InertiaLinkProps, 'href' | 'onCl
27
27
  * A rel attribute value to apply on the link. Defaults to "noopener noreferrer" for external links.
28
28
  */
29
29
  rel?: 'noopener' | 'noreferrer' | 'nofollow' | 'sponsored' | 'ugc' | (string & {}) | null;
30
+ /**
31
+ * If set to true, no rel attribute will be added to the link
32
+ */
33
+ noRel?: boolean;
30
34
  /**
31
35
  * Value passed to the attribute `aria-current` when the link is exact active.
32
36
  *
@@ -61,8 +65,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<LinkPr
61
65
  as: any;
62
66
  type: "reset" | "submit" | "button";
63
67
  active: boolean;
64
- activeClass: string;
65
- inactiveClass: string;
68
+ ariaCurrentValue: "page" | "step" | "location" | "date" | "time" | "true" | "false";
66
69
  isAction: boolean;
67
70
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, LinkSlots>;
68
71
  declare const _default: typeof __VLS_export;
@@ -11,22 +11,24 @@ import { usePage } from "@inertiajs/vue3";
11
11
  import { hasProtocol } from "ufo";
12
12
  import { useAppConfig } from "#imports";
13
13
  import { tv } from "../../utils/tv";
14
- import B24LinkBase from "./../../components/LinkBase.vue";
14
+ import { mergeClasses } from "../../utils";
15
+ import B24LinkBase from "../../components/LinkBase.vue";
15
16
  defineOptions({ inheritAttrs: false });
16
17
  const props = defineProps({
17
18
  as: { type: null, required: false, default: "button" },
18
- activeClass: { type: String, required: false, default: "" },
19
+ activeClass: { type: String, required: false },
19
20
  to: { type: String, required: false },
20
21
  href: { type: String, required: false },
21
22
  external: { type: Boolean, required: false },
22
23
  target: { type: [String, Object, null], required: false },
23
24
  rel: { type: [String, Object, null], required: false },
24
- ariaCurrentValue: { type: String, required: false },
25
+ noRel: { type: Boolean, required: false },
26
+ ariaCurrentValue: { type: String, required: false, default: "page" },
25
27
  type: { type: null, required: false, default: "button" },
26
28
  disabled: { type: Boolean, required: false },
27
29
  active: { type: Boolean, required: false, default: void 0 },
28
30
  exact: { type: Boolean, required: false },
29
- inactiveClass: { type: String, required: false, default: "" },
31
+ inactiveClass: { type: String, required: false },
30
32
  custom: { type: Boolean, required: false },
31
33
  isAction: { type: Boolean, required: false, default: false },
32
34
  raw: { type: Boolean, required: false },
@@ -61,14 +63,14 @@ const props = defineProps({
61
63
  defineSlots();
62
64
  const page = usePage();
63
65
  const appConfig = useAppConfig();
64
- const routerLinkProps = useForwardProps(reactiveOmit(props, "as", "type", "disabled", "active", "exact", "activeClass", "inactiveClass", "to", "href", "raw", "custom", "class"));
66
+ const routerLinkProps = useForwardProps(reactiveOmit(props, "as", "type", "disabled", "active", "exact", "activeClass", "inactiveClass", "to", "href", "raw", "custom", "class", "noRel"));
65
67
  const b24ui = computed(() => tv({
66
68
  extend: tv(theme),
67
69
  ...defu({
68
70
  variants: {
69
71
  active: {
70
- true: props.activeClass,
71
- false: props.inactiveClass
72
+ true: mergeClasses(appConfig.b24ui?.link?.variants?.active?.true, props.activeClass),
73
+ false: mergeClasses(appConfig.b24ui?.link?.variants?.active?.false, props.inactiveClass)
72
74
  }
73
75
  }
74
76
  }, appConfig.b24ui?.link || {})
@@ -86,6 +88,19 @@ const isExternal = computed(() => {
86
88
  }
87
89
  return typeof href.value === "string" && hasProtocol(href.value, { acceptRelative: true });
88
90
  });
91
+ const hasTarget = computed(() => !!props.target && props.target !== "_self");
92
+ const rel = computed(() => {
93
+ if (props.noRel) {
94
+ return null;
95
+ }
96
+ if (props.rel !== void 0) {
97
+ return props.rel || null;
98
+ }
99
+ if (isExternal.value || hasTarget.value) {
100
+ return "noopener noreferrer";
101
+ }
102
+ return null;
103
+ });
89
104
  const isLinkActive = computed(() => {
90
105
  if (props.active !== void 0) {
91
106
  return props.active;
@@ -125,6 +140,8 @@ const linkClass = computed(() => {
125
140
  type,
126
141
  disabled,
127
142
  href,
143
+ rel,
144
+ target,
128
145
  active: isLinkActive,
129
146
  isExternal
130
147
  }"
@@ -139,6 +156,8 @@ const linkClass = computed(() => {
139
156
  type,
140
157
  disabled,
141
158
  href,
159
+ rel,
160
+ target,
142
161
  isExternal
143
162
  }"
144
163
  :class="linkClass"