aloha-vue 2.67.0 → 2.69.0
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/CHANGELOG.md +10 -0
- package/dist/aloha-vue.es.js +2793 -2759
- package/dist/aloha-vue.umd.js +37 -37
- package/package.json +1 -1
- package/src/ATableForm/ATableFormCell/ATableFormCell.js +8 -0
- package/src/ui/ACheckbox/ACheckbox.js +11 -6
- package/src/ui/AInputCurrency/AInputCurrency.js +9 -7
- package/src/ui/AInputCurrency/__tests__/AInputCurrency.ModelAPI.test.js +73 -0
- package/src/ui/AInputCurrency/compositionAPI/ModelAPI.js +18 -5
- package/src/ui/AMultiselectOrdered/AMultiselectOrdered.js +11 -6
- package/src/ui/ARadio/ARadio.js +11 -6
- package/src/ui/ASelect/ASelect.js +11 -6
- package/src/ui/compositionApi/UiDataWithKeyIdAndLabelAPI.js +12 -4
- package/src/ui/compositionApi/__tests__/UiDataWithKeyIdAndLabelAPI.test.js +128 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aloha-vue",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.69.0",
|
|
4
4
|
"description": "Aloha-vue is a JavaScript library that provides a wide range of accessible components and directives for Vue.js. Accessibility is of paramount importance to us, and we have designed all our components to meet accessibility compliance criteria. This library is a valuable tool for frontend developers and has already been used in three projects, including two large-scale ones",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility compliance criteria",
|
|
@@ -161,8 +161,16 @@ export default {
|
|
|
161
161
|
} = this.formElementLocal;
|
|
162
162
|
|
|
163
163
|
const slotProps = {
|
|
164
|
+
change: this.updateRowData,
|
|
164
165
|
column: this.column,
|
|
165
166
|
columnIndex: this.columnIndex,
|
|
167
|
+
errorIcon: this.errorIcon,
|
|
168
|
+
errors: this.errors,
|
|
169
|
+
id: this.id,
|
|
170
|
+
isCreateMode: this.isCreateMode,
|
|
171
|
+
isEditMode: this.isEditMode,
|
|
172
|
+
isFooter: this.isFooter,
|
|
173
|
+
modelValue: get(this.rowDataLocal, this.column.id),
|
|
166
174
|
row: this.row,
|
|
167
175
|
rowIndex: this.rowIndex,
|
|
168
176
|
rows: this.rows,
|
|
@@ -88,12 +88,17 @@ export default {
|
|
|
88
88
|
required: false,
|
|
89
89
|
default: undefined,
|
|
90
90
|
},
|
|
91
|
-
dataExtra: {
|
|
92
|
-
type: Array,
|
|
93
|
-
required: false,
|
|
94
|
-
default: () => [],
|
|
95
|
-
},
|
|
96
|
-
|
|
91
|
+
dataExtra: {
|
|
92
|
+
type: Array,
|
|
93
|
+
required: false,
|
|
94
|
+
default: () => [],
|
|
95
|
+
},
|
|
96
|
+
mergeData: {
|
|
97
|
+
type: Boolean,
|
|
98
|
+
required: false,
|
|
99
|
+
default: false,
|
|
100
|
+
},
|
|
101
|
+
dependencies: {
|
|
97
102
|
type: [Array, Object],
|
|
98
103
|
required: false,
|
|
99
104
|
default: undefined,
|
|
@@ -353,9 +353,10 @@ export default {
|
|
|
353
353
|
} = VerifyAPI(props);
|
|
354
354
|
|
|
355
355
|
const {
|
|
356
|
-
clearModel,
|
|
357
|
-
displayValue,
|
|
358
|
-
|
|
356
|
+
clearModel,
|
|
357
|
+
displayValue,
|
|
358
|
+
displayValueReadonly,
|
|
359
|
+
initLocalVars,
|
|
359
360
|
isInternalChange,
|
|
360
361
|
localModel,
|
|
361
362
|
modelNumber,
|
|
@@ -415,9 +416,10 @@ export default {
|
|
|
415
416
|
attributesToExcludeFromRender,
|
|
416
417
|
clearModel,
|
|
417
418
|
componentStyleHide,
|
|
418
|
-
decrease,
|
|
419
|
-
displayValue,
|
|
420
|
-
|
|
419
|
+
decrease,
|
|
420
|
+
displayValue,
|
|
421
|
+
displayValueReadonly,
|
|
422
|
+
errorsId,
|
|
421
423
|
hasErrorIcon,
|
|
422
424
|
handleInput,
|
|
423
425
|
handleKeydown,
|
|
@@ -452,7 +454,7 @@ export default {
|
|
|
452
454
|
label: this.label,
|
|
453
455
|
labelClass: this.labelClass,
|
|
454
456
|
labelScreenReader: this.labelScreenReader,
|
|
455
|
-
modelValue: this.
|
|
457
|
+
modelValue: this.displayValueReadonly,
|
|
456
458
|
readonlyDefault: this.readonlyDefault,
|
|
457
459
|
required: this.required,
|
|
458
460
|
style: this.componentStyleHide,
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
reactive,
|
|
3
|
+
} from "vue";
|
|
4
|
+
import {
|
|
5
|
+
describe,
|
|
6
|
+
expect,
|
|
7
|
+
it,
|
|
8
|
+
} from "@jest/globals";
|
|
9
|
+
|
|
10
|
+
import ModelAPI from "../compositionAPI/ModelAPI";
|
|
11
|
+
|
|
12
|
+
const getModelAPI = () => {
|
|
13
|
+
const props = reactive({
|
|
14
|
+
currencySymbol: "€",
|
|
15
|
+
currencySymbolPosition: "right",
|
|
16
|
+
decimalDivider: ",",
|
|
17
|
+
decimalPartLength: 2,
|
|
18
|
+
disabled: false,
|
|
19
|
+
modelType: "number",
|
|
20
|
+
modelUndefined: undefined,
|
|
21
|
+
modelValue: 1234.5,
|
|
22
|
+
required: false,
|
|
23
|
+
skipRequiredModelInit: false,
|
|
24
|
+
thousandDivider: ".",
|
|
25
|
+
});
|
|
26
|
+
const modelAPI = ModelAPI(props, {
|
|
27
|
+
adjustFloatPartAndDivider: () => "1.234,50",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
modelAPI.initLocalVars();
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
modelAPI,
|
|
34
|
+
props,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
describe("AInputCurrency ModelAPI", () => {
|
|
39
|
+
it("adds the currency symbol to the readonly display value at the configured position", () => {
|
|
40
|
+
const {
|
|
41
|
+
modelAPI,
|
|
42
|
+
props,
|
|
43
|
+
} = getModelAPI();
|
|
44
|
+
|
|
45
|
+
expect(modelAPI.displayValueReadonly.value).toBe("1.234,50 €");
|
|
46
|
+
|
|
47
|
+
props.currencySymbol = "$";
|
|
48
|
+
props.currencySymbolPosition = "left";
|
|
49
|
+
|
|
50
|
+
expect(modelAPI.displayValueReadonly.value).toBe("$ 1.234,50");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("does not add the currency symbol to an empty readonly display value", () => {
|
|
54
|
+
const {
|
|
55
|
+
modelAPI,
|
|
56
|
+
} = getModelAPI();
|
|
57
|
+
|
|
58
|
+
modelAPI.displayValue.value = "";
|
|
59
|
+
|
|
60
|
+
expect(modelAPI.displayValueReadonly.value).toBe("");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("keeps the readonly display value unchanged when the currency symbol is empty", () => {
|
|
64
|
+
const {
|
|
65
|
+
modelAPI,
|
|
66
|
+
props,
|
|
67
|
+
} = getModelAPI();
|
|
68
|
+
|
|
69
|
+
props.currencySymbol = "";
|
|
70
|
+
|
|
71
|
+
expect(modelAPI.displayValueReadonly.value).toBe("1.234,50");
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -13,20 +13,32 @@ export default function ModelAPI(props, {
|
|
|
13
13
|
adjustFloatPartAndDivider = () => {},
|
|
14
14
|
changeModel = () => {},
|
|
15
15
|
}) {
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const currencySymbol = toRef(props, "currencySymbol");
|
|
17
|
+
const currencySymbolPosition = toRef(props, "currencySymbolPosition");
|
|
18
|
+
const decimalDivider = toRef(props, "decimalDivider");
|
|
19
|
+
const decimalPartLength = toRef(props, "decimalPartLength");
|
|
20
|
+
const disabled = toRef(props, "disabled");
|
|
18
21
|
const modelType = toRef(props, "modelType");
|
|
19
22
|
const modelUndefined = toRef(props, "modelUndefined");
|
|
23
|
+
const modelValue = toRef(props, "modelValue");
|
|
24
|
+
const required = toRef(props, "required");
|
|
20
25
|
const skipRequiredModelInit = toRef(props, "skipRequiredModelInit");
|
|
21
|
-
const decimalDivider = toRef(props, "decimalDivider");
|
|
22
|
-
const disabled = toRef(props, "disabled");
|
|
23
|
-
const decimalPartLength = toRef(props, "decimalPartLength");
|
|
24
26
|
const thousandDivider = toRef(props, "thousandDivider");
|
|
25
27
|
|
|
26
28
|
const displayValue = ref(undefined);
|
|
27
29
|
const isInternalChange = ref(false);
|
|
28
30
|
const localModel = ref(undefined);
|
|
29
31
|
|
|
32
|
+
const displayValueReadonly = computed(() => {
|
|
33
|
+
if (isNil(displayValue.value) || displayValue.value === "" || !currencySymbol.value) {
|
|
34
|
+
return displayValue.value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return currencySymbolPosition.value === "left" ?
|
|
38
|
+
`${ currencySymbol.value } ${ displayValue.value }` :
|
|
39
|
+
`${ displayValue.value } ${ currencySymbol.value }`;
|
|
40
|
+
});
|
|
41
|
+
|
|
30
42
|
const initLocalVars = () => {
|
|
31
43
|
displayValue.value = adjustFloatPartAndDivider(modelValue.value);
|
|
32
44
|
localModel.value = modelValue.value;
|
|
@@ -78,6 +90,7 @@ export default function ModelAPI(props, {
|
|
|
78
90
|
return {
|
|
79
91
|
clearModel,
|
|
80
92
|
displayValue,
|
|
93
|
+
displayValueReadonly,
|
|
81
94
|
initLocalVars,
|
|
82
95
|
isInternalChange,
|
|
83
96
|
localModel,
|
|
@@ -119,12 +119,17 @@ export default {
|
|
|
119
119
|
required: false,
|
|
120
120
|
default: undefined,
|
|
121
121
|
},
|
|
122
|
-
dataExtra: {
|
|
123
|
-
type: Array,
|
|
124
|
-
required: false,
|
|
125
|
-
default: () => [],
|
|
126
|
-
},
|
|
127
|
-
|
|
122
|
+
dataExtra: {
|
|
123
|
+
type: Array,
|
|
124
|
+
required: false,
|
|
125
|
+
default: () => [],
|
|
126
|
+
},
|
|
127
|
+
mergeData: {
|
|
128
|
+
type: Boolean,
|
|
129
|
+
required: false,
|
|
130
|
+
default: false,
|
|
131
|
+
},
|
|
132
|
+
dependencies: {
|
|
128
133
|
type: [Array, Object],
|
|
129
134
|
required: false,
|
|
130
135
|
default: undefined,
|
package/src/ui/ARadio/ARadio.js
CHANGED
|
@@ -88,12 +88,17 @@ export default {
|
|
|
88
88
|
required: false,
|
|
89
89
|
default: undefined,
|
|
90
90
|
},
|
|
91
|
-
dataExtra: {
|
|
92
|
-
type: Array,
|
|
93
|
-
required: false,
|
|
94
|
-
default: () => [],
|
|
95
|
-
},
|
|
96
|
-
|
|
91
|
+
dataExtra: {
|
|
92
|
+
type: Array,
|
|
93
|
+
required: false,
|
|
94
|
+
default: () => [],
|
|
95
|
+
},
|
|
96
|
+
mergeData: {
|
|
97
|
+
type: Boolean,
|
|
98
|
+
required: false,
|
|
99
|
+
default: false,
|
|
100
|
+
},
|
|
101
|
+
dependencies: {
|
|
97
102
|
type: [Array, Object],
|
|
98
103
|
required: false,
|
|
99
104
|
default: undefined,
|
|
@@ -122,12 +122,17 @@ export default {
|
|
|
122
122
|
required: false,
|
|
123
123
|
default: undefined,
|
|
124
124
|
},
|
|
125
|
-
dataExtra: {
|
|
126
|
-
type: Array,
|
|
127
|
-
required: false,
|
|
128
|
-
default: () => ASelectPluginOptions.propsDefault.dataExtra,
|
|
129
|
-
},
|
|
130
|
-
|
|
125
|
+
dataExtra: {
|
|
126
|
+
type: Array,
|
|
127
|
+
required: false,
|
|
128
|
+
default: () => ASelectPluginOptions.propsDefault.dataExtra,
|
|
129
|
+
},
|
|
130
|
+
mergeData: {
|
|
131
|
+
type: Boolean,
|
|
132
|
+
required: false,
|
|
133
|
+
default: false,
|
|
134
|
+
},
|
|
135
|
+
dependencies: {
|
|
131
136
|
type: [Array, Object],
|
|
132
137
|
required: false,
|
|
133
138
|
default: undefined,
|
|
@@ -31,9 +31,10 @@ export default function UiDataWithKeyIdAndLabelAPI(props) {
|
|
|
31
31
|
const data = toRef(props, "data");
|
|
32
32
|
const dataExtra = toRef(props, "dataExtra");
|
|
33
33
|
const isDataSimpleArray = toRef(props, "isDataSimpleArray");
|
|
34
|
-
const keyId = toRef(props, "keyId");
|
|
35
|
-
const keyLabel = toRef(props, "keyLabel");
|
|
36
|
-
const keyLabelCallback = toRef(props, "keyLabelCallback");
|
|
34
|
+
const keyId = toRef(props, "keyId");
|
|
35
|
+
const keyLabel = toRef(props, "keyLabel");
|
|
36
|
+
const keyLabelCallback = toRef(props, "keyLabelCallback");
|
|
37
|
+
const mergeData = toRef(props, "mergeData");
|
|
37
38
|
const searchTextInHtml = toRef(props, "searchTextInHtml");
|
|
38
39
|
const translateData = toRef(props, "translateData");
|
|
39
40
|
|
|
@@ -156,7 +157,14 @@ export default function UiDataWithKeyIdAndLabelAPI(props) {
|
|
|
156
157
|
let DATA_LOCAL = data.value || [];
|
|
157
158
|
|
|
158
159
|
if (dataFromServer.value.length) {
|
|
159
|
-
|
|
160
|
+
if (mergeData.value) {
|
|
161
|
+
DATA_LOCAL = uniqBy([
|
|
162
|
+
...dataFromServer.value,
|
|
163
|
+
...DATA_LOCAL,
|
|
164
|
+
], item => get(item, keyId.value, item));
|
|
165
|
+
} else {
|
|
166
|
+
DATA_LOCAL = dataFromServer.value;
|
|
167
|
+
}
|
|
160
168
|
}
|
|
161
169
|
|
|
162
170
|
if (!dataFromRetrieve.value.length) {
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createApp,
|
|
3
|
+
defineComponent,
|
|
4
|
+
} from "vue";
|
|
5
|
+
import {
|
|
6
|
+
describe,
|
|
7
|
+
expect,
|
|
8
|
+
it,
|
|
9
|
+
jest,
|
|
10
|
+
} from "@jest/globals";
|
|
11
|
+
|
|
12
|
+
import UiDataWithKeyIdAndLabelAPI from "../UiDataWithKeyIdAndLabelAPI";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
AKeyId,
|
|
16
|
+
AKeyLabel,
|
|
17
|
+
} from "../../../const/AKeys";
|
|
18
|
+
|
|
19
|
+
jest.mock("../../../index", () => ({
|
|
20
|
+
AKeyId: "_a_id",
|
|
21
|
+
AKeyLabel: "_a_label",
|
|
22
|
+
AKeyLabelSearch: "_a_label_search",
|
|
23
|
+
extractTextFromHtml: value => value,
|
|
24
|
+
getTranslatedText: ({ placeholder }) => placeholder,
|
|
25
|
+
isArrayOfArrays: value => Array.isArray(value) && value.every(Array.isArray),
|
|
26
|
+
isPlaceholderTranslate: () => false,
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
const createProps = ({
|
|
30
|
+
data,
|
|
31
|
+
isDataSimpleArray = false,
|
|
32
|
+
mergeData = false,
|
|
33
|
+
}) => ({
|
|
34
|
+
alwaysTranslate: false,
|
|
35
|
+
data,
|
|
36
|
+
dataExtra: [],
|
|
37
|
+
isDataSimpleArray,
|
|
38
|
+
keyId: "id",
|
|
39
|
+
keyLabel: "label",
|
|
40
|
+
keyLabelCallback: undefined,
|
|
41
|
+
mergeData,
|
|
42
|
+
searchTextInHtml: false,
|
|
43
|
+
translateData: false,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const useDataAPI = props => {
|
|
47
|
+
let result;
|
|
48
|
+
const app = createApp(defineComponent({
|
|
49
|
+
name: "TestUiDataWithKeyIdAndLabelAPI",
|
|
50
|
+
setup() {
|
|
51
|
+
result = UiDataWithKeyIdAndLabelAPI(props);
|
|
52
|
+
return () => null;
|
|
53
|
+
},
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
app.mount(document.createElement("div"));
|
|
57
|
+
return result;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
describe("UiDataWithKeyIdAndLabelAPI", () => {
|
|
61
|
+
it("keeps replacing prop data with internally loaded data by default", () => {
|
|
62
|
+
const {
|
|
63
|
+
dataFromServer,
|
|
64
|
+
dataLocal,
|
|
65
|
+
} = useDataAPI(createProps({
|
|
66
|
+
data: [
|
|
67
|
+
{ id: 1, label: "Prop one" },
|
|
68
|
+
{ id: 3, label: "Prop three" },
|
|
69
|
+
],
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
dataFromServer.value = [
|
|
73
|
+
{ id: 1, label: "Internal one" },
|
|
74
|
+
{ id: 2, label: "Internal two" },
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
expect(dataLocal.value.map(item => item[AKeyLabel])).toEqual([
|
|
78
|
+
"Internal one",
|
|
79
|
+
"Internal two",
|
|
80
|
+
]);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("merges prop and internally loaded data by ID with internal items taking precedence", () => {
|
|
84
|
+
const {
|
|
85
|
+
dataFromServer,
|
|
86
|
+
dataLocal,
|
|
87
|
+
} = useDataAPI(createProps({
|
|
88
|
+
data: [
|
|
89
|
+
{ id: 1, label: "Prop one" },
|
|
90
|
+
{ id: 3, label: "Prop three" },
|
|
91
|
+
],
|
|
92
|
+
mergeData: true,
|
|
93
|
+
}));
|
|
94
|
+
|
|
95
|
+
dataFromServer.value = [
|
|
96
|
+
{ id: 1, label: "Internal one" },
|
|
97
|
+
{ id: 2, label: "Internal two" },
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
expect(dataLocal.value.map(item => ({
|
|
101
|
+
id: item[AKeyId],
|
|
102
|
+
label: item[AKeyLabel],
|
|
103
|
+
}))).toEqual([
|
|
104
|
+
{ id: 1, label: "Internal one" },
|
|
105
|
+
{ id: 2, label: "Internal two" },
|
|
106
|
+
{ id: 3, label: "Prop three" },
|
|
107
|
+
]);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("merges simple arrays by their values", () => {
|
|
111
|
+
const {
|
|
112
|
+
dataFromServer,
|
|
113
|
+
dataLocal,
|
|
114
|
+
} = useDataAPI(createProps({
|
|
115
|
+
data: ["one", "three"],
|
|
116
|
+
isDataSimpleArray: true,
|
|
117
|
+
mergeData: true,
|
|
118
|
+
}));
|
|
119
|
+
|
|
120
|
+
dataFromServer.value = ["one", "two"];
|
|
121
|
+
|
|
122
|
+
expect(dataLocal.value.map(item => item[AKeyId])).toEqual([
|
|
123
|
+
"one",
|
|
124
|
+
"two",
|
|
125
|
+
"three",
|
|
126
|
+
]);
|
|
127
|
+
});
|
|
128
|
+
});
|