Aller au contenu
SuperScheduler

ProductionS’applique àLite et Pro

Dépannage

La plupart des problèmes viennent de quelques causes : la feuille de style n’est pas importée, l’hôte n’a pas de hauteur pour `height="100%"`, le contrôle est lu avant le montage, ou la vue montre une seule journée, aujourd’hui, alors que les données se trouvent ailleurs (`days` vaut 1 par défaut et `startDate` vaut aujourd’hui). Vérifiez aussi que les chaînes de date comportent les secondes, que les valeurs `resource` des événements correspondent exactement aux id des ressources, et qu’une seule copie de React est installée. Chaque section ci-dessous donne le symptôme, la cause et la solution.

Vérifié avec la v0.1.0 · relu le 7 octobre 2026.md

Trouvez le symptôme, vérifiez la cause, appliquez la solution. Les sections concernent Pro et Lite, sauf si elles nomment une édition. Si votre problème n’est pas ici, la référence de l’API liste chaque option implémentée avec sa valeur par défaut, et sa section API réservées liste ce qui est typé mais pas implémenté.

Le planificateur s’affiche sans styles

Symptôme. Les lignes et les événements apparaissent, mais sans lignes de grille, sans couleurs ni en-têtes alignés.

Cause. La feuille de style n’est pas chargée, ou c’est celle de l’autre édition qui l’est.

Solution. Importez-la une seule fois, dans votre point d’entrée ou votre layout racine : import 'super-scheduler/styles.css' pour Pro, import 'super-scheduler-lite/styles.css' pour Lite. La feuille de style Pro vit dans @layer super-scheduler avec des sélecteurs de spécificité nulle : n’importe laquelle de vos règles hors couche l’emporte, et une réinitialisation large comme * { border: 0 } supprime donc aussi les bordures de la bibliothèque (voir Tailwind). unstyled désactive volontairement les règles visuelles de la bibliothèque.

Le planificateur fait 0 px de haut ou n’a pas la hauteur définie

Symptôme. Rien n’est visible, ou la grille est plus petite ou plus grande que prévu.

Causes et solutions (Pro).

  • heightSpec vaut 'Max' par défaut : height (600 par défaut) est un plafond, et la grille est aussi haute que ses lignes, jusqu’à cette valeur. Deux lignes avec height={320} s’affichent sur environ 130 px de haut. Utilisez heightSpec="Fixed" pour une boîte de taille constante.
  • height="100%" remplit l’élément hôte du composant, un <div> sans style que SuperSchedulerComponent rend à l’intérieur de votre conteneur. Si ce <div> n’a pas de hauteur, le planificateur s’effondre à 0 px. Donnez au conteneur une hauteur définie et à l’hôte 100 % :
src/FillParent.tsxtsx
import { SuperSchedulerComponent } from 'super-scheduler'
import type { SuperScheduler } from 'super-scheduler'

interface Props {
  readonly rooms: SuperScheduler.ResourceData[]
  readonly events: SuperScheduler.EventData[]
}

// height="100%" fills the component's own host <div>: .fill sizes it (see the CSS below).
export function FillParent({ rooms, events }: Props) {
  return (
    <div className="fill">
      <SuperSchedulerComponent
        height="100%"
        startDate="2026-10-01"
        days={31}
        scale="Day"
        resources={rooms}
        events={events}
      />
    </div>
  )
}
csscss
.fill {
  height: 70vh; /* or a flex item with min-height: 0 */
}
.fill > div {
  height: 100%;
}
  • heightSpec="Auto" dimensionne le contrôle selon son contenu, sans barre de défilement verticale : c’est alors la page qui défile.
  • SchedulerPanes prend sa propre height numérique pour l’ensemble des volets.

Dans Lite, height est toujours un nombre fixe de pixels (400 par défaut). Dans les deux éditions, quand le conteneur est un élément flex, donnez-lui min-width: 0 dans une ligne (ou min-height: 0 dans une colonne) ; sinon, la taille minimale automatique de l’élément flex peut laisser la grille élargir ou allonger la mise en page au lieu de défiler.

ref.current ou control vaut null

Cause. Le contrôle est créé dans componentDidMount. Pendant le premier rendu, côté serveur et après le démontage, il n’existe aucun contrôle actif : ref.current vaut null avant le montage, et les objets ref passés dans controlRef sont remis à null au démontage.

Solution. Lisez le contrôle dans des effets et des gestionnaires d’événements, jamais pendant le rendu. useSchedulerControl() renvoie le contrôle sous forme d’état, si bien qu’un effet peut en dépendre :

src/Planning.tsxtsx
import { useEffect } from 'react'
import { SuperScheduler, SuperSchedulerComponent, useSchedulerControl } from 'super-scheduler'

const START = SuperScheduler.Date.today().addDays(-30)

export function Planning({ rooms }: { rooms: SuperScheduler.ResourceData[] }) {
  // `control` is null during the first render and the live control after mount.
  const { controlRef, control } = useSchedulerControl()

  useEffect(() => {
    if (control === null || control.disposed()) return
    control.scrollTo(SuperScheduler.Date.today(), false, 'middle')
  }, [control])

  return (
    <SuperSchedulerComponent
      controlRef={controlRef}
      startDate={START}
      days={90}
      scale="Day"
      resources={rooms}
    />
  )
}

Dans Pro, une fonction controlRef est appelée avec le contrôle au montage et n’est pas appelée avec null au démontage. Une référence au contrôle conservée d’avant un démontage pointe vers un contrôle libéré : vérifiez control.disposed() dans le code asynchrone. Avec l’API impérative, appelez init() avant toute autre chose ; update() avant init() lève SuperScheduler.Exception.

Rien ne s’affiche dans la grille

Vérifiez ces points dans l’ordre :

  1. Plage. days vaut 1 par défaut et startDate vaut aujourd’hui. Dans Pro, scale correspond aussi par défaut à des cellules d’une heure ('CellDuration' avec 60 minutes). Réglez startDate, days et scale="Day" sur la période que couvrent vos données. Les jeux de données de super-scheduler/datasets commencent par défaut le 2026-01-01.
  2. Chaînes de date. '2026-10-01T10:00' lève SchedulerDate: "2026-10-01T10:00" is not an ISO 8601 date. Utilisez '2026-10-01' ou '2026-10-01T10:00:00'. Les objets Date natifs ne passent pas la vérification de types ; convertissez-les (voir dates civiles).
  3. Id des ressources. La resource d’un événement doit être exactement égale à l’id d’une ressource : 1 et '1' sont différents. Les événements de ressources inconnues ne sont pas dessinés.
  4. Arborescences (Pro). Les children ne s’affichent qu’avec treeEnabled, et un parent ne montre ses enfants que s’il a expanded: true.
  5. Filtres et indicateurs. Un control.events.filter() ou un control.rows.filter() actif, ou hidden: true sur l’événement, le masque.
  6. État vide. Sans ligne visible, Pro affiche emptyState si vous l’avez défini ; Lite affiche « No resources » par défaut.

Les modifications n’apparaissent pas

  • Modification sur place. Le composant React ne transmet une prop que si son identité change. Ajouter des éléments au même tableau events ou resources puis refaire un rendu n’envoie rien. Passez un nouveau tableau, ou appelez control.update() après une modification sur place.
  • Le tableau change tout seul (Pro). Le contrôle adopte le tableau events que vous passez et le modifie avec splice quand des événements sont ajoutés, retirés ou validés. Passez une copie (useMemo(() => events.slice(), [events])) si ce tableau est un état partagé. Un tableau gelé, comme en produisent certaines bibliothèques d’état en développement, fait lever une TypeError à control.events.add, update et remove.
  • Mise à jour d’un id inconnu. control.events.update(data) ne fait rien quand l’id n’est pas chargé ; utilisez add pour les nouveaux événements. add lève une exception en cas d’id en double.
  • defaultEvents a changé. Il n’est lu qu’une fois, lors de init() ; les valeurs ultérieures sont ignorées avec un avertissement en développement. Utilisez des events contrôlés pour des données qui changent.
  • Hooks de cellule (Pro). Les résultats de onBeforeCellRender sont mis en cache par cellule. Si une cellule dépend des événements, définissez cellsAutoUpdated: true sur sa ressource ou appelez control.update().
  • Une prop retirée. Une prop qui disparaît entre deux rendus revient à sa valeur par défaut.

Erreurs d’import et sous-chemins erronés

Seuls ces points d’entrée existent ; tout autre, comme super-scheduler/dist/..., échoue avec une erreur « not exported » de votre bundler ou de Node :

  • Pro : super-scheduler, /styles.css, /react-render, /history, /minimap, /panes, /zoom-ui, /views, /ranges, /hooks, /tailwind, /datasets et /core.
  • Lite : super-scheduler-lite et super-scheduler-lite/styles.css uniquement. Les modules Pro ne font pas partie de Lite.

TypeScript les résout via les exports du paquet avec moduleResolution réglé sur bundler, node16 ou nodenext ; l’ancien réglage node fonctionne grâce aux typesVersions du paquet. Avec noUncheckedSideEffectImports (TypeScript 5.6 et ultérieur), l’import d’une feuille de style nécessite une déclaration declare module '*.css', que fournissent déjà les types client des bundlers comme vite/client. super-scheduler/tailwind est un preset de style CommonJS : chargez-le avec require('super-scheduler/tailwind'), ou avec un import par défaut si votre configuration prend en charge l’interopérabilité CommonJS.

Messages de la console

