aloha-vue 2.57.3 → 2.57.5

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/aloha-vue.es.js +12519 -12436
  3. package/dist/aloha-vue.umd.js +52 -52
  4. package/package.json +1 -1
  5. package/src/AButton/AButton.js +275 -270
  6. package/src/AElement/AElement.js +23 -11
  7. package/src/AElement/{comositionAPI → compositionAPI}/AttributesAPI.js +51 -51
  8. package/src/AElement/{comositionAPI → compositionAPI}/ClickAPI.js +30 -30
  9. package/src/AElement/{comositionAPI → compositionAPI}/ComponentLocalAPI.js +23 -23
  10. package/src/AElement/{comositionAPI → compositionAPI}/DisabledAPI.js +22 -22
  11. package/src/AElement/{comositionAPI → compositionAPI}/HtmlTitleAPI.js +33 -33
  12. package/src/AElement/compositionAPI/KeydownAPI.js +35 -0
  13. package/src/AElement/{comositionAPI → compositionAPI}/LoadingAPI.js +22 -22
  14. package/src/AElement/{comositionAPI → compositionAPI}/RouterLinkAPI.js +20 -20
  15. package/src/AElement/{comositionAPI → compositionAPI}/SwitchAPI.js +33 -33
  16. package/src/AElement/{comositionAPI → compositionAPI}/TagAPI.js +34 -34
  17. package/src/AElement/{comositionAPI → compositionAPI}/TextAPI.js +78 -78
  18. package/src/AElement/{comositionAPI → compositionAPI}/TitleAPI.js +29 -29
  19. package/src/ALink/ALink.js +253 -248
  20. package/src/ATableForm/ATableForm.js +11 -6
  21. package/src/ATableForm/ATableFormCellAction/ATableFormCellAction.js +18 -0
  22. package/src/ATableForm/ATableFormCellAction/compositionAPI/DeleteAPI.js +5 -5
  23. package/src/ATableForm/ATableFormCellAction/compositionAPI/IdsAPI.js +31 -0
  24. package/src/ATableForm/ATableFormCellDnd/ATableFormCellDnd.js +2 -0
  25. package/src/ATableForm/ATableFormRow/compositionAPI/EditAPI.js +5 -4
  26. package/src/ATableForm/ATableFormTh/ATableFormTh.js +0 -6
  27. package/src/ATableForm/compositionAPI/ClassesAPI.js +4 -4
  28. package/src/ATableForm/compositionAPI/ColumnsGrowAPI.js +4 -1
  29. package/src/ATableForm/compositionAPI/DeleteAPI.js +2 -2
  30. package/src/ATableForm/compositionAPI/DragAndDropAPI.js +24 -14
  31. package/src/ATableForm/compositionAPI/EditAPI.js +119 -107
  32. package/src/ui/AInputCurrency/AInputCurrency.js +4 -0
  33. package/src/ui/AInputCurrency/compositionAPI/InputEventsAPI.js +4 -3
  34. package/src/ui/AInputCurrency/compositionAPI/ModelAPI.js +3 -2
