@awes-io/ui 2.35.0 → 2.39.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 +49 -0
- package/assets/css/components/_index.css +1 -0
- package/assets/css/components/button-fixed.css +49 -0
- package/assets/css/components/button.css +1 -1
- package/assets/css/components/page-menu-buttons.css +11 -1
- package/assets/js/events.js +25 -0
- package/components/1_atoms/AwCheckbox.vue +5 -6
- package/components/1_atoms/AwFlow.vue +17 -2
- package/components/1_atoms/AwIcon/AwIcon.vue +21 -19
- package/components/2_molecules/AwButton.vue +1 -1
- package/components/2_molecules/AwSelectObject.vue +9 -1
- package/components/3_organisms/AwAddress.vue +49 -65
- package/components/3_organisms/AwBirthdayPicker.vue +5 -5
- package/components/3_organisms/AwDisplayDate.vue +1 -1
- package/components/4_pages/AwPage.vue +1 -1
- package/components/4_pages/AwPageMenuButtons.vue +48 -7
- package/components/4_pages/_AwButtonFixed.vue +45 -0
- package/components/5_layouts/AwLayoutCenter.vue +3 -12
- package/components/5_layouts/_AwLayoutLogo.vue +18 -0
- package/components/5_layouts/_AwLayoutMenu.vue +9 -13
- package/components/5_layouts/_AwMobileMenu.vue +18 -7
- package/components/_config.js +1 -1
- package/lang/de.js +1 -0
- package/lang/en.js +1 -0
- package/lang/ru.js +1 -0
- package/lang/uk.js +1 -0
- package/mixins/birthday.js +4 -17
- package/mixins/button.js +17 -0
- package/nuxt/templates/dayjs.plugin.js +1 -1
- package/nuxt/templates/store.plugin.js +6 -0
- package/package.json +2 -2
- package/store/awesIo.js +53 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,55 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [2.39.0](https://github.com/awes-io/client/compare/@awes-io/ui@2.38.0...@awes-io/ui@2.39.0) (2022-01-17)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* aw-address uses select internally ([d8a71f0](https://github.com/awes-io/client/commit/d8a71f0b42f22853ca69d1b61cfdb3d9d91aed40))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [2.38.0](https://github.com/awes-io/client/compare/@awes-io/ui@2.37.0...@awes-io/ui@2.38.0) (2021-12-30)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* default button color replaced to accent ([980a96d](https://github.com/awes-io/client/commit/980a96d5a23c5025a618a53ddf630934440eda91))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# [2.37.0](https://github.com/awes-io/client/compare/@awes-io/ui@2.36.0...@awes-io/ui@2.37.0) (2021-12-28)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* **aw-birthday-picker:** global dayjs with leap year plugin used instead of custom ([047890f](https://github.com/awes-io/client/commit/047890ff1eb26923f455a64dfd12b5a6c5c972c8))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
* scroll buttons collabsing added ([b773080](https://github.com/awes-io/client/commit/b77308027776ca4c2aba94753ec0826819d090c3))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# [2.36.0](https://github.com/awes-io/client/compare/@awes-io/ui@2.35.0...@awes-io/ui@2.36.0) (2021-12-10)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Features
|
|
48
|
+
|
|
49
|
+
* logo switching added ([e5e7328](https://github.com/awes-io/client/commit/e5e732812e9acb5c3a6c810d9a7346affa422988))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
6
55
|
# [2.35.0](https://github.com/awes-io/client/compare/@awes-io/ui@2.34.2...@awes-io/ui@2.35.0) (2021-12-04)
|
|
7
56
|
|
|
8
57
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
.aw-button-fixed {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
|
|
5
|
+
padding: 0.75rem 1rem;
|
|
6
|
+
min-width: 3.5rem;
|
|
7
|
+
min-height: 3.5rem;
|
|
8
|
+
/* border-radius: 1rem; */
|
|
9
|
+
|
|
10
|
+
font-size: 0.75rem;
|
|
11
|
+
font-weight: bold;
|
|
12
|
+
letter-spacing: 0.09375rem;
|
|
13
|
+
text-transform: uppercase;
|
|
14
|
+
|
|
15
|
+
background-color: rgba(var(--btn-bg), 1);
|
|
16
|
+
color: rgba(var(--btn-fg), 1);
|
|
17
|
+
|
|
18
|
+
box-shadow: 0px 0.25rem 0.5rem rgba(var(--btn-bg), 0.2);
|
|
19
|
+
|
|
20
|
+
&__text {
|
|
21
|
+
flex-shrink: 1;
|
|
22
|
+
max-width: 1px;
|
|
23
|
+
margin-right: -1px;
|
|
24
|
+
|
|
25
|
+
opacity: 0.1;
|
|
26
|
+
transition-property: max-width, margin, opacity;
|
|
27
|
+
transition-duration: 120ms;
|
|
28
|
+
|
|
29
|
+
&--expanded {
|
|
30
|
+
max-width: 16rem;
|
|
31
|
+
margin-right: 0.75em;
|
|
32
|
+
opacity: 1;
|
|
33
|
+
transition-timing-function: ease-out;
|
|
34
|
+
transition-duration: 240ms;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:hover {
|
|
39
|
+
background-image: linear-gradient(rgba(var(--btn-fg), 0.15), rgba(var(--btn-fg), 0.15));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&:active {
|
|
43
|
+
transform: translateY(1px);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&:focus-visible {
|
|
47
|
+
outline: theme('focusOutline');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
/**
|
|
201
201
|
* Colors
|
|
202
202
|
*/
|
|
203
|
-
@each $color in (info, success, warning, error, surface, overlay) {
|
|
203
|
+
@each $color in (accent, info, success, warning, error, surface, overlay) {
|
|
204
204
|
.aw-button {
|
|
205
205
|
/* Circle, Solid */
|
|
206
206
|
&.theme-circle.color-$(color),
|
|
@@ -6,9 +6,19 @@
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
&__fixed-btns {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
align-items: flex-end;
|
|
12
|
+
|
|
13
|
+
max-width: calc(100vw - 2 * theme('spacing.4', 1rem));
|
|
14
|
+
|
|
9
15
|
position: fixed;
|
|
10
16
|
right: theme('spacing.4', 1rem);
|
|
11
|
-
bottom: calc(env(safe-area-inset-bottom, 0) + var(--page-buttons-bottom,
|
|
17
|
+
bottom: calc(env(safe-area-inset-bottom, 0) + var(--page-buttons-bottom, 0));
|
|
12
18
|
z-index: 2;
|
|
19
|
+
|
|
20
|
+
& > * {
|
|
21
|
+
margin-bottom: 1rem;
|
|
22
|
+
}
|
|
13
23
|
}
|
|
14
24
|
}
|
package/assets/js/events.js
CHANGED
|
@@ -60,3 +60,28 @@ export const getEventTargetAttribute = ($event, attrName, bound = null) => {
|
|
|
60
60
|
|
|
61
61
|
return null
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Detect if client supports passive event listeners
|
|
66
|
+
* @return {Boolean} true if supports
|
|
67
|
+
*/
|
|
68
|
+
export const supportsPassive = () => {
|
|
69
|
+
let supports = false
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
window &&
|
|
73
|
+
typeof window.addEventListener === 'function' &&
|
|
74
|
+
typeof Object.defineProperty === 'function'
|
|
75
|
+
) {
|
|
76
|
+
const options = Object.defineProperty({}, 'passive', {
|
|
77
|
+
// eslint-disable-next-line getter-return
|
|
78
|
+
get() {
|
|
79
|
+
supports = true
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
window.addEventListener('_', null, options)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return supports
|
|
87
|
+
}
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
</template>
|
|
32
32
|
|
|
33
33
|
<script>
|
|
34
|
-
import { equals } from 'rambdax'
|
|
35
34
|
import FieldMixin from '@AwMixins/field'
|
|
36
35
|
import ErrorMixin from '@AwMixins/error'
|
|
37
36
|
|
|
@@ -89,16 +88,16 @@ export default {
|
|
|
89
88
|
_onChange($event) {
|
|
90
89
|
let value = this._createValue($event.target.checked)
|
|
91
90
|
|
|
92
|
-
if (equals(value, this.checked)) {
|
|
93
|
-
$event.target.checked = this.isChecked
|
|
94
|
-
return
|
|
95
|
-
}
|
|
96
|
-
|
|
97
91
|
if (this.hasError) {
|
|
98
92
|
this.setError('')
|
|
99
93
|
}
|
|
100
94
|
|
|
101
95
|
this.$emit('change', value)
|
|
96
|
+
|
|
97
|
+
// sync checkbox state
|
|
98
|
+
this.$nextTick(() => {
|
|
99
|
+
$event.target.checked = this.isChecked
|
|
100
|
+
})
|
|
102
101
|
},
|
|
103
102
|
|
|
104
103
|
_createValue(isChecked) {
|
|
@@ -20,11 +20,21 @@ export default {
|
|
|
20
20
|
default: true
|
|
21
21
|
},
|
|
22
22
|
|
|
23
|
+
justify: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: ''
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
align: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: ''
|
|
31
|
+
},
|
|
32
|
+
|
|
23
33
|
vertical: Boolean
|
|
24
34
|
},
|
|
25
35
|
|
|
26
36
|
render(h) {
|
|
27
|
-
const { tag, gap, wrapChildren, vertical } = this.$props
|
|
37
|
+
const { tag, gap, wrapChildren, vertical, align, justify } = this.$props
|
|
28
38
|
const children = this.$scopedSlots.default
|
|
29
39
|
? this.$scopedSlots.default()
|
|
30
40
|
: []
|
|
@@ -44,7 +54,12 @@ export default {
|
|
|
44
54
|
staticClass: 'aw-flow__wrap',
|
|
45
55
|
class: {
|
|
46
56
|
'aw-flow__wrap--children': !wrapChildren,
|
|
47
|
-
'aw-flow__wrap--vertical': vertical
|
|
57
|
+
'aw-flow__wrap--vertical': vertical,
|
|
58
|
+
'justify-center': justify === 'center',
|
|
59
|
+
'justify-end': justify === 'end',
|
|
60
|
+
'items-start': align === 'start',
|
|
61
|
+
'items-center': align === 'center',
|
|
62
|
+
'items-end': align === 'end'
|
|
48
63
|
}
|
|
49
64
|
},
|
|
50
65
|
children.reduce((acc, vNode) => {
|
|
@@ -26,25 +26,27 @@ export default {
|
|
|
26
26
|
render(h, { props: { name, size, viewBox }, data }) {
|
|
27
27
|
const attrs = data.attrs || {}
|
|
28
28
|
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
29
|
+
return name
|
|
30
|
+
? h('SvgIcon', {
|
|
31
|
+
props: { name, viewBox },
|
|
32
|
+
staticClass: 'aw-icon',
|
|
33
|
+
class: [
|
|
34
|
+
data.class,
|
|
35
|
+
data.staticClass,
|
|
36
|
+
{
|
|
37
|
+
'aw-icon--size-text':
|
|
38
|
+
!size && isNil(attrs.width) && isNil(attrs.height)
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
style: [data.style, data.staticStyle],
|
|
42
|
+
attrs: {
|
|
43
|
+
'aria-hidden': true,
|
|
44
|
+
width: size || null,
|
|
45
|
+
height: size || null,
|
|
46
|
+
...attrs
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
: null
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
</script>
|
|
@@ -178,6 +178,14 @@
|
|
|
178
178
|
</div>
|
|
179
179
|
|
|
180
180
|
<div v-if="_isAjax && _hasNextPage" ref="dropdownEnd"></div>
|
|
181
|
+
|
|
182
|
+
<slot
|
|
183
|
+
name="dropdown-after"
|
|
184
|
+
v-bind="{
|
|
185
|
+
optionsList,
|
|
186
|
+
isLoading
|
|
187
|
+
}"
|
|
188
|
+
></slot>
|
|
181
189
|
</slot>
|
|
182
190
|
</div>
|
|
183
191
|
</div>
|
|
@@ -438,7 +446,7 @@ export default {
|
|
|
438
446
|
_showNotFound() {
|
|
439
447
|
return this._isAjax
|
|
440
448
|
? !this.selectOptions.length && !this.isLoading
|
|
441
|
-
: !this.optionsList.length
|
|
449
|
+
: this._searchPhraseLength && !this.optionsList.length
|
|
442
450
|
},
|
|
443
451
|
|
|
444
452
|
isMobile() {
|
|
@@ -1,34 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
>
|
|
11
|
-
<AwDropdownButton
|
|
12
|
-
icon="location"
|
|
13
|
-
v-for="place in suggestions"
|
|
14
|
-
:key="place.place_id"
|
|
15
|
-
@click="select(place)"
|
|
16
|
-
>
|
|
17
|
-
{{ place.description }}
|
|
18
|
-
</AwDropdownButton>
|
|
19
|
-
|
|
2
|
+
<AwSelectObject
|
|
3
|
+
ref="select"
|
|
4
|
+
v-model="place"
|
|
5
|
+
:options="suggestions"
|
|
6
|
+
track-by="place_id"
|
|
7
|
+
option-label="description"
|
|
8
|
+
@search="search"
|
|
9
|
+
>
|
|
10
|
+
<template #dropdown-after>
|
|
20
11
|
<!-- branding -->
|
|
21
12
|
<img
|
|
13
|
+
v-if="suggestions.length"
|
|
22
14
|
class="block my-2 mx-auto"
|
|
23
15
|
aria-hidden="true"
|
|
24
16
|
src="https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3.png"
|
|
25
17
|
alt=""
|
|
26
18
|
/>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
</div>
|
|
19
|
+
<!-- places service needs a container to init -->
|
|
20
|
+
<div ref="place"></div>
|
|
21
|
+
</template>
|
|
22
|
+
</AwSelectObject>
|
|
32
23
|
</template>
|
|
33
24
|
|
|
34
25
|
<script>
|
|
@@ -56,30 +47,34 @@ export default {
|
|
|
56
47
|
autocomplete: null,
|
|
57
48
|
placesService: null,
|
|
58
49
|
sessionToken: null,
|
|
50
|
+
isLoading: false,
|
|
59
51
|
suggestions: [],
|
|
60
|
-
placeDescription: '',
|
|
61
52
|
place: null
|
|
62
53
|
}
|
|
63
54
|
},
|
|
64
55
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
set(text) {
|
|
72
|
-
this.placeDescription = text
|
|
73
|
-
|
|
74
|
-
if (!this.autocomplete) return
|
|
56
|
+
watch: {
|
|
57
|
+
place(place) {
|
|
58
|
+
if (!place || !place.place_id) {
|
|
59
|
+
this.place = null
|
|
60
|
+
return
|
|
61
|
+
}
|
|
75
62
|
|
|
76
|
-
|
|
63
|
+
this.placesService.getDetails(
|
|
64
|
+
{
|
|
65
|
+
placeId: place.place_id,
|
|
66
|
+
sessionToken: this.sessionToken
|
|
67
|
+
},
|
|
68
|
+
(details) => {
|
|
69
|
+
if (this.$refs.select) {
|
|
70
|
+
this.$refs.select.searchPhrase = ''
|
|
71
|
+
}
|
|
77
72
|
this._resetSearch()
|
|
78
|
-
|
|
73
|
+
this._formatAddressResponse(details).then((result) => {
|
|
74
|
+
this.$emit('input', result)
|
|
75
|
+
})
|
|
79
76
|
}
|
|
80
|
-
|
|
81
|
-
this._query(text)
|
|
82
|
-
}
|
|
77
|
+
)
|
|
83
78
|
}
|
|
84
79
|
},
|
|
85
80
|
|
|
@@ -107,13 +102,22 @@ export default {
|
|
|
107
102
|
this.placesService = new window.google.maps.places.PlacesService(
|
|
108
103
|
this.$refs.place
|
|
109
104
|
)
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
search(text) {
|
|
108
|
+
if (!this.autocomplete) return
|
|
110
109
|
|
|
111
|
-
if (
|
|
112
|
-
this.
|
|
110
|
+
if (!text) {
|
|
111
|
+
this._resetSearch()
|
|
112
|
+
return
|
|
113
113
|
}
|
|
114
|
+
|
|
115
|
+
this._query(text)
|
|
114
116
|
},
|
|
115
117
|
|
|
116
118
|
_query(input) {
|
|
119
|
+
this.$refs.select.isLoading = true
|
|
120
|
+
|
|
117
121
|
if (!this.sessionToken) {
|
|
118
122
|
this.sessionToken = new window.google.maps.places.AutocompleteSessionToken()
|
|
119
123
|
}
|
|
@@ -129,10 +133,14 @@ export default {
|
|
|
129
133
|
},
|
|
130
134
|
|
|
131
135
|
_setSuggestions(data) {
|
|
136
|
+
this.$refs.select.isLoading = false
|
|
132
137
|
this.suggestions = data || []
|
|
133
138
|
},
|
|
134
139
|
|
|
135
140
|
_resetSearch() {
|
|
141
|
+
if (this.$refs.select) {
|
|
142
|
+
this.$refs.select.isLoading = false
|
|
143
|
+
}
|
|
136
144
|
this.suggestions = []
|
|
137
145
|
this.sessionToken = null
|
|
138
146
|
},
|
|
@@ -222,32 +230,8 @@ export default {
|
|
|
222
230
|
})
|
|
223
231
|
},
|
|
224
232
|
|
|
225
|
-
select(place) {
|
|
226
|
-
if (!place || !place.place_id) {
|
|
227
|
-
this.place = null
|
|
228
|
-
this.placeDescription = ''
|
|
229
|
-
return
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
this.placesService.getDetails(
|
|
233
|
-
{
|
|
234
|
-
placeId: place.place_id,
|
|
235
|
-
sessionToken: this.sessionToken
|
|
236
|
-
},
|
|
237
|
-
(details) => {
|
|
238
|
-
this.place = details
|
|
239
|
-
this.placeDescription = details.formatted_address
|
|
240
|
-
this._resetSearch()
|
|
241
|
-
this._formatAddressResponse(details).then((result) => {
|
|
242
|
-
this.$emit('input', result)
|
|
243
|
-
})
|
|
244
|
-
}
|
|
245
|
-
)
|
|
246
|
-
},
|
|
247
|
-
|
|
248
233
|
reset() {
|
|
249
234
|
this.suggestions = []
|
|
250
|
-
this.placeDescription = ''
|
|
251
235
|
this.place = null
|
|
252
236
|
}
|
|
253
237
|
}
|
|
@@ -123,7 +123,7 @@ export default {
|
|
|
123
123
|
},
|
|
124
124
|
|
|
125
125
|
monthsList() {
|
|
126
|
-
const date = this
|
|
126
|
+
const date = this.$dayjs()
|
|
127
127
|
return [...Array(12).keys()].map((el) => ({
|
|
128
128
|
value: el,
|
|
129
129
|
text: date.month(el).format('MMMM')
|
|
@@ -131,7 +131,7 @@ export default {
|
|
|
131
131
|
},
|
|
132
132
|
|
|
133
133
|
daysList() {
|
|
134
|
-
const date = this
|
|
134
|
+
const date = this.$dayjs().year(this.year || 2000)
|
|
135
135
|
|
|
136
136
|
const maxDays = date.month(this.month || 0).daysInMonth()
|
|
137
137
|
|
|
@@ -141,10 +141,10 @@ export default {
|
|
|
141
141
|
},
|
|
142
142
|
|
|
143
143
|
yearsList() {
|
|
144
|
-
const current = this
|
|
144
|
+
const current = this.$dayjs().year()
|
|
145
145
|
return [...Array(101).keys()].map((el) => ({
|
|
146
146
|
year: current - el,
|
|
147
|
-
isLeapYear: this
|
|
147
|
+
isLeapYear: this.$dayjs()
|
|
148
148
|
.year(current - el)
|
|
149
149
|
.isLeapYear()
|
|
150
150
|
}))
|
|
@@ -175,7 +175,7 @@ export default {
|
|
|
175
175
|
|
|
176
176
|
emit() {
|
|
177
177
|
if (!isNil(this.month) && this.day) {
|
|
178
|
-
let d = this
|
|
178
|
+
let d = this.$dayjs()
|
|
179
179
|
.year(this.year || 2000)
|
|
180
180
|
.month(this.month)
|
|
181
181
|
.date(this.day)
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<slot name="heading" v-bind="{ titleTag, title, breadcrumb }">
|
|
10
10
|
<AwPageHeadline
|
|
11
11
|
:style="{
|
|
12
|
-
'--page-buttons-bottom': _hideBottomBar ? null : '
|
|
12
|
+
'--page-buttons-bottom': _hideBottomBar ? null : '4rem'
|
|
13
13
|
}"
|
|
14
14
|
:title="_title"
|
|
15
15
|
:breadcrumb="breadcrumb"
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
<AwFlow
|
|
5
5
|
v-if="isExpanded && splitButtons.buttons.length"
|
|
6
6
|
tag="div"
|
|
7
|
+
justify="end"
|
|
7
8
|
class="aw-page-menu-buttons__expanded-btns"
|
|
8
9
|
>
|
|
9
10
|
<AwButton
|
|
@@ -34,28 +35,27 @@
|
|
|
34
35
|
</AwContextMenu>
|
|
35
36
|
|
|
36
37
|
<!-- fixed button -->
|
|
37
|
-
<
|
|
38
|
+
<div
|
|
38
39
|
v-if="!isExpanded && splitButtons.fixed"
|
|
39
40
|
class="aw-page-menu-buttons__fixed-btns"
|
|
40
|
-
tag="div"
|
|
41
|
-
vertical
|
|
42
41
|
>
|
|
43
|
-
<
|
|
42
|
+
<AwButtonFixed
|
|
44
43
|
v-for="({ listeners, tooltip, ...attrs },
|
|
45
44
|
i) in splitButtons.fixed"
|
|
46
45
|
:key="i"
|
|
47
|
-
|
|
46
|
+
:expanded="isInTopPosition"
|
|
48
47
|
v-tooltip="tooltip"
|
|
49
48
|
v-bind="attrs"
|
|
50
49
|
v-on="listeners"
|
|
51
50
|
/>
|
|
52
|
-
</
|
|
51
|
+
</div>
|
|
53
52
|
</div>
|
|
54
53
|
</template>
|
|
55
54
|
|
|
56
55
|
<script>
|
|
57
56
|
import { isType, defaultTo } from 'rambdax'
|
|
58
57
|
import { downloadFile } from '@AwUtils/download'
|
|
58
|
+
import { supportsPassive } from '@AwUtils/events'
|
|
59
59
|
|
|
60
60
|
const toIconButton = (props) => ({
|
|
61
61
|
...props,
|
|
@@ -66,6 +66,10 @@ const toIconButton = (props) => ({
|
|
|
66
66
|
export default {
|
|
67
67
|
name: 'AwPageMenuButtons',
|
|
68
68
|
|
|
69
|
+
components: {
|
|
70
|
+
AwButtonFixed: () => import('@AwPages/_AwButtonFixed.vue')
|
|
71
|
+
},
|
|
72
|
+
|
|
69
73
|
props: {
|
|
70
74
|
items: {
|
|
71
75
|
type: Array,
|
|
@@ -75,12 +79,20 @@ export default {
|
|
|
75
79
|
breakpoint: {
|
|
76
80
|
type: String,
|
|
77
81
|
default: 'lg'
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
/* max window scroll when fixed buttons expanded */
|
|
85
|
+
/* pass -1 to collapse button eventually */
|
|
86
|
+
expandOffset: {
|
|
87
|
+
type: Number,
|
|
88
|
+
default: 150 // px
|
|
78
89
|
}
|
|
79
90
|
},
|
|
80
91
|
|
|
81
92
|
data() {
|
|
82
93
|
return {
|
|
83
|
-
isDownloading: {}
|
|
94
|
+
isDownloading: {},
|
|
95
|
+
isInTopPosition: true
|
|
84
96
|
}
|
|
85
97
|
},
|
|
86
98
|
|
|
@@ -121,6 +133,10 @@ export default {
|
|
|
121
133
|
}
|
|
122
134
|
},
|
|
123
135
|
|
|
136
|
+
mounted() {
|
|
137
|
+
this._initScrollListener()
|
|
138
|
+
},
|
|
139
|
+
|
|
124
140
|
methods: {
|
|
125
141
|
_getVisiblity(show) {
|
|
126
142
|
return isType('Function', show) ? show(this) : defaultTo(true, show)
|
|
@@ -145,6 +161,31 @@ export default {
|
|
|
145
161
|
} finally {
|
|
146
162
|
this.$delete(this.isDownloading, url)
|
|
147
163
|
}
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
_initScrollListener() {
|
|
167
|
+
if (this.expandOffset < 0) {
|
|
168
|
+
this.isInTopPosition = false
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const opts = supportsPassive()
|
|
173
|
+
? {
|
|
174
|
+
passive: true
|
|
175
|
+
}
|
|
176
|
+
: false
|
|
177
|
+
|
|
178
|
+
const detectTopPosition = () => {
|
|
179
|
+
this.isInTopPosition = window.pageYOffset < this.expandOffset
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
detectTopPosition()
|
|
183
|
+
|
|
184
|
+
window.addEventListener('scroll', detectTopPosition, opts)
|
|
185
|
+
|
|
186
|
+
this.$once('hook:beforeDestroy', () => {
|
|
187
|
+
window.removeEventListener('scroll', detectTopPosition, opts)
|
|
188
|
+
})
|
|
148
189
|
}
|
|
149
190
|
},
|
|
150
191
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Component
|
|
3
|
+
:is="_linkComponent"
|
|
4
|
+
v-bind="_linkAttrs"
|
|
5
|
+
:style="buttonStyle"
|
|
6
|
+
class="aw-button-fixed"
|
|
7
|
+
v-on="$listeners"
|
|
8
|
+
>
|
|
9
|
+
<span
|
|
10
|
+
v-if="text"
|
|
11
|
+
class="aw-button-fixed__text truncate"
|
|
12
|
+
:class="{ 'aw-button-fixed__text--expanded': expanded }"
|
|
13
|
+
>
|
|
14
|
+
<slot>{{ text }}</slot>
|
|
15
|
+
</span>
|
|
16
|
+
<slot name="icon">
|
|
17
|
+
<AwIcon :name="icon" size="24" class="flex-shrink-0" />
|
|
18
|
+
</slot>
|
|
19
|
+
</Component>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
import linkMixin from '@AwMixins/link'
|
|
24
|
+
import buttonMixin from '@AwMixins/button'
|
|
25
|
+
|
|
26
|
+
export default {
|
|
27
|
+
name: 'AwButtonFixed',
|
|
28
|
+
|
|
29
|
+
mixins: [linkMixin, buttonMixin],
|
|
30
|
+
|
|
31
|
+
props: {
|
|
32
|
+
icon: {
|
|
33
|
+
type: String,
|
|
34
|
+
required: true
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
text: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: ''
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
expanded: Boolean
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
@@ -27,23 +27,14 @@
|
|
|
27
27
|
</template>
|
|
28
28
|
|
|
29
29
|
<script>
|
|
30
|
+
import { mapGetters } from 'vuex'
|
|
30
31
|
import { pathOr } from 'rambdax'
|
|
31
32
|
|
|
32
33
|
export default {
|
|
33
34
|
name: 'AwLayoutCenter',
|
|
34
35
|
|
|
35
36
|
computed: {
|
|
36
|
-
|
|
37
|
-
return this.$store.getters['awesIo/isDarkTheme']
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
logo() {
|
|
41
|
-
return pathOr(
|
|
42
|
-
null,
|
|
43
|
-
['$awes', '_config', this.isDark ? 'dark' : 'default', 'logo'],
|
|
44
|
-
this
|
|
45
|
-
)
|
|
46
|
-
},
|
|
37
|
+
...mapGetters('awesIo', ['isDarkTheme', 'logo']),
|
|
47
38
|
|
|
48
39
|
background() {
|
|
49
40
|
const { src, ...background } = pathOr(
|
|
@@ -51,7 +42,7 @@ export default {
|
|
|
51
42
|
[
|
|
52
43
|
'$awes',
|
|
53
44
|
'_config',
|
|
54
|
-
this.
|
|
45
|
+
this.isDarkTheme ? 'dark' : 'default',
|
|
55
46
|
'background'
|
|
56
47
|
],
|
|
57
48
|
this
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<template functional>
|
|
2
|
+
<NLink
|
|
3
|
+
to="/"
|
|
4
|
+
class="aw-layout-logo"
|
|
5
|
+
:class="[data.class, data.staticClass]"
|
|
6
|
+
>
|
|
7
|
+
<img v-if="props.logo" v-bind="props.logo" />
|
|
8
|
+
<span class="sr-only">
|
|
9
|
+
{{ parent.$t('AwLayoutDefault.homepage') }}
|
|
10
|
+
</span>
|
|
11
|
+
</NLink>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
export default {
|
|
16
|
+
name: 'AwLayoutLogo'
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
'aw-layout-menu--no-submenu': hideAside || !hasSubmenu
|
|
6
6
|
}"
|
|
7
7
|
>
|
|
8
|
-
<slot name="logo"
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
<slot name="logo">
|
|
9
|
+
<Component
|
|
10
|
+
:is="logoComponent.is"
|
|
11
|
+
v-bind="logoComponent.props"
|
|
12
|
+
class="aw-layout-menu__logo"
|
|
13
|
+
/>
|
|
12
14
|
</slot>
|
|
13
15
|
|
|
14
16
|
<div class="aw-layout-menu__menu">
|
|
@@ -62,6 +64,7 @@
|
|
|
62
64
|
import { mapGetters } from 'vuex'
|
|
63
65
|
import { pathOr, viewOr, lensProp, omit } from 'rambdax'
|
|
64
66
|
import AwMenuItemIcon from '@AwLayouts/_AwMenuItemIcon.vue'
|
|
67
|
+
import AwLayoutLogo from '@AwLayouts/_AwLayoutLogo.vue'
|
|
65
68
|
import AwUserMenu from '@AwLayouts/_AwUserMenu.vue'
|
|
66
69
|
import AwNav from '@AwLayouts/_AwNav.vue'
|
|
67
70
|
|
|
@@ -70,6 +73,7 @@ export default {
|
|
|
70
73
|
|
|
71
74
|
components: {
|
|
72
75
|
AwMenuItemIcon,
|
|
76
|
+
AwLayoutLogo,
|
|
73
77
|
AwUserMenu,
|
|
74
78
|
AwNav
|
|
75
79
|
},
|
|
@@ -85,7 +89,7 @@ export default {
|
|
|
85
89
|
},
|
|
86
90
|
|
|
87
91
|
computed: {
|
|
88
|
-
...mapGetters('awesIo', ['user', '
|
|
92
|
+
...mapGetters('awesIo', ['user', 'logoComponent']),
|
|
89
93
|
|
|
90
94
|
mainMenu() {
|
|
91
95
|
return viewOr([], lensProp('mainMenu'), this.layoutProvider)
|
|
@@ -115,14 +119,6 @@ export default {
|
|
|
115
119
|
this.activeMenu
|
|
116
120
|
)
|
|
117
121
|
: ''
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
logo() {
|
|
121
|
-
return pathOr(
|
|
122
|
-
null,
|
|
123
|
-
['_config', this.isDarkTheme ? 'dark' : 'default', 'logo'],
|
|
124
|
-
this.$awes
|
|
125
|
-
)
|
|
126
122
|
}
|
|
127
123
|
},
|
|
128
124
|
|
|
@@ -84,14 +84,21 @@
|
|
|
84
84
|
/>
|
|
85
85
|
</template>
|
|
86
86
|
|
|
87
|
+
<slot name="after-mobile-menu">
|
|
88
|
+
<Component
|
|
89
|
+
v-if="afterMobileMenuComponent"
|
|
90
|
+
:is="afterMobileMenuComponent.is"
|
|
91
|
+
v-bind="afterMobileMenuComponent.props"
|
|
92
|
+
/>
|
|
93
|
+
</slot>
|
|
94
|
+
|
|
87
95
|
<!-- logo -->
|
|
88
96
|
<slot name="logo" v-bind="logo">
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
</NLink>
|
|
97
|
+
<Component
|
|
98
|
+
:is="logoComponent.is"
|
|
99
|
+
v-bind="logoComponent.props"
|
|
100
|
+
class="aw-mobile-menu__logo"
|
|
101
|
+
/>
|
|
95
102
|
<span class="aw-mobile-menu__version">
|
|
96
103
|
{{ $t('AwMobileMenu.version', { version: $config.VERSION }) }}
|
|
97
104
|
</span>
|
|
@@ -128,7 +135,11 @@ export default {
|
|
|
128
135
|
},
|
|
129
136
|
|
|
130
137
|
computed: {
|
|
131
|
-
...mapGetters('awesIo', [
|
|
138
|
+
...mapGetters('awesIo', [
|
|
139
|
+
'user',
|
|
140
|
+
'logoComponent',
|
|
141
|
+
'afterMobileMenuComponent'
|
|
142
|
+
]),
|
|
132
143
|
|
|
133
144
|
mainMenu() {
|
|
134
145
|
return viewOr([], lensProp('mainMenu'), this.layoutProvider).filter(
|
package/components/_config.js
CHANGED
package/lang/de.js
CHANGED
package/lang/en.js
CHANGED
package/lang/ru.js
CHANGED
package/lang/uk.js
CHANGED
package/mixins/birthday.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import dayjs from 'dayjs'
|
|
2
|
-
import customParseFormat from 'dayjs/plugin/customParseFormat'
|
|
3
|
-
import localizedFormat from 'dayjs/plugin/localizedFormat'
|
|
4
|
-
|
|
5
|
-
dayjs.extend(customParseFormat)
|
|
6
|
-
dayjs.extend(localizedFormat)
|
|
7
|
-
|
|
8
1
|
export default {
|
|
9
2
|
props: {
|
|
10
3
|
/**
|
|
@@ -26,20 +19,14 @@ export default {
|
|
|
26
19
|
}
|
|
27
20
|
},
|
|
28
21
|
|
|
29
|
-
computed: {
|
|
30
|
-
dayjs() {
|
|
31
|
-
return this.$dayjs || dayjs
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
|
|
35
22
|
methods: {
|
|
36
23
|
toDayjs(input) {
|
|
37
24
|
if (typeof input !== 'string') {
|
|
38
|
-
return this
|
|
25
|
+
return this.$dayjs(input)
|
|
39
26
|
}
|
|
40
27
|
|
|
41
28
|
if (this.fullParseFormat) {
|
|
42
|
-
const dLong = this
|
|
29
|
+
const dLong = this.$dayjs(input, this.fullParseFormat)
|
|
43
30
|
if (dLong.isValid()) {
|
|
44
31
|
return dLong
|
|
45
32
|
}
|
|
@@ -48,13 +35,13 @@ export default {
|
|
|
48
35
|
if (this.shortParseFormat) {
|
|
49
36
|
const _formatWithYear = `${this.shortParseFormat}.YYYY`
|
|
50
37
|
const _inputWithYear = `${input}.2000` // 2000 is leap year
|
|
51
|
-
const dShort = this
|
|
38
|
+
const dShort = this.$dayjs(_inputWithYear, _formatWithYear)
|
|
52
39
|
if (dShort.isValid()) {
|
|
53
40
|
return dShort
|
|
54
41
|
}
|
|
55
42
|
}
|
|
56
43
|
|
|
57
|
-
return this
|
|
44
|
+
return this.$dayjs(input)
|
|
58
45
|
},
|
|
59
46
|
|
|
60
47
|
parseDate(date) {
|
package/mixins/button.js
ADDED
|
@@ -2,7 +2,7 @@ import Vue from 'vue'
|
|
|
2
2
|
import dayjs from 'dayjs'
|
|
3
3
|
|
|
4
4
|
/* eslint-disable */
|
|
5
|
-
<% ['dayjs/plugin/relativeTime', 'dayjs/plugin/customParseFormat', 'dayjs/plugin/localizedFormat'].concat(Array.isArray(options.dayjs.plugins) ? options.dayjs.plugins : []).filter((val, i, arr) => arr.indexOf(val) === i).forEach((plugin) => {
|
|
5
|
+
<% ['dayjs/plugin/relativeTime', 'dayjs/plugin/customParseFormat', 'dayjs/plugin/localizedFormat', 'dayjs/plugin/isLeapYear'].concat(Array.isArray(options.dayjs.plugins) ? options.dayjs.plugins : []).filter((val, i, arr) => arr.indexOf(val) === i).forEach((plugin) => {
|
|
6
6
|
const src = plugin.src || plugin
|
|
7
7
|
const name = plugin.name || src.replace('dayjs/plugin/', '')
|
|
8
8
|
const options = plugin.options || {}
|
|
@@ -6,6 +6,12 @@ export default ({ store, app }) => {
|
|
|
6
6
|
*/
|
|
7
7
|
if (!store.hasModule('awesIo')) {
|
|
8
8
|
store.registerModule('awesIo', storeModule)
|
|
9
|
+
|
|
10
|
+
// Set default logo
|
|
11
|
+
store.commit('awesIo/SET_LOGO', {
|
|
12
|
+
default: JSON.parse('<%= JSON.stringify(options.default.logo) %>'),
|
|
13
|
+
dark: JSON.parse('<%= JSON.stringify(options.dark.logo) %>')
|
|
14
|
+
})
|
|
9
15
|
}
|
|
10
16
|
|
|
11
17
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awes-io/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.39.0",
|
|
4
4
|
"description": "User Interface (UI) components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui",
|
|
@@ -124,5 +124,5 @@
|
|
|
124
124
|
"vue-template-compiler": "^2.6.10",
|
|
125
125
|
"webfonts-generator": "^0.4.0"
|
|
126
126
|
},
|
|
127
|
-
"gitHead": "
|
|
127
|
+
"gitHead": "357c3e4b953260cceb0e1514598dc7246aaff63d"
|
|
128
128
|
}
|
package/store/awesIo.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Vue from 'vue'
|
|
2
|
-
import { pathOr, pick, isType } from 'rambdax'
|
|
2
|
+
import { pathOr, pick, isType, mergeDeepRight } from 'rambdax'
|
|
3
3
|
|
|
4
4
|
const castArray = (val) => (Array.isArray(val) ? val : [])
|
|
5
5
|
|
|
@@ -20,12 +20,18 @@ export const state = () => ({
|
|
|
20
20
|
|
|
21
21
|
profileUrl: null,
|
|
22
22
|
|
|
23
|
+
logo: {
|
|
24
|
+
default: { src: '' },
|
|
25
|
+
dark: { src: '' }
|
|
26
|
+
},
|
|
27
|
+
|
|
23
28
|
menus: {
|
|
24
29
|
main: [],
|
|
25
30
|
secondary: [],
|
|
26
31
|
user: []
|
|
27
32
|
},
|
|
28
33
|
mobileMenuOpened: false,
|
|
34
|
+
afterMobileMenu: null,
|
|
29
35
|
|
|
30
36
|
headerNotification: null,
|
|
31
37
|
|
|
@@ -83,7 +89,26 @@ export const getters = {
|
|
|
83
89
|
}
|
|
84
90
|
},
|
|
85
91
|
|
|
86
|
-
isDarkTheme: pathOr(false, 'isDarkTheme')
|
|
92
|
+
isDarkTheme: pathOr(false, 'isDarkTheme'),
|
|
93
|
+
|
|
94
|
+
logo(state, getters) {
|
|
95
|
+
return getters.isDarkTheme ? state.logo.dark : state.logo.default
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
logoComponent(state, getters) {
|
|
99
|
+
const logoComponent = pathOr(null, 'logo.component', state)
|
|
100
|
+
|
|
101
|
+
return logoComponent && logoComponent.is
|
|
102
|
+
? logoComponent
|
|
103
|
+
: {
|
|
104
|
+
is: 'AwLayoutLogo',
|
|
105
|
+
props: { logo: getters.logo }
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
afterMobileMenuComponent(state) {
|
|
110
|
+
return state.afterMobileMenu
|
|
111
|
+
}
|
|
87
112
|
}
|
|
88
113
|
|
|
89
114
|
export const mutations = {
|
|
@@ -127,6 +152,32 @@ export const mutations = {
|
|
|
127
152
|
|
|
128
153
|
TOGGLE_MOBILE_MENU(state, status = !state.mobileMenuOpened) {
|
|
129
154
|
state.mobileMenuOpened = Boolean(status)
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
SET_LOGO(state, logo) {
|
|
158
|
+
if (typeof logo === 'string') {
|
|
159
|
+
state.logo = mergeDeepRight(state.logo, {
|
|
160
|
+
default: { src: logo },
|
|
161
|
+
dark: { src: logo }
|
|
162
|
+
})
|
|
163
|
+
} else if (typeof logo === 'object' && logo !== null) {
|
|
164
|
+
const _logo = {}
|
|
165
|
+
_logo.default = pathOr(state.logo.default, 'default', logo)
|
|
166
|
+
_logo.dark = pathOr(
|
|
167
|
+
pathOr(state.logo.dark, 'default', logo),
|
|
168
|
+
'dark',
|
|
169
|
+
logo
|
|
170
|
+
)
|
|
171
|
+
_logo.component = pathOr(state.logo.component, 'component', logo)
|
|
172
|
+
|
|
173
|
+
state.logo = _logo
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
SET_AFTER_MOBILE_MENU(state, payload) {
|
|
178
|
+
if (payload && payload.component) {
|
|
179
|
+
state.afterMobileMenu = payload.component
|
|
180
|
+
}
|
|
130
181
|
}
|
|
131
182
|
}
|
|
132
183
|
|