componentes / date-picker
DatePicker
Campo que abre un Calendar para elegir un día.
Cómo usar
Un botón con aspecto de `Input` muestra el día elegido y abre un `Calendar`; elegir un día lo cierra. La fecha no se escribe (para una fecha escrita, usa un `Input` con `mask="date"`). Con `name`, el formulario recibe `yyyy-mm-dd`. El foco entra en el día al abrir y vuelve al campo con `Esc`.
preview
DatePicker.tsx
import { DatePicker } from "vaiperui"; const [date, setDate] = useState<Date>(); <DatePicker label="Fecha de entrega" value={date} onValueChange={setDate} /><DatePicker label="Fecha de entrega" minDate={new Date()} weekStartsOn={1} locale="es-ES"/>Tamaños
preview
tamanos.tsx
<DatePicker size="sm" /><DatePicker size="md" /><DatePicker size="lg" />Estados
preview
Detalle extra
Esto es obligatorio
estados.tsx
<DatePicker label="..." helperText="..." /><DatePicker label="..." errorMessage="..." /><DatePicker label="..." disabled /><DatePicker label="..." readOnly />Límites
preview
limites.tsx
<DatePicker label="..." minDate={new Date(2026, 9, 10)} maxDate={new Date(2026, 9, 25)} />Colores
preview
colores.tsx
<DatePicker variantColor="success" /><DatePicker customColor="#ff6600" />Props
| Prop | Valores | Predeterminado | Descripción |
|---|---|---|---|
| value / defaultValue | Date | ninguno | Día elegido, controlado o inicial |
| onValueChange | (date: Date) => void | ninguno | Se llama cuando se elige un día |
| label / helperText | string | ninguno | Etiqueta sobre el campo y texto de ayuda debajo |
| errorMessage | string | ninguno | Texto de error; su sola presencia fuerza el estado de error |
| placeholder | string | del idioma | Texto cuando no se eligió nada (p. ej. dd/mm/aaaa) |
| name | string | ninguno | Nombre del campo del formulario |
| disabled / readOnly | boolean | false | No abre el panel; readOnly aún muestra el valor |
| variant | ring | outline | ring | Estilo de foco, igual que Input |
| size / radius | sm | md | lg / none | sm | md | lg | full | md / md | Altura del campo y redondeo de las esquinas |
| aria-label | string | ninguno | Nombre accesible cuando no hay etiqueta |
| panelLabel | string | ninguno | Nombre accesible del panel abierto |
| minDate / maxDate | Date | ninguno | Primer y último día permitidos; el resto y las flechas de mes que llevan fuera quedan deshabilitados |
| locale | string | "en-US" | Idioma de los nombres de mes/día y formato de la fecha (BCP 47) |
| weekStartsOn | 0 – 6 | 0 | Primer día de la semana (0 = domingo) |
| previousMonthLabel / nextMonthLabel | string | "Previous month" / "Next month" | Nombres accesibles de los botones de mes |
| variantColor / customColor / animation | primary | success | warning | danger / CSS color / none | smooth | fast | bounce | primary / smooth | Color de la selección y del foco, y velocidad de la transición |
Accesibilidad
- El disparador es un `<button>` con `aria-haspopup="dialog"` y `aria-expanded` que refleja el estado del panel.
- El `label` se enlaza con `htmlFor`; sin `label`, el disparador usa `aria-label`.
- `errorMessage` define `aria-invalid` y `aria-describedby` apuntando al mensaje; sin error, `helperText` se enlaza con `aria-describedby`.
- El panel es un `role="dialog"` nombrado por `panelLabel`, renderizado en un portal en `document.body`.
- `disabled` deshabilita el botón; `readOnly` mantiene el foco posible, pero el panel nunca se abre.
- Al abrir, el foco va al día seleccionado (o hoy) en el `Calendar`, que sigue su patrón de cuadrícula.
Teclado
| Tecla | Acción |
|---|---|
| Enter / Space | Abre o cierra el panel desde el disparador. |
| Arrow keys, Home, End, Page Up/Down | Navegan por los días dentro del panel abierto (ver Calendar); Enter o Espacio en un día lo elige y cierra el panel. |
| Esc | Cierra el panel y devuelve el foco al disparador. |
Ten en cuenta
- El panel no atrapa el foco: Tab sale de él y, como se renderiza al final de `<body>`, Tab desde el disparador no entra en él por sí solo.
- Hacer clic fuera cierra el panel sin devolver el foco; solo Esc restaura el foco en el disparador.
- La fecha no se puede escribir: la única forma de definirla es el calendario. Usa `Input` con `mask="date"` para fechas escritas.