LIVE · LANȚ DE AUDIT · UE
SISTEM · 99,99% UPTIME
v 1.0 ↗ FĂCUT ÎN UE

@nexbasira/react

Wrapper React în jurul @nexbasira/embed. Două suprafețe — o componentă <NexBasiraSession> gata de folosit pentru cazul comun, plus un hook useNexBasiraSession() pentru layout-uri personalizate.

Instalare

npm install @nexbasira/react @nexbasira/embed react

react și @nexbasira/embed sunt dependențe peer — nu sunt împachetate cu acest pachet.

Componentă

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

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

sessionUrl este URL-ul de unică folosință pe care backend-ul dvs. îl primește de la sessions.invite() din SDK-ul Node / Python. Componenta montează iframe-ul la primul render și îl distruge curat la demontare.

Acces imperativ prin ref

Folosiți un ref atunci când controalele de partea de teren se află în afara iframe-ului (bară de instrumente deasupra componentei, declanșator de modal 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} />
    </>
  );
}

Varianta cu hook

Când wrapper-ul <div> nu se potrivește layout-ului dvs. — de exemplu, doriți iframe-ul într-un container flex cu o bară laterală — folosiți hook-ul + atașați ref-ul returnat propriului element gazdă:

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

Callback-urile de ciclu de viață rămân actualizate între render-uri

Widget-ul de embed este creat o singură dată per sessionUrl. Pentru a vă asigura că callback-urile dvs. văd întotdeauna cel mai recent closure (închizându-se peste cel mai recent state), wrapper-ul le stochează intern într-un useRef și le recitește la fiecare eveniment. Puteți transmite în siguranță funcții arrow inline:

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

Când se reconstruiește iframe-ul?

Doar când se schimbă sessionUrl. Orice altă prop (callback-uri, width, height, expectedOrigin) se aplică în loc, fără remontare. Asta înseamnă că schimbarea unui callback sau redimensionarea gazdei nu repornește sesiunea live — util când aplicația dvs. face re-render frecvent.

Props

PropTipNote
sessionUrlstringObligatoriu. Emis de backend-ul dvs.
width / heightstringDimensiuni CSS. Implicit 100% / 600px.
expectedOriginstringSuprascrie originea iframe-ului dacă găzduiți pe un domeniu personalizat.
classNamestringAplicat pe div-ul wrapper.
styleCSSPropertiesAplicat pe div-ul wrapper.
on* callbacksfunctionAceeași suprafață ca @nexbasira/embed — vedeți acea pagină.

Handle tipizat

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

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

Ce urmează