@energie360/ui-library 0.1.32 → 0.1.33
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/components/badge/badge.scss +11 -4
- package/components/badge/u-badge.vue +3 -13
- package/components/card-amount/u-card-amount.vue +1 -1
- package/components/card-amount-illustrated/u-card-amount-illustrated.vue +1 -1
- package/components/card-contact/u-card-contact.vue +1 -1
- package/components/card-highlight/u-card-highlight.vue +2 -2
- package/components/card-price-list/u-card-price-list.vue +2 -2
- package/components/card-statistic/card-statistic.scss +31 -0
- package/components/card-statistic/u-card-statistic.vue +34 -0
- package/components/chip/chip.scss +1 -0
- package/components/chip/u-chip.vue +1 -0
- package/components/download-list-item/u-download-list-item.vue +1 -0
- package/components/empty/empty.scss +27 -0
- package/components/empty/u-empty.vue +32 -0
- package/components/hint/hint.scss +106 -35
- package/components/hint/u-hint.vue +35 -4
- package/components/index.js +2 -0
- package/components/navigation-panel-tile/navigation-panel-tile.scss +0 -18
- package/components/navigation-panel-tile/u-navigation-panel-tile.vue +8 -7
- package/components/navigation-toolbar-link/u-navigation-toolbar-link.vue +2 -2
- package/components/progress-avatar/u-progress-avatar.vue +1 -1
- package/components/slider/u-slider.vue +1 -1
- package/components/slider-progress-animation/u-slider-progress-animation.vue +1 -1
- package/components/table/table-cell.scss +9 -0
- package/components/table/u-cell-icon-group.vue +1 -1
- package/components/table/u-cell-progress-bar.vue +1 -1
- package/components/table/u-table-cell.vue +3 -0
- package/components/text-block/u-text-block.vue +1 -1
- package/dist/base-style.css +2 -2
- package/elements/button/u-button.vue +2 -1
- package/layout/portal-block/portal-block.scss +36 -3
- package/layout/portal-block/u-portal-block.vue +9 -3
- package/modules/dialog/dialog.scss +28 -23
- package/modules/dialog/u-dialog.vue +14 -17
- package/modules/login-animation/u-login-animation.vue +2 -7
- package/modules/navigation-toolbar-top/u-navigation-toolbar-top.vue +24 -2
- package/package.json +9 -9
- package/utils/http/url.js +25 -0
- package/utils/vue/helpers.ts +27 -0
- package/wizard/wizard-outro/u-wizard-outro.vue +3 -0
|
@@ -31,11 +31,18 @@ $ease-out-bounce: cubic-bezier(0.674, 1.901, 0.651, 0.744);
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
.badge__sup.number {
|
|
34
|
-
width: 16px;
|
|
34
|
+
min-width: 16px;
|
|
35
35
|
height: 16px;
|
|
36
36
|
font-size: 10px;
|
|
37
37
|
font-weight: bold;
|
|
38
|
-
line-height:
|
|
38
|
+
line-height: 10px;
|
|
39
|
+
letter-spacing: 0;
|
|
40
|
+
border-radius: 24px;
|
|
41
|
+
text-align: center;
|
|
42
|
+
padding: 0 2px;
|
|
43
|
+
top: var(--top, -5px);
|
|
44
|
+
right: var(--right, 3px);
|
|
45
|
+
transform: translateX(50%);
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
.badge__sup.state {
|
|
@@ -48,8 +55,8 @@ $ease-out-bounce: cubic-bezier(0.674, 1.901, 0.651, 0.744);
|
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
.badge__sup.dot {
|
|
51
|
-
top: var(--top, -
|
|
52
|
-
right: var(--right, -
|
|
58
|
+
top: var(--top, -1px);
|
|
59
|
+
right: var(--right, -1px);
|
|
53
60
|
width: 8px;
|
|
54
61
|
height: 8px;
|
|
55
62
|
border-radius: 100%;
|
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
export interface Badge {
|
|
3
3
|
color?: string
|
|
4
4
|
dot?: boolean
|
|
5
|
-
type?: 'default' | 'success' | 'error' | 'warning' | 'info'
|
|
6
5
|
value?: number
|
|
7
6
|
state?: '' | 'inactive'
|
|
8
7
|
show?: boolean
|
|
9
|
-
border?: boolean
|
|
10
8
|
top?: number
|
|
11
9
|
right?: number
|
|
12
10
|
}
|
|
@@ -17,7 +15,6 @@ const {
|
|
|
17
15
|
top = 0,
|
|
18
16
|
right = 0,
|
|
19
17
|
color = 'var(--e-c-mono-900)',
|
|
20
|
-
type = 'default',
|
|
21
18
|
show = true,
|
|
22
19
|
} = defineProps<Badge>()
|
|
23
20
|
</script>
|
|
@@ -32,23 +29,16 @@ const {
|
|
|
32
29
|
>
|
|
33
30
|
<slot></slot>
|
|
34
31
|
|
|
35
|
-
<sup
|
|
36
|
-
v-if="dot"
|
|
37
|
-
class="badge__sup dot"
|
|
38
|
-
:class="[`type-${type}`, { border }]"
|
|
39
|
-
:style="{ backgroundColor: color }"
|
|
40
|
-
></sup>
|
|
32
|
+
<sup v-if="dot" class="badge__sup dot" :style="{ backgroundColor: color }"></sup>
|
|
41
33
|
|
|
42
34
|
<sup
|
|
43
35
|
v-else-if="state"
|
|
44
36
|
class="badge__sup state"
|
|
45
|
-
:class="[state
|
|
37
|
+
:class="[state]"
|
|
46
38
|
:style="{ backgroundColor: color }"
|
|
47
39
|
></sup>
|
|
48
40
|
|
|
49
|
-
<sup v-else class="badge__sup number" :
|
|
50
|
-
value
|
|
51
|
-
}}</sup>
|
|
41
|
+
<sup v-else class="badge__sup number" :style="{ backgroundColor: color }">{{ value }}</sup>
|
|
52
42
|
</span>
|
|
53
43
|
</template>
|
|
54
44
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import UProgressBar from '../progress-bar/u-progress-bar.vue'
|
|
3
3
|
import { useTemplateRef, inject, watch, ref, onMounted, onUnmounted } from 'vue'
|
|
4
4
|
import { Image } from '../../elements/types'
|
|
5
5
|
import '@lottiefiles/lottie-player'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { Chip } from '../chip/u-chip.vue'
|
|
3
3
|
import { Image } from '../../elements/types'
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import UIcon from '../../elements/icon/u-icon.vue'
|
|
5
|
+
import UChip from '../chip/u-chip.vue'
|
|
6
6
|
|
|
7
7
|
interface Props {
|
|
8
8
|
title?: string
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
@use '../../base/abstracts' as a;
|
|
2
|
+
|
|
3
|
+
.card-statistic {
|
|
4
|
+
display: flex;
|
|
5
|
+
justify-content: space-between;
|
|
6
|
+
column-gap: var(--e-space-2);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.card-statistic__image {
|
|
10
|
+
width: 80px;
|
|
11
|
+
height: 80px;
|
|
12
|
+
flex: 0 0 auto;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.card-statistic__content {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
row-gap: var(--e-space-2);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.card-statistic__label {
|
|
22
|
+
@include a.type(200);
|
|
23
|
+
|
|
24
|
+
order: 2;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.card-statistic__value {
|
|
28
|
+
@include a.type(700, strong);
|
|
29
|
+
|
|
30
|
+
order: 1;
|
|
31
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Image } from '../../elements/types'
|
|
3
|
+
import { hasSlotContent } from '../../utils/vue/helpers'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
label?: string
|
|
7
|
+
value?: string
|
|
8
|
+
image?: Image
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
defineProps<Props>()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<div class="card-statistic">
|
|
16
|
+
<dl class="card-statistic__content">
|
|
17
|
+
<dt class="card-statistic__label">
|
|
18
|
+
<slot name="label">{{ label }}</slot>
|
|
19
|
+
</dt>
|
|
20
|
+
|
|
21
|
+
<dd class="card-statistic__value">
|
|
22
|
+
<slot name="value">{{ value }}</slot>
|
|
23
|
+
</dd>
|
|
24
|
+
</dl>
|
|
25
|
+
|
|
26
|
+
<div v-if="image || hasSlotContent($slots.image)" class="card-statistic__image">
|
|
27
|
+
<slot name="image">
|
|
28
|
+
<img v-bind="image" />
|
|
29
|
+
</slot>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<style scoped lang="scss" src="./card-statistic.scss"></style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
@use '../../base/abstracts' as a;
|
|
2
|
+
|
|
3
|
+
.empty {
|
|
4
|
+
text-align: center;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.empty__image {
|
|
8
|
+
margin: 0 auto var(--e-space-6);
|
|
9
|
+
width: a.rem(120);
|
|
10
|
+
height: a.rem(120);
|
|
11
|
+
|
|
12
|
+
> img {
|
|
13
|
+
object-fit: cover;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 100%;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.empty__title {
|
|
20
|
+
@include a.type(600);
|
|
21
|
+
|
|
22
|
+
margin-bottom: var(--e-space-6);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.empty__text {
|
|
26
|
+
@include a.type(300, strong);
|
|
27
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { hasSlotContent } from '../../utils/vue/helpers'
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
title?: string
|
|
6
|
+
text?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
defineProps<Props>()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<div class="empty">
|
|
14
|
+
<div class="empty__image">
|
|
15
|
+
<slot name="image">
|
|
16
|
+
<img src="/static/ui-assets/images/search.svg" alt="" />
|
|
17
|
+
</slot>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<p v-if="title || hasSlotContent($slots.title)" class="empty__title">
|
|
21
|
+
<slot name="title">
|
|
22
|
+
{{ title }}
|
|
23
|
+
</slot>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<p v-if="text || hasSlotContent($slots.text)" class="empty__text">
|
|
27
|
+
<slot name="text"> {{ text }} </slot>
|
|
28
|
+
</p>
|
|
29
|
+
</div>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<style scoped lang="scss" src="./empty.scss"></style>
|
|
@@ -7,10 +7,6 @@
|
|
|
7
7
|
background-color: var(--e-c-secondary-05-100);
|
|
8
8
|
color: var(--e-c-secondary-05-900);
|
|
9
9
|
|
|
10
|
-
&::before {
|
|
11
|
-
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1Zm1-8h-2V7h2v2Z' fill='%230096DC'/%3E%3C/svg%3E");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
.hint__richtext {
|
|
15
11
|
margin-left: var(--e-space-9);
|
|
16
12
|
|
|
@@ -19,6 +15,10 @@
|
|
|
19
15
|
}
|
|
20
16
|
}
|
|
21
17
|
|
|
18
|
+
.hint__icon {
|
|
19
|
+
color: var(--e-c-secondary-05-500);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
22
|
// override some richtext styles.
|
|
23
23
|
.richtext {
|
|
24
24
|
a {
|
|
@@ -37,10 +37,6 @@
|
|
|
37
37
|
background-color: var(--e-c-signal-02-100);
|
|
38
38
|
color: var(--e-c-signal-02-900);
|
|
39
39
|
|
|
40
|
-
&::before {
|
|
41
|
-
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 21 12 2l11 19H1Zm11-3c.283 0 .52-.096.713-.288A.968.968 0 0 0 13 17a.968.968 0 0 0-.287-.712A.968.968 0 0 0 12 16a.968.968 0 0 0-.713.288A.968.968 0 0 0 11 17c0 .283.096.52.287.712.192.192.43.288.713.288Zm-1-3h2v-5h-2v5Z' fill='%23FF9800'/%3E%3C/svg%3E");
|
|
42
|
-
}
|
|
43
|
-
|
|
44
40
|
.hint__richtext {
|
|
45
41
|
margin-left: var(--e-space-9);
|
|
46
42
|
|
|
@@ -49,6 +45,10 @@
|
|
|
49
45
|
}
|
|
50
46
|
}
|
|
51
47
|
|
|
48
|
+
.hint__icon {
|
|
49
|
+
color: var(--e-c-signal-02-500);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
52
|
// override some richtext styles.
|
|
53
53
|
.richtext {
|
|
54
54
|
a {
|
|
@@ -76,17 +76,18 @@
|
|
|
76
76
|
border-left-color: var(--e-c-mono-700);
|
|
77
77
|
color: var(--e-c-mono-900);
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
left: calc(
|
|
83
|
-
-24px - 12px - 4px
|
|
84
|
-
); // 24px: icon width, 12px: distance to box, 4px: additonal border-width
|
|
79
|
+
.hint__label,
|
|
80
|
+
.hint__richtext {
|
|
81
|
+
margin-left: 0;
|
|
85
82
|
}
|
|
86
83
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
&.no-label .hint__label {
|
|
85
|
+
height: 0;
|
|
86
|
+
min-height: 0;
|
|
87
|
+
|
|
88
|
+
@include a.bp(lg) {
|
|
89
|
+
margin-top: -8px;
|
|
90
|
+
}
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
.hint__link {
|
|
@@ -96,13 +97,22 @@
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
.hint__icon {
|
|
101
|
+
top: 0;
|
|
102
|
+
left: calc(
|
|
103
|
+
-24px - 12px - 4px
|
|
104
|
+
); // 24px: icon width, 12px: distance to box, 4px: additonal border-width
|
|
105
|
+
|
|
106
|
+
color: var(--e-c-mono-700);
|
|
107
|
+
}
|
|
108
|
+
|
|
99
109
|
@include a.bp(lg) {
|
|
100
110
|
margin-top: calc(4px + 4px + 24px);
|
|
101
111
|
border: 1px solid var(--e-c-mono-500);
|
|
102
112
|
border-top-width: 4px;
|
|
103
113
|
border-top-color: var(--e-c-mono-700);
|
|
104
114
|
|
|
105
|
-
|
|
115
|
+
.hint__icon {
|
|
106
116
|
left: 0;
|
|
107
117
|
top: calc(
|
|
108
118
|
-24px - 4px - 4px
|
|
@@ -115,10 +125,42 @@
|
|
|
115
125
|
background-color: var(--e-c-signal-03-100);
|
|
116
126
|
color: var(--e-c-signal-03-900);
|
|
117
127
|
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
.hint__richtext {
|
|
129
|
+
margin-left: var(--e-space-9);
|
|
130
|
+
|
|
131
|
+
@include a.bp(lg) {
|
|
132
|
+
margin-left: 0;
|
|
133
|
+
}
|
|
120
134
|
}
|
|
121
135
|
|
|
136
|
+
// override some richtext styles.
|
|
137
|
+
.richtext {
|
|
138
|
+
a {
|
|
139
|
+
color: inherit;
|
|
140
|
+
|
|
141
|
+
&:active,
|
|
142
|
+
&:hover {
|
|
143
|
+
text-decoration-color: var(--e-c-signal-03-100);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.hint__link {
|
|
149
|
+
&:active,
|
|
150
|
+
&:hover {
|
|
151
|
+
text-decoration-color: var(--e-c-signal-03-100);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.hint__icon {
|
|
156
|
+
color: var(--e-c-signal-03-500);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@mixin type-task {
|
|
161
|
+
background-color: var(--e-c-secondary-03-100);
|
|
162
|
+
color: var(--e-c-signal-03-900);
|
|
163
|
+
|
|
122
164
|
.hint__richtext {
|
|
123
165
|
margin-left: var(--e-space-9);
|
|
124
166
|
|
|
@@ -127,6 +169,10 @@
|
|
|
127
169
|
}
|
|
128
170
|
}
|
|
129
171
|
|
|
172
|
+
.hint__icon {
|
|
173
|
+
color: var(--e-c-secondary-03-500);
|
|
174
|
+
}
|
|
175
|
+
|
|
130
176
|
// override some richtext styles.
|
|
131
177
|
.richtext {
|
|
132
178
|
a {
|
|
@@ -160,7 +206,6 @@
|
|
|
160
206
|
|
|
161
207
|
display: inline-block;
|
|
162
208
|
color: inherit;
|
|
163
|
-
margin-left: var(--e-space-2);
|
|
164
209
|
|
|
165
210
|
&:active,
|
|
166
211
|
&:hover {
|
|
@@ -169,11 +214,19 @@
|
|
|
169
214
|
|
|
170
215
|
@include a.bp(lg) {
|
|
171
216
|
display: block;
|
|
172
|
-
margin-left: 0;
|
|
173
217
|
}
|
|
174
218
|
}
|
|
175
219
|
|
|
176
220
|
.hint__label {
|
|
221
|
+
@include a.type(200, strong);
|
|
222
|
+
|
|
223
|
+
margin-left: var(--e-space-9);
|
|
224
|
+
|
|
225
|
+
@include a.bp(lg) {
|
|
226
|
+
margin-left: var(--e-space-7);
|
|
227
|
+
min-height: 24px;
|
|
228
|
+
}
|
|
229
|
+
|
|
177
230
|
+ .hint__richtext {
|
|
178
231
|
margin-top: var(--e-space-1);
|
|
179
232
|
|
|
@@ -183,29 +236,35 @@
|
|
|
183
236
|
}
|
|
184
237
|
}
|
|
185
238
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
position: absolute;
|
|
189
|
-
top: var(--e-space-5);
|
|
190
|
-
left: var(--e-space-4);
|
|
191
|
-
width: a.rem(24);
|
|
192
|
-
height: a.rem(24);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
> p {
|
|
196
|
-
@include a.type(200, strong);
|
|
239
|
+
.hint__label-text + .hint__link {
|
|
240
|
+
margin-left: var(--e-space-2);
|
|
197
241
|
|
|
198
|
-
|
|
242
|
+
@include a.bp(lg) {
|
|
243
|
+
margin-left: 0;
|
|
244
|
+
}
|
|
199
245
|
}
|
|
200
246
|
|
|
201
247
|
@include a.bp(lg) {
|
|
202
248
|
padding: var(--e-space-4);
|
|
203
249
|
|
|
204
|
-
|
|
250
|
+
.hint__icon {
|
|
205
251
|
top: var(--e-space-4);
|
|
206
252
|
}
|
|
207
253
|
}
|
|
208
254
|
|
|
255
|
+
// States
|
|
256
|
+
&.no-label {
|
|
257
|
+
.hint__label {
|
|
258
|
+
// This gives same layout as when `.hint__label` was removed from DOM.
|
|
259
|
+
// We can't remove it because wew need this element for mobile layout.
|
|
260
|
+
margin-top: -4px;
|
|
261
|
+
|
|
262
|
+
@include a.bp(lg) {
|
|
263
|
+
margin-top: 0;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
209
268
|
// Modifiers
|
|
210
269
|
&.hint--warning {
|
|
211
270
|
@include type-warning;
|
|
@@ -218,4 +277,16 @@
|
|
|
218
277
|
&.hint--error {
|
|
219
278
|
@include type-error;
|
|
220
279
|
}
|
|
280
|
+
|
|
281
|
+
&.hint--task {
|
|
282
|
+
@include type-task;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.hint__icon {
|
|
287
|
+
position: absolute;
|
|
288
|
+
top: var(--e-space-5);
|
|
289
|
+
left: var(--e-space-4);
|
|
290
|
+
width: a.rem(24);
|
|
291
|
+
height: a.rem(24);
|
|
221
292
|
}
|
|
@@ -1,21 +1,43 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import URichtext from '../richtext/u-richtext.vue'
|
|
3
3
|
import { Cta } from '../../elements/types'
|
|
4
|
+
import { hasSlotContent } from '../../utils/vue/helpers'
|
|
5
|
+
import UIcon from '../../elements/icon/u-icon.vue'
|
|
4
6
|
|
|
5
7
|
interface Props {
|
|
6
|
-
type?: 'neutral' | 'warning' | 'legal' | 'error'
|
|
8
|
+
type?: 'neutral' | 'warning' | 'legal' | 'error' | 'task'
|
|
7
9
|
label?: string
|
|
8
10
|
link?: Cta
|
|
9
11
|
text?: string
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
const { label = '', link = undefined, text = '', type = 'neutral' } = defineProps<Props>()
|
|
15
|
+
|
|
16
|
+
// default mapping 'type' -> icon
|
|
17
|
+
const iconMap = {
|
|
18
|
+
neutral: 'info-circle-filled',
|
|
19
|
+
warning: 'alert-triangle-filled',
|
|
20
|
+
legal: 'legal',
|
|
21
|
+
error: 'alert-octagon-filled',
|
|
22
|
+
task: 'check-circle-filled',
|
|
23
|
+
}
|
|
13
24
|
</script>
|
|
14
25
|
|
|
15
26
|
<template>
|
|
16
|
-
<div
|
|
27
|
+
<div
|
|
28
|
+
:class="[
|
|
29
|
+
'hint',
|
|
30
|
+
`hint--${type}`,
|
|
31
|
+
{ 'no-label': !label && !hasSlotContent($slots.label) && !link },
|
|
32
|
+
]"
|
|
33
|
+
>
|
|
34
|
+
<span class="hint__icon">
|
|
35
|
+
<slot name="icon"> <UIcon :name="iconMap[type]" /> </slot>
|
|
36
|
+
</span>
|
|
17
37
|
<p class="hint__label">
|
|
18
|
-
<
|
|
38
|
+
<span v-if="label || hasSlotContent($slots.label)" class="hint__label-text">
|
|
39
|
+
<slot name="label">{{ label }}</slot>
|
|
40
|
+
</span>
|
|
19
41
|
|
|
20
42
|
<a v-if="link" :href="link.href" :target="link.target" class="hint__link">
|
|
21
43
|
{{ link.label }}
|
|
@@ -68,4 +90,13 @@ const { label = '', link = undefined, text = '', type = 'neutral' } = defineProp
|
|
|
68
90
|
}
|
|
69
91
|
}
|
|
70
92
|
}
|
|
93
|
+
|
|
94
|
+
.hint--error {
|
|
95
|
+
.hint__richtext a {
|
|
96
|
+
&:active,
|
|
97
|
+
&:hover {
|
|
98
|
+
text-decoration-color: var(--e-c-secondary-03-100);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
71
102
|
</style>
|
package/components/index.js
CHANGED
|
@@ -72,3 +72,5 @@ export { default as UNotificationItem } from './notification-item/u-notification
|
|
|
72
72
|
export { default as UNotificationList } from './notification-list/u-notification-list.vue'
|
|
73
73
|
export { default as UDefinitionList } from './definition-list/u-definition-list.vue'
|
|
74
74
|
export { default as UDefinitionListItem } from './definition-list-item/u-definition-list-item.vue'
|
|
75
|
+
export { default as UCardStatistic } from './card-statistic/u-card-statistic.vue'
|
|
76
|
+
export { default as UEmpty } from './empty/u-empty.vue'
|
|
@@ -82,24 +82,6 @@
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
.badge {
|
|
86
|
-
position: absolute;
|
|
87
|
-
top: -2px;
|
|
88
|
-
right: -2px;
|
|
89
|
-
width: a.rem(13);
|
|
90
|
-
height: a.rem(13);
|
|
91
|
-
background-color: var(--e-c-mono-900);
|
|
92
|
-
border-radius: 100%;
|
|
93
|
-
|
|
94
|
-
&.inactive {
|
|
95
|
-
background-image: url("data:image/svg+xml,%3Csvg width='13' height='13' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='6.5' cy='6.5' r='6.5' fill='%23333'/%3E%3Cpath d='m4.414 3 2.12 2.121L8.658 3l1.414 1.414-2.122 2.122 2.122 2.121-1.414 1.414-2.122-2.12-2.12 2.12L3 8.656l2.12-2.12L3 4.412 4.414 3Z' fill='%23fff'/%3E%3C/svg%3E");
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
85
|
.navigation-panel-tile__text-column {
|
|
100
86
|
flex: 1 1 auto;
|
|
101
87
|
}
|
|
102
|
-
|
|
103
|
-
.badge + .icon {
|
|
104
|
-
color: var(--e-c-mono-500);
|
|
105
|
-
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
import { UIcon } from '../../elements'
|
|
4
|
-
|
|
5
|
-
type
|
|
4
|
+
import UBadge from '../../components/badge/u-badge.vue'
|
|
5
|
+
import type { Badge } from '../badge/u-badge.vue'
|
|
6
6
|
|
|
7
7
|
interface Props {
|
|
8
8
|
active?: boolean
|
|
@@ -11,7 +11,7 @@ interface Props {
|
|
|
11
11
|
greyed?: boolean
|
|
12
12
|
href?: string
|
|
13
13
|
icon?: string
|
|
14
|
-
|
|
14
|
+
badge?: Badge
|
|
15
15
|
target?: string
|
|
16
16
|
title?: string
|
|
17
17
|
}
|
|
@@ -19,7 +19,7 @@ interface Props {
|
|
|
19
19
|
const {
|
|
20
20
|
description = '',
|
|
21
21
|
icon = '',
|
|
22
|
-
|
|
22
|
+
badge = undefined,
|
|
23
23
|
title = '',
|
|
24
24
|
href = '',
|
|
25
25
|
target = '_self',
|
|
@@ -53,9 +53,10 @@ const tag = computed(() => (href ? 'a' : 'div'))
|
|
|
53
53
|
|
|
54
54
|
<div class="navigation-panel-tile__icon-column">
|
|
55
55
|
<div v-if="icon" class="navigation-panel-tile__icon-wrapper">
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
<UBadge v-if="badge" v-bind="badge">
|
|
57
|
+
<UIcon :name="icon" />
|
|
58
|
+
</UBadge>
|
|
59
|
+
<UIcon v-else :name="icon" />
|
|
59
60
|
</div>
|
|
60
61
|
</div>
|
|
61
62
|
</component>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, watch, computed, useTemplateRef } from 'vue'
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import UIcon from '../../elements/icon/u-icon.vue'
|
|
4
|
+
import UBadge from '../../components/badge/u-badge.vue'
|
|
5
5
|
import { Badge } from '../badge/u-badge.vue'
|
|
6
6
|
|
|
7
7
|
// TODO: Label animation when collapsed is a mess. Refactor it as soon as possbile!
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { onMounted, useTemplateRef, ref } from 'vue'
|
|
3
3
|
import { Image } from '../../elements/types'
|
|
4
|
-
import
|
|
4
|
+
import UCircularProgress from '../circular-progress/u-circular-progress.vue'
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
image: Image
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { watch, useId, useTemplateRef, onMounted, ref } from 'vue'
|
|
3
3
|
import { scaleValue } from '../../utils/math/scale-value'
|
|
4
4
|
import { clamp } from '../../utils/math/clamp'
|
|
5
|
-
import
|
|
5
|
+
import UTooltip from '../tooltip/u-tooltip.vue'
|
|
6
6
|
|
|
7
7
|
interface SliderDot {
|
|
8
8
|
value: number
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
|
|
3
3
|
import '@lottiefiles/lottie-player'
|
|
4
|
-
import
|
|
4
|
+
import USlider from '../slider/u-slider.vue'
|
|
5
5
|
import { Slider } from '../slider/u-slider.vue'
|
|
6
6
|
import { Image } from '../../elements/types'
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import UIcon from '../../elements/icon/u-icon.vue'
|
|
3
3
|
import UTooltip from '../tooltip/u-tooltip.vue'
|
|
4
|
-
import
|
|
4
|
+
import UBadge from '../badge/u-badge.vue'
|
|
5
5
|
import { Badge } from '../badge/u-badge.vue'
|
|
6
6
|
import { TableCellIconColor } from './table.type'
|
|
7
7
|
|
|
@@ -7,6 +7,7 @@ interface Props extends TableCellBase {
|
|
|
7
7
|
infoText?: string
|
|
8
8
|
textStyle?: TableCellTextStyle
|
|
9
9
|
nowrap?: boolean
|
|
10
|
+
dotColor?: string
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
const {
|
|
@@ -15,6 +16,7 @@ const {
|
|
|
15
16
|
hAlign = TableCellHAlign.left,
|
|
16
17
|
vAlign = TableCellVAlign.center,
|
|
17
18
|
nowrap = false,
|
|
19
|
+
dotColor = '',
|
|
18
20
|
} = defineProps<Props>()
|
|
19
21
|
</script>
|
|
20
22
|
|
|
@@ -24,6 +26,7 @@ const {
|
|
|
24
26
|
:class="['table-cell', `h-align-${hAlign}`, `v-align-${vAlign}`, { 'has-tooltip': infoText }]"
|
|
25
27
|
>
|
|
26
28
|
<div :class="['cell-content', `text-${textStyle}`, { nowrap }]">
|
|
29
|
+
<span v-if="dotColor" class="table-cell__dot" :style="{ backgroundColor: dotColor }"></span>
|
|
27
30
|
<slot><span v-html="text" /></slot>
|
|
28
31
|
</div>
|
|
29
32
|
|
package/dist/base-style.css
CHANGED
|
@@ -317,8 +317,8 @@ body {
|
|
|
317
317
|
--e-c-signal-02-700-rgb: 204, 122, 0;
|
|
318
318
|
--e-c-signal-02-900: #703600;
|
|
319
319
|
--e-c-signal-02-900-rgb: 112, 54, 0;
|
|
320
|
-
--e-c-signal-03-100: #
|
|
321
|
-
--e-c-signal-03-100-rgb: 255,
|
|
320
|
+
--e-c-signal-03-100: #ffccd7;
|
|
321
|
+
--e-c-signal-03-100-rgb: 255, 204, 215;
|
|
322
322
|
--e-c-signal-03-500: #ff0c3e;
|
|
323
323
|
--e-c-signal-03-500-rgb: 255, 12, 62;
|
|
324
324
|
--e-c-signal-03-700: #b90d31;
|
|
@@ -1,8 +1,41 @@
|
|
|
1
1
|
.portal-block {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
&.bottom-space-0 {
|
|
3
|
+
margin-bottom: 0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
&.bottom-space-100 {
|
|
7
|
+
margin-bottom: var(--e-space-6);
|
|
8
|
+
}
|
|
4
9
|
|
|
5
|
-
&.
|
|
10
|
+
&.bottom-space-300 {
|
|
6
11
|
margin-bottom: var(--e-space-10);
|
|
7
12
|
}
|
|
13
|
+
|
|
14
|
+
&.bottom-space-500 {
|
|
15
|
+
margin-bottom: var(--e-space-16);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&.bottom-space-700 {
|
|
19
|
+
margin-bottom: var(--e-space-28);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&.top-space-0 {
|
|
23
|
+
margin-top: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&.top-space-100 {
|
|
27
|
+
margin-top: var(--e-space-6);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&.top-space-300 {
|
|
31
|
+
margin-top: var(--e-space-10);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&.top-space-500 {
|
|
35
|
+
margin-top: var(--e-space-16);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&.top-space-700 {
|
|
39
|
+
margin-top: var(--e-space-28);
|
|
40
|
+
}
|
|
8
41
|
}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
Preferably only use `bottom-space`.
|
|
4
|
+
`top-space` can make sense for last portal-block for example.
|
|
5
|
+
This works because parent container is `display: block`, meaning that the vertical margins will collapse.
|
|
6
|
+
*/
|
|
2
7
|
interface Props {
|
|
3
8
|
big?: boolean
|
|
4
|
-
|
|
9
|
+
bottomSpace?: '0' | '100' | '300' | '500' | '700'
|
|
10
|
+
topSpace?: '0' | '100' | '300' | '500' | '700'
|
|
5
11
|
}
|
|
6
12
|
|
|
7
|
-
const {
|
|
13
|
+
const { bottomSpace = '100', topSpace = '0' } = defineProps<Props>()
|
|
8
14
|
</script>
|
|
9
15
|
|
|
10
16
|
<template>
|
|
11
|
-
<div :class="['portal-block', space]">
|
|
17
|
+
<div :class="['portal-block', `bottom-space-${bottomSpace}`, `top-space-${topSpace}`]">
|
|
12
18
|
<slot />
|
|
13
19
|
</div>
|
|
14
20
|
</template>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
.dialog-container {
|
|
6
6
|
--overflow-gradient-height: var(--e-space-10);
|
|
7
|
+
--dialog-max-width: #{a.rem(540)};
|
|
7
8
|
|
|
8
9
|
padding: 0;
|
|
9
10
|
border: 0;
|
|
@@ -26,18 +27,6 @@
|
|
|
26
27
|
opacity: 0.4;
|
|
27
28
|
animation: fade-in-backdrop var(--e-trs-duration-faster) var(--e-trs-easing-default);
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
-
&.has-header-image {
|
|
31
|
-
.dialog__header-image-container {
|
|
32
|
-
display: flex;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
&.has-content-image {
|
|
37
|
-
.dialog__content-image {
|
|
38
|
-
display: block;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
30
|
}
|
|
42
31
|
|
|
43
32
|
.dialog {
|
|
@@ -47,14 +36,22 @@
|
|
|
47
36
|
overflow: auto;
|
|
48
37
|
scrollbar-width: none;
|
|
49
38
|
border-radius: var(--e-brd-radius-3);
|
|
50
|
-
padding: var(--e-space-
|
|
39
|
+
padding: var(--e-space-8) var(--e-space-8) 0;
|
|
51
40
|
height: a.rem(670);
|
|
52
41
|
max-height: 80vh;
|
|
53
|
-
max-width:
|
|
42
|
+
max-width: var(--dialog-max-width);
|
|
54
43
|
min-width: a.rem(480);
|
|
55
44
|
|
|
56
|
-
&.
|
|
45
|
+
&.fit-height {
|
|
57
46
|
height: auto;
|
|
47
|
+
|
|
48
|
+
.cta-container {
|
|
49
|
+
margin-top: 0;
|
|
50
|
+
|
|
51
|
+
&::after {
|
|
52
|
+
content: none;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
* + .dialog__content-image {
|
|
@@ -67,13 +64,14 @@
|
|
|
67
64
|
min-width: 0;
|
|
68
65
|
height: auto;
|
|
69
66
|
min-height: a.rem(440);
|
|
67
|
+
padding-top: var(--e-space-6);
|
|
70
68
|
padding-left: var(--e-space-5);
|
|
71
69
|
padding-right: var(--e-space-5);
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
|
|
75
73
|
.dialog__header-image-container {
|
|
76
|
-
display:
|
|
74
|
+
display: flex;
|
|
77
75
|
justify-content: center;
|
|
78
76
|
height: a.rem(184);
|
|
79
77
|
margin-bottom: var(--e-space-8);
|
|
@@ -105,8 +103,6 @@
|
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
.dialog__content-image {
|
|
108
|
-
display: none;
|
|
109
|
-
|
|
110
106
|
img {
|
|
111
107
|
width: 100%;
|
|
112
108
|
}
|
|
@@ -116,10 +112,10 @@
|
|
|
116
112
|
position: sticky;
|
|
117
113
|
display: flex;
|
|
118
114
|
flex-direction: column;
|
|
119
|
-
|
|
115
|
+
gap: var(--e-space-4) var(--e-space-3);
|
|
120
116
|
bottom: 0;
|
|
121
117
|
margin-top: var(--overflow-gradient-height);
|
|
122
|
-
padding: var(--e-space-8) var(--e-space-1) var(--e-space-
|
|
118
|
+
padding: var(--e-space-8) var(--e-space-1) var(--e-space-8);
|
|
123
119
|
background-color: var(--e-c-mono-00);
|
|
124
120
|
|
|
125
121
|
&::after {
|
|
@@ -132,13 +128,22 @@
|
|
|
132
128
|
background-image: linear-gradient(0deg, rgb(255 255 255 / 100%) 0%, rgb(255 255 255 / 0%) 100%);
|
|
133
129
|
}
|
|
134
130
|
|
|
131
|
+
&.cta-inline {
|
|
132
|
+
display: grid;
|
|
133
|
+
grid-template-columns: 1fr 1fr;
|
|
134
|
+
}
|
|
135
|
+
|
|
135
136
|
@include a.bp(m) {
|
|
136
|
-
padding: var(--e-space-8) 0 var(--e-space-
|
|
137
|
+
padding: var(--e-space-8) 0 var(--e-space-6);
|
|
138
|
+
|
|
139
|
+
&.cta-inline {
|
|
140
|
+
display: flex;
|
|
141
|
+
}
|
|
137
142
|
}
|
|
138
143
|
}
|
|
139
144
|
|
|
140
145
|
// MOBILE "MODAL" Variant
|
|
141
|
-
.dialog-container.modal {
|
|
146
|
+
.dialog-container.variant-modal {
|
|
142
147
|
@include a.bp(m) {
|
|
143
148
|
padding-left: a.rem(a.$container-edge-m);
|
|
144
149
|
padding-right: a.rem(a.$container-edge-m);
|
|
@@ -151,7 +156,7 @@
|
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
// MOBILE "SLIDE-OUT" Variant
|
|
154
|
-
.dialog-container.slideout {
|
|
159
|
+
.dialog-container.variant-slideout {
|
|
155
160
|
@include a.bp(m) {
|
|
156
161
|
align-items: flex-end;
|
|
157
162
|
|
|
@@ -11,9 +11,10 @@ interface Props {
|
|
|
11
11
|
headerImage?: Image
|
|
12
12
|
contentImage?: Image
|
|
13
13
|
closeBtnLabel?: string
|
|
14
|
-
autoHeight?: boolean
|
|
15
14
|
modal?: boolean
|
|
16
15
|
mobileDialogStyle?: 'modal' | 'slideout'
|
|
16
|
+
ctaInline?: boolean
|
|
17
|
+
fitHeight?: boolean
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
const {
|
|
@@ -24,6 +25,8 @@ const {
|
|
|
24
25
|
contentImage = undefined,
|
|
25
26
|
mobileDialogStyle = 'modal',
|
|
26
27
|
closeBtnLabel = getTranslation('close'),
|
|
28
|
+
ctaInline = false,
|
|
29
|
+
fitHeight = false,
|
|
27
30
|
} = defineProps<Props>()
|
|
28
31
|
|
|
29
32
|
const visible = defineModel<boolean>('visible')
|
|
@@ -84,18 +87,11 @@ watch(visible, (newV) => {
|
|
|
84
87
|
<dialog
|
|
85
88
|
ref="dialog"
|
|
86
89
|
closedby="none"
|
|
87
|
-
:class="[
|
|
88
|
-
'dialog-container',
|
|
89
|
-
mobileDialogStyle,
|
|
90
|
-
{
|
|
91
|
-
'has-header-image': !!slots['header-image'] || (headerImage?.src && headerImage?.alt),
|
|
92
|
-
'has-content-image': !!slots['content-image'] || contentImage,
|
|
93
|
-
},
|
|
94
|
-
]"
|
|
90
|
+
:class="['dialog-container', `variant-${mobileDialogStyle}`]"
|
|
95
91
|
>
|
|
96
|
-
<div :class="['dialog', { '
|
|
97
|
-
<div class="dialog__header-image-container">
|
|
98
|
-
<slot name="
|
|
92
|
+
<div :class="['dialog', { 'fit-height': fitHeight }]">
|
|
93
|
+
<div v-if="!!slots.headerImage || headerImage" class="dialog__header-image-container">
|
|
94
|
+
<slot name="headerImage">
|
|
99
95
|
<img v-bind="headerImage" />
|
|
100
96
|
</slot>
|
|
101
97
|
</div>
|
|
@@ -119,16 +115,17 @@ watch(visible, (newV) => {
|
|
|
119
115
|
<slot name="custom"></slot>
|
|
120
116
|
</div>
|
|
121
117
|
|
|
122
|
-
<div class="dialog__content-image">
|
|
123
|
-
<slot name="
|
|
118
|
+
<div v-if="!!slots.contentImage || contentImage" class="dialog__content-image">
|
|
119
|
+
<slot name="contentImage">
|
|
124
120
|
<img v-bind="contentImage" />
|
|
125
121
|
</slot>
|
|
126
122
|
</div>
|
|
127
123
|
</div>
|
|
128
124
|
|
|
129
|
-
<div class="cta-container">
|
|
130
|
-
<slot name="cta"
|
|
131
|
-
|
|
125
|
+
<div :class="['cta-container', { 'cta-inline': ctaInline }]">
|
|
126
|
+
<slot name="cta">
|
|
127
|
+
<UButton @click="visible = false">{{ closeBtnLabel || getTranslation('close') }}</UButton>
|
|
128
|
+
</slot>
|
|
132
129
|
</div>
|
|
133
130
|
</div>
|
|
134
131
|
</dialog>
|
|
@@ -48,13 +48,8 @@ const onMousemove = (e) => {
|
|
|
48
48
|
</script>
|
|
49
49
|
|
|
50
50
|
<template>
|
|
51
|
-
<div class="login-animation">
|
|
52
|
-
<div
|
|
53
|
-
ref="container"
|
|
54
|
-
class="login-animation__image"
|
|
55
|
-
@mousemove="onMousemove"
|
|
56
|
-
@mouseleave="onMouseleave"
|
|
57
|
-
>
|
|
51
|
+
<div ref="container" class="login-animation" @mousemove="onMousemove" @mouseleave="onMouseleave">
|
|
52
|
+
<div class="login-animation__image">
|
|
58
53
|
<div ref="butterflyWrapper" :class="['login-animation__sprite', { flip: !mouseRightSide }]">
|
|
59
54
|
<USpriteAnimation
|
|
60
55
|
ref="butterfly"
|
|
@@ -23,24 +23,38 @@ interface Props {
|
|
|
23
23
|
|
|
24
24
|
defineProps<Props>()
|
|
25
25
|
|
|
26
|
+
const model = defineModel<boolean>({ default: false })
|
|
27
|
+
|
|
26
28
|
const mobilePanelEl = useTemplateRef('mobile-panel')
|
|
27
29
|
const mobileOpen = ref(false)
|
|
28
30
|
const isMobilePanelOpening = ref(false)
|
|
29
31
|
const isMobilePanelClosing = ref(false)
|
|
30
32
|
|
|
31
|
-
const
|
|
33
|
+
const openPanel = () => {
|
|
32
34
|
mobilePanelEl.value?.addEventListener('transitionend', onMobilePanelTransitionEnd)
|
|
33
35
|
|
|
34
36
|
document.documentElement.classList.toggle('navigation-toolbar-mobile-open', true)
|
|
35
37
|
isMobilePanelOpening.value = true
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
const
|
|
40
|
+
const closePanel = () => {
|
|
39
41
|
mobilePanelEl.value?.addEventListener('transitionend', onMobilePanelTransitionEnd)
|
|
40
42
|
|
|
41
43
|
isMobilePanelClosing.value = true
|
|
42
44
|
}
|
|
43
45
|
|
|
46
|
+
const onToggleMenu = () => {
|
|
47
|
+
openPanel()
|
|
48
|
+
|
|
49
|
+
model.value = true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const onNavClose = () => {
|
|
53
|
+
closePanel()
|
|
54
|
+
|
|
55
|
+
model.value = false
|
|
56
|
+
}
|
|
57
|
+
|
|
44
58
|
const onMobilePanelTransitionEnd = (e) => {
|
|
45
59
|
if (e.target !== mobilePanelEl.value) {
|
|
46
60
|
return
|
|
@@ -58,6 +72,14 @@ const onMobilePanelTransitionEnd = (e) => {
|
|
|
58
72
|
watch(mobileOpen, (newV) => {
|
|
59
73
|
document.documentElement.classList.toggle('navigation-toolbar-mobile-open', newV)
|
|
60
74
|
})
|
|
75
|
+
|
|
76
|
+
watch(model, (newV) => {
|
|
77
|
+
if (newV === true) {
|
|
78
|
+
openPanel()
|
|
79
|
+
} else {
|
|
80
|
+
closePanel()
|
|
81
|
+
}
|
|
82
|
+
})
|
|
61
83
|
</script>
|
|
62
84
|
|
|
63
85
|
<template>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@energie360/ui-library",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,20 +24,20 @@
|
|
|
24
24
|
"author": "",
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"devDependencies": {
|
|
27
|
+
"@lottiefiles/dotlottie-web": "^0.60.0",
|
|
27
28
|
"@tsconfig/node22": "^22.0.5",
|
|
28
|
-
"@types/node": "^
|
|
29
|
-
"@vue/tsconfig": "^0.
|
|
30
|
-
"autoprefixer": "^10.4.
|
|
31
|
-
"chokidar": "^
|
|
29
|
+
"@types/node": "^25.0.3",
|
|
30
|
+
"@vue/tsconfig": "^0.8.1",
|
|
31
|
+
"autoprefixer": "^10.4.23",
|
|
32
|
+
"chokidar": "^5.0.0",
|
|
32
33
|
"postcss": "^8.5.6",
|
|
33
|
-
"sass": "^1.
|
|
34
|
+
"sass": "^1.97.1",
|
|
34
35
|
"typescript": "^5.9.3"
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
|
-
"@lottiefiles/dotlottie-vue": "^0.10.
|
|
38
|
-
"@lottiefiles/dotlottie-web": "^0.58.1",
|
|
38
|
+
"@lottiefiles/dotlottie-vue": "^0.10.12",
|
|
39
39
|
"@lottiefiles/lottie-player": "^2.0.12",
|
|
40
|
-
"gsap": "^3.14.
|
|
40
|
+
"gsap": "^3.14.2",
|
|
41
41
|
"@energie360/design-tokens": "^1.3.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create query parameter for an url with an object or an array
|
|
3
|
+
* INFO: Use an array as parameter if you have multiple values for a key
|
|
4
|
+
*
|
|
5
|
+
* @param url {string} - url to append the query parameters
|
|
6
|
+
* @param params {(object | Array)} - object with key, value as query parameter
|
|
7
|
+
* e.q object => random/testing, data = {'test': 1, 'hello': 'world'} => random/testing?test=1&hello=world
|
|
8
|
+
* e.q array => random/testing, data = [['test', 2], ['hello', 'earth']] => random/testing?test=2&hello=earth
|
|
9
|
+
*
|
|
10
|
+
* @returns {string}
|
|
11
|
+
*/
|
|
12
|
+
export function addQueryParameter(url, params) {
|
|
13
|
+
const queryParams = []
|
|
14
|
+
|
|
15
|
+
if (Array.isArray(params)) {
|
|
16
|
+
queryParams.push(params.map((param) => param.map(encodeURIComponent)))
|
|
17
|
+
} else {
|
|
18
|
+
queryParams.push(Object.keys(params).map((key) => [key, params[key]].map(encodeURIComponent)))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const queryString = queryParams.map((param) =>
|
|
22
|
+
param.map((keyValue) => keyValue.join('=')).join('&'),
|
|
23
|
+
)
|
|
24
|
+
return `${url}?${queryString}`
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// From https://github.com/vuejs/core/issues/4733
|
|
2
|
+
|
|
3
|
+
import { Comment, Text, Fragment, type Slot, type VNode } from 'vue'
|
|
4
|
+
|
|
5
|
+
export function hasSlotContent(slot: Slot | undefined | null, props: any = {}) {
|
|
6
|
+
return !isSlotEmpty(slot, props)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function isSlotEmpty(slot: Slot | undefined | null, props: any = {}) {
|
|
10
|
+
return isVNodeEmpty(slot?.(props))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function isVNodeEmpty(vnode: VNode | VNode[] | undefined | null) {
|
|
14
|
+
return (
|
|
15
|
+
!vnode ||
|
|
16
|
+
asArray(vnode).every(
|
|
17
|
+
(vnode) =>
|
|
18
|
+
vnode.type === Comment ||
|
|
19
|
+
(vnode.type === Text && !vnode.children?.length) ||
|
|
20
|
+
(vnode.type === Fragment && !vnode.children?.length),
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function asArray<T>(arg: T | T[] | null) {
|
|
26
|
+
return Array.isArray(arg) ? arg : arg !== null ? [arg] : []
|
|
27
|
+
}
|
|
@@ -7,13 +7,16 @@ interface Props {
|
|
|
7
7
|
title?: string
|
|
8
8
|
text?: string
|
|
9
9
|
image?: Image
|
|
10
|
+
|
|
10
11
|
cta?: Cta
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
const { text = '', image = undefined, cta = undefined, title = '' } = defineProps<Props>()
|
|
14
15
|
|
|
15
16
|
const slots = useSlots()
|
|
17
|
+
|
|
16
18
|
const hasCta = computed(() => !!slots.cta || cta)
|
|
19
|
+
|
|
17
20
|
const hasText = computed(() => !!slots.text || text)
|
|
18
21
|
</script>
|
|
19
22
|
|