sprintify-ui 0.4.11 → 0.5.3
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/sprintify-ui.es.js +11240 -11075
- package/dist/style.css +1 -1
- package/dist/types/src/components/BaseActionItem.vue.d.ts +7 -17
- package/dist/types/src/components/BaseActionItemButton.vue.d.ts +3 -3
- package/dist/types/src/components/BaseAutocomplete.vue.d.ts +1 -1
- package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +1 -1
- package/dist/types/src/components/BaseBelongsTo.vue.d.ts +1 -1
- package/dist/types/src/components/BaseBelongsToFetch.vue.d.ts +1 -1
- package/dist/types/src/components/BaseButtonGroup.vue.d.ts +1 -1
- package/dist/types/src/components/BaseColor.vue.d.ts +1 -1
- package/dist/types/src/components/BaseDataIterator.vue.d.ts +5 -4
- package/dist/types/src/components/BaseDataTable.vue.d.ts +8 -7
- package/dist/types/src/components/BaseDatePicker.vue.d.ts +9 -9
- package/dist/types/src/components/BaseDateSelect.vue.d.ts +1 -1
- package/dist/types/src/components/BaseDropdownAutocomplete.vue.d.ts +1 -1
- package/dist/types/src/components/BaseField.vue.d.ts +1 -1
- package/dist/types/src/components/BaseFieldI18n.vue.d.ts +1 -1
- package/dist/types/src/components/BaseHeader.vue.d.ts +2 -1
- package/dist/types/src/components/BaseInput.vue.d.ts +1 -1
- package/dist/types/src/components/BaseInputPercent.vue.d.ts +1 -1
- package/dist/types/src/components/BaseLayoutSidebarConfigurable.vue.d.ts +4 -3
- package/dist/types/src/components/BaseLayoutStacked.vue.d.ts +39 -7
- package/dist/types/src/components/BaseLayoutStackedConfigurable.vue.d.ts +20 -1
- package/dist/types/src/components/BaseMenu.vue.d.ts +7 -7
- package/dist/types/src/components/BaseMenuItem.vue.d.ts +9 -0
- package/dist/types/src/components/BaseNavbar.vue.d.ts +40 -8
- package/dist/types/src/components/BaseNavbarItem.vue.d.ts +10 -1
- package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +4 -4
- package/dist/types/src/components/BaseNavbarSideItem.vue.d.ts +1 -10
- package/dist/types/src/components/BaseNavbarSideItemContent.vue.d.ts +1 -1
- package/dist/types/src/components/BasePassword.vue.d.ts +1 -1
- package/dist/types/src/components/BaseRadioGroup.vue.d.ts +1 -1
- package/dist/types/src/components/BaseRichText.vue.d.ts +4 -4
- package/dist/types/src/components/BaseSelect.vue.d.ts +1 -1
- package/dist/types/src/components/BaseShortcut.vue.d.ts +1 -1
- package/dist/types/src/components/BaseStatistic.vue.d.ts +1 -1
- package/dist/types/src/components/BaseSwitch.vue.d.ts +1 -1
- package/dist/types/src/components/BaseSystemAlert.vue.d.ts +1 -1
- package/dist/types/src/components/BaseTableColumn.vue.d.ts +1 -1
- package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +1 -1
- package/dist/types/src/components/BaseTextarea.vue.d.ts +1 -1
- package/dist/types/src/types/ActionItem.d.ts +15 -0
- package/dist/types/src/types/index.d.ts +0 -26
- package/package.json +1 -1
- package/src/components/BaseActionItem.vue +25 -14
- package/src/components/BaseActionItemButton.vue +14 -16
- package/src/components/BaseDataIterator.stories.js +1 -1
- package/src/components/BaseDataIterator.vue +2 -2
- package/src/components/BaseDataTable.stories.js +1 -1
- package/src/components/BaseDataTable.vue +4 -4
- package/src/components/BaseHeader.vue +3 -2
- package/src/components/BaseLayoutNotificationDropdown.vue +7 -7
- package/src/components/BaseLayoutSidebarConfigurable.stories.js +25 -5
- package/src/components/BaseLayoutSidebarConfigurable.vue +23 -27
- package/src/components/BaseLayoutStacked.vue +38 -11
- package/src/components/BaseLayoutStackedConfigurable.stories.js +50 -1
- package/src/components/BaseLayoutStackedConfigurable.vue +22 -6
- package/src/components/BaseMenu.vue +3 -3
- package/src/components/BaseMenuItem.vue +39 -15
- package/src/components/BaseNavbar.stories.js +8 -7
- package/src/components/BaseNavbar.vue +81 -17
- package/src/components/BaseNavbarItem.vue +38 -7
- package/src/components/BaseNavbarItemContent.vue +37 -19
- package/src/components/BaseNavbarSideItem.vue +22 -17
- package/src/components/BaseNavbarSideItemContent.vue +1 -1
- package/src/components/BaseShortcut.vue +5 -3
- package/src/components/BaseSideNavigation.stories.js +1 -1
- package/src/components/BaseTabItem.vue +4 -9
- package/src/components/BaseTabs.stories.js +7 -3
- package/src/components/BaseTabs.vue +94 -5
- package/src/stories/List.stories.js +1 -1
- package/src/types/ActionItem.ts +16 -0
- package/src/types/index.ts +0 -29
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<BaseLayoutStacked
|
|
2
|
+
<BaseLayoutStacked
|
|
3
|
+
:size="size"
|
|
4
|
+
:dark="dark"
|
|
5
|
+
>
|
|
3
6
|
<template #navbar>
|
|
4
|
-
<div class="flex
|
|
7
|
+
<div class="flex w-full justify-between">
|
|
5
8
|
<!-- Left -->
|
|
6
9
|
|
|
7
|
-
<div class="flex
|
|
10
|
+
<div class="flex grow">
|
|
8
11
|
<!-- Logo -->
|
|
9
12
|
<RouterLink
|
|
10
13
|
to="/"
|
|
@@ -18,10 +21,11 @@
|
|
|
18
21
|
</RouterLink>
|
|
19
22
|
|
|
20
23
|
<!-- Links (desktop) -->
|
|
21
|
-
<div class="ml-10 hidden space-x-
|
|
24
|
+
<div class="ml-10 hidden space-x-2 md:flex">
|
|
22
25
|
<BaseNavbarItem
|
|
23
26
|
v-for="item in menu"
|
|
24
27
|
:key="item.label"
|
|
28
|
+
:size="size"
|
|
25
29
|
:item="item"
|
|
26
30
|
:dark="dark"
|
|
27
31
|
/>
|
|
@@ -29,12 +33,13 @@
|
|
|
29
33
|
</div>
|
|
30
34
|
|
|
31
35
|
<!-- Right -->
|
|
32
|
-
<div class="flex items-center md:ml-6">
|
|
36
|
+
<div class="flex shrink-0 items-center md:ml-6">
|
|
33
37
|
<!-- Notification dropdown -->
|
|
34
38
|
<BaseLayoutNotificationDropdown
|
|
35
39
|
v-if="notifications"
|
|
36
40
|
class="mr-4 md:mr-5"
|
|
37
41
|
:dark="dark"
|
|
42
|
+
:size="size"
|
|
38
43
|
:notifications-config="notifications"
|
|
39
44
|
@click="onNotificationClick"
|
|
40
45
|
@open="onNotificationOpen"
|
|
@@ -43,6 +48,7 @@
|
|
|
43
48
|
<!-- Profile dropdown -->
|
|
44
49
|
<BaseMenu
|
|
45
50
|
tw-menu="w-52"
|
|
51
|
+
:size="size == 'xs' ? 'xs' : 'sm'"
|
|
46
52
|
class="hidden md:block"
|
|
47
53
|
:items="userMenu"
|
|
48
54
|
>
|
|
@@ -54,6 +60,7 @@
|
|
|
54
60
|
<BaseAvatar
|
|
55
61
|
:class="dark ? 'text-white' : ''"
|
|
56
62
|
:user="user"
|
|
63
|
+
:size="size"
|
|
57
64
|
/>
|
|
58
65
|
</div>
|
|
59
66
|
</template>
|
|
@@ -107,7 +114,8 @@
|
|
|
107
114
|
<script lang="ts" setup>
|
|
108
115
|
import { User } from '@/types/User';
|
|
109
116
|
import { PropType } from 'vue';
|
|
110
|
-
import {
|
|
117
|
+
import { NotificationsConfig } from '../types';
|
|
118
|
+
import { ActionItem } from '@/types/ActionItem';
|
|
111
119
|
import BaseAvatar from './BaseAvatar.vue';
|
|
112
120
|
import BaseLayoutStacked from './BaseLayoutStacked.vue';
|
|
113
121
|
import BaseMenu from './BaseMenu.vue';
|
|
@@ -142,10 +150,18 @@ defineProps({
|
|
|
142
150
|
default: undefined,
|
|
143
151
|
type: Object as PropType<NotificationsConfig>,
|
|
144
152
|
},
|
|
153
|
+
navbar: {
|
|
154
|
+
default: undefined,
|
|
155
|
+
type: Object as PropType<Record<string, unknown>>,
|
|
156
|
+
},
|
|
145
157
|
dark: {
|
|
146
158
|
default: false,
|
|
147
159
|
type: Boolean,
|
|
148
160
|
},
|
|
161
|
+
size: {
|
|
162
|
+
default: 'md',
|
|
163
|
+
type: String as PropType<'xs' | 'sm' | 'md'>,
|
|
164
|
+
},
|
|
149
165
|
});
|
|
150
166
|
|
|
151
167
|
function onNotificationClick(notification: Notification) {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
:key="item.label + 'link'"
|
|
37
37
|
>
|
|
38
38
|
<div
|
|
39
|
-
v-if="item.line"
|
|
39
|
+
v-if="item.meta?.line"
|
|
40
40
|
class="-mx-1 my-1 flex h-px bg-slate-200"
|
|
41
41
|
/>
|
|
42
42
|
|
|
@@ -118,14 +118,14 @@
|
|
|
118
118
|
<script lang="ts" setup>
|
|
119
119
|
import { PropType } from 'vue';
|
|
120
120
|
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue';
|
|
121
|
-
import { MenuItemInterface } from '@/types';
|
|
122
121
|
import BaseMenuItem from './BaseMenuItem.vue';
|
|
123
122
|
import { twMerge } from 'tailwind-merge';
|
|
123
|
+
import { ActionItem } from '@/types/ActionItem';
|
|
124
124
|
|
|
125
125
|
const props = defineProps({
|
|
126
126
|
items: {
|
|
127
127
|
default: undefined,
|
|
128
|
-
type: Array as PropType<
|
|
128
|
+
type: Array as PropType<ActionItem[]>,
|
|
129
129
|
},
|
|
130
130
|
position: {
|
|
131
131
|
default: 'bottom-left',
|
|
@@ -1,29 +1,43 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
:style="buttonStyles"
|
|
4
|
-
class="rounded leading-tight"
|
|
4
|
+
class="rounded leading-tight hover:bg-slate-100"
|
|
5
5
|
:class="[active ? 'bg-slate-100' : 'bg-white']"
|
|
6
6
|
>
|
|
7
|
-
<div
|
|
7
|
+
<div
|
|
8
|
+
class="flex"
|
|
9
|
+
:class="[description ? 'items-start' : 'items-center']"
|
|
10
|
+
>
|
|
8
11
|
<BaseIcon
|
|
9
12
|
v-if="icon"
|
|
10
13
|
:icon="icon"
|
|
11
14
|
:class="[iconClasses]"
|
|
12
15
|
/>
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
<div class="grow">
|
|
17
|
+
<p :class="['font-medium', textClasses, textColor]">
|
|
18
|
+
{{ label }}
|
|
19
|
+
</p>
|
|
20
|
+
<p
|
|
21
|
+
v-if="description"
|
|
22
|
+
class="text-xs text-slate-500"
|
|
23
|
+
:class="[size == 'xs' ? 'mt-px' : 'mt-0.5']"
|
|
24
|
+
>
|
|
25
|
+
{{ description }}
|
|
26
|
+
</p>
|
|
27
|
+
</div>
|
|
25
28
|
</div>
|
|
26
29
|
</div>
|
|
30
|
+
<div
|
|
31
|
+
v-if="count"
|
|
32
|
+
class="relative -top-px ml-[5px]"
|
|
33
|
+
>
|
|
34
|
+
<BaseCounter
|
|
35
|
+
:count="count"
|
|
36
|
+
:max-digit="2"
|
|
37
|
+
:color="color"
|
|
38
|
+
:size="size"
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
27
41
|
</template>
|
|
28
42
|
|
|
29
43
|
<script lang="ts" setup>
|
|
@@ -36,6 +50,10 @@ const props = defineProps({
|
|
|
36
50
|
default: undefined,
|
|
37
51
|
type: String,
|
|
38
52
|
},
|
|
53
|
+
description: {
|
|
54
|
+
default: undefined,
|
|
55
|
+
type: String,
|
|
56
|
+
},
|
|
39
57
|
icon: {
|
|
40
58
|
default: undefined,
|
|
41
59
|
type: String,
|
|
@@ -134,7 +152,13 @@ const buttonStyles = computed((): StyleValue => {
|
|
|
134
152
|
});
|
|
135
153
|
|
|
136
154
|
const iconClasses = computed((): string => {
|
|
137
|
-
let baseClasses = ' w-5 h-5 shrink-0
|
|
155
|
+
let baseClasses = ' w-5 h-5 shrink-0 ';
|
|
156
|
+
|
|
157
|
+
if (props.size == 'xs') {
|
|
158
|
+
baseClasses += ' mr-2 ';
|
|
159
|
+
} else {
|
|
160
|
+
baseClasses += ' mr-3 ';
|
|
161
|
+
}
|
|
138
162
|
|
|
139
163
|
if (!props.active) {
|
|
140
164
|
baseClasses += ' opacity-70 ' + textColor.value;
|
|
@@ -6,7 +6,7 @@ import BaseMenu from './BaseMenu.vue';
|
|
|
6
6
|
import { Icon as BaseIcon } from '@iconify/vue';
|
|
7
7
|
|
|
8
8
|
export default {
|
|
9
|
-
title: '
|
|
9
|
+
title: 'Navigation/BaseNavbar',
|
|
10
10
|
component: BaseNavbar,
|
|
11
11
|
args: {},
|
|
12
12
|
parameters: {
|
|
@@ -56,7 +56,7 @@ const Template = (args) => ({
|
|
|
56
56
|
href: 'https://google.com',
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
|
-
line: true,
|
|
59
|
+
meta: { line: true },
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
label: 'Logout',
|
|
@@ -71,12 +71,12 @@ const Template = (args) => ({
|
|
|
71
71
|
<div class="sticky top-0 left-0 w-full shadow">
|
|
72
72
|
<BaseNavbar v-bind="args">
|
|
73
73
|
<template #navbar>
|
|
74
|
-
<div class="flex
|
|
74
|
+
<div class="flex w-full justify-between">
|
|
75
75
|
<!-- Left -->
|
|
76
76
|
|
|
77
|
-
<div class="flex justify-
|
|
77
|
+
<div class="flex justify-start grow">
|
|
78
78
|
<!-- Logo -->
|
|
79
|
-
<RouterLink to="/" class="flex flex-shrink-0
|
|
79
|
+
<RouterLink to="/" class="flex flex-shrink-0 items-center">
|
|
80
80
|
<img
|
|
81
81
|
class="block h-8 w-auto"
|
|
82
82
|
src="https://sprintify.witify.io/img/logo/logo-side.svg"
|
|
@@ -90,6 +90,7 @@ const Template = (args) => ({
|
|
|
90
90
|
v-for="item in menu"
|
|
91
91
|
:key="item.label"
|
|
92
92
|
:item="item"
|
|
93
|
+
class="flex"
|
|
93
94
|
item-class="flex"
|
|
94
95
|
/>
|
|
95
96
|
</div>
|
|
@@ -97,13 +98,13 @@ const Template = (args) => ({
|
|
|
97
98
|
|
|
98
99
|
<!-- Right -->
|
|
99
100
|
|
|
100
|
-
<div class="hidden md:ml-6 md:flex md:items-center">
|
|
101
|
+
<div class="hidden md:ml-6 md:flex md:items-center shrink-0">
|
|
101
102
|
<!-- Profile dropdown -->
|
|
102
103
|
<BaseMenu tw-menu="w-52" :items="userMenu">
|
|
103
104
|
<template #button="{ open }">
|
|
104
105
|
<div
|
|
105
106
|
class="flex rounded-full"
|
|
106
|
-
:class="[open ? 'bg-slate-700 ring-
|
|
107
|
+
:class="[open ? 'bg-slate-700 ring-4 ring-slate-200' : '']"
|
|
107
108
|
>
|
|
108
109
|
<BaseAvatar :user="user" />
|
|
109
110
|
</div>
|
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<nav
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<nav :class="classInternal">
|
|
3
|
+
<BaseContainer size="7xl">
|
|
4
|
+
<div
|
|
5
|
+
:style="{
|
|
6
|
+
height: `${heightInner}px`,
|
|
7
|
+
}"
|
|
8
|
+
class="flex justify-between"
|
|
9
|
+
>
|
|
8
10
|
<!-- Navbar (desktop and mobile) -->
|
|
9
|
-
<div class="grow">
|
|
10
|
-
<slot
|
|
11
|
+
<div class="grow flex">
|
|
12
|
+
<slot
|
|
13
|
+
name="navbar"
|
|
14
|
+
:dark="dark"
|
|
15
|
+
:height="heightInner"
|
|
16
|
+
/>
|
|
11
17
|
</div>
|
|
12
18
|
|
|
13
19
|
<!-- Mobile Burger menu button -->
|
|
14
|
-
<div
|
|
20
|
+
<div
|
|
21
|
+
v-if="mobile"
|
|
22
|
+
class="-mr-2 flex items-center"
|
|
23
|
+
>
|
|
15
24
|
<button
|
|
16
25
|
type="button"
|
|
17
26
|
class="inline-flex items-center justify-center rounded-md p-2 focus:outline-none focus:ring-2 focus:ring-offset-2"
|
|
@@ -42,12 +51,13 @@
|
|
|
42
51
|
|
|
43
52
|
<!-- Mobile -->
|
|
44
53
|
<div
|
|
45
|
-
v-if="showMobileMenu"
|
|
46
|
-
class="absolute w-full
|
|
47
|
-
:class="
|
|
54
|
+
v-if="mobile && showMobileMenu"
|
|
55
|
+
class="absolute w-full"
|
|
56
|
+
:class="backgroundClass"
|
|
48
57
|
>
|
|
49
58
|
<slot
|
|
50
59
|
name="mobile"
|
|
60
|
+
:dark="dark"
|
|
51
61
|
:toggle-menu="toggleMenu"
|
|
52
62
|
:close-menu="closeMenu"
|
|
53
63
|
:open-menu="openMenu"
|
|
@@ -59,18 +69,71 @@
|
|
|
59
69
|
<script setup lang="ts">
|
|
60
70
|
import { Icon as BaseIcon } from '@iconify/vue';
|
|
61
71
|
import BaseContainer from './BaseContainer.vue';
|
|
72
|
+
import { twMerge } from 'tailwind-merge';
|
|
73
|
+
import { PropType } from 'vue';
|
|
74
|
+
import { useWindowSize } from '@vueuse/core';
|
|
62
75
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
defineOptions({
|
|
77
|
+
inheritAttrs: false,
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const props = defineProps({
|
|
68
81
|
dark: {
|
|
69
82
|
default: false,
|
|
70
83
|
type: Boolean,
|
|
71
84
|
},
|
|
85
|
+
height: {
|
|
86
|
+
default: undefined,
|
|
87
|
+
type: Number,
|
|
88
|
+
},
|
|
89
|
+
breakpoint: {
|
|
90
|
+
default: 768,
|
|
91
|
+
type: Number,
|
|
92
|
+
},
|
|
93
|
+
class: {
|
|
94
|
+
default: '',
|
|
95
|
+
type: [String, Array] as PropType<string | string[]>,
|
|
96
|
+
},
|
|
97
|
+
size: {
|
|
98
|
+
default: 'md',
|
|
99
|
+
type: String as PropType<'xs' | 'sm' | 'md'>,
|
|
100
|
+
},
|
|
72
101
|
});
|
|
73
102
|
|
|
103
|
+
const window = useWindowSize();
|
|
104
|
+
|
|
105
|
+
const mobile = computed(() => {
|
|
106
|
+
return window.width.value < props.breakpoint;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const heightInner = computed(() => {
|
|
110
|
+
if (props.height) {
|
|
111
|
+
return props.height;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (props.size == 'xs') {
|
|
115
|
+
return 48;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (props.size == 'sm') {
|
|
119
|
+
return 56;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return 64;
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const backgroundClass = computed(() => {
|
|
126
|
+
return props.dark ? 'bg-slate-900' : 'bg-white';
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const classInternal = computed(() => {
|
|
130
|
+
return twMerge(
|
|
131
|
+
'w-full',
|
|
132
|
+
backgroundClass.value,
|
|
133
|
+
props.class,
|
|
134
|
+
)
|
|
135
|
+
})
|
|
136
|
+
|
|
74
137
|
const showMobileMenu = ref(false);
|
|
75
138
|
|
|
76
139
|
function toggleMenu() {
|
|
@@ -88,4 +151,5 @@ function closeMenu() {
|
|
|
88
151
|
provide('toggleMenu', toggleMenu);
|
|
89
152
|
provide('openMenu', openMenu);
|
|
90
153
|
provide('closeMenu', closeMenu);
|
|
154
|
+
provide('navbar:height', heightInner);
|
|
91
155
|
</script>
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex">
|
|
2
|
+
<div class="flex group relative">
|
|
3
3
|
<BaseActionItem
|
|
4
|
-
:
|
|
5
|
-
:href="item.href"
|
|
6
|
-
:action="item.action"
|
|
7
|
-
:dark="dark"
|
|
4
|
+
:item="item"
|
|
8
5
|
class="flex w-full"
|
|
9
6
|
@click="onClick"
|
|
10
7
|
>
|
|
11
8
|
<template #default="{ active }">
|
|
12
9
|
<BaseNavbarItemContent
|
|
10
|
+
:size="size"
|
|
13
11
|
:label="item.label"
|
|
14
12
|
:icon="item.icon"
|
|
15
13
|
:active="active"
|
|
@@ -18,14 +16,41 @@
|
|
|
18
16
|
/>
|
|
19
17
|
</template>
|
|
20
18
|
</BaseActionItem>
|
|
19
|
+
<div
|
|
20
|
+
v-if="item.actions && item.actions.length"
|
|
21
|
+
class="absolute ring-1 ring-black ring-opacity-10 shadow-lg rounded-md invisible p-1 left-0 bg-white w-56 duration-100 opacity-0 translate-y-1 || group-hover:visible group-hover:opacity-100 group-hover:translate-y-0"
|
|
22
|
+
:style="{
|
|
23
|
+
top: `${height - 3}px`,
|
|
24
|
+
}"
|
|
25
|
+
>
|
|
26
|
+
<div class="space-y-px">
|
|
27
|
+
<div
|
|
28
|
+
v-for="subItem in item.actions"
|
|
29
|
+
:key="subItem.label"
|
|
30
|
+
>
|
|
31
|
+
<BaseActionItem
|
|
32
|
+
:item="subItem"
|
|
33
|
+
>
|
|
34
|
+
<BaseMenuItem
|
|
35
|
+
:size="size == 'xs' ? 'xs' : 'sm'"
|
|
36
|
+
:label="subItem.label"
|
|
37
|
+
:count="subItem.count"
|
|
38
|
+
:icon="subItem.icon"
|
|
39
|
+
:description="subItem.description"
|
|
40
|
+
/>
|
|
41
|
+
</BaseActionItem>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
21
45
|
</div>
|
|
22
46
|
</template>
|
|
23
47
|
|
|
24
48
|
<script setup lang="ts">
|
|
25
|
-
import { PropType } from 'vue';
|
|
26
|
-
import { ActionItem } from '@/types';
|
|
49
|
+
import { PropType, Ref } from 'vue';
|
|
50
|
+
import { ActionItem } from '@/types/ActionItem';
|
|
27
51
|
import BaseActionItem from './BaseActionItem.vue';
|
|
28
52
|
import BaseNavbarItemContent from './BaseNavbarItemContent.vue';
|
|
53
|
+
import BaseMenuItem from './BaseMenuItem.vue';
|
|
29
54
|
|
|
30
55
|
defineProps({
|
|
31
56
|
item: {
|
|
@@ -36,8 +61,14 @@ defineProps({
|
|
|
36
61
|
default: false,
|
|
37
62
|
type: Boolean,
|
|
38
63
|
},
|
|
64
|
+
size: {
|
|
65
|
+
default: 'md',
|
|
66
|
+
type: String as PropType<'xs' | 'sm' | 'md'>,
|
|
67
|
+
},
|
|
39
68
|
});
|
|
40
69
|
|
|
70
|
+
const height = inject('navbar:height') as Ref<number>;
|
|
71
|
+
|
|
41
72
|
const closeMenu = inject('closeMenu') as () => void;
|
|
42
73
|
|
|
43
74
|
const emit = defineEmits(['click']);
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="classes">
|
|
3
|
-
<div class="
|
|
3
|
+
<div :class="classesInner">
|
|
4
4
|
<BaseIcon
|
|
5
5
|
v-if="icon"
|
|
6
6
|
:icon="icon"
|
|
7
7
|
:class="iconClasses"
|
|
8
8
|
/>
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
<div :class="[sizeClasses, 'text-base']">
|
|
10
|
+
{{ label }}
|
|
11
|
+
</div>
|
|
12
|
+
<div
|
|
13
|
+
v-if="count"
|
|
14
|
+
class="relative -top-px ml-[5px]"
|
|
15
|
+
>
|
|
16
|
+
<BaseCounter
|
|
17
|
+
:count="count"
|
|
18
|
+
:max-digit="2"
|
|
19
|
+
color="danger"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
20
22
|
</div>
|
|
21
23
|
</div>
|
|
22
24
|
</template>
|
|
@@ -49,28 +51,27 @@ const props = defineProps({
|
|
|
49
51
|
},
|
|
50
52
|
size: {
|
|
51
53
|
default: 'md',
|
|
52
|
-
type: String as PropType<'sm' | 'md'>,
|
|
54
|
+
type: String as PropType<'xs' | 'sm' | 'md'>,
|
|
53
55
|
},
|
|
54
56
|
});
|
|
55
57
|
|
|
56
58
|
const classes = computed(() => {
|
|
57
59
|
const classList = [
|
|
58
|
-
'
|
|
60
|
+
'flex items-center w-full',
|
|
59
61
|
];
|
|
60
62
|
|
|
61
63
|
if (props.active) {
|
|
62
64
|
if (props.dark) {
|
|
63
|
-
classList.push('
|
|
65
|
+
classList.push('text-white');
|
|
64
66
|
} else {
|
|
65
|
-
classList.push('
|
|
67
|
+
classList.push('text-slate-900');
|
|
66
68
|
}
|
|
67
69
|
} else {
|
|
68
|
-
classList.push('border-transparent');
|
|
69
70
|
if (props.dark) {
|
|
70
|
-
classList.push('hover:
|
|
71
|
+
classList.push('hover:text-white text-slate-200');
|
|
71
72
|
} else {
|
|
72
73
|
classList.push(
|
|
73
|
-
'hover:
|
|
74
|
+
'hover:text-slate-900 text-slate-800'
|
|
74
75
|
);
|
|
75
76
|
}
|
|
76
77
|
}
|
|
@@ -78,6 +79,20 @@ const classes = computed(() => {
|
|
|
78
79
|
return classList;
|
|
79
80
|
});
|
|
80
81
|
|
|
82
|
+
const classesInner = computed(() => {
|
|
83
|
+
const classList = [
|
|
84
|
+
'px-3 py-1 grow rounded-md duration-100 flex items-center font-medium',
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
if (props.dark) {
|
|
88
|
+
classList.push('hover:bg-slate-700');
|
|
89
|
+
} else {
|
|
90
|
+
classList.push('hover:bg-slate-100');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return classList;
|
|
94
|
+
});
|
|
95
|
+
|
|
81
96
|
const iconClasses = computed((): string[] => {
|
|
82
97
|
const classList = ['w-5 h-5 shrink-0 mr-2 leading-none inline-block'];
|
|
83
98
|
if (props.active) {
|
|
@@ -89,6 +104,9 @@ const iconClasses = computed((): string[] => {
|
|
|
89
104
|
});
|
|
90
105
|
|
|
91
106
|
const sizeClasses = computed(() => {
|
|
107
|
+
if (props.size == 'xs') {
|
|
108
|
+
return 'text-xs';
|
|
109
|
+
}
|
|
92
110
|
if (props.size == 'sm') {
|
|
93
111
|
return 'text-sm';
|
|
94
112
|
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
3
|
<BaseActionItem
|
|
4
|
-
:
|
|
5
|
-
:href="item.href"
|
|
6
|
-
:action="item.action"
|
|
7
|
-
:dark="dark"
|
|
4
|
+
:item="item"
|
|
8
5
|
class="flex w-full"
|
|
9
6
|
@click="onClick"
|
|
10
7
|
>
|
|
@@ -29,12 +26,23 @@
|
|
|
29
26
|
:key="subItem.label"
|
|
30
27
|
>
|
|
31
28
|
<BaseActionItem
|
|
32
|
-
:
|
|
33
|
-
:href="subItem.href"
|
|
34
|
-
:action="subItem.action"
|
|
29
|
+
:item="subItem"
|
|
35
30
|
:class="subItemClasses"
|
|
36
31
|
>
|
|
37
|
-
{
|
|
32
|
+
<template #default="{ active }">
|
|
33
|
+
<div
|
|
34
|
+
class="grow"
|
|
35
|
+
:class="{ 'font-medium': active, 'text-white': active && dark }"
|
|
36
|
+
>
|
|
37
|
+
{{ subItem.label }}
|
|
38
|
+
</div>
|
|
39
|
+
<BaseCounter
|
|
40
|
+
v-if="subItem.count"
|
|
41
|
+
:count="subItem.count"
|
|
42
|
+
:size="size"
|
|
43
|
+
:color="dark ? 'light' : 'light'"
|
|
44
|
+
/>
|
|
45
|
+
</template>
|
|
38
46
|
</BaseActionItem>
|
|
39
47
|
</div>
|
|
40
48
|
</div>
|
|
@@ -43,9 +51,10 @@
|
|
|
43
51
|
|
|
44
52
|
<script setup lang="ts">
|
|
45
53
|
import { PropType } from 'vue';
|
|
46
|
-
import { ActionItem } from '@/types';
|
|
54
|
+
import { ActionItem } from '@/types/ActionItem';
|
|
47
55
|
import BaseActionItem from './BaseActionItem.vue';
|
|
48
56
|
import BaseNavbarSideItemContent from './BaseNavbarSideItemContent.vue';
|
|
57
|
+
import BaseCounter from './BaseCounter.vue';
|
|
49
58
|
|
|
50
59
|
const props = defineProps({
|
|
51
60
|
item: {
|
|
@@ -56,10 +65,6 @@ const props = defineProps({
|
|
|
56
65
|
default: false,
|
|
57
66
|
type: Boolean,
|
|
58
67
|
},
|
|
59
|
-
actionsVisible: {
|
|
60
|
-
default: 'toggle',
|
|
61
|
-
type: String as PropType<'toggle' | 'always'>,
|
|
62
|
-
},
|
|
63
68
|
size: {
|
|
64
69
|
default: 'md',
|
|
65
70
|
type: String as PropType<'xs' | 'sm' | 'md'>,
|
|
@@ -83,7 +88,7 @@ const routeActive = computed((): boolean => {
|
|
|
83
88
|
});
|
|
84
89
|
|
|
85
90
|
const showSubActions = computed((): boolean => {
|
|
86
|
-
if (props.
|
|
91
|
+
if (props.item.meta?.showSubItems == 'always') {
|
|
87
92
|
return true;
|
|
88
93
|
}
|
|
89
94
|
if (!props.item.to) {
|
|
@@ -102,11 +107,11 @@ const subItemClasses = computed((): string[] => {
|
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
if (props.size == 'xs') {
|
|
105
|
-
classList.push('pl-[33.5px] text-[13px] mb-1');
|
|
110
|
+
classList.push('pl-[33.5px] text-[13px] mb-1 pr-2.5');
|
|
106
111
|
} else if (props.size == 'sm') {
|
|
107
|
-
classList.push('pl-[36px] text-sm mb-1.5');
|
|
112
|
+
classList.push('pl-[36px] text-sm mb-1.5 pr-3');
|
|
108
113
|
} else {
|
|
109
|
-
classList.push('pl-[40px] text-base mb-1');
|
|
114
|
+
classList.push('pl-[40px] text-base mb-1 pr-3');
|
|
110
115
|
}
|
|
111
116
|
|
|
112
117
|
return classList;
|