vueless 0.0.497 → 0.0.499
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/package.json +1 -1
- package/types.ts +2 -0
- package/ui.data-table/UTable.vue +415 -458
- package/ui.data-table/UTableRow.vue +234 -253
- package/ui.data-table/{config.js → config.ts} +3 -10
- package/ui.data-table/storybook/Docs.mdx +2 -2
- package/ui.data-table/storybook/{stories.js → stories.ts} +65 -50
- package/ui.data-table/types.ts +142 -0
- package/ui.data-table/{useAttrs.js → useAttrs.ts} +32 -14
- package/ui.data-table/{utilTable.js → utilTable.ts} +24 -18
- package/ui.form-calendar/UCalendar.vue +1 -1
- package/utils/node/mergeConfigs.js +42 -11
- package/web-types.json +36 -21
- /package/ui.data-table/{constants.js → constants.ts} +0 -0
|
@@ -1,13 +1,23 @@
|
|
|
1
|
+
import type { Meta, StoryFn } from "@storybook/vue3";
|
|
1
2
|
import { getArgTypes, getSlotNames, getSlotsFragment } from "../../utils/storybook.ts";
|
|
2
3
|
import { getRandomId } from "../../utils/ui.ts";
|
|
3
4
|
|
|
4
|
-
import UTable from "
|
|
5
|
+
import UTable from "../UTable.vue";
|
|
5
6
|
import UButton from "../../ui.button/UButton.vue";
|
|
6
7
|
import ULink from "../../ui.button-link/ULink.vue";
|
|
7
8
|
import UMoney from "../../ui.text-money/UMoney.vue";
|
|
8
9
|
import UBadge from "../../ui.text-badge/UBadge.vue";
|
|
9
10
|
import URow from "../../ui.container-row/URow.vue";
|
|
10
11
|
|
|
12
|
+
import type { Row, UTableProps } from "../types.ts";
|
|
13
|
+
|
|
14
|
+
interface UTableArgs extends UTableProps {
|
|
15
|
+
slotTemplate?: string;
|
|
16
|
+
enum: "size";
|
|
17
|
+
numberOfRows: number;
|
|
18
|
+
row: Row | typeof getRow | typeof getNestedRow | typeof getNestedContentRow;
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
const SHORT_STORY_PARAMETERS = {
|
|
12
22
|
docs: {
|
|
13
23
|
story: {
|
|
@@ -45,7 +55,7 @@ export default {
|
|
|
45
55
|
row: getRow,
|
|
46
56
|
numberOfRows: 5,
|
|
47
57
|
},
|
|
48
|
-
};
|
|
58
|
+
} as Meta;
|
|
49
59
|
|
|
50
60
|
function getDateDividerRow() {
|
|
51
61
|
return {
|
|
@@ -128,7 +138,51 @@ function getRow() {
|
|
|
128
138
|
};
|
|
129
139
|
}
|
|
130
140
|
|
|
131
|
-
|
|
141
|
+
function getNestedContentRow(index: number) {
|
|
142
|
+
if (index === 0) {
|
|
143
|
+
return {
|
|
144
|
+
id: getRandomId(),
|
|
145
|
+
isChecked: false,
|
|
146
|
+
key_1: "Row with nested content",
|
|
147
|
+
key_2: "Basic data",
|
|
148
|
+
key_3: "More info",
|
|
149
|
+
nestedData: {
|
|
150
|
+
isChecked: false,
|
|
151
|
+
isHidden: true,
|
|
152
|
+
rows: [
|
|
153
|
+
{
|
|
154
|
+
id: getRandomId(),
|
|
155
|
+
key_1: "Detail 1A",
|
|
156
|
+
key_2: "Info 1B",
|
|
157
|
+
key_3: "Data 1C",
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: getRandomId(),
|
|
161
|
+
key_1: "Detail 2A",
|
|
162
|
+
key_2: "Info 2B",
|
|
163
|
+
key_3: "Data 2C",
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: getRandomId(),
|
|
167
|
+
key_1: "Detail 3A",
|
|
168
|
+
key_2: "Info 3B",
|
|
169
|
+
key_3: "Data 3C",
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
} else {
|
|
175
|
+
return {
|
|
176
|
+
id: getRandomId(),
|
|
177
|
+
isChecked: false,
|
|
178
|
+
key_1: `Regular row ${index}`,
|
|
179
|
+
key_2: "Standard info",
|
|
180
|
+
key_3: "Basic data",
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const DefaultTemplate: StoryFn<UTableArgs> = (args: UTableArgs) => ({
|
|
132
186
|
components: { UTable, UButton, ULink, UMoney, UBadge, URow },
|
|
133
187
|
setup() {
|
|
134
188
|
const slots = getSlotNames(UTable.__name);
|
|
@@ -140,12 +194,12 @@ const DefaultTemplate = (args) => ({
|
|
|
140
194
|
v-bind="args"
|
|
141
195
|
:rows="args.rows || itemsData"
|
|
142
196
|
>
|
|
143
|
-
${args.slotTemplate || getSlotsFragment()}
|
|
197
|
+
${args.slotTemplate || getSlotsFragment("")}
|
|
144
198
|
</UTable>
|
|
145
199
|
`,
|
|
146
200
|
computed: {
|
|
147
201
|
itemsData() {
|
|
148
|
-
|
|
202
|
+
const rows = [];
|
|
149
203
|
|
|
150
204
|
if (typeof args.row === "function") {
|
|
151
205
|
for (let i = 0; i < args.numberOfRows; i++) {
|
|
@@ -160,7 +214,7 @@ const DefaultTemplate = (args) => ({
|
|
|
160
214
|
},
|
|
161
215
|
});
|
|
162
216
|
|
|
163
|
-
const EmptyTemplate = (args) => ({
|
|
217
|
+
const EmptyTemplate: StoryFn<UTableArgs> = (args: UTableArgs) => ({
|
|
164
218
|
components: { UTable },
|
|
165
219
|
setup() {
|
|
166
220
|
const slots = getSlotNames(UTable.__name);
|
|
@@ -185,49 +239,7 @@ NestedContent.args = {
|
|
|
185
239
|
{ key: "key_2", label: "Title 2" },
|
|
186
240
|
{ key: "key_3", label: "Title 3" },
|
|
187
241
|
],
|
|
188
|
-
row:
|
|
189
|
-
if (index === 0) {
|
|
190
|
-
return {
|
|
191
|
-
id: getRandomId(),
|
|
192
|
-
isChecked: false,
|
|
193
|
-
key_1: "Row with nested content",
|
|
194
|
-
key_2: "Basic data",
|
|
195
|
-
key_3: "More info",
|
|
196
|
-
nestedData: {
|
|
197
|
-
isChecked: false,
|
|
198
|
-
isHidden: true,
|
|
199
|
-
rows: [
|
|
200
|
-
{
|
|
201
|
-
id: getRandomId(),
|
|
202
|
-
key_1: "Detail 1A",
|
|
203
|
-
key_2: "Info 1B",
|
|
204
|
-
key_3: "Data 1C",
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
id: getRandomId(),
|
|
208
|
-
key_1: "Detail 2A",
|
|
209
|
-
key_2: "Info 2B",
|
|
210
|
-
key_3: "Data 2C",
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
id: getRandomId(),
|
|
214
|
-
key_1: "Detail 3A",
|
|
215
|
-
key_2: "Info 3B",
|
|
216
|
-
key_3: "Data 3C",
|
|
217
|
-
},
|
|
218
|
-
],
|
|
219
|
-
},
|
|
220
|
-
};
|
|
221
|
-
} else {
|
|
222
|
-
return {
|
|
223
|
-
id: getRandomId(),
|
|
224
|
-
isChecked: false,
|
|
225
|
-
key_1: `Regular row ${index}`,
|
|
226
|
-
key_2: "Standard info",
|
|
227
|
-
key_3: "Basic data",
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
},
|
|
242
|
+
row: getNestedContentRow,
|
|
231
243
|
slotTemplate: `
|
|
232
244
|
<template #nested-content="{ row }">
|
|
233
245
|
<div class="p-4 bg-gray-100">
|
|
@@ -313,7 +325,7 @@ DateDivider.args = { dateDivider: true, row: getDateDividerRow };
|
|
|
313
325
|
export const DateDividerCustomLabel = DefaultTemplate.bind({});
|
|
314
326
|
DateDividerCustomLabel.args = {
|
|
315
327
|
rows: Array(10)
|
|
316
|
-
.fill()
|
|
328
|
+
.fill({})
|
|
317
329
|
.map(() => getDateDividerRow()),
|
|
318
330
|
dateDivider: [{ date: new Date().toString(), label: "Custom label for specific date" }],
|
|
319
331
|
};
|
|
@@ -407,6 +419,7 @@ CellSlots.args = {
|
|
|
407
419
|
{ key: "tags", label: "tags" },
|
|
408
420
|
],
|
|
409
421
|
row: {
|
|
422
|
+
id: getRandomId(),
|
|
410
423
|
link: "some link",
|
|
411
424
|
money: {
|
|
412
425
|
sum: 10,
|
|
@@ -419,6 +432,7 @@ CellSlots.args = {
|
|
|
419
432
|
},
|
|
420
433
|
row: [
|
|
421
434
|
{
|
|
435
|
+
id: getRandomId(),
|
|
422
436
|
isHidden: false,
|
|
423
437
|
link: "some link",
|
|
424
438
|
money: {
|
|
@@ -432,6 +446,7 @@ CellSlots.args = {
|
|
|
432
446
|
},
|
|
433
447
|
},
|
|
434
448
|
{
|
|
449
|
+
id: getRandomId(),
|
|
435
450
|
isHidden: false,
|
|
436
451
|
link: "some link",
|
|
437
452
|
money: {
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import defaultConfig from "./config.ts";
|
|
2
|
+
|
|
3
|
+
import type { UnknownObject } from "../types.ts";
|
|
4
|
+
import type { Ref } from "vue";
|
|
5
|
+
|
|
6
|
+
type RowKeys =
|
|
7
|
+
| number
|
|
8
|
+
| string
|
|
9
|
+
| boolean
|
|
10
|
+
| undefined
|
|
11
|
+
| Date
|
|
12
|
+
| Row
|
|
13
|
+
| Row[]
|
|
14
|
+
| string
|
|
15
|
+
| ((row: Row) => string);
|
|
16
|
+
|
|
17
|
+
export interface CellObject {
|
|
18
|
+
contentClasses?: string | ((value: unknown | string, row: Row) => string);
|
|
19
|
+
class?: string | ((value: unknown | string, row: Row) => string);
|
|
20
|
+
[key: string]: unknown | string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type RowId = string | number;
|
|
24
|
+
export type Cell = CellObject | string;
|
|
25
|
+
|
|
26
|
+
export interface RowData {
|
|
27
|
+
[key: string]: Cell;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface DateDivider {
|
|
31
|
+
date: Date | string;
|
|
32
|
+
label?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface Row {
|
|
36
|
+
id: RowId;
|
|
37
|
+
isChecked?: boolean;
|
|
38
|
+
isHidden?: boolean;
|
|
39
|
+
rowDate?: string | Date;
|
|
40
|
+
row?: Row | Row[];
|
|
41
|
+
nestedData?: Row;
|
|
42
|
+
class?: string | ((row: Row) => string);
|
|
43
|
+
[key: string]: Cell | RowKeys;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ColumnObject {
|
|
47
|
+
key: string;
|
|
48
|
+
label?: string;
|
|
49
|
+
isHidden?: string;
|
|
50
|
+
class?: string | ((value: unknown | string, row: Row) => string);
|
|
51
|
+
tdClass?: string;
|
|
52
|
+
thClass?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type Column = ColumnObject | string;
|
|
56
|
+
export type Config = Partial<typeof defaultConfig>;
|
|
57
|
+
|
|
58
|
+
export interface RowScopedProps {
|
|
59
|
+
value: unknown | string | number;
|
|
60
|
+
row: Row;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface UTableProps {
|
|
64
|
+
/**
|
|
65
|
+
* Table columns (headers).
|
|
66
|
+
*/
|
|
67
|
+
columns: Column[];
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Table rows data.
|
|
71
|
+
*/
|
|
72
|
+
rows: Row[];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Label to display for empty cell values.
|
|
76
|
+
*/
|
|
77
|
+
emptyCellLabel?: string;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Show date divider line between dates.
|
|
81
|
+
*/
|
|
82
|
+
dateDivider?: boolean | DateDivider[];
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Allow rows selecting.
|
|
86
|
+
*/
|
|
87
|
+
selectable?: boolean;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Makes the table compact (fewer spacings).
|
|
91
|
+
*/
|
|
92
|
+
compact?: boolean;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Set header sticky.
|
|
96
|
+
*/
|
|
97
|
+
stickyHeader?: boolean;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Set footer sticky.
|
|
101
|
+
*/
|
|
102
|
+
stickyFooter?: boolean;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Set table loader state.
|
|
106
|
+
*/
|
|
107
|
+
loading?: boolean;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Component config object.
|
|
111
|
+
*/
|
|
112
|
+
config?: Config;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Data-test attribute for automated testing.
|
|
116
|
+
*/
|
|
117
|
+
dataTest?: string;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface UTableRowAttrs {
|
|
121
|
+
bodyCellContentAttrs: Ref<UnknownObject>;
|
|
122
|
+
bodyCellCheckboxAttrs: Ref<UnknownObject>;
|
|
123
|
+
bodyCheckboxAttrs: Ref<UnknownObject>;
|
|
124
|
+
bodyCellNestedAttrs: Ref<UnknownObject>;
|
|
125
|
+
bodyCellNestedExpandIconAttrs: Ref<UnknownObject>;
|
|
126
|
+
bodyCellNestedCollapseIconAttrs: Ref<UnknownObject>;
|
|
127
|
+
bodyCellBaseAttrs: Ref<UnknownObject>;
|
|
128
|
+
bodyCellNestedExpandIconWrapperAttrs: Ref<UnknownObject>;
|
|
129
|
+
bodyRowCheckedAttrs: Ref<UnknownObject>;
|
|
130
|
+
bodyRowAttrs: Ref<UnknownObject>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface UTableRowProps {
|
|
134
|
+
row: Row;
|
|
135
|
+
columns: ColumnObject[];
|
|
136
|
+
emptyCellLabel?: string;
|
|
137
|
+
selectable: boolean;
|
|
138
|
+
nestedLevel: number;
|
|
139
|
+
dataTest: string;
|
|
140
|
+
attrs: UTableRowAttrs;
|
|
141
|
+
config: Config;
|
|
142
|
+
}
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { computed } from "vue";
|
|
2
2
|
import useUI from "../composables/useUI.ts";
|
|
3
3
|
|
|
4
|
-
import defaultConfig from "./config.
|
|
4
|
+
import defaultConfig from "./config.ts";
|
|
5
|
+
|
|
6
|
+
import type { Row, UTableProps, Config } from "./types.ts";
|
|
7
|
+
import type { UseAttrs } from "../types.ts";
|
|
8
|
+
import type { Ref } from "vue";
|
|
9
|
+
|
|
10
|
+
export type UTableState = {
|
|
11
|
+
tableRows: Ref<Row[]>;
|
|
12
|
+
isShownActionsHeader: Ref<boolean>;
|
|
13
|
+
isHeaderSticky: Ref<boolean>;
|
|
14
|
+
isFooterSticky: Ref<boolean>;
|
|
15
|
+
};
|
|
5
16
|
|
|
6
17
|
export default function useAttrs(
|
|
7
|
-
props,
|
|
8
|
-
{ tableRows, isShownActionsHeader, isHeaderSticky, isFooterSticky },
|
|
9
|
-
) {
|
|
18
|
+
props: UTableProps,
|
|
19
|
+
{ tableRows, isShownActionsHeader, isHeaderSticky, isFooterSticky }: UTableState,
|
|
20
|
+
): UseAttrs<Config> {
|
|
10
21
|
const { config, getKeysAttrs, hasSlotContent, getExtendingKeysClasses } = useUI(
|
|
11
22
|
defaultConfig,
|
|
12
23
|
() => props.config,
|
|
@@ -27,15 +38,23 @@ export default function useAttrs(
|
|
|
27
38
|
|
|
28
39
|
const keysAttrs = getKeysAttrs({}, extendingKeys, {
|
|
29
40
|
stickyHeader: {
|
|
30
|
-
extend: computed(() =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
extendingKeysClasses.stickyHeaderActions.value
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
extend: computed(() => {
|
|
42
|
+
const classes = [];
|
|
43
|
+
|
|
44
|
+
if (isShownActionsHeader.value) {
|
|
45
|
+
classes.push(extendingKeysClasses.stickyHeaderActions.value);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (isShownActionsHeader.value && isHeaderSticky.value) {
|
|
49
|
+
classes.push(extendingKeysClasses.stickyHeaderActions.value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!isShownActionsHeader.value && isHeaderSticky.value) {
|
|
53
|
+
classes.push(extendingKeysClasses.stickyHeaderRow.value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return classes;
|
|
57
|
+
}),
|
|
39
58
|
},
|
|
40
59
|
stickyHeaderCell: {
|
|
41
60
|
base: computed(() => [extendingKeysClasses.headerCellBase.value]),
|
|
@@ -73,7 +92,6 @@ export default function useAttrs(
|
|
|
73
92
|
|
|
74
93
|
return {
|
|
75
94
|
config,
|
|
76
|
-
keysAttrs,
|
|
77
95
|
...keysAttrs,
|
|
78
96
|
hasSlotContent,
|
|
79
97
|
};
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { getRandomId } from "../utils/ui.ts";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import type { Column, ColumnObject, Row, RowData, RowId } from "./types.ts";
|
|
4
|
+
|
|
5
|
+
export function normalizeColumns(columns: Column[]): ColumnObject[] {
|
|
6
|
+
return columns.map((column) =>
|
|
7
|
+
typeof column === "string" ? { label: column, key: column } : column,
|
|
8
|
+
);
|
|
5
9
|
}
|
|
6
10
|
|
|
7
|
-
export function
|
|
11
|
+
export function mapRowColumns(row: Row, columns: ColumnObject[]): RowData {
|
|
8
12
|
const filteredRow = Object.entries(row).filter((item) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (isShownColumn) return item;
|
|
13
|
+
return columns.some((column) => column.key === item[0] && !column.isHidden);
|
|
12
14
|
});
|
|
13
15
|
|
|
14
|
-
return Object.fromEntries(filteredRow);
|
|
16
|
+
return Object.fromEntries(filteredRow) as RowData;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
export function syncRowCheck(row, selectedRows) {
|
|
18
|
-
row.isChecked = selectedRows.includes(row.id);
|
|
19
|
+
export function syncRowCheck(row: Row, selectedRows: RowId[]) {
|
|
20
|
+
row.isChecked = selectedRows.map((rowId) => String(rowId)).includes(String(row.id));
|
|
19
21
|
|
|
20
22
|
if (row.row && !Array.isArray(row.row)) {
|
|
21
23
|
row.row = syncRowCheck(row.row, selectedRows);
|
|
@@ -24,7 +26,7 @@ export function syncRowCheck(row, selectedRows) {
|
|
|
24
26
|
return row;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
export function addRowId(row) {
|
|
29
|
+
export function addRowId(row: Row) {
|
|
28
30
|
const hasRowId = typeof row.id !== "undefined" && row.id !== null && row.id !== "";
|
|
29
31
|
|
|
30
32
|
row.id = hasRowId ? row.id : getRandomId();
|
|
@@ -40,11 +42,11 @@ export function addRowId(row) {
|
|
|
40
42
|
return row;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
export function toggleRowVisibility(row, targetRowId) {
|
|
45
|
+
export function toggleRowVisibility(row: Row, targetRowId: string | number) {
|
|
44
46
|
if (row.id === targetRowId) {
|
|
45
|
-
if (
|
|
47
|
+
if (row.hasOwnProperty("isHidden")) {
|
|
46
48
|
row.isHidden = !row.isHidden;
|
|
47
|
-
} else if (row.nestedData &&
|
|
49
|
+
} else if (row.nestedData && row.nestedData.hasOwnProperty("isHidden")) {
|
|
48
50
|
row.nestedData.isHidden = !row.nestedData.isHidden;
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -64,18 +66,22 @@ export function toggleRowVisibility(row, targetRowId) {
|
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
export function switchRowCheck(row, isChecked) {
|
|
69
|
+
export function switchRowCheck(row: Row, isChecked: boolean) {
|
|
68
70
|
row.isChecked = isChecked;
|
|
69
71
|
|
|
70
|
-
if (row.row) {
|
|
72
|
+
if (row.row && !Array.isArray(row.row)) {
|
|
71
73
|
switchRowCheck(row.row, isChecked);
|
|
72
74
|
}
|
|
75
|
+
|
|
76
|
+
if (row.row && Array.isArray(row.row)) {
|
|
77
|
+
row.row.map((currentRow) => switchRowCheck(currentRow, isChecked));
|
|
78
|
+
}
|
|
73
79
|
}
|
|
74
80
|
|
|
75
|
-
export function getFlatRows(tableRows) {
|
|
76
|
-
const rows = [];
|
|
81
|
+
export function getFlatRows(tableRows: Row[]) {
|
|
82
|
+
const rows: Row[] = [];
|
|
77
83
|
|
|
78
|
-
function addRow(row) {
|
|
84
|
+
function addRow(row: Row) {
|
|
79
85
|
rows.push(row);
|
|
80
86
|
|
|
81
87
|
if (row.row && !Array.isArray(row.row)) {
|
|
@@ -40,11 +40,11 @@ import defaultConfig from "./config.ts";
|
|
|
40
40
|
|
|
41
41
|
import type { UCalendarProps, DateValue, RangeDate, Locale } from "./types.ts";
|
|
42
42
|
import type { ComputedRef, Ref } from "vue";
|
|
43
|
+
import type { DateLocale } from "./utilFormatting.ts";
|
|
43
44
|
|
|
44
45
|
import DayView from "./UCalendarDayView.vue";
|
|
45
46
|
import MonthView from "./UCalendarMonthView.vue";
|
|
46
47
|
import YearView from "./UCalendarYearView.vue";
|
|
47
|
-
import type { DateLocale } from "./utilFormatting.ts";
|
|
48
48
|
|
|
49
49
|
type DefaultLocale = typeof defaultConfig.i18n;
|
|
50
50
|
|
|
@@ -131,10 +131,11 @@ export function createMergeConfigs(cx) {
|
|
|
131
131
|
console.error("CompoundVariants should be an array.");
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
const
|
|
135
|
-
const
|
|
134
|
+
const defaultCompoundVariants = expandCompoundVariants(defaultConfig.compoundVariants);
|
|
135
|
+
const globalCompoundVariants = expandCompoundVariants(globalConfig.compoundVariants);
|
|
136
|
+
const propsCompoundVariants = expandCompoundVariants(propsConfig.compoundVariants);
|
|
136
137
|
|
|
137
|
-
const config =
|
|
138
|
+
const config = defaultCompoundVariants?.map((defaultConfigItem) => {
|
|
138
139
|
/**
|
|
139
140
|
* Compare two objects by keys for match.
|
|
140
141
|
*/
|
|
@@ -151,25 +152,27 @@ export function createMergeConfigs(cx) {
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
/**
|
|
154
|
-
* Find the same compound variant item in custom config if
|
|
155
|
+
* Find the same compound variant item in custom config if existed.
|
|
155
156
|
*/
|
|
156
157
|
function findItem(config = []) {
|
|
157
|
-
|
|
158
|
-
|
|
158
|
+
config = cloneDeep(config);
|
|
159
|
+
|
|
160
|
+
const globalConfigUniqueItemIndex = globalCompoundVariants.findIndex(isSameItem);
|
|
161
|
+
const propsConfigUniqueItemIndex = propsCompoundVariants.findIndex(isSameItem);
|
|
159
162
|
|
|
160
163
|
if (~globalConfigUniqueItemIndex) {
|
|
161
|
-
|
|
164
|
+
globalCompoundVariants.splice(globalConfigUniqueItemIndex, 1);
|
|
162
165
|
}
|
|
163
166
|
|
|
164
167
|
if (~propsConfigUniqueItemIndex) {
|
|
165
|
-
|
|
168
|
+
propsCompoundVariants.splice(propsConfigUniqueItemIndex, 1);
|
|
166
169
|
}
|
|
167
170
|
|
|
168
171
|
return config.find(isSameItem);
|
|
169
172
|
}
|
|
170
173
|
|
|
171
|
-
const globalConfigItem = findItem(
|
|
172
|
-
const propsConfigItem = findItem(
|
|
174
|
+
const globalConfigItem = findItem(globalCompoundVariants);
|
|
175
|
+
const propsConfigItem = findItem(propsCompoundVariants);
|
|
173
176
|
|
|
174
177
|
return globalConfigItem || propsConfigItem
|
|
175
178
|
? {
|
|
@@ -181,7 +184,35 @@ export function createMergeConfigs(cx) {
|
|
|
181
184
|
: defaultConfigItem;
|
|
182
185
|
});
|
|
183
186
|
|
|
184
|
-
return [...(config || []), ...
|
|
187
|
+
return [...(config || []), ...globalCompoundVariants, ...propsCompoundVariants];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Convert compound variants with arrays in values into compound variants with primitives.
|
|
192
|
+
*/
|
|
193
|
+
function expandCompoundVariants(compoundVariants) {
|
|
194
|
+
compoundVariants = cloneDeep(compoundVariants || []);
|
|
195
|
+
|
|
196
|
+
function expand(compoundVariant) {
|
|
197
|
+
const keysWithArray = Object.keys(compoundVariant).filter((key) =>
|
|
198
|
+
Array.isArray(compoundVariant[key]),
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
if (!keysWithArray.length) {
|
|
202
|
+
return [compoundVariant];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const [firstKey] = keysWithArray;
|
|
206
|
+
const expandedArray = compoundVariant[firstKey].map((value) => ({
|
|
207
|
+
...compoundVariant,
|
|
208
|
+
[firstKey]: value,
|
|
209
|
+
}));
|
|
210
|
+
|
|
211
|
+
// Recursively expand the remaining array keys
|
|
212
|
+
return expandedArray.flatMap((expandedCompoundVariant) => expand(expandedCompoundVariant));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return compoundVariants.flatMap(expand);
|
|
185
216
|
}
|
|
186
217
|
|
|
187
218
|
return mergeConfigs;
|