{"$schema":"https:\/\/ui.particle.academy\/schema\/registry-item.json","name":"fancy-app-root","type":"registry:ui","title":"FancyAppRoot","description":"Inertia app root.","package":"fancy-inertia","dependencies":["@particle-academy\/react-fancy","@particle-academy\/fancy-screens","@particle-academy\/fancy-echarts"],"registryDependencies":[],"files":[{"path":"components\/fancy\/fancy-app-root\/FancyAppRoot.tsx","content":"import { useEffect, lazy, Suspense, type ComponentType, type ReactNode } from \"react\";\r\nimport { Toast } from \"@particle-academy\/react-fancy\";\r\n\r\n\/**\r\n * fancy-screens is an OPTIONAL peer. Importing `ScreenSystem` statically\r\n * would put `@particle-academy\/fancy-screens` in the base import graph, so\r\n * any bundler resolving `fancy-inertia` would hard-fail when it isn't\r\n * installed \u2014 even for consumers who only use `<FancyAppRoot withScreens={false}>`.\r\n * Load it lazily instead, and degrade to a passthrough if it's absent.\r\n *\/\r\nconst Passthrough = ({ children }: { children?: ReactNode }) => <>{children}<\/>;\r\n\r\nconst SCREENS_MISSING =\r\n  \"[fancy-inertia] `withScreens` is on but @particle-academy\/fancy-screens is not available \u2014 rendering children without the ScreenSystem provider. Pass `withScreens={false}` to silence this.\";\r\n\r\nconst ScreenSystemLazy = lazy<ComponentType<{ children?: ReactNode }>>(() =>\r\n  import(\"@particle-academy\/fancy-screens\")\r\n    .then((m) => {\r\n      const Comp = (m as { ScreenSystem?: ComponentType<{ children?: ReactNode }> })?.ScreenSystem;\r\n      \/\/ A bundler resolving an ABSENT optional peer can hand back an\r\n      \/\/ export-less stub ({ default: undefined }) instead of rejecting \u2014 so a\r\n      \/\/ reject-only `.catch` misses it and React.lazy gets `{ default: undefined }`\r\n      \/\/ (React #306). Guard the resolved export, not just rejection.\r\n      if (!Comp) {\r\n        console.warn(SCREENS_MISSING);\r\n        return { default: Passthrough };\r\n      }\r\n      return { default: Comp };\r\n    })\r\n    .catch((err) => {\r\n      console.warn(SCREENS_MISSING, err);\r\n      return { default: Passthrough };\r\n    }),\r\n);\r\n\r\nexport interface FancyAppRootProps {\r\n  children: ReactNode;\r\n\r\n  \/** Toast position. Default `\"bottom-right\"`. *\/\r\n  toastPosition?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\r\n\r\n  \/**\r\n   * Mount fancy-screens' `<Screen.System>` provider. Default `true`. Set\r\n   * `false` if your app doesn't use fancy-screens \u2014 the optional peer is\r\n   * never imported in that case.\r\n   *\/\r\n  withScreens?: boolean;\r\n\r\n  \/**\r\n   * Auto-register echarts modules + built-in themes on mount. Default\r\n   * `true`. Disable if you call `registerCharts(...)` yourself for\r\n   * tree-shaking control, or if fancy-echarts isn't installed.\r\n   *\/\r\n  withECharts?: boolean;\r\n}\r\n\r\n\/**\r\n * Composite top-level provider for the fancy UI set under Inertia.\r\n *\r\n * Mount once in your Inertia app entry, ABOVE the `<Inertia App>` outlet.\r\n * Subsequent page swaps preserve the providers \u2014 toasts survive\r\n * navigation, the screen registry persists, and echarts modules don't\r\n * have to re-register.\r\n *\r\n *   import { createInertiaApp } from \"@inertiajs\/react\";\r\n *   import { FancyAppRoot } from \"@particle-academy\/fancy-inertia\";\r\n *\r\n *   createInertiaApp({\r\n *     setup({ App, props, el }) {\r\n *       createRoot(el).render(\r\n *         <FancyAppRoot>\r\n *           <App {...props} \/>\r\n *         <\/FancyAppRoot>\r\n *       );\r\n *     },\r\n *   });\r\n *\r\n * `fancy-screens` and `fancy-echarts` are optional peers, loaded lazily\r\n * only when `withScreens` \/ `withECharts` are enabled \u2014 the base bundle\r\n * depends on nothing but `react-fancy`.\r\n *\/\r\nexport function FancyAppRoot({\r\n  children,\r\n  toastPosition = \"bottom-right\",\r\n  withScreens = true,\r\n  withECharts = true,\r\n}: FancyAppRootProps) {\r\n  useEffect(() => {\r\n    if (!withECharts) return;\r\n    let cancelled = false;\r\n    void (async () => {\r\n      try {\r\n        const echarts = await import(\"@particle-academy\/fancy-echarts\");\r\n        if (cancelled) return;\r\n        echarts.registerAll?.();\r\n        echarts.registerBuiltinThemes?.();\r\n      } catch (err) {\r\n        console.warn(\r\n          \"[fancy-inertia] `withECharts` is on but @particle-academy\/fancy-echarts is not installed \u2014 skipping chart registration. Pass `withECharts={false}` to silence this.\",\r\n          err,\r\n        );\r\n      }\r\n    })();\r\n    return () => {\r\n      cancelled = true;\r\n    };\r\n  }, [withECharts]);\r\n\r\n  const Inner = withScreens ? (\r\n    <Suspense fallback={null}>\r\n      <ScreenSystemLazy>{children}<\/ScreenSystemLazy>\r\n    <\/Suspense>\r\n  ) : (\r\n    <>{children}<\/>\r\n  );\r\n\r\n  return <Toast.Provider position={toastPosition}>{Inner}<\/Toast.Provider>;\r\n}\r\n\r\nFancyAppRoot.displayName = \"FancyAppRoot\";\r\n","type":"registry:ui","target":"components\/fancy\/fancy-app-root\/FancyAppRoot.tsx"}]}