design-system-next 2.12.3 → 2.12.7

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.
@@ -82,8 +82,18 @@ export const calendarPropTypes = {
82
82
  },
83
83
  };
84
84
 
85
- export const calendarEmitTypes = {};
86
-
85
+ export const calendarEmitTypes = [
86
+ 'loadMore',
87
+ 'onCellClick',
88
+ 'update:firstLastDayOfWeek',
89
+ 'update:sort',
90
+ 'update:search',
91
+ 'update:selectedCell',
92
+ 'update:selectedCompany',
93
+ 'update:selectedDepartment',
94
+ 'update:selectedBranch',
95
+ 'onClickEmptyButton',
96
+ ];
87
97
  export type CalendarEmitTypes = typeof calendarEmitTypes;
88
98
 
89
99
  export type CalendarPropTypes = ExtractPropTypes<typeof calendarPropTypes>;
@@ -0,0 +1,304 @@
1
+ <template>
2
+ <div v-for="(navLink, navLinkIndex) in navLinks.top" :key="navLinkIndex">
3
+ <template v-for="(parentLink, parentLinkIndex) in navLink.parentLinks" :key="parentLinkIndex">
4
+ <!-- #region - Parent Links with Menus -->
5
+ <template v-if="parentLink.menuLinks && parentLink.menuLinks.length > 0">
6
+ <Menu
7
+ aria-id="sidenav-menu-wrapper"
8
+ distance="18"
9
+ placement="right"
10
+ :triggers="['click', 'hover']"
11
+ instant-move
12
+ :delay="0"
13
+ >
14
+ <!-- #region - Parent Links -->
15
+ <div
16
+ :id="`${generateId(parentLink.title)}`"
17
+ :class="{
18
+ 'spr-m-auto spr-box-border spr-flex spr-max-h-9 spr-max-w-9 spr-cursor-pointer spr-items-center spr-justify-center spr-rounded-border-radius-md spr-p-2 spr-transition spr-duration-150 spr-ease-in-out': true,
19
+ 'spr-background-color-single-active spr-border-color-brand-base spr-border-[1.5px] spr-border-solid active:spr-scale-90':
20
+ props.activeNav.parentNav === parentLink.title,
21
+ 'hover:spr-background-color-hover': props.activeNav.parentNav != parentLink.title,
22
+ 'active:spr-background-color-single-active active:spr-scale-90': true,
23
+ }"
24
+ >
25
+ <template v-if="parentLink.icon && parentLink.icon.includes('https://')">
26
+ <img
27
+ v-if="parentLink.icon && props.activeNav.parentNav !== parentLink.title"
28
+ :src="parentLink.icon"
29
+ :alt="`${parentLink.title} icon`"
30
+ class="spr-h-[1.25em] spr-w-[1.25em] spr-max-w-[1.25em]"
31
+ />
32
+ <img
33
+ v-else-if="props.activeNav.parentNav === parentLink.title"
34
+ :src="parentLink.icon.replace(/\.(svg|png|jpg)$/, '-fill.$1')"
35
+ :alt="`${parentLink.title} icon`"
36
+ class="spr-h-[1.25em] spr-w-[1.25em] spr-max-w-[1.25em]"
37
+ />
38
+ </template>
39
+ <template v-else>
40
+ <Icon
41
+ v-if="parentLink.icon && props.activeNav.parentNav !== parentLink.title"
42
+ :icon="parentLink.icon"
43
+ class="spr-h-[1.25em] spr-w-[1.25em]"
44
+ />
45
+ <Icon
46
+ v-else-if="props.activeNav.parentNav === parentLink.title"
47
+ :icon="`${parentLink.icon}-fill`"
48
+ class="spr-h-[1.25em] spr-w-[1.25em] spr-text-kangkong-700"
49
+ />
50
+ <Icon v-else icon="ph:globe" />
51
+ </template>
52
+ </div>
53
+ <!-- #endregion - Parent Links -->
54
+
55
+ <!-- #region - Menu Links Popper -->
56
+ <template #popper>
57
+ <div class="spr-border-color-weak spr-border-x-0 spr-border-b spr-border-t-0 spr-border-solid spr-p-2">
58
+ <h3 class="spr-body-sm-regular-medium spr-m-0">
59
+ {{ parentLink.title }}
60
+ </h3>
61
+ </div>
62
+
63
+ <template v-for="(menuLink, menuLinkIndex) in parentLink.menuLinks" :key="menuLinkIndex">
64
+ <h5
65
+ v-if="menuLink.menuHeading"
66
+ :class="{
67
+ 'spr-label-xs-medium spr-text-color-supporting spr-m-0 spr-p-2': true,
68
+ 'spr-mt-2': menuLinkIndex !== 0,
69
+ }"
70
+ >
71
+ {{ menuLink.menuHeading }}
72
+ </h5>
73
+
74
+ <template v-for="(menuLinkItem, menuLinkItemIndex) in menuLink.items" :key="menuLinkItemIndex">
75
+ <!-- #region - Menu link with Submenu links -->
76
+ <template v-if="menuLinkItem.submenuLinks && menuLinkItem.submenuLinks.length > 0">
77
+ <Menu
78
+ aria-id="sidenav-submenu-l1-wrapper"
79
+ distance="4"
80
+ placement="right-start"
81
+ :triggers="['click', 'hover']"
82
+ instant-move
83
+ :delay="0"
84
+ >
85
+ <!-- #region - Menu links -->
86
+ <div
87
+ :id="`${generateId(parentLink.title, menuLinkItem.title)}`"
88
+ :class="{
89
+ 'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-justify-between spr-px-2 spr-py-1.5 spr-align-middle spr-duration-150 spr-ease-in-out': true,
90
+ 'spr-background-color-single-active': props.activeNav.menu === menuLinkItem.title,
91
+ 'hover:spr-background-color-hover': props.activeNav.menu !== menuLinkItem.title,
92
+ 'active:spr-background-color-pressed': true,
93
+ }"
94
+ >
95
+ <div
96
+ v-if="props.activeNav.menu === menuLinkItem.title"
97
+ class="spr-background-color-brand-base spr-absolute spr-left-0 spr-top-0 spr-h-full spr-w-[2px]"
98
+ ></div>
99
+ <span>{{ menuLinkItem.title }}</span>
100
+ <div class="spr-flex spr-items-center spr-gap-1">
101
+ <template v-for="(attr, i) in menuLinkItem?.attributes" :key="i">
102
+ <spr-lozenge
103
+ v-if="attr?.name === 'lozenge' && attr?.value"
104
+ :label="getLozengeLabel(attr)"
105
+ :tone="getLozengeTone(attr)"
106
+ fill
107
+ />
108
+ </template>
109
+ <Icon
110
+ icon="ph:caret-right"
111
+ class="spr-h-[16px] spr-w-[16px] spr-transform spr-font-normal spr-transition-transform spr-duration-300"
112
+ />
113
+ </div>
114
+ </div>
115
+ <!-- #endregion - Menu links -->
116
+
117
+ <!-- #region - Submenu Links Popper -->
118
+ <!--
119
+ Note: if you want the popper to stay open while hovering over submenuLink.subMenuHeading & submenuLinkItem.title,
120
+ you need to keep it inside a <Menu> or ensure the content is part of the popper's interactive area.
121
+
122
+ "sidenav-submenu-l2-wrapper" - Popper is currently hidden since sidenav only has 1 level of submenu links.
123
+ -->
124
+ <template #popper>
125
+ <Menu aria-id="sidenav-submenu-l2-wrapper" :triggers="['click', 'hover']" instant-move :delay="0">
126
+ <template
127
+ v-for="(submenuLink, submenuLinkIndex) in menuLinkItem.submenuLinks"
128
+ :key="submenuLinkIndex"
129
+ >
130
+ <h5
131
+ v-if="submenuLink.subMenuHeading"
132
+ :class="{
133
+ 'spr-label-xs-medium spr-text-color-supporting spr-m-0 spr-p-2': true,
134
+ 'spr-mt-2': submenuLinkIndex !== 0,
135
+ }"
136
+ >
137
+ {{ submenuLink.subMenuHeading }}
138
+ </h5>
139
+
140
+ <template
141
+ v-for="(submenuLinkItem, submenuLinkItemIndex) in submenuLink.items"
142
+ :key="submenuLinkItemIndex"
143
+ >
144
+ <!-- #region - Submenu Links -->
145
+ <div
146
+ v-if="!submenuLinkItem.hidden"
147
+ :id="`${generateId(parentLink.title, menuLinkItem.title, submenuLinkItem.title)}`"
148
+ :class="{
149
+ 'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-justify-between spr-px-2 spr-py-1.5 spr-align-middle spr-duration-150 spr-ease-in-out': true,
150
+ 'spr-background-color-single-active': props.activeNav.submenu === submenuLinkItem.title,
151
+ 'hover:spr-background-color-hover': props.activeNav.submenu !== submenuLinkItem.title,
152
+ 'active:spr-background-color-pressed': true,
153
+ }"
154
+ @click="
155
+ handleRedirect(
156
+ submenuLinkItem,
157
+ parentLink.title,
158
+ menuLinkItem.title,
159
+ submenuLinkItem.title,
160
+ )
161
+ "
162
+ >
163
+ <div
164
+ v-show="props.activeNav.submenu === submenuLinkItem.title"
165
+ class="spr-background-color-brand-base spr-absolute spr-left-0 spr-top-0 spr-h-full spr-w-[2px]"
166
+ ></div>
167
+ <div class="spr-flex spr-items-center spr-gap-1">
168
+ <span>{{ submenuLinkItem.title }}</span>
169
+
170
+ <template v-for="(attr, i) in submenuLinkItem?.attributes" :key="i">
171
+ <spr-lozenge
172
+ v-if="attr?.name === 'lozenge' && attr?.value"
173
+ :label="getLozengeLabel(attr)"
174
+ :tone="getLozengeTone(attr)"
175
+ fill
176
+ />
177
+ </template>
178
+ </div>
179
+ </div>
180
+ <!-- #endregion - Submenu Links -->
181
+ </template>
182
+ </template>
183
+ </Menu>
184
+ </template>
185
+ <!-- #endregion - Submenu Links Popper -->
186
+ </Menu>
187
+ </template>
188
+ <!-- #endregion - Menu link with Submenu links -->
189
+
190
+ <!-- #region - Menu link only -->
191
+ <template v-else>
192
+ <div
193
+ v-if="!menuLinkItem.hidden"
194
+ :id="`${generateId(parentLink.title, menuLinkItem.title)}`"
195
+ :class="{
196
+ 'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-justify-between spr-px-2 spr-py-1.5 spr-align-middle spr-duration-150 spr-ease-in-out': true,
197
+ 'spr-background-color-single-active': props.activeNav.menu === menuLinkItem.title,
198
+ 'hover:spr-background-color-hover': props.activeNav.menu !== menuLinkItem.title,
199
+ 'active:spr-background-color-pressed': true,
200
+ }"
201
+ @click="handleRedirect(menuLinkItem, parentLink.title, menuLinkItem.title, '')"
202
+ >
203
+ <div
204
+ v-if="props.activeNav.menu === menuLinkItem.title"
205
+ class="spr-background-color-brand-base spr-absolute spr-left-0 spr-top-0 spr-h-full spr-w-[2px]"
206
+ ></div>
207
+ <span>{{ menuLinkItem.title }}</span>
208
+ <template v-for="(attr, i) in menuLinkItem?.attributes" :key="i">
209
+ <spr-lozenge
210
+ v-if="attr?.name === 'lozenge' && attr?.value"
211
+ :label="getLozengeLabel(attr)"
212
+ :tone="getLozengeTone(attr)"
213
+ fill
214
+ />
215
+ </template>
216
+ </div>
217
+ </template>
218
+ <!-- #endregion - Menu link only -->
219
+ </template>
220
+ </template>
221
+ </template>
222
+ <!-- #endregion - Menu Links -->
223
+ </Menu>
224
+ </template>
225
+ <!-- #endregion - Parent Links with Menus -->
226
+
227
+ <!-- #region - Parent link only -->
228
+ <template v-else>
229
+ <spr-tooltip
230
+ v-if="!parentLink.hidden"
231
+ :text="parentLink.title"
232
+ placement="right"
233
+ :distance="18"
234
+ :fit-content="false"
235
+ >
236
+ <div
237
+ :id="`${generateId(parentLink.title)}`"
238
+ :class="{
239
+ 'spr-m-auto spr-box-border spr-flex spr-max-h-9 spr-max-w-9 spr-cursor-pointer spr-items-center spr-justify-center spr-rounded-border-radius-md spr-p-2 spr-transition spr-duration-150 spr-ease-in-out': true,
240
+ 'spr-background-color-single-active spr-border-color-brand-base spr-border-[1.5px] spr-border-solid active:spr-scale-90':
241
+ props.activeNav.parentNav === parentLink.title,
242
+ 'hover:spr-background-color-hover': props.activeNav.parentNav != parentLink.title,
243
+ 'active:spr-background-color-single-active active:spr-scale-90': true,
244
+ }"
245
+ @click="handleRedirect(parentLink, parentLink.title, '', '')"
246
+ >
247
+ <template v-if="parentLink.icon && parentLink.icon.includes('https://')">
248
+ <img
249
+ v-if="parentLink.icon && props.activeNav.parentNav !== parentLink.title"
250
+ :src="parentLink.icon"
251
+ :alt="`${parentLink.title} icon`"
252
+ class="spr-h-[1.25em] spr-w-[1.25em] spr-max-w-[1.25em]"
253
+ />
254
+ <img
255
+ v-else-if="props.activeNav.parentNav === parentLink.title"
256
+ :src="parentLink.icon.replace(/\.(svg|png|jpg)$/, '-fill.$1')"
257
+ :alt="`${parentLink.title} icon`"
258
+ class="spr-h-[1.25em] spr-w-[1.25em] spr-max-w-[1.25em]"
259
+ />
260
+ </template>
261
+ <template v-else>
262
+ <Icon
263
+ v-if="parentLink.icon && props.activeNav.parentNav !== parentLink.title"
264
+ :icon="parentLink.icon"
265
+ class="spr-h-[1.25em] spr-w-[1.25em]"
266
+ />
267
+ <Icon
268
+ v-else-if="props.activeNav.parentNav === parentLink.title"
269
+ :icon="`${parentLink.icon}-fill`"
270
+ class="spr-h-[1.25em] spr-w-[1.25em] spr-text-kangkong-700"
271
+ />
272
+ <Icon v-else icon="ph:globe" />
273
+ </template>
274
+ </div>
275
+ </spr-tooltip>
276
+ </template>
277
+ <!-- #endregion - Parent link only -->
278
+ </template>
279
+
280
+ <!-- Divider -->
281
+ <div
282
+ v-if="navLinks.top.length > 0 && navLinkIndex < navLinks.top.length - 1"
283
+ class="spr-background-color-hover spr-h-[2px] spr-w-full"
284
+ ></div>
285
+ </div>
286
+ </template>
287
+
288
+ <script lang="ts" setup>
289
+ import { Menu } from 'floating-vue';
290
+ import { Icon } from '@iconify/vue';
291
+
292
+ import 'floating-vue/dist/style.css';
293
+
294
+ import { sidenavPropTypes, sidenavEmitTypes } from './sidenav';
295
+ import { useSidenav } from './use-sidenav';
296
+
297
+ import SprLozenge from '../lozenge/lozenge.vue';
298
+ import SprTooltip from '../tooltip/tooltip.vue';
299
+
300
+ const props = defineProps(sidenavPropTypes);
301
+ const emit = defineEmits(sidenavEmitTypes);
302
+
303
+ const { handleRedirect, generateId, getLozengeLabel, getLozengeTone } = useSidenav(props, emit);
304
+ </script>
@@ -95,10 +95,11 @@ export type Attributes = {
95
95
  name: string;
96
96
  value: unknown | string | number | boolean | AttrLozenge;
97
97
  };
