aloha-vue 2.53.0 → 2.55.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.
@@ -1,63 +1,63 @@
1
- import {
2
- computed,
3
- toRef,
4
- watch,
5
- } from "vue";
6
-
7
- import {
8
- AKeyId,
9
- } from "../../const/AKeys";
10
- import {
11
- forEach,
12
- get,
13
- isNil,
14
- } from "lodash-es";
15
-
16
- export default function IndexesForOpenAPI(props, {
17
- idsForOpen = computed(() => []),
18
- dataWithIds = computed(() => []),
19
- }) {
20
- const indexesForOpen = toRef(props, "indexesForOpen");
21
- const keyChildren = toRef(props, "keyChildren");
22
-
23
- const getPathForIndexForOpen = ({ indexForOpen }) => {
24
- let path = `${ indexForOpen }`.replaceAll(".", `.${ keyChildren.value }.`);
25
- path += `.${ AKeyId }`;
26
- return path;
27
- };
28
-
29
- const setIdsFromIndexesForOpen = ({ isInit } = {}) => {
30
- if (isInit && !indexesForOpen.value.length) {
31
- return;
32
- }
33
- const IDS_FOR_OPEN = [];
34
- if (keyChildren.value) {
35
- forEach(indexesForOpen.value, indexForOpen => {
36
- const ID = get(dataWithIds.value, getPathForIndexForOpen({ indexForOpen }));
37
- if (!isNil(ID)) {
38
- IDS_FOR_OPEN.push(ID);
39
- }
40
- });
41
- } else {
42
- forEach(indexesForOpen.value, indexForOpen => {
43
- const ID = get(dataWithIds.value, `${ indexForOpen }.${ AKeyId }`);
44
- if (!isNil(ID)) {
45
- IDS_FOR_OPEN.push(ID);
46
- }
47
- });
48
- }
49
- idsForOpen.value = IDS_FOR_OPEN;
50
- };
51
-
52
- const initIdsFromIndexesForOpen = () => {
53
- setIdsFromIndexesForOpen({ isInit: true });
54
- };
55
-
56
- watch(indexesForOpen, () => {
57
- setIdsFromIndexesForOpen();
58
- });
59
-
60
- return {
61
- initIdsFromIndexesForOpen,
62
- };
63
- }
1
+ import {
2
+ computed,
3
+ toRef,
4
+ watch,
5
+ } from "vue";
6
+
7
+ import {
8
+ AKeyId,
9
+ } from "../../const/AKeys";
10
+ import {
11
+ forEach,
12
+ get,
13
+ isNil,
14
+ } from "lodash-es";
15
+
16
+ export default function IndexesForOpenAPI(props, {
17
+ idsForOpen = computed(() => []),
18
+ dataWithIds = computed(() => []),
19
+ }) {
20
+ const indexesForOpen = toRef(props, "indexesForOpen");
21
+ const keyChildren = toRef(props, "keyChildren");
22
+
23
+ const getPathForIndexForOpen = ({ indexForOpen }) => {
24
+ let path = `${ indexForOpen }`.replaceAll(".", `.${ keyChildren.value }.`);
25
+ path += `.${ AKeyId }`;
26
+ return path;
27
+ };
28
+
29
+ const setIdsFromIndexesForOpen = ({ isInit } = {}) => {
30
+ if (isInit && !indexesForOpen.value.length) {
31
+ return;
32
+ }
33
+ const IDS_FOR_OPEN = [];
34
+ if (keyChildren.value) {
35
+ forEach(indexesForOpen.value, indexForOpen => {
36
+ const ID = get(dataWithIds.value, getPathForIndexForOpen({ indexForOpen }));
37
+ if (!isNil(ID)) {
38
+ IDS_FOR_OPEN.push(ID);
39
+ }
40
+ });
41
+ } else {
42
+ forEach(indexesForOpen.value, indexForOpen => {
43
+ const ID = get(dataWithIds.value, `${ indexForOpen }.${ AKeyId }`);
44
+ if (!isNil(ID)) {
45
+ IDS_FOR_OPEN.push(ID);
46
+ }
47
+ });
48
+ }
49
+ idsForOpen.value = IDS_FOR_OPEN;
50
+ };
51
+
52
+ const initIdsFromIndexesForOpen = () => {
53
+ setIdsFromIndexesForOpen({ isInit: true });
54
+ };
55
+
56
+ watch(indexesForOpen, () => {
57
+ setIdsFromIndexesForOpen();
58
+ });
59
+
60
+ return {
61
+ initIdsFromIndexesForOpen,
62
+ };
63
+ }
@@ -1,81 +1,85 @@
1
- import {
2
- ref,
3
- toRef,
4
- watch,
5
- } from "vue";
6
-
7
- import {
8
- AKeyId,
9
- } from "../../const/AKeys";
10
- import {
11
- cloneDeep,
12
- filter,
13
- isEqual,
14
- startsWith,
15
- } from "lodash-es";
16
-
17
- export default function ToggleAPI(props, { emit }) {
18
- const alwaysOpen = toRef(props, "alwaysOpen");
19
- const disabled = toRef(props, "disabled");
20
- const idsForOpenDefault = toRef(props, "idsForOpenDefault");
21
- const prevent = toRef(props, "prevent");
22
- const stop = toRef(props, "stop");
23
-
24
- const idsForOpen = ref(undefined);
25
-
26
- const initIdsForOpen = () => {
27
- idsForOpen.value = idsForOpenDefault.value;
28
- };
29
-
30
- const toggleWithAlwaysOpen = ({ currentId, isOpen }) => {
31
- if (isOpen) {
32
- const CURRENT_ID_PREFIX = currentId.split("__")[0];
33
- idsForOpen.value = filter(idsForOpen.value, index => {
34
- return !startsWith(index, CURRENT_ID_PREFIX);
35
- });
36
- } else {
37
- idsForOpen.value.push(currentId);
38
- }
39
- };
40
-
41
- const toggleWithoutAlwaysOpen = ({ currentId, parentsIds, isOpen }) => {
42
- if (isOpen) {
43
- idsForOpen.value = parentsIds;
44
- } else {
45
- idsForOpen.value = [...parentsIds, currentId];
46
- }
47
- };
48
-
49
- const toggleLocal = ({ item, parentsIds, isOpen, $event }) => {
50
- if (disabled.value) {
51
- return;
52
- }
53
- const PARENT_IDS = cloneDeep(parentsIds);
54
- const CURRENT_ID = item[AKeyId];
55
- if (alwaysOpen.value) {
56
- toggleWithAlwaysOpen({ item, currentId: CURRENT_ID, isOpen });
57
- } else {
58
- toggleWithoutAlwaysOpen({ parentsIds: PARENT_IDS, currentId: CURRENT_ID, isOpen });
59
- }
60
- emit("toggle", { idsForOpen: idsForOpen.value, currentId: CURRENT_ID, parentsIds: PARENT_IDS, isOpen: isOpen, $event, item });
61
-
62
- if (stop.value && $event) {
63
- $event.stopPropagation();
64
- }
65
- if (prevent.value && $event) {
66
- $event.preventDefault();
67
- }
68
- };
69
-
70
- watch(idsForOpenDefault, newValue => {
71
- if (!isEqual(newValue, idsForOpen.value)) {
72
- idsForOpen.value = cloneDeep(newValue);
73
- }
74
- });
75
-
76
- return {
77
- idsForOpen,
78
- initIdsForOpen,
79
- toggleLocal,
80
- };
81
- }
1
+ import {
2
+ ref,
3
+ toRef,
4
+ watch,
5
+ } from "vue";
6
+
7
+ import {
8
+ AKeyId,
9
+ } from "../../const/AKeys";
10
+ import {
11
+ cloneDeep,
12
+ filter,
13
+ isEqual,
14
+ startsWith,
15
+ } from "lodash-es";
16
+
17
+ export default function ToggleAPI(props, { emit }) {
18
+ const alwaysOpen = toRef(props, "alwaysOpen");
19
+ const disabled = toRef(props, "disabled");
20
+ const idsForOpenDefault = toRef(props, "idsForOpenDefault");
21
+ const oneItemAlwaysOpen = toRef(props, "oneItemAlwaysOpen");
22
+ const prevent = toRef(props, "prevent");
23
+ const stop = toRef(props, "stop");
24
+
25
+ const idsForOpen = ref(undefined);
26
+
27
+ const initIdsForOpen = () => {
28
+ idsForOpen.value = idsForOpenDefault.value;
29
+ };
30
+
31
+ const toggleWithAlwaysOpen = ({ currentId, isOpen }) => {
32
+ if (isOpen) {
33
+ const CURRENT_ID_PREFIX = currentId.split("__")[0];
34
+ idsForOpen.value = filter(idsForOpen.value, index => {
35
+ return !startsWith(index, CURRENT_ID_PREFIX);
36
+ });
37
+ } else {
38
+ idsForOpen.value.push(currentId);
39
+ }
40
+ };
41
+
42
+ const toggleWithoutAlwaysOpen = ({ currentId, parentsIds, isOpen }) => {
43
+ if (isOpen) {
44
+ if (oneItemAlwaysOpen.value) {
45
+ return;
46
+ }
47
+ idsForOpen.value = parentsIds;
48
+ } else {
49
+ idsForOpen.value = [...parentsIds, currentId];
50
+ }
51
+ };
52
+
53
+ const toggleLocal = ({ item, parentsIds, isOpen, $event }) => {
54
+ if (disabled.value) {
55
+ return;
56
+ }
57
+ const PARENT_IDS = cloneDeep(parentsIds);
58
+ const CURRENT_ID = item[AKeyId];
59
+ if (alwaysOpen.value) {
60
+ toggleWithAlwaysOpen({ item, currentId: CURRENT_ID, isOpen });
61
+ } else {
62
+ toggleWithoutAlwaysOpen({ parentsIds: PARENT_IDS, currentId: CURRENT_ID, isOpen });
63
+ }
64
+ emit("toggle", { idsForOpen: idsForOpen.value, currentId: CURRENT_ID, parentsIds: PARENT_IDS, isOpen: isOpen, $event, item });
65
+
66
+ if (stop.value && $event) {
67
+ $event.stopPropagation();
68
+ }
69
+ if (prevent.value && $event) {
70
+ $event.preventDefault();
71
+ }
72
+ };
73
+
74
+ watch(idsForOpenDefault, newValue => {
75
+ if (!isEqual(newValue, idsForOpen.value)) {
76
+ idsForOpen.value = cloneDeep(newValue);
77
+ }
78
+ });
79
+
80
+ return {
81
+ idsForOpen,
82
+ initIdsForOpen,
83
+ toggleLocal,
84
+ };
85
+ }
@@ -15,8 +15,6 @@ import {
15
15
  focusableSelector,
16
16
  } from "../index";
