@energie360/ui-library 0.1.1 → 0.1.3
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/_input-resets.scss +9 -3
- package/base/_resets.scss +5 -0
- package/components/accordion-item/accordion-item.scss +62 -0
- package/components/accordion-item/u-accordion-item.vue +44 -0
- package/components/card/card.scss +58 -0
- package/components/card/u-card.vue +26 -0
- package/components/card-header/card-header.scss +102 -0
- package/components/card-header/u-card-header.vue +51 -0
- package/components/card-hint/card-hint.scss +13 -0
- package/components/card-hint/u-card-hint.vue +23 -0
- package/components/card-price/card-price.scss +110 -0
- package/components/card-price/u-card-price.vue +47 -0
- package/components/card-table/card-table.scss +76 -0
- package/components/card-table/u-card-table.vue +77 -0
- package/components/card-toggle-switches/card-toggle-switches.scss +13 -0
- package/components/card-toggle-switches/u-card-toggle-switches.vue +30 -0
- package/components/collapsible/collapsible.scss +14 -0
- package/components/collapsible/u-collapsible.vue +81 -0
- package/components/collapsible-group/u-collapsible-group.vue +14 -0
- package/components/icon-teaser/icon-teaser.scss +58 -0
- package/components/icon-teaser/u-icon-teaser.vue +35 -0
- package/components/icon-teaser-group/icon-teaser-group.scss +10 -0
- package/components/icon-teaser-group/u-icon-teaser-group.vue +19 -0
- package/components/icon-text-block/u-icon-text-block.vue +3 -8
- package/components/language-nav/language-nav.scss +32 -0
- package/components/language-nav/u-language-nav.vue +27 -0
- package/components/panel/panel.scss +43 -6
- package/components/panel/u-panel.vue +22 -11
- package/components/progress-bar/u-progress-bar.vue +1 -1
- package/components/richtext/richtext.scss +208 -0
- package/components/richtext/u-richtext.vue +21 -0
- package/components/table/u-cell-ctas.vue +2 -7
- package/components/table/u-cell-icon-group.vue +1 -1
- package/components/table/u-cell-icon-text.vue +1 -1
- package/components/table/u-cell-progress-bar.vue +1 -1
- package/components/table/u-table-cell.vue +3 -13
- package/components/table/u-table-heading.vue +1 -4
- package/components/tooltip/{popover.js → popover.ts} +51 -43
- package/components/tooltip/u-tooltip.vue +40 -60
- package/dist/base-style.css +409 -2
- package/dist/base-style.css.map +1 -0
- package/dist/elements/text-link.css +40 -0
- package/dist/elements/text-link.css.map +1 -0
- package/dist/layout/split.css +124 -0
- package/dist/layout/split.css.map +1 -0
- package/elements/button/u-button.vue +2 -5
- package/elements/button-chip/button-chip.scss +83 -0
- package/elements/button-chip/u-button-chip.vue +45 -0
- package/elements/form-field/form-field-base.scss +2 -3
- package/elements/form-field/form-field.types.ts +8 -0
- package/elements/icon/u-icon.vue +1 -3
- package/elements/image/u-image.vue +2 -2
- package/elements/numeric-stepper/numeric-stepper.scss +110 -0
- package/elements/numeric-stepper/u-numeric-stepper.vue +135 -0
- package/elements/select/select.scss +32 -0
- package/elements/select/u-select.vue +130 -0
- package/elements/select-chip/select-chip.scss +18 -0
- package/elements/select-chip/u-select-chip.vue +50 -0
- package/elements/select-chips/select-chips.scss +5 -0
- package/elements/select-chips/u-select-chips.vue +23 -0
- package/elements/spectro/spectro.scss +1 -4
- package/elements/text-field/u-text-field.vue +43 -27
- package/elements/text-link/text-link.scss +57 -0
- package/elements/toggle-switch/toggle-switch-small.scss +40 -0
- package/elements/toggle-switch/toggle-switch.scss +149 -0
- package/elements/toggle-switch/u-toggle-switch.vue +68 -0
- package/elements/types.ts +7 -0
- package/globals.js +6 -2
- package/helpers/transition-height.vue +39 -0
- package/i18n/i18n.ts +40 -0
- package/layout/grid/grid.mixin.scss +4 -11
- package/layout/split/split.scss +96 -0
- package/modules/footer/footer.scss +161 -0
- package/modules/footer/u-footer.vue +59 -0
- package/package.json +23 -13
- package/utility/elements/text-link.scss +1 -0
- package/utility/layout/split.scss +1 -0
- package/utility/utility-text.js +1 -0
- package/utils/object/deep-get.js +1 -2
- package/utils/translations/translate.js +13 -0
- package/vite.config.ts +1 -0
- package/watch.js +27 -0
- package/wizard/wizard-intro/wizard-intro.scss +4 -0
- package/wizard/wizard-layout/u-wizard-layout-block.vue +1 -1
- package/wizard/wizard-layout/u-wizard-layout-element.vue +1 -1
- package/wizard/wizard-layout/u-wizard-layout.vue +1 -1
- package/wizard/wizard-layout/wizard-layout.scss +6 -6
- package/dist/base-style.js +0 -2
- package/dist/base-style.js.map +0 -1
- package/dist/custom-elements.css +0 -1
- package/dist/custom-elements.js +0 -5185
- package/dist/custom-elements.js.map +0 -1
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import UIcon from '../icon/u-icon.vue'
|
|
3
3
|
import { TextFieldTypes } from './text-field.types'
|
|
4
|
-
import { computed, ref, useSlots, useTemplateRef, useId } from 'vue'
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
disabled?: boolean
|
|
12
|
-
readonly?: boolean
|
|
4
|
+
import { computed, ref, useSlots, useTemplateRef, useId, watch } from 'vue'
|
|
5
|
+
import { FormFieldBase } from '../form-field/form-field.types'
|
|
6
|
+
import { getTranslation } from '../../utils/translations/translate'
|
|
7
|
+
|
|
8
|
+
interface Props extends FormFieldBase {
|
|
9
|
+
name: string
|
|
10
|
+
type?: TextFieldTypes
|
|
13
11
|
placeholder?: string
|
|
14
|
-
|
|
12
|
+
readonly?: boolean
|
|
15
13
|
unit?: string
|
|
16
|
-
helpText?: string
|
|
17
|
-
errorMessage?: string
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
const inputId = useId()
|
|
21
17
|
|
|
22
18
|
const {
|
|
23
19
|
disabled = false,
|
|
@@ -29,12 +25,13 @@ const {
|
|
|
29
25
|
} = defineProps<Props>()
|
|
30
26
|
|
|
31
27
|
const slots = useSlots()
|
|
28
|
+
const model = defineModel<string>()
|
|
32
29
|
|
|
33
30
|
const input = useTemplateRef('input')
|
|
34
31
|
|
|
35
32
|
const isFocused = ref(false)
|
|
36
33
|
const isHovering = ref(false)
|
|
37
|
-
const hasValue = ref(false)
|
|
34
|
+
const hasValue = ref(false) // only needed for input type 'search'
|
|
38
35
|
const forceFloatLabel = ref(false)
|
|
39
36
|
|
|
40
37
|
const spacer = '. '
|
|
@@ -55,7 +52,7 @@ const onBlur = () => {
|
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
const onInput = () => {
|
|
58
|
-
hasValue.value = input.value.value !== ''
|
|
55
|
+
hasValue.value = !!input.value && input.value.value !== ''
|
|
59
56
|
}
|
|
60
57
|
|
|
61
58
|
const onHover = () => {
|
|
@@ -80,16 +77,27 @@ const needsHelpTextSpacer = computed(() => {
|
|
|
80
77
|
|
|
81
78
|
const onPasswordToggle = () => {
|
|
82
79
|
_inputType.value =
|
|
83
|
-
_inputType.value === TextFieldTypes.password
|
|
84
|
-
? TextFieldTypes.text
|
|
85
|
-
: TextFieldTypes.password
|
|
80
|
+
_inputType.value === TextFieldTypes.password ? TextFieldTypes.text : TextFieldTypes.password
|
|
86
81
|
}
|
|
87
82
|
|
|
88
83
|
const passwordIcon = computed(() => {
|
|
89
|
-
return _inputType.value === TextFieldTypes.password
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
return _inputType.value === TextFieldTypes.password ? 'password' : 'password-show'
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const passwordA11yText = computed(() => {
|
|
88
|
+
return _inputType.value === TextFieldTypes.password ? 'showPassword' : 'hidePassword'
|
|
92
89
|
})
|
|
90
|
+
|
|
91
|
+
watch(
|
|
92
|
+
() => type,
|
|
93
|
+
() => {
|
|
94
|
+
if (type === TextFieldTypes.password) {
|
|
95
|
+
_inputType.value = TextFieldTypes.password
|
|
96
|
+
} else {
|
|
97
|
+
_inputType.value = type
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
)
|
|
93
101
|
</script>
|
|
94
102
|
|
|
95
103
|
<template>
|
|
@@ -121,32 +129,40 @@ const passwordIcon = computed(() => {
|
|
|
121
129
|
<div class="control">
|
|
122
130
|
<slot
|
|
123
131
|
><input
|
|
124
|
-
ref="input"
|
|
125
132
|
:id="inputId"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
133
|
+
ref="input"
|
|
134
|
+
v-model="model"
|
|
135
|
+
:name
|
|
129
136
|
:type="_inputType"
|
|
130
137
|
:disabled
|
|
131
138
|
:readonly
|
|
132
139
|
:placeholder
|
|
133
140
|
:required
|
|
141
|
+
@input="onInput"
|
|
142
|
+
@focus="onFocus"
|
|
143
|
+
@blur="onBlur"
|
|
134
144
|
/></slot>
|
|
135
145
|
|
|
136
146
|
<div class="control-border"></div>
|
|
137
147
|
</div>
|
|
138
148
|
|
|
139
149
|
<!-- TYPE: PASSWORD -->
|
|
140
|
-
<span
|
|
150
|
+
<span v-if="type === TextFieldTypes.password" class="suffix-action">
|
|
141
151
|
<button type="button" class="password-toggle" @click="onPasswordToggle">
|
|
152
|
+
<span class="visually-hidden">{{ getTranslation(passwordA11yText) }}</span>
|
|
142
153
|
<UIcon :name="passwordIcon"></UIcon>
|
|
143
154
|
</button>
|
|
144
155
|
</span>
|
|
156
|
+
|
|
157
|
+
<!-- UNIT -->
|
|
158
|
+
<span v-if="unit" class="suffix-text">
|
|
159
|
+
{{ unit }}
|
|
160
|
+
</span>
|
|
145
161
|
</div>
|
|
146
162
|
|
|
147
163
|
<div class="help-text">
|
|
148
164
|
<span class="optional-text"
|
|
149
|
-
>{{
|
|
165
|
+
>{{ getTranslation('optional')
|
|
150
166
|
}}<span v-if="needsHelpTextSpacer" v-html="spacer"></span></span
|
|
151
167
|
><slot name="helpText">{{ helpText }}</slot>
|
|
152
168
|
</div>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
@use '../../base/abstracts' as a;
|
|
2
|
+
|
|
3
|
+
@mixin text-link {
|
|
4
|
+
@include a.type(200, strong);
|
|
5
|
+
|
|
6
|
+
color: var(--e-c-primary-01-700);
|
|
7
|
+
text-decoration: underline;
|
|
8
|
+
text-underline-offset: 0.4em;
|
|
9
|
+
transition:
|
|
10
|
+
text-decoration-color a.$trs-default,
|
|
11
|
+
color a.$trs-default;
|
|
12
|
+
|
|
13
|
+
&:hover {
|
|
14
|
+
text-decoration-color: var(--e-c-primary-01-50);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&:active {
|
|
18
|
+
text-decoration-color: var(--e-c-primary-01-700);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@mixin text-link--inverted {
|
|
23
|
+
color: var(--e-c-primary-01-50);
|
|
24
|
+
|
|
25
|
+
&:hover {
|
|
26
|
+
text-decoration-color: var(--e-c-primary-01-200);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&:active {
|
|
30
|
+
text-decoration-color: var(--e-c-primary-01-50);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@mixin text-link--secondary {
|
|
35
|
+
text-decoration: none;
|
|
36
|
+
color: var(--e-c-mono-700);
|
|
37
|
+
|
|
38
|
+
&:hover {
|
|
39
|
+
color: var(--e-c-mono-900);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&:active {
|
|
43
|
+
color: var(--e-c-mono-700);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.text-link {
|
|
48
|
+
@include text-link;
|
|
49
|
+
|
|
50
|
+
&.inverted {
|
|
51
|
+
@include text-link--inverted;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.secondary {
|
|
55
|
+
@include text-link--secondary;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
@use '../../base/abstracts' as a;
|
|
2
|
+
|
|
3
|
+
.toggle-switch.toggle-switch--small {
|
|
4
|
+
--width: 54px;
|
|
5
|
+
--height: 28px;
|
|
6
|
+
--handle-size: 24px;
|
|
7
|
+
--inner-padding: 2px;
|
|
8
|
+
|
|
9
|
+
.toggle-switch__wrapper {
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
width: 100%;
|
|
13
|
+
gap: var(--e-space-4);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.toggle-switch__handle {
|
|
17
|
+
padding: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.toggle-switch__text {
|
|
21
|
+
@include a.visually-hidden;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.toggle-switch__label {
|
|
25
|
+
@include a.type(200);
|
|
26
|
+
|
|
27
|
+
padding-top: var(--e-space-0_5);
|
|
28
|
+
padding-bottom: var(--e-space-0_5);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&.label-left {
|
|
32
|
+
.toggle-switch__wrapper {
|
|
33
|
+
flex-direction: row-reverse;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.toggle-switch__label {
|
|
37
|
+
margin-right: auto;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
@use '../../base/abstracts/' as a;
|
|
2
|
+
@use './toggle-switch-small';
|
|
3
|
+
|
|
4
|
+
.toggle-switch {
|
|
5
|
+
--width: 102px;
|
|
6
|
+
--height: 48px;
|
|
7
|
+
--handle-size: 40px;
|
|
8
|
+
--inner-padding: 4px;
|
|
9
|
+
|
|
10
|
+
.toggle-switch__wrapper {
|
|
11
|
+
display: block;
|
|
12
|
+
position: relative;
|
|
13
|
+
width: var(--width);
|
|
14
|
+
min-height: var(--height);
|
|
15
|
+
|
|
16
|
+
input {
|
|
17
|
+
// So that the focus works nicely.
|
|
18
|
+
position: absolute;
|
|
19
|
+
inset: 0;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.toggle-switch__toggle {
|
|
24
|
+
display: flex;
|
|
25
|
+
width: var(--width);
|
|
26
|
+
height: var(--height);
|
|
27
|
+
flex: 0 0 auto;
|
|
28
|
+
align-items: center;
|
|
29
|
+
position: relative;
|
|
30
|
+
background-color: var(--e-c-mono-200);
|
|
31
|
+
border-radius: calc(var(--height) * 0.5);
|
|
32
|
+
transition: background-color var(--e-trs-duration-faster) var(--e-trs-easing-default);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.toggle-switch__handle {
|
|
36
|
+
position: absolute;
|
|
37
|
+
padding: a.rem(8);
|
|
38
|
+
background-color: var(--e-c-mono-00);
|
|
39
|
+
border-radius: 100%;
|
|
40
|
+
width: var(--handle-size);
|
|
41
|
+
height: var(--handle-size);
|
|
42
|
+
top: var(--inner-padding);
|
|
43
|
+
left: var(--inner-padding);
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
color: var(--e-c-mono-900);
|
|
46
|
+
transition:
|
|
47
|
+
transform var(--e-trs-duration-faster) var(--e-trs-easing-default),
|
|
48
|
+
color var(--e-trs-duration-faster) var(--e-trs-easing-default);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.toggle-switch__text {
|
|
52
|
+
@include a.type(200, strong);
|
|
53
|
+
|
|
54
|
+
display: block;
|
|
55
|
+
position: absolute;
|
|
56
|
+
padding-left: a.rem(8);
|
|
57
|
+
padding-right: a.rem(8);
|
|
58
|
+
transition:
|
|
59
|
+
color var(--e-trs-duration-faster) var(--e-trs-easing-default),
|
|
60
|
+
opacity var(--e-trs-duration-faster) var(--e-trs-easing-default);
|
|
61
|
+
|
|
62
|
+
&.yes {
|
|
63
|
+
left: 16px;
|
|
64
|
+
opacity: 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&.no {
|
|
68
|
+
right: 10px;
|
|
69
|
+
opacity: 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&:hover {
|
|
74
|
+
.toggle-switch__toggle {
|
|
75
|
+
background-color: var(--e-c-mono-500);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&:active {
|
|
80
|
+
.toggle-switch__toggle {
|
|
81
|
+
background-color: var(--e-c-mono-700);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.toggle-switch__text {
|
|
85
|
+
color: var(--e-c-mono-00);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// States
|
|
90
|
+
&.checked {
|
|
91
|
+
.toggle-switch__toggle {
|
|
92
|
+
background-color: var(--e-c-primary-01-900);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.toggle-switch__handle {
|
|
96
|
+
transform: translateX(calc(var(--width) - var(--handle-size) - var(--inner-padding) * 2));
|
|
97
|
+
color: var(--e-c-primary-01-900);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.toggle-switch__text {
|
|
101
|
+
color: var(--e-c-mono-00);
|
|
102
|
+
|
|
103
|
+
&.yes {
|
|
104
|
+
opacity: 1;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&.no {
|
|
108
|
+
opacity: 0;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&:hover {
|
|
113
|
+
.toggle-switch__toggle {
|
|
114
|
+
background-color: var(--e-c-secondary-01-900);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.toggle-switch__handle {
|
|
118
|
+
color: var(--e-c-secondary-01-900);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
&:active {
|
|
123
|
+
.toggle-switch__toggle {
|
|
124
|
+
background-color: var(--e-c-secondary-01-700);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.toggle-switch__handle {
|
|
128
|
+
color: var(--e-c-secondary-01-700);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
&.disabled,
|
|
134
|
+
&.disabled.checked {
|
|
135
|
+
.toggle-switch__handle,
|
|
136
|
+
.toggle-switch__text {
|
|
137
|
+
color: var(--e-c-mono-500);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.toggle-switch__toggle {
|
|
141
|
+
background-color: var(--e-c-mono-50);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// // TODO: Do we need readonly styles here?
|
|
146
|
+
// &.readonly {
|
|
147
|
+
// //
|
|
148
|
+
// }
|
|
149
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import UIcon from '../icon/u-icon.vue'
|
|
4
|
+
import { getTranslation } from '../../utils/translations/translate'
|
|
5
|
+
|
|
6
|
+
export interface ToggleSwitch {
|
|
7
|
+
name: string
|
|
8
|
+
label?: string
|
|
9
|
+
required?: boolean
|
|
10
|
+
disabled?: boolean
|
|
11
|
+
readonly?: boolean
|
|
12
|
+
value?: string
|
|
13
|
+
variant?: 'normal' | 'small'
|
|
14
|
+
labelPosition?: 'left' | 'right'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
variant = 'big',
|
|
19
|
+
labelPosition = 'right',
|
|
20
|
+
disabled = false,
|
|
21
|
+
readonly = false,
|
|
22
|
+
required = false,
|
|
23
|
+
} = defineProps<ToggleSwitch>()
|
|
24
|
+
|
|
25
|
+
const model = defineModel<boolean>({ default: false })
|
|
26
|
+
|
|
27
|
+
const iconsMap = {
|
|
28
|
+
small: ['close-small', 'check-small'],
|
|
29
|
+
big: ['close', 'mini-check'],
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const uncheckIcon = computed(() => iconsMap[variant][0])
|
|
33
|
+
const checkIcon = computed(() => iconsMap[variant][1])
|
|
34
|
+
|
|
35
|
+
const classes = computed(() => ({
|
|
36
|
+
checked: model.value,
|
|
37
|
+
disabled,
|
|
38
|
+
readonly,
|
|
39
|
+
[`toggle-switch--${variant}`]: variant,
|
|
40
|
+
[`label-${labelPosition}`]: labelPosition,
|
|
41
|
+
}))
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template>
|
|
45
|
+
<div :class="['toggle-switch', classes]">
|
|
46
|
+
<label class="toggle-switch__wrapper">
|
|
47
|
+
<span class="toggle-switch__toggle">
|
|
48
|
+
<span class="toggle-switch__text yes" :aria-hidden="model.value ? 'false' : 'true'">{{
|
|
49
|
+
getTranslation('yes')
|
|
50
|
+
}}</span>
|
|
51
|
+
<span class="toggle-switch__text no" :aria-hidden="model.value ? 'true' : 'false'">{{
|
|
52
|
+
getTranslation('no')
|
|
53
|
+
}}</span>
|
|
54
|
+
<span class="toggle-switch__handle">
|
|
55
|
+
<UIcon :name="model.value ? checkIcon : uncheckIcon" custom-size />
|
|
56
|
+
</span>
|
|
57
|
+
</span>
|
|
58
|
+
{{ label }}
|
|
59
|
+
<slot name="input"
|
|
60
|
+
><input v-model="model" type="checkbox" :name :required :disabled :readonly :value
|
|
61
|
+
/></slot>
|
|
62
|
+
</label>
|
|
63
|
+
</div>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<style lang="scss">
|
|
67
|
+
@use './toggle-switch.scss';
|
|
68
|
+
</style>
|
package/elements/types.ts
CHANGED
package/globals.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
// A possible idea would be to use a cdn when the package is built.
|
|
2
2
|
// Currently we'll use a fixed path for the assets on dev and prod. This must be made available by the application using ui-library.
|
|
3
|
-
export const assetsPath =
|
|
4
|
-
|
|
3
|
+
// export const assetsPath = import.meta.env.DEV === true ? '/static/ui-assets/' : '/static/ui-assets/'
|
|
4
|
+
|
|
5
|
+
// The library shouldn't rely on any specific build tools, like vite. That's why we shouldn't use `import.meta.env.DEV`.
|
|
6
|
+
// TODO: Find a more 'generic' way to set an environment variable when using/developing the library.
|
|
7
|
+
// In the meantime we'll just use this fixed path for the ui-assets.
|
|
8
|
+
export const assetsPath = '/static/ui-assets/'
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const onEnter = (el) => {
|
|
3
|
+
el.hidden = false
|
|
4
|
+
el.style.height = `${el.scrollHeight}px`
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const onAfterEnter = (el) => {
|
|
8
|
+
el.style.height = 'auto'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const onLeave = (el) => {
|
|
12
|
+
el.style.height = `${el.scrollHeight}px`
|
|
13
|
+
|
|
14
|
+
requestAnimationFrame(() => {
|
|
15
|
+
el.style.height = '0'
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<Transition name="fade" @enter="onEnter" @after-enter="onAfterEnter" @leave="onLeave">
|
|
22
|
+
<slot></slot>
|
|
23
|
+
</Transition>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<style scoped lang="scss">
|
|
27
|
+
@use '../base/abstracts' as a;
|
|
28
|
+
|
|
29
|
+
.fade-enter-active,
|
|
30
|
+
.fade-leave-active {
|
|
31
|
+
transition: height a.$trs-default;
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.fade-enter-from,
|
|
36
|
+
.fade-leave-to {
|
|
37
|
+
height: 0;
|
|
38
|
+
}
|
|
39
|
+
</style>
|
package/i18n/i18n.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
DE: {
|
|
3
|
+
yes: 'Ja',
|
|
4
|
+
no: 'Nein',
|
|
5
|
+
optional: 'Optional',
|
|
6
|
+
increaseValue: 'Wert erhöhen',
|
|
7
|
+
decreaseValue: 'Wert vermindern',
|
|
8
|
+
showPassword: 'Passwort anzeigen',
|
|
9
|
+
hidePassword: 'Passwort verbergen',
|
|
10
|
+
},
|
|
11
|
+
FR: {
|
|
12
|
+
yes: 'Ja',
|
|
13
|
+
no: 'Nein',
|
|
14
|
+
optional: 'Optional',
|
|
15
|
+
increaseValue: 'Wert erhöhen',
|
|
16
|
+
decreaseValue: 'Wert vermindern',
|
|
17
|
+
showPassword: 'Passwort anzeigen',
|
|
18
|
+
hidePassword: 'Passwort verbergen',
|
|
19
|
+
},
|
|
20
|
+
IT: {
|
|
21
|
+
yes: 'Ja',
|
|
22
|
+
no: 'Nein',
|
|
23
|
+
optional: 'Optional',
|
|
24
|
+
increaseValue: 'Wert erhöhen',
|
|
25
|
+
decreaseValue: 'Wert vermindern',
|
|
26
|
+
showPassword: 'Passwort anzeigen',
|
|
27
|
+
hidePassword: 'Passwort verbergen',
|
|
28
|
+
},
|
|
29
|
+
EN: {
|
|
30
|
+
yes: 'Ja',
|
|
31
|
+
no: 'Nein',
|
|
32
|
+
optional: 'Optional',
|
|
33
|
+
increaseValue: 'Wert erhöhen',
|
|
34
|
+
decreaseValue: 'Wert vermindern',
|
|
35
|
+
showPassword: 'Passwort anzeigen',
|
|
36
|
+
hidePassword: 'Passwort verbergen',
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default translations
|
|
@@ -6,8 +6,7 @@ Helper to colculate col width in %.
|
|
|
6
6
|
Looks complicated because we use grid-gap on the row, which takes away from available width.
|
|
7
7
|
*/
|
|
8
8
|
@function col-width($size, $columns, $gutter) {
|
|
9
|
-
@return math.div(100% - (($columns - 1) * $gutter), $columns) * $size +
|
|
10
|
-
(($size - 1) * $gutter);
|
|
9
|
+
@return math.div(100% - (($columns - 1) * $gutter), $columns) * $size + (($size - 1) * $gutter);
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
@mixin grid-row() {
|
|
@@ -63,17 +62,11 @@ $columns: Grid size (in columns). Default is set by global variable $grid-column
|
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
// TODO: Change args order -> $prop, $indent, $columns
|
|
66
|
-
@mixin grid-col-space(
|
|
67
|
-
$indent,
|
|
68
|
-
$columns: a.$grid-columns,
|
|
69
|
-
$prop: 'margin-left'
|
|
70
|
-
) {
|
|
71
|
-
#{$prop}: col-width($indent, $columns, a.$grid-gutter-2xl) +
|
|
72
|
-
a.$grid-gutter-2xl;
|
|
65
|
+
@mixin grid-col-space($indent, $columns: a.$grid-columns, $prop: 'margin-left') {
|
|
66
|
+
#{$prop}: col-width($indent, $columns, a.$grid-gutter-2xl) + a.$grid-gutter-2xl;
|
|
73
67
|
|
|
74
68
|
@include a.bp(lg) {
|
|
75
|
-
#{$prop}: col-width($indent, $columns, a.$grid-gutter-lg) +
|
|
76
|
-
a.$grid-gutter-lg;
|
|
69
|
+
#{$prop}: col-width($indent, $columns, a.$grid-gutter-lg) + a.$grid-gutter-lg;
|
|
77
70
|
}
|
|
78
71
|
|
|
79
72
|
@include a.bp(m) {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
@use '../../base/abstracts/' as a;
|
|
2
|
+
@use '../container/container.scss' as c;
|
|
3
|
+
|
|
4
|
+
$split-top-bar-height: 120px;
|
|
5
|
+
$split-top-bar-height-mobile: 72px;
|
|
6
|
+
|
|
7
|
+
.split {
|
|
8
|
+
position: relative;
|
|
9
|
+
padding-left: 50%;
|
|
10
|
+
|
|
11
|
+
@include a.bp(lg) {
|
|
12
|
+
display: grid;
|
|
13
|
+
padding-left: 0;
|
|
14
|
+
grid-template-columns: 1fr 1fr;
|
|
15
|
+
grid-template-rows: 1fr auto;
|
|
16
|
+
gap: 0;
|
|
17
|
+
grid-template-areas:
|
|
18
|
+
'fixed content'
|
|
19
|
+
'footer footer';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@include a.bp(m) {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.split__fixed {
|
|
29
|
+
position: fixed;
|
|
30
|
+
inset: 0 50% 0 0;
|
|
31
|
+
|
|
32
|
+
@include a.bp(lg) {
|
|
33
|
+
position: static;
|
|
34
|
+
grid-area: fixed;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@include a.bp(m) {
|
|
38
|
+
width: 100%;
|
|
39
|
+
aspect-ratio: 4/5;
|
|
40
|
+
order: 3;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.split__top-bar {
|
|
45
|
+
height: a.rem($split-top-bar-height);
|
|
46
|
+
|
|
47
|
+
@include a.bp(lg) {
|
|
48
|
+
grid-area: content;
|
|
49
|
+
height: a.rem($split-top-bar-height-mobile);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@include a.bp(m) {
|
|
53
|
+
order: 1;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.split__content {
|
|
58
|
+
padding-top: var(--e-space-20);
|
|
59
|
+
padding-bottom: var(--e-space-20);
|
|
60
|
+
margin: 0 auto;
|
|
61
|
+
width: a.rem(400);
|
|
62
|
+
|
|
63
|
+
@include a.bp(lg) {
|
|
64
|
+
margin-top: a.rem(
|
|
65
|
+
$split-top-bar-height-mobile
|
|
66
|
+
); // Because multiple divs in same area do overlap.
|
|
67
|
+
|
|
68
|
+
grid-area: content;
|
|
69
|
+
width: a.rem(338);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@include a.bp(m) {
|
|
73
|
+
order: 2;
|
|
74
|
+
width: auto;
|
|
75
|
+
margin-top: 0;
|
|
76
|
+
max-width: calc(#{a.rem(338)} + 2 * #{a.rem(a.$container-edge-m)});
|
|
77
|
+
padding-left: a.rem(a.$container-edge-m);
|
|
78
|
+
padding-right: a.rem(a.$container-edge-m);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@include a.bp(s) {
|
|
82
|
+
max-width: calc(#{a.rem(338)} + 2 * #{a.rem(a.$container-edge-s)});
|
|
83
|
+
padding-left: a.rem(a.$container-edge-s);
|
|
84
|
+
padding-right: a.rem(a.$container-edge-s);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.split__footer {
|
|
89
|
+
@include a.bp(lg) {
|
|
90
|
+
grid-area: footer;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@include a.bp(m) {
|
|
94
|
+
order: 4;
|
|
95
|
+
}
|
|
96
|
+
}
|