PluginProbe
The Innovative Form Builder – IvyForms / 0.1.2
The Innovative Form Builder – IvyForms v0.1.2
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / toggle / IvyToggle.vue

IvyToggle.vue in The Innovative Form Builder – IvyForms 0.1.2, at frontend/src/views/_components/toggle/IvyToggle.vue

301 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <div
3 class="ivyforms-toggle"
4 :class="[
5 `text-position-${props.textPosition}`,
6 `size-${props.size}`,
7 `priority-${props.priority}`,
8 `type-${props.type}`,
9 { 'is-disabled': props.disabled },
10 ]"
11 >
12 <ElSwitch
13 v-model="localModelValue"
14 v-bind="{ ...$props, ...$attrs, size: '' }"
15 :inline-prompt="props.type === 'stroke-with-text'"
16 :active-text="computedActiveText"
17 :inactive-text="computedInactiveText"
18 @change="(eventValue: boolean | string | number) => $emit('change', eventValue)"
19 />
20 <div
21 v-if="props.title || props.tooltip || props.description"
22 class="ivyforms-toogle__text-block"
23 >
24 <div
25 v-if="props.title || props.tooltip"
26 class="ivyforms-toggle__text-block__title ivyforms-flex ivyforms-align-items-center"
27 >
28 <div v-if="props.title" class="regular-16">{{ props.title }}</div>
29 <IvyTooltip v-if="props.tooltip" :content="props.tooltip" raw-content placement="top">
30 <IvyIcon
31 name="question"
32 type="outline"
33 size="s"
34 color="var(--map-base-dusk-symbol-2)"
35 @click.prevent
36 />
37 </IvyTooltip>
38 </div>
39
40 <div v-if="props.description" class="ivyforms-toogle__text-block__description">
41 {{ props.description }}
42 </div>
43 </div>
44 </div>
45 </template>
46
47 <script setup lang="ts">
48 import { computed } from 'vue'
49 import { useLabels } from '@/composables/useLabels'
50 const { getLabel } = useLabels()
51
52 interface Props {
53 modelValue?: boolean | string | number
54 label?: string
55 disabled?: boolean
56 size?: 's' | 'd' | 'l' | 'xl'
57 priority?: 'primary' | 'secondary' | 'amber'
58 type?: 'fill' | 'stroke' | 'stroke-with-text'
59 textPosition?: 'left' | 'right'
60 title?: string
61 description?: string
62 tooltip?: string
63 }
64
65 const props = withDefaults(defineProps<Props>(), {
66 disabled: false,
67 size: 'd',
68 priority: 'primary',
69 type: 'fill',
70 label: '',
71 modelValue: '',
72 textPosition: 'right',
73 title: '',
74 description: '',
75 tooltip: '',
76 })
77
78 const emit = defineEmits(['update:modelValue', 'change'])
79
80 const localModelValue = computed({
81 get() {
82 return props.modelValue
83 },
84 set(value) {
85 emit('update:modelValue', value)
86 },
87 })
88
89 const computedActiveText = computed(() =>
90 props.type === 'stroke-with-text' ? (props.label ? props.label : getLabel('on')) : '',
91 )
92 const computedInactiveText = computed(() =>
93 props.type === 'stroke-with-text' ? (props.label ? props.label : getLabel('off')) : '',
94 )
95 </script>
96
97 <style lang="scss">
98 @use 'sass:list' as *;
99
100 .ivyforms-toggle {
101 display: flex;
102 align-items: center;
103 gap: 12px;
104 min-height: 24px;
105 border-radius: 49%;
106
107 &.text-position-left {
108 flex-direction: row-reverse;
109 }
110 // Text Block
111 &__text-block {
112 // Title
113 &__title {
114 height: 24px;
115 color: var(--map-base-text-0);
116 }
117
118 // Switch Description
119 & &__description {
120 color: var(--map-base-text--1);
121 }
122 }
123
124 .el-switch__input {
125 background-color: transparent;
126 box-shadow: none;
127 color: transparent;
128 border: none;
129 }
130 .el-switch__inner {
131 align-items: flex-start;
132 justify-content: center;
133 .is-text {
134 font-weight: 400;
135 font-size: 12px;
136 line-height: 16px;
137 text-align: center;
138 position: absolute;
139 left: 50%;
140 }
141 }
142
143 &.is-disabled {
144 opacity: 0.5;
145 pointer-events: none;
146 }
147
148 .el-switch {
149 display: flex;
150
151 &__core {
152 background-color: var(--map-base-dusk-o05);
153 border-color: var(--theme-base-dusk--2);
154 border-radius: 49px;
155 min-width: 34px;
156
157 .el-switch__action {
158 background-color: var(--theme-base-dusk-1);
159 box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.04);
160 }
161
162 &:not(.is-checked):hover .el-switch__action {
163 background-color: var(--theme-base-dusk-2);
164 }
165
166 .el-switch__inner {
167 .is-text {
168 color: var(--theme-base-text--1);
169 }
170 }
171 }
172 }
173
174 &__label {
175 font-size: 14px;
176 font-weight: 500;
177 }
178
179 $priorities: (
180 'primary': (
181 var(--map-base-brand-fill-0),
182 var(--map-base-brand-fill-1),
183 ),
184 'secondary': (
185 var(--map-base-purple-fill-0),
186 var(--map-base-purple-fill-1),
187 ),
188 'amber': (
189 var(--map-accent-amber-fill-0),
190 var(--map-accent-amber-fill-1),
191 ),
192 );
193
194 // Process each priority value if is array
195 @each $priority, $values in $priorities {
196 &.priority-#{$priority} {
197 .el-switch {
198 &.is-checked {
199 .el-switch__core {
200 background-color: nth($values, 1);
201 border-color: nth($values, 1);
202
203 .el-switch__action {
204 background-color: $primitive-white;
205 }
206
207 .el-switch__inner .is-text {
208 color: $primitive-white;
209 left: 20%;
210 }
211 }
212
213 // Hover state when checked
214 &:hover .el-switch__core {
215 background-color: nth($values, 2);
216 }
217 }
218 }
219 }
220 }
221
222 // Define sizes in a map
223 $sizes: (
224 'xl': (
225 70px,
226 36px,
227 32px,
228 28px,
229 ),
230 'l': (
231 64px,
232 32px,
233 28px,
234 24px,
235 ),
236 'd': (
237 46px,
238 24px,
239 20px,
240 16px,
241 ),
242 's': (
243 34px,
244 16px,
245 14px,
246 12px,
247 ),
248 );
249
250 // Process each size value if is array
251 @each $size, $values in $sizes {
252 &.size-#{$size} {
253 .el-switch {
254 .el-switch__core {
255 height: nth($values, 2);
256 width: nth($values, 1);
257
258 .el-switch__action {
259 height: nth($values, 3);
260 width: nth($values, 3);
261 left: calc(100% - nth($values, 3));
262 }
263 }
264
265 &:not(.is-checked) .el-switch__action {
266 left: 1px;
267 }
268 }
269 &.type-stroke-with-text {
270 .el-switch {
271 .el-switch__core {
272 .el-switch__action {
273 height: nth($values, 4);
274 width: nth($values, 4);
275 }
276 }
277 }
278 }
279 &.type-stroke {
280 .el-switch {
281 .el-switch__core {
282 height: nth($values, 4);
283 width: nth($values, 1);
284
285 .el-switch__action {
286 height: nth($values, 2);
287 width: nth($values, 2);
288 left: calc(100% - nth($values, 2) + 3px);
289 }
290 }
291
292 &:not(.is-checked) .el-switch__action {
293 left: -2px;
294 }
295 }
296 }
297 }
298 }
299 }
300 </style>
301