react-panel-layout 0.4.2 → 0.5.1

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.
Files changed (76) hide show
  1. package/dist/FloatingPanelFrame-6W5OexYe.js +98 -0
  2. package/dist/FloatingPanelFrame-6W5OexYe.js.map +1 -0
  3. package/dist/FloatingPanelFrame-D9Cp2al1.cjs +2 -0
  4. package/dist/FloatingPanelFrame-D9Cp2al1.cjs.map +1 -0
  5. package/dist/GridLayout-BzrIDrC9.js +1465 -0
  6. package/dist/GridLayout-BzrIDrC9.js.map +1 -0
  7. package/dist/GridLayout-ZrOhoLLB.cjs +2 -0
  8. package/dist/GridLayout-ZrOhoLLB.cjs.map +1 -0
  9. package/dist/PanelSystemContext.d.ts +9 -0
  10. package/dist/components/grid/GridLayerList.d.ts +3 -0
  11. package/dist/components/grid/GridLayout.d.ts +5 -0
  12. package/dist/components/paneling/FloatingPanelFrame.d.ts +4 -0
  13. package/dist/components/window/FloatingWindow.d.ts +15 -0
  14. package/dist/config/panelRouter.d.ts +2 -2
  15. package/dist/config.cjs +1 -1
  16. package/dist/config.cjs.map +1 -1
  17. package/dist/config.js +1 -1
  18. package/dist/config.js.map +1 -1
  19. package/dist/constants/styles.d.ts +3 -1
  20. package/dist/floating.cjs +1 -1
  21. package/dist/floating.js +1 -1
  22. package/dist/hooks/ContentCacheContext.d.ts +59 -0
  23. package/dist/hooks/useContainerScroll.d.ts +23 -0
  24. package/dist/hooks/useContentCache.d.ts +67 -0
  25. package/dist/hooks/useDocumentScroll.d.ts +13 -0
  26. package/dist/hooks/useScrollContainer.d.ts +21 -0
  27. package/dist/index.cjs +2 -2
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.ts +4 -1
  30. package/dist/index.js +950 -878
  31. package/dist/index.js.map +1 -1
  32. package/dist/modules/grid/GridLayoutContext.d.ts +5 -0
  33. package/dist/modules/grid/resizeHandles.d.ts +14 -0
  34. package/dist/modules/grid/trackUtils.d.ts +29 -0
  35. package/dist/modules/grid/useGridTracks.d.ts +6 -15
  36. package/dist/modules/grid/useLayerInteractions.d.ts +2 -1
  37. package/dist/modules/window/useFloatingState.d.ts +9 -0
  38. package/dist/pivot.cjs +1 -1
  39. package/dist/pivot.js +1 -1
  40. package/dist/sticky-header/StickyHeader.d.ts +53 -0
  41. package/dist/sticky-header/index.d.ts +7 -0
  42. package/dist/sticky-header/types.d.ts +50 -0
  43. package/dist/sticky-header.cjs +2 -0
  44. package/dist/sticky-header.cjs.map +1 -0
  45. package/dist/sticky-header.js +198 -0
  46. package/dist/sticky-header.js.map +1 -0
  47. package/dist/styles-CA2_zLZt.js +52 -0
  48. package/dist/{styles-DcG3aIFx.cjs.map → styles-CA2_zLZt.js.map} +1 -1
  49. package/dist/styles-PsqGOEJP.cjs +2 -0
  50. package/dist/styles-PsqGOEJP.cjs.map +1 -0
  51. package/dist/types.d.ts +79 -4
  52. package/dist/useIsomorphicLayoutEffect-DGRNF4Lf.cjs +2 -0
  53. package/dist/useIsomorphicLayoutEffect-DGRNF4Lf.cjs.map +1 -0
  54. package/dist/useIsomorphicLayoutEffect-DhmEnmZ_.js +6 -0
  55. package/dist/useIsomorphicLayoutEffect-DhmEnmZ_.js.map +1 -0
  56. package/dist/usePivot-BS-DGfwd.cjs +2 -0
  57. package/dist/usePivot-BS-DGfwd.cjs.map +1 -0
  58. package/dist/usePivot-BvOGxLQQ.js +124 -0
  59. package/dist/usePivot-BvOGxLQQ.js.map +1 -0
  60. package/dist/utils/css.d.ts +19 -0
  61. package/package.json +6 -1
  62. package/dist/FloatingPanelFrame-SOrLGjZd.js +0 -67
  63. package/dist/FloatingPanelFrame-SOrLGjZd.js.map +0 -1
  64. package/dist/FloatingPanelFrame-XtBcHANI.cjs +0 -2
  65. package/dist/FloatingPanelFrame-XtBcHANI.cjs.map +0 -1
  66. package/dist/GridLayout-CLvW8jID.js +0 -1352
  67. package/dist/GridLayout-CLvW8jID.js.map +0 -1
  68. package/dist/GridLayout-qufTyOQM.cjs +0 -2
  69. package/dist/GridLayout-qufTyOQM.cjs.map +0 -1
  70. package/dist/styles-DcG3aIFx.cjs +0 -2
  71. package/dist/styles-w0ZixggV.js +0 -51
  72. package/dist/styles-w0ZixggV.js.map +0 -1
  73. package/dist/usePivot-C8q0pMgW.cjs +0 -2
  74. package/dist/usePivot-C8q0pMgW.cjs.map +0 -1
  75. package/dist/usePivot-z9gumDf-.js +0 -97
  76. package/dist/usePivot-z9gumDf-.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"config.cjs","sources":["../src/config/panelRouter.tsx","../src/config/PanelContentDeclaration.tsx"],"sourcesContent":["/**\n * @file Router-like builder for GridLayout\n *\n * Provides a React Router–style configuration API to declare panel layers.\n * Converts route objects to the existing GridLayout props without magic.\n */\nimport * as React from \"react\";\nimport type {\n DrawerBehavior,\n FloatingWindowConfig,\n LayerDefinition,\n LayerPositionMode,\n PanelLayoutConfig,\n PanelLayoutProps,\n PivotBehavior,\n WindowPosition,\n} from \"../types\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\n\nexport type PanelRoute = {\n /** Unique id for the layer. Required. */\n id: string;\n /** React node to render for this layer. Required. */\n element: React.ReactNode;\n /** Visibility flag. Defaults to visible. */\n visible?: boolean;\n\n /**\n * Grid placement key. When using `positionMode: 'grid'` (default), this must be provided.\n * Using `area` mirrors React Router's route path intent but for grid cells.\n */\n area?: string;\n\n /** Explicit positioning mode; defaults to 'grid' unless floating/drawer implies otherwise. */\n positionMode?: LayerPositionMode;\n /** Offsets when using non-grid modes. */\n position?: WindowPosition;\n /** Optional stacking order. */\n zIndex?: number;\n /** Optional dimensions; required for resizable/draggable floating layers. */\n width?: number | string;\n height?: number | string;\n /** Pointer events control. */\n pointerEvents?: boolean | \"auto\" | \"none\";\n /** Optional style overrides. */\n style?: React.CSSProperties;\n /** Optional backdrop style (drawer). */\n backdropStyle?: React.CSSProperties;\n\n /** Drawer behavior for mobile-friendly panels. */\n drawer?: DrawerBehavior;\n /** Floating window configuration. */\n floating?: FloatingWindowConfig;\n /** Pivot behavior for content switching. */\n pivot?: PivotBehavior;\n\n /**\n * Optional child declarations; purely a grouping convenience.\n * Children are flattened; no implicit inheritance.\n */\n children?: PanelRoute[];\n};\n\nconst toLayer = (route: PanelRoute): LayerDefinition => {\n const inferredMode: LayerPositionMode = resolveRoutePositionMode(route);\n\n if (inferredMode === \"grid\") {\n if (!route.area) {\n throw new Error(`PanelRoute ${route.id} must specify 'area' for grid placement.`);\n }\n }\n\n return {\n id: route.id,\n component: route.element,\n visible: route.visible,\n gridArea: route.area,\n positionMode: inferredMode,\n position: route.position,\n zIndex: route.zIndex,\n width: route.width,\n height: route.height,\n pointerEvents: route.pointerEvents,\n style: route.style,\n drawer: route.drawer,\n floating: route.floating,\n pivot: route.pivot,\n backdropStyle: route.backdropStyle,\n } satisfies LayerDefinition;\n};\n\nconst resolveRoutePositionMode = (route: PanelRoute): LayerPositionMode => {\n if (route.positionMode) {\n return route.positionMode;\n }\n if (route.floating) {\n // Embedded => absolute, Popup => relative (handled by renderer); keep explicitness here.\n return \"absolute\";\n }\n if (route.drawer) {\n return \"grid\";\n }\n return \"grid\";\n};\n\nconst flattenRoutes = (routes: PanelRoute[]): PanelRoute[] => {\n const result: PanelRoute[] = [];\n const walk = (node: PanelRoute): void => {\n result.push(node);\n if (node.children) {\n node.children.forEach((child) => walk(child));\n }\n };\n routes.forEach((r) => walk(r));\n return result;\n};\n\nconst validateUniqueIds = (routes: PanelRoute[]): void => {\n const seen = new Set<string>();\n routes.forEach((r) => {\n if (seen.has(r.id)) {\n throw new Error(`Duplicate PanelRoute id detected: ${r.id}`);\n }\n seen.add(r.id);\n });\n};\n\nexport const buildLayersFromRoutes = (routes: PanelRoute[]): LayerDefinition[] => {\n const flat = flattenRoutes(routes);\n validateUniqueIds(flat);\n return flat.map((r) => toLayer(r));\n};\n\nexport const createPanelLayoutFromRoutes = (input: {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n}): PanelLayoutProps => {\n const layers = buildLayersFromRoutes(input.routes);\n return {\n config: input.config,\n layers,\n };\n};\n\nexport type PanelLayoutRouterProps = {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n};\n\nexport const PanelLayoutRouter: React.FC<PanelLayoutRouterProps> = ({ config, routes, style }) => {\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n return <GridLayout config={config} layers={layers} style={style} />;\n};\n","/**\n * @file PanelContentDeclaration (JSX DSL for content configuration ONLY)\n *\n * IMPORTANT: This file declares a JSX DSL to configure panel \"content\" and layout\n * tracks. It does NOT implement grid rendering, resizing, dragging, or drawers.\n * Those behaviors live in the existing layout/rendering modules. Keep this file\n * limited to declaration and conversion into GridLayout props.\n *\n * Usage (content declaration):\n * <PanelLayout>\n * <Config>\n * <Rows>...</Rows>\n * <Columns>...</Columns>\n * <Areas matrix={...}/>\n * </Config>\n * <Panel type=\"grid\" id=\"main\" area=\"main\">...</Panel>\n * <Panel type=\"floating\" id=\"preview\" position={{ left: 0, top: 0 }} width={300} height={200} />\n * <Panel type=\"drawer\" id=\"nav\" drawer={{ defaultOpen: true }} position={{ left: 0 }} />\n * </PanelLayout>\n */\nimport * as React from \"react\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\nimport type { DrawerBehavior, GridTrack, PanelLayoutConfig, WindowPosition } from \"../types\";\nimport type { PanelRoute } from \"./panelRouter\";\nimport { buildLayersFromRoutes } from \"./panelRouter\";\n\nexport type PanelRootProps = {\n config?: PanelLayoutConfig;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\n// Unified child declaration: <Panel type=\"grid\" .../> or <Panel type=\"floating\" .../>...\ntype PanelCommonProps = {\n id: string;\n visible?: boolean;\n zIndex?: number;\n width?: number | string;\n height?: number | string;\n pointerEvents?: boolean | \"auto\" | \"none\";\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport type PanelProps =\n | (PanelCommonProps & { type: \"grid\"; area: string })\n | (PanelCommonProps & {\n type: \"floating\";\n position: WindowPosition;\n width: number | string;\n height: number | string;\n draggable?: boolean;\n resizable?: boolean;\n })\n | (PanelCommonProps & {\n type: \"drawer\";\n drawer: DrawerBehavior;\n position?: WindowPosition;\n backdropStyle?: React.CSSProperties;\n })\n | (Omit<PanelCommonProps, \"children\"> & {\n type: \"pivot\";\n area: string;\n /** Currently active item ID (controlled mode) */\n activeId?: string;\n /** Default active item ID (uncontrolled mode) */\n defaultActiveId?: string;\n /** Callback when active item changes */\n onActiveChange?: (id: string) => void;\n children?: React.ReactNode;\n });\n\nexport const Panel: React.FC<PanelProps> = () => null;\n\n/**\n * PivotItem declaration for use inside <Panel type=\"pivot\">\n */\nexport type PivotItemDeclProps = {\n id: string;\n label?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n};\n\nexport const PivotItem: React.FC<PivotItemDeclProps> = () => null;\n\nconst isElementOf = <P,>(element: unknown, component: React.FC<P>): element is React.ReactElement<P> => {\n if (!React.isValidElement<P>(element)) {\n return false;\n }\n return element.type === component;\n};\n\nexport const buildRoutesFromChildren = (children: React.ReactNode): PanelRoute[] => {\n const routes: PanelRoute[] = [];\n\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n // Unified <Panel type=\"...\" />\n if (isElementOf(node, Panel)) {\n const props = node.props as PanelProps;\n if (!props.id) {\n throw new Error(\"<Panel> requires an 'id' prop.\");\n }\n if (props.type === \"grid\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"grid\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: props.children ?? null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n });\n return;\n }\n if (props.type === \"floating\") {\n if (!props.position) {\n throw new Error(`<Panel id=\"${props.id}\"> requires a 'position' prop when type=\"floating\".`);\n }\n if (props.width === undefined || props.height === undefined) {\n throw new Error(`<Panel id=\"${props.id}\"> requires 'width' and 'height' when type=\"floating\".`);\n }\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"absolute\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n floating: { mode: \"embedded\", draggable: props.draggable, resizable: props.resizable },\n });\n return;\n }\n if (props.type === \"drawer\") {\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"relative\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n drawer: props.drawer,\n backdropStyle: props.backdropStyle,\n });\n return;\n }\n if (props.type === \"pivot\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"pivot\".`);\n }\n const pivotItems = collectPivotItems(props.children);\n if (pivotItems.length === 0) {\n throw new Error(`<Panel id=\"${props.id}\"> requires at least one <PivotItem> child when type=\"pivot\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n pivot: {\n items: pivotItems,\n activeId: props.activeId,\n defaultActiveId: props.defaultActiveId,\n onActiveChange: props.onActiveChange,\n },\n });\n return;\n }\n // unknown type -> error for explicitness\n throw new Error(\"<Panel> has unsupported type.\");\n }\n\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n return;\n }\n // Unknown element: ignore quietly to allow comments/wrappers.\n return;\n }\n // Primitive nodes (string/number) are ignored.\n };\n\n visit(children);\n return routes;\n};\n\n// Root container renamed to PanelLayout to avoid name collision with child <Panel/>\nexport const PanelLayout: React.FC<PanelRootProps> = ({ config, style, children }) => {\n const routes = React.useMemo(() => buildRoutesFromChildren(children), [children]);\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n const derivedConfig = React.useMemo(() => {\n if (config) {\n return config;\n }\n const built = buildConfigFromChildren(children);\n if (!built) {\n throw new Error(\"Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). \");\n }\n return built;\n }, [children, config]);\n return <GridLayout config={derivedConfig} layers={layers} style={style} />;\n};\n\n// =============================\n// JSX Config Declarations\n// =============================\n\nexport type ConfigProps = {\n gap?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport const Config: React.FC<ConfigProps> = () => {\n return null;\n};\n\nexport const Rows: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport const Columns: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport type RowProps = GridTrack;\nexport const Row: React.FC<RowProps> = () => {\n return null;\n};\n\nexport type ColumnProps = GridTrack;\nexport const Col: React.FC<ColumnProps> = () => {\n return null;\n};\n\nexport type AreasProps = {\n matrix: string[][];\n};\nexport const Areas: React.FC<AreasProps> = () => {\n return null;\n};\n\ntype CollectedConfig = {\n gap?: string;\n style?: React.CSSProperties;\n rows?: GridTrack[];\n columns?: GridTrack[];\n areas?: string[][];\n};\n\nconst collectTracks = <P extends GridTrack>(children: React.ReactNode, marker: React.FC<P>): GridTrack[] => {\n const result: GridTrack[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, marker)) {\n const props = node.props as P;\n if (!props.size) {\n throw new Error(\"Row/Col requires 'size' property.\");\n }\n result.push({\n size: props.size,\n resizable: props.resizable,\n minSize: props.minSize,\n maxSize: props.maxSize,\n });\n return;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n };\n visit(children);\n return result;\n};\n\nconst collectConfigBlock = (children: React.ReactNode): CollectedConfig | null => {\n const node = findFirst(children, Config);\n if (!node) {\n return null;\n }\n const props = node.props as ConfigProps;\n const rows = collectTracks(node.props.children, Row);\n const columns = collectTracks(node.props.children, Col);\n const areasNode = findFirst(node.props.children, Areas);\n const areas = areasNode ? (areasNode.props as AreasProps).matrix : undefined;\n return {\n gap: props.gap,\n style: props.style,\n rows,\n columns,\n areas,\n };\n};\n\nconst findFirst = <P,>(children: React.ReactNode, marker: React.FC<P>): React.ReactElement<P> | null => {\n const visit = (node: React.ReactNode): React.ReactElement<P> | null => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return null;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n const found = visit(item);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (isElementOf(node, marker)) {\n return node as React.ReactElement<P>;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n return visit(el.props.children);\n }\n return null;\n };\n return visit(children);\n};\n\ntype CollectedPivotItem = {\n id: string;\n label?: string;\n content: React.ReactNode;\n disabled?: boolean;\n};\n\nconst collectPivotItems = (children: React.ReactNode): CollectedPivotItem[] => {\n const items: CollectedPivotItem[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, PivotItem)) {\n const props = node.props as PivotItemDeclProps;\n if (!props.id) {\n throw new Error(\"<PivotItem> requires an 'id' prop.\");\n }\n items.push({\n id: props.id,\n label: props.label,\n content: props.children ?? null,\n disabled: props.disabled,\n });\n return;\n }\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n }\n };\n visit(children);\n return items;\n};\n\nexport const buildConfigFromChildren = (children: React.ReactNode): PanelLayoutConfig | null => {\n const collected = collectConfigBlock(children);\n if (!collected) {\n return null;\n }\n if (!collected.rows || collected.rows.length === 0) {\n throw new Error(\"Config must include at least one <Row size=...> inside <Config>.\");\n }\n if (!collected.columns || collected.columns.length === 0) {\n throw new Error(\"Config must include at least one <Col size=...> inside <Config>.\");\n }\n if (!collected.areas || collected.areas.length === 0) {\n throw new Error(\"Config must include <Areas matrix={...}> inside <Config>.\");\n }\n\n const rowCount = collected.areas.length;\n const colCount = collected.areas[0]?.length ?? 0;\n if (rowCount !== collected.rows.length) {\n throw new Error(`Areas row count (${rowCount}) must match Rows count (${collected.rows.length}).`);\n }\n if (colCount !== collected.columns.length) {\n throw new Error(`Areas column count (${colCount}) must match Columns count (${collected.columns.length}).`);\n }\n\n return {\n areas: collected.areas,\n rows: collected.rows,\n columns: collected.columns,\n gap: collected.gap,\n style: collected.style,\n } satisfies PanelLayoutConfig;\n};\n"],"names":["toLayer","route","inferredMode","resolveRoutePositionMode","flattenRoutes","routes","result","walk","node","child","r","validateUniqueIds","seen","buildLayersFromRoutes","flat","Panel","PivotItem","isElementOf","element","component","React","buildRoutesFromChildren","children","visit","props","pivotItems","collectPivotItems","PanelLayout","config","style","layers","derivedConfig","built","buildConfigFromChildren","jsx","GridLayout","Config","Rows","Columns","Row","Col","Areas","collectTracks","marker","collectConfigBlock","findFirst","rows","columns","areasNode","areas","item","found","items","collected","rowCount","colCount"],"mappings":"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"}
