EN VIVO · CON AUDITORÍA · UE
SISTEMA · 99,99% UPTIME
v 1.0 ↗ HECHO EN UE

@nexbasira/react

Wrapper de React en torno a @nexbasira/embed. Dos superficies — un componente <NexBasiraSession> listo para usar para el caso común, más un hook useNexBasiraSession() para diseños personalizados.

Instalar

npm install @nexbasira/react @nexbasira/embed react

react y @nexbasira/embed son dependencias de par (peer dependencies) — no se incluyen con este paquete.

Componente

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

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

sessionUrl es la URL de un solo uso que su backend recibe de sessions.invite() en el SDK de Node / Python. El componente monta el iframe en el primer renderizado y lo destruye limpiamente al desmontarse.

Acceso imperativo mediante ref

Utilice una ref cuando los controles del lado de campo viven fuera del iframe (barra de herramientas encima del componente, activador 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} />
    </>
  );
}

Variante con hook

Cuando el <div> del wrapper no encaja en su diseño —por ejemplo, si desea el iframe en un contenedor flex con una barra lateral— utilice el hook y adjunte la ref devuelta a su propio elemento anfitrión:

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

Las callbacks de ciclo de vida se mantienen actualizadas entre renderizados

El widget de embed se crea una vez por sessionUrl. Para asegurar que sus callbacks siempre vean el closure más reciente (capturando el último estado), el wrapper las almacena internamente en un useRef y las vuelve a leer en cada evento. Puede pasar funciones flecha en línea de forma segura:

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

¿Cuándo se reconstruye el iframe?

Solo cuando cambia sessionUrl. Cualquier otra prop (callbacks, width, height, expectedOrigin) se aplica en el sitio sin volver a montar. Esto significa que cambiar una callback o redimensionar el anfitrión no reinicia la sesión en vivo — útil cuando su aplicación se vuelve a renderizar con frecuencia.

Props

PropTipoNotas
sessionUrlstringObligatorio. Generado por su backend.
width / heightstringTamaños CSS. Predeterminado 100% / 600px.
expectedOriginstringAnula el origen del iframe si aloja en un dominio personalizado.
classNamestringSe aplica al div del wrapper.
styleCSSPropertiesSe aplica al div del wrapper.
on* callbacksfunctionMisma superficie que @nexbasira/embed — véase esa página.

Handle tipado

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

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

Qué sigue