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.
Files changed (73) hide show
  1. package/dist/sprintify-ui.es.js +11240 -11075
  2. package/dist/style.css +1 -1
  3. package/dist/types/src/components/BaseActionItem.vue.d.ts +7 -17
  4. package/dist/types/src/components/BaseActionItemButton.vue.d.ts +3 -3
  5. package/dist/types/src/components/BaseAutocomplete.vue.d.ts +1 -1
  6. package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +1 -1
  7. package/dist/types/src/components/BaseBelongsTo.vue.d.ts +1 -1
  8. package/dist/types/src/components/BaseBelongsToFetch.vue.d.ts +1 -1
  9. package/dist/types/src/components/BaseButtonGroup.vue.d.ts +1 -1
  10. package/dist/types/src/components/BaseColor.vue.d.ts +1 -1
  11. package/dist/types/src/components/BaseDataIterator.vue.d.ts +5 -4
  12. package/dist/types/src/components/BaseDataTable.vue.d.ts +8 -7
  13. package/dist/types/src/components/BaseDatePicker.vue.d.ts +9 -9
  14. package/dist/types/src/components/BaseDateSelect.vue.d.ts +1 -1
  15. package/dist/types/src/components/BaseDropdownAutocomplete.vue.d.ts +1 -1
  16. package/dist/types/src/components/BaseField.vue.d.ts +1 -1
  17. package/dist/types/src/components/BaseFieldI18n.vue.d.ts +1 -1
  18. package/dist/types/src/components/BaseHeader.vue.d.ts +2 -1
  19. package/dist/types/src/components/BaseInput.vue.d.ts +1 -1
  20. package/dist/types/src/components/BaseInputPercent.vue.d.ts +1 -1
  21. package/dist/types/src/components/BaseLayoutSidebarConfigurable.vue.d.ts +4 -3
  22. package/dist/types/src/components/BaseLayoutStacked.vue.d.ts +39 -7
  23. package/dist/types/src/components/BaseLayoutStackedConfigurable.vue.d.ts +20 -1
  24. package/dist/types/src/components/BaseMenu.vue.d.ts +7 -7
  25. package/dist/types/src/components/BaseMenuItem.vue.d.ts +9 -0
  26. package/dist/types/src/components/BaseNavbar.vue.d.ts +40 -8
  27. package/dist/types/src/components/BaseNavbarItem.vue.d.ts +10 -1
  28. package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +4 -4
  29. package/dist/types/src/components/BaseNavbarSideItem.vue.d.ts +1 -10
  30. package/dist/types/src/components/BaseNavbarSideItemContent.vue.d.ts +1 -1
  31. package/dist/types/src/components/BasePassword.vue.d.ts +1 -1
  32. package/dist/types/src/components/BaseRadioGroup.vue.d.ts +1 -1
  33. package/dist/types/src/components/BaseRichText.vue.d.ts +4 -4
  34. package/dist/types/src/components/BaseSelect.vue.d.ts +1 -1
  35. package/dist/types/src/components/BaseShortcut.vue.d.ts +1 -1
  36. package/dist/types/src/components/BaseStatistic.vue.d.ts +1 -1
  37. package/dist/types/src/components/BaseSwitch.vue.d.ts +1 -1
  38. package/dist/types/src/components/BaseSystemAlert.vue.d.ts +1 -1
  39. package/dist/types/src/components/BaseTableColumn.vue.d.ts +1 -1
  40. package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +1 -1
  41. package/dist/types/src/components/BaseTextarea.vue.d.ts +1 -1
  42. package/dist/types/src/types/ActionItem.d.ts +15 -0
  43. package/dist/types/src/types/index.d.ts +0 -26
  44. package/package.json +1 -1
  45. package/src/components/BaseActionItem.vue +25 -14
  46. package/src/components/BaseActionItemButton.vue +14 -16
  47. package/src/components/BaseDataIterator.stories.js +1 -1
  48. package/src/components/BaseDataIterator.vue +2 -2
  49. package/src/components/BaseDataTable.stories.js +1 -1
  50. package/src/components/BaseDataTable.vue +4 -4
  51. package/src/components/BaseHeader.vue +3 -2
  52. package/src/components/BaseLayoutNotificationDropdown.vue +7 -7
  53. package/src/components/BaseLayoutSidebarConfigurable.stories.js +25 -5
  54. package/src/components/BaseLayoutSidebarConfigurable.vue +23 -27
  55. package/src/components/BaseLayoutStacked.vue +38 -11
  56. package/src/components/BaseLayoutStackedConfigurable.stories.js +50 -1
  57. package/src/components/BaseLayoutStackedConfigurable.vue +22 -6
  58. package/src/components/BaseMenu.vue +3 -3
  59. package/src/components/BaseMenuItem.vue +39 -15
  60. package/src/components/BaseNavbar.stories.js +8 -7
  61. package/src/components/BaseNavbar.vue +81 -17
  62. package/src/components/BaseNavbarItem.vue +38 -7
  63. package/src/components/BaseNavbarItemContent.vue +37 -19
  64. package/src/components/BaseNavbarSideItem.vue +22 -17
  65. package/src/components/BaseNavbarSideItemContent.vue +1 -1
  66. package/src/components/BaseShortcut.vue +5 -3
  67. package/src/components/BaseSideNavigation.stories.js +1 -1
  68. package/src/components/BaseTabItem.vue +4 -9
  69. package/src/components/BaseTabs.stories.js +7 -3
  70. package/src/components/BaseTabs.vue +94 -5
  71. package/src/stories/List.stories.js +1 -1
  72. package/src/types/ActionItem.ts +16 -0
  73. package/src/types/index.ts +0 -29