1
+ {"version":3,"file":"config.cjs","sources":["../src/config/panelRouter.tsx","../src/config/PanelContentDeclaration.tsx"],"sourcesContent":["/**\n * @file Router-like builder for GridLayout\n *\n * Provides a React Router–style configuration API to declare panel layers.\n * Converts route objects to the existing GridLayout props without magic.\n */\nimport * as React from \"react\";\nimport type {\n DrawerBehavior,\n FloatingBehavior,\n LayerDefinition,\n LayerPositionMode,\n PanelLayoutConfig,\n PanelLayoutProps,\n PivotBehavior,\n WindowPosition,\n} from \"../types\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\n\nexport type PanelRoute = {\n /** Unique id for the layer. Required. */\n id: string;\n /** React node to render for this layer. Required. */\n element: React.ReactNode;\n /** Visibility flag. Defaults to visible. */\n visible?: boolean;\n\n /**\n * Grid placement key. When using `positionMode: 'grid'` (default), this must be provided.\n * Using `area` mirrors React Router's route path intent but for grid cells.\n */\n area?: string;\n\n /** Explicit positioning mode; defaults to 'grid' unless floating/drawer implies otherwise. */\n positionMode?: LayerPositionMode;\n /** Offsets when using non-grid modes. */\n position?: WindowPosition;\n /** Optional stacking order. */\n zIndex?: number;\n /** Optional dimensions; required for resizable/draggable floating layers. */\n width?: number | string;\n height?: number | string;\n /** Pointer events control. */\n pointerEvents?: boolean | \"auto\" | \"none\";\n /** Optional style overrides. */\n style?: React.CSSProperties;\n /** Optional backdrop style (drawer). */\n backdropStyle?: React.CSSProperties;\n\n /** Drawer behavior for mobile-friendly panels. */\n drawer?: DrawerBehavior;\n /** Floating window configuration. */\n floating?: FloatingBehavior;\n /** Pivot behavior for content switching. */\n pivot?: PivotBehavior;\n\n /**\n * Optional child declarations; purely a grouping convenience.\n * Children are flattened; no implicit inheritance.\n */\n children?: PanelRoute[];\n};\n\nconst toLayer = (route: PanelRoute): LayerDefinition => {\n const inferredMode: LayerPositionMode = resolveRoutePositionMode(route);\n\n if (inferredMode === \"grid\") {\n if (!route.area) {\n throw new Error(`PanelRoute ${route.id} must specify 'area' for grid placement.`);\n }\n }\n\n return {\n id: route.id,\n component: route.element,\n visible: route.visible,\n gridArea: route.area,\n positionMode: inferredMode,\n position: route.position,\n zIndex: route.zIndex,\n width: route.width,\n height: route.height,\n pointerEvents: route.pointerEvents,\n style: route.style,\n drawer: route.drawer,\n floating: route.floating,\n pivot: route.pivot,\n backdropStyle: route.backdropStyle,\n } satisfies LayerDefinition;\n};\n\nconst resolveRoutePositionMode = (route: PanelRoute): LayerPositionMode => {\n if (route.positionMode) {\n return route.positionMode;\n }\n if (route.floating) {\n // Embedded => absolute, Popup => relative (handled by renderer); keep explicitness here.\n return \"absolute\";\n }\n if (route.drawer) {\n return \"grid\";\n }\n return \"grid\";\n};\n\nconst flattenRoutes = (routes: PanelRoute[]): PanelRoute[] => {\n const result: PanelRoute[] = [];\n const walk = (node: PanelRoute): void => {\n result.push(node);\n if (node.children) {\n node.children.forEach((child) => walk(child));\n }\n };\n routes.forEach((r) => walk(r));\n return result;\n};\n\nconst validateUniqueIds = (routes: PanelRoute[]): void => {\n const seen = new Set<string>();\n routes.forEach((r) => {\n if (seen.has(r.id)) {\n throw new Error(`Duplicate PanelRoute id detected: ${r.id}`);\n }\n seen.add(r.id);\n });\n};\n\nexport const buildLayersFromRoutes = (routes: PanelRoute[]): LayerDefinition[] => {\n const flat = flattenRoutes(routes);\n validateUniqueIds(flat);\n return flat.map((r) => toLayer(r));\n};\n\nexport const createPanelLayoutFromRoutes = (input: {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n}): PanelLayoutProps => {\n const layers = buildLayersFromRoutes(input.routes);\n return {\n config: input.config,\n layers,\n };\n};\n\nexport type PanelLayoutRouterProps = {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n};\n\nexport const PanelLayoutRouter: React.FC<PanelLayoutRouterProps> = ({ config, routes, style }) => {\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n return <GridLayout config={config} layers={layers} style={style} />;\n};\n","/**\n * @file PanelContentDeclaration (JSX DSL for content configuration ONLY)\n *\n * IMPORTANT: This file declares a JSX DSL to configure panel \"content\" and layout\n * tracks. It does NOT implement grid rendering, resizing, dragging, or drawers.\n * Those behaviors live in the existing layout/rendering modules. Keep this file\n * limited to declaration and conversion into GridLayout props.\n *\n * Usage (content declaration):\n * <PanelLayout>\n * <Config>\n * <Rows>...</Rows>\n * <Columns>...</Columns>\n * <Areas matrix={...}/>\n * </Config>\n * <Panel type=\"grid\" id=\"main\" area=\"main\">...</Panel>\n * <Panel type=\"floating\" id=\"preview\" position={{ left: 0, top: 0 }} width={300} height={200} />\n * <Panel type=\"drawer\" id=\"nav\" drawer={{ defaultOpen: true }} position={{ left: 0 }} />\n * </PanelLayout>\n */\nimport * as React from \"react\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\nimport type { DrawerBehavior, GridTrack, PanelLayoutConfig, WindowPosition } from \"../types\";\nimport type { PanelRoute } from \"./panelRouter\";\nimport { buildLayersFromRoutes } from \"./panelRouter\";\n\nexport type PanelRootProps = {\n config?: PanelLayoutConfig;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\n// Unified child declaration: <Panel type=\"grid\" .../> or <Panel type=\"floating\" .../>...\ntype PanelCommonProps = {\n id: string;\n visible?: boolean;\n zIndex?: number;\n width?: number | string;\n height?: number | string;\n pointerEvents?: boolean | \"auto\" | \"none\";\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport type PanelProps =\n | (PanelCommonProps & { type: \"grid\"; area: string })\n | (PanelCommonProps & {\n type: \"floating\";\n position: WindowPosition;\n width: number | string;\n height: number | string;\n draggable?: boolean;\n resizable?: boolean;\n })\n | (PanelCommonProps & {\n type: \"drawer\";\n drawer: DrawerBehavior;\n position?: WindowPosition;\n backdropStyle?: React.CSSProperties;\n })\n | (Omit<PanelCommonProps, \"children\"> & {\n type: \"pivot\";\n area: string;\n /** Currently active item ID (controlled mode) */\n activeId?: string;\n /** Default active item ID (uncontrolled mode) */\n defaultActiveId?: string;\n /** Callback when active item changes */\n onActiveChange?: (id: string) => void;\n children?: React.ReactNode;\n });\n\nexport const Panel: React.FC<PanelProps> = () => null;\n\n/**\n * PivotItem declaration for use inside <Panel type=\"pivot\">\n */\nexport type PivotItemDeclProps = {\n id: string;\n label?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n};\n\nexport const PivotItem: React.FC<PivotItemDeclProps> = () => null;\n\nconst isElementOf = <P,>(element: unknown, component: React.FC<P>): element is React.ReactElement<P> => {\n if (!React.isValidElement<P>(element)) {\n return false;\n }\n return element.type === component;\n};\n\nexport const buildRoutesFromChildren = (children: React.ReactNode): PanelRoute[] => {\n const routes: PanelRoute[] = [];\n\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n // Unified <Panel type=\"...\" />\n if (isElementOf(node, Panel)) {\n const props = node.props as PanelProps;\n if (!props.id) {\n throw new Error(\"<Panel> requires an 'id' prop.\");\n }\n if (props.type === \"grid\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"grid\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: props.children ?? null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n });\n return;\n }\n if (props.type === \"floating\") {\n if (!props.position) {\n throw new Error(`<Panel id=\"${props.id}\"> requires a 'position' prop when type=\"floating\".`);\n }\n if (props.width === undefined || props.height === undefined) {\n throw new Error(`<Panel id=\"${props.id}\"> requires 'width' and 'height' when type=\"floating\".`);\n }\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"absolute\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n floating: { mode: \"embedded\", draggable: props.draggable, resizable: props.resizable },\n });\n return;\n }\n if (props.type === \"drawer\") {\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"relative\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n drawer: props.drawer,\n backdropStyle: props.backdropStyle,\n });\n return;\n }\n if (props.type === \"pivot\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"pivot\".`);\n }\n const pivotItems = collectPivotItems(props.children);\n if (pivotItems.length === 0) {\n throw new Error(`<Panel id=\"${props.id}\"> requires at least one <PivotItem> child when type=\"pivot\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n pivot: {\n items: pivotItems,\n activeId: props.activeId,\n defaultActiveId: props.defaultActiveId,\n onActiveChange: props.onActiveChange,\n },\n });\n return;\n }\n // unknown type -> error for explicitness\n throw new Error(\"<Panel> has unsupported type.\");\n }\n\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n return;\n }\n // Unknown element: ignore quietly to allow comments/wrappers.\n return;\n }\n // Primitive nodes (string/number) are ignored.\n };\n\n visit(children);\n return routes;\n};\n\n// Root container renamed to PanelLayout to avoid name collision with child <Panel/>\nexport const PanelLayout: React.FC<PanelRootProps> = ({ config, style, children }) => {\n const routes = React.useMemo(() => buildRoutesFromChildren(children), [children]);\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n const derivedConfig = React.useMemo(() => {\n if (config) {\n return config;\n }\n const built = buildConfigFromChildren(children);\n if (!built) {\n throw new Error(\"Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). \");\n }\n return built;\n }, [children, config]);\n return <GridLayout config={derivedConfig} layers={layers} style={style} />;\n};\n\n// =============================\n// JSX Config Declarations\n// =============================\n\nexport type ConfigProps = {\n gap?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport const Config: React.FC<ConfigProps> = () => {\n return null;\n};\n\nexport const Rows: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport const Columns: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport type RowProps = GridTrack;\nexport const Row: React.FC<RowProps> = () => {\n return null;\n};\n\nexport type ColumnProps = GridTrack;\nexport const Col: React.FC<ColumnProps> = () => {\n return null;\n};\n\nexport type AreasProps = {\n matrix: string[][];\n};\nexport const Areas: React.FC<AreasProps> = () => {\n return null;\n};\n\ntype CollectedConfig = {\n gap?: string;\n style?: React.CSSProperties;\n rows?: GridTrack[];\n columns?: GridTrack[];\n areas?: string[][];\n};\n\nconst collectTracks = <P extends GridTrack>(children: React.ReactNode, marker: React.FC<P>): GridTrack[] => {\n const result: GridTrack[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, marker)) {\n const props = node.props as P;\n if (!props.size) {\n throw new Error(\"Row/Col requires 'size' property.\");\n }\n result.push({\n size: props.size,\n resizable: props.resizable,\n minSize: props.minSize,\n maxSize: props.maxSize,\n });\n return;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n };\n visit(children);\n return result;\n};\n\nconst collectConfigBlock = (children: React.ReactNode): CollectedConfig | null => {\n const node = findFirst(children, Config);\n if (!node) {\n return null;\n }\n const props = node.props as ConfigProps;\n const rows = collectTracks(node.props.children, Row);\n const columns = collectTracks(node.props.children, Col);\n const areasNode = findFirst(node.props.children, Areas);\n const areas = areasNode ? (areasNode.props as AreasProps).matrix : undefined;\n return {\n gap: props.gap,\n style: props.style,\n rows,\n columns,\n areas,\n };\n};\n\nconst findFirst = <P,>(children: React.ReactNode, marker: React.FC<P>): React.ReactElement<P> | null => {\n const visit = (node: React.ReactNode): React.ReactElement<P> | null => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return null;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n const found = visit(item);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (isElementOf(node, marker)) {\n return node as React.ReactElement<P>;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n return visit(el.props.children);\n }\n return null;\n };\n return visit(children);\n};\n\ntype CollectedPivotItem = {\n id: string;\n label?: string;\n content: React.ReactNode;\n disabled?: boolean;\n};\n\nconst collectPivotItems = (children: React.ReactNode): CollectedPivotItem[] => {\n const items: CollectedPivotItem[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, PivotItem)) {\n const props = node.props as PivotItemDeclProps;\n if (!props.id) {\n throw new Error(\"<PivotItem> requires an 'id' prop.\");\n }\n items.push({\n id: props.id,\n label: props.label,\n content: props.children ?? null,\n disabled: props.disabled,\n });\n return;\n }\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n }\n };\n visit(children);\n return items;\n};\n\nexport const buildConfigFromChildren = (children: React.ReactNode): PanelLayoutConfig | null => {\n const collected = collectConfigBlock(children);\n if (!collected) {\n return null;\n }\n if (!collected.rows || collected.rows.length === 0) {\n throw new Error(\"Config must include at least one <Row size=...> inside <Config>.\");\n }\n if (!collected.columns || collected.columns.length === 0) {\n throw new Error(\"Config must include at least one <Col size=...> inside <Config>.\");\n }\n if (!collected.areas || collected.areas.length === 0) {\n throw new Error(\"Config must include <Areas matrix={...}> inside <Config>.\");\n }\n\n const rowCount = collected.areas.length;\n const colCount = collected.areas[0]?.length ?? 0;\n if (rowCount !== collected.rows.length) {\n throw new Error(`Areas row count (${rowCount}) must match Rows count (${collected.rows.length}).`);\n }\n if (colCount !== collected.columns.length) {\n throw new Error(`Areas column count (${colCount}) must match Columns count (${collected.columns.length}).`);\n }\n\n return {\n areas: collected.areas,\n rows: collected.rows,\n columns: collected.columns,\n gap: collected.gap,\n style: collected.style,\n } satisfies PanelLayoutConfig;\n};\n"],"names":["toLayer","route","inferredMode","resolveRoutePositionMode","flattenRoutes","routes","result","walk","node","child","r","validateUniqueIds","seen","buildLayersFromRoutes","flat","Panel","PivotItem","isElementOf","element","component","React","buildRoutesFromChildren","children","visit","props","pivotItems","collectPivotItems","PanelLayout","config","style","layers","derivedConfig","built","buildConfigFromChildren","jsx","GridLayout","Config","Rows","Columns","Row","Col","Areas","collectTracks","marker","collectConfigBlock","findFirst","rows","columns","areasNode","areas","item","found","items","collected","rowCount","colCount"],"mappings":"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"}
package/dist/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx as u } from "react/jsx-runtime";
2
2
  import * as s from "react";
