@gridstorm/react 0.1.2 → 0.1.3
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/LICENSE.md +21 -0
- package/README.md +47 -47
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GridStorm Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
# @gridstorm/react
|
|
2
|
-
|
|
3
|
-
React 18+ adapter for GridStorm with hooks, error boundaries, and portal-based overlays.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @gridstorm/react @gridstorm/core @gridstorm/dom-renderer
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```tsx
|
|
14
|
-
import { GridStorm } from '@gridstorm/react';
|
|
15
|
-
import { SortingPlugin } from '@gridstorm/plugin-sorting';
|
|
16
|
-
|
|
17
|
-
const columns = [
|
|
18
|
-
{ field: 'name', headerName: 'Name' },
|
|
19
|
-
{ field: 'age', headerName: 'Age' },
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
export default function App() {
|
|
23
|
-
return (
|
|
24
|
-
<GridStorm
|
|
25
|
-
rowData={[{ id: 1, name: 'Alice', age: 32 }]}
|
|
26
|
-
columnDefs={columns}
|
|
27
|
-
plugins={[SortingPlugin()]}
|
|
28
|
-
height={400}
|
|
29
|
-
/>
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Features
|
|
35
|
-
|
|
36
|
-
- `<GridStorm>` component with declarative props
|
|
37
|
-
- React hooks for grid state access
|
|
38
|
-
- Error boundary for graceful error handling
|
|
39
|
-
- Portal-based overlays for editors and menus
|
|
40
|
-
|
|
41
|
-
## Documentation
|
|
42
|
-
|
|
43
|
-
[Full API Reference](https://grid-data-analytics-explorer.vercel.app//api/react) | [React Guide](https://grid-data-analytics-explorer.vercel.app//docs/react)
|
|
44
|
-
|
|
45
|
-
## License
|
|
46
|
-
|
|
47
|
-
MIT
|
|
1
|
+
# @gridstorm/react
|
|
2
|
+
|
|
3
|
+
React 18+ adapter for GridStorm with hooks, error boundaries, and portal-based overlays.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @gridstorm/react @gridstorm/core @gridstorm/dom-renderer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { GridStorm } from '@gridstorm/react';
|
|
15
|
+
import { SortingPlugin } from '@gridstorm/plugin-sorting';
|
|
16
|
+
|
|
17
|
+
const columns = [
|
|
18
|
+
{ field: 'name', headerName: 'Name' },
|
|
19
|
+
{ field: 'age', headerName: 'Age' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export default function App() {
|
|
23
|
+
return (
|
|
24
|
+
<GridStorm
|
|
25
|
+
rowData={[{ id: 1, name: 'Alice', age: 32 }]}
|
|
26
|
+
columnDefs={columns}
|
|
27
|
+
plugins={[SortingPlugin()]}
|
|
28
|
+
height={400}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- `<GridStorm>` component with declarative props
|
|
37
|
+
- React hooks for grid state access
|
|
38
|
+
- Error boundary for graceful error handling
|
|
39
|
+
- Portal-based overlays for editors and menus
|
|
40
|
+
|
|
41
|
+
## Documentation
|
|
42
|
+
|
|
43
|
+
[Full API Reference](https://grid-data-analytics-explorer.vercel.app//api/react) | [React Guide](https://grid-data-analytics-explorer.vercel.app//docs/react)
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -652,7 +652,7 @@ function GridStorm(props) {
|
|
|
652
652
|
theme
|
|
653
653
|
}),
|
|
654
654
|
// Only recreate config on structural changes
|
|
655
|
-
// eslint-disable-next-line
|
|
655
|
+
// eslint-disable-next-line -- intentional dependency omission
|
|
656
656
|
[coreColumns, plugins, rowModelType, getRowId]
|
|
657
657
|
);
|
|
658
658
|
const engine = useGridEngine(config);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.ts","../src/renderers/ReactCellRenderer.ts","../src/renderers/ReactHeaderRenderer.ts","../src/portals/CellRendererPortal.tsx","../src/portals/CellEditorPortal.tsx","../src/portals/ContextMenuPortal.tsx","../src/portals/PortalManager.tsx","../src/ErrorBoundary.tsx","../src/GridStorm.tsx","../src/hooks/useGridApi.ts","../src/hooks/useGridState.ts","../src/hooks/useGridSelection.ts","../src/hooks/useGridSort.ts","../src/hooks/useGridFilter.ts","../src/hooks/useGridPagination.ts","../src/hooks/useGridEvent.ts","../src/hooks/useGridColumn.ts"],"names":["createContext","useContext","Component","jsx","memo","useState","useRef","useCallback","useEffect","getValueFromData","useSyncExternalStore","jsxs","Fragment","createPortal","createGrid","useMemo","DomRenderer"],"mappings":"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","file":"index.cjs","sourcesContent":["// ─── Grid Context ───\n// Provides the engine, API, and metadata to all child hooks and components.\n\nimport { createContext, useContext } from 'react';\nimport type { GridEngine, GridApi } from '@gridstorm/core';\n\nexport interface GridContextValue<TData = any> {\n engine: GridEngine<TData>;\n api: GridApi<TData>;\n /** The root DOM element (.gs-root) of the grid. */\n rootElement: HTMLElement | null;\n}\n\nexport const GridContext = createContext<GridContextValue | null>(null);\n\n/**\n * Internal helper — gets grid context with null-check.\n * All public hooks use this internally.\n */\nexport function useGridContext<TData = any>(): GridContextValue<TData> {\n const ctx = useContext(GridContext);\n if (!ctx) {\n throw new Error(\n '[GridStorm] Hook must be used within a <GridStorm> component.',\n );\n }\n return ctx as GridContextValue<TData>;\n}\n","// ─── React Cell Renderer Marker ───\n// Wraps a React component so it can be used as a CellRendererFn.\n// The DomRenderer will receive an empty string (creating an empty cell),\n// and the PortalManager will detect the marker and portal the React\n// component into that cell.\n\nimport type { ReactCellRenderer } from '../types';\n\n/** Symbol marker for React cell renderers. */\nexport const REACT_CELL_RENDERER = Symbol.for('gridstorm:reactCellRenderer');\n\n/**\n * Wrap a React component to use as a cell renderer.\n *\n * @example\n * ```tsx\n * const StatusCell = ({ value }: CellRendererProps) => (\n * <span className={value ? 'active' : 'inactive'}>{value ? 'Yes' : 'No'}</span>\n * );\n *\n * const columns = [\n * { field: 'active', cellRenderer: reactCellRenderer(StatusCell) },\n * ];\n * ```\n */\nexport function reactCellRenderer<TData = any, TValue = any>(\n Component: ReactCellRenderer<TData, TValue>,\n): any {\n // Return a CellRendererFn that outputs empty string.\n // The DomRenderer will create an empty cell; the PortalManager portals React content into it.\n const fn = () => '';\n (fn as any)[REACT_CELL_RENDERER] = Component;\n return fn;\n}\n\n/** Check if a cellRenderer is a wrapped React component. */\nexport function isReactCellRenderer(fn: unknown): boolean {\n return typeof fn === 'function' && REACT_CELL_RENDERER in (fn as any);\n}\n\n/** Extract the React component from a wrapped cell renderer. */\nexport function getReactCellComponent<TData = any, TValue = any>(\n fn: unknown,\n): ReactCellRenderer<TData, TValue> | null {\n if (isReactCellRenderer(fn)) {\n return (fn as any)[REACT_CELL_RENDERER];\n }\n return null;\n}\n","// ─── React Header Renderer Marker ───\n// Same pattern as ReactCellRenderer but for header cells.\n\nimport type { ReactHeaderRenderer } from '../types';\n\n/** Symbol marker for React header renderers. */\nexport const REACT_HEADER_RENDERER = Symbol.for('gridstorm:reactHeaderRenderer');\n\n/**\n * Wrap a React component to use as a header renderer.\n *\n * @example\n * ```tsx\n * const SortHeader = ({ displayName, sortDirection, onSortRequested }: HeaderRendererProps) => (\n * <div onClick={() => onSortRequested(false)}>\n * {displayName} {sortDirection === 'asc' ? '▲' : sortDirection === 'desc' ? '▼' : ''}\n * </div>\n * );\n *\n * const columns = [\n * { field: 'name', headerRenderer: reactHeaderRenderer(SortHeader) },\n * ];\n * ```\n */\nexport function reactHeaderRenderer<TData = any>(\n Component: ReactHeaderRenderer<TData>,\n): any {\n const fn = () => '';\n (fn as any)[REACT_HEADER_RENDERER] = Component;\n return fn;\n}\n\n/** Check if a headerRenderer is a wrapped React component. */\nexport function isReactHeaderRenderer(fn: unknown): boolean {\n return typeof fn === 'function' && REACT_HEADER_RENDERER in (fn as any);\n}\n\n/** Extract the React component from a wrapped header renderer. */\nexport function getReactHeaderComponent<TData = any>(\n fn: unknown,\n): ReactHeaderRenderer<TData> | null {\n if (isReactHeaderRenderer(fn)) {\n return (fn as any)[REACT_HEADER_RENDERER];\n }\n return null;\n}\n","// ─── Cell Renderer Portal ───\n// Memoized wrapper for individual React cell renderer portals.\n// Custom comparator prevents re-renders when cell data hasn't changed.\n\nimport { memo } from 'react';\nimport type { ReactCellRenderer, CellRendererProps } from '../types';\n\ninterface CellRendererPortalProps<TData = any, TValue = any> {\n Component: ReactCellRenderer<TData, TValue>;\n rendererProps: CellRendererProps<TData, TValue>;\n nodeVersion: number;\n}\n\nfunction CellRendererPortalInner<TData = any, TValue = any>(\n props: CellRendererPortalProps<TData, TValue>,\n) {\n const { Component, rendererProps } = props;\n return <Component {...rendererProps} />;\n}\n\n/** Memoized cell renderer portal — only re-renders when value or version changes. */\nexport const CellRendererPortal = memo(\n CellRendererPortalInner,\n (prev, next) =>\n prev.nodeVersion === next.nodeVersion &&\n prev.rendererProps.value === next.rendererProps.value &&\n prev.rendererProps.rowIndex === next.rendererProps.rowIndex &&\n prev.rendererProps.colId === next.rendererProps.colId,\n) as typeof CellRendererPortalInner;\n","// ─── Cell Editor Portal ───\n// Renders a React cell editor component as an absolutely-positioned\n// overlay on top of the editing cell.\n\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport type { GridEngine, GridApi } from '@gridstorm/core';\nimport type { ReactCellEditor, EditorPortalState } from '../types';\n\ninterface CellEditorPortalProps<TData = any> {\n state: EditorPortalState;\n api: GridApi<TData>;\n engine: GridEngine<TData>;\n EditorComponent: ReactCellEditor<TData>;\n editorParams: Record<string, unknown>;\n gridRootRect: DOMRect;\n}\n\nexport function CellEditorPortal<TData = any>(props: CellEditorPortalProps<TData>) {\n const { state, api, engine, EditorComponent, editorParams, gridRootRect } = props;\n const { editing, cellRect } = state;\n const [value, setValue] = useState(editing.value);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const onValueChange = useCallback(\n (newValue: any) => {\n setValue(newValue);\n engine.commandBus.dispatch('editing:setValue', { value: newValue });\n },\n [engine],\n );\n\n const stopEditing = useCallback(\n (cancel?: boolean) => {\n api.stopEditing(cancel);\n },\n [api],\n );\n\n // Auto-focus the editor on mount\n useEffect(() => {\n requestAnimationFrame(() => {\n const el = containerRef.current;\n if (!el) return;\n const focusable = el.querySelector<HTMLElement>(\n 'input, textarea, select, [tabindex]',\n );\n focusable?.focus();\n });\n }, []);\n\n const column = engine.store\n .getState()\n .columns.find((c) => c.colId === editing.colId)!;\n\n const node = engine.store.getState().rowNodes.get(editing.rowId);\n\n // Position relative to the grid root\n const top = cellRect.top - gridRootRect.top;\n const left = cellRect.left - gridRootRect.left;\n\n return (\n <div\n ref={containerRef}\n className=\"gs-editor-portal\"\n style={{\n position: 'absolute',\n top,\n left,\n width: cellRect.width,\n height: cellRect.height,\n zIndex: 10,\n boxSizing: 'border-box',\n background: 'var(--gs-color-cell-editing-bg, #fff)',\n border: '2px solid var(--gs-color-cell-editing-border, #2196f3)',\n }}\n >\n <EditorComponent\n value={value}\n data={node?.data as TData}\n colId={editing.colId}\n rowId={editing.rowId}\n column={column}\n editorParams={editorParams}\n onValueChange={onValueChange}\n stopEditing={stopEditing}\n api={api}\n />\n </div>\n );\n}\n","// ─── Context Menu Portal ───\n// Renders a user-provided context menu component at the right-click position.\n\nimport { useEffect, useRef } from 'react';\nimport type { ContextMenuProps, ReactContextMenu } from '../types';\n\ninterface ContextMenuPortalProps<TData = any> {\n x: number;\n y: number;\n menuProps: ContextMenuProps<TData>;\n Component: ReactContextMenu<TData>;\n}\n\nexport function ContextMenuPortal<TData = any>(\n props: ContextMenuPortalProps<TData>,\n) {\n const { x, y, menuProps, Component } = props;\n const ref = useRef<HTMLDivElement>(null);\n\n // Close on click outside\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n menuProps.closeMenu();\n }\n };\n // Use setTimeout so the current click doesn't immediately close the menu\n const id = setTimeout(() => {\n document.addEventListener('mousedown', handler);\n }, 0);\n return () => {\n clearTimeout(id);\n document.removeEventListener('mousedown', handler);\n };\n }, [menuProps]);\n\n // Close on Escape\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') menuProps.closeMenu();\n };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [menuProps]);\n\n return (\n <div\n ref={ref}\n className=\"gs-context-menu-portal\"\n style={{\n position: 'absolute',\n top: y,\n left: x,\n zIndex: 100,\n minWidth: 160,\n }}\n >\n <Component {...menuProps} />\n </div>\n );\n}\n","// ─── Portal Manager ───\r\n// Central orchestrator for all React portals: cell renderers, header\r\n// renderers, editors, and context menus.\r\n//\r\n// Uses a MutationObserver on .gs-body to detect when DomRenderer\r\n// adds/removes row elements, then portals React content into wrapper\r\n// divs inside cells that have React renderers.\r\n//\r\n// KEY DESIGN: We never portal directly into DomRenderer-managed cells.\r\n// Instead, we create a wrapper <div style=\"display:contents\"> inside each\r\n// cell and portal into that wrapper. This prevents crashes when DomRenderer\r\n// destroys/recycles cells — the wrapper is detached but still maintains\r\n// its React children, so React can safely unmount.\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useState,\r\n useCallback,\r\n useSyncExternalStore,\r\n} from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport type { GridEngine, GridApi, ColumnState, RowNode } from '@gridstorm/core';\r\nimport { getValueFromData } from '@gridstorm/core';\r\nimport type {\r\n ReactColumnDef,\r\n CellRendererProps,\r\n HeaderRendererProps,\r\n EditorPortalState,\r\n ContextMenuProps,\r\n ReactContextMenu,\r\n ReactCellEditor,\r\n} from '../types';\r\nimport { getReactCellComponent, isReactCellRenderer } from '../renderers/ReactCellRenderer';\r\nimport { getReactHeaderComponent, isReactHeaderRenderer } from '../renderers/ReactHeaderRenderer';\r\nimport { CellRendererPortal } from './CellRendererPortal';\r\nimport { CellEditorPortal } from './CellEditorPortal';\r\nimport { ContextMenuPortal } from './ContextMenuPortal';\r\n\r\nexport interface PortalManagerProps<TData = any> {\r\n engine: GridEngine<TData>;\r\n api: GridApi<TData>;\r\n columns: ReactColumnDef<TData>[];\r\n rootElement: HTMLElement | null;\r\n contextMenuComponent?: ReactContextMenu<TData>;\r\n}\r\n\r\n// ── Portal wrapper attribute ──\r\n// Used to identify wrapper divs we've created inside cells.\r\nconst WRAPPER_ATTR = 'data-gs-portal';\r\n\r\n// ── Cell renderer portal entry ──\r\ninterface CellPortalEntry<TData = any> {\r\n key: string;\r\n /** The wrapper div inside the cell (React-owned, safe to portal into) */\r\n container: HTMLElement;\r\n component: any;\r\n props: CellRendererProps<TData>;\r\n nodeVersion: number;\r\n}\r\n\r\n// ── Header renderer portal entry ──\r\ninterface HeaderPortalEntry {\r\n key: string;\r\n /** The wrapper div inside the header cell */\r\n container: HTMLElement;\r\n element: any;\r\n}\r\n\r\n// ── Context menu state ──\r\ninterface ContextMenuState<TData = any> {\r\n x: number;\r\n y: number;\r\n menuProps: ContextMenuProps<TData>;\r\n}\r\n\r\n// ── Helper: get or create a stable wrapper div inside a cell ──\r\n// The wrapper uses display:contents so it's layout-transparent.\r\n// When DomRenderer destroys the cell, the wrapper is detached but\r\n// still maintains its children — React can safely unmount from it.\r\nfunction getOrCreateWrapper(cell: HTMLElement): HTMLElement {\r\n // Check direct children only (not descendants) for existing wrapper\r\n for (let i = 0; i < cell.children.length; i++) {\r\n const child = cell.children[i] as HTMLElement;\r\n if (child.hasAttribute(WRAPPER_ATTR)) {\r\n return child;\r\n }\r\n }\r\n // Create new wrapper\r\n const wrapper = document.createElement('div');\r\n wrapper.setAttribute(WRAPPER_ATTR, '');\r\n wrapper.style.display = 'contents';\r\n cell.appendChild(wrapper);\r\n return wrapper;\r\n}\r\n\r\nexport function PortalManager<TData = any>(props: PortalManagerProps<TData>) {\r\n const { engine, api, columns, rootElement, contextMenuComponent } = props;\r\n\r\n // ── Portal state ──\r\n const [cellPortals, setCellPortals] = useState<Map<string, CellPortalEntry<TData>>>(\r\n () => new Map(),\r\n );\r\n const [headerPortals, setHeaderPortals] = useState<Map<string, HeaderPortalEntry>>(\r\n () => new Map(),\r\n );\r\n const [editorPortal, setEditorPortal] = useState<EditorPortalState | null>(null);\r\n const [contextMenu, setContextMenu] = useState<ContextMenuState<TData> | null>(null);\r\n\r\n // Refs for stable access in callbacks\r\n const columnsRef = useRef(columns);\r\n columnsRef.current = columns;\r\n const engineRef = useRef(engine);\r\n engineRef.current = engine;\r\n\r\n // Track if we're currently scanning to prevent re-entrant scans\r\n const scanningRef = useRef(false);\r\n\r\n // ── Build lookup maps for which columns have React renderers ──\r\n const reactCellRendererMap = useRef(new Map<string, any>());\r\n const reactHeaderRendererMap = useRef(new Map<string, any>());\r\n const reactEditorMap = useRef(new Map<string, ReactCellEditor<TData>>());\r\n\r\n useEffect(() => {\r\n const cellMap = new Map<string, any>();\r\n const headerMap = new Map<string, any>();\r\n const editorMap = new Map<string, ReactCellEditor<TData>>();\r\n\r\n for (const col of columns) {\r\n const colId = (col as any).colId ?? col.field ?? '';\r\n if (col.cellRenderer && isReactCellRenderer(col.cellRenderer)) {\r\n cellMap.set(colId, getReactCellComponent(col.cellRenderer));\r\n }\r\n if (col.headerRenderer && isReactHeaderRenderer(col.headerRenderer)) {\r\n headerMap.set(colId, getReactHeaderComponent(col.headerRenderer));\r\n }\r\n if (col.cellEditorComponent) {\r\n editorMap.set(colId, col.cellEditorComponent);\r\n }\r\n }\r\n\r\n reactCellRendererMap.current = cellMap;\r\n reactHeaderRendererMap.current = headerMap;\r\n reactEditorMap.current = editorMap;\r\n }, [columns]);\r\n\r\n // ── Helper: build cell renderer props ──\r\n const buildCellProps = useCallback(\r\n (node: RowNode<TData>, col: ColumnState, rowIndex: number): CellRendererProps<TData> => {\r\n const colDef = col.originalDef;\r\n let value: any;\r\n if (colDef.valueGetter) {\r\n value = colDef.valueGetter({\r\n data: node.data,\r\n node,\r\n colDef,\r\n colId: col.colId,\r\n });\r\n } else {\r\n value = getValueFromData(node.data, col.field);\r\n }\r\n\r\n let formattedValue = value != null ? String(value) : '';\r\n if (colDef.valueFormatter) {\r\n formattedValue = colDef.valueFormatter({ value, data: node.data, node, colDef });\r\n }\r\n\r\n return {\r\n value,\r\n formattedValue,\r\n data: node.data,\r\n node,\r\n colDef,\r\n colId: col.colId,\r\n rowIndex,\r\n api,\r\n };\r\n },\r\n [api],\r\n );\r\n\r\n // ── Scan visible rows and create/update cell portals ──\r\n const scanVisibleRows = useCallback(() => {\r\n if (!rootElement || scanningRef.current) return;\r\n scanningRef.current = true;\r\n\r\n try {\r\n const bodyContainer = rootElement.querySelector('.gs-body');\r\n if (!bodyContainer) return;\r\n\r\n const state = engineRef.current.store.getState();\r\n const cellRenderers = reactCellRendererMap.current;\r\n if (cellRenderers.size === 0) return;\r\n\r\n const newPortals = new Map<string, CellPortalEntry<TData>>();\r\n const rowElements = bodyContainer.querySelectorAll<HTMLElement>('.gs-row');\r\n\r\n // Pre-build O(1) lookup maps to avoid O(n) indexOf / find in hot path\r\n const rowIdIndexMap = new Map<string, number>();\r\n for (let i = 0; i < state.displayedRowIds.length; i++) {\r\n rowIdIndexMap.set(state.displayedRowIds[i]!, i);\r\n }\r\n const columnMap = new Map<string, ColumnState>();\r\n for (const col of state.columns) {\r\n columnMap.set(col.colId, col);\r\n }\r\n\r\n for (const rowEl of rowElements) {\r\n const rowId = rowEl.getAttribute('data-row-id');\r\n if (!rowId) continue;\r\n\r\n const node = state.rowNodes.get(rowId);\r\n if (!node) continue;\r\n\r\n const cells = rowEl.querySelectorAll<HTMLElement>('.gs-cell');\r\n for (const cellEl of cells) {\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!colId || !cellRenderers.has(colId)) continue;\r\n\r\n const key = `${rowId}:${colId}`;\r\n const Component = cellRenderers.get(colId)!;\r\n const colState = columnMap.get(colId);\r\n if (!colState) continue;\r\n\r\n const rowIndex = rowIdIndexMap.get(rowId) ?? -1;\r\n const rendererProps = buildCellProps(node, colState, rowIndex);\r\n\r\n // Get or create a stable wrapper div inside the cell.\r\n // We portal into the wrapper, NOT the cell directly.\r\n // This prevents crashes when DomRenderer destroys/recycles cells.\r\n const wrapper = getOrCreateWrapper(cellEl);\r\n\r\n newPortals.set(key, {\r\n key,\r\n container: wrapper,\r\n component: Component,\r\n props: rendererProps,\r\n nodeVersion: node.version,\r\n });\r\n }\r\n }\r\n\r\n setCellPortals(newPortals);\r\n } finally {\r\n scanningRef.current = false;\r\n }\r\n }, [rootElement, buildCellProps]);\r\n\r\n // ── Scan header cells for React header renderers ──\r\n const scanHeaderCells = useCallback(() => {\r\n if (!rootElement) return;\r\n const headerRenderers = reactHeaderRendererMap.current;\r\n if (headerRenderers.size === 0) return;\r\n\r\n const headerContainer = rootElement.querySelector('.gs-header');\r\n if (!headerContainer) return;\r\n\r\n const state = engineRef.current.store.getState();\r\n const newPortals = new Map<string, HeaderPortalEntry>();\r\n\r\n const headerCells = headerContainer.querySelectorAll<HTMLElement>('.gs-header-cell');\r\n for (const cellEl of headerCells) {\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!colId || !headerRenderers.has(colId)) continue;\r\n\r\n const Component = headerRenderers.get(colId)!;\r\n const colState = state.columns.find((c) => c.colId === colId);\r\n if (!colState) continue;\r\n\r\n const sortItem = state.sortModel.find((s) => s.colId === colId);\r\n\r\n const headerProps: HeaderRendererProps<TData> = {\r\n colDef: colState.originalDef,\r\n colId,\r\n displayName: colState.headerName,\r\n sortDirection: sortItem?.sort ?? null,\r\n sortIndex: colState.sortIndex,\r\n api,\r\n onSortRequested: (multiSort: boolean) => {\r\n engineRef.current.commandBus.dispatch('sort:toggle', { colId, multiSort });\r\n },\r\n };\r\n\r\n // Get or create a stable wrapper div inside the header cell.\r\n const wrapper = getOrCreateWrapper(cellEl);\r\n\r\n newPortals.set(colId, {\r\n key: colId,\r\n container: wrapper,\r\n element: <Component {...headerProps} />,\r\n });\r\n }\r\n\r\n setHeaderPortals(newPortals);\r\n }, [rootElement, api]);\r\n\r\n // ── MutationObserver on .gs-body for row add/remove ──\r\n useEffect(() => {\r\n if (!rootElement) return;\r\n const bodyContainer = rootElement.querySelector('.gs-body');\r\n if (!bodyContainer) return;\r\n\r\n const observer = new MutationObserver(() => {\r\n // When DomRenderer adds/removes rows, re-scan for portals\r\n scanVisibleRows();\r\n });\r\n\r\n observer.observe(bodyContainer, { childList: true });\r\n\r\n // Initial scan for already-rendered rows\r\n scanVisibleRows();\r\n scanHeaderCells();\r\n\r\n return () => observer.disconnect();\r\n }, [rootElement, scanVisibleRows, scanHeaderCells]);\r\n\r\n // ── Re-scan when state changes (sort, filter, data) ──\r\n const getVersionSnapshot = useCallback(() => engine.store.getVersion(), [engine]);\r\n const subscribeStore = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const stateVersion = useSyncExternalStore(\r\n subscribeStore,\r\n getVersionSnapshot,\r\n getVersionSnapshot,\r\n );\r\n\r\n useEffect(() => {\r\n scanVisibleRows();\r\n }, [stateVersion, scanVisibleRows]);\r\n\r\n // ── Re-scan headers when sort or columns change ──\r\n useEffect(() => {\r\n const unsubs = [\r\n engine.eventBus.on('column:sort:changed', () => {\r\n // Delay slightly to let DomRenderer recreate header cells first\r\n requestAnimationFrame(() => scanHeaderCells());\r\n }),\r\n engine.eventBus.on('columns:changed', () => {\r\n requestAnimationFrame(() => scanHeaderCells());\r\n }),\r\n ];\r\n return () => unsubs.forEach((u) => u());\r\n }, [engine, scanHeaderCells]);\r\n\r\n // ── Editor portal lifecycle ──\r\n useEffect(() => {\r\n const unsubStart = engine.eventBus.on(\r\n 'cell:editingStarted',\r\n (event: any) => {\r\n const { node, colId } = event;\r\n const editorComponent = reactEditorMap.current.get(colId);\r\n if (!editorComponent || !rootElement) return;\r\n\r\n // Find the cell element (CSS.escape prevents selector injection from rowId/colId)\r\n const cellEl = rootElement.querySelector<HTMLElement>(\r\n `.gs-row[data-row-id=\"${CSS.escape(node.id)}\"] .gs-cell[data-col-id=\"${CSS.escape(colId)}\"]`,\r\n );\r\n if (!cellEl) return;\r\n\r\n const state = engine.store.getState();\r\n const editing = state.editing;\r\n if (!editing) return;\r\n\r\n setEditorPortal({\r\n editing,\r\n cellElement: cellEl,\r\n cellRect: cellEl.getBoundingClientRect(),\r\n });\r\n },\r\n );\r\n\r\n const unsubStop = engine.eventBus.on('cell:editingStopped', () => {\r\n setEditorPortal(null);\r\n });\r\n\r\n return () => {\r\n unsubStart();\r\n unsubStop();\r\n };\r\n }, [engine, rootElement]);\r\n\r\n // ── Context menu ──\r\n useEffect(() => {\r\n if (!rootElement || !contextMenuComponent) return;\r\n\r\n const handler = (e: MouseEvent) => {\r\n e.preventDefault();\r\n const target = e.target as HTMLElement;\r\n const cellEl = target.closest<HTMLElement>('.gs-cell');\r\n const rowEl = target.closest<HTMLElement>('.gs-row');\r\n if (!cellEl || !rowEl) return;\r\n\r\n const rowId = rowEl.getAttribute('data-row-id');\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!rowId || !colId) return;\r\n\r\n const state = engine.store.getState();\r\n const node = state.rowNodes.get(rowId);\r\n if (!node) return;\r\n\r\n const colState = state.columns.find((c) => c.colId === colId);\r\n const value = colState\r\n ? getValueFromData(node.data, colState.field)\r\n : undefined;\r\n\r\n const rootRect = rootElement.getBoundingClientRect();\r\n const rowIndex = state.displayedRowIds.indexOf(rowId);\r\n\r\n setContextMenu({\r\n x: e.clientX - rootRect.left,\r\n y: e.clientY - rootRect.top,\r\n menuProps: {\r\n position: { rowIndex, colId },\r\n node,\r\n colId,\r\n value,\r\n api,\r\n closeMenu: () => setContextMenu(null),\r\n },\r\n });\r\n };\r\n\r\n rootElement.addEventListener('contextmenu', handler);\r\n return () => rootElement.removeEventListener('contextmenu', handler);\r\n }, [rootElement, contextMenuComponent, api, engine]);\r\n\r\n // ── Render portals ──\r\n return (\r\n <>\r\n {/* Cell renderer portals — portaled into wrapper divs, NOT cells directly */}\r\n {Array.from(cellPortals.values()).map((entry) =>\r\n createPortal(\r\n <CellRendererPortal\r\n key={entry.key}\r\n Component={entry.component}\r\n rendererProps={entry.props}\r\n nodeVersion={entry.nodeVersion}\r\n />,\r\n entry.container,\r\n entry.key,\r\n ),\r\n )}\r\n\r\n {/* Header renderer portals — portaled into wrapper divs in header cells */}\r\n {Array.from(headerPortals.values()).map((entry) =>\r\n createPortal(entry.element, entry.container, entry.key),\r\n )}\r\n\r\n {/* Editor portal */}\r\n {editorPortal && rootElement && (() => {\r\n const editorComponent = reactEditorMap.current.get(editorPortal.editing.colId);\r\n if (!editorComponent) return null;\r\n const colDef = columnsRef.current.find(\r\n (c) => ((c as any).colId ?? c.field) === editorPortal.editing.colId,\r\n );\r\n return createPortal(\r\n <CellEditorPortal\r\n state={editorPortal}\r\n api={api}\r\n engine={engine}\r\n EditorComponent={editorComponent}\r\n editorParams={(colDef?.cellEditorParams as Record<string, unknown>) ?? {}}\r\n gridRootRect={rootElement.getBoundingClientRect()}\r\n />,\r\n rootElement,\r\n 'gs-editor',\r\n );\r\n })()}\r\n\r\n {/* Context menu portal */}\r\n {contextMenu && contextMenuComponent && rootElement &&\r\n createPortal(\r\n <ContextMenuPortal\r\n x={contextMenu.x}\r\n y={contextMenu.y}\r\n menuProps={contextMenu.menuProps}\r\n Component={contextMenuComponent}\r\n />,\r\n rootElement,\r\n 'gs-context-menu',\r\n )}\r\n </>\r\n );\r\n}\r\n","// ─── GridStorm Error Boundary ───\n// Catches rendering errors in the grid and displays a fallback UI.\n\nimport { Component, type ReactNode, type ErrorInfo } from 'react';\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class GridErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state: ErrorBoundaryState = { hasError: false, error: null };\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n console.error('[GridStorm] Rendering error:', error, errorInfo.componentStack);\n }\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n return null;\n }\n return this.props.children;\n }\n}\n","// ─── GridStorm React Component ───\r\n// Production-grade React wrapper around the headless core engine.\r\n// Supports controlled + uncontrolled modes, React component cell/header\r\n// renderers via portals, event bridging, and comprehensive hooks.\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useMemo,\r\n useState,\r\n type CSSProperties,\r\n} from 'react';\r\nimport type {\r\n GridConfig,\r\n ColumnDef,\r\n GridEngine,\r\n} from '@gridstorm/core';\r\nimport { createGrid } from '@gridstorm/core';\r\nimport { DomRenderer } from '@gridstorm/dom-renderer';\r\nimport { GridContext, type GridContextValue } from './context';\r\nimport { PortalManager } from './portals/PortalManager';\r\nimport type { GridStormProps, ReactColumnDef } from './types';\r\nimport { GridErrorBoundary } from './ErrorBoundary';\r\n\r\n// ── useGridEngine hook (internal) ──\r\n// Uses useState + useEffect so that StrictMode's cleanup → remount cycle\r\n// creates a fresh engine each time instead of leaving a null ref.\r\n\r\nfunction useGridEngine<TData = any>(config: GridConfig<TData>): GridEngine<TData> | null {\r\n const [engine, setEngine] = useState<GridEngine<TData> | null>(null);\r\n const configRef = useRef(config);\r\n configRef.current = config;\r\n\r\n // Track whether the initial mount has completed so sync effects\r\n // don't double-set data that was already applied during createGrid.\r\n const rowDataMountedRef = useRef(false);\r\n const columnsMountedRef = useRef(false);\r\n\r\n // Create engine in useEffect so StrictMode can safely destroy + recreate\r\n useEffect(() => {\r\n const eng = createGrid(configRef.current);\r\n setEngine(eng);\r\n\r\n // Reset mounted flags when engine is (re)created\r\n rowDataMountedRef.current = false;\r\n columnsMountedRef.current = false;\r\n\r\n return () => {\r\n eng.destroy();\r\n setEngine(null);\r\n };\r\n }, []);\r\n\r\n // Sync rowData changes (skip the first run — createGrid already applied initial data)\r\n useEffect(() => {\r\n if (!engine) return;\r\n if (!rowDataMountedRef.current) {\r\n rowDataMountedRef.current = true;\r\n return;\r\n }\r\n if (config.rowData) {\r\n engine.api.setRowData(config.rowData);\r\n }\r\n }, [config.rowData, engine]);\r\n\r\n // Sync column changes (skip the first run — createGrid already applied initial columns)\r\n useEffect(() => {\r\n if (!engine) return;\r\n if (!columnsMountedRef.current) {\r\n columnsMountedRef.current = true;\r\n return;\r\n }\r\n if (config.columns) {\r\n engine.api.setColumnDefs(config.columns);\r\n }\r\n }, [config.columns, engine]);\r\n\r\n return engine;\r\n}\r\n\r\n// ── Column processing: convert ReactColumnDef[] → ColumnDef[] ──\r\n\r\nfunction processColumns<TData>(\r\n reactColumns: ReactColumnDef<TData>[],\r\n): ColumnDef<TData>[] {\r\n return reactColumns.map((col) => {\r\n const coreDef = { ...col } as any;\r\n\r\n // If cellRenderer is a React-wrapped renderer, keep the marker function\r\n // (it returns '' so DomRenderer creates empty cells; PortalManager handles rendering)\r\n // If it's a plain CellRendererFn, leave it as-is.\r\n // No conversion needed — the marker fn IS a valid CellRendererFn.\r\n\r\n // If headerRenderer is React-wrapped, same logic applies.\r\n\r\n // Remove React-only fields from the core column def\r\n delete coreDef.cellEditorComponent;\r\n\r\n return coreDef as ColumnDef<TData>;\r\n });\r\n}\r\n\r\n// ── Main Component ──\r\n\r\nexport function GridStorm<TData = any>(props: GridStormProps<TData>) {\r\n const {\r\n // GridConfig props\r\n columns: reactColumns,\r\n rowData,\r\n dataSource,\r\n rowModelType,\r\n getRowId,\r\n plugins,\r\n defaultColDef,\r\n rowHeight,\r\n headerHeight,\r\n domLayout,\r\n pinnedTopRowData,\r\n pinnedBottomRowData,\r\n suppressScrollX,\r\n suppressScrollY,\r\n rowSelection,\r\n editType,\r\n undoRedoCellEditing,\r\n pagination,\r\n paginationPageSize,\r\n animateRows,\r\n ariaLabel,\r\n locale,\r\n theme,\r\n // Controlled state props\r\n sortModel: controlledSortModel,\r\n onSortModelChange,\r\n filterModel: controlledFilterModel,\r\n onFilterModelChange,\r\n selectedRowIds: controlledSelectedRowIds,\r\n onSelectedRowIdsChange,\r\n currentPage: controlledCurrentPage,\r\n onCurrentPageChange,\r\n // Event props\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n // Renderer config props\r\n enableCellEditing,\r\n enableGrouping,\r\n groupIndent,\r\n checkboxSelection,\r\n checkboxColumnWidth,\r\n floatingFilter,\r\n floatingFilterDebounce,\r\n enablePagination,\r\n pageSizeOptions,\r\n // Component props\r\n height = 400,\r\n width = '100%',\r\n containerClass,\r\n containerStyle,\r\n contextMenu,\r\n children,\r\n // Rest are ignored (no HTML div passthrough to avoid TS errors)\r\n } = props;\r\n\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const rendererRef = useRef<DomRenderer | null>(null);\r\n const [rootElement, setRootElement] = useState<HTMLElement | null>(null);\r\n\r\n // ── Convert React columns to core columns ──\r\n const coreColumns = useMemo(\r\n () => processColumns(reactColumns),\r\n [reactColumns],\r\n );\r\n\r\n // ── Build core config (only depends on structural changes) ──\r\n const config = useMemo<GridConfig<TData>>(\r\n () => ({\r\n columns: coreColumns,\r\n rowData,\r\n dataSource,\r\n rowModelType,\r\n getRowId,\r\n plugins,\r\n defaultColDef,\r\n rowHeight,\r\n headerHeight,\r\n domLayout,\r\n pinnedTopRowData,\r\n pinnedBottomRowData,\r\n suppressScrollX,\r\n suppressScrollY,\r\n rowSelection,\r\n editType,\r\n undoRedoCellEditing,\r\n pagination,\r\n paginationPageSize,\r\n animateRows,\r\n ariaLabel,\r\n locale,\r\n theme,\r\n }),\r\n // Only recreate config on structural changes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [coreColumns, plugins, rowModelType, getRowId],\r\n );\r\n\r\n // ── Create grid engine ──\r\n const engine = useGridEngine<TData>(config);\r\n\r\n // ── Mount DOM renderer ──\r\n useEffect(() => {\r\n if (!containerRef.current || !engine) return;\r\n\r\n const renderer = new DomRenderer({\r\n container: containerRef.current,\r\n engine,\r\n enableCellEditing,\r\n enableGrouping,\r\n groupIndent,\r\n checkboxSelection,\r\n checkboxColumnWidth,\r\n floatingFilter,\r\n floatingFilterDebounce,\r\n enablePagination,\r\n pageSizeOptions,\r\n });\r\n renderer.mount();\r\n rendererRef.current = renderer;\r\n\r\n // Capture root element for portals\r\n const root = containerRef.current.querySelector<HTMLElement>('.gs-root');\r\n setRootElement(root);\r\n\r\n // Re-emit grid:ready now that the DOM renderer has mounted.\r\n // Plugins like column-resize, column-reorder, and context-menu\r\n // use requestAnimationFrame on grid:ready to inject DOM elements.\r\n // The original grid:ready fires during createGrid() before the\r\n // renderer exists, so those rAF callbacks find no DOM to work with.\r\n requestAnimationFrame(() => {\r\n engine.eventBus.emit('grid:ready', { api: engine.api });\r\n });\r\n\r\n return () => {\r\n renderer.destroy();\r\n rendererRef.current = null;\r\n setRootElement(null);\r\n };\r\n }, [engine]);\r\n\r\n // ── Controlled mode: install command bus middleware ──\r\n const controlledCallbacksRef = useRef({\r\n onSortModelChange,\r\n onFilterModelChange,\r\n onSelectedRowIdsChange,\r\n onCurrentPageChange,\r\n });\r\n controlledCallbacksRef.current = {\r\n onSortModelChange,\r\n onFilterModelChange,\r\n onSelectedRowIdsChange,\r\n onCurrentPageChange,\r\n };\r\n\r\n useEffect(() => {\r\n if (!engine) return;\r\n const removeMw = engine.commandBus.use((ctx) => {\r\n const cbs = controlledCallbacksRef.current;\r\n\r\n // Intercept sort commands in controlled mode\r\n if (ctx.commandType === 'sort:toggle' && cbs.onSortModelChange) {\r\n // Let the command execute to compute the new sort model,\r\n // then we'll intercept the result via the event listener\r\n return;\r\n }\r\n\r\n // Intercept selection in controlled mode\r\n if (ctx.commandType === 'selection:select' && cbs.onSelectedRowIdsChange) {\r\n // Let it through — we intercept via event\r\n return;\r\n }\r\n });\r\n\r\n return removeMw;\r\n }, [engine]);\r\n\r\n // ── Controlled mode: sync controlled props to engine ──\r\n useEffect(() => {\r\n if (controlledSortModel !== undefined && engine) {\r\n engine.api.setSortModel(controlledSortModel);\r\n }\r\n }, [controlledSortModel, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledFilterModel !== undefined && engine) {\r\n engine.api.setFilterModel(controlledFilterModel as any);\r\n }\r\n }, [controlledFilterModel, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledCurrentPage !== undefined && engine) {\r\n engine.api.paginationGoToPage(controlledCurrentPage);\r\n }\r\n }, [controlledCurrentPage, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledSelectedRowIds !== undefined && engine) {\r\n engine.commandBus.dispatch('selection:set', {\r\n selectedRowIds: new Set(controlledSelectedRowIds),\r\n });\r\n }\r\n }, [controlledSelectedRowIds, engine]);\r\n\r\n // ── Event bridge: core events → React callbacks ──\r\n const eventCallbacksRef = useRef({\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n });\r\n eventCallbacksRef.current = {\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n };\r\n\r\n useEffect(() => {\r\n if (!engine) return;\r\n const eb = engine.eventBus;\r\n const cbs = () => eventCallbacksRef.current;\r\n\r\n const unsubs = [\r\n eb.on('rowData:changed', (e) => cbs().onRowDataChanged?.(e)),\r\n eb.on('selection:changed', (e) => {\r\n cbs().onSelectionChanged?.(e);\r\n // Controlled mode: notify parent of selection change\r\n controlledCallbacksRef.current.onSelectedRowIdsChange?.(\r\n engine.store.getState().selection.selectedRowIds,\r\n (e as any).source ?? 'api',\r\n );\r\n }),\r\n eb.on('column:sort:changed', (e) => {\r\n cbs().onSortChanged?.(e);\r\n // Controlled mode: notify parent of sort change\r\n controlledCallbacksRef.current.onSortModelChange?.(e.sortModel);\r\n }),\r\n eb.on('filter:changed', (e) => {\r\n cbs().onFilterChanged?.(e);\r\n controlledCallbacksRef.current.onFilterModelChange?.(e.filterModel);\r\n }),\r\n eb.on('cell:valueChanged', (e) => cbs().onCellValueChanged?.(e)),\r\n eb.on('cell:clicked', (e) => cbs().onCellClicked?.(e)),\r\n eb.on('cell:doubleClicked', (e) => cbs().onCellDoubleClicked?.(e)),\r\n eb.on('row:clicked', (e) => cbs().onRowClicked?.(e)),\r\n eb.on('cell:editingStarted', (e) => cbs().onCellEditingStarted?.(e)),\r\n eb.on('cell:editingStopped', (e) => cbs().onCellEditingStopped?.(e)),\r\n eb.on('pagination:changed', (e) => {\r\n cbs().onPaginationChanged?.(e);\r\n controlledCallbacksRef.current.onCurrentPageChange?.(e.currentPage);\r\n }),\r\n eb.on('column:resized', (e) => cbs().onColumnResized?.(e)),\r\n ];\r\n\r\n return () => unsubs.forEach((u) => u());\r\n }, [engine]);\r\n\r\n // ── Fire onGridReady ──\r\n useEffect(() => {\r\n if (engine) {\r\n onGridReady?.(engine.api);\r\n }\r\n }, [engine]); // eslint-disable-line react-hooks/exhaustive-deps\r\n\r\n // ── Container style ──\r\n const style: CSSProperties = {\r\n height: typeof height === 'number' ? `${height}px` : height,\r\n width: typeof width === 'number' ? `${width}px` : width,\r\n ...containerStyle,\r\n };\r\n\r\n // ── Context value (stable reference) ──\r\n const contextValue = useMemo<GridContextValue<TData> | null>(\r\n () => (engine ? { engine, api: engine.api, rootElement } : null),\r\n [engine, rootElement],\r\n );\r\n\r\n // ── Before engine is ready (first render before useEffect), render only the container ──\r\n if (!engine || !contextValue) {\r\n return (\r\n <GridErrorBoundary>\r\n <div\r\n ref={containerRef}\r\n className={`gs-container ${containerClass ?? ''}`.trim()}\r\n style={style}\r\n />\r\n </GridErrorBoundary>\r\n );\r\n }\r\n\r\n return (\r\n <GridErrorBoundary>\r\n <GridContext.Provider value={contextValue as GridContextValue}>\r\n {children}\r\n <div\r\n ref={containerRef}\r\n className={`gs-container ${containerClass ?? ''}`.trim()}\r\n style={style}\r\n />\r\n <PortalManager\r\n engine={engine}\r\n api={engine.api}\r\n columns={reactColumns}\r\n rootElement={rootElement}\r\n contextMenuComponent={contextMenu}\r\n />\r\n </GridContext.Provider>\r\n </GridErrorBoundary>\r\n );\r\n}\r\n","// ─── useGridApi Hook ───\n// Access the GridApi from context.\n\nimport type { GridApi } from '@gridstorm/core';\nimport { useGridContext } from '../context';\n\n/**\n * Access the GridApi instance.\n * Must be used within a `<GridStorm>` component.\n */\nexport function useGridApi<TData = any>(): GridApi<TData> {\n return useGridContext<TData>().api;\n}\n","// ─── useGridState Hook ───\r\n// Selector-based reactive state subscription via useSyncExternalStore.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { GridState } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\n/**\r\n * Subscribe to grid state changes with a selector.\r\n * Re-renders only when the selected value changes (reference equality).\r\n *\r\n * @example\r\n * ```tsx\r\n * const rowCount = useGridState(state => state.displayedRowIds.length);\r\n * const sortModel = useGridState(state => state.sortModel);\r\n * ```\r\n */\r\nexport function useGridState<TData = any, TResult = any>(\r\n selector: (state: GridState<TData>) => TResult,\r\n): TResult {\r\n const { engine } = useGridContext<TData>();\r\n\r\n // Memoize getSnapshot so useSyncExternalStore doesn't re-subscribe every render\r\n const getSnapshot = useCallback(\r\n () => selector(engine.store.getState() as GridState<TData>),\r\n [selector, engine],\r\n );\r\n\r\n return useSyncExternalStore(\r\n (onStoreChange) => engine.store.subscribe(onStoreChange),\r\n getSnapshot,\r\n getSnapshot,\r\n );\r\n}\r\n","// ─── useGridSelection Hook ───\r\n// Selection state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { RowNode } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridSelectionResult<TData = any> {\r\n /** Set of selected row IDs. */\r\n selectedRowIds: Set<string>;\r\n /** Number of selected rows. */\r\n selectedCount: number;\r\n /** Get selected row data objects. */\r\n getSelectedRows: () => TData[];\r\n /** Get selected RowNode objects. */\r\n getSelectedNodes: () => RowNode<TData>[];\r\n /** Check if a specific row is selected. */\r\n isRowSelected: (rowId: string) => boolean;\r\n /** Select all visible rows. */\r\n selectAll: () => void;\r\n /** Deselect all rows. */\r\n deselectAll: () => void;\r\n}\r\n\r\n/**\r\n * Access selection state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { selectedCount, selectAll, deselectAll, isRowSelected } = useGridSelection();\r\n * ```\r\n */\r\nexport function useGridSelection<TData = any>(): GridSelectionResult<TData> {\r\n const { engine, api } = useGridContext<TData>();\r\n\r\n const getSelectionSnapshot = useCallback(() => engine.store.getState().selection.selectedRowIds, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const selectedRowIds = useSyncExternalStore(\r\n subscribe,\r\n getSelectionSnapshot,\r\n getSelectionSnapshot,\r\n );\r\n\r\n const selectedCount = selectedRowIds.size;\r\n\r\n const isRowSelected = useCallback(\r\n (rowId: string) =>\r\n engine.store.getState().selection.selectedRowIds.has(rowId),\r\n [engine],\r\n );\r\n\r\n const getSelectedRows = useCallback(() => api.getSelectedRows(), [api]);\r\n const getSelectedNodes = useCallback(() => api.getSelectedNodes(), [api]);\r\n const selectAll = useCallback(() => api.selectAll(), [api]);\r\n const deselectAll = useCallback(() => api.deselectAll(), [api]);\r\n\r\n return {\r\n selectedRowIds,\r\n selectedCount,\r\n getSelectedRows,\r\n getSelectedNodes,\r\n isRowSelected,\r\n selectAll,\r\n deselectAll,\r\n };\r\n}\r\n","// ─── useGridSort Hook ───\r\n// Sort model state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { SortModelItem } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridSortResult {\r\n /** Current sort model. */\r\n sortModel: SortModelItem[];\r\n /** Whether any sort is active. */\r\n isSorted: boolean;\r\n /** Set the sort model directly. */\r\n setSortModel: (model: SortModelItem[]) => void;\r\n /** Toggle sort on a column. */\r\n toggleSort: (colId: string, multiSort?: boolean) => void;\r\n /** Clear all sort. */\r\n clearSort: () => void;\r\n}\r\n\r\n/**\r\n * Access sort state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();\r\n * ```\r\n */\r\nexport function useGridSort(): GridSortResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getSortSnapshot = useCallback(() => engine.store.getState().sortModel, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const sortModel = useSyncExternalStore(\r\n subscribe,\r\n getSortSnapshot,\r\n getSortSnapshot,\r\n );\r\n\r\n const isSorted = sortModel.length > 0;\r\n\r\n const setSortModel = useCallback(\r\n (model: SortModelItem[]) => api.setSortModel(model),\r\n [api],\r\n );\r\n\r\n const toggleSort = useCallback(\r\n (colId: string, multiSort = false) => {\r\n engine.commandBus.dispatch('sort:toggle', { colId, multiSort });\r\n },\r\n [engine],\r\n );\r\n\r\n const clearSort = useCallback(() => api.setSortModel([]), [api]);\r\n\r\n return { sortModel, isSorted, setSortModel, toggleSort, clearSort };\r\n}\r\n","// ─── useGridFilter Hook ───\r\n// Filter model state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { FilterModel } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridFilterResult {\r\n /** Current filter model (keyed by column ID). */\r\n filterModel: Record<string, FilterModel>;\r\n /** Current quick filter text. */\r\n quickFilterText: string;\r\n /** Whether any filter is active. */\r\n isFiltered: boolean;\r\n /** Set the filter model. */\r\n setFilterModel: (model: Record<string, FilterModel>) => void;\r\n /** Set quick filter text. */\r\n setQuickFilter: (text: string) => void;\r\n /** Clear all filters. */\r\n clearFilters: () => void;\r\n}\r\n\r\n/**\r\n * Access filter state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();\r\n * ```\r\n */\r\nexport function useGridFilter(): GridFilterResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getFilterSnapshot = useCallback(() => engine.store.getState().filterModel, [engine]);\r\n const getQuickFilterSnapshot = useCallback(() => engine.store.getState().quickFilterText, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const filterModel = useSyncExternalStore(\r\n subscribe,\r\n getFilterSnapshot,\r\n getFilterSnapshot,\r\n );\r\n\r\n const quickFilterText = useSyncExternalStore(\r\n subscribe,\r\n getQuickFilterSnapshot,\r\n getQuickFilterSnapshot,\r\n );\r\n\r\n const isFiltered =\r\n Object.keys(filterModel).length > 0 || quickFilterText.length > 0;\r\n\r\n const setFilterModel = useCallback(\r\n (model: Record<string, FilterModel>) => api.setFilterModel(model),\r\n [api],\r\n );\r\n\r\n const setQuickFilter = useCallback(\r\n (text: string) => api.setQuickFilter(text),\r\n [api],\r\n );\r\n\r\n const clearFilters = useCallback(() => {\r\n api.setFilterModel({});\r\n api.setQuickFilter('');\r\n }, [api]);\r\n\r\n return {\r\n filterModel,\r\n quickFilterText,\r\n isFiltered,\r\n setFilterModel,\r\n setQuickFilter,\r\n clearFilters,\r\n };\r\n}\r\n","// ─── useGridPagination Hook ───\r\n// Pagination state and navigation actions.\r\n\r\nimport { useSyncExternalStore, useCallback, useMemo } from 'react';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridPaginationResult {\r\n /** Current page (0-indexed). */\r\n currentPage: number;\r\n /** Total number of pages. */\r\n totalPages: number;\r\n /** Rows per page. */\r\n pageSize: number;\r\n /** Total row count (after filtering). */\r\n totalRows: number;\r\n /** Is there a next page? */\r\n hasNextPage: boolean;\r\n /** Is there a previous page? */\r\n hasPreviousPage: boolean;\r\n /** Go to a specific page. */\r\n goToPage: (page: number) => void;\r\n /** Go to next page. */\r\n nextPage: () => void;\r\n /** Go to previous page. */\r\n previousPage: () => void;\r\n /** Go to first page. */\r\n firstPage: () => void;\r\n /** Go to last page. */\r\n lastPage: () => void;\r\n}\r\n\r\n/**\r\n * Access pagination state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { currentPage, totalPages, nextPage, previousPage } = useGridPagination();\r\n * ```\r\n */\r\nexport function useGridPagination(): GridPaginationResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getPaginationSnapshot = useCallback(() => engine.store.getState().pagination, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const paginationState = useSyncExternalStore(\r\n subscribe,\r\n getPaginationSnapshot,\r\n getPaginationSnapshot,\r\n );\r\n\r\n const { currentPage, pageSize, totalRows } = paginationState;\r\n const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));\r\n const hasNextPage = currentPage < totalPages - 1;\r\n const hasPreviousPage = currentPage > 0;\r\n\r\n const goToPage = useCallback(\r\n (page: number) => api.paginationGoToPage(page),\r\n [api],\r\n );\r\n\r\n const nextPage = useCallback(() => {\r\n if (hasNextPage) api.paginationGoToPage(currentPage + 1);\r\n }, [api, currentPage, hasNextPage]);\r\n\r\n const previousPage = useCallback(() => {\r\n if (hasPreviousPage) api.paginationGoToPage(currentPage - 1);\r\n }, [api, currentPage, hasPreviousPage]);\r\n\r\n const firstPage = useCallback(() => api.paginationGoToPage(0), [api]);\r\n\r\n const lastPage = useCallback(\r\n () => api.paginationGoToPage(totalPages - 1),\r\n [api, totalPages],\r\n );\r\n\r\n return useMemo(\r\n () => ({\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n }),\r\n [\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n ],\r\n );\r\n}\r\n","// ─── useGridEvent Hook ───\n// Subscribe to typed grid events.\n\nimport { useEffect, useRef } from 'react';\nimport type { GridEventMap } from '@gridstorm/core';\nimport { useGridContext } from '../context';\n\n/**\n * Subscribe to a specific grid event.\n * Handler ref prevents stale closures without re-subscribing.\n *\n * @example\n * ```tsx\n * useGridEvent('cell:clicked', (event) => {\n * console.log('Clicked cell:', event.colId, event.value);\n * });\n * ```\n */\nexport function useGridEvent<\n TData = any,\n K extends keyof GridEventMap<TData> = any,\n>(\n event: K,\n handler: (payload: GridEventMap<TData>[K]) => void,\n): void {\n const { engine } = useGridContext<TData>();\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const unsub = engine.eventBus.on(event as any, (payload: any) => {\n handlerRef.current(payload);\n });\n return unsub;\n }, [engine, event]);\n}\n","// ─── useGridColumn Hook ───\r\n// Column state and manipulation actions.\r\n\r\nimport { useSyncExternalStore, useCallback, useMemo } from 'react';\r\nimport type { ColumnState, PinnedPosition } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridColumnResult {\r\n /** All columns (including hidden). */\r\n allColumns: ColumnState[];\r\n /** Only visible columns. */\r\n visibleColumns: ColumnState[];\r\n /** Set a column's visibility. */\r\n setColumnVisible: (colId: string, visible: boolean) => void;\r\n /** Set a column's width. */\r\n setColumnWidth: (colId: string, width: number) => void;\r\n /** Move a column to a new index. */\r\n moveColumn: (colId: string, toIndex: number) => void;\r\n /** Pin a column. */\r\n setColumnPinned: (colId: string, pinned: PinnedPosition) => void;\r\n /** Get a single column by ID. */\r\n getColumn: (colId: string) => ColumnState | undefined;\r\n}\r\n\r\n/**\r\n * Access column state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { visibleColumns, setColumnVisible, setColumnWidth } = useGridColumn();\r\n * ```\r\n */\r\nexport function useGridColumn(): GridColumnResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getColumnsSnapshot = useCallback(() => engine.store.getState().columns, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const allColumns = useSyncExternalStore(\r\n subscribe,\r\n getColumnsSnapshot,\r\n getColumnsSnapshot,\r\n );\r\n\r\n const visibleColumns = useMemo(\r\n () => allColumns.filter((c) => !c.hide),\r\n [allColumns],\r\n );\r\n\r\n const setColumnVisible = useCallback(\r\n (colId: string, visible: boolean) => api.setColumnVisible(colId, visible),\r\n [api],\r\n );\r\n\r\n const setColumnWidth = useCallback(\r\n (colId: string, width: number) => api.setColumnWidth(colId, width),\r\n [api],\r\n );\r\n\r\n const moveColumn = useCallback(\r\n (colId: string, toIndex: number) => api.moveColumn(colId, toIndex),\r\n [api],\r\n );\r\n\r\n const setColumnPinned = useCallback(\r\n (colId: string, pinned: PinnedPosition) =>\r\n api.setColumnPinned(colId, pinned),\r\n [api],\r\n );\r\n\r\n const getColumn = useCallback(\r\n (colId: string) => api.getColumn(colId),\r\n [api],\r\n );\r\n\r\n return {\r\n allColumns,\r\n visibleColumns,\r\n setColumnVisible,\r\n setColumnWidth,\r\n moveColumn,\r\n setColumnPinned,\r\n getColumn,\r\n };\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/renderers/ReactCellRenderer.ts","../src/renderers/ReactHeaderRenderer.ts","../src/portals/CellRendererPortal.tsx","../src/portals/CellEditorPortal.tsx","../src/portals/ContextMenuPortal.tsx","../src/portals/PortalManager.tsx","../src/ErrorBoundary.tsx","../src/GridStorm.tsx","../src/hooks/useGridApi.ts","../src/hooks/useGridState.ts","../src/hooks/useGridSelection.ts","../src/hooks/useGridSort.ts","../src/hooks/useGridFilter.ts","../src/hooks/useGridPagination.ts","../src/hooks/useGridEvent.ts","../src/hooks/useGridColumn.ts"],"names":["createContext","useContext","Component","jsx","memo","useState","useRef","useCallback","useEffect","getValueFromData","useSyncExternalStore","jsxs","Fragment","createPortal","createGrid","useMemo","DomRenderer"],"mappings":";;;;;;;;;AAaO,IAAM,WAAA,GAAcA,oBAAuC,IAAI;AAM/D,SAAS,cAAA,GAAuD;AACrE,EAAA,MAAM,GAAA,GAAMC,iBAAW,WAAW,CAAA;AAClC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;;;AClBO,IAAM,mBAAA,mBAAsB,MAAA,CAAO,GAAA,CAAI,6BAA6B,CAAA;AAgBpE,SAAS,kBACdC,UAAAA,EACK;AAGL,EAAA,MAAM,KAAK,MAAM,EAAA;AACjB,EAAC,EAAA,CAAW,mBAAmB,CAAA,GAAIA,UAAAA;AACnC,EAAA,OAAO,EAAA;AACT;AAGO,SAAS,oBAAoB,EAAA,EAAsB;AACxD,EAAA,OAAO,OAAO,EAAA,KAAO,UAAA,IAAc,mBAAA,IAAwB,EAAA;AAC7D;AAGO,SAAS,sBACd,EAAA,EACyC;AACzC,EAAA,IAAI,mBAAA,CAAoB,EAAE,CAAA,EAAG;AAC3B,IAAA,OAAQ,GAAW,mBAAmB,CAAA;AAAA,EACxC;AACA,EAAA,OAAO,IAAA;AACT;;;AC1CO,IAAM,qBAAA,mBAAwB,MAAA,CAAO,GAAA,CAAI,+BAA+B,CAAA;AAkBxE,SAAS,oBACdA,UAAAA,EACK;AACL,EAAA,MAAM,KAAK,MAAM,EAAA;AACjB,EAAC,EAAA,CAAW,qBAAqB,CAAA,GAAIA,UAAAA;AACrC,EAAA,OAAO,EAAA;AACT;AAGO,SAAS,sBAAsB,EAAA,EAAsB;AAC1D,EAAA,OAAO,OAAO,EAAA,KAAO,UAAA,IAAc,qBAAA,IAA0B,EAAA;AAC/D;AAGO,SAAS,wBACd,EAAA,EACmC;AACnC,EAAA,IAAI,qBAAA,CAAsB,EAAE,CAAA,EAAG;AAC7B,IAAA,OAAQ,GAAW,qBAAqB,CAAA;AAAA,EAC1C;AACA,EAAA,OAAO,IAAA;AACT;AChCA,SAAS,wBACP,KAAA,EACA;AACA,EAAA,MAAM,EAAE,SAAA,EAAAA,UAAAA,EAAW,aAAA,EAAc,GAAI,KAAA;AACrC,EAAA,uBAAOC,cAAA,CAACD,UAAAA,EAAA,EAAW,GAAG,aAAA,EAAe,CAAA;AACvC;AAGO,IAAM,kBAAA,GAAqBE,UAAA;AAAA,EAChC,uBAAA;AAAA,EACA,CAAC,MAAM,IAAA,KACL,IAAA,CAAK,gBAAgB,IAAA,CAAK,WAAA,IAC1B,IAAA,CAAK,aAAA,CAAc,KAAA,KAAU,IAAA,CAAK,cAAc,KAAA,IAChD,IAAA,CAAK,aAAA,CAAc,QAAA,KAAa,IAAA,CAAK,aAAA,CAAc,YACnD,IAAA,CAAK,aAAA,CAAc,KAAA,KAAU,IAAA,CAAK,aAAA,CAAc;AACpD,CAAA;ACXO,SAAS,iBAA8B,KAAA,EAAqC;AACjF,EAAA,MAAM,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,eAAA,EAAiB,YAAA,EAAc,cAAa,GAAI,KAAA;AAC5E,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAS,GAAI,KAAA;AAC9B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,cAAA,CAAS,QAAQ,KAAK,CAAA;AAChD,EAAA,MAAM,YAAA,GAAeC,aAAuB,IAAI,CAAA;AAEhD,EAAA,MAAM,aAAA,GAAgBC,iBAAA;AAAA,IACpB,CAAC,QAAA,KAAkB;AACjB,MAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,MAAA,MAAA,CAAO,WAAW,QAAA,CAAS,kBAAA,EAAoB,EAAE,KAAA,EAAO,UAAU,CAAA;AAAA,IACpE,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,WAAA,GAAcA,iBAAA;AAAA,IAClB,CAAC,MAAA,KAAqB;AACpB,MAAA,GAAA,CAAI,YAAY,MAAM,CAAA;AAAA,IACxB,CAAA;AAAA,IACA,CAAC,GAAG;AAAA,GACN;AAGA,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,qBAAA,CAAsB,MAAM;AAC1B,MAAA,MAAM,KAAK,YAAA,CAAa,OAAA;AACxB,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,MAAM,YAAY,EAAA,CAAG,aAAA;AAAA,QACnB;AAAA,OACF;AACA,MAAA,SAAA,EAAW,KAAA,EAAM;AAAA,IACnB,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,CACnB,QAAA,EAAS,CACT,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,KAAU,OAAA,CAAQ,KAAK,CAAA;AAEhD,EAAA,MAAM,IAAA,GAAO,OAAO,KAAA,CAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,QAAQ,KAAK,CAAA;AAG/D,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,GAAM,YAAA,CAAa,GAAA;AACxC,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,GAAO,YAAA,CAAa,IAAA;AAE1C,EAAA,uBACEL,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,YAAA;AAAA,MACL,SAAA,EAAU,kBAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,GAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAO,QAAA,CAAS,KAAA;AAAA,QAChB,QAAQ,QAAA,CAAS,MAAA;AAAA,QACjB,MAAA,EAAQ,EAAA;AAAA,QACR,SAAA,EAAW,YAAA;AAAA,QACX,UAAA,EAAY,uCAAA;AAAA,QACZ,MAAA,EAAQ;AAAA,OACV;AAAA,MAEA,QAAA,kBAAAA,cAAAA;AAAA,QAAC,eAAA;AAAA,QAAA;AAAA,UACC,KAAA;AAAA,UACA,MAAM,IAAA,EAAM,IAAA;AAAA,UACZ,OAAO,OAAA,CAAQ,KAAA;AAAA,UACf,OAAO,OAAA,CAAQ,KAAA;AAAA,UACf,MAAA;AAAA,UACA,YAAA;AAAA,UACA,aAAA;AAAA,UACA,WAAA;AAAA,UACA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;AC5EO,SAAS,kBACd,KAAA,EACA;AACA,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,SAAA,EAAW,SAAA,EAAAD,YAAU,GAAI,KAAA;AACvC,EAAA,MAAM,GAAA,GAAMI,aAAuB,IAAI,CAAA;AAGvC,EAAAE,gBAAU,MAAM;AACd,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAkB;AACjC,MAAA,IAAI,GAAA,CAAI,WAAW,CAAC,GAAA,CAAI,QAAQ,QAAA,CAAS,CAAA,CAAE,MAAc,CAAA,EAAG;AAC1D,QAAA,SAAA,CAAU,SAAA,EAAU;AAAA,MACtB;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,EAAA,GAAK,WAAW,MAAM;AAC1B,MAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,OAAO,CAAA;AAAA,IAChD,GAAG,CAAC,CAAA;AACJ,IAAA,OAAO,MAAM;AACX,MAAA,YAAA,CAAa,EAAE,CAAA;AACf,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,OAAO,CAAA;AAAA,IACnD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAGd,EAAAA,gBAAU,MAAM;AACd,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAqB;AACpC,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,SAAA,CAAU,SAAA,EAAU;AAAA,IAC9C,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,OAAO,CAAA;AAC5C,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,OAAO,CAAA;AAAA,EAC9D,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,uBACEL,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAU,wBAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,GAAA,EAAK,CAAA;AAAA,QACL,IAAA,EAAM,CAAA;AAAA,QACN,MAAA,EAAQ,GAAA;AAAA,QACR,QAAA,EAAU;AAAA,OACZ;AAAA,MAEA,QAAA,kBAAAA,cAAAA,CAACD,UAAAA,EAAA,EAAW,GAAG,SAAA,EAAW;AAAA;AAAA,GAC5B;AAEJ;ACXA,IAAM,YAAA,GAAe,gBAAA;AA+BrB,SAAS,mBAAmB,IAAA,EAAgC;AAE1D,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC7C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC7B,IAAA,IAAI,KAAA,CAAM,YAAA,CAAa,YAAY,CAAA,EAAG;AACpC,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AAC5C,EAAA,OAAA,CAAQ,YAAA,CAAa,cAAc,EAAE,CAAA;AACrC,EAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,UAAA;AACxB,EAAA,IAAA,CAAK,YAAY,OAAO,CAAA;AACxB,EAAA,OAAO,OAAA;AACT;AAEO,SAAS,cAA2B,KAAA,EAAkC;AAC3E,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAK,OAAA,EAAS,WAAA,EAAa,sBAAqB,GAAI,KAAA;AAGpE,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIG,cAAAA;AAAA,IACpC,0BAAU,GAAA;AAAI,GAChB;AACA,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIA,cAAAA;AAAA,IACxC,0BAAU,GAAA;AAAI,GAChB;AACA,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,eAAmC,IAAI,CAAA;AAC/E,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAyC,IAAI,CAAA;AAGnF,EAAA,MAAM,UAAA,GAAaC,aAAO,OAAO,CAAA;AACjC,EAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,EAAA,MAAM,SAAA,GAAYA,aAAO,MAAM,CAAA;AAC/B,EAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAGpB,EAAA,MAAM,WAAA,GAAcA,aAAO,KAAK,CAAA;AAGhC,EAAA,MAAM,oBAAA,GAAuBA,YAAAA,iBAAO,IAAI,GAAA,EAAkB,CAAA;AAC1D,EAAA,MAAM,sBAAA,GAAyBA,YAAAA,iBAAO,IAAI,GAAA,EAAkB,CAAA;AAC5D,EAAA,MAAM,cAAA,GAAiBA,YAAAA,iBAAO,IAAI,GAAA,EAAqC,CAAA;AAEvE,EAAAE,gBAAU,MAAM;AACd,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAiB;AACrC,IAAA,MAAM,SAAA,uBAAgB,GAAA,EAAiB;AACvC,IAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoC;AAE1D,IAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,MAAA,MAAM,KAAA,GAAS,GAAA,CAAY,KAAA,IAAS,GAAA,CAAI,KAAA,IAAS,EAAA;AACjD,MAAA,IAAI,GAAA,CAAI,YAAA,IAAgB,mBAAA,CAAoB,GAAA,CAAI,YAAY,CAAA,EAAG;AAC7D,QAAA,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,qBAAA,CAAsB,GAAA,CAAI,YAAY,CAAC,CAAA;AAAA,MAC5D;AACA,MAAA,IAAI,GAAA,CAAI,cAAA,IAAkB,qBAAA,CAAsB,GAAA,CAAI,cAAc,CAAA,EAAG;AACnE,QAAA,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,uBAAA,CAAwB,GAAA,CAAI,cAAc,CAAC,CAAA;AAAA,MAClE;AACA,MAAA,IAAI,IAAI,mBAAA,EAAqB;AAC3B,QAAA,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,GAAA,CAAI,mBAAmB,CAAA;AAAA,MAC9C;AAAA,IACF;AAEA,IAAA,oBAAA,CAAqB,OAAA,GAAU,OAAA;AAC/B,IAAA,sBAAA,CAAuB,OAAA,GAAU,SAAA;AACjC,IAAA,cAAA,CAAe,OAAA,GAAU,SAAA;AAAA,EAC3B,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAGZ,EAAA,MAAM,cAAA,GAAiBD,iBAAAA;AAAA,IACrB,CAAC,IAAA,EAAsB,GAAA,EAAkB,QAAA,KAA+C;AACtF,MAAA,MAAM,SAAS,GAAA,CAAI,WAAA;AACnB,MAAA,IAAI,KAAA;AACJ,MAAA,IAAI,OAAO,WAAA,EAAa;AACtB,QAAA,KAAA,GAAQ,OAAO,WAAA,CAAY;AAAA,UACzB,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,IAAA;AAAA,UACA,MAAA;AAAA,UACA,OAAO,GAAA,CAAI;AAAA,SACZ,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,KAAA,GAAQE,qBAAA,CAAiB,IAAA,CAAK,IAAA,EAAM,GAAA,CAAI,KAAK,CAAA;AAAA,MAC/C;AAEA,MAAA,IAAI,cAAA,GAAiB,KAAA,IAAS,IAAA,GAAO,MAAA,CAAO,KAAK,CAAA,GAAI,EAAA;AACrD,MAAA,IAAI,OAAO,cAAA,EAAgB;AACzB,QAAA,cAAA,GAAiB,MAAA,CAAO,eAAe,EAAE,KAAA,EAAO,MAAM,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,CAAA;AAAA,MACjF;AAEA,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,cAAA;AAAA,QACA,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,IAAA;AAAA,QACA,MAAA;AAAA,QACA,OAAO,GAAA,CAAI,KAAA;AAAA,QACX,QAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAAA,IACA,CAAC,GAAG;AAAA,GACN;AAGA,EAAA,MAAM,eAAA,GAAkBF,kBAAY,MAAM;AACxC,IAAA,IAAI,CAAC,WAAA,IAAe,WAAA,CAAY,OAAA,EAAS;AACzC,IAAA,WAAA,CAAY,OAAA,GAAU,IAAA;AAEtB,IAAA,IAAI;AACF,MAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,aAAA,CAAc,UAAU,CAAA;AAC1D,MAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,OAAA,CAAQ,KAAA,CAAM,QAAA,EAAS;AAC/C,MAAA,MAAM,gBAAgB,oBAAA,CAAqB,OAAA;AAC3C,MAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAE9B,MAAA,MAAM,UAAA,uBAAiB,GAAA,EAAoC;AAC3D,MAAA,MAAM,WAAA,GAAc,aAAA,CAAc,gBAAA,CAA8B,SAAS,CAAA;AAGzE,MAAA,MAAM,aAAA,uBAAoB,GAAA,EAAoB;AAC9C,MAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,eAAA,CAAgB,QAAQ,CAAA,EAAA,EAAK;AACrD,QAAA,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,eAAA,CAAgB,CAAC,GAAI,CAAC,CAAA;AAAA,MAChD;AACA,MAAA,MAAM,SAAA,uBAAgB,GAAA,EAAyB;AAC/C,MAAA,KAAA,MAAW,GAAA,IAAO,MAAM,OAAA,EAAS;AAC/B,QAAA,SAAA,CAAU,GAAA,CAAI,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AAAA,MAC9B;AAEA,MAAA,KAAA,MAAW,SAAS,WAAA,EAAa;AAC/B,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,YAAA,CAAa,aAAa,CAAA;AAC9C,QAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,QAAA,MAAM,IAAA,GAAO,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACrC,QAAA,IAAI,CAAC,IAAA,EAAM;AAEX,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,gBAAA,CAA8B,UAAU,CAAA;AAC5D,QAAA,KAAA,MAAW,UAAU,KAAA,EAAO;AAC1B,UAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,YAAA,CAAa,aAAa,CAAA;AAC/C,UAAA,IAAI,CAAC,KAAA,IAAS,CAAC,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,EAAG;AAEzC,UAAA,MAAM,GAAA,GAAM,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA;AAC7B,UAAA,MAAML,UAAAA,GAAY,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AACzC,UAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AACpC,UAAA,IAAI,CAAC,QAAA,EAAU;AAEf,UAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,IAAK,CAAA,CAAA;AAC7C,UAAA,MAAM,aAAA,GAAgB,cAAA,CAAe,IAAA,EAAM,QAAA,EAAU,QAAQ,CAAA;AAK7D,UAAA,MAAM,OAAA,GAAU,mBAAmB,MAAM,CAAA;AAEzC,UAAA,UAAA,CAAW,IAAI,GAAA,EAAK;AAAA,YAClB,GAAA;AAAA,YACA,SAAA,EAAW,OAAA;AAAA,YACX,SAAA,EAAWA,UAAAA;AAAA,YACX,KAAA,EAAO,aAAA;AAAA,YACP,aAAa,IAAA,CAAK;AAAA,WACnB,CAAA;AAAA,QACH;AAAA,MACF;AAEA,MAAA,cAAA,CAAe,UAAU,CAAA;AAAA,IAC3B,CAAA,SAAE;AACA,MAAA,WAAA,CAAY,OAAA,GAAU,KAAA;AAAA,IACxB;AAAA,EACF,CAAA,EAAG,CAAC,WAAA,EAAa,cAAc,CAAC,CAAA;AAGhC,EAAA,MAAM,eAAA,GAAkBK,kBAAY,MAAM;AACxC,IAAA,IAAI,CAAC,WAAA,EAAa;AAClB,IAAA,MAAM,kBAAkB,sBAAA,CAAuB,OAAA;AAC/C,IAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAEhC,IAAA,MAAM,eAAA,GAAkB,WAAA,CAAY,aAAA,CAAc,YAAY,CAAA;AAC9D,IAAA,IAAI,CAAC,eAAA,EAAiB;AAEtB,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,OAAA,CAAQ,KAAA,CAAM,QAAA,EAAS;AAC/C,IAAA,MAAM,UAAA,uBAAiB,GAAA,EAA+B;AAEtD,IAAA,MAAM,WAAA,GAAc,eAAA,CAAgB,gBAAA,CAA8B,iBAAiB,CAAA;AACnF,IAAA,KAAA,MAAW,UAAU,WAAA,EAAa;AAChC,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,YAAA,CAAa,aAAa,CAAA;AAC/C,MAAA,IAAI,CAAC,KAAA,IAAS,CAAC,eAAA,CAAgB,GAAA,CAAI,KAAK,CAAA,EAAG;AAE3C,MAAA,MAAML,UAAAA,GAAY,eAAA,CAAgB,GAAA,CAAI,KAAK,CAAA;AAC3C,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AAC5D,MAAA,IAAI,CAAC,QAAA,EAAU;AAEf,MAAA,MAAM,QAAA,GAAW,MAAM,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AAE9D,MAAA,MAAM,WAAA,GAA0C;AAAA,QAC9C,QAAQ,QAAA,CAAS,WAAA;AAAA,QACjB,KAAA;AAAA,QACA,aAAa,QAAA,CAAS,UAAA;AAAA,QACtB,aAAA,EAAe,UAAU,IAAA,IAAQ,IAAA;AAAA,QACjC,WAAW,QAAA,CAAS,SAAA;AAAA,QACpB,GAAA;AAAA,QACA,eAAA,EAAiB,CAAC,SAAA,KAAuB;AACvC,UAAA,SAAA,CAAU,QAAQ,UAAA,CAAW,QAAA,CAAS,eAAe,EAAE,KAAA,EAAO,WAAW,CAAA;AAAA,QAC3E;AAAA,OACF;AAGA,MAAA,MAAM,OAAA,GAAU,mBAAmB,MAAM,CAAA;AAEzC,MAAA,UAAA,CAAW,IAAI,KAAA,EAAO;AAAA,QACpB,GAAA,EAAK,KAAA;AAAA,QACL,SAAA,EAAW,OAAA;AAAA,QACX,yBAASC,cAAAA,CAACD,UAAAA,EAAA,EAAW,GAAG,WAAA,EAAa;AAAA,OACtC,CAAA;AAAA,IACH;AAEA,IAAA,gBAAA,CAAiB,UAAU,CAAA;AAAA,EAC7B,CAAA,EAAG,CAAC,WAAA,EAAa,GAAG,CAAC,CAAA;AAGrB,EAAAM,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,EAAa;AAClB,IAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,aAAA,CAAc,UAAU,CAAA;AAC1D,IAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,IAAA,MAAM,QAAA,GAAW,IAAI,gBAAA,CAAiB,MAAM;AAE1C,MAAA,eAAA,EAAgB;AAAA,IAClB,CAAC,CAAA;AAED,IAAA,QAAA,CAAS,OAAA,CAAQ,aAAA,EAAe,EAAE,SAAA,EAAW,MAAM,CAAA;AAGnD,IAAA,eAAA,EAAgB;AAChB,IAAA,eAAA,EAAgB;AAEhB,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,WAAA,EAAa,eAAA,EAAiB,eAAe,CAAC,CAAA;AAGlD,EAAA,MAAM,kBAAA,GAAqBD,kBAAY,MAAM,MAAA,CAAO,MAAM,UAAA,EAAW,EAAG,CAAC,MAAM,CAAC,CAAA;AAChF,EAAA,MAAM,cAAA,GAAiBA,iBAAAA,CAAY,CAAC,EAAA,KAAmB,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,EAAE,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAE3F,EAAA,MAAM,YAAA,GAAeG,0BAAA;AAAA,IACnB,cAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAAF,gBAAU,MAAM;AACd,IAAA,eAAA,EAAgB;AAAA,EAClB,CAAA,EAAG,CAAC,YAAA,EAAc,eAAe,CAAC,CAAA;AAGlC,EAAAA,gBAAU,MAAM;AACd,IAAA,MAAM,MAAA,GAAS;AAAA,MACb,MAAA,CAAO,QAAA,CAAS,EAAA,CAAG,qBAAA,EAAuB,MAAM;AAE9C,QAAA,qBAAA,CAAsB,MAAM,iBAAiB,CAAA;AAAA,MAC/C,CAAC,CAAA;AAAA,MACD,MAAA,CAAO,QAAA,CAAS,EAAA,CAAG,iBAAA,EAAmB,MAAM;AAC1C,QAAA,qBAAA,CAAsB,MAAM,iBAAiB,CAAA;AAAA,MAC/C,CAAC;AAAA,KACH;AACA,IAAA,OAAO,MAAM,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,KAAM,GAAG,CAAA;AAAA,EACxC,CAAA,EAAG,CAAC,MAAA,EAAQ,eAAe,CAAC,CAAA;AAG5B,EAAAA,gBAAU,MAAM;AACd,IAAA,MAAM,UAAA,GAAa,OAAO,QAAA,CAAS,EAAA;AAAA,MACjC,qBAAA;AAAA,MACA,CAAC,KAAA,KAAe;AACd,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,KAAA;AACxB,QAAA,MAAM,eAAA,GAAkB,cAAA,CAAe,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AACxD,QAAA,IAAI,CAAC,eAAA,IAAmB,CAAC,WAAA,EAAa;AAGtC,QAAA,MAAM,SAAS,WAAA,CAAY,aAAA;AAAA,UACzB,CAAA,qBAAA,EAAwB,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,EAAE,CAAC,CAAA,yBAAA,EAA4B,GAAA,CAAI,MAAA,CAAO,KAAK,CAAC,CAAA,EAAA;AAAA,SAC1F;AACA,QAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,QAAA,EAAS;AACpC,QAAA,MAAM,UAAU,KAAA,CAAM,OAAA;AACtB,QAAA,IAAI,CAAC,OAAA,EAAS;AAEd,QAAA,eAAA,CAAgB;AAAA,UACd,OAAA;AAAA,UACA,WAAA,EAAa,MAAA;AAAA,UACb,QAAA,EAAU,OAAO,qBAAA;AAAsB,SACxC,CAAA;AAAA,MACH;AAAA,KACF;AAEA,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,QAAA,CAAS,EAAA,CAAG,uBAAuB,MAAM;AAChE,MAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,IACtB,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,UAAA,EAAW;AACX,MAAA,SAAA,EAAU;AAAA,IACZ,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAW,CAAC,CAAA;AAGxB,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,IAAe,CAAC,oBAAA,EAAsB;AAE3C,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAkB;AACjC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,OAAA,CAAqB,UAAU,CAAA;AACrD,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAqB,SAAS,CAAA;AACnD,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,KAAA,EAAO;AAEvB,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,YAAA,CAAa,aAAa,CAAA;AAC9C,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,YAAA,CAAa,aAAa,CAAA;AAC/C,MAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,EAAO;AAEtB,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,QAAA,EAAS;AACpC,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACrC,MAAA,IAAI,CAAC,IAAA,EAAM;AAEX,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AAC5D,MAAA,MAAM,QAAQ,QAAA,GACVC,qBAAA,CAAiB,KAAK,IAAA,EAAM,QAAA,CAAS,KAAK,CAAA,GAC1C,MAAA;AAEJ,MAAA,MAAM,QAAA,GAAW,YAAY,qBAAA,EAAsB;AACnD,MAAA,MAAM,QAAA,GAAW,KAAA,CAAM,eAAA,CAAgB,OAAA,CAAQ,KAAK,CAAA;AAEpD,MAAA,cAAA,CAAe;AAAA,QACb,CAAA,EAAG,CAAA,CAAE,OAAA,GAAU,QAAA,CAAS,IAAA;AAAA,QACxB,CAAA,EAAG,CAAA,CAAE,OAAA,GAAU,QAAA,CAAS,GAAA;AAAA,QACxB,SAAA,EAAW;AAAA,UACT,QAAA,EAAU,EAAE,QAAA,EAAU,KAAA,EAAM;AAAA,UAC5B,IAAA;AAAA,UACA,KAAA;AAAA,UACA,KAAA;AAAA,UACA,GAAA;AAAA,UACA,SAAA,EAAW,MAAM,cAAA,CAAe,IAAI;AAAA;AACtC,OACD,CAAA;AAAA,IACH,CAAA;AAEA,IAAA,WAAA,CAAY,gBAAA,CAAiB,eAAe,OAAO,CAAA;AACnD,IAAA,OAAO,MAAM,WAAA,CAAY,mBAAA,CAAoB,aAAA,EAAe,OAAO,CAAA;AAAA,EACrE,GAAG,CAAC,WAAA,EAAa,oBAAA,EAAsB,GAAA,EAAK,MAAM,CAAC,CAAA;AAGnD,EAAA,uBACEE,eAAA,CAAAC,mBAAA,EAAA,EAEG,QAAA,EAAA;AAAA,IAAA,KAAA,CAAM,IAAA,CAAK,WAAA,CAAY,MAAA,EAAQ,CAAA,CAAE,GAAA;AAAA,MAAI,CAAC,KAAA,KACrCC,qBAAA;AAAA,wBACEV,cAAAA;AAAA,UAAC,kBAAA;AAAA,UAAA;AAAA,YAEC,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,eAAe,KAAA,CAAM,KAAA;AAAA,YACrB,aAAa,KAAA,CAAM;AAAA,WAAA;AAAA,UAHd,KAAA,CAAM;AAAA,SAIb;AAAA,QACA,KAAA,CAAM,SAAA;AAAA,QACN,KAAA,CAAM;AAAA;AACR,KACF;AAAA,IAGC,KAAA,CAAM,IAAA,CAAK,aAAA,CAAc,MAAA,EAAQ,CAAA,CAAE,GAAA;AAAA,MAAI,CAAC,UACvCU,qBAAA,CAAa,KAAA,CAAM,SAAS,KAAA,CAAM,SAAA,EAAW,MAAM,GAAG;AAAA,KACxD;AAAA,IAGC,YAAA,IAAgB,gBAAgB,MAAM;AACrC,MAAA,MAAM,kBAAkB,cAAA,CAAe,OAAA,CAAQ,GAAA,CAAI,YAAA,CAAa,QAAQ,KAAK,CAAA;AAC7E,MAAA,IAAI,CAAC,iBAAiB,OAAO,IAAA;AAC7B,MAAA,MAAM,MAAA,GAAS,WAAW,OAAA,CAAQ,IAAA;AAAA,QAChC,CAAC,CAAA,KAAA,CAAQ,CAAA,CAAU,SAAS,CAAA,CAAE,KAAA,MAAW,aAAa,OAAA,CAAQ;AAAA,OAChE;AACA,MAAA,OAAOA,qBAAA;AAAA,wBACLV,cAAAA;AAAA,UAAC,gBAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,YAAA;AAAA,YACP,GAAA;AAAA,YACA,MAAA;AAAA,YACA,eAAA,EAAiB,eAAA;AAAA,YACjB,YAAA,EAAe,MAAA,EAAQ,gBAAA,IAAgD,EAAC;AAAA,YACxE,YAAA,EAAc,YAAY,qBAAA;AAAsB;AAAA,SAClD;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA,GAAG;AAAA,IAGF,WAAA,IAAe,wBAAwB,WAAA,IACtCU,qBAAA;AAAA,sBACEV,cAAAA;AAAA,QAAC,iBAAA;AAAA,QAAA;AAAA,UACC,GAAG,WAAA,CAAY,CAAA;AAAA,UACf,GAAG,WAAA,CAAY,CAAA;AAAA,UACf,WAAW,WAAA,CAAY,SAAA;AAAA,UACvB,SAAA,EAAW;AAAA;AAAA,OACb;AAAA,MACA,WAAA;AAAA,MACA;AAAA;AACF,GAAA,EACJ,CAAA;AAEJ;ACpdO,IAAM,iBAAA,GAAN,cAAgCD,eAAA,CAAkD;AAAA,EAAlF,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AACL,IAAA,IAAA,CAAA,KAAA,GAA4B,EAAE,QAAA,EAAU,KAAA,EAAO,KAAA,EAAO,IAAA,EAAK;AAAA,EAAA;AAAA,EAE3D,OAAO,yBAAyB,KAAA,EAAkC;AAChE,IAAA,OAAO,EAAE,QAAA,EAAU,IAAA,EAAM,KAAA,EAAM;AAAA,EACjC;AAAA,EAEA,iBAAA,CAAkB,OAAc,SAAA,EAA4B;AAC1D,IAAA,OAAA,CAAQ,KAAA,CAAM,8BAAA,EAAgC,KAAA,EAAO,SAAA,CAAU,cAAc,CAAA;AAAA,EAC/E;AAAA,EAEA,MAAA,GAAS;AACP,IAAA,IAAI,IAAA,CAAK,MAAM,QAAA,EAAU;AACvB,MAAA,IAAI,IAAA,CAAK,MAAM,QAAA,EAAU;AACvB,QAAA,OAAO,KAAK,KAAA,CAAM,QAAA;AAAA,MACpB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAK,KAAA,CAAM,QAAA;AAAA,EACpB;AACF;ACPA,SAAS,cAA2B,MAAA,EAAqD;AACvF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIG,eAAmC,IAAI,CAAA;AACnE,EAAA,MAAM,SAAA,GAAYC,aAAO,MAAM,CAAA;AAC/B,EAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAIpB,EAAA,MAAM,iBAAA,GAAoBA,aAAO,KAAK,CAAA;AACtC,EAAA,MAAM,iBAAA,GAAoBA,aAAO,KAAK,CAAA;AAGtC,EAAAE,gBAAU,MAAM;AACd,IAAA,MAAM,GAAA,GAAMM,eAAA,CAAW,SAAA,CAAU,OAAO,CAAA;AACxC,IAAA,SAAA,CAAU,GAAG,CAAA;AAGb,IAAA,iBAAA,CAAkB,OAAA,GAAU,KAAA;AAC5B,IAAA,iBAAA,CAAkB,OAAA,GAAU,KAAA;AAE5B,IAAA,OAAO,MAAM;AACX,MAAA,GAAA,CAAI,OAAA,EAAQ;AACZ,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,IAChB,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAAN,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,IAAI,CAAC,kBAAkB,OAAA,EAAS;AAC9B,MAAA,iBAAA,CAAkB,OAAA,GAAU,IAAA;AAC5B,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,MAAA,CAAO,OAAO,CAAA;AAAA,IACtC;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,CAAO,OAAA,EAAS,MAAM,CAAC,CAAA;AAG3B,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,IAAI,CAAC,kBAAkB,OAAA,EAAS;AAC9B,MAAA,iBAAA,CAAkB,OAAA,GAAU,IAAA;AAC5B,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,MAAA,CAAO,GAAA,CAAI,aAAA,CAAc,MAAA,CAAO,OAAO,CAAA;AAAA,IACzC;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,CAAO,OAAA,EAAS,MAAM,CAAC,CAAA;AAE3B,EAAA,OAAO,MAAA;AACT;AAIA,SAAS,eACP,YAAA,EACoB;AACpB,EAAA,OAAO,YAAA,CAAa,GAAA,CAAI,CAAC,GAAA,KAAQ;AAC/B,IAAA,MAAM,OAAA,GAAU,EAAE,GAAG,GAAA,EAAI;AAUzB,IAAA,OAAO,OAAA,CAAQ,mBAAA;AAEf,IAAA,OAAO,OAAA;AAAA,EACT,CAAC,CAAA;AACH;AAIO,SAAS,UAAuB,KAAA,EAA8B;AACnE,EAAA,MAAM;AAAA;AAAA,IAEJ,OAAA,EAAS,YAAA;AAAA,IACT,OAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,mBAAA;AAAA,IACA,eAAA;AAAA,IACA,eAAA;AAAA,IACA,YAAA;AAAA,IACA,QAAA;AAAA,IACA,mBAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA;AAAA,IAEA,SAAA,EAAW,mBAAA;AAAA,IACX,iBAAA;AAAA,IACA,WAAA,EAAa,qBAAA;AAAA,IACb,mBAAA;AAAA,IACA,cAAA,EAAgB,wBAAA;AAAA,IAChB,sBAAA;AAAA,IACA,WAAA,EAAa,qBAAA;AAAA,IACb,mBAAA;AAAA;AAAA,IAEA,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,YAAA;AAAA,IACA,oBAAA;AAAA,IACA,oBAAA;AAAA,IACA,mBAAA;AAAA,IACA,eAAA;AAAA;AAAA,IAEA,iBAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAA;AAAA,IACA,iBAAA;AAAA,IACA,mBAAA;AAAA,IACA,cAAA;AAAA,IACA,sBAAA;AAAA,IACA,gBAAA;AAAA,IACA,eAAA;AAAA;AAAA,IAEA,MAAA,GAAS,GAAA;AAAA,IACT,KAAA,GAAQ,MAAA;AAAA,IACR,cAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA;AAAA,GAEF,GAAI,KAAA;AAEJ,EAAA,MAAM,YAAA,GAAeF,aAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,WAAA,GAAcA,aAA2B,IAAI,CAAA;AACnD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAID,eAA6B,IAAI,CAAA;AAGvE,EAAA,MAAM,WAAA,GAAcU,aAAA;AAAA,IAClB,MAAM,eAAe,YAAY,CAAA;AAAA,IACjC,CAAC,YAAY;AAAA,GACf;AAGA,EAAA,MAAM,MAAA,GAASA,aAAA;AAAA,IACb,OAAO;AAAA,MACL,OAAA,EAAS,WAAA;AAAA,MACT,OAAA;AAAA,MACA,UAAA;AAAA,MACA,YAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,aAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA,gBAAA;AAAA,MACA,mBAAA;AAAA,MACA,eAAA;AAAA,MACA,eAAA;AAAA,MACA,YAAA;AAAA,MACA,QAAA;AAAA,MACA,mBAAA;AAAA,MACA,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA;AAAA;AAAA,IAGA,CAAC,WAAA,EAAa,OAAA,EAAS,YAAA,EAAc,QAAQ;AAAA,GAC/C;AAGA,EAAA,MAAM,MAAA,GAAS,cAAqB,MAAM,CAAA;AAG1C,EAAAP,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,CAAa,OAAA,IAAW,CAAC,MAAA,EAAQ;AAEtC,IAAA,MAAM,QAAA,GAAW,IAAIQ,uBAAA,CAAY;AAAA,MAC/B,WAAW,YAAA,CAAa,OAAA;AAAA,MACxB,MAAA;AAAA,MACA,iBAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,iBAAA;AAAA,MACA,mBAAA;AAAA,MACA,cAAA;AAAA,MACA,sBAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,QAAA,CAAS,KAAA,EAAM;AACf,IAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AAGtB,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,OAAA,CAAQ,aAAA,CAA2B,UAAU,CAAA;AACvE,IAAA,cAAA,CAAe,IAAI,CAAA;AAOnB,IAAA,qBAAA,CAAsB,MAAM;AAC1B,MAAA,MAAA,CAAO,SAAS,IAAA,CAAK,YAAA,EAAc,EAAE,GAAA,EAAK,MAAA,CAAO,KAAK,CAAA;AAAA,IACxD,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,OAAA,EAAQ;AACjB,MAAA,WAAA,CAAY,OAAA,GAAU,IAAA;AACtB,MAAA,cAAA,CAAe,IAAI,CAAA;AAAA,IACrB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,MAAM,yBAAyBV,YAAAA,CAAO;AAAA,IACpC,iBAAA;AAAA,IACA,mBAAA;AAAA,IACA,sBAAA;AAAA,IACA;AAAA,GACD,CAAA;AACD,EAAA,sBAAA,CAAuB,OAAA,GAAU;AAAA,IAC/B,iBAAA;AAAA,IACA,mBAAA;AAAA,IACA,sBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAAE,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,UAAA,CAAW,GAAA,CAAI,CAAC,GAAA,KAAQ;AAC9C,MAAA,MAAM,MAAM,sBAAA,CAAuB,OAAA;AAGnC,MAAA,IAAI,GAAA,CAAI,WAAA,KAAgB,aAAA,IAAiB,GAAA,CAAI,iBAAA,EAAmB;AAG9D,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,GAAA,CAAI,WAAA,KAAgB,kBAAA,IAAsB,GAAA,CAAI,sBAAA,EAAwB;AAExE,QAAA;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,QAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,mBAAA,KAAwB,UAAa,MAAA,EAAQ;AAC/C,MAAA,MAAA,CAAO,GAAA,CAAI,aAAa,mBAAmB,CAAA;AAAA,IAC7C;AAAA,EACF,CAAA,EAAG,CAAC,mBAAA,EAAqB,MAAM,CAAC,CAAA;AAEhC,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,qBAAA,KAA0B,UAAa,MAAA,EAAQ;AACjD,MAAA,MAAA,CAAO,GAAA,CAAI,eAAe,qBAA4B,CAAA;AAAA,IACxD;AAAA,EACF,CAAA,EAAG,CAAC,qBAAA,EAAuB,MAAM,CAAC,CAAA;AAElC,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,qBAAA,KAA0B,UAAa,MAAA,EAAQ;AACjD,MAAA,MAAA,CAAO,GAAA,CAAI,mBAAmB,qBAAqB,CAAA;AAAA,IACrD;AAAA,EACF,CAAA,EAAG,CAAC,qBAAA,EAAuB,MAAM,CAAC,CAAA;AAElC,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,wBAAA,KAA6B,UAAa,MAAA,EAAQ;AACpD,MAAA,MAAA,CAAO,UAAA,CAAW,SAAS,eAAA,EAAiB;AAAA,QAC1C,cAAA,EAAgB,IAAI,GAAA,CAAI,wBAAwB;AAAA,OACjD,CAAA;AAAA,IACH;AAAA,EACF,CAAA,EAAG,CAAC,wBAAA,EAA0B,MAAM,CAAC,CAAA;AAGrC,EAAA,MAAM,oBAAoBF,YAAAA,CAAO;AAAA,IAC/B,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,YAAA;AAAA,IACA,oBAAA;AAAA,IACA,oBAAA;AAAA,IACA,mBAAA;AAAA,IACA;AAAA,GACD,CAAA;AACD,EAAA,iBAAA,CAAkB,OAAA,GAAU;AAAA,IAC1B,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,YAAA;AAAA,IACA,oBAAA;AAAA,IACA,oBAAA;AAAA,IACA,mBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAAE,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAM,KAAK,MAAA,CAAO,QAAA;AAClB,IAAA,MAAM,GAAA,GAAM,MAAM,iBAAA,CAAkB,OAAA;AAEpC,IAAA,MAAM,MAAA,GAAS;AAAA,MACb,EAAA,CAAG,GAAG,iBAAA,EAAmB,CAAC,MAAM,GAAA,EAAI,CAAE,gBAAA,GAAmB,CAAC,CAAC,CAAA;AAAA,MAC3D,EAAA,CAAG,EAAA,CAAG,mBAAA,EAAqB,CAAC,CAAA,KAAM;AAChC,QAAA,GAAA,EAAI,CAAE,qBAAqB,CAAC,CAAA;AAE5B,QAAA,sBAAA,CAAuB,OAAA,CAAQ,sBAAA;AAAA,UAC7B,MAAA,CAAO,KAAA,CAAM,QAAA,EAAS,CAAE,SAAA,CAAU,cAAA;AAAA,UACjC,EAAU,MAAA,IAAU;AAAA,SACvB;AAAA,MACF,CAAC,CAAA;AAAA,MACD,EAAA,CAAG,EAAA,CAAG,qBAAA,EAAuB,CAAC,CAAA,KAAM;AAClC,QAAA,GAAA,EAAI,CAAE,gBAAgB,CAAC,CAAA;AAEvB,QAAA,sBAAA,CAAuB,OAAA,CAAQ,iBAAA,GAAoB,CAAA,CAAE,SAAS,CAAA;AAAA,MAChE,CAAC,CAAA;AAAA,MACD,EAAA,CAAG,EAAA,CAAG,gBAAA,EAAkB,CAAC,CAAA,KAAM;AAC7B,QAAA,GAAA,EAAI,CAAE,kBAAkB,CAAC,CAAA;AACzB,QAAA,sBAAA,CAAuB,OAAA,CAAQ,mBAAA,GAAsB,CAAA,CAAE,WAAW,CAAA;AAAA,MACpE,CAAC,CAAA;AAAA,MACD,EAAA,CAAG,GAAG,mBAAA,EAAqB,CAAC,MAAM,GAAA,EAAI,CAAE,kBAAA,GAAqB,CAAC,CAAC,CAAA;AAAA,MAC/D,EAAA,CAAG,GAAG,cAAA,EAAgB,CAAC,MAAM,GAAA,EAAI,CAAE,aAAA,GAAgB,CAAC,CAAC,CAAA;AAAA,MACrD,EAAA,CAAG,GAAG,oBAAA,EAAsB,CAAC,MAAM,GAAA,EAAI,CAAE,mBAAA,GAAsB,CAAC,CAAC,CAAA;AAAA,MACjE,EAAA,CAAG,GAAG,aAAA,EAAe,CAAC,MAAM,GAAA,EAAI,CAAE,YAAA,GAAe,CAAC,CAAC,CAAA;AAAA,MACnD,EAAA,CAAG,GAAG,qBAAA,EAAuB,CAAC,MAAM,GAAA,EAAI,CAAE,oBAAA,GAAuB,CAAC,CAAC,CAAA;AAAA,MACnE,EAAA,CAAG,GAAG,qBAAA,EAAuB,CAAC,MAAM,GAAA,EAAI,CAAE,oBAAA,GAAuB,CAAC,CAAC,CAAA;AAAA,MACnE,EAAA,CAAG,EAAA,CAAG,oBAAA,EAAsB,CAAC,CAAA,KAAM;AACjC,QAAA,GAAA,EAAI,CAAE,sBAAsB,CAAC,CAAA;AAC7B,QAAA,sBAAA,CAAuB,OAAA,CAAQ,mBAAA,GAAsB,CAAA,CAAE,WAAW,CAAA;AAAA,MACpE,CAAC,CAAA;AAAA,MACD,EAAA,CAAG,GAAG,gBAAA,EAAkB,CAAC,MAAM,GAAA,EAAI,CAAE,eAAA,GAAkB,CAAC,CAAC;AAAA,KAC3D;AAEA,IAAA,OAAO,MAAM,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,KAAM,GAAG,CAAA;AAAA,EACxC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,WAAA,GAAc,OAAO,GAAG,CAAA;AAAA,IAC1B;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,MAAM,KAAA,GAAuB;AAAA,IAC3B,QAAQ,OAAO,MAAA,KAAW,QAAA,GAAW,CAAA,EAAG,MAAM,CAAA,EAAA,CAAA,GAAO,MAAA;AAAA,IACrD,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,CAAA,EAAG,KAAK,CAAA,EAAA,CAAA,GAAO,KAAA;AAAA,IAClD,GAAG;AAAA,GACL;AAGA,EAAA,MAAM,YAAA,GAAeO,aAAA;AAAA,IACnB,MAAO,SAAS,EAAE,MAAA,EAAQ,KAAK,MAAA,CAAO,GAAA,EAAK,aAAY,GAAI,IAAA;AAAA,IAC3D,CAAC,QAAQ,WAAW;AAAA,GACtB;AAGA,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,YAAA,EAAc;AAC5B,IAAA,uBACEZ,cAAAA,CAAC,iBAAA,EAAA,EACC,QAAA,kBAAAA,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,YAAA;AAAA,QACL,SAAA,EAAW,CAAA,aAAA,EAAgB,cAAA,IAAkB,EAAE,GAAG,IAAA,EAAK;AAAA,QACvD;AAAA;AAAA,KACF,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACEA,eAAC,iBAAA,EAAA,EACC,QAAA,kBAAAQ,gBAAC,WAAA,CAAY,QAAA,EAAZ,EAAqB,KAAA,EAAO,YAAA,EAC1B,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,oBACDR,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,YAAA;AAAA,QACL,SAAA,EAAW,CAAA,aAAA,EAAgB,cAAA,IAAkB,EAAE,GAAG,IAAA,EAAK;AAAA,QACvD;AAAA;AAAA,KACF;AAAA,oBACAA,cAAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,KAAK,MAAA,CAAO,GAAA;AAAA,QACZ,OAAA,EAAS,YAAA;AAAA,QACT,WAAA;AAAA,QACA,oBAAA,EAAsB;AAAA;AAAA;AACxB,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;;;ACnbO,SAAS,UAAA,GAA0C;AACxD,EAAA,OAAO,gBAAsB,CAAE,GAAA;AACjC;ACKO,SAAS,aACd,QAAA,EACS;AACT,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,cAAA,EAAsB;AAGzC,EAAA,MAAM,WAAA,GAAcI,iBAAAA;AAAA,IAClB,MAAM,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,UAA8B,CAAA;AAAA,IAC1D,CAAC,UAAU,MAAM;AAAA,GACnB;AAEA,EAAA,OAAOG,0BAAAA;AAAA,IACL,CAAC,aAAA,KAAkB,MAAA,CAAO,KAAA,CAAM,UAAU,aAAa,CAAA;AAAA,IACvD,WAAA;AAAA,IACA;AAAA,GACF;AACF;ACDO,SAAS,gBAAA,GAA4D;AAC1E,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAI,GAAI,cAAA,EAAsB;AAE9C,EAAA,MAAM,oBAAA,GAAuBH,iBAAAA,CAAY,MAAM,MAAA,CAAO,KAAA,CAAM,QAAA,EAAS,CAAE,SAAA,CAAU,cAAA,EAAgB,CAAC,MAAM,CAAC,CAAA;AACzG,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAY,CAAC,EAAA,KAAmB,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,EAAE,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEtF,EAAA,MAAM,cAAA,GAAiBG,0BAAAA;AAAA,IACrB,SAAA;AAAA,IACA,oBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,gBAAgB,cAAA,CAAe,IAAA;AAErC,EAAA,MAAM,aAAA,GAAgBH,iBAAAA;AAAA,IACpB,CAAC,UACC,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE,SAAA,CAAU,cAAA,CAAe,GAAA,CAAI,KAAK,CAAA;AAAA,IAC5D,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,eAAA,GAAkBA,kBAAY,MAAM,GAAA,CAAI,iBAAgB,EAAG,CAAC,GAAG,CAAC,CAAA;AACtE,EAAA,MAAM,gBAAA,GAAmBA,kBAAY,MAAM,GAAA,CAAI,kBAAiB,EAAG,CAAC,GAAG,CAAC,CAAA;AACxE,EAAA,MAAM,SAAA,GAAYA,kBAAY,MAAM,GAAA,CAAI,WAAU,EAAG,CAAC,GAAG,CAAC,CAAA;AAC1D,EAAA,MAAM,WAAA,GAAcA,kBAAY,MAAM,GAAA,CAAI,aAAY,EAAG,CAAC,GAAG,CAAC,CAAA;AAE9D,EAAA,OAAO;AAAA,IACL,cAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;ACtCO,SAAS,WAAA,GAA8B;AAC5C,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAI,GAAI,cAAA,EAAe;AAEvC,EAAA,MAAM,eAAA,GAAkBA,iBAAAA,CAAY,MAAM,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE,SAAA,EAAW,CAAC,MAAM,CAAC,CAAA;AACrF,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAY,CAAC,EAAA,KAAmB,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,EAAE,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEtF,EAAA,MAAM,SAAA,GAAYG,0BAAAA;AAAA,IAChB,SAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,QAAA,GAAW,UAAU,MAAA,GAAS,CAAA;AAEpC,EAAA,MAAM,YAAA,GAAeH,iBAAAA;AAAA,IACnB,CAAC,KAAA,KAA2B,GAAA,CAAI,YAAA,CAAa,KAAK,CAAA;AAAA,IAClD,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,UAAA,GAAaA,iBAAAA;AAAA,IACjB,CAAC,KAAA,EAAe,SAAA,GAAY,KAAA,KAAU;AACpC,MAAA,MAAA,CAAO,WAAW,QAAA,CAAS,aAAA,EAAe,EAAE,KAAA,EAAO,WAAW,CAAA;AAAA,IAChE,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAY,MAAM,GAAA,CAAI,YAAA,CAAa,EAAE,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAE/D,EAAA,OAAO,EAAE,SAAA,EAAW,QAAA,EAAU,YAAA,EAAc,YAAY,SAAA,EAAU;AACpE;AC3BO,SAAS,aAAA,GAAkC;AAChD,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAI,GAAI,cAAA,EAAe;AAEvC,EAAA,MAAM,iBAAA,GAAoBA,iBAAAA,CAAY,MAAM,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE,WAAA,EAAa,CAAC,MAAM,CAAC,CAAA;AACzF,EAAA,MAAM,sBAAA,GAAyBA,iBAAAA,CAAY,MAAM,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE,eAAA,EAAiB,CAAC,MAAM,CAAC,CAAA;AAClG,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAY,CAAC,EAAA,KAAmB,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,EAAE,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEtF,EAAA,MAAM,WAAA,GAAcG,0BAAAA;AAAA,IAClB,SAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,eAAA,GAAkBA,0BAAAA;AAAA,IACtB,SAAA;AAAA,IACA,sBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,UAAA,GACJ,OAAO,IAAA,CAAK,WAAW,EAAE,MAAA,GAAS,CAAA,IAAK,gBAAgB,MAAA,GAAS,CAAA;AAElE,EAAA,MAAM,cAAA,GAAiBH,iBAAAA;AAAA,IACrB,CAAC,KAAA,KAAuC,GAAA,CAAI,cAAA,CAAe,KAAK,CAAA;AAAA,IAChE,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,cAAA,GAAiBA,iBAAAA;AAAA,IACrB,CAAC,IAAA,KAAiB,GAAA,CAAI,cAAA,CAAe,IAAI,CAAA;AAAA,IACzC,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,YAAA,GAAeA,kBAAY,MAAM;AACrC,IAAA,GAAA,CAAI,cAAA,CAAe,EAAE,CAAA;AACrB,IAAA,GAAA,CAAI,eAAe,EAAE,CAAA;AAAA,EACvB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,eAAA;AAAA,IACA,UAAA;AAAA,IACA,cAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACF;AACF;ACpCO,SAAS,iBAAA,GAA0C;AACxD,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAI,GAAI,cAAA,EAAe;AAEvC,EAAA,MAAM,qBAAA,GAAwBA,iBAAAA,CAAY,MAAM,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE,UAAA,EAAY,CAAC,MAAM,CAAC,CAAA;AAC5F,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAY,CAAC,EAAA,KAAmB,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,EAAE,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEtF,EAAA,MAAM,eAAA,GAAkBG,0BAAAA;AAAA,IACtB,SAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,EAAE,WAAA,EAAa,QAAA,EAAU,SAAA,EAAU,GAAI,eAAA;AAC7C,EAAA,MAAM,UAAA,GAAa,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,IAAA,CAAK,SAAA,GAAY,QAAQ,CAAC,CAAA;AAC9D,EAAA,MAAM,WAAA,GAAc,cAAc,UAAA,GAAa,CAAA;AAC/C,EAAA,MAAM,kBAAkB,WAAA,GAAc,CAAA;AAEtC,EAAA,MAAM,QAAA,GAAWH,iBAAAA;AAAA,IACf,CAAC,IAAA,KAAiB,GAAA,CAAI,kBAAA,CAAmB,IAAI,CAAA;AAAA,IAC7C,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,QAAA,GAAWA,kBAAY,MAAM;AACjC,IAAA,IAAI,WAAA,EAAa,GAAA,CAAI,kBAAA,CAAmB,WAAA,GAAc,CAAC,CAAA;AAAA,EACzD,CAAA,EAAG,CAAC,GAAA,EAAK,WAAA,EAAa,WAAW,CAAC,CAAA;AAElC,EAAA,MAAM,YAAA,GAAeA,kBAAY,MAAM;AACrC,IAAA,IAAI,eAAA,EAAiB,GAAA,CAAI,kBAAA,CAAmB,WAAA,GAAc,CAAC,CAAA;AAAA,EAC7D,CAAA,EAAG,CAAC,GAAA,EAAK,WAAA,EAAa,eAAe,CAAC,CAAA;AAEtC,EAAA,MAAM,SAAA,GAAYA,kBAAY,MAAM,GAAA,CAAI,mBAAmB,CAAC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAEpE,EAAA,MAAM,QAAA,GAAWA,iBAAAA;AAAA,IACf,MAAM,GAAA,CAAI,kBAAA,CAAmB,UAAA,GAAa,CAAC,CAAA;AAAA,IAC3C,CAAC,KAAK,UAAU;AAAA,GAClB;AAEA,EAAA,OAAOQ,aAAAA;AAAA,IACL,OAAO;AAAA,MACL,WAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA;AAAA,MACA,eAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA;AAAA,MACE,WAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA;AAAA,MACA,eAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA;AAAA;AACF,GACF;AACF;ACtFO,SAAS,YAAA,CAId,OACA,OAAA,EACM;AACN,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,cAAA,EAAsB;AACzC,EAAA,MAAM,UAAA,GAAaT,aAAO,OAAO,CAAA;AACjC,EAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAErB,EAAAE,gBAAU,MAAM;AACd,IAAA,MAAM,QAAQ,MAAA,CAAO,QAAA,CAAS,EAAA,CAAG,KAAA,EAAc,CAAC,OAAA,KAAiB;AAC/D,MAAA,UAAA,CAAW,QAAQ,OAAO,CAAA;AAAA,IAC5B,CAAC,CAAA;AACD,IAAA,OAAO,KAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAA,EAAQ,KAAK,CAAC,CAAA;AACpB;ACHO,SAAS,aAAA,GAAkC;AAChD,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAI,GAAI,cAAA,EAAe;AAEvC,EAAA,MAAM,kBAAA,GAAqBD,iBAAAA,CAAY,MAAM,MAAA,CAAO,KAAA,CAAM,UAAS,CAAE,OAAA,EAAS,CAAC,MAAM,CAAC,CAAA;AACtF,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAY,CAAC,EAAA,KAAmB,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,EAAE,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEtF,EAAA,MAAM,UAAA,GAAaG,0BAAAA;AAAA,IACjB,SAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,cAAA,GAAiBK,aAAAA;AAAA,IACrB,MAAM,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,EAAE,IAAI,CAAA;AAAA,IACtC,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,MAAM,gBAAA,GAAmBR,iBAAAA;AAAA,IACvB,CAAC,KAAA,EAAe,OAAA,KAAqB,GAAA,CAAI,gBAAA,CAAiB,OAAO,OAAO,CAAA;AAAA,IACxE,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,cAAA,GAAiBA,iBAAAA;AAAA,IACrB,CAAC,KAAA,EAAe,KAAA,KAAkB,GAAA,CAAI,cAAA,CAAe,OAAO,KAAK,CAAA;AAAA,IACjE,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,UAAA,GAAaA,iBAAAA;AAAA,IACjB,CAAC,KAAA,EAAe,OAAA,KAAoB,GAAA,CAAI,UAAA,CAAW,OAAO,OAAO,CAAA;AAAA,IACjE,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,eAAA,GAAkBA,iBAAAA;AAAA,IACtB,CAAC,KAAA,EAAe,MAAA,KACd,GAAA,CAAI,eAAA,CAAgB,OAAO,MAAM,CAAA;AAAA,IACnC,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,SAAA,GAAYA,iBAAAA;AAAA,IAChB,CAAC,KAAA,KAAkB,GAAA,CAAI,SAAA,CAAU,KAAK,CAAA;AAAA,IACtC,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,cAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,GACF;AACF","file":"index.cjs","sourcesContent":["// ─── Grid Context ───\n// Provides the engine, API, and metadata to all child hooks and components.\n\nimport { createContext, useContext } from 'react';\nimport type { GridEngine, GridApi } from '@gridstorm/core';\n\nexport interface GridContextValue<TData = any> {\n engine: GridEngine<TData>;\n api: GridApi<TData>;\n /** The root DOM element (.gs-root) of the grid. */\n rootElement: HTMLElement | null;\n}\n\nexport const GridContext = createContext<GridContextValue | null>(null);\n\n/**\n * Internal helper — gets grid context with null-check.\n * All public hooks use this internally.\n */\nexport function useGridContext<TData = any>(): GridContextValue<TData> {\n const ctx = useContext(GridContext);\n if (!ctx) {\n throw new Error(\n '[GridStorm] Hook must be used within a <GridStorm> component.',\n );\n }\n return ctx as GridContextValue<TData>;\n}\n","// ─── React Cell Renderer Marker ───\n// Wraps a React component so it can be used as a CellRendererFn.\n// The DomRenderer will receive an empty string (creating an empty cell),\n// and the PortalManager will detect the marker and portal the React\n// component into that cell.\n\nimport type { ReactCellRenderer } from '../types';\n\n/** Symbol marker for React cell renderers. */\nexport const REACT_CELL_RENDERER = Symbol.for('gridstorm:reactCellRenderer');\n\n/**\n * Wrap a React component to use as a cell renderer.\n *\n * @example\n * ```tsx\n * const StatusCell = ({ value }: CellRendererProps) => (\n * <span className={value ? 'active' : 'inactive'}>{value ? 'Yes' : 'No'}</span>\n * );\n *\n * const columns = [\n * { field: 'active', cellRenderer: reactCellRenderer(StatusCell) },\n * ];\n * ```\n */\nexport function reactCellRenderer<TData = any, TValue = any>(\n Component: ReactCellRenderer<TData, TValue>,\n): any {\n // Return a CellRendererFn that outputs empty string.\n // The DomRenderer will create an empty cell; the PortalManager portals React content into it.\n const fn = () => '';\n (fn as any)[REACT_CELL_RENDERER] = Component;\n return fn;\n}\n\n/** Check if a cellRenderer is a wrapped React component. */\nexport function isReactCellRenderer(fn: unknown): boolean {\n return typeof fn === 'function' && REACT_CELL_RENDERER in (fn as any);\n}\n\n/** Extract the React component from a wrapped cell renderer. */\nexport function getReactCellComponent<TData = any, TValue = any>(\n fn: unknown,\n): ReactCellRenderer<TData, TValue> | null {\n if (isReactCellRenderer(fn)) {\n return (fn as any)[REACT_CELL_RENDERER];\n }\n return null;\n}\n","// ─── React Header Renderer Marker ───\n// Same pattern as ReactCellRenderer but for header cells.\n\nimport type { ReactHeaderRenderer } from '../types';\n\n/** Symbol marker for React header renderers. */\nexport const REACT_HEADER_RENDERER = Symbol.for('gridstorm:reactHeaderRenderer');\n\n/**\n * Wrap a React component to use as a header renderer.\n *\n * @example\n * ```tsx\n * const SortHeader = ({ displayName, sortDirection, onSortRequested }: HeaderRendererProps) => (\n * <div onClick={() => onSortRequested(false)}>\n * {displayName} {sortDirection === 'asc' ? '▲' : sortDirection === 'desc' ? '▼' : ''}\n * </div>\n * );\n *\n * const columns = [\n * { field: 'name', headerRenderer: reactHeaderRenderer(SortHeader) },\n * ];\n * ```\n */\nexport function reactHeaderRenderer<TData = any>(\n Component: ReactHeaderRenderer<TData>,\n): any {\n const fn = () => '';\n (fn as any)[REACT_HEADER_RENDERER] = Component;\n return fn;\n}\n\n/** Check if a headerRenderer is a wrapped React component. */\nexport function isReactHeaderRenderer(fn: unknown): boolean {\n return typeof fn === 'function' && REACT_HEADER_RENDERER in (fn as any);\n}\n\n/** Extract the React component from a wrapped header renderer. */\nexport function getReactHeaderComponent<TData = any>(\n fn: unknown,\n): ReactHeaderRenderer<TData> | null {\n if (isReactHeaderRenderer(fn)) {\n return (fn as any)[REACT_HEADER_RENDERER];\n }\n return null;\n}\n","// ─── Cell Renderer Portal ───\n// Memoized wrapper for individual React cell renderer portals.\n// Custom comparator prevents re-renders when cell data hasn't changed.\n\nimport { memo } from 'react';\nimport type { ReactCellRenderer, CellRendererProps } from '../types';\n\ninterface CellRendererPortalProps<TData = any, TValue = any> {\n Component: ReactCellRenderer<TData, TValue>;\n rendererProps: CellRendererProps<TData, TValue>;\n nodeVersion: number;\n}\n\nfunction CellRendererPortalInner<TData = any, TValue = any>(\n props: CellRendererPortalProps<TData, TValue>,\n) {\n const { Component, rendererProps } = props;\n return <Component {...rendererProps} />;\n}\n\n/** Memoized cell renderer portal — only re-renders when value or version changes. */\nexport const CellRendererPortal = memo(\n CellRendererPortalInner,\n (prev, next) =>\n prev.nodeVersion === next.nodeVersion &&\n prev.rendererProps.value === next.rendererProps.value &&\n prev.rendererProps.rowIndex === next.rendererProps.rowIndex &&\n prev.rendererProps.colId === next.rendererProps.colId,\n) as typeof CellRendererPortalInner;\n","// ─── Cell Editor Portal ───\n// Renders a React cell editor component as an absolutely-positioned\n// overlay on top of the editing cell.\n\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport type { GridEngine, GridApi } from '@gridstorm/core';\nimport type { ReactCellEditor, EditorPortalState } from '../types';\n\ninterface CellEditorPortalProps<TData = any> {\n state: EditorPortalState;\n api: GridApi<TData>;\n engine: GridEngine<TData>;\n EditorComponent: ReactCellEditor<TData>;\n editorParams: Record<string, unknown>;\n gridRootRect: DOMRect;\n}\n\nexport function CellEditorPortal<TData = any>(props: CellEditorPortalProps<TData>) {\n const { state, api, engine, EditorComponent, editorParams, gridRootRect } = props;\n const { editing, cellRect } = state;\n const [value, setValue] = useState(editing.value);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const onValueChange = useCallback(\n (newValue: any) => {\n setValue(newValue);\n engine.commandBus.dispatch('editing:setValue', { value: newValue });\n },\n [engine],\n );\n\n const stopEditing = useCallback(\n (cancel?: boolean) => {\n api.stopEditing(cancel);\n },\n [api],\n );\n\n // Auto-focus the editor on mount\n useEffect(() => {\n requestAnimationFrame(() => {\n const el = containerRef.current;\n if (!el) return;\n const focusable = el.querySelector<HTMLElement>(\n 'input, textarea, select, [tabindex]',\n );\n focusable?.focus();\n });\n }, []);\n\n const column = engine.store\n .getState()\n .columns.find((c) => c.colId === editing.colId)!;\n\n const node = engine.store.getState().rowNodes.get(editing.rowId);\n\n // Position relative to the grid root\n const top = cellRect.top - gridRootRect.top;\n const left = cellRect.left - gridRootRect.left;\n\n return (\n <div\n ref={containerRef}\n className=\"gs-editor-portal\"\n style={{\n position: 'absolute',\n top,\n left,\n width: cellRect.width,\n height: cellRect.height,\n zIndex: 10,\n boxSizing: 'border-box',\n background: 'var(--gs-color-cell-editing-bg, #fff)',\n border: '2px solid var(--gs-color-cell-editing-border, #2196f3)',\n }}\n >\n <EditorComponent\n value={value}\n data={node?.data as TData}\n colId={editing.colId}\n rowId={editing.rowId}\n column={column}\n editorParams={editorParams}\n onValueChange={onValueChange}\n stopEditing={stopEditing}\n api={api}\n />\n </div>\n );\n}\n","// ─── Context Menu Portal ───\n// Renders a user-provided context menu component at the right-click position.\n\nimport { useEffect, useRef } from 'react';\nimport type { ContextMenuProps, ReactContextMenu } from '../types';\n\ninterface ContextMenuPortalProps<TData = any> {\n x: number;\n y: number;\n menuProps: ContextMenuProps<TData>;\n Component: ReactContextMenu<TData>;\n}\n\nexport function ContextMenuPortal<TData = any>(\n props: ContextMenuPortalProps<TData>,\n) {\n const { x, y, menuProps, Component } = props;\n const ref = useRef<HTMLDivElement>(null);\n\n // Close on click outside\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n menuProps.closeMenu();\n }\n };\n // Use setTimeout so the current click doesn't immediately close the menu\n const id = setTimeout(() => {\n document.addEventListener('mousedown', handler);\n }, 0);\n return () => {\n clearTimeout(id);\n document.removeEventListener('mousedown', handler);\n };\n }, [menuProps]);\n\n // Close on Escape\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') menuProps.closeMenu();\n };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [menuProps]);\n\n return (\n <div\n ref={ref}\n className=\"gs-context-menu-portal\"\n style={{\n position: 'absolute',\n top: y,\n left: x,\n zIndex: 100,\n minWidth: 160,\n }}\n >\n <Component {...menuProps} />\n </div>\n );\n}\n","// ─── Portal Manager ───\r\n// Central orchestrator for all React portals: cell renderers, header\r\n// renderers, editors, and context menus.\r\n//\r\n// Uses a MutationObserver on .gs-body to detect when DomRenderer\r\n// adds/removes row elements, then portals React content into wrapper\r\n// divs inside cells that have React renderers.\r\n//\r\n// KEY DESIGN: We never portal directly into DomRenderer-managed cells.\r\n// Instead, we create a wrapper <div style=\"display:contents\"> inside each\r\n// cell and portal into that wrapper. This prevents crashes when DomRenderer\r\n// destroys/recycles cells — the wrapper is detached but still maintains\r\n// its React children, so React can safely unmount.\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useState,\r\n useCallback,\r\n useSyncExternalStore,\r\n} from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport type { GridEngine, GridApi, ColumnState, RowNode } from '@gridstorm/core';\r\nimport { getValueFromData } from '@gridstorm/core';\r\nimport type {\r\n ReactColumnDef,\r\n CellRendererProps,\r\n HeaderRendererProps,\r\n EditorPortalState,\r\n ContextMenuProps,\r\n ReactContextMenu,\r\n ReactCellEditor,\r\n} from '../types';\r\nimport { getReactCellComponent, isReactCellRenderer } from '../renderers/ReactCellRenderer';\r\nimport { getReactHeaderComponent, isReactHeaderRenderer } from '../renderers/ReactHeaderRenderer';\r\nimport { CellRendererPortal } from './CellRendererPortal';\r\nimport { CellEditorPortal } from './CellEditorPortal';\r\nimport { ContextMenuPortal } from './ContextMenuPortal';\r\n\r\nexport interface PortalManagerProps<TData = any> {\r\n engine: GridEngine<TData>;\r\n api: GridApi<TData>;\r\n columns: ReactColumnDef<TData>[];\r\n rootElement: HTMLElement | null;\r\n contextMenuComponent?: ReactContextMenu<TData>;\r\n}\r\n\r\n// ── Portal wrapper attribute ──\r\n// Used to identify wrapper divs we've created inside cells.\r\nconst WRAPPER_ATTR = 'data-gs-portal';\r\n\r\n// ── Cell renderer portal entry ──\r\ninterface CellPortalEntry<TData = any> {\r\n key: string;\r\n /** The wrapper div inside the cell (React-owned, safe to portal into) */\r\n container: HTMLElement;\r\n component: any;\r\n props: CellRendererProps<TData>;\r\n nodeVersion: number;\r\n}\r\n\r\n// ── Header renderer portal entry ──\r\ninterface HeaderPortalEntry {\r\n key: string;\r\n /** The wrapper div inside the header cell */\r\n container: HTMLElement;\r\n element: any;\r\n}\r\n\r\n// ── Context menu state ──\r\ninterface ContextMenuState<TData = any> {\r\n x: number;\r\n y: number;\r\n menuProps: ContextMenuProps<TData>;\r\n}\r\n\r\n// ── Helper: get or create a stable wrapper div inside a cell ──\r\n// The wrapper uses display:contents so it's layout-transparent.\r\n// When DomRenderer destroys the cell, the wrapper is detached but\r\n// still maintains its children — React can safely unmount from it.\r\nfunction getOrCreateWrapper(cell: HTMLElement): HTMLElement {\r\n // Check direct children only (not descendants) for existing wrapper\r\n for (let i = 0; i < cell.children.length; i++) {\r\n const child = cell.children[i] as HTMLElement;\r\n if (child.hasAttribute(WRAPPER_ATTR)) {\r\n return child;\r\n }\r\n }\r\n // Create new wrapper\r\n const wrapper = document.createElement('div');\r\n wrapper.setAttribute(WRAPPER_ATTR, '');\r\n wrapper.style.display = 'contents';\r\n cell.appendChild(wrapper);\r\n return wrapper;\r\n}\r\n\r\nexport function PortalManager<TData = any>(props: PortalManagerProps<TData>) {\r\n const { engine, api, columns, rootElement, contextMenuComponent } = props;\r\n\r\n // ── Portal state ──\r\n const [cellPortals, setCellPortals] = useState<Map<string, CellPortalEntry<TData>>>(\r\n () => new Map(),\r\n );\r\n const [headerPortals, setHeaderPortals] = useState<Map<string, HeaderPortalEntry>>(\r\n () => new Map(),\r\n );\r\n const [editorPortal, setEditorPortal] = useState<EditorPortalState | null>(null);\r\n const [contextMenu, setContextMenu] = useState<ContextMenuState<TData> | null>(null);\r\n\r\n // Refs for stable access in callbacks\r\n const columnsRef = useRef(columns);\r\n columnsRef.current = columns;\r\n const engineRef = useRef(engine);\r\n engineRef.current = engine;\r\n\r\n // Track if we're currently scanning to prevent re-entrant scans\r\n const scanningRef = useRef(false);\r\n\r\n // ── Build lookup maps for which columns have React renderers ──\r\n const reactCellRendererMap = useRef(new Map<string, any>());\r\n const reactHeaderRendererMap = useRef(new Map<string, any>());\r\n const reactEditorMap = useRef(new Map<string, ReactCellEditor<TData>>());\r\n\r\n useEffect(() => {\r\n const cellMap = new Map<string, any>();\r\n const headerMap = new Map<string, any>();\r\n const editorMap = new Map<string, ReactCellEditor<TData>>();\r\n\r\n for (const col of columns) {\r\n const colId = (col as any).colId ?? col.field ?? '';\r\n if (col.cellRenderer && isReactCellRenderer(col.cellRenderer)) {\r\n cellMap.set(colId, getReactCellComponent(col.cellRenderer));\r\n }\r\n if (col.headerRenderer && isReactHeaderRenderer(col.headerRenderer)) {\r\n headerMap.set(colId, getReactHeaderComponent(col.headerRenderer));\r\n }\r\n if (col.cellEditorComponent) {\r\n editorMap.set(colId, col.cellEditorComponent);\r\n }\r\n }\r\n\r\n reactCellRendererMap.current = cellMap;\r\n reactHeaderRendererMap.current = headerMap;\r\n reactEditorMap.current = editorMap;\r\n }, [columns]);\r\n\r\n // ── Helper: build cell renderer props ──\r\n const buildCellProps = useCallback(\r\n (node: RowNode<TData>, col: ColumnState, rowIndex: number): CellRendererProps<TData> => {\r\n const colDef = col.originalDef;\r\n let value: any;\r\n if (colDef.valueGetter) {\r\n value = colDef.valueGetter({\r\n data: node.data,\r\n node,\r\n colDef,\r\n colId: col.colId,\r\n });\r\n } else {\r\n value = getValueFromData(node.data, col.field);\r\n }\r\n\r\n let formattedValue = value != null ? String(value) : '';\r\n if (colDef.valueFormatter) {\r\n formattedValue = colDef.valueFormatter({ value, data: node.data, node, colDef });\r\n }\r\n\r\n return {\r\n value,\r\n formattedValue,\r\n data: node.data,\r\n node,\r\n colDef,\r\n colId: col.colId,\r\n rowIndex,\r\n api,\r\n };\r\n },\r\n [api],\r\n );\r\n\r\n // ── Scan visible rows and create/update cell portals ──\r\n const scanVisibleRows = useCallback(() => {\r\n if (!rootElement || scanningRef.current) return;\r\n scanningRef.current = true;\r\n\r\n try {\r\n const bodyContainer = rootElement.querySelector('.gs-body');\r\n if (!bodyContainer) return;\r\n\r\n const state = engineRef.current.store.getState();\r\n const cellRenderers = reactCellRendererMap.current;\r\n if (cellRenderers.size === 0) return;\r\n\r\n const newPortals = new Map<string, CellPortalEntry<TData>>();\r\n const rowElements = bodyContainer.querySelectorAll<HTMLElement>('.gs-row');\r\n\r\n // Pre-build O(1) lookup maps to avoid O(n) indexOf / find in hot path\r\n const rowIdIndexMap = new Map<string, number>();\r\n for (let i = 0; i < state.displayedRowIds.length; i++) {\r\n rowIdIndexMap.set(state.displayedRowIds[i]!, i);\r\n }\r\n const columnMap = new Map<string, ColumnState>();\r\n for (const col of state.columns) {\r\n columnMap.set(col.colId, col);\r\n }\r\n\r\n for (const rowEl of rowElements) {\r\n const rowId = rowEl.getAttribute('data-row-id');\r\n if (!rowId) continue;\r\n\r\n const node = state.rowNodes.get(rowId);\r\n if (!node) continue;\r\n\r\n const cells = rowEl.querySelectorAll<HTMLElement>('.gs-cell');\r\n for (const cellEl of cells) {\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!colId || !cellRenderers.has(colId)) continue;\r\n\r\n const key = `${rowId}:${colId}`;\r\n const Component = cellRenderers.get(colId)!;\r\n const colState = columnMap.get(colId);\r\n if (!colState) continue;\r\n\r\n const rowIndex = rowIdIndexMap.get(rowId) ?? -1;\r\n const rendererProps = buildCellProps(node, colState, rowIndex);\r\n\r\n // Get or create a stable wrapper div inside the cell.\r\n // We portal into the wrapper, NOT the cell directly.\r\n // This prevents crashes when DomRenderer destroys/recycles cells.\r\n const wrapper = getOrCreateWrapper(cellEl);\r\n\r\n newPortals.set(key, {\r\n key,\r\n container: wrapper,\r\n component: Component,\r\n props: rendererProps,\r\n nodeVersion: node.version,\r\n });\r\n }\r\n }\r\n\r\n setCellPortals(newPortals);\r\n } finally {\r\n scanningRef.current = false;\r\n }\r\n }, [rootElement, buildCellProps]);\r\n\r\n // ── Scan header cells for React header renderers ──\r\n const scanHeaderCells = useCallback(() => {\r\n if (!rootElement) return;\r\n const headerRenderers = reactHeaderRendererMap.current;\r\n if (headerRenderers.size === 0) return;\r\n\r\n const headerContainer = rootElement.querySelector('.gs-header');\r\n if (!headerContainer) return;\r\n\r\n const state = engineRef.current.store.getState();\r\n const newPortals = new Map<string, HeaderPortalEntry>();\r\n\r\n const headerCells = headerContainer.querySelectorAll<HTMLElement>('.gs-header-cell');\r\n for (const cellEl of headerCells) {\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!colId || !headerRenderers.has(colId)) continue;\r\n\r\n const Component = headerRenderers.get(colId)!;\r\n const colState = state.columns.find((c) => c.colId === colId);\r\n if (!colState) continue;\r\n\r\n const sortItem = state.sortModel.find((s) => s.colId === colId);\r\n\r\n const headerProps: HeaderRendererProps<TData> = {\r\n colDef: colState.originalDef,\r\n colId,\r\n displayName: colState.headerName,\r\n sortDirection: sortItem?.sort ?? null,\r\n sortIndex: colState.sortIndex,\r\n api,\r\n onSortRequested: (multiSort: boolean) => {\r\n engineRef.current.commandBus.dispatch('sort:toggle', { colId, multiSort });\r\n },\r\n };\r\n\r\n // Get or create a stable wrapper div inside the header cell.\r\n const wrapper = getOrCreateWrapper(cellEl);\r\n\r\n newPortals.set(colId, {\r\n key: colId,\r\n container: wrapper,\r\n element: <Component {...headerProps} />,\r\n });\r\n }\r\n\r\n setHeaderPortals(newPortals);\r\n }, [rootElement, api]);\r\n\r\n // ── MutationObserver on .gs-body for row add/remove ──\r\n useEffect(() => {\r\n if (!rootElement) return;\r\n const bodyContainer = rootElement.querySelector('.gs-body');\r\n if (!bodyContainer) return;\r\n\r\n const observer = new MutationObserver(() => {\r\n // When DomRenderer adds/removes rows, re-scan for portals\r\n scanVisibleRows();\r\n });\r\n\r\n observer.observe(bodyContainer, { childList: true });\r\n\r\n // Initial scan for already-rendered rows\r\n scanVisibleRows();\r\n scanHeaderCells();\r\n\r\n return () => observer.disconnect();\r\n }, [rootElement, scanVisibleRows, scanHeaderCells]);\r\n\r\n // ── Re-scan when state changes (sort, filter, data) ──\r\n const getVersionSnapshot = useCallback(() => engine.store.getVersion(), [engine]);\r\n const subscribeStore = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const stateVersion = useSyncExternalStore(\r\n subscribeStore,\r\n getVersionSnapshot,\r\n getVersionSnapshot,\r\n );\r\n\r\n useEffect(() => {\r\n scanVisibleRows();\r\n }, [stateVersion, scanVisibleRows]);\r\n\r\n // ── Re-scan headers when sort or columns change ──\r\n useEffect(() => {\r\n const unsubs = [\r\n engine.eventBus.on('column:sort:changed', () => {\r\n // Delay slightly to let DomRenderer recreate header cells first\r\n requestAnimationFrame(() => scanHeaderCells());\r\n }),\r\n engine.eventBus.on('columns:changed', () => {\r\n requestAnimationFrame(() => scanHeaderCells());\r\n }),\r\n ];\r\n return () => unsubs.forEach((u) => u());\r\n }, [engine, scanHeaderCells]);\r\n\r\n // ── Editor portal lifecycle ──\r\n useEffect(() => {\r\n const unsubStart = engine.eventBus.on(\r\n 'cell:editingStarted',\r\n (event: any) => {\r\n const { node, colId } = event;\r\n const editorComponent = reactEditorMap.current.get(colId);\r\n if (!editorComponent || !rootElement) return;\r\n\r\n // Find the cell element (CSS.escape prevents selector injection from rowId/colId)\r\n const cellEl = rootElement.querySelector<HTMLElement>(\r\n `.gs-row[data-row-id=\"${CSS.escape(node.id)}\"] .gs-cell[data-col-id=\"${CSS.escape(colId)}\"]`,\r\n );\r\n if (!cellEl) return;\r\n\r\n const state = engine.store.getState();\r\n const editing = state.editing;\r\n if (!editing) return;\r\n\r\n setEditorPortal({\r\n editing,\r\n cellElement: cellEl,\r\n cellRect: cellEl.getBoundingClientRect(),\r\n });\r\n },\r\n );\r\n\r\n const unsubStop = engine.eventBus.on('cell:editingStopped', () => {\r\n setEditorPortal(null);\r\n });\r\n\r\n return () => {\r\n unsubStart();\r\n unsubStop();\r\n };\r\n }, [engine, rootElement]);\r\n\r\n // ── Context menu ──\r\n useEffect(() => {\r\n if (!rootElement || !contextMenuComponent) return;\r\n\r\n const handler = (e: MouseEvent) => {\r\n e.preventDefault();\r\n const target = e.target as HTMLElement;\r\n const cellEl = target.closest<HTMLElement>('.gs-cell');\r\n const rowEl = target.closest<HTMLElement>('.gs-row');\r\n if (!cellEl || !rowEl) return;\r\n\r\n const rowId = rowEl.getAttribute('data-row-id');\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!rowId || !colId) return;\r\n\r\n const state = engine.store.getState();\r\n const node = state.rowNodes.get(rowId);\r\n if (!node) return;\r\n\r\n const colState = state.columns.find((c) => c.colId === colId);\r\n const value = colState\r\n ? getValueFromData(node.data, colState.field)\r\n : undefined;\r\n\r\n const rootRect = rootElement.getBoundingClientRect();\r\n const rowIndex = state.displayedRowIds.indexOf(rowId);\r\n\r\n setContextMenu({\r\n x: e.clientX - rootRect.left,\r\n y: e.clientY - rootRect.top,\r\n menuProps: {\r\n position: { rowIndex, colId },\r\n node,\r\n colId,\r\n value,\r\n api,\r\n closeMenu: () => setContextMenu(null),\r\n },\r\n });\r\n };\r\n\r\n rootElement.addEventListener('contextmenu', handler);\r\n return () => rootElement.removeEventListener('contextmenu', handler);\r\n }, [rootElement, contextMenuComponent, api, engine]);\r\n\r\n // ── Render portals ──\r\n return (\r\n <>\r\n {/* Cell renderer portals — portaled into wrapper divs, NOT cells directly */}\r\n {Array.from(cellPortals.values()).map((entry) =>\r\n createPortal(\r\n <CellRendererPortal\r\n key={entry.key}\r\n Component={entry.component}\r\n rendererProps={entry.props}\r\n nodeVersion={entry.nodeVersion}\r\n />,\r\n entry.container,\r\n entry.key,\r\n ),\r\n )}\r\n\r\n {/* Header renderer portals — portaled into wrapper divs in header cells */}\r\n {Array.from(headerPortals.values()).map((entry) =>\r\n createPortal(entry.element, entry.container, entry.key),\r\n )}\r\n\r\n {/* Editor portal */}\r\n {editorPortal && rootElement && (() => {\r\n const editorComponent = reactEditorMap.current.get(editorPortal.editing.colId);\r\n if (!editorComponent) return null;\r\n const colDef = columnsRef.current.find(\r\n (c) => ((c as any).colId ?? c.field) === editorPortal.editing.colId,\r\n );\r\n return createPortal(\r\n <CellEditorPortal\r\n state={editorPortal}\r\n api={api}\r\n engine={engine}\r\n EditorComponent={editorComponent}\r\n editorParams={(colDef?.cellEditorParams as Record<string, unknown>) ?? {}}\r\n gridRootRect={rootElement.getBoundingClientRect()}\r\n />,\r\n rootElement,\r\n 'gs-editor',\r\n );\r\n })()}\r\n\r\n {/* Context menu portal */}\r\n {contextMenu && contextMenuComponent && rootElement &&\r\n createPortal(\r\n <ContextMenuPortal\r\n x={contextMenu.x}\r\n y={contextMenu.y}\r\n menuProps={contextMenu.menuProps}\r\n Component={contextMenuComponent}\r\n />,\r\n rootElement,\r\n 'gs-context-menu',\r\n )}\r\n </>\r\n );\r\n}\r\n","// ─── GridStorm Error Boundary ───\n// Catches rendering errors in the grid and displays a fallback UI.\n\nimport { Component, type ReactNode, type ErrorInfo } from 'react';\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class GridErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state: ErrorBoundaryState = { hasError: false, error: null };\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n console.error('[GridStorm] Rendering error:', error, errorInfo.componentStack);\n }\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n return null;\n }\n return this.props.children;\n }\n}\n","// ─── GridStorm React Component ───\r\n// Production-grade React wrapper around the headless core engine.\r\n// Supports controlled + uncontrolled modes, React component cell/header\r\n// renderers via portals, event bridging, and comprehensive hooks.\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useMemo,\r\n useState,\r\n type CSSProperties,\r\n} from 'react';\r\nimport type {\r\n GridConfig,\r\n ColumnDef,\r\n GridEngine,\r\n} from '@gridstorm/core';\r\nimport { createGrid } from '@gridstorm/core';\r\nimport { DomRenderer } from '@gridstorm/dom-renderer';\r\nimport { GridContext, type GridContextValue } from './context';\r\nimport { PortalManager } from './portals/PortalManager';\r\nimport type { GridStormProps, ReactColumnDef } from './types';\r\nimport { GridErrorBoundary } from './ErrorBoundary';\r\n\r\n// ── useGridEngine hook (internal) ──\r\n// Uses useState + useEffect so that StrictMode's cleanup → remount cycle\r\n// creates a fresh engine each time instead of leaving a null ref.\r\n\r\nfunction useGridEngine<TData = any>(config: GridConfig<TData>): GridEngine<TData> | null {\r\n const [engine, setEngine] = useState<GridEngine<TData> | null>(null);\r\n const configRef = useRef(config);\r\n configRef.current = config;\r\n\r\n // Track whether the initial mount has completed so sync effects\r\n // don't double-set data that was already applied during createGrid.\r\n const rowDataMountedRef = useRef(false);\r\n const columnsMountedRef = useRef(false);\r\n\r\n // Create engine in useEffect so StrictMode can safely destroy + recreate\r\n useEffect(() => {\r\n const eng = createGrid(configRef.current);\r\n setEngine(eng);\r\n\r\n // Reset mounted flags when engine is (re)created\r\n rowDataMountedRef.current = false;\r\n columnsMountedRef.current = false;\r\n\r\n return () => {\r\n eng.destroy();\r\n setEngine(null);\r\n };\r\n }, []);\r\n\r\n // Sync rowData changes (skip the first run — createGrid already applied initial data)\r\n useEffect(() => {\r\n if (!engine) return;\r\n if (!rowDataMountedRef.current) {\r\n rowDataMountedRef.current = true;\r\n return;\r\n }\r\n if (config.rowData) {\r\n engine.api.setRowData(config.rowData);\r\n }\r\n }, [config.rowData, engine]);\r\n\r\n // Sync column changes (skip the first run — createGrid already applied initial columns)\r\n useEffect(() => {\r\n if (!engine) return;\r\n if (!columnsMountedRef.current) {\r\n columnsMountedRef.current = true;\r\n return;\r\n }\r\n if (config.columns) {\r\n engine.api.setColumnDefs(config.columns);\r\n }\r\n }, [config.columns, engine]);\r\n\r\n return engine;\r\n}\r\n\r\n// ── Column processing: convert ReactColumnDef[] → ColumnDef[] ──\r\n\r\nfunction processColumns<TData>(\r\n reactColumns: ReactColumnDef<TData>[],\r\n): ColumnDef<TData>[] {\r\n return reactColumns.map((col) => {\r\n const coreDef = { ...col } as any;\r\n\r\n // If cellRenderer is a React-wrapped renderer, keep the marker function\r\n // (it returns '' so DomRenderer creates empty cells; PortalManager handles rendering)\r\n // If it's a plain CellRendererFn, leave it as-is.\r\n // No conversion needed — the marker fn IS a valid CellRendererFn.\r\n\r\n // If headerRenderer is React-wrapped, same logic applies.\r\n\r\n // Remove React-only fields from the core column def\r\n delete coreDef.cellEditorComponent;\r\n\r\n return coreDef as ColumnDef<TData>;\r\n });\r\n}\r\n\r\n// ── Main Component ──\r\n\r\nexport function GridStorm<TData = any>(props: GridStormProps<TData>) {\r\n const {\r\n // GridConfig props\r\n columns: reactColumns,\r\n rowData,\r\n dataSource,\r\n rowModelType,\r\n getRowId,\r\n plugins,\r\n defaultColDef,\r\n rowHeight,\r\n headerHeight,\r\n domLayout,\r\n pinnedTopRowData,\r\n pinnedBottomRowData,\r\n suppressScrollX,\r\n suppressScrollY,\r\n rowSelection,\r\n editType,\r\n undoRedoCellEditing,\r\n pagination,\r\n paginationPageSize,\r\n animateRows,\r\n ariaLabel,\r\n locale,\r\n theme,\r\n // Controlled state props\r\n sortModel: controlledSortModel,\r\n onSortModelChange,\r\n filterModel: controlledFilterModel,\r\n onFilterModelChange,\r\n selectedRowIds: controlledSelectedRowIds,\r\n onSelectedRowIdsChange,\r\n currentPage: controlledCurrentPage,\r\n onCurrentPageChange,\r\n // Event props\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n // Renderer config props\r\n enableCellEditing,\r\n enableGrouping,\r\n groupIndent,\r\n checkboxSelection,\r\n checkboxColumnWidth,\r\n floatingFilter,\r\n floatingFilterDebounce,\r\n enablePagination,\r\n pageSizeOptions,\r\n // Component props\r\n height = 400,\r\n width = '100%',\r\n containerClass,\r\n containerStyle,\r\n contextMenu,\r\n children,\r\n // Rest are ignored (no HTML div passthrough to avoid TS errors)\r\n } = props;\r\n\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const rendererRef = useRef<DomRenderer | null>(null);\r\n const [rootElement, setRootElement] = useState<HTMLElement | null>(null);\r\n\r\n // ── Convert React columns to core columns ──\r\n const coreColumns = useMemo(\r\n () => processColumns(reactColumns),\r\n [reactColumns],\r\n );\r\n\r\n // ── Build core config (only depends on structural changes) ──\r\n const config = useMemo<GridConfig<TData>>(\r\n () => ({\r\n columns: coreColumns,\r\n rowData,\r\n dataSource,\r\n rowModelType,\r\n getRowId,\r\n plugins,\r\n defaultColDef,\r\n rowHeight,\r\n headerHeight,\r\n domLayout,\r\n pinnedTopRowData,\r\n pinnedBottomRowData,\r\n suppressScrollX,\r\n suppressScrollY,\r\n rowSelection,\r\n editType,\r\n undoRedoCellEditing,\r\n pagination,\r\n paginationPageSize,\r\n animateRows,\r\n ariaLabel,\r\n locale,\r\n theme,\r\n }),\r\n // Only recreate config on structural changes\r\n // eslint-disable-next-line -- intentional dependency omission\r\n [coreColumns, plugins, rowModelType, getRowId],\r\n );\r\n\r\n // ── Create grid engine ──\r\n const engine = useGridEngine<TData>(config);\r\n\r\n // ── Mount DOM renderer ──\r\n useEffect(() => {\r\n if (!containerRef.current || !engine) return;\r\n\r\n const renderer = new DomRenderer({\r\n container: containerRef.current,\r\n engine,\r\n enableCellEditing,\r\n enableGrouping,\r\n groupIndent,\r\n checkboxSelection,\r\n checkboxColumnWidth,\r\n floatingFilter,\r\n floatingFilterDebounce,\r\n enablePagination,\r\n pageSizeOptions,\r\n });\r\n renderer.mount();\r\n rendererRef.current = renderer;\r\n\r\n // Capture root element for portals\r\n const root = containerRef.current.querySelector<HTMLElement>('.gs-root');\r\n setRootElement(root);\r\n\r\n // Re-emit grid:ready now that the DOM renderer has mounted.\r\n // Plugins like column-resize, column-reorder, and context-menu\r\n // use requestAnimationFrame on grid:ready to inject DOM elements.\r\n // The original grid:ready fires during createGrid() before the\r\n // renderer exists, so those rAF callbacks find no DOM to work with.\r\n requestAnimationFrame(() => {\r\n engine.eventBus.emit('grid:ready', { api: engine.api });\r\n });\r\n\r\n return () => {\r\n renderer.destroy();\r\n rendererRef.current = null;\r\n setRootElement(null);\r\n };\r\n }, [engine]);\r\n\r\n // ── Controlled mode: install command bus middleware ──\r\n const controlledCallbacksRef = useRef({\r\n onSortModelChange,\r\n onFilterModelChange,\r\n onSelectedRowIdsChange,\r\n onCurrentPageChange,\r\n });\r\n controlledCallbacksRef.current = {\r\n onSortModelChange,\r\n onFilterModelChange,\r\n onSelectedRowIdsChange,\r\n onCurrentPageChange,\r\n };\r\n\r\n useEffect(() => {\r\n if (!engine) return;\r\n const removeMw = engine.commandBus.use((ctx) => {\r\n const cbs = controlledCallbacksRef.current;\r\n\r\n // Intercept sort commands in controlled mode\r\n if (ctx.commandType === 'sort:toggle' && cbs.onSortModelChange) {\r\n // Let the command execute to compute the new sort model,\r\n // then we'll intercept the result via the event listener\r\n return;\r\n }\r\n\r\n // Intercept selection in controlled mode\r\n if (ctx.commandType === 'selection:select' && cbs.onSelectedRowIdsChange) {\r\n // Let it through — we intercept via event\r\n return;\r\n }\r\n });\r\n\r\n return removeMw;\r\n }, [engine]);\r\n\r\n // ── Controlled mode: sync controlled props to engine ──\r\n useEffect(() => {\r\n if (controlledSortModel !== undefined && engine) {\r\n engine.api.setSortModel(controlledSortModel);\r\n }\r\n }, [controlledSortModel, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledFilterModel !== undefined && engine) {\r\n engine.api.setFilterModel(controlledFilterModel as any);\r\n }\r\n }, [controlledFilterModel, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledCurrentPage !== undefined && engine) {\r\n engine.api.paginationGoToPage(controlledCurrentPage);\r\n }\r\n }, [controlledCurrentPage, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledSelectedRowIds !== undefined && engine) {\r\n engine.commandBus.dispatch('selection:set', {\r\n selectedRowIds: new Set(controlledSelectedRowIds),\r\n });\r\n }\r\n }, [controlledSelectedRowIds, engine]);\r\n\r\n // ── Event bridge: core events → React callbacks ──\r\n const eventCallbacksRef = useRef({\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n });\r\n eventCallbacksRef.current = {\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n };\r\n\r\n useEffect(() => {\r\n if (!engine) return;\r\n const eb = engine.eventBus;\r\n const cbs = () => eventCallbacksRef.current;\r\n\r\n const unsubs = [\r\n eb.on('rowData:changed', (e) => cbs().onRowDataChanged?.(e)),\r\n eb.on('selection:changed', (e) => {\r\n cbs().onSelectionChanged?.(e);\r\n // Controlled mode: notify parent of selection change\r\n controlledCallbacksRef.current.onSelectedRowIdsChange?.(\r\n engine.store.getState().selection.selectedRowIds,\r\n (e as any).source ?? 'api',\r\n );\r\n }),\r\n eb.on('column:sort:changed', (e) => {\r\n cbs().onSortChanged?.(e);\r\n // Controlled mode: notify parent of sort change\r\n controlledCallbacksRef.current.onSortModelChange?.(e.sortModel);\r\n }),\r\n eb.on('filter:changed', (e) => {\r\n cbs().onFilterChanged?.(e);\r\n controlledCallbacksRef.current.onFilterModelChange?.(e.filterModel);\r\n }),\r\n eb.on('cell:valueChanged', (e) => cbs().onCellValueChanged?.(e)),\r\n eb.on('cell:clicked', (e) => cbs().onCellClicked?.(e)),\r\n eb.on('cell:doubleClicked', (e) => cbs().onCellDoubleClicked?.(e)),\r\n eb.on('row:clicked', (e) => cbs().onRowClicked?.(e)),\r\n eb.on('cell:editingStarted', (e) => cbs().onCellEditingStarted?.(e)),\r\n eb.on('cell:editingStopped', (e) => cbs().onCellEditingStopped?.(e)),\r\n eb.on('pagination:changed', (e) => {\r\n cbs().onPaginationChanged?.(e);\r\n controlledCallbacksRef.current.onCurrentPageChange?.(e.currentPage);\r\n }),\r\n eb.on('column:resized', (e) => cbs().onColumnResized?.(e)),\r\n ];\r\n\r\n return () => unsubs.forEach((u) => u());\r\n }, [engine]);\r\n\r\n // ── Fire onGridReady ──\r\n useEffect(() => {\r\n if (engine) {\r\n onGridReady?.(engine.api);\r\n }\r\n }, [engine]); // eslint-disable-line -- intentional dependency omission\r\n\r\n // ── Container style ──\r\n const style: CSSProperties = {\r\n height: typeof height === 'number' ? `${height}px` : height,\r\n width: typeof width === 'number' ? `${width}px` : width,\r\n ...containerStyle,\r\n };\r\n\r\n // ── Context value (stable reference) ──\r\n const contextValue = useMemo<GridContextValue<TData> | null>(\r\n () => (engine ? { engine, api: engine.api, rootElement } : null),\r\n [engine, rootElement],\r\n );\r\n\r\n // ── Before engine is ready (first render before useEffect), render only the container ──\r\n if (!engine || !contextValue) {\r\n return (\r\n <GridErrorBoundary>\r\n <div\r\n ref={containerRef}\r\n className={`gs-container ${containerClass ?? ''}`.trim()}\r\n style={style}\r\n />\r\n </GridErrorBoundary>\r\n );\r\n }\r\n\r\n return (\r\n <GridErrorBoundary>\r\n <GridContext.Provider value={contextValue as GridContextValue}>\r\n {children}\r\n <div\r\n ref={containerRef}\r\n className={`gs-container ${containerClass ?? ''}`.trim()}\r\n style={style}\r\n />\r\n <PortalManager\r\n engine={engine}\r\n api={engine.api}\r\n columns={reactColumns}\r\n rootElement={rootElement}\r\n contextMenuComponent={contextMenu}\r\n />\r\n </GridContext.Provider>\r\n </GridErrorBoundary>\r\n );\r\n}\r\n","// ─── useGridApi Hook ───\n// Access the GridApi from context.\n\nimport type { GridApi } from '@gridstorm/core';\nimport { useGridContext } from '../context';\n\n/**\n * Access the GridApi instance.\n * Must be used within a `<GridStorm>` component.\n */\nexport function useGridApi<TData = any>(): GridApi<TData> {\n return useGridContext<TData>().api;\n}\n","// ─── useGridState Hook ───\r\n// Selector-based reactive state subscription via useSyncExternalStore.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { GridState } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\n/**\r\n * Subscribe to grid state changes with a selector.\r\n * Re-renders only when the selected value changes (reference equality).\r\n *\r\n * @example\r\n * ```tsx\r\n * const rowCount = useGridState(state => state.displayedRowIds.length);\r\n * const sortModel = useGridState(state => state.sortModel);\r\n * ```\r\n */\r\nexport function useGridState<TData = any, TResult = any>(\r\n selector: (state: GridState<TData>) => TResult,\r\n): TResult {\r\n const { engine } = useGridContext<TData>();\r\n\r\n // Memoize getSnapshot so useSyncExternalStore doesn't re-subscribe every render\r\n const getSnapshot = useCallback(\r\n () => selector(engine.store.getState() as GridState<TData>),\r\n [selector, engine],\r\n );\r\n\r\n return useSyncExternalStore(\r\n (onStoreChange) => engine.store.subscribe(onStoreChange),\r\n getSnapshot,\r\n getSnapshot,\r\n );\r\n}\r\n","// ─── useGridSelection Hook ───\r\n// Selection state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { RowNode } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridSelectionResult<TData = any> {\r\n /** Set of selected row IDs. */\r\n selectedRowIds: Set<string>;\r\n /** Number of selected rows. */\r\n selectedCount: number;\r\n /** Get selected row data objects. */\r\n getSelectedRows: () => TData[];\r\n /** Get selected RowNode objects. */\r\n getSelectedNodes: () => RowNode<TData>[];\r\n /** Check if a specific row is selected. */\r\n isRowSelected: (rowId: string) => boolean;\r\n /** Select all visible rows. */\r\n selectAll: () => void;\r\n /** Deselect all rows. */\r\n deselectAll: () => void;\r\n}\r\n\r\n/**\r\n * Access selection state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { selectedCount, selectAll, deselectAll, isRowSelected } = useGridSelection();\r\n * ```\r\n */\r\nexport function useGridSelection<TData = any>(): GridSelectionResult<TData> {\r\n const { engine, api } = useGridContext<TData>();\r\n\r\n const getSelectionSnapshot = useCallback(() => engine.store.getState().selection.selectedRowIds, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const selectedRowIds = useSyncExternalStore(\r\n subscribe,\r\n getSelectionSnapshot,\r\n getSelectionSnapshot,\r\n );\r\n\r\n const selectedCount = selectedRowIds.size;\r\n\r\n const isRowSelected = useCallback(\r\n (rowId: string) =>\r\n engine.store.getState().selection.selectedRowIds.has(rowId),\r\n [engine],\r\n );\r\n\r\n const getSelectedRows = useCallback(() => api.getSelectedRows(), [api]);\r\n const getSelectedNodes = useCallback(() => api.getSelectedNodes(), [api]);\r\n const selectAll = useCallback(() => api.selectAll(), [api]);\r\n const deselectAll = useCallback(() => api.deselectAll(), [api]);\r\n\r\n return {\r\n selectedRowIds,\r\n selectedCount,\r\n getSelectedRows,\r\n getSelectedNodes,\r\n isRowSelected,\r\n selectAll,\r\n deselectAll,\r\n };\r\n}\r\n","// ─── useGridSort Hook ───\r\n// Sort model state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { SortModelItem } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridSortResult {\r\n /** Current sort model. */\r\n sortModel: SortModelItem[];\r\n /** Whether any sort is active. */\r\n isSorted: boolean;\r\n /** Set the sort model directly. */\r\n setSortModel: (model: SortModelItem[]) => void;\r\n /** Toggle sort on a column. */\r\n toggleSort: (colId: string, multiSort?: boolean) => void;\r\n /** Clear all sort. */\r\n clearSort: () => void;\r\n}\r\n\r\n/**\r\n * Access sort state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();\r\n * ```\r\n */\r\nexport function useGridSort(): GridSortResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getSortSnapshot = useCallback(() => engine.store.getState().sortModel, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const sortModel = useSyncExternalStore(\r\n subscribe,\r\n getSortSnapshot,\r\n getSortSnapshot,\r\n );\r\n\r\n const isSorted = sortModel.length > 0;\r\n\r\n const setSortModel = useCallback(\r\n (model: SortModelItem[]) => api.setSortModel(model),\r\n [api],\r\n );\r\n\r\n const toggleSort = useCallback(\r\n (colId: string, multiSort = false) => {\r\n engine.commandBus.dispatch('sort:toggle', { colId, multiSort });\r\n },\r\n [engine],\r\n );\r\n\r\n const clearSort = useCallback(() => api.setSortModel([]), [api]);\r\n\r\n return { sortModel, isSorted, setSortModel, toggleSort, clearSort };\r\n}\r\n","// ─── useGridFilter Hook ───\r\n// Filter model state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { FilterModel } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridFilterResult {\r\n /** Current filter model (keyed by column ID). */\r\n filterModel: Record<string, FilterModel>;\r\n /** Current quick filter text. */\r\n quickFilterText: string;\r\n /** Whether any filter is active. */\r\n isFiltered: boolean;\r\n /** Set the filter model. */\r\n setFilterModel: (model: Record<string, FilterModel>) => void;\r\n /** Set quick filter text. */\r\n setQuickFilter: (text: string) => void;\r\n /** Clear all filters. */\r\n clearFilters: () => void;\r\n}\r\n\r\n/**\r\n * Access filter state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();\r\n * ```\r\n */\r\nexport function useGridFilter(): GridFilterResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getFilterSnapshot = useCallback(() => engine.store.getState().filterModel, [engine]);\r\n const getQuickFilterSnapshot = useCallback(() => engine.store.getState().quickFilterText, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const filterModel = useSyncExternalStore(\r\n subscribe,\r\n getFilterSnapshot,\r\n getFilterSnapshot,\r\n );\r\n\r\n const quickFilterText = useSyncExternalStore(\r\n subscribe,\r\n getQuickFilterSnapshot,\r\n getQuickFilterSnapshot,\r\n );\r\n\r\n const isFiltered =\r\n Object.keys(filterModel).length > 0 || quickFilterText.length > 0;\r\n\r\n const setFilterModel = useCallback(\r\n (model: Record<string, FilterModel>) => api.setFilterModel(model),\r\n [api],\r\n );\r\n\r\n const setQuickFilter = useCallback(\r\n (text: string) => api.setQuickFilter(text),\r\n [api],\r\n );\r\n\r\n const clearFilters = useCallback(() => {\r\n api.setFilterModel({});\r\n api.setQuickFilter('');\r\n }, [api]);\r\n\r\n return {\r\n filterModel,\r\n quickFilterText,\r\n isFiltered,\r\n setFilterModel,\r\n setQuickFilter,\r\n clearFilters,\r\n };\r\n}\r\n","// ─── useGridPagination Hook ───\r\n// Pagination state and navigation actions.\r\n\r\nimport { useSyncExternalStore, useCallback, useMemo } from 'react';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridPaginationResult {\r\n /** Current page (0-indexed). */\r\n currentPage: number;\r\n /** Total number of pages. */\r\n totalPages: number;\r\n /** Rows per page. */\r\n pageSize: number;\r\n /** Total row count (after filtering). */\r\n totalRows: number;\r\n /** Is there a next page? */\r\n hasNextPage: boolean;\r\n /** Is there a previous page? */\r\n hasPreviousPage: boolean;\r\n /** Go to a specific page. */\r\n goToPage: (page: number) => void;\r\n /** Go to next page. */\r\n nextPage: () => void;\r\n /** Go to previous page. */\r\n previousPage: () => void;\r\n /** Go to first page. */\r\n firstPage: () => void;\r\n /** Go to last page. */\r\n lastPage: () => void;\r\n}\r\n\r\n/**\r\n * Access pagination state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { currentPage, totalPages, nextPage, previousPage } = useGridPagination();\r\n * ```\r\n */\r\nexport function useGridPagination(): GridPaginationResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getPaginationSnapshot = useCallback(() => engine.store.getState().pagination, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const paginationState = useSyncExternalStore(\r\n subscribe,\r\n getPaginationSnapshot,\r\n getPaginationSnapshot,\r\n );\r\n\r\n const { currentPage, pageSize, totalRows } = paginationState;\r\n const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));\r\n const hasNextPage = currentPage < totalPages - 1;\r\n const hasPreviousPage = currentPage > 0;\r\n\r\n const goToPage = useCallback(\r\n (page: number) => api.paginationGoToPage(page),\r\n [api],\r\n );\r\n\r\n const nextPage = useCallback(() => {\r\n if (hasNextPage) api.paginationGoToPage(currentPage + 1);\r\n }, [api, currentPage, hasNextPage]);\r\n\r\n const previousPage = useCallback(() => {\r\n if (hasPreviousPage) api.paginationGoToPage(currentPage - 1);\r\n }, [api, currentPage, hasPreviousPage]);\r\n\r\n const firstPage = useCallback(() => api.paginationGoToPage(0), [api]);\r\n\r\n const lastPage = useCallback(\r\n () => api.paginationGoToPage(totalPages - 1),\r\n [api, totalPages],\r\n );\r\n\r\n return useMemo(\r\n () => ({\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n }),\r\n [\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n ],\r\n );\r\n}\r\n","// ─── useGridEvent Hook ───\n// Subscribe to typed grid events.\n\nimport { useEffect, useRef } from 'react';\nimport type { GridEventMap } from '@gridstorm/core';\nimport { useGridContext } from '../context';\n\n/**\n * Subscribe to a specific grid event.\n * Handler ref prevents stale closures without re-subscribing.\n *\n * @example\n * ```tsx\n * useGridEvent('cell:clicked', (event) => {\n * console.log('Clicked cell:', event.colId, event.value);\n * });\n * ```\n */\nexport function useGridEvent<\n TData = any,\n K extends keyof GridEventMap<TData> = any,\n>(\n event: K,\n handler: (payload: GridEventMap<TData>[K]) => void,\n): void {\n const { engine } = useGridContext<TData>();\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const unsub = engine.eventBus.on(event as any, (payload: any) => {\n handlerRef.current(payload);\n });\n return unsub;\n }, [engine, event]);\n}\n","// ─── useGridColumn Hook ───\r\n// Column state and manipulation actions.\r\n\r\nimport { useSyncExternalStore, useCallback, useMemo } from 'react';\r\nimport type { ColumnState, PinnedPosition } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridColumnResult {\r\n /** All columns (including hidden). */\r\n allColumns: ColumnState[];\r\n /** Only visible columns. */\r\n visibleColumns: ColumnState[];\r\n /** Set a column's visibility. */\r\n setColumnVisible: (colId: string, visible: boolean) => void;\r\n /** Set a column's width. */\r\n setColumnWidth: (colId: string, width: number) => void;\r\n /** Move a column to a new index. */\r\n moveColumn: (colId: string, toIndex: number) => void;\r\n /** Pin a column. */\r\n setColumnPinned: (colId: string, pinned: PinnedPosition) => void;\r\n /** Get a single column by ID. */\r\n getColumn: (colId: string) => ColumnState | undefined;\r\n}\r\n\r\n/**\r\n * Access column state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { visibleColumns, setColumnVisible, setColumnWidth } = useGridColumn();\r\n * ```\r\n */\r\nexport function useGridColumn(): GridColumnResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getColumnsSnapshot = useCallback(() => engine.store.getState().columns, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const allColumns = useSyncExternalStore(\r\n subscribe,\r\n getColumnsSnapshot,\r\n getColumnsSnapshot,\r\n );\r\n\r\n const visibleColumns = useMemo(\r\n () => allColumns.filter((c) => !c.hide),\r\n [allColumns],\r\n );\r\n\r\n const setColumnVisible = useCallback(\r\n (colId: string, visible: boolean) => api.setColumnVisible(colId, visible),\r\n [api],\r\n );\r\n\r\n const setColumnWidth = useCallback(\r\n (colId: string, width: number) => api.setColumnWidth(colId, width),\r\n [api],\r\n );\r\n\r\n const moveColumn = useCallback(\r\n (colId: string, toIndex: number) => api.moveColumn(colId, toIndex),\r\n [api],\r\n );\r\n\r\n const setColumnPinned = useCallback(\r\n (colId: string, pinned: PinnedPosition) =>\r\n api.setColumnPinned(colId, pinned),\r\n [api],\r\n );\r\n\r\n const getColumn = useCallback(\r\n (colId: string) => api.getColumn(colId),\r\n [api],\r\n );\r\n\r\n return {\r\n allColumns,\r\n visibleColumns,\r\n setColumnVisible,\r\n setColumnWidth,\r\n moveColumn,\r\n setColumnPinned,\r\n getColumn,\r\n };\r\n}\r\n"]}
|
package/dist/index.js
CHANGED
|
@@ -650,7 +650,7 @@ function GridStorm(props) {
|
|
|
650
650
|
theme
|
|
651
651
|
}),
|
|
652
652
|
// Only recreate config on structural changes
|
|
653
|
-
// eslint-disable-next-line
|
|
653
|
+
// eslint-disable-next-line -- intentional dependency omission
|
|
654
654
|
[coreColumns, plugins, rowModelType, getRowId]
|
|
655
655
|
);
|
|
656
656
|
const engine = useGridEngine(config);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.ts","../src/renderers/ReactCellRenderer.ts","../src/renderers/ReactHeaderRenderer.ts","../src/portals/CellRendererPortal.tsx","../src/portals/CellEditorPortal.tsx","../src/portals/ContextMenuPortal.tsx","../src/portals/PortalManager.tsx","../src/ErrorBoundary.tsx","../src/GridStorm.tsx","../src/hooks/useGridApi.ts","../src/hooks/useGridState.ts","../src/hooks/useGridSelection.ts","../src/hooks/useGridSort.ts","../src/hooks/useGridFilter.ts","../src/hooks/useGridPagination.ts","../src/hooks/useGridEvent.ts","../src/hooks/useGridColumn.ts"],"names":["Component","jsx","useRef","useEffect","useState","useCallback","jsxs","useSyncExternalStore","useMemo"],"mappings":"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","file":"index.js","sourcesContent":["// ─── Grid Context ───\n// Provides the engine, API, and metadata to all child hooks and components.\n\nimport { createContext, useContext } from 'react';\nimport type { GridEngine, GridApi } from '@gridstorm/core';\n\nexport interface GridContextValue<TData = any> {\n engine: GridEngine<TData>;\n api: GridApi<TData>;\n /** The root DOM element (.gs-root) of the grid. */\n rootElement: HTMLElement | null;\n}\n\nexport const GridContext = createContext<GridContextValue | null>(null);\n\n/**\n * Internal helper — gets grid context with null-check.\n * All public hooks use this internally.\n */\nexport function useGridContext<TData = any>(): GridContextValue<TData> {\n const ctx = useContext(GridContext);\n if (!ctx) {\n throw new Error(\n '[GridStorm] Hook must be used within a <GridStorm> component.',\n );\n }\n return ctx as GridContextValue<TData>;\n}\n","// ─── React Cell Renderer Marker ───\n// Wraps a React component so it can be used as a CellRendererFn.\n// The DomRenderer will receive an empty string (creating an empty cell),\n// and the PortalManager will detect the marker and portal the React\n// component into that cell.\n\nimport type { ReactCellRenderer } from '../types';\n\n/** Symbol marker for React cell renderers. */\nexport const REACT_CELL_RENDERER = Symbol.for('gridstorm:reactCellRenderer');\n\n/**\n * Wrap a React component to use as a cell renderer.\n *\n * @example\n * ```tsx\n * const StatusCell = ({ value }: CellRendererProps) => (\n * <span className={value ? 'active' : 'inactive'}>{value ? 'Yes' : 'No'}</span>\n * );\n *\n * const columns = [\n * { field: 'active', cellRenderer: reactCellRenderer(StatusCell) },\n * ];\n * ```\n */\nexport function reactCellRenderer<TData = any, TValue = any>(\n Component: ReactCellRenderer<TData, TValue>,\n): any {\n // Return a CellRendererFn that outputs empty string.\n // The DomRenderer will create an empty cell; the PortalManager portals React content into it.\n const fn = () => '';\n (fn as any)[REACT_CELL_RENDERER] = Component;\n return fn;\n}\n\n/** Check if a cellRenderer is a wrapped React component. */\nexport function isReactCellRenderer(fn: unknown): boolean {\n return typeof fn === 'function' && REACT_CELL_RENDERER in (fn as any);\n}\n\n/** Extract the React component from a wrapped cell renderer. */\nexport function getReactCellComponent<TData = any, TValue = any>(\n fn: unknown,\n): ReactCellRenderer<TData, TValue> | null {\n if (isReactCellRenderer(fn)) {\n return (fn as any)[REACT_CELL_RENDERER];\n }\n return null;\n}\n","// ─── React Header Renderer Marker ───\n// Same pattern as ReactCellRenderer but for header cells.\n\nimport type { ReactHeaderRenderer } from '../types';\n\n/** Symbol marker for React header renderers. */\nexport const REACT_HEADER_RENDERER = Symbol.for('gridstorm:reactHeaderRenderer');\n\n/**\n * Wrap a React component to use as a header renderer.\n *\n * @example\n * ```tsx\n * const SortHeader = ({ displayName, sortDirection, onSortRequested }: HeaderRendererProps) => (\n * <div onClick={() => onSortRequested(false)}>\n * {displayName} {sortDirection === 'asc' ? '▲' : sortDirection === 'desc' ? '▼' : ''}\n * </div>\n * );\n *\n * const columns = [\n * { field: 'name', headerRenderer: reactHeaderRenderer(SortHeader) },\n * ];\n * ```\n */\nexport function reactHeaderRenderer<TData = any>(\n Component: ReactHeaderRenderer<TData>,\n): any {\n const fn = () => '';\n (fn as any)[REACT_HEADER_RENDERER] = Component;\n return fn;\n}\n\n/** Check if a headerRenderer is a wrapped React component. */\nexport function isReactHeaderRenderer(fn: unknown): boolean {\n return typeof fn === 'function' && REACT_HEADER_RENDERER in (fn as any);\n}\n\n/** Extract the React component from a wrapped header renderer. */\nexport function getReactHeaderComponent<TData = any>(\n fn: unknown,\n): ReactHeaderRenderer<TData> | null {\n if (isReactHeaderRenderer(fn)) {\n return (fn as any)[REACT_HEADER_RENDERER];\n }\n return null;\n}\n","// ─── Cell Renderer Portal ───\n// Memoized wrapper for individual React cell renderer portals.\n// Custom comparator prevents re-renders when cell data hasn't changed.\n\nimport { memo } from 'react';\nimport type { ReactCellRenderer, CellRendererProps } from '../types';\n\ninterface CellRendererPortalProps<TData = any, TValue = any> {\n Component: ReactCellRenderer<TData, TValue>;\n rendererProps: CellRendererProps<TData, TValue>;\n nodeVersion: number;\n}\n\nfunction CellRendererPortalInner<TData = any, TValue = any>(\n props: CellRendererPortalProps<TData, TValue>,\n) {\n const { Component, rendererProps } = props;\n return <Component {...rendererProps} />;\n}\n\n/** Memoized cell renderer portal — only re-renders when value or version changes. */\nexport const CellRendererPortal = memo(\n CellRendererPortalInner,\n (prev, next) =>\n prev.nodeVersion === next.nodeVersion &&\n prev.rendererProps.value === next.rendererProps.value &&\n prev.rendererProps.rowIndex === next.rendererProps.rowIndex &&\n prev.rendererProps.colId === next.rendererProps.colId,\n) as typeof CellRendererPortalInner;\n","// ─── Cell Editor Portal ───\n// Renders a React cell editor component as an absolutely-positioned\n// overlay on top of the editing cell.\n\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport type { GridEngine, GridApi } from '@gridstorm/core';\nimport type { ReactCellEditor, EditorPortalState } from '../types';\n\ninterface CellEditorPortalProps<TData = any> {\n state: EditorPortalState;\n api: GridApi<TData>;\n engine: GridEngine<TData>;\n EditorComponent: ReactCellEditor<TData>;\n editorParams: Record<string, unknown>;\n gridRootRect: DOMRect;\n}\n\nexport function CellEditorPortal<TData = any>(props: CellEditorPortalProps<TData>) {\n const { state, api, engine, EditorComponent, editorParams, gridRootRect } = props;\n const { editing, cellRect } = state;\n const [value, setValue] = useState(editing.value);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const onValueChange = useCallback(\n (newValue: any) => {\n setValue(newValue);\n engine.commandBus.dispatch('editing:setValue', { value: newValue });\n },\n [engine],\n );\n\n const stopEditing = useCallback(\n (cancel?: boolean) => {\n api.stopEditing(cancel);\n },\n [api],\n );\n\n // Auto-focus the editor on mount\n useEffect(() => {\n requestAnimationFrame(() => {\n const el = containerRef.current;\n if (!el) return;\n const focusable = el.querySelector<HTMLElement>(\n 'input, textarea, select, [tabindex]',\n );\n focusable?.focus();\n });\n }, []);\n\n const column = engine.store\n .getState()\n .columns.find((c) => c.colId === editing.colId)!;\n\n const node = engine.store.getState().rowNodes.get(editing.rowId);\n\n // Position relative to the grid root\n const top = cellRect.top - gridRootRect.top;\n const left = cellRect.left - gridRootRect.left;\n\n return (\n <div\n ref={containerRef}\n className=\"gs-editor-portal\"\n style={{\n position: 'absolute',\n top,\n left,\n width: cellRect.width,\n height: cellRect.height,\n zIndex: 10,\n boxSizing: 'border-box',\n background: 'var(--gs-color-cell-editing-bg, #fff)',\n border: '2px solid var(--gs-color-cell-editing-border, #2196f3)',\n }}\n >\n <EditorComponent\n value={value}\n data={node?.data as TData}\n colId={editing.colId}\n rowId={editing.rowId}\n column={column}\n editorParams={editorParams}\n onValueChange={onValueChange}\n stopEditing={stopEditing}\n api={api}\n />\n </div>\n );\n}\n","// ─── Context Menu Portal ───\n// Renders a user-provided context menu component at the right-click position.\n\nimport { useEffect, useRef } from 'react';\nimport type { ContextMenuProps, ReactContextMenu } from '../types';\n\ninterface ContextMenuPortalProps<TData = any> {\n x: number;\n y: number;\n menuProps: ContextMenuProps<TData>;\n Component: ReactContextMenu<TData>;\n}\n\nexport function ContextMenuPortal<TData = any>(\n props: ContextMenuPortalProps<TData>,\n) {\n const { x, y, menuProps, Component } = props;\n const ref = useRef<HTMLDivElement>(null);\n\n // Close on click outside\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n menuProps.closeMenu();\n }\n };\n // Use setTimeout so the current click doesn't immediately close the menu\n const id = setTimeout(() => {\n document.addEventListener('mousedown', handler);\n }, 0);\n return () => {\n clearTimeout(id);\n document.removeEventListener('mousedown', handler);\n };\n }, [menuProps]);\n\n // Close on Escape\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') menuProps.closeMenu();\n };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [menuProps]);\n\n return (\n <div\n ref={ref}\n className=\"gs-context-menu-portal\"\n style={{\n position: 'absolute',\n top: y,\n left: x,\n zIndex: 100,\n minWidth: 160,\n }}\n >\n <Component {...menuProps} />\n </div>\n );\n}\n","// ─── Portal Manager ───\r\n// Central orchestrator for all React portals: cell renderers, header\r\n// renderers, editors, and context menus.\r\n//\r\n// Uses a MutationObserver on .gs-body to detect when DomRenderer\r\n// adds/removes row elements, then portals React content into wrapper\r\n// divs inside cells that have React renderers.\r\n//\r\n// KEY DESIGN: We never portal directly into DomRenderer-managed cells.\r\n// Instead, we create a wrapper <div style=\"display:contents\"> inside each\r\n// cell and portal into that wrapper. This prevents crashes when DomRenderer\r\n// destroys/recycles cells — the wrapper is detached but still maintains\r\n// its React children, so React can safely unmount.\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useState,\r\n useCallback,\r\n useSyncExternalStore,\r\n} from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport type { GridEngine, GridApi, ColumnState, RowNode } from '@gridstorm/core';\r\nimport { getValueFromData } from '@gridstorm/core';\r\nimport type {\r\n ReactColumnDef,\r\n CellRendererProps,\r\n HeaderRendererProps,\r\n EditorPortalState,\r\n ContextMenuProps,\r\n ReactContextMenu,\r\n ReactCellEditor,\r\n} from '../types';\r\nimport { getReactCellComponent, isReactCellRenderer } from '../renderers/ReactCellRenderer';\r\nimport { getReactHeaderComponent, isReactHeaderRenderer } from '../renderers/ReactHeaderRenderer';\r\nimport { CellRendererPortal } from './CellRendererPortal';\r\nimport { CellEditorPortal } from './CellEditorPortal';\r\nimport { ContextMenuPortal } from './ContextMenuPortal';\r\n\r\nexport interface PortalManagerProps<TData = any> {\r\n engine: GridEngine<TData>;\r\n api: GridApi<TData>;\r\n columns: ReactColumnDef<TData>[];\r\n rootElement: HTMLElement | null;\r\n contextMenuComponent?: ReactContextMenu<TData>;\r\n}\r\n\r\n// ── Portal wrapper attribute ──\r\n// Used to identify wrapper divs we've created inside cells.\r\nconst WRAPPER_ATTR = 'data-gs-portal';\r\n\r\n// ── Cell renderer portal entry ──\r\ninterface CellPortalEntry<TData = any> {\r\n key: string;\r\n /** The wrapper div inside the cell (React-owned, safe to portal into) */\r\n container: HTMLElement;\r\n component: any;\r\n props: CellRendererProps<TData>;\r\n nodeVersion: number;\r\n}\r\n\r\n// ── Header renderer portal entry ──\r\ninterface HeaderPortalEntry {\r\n key: string;\r\n /** The wrapper div inside the header cell */\r\n container: HTMLElement;\r\n element: any;\r\n}\r\n\r\n// ── Context menu state ──\r\ninterface ContextMenuState<TData = any> {\r\n x: number;\r\n y: number;\r\n menuProps: ContextMenuProps<TData>;\r\n}\r\n\r\n// ── Helper: get or create a stable wrapper div inside a cell ──\r\n// The wrapper uses display:contents so it's layout-transparent.\r\n// When DomRenderer destroys the cell, the wrapper is detached but\r\n// still maintains its children — React can safely unmount from it.\r\nfunction getOrCreateWrapper(cell: HTMLElement): HTMLElement {\r\n // Check direct children only (not descendants) for existing wrapper\r\n for (let i = 0; i < cell.children.length; i++) {\r\n const child = cell.children[i] as HTMLElement;\r\n if (child.hasAttribute(WRAPPER_ATTR)) {\r\n return child;\r\n }\r\n }\r\n // Create new wrapper\r\n const wrapper = document.createElement('div');\r\n wrapper.setAttribute(WRAPPER_ATTR, '');\r\n wrapper.style.display = 'contents';\r\n cell.appendChild(wrapper);\r\n return wrapper;\r\n}\r\n\r\nexport function PortalManager<TData = any>(props: PortalManagerProps<TData>) {\r\n const { engine, api, columns, rootElement, contextMenuComponent } = props;\r\n\r\n // ── Portal state ──\r\n const [cellPortals, setCellPortals] = useState<Map<string, CellPortalEntry<TData>>>(\r\n () => new Map(),\r\n );\r\n const [headerPortals, setHeaderPortals] = useState<Map<string, HeaderPortalEntry>>(\r\n () => new Map(),\r\n );\r\n const [editorPortal, setEditorPortal] = useState<EditorPortalState | null>(null);\r\n const [contextMenu, setContextMenu] = useState<ContextMenuState<TData> | null>(null);\r\n\r\n // Refs for stable access in callbacks\r\n const columnsRef = useRef(columns);\r\n columnsRef.current = columns;\r\n const engineRef = useRef(engine);\r\n engineRef.current = engine;\r\n\r\n // Track if we're currently scanning to prevent re-entrant scans\r\n const scanningRef = useRef(false);\r\n\r\n // ── Build lookup maps for which columns have React renderers ──\r\n const reactCellRendererMap = useRef(new Map<string, any>());\r\n const reactHeaderRendererMap = useRef(new Map<string, any>());\r\n const reactEditorMap = useRef(new Map<string, ReactCellEditor<TData>>());\r\n\r\n useEffect(() => {\r\n const cellMap = new Map<string, any>();\r\n const headerMap = new Map<string, any>();\r\n const editorMap = new Map<string, ReactCellEditor<TData>>();\r\n\r\n for (const col of columns) {\r\n const colId = (col as any).colId ?? col.field ?? '';\r\n if (col.cellRenderer && isReactCellRenderer(col.cellRenderer)) {\r\n cellMap.set(colId, getReactCellComponent(col.cellRenderer));\r\n }\r\n if (col.headerRenderer && isReactHeaderRenderer(col.headerRenderer)) {\r\n headerMap.set(colId, getReactHeaderComponent(col.headerRenderer));\r\n }\r\n if (col.cellEditorComponent) {\r\n editorMap.set(colId, col.cellEditorComponent);\r\n }\r\n }\r\n\r\n reactCellRendererMap.current = cellMap;\r\n reactHeaderRendererMap.current = headerMap;\r\n reactEditorMap.current = editorMap;\r\n }, [columns]);\r\n\r\n // ── Helper: build cell renderer props ──\r\n const buildCellProps = useCallback(\r\n (node: RowNode<TData>, col: ColumnState, rowIndex: number): CellRendererProps<TData> => {\r\n const colDef = col.originalDef;\r\n let value: any;\r\n if (colDef.valueGetter) {\r\n value = colDef.valueGetter({\r\n data: node.data,\r\n node,\r\n colDef,\r\n colId: col.colId,\r\n });\r\n } else {\r\n value = getValueFromData(node.data, col.field);\r\n }\r\n\r\n let formattedValue = value != null ? String(value) : '';\r\n if (colDef.valueFormatter) {\r\n formattedValue = colDef.valueFormatter({ value, data: node.data, node, colDef });\r\n }\r\n\r\n return {\r\n value,\r\n formattedValue,\r\n data: node.data,\r\n node,\r\n colDef,\r\n colId: col.colId,\r\n rowIndex,\r\n api,\r\n };\r\n },\r\n [api],\r\n );\r\n\r\n // ── Scan visible rows and create/update cell portals ──\r\n const scanVisibleRows = useCallback(() => {\r\n if (!rootElement || scanningRef.current) return;\r\n scanningRef.current = true;\r\n\r\n try {\r\n const bodyContainer = rootElement.querySelector('.gs-body');\r\n if (!bodyContainer) return;\r\n\r\n const state = engineRef.current.store.getState();\r\n const cellRenderers = reactCellRendererMap.current;\r\n if (cellRenderers.size === 0) return;\r\n\r\n const newPortals = new Map<string, CellPortalEntry<TData>>();\r\n const rowElements = bodyContainer.querySelectorAll<HTMLElement>('.gs-row');\r\n\r\n // Pre-build O(1) lookup maps to avoid O(n) indexOf / find in hot path\r\n const rowIdIndexMap = new Map<string, number>();\r\n for (let i = 0; i < state.displayedRowIds.length; i++) {\r\n rowIdIndexMap.set(state.displayedRowIds[i]!, i);\r\n }\r\n const columnMap = new Map<string, ColumnState>();\r\n for (const col of state.columns) {\r\n columnMap.set(col.colId, col);\r\n }\r\n\r\n for (const rowEl of rowElements) {\r\n const rowId = rowEl.getAttribute('data-row-id');\r\n if (!rowId) continue;\r\n\r\n const node = state.rowNodes.get(rowId);\r\n if (!node) continue;\r\n\r\n const cells = rowEl.querySelectorAll<HTMLElement>('.gs-cell');\r\n for (const cellEl of cells) {\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!colId || !cellRenderers.has(colId)) continue;\r\n\r\n const key = `${rowId}:${colId}`;\r\n const Component = cellRenderers.get(colId)!;\r\n const colState = columnMap.get(colId);\r\n if (!colState) continue;\r\n\r\n const rowIndex = rowIdIndexMap.get(rowId) ?? -1;\r\n const rendererProps = buildCellProps(node, colState, rowIndex);\r\n\r\n // Get or create a stable wrapper div inside the cell.\r\n // We portal into the wrapper, NOT the cell directly.\r\n // This prevents crashes when DomRenderer destroys/recycles cells.\r\n const wrapper = getOrCreateWrapper(cellEl);\r\n\r\n newPortals.set(key, {\r\n key,\r\n container: wrapper,\r\n component: Component,\r\n props: rendererProps,\r\n nodeVersion: node.version,\r\n });\r\n }\r\n }\r\n\r\n setCellPortals(newPortals);\r\n } finally {\r\n scanningRef.current = false;\r\n }\r\n }, [rootElement, buildCellProps]);\r\n\r\n // ── Scan header cells for React header renderers ──\r\n const scanHeaderCells = useCallback(() => {\r\n if (!rootElement) return;\r\n const headerRenderers = reactHeaderRendererMap.current;\r\n if (headerRenderers.size === 0) return;\r\n\r\n const headerContainer = rootElement.querySelector('.gs-header');\r\n if (!headerContainer) return;\r\n\r\n const state = engineRef.current.store.getState();\r\n const newPortals = new Map<string, HeaderPortalEntry>();\r\n\r\n const headerCells = headerContainer.querySelectorAll<HTMLElement>('.gs-header-cell');\r\n for (const cellEl of headerCells) {\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!colId || !headerRenderers.has(colId)) continue;\r\n\r\n const Component = headerRenderers.get(colId)!;\r\n const colState = state.columns.find((c) => c.colId === colId);\r\n if (!colState) continue;\r\n\r\n const sortItem = state.sortModel.find((s) => s.colId === colId);\r\n\r\n const headerProps: HeaderRendererProps<TData> = {\r\n colDef: colState.originalDef,\r\n colId,\r\n displayName: colState.headerName,\r\n sortDirection: sortItem?.sort ?? null,\r\n sortIndex: colState.sortIndex,\r\n api,\r\n onSortRequested: (multiSort: boolean) => {\r\n engineRef.current.commandBus.dispatch('sort:toggle', { colId, multiSort });\r\n },\r\n };\r\n\r\n // Get or create a stable wrapper div inside the header cell.\r\n const wrapper = getOrCreateWrapper(cellEl);\r\n\r\n newPortals.set(colId, {\r\n key: colId,\r\n container: wrapper,\r\n element: <Component {...headerProps} />,\r\n });\r\n }\r\n\r\n setHeaderPortals(newPortals);\r\n }, [rootElement, api]);\r\n\r\n // ── MutationObserver on .gs-body for row add/remove ──\r\n useEffect(() => {\r\n if (!rootElement) return;\r\n const bodyContainer = rootElement.querySelector('.gs-body');\r\n if (!bodyContainer) return;\r\n\r\n const observer = new MutationObserver(() => {\r\n // When DomRenderer adds/removes rows, re-scan for portals\r\n scanVisibleRows();\r\n });\r\n\r\n observer.observe(bodyContainer, { childList: true });\r\n\r\n // Initial scan for already-rendered rows\r\n scanVisibleRows();\r\n scanHeaderCells();\r\n\r\n return () => observer.disconnect();\r\n }, [rootElement, scanVisibleRows, scanHeaderCells]);\r\n\r\n // ── Re-scan when state changes (sort, filter, data) ──\r\n const getVersionSnapshot = useCallback(() => engine.store.getVersion(), [engine]);\r\n const subscribeStore = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const stateVersion = useSyncExternalStore(\r\n subscribeStore,\r\n getVersionSnapshot,\r\n getVersionSnapshot,\r\n );\r\n\r\n useEffect(() => {\r\n scanVisibleRows();\r\n }, [stateVersion, scanVisibleRows]);\r\n\r\n // ── Re-scan headers when sort or columns change ──\r\n useEffect(() => {\r\n const unsubs = [\r\n engine.eventBus.on('column:sort:changed', () => {\r\n // Delay slightly to let DomRenderer recreate header cells first\r\n requestAnimationFrame(() => scanHeaderCells());\r\n }),\r\n engine.eventBus.on('columns:changed', () => {\r\n requestAnimationFrame(() => scanHeaderCells());\r\n }),\r\n ];\r\n return () => unsubs.forEach((u) => u());\r\n }, [engine, scanHeaderCells]);\r\n\r\n // ── Editor portal lifecycle ──\r\n useEffect(() => {\r\n const unsubStart = engine.eventBus.on(\r\n 'cell:editingStarted',\r\n (event: any) => {\r\n const { node, colId } = event;\r\n const editorComponent = reactEditorMap.current.get(colId);\r\n if (!editorComponent || !rootElement) return;\r\n\r\n // Find the cell element (CSS.escape prevents selector injection from rowId/colId)\r\n const cellEl = rootElement.querySelector<HTMLElement>(\r\n `.gs-row[data-row-id=\"${CSS.escape(node.id)}\"] .gs-cell[data-col-id=\"${CSS.escape(colId)}\"]`,\r\n );\r\n if (!cellEl) return;\r\n\r\n const state = engine.store.getState();\r\n const editing = state.editing;\r\n if (!editing) return;\r\n\r\n setEditorPortal({\r\n editing,\r\n cellElement: cellEl,\r\n cellRect: cellEl.getBoundingClientRect(),\r\n });\r\n },\r\n );\r\n\r\n const unsubStop = engine.eventBus.on('cell:editingStopped', () => {\r\n setEditorPortal(null);\r\n });\r\n\r\n return () => {\r\n unsubStart();\r\n unsubStop();\r\n };\r\n }, [engine, rootElement]);\r\n\r\n // ── Context menu ──\r\n useEffect(() => {\r\n if (!rootElement || !contextMenuComponent) return;\r\n\r\n const handler = (e: MouseEvent) => {\r\n e.preventDefault();\r\n const target = e.target as HTMLElement;\r\n const cellEl = target.closest<HTMLElement>('.gs-cell');\r\n const rowEl = target.closest<HTMLElement>('.gs-row');\r\n if (!cellEl || !rowEl) return;\r\n\r\n const rowId = rowEl.getAttribute('data-row-id');\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!rowId || !colId) return;\r\n\r\n const state = engine.store.getState();\r\n const node = state.rowNodes.get(rowId);\r\n if (!node) return;\r\n\r\n const colState = state.columns.find((c) => c.colId === colId);\r\n const value = colState\r\n ? getValueFromData(node.data, colState.field)\r\n : undefined;\r\n\r\n const rootRect = rootElement.getBoundingClientRect();\r\n const rowIndex = state.displayedRowIds.indexOf(rowId);\r\n\r\n setContextMenu({\r\n x: e.clientX - rootRect.left,\r\n y: e.clientY - rootRect.top,\r\n menuProps: {\r\n position: { rowIndex, colId },\r\n node,\r\n colId,\r\n value,\r\n api,\r\n closeMenu: () => setContextMenu(null),\r\n },\r\n });\r\n };\r\n\r\n rootElement.addEventListener('contextmenu', handler);\r\n return () => rootElement.removeEventListener('contextmenu', handler);\r\n }, [rootElement, contextMenuComponent, api, engine]);\r\n\r\n // ── Render portals ──\r\n return (\r\n <>\r\n {/* Cell renderer portals — portaled into wrapper divs, NOT cells directly */}\r\n {Array.from(cellPortals.values()).map((entry) =>\r\n createPortal(\r\n <CellRendererPortal\r\n key={entry.key}\r\n Component={entry.component}\r\n rendererProps={entry.props}\r\n nodeVersion={entry.nodeVersion}\r\n />,\r\n entry.container,\r\n entry.key,\r\n ),\r\n )}\r\n\r\n {/* Header renderer portals — portaled into wrapper divs in header cells */}\r\n {Array.from(headerPortals.values()).map((entry) =>\r\n createPortal(entry.element, entry.container, entry.key),\r\n )}\r\n\r\n {/* Editor portal */}\r\n {editorPortal && rootElement && (() => {\r\n const editorComponent = reactEditorMap.current.get(editorPortal.editing.colId);\r\n if (!editorComponent) return null;\r\n const colDef = columnsRef.current.find(\r\n (c) => ((c as any).colId ?? c.field) === editorPortal.editing.colId,\r\n );\r\n return createPortal(\r\n <CellEditorPortal\r\n state={editorPortal}\r\n api={api}\r\n engine={engine}\r\n EditorComponent={editorComponent}\r\n editorParams={(colDef?.cellEditorParams as Record<string, unknown>) ?? {}}\r\n gridRootRect={rootElement.getBoundingClientRect()}\r\n />,\r\n rootElement,\r\n 'gs-editor',\r\n );\r\n })()}\r\n\r\n {/* Context menu portal */}\r\n {contextMenu && contextMenuComponent && rootElement &&\r\n createPortal(\r\n <ContextMenuPortal\r\n x={contextMenu.x}\r\n y={contextMenu.y}\r\n menuProps={contextMenu.menuProps}\r\n Component={contextMenuComponent}\r\n />,\r\n rootElement,\r\n 'gs-context-menu',\r\n )}\r\n </>\r\n );\r\n}\r\n","// ─── GridStorm Error Boundary ───\n// Catches rendering errors in the grid and displays a fallback UI.\n\nimport { Component, type ReactNode, type ErrorInfo } from 'react';\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class GridErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state: ErrorBoundaryState = { hasError: false, error: null };\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n console.error('[GridStorm] Rendering error:', error, errorInfo.componentStack);\n }\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n return null;\n }\n return this.props.children;\n }\n}\n","// ─── GridStorm React Component ───\r\n// Production-grade React wrapper around the headless core engine.\r\n// Supports controlled + uncontrolled modes, React component cell/header\r\n// renderers via portals, event bridging, and comprehensive hooks.\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useMemo,\r\n useState,\r\n type CSSProperties,\r\n} from 'react';\r\nimport type {\r\n GridConfig,\r\n ColumnDef,\r\n GridEngine,\r\n} from '@gridstorm/core';\r\nimport { createGrid } from '@gridstorm/core';\r\nimport { DomRenderer } from '@gridstorm/dom-renderer';\r\nimport { GridContext, type GridContextValue } from './context';\r\nimport { PortalManager } from './portals/PortalManager';\r\nimport type { GridStormProps, ReactColumnDef } from './types';\r\nimport { GridErrorBoundary } from './ErrorBoundary';\r\n\r\n// ── useGridEngine hook (internal) ──\r\n// Uses useState + useEffect so that StrictMode's cleanup → remount cycle\r\n// creates a fresh engine each time instead of leaving a null ref.\r\n\r\nfunction useGridEngine<TData = any>(config: GridConfig<TData>): GridEngine<TData> | null {\r\n const [engine, setEngine] = useState<GridEngine<TData> | null>(null);\r\n const configRef = useRef(config);\r\n configRef.current = config;\r\n\r\n // Track whether the initial mount has completed so sync effects\r\n // don't double-set data that was already applied during createGrid.\r\n const rowDataMountedRef = useRef(false);\r\n const columnsMountedRef = useRef(false);\r\n\r\n // Create engine in useEffect so StrictMode can safely destroy + recreate\r\n useEffect(() => {\r\n const eng = createGrid(configRef.current);\r\n setEngine(eng);\r\n\r\n // Reset mounted flags when engine is (re)created\r\n rowDataMountedRef.current = false;\r\n columnsMountedRef.current = false;\r\n\r\n return () => {\r\n eng.destroy();\r\n setEngine(null);\r\n };\r\n }, []);\r\n\r\n // Sync rowData changes (skip the first run — createGrid already applied initial data)\r\n useEffect(() => {\r\n if (!engine) return;\r\n if (!rowDataMountedRef.current) {\r\n rowDataMountedRef.current = true;\r\n return;\r\n }\r\n if (config.rowData) {\r\n engine.api.setRowData(config.rowData);\r\n }\r\n }, [config.rowData, engine]);\r\n\r\n // Sync column changes (skip the first run — createGrid already applied initial columns)\r\n useEffect(() => {\r\n if (!engine) return;\r\n if (!columnsMountedRef.current) {\r\n columnsMountedRef.current = true;\r\n return;\r\n }\r\n if (config.columns) {\r\n engine.api.setColumnDefs(config.columns);\r\n }\r\n }, [config.columns, engine]);\r\n\r\n return engine;\r\n}\r\n\r\n// ── Column processing: convert ReactColumnDef[] → ColumnDef[] ──\r\n\r\nfunction processColumns<TData>(\r\n reactColumns: ReactColumnDef<TData>[],\r\n): ColumnDef<TData>[] {\r\n return reactColumns.map((col) => {\r\n const coreDef = { ...col } as any;\r\n\r\n // If cellRenderer is a React-wrapped renderer, keep the marker function\r\n // (it returns '' so DomRenderer creates empty cells; PortalManager handles rendering)\r\n // If it's a plain CellRendererFn, leave it as-is.\r\n // No conversion needed — the marker fn IS a valid CellRendererFn.\r\n\r\n // If headerRenderer is React-wrapped, same logic applies.\r\n\r\n // Remove React-only fields from the core column def\r\n delete coreDef.cellEditorComponent;\r\n\r\n return coreDef as ColumnDef<TData>;\r\n });\r\n}\r\n\r\n// ── Main Component ──\r\n\r\nexport function GridStorm<TData = any>(props: GridStormProps<TData>) {\r\n const {\r\n // GridConfig props\r\n columns: reactColumns,\r\n rowData,\r\n dataSource,\r\n rowModelType,\r\n getRowId,\r\n plugins,\r\n defaultColDef,\r\n rowHeight,\r\n headerHeight,\r\n domLayout,\r\n pinnedTopRowData,\r\n pinnedBottomRowData,\r\n suppressScrollX,\r\n suppressScrollY,\r\n rowSelection,\r\n editType,\r\n undoRedoCellEditing,\r\n pagination,\r\n paginationPageSize,\r\n animateRows,\r\n ariaLabel,\r\n locale,\r\n theme,\r\n // Controlled state props\r\n sortModel: controlledSortModel,\r\n onSortModelChange,\r\n filterModel: controlledFilterModel,\r\n onFilterModelChange,\r\n selectedRowIds: controlledSelectedRowIds,\r\n onSelectedRowIdsChange,\r\n currentPage: controlledCurrentPage,\r\n onCurrentPageChange,\r\n // Event props\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n // Renderer config props\r\n enableCellEditing,\r\n enableGrouping,\r\n groupIndent,\r\n checkboxSelection,\r\n checkboxColumnWidth,\r\n floatingFilter,\r\n floatingFilterDebounce,\r\n enablePagination,\r\n pageSizeOptions,\r\n // Component props\r\n height = 400,\r\n width = '100%',\r\n containerClass,\r\n containerStyle,\r\n contextMenu,\r\n children,\r\n // Rest are ignored (no HTML div passthrough to avoid TS errors)\r\n } = props;\r\n\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const rendererRef = useRef<DomRenderer | null>(null);\r\n const [rootElement, setRootElement] = useState<HTMLElement | null>(null);\r\n\r\n // ── Convert React columns to core columns ──\r\n const coreColumns = useMemo(\r\n () => processColumns(reactColumns),\r\n [reactColumns],\r\n );\r\n\r\n // ── Build core config (only depends on structural changes) ──\r\n const config = useMemo<GridConfig<TData>>(\r\n () => ({\r\n columns: coreColumns,\r\n rowData,\r\n dataSource,\r\n rowModelType,\r\n getRowId,\r\n plugins,\r\n defaultColDef,\r\n rowHeight,\r\n headerHeight,\r\n domLayout,\r\n pinnedTopRowData,\r\n pinnedBottomRowData,\r\n suppressScrollX,\r\n suppressScrollY,\r\n rowSelection,\r\n editType,\r\n undoRedoCellEditing,\r\n pagination,\r\n paginationPageSize,\r\n animateRows,\r\n ariaLabel,\r\n locale,\r\n theme,\r\n }),\r\n // Only recreate config on structural changes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [coreColumns, plugins, rowModelType, getRowId],\r\n );\r\n\r\n // ── Create grid engine ──\r\n const engine = useGridEngine<TData>(config);\r\n\r\n // ── Mount DOM renderer ──\r\n useEffect(() => {\r\n if (!containerRef.current || !engine) return;\r\n\r\n const renderer = new DomRenderer({\r\n container: containerRef.current,\r\n engine,\r\n enableCellEditing,\r\n enableGrouping,\r\n groupIndent,\r\n checkboxSelection,\r\n checkboxColumnWidth,\r\n floatingFilter,\r\n floatingFilterDebounce,\r\n enablePagination,\r\n pageSizeOptions,\r\n });\r\n renderer.mount();\r\n rendererRef.current = renderer;\r\n\r\n // Capture root element for portals\r\n const root = containerRef.current.querySelector<HTMLElement>('.gs-root');\r\n setRootElement(root);\r\n\r\n // Re-emit grid:ready now that the DOM renderer has mounted.\r\n // Plugins like column-resize, column-reorder, and context-menu\r\n // use requestAnimationFrame on grid:ready to inject DOM elements.\r\n // The original grid:ready fires during createGrid() before the\r\n // renderer exists, so those rAF callbacks find no DOM to work with.\r\n requestAnimationFrame(() => {\r\n engine.eventBus.emit('grid:ready', { api: engine.api });\r\n });\r\n\r\n return () => {\r\n renderer.destroy();\r\n rendererRef.current = null;\r\n setRootElement(null);\r\n };\r\n }, [engine]);\r\n\r\n // ── Controlled mode: install command bus middleware ──\r\n const controlledCallbacksRef = useRef({\r\n onSortModelChange,\r\n onFilterModelChange,\r\n onSelectedRowIdsChange,\r\n onCurrentPageChange,\r\n });\r\n controlledCallbacksRef.current = {\r\n onSortModelChange,\r\n onFilterModelChange,\r\n onSelectedRowIdsChange,\r\n onCurrentPageChange,\r\n };\r\n\r\n useEffect(() => {\r\n if (!engine) return;\r\n const removeMw = engine.commandBus.use((ctx) => {\r\n const cbs = controlledCallbacksRef.current;\r\n\r\n // Intercept sort commands in controlled mode\r\n if (ctx.commandType === 'sort:toggle' && cbs.onSortModelChange) {\r\n // Let the command execute to compute the new sort model,\r\n // then we'll intercept the result via the event listener\r\n return;\r\n }\r\n\r\n // Intercept selection in controlled mode\r\n if (ctx.commandType === 'selection:select' && cbs.onSelectedRowIdsChange) {\r\n // Let it through — we intercept via event\r\n return;\r\n }\r\n });\r\n\r\n return removeMw;\r\n }, [engine]);\r\n\r\n // ── Controlled mode: sync controlled props to engine ──\r\n useEffect(() => {\r\n if (controlledSortModel !== undefined && engine) {\r\n engine.api.setSortModel(controlledSortModel);\r\n }\r\n }, [controlledSortModel, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledFilterModel !== undefined && engine) {\r\n engine.api.setFilterModel(controlledFilterModel as any);\r\n }\r\n }, [controlledFilterModel, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledCurrentPage !== undefined && engine) {\r\n engine.api.paginationGoToPage(controlledCurrentPage);\r\n }\r\n }, [controlledCurrentPage, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledSelectedRowIds !== undefined && engine) {\r\n engine.commandBus.dispatch('selection:set', {\r\n selectedRowIds: new Set(controlledSelectedRowIds),\r\n });\r\n }\r\n }, [controlledSelectedRowIds, engine]);\r\n\r\n // ── Event bridge: core events → React callbacks ──\r\n const eventCallbacksRef = useRef({\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n });\r\n eventCallbacksRef.current = {\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n };\r\n\r\n useEffect(() => {\r\n if (!engine) return;\r\n const eb = engine.eventBus;\r\n const cbs = () => eventCallbacksRef.current;\r\n\r\n const unsubs = [\r\n eb.on('rowData:changed', (e) => cbs().onRowDataChanged?.(e)),\r\n eb.on('selection:changed', (e) => {\r\n cbs().onSelectionChanged?.(e);\r\n // Controlled mode: notify parent of selection change\r\n controlledCallbacksRef.current.onSelectedRowIdsChange?.(\r\n engine.store.getState().selection.selectedRowIds,\r\n (e as any).source ?? 'api',\r\n );\r\n }),\r\n eb.on('column:sort:changed', (e) => {\r\n cbs().onSortChanged?.(e);\r\n // Controlled mode: notify parent of sort change\r\n controlledCallbacksRef.current.onSortModelChange?.(e.sortModel);\r\n }),\r\n eb.on('filter:changed', (e) => {\r\n cbs().onFilterChanged?.(e);\r\n controlledCallbacksRef.current.onFilterModelChange?.(e.filterModel);\r\n }),\r\n eb.on('cell:valueChanged', (e) => cbs().onCellValueChanged?.(e)),\r\n eb.on('cell:clicked', (e) => cbs().onCellClicked?.(e)),\r\n eb.on('cell:doubleClicked', (e) => cbs().onCellDoubleClicked?.(e)),\r\n eb.on('row:clicked', (e) => cbs().onRowClicked?.(e)),\r\n eb.on('cell:editingStarted', (e) => cbs().onCellEditingStarted?.(e)),\r\n eb.on('cell:editingStopped', (e) => cbs().onCellEditingStopped?.(e)),\r\n eb.on('pagination:changed', (e) => {\r\n cbs().onPaginationChanged?.(e);\r\n controlledCallbacksRef.current.onCurrentPageChange?.(e.currentPage);\r\n }),\r\n eb.on('column:resized', (e) => cbs().onColumnResized?.(e)),\r\n ];\r\n\r\n return () => unsubs.forEach((u) => u());\r\n }, [engine]);\r\n\r\n // ── Fire onGridReady ──\r\n useEffect(() => {\r\n if (engine) {\r\n onGridReady?.(engine.api);\r\n }\r\n }, [engine]); // eslint-disable-line react-hooks/exhaustive-deps\r\n\r\n // ── Container style ──\r\n const style: CSSProperties = {\r\n height: typeof height === 'number' ? `${height}px` : height,\r\n width: typeof width === 'number' ? `${width}px` : width,\r\n ...containerStyle,\r\n };\r\n\r\n // ── Context value (stable reference) ──\r\n const contextValue = useMemo<GridContextValue<TData> | null>(\r\n () => (engine ? { engine, api: engine.api, rootElement } : null),\r\n [engine, rootElement],\r\n );\r\n\r\n // ── Before engine is ready (first render before useEffect), render only the container ──\r\n if (!engine || !contextValue) {\r\n return (\r\n <GridErrorBoundary>\r\n <div\r\n ref={containerRef}\r\n className={`gs-container ${containerClass ?? ''}`.trim()}\r\n style={style}\r\n />\r\n </GridErrorBoundary>\r\n );\r\n }\r\n\r\n return (\r\n <GridErrorBoundary>\r\n <GridContext.Provider value={contextValue as GridContextValue}>\r\n {children}\r\n <div\r\n ref={containerRef}\r\n className={`gs-container ${containerClass ?? ''}`.trim()}\r\n style={style}\r\n />\r\n <PortalManager\r\n engine={engine}\r\n api={engine.api}\r\n columns={reactColumns}\r\n rootElement={rootElement}\r\n contextMenuComponent={contextMenu}\r\n />\r\n </GridContext.Provider>\r\n </GridErrorBoundary>\r\n );\r\n}\r\n","// ─── useGridApi Hook ───\n// Access the GridApi from context.\n\nimport type { GridApi } from '@gridstorm/core';\nimport { useGridContext } from '../context';\n\n/**\n * Access the GridApi instance.\n * Must be used within a `<GridStorm>` component.\n */\nexport function useGridApi<TData = any>(): GridApi<TData> {\n return useGridContext<TData>().api;\n}\n","// ─── useGridState Hook ───\r\n// Selector-based reactive state subscription via useSyncExternalStore.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { GridState } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\n/**\r\n * Subscribe to grid state changes with a selector.\r\n * Re-renders only when the selected value changes (reference equality).\r\n *\r\n * @example\r\n * ```tsx\r\n * const rowCount = useGridState(state => state.displayedRowIds.length);\r\n * const sortModel = useGridState(state => state.sortModel);\r\n * ```\r\n */\r\nexport function useGridState<TData = any, TResult = any>(\r\n selector: (state: GridState<TData>) => TResult,\r\n): TResult {\r\n const { engine } = useGridContext<TData>();\r\n\r\n // Memoize getSnapshot so useSyncExternalStore doesn't re-subscribe every render\r\n const getSnapshot = useCallback(\r\n () => selector(engine.store.getState() as GridState<TData>),\r\n [selector, engine],\r\n );\r\n\r\n return useSyncExternalStore(\r\n (onStoreChange) => engine.store.subscribe(onStoreChange),\r\n getSnapshot,\r\n getSnapshot,\r\n );\r\n}\r\n","// ─── useGridSelection Hook ───\r\n// Selection state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { RowNode } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridSelectionResult<TData = any> {\r\n /** Set of selected row IDs. */\r\n selectedRowIds: Set<string>;\r\n /** Number of selected rows. */\r\n selectedCount: number;\r\n /** Get selected row data objects. */\r\n getSelectedRows: () => TData[];\r\n /** Get selected RowNode objects. */\r\n getSelectedNodes: () => RowNode<TData>[];\r\n /** Check if a specific row is selected. */\r\n isRowSelected: (rowId: string) => boolean;\r\n /** Select all visible rows. */\r\n selectAll: () => void;\r\n /** Deselect all rows. */\r\n deselectAll: () => void;\r\n}\r\n\r\n/**\r\n * Access selection state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { selectedCount, selectAll, deselectAll, isRowSelected } = useGridSelection();\r\n * ```\r\n */\r\nexport function useGridSelection<TData = any>(): GridSelectionResult<TData> {\r\n const { engine, api } = useGridContext<TData>();\r\n\r\n const getSelectionSnapshot = useCallback(() => engine.store.getState().selection.selectedRowIds, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const selectedRowIds = useSyncExternalStore(\r\n subscribe,\r\n getSelectionSnapshot,\r\n getSelectionSnapshot,\r\n );\r\n\r\n const selectedCount = selectedRowIds.size;\r\n\r\n const isRowSelected = useCallback(\r\n (rowId: string) =>\r\n engine.store.getState().selection.selectedRowIds.has(rowId),\r\n [engine],\r\n );\r\n\r\n const getSelectedRows = useCallback(() => api.getSelectedRows(), [api]);\r\n const getSelectedNodes = useCallback(() => api.getSelectedNodes(), [api]);\r\n const selectAll = useCallback(() => api.selectAll(), [api]);\r\n const deselectAll = useCallback(() => api.deselectAll(), [api]);\r\n\r\n return {\r\n selectedRowIds,\r\n selectedCount,\r\n getSelectedRows,\r\n getSelectedNodes,\r\n isRowSelected,\r\n selectAll,\r\n deselectAll,\r\n };\r\n}\r\n","// ─── useGridSort Hook ───\r\n// Sort model state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { SortModelItem } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridSortResult {\r\n /** Current sort model. */\r\n sortModel: SortModelItem[];\r\n /** Whether any sort is active. */\r\n isSorted: boolean;\r\n /** Set the sort model directly. */\r\n setSortModel: (model: SortModelItem[]) => void;\r\n /** Toggle sort on a column. */\r\n toggleSort: (colId: string, multiSort?: boolean) => void;\r\n /** Clear all sort. */\r\n clearSort: () => void;\r\n}\r\n\r\n/**\r\n * Access sort state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();\r\n * ```\r\n */\r\nexport function useGridSort(): GridSortResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getSortSnapshot = useCallback(() => engine.store.getState().sortModel, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const sortModel = useSyncExternalStore(\r\n subscribe,\r\n getSortSnapshot,\r\n getSortSnapshot,\r\n );\r\n\r\n const isSorted = sortModel.length > 0;\r\n\r\n const setSortModel = useCallback(\r\n (model: SortModelItem[]) => api.setSortModel(model),\r\n [api],\r\n );\r\n\r\n const toggleSort = useCallback(\r\n (colId: string, multiSort = false) => {\r\n engine.commandBus.dispatch('sort:toggle', { colId, multiSort });\r\n },\r\n [engine],\r\n );\r\n\r\n const clearSort = useCallback(() => api.setSortModel([]), [api]);\r\n\r\n return { sortModel, isSorted, setSortModel, toggleSort, clearSort };\r\n}\r\n","// ─── useGridFilter Hook ───\r\n// Filter model state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { FilterModel } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridFilterResult {\r\n /** Current filter model (keyed by column ID). */\r\n filterModel: Record<string, FilterModel>;\r\n /** Current quick filter text. */\r\n quickFilterText: string;\r\n /** Whether any filter is active. */\r\n isFiltered: boolean;\r\n /** Set the filter model. */\r\n setFilterModel: (model: Record<string, FilterModel>) => void;\r\n /** Set quick filter text. */\r\n setQuickFilter: (text: string) => void;\r\n /** Clear all filters. */\r\n clearFilters: () => void;\r\n}\r\n\r\n/**\r\n * Access filter state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();\r\n * ```\r\n */\r\nexport function useGridFilter(): GridFilterResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getFilterSnapshot = useCallback(() => engine.store.getState().filterModel, [engine]);\r\n const getQuickFilterSnapshot = useCallback(() => engine.store.getState().quickFilterText, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const filterModel = useSyncExternalStore(\r\n subscribe,\r\n getFilterSnapshot,\r\n getFilterSnapshot,\r\n );\r\n\r\n const quickFilterText = useSyncExternalStore(\r\n subscribe,\r\n getQuickFilterSnapshot,\r\n getQuickFilterSnapshot,\r\n );\r\n\r\n const isFiltered =\r\n Object.keys(filterModel).length > 0 || quickFilterText.length > 0;\r\n\r\n const setFilterModel = useCallback(\r\n (model: Record<string, FilterModel>) => api.setFilterModel(model),\r\n [api],\r\n );\r\n\r\n const setQuickFilter = useCallback(\r\n (text: string) => api.setQuickFilter(text),\r\n [api],\r\n );\r\n\r\n const clearFilters = useCallback(() => {\r\n api.setFilterModel({});\r\n api.setQuickFilter('');\r\n }, [api]);\r\n\r\n return {\r\n filterModel,\r\n quickFilterText,\r\n isFiltered,\r\n setFilterModel,\r\n setQuickFilter,\r\n clearFilters,\r\n };\r\n}\r\n","// ─── useGridPagination Hook ───\r\n// Pagination state and navigation actions.\r\n\r\nimport { useSyncExternalStore, useCallback, useMemo } from 'react';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridPaginationResult {\r\n /** Current page (0-indexed). */\r\n currentPage: number;\r\n /** Total number of pages. */\r\n totalPages: number;\r\n /** Rows per page. */\r\n pageSize: number;\r\n /** Total row count (after filtering). */\r\n totalRows: number;\r\n /** Is there a next page? */\r\n hasNextPage: boolean;\r\n /** Is there a previous page? */\r\n hasPreviousPage: boolean;\r\n /** Go to a specific page. */\r\n goToPage: (page: number) => void;\r\n /** Go to next page. */\r\n nextPage: () => void;\r\n /** Go to previous page. */\r\n previousPage: () => void;\r\n /** Go to first page. */\r\n firstPage: () => void;\r\n /** Go to last page. */\r\n lastPage: () => void;\r\n}\r\n\r\n/**\r\n * Access pagination state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { currentPage, totalPages, nextPage, previousPage } = useGridPagination();\r\n * ```\r\n */\r\nexport function useGridPagination(): GridPaginationResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getPaginationSnapshot = useCallback(() => engine.store.getState().pagination, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const paginationState = useSyncExternalStore(\r\n subscribe,\r\n getPaginationSnapshot,\r\n getPaginationSnapshot,\r\n );\r\n\r\n const { currentPage, pageSize, totalRows } = paginationState;\r\n const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));\r\n const hasNextPage = currentPage < totalPages - 1;\r\n const hasPreviousPage = currentPage > 0;\r\n\r\n const goToPage = useCallback(\r\n (page: number) => api.paginationGoToPage(page),\r\n [api],\r\n );\r\n\r\n const nextPage = useCallback(() => {\r\n if (hasNextPage) api.paginationGoToPage(currentPage + 1);\r\n }, [api, currentPage, hasNextPage]);\r\n\r\n const previousPage = useCallback(() => {\r\n if (hasPreviousPage) api.paginationGoToPage(currentPage - 1);\r\n }, [api, currentPage, hasPreviousPage]);\r\n\r\n const firstPage = useCallback(() => api.paginationGoToPage(0), [api]);\r\n\r\n const lastPage = useCallback(\r\n () => api.paginationGoToPage(totalPages - 1),\r\n [api, totalPages],\r\n );\r\n\r\n return useMemo(\r\n () => ({\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n }),\r\n [\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n ],\r\n );\r\n}\r\n","// ─── useGridEvent Hook ───\n// Subscribe to typed grid events.\n\nimport { useEffect, useRef } from 'react';\nimport type { GridEventMap } from '@gridstorm/core';\nimport { useGridContext } from '../context';\n\n/**\n * Subscribe to a specific grid event.\n * Handler ref prevents stale closures without re-subscribing.\n *\n * @example\n * ```tsx\n * useGridEvent('cell:clicked', (event) => {\n * console.log('Clicked cell:', event.colId, event.value);\n * });\n * ```\n */\nexport function useGridEvent<\n TData = any,\n K extends keyof GridEventMap<TData> = any,\n>(\n event: K,\n handler: (payload: GridEventMap<TData>[K]) => void,\n): void {\n const { engine } = useGridContext<TData>();\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const unsub = engine.eventBus.on(event as any, (payload: any) => {\n handlerRef.current(payload);\n });\n return unsub;\n }, [engine, event]);\n}\n","// ─── useGridColumn Hook ───\r\n// Column state and manipulation actions.\r\n\r\nimport { useSyncExternalStore, useCallback, useMemo } from 'react';\r\nimport type { ColumnState, PinnedPosition } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridColumnResult {\r\n /** All columns (including hidden). */\r\n allColumns: ColumnState[];\r\n /** Only visible columns. */\r\n visibleColumns: ColumnState[];\r\n /** Set a column's visibility. */\r\n setColumnVisible: (colId: string, visible: boolean) => void;\r\n /** Set a column's width. */\r\n setColumnWidth: (colId: string, width: number) => void;\r\n /** Move a column to a new index. */\r\n moveColumn: (colId: string, toIndex: number) => void;\r\n /** Pin a column. */\r\n setColumnPinned: (colId: string, pinned: PinnedPosition) => void;\r\n /** Get a single column by ID. */\r\n getColumn: (colId: string) => ColumnState | undefined;\r\n}\r\n\r\n/**\r\n * Access column state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { visibleColumns, setColumnVisible, setColumnWidth } = useGridColumn();\r\n * ```\r\n */\r\nexport function useGridColumn(): GridColumnResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getColumnsSnapshot = useCallback(() => engine.store.getState().columns, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const allColumns = useSyncExternalStore(\r\n subscribe,\r\n getColumnsSnapshot,\r\n getColumnsSnapshot,\r\n );\r\n\r\n const visibleColumns = useMemo(\r\n () => allColumns.filter((c) => !c.hide),\r\n [allColumns],\r\n );\r\n\r\n const setColumnVisible = useCallback(\r\n (colId: string, visible: boolean) => api.setColumnVisible(colId, visible),\r\n [api],\r\n );\r\n\r\n const setColumnWidth = useCallback(\r\n (colId: string, width: number) => api.setColumnWidth(colId, width),\r\n [api],\r\n );\r\n\r\n const moveColumn = useCallback(\r\n (colId: string, toIndex: number) => api.moveColumn(colId, toIndex),\r\n [api],\r\n );\r\n\r\n const setColumnPinned = useCallback(\r\n (colId: string, pinned: PinnedPosition) =>\r\n api.setColumnPinned(colId, pinned),\r\n [api],\r\n );\r\n\r\n const getColumn = useCallback(\r\n (colId: string) => api.getColumn(colId),\r\n [api],\r\n );\r\n\r\n return {\r\n allColumns,\r\n visibleColumns,\r\n setColumnVisible,\r\n setColumnWidth,\r\n moveColumn,\r\n setColumnPinned,\r\n getColumn,\r\n };\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/renderers/ReactCellRenderer.ts","../src/renderers/ReactHeaderRenderer.ts","../src/portals/CellRendererPortal.tsx","../src/portals/CellEditorPortal.tsx","../src/portals/ContextMenuPortal.tsx","../src/portals/PortalManager.tsx","../src/ErrorBoundary.tsx","../src/GridStorm.tsx","../src/hooks/useGridApi.ts","../src/hooks/useGridState.ts","../src/hooks/useGridSelection.ts","../src/hooks/useGridSort.ts","../src/hooks/useGridFilter.ts","../src/hooks/useGridPagination.ts","../src/hooks/useGridEvent.ts","../src/hooks/useGridColumn.ts"],"names":["Component","jsx","useRef","useEffect","useState","useCallback","jsxs","useSyncExternalStore","useMemo"],"mappings":"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","file":"index.js","sourcesContent":["// ─── Grid Context ───\n// Provides the engine, API, and metadata to all child hooks and components.\n\nimport { createContext, useContext } from 'react';\nimport type { GridEngine, GridApi } from '@gridstorm/core';\n\nexport interface GridContextValue<TData = any> {\n engine: GridEngine<TData>;\n api: GridApi<TData>;\n /** The root DOM element (.gs-root) of the grid. */\n rootElement: HTMLElement | null;\n}\n\nexport const GridContext = createContext<GridContextValue | null>(null);\n\n/**\n * Internal helper — gets grid context with null-check.\n * All public hooks use this internally.\n */\nexport function useGridContext<TData = any>(): GridContextValue<TData> {\n const ctx = useContext(GridContext);\n if (!ctx) {\n throw new Error(\n '[GridStorm] Hook must be used within a <GridStorm> component.',\n );\n }\n return ctx as GridContextValue<TData>;\n}\n","// ─── React Cell Renderer Marker ───\n// Wraps a React component so it can be used as a CellRendererFn.\n// The DomRenderer will receive an empty string (creating an empty cell),\n// and the PortalManager will detect the marker and portal the React\n// component into that cell.\n\nimport type { ReactCellRenderer } from '../types';\n\n/** Symbol marker for React cell renderers. */\nexport const REACT_CELL_RENDERER = Symbol.for('gridstorm:reactCellRenderer');\n\n/**\n * Wrap a React component to use as a cell renderer.\n *\n * @example\n * ```tsx\n * const StatusCell = ({ value }: CellRendererProps) => (\n * <span className={value ? 'active' : 'inactive'}>{value ? 'Yes' : 'No'}</span>\n * );\n *\n * const columns = [\n * { field: 'active', cellRenderer: reactCellRenderer(StatusCell) },\n * ];\n * ```\n */\nexport function reactCellRenderer<TData = any, TValue = any>(\n Component: ReactCellRenderer<TData, TValue>,\n): any {\n // Return a CellRendererFn that outputs empty string.\n // The DomRenderer will create an empty cell; the PortalManager portals React content into it.\n const fn = () => '';\n (fn as any)[REACT_CELL_RENDERER] = Component;\n return fn;\n}\n\n/** Check if a cellRenderer is a wrapped React component. */\nexport function isReactCellRenderer(fn: unknown): boolean {\n return typeof fn === 'function' && REACT_CELL_RENDERER in (fn as any);\n}\n\n/** Extract the React component from a wrapped cell renderer. */\nexport function getReactCellComponent<TData = any, TValue = any>(\n fn: unknown,\n): ReactCellRenderer<TData, TValue> | null {\n if (isReactCellRenderer(fn)) {\n return (fn as any)[REACT_CELL_RENDERER];\n }\n return null;\n}\n","// ─── React Header Renderer Marker ───\n// Same pattern as ReactCellRenderer but for header cells.\n\nimport type { ReactHeaderRenderer } from '../types';\n\n/** Symbol marker for React header renderers. */\nexport const REACT_HEADER_RENDERER = Symbol.for('gridstorm:reactHeaderRenderer');\n\n/**\n * Wrap a React component to use as a header renderer.\n *\n * @example\n * ```tsx\n * const SortHeader = ({ displayName, sortDirection, onSortRequested }: HeaderRendererProps) => (\n * <div onClick={() => onSortRequested(false)}>\n * {displayName} {sortDirection === 'asc' ? '▲' : sortDirection === 'desc' ? '▼' : ''}\n * </div>\n * );\n *\n * const columns = [\n * { field: 'name', headerRenderer: reactHeaderRenderer(SortHeader) },\n * ];\n * ```\n */\nexport function reactHeaderRenderer<TData = any>(\n Component: ReactHeaderRenderer<TData>,\n): any {\n const fn = () => '';\n (fn as any)[REACT_HEADER_RENDERER] = Component;\n return fn;\n}\n\n/** Check if a headerRenderer is a wrapped React component. */\nexport function isReactHeaderRenderer(fn: unknown): boolean {\n return typeof fn === 'function' && REACT_HEADER_RENDERER in (fn as any);\n}\n\n/** Extract the React component from a wrapped header renderer. */\nexport function getReactHeaderComponent<TData = any>(\n fn: unknown,\n): ReactHeaderRenderer<TData> | null {\n if (isReactHeaderRenderer(fn)) {\n return (fn as any)[REACT_HEADER_RENDERER];\n }\n return null;\n}\n","// ─── Cell Renderer Portal ───\n// Memoized wrapper for individual React cell renderer portals.\n// Custom comparator prevents re-renders when cell data hasn't changed.\n\nimport { memo } from 'react';\nimport type { ReactCellRenderer, CellRendererProps } from '../types';\n\ninterface CellRendererPortalProps<TData = any, TValue = any> {\n Component: ReactCellRenderer<TData, TValue>;\n rendererProps: CellRendererProps<TData, TValue>;\n nodeVersion: number;\n}\n\nfunction CellRendererPortalInner<TData = any, TValue = any>(\n props: CellRendererPortalProps<TData, TValue>,\n) {\n const { Component, rendererProps } = props;\n return <Component {...rendererProps} />;\n}\n\n/** Memoized cell renderer portal — only re-renders when value or version changes. */\nexport const CellRendererPortal = memo(\n CellRendererPortalInner,\n (prev, next) =>\n prev.nodeVersion === next.nodeVersion &&\n prev.rendererProps.value === next.rendererProps.value &&\n prev.rendererProps.rowIndex === next.rendererProps.rowIndex &&\n prev.rendererProps.colId === next.rendererProps.colId,\n) as typeof CellRendererPortalInner;\n","// ─── Cell Editor Portal ───\n// Renders a React cell editor component as an absolutely-positioned\n// overlay on top of the editing cell.\n\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport type { GridEngine, GridApi } from '@gridstorm/core';\nimport type { ReactCellEditor, EditorPortalState } from '../types';\n\ninterface CellEditorPortalProps<TData = any> {\n state: EditorPortalState;\n api: GridApi<TData>;\n engine: GridEngine<TData>;\n EditorComponent: ReactCellEditor<TData>;\n editorParams: Record<string, unknown>;\n gridRootRect: DOMRect;\n}\n\nexport function CellEditorPortal<TData = any>(props: CellEditorPortalProps<TData>) {\n const { state, api, engine, EditorComponent, editorParams, gridRootRect } = props;\n const { editing, cellRect } = state;\n const [value, setValue] = useState(editing.value);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const onValueChange = useCallback(\n (newValue: any) => {\n setValue(newValue);\n engine.commandBus.dispatch('editing:setValue', { value: newValue });\n },\n [engine],\n );\n\n const stopEditing = useCallback(\n (cancel?: boolean) => {\n api.stopEditing(cancel);\n },\n [api],\n );\n\n // Auto-focus the editor on mount\n useEffect(() => {\n requestAnimationFrame(() => {\n const el = containerRef.current;\n if (!el) return;\n const focusable = el.querySelector<HTMLElement>(\n 'input, textarea, select, [tabindex]',\n );\n focusable?.focus();\n });\n }, []);\n\n const column = engine.store\n .getState()\n .columns.find((c) => c.colId === editing.colId)!;\n\n const node = engine.store.getState().rowNodes.get(editing.rowId);\n\n // Position relative to the grid root\n const top = cellRect.top - gridRootRect.top;\n const left = cellRect.left - gridRootRect.left;\n\n return (\n <div\n ref={containerRef}\n className=\"gs-editor-portal\"\n style={{\n position: 'absolute',\n top,\n left,\n width: cellRect.width,\n height: cellRect.height,\n zIndex: 10,\n boxSizing: 'border-box',\n background: 'var(--gs-color-cell-editing-bg, #fff)',\n border: '2px solid var(--gs-color-cell-editing-border, #2196f3)',\n }}\n >\n <EditorComponent\n value={value}\n data={node?.data as TData}\n colId={editing.colId}\n rowId={editing.rowId}\n column={column}\n editorParams={editorParams}\n onValueChange={onValueChange}\n stopEditing={stopEditing}\n api={api}\n />\n </div>\n );\n}\n","// ─── Context Menu Portal ───\n// Renders a user-provided context menu component at the right-click position.\n\nimport { useEffect, useRef } from 'react';\nimport type { ContextMenuProps, ReactContextMenu } from '../types';\n\ninterface ContextMenuPortalProps<TData = any> {\n x: number;\n y: number;\n menuProps: ContextMenuProps<TData>;\n Component: ReactContextMenu<TData>;\n}\n\nexport function ContextMenuPortal<TData = any>(\n props: ContextMenuPortalProps<TData>,\n) {\n const { x, y, menuProps, Component } = props;\n const ref = useRef<HTMLDivElement>(null);\n\n // Close on click outside\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n menuProps.closeMenu();\n }\n };\n // Use setTimeout so the current click doesn't immediately close the menu\n const id = setTimeout(() => {\n document.addEventListener('mousedown', handler);\n }, 0);\n return () => {\n clearTimeout(id);\n document.removeEventListener('mousedown', handler);\n };\n }, [menuProps]);\n\n // Close on Escape\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') menuProps.closeMenu();\n };\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n }, [menuProps]);\n\n return (\n <div\n ref={ref}\n className=\"gs-context-menu-portal\"\n style={{\n position: 'absolute',\n top: y,\n left: x,\n zIndex: 100,\n minWidth: 160,\n }}\n >\n <Component {...menuProps} />\n </div>\n );\n}\n","// ─── Portal Manager ───\r\n// Central orchestrator for all React portals: cell renderers, header\r\n// renderers, editors, and context menus.\r\n//\r\n// Uses a MutationObserver on .gs-body to detect when DomRenderer\r\n// adds/removes row elements, then portals React content into wrapper\r\n// divs inside cells that have React renderers.\r\n//\r\n// KEY DESIGN: We never portal directly into DomRenderer-managed cells.\r\n// Instead, we create a wrapper <div style=\"display:contents\"> inside each\r\n// cell and portal into that wrapper. This prevents crashes when DomRenderer\r\n// destroys/recycles cells — the wrapper is detached but still maintains\r\n// its React children, so React can safely unmount.\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useState,\r\n useCallback,\r\n useSyncExternalStore,\r\n} from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport type { GridEngine, GridApi, ColumnState, RowNode } from '@gridstorm/core';\r\nimport { getValueFromData } from '@gridstorm/core';\r\nimport type {\r\n ReactColumnDef,\r\n CellRendererProps,\r\n HeaderRendererProps,\r\n EditorPortalState,\r\n ContextMenuProps,\r\n ReactContextMenu,\r\n ReactCellEditor,\r\n} from '../types';\r\nimport { getReactCellComponent, isReactCellRenderer } from '../renderers/ReactCellRenderer';\r\nimport { getReactHeaderComponent, isReactHeaderRenderer } from '../renderers/ReactHeaderRenderer';\r\nimport { CellRendererPortal } from './CellRendererPortal';\r\nimport { CellEditorPortal } from './CellEditorPortal';\r\nimport { ContextMenuPortal } from './ContextMenuPortal';\r\n\r\nexport interface PortalManagerProps<TData = any> {\r\n engine: GridEngine<TData>;\r\n api: GridApi<TData>;\r\n columns: ReactColumnDef<TData>[];\r\n rootElement: HTMLElement | null;\r\n contextMenuComponent?: ReactContextMenu<TData>;\r\n}\r\n\r\n// ── Portal wrapper attribute ──\r\n// Used to identify wrapper divs we've created inside cells.\r\nconst WRAPPER_ATTR = 'data-gs-portal';\r\n\r\n// ── Cell renderer portal entry ──\r\ninterface CellPortalEntry<TData = any> {\r\n key: string;\r\n /** The wrapper div inside the cell (React-owned, safe to portal into) */\r\n container: HTMLElement;\r\n component: any;\r\n props: CellRendererProps<TData>;\r\n nodeVersion: number;\r\n}\r\n\r\n// ── Header renderer portal entry ──\r\ninterface HeaderPortalEntry {\r\n key: string;\r\n /** The wrapper div inside the header cell */\r\n container: HTMLElement;\r\n element: any;\r\n}\r\n\r\n// ── Context menu state ──\r\ninterface ContextMenuState<TData = any> {\r\n x: number;\r\n y: number;\r\n menuProps: ContextMenuProps<TData>;\r\n}\r\n\r\n// ── Helper: get or create a stable wrapper div inside a cell ──\r\n// The wrapper uses display:contents so it's layout-transparent.\r\n// When DomRenderer destroys the cell, the wrapper is detached but\r\n// still maintains its children — React can safely unmount from it.\r\nfunction getOrCreateWrapper(cell: HTMLElement): HTMLElement {\r\n // Check direct children only (not descendants) for existing wrapper\r\n for (let i = 0; i < cell.children.length; i++) {\r\n const child = cell.children[i] as HTMLElement;\r\n if (child.hasAttribute(WRAPPER_ATTR)) {\r\n return child;\r\n }\r\n }\r\n // Create new wrapper\r\n const wrapper = document.createElement('div');\r\n wrapper.setAttribute(WRAPPER_ATTR, '');\r\n wrapper.style.display = 'contents';\r\n cell.appendChild(wrapper);\r\n return wrapper;\r\n}\r\n\r\nexport function PortalManager<TData = any>(props: PortalManagerProps<TData>) {\r\n const { engine, api, columns, rootElement, contextMenuComponent } = props;\r\n\r\n // ── Portal state ──\r\n const [cellPortals, setCellPortals] = useState<Map<string, CellPortalEntry<TData>>>(\r\n () => new Map(),\r\n );\r\n const [headerPortals, setHeaderPortals] = useState<Map<string, HeaderPortalEntry>>(\r\n () => new Map(),\r\n );\r\n const [editorPortal, setEditorPortal] = useState<EditorPortalState | null>(null);\r\n const [contextMenu, setContextMenu] = useState<ContextMenuState<TData> | null>(null);\r\n\r\n // Refs for stable access in callbacks\r\n const columnsRef = useRef(columns);\r\n columnsRef.current = columns;\r\n const engineRef = useRef(engine);\r\n engineRef.current = engine;\r\n\r\n // Track if we're currently scanning to prevent re-entrant scans\r\n const scanningRef = useRef(false);\r\n\r\n // ── Build lookup maps for which columns have React renderers ──\r\n const reactCellRendererMap = useRef(new Map<string, any>());\r\n const reactHeaderRendererMap = useRef(new Map<string, any>());\r\n const reactEditorMap = useRef(new Map<string, ReactCellEditor<TData>>());\r\n\r\n useEffect(() => {\r\n const cellMap = new Map<string, any>();\r\n const headerMap = new Map<string, any>();\r\n const editorMap = new Map<string, ReactCellEditor<TData>>();\r\n\r\n for (const col of columns) {\r\n const colId = (col as any).colId ?? col.field ?? '';\r\n if (col.cellRenderer && isReactCellRenderer(col.cellRenderer)) {\r\n cellMap.set(colId, getReactCellComponent(col.cellRenderer));\r\n }\r\n if (col.headerRenderer && isReactHeaderRenderer(col.headerRenderer)) {\r\n headerMap.set(colId, getReactHeaderComponent(col.headerRenderer));\r\n }\r\n if (col.cellEditorComponent) {\r\n editorMap.set(colId, col.cellEditorComponent);\r\n }\r\n }\r\n\r\n reactCellRendererMap.current = cellMap;\r\n reactHeaderRendererMap.current = headerMap;\r\n reactEditorMap.current = editorMap;\r\n }, [columns]);\r\n\r\n // ── Helper: build cell renderer props ──\r\n const buildCellProps = useCallback(\r\n (node: RowNode<TData>, col: ColumnState, rowIndex: number): CellRendererProps<TData> => {\r\n const colDef = col.originalDef;\r\n let value: any;\r\n if (colDef.valueGetter) {\r\n value = colDef.valueGetter({\r\n data: node.data,\r\n node,\r\n colDef,\r\n colId: col.colId,\r\n });\r\n } else {\r\n value = getValueFromData(node.data, col.field);\r\n }\r\n\r\n let formattedValue = value != null ? String(value) : '';\r\n if (colDef.valueFormatter) {\r\n formattedValue = colDef.valueFormatter({ value, data: node.data, node, colDef });\r\n }\r\n\r\n return {\r\n value,\r\n formattedValue,\r\n data: node.data,\r\n node,\r\n colDef,\r\n colId: col.colId,\r\n rowIndex,\r\n api,\r\n };\r\n },\r\n [api],\r\n );\r\n\r\n // ── Scan visible rows and create/update cell portals ──\r\n const scanVisibleRows = useCallback(() => {\r\n if (!rootElement || scanningRef.current) return;\r\n scanningRef.current = true;\r\n\r\n try {\r\n const bodyContainer = rootElement.querySelector('.gs-body');\r\n if (!bodyContainer) return;\r\n\r\n const state = engineRef.current.store.getState();\r\n const cellRenderers = reactCellRendererMap.current;\r\n if (cellRenderers.size === 0) return;\r\n\r\n const newPortals = new Map<string, CellPortalEntry<TData>>();\r\n const rowElements = bodyContainer.querySelectorAll<HTMLElement>('.gs-row');\r\n\r\n // Pre-build O(1) lookup maps to avoid O(n) indexOf / find in hot path\r\n const rowIdIndexMap = new Map<string, number>();\r\n for (let i = 0; i < state.displayedRowIds.length; i++) {\r\n rowIdIndexMap.set(state.displayedRowIds[i]!, i);\r\n }\r\n const columnMap = new Map<string, ColumnState>();\r\n for (const col of state.columns) {\r\n columnMap.set(col.colId, col);\r\n }\r\n\r\n for (const rowEl of rowElements) {\r\n const rowId = rowEl.getAttribute('data-row-id');\r\n if (!rowId) continue;\r\n\r\n const node = state.rowNodes.get(rowId);\r\n if (!node) continue;\r\n\r\n const cells = rowEl.querySelectorAll<HTMLElement>('.gs-cell');\r\n for (const cellEl of cells) {\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!colId || !cellRenderers.has(colId)) continue;\r\n\r\n const key = `${rowId}:${colId}`;\r\n const Component = cellRenderers.get(colId)!;\r\n const colState = columnMap.get(colId);\r\n if (!colState) continue;\r\n\r\n const rowIndex = rowIdIndexMap.get(rowId) ?? -1;\r\n const rendererProps = buildCellProps(node, colState, rowIndex);\r\n\r\n // Get or create a stable wrapper div inside the cell.\r\n // We portal into the wrapper, NOT the cell directly.\r\n // This prevents crashes when DomRenderer destroys/recycles cells.\r\n const wrapper = getOrCreateWrapper(cellEl);\r\n\r\n newPortals.set(key, {\r\n key,\r\n container: wrapper,\r\n component: Component,\r\n props: rendererProps,\r\n nodeVersion: node.version,\r\n });\r\n }\r\n }\r\n\r\n setCellPortals(newPortals);\r\n } finally {\r\n scanningRef.current = false;\r\n }\r\n }, [rootElement, buildCellProps]);\r\n\r\n // ── Scan header cells for React header renderers ──\r\n const scanHeaderCells = useCallback(() => {\r\n if (!rootElement) return;\r\n const headerRenderers = reactHeaderRendererMap.current;\r\n if (headerRenderers.size === 0) return;\r\n\r\n const headerContainer = rootElement.querySelector('.gs-header');\r\n if (!headerContainer) return;\r\n\r\n const state = engineRef.current.store.getState();\r\n const newPortals = new Map<string, HeaderPortalEntry>();\r\n\r\n const headerCells = headerContainer.querySelectorAll<HTMLElement>('.gs-header-cell');\r\n for (const cellEl of headerCells) {\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!colId || !headerRenderers.has(colId)) continue;\r\n\r\n const Component = headerRenderers.get(colId)!;\r\n const colState = state.columns.find((c) => c.colId === colId);\r\n if (!colState) continue;\r\n\r\n const sortItem = state.sortModel.find((s) => s.colId === colId);\r\n\r\n const headerProps: HeaderRendererProps<TData> = {\r\n colDef: colState.originalDef,\r\n colId,\r\n displayName: colState.headerName,\r\n sortDirection: sortItem?.sort ?? null,\r\n sortIndex: colState.sortIndex,\r\n api,\r\n onSortRequested: (multiSort: boolean) => {\r\n engineRef.current.commandBus.dispatch('sort:toggle', { colId, multiSort });\r\n },\r\n };\r\n\r\n // Get or create a stable wrapper div inside the header cell.\r\n const wrapper = getOrCreateWrapper(cellEl);\r\n\r\n newPortals.set(colId, {\r\n key: colId,\r\n container: wrapper,\r\n element: <Component {...headerProps} />,\r\n });\r\n }\r\n\r\n setHeaderPortals(newPortals);\r\n }, [rootElement, api]);\r\n\r\n // ── MutationObserver on .gs-body for row add/remove ──\r\n useEffect(() => {\r\n if (!rootElement) return;\r\n const bodyContainer = rootElement.querySelector('.gs-body');\r\n if (!bodyContainer) return;\r\n\r\n const observer = new MutationObserver(() => {\r\n // When DomRenderer adds/removes rows, re-scan for portals\r\n scanVisibleRows();\r\n });\r\n\r\n observer.observe(bodyContainer, { childList: true });\r\n\r\n // Initial scan for already-rendered rows\r\n scanVisibleRows();\r\n scanHeaderCells();\r\n\r\n return () => observer.disconnect();\r\n }, [rootElement, scanVisibleRows, scanHeaderCells]);\r\n\r\n // ── Re-scan when state changes (sort, filter, data) ──\r\n const getVersionSnapshot = useCallback(() => engine.store.getVersion(), [engine]);\r\n const subscribeStore = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const stateVersion = useSyncExternalStore(\r\n subscribeStore,\r\n getVersionSnapshot,\r\n getVersionSnapshot,\r\n );\r\n\r\n useEffect(() => {\r\n scanVisibleRows();\r\n }, [stateVersion, scanVisibleRows]);\r\n\r\n // ── Re-scan headers when sort or columns change ──\r\n useEffect(() => {\r\n const unsubs = [\r\n engine.eventBus.on('column:sort:changed', () => {\r\n // Delay slightly to let DomRenderer recreate header cells first\r\n requestAnimationFrame(() => scanHeaderCells());\r\n }),\r\n engine.eventBus.on('columns:changed', () => {\r\n requestAnimationFrame(() => scanHeaderCells());\r\n }),\r\n ];\r\n return () => unsubs.forEach((u) => u());\r\n }, [engine, scanHeaderCells]);\r\n\r\n // ── Editor portal lifecycle ──\r\n useEffect(() => {\r\n const unsubStart = engine.eventBus.on(\r\n 'cell:editingStarted',\r\n (event: any) => {\r\n const { node, colId } = event;\r\n const editorComponent = reactEditorMap.current.get(colId);\r\n if (!editorComponent || !rootElement) return;\r\n\r\n // Find the cell element (CSS.escape prevents selector injection from rowId/colId)\r\n const cellEl = rootElement.querySelector<HTMLElement>(\r\n `.gs-row[data-row-id=\"${CSS.escape(node.id)}\"] .gs-cell[data-col-id=\"${CSS.escape(colId)}\"]`,\r\n );\r\n if (!cellEl) return;\r\n\r\n const state = engine.store.getState();\r\n const editing = state.editing;\r\n if (!editing) return;\r\n\r\n setEditorPortal({\r\n editing,\r\n cellElement: cellEl,\r\n cellRect: cellEl.getBoundingClientRect(),\r\n });\r\n },\r\n );\r\n\r\n const unsubStop = engine.eventBus.on('cell:editingStopped', () => {\r\n setEditorPortal(null);\r\n });\r\n\r\n return () => {\r\n unsubStart();\r\n unsubStop();\r\n };\r\n }, [engine, rootElement]);\r\n\r\n // ── Context menu ──\r\n useEffect(() => {\r\n if (!rootElement || !contextMenuComponent) return;\r\n\r\n const handler = (e: MouseEvent) => {\r\n e.preventDefault();\r\n const target = e.target as HTMLElement;\r\n const cellEl = target.closest<HTMLElement>('.gs-cell');\r\n const rowEl = target.closest<HTMLElement>('.gs-row');\r\n if (!cellEl || !rowEl) return;\r\n\r\n const rowId = rowEl.getAttribute('data-row-id');\r\n const colId = cellEl.getAttribute('data-col-id');\r\n if (!rowId || !colId) return;\r\n\r\n const state = engine.store.getState();\r\n const node = state.rowNodes.get(rowId);\r\n if (!node) return;\r\n\r\n const colState = state.columns.find((c) => c.colId === colId);\r\n const value = colState\r\n ? getValueFromData(node.data, colState.field)\r\n : undefined;\r\n\r\n const rootRect = rootElement.getBoundingClientRect();\r\n const rowIndex = state.displayedRowIds.indexOf(rowId);\r\n\r\n setContextMenu({\r\n x: e.clientX - rootRect.left,\r\n y: e.clientY - rootRect.top,\r\n menuProps: {\r\n position: { rowIndex, colId },\r\n node,\r\n colId,\r\n value,\r\n api,\r\n closeMenu: () => setContextMenu(null),\r\n },\r\n });\r\n };\r\n\r\n rootElement.addEventListener('contextmenu', handler);\r\n return () => rootElement.removeEventListener('contextmenu', handler);\r\n }, [rootElement, contextMenuComponent, api, engine]);\r\n\r\n // ── Render portals ──\r\n return (\r\n <>\r\n {/* Cell renderer portals — portaled into wrapper divs, NOT cells directly */}\r\n {Array.from(cellPortals.values()).map((entry) =>\r\n createPortal(\r\n <CellRendererPortal\r\n key={entry.key}\r\n Component={entry.component}\r\n rendererProps={entry.props}\r\n nodeVersion={entry.nodeVersion}\r\n />,\r\n entry.container,\r\n entry.key,\r\n ),\r\n )}\r\n\r\n {/* Header renderer portals — portaled into wrapper divs in header cells */}\r\n {Array.from(headerPortals.values()).map((entry) =>\r\n createPortal(entry.element, entry.container, entry.key),\r\n )}\r\n\r\n {/* Editor portal */}\r\n {editorPortal && rootElement && (() => {\r\n const editorComponent = reactEditorMap.current.get(editorPortal.editing.colId);\r\n if (!editorComponent) return null;\r\n const colDef = columnsRef.current.find(\r\n (c) => ((c as any).colId ?? c.field) === editorPortal.editing.colId,\r\n );\r\n return createPortal(\r\n <CellEditorPortal\r\n state={editorPortal}\r\n api={api}\r\n engine={engine}\r\n EditorComponent={editorComponent}\r\n editorParams={(colDef?.cellEditorParams as Record<string, unknown>) ?? {}}\r\n gridRootRect={rootElement.getBoundingClientRect()}\r\n />,\r\n rootElement,\r\n 'gs-editor',\r\n );\r\n })()}\r\n\r\n {/* Context menu portal */}\r\n {contextMenu && contextMenuComponent && rootElement &&\r\n createPortal(\r\n <ContextMenuPortal\r\n x={contextMenu.x}\r\n y={contextMenu.y}\r\n menuProps={contextMenu.menuProps}\r\n Component={contextMenuComponent}\r\n />,\r\n rootElement,\r\n 'gs-context-menu',\r\n )}\r\n </>\r\n );\r\n}\r\n","// ─── GridStorm Error Boundary ───\n// Catches rendering errors in the grid and displays a fallback UI.\n\nimport { Component, type ReactNode, type ErrorInfo } from 'react';\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class GridErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state: ErrorBoundaryState = { hasError: false, error: null };\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n console.error('[GridStorm] Rendering error:', error, errorInfo.componentStack);\n }\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n return null;\n }\n return this.props.children;\n }\n}\n","// ─── GridStorm React Component ───\r\n// Production-grade React wrapper around the headless core engine.\r\n// Supports controlled + uncontrolled modes, React component cell/header\r\n// renderers via portals, event bridging, and comprehensive hooks.\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useMemo,\r\n useState,\r\n type CSSProperties,\r\n} from 'react';\r\nimport type {\r\n GridConfig,\r\n ColumnDef,\r\n GridEngine,\r\n} from '@gridstorm/core';\r\nimport { createGrid } from '@gridstorm/core';\r\nimport { DomRenderer } from '@gridstorm/dom-renderer';\r\nimport { GridContext, type GridContextValue } from './context';\r\nimport { PortalManager } from './portals/PortalManager';\r\nimport type { GridStormProps, ReactColumnDef } from './types';\r\nimport { GridErrorBoundary } from './ErrorBoundary';\r\n\r\n// ── useGridEngine hook (internal) ──\r\n// Uses useState + useEffect so that StrictMode's cleanup → remount cycle\r\n// creates a fresh engine each time instead of leaving a null ref.\r\n\r\nfunction useGridEngine<TData = any>(config: GridConfig<TData>): GridEngine<TData> | null {\r\n const [engine, setEngine] = useState<GridEngine<TData> | null>(null);\r\n const configRef = useRef(config);\r\n configRef.current = config;\r\n\r\n // Track whether the initial mount has completed so sync effects\r\n // don't double-set data that was already applied during createGrid.\r\n const rowDataMountedRef = useRef(false);\r\n const columnsMountedRef = useRef(false);\r\n\r\n // Create engine in useEffect so StrictMode can safely destroy + recreate\r\n useEffect(() => {\r\n const eng = createGrid(configRef.current);\r\n setEngine(eng);\r\n\r\n // Reset mounted flags when engine is (re)created\r\n rowDataMountedRef.current = false;\r\n columnsMountedRef.current = false;\r\n\r\n return () => {\r\n eng.destroy();\r\n setEngine(null);\r\n };\r\n }, []);\r\n\r\n // Sync rowData changes (skip the first run — createGrid already applied initial data)\r\n useEffect(() => {\r\n if (!engine) return;\r\n if (!rowDataMountedRef.current) {\r\n rowDataMountedRef.current = true;\r\n return;\r\n }\r\n if (config.rowData) {\r\n engine.api.setRowData(config.rowData);\r\n }\r\n }, [config.rowData, engine]);\r\n\r\n // Sync column changes (skip the first run — createGrid already applied initial columns)\r\n useEffect(() => {\r\n if (!engine) return;\r\n if (!columnsMountedRef.current) {\r\n columnsMountedRef.current = true;\r\n return;\r\n }\r\n if (config.columns) {\r\n engine.api.setColumnDefs(config.columns);\r\n }\r\n }, [config.columns, engine]);\r\n\r\n return engine;\r\n}\r\n\r\n// ── Column processing: convert ReactColumnDef[] → ColumnDef[] ──\r\n\r\nfunction processColumns<TData>(\r\n reactColumns: ReactColumnDef<TData>[],\r\n): ColumnDef<TData>[] {\r\n return reactColumns.map((col) => {\r\n const coreDef = { ...col } as any;\r\n\r\n // If cellRenderer is a React-wrapped renderer, keep the marker function\r\n // (it returns '' so DomRenderer creates empty cells; PortalManager handles rendering)\r\n // If it's a plain CellRendererFn, leave it as-is.\r\n // No conversion needed — the marker fn IS a valid CellRendererFn.\r\n\r\n // If headerRenderer is React-wrapped, same logic applies.\r\n\r\n // Remove React-only fields from the core column def\r\n delete coreDef.cellEditorComponent;\r\n\r\n return coreDef as ColumnDef<TData>;\r\n });\r\n}\r\n\r\n// ── Main Component ──\r\n\r\nexport function GridStorm<TData = any>(props: GridStormProps<TData>) {\r\n const {\r\n // GridConfig props\r\n columns: reactColumns,\r\n rowData,\r\n dataSource,\r\n rowModelType,\r\n getRowId,\r\n plugins,\r\n defaultColDef,\r\n rowHeight,\r\n headerHeight,\r\n domLayout,\r\n pinnedTopRowData,\r\n pinnedBottomRowData,\r\n suppressScrollX,\r\n suppressScrollY,\r\n rowSelection,\r\n editType,\r\n undoRedoCellEditing,\r\n pagination,\r\n paginationPageSize,\r\n animateRows,\r\n ariaLabel,\r\n locale,\r\n theme,\r\n // Controlled state props\r\n sortModel: controlledSortModel,\r\n onSortModelChange,\r\n filterModel: controlledFilterModel,\r\n onFilterModelChange,\r\n selectedRowIds: controlledSelectedRowIds,\r\n onSelectedRowIdsChange,\r\n currentPage: controlledCurrentPage,\r\n onCurrentPageChange,\r\n // Event props\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n // Renderer config props\r\n enableCellEditing,\r\n enableGrouping,\r\n groupIndent,\r\n checkboxSelection,\r\n checkboxColumnWidth,\r\n floatingFilter,\r\n floatingFilterDebounce,\r\n enablePagination,\r\n pageSizeOptions,\r\n // Component props\r\n height = 400,\r\n width = '100%',\r\n containerClass,\r\n containerStyle,\r\n contextMenu,\r\n children,\r\n // Rest are ignored (no HTML div passthrough to avoid TS errors)\r\n } = props;\r\n\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const rendererRef = useRef<DomRenderer | null>(null);\r\n const [rootElement, setRootElement] = useState<HTMLElement | null>(null);\r\n\r\n // ── Convert React columns to core columns ──\r\n const coreColumns = useMemo(\r\n () => processColumns(reactColumns),\r\n [reactColumns],\r\n );\r\n\r\n // ── Build core config (only depends on structural changes) ──\r\n const config = useMemo<GridConfig<TData>>(\r\n () => ({\r\n columns: coreColumns,\r\n rowData,\r\n dataSource,\r\n rowModelType,\r\n getRowId,\r\n plugins,\r\n defaultColDef,\r\n rowHeight,\r\n headerHeight,\r\n domLayout,\r\n pinnedTopRowData,\r\n pinnedBottomRowData,\r\n suppressScrollX,\r\n suppressScrollY,\r\n rowSelection,\r\n editType,\r\n undoRedoCellEditing,\r\n pagination,\r\n paginationPageSize,\r\n animateRows,\r\n ariaLabel,\r\n locale,\r\n theme,\r\n }),\r\n // Only recreate config on structural changes\r\n // eslint-disable-next-line -- intentional dependency omission\r\n [coreColumns, plugins, rowModelType, getRowId],\r\n );\r\n\r\n // ── Create grid engine ──\r\n const engine = useGridEngine<TData>(config);\r\n\r\n // ── Mount DOM renderer ──\r\n useEffect(() => {\r\n if (!containerRef.current || !engine) return;\r\n\r\n const renderer = new DomRenderer({\r\n container: containerRef.current,\r\n engine,\r\n enableCellEditing,\r\n enableGrouping,\r\n groupIndent,\r\n checkboxSelection,\r\n checkboxColumnWidth,\r\n floatingFilter,\r\n floatingFilterDebounce,\r\n enablePagination,\r\n pageSizeOptions,\r\n });\r\n renderer.mount();\r\n rendererRef.current = renderer;\r\n\r\n // Capture root element for portals\r\n const root = containerRef.current.querySelector<HTMLElement>('.gs-root');\r\n setRootElement(root);\r\n\r\n // Re-emit grid:ready now that the DOM renderer has mounted.\r\n // Plugins like column-resize, column-reorder, and context-menu\r\n // use requestAnimationFrame on grid:ready to inject DOM elements.\r\n // The original grid:ready fires during createGrid() before the\r\n // renderer exists, so those rAF callbacks find no DOM to work with.\r\n requestAnimationFrame(() => {\r\n engine.eventBus.emit('grid:ready', { api: engine.api });\r\n });\r\n\r\n return () => {\r\n renderer.destroy();\r\n rendererRef.current = null;\r\n setRootElement(null);\r\n };\r\n }, [engine]);\r\n\r\n // ── Controlled mode: install command bus middleware ──\r\n const controlledCallbacksRef = useRef({\r\n onSortModelChange,\r\n onFilterModelChange,\r\n onSelectedRowIdsChange,\r\n onCurrentPageChange,\r\n });\r\n controlledCallbacksRef.current = {\r\n onSortModelChange,\r\n onFilterModelChange,\r\n onSelectedRowIdsChange,\r\n onCurrentPageChange,\r\n };\r\n\r\n useEffect(() => {\r\n if (!engine) return;\r\n const removeMw = engine.commandBus.use((ctx) => {\r\n const cbs = controlledCallbacksRef.current;\r\n\r\n // Intercept sort commands in controlled mode\r\n if (ctx.commandType === 'sort:toggle' && cbs.onSortModelChange) {\r\n // Let the command execute to compute the new sort model,\r\n // then we'll intercept the result via the event listener\r\n return;\r\n }\r\n\r\n // Intercept selection in controlled mode\r\n if (ctx.commandType === 'selection:select' && cbs.onSelectedRowIdsChange) {\r\n // Let it through — we intercept via event\r\n return;\r\n }\r\n });\r\n\r\n return removeMw;\r\n }, [engine]);\r\n\r\n // ── Controlled mode: sync controlled props to engine ──\r\n useEffect(() => {\r\n if (controlledSortModel !== undefined && engine) {\r\n engine.api.setSortModel(controlledSortModel);\r\n }\r\n }, [controlledSortModel, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledFilterModel !== undefined && engine) {\r\n engine.api.setFilterModel(controlledFilterModel as any);\r\n }\r\n }, [controlledFilterModel, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledCurrentPage !== undefined && engine) {\r\n engine.api.paginationGoToPage(controlledCurrentPage);\r\n }\r\n }, [controlledCurrentPage, engine]);\r\n\r\n useEffect(() => {\r\n if (controlledSelectedRowIds !== undefined && engine) {\r\n engine.commandBus.dispatch('selection:set', {\r\n selectedRowIds: new Set(controlledSelectedRowIds),\r\n });\r\n }\r\n }, [controlledSelectedRowIds, engine]);\r\n\r\n // ── Event bridge: core events → React callbacks ──\r\n const eventCallbacksRef = useRef({\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n });\r\n eventCallbacksRef.current = {\r\n onGridReady,\r\n onRowDataChanged,\r\n onSelectionChanged,\r\n onSortChanged,\r\n onFilterChanged,\r\n onCellValueChanged,\r\n onCellClicked,\r\n onCellDoubleClicked,\r\n onRowClicked,\r\n onCellEditingStarted,\r\n onCellEditingStopped,\r\n onPaginationChanged,\r\n onColumnResized,\r\n };\r\n\r\n useEffect(() => {\r\n if (!engine) return;\r\n const eb = engine.eventBus;\r\n const cbs = () => eventCallbacksRef.current;\r\n\r\n const unsubs = [\r\n eb.on('rowData:changed', (e) => cbs().onRowDataChanged?.(e)),\r\n eb.on('selection:changed', (e) => {\r\n cbs().onSelectionChanged?.(e);\r\n // Controlled mode: notify parent of selection change\r\n controlledCallbacksRef.current.onSelectedRowIdsChange?.(\r\n engine.store.getState().selection.selectedRowIds,\r\n (e as any).source ?? 'api',\r\n );\r\n }),\r\n eb.on('column:sort:changed', (e) => {\r\n cbs().onSortChanged?.(e);\r\n // Controlled mode: notify parent of sort change\r\n controlledCallbacksRef.current.onSortModelChange?.(e.sortModel);\r\n }),\r\n eb.on('filter:changed', (e) => {\r\n cbs().onFilterChanged?.(e);\r\n controlledCallbacksRef.current.onFilterModelChange?.(e.filterModel);\r\n }),\r\n eb.on('cell:valueChanged', (e) => cbs().onCellValueChanged?.(e)),\r\n eb.on('cell:clicked', (e) => cbs().onCellClicked?.(e)),\r\n eb.on('cell:doubleClicked', (e) => cbs().onCellDoubleClicked?.(e)),\r\n eb.on('row:clicked', (e) => cbs().onRowClicked?.(e)),\r\n eb.on('cell:editingStarted', (e) => cbs().onCellEditingStarted?.(e)),\r\n eb.on('cell:editingStopped', (e) => cbs().onCellEditingStopped?.(e)),\r\n eb.on('pagination:changed', (e) => {\r\n cbs().onPaginationChanged?.(e);\r\n controlledCallbacksRef.current.onCurrentPageChange?.(e.currentPage);\r\n }),\r\n eb.on('column:resized', (e) => cbs().onColumnResized?.(e)),\r\n ];\r\n\r\n return () => unsubs.forEach((u) => u());\r\n }, [engine]);\r\n\r\n // ── Fire onGridReady ──\r\n useEffect(() => {\r\n if (engine) {\r\n onGridReady?.(engine.api);\r\n }\r\n }, [engine]); // eslint-disable-line -- intentional dependency omission\r\n\r\n // ── Container style ──\r\n const style: CSSProperties = {\r\n height: typeof height === 'number' ? `${height}px` : height,\r\n width: typeof width === 'number' ? `${width}px` : width,\r\n ...containerStyle,\r\n };\r\n\r\n // ── Context value (stable reference) ──\r\n const contextValue = useMemo<GridContextValue<TData> | null>(\r\n () => (engine ? { engine, api: engine.api, rootElement } : null),\r\n [engine, rootElement],\r\n );\r\n\r\n // ── Before engine is ready (first render before useEffect), render only the container ──\r\n if (!engine || !contextValue) {\r\n return (\r\n <GridErrorBoundary>\r\n <div\r\n ref={containerRef}\r\n className={`gs-container ${containerClass ?? ''}`.trim()}\r\n style={style}\r\n />\r\n </GridErrorBoundary>\r\n );\r\n }\r\n\r\n return (\r\n <GridErrorBoundary>\r\n <GridContext.Provider value={contextValue as GridContextValue}>\r\n {children}\r\n <div\r\n ref={containerRef}\r\n className={`gs-container ${containerClass ?? ''}`.trim()}\r\n style={style}\r\n />\r\n <PortalManager\r\n engine={engine}\r\n api={engine.api}\r\n columns={reactColumns}\r\n rootElement={rootElement}\r\n contextMenuComponent={contextMenu}\r\n />\r\n </GridContext.Provider>\r\n </GridErrorBoundary>\r\n );\r\n}\r\n","// ─── useGridApi Hook ───\n// Access the GridApi from context.\n\nimport type { GridApi } from '@gridstorm/core';\nimport { useGridContext } from '../context';\n\n/**\n * Access the GridApi instance.\n * Must be used within a `<GridStorm>` component.\n */\nexport function useGridApi<TData = any>(): GridApi<TData> {\n return useGridContext<TData>().api;\n}\n","// ─── useGridState Hook ───\r\n// Selector-based reactive state subscription via useSyncExternalStore.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { GridState } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\n/**\r\n * Subscribe to grid state changes with a selector.\r\n * Re-renders only when the selected value changes (reference equality).\r\n *\r\n * @example\r\n * ```tsx\r\n * const rowCount = useGridState(state => state.displayedRowIds.length);\r\n * const sortModel = useGridState(state => state.sortModel);\r\n * ```\r\n */\r\nexport function useGridState<TData = any, TResult = any>(\r\n selector: (state: GridState<TData>) => TResult,\r\n): TResult {\r\n const { engine } = useGridContext<TData>();\r\n\r\n // Memoize getSnapshot so useSyncExternalStore doesn't re-subscribe every render\r\n const getSnapshot = useCallback(\r\n () => selector(engine.store.getState() as GridState<TData>),\r\n [selector, engine],\r\n );\r\n\r\n return useSyncExternalStore(\r\n (onStoreChange) => engine.store.subscribe(onStoreChange),\r\n getSnapshot,\r\n getSnapshot,\r\n );\r\n}\r\n","// ─── useGridSelection Hook ───\r\n// Selection state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { RowNode } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridSelectionResult<TData = any> {\r\n /** Set of selected row IDs. */\r\n selectedRowIds: Set<string>;\r\n /** Number of selected rows. */\r\n selectedCount: number;\r\n /** Get selected row data objects. */\r\n getSelectedRows: () => TData[];\r\n /** Get selected RowNode objects. */\r\n getSelectedNodes: () => RowNode<TData>[];\r\n /** Check if a specific row is selected. */\r\n isRowSelected: (rowId: string) => boolean;\r\n /** Select all visible rows. */\r\n selectAll: () => void;\r\n /** Deselect all rows. */\r\n deselectAll: () => void;\r\n}\r\n\r\n/**\r\n * Access selection state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { selectedCount, selectAll, deselectAll, isRowSelected } = useGridSelection();\r\n * ```\r\n */\r\nexport function useGridSelection<TData = any>(): GridSelectionResult<TData> {\r\n const { engine, api } = useGridContext<TData>();\r\n\r\n const getSelectionSnapshot = useCallback(() => engine.store.getState().selection.selectedRowIds, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const selectedRowIds = useSyncExternalStore(\r\n subscribe,\r\n getSelectionSnapshot,\r\n getSelectionSnapshot,\r\n );\r\n\r\n const selectedCount = selectedRowIds.size;\r\n\r\n const isRowSelected = useCallback(\r\n (rowId: string) =>\r\n engine.store.getState().selection.selectedRowIds.has(rowId),\r\n [engine],\r\n );\r\n\r\n const getSelectedRows = useCallback(() => api.getSelectedRows(), [api]);\r\n const getSelectedNodes = useCallback(() => api.getSelectedNodes(), [api]);\r\n const selectAll = useCallback(() => api.selectAll(), [api]);\r\n const deselectAll = useCallback(() => api.deselectAll(), [api]);\r\n\r\n return {\r\n selectedRowIds,\r\n selectedCount,\r\n getSelectedRows,\r\n getSelectedNodes,\r\n isRowSelected,\r\n selectAll,\r\n deselectAll,\r\n };\r\n}\r\n","// ─── useGridSort Hook ───\r\n// Sort model state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { SortModelItem } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridSortResult {\r\n /** Current sort model. */\r\n sortModel: SortModelItem[];\r\n /** Whether any sort is active. */\r\n isSorted: boolean;\r\n /** Set the sort model directly. */\r\n setSortModel: (model: SortModelItem[]) => void;\r\n /** Toggle sort on a column. */\r\n toggleSort: (colId: string, multiSort?: boolean) => void;\r\n /** Clear all sort. */\r\n clearSort: () => void;\r\n}\r\n\r\n/**\r\n * Access sort state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { sortModel, isSorted, toggleSort, clearSort } = useGridSort();\r\n * ```\r\n */\r\nexport function useGridSort(): GridSortResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getSortSnapshot = useCallback(() => engine.store.getState().sortModel, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const sortModel = useSyncExternalStore(\r\n subscribe,\r\n getSortSnapshot,\r\n getSortSnapshot,\r\n );\r\n\r\n const isSorted = sortModel.length > 0;\r\n\r\n const setSortModel = useCallback(\r\n (model: SortModelItem[]) => api.setSortModel(model),\r\n [api],\r\n );\r\n\r\n const toggleSort = useCallback(\r\n (colId: string, multiSort = false) => {\r\n engine.commandBus.dispatch('sort:toggle', { colId, multiSort });\r\n },\r\n [engine],\r\n );\r\n\r\n const clearSort = useCallback(() => api.setSortModel([]), [api]);\r\n\r\n return { sortModel, isSorted, setSortModel, toggleSort, clearSort };\r\n}\r\n","// ─── useGridFilter Hook ───\r\n// Filter model state and actions.\r\n\r\nimport { useSyncExternalStore, useCallback } from 'react';\r\nimport type { FilterModel } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridFilterResult {\r\n /** Current filter model (keyed by column ID). */\r\n filterModel: Record<string, FilterModel>;\r\n /** Current quick filter text. */\r\n quickFilterText: string;\r\n /** Whether any filter is active. */\r\n isFiltered: boolean;\r\n /** Set the filter model. */\r\n setFilterModel: (model: Record<string, FilterModel>) => void;\r\n /** Set quick filter text. */\r\n setQuickFilter: (text: string) => void;\r\n /** Clear all filters. */\r\n clearFilters: () => void;\r\n}\r\n\r\n/**\r\n * Access filter state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { isFiltered, setQuickFilter, clearFilters } = useGridFilter();\r\n * ```\r\n */\r\nexport function useGridFilter(): GridFilterResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getFilterSnapshot = useCallback(() => engine.store.getState().filterModel, [engine]);\r\n const getQuickFilterSnapshot = useCallback(() => engine.store.getState().quickFilterText, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const filterModel = useSyncExternalStore(\r\n subscribe,\r\n getFilterSnapshot,\r\n getFilterSnapshot,\r\n );\r\n\r\n const quickFilterText = useSyncExternalStore(\r\n subscribe,\r\n getQuickFilterSnapshot,\r\n getQuickFilterSnapshot,\r\n );\r\n\r\n const isFiltered =\r\n Object.keys(filterModel).length > 0 || quickFilterText.length > 0;\r\n\r\n const setFilterModel = useCallback(\r\n (model: Record<string, FilterModel>) => api.setFilterModel(model),\r\n [api],\r\n );\r\n\r\n const setQuickFilter = useCallback(\r\n (text: string) => api.setQuickFilter(text),\r\n [api],\r\n );\r\n\r\n const clearFilters = useCallback(() => {\r\n api.setFilterModel({});\r\n api.setQuickFilter('');\r\n }, [api]);\r\n\r\n return {\r\n filterModel,\r\n quickFilterText,\r\n isFiltered,\r\n setFilterModel,\r\n setQuickFilter,\r\n clearFilters,\r\n };\r\n}\r\n","// ─── useGridPagination Hook ───\r\n// Pagination state and navigation actions.\r\n\r\nimport { useSyncExternalStore, useCallback, useMemo } from 'react';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridPaginationResult {\r\n /** Current page (0-indexed). */\r\n currentPage: number;\r\n /** Total number of pages. */\r\n totalPages: number;\r\n /** Rows per page. */\r\n pageSize: number;\r\n /** Total row count (after filtering). */\r\n totalRows: number;\r\n /** Is there a next page? */\r\n hasNextPage: boolean;\r\n /** Is there a previous page? */\r\n hasPreviousPage: boolean;\r\n /** Go to a specific page. */\r\n goToPage: (page: number) => void;\r\n /** Go to next page. */\r\n nextPage: () => void;\r\n /** Go to previous page. */\r\n previousPage: () => void;\r\n /** Go to first page. */\r\n firstPage: () => void;\r\n /** Go to last page. */\r\n lastPage: () => void;\r\n}\r\n\r\n/**\r\n * Access pagination state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { currentPage, totalPages, nextPage, previousPage } = useGridPagination();\r\n * ```\r\n */\r\nexport function useGridPagination(): GridPaginationResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getPaginationSnapshot = useCallback(() => engine.store.getState().pagination, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const paginationState = useSyncExternalStore(\r\n subscribe,\r\n getPaginationSnapshot,\r\n getPaginationSnapshot,\r\n );\r\n\r\n const { currentPage, pageSize, totalRows } = paginationState;\r\n const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));\r\n const hasNextPage = currentPage < totalPages - 1;\r\n const hasPreviousPage = currentPage > 0;\r\n\r\n const goToPage = useCallback(\r\n (page: number) => api.paginationGoToPage(page),\r\n [api],\r\n );\r\n\r\n const nextPage = useCallback(() => {\r\n if (hasNextPage) api.paginationGoToPage(currentPage + 1);\r\n }, [api, currentPage, hasNextPage]);\r\n\r\n const previousPage = useCallback(() => {\r\n if (hasPreviousPage) api.paginationGoToPage(currentPage - 1);\r\n }, [api, currentPage, hasPreviousPage]);\r\n\r\n const firstPage = useCallback(() => api.paginationGoToPage(0), [api]);\r\n\r\n const lastPage = useCallback(\r\n () => api.paginationGoToPage(totalPages - 1),\r\n [api, totalPages],\r\n );\r\n\r\n return useMemo(\r\n () => ({\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n }),\r\n [\r\n currentPage,\r\n totalPages,\r\n pageSize,\r\n totalRows,\r\n hasNextPage,\r\n hasPreviousPage,\r\n goToPage,\r\n nextPage,\r\n previousPage,\r\n firstPage,\r\n lastPage,\r\n ],\r\n );\r\n}\r\n","// ─── useGridEvent Hook ───\n// Subscribe to typed grid events.\n\nimport { useEffect, useRef } from 'react';\nimport type { GridEventMap } from '@gridstorm/core';\nimport { useGridContext } from '../context';\n\n/**\n * Subscribe to a specific grid event.\n * Handler ref prevents stale closures without re-subscribing.\n *\n * @example\n * ```tsx\n * useGridEvent('cell:clicked', (event) => {\n * console.log('Clicked cell:', event.colId, event.value);\n * });\n * ```\n */\nexport function useGridEvent<\n TData = any,\n K extends keyof GridEventMap<TData> = any,\n>(\n event: K,\n handler: (payload: GridEventMap<TData>[K]) => void,\n): void {\n const { engine } = useGridContext<TData>();\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const unsub = engine.eventBus.on(event as any, (payload: any) => {\n handlerRef.current(payload);\n });\n return unsub;\n }, [engine, event]);\n}\n","// ─── useGridColumn Hook ───\r\n// Column state and manipulation actions.\r\n\r\nimport { useSyncExternalStore, useCallback, useMemo } from 'react';\r\nimport type { ColumnState, PinnedPosition } from '@gridstorm/core';\r\nimport { useGridContext } from '../context';\r\n\r\ninterface GridColumnResult {\r\n /** All columns (including hidden). */\r\n allColumns: ColumnState[];\r\n /** Only visible columns. */\r\n visibleColumns: ColumnState[];\r\n /** Set a column's visibility. */\r\n setColumnVisible: (colId: string, visible: boolean) => void;\r\n /** Set a column's width. */\r\n setColumnWidth: (colId: string, width: number) => void;\r\n /** Move a column to a new index. */\r\n moveColumn: (colId: string, toIndex: number) => void;\r\n /** Pin a column. */\r\n setColumnPinned: (colId: string, pinned: PinnedPosition) => void;\r\n /** Get a single column by ID. */\r\n getColumn: (colId: string) => ColumnState | undefined;\r\n}\r\n\r\n/**\r\n * Access column state and actions.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { visibleColumns, setColumnVisible, setColumnWidth } = useGridColumn();\r\n * ```\r\n */\r\nexport function useGridColumn(): GridColumnResult {\r\n const { engine, api } = useGridContext();\r\n\r\n const getColumnsSnapshot = useCallback(() => engine.store.getState().columns, [engine]);\r\n const subscribe = useCallback((cb: () => void) => engine.store.subscribe(cb), [engine]);\r\n\r\n const allColumns = useSyncExternalStore(\r\n subscribe,\r\n getColumnsSnapshot,\r\n getColumnsSnapshot,\r\n );\r\n\r\n const visibleColumns = useMemo(\r\n () => allColumns.filter((c) => !c.hide),\r\n [allColumns],\r\n );\r\n\r\n const setColumnVisible = useCallback(\r\n (colId: string, visible: boolean) => api.setColumnVisible(colId, visible),\r\n [api],\r\n );\r\n\r\n const setColumnWidth = useCallback(\r\n (colId: string, width: number) => api.setColumnWidth(colId, width),\r\n [api],\r\n );\r\n\r\n const moveColumn = useCallback(\r\n (colId: string, toIndex: number) => api.moveColumn(colId, toIndex),\r\n [api],\r\n );\r\n\r\n const setColumnPinned = useCallback(\r\n (colId: string, pinned: PinnedPosition) =>\r\n api.setColumnPinned(colId, pinned),\r\n [api],\r\n );\r\n\r\n const getColumn = useCallback(\r\n (colId: string) => api.getColumn(colId),\r\n [api],\r\n );\r\n\r\n return {\r\n allColumns,\r\n visibleColumns,\r\n setColumnVisible,\r\n setColumnWidth,\r\n moveColumn,\r\n setColumnPinned,\r\n getColumn,\r\n };\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridstorm/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "GridStorm React adapter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -66,10 +66,10 @@
|
|
|
66
66
|
"bugs": {
|
|
67
67
|
"url": "https://github.com/007krcs/grid-data/issues"
|
|
68
68
|
},
|
|
69
|
-
"homepage": "https://
|
|
69
|
+
"homepage": "https://gridstorm.tekivex.com",
|
|
70
70
|
"author": {
|
|
71
71
|
"name": "GridStorm",
|
|
72
|
-
"url": "https://
|
|
72
|
+
"url": "https://gridstorm.tekivex.com/"
|
|
73
73
|
},
|
|
74
74
|
"funding": {
|
|
75
75
|
"type": "github",
|