@awes-io/ui 2.75.0 → 2.77.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/assets/css/components/_index.css +4 -0
  3. package/assets/css/components/avatar.css +8 -1
  4. package/assets/css/components/button-nav.css +58 -10
  5. package/assets/css/components/button.css +8 -7
  6. package/assets/css/components/cropper.css +8 -0
  7. package/assets/css/components/empty-container.css +8 -0
  8. package/assets/css/components/icon-menu-item.css +5 -3
  9. package/assets/css/components/layout-menu.css +3 -1
  10. package/assets/css/components/main.css +3 -3
  11. package/assets/css/components/nav.css +1 -1
  12. package/assets/css/components/page-header.css +61 -0
  13. package/assets/css/components/page-single.css +186 -0
  14. package/assets/css/components/progress.css +23 -0
  15. package/assets/css/components/user-menu.css +27 -2
  16. package/assets/js/constants.js +6 -20
  17. package/components/1_atoms/AwAvatar.vue +39 -8
  18. package/components/1_atoms/AwProgress.vue +68 -0
  19. package/components/2_molecules/AwEmptyContainer.vue +104 -0
  20. package/components/3_organisms/AwCropper.vue +6 -1
  21. package/components/3_organisms/AwIslandAvatar.vue +15 -2
  22. package/components/3_organisms/AwPagination.vue +10 -6
  23. package/components/3_organisms/AwTags.vue +1 -1
  24. package/components/4_pages/AwPage.vue +3 -41
  25. package/components/4_pages/AwPageSingle.vue +219 -0
  26. package/components/4_pages/_AwPageHeader.vue +64 -0
  27. package/components/5_layouts/_AwMenuItemIcon.vue +8 -2
  28. package/components/5_layouts/_AwUserMenu.vue +29 -2
  29. package/mixins/page.js +58 -0
  30. package/nuxt/awes.config.js +2 -2
  31. package/package.json +3 -2
  32. package/tailwind/container.js +1 -1
  33. package/tailwind.config.js +4 -1
