Anatomy
All shaduler primitives and how they fit together.
The component file exposes 15 primitives that compose into your scheduler. The expected nesting is:
<Shaduler>
<ShadulerHeader>...optional toolbar...</ShadulerHeader>
<ShadulerContent>
<ShadulerColumnsHeader gridTemplateColumns={calc.gridTemplateColumns}>
<ShadulerCorner />
{columns.map((c, i) => (
<ShadulerColumnHeader key={c.id} column={c} columnIndex={i} />
))}
</ShadulerColumnsHeader>
{/* Optional: multi-day all-day events */}
<ShadulerAllDayStrip
columns={columns}
tasks={allDayEvents}
gridTemplateColumns={calc.gridTemplateColumns}
/>
<ShadulerGrid
gridTemplateColumns={calc.gridTemplateColumns}
gridTemplateRows={calc.gridTemplateRows}
>
<ShadulerTimeColumn rows={calc.rows} startTime={8} endTime={19} />
<ShadulerCells rows={calc.rows} columns={columns} hourHeight={60} />
<ShadulerTasksOverlay
taskPositions={calc.taskPositions}
columns={columns}
startHour={8}
endHour={19}
/>
</ShadulerGrid>
</ShadulerContent>
</Shaduler>Primitives
Layout
Shaduler— root wrapper. Applies the shadcn-themed border, background, and rounded card. Carriesdata-slot="shaduler"for theming hooks. Accepts any<div>props.ShadulerHeader— optional sticky top strip for toolbars (date picker, view switcher). No default content; pass children. Skip it if you don't need one.ShadulerContent— scroll wrapper. Holds everything below the header and owns the vertical / horizontal overflow.ShadulerGrid— the CSS grid that owns column and row tracks. PassgridTemplateColumnsandgridTemplateRowsfromcalculateShadulerData(...).
Header row
ShadulerColumnsHeader— sticky horizontal strip above the grid. Holds the corner cell plus one header per resource. Accepts eithercolumns(renders defaults) or children for full control.ShadulerColumnHeader— one header cell, takes aShadulerColumnandcolumnIndex. Renderscolumn.labelby default; pass children to customize the markup.ShadulerCorner— sticky top-left freeze cell (above the time column, left of the column headers). Empty by default.
Time axis
ShadulerTimeColumn— sticky-left column with hour labels. Passcalculations.rowsfor partial-row support, orstartTime/endTimefor simple integer-hour ranges.timeFormat='12h'and BCP 47localeswitch between 24h/12h and locale-aware formatting viaIntl.DateTimeFormat.ShadulerTimeSlot— one row inside the time column. Usually generated byShadulerTimeColumn; render it directly only if you need to opt out of the default iteration.
Cells (background grid)
ShadulerCell— one background cell at(columnIndex, hourIndex). WireonCellPointerDownto react to clicks — the handler receives{ hour, minute, column }already snapped totimeInterval(default 15 minutes).ShadulerCells— convenience iterator. Passrows+columns+hourHeightand it renders a<ShadulerCell>for every (row, column) pair. UsecellPropsto spread shared props onto every cell (e.g.useShadulerRangeSelect().getCellProps());getCellPropsForis the per-cell escape hatch.
Tasks
ShadulerTask— one positioned task. ReadspositionfromcalculateShadulerData(...).taskPositionsand absolute-positions itself inside<ShadulerTasksOverlay>. Supportsvariant(default/secondary/outline/destructive), plus the gesture wiresonResizeStart,onTaskDragStart,isDragging,isSelecting, anddragHandleOnlyfor touch UX.ShadulerTasksOverlay— pointer-transparent layer that spans the resource columns. PasstaskPositionsand either children (custom render) orcolumns(default<ShadulerTask>per item). Children can be a function(taskPositions, columns) => ReactNodefor fine-grained control.
All-day strip
ShadulerAllDayStrip— optional row between the columns header and the hourly grid for multi-day events (vacations, workshops, holidays). Lane assignment is computed automatically viacalculateAllDayPositions(columns, tasks). Pass children for custom rendering, or let it default to<ShadulerAllDayTask>per item.ShadulerAllDayTask— one bar inside the strip. Reads its placement from anAllDayPosition. PassonClickto make it interactive.
Continue with Hooks →