PluginProbe
The Innovative Form Builder – IvyForms / 0.5
The Innovative Form Builder – IvyForms v0.5
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 0.5, at frontend/src/views/_components/checkbox/IvyCheckbox.vue

372 lines 8.2 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 -webkit-tap-highlight-color: transparent;
118 min-height: 24px;
119 height: unset;
120 color: var(--map-base-text-0);
121 &.is-checked {
122 color: var(--map-base-text-0);
123 .el-checkbox__label {
124 color: var(--map-base-text-0);
125 }
126 &.is-indeterminate {
127 .el-checkbox__inner {
128 background-color: var(--map-base-dusk-o05);
129 border-color: var(--map-base-dusk-stroke--2);
130 &::after {
131 content: '';
132 width: 10px;
133 height: 2px;
134 background-color: white;
135 position: absolute;
136 top: 50%;
137 left: 50%;
138 transform: translate(-50%, -50%);
139 }
140 }
141 }
142 }
143 }
144 .el-checkbox__input {
145 margin-right: 0;
146 padding: 0;
147
148 .el-checkbox__inner {
149 background-color: var(--map-base-dusk-o05);
150 border-color: var(--map-base-dusk-stroke--2);
151 border-radius: 4px;
152 }
153
154 &:disabled {
155 opacity: 0.5;
156 }
157
158 &.is-checked {
159 color: var(--map-base-text-0);
160 .el-checkbox__inner {
161 background-color: var(--map-base-dusk-o05);
162 border-color: var(--map-base-dusk-stroke--2);
163 &::after {
164 content: '';
165 display: inline-block;
166 position: absolute;
167 left: 50%;
168 top: 50%;
169 transform: translate(-50%, -50%);
170 width: 100%;
171 height: 100%;
172 }
173 }
174 .el-checkbox__label {
175 color: var(--map-base-text-0);
176 }
177 }
178 &.is-checked {
179 &:disabled {
180 opacity: 0.5;
181 }
182 }
183 }
184 .el-checkbox__label {
185 padding: 0;
186 font-size: 16px;
187 font-weight: 400;
188 display: flex;
189 line-height: 22px;
190 flex-direction: column;
191 color: var(--map-base-text-0);
192 }
193
194 &.label-left {
195 .el-checkbox__input {
196 order: 2;
197 }
198 .el-checkbox__label {
199 order: 1;
200 }
201 }
202
203 &.with-description {
204 align-items: flex-start;
205 }
206
207 &__description {
208 font-size: 14px;
209 font-weight: 400;
210 line-height: 20px;
211 color: var(--map-base-text--1);
212 }
213
214 // Sizes
215 $sizes: (
216 'xl': (
217 32px,
218 24px,
219 16px,
220 ),
221 'l': (
222 24px,
223 16px,
224 12px,
225 ),
226 'd': (
227 20px,
228 16px,
229 12px,
230 ),
231 's': (
232 16px,
233 12px,
234 8px,
235 ),
236 );
237
238 @each $size, $values in $sizes {
239 &.size-#{$size} {
240 .el-checkbox__inner {
241 height: nth($values, 1);
242 width: nth($values, 1);
243 &::after {
244 height: nth($values, 2);
245 width: nth($values, 2);
246 }
247 }
248 &.type-withMarker {
249 .el-checkbox__inner {
250 &::after {
251 height: nth($values, 3);
252 width: nth($values, 3);
253 }
254 }
255 }
256 }
257 }
258
259 // Priorities
260 $priorities: (
261 'primary': (
262 var(--map-base-brand-fill-0),
263 var(--map-base-brand-fill-1),
264 var(--map-base-brand-o05),
265 var(--map-base-brand-stroke-0),
266 ),
267 'secondary': (
268 var(--map-base-purple-fill-0),
269 var(--map-base-purple-fill-1),
270 var(--map-base-purple-o05),
271 var(--map-base-purple-stroke-0),
272 ),
273 'amber': (
274 var(--map-accent-amber-fill-0),
275 var(--map-accent-amber-fill-1),
276 var(--map-accent-amber-o05),
277 var(--map-accent-amber-stroke-0),
278 ),
279 );
280
281 @each $priority, $values in $priorities {
282 &.priority-#{$priority} {
283 &.is-checked {
284 &.type-checkmark {
285 .el-checkbox__inner {
286 background-color: nth($values, 1);
287 border-color: nth($values, 1);
288 }
289 &:hover:not(.is-disabled) {
290 .el-checkbox__inner {
291 &::after {
292 background-color: nth($values, 2);
293 border-color: nth($values, 2);
294 }
295 }
296 }
297 }
298
299 .el-checkbox__inner {
300 &::after {
301 background-color: nth($values, 1);
302 border-color: nth($values, 1);
303 }
304 }
305
306 &:hover:not(.is-disabled) {
307 .el-checkbox__inner {
308 &::after {
309 background-color: nth($values, 2);
310 border-color: nth($values, 2);
311 }
312 }
313 }
314 &.is-indeterminate {
315 .el-checkbox__inner {
316 background-color: nth($values, 1);
317 border-color: nth($values, 1);
318 }
319 &:hover:not(.is-disabled) {
320 .el-checkbox__inner {
321 background-color: nth($values, 2);
322 border-color: nth($values, 2);
323 &::after {
324 background-color: white;
325 }
326 }
327 }
328 }
329 }
330
331 &:not(.is-checked) {
332 &:hover:not(.is-disabled) {
333 .el-checkbox__inner {
334 background-color: nth($values, 3);
335 border-color: nth($values, 4);
336 }
337 }
338 }
339 }
340 }
341
342 &.type-checkmark {
343 &.is-checked {
344 .el-checkbox__inner {
345 &::after {
346 content: '';
347 display: inline-block;
348 background-image: url('@/assets/images/radioButton/radio-button-checkmark.svg');
349 background-size: contain;
350 background-repeat: no-repeat;
351 position: absolute;
352 left: 50%;
353 top: 50%;
354 transform: translate(-50%, -50%);
355 border-radius: 4px;
356 }
357 }
358 }
359 }
360 &__label-with-tooltip {
361 display: inline-flex;
362 align-items: center;
363 gap: 0.25rem;
364 }
365
366 &__tooltip-icon {
367 cursor: pointer;
368 flex-shrink: 0;
369 }
370 }
371 </style>
372