design-system-next 2.23.0 → 2.24.2
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.d.ts +28 -6
- package/dist/design-system-next.es.js +7544 -7332
- 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/package.json +1 -1
- package/src/App.vue +89 -1
- package/src/components/date-picker/date-picker.vue +2 -2
- package/src/components/date-picker/use-date-picker.ts +41 -33
- package/src/components/dropdown/dropdown.ts +6 -2
- package/src/components/dropdown/dropdown.vue +8 -1
- package/src/components/dropdown/use-dropdown.ts +13 -0
- package/src/components/list/list-item/list-item.ts +60 -60
- package/src/components/radio-grouped/radio-grouped.ts +65 -65
- package/src/components/radio-grouped/use-radio-grouped.ts +62 -62
- package/src/components/sidepanel/sidepanel.ts +4 -0
- package/src/components/sidepanel/sidepanel.vue +3 -1
- package/src/components/sidepanel/use-sidepanel.ts +3 -2
- package/src/components/table/table-header-dropdown/table-header-dropdown.ts +48 -0
- package/src/components/table/table-header-dropdown/table-header-dropdown.vue +84 -0
- package/src/components/table/table-pagination/table-pagination.ts +4 -0
- package/src/components/table/table-pagination/table-pagination.vue +9 -1
- package/src/components/table/table-pagination/use-table-pagination.ts +4 -3
- package/src/components/table/table.ts +9 -1
- package/src/components/table/table.vue +17 -2
- package/src/components/table/use-table.ts +6 -1
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
aria-labelledby="sidepanel-title"
|
|
18
18
|
aria-describedby="sidepanel-content"
|
|
19
19
|
:class="sidepanelClasses.sidepanelBaseClasses"
|
|
20
|
+
data-testid="sidepanel-dialog"
|
|
20
21
|
:style="{ height: typeof height === 'number' ? `${height}px` : height }"
|
|
21
22
|
>
|
|
22
23
|
<template v-if="!props.hideHeader">
|
|
@@ -29,9 +30,10 @@
|
|
|
29
30
|
v-if="props.isExpandable"
|
|
30
31
|
:class="sidepanelClasses.sidepanelHeaderIconClasses"
|
|
31
32
|
:icon="isExpanded ? 'ph:arrows-in-simple' : 'ph:arrows-out-simple'"
|
|
33
|
+
data-testid="expand-icon"
|
|
32
34
|
@click="handlePanelExpansion"
|
|
33
35
|
/>
|
|
34
|
-
<Icon :class="sidepanelClasses.sidepanelHeaderIconClasses" icon="ph:x" @click="handleClose" />
|
|
36
|
+
<Icon :class="sidepanelClasses.sidepanelHeaderIconClasses" icon="ph:x" data-testid="x-icon" @click="handleClose" />
|
|
35
37
|
</div>
|
|
36
38
|
</div>
|
|
37
39
|
<div v-else>
|
|
@@ -19,7 +19,7 @@ interface SidepanelClasses {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export const useSidepanel = (props: SidepanelPropTypes, emit: SetupContext<SidepanelEmitTypes>['emit']) => {
|
|
22
|
-
const { size, position, isStacking, footerNoPadding, isExpanded, isActivePanel } = toRefs(props);
|
|
22
|
+
const { size, position, isStacking, footerNoPadding, isExpanded, isActivePanel, footerNoTopBorder } = toRefs(props);
|
|
23
23
|
|
|
24
24
|
const sidepanelClasses: ComputedRef<SidepanelClasses> = computed(() => {
|
|
25
25
|
const sidepanelBaseClasses = classNames(
|
|
@@ -48,9 +48,10 @@ export const useSidepanel = (props: SidepanelPropTypes, emit: SetupContext<Sidep
|
|
|
48
48
|
const sidepanelContentClasses = classNames('spr-h-full spr-overflow-y-auto');
|
|
49
49
|
|
|
50
50
|
const sidepanelFooterClasses = classNames(
|
|
51
|
-
'spr-bottom-0 spr-left-0 spr-w-full spr-rounded-b-border-radius-xl spr-border-0 spr-border-
|
|
51
|
+
'spr-bottom-0 spr-left-0 spr-w-full spr-rounded-b-border-radius-xl spr-border-0 spr-border-solid spr-border-mushroom-200 spr-bg-white-50 ',
|
|
52
52
|
{
|
|
53
53
|
'spr-py-3': !footerNoPadding.value,
|
|
54
|
+
'spr-border-t': !footerNoTopBorder.value
|
|
54
55
|
},
|
|
55
56
|
);
|
|
56
57
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { MenuListType } from '@/components/list/list';
|
|
2
|
+
import { type PropType, type ExtractPropTypes, ref } from 'vue';
|
|
3
|
+
import type { Header } from '../table';
|
|
4
|
+
export const definePropType = <T>(val: unknown): PropType<T> => val as PropType<T>;
|
|
5
|
+
|
|
6
|
+
const defaultSortOptions = ref([
|
|
7
|
+
{ text: 'Sort Ascending', value: 'asc', icon: 'ph:sort-ascending', iconColor: 'spr-text-color-supporting' },
|
|
8
|
+
{ text: 'Sort Descending', value: 'desc', icon: 'ph:sort-descending', iconColor: 'spr-text-color-supporting' },
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
export const tableHeaderDropdownPropTypes = {
|
|
12
|
+
id: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: true,
|
|
15
|
+
},
|
|
16
|
+
header: {
|
|
17
|
+
type: Object as PropType<Header>,
|
|
18
|
+
default: () => ({}),
|
|
19
|
+
},
|
|
20
|
+
isSortable: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: true,
|
|
23
|
+
},
|
|
24
|
+
headerClasses: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: '',
|
|
27
|
+
},
|
|
28
|
+
sortOptions: {
|
|
29
|
+
type: Array as PropType<MenuListType[]>,
|
|
30
|
+
default: () => defaultSortOptions.value,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export interface TableHeaderFilterType {
|
|
35
|
+
headerField: string;
|
|
36
|
+
sortBy: 'asc' | 'desc' | null;
|
|
37
|
+
appliedFilters: Record<string, string>;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const tableHeaderDropdownEmitTypes = {
|
|
41
|
+
onApplyFilter: (filter: TableHeaderFilterType) => !!filter,
|
|
42
|
+
onSelectAll: () => true,
|
|
43
|
+
'update:selectedSort': (selectedSort: MenuListType[]) => Array.isArray(selectedSort),
|
|
44
|
+
'update:selectedFilters': (selectedFilters: MenuListType[]) => Array.isArray(selectedFilters),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type TableHeaderDropdownPropTypes = ExtractPropTypes<typeof tableHeaderDropdownPropTypes>;
|
|
48
|
+
export type TableHeaderDropdownEmitTypes = typeof tableHeaderDropdownEmitTypes;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<spr-dropdown
|
|
3
|
+
:id="props.id"
|
|
4
|
+
ref="tableHeaderDropdown"
|
|
5
|
+
width="100%"
|
|
6
|
+
:triggers="[]"
|
|
7
|
+
:popper-triggers="['click']"
|
|
8
|
+
popper-width="448px"
|
|
9
|
+
no-padding
|
|
10
|
+
>
|
|
11
|
+
<div :class="props.headerClasses" @click="showDropdown">
|
|
12
|
+
<span> {{ props.header.name }} </span>
|
|
13
|
+
<span>
|
|
14
|
+
<Icon class="spr-text-[#4B685E] !spr-justify-normal" icon="ph:funnel-simple" height="20px" width="20px" />
|
|
15
|
+
</span>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<template #popper>
|
|
19
|
+
<spr-card class="spr-font-main" border-width="0px" :has-content-padding="false" show-header>
|
|
20
|
+
<template #header>
|
|
21
|
+
<div class="spr-w-full spr-border-0 spr-border-b spr-border-solid spr-border-color-weak spr-p-size-spacing-xs spr-flex spr-flex-row spr-justify-between spr-items-center">
|
|
22
|
+
<span class="spr-subheading-xs spr-capitalize">{{ props.header.name }}</span>
|
|
23
|
+
<spr-button size="small" variant="secondary" @click="selectAll">Select All</spr-button>
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
<template #content>
|
|
27
|
+
<div v-if="props.isSortable" class="spr-border-0 spr-border-b spr-border-solid spr-border-color-weak">
|
|
28
|
+
<spr-list v-model="selectedSort" class="spr-capitalize spr-body-sm-regular spr-text-color-strong [&_svg]:spr-w-[16px] [&_svg]:spr-h-[16px] [&_svg.spr-text-color-brand-base]:spr-hidden" :menu-list="props.sortOptions"/>
|
|
29
|
+
</div>
|
|
30
|
+
<div v-if="props.header.filterList && props.header.filterList.length > 0" >
|
|
31
|
+
<spr-list v-model="selectedFilters" class="spr-capitalize spr-body-sm-regular spr-text-color-strong [&_svg]:spr-w-[16px] [&_svg]:spr-h-[16px]" :menu-list="props.header.filterList" multi-select/>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
<template #footer>
|
|
35
|
+
<div class="spr-ms-auto spr-flex spr-items-center spr-py-size-spacing-5xs">
|
|
36
|
+
<spr-button tone="success" @click="applyFilter">Apply Filter</spr-button>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
</spr-card>
|
|
40
|
+
</template>
|
|
41
|
+
</spr-dropdown>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<script setup lang="ts">
|
|
45
|
+
import SprDropdown from '@/components/dropdown/dropdown.vue';
|
|
46
|
+
import SprCard from '@/components/card/card.vue';
|
|
47
|
+
import SprButton from '@/components/button/button.vue';
|
|
48
|
+
import SprList from '@/components/list/list.vue';
|
|
49
|
+
import Icon from '@/components/icon/icon.vue';
|
|
50
|
+
import {
|
|
51
|
+
tableHeaderDropdownEmitTypes,
|
|
52
|
+
tableHeaderDropdownPropTypes
|
|
53
|
+
} from './table-header-dropdown';
|
|
54
|
+
import { ref } from 'vue';
|
|
55
|
+
import { MenuListType } from '@/components/list/list';
|
|
56
|
+
|
|
57
|
+
const tableHeaderDropdown = ref<InstanceType<typeof SprDropdown> | null>(null);
|
|
58
|
+
const showDropdown = () => {
|
|
59
|
+
tableHeaderDropdown.value?.showDropdown();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const props = defineProps(tableHeaderDropdownPropTypes);
|
|
63
|
+
const emits = defineEmits(tableHeaderDropdownEmitTypes,);
|
|
64
|
+
|
|
65
|
+
const selectedSort = ref<MenuListType[]>([]);
|
|
66
|
+
const selectedFilters = ref<MenuListType[]>([]);
|
|
67
|
+
|
|
68
|
+
const applyFilter = () => {
|
|
69
|
+
emits('onApplyFilter', {
|
|
70
|
+
headerField: props.header.field,
|
|
71
|
+
sortBy: selectedSort.value[0] ? selectedSort.value[0].value as 'asc' | 'desc' | null : null,
|
|
72
|
+
appliedFilters: selectedFilters.value.reduce((acc, filter) => {
|
|
73
|
+
acc[filter.text] = filter.value as string;
|
|
74
|
+
return acc;
|
|
75
|
+
}, {} as Record<string, string>),
|
|
76
|
+
});
|
|
77
|
+
tableHeaderDropdown.value?.hideDropdown();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const selectAll = () => {
|
|
81
|
+
selectedFilters.value = props.header.filterList ? [...props.header.filterList] : [];
|
|
82
|
+
emits('onSelectAll');
|
|
83
|
+
};
|
|
84
|
+
</script>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="paginationClasses.baseClass">
|
|
2
|
+
<div :class="paginationClasses.baseClass" v-bind="$attrs">
|
|
3
|
+
|
|
3
4
|
<spr-dropdown
|
|
5
|
+
v-if="showNumberOfRowsDropdown"
|
|
4
6
|
:id="dropdownId"
|
|
5
7
|
:menu-list="dropdownSelection"
|
|
6
8
|
dropdown-type="single-select"
|
|
@@ -53,6 +55,9 @@
|
|
|
53
55
|
</spr-button>
|
|
54
56
|
</div>
|
|
55
57
|
</div>
|
|
58
|
+
<div v-if="slots.actions" id="table_pagination_actions_slot">
|
|
59
|
+
<slot name="actions" />
|
|
60
|
+
</div>
|
|
56
61
|
</div>
|
|
57
62
|
</template>
|
|
58
63
|
|
|
@@ -65,8 +70,10 @@ import { useTablePagination } from './use-table-pagination';
|
|
|
65
70
|
import SprInput from '@/components/input/input.vue';
|
|
66
71
|
import SprButton from '@/components/button/button.vue';
|
|
67
72
|
import SprDropdown from '@/components/dropdown/dropdown.vue';
|
|
73
|
+
import { useSlots } from 'vue';
|
|
68
74
|
|
|
69
75
|
const emit = defineEmits(tablePaginationEmitTypes);
|
|
76
|
+
const slots = useSlots();
|
|
70
77
|
|
|
71
78
|
const props = defineProps(tablePaginationPropTypes);
|
|
72
79
|
|
|
@@ -83,6 +90,7 @@ const {
|
|
|
83
90
|
dropdownId,
|
|
84
91
|
currentPage,
|
|
85
92
|
totalPages,
|
|
93
|
+
showNumberOfRowsDropdown
|
|
86
94
|
} = useTablePagination(props, emit);
|
|
87
95
|
</script>
|
|
88
96
|
|
|
@@ -22,7 +22,7 @@ export const useTablePagination = (
|
|
|
22
22
|
props: TablePaginationPropTypes,
|
|
23
23
|
emit: SetupContext<TablePaginationEmitTypes>['emit'],
|
|
24
24
|
) => {
|
|
25
|
-
const { selectedRowCount, totalItems, bordered, editableCurrentPage } = toRefs(props);
|
|
25
|
+
const { selectedRowCount, totalItems, bordered, editableCurrentPage, showNumberOfRowsDropdown } = toRefs(props);
|
|
26
26
|
|
|
27
27
|
const currentPage = useVModel(props, 'currentPage', emit);
|
|
28
28
|
|
|
@@ -67,13 +67,13 @@ export const useTablePagination = (
|
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
const dropdownSelection = ref(props.dropdownSelection);
|
|
70
|
-
const computeRowRange = computed(() => {
|
|
70
|
+
const computeRowRange = computed(() => {
|
|
71
71
|
const startRow = (currentPage.value - 1) * selectedRowCount.value + 1;
|
|
72
72
|
const endRow = Math.min(currentPage.value * selectedRowCount.value, totalItems.value);
|
|
73
73
|
return `${startRow} - ${endRow} of ${totalItems.value}`;
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
const computeSelectedRowCount = computed(() => {
|
|
76
|
+
const computeSelectedRowCount = computed(() => {
|
|
77
77
|
return `${selectedRowCount.value} Rows`;
|
|
78
78
|
});
|
|
79
79
|
|
|
@@ -124,5 +124,6 @@ export const useTablePagination = (
|
|
|
124
124
|
dropdownId,
|
|
125
125
|
currentPage,
|
|
126
126
|
totalPages,
|
|
127
|
+
showNumberOfRowsDropdown
|
|
127
128
|
};
|
|
128
129
|
};
|
|
@@ -2,6 +2,8 @@ import type { PropType, ExtractPropTypes } from 'vue';
|
|
|
2
2
|
import type { ChipTitle } from '@/components/table/table-chips-title/table-chips-title';
|
|
3
3
|
import type { LozengeTitle } from '@/components/table/table-lozenge-title/table-lozenge-title';
|
|
4
4
|
import { type SortableEvent } from 'sortablejs';
|
|
5
|
+
import type { MenuListType } from '../list/list';
|
|
6
|
+
import type { TableHeaderFilterType } from './table-header-dropdown/table-header-dropdown';
|
|
5
7
|
export const definePropType = <T>(val: unknown): PropType<T> => val as PropType<T>;
|
|
6
8
|
|
|
7
9
|
export interface Header {
|
|
@@ -18,6 +20,7 @@ export interface Header {
|
|
|
18
20
|
avatarVariant?: string;
|
|
19
21
|
customTailwindClasses?: string;
|
|
20
22
|
width?: string;
|
|
23
|
+
filterList?: MenuListType[]; // List of filter options for table header dropdown
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
export interface TableData {
|
|
@@ -183,6 +186,10 @@ export const tablePropTypes = {
|
|
|
183
186
|
retainSelectionOnDataChange: {
|
|
184
187
|
type: Boolean,
|
|
185
188
|
default: false,
|
|
189
|
+
},
|
|
190
|
+
showHeaderFilter: {
|
|
191
|
+
type: Boolean,
|
|
192
|
+
default: false,
|
|
186
193
|
}
|
|
187
194
|
};
|
|
188
195
|
|
|
@@ -202,7 +209,8 @@ export const tableEmitTypes = {
|
|
|
202
209
|
onDragAdd: (event: DragOnAddEvent): event is DragOnAddEvent =>
|
|
203
210
|
event !== undefined && Array.isArray(event.updatedList),
|
|
204
211
|
onDragRemove: (event: DragOnRemoveEvent): event is DragOnRemoveEvent =>
|
|
205
|
-
event !== undefined && Array.isArray(event.updatedList),
|
|
212
|
+
event !== undefined && Array.isArray(event.updatedList),
|
|
213
|
+
onApplyFilter: (filter: TableHeaderFilterType) => !!filter,
|
|
206
214
|
};
|
|
207
215
|
|
|
208
216
|
export type TablePropTypes = ExtractPropTypes<typeof tablePropTypes>;
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<table
|
|
21
21
|
:key="tableKey"
|
|
22
22
|
aria-describedby="describe"
|
|
23
|
-
class="spr-h-full spr-w-full
|
|
23
|
+
class="spr-h-full spr-w-full"
|
|
24
24
|
cellspacing="0"
|
|
25
25
|
cellpadding="0"
|
|
26
26
|
>
|
|
@@ -45,7 +45,18 @@
|
|
|
45
45
|
:class="[getTableClasses.headerClasses(header)]"
|
|
46
46
|
:style="{ width: header?.width }"
|
|
47
47
|
>
|
|
48
|
-
|
|
48
|
+
<!-- Header with Dropdown Filter -->
|
|
49
|
+
<spr-table-header-dropdown
|
|
50
|
+
v-if="props.showHeaderFilter"
|
|
51
|
+
:id="`th-dropdown-${keyHeader}`"
|
|
52
|
+
:header="header"
|
|
53
|
+
:is-sortable="true"
|
|
54
|
+
:header-classes="getTableClasses.headerNameClass"
|
|
55
|
+
:filter-options="header.filterList"
|
|
56
|
+
@on-apply-filter="(filters) => emit('onApplyFilter', filters)"
|
|
57
|
+
/>
|
|
58
|
+
<!-- Default Header -->
|
|
59
|
+
<div v-else :class="getTableClasses.headerNameClass">
|
|
49
60
|
<span :class="[{ 'spr-cursor-pointer': header.sort }]" @click="header.sort && sortData(header.field)">
|
|
50
61
|
{{ header.name }}
|
|
51
62
|
</span>
|
|
@@ -69,6 +80,9 @@
|
|
|
69
80
|
:class="[{ 'spr-text-kangkong-700': sortField === header.field }]"
|
|
70
81
|
/>
|
|
71
82
|
</span>
|
|
83
|
+
<span v-if="props.showHeaderFilter">
|
|
84
|
+
<Icon icon="ph:funnel-simple" height="20" width="20" class="spr-ml-size-spacing-5xs spr-text-[#4B685E]" />
|
|
85
|
+
</span>
|
|
72
86
|
</div>
|
|
73
87
|
</th>
|
|
74
88
|
|
|
@@ -213,6 +227,7 @@ import SprTableActions from '@/components/table/table-actions/table-actions.vue'
|
|
|
213
227
|
import SprTableLozengeTitle from '@/components/table/table-lozenge-title/table-lozenge-title.vue';
|
|
214
228
|
import SprTableChipsTitle from '@/components/table/table-chips-title/table-chips-title.vue';
|
|
215
229
|
import SprCheckbox from '@/components/checkbox/checkbox.vue';
|
|
230
|
+
import SprTableHeaderDropdown from '@/components/table/table-header-dropdown/table-header-dropdown.vue';
|
|
216
231
|
|
|
217
232
|
import { tablePropTypes, tableEmitTypes } from './table';
|
|
218
233
|
import type { ChipTitle } from '@/components/table/table-chips-title/table-chips-title';
|
|
@@ -198,7 +198,11 @@ export const useTable = (props: TablePropTypes, emit: SetupContext<TableEmitType
|
|
|
198
198
|
|
|
199
199
|
const getTableClasses = computed(() => {
|
|
200
200
|
const tableWrapperClasses = classNames(
|
|
201
|
-
'spr-flex spr-flex-col spr-h-full spr-border-color-weak spr-w-full spr-overflow-
|
|
201
|
+
'spr-flex spr-flex-col spr-h-full spr-border-color-weak spr-w-full spr-overflow-auto spr-rounded-border-radius-lg spr-border spr-border-solid spr-table-wrapper spr-relative spr-font-main',
|
|
202
|
+
{
|
|
203
|
+
'spr-overflow-hidden': isDraggable.value,
|
|
204
|
+
'spr-overflow-auto': !isDraggable.value,
|
|
205
|
+
}
|
|
202
206
|
);
|
|
203
207
|
const tableFooterClasses = classNames('spr-w-full spr-bottom-0 spr-left-0', {
|
|
204
208
|
'spr-background-color-surface': props.variant === 'surface',
|
|
@@ -219,6 +223,7 @@ export const useTable = (props: TablePropTypes, emit: SetupContext<TableEmitType
|
|
|
219
223
|
'spr-border-color-weak spr-border-x-0 spr-border-y spr-border-solid',
|
|
220
224
|
{
|
|
221
225
|
'spr-border-t-0': !slots.default,
|
|
226
|
+
'spr-cursor-pointer hover:spr-background-color-hover active:spr-background-color-pressed': props.showHeaderFilter,
|
|
222
227
|
},
|
|
223
228
|
headerBackground,
|
|
224
229
|
);
|