95 lines
2.2 KiB
Vue
95 lines
2.2 KiB
Vue
<template>
|
|
<label class="shared-checkbox" :class="{ 'is-checked': model, 'is-disabled': disabled }">
|
|
<input
|
|
type="checkbox"
|
|
:disabled="disabled"
|
|
v-model="model"
|
|
/>
|
|
<span class="box">
|
|
<svg class="check" viewBox="0 0 10 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M1 4L3.5 6.5L9 1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
</svg>
|
|
</span>
|
|
<span v-if="$slots.default" class="checkbox-label"><slot /></span>
|
|
</label>
|
|
</template>
|
|
|
|
<script setup>
|
|
const props = defineProps({
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
})
|
|
|
|
const model = defineModel()
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.shared-checkbox {
|
|
--t-duration: 200ms;
|
|
--t-ease: var(--ease-out-quad);
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: rs(10px);
|
|
cursor: pointer;
|
|
user-select: none;
|
|
|
|
input[type='checkbox'] {
|
|
position: absolute;
|
|
opacity: 0;
|
|
width: 0;
|
|
height: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.box {
|
|
flex-shrink: 0;
|
|
width: rs(18px);
|
|
height: rs(18px);
|
|
border: rs(1px) solid var(--grey-400);
|
|
border-radius: rs(4px);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: transparent;
|
|
transition:
|
|
background var(--t-duration) var(--t-ease),
|
|
border-color var(--t-duration) var(--t-ease);
|
|
|
|
.check {
|
|
width: rs(10px);
|
|
height: auto;
|
|
color: var(--ivory);
|
|
opacity: 0;
|
|
transform: scale(0.5);
|
|
transition:
|
|
opacity var(--t-duration) var(--t-ease),
|
|
transform var(--t-duration) var(--t-ease);
|
|
}
|
|
}
|
|
|
|
.checkbox-label {
|
|
@include p;
|
|
}
|
|
|
|
&:hover .box {
|
|
border-color: var(--theme-contrast);
|
|
}
|
|
|
|
&.is-checked .box {
|
|
background: var(--theme-contrast);
|
|
border-color: var(--theme-contrast);
|
|
|
|
.check {
|
|
opacity: 1;
|
|
transform: none;
|
|
}
|
|
}
|
|
|
|
&.is-disabled {
|
|
opacity: 0.3;
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
</style>
|