@energie360/ui-library 0.1.9 → 0.1.10
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/base/abstracts/_variables.scss +1 -0
- package/components/context-menu/context-menu.scss +28 -0
- package/components/context-menu/u-context-menu.vue +113 -0
- package/components/context-menu-divider/context-menu-divider.scss +6 -0
- package/components/context-menu-divider/u-context-menu-divider.vue +5 -0
- package/components/context-menu-link/context-menu-link.scss +26 -0
- package/components/context-menu-link/u-context-menu-link.vue +27 -0
- package/components/index.js +5 -0
- package/components/navigation-toolbar-link/navigation-toolbar-link.scss +177 -0
- package/components/navigation-toolbar-link/u-navigation-toolbar-link.vue +108 -0
- package/components/text-block/text-block.scss +58 -0
- package/components/text-block/u-text-block.vue +26 -0
- package/components/tooltip/popover.ts +74 -12
- package/dist/base-style.css +1 -0
- package/dist/base-style.css.map +1 -1
- package/dist/elements/text-link.css +1 -0
- package/dist/elements/text-link.css.map +1 -1
- package/dist/layout/split.css +1 -0
- package/dist/layout/split.css.map +1 -1
- package/elements/button-chip/button-chip.scss +2 -2
- package/elements/text-field/u-text-field.vue +9 -1
- package/i18n/i18n.ts +8 -0
- package/modules/index.js +2 -0
- package/modules/navigation-toolbar-side/navigation-toolbar-side.scss +89 -0
- package/modules/navigation-toolbar-side/u-navigation-toolbar-side.vue +93 -0
- package/modules/navigation-toolbar-top/navigation-toolbar-top.scss +89 -0
- package/modules/navigation-toolbar-top/u-navigation-toolbar-top.vue +130 -0
- package/package.json +2 -2
- package/utils/a11y/focus-trap.js +128 -0
|
@@ -35,6 +35,7 @@ $grid-gutter-s: math.div(dt.$space-5, $container-inner-s) * 100%;
|
|
|
35
35
|
|
|
36
36
|
// Transition
|
|
37
37
|
$trs-default: var(--e-trs-duration-faster) var(--e-trs-easing-default);
|
|
38
|
+
$trs-ease-out: var(--e-trs-duration-faster) cubic-bezier(0.215, 0.61, 0.355, 1); /* easeOutCubic */
|
|
38
39
|
|
|
39
40
|
// CMS-Section
|
|
40
41
|
$section-default-padding-2xl: dt.$space-28;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
@use '../../base/abstracts/' as a;
|
|
2
|
+
|
|
3
|
+
// .context-menu {
|
|
4
|
+
// // position: relative;
|
|
5
|
+
// }
|
|
6
|
+
|
|
7
|
+
.context-menu__menu {
|
|
8
|
+
position: absolute;
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
row-gap: var(--e-space-2);
|
|
12
|
+
padding: var(--e-space-2);
|
|
13
|
+
border-radius: var(--e-brd-radius-2);
|
|
14
|
+
border: 1px solid var(--e-c-mono-200);
|
|
15
|
+
box-shadow: var(--e-elevation-md);
|
|
16
|
+
background-color: var(--e-c-mono-00);
|
|
17
|
+
min-width: a.rem(240);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.menu-enter-active,
|
|
21
|
+
.menu-leave-active {
|
|
22
|
+
transition: opacity a.$trs-default;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.menu-enter-from,
|
|
26
|
+
.menu-leave-to {
|
|
27
|
+
opacity: 0;
|
|
28
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref, useTemplateRef, watch } from 'vue'
|
|
3
|
+
import { PopoverPositionParams, getPopoverPosition } from '../tooltip/popover'
|
|
4
|
+
import { debounceRaf } from '../../utils/functions/debounce'
|
|
5
|
+
import { focusTrap } from '../../utils/a11y/focus-trap'
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
placement = 'top-center',
|
|
9
|
+
offset = 8,
|
|
10
|
+
viewportPadding = 20,
|
|
11
|
+
} = defineProps<PopoverPositionParams>()
|
|
12
|
+
|
|
13
|
+
// TODO: Key codes should be defined globally
|
|
14
|
+
const ESC = 'Escape'
|
|
15
|
+
|
|
16
|
+
const triggerEl = useTemplateRef('trigger')
|
|
17
|
+
const menuEl = useTemplateRef('menu')
|
|
18
|
+
const isOpen = ref(false)
|
|
19
|
+
let focusTrapInstance
|
|
20
|
+
|
|
21
|
+
const onToggleMenu = (e: Event) => {
|
|
22
|
+
e.stopPropagation()
|
|
23
|
+
e.preventDefault()
|
|
24
|
+
|
|
25
|
+
isOpen.value = !isOpen.value
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const onResize = () => {
|
|
29
|
+
// Clear right position value, so we can get actual width of popover.
|
|
30
|
+
menuEl.value!.style.right = ''
|
|
31
|
+
|
|
32
|
+
const popoverPosition = getPopoverPosition(
|
|
33
|
+
triggerEl.value as HTMLElement,
|
|
34
|
+
menuEl.value as HTMLElement,
|
|
35
|
+
{
|
|
36
|
+
placement,
|
|
37
|
+
offset,
|
|
38
|
+
viewportPadding,
|
|
39
|
+
},
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
menuEl.value!.style.top = `${popoverPosition.top}px`
|
|
43
|
+
menuEl.value!.style.left = `${popoverPosition.left}px`
|
|
44
|
+
if (popoverPosition.right) {
|
|
45
|
+
menuEl.value!.style.right = `${popoverPosition.right}px`
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const onResizeDebounced = debounceRaf(onResize)
|
|
50
|
+
|
|
51
|
+
const onEnter = () => {
|
|
52
|
+
// 1. Position context-menu
|
|
53
|
+
onResize()
|
|
54
|
+
|
|
55
|
+
// 2. Set focus to first focusable element in menu
|
|
56
|
+
focusTrapInstance = focusTrap(menuEl.value, {
|
|
57
|
+
focusFirstElement: true,
|
|
58
|
+
allowArrowUpDown: true,
|
|
59
|
+
allowArrowLeftRight: true,
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// 3. Bind events
|
|
63
|
+
menuEl.value.addEventListener('keydown', onEsc)
|
|
64
|
+
document.addEventListener('click', onDocumentClick)
|
|
65
|
+
window.addEventListener('resize', onResizeDebounced)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const onAfterLeave = () => {
|
|
69
|
+
focusTrapInstance.release()
|
|
70
|
+
window.removeEventListener('resize', onResizeDebounced)
|
|
71
|
+
document.removeEventListener('click', onDocumentClick)
|
|
72
|
+
menuEl.value?.removeEventListener('keydown', onEsc)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const onEsc = (e) => {
|
|
76
|
+
if (e.code === ESC) {
|
|
77
|
+
isOpen.value = false
|
|
78
|
+
|
|
79
|
+
// Set focus back to the trigger element
|
|
80
|
+
triggerEl.value.focus()
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const onDocumentClick = (e: Event) => {
|
|
85
|
+
e.stopPropagation()
|
|
86
|
+
e.preventDefault()
|
|
87
|
+
|
|
88
|
+
// Close context menu when any click happens.
|
|
89
|
+
isOpen.value = false
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
watch([() => placement, () => offset, () => viewportPadding], () => {
|
|
93
|
+
if (isOpen.value) {
|
|
94
|
+
onResize()
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<template>
|
|
100
|
+
<div class="context-menu" :class="{ 'is-open': isOpen, 'is-closed': !isOpen }">
|
|
101
|
+
<div ref="trigger" class="context-menu__trigger" @click="onToggleMenu">
|
|
102
|
+
<slot name="trigger"></slot>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<Transition name="menu" @enter="onEnter" @after-leave="onAfterLeave">
|
|
106
|
+
<div v-if="isOpen" ref="menu" class="context-menu__menu">
|
|
107
|
+
<slot></slot>
|
|
108
|
+
</div>
|
|
109
|
+
</Transition>
|
|
110
|
+
</div>
|
|
111
|
+
</template>
|
|
112
|
+
|
|
113
|
+
<style lang="scss" scoped src="./context-menu.scss"></style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@use '../../base/abstracts/' as a;
|
|
2
|
+
|
|
3
|
+
.context-menu-link {
|
|
4
|
+
@include a.type(200, strong);
|
|
5
|
+
|
|
6
|
+
display: flex;
|
|
7
|
+
column-gap: var(--e-space-2);
|
|
8
|
+
padding: var(--e-space-1_5) var(--e-space-3);
|
|
9
|
+
color: var(--e-c-mono-700);
|
|
10
|
+
border-radius: var(--e-brd-radius-2);
|
|
11
|
+
text-wrap: nowrap;
|
|
12
|
+
transition:
|
|
13
|
+
background-color a.$trs-ease-out,
|
|
14
|
+
color a.$trs-ease-out;
|
|
15
|
+
|
|
16
|
+
&:hover,
|
|
17
|
+
&:active {
|
|
18
|
+
background-color: var(--e-c-primary-01-50);
|
|
19
|
+
color: var(--e-c-primary-01-700);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&.active {
|
|
23
|
+
background-color: var(--e-c-primary-01-100);
|
|
24
|
+
color: var(--e-c-primary-01-900);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { UIcon } from '../../elements'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
icon: string
|
|
7
|
+
label?: string
|
|
8
|
+
href?: string
|
|
9
|
+
target?: string
|
|
10
|
+
active?: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { href, active = false } = defineProps<Props>()
|
|
14
|
+
|
|
15
|
+
const tag = computed(() => {
|
|
16
|
+
return href ? 'a' : 'span'
|
|
17
|
+
})
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<component :is="tag" class="context-menu-link" :class="{ active }">
|
|
22
|
+
<UIcon :name="icon" />
|
|
23
|
+
<slot>{{ label }}</slot>
|
|
24
|
+
</component>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<style scoped lang="scss" src="./context-menu-link.scss"></style>
|
package/components/index.js
CHANGED
|
@@ -39,4 +39,9 @@ export { default as UTableRow } from './table/u-table-row.vue'
|
|
|
39
39
|
export { default as UTable } from './table/u-table.vue'
|
|
40
40
|
|
|
41
41
|
export { default as UTabs } from './tabs/u-tabs.vue'
|
|
42
|
+
export { default as UTextBlock } from './text-block/u-text-block.vue'
|
|
42
43
|
export { default as UTooltip } from './tooltip/u-tooltip.vue'
|
|
44
|
+
export { default as UNavigationToolbarLink } from './navigation-toolbar-link/u-navigation-toolbar-link.vue'
|
|
45
|
+
export { default as UContextMenu } from './context-menu/u-context-menu.vue'
|
|
46
|
+
export { default as UContextMenuLink } from './context-menu-link/u-context-menu-link.vue'
|
|
47
|
+
export { default as UContextMenuDivider } from './context-menu-divider/u-context-menu-divider.vue'
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// TODO: How to handle text overflow?
|
|
2
|
+
|
|
3
|
+
@use '../../base/abstracts/' as a;
|
|
4
|
+
|
|
5
|
+
@keyframes fadeInLabel {
|
|
6
|
+
0% {
|
|
7
|
+
opacity: 0;
|
|
8
|
+
transform: translateX(calc(100% + #{a.rem(8)}));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
100% {
|
|
12
|
+
opacity: 1;
|
|
13
|
+
transform: translateX(100%);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@keyframes fadeOutLabel {
|
|
18
|
+
0% {
|
|
19
|
+
opacity: 1;
|
|
20
|
+
transform: translateX(100%);
|
|
21
|
+
width: auto;
|
|
22
|
+
height: auto;
|
|
23
|
+
padding: var(--e-space-1_5) var(--e-space-2);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
100% {
|
|
27
|
+
opacity: 0;
|
|
28
|
+
transform: translateX(calc(100% + #{a.rem(8)}));
|
|
29
|
+
width: auto;
|
|
30
|
+
height: auto;
|
|
31
|
+
padding: var(--e-space-1_5) var(--e-space-2);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@keyframes collapse {
|
|
36
|
+
0% {
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
padding: var(--e-space-1_5) var(--e-space-3);
|
|
39
|
+
width: 100%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
100% {
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
padding: var(--e-space-1_5);
|
|
45
|
+
width: a.rem(36);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@keyframes expand {
|
|
50
|
+
0% {
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
padding: var(--e-space-1_5);
|
|
53
|
+
width: a.rem(36);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
100% {
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
padding: var(--e-space-1_5) var(--e-space-3);
|
|
59
|
+
width: 100%;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.navigation-toolbar-link {
|
|
64
|
+
--transition-ease-out: cubic-bezier(0.215, 0.61, 0.355, 1); /* easeOutCubic */
|
|
65
|
+
|
|
66
|
+
position: relative;
|
|
67
|
+
padding: var(--e-space-1_5) var(--e-space-3);
|
|
68
|
+
height: a.rem(36);
|
|
69
|
+
display: flex;
|
|
70
|
+
justify-content: flex-start;
|
|
71
|
+
align-items: center;
|
|
72
|
+
flex-wrap: nowrap;
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
width: 100%;
|
|
75
|
+
column-gap: var(--e-space-2);
|
|
76
|
+
background-color: var(--e-c-secondary-01-1000);
|
|
77
|
+
color: var(--e-c-mono-00);
|
|
78
|
+
border-radius: var(--e-brd-radius-2);
|
|
79
|
+
cursor: pointer;
|
|
80
|
+
transition:
|
|
81
|
+
background-color a.$trs-default,
|
|
82
|
+
color a.$trs-default;
|
|
83
|
+
|
|
84
|
+
@include a.type(200, strong);
|
|
85
|
+
|
|
86
|
+
> * {
|
|
87
|
+
flex: 0 0 auto;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&:active,
|
|
91
|
+
&:hover:not(.is-collapsing, .is-expanding) {
|
|
92
|
+
background-color: var(--e-c-secondary-01-950);
|
|
93
|
+
color: var(--e-c-primary-01-100);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Active Page
|
|
97
|
+
&.active {
|
|
98
|
+
background-color: var(--e-c-secondary-01-900);
|
|
99
|
+
color: var(--e-c-primary-01-50);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Collapsed
|
|
103
|
+
&.collapsed {
|
|
104
|
+
padding: var(--e-space-1_5);
|
|
105
|
+
width: a.rem(36);
|
|
106
|
+
|
|
107
|
+
.navigation-toolbar-link__label {
|
|
108
|
+
position: absolute;
|
|
109
|
+
top: 0;
|
|
110
|
+
right: calc(var(--e-space-2) * -1);
|
|
111
|
+
transform: translateX(calc(100% + #{a.rem(8)}));
|
|
112
|
+
border-radius: var(--e-brd-radius-2);
|
|
113
|
+
background-color: var(--e-c-mono-900);
|
|
114
|
+
color: var(--e-c-mono-00);
|
|
115
|
+
|
|
116
|
+
// Hide visually
|
|
117
|
+
width: 0;
|
|
118
|
+
height: 0;
|
|
119
|
+
opacity: 0;
|
|
120
|
+
overflow: hidden;
|
|
121
|
+
pointer-events: none;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
&.hover-out:not(.is-expanding, .is-collapsing, .label-hidden) {
|
|
125
|
+
.navigation-toolbar-link__label {
|
|
126
|
+
// TODO: Maybe just use transitions instead of keyframe animations
|
|
127
|
+
animation-name: fadeOutLabel;
|
|
128
|
+
animation-duration: var(--e-trs-duration-faster);
|
|
129
|
+
animation-timing-function: ease-out;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
&:hover:not(.is-expanding, .is-collapsing, .label-hidden) {
|
|
134
|
+
.navigation-toolbar-link__label {
|
|
135
|
+
animation-name: fadeInLabel;
|
|
136
|
+
animation-duration: var(--e-trs-duration-faster);
|
|
137
|
+
animation-timing-function: ease-out;
|
|
138
|
+
|
|
139
|
+
padding: var(--e-space-1_5) var(--e-space-2);
|
|
140
|
+
transform: translateX(100%);
|
|
141
|
+
width: auto;
|
|
142
|
+
height: auto;
|
|
143
|
+
opacity: 1;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Animation
|
|
150
|
+
.navigation-toolbar-link {
|
|
151
|
+
&.is-collapsing,
|
|
152
|
+
&.is-expanding {
|
|
153
|
+
animation-duration: var(--e-trs-duration-faster);
|
|
154
|
+
|
|
155
|
+
.navigation-toolbar-link__label {
|
|
156
|
+
animation: none;
|
|
157
|
+
position: static;
|
|
158
|
+
width: auto;
|
|
159
|
+
height: auto;
|
|
160
|
+
opacity: 1;
|
|
161
|
+
background-color: transparent;
|
|
162
|
+
transform: none;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
&.is-collapsing {
|
|
167
|
+
// TODO: Maybe just use transitions instead of keyframe animations
|
|
168
|
+
animation-name: collapse;
|
|
169
|
+
animation-timing-function: var(--transition-ease-out);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
&.is-expanding {
|
|
173
|
+
// TODO: Maybe just use transitions instead of keyframe animations
|
|
174
|
+
animation-name: expand;
|
|
175
|
+
animation-timing-function: var(--transition-ease-out);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, watch, computed, useTemplateRef } from 'vue'
|
|
3
|
+
import { UIcon } from '../../elements'
|
|
4
|
+
|
|
5
|
+
// TODO: Label animation when collapsed is a mess. Refactor it as soon as possbile!
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
label?: string
|
|
9
|
+
icon: string
|
|
10
|
+
href?: string
|
|
11
|
+
target?: string
|
|
12
|
+
active?: boolean
|
|
13
|
+
collapsed?: boolean
|
|
14
|
+
labelHidden?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
active = false,
|
|
19
|
+
collapsed = false,
|
|
20
|
+
labelHidden = false,
|
|
21
|
+
href = '',
|
|
22
|
+
target = '_self',
|
|
23
|
+
} = defineProps<Props>()
|
|
24
|
+
|
|
25
|
+
const isCollapsed = ref(collapsed)
|
|
26
|
+
const isCollapsing = ref(false)
|
|
27
|
+
const isExpanding = ref(false)
|
|
28
|
+
const isHovering = ref(false)
|
|
29
|
+
const isHoverout = ref(false)
|
|
30
|
+
const labelEl = useTemplateRef('label')
|
|
31
|
+
|
|
32
|
+
const onWrapperAnimationEnd = (e: Event) => {
|
|
33
|
+
if (e.target === labelEl.value) {
|
|
34
|
+
isHoverout.value = false
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
isCollapsing.value = false
|
|
39
|
+
isExpanding.value = false
|
|
40
|
+
isHoverout.value = false
|
|
41
|
+
|
|
42
|
+
isCollapsed.value = !isCollapsed.value
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const onHover = () => {
|
|
46
|
+
isHovering.value = true
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const onHoverOut = () => {
|
|
50
|
+
isHovering.value = false
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
watch(
|
|
54
|
+
() => collapsed,
|
|
55
|
+
(newV) => {
|
|
56
|
+
if (newV) {
|
|
57
|
+
// Start collapsing animation
|
|
58
|
+
isCollapsing.value = true
|
|
59
|
+
} else {
|
|
60
|
+
// Start expanding animation
|
|
61
|
+
isExpanding.value = true
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
watch(isHovering, (newV) => {
|
|
67
|
+
if (!newV) {
|
|
68
|
+
isHoverout.value = true
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const tag = computed(() => {
|
|
73
|
+
if (href) {
|
|
74
|
+
return 'a'
|
|
75
|
+
} else {
|
|
76
|
+
return 'span'
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<template>
|
|
82
|
+
<component
|
|
83
|
+
:is="tag"
|
|
84
|
+
:href="tag === 'a' ? href : null"
|
|
85
|
+
:target="tag === 'a' ? target : null"
|
|
86
|
+
:class="[
|
|
87
|
+
'navigation-toolbar-link',
|
|
88
|
+
{
|
|
89
|
+
active,
|
|
90
|
+
collapsed: isCollapsed,
|
|
91
|
+
'hover-out': isHoverout,
|
|
92
|
+
'is-collapsing': isCollapsing,
|
|
93
|
+
'is-expanding': isExpanding,
|
|
94
|
+
'label-hidden': labelHidden,
|
|
95
|
+
},
|
|
96
|
+
]"
|
|
97
|
+
@animationend="onWrapperAnimationEnd"
|
|
98
|
+
@mouseenter="onHover"
|
|
99
|
+
@mouseleave="onHoverOut"
|
|
100
|
+
>
|
|
101
|
+
<UIcon :name="icon" />
|
|
102
|
+
<span ref="label" class="navigation-toolbar-link__label">
|
|
103
|
+
<slot>{{ label }}</slot>
|
|
104
|
+
</span>
|
|
105
|
+
</component>
|
|
106
|
+
</template>
|
|
107
|
+
|
|
108
|
+
<style lang="scss" src="./navigation-toolbar-link.scss" scoped></style>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
@use '../../base/abstracts/' as a;
|
|
2
|
+
|
|
3
|
+
.wizard-text-block {
|
|
4
|
+
.wizard-text-block__title {
|
|
5
|
+
@include a.type(800, strong);
|
|
6
|
+
|
|
7
|
+
+ .wizard-text-block__text {
|
|
8
|
+
margin-top: var(--e-space-4);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.wizard-text-block__title--small {
|
|
13
|
+
@include a.type(500, strong);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.wizard-text-block__text {
|
|
17
|
+
@include a.type(300);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@include a.bp(lg) {
|
|
21
|
+
.wizard-text-block__title {
|
|
22
|
+
@include a.type(700, strong);
|
|
23
|
+
|
|
24
|
+
+ .wizard-text-block__text {
|
|
25
|
+
margin-top: var(--e-space-3);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Modifiers
|
|
31
|
+
&.wizard-text-block--sub {
|
|
32
|
+
.wizard-text-block__title {
|
|
33
|
+
@include a.type(300, strong);
|
|
34
|
+
|
|
35
|
+
+ .wizard-text-block__text {
|
|
36
|
+
margin-top: var(--e-space-2);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.wizard-text-block__text {
|
|
41
|
+
@include a.type(300);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@include a.bp(lg) {
|
|
45
|
+
.wizard-text-block__title {
|
|
46
|
+
@include a.type(200, strong);
|
|
47
|
+
|
|
48
|
+
+ .wizard-text-block__text {
|
|
49
|
+
margin-top: var(--e-space-2);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.wizard-text-block__text {
|
|
54
|
+
@include a.type(200);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
interface Props {
|
|
3
|
+
variant: 'lead' | 'sub'
|
|
4
|
+
title?: string
|
|
5
|
+
text?: string
|
|
6
|
+
centered?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { centered = false } = defineProps<Props>()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<div :class="['wizard-text-block', `wizard-text-block--${variant}`, { centered }]">
|
|
14
|
+
<h2 v-if="title" class="wizard-text-block__title" v-html="title" />
|
|
15
|
+
|
|
16
|
+
<div v-if="text" class="wizard-text-block__text richtext" v-html="text" />
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<style scoped lang="scss">
|
|
21
|
+
@use './text-block.scss';
|
|
22
|
+
|
|
23
|
+
.centered {
|
|
24
|
+
text-align: center;
|
|
25
|
+
}
|
|
26
|
+
</style>
|