forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
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>