Proofs of how the buttons are shown.
BIN
resources/images/Growth_symbol/Growth Symbol Charcoal EPS.eps
Normal file
BIN
resources/images/Growth_symbol/Growth Symbol Charcoal JPEG.jpg
Normal file
|
After Width: | Height: | Size: 704 KiB |
BIN
resources/images/Growth_symbol/Growth Symbol Charcoal PNG.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
resources/images/Growth_symbol/Growth Symbol REV EPS.eps
Normal file
BIN
resources/images/Growth_symbol/Growth Symbol REV PNG.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
6669
resources/images/Growth_symbol/Growth Symbol_Outline_Charcoal AI.ai
Normal file
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 28 KiB |
BIN
resources/images/Growth_symbol/Transparency 15%.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
resources/images/Growth_symbol/Transparency 40%.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
95
resources/js/Components/RadioButtonGroup.vue
Normal 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>
|
||||