@@ -0,0 +1,31 @@
1
+ import {
2
+ computed,
3
+ toRef,
4
+ } from "vue";
5
+
6
+ export default function IdsAPI(props) {
7
+ const id = toRef(props, "id");
8
+
9
+ const idBtnDelete = computed(() => {
10
+ return `${ id.value }_delete`;
11
+ });
12
+
13
+ const idBtnEdit = computed(() => {
14
+ return `${ id.value }_edit`;
15
+ });
16
+
17
+ const idBtnCancel = computed(() => {
18
+ return `${ id.value }_cancel`;
19
+ });
20
+
21
+ const idBtnSave = computed(() => {
22
+ return `${ id.value }_save`;
23
+ });
24
+
25
+ return {
26
+ idBtnCancel,
27
+ idBtnDelete,
28
+ idBtnEdit,
29
+ idBtnSave,
30
+ };
31
+ }
@@ -133,6 +133,7 @@ export default {
133
133
  class: "a_sr_only_focusable a_btn a_btn_transparent_dark a_table_form__reorder_button",
134
134
  disabled: this.isDndDisabled,
135
135
  iconLeft: ChevronUp,
136
+ preventKeyboardRepeat: true,
136
137
  tabindex: this.isDndDisabled ? -1 : undefined,
137
138
  title: this.texts.reorderUp,
138
139
  textScreenReader: this.texts.reorderUp,
@@ -163,6 +164,7 @@ export default {
163
164
  class: "a_sr_only_focusable a_btn a_btn_transparent_dark a_table_form__reorder_button",
164
165
  disabled: this.isDndDisabled,
165
166
  iconLeft: ChevronDown,
167
+ preventKeyboardRepeat: true,
166
168
  tabindex: this.isDndDisabled ? -1 : undefined,
167
169
  title: this.texts.reorderDown,
168
170
  textScreenReader: this.texts.reorderDown,
@@ -5,7 +5,6 @@ import {
5
5
 
6
6
  import {
7
7
  cloneDeep,
8
- isPlainObject,
9
8
  set,
10
9
  unset,
11
10
  } from "lodash-es";
@@ -51,14 +50,16 @@ export default function EditAPI(props, {
51
50
  unset(errorsLocal.value, columnId);
52
51
  };
53
52
 
54
- const cancelEditRow = () => {
53
+ const cancelEditRow = ({ trigger, id } = {}) => {
55
54
  onCancelEditRow.value({
56
55
  row: row.value,
57
56
  rowIndex: rowIndex.value,
57
+ trigger,
58
+ id,
58
59
  });
59
60
  };
60
61
 
61
- const saveEditRow = async() => {
62
+ const saveEditRow = async({ id } = {}) => {
62
63
  if (isSaving.value) {
63
64
  return;
64
65
  }
@@ -79,7 +80,7 @@ export default function EditAPI(props, {
79
80
  return;
80
81
  }
81
82
 
82
- cancelEditRow();
83
+ cancelEditRow({ trigger: "save", id });
83
84
  } catch (error) {
84
85
  errorsLocal.value = error;
85
86
  } finally {
@@ -36,12 +36,6 @@ export default {
36
36
  };
37
37
  },
38
38
  render() {
39
- const slotHeader = this.column.slotHeader;
40
- const slotProps = {
41
- column: this.column,
42
- isEditable: this.isEditable,
43
- };
44
-
45
39
  return h("th", {
46
40
  class: [
47
41
  "a_table_form__cell",
@@ -4,20 +4,20 @@ import {
4
4
  } from "vue";
5
5
 
6
6
  export default function ClassesAPI(props) {
7
- const classes = toRef(props, "actionsClasses");
7
+ const actionsClasses = toRef(props, "actionsClasses");
8
8
 
9
- const classesLocal = computed(() => {
9
+ const actionsClassesLocal = computed(() => {
10
10
  return {
11
11
  delete: "a_btn a_btn_transparent_danger",
12
12
  edit: "a_btn a_btn_transparent_primary",
13
13
  editCancel: "a_btn a_btn_transparent_primary",
14
14
  editSave: "a_btn a_btn_transparent_primary",
15
15
  addRow: "a_btn a_btn_outline_primary",
16
- ...classes.value,
16
+ ...actionsClasses.value,
17
17
  };
18
18
  });
19
19
 
20
20
  return {
21
- classesLocal,
21
+ actionsClassesLocal,
22
22
  };
23
23
  }
@@ -14,6 +14,8 @@ import {
14
14
  isString,
15
15
  } from "lodash-es";
16
16
 
17
+ const TABLE_WIDTH_SAFE_DELTA = 2;
18
+
17
19
  export default function ColumnsGrowAPI(props, {
18
20
  hasActionsColumn = computed(() => false),
19
21
  widthsLocal = computed(() => ({})),
@@ -106,7 +108,8 @@ export default function ColumnsGrowAPI(props, {
106
108
  }
107
109
 
108
110
  const columnsLocal = columns.value || [];
109
- const tableWidthAvailable = tableWidth.value - actionsColumnWidth.value - dndColumnWidth.value;
111
+ // Leave a small buffer to avoid subpixel overflow triggering a useless scrollbar.
112
+ const tableWidthAvailable = tableWidth.value - actionsColumnWidth.value - dndColumnWidth.value - TABLE_WIDTH_SAFE_DELTA;
110
113
 
111
114
  if (tableWidthAvailable <= 0) {
112
115
  columnsStylesGrow.value = {};
@@ -1,6 +1,6 @@
1
1
  export default function DeleteAPI(props, { emit }) {
2
- const onDeleteRow = ({ row, rowIndex }) => {
3
- emit("deleteRow", { row, rowIndex });
2
+ const onDeleteRow = ({ row, rowIndex, rowId, btnDeleteId }) => {
3
+ emit("deleteRow", { row, rowIndex, rowId, btnDeleteId });
4
4
  };
5
5
 
6
6
  return {
@@ -12,6 +12,7 @@ import {
12
12
  export default function DragAndDropAPI(props, { emit }, {
13
13
  isDndDisabled = computed(() => false),
14
14
  } = {}) {
15
+ const focusAfterMove = toRef(props, "focusAfterMove");
15
16
  const id = toRef(props, "id");
16
17
  const isDragAndDrop = toRef(props, "isDragAndDrop");
17
18
  const rows = toRef(props, "rows");
@@ -82,7 +83,7 @@ export default function DragAndDropAPI(props, { emit }, {
82
83
  };
83
84
  };
84
85
 
85
- const moveRow = ({ fromIndex, toIndex, trigger }) => {
86
+ const moveRow = ({ focusId, fromIndex, toIndex, trigger }) => {
86
87
  if (!isDragAndDrop.value ||
87
88
  isDndDisabled.value ||
88
89
  fromIndex === toIndex ||
@@ -97,8 +98,9 @@ export default function DragAndDropAPI(props, { emit }, {
97
98
  const [movedRow] = ROWS_LOCAL.splice(fromIndex, 1);
98
99
  ROWS_LOCAL.splice(toIndex, 0, movedRow);
99
100
 
100
- emit("updateRows", { rows: ROWS_LOCAL, trigger, fromIndex, toIndex });
101
+ emit("updateRows", { focusId, rows: ROWS_LOCAL, trigger, fromIndex, toIndex });
101
102
  emit("moveRow", {
103
+ focusId,
102
104
  fromIndex,
103
105
  row: movedRow,
104
106
  toIndex,
@@ -128,34 +130,42 @@ export default function DragAndDropAPI(props, { emit }, {
128
130
  });
129
131
  };
130
132
 
133
+ const setFocusAfterMoveLocal = ({ focusId }) => {
134
+ if (!focusAfterMove.value) {
135
+ return;
136
+ }
137
+
138
+ nextTick().then(
139
+ () => {
140
+ setFocusToElement({ selector: `#${ focusId }` });
141
+ },
142
+ );
143
+ };
144
+
131
145
  const moveRowUp = rowIndex => {
146
+ const focusIndex = Math.max(1, rowIndex - 1);
147
+ const focusId = `${ id.value }_${ focusIndex }_up`;
132
148
  moveRow({
149
+ focusId,
133
150
  fromIndex: rowIndex,
134
151
  toIndex: rowIndex - 1,
135
152
  trigger: "moveRowUp",
136
153
  });
137
154
 
138
- nextTick().then(
139
- () => {
140
- const INDEX = Math.max(1, rowIndex - 1);
141
- setFocusToElement({ selector: `#${ id.value }_${ INDEX }_up` });
142
- },
143
- );
155
+ setFocusAfterMoveLocal({ focusId });
144
156
  };
145
157
 
146
158
  const moveRowDown = rowIndex => {
159
+ const focusIndex = Math.min(rows.value.length - 2, rowIndex + 1);
160
+ const focusId = `${ id.value }_${ focusIndex }_down`;
147
161
  moveRow({
162
+ focusId,
148
163
  fromIndex: rowIndex,
149
164
  toIndex: rowIndex + 1,
150
165
  trigger: "moveRowDown",
151
166
  });
152
167
 
153
- nextTick().then(
154
- () => {
155
- const INDEX = Math.min(rows.value.length - 2, rowIndex + 1);
156
- setFocusToElement({ selector: `#${ id.value }_${ INDEX }_down` });
157
- },
158
- );
168
+ setFocusAfterMoveLocal({ focusId });
159
169
  };
160
170
 
161
171
  const onDragstart = ($event, rowIndex) => {
@@ -1,107 +1,119 @@
1
- import {
2
- computed,
3
- ref,
4
- toRef,
5
- } from "vue";
6
-
7
- import {
8
- cloneDeep,
9
- isFunction,
10
- } from "lodash-es";
11
-
12
- export default function EditAPI(props, {
13
- getRowKey = () => {},
14
- }) {
15
- const addRow = toRef(props, "addRow");
16
- const columns = toRef(props, "columns");
17
- const isAddable = toRef(props, "isAddable");
18
- const isEditable = toRef(props, "isEditable");
19
- const prepareEditModel = toRef(props, "prepareEditModel");
20
- const rows = toRef(props, "rows");
21
-
22
- const activeEditRowKey = ref(undefined);
23
- const activeEditModel = ref(undefined);
24
- const isAddRowActive = ref(false);
25
-
26
- const hasActiveEditRow = computed(() => {
27
- return !!activeEditRowKey.value || isAddRowActive.value;
28
- });
29
-
30
- const canAddRow = computed(() => {
31
- if (!isAddable.value) {
32
- return false;
33
- }
34
-
35
- return isFunction(addRow.value);
36
- });
37
-
38
- const hasRequiredEditableColumns = computed(() => {
39
- if (!isEditable.value) {
40
- return false;
41
- }
42
-
43
- return columns.value.some(column => {
44
- return !!column.formElement?.required;
45
- });
46
- });
47
-
48
- const getPreparedEditModel = params => {
49
- if (!isFunction(prepareEditModel.value)) {
50
- return undefined;
51
- }
52
-
53
- const result = prepareEditModel.value(params);
54
-
55
- if (result?.model === undefined) {
56
- return undefined;
57
- }
58
-
59
- return cloneDeep(result.model);
60
- };
61
-
62
- const onAddRow = () => {
63
- if (hasActiveEditRow.value || !canAddRow.value) {
64
- return;
65
- }
66
-
67
- activeEditRowKey.value = undefined;
68
- activeEditModel.value = getPreparedEditModel({
69
- rows: rows.value,
70
- });
71
- isAddRowActive.value = true;
72
- };
73
-
74
- const onCancelEditRow = () => {
75
- activeEditRowKey.value = undefined;
76
- activeEditModel.value = undefined;
77
- isAddRowActive.value = false;
78
- };
79
-
80
- const onEditRow = ({ row, rowIndex }) => {
81
- if (isAddRowActive.value) {
82
- return;
83
- }
84
-
85
- activeEditModel.value = getPreparedEditModel({
86
- row,
87
- rowIndex,
88
- rows: rows.value,
89
- });
90
- activeEditRowKey.value = getRowKey({
91
- row,
92
- rowIndex,
93
- });
94
- };
95
-
96
- return {
97
- activeEditRowKey,
98
- activeEditModel,
99
- canAddRow,
100
- hasActiveEditRow,
101
- hasRequiredEditableColumns,
102
- isAddRowActive,
103
- onAddRow,
104
- onCancelEditRow,
105
- onEditRow,
106
- };
107
- }
1
+ import {
2
+ computed,
3
+ ref,
4
+ toRef,
5
+ } from "vue";
6
+
7
+ import {
8
+ setFocusToElement,
9
+ } from "../../utils/utilsDOM";
10
+ import {
11
+ cloneDeep,
12
+ isFunction,
13
+ } from "lodash-es";
14
+
15
+ export default function EditAPI(props, {
16
+ getRowKey = () => {},
17
+ }) {
18
+ const addRow = toRef(props, "addRow");
19
+ const columns = toRef(props, "columns");
20
+ const isAddable = toRef(props, "isAddable");
21
+ const isEditable = toRef(props, "isEditable");
22
+ const prepareEditModel = toRef(props, "prepareEditModel");
23
+ const rows = toRef(props, "rows");
24
+
25
+ const activeEditRowKey = ref(undefined);
26
+ const activeEditModel = ref(undefined);
27
+ const isAddRowActive = ref(false);
28
+
29
+ const hasActiveEditRow = computed(() => {
30
+ return !!activeEditRowKey.value || isAddRowActive.value;
31
+ });
32
+
33
+ const canAddRow = computed(() => {
34
+ if (!isAddable.value) {
35
+ return false;
36
+ }
37
+
38
+ return isFunction(addRow.value);
39
+ });
40
+
41
+ const hasRequiredEditableColumns = computed(() => {
42
+ if (!isEditable.value) {
43
+ return false;
44
+ }
45
+
46
+ return columns.value.some(column => {
47
+ return !!column.formElement?.required;
48
+ });
49
+ });
50
+
51
+ const getPreparedEditModel = params => {
52
+ if (!isFunction(prepareEditModel.value)) {
53
+ return undefined;
54
+ }
55
+
56
+ const result = prepareEditModel.value(params);
57
+
58
+ if (result?.model === undefined) {
59
+ return undefined;
60
+ }
61
+
62
+ return cloneDeep(result.model);
63
+ };
64
+
65
+ const onAddRow = () => {
66
+ if (hasActiveEditRow.value || !canAddRow.value) {
67
+ return;
68
+ }
69
+
70
+ activeEditRowKey.value = undefined;
71
+ activeEditModel.value = getPreparedEditModel({
72
+ rows: rows.value,
73
+ });
74
+ isAddRowActive.value = true;
75
+ };
76
+
77
+ const onCancelEditRow = ({ trigger, id } = {}) => {
78
+ activeEditRowKey.value = undefined;
79
+ activeEditModel.value = undefined;
80
+ isAddRowActive.value = false;
81
+ if (trigger === "cancel") {
82
+ setTimeout(() => {
83
+ setFocusToElement({ selector: `#${ id }_edit` });
84
+ });
85
+ } else if (trigger === "save") {
86
+ setTimeout(() => {
87
+ setFocusToElement({ selector: `#${ id }` });
88
+ });
89
+ }
90
+ };
91
+
92
+ const onEditRow = ({ row, rowIndex }) => {
93
+ if (isAddRowActive.value) {
94
+ return;
95
+ }
96
+
97
+ activeEditModel.value = getPreparedEditModel({
98
+ row,
99
+ rowIndex,
100
+ rows: rows.value,
101
+ });
102
+ activeEditRowKey.value = getRowKey({
103
+ row,
104
+ rowIndex,
105
+ });
106
+ };
107
+
108
+ return {
109
+ activeEditRowKey,
110
+ activeEditModel,
111
+ canAddRow,
112
+ hasActiveEditRow,
113
+ hasRequiredEditableColumns,
114
+ isAddRowActive,
115
+ onAddRow,
116
+ onCancelEditRow,
117
+ onEditRow,
118
+ };
119
+ }
@@ -242,6 +242,10 @@ export default {
242
242
  required: false,
243
243
  default: () => AInputCurrencyPluginOptions.propsDefault.modelUndefined,
244
244
  },
245
+ skipRequiredModelInit: {
246
+ type: Boolean,
247
+ required: false,
248
+ },
245
249
  modelValue: {
246
250
  type: [String, Number],
247
251
  required: false,
@@ -30,6 +30,7 @@ export default function InputEventsAPI(props, {
30
30
  const modelValue = toRef(props, "modelValue");
31
31
  const readonly = toRef(props, "readonly");
32
32
  const required = toRef(props, "required");
33
+ const skipRequiredModelInit = toRef(props, "skipRequiredModelInit");
33
34
  const decimalPartLength = toRef(props, "decimalPartLength");
34
35
  const thousandDivider = toRef(props, "thousandDivider");
35
36
  const validationOnChange = toRef(props, "validationOnChange");
@@ -121,7 +122,7 @@ export default function InputEventsAPI(props, {
121
122
  };
122
123
 
123
124
  const handleInput = ($event, { value: _value, updateOutside = false, triggerDetails = "keydown" } = {}) => {
124
- if (!required.value && isNil(_value) && !$event?.target?.value) {
125
+ if ((!required.value || skipRequiredModelInit.value) && isNil(_value) && !$event?.target?.value) {
125
126
  setValueLocal({ value: _value, updateOutside, triggerDetails });
126
127
 
127
128
  return;
@@ -726,7 +727,7 @@ export default function InputEventsAPI(props, {
726
727
  valueToSet = `${ setMinusSymbol }${ intPart }${ decimalDivider.value }${ floatPart }${ zerosToAdd }`;
727
728
  }
728
729
  } else {
729
- valueToSet = required.value ?
730
+ valueToSet = required.value && !skipRequiredModelInit.value ?
730
731
  [
731
732
  "0",
732
733
  decimalDivider.value,
@@ -734,7 +735,7 @@ export default function InputEventsAPI(props, {
734
735
  ].join("") :
735
736
  modelUndefinedLocal.value;
736
737
  }
737
- const shouldInitModel = required.value && !hasModel;
738
+ const shouldInitModel = required.value && !skipRequiredModelInit.value && !hasModel;
738
739
  handleInput(null, { value: valueToSet, updateOutside: !shouldInitModel, triggerDetails: "init" });
739
740
  });
740
741
  };
@@ -17,6 +17,7 @@ export default function ModelAPI(props, {
17
17
  const modelValue = toRef(props, "modelValue");
18
18
  const modelType = toRef(props, "modelType");
19
19
  const modelUndefined = toRef(props, "modelUndefined");
20
+ const skipRequiredModelInit = toRef(props, "skipRequiredModelInit");
20
21
  const decimalDivider = toRef(props, "decimalDivider");
21
22
  const disabled = toRef(props, "disabled");
22
23
  const decimalPartLength = toRef(props, "decimalPartLength");
@@ -36,7 +37,7 @@ export default function ModelAPI(props, {
36
37
  });
37
38
 
38
39
  const modelUndefinedLocal = computed(() => {
39
- if (!required.value) {
40
+ if (!required.value || skipRequiredModelInit.value) {
40
41
  return modelUndefined.value;
41
42
  }
42
43
  if (!decimalPartLength.value) {
@@ -53,7 +54,7 @@ export default function ModelAPI(props, {
53
54
  const setCurrentValue = ({ value, updateOutside = false, trigger, triggerDetails } = {}) => {
54
55
  displayValue.value = isNil(value) ? "" : value;
55
56
  let newVal;
56
- if (!required.value && isNil(value)) {
57
+ if ((!required.value || skipRequiredModelInit.value) && isNil(value)) {
57
58
  newVal = modelUndefinedLocal.value;
58
59
  } else {
59
60
  newVal = modelType.value === "number" ?