@energie360/ui-library 0.1.26 → 0.1.27
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/index.js +2 -0
- package/components/notification-item/notification-item.scss +115 -0
- package/components/notification-item/u-notification-item.vue +46 -0
- package/components/notification-list/notification-list.scss +37 -0
- package/components/notification-list/u-notification-list.vue +51 -0
- package/i18n/i18n.ts +4 -0
- package/layout/index.js +1 -0
- package/layout/portal-block/portal-block.scss +8 -0
- package/layout/portal-block/u-portal-block.vue +16 -0
- package/layout/portal-main/portal-main.scss +1 -0
- package/modules/navigation-toolbar-side/navigation-toolbar-side.scss +42 -11
- package/modules/navigation-toolbar-side/u-navigation-toolbar-side.vue +10 -7
- package/package.json +5 -5
package/components/index.js
CHANGED
|
@@ -68,3 +68,5 @@ export { default as USlider } from './slider/u-slider.vue'
|
|
|
68
68
|
export { default as USpriteAnimation } from './sprite-animation/u-sprite-animation.vue'
|
|
69
69
|
export { default as USliderProgressAnimation } from './slider-progress-animation/u-slider-progress-animation.vue'
|
|
70
70
|
export { default as UStickyCta } from './sticky-cta/u-sticky-cta.vue'
|
|
71
|
+
export { default as UNotificationItem } from './notification-item/u-notification-item.vue'
|
|
72
|
+
export { default as UNotificationList } from './notification-list/u-notification-list.vue'
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
@use '../../base/abstracts' as a;
|
|
2
|
+
|
|
3
|
+
.notification-item {
|
|
4
|
+
z-index: 1;
|
|
5
|
+
position: relative;
|
|
6
|
+
container-type: inline-size;
|
|
7
|
+
margin-bottom: -1px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Unread state
|
|
11
|
+
.notification-item__inner {
|
|
12
|
+
padding: var(--e-space-4);
|
|
13
|
+
border-top: 1px solid var(--e-c-secondary-05-100);
|
|
14
|
+
border-bottom: 1px solid var(--e-c-secondary-05-100);
|
|
15
|
+
background-color: var(--e-c-secondary-05-50);
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
transition: background-color a.$trs-default;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
|
|
21
|
+
&:hover {
|
|
22
|
+
background-color: var(--e-c-secondary-05-100);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
&:active {
|
|
26
|
+
background-color: var(--e-c-secondary-05-200);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@container (width < 740px) {
|
|
30
|
+
flex-wrap: wrap;
|
|
31
|
+
border-radius: var(--e-brd-radius-2);
|
|
32
|
+
border: 1px solid var(--e-c-secondary-05-100);
|
|
33
|
+
row-gap: var(--e-space-2);
|
|
34
|
+
|
|
35
|
+
.notification-item__text {
|
|
36
|
+
order: 1;
|
|
37
|
+
flex: 0 0 100%;
|
|
38
|
+
padding: 0;
|
|
39
|
+
margin-right: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.notification-item__dot {
|
|
43
|
+
order: 2;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.notification-item__when {
|
|
47
|
+
padding: 3px 0;
|
|
48
|
+
order: 3;
|
|
49
|
+
margin-left: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.notification-item__remove {
|
|
53
|
+
order: 4;
|
|
54
|
+
margin-left: auto;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Read state
|
|
60
|
+
.notification-item.read {
|
|
61
|
+
z-index: 0;
|
|
62
|
+
|
|
63
|
+
.notification-item__inner {
|
|
64
|
+
background-color: var(--e-c-mono-00);
|
|
65
|
+
border-color: var(--e-c-mono-100);
|
|
66
|
+
|
|
67
|
+
&:hover {
|
|
68
|
+
background-color: var(--e-c-primary-01-50);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&:active {
|
|
72
|
+
background-color: var(--e-c-primary-01-100);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.notification-item__text {
|
|
78
|
+
@include a.type(100);
|
|
79
|
+
|
|
80
|
+
margin-right: var(--e-space-2);
|
|
81
|
+
min-height: 24px;
|
|
82
|
+
padding: 1px 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.notification-item__dot {
|
|
86
|
+
display: block;
|
|
87
|
+
width: 8px;
|
|
88
|
+
height: 8px;
|
|
89
|
+
border-radius: 100%;
|
|
90
|
+
margin-right: var(--e-space-2);
|
|
91
|
+
background-color: var(--e-c-secondary-05-500);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.notification-item__when {
|
|
95
|
+
@include a.type(50);
|
|
96
|
+
|
|
97
|
+
white-space: nowrap;
|
|
98
|
+
color: var(--e-c-mono-700);
|
|
99
|
+
margin-left: auto;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.notification-item__remove {
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
z-index: 1;
|
|
105
|
+
color: var(--e-c-primary-01-700);
|
|
106
|
+
margin-left: var(--e-space-6);
|
|
107
|
+
|
|
108
|
+
&:hover {
|
|
109
|
+
color: var(--e-c-secondary-01-900);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.visually-hidden {
|
|
114
|
+
@include a.visually-hidden;
|
|
115
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { UIcon } from '../../elements'
|
|
3
|
+
import { getTranslation } from '../../utils/translations/translate'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
read: boolean
|
|
7
|
+
when: string
|
|
8
|
+
text?: string
|
|
9
|
+
removable: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
defineProps<Props>()
|
|
13
|
+
const emits = defineEmits(['remove'])
|
|
14
|
+
|
|
15
|
+
const onRemove = () => {
|
|
16
|
+
emits('remove')
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<div :class="['notification-item', { read, removable }]">
|
|
22
|
+
<div class="notification-item__inner">
|
|
23
|
+
<div v-if="!read" class="notification-item__dot"></div>
|
|
24
|
+
|
|
25
|
+
<div class="notification-item__text">
|
|
26
|
+
<slot><div v-html="text" /></slot>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="notification-item__when">
|
|
30
|
+
{{ when }}
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div
|
|
34
|
+
v-if="removable"
|
|
35
|
+
class="notification-item__remove"
|
|
36
|
+
role="button"
|
|
37
|
+
@click.prevent.stop="onRemove"
|
|
38
|
+
>
|
|
39
|
+
<span class="visually-hidden">{{ getTranslation('removeNotification') }}</span>
|
|
40
|
+
<UIcon name="delete" />
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<style lang="scss" scoped src="./notification-item.scss"></style>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
@use '../../base/abstracts' as a;
|
|
2
|
+
|
|
3
|
+
.notification-list {
|
|
4
|
+
container-type: inline-size;
|
|
5
|
+
|
|
6
|
+
&.is-empty {
|
|
7
|
+
// This vertical centered style only works in the portal-main layout.
|
|
8
|
+
// It's not really possible to do this "correctly" at the moment, because `portal-main__content` is `display: block`.
|
|
9
|
+
// With `display: flex` it would work, but this would need some refactoring.
|
|
10
|
+
position: relative;
|
|
11
|
+
top: 50%;
|
|
12
|
+
transform: translateY(-100%);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.notification-list__inner {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
|
|
20
|
+
@container (width < 740px) {
|
|
21
|
+
gap: var(--e-space-3);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.notification-list__empty-wrapper {
|
|
26
|
+
text-align: center;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.notification-list__empty_animation {
|
|
30
|
+
width: 120px;
|
|
31
|
+
height: 120px;
|
|
32
|
+
margin: 0 auto var(--e-space-6);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.notification-list__empty-text {
|
|
36
|
+
@include a.type(300, strong);
|
|
37
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
|
3
|
+
import { ref, onMounted, useTemplateRef } from 'vue'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
emptyText: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
defineProps<Props>()
|
|
10
|
+
|
|
11
|
+
const innerEl = useTemplateRef('inner')
|
|
12
|
+
const isEmpty = ref(false)
|
|
13
|
+
const checkItems = () => {
|
|
14
|
+
const itemCount = innerEl.value.children.length
|
|
15
|
+
|
|
16
|
+
isEmpty.value = itemCount === 0
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
onMounted(() => {
|
|
20
|
+
checkItems()
|
|
21
|
+
|
|
22
|
+
const observer = new window.MutationObserver(() => {
|
|
23
|
+
checkItems()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
observer.observe(innerEl.value, { childList: true, subtree: true })
|
|
27
|
+
})
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<template>
|
|
31
|
+
<div :class="['notification-list', { 'is-empty': isEmpty }]">
|
|
32
|
+
<div ref="inner" class="notification-list__inner">
|
|
33
|
+
<slot />
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div v-if="isEmpty" class="notification-list__empty-wrapper">
|
|
37
|
+
<div class="notification-list__empty_animation">
|
|
38
|
+
<DotLottieVue
|
|
39
|
+
autoplay
|
|
40
|
+
loop
|
|
41
|
+
src="/static/ui-assets/lottie/notification-empty.lottie"
|
|
42
|
+
style="height: 100%; width: 100%"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<p class="notification-list__empty-text">{{ emptyText }}</p>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<style lang="scss" scoped src="./notification-list.scss"></style>
|
package/i18n/i18n.ts
CHANGED
|
@@ -23,6 +23,7 @@ const translations = {
|
|
|
23
23
|
download: 'Herunterladen',
|
|
24
24
|
like: 'Gefällt mir',
|
|
25
25
|
dislike: 'Gefällt mir nicht',
|
|
26
|
+
removeNotification: 'Benachrichtigung entfernen',
|
|
26
27
|
},
|
|
27
28
|
FR: {
|
|
28
29
|
yes: 'Ja',
|
|
@@ -48,6 +49,7 @@ const translations = {
|
|
|
48
49
|
download: 'Télécharger',
|
|
49
50
|
like: "J'aime ça",
|
|
50
51
|
dislike: "je ne l'aime pas",
|
|
52
|
+
removeNotification: 'supprimer la notification',
|
|
51
53
|
},
|
|
52
54
|
IT: {
|
|
53
55
|
yes: 'Ja',
|
|
@@ -73,6 +75,7 @@ const translations = {
|
|
|
73
75
|
download: 'scaricamento',
|
|
74
76
|
like: 'Mi piace',
|
|
75
77
|
dislike: 'Non mi piace',
|
|
78
|
+
removeNotification: 'rimuovere la notifica',
|
|
76
79
|
},
|
|
77
80
|
EN: {
|
|
78
81
|
yes: 'Ja',
|
|
@@ -98,6 +101,7 @@ const translations = {
|
|
|
98
101
|
download: 'Download',
|
|
99
102
|
like: 'I like it',
|
|
100
103
|
dislike: 'I do not like it',
|
|
104
|
+
removeNotification: 'remove notification',
|
|
101
105
|
},
|
|
102
106
|
}
|
|
103
107
|
|
package/layout/index.js
CHANGED
|
@@ -4,3 +4,4 @@ export { default as UPortalContentAside } from './portal-content-aside/u-portal-
|
|
|
4
4
|
export { default as UTileGrid } from './tile-grid/u-tile-grid.vue'
|
|
5
5
|
export { default as UTileItem } from './tile-grid/u-tile-item.vue'
|
|
6
6
|
export { default as UResponsiveContainer } from './responsive-container/u-responsive-container.vue'
|
|
7
|
+
export { default as UPortalBlock } from './portal-block/u-portal-block.vue'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
interface Props {
|
|
3
|
+
big?: boolean
|
|
4
|
+
space?: 'small' | 'big'
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const { space = 'small' } = defineProps<Props>()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div :class="['portal-block', space]">
|
|
12
|
+
<slot />
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<style scoped lang="scss" src="./portal-block.scss"></style>
|
|
@@ -15,7 +15,13 @@
|
|
|
15
15
|
width: a.rem(88);
|
|
16
16
|
|
|
17
17
|
.navigation-toolbar-side__logo {
|
|
18
|
-
|
|
18
|
+
.mini {
|
|
19
|
+
opacity: 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.large {
|
|
23
|
+
opacity: 0;
|
|
24
|
+
}
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
.navigation-toolbar-side__nav-links,
|
|
@@ -29,6 +35,11 @@
|
|
|
29
35
|
width: a.rem(196);
|
|
30
36
|
height: a.rem(40);
|
|
31
37
|
margin-bottom: var(--e-space-12);
|
|
38
|
+
|
|
39
|
+
.mini {
|
|
40
|
+
position: absolute;
|
|
41
|
+
opacity: 0;
|
|
42
|
+
}
|
|
32
43
|
}
|
|
33
44
|
|
|
34
45
|
.navigation-toolbar-side__nav-links {
|
|
@@ -49,12 +60,6 @@
|
|
|
49
60
|
width: 100%;
|
|
50
61
|
}
|
|
51
62
|
|
|
52
|
-
.navigation-toolbar-side__top-bar-logo {
|
|
53
|
-
img {
|
|
54
|
-
height: a.rem(24);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
63
|
.navigation-toolbar-side__top-bar-ctas {
|
|
59
64
|
display: flex;
|
|
60
65
|
column-gap: var(--e-space-4);
|
|
@@ -62,28 +67,54 @@
|
|
|
62
67
|
|
|
63
68
|
// Animation
|
|
64
69
|
.navigation-toolbar-side {
|
|
70
|
+
--duration: var(--e-trs-duration-faster);
|
|
71
|
+
|
|
65
72
|
&.is-collapsing {
|
|
66
73
|
will-change: width;
|
|
67
|
-
transition: width var(--
|
|
74
|
+
transition: width var(--duration) var(--transition-ease-out);
|
|
68
75
|
width: a.rem(88);
|
|
69
76
|
overflow: hidden;
|
|
70
77
|
|
|
71
78
|
.navigation-toolbar-side__nav-links,
|
|
72
79
|
.navigation-toolbar-side__menu-ctas {
|
|
73
|
-
transition: padding var(--
|
|
80
|
+
transition: padding var(--duration) var(--transition-ease-out);
|
|
74
81
|
padding: 0 var(--e-space-0_5);
|
|
75
82
|
}
|
|
83
|
+
|
|
84
|
+
.navigation-toolbar-side__logo {
|
|
85
|
+
.mini {
|
|
86
|
+
opacity: 1;
|
|
87
|
+
transition: opacity var(--duration) var(--transition-ease-out);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.large {
|
|
91
|
+
opacity: 0;
|
|
92
|
+
transition: opacity var(--duration) var(--transition-ease-out);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
76
95
|
}
|
|
77
96
|
|
|
78
97
|
&.is-expanding {
|
|
79
98
|
will-change: width;
|
|
80
|
-
transition: all var(--
|
|
99
|
+
transition: all var(--duration) var(--transition-ease-out);
|
|
81
100
|
width: var(--nav-width-expanded);
|
|
82
101
|
|
|
83
102
|
.navigation-toolbar-side__nav-links,
|
|
84
103
|
.navigation-toolbar-side__menu-ctas {
|
|
85
|
-
transition: padding var(--
|
|
104
|
+
transition: padding var(--duration) var(--transition-ease-out);
|
|
86
105
|
padding: 0;
|
|
87
106
|
}
|
|
107
|
+
|
|
108
|
+
.navigation-toolbar-side__logo {
|
|
109
|
+
.mini {
|
|
110
|
+
opacity: 0;
|
|
111
|
+
transition: opacity var(--duration) var(--transition-ease-out);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.large {
|
|
115
|
+
opacity: 1;
|
|
116
|
+
transition: opacity var(--duration) var(--transition-ease-out);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
88
119
|
}
|
|
89
120
|
}
|
|
@@ -61,13 +61,16 @@ watch(
|
|
|
61
61
|
},
|
|
62
62
|
]"
|
|
63
63
|
>
|
|
64
|
-
<a
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
<a
|
|
65
|
+
:class="[
|
|
66
|
+
'navigation-toolbar-side__logo',
|
|
67
|
+
{ 'is-collapsing': isCollapsing, 'is-expanding': isExpanding },
|
|
68
|
+
]"
|
|
69
|
+
:href="logoLink.href"
|
|
70
|
+
:target="logoLink.target"
|
|
71
|
+
>
|
|
72
|
+
<img class="mini" :src="logoMinifiedImage.src" :alt="logoMinifiedImage.alt" />
|
|
73
|
+
<img class="large" :src="logoImage.src" :alt="logoImage.alt" />
|
|
71
74
|
</a>
|
|
72
75
|
|
|
73
76
|
<nav ref="mobile-panel" class="navigation-toolbar-side__nav-panel">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@energie360/ui-library",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,17 +25,17 @@
|
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@tsconfig/node22": "^22.0.2",
|
|
28
|
-
"@types/node": "^22.
|
|
28
|
+
"@types/node": "^22.19.0",
|
|
29
29
|
"@vue/tsconfig": "^0.7.0",
|
|
30
|
-
"autoprefixer": "^10.4.
|
|
30
|
+
"autoprefixer": "^10.4.22",
|
|
31
31
|
"chokidar": "^4.0.3",
|
|
32
32
|
"postcss": "^8.5.6",
|
|
33
|
-
"sass": "^1.
|
|
33
|
+
"sass": "^1.94.0",
|
|
34
34
|
"typescript": "^5.9.3"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"@lottiefiles/dotlottie-vue": "^0.10.7",
|
|
37
38
|
"@lottiefiles/lottie-player": "^2.0.12",
|
|
38
|
-
"swiper": "^11.2.10",
|
|
39
39
|
"@energie360/design-tokens": "^1.3.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|