shaduler

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. Carries data-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. Pass gridTemplateColumns and gridTemplateRows from calculateShadulerData(...).

Header row

  • ShadulerColumnsHeader — sticky horizontal strip above the grid. Holds the corner cell plus one header per resource. Accepts either columns (renders defaults) or children for full control.
  • ShadulerColumnHeader — one header cell, takes a ShadulerColumn and columnIndex. Renders column.label by 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. Pass calculations.rows for partial-row support, or startTime / endTime for simple integer-hour ranges. timeFormat='12h' and BCP 47 locale switch between 24h/12h and locale-aware formatting via Intl.DateTimeFormat.
  • ShadulerTimeSlot — one row inside the time column. Usually generated by ShadulerTimeColumn; render it directly only if you need to opt out of the default iteration.

Cells (background grid)

  • ShadulerCell — one background cell at (columnIndex, hourIndex). Wire onCellPointerDown to react to clicks — the handler receives { hour, minute, column } already snapped to timeInterval (default 15 minutes).
  • ShadulerCells — convenience iterator. Pass rows + columns + hourHeight and it renders a <ShadulerCell> for every (row, column) pair. Use cellProps to spread shared props onto every cell (e.g. useShadulerRangeSelect().getCellProps()); getCellPropsFor is the per-cell escape hatch.

Tasks

  • ShadulerTask — one positioned task. Reads position from calculateShadulerData(...).taskPositions and absolute-positions itself inside <ShadulerTasksOverlay>. Supports variant (default / secondary / outline / destructive), plus the gesture wires onResizeStart, onTaskDragStart, isDragging, isSelecting, and dragHandleOnly for touch UX.
  • ShadulerTasksOverlay — pointer-transparent layer that spans the resource columns. Pass taskPositions and either children (custom render) or columns (default <ShadulerTask> per item). Children can be a function (taskPositions, columns) => ReactNode for 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 via calculateAllDayPositions(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 an AllDayPosition. Pass onClick to make it interactive.

Continue with Hooks

On this page