LIVE · AUDIT-KEDJA · EU-VÄRD
SYSTEM · 99,99 % DRIFTSTID
v 1.0 ↗ TILLVERKAT I EU

@nexbasira/react

React-wrapper runt @nexbasira/embed. Två ytor — en färdig <NexBasiraSession>-komponent för det vanliga fallet, plus en useNexBasiraSession()-hook för anpassade layouter.

Installera

npm install @nexbasira/react @nexbasira/embed react

react och @nexbasira/embed är peer-beroenden — de buntas inte med det här paketet.

Komponent

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

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

sessionUrl är den engångs-URL som din backend får tillbaka från sessions.invite() i Node/Python-SDK:n. Komponenten monterar iframen vid första renderingen och river ned den rent vid unmount.

Imperativ åtkomst via ref

Använd en ref när fältsidans kontroller ligger utanför iframen (verktygsrad ovanför komponenten, modal-trigger, osv.):

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-variant

När wrapper-<div>:en inte passar din layout — säg att du vill ha iframen i en flex-container med en sidopanel — använd hooken + fäst den returnerade refen på ditt eget värdelement:

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

Livscykel-callbacks förblir färska över omrenderingar

Embed-widgeten skapas en gång per sessionUrl. För att säkerställa att dina callbacks alltid ser den senaste closuren (som sluter över det senaste tillståndet) lagrar wrappern dem internt i en useRef och läser om dem vid varje händelse. Du kan skicka inline-pilfunktioner tryggt:

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

När byggs iframen om?

Bara när sessionUrl ändras. Alla andra props (callbacks, bredd, höjd, expectedOrigin) appliceras på plats utan att montera om. Det betyder att ändra en callback eller ändra storlek på värden inte startar om den live-sessionen — användbart när din app renderar om ofta.

Props

PropTypAnteckningar
sessionUrlstringObligatoriskt. Präglat av din backend.
width / heightstringCSS-storlekar. Standard 100% / 600px.
expectedOriginstringÅsidosätt iframe-origin om du hostar på en egen domän.
classNamestringAppliceras på wrapper-diven.
styleCSSPropertiesAppliceras på wrapper-diven.
on* callbacksfunctionSamma yta som @nexbasira/embed — se den sidan.

Typat handtag

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

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

Vad händer nu