APOLLO VISION LABS

Référence de l'API

Tous les symboles exportés par guide-core et guide-mui, avec leur signature et ce qu'ils font.

Deux paquets. @apollovisionlabs/guide-core exporte 57 symboles et ne rend rien. @apollovisionlabs/guide-mui en exporte 16 et rend le cœur avec MUI 7 ou MUI 9. React 19 est le pair des deux.

Une collision de noms

Checklist est un type dans le cœur et un composant dans le paquet MUI. Importer les deux dans le même module demande un alias :

import { useChecklist, type Checklist as ChecklistData } from '@apollovisionlabs/guide-core'
import { Checklist } from '@apollovisionlabs/guide-mui'

const onboarding: ChecklistData = { id: 'onboarding', items: [] }

Aliaser le type plutôt que le composant coûte moins cher, puisque le composant apparaît dans le JSX et pas le type.

Cœur : types de visite et d’étape

  • Rect : { top: number; left: number; width: number; height: number }. Coordonnées d’un élément mesuré, dans le repère de la fenêtre.
  • Placement : 'top' | 'bottom' | 'left' | 'right'. Position du popover par rapport à sa cible.
  • MissingTargetPolicy : 'skip' | 'wait' | 'error'. Que faire quand une cible n’apparaît jamais.
  • Step : { target, route?, navigateTo?, placement?, interactive?, advanceOn?, title?, titleKey?, body?, bodyKey?, onMissingTarget? }. target est la clé logique portée par data-guide. advanceOn vaut 'click' ou undefined ; une étape qui le déclare avance quand l’utilisateur clique la cible, et cela implique interactive (voir ActiveStep plus bas). Voir Visites.
  • Tour : { id: string; steps: Step[] }.
  • TourStatus : 'idle' | 'running' | 'paused' | 'completed'.
  • TourProgress : { status: 'in-progress' | 'completed'; stepIndex: number }. La valeur persistée sous tour:<id>.

Cœur : types de checklist

  • ChecklistItem : { id, title?, titleKey?, body?, bodyKey?, tourId?, href? }. Un élément portant un tourId se termine quand cette visite se termine ; un élément portant un href navigue et ne termine rien.
  • Checklist : { id: string; items: ChecklistItem[] }.
  • ChecklistProgress : { completed: string[]; dismissed: boolean }. La valeur persistée sous checklist:<id>.
  • ResolvedChecklistItem : { id, title, body, completed, tourId?, href? }. Un élément après résolution des textes et lecture de la progression, tel que le renvoie useChecklist.

Cœur : types de hotspot

Voir Hotspots pour la fonctionnalité elle-même ; ceci est la référence des types.

  • Hotspot : { id, target, title?, titleKey?, body?, bodyKey?, tourId?, placement? }. target est la clé logique portée par data-guide, comme pour une étape. tourId nomme une visite lancée depuis la bulle du hotspot.
  • ResolvedHotspot : { id, target, title, body, seen, tourId?, placement? }. Un hotspot après résolution des textes et lecture de seen, tel que le renvoie useHotspots.
  • HotspotsProgress : { seen: string[] }. La valeur persistée sous la seule clé hotspots:seen.
  • isHotspotsProgress(value: unknown): value is HotspotsProgress : garde exigeant un tableau seen de chaînes.

Cœur : stockage et texte

  • GuideStorage : { read<T>(key: string): Promise<T | null>; write<T>(key: string, value: T): Promise<void> }. Générique sur la valeur stockée ; la clé est préfixée par l’appelant.
  • createMemoryStorage(initial?: Record<string, unknown>): GuideStorage : une Map le temps de vie de la page. Le choix pour les tests.
  • createBrowserStorage(namespace = 'guide'): GuideStorage : du JSON dans localStorage sous <namespace>:<key>. Renvoie null au lieu de lever une exception quand le stockage est indisponible.
  • isTourProgress(value: unknown): value is TourProgress : garde utilisée à la lecture. Exige un stepIndex entier positif ou nul et un status connu.
  • isChecklistProgress(value: unknown): value is ChecklistProgress : garde exigeant un tableau de chaînes et un booléen.
  • Translate : (key: string) => string. Le point d’entrée de traduction du provider.
  • resolveText(value: string | undefined, key: string | undefined, translate: Translate | undefined): string : renvoie value s’il est défini, sinon la traduction de key, sinon la clé brute, sinon une chaîne vide.

