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.
- package/dist/design-system-next.es.js +6821 -7001
- package/dist/design-system-next.es.js.gz +0 -0
- package/dist/design-system-next.umd.js +12 -12
- package/dist/design-system-next.umd.js.gz +0 -0
- package/dist/main.css +1 -1
- package/dist/main.css.gz +0 -0
- package/dist/package.json.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/avatar/avatar.ts +8 -1
- package/src/components/avatar/avatar.vue +10 -5
- package/src/components/avatar/use-avatar.ts +14 -3
- package/src/components/calendar/calendar.ts +12 -2
- package/src/components/sidenav/sidenav-menu-links.vue +304 -0
- package/src/components/sidenav/sidenav.ts +7 -6
- package/src/components/sidenav/sidenav.vue +34 -587
- package/src/components/sidenav/use-sidenav.ts +29 -20
- package/src/components/table/table.vue +1 -1
- package/src/components/table/use-table.ts +2 -2
- package/src/components/date-picker/__tests__/date-picker.test.ts +0 -112
- package/src/components/dropdown/__tests__/dropdown-fixes.spec.ts +0 -106
- package/src/components/dropdown/__tests__/dropdown-value-types.spec.ts +0 -213
- package/src/examples/dropdown-number-multi-select.vue +0 -76
|
@@ -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
|
-
|
|
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:
|
|
159
|
+
validator: (value: unknown) => value === null || typeof value === 'object',
|
|
160
|
+
default: null,
|
|
160
161
|
},
|
|
161
162
|
isNotifActive: {
|
|
162
163
|
type: Boolean,
|