import { Component, type ErrorInfo, type ReactNode } from "react"; export interface ExtensionSlotBoundaryProps { children?: ReactNode; fallback?: ReactNode; resetKey?: unknown; onError?: (error: Error, info: ErrorInfo) => void; } interface ExtensionSlotBoundaryState { failed: boolean; } /** Keep an optional extension failure local to its slot. */ export class ExtensionSlotBoundary extends Component< ExtensionSlotBoundaryProps, ExtensionSlotBoundaryState > { state: ExtensionSlotBoundaryState = { failed: false }; static getDerivedStateFromError(): ExtensionSlotBoundaryState { return { failed: true }; } componentDidUpdate(previous: ExtensionSlotBoundaryProps): void { if (this.state.failed && previous.resetKey !== this.props.resetKey) { this.setState({ failed: false }); } } componentDidCatch(error: Error, info: ErrorInfo): void { if (this.props.onError) { try { this.props.onError(error, info); } catch (reportingError) { console.error( "[b3-swatches] Extension error reporter failed.", reportingError, ); console.error( "[b3-swatches] Extension-rendered admin UI failed.", error, info.componentStack, ); } return; } console.error( "[b3-swatches] Extension-rendered admin UI failed.", error, info.componentStack, ); } render() { if (this.state.failed) return this.props.fallback ?? null; return this.props.children; } }