design-system-next 2.12.10 → 2.12.15
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 +3517 -3427
- 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/App.vue +2 -1
- package/src/components/checkbox/use-checkbox.ts +2 -2
- package/src/components/sidenav/sidenav-menu-links.vue +59 -37
- package/src/components/sidenav/sidenav.ts +8 -9
- package/src/components/sidenav/sidenav.vue +10 -2
- package/src/components/sidenav/use-sidenav.ts +69 -15
- package/src/components/table/table-pagination/table-pagination.ts +8 -0
- package/src/components/table/table-pagination/table-pagination.vue +29 -2
- package/src/components/table/table-pagination/use-table-pagination.ts +26 -4
- package/src/components/table/table.vue +10 -3
- package/src/components/table/use-table.ts +6 -5
- package/src/components/textarea/use-textarea.ts +1 -1
- package/src/mock/tableData.ts +23 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-for="(navLink, navLinkIndex) in navLinks
|
|
2
|
+
<div v-for="(navLink, navLinkIndex) in navLinks" :key="navLinkIndex" class="spr-grid spr-gap-2">
|
|
3
3
|
<template v-for="(parentLink, parentLinkIndex) in navLink.parentLinks" :key="parentLinkIndex">
|
|
4
4
|
<!-- #region - Parent Links with Menus -->
|
|
5
5
|
<template v-if="parentLink.menuLinks && parentLink.menuLinks.length > 0">
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
<div
|
|
87
87
|
:id="`${generateId(parentLink.title, menuLinkItem.title)}`"
|
|
88
88
|
:class="{
|
|
89
|
-
'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-
|
|
89
|
+
'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-px-2 spr-py-1.5 spr-align-middle spr-duration-150 spr-ease-in-out': true,
|
|
90
90
|
'spr-background-color-single-active': props.activeNav.menu === menuLinkItem.title,
|
|
91
91
|
'hover:spr-background-color-hover': props.activeNav.menu !== menuLinkItem.title,
|
|
92
92
|
'active:spr-background-color-pressed': true,
|
|
@@ -96,20 +96,27 @@
|
|
|
96
96
|
v-if="props.activeNav.menu === menuLinkItem.title"
|
|
97
97
|
class="spr-background-color-brand-base spr-absolute spr-left-0 spr-top-0 spr-h-full spr-w-[2px]"
|
|
98
98
|
></div>
|
|
99
|
-
|
|
100
|
-
<div class="spr-flex spr-items-center spr-gap-1">
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
|
|
100
|
+
<div class="spr-flex spr-w-full spr-items-center spr-justify-between spr-gap-1">
|
|
101
|
+
<span>{{ menuLinkItem.title }}</span>
|
|
102
|
+
|
|
103
|
+
<div class="spr-flex spr-items-center spr-gap-2">
|
|
104
|
+
<template
|
|
105
|
+
v-for="(attribute, i) in convertAttributesToArray(menuLinkItem?.attributes)"
|
|
106
|
+
:key="i"
|
|
107
|
+
>
|
|
108
|
+
<spr-lozenge
|
|
109
|
+
v-if="attribute?.name === 'lozenge' && attribute?.value"
|
|
110
|
+
:label="getLozengeLabel(attribute)"
|
|
111
|
+
:tone="getLozengeTone(attribute)"
|
|
112
|
+
fill
|
|
113
|
+
/>
|
|
114
|
+
</template>
|
|
115
|
+
<Icon
|
|
116
|
+
icon="ph:caret-right"
|
|
117
|
+
class="spr-h-[16px] spr-w-[16px] spr-transform spr-font-normal spr-transition-transform spr-duration-300"
|
|
107
118
|
/>
|
|
108
|
-
</
|
|
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
|
-
/>
|
|
119
|
+
</div>
|
|
113
120
|
</div>
|
|
114
121
|
</div>
|
|
115
122
|
<!-- #endregion - Menu links -->
|
|
@@ -146,7 +153,7 @@
|
|
|
146
153
|
v-if="!submenuLinkItem.hidden"
|
|
147
154
|
:id="`${generateId(parentLink.title, menuLinkItem.title, submenuLinkItem.title)}`"
|
|
148
155
|
:class="{
|
|
149
|
-
'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-
|
|
156
|
+
'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-px-2 spr-py-1.5 spr-align-middle spr-duration-150 spr-ease-in-out': true,
|
|
150
157
|
'spr-background-color-single-active': props.activeNav.submenu === submenuLinkItem.title,
|
|
151
158
|
'hover:spr-background-color-hover': props.activeNav.submenu !== submenuLinkItem.title,
|
|
152
159
|
'active:spr-background-color-pressed': true,
|
|
@@ -164,17 +171,23 @@
|
|
|
164
171
|
v-show="props.activeNav.submenu === submenuLinkItem.title"
|
|
165
172
|
class="spr-background-color-brand-base spr-absolute spr-left-0 spr-top-0 spr-h-full spr-w-[2px]"
|
|
166
173
|
></div>
|
|
167
|
-
|
|
174
|
+
|
|
175
|
+
<div class="spr-flex spr-w-full spr-items-center spr-justify-between spr-gap-1">
|
|
168
176
|
<span>{{ submenuLinkItem.title }}</span>
|
|
169
177
|
|
|
170
|
-
<
|
|
171
|
-
<
|
|
172
|
-
v-
|
|
173
|
-
:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
+
<div class="spr-flex spr-items-center spr-gap-2">
|
|
179
|
+
<template
|
|
180
|
+
v-for="(attribute, i) in convertAttributesToArray(submenuLinkItem?.attributes)"
|
|
181
|
+
:key="i"
|
|
182
|
+
>
|
|
183
|
+
<spr-lozenge
|
|
184
|
+
v-if="attribute?.name === 'lozenge' && attribute?.value"
|
|
185
|
+
:label="getLozengeLabel(attribute)"
|
|
186
|
+
:tone="getLozengeTone(attribute)"
|
|
187
|
+
fill
|
|
188
|
+
/>
|
|
189
|
+
</template>
|
|
190
|
+
</div>
|
|
178
191
|
</div>
|
|
179
192
|
</div>
|
|
180
193
|
<!-- #endregion - Submenu Links -->
|
|
@@ -193,7 +206,7 @@
|
|
|
193
206
|
v-if="!menuLinkItem.hidden"
|
|
194
207
|
:id="`${generateId(parentLink.title, menuLinkItem.title)}`"
|
|
195
208
|
:class="{
|
|
196
|
-
'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-
|
|
209
|
+
'spr-body-sm-regular spr-relative spr-m-0 spr-flex spr-cursor-pointer spr-px-2 spr-py-1.5 spr-align-middle spr-duration-150 spr-ease-in-out': true,
|
|
197
210
|
'spr-background-color-single-active': props.activeNav.menu === menuLinkItem.title,
|
|
198
211
|
'hover:spr-background-color-hover': props.activeNav.menu !== menuLinkItem.title,
|
|
199
212
|
'active:spr-background-color-pressed': true,
|
|
@@ -204,15 +217,21 @@
|
|
|
204
217
|
v-if="props.activeNav.menu === menuLinkItem.title"
|
|
205
218
|
class="spr-background-color-brand-base spr-absolute spr-left-0 spr-top-0 spr-h-full spr-w-[2px]"
|
|
206
219
|
></div>
|
|
207
|
-
|
|
208
|
-
<
|
|
209
|
-
<
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
220
|
+
|
|
221
|
+
<div class="spr-flex spr-w-full spr-items-center spr-justify-between spr-gap-1">
|
|
222
|
+
<span>{{ menuLinkItem.title }}</span>
|
|
223
|
+
|
|
224
|
+
<div class="spr-flex spr-items-center spr-gap-2">
|
|
225
|
+
<template v-for="(attribute, i) in convertAttributesToArray(menuLinkItem?.attributes)" :key="i">
|
|
226
|
+
<spr-lozenge
|
|
227
|
+
v-if="attribute?.name === 'lozenge' && attribute?.value"
|
|
228
|
+
:label="getLozengeLabel(attribute)"
|
|
229
|
+
:tone="getLozengeTone(attribute)"
|
|
230
|
+
fill
|
|
231
|
+
/>
|
|
232
|
+
</template>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
216
235
|
</div>
|
|
217
236
|
</template>
|
|
218
237
|
<!-- #endregion - Menu link only -->
|
|
@@ -279,7 +298,7 @@
|
|
|
279
298
|
|
|
280
299
|
<!-- Divider -->
|
|
281
300
|
<div
|
|
282
|
-
v-if="navLinks.
|
|
301
|
+
v-if="navLinks.length > 0 && navLinkIndex < navLinks.length - 1"
|
|
283
302
|
class="spr-background-color-hover spr-h-[2px] spr-w-full"
|
|
284
303
|
></div>
|
|
285
304
|
</div>
|
|
@@ -300,5 +319,8 @@ import SprTooltip from '../tooltip/tooltip.vue';
|
|
|
300
319
|
const props = defineProps(sidenavPropTypes);
|
|
301
320
|
const emit = defineEmits(sidenavEmitTypes);
|
|
302
321
|
|
|
303
|
-
const { handleRedirect, generateId, getLozengeLabel, getLozengeTone } = useSidenav(
|
|
322
|
+
const { handleRedirect, generateId, getLozengeLabel, getLozengeTone, convertAttributesToArray } = useSidenav(
|
|
323
|
+
props,
|
|
324
|
+
emit,
|
|
325
|
+
);
|
|
304
326
|
</script>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
2
|
|
|
3
|
+
import { LozengePropTypes } from '../lozenge/lozenge';
|
|
4
|
+
|
|
3
5
|
export type QuickAction = {
|
|
4
6
|
menuHeading: string;
|
|
5
7
|
items: QuickActionItem[];
|
|
@@ -32,7 +34,7 @@ export type ParentLinkItem = {
|
|
|
32
34
|
menuLinks: MenuLink[];
|
|
33
35
|
submenuLinks?: SubmenuLink[];
|
|
34
36
|
hidden?: boolean;
|
|
35
|
-
attributes?: Attributes[];
|
|
37
|
+
attributes?: Attributes[] | string;
|
|
36
38
|
};
|
|
37
39
|
|
|
38
40
|
export type MenuLink = {
|
|
@@ -44,7 +46,7 @@ export type MenuLinkItem = {
|
|
|
44
46
|
title: string;
|
|
45
47
|
hidden: boolean;
|
|
46
48
|
redirect: Redirect;
|
|
47
|
-
attributes?: Attributes[];
|
|
49
|
+
attributes?: Attributes[] | string;
|
|
48
50
|
submenuLinks: SubmenuLink[];
|
|
49
51
|
};
|
|
50
52
|
|
|
@@ -57,7 +59,7 @@ export type SubmenuLinkItem = {
|
|
|
57
59
|
title: string;
|
|
58
60
|
hidden: boolean;
|
|
59
61
|
redirect: Redirect;
|
|
60
|
-
attributes?: Attributes[];
|
|
62
|
+
attributes?: Attributes[] | string;
|
|
61
63
|
};
|
|
62
64
|
|
|
63
65
|
export type Redirect = {
|
|
@@ -88,7 +90,7 @@ export interface NavItem {
|
|
|
88
90
|
children?: NavItem[] | null;
|
|
89
91
|
groupName?: string | null;
|
|
90
92
|
hidden?: boolean;
|
|
91
|
-
attributes?: Attributes[] | null;
|
|
93
|
+
attributes?: Attributes[] | string | null;
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
export type Attributes = {
|
|
@@ -96,10 +98,7 @@ export type Attributes = {
|
|
|
96
98
|
value: unknown | string | number | boolean | AttrLozenge;
|
|
97
99
|
};
|
|
98
100
|
|
|
99
|
-
export type AttrLozenge =
|
|
100
|
-
label: string;
|
|
101
|
-
tone?: string;
|
|
102
|
-
};
|
|
101
|
+
export type AttrLozenge = LozengePropTypes;
|
|
103
102
|
|
|
104
103
|
export interface MappedNavItem {
|
|
105
104
|
title: string;
|
|
@@ -109,7 +108,7 @@ export interface MappedNavItem {
|
|
|
109
108
|
isAbsoluteURL: boolean;
|
|
110
109
|
link: string;
|
|
111
110
|
};
|
|
112
|
-
attributes?:
|
|
111
|
+
attributes?: Attributes[] | string | unknown[];
|
|
113
112
|
menuLinks?: {
|
|
114
113
|
menuHeading: string;
|
|
115
114
|
items: MappedNavItem[];
|
|
@@ -144,7 +144,11 @@
|
|
|
144
144
|
<!-- #endregion - Search -->
|
|
145
145
|
|
|
146
146
|
<!-- #region - Grouped Nav Links -->
|
|
147
|
-
<sidenav-menu-links
|
|
147
|
+
<sidenav-menu-links
|
|
148
|
+
:nav-links="navLinks.top"
|
|
149
|
+
:active-nav="props.activeNav"
|
|
150
|
+
@get-navlink-item="emit('get-navlink-item', $event)"
|
|
151
|
+
/>
|
|
148
152
|
<!-- #endregion - Grouped Nav Links -->
|
|
149
153
|
</div>
|
|
150
154
|
<!-- #endregion - Top Section -->
|
|
@@ -155,7 +159,11 @@
|
|
|
155
159
|
class="spr-grid spr-justify-center spr-gap-2 spr-px-3 spr-pb-4 spr-pt-0"
|
|
156
160
|
>
|
|
157
161
|
<!-- #region - Grouped Nav Links -->
|
|
158
|
-
<sidenav-menu-links
|
|
162
|
+
<sidenav-menu-links
|
|
163
|
+
:nav-links="navLinks.bottom"
|
|
164
|
+
:active-nav="props.activeNav"
|
|
165
|
+
@get-navlink-item="emit('get-navlink-item', $event)"
|
|
166
|
+
/>
|
|
159
167
|
<!-- #endregion - Grouped Nav Links -->
|
|
160
168
|
</div>
|
|
161
169
|
<!-- #endregion - Bottom Section -->
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { ref, onMounted } from 'vue';
|
|
1
|
+
import { ref, onMounted, watch } from 'vue';
|
|
2
|
+
|
|
3
|
+
import { LOZENGE_TONE } from '../lozenge/lozenge';
|
|
2
4
|
|
|
3
5
|
import type { SetupContext } from 'vue';
|
|
4
6
|
import type {
|
|
@@ -22,6 +24,7 @@ interface ObjectItem {
|
|
|
22
24
|
menu: string;
|
|
23
25
|
submenu: string;
|
|
24
26
|
};
|
|
27
|
+
attributes?: Attributes[] | string;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
export const useSidenav = (props: SidenavPropTypes, emit: SetupContext<SidenavEmitTypes>['emit']) => {
|
|
@@ -182,30 +185,80 @@ export const useSidenav = (props: SidenavPropTypes, emit: SetupContext<SidenavEm
|
|
|
182
185
|
return transformedData;
|
|
183
186
|
};
|
|
184
187
|
|
|
185
|
-
const getLozengeTone = (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
const getLozengeTone = (attributes: Attributes | string) => {
|
|
189
|
+
// Handle case where attr is a string (needs conversion)
|
|
190
|
+
if (!attributes) return;
|
|
191
|
+
|
|
192
|
+
let parsedAttributes;
|
|
193
|
+
|
|
194
|
+
if (typeof attributes === 'string') {
|
|
195
|
+
parsedAttributes = JSON.parse(attributes);
|
|
196
|
+
} else {
|
|
197
|
+
parsedAttributes = attributes;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (parsedAttributes.value.tone && LOZENGE_TONE.includes(parsedAttributes.value.tone)) {
|
|
201
|
+
return parsedAttributes.value.tone;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return 'neutral';
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const getLozengeLabel = (attributes: Attributes | string) => {
|
|
208
|
+
// Handle case where attr is a string (needs conversion)
|
|
209
|
+
if (!attributes) return;
|
|
210
|
+
|
|
211
|
+
let parsedAttributes;
|
|
212
|
+
|
|
213
|
+
if (typeof attributes === 'string') {
|
|
214
|
+
parsedAttributes = JSON.parse(attributes);
|
|
215
|
+
} else {
|
|
216
|
+
parsedAttributes = attributes;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (parsedAttributes.value.label) {
|
|
220
|
+
return String(parsedAttributes.value.label);
|
|
194
221
|
}
|
|
195
|
-
|
|
222
|
+
|
|
223
|
+
return '';
|
|
196
224
|
};
|
|
197
225
|
|
|
198
|
-
|
|
199
|
-
|
|
226
|
+
// Utility function to convert string attributes to array
|
|
227
|
+
const convertAttributesToArray = (attributes: string | Attributes[] | undefined): Attributes[] => {
|
|
228
|
+
if (!attributes) {
|
|
229
|
+
return [];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (typeof attributes === 'string') {
|
|
233
|
+
try {
|
|
234
|
+
const parsed = JSON.parse(attributes);
|
|
235
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
236
|
+
} catch {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return Array.isArray(attributes) ? attributes : [];
|
|
200
242
|
};
|
|
201
243
|
|
|
202
|
-
|
|
244
|
+
const setNavLinkItems = async () => {
|
|
203
245
|
if (props.isNavApi) {
|
|
204
246
|
navLinks.value = await transformedNavItems(props.navLinks);
|
|
205
247
|
} else {
|
|
206
|
-
// Use the original navLinks from props
|
|
207
248
|
navLinks.value = props.navLinks;
|
|
208
249
|
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
watch(
|
|
253
|
+
() => props.navLinks,
|
|
254
|
+
async () => {
|
|
255
|
+
await setNavLinkItems();
|
|
256
|
+
},
|
|
257
|
+
{ immediate: true },
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
onMounted(async () => {
|
|
261
|
+
await setNavLinkItems();
|
|
209
262
|
});
|
|
210
263
|
|
|
211
264
|
return {
|
|
@@ -217,5 +270,6 @@ export const useSidenav = (props: SidenavPropTypes, emit: SetupContext<SidenavEm
|
|
|
217
270
|
transformedNavItems,
|
|
218
271
|
getLozengeTone,
|
|
219
272
|
getLozengeLabel,
|
|
273
|
+
convertAttributesToArray,
|
|
220
274
|
};
|
|
221
275
|
};
|
|
@@ -51,10 +51,18 @@ export const tablePaginationPropTypes = {
|
|
|
51
51
|
type: Boolean as PropType<boolean>,
|
|
52
52
|
default: true,
|
|
53
53
|
},
|
|
54
|
+
/**
|
|
55
|
+
* @description Toggle editable state for current page input
|
|
56
|
+
*/
|
|
57
|
+
editableCurrentPage: {
|
|
58
|
+
type: Boolean as PropType<boolean>,
|
|
59
|
+
default: false,
|
|
60
|
+
},
|
|
54
61
|
};
|
|
55
62
|
|
|
56
63
|
export const tablePaginationEmitTypes = {
|
|
57
64
|
'update:selectedRowCount': (value: number): value is number => typeof value === 'number',
|
|
65
|
+
'update:currentPage': (value: number): value is number => typeof value === 'number',
|
|
58
66
|
previous: () => true,
|
|
59
67
|
next: () => true,
|
|
60
68
|
};
|
|
@@ -16,9 +16,22 @@
|
|
|
16
16
|
</spr-dropdown>
|
|
17
17
|
|
|
18
18
|
<div :class="paginationClasses.rightSideClass">
|
|
19
|
-
<div
|
|
20
|
-
|
|
19
|
+
<div v-if="editableCurrentPage" class="spr-flex spr-flex-row spr-items-center spr-gap-size-spacing-4xs">
|
|
20
|
+
<span class="spr-body-xs-regular spr-text-color-base">Page</span>
|
|
21
|
+
<input
|
|
22
|
+
v-model="currentPage" type="number" min="1" :max="totalPages"
|
|
23
|
+
class="number-input
|
|
24
|
+
spr-text-center spr-font-main spr-font-medium spr-font-size-200 spr-font-height-300 sp-text-color-strong
|
|
25
|
+
spr-p-size-spacing-3xs spr-rounded-border-radius-md spr-border spr-border-solid spr-border-color-base spr-outline-none
|
|
26
|
+
spr-min-w-[48px] spr-max-h-[36px] spr-w-[48px] spr-h-[32px] spr-box-border"
|
|
27
|
+
/>
|
|
28
|
+
<span class="spr-body-xs-regular spr-text-color-base">of {{ totalPages }}</span>
|
|
21
29
|
</div>
|
|
30
|
+
<template v-else>
|
|
31
|
+
<div :class="paginationClasses.computeRowRangeClass">
|
|
32
|
+
{{ computeRowRange }}
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
22
35
|
<div :class="paginationClasses.navigationContainerClass">
|
|
23
36
|
<spr-button
|
|
24
37
|
id="previousButton"
|
|
@@ -68,5 +81,19 @@ const {
|
|
|
68
81
|
disabledPrevious,
|
|
69
82
|
dropdownSelection,
|
|
70
83
|
dropdownId,
|
|
84
|
+
currentPage,
|
|
85
|
+
totalPages,
|
|
71
86
|
} = useTablePagination(props, emit);
|
|
72
87
|
</script>
|
|
88
|
+
|
|
89
|
+
<style scoped>
|
|
90
|
+
.number-input::-webkit-outer-spin-button,
|
|
91
|
+
.number-input::-webkit-inner-spin-button {
|
|
92
|
+
margin: 0;
|
|
93
|
+
-webkit-appearance: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.number-input {
|
|
97
|
+
-moz-appearance: textfield;
|
|
98
|
+
}
|
|
99
|
+
</style>
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
TablePaginationPropTypes,
|
|
6
6
|
TablePaginationEmitTypes,
|
|
7
7
|
} from '@/components/table/table-pagination/table-pagination';
|
|
8
|
+
import { useVModel } from '@vueuse/core';
|
|
8
9
|
|
|
9
10
|
interface TablePaginationClasses {
|
|
10
11
|
baseClass: string;
|
|
@@ -21,7 +22,9 @@ export const useTablePagination = (
|
|
|
21
22
|
props: TablePaginationPropTypes,
|
|
22
23
|
emit: SetupContext<TablePaginationEmitTypes>['emit'],
|
|
23
24
|
) => {
|
|
24
|
-
const { selectedRowCount,
|
|
25
|
+
const { selectedRowCount, totalItems, bordered, editableCurrentPage } = toRefs(props);
|
|
26
|
+
|
|
27
|
+
const currentPage = useVModel(props, 'currentPage', emit);
|
|
25
28
|
|
|
26
29
|
const paginationClasses: ComputedRef<TablePaginationClasses> = computed(() => {
|
|
27
30
|
const baseClass = classNames('spr-p-size-spacing-xs spr-flex spr-justify-between spr-bg-white-50 spr-h-max', {
|
|
@@ -30,9 +33,21 @@ export const useTablePagination = (
|
|
|
30
33
|
});
|
|
31
34
|
const dropdownInputFieldClass = classNames('spr-w-[120px] spr-h-full spr-space-x-2');
|
|
32
35
|
const inputFieldIconClass = classNames('spr-mt-0.5 spr-pl-1 spr-text-mushroom-950');
|
|
33
|
-
const rightSideClass = classNames(
|
|
36
|
+
const rightSideClass = classNames(
|
|
37
|
+
'spr-flex spr-justify-between spr-items-center',
|
|
38
|
+
{
|
|
39
|
+
'spr-space-x-4': !editableCurrentPage.value,
|
|
40
|
+
'spr-gap-size-spacing-3xs': editableCurrentPage.value
|
|
41
|
+
}
|
|
42
|
+
);
|
|
34
43
|
const computeRowRangeClass = classNames('spr-text-color-base spr-body-sm-regular');
|
|
35
|
-
const navigationContainerClass = classNames(
|
|
44
|
+
const navigationContainerClass = classNames(
|
|
45
|
+
'spr-flex',
|
|
46
|
+
{
|
|
47
|
+
'spr-space-x-2': !editableCurrentPage.value,
|
|
48
|
+
'spr-gap-size-spacing-5xs': editableCurrentPage.value
|
|
49
|
+
}
|
|
50
|
+
);
|
|
36
51
|
const navigationButtonClass = classNames('spr-rounded-border-radius-md');
|
|
37
52
|
const dropdownClass = classNames('!spr-w-max');
|
|
38
53
|
return {
|
|
@@ -58,7 +73,7 @@ export const useTablePagination = (
|
|
|
58
73
|
return `${selectedRowCount.value} Rows`;
|
|
59
74
|
});
|
|
60
75
|
|
|
61
|
-
const handleSelectedItem = (item:
|
|
76
|
+
const handleSelectedItem = (item: unknown) => {
|
|
62
77
|
emit('update:selectedRowCount', Number(item));
|
|
63
78
|
};
|
|
64
79
|
|
|
@@ -87,6 +102,11 @@ export const useTablePagination = (
|
|
|
87
102
|
|
|
88
103
|
const dropdownId = ref(`dropdown-${generateUniqueId()}`);
|
|
89
104
|
|
|
105
|
+
// Get total number of pages
|
|
106
|
+
const totalPages = computed(() => {
|
|
107
|
+
return Math.ceil(props.totalItems / props.selectedRowCount);
|
|
108
|
+
});
|
|
109
|
+
|
|
90
110
|
return {
|
|
91
111
|
paginationClasses,
|
|
92
112
|
handleSelectedItem,
|
|
@@ -98,5 +118,7 @@ export const useTablePagination = (
|
|
|
98
118
|
disabledPrevious,
|
|
99
119
|
dropdownSelection,
|
|
100
120
|
dropdownId,
|
|
121
|
+
currentPage,
|
|
122
|
+
totalPages,
|
|
101
123
|
};
|
|
102
124
|
};
|
|
@@ -21,7 +21,10 @@
|
|
|
21
21
|
<table aria-describedby="describe" class="spr-h-full spr-w-full spr-table-fixed" cellspacing="0" cellpadding="0">
|
|
22
22
|
<thead>
|
|
23
23
|
<tr v-if="!(props.removeHeaderOnEmpty && sortedData.length <= 0)">
|
|
24
|
-
<th
|
|
24
|
+
<th
|
|
25
|
+
v-if="props.isMultiSelect"
|
|
26
|
+
:class="[getTableClasses.multiselectClass, getTableClasses.headerClasses(null)]"
|
|
27
|
+
>
|
|
25
28
|
<div class="spr-flex spr-items-center spr-justify-center">
|
|
26
29
|
<spr-checkbox
|
|
27
30
|
label=""
|
|
@@ -31,7 +34,11 @@
|
|
|
31
34
|
/>
|
|
32
35
|
</div>
|
|
33
36
|
</th>
|
|
34
|
-
<th
|
|
37
|
+
<th
|
|
38
|
+
v-for="(header, keyHeader) in headers"
|
|
39
|
+
:key="keyHeader"
|
|
40
|
+
:class="[getTableClasses.headerClasses(header)]"
|
|
41
|
+
>
|
|
35
42
|
<div :class="getTableClasses.headerNameClass">
|
|
36
43
|
<span :class="[{ 'spr-cursor-pointer': header.sort }]" @click="header.sort && sortData(header.field)">
|
|
37
44
|
{{ header.name }}
|
|
@@ -60,7 +67,7 @@
|
|
|
60
67
|
</th>
|
|
61
68
|
|
|
62
69
|
<!-- for action Button -->
|
|
63
|
-
<th v-if="action" :class="getTableClasses.headerClasses">
|
|
70
|
+
<th v-if="action" :class="getTableClasses.headerClasses(null)">
|
|
64
71
|
<slot name="action-name" :class="getTableClasses.tableCellSlotClasses" />
|
|
65
72
|
</th>
|
|
66
73
|
</tr>
|
|
@@ -86,7 +86,7 @@ export const useTable = (props: TablePropTypes, emit: SetupContext<TableEmitType
|
|
|
86
86
|
|
|
87
87
|
const getTableClasses = computed(() => {
|
|
88
88
|
const tableWrapperClasses = classNames(
|
|
89
|
-
'spr-flex spr-flex-col spr-h-full spr-border-color-weak spr-w-full spr-overflow-hidden spr-rounded-border-radius-lg spr-border spr-border-solid spr-table-wrapper spr-relative',
|
|
89
|
+
'spr-flex spr-flex-col spr-h-full spr-border-color-weak spr-w-full spr-overflow-hidden spr-rounded-border-radius-lg spr-border spr-border-solid spr-table-wrapper spr-relative spr-font-main',
|
|
90
90
|
);
|
|
91
91
|
const tableFooterClasses = classNames('spr-w-full spr-bottom-0 spr-left-0', {
|
|
92
92
|
'spr-background-color-surface': props.variant === 'surface',
|
|
@@ -97,7 +97,7 @@ export const useTable = (props: TablePropTypes, emit: SetupContext<TableEmitType
|
|
|
97
97
|
'spr-background-color-surface': props.variant === 'surface',
|
|
98
98
|
});
|
|
99
99
|
const headerClasses = (header: Header | null) => {
|
|
100
|
-
if (header?.customTailwindClasses){
|
|
100
|
+
if (header?.customTailwindClasses) {
|
|
101
101
|
return classNames(header.customTailwindClasses);
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -107,9 +107,10 @@ export const useTable = (props: TablePropTypes, emit: SetupContext<TableEmitType
|
|
|
107
107
|
'spr-border-color-weak spr-border-x-0 spr-border-y spr-border-solid',
|
|
108
108
|
{
|
|
109
109
|
'spr-border-t-0': !slots.default,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
},
|
|
111
|
+
headerBackground,
|
|
112
|
+
);
|
|
113
|
+
};
|
|
113
114
|
|
|
114
115
|
const headerNameClass = 'spr-flex spr-flex-row spr-items-center spr-gap-size-spacing-5xs';
|
|
115
116
|
|
|
@@ -44,7 +44,7 @@ export const useTextArea = (props: TextAreaPropTypes, emit: SetupContext<TextAre
|
|
|
44
44
|
'spr-text-color-supporting': !error.value,
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
const slotWrapperClasses = classNames('spr-flex spr-items-
|
|
47
|
+
const slotWrapperClasses = classNames('spr-flex spr-items-start', {
|
|
48
48
|
'spr-justify-between': props.displayHelper && props.hasCounter,
|
|
49
49
|
'spr-justify-end': !props.displayHelper && props.hasCounter,
|
|
50
50
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
|
|
3
|
+
const data = ref([
|
|
4
|
+
...Array.from({ length: 100 }, (_, i) => ({
|
|
5
|
+
name: {
|
|
6
|
+
title: `Shift ${i + 1}`,
|
|
7
|
+
subtext: `Lorem ipsectetur adipiscing elit. Sed etiam, sed etiam. Item ${i + 1}`,
|
|
8
|
+
image: `https://media.sproutsocial.com/uploads/2022/06/profile-picture.jpeg`,
|
|
9
|
+
},
|
|
10
|
+
lastUpdate: {
|
|
11
|
+
title: `Nov ${((i % 30) + 1)}, 2025`,
|
|
12
|
+
subtext: `Lorem ipsum dolor item ${i + 1}`,
|
|
13
|
+
image: `https://media.sproutsocial.com/uploads/2022/06/profile-picture.jpeg`,
|
|
14
|
+
},
|
|
15
|
+
status: {
|
|
16
|
+
title: ['Success', 'Pending', 'Failed'][i % 3],
|
|
17
|
+
subtext: `Lorem ipsum dolor sit amet, consectetur, sed etiam. Status ${i + 1}`,
|
|
18
|
+
image: `https://media.sproutsocial.com/uploads/2022/06/profile-picture.jpeg`,
|
|
19
|
+
},
|
|
20
|
+
}))
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
export default data;
|