# Von Lite zu Pro migrieren

> Eine Integration von super-scheduler-lite auf super-scheduler umstellen: was bleibt, welche Standards und Callbacks sich ändern, wie Sie Pro schrittweise nutzen.

Source: https://superscheduler.org/de/docs/migrate-lite-to-pro/
Reviewed: 2026-10-07

Installieren Sie den Pro-Tarball als `super-scheduler`, stellen Sie Imports und Stylesheet von `super-scheduler-lite` auf `super-scheduler` um und schreiben Sie die Standardwerte von Lite explizit aus, denn die Standardwerte von Pro sind andere (ein Tag mit Stundenzellen, Bearbeitung an, Tastatur aus). Komponentenname, ISO-Datums-Strings, Ressourcen- und Ereignisfelder sowie die grundlegenden Optionen bleiben erhalten. Ersetzen Sie `onTimeRangeClick` aus Lite durch `onTimeRangeSelected` und aktivieren Sie dann die Pro-Funktionen eine nach der anderen.

Lite und Pro teilen den Komponentennamen, das Datenmodell mit bürgerlicher Zeit und die grundlegenden Datenstrukturen; eine Lite-Ansicht wechselt daher mit einer Handvoll Änderungen zu Pro. Die Unterschiede, auf die es ankommt, sind die Standardwerte, einige Callbacks und die Styling-Tokens. Diese Anleitung wandelt eine Lite-Ansicht zuerst in eine gleichwertige, schreibgeschützte Pro-Ansicht um und ergänzt dann die Pro-Funktionen nacheinander, sodass sich jeder Schritt für sich testen lässt.

## Was gleich bleibt
| Bereich | Gemeinsam in Lite und Pro |
|---|---|
| Komponente | `SuperSchedulerComponent`, mit `ref.current.control` und `controlRef` |
| Datumswerte | ISO-Strings in bürgerlicher Zeit mit Sekunden, halboffene Intervalle, `SuperScheduler.Date` und `SchedulerDate` mit denselben Methoden |
| Ressourcen | `{ id, name }`, IDs werden strikt verglichen (`1` und `'1'` unterscheiden sich) |
| Ereignisse | `id`, `resource`, `start`, `end`, `text`, `backColor`, `fontColor`, `cssClass`, `toolTip`, `tags` |
| Optionen | `startDate`, `days`, `scale: 'Day'`, `cellWidth`, `height`, `rowHeaderWidth`, `rowMinHeight`, `eventHeight`, `locale`, `emptyState` |
| Control | `update()`, `scrollTo()`, `scrollToResource()`, `visibleStart()`, `visibleEnd()`, `dispose()`, `disposed()` |
| Callback | `onEventClick({ e })` mit `e.data` |

Alles, was Lite akzeptiert, hat ein Gegenstück in Pro, mit Ausnahme von `ariaLabel` (siehe unten). Pro-Optionen wie `treeEnabled` oder `zoomLevels`, die Lite mit „unsupported option“ ablehnt, funktionieren nach dem Wechsel.

## Das Paket wechseln
Pro wird aus einem versionierten HTTPS-Tarball unter dem Paketnamen `super-scheduler` installiert. Entfernen Sie Lite, sofern kein anderer Teil Ihrer App es noch verwendet:

```sh
npm uninstall super-scheduler-lite
npm install https://npm.superscheduler.org/pro/YOUR_DOWNLOAD_KEY/0.1.0.tgz
```

