photon-grid-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -0
- package/README.md +0 -0
- package/cell-selection/active-grid-registry.d.ts +37 -0
- package/cell-selection/active-grid-registry.d.ts.map +1 -0
- package/cell-selection/active-grid-registry.js +25 -0
- package/cell-selection/active-grid-registry.js.map +1 -0
- package/cell-selection/cell-selection-engine.d.ts +336 -0
- package/cell-selection/cell-selection-engine.d.ts.map +1 -0
- package/cell-selection/cell-selection-engine.js +1534 -0
- package/cell-selection/cell-selection-engine.js.map +1 -0
- package/cell-selection/selection-range.d.ts +16 -0
- package/cell-selection/selection-range.d.ts.map +1 -0
- package/cell-selection/selection-range.js +48 -0
- package/cell-selection/selection-range.js.map +1 -0
- package/cell-selection/selection-renderer.d.ts +24 -0
- package/cell-selection/selection-renderer.d.ts.map +1 -0
- package/cell-selection/selection-renderer.js +107 -0
- package/cell-selection/selection-renderer.js.map +1 -0
- package/chart/chart-analyzer/aggregation-analyzer.d.ts +18 -0
- package/chart/chart-analyzer/aggregation-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/aggregation-analyzer.js +63 -0
- package/chart/chart-analyzer/aggregation-analyzer.js.map +1 -0
- package/chart/chart-analyzer/bar-analyzer.d.ts +19 -0
- package/chart/chart-analyzer/bar-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/bar-analyzer.js +56 -0
- package/chart/chart-analyzer/bar-analyzer.js.map +1 -0
- package/chart/chart-analyzer/bubble-analyzer.d.ts +16 -0
- package/chart/chart-analyzer/bubble-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/bubble-analyzer.js +61 -0
- package/chart/chart-analyzer/bubble-analyzer.js.map +1 -0
- package/chart/chart-analyzer/cardinality-analyzer.d.ts +13 -0
- package/chart/chart-analyzer/cardinality-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/cardinality-analyzer.js +28 -0
- package/chart/chart-analyzer/cardinality-analyzer.js.map +1 -0
- package/chart/chart-analyzer/dimension-analyzer.d.ts +12 -0
- package/chart/chart-analyzer/dimension-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/dimension-analyzer.js +33 -0
- package/chart/chart-analyzer/dimension-analyzer.js.map +1 -0
- package/chart/chart-analyzer/histogram-analyzer.d.ts +11 -0
- package/chart/chart-analyzer/histogram-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/histogram-analyzer.js +43 -0
- package/chart/chart-analyzer/histogram-analyzer.js.map +1 -0
- package/chart/chart-analyzer/index.d.ts +58 -0
- package/chart/chart-analyzer/index.d.ts.map +1 -0
- package/chart/chart-analyzer/index.js +130 -0
- package/chart/chart-analyzer/index.js.map +1 -0
- package/chart/chart-analyzer/line-analyzer.d.ts +23 -0
- package/chart/chart-analyzer/line-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/line-analyzer.js +61 -0
- package/chart/chart-analyzer/line-analyzer.js.map +1 -0
- package/chart/chart-analyzer/measure-analyzer.d.ts +11 -0
- package/chart/chart-analyzer/measure-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/measure-analyzer.js +44 -0
- package/chart/chart-analyzer/measure-analyzer.js.map +1 -0
- package/chart/chart-analyzer/pie-analyzer.d.ts +19 -0
- package/chart/chart-analyzer/pie-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/pie-analyzer.js +64 -0
- package/chart/chart-analyzer/pie-analyzer.js.map +1 -0
- package/chart/chart-analyzer/recommendation-engine.d.ts +18 -0
- package/chart/chart-analyzer/recommendation-engine.d.ts.map +1 -0
- package/chart/chart-analyzer/recommendation-engine.js +82 -0
- package/chart/chart-analyzer/recommendation-engine.js.map +1 -0
- package/chart/chart-analyzer/scatter-analyzer.d.ts +16 -0
- package/chart/chart-analyzer/scatter-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer/scatter-analyzer.js +70 -0
- package/chart/chart-analyzer/scatter-analyzer.js.map +1 -0
- package/chart/chart-analyzer/types.d.ts +52 -0
- package/chart/chart-analyzer/types.d.ts.map +1 -0
- package/chart/chart-analyzer/types.js +10 -0
- package/chart/chart-analyzer/types.js.map +1 -0
- package/chart/chart-analyzer.d.ts +12 -0
- package/chart/chart-analyzer.d.ts.map +1 -0
- package/chart/chart-analyzer.js +77 -0
- package/chart/chart-analyzer.js.map +1 -0
- package/chart/chart-data-transformer.d.ts +26 -0
- package/chart/chart-data-transformer.d.ts.map +1 -0
- package/chart/chart-data-transformer.js +93 -0
- package/chart/chart-data-transformer.js.map +1 -0
- package/chart/chart-engine.d.ts +38 -0
- package/chart/chart-engine.d.ts.map +1 -0
- package/chart/chart-engine.js +96 -0
- package/chart/chart-engine.js.map +1 -0
- package/chart/chart-panel.d.ts +54 -0
- package/chart/chart-panel.d.ts.map +1 -0
- package/chart/chart-panel.js +350 -0
- package/chart/chart-panel.js.map +1 -0
- package/chart/chart-renderer.d.ts +93 -0
- package/chart/chart-renderer.d.ts.map +1 -0
- package/chart/chart-renderer.js +1330 -0
- package/chart/chart-renderer.js.map +1 -0
- package/chart/sparkline/sparkline-renderer.d.ts +269 -0
- package/chart/sparkline/sparkline-renderer.d.ts.map +1 -0
- package/chart/sparkline/sparkline-renderer.js +875 -0
- package/chart/sparkline/sparkline-renderer.js.map +1 -0
- package/chart/sparkline/sparkline.types.d.ts +214 -0
- package/chart/sparkline/sparkline.types.d.ts.map +1 -0
- package/chart/sparkline/sparkline.types.js +8 -0
- package/chart/sparkline/sparkline.types.js.map +1 -0
- package/column-groups/column-group-drag-handler.d.ts +169 -0
- package/column-groups/column-group-drag-handler.d.ts.map +1 -0
- package/column-groups/column-group-drag-handler.js +517 -0
- package/column-groups/column-group-drag-handler.js.map +1 -0
- package/column-groups/column-group-header-builder.d.ts +106 -0
- package/column-groups/column-group-header-builder.d.ts.map +1 -0
- package/column-groups/column-group-header-builder.js +311 -0
- package/column-groups/column-group-header-builder.js.map +1 -0
- package/column-groups/column-group-model.d.ts +248 -0
- package/column-groups/column-group-model.d.ts.map +1 -0
- package/column-groups/column-group-model.js +668 -0
- package/column-groups/column-group-model.js.map +1 -0
- package/column-groups/column-group-state-manager.d.ts +110 -0
- package/column-groups/column-group-state-manager.d.ts.map +1 -0
- package/column-groups/column-group-state-manager.js +153 -0
- package/column-groups/column-group-state-manager.js.map +1 -0
- package/column-groups/column-group.types.d.ts +250 -0
- package/column-groups/column-group.types.d.ts.map +1 -0
- package/column-groups/column-group.types.js +20 -0
- package/column-groups/column-group.types.js.map +1 -0
- package/column-groups/display-group-builder.d.ts +91 -0
- package/column-groups/display-group-builder.d.ts.map +1 -0
- package/column-groups/display-group-builder.js +225 -0
- package/column-groups/display-group-builder.js.map +1 -0
- package/column-groups/display-group-drag-handler.d.ts +205 -0
- package/column-groups/display-group-drag-handler.d.ts.map +1 -0
- package/column-groups/display-group-drag-handler.js +536 -0
- package/column-groups/display-group-drag-handler.js.map +1 -0
- package/column-groups/display-group-engine.d.ts +310 -0
- package/column-groups/display-group-engine.d.ts.map +1 -0
- package/column-groups/display-group-engine.js +549 -0
- package/column-groups/display-group-engine.js.map +1 -0
- package/column-groups/display-group-header-builder.d.ts +94 -0
- package/column-groups/display-group-header-builder.d.ts.map +1 -0
- package/column-groups/display-group-header-builder.js +224 -0
- package/column-groups/display-group-header-builder.js.map +1 -0
- package/column-groups/display-group.types.d.ts +140 -0
- package/column-groups/display-group.types.d.ts.map +1 -0
- package/column-groups/display-group.types.js +2 -0
- package/column-groups/display-group.types.js.map +1 -0
- package/column-groups/index.d.ts +25 -0
- package/column-groups/index.d.ts.map +1 -0
- package/column-groups/index.js +26 -0
- package/column-groups/index.js.map +1 -0
- package/column-groups/logical-group-registry.d.ts +77 -0
- package/column-groups/logical-group-registry.d.ts.map +1 -0
- package/column-groups/logical-group-registry.js +118 -0
- package/column-groups/logical-group-registry.js.map +1 -0
- package/core/column-model.d.ts +30 -0
- package/core/column-model.d.ts.map +1 -0
- package/core/column-model.js +203 -0
- package/core/column-model.js.map +1 -0
- package/core/grid-api.d.ts +187 -0
- package/core/grid-api.d.ts.map +1 -0
- package/core/grid-api.js +569 -0
- package/core/grid-api.js.map +1 -0
- package/core/grid-context.d.ts +61 -0
- package/core/grid-context.d.ts.map +1 -0
- package/core/grid-context.js +2 -0
- package/core/grid-context.js.map +1 -0
- package/core/grid-core.d.ts +49 -0
- package/core/grid-core.d.ts.map +1 -0
- package/core/grid-core.js +675 -0
- package/core/grid-core.js.map +1 -0
- package/core/grid-store.d.ts +62 -0
- package/core/grid-store.d.ts.map +1 -0
- package/core/grid-store.js +104 -0
- package/core/grid-store.js.map +1 -0
- package/core/row-model.d.ts +32 -0
- package/core/row-model.d.ts.map +1 -0
- package/core/row-model.js +150 -0
- package/core/row-model.js.map +1 -0
- package/drag-drop/drag-autoscroll.d.ts +14 -0
- package/drag-drop/drag-autoscroll.d.ts.map +1 -0
- package/drag-drop/drag-autoscroll.js +66 -0
- package/drag-drop/drag-autoscroll.js.map +1 -0
- package/drag-drop/drag-drop-engine.d.ts +55 -0
- package/drag-drop/drag-drop-engine.d.ts.map +1 -0
- package/drag-drop/drag-drop-engine.js +179 -0
- package/drag-drop/drag-drop-engine.js.map +1 -0
- package/drag-drop/drag-preview.d.ts +32 -0
- package/drag-drop/drag-preview.d.ts.map +1 -0
- package/drag-drop/drag-preview.js +74 -0
- package/drag-drop/drag-preview.js.map +1 -0
- package/engines/aggregation/aggregation-engine.d.ts +66 -0
- package/engines/aggregation/aggregation-engine.d.ts.map +1 -0
- package/engines/aggregation/aggregation-engine.js +149 -0
- package/engines/aggregation/aggregation-engine.js.map +1 -0
- package/engines/clipboard/clipboard-engine.d.ts +89 -0
- package/engines/clipboard/clipboard-engine.d.ts.map +1 -0
- package/engines/clipboard/clipboard-engine.js +323 -0
- package/engines/clipboard/clipboard-engine.js.map +1 -0
- package/engines/editing/cell-editor-engine.d.ts +62 -0
- package/engines/editing/cell-editor-engine.d.ts.map +1 -0
- package/engines/editing/cell-editor-engine.js +359 -0
- package/engines/editing/cell-editor-engine.js.map +1 -0
- package/engines/editing/custom-dropdown-editor.d.ts +99 -0
- package/engines/editing/custom-dropdown-editor.d.ts.map +1 -0
- package/engines/editing/custom-dropdown-editor.js +355 -0
- package/engines/editing/custom-dropdown-editor.js.map +1 -0
- package/engines/editing/value-parser.d.ts +12 -0
- package/engines/editing/value-parser.d.ts.map +1 -0
- package/engines/editing/value-parser.js +125 -0
- package/engines/editing/value-parser.js.map +1 -0
- package/engines/export/export-engine.d.ts +16 -0
- package/engines/export/export-engine.d.ts.map +1 -0
- package/engines/export/export-engine.js +99 -0
- package/engines/export/export-engine.js.map +1 -0
- package/engines/filter/filter-condition.d.ts +7 -0
- package/engines/filter/filter-condition.d.ts.map +1 -0
- package/engines/filter/filter-condition.js +126 -0
- package/engines/filter/filter-condition.js.map +1 -0
- package/engines/filter/filter-engine.d.ts +35 -0
- package/engines/filter/filter-engine.d.ts.map +1 -0
- package/engines/filter/filter-engine.js +150 -0
- package/engines/filter/filter-engine.js.map +1 -0
- package/engines/filter/filter-panel.d.ts +103 -0
- package/engines/filter/filter-panel.d.ts.map +1 -0
- package/engines/filter/filter-panel.js +645 -0
- package/engines/filter/filter-panel.js.map +1 -0
- package/engines/grouping/group-node.d.ts +21 -0
- package/engines/grouping/group-node.d.ts.map +1 -0
- package/engines/grouping/group-node.js +96 -0
- package/engines/grouping/group-node.js.map +1 -0
- package/engines/grouping/grouping-engine.d.ts +33 -0
- package/engines/grouping/grouping-engine.d.ts.map +1 -0
- package/engines/grouping/grouping-engine.js +118 -0
- package/engines/grouping/grouping-engine.js.map +1 -0
- package/engines/master-detail/master-detail-engine.d.ts +77 -0
- package/engines/master-detail/master-detail-engine.d.ts.map +1 -0
- package/engines/master-detail/master-detail-engine.js +199 -0
- package/engines/master-detail/master-detail-engine.js.map +1 -0
- package/engines/pagination/pagination-engine.d.ts +33 -0
- package/engines/pagination/pagination-engine.d.ts.map +1 -0
- package/engines/pagination/pagination-engine.js +110 -0
- package/engines/pagination/pagination-engine.js.map +1 -0
- package/engines/selection/row-selection-engine.d.ts +26 -0
- package/engines/selection/row-selection-engine.d.ts.map +1 -0
- package/engines/selection/row-selection-engine.js +145 -0
- package/engines/selection/row-selection-engine.js.map +1 -0
- package/engines/sort/sort-comparator.d.ts +43 -0
- package/engines/sort/sort-comparator.d.ts.map +1 -0
- package/engines/sort/sort-comparator.js +113 -0
- package/engines/sort/sort-comparator.js.map +1 -0
- package/engines/sort/sort-engine.d.ts +67 -0
- package/engines/sort/sort-engine.d.ts.map +1 -0
- package/engines/sort/sort-engine.js +178 -0
- package/engines/sort/sort-engine.js.map +1 -0
- package/engines/summary/summary-engine.d.ts +17 -0
- package/engines/summary/summary-engine.d.ts.map +1 -0
- package/engines/summary/summary-engine.js +72 -0
- package/engines/summary/summary-engine.js.map +1 -0
- package/engines/tree/tree-data-service.d.ts +117 -0
- package/engines/tree/tree-data-service.d.ts.map +1 -0
- package/engines/tree/tree-data-service.js +296 -0
- package/engines/tree/tree-data-service.js.map +1 -0
- package/engines/tree/tree-expansion-service.d.ts +35 -0
- package/engines/tree/tree-expansion-service.d.ts.map +1 -0
- package/engines/tree/tree-expansion-service.js +84 -0
- package/engines/tree/tree-expansion-service.js.map +1 -0
- package/engines/tree/tree-node.d.ts +40 -0
- package/engines/tree/tree-node.d.ts.map +1 -0
- package/engines/tree/tree-node.js +199 -0
- package/engines/tree/tree-node.js.map +1 -0
- package/engines/tree/tree-selection-service.d.ts +35 -0
- package/engines/tree/tree-selection-service.d.ts.map +1 -0
- package/engines/tree/tree-selection-service.js +72 -0
- package/engines/tree/tree-selection-service.js.map +1 -0
- package/engines/undo-redo/undo-redo-engine.d.ts +114 -0
- package/engines/undo-redo/undo-redo-engine.d.ts.map +1 -0
- package/engines/undo-redo/undo-redo-engine.js +165 -0
- package/engines/undo-redo/undo-redo-engine.js.map +1 -0
- package/event-bus/event-bus.d.ts +21 -0
- package/event-bus/event-bus.d.ts.map +1 -0
- package/event-bus/event-bus.js +106 -0
- package/event-bus/event-bus.js.map +1 -0
- package/icons/icon-registry.d.ts +19 -0
- package/icons/icon-registry.d.ts.map +1 -0
- package/icons/icon-registry.js +37 -0
- package/icons/icon-registry.js.map +1 -0
- package/icons/icon-renderer.d.ts +18 -0
- package/icons/icon-renderer.d.ts.map +1 -0
- package/icons/icon-renderer.js +75 -0
- package/icons/icon-renderer.js.map +1 -0
- package/icons/icon-sets/core-icons.d.ts +2 -0
- package/icons/icon-sets/core-icons.d.ts.map +1 -0
- package/icons/icon-sets/core-icons.js +48 -0
- package/icons/icon-sets/core-icons.js.map +1 -0
- package/index.d.ts +72 -0
- package/index.d.ts.map +1 -0
- package/index.js +54 -0
- package/index.js.map +1 -0
- package/package.json +64 -0
- package/photon-ai/builtins/filter.commands.d.ts +4 -0
- package/photon-ai/builtins/filter.commands.d.ts.map +1 -0
- package/photon-ai/builtins/filter.commands.js +189 -0
- package/photon-ai/builtins/filter.commands.js.map +1 -0
- package/photon-ai/builtins/grouping.commands.d.ts +4 -0
- package/photon-ai/builtins/grouping.commands.d.ts.map +1 -0
- package/photon-ai/builtins/grouping.commands.js +115 -0
- package/photon-ai/builtins/grouping.commands.js.map +1 -0
- package/photon-ai/builtins/index.d.ts +10 -0
- package/photon-ai/builtins/index.d.ts.map +1 -0
- package/photon-ai/builtins/index.js +26 -0
- package/photon-ai/builtins/index.js.map +1 -0
- package/photon-ai/builtins/info.commands.d.ts +4 -0
- package/photon-ai/builtins/info.commands.d.ts.map +1 -0
- package/photon-ai/builtins/info.commands.js +201 -0
- package/photon-ai/builtins/info.commands.js.map +1 -0
- package/photon-ai/builtins/move.commands.d.ts +4 -0
- package/photon-ai/builtins/move.commands.d.ts.map +1 -0
- package/photon-ai/builtins/move.commands.js +53 -0
- package/photon-ai/builtins/move.commands.js.map +1 -0
- package/photon-ai/builtins/pin.commands.d.ts +4 -0
- package/photon-ai/builtins/pin.commands.d.ts.map +1 -0
- package/photon-ai/builtins/pin.commands.js +106 -0
- package/photon-ai/builtins/pin.commands.js.map +1 -0
- package/photon-ai/builtins/selection.commands.d.ts +4 -0
- package/photon-ai/builtins/selection.commands.d.ts.map +1 -0
- package/photon-ai/builtins/selection.commands.js +102 -0
- package/photon-ai/builtins/selection.commands.js.map +1 -0
- package/photon-ai/builtins/sort.commands.d.ts +4 -0
- package/photon-ai/builtins/sort.commands.d.ts.map +1 -0
- package/photon-ai/builtins/sort.commands.js +67 -0
- package/photon-ai/builtins/sort.commands.js.map +1 -0
- package/photon-ai/builtins/visibility.commands.d.ts +4 -0
- package/photon-ai/builtins/visibility.commands.d.ts.map +1 -0
- package/photon-ai/builtins/visibility.commands.js +75 -0
- package/photon-ai/builtins/visibility.commands.js.map +1 -0
- package/photon-ai/command-builder.d.ts +21 -0
- package/photon-ai/command-builder.d.ts.map +1 -0
- package/photon-ai/command-builder.js +18 -0
- package/photon-ai/command-builder.js.map +1 -0
- package/photon-ai/command-executor.d.ts +15 -0
- package/photon-ai/command-executor.d.ts.map +1 -0
- package/photon-ai/command-executor.js +26 -0
- package/photon-ai/command-executor.js.map +1 -0
- package/photon-ai/entity-resolver.d.ts +121 -0
- package/photon-ai/entity-resolver.d.ts.map +1 -0
- package/photon-ai/entity-resolver.js +393 -0
- package/photon-ai/entity-resolver.js.map +1 -0
- package/photon-ai/fuzzy-match.d.ts +12 -0
- package/photon-ai/fuzzy-match.d.ts.map +1 -0
- package/photon-ai/fuzzy-match.js +37 -0
- package/photon-ai/fuzzy-match.js.map +1 -0
- package/photon-ai/index.d.ts +15 -0
- package/photon-ai/index.d.ts.map +1 -0
- package/photon-ai/index.js +13 -0
- package/photon-ai/index.js.map +1 -0
- package/photon-ai/intent-parser.d.ts +20 -0
- package/photon-ai/intent-parser.d.ts.map +1 -0
- package/photon-ai/intent-parser.js +52 -0
- package/photon-ai/intent-parser.js.map +1 -0
- package/photon-ai/photon-ai-memory.d.ts +42 -0
- package/photon-ai/photon-ai-memory.d.ts.map +1 -0
- package/photon-ai/photon-ai-memory.js +86 -0
- package/photon-ai/photon-ai-memory.js.map +1 -0
- package/photon-ai/photon-ai-panel.d.ts +54 -0
- package/photon-ai/photon-ai-panel.d.ts.map +1 -0
- package/photon-ai/photon-ai-panel.js +191 -0
- package/photon-ai/photon-ai-panel.js.map +1 -0
- package/photon-ai/photon-ai-registry.d.ts +25 -0
- package/photon-ai/photon-ai-registry.d.ts.map +1 -0
- package/photon-ai/photon-ai-registry.js +41 -0
- package/photon-ai/photon-ai-registry.js.map +1 -0
- package/photon-ai/photon-ai-service.d.ts +71 -0
- package/photon-ai/photon-ai-service.d.ts.map +1 -0
- package/photon-ai/photon-ai-service.js +165 -0
- package/photon-ai/photon-ai-service.js.map +1 -0
- package/photon-ai/photon-ai.types.d.ts +100 -0
- package/photon-ai/photon-ai.types.d.ts.map +1 -0
- package/photon-ai/photon-ai.types.js +2 -0
- package/photon-ai/photon-ai.types.js.map +1 -0
- package/photon-ai/query-splitter.d.ts +22 -0
- package/photon-ai/query-splitter.d.ts.map +1 -0
- package/photon-ai/query-splitter.js +81 -0
- package/photon-ai/query-splitter.js.map +1 -0
- package/photon-ai/text-normalizer.d.ts +33 -0
- package/photon-ai/text-normalizer.d.ts.map +1 -0
- package/photon-ai/text-normalizer.js +132 -0
- package/photon-ai/text-normalizer.js.map +1 -0
- package/renderer/auto-scroller.d.ts +78 -0
- package/renderer/auto-scroller.d.ts.map +1 -0
- package/renderer/auto-scroller.js +141 -0
- package/renderer/auto-scroller.js.map +1 -0
- package/renderer/body-renderer.d.ts +191 -0
- package/renderer/body-renderer.d.ts.map +1 -0
- package/renderer/body-renderer.js +806 -0
- package/renderer/body-renderer.js.map +1 -0
- package/renderer/cell-renderer.d.ts +26 -0
- package/renderer/cell-renderer.d.ts.map +1 -0
- package/renderer/cell-renderer.js +201 -0
- package/renderer/cell-renderer.js.map +1 -0
- package/renderer/column-menu.d.ts +285 -0
- package/renderer/column-menu.d.ts.map +1 -0
- package/renderer/column-menu.js +873 -0
- package/renderer/column-menu.js.map +1 -0
- package/renderer/column-style-manager.d.ts +38 -0
- package/renderer/column-style-manager.d.ts.map +1 -0
- package/renderer/column-style-manager.js +110 -0
- package/renderer/column-style-manager.js.map +1 -0
- package/renderer/detail-row-renderer.d.ts +153 -0
- package/renderer/detail-row-renderer.d.ts.map +1 -0
- package/renderer/detail-row-renderer.js +388 -0
- package/renderer/detail-row-renderer.js.map +1 -0
- package/renderer/dom-utils.d.ts +22 -0
- package/renderer/dom-utils.d.ts.map +1 -0
- package/renderer/dom-utils.js +132 -0
- package/renderer/dom-utils.js.map +1 -0
- package/renderer/footer-renderer.d.ts +25 -0
- package/renderer/footer-renderer.d.ts.map +1 -0
- package/renderer/footer-renderer.js +168 -0
- package/renderer/footer-renderer.js.map +1 -0
- package/renderer/grid-renderer.d.ts +295 -0
- package/renderer/grid-renderer.d.ts.map +1 -0
- package/renderer/grid-renderer.js +1456 -0
- package/renderer/grid-renderer.js.map +1 -0
- package/renderer/group-context-menu.d.ts +79 -0
- package/renderer/group-context-menu.d.ts.map +1 -0
- package/renderer/group-context-menu.js +238 -0
- package/renderer/group-context-menu.js.map +1 -0
- package/renderer/group-drop-zone.d.ts +56 -0
- package/renderer/group-drop-zone.d.ts.map +1 -0
- package/renderer/group-drop-zone.js +376 -0
- package/renderer/group-drop-zone.js.map +1 -0
- package/renderer/header-renderer.d.ts +264 -0
- package/renderer/header-renderer.d.ts.map +1 -0
- package/renderer/header-renderer.js +1321 -0
- package/renderer/header-renderer.js.map +1 -0
- package/renderer/overlay-renderer.d.ts +16 -0
- package/renderer/overlay-renderer.d.ts.map +1 -0
- package/renderer/overlay-renderer.js +64 -0
- package/renderer/overlay-renderer.js.map +1 -0
- package/renderer/renderer-resolver.d.ts +18 -0
- package/renderer/renderer-resolver.d.ts.map +1 -0
- package/renderer/renderer-resolver.js +18 -0
- package/renderer/renderer-resolver.js.map +1 -0
- package/renderer/row-animator.d.ts +72 -0
- package/renderer/row-animator.d.ts.map +1 -0
- package/renderer/row-animator.js +175 -0
- package/renderer/row-animator.js.map +1 -0
- package/renderer/row-drag-renderer.d.ts +58 -0
- package/renderer/row-drag-renderer.d.ts.map +1 -0
- package/renderer/row-drag-renderer.js +395 -0
- package/renderer/row-drag-renderer.js.map +1 -0
- package/renderer/row-offset-search.d.ts +17 -0
- package/renderer/row-offset-search.d.ts.map +1 -0
- package/renderer/row-offset-search.js +31 -0
- package/renderer/row-offset-search.js.map +1 -0
- package/renderer/row-position-sheet.d.ts +11 -0
- package/renderer/row-position-sheet.d.ts.map +1 -0
- package/renderer/row-position-sheet.js +29 -0
- package/renderer/row-position-sheet.js.map +1 -0
- package/renderer/scroll-controller.d.ts +58 -0
- package/renderer/scroll-controller.d.ts.map +1 -0
- package/renderer/scroll-controller.js +200 -0
- package/renderer/scroll-controller.js.map +1 -0
- package/renderer/sticky-row-tracker.d.ts +40 -0
- package/renderer/sticky-row-tracker.d.ts.map +1 -0
- package/renderer/sticky-row-tracker.js +63 -0
- package/renderer/sticky-row-tracker.js.map +1 -0
- package/renderer/tooltip-renderer.d.ts +36 -0
- package/renderer/tooltip-renderer.d.ts.map +1 -0
- package/renderer/tooltip-renderer.js +133 -0
- package/renderer/tooltip-renderer.js.map +1 -0
- package/renderer/tree-cell-renderer.d.ts +37 -0
- package/renderer/tree-cell-renderer.d.ts.map +1 -0
- package/renderer/tree-cell-renderer.js +75 -0
- package/renderer/tree-cell-renderer.js.map +1 -0
- package/renderer/tree-sticky-row-tracker.d.ts +62 -0
- package/renderer/tree-sticky-row-tracker.d.ts.map +1 -0
- package/renderer/tree-sticky-row-tracker.js +120 -0
- package/renderer/tree-sticky-row-tracker.js.map +1 -0
- package/renderer/virtual-scroll-renderer.d.ts +37 -0
- package/renderer/virtual-scroll-renderer.d.ts.map +1 -0
- package/renderer/virtual-scroll-renderer.js +133 -0
- package/renderer/virtual-scroll-renderer.js.map +1 -0
- package/styles/base-styles.d.ts +3 -0
- package/styles/base-styles.d.ts.map +1 -0
- package/styles/base-styles.js +3045 -0
- package/styles/base-styles.js.map +1 -0
- package/styles/themes/theme-alpine.d.ts +2 -0
- package/styles/themes/theme-alpine.d.ts.map +1 -0
- package/styles/themes/theme-alpine.js +120 -0
- package/styles/themes/theme-alpine.js.map +1 -0
- package/styles/themes/theme-balham.d.ts +2 -0
- package/styles/themes/theme-balham.d.ts.map +1 -0
- package/styles/themes/theme-balham.js +120 -0
- package/styles/themes/theme-balham.js.map +1 -0
- package/styles/themes/theme-dark.d.ts +2 -0
- package/styles/themes/theme-dark.d.ts.map +1 -0
- package/styles/themes/theme-dark.js +216 -0
- package/styles/themes/theme-dark.js.map +1 -0
- package/styles/themes/theme-material.d.ts +2 -0
- package/styles/themes/theme-material.d.ts.map +1 -0
- package/styles/themes/theme-material.js +134 -0
- package/styles/themes/theme-material.js.map +1 -0
- package/styles/themes/theme-quartz.d.ts +2 -0
- package/styles/themes/theme-quartz.d.ts.map +1 -0
- package/styles/themes/theme-quartz.js +120 -0
- package/styles/themes/theme-quartz.js.map +1 -0
- package/theme/css-var-injector.d.ts +10 -0
- package/theme/css-var-injector.d.ts.map +1 -0
- package/theme/css-var-injector.js +63 -0
- package/theme/css-var-injector.js.map +1 -0
- package/theme/theme-manager.d.ts +20 -0
- package/theme/theme-manager.d.ts.map +1 -0
- package/theme/theme-manager.js +79 -0
- package/theme/theme-manager.js.map +1 -0
- package/theme/themes/dark-theme.d.ts +3 -0
- package/theme/themes/dark-theme.d.ts.map +1 -0
- package/theme/themes/dark-theme.js +149 -0
- package/theme/themes/dark-theme.js.map +1 -0
- package/theme/themes/light-theme.d.ts +3 -0
- package/theme/themes/light-theme.d.ts.map +1 -0
- package/theme/themes/light-theme.js +149 -0
- package/theme/themes/light-theme.js.map +1 -0
- package/types/column.types.d.ts +195 -0
- package/types/column.types.d.ts.map +1 -0
- package/types/column.types.js +2 -0
- package/types/column.types.js.map +1 -0
- package/types/event.types.d.ts +213 -0
- package/types/event.types.d.ts.map +1 -0
- package/types/event.types.js +67 -0
- package/types/event.types.js.map +1 -0
- package/types/filter.types.d.ts +42 -0
- package/types/filter.types.d.ts.map +1 -0
- package/types/filter.types.js +2 -0
- package/types/filter.types.js.map +1 -0
- package/types/grid.types.d.ts +214 -0
- package/types/grid.types.d.ts.map +1 -0
- package/types/grid.types.js +2 -0
- package/types/grid.types.js.map +1 -0
- package/types/master-detail.types.d.ts +112 -0
- package/types/master-detail.types.d.ts.map +1 -0
- package/types/master-detail.types.js +2 -0
- package/types/master-detail.types.js.map +1 -0
- package/types/photon-ai.types.d.ts +19 -0
- package/types/photon-ai.types.d.ts.map +1 -0
- package/types/photon-ai.types.js +2 -0
- package/types/photon-ai.types.js.map +1 -0
- package/types/renderer.types.d.ts +156 -0
- package/types/renderer.types.d.ts.map +1 -0
- package/types/renderer.types.js +19 -0
- package/types/renderer.types.js.map +1 -0
- package/types/row.types.d.ts +127 -0
- package/types/row.types.d.ts.map +1 -0
- package/types/row.types.js +9 -0
- package/types/row.types.js.map +1 -0
- package/types/theme.types.d.ts +159 -0
- package/types/theme.types.d.ts.map +1 -0
- package/types/theme.types.js +2 -0
- package/types/theme.types.js.map +1 -0
- package/types/tree-data.types.d.ts +94 -0
- package/types/tree-data.types.d.ts.map +1 -0
- package/types/tree-data.types.js +2 -0
- package/types/tree-data.types.js.map +1 -0
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
import { GridEventType } from '../types/event.types';
|
|
2
|
+
import { CellRenderer } from './cell-renderer';
|
|
3
|
+
import { formatValue } from '../engines/editing/value-parser';
|
|
4
|
+
import { createDiv, toggleClass } from './dom-utils';
|
|
5
|
+
import { resolveColumnRenderer } from './renderer-resolver';
|
|
6
|
+
import { applyTreeToggle, syncTreeToggle } from './tree-cell-renderer';
|
|
7
|
+
/**
|
|
8
|
+
* Sentinel `ColumnDef` emitted with `CELL_CLICKED` for the auto-group label cell.
|
|
9
|
+
* Editing is unconditionally blocked for group rows in `startCellEdit`, so this
|
|
10
|
+
* colDef's `editable: false` is a secondary safety net.
|
|
11
|
+
*/
|
|
12
|
+
const GROUP_LABEL_COL_DEF = {
|
|
13
|
+
colId: '__group__',
|
|
14
|
+
field: '__group__',
|
|
15
|
+
header: 'Group',
|
|
16
|
+
type: 'string',
|
|
17
|
+
editable: false,
|
|
18
|
+
};
|
|
19
|
+
export class BodyRenderer {
|
|
20
|
+
constructor(store, eventBus, iconRenderer, rowSelectionEngine) {
|
|
21
|
+
this.store = store;
|
|
22
|
+
this.eventBus = eventBus;
|
|
23
|
+
this.iconRenderer = iconRenderer;
|
|
24
|
+
this.rowSelectionEngine = rowSelectionEngine;
|
|
25
|
+
this.cellRenderer = new CellRenderer();
|
|
26
|
+
this.renderedRowMap = new Map();
|
|
27
|
+
this.leftContent = null;
|
|
28
|
+
this.centerContent = null;
|
|
29
|
+
this.rightContent = null;
|
|
30
|
+
// Track last rendered center col range to detect changes
|
|
31
|
+
this.lastCenterStart = -1;
|
|
32
|
+
this.lastCenterEnd = -1;
|
|
33
|
+
// Sticky-row overlay containers (Master/Detail) — siblings of the
|
|
34
|
+
// `*Content` panels above, outside the scroll transform. `null` unless
|
|
35
|
+
// `masterDetail.enabled`.
|
|
36
|
+
this.leftSticky = null;
|
|
37
|
+
this.centerSticky = null;
|
|
38
|
+
this.rightSticky = null;
|
|
39
|
+
/** `nodeId`s of the rows currently parked in the sticky containers — a single Master/Detail master row, or a stack of Tree Data ancestor rows. */
|
|
40
|
+
this.stuckNodeIds = new Set();
|
|
41
|
+
}
|
|
42
|
+
setPanels(leftContent, centerContent, rightContent) {
|
|
43
|
+
this.leftContent = leftContent;
|
|
44
|
+
this.centerContent = centerContent;
|
|
45
|
+
this.rightContent = rightContent;
|
|
46
|
+
// Delegated hover sync: works even after center panels are rebuilt on col range change.
|
|
47
|
+
// mouseover/mouseout bubble; we track nodeId to avoid spurious remove when moving between children.
|
|
48
|
+
const panels = [leftContent, centerContent, rightContent].filter((p) => p !== null);
|
|
49
|
+
const getNodeId = (el) => el instanceof HTMLElement ? el.closest('[data-node-id]')?.getAttribute('data-node-id') ?? null : null;
|
|
50
|
+
for (const panel of panels) {
|
|
51
|
+
panel.addEventListener('mouseover', (e) => {
|
|
52
|
+
const nodeId = getNodeId(e.target);
|
|
53
|
+
if (!nodeId)
|
|
54
|
+
return;
|
|
55
|
+
for (const p of panels) {
|
|
56
|
+
p.querySelectorAll(`[data-node-id="${nodeId}"]`).forEach((r) => r.classList.add('pg-row--hover'));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
panel.addEventListener('mouseout', (e) => {
|
|
60
|
+
const nodeId = getNodeId(e.target);
|
|
61
|
+
if (!nodeId || nodeId === getNodeId(e.relatedTarget))
|
|
62
|
+
return;
|
|
63
|
+
for (const p of panels) {
|
|
64
|
+
p.querySelectorAll(`[data-node-id="${nodeId}"]`).forEach((r) => r.classList.remove('pg-row--hover'));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Wires the per-panel sticky-row overlay containers. Called once from `GridRenderer` when `masterDetail.enabled`. */
|
|
70
|
+
setStickyContainers(left, center, right) {
|
|
71
|
+
this.leftSticky = left;
|
|
72
|
+
this.centerSticky = center;
|
|
73
|
+
this.rightSticky = right;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Parks each entry's row in the sticky overlay (pinned at the panel's own
|
|
77
|
+
* top, ignoring the scroll transform, stacked in array order) — releasing
|
|
78
|
+
* whatever was previously stuck but isn't in `entries` back into normal
|
|
79
|
+
* scrolled flow. A single entry reproduces the old Master/Detail behavior;
|
|
80
|
+
* multiple entries stack Tree Data's ancestor-row chain, each at its own
|
|
81
|
+
* `top` (see `TreeStickyRowTracker`).
|
|
82
|
+
*
|
|
83
|
+
* Moves the *actual* cached DOM nodes (not clones) so every existing
|
|
84
|
+
* listener, selection class, and edit-in-progress state carries over
|
|
85
|
+
* untouched — this only ever runs on already-rendered rows.
|
|
86
|
+
*/
|
|
87
|
+
setStickyRows(entries) {
|
|
88
|
+
const newIds = new Set(entries.map((e) => e.nodeId));
|
|
89
|
+
for (const nodeId of this.stuckNodeIds) {
|
|
90
|
+
if (newIds.has(nodeId))
|
|
91
|
+
continue;
|
|
92
|
+
const prev = this.renderedRowMap.get(nodeId);
|
|
93
|
+
if (prev) {
|
|
94
|
+
if (prev.left) {
|
|
95
|
+
prev.left.style.top = '';
|
|
96
|
+
prev.left.style.zIndex = '';
|
|
97
|
+
this.leftContent?.appendChild(prev.left);
|
|
98
|
+
}
|
|
99
|
+
if (prev.center) {
|
|
100
|
+
prev.center.style.top = '';
|
|
101
|
+
prev.center.style.zIndex = '';
|
|
102
|
+
this.centerContent?.appendChild(prev.center);
|
|
103
|
+
}
|
|
104
|
+
if (prev.right) {
|
|
105
|
+
prev.right.style.top = '';
|
|
106
|
+
prev.right.style.zIndex = '';
|
|
107
|
+
this.rightContent?.appendChild(prev.right);
|
|
108
|
+
}
|
|
109
|
+
for (const el of [prev.left, prev.center, prev.right])
|
|
110
|
+
el?.classList.remove('pg-row--sticky');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
this.stuckNodeIds = newIds;
|
|
114
|
+
// Appended in order so the sticky containers' DOM order matches the
|
|
115
|
+
// visual stack (shallowest ancestor first, at the top) — plus an
|
|
116
|
+
// explicit `z-index`, shallowest highest, so stacking order is correct
|
|
117
|
+
// by rule rather than by incidental DOM order: without it, a deeper
|
|
118
|
+
// level whose push-off briefly overshoots into a shallower ancestor's
|
|
119
|
+
// slot (a real risk with `stackedTop` compounding per level) would paint
|
|
120
|
+
// over it instead of staying tucked behind, since later-appended
|
|
121
|
+
// elements win ties on `z-index: auto` by default.
|
|
122
|
+
const topLevel = entries.length;
|
|
123
|
+
entries.forEach(({ nodeId, top }, i) => {
|
|
124
|
+
const next = this.renderedRowMap.get(nodeId);
|
|
125
|
+
if (!next)
|
|
126
|
+
return;
|
|
127
|
+
const zIndex = String(topLevel - i);
|
|
128
|
+
// Inline `top` beats the RowPositionSheet stylesheet rule for this
|
|
129
|
+
// same nodeId without fighting CSS specificity — reverted above by
|
|
130
|
+
// clearing the inline style, which lets the stylesheet rule apply again.
|
|
131
|
+
if (next.left && this.leftSticky) {
|
|
132
|
+
next.left.style.top = `${top}px`;
|
|
133
|
+
next.left.style.zIndex = zIndex;
|
|
134
|
+
this.leftSticky.appendChild(next.left);
|
|
135
|
+
}
|
|
136
|
+
if (next.center && this.centerSticky) {
|
|
137
|
+
next.center.style.top = `${top}px`;
|
|
138
|
+
next.center.style.zIndex = zIndex;
|
|
139
|
+
this.centerSticky.appendChild(next.center);
|
|
140
|
+
}
|
|
141
|
+
if (next.right && this.rightSticky) {
|
|
142
|
+
next.right.style.top = `${top}px`;
|
|
143
|
+
next.right.style.zIndex = zIndex;
|
|
144
|
+
this.rightSticky.appendChild(next.right);
|
|
145
|
+
}
|
|
146
|
+
for (const el of [next.left, next.center, next.right])
|
|
147
|
+
el?.classList.add('pg-row--sticky');
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
renderRows(rows, leftCols, centerCols, // visible slice only
|
|
151
|
+
rightCols, options = {}) {
|
|
152
|
+
const cStart = options.centerColStart ?? 0;
|
|
153
|
+
const cEnd = cStart + centerCols.length;
|
|
154
|
+
// When the visible center col range changes, invalidate all center panels
|
|
155
|
+
if (cStart !== this.lastCenterStart || cEnd !== this.lastCenterEnd) {
|
|
156
|
+
this.lastCenterStart = cStart;
|
|
157
|
+
this.lastCenterEnd = cEnd;
|
|
158
|
+
if (this.centerContent)
|
|
159
|
+
this.centerContent.innerHTML = '';
|
|
160
|
+
for (const ps of this.renderedRowMap.values()) {
|
|
161
|
+
ps.center = null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const newIds = new Set(rows.map((r) => r.nodeId));
|
|
165
|
+
// Remove rows no longer visible
|
|
166
|
+
for (const [nodeId, ps] of this.renderedRowMap) {
|
|
167
|
+
if (!newIds.has(nodeId)) {
|
|
168
|
+
ps.left?.remove();
|
|
169
|
+
ps.center?.remove();
|
|
170
|
+
ps.right?.remove();
|
|
171
|
+
this.renderedRowMap.delete(nodeId);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const leftFrag = document.createDocumentFragment();
|
|
175
|
+
const centerFrag = document.createDocumentFragment();
|
|
176
|
+
const rightFrag = document.createDocumentFragment();
|
|
177
|
+
const totalCenterCols = options.totalCenterCols ?? centerCols.length;
|
|
178
|
+
const centerOffset = leftCols.length + cStart;
|
|
179
|
+
const rightOffset = leftCols.length + totalCenterCols;
|
|
180
|
+
for (let i = 0; i < rows.length; i++) {
|
|
181
|
+
const row = rows[i];
|
|
182
|
+
let existing = this.renderedRowMap.get(row.nodeId);
|
|
183
|
+
// Group header and footer rows carrying aggregated values must be fully
|
|
184
|
+
// rebuilt on every pipeline run so that updated aggregations (e.g. after
|
|
185
|
+
// filtering) are reflected in the DOM rather than served from the stale cache.
|
|
186
|
+
if (existing && (row.type === 'group' || row.type === 'group-footer') && row.aggregatedValues) {
|
|
187
|
+
existing.left?.remove();
|
|
188
|
+
existing.center?.remove();
|
|
189
|
+
existing.right?.remove();
|
|
190
|
+
this.renderedRowMap.delete(row.nodeId);
|
|
191
|
+
existing = undefined;
|
|
192
|
+
}
|
|
193
|
+
if (existing && row.type === 'detail') {
|
|
194
|
+
// Detail rows never have panel DOM (see buildPanelRow) — their
|
|
195
|
+
// `center` is permanently null by design, not because a column-range
|
|
196
|
+
// change invalidated it. Without this check the branch below would
|
|
197
|
+
// mistake that for "needs rebuilding" on every single render pass
|
|
198
|
+
// and spuriously build real cell content for a row type that must
|
|
199
|
+
// never appear in these panels at all.
|
|
200
|
+
}
|
|
201
|
+
else if (existing && existing.center !== null) {
|
|
202
|
+
// Normal update — row and center already in DOM
|
|
203
|
+
this.updatePanelRow(existing, row, i, options);
|
|
204
|
+
}
|
|
205
|
+
else if (existing) {
|
|
206
|
+
// Center was invalidated (col range changed) — rebuild center only
|
|
207
|
+
this.updatePanelRow(existing, row, i, options);
|
|
208
|
+
const newCenter = this.buildSingleRow(row, i, 'center', centerCols, centerOffset, options);
|
|
209
|
+
existing.center = newCenter;
|
|
210
|
+
centerFrag.appendChild(newCenter);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// Entirely new row
|
|
214
|
+
const ps = this.buildPanelRow(row, i, leftCols, centerCols, rightCols, centerOffset, rightOffset, options);
|
|
215
|
+
this.renderedRowMap.set(row.nodeId, ps);
|
|
216
|
+
if (ps.left)
|
|
217
|
+
leftFrag.appendChild(ps.left);
|
|
218
|
+
if (ps.center)
|
|
219
|
+
centerFrag.appendChild(ps.center);
|
|
220
|
+
if (ps.right)
|
|
221
|
+
rightFrag.appendChild(ps.right);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (this.leftContent)
|
|
225
|
+
this.leftContent.appendChild(leftFrag);
|
|
226
|
+
this.centerContent?.appendChild(centerFrag);
|
|
227
|
+
if (this.rightContent)
|
|
228
|
+
this.rightContent.appendChild(rightFrag);
|
|
229
|
+
}
|
|
230
|
+
updateRowSelection(nodeId, selected) {
|
|
231
|
+
const ps = this.renderedRowMap.get(nodeId);
|
|
232
|
+
if (!ps)
|
|
233
|
+
return;
|
|
234
|
+
const els = [ps.left, ps.center, ps.right].filter((e) => e !== null);
|
|
235
|
+
for (const el of els) {
|
|
236
|
+
toggleClass(el, 'pg-row--selected', selected);
|
|
237
|
+
const cb = el.querySelector('.pg-checkbox');
|
|
238
|
+
if (cb)
|
|
239
|
+
cb.checked = selected;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Advances the tracked virtual-column range without touching any DOM.
|
|
244
|
+
*
|
|
245
|
+
* Call this when the column range has logically changed but the body rows must
|
|
246
|
+
* NOT be rebuilt — specifically during an active column resize where CSS rules
|
|
247
|
+
* already handle width changes via `ColumnStyleManager`. Keeping the tracked
|
|
248
|
+
* range current prevents the next normal `renderRows` call (on `mouseup`) from
|
|
249
|
+
* seeing a false "range changed" signal and wiping all center panels.
|
|
250
|
+
*
|
|
251
|
+
* @param cStart - New first visible center-column index.
|
|
252
|
+
* @param cEnd - New last visible center-column index (exclusive).
|
|
253
|
+
*/
|
|
254
|
+
syncCenterRange(cStart, cEnd) {
|
|
255
|
+
this.lastCenterStart = cStart;
|
|
256
|
+
this.lastCenterEnd = cEnd;
|
|
257
|
+
}
|
|
258
|
+
clear() {
|
|
259
|
+
for (const ps of this.renderedRowMap.values()) {
|
|
260
|
+
ps.left?.remove();
|
|
261
|
+
ps.center?.remove();
|
|
262
|
+
ps.right?.remove();
|
|
263
|
+
}
|
|
264
|
+
this.renderedRowMap.clear();
|
|
265
|
+
this.lastCenterStart = -1;
|
|
266
|
+
this.lastCenterEnd = -1;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Evicts only the specified rows from the render cache so they are fully
|
|
270
|
+
* rebuilt on the next paint cycle. Rows whose `nodeId` is not in the set
|
|
271
|
+
* are untouched — their DOM is reused as-is, so custom cell renderers
|
|
272
|
+
* (images, flags, progress bars, etc.) are NOT re-executed for them.
|
|
273
|
+
*
|
|
274
|
+
* Use this instead of `clear()` after in-place data mutations (fill, cut,
|
|
275
|
+
* paste, undo/redo) where only a known subset of rows changed.
|
|
276
|
+
*
|
|
277
|
+
* @param nodeIds - Set of row node IDs whose cache entries should be evicted.
|
|
278
|
+
*/
|
|
279
|
+
invalidateRowsByNodeId(nodeIds) {
|
|
280
|
+
for (const nodeId of nodeIds) {
|
|
281
|
+
const ps = this.renderedRowMap.get(nodeId);
|
|
282
|
+
if (ps) {
|
|
283
|
+
ps.left?.remove();
|
|
284
|
+
ps.center?.remove();
|
|
285
|
+
ps.right?.remove();
|
|
286
|
+
this.renderedRowMap.delete(nodeId);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
destroy() {
|
|
291
|
+
this.clear();
|
|
292
|
+
}
|
|
293
|
+
// ─── Private ─────────────────────────────────────────────────────────────
|
|
294
|
+
buildPanelRow(row, displayIndex, leftCols, centerCols, rightCols, centerOffset, rightOffset, options) {
|
|
295
|
+
// Detail rows render exclusively in `DetailRowRenderer`'s full-width overlay
|
|
296
|
+
// layer — they occupy a slot in `visibleRows` (for height/virtualization
|
|
297
|
+
// bookkeeping) but must not produce any left/center/right panel DOM.
|
|
298
|
+
if (row.type === 'detail')
|
|
299
|
+
return { left: null, center: null, right: null };
|
|
300
|
+
const hasLeft = !!(this.leftContent && (options.showCheckboxes || options.showSerialNumber || leftCols.length > 0));
|
|
301
|
+
const hasRight = !!(this.rightContent && rightCols.length > 0);
|
|
302
|
+
const left = hasLeft ? this.buildSingleRow(row, displayIndex, 'left', leftCols, 0, options) : null;
|
|
303
|
+
const center = this.buildSingleRow(row, displayIndex, 'center', centerCols, centerOffset, options);
|
|
304
|
+
const right = hasRight ? this.buildSingleRow(row, displayIndex, 'right', rightCols, rightOffset, options) : null;
|
|
305
|
+
return { left, center, right };
|
|
306
|
+
}
|
|
307
|
+
buildSingleRow(row, displayIndex, panel, cols, colOffset, options) {
|
|
308
|
+
const el = createDiv(this.getRowClass(row, displayIndex, options));
|
|
309
|
+
el.setAttribute('role', 'row');
|
|
310
|
+
el.setAttribute('data-node-id', row.nodeId);
|
|
311
|
+
el.setAttribute('data-row-index', String(row.rowIndex));
|
|
312
|
+
el.setAttribute('data-panel', panel);
|
|
313
|
+
if (row.type === 'group' || row.type === 'group-footer') {
|
|
314
|
+
el.setAttribute('data-level', String(row.level));
|
|
315
|
+
if (panel === 'center') {
|
|
316
|
+
// Left virtual spacer (mirrors the data-row spacer for correct scroll alignment)
|
|
317
|
+
const leftSpacerW = options.centerLeftSpacerW ?? 0;
|
|
318
|
+
if (leftSpacerW > 0) {
|
|
319
|
+
const sp = createDiv('pg-cell--h-spacer');
|
|
320
|
+
sp.style.cssText = `width:${leftSpacerW}px;min-width:${leftSpacerW}px;flex-shrink:0;`;
|
|
321
|
+
el.appendChild(sp);
|
|
322
|
+
}
|
|
323
|
+
if (row.type === 'group') {
|
|
324
|
+
this.buildGroupRowContent(el, row, options);
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
this.buildGroupFooterContent(el, row, options);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// Render one cell per column — shows the aggregated value for agg-eligible
|
|
331
|
+
// columns, empty for all others (maintains column alignment with data rows).
|
|
332
|
+
this.buildGroupAggregateCells(el, row, cols, colOffset, options);
|
|
333
|
+
if (panel === 'center') {
|
|
334
|
+
// Right virtual spacer
|
|
335
|
+
const rightSpacerW = options.centerRightSpacerW ?? 0;
|
|
336
|
+
if (rightSpacerW > 0) {
|
|
337
|
+
const sp = createDiv('pg-cell--h-spacer');
|
|
338
|
+
sp.style.cssText = `width:${rightSpacerW}px;min-width:${rightSpacerW}px;flex-shrink:0;`;
|
|
339
|
+
el.appendChild(sp);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
this.attachRowListeners(el, row, cols, colOffset, options);
|
|
343
|
+
return el;
|
|
344
|
+
}
|
|
345
|
+
if (options.treeData && row.type === 'data') {
|
|
346
|
+
el.setAttribute('data-level', String(row.level));
|
|
347
|
+
}
|
|
348
|
+
if (panel === 'left') {
|
|
349
|
+
if (options.showCheckboxes) {
|
|
350
|
+
el.appendChild(this.cellRenderer.renderCheckboxCell(row, row.rowIndex));
|
|
351
|
+
}
|
|
352
|
+
if (options.showSerialNumber) {
|
|
353
|
+
el.appendChild(this.cellRenderer.renderSerialNumberCell(row.rowIndex, displayIndex + 1));
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (panel === 'center') {
|
|
357
|
+
// Left virtual spacer (columns scrolled off to the left)
|
|
358
|
+
const leftSpacerW = options.centerLeftSpacerW ?? 0;
|
|
359
|
+
if (leftSpacerW > 0) {
|
|
360
|
+
const sp = createDiv('pg-cell--h-spacer');
|
|
361
|
+
sp.style.cssText = `width:${leftSpacerW}px;min-width:${leftSpacerW}px;flex-shrink:0;`;
|
|
362
|
+
el.appendChild(sp);
|
|
363
|
+
}
|
|
364
|
+
if (options.showGroupsColumn) {
|
|
365
|
+
this.buildLeafGroupCell(el, row, options);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
for (let i = 0; i < cols.length; i++) {
|
|
369
|
+
const cellEl = this.cellRenderer.renderCell({
|
|
370
|
+
row,
|
|
371
|
+
colDef: cols[i],
|
|
372
|
+
rowIndex: row.rowIndex,
|
|
373
|
+
colIndex: colOffset + i, // global index across all panels
|
|
374
|
+
iconRenderer: this.iconRenderer,
|
|
375
|
+
dateFormat: options.dateFormat,
|
|
376
|
+
timeZone: options.timeZone,
|
|
377
|
+
currencySymbol: options.currencySymbol,
|
|
378
|
+
locale: options.locale,
|
|
379
|
+
api: options.api ?? null,
|
|
380
|
+
});
|
|
381
|
+
if (options.showVerticalBorders)
|
|
382
|
+
cellEl.classList.add('pg-cell--v-border');
|
|
383
|
+
if (cols[i].rowDrag && row.type !== 'summary') {
|
|
384
|
+
const handle = createDiv('pg-row-drag-handle');
|
|
385
|
+
handle.setAttribute('data-row-drag', '');
|
|
386
|
+
handle.setAttribute('data-drag-label', String(row.data[cols[i].field] ?? ''));
|
|
387
|
+
handle.innerHTML = this.iconRenderer.renderToString('drag', 14);
|
|
388
|
+
const inner = cellEl.querySelector('.pg-cell__inner');
|
|
389
|
+
if (inner) {
|
|
390
|
+
inner.insertBefore(handle, inner.firstChild);
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
cellEl.insertBefore(handle, cellEl.firstChild);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
this.applyMasterDetailToggle(cellEl, row, cols[i], options);
|
|
397
|
+
applyTreeToggle(cellEl, row, cols[i], options.treeData, this.iconRenderer, this.eventBus);
|
|
398
|
+
el.appendChild(cellEl);
|
|
399
|
+
}
|
|
400
|
+
if (panel === 'center') {
|
|
401
|
+
// Right virtual spacer (columns scrolled off to the right)
|
|
402
|
+
const rightSpacerW = options.centerRightSpacerW ?? 0;
|
|
403
|
+
if (rightSpacerW > 0) {
|
|
404
|
+
const sp = createDiv('pg-cell--h-spacer');
|
|
405
|
+
sp.style.cssText = `width:${rightSpacerW}px;min-width:${rightSpacerW}px;flex-shrink:0;`;
|
|
406
|
+
el.appendChild(sp);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
this.attachRowListeners(el, row, cols, colOffset, options);
|
|
410
|
+
return el;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Renders the auto-group column cell for a **leaf data row**.
|
|
414
|
+
*
|
|
415
|
+
* When `options.leafGroupColDef` is set (i.e. grouping is active), this cell
|
|
416
|
+
* shows the row's actual value for the deepest grouping field and participates
|
|
417
|
+
* fully in cell selection (colIndex −1), keyboard navigation, editing, and
|
|
418
|
+
* copy/cut/paste — behaving exactly like any normal data cell.
|
|
419
|
+
*
|
|
420
|
+
* When `leafGroupColDef` is absent (no grouping active) a non-interactive
|
|
421
|
+
* spacer cell is rendered to maintain column alignment with group header rows.
|
|
422
|
+
*
|
|
423
|
+
* @param el - Row container element to append the cell into.
|
|
424
|
+
* @param row - Leaf data `RowNode` being rendered.
|
|
425
|
+
* @param options - Renderer options; `autoGroupColWidth` controls cell width.
|
|
426
|
+
*/
|
|
427
|
+
buildLeafGroupCell(el, row, options) {
|
|
428
|
+
const w = options.autoGroupColWidth ?? 200;
|
|
429
|
+
const colDef = options.leafGroupColDef;
|
|
430
|
+
if (!colDef) {
|
|
431
|
+
// Grouping inactive — plain spacer keeps the layout aligned.
|
|
432
|
+
const spacer = createDiv('pg-cell pg-cell--auto-group-spacer');
|
|
433
|
+
spacer.style.width = `${w}px`;
|
|
434
|
+
spacer.style.minWidth = `${w}px`;
|
|
435
|
+
el.appendChild(spacer);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
// Full interactive cell: rendered through CellRenderer so it inherits all
|
|
439
|
+
// type-aware formatting, selection borders, editor wiring, etc.
|
|
440
|
+
const cellEl = this.cellRenderer.renderCell({
|
|
441
|
+
row,
|
|
442
|
+
colDef,
|
|
443
|
+
rowIndex: row.rowIndex,
|
|
444
|
+
colIndex: -1, // virtual auto-group column index
|
|
445
|
+
iconRenderer: this.iconRenderer,
|
|
446
|
+
dateFormat: options.dateFormat,
|
|
447
|
+
timeZone: options.timeZone,
|
|
448
|
+
currencySymbol: options.currencySymbol,
|
|
449
|
+
locale: options.locale,
|
|
450
|
+
api: options.api ?? null,
|
|
451
|
+
});
|
|
452
|
+
// Override to virtual group column identity so selection/keyboard navigation
|
|
453
|
+
// and clipboard logic treat this cell as colIndex −1 uniformly across all row
|
|
454
|
+
// types (group header, group footer, leaf data).
|
|
455
|
+
cellEl.setAttribute('data-col-index', '-1');
|
|
456
|
+
cellEl.setAttribute('data-col-id', '__group__');
|
|
457
|
+
cellEl.style.width = `${w}px`;
|
|
458
|
+
cellEl.style.minWidth = `${w}px`;
|
|
459
|
+
cellEl.style.flex = 'none';
|
|
460
|
+
el.appendChild(cellEl);
|
|
461
|
+
}
|
|
462
|
+
buildGroupRowContent(el, row, options) {
|
|
463
|
+
// pg-cell is added so applySelectionClasses can highlight this cell and
|
|
464
|
+
// keyboard navigation / Ctrl+C works on it (colIndex −1 = auto-group column).
|
|
465
|
+
const cell = createDiv('pg-cell pg-row-group__cell');
|
|
466
|
+
cell.setAttribute('data-row-index', String(row.rowIndex));
|
|
467
|
+
cell.setAttribute('data-col-index', '-1');
|
|
468
|
+
cell.setAttribute('data-col-id', '__group__');
|
|
469
|
+
cell.setAttribute('role', 'gridcell');
|
|
470
|
+
// Fix the label cell to the auto-group column width so that the aggregate
|
|
471
|
+
// value cells that follow it sit exactly under their column headers.
|
|
472
|
+
// This mirrors the pg-cell--auto-group-spacer used in data rows.
|
|
473
|
+
const groupColW = options.autoGroupColWidth ?? 200;
|
|
474
|
+
cell.style.width = `${groupColW}px`;
|
|
475
|
+
cell.style.minWidth = `${groupColW}px`;
|
|
476
|
+
cell.style.flex = 'none';
|
|
477
|
+
// Toggle button is a themed wrapper div; the icon lives inside it.
|
|
478
|
+
// This keeps the button's CSS sizing free from the icon renderer's inline style.
|
|
479
|
+
const toggleBtn = createDiv('pg-row-group__toggle');
|
|
480
|
+
toggleBtn.setAttribute('role', 'button');
|
|
481
|
+
toggleBtn.setAttribute('aria-label', row.expanded ? 'Collapse group' : 'Expand group');
|
|
482
|
+
const toggleIcon = this.iconRenderer.render(row.expanded ? 'chevronDown' : 'chevronRight', { size: 16 });
|
|
483
|
+
toggleBtn.appendChild(toggleIcon);
|
|
484
|
+
const label = createDiv('pg-row-group__label');
|
|
485
|
+
const groupColDef = options.allLeafColumns?.find((c) => c.field === row.groupField);
|
|
486
|
+
const groupFn = groupColDef ? resolveColumnRenderer(groupColDef, 'group') : undefined;
|
|
487
|
+
if (groupColDef && groupFn) {
|
|
488
|
+
const rendered = groupFn({
|
|
489
|
+
row,
|
|
490
|
+
colDef: groupColDef,
|
|
491
|
+
groupValue: row.groupValue,
|
|
492
|
+
childCount: row.childCount ?? 0,
|
|
493
|
+
collapsed: !row.expanded,
|
|
494
|
+
api: null,
|
|
495
|
+
});
|
|
496
|
+
if (typeof rendered === 'string')
|
|
497
|
+
label.innerHTML = rendered;
|
|
498
|
+
else
|
|
499
|
+
label.appendChild(rendered);
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
label.textContent = String(row.groupValue + ' (' + row.childCount + ')');
|
|
503
|
+
}
|
|
504
|
+
// const countBadge = createDiv('pg-row-group__count');
|
|
505
|
+
// countBadge.textContent = String(row.childCount ?? 0);
|
|
506
|
+
cell.appendChild(toggleBtn);
|
|
507
|
+
cell.appendChild(label);
|
|
508
|
+
// cell.appendChild(countBadge);
|
|
509
|
+
el.appendChild(cell);
|
|
510
|
+
toggleBtn.addEventListener('click', (e) => {
|
|
511
|
+
e.stopPropagation();
|
|
512
|
+
this.eventBus.emit(GridEventType.ROW_GROUP_OPENED, { groupKey: row.groupKey });
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Builds the label cell for a group **footer** row.
|
|
517
|
+
*
|
|
518
|
+
* Unlike the header, there is no expand/collapse toggle — the cell shows
|
|
519
|
+
* a Σ-prefixed group value to signal "total for this group".
|
|
520
|
+
* The cell participates in cell selection (colIndex −1) identically to the
|
|
521
|
+
* group header's label cell.
|
|
522
|
+
*/
|
|
523
|
+
buildGroupFooterContent(el, row, options) {
|
|
524
|
+
const cell = createDiv('pg-cell pg-row-group__cell');
|
|
525
|
+
cell.setAttribute('data-row-index', String(row.rowIndex));
|
|
526
|
+
cell.setAttribute('data-col-index', '-1');
|
|
527
|
+
cell.setAttribute('data-col-id', '__group__');
|
|
528
|
+
cell.setAttribute('role', 'gridcell');
|
|
529
|
+
const groupColW = options.autoGroupColWidth ?? 200;
|
|
530
|
+
cell.style.width = `${groupColW}px`;
|
|
531
|
+
cell.style.minWidth = `${groupColW}px`;
|
|
532
|
+
cell.style.flex = 'none';
|
|
533
|
+
const label = createDiv('pg-row-group__label');
|
|
534
|
+
label.textContent = `Σ ${String(row.groupValue ?? '')}`;
|
|
535
|
+
cell.appendChild(label);
|
|
536
|
+
el.appendChild(cell);
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Append one `pg-cell` per column to `el` for a group row.
|
|
540
|
+
*
|
|
541
|
+
* - Columns with `type === 'currency'` **and** `aggFunc` set receive a
|
|
542
|
+
* `pg-cell--agg` cell showing the formatted aggregate value.
|
|
543
|
+
* - All other columns receive an empty `pg-cell` to maintain column
|
|
544
|
+
* alignment with data rows.
|
|
545
|
+
*
|
|
546
|
+
* Column widths are automatically applied by the {@link ColumnStyleManager}
|
|
547
|
+
* via the `[data-col-id]` CSS rules — no inline width needed here.
|
|
548
|
+
*/
|
|
549
|
+
buildGroupAggregateCells(el, row, cols, colOffset, options) {
|
|
550
|
+
const aggValues = row.aggregatedValues;
|
|
551
|
+
for (let i = 0; i < cols.length; i++) {
|
|
552
|
+
const col = cols[i];
|
|
553
|
+
const isAggCol = (col.type === 'currency' || col.type === 'number') && col.aggFunc != null;
|
|
554
|
+
const aggVal = isAggCol && aggValues ? aggValues[col.field] : undefined;
|
|
555
|
+
const hasValue = aggVal != null;
|
|
556
|
+
const cell = createDiv(hasValue ? 'pg-cell pg-cell--agg' : 'pg-cell');
|
|
557
|
+
cell.setAttribute('data-row-index', String(row.rowIndex));
|
|
558
|
+
cell.setAttribute('data-col-index', String(colOffset + i));
|
|
559
|
+
cell.setAttribute('data-col-id', col.colId);
|
|
560
|
+
cell.setAttribute('role', 'gridcell');
|
|
561
|
+
if (hasValue) {
|
|
562
|
+
const align = col.textAlign ?? 'right';
|
|
563
|
+
if (align !== 'left')
|
|
564
|
+
cell.classList.add(`pg-cell--align-${align}`);
|
|
565
|
+
if (options.showVerticalBorders)
|
|
566
|
+
cell.classList.add('pg-cell--v-border');
|
|
567
|
+
const inner = createDiv('pg-cell__inner');
|
|
568
|
+
const summaryFn = resolveColumnRenderer(col, 'summary');
|
|
569
|
+
if (summaryFn) {
|
|
570
|
+
const rendered = summaryFn({
|
|
571
|
+
colDef: col,
|
|
572
|
+
value: aggVal,
|
|
573
|
+
aggregation: col.aggFunc,
|
|
574
|
+
label: col.summaryLabel,
|
|
575
|
+
api: null,
|
|
576
|
+
});
|
|
577
|
+
if (typeof rendered === 'string')
|
|
578
|
+
inner.innerHTML = rendered;
|
|
579
|
+
else
|
|
580
|
+
inner.appendChild(rendered);
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
const span = document.createElement('span');
|
|
584
|
+
span.className = 'pg-cell__value';
|
|
585
|
+
span.textContent = this.formatAggValue(aggVal, col, options);
|
|
586
|
+
inner.appendChild(span);
|
|
587
|
+
}
|
|
588
|
+
cell.appendChild(inner);
|
|
589
|
+
}
|
|
590
|
+
el.appendChild(cell);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Format a computed aggregate value for display.
|
|
595
|
+
*
|
|
596
|
+
* - For `count` the value is emitted as a plain integer string.
|
|
597
|
+
* - For all other functions the value is routed through {@link formatValue}
|
|
598
|
+
* so the column's currency symbol, locale, and precision are applied.
|
|
599
|
+
*
|
|
600
|
+
* @param value - Raw numeric aggregate result.
|
|
601
|
+
* @param col - Column definition (used for type and formatting options).
|
|
602
|
+
* @param options - Renderer options (locale, currency symbol, etc.).
|
|
603
|
+
*/
|
|
604
|
+
formatAggValue(value, col, options) {
|
|
605
|
+
if (col.aggFunc === 'count') {
|
|
606
|
+
return String(typeof value === 'number' ? Math.round(value) : value ?? '');
|
|
607
|
+
}
|
|
608
|
+
const num = typeof value === 'number' ? value : parseFloat(String(value ?? ''));
|
|
609
|
+
if (!isFinite(num))
|
|
610
|
+
return '—';
|
|
611
|
+
return (formatValue(num, col, {
|
|
612
|
+
locale: options.locale,
|
|
613
|
+
currencySymbol: options.currencySymbol,
|
|
614
|
+
dateFormat: options.dateFormat,
|
|
615
|
+
timeZone: options.timeZone,
|
|
616
|
+
}) || '—');
|
|
617
|
+
}
|
|
618
|
+
updatePanelRow(ps, row, displayIndex, options) {
|
|
619
|
+
const cls = this.getRowClass(row, displayIndex, options);
|
|
620
|
+
const els = [ps.left, ps.center, ps.right].filter((e) => e !== null);
|
|
621
|
+
const rowIndexStr = String(row.rowIndex);
|
|
622
|
+
for (const el of els) {
|
|
623
|
+
el.className = cls;
|
|
624
|
+
el.setAttribute('data-row-index', rowIndexStr);
|
|
625
|
+
if (row.type === 'group')
|
|
626
|
+
el.setAttribute('data-level', String(row.level));
|
|
627
|
+
if (options.treeData && row.type === 'data')
|
|
628
|
+
el.setAttribute('data-level', String(row.level));
|
|
629
|
+
// Re-stamp every cell's own `data-row-index` too. Cells set it at build
|
|
630
|
+
// time and are reused across renders — but a row's index can shift while
|
|
631
|
+
// its cached DOM is kept (e.g. a Master/Detail detail row being injected
|
|
632
|
+
// above it, or a group expanding). Selection/keyboard/clipboard all match
|
|
633
|
+
// cells by this attribute, so leaving it stale silently breaks cell
|
|
634
|
+
// selection on any row whose index moved without a full rebuild.
|
|
635
|
+
const cells = el.querySelectorAll('.pg-cell[data-row-index]');
|
|
636
|
+
for (const cell of cells)
|
|
637
|
+
cell.setAttribute('data-row-index', rowIndexStr);
|
|
638
|
+
}
|
|
639
|
+
// Sync expand/collapse icon — expanded state can change without a full row rebuild.
|
|
640
|
+
// Footer rows have no toggle button so the querySelector guard handles them.
|
|
641
|
+
if ((row.type === 'group' || row.type === 'group-footer') && ps.center) {
|
|
642
|
+
const toggleBtn = ps.center.querySelector('.pg-row-group__toggle');
|
|
643
|
+
if (toggleBtn) {
|
|
644
|
+
const iconEl = toggleBtn.querySelector('.pg-icon');
|
|
645
|
+
if (iconEl) {
|
|
646
|
+
this.iconRenderer.updateIcon(iconEl, row.expanded ? 'chevronDown' : 'chevronRight');
|
|
647
|
+
}
|
|
648
|
+
toggleBtn.setAttribute('aria-label', row.expanded ? 'Collapse group' : 'Expand group');
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
// Sync the Master/Detail toggle icon — expanded state lives in
|
|
652
|
+
// `store.expandedRowIds`, not on the `RowNode` itself, so it must be
|
|
653
|
+
// re-read and re-applied on every update rather than baked in at build time.
|
|
654
|
+
if (row.type === 'data' && options.masterDetail) {
|
|
655
|
+
const isExpanded = options.masterDetail.isExpandedFn(row.nodeId);
|
|
656
|
+
for (const el of els) {
|
|
657
|
+
const toggleBtn = el.querySelector('.pg-detail-toggle');
|
|
658
|
+
if (!toggleBtn)
|
|
659
|
+
continue;
|
|
660
|
+
const iconEl = toggleBtn.querySelector('.pg-icon');
|
|
661
|
+
if (iconEl)
|
|
662
|
+
this.iconRenderer.updateIcon(iconEl, isExpanded ? 'chevronDown' : 'chevronRight');
|
|
663
|
+
toggleBtn.setAttribute('aria-label', isExpanded ? 'Collapse detail' : 'Expand detail');
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
// Sync the Tree Data toggle icon — same reasoning as Master/Detail above:
|
|
667
|
+
// expansion state lives in `expandedTreeNodeIds`, not on the `RowNode`.
|
|
668
|
+
if (row.type === 'data' && options.treeData) {
|
|
669
|
+
for (const el of els)
|
|
670
|
+
syncTreeToggle(el, row, options.treeData, this.iconRenderer);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Inserts the Master/Detail expand/collapse toggle as a sibling of
|
|
675
|
+
* `.pg-cell__inner` (never inside it) — `.pg-cell__inner` is wiped and
|
|
676
|
+
* rebuilt wholesale by cell-edit start/stop (`GridCore.startCellEdit` /
|
|
677
|
+
* `renderCellValue`), which would silently destroy a toggle placed inside it
|
|
678
|
+
* the first time this column is edited.
|
|
679
|
+
*/
|
|
680
|
+
applyMasterDetailToggle(cellEl, row, colDef, options) {
|
|
681
|
+
const md = options.masterDetail;
|
|
682
|
+
if (!md || row.type !== 'data' || colDef.colId !== md.toggleColumnId)
|
|
683
|
+
return;
|
|
684
|
+
if (!md.hasDetailFn(row.data))
|
|
685
|
+
return;
|
|
686
|
+
const isExpanded = md.isExpandedFn(row.nodeId);
|
|
687
|
+
const toggleBtn = createDiv('pg-detail-toggle');
|
|
688
|
+
toggleBtn.setAttribute('role', 'button');
|
|
689
|
+
toggleBtn.setAttribute('data-detail-toggle', '');
|
|
690
|
+
toggleBtn.setAttribute('aria-label', isExpanded ? 'Collapse detail' : 'Expand detail');
|
|
691
|
+
toggleBtn.appendChild(this.iconRenderer.render(isExpanded ? 'chevronDown' : 'chevronRight', { size: 16 }));
|
|
692
|
+
const inner = cellEl.querySelector('.pg-cell__inner');
|
|
693
|
+
if (inner) {
|
|
694
|
+
cellEl.insertBefore(toggleBtn, inner);
|
|
695
|
+
}
|
|
696
|
+
else {
|
|
697
|
+
cellEl.insertBefore(toggleBtn, cellEl.firstChild);
|
|
698
|
+
}
|
|
699
|
+
toggleBtn.addEventListener('click', (e) => {
|
|
700
|
+
e.stopPropagation();
|
|
701
|
+
this.eventBus.emit(GridEventType.ROW_DETAIL_TOGGLE_CLICKED, { row, colDef });
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
attachRowListeners(el, row, cols, colOffset, options) {
|
|
705
|
+
el.addEventListener('click', (e) => {
|
|
706
|
+
const checkboxEl = e.target.closest('.pg-checkbox');
|
|
707
|
+
if (checkboxEl) {
|
|
708
|
+
e.stopPropagation();
|
|
709
|
+
this.rowSelectionEngine.toggleRowSelection(row.nodeId, this.store.get('allRows'));
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
this.eventBus.emit(GridEventType.ROW_CLICKED, { row, event: e, rowIndex: row.rowIndex });
|
|
713
|
+
});
|
|
714
|
+
el.addEventListener('dblclick', (e) => {
|
|
715
|
+
this.eventBus.emit(GridEventType.ROW_DOUBLE_CLICKED, { row, event: e, rowIndex: row.rowIndex });
|
|
716
|
+
});
|
|
717
|
+
el.addEventListener('mousedown', (e) => {
|
|
718
|
+
if (e.button !== 0)
|
|
719
|
+
return;
|
|
720
|
+
// The Master/Detail toggle sits inside a cell but must never trigger
|
|
721
|
+
// cell selection — it emits its own click event (see
|
|
722
|
+
// applyMasterDetailToggle) and stops there.
|
|
723
|
+
if (e.target.closest('[data-detail-toggle]'))
|
|
724
|
+
return;
|
|
725
|
+
const cellEl = e.target.closest('[data-col-index][data-col-id]');
|
|
726
|
+
if (!cellEl)
|
|
727
|
+
return;
|
|
728
|
+
const globalColIndex = Number(cellEl.getAttribute('data-col-index'));
|
|
729
|
+
const colId = cellEl.getAttribute('data-col-id') ?? '';
|
|
730
|
+
// For the virtual auto-group column (colId '__group__'):
|
|
731
|
+
// • data rows → use the real leaf group ColumnDef (supports editing)
|
|
732
|
+
// • group/footer rows → use the non-editable sentinel (editing blocked at startCellEdit)
|
|
733
|
+
const colDef = cols.find((c) => c.colId === colId)
|
|
734
|
+
?? (colId === '__group__'
|
|
735
|
+
? (row.type === 'data' ? (options.leafGroupColDef ?? null) : GROUP_LABEL_COL_DEF)
|
|
736
|
+
: null);
|
|
737
|
+
if (!colDef)
|
|
738
|
+
return;
|
|
739
|
+
this.eventBus.emit(GridEventType.CELL_CLICKED, {
|
|
740
|
+
row,
|
|
741
|
+
colDef,
|
|
742
|
+
value: null,
|
|
743
|
+
rowIndex: row.rowIndex,
|
|
744
|
+
colIndex: globalColIndex,
|
|
745
|
+
event: e,
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
el.addEventListener('contextmenu', (e) => {
|
|
749
|
+
const cellEl = e.target.closest('[data-col-index][data-col-id]');
|
|
750
|
+
if (!cellEl)
|
|
751
|
+
return;
|
|
752
|
+
e.preventDefault();
|
|
753
|
+
const globalColIndex = Number(cellEl.getAttribute('data-col-index'));
|
|
754
|
+
this.eventBus.emit(GridEventType.CELL_CONTEXT_MENU, {
|
|
755
|
+
row,
|
|
756
|
+
rowIndex: row.rowIndex,
|
|
757
|
+
colIndex: globalColIndex,
|
|
758
|
+
x: e.clientX,
|
|
759
|
+
y: e.clientY,
|
|
760
|
+
event: e,
|
|
761
|
+
});
|
|
762
|
+
});
|
|
763
|
+
el.addEventListener('dblclick', (e) => {
|
|
764
|
+
const cellEl = e.target.closest('[data-col-index][data-col-id]');
|
|
765
|
+
if (!cellEl)
|
|
766
|
+
return;
|
|
767
|
+
const globalColIndex = Number(cellEl.getAttribute('data-col-index'));
|
|
768
|
+
const colId = cellEl.getAttribute('data-col-id') ?? '';
|
|
769
|
+
const colDef = cols.find((c) => c.colId === colId)
|
|
770
|
+
?? (colId === '__group__'
|
|
771
|
+
? (row.type === 'data' ? (options.leafGroupColDef ?? null) : GROUP_LABEL_COL_DEF)
|
|
772
|
+
: null);
|
|
773
|
+
if (!colDef)
|
|
774
|
+
return;
|
|
775
|
+
this.eventBus.emit(GridEventType.CELL_DOUBLE_CLICKED, {
|
|
776
|
+
row,
|
|
777
|
+
colDef,
|
|
778
|
+
value: null,
|
|
779
|
+
rowIndex: row.rowIndex,
|
|
780
|
+
colIndex: globalColIndex,
|
|
781
|
+
event: e,
|
|
782
|
+
});
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
getRowClass(row, displayIndex, options) {
|
|
786
|
+
const cls = ['pg-row'];
|
|
787
|
+
if (row.selected)
|
|
788
|
+
cls.push('pg-row--selected');
|
|
789
|
+
if (row.type === 'group')
|
|
790
|
+
cls.push('pg-row--group');
|
|
791
|
+
if (row.type === 'group-footer')
|
|
792
|
+
cls.push('pg-row--group-footer');
|
|
793
|
+
if (row.type === 'detail')
|
|
794
|
+
cls.push('pg-row--detail');
|
|
795
|
+
if (options.treeData && row.type === 'data')
|
|
796
|
+
cls.push('pg-row--tree');
|
|
797
|
+
if (row.isTreeFiller)
|
|
798
|
+
cls.push('pg-row--tree-filler');
|
|
799
|
+
if (options.rowShading && displayIndex % 2 === 1)
|
|
800
|
+
cls.push('pg-row--alt');
|
|
801
|
+
if (row.cssClass)
|
|
802
|
+
cls.push(row.cssClass);
|
|
803
|
+
return cls.join(' ');
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
//# sourceMappingURL=body-renderer.js.map
|