Ir al contenido
Contenido y datos

CalendarView

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>.

PropTipoPor defectoDescripción
dateDate—El día activo: el mes o la semana que se ve y dónde está el foco. Pasarlo lo vuelve controlado.
defaultDateDate—El día activo al arrancar. Por defecto, hoy.
defaultView"month" | "week" | "day""month"La vista al arrancar. Por defecto month.
eventsCalendarEvent[][]Los eventos: { id, title, start, end?, allDay?, color? } (color de la paleta de Badge, por defecto la marca).
hour12boolean—false fuerza 24 horas; true, 12. Por defecto, el locale.
labelsPartial<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.
localestring—El locale de los nombres de meses y días y de las horas.
nowDate—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.
scrollToHournumber8La 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.
weekStartsOn0 | 1—1 lunes (default) o 0 domingo.
classNamestring—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 tablist de 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»), con columnheader de los días y gridcell con 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 activo aria-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 h2 con aria-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 a onDayOpen, que tiene que mostrar los eventos de ese día (un Popover con una List, 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 son calendarViewDayLabels. Un provider armado antes de R9, sin esas claves (o con ellas en undefined), no rompe nada: la vista Día cae al español por defecto hasta que las traduzcas. Lo mismo vale para cualquier clave en undefined, en el provider o en labels: 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én format para el campo de DatePicker). Lo leen Calendar, DatePicker, DateTimePicker y CalendarView; 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 Calendar o DatePicker.
  • Los eventos son datos (events): { id, title, start, end?, allDay?, color? }. El componente no crea ni arrastra eventos: onDayOpen y onEventClick son para que la app lo haga.
  • now para 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.

Relacionados