Cœur : l’union GuideEvent

GuideEvent est l’union discriminée passée à onEvent. Les variantes de visite sont émises par GuideProvider, celles de checklist par ChecklistProvider, celles de hotspot par HotspotProvider.

Variante Charge Émise quand
tour:start tourId, stepIndex start() aboutit, avec l’index de départ réel, reprise comprise
tour:complete tourId next() est appelé sur la dernière étape
tour:stop tourId, stepIndex stop() est appelé
step:show tourId, stepIndex, target La visite est en cours et l’élément cible de l’étape a été résolu
target:missing tourId, stepIndex, target L’attente d’une cible expire, avant application de la politique
checklist:item-complete checklistId, itemId Un élément passe de non terminé à terminé
checklist:complete checklistId Le dernier élément restant se termine
checklist:dismiss checklistId dismiss() est appelé
hotspot:show hotspotId Le marqueur d’un hotspot est réellement dessiné à l’écran. Émis une fois par hotspot et par montage.
hotspot:open hotspotId La bulle du hotspot s’ouvre, ce qui le marque aussi comme vu. Ne se répète pas pour une bulle déjà ouverte.

Deux silences valent d’être connus. Décocher un élément n’émet rien, et ni checklist:item-complete ni checklist:complete ne se répètent pour un élément déjà coché. Et la politique error arrête la visite sans tour:stop : seul un stop() explicite l’émet, donc c’est target:missing qu’il faut surveiller dans ce cas.

Cœur : providers

  • GuideProvider(props: GuideProviderProps) : détient l’état de la visite, résout les cibles, délègue la navigation et persiste la progression. Lève une exception sur des identifiants de visite en double.
  • GuideProviderProps : { tours, children, navigate?, location?, storage?, translate?, onEvent?, onMissingTarget = 'wait', targetTimeoutMs = 5000 }.
  • GuideContext : React.Context<GuideContextValue | null>. Exporté pour un rendu maison.
  • GuideContextValue : { state, activeStep, start, next, previous, stop }.
  • ActiveStep : { tourId, step, stepIndex, stepCount, element, rect, interactive, awaitsAction, title, body, isFirst, isLast, next, previous, stop }. Tout ce dont un rendu a besoin pour l’étape courante. interactive et awaitsAction sont dérivés, pas lus directement sur step : interactive vaut vrai quand l’étape pose interactive: true ou déclare advanceOn ; awaitsAction ne vaut vrai que quand l’étape déclare advanceOn. Les rendus lisent ces valeurs, pas step.interactive, qui reste undefined sur une étape qui ne déclare que advanceOn. Voir Visites.
  • ChecklistProvider(props: ChecklistProviderProps) : détient la progression des checklists, coche les éléments quand leur visite se termine, et persiste. Imbriquez-le dans GuideProvider pour que les éléments à tourId fonctionnent.
  • ChecklistProviderProps : { checklists, children, storage?, translate?, navigate?, onEvent? }.
  • ChecklistContext : React.Context<ChecklistContextValue | null>.
  • ChecklistContextValue : { checklists, progress, translate?, restored, activate, toggle, complete, dismiss, reset }. Les méthodes du contexte prennent (checklistId, itemId). restored est indexé par identifiant de checklist, une entrée par checklist.
  • HotspotProvider(props: HotspotProviderProps) : détient les hotspots déjà ouverts, lance la visite d’un hotspot, et persiste. Imbriquez-le dans GuideProvider pour que le tourId d’un hotspot fonctionne. Lève une exception sur des identifiants de hotspot en double. Voir Hotspots.
  • HotspotProviderProps : { hotspots, children, storage?, translate?, onEvent? }.
  • HotspotContext : React.Context<HotspotContextValue | null>.
  • HotspotContextValue : { hotspots, seen, translate?, restored, open, startTour, reset, notifyShown }.