@@ -0,0 +1,219 @@
1
+ <template>
2
+ <div class="aw-page-single">
3
+ <AwPageHeader
4
+ ref="header"
5
+ :progress="headerProgress"
6
+ :primary="$screen.lg || isHeaderStuck"
7
+ :title="_title"
8
+ :hide-title="!$screen.lg && !isHeaderStuck"
9
+ :hide-menu="hideMenu"
10
+ class="aw-page-single__header"
11
+ :class="{ 'aw-page-single__header--is-stuck': isHeaderStuck }"
12
+ >
13
+ <template #breadcrumbs>
14
+ <slot name="breadcrumb">
15
+ <AwButton
16
+ theme="ghost"
17
+ color="default"
18
+ :href="backUrl"
19
+ :aria-label="breadcrumb?.title ?? $t('Back')"
20
+ v-on="backUrl ? null : { click: () => $router.back() }"
21
+ >
22
+ <template #icon>
23
+ <AwIconSystemMono name="arrow" />
24
+ </template>
25
+ </AwButton>
26
+ </slot>
27
+
28
+ <slot name="after-breadcrumb" />
29
+ </template>
30
+
31
+ <template #default>
32
+ <slot name="buttons"></slot>
33
+
34
+ <AwButton
35
+ v-if="actionButton && $screen.lg"
36
+ v-bind="actionButton"
37
+ size="md"
38
+ @click="$emit('action')"
39
+ />
40
+ </template>
41
+ </AwPageHeader>
42
+
43
+ <div
44
+ class="aw-page-single__container"
45
+ :class="{
46
+ 'aw-page-single__container--preview': isPreviewContainer,
47
+ container: containerType === 'default',
48
+ 'container-fluid': containerType === 'full'
49
+ }"
50
+ >
51
+ <div class="aw-page-single__mobile-title" aria-hidden="true">
52
+ {{ _title }}
53
+ </div>
54
+
55
+ <AwDescription
56
+ v-if="!$screen.lg && description"
57
+ class="aw-page-single__mobile-description"
58
+ tag="div"
59
+ >
60
+ {{ description }}
61
+ </AwDescription>
62
+
63
+ <div
64
+ ref="topScrollMark"
65
+ class="aw-page-single__top-scroll-mark"
66
+ aria-hidden="true"
67
+ ></div>
68
+
69
+ <div
70
+ class="aw-page-single__content"
71
+ :class="{
72
+ 'aw-page-single__content--column': isPreviewContainer
73
+ }"
74
+ >
75
+ <slot />
76
+ </div>
77
+
78
+ <!-- 'aw-page-single__preview--header-sticky': isHeaderStuck -->
79
+ <div
80
+ v-if="hasPreview"
81
+ class="aw-page-single__preview"
82
+ :class="{
83
+ 'aw-page-single__preview--reverse': reverse,
84
+ 'aw-page-single__preview--column': isPreviewContainer
85
+ }"
86
+ >
87
+ <slot name="preview" />
88
+ </div>
89
+
90
+ <div
91
+ v-if="actionButton && !$screen.lg"
92
+ class="aw-page-single__mobile-action-button"
93
+ :class="{
94
+ 'aw-page-single__mobile-action-button--is-stuck': isActionButtonStuck
95
+ }"
96
+ >
97
+ <AwButton
98
+ v-bind="actionButton"
99
+ size="lg"
100
+ @click="$emit('action')"
101
+ />
102
+ </div>
103
+
104
+ <div
105
+ ref="bottomScrollMark"
106
+ class="aw-page-single__bottom-scroll-mark"
107
+ aria-hidden="true"
108
+ ></div>
109
+ </div>
110
+ </div>
111
+ </template>
112
+
113
+ <script>
114
+ import { isType } from 'rambdax'
115
+ import pageMixin from '@AwMixins/page'
116
+
117
+ const CONTAINER_TYPES = ['default', 'full']
118
+
119
+ export default {
120
+ name: 'AwPageSingle',
121
+
122
+ components: {
123
+ AwPageHeader: () => import('@AwPages/_AwPageHeader.vue')
124
+ },
125
+
126
+ mixins: [pageMixin],
127
+
128
+ props: {
129
+ headerProgress: {
130
+ type: Number,
131
+ default: null
132
+ },
133
+
134
+ action: {
135
+ type: Object,
136
+ default: null
137
+ },
138
+
139
+ container: {
140
+ type: String,
141
+ default: null
142
+ },
143
+
144
+ description: {
145
+ type: String,
146
+ default: ''
147
+ },
148
+
149
+ reverse: Boolean,
150
+
151
+ hideMenu: Boolean
152
+ },
153
+
154
+ data() {
155
+ return {
156
+ isHeaderStuck: false,
157
+ isActionButtonStuck: false
158
+ }
159
+ },
160
+
161
+ computed: {
162
+ containerType() {
163
+ return CONTAINER_TYPES.includes(this.container)
164
+ ? this.container
165
+ : null
166
+ },
167
+
168
+ isPreviewContainer() {
169
+ return this.containerType === null
170
+ },
171
+
172
+ hasPreview() {
173
+ return this.$scopedSlots.preview || this.$slots.preview
174
+ },
175
+
176
+ actionButton() {
177
+ if (!isType('Object', this.action)) {
178
+ return null
179
+ }
180
+
181
+ return this.action
182
+ }
183
+ },
184
+
185
+ mounted() {
186
+ this._initScrollWatcher()
187
+ },
188
+
189
+ methods: {
190
+ _initScrollWatcher() {
191
+ if (this.$options.$observer) return
192
+
193
+ const { topScrollMark, bottomScrollMark } = this.$refs
194
+
195
+ this.$options.$observer = new IntersectionObserver((entries) => {
196
+ for (let i = 0; i < entries.length; i++) {
197
+ const entry = entries[i]
198
+
199
+ if (entry.target === topScrollMark) {
200
+ this.isHeaderStuck = !entry.isIntersecting
201
+ }
202
+
203
+ if (entry.target === bottomScrollMark) {
204
+ this.isActionButtonStuck = !entry.isIntersecting
205
+ }
206
+ }
207
+ })
208
+
209
+ this.$options.$observer.observe(topScrollMark)
210
+ this.$options.$observer.observe(bottomScrollMark)
211
+
212
+ this.$once('hook:beforeDestroy', () => {
213
+ this.$options.$observer.disconnect()
214
+ this.$options.$observer = null
215
+ })
216
+ }
217
+ }
218
+ }
219
+ </script>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="aw-page-header" :class="{ 'aw-page-header--primary': primary }">
3
+ <div class="aw-page-header__breadcrumbs">
4
+ <slot name="breadcrumbs"> </slot>
5
+ </div>
6
+
7
+ <h1
8
+ v-if="title"
9
+ class="aw-page-header__title"
10
+ :class="{ 'sr-only': hideTitle }"
11
+ >
12
+ {{ title }}
13
+ </h1>
14
+
15
+ <div class="aw-page-header__buttons">
16
+ <slot>
17
+ <!-- <EwSupportChat /> -->
18
+ </slot>
19
+
20
+ <AwUserMenu v-if="!hideMenu" outline vertical caret />
21
+ </div>
22
+
23
+ <slot name="progress">
24
+ <AwProgress v-if="showProgress" :progress="progress" />
25
+ </slot>
26
+ </div>
27
+ </template>
28
+
29
+ <script>
30
+ import { isType } from 'rambdax'
31
+
32
+ export default {
33
+ name: 'AwPageHeader',
34
+
35
+ components: {
36
+ AwProgress: () => import('@AwAtoms/AwProgress.vue'),
37
+ AwUserMenu: () => import('@AwLayouts/_AwUserMenu.vue')
38
+ },
39
+
40
+ props: {
41
+ progress: {
42
+ type: Number,
43
+ default: null
44
+ },
45
+
46
+ title: {
47
+ type: String,
48
+ default: ''
49
+ },
50
+
51
+ hideTitle: Boolean,
52
+
53
+ hideMenu: Boolean,
54
+
55
+ primary: Boolean
56
+ },
57
+
58
+ computed: {
59
+ showProgress() {
60
+ return isType('Number', this.progress)
61
+ }
62
+ }
63
+ }
64
+ </script>
@@ -9,7 +9,13 @@
9
9
  v-on="$listeners"
