Skip to content

Instantly share code, notes, and snippets.

@naillizard
Last active June 7, 2021 23:47
Show Gist options
  • Save naillizard/c68e4c8879675096f2a98b344175c53d to your computer and use it in GitHub Desktop.
Save naillizard/c68e4c8879675096f2a98b344175c53d to your computer and use it in GitHub Desktop.
Tailwind headless ui radio group component
<template>
<RadioGroup v-model="selected">
<RadioGroupLabel v-if="label" class="block font-medium text-sm text-gray-700">{{ label }}</RadioGroupLabel>
<div class="space-y-2 mt-1">
<RadioGroupOption
v-for="option in options"
:key="option.name"
v-slot="{ active, checked }"
:value="option"
as="template"
@click="$emit('update:modelValue', option.value)"
>
<div
:class="[
active
? 'ring-2 ring-offset-2 ring-offset-indigo-300 ring-white ring-opacity-60'
: '',
checked
? 'bg-indigo-900 bg-opacity-75 text-white'
: 'bg-white ',
]"
class="relative flex px-5 py-4 rounded-lg shadow-md cursor-pointer focus:outline-none"
>
<div class="flex items-center justify-between w-full">
<div class="flex items-center">
<div class="text-sm">
<RadioGroupLabel
:class="checked ? 'text-white' : 'text-gray-900'"
as="p"
class="font-medium"
>
{{ option.name }}
</RadioGroupLabel>
<RadioGroupDescription
:class="checked ? 'text-indigo-100' : 'text-gray-500'"
as="span"
class="inline"
>
<span class="text-xs"> {{ option.description }}</span>
</RadioGroupDescription>
</div>
</div>
<div v-show="checked" class="flex-shrink-0 text-white">
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24">
<circle
cx="12"
cy="12"
fill="#fff"
fill-opacity="0.2"
r="12"
/>
<path
d="M7 13l3 3 7-7"
stroke="#fff"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
/>
</svg>
</div>
</div>
</div>
</RadioGroupOption>
</div>
</RadioGroup>
</template>
<script>
import {reactive} from 'vue'
import {RadioGroup, RadioGroupDescription, RadioGroupLabel, RadioGroupOption,} from '@headlessui/vue'
export default {
props: {
modelValue: Number,
defaultSelected: {
type: Number,
default: 0
},
label: {
type: String,
default: ''
},
options: {
type: Array,
required: true,
},
},
emits: ['update:modelValue'],
components: {
RadioGroup,
RadioGroupLabel,
RadioGroupDescription,
RadioGroupOption,
},
setup(props) {
const selected = reactive(props.options[props.modelValue])
return {selected}
},
}
</script>
/** this is a simplified page, submiting the form unchecks the selected option, the form.status is */
<template>
<app-radio-group id="status" v-model="form.status" :default-selected="form.status" :options="availableStatuses" label="Status"/>
</template>
<script>
import AppRadioGroup from "@/Components/AppRadioGroup"
export default {
props: ['game', 'availableStatuses'],
components: {
AppRadioGroup,
},
data() {
return {
form: {
status: this.game.status
}
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment