# Démarrage rapide avec Lite

> Installez super-scheduler-lite depuis npm et affichez une frise quotidienne de ressources en lecture seule dans React : options, callbacks de clic et limites.

Source: https://superscheduler.org/fr/docs/quick-start-lite/
Reviewed: 2026-10-07

Lancez npm install super-scheduler-lite, importez SuperSchedulerComponent et super-scheduler-lite/styles.css, puis passez startDate, days, resources et events. Lite affiche une frise virtualisée en lecture seule avec une cellule par jour, signale les clics via onEventClick et onTimeRangeClick, et lève une erreur pour toute option qu’il n’implémente pas.

SuperScheduler Lite est l’édition publique en lecture seule : une ligne par ressource, une colonne par jour, des événements sous forme de barres et des clics transmis à votre code. C’est le moyen le plus rapide d’intégrer un tableau d’occupation ou de disponibilité dans une application React. Ce guide vous mène d’un projet vide à une frise fonctionnelle, puis passe en revue chaque option, les callbacks, l’API impérative et ce que Lite refuse délibérément.

Si vous avez besoin du glisser, du redimensionnement, des heures et des minutes, du zoom ou des arborescences de ressources, tout cela relève de Pro : voir [Installer SuperScheduler Pro](https://superscheduler.org/fr/docs/install-pro/) et [Passer de Lite à Pro](https://superscheduler.org/fr/docs/migrate-lite-to-pro/).

## Prérequis
- React 18.2 ou ultérieur, ou React 19. React est une dépendance pair (peer dependency) : Lite utilise donc la copie de votre application.
- Un bundler ou un framework qui comprend les modules ES ou CommonJS (Vite, Next.js, webpack, Parcel et équivalents). Les deux formats et leurs déclarations TypeScript sont fournis dans le paquet.
- Un environnement navigateur pour le rendu. Le paquet peut être importé pendant le rendu serveur ; la frise elle-même est construite dans le navigateur au montage du composant.

## Installer le paquet
```sh
npm install super-scheduler-lite react react-dom
```

`react-dom` figure dans la commande parce que vous faites le rendu avec, pas parce que Lite l’importe.

## Afficher une première frise
```tsx
// src/Planning.tsx
import { SuperSchedulerComponent } from 'super-scheduler-lite'
import type { SuperScheduler } from 'super-scheduler-lite'
import 'super-scheduler-lite/styles.css'

// Module-level arrays keep the same identity on every render, so React never re-applies them.
const ROOMS: SuperScheduler.ResourceData[] = [
  { id: 'r101', name: 'Room 101' },
  { id: 'r102', name: 'Room 102' },
  { id: 'r103', name: 'Room 103' },
]

const BOOKINGS: SuperScheduler.EventData[] = [
  // Date-only values: the bar covers 2, 3 and 4 October (the end is exclusive).
  { id: 1, resource: 'r101', start: '2026-10-02', end: '2026-10-05', text: 'Booking 1042' },
  // Overlaps the first booking on the same row: Lite stacks it on a second line.
  {
    id: 2,
    resource: 'r101',
    start: '2026-10-04',
    end: '2026-10-07',
    text: 'Booking 1043',
    backColor: '#dbeafe',
  },
  // Times are kept: the bar starts at 14:00 and ends at 11:00, inside the day cells.
  {
    id: 3,
    resource: 'r103',
    start: '2026-10-06T14:00:00',
    end: '2026-10-09T11:00:00',
    text: 'Booking 1051',
  },
]

export function Planning() {
  return (
    <SuperSchedulerComponent startDate="2026-10-01" days={31} resources={ROOMS} events={BOOKINGS} />
  )
}
```
Vous devriez voir une grille de 400 pixels de haut avec un en-tête de libellés de jours (`1 Oct`, `2 Oct`, …), trois lignes de chambres et trois barres. La réservation 1042 couvre les 2, 3 et 4 octobre : la date de fin est exclusive, donc un séjour qui se termine le `2026-10-05` a disparu à minuit le 5. La réservation 1043 la chevauche : la ligne Room 101 passe alors à deux niveaux et empile les deux barres. La réservation 1051 commence à 14:00 le 6 et se termine à 11:00 le 9 : Lite place les barres à leur heure exacte à l’intérieur des cellules de jour.

Faites défiler la grille dans n’importe quelle direction. Seuls les lignes, les jours et les événements visibles existent dans le DOM, et le défilement ne provoque jamais de rendu React, quelle que soit la taille de vos données.

> **Tip:**
> Gardez `resources` et `events` stables d’un rendu à l’autre : constantes de module, state ou `useMemo`. Le composant compare les props par identité et n’envoie au contrôle que celles qui ont changé ; un nouveau littéral de tableau à chaque rendu reconstruit donc la frise à chaque fois.

## Importer les styles
Importez `super-scheduler-lite/styles.css` une seule fois, en général dans votre fichier d’entrée ou votre layout racine. Les règles vivent dans une couche de cascade CSS nommée `super-scheduler` : toute règle hors couche de votre propre feuille de style les remplace donc sans `!important`.

L’élément racine porte la classe `super-scheduler-lite` et six propriétés personnalisées. Redéfinissez-les sur cette classe (et non sur un ancêtre éloigné, car la racine déclare ses propres valeurs) :

```css
.super-scheduler-lite {
  --super-scheduler-background: #ffffff;
  --super-scheduler-text: #18212f;
  --super-scheduler-border: #dce3ed;
  --super-scheduler-header: #f4f7fb;
  --super-scheduler-event: #d7e8fa;
  --super-scheduler-focus: #005cbf;
}

/* A dark theme driven by your own class on <html>. */
.dark .super-scheduler-lite {
  --super-scheduler-background: #121518;
  --super-scheduler-text: #f4f4f5;
  --super-scheduler-border: #2b3139;
  --super-scheduler-header: #1b1f24;
  --super-scheduler-event: #1f3a5c;
}
```

Lite définit sa propre police (13 px, police système) et occupe toute la largeur de son parent. Les couleurs par événement viennent des données (`backColor`, `fontColor`) ou d’une `cssClass` que vous stylez vous-même.

## Options et valeurs par défaut
Toutes les options acceptées par Lite figurent dans ce tableau. Toute autre option lève une erreur (voir [Ce que Lite refuse](#rejects)).

| Option | Type | Défaut | Remarques |
|---|---|---|---|
| `startDate` | chaîne ISO ou `SuperScheduler.Date` | Aujourd’hui | Le premier jour ; une éventuelle heure est ignorée |
| `days` | entier positif | `31` | Nombre de colonnes de jours |
| `scale` | `'Day'` | `'Day'` | Seule valeur acceptée |
| `cellWidth` | nombre (px) | `64` | Largeur d’un jour |
| `height` | nombre (px) | `400` | Hauteur totale de la zone de défilement, en-tête compris |
| `rowHeaderWidth` | nombre (px) | `160` | Largeur de la colonne des noms de ressources |
| `rowMinHeight` | nombre (px) | `40` | Les lignes s’agrandissent quand des événements qui se chevauchent s’empilent |
| `eventHeight` | nombre (px) | `26` | Hauteur d’un niveau d’événements |
| `resources` | `ResourceData[]` | `[]` | `{ id, name }`, liste plate |
| `events` | `EventData[]` | `[]` | Voir [Champs des événements](#event-fields) |
| `locale` | chaîne | `'en-us'` | Libellés des jours dans l’en-tête, par exemple `es-es` ou `de-de` |
| `ariaLabel` | chaîne | `'Resource schedule'` | Nom accessible de la grille, également affiché dans le coin supérieur gauche |
| `emptyState` | chaîne | `'No resources'` | Texte affiché quand `resources` est vide |
| `onEventClick` | fonction | aucune | Voir [Réagir aux clics](#clicks) |
| `onTimeRangeClick` | fonction | aucune | Voir [Réagir aux clics](#clicks) |

Les options numériques doivent être positives et finies, et `days` doit être un entier.

## Champs des événements et des ressources
Une ressource est `{ id, name }`. Un événement a cinq champs obligatoires et cinq facultatifs :

| Champ | Obligatoire | Signification |
|---|---|---|
| `id` | oui | Chaîne ou nombre fini, unique parmi les événements |
| `resource` | oui | L’`id` de la ligne à laquelle il appartient, du même type |
| `start`, `end` | oui | Chaînes ISO (`2026-10-02` ou `2026-10-02T14:00:00`, secondes comprises) ou `SuperScheduler.Date` ; `end` est exclusif |
| `text` | oui | Le libellé, rendu comme texte (jamais comme HTML) |
| `backColor`, `fontColor` | non | Toute couleur CSS |
| `cssClass` | non | Noms de classes supplémentaires sur le bouton de l’événement |
| `toolTip` | non | Infobulle native ; vaut `text` par défaut |
| `tags` | non | Toute valeur que vous voulez récupérer dans `onEventClick` |

Les ids sont comparés strictement : `1` et `'1'` sont des ids différents, donc un événement avec `resource: '101'` n’apparaît pas sur une ligne avec `id: 101`. Les dates sont des valeurs civiles, en heure locale, sans fuseau horaire ; le [guide du modèle de données](https://superscheduler.org/fr/docs/resources-events-intervals/) explique les règles, identiques dans les deux éditions.

## Réagir aux clics
Lite signale deux interactions. `onEventClick` reçoit `{ control, e, originalEvent }`, où `e.data` est votre objet événement. `onTimeRangeClick` reçoit `{ control, start, end, resource, originalEvent }` lors d’un clic sur une cellule de jour vide ; `start` est ce jour à minuit et `end` le minuit suivant, tous deux en `SuperScheduler.Date`.

```tsx
// src/PlanningWithDetails.tsx
import { useCallback, useState } from 'react'
import { SuperSchedulerComponent } from 'super-scheduler-lite'
import type {
  SchedulerEventClickArgs,
  SchedulerTimeRangeClickArgs,
  SuperScheduler,
} from 'super-scheduler-lite'

interface PlanningProps {
  readonly rooms: SuperScheduler.ResourceData[]
  readonly bookings: SuperScheduler.EventData[]
}

export function PlanningWithDetails({ rooms, bookings }: PlanningProps) {
  const [detail, setDetail] = useState('Select a booking or a free day.')

  // Stable callbacks: a new function per render would be sent to the control on every render.
  const onEventClick = useCallback((args: SchedulerEventClickArgs) => {
    // Lite hands you the event's own data object, including `tags`.
    setDetail(`${args.e.data.text} (id ${String(args.e.data.id)})`)
  }, [])

  const onTimeRangeClick = useCallback((args: SchedulerTimeRangeClickArgs) => {
    // One day cell: `end` is the next midnight. Enter and Space on the active cell also land here.
    setDetail(`Free cell: ${String(args.resource)} on ${args.start.toString('d MMMM yyyy')}`)
  }, [])

  return (
    <>
      <p aria-live="polite">{detail}</p>
      <SuperSchedulerComponent
        startDate="2026-10-01"
        days={31}
        resources={rooms}
        events={bookings}
        onEventClick={onEventClick}
        onTimeRangeClick={onTimeRangeClick}
      />
    </>
  )
}
```
Le paragraphe devrait changer quand vous cliquez sur une réservation ou sur une cellule libre. Les mêmes callbacks s’exécutent depuis le clavier : Tab donne le focus à la grille, les flèches déplacent la cellule active, et Entrée ou Espace sur celle-ci appelle `onTimeRangeClick` ; les événements sont des boutons, donc Entrée sur un événement qui a le focus appelle `onEventClick`. `originalEvent` est l’événement DOM à l’origine de l’appel : le `KeyboardEvent` quand Entrée ou Espace a activé une cellule, un événement de clic sinon.

> **Behavior:**
> Les arguments des callbacks de Lite sont plus réduits que ceux de Pro : `e` n’expose que `data`. Dans Pro, `args.e` est un objet enveloppe `SuperScheduler.Event` doté de méthodes comme `id()` et `start()`. Si vous comptez migrer, appuyez la logique de vos handlers sur les champs de `e.data`.

## Piloter la frise depuis le code
Le composant React crée un contrôle au montage et le libère au démontage. Accédez-y par `ref.current.control` sur le composant, ou avec la prop `controlRef` (un objet ref ou un callback ; Lite le remet à `null` au démontage).

```tsx
// src/NavigablePlanning.tsx
import { useRef } from 'react'
import { SuperScheduler, SuperSchedulerComponent } from 'super-scheduler-lite'

interface PlanningProps {
  readonly rooms: SuperScheduler.ResourceData[]
  readonly bookings: SuperScheduler.EventData[]
}

export function NavigablePlanning({ rooms, bookings }: PlanningProps) {
  // Lite sets `current` after mount and clears it on unmount.
  const controlRef = useRef<SuperScheduler.Scheduler | null>(null)

  const goToToday = () => controlRef.current?.scrollTo(SuperScheduler.Date.today())
  const findRoom = (id: SuperScheduler.ResourceData['id']) =>
    controlRef.current?.scrollToResource(id)
  const logRange = () => {
    const control = controlRef.current
    if (control !== null)
      console.info(`${control.visibleStart().value} to ${control.visibleEnd().value}`)
  }

  return (
    <>
      <div role="toolbar" aria-label="Planning navigation">
        <button type="button" onClick={goToToday}>
          Today
        </button>
        <button type="button" onClick={() => findRoom('r310')}>
          Room 310
        </button>
        <button type="button" onClick={logRange}>
          Visible range
        </button>
      </div>
      <SuperSchedulerComponent
        controlRef={controlRef}
        startDate="2026-10-01"
        days={92}
        height={520}
        resources={rooms}
        events={bookings}
      />
    </>
  )
}
```
Le contrôle de Lite comporte huit membres :

| Membre | Rôle |
|---|---|
| `update(options)` | Fusionne `options` avec les options actuelles et redessine. Un `undefined` explicite rétablit la valeur par défaut |
| `scrollTo(date)` | Fait défiler pour placer `date` au bord gauche |
| `scrollToResource(id)` | Fait défiler pour placer cette ligne en haut |
| `visibleStart()`, `visibleEnd()` | Les dates aux bords gauche et droit de la vue défilée |
| `disposed()` | Indique si `dispose()` a été exécuté |
| `dispose()` | Supprime le DOM, les écouteurs et les observers, et libère les données |
| `init()` | Construit le DOM ; le composant React l’appelle pour vous |

Sans React, créez le contrôle sur un élément qui vous appartient :

```ts
// src/mount-planning.ts
import { SuperScheduler } from 'super-scheduler-lite'
import 'super-scheduler-lite/styles.css'

/** Mounts a read-only planning into `host` without React and returns its teardown. */
export function mountPlanning(host: HTMLElement): () => void {
  const control = new SuperScheduler.Scheduler(host, {
    startDate: '2026-10-01',
    days: 31,
    resources: [
      { id: 'r101', name: 'Room 101' },
      { id: 'r102', name: 'Room 102' },
    ],
    events: [
      { id: 1, resource: 'r101', start: '2026-10-02', end: '2026-10-05', text: 'Booking 1042' },
    ],
    onEventClick: ({ e }) => console.info('booking', e.data.id),
  })
  control.init()

  // update() merges with the current options; an explicit undefined restores a default.
  control.update({ days: 62, cellWidth: 48 })
  control.scrollTo('2026-10-15')

  return () => control.dispose()
}
```
## Mettre à jour les données
Le composant n’envoie à `control.update()` que les props modifiées, en les comparant par identité. Pour changer les données, passez un nouveau tableau : `setEvents([...events, next])` fonctionne, alors que `events.push(next)` sur le même tableau n’atteint pas la frise tant que vous n’appelez pas vous-même `control.update()`. Les mises à jour qui ne changent que `onEventClick` ou `onTimeRangeClick` remplacent les callbacks sans redessiner.

## Ce que Lite refuse
Lite valide ses entrées et lève une erreur plutôt que d’ignorer ce qu’il ne sait pas faire : une erreur de configuration apparaît ainsi pendant le développement, et non sous la forme d’un écran qui fonctionne à moitié :

- Une option absente du tableau ci-dessus, y compris les options Pro comme `allowEventOverlap` ou `zoomLevels`, même passée depuis du JavaScript pur : `SuperScheduler Lite: unsupported option "zoomLevels"`.
- Une `scale` autre que `'Day'`.
- Une ressource avec `children`, `frozen`, `split` ou `columns` (`resource children requires Pro`).
- Des ids de ressources en double, des ids qui ne sont ni des chaînes ni des nombres finis, et des événements dont `end` précède `start`.
- Des dimensions nulles, négatives ou non finies, et un `days` non entier.

Quand `update()` lève une erreur, la configuration précédente reste affichée et utilisable. Dans React, l’erreur est levée pendant que le composant applique les nouvelles props : un error boundary placé au-dessus l’intercepte.

> **Limitation:**
> Lite n’offre ni édition, ni cellules d’une heure ou d’une minute, ni zoom, ni défilement infini, ni arborescence de ressources, ni lignes figées ou scindées, ni liens, ni sélection, ni mise en évidence des conflits, ni minimap, ni volets, ni historique, ni vues enregistrées, ni chargement par plages, ni slots de rendu React. Leur code n’est pas dans le paquet. Les champs supplémentaires de vos objets événements sont conservés mais n’activent rien.

## Étapes suivantes
- Comprenez les règles de données communes aux deux éditions : [Ressources, événements et intervalles](https://superscheduler.org/fr/docs/resources-events-intervals/).
- Intégrez correctement le composant dans une application React plus large : [Intégration React](https://superscheduler.org/fr/docs/react-integration/).
- Découvrez à quoi ressemble un planning modifiable dans les [exemples](https://superscheduler.org/fr/examples/), tous construits avec Pro.
- Quand vous avez besoin de l’édition : [Passer de Lite à Pro](https://superscheduler.org/fr/docs/migrate-lite-to-pro/).
