Proofs of how the buttons are shown.

This commit is contained in:
2026-02-16 09:13:46 +01:00
parent baa43de4e1
commit bc1d5a2796
15 changed files with 6764 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
<script setup>
import { computed } from 'vue'
const props = defineProps({
modelValue: {
type: String,
default: null,
},
options: {
type: Array,
required: true,
},
name: {
type: String,
required: true,
},
disabled: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:modelValue'])
const handleChange = (value) => {
emit('update:modelValue', value)
}
const getSegmentClasses = (index) => {
const classes = [
'px-6',
'py-3',
'text-sm',
'font-medium',
'select-none',
'transition-colors',
'bg-primary',
'text-gray-900',
'cursor-pointer',
'hover:bg-primary-dark',
'peer-checked:bg-primary-dark',
'peer-checked:text-gray-900',
'peer-focus-visible:ring-2',
'peer-focus-visible:ring-primary-dark',
'peer-focus-visible:ring-offset-2',
'peer-focus-visible:ring-offset-surface',
]
// First segment
if (index === 0) {
classes.push('rounded-l-lg')
}
// Last segment
if (index === props.options.length - 1) {
classes.push('rounded-r-lg')
}
// All except last: add divider
if (index < props.options.length - 1) {
classes.push('border-r', 'border-primary-dark/40')
}
// Disabled state
if (props.disabled) {
classes.push('disabled:opacity-50', 'disabled:cursor-not-allowed')
}
return classes.join(' ')
}
</script>
<template>
<div role="radiogroup" :aria-label="name" class="inline-flex">
<label
v-for="(option, index) in options"
:key="option.value"
class="relative"
>
<input
type="radio"
:name="name"
:value="option.value"
:checked="modelValue === option.value"
:disabled="disabled"
:data-cy="option.value === 'not_applicable' ? 'na' : option.value"
@change="handleChange(option.value)"
class="sr-only peer"
/>
<span :class="getSegmentClasses(index)">
{{ option.label }}
</span>
</label>
</div>
</template>