[READ-ONLY] a fast, modern browser for the npm registry
at main 45 lines 1.4 kB view raw
1<script setup lang="ts"> 2const model = defineModel<string>() 3 4const props = defineProps<{ 5 disabled?: boolean 6 /** 7 * type should never be used, because this will always be a radio button. 8 * 9 * If you want a link use `TagLink` instead. 10 * */ 11 type?: never 12 13 /** Shouldn't try to set `checked` explicitly, is handled internally */ 14 checked?: never 15 value: string 16}>() 17 18const uid = useId() 19const internalId = `${model.value}-${uid}` 20const checked = computed(() => model.value === props.value) 21/** Todo: This shouldn't be necessary, but using v-model on `input type=radio` doesn't work as expected in Vue */ 22const onChange = () => { 23 model.value = props.value 24} 25</script> 26 27<template> 28 <div> 29 <input 30 type="radio" 31 :id="internalId" 32 :value="props.value" 33 :checked="checked" 34 :disabled="props.disabled ? true : undefined" 35 @change="onChange" 36 class="peer sr-only" 37 /> 38 <label 39 class="bg-bg-muted text-fg-muted border-border hover:(text-fg border-border-hover) inline-flex items-center px-2 py-0.5 text-xs font-mono border rounded transition-colors duration-200 peer-focus-visible:(outline-2 outline-accent/70 outline-offset-2) border-none peer-checked:(bg-fg text-bg border-fg hover:(text-text-bg/50)) peer-disabled:(opacity-50 pointer-events-none)" 40 :htmlFor="internalId" 41 > 42 <slot /> 43 </label> 44 </div> 45</template>