Cœur : hooks

  • useTour(tourId: string): UseTourResult : pilote une visite. Lève une exception hors d’un GuideProvider.
  • UseTourResult : { start(options?: { from?: number; resume?: boolean }): Promise<void>; next; previous; stop; status: TourStatus; stepIndex: number }. status et stepIndex valent 'idle' et 0 quand une autre visite est la visite courante. Il n’y a pas de complete() : une visite se termine quand next() est appelé sur sa dernière étape.
  • useGuideStep(): ActiveStep | null : l’étape courante, ou null si aucune visite n’est active. Le hook sur lequel se construit un rendu maison.
  • useChecklist(checklistId: string): UseChecklistResult : les éléments résolus et les actions d’une checklist. Lève une exception hors d’un ChecklistProvider, et sur un identifiant inconnu.
  • UseChecklistResult : { items: ResolvedChecklistItem[]; completedCount; total; isComplete; dismissed; restored; activate(itemId); toggle(itemId); complete(itemId); dismiss(); reset() }. restored indique si la lecture initiale de stockage propre à cette checklist s’est terminée : true immédiatement sans prop storage, true une fois que la lecture propre à cette checklist a abouti ou échoué. Se règle indépendamment par checklist. Voir Checklist.
  • useHotspots(): UseHotspotsResult : tous les hotspots et les actions sur l’ensemble. Lève une exception hors d’un HotspotProvider.
  • UseHotspotsResult : { hotspots: ResolvedHotspot[]; restored: boolean; open(hotspotId): void; startTour(hotspotId): void; reset(): void; notifyShown(hotspotId): void }. hotspots liste tous les hotspots, y compris ceux déjà vus, chacun avec son propre seen. restored a la même forme que celui de useChecklist : la lecture initiale de stockage s’est-elle terminée. open marque un hotspot comme vu et émet hotspot:open. startTour lance la visite nommée par le tourId du hotspot, s’il en a un. notifyShown est pour les rendus : à appeler une fois qu’un marqueur est effectivement dessiné, pour que hotspot:show s’émette une fois par hotspot et par montage. Voir Hotspots.

Cœur : machine à états

  • TourState : { tourId: string | null; stepIndex: number; status: TourStatus }.
  • TourAction : START | NEXT | PREVIOUS | PAUSE | RESUME | STOP. START porte tourId et stepIndex ; NEXT porte stepCount.
  • initialTourState: TourState : { tourId: null, stepIndex: 0, status: 'idle' }.
  • tourReducer(state: TourState, action: TourAction): TourState : réducteur pur. NEXT sur la dernière étape passe à completed ; NEXT et PREVIOUS depuis paused relancent la visite.

Cœur : routage

  • matchRoute(pattern: string, pathname: string): boolean : comparaison segment par segment, acceptant :param et un joker * qui accepte tout à partir de ce segment. La chaîne de requête et la barre oblique finale sont ignorées.
  • isLiteralRoute(pattern: string): boolean : vrai quand le motif ne contient ni : ni *, c’est-à-dire quand il peut servir de destination de navigation.

Cœur : aides DOM

  • useTargetElement(target: string | null, options?: UseTargetElementOptions): { element: HTMLElement | null; timedOut: boolean } : résout [data-guide="<target>"], attend avec un MutationObserver, et signale l’expiration sans renoncer à une apparition ultérieure.
  • UseTargetElementOptions : { timeoutMs = 5000; attribute = 'data-guide' }.
  • useElementRect(element: HTMLElement | null): Rect | null : mesure avant peinture et remesure au défilement, au redimensionnement et sur notification de ResizeObserver.
  • findMissingTargets(tour: Tour, location: string | undefined, attribute = 'data-guide'): string[] : les cibles des étapes valides sur cette route qui ne sont pas dans le DOM. Utilisé par l’avertissement de développement du provider, utilisable dans vos propres tests.

Cœur : primitives d’accessibilité

  • useFocusTrap(container: HTMLElement | null, active: boolean, options?: UseFocusTrapOptions): void : fait tourner Tab dans le conteneur et rend le focus à l’élément précédent au démontage.
  • UseFocusTrapOptions : { initialFocus?: 'first' | 'container' }. 'container' exige tabIndex={-1} sur le conteneur.
  • useAnnouncer(): (message: string) => void : écrit dans un nœud unique et partagé, masqué visuellement, en aria-live="polite".
  • usePrefersReducedMotion(): boolean : suit (prefers-reduced-motion: reduce), y compris les changements faits en cours de session.