10
10
  >
11
11
  <slot v-bind="$props">
12
- <span class="aw-icon-menu-item__icon-block" tabindex="-1">
12
+ <span
13
+ class="aw-icon-menu-item__icon-block"
14
+ tabindex="-1"
15
+ v-tooltip:right="
16
+ tooltip ? { content: text, offset: [0, -6] } : null
17
+ "
18
+ >
13
19
  <AwIcon
14
20
  :name="(active && iconActive) || icon"
15
21
  :size="size"
@@ -72,7 +78,7 @@ export default {
72
78
 
73
79
  size: {
74
80
  type: [String, Number],
75
- default: 24
81
+ default: 18
76
82
  },
77
83
 
78
84
  active: Boolean,
@@ -10,12 +10,24 @@
10
10
  <slot name="user">
11
11
  <button
12
12
  class="aw-user-menu__user focus-outline"
13
+ :class="{ 'aw-user-menu__user--outline': outline }"
13
14
  aria-haspopup="true"
14
15
  :aria-label="$t('Open menu')"
15
16
  @focus="openDropdown"
16
17
  @mouseenter="openDropdown"
17
18
  >
18
- <AwAvatar v-bind="user" size="40" tabindex="-1" />
19
+ <AwAvatar
20
+ v-bind="user"
21
+ :size="outline ? 24 : 40"
22
+ tabindex="-1"
23
+ />
24
+
25
+ <AwIconSystemMono
26
+ v-if="caret"
27
+ name="angle"
28
+ class="transform transition duration-100"
29
+ :class="{ 'rotate-90': isOpened, 'rotate-270': !isOpened }"
30
+ />
19
31
  </button>
20
32
  </slot>
21
33
 
@@ -23,8 +35,9 @@
23
35
  <AwDropdown
24
36
  ref="dropdown"
25
37
  class="aw-user-menu__menu"
38
+ :show.sync="isOpened"
26
39
  :options="{
27
- placement: 'right-end',
40
+ placement: vertical ? 'bottom-end' : 'right-end',
28
41
  modifiers: [{ name: 'offset', options: { offset: [4, 8] } }]
29
42
  }"
30
43
  >
@@ -111,12 +124,26 @@ export default {
111
124
  AwNavItem
112
125
  },
113
126
 
127
+ props: {
128
+ vertical: Boolean,
129
+
130
+ outline: Boolean,
131
+
132
+ caret: Boolean
133
+ },
134
+
114
135
  inject: {
115
136
  layoutProvider: {
116
137
  default: null
117
138
  }
118
139
  },
119
140
 