MessageSignification
[super-scheduler] renderEvent needs the component from "super-scheduler/react-render"Une prop de rendu React (renderEvent, renderCell, eventHover, un handler onBefore*DomAdd...) a été donnée au composant racine. Importez SuperSchedulerComponent depuis super-scheduler/react-render.
super-scheduler: <feature> is not supported yetUne API réservée : typée, acceptée, inerte. Voir API réservées.
[super-scheduler] events wins over defaultEventsLes deux props ont été données ; c’est events qui est utilisée.
[super-scheduler] defaultEvents is read only during init()Une nouvelle valeur de defaultEvents après le montage est ignorée.
SuperScheduler Lite: unsupported option "..."Lite lève une erreur pour toute option qu’il n’implémente pas, y compris en production. scale doit valoir 'Day', et les children, frozen, split et columns des ressources nécessitent Pro.

Pro n’affiche ces avertissements que lorsque NODE_ENV ne vaut pas production, et les avertissements des API réservées une seule fois par fonction. Les erreurs de Lite sont levées dans tous les builds.

« Invalid hook call » ou deux copies de React

Symptôme. « Invalid hook call » depuis useSchedulerControl ou useScheduler, du contenu React dans les slots de rendu qui ne voit pas vos context providers, ou des erreurs de portail.

Cause. La bibliothèque résout une autre copie de React que votre application. Les deux éditions déclarent React comme dépendance peer et ne l’embarquent jamais : cela arrive donc quand l’installation ou un lien apporte une seconde copie, par exemple un paquet lié ou compilé localement, un monorepo avec plusieurs versions de React, ou des plages peer non satisfaites (18.2 ou ultérieur, ou 19).

Solution. npm ls react react-dom doit afficher une seule version. Installez l’archive tarball Pro au lieu de lier une copie locale. Dans Vite, ajoutez resolve: { dedupe: ['react', 'react-dom'] } ; dans webpack, faites pointer des alias react et react-dom vers les copies de votre application.

Erreurs de Content Security Policy

La bibliothèque n’a besoin ni de scripts inline ni de styles 'unsafe-inline' : elle se charge sous forme de modules et écrit la géométrie via element.style. Si la console signale des violations, vérifiez trois choses : les chunks chargés à la demande doivent être autorisés par script-src ; les petites images SVG data: de la feuille de style Pro nécessitent img-src data: ; et les attributs style inline dans les chaînes HTML que vous passez (html, bubbleHtml) sont bloqués, utilisez donc des classes. Les détails et un exemple de politique se trouvent dans Rendu serveur.

Tailwind supprime les bordures ou écrase le planificateur

Le preflight de Tailwind v3 est hors couche et réinitialise les bordures de tous les éléments, ce qui l’emporte sur les règles en couche de la bibliothèque. Placez le preflight dans une couche inférieure à SuperScheduler :

csscss
@layer tw-base, super-scheduler;

@import 'super-scheduler/styles.css';

@layer tw-base {
  @tailwind base;
}
@tailwind components;
@tailwind utilities;

Avec Tailwind v4, déclarez l’ordre des couches avant les imports pour que la bibliothèque se place entre base et vos utilitaires :

csscss
@layer theme, base, super-scheduler, components, utilities;

@import 'tailwindcss';
@import 'super-scheduler/styles.css';

Voir Thèmes pour le preset Tailwind et la correspondance des tokens.

Autres surprises

  • Les événements s’alignent sur des journées entières (Pro). useEventBoxes vaut 'Always' par défaut, ce qui dessine les événements sur des cellules entières. Utilisez 'Never' pour dessiner les horaires exacts, et ajoutez eventMoveByCell si le glissement doit rester ancré aux cellules.
  • Un clic laisse une sélection derrière lui (Pro). Un clic sur une cellule vide est une sélection d’une cellule signalée à onTimeRangeSelected avec origin: 'click', et son ombre reste jusqu’à la sélection suivante ou un clic ailleurs. Appelez args.control.clearSelection() dans le handler.
  • Les touches ne font rien (Pro). keyboardEnabled vaut false par défaut. keyboardMode="Full" en a aussi besoin. Avec plusieurs planificateurs sur une page, définissez keyboardTarget="component".
  • Les dates sont devenues des objets (Pro). Après un glissement ou un redimensionnement, le start et le end de l’événement sont des objets SuperScheduler.Date. String(date) et JSON.stringify donnent la valeur ISO civile ; date.toString('d MMM', locale) la formate.
  • Mauvais jour de la semaine. SuperScheduler.Date#getDay() renvoie le jour du mois. Utilisez getDayOfWeek() (0 correspond à dimanche) ou dayOfWeekISO() (1 correspond à lundi).

Guides associés : Intégration React, État contrôlé, Rendu serveur et Virtualisation et performances.