Basic Switch
A labelled on/off switch built on a real checkbox with `role="switch"`, driven entirely by CSS.
3 个框架初级
A grid of selectable cards backed by a radio group, showing a ring and a check on the chosen one.
<!--
Selectable cards are still a radio group underneath - the whole card is the
label, the radio is sr-only. has-[:checked] rings the chosen card and
peer-checked reveals a filled check badge, so "selected" is a ring PLUS a tick,
never colour on its own. Cards stack to one column below sm.
-->
<fieldset class="grid w-full gap-3 sm:grid-cols-2">
<legend class="sr-only">Choose a plan</legend>
<label class="relative flex cursor-pointer flex-col rounded-xl border border-gray-200 bg-white p-4 transition-colors has-[:checked]:border-blue-600 has-[:checked]:ring-2 has-[:checked]:ring-blue-600 has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-blue-500 dark:border-gray-700 dark:bg-gray-900 dark:has-[:checked]:border-blue-400">
<input type="radio" name="plan" value="starter" class="peer sr-only" checked />
<span aria-hidden="true" class="absolute right-3 top-3 flex h-5 w-5 items-center justify-center rounded-full bg-blue-600 text-white opacity-0 peer-checked:opacity-100">
<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2.5" class="h-3 w-3"><path d="M4 10l4 4 8-9" stroke-linecap="round" stroke-linejoin="round" /></svg>
</span>
<span class="text-sm font-semibold text-gray-900 dark:text-white">Starter</span>
<span class="mt-1 text-xs text-gray-500 dark:text-gray-400">$9 / month</span>
</label>
<label class="relative flex cursor-pointer flex-col rounded-xl border border-gray-200 bg-white p-4 transition-colors has-[:checked]:border-blue-600 has-[:checked]:ring-2 has-[:checked]:ring-blue-600 has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-blue-500 dark:border-gray-700 dark:bg-gray-900 dark:has-[:checked]:border-blue-400">
<input type="radio" name="plan" value="pro" class="peer sr-only" />
<span aria-hidden="true" class="absolute right-3 top-3 flex h-5 w-5 items-center justify-center rounded-full bg-blue-600 text-white opacity-0 peer-checked:opacity-100">
<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2.5" class="h-3 w-3"><path d="M4 10l4 4 8-9" stroke-linecap="round" stroke-linejoin="round" /></svg>
</span>
<span class="text-sm font-semibold text-gray-900 dark:text-white">Pro</span>
<span class="mt-1 text-xs text-gray-500 dark:text-gray-400">$29 / month</span>
</label>
</fieldset>| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
legend必填 | string | - | Legend |
name必填 | string | - | 作为标题显示的套餐名称。 |
options必填 | { value: string; title: string; detail: string }[] | - | Options |
defaultValue | string | - | Default value |
onChange | (value: string) => void | - | On change |
`has-[:checked]` rings the selected card while `peer-checked` reveals a filled check badge, so "selected" is a ring plus a tick - never colour on its own. Cards collapse from two columns to one below `sm`.