Paquet MUI

  • GuideTour(props?: GuideTourProps) : le seul composant qu’une visite demande. Rend le voile et le popover de l’étape active, null avant le montage, et un gestionnaire d’Échap seul pendant l’attente d’une cible.
  • GuideTourProps : { zIndex?, padding?, radius?, labels? }.
  • StepPopover(props: StepPopoverProps) : la boîte de dialogue d’étape : titre, corps, compteur de position, boutons Précédent et Suivant, bouton de fermeture, flèches et Échap. Quand l’étape attend une action, Suivant est remplacé par le libellé awaitingAction et ArrowRight est ignorée.
  • StepPopoverProps : { anchorEl, open, title, body, stepIndex, stepCount, isFirst, isLast, placement = 'bottom', zIndex?, describeElement?, modal = true, awaitsAction = false, labels?, onNext, onPrevious, onStop }.
  • StepPopoverLabels : { next; previous; finish; close; awaitingAction }, par défaut Next, Back, Finish, Close, Click the highlighted element to continue.. close est le nom accessible du bouton de fermeture ; awaitingAction s’affiche à la place du bouton principal pendant que l’étape attend l’action de l’utilisateur.
  • Spotlight(props: SpotlightProps) : le voile assombrissant, percé d’un trou sur la cible. Cliquer hors du trou arrête la visite ; cliquer dedans ne fait rien, sauf si l’étape est interactive.
  • SpotlightProps : { rect, padding = 8, radius = 8, interactive = false, zIndex?, onDismiss? }.
  • Hotspots(props?: HotspotsProps) : dessine un marqueur à la cible de chaque hotspot non vu ; cliquer dessus ouvre une bulle avec le titre du hotspot, son corps, et, s’il nomme un tourId, un bouton qui lance cette visite. Rend null tant que restored n’est pas vrai, et pendant qu’une visite est en cours ou en pause. Voir Hotspots.
  • HotspotsProps : { labels?, placement = 'bottom', zIndex? }.
  • HotspotLabels : { marker: (title: string) => string; startTour: string; close: string }, avec startTour par défaut à Show me et close à Close. marker est une fonction et non une chaîne fixe, parce que l’ordre des mots autour d’un nom varie d’une langue à l’autre ; sa valeur par défaut est (title) => `Show what is new: ${title}`.
  • Checklist(props: ChecklistProps) : la liste elle-même : barre de progression, une ligne par élément, un bouton de fermeture. Rend null tant que restored n’est pas vrai, et une fois fermée.
  • ChecklistProps : { checklistId, title?, onDismiss?, onActivate?, labels? }. onActivate reçoit le ResolvedChecklistItem.
  • ChecklistLabels : { dismiss: string; progress: (completedCount: number, total: number) => string; markComplete: (itemTitle: string) => string; markNotComplete: (itemTitle: string) => string }, par défaut Dismiss, <n> of <total>, Mark <titre> as complete et Mark <titre> as not complete. labels accepte un Partial : ce que vous n’indiquez pas garde sa valeur par défaut.
  • ChecklistLauncher(props: ChecklistLauncherProps) : un bouton d’angle affichant fait/total avec un anneau de progression, qui ouvre la checklist dans un popover modal.
  • ChecklistLauncherProps : { checklistId, title?, placement = 'bottom-right', labels? }, le placement étant l’un des quatre angles.
  • ChecklistLauncherLabels : étend ChecklistLabels avec fabLabel: (title: string, completedCount: number, total: number) => string et dismissed: (title: string) => string, par défaut <titre>, <n> of <total> complete et <titre> dismissed. Le lanceur transmet les libellés résolus à la Checklist qu’il rend dans son popover : un seul objet couvre les deux.

Pour aller plus loin

  • Démarrage pour l’installation et la première visite.
  • Hotspots pour la fonctionnalité à laquelle appartiennent ces types et ces hooks.
  • Persistance pour GuideStorage en détail.
  • Accessibilité pour ce que garantissent les primitives d’accessibilité.