@@ -1,10 +1,13 @@
1
1
  <template>
2
- <BaseLayoutStacked :dark="dark">
2
+ <BaseLayoutStacked
3
+ :size="size"
4
+ :dark="dark"
5
+ >
3
6
  <template #navbar>
4
- <div class="flex h-16 justify-between">
7
+ <div class="flex w-full justify-between">
5
8
  <!-- Left -->
6
9
 
7
- <div class="flex justify-center">
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-4 md:flex">
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 { ActionItem, NotificationsConfig } from '../types';
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<MenuItemInterface[]>,
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 class="flex items-center">
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
- <span :class="[textClasses, textColor]">{{ label }}</span>
14
- </div>
15
- <div
16
- v-if="count"
17
- class="relative -top-px ml-[5px]"
18
- >
19
- <BaseCounter
20
- :count="count"
21
- :max-digit="2"
22
- :color="color"
23
- :size="size"
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 mr-2';
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: 'Layout/BaseNavbar',
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 h-16 justify-between">
74
+ <div class="flex w-full justify-between">
75
75
  <!-- Left -->
76
76
 
77
- <div class="flex justify-center">
77
+ <div class="flex justify-start grow">
78
78
  <!-- Logo -->
79
- <RouterLink to="/" class="flex flex-shrink-0 grow items-center p-2 pl-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-2 ring-blue-500 ring-offset-2 ring-offset-slate-700' : '']"
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
- class="border-t-[3px] border-primary-500"
4
- :class="[dark ? 'bg-slate-900' : 'bg-white']"
5
- >
6
- <BaseContainer :size="size">
7
- <div class="flex h-16 justify-between">
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 name="navbar" />
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 class="-mr-2 flex items-center md:hidden">
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 md:hidden"
47
- :class="[dark ? 'bg-slate-900' : 'bg-white']"
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
- defineProps({
64
- size: {
65
- default: '7xl',
66
- type: String,
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
- :to="item.to"
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="group flex grow items-center">
3
+ <div :class="classesInner">
4
4
  <BaseIcon
5
5
  v-if="icon"
6
6
  :icon="icon"
7
7
  :class="iconClasses"
8
8
  />
9
- <span :class="[sizeClasses]">{{ label }}</span>
10
- </div>
11
- <div
12
- v-if="count"
13
- class="relative -top-px ml-[5px]"
14
- >
15
- <BaseCounter
16
- :count="count"
17
- :max-digit="2"
18
- :color="'primary'"
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
- 'text-left border-b-2 px-2 flex items-center text-base font-medium w-full',
60
+ 'flex items-center w-full',
59
61
  ];
60
62
 
61
63
  if (props.active) {
62
64
  if (props.dark) {
63
- classList.push('border-white text-white');
65
+ classList.push('text-white');
64
66
  } else {
65
- classList.push('border-primary-500 text-slate-900');
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:border-white hover:text-white text-slate-200');
71
+ classList.push('hover:text-white text-slate-200');
71
72
  } else {
72
73
  classList.push(
73
- 'hover:border-primary-500 hover:text-slate-900 text-slate-800'
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
- :to="item.to"
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
- :to="subItem.to"
33
- :href="subItem.href"
34
- :action="subItem.action"
29
+ :item="subItem"
35
30
  :class="subItemClasses"
36
31
  >
37
- {{ subItem.label }}
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.actionsVisible == 'always') {
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;
@@ -16,7 +16,7 @@
16
16
  :size="size"
17
17
  :count="count"
18
18
  :max-digit="2"
19
- :color="'primary'"
19
+ color="danger"
20
20
  />
21
21
  </div>
22
22
  </div>
@@ -1,9 +1,11 @@
1
1
  <template>
2
2
  <BaseCard class="flex duration-200 hover:bg-slate-50">
3
3
  <BaseActionItem
4
- :to="to"
5
- :href="href"
6
- :action="action"
4
+ :item="{
5
+ to,
6
+ href,
7
+ action,
8
+ }"
7
9
  class="block w-full"
8
10
  >
9
11
  <section class="whitespace-pre-line p-4">