Slots API
La Slots API te permite reemplazar cualquier sub-componente con el tuyo propio. Los componentes slot reciben props tipados — construye UIs completamente personalizadas mientras mantienes la gestion de estado, algoritmos de layout y navegacion del calendario.
Pasa tus componentes personalizados via la prop slots:
<Calendar events={events} slots={{ toolbar: MiToolbarPersonalizado, dayCell: MiCeldaDeDia, timeEvent: MiEventoTemporal, allDayEvent: MiEventoDeDiaCompleto, popover: MiPopover, agendaEvent: MiEventoAgenda, }}/>Slots disponibles
Sección titulada «Slots disponibles»| Slot | Props | Usado en |
|---|---|---|
toolbar | ToolbarSlotProps | Todas las vistas |
dayCell | DayCellSlotProps | Vista de mes |
timeEvent | TimeEventSlotProps | Vista de semana/dia |
allDayEvent | AllDayEventSlotProps | Vista de semana/dia |
popover | PopoverSlotProps | Todas las vistas |
agendaEvent | AgendaEventSlotProps | Vista de agenda |
resourceHeader | ResourceHeaderSlotProps | Vistas de recursos (dia/semana con recursos) |
Referencia de props de slots
Sección titulada «Referencia de props de slots»ToolbarSlotProps
Sección titulada «ToolbarSlotProps»interface ToolbarSlotProps { currentDate: DateString; view: CalendarView; onPrev: () => void; onNext: () => void; onToday: () => void; onViewChange: (view: CalendarView) => void; formattedDate: string; // Titulo con formato de locale, ej: "marzo 2026" customButtons: CustomButton[]; // Botones del prop customButtons canGoPrev: boolean; // false cuando se alcanza el inicio de validRange canGoNext: boolean; // false cuando se alcanza el fin de validRange}DayCellSlotProps
Sección titulada «DayCellSlotProps»interface DayCellSlotProps { date: DateString; isToday: boolean; isCurrentMonth: boolean; events: CalendarEvent[];}TimeEventSlotProps
Sección titulada «TimeEventSlotProps»interface TimeEventSlotProps { event: CalendarEvent; positioned: PositionedEvent; // positioned.column: indice de columna (base 0) // positioned.totalColumns: total de columnas en grupo de solapamiento // positioned.top: posicion % desde arriba // positioned.height: altura en %}AllDayEventSlotProps
Sección titulada «AllDayEventSlotProps»interface AllDayEventSlotProps { event: CalendarEvent; segment: EventSegment; // segment.date: la fecha de este segmento // segment.isStart: primer dia del evento // segment.isEnd: ultimo dia del evento}PopoverSlotProps
Sección titulada «PopoverSlotProps»interface PopoverSlotProps { event: CalendarEvent; onClose: () => void;}AgendaEventSlotProps
Sección titulada «AgendaEventSlotProps»interface AgendaEventSlotProps { event: CalendarEvent;}ResourceHeaderSlotProps
Sección titulada «ResourceHeaderSlotProps»interface ResourceHeaderSlotProps { resource: Resource; // resource.id: identificador unico // resource.title: nombre para mostrar // resource.color: color opcional}Ejemplos
Sección titulada «Ejemplos»Toolbar personalizado
Sección titulada «Toolbar personalizado»import type { ToolbarSlotProps, CalendarView } from "trud-calendar";
function MiToolbar({ formattedDate, view, onPrev, onNext, onToday, onViewChange, customButtons, canGoPrev, canGoNext,}: ToolbarSlotProps) { return ( <div className="flex items-center justify-between p-4 border-b"> <div className="flex gap-2"> <button onClick={onPrev} disabled={!canGoPrev}>Anterior</button> <button onClick={onToday}>Hoy</button> <button onClick={onNext} disabled={!canGoNext}>Siguiente</button> </div> <h2 className="text-lg font-bold">{formattedDate}</h2> <div className="flex gap-2"> <select value={view} onChange={(e) => onViewChange(e.target.value as CalendarView)} > <option value="month">Mes</option> <option value="week">Semana</option> <option value="day">Dia</option> <option value="agenda">Agenda</option> <option value="year">Ano</option> </select> {customButtons.map((btn) => ( <button key={btn.key} onClick={btn.onClick}> {btn.text} </button> ))} </div> </div> );}
<Calendar events={events} slots={{ toolbar: MiToolbar }} />Celda de dia personalizada (vista mes)
Sección titulada «Celda de dia personalizada (vista mes)»import type { DayCellSlotProps } from "trud-calendar";
function MiCeldaDeDia({ date, isToday, isCurrentMonth, events }: DayCellSlotProps) { return ( <div className={`p-2 min-h-[80px] ${ isToday ? "bg-blue-50 border-blue-300" : "" } ${!isCurrentMonth ? "opacity-30" : ""}`} > <div className="font-bold">{new Date(date).getDate()}</div> {events.map((e) => ( <div key={e.id} className="text-xs truncate" style={{ color: e.color }}> {e.title} </div> ))} </div> );}Evento de agenda personalizado
Sección titulada «Evento de agenda personalizado»import type { AgendaEventSlotProps } from "trud-calendar";
function MiEventoAgenda({ event }: AgendaEventSlotProps) { return ( <div className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-50"> <div className="w-3 h-3 rounded-full" style={{ backgroundColor: event.color }} /> <div> <div className="font-medium">{event.title}</div> <div className="text-sm text-gray-500"> {event.description || "Sin descripcion"} </div> </div> </div> );}