Layout, Headers, and Cells
Grouped customization API
Section titled “Grouped customization API”Use the grouped customization API when you need precise control over generated scheduler surfaces.
grid.eventScheduler = { view: 'week', weekStartDate: '2026-06-08', customization: { columnSizes: { week: { timeColumnSize: 96, dayColumnSize: 220, }, resourceTimeline: { resourceColumnSize: 260, timelineColumnSize: 144, }, }, headers: { dayTemplate: (h, context) => h('span', { class: 'scheduler-day-header' }, context.defaultLabel), dayProperties: (context) => ({ class: context.today ? 'scheduler-day-header--brand-today' : '', 'data-scheduler-date': context.date, }), groupTemplate: (h, context) => h('strong', { class: 'scheduler-range-header' }, context.defaultLabel), }, cells: { resourceProperties: ({ resource }) => ({ 'data-resource-role': resource?.role, }), timelineProperties: ({ date, slotIndex }) => ({ class: 'scheduler-timeline-slot', 'data-scheduler-slot-key': `${date}:${slotIndex}`, }), }, events: { properties: ({ event }) => ({ 'data-event-status': event.status, }), content: (h, { event, resource }) => h('span', { class: 'scheduler-event-title' }, [ h('strong', {}, event.title), h('small', {}, resource?.name ?? 'Unassigned'), ]), badge: (h, context) => h('span', { class: `scheduler-event-chip scheduler-event-chip--${context.kind}`, }, context.label), resizeHandle: (h, context) => h('span', { class: `scheduler-event-resize scheduler-event-resize--${context.edge}`, }), }, createPreview: { createRangeTemplate: (context) => `${context.title}: ${context.startLabel}-${context.endLabel}`, createRangeProperties: () => ({ class: 'scheduler-create-preview' }), }, conflicts: { className: ({ severity }) => `scheduler-conflict scheduler-conflict--${severity}`, indicator: (h, context) => h('span', { class: 'scheduler-conflict-badge' }, context.severity), tooltip: ({ label }) => `Review before saving: ${label}`, }, emptyState: { template: ({ kind, label }) => `${kind}: ${label}`, properties: ({ kind }) => ({ class: `scheduler-state scheduler-state--${kind}`, }), }, },};Template hooks receive RevoGrid's h helper and a scheduler context object. Return a string, a VNode, null, or undefined. Returning null or undefined keeps the built-in section. Property hooks return attributes, class, style, or data attributes for the target element.
Custom properties are merged with built-in scheduler properties. Built-in interaction handlers and scheduler data attributes remain in place, so custom hooks should not attach drag, resize, selection, or mutation behavior directly.
Column sizes
Section titled “Column sizes”customization.columnSizes controls scheduler-owned column widths by view. These values are resolved before legacy top-level size props such as timeColumnSize, dayColumnSize, resourceColumnSize, and timelineColumnSize.
grid.eventScheduler = { view: 'resourceTimeline', weekStartDate: '2026-06-08', customization: { columnSizes: { week: { timeColumnSize: 88, dayColumnSize: 180, }, resourceTimeline: { resourceColumnSize: 280, timelineColumnSize: 120, }, }, },};Use week sizes for day, week, and month style calendar grids. Use resource timeline sizes when the first column is the pinned resource column and the remaining columns are timeline slots.
Header templates and properties
Section titled “Header templates and properties”Header customization targets the generated scheduler columns. For day headers, use the direct week-scheduler hooks when you only need day-header customization. Use customization.headers when you need to customize every generated header type.
Direct day-header hooks:
| Hook | Surface |
| --- | --- |
| dayHeaderFormatter | Formats the built-in day header label. |
| dayHeaderTemplate | Replaces the day header content. |
| dayHeaderProperties | Adds classes, styles, attributes, data fields, or event handlers to day headers. |
grid.eventScheduler = { view: 'week', weekStartDate: '2026-06-08', dayHeaderFormatter: (date) => date.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', timeZone: 'UTC', }), dayHeaderTemplate: (h, context) => h('span', { class: 'planner-day-header' }, [ h('span', { class: 'planner-day-header__label' }, context.defaultLabel), context.today ? h('span', { class: 'planner-day-header__badge' }, 'Today') : null, context.holiday ? h('span', { class: 'planner-day-header__holiday' }, context.holidayLabel) : null, h('span', { class: 'planner-day-header__count' }, `${context.eventCount ?? 0} events`), ]), dayHeaderProperties: (context) => ({ class: [ context.today ? 'planner-day-header--today' : '', context.weekend ? 'planner-day-header--weekend' : '', context.holiday ? 'planner-day-header--holiday' : '', ].filter(Boolean).join(' '), style: { '--planner-day-event-count': context.eventCount ?? 0, ...(context.holiday ? { '--planner-day-state': 'holiday' } : {}), }, 'data-planner-day': context.date, }),};Day header context includes defaultLabel, date, dayIndex, eventCount, today, weekend, holiday, and holidayLabel. Holiday state is date-level: it comes from the primary scheduler calendar or global kind: 'holiday' availability entries. Resource-specific holidays stay on the scheduler body cells.
customization.headers.dayTemplate takes precedence over dayHeaderTemplate when both are provided. This lets applications keep older grouped customization config while adding direct day-header hooks where convenient.
Grouped header customization has one template hook and one matching properties hook per generated header section.
| Hook | Surface |
| --- | --- |
| timeTemplate / timeProperties | Pinned time header in day/week/month style views. |
| resourceTemplate / resourceProperties | Pinned resource header in resource timeline views. |
| dayTemplate / dayProperties | Day header cells. |
| timelineTemplate / timelineProperties | Resource timeline slot headers. |
| groupTemplate / groupProperties | Grouped range/day/timeline headers when column grouping is enabled. |
grid.eventScheduler = { view: 'week', weekStartDate: '2026-06-08', customization: { headers: { dayTemplate: (h, context) => h('span', { class: 'brand-day-header' }, [ h('strong', {}, context.defaultLabel), context.today ? h('small', {}, 'Today') : null, context.holiday ? h('small', {}, context.holidayLabel) : null, context.eventCount ? h('small', {}, `${context.eventCount} events`) : null, ]), dayProperties: (context) => ({ class: [ context.today ? 'brand-day-header--today' : '', context.weekend ? 'brand-day-header--weekend' : '', context.holiday ? 'brand-day-header--holiday' : '', ], 'data-brand-date': context.date, }), }, },};Header contexts include the active view, the default label, date or slot fields where relevant, event counts, today/weekend/holiday flags, holiday labels, and group kind for grouped headers.
Cell templates and properties
Section titled “Cell templates and properties”Cell customization targets the scheduler body cells. Use property hooks when you only need classes, styles, or test/data attributes. Use templates when the default cell body should be replaced.
Use the direct time-axis hooks when the product only needs to control the pinned time column in day, week, or month-style views.
| Config | Purpose |
| --- | --- |
| timeLabelFormatter | Formats built-in time text such as 06:00, 6 AM, or 6:00. |
| timeLabelTemplate | Replaces the pinned time-label cell content. |
| timeRowProperties | Adds classes, styles, attributes, data fields, or event handlers to time-label cells. |
| timeRange | Sets the visible start/end time and hides time outside that range. |
| slotMinutes | Sets row granularity, for example 5, 10, 15, 30, or 60. |
| rowSize | Controls row density in pixels. |
| nonWorkingTime | Styles closed or outside-business-hours cells in the scheduler body. |
grid.eventScheduler = { view: 'week', weekStartDate: '2026-06-08', timeRange: { start: '06:00', end: '22:00' }, slotMinutes: 30, rowSize: 40, timeLabelFormatter: (minutes) => { const hour = Math.floor(minutes / 60); const minute = minutes % 60; return `${hour % 12 || 12}:${String(minute).padStart(2, '0')} ${hour < 12 ? 'AM' : 'PM'}`; }, timeLabelTemplate: (h, context) => h('span', { class: 'planner-time-label' }, context.timeLabel), timeRowProperties: (context) => ({ class: context.currentTimeLabel ? 'planner-time-row--current' : 'planner-time-row', style: { '--planner-time-start': context.startMinutes, }, 'data-planner-time': context.timeLabel, }), nonWorkingTime: { enabled: true, workingDays: [1, 2, 3, 4, 5], workingHours: { start: '08:00', end: '18:00' }, className: 'planner-closed-hours', },};customization.cells.timeTemplate and customization.cells.timeProperties layer over the direct timeLabelTemplate and timeRowProperties hooks when both are provided. Use rowSize for compact, dense, or comfortable density presets, and use timeRange when night hours should be hidden from the grid instead of only styled as closed.
| Hook | Surface |
| --- | --- |
| timeTemplate / timeProperties | Time-label rows in week-style grids. |
| dayTemplate / dayProperties | Day/time slots in week-style grids. |
| resourceTemplate / resourceProperties | Resource rows in resource timeline grids. |
| resourceGroupTemplate / resourceGroupProperties | Group rows when resource grouping is enabled. |
| timelineTemplate / timelineProperties | Timeline cells in resource timeline grids. |
grid.eventScheduler = { view: 'resourceTimeline', weekStartDate: '2026-06-08', customization: { cells: { resourceProperties: ({ resource, unassigned, depth }) => ({ class: [ resource?.role ? `resource-row--${resource.role.toLowerCase()}` : '', unassigned ? 'resource-row--open-demand' : '', ], style: { '--resource-depth': depth }, 'data-resource-role': resource?.role, }), timelineProperties: ({ date, slotIndex, segmentCount }) => ({ class: segmentCount > 0 ? 'timeline-slot--busy' : 'timeline-slot--open', 'data-slot-key': `${date}:${slotIndex}`, }), }, },};When a cell template is provided, the scheduler renders that template instead of the default cell content for that slot. For day cells, replacing the template also replaces the built-in visible event slices inside that cell, so prefer dayProperties when the goal is only styling or annotation.