@bitrix24/b24ui-nuxt 0.4.10 → 0.5.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/.nuxt/b24ui/collapsible.ts +6 -0
- package/.nuxt/b24ui/index.ts +2 -0
- package/.nuxt/b24ui/navigation-menu.ts +312 -0
- package/.nuxt/b24ui/sidebar-body.ts +1 -1
- package/.nuxt/b24ui/sidebar-footer.ts +1 -1
- package/.nuxt/b24ui/sidebar-header.ts +1 -1
- package/.nuxt/b24ui/sidebar-heading.ts +1 -1
- package/.nuxt/b24ui/sidebar-section.ts +1 -1
- package/cli/package.json +1 -1
- package/dist/meta.cjs +9778 -588
- package/dist/meta.d.cts +9778 -588
- package/dist/meta.d.mts +9778 -588
- package/dist/meta.d.ts +9778 -588
- package/dist/meta.mjs +9778 -588
- package/dist/module.cjs +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/components/Collapsible.vue +56 -0
- package/dist/runtime/components/DropdownMenu.vue +3 -1
- package/dist/runtime/components/Form.vue +21 -1
- package/dist/runtime/components/FormField.vue +5 -0
- package/dist/runtime/components/Navbar.vue +1 -2
- package/dist/runtime/components/NavbarDivider.vue +1 -2
- package/dist/runtime/components/NavbarSection.vue +1 -2
- package/dist/runtime/components/NavbarSpacer.vue +1 -2
- package/dist/runtime/components/NavigationMenu.vue +345 -0
- package/dist/runtime/components/Sidebar.vue +1 -2
- package/dist/runtime/components/SidebarFooter.vue +1 -2
- package/dist/runtime/components/SidebarHeader.vue +1 -2
- package/dist/runtime/components/SidebarHeading.vue +1 -2
- package/dist/runtime/components/SidebarLayout.vue +34 -8
- package/dist/runtime/components/SidebarSection.vue +1 -2
- package/dist/runtime/components/SidebarSpacer.vue +1 -2
- package/dist/runtime/components/StackedLayout.vue +1 -3
- package/dist/runtime/composables/defineLocale.js +1 -0
- package/dist/runtime/composables/defineShortcuts.js +1 -0
- package/dist/runtime/composables/useKbd.js +1 -1
- package/dist/runtime/composables/useLocale.js +2 -2
- package/dist/runtime/composables/useOverlay.js +1 -1
- package/dist/runtime/index.css +1 -1
- package/dist/runtime/types/form.d.ts +1 -3
- package/dist/runtime/types/index.d.ts +2 -0
- package/dist/runtime/types/index.js +2 -0
- package/dist/runtime/utils/form.d.ts +0 -4
- package/dist/runtime/utils/form.js +2 -47
- package/dist/runtime/utils/link.d.ts +8 -8
- package/dist/runtime/utils/tv.js +1 -1
- package/dist/runtime/vue/stubs.d.ts +1 -1
- package/dist/shared/{b24ui-nuxt._rviRWFf.mjs → b24ui-nuxt.Bj4fKDSa.mjs} +375 -4
- package/dist/shared/{b24ui-nuxt.CY35QViH.cjs → b24ui-nuxt.DHbGsmbj.cjs} +375 -4
- package/dist/unplugin.cjs +1 -1
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.cjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +6 -6
package/dist/module.cjs
CHANGED
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defu } from 'defu';
|
|
2
2
|
import { defineNuxtModule, createResolver, addVitePlugin, addPlugin, addComponentsDir, addImportsDir, hasNuxtModule, installModule } from '@nuxt/kit';
|
|
3
|
-
import { d as defaultOptions, a as getDefaultUiConfig, b as addTemplates } from './shared/b24ui-nuxt.
|
|
3
|
+
import { d as defaultOptions, a as getDefaultUiConfig, b as addTemplates } from './shared/b24ui-nuxt.Bj4fKDSa.mjs';
|
|
4
4
|
import 'node:url';
|
|
5
5
|
import 'scule';
|
|
6
6
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { CollapsibleRootProps, CollapsibleRootEmits } from 'reka-ui'
|
|
3
|
+
import type { AppConfig } from '@nuxt/schema'
|
|
4
|
+
import _appConfig from '#build/app.config'
|
|
5
|
+
import theme from '#build/b24ui/collapsible'
|
|
6
|
+
import { tv } from '../utils/tv'
|
|
7
|
+
|
|
8
|
+
const appConfigCollapsible = _appConfig as AppConfig & { b24ui: { collapsible: Partial<typeof theme> } }
|
|
9
|
+
|
|
10
|
+
const collapsible = tv({ extend: tv(theme), ...(appConfigCollapsible.b24ui?.collapsible || {}) })
|
|
11
|
+
|
|
12
|
+
export interface CollapsibleProps extends Pick<CollapsibleRootProps, 'defaultOpen' | 'open' | 'disabled' | 'unmountOnHide'> {
|
|
13
|
+
/**
|
|
14
|
+
* The element or component this component should render as.
|
|
15
|
+
* @defaultValue 'div'
|
|
16
|
+
*/
|
|
17
|
+
as?: any
|
|
18
|
+
class?: any
|
|
19
|
+
b24ui?: Partial<typeof collapsible.slots>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface CollapsibleEmits extends CollapsibleRootEmits {}
|
|
23
|
+
|
|
24
|
+
export interface CollapsibleSlots {
|
|
25
|
+
default(props: { open: boolean }): any
|
|
26
|
+
content(props?: {}): any
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<script setup lang="ts">
|
|
31
|
+
import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent, useForwardPropsEmits } from 'reka-ui'
|
|
32
|
+
import { reactivePick } from '@vueuse/core'
|
|
33
|
+
|
|
34
|
+
const props = withDefaults(defineProps<CollapsibleProps>(), {
|
|
35
|
+
unmountOnHide: true
|
|
36
|
+
})
|
|
37
|
+
const emits = defineEmits<CollapsibleEmits>()
|
|
38
|
+
const slots = defineSlots<CollapsibleSlots>()
|
|
39
|
+
|
|
40
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen', 'open', 'disabled', 'unmountOnHide'), emits)
|
|
41
|
+
|
|
42
|
+
// eslint-disable-next-line vue/no-dupe-keys
|
|
43
|
+
const b24ui = collapsible()
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<template>
|
|
47
|
+
<CollapsibleRoot v-slot="{ open }" v-bind="rootProps" :class="b24ui.root({ class: [props.class, props.b24ui?.root] })">
|
|
48
|
+
<CollapsibleTrigger v-if="!!slots.default" as-child>
|
|
49
|
+
<slot :open="open" />
|
|
50
|
+
</CollapsibleTrigger>
|
|
51
|
+
|
|
52
|
+
<CollapsibleContent :class="b24ui.content({ class: props.b24ui?.content })">
|
|
53
|
+
<slot name="content" />
|
|
54
|
+
</CollapsibleContent>
|
|
55
|
+
</CollapsibleRoot>
|
|
56
|
+
</template>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!-- eslint-disable vue/block-tag-newline -->
|
|
1
2
|
<script lang="ts">
|
|
2
3
|
import type { VariantProps } from 'tailwind-variants'
|
|
3
4
|
import type { DropdownMenuRootProps, DropdownMenuRootEmits, DropdownMenuContentProps, DropdownMenuArrowProps } from 'reka-ui'
|
|
@@ -99,6 +100,7 @@ export type DropdownMenuSlots<T extends { slot?: string }> = {
|
|
|
99
100
|
'item-label': SlotProps<T>
|
|
100
101
|
'item-trailing': SlotProps<T>
|
|
101
102
|
} & DynamicSlots<T, SlotProps<T>>
|
|
103
|
+
|
|
102
104
|
</script>
|
|
103
105
|
|
|
104
106
|
<script setup lang="ts" generic="T extends DropdownMenuItem">
|
|
@@ -145,7 +147,7 @@ const b24ui = computed(() => dropdownMenu({
|
|
|
145
147
|
:checked-icon="checkedIcon"
|
|
146
148
|
:external-icon="externalIcon"
|
|
147
149
|
>
|
|
148
|
-
<template v-for="(_, name) in proxySlots" #[name]="slotData
|
|
150
|
+
<template v-for="(_, name) in proxySlots" #[name]="slotData">
|
|
149
151
|
<slot :name="name" v-bind="slotData" />
|
|
150
152
|
</template>
|
|
151
153
|
|
|
@@ -12,14 +12,34 @@ const form = tv({ extend: tv(theme), ...(appConfigForm.b24ui?.form || {}) })
|
|
|
12
12
|
|
|
13
13
|
export interface FormProps<T extends object> {
|
|
14
14
|
id?: string | number
|
|
15
|
+
/** Schema to validate the form state. Supports Standard Schema objects, Yup, Joi, and Superstructs. */
|
|
15
16
|
schema?: FormSchema<T>
|
|
17
|
+
/** An object representing the current state of the form. */
|
|
16
18
|
state: Partial<T>
|
|
19
|
+
/**
|
|
20
|
+
* Custom validation function to validate the form state.
|
|
21
|
+
* @param state - The current state of the form.
|
|
22
|
+
* @returns A promise that resolves to an array of FormError objects, or an array of FormError objects directly.
|
|
23
|
+
*/
|
|
17
24
|
validate?: (state: Partial<T>) => Promise<FormError[]> | FormError[]
|
|
25
|
+
/**
|
|
26
|
+
* The list of input events that trigger the form validation.
|
|
27
|
+
* @defaultValue `['blur', 'change', 'input']`
|
|
28
|
+
*/
|
|
18
29
|
validateOn?: FormInputEvents[]
|
|
30
|
+
/** Disable all inputs inside the form. */
|
|
19
31
|
disabled?: boolean
|
|
32
|
+
/**
|
|
33
|
+
* Delay in milliseconds before validating the form on input events.
|
|
34
|
+
* @defaultValue `300`
|
|
35
|
+
*/
|
|
20
36
|
validateOnInputDelay?: number
|
|
21
|
-
|
|
37
|
+
/**
|
|
38
|
+
* If true, schema transformations will be applied to the state on submit.
|
|
39
|
+
* @defaultValue `true`
|
|
40
|
+
*/
|
|
22
41
|
transform?: boolean
|
|
42
|
+
class?: any
|
|
23
43
|
onSubmit?: ((event: FormSubmitEvent<T>) => void | Promise<void>) | (() => void | Promise<void>)
|
|
24
44
|
}
|
|
25
45
|
|
|
@@ -34,7 +34,12 @@ export interface FormFieldProps {
|
|
|
34
34
|
* @defaultValue false
|
|
35
35
|
*/
|
|
36
36
|
required?: boolean
|
|
37
|
+
/** If true, validation on input will be active immediately instead of waiting for a blur event. */
|
|
37
38
|
eagerValidation?: boolean
|
|
39
|
+
/**
|
|
40
|
+
* Delay in milliseconds before validating the form on input events.
|
|
41
|
+
* @defaultValue `300`
|
|
42
|
+
*/
|
|
38
43
|
validateOnInputDelay?: number
|
|
39
44
|
class?: any
|
|
40
45
|
b24ui?: Partial<typeof formField.slots>
|
|
@@ -24,7 +24,6 @@ export interface NavbarSlots {
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
-
import { computed } from 'vue'
|
|
28
27
|
import { Primitive } from 'reka-ui'
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(defineProps<NavbarProps>(), {
|
|
@@ -33,7 +32,7 @@ const props = withDefaults(defineProps<NavbarProps>(), {
|
|
|
33
32
|
defineSlots<NavbarSlots>()
|
|
34
33
|
|
|
35
34
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
36
|
-
const b24ui =
|
|
35
|
+
const b24ui = navbar()
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<template>
|
|
@@ -24,7 +24,6 @@ export interface NavbarDividerSlots {
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
-
import { computed } from 'vue'
|
|
28
27
|
import { Primitive } from 'reka-ui'
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(defineProps<NavbarDividerProps>(), {
|
|
@@ -33,7 +32,7 @@ const props = withDefaults(defineProps<NavbarDividerProps>(), {
|
|
|
33
32
|
defineSlots<NavbarDividerSlots>()
|
|
34
33
|
|
|
35
34
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
36
|
-
const b24ui =
|
|
35
|
+
const b24ui = navbarDivider()
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<template>
|
|
@@ -24,7 +24,6 @@ export interface NavbarSectionSlots {
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
-
import { computed } from 'vue'
|
|
28
27
|
import { Primitive } from 'reka-ui'
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(defineProps<NavbarSectionProps>(), {
|
|
@@ -33,7 +32,7 @@ const props = withDefaults(defineProps<NavbarSectionProps>(), {
|
|
|
33
32
|
defineSlots<NavbarSectionSlots>()
|
|
34
33
|
|
|
35
34
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
36
|
-
const b24ui =
|
|
35
|
+
const b24ui = navbarSection()
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<template>
|
|
@@ -24,7 +24,6 @@ export interface NavbarSpacerSlots {
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
-
import { computed } from 'vue'
|
|
28
27
|
import { Primitive } from 'reka-ui'
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(defineProps<NavbarSpacerProps>(), {
|
|
@@ -33,7 +32,7 @@ const props = withDefaults(defineProps<NavbarSpacerProps>(), {
|
|
|
33
32
|
defineSlots<NavbarSpacerSlots>()
|
|
34
33
|
|
|
35
34
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
36
|
-
const b24ui =
|
|
35
|
+
const b24ui = navbarSpacer()
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<template>
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
<!-- eslint-disable vue/block-tag-newline -->
|
|
2
|
+
<script lang="ts">
|
|
3
|
+
import type { VariantProps } from 'tailwind-variants'
|
|
4
|
+
import type { NavigationMenuRootProps, NavigationMenuRootEmits, NavigationMenuContentProps, CollapsibleRootProps } from 'reka-ui'
|
|
5
|
+
import type { AppConfig } from '@nuxt/schema'
|
|
6
|
+
import _appConfig from '#build/app.config'
|
|
7
|
+
import theme from '#build/b24ui/navigation-menu'
|
|
8
|
+
import { tv } from '../utils/tv'
|
|
9
|
+
import type { AvatarProps, BadgeProps, LinkProps, IconComponent } from '../types'
|
|
10
|
+
import type { DynamicSlots, MaybeArrayOfArray, MaybeArrayOfArrayItem, PartialString } from '../types/utils'
|
|
11
|
+
|
|
12
|
+
const appConfigNavigationMenu = _appConfig as AppConfig & { b24ui: { navigationMenu: Partial<typeof theme> } }
|
|
13
|
+
|
|
14
|
+
const navigationMenu = tv({ extend: tv(theme), ...(appConfigNavigationMenu.b24ui?.navigationMenu || {}) })
|
|
15
|
+
|
|
16
|
+
export interface NavigationMenuChildItem extends Omit<NavigationMenuItem, 'children' | 'type'> {
|
|
17
|
+
/** Description is only used when `orientation` is `horizontal`. */
|
|
18
|
+
description?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface NavigationMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'>, Pick<CollapsibleRootProps, 'defaultOpen' | 'open'> {
|
|
22
|
+
label?: string
|
|
23
|
+
/**
|
|
24
|
+
* @IconComponent
|
|
25
|
+
*/
|
|
26
|
+
icon?: IconComponent
|
|
27
|
+
avatar?: AvatarProps
|
|
28
|
+
/**
|
|
29
|
+
* Display a badge on the item.
|
|
30
|
+
* `{ size: 'sm', color: 'neutral', variant: 'outline' }`{lang="ts-type"}
|
|
31
|
+
*/
|
|
32
|
+
badge?: string | number | BadgeProps
|
|
33
|
+
/**
|
|
34
|
+
* @IconComponent
|
|
35
|
+
*/
|
|
36
|
+
trailingIcon?: IconComponent
|
|
37
|
+
/**
|
|
38
|
+
* The type of the item.
|
|
39
|
+
* The `label` type only works on `vertical` orientation.
|
|
40
|
+
* @defaultValue 'link'
|
|
41
|
+
*/
|
|
42
|
+
type?: 'label' | 'link'
|
|
43
|
+
slot?: string
|
|
44
|
+
value?: string
|
|
45
|
+
children?: NavigationMenuChildItem[]
|
|
46
|
+
onSelect?(e: Event): void
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type NavigationMenuVariants = VariantProps<typeof navigationMenu>
|
|
50
|
+
|
|
51
|
+
export interface NavigationMenuProps<T> extends Pick<NavigationMenuRootProps, 'modelValue' | 'defaultValue' | 'delayDuration' | 'disableClickTrigger' | 'disableHoverTrigger' | 'skipDelayDuration' | 'disablePointerLeaveClose' | 'unmountOnHide'> {
|
|
52
|
+
/**
|
|
53
|
+
* The element or component this component should render as.
|
|
54
|
+
* @defaultValue 'div'
|
|
55
|
+
*/
|
|
56
|
+
as?: any
|
|
57
|
+
/**
|
|
58
|
+
* The icon displayed to open the menu.
|
|
59
|
+
* @defaultValue icons.chevronDown
|
|
60
|
+
* @IconComponent
|
|
61
|
+
*/
|
|
62
|
+
trailingIcon?: IconComponent
|
|
63
|
+
/**
|
|
64
|
+
* The icon displayed when the item is an external link.
|
|
65
|
+
* Set to `false` to hide the external icon.
|
|
66
|
+
* @defaultValue icons.external
|
|
67
|
+
* @IconComponent
|
|
68
|
+
*/
|
|
69
|
+
externalIcon?: boolean | IconComponent
|
|
70
|
+
items?: T
|
|
71
|
+
/**
|
|
72
|
+
* @defaultValue 'primary'
|
|
73
|
+
*/
|
|
74
|
+
color?: NavigationMenuVariants['color']
|
|
75
|
+
/**
|
|
76
|
+
* @defaultValue 'pill'
|
|
77
|
+
*/
|
|
78
|
+
variant?: NavigationMenuVariants['variant']
|
|
79
|
+
/**
|
|
80
|
+
* The orientation of the menu.
|
|
81
|
+
* @defaultValue 'horizontal'
|
|
82
|
+
*/
|
|
83
|
+
orientation?: NavigationMenuRootProps['orientation']
|
|
84
|
+
/**
|
|
85
|
+
* Collapse the navigation menu to only show icons.
|
|
86
|
+
* Only works when `orientation` is `vertical`.
|
|
87
|
+
* @defaultValue false
|
|
88
|
+
*/
|
|
89
|
+
collapsed?: boolean
|
|
90
|
+
/** Display a line next to the active item. */
|
|
91
|
+
highlight?: boolean
|
|
92
|
+
/**
|
|
93
|
+
* @defaultValue 'primary'
|
|
94
|
+
*/
|
|
95
|
+
highlightColor?: NavigationMenuVariants['highlightColor']
|
|
96
|
+
/** The content of the menu. */
|
|
97
|
+
content?: Omit<NavigationMenuContentProps, 'as' | 'asChild' | 'forceMount'>
|
|
98
|
+
/**
|
|
99
|
+
* The orientation of the content.
|
|
100
|
+
* Only works when `orientation` is `horizontal`.
|
|
101
|
+
* @defaultValue 'horizontal'
|
|
102
|
+
*/
|
|
103
|
+
contentOrientation?: NavigationMenuVariants['contentOrientation']
|
|
104
|
+
/**
|
|
105
|
+
* Display an arrow alongside the menu.
|
|
106
|
+
* @defaultValue false
|
|
107
|
+
*/
|
|
108
|
+
arrow?: boolean
|
|
109
|
+
/**
|
|
110
|
+
* The key used to get the label from the item.
|
|
111
|
+
* @defaultValue 'label'
|
|
112
|
+
*/
|
|
113
|
+
labelKey?: string
|
|
114
|
+
class?: any
|
|
115
|
+
b24ui?: PartialString<typeof navigationMenu.slots>
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface NavigationMenuEmits extends NavigationMenuRootEmits {}
|
|
119
|
+
|
|
120
|
+
type SlotProps<T> = (props: { item: T, index: number, active?: boolean }) => any
|
|
121
|
+
|
|
122
|
+
export type NavigationMenuSlots<T extends { slot?: string }> = {
|
|
123
|
+
'item': SlotProps<T>
|
|
124
|
+
'item-leading': SlotProps<T>
|
|
125
|
+
'item-label': SlotProps<T>
|
|
126
|
+
'item-trailing': SlotProps<T>
|
|
127
|
+
'item-content': SlotProps<T>
|
|
128
|
+
} & DynamicSlots<T, SlotProps<T>>
|
|
129
|
+
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<NavigationMenuItem>">
|
|
133
|
+
import { computed, toRef } from 'vue'
|
|
134
|
+
import { NavigationMenuRoot, NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, useForwardPropsEmits } from 'reka-ui'
|
|
135
|
+
import { createReusableTemplate } from '@vueuse/core'
|
|
136
|
+
import { get } from '../utils'
|
|
137
|
+
import { pickLinkProps } from '../utils/link'
|
|
138
|
+
import icons from '../dictionary/icons'
|
|
139
|
+
import B24LinkBase from './LinkBase.vue'
|
|
140
|
+
import B24Link from './Link.vue'
|
|
141
|
+
import B24Avatar from './Avatar.vue'
|
|
142
|
+
import B24Badge from './Badge.vue'
|
|
143
|
+
import B24Collapsible from './Collapsible.vue'
|
|
144
|
+
|
|
145
|
+
const props = withDefaults(defineProps<NavigationMenuProps<I>>(), {
|
|
146
|
+
orientation: 'horizontal',
|
|
147
|
+
contentOrientation: 'horizontal',
|
|
148
|
+
externalIcon: true,
|
|
149
|
+
delayDuration: 0,
|
|
150
|
+
unmountOnHide: true,
|
|
151
|
+
labelKey: 'label'
|
|
152
|
+
})
|
|
153
|
+
const emits = defineEmits<NavigationMenuEmits>()
|
|
154
|
+
const slots = defineSlots<NavigationMenuSlots<T>>()
|
|
155
|
+
|
|
156
|
+
const rootProps = useForwardPropsEmits(computed(() => ({
|
|
157
|
+
as: props.as,
|
|
158
|
+
modelValue: props.modelValue,
|
|
159
|
+
defaultValue: props.defaultValue,
|
|
160
|
+
delayDuration: props.delayDuration,
|
|
161
|
+
skipDelayDuration: props.skipDelayDuration,
|
|
162
|
+
orientation: props.orientation,
|
|
163
|
+
disableClickTrigger: props.disableClickTrigger,
|
|
164
|
+
disableHoverTrigger: props.disableHoverTrigger,
|
|
165
|
+
disablePointerLeaveClose: props.disablePointerLeaveClose,
|
|
166
|
+
unmountOnHide: props.unmountOnHide
|
|
167
|
+
})), emits)
|
|
168
|
+
|
|
169
|
+
const contentProps = toRef(() => props.content)
|
|
170
|
+
|
|
171
|
+
const [DefineLinkTemplate, ReuseLinkTemplate] = createReusableTemplate<{ item: NavigationMenuItem, index: number, active?: boolean }>()
|
|
172
|
+
const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: NavigationMenuItem, index: number, level?: number }>({
|
|
173
|
+
props: {
|
|
174
|
+
item: Object,
|
|
175
|
+
index: Number,
|
|
176
|
+
level: Number
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
const b24ui = computed(() => navigationMenu({
|
|
181
|
+
orientation: props.orientation,
|
|
182
|
+
contentOrientation: props.contentOrientation,
|
|
183
|
+
collapsed: props.collapsed,
|
|
184
|
+
color: props.color,
|
|
185
|
+
variant: props.variant,
|
|
186
|
+
highlight: props.highlight,
|
|
187
|
+
highlightColor: props.highlightColor || props.color
|
|
188
|
+
}))
|
|
189
|
+
|
|
190
|
+
const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]) ? props.items : [props.items]) as T[][] : [])
|
|
191
|
+
</script>
|
|
192
|
+
|
|
193
|
+
<template>
|
|
194
|
+
<DefineLinkTemplate v-slot="{ item, active, index }">
|
|
195
|
+
<slot :name="item.slot || 'item'" :item="(item as T)" :index="index">
|
|
196
|
+
<slot :name="item.slot ? `${item.slot}-leading` : 'item-leading'" :item="(item as T)" :active="active" :index="index">
|
|
197
|
+
<Component
|
|
198
|
+
:is="item.icon"
|
|
199
|
+
v-if="item.icon"
|
|
200
|
+
:class="b24ui.linkLeadingIcon({ class: props.b24ui?.linkLeadingIcon, active, disabled: !!item.disabled })"
|
|
201
|
+
/>
|
|
202
|
+
<B24Avatar v-else-if="item.avatar" :size="((props.b24ui?.linkLeadingAvatarSize || b24ui.linkLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="b24ui.linkLeadingAvatar({ class: props.b24ui?.linkLeadingAvatar, active, disabled: !!item.disabled })" />
|
|
203
|
+
</slot>
|
|
204
|
+
|
|
205
|
+
<span
|
|
206
|
+
v-if="(!collapsed || orientation !== 'vertical') && (get(item, props.labelKey as string) || !!slots[item.slot ? `${item.slot}-label` : 'item-label'])"
|
|
207
|
+
:class="b24ui.linkLabel({ class: props.b24ui?.linkLabel, active })"
|
|
208
|
+
>
|
|
209
|
+
<slot :name="item.slot ? `${item.slot}-label` : 'item-label'" :item="(item as T)" :active="active" :index="index">
|
|
210
|
+
{{ get(item, props.labelKey as string) }}
|
|
211
|
+
</slot>
|
|
212
|
+
|
|
213
|
+
<Component
|
|
214
|
+
:is="typeof externalIcon !== 'boolean' ? externalIcon : icons.external"
|
|
215
|
+
v-if="item.target === '_blank' && externalIcon !== false"
|
|
216
|
+
:class="b24ui.linkLabelExternalIcon({ class: props.b24ui?.linkLabelExternalIcon, active })"
|
|
217
|
+
/>
|
|
218
|
+
</span>
|
|
219
|
+
|
|
220
|
+
<span v-if="(!collapsed || orientation !== 'vertical') && (item.badge || (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'])" :class="b24ui.linkTrailing({ class: props.b24ui?.linkTrailing })">
|
|
221
|
+
<slot :name="item.slot ? `${item.slot}-trailing` : 'item-trailing'" :item="(item as T)" :active="active" :index="index">
|
|
222
|
+
<B24Badge
|
|
223
|
+
v-if="item.badge"
|
|
224
|
+
color="default"
|
|
225
|
+
depth="normal"
|
|
226
|
+
:use-fill="false"
|
|
227
|
+
:size="((props.b24ui?.linkTrailingBadgeSize || b24ui.linkTrailingBadgeSize()) as BadgeProps['size'])"
|
|
228
|
+
v-bind="(typeof item.badge === 'string' || typeof item.badge === 'number') ? { label: item.badge } : item.badge"
|
|
229
|
+
:class="b24ui.linkTrailingBadge({ class: props.b24ui?.linkTrailingBadge })"
|
|
230
|
+
/>
|
|
231
|
+
|
|
232
|
+
<Component
|
|
233
|
+
:is="item.trailingIcon || trailingIcon || icons.chevronDown"
|
|
234
|
+
v-if="(orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content'])) || (orientation === 'vertical' && item.children?.length)"
|
|
235
|
+
:class="b24ui.linkTrailingIcon({ class: props.b24ui?.linkTrailingIcon, active })"
|
|
236
|
+
/>
|
|
237
|
+
<Component
|
|
238
|
+
:is="item.trailingIcon"
|
|
239
|
+
v-else-if="item.trailingIcon"
|
|
240
|
+
:class="b24ui.linkTrailingIcon({ class: props.b24ui?.linkTrailingIcon, active })"
|
|
241
|
+
/>
|
|
242
|
+
</slot>
|
|
243
|
+
</span>
|
|
244
|
+
</slot>
|
|
245
|
+
</DefineLinkTemplate>
|
|
246
|
+
|
|
247
|
+
<DefineItemTemplate v-slot="{ item, index, level = 0 }">
|
|
248
|
+
<component
|
|
249
|
+
:is="(orientation === 'vertical' && item.children?.length && !collapsed) ? B24Collapsible : NavigationMenuItem"
|
|
250
|
+
as="li"
|
|
251
|
+
:value="item.value || String(index)"
|
|
252
|
+
:default-open="item.defaultOpen"
|
|
253
|
+
:unmount-on-hide="(orientation === 'vertical' && item.children?.length && !collapsed) ? unmountOnHide : undefined"
|
|
254
|
+
:open="item.open"
|
|
255
|
+
>
|
|
256
|
+
<div v-if="orientation === 'vertical' && item.type === 'label'" :class="b24ui.label({ class: props.b24ui?.label })">
|
|
257
|
+
<ReuseLinkTemplate :item="(item as T)" :index="index" />
|
|
258
|
+
</div>
|
|
259
|
+
<B24Link v-else-if="item.type !== 'label'" v-slot="{ active, ...slotProps }" v-bind="(orientation === 'vertical' && item.children?.length && !collapsed) ? {} : pickLinkProps(item as Omit<NavigationMenuItem, 'type'>)" custom>
|
|
260
|
+
<component
|
|
261
|
+
:is="(orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content'])) ? NavigationMenuTrigger : NavigationMenuLink"
|
|
262
|
+
as-child
|
|
263
|
+
:active="active || item.active"
|
|
264
|
+
:disabled="item.disabled"
|
|
265
|
+
@select="item.onSelect"
|
|
266
|
+
>
|
|
267
|
+
<B24LinkBase v-bind="slotProps" :class="b24ui.link({ class: [props.b24ui?.link, item.class], active: active || item.active, disabled: !!item.disabled, level: orientation === 'horizontal' || level > 0 })">
|
|
268
|
+
<ReuseLinkTemplate :item="(item as T)" :active="active || item.active" :index="index" />
|
|
269
|
+
</B24LinkBase>
|
|
270
|
+
</component>
|
|
271
|
+
|
|
272
|
+
<NavigationMenuContent v-if="orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content'])" v-bind="contentProps" :class="b24ui.content({ class: props.b24ui?.content })">
|
|
273
|
+
<slot :name="item.slot ? `${item.slot}-content` : 'item-content'" :item="(item as T)" :active="active" :index="index">
|
|
274
|
+
<ul :class="b24ui.childList({ class: props.b24ui?.childList })">
|
|
275
|
+
<li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="b24ui.childItem({ class: props.b24ui?.childItem })">
|
|
276
|
+
<B24Link v-slot="{ active: childActive, ...childSlotProps }" v-bind="pickLinkProps(childItem)" custom>
|
|
277
|
+
<NavigationMenuLink as-child :active="childActive" @select="childItem.onSelect">
|
|
278
|
+
<B24LinkBase v-bind="childSlotProps" :class="b24ui.childLink({ class: [props.b24ui?.childLink, childItem.class], active: childActive })">
|
|
279
|
+
<Component
|
|
280
|
+
:is="childItem.icon"
|
|
281
|
+
v-if="childItem.icon"
|
|
282
|
+
:class="b24ui.childLinkIcon({ class: props.b24ui?.childLinkIcon, active: childActive })"
|
|
283
|
+
/>
|
|
284
|
+
|
|
285
|
+
<div :class="b24ui.childLinkWrapper({ class: props.b24ui?.childLinkWrapper })">
|
|
286
|
+
<p :class="b24ui.childLinkLabel({ class: props.b24ui?.childLinkLabel, active: childActive })">
|
|
287
|
+
{{ get(childItem, props.labelKey as string) }}
|
|
288
|
+
|
|
289
|
+
<Component
|
|
290
|
+
:is="typeof externalIcon === 'string' ? externalIcon : icons.external"
|
|
291
|
+
v-if="childItem.target === '_blank' && externalIcon !== false"
|
|
292
|
+
:class="b24ui.childLinkLabelExternalIcon({ class: props.b24ui?.childLinkLabelExternalIcon, active: childActive })"
|
|
293
|
+
/>
|
|
294
|
+
</p>
|
|
295
|
+
<p v-if="childItem.description" :class="b24ui.childLinkDescription({ class: props.b24ui?.childLinkDescription, active: childActive })">
|
|
296
|
+
{{ childItem.description }}
|
|
297
|
+
</p>
|
|
298
|
+
</div>
|
|
299
|
+
</B24LinkBase>
|
|
300
|
+
</NavigationMenuLink>
|
|
301
|
+
</B24Link>
|
|
302
|
+
</li>
|
|
303
|
+
</ul>
|
|
304
|
+
</slot>
|
|
305
|
+
</NavigationMenuContent>
|
|
306
|
+
</B24Link>
|
|
307
|
+
|
|
308
|
+
<template v-if="orientation === 'vertical' && item.children?.length && !collapsed" #content>
|
|
309
|
+
<ul :class="b24ui.childList({ class: props.b24ui?.childList })">
|
|
310
|
+
<ReuseItemTemplate
|
|
311
|
+
v-for="(childItem, childIndex) in item.children"
|
|
312
|
+
:key="childIndex"
|
|
313
|
+
:item="childItem"
|
|
314
|
+
:index="childIndex"
|
|
315
|
+
:level="level + 1"
|
|
316
|
+
:class="b24ui.childItem({ class: props.b24ui?.childItem })"
|
|
317
|
+
/>
|
|
318
|
+
</ul>
|
|
319
|
+
</template>
|
|
320
|
+
</component>
|
|
321
|
+
</DefineItemTemplate>
|
|
322
|
+
|
|
323
|
+
<NavigationMenuRoot
|
|
324
|
+
v-bind="rootProps"
|
|
325
|
+
:data-collapsed="collapsed"
|
|
326
|
+
:class="b24ui.root({ class: [props.class, props.b24ui?.root] })"
|
|
327
|
+
data-slot="section"
|
|
328
|
+
>
|
|
329
|
+
<template v-for="(list, listIndex) in lists" :key="`list-${listIndex}`">
|
|
330
|
+
<NavigationMenuList :class="b24ui.list({ class: props.b24ui?.list })">
|
|
331
|
+
<ReuseItemTemplate v-for="(item, index) in list" :key="`list-${listIndex}-${index}`" :item="item" :index="index" :class="b24ui.item({ class: props.b24ui?.item })" />
|
|
332
|
+
</NavigationMenuList>
|
|
333
|
+
|
|
334
|
+
<div v-if="orientation === 'vertical' && listIndex < lists.length - 1" :class="b24ui.separator({ class: props.b24ui?.separator })" />
|
|
335
|
+
</template>
|
|
336
|
+
|
|
337
|
+
<div v-if="orientation === 'horizontal'" :class="b24ui.viewportWrapper({ class: props.b24ui?.viewportWrapper })">
|
|
338
|
+
<NavigationMenuIndicator v-if="arrow" :class="b24ui.indicator({ class: props.b24ui?.indicator })">
|
|
339
|
+
<div :class="b24ui.arrow({ class: props.b24ui?.arrow })" />
|
|
340
|
+
</NavigationMenuIndicator>
|
|
341
|
+
|
|
342
|
+
<NavigationMenuViewport :class="b24ui.viewport({ class: props.b24ui?.viewport })" />
|
|
343
|
+
</div>
|
|
344
|
+
</NavigationMenuRoot>
|
|
345
|
+
</template>
|
|
@@ -24,7 +24,6 @@ export interface SidebarSlots {
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
-
import { computed } from 'vue'
|
|
28
27
|
import { Primitive } from 'reka-ui'
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(defineProps<SidebarProps>(), {
|
|
@@ -33,7 +32,7 @@ const props = withDefaults(defineProps<SidebarProps>(), {
|
|
|
33
32
|
defineSlots<SidebarSlots>()
|
|
34
33
|
|
|
35
34
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
36
|
-
const b24ui =
|
|
35
|
+
const b24ui = sidebar()
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<template>
|
|
@@ -24,7 +24,6 @@ export interface SidebarFooterSlots {
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
-
import { computed } from 'vue'
|
|
28
27
|
import { Primitive } from 'reka-ui'
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(defineProps<SidebarFooterProps>(), {
|
|
@@ -33,7 +32,7 @@ const props = withDefaults(defineProps<SidebarFooterProps>(), {
|
|
|
33
32
|
defineSlots<SidebarFooterSlots>()
|
|
34
33
|
|
|
35
34
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
36
|
-
const b24ui =
|
|
35
|
+
const b24ui = sidebarFooter()
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<template>
|
|
@@ -24,7 +24,6 @@ export interface SidebarHeaderSlots {
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
-
import { computed } from 'vue'
|
|
28
27
|
import { Primitive } from 'reka-ui'
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(defineProps<SidebarHeaderProps>(), {
|
|
@@ -33,7 +32,7 @@ const props = withDefaults(defineProps<SidebarHeaderProps>(), {
|
|
|
33
32
|
defineSlots<SidebarHeaderSlots>()
|
|
34
33
|
|
|
35
34
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
36
|
-
const b24ui =
|
|
35
|
+
const b24ui = sidebarHeader()
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<template>
|
|
@@ -24,7 +24,6 @@ export interface SidebarHeadingSlots {
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
-
import { computed } from 'vue'
|
|
28
27
|
import { Primitive } from 'reka-ui'
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(defineProps<SidebarHeadingProps>(), {
|
|
@@ -33,7 +32,7 @@ const props = withDefaults(defineProps<SidebarHeadingProps>(), {
|
|
|
33
32
|
defineSlots<SidebarHeadingSlots>()
|
|
34
33
|
|
|
35
34
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
36
|
-
const b24ui =
|
|
35
|
+
const b24ui = sidebarHeading()
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<template>
|