ŽIVĚ · AUDIT CHAIN · EU
SYSTÉM · 99,99 % DOSTUPNOST
v 1.0 ↗ VYROBENO V EU

@nexbasira/react

React wrapper kolem @nexbasira/embed. Dvě rozhraní — drop-in komponenta <NexBasiraSession> pro běžný případ a hook useNexBasiraSession() pro vlastní rozvržení.

Instalace

npm install @nexbasira/react @nexbasira/embed react

react a @nexbasira/embed jsou peer dependencies — nejsou dodávány s tímto balíčkem.

Komponenta

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

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

sessionUrl je jednorázová URL, kterou váš backend získá zpět z sessions.invite() na Node / Python SDK. Komponenta připojí iframe při prvním renderu a při odpojení jej čistě zničí.

Imperativní přístup přes ref

Použijte ref, když terénní ovládací prvky žijí mimo iframe (panel nástrojů nad komponentou, spouštěč modálního okna atd.):

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 s hookem

Když wrapper <div> nevyhovuje vašemu rozvržení — řekněme chcete iframe ve flex kontejneru s postranním panelem — použijte hook a připojte vrácený ref ke svému vlastnímu hostitelskému elementu:

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

Callbacky životního cyklu zůstávají čerstvé napříč rendery

Embed widget je vytvořen jednou na sessionUrl. Aby vaše callbacky vždy viděly nejnovější closure (uzavírající nad nejnovějším stavem), wrapper je interně ukládá do useRef a znovu je načítá při každé události. Můžete bezpečně předávat inline arrow funkce:

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

Kdy se iframe znovu sestaví?

Pouze když se změní sessionUrl. Každá jiná prop (callbacky, šířka, výška, expectedOrigin) se aplikuje na místě bez opětovného připojení. To znamená, že změna callbacku nebo změna velikosti hostitele nerestartuje živou relaci — užitečné, když se vaše aplikace často re-renderuje.

Props

PropTypPoznámky
sessionUrlstringPovinné. Vytvořeno vaším backendem.
width / heightstringCSS rozměry. Výchozí 100% / 600px.
expectedOriginstringPřepsat origin iframu při hostování na vlastní doméně.
classNamestringAplikováno na wrapper div.
styleCSSPropertiesAplikováno na wrapper div.
on* callbackyfunctionStejné rozhraní jako @nexbasira/embed — viz tuto stránku.

Typovaný handle

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

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

Co dál