Premium Widgets
Custom Calendar Grid
CalendarGrid en React
Muestra citas en una vista mensual y selecciona días o entradas.
Referencia para @arcrider/arcwidgets-react@0.1.0-alpha.5. <a href="/docs/react/intro/setup-react">Instalación</a> · <a href="/docs/react/intro/react-components">Todos los componentes</a>.
Ejemplo completo
import { ArcWidgetCalendarGrid } from '@arcrider/arcwidgets-react';
import { useState } from 'react';
const lang = document.documentElement.lang.startsWith('en') ? 'en' : document.documentElement.lang.startsWith('es') ? 'es' : 'de'; const requested = new URLSearchParams(location.search).get('data'); const pack = requested === 'empty' || requested === 'busy' ? requested : 'demo'; const t = (de: string, en: string, es: string) => lang === 'en' ? en : lang === 'es' ? es : de; const locale = lang === 'en' ? 'en-US' : lang === 'es' ? 'es-ES' : 'de-DE';
const chrome = { backgroundColor: '#ffffff', fontColor: '#18181b', mutedColor: '#52525b', subtleColor: '#71717a', borders: { color: '#e4e4e7', outer: true, columns: true, rows: true }, };
const look = (backgroundColor: string, color: string) => ({ backgroundColor, color, fontColor: color, });
type Entry = { id: string; title: string; dateFrom: number; dateTo: number; timeFrom: number; timeTo: number; clickable: true; draggable: true; styles: ReturnType<typeof look>; };
const event = ( id: string, title: string, day: number, backgroundColor: string, color: string, ): Entry => ({ id, title, dateFrom: new Date(2026, 8, day).getTime(), dateTo: new Date(2026, 8, day).getTime(), timeFrom: 9 * 3600000, timeTo: 11 * 3600000, clickable: true, draggable: true, styles: look(backgroundColor, color), });
const demoEntries: Entry[] = [ event( 'travel-out', t('Anfahrt', 'Travel there', 'Ida'), 16, '#99f6e4', '#115e59', ), event( 'visit', t('Hauptarbeit', 'On site', 'Trabajo principal'), 17, '#ccfbf1', '#115e59', ), event( 'travel-back', t('Abfahrt', 'Travel back', 'Vuelta'), 18, '#99f6e4', '#115e59', ), event( 'review', t('Projekt-Review', 'Project review', 'Revisión'), 21, '#ede9fe', '#5b21b6', ), event( 'ship', t('Lieferung', 'Delivery', 'Entrega'), 24, '#fef3c7', '#92400e', ), ];
const busyEntries: Entry[] = [ ...demoEntries, event('kickoff', t('Kickoff', 'Kickoff', 'Kickoff'), 3, '#d1fae5', '#065f46'), event('fair', t('Messe', 'Fair', 'Feria'), 8, '#ffe4e6', '#9f1239'), event('retro', t('Retro', 'Retro', 'Retro'), 28, '#e0f2fe', '#075985'), ];
export default function Example() { const [month, setMonth] = useState(9); const [entries, setEntries] = useState( pack === 'empty' ? [] : pack === 'busy' ? busyEntries : demoEntries, ); const [selected, setSelected] = useState( t( 'Termin ziehen oder anklicken', 'Drag or click an event', 'Arrastra o pulsa un evento', ), ); return ( <> <button onClick={() => setMonth((m) => (m === 1 ? 12 : m - 1))}> {t('Vorheriger Monat', 'Previous month', 'Mes anterior')} </button> <button onClick={() => setMonth((m) => (m === 12 ? 1 : m + 1))}> {t('Nächster Monat', 'Next month', 'Mes siguiente')} </button> <ArcWidgetCalendarGrid id="month" data={{ timeZoneBalance: 0, height: '480px', lang, styles: chrome, dateSettings: { month, year: 2026, day: { clickable: true }, }, timeEntries: entries, }} onDayClick={(date) => setSelected(new Date(date).toLocaleDateString(locale)) } onEntryClick={(index) => setSelected(entries[index]?.title ?? selected)} onEntryDragSave={(index, start) => { setEntries((previous) => previous.map((entry, i) => i === index ? { ...entry, dateFrom: Number(start.dateFrom ?? entry.dateFrom), dateTo: Number(start.dateTo ?? entry.dateTo), } : entry, ), ); setSelected(t('Termin verschoben', 'Event moved', 'Evento movido')); }} /> <p aria-live="polite">{selected}</p> </> ); }</code></pre>
Props del componente
id
ID opcional y estable de la instancia del widget. Sin especificarlo, React genera un ID.
data
Configuración de tipo ArcWidgetCalendarGridData. Pasa los cambios como objetos nuevos; gestiona los datos de negocio y la selección en el estado de React.
onAction
Fallback opcional (type: string, ...args: unknown[]) => unknown. El callback concreto tiene prioridad. Detalles: <a href="/docs/react/patterns/react-state-events">Estado y eventos</a>.
onEntryClick
Índice de la cita, y en Timeline también la fila del recurso.
onEntryClick?: (entry_index: number) => void;
onDayClick
Fecha del día seleccionado como marca de tiempo en milisegundos.
onDayClick?: (date_millis: number) => void;
onEntryDragSave
Fin del arrastre con los datos originales. No hay horas de destino completas nuevas; consulta las notas sobre persistencia.
onEntryDragSave?: (entry_index: number, start_data: ArcWidgetCalendarGridDragStart) => void;
onDailyEntryDragSave
Fin del arrastre de una cita de todo el día con los datos originales.
onDailyEntryDragSave?: (entry_index: number, start_data: ArcWidgetCalendarGridDragStart) => void;
Configuración
Los siguientes campos pertenecen a data. Los tamaños se indican como strings, los números y valores de tiempo según su tipo respectivo.
height
Altura del widget, p. ej. "320px". Los valores porcentuales necesitan un contenedor padre con altura definida.
Tipo: string.
timeZoneBalance
Corrección en horas; los ejemplos usan 0 y valores de día generados localmente.
Tipo: number | string.
styles
Colores, espaciados y bordes comunes; los campos ofrecidos son específicos del widget.
Tipo: ArcWidgetCalendarGridStyles | string.
dateSettings
Rango de fechas, cabeceras y marcados.
El tipo y los campos anidados están en ArcWidgetCalendarGridData, bajo tipos de datos.
timeSettings
Rango horario y cuadrícula; las unidades son milisegundos.
Tipo: Record<string, unknown>.
lang
Idioma de las etiquetas del calendario.
Tipo: string.
timeEntries
Citas con valores de fecha, horas y contenidos.
El tipo y los campos anidados están en ArcWidgetCalendarGridData, bajo tipos de datos.
Comportamiento y límites
- Para JSX en citas usa
customLayout. Los campos estándar title, subtitle y value se procesan como texto o HTML.
- Los valores de fecha son marcas de tiempo en milisegundos; las horas son milisegundos desde el inicio del día. Consulta <a href="/docs/react/patterns/react-dates">Fecha y hora</a>.
clickable: true activa la selección. Un índice de callback no es un ID de registro; resuélvelo mediante tu lista actual de entradas.
- Los callbacks de arrastre actuales contienen el estado original (
start_data), pero no horas de destino completas nuevas. Por eso el ejemplo establece draggable: false. Edita las citas mediante el estado de React hasta que exista un contrato de persistencia completo para arrastrar y soltar.
dateSettings.month empieza en uno: enero es 1. Los marcados están en dateSettings.highlights.
Los campos ArcWidgetSlot admitidos permiten elementos JSX individuales, texto o descriptores de widget. Pasa texto externo como texto JSX; los strings HTML se interpretan como HTML. <a href="/docs/react/patterns/nested-widget-descriptors">Combinar contenidos</a>.
Tipos de datos
Estos tipos relacionados con el widget se exportan desde el paquete. También están disponibles tipos comunes como ArcWidgetSlot, ArcWidgetStyles y ArcReactWidgetProps. Las firmas de índice permiten extensiones; no garantizan que el widget evalúe campos arbitrarios.
export interface ArcWidgetCalendarGridDay {
clickable?: boolean;
height?: string;
alignX?: string;
backgroundColor?: string;
hoverBackgroundColor?: string;
padding?: string;
[key: string]: unknown;
}
export interface ArcWidgetCalendarGridDragStart { dateFrom?: unknown; dateTo?: unknown; timeFrom?: unknown; timeTo?: unknown; }
export type ArcWidgetCalendarGridBorderLine = boolean | { color?: string; width?: string; borderColor?: string; borderWidth?: string; borderSize?: string; enabled?: boolean; };
export interface ArcWidgetCalendarGridBorders { color?: string; width?: string; outer?: ArcWidgetCalendarGridBorderLine; columns?: ArcWidgetCalendarGridBorderLine; rows?: ArcWidgetCalendarGridBorderLine; }
export interface ArcWidgetCalendarGridStyles extends ArcWidgetStyles { borders?: ArcWidgetCalendarGridBorders; headerBackgroundColor?: string; mutedColor?: string; subtleColor?: string; }
export interface ArcWidgetCalendarGridData extends Omit<ArcWidgetBaseData, 'actions'> { height?: string; timeZoneBalance?: number | string; styles?: ArcWidgetCalendarGridStyles | string; dateSettings?: { month?: number; year?: number; day?: ArcWidgetCalendarGridDay; highlights?: Array<{ date?: unknown; color?: string; [key: string]: unknown }>; [key: string]: unknown; }; timeSettings?: Record<string, unknown>; lang?: string; timeEntries?: Array<{ id?: string | number; title?: string; subtitle?: string; value?: string; customLayout?: ArcWidgetSlot; dateFrom?: unknown; dateTo?: unknown; timeFrom?: unknown; timeTo?: unknown; styles?: ArcWidgetStyles | string; clickable?: boolean; draggable?: boolean; [key: string]: unknown; }>; }
export interface ArcWidgetCalendarGridProps extends ArcReactWidgetProps<ArcWidgetCalendarGridData> { onEntryClick?: (entry_index: number) => void; onDayClick?: (date_millis: number) => void; onEntryDragSave?: (entry_index: number, start_data: ArcWidgetCalendarGridDragStart) => void; onDailyEntryDragSave?: (entry_index: number, start_data: ArcWidgetCalendarGridDragStart) => void; }</code></pre>