import React from "react"; import ReactDOM, { type Root } from "react-dom/client"; import SwatchGroup from "../components/SwatchGroup"; import SwatchErrorBoundary from "../components/ErrorBoundary"; import { safeParseJson } from "./debug"; const mountedRoots = new WeakMap(); /** * Initialize and mount React swatch components */ export const initSwatches = ({ forceRemount = false, SwatchGroupComponent = SwatchGroup, }: { forceRemount?: boolean; SwatchGroupComponent?: React.ComponentType; } = {}) => { const mountPoints = document.querySelectorAll( ".b3-wvs-swatches-mount", ); mountPoints.forEach((mount) => { const container = mount.closest(".b3-wvs-swatches-container"); if (!container) return; if (forceRemount) { mountedRoots.get(mount)?.unmount(); mountedRoots.delete(mount); delete mount.dataset.b3WvsMounted; container.classList.remove("b3-wvs-initialized"); container.classList.add("b3-wvs-fallback"); const original = container.querySelector( ".b3-wvs-original-select", ); if (original) original.style.display = ""; } // Avoid creating multiple React roots for the same mount. if ( container.classList.contains("b3-wvs-initialized") || mount.dataset.b3WvsMounted === "1" ) { return; } const attribute = container.dataset.attribute; const swatchesData = safeParseJson(container.dataset.swatches); const select = container.querySelector("select"); if (!attribute || !(select instanceof HTMLSelectElement)) { return; } const root = ReactDOM.createRoot(mount); mountedRoots.set(mount, root); root.render( , ); // After successful mount, hide the original select UI. mount.dataset.b3WvsMounted = "1"; container.classList.add("b3-wvs-initialized"); container.classList.remove("b3-wvs-fallback"); const original = container.querySelector( ".b3-wvs-original-select", ); if (original) original.style.display = "none"; }); }; /** * Schedule fallback reveal if swatches don't initialize */ let fallbackScheduled = false; export const scheduleFallbackReveal = () => { if (fallbackScheduled) return; fallbackScheduled = true; // If swatches don't initialize (e.g. a JS error), restore the original select UI. // This avoids a blank UI state. window.setTimeout(() => { const containers = document.querySelectorAll( ".b3-wvs-swatches-container", ); containers.forEach((container) => { if (!container.classList.contains("b3-wvs-initialized")) { container.classList.add("b3-wvs-fallback"); } }); }, 3000); };