17
17
 
18
- import ADropdownAction from "./ADropdownAction/ADropdownAction";
19
-
20
18
  import APopupAPI from "../compositionAPI/APopupAPI";
21
19
  import ActionsAPI from "./compositionAPI/ActionsAPI";
22
20
  import AttributesAPI from "./compositionAPI/AttributesAPI";
@@ -28,6 +26,7 @@ import PopperContainerAPI from "../ATooltip/compositionAPI/PopperContainerAPI";
28
26
  import RefsAPI from "./compositionAPI/RefsAPI";
29
27
  import ToggleAPI from "./compositionAPI/ToggleAPI";
30
28
 
29
+ import ADropdownGroup from "./ADropdownGroup";
31
30
  import ChevronDown from "aloha-svg/dist/js/bootstrap/ChevronDown";
32
31
  import {
33
32
  difference,
@@ -189,6 +188,16 @@ export default {
189
188
  required: false,
190
189
  default: undefined,
191
190
  },
191
+ keyGroup: {
192
+ type: [String, Number, Array],
193
+ required: false,
194
+ default: undefined,
195
+ },
196
+ keyGroupLabelCallback: {
197
+ type: Function,
198
+ required: false,
199
+ default: undefined,
200
+ },
192
201
  floatingFlip: {
193
202
  type: Object,
194
203
  required: false,
@@ -220,7 +229,7 @@ export default {
220
229
  id: {
221
230
  type: String,
222
231
  required: false,
223
- default: () => uniqueId("a_dropdown_btn_"),
232
+ default: () => uniqueId("a_dropdown_"),
224
233
  },
225
234
  inBody: {
226
235
  type: Boolean,
@@ -237,6 +246,11 @@ export default {
237
246
  required: false,
238
247
  default: true,
239
248
  },
249
+ isCloseByButtonInvisibleInViewport: {
250
+ type: Boolean,
251
+ required: false,
252
+ default: true,
253
+ },
240
254
  isHideWithoutActionAndSlot: {
241
255
  type: Boolean,
242
256
  required: false,
@@ -282,6 +296,12 @@ export default {
282
296
  required: false,
283
297
  default: false,
284
298
  },
299
+ sortOrderGroup: {
300
+ type: String,
301
+ required: false,
302
+ default: undefined,
303
+ validator: value => ["asc", "desc"].indexOf(value) !== -1,
304
+ },
285
305
  triggers: {
286
306
  type: Array,
287
307
  required: false,
@@ -330,6 +350,7 @@ export default {
330
350
  } = PopoverAPI(props, {
331
351
  dropdownButtonRef,
332
352
  dropdownRef,
353
+ onReferenceHidden,
333
354
  });
334
355
 
335
356
  const {
@@ -394,6 +415,13 @@ export default {
394
415
  buttonClassLocal,
395
416
  } = ClassAPI(props);
396
417
 
418
+ function onReferenceHidden() {
419
+ onClose({
420
+ isFocusButton: false,
421
+ trigger: "referenceHidden",
422
+ });
423
+ }
424
+
397
425
  initWasOpened();
398
426
 
399
427
  onMounted(() => {
@@ -491,7 +519,6 @@ export default {
491
519
  "div",
492
520
  {
493
521
  ref: "dropdownRef",
494
- role: "application",
495
522
  "aria-labelledby": this.idLocal,
496
523
  ariaHidden: !this.statusExpanded,
497
524
  ...this.dropdownAttributesLocal,
@@ -499,13 +526,11 @@ export default {
499
526
  [
500
527
  h(this.dropdownTag, {}, [
501
528
  this.$slots.dropdown && this.$slots.dropdown(),
502
- this.hasActions && this.actionsFiltered.map((action, actionIndex) => {
503
- return h(ADropdownAction, {
504
- key: actionIndex,
505
- action,
506
- alwaysTranslate: this.alwaysTranslate,
507
- }, this.$slots);
508
- }),
529
+ this.hasActions && h(ADropdownGroup, {
530
+ actions: this.actionsFiltered,
531
+ alwaysTranslate: this.alwaysTranslate,
532
+ dropdownId: this.idLocal,
533
+ }, this.$slots),
509
534
  ]),
510
535
  ],
511
536
  ), [
@@ -0,0 +1,85 @@
1
+ import {
2
+ h,
3
+ resolveComponent,
4
+ } from "vue";
5
+ import {
6
+ ATranslation,
7
+ } from "../index";
8
+
9
+ import ADropdownAction from "./ADropdownAction/ADropdownAction";
10
+
11
+ export default {
12
+ name: "ADropdownGroup",
13
+ props: {
14
+ actions: {
15
+ type: Array,
16
+ required: true,
17
+ },
18
+ alwaysTranslate: {
19
+ type: Boolean,
20
+ required: false,
21
+ },
22
+ dropdownId: {
23
+ type: String,
24
+ required: true,
25
+ },
26
+ levelIndex: {
27
+ type: Number,
28
+ required: false,
29
+ default: 0,
30
+ },
31
+ },
32
+ render() {
33
+ return this.actions.map((action, actionIndex) => {
34
+ if (action.__isDropdownGroup) {
35
+ if (!action.groupLabel) {
36
+ return h(resolveComponent("ADropdownGroup"), {
37
+ key: `group_${ this.levelIndex }_${ actionIndex }`,
38
+ actions: action.children,
39
+ alwaysTranslate: this.alwaysTranslate,
40
+ dropdownId: this.dropdownId,
41
+ levelIndex: this.levelIndex + 1,
42
+ }, this.$slots);
43
+ }
44
+
45
+ const labelId = `${ this.dropdownId }_group_${ this.levelIndex }_${ actionIndex }`;
46
+
47
+ return h("li", {
48
+ key: `group_${ this.levelIndex }_${ actionIndex }`,
49
+ class: [
50
+ "a_dropdown__group",
51
+ `a_dropdown__group_level_${ this.levelIndex }`,
52
+ ],
53
+ }, [
54
+ h(ATranslation, {
55
+ id: labelId,
56
+ alwaysTranslate: this.alwaysTranslate,
57
+ class: [
58
+ "a_dropdown__group__label",
59
+ "a_dropdown__item_header",
60
+ ],
61
+ html: action.groupLabel,
62
+ tag: "div",
63
+ }),
64
+ h("ul", {
65
+ class: "a_dropdown__group__list",
66
+ "aria-labelledby": labelId,
67
+ }, [
68
+ h(resolveComponent("ADropdownGroup"), {
69
+ actions: action.children,
70
+ alwaysTranslate: this.alwaysTranslate,
71
+ dropdownId: this.dropdownId,
72
+ levelIndex: this.levelIndex + 1,
73
+ }, this.$slots),
74
+ ]),
75
+ ]);
76
+ }
77
+
78
+ return h(ADropdownAction, {
79
+ key: `action_${ this.levelIndex }_${ actionIndex }`,
80
+ action,
81
+ alwaysTranslate: this.alwaysTranslate,
82
+ }, this.$slots);
83
+ });
84
+ },
85
+ };
@@ -1,27 +1,147 @@
1
- import {
2
- computed,
3
- toRef,
4
- } from "vue";
5
-
6
- import {
7
- filterActionsHiddenAndDivider,
8
- } from "../../utils/actions";
9
-
10
- export default function ActionsAPI(props) {
11
- const actions = toRef(props, "actions");
12
-
13
- const actionsFiltered = computed(() => {
14
- return filterActionsHiddenAndDivider({
15
- actions: actions.value,
16
- });
17
- });
18
-
19
- const hasActions = computed(() => {
20
- return actionsFiltered.value.length > 0;
21
- });
22
-
23
- return {
24
- actionsFiltered,
25
- hasActions,
26
- };
27
- }
1
+ import {
2
+ computed,
3
+ toRef,
4
+ } from "vue";
5
+
6
+ import {
7
+ aOrderBy,
8
+ } from "../../utils/utils";
9
+
10
+ import {
11
+ filterActionsDivider,
12
+ filterActionsHiddenAndDivider,
13
+ } from "../../utils/actions";
14
+ import {
15
+ filter,
16
+ forEach,
17
+ get,
18
+ isArray,
19
+ isFunction,
20
+ isNil,
21
+ isString,
22
+ } from "lodash-es";
23
+
24
+ export default function ActionsAPI(props) {
25
+ const actions = toRef(props, "actions");
26
+ const keyGroup = toRef(props, "keyGroup");
27
+ const keyGroupLabelCallback = toRef(props, "keyGroupLabelCallback");
28
+ const sortOrderGroup = toRef(props, "sortOrderGroup");
29
+
30
+ const keyGroupArray = computed(() => {
31
+ if (isArray(keyGroup.value)) {
32
+ return keyGroup.value;
33
+ }
34
+ if (isString(keyGroup.value)) {
35
+ return [keyGroup.value];
36
+ }
37
+ return [];
38
+ });
39
+
40
+ const hasKeyGroup = computed(() => {
41
+ return keyGroupArray.value.length > 0;
42
+ });
43
+
44
+ const actionsVisible = computed(() => {
45
+ return filter(actions.value, action => !action.isHidden);
46
+ });
47
+
48
+ const getGroupedActions = ({
49
+ actionsLocal = [],
50
+ levelIndex = 0,
51
+ parentGroups = [],
52
+ }) => {
53
+ if (levelIndex >= keyGroupArray.value.length) {
54
+ return filterActionsDivider({
55
+ actions: actionsLocal,
56
+ });
57
+ }
58
+
59
+ const ACTIONS_WITHOUT_GROUP = [];
60
+ const GROUPS = {};
61
+
62
+ forEach(actionsLocal, action => {
63
+ const GROUP_KEY = get(action, keyGroupArray.value[levelIndex]);
64
+ if (isNil(GROUP_KEY) || GROUP_KEY === "") {
65
+ ACTIONS_WITHOUT_GROUP.push(action);
66
+ return;
67
+ }
68
+
69
+ if (!GROUPS[GROUP_KEY]) {
70
+ GROUPS[GROUP_KEY] = {
71
+ groupKey: GROUP_KEY,
72
+ item: action,
73
+ actions: [],
74
+ };
75
+ }
76
+ GROUPS[GROUP_KEY].actions.push(action);
77
+ });
78
+
79
+ const ACTIONS_GROUPED = [];
80
+
81
+ if (ACTIONS_WITHOUT_GROUP.length) {
82
+ ACTIONS_GROUPED.push(...getGroupedActions({
83
+ actionsLocal: ACTIONS_WITHOUT_GROUP,
84
+ levelIndex: levelIndex + 1,
85
+ parentGroups,
86
+ }));
87
+ }
88
+
89
+ let GROUPS_ARRAY = Object.values(GROUPS).map(group => {
90
+ const CHILDREN = getGroupedActions({
91
+ actionsLocal: group.actions,
92
+ levelIndex: levelIndex + 1,
93
+ parentGroups: [...parentGroups, group.groupKey],
94
+ });
95
+
96
+ if (!CHILDREN.length) {
97
+ return undefined;
98
+ }
99
+
100
+ return {
101
+ __isDropdownGroup: true,
102
+ children: CHILDREN,
103
+ groupKey: group.groupKey,
104
+ groupLabel: isFunction(keyGroupLabelCallback.value) ?
105
+ keyGroupLabelCallback.value({
106
+ group: group.groupKey,
107
+ item: group.item,
108
+ inDropdown: true,
109
+ levelIndex,
110
+ parentGroups,
111
+ }) :
112
+ group.groupKey,
113
+ };
114
+ }).filter(Boolean);
115
+
116
+ if (sortOrderGroup.value) {
117
+ GROUPS_ARRAY = aOrderBy(GROUPS_ARRAY, ["groupLabel"], [sortOrderGroup.value]);
118
+ }
119
+
120
+ ACTIONS_GROUPED.push(...GROUPS_ARRAY);
121
+
122
+ return ACTIONS_GROUPED;
123
+ };
124
+
125
+ const actionsFiltered = computed(() => {
126
+ if (hasKeyGroup.value) {
127
+ return getGroupedActions({
128
+ actionsLocal: actionsVisible.value,
129
+ });
130
+ }
131
+
132
+ return filterActionsHiddenAndDivider({
133
+ actions: actionsVisible.value,
134
+ });
135
+ });
136
+
137
+ const hasActions = computed(() => {
138
+ return actionsFiltered.value.length > 0;
139
+ });
140
+
141
+ return {
142
+ actionsFiltered,
143
+ hasActions,
144
+ hasKeyGroup,
145
+ keyGroupArray,
146
+ };
147
+ }