{"version":3,"file":"ahroweProvider.mjs","names":[],"sources":["../../../../package/common/ahroweProvider/ahroweProvider.tsx"],"sourcesContent":["import {\n  useCallback,\n  useContext,\n  useEffect,\n  useLayoutEffect,\n  useState,\n  useSyncExternalStore,\n  type ReactElement,\n} from 'react';\n\nimport ConfigProvider from 'components/common/configProvider';\nimport ScrollbarProvider from 'components/common/scrollbarProvider';\nimport ThemeProvider from 'components/common/themeProvider';\nimport ToastHost from '../toast/toastHost';\nimport { PortalHostContext } from '../bodyEnd/portalHostContext';\nimport type { AhroweProviderProps } from './ahroweProvider.types';\n\nconst subscribeToNothing = () => () => {};\n\nfunction AhroweProvider({\n  children,\n  themes,\n  currentThemeId,\n  defaultProps,\n  presentation,\n  navigate,\n  locale,\n  toast,\n  scrollbars,\n}: AhroweProviderProps): ReactElement {\n  // A nested provider themes and configures its section only. A second toast list would stack\n  // over the first in the same corner, and a second host would split the portals in two.\n  const isNested = useContext(PortalHostContext) !== undefined;\n\n  // The server renders no portal, so hydration must not either: `false` there, and `true` from\n  // the first render of an app that is not hydrating.\n  const canPortal = useSyncExternalStore(\n    subscribeToNothing,\n    () => true,\n    () => false,\n  );\n\n  // Created up front instead of rendered: a rendered host exists only after the first commit, so\n  // a modal open on the first render mounted a commit late and its initial focus found nothing.\n  const [host] = useState(() => (typeof document === 'undefined' ? null : document.createElement('div')));\n\n  // Attached from a marker before the app, because refs attach in tree order: this way the host is\n  // in the page before any layout effect runs. The slot stays last, so panels paint above the app.\n  const attachHost = useCallback(\n    (marker: HTMLTemplateElement | null) => {\n      const slot = marker?.parentElement?.lastElementChild;\n      if (!slot || !host) return;\n      // No cleanup, and no move when already in place: the host leaves with its slot anyway, and\n      // StrictMode's extra detach and reattach otherwise took a focused element in it along.\n      if (host.parentNode !== slot) slot.appendChild(host);\n    },\n    [host],\n  );\n\n  // Read from the host rather than `themes`, for the resolved value, `var()` references included.\n  const stylesPage = !isNested && scrollbars !== false;\n  useLayoutEffect(() => {\n    if (!stylesPage || !host) return;\n    const thumb = getComputedStyle(host).getPropertyValue('--background-accent-light').trim();\n    const page = document.documentElement.style;\n    page.setProperty('--ahrowe-page-scrollbar-thumb', thumb);\n    return () => {\n      page.removeProperty('--ahrowe-page-scrollbar-thumb');\n    };\n  }, [stylesPage, host, themes, currentThemeId]);\n\n  const ignoresRootProps = isNested && (toast !== undefined || scrollbars !== undefined);\n  useEffect(() => {\n    if (ignoresRootProps) {\n      console.warn(\n        '[AhroweProvider] `toast` and `scrollbars` are read by the outermost AhroweProvider only. Set them there.',\n      );\n    }\n  }, [ignoresRootProps]);\n\n  const root = (\n    <PortalHostContext.Provider value={canPortal ? host : null}>\n      <template ref={attachHost} />\n      <ToastHost {...toast}>{children}</ToastHost>\n      <div />\n    </PortalHostContext.Provider>\n  );\n\n  return (\n    <ConfigProvider defaultProps={defaultProps} presentation={presentation} navigate={navigate} locale={locale}>\n      <ThemeProvider themes={themes} currentThemeId={currentThemeId}>\n        {/* Around the portal slot too, so the scrollbars of the panels in it are styled as well. */}\n        {isNested ? children : scrollbars === false ? root : <ScrollbarProvider>{root}</ScrollbarProvider>}\n      </ThemeProvider>\n    </ConfigProvider>\n  );\n}\n\nexport default AhroweProvider;\n"],"mappings":"8bAiBA,IAAM,UAAiC,CAAC,EAExC,SAAS,EAAe,CACtB,WACA,SACA,iBACA,eACA,eACA,WACA,SACA,QACA,cACoC,CAGpC,IAAM,EAAW,EAAW,CAAiB,IAAM,IAAA,GAI7C,EAAY,EAChB,MACM,OACA,EACR,EAIM,CAAC,GAAQ,MAAgB,OAAO,SAAa,IAAc,KAAO,SAAS,cAAc,KAAK,CAAE,EAIhG,EAAa,EAChB,GAAuC,CACtC,IAAM,EAAO,GAAQ,eAAe,iBAC/B,GAAS,GAGV,EAAK,aAAe,GAAM,EAAK,YAAY,CAAI,CACrD,EACA,CAAC,CAAI,CACP,EAGM,EAAa,CAAC,GAAY,IAAe,GAC/C,MAAsB,CACpB,GAAI,CAAC,GAAc,CAAC,EAAM,OAC1B,IAAM,EAAQ,iBAAiB,CAAI,CAAC,CAAC,iBAAiB,2BAA2B,CAAC,CAAC,KAAK,EAClF,EAAO,SAAS,gBAAgB,MAEtC,OADA,EAAK,YAAY,gCAAiC,CAAK,MAC1C,CACX,EAAK,eAAe,+BAA+B,CACrD,CACF,EAAG,CAAC,EAAY,EAAM,EAAQ,CAAc,CAAC,EAE7C,IAAM,EAAmB,IAAa,IAAU,IAAA,IAAa,IAAe,IAAA,IAC5E,MAAgB,CACV,GACF,QAAQ,KACN,0GACF,CAEJ,EAAG,CAAC,CAAgB,CAAC,EAErB,IAAM,EACJ,EAAC,EAAkB,SAAnB,CAA4B,MAAO,EAAY,EAAO,KAAtD,SAAA,CACE,EAAC,WAAD,CAAU,IAAK,CAAa,CAAA,EAC5B,EAAC,EAAD,CAAW,GAAI,EAAQ,UAAoB,CAAA,EAC3C,EAAC,MAAD,CAAM,CAAA,CACoB,IAG9B,OACE,EAAC,EAAD,CAA8B,eAA4B,eAAwB,WAAkB,SAClG,SAAA,EAAC,EAAD,CAAuB,SAAwB,iBAE5C,SAAA,EAAW,EAAW,IAAe,GAAQ,EAAO,EAAC,EAAD,CAAA,SAAoB,CAAwB,CAAA,CACpF,CAAA,CACD,CAAA,CAEpB"}