ProductionApplies toLite and Pro
Migrating from Lite to Pro
Install the Pro tarball as `super-scheduler`, change the imports and the stylesheet from `super-scheduler-lite` to `super-scheduler`, and write out Lite's defaults, because Pro's defaults differ (one day of hourly cells, editing on, keyboard off). The component name, ISO date strings, resource and event fields and the basic options carry over. Replace Lite's `onTimeRangeClick` with `onTimeRangeSelected`, then enable Pro features one at a time.
Lite and Pro share their component name, their civil date model and their basic data shapes, so a Lite view moves to Pro with a handful of edits. The differences that matter are the defaults, a few callbacks and the styling tokens. This guide converts a Lite view to an equivalent read-only Pro view first, then adds Pro features one by one, so each step can be tested on its own.
What stays the same
| Area | Shared by Lite and Pro |
|---|---|
| Component | SuperSchedulerComponent, with ref.current.control and controlRef |
| Dates | Civil ISO strings with seconds, half-open intervals, SuperScheduler.Date and SchedulerDate with the same methods |
| Resources | { id, name }, ids compared strictly (1 and '1' differ) |
| Events | id, resource, start, end, text, backColor, fontColor, cssClass, toolTip, tags |
| Options | startDate, days, scale: 'Day', cellWidth, height, rowHeaderWidth, rowMinHeight, eventHeight, locale, emptyState |
| Control | update(), scrollTo(), scrollToResource(), visibleStart(), visibleEnd(), dispose(), disposed() |
| Callback | onEventClick({ e }) with e.data |
Everything Lite accepts has a Pro counterpart except ariaLabel (see below). Pro options such as treeEnabled or zoomLevels, which Lite rejects with "unsupported option", work once you switch.
Switch the package
Pro is installed from a versioned HTTPS tarball under the package name super-scheduler. Remove Lite unless another part of your app still uses it:
npm uninstall super-scheduler-lite
npm install https://npm.superscheduler.org/pro/YOUR_DOWNLOAD_KEY/0.1.0.tgzpackage.json then lists the URL and your lockfile records its integrity. The key in that URL is a download secret: it appears in package.json and the lockfile, so treat both accordingly. Install SuperScheduler Pro covers keys, CI and upgrades. Pro lists React and React DOM (18.2 or later, or 19) as peer dependencies.
Update imports, styles and defaults
Here is a Lite view:
import { useState } from 'react'
import { SuperSchedulerComponent } from 'super-scheduler-lite'
import type { SuperScheduler } from 'super-scheduler-lite'
import 'super-scheduler-lite/styles.css'
const ROOMS: SuperScheduler.ResourceData[] = [
{ id: 'r101', name: 'Room 101' },
{ id: 'r102', name: 'Room 102' },
]
const EVENTS: SuperScheduler.EventData[] = [
{
id: 'b-1042',
resource: 'r101',
start: '2026-10-02T14:00:00',
end: '2026-10-05T11:00:00',
text: 'Ana Ruiz',
backColor: '#dbeafe',
},
{
id: 'b-1043',
resource: 'r102',
start: '2026-10-03T14:00:00',
end: '2026-10-08T11:00:00',
text: 'Tom Berg',
backColor: '#dcfce7',
},
]
/** Before: the read-only Lite view. */
export function Availability() {
const [picked, setPicked] = useState('')
return (
<>
<p aria-live="polite">{picked}</p>
<SuperSchedulerComponent
startDate="2026-10-01"
resources={ROOMS}
events={EVENTS}
ariaLabel="Room availability"
onEventClick={({ e }) => setPicked(`Booking ${String(e.data.id)}`)}
onTimeRangeClick={({ start, resource }) =>
setPicked(`Free: ${String(resource)} on ${start.toString('d MMM')}`)
}
/>
</>
)
}And the same view on Pro:
import { useCallback, useState } from 'react'
import { SuperSchedulerComponent } from 'super-scheduler'
import type {
SchedulerEventClickArgs,
SchedulerTimeRangeSelectedArgs,
SuperScheduler,
} from 'super-scheduler'
import 'super-scheduler/styles.css'
const ROOMS: SuperScheduler.ResourceData[] = [
{ id: 'r101', name: 'Room 101' },
{ id: 'r102', name: 'Room 102' },
]
const EVENTS: SuperScheduler.EventData[] = [
{
id: 'b-1042',
resource: 'r101',
start: '2026-10-02T14:00:00',
end: '2026-10-05T11:00:00',
text: 'Ana Ruiz',
backColor: '#dbeafe',
},
{
id: 'b-1043',
resource: 'r102',
start: '2026-10-03T14:00:00',
end: '2026-10-08T11:00:00',
text: 'Tom Berg',
backColor: '#dcfce7',
},
]
// Lite draws one header row with "d MMM" per day.
const TIME_HEADERS: SuperScheduler.TimeHeaderData[] = [{ groupBy: 'Day', format: 'd MMM' }]
/** After: the same view on Pro, still read-only. */
export function Availability() {
const [picked, setPicked] = useState('')
// Pro splices the events array it receives: give it its own copy.
const [events] = useState(() => EVENTS.slice())
const onEventClick = useCallback((args: SchedulerEventClickArgs) => {
setPicked(`Booking ${String(args.e.id())}`)
}, [])
// Lite's onTimeRangeClick fires for any empty cell. In Pro, clicking an empty cell selects it;
// Pro's own onTimeRangeClick fires only for a click on a range that is already selected.
const onTimeRangeSelected = useCallback((args: SchedulerTimeRangeSelectedArgs) => {
args.control.clearSelection()
if (args.origin !== 'click' && args.origin !== 'keyboard') return
setPicked(`Free: ${String(args.resource)} on ${args.start.toString('d MMM')}`)
}, [])
return (
// Pro has no ariaLabel option: name the region around it.
<section aria-label="Room availability">
<p aria-live="polite">{picked}</p>
<SuperSchedulerComponent
// Lite's defaults, written out: Pro's defaults differ.
startDate="2026-10-01"
days={31}
scale="Day"
cellWidth={64}
heightSpec="Fixed"
height={400}
rowHeaderWidth={160}
rowHeaderWidthAutoFit={false}
rowMinHeight={40}
eventHeight={26}
timeHeaders={TIME_HEADERS}
emptyState="No resources"
// Read-only, as in Lite: Pro enables dragging, resizing and zoom gestures by default.
eventMoveHandling="Disabled"
eventResizeHandling="Disabled"
zoomGesture={false}
// Keyboard navigation is built into Lite and opt-in in Pro.
keyboardEnabled
keyboardTarget="component"
keyboardMode="Full"
resources={ROOMS}
events={events}
onEventClick={onEventClick}
onTimeRangeSelected={onTimeRangeSelected}
/>
</section>
)
}You should see the same rooms, bookings and colors, the same messages on click, and no dragging. The grid uses your page's font instead of Lite's 13 px system font, and Pro's theme colors.
The edits, in order:
- Imports:
super-scheduler-litebecomessuper-scheduler, andsuper-scheduler-lite/styles.cssbecomessuper-scheduler/styles.css. - Defaults: write out every Lite default you relied on (table below).
- Behavior: disable what Pro turns on by default, enable keyboard support.
- Callbacks: move cell clicks to
onTimeRangeSelected. - Data: give the control its own copy of the events array, because Pro splices the array it receives when events change. Lite treats its arrays as read-only.
| Option | Lite default | Pro default |
|---|---|---|
days | 31 | 1 |
scale | 'Day' (the only value) | 'CellDuration' with cellDuration: 60, hourly cells |
cellWidth | 64 | 40 |
height | 400, fixed | 600, a maximum (heightSpec: 'Max'): the grid shrinks to its rows |
rowHeaderWidth | 160 | 80, and rowHeaderWidthAutoFit: true grows it to the names |
rowMinHeight | 40 | 0 |
eventHeight | 26 | 35 |
emptyState | 'No resources' | none |
ariaLabel | 'Resource schedule' | not available |
| Time header | one row, d MMM | [{ groupBy: 'Default' }, { groupBy: 'Cell' }] |
Pro has no ariaLabel option: its grid has a built-in accessible name. Put the label on the region that contains it, as the example does with <section aria-label>.
Styles and selectors
Class names and tokens change prefix. Lite's root is .super-scheduler-lite with parts such as .super-scheduler-lite__event; Pro's root is .super-scheduler with .super-scheduler__event, plus [data-super-scheduler-part] markers. Map Lite's six tokens as a starting point:
| Lite token | Pro token |
|---|---|
--super-scheduler-background | --super-scheduler-surface |
--super-scheduler-text | --super-scheduler-text |
--super-scheduler-border | --super-scheduler-border |
--super-scheduler-header | no single equivalent; style the timeHeader slot or .super-scheduler__header |
--super-scheduler-event | --super-scheduler-event-bg (or backColor per event) |
--super-scheduler-focus | --super-scheduler-focus-color and --super-scheduler-focus-ring |
Pro has a richer token set, dark mode and density presets; see Theming.
Behavior that Pro turns on
Lite is read-only by construction. Pro is an editor, so out of the box it:
- moves and resizes events by dragging (
eventMoveHandlingandeventResizeHandlingdefault to'Update'); - selects time ranges on click and drag (
timeRangeSelectedHandling: 'Enabled'), leaving the selection shadow until the next selection, a click elsewhere orclearSelection(); - zooms with Ctrl or Cmd plus the wheel and with pinch gestures (
zoomGesture: true); - leaves keyboard support off (
keyboardEnabled: false), while Lite always has arrow-key navigation. WithkeyboardEnabledPro listens on the whole document unlesskeyboardTargetis'component'.
The Pro example above pins all of these to Lite's behavior. Remove those lines one at a time as you adopt features.
Callbacks with richer arguments
| Lite | Pro |
|---|---|
onEventClick({ control, e: { data }, originalEvent }) | onEventClick({ e, div, control, originalEvent, ctrl, shift, meta, preventDefault }), where e is a SuperScheduler.Event with data, id(), start(), end(), text(), resource() and duration(); then onEventClicked |
onTimeRangeClick({ control, start, end, resource, originalEvent }) on any empty cell | onTimeRangeSelected({ start, end, resource, control, origin, multirange }), with origin 'click', 'drag', 'keyboard' or 'api' |
Other differences to check in your handlers:
- In Pro, handlers run with
thisset to the control, and most arguments includecontrol. - In Lite,
originalEventis aKeyboardEventwhen a cell or event is activated from the keyboard. In Pro, Enter on an event dispatches a click, soonEventClickalways receives aMouseEvent, and Enter on a cell is a selection withorigin: 'keyboard'. controlRefcallbacks are called withnullon unmount in Lite; Pro calls them only with the control and clears ref objects on unmount.scrollTo(date)takes optionalanimatedandpositionarguments in Pro.
When both packages are installed
Some products keep Lite on public pages and use Pro in the back office. That works, with two rules:
- Exchange ISO strings, not date objects. Each edition has its own date class, and Pro rejects a Lite date object.
- Keep their CSS apart. Each package has its own stylesheet. Some token names exist in both (
--super-scheduler-text,--super-scheduler-border), so scope Lite overrides to.super-scheduler-liteinstead of:root.
import { type SuperScheduler as Lite } from 'super-scheduler-lite'
import { SuperScheduler as Pro } from 'super-scheduler'
// Each edition has its own date class. Passing a Lite date object to Pro throws
// ("expected a Date, a SchedulerDate, a number of ticks or an ISO 8601 string").
export function toProDate(date: Lite.Date): Pro.Date {
return new Pro.Date(date.value)
}
// Shared state, URLs and storage hold civil ISO strings, which both editions accept.
export const selectedDay: string = Pro.Date.today().valueImport the two components under different local names when one module needs both, for example import { SuperSchedulerComponent as LiteScheduler } from 'super-scheduler-lite'.
Adopt Pro features step by step
Once the read-only view matches, add one capability at a time and test it:
- Keyboard and accessibility. Keep
keyboardEnabledandkeyboardMode="Full"; see Keyboard, accessibility and touch. - Editing. Remove
eventMoveHandling="Disabled"andeventResizeHandling="Disabled", add rules withonEventMovingandonEventMove, and persist changes fromonEventsChange; see Drag and resize rules and Controlled state. - Creating bookings. Use
onTimeRangeSelectedwithorigin === 'drag'to open a form. - Hours and zoom. Add
zoomLevels, removezoomGesture={false}; see Time scales and zoom. - Rows. Trees, frozen rows, split rows and row header columns; see Trees, columns and selection.
- Modules. Undo and redo, Minimap, Links, Panes and saved views and Range loading.
- React content. Switch the import to
super-scheduler/react-renderwhen you need React inside events or headers; see React render slots.
Hotel room planningA shower leaks in Room 104. Rehouse the next guest, block the room for the plumber and find the nights that are already full. For commercial questions about Pro, see the pricing page.