PluginProbe
The Innovative Form Builder – IvyForms / 1.1
The Innovative Form Builder – IvyForms v1.1
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 / checkbox / IvyCheckbox.vue

IvyCheckbox.vue in The Innovative Form Builder – IvyForms 1.1, at frontend/src/views/_components/checkbox/IvyCheckbox.vue

373 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <ElCheckbox
3 v-if="$slots.default"
4 v-model="localModelValue"
5 class="ivyforms-checkbox"
6 :class="[
7 `size-${props.size}`,
8 `priority-${props.priority}`,
9 `type-${props.type}`,
10 props.labelPosition === 'left' ? 'label-left' : 'label-right',
11 { 'with-description': props.description },
12 {
13 'is-checked': localModelValue,
14 'is-indeterminate': props.indeterminate,
15 'is-disabled': props.disabled,
16 'with-marker': props.type === 'withMarker',
17 },
18 ]"
19 :disabled="props.disabled"
20 :aria-label="props.ariaLabel || getLabel('checkbox')"
21 @change="(eventValue) => $emit('change', eventValue)"
22 >
23 <span class="ivyforms-checkbox__label-with-tooltip">
24 <slot />
25 <IvyTooltip v-if="props.tooltip" :content="props.tooltip" raw-content placement="top">
26 <IvyIcon
27 name="question"
28 type="outline"
29 size="s"
30 color="var(--map-base-dusk-symbol-2)"
31 class="ivyforms-checkbox__tooltip-icon"
32 @click.prevent
33 />
34 </IvyTooltip>
35 </span>
36
37 <span v-if="props.description" class="ivyforms-checkbox__description">
38 {{ props.description }}
39 </span>
40 </ElCheckbox>
41 </template>
42
43 <script setup lang="ts">
44 import { computed } from 'vue'
45 import { useLabels } from '@/composables/useLabels'
46 const { getLabel } = useLabels()
47 interface Props {
48 modelValue?: boolean
49 indeterminate?: boolean
50 labelPosition?: 'right' | 'left'
51 description?: string
52 priority?: 'primary' | 'secondary' | 'amber'
53 size?: 's' | 'd' | 'l' | 'xl'
54 type?: 'checkmark' | 'withMarker'
55 disabled?: boolean
56 ariaLabel?: string
57 tooltip?: string
58 }
59
60 const props = withDefaults(defineProps<Props>(), {
61 labelPosition: 'right',
62 priority: 'primary',
63 size: 'd',
64 type: 'withMarker',
65 disabled: false,
66 indeterminate: false,
67 description: '',
68 ariaLabel: '',
69 tooltip: '',
70 })
71
72 const emit = defineEmits(['update:modelValue', 'change'])
73
74 const localModelValue = computed({
75 get() {
76 return props.modelValue
77 },
78 set(value) {
79 emit('update:modelValue', value)
80 },
81 })
82 </script>
83
84 <style lang="scss">
85 @use 'sass:list' as *;
86 @use 'sass:meta' as *;
87 $el: '.el-checkbox';
88
89 // Checkbox
90 .ivyforms-checkbox {
91 display: flex;
92 flex-direction: row;
93 gap: 12px;
94 margin-right: 0;
95 height: unset;
96 min-height: 24px;
97 white-space: normal;
98
99 // Override Element UI styles for disabled checkbox in dark theme
100 .el-checkbox__input.is-disabled .el-checkbox__inner {
101 background-color: var(--map-base-dusk-o05);
102 border-color: var(--map-base-dusk-stroke--2);
103 cursor: not-allowed;
104 }
105
106 &.show-all-columns {
107 border-bottom: 1px solid var(--map-divider);
108 padding-bottom: 6px;
109 margin-top: 0 !important;
110 }
111
112 &.el-checkbox {
113 white-space: normal;
114 display: flex;
115 align-items: center;
116 gap: 12px;
117 margin-right: 0;
118 -webkit-tap-highlight-color: transparent;
119 min-height: 24px;
120 height: unset;
121 color: var(--map-base-text-0);
122 &.is-checked {
123 color: var(--map-base-text-0);
124 .el-checkbox__label {
125 color: var(--map-base-text-0);
126 }
127 &.is-indeterminate {
128 .el-checkbox__inner {
129 background-color: var(--map-base-dusk-o05);
130 border-color: var(--map-base-dusk-stroke--2);
131 &::after {
132 content: '';
133 width: 10px;
134 height: 2px;
135 background-color: white;
136 position: absolute;
137 top: 50%;
138 left: 50%;
139 transform: translate(-50%, -50%);
140 }
141 }
142 }
143 }
144 }
145 .el-checkbox__input {
146 margin-right: 0;
147 padding: 0;
148
149 .el-checkbox__inner {
150 background-color: var(--map-base-dusk-o05);
151 border-color: var(--map-base-dusk-stroke--2);
152 border-radius: 4px;
153 }
154
155 &:disabled {
156 opacity: 0.5;
157 }
158
159 &.is-checked {
160 color: var(--map-base-text-0);
161 .el-checkbox__inner {
162 background-color: var(--map-base-dusk-o05);
163 border-color: var(--map-base-dusk-stroke--2);
164 &::after {
165 content: '';
166 display: inline-block;
167 position: absolute;
168 left: 50%;
169 top: 50%;
170 transform: translate(-50%, -50%);
171 width: 100%;
172 height: 100%;
173 }
174 }
175 .el-checkbox__label {
176 color: var(--map-base-text-0);
177 }
178 }
179 &.is-checked {
180 &:disabled {
181 opacity: 0.5;
182 }
183 }
184 }
185 .el-checkbox__label {
186 padding: 0;
187 font-size: 16px;
188 font-weight: 400;
189 display: flex;
190 line-height: 22px;
191 flex-direction: column;
192 color: var(--map-base-text-0);
193 }
194
195 &.label-left {
196 .el-checkbox__input {
197 order: 2;
198 }
199 .el-checkbox__label {
200 order: 1;
201 }
202 }
203
204 &.with-description {
205 align-items: flex-start;
206 }
207
208 &__description {
209 font-size: 14px;
210 font-weight: 400;
211 line-height: 20px;
212 color: var(--map-base-text--1);
213 }
214
215 // Sizes
216 $sizes: (
217 'xl': (
218 32px,
219 24px,
220 16px,
221 ),
222 'l': (
223 24px,
224 16px,
225 12px,
226 ),
227 'd': (
228 20px,
229 16px,
230 12px,
231 ),
232 's': (
233 16px,
234 12px,
235 8px,
236 ),
237 );
238
239 @each $size, $values in $sizes {
240 &.size-#{$size} {
241 .el-checkbox__inner {
242 height: nth($values, 1);
243 width: nth($values, 1);
244 &::after {
245 height: nth($values, 2);
246 width: nth($values, 2);
247 }
248 }
249 &.type-withMarker {
250 .el-checkbox__inner {
251 &::after {
252 height: nth($values, 3);
253 width: nth($values, 3);
254 }
255 }
256 }
257 }
258 }
259
260 // Priorities
261 $priorities: (
262 'primary': (
263 var(--map-base-brand-fill-0),
264 var(--map-base-brand-fill-1),
265 var(--map-base-brand-o05),
266 var(--map-base-brand-stroke-0),
267 ),
268 'secondary': (
269 var(--map-base-purple-fill-0),
270 var(--map-base-purple-fill-1),
271 var(--map-base-purple-o05),
272 var(--map-base-purple-stroke-0),
273 ),
274 'amber': (
275 var(--map-accent-amber-fill-0),
276 var(--map-accent-amber-fill-1),
277 var(--map-accent-amber-o05),
278 var(--map-accent-amber-stroke-0),
279 ),
280 );
281
282 @each $priority, $values in $priorities {
283 &.priority-#{$priority} {
284 &.is-checked {
285 &.type-checkmark {
286 .el-checkbox__inner {
287 background-color: nth($values, 1);
288 border-color: nth($values, 1);
289 }
290 &:hover:not(.is-disabled) {
291 .el-checkbox__inner {
292 &::after {
293 background-color: nth($values, 2);
294 border-color: nth($values, 2);
295 }
296 }
297 }
298 }
299
300 .el-checkbox__inner {
301 &::after {
302 background-color: nth($values, 1);
303 border-color: nth($values, 1);
304 }
305 }
306
307 &:hover:not(.is-disabled) {
308 .el-checkbox__inner {
309 &::after {
310 background-color: nth($values, 2);
311 border-color: nth($values, 2);
312 }
313 }
314 }
315 &.is-indeterminate {
316 .el-checkbox__inner {
317 background-color: nth($values, 1);
318 border-color: nth($values, 1);
319 }
320 &:hover:not(.is-disabled) {
321 .el-checkbox__inner {
322 background-color: nth($values, 2);
323 border-color: nth($values, 2);
324 &::after {
325 background-color: white;
326 }
327 }
328 }
329 }
330 }
331
332 &:not(.is-checked) {
333 &:hover:not(.is-disabled) {
334 .el-checkbox__inner {
335 background-color: nth($values, 3);
336 border-color: nth($values, 4);
337 }
338 }
339 }
340 }
341 }
342
343 &.type-checkmark {
344 &.is-checked {
345 .el-checkbox__inner {
346 &::after {
347 content: '';
348 display: inline-block;
349 background-image: url('@/assets/images/radioButton/radio-button-checkmark.svg');
350 background-size: contain;
351 background-repeat: no-repeat;
352 position: absolute;
353 left: 50%;
354 top: 50%;
355 transform: translate(-50%, -50%);
356 border-radius: 4px;
357 }
358 }
359 }
360 }
361 &__label-with-tooltip {
362 display: inline-flex;
363 align-items: center;
364 gap: 0.25rem;
365 }
366
367 &__tooltip-icon {
368 cursor: pointer;
369 flex-shrink: 0;
370 }
371 }
372 </style>
373