aloha-vue 1.0.235 → 1.0.237
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/docs/src/components/TheMenu/TheMenu.js +8 -0
- package/docs/src/main.js +12 -4
- package/docs/src/router/index.js +5 -0
- package/docs/src/views/PageDropdown/PageDropdown.pug +2 -4
- package/docs/src/views/PageGroupButtonDropdown/PageGroupButtonDropdown.js +52 -0
- package/docs/src/views/PageGroupButtonDropdown/PageGroupButtonDropdown.pug +8 -0
- package/docs/src/views/PageGroupButtonDropdown/PageGroupButtonDropdown.vue +2 -0
- package/docs/src/views/PageModal/PageModal.js +2 -0
- package/docs/src/views/PageModal/PageModal.pug +5 -2
- package/package.json +1 -1
- package/src/AButton/AButton.js +1 -0
- package/src/ADropdown/ADropdown.js +158 -32
- package/src/ADropdown/compositionAPI/ActionsAPI.js +4 -21
- package/src/ADropdown/compositionAPI/AttributesAPI.js +10 -13
- package/src/ADropdown/compositionAPI/PopoverAPI.js +1 -1
- package/src/AGroupButtonDropdown/AGroupButtonDropdown.js +85 -0
- package/src/AGroupButtonDropdown/AGroupButtonDropdownItem/AGroupButtonDropdownItem.js +91 -0
- package/src/AGroupButtonDropdown/AGroupButtonDropdownItem/compositionAPI/DropdownAPI.js +27 -0
- package/src/AGroupButtonDropdown/compositionAPI/ActionsAPI.js +106 -0
- package/src/compositionAPI/AMobileAPI.js +16 -0
- package/src/plugins/AGroupButtonDropdownPlugin.js +24 -0
- package/src/plugins/AMobilePlugin.js +25 -0
- package/src/styles/components/AButton.scss +3 -8
- package/src/styles/components/AGroupButtonDropdown.scss +5 -0
- package/src/styles/components/ALink.scss +3 -8
- package/src/styles/styles.scss +8 -0
- package/src/utils/actions.js +43 -0
package/docs/src/main.js
CHANGED
|
@@ -3,7 +3,8 @@ import { createApp } from "vue";
|
|
|
3
3
|
import store from "./store/index";
|
|
4
4
|
import router from "./router/index";
|
|
5
5
|
import AI18nPlugin from "../../src/plugins/AI18nPlugin";
|
|
6
|
-
|
|
6
|
+
import AMobilePlugin from "../../src/plugins/AMobilePlugin";
|
|
7
|
+
import AGroupButtonDropdownPlugin from "../../src/plugins/AGroupButtonDropdownPlugin";
|
|
7
8
|
import AIconPlugin from "../../src/plugins/AIconPlugin";
|
|
8
9
|
import AModalPlugin from "../../src/plugins/AModalPlugin";
|
|
9
10
|
import mainIcons from "./mainIcons";
|
|
@@ -28,14 +29,21 @@ const TRANSLATIONS = {
|
|
|
28
29
|
};
|
|
29
30
|
APP.use(AI18nPlugin, TRANSLATIONS, "de");
|
|
30
31
|
APP.use(AIconPlugin, mainIcons);
|
|
32
|
+
APP.use(AMobilePlugin, {
|
|
33
|
+
breakpoint: 991,
|
|
34
|
+
});
|
|
31
35
|
APP.use(AModalPlugin, {
|
|
32
36
|
propsDefault: {
|
|
33
37
|
closeButtonClass: "a_btn a_btn_link",
|
|
34
38
|
},
|
|
35
39
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
APP.use(AGroupButtonDropdownPlugin, {
|
|
41
|
+
propsDefault: {
|
|
42
|
+
dropdownAttributes: {
|
|
43
|
+
buttonText: "Weitere Aktionen",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
39
47
|
APP.config.unwrapInjectedRef = true;
|
|
40
48
|
APP.directive("SafeHtml", ASafeHtml);
|
|
41
49
|
APP.use(store).use(router).mount("#app");
|
package/docs/src/router/index.js
CHANGED
|
@@ -149,6 +149,11 @@ const ROUTES = [
|
|
|
149
149
|
name: "PageWizard",
|
|
150
150
|
component: () => import(/* webpackChunkName: "PageWizard" */ "../views/PageWizard/PageWizard.vue"),
|
|
151
151
|
},
|
|
152
|
+
{
|
|
153
|
+
path: "/group-button-dropdown",
|
|
154
|
+
name: "PageGroupButtonDropdown",
|
|
155
|
+
component: () => import(/* webpackChunkName: "PageGroupButtonDropdown" */ "../views/PageGroupButtonDropdown/PageGroupButtonDropdown.vue"),
|
|
156
|
+
},
|
|
152
157
|
{
|
|
153
158
|
// If the routing configuration '*' reports an error, replace it with '/: catchAll(. *)'
|
|
154
159
|
// caught Error: Catch all routes ("*") must now be defined using a param with a custom regexp
|
|
@@ -31,15 +31,13 @@ div
|
|
|
31
31
|
button-class="a_btn a_btn_primary"
|
|
32
32
|
:is-render-default="true"
|
|
33
33
|
:actions="dropdownActions"
|
|
34
|
+
button-text="Weitere Aktionen"
|
|
34
35
|
)
|
|
35
|
-
template(
|
|
36
|
-
v-slot:button
|
|
37
|
-
)
|
|
38
|
-
span Weitere Aktionen
|
|
39
36
|
|
|
40
37
|
a-dropdown.ml_3(
|
|
41
38
|
button-class="a_btn a_btn_primary"
|
|
42
39
|
:is-render-default="true"
|
|
40
|
+
|
|
43
41
|
)
|
|
44
42
|
template(
|
|
45
43
|
v-slot:button
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import AGroupButtonDropdown from "../../../../src/AGroupButtonDropdown/AGroupButtonDropdown";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
name: "PageGroupButtonDropdown",
|
|
5
|
+
components: {
|
|
6
|
+
AGroupButtonDropdown,
|
|
7
|
+
},
|
|
8
|
+
setup() {
|
|
9
|
+
const actions = [
|
|
10
|
+
{
|
|
11
|
+
text: "Actions 0",
|
|
12
|
+
type: "button",
|
|
13
|
+
callback: () => {},
|
|
14
|
+
isHidden: true,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
text: "Actions 1",
|
|
18
|
+
type: "button",
|
|
19
|
+
callback: () => {},
|
|
20
|
+
disabled: false,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: "divider",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: "divider",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
text: "Actions 2",
|
|
30
|
+
type: "button",
|
|
31
|
+
callback: () => {},
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: "link",
|
|
35
|
+
text: "Link 1",
|
|
36
|
+
href: "#",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: "divider",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: "link",
|
|
43
|
+
text: "Link 2",
|
|
44
|
+
href: "#",
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
actions,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import AButton from "../../../../src/AButton/AButton";
|
|
1
2
|
import AModal from "../../../../src/AModal/AModal";
|
|
2
3
|
|
|
3
4
|
import AConfirmAPI from "../../../../src/compositionAPI/AConfirmAPI";
|
|
@@ -5,6 +6,7 @@ import AConfirmAPI from "../../../../src/compositionAPI/AConfirmAPI";
|
|
|
5
6
|
export default {
|
|
6
7
|
name: "PageModal",
|
|
7
8
|
components: {
|
|
9
|
+
AButton,
|
|
8
10
|
AModal,
|
|
9
11
|
},
|
|
10
12
|
setup() {
|
package/package.json
CHANGED
package/src/AButton/AButton.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
h,
|
|
2
|
+
h,
|
|
3
|
+
onBeforeUnmount,
|
|
3
4
|
Teleport,
|
|
4
5
|
} from "vue";
|
|
5
6
|
|
|
7
|
+
import AButton from "../AButton/AButton";
|
|
6
8
|
import ADropdownAction from "./ADropdownAction/ADropdownAction";
|
|
7
9
|
import AIcon from "../AIcon/AIcon";
|
|
8
10
|
import ATranslation from "../ATranslation/ATranslation";
|
|
@@ -22,6 +24,7 @@ import {
|
|
|
22
24
|
|
|
23
25
|
export default {
|
|
24
26
|
name: "ADropdown",
|
|
27
|
+
inheritAttrs: false,
|
|
25
28
|
components: {
|
|
26
29
|
ATranslation,
|
|
27
30
|
},
|
|
@@ -41,6 +44,26 @@ export default {
|
|
|
41
44
|
required: false,
|
|
42
45
|
default: () => ({}),
|
|
43
46
|
},
|
|
47
|
+
buttonText: {
|
|
48
|
+
type: [String, Number],
|
|
49
|
+
required: false,
|
|
50
|
+
default: undefined,
|
|
51
|
+
},
|
|
52
|
+
buttonTextScreenReader: {
|
|
53
|
+
type: String,
|
|
54
|
+
required: false,
|
|
55
|
+
default: undefined,
|
|
56
|
+
},
|
|
57
|
+
buttonTextAriaHidden: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
required: false,
|
|
60
|
+
default: false,
|
|
61
|
+
},
|
|
62
|
+
buttonTextClass: {
|
|
63
|
+
type: String,
|
|
64
|
+
required: false,
|
|
65
|
+
default: undefined,
|
|
66
|
+
},
|
|
44
67
|
buttonClass: {
|
|
45
68
|
type: [String, Object],
|
|
46
69
|
required: false,
|
|
@@ -51,6 +74,76 @@ export default {
|
|
|
51
74
|
required: false,
|
|
52
75
|
default: "button",
|
|
53
76
|
},
|
|
77
|
+
buttonTitle: {
|
|
78
|
+
type: String,
|
|
79
|
+
required: false,
|
|
80
|
+
default: undefined,
|
|
81
|
+
},
|
|
82
|
+
buttonIsTitleHtml: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
required: false,
|
|
85
|
+
},
|
|
86
|
+
buttonTitlePlacement: {
|
|
87
|
+
type: String,
|
|
88
|
+
required: false,
|
|
89
|
+
default: "top",
|
|
90
|
+
validator: value => ["top", "left", "bottom", "right"].indexOf(value) !== -1,
|
|
91
|
+
},
|
|
92
|
+
buttonLoading: {
|
|
93
|
+
type: Boolean,
|
|
94
|
+
required: false,
|
|
95
|
+
default: false,
|
|
96
|
+
},
|
|
97
|
+
buttonLoadingClass: {
|
|
98
|
+
type: [String, Object],
|
|
99
|
+
required: false,
|
|
100
|
+
default: "a_spinner_small",
|
|
101
|
+
},
|
|
102
|
+
buttonLoadingAlign: {
|
|
103
|
+
type: String,
|
|
104
|
+
required: false,
|
|
105
|
+
default: "right",
|
|
106
|
+
validator: value => ["right", "left"].indexOf(value) !== -1,
|
|
107
|
+
},
|
|
108
|
+
buttonIcon: {
|
|
109
|
+
type: String,
|
|
110
|
+
required: false,
|
|
111
|
+
default: undefined,
|
|
112
|
+
},
|
|
113
|
+
buttonIconAlign: {
|
|
114
|
+
type: String,
|
|
115
|
+
required: false,
|
|
116
|
+
default: "left",
|
|
117
|
+
validator: value => ["right", "left"].indexOf(value) !== -1,
|
|
118
|
+
},
|
|
119
|
+
buttonIconClass: {
|
|
120
|
+
type: String,
|
|
121
|
+
required: false,
|
|
122
|
+
default: undefined,
|
|
123
|
+
},
|
|
124
|
+
buttonIconAttributes: {
|
|
125
|
+
type: Object,
|
|
126
|
+
required: false,
|
|
127
|
+
default: () => ({}),
|
|
128
|
+
},
|
|
129
|
+
buttonIconTag: {
|
|
130
|
+
type: String,
|
|
131
|
+
required: false,
|
|
132
|
+
default: undefined,
|
|
133
|
+
},
|
|
134
|
+
buttonPrevent: {
|
|
135
|
+
type: Boolean,
|
|
136
|
+
required: false,
|
|
137
|
+
},
|
|
138
|
+
buttonStop: {
|
|
139
|
+
type: Boolean,
|
|
140
|
+
required: false,
|
|
141
|
+
},
|
|
142
|
+
extraTranslate: {
|
|
143
|
+
type: Object,
|
|
144
|
+
required: false,
|
|
145
|
+
default: undefined,
|
|
146
|
+
},
|
|
54
147
|
classForTooltipInner: {
|
|
55
148
|
type: [String, Object],
|
|
56
149
|
required: false,
|
|
@@ -161,6 +254,8 @@ export default {
|
|
|
161
254
|
});
|
|
162
255
|
|
|
163
256
|
const {
|
|
257
|
+
idLocal,
|
|
258
|
+
buttonAttributesDisabled,
|
|
164
259
|
buttonAttributesLocal,
|
|
165
260
|
dropdownAttributesLocal,
|
|
166
261
|
isMenuRendered,
|
|
@@ -183,13 +278,18 @@ export default {
|
|
|
183
278
|
|
|
184
279
|
return {
|
|
185
280
|
actionsFiltered,
|
|
281
|
+
buttonAttributesDisabled,
|
|
186
282
|
buttonAttributesLocal,
|
|
187
283
|
buttonWidth,
|
|
188
284
|
dropdownAttributesLocal,
|
|
189
285
|
dropdownButtonRef,
|
|
190
286
|
dropdownRef,
|
|
191
287
|
hasActions,
|
|
288
|
+
idLocal,
|
|
192
289
|
isMenuRendered,
|
|
290
|
+
onToggle,
|
|
291
|
+
onKeydown,
|
|
292
|
+
statusExpanded,
|
|
193
293
|
};
|
|
194
294
|
},
|
|
195
295
|
render() {
|
|
@@ -198,39 +298,65 @@ export default {
|
|
|
198
298
|
!this.$slots.dropdown) {
|
|
199
299
|
return "";
|
|
200
300
|
}
|
|
201
|
-
return
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
301
|
+
return [
|
|
302
|
+
h(AButton, {
|
|
303
|
+
ref: "dropdownButtonRef",
|
|
304
|
+
...this.$attrs,
|
|
305
|
+
id: this.idLocal,
|
|
306
|
+
tag: this.buttonTag,
|
|
307
|
+
class: this.buttonClass,
|
|
308
|
+
text: this.buttonText,
|
|
309
|
+
textScreenReader: this.buttonTextScreenReader,
|
|
310
|
+
textAriaHidden: this.buttonTextAriaHidden,
|
|
311
|
+
textClass: this.buttonTextClass,
|
|
312
|
+
title: this.buttonTitle,
|
|
313
|
+
isTitleHtml: this.buttonIsTitleHtml,
|
|
314
|
+
titlePlacement: this.buttonTitlePlacement,
|
|
315
|
+
loading: this.buttonLoading,
|
|
316
|
+
loadingClass: this.buttonLoadingClass,
|
|
317
|
+
loadingAlign: this.buttonLoadingAlign,
|
|
318
|
+
icon: this.buttonIcon,
|
|
319
|
+
iconAlign: this.buttonIconAlign,
|
|
320
|
+
iconClass: this.buttonIconClass,
|
|
321
|
+
iconAttributes: this.buttonIconAttributes,
|
|
322
|
+
iconTag: this.buttonIconTag,
|
|
323
|
+
prevent: this.buttonPrevent,
|
|
324
|
+
stop: this.buttonStop,
|
|
325
|
+
extraTranslate: this.extraTranslate,
|
|
326
|
+
attributes: this.buttonAttributesLocal,
|
|
327
|
+
...this.buttonAttributesDisabled,
|
|
328
|
+
onClick: this.onToggle,
|
|
329
|
+
onKeydown: this.onKeydown,
|
|
330
|
+
}, {
|
|
331
|
+
default: () => {
|
|
332
|
+
return this.$slots.button && this.$slots.button();
|
|
333
|
+
},
|
|
334
|
+
buttonAppend: () => {
|
|
335
|
+
return this.isCaret && h(AIcon, {
|
|
210
336
|
class: "a_dropdown__caret",
|
|
211
337
|
icon: "ChevronDown",
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
338
|
+
});
|
|
339
|
+
},
|
|
340
|
+
}),
|
|
341
|
+
h(Teleport, {
|
|
342
|
+
to: "body",
|
|
343
|
+
}, [
|
|
344
|
+
this.isMenuRendered && h("div", null, [
|
|
345
|
+
h(
|
|
346
|
+
this.dropdownTag,
|
|
347
|
+
this.dropdownAttributesLocal,
|
|
348
|
+
[
|
|
349
|
+
this.$slots.dropdown && this.$slots.dropdown(),
|
|
350
|
+
this.hasActions && this.actionsFiltered.map((action, actionIndex) => {
|
|
351
|
+
return h(ADropdownAction, {
|
|
352
|
+
key: actionIndex,
|
|
353
|
+
action,
|
|
354
|
+
}, this.$slots);
|
|
355
|
+
}),
|
|
356
|
+
],
|
|
357
|
+
),
|
|
232
358
|
]),
|
|
233
|
-
],
|
|
234
|
-
|
|
359
|
+
]),
|
|
360
|
+
];
|
|
235
361
|
},
|
|
236
362
|
};
|
|
@@ -4,33 +4,16 @@ import {
|
|
|
4
4
|
} from "vue";
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
last,
|
|
10
|
-
} from "lodash-es";
|
|
7
|
+
filterActionsHiddenAndDivider,
|
|
8
|
+
} from "../../utils/actions";
|
|
11
9
|
|
|
12
10
|
export default function ActionsAPI(props) {
|
|
13
11
|
const actions = toRef(props, "actions");
|
|
14
12
|
|
|
15
13
|
const actionsFiltered = computed(() => {
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
return filterActionsHiddenAndDivider({
|
|
15
|
+
actions: actions.value,
|
|
18
16
|
});
|
|
19
|
-
|
|
20
|
-
const ACTIONS_DIVIDER_FILTERED = [];
|
|
21
|
-
forEach(ACTIONS_FILTERED, action => {
|
|
22
|
-
if (action.type !== "divider" ||
|
|
23
|
-
(ACTIONS_DIVIDER_FILTERED.length > 0 &&
|
|
24
|
-
last(ACTIONS_DIVIDER_FILTERED).type !== "divider")) {
|
|
25
|
-
ACTIONS_DIVIDER_FILTERED.push(action);
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
const LAST_ACTION = last(ACTIONS_DIVIDER_FILTERED);
|
|
29
|
-
if (LAST_ACTION && LAST_ACTION.type === "divider") {
|
|
30
|
-
ACTIONS_DIVIDER_FILTERED.pop();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return ACTIONS_DIVIDER_FILTERED;
|
|
34
17
|
});
|
|
35
18
|
|
|
36
19
|
const hasActions = computed(() => {
|
|
@@ -10,11 +10,8 @@ import {
|
|
|
10
10
|
|
|
11
11
|
export default function AttributesAPI(props, {
|
|
12
12
|
statusExpanded = ref(false),
|
|
13
|
-
onToggle = () => {},
|
|
14
|
-
onKeydown = () => {},
|
|
15
13
|
}) {
|
|
16
14
|
const buttonAttributes = toRef(props, "buttonAttributes");
|
|
17
|
-
const buttonClass = toRef(props, "buttonClass");
|
|
18
15
|
const buttonTag = toRef(props, "buttonTag");
|
|
19
16
|
const disabled = toRef(props, "disabled");
|
|
20
17
|
const dropdownAttributes = toRef(props, "dropdownAttributes");
|
|
@@ -29,27 +26,25 @@ export default function AttributesAPI(props, {
|
|
|
29
26
|
|
|
30
27
|
const buttonAttributesLocal = computed(() => {
|
|
31
28
|
const BUTTON_ATTRIBUTES = cloneDeep(buttonAttributes.value);
|
|
32
|
-
BUTTON_ATTRIBUTES.id = idLocal.value;
|
|
33
|
-
BUTTON_ATTRIBUTES.ref = "dropdownButtonRef";
|
|
34
29
|
BUTTON_ATTRIBUTES["aria-haspopup"] = "true";
|
|
35
30
|
BUTTON_ATTRIBUTES["aria-expanded"] = statusExpanded.value;
|
|
36
|
-
if (buttonClass.value) {
|
|
37
|
-
BUTTON_ATTRIBUTES.class = buttonClass.value;
|
|
38
|
-
}
|
|
39
|
-
BUTTON_ATTRIBUTES.onClick = onToggle;
|
|
40
|
-
BUTTON_ATTRIBUTES.onKeydown = onKeydown;
|
|
41
31
|
|
|
42
32
|
if (buttonTag.value === "button") {
|
|
43
33
|
BUTTON_ATTRIBUTES.type = BUTTON_ATTRIBUTES.type || "button";
|
|
44
34
|
}
|
|
35
|
+
return BUTTON_ATTRIBUTES;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const buttonAttributesDisabled = computed(() => {
|
|
39
|
+
const ATTRIBUTES = {};
|
|
45
40
|
if (disabled.value) {
|
|
46
41
|
if (buttonTag.value === "button") {
|
|
47
|
-
|
|
42
|
+
ATTRIBUTES.disabled = true;
|
|
48
43
|
} else if (buttonTag.value === "a") {
|
|
49
|
-
|
|
44
|
+
ATTRIBUTES.ariaDisabled = true;
|
|
50
45
|
}
|
|
51
46
|
}
|
|
52
|
-
return
|
|
47
|
+
return ATTRIBUTES;
|
|
53
48
|
});
|
|
54
49
|
|
|
55
50
|
const dropdownAttributesLocal = computed(() => {
|
|
@@ -70,6 +65,8 @@ export default function AttributesAPI(props, {
|
|
|
70
65
|
});
|
|
71
66
|
|
|
72
67
|
return {
|
|
68
|
+
idLocal,
|
|
69
|
+
buttonAttributesDisabled,
|
|
73
70
|
buttonAttributesLocal,
|
|
74
71
|
dropdownAttributesLocal,
|
|
75
72
|
isMenuRendered,
|
|
@@ -17,7 +17,7 @@ export default function PopoverAPI(props, {
|
|
|
17
17
|
const openPopoverWithPopperjs = () => {
|
|
18
18
|
if (!popper.value) {
|
|
19
19
|
popper.value = createPopper(
|
|
20
|
-
dropdownButtonRef.value,
|
|
20
|
+
dropdownButtonRef.value.$el,
|
|
21
21
|
dropdownRef.value,
|
|
22
22
|
{
|
|
23
23
|
placement: placement.value,
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import {
|
|
2
|
+
h,
|
|
3
|
+
} from "vue";
|
|
4
|
+
|
|
5
|
+
import AGroupButtonDropdownItem from "./AGroupButtonDropdownItem/AGroupButtonDropdownItem";
|
|
6
|
+
|
|
7
|
+
import ActionsAPI from "./compositionAPI/ActionsAPI";
|
|
8
|
+
import {
|
|
9
|
+
groupButtonDropdownPluginOptions,
|
|
10
|
+
} from "../plugins/AGroupButtonDropdownPlugin";
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
name: "AGroupButtonDropdown",
|
|
14
|
+
props: {
|
|
15
|
+
actions: {
|
|
16
|
+
type: Array,
|
|
17
|
+
required: false,
|
|
18
|
+
default: () => [],
|
|
19
|
+
},
|
|
20
|
+
actionsClasses: {
|
|
21
|
+
type: Array,
|
|
22
|
+
required: false,
|
|
23
|
+
default: () => groupButtonDropdownPluginOptions.value.propsDefault.actionsClasses,
|
|
24
|
+
},
|
|
25
|
+
dropdownAttributes: {
|
|
26
|
+
type: Object,
|
|
27
|
+
required: false,
|
|
28
|
+
default: () => groupButtonDropdownPluginOptions.value.propsDefault.dropdownAttributes,
|
|
29
|
+
},
|
|
30
|
+
hasDividerBeforeDropdown: {
|
|
31
|
+
type: Boolean,
|
|
32
|
+
required: false,
|
|
33
|
+
default: () => groupButtonDropdownPluginOptions.value.propsDefault.hasDividerBeforeDropdown,
|
|
34
|
+
},
|
|
35
|
+
indexFirstDropdownAction: {
|
|
36
|
+
type: Number,
|
|
37
|
+
required: false,
|
|
38
|
+
default: () => groupButtonDropdownPluginOptions.value.propsDefault.indexFirstDropdownAction,
|
|
39
|
+
validator: value => value > -1,
|
|
40
|
+
},
|
|
41
|
+
indexFirstDropdownActionMobile: {
|
|
42
|
+
type: Number,
|
|
43
|
+
required: false,
|
|
44
|
+
default: () => groupButtonDropdownPluginOptions.value.propsDefault.indexFirstDropdownActionMobile,
|
|
45
|
+
validator: value => value > -1,
|
|
46
|
+
},
|
|
47
|
+
minDropdownActions: {
|
|
48
|
+
type: Number,
|
|
49
|
+
required: false,
|
|
50
|
+
default: () => groupButtonDropdownPluginOptions.value.propsDefault.minDropdownActions,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
setup(props) {
|
|
54
|
+
const {
|
|
55
|
+
actionsAllFiltered,
|
|
56
|
+
actionsGrouped,
|
|
57
|
+
hasDropdownActions,
|
|
58
|
+
} = ActionsAPI(props);
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
actionsAllFiltered,
|
|
62
|
+
actionsGrouped,
|
|
63
|
+
hasDropdownActions,
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
render() {
|
|
67
|
+
if (this.actionsAllFiltered.length) {
|
|
68
|
+
return h("div", {
|
|
69
|
+
class: "aloha_group_btn_dropdown",
|
|
70
|
+
}, [
|
|
71
|
+
...this.actionsGrouped.buttons.map((item, itemIndex) => {
|
|
72
|
+
return h(AGroupButtonDropdownItem, {
|
|
73
|
+
data: item,
|
|
74
|
+
actionsDropdown: this.actionsGrouped.dropdown,
|
|
75
|
+
hasDropdownActions: this.hasDropdownActions,
|
|
76
|
+
dropdownAttributes: this.dropdownAttributes,
|
|
77
|
+
actionsClasses: this.actionsClasses,
|
|
78
|
+
isLast: itemIndex === this.actionsGrouped.buttons.length - 1,
|
|
79
|
+
hasDividerBeforeDropdown: this.hasDividerBeforeDropdown,
|
|
80
|
+
}, this.$slots);
|
|
81
|
+
}),
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {
|
|
2
|
+
h,
|
|
3
|
+
} from "vue";
|
|
4
|
+
|
|
5
|
+
import AButton from "../../AButton/AButton";
|
|
6
|
+
import ADropdown from "../../ADropdown/ADropdown";
|
|
7
|
+
import ALink from "../../ALink/ALink";
|
|
8
|
+
|
|
9
|
+
import DropdownAPI from "./compositionAPI/DropdownAPI";
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
name: "AGroupButtonDropdownItem",
|
|
13
|
+
props: {
|
|
14
|
+
data: {
|
|
15
|
+
type: Object,
|
|
16
|
+
required: true,
|
|
17
|
+
},
|
|
18
|
+
actionsDropdown: {
|
|
19
|
+
type: Array,
|
|
20
|
+
required: true,
|
|
21
|
+
},
|
|
22
|
+
hasDropdownActions: {
|
|
23
|
+
type: Boolean,
|
|
24
|
+
required: true,
|
|
25
|
+
},
|
|
26
|
+
dropdownAttributes: {
|
|
27
|
+
type: Object,
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
isLast: {
|
|
31
|
+
type: Boolean,
|
|
32
|
+
required: true,
|
|
33
|
+
},
|
|
34
|
+
actionsClasses: {
|
|
35
|
+
type: Array,
|
|
36
|
+
required: true,
|
|
37
|
+
},
|
|
38
|
+
hasDividerBeforeDropdown: {
|
|
39
|
+
type: Boolean,
|
|
40
|
+
required: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
setup(props) {
|
|
44
|
+
const {
|
|
45
|
+
isDropdownActionsAfterGroup,
|
|
46
|
+
isDropdownActionsInGroup,
|
|
47
|
+
} = DropdownAPI(props);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
isDropdownActionsAfterGroup,
|
|
51
|
+
isDropdownActionsInGroup,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
render() {
|
|
55
|
+
return [
|
|
56
|
+
h("div", {
|
|
57
|
+
class: "a_btn_group",
|
|
58
|
+
}, [
|
|
59
|
+
...this.data.children.map(action => {
|
|
60
|
+
if (action.type === "button") {
|
|
61
|
+
return h(AButton, {
|
|
62
|
+
class: this.actionsClasses[action.actionNotDividerIndex],
|
|
63
|
+
...action,
|
|
64
|
+
onClick: action.callback,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (action.type === "link") {
|
|
68
|
+
return h(ALink, action);
|
|
69
|
+
}
|
|
70
|
+
if (action.type === "template" &&
|
|
71
|
+
action.slotName &&
|
|
72
|
+
this.$slots[action.slotName]) {
|
|
73
|
+
return this.$slots[action.slotName]({
|
|
74
|
+
action: action,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}),
|
|
78
|
+
this.isDropdownActionsInGroup && h(ADropdown, {
|
|
79
|
+
isHideWithoutActionAndSlot: true,
|
|
80
|
+
actions: this.actionsDropdown,
|
|
81
|
+
...this.dropdownAttributes,
|
|
82
|
+
}, this.$slots),
|
|
83
|
+
]),
|
|
84
|
+
this.isDropdownActionsAfterGroup && h(ADropdown, {
|
|
85
|
+
isHideWithoutActionAndSlot: true,
|
|
86
|
+
actions: this.actionsDropdown,
|
|
87
|
+
...this.dropdownAttributes,
|
|
88
|
+
}, this.$slots),
|
|
89
|
+
];
|
|
90
|
+
},
|
|
91
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
computed,
|
|
3
|
+
toRef,
|
|
4
|
+
} from "vue";
|
|
5
|
+
|
|
6
|
+
export default function DropdownAPI(props) {
|
|
7
|
+
const isLast = toRef(props, "isLast");
|
|
8
|
+
const hasDropdownActions = toRef(props, "hasDropdownActions");
|
|
9
|
+
const hasDividerBeforeDropdown = toRef(props, "hasDividerBeforeDropdown");
|
|
10
|
+
|
|
11
|
+
const isDropdownActionsVisible = computed(() => {
|
|
12
|
+
return isLast.value && hasDropdownActions.value;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const isDropdownActionsInGroup = computed(() => {
|
|
16
|
+
return isDropdownActionsVisible.value && !hasDividerBeforeDropdown.value;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const isDropdownActionsAfterGroup = computed(() => {
|
|
20
|
+
return isDropdownActionsVisible.value && hasDividerBeforeDropdown.value;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
isDropdownActionsAfterGroup,
|
|
25
|
+
isDropdownActionsInGroup,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
computed,
|
|
3
|
+
toRef,
|
|
4
|
+
} from "vue";
|
|
5
|
+
|
|
6
|
+
import AMobileAPI from "../../compositionAPI/AMobileAPI";
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
filterActionsHiddenAndDivider,
|
|
10
|
+
} from "../../utils/actions";
|
|
11
|
+
import {
|
|
12
|
+
cloneDeep,
|
|
13
|
+
forEach, last,
|
|
14
|
+
} from "lodash-es";
|
|
15
|
+
|
|
16
|
+
export default function ActionsAPI(props) {
|
|
17
|
+
const actions = toRef(props, "actions");
|
|
18
|
+
const indexFirstDropdownAction = toRef(props, "indexFirstDropdownAction");
|
|
19
|
+
const indexFirstDropdownActionMobile = toRef(props, "indexFirstDropdownActionMobile");
|
|
20
|
+
const minDropdownActions = toRef(props, "minDropdownActions");
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
isMobile,
|
|
24
|
+
} = AMobileAPI();
|
|
25
|
+
|
|
26
|
+
const actionsAllFiltered = computed(() => {
|
|
27
|
+
return filterActionsHiddenAndDivider({
|
|
28
|
+
actions: actions.value,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const currentIndexFirstDropdownAction = computed(() => {
|
|
33
|
+
return isMobile.value ? indexFirstDropdownActionMobile.value : indexFirstDropdownAction.value;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const hasMoreEqualActionsThenParameter = ({ actions = [], minCountActions = 0 }) => {
|
|
37
|
+
let countActions = 0;
|
|
38
|
+
forEach(actions, action => {
|
|
39
|
+
if (countActions >= minCountActions) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
if (action.type !== "divider") {
|
|
43
|
+
countActions++;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return countActions >= minCountActions;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const actionsGrouped = computed(() => {
|
|
51
|
+
const ACTIONS_ALL = cloneDeep(actionsAllFiltered.value);
|
|
52
|
+
|
|
53
|
+
const ACTIONS_GROUPED = {
|
|
54
|
+
buttons: [],
|
|
55
|
+
dropdown: [],
|
|
56
|
+
};
|
|
57
|
+
let actionNotDividerIndex = 0;
|
|
58
|
+
let isPreviousActionDivider = true;
|
|
59
|
+
forEach(ACTIONS_ALL, (action, actionIndex) => {
|
|
60
|
+
if (actionNotDividerIndex === currentIndexFirstDropdownAction.value) {
|
|
61
|
+
const ACTION_DROPDOWN = ACTIONS_ALL.slice(actionIndex, ACTIONS_ALL.length);
|
|
62
|
+
|
|
63
|
+
if (hasMoreEqualActionsThenParameter({
|
|
64
|
+
actions: ACTION_DROPDOWN,
|
|
65
|
+
minCountActions: minDropdownActions.value,
|
|
66
|
+
})) {
|
|
67
|
+
ACTIONS_GROUPED.dropdown = ACTIONS_ALL.splice(actionIndex, ACTIONS_ALL.length);
|
|
68
|
+
if (currentIndexFirstDropdownAction.value === 0) {
|
|
69
|
+
ACTIONS_GROUPED.buttons.push({
|
|
70
|
+
type: "group",
|
|
71
|
+
children: [],
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (action.type !== "divider") {
|
|
79
|
+
action.actionNotDividerIndex = actionNotDividerIndex;
|
|
80
|
+
actionNotDividerIndex++;
|
|
81
|
+
if (isPreviousActionDivider) {
|
|
82
|
+
ACTIONS_GROUPED.buttons.push({
|
|
83
|
+
type: "group",
|
|
84
|
+
children: [action],
|
|
85
|
+
});
|
|
86
|
+
} else {
|
|
87
|
+
last(ACTIONS_GROUPED.buttons).children.push(action);
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
isPreviousActionDivider = true;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return ACTIONS_GROUPED;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const hasDropdownActions = computed(() => {
|
|
98
|
+
return actionsGrouped.value.dropdown.length > 0;
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
actionsAllFiltered,
|
|
103
|
+
actionsGrouped,
|
|
104
|
+
hasDropdownActions,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ref,
|
|
3
|
+
} from "vue";
|
|
4
|
+
|
|
5
|
+
export const isMobile = ref(undefined);
|
|
6
|
+
|
|
7
|
+
export function setIsMobile(isMobileLocal) {
|
|
8
|
+
isMobile.value = isMobileLocal;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function AMobileAPI() {
|
|
12
|
+
return {
|
|
13
|
+
isMobile,
|
|
14
|
+
setIsMobile,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ref,
|
|
3
|
+
} from "vue";
|
|
4
|
+
|
|
5
|
+
export const groupButtonDropdownPluginOptions = ref({
|
|
6
|
+
propsDefault: {
|
|
7
|
+
actionsClasses: ["a_btn a_btn_primary", "a_btn a_btn_secondary"],
|
|
8
|
+
dropdownAttributes: {},
|
|
9
|
+
hasDividerBeforeDropdown: true,
|
|
10
|
+
indexFirstDropdownAction: 1,
|
|
11
|
+
indexFirstDropdownActionMobile: 0,
|
|
12
|
+
minDropdownActions: 2,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
export default {
|
|
16
|
+
install: (app, {
|
|
17
|
+
propsDefault = {},
|
|
18
|
+
} = {}) => {
|
|
19
|
+
groupButtonDropdownPluginOptions.value.propsDefault = {
|
|
20
|
+
...groupButtonDropdownPluginOptions.value.propsDefault,
|
|
21
|
+
...propsDefault,
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isMobile,
|
|
3
|
+
setIsMobile,
|
|
4
|
+
} from "../compositionAPI/AMobileAPI";
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
install: (app, {
|
|
8
|
+
breakpoint,
|
|
9
|
+
} = {}) => {
|
|
10
|
+
setIsMobile(window.innerWidth <= breakpoint);
|
|
11
|
+
const resizeWindow = () => {
|
|
12
|
+
if (window.innerWidth > breakpoint) {
|
|
13
|
+
if (isMobile.value) {
|
|
14
|
+
setIsMobile(false);
|
|
15
|
+
}
|
|
16
|
+
} else {
|
|
17
|
+
if (!isMobile.value) {
|
|
18
|
+
setIsMobile(true);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
window.addEventListener("resize", resizeWindow);
|
|
24
|
+
},
|
|
25
|
+
};
|
package/src/styles/styles.scss
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
filter,
|
|
3
|
+
forEach,
|
|
4
|
+
last,
|
|
5
|
+
} from "lodash-es";
|
|
6
|
+
|
|
7
|
+
export function filterActionsHiddenAndDivider({ actions }) {
|
|
8
|
+
const ACTIONS_FILTERED = filter(actions, action => {
|
|
9
|
+
return !action.isHidden;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const ACTIONS_DIVIDER_FILTERED = [];
|
|
13
|
+
forEach(ACTIONS_FILTERED, action => {
|
|
14
|
+
if (action.type !== "divider" ||
|
|
15
|
+
(ACTIONS_DIVIDER_FILTERED.length > 0 &&
|
|
16
|
+
last(ACTIONS_DIVIDER_FILTERED).type !== "divider")) {
|
|
17
|
+
ACTIONS_DIVIDER_FILTERED.push(action);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const LAST_ACTION = last(ACTIONS_DIVIDER_FILTERED);
|
|
21
|
+
if (LAST_ACTION && LAST_ACTION.type === "divider") {
|
|
22
|
+
ACTIONS_DIVIDER_FILTERED.pop();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return ACTIONS_DIVIDER_FILTERED;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function filterActionsDivider({ actions }) {
|
|
29
|
+
const ACTIONS_DIVIDER_FILTERED = [];
|
|
30
|
+
forEach(actions, action => {
|
|
31
|
+
if (action.type !== "divider" ||
|
|
32
|
+
(ACTIONS_DIVIDER_FILTERED.length > 0 &&
|
|
33
|
+
last(ACTIONS_DIVIDER_FILTERED).type !== "divider")) {
|
|
34
|
+
ACTIONS_DIVIDER_FILTERED.push(action);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const LAST_ACTION = last(ACTIONS_DIVIDER_FILTERED);
|
|
38
|
+
if (LAST_ACTION && LAST_ACTION.type === "divider") {
|
|
39
|
+
ACTIONS_DIVIDER_FILTERED.pop();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return ACTIONS_DIVIDER_FILTERED;
|
|
43
|
+
}
|