107 lines
1.9 KiB
Vue
107 lines
1.9 KiB
Vue
<template>
|
|
<div
|
|
:class="[
|
|
cn.b(),
|
|
cn.is('checked', checked),
|
|
cn.is('disabled', disabled),
|
|
cn.is('focused', focused),
|
|
cn.is('disabled', disabled),
|
|
]"
|
|
@click="handleChange"
|
|
>
|
|
<p :class="[cn.e('label')]">
|
|
<slot>
|
|
{{ label }}
|
|
</slot>
|
|
</p>
|
|
|
|
<p v-if="caption || $slots.caption" :class="[cn.e('caption')]">
|
|
<slot name="caption">
|
|
{{ caption }}
|
|
</slot>
|
|
</p>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
export interface Props {
|
|
id: string
|
|
value: string | number
|
|
label?: string
|
|
caption?: string
|
|
disabled?: boolean
|
|
modelValue?: string | number
|
|
required?: boolean
|
|
}
|
|
|
|
defineOptions({
|
|
name: 'RadioButton',
|
|
})
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
disabled: false,
|
|
trueValue: true,
|
|
falseValue: false,
|
|
required: false,
|
|
modelValue: undefined,
|
|
})
|
|
const slots = useSlots()
|
|
const { checked, focused, handleChange } = useRadio(props, slots)
|
|
|
|
const cn = useClassname('radio-button')
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.radio-button {
|
|
$self: &;
|
|
|
|
@include txt-i-m;
|
|
|
|
--border-color: #{$clr-grey-300};
|
|
--border-width: 1px;
|
|
|
|
display: inline-flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-direction: column;
|
|
text-align: center;
|
|
height: 48px;
|
|
padding: 8px 16px;
|
|
border-radius: 12px;
|
|
outline: var(--border-width) solid var(--border-color);
|
|
outline-offset: calc(var(--border-width) * -1);
|
|
cursor: pointer;
|
|
transition: .2s ease-out;
|
|
transition-property: outline-color, background-color, color;
|
|
user-select: none;
|
|
|
|
&:hover {
|
|
--border-color: transparent;
|
|
|
|
background-color: $clr-grey-200;
|
|
}
|
|
|
|
&.is-checked {
|
|
--border-color: transparent;
|
|
|
|
background-color: $clr-cyan-500;
|
|
color: $clr-white;
|
|
}
|
|
|
|
&.is-disabled {
|
|
opacity: 0.4;
|
|
pointer-events: none;
|
|
}
|
|
|
|
&__caption {
|
|
@include txt-r-m;
|
|
|
|
color: $clr-cyan-400;
|
|
|
|
#{$self}.is-checked & {
|
|
color: $clr-cyan-300;
|
|
}
|
|
}
|
|
}
|
|
</style>
|