141
+ data() {
142
+ return {
143
+ isOpened: false
144
+ }
145
+ },
146
+
120
147
  computed: {
121
148
  ...mapGetters('awesIo', ['user']),
122
149
 
package/mixins/page.js ADDED
@@ -0,0 +1,58 @@
1
+ import { getPath } from '@AwUtils/router'
2
+
3
+ export default {
4
+ props: {
5
+ // Main headline on the page
6
+ title: {
7
+ type: String,
8
+ default: ''
9
+ },
10
+
11
+ // Meta title (`title` prop if not provided)
12
+ metaTitle: {
13
+ type: String,
14
+ default: ''
15
+ },
16
+
17
+ // Breadcrumb object with title and href to return back
18
+ breadcrumb: {
19
+ type: Object,
20
+ default: null,
21
+ validator(params) {
22
+ return params ? typeof params.href !== 'undefined' : true
23
+ }
24
+ }
25
+ },
26
+
27
+ head() {
28
+ return {
29
+ title: this.metaTitle || this.title || undefined
30
+ }
31
+ },
32
+
33
+ computed: {
34
+ backUrl() {
35
+ if (!this.breadcrumb) return null
36
+
37
+ if (this.$store.state.awesIo.backRoute) {
38
+ const { from: _from, to } = this.$store.state.awesIo.backRoute
39
+
40
+ if (getPath(_from) === getPath(this.$route)) {
41
+ return to
42
+ } else {
43
+ return this.breadcrumb.href
44
+ }
45
+ }
46
+
47
+ return this.breadcrumb.href
48
+ },
49
+
50
+ _title() {
51
+ return this.title
52
+ },
53
+
54
+ _hasBreadcrumb() {
55
+ return this.breadcrumb ? !!this.breadcrumb.href : false
56
+ }
57
+ }
58
+ }
@@ -2,7 +2,7 @@ import styles from '../assets/js/styles'
2
2
 
3
3
  export default {
4
4
  logo: {
5
- src: 'https://static.awes.io/logo-blue_white.svg',
5
+ src: 'https://static.awes.io/logo-blue.svg',
6
6
  alt: 'Awes.io'
7
7
  },
8
8
 
@@ -23,7 +23,7 @@ export default {
23
23
 
24
24
  export const dark = {
25
25
  logo: {
26
- src: 'https://static.awes.io/logo-blue.svg',
26
+ src: 'https://static.awes.io/logo-blue_white.svg',
27
27
  alt: 'Awes.io'
28
28
  },
29
29
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awes-io/ui",
3
- "version": "2.75.0",
3
+ "version": "2.77.0",
4
4
  "description": "User Interface (UI) components",
5
5
  "keywords": [
6
6
  "ui",
@@ -51,6 +51,7 @@
51
51
  "@nuxtjs/axios": "^5.13.6",
52
52
  "@nuxtjs/svg-sprite": "^0.5.2",
53
53
  "@popperjs/core": "^2.0.5",
54
+ "animejs": "^3.2.1",
54
55
  "autosize": "^4.0.2",
55
56
  "axios": "^0.27.2",
56
57
  "body-scroll-lock": "^2.6.4",
@@ -112,5 +113,5 @@
112
113
  "rollup-plugin-visualizer": "^2.6.0",
113
114
  "rollup-plugin-vue": "^5.0.1"
114
115
  },
115
- "gitHead": "f06e4e7b83c40ecd59abd6f4249b00ce89d8a7b5"
116
+ "gitHead": "c25bfd73e3141b0aed68fc34d181000dbbd53d16"
116
117
  }
@@ -8,7 +8,7 @@ module.exports = function({ addComponents, theme }) {
8
8
 
9
9
  const containerCenter = theme('container.center', true)
10
10
 
11
- const maxWidth = theme('container.maxWidth', '1200px')
11
+ const maxWidth = theme('container.maxWidth', '1260px')
12
12
  const smallWidth = theme('container.smallWidth', '580px')
13
13
 
14
14
  const container = [
@@ -19,7 +19,7 @@ module.exports = {
19
19
  full: '9999px'
20
20
  },
21
21
  container: {
22
- maxWidth: '1250px',
22
+ maxWidth: '1260px',
23
23
  smallWidth: '580px',
24
24
  padding: {
25
25
  default: '1rem',
@@ -128,6 +128,9 @@ module.exports = {
128
128
  '0 -10px 15px -3px rgba(0, 0, 0, 0.1), 0 -4px 6px -2px rgba(0, 0, 0, 0.05)',
129
129
  button: '2px 2px 4px rgba(0, 0, 0, 0.15)',
130
130
  'button-active': '1px 1px 2px rgba(0, 0, 0, 0.15)'
131
+ },
132
+ rotate: {
133
+ '270': '270deg'
131
134
  }
132
135
  }
133
136
  },