EN DIRECT · AUDIT CHAÎNÉ · ÉDR UE
SYSTÈME · 99,99% DISPONIBILITÉ
v 1.0 ↗ FAIT EN UE

@nexbasira/react

Wrapper React autour de @nexbasira/embed. Deux surfaces — un composant <NexBasiraSession> prêt à l'emploi pour le cas courant, plus un hook useNexBasiraSession() pour les mises en page personnalisées.

Installation

npm install @nexbasira/react @nexbasira/embed react

react et @nexbasira/embed sont des peer dependencies — elles ne sont pas incluses dans ce package.

Composant

import { NexBasiraSession } from "@nexbasira/react";

function InspectionPage({ joinUrl }: { joinUrl: string }) {
  return (
    <NexBasiraSession
      sessionUrl={joinUrl}
      height="720px"
      onSessionComplete={(id) => navigate(`/inspections/${id}`)}
    />
  );
}

sessionUrl est l'URL à usage unique que votre backend récupère depuis sessions.invite() sur le SDK Node / Python. Le composant monte l'iframe au premier rendu et la détruit proprement au démontage.

Accès impératif via ref

Utilisez une ref lorsque les contrôles côté terrain vivent en dehors de l'iframe (barre d'outils au-dessus du composant, déclencheur de modale, etc.) :

import { useRef } from "react";
import { NexBasiraSession, type NexBasiraSessionHandle } from "@nexbasira/react";

function Toolbar({ joinUrl }: { joinUrl: string }) {
  const session = useRef<NexBasiraSessionHandle>(null);
  return (
    <>
      <button onClick={() => session.current?.requestSnapshot()}>Capture</button>
      <button onClick={() => session.current?.openWhiteboard()}>Whiteboard</button>
      <button onClick={() => session.current?.endSession()}>End</button>
      <NexBasiraSession ref={session} sessionUrl={joinUrl} />
    </>
  );
}

Variante avec hook

Lorsque le <div> wrapper ne convient pas à votre mise en page — par exemple si vous voulez l'iframe dans un conteneur flex avec une barre latérale — utilisez le hook + attachez la ref renvoyée à votre propre élément hôte :

import { useNexBasiraSession } from "@nexbasira/react";

function CustomLayout({ joinUrl }: { joinUrl: string }) {
  const [containerRef, widget] = useNexBasiraSession({
    sessionUrl: joinUrl,
    onSessionComplete: (id) => navigate(`/inspections/${id}`),
  });

  return (
    <div className="grid grid-cols-[1fr_240px] gap-4">
      <div ref={containerRef} style={{ minHeight: 600 }} />
      <aside>
        <button onClick={() => widget.current?.requestSnapshot()}>Snap</button>
      </aside>
    </div>
  );
}

Les callbacks de cycle de vie restent frais à travers les rendus

Le widget embed est créé une seule fois par sessionUrl. Pour garantir que vos callbacks voient toujours la dernière closure (fermant sur le dernier état), le wrapper les stocke en interne dans un useRef et les relit à chaque événement. Vous pouvez passer des fonctions fléchées inline en toute sécurité :

function Page() {
  const [count, setCount] = useState(0);
  return (
    <NexBasiraSession
      sessionUrl={joinUrl}
      onEvidenceAdded={() => {
        // 'count' is always the latest value, not the value at mount
        setCount(count + 1);
      }}
    />
  );
}

Quand l'iframe est-elle reconstruite ?

Uniquement lorsque sessionUrl change. Toute autre prop (callbacks, width, height, expectedOrigin) s'applique sur place sans remontage. Autrement dit, changer un callback ou redimensionner l'hôte ne redémarre pas la session en direct — utile quand votre application se re-rend fréquemment.

Props

PropTypeNotes
sessionUrlstringRequis. Émis par votre backend.
width / heightstringTailles CSS. Par défaut 100% / 600px.
expectedOriginstringRedéfinit l'origine de l'iframe en cas d'hébergement sur un domaine personnalisé.
classNamestringAppliqué au div wrapper.
styleCSSPropertiesAppliqué au div wrapper.
on* callbacksfunctionMême surface que @nexbasira/embed — voir cette page.

Handle typé

import type { NexBasiraSessionHandle } from "@nexbasira/react";

const ref = useRef<NexBasiraSessionHandle>(null);
// ref.current has typed methods: requestSnapshot(), openWhiteboard(), etc.

Et ensuite