@nexbasira/react
Wrapper React wokół @nexbasira/embed. Dwie powierzchnie — gotowy do wstawienia komponent <NexBasiraSession> dla typowego przypadku oraz hook useNexBasiraSession() dla niestandardowych układów.
Instalacja
npm install @nexbasira/react @nexbasira/embed react react i @nexbasira/embed są zależnościami peer — nie są dołączane do tego pakietu.
Komponent
import { NexBasiraSession } from "@nexbasira/react";
function InspectionPage({ joinUrl }: { joinUrl: string }) {
return (
<NexBasiraSession
sessionUrl={joinUrl}
height="720px"
onSessionComplete={(id) => navigate(`/inspections/${id}`)}
/>
);
} sessionUrl to jednorazowy URL, który Twój backend otrzymuje z sessions.invite() w SDK Node / Python. Komponent montuje iframe przy pierwszym renderze i czysto go niszczy przy odmontowaniu.
Dostęp imperatywny przez ref
Użyj ref, gdy kontrolki strony terenowej znajdują się poza iframe (pasek narzędzi nad komponentem, wyzwalacz modala itp.):
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} />
</>
);
} Wariant z hookiem
Gdy opakowujący <div> nie pasuje do Twojego układu — powiedzmy, że chcesz iframe w kontenerze flex z panelem bocznym — użyj hooka + podłącz zwrócony ref do własnego elementu hosta:
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>
);
} Callbacki cyklu życia pozostają świeże między renderami
Widget embed jest tworzony raz na sessionUrl. Aby zapewnić, że Twoje callbacki zawsze widzą najnowsze domknięcie (obejmujące najnowszy stan), wrapper wewnętrznie przechowuje je w useRef i odczytuje ponownie przy każdym zdarzeniu. Możesz bezpiecznie przekazywać wbudowane funkcje strzałkowe:
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);
}}
/>
);
} Kiedy iframe jest przebudowywany?
Tylko gdy zmieni się sessionUrl. Każdy inny prop (callbacki, szerokość, wysokość, expectedOrigin) stosuje się w miejscu bez ponownego montowania. Oznacza to, że zmiana callbacku lub zmiana rozmiaru hosta nie restartuje sesji na żywo — przydatne, gdy Twoja aplikacja często się renderuje.
Propsy
| Prop | Typ | Uwagi |
|---|---|---|
sessionUrl | string | Wymagane. Tworzone przez Twój backend. |
width / height | string | Rozmiary CSS. Domyślnie 100% / 600px. |
expectedOrigin | string | Nadpisz origin iframe, jeśli hostujesz na własnej domenie. |
className | string | Stosowane do opakowującego diva. |
style | CSSProperties | Stosowane do opakowującego diva. |
on* callbacks | function | Ta sama powierzchnia co @nexbasira/embed — zobacz tamtą stronę. |
Typowany uchwyt
import type { NexBasiraSessionHandle } from "@nexbasira/react";
const ref = useRef<NexBasiraSessionHandle>(null);
// ref.current has typed methods: requestSnapshot(), openWhiteboard(), etc. Co dalej
- @nexbasira/embed — bazowy widget
- @nexbasira/node — utwórz
sessionUrlw swoim backendzie - Źródło na GitHub