1
0

fix(checkbox): use sibling css selector instead of has

This makes the checkbox work as intended on older browsers which do not support the :has selector.

Resolves https://kolaente.dev/vikunja/vikunja/issues/2713

(cherry picked from commit 15d95f16da86d57edd02dbe09fd3b55e185b75d9)
This commit is contained in:
kolaente 2024-09-25 14:37:47 +02:00
parent 3e3efa85ea
commit 6dbfbc43da
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
2 changed files with 16 additions and 30 deletions

View File

@ -3,33 +3,22 @@
v-cy="'checkbox'" v-cy="'checkbox'"
class="base-checkbox" class="base-checkbox"
> >
<input <label
:id="checkboxId" class="base-checkbox__label"
type="checkbox"
class="is-sr-only"
:checked="modelValue"
:disabled="disabled || undefined"
@change="(event) => emit('update:modelValue', (event.target as HTMLInputElement).checked)"
> >
<input
<slot type="checkbox"
name="label" class="is-sr-only"
:checkbox-id="checkboxId" :checked="modelValue"
> :disabled="disabled || undefined"
<label @change="(event) => emit('update:modelValue', (event.target as HTMLInputElement).checked)"
:for="checkboxId"
class="base-checkbox__label"
> >
<slot /> <slot />
</label> </label>
</slot>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {ref} from 'vue'
import {createRandomID} from '@/helpers/randomId'
withDefaults(defineProps<{ withDefaults(defineProps<{
modelValue?: boolean, modelValue?: boolean,
disabled: boolean, disabled: boolean,
@ -38,10 +27,8 @@ withDefaults(defineProps<{
}) })
const emit = defineEmits<{ const emit = defineEmits<{
(event: 'update:modelValue', value: boolean): void (event: 'update:modelValue', value: boolean): void
}>() }>()
const checkboxId = ref(`checkbox_${createRandomID()}`)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -53,7 +40,7 @@ const checkboxId = ref(`checkbox_${createRandomID()}`)
} }
.base-checkbox:has(input:disabled) .base-checkbox__label { .base-checkbox:has(input:disabled) .base-checkbox__label {
cursor:not-allowed; cursor: not-allowed;
pointer-events: none; pointer-events: none;
} }
</style> </style>

View File

@ -38,7 +38,6 @@ const emit = defineEmits<{
}>() }>()
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.fancy-checkbox { .fancy-checkbox {
display: inline-block; display: inline-block;
@ -70,8 +69,8 @@ const emit = defineEmits<{
} }
} }
.fancy-checkbox:not(:has(input:disabled)):hover .fancy-checkbox__icon, .fancy-checkbox:hover input:not(:disabled) + .fancy-checkbox__icon,
.fancy-checkbox:has(input:checked) .fancy-checkbox__icon { .fancy-checkbox input:checked + .fancy-checkbox__icon {
--stroke-color: var(--primary); --stroke-color: var(--primary);
} }
</style> </style>
@ -80,13 +79,13 @@ const emit = defineEmits<{
// Since css-has-pseudo doesn't work with deep classes, // Since css-has-pseudo doesn't work with deep classes,
// the following rules can't be scoped // the following rules can't be scoped
.fancy-checkbox:has(:not(input:checked)) .fancy-checkbox__icon { .fancy-checkbox :not(input:checked) + .fancy-checkbox__icon {
path { path {
transition-delay: 0.05s; transition-delay: 0.05s;
} }
} }
.fancy-checkbox:has(input:checked) .fancy-checkbox__icon { .fancy-checkbox input:checked + .fancy-checkbox__icon {
path { path {
stroke-dashoffset: 60; stroke-dashoffset: 60;
} }