Calendar View
El calendario de iCloud en vista de mes, semana y día: hoy en el círculo del acento, chips de todo el día, eventos con hora y la línea roja de ahora.
import { CalendarView } from "sebs7n-ui/calendar-view"Ejemplos
Mes
La vista de mes de iCloud: hoy en el círculo del acento, los eventos de todo el día como chips y los que tienen hora con su punto. Hacé foco en un día y probá las flechas, Home/End y PageUp/PageDown.
import { CalendarView } from "sebs7n-ui/calendar-view"
function Mes() {
const events = useSampleEvents()
return (
<div className="h-[640px] w-full overflow-hidden rounded-surface border border-separator">
<CalendarView events={events} hour12={false} locale="es-AR" />
</div>
)
}Semana
Filas de una hora de 61, bloques con el borde izquierdo del color del calendario, la fila «Todo el día» arriba y la línea roja de ahora. Los eventos que se pisan se reparten el ancho.
import { CalendarView } from "sebs7n-ui/calendar-view"
function Semana() {
const events = useSampleEvents()
return (
<div className="h-[560px] w-full overflow-hidden rounded-surface border border-separator">
<CalendarView defaultView="week" events={events} hour12={false} locale="es-AR" />
</div>
)
}Día
La semana con una sola columna: la fila «Todo el día», las horas de 61, los eventos con su borde de color y la línea de ahora. ‹ › pasan de a un día y el teclado es el mismo.
import { CalendarView } from "sebs7n-ui/calendar-view"
function Dia() {
const events = useSampleEvents()
return (
<div className="h-[560px] w-full overflow-hidden rounded-surface border border-separator">
<CalendarView defaultView="day" events={events} hour12={false} locale="es-AR" />
</div>
)
}Idioma global
Con `LabelsProvider` `dates` (`en-US`, semana del domingo) no hace falta pasarle `locale` ni `weekStartsOn`.
import { CalendarView } from "sebs7n-ui/calendar-view"
import { LabelsProvider } from "sebs7n-ui/labels"
function IdiomaGlobal() {
const events = useSampleEvents()
return (
<LabelsProvider value={{ dates: { locale: "en-US", weekStartsOn: 0 } }}>
<div className="h-[640px] w-full overflow-hidden rounded-surface border border-separator">
<CalendarView events={events} />
</div>
</LabelsProvider>
)
}Props
Generadas del TypeScript del paquete. Las propias del componente, más las heredadas del primitivo que tienen algo que explicar —marcadas «heredada de Base UI»—. El resto está en la línea «hereda de».
CalendarView
Hereda las props de <div>.
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
date | Date | — | El día activo: el mes o la semana que se ve y dónde está el foco. Pasarlo lo vuelve controlado. |
defaultDate | Date | — | El día activo al arrancar. Por defecto, hoy. |
defaultView | "month" | "week" | "day" | "month" | La vista al arrancar. Por defecto month. |
events | CalendarEvent[] | [] | Los eventos: { id, title, start, end?, allDay?, color? } (color de la paleta de Badge, por defecto la marca). |
hour12 | boolean | — | false fuerza 24 horas; true, 12. Por defecto, el locale. |
labels | Partial<Labels["calendarView"]> | — | Textos: today, view, month, week, day, previous*/next* de mes, semana y día, allDay, weekOf y more. Los de Día, por defecto, son calendarViewDayLabels. |
locale | string | — | El locale de los nombres de meses y días y de las horas. |
now | Date | — | El momento actual, para hoy y la línea de ahora. Por defecto, el reloj del navegador. |
onDateChange | (date: Date) => void | — | Se llama con el día activo nuevo (flechas, ‹ ›, Hoy, click). |
onDayOpen | (date: Date) => void | — | Enter o doble click sobre un día. |
onEventClick | (event: CalendarEvent) => void | — | Click en un evento. |
onViewChange | (view: CalendarViewMode) => void | — | Se llama con la vista nueva. |
scrollToHour | number | 8 | La hora que queda arriba al abrir una semana (o un día) que no incluye hoy. Por defecto, 8. |
view | "month" | "week" | "day" | — | month, week o day. Pasarla la vuelve controlada. |
weekStartsOn | 0 | 1 | — | 1 lunes (default) o 0 domingo. |
className | string | — | Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana. |
Teclado
- F2
- Con
onEventClick, entra a los eventos del día activo: ↓ ↑ los recorren, Enter o Espacio abren el evento, Escape (o F2) vuelve al día. En la semana entran los de todo el día; los de hora y los que quedan en «+N más» se llegan con Enter (onDayOpen). - Tab
- Recorre el segmentado de la vista, ‹ Hoy › y entra a la grilla en el día activo (una sola parada).
- ← → (en el segmentado)
- Mueven entre Día, Semana y Mes; Enter o Espacio la elige. Es un
tablistde una sola opción, el segmentado gris de Calendar. - ← →
- El día anterior o siguiente (cruza de mes o de semana; en el día, cambia de día).
- ↑ ↓
- En el mes, la misma fecha una semana antes o después.
- Home End
- El primer y el último día de la semana (también en el día).
- PageUp PageDown
- El mes anterior o siguiente (en la semana y el día, una semana). Con Shift, un año (en la semana y el día, un mes).
- Enter · Espacio
- Abre el día (
onDayOpen): mostrar sus eventos o crear uno.
Accesibilidad
- El mes o la semana nueva se anuncia (región
status) al cambiarla con ‹ Hoy ›; con el teclado en la grilla no, porque el foco ya dice la fecha de la celda. - Los días son un
role="grid"nombrado por el mes («Septiembre 2026»), la semana o el día («martes, 29 de septiembre de 2026»), concolumnheaderde los días ygridcellcon foco itinerante. El día es la misma grilla que la semana, con una sola columna. - Cada celda se lee con la fecha completa («martes, 29 de septiembre de 2026») y sus eventos; el número grande es decorativo. Hoy lleva
aria-current="date"y el activoaria-selected. - En la semana, los bloques con hora están fuera de las celdas (en la escala de horas,
aria-hidden): cada celda de «Todo el día» repite para el lector los eventos del día con su hora. - El título del mes es un
h2conaria-live="polite": al cambiar de mes, el lector lo anuncia. - Los eventos son botones (con
onEventClick) fuera del orden de Tab: la grilla es una sola parada. Con teclado, Enter en el día llama aonDayOpen, que tiene que mostrar los eventos de ese día (unPopovercon unaList, por ejemplo). - El color del calendario nunca es el único dato: el título del evento está siempre escrito.
- ‹ y › se llaman «Mes anterior»/«Mes siguiente» (o semana, o día), desde el
LabelsProvider(calendarView). Los de la vista Día (day,previousDay,nextDay) son opcionales en el tipo: sus valores por defecto soncalendarViewDayLabels. Un provider armado antes de R9, sin esas claves (o con ellas enundefined), no rompe nada: la vista Día cae al español por defecto hasta que las traduzcas. Lo mismo vale para cualquier clave enundefined, en el provider o enlabels: no pisa el texto de abajo.
Reglas de uso
- Idioma y semana para toda la app:
<LabelsProvider value={{ dates: { locale: "en-US", weekStartsOn: 0 } }}>(tambiénformatpara el campo deDatePicker). Lo leenCalendar,DatePicker,DateTimePickeryCalendarView; la prop de cada uno gana. - Con SSR, pasá `now` o `defaultDate` (la fecha del request): sin ellas el calendario no puede saber qué día es hoy hasta montar, y se dibuja invisible hasta entonces para que el server y el cliente coincidan.
- Para ver fechas con cosas encima: vencimientos, cobros, turnos. Para elegir una fecha, es
CalendaroDatePicker. - Los eventos son datos (
events):{ id, title, start, end?, allDay?, color? }. El componente no crea ni arrastra eventos:onDayOpenyonEventClickson para que la app lo haga. nowpara tests y para servidores con otro huso: sin él, hoy y la línea de ahora salen del reloj del navegador después de montar (no hay desfase de hidratación).hour12={false}fuerza 24 horas; por defecto manda el locale.- El alto lo pone quien lo contiene: el mes reparte las filas y la semana y el día scrollean las horas (abren en la hora de ahora, o en
scrollToHour). - Día para una agenda apretada: los turnos o cobros de hoy con su horario. Es la semana con una columna: los eventos que se pisan se reparten el ancho igual.
- Arrastrar eventos no está. Solo por subpath (
sebs7n-ui/calendar-view): no está en el barrel, por peso.