@wildo-ai/saas-frontend-lib 1.1.6 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/core/app-shell/AppShellBuildingBlocks.d.ts +6 -3
- package/dist/esm/core/app-shell/AppShellBuildingBlocks.d.ts.map +1 -1
- package/dist/esm/core/app-shell/AppShellBuildingBlocks.js +7 -4
- package/dist/esm/core/app-shell/AppShellBuildingBlocks.js.map +1 -1
- package/dist/esm/core/config/chart-view.frontend.schemas.d.ts +14 -14
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +6 -6
- package/dist/esm/core/navigation/useIsStackEntryActive.d.ts +0 -0
- package/dist/esm/core/navigation/useIsStackEntryActive.d.ts.map +0 -0
- package/dist/esm/core/navigation/useIsStackEntryActive.js.map +0 -0
|
@@ -38,9 +38,12 @@ export declare function AppShellProviders({ layout, children }: AppShellProvider
|
|
|
38
38
|
* are TRANSFORMED — a 3D placement. Render it once, inside the providers but OUTSIDE the transformed subtree; the
|
|
39
39
|
* providers then prefer it to `<main>`. A layout that transforms nothing does not need it.
|
|
40
40
|
*
|
|
41
|
-
* It is a zero-size, untransformed
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* It is a zero-size, untransformed box at the shell root's origin (the root fills the viewport), with NO z-index and
|
|
42
|
+
* NOT `position: fixed`: either would make it a stacking context and cap every overlay inside it below anything
|
|
43
|
+
* positioned outside the shell — a consent prompt would paint over the shell's own dialogs (the reordering #1830
|
|
44
|
+
* measured and avoided). So each overlay keeps its own global z-index. An overlay positioned `fixed` still resolves
|
|
45
|
+
* against the viewport (nothing between it and the viewport is transformed), one positioned `absolute` against the
|
|
46
|
+
* root's origin, so floating content lands where its trigger is on screen. The layout's root must be positioned.
|
|
44
47
|
*/
|
|
45
48
|
export declare function AppShellOverlayPortalLayer(): React.JSX.Element;
|
|
46
49
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShellBuildingBlocks.d.ts","sourceRoot":"","sources":["../../../../../src/core/app-shell/AppShellBuildingBlocks.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsE,MAAM,OAAO,CAAC;AAE3F,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAqC,MAAM,qCAAqC,CAAC;AAe1H,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uEAAuE,CAAC;AAEhH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAoE9D;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAMrE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAUxD;AAED,MAAM,WAAW,sBAAsB;IACrC,qGAAqG;IACrG,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,sBAAsB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAqBjG;AAED
|
|
1
|
+
{"version":3,"file":"AppShellBuildingBlocks.d.ts","sourceRoot":"","sources":["../../../../../src/core/app-shell/AppShellBuildingBlocks.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsE,MAAM,OAAO,CAAC;AAE3F,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAqC,MAAM,qCAAqC,CAAC;AAe1H,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uEAAuE,CAAC;AAEhH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAoE9D;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAMrE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAUxD;AAED,MAAM,WAAW,sBAAsB;IACrC,qGAAqG;IACrG,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,sBAAsB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAqBjG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAM9D;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,yBAAyB,GACjC;IAAE,MAAM,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,aAAa,CAAC;IAAC,SAAS,CAAC,EAAE,mBAAmB,CAAC,KAAK,GAAG,mBAAmB,CAAC,GAAG,CAAA;CAAE,GAC5H;IAAE,MAAM,EAAE,WAAW,CAAC,UAAU,CAAC;IAAC,SAAS,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAClE;IAAE,MAAM,EAAE,WAAW,CAAC,YAAY,GAAG,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAExG;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CA8B/F;AAED,MAAM,WAAW,0BAA0B;IACzC,+GAA+G;IAC/G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mHAAmH;IACnH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,0BAA0B,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAW5G;AAED,6GAA6G;AAC7G,wBAAgB,sBAAsB,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAO1D;AACD,qEAAqE"}
|
|
@@ -125,16 +125,19 @@ export function AppShellProviders({ layout, children }) {
|
|
|
125
125
|
* are TRANSFORMED — a 3D placement. Render it once, inside the providers but OUTSIDE the transformed subtree; the
|
|
126
126
|
* providers then prefer it to `<main>`. A layout that transforms nothing does not need it.
|
|
127
127
|
*
|
|
128
|
-
* It is a zero-size, untransformed
|
|
129
|
-
*
|
|
130
|
-
*
|
|
128
|
+
* It is a zero-size, untransformed box at the shell root's origin (the root fills the viewport), with NO z-index and
|
|
129
|
+
* NOT `position: fixed`: either would make it a stacking context and cap every overlay inside it below anything
|
|
130
|
+
* positioned outside the shell — a consent prompt would paint over the shell's own dialogs (the reordering #1830
|
|
131
|
+
* measured and avoided). So each overlay keeps its own global z-index. An overlay positioned `fixed` still resolves
|
|
132
|
+
* against the viewport (nothing between it and the viewport is transformed), one positioned `absolute` against the
|
|
133
|
+
* root's origin, so floating content lands where its trigger is on screen. The layout's root must be positioned.
|
|
131
134
|
*/
|
|
132
135
|
export function AppShellOverlayPortalLayer() {
|
|
133
136
|
const register = useContext(AppShellOverlayLayerTargetContext);
|
|
134
137
|
if (!register) {
|
|
135
138
|
throw new Error('AppShellOverlayPortalLayer must be rendered inside <AppShellProviders>, which exposes it as the portal container.');
|
|
136
139
|
}
|
|
137
|
-
return _jsx("div", { ref: register, "data-shell-overlay-layer": "", className: "
|
|
140
|
+
return _jsx("div", { ref: register, "data-shell-overlay-layer": "", className: "absolute left-0 top-0 h-0 w-0" });
|
|
138
141
|
}
|
|
139
142
|
/**
|
|
140
143
|
* Renders one shell region's component — the registry-resolved wrapper, with its placement prop — when the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShellBuildingBlocks.js","sourceRoot":"","sources":["../../../../../src/core/app-shell/AppShellBuildingBlocks.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';\n\nimport { HorizontalPlacement, ShellRegion, SurfaceVariant, VerticalPlacement } from '@wildo-ai/presets-components-models';\nimport { LoadingSpinner } from '~wildo-frontend-lib/components/feedback/loading-spinner';\nimport { Surface } from '~wildo-frontend-lib/components/sections/surface';\nimport { NON_CANONICAL_SHELL_SURFACE_POLICY_OVERRIDE } from '~wildo-frontend-lib/core/ui/surface-a11y.utils';\nimport { ApplicationLevel_ActivityBar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_ActivityBar';\nimport { ApplicationLevel_MenuBar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_MenuBar';\nimport { ApplicationLevel_QuickActionButton } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_QuickActionButton';\nimport { ApplicationLevel_Sidebar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_Sidebar';\nimport { ApplicationLevel_StatusBar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_StatusBar';\nimport { ApplicationLevel_Toolbar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_Toolbar';\nimport { ApplicationLevel_UtilityPanel } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_UtilityPanel';\nimport { HostedComponentInteractionsProvider } from '~wildo-frontend-lib/components/navigation/app-level/HostedComponentInteractionsProvider';\nimport { GuidanceRenderer } from '~wildo-frontend-lib/core/guidance/GuidanceRenderer';\nimport { NavigationContentAreas, NavigationOverlays } from '~wildo-frontend-lib/core/navigation/NavigationContentAreas';\n\nimport type { StatusBarPlacement } from '~wildo-frontend-lib/core/config/app-level-components.frontend.schemas';\n\nimport type { AppShellLayoutInfo } from './app-shell.schemas';\nimport { PortalContainerContext } from './PortalContainerContext';\n\n/** @wildo_source:part:start saas.frontend.app-shell.building-blocks facet:layer:frontend facet:family:app-shell facet:audience:app-developer */\n/**\n * # App shell building blocks\n *\n * The signed-in shell is a LAYOUT — where the regions sit — over parts that do not depend on the layout: the\n * region components themselves (each resolved from the component registry by its wrapper), the content area,\n * the overlays, and two providers every region reads. These building blocks are those parts, so a layout\n * preset only decides the ARRANGEMENT. `AppLayoutPreset_MainContainer_Default` is composed from them, and any\n * other layout container an application registers should be too — a different arrangement of the same regions,\n * or, later, an alternative rendering that draws decoration around them.\n *\n * A layout preset uses them like this:\n *\n * ```tsx\n * const layout = useAppShellLayout();\n * const hasBeenReady = useAppShellFirstReady(layout.isLayoutReady);\n * if (!layout.isLayoutReady && !hasBeenReady) return <AppShellLoadingState />;\n * return (\n * <AppShellProviders layout={layout}>\n * <div className=\"my-arrangement\">\n * <AppShellRegionOutlet region={ShellRegion.SIDEBAR} placement={HorizontalPlacement.START} />\n * <AppShellRegionOutlet region={ShellRegion.MENUBAR} />\n * <AppShellContentOutlet className=\"flex-1 relative min-w-0\">{children}</AppShellContentOutlet>\n * <AppShellOverlaysOutlet />\n * </div>\n * </AppShellProviders>\n * );\n * ```\n *\n * Four rules keep a custom layout correct:\n *\n * - **Render `AppShellProviders` exactly once, around the whole shell.** It owns the single open state and the\n * single hotkey registration of the command menu, notification center and quick switcher; two copies would\n * make one shortcut open two dialogs.\n * - **Place every region the application configures.** An outlet renders nothing when its region is not\n * configured, so placing an outlet is always safe; leaving one out silently drops a region.\n * - **Render `AppShellContentOutlet` exactly once.** It is the `<main>` landmark, and overlays portal into it —\n * unless the layout also renders `AppShellOverlayPortalLayer`, which then takes the overlays instead. A layout that\n * transforms its regions (a 3D placement) must render that layer OUTSIDE the transformed subtree: a transformed\n * ancestor is the containing block of every `position: fixed` descendant, so a dialog in `<main>` would be confined\n * to the pane and a menu would be placed in the wrong coordinates.\n * - **Give the root `position: relative`, not `isolation: isolate`,** when the theme may declare a background\n * layer. That layer is painted in its own stacking context above ordinary in-flow content, so shell text with\n * no positioned ancestor is painted UNDER it; positioning the root lifts the whole shell above it. `isolate`\n * would also lift it, but would make the shell one stacking context, so an overlay outside the shell with a\n * lower z-index (a consent prompt) would paint over the shell's own dialogs.\n */\n\n/** The layout decisions `useAppShellLayout()` computed, shared with every outlet below the providers. */\nconst AppShellLayoutContext = createContext<AppShellLayoutInfo | null>(null);\n\n/** Lets the content outlet hand its `<main>` element to the providers, which expose it as the portal container. */\nconst AppShellPortalTargetContext = createContext<((node: HTMLElement | null) => void) | null>(null);\n\n/** Lets `AppShellOverlayPortalLayer` hand its element to the providers, which then prefer it over `<main>`. */\nconst AppShellOverlayLayerTargetContext = createContext<((node: HTMLElement | null) => void) | null>(null);\n\nfunction useAppShellLayoutContext(consumer: string): AppShellLayoutInfo {\n const layout = useContext(AppShellLayoutContext);\n if (!layout) {\n throw new Error(`${consumer} must be rendered inside <AppShellProviders>, which supplies the layout it places regions from.`);\n }\n return layout;\n}\n\n/**\n * Latches the FIRST time the shell becomes ready.\n *\n * `isLayoutReady` derives from configuration presence and can drop transiently after bootstrap (an\n * organization switch reloading config, for example). Replacing the mounted shell with a loading state on such\n * a drop would unmount every provider and zone below it and destroy navigation state — the failure mode\n * `AppLoadingGate` documents. So a layout shows its loading state only while this returns `false`.\n */\nexport function useAppShellFirstReady(isLayoutReady: boolean): boolean {\n const [hasLayoutBeenReady, setHasLayoutBeenReady] = useState(false);\n useEffect(() => {\n if (isLayoutReady) setHasLayoutBeenReady(true);\n }, [isLayoutReady]);\n return hasLayoutBeenReady;\n}\n\n/**\n * The shell's loading state: a centred spinner on the page background, announced politely. What every layout\n * shows while `useAppShellFirstReady` says the shell has never been ready — one component rather than a copy per\n * layout, so the loading state is the same whatever the disposal.\n */\nexport function AppShellLoadingState(): React.JSX.Element {\n return (\n <Surface asChild emitPolicyVars={false} variant={SurfaceVariant.SHELL} policyOverride={NON_CANONICAL_SHELL_SURFACE_POLICY_OVERRIDE}>\n <div className=\"h-screen w-screen bg-background flex items-center justify-center\" role=\"status\" aria-live=\"polite\">\n <div className=\"text-center\">\n <LoadingSpinner size={32} className=\"text-primary mx-auto mb-field\" aria-hidden=\"true\" />\n </div>\n </div>\n </Surface>\n );\n}\n\nexport interface AppShellProvidersProps {\n /** The result of `useAppShellLayout()`, computed once by the layout and shared with every outlet. */\n layout: AppShellLayoutInfo;\n children: React.ReactNode;\n}\n\n/**\n * The providers every shell region reads, and nothing else — they render no DOM of their own:\n *\n * - `PortalContainerContext`, holding the `<main>` element `AppShellContentOutlet` registers, so overlays opened\n * from any region portal into the content area — or, when the layout renders `AppShellOverlayPortalLayer`, that\n * layer instead;\n * - `HostedComponentInteractionsProvider`, the single owner of the open state and the open hotkey of the\n * interactive hosted components (command menu, notification center, quick switcher), which may be hosted in the\n * menubar and the sidebar at once.\n */\nexport function AppShellProviders({ layout, children }: AppShellProvidersProps): React.JSX.Element {\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const [overlayLayer, setOverlayLayer] = useState<HTMLElement | null>(null);\n const registerPortalTarget = useCallback((node: HTMLElement | null) => {\n setPortalContainer(node);\n }, []);\n const registerOverlayLayer = useCallback((node: HTMLElement | null) => {\n setOverlayLayer(node);\n }, []);\n return (\n <AppShellLayoutContext.Provider value={layout}>\n <AppShellPortalTargetContext.Provider value={registerPortalTarget}>\n <AppShellOverlayLayerTargetContext.Provider value={registerOverlayLayer}>\n {/* The dedicated overlay layer wins when a layout renders one; otherwise overlays stay in `<main>`. */}\n <PortalContainerContext.Provider value={overlayLayer ?? portalContainer}>\n <HostedComponentInteractionsProvider>{children}</HostedComponentInteractionsProvider>\n </PortalContainerContext.Provider>\n </AppShellOverlayLayerTargetContext.Provider>\n </AppShellPortalTargetContext.Provider>\n </AppShellLayoutContext.Provider>\n );\n}\n\n/**\n * A dedicated layer every overlay (dialog, sheet, menu, popover, tooltip) portals into, for a layout whose regions\n * are TRANSFORMED — a 3D placement. Render it once, inside the providers but OUTSIDE the transformed subtree; the\n * providers then prefer it to `<main>`. A layout that transforms nothing does not need it.\n *\n * It is a zero-size, untransformed, fixed box at the viewport's origin: an overlay positioned `fixed` resolves\n * against the viewport, one positioned `absolute` against the viewport's origin, so floating content lands where its\n * trigger is on screen. It carries the stacking tier overlays need above a layout's own layers.\n */\nexport function AppShellOverlayPortalLayer(): React.JSX.Element {\n const register = useContext(AppShellOverlayLayerTargetContext);\n if (!register) {\n throw new Error('AppShellOverlayPortalLayer must be rendered inside <AppShellProviders>, which exposes it as the portal container.');\n }\n return <div ref={register} data-shell-overlay-layer=\"\" className=\"fixed left-0 top-0 z-50 h-0 w-0\" />;\n}\n\n/**\n * Which region to render, and — for a region that sits at an edge — at which edge. The content area is not\n * among them: it has its own outlet, because it owns `<main>` and the page.\n *\n * `placement` renders the region only when the application configured THAT placement. A layout that places the\n * same region at two positions — as the default layout does for the sidebar's start and end edges — renders one\n * outlet per edge. Omitted, the region renders at whatever placement is configured. The type admits only the\n * placement axis the region has, so a sidebar cannot be asked for a vertical edge and render nothing.\n */\nexport type AppShellRegionOutletProps =\n | { region: ShellRegion.SIDEBAR | ShellRegion.UTILITY_PANEL; placement?: HorizontalPlacement.START | HorizontalPlacement.END }\n | { region: ShellRegion.STATUS_BAR; placement?: StatusBarPlacement }\n | { region: ShellRegion.ACTIVITY_BAR | ShellRegion.MENUBAR | ShellRegion.TOOLBAR; placement?: never };\n\n/**\n * Renders one shell region's component — the registry-resolved wrapper, with its placement prop — when the\n * application configures that region (and, if `placement` is given, at that placement). Renders nothing\n * otherwise, so placing an outlet for every region is always safe.\n */\nexport function AppShellRegionOutlet(props: AppShellRegionOutletProps): React.JSX.Element | null {\n const layout = useAppShellLayoutContext('AppShellRegionOutlet');\n const { region, placement } = props;\n const at = <T extends HorizontalPlacement | VerticalPlacement>(configured: T): T | null =>\n placement === undefined || placement === configured ? configured : null;\n\n switch (region) {\n case ShellRegion.ACTIVITY_BAR:\n return layout.hasActivityBar ? <ApplicationLevel_ActivityBar /> : null;\n case ShellRegion.MENUBAR:\n return layout.hasMenubar ? <ApplicationLevel_MenuBar /> : null;\n case ShellRegion.TOOLBAR:\n return layout.hasToolbar ? <ApplicationLevel_Toolbar /> : null;\n case ShellRegion.SIDEBAR: {\n const sidebarPlacement = at(layout.sidebarPlacement);\n return layout.hasSidebar && sidebarPlacement ? <ApplicationLevel_Sidebar placement={sidebarPlacement} /> : null;\n }\n case ShellRegion.UTILITY_PANEL: {\n const utilityPanelPlacement = at(layout.utilityPanelPlacement);\n return layout.hasUtilityPanel && utilityPanelPlacement ? <ApplicationLevel_UtilityPanel position={utilityPanelPlacement} /> : null;\n }\n case ShellRegion.STATUS_BAR: {\n const statusBarPlacement = at(layout.statusBarPlacement);\n return layout.hasStatusBar && statusBarPlacement ? <ApplicationLevel_StatusBar placement={statusBarPlacement} /> : null;\n }\n default: {\n const unhandled: never = region;\n throw new Error(`AppShellRegionOutlet has no rendering for region \"${String(unhandled)}\".`);\n }\n }\n}\n\nexport interface AppShellContentOutletProps {\n /** Classes for the `<main>` element — the layout decides how the content area sizes within its arrangement. */\n className?: string;\n /** The route outlet the layout container receives; rendered by the navigation zones while their stack is empty. */\n children?: React.ReactNode;\n}\n\n/**\n * The content area: the `<main>` landmark carrying `ShellRegion.CONTENT`, the navigation zones, and the floating\n * quick-action button when configured. Its element is registered with `AppShellProviders` as the portal\n * container, so it must be rendered exactly once, inside the providers.\n */\nexport function AppShellContentOutlet({ className, children }: AppShellContentOutletProps): React.JSX.Element {\n const layout = useAppShellLayoutContext('AppShellContentOutlet');\n const registerPortalTarget = useContext(AppShellPortalTargetContext);\n return (\n <main ref={registerPortalTarget ?? undefined} data-component-area={ShellRegion.CONTENT} className={className}>\n <NavigationContentAreas routerChildren={children} />\n\n {/* Floating Quick Action Button */}\n {layout.hasQuickActionButton && <ApplicationLevel_QuickActionButton placement=\"floating\" />}\n </main>\n );\n}\n\n/** The shell's overlay layer: navigation dialogs and sheets, then guidance (tours, tooltips, highlights). */\nexport function AppShellOverlaysOutlet(): React.JSX.Element {\n return (\n <>\n <NavigationOverlays />\n <GuidanceRenderer />\n </>\n );\n}\n/** @wildo_source:part:end saas.frontend.app-shell.building-blocks */\n"]}
|
|
1
|
+
{"version":3,"file":"AppShellBuildingBlocks.js","sourceRoot":"","sources":["../../../../../src/core/app-shell/AppShellBuildingBlocks.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';\n\nimport { HorizontalPlacement, ShellRegion, SurfaceVariant, VerticalPlacement } from '@wildo-ai/presets-components-models';\nimport { LoadingSpinner } from '~wildo-frontend-lib/components/feedback/loading-spinner';\nimport { Surface } from '~wildo-frontend-lib/components/sections/surface';\nimport { NON_CANONICAL_SHELL_SURFACE_POLICY_OVERRIDE } from '~wildo-frontend-lib/core/ui/surface-a11y.utils';\nimport { ApplicationLevel_ActivityBar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_ActivityBar';\nimport { ApplicationLevel_MenuBar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_MenuBar';\nimport { ApplicationLevel_QuickActionButton } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_QuickActionButton';\nimport { ApplicationLevel_Sidebar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_Sidebar';\nimport { ApplicationLevel_StatusBar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_StatusBar';\nimport { ApplicationLevel_Toolbar } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_Toolbar';\nimport { ApplicationLevel_UtilityPanel } from '~wildo-frontend-lib/components/navigation/app-level/ApplicationLevel_UtilityPanel';\nimport { HostedComponentInteractionsProvider } from '~wildo-frontend-lib/components/navigation/app-level/HostedComponentInteractionsProvider';\nimport { GuidanceRenderer } from '~wildo-frontend-lib/core/guidance/GuidanceRenderer';\nimport { NavigationContentAreas, NavigationOverlays } from '~wildo-frontend-lib/core/navigation/NavigationContentAreas';\n\nimport type { StatusBarPlacement } from '~wildo-frontend-lib/core/config/app-level-components.frontend.schemas';\n\nimport type { AppShellLayoutInfo } from './app-shell.schemas';\nimport { PortalContainerContext } from './PortalContainerContext';\n\n/** @wildo_source:part:start saas.frontend.app-shell.building-blocks facet:layer:frontend facet:family:app-shell facet:audience:app-developer */\n/**\n * # App shell building blocks\n *\n * The signed-in shell is a LAYOUT — where the regions sit — over parts that do not depend on the layout: the\n * region components themselves (each resolved from the component registry by its wrapper), the content area,\n * the overlays, and two providers every region reads. These building blocks are those parts, so a layout\n * preset only decides the ARRANGEMENT. `AppLayoutPreset_MainContainer_Default` is composed from them, and any\n * other layout container an application registers should be too — a different arrangement of the same regions,\n * or, later, an alternative rendering that draws decoration around them.\n *\n * A layout preset uses them like this:\n *\n * ```tsx\n * const layout = useAppShellLayout();\n * const hasBeenReady = useAppShellFirstReady(layout.isLayoutReady);\n * if (!layout.isLayoutReady && !hasBeenReady) return <AppShellLoadingState />;\n * return (\n * <AppShellProviders layout={layout}>\n * <div className=\"my-arrangement\">\n * <AppShellRegionOutlet region={ShellRegion.SIDEBAR} placement={HorizontalPlacement.START} />\n * <AppShellRegionOutlet region={ShellRegion.MENUBAR} />\n * <AppShellContentOutlet className=\"flex-1 relative min-w-0\">{children}</AppShellContentOutlet>\n * <AppShellOverlaysOutlet />\n * </div>\n * </AppShellProviders>\n * );\n * ```\n *\n * Four rules keep a custom layout correct:\n *\n * - **Render `AppShellProviders` exactly once, around the whole shell.** It owns the single open state and the\n * single hotkey registration of the command menu, notification center and quick switcher; two copies would\n * make one shortcut open two dialogs.\n * - **Place every region the application configures.** An outlet renders nothing when its region is not\n * configured, so placing an outlet is always safe; leaving one out silently drops a region.\n * - **Render `AppShellContentOutlet` exactly once.** It is the `<main>` landmark, and overlays portal into it —\n * unless the layout also renders `AppShellOverlayPortalLayer`, which then takes the overlays instead. A layout that\n * transforms its regions (a 3D placement) must render that layer OUTSIDE the transformed subtree: a transformed\n * ancestor is the containing block of every `position: fixed` descendant, so a dialog in `<main>` would be confined\n * to the pane and a menu would be placed in the wrong coordinates.\n * - **Give the root `position: relative`, not `isolation: isolate`,** when the theme may declare a background\n * layer. That layer is painted in its own stacking context above ordinary in-flow content, so shell text with\n * no positioned ancestor is painted UNDER it; positioning the root lifts the whole shell above it. `isolate`\n * would also lift it, but would make the shell one stacking context, so an overlay outside the shell with a\n * lower z-index (a consent prompt) would paint over the shell's own dialogs.\n */\n\n/** The layout decisions `useAppShellLayout()` computed, shared with every outlet below the providers. */\nconst AppShellLayoutContext = createContext<AppShellLayoutInfo | null>(null);\n\n/** Lets the content outlet hand its `<main>` element to the providers, which expose it as the portal container. */\nconst AppShellPortalTargetContext = createContext<((node: HTMLElement | null) => void) | null>(null);\n\n/** Lets `AppShellOverlayPortalLayer` hand its element to the providers, which then prefer it over `<main>`. */\nconst AppShellOverlayLayerTargetContext = createContext<((node: HTMLElement | null) => void) | null>(null);\n\nfunction useAppShellLayoutContext(consumer: string): AppShellLayoutInfo {\n const layout = useContext(AppShellLayoutContext);\n if (!layout) {\n throw new Error(`${consumer} must be rendered inside <AppShellProviders>, which supplies the layout it places regions from.`);\n }\n return layout;\n}\n\n/**\n * Latches the FIRST time the shell becomes ready.\n *\n * `isLayoutReady` derives from configuration presence and can drop transiently after bootstrap (an\n * organization switch reloading config, for example). Replacing the mounted shell with a loading state on such\n * a drop would unmount every provider and zone below it and destroy navigation state — the failure mode\n * `AppLoadingGate` documents. So a layout shows its loading state only while this returns `false`.\n */\nexport function useAppShellFirstReady(isLayoutReady: boolean): boolean {\n const [hasLayoutBeenReady, setHasLayoutBeenReady] = useState(false);\n useEffect(() => {\n if (isLayoutReady) setHasLayoutBeenReady(true);\n }, [isLayoutReady]);\n return hasLayoutBeenReady;\n}\n\n/**\n * The shell's loading state: a centred spinner on the page background, announced politely. What every layout\n * shows while `useAppShellFirstReady` says the shell has never been ready — one component rather than a copy per\n * layout, so the loading state is the same whatever the disposal.\n */\nexport function AppShellLoadingState(): React.JSX.Element {\n return (\n <Surface asChild emitPolicyVars={false} variant={SurfaceVariant.SHELL} policyOverride={NON_CANONICAL_SHELL_SURFACE_POLICY_OVERRIDE}>\n <div className=\"h-screen w-screen bg-background flex items-center justify-center\" role=\"status\" aria-live=\"polite\">\n <div className=\"text-center\">\n <LoadingSpinner size={32} className=\"text-primary mx-auto mb-field\" aria-hidden=\"true\" />\n </div>\n </div>\n </Surface>\n );\n}\n\nexport interface AppShellProvidersProps {\n /** The result of `useAppShellLayout()`, computed once by the layout and shared with every outlet. */\n layout: AppShellLayoutInfo;\n children: React.ReactNode;\n}\n\n/**\n * The providers every shell region reads, and nothing else — they render no DOM of their own:\n *\n * - `PortalContainerContext`, holding the `<main>` element `AppShellContentOutlet` registers, so overlays opened\n * from any region portal into the content area — or, when the layout renders `AppShellOverlayPortalLayer`, that\n * layer instead;\n * - `HostedComponentInteractionsProvider`, the single owner of the open state and the open hotkey of the\n * interactive hosted components (command menu, notification center, quick switcher), which may be hosted in the\n * menubar and the sidebar at once.\n */\nexport function AppShellProviders({ layout, children }: AppShellProvidersProps): React.JSX.Element {\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const [overlayLayer, setOverlayLayer] = useState<HTMLElement | null>(null);\n const registerPortalTarget = useCallback((node: HTMLElement | null) => {\n setPortalContainer(node);\n }, []);\n const registerOverlayLayer = useCallback((node: HTMLElement | null) => {\n setOverlayLayer(node);\n }, []);\n return (\n <AppShellLayoutContext.Provider value={layout}>\n <AppShellPortalTargetContext.Provider value={registerPortalTarget}>\n <AppShellOverlayLayerTargetContext.Provider value={registerOverlayLayer}>\n {/* The dedicated overlay layer wins when a layout renders one; otherwise overlays stay in `<main>`. */}\n <PortalContainerContext.Provider value={overlayLayer ?? portalContainer}>\n <HostedComponentInteractionsProvider>{children}</HostedComponentInteractionsProvider>\n </PortalContainerContext.Provider>\n </AppShellOverlayLayerTargetContext.Provider>\n </AppShellPortalTargetContext.Provider>\n </AppShellLayoutContext.Provider>\n );\n}\n\n/**\n * A dedicated layer every overlay (dialog, sheet, menu, popover, tooltip) portals into, for a layout whose regions\n * are TRANSFORMED — a 3D placement. Render it once, inside the providers but OUTSIDE the transformed subtree; the\n * providers then prefer it to `<main>`. A layout that transforms nothing does not need it.\n *\n * It is a zero-size, untransformed box at the shell root's origin (the root fills the viewport), with NO z-index and\n * NOT `position: fixed`: either would make it a stacking context and cap every overlay inside it below anything\n * positioned outside the shell — a consent prompt would paint over the shell's own dialogs (the reordering #1830\n * measured and avoided). So each overlay keeps its own global z-index. An overlay positioned `fixed` still resolves\n * against the viewport (nothing between it and the viewport is transformed), one positioned `absolute` against the\n * root's origin, so floating content lands where its trigger is on screen. The layout's root must be positioned.\n */\nexport function AppShellOverlayPortalLayer(): React.JSX.Element {\n const register = useContext(AppShellOverlayLayerTargetContext);\n if (!register) {\n throw new Error('AppShellOverlayPortalLayer must be rendered inside <AppShellProviders>, which exposes it as the portal container.');\n }\n return <div ref={register} data-shell-overlay-layer=\"\" className=\"absolute left-0 top-0 h-0 w-0\" />;\n}\n\n/**\n * Which region to render, and — for a region that sits at an edge — at which edge. The content area is not\n * among them: it has its own outlet, because it owns `<main>` and the page.\n *\n * `placement` renders the region only when the application configured THAT placement. A layout that places the\n * same region at two positions — as the default layout does for the sidebar's start and end edges — renders one\n * outlet per edge. Omitted, the region renders at whatever placement is configured. The type admits only the\n * placement axis the region has, so a sidebar cannot be asked for a vertical edge and render nothing.\n */\nexport type AppShellRegionOutletProps =\n | { region: ShellRegion.SIDEBAR | ShellRegion.UTILITY_PANEL; placement?: HorizontalPlacement.START | HorizontalPlacement.END }\n | { region: ShellRegion.STATUS_BAR; placement?: StatusBarPlacement }\n | { region: ShellRegion.ACTIVITY_BAR | ShellRegion.MENUBAR | ShellRegion.TOOLBAR; placement?: never };\n\n/**\n * Renders one shell region's component — the registry-resolved wrapper, with its placement prop — when the\n * application configures that region (and, if `placement` is given, at that placement). Renders nothing\n * otherwise, so placing an outlet for every region is always safe.\n */\nexport function AppShellRegionOutlet(props: AppShellRegionOutletProps): React.JSX.Element | null {\n const layout = useAppShellLayoutContext('AppShellRegionOutlet');\n const { region, placement } = props;\n const at = <T extends HorizontalPlacement | VerticalPlacement>(configured: T): T | null =>\n placement === undefined || placement === configured ? configured : null;\n\n switch (region) {\n case ShellRegion.ACTIVITY_BAR:\n return layout.hasActivityBar ? <ApplicationLevel_ActivityBar /> : null;\n case ShellRegion.MENUBAR:\n return layout.hasMenubar ? <ApplicationLevel_MenuBar /> : null;\n case ShellRegion.TOOLBAR:\n return layout.hasToolbar ? <ApplicationLevel_Toolbar /> : null;\n case ShellRegion.SIDEBAR: {\n const sidebarPlacement = at(layout.sidebarPlacement);\n return layout.hasSidebar && sidebarPlacement ? <ApplicationLevel_Sidebar placement={sidebarPlacement} /> : null;\n }\n case ShellRegion.UTILITY_PANEL: {\n const utilityPanelPlacement = at(layout.utilityPanelPlacement);\n return layout.hasUtilityPanel && utilityPanelPlacement ? <ApplicationLevel_UtilityPanel position={utilityPanelPlacement} /> : null;\n }\n case ShellRegion.STATUS_BAR: {\n const statusBarPlacement = at(layout.statusBarPlacement);\n return layout.hasStatusBar && statusBarPlacement ? <ApplicationLevel_StatusBar placement={statusBarPlacement} /> : null;\n }\n default: {\n const unhandled: never = region;\n throw new Error(`AppShellRegionOutlet has no rendering for region \"${String(unhandled)}\".`);\n }\n }\n}\n\nexport interface AppShellContentOutletProps {\n /** Classes for the `<main>` element — the layout decides how the content area sizes within its arrangement. */\n className?: string;\n /** The route outlet the layout container receives; rendered by the navigation zones while their stack is empty. */\n children?: React.ReactNode;\n}\n\n/**\n * The content area: the `<main>` landmark carrying `ShellRegion.CONTENT`, the navigation zones, and the floating\n * quick-action button when configured. Its element is registered with `AppShellProviders` as the portal\n * container, so it must be rendered exactly once, inside the providers.\n */\nexport function AppShellContentOutlet({ className, children }: AppShellContentOutletProps): React.JSX.Element {\n const layout = useAppShellLayoutContext('AppShellContentOutlet');\n const registerPortalTarget = useContext(AppShellPortalTargetContext);\n return (\n <main ref={registerPortalTarget ?? undefined} data-component-area={ShellRegion.CONTENT} className={className}>\n <NavigationContentAreas routerChildren={children} />\n\n {/* Floating Quick Action Button */}\n {layout.hasQuickActionButton && <ApplicationLevel_QuickActionButton placement=\"floating\" />}\n </main>\n );\n}\n\n/** The shell's overlay layer: navigation dialogs and sheets, then guidance (tours, tooltips, highlights). */\nexport function AppShellOverlaysOutlet(): React.JSX.Element {\n return (\n <>\n <NavigationOverlays />\n <GuidanceRenderer />\n </>\n );\n}\n/** @wildo_source:part:end saas.frontend.app-shell.building-blocks */\n"]}
|
|
@@ -163,9 +163,9 @@ export declare const InsertedChartDeclarationSchema: z.ZodObject<{
|
|
|
163
163
|
labelPosition: z.ZodOptional<z.ZodEnum<{
|
|
164
164
|
left: "left";
|
|
165
165
|
right: "right";
|
|
166
|
-
center: "center";
|
|
167
166
|
top: "top";
|
|
168
167
|
bottom: "bottom";
|
|
168
|
+
center: "center";
|
|
169
169
|
inside: "inside";
|
|
170
170
|
outside: "outside";
|
|
171
171
|
}>>;
|
|
@@ -173,8 +173,8 @@ export declare const InsertedChartDeclarationSchema: z.ZodObject<{
|
|
|
173
173
|
emphasisScale: z.ZodOptional<z.ZodBoolean>;
|
|
174
174
|
markLines: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
175
175
|
type: z.ZodOptional<z.ZodEnum<{
|
|
176
|
-
min: "min";
|
|
177
176
|
max: "max";
|
|
177
|
+
min: "min";
|
|
178
178
|
average: "average";
|
|
179
179
|
}>>;
|
|
180
180
|
yValue: z.ZodOptional<z.ZodNumber>;
|
|
@@ -189,8 +189,8 @@ export declare const InsertedChartDeclarationSchema: z.ZodObject<{
|
|
|
189
189
|
}, z.core.$strip>>>;
|
|
190
190
|
markPoints: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
191
191
|
type: z.ZodOptional<z.ZodEnum<{
|
|
192
|
-
min: "min";
|
|
193
192
|
max: "max";
|
|
193
|
+
min: "min";
|
|
194
194
|
average: "average";
|
|
195
195
|
}>>;
|
|
196
196
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -270,8 +270,8 @@ export declare const InsertedChartDeclarationSchema: z.ZodObject<{
|
|
|
270
270
|
textAlign: z.ZodOptional<z.ZodEnum<{
|
|
271
271
|
left: "left";
|
|
272
272
|
right: "right";
|
|
273
|
-
auto: "auto";
|
|
274
273
|
center: "center";
|
|
274
|
+
auto: "auto";
|
|
275
275
|
}>>;
|
|
276
276
|
}, z.core.$strip>>;
|
|
277
277
|
animationDuration: z.ZodOptional<z.ZodNumber>;
|
|
@@ -304,8 +304,8 @@ export declare const InsertedChartDeclarationSchema: z.ZodObject<{
|
|
|
304
304
|
formatter: z.ZodOptional<z.ZodString>;
|
|
305
305
|
axisPointerType: z.ZodOptional<z.ZodEnum<{
|
|
306
306
|
none: "none";
|
|
307
|
-
line: "line";
|
|
308
307
|
shadow: "shadow";
|
|
308
|
+
line: "line";
|
|
309
309
|
cross: "cross";
|
|
310
310
|
}>>;
|
|
311
311
|
}, z.core.$strip>>;
|
|
@@ -329,8 +329,8 @@ export declare const InsertedChartDeclarationSchema: z.ZodObject<{
|
|
|
329
329
|
slider: "slider";
|
|
330
330
|
}>>>;
|
|
331
331
|
axis: z.ZodOptional<z.ZodEnum<{
|
|
332
|
-
both: "both";
|
|
333
332
|
y: "y";
|
|
333
|
+
both: "both";
|
|
334
334
|
x: "x";
|
|
335
335
|
}>>;
|
|
336
336
|
start: z.ZodOptional<z.ZodNumber>;
|
|
@@ -472,8 +472,8 @@ export declare const InsertedChartDeclarationSchema: z.ZodObject<{
|
|
|
472
472
|
}, z.core.$loose>, z.ZodObject<{
|
|
473
473
|
emphasisFocus: z.ZodOptional<z.ZodEnum<{
|
|
474
474
|
none: "none";
|
|
475
|
-
adjacency: "adjacency";
|
|
476
475
|
self: "self";
|
|
476
|
+
adjacency: "adjacency";
|
|
477
477
|
}>>;
|
|
478
478
|
nodeWidth: z.ZodOptional<z.ZodNumber>;
|
|
479
479
|
nodeGap: z.ZodOptional<z.ZodNumber>;
|
|
@@ -690,9 +690,9 @@ export declare const ResolvedInsertedChartDescriptorSchema: z.ZodObject<{
|
|
|
690
690
|
labelPosition: z.ZodOptional<z.ZodEnum<{
|
|
691
691
|
left: "left";
|
|
692
692
|
right: "right";
|
|
693
|
-
center: "center";
|
|
694
693
|
top: "top";
|
|
695
694
|
bottom: "bottom";
|
|
695
|
+
center: "center";
|
|
696
696
|
inside: "inside";
|
|
697
697
|
outside: "outside";
|
|
698
698
|
}>>;
|
|
@@ -700,8 +700,8 @@ export declare const ResolvedInsertedChartDescriptorSchema: z.ZodObject<{
|
|
|
700
700
|
emphasisScale: z.ZodOptional<z.ZodBoolean>;
|
|
701
701
|
markLines: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
702
702
|
type: z.ZodOptional<z.ZodEnum<{
|
|
703
|
-
min: "min";
|
|
704
703
|
max: "max";
|
|
704
|
+
min: "min";
|
|
705
705
|
average: "average";
|
|
706
706
|
}>>;
|
|
707
707
|
yValue: z.ZodOptional<z.ZodNumber>;
|
|
@@ -716,8 +716,8 @@ export declare const ResolvedInsertedChartDescriptorSchema: z.ZodObject<{
|
|
|
716
716
|
}, z.core.$strip>>>;
|
|
717
717
|
markPoints: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
718
718
|
type: z.ZodOptional<z.ZodEnum<{
|
|
719
|
-
min: "min";
|
|
720
719
|
max: "max";
|
|
720
|
+
min: "min";
|
|
721
721
|
average: "average";
|
|
722
722
|
}>>;
|
|
723
723
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -797,8 +797,8 @@ export declare const ResolvedInsertedChartDescriptorSchema: z.ZodObject<{
|
|
|
797
797
|
textAlign: z.ZodOptional<z.ZodEnum<{
|
|
798
798
|
left: "left";
|
|
799
799
|
right: "right";
|
|
800
|
-
auto: "auto";
|
|
801
800
|
center: "center";
|
|
801
|
+
auto: "auto";
|
|
802
802
|
}>>;
|
|
803
803
|
}, z.core.$strip>>;
|
|
804
804
|
animationDuration: z.ZodOptional<z.ZodNumber>;
|
|
@@ -831,8 +831,8 @@ export declare const ResolvedInsertedChartDescriptorSchema: z.ZodObject<{
|
|
|
831
831
|
formatter: z.ZodOptional<z.ZodString>;
|
|
832
832
|
axisPointerType: z.ZodOptional<z.ZodEnum<{
|
|
833
833
|
none: "none";
|
|
834
|
-
line: "line";
|
|
835
834
|
shadow: "shadow";
|
|
835
|
+
line: "line";
|
|
836
836
|
cross: "cross";
|
|
837
837
|
}>>;
|
|
838
838
|
}, z.core.$strip>>;
|
|
@@ -856,8 +856,8 @@ export declare const ResolvedInsertedChartDescriptorSchema: z.ZodObject<{
|
|
|
856
856
|
slider: "slider";
|
|
857
857
|
}>>>;
|
|
858
858
|
axis: z.ZodOptional<z.ZodEnum<{
|
|
859
|
-
both: "both";
|
|
860
859
|
y: "y";
|
|
860
|
+
both: "both";
|
|
861
861
|
x: "x";
|
|
862
862
|
}>>;
|
|
863
863
|
start: z.ZodOptional<z.ZodNumber>;
|
|
@@ -999,8 +999,8 @@ export declare const ResolvedInsertedChartDescriptorSchema: z.ZodObject<{
|
|
|
999
999
|
}, z.core.$loose>, z.ZodObject<{
|
|
1000
1000
|
emphasisFocus: z.ZodOptional<z.ZodEnum<{
|
|
1001
1001
|
none: "none";
|
|
1002
|
-
adjacency: "adjacency";
|
|
1003
1002
|
self: "self";
|
|
1003
|
+
adjacency: "adjacency";
|
|
1004
1004
|
}>>;
|
|
1005
1005
|
nodeWidth: z.ZodOptional<z.ZodNumber>;
|
|
1006
1006
|
nodeGap: z.ZodOptional<z.ZodNumber>;
|