`package.json` führt dann die URL auf, und Ihr Lockfile hält deren Integrität fest. Der Schlüssel in dieser URL ist ein Download-Geheimnis: Er steht in `package.json` und im Lockfile, behandeln Sie also beide entsprechend. [SuperScheduler Pro installieren](https://superscheduler.org/de/docs/install-pro/) behandelt Download-Schlüssel, CI und Upgrades. Pro führt React und React DOM (18.2 oder neuer, oder 19) als Peer-Abhängigkeiten.

## Imports, Styles und Standardwerte anpassen
Hier eine Lite-Ansicht:

```tsx
// src/Availability.tsx (Lite)
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')}`)
        }
      />
    </>
  )
}
```
Und dieselbe Ansicht mit Pro:

```tsx
// src/Availability.tsx (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>
  )
}
```
Sie sollten dieselben Zimmer, Buchungen und Farben sehen, dieselben Meldungen beim Klicken und kein Ziehen. Das Raster verwendet die Schrift Ihrer Seite statt der 13-px-Systemschrift von Lite sowie die Theme-Farben von Pro.

Die Änderungen, der Reihe nach:

1. Imports: Aus `super-scheduler-lite` wird `super-scheduler`, und aus `super-scheduler-lite/styles.css` wird `super-scheduler/styles.css`.
2. Standardwerte: Schreiben Sie jeden Standardwert von Lite aus, auf den Sie sich verlassen haben (Tabelle unten).
3. Verhalten: Deaktivieren Sie, was Pro standardmäßig einschaltet, und aktivieren Sie die Tastaturunterstützung.
4. Callbacks: Verlagern Sie Zellklicks nach `onTimeRangeSelected`.
5. Daten: Geben Sie dem Control eine eigene Kopie des Ereignis-Arrays, denn Pro verändert das übergebene Array per splice, wenn sich Ereignisse ändern. Lite behandelt seine Arrays als schreibgeschützt.

| Option | Standard in Lite | Standard in Pro |
|---|---|---|
| `days` | `31` | `1` |
| `scale` | `'Day'` (der einzige Wert) | `'CellDuration'` mit `cellDuration: 60`, Stundenzellen |
| `cellWidth` | `64` | `40` |
| `height` | `400`, fest | `600`, ein Maximum (`heightSpec: 'Max'`): Das Raster schrumpft auf seine Zeilen |
| `rowHeaderWidth` | `160` | `80`, und `rowHeaderWidthAutoFit: true` verbreitert ihn passend zu den Namen |
| `rowMinHeight` | `40` | `0` |
| `eventHeight` | `26` | `35` |
| `emptyState` | `'No resources'` | keiner |
| `ariaLabel` | `'Resource schedule'` | nicht verfügbar |
| Zeitkopf | eine Zeile, `d MMM` | `[{ groupBy: 'Default' }, { groupBy: 'Cell' }]` |

Pro hat keine Option `ariaLabel`: Sein Raster hat einen eingebauten barrierefreien Namen. Setzen Sie die Beschriftung auf den Bereich, der es enthält, wie es das Beispiel mit `<section aria-label>` tut.

### Styles und Selektoren
Klassennamen und Tokens wechseln das Präfix. Die Wurzel von Lite ist `.super-scheduler-lite` mit Teilen wie `.super-scheduler-lite__event`; die Wurzel von Pro ist `.super-scheduler` mit `.super-scheduler__event`, dazu Markierungen `[data-super-scheduler-part]`. Ordnen Sie die sechs Tokens von Lite als Ausgangspunkt zu:

| Token in Lite | Token in Pro |
|---|---|
| `--super-scheduler-background` | `--super-scheduler-surface` |
| `--super-scheduler-text` | `--super-scheduler-text` |
| `--super-scheduler-border` | `--super-scheduler-border` |
| `--super-scheduler-header` | keine direkte Entsprechung; gestalten Sie den Slot `timeHeader` oder `.super-scheduler__header` |
| `--super-scheduler-event` | `--super-scheduler-event-bg` (oder `backColor` pro Ereignis) |
| `--super-scheduler-focus` | `--super-scheduler-focus-color` und `--super-scheduler-focus-ring` |

Pro hat einen umfangreicheren Satz an Tokens, einen Dark Mode und Dichte-Voreinstellungen; siehe [Theming](https://superscheduler.org/de/docs/theming/).

## Verhalten, das Pro einschaltet
Lite ist von Grund auf schreibgeschützt. Pro ist ein Editor und macht daher ab Werk Folgendes:

- Es verschiebt Ereignisse und ändert ihre Dauer per Ziehen (`eventMoveHandling` und `eventResizeHandling` stehen standardmäßig auf `'Update'`);
- es wählt Zeiträume per Klick und Ziehen aus (`timeRangeSelectedHandling: 'Enabled'`) und lässt den Auswahlschatten bis zur nächsten Auswahl, einem Klick an anderer Stelle oder `clearSelection()` stehen;
- es zoomt mit Ctrl oder Cmd plus Mausrad und mit Pinch-Gesten (`zoomGesture: true`);
- es lässt die Tastaturunterstützung ausgeschaltet (`keyboardEnabled: false`), während Lite immer Navigation mit den Pfeiltasten bietet. Mit `keyboardEnabled` lauscht Pro auf dem ganzen Dokument, sofern `keyboardTarget` nicht `'component'` ist.

Das Pro-Beispiel oben setzt all das auf das Verhalten von Lite fest. Entfernen Sie diese Zeilen eine nach der anderen, während Sie Funktionen übernehmen.

## Callbacks mit umfangreicheren Argumenten
| Lite | Pro |
|---|---|
| `onEventClick({ control, e: { data }, originalEvent })` | `onEventClick({ e, div, control, originalEvent, ctrl, shift, meta, preventDefault })`, wobei `e` ein `SuperScheduler.Event` mit `data`, `id()`, `start()`, `end()`, `text()`, `resource()` und `duration()` ist; danach `onEventClicked` |
| `onTimeRangeClick({ control, start, end, resource, originalEvent })` auf jeder leeren Zelle | `onTimeRangeSelected({ start, end, resource, control, origin, multirange })`, mit `origin` gleich `'click'`, `'drag'`, `'keyboard'` oder `'api'` |

> **Behavior:**
> Pro hat ebenfalls ein `onTimeRangeClick`, aber es bedeutet etwas anderes: Es wird ausgelöst, wenn der Nutzer auf einen bereits ausgewählten Zeitraum klickt. Ein Klick auf eine leere Zelle ist in Pro eine Auswahl von einer Zelle, gemeldet von `onTimeRangeSelect` (davor, abbrechbar) und `onTimeRangeSelected` (danach). Filtern Sie auf `args.origin === 'click'`, wenn Ziehvorgänge nicht zählen sollen.

Weitere Unterschiede, die Sie in Ihren Handlern prüfen sollten:

- In Pro laufen Handler mit `this` auf das Control gesetzt, und die meisten Argumente enthalten `control`.
- In Lite ist `originalEvent` ein `KeyboardEvent`, wenn eine Zelle oder ein Ereignis per Tastatur aktiviert wird. In Pro löst Eingabe auf einem Ereignis einen Klick aus, sodass `onEventClick` immer ein `MouseEvent` erhält, und Eingabe auf einer Zelle ist eine Auswahl mit `origin: 'keyboard'`.
- `controlRef`-Callbacks werden in Lite beim Unmount mit `null` aufgerufen; Pro ruft sie nur mit dem Control auf und leert Ref-Objekte beim Unmount.
- `scrollTo(date)` akzeptiert in Pro die optionalen Argumente `animated` und `position`.

## Wenn beide Pakete installiert sind
Manche Produkte behalten Lite auf öffentlichen Seiten und nutzen Pro im Backoffice. Das funktioniert, mit zwei Regeln:

- **ISO-Strings austauschen, keine Datumsobjekte.** Jede Edition hat ihre eigene Datumsklasse, und Pro lehnt ein Datumsobjekt von Lite ab.
- **CSS getrennt halten.** Jedes Paket hat sein eigenes Stylesheet. Einige Token-Namen gibt es in beiden (`--super-scheduler-text`, `--super-scheduler-border`); begrenzen Sie Überschreibungen für Lite daher auf `.super-scheduler-lite` statt auf `:root`.

```ts
// src/dates.ts
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().value
```
Importieren Sie die beiden Komponenten unter verschiedenen lokalen Namen, wenn ein Modul beide braucht, zum Beispiel `import { SuperSchedulerComponent as LiteScheduler } from 'super-scheduler-lite'`.

## Pro-Funktionen Schritt für Schritt übernehmen
Sobald die schreibgeschützte Ansicht übereinstimmt, fügen Sie eine Fähigkeit nach der anderen hinzu und testen sie:

1. **Tastatur und Barrierefreiheit.** Behalten Sie `keyboardEnabled` und `keyboardMode="Full"`; siehe [Tastatur, Barrierefreiheit und Touch](https://superscheduler.org/de/docs/keyboard-accessibility-touch/).
2. **Bearbeitung.** Entfernen Sie `eventMoveHandling="Disabled"` und `eventResizeHandling="Disabled"`, ergänzen Sie Regeln mit `onEventMoving` und `onEventMove` und speichern Sie Änderungen aus `onEventsChange`; siehe [Regeln für Ziehen und Dauer ändern](https://superscheduler.org/de/docs/drag-resize-rules/) und [Kontrollierter Zustand](https://superscheduler.org/de/docs/controlled-state/).
3. **Buchungen anlegen.** Verwenden Sie `onTimeRangeSelected` mit `origin === 'drag'`, um ein Formular zu öffnen.
4. **Stunden und Zoom.** Fügen Sie `zoomLevels` hinzu und entfernen Sie `zoomGesture={false}`; siehe [Zeitskalen und Zoom](https://superscheduler.org/de/docs/time-scales-zoom/).
5. **Zeilen.** Bäume, fixierte Zeilen, geteilte Zeilen und Spalten im Zeilenkopf; siehe [Bäume, Spalten und Auswahl](https://superscheduler.org/de/docs/trees-columns-selection/).
6. **Module.** [Rückgängig und Wiederholen](https://superscheduler.org/de/docs/undo-redo/), [Minimap](https://superscheduler.org/de/docs/minimap-metrics/), [Verknüpfungen](https://superscheduler.org/de/docs/links-dependencies/), [Bereiche und gespeicherte Ansichten](https://superscheduler.org/de/docs/panes-saved-views/) und [bereichsweises Laden](https://superscheduler.org/de/docs/range-loading/).
7. **React-Inhalte.** Stellen Sie den Import auf `super-scheduler/react-render` um, wenn Sie React in Ereignissen oder Köpfen brauchen; siehe [React-Render-Slots](https://superscheduler.org/de/docs/react-render-slots/).

→ https://superscheduler.org/de/examples/hotel-rooms/
Für kaufmännische Fragen zu Pro siehe die [Preisseite](https://superscheduler.org/de/pricing/).
