Ir al contenido

radio —— Botón de radio

La semántica del botón de radio es «de un grupo, solo uno está activo». core/radio la abstrae a la comprobación más simple: ¿el valor actual del grupo modelValue es igual a mi value? A diferencia de la operación de conjuntos de checkbox, el botón de radio es una comparación de un solo valor.

  • Cada framework implementa LhRadio y LhRadioGroup (el grupo mantiene modelValue y cada elemento deduce de él su propio estado seleccionado).
  • Selección excluyente: sexo, forma de pago, ramas de formulario estilo pestañas.
  • No usarlo para: selección múltiple, usa checkbox; un conmutador, switch; una conmutación segmentada, segmented (visualmente más ligero).
import { isRadioChecked, getRadioClassNames } from '@lh-ui/share/core/radio'
import type { LhRadioState } from '@lh-ui/share/core/radio'

isRadioChecked usa Object.is(modelValue, value) y no ===, por la misma razón que checkbox: coherencia en la semántica de conjuntos con NaN / -0 y «que cualquier tipo de valor pueda servir de clave de selección única».

El botón de radio no necesita una función toggle — seleccionar es asignar (modelValue = value); esa es la diferencia matemática entre selección única y selección múltiple (la asignación de una variable frente a la inserción y el borrado en un conjunto).

Función Firma Devuelve Función
isRadioChecked (state: LhRadioState) => boolean booleano Object.is(modelValue, value)
getRadioClassNames (type: string) => string[] array de clases lh-radio + modificador de tipo
getRadioClassNames('primary') // ['lh-radio', 'lh-radio--primary']
getRadioClassNames('') // ['lh-radio']
export interface LhRadioState {
modelValue: unknown // valor actual del grupo
value: unknown // el valor de este radio
checked: boolean
}

Al igual que con checkbox: usa el <input type="radio"> nativo; la semántica, el teclado y el envío del formulario salen gratis. La propiedad name es clave en el botón de radio — los radios de un mismo grupo deben compartir name, ya que la navegación con flechas del navegador (las arrow keys se mueven dentro del grupo) depende de ella.

// El lector de pantalla anuncia el texto del label + el estado «seleccionado/no seleccionado»;
// el radio nativo lo cubre todo
import { isRadioChecked, getRadioClassNames } from '@lh-ui/share/core/radio'
isRadioChecked({ modelValue: 'b', value: 'b', checked: false }) // true
isRadioChecked({ modelValue: 'b', value: 'a', checked: false }) // false
<!-- Vue3 -->
<div class="lh-radio-group" :class="`lh-radio-group--${size}`">
<label
v-for="opt in options"
:key="String(opt.value)"
:class="getRadioClassNames(type)"
:class-mod="{ 'lh-radio--checked': isRadioChecked({ modelValue, value: opt.value, checked: false }) }"
>
<span class="lh-radio__box">
<input
class="lh-radio__input"
type="radio"
:name="groupName"
:checked="modelValue === opt.value"
@change="emit('update:modelValue', opt.value)"
/>
</span>
<span class="lh-radio__label">{{ opt.label }}</span>
</label>
</div>
// React
const [value, setValue] = useState('a')
return options.map((opt) => (
<label key={opt.value} className="lh-radio">
<input
type="radio"
name={groupName}
checked={value === opt.value}
onChange={() => setValue(opt.value)}
/>
<span className="lh-radio__label">{opt.label}</span>
</label>
))
// uniapp: <radio-group> + <radio> son componentes integrados y el evento change entrega
// directamente el value de la opción seleccionada; ten en cuenta que el value del radio
// de uniapp solo admite cadenas
Clase Semántica
.lh-radio clase base
.lh-radio--checked / --disabled estados
.lh-radio--{small|large} tamaños
.lh-radio__box círculo personalizado del radio (sobrescribe la apariencia nativa)
.lh-radio__input input nativo (oculto visualmente, conserva la semántica)
.lh-radio__label texto
.lh-radio-group / --{small|large} contenedor del grupo

El punto interior del estado seleccionado usa var(--lh-primary-color); el estado desactivado, --lh-text-disabled.

  • El parámetro type y el tamaño del checkbox-group son dos cosas distintas: lo que getRadioClassNames(type) emite para el radio es un modificador de tipo (como primary); el modificador de tamaño va en el grupo (lh-radio-group--{size}).
  • El name debe ser el mismo en todo el grupo: si no, la navegación por teclado del navegador (el movimiento con flechas dentro del grupo) deja de funcionar y, al enviar el formulario, se envían varios valores.
  • El valor inicial de modelValue: debería ser el value de alguna opción o undefined (nada seleccionado). Dar un valor que no está entre las opciones deja todos los radios sin seleccionar y, además, no se puede recuperar desde la UI.
  • Tanto el radio como segmented sirven para una conmutación excluyente: el radio tiene semántica de «control de formulario» (nativo, submisible) y segmented, de «cambio de vista» (más ligero, más parecido a un grupo de botones).
@lh-ui/share/core/radio → getRadioClassNames( )
返回值
(填好参数后点运行)

Copyright © 2024-2026 FengMo WenXue