LIVE · AUDIT-KETTE · EU-ANSÄSSIG
SYSTEM · 99,99 % VERFÜGBARKEIT
v 1.0 ↗ HERGESTELLT IN DER EU

@nexbasira/react

React-Wrapper um @nexbasira/embed. Zwei Oberflächen — eine Drop-in-<NexBasiraSession>-Komponente für den Normalfall, plus ein useNexBasiraSession()-Hook für benutzerdefinierte Layouts.

Installation

npm install @nexbasira/react @nexbasira/embed react

react und @nexbasira/embed sind Peer-Dependencies — sie werden nicht mit diesem Paket gebundelt.

Komponente

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

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

sessionUrl ist die Einmal-URL, die Ihr Backend von sessions.invite() im Node- / Python-SDK zurückerhält. Die Komponente mountet das iframe beim ersten Render und zerstört es sauber beim Unmount.

Imperativer Zugriff via ref

Nutzen Sie ein ref, wenn die Feldseiten-Steuerungen außerhalb des iframe leben (Toolbar über der Komponente, Modal-Trigger usw.):

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} />
    </>
  );
}

Hook-Variante

Wenn das umschließende <div> nicht zu Ihrem Layout passt — etwa wenn Sie das iframe in einem Flex-Container mit einer Sidebar möchten — nutzen Sie den Hook + hängen Sie das zurückgegebene ref an Ihr eigenes Host-Element:

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>
  );
}

Lifecycle-Callbacks bleiben über Renders hinweg frisch

Das Embed-Widget wird einmal pro sessionUrl erstellt. Damit Ihre Callbacks immer die neueste Closure sehen (über den neuesten State schließen), speichert der Wrapper sie intern in einem useRef und liest sie bei jedem Event neu. Sie können inline-Arrow-Funktionen gefahrlos übergeben:

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);
      }}
    />
  );
}

Wann wird das iframe neu gebaut?

Nur wenn sich sessionUrl ändert. Jede andere Prop (Callbacks, width, height, expectedOrigin) wird in-place angewendet, ohne neu zu mounten. Das bedeutet, ein Callback zu ändern oder den Host zu skalieren startet die Live-Sitzung nicht neu — nützlich, wenn Ihre App häufig re-rendert.

Props

PropTypAnmerkungen
sessionUrlstringErforderlich. Von Ihrem Backend geprägt.
width / heightstringCSS-Größen. Standard 100% / 600px.
expectedOriginstringiframe-Origin überschreiben, falls auf einer eigenen Domain gehostet.
classNamestringWird auf das Wrapper-div angewendet.
styleCSSPropertiesWird auf das Wrapper-div angewendet.
on* callbacksfunctionGleiche Oberfläche wie @nexbasira/embed — siehe jene Seite.

Typisiertes Handle

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

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

Was als Nächstes kommt