3
- import { G as d } from "./GridLayout-CLvW8jID.js";
3
+ import { G as d } from "./GridLayout-BzrIDrC9.js";
4
4
  const h = (i) => {
5
5
  const r = f(i);
6
6
  if (r === "grid" && !i.area)
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../src/config/panelRouter.tsx","../src/config/PanelContentDeclaration.tsx"],"sourcesContent":["/**\n * @file Router-like builder for GridLayout\n *\n * Provides a React Router–style configuration API to declare panel layers.\n * Converts route objects to the existing GridLayout props without magic.\n */\nimport * as React from \"react\";\nimport type {\n DrawerBehavior,\n FloatingWindowConfig,\n LayerDefinition,\n LayerPositionMode,\n PanelLayoutConfig,\n PanelLayoutProps,\n PivotBehavior,\n WindowPosition,\n} from \"../types\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\n\nexport type PanelRoute = {\n /** Unique id for the layer. Required. */\n id: string;\n /** React node to render for this layer. Required. */\n element: React.ReactNode;\n /** Visibility flag. Defaults to visible. */\n visible?: boolean;\n\n /**\n * Grid placement key. When using `positionMode: 'grid'` (default), this must be provided.\n * Using `area` mirrors React Router's route path intent but for grid cells.\n */\n area?: string;\n\n /** Explicit positioning mode; defaults to 'grid' unless floating/drawer implies otherwise. */\n positionMode?: LayerPositionMode;\n /** Offsets when using non-grid modes. */\n position?: WindowPosition;\n /** Optional stacking order. */\n zIndex?: number;\n /** Optional dimensions; required for resizable/draggable floating layers. */\n width?: number | string;\n height?: number | string;\n /** Pointer events control. */\n pointerEvents?: boolean | \"auto\" | \"none\";\n /** Optional style overrides. */\n style?: React.CSSProperties;\n /** Optional backdrop style (drawer). */\n backdropStyle?: React.CSSProperties;\n\n /** Drawer behavior for mobile-friendly panels. */\n drawer?: DrawerBehavior;\n /** Floating window configuration. */\n floating?: FloatingWindowConfig;\n /** Pivot behavior for content switching. */\n pivot?: PivotBehavior;\n\n /**\n * Optional child declarations; purely a grouping convenience.\n * Children are flattened; no implicit inheritance.\n */\n children?: PanelRoute[];\n};\n\nconst toLayer = (route: PanelRoute): LayerDefinition => {\n const inferredMode: LayerPositionMode = resolveRoutePositionMode(route);\n\n if (inferredMode === \"grid\") {\n if (!route.area) {\n throw new Error(`PanelRoute ${route.id} must specify 'area' for grid placement.`);\n }\n }\n\n return {\n id: route.id,\n component: route.element,\n visible: route.visible,\n gridArea: route.area,\n positionMode: inferredMode,\n position: route.position,\n zIndex: route.zIndex,\n width: route.width,\n height: route.height,\n pointerEvents: route.pointerEvents,\n style: route.style,\n drawer: route.drawer,\n floating: route.floating,\n pivot: route.pivot,\n backdropStyle: route.backdropStyle,\n } satisfies LayerDefinition;\n};\n\nconst resolveRoutePositionMode = (route: PanelRoute): LayerPositionMode => {\n if (route.positionMode) {\n return route.positionMode;\n }\n if (route.floating) {\n // Embedded => absolute, Popup => relative (handled by renderer); keep explicitness here.\n return \"absolute\";\n }\n if (route.drawer) {\n return \"grid\";\n }\n return \"grid\";\n};\n\nconst flattenRoutes = (routes: PanelRoute[]): PanelRoute[] => {\n const result: PanelRoute[] = [];\n const walk = (node: PanelRoute): void => {\n result.push(node);\n if (node.children) {\n node.children.forEach((child) => walk(child));\n }\n };\n routes.forEach((r) => walk(r));\n return result;\n};\n\nconst validateUniqueIds = (routes: PanelRoute[]): void => {\n const seen = new Set<string>();\n routes.forEach((r) => {\n if (seen.has(r.id)) {\n throw new Error(`Duplicate PanelRoute id detected: ${r.id}`);\n }\n seen.add(r.id);\n });\n};\n\nexport const buildLayersFromRoutes = (routes: PanelRoute[]): LayerDefinition[] => {\n const flat = flattenRoutes(routes);\n validateUniqueIds(flat);\n return flat.map((r) => toLayer(r));\n};\n\nexport const createPanelLayoutFromRoutes = (input: {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n}): PanelLayoutProps => {\n const layers = buildLayersFromRoutes(input.routes);\n return {\n config: input.config,\n layers,\n };\n};\n\nexport type PanelLayoutRouterProps = {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n};\n\nexport const PanelLayoutRouter: React.FC<PanelLayoutRouterProps> = ({ config, routes, style }) => {\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n return <GridLayout config={config} layers={layers} style={style} />;\n};\n","/**\n * @file PanelContentDeclaration (JSX DSL for content configuration ONLY)\n *\n * IMPORTANT: This file declares a JSX DSL to configure panel \"content\" and layout\n * tracks. It does NOT implement grid rendering, resizing, dragging, or drawers.\n * Those behaviors live in the existing layout/rendering modules. Keep this file\n * limited to declaration and conversion into GridLayout props.\n *\n * Usage (content declaration):\n * <PanelLayout>\n * <Config>\n * <Rows>...</Rows>\n * <Columns>...</Columns>\n * <Areas matrix={...}/>\n * </Config>\n * <Panel type=\"grid\" id=\"main\" area=\"main\">...</Panel>\n * <Panel type=\"floating\" id=\"preview\" position={{ left: 0, top: 0 }} width={300} height={200} />\n * <Panel type=\"drawer\" id=\"nav\" drawer={{ defaultOpen: true }} position={{ left: 0 }} />\n * </PanelLayout>\n */\nimport * as React from \"react\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\nimport type { DrawerBehavior, GridTrack, PanelLayoutConfig, WindowPosition } from \"../types\";\nimport type { PanelRoute } from \"./panelRouter\";\nimport { buildLayersFromRoutes } from \"./panelRouter\";\n\nexport type PanelRootProps = {\n config?: PanelLayoutConfig;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\n// Unified child declaration: <Panel type=\"grid\" .../> or <Panel type=\"floating\" .../>...\ntype PanelCommonProps = {\n id: string;\n visible?: boolean;\n zIndex?: number;\n width?: number | string;\n height?: number | string;\n pointerEvents?: boolean | \"auto\" | \"none\";\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport type PanelProps =\n | (PanelCommonProps & { type: \"grid\"; area: string })\n | (PanelCommonProps & {\n type: \"floating\";\n position: WindowPosition;\n width: number | string;\n height: number | string;\n draggable?: boolean;\n resizable?: boolean;\n })\n | (PanelCommonProps & {\n type: \"drawer\";\n drawer: DrawerBehavior;\n position?: WindowPosition;\n backdropStyle?: React.CSSProperties;\n })\n | (Omit<PanelCommonProps, \"children\"> & {\n type: \"pivot\";\n area: string;\n /** Currently active item ID (controlled mode) */\n activeId?: string;\n /** Default active item ID (uncontrolled mode) */\n defaultActiveId?: string;\n /** Callback when active item changes */\n onActiveChange?: (id: string) => void;\n children?: React.ReactNode;\n });\n\nexport const Panel: React.FC<PanelProps> = () => null;\n\n/**\n * PivotItem declaration for use inside <Panel type=\"pivot\">\n */\nexport type PivotItemDeclProps = {\n id: string;\n label?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n};\n\nexport const PivotItem: React.FC<PivotItemDeclProps> = () => null;\n\nconst isElementOf = <P,>(element: unknown, component: React.FC<P>): element is React.ReactElement<P> => {\n if (!React.isValidElement<P>(element)) {\n return false;\n }\n return element.type === component;\n};\n\nexport const buildRoutesFromChildren = (children: React.ReactNode): PanelRoute[] => {\n const routes: PanelRoute[] = [];\n\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n // Unified <Panel type=\"...\" />\n if (isElementOf(node, Panel)) {\n const props = node.props as PanelProps;\n if (!props.id) {\n throw new Error(\"<Panel> requires an 'id' prop.\");\n }\n if (props.type === \"grid\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"grid\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: props.children ?? null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n });\n return;\n }\n if (props.type === \"floating\") {\n if (!props.position) {\n throw new Error(`<Panel id=\"${props.id}\"> requires a 'position' prop when type=\"floating\".`);\n }\n if (props.width === undefined || props.height === undefined) {\n throw new Error(`<Panel id=\"${props.id}\"> requires 'width' and 'height' when type=\"floating\".`);\n }\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"absolute\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n floating: { mode: \"embedded\", draggable: props.draggable, resizable: props.resizable },\n });\n return;\n }\n if (props.type === \"drawer\") {\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"relative\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n drawer: props.drawer,\n backdropStyle: props.backdropStyle,\n });\n return;\n }\n if (props.type === \"pivot\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"pivot\".`);\n }\n const pivotItems = collectPivotItems(props.children);\n if (pivotItems.length === 0) {\n throw new Error(`<Panel id=\"${props.id}\"> requires at least one <PivotItem> child when type=\"pivot\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n pivot: {\n items: pivotItems,\n activeId: props.activeId,\n defaultActiveId: props.defaultActiveId,\n onActiveChange: props.onActiveChange,\n },\n });\n return;\n }\n // unknown type -> error for explicitness\n throw new Error(\"<Panel> has unsupported type.\");\n }\n\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n return;\n }\n // Unknown element: ignore quietly to allow comments/wrappers.\n return;\n }\n // Primitive nodes (string/number) are ignored.\n };\n\n visit(children);\n return routes;\n};\n\n// Root container renamed to PanelLayout to avoid name collision with child <Panel/>\nexport const PanelLayout: React.FC<PanelRootProps> = ({ config, style, children }) => {\n const routes = React.useMemo(() => buildRoutesFromChildren(children), [children]);\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n const derivedConfig = React.useMemo(() => {\n if (config) {\n return config;\n }\n const built = buildConfigFromChildren(children);\n if (!built) {\n throw new Error(\"Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). \");\n }\n return built;\n }, [children, config]);\n return <GridLayout config={derivedConfig} layers={layers} style={style} />;\n};\n\n// =============================\n// JSX Config Declarations\n// =============================\n\nexport type ConfigProps = {\n gap?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport const Config: React.FC<ConfigProps> = () => {\n return null;\n};\n\nexport const Rows: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport const Columns: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport type RowProps = GridTrack;\nexport const Row: React.FC<RowProps> = () => {\n return null;\n};\n\nexport type ColumnProps = GridTrack;\nexport const Col: React.FC<ColumnProps> = () => {\n return null;\n};\n\nexport type AreasProps = {\n matrix: string[][];\n};\nexport const Areas: React.FC<AreasProps> = () => {\n return null;\n};\n\ntype CollectedConfig = {\n gap?: string;\n style?: React.CSSProperties;\n rows?: GridTrack[];\n columns?: GridTrack[];\n areas?: string[][];\n};\n\nconst collectTracks = <P extends GridTrack>(children: React.ReactNode, marker: React.FC<P>): GridTrack[] => {\n const result: GridTrack[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, marker)) {\n const props = node.props as P;\n if (!props.size) {\n throw new Error(\"Row/Col requires 'size' property.\");\n }\n result.push({\n size: props.size,\n resizable: props.resizable,\n minSize: props.minSize,\n maxSize: props.maxSize,\n });\n return;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n };\n visit(children);\n return result;\n};\n\nconst collectConfigBlock = (children: React.ReactNode): CollectedConfig | null => {\n const node = findFirst(children, Config);\n if (!node) {\n return null;\n }\n const props = node.props as ConfigProps;\n const rows = collectTracks(node.props.children, Row);\n const columns = collectTracks(node.props.children, Col);\n const areasNode = findFirst(node.props.children, Areas);\n const areas = areasNode ? (areasNode.props as AreasProps).matrix : undefined;\n return {\n gap: props.gap,\n style: props.style,\n rows,\n columns,\n areas,\n };\n};\n\nconst findFirst = <P,>(children: React.ReactNode, marker: React.FC<P>): React.ReactElement<P> | null => {\n const visit = (node: React.ReactNode): React.ReactElement<P> | null => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return null;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n const found = visit(item);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (isElementOf(node, marker)) {\n return node as React.ReactElement<P>;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n return visit(el.props.children);\n }\n return null;\n };\n return visit(children);\n};\n\ntype CollectedPivotItem = {\n id: string;\n label?: string;\n content: React.ReactNode;\n disabled?: boolean;\n};\n\nconst collectPivotItems = (children: React.ReactNode): CollectedPivotItem[] => {\n const items: CollectedPivotItem[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, PivotItem)) {\n const props = node.props as PivotItemDeclProps;\n if (!props.id) {\n throw new Error(\"<PivotItem> requires an 'id' prop.\");\n }\n items.push({\n id: props.id,\n label: props.label,\n content: props.children ?? null,\n disabled: props.disabled,\n });\n return;\n }\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n }\n };\n visit(children);\n return items;\n};\n\nexport const buildConfigFromChildren = (children: React.ReactNode): PanelLayoutConfig | null => {\n const collected = collectConfigBlock(children);\n if (!collected) {\n return null;\n }\n if (!collected.rows || collected.rows.length === 0) {\n throw new Error(\"Config must include at least one <Row size=...> inside <Config>.\");\n }\n if (!collected.columns || collected.columns.length === 0) {\n throw new Error(\"Config must include at least one <Col size=...> inside <Config>.\");\n }\n if (!collected.areas || collected.areas.length === 0) {\n throw new Error(\"Config must include <Areas matrix={...}> inside <Config>.\");\n }\n\n const rowCount = collected.areas.length;\n const colCount = collected.areas[0]?.length ?? 0;\n if (rowCount !== collected.rows.length) {\n throw new Error(`Areas row count (${rowCount}) must match Rows count (${collected.rows.length}).`);\n }\n if (colCount !== collected.columns.length) {\n throw new Error(`Areas column count (${colCount}) must match Columns count (${collected.columns.length}).`);\n }\n\n return {\n areas: collected.areas,\n rows: collected.rows,\n columns: collected.columns,\n gap: collected.gap,\n style: collected.style,\n } satisfies PanelLayoutConfig;\n};\n"],"names":["toLayer","route","inferredMode","resolveRoutePositionMode","flattenRoutes","routes","result","walk","node","child","r","validateUniqueIds","seen","buildLayersFromRoutes","flat","Panel","PivotItem","isElementOf","element","component","React","buildRoutesFromChildren","children","visit","props","pivotItems","collectPivotItems","PanelLayout","config","style","layers","derivedConfig","built","buildConfigFromChildren","jsx","GridLayout","Config","Rows","Columns","Row","Col","Areas","collectTracks","marker","collectConfigBlock","findFirst","rows","columns","areasNode","areas","item","found","items","collected","rowCount","colCount"],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sources":["../src/config/panelRouter.tsx","../src/config/PanelContentDeclaration.tsx"],"sourcesContent":["/**\n * @file Router-like builder for GridLayout\n *\n * Provides a React Router–style configuration API to declare panel layers.\n * Converts route objects to the existing GridLayout props without magic.\n */\nimport * as React from \"react\";\nimport type {\n DrawerBehavior,\n FloatingBehavior,\n LayerDefinition,\n LayerPositionMode,\n PanelLayoutConfig,\n PanelLayoutProps,\n PivotBehavior,\n WindowPosition,\n} from \"../types\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\n\nexport type PanelRoute = {\n /** Unique id for the layer. Required. */\n id: string;\n /** React node to render for this layer. Required. */\n element: React.ReactNode;\n /** Visibility flag. Defaults to visible. */\n visible?: boolean;\n\n /**\n * Grid placement key. When using `positionMode: 'grid'` (default), this must be provided.\n * Using `area` mirrors React Router's route path intent but for grid cells.\n */\n area?: string;\n\n /** Explicit positioning mode; defaults to 'grid' unless floating/drawer implies otherwise. */\n positionMode?: LayerPositionMode;\n /** Offsets when using non-grid modes. */\n position?: WindowPosition;\n /** Optional stacking order. */\n zIndex?: number;\n /** Optional dimensions; required for resizable/draggable floating layers. */\n width?: number | string;\n height?: number | string;\n /** Pointer events control. */\n pointerEvents?: boolean | \"auto\" | \"none\";\n /** Optional style overrides. */\n style?: React.CSSProperties;\n /** Optional backdrop style (drawer). */\n backdropStyle?: React.CSSProperties;\n\n /** Drawer behavior for mobile-friendly panels. */\n drawer?: DrawerBehavior;\n /** Floating window configuration. */\n floating?: FloatingBehavior;\n /** Pivot behavior for content switching. */\n pivot?: PivotBehavior;\n\n /**\n * Optional child declarations; purely a grouping convenience.\n * Children are flattened; no implicit inheritance.\n */\n children?: PanelRoute[];\n};\n\nconst toLayer = (route: PanelRoute): LayerDefinition => {\n const inferredMode: LayerPositionMode = resolveRoutePositionMode(route);\n\n if (inferredMode === \"grid\") {\n if (!route.area) {\n throw new Error(`PanelRoute ${route.id} must specify 'area' for grid placement.`);\n }\n }\n\n return {\n id: route.id,\n component: route.element,\n visible: route.visible,\n gridArea: route.area,\n positionMode: inferredMode,\n position: route.position,\n zIndex: route.zIndex,\n width: route.width,\n height: route.height,\n pointerEvents: route.pointerEvents,\n style: route.style,\n drawer: route.drawer,\n floating: route.floating,\n pivot: route.pivot,\n backdropStyle: route.backdropStyle,\n } satisfies LayerDefinition;\n};\n\nconst resolveRoutePositionMode = (route: PanelRoute): LayerPositionMode => {\n if (route.positionMode) {\n return route.positionMode;\n }\n if (route.floating) {\n // Embedded => absolute, Popup => relative (handled by renderer); keep explicitness here.\n return \"absolute\";\n }\n if (route.drawer) {\n return \"grid\";\n }\n return \"grid\";\n};\n\nconst flattenRoutes = (routes: PanelRoute[]): PanelRoute[] => {\n const result: PanelRoute[] = [];\n const walk = (node: PanelRoute): void => {\n result.push(node);\n if (node.children) {\n node.children.forEach((child) => walk(child));\n }\n };\n routes.forEach((r) => walk(r));\n return result;\n};\n\nconst validateUniqueIds = (routes: PanelRoute[]): void => {\n const seen = new Set<string>();\n routes.forEach((r) => {\n if (seen.has(r.id)) {\n throw new Error(`Duplicate PanelRoute id detected: ${r.id}`);\n }\n seen.add(r.id);\n });\n};\n\nexport const buildLayersFromRoutes = (routes: PanelRoute[]): LayerDefinition[] => {\n const flat = flattenRoutes(routes);\n validateUniqueIds(flat);\n return flat.map((r) => toLayer(r));\n};\n\nexport const createPanelLayoutFromRoutes = (input: {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n}): PanelLayoutProps => {\n const layers = buildLayersFromRoutes(input.routes);\n return {\n config: input.config,\n layers,\n };\n};\n\nexport type PanelLayoutRouterProps = {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n};\n\nexport const PanelLayoutRouter: React.FC<PanelLayoutRouterProps> = ({ config, routes, style }) => {\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n return <GridLayout config={config} layers={layers} style={style} />;\n};\n","/**\n * @file PanelContentDeclaration (JSX DSL for content configuration ONLY)\n *\n * IMPORTANT: This file declares a JSX DSL to configure panel \"content\" and layout\n * tracks. It does NOT implement grid rendering, resizing, dragging, or drawers.\n * Those behaviors live in the existing layout/rendering modules. Keep this file\n * limited to declaration and conversion into GridLayout props.\n *\n * Usage (content declaration):\n * <PanelLayout>\n * <Config>\n * <Rows>...</Rows>\n * <Columns>...</Columns>\n * <Areas matrix={...}/>\n * </Config>\n * <Panel type=\"grid\" id=\"main\" area=\"main\">...</Panel>\n * <Panel type=\"floating\" id=\"preview\" position={{ left: 0, top: 0 }} width={300} height={200} />\n * <Panel type=\"drawer\" id=\"nav\" drawer={{ defaultOpen: true }} position={{ left: 0 }} />\n * </PanelLayout>\n */\nimport * as React from \"react\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\nimport type { DrawerBehavior, GridTrack, PanelLayoutConfig, WindowPosition } from \"../types\";\nimport type { PanelRoute } from \"./panelRouter\";\nimport { buildLayersFromRoutes } from \"./panelRouter\";\n\nexport type PanelRootProps = {\n config?: PanelLayoutConfig;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\n// Unified child declaration: <Panel type=\"grid\" .../> or <Panel type=\"floating\" .../>...\ntype PanelCommonProps = {\n id: string;\n visible?: boolean;\n zIndex?: number;\n width?: number | string;\n height?: number | string;\n pointerEvents?: boolean | \"auto\" | \"none\";\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport type PanelProps =\n | (PanelCommonProps & { type: \"grid\"; area: string })\n | (PanelCommonProps & {\n type: \"floating\";\n position: WindowPosition;\n width: number | string;\n height: number | string;\n draggable?: boolean;\n resizable?: boolean;\n })\n | (PanelCommonProps & {\n type: \"drawer\";\n drawer: DrawerBehavior;\n position?: WindowPosition;\n backdropStyle?: React.CSSProperties;\n })\n | (Omit<PanelCommonProps, \"children\"> & {\n type: \"pivot\";\n area: string;\n /** Currently active item ID (controlled mode) */\n activeId?: string;\n /** Default active item ID (uncontrolled mode) */\n defaultActiveId?: string;\n /** Callback when active item changes */\n onActiveChange?: (id: string) => void;\n children?: React.ReactNode;\n });\n\nexport const Panel: React.FC<PanelProps> = () => null;\n\n/**\n * PivotItem declaration for use inside <Panel type=\"pivot\">\n */\nexport type PivotItemDeclProps = {\n id: string;\n label?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n};\n\nexport const PivotItem: React.FC<PivotItemDeclProps> = () => null;\n\nconst isElementOf = <P,>(element: unknown, component: React.FC<P>): element is React.ReactElement<P> => {\n if (!React.isValidElement<P>(element)) {\n return false;\n }\n return element.type === component;\n};\n\nexport const buildRoutesFromChildren = (children: React.ReactNode): PanelRoute[] => {\n const routes: PanelRoute[] = [];\n\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n // Unified <Panel type=\"...\" />\n if (isElementOf(node, Panel)) {\n const props = node.props as PanelProps;\n if (!props.id) {\n throw new Error(\"<Panel> requires an 'id' prop.\");\n }\n if (props.type === \"grid\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"grid\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: props.children ?? null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n });\n return;\n }\n if (props.type === \"floating\") {\n if (!props.position) {\n throw new Error(`<Panel id=\"${props.id}\"> requires a 'position' prop when type=\"floating\".`);\n }\n if (props.width === undefined || props.height === undefined) {\n throw new Error(`<Panel id=\"${props.id}\"> requires 'width' and 'height' when type=\"floating\".`);\n }\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"absolute\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n floating: { mode: \"embedded\", draggable: props.draggable, resizable: props.resizable },\n });\n return;\n }\n if (props.type === \"drawer\") {\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"relative\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n drawer: props.drawer,\n backdropStyle: props.backdropStyle,\n });\n return;\n }\n if (props.type === \"pivot\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"pivot\".`);\n }\n const pivotItems = collectPivotItems(props.children);\n if (pivotItems.length === 0) {\n throw new Error(`<Panel id=\"${props.id}\"> requires at least one <PivotItem> child when type=\"pivot\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n pivot: {\n items: pivotItems,\n activeId: props.activeId,\n defaultActiveId: props.defaultActiveId,\n onActiveChange: props.onActiveChange,\n },\n });\n return;\n }\n // unknown type -> error for explicitness\n throw new Error(\"<Panel> has unsupported type.\");\n }\n\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n return;\n }\n // Unknown element: ignore quietly to allow comments/wrappers.\n return;\n }\n // Primitive nodes (string/number) are ignored.\n };\n\n visit(children);\n return routes;\n};\n\n// Root container renamed to PanelLayout to avoid name collision with child <Panel/>\nexport const PanelLayout: React.FC<PanelRootProps> = ({ config, style, children }) => {\n const routes = React.useMemo(() => buildRoutesFromChildren(children), [children]);\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n const derivedConfig = React.useMemo(() => {\n if (config) {\n return config;\n }\n const built = buildConfigFromChildren(children);\n if (!built) {\n throw new Error(\"Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). \");\n }\n return built;\n }, [children, config]);\n return <GridLayout config={derivedConfig} layers={layers} style={style} />;\n};\n\n// =============================\n// JSX Config Declarations\n// =============================\n\nexport type ConfigProps = {\n gap?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport const Config: React.FC<ConfigProps> = () => {\n return null;\n};\n\nexport const Rows: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport const Columns: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport type RowProps = GridTrack;\nexport const Row: React.FC<RowProps> = () => {\n return null;\n};\n\nexport type ColumnProps = GridTrack;\nexport const Col: React.FC<ColumnProps> = () => {\n return null;\n};\n\nexport type AreasProps = {\n matrix: string[][];\n};\nexport const Areas: React.FC<AreasProps> = () => {\n return null;\n};\n\ntype CollectedConfig = {\n gap?: string;\n style?: React.CSSProperties;\n rows?: GridTrack[];\n columns?: GridTrack[];\n areas?: string[][];\n};\n\nconst collectTracks = <P extends GridTrack>(children: React.ReactNode, marker: React.FC<P>): GridTrack[] => {\n const result: GridTrack[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, marker)) {\n const props = node.props as P;\n if (!props.size) {\n throw new Error(\"Row/Col requires 'size' property.\");\n }\n result.push({\n size: props.size,\n resizable: props.resizable,\n minSize: props.minSize,\n maxSize: props.maxSize,\n });\n return;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n };\n visit(children);\n return result;\n};\n\nconst collectConfigBlock = (children: React.ReactNode): CollectedConfig | null => {\n const node = findFirst(children, Config);\n if (!node) {\n return null;\n }\n const props = node.props as ConfigProps;\n const rows = collectTracks(node.props.children, Row);\n const columns = collectTracks(node.props.children, Col);\n const areasNode = findFirst(node.props.children, Areas);\n const areas = areasNode ? (areasNode.props as AreasProps).matrix : undefined;\n return {\n gap: props.gap,\n style: props.style,\n rows,\n columns,\n areas,\n };\n};\n\nconst findFirst = <P,>(children: React.ReactNode, marker: React.FC<P>): React.ReactElement<P> | null => {\n const visit = (node: React.ReactNode): React.ReactElement<P> | null => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return null;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n const found = visit(item);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (isElementOf(node, marker)) {\n return node as React.ReactElement<P>;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n return visit(el.props.children);\n }\n return null;\n };\n return visit(children);\n};\n\ntype CollectedPivotItem = {\n id: string;\n label?: string;\n content: React.ReactNode;\n disabled?: boolean;\n};\n\nconst collectPivotItems = (children: React.ReactNode): CollectedPivotItem[] => {\n const items: CollectedPivotItem[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, PivotItem)) {\n const props = node.props as PivotItemDeclProps;\n if (!props.id) {\n throw new Error(\"<PivotItem> requires an 'id' prop.\");\n }\n items.push({\n id: props.id,\n label: props.label,\n content: props.children ?? null,\n disabled: props.disabled,\n });\n return;\n }\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n }\n };\n visit(children);\n return items;\n};\n\nexport const buildConfigFromChildren = (children: React.ReactNode): PanelLayoutConfig | null => {\n const collected = collectConfigBlock(children);\n if (!collected) {\n return null;\n }\n if (!collected.rows || collected.rows.length === 0) {\n throw new Error(\"Config must include at least one <Row size=...> inside <Config>.\");\n }\n if (!collected.columns || collected.columns.length === 0) {\n throw new Error(\"Config must include at least one <Col size=...> inside <Config>.\");\n }\n if (!collected.areas || collected.areas.length === 0) {\n throw new Error(\"Config must include <Areas matrix={...}> inside <Config>.\");\n }\n\n const rowCount = collected.areas.length;\n const colCount = collected.areas[0]?.length ?? 0;\n if (rowCount !== collected.rows.length) {\n throw new Error(`Areas row count (${rowCount}) must match Rows count (${collected.rows.length}).`);\n }\n if (colCount !== collected.columns.length) {\n throw new Error(`Areas column count (${colCount}) must match Columns count (${collected.columns.length}).`);\n }\n\n return {\n areas: collected.areas,\n rows: collected.rows,\n columns: collected.columns,\n gap: collected.gap,\n style: collected.style,\n } satisfies PanelLayoutConfig;\n};\n"],"names":["toLayer","route","inferredMode","resolveRoutePositionMode","flattenRoutes","routes","result","walk","node","child","r","validateUniqueIds","seen","buildLayersFromRoutes","flat","Panel","PivotItem","isElementOf","element","component","React","buildRoutesFromChildren","children","visit","props","pivotItems","collectPivotItems","PanelLayout","config","style","layers","derivedConfig","built","buildConfigFromChildren","jsx","GridLayout","Config","Rows","Columns","Row","Col","Areas","collectTracks","marker","collectConfigBlock","findFirst","rows","columns","areasNode","areas","item","found","items","collected","rowCount","colCount"],"mappings":"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"}
@@ -34,7 +34,7 @@ export declare const COLOR_PANEL_BG = "var(--rpl-color-panel-bg, #0b0b0c)";
34
34
  * Primary color - used for resize handles, highlights
