Sizing & Mobile
The scheduler fills the height it is given and scrolls inside it, and it measures its own width to decide when to switch to a layout made for a phone. Neither needs a media query from you.
Three Layouts
Three arrangements cover every page, and the common one needs no number at all. The frame below stands in for a page: a header, and a scheduler that takes the rest.
Oct 19 – 25, 2026
<!-- The rest of the page: a flex column, and the scheduler takes what is left.
min-h-0 lets it shrink below its content so it scrolls inside instead of
stretching the page. -->
<div class="flex h-dvh flex-col">
<header class="h-14 shrink-0 border-b">App header</header>
<Scheduler bind:events class="min-h-0 flex-1" />
</div>Which one
| Layout | How |
|---|---|
The rest of the page | Flex column; the scheduler gets min-h-0 flex-1 |
Grows with its content | Nothing: no height on it or any parent |
A fixed size | height={640}, height="70dvh", or a parent with a height |
Growing With Content
Without a bounded height the scheduler is as tall as its content. For the month and the agenda that is a few hundred pixels; for the week view it is the whole day, about 1150px plus headers, because the grid has no reason to hide any hour. Fine in a long article, rarely what a page wants for its main calendar.
<!-- No height anywhere: each view grows to its content. The week view is the
full day at 48 slots of 24px, about 1150px plus headers. -->
<article>
<h1>Season programme</h1>
<p>...</p>
<Scheduler bind:events view="month" />
<p>...</p>
</article>A Fixed Size
height takes pixels or any CSS length. Sizing the parent works the same way, since the scheduler fills
it. Every demo on these pages uses one or the other.
October 2026
<!-- A card, a tile, a modal: pixels or any CSS length -->
<Scheduler bind:events height={640} />
<Scheduler bind:events height="70dvh" />
<!-- Or size the parent and let the scheduler fill it -->
<div class="h-[32rem]">
<Scheduler bind:events />
</div>The Compact Layout
Below compactBreakpoint, 640px of the scheduler's own width, the calendar rearranges itself for touch. The number
is the scheduler's width rather than the viewport's, so a calendar in a narrow panel of a
wide page gets the same treatment as one on a phone. Drag the slider to watch it switch.
Oct 19 – 25, 2026
<!-- Below 640px of scheduler width the compact layout switches on by itself.
The number is the scheduler's own width, not the viewport's. -->
<Scheduler bind:events />
<!-- Show the whole week on phones anyway -->
<Scheduler bind:events compactDays={null} />
<!-- Switch earlier or later -->
<Scheduler bind:events compactBreakpoint={720} />
<!-- Never switch -->
<Scheduler bind:events compactBreakpoint={0} />What changes
| Part | Compact |
|---|---|
Toolbar | Today as an icon, arrows, short title, a view menu; every control at least 36px |
Week view | compactDays days from date, 3 by default; the arrows step by that many |
Event details | A slide-over inside the calendar |
Month cells | Day numbers only |
Everything else | Unchanged: the same gestures, the same keys |
Four Thresholds
Four widths decide the layout, and only two of them are props. The month grid has a density threshold of its own, measured on the grid rather than the scheduler, so a wide scheduler with a docked sidebar can still get the dense month. The popover rule is the one exception that reads the viewport: on a narrow screen there is no room beside an event, so the card opens below it and never pushes the page sideways.
Thresholds
| What | Measured against |
|---|---|
Compact layout | compactBreakpoint, 640px of the scheduler |
Month cell density | 768px of the month grid |
Sidebar | sidebarBreakpoint, 1024px of the scheduler |
Popover side | 768px of the viewport |
Touch
A tap does what a click does. A drag starts after a press of 300 milliseconds, so a finger that swipes across the grid scrolls the page as it should, and one that rests on an event picks it up. While a drag is in progress the context menu is suppressed and the grid scrolls itself when the finger nears an edge. Escape from an attached keyboard cancels.
The Sidebar Below Its Breakpoint
The sidebar docks beside the view while the scheduler is at least sidebarBreakpoint wide, 1024px by default, and becomes a slide-over behind the toolbar's menu button below that.
Picking a date in the slide-over closes it. This docs column is 884px wide, so the demos here
lower the breakpoint to keep the sidebar docked; drag the slider under it to see the switch. See Sidebar.
Oct 19 – 25, 2026
A Toolbar of Your Own on Phones
A toolbar snippet receives compact and can rearrange itself on the same switch. A registered view can offer a shortTitle for the narrow bar, the way the built-in week view shortens Sep 14 – 20, 2026 to Sep 14 – 16.
<!-- A toolbar snippet receives the same switch, so it can follow the built-in one -->
<Scheduler bind:events toolbar={header} />
{#snippet header({ title, step, today, view, views, setView, compact })}
<div class="flex items-center gap-2 px-3 py-2">
<Button icon="lucide:chevron-left" size={compact ? 'md' : 'sm'} onclick={() => step(-1)} />
<Button icon="lucide:chevron-right" size={compact ? 'md' : 'sm'} onclick={() => step(1)} />
<h2 class={compact ? 'text-sm' : 'text-lg'}>{title}</h2>
{#if compact}
<Select items={views.map(({ name, label }) => ({ value: name, label }))} value={view} onValueChange={setView} />
{:else}
<ToggleGroup items={views.map(({ name, label }) => ({ value: name, label }))} value={view} onValueChange={setView} />
{/if}
</div>
{/snippet}
<!-- A view of your own can offer a shorter title for the compact toolbar -->
const workWeek: ViewDefinition = {
name: 'workweek',
title: (anchor, range, ctx) => `Week of ${format(range.start)}`,
shortTitle: (anchor, range) => format(range.start),
/* ... */
};Props
The props that decide how the scheduler fits its box.
| Prop | Type | Default |
|---|---|---|
height | number | string | - |
compactBreakpoint | number | 640 |
compactDays | number | null | 3 |
sidebarBreakpoint | number | 1024 |
detail | 'popover' | 'slideover' | false | 'popover' |
toolbar | boolean | Snippet<[ToolbarSnippetProps]> | true |
Snippets
What the snippets on this page receive. Every type is exported from @sv5ui/scheduler.
| Type | Fields |
|---|---|
ToolbarSnippetProps | title, date, range, view, views, scheduler, step, today, navigate, setView, toggleSidebar, sidebarOpen, compact |