98
- type AttrLozenge = {
98
+
99
+ export type AttrLozenge = {
99
100
  label: string;
100
101
  tone?: string;
101
- }
102
+ };
102
103
 
103
104
  export interface MappedNavItem {
104
105
  title: string;
@@ -108,7 +109,7 @@ export interface MappedNavItem {
108
109
  isAbsoluteURL: boolean;
109
110
  link: string;
110
111
  };
111
- attributes?: AttrLozenge | unknown [];
112
+ attributes?: AttrLozenge | unknown[];
112
113
  menuLinks?: {
113
114
  menuHeading: string;
114
115
  items: MappedNavItem[];
@@ -137,7 +138,7 @@ export const sidenavPropTypes = {
137
138
  },
138
139
  navLinks: {
139
140
  type: Object as PropType<NavLinks>,
140
- default: () => [],
141
+ default: () => ({ top: [], bottom: [] }),
141
142
  },
142
143
  notificationCount: {
143
144
  type: [String, Number],
@@ -155,8 +156,8 @@ export const sidenavPropTypes = {
155
156
  },
156
157
  userMenu: {
157
158
  type: Object as PropType<UserMenu>,
158
- validator: (value: unknown) => typeof value === 'object',
159
- default: false,
159
+ validator: (value: unknown) => value === null || typeof value === 'object',
160
+ default: null,
160
161
  },
161
162
  isNotifActive: {
162
163
  type: Boolean,