35
35
  */
36
36
  export declare const COLOR_PRIMARY = "var(--rpl-color-primary, #2196f3)";
37
- export declare const COLOR_RESIZE_HANDLE_IDLE = "var(--rpl-color-resize-handle-idle, rgba(255, 255, 255, 0.12))";
37
+ export declare const COLOR_RESIZE_HANDLE_IDLE = "var(--rpl-color-resize-handle-idle, rgba(255, 255, 255, 0.0))";
38
38
  export declare const COLOR_RESIZE_HANDLE_HOVER = "var(--rpl-color-resize-handle-hover, rgba(33, 150, 243, 0.35))";
39
39
  export declare const COLOR_RESIZE_HANDLE_ACTIVE = "var(--rpl-color-resize-handle-active, rgba(33, 150, 243, 0.55))";
40
40
  /**
@@ -168,6 +168,8 @@ export declare const FLOATING_PANEL_HEADER_PADDING_X = "var(--rpl-space-floating
168
168
  export declare const FLOATING_PANEL_CONTENT_PADDING = "var(--rpl-space-floating-panel-content-padding, 12px)";
169
169
  export declare const FLOATING_PANEL_META_FONT_SIZE = "var(--rpl-size-floating-panel-meta-font, 12px)";
170
170
  export declare const FLOATING_PANEL_CONTROLS_GAP = "var(--rpl-space-floating-panel-controls-gap, 6px)";
171
+ export declare const FLOATING_PANEL_CLOSE_BUTTON_FONT_SIZE = "var(--rpl-size-floating-panel-close-button-font, 1.25rem)";
172
+ export declare const FLOATING_PANEL_CLOSE_BUTTON_PADDING = "var(--rpl-space-floating-panel-close-button-padding, 0.25rem 0.5rem)";
171
173
  export declare const FLOATING_PANEL_SURFACE_COLOR = "var(--rpl-color-surface, #fff)";
172
174
  export declare const FLOATING_PANEL_SURFACE_2_COLOR = "var(--rpl-color-surface-2, #fafafa)";
173
175
  export declare const FLOATING_PANEL_BORDER_COLOR = "var(--rpl-color-border, #e5e7eb)";
package/dist/floating.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./FloatingPanelFrame-XtBcHANI.cjs");exports.FloatingPanelContent=a.FloatingPanelContent;exports.FloatingPanelControls=a.FloatingPanelControls;exports.FloatingPanelFrame=a.FloatingPanelFrame;exports.FloatingPanelHeader=a.FloatingPanelHeader;exports.FloatingPanelMeta=a.FloatingPanelMeta;exports.FloatingPanelTitle=a.FloatingPanelTitle;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./FloatingPanelFrame-D9Cp2al1.cjs");exports.FloatingPanelContent=a.FloatingPanelContent;exports.FloatingPanelControls=a.FloatingPanelControls;exports.FloatingPanelFrame=a.FloatingPanelFrame;exports.FloatingPanelHeader=a.FloatingPanelHeader;exports.FloatingPanelMeta=a.FloatingPanelMeta;exports.FloatingPanelTitle=a.FloatingPanelTitle;
2
2
  //# sourceMappingURL=floating.cjs.map
package/dist/floating.js CHANGED
@@ -1,4 +1,4 @@
1
- import { e, d as l, F as t, a as o, c as F, b as i } from "./FloatingPanelFrame-SOrLGjZd.js";
1
+ import { e, d as l, F as t, a as o, c as F, b as i } from "./FloatingPanelFrame-6W5OexYe.js";
2
2
  export {
3
3
  e as FloatingPanelContent,
4
4
  l as FloatingPanelControls,
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @file Context + Provider pattern for shared content caching.
3
+ *
4
+ * Use this when you need to share content caching across a component tree,
5
+ * such as when multiple child components need access to cached content.
6
+ *
7
+ * For local caching within a single component, use useContentCache directly.
8
+ */
9
+ import * as React from "react";
10
+ import { type ContentResolver, type UseContentCacheResult } from "./useContentCache";
11
+ /**
12
+ * Context value type for content cache.
13
+ */
14
+ export type ContentCacheContextValue<TId extends string = string> = UseContentCacheResult<TId>;
15
+ /**
16
+ * Creates a content cache context and associated hooks/providers.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * // Create context for a specific use case
21
+ * const { Provider, useCache } = createContentCacheContext<LayerId>('LayerContent');
22
+ *
23
+ * // In provider component
24
+ * <Provider resolveContent={getLayerContent} validIds={layerIds}>
25
+ * {children}
26
+ * </Provider>
27
+ *
28
+ * // In consumer component
29
+ * const { getCachedContent } = useCache();
30
+ * return <div>{getCachedContent(layerId)}</div>;
31
+ * ```
32
+ */
33
+ export declare function createContentCacheContext<TId extends string = string>(displayName: string): {
34
+ /**
35
+ * Provider component that manages content caching for its children.
36
+ */
37
+ Provider: React.FC<ContentCacheProviderProps<TId>>;
38
+ /**
39
+ * Hook to access the content cache from a child component.
40
+ */
41
+ useCache: () => ContentCacheContextValue<TId>;
42
+ /**
43
+ * The raw React context (for advanced use cases).
44
+ */
45
+ Context: React.Context<ContentCacheContextValue<TId> | null>;
46
+ };
47
+ /**
48
+ * Props for content cache provider components.
49
+ */
50
+ export type ContentCacheProviderProps<TId extends string = string> = React.PropsWithChildren<{
51
+ /**
52
+ * Function to resolve content by ID.
53
+ */
54
+ resolveContent: ContentResolver<TId>;
55
+ /**
56
+ * Current valid IDs for cache cleanup.
57
+ */
58
+ validIds: readonly TId[];
59
+ }>;
@@ -0,0 +1,23 @@
1
+ export type ScrollPosition = {
2
+ /** Vertical scroll position */
3
+ scrollTop: number;
4
+ /** Horizontal scroll position */
5
+ scrollLeft: number;
6
+ };
7
+ /**
8
+ * Track scroll position of a container element or the document.
9
+ *
10
+ * @param container - Scroll container element, or null for document scroll
11
+ * @returns Current scroll position
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * // For document scroll
16
+ * const scroll = useContainerScroll(null);
17
+ *
18
+ * // For container scroll
19
+ * const containerRef = useRef<HTMLDivElement>(null);
20
+ * const scroll = useContainerScroll(containerRef.current);
21
+ * ```
22
+ */
23
+ export declare function useContainerScroll(container: HTMLElement | null): ScrollPosition;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @file Shared content caching hook for preserving React component state.
3
+ *
4
+ * This hook provides a common pattern for caching ReactNode content by ID,
5
+ * ensuring the same reference is returned for the same ID across re-renders.
6
+ * This prevents component remounting when parent components re-create content arrays.
7
+ *
8
+ * Used by:
9
+ * - PanelSystemContext (GridLayout layer content)
10
+ * - usePivot (Pivot item content)
11
+ * - ContentRegistry (Panel content)
12
+ */
13
+ import * as React from "react";
14
+ /**
15
+ * Function type for resolving content by ID.
16
+ * Called only when content is not already cached.
17
+ */
18
+ export type ContentResolver<TId extends string = string> = (id: TId) => React.ReactNode | null;
19
+ /**
20
+ * Options for useContentCache hook.
21
+ */
22
+ export type UseContentCacheOptions<TId extends string = string> = {
23
+ /**
24
+ * Function to resolve content by ID.
25
+ * Called only when content is not already in cache.
26
+ */
27
+ resolveContent: ContentResolver<TId>;
28
+ /**
29
+ * Current valid IDs. Used to clean up stale cache entries.
30
+ * When an ID is removed from this array, its cached content is deleted.
31
+ */
32
+ validIds: readonly TId[];
33
+ };
34
+ /**
35
+ * Result from useContentCache hook.
36
+ */
37
+ export type UseContentCacheResult<TId extends string = string> = {
38
+ /**
39
+ * Get cached content for an ID.
40
+ * Returns the same ReactNode reference for the same ID.
41
+ */
42
+ getCachedContent: (id: TId) => React.ReactNode | null;
43
+ /**
44
+ * Clear all cached content.
45
+ * Use when you need to force re-creation of all content.
46
+ */
47
+ clearCache: () => void;
48
+ };
49
+ /**
50
+ * Hook for caching ReactNode content by ID.
51
+ *
52
+ * Ensures the same ReactNode reference is returned for the same ID,
53
+ * preventing unnecessary component remounting when parent re-renders.
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * const { getCachedContent } = useContentCache({
58
+ * resolveContent: (id) => items.find(i => i.id === id)?.content ?? null,
59
+ * validIds: items.map(i => i.id),
60
+ * });
61
+ *
62
+ * return items.map(item => (
63
+ * <div key={item.id}>{getCachedContent(item.id)}</div>
64
+ * ));
65
+ * ```
66
+ */
67
+ export declare function useContentCache<TId extends string = string>(options: UseContentCacheOptions<TId>): UseContentCacheResult<TId>;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Track document scroll position.
3
+ *
4
+ * @returns Current vertical scroll position (scrollY).
5
+ * Returns negative values during overscroll/bounce.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * const scrollY = useDocumentScroll();
10
+ * // scrollY < 0 during overscroll (pull-down bounce)
11
+ * ```
12
+ */
13
+ export declare function useDocumentScroll(): number;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @file useScrollContainer - Detect the nearest scrollable ancestor
3
+ *
4
+ * Traverses the DOM tree to find the nearest ancestor with overflow: scroll/auto.
5
+ * Returns null if the document is the scroll container.
6
+ */
7
+ import * as React from "react";
8
+ /**
9
+ * Hook to detect the nearest scrollable ancestor of a ref element.
10
+ *
11
+ * @param ref - Ref to the element to find scroll container for
12
+ * @returns The nearest scrollable ancestor element, or null if document is the container
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * const elementRef = useRef<HTMLDivElement>(null);
17
+ * const scrollContainer = useScrollContainer(elementRef);
18
+ * // scrollContainer is HTMLElement if in nested scroll, null if document scroll
19
+ * ```
20
+ */
21
+ export declare function useScrollContainer<T extends HTMLElement>(ref: React.RefObject<T | null>): HTMLElement | null;