@toolbox-web/grid 0.3.2 → 0.4.0
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/README.md +5 -4
- package/all.d.ts +19 -19
- package/all.d.ts.map +1 -1
- package/all.js +1775 -1202
- package/all.js.map +1 -1
- package/index.js +2143 -2015
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +22 -12
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/columns.d.ts +0 -9
- package/lib/core/internal/columns.d.ts.map +1 -1
- package/lib/core/internal/config-manager.d.ts +236 -0
- package/lib/core/internal/config-manager.d.ts.map +1 -0
- package/lib/core/internal/event-delegation.d.ts.map +1 -1
- package/lib/core/internal/header.d.ts.map +1 -1
- package/lib/core/internal/keyboard.d.ts.map +1 -1
- package/lib/core/internal/render-scheduler.d.ts +123 -0
- package/lib/core/internal/render-scheduler.d.ts.map +1 -0
- package/lib/core/internal/rows.d.ts +8 -3
- package/lib/core/internal/rows.d.ts.map +1 -1
- package/lib/core/internal/sanitize.d.ts +10 -2
- package/lib/core/internal/sanitize.d.ts.map +1 -1
- package/lib/core/internal/shell.d.ts +40 -2
- package/lib/core/internal/shell.d.ts.map +1 -1
- package/lib/core/internal/validate-config.d.ts +11 -0
- package/lib/core/internal/validate-config.d.ts.map +1 -0
- package/lib/core/plugin/base-plugin.d.ts +70 -0
- package/lib/core/plugin/base-plugin.d.ts.map +1 -1
- package/lib/core/plugin/plugin-manager.d.ts +13 -2
- package/lib/core/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/core/plugin/types.d.ts +17 -3
- package/lib/core/plugin/types.d.ts.map +1 -1
- package/lib/core/types.d.ts +112 -12
- package/lib/core/types.d.ts.map +1 -1
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.js +50 -18
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +60 -25
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +51 -16
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts +117 -0
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -0
- package/lib/{core/internal → plugins/editing}/editors.d.ts +1 -1
- package/lib/plugins/editing/editors.d.ts.map +1 -0
- package/lib/plugins/editing/index.d.ts +8 -0
- package/lib/plugins/editing/index.d.ts.map +1 -0
- package/lib/plugins/editing/index.js +705 -0
- package/lib/plugins/editing/index.js.map +1 -0
- package/lib/plugins/editing/types.d.ts +45 -0
- package/lib/plugins/editing/types.d.ts.map +1 -0
- package/lib/plugins/export/ExportPlugin.d.ts.map +1 -1
- package/lib/plugins/export/index.js +74 -39
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
- package/lib/plugins/filtering/index.js +87 -50
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/grouping-columns.d.ts +4 -4
- package/lib/plugins/grouping-columns/grouping-columns.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/index.js +59 -24
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-rows/grouping-rows.d.ts.map +1 -1
- package/lib/plugins/grouping-rows/index.js +46 -11
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +2 -2
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
- package/lib/plugins/master-detail/index.js +140 -102
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/master-detail/types.d.ts +12 -2
- package/lib/plugins/master-detail/types.d.ts.map +1 -1
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts.map +1 -1
- package/lib/plugins/multi-sort/index.js +59 -22
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +41 -6
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-rows/index.js +45 -9
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +42 -7
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/reorder/ReorderPlugin.d.ts.map +1 -1
- package/lib/plugins/reorder/index.js +59 -19
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js +41 -6
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js +48 -13
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +3 -3
- package/lib/plugins/tree/TreePlugin.d.ts.map +1 -1
- package/lib/plugins/tree/index.js +165 -126
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/tree-data.d.ts +6 -6
- package/lib/plugins/tree/tree-data.d.ts.map +1 -1
- package/lib/plugins/tree/tree-detect.d.ts +5 -9
- package/lib/plugins/tree/tree-detect.d.ts.map +1 -1
- package/lib/plugins/tree/types.d.ts +16 -4
- package/lib/plugins/tree/types.d.ts.map +1 -1
- package/lib/plugins/undo-redo/index.js +46 -11
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +37 -2
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/public.d.ts +104 -13
- package/public.d.ts.map +1 -1
- package/umd/grid.all.umd.js +31 -19
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +18 -6
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/clipboard.umd.js +1 -1
- package/umd/plugins/clipboard.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +2 -0
- package/umd/plugins/editing.umd.js.map +1 -0
- package/umd/plugins/export.umd.js +2 -2
- package/umd/plugins/export.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pinned-rows.umd.js +1 -1
- package/umd/plugins/pinned-rows.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
- package/lib/core/internal/column-state.d.ts +0 -124
- package/lib/core/internal/column-state.d.ts.map +0 -1
- package/lib/core/internal/editing.d.ts +0 -76
- package/lib/core/internal/editing.d.ts.map +0 -1
- package/lib/core/internal/editors.d.ts.map +0 -1
- package/lib/core/internal/grid-internals.d.ts +0 -83
- package/lib/core/internal/grid-internals.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reorder.umd.js","sources":["../../../../../libs/grid/src/lib/plugins/reorder/column-drag.ts","../../../../../libs/grid/src/lib/plugins/reorder/ReorderPlugin.ts"],"sourcesContent":["/**\n * Column Reordering Core Logic\n *\n * Pure functions for column drag and reordering operations.\n */\n\nimport type { ColumnConfig } from '../../core/types';\n\n/**\n * Check if a column can be moved based on its own metadata.\n * This checks column-level properties like lockPosition and suppressMovable.\n *\n * Note: For full movability checks including plugin constraints (e.g., pinned columns),\n * use `grid.queryPlugins({ type: PLUGIN_QUERIES.CAN_MOVE_COLUMN, context: column })`\n * which queries all plugins via the generic plugin query system.\n *\n * @param column - The column configuration to check\n * @returns True if the column can be moved based on its metadata\n */\nexport function canMoveColumn<TRow = unknown>(column: ColumnConfig<TRow>): boolean {\n // Check for lockPosition or suppressMovable properties in the column config\n const meta = column.meta ?? {};\n return meta.lockPosition !== true && meta.suppressMovable !== true;\n}\n\n/**\n * Move a column from one position to another in the order array.\n *\n * @param columns - Array of field names in current order\n * @param fromIndex - The current index of the column to move\n * @param toIndex - The target index to move the column to\n * @returns New array with updated order\n */\nexport function moveColumn(columns: string[], fromIndex: number, toIndex: number): string[] {\n if (fromIndex === toIndex) return columns;\n if (fromIndex < 0 || fromIndex >= columns.length) return columns;\n if (toIndex < 0 || toIndex > columns.length) return columns;\n\n const result = [...columns];\n const [removed] = result.splice(fromIndex, 1);\n result.splice(toIndex, 0, removed);\n return result;\n}\n\n/**\n * Calculate the drop index based on the current drag position.\n *\n * @param dragX - The current X position of the drag\n * @param headerRect - The bounding rect of the header container\n * @param columnWidths - Array of column widths in order\n * @returns The index where the column should be dropped\n */\nexport function getDropIndex(dragX: number, headerRect: DOMRect, columnWidths: number[]): number {\n let x = headerRect.left;\n\n for (let i = 0; i < columnWidths.length; i++) {\n const mid = x + columnWidths[i] / 2;\n if (dragX < mid) return i;\n x += columnWidths[i];\n }\n\n return columnWidths.length;\n}\n\n/**\n * Reorder columns according to a specified order.\n * Columns not in the order array are appended at the end.\n *\n * @param columns - Array of column configurations\n * @param order - Array of field names specifying the desired order\n * @returns New array of columns in the specified order\n */\nexport function reorderColumns<TRow = unknown>(columns: ColumnConfig<TRow>[], order: string[]): ColumnConfig<TRow>[] {\n const columnMap = new Map<string, ColumnConfig<TRow>>(columns.map((c) => [c.field as string, c]));\n const reordered: ColumnConfig<TRow>[] = [];\n\n // Add columns in specified order\n for (const field of order) {\n const col = columnMap.get(field);\n if (col) {\n reordered.push(col);\n columnMap.delete(field);\n }\n }\n\n // Add any remaining columns not in order\n for (const col of columnMap.values()) {\n reordered.push(col);\n }\n\n return reordered;\n}\n","/**\n * Column Reordering Plugin (Class-based)\n *\n * Provides drag-and-drop column reordering functionality for tbw-grid.\n * Supports keyboard and mouse interactions with visual feedback.\n * Uses FLIP animation technique for smooth column transitions.\n *\n * Animation respects grid-level animation.mode setting but style is plugin-configured.\n */\n\nimport { ensureCellVisible } from '../../core/internal/keyboard';\nimport { BaseGridPlugin, PLUGIN_QUERIES } from '../../core/plugin/base-plugin';\nimport type { ColumnConfig, GridConfig } from '../../core/types';\nimport { canMoveColumn, moveColumn } from './column-drag';\nimport styles from './reorder.css?inline';\nimport type { ColumnMoveDetail, ReorderConfig } from './types';\n\n/** Extended grid interface with column order methods */\ninterface GridWithColumnOrder {\n setColumnOrder(order: string[]): void;\n getColumnOrder(): string[];\n requestStateChange?: () => void;\n /** Query plugins for inter-plugin communication */\n queryPlugins<T>(query: { type: string; context: unknown }): T[];\n /** Effective grid config */\n effectiveConfig?: GridConfig;\n}\n\n/**\n * Column Reordering Plugin for tbw-grid\n *\n * @example\n * ```ts\n * new ReorderPlugin()\n * ```\n */\nexport class ReorderPlugin extends BaseGridPlugin<ReorderConfig> {\n readonly name = 'reorder';\n override readonly version = '1.0.0';\n\n protected override get defaultConfig(): Partial<ReorderConfig> {\n return {\n animation: 'flip', // Plugin's own default\n };\n }\n\n /**\n * Resolve animation type from plugin config.\n * Respects grid-level animation.mode (disabled = no animation).\n */\n private get animationType(): false | 'flip' | 'fade' {\n // Check if animations are globally disabled\n if (!this.isAnimationEnabled) return false;\n\n // Plugin config (with default from defaultConfig)\n if (this.config.animation !== undefined) return this.config.animation;\n\n // Legacy viewTransition fallback\n if (this.config.viewTransition === false) return false;\n if (this.config.viewTransition === true) return 'flip';\n\n return 'flip'; // Plugin default\n }\n\n /**\n * Check if animations are enabled at the grid level.\n * Respects gridConfig.animation.mode and CSS variable.\n */\n private get isAnimationEnabled(): boolean {\n const gridEl = this.grid as unknown as GridWithColumnOrder;\n const mode = gridEl.effectiveConfig?.animation?.mode ?? 'reduced-motion';\n\n // Explicit off = disabled\n if (mode === false || mode === 'off') return false;\n\n // Explicit on = always enabled\n if (mode === true || mode === 'on') return true;\n\n // reduced-motion: check CSS variable (set by grid based on media query)\n const host = this.shadowRoot?.host as HTMLElement | undefined;\n if (host) {\n const enabled = getComputedStyle(host).getPropertyValue('--tbw-animation-enabled').trim();\n return enabled !== '0';\n }\n\n return true; // Default to enabled\n }\n\n /**\n * Get animation duration from CSS variable (set by grid config).\n */\n private get animationDuration(): number {\n // Plugin config override\n if (this.config.animationDuration !== undefined) {\n return this.config.animationDuration;\n }\n\n // Read from CSS variable (already set by grid from gridConfig.animation.duration)\n const host = this.shadowRoot?.host as HTMLElement | undefined;\n if (host) {\n const durationStr = getComputedStyle(host).getPropertyValue('--tbw-animation-duration').trim();\n const parsed = parseInt(durationStr, 10);\n if (!isNaN(parsed)) return parsed;\n }\n\n return 200; // Default\n }\n\n // #region Internal State\n private isDragging = false;\n private draggedField: string | null = null;\n private draggedIndex: number | null = null;\n private dropIndex: number | null = null;\n // #endregion\n\n // #region Lifecycle\n\n override attach(grid: import('../../core/plugin/base-plugin').GridElement): void {\n super.attach(grid);\n\n // Listen for reorder requests from other plugins (e.g., VisibilityPlugin)\n // Uses disconnectSignal for automatic cleanup - no need for manual removeEventListener\n (grid as unknown as HTMLElement).addEventListener(\n 'column-reorder-request',\n (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (detail?.field && typeof detail.toIndex === 'number') {\n this.moveColumn(detail.field, detail.toIndex);\n }\n },\n { signal: this.disconnectSignal },\n );\n }\n\n override detach(): void {\n this.isDragging = false;\n this.draggedField = null;\n this.draggedIndex = null;\n this.dropIndex = null;\n }\n // #endregion\n\n // #region Hooks\n\n override afterRender(): void {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot) return;\n\n const headers = shadowRoot.querySelectorAll('.header-row > .cell');\n\n headers.forEach((header) => {\n const headerEl = header as HTMLElement;\n const field = headerEl.getAttribute('data-field');\n if (!field) return;\n\n const column = this.columns.find((c) => c.field === field);\n // Check both local metadata and plugin queries (e.g., PinnedColumnsPlugin)\n const gridEl = this.grid as unknown as GridWithColumnOrder;\n const pluginResponses = gridEl.queryPlugins<boolean>({\n type: PLUGIN_QUERIES.CAN_MOVE_COLUMN,\n context: column as ColumnConfig,\n });\n const pluginAllows = !pluginResponses.includes(false);\n if (!column || !canMoveColumn(column) || !pluginAllows) {\n headerEl.draggable = false;\n return;\n }\n\n headerEl.draggable = true;\n\n // Remove existing listeners to prevent duplicates\n if (headerEl.getAttribute('data-dragstart-bound')) return;\n headerEl.setAttribute('data-dragstart-bound', 'true');\n\n headerEl.addEventListener('dragstart', (e: DragEvent) => {\n const currentOrder = this.getColumnOrder();\n const orderIndex = currentOrder.indexOf(field);\n this.isDragging = true;\n this.draggedField = field;\n this.draggedIndex = orderIndex;\n\n if (e.dataTransfer) {\n e.dataTransfer.effectAllowed = 'move';\n e.dataTransfer.setData('text/plain', field);\n }\n\n headerEl.classList.add('dragging');\n });\n\n headerEl.addEventListener('dragend', () => {\n this.isDragging = false;\n this.draggedField = null;\n this.draggedIndex = null;\n this.dropIndex = null;\n\n shadowRoot.querySelectorAll('.header-row > .cell').forEach((h) => {\n h.classList.remove('dragging', 'drop-target', 'drop-before', 'drop-after');\n });\n });\n\n headerEl.addEventListener('dragover', (e: DragEvent) => {\n e.preventDefault();\n if (!this.isDragging || this.draggedField === field) return;\n\n const rect = headerEl.getBoundingClientRect();\n const midX = rect.left + rect.width / 2;\n\n const currentOrder = this.getColumnOrder();\n const orderIndex = currentOrder.indexOf(field);\n this.dropIndex = e.clientX < midX ? orderIndex : orderIndex + 1;\n\n headerEl.classList.add('drop-target');\n headerEl.classList.toggle('drop-before', e.clientX < midX);\n headerEl.classList.toggle('drop-after', e.clientX >= midX);\n });\n\n headerEl.addEventListener('dragleave', () => {\n headerEl.classList.remove('drop-target', 'drop-before', 'drop-after');\n });\n\n headerEl.addEventListener('drop', (e: DragEvent) => {\n e.preventDefault();\n const draggedField = this.draggedField;\n const draggedIndex = this.draggedIndex;\n const dropIndex = this.dropIndex;\n\n if (!this.isDragging || draggedField === null || draggedIndex === null || dropIndex === null) {\n return;\n }\n\n const effectiveToIndex = dropIndex > draggedIndex ? dropIndex - 1 : dropIndex;\n const currentOrder = this.getColumnOrder();\n const newOrder = moveColumn(currentOrder, draggedIndex, effectiveToIndex);\n\n const detail: ColumnMoveDetail = {\n field: draggedField,\n fromIndex: draggedIndex,\n toIndex: effectiveToIndex,\n columnOrder: newOrder,\n };\n\n // Update the grid's column order (with optional view transition)\n this.updateColumnOrder(newOrder);\n\n this.emit('column-move', detail);\n });\n });\n }\n\n /**\n * Handle Alt+Arrow keyboard shortcuts for column reordering.\n */\n override onKeyDown(event: KeyboardEvent): boolean | void {\n if (!event.altKey || (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight')) {\n return;\n }\n\n const grid = this.grid as unknown as { _focusCol: number; _visibleColumns: ColumnConfig[] };\n const focusCol = grid._focusCol;\n const columns = grid._visibleColumns;\n\n if (focusCol < 0 || focusCol >= columns.length) return;\n\n const column = columns[focusCol];\n if (!column || !canMoveColumn(column)) return;\n\n // Check plugin queries (e.g., PinnedColumnsPlugin)\n const gridEl = this.grid as unknown as GridWithColumnOrder;\n const pluginResponses = gridEl.queryPlugins<boolean>({\n type: PLUGIN_QUERIES.CAN_MOVE_COLUMN,\n context: column,\n });\n if (pluginResponses.includes(false)) return;\n\n const currentOrder = this.getColumnOrder();\n const fromIndex = currentOrder.indexOf(column.field);\n if (fromIndex === -1) return;\n\n const toIndex = event.key === 'ArrowLeft' ? fromIndex - 1 : fromIndex + 1;\n\n // Check bounds\n if (toIndex < 0 || toIndex >= currentOrder.length) return;\n\n // Check if target position is allowed (e.g., not into pinned area)\n const targetColumn = columns.find((c) => c.field === currentOrder[toIndex]);\n if (targetColumn) {\n const targetResponses = gridEl.queryPlugins<boolean>({\n type: PLUGIN_QUERIES.CAN_MOVE_COLUMN,\n context: targetColumn,\n });\n if (targetResponses.includes(false)) return;\n }\n\n this.moveColumn(column.field, toIndex);\n\n // Update focus to follow the moved column and refresh visual focus state\n grid._focusCol = toIndex;\n ensureCellVisible(this.grid as any);\n\n event.preventDefault();\n event.stopPropagation();\n return true;\n }\n // #endregion\n\n // #region Public API\n\n /**\n * Get the current column order from the grid.\n * @returns Array of field names in display order\n */\n getColumnOrder(): string[] {\n return (this.grid as unknown as GridWithColumnOrder).getColumnOrder();\n }\n\n /**\n * Move a column to a new position.\n * @param field - The field name of the column to move\n * @param toIndex - The target index\n */\n moveColumn(field: string, toIndex: number): void {\n const currentOrder = this.getColumnOrder();\n const fromIndex = currentOrder.indexOf(field);\n if (fromIndex === -1) return;\n\n const newOrder = moveColumn(currentOrder, fromIndex, toIndex);\n\n // Update with view transition\n this.updateColumnOrder(newOrder);\n\n this.emit<ColumnMoveDetail>('column-move', {\n field,\n fromIndex,\n toIndex,\n columnOrder: newOrder,\n });\n }\n\n /**\n * Set a specific column order.\n * @param order - Array of field names in desired order\n */\n setColumnOrder(order: string[]): void {\n this.updateColumnOrder(order);\n }\n\n /**\n * Reset column order to the original configuration order.\n */\n resetColumnOrder(): void {\n const originalOrder = this.columns.map((c) => c.field);\n this.updateColumnOrder(originalOrder);\n }\n // #endregion\n\n // #region View Transition\n\n /**\n * Capture header cell positions before reorder.\n */\n private captureHeaderPositions(): Map<string, number> {\n const positions = new Map<string, number>();\n this.shadowRoot?.querySelectorAll('.header-row > .cell[data-field]').forEach((cell) => {\n const field = cell.getAttribute('data-field');\n if (field) positions.set(field, cell.getBoundingClientRect().left);\n });\n return positions;\n }\n\n /**\n * Apply FLIP animation for column reorder.\n * Uses CSS transitions - JS sets initial transform and toggles class.\n * @param oldPositions - Header positions captured before DOM change\n */\n private animateFLIP(oldPositions: Map<string, number>): void {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot || oldPositions.size === 0) return;\n\n // Compute deltas from header cells (stable reference points)\n const deltas = new Map<string, number>();\n shadowRoot.querySelectorAll('.header-row > .cell[data-field]').forEach((cell) => {\n const field = cell.getAttribute('data-field');\n if (!field) return;\n const oldLeft = oldPositions.get(field);\n if (oldLeft === undefined) return;\n const deltaX = oldLeft - cell.getBoundingClientRect().left;\n if (Math.abs(deltaX) > 1) deltas.set(field, deltaX);\n });\n\n if (deltas.size === 0) return;\n\n // Set initial transform (First → Last position offset)\n const cells: HTMLElement[] = [];\n shadowRoot.querySelectorAll('.cell[data-field]').forEach((cell) => {\n const deltaX = deltas.get(cell.getAttribute('data-field') ?? '');\n if (deltaX !== undefined) {\n const el = cell as HTMLElement;\n el.style.transform = `translateX(${deltaX}px)`;\n cells.push(el);\n }\n });\n\n if (cells.length === 0) return;\n\n // Force reflow then animate to final position via CSS transition\n void (shadowRoot.host as HTMLElement).offsetHeight;\n\n const duration = this.animationDuration;\n\n requestAnimationFrame(() => {\n cells.forEach((el) => {\n el.classList.add('flip-animating');\n el.style.transform = '';\n });\n\n // Cleanup after animation\n setTimeout(() => {\n cells.forEach((el) => {\n el.style.transform = '';\n el.classList.remove('flip-animating');\n });\n }, duration + 50);\n });\n }\n\n /**\n * Apply crossfade animation for moved columns.\n * Uses CSS keyframes - JS just toggles classes.\n */\n private animateFade(applyChange: () => void): void {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot) {\n applyChange();\n return;\n }\n\n // Capture old positions to detect which columns moved\n const oldPositions = this.captureHeaderPositions();\n\n // Apply the change first\n applyChange();\n\n // Find which columns changed position\n const movedFields = new Set<string>();\n shadowRoot.querySelectorAll('.header-row > .cell[data-field]').forEach((cell) => {\n const field = cell.getAttribute('data-field');\n if (!field) return;\n const oldLeft = oldPositions.get(field);\n if (oldLeft === undefined) return;\n const newLeft = cell.getBoundingClientRect().left;\n if (Math.abs(oldLeft - newLeft) > 1) {\n movedFields.add(field);\n }\n });\n\n if (movedFields.size === 0) return;\n\n // Add animation class to moved columns (headers + body cells)\n const cells: HTMLElement[] = [];\n shadowRoot.querySelectorAll('.cell[data-field]').forEach((cell) => {\n const field = cell.getAttribute('data-field');\n if (field && movedFields.has(field)) {\n const el = cell as HTMLElement;\n el.classList.add('fade-animating');\n cells.push(el);\n }\n });\n\n if (cells.length === 0) return;\n\n // Remove class after animation completes\n const duration = this.animationDuration;\n setTimeout(() => {\n cells.forEach((el) => el.classList.remove('fade-animating'));\n }, duration + 50);\n }\n\n /**\n * Update column order with configured animation.\n */\n private updateColumnOrder(newOrder: string[]): void {\n const gridEl = this.grid as unknown as GridWithColumnOrder;\n const animation = this.animationType;\n\n if (animation === 'flip' && this.shadowRoot) {\n const oldPositions = this.captureHeaderPositions();\n gridEl.setColumnOrder(newOrder);\n void (this.shadowRoot.host as HTMLElement).offsetHeight;\n this.animateFLIP(oldPositions);\n } else if (animation === 'fade') {\n this.animateFade(() => gridEl.setColumnOrder(newOrder));\n } else {\n gridEl.setColumnOrder(newOrder);\n }\n\n gridEl.requestStateChange?.();\n }\n // #endregion\n\n // #region Styles\n\n override readonly styles = styles;\n // #endregion\n}\n"],"names":["canMoveColumn","column","meta","moveColumn","columns","fromIndex","toIndex","result","removed","ReorderPlugin","BaseGridPlugin","mode","host","durationStr","parsed","grid","e","detail","shadowRoot","header","headerEl","field","c","pluginAllows","PLUGIN_QUERIES","orderIndex","h","rect","midX","draggedField","draggedIndex","dropIndex","effectiveToIndex","currentOrder","newOrder","event","focusCol","gridEl","targetColumn","ensureCellVisible","order","originalOrder","positions","cell","oldPositions","deltas","oldLeft","deltaX","cells","el","duration","applyChange","movedFields","newLeft","animation","styles"],"mappings":"sZAmBO,SAASA,EAA8BC,EAAqC,CAEjF,MAAMC,EAAOD,EAAO,MAAQ,CAAA,EAC5B,OAAOC,EAAK,eAAiB,IAAQA,EAAK,kBAAoB,EAChE,CAUO,SAASC,EAAWC,EAAmBC,EAAmBC,EAA2B,CAG1F,GAFID,IAAcC,GACdD,EAAY,GAAKA,GAAaD,EAAQ,QACtCE,EAAU,GAAKA,EAAUF,EAAQ,OAAQ,OAAOA,EAEpD,MAAMG,EAAS,CAAC,GAAGH,CAAO,EACpB,CAACI,CAAO,EAAID,EAAO,OAAOF,EAAW,CAAC,EAC5C,OAAAE,EAAO,OAAOD,EAAS,EAAGE,CAAO,EAC1BD,CACT,4uBCNO,MAAME,UAAsBC,EAAAA,cAA8B,CACtD,KAAO,UACE,QAAU,QAE5B,IAAuB,eAAwC,CAC7D,MAAO,CACL,UAAW,MAAA,CAEf,CAMA,IAAY,eAAyC,CAEnD,OAAK,KAAK,mBAGN,KAAK,OAAO,YAAc,OAAkB,KAAK,OAAO,UAGxD,KAAK,OAAO,iBAAmB,GAAc,IAC7C,KAAK,OAAO,iBAAmB,GAAa,QAPX,EAUvC,CAMA,IAAY,oBAA8B,CAExC,MAAMC,EADS,KAAK,KACA,iBAAiB,WAAW,MAAQ,iBAGxD,GAAIA,IAAS,IAASA,IAAS,MAAO,MAAO,GAG7C,GAAIA,IAAS,IAAQA,IAAS,KAAM,MAAO,GAG3C,MAAMC,EAAO,KAAK,YAAY,KAC9B,OAAIA,EACc,iBAAiBA,CAAI,EAAE,iBAAiB,yBAAyB,EAAE,KAAA,IAChE,IAGd,EACT,CAKA,IAAY,mBAA4B,CAEtC,GAAI,KAAK,OAAO,oBAAsB,OACpC,OAAO,KAAK,OAAO,kBAIrB,MAAMA,EAAO,KAAK,YAAY,KAC9B,GAAIA,EAAM,CACR,MAAMC,EAAc,iBAAiBD,CAAI,EAAE,iBAAiB,0BAA0B,EAAE,KAAA,EAClFE,EAAS,SAASD,EAAa,EAAE,EACvC,GAAI,CAAC,MAAMC,CAAM,EAAG,OAAOA,CAC7B,CAEA,MAAO,IACT,CAGQ,WAAa,GACb,aAA8B,KAC9B,aAA8B,KAC9B,UAA2B,KAK1B,OAAOC,EAAiE,CAC/E,MAAM,OAAOA,CAAI,EAIhBA,EAAgC,iBAC/B,yBACCC,GAAa,CACZ,MAAMC,EAAUD,EAAkB,OAC9BC,GAAQ,OAAS,OAAOA,EAAO,SAAY,UAC7C,KAAK,WAAWA,EAAO,MAAOA,EAAO,OAAO,CAEhD,EACA,CAAE,OAAQ,KAAK,gBAAA,CAAiB,CAEpC,CAES,QAAe,CACtB,KAAK,WAAa,GAClB,KAAK,aAAe,KACpB,KAAK,aAAe,KACpB,KAAK,UAAY,IACnB,CAKS,aAAoB,CAC3B,MAAMC,EAAa,KAAK,WACxB,GAAI,CAACA,EAAY,OAEDA,EAAW,iBAAiB,qBAAqB,EAEzD,QAASC,GAAW,CAC1B,MAAMC,EAAWD,EACXE,EAAQD,EAAS,aAAa,YAAY,EAChD,GAAI,CAACC,EAAO,OAEZ,MAAMpB,EAAS,KAAK,QAAQ,KAAMqB,GAAMA,EAAE,QAAUD,CAAK,EAOnDE,EAAe,CALN,KAAK,KACW,aAAsB,CACnD,KAAMC,EAAAA,eAAe,gBACrB,QAASvB,CAAA,CACV,EACqC,SAAS,EAAK,EACpD,GAAI,CAACA,GAAU,CAACD,EAAcC,CAAM,GAAK,CAACsB,EAAc,CACtDH,EAAS,UAAY,GACrB,MACF,CAEAA,EAAS,UAAY,GAGjB,CAAAA,EAAS,aAAa,sBAAsB,IAChDA,EAAS,aAAa,uBAAwB,MAAM,EAEpDA,EAAS,iBAAiB,YAAcJ,GAAiB,CAEvD,MAAMS,EADe,KAAK,eAAA,EACM,QAAQJ,CAAK,EAC7C,KAAK,WAAa,GAClB,KAAK,aAAeA,EACpB,KAAK,aAAeI,EAEhBT,EAAE,eACJA,EAAE,aAAa,cAAgB,OAC/BA,EAAE,aAAa,QAAQ,aAAcK,CAAK,GAG5CD,EAAS,UAAU,IAAI,UAAU,CACnC,CAAC,EAEDA,EAAS,iBAAiB,UAAW,IAAM,CACzC,KAAK,WAAa,GAClB,KAAK,aAAe,KACpB,KAAK,aAAe,KACpB,KAAK,UAAY,KAEjBF,EAAW,iBAAiB,qBAAqB,EAAE,QAASQ,GAAM,CAChEA,EAAE,UAAU,OAAO,WAAY,cAAe,cAAe,YAAY,CAC3E,CAAC,CACH,CAAC,EAEDN,EAAS,iBAAiB,WAAaJ,GAAiB,CAEtD,GADAA,EAAE,eAAA,EACE,CAAC,KAAK,YAAc,KAAK,eAAiBK,EAAO,OAErD,MAAMM,EAAOP,EAAS,sBAAA,EAChBQ,EAAOD,EAAK,KAAOA,EAAK,MAAQ,EAGhCF,EADe,KAAK,eAAA,EACM,QAAQJ,CAAK,EAC7C,KAAK,UAAYL,EAAE,QAAUY,EAAOH,EAAaA,EAAa,EAE9DL,EAAS,UAAU,IAAI,aAAa,EACpCA,EAAS,UAAU,OAAO,cAAeJ,EAAE,QAAUY,CAAI,EACzDR,EAAS,UAAU,OAAO,aAAcJ,EAAE,SAAWY,CAAI,CAC3D,CAAC,EAEDR,EAAS,iBAAiB,YAAa,IAAM,CAC3CA,EAAS,UAAU,OAAO,cAAe,cAAe,YAAY,CACtE,CAAC,EAEDA,EAAS,iBAAiB,OAASJ,GAAiB,CAClDA,EAAE,eAAA,EACF,MAAMa,EAAe,KAAK,aACpBC,EAAe,KAAK,aACpBC,EAAY,KAAK,UAEvB,GAAI,CAAC,KAAK,YAAcF,IAAiB,MAAQC,IAAiB,MAAQC,IAAc,KACtF,OAGF,MAAMC,EAAmBD,EAAYD,EAAeC,EAAY,EAAIA,EAC9DE,EAAe,KAAK,eAAA,EACpBC,EAAW/B,EAAW8B,EAAcH,EAAcE,CAAgB,EAElEf,EAA2B,CAC/B,MAAOY,EACP,UAAWC,EACX,QAASE,EACT,YAAaE,CAAA,EAIf,KAAK,kBAAkBA,CAAQ,EAE/B,KAAK,KAAK,cAAejB,CAAM,CACjC,CAAC,EACH,CAAC,CACH,CAKS,UAAUkB,EAAsC,CACvD,GAAI,CAACA,EAAM,QAAWA,EAAM,MAAQ,aAAeA,EAAM,MAAQ,aAC/D,OAGF,MAAMpB,EAAO,KAAK,KACZqB,EAAWrB,EAAK,UAChBX,EAAUW,EAAK,gBAErB,GAAIqB,EAAW,GAAKA,GAAYhC,EAAQ,OAAQ,OAEhD,MAAMH,EAASG,EAAQgC,CAAQ,EAC/B,GAAI,CAACnC,GAAU,CAACD,EAAcC,CAAM,EAAG,OAGvC,MAAMoC,EAAS,KAAK,KAKpB,GAJwBA,EAAO,aAAsB,CACnD,KAAMb,EAAAA,eAAe,gBACrB,QAASvB,CAAA,CACV,EACmB,SAAS,EAAK,EAAG,OAErC,MAAMgC,EAAe,KAAK,eAAA,EACpB5B,EAAY4B,EAAa,QAAQhC,EAAO,KAAK,EACnD,GAAII,IAAc,GAAI,OAEtB,MAAMC,EAAU6B,EAAM,MAAQ,YAAc9B,EAAY,EAAIA,EAAY,EAGxE,GAAIC,EAAU,GAAKA,GAAW2B,EAAa,OAAQ,OAGnD,MAAMK,EAAelC,EAAQ,KAAMkB,GAAMA,EAAE,QAAUW,EAAa3B,CAAO,CAAC,EAC1E,GAAI,EAAAgC,GACsBD,EAAO,aAAsB,CACnD,KAAMb,EAAAA,eAAe,gBACrB,QAASc,CAAA,CACV,EACmB,SAAS,EAAK,GAGpC,YAAK,WAAWrC,EAAO,MAAOK,CAAO,EAGrCS,EAAK,UAAYT,EACjBiC,EAAAA,kBAAkB,KAAK,IAAW,EAElCJ,EAAM,eAAA,EACNA,EAAM,gBAAA,EACC,EACT,CASA,gBAA2B,CACzB,OAAQ,KAAK,KAAwC,eAAA,CACvD,CAOA,WAAWd,EAAef,EAAuB,CAC/C,MAAM2B,EAAe,KAAK,eAAA,EACpB5B,EAAY4B,EAAa,QAAQZ,CAAK,EAC5C,GAAIhB,IAAc,GAAI,OAEtB,MAAM6B,EAAW/B,EAAW8B,EAAc5B,EAAWC,CAAO,EAG5D,KAAK,kBAAkB4B,CAAQ,EAE/B,KAAK,KAAuB,cAAe,CACzC,MAAAb,EACA,UAAAhB,EACA,QAAAC,EACA,YAAa4B,CAAA,CACd,CACH,CAMA,eAAeM,EAAuB,CACpC,KAAK,kBAAkBA,CAAK,CAC9B,CAKA,kBAAyB,CACvB,MAAMC,EAAgB,KAAK,QAAQ,IAAKnB,GAAMA,EAAE,KAAK,EACrD,KAAK,kBAAkBmB,CAAa,CACtC,CAQQ,wBAA8C,CACpD,MAAMC,MAAgB,IACtB,YAAK,YAAY,iBAAiB,iCAAiC,EAAE,QAASC,GAAS,CACrF,MAAMtB,EAAQsB,EAAK,aAAa,YAAY,EACxCtB,GAAOqB,EAAU,IAAIrB,EAAOsB,EAAK,sBAAA,EAAwB,IAAI,CACnE,CAAC,EACMD,CACT,CAOQ,YAAYE,EAAyC,CAC3D,MAAM1B,EAAa,KAAK,WACxB,GAAI,CAACA,GAAc0B,EAAa,OAAS,EAAG,OAG5C,MAAMC,MAAa,IAUnB,GATA3B,EAAW,iBAAiB,iCAAiC,EAAE,QAASyB,GAAS,CAC/E,MAAMtB,EAAQsB,EAAK,aAAa,YAAY,EAC5C,GAAI,CAACtB,EAAO,OACZ,MAAMyB,EAAUF,EAAa,IAAIvB,CAAK,EACtC,GAAIyB,IAAY,OAAW,OAC3B,MAAMC,EAASD,EAAUH,EAAK,sBAAA,EAAwB,KAClD,KAAK,IAAII,CAAM,EAAI,GAAGF,EAAO,IAAIxB,EAAO0B,CAAM,CACpD,CAAC,EAEGF,EAAO,OAAS,EAAG,OAGvB,MAAMG,EAAuB,CAAA,EAU7B,GATA9B,EAAW,iBAAiB,mBAAmB,EAAE,QAASyB,GAAS,CACjE,MAAMI,EAASF,EAAO,IAAIF,EAAK,aAAa,YAAY,GAAK,EAAE,EAC/D,GAAII,IAAW,OAAW,CACxB,MAAME,EAAKN,EACXM,EAAG,MAAM,UAAY,cAAcF,CAAM,MACzCC,EAAM,KAAKC,CAAE,CACf,CACF,CAAC,EAEGD,EAAM,SAAW,EAAG,OAGlB9B,EAAW,KAAqB,aAEtC,MAAMgC,EAAW,KAAK,kBAEtB,sBAAsB,IAAM,CAC1BF,EAAM,QAASC,GAAO,CACpBA,EAAG,UAAU,IAAI,gBAAgB,EACjCA,EAAG,MAAM,UAAY,EACvB,CAAC,EAGD,WAAW,IAAM,CACfD,EAAM,QAASC,GAAO,CACpBA,EAAG,MAAM,UAAY,GACrBA,EAAG,UAAU,OAAO,gBAAgB,CACtC,CAAC,CACH,EAAGC,EAAW,EAAE,CAClB,CAAC,CACH,CAMQ,YAAYC,EAA+B,CACjD,MAAMjC,EAAa,KAAK,WACxB,GAAI,CAACA,EAAY,CACfiC,EAAA,EACA,MACF,CAGA,MAAMP,EAAe,KAAK,uBAAA,EAG1BO,EAAA,EAGA,MAAMC,MAAkB,IAYxB,GAXAlC,EAAW,iBAAiB,iCAAiC,EAAE,QAASyB,GAAS,CAC/E,MAAMtB,EAAQsB,EAAK,aAAa,YAAY,EAC5C,GAAI,CAACtB,EAAO,OACZ,MAAMyB,EAAUF,EAAa,IAAIvB,CAAK,EACtC,GAAIyB,IAAY,OAAW,OAC3B,MAAMO,EAAUV,EAAK,sBAAA,EAAwB,KACzC,KAAK,IAAIG,EAAUO,CAAO,EAAI,GAChCD,EAAY,IAAI/B,CAAK,CAEzB,CAAC,EAEG+B,EAAY,OAAS,EAAG,OAG5B,MAAMJ,EAAuB,CAAA,EAU7B,GATA9B,EAAW,iBAAiB,mBAAmB,EAAE,QAASyB,GAAS,CACjE,MAAMtB,EAAQsB,EAAK,aAAa,YAAY,EAC5C,GAAItB,GAAS+B,EAAY,IAAI/B,CAAK,EAAG,CACnC,MAAM4B,EAAKN,EACXM,EAAG,UAAU,IAAI,gBAAgB,EACjCD,EAAM,KAAKC,CAAE,CACf,CACF,CAAC,EAEGD,EAAM,SAAW,EAAG,OAGxB,MAAME,EAAW,KAAK,kBACtB,WAAW,IAAM,CACfF,EAAM,QAASC,GAAOA,EAAG,UAAU,OAAO,gBAAgB,CAAC,CAC7D,EAAGC,EAAW,EAAE,CAClB,CAKQ,kBAAkBhB,EAA0B,CAClD,MAAMG,EAAS,KAAK,KACdiB,EAAY,KAAK,cAEvB,GAAIA,IAAc,QAAU,KAAK,WAAY,CAC3C,MAAMV,EAAe,KAAK,uBAAA,EAC1BP,EAAO,eAAeH,CAAQ,EACxB,KAAK,WAAW,KAAqB,aAC3C,KAAK,YAAYU,CAAY,CAC/B,MAAWU,IAAc,OACvB,KAAK,YAAY,IAAMjB,EAAO,eAAeH,CAAQ,CAAC,EAEtDG,EAAO,eAAeH,CAAQ,EAGhCG,EAAO,qBAAA,CACT,CAKkB,OAASkB,CAE7B"}
|
|
1
|
+
{"version":3,"file":"reorder.umd.js","sources":["../../../../../libs/grid/src/lib/plugins/reorder/column-drag.ts","../../../../../libs/grid/src/lib/plugins/reorder/ReorderPlugin.ts"],"sourcesContent":["/**\n * Column Reordering Core Logic\n *\n * Pure functions for column drag and reordering operations.\n */\n\nimport type { ColumnConfig } from '../../core/types';\n\n/**\n * Check if a column can be moved based on its own metadata.\n * This checks column-level properties like lockPosition and suppressMovable.\n *\n * Note: For full movability checks including plugin constraints (e.g., pinned columns),\n * use `grid.queryPlugins({ type: PLUGIN_QUERIES.CAN_MOVE_COLUMN, context: column })`\n * which queries all plugins via the generic plugin query system.\n *\n * @param column - The column configuration to check\n * @returns True if the column can be moved based on its metadata\n */\nexport function canMoveColumn<TRow = unknown>(column: ColumnConfig<TRow>): boolean {\n // Check for lockPosition or suppressMovable properties in the column config\n const meta = column.meta ?? {};\n return meta.lockPosition !== true && meta.suppressMovable !== true;\n}\n\n/**\n * Move a column from one position to another in the order array.\n *\n * @param columns - Array of field names in current order\n * @param fromIndex - The current index of the column to move\n * @param toIndex - The target index to move the column to\n * @returns New array with updated order\n */\nexport function moveColumn(columns: string[], fromIndex: number, toIndex: number): string[] {\n if (fromIndex === toIndex) return columns;\n if (fromIndex < 0 || fromIndex >= columns.length) return columns;\n if (toIndex < 0 || toIndex > columns.length) return columns;\n\n const result = [...columns];\n const [removed] = result.splice(fromIndex, 1);\n result.splice(toIndex, 0, removed);\n return result;\n}\n\n/**\n * Calculate the drop index based on the current drag position.\n *\n * @param dragX - The current X position of the drag\n * @param headerRect - The bounding rect of the header container\n * @param columnWidths - Array of column widths in order\n * @returns The index where the column should be dropped\n */\nexport function getDropIndex(dragX: number, headerRect: DOMRect, columnWidths: number[]): number {\n let x = headerRect.left;\n\n for (let i = 0; i < columnWidths.length; i++) {\n const mid = x + columnWidths[i] / 2;\n if (dragX < mid) return i;\n x += columnWidths[i];\n }\n\n return columnWidths.length;\n}\n\n/**\n * Reorder columns according to a specified order.\n * Columns not in the order array are appended at the end.\n *\n * @param columns - Array of column configurations\n * @param order - Array of field names specifying the desired order\n * @returns New array of columns in the specified order\n */\nexport function reorderColumns<TRow = unknown>(columns: ColumnConfig<TRow>[], order: string[]): ColumnConfig<TRow>[] {\n const columnMap = new Map<string, ColumnConfig<TRow>>(columns.map((c) => [c.field as string, c]));\n const reordered: ColumnConfig<TRow>[] = [];\n\n // Add columns in specified order\n for (const field of order) {\n const col = columnMap.get(field);\n if (col) {\n reordered.push(col);\n columnMap.delete(field);\n }\n }\n\n // Add any remaining columns not in order\n for (const col of columnMap.values()) {\n reordered.push(col);\n }\n\n return reordered;\n}\n","/**\n * Column Reordering Plugin (Class-based)\n *\n * Provides drag-and-drop column reordering functionality for tbw-grid.\n * Supports keyboard and mouse interactions with visual feedback.\n * Uses FLIP animation technique for smooth column transitions.\n *\n * Animation respects grid-level animation.mode setting but style is plugin-configured.\n */\n\nimport { ensureCellVisible } from '../../core/internal/keyboard';\nimport { BaseGridPlugin, PLUGIN_QUERIES } from '../../core/plugin/base-plugin';\nimport type { ColumnConfig, GridConfig, InternalGrid } from '../../core/types';\nimport { canMoveColumn, moveColumn } from './column-drag';\nimport styles from './reorder.css?inline';\nimport type { ColumnMoveDetail, ReorderConfig } from './types';\n\n/** Extended grid interface with column order methods */\ninterface GridWithColumnOrder {\n setColumnOrder(order: string[]): void;\n getColumnOrder(): string[];\n requestStateChange?: () => void;\n /** Query plugins for inter-plugin communication */\n queryPlugins<T>(query: { type: string; context: unknown }): T[];\n /** Effective grid config */\n effectiveConfig?: GridConfig;\n}\n\n/**\n * Column Reordering Plugin for tbw-grid\n *\n * @example\n * ```ts\n * new ReorderPlugin()\n * ```\n */\nexport class ReorderPlugin extends BaseGridPlugin<ReorderConfig> {\n readonly name = 'reorder';\n override readonly version = '1.0.0';\n\n protected override get defaultConfig(): Partial<ReorderConfig> {\n return {\n animation: 'flip', // Plugin's own default\n };\n }\n\n /**\n * Resolve animation type from plugin config.\n * Respects grid-level animation.mode (disabled = no animation).\n */\n private get animationType(): false | 'flip' | 'fade' {\n // Check if animations are globally disabled\n if (!this.isAnimationEnabled) return false;\n\n // Plugin config (with default from defaultConfig)\n if (this.config.animation !== undefined) return this.config.animation;\n\n // Legacy viewTransition fallback\n if (this.config.viewTransition === false) return false;\n if (this.config.viewTransition === true) return 'flip';\n\n return 'flip'; // Plugin default\n }\n\n /**\n * Check if animations are enabled at the grid level.\n * Respects gridConfig.animation.mode and CSS variable.\n */\n private get isAnimationEnabled(): boolean {\n const gridEl = this.grid as unknown as GridWithColumnOrder;\n const mode = gridEl.effectiveConfig?.animation?.mode ?? 'reduced-motion';\n\n // Explicit off = disabled\n if (mode === false || mode === 'off') return false;\n\n // Explicit on = always enabled\n if (mode === true || mode === 'on') return true;\n\n // reduced-motion: check CSS variable (set by grid based on media query)\n const host = this.shadowRoot?.host as HTMLElement | undefined;\n if (host) {\n const enabled = getComputedStyle(host).getPropertyValue('--tbw-animation-enabled').trim();\n return enabled !== '0';\n }\n\n return true; // Default to enabled\n }\n\n /**\n * Get animation duration from CSS variable (set by grid config).\n */\n private get animationDuration(): number {\n // Plugin config override\n if (this.config.animationDuration !== undefined) {\n return this.config.animationDuration;\n }\n\n // Read from CSS variable (already set by grid from gridConfig.animation.duration)\n const host = this.shadowRoot?.host as HTMLElement | undefined;\n if (host) {\n const durationStr = getComputedStyle(host).getPropertyValue('--tbw-animation-duration').trim();\n const parsed = parseInt(durationStr, 10);\n if (!isNaN(parsed)) return parsed;\n }\n\n return 200; // Default\n }\n\n // #region Internal State\n private isDragging = false;\n private draggedField: string | null = null;\n private draggedIndex: number | null = null;\n private dropIndex: number | null = null;\n // #endregion\n\n // #region Lifecycle\n\n override attach(grid: import('../../core/plugin/base-plugin').GridElement): void {\n super.attach(grid);\n\n // Listen for reorder requests from other plugins (e.g., VisibilityPlugin)\n // Uses disconnectSignal for automatic cleanup - no need for manual removeEventListener\n (grid as unknown as HTMLElement).addEventListener(\n 'column-reorder-request',\n (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (detail?.field && typeof detail.toIndex === 'number') {\n this.moveColumn(detail.field, detail.toIndex);\n }\n },\n { signal: this.disconnectSignal },\n );\n }\n\n override detach(): void {\n this.isDragging = false;\n this.draggedField = null;\n this.draggedIndex = null;\n this.dropIndex = null;\n }\n // #endregion\n\n // #region Hooks\n\n override afterRender(): void {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot) return;\n\n const headers = shadowRoot.querySelectorAll('.header-row > .cell');\n\n headers.forEach((header) => {\n const headerEl = header as HTMLElement;\n const field = headerEl.getAttribute('data-field');\n if (!field) return;\n\n const column = this.columns.find((c) => c.field === field);\n // Check both local metadata and plugin queries (e.g., PinnedColumnsPlugin)\n const gridEl = this.grid as unknown as GridWithColumnOrder;\n const pluginResponses = gridEl.queryPlugins<boolean>({\n type: PLUGIN_QUERIES.CAN_MOVE_COLUMN,\n context: column as ColumnConfig,\n });\n const pluginAllows = !pluginResponses.includes(false);\n if (!column || !canMoveColumn(column) || !pluginAllows) {\n headerEl.draggable = false;\n return;\n }\n\n headerEl.draggable = true;\n\n // Remove existing listeners to prevent duplicates\n if (headerEl.getAttribute('data-dragstart-bound')) return;\n headerEl.setAttribute('data-dragstart-bound', 'true');\n\n headerEl.addEventListener('dragstart', (e: DragEvent) => {\n const currentOrder = this.getColumnOrder();\n const orderIndex = currentOrder.indexOf(field);\n this.isDragging = true;\n this.draggedField = field;\n this.draggedIndex = orderIndex;\n\n if (e.dataTransfer) {\n e.dataTransfer.effectAllowed = 'move';\n e.dataTransfer.setData('text/plain', field);\n }\n\n headerEl.classList.add('dragging');\n });\n\n headerEl.addEventListener('dragend', () => {\n this.isDragging = false;\n this.draggedField = null;\n this.draggedIndex = null;\n this.dropIndex = null;\n\n shadowRoot.querySelectorAll('.header-row > .cell').forEach((h) => {\n h.classList.remove('dragging', 'drop-target', 'drop-before', 'drop-after');\n });\n });\n\n headerEl.addEventListener('dragover', (e: DragEvent) => {\n e.preventDefault();\n if (!this.isDragging || this.draggedField === field) return;\n\n const rect = headerEl.getBoundingClientRect();\n const midX = rect.left + rect.width / 2;\n\n const currentOrder = this.getColumnOrder();\n const orderIndex = currentOrder.indexOf(field);\n this.dropIndex = e.clientX < midX ? orderIndex : orderIndex + 1;\n\n headerEl.classList.add('drop-target');\n headerEl.classList.toggle('drop-before', e.clientX < midX);\n headerEl.classList.toggle('drop-after', e.clientX >= midX);\n });\n\n headerEl.addEventListener('dragleave', () => {\n headerEl.classList.remove('drop-target', 'drop-before', 'drop-after');\n });\n\n headerEl.addEventListener('drop', (e: DragEvent) => {\n e.preventDefault();\n const draggedField = this.draggedField;\n const draggedIndex = this.draggedIndex;\n const dropIndex = this.dropIndex;\n\n if (!this.isDragging || draggedField === null || draggedIndex === null || dropIndex === null) {\n return;\n }\n\n const effectiveToIndex = dropIndex > draggedIndex ? dropIndex - 1 : dropIndex;\n const currentOrder = this.getColumnOrder();\n const newOrder = moveColumn(currentOrder, draggedIndex, effectiveToIndex);\n\n const detail: ColumnMoveDetail = {\n field: draggedField,\n fromIndex: draggedIndex,\n toIndex: effectiveToIndex,\n columnOrder: newOrder,\n };\n\n // Update the grid's column order (with optional view transition)\n this.updateColumnOrder(newOrder);\n\n this.emit('column-move', detail);\n });\n });\n }\n\n /**\n * Handle Alt+Arrow keyboard shortcuts for column reordering.\n */\n override onKeyDown(event: KeyboardEvent): boolean | void {\n if (!event.altKey || (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight')) {\n return;\n }\n\n const grid = this.grid as unknown as { _focusCol: number; _visibleColumns: ColumnConfig[] };\n const focusCol = grid._focusCol;\n const columns = grid._visibleColumns;\n\n if (focusCol < 0 || focusCol >= columns.length) return;\n\n const column = columns[focusCol];\n if (!column || !canMoveColumn(column)) return;\n\n // Check plugin queries (e.g., PinnedColumnsPlugin)\n const gridEl = this.grid as unknown as GridWithColumnOrder;\n const pluginResponses = gridEl.queryPlugins<boolean>({\n type: PLUGIN_QUERIES.CAN_MOVE_COLUMN,\n context: column,\n });\n if (pluginResponses.includes(false)) return;\n\n const currentOrder = this.getColumnOrder();\n const fromIndex = currentOrder.indexOf(column.field);\n if (fromIndex === -1) return;\n\n const toIndex = event.key === 'ArrowLeft' ? fromIndex - 1 : fromIndex + 1;\n\n // Check bounds\n if (toIndex < 0 || toIndex >= currentOrder.length) return;\n\n // Check if target position is allowed (e.g., not into pinned area)\n const targetColumn = columns.find((c) => c.field === currentOrder[toIndex]);\n if (targetColumn) {\n const targetResponses = gridEl.queryPlugins<boolean>({\n type: PLUGIN_QUERIES.CAN_MOVE_COLUMN,\n context: targetColumn,\n });\n if (targetResponses.includes(false)) return;\n }\n\n this.moveColumn(column.field, toIndex);\n\n // Update focus to follow the moved column and refresh visual focus state\n grid._focusCol = toIndex;\n ensureCellVisible(this.grid as unknown as InternalGrid);\n\n event.preventDefault();\n event.stopPropagation();\n return true;\n }\n // #endregion\n\n // #region Public API\n\n /**\n * Get the current column order from the grid.\n * @returns Array of field names in display order\n */\n getColumnOrder(): string[] {\n return (this.grid as unknown as GridWithColumnOrder).getColumnOrder();\n }\n\n /**\n * Move a column to a new position.\n * @param field - The field name of the column to move\n * @param toIndex - The target index\n */\n moveColumn(field: string, toIndex: number): void {\n const currentOrder = this.getColumnOrder();\n const fromIndex = currentOrder.indexOf(field);\n if (fromIndex === -1) return;\n\n const newOrder = moveColumn(currentOrder, fromIndex, toIndex);\n\n // Update with view transition\n this.updateColumnOrder(newOrder);\n\n this.emit<ColumnMoveDetail>('column-move', {\n field,\n fromIndex,\n toIndex,\n columnOrder: newOrder,\n });\n }\n\n /**\n * Set a specific column order.\n * @param order - Array of field names in desired order\n */\n setColumnOrder(order: string[]): void {\n this.updateColumnOrder(order);\n }\n\n /**\n * Reset column order to the original configuration order.\n */\n resetColumnOrder(): void {\n const originalOrder = this.columns.map((c) => c.field);\n this.updateColumnOrder(originalOrder);\n }\n // #endregion\n\n // #region View Transition\n\n /**\n * Capture header cell positions before reorder.\n */\n private captureHeaderPositions(): Map<string, number> {\n const positions = new Map<string, number>();\n this.shadowRoot?.querySelectorAll('.header-row > .cell[data-field]').forEach((cell) => {\n const field = cell.getAttribute('data-field');\n if (field) positions.set(field, cell.getBoundingClientRect().left);\n });\n return positions;\n }\n\n /**\n * Apply FLIP animation for column reorder.\n * Uses CSS transitions - JS sets initial transform and toggles class.\n * @param oldPositions - Header positions captured before DOM change\n */\n private animateFLIP(oldPositions: Map<string, number>): void {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot || oldPositions.size === 0) return;\n\n // Compute deltas from header cells (stable reference points)\n const deltas = new Map<string, number>();\n shadowRoot.querySelectorAll('.header-row > .cell[data-field]').forEach((cell) => {\n const field = cell.getAttribute('data-field');\n if (!field) return;\n const oldLeft = oldPositions.get(field);\n if (oldLeft === undefined) return;\n const deltaX = oldLeft - cell.getBoundingClientRect().left;\n if (Math.abs(deltaX) > 1) deltas.set(field, deltaX);\n });\n\n if (deltas.size === 0) return;\n\n // Set initial transform (First → Last position offset)\n const cells: HTMLElement[] = [];\n shadowRoot.querySelectorAll('.cell[data-field]').forEach((cell) => {\n const deltaX = deltas.get(cell.getAttribute('data-field') ?? '');\n if (deltaX !== undefined) {\n const el = cell as HTMLElement;\n el.style.transform = `translateX(${deltaX}px)`;\n cells.push(el);\n }\n });\n\n if (cells.length === 0) return;\n\n // Force reflow then animate to final position via CSS transition\n void (shadowRoot.host as HTMLElement).offsetHeight;\n\n const duration = this.animationDuration;\n\n requestAnimationFrame(() => {\n cells.forEach((el) => {\n el.classList.add('flip-animating');\n el.style.transform = '';\n });\n\n // Cleanup after animation\n setTimeout(() => {\n cells.forEach((el) => {\n el.style.transform = '';\n el.classList.remove('flip-animating');\n });\n }, duration + 50);\n });\n }\n\n /**\n * Apply crossfade animation for moved columns.\n * Uses CSS keyframes - JS just toggles classes.\n */\n private animateFade(applyChange: () => void): void {\n const shadowRoot = this.shadowRoot;\n if (!shadowRoot) {\n applyChange();\n return;\n }\n\n // Capture old positions to detect which columns moved\n const oldPositions = this.captureHeaderPositions();\n\n // Apply the change first\n applyChange();\n\n // Find which columns changed position\n const movedFields = new Set<string>();\n shadowRoot.querySelectorAll('.header-row > .cell[data-field]').forEach((cell) => {\n const field = cell.getAttribute('data-field');\n if (!field) return;\n const oldLeft = oldPositions.get(field);\n if (oldLeft === undefined) return;\n const newLeft = cell.getBoundingClientRect().left;\n if (Math.abs(oldLeft - newLeft) > 1) {\n movedFields.add(field);\n }\n });\n\n if (movedFields.size === 0) return;\n\n // Add animation class to moved columns (headers + body cells)\n const cells: HTMLElement[] = [];\n shadowRoot.querySelectorAll('.cell[data-field]').forEach((cell) => {\n const field = cell.getAttribute('data-field');\n if (field && movedFields.has(field)) {\n const el = cell as HTMLElement;\n el.classList.add('fade-animating');\n cells.push(el);\n }\n });\n\n if (cells.length === 0) return;\n\n // Remove class after animation completes\n const duration = this.animationDuration;\n setTimeout(() => {\n cells.forEach((el) => el.classList.remove('fade-animating'));\n }, duration + 50);\n }\n\n /**\n * Update column order with configured animation.\n */\n private updateColumnOrder(newOrder: string[]): void {\n const gridEl = this.grid as unknown as GridWithColumnOrder;\n const animation = this.animationType;\n\n if (animation === 'flip' && this.shadowRoot) {\n const oldPositions = this.captureHeaderPositions();\n gridEl.setColumnOrder(newOrder);\n // Wait for the scheduler to process the virtual window update (RAF)\n // before running FLIP animation on the new cells\n requestAnimationFrame(() => {\n void (this.shadowRoot?.host as HTMLElement)?.offsetHeight;\n this.animateFLIP(oldPositions);\n });\n } else if (animation === 'fade') {\n this.animateFade(() => gridEl.setColumnOrder(newOrder));\n } else {\n gridEl.setColumnOrder(newOrder);\n }\n\n gridEl.requestStateChange?.();\n }\n // #endregion\n\n // #region Styles\n\n override readonly styles = styles;\n // #endregion\n}\n"],"names":["canMoveColumn","column","meta","moveColumn","columns","fromIndex","toIndex","result","removed","ReorderPlugin","BaseGridPlugin","mode","host","durationStr","parsed","grid","e","detail","shadowRoot","header","headerEl","field","c","pluginAllows","PLUGIN_QUERIES","orderIndex","h","rect","midX","draggedField","draggedIndex","dropIndex","effectiveToIndex","currentOrder","newOrder","event","focusCol","gridEl","targetColumn","ensureCellVisible","order","originalOrder","positions","cell","oldPositions","deltas","oldLeft","deltaX","cells","el","duration","applyChange","movedFields","newLeft","animation","styles"],"mappings":"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"}
|
package/umd/plugins/tree.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(c,
|
|
1
|
+
(function(c,p){typeof exports=="object"&&typeof module<"u"?p(exports,require("../../core/plugin/base-plugin")):typeof define=="function"&&define.amd?define(["exports","../../core/plugin/base-plugin"],p):(c=typeof globalThis<"u"?globalThis:c||self,p(c.TbwGridPlugin_tree={},c.TbwGrid))})(this,(function(c,p){"use strict";function b(s,t,e){return s.id!==void 0?String(s.id):e?`${e}-${t}`:String(t)}function K(s,t){const e=new Set(s);return e.has(t)?e.delete(t):e.add(t),e}function m(s,t,e=null,n=0){const r=t.childrenField??"children",o=new Set;for(let i=0;i<s.length;i++){const d=s[i],a=b(d,i,e),l=d[r];if(Array.isArray(l)&&l.length>0){o.add(a);const u=m(l,t,a,n+1);for(const y of u)o.add(y)}}return o}function k(){return new Set}function S(s,t,e,n=null,r=0){const o=e.childrenField??"children";for(let i=0;i<s.length;i++){const d=s[i],a=b(d,i,n);if(a===t)return[a];const l=d[o];if(Array.isArray(l)&&l.length>0){const u=S(l,t,e,a,r+1);if(u)return[a,...u]}}return null}function E(s,t,e,n){const r=S(s,t,e);if(!r)return n;const o=new Set(n);for(let i=0;i<r.length-1;i++)o.add(r[i]);return o}function x(s,t="children"){if(!Array.isArray(s)||s.length===0)return!1;for(const e of s){if(!e)continue;const n=e[t];if(Array.isArray(n)&&n.length>0)return!0}return!1}function A(s){if(!Array.isArray(s)||s.length===0)return null;const t=["children","items","nodes","subRows","nested"];for(const e of s)if(!(!e||typeof e!="object"))for(const n of t){const r=e[n];if(Array.isArray(r)&&r.length>0)return n}return null}function R(s,t="children",e=0){if(!Array.isArray(s)||s.length===0)return e;let n=e;for(const r of s){if(!r)continue;const o=r[t];if(Array.isArray(o)&&o.length>0){const i=R(o,t,e+1);i>n&&(n=i)}}return n}function _(s,t="children"){if(!Array.isArray(s))return 0;let e=0;for(const n of s){if(!n)continue;e++;const r=n[t];Array.isArray(r)&&(e+=_(r,t))}return e}const T=".tree-cell{display:flex;align-items:center;padding-left:calc(var(--tree-depth, 0) * var(--tbw-tree-indent, 20px))}.tree-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center;margin-right:4px}.tree-toggle:hover{color:var(--tbw-tree-accent, var(--tbw-color-accent))}.tree-spacer{width:14px;display:inline-block}.data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}";class C extends p.BaseGridPlugin{name="tree";version="1.0.0";styles=T;get defaultConfig(){return{childrenField:"children",autoDetect:!0,defaultExpanded:!1,indentWidth:20,showExpandIcons:!0,animation:"slide"}}expandedKeys=new Set;initialExpansionDone=!1;flattenedRows=[];rowKeyMap=new Map;previousVisibleKeys=new Set;keysToAnimate=new Set;sortState=null;detach(){this.expandedKeys.clear(),this.initialExpansionDone=!1,this.flattenedRows=[],this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.sortState=null}get animationStyle(){const e=this.grid.effectiveConfig?.animation?.mode??"reduced-motion";if(e===!1||e==="off")return!1;if(e!==!0&&e!=="on"){const n=this.shadowRoot?.host;if(n&&getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim()==="0")return!1}return this.config.animation??"slide"}detect(t){if(!this.config.autoDetect)return!1;const e=t,n=this.config.childrenField??A(e)??"children";return x(e,n)}processRows(t){const e=this.config.childrenField??"children",n=t;if(!x(n,e))return this.flattenedRows=[],this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),[...t];let r=this.withStableKeys(n);this.sortState&&(r=this.sortTree(r,this.sortState.field,this.sortState.direction)),this.config.defaultExpanded&&!this.initialExpansionDone&&(this.expandedKeys=m(r,this.config),this.initialExpansionDone=!0),this.flattenedRows=this.flattenTree(r,this.expandedKeys),this.rowKeyMap.clear(),this.keysToAnimate.clear();const o=new Set;for(const i of this.flattenedRows)this.rowKeyMap.set(i.key,i),o.add(i.key),!this.previousVisibleKeys.has(i.key)&&i.depth>0&&this.keysToAnimate.add(i.key);return this.previousVisibleKeys=o,this.flattenedRows.map(i=>({...i.data,__treeKey:i.key,__treeDepth:i.depth,__treeHasChildren:i.hasChildren,__treeExpanded:i.isExpanded}))}withStableKeys(t,e=null){const n=this.config.childrenField??"children";return t.map((r,o)=>{const i=r.__stableKey,d=r.id!==void 0?String(r.id):i??(e?`${e}-${o}`:String(o)),a=r[n],l=Array.isArray(a)&&a.length>0;return{...r,__stableKey:d,...l?{[n]:this.withStableKeys(a,d)}:{}}})}flattenTree(t,e,n=0){const r=this.config.childrenField??"children",o=[];for(const i of t){const a=i.__stableKey??String(i.id??"?"),l=i[r],u=Array.isArray(l)&&l.length>0,y=e.has(a);o.push({key:a,data:i,depth:n,hasChildren:u,isExpanded:y,parentKey:n>0&&a.substring(0,a.lastIndexOf("-"))||null}),u&&y&&o.push(...this.flattenTree(l,e,n+1))}return o}sortTree(t,e,n){const r=this.config.childrenField??"children";return[...t].sort((i,d)=>{const a=i[e],l=d[e];return a==null&&l==null?0:a==null?-1:l==null?1:a>l?n:a<l?-n:0}).map(i=>{const d=i[r];return Array.isArray(d)&&d.length>0?{...i,[r]:this.sortTree(d,e,n)}:i})}processColumns(t){if(this.flattenedRows.length===0)return[...t];const e=[...t];if(e.length===0)return e;const n={...e[0]},r=n.viewRenderer;if(r?.__treeWrapped)return e;const o=()=>this.config,i=this.setIcon.bind(this),d=this.resolveIcon.bind(this),a=l=>{const{value:u,row:y}=l,{indentWidth:F=20,showExpandIcons:v=!0}=o(),g=y,f=document.createElement("span");if(f.className="tree-cell",f.style.setProperty("--tree-depth",String(g.__treeDepth??0)),f.style.setProperty("--tbw-tree-indent",`${F}px`),g.__treeHasChildren&&v){const h=document.createElement("span");h.className=`tree-toggle${g.__treeExpanded?" expanded":""}`,i(h,d(g.__treeExpanded?"collapse":"expand")),h.setAttribute("data-tree-key",String(g.__treeKey??"")),f.appendChild(h)}else if(v){const h=document.createElement("span");h.className="tree-spacer",f.appendChild(h)}const w=document.createElement("span");if(r){const h=r(l);h instanceof Node?w.appendChild(h):w.textContent=String(h??u??"")}else w.textContent=String(u??"");return f.appendChild(w),f};return a.__treeWrapped=!0,n.viewRenderer=a,e[0]=n,e}onCellClick(t){const e=t.originalEvent?.target;if(!e?.classList.contains("tree-toggle"))return!1;const n=e.getAttribute("data-tree-key"),r=n?this.rowKeyMap.get(n):null;return r?(this.expandedKeys=K(this.expandedKeys,n),this.emit("tree-expand",{key:n,row:r.data,expanded:this.expandedKeys.has(n),depth:r.depth}),this.requestRender(),!0):!1}onHeaderClick(t){if(this.flattenedRows.length===0||!t.column.sortable)return!1;const{field:e}=t.column;!this.sortState||this.sortState.field!==e?this.sortState={field:e,direction:1}:this.sortState.direction===1?this.sortState={field:e,direction:-1}:this.sortState=null;const n=this.grid;return n._sortState!==void 0&&(n._sortState=this.sortState?{...this.sortState}:null),this.emit("sort-change",{field:e,direction:this.sortState?.direction??0}),this.requestRender(),!0}afterRender(){const t=this.animationStyle;if(t===!1||this.keysToAnimate.size===0)return;const e=this.shadowRoot?.querySelector(".rows");if(!e)return;const n=t==="fade"?"tbw-tree-fade-in":"tbw-tree-slide-in";for(const r of e.querySelectorAll(".data-grid-row")){const o=r.querySelector(".cell[data-row]"),i=o?parseInt(o.getAttribute("data-row")??"-1",10):-1,d=this.flattenedRows[i]?.key;d&&this.keysToAnimate.has(d)&&(r.classList.add(n),r.addEventListener("animationend",()=>r.classList.remove(n),{once:!0}))}this.keysToAnimate.clear()}expand(t){this.expandedKeys.add(t),this.requestRender()}collapse(t){this.expandedKeys.delete(t),this.requestRender()}toggle(t){this.expandedKeys=K(this.expandedKeys,t),this.requestRender()}expandAll(){this.expandedKeys=m(this.rows,this.config),this.requestRender()}collapseAll(){this.expandedKeys=k(),this.requestRender()}isExpanded(t){return this.expandedKeys.has(t)}getExpandedKeys(){return[...this.expandedKeys]}getFlattenedRows(){return[...this.flattenedRows]}getRowByKey(t){return this.rowKeyMap.get(t)?.data}expandToKey(t){this.expandedKeys=E(this.rows,t,this.config,this.expandedKeys),this.requestRender()}}c.TreePlugin=C,c.countNodes=_,c.detectTreeStructure=x,c.getMaxDepth=R,c.inferChildrenField=A,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
|
2
2
|
//# sourceMappingURL=tree.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree.umd.js","sources":["../../../../../libs/grid/src/lib/plugins/tree/tree-data.ts","../../../../../libs/grid/src/lib/plugins/tree/tree-detect.ts","../../../../../libs/grid/src/lib/plugins/tree/TreePlugin.ts"],"sourcesContent":["/**\n * Core Tree Data Logic\n *\n * Pure functions for tree flattening, expansion, and traversal.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// The tree plugin intentionally uses `any` for maximum flexibility with user-defined row types.\n\nimport type { FlattenedTreeRow, TreeConfig } from './types';\n\n/**\n * Generates a unique key for a row.\n * Uses row.id if available, otherwise generates from path.\n */\nexport function generateRowKey(row: any, index: number, parentKey: string | null): string {\n if (row.id !== undefined) return String(row.id);\n return parentKey ? `${parentKey}-${index}` : String(index);\n}\n\n/**\n * Flattens a hierarchical tree into a flat array of rows with metadata.\n * Only includes children of expanded nodes.\n */\nexport function flattenTree(\n rows: any[],\n config: TreeConfig,\n expandedKeys: Set<string>,\n parentKey: string | null = null,\n depth = 0\n): FlattenedTreeRow[] {\n const childrenField = config.childrenField ?? 'children';\n const result: FlattenedTreeRow[] = [];\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const key = generateRowKey(row, i, parentKey);\n const children = row[childrenField];\n const hasChildren = Array.isArray(children) && children.length > 0;\n const isExpanded = expandedKeys.has(key);\n\n result.push({\n key,\n data: row,\n depth,\n hasChildren,\n isExpanded,\n parentKey,\n });\n\n // Recursively add children if expanded\n if (hasChildren && isExpanded) {\n const childRows = flattenTree(children, config, expandedKeys, key, depth + 1);\n result.push(...childRows);\n }\n }\n\n return result;\n}\n\n/**\n * Toggles the expansion state of a row.\n * Returns a new Set with the toggled state.\n */\nexport function toggleExpand(expandedKeys: Set<string>, key: string): Set<string> {\n const newExpanded = new Set(expandedKeys);\n if (newExpanded.has(key)) {\n newExpanded.delete(key);\n } else {\n newExpanded.add(key);\n }\n return newExpanded;\n}\n\n/**\n * Expands all nodes in the tree.\n * Returns a Set of all parent row keys.\n */\nexport function expandAll(rows: any[], config: TreeConfig, parentKey: string | null = null, depth = 0): Set<string> {\n const childrenField = config.childrenField ?? 'children';\n const keys = new Set<string>();\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const key = generateRowKey(row, i, parentKey);\n const children = row[childrenField];\n\n if (Array.isArray(children) && children.length > 0) {\n keys.add(key);\n const childKeys = expandAll(children, config, key, depth + 1);\n for (const k of childKeys) keys.add(k);\n }\n }\n\n return keys;\n}\n\n/**\n * Collapses all nodes.\n * Returns an empty Set.\n */\nexport function collapseAll(): Set<string> {\n return new Set();\n}\n\n/**\n * Gets all descendants of a node from the flattened row list.\n * Useful for operations that need to affect an entire subtree.\n */\nexport function getDescendants(flattenedRows: FlattenedTreeRow[], parentKey: string): FlattenedTreeRow[] {\n const descendants: FlattenedTreeRow[] = [];\n let collecting = false;\n let parentDepth = -1;\n\n for (const row of flattenedRows) {\n if (row.key === parentKey) {\n collecting = true;\n parentDepth = row.depth;\n continue;\n }\n\n if (collecting) {\n if (row.depth > parentDepth) {\n descendants.push(row);\n } else {\n break; // No longer a descendant\n }\n }\n }\n\n return descendants;\n}\n\n/**\n * Finds the path from root to a specific row key.\n * Returns an array of keys from root to the target (inclusive).\n */\nexport function getPathToKey(\n rows: any[],\n targetKey: string,\n config: TreeConfig,\n parentKey: string | null = null,\n depth = 0\n): string[] | null {\n const childrenField = config.childrenField ?? 'children';\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const key = generateRowKey(row, i, parentKey);\n\n if (key === targetKey) {\n return [key];\n }\n\n const children = row[childrenField];\n if (Array.isArray(children) && children.length > 0) {\n const childPath = getPathToKey(children, targetKey, config, key, depth + 1);\n if (childPath) {\n return [key, ...childPath];\n }\n }\n }\n\n return null;\n}\n\n/**\n * Expands all ancestors of a specific row to make it visible.\n * Returns a new Set with the required keys added.\n */\nexport function expandToKey(\n rows: any[],\n targetKey: string,\n config: TreeConfig,\n existingExpanded: Set<string>\n): Set<string> {\n const path = getPathToKey(rows, targetKey, config);\n if (!path) return existingExpanded;\n\n const newExpanded = new Set(existingExpanded);\n // Add all keys except the last one (the target itself)\n for (let i = 0; i < path.length - 1; i++) {\n newExpanded.add(path[i]);\n }\n return newExpanded;\n}\n","/**\n * Tree Structure Auto-Detection\n *\n * Utilities for detecting hierarchical tree data structures.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// The tree plugin intentionally uses `any` for maximum flexibility with user-defined row types.\n\n/**\n * Detects if the data has a tree structure by checking for children arrays.\n */\nexport function detectTreeStructure(rows: any[], childrenField = 'children'): boolean {\n if (!Array.isArray(rows) || rows.length === 0) return false;\n\n // Check if any row has a non-empty children array\n for (const row of rows) {\n if (row && Array.isArray(row[childrenField]) && row[childrenField].length > 0) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Attempts to infer the children field name from common patterns.\n * Returns the first field that contains an array with items.\n */\nexport function inferChildrenField(rows: any[]): string | null {\n if (!Array.isArray(rows) || rows.length === 0) return null;\n\n const commonArrayFields = ['children', 'items', 'nodes', 'subRows', 'nested'];\n\n for (const row of rows) {\n if (!row || typeof row !== 'object') continue;\n\n for (const field of commonArrayFields) {\n if (Array.isArray(row[field]) && row[field].length > 0) {\n return field;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Calculates the maximum depth of the tree.\n * Useful for layout calculations and virtualization.\n */\nexport function getMaxDepth(rows: any[], childrenField = 'children', currentDepth = 0): number {\n if (!Array.isArray(rows) || rows.length === 0) return currentDepth;\n\n let maxDepth = currentDepth;\n\n for (const row of rows) {\n if (!row) continue;\n const children = row[childrenField];\n if (Array.isArray(children) && children.length > 0) {\n const childDepth = getMaxDepth(children, childrenField, currentDepth + 1);\n if (childDepth > maxDepth) {\n maxDepth = childDepth;\n }\n }\n }\n\n return maxDepth;\n}\n\n/**\n * Counts total nodes in the tree (including all descendants).\n */\nexport function countNodes(rows: any[], childrenField = 'children'): number {\n if (!Array.isArray(rows)) return 0;\n\n let count = 0;\n for (const row of rows) {\n if (!row) continue;\n count++;\n const children = row[childrenField];\n if (Array.isArray(children)) {\n count += countNodes(children, childrenField);\n }\n }\n\n return count;\n}\n","/**\n * Tree Data Plugin\n *\n * Enables hierarchical tree data with expand/collapse, sorting, and auto-detection.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { BaseGridPlugin, CellClickEvent, HeaderClickEvent } from '../../core/plugin/base-plugin';\nimport type { ColumnConfig, GridConfig } from '../../core/types';\nimport { collapseAll, expandAll, expandToKey, toggleExpand } from './tree-data';\nimport { detectTreeStructure, inferChildrenField } from './tree-detect';\nimport styles from './tree.css?inline';\nimport type { ExpandCollapseAnimation, FlattenedTreeRow, TreeConfig, TreeExpandDetail } from './types';\n\ninterface GridWithConfig {\n effectiveConfig?: GridConfig;\n _sortState?: { field: string; direction: 1 | -1 } | null;\n}\n\n/**\n * Tree Data Plugin for tbw-grid\n *\n * @example\n * ```ts\n * new TreePlugin({ defaultExpanded: true, indentWidth: 24 })\n * ```\n */\nexport class TreePlugin extends BaseGridPlugin<TreeConfig> {\n readonly name = 'tree';\n override readonly version = '1.0.0';\n override readonly styles = styles;\n\n protected override get defaultConfig(): Partial<TreeConfig> {\n return {\n childrenField: 'children',\n autoDetect: true,\n defaultExpanded: false,\n indentWidth: 20,\n showExpandIcons: true,\n animation: 'slide',\n };\n }\n\n // #region State\n\n private expandedKeys = new Set<string>();\n private initialExpansionDone = false;\n private flattenedRows: FlattenedTreeRow[] = [];\n private rowKeyMap = new Map<string, FlattenedTreeRow>();\n private previousVisibleKeys = new Set<string>();\n private keysToAnimate = new Set<string>();\n private sortState: { field: string; direction: 1 | -1 } | null = null;\n\n override detach(): void {\n this.expandedKeys.clear();\n this.initialExpansionDone = false;\n this.flattenedRows = [];\n this.rowKeyMap.clear();\n this.previousVisibleKeys.clear();\n this.keysToAnimate.clear();\n this.sortState = null;\n }\n\n // #endregion\n\n // #region Animation\n\n private get animationStyle(): ExpandCollapseAnimation {\n const gridEl = this.grid as unknown as GridWithConfig;\n const mode = gridEl.effectiveConfig?.animation?.mode ?? 'reduced-motion';\n\n if (mode === false || mode === 'off') return false;\n if (mode !== true && mode !== 'on') {\n const host = this.shadowRoot?.host as HTMLElement | undefined;\n if (host && getComputedStyle(host).getPropertyValue('--tbw-animation-enabled').trim() === '0') {\n return false;\n }\n }\n return this.config.animation ?? 'slide';\n }\n\n // #endregion\n\n // #region Auto-Detection\n\n detect(rows: readonly unknown[]): boolean {\n if (!this.config.autoDetect) return false;\n const field = this.config.childrenField ?? inferChildrenField(rows as any[]) ?? 'children';\n return detectTreeStructure(rows as any[], field);\n }\n\n // #endregion\n\n // #region Data Processing\n\n override processRows(rows: readonly unknown[]): any[] {\n const childrenField = this.config.childrenField ?? 'children';\n\n if (!detectTreeStructure(rows as any[], childrenField)) {\n this.flattenedRows = [];\n this.rowKeyMap.clear();\n this.previousVisibleKeys.clear();\n return [...rows];\n }\n\n // Assign stable keys, then optionally sort\n let data = this.withStableKeys(rows as any[]);\n if (this.sortState) {\n data = this.sortTree(data, this.sortState.field, this.sortState.direction);\n }\n\n // Initialize expansion if needed\n if (this.config.defaultExpanded && !this.initialExpansionDone) {\n this.expandedKeys = expandAll(data, this.config);\n this.initialExpansionDone = true;\n }\n\n // Flatten and track animations\n this.flattenedRows = this.flattenTree(data, this.expandedKeys);\n this.rowKeyMap.clear();\n this.keysToAnimate.clear();\n const currentKeys = new Set<string>();\n\n for (const row of this.flattenedRows) {\n this.rowKeyMap.set(row.key, row);\n currentKeys.add(row.key);\n if (!this.previousVisibleKeys.has(row.key) && row.depth > 0) {\n this.keysToAnimate.add(row.key);\n }\n }\n this.previousVisibleKeys = currentKeys;\n\n return this.flattenedRows.map((r) => ({\n ...r.data,\n __treeKey: r.key,\n __treeDepth: r.depth,\n __treeHasChildren: r.hasChildren,\n __treeExpanded: r.isExpanded,\n }));\n }\n\n /** Assign stable keys to rows (preserves key across sort operations) */\n private withStableKeys(rows: any[], parentKey: string | null = null): any[] {\n const childrenField = this.config.childrenField ?? 'children';\n return rows.map((row, i) => {\n const key =\n row.id !== undefined ? String(row.id) : (row.__stableKey ?? (parentKey ? `${parentKey}-${i}` : String(i)));\n const children = row[childrenField];\n const hasChildren = Array.isArray(children) && children.length > 0;\n return {\n ...row,\n __stableKey: key,\n ...(hasChildren ? { [childrenField]: this.withStableKeys(children, key) } : {}),\n };\n });\n }\n\n /** Flatten tree using stable keys */\n private flattenTree(rows: any[], expanded: Set<string>, depth = 0): FlattenedTreeRow[] {\n const childrenField = this.config.childrenField ?? 'children';\n const result: FlattenedTreeRow[] = [];\n\n for (const row of rows) {\n const key = row.__stableKey ?? row.id ?? '?';\n const children = row[childrenField];\n const hasChildren = Array.isArray(children) && children.length > 0;\n const isExpanded = expanded.has(key);\n\n result.push({\n key,\n data: row,\n depth,\n hasChildren,\n isExpanded,\n parentKey: depth > 0 ? key.substring(0, key.lastIndexOf('-')) || null : null,\n });\n\n if (hasChildren && isExpanded) {\n result.push(...this.flattenTree(children, expanded, depth + 1));\n }\n }\n return result;\n }\n\n /** Sort tree recursively, keeping children with parents */\n private sortTree(rows: any[], field: string, dir: 1 | -1): any[] {\n const childrenField = this.config.childrenField ?? 'children';\n const sorted = [...rows].sort((a, b) => {\n const aVal = a[field],\n bVal = b[field];\n if (aVal == null && bVal == null) return 0;\n if (aVal == null) return -1;\n if (bVal == null) return 1;\n return aVal > bVal ? dir : aVal < bVal ? -dir : 0;\n });\n return sorted.map((row) => {\n const children = row[childrenField];\n return Array.isArray(children) && children.length > 0\n ? { ...row, [childrenField]: this.sortTree(children, field, dir) }\n : row;\n });\n }\n\n override processColumns(columns: readonly ColumnConfig[]): ColumnConfig[] {\n if (this.flattenedRows.length === 0) return [...columns];\n\n const cols = [...columns] as ColumnConfig[];\n if (cols.length === 0) return cols;\n\n const firstCol = { ...cols[0] };\n const original = firstCol.viewRenderer;\n if ((original as any)?.__treeWrapped) return cols;\n\n const getConfig = () => this.config;\n const setIcon = this.setIcon.bind(this);\n const resolveIcon = this.resolveIcon.bind(this);\n\n const wrapped = (ctx: Parameters<NonNullable<typeof original>>[0]) => {\n const { value, row } = ctx;\n const { indentWidth = 20, showExpandIcons = true } = getConfig();\n\n const container = document.createElement('span');\n container.className = 'tree-cell';\n container.style.setProperty('--tree-depth', String(row.__treeDepth ?? 0));\n container.style.setProperty('--tbw-tree-indent', `${indentWidth}px`);\n\n if (row.__treeHasChildren && showExpandIcons) {\n const icon = document.createElement('span');\n icon.className = `tree-toggle${row.__treeExpanded ? ' expanded' : ''}`;\n setIcon(icon, resolveIcon(row.__treeExpanded ? 'collapse' : 'expand'));\n icon.setAttribute('data-tree-key', row.__treeKey);\n container.appendChild(icon);\n } else if (showExpandIcons) {\n const spacer = document.createElement('span');\n spacer.className = 'tree-spacer';\n container.appendChild(spacer);\n }\n\n const content = document.createElement('span');\n if (original) {\n const rendered = original(ctx);\n if (rendered instanceof Node) {\n content.appendChild(rendered);\n } else {\n content.textContent = String(rendered ?? value ?? '');\n }\n } else {\n content.textContent = String(value ?? '');\n }\n container.appendChild(content);\n return container;\n };\n\n (wrapped as any).__treeWrapped = true;\n firstCol.viewRenderer = wrapped;\n cols[0] = firstCol;\n return cols;\n }\n\n // #endregion\n\n // #region Event Handlers\n\n override onCellClick(event: CellClickEvent): boolean {\n const target = event.originalEvent?.target as HTMLElement;\n if (!target?.classList.contains('tree-toggle')) return false;\n\n const key = target.getAttribute('data-tree-key');\n const flatRow = key ? this.rowKeyMap.get(key) : null;\n if (!flatRow) return false;\n\n this.expandedKeys = toggleExpand(this.expandedKeys, key!);\n this.emit<TreeExpandDetail>('tree-expand', {\n key: key!,\n row: flatRow.data,\n expanded: this.expandedKeys.has(key!),\n depth: flatRow.depth,\n });\n this.requestRender();\n return true;\n }\n\n override onHeaderClick(event: HeaderClickEvent): boolean {\n if (this.flattenedRows.length === 0 || !event.column.sortable) return false;\n\n const { field } = event.column;\n if (!this.sortState || this.sortState.field !== field) {\n this.sortState = { field, direction: 1 };\n } else if (this.sortState.direction === 1) {\n this.sortState = { field, direction: -1 };\n } else {\n this.sortState = null;\n }\n\n // Sync grid sort indicator\n const gridEl = this.grid as unknown as GridWithConfig;\n if (gridEl._sortState !== undefined) {\n gridEl._sortState = this.sortState ? { ...this.sortState } : null;\n }\n\n this.emit('sort-change', { field, direction: this.sortState?.direction ?? 0 });\n this.requestRender();\n return true;\n }\n\n override afterRender(): void {\n const style = this.animationStyle;\n if (style === false || this.keysToAnimate.size === 0) return;\n\n const body = this.shadowRoot?.querySelector('.rows');\n if (!body) return;\n\n const animClass = style === 'fade' ? 'tbw-tree-fade-in' : 'tbw-tree-slide-in';\n for (const rowEl of body.querySelectorAll('.data-grid-row')) {\n const cell = rowEl.querySelector('.cell[data-row]');\n const idx = cell ? parseInt(cell.getAttribute('data-row') ?? '-1', 10) : -1;\n const key = this.flattenedRows[idx]?.key;\n\n if (key && this.keysToAnimate.has(key)) {\n rowEl.classList.add(animClass);\n rowEl.addEventListener('animationend', () => rowEl.classList.remove(animClass), { once: true });\n }\n }\n this.keysToAnimate.clear();\n }\n\n // #endregion\n\n // #region Public API\n\n expand(key: string): void {\n this.expandedKeys.add(key);\n this.requestRender();\n }\n\n collapse(key: string): void {\n this.expandedKeys.delete(key);\n this.requestRender();\n }\n\n toggle(key: string): void {\n this.expandedKeys = toggleExpand(this.expandedKeys, key);\n this.requestRender();\n }\n\n expandAll(): void {\n this.expandedKeys = expandAll(this.rows as any[], this.config);\n this.requestRender();\n }\n\n collapseAll(): void {\n this.expandedKeys = collapseAll();\n this.requestRender();\n }\n\n isExpanded(key: string): boolean {\n return this.expandedKeys.has(key);\n }\n\n getExpandedKeys(): string[] {\n return [...this.expandedKeys];\n }\n\n getFlattenedRows(): FlattenedTreeRow[] {\n return [...this.flattenedRows];\n }\n\n getRowByKey(key: string): any | undefined {\n return this.rowKeyMap.get(key)?.data;\n }\n\n expandToKey(key: string): void {\n this.expandedKeys = expandToKey(this.rows as any[], key, this.config, this.expandedKeys);\n this.requestRender();\n }\n\n // #endregion\n}\n"],"names":["generateRowKey","row","index","parentKey","toggleExpand","expandedKeys","key","newExpanded","expandAll","rows","config","depth","childrenField","keys","i","children","childKeys","k","collapseAll","getPathToKey","targetKey","childPath","expandToKey","existingExpanded","path","detectTreeStructure","inferChildrenField","commonArrayFields","field","getMaxDepth","currentDepth","maxDepth","childDepth","countNodes","count","TreePlugin","BaseGridPlugin","styles","mode","host","data","currentKeys","hasChildren","expanded","result","isExpanded","dir","a","b","aVal","bVal","columns","cols","firstCol","original","getConfig","setIcon","resolveIcon","wrapped","ctx","value","indentWidth","showExpandIcons","container","icon","spacer","content","rendered","event","target","flatRow","gridEl","style","body","animClass","rowEl","cell","idx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tree.umd.js","sources":["../../../../../libs/grid/src/lib/plugins/tree/tree-data.ts","../../../../../libs/grid/src/lib/plugins/tree/tree-detect.ts","../../../../../libs/grid/src/lib/plugins/tree/TreePlugin.ts"],"sourcesContent":["/**\n * Core Tree Data Logic\n *\n * Pure functions for tree flattening, expansion, and traversal.\n */\n\nimport type { FlattenedTreeRow, TreeConfig, TreeRow } from './types';\n\n/**\n * Generates a unique key for a row.\n * Uses row.id if available, otherwise generates from path.\n */\nexport function generateRowKey(row: TreeRow, index: number, parentKey: string | null): string {\n if (row.id !== undefined) return String(row.id);\n return parentKey ? `${parentKey}-${index}` : String(index);\n}\n\n/**\n * Flattens a hierarchical tree into a flat array of rows with metadata.\n * Only includes children of expanded nodes.\n */\nexport function flattenTree(\n rows: readonly TreeRow[],\n config: TreeConfig,\n expandedKeys: Set<string>,\n parentKey: string | null = null,\n depth = 0,\n): FlattenedTreeRow[] {\n const childrenField = config.childrenField ?? 'children';\n const result: FlattenedTreeRow[] = [];\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const key = generateRowKey(row, i, parentKey);\n const children = row[childrenField];\n const hasChildren = Array.isArray(children) && children.length > 0;\n const isExpanded = expandedKeys.has(key);\n\n result.push({\n key,\n data: row,\n depth,\n hasChildren,\n isExpanded,\n parentKey,\n });\n\n // Recursively add children if expanded\n if (hasChildren && isExpanded) {\n const childRows = flattenTree(children as TreeRow[], config, expandedKeys, key, depth + 1);\n result.push(...childRows);\n }\n }\n\n return result;\n}\n\n/**\n * Toggles the expansion state of a row.\n * Returns a new Set with the toggled state.\n */\nexport function toggleExpand(expandedKeys: Set<string>, key: string): Set<string> {\n const newExpanded = new Set(expandedKeys);\n if (newExpanded.has(key)) {\n newExpanded.delete(key);\n } else {\n newExpanded.add(key);\n }\n return newExpanded;\n}\n\n/**\n * Expands all nodes in the tree.\n * Returns a Set of all parent row keys.\n */\nexport function expandAll(\n rows: readonly TreeRow[],\n config: TreeConfig,\n parentKey: string | null = null,\n depth = 0,\n): Set<string> {\n const childrenField = config.childrenField ?? 'children';\n const keys = new Set<string>();\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const key = generateRowKey(row, i, parentKey);\n const children = row[childrenField];\n\n if (Array.isArray(children) && children.length > 0) {\n keys.add(key);\n const childKeys = expandAll(children as TreeRow[], config, key, depth + 1);\n for (const k of childKeys) keys.add(k);\n }\n }\n\n return keys;\n}\n\n/**\n * Collapses all nodes.\n * Returns an empty Set.\n */\nexport function collapseAll(): Set<string> {\n return new Set();\n}\n\n/**\n * Gets all descendants of a node from the flattened row list.\n * Useful for operations that need to affect an entire subtree.\n */\nexport function getDescendants(flattenedRows: FlattenedTreeRow[], parentKey: string): FlattenedTreeRow[] {\n const descendants: FlattenedTreeRow[] = [];\n let collecting = false;\n let parentDepth = -1;\n\n for (const row of flattenedRows) {\n if (row.key === parentKey) {\n collecting = true;\n parentDepth = row.depth;\n continue;\n }\n\n if (collecting) {\n if (row.depth > parentDepth) {\n descendants.push(row);\n } else {\n break; // No longer a descendant\n }\n }\n }\n\n return descendants;\n}\n\n/**\n * Finds the path from root to a specific row key.\n * Returns an array of keys from root to the target (inclusive).\n */\nexport function getPathToKey(\n rows: readonly TreeRow[],\n targetKey: string,\n config: TreeConfig,\n parentKey: string | null = null,\n depth = 0,\n): string[] | null {\n const childrenField = config.childrenField ?? 'children';\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const key = generateRowKey(row, i, parentKey);\n\n if (key === targetKey) {\n return [key];\n }\n\n const children = row[childrenField];\n if (Array.isArray(children) && children.length > 0) {\n const childPath = getPathToKey(children as TreeRow[], targetKey, config, key, depth + 1);\n if (childPath) {\n return [key, ...childPath];\n }\n }\n }\n\n return null;\n}\n\n/**\n * Expands all ancestors of a specific row to make it visible.\n * Returns a new Set with the required keys added.\n */\nexport function expandToKey(\n rows: readonly TreeRow[],\n targetKey: string,\n config: TreeConfig,\n existingExpanded: Set<string>,\n): Set<string> {\n const path = getPathToKey(rows, targetKey, config);\n if (!path) return existingExpanded;\n\n const newExpanded = new Set(existingExpanded);\n // Add all keys except the last one (the target itself)\n for (let i = 0; i < path.length - 1; i++) {\n newExpanded.add(path[i]);\n }\n return newExpanded;\n}\n","/**\n * Tree Structure Auto-Detection\n *\n * Utilities for detecting hierarchical tree data structures.\n */\n\nimport type { TreeRow } from './types';\n\n/**\n * Detects if the data has a tree structure by checking for children arrays.\n */\nexport function detectTreeStructure(rows: readonly TreeRow[], childrenField = 'children'): boolean {\n if (!Array.isArray(rows) || rows.length === 0) return false;\n\n // Check if any row has a non-empty children array\n for (const row of rows) {\n if (!row) continue;\n const children = row[childrenField];\n if (Array.isArray(children) && children.length > 0) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Attempts to infer the children field name from common patterns.\n * Returns the first field that contains an array with items.\n */\nexport function inferChildrenField(rows: readonly TreeRow[]): string | null {\n if (!Array.isArray(rows) || rows.length === 0) return null;\n\n const commonArrayFields = ['children', 'items', 'nodes', 'subRows', 'nested'];\n\n for (const row of rows) {\n if (!row || typeof row !== 'object') continue;\n\n for (const field of commonArrayFields) {\n const value = row[field];\n if (Array.isArray(value) && value.length > 0) {\n return field;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Calculates the maximum depth of the tree.\n * Useful for layout calculations and virtualization.\n */\nexport function getMaxDepth(rows: readonly TreeRow[], childrenField = 'children', currentDepth = 0): number {\n if (!Array.isArray(rows) || rows.length === 0) return currentDepth;\n\n let maxDepth = currentDepth;\n\n for (const row of rows) {\n if (!row) continue;\n const children = row[childrenField];\n if (Array.isArray(children) && children.length > 0) {\n const childDepth = getMaxDepth(children as TreeRow[], childrenField, currentDepth + 1);\n if (childDepth > maxDepth) {\n maxDepth = childDepth;\n }\n }\n }\n\n return maxDepth;\n}\n\n/**\n * Counts total nodes in the tree (including all descendants).\n */\nexport function countNodes(rows: readonly TreeRow[], childrenField = 'children'): number {\n if (!Array.isArray(rows)) return 0;\n\n let count = 0;\n for (const row of rows) {\n if (!row) continue;\n count++;\n const children = row[childrenField];\n if (Array.isArray(children)) {\n count += countNodes(children as TreeRow[], childrenField);\n }\n }\n\n return count;\n}\n","/**\n * Tree Data Plugin\n *\n * Enables hierarchical tree data with expand/collapse, sorting, and auto-detection.\n */\n\nimport { BaseGridPlugin, CellClickEvent, HeaderClickEvent } from '../../core/plugin/base-plugin';\nimport type { ColumnConfig, GridConfig } from '../../core/types';\nimport { collapseAll, expandAll, expandToKey, toggleExpand } from './tree-data';\nimport { detectTreeStructure, inferChildrenField } from './tree-detect';\nimport styles from './tree.css?inline';\nimport type {\n ExpandCollapseAnimation,\n FlattenedTreeRow,\n TreeConfig,\n TreeExpandDetail,\n TreeRow,\n TreeWrappedRenderer,\n} from './types';\n\ninterface GridWithConfig {\n effectiveConfig?: GridConfig;\n _sortState?: { field: string; direction: 1 | -1 } | null;\n}\n\n/**\n * Tree Data Plugin for tbw-grid\n *\n * @example\n * ```ts\n * new TreePlugin({ defaultExpanded: true, indentWidth: 24 })\n * ```\n */\nexport class TreePlugin extends BaseGridPlugin<TreeConfig> {\n readonly name = 'tree';\n override readonly version = '1.0.0';\n override readonly styles = styles;\n\n protected override get defaultConfig(): Partial<TreeConfig> {\n return {\n childrenField: 'children',\n autoDetect: true,\n defaultExpanded: false,\n indentWidth: 20,\n showExpandIcons: true,\n animation: 'slide',\n };\n }\n\n // #region State\n\n private expandedKeys = new Set<string>();\n private initialExpansionDone = false;\n private flattenedRows: FlattenedTreeRow[] = [];\n private rowKeyMap = new Map<string, FlattenedTreeRow>();\n private previousVisibleKeys = new Set<string>();\n private keysToAnimate = new Set<string>();\n private sortState: { field: string; direction: 1 | -1 } | null = null;\n\n override detach(): void {\n this.expandedKeys.clear();\n this.initialExpansionDone = false;\n this.flattenedRows = [];\n this.rowKeyMap.clear();\n this.previousVisibleKeys.clear();\n this.keysToAnimate.clear();\n this.sortState = null;\n }\n\n // #endregion\n\n // #region Animation\n\n private get animationStyle(): ExpandCollapseAnimation {\n const gridEl = this.grid as unknown as GridWithConfig;\n const mode = gridEl.effectiveConfig?.animation?.mode ?? 'reduced-motion';\n\n if (mode === false || mode === 'off') return false;\n if (mode !== true && mode !== 'on') {\n const host = this.shadowRoot?.host as HTMLElement | undefined;\n if (host && getComputedStyle(host).getPropertyValue('--tbw-animation-enabled').trim() === '0') {\n return false;\n }\n }\n return this.config.animation ?? 'slide';\n }\n\n // #endregion\n\n // #region Auto-Detection\n\n detect(rows: readonly unknown[]): boolean {\n if (!this.config.autoDetect) return false;\n const treeRows = rows as readonly TreeRow[];\n const field = this.config.childrenField ?? inferChildrenField(treeRows) ?? 'children';\n return detectTreeStructure(treeRows, field);\n }\n\n // #endregion\n\n // #region Data Processing\n\n override processRows(rows: readonly unknown[]): TreeRow[] {\n const childrenField = this.config.childrenField ?? 'children';\n const treeRows = rows as readonly TreeRow[];\n\n if (!detectTreeStructure(treeRows, childrenField)) {\n this.flattenedRows = [];\n this.rowKeyMap.clear();\n this.previousVisibleKeys.clear();\n return [...rows] as TreeRow[];\n }\n\n // Assign stable keys, then optionally sort\n let data = this.withStableKeys(treeRows);\n if (this.sortState) {\n data = this.sortTree(data, this.sortState.field, this.sortState.direction);\n }\n\n // Initialize expansion if needed\n if (this.config.defaultExpanded && !this.initialExpansionDone) {\n this.expandedKeys = expandAll(data, this.config);\n this.initialExpansionDone = true;\n }\n\n // Flatten and track animations\n this.flattenedRows = this.flattenTree(data, this.expandedKeys);\n this.rowKeyMap.clear();\n this.keysToAnimate.clear();\n const currentKeys = new Set<string>();\n\n for (const row of this.flattenedRows) {\n this.rowKeyMap.set(row.key, row);\n currentKeys.add(row.key);\n if (!this.previousVisibleKeys.has(row.key) && row.depth > 0) {\n this.keysToAnimate.add(row.key);\n }\n }\n this.previousVisibleKeys = currentKeys;\n\n return this.flattenedRows.map((r) => ({\n ...r.data,\n __treeKey: r.key,\n __treeDepth: r.depth,\n __treeHasChildren: r.hasChildren,\n __treeExpanded: r.isExpanded,\n }));\n }\n\n /** Assign stable keys to rows (preserves key across sort operations) */\n private withStableKeys(rows: readonly TreeRow[], parentKey: string | null = null): TreeRow[] {\n const childrenField = this.config.childrenField ?? 'children';\n return rows.map((row, i) => {\n const stableKey = row.__stableKey as string | undefined;\n const key = row.id !== undefined ? String(row.id) : (stableKey ?? (parentKey ? `${parentKey}-${i}` : String(i)));\n const children = row[childrenField];\n const hasChildren = Array.isArray(children) && children.length > 0;\n return {\n ...row,\n __stableKey: key,\n ...(hasChildren ? { [childrenField]: this.withStableKeys(children as TreeRow[], key) } : {}),\n };\n });\n }\n\n /** Flatten tree using stable keys */\n private flattenTree(rows: readonly TreeRow[], expanded: Set<string>, depth = 0): FlattenedTreeRow[] {\n const childrenField = this.config.childrenField ?? 'children';\n const result: FlattenedTreeRow[] = [];\n\n for (const row of rows) {\n const stableKey = row.__stableKey as string | undefined;\n const key = stableKey ?? String(row.id ?? '?');\n const children = row[childrenField];\n const hasChildren = Array.isArray(children) && children.length > 0;\n const isExpanded = expanded.has(key);\n\n result.push({\n key,\n data: row,\n depth,\n hasChildren,\n isExpanded,\n parentKey: depth > 0 ? key.substring(0, key.lastIndexOf('-')) || null : null,\n });\n\n if (hasChildren && isExpanded) {\n result.push(...this.flattenTree(children as TreeRow[], expanded, depth + 1));\n }\n }\n return result;\n }\n\n /** Sort tree recursively, keeping children with parents */\n private sortTree(rows: readonly TreeRow[], field: string, dir: 1 | -1): TreeRow[] {\n const childrenField = this.config.childrenField ?? 'children';\n const sorted = [...rows].sort((a, b) => {\n const aVal = a[field],\n bVal = b[field];\n if (aVal == null && bVal == null) return 0;\n if (aVal == null) return -1;\n if (bVal == null) return 1;\n return aVal > bVal ? dir : aVal < bVal ? -dir : 0;\n });\n return sorted.map((row) => {\n const children = row[childrenField];\n return Array.isArray(children) && children.length > 0\n ? { ...row, [childrenField]: this.sortTree(children as TreeRow[], field, dir) }\n : row;\n });\n }\n\n override processColumns(columns: readonly ColumnConfig[]): ColumnConfig[] {\n if (this.flattenedRows.length === 0) return [...columns];\n\n const cols = [...columns] as ColumnConfig[];\n if (cols.length === 0) return cols;\n\n const firstCol = { ...cols[0] };\n const original = firstCol.viewRenderer as TreeWrappedRenderer | undefined;\n if (original?.__treeWrapped) return cols;\n\n const getConfig = () => this.config;\n const setIcon = this.setIcon.bind(this);\n const resolveIcon = this.resolveIcon.bind(this);\n\n const wrapped: TreeWrappedRenderer = (ctx) => {\n const { value, row } = ctx;\n const { indentWidth = 20, showExpandIcons = true } = getConfig();\n const treeRow = row as TreeRow;\n\n const container = document.createElement('span');\n container.className = 'tree-cell';\n container.style.setProperty('--tree-depth', String(treeRow.__treeDepth ?? 0));\n container.style.setProperty('--tbw-tree-indent', `${indentWidth}px`);\n\n if (treeRow.__treeHasChildren && showExpandIcons) {\n const icon = document.createElement('span');\n icon.className = `tree-toggle${treeRow.__treeExpanded ? ' expanded' : ''}`;\n setIcon(icon, resolveIcon(treeRow.__treeExpanded ? 'collapse' : 'expand'));\n icon.setAttribute('data-tree-key', String(treeRow.__treeKey ?? ''));\n container.appendChild(icon);\n } else if (showExpandIcons) {\n const spacer = document.createElement('span');\n spacer.className = 'tree-spacer';\n container.appendChild(spacer);\n }\n\n const content = document.createElement('span');\n if (original) {\n const rendered = original(ctx);\n if (rendered instanceof Node) {\n content.appendChild(rendered);\n } else {\n content.textContent = String(rendered ?? value ?? '');\n }\n } else {\n content.textContent = String(value ?? '');\n }\n container.appendChild(content);\n return container;\n };\n\n wrapped.__treeWrapped = true;\n firstCol.viewRenderer = wrapped;\n cols[0] = firstCol;\n return cols;\n }\n\n // #endregion\n\n // #region Event Handlers\n\n override onCellClick(event: CellClickEvent): boolean {\n const target = event.originalEvent?.target as HTMLElement;\n if (!target?.classList.contains('tree-toggle')) return false;\n\n const key = target.getAttribute('data-tree-key');\n const flatRow = key ? this.rowKeyMap.get(key) : null;\n if (!flatRow) return false;\n\n this.expandedKeys = toggleExpand(this.expandedKeys, key!);\n this.emit<TreeExpandDetail>('tree-expand', {\n key: key!,\n row: flatRow.data,\n expanded: this.expandedKeys.has(key!),\n depth: flatRow.depth,\n });\n this.requestRender();\n return true;\n }\n\n override onHeaderClick(event: HeaderClickEvent): boolean {\n if (this.flattenedRows.length === 0 || !event.column.sortable) return false;\n\n const { field } = event.column;\n if (!this.sortState || this.sortState.field !== field) {\n this.sortState = { field, direction: 1 };\n } else if (this.sortState.direction === 1) {\n this.sortState = { field, direction: -1 };\n } else {\n this.sortState = null;\n }\n\n // Sync grid sort indicator\n const gridEl = this.grid as unknown as GridWithConfig;\n if (gridEl._sortState !== undefined) {\n gridEl._sortState = this.sortState ? { ...this.sortState } : null;\n }\n\n this.emit('sort-change', { field, direction: this.sortState?.direction ?? 0 });\n this.requestRender();\n return true;\n }\n\n override afterRender(): void {\n const style = this.animationStyle;\n if (style === false || this.keysToAnimate.size === 0) return;\n\n const body = this.shadowRoot?.querySelector('.rows');\n if (!body) return;\n\n const animClass = style === 'fade' ? 'tbw-tree-fade-in' : 'tbw-tree-slide-in';\n for (const rowEl of body.querySelectorAll('.data-grid-row')) {\n const cell = rowEl.querySelector('.cell[data-row]');\n const idx = cell ? parseInt(cell.getAttribute('data-row') ?? '-1', 10) : -1;\n const key = this.flattenedRows[idx]?.key;\n\n if (key && this.keysToAnimate.has(key)) {\n rowEl.classList.add(animClass);\n rowEl.addEventListener('animationend', () => rowEl.classList.remove(animClass), { once: true });\n }\n }\n this.keysToAnimate.clear();\n }\n\n // #endregion\n\n // #region Public API\n\n expand(key: string): void {\n this.expandedKeys.add(key);\n this.requestRender();\n }\n\n collapse(key: string): void {\n this.expandedKeys.delete(key);\n this.requestRender();\n }\n\n toggle(key: string): void {\n this.expandedKeys = toggleExpand(this.expandedKeys, key);\n this.requestRender();\n }\n\n expandAll(): void {\n this.expandedKeys = expandAll(this.rows as TreeRow[], this.config);\n this.requestRender();\n }\n\n collapseAll(): void {\n this.expandedKeys = collapseAll();\n this.requestRender();\n }\n\n isExpanded(key: string): boolean {\n return this.expandedKeys.has(key);\n }\n\n getExpandedKeys(): string[] {\n return [...this.expandedKeys];\n }\n\n getFlattenedRows(): FlattenedTreeRow[] {\n return [...this.flattenedRows];\n }\n\n getRowByKey(key: string): TreeRow | undefined {\n return this.rowKeyMap.get(key)?.data;\n }\n\n expandToKey(key: string): void {\n this.expandedKeys = expandToKey(this.rows as TreeRow[], key, this.config, this.expandedKeys);\n this.requestRender();\n }\n\n // #endregion\n}\n"],"names":["generateRowKey","row","index","parentKey","toggleExpand","expandedKeys","key","newExpanded","expandAll","rows","config","depth","childrenField","keys","children","childKeys","k","collapseAll","getPathToKey","targetKey","childPath","expandToKey","existingExpanded","path","detectTreeStructure","inferChildrenField","commonArrayFields","field","value","getMaxDepth","currentDepth","maxDepth","childDepth","countNodes","count","TreePlugin","BaseGridPlugin","styles","mode","host","treeRows","data","currentKeys","r","i","stableKey","hasChildren","expanded","result","isExpanded","dir","a","b","aVal","bVal","columns","cols","firstCol","original","getConfig","setIcon","resolveIcon","wrapped","ctx","indentWidth","showExpandIcons","treeRow","container","icon","spacer","content","rendered","event","target","flatRow","gridEl","style","body","animClass","rowEl","cell","idx"],"mappings":"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"}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { BaseGridPlugin } from '../plugin';
|
|
2
|
-
import { ColumnConfig, GridColumnState, InternalGrid } from '../types';
|
|
3
|
-
/**
|
|
4
|
-
* Collect column state from the grid and all plugins.
|
|
5
|
-
* Returns a complete GridColumnState object ready for serialization.
|
|
6
|
-
*/
|
|
7
|
-
export declare function collectColumnState<T>(grid: InternalGrid<T>, plugins: BaseGridPlugin[]): GridColumnState;
|
|
8
|
-
/**
|
|
9
|
-
* Apply column state to the grid and all plugins.
|
|
10
|
-
* Modifies the grid's internal state and triggers plugin state restoration.
|
|
11
|
-
*
|
|
12
|
-
* @param grid - The grid instance
|
|
13
|
-
* @param state - The state to apply
|
|
14
|
-
* @param allColumns - All available columns (including hidden ones)
|
|
15
|
-
* @param plugins - Plugins that may have applyColumnState hooks
|
|
16
|
-
*/
|
|
17
|
-
export declare function applyColumnState<T>(grid: InternalGrid<T>, state: GridColumnState, allColumns: ColumnConfig<T>[], plugins: BaseGridPlugin[]): void;
|
|
18
|
-
/**
|
|
19
|
-
* Create a state change handler with debouncing.
|
|
20
|
-
* Returns a function that, when called, will eventually emit the state change event.
|
|
21
|
-
*/
|
|
22
|
-
export declare function createStateChangeHandler<T>(grid: InternalGrid<T>, getPlugins: () => BaseGridPlugin[], emit: (detail: GridColumnState) => void): () => void;
|
|
23
|
-
/**
|
|
24
|
-
* Compare two column states to check if they are equal.
|
|
25
|
-
* Useful for preventing duplicate state change events.
|
|
26
|
-
*/
|
|
27
|
-
export declare function areColumnStatesEqual(a: GridColumnState, b: GridColumnState): boolean;
|
|
28
|
-
/**
|
|
29
|
-
* State manager for a grid instance.
|
|
30
|
-
* Encapsulates the state change handler and initial state storage.
|
|
31
|
-
*/
|
|
32
|
-
export interface ColumnStateManager {
|
|
33
|
-
/** The initial state to apply after initialization */
|
|
34
|
-
initialState: GridColumnState | undefined;
|
|
35
|
-
/** Debounced state change handler */
|
|
36
|
-
stateChangeHandler: (() => void) | undefined;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Create a column state manager for a grid.
|
|
40
|
-
*/
|
|
41
|
-
export declare function createColumnStateManager(): ColumnStateManager;
|
|
42
|
-
/**
|
|
43
|
-
* Get the current column state from the grid.
|
|
44
|
-
* @param grid - The grid instance
|
|
45
|
-
* @param plugins - Array of attached plugins
|
|
46
|
-
* @returns Serializable column state object
|
|
47
|
-
*/
|
|
48
|
-
export declare function getGridColumnState<T>(grid: InternalGrid<T>, plugins: BaseGridPlugin[]): GridColumnState;
|
|
49
|
-
/**
|
|
50
|
-
* Set column state on a grid, storing for later if not yet initialized.
|
|
51
|
-
* @param grid - The grid instance
|
|
52
|
-
* @param state - The state to apply
|
|
53
|
-
* @param manager - The column state manager
|
|
54
|
-
* @param isInitialized - Whether the grid is initialized
|
|
55
|
-
* @param applyNow - Function to apply the state immediately
|
|
56
|
-
*/
|
|
57
|
-
export declare function setGridColumnState<T>(state: GridColumnState | undefined, manager: ColumnStateManager, isInitialized: boolean, applyNow: (state: GridColumnState) => void): void;
|
|
58
|
-
/**
|
|
59
|
-
* Request a state change event emission (debounced).
|
|
60
|
-
* @param grid - The grid instance
|
|
61
|
-
* @param manager - The column state manager
|
|
62
|
-
* @param getPlugins - Function to get attached plugins
|
|
63
|
-
* @param emit - Function to emit the event
|
|
64
|
-
*/
|
|
65
|
-
export declare function requestGridStateChange<T>(grid: InternalGrid<T>, manager: ColumnStateManager, getPlugins: () => BaseGridPlugin[], emit: (state: GridColumnState) => void): void;
|
|
66
|
-
/**
|
|
67
|
-
* Reset column state to initial configuration.
|
|
68
|
-
* @param grid - The grid instance
|
|
69
|
-
* @param manager - The column state manager
|
|
70
|
-
* @param plugins - Array of attached plugins
|
|
71
|
-
* @param callbacks - Grid callbacks for triggering updates
|
|
72
|
-
*/
|
|
73
|
-
export declare function resetGridColumnState<T>(grid: InternalGrid<T>, manager: ColumnStateManager, plugins: BaseGridPlugin[], callbacks: {
|
|
74
|
-
mergeEffectiveConfig: () => void;
|
|
75
|
-
setup: () => void;
|
|
76
|
-
requestStateChange: () => void;
|
|
77
|
-
}): void;
|
|
78
|
-
/** Callbacks for visibility changes that need grid integration */
|
|
79
|
-
export interface VisibilityCallbacks {
|
|
80
|
-
emit: (eventName: string, detail: unknown) => void;
|
|
81
|
-
clearRowPool: () => void;
|
|
82
|
-
setup: () => void;
|
|
83
|
-
requestStateChange: () => void;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Set the visibility of a column.
|
|
87
|
-
* @returns true if visibility changed, false otherwise
|
|
88
|
-
*/
|
|
89
|
-
export declare function setColumnVisible<T>(grid: InternalGrid<T>, field: string, visible: boolean, callbacks: VisibilityCallbacks): boolean;
|
|
90
|
-
/**
|
|
91
|
-
* Toggle column visibility.
|
|
92
|
-
* @returns true if toggled, false if column not found or locked
|
|
93
|
-
*/
|
|
94
|
-
export declare function toggleColumnVisibility<T>(grid: InternalGrid<T>, field: string, callbacks: VisibilityCallbacks): boolean;
|
|
95
|
-
/**
|
|
96
|
-
* Check if a column is visible.
|
|
97
|
-
*/
|
|
98
|
-
export declare function isColumnVisible<T>(grid: InternalGrid<T>, field: string): boolean;
|
|
99
|
-
/**
|
|
100
|
-
* Show all columns.
|
|
101
|
-
*/
|
|
102
|
-
export declare function showAllColumns<T>(grid: InternalGrid<T>, callbacks: VisibilityCallbacks): void;
|
|
103
|
-
/**
|
|
104
|
-
* Get all columns with visibility info.
|
|
105
|
-
*/
|
|
106
|
-
export declare function getAllColumns<T>(grid: InternalGrid<T>): Array<{
|
|
107
|
-
field: string;
|
|
108
|
-
header: string;
|
|
109
|
-
visible: boolean;
|
|
110
|
-
lockVisible?: boolean;
|
|
111
|
-
}>;
|
|
112
|
-
/**
|
|
113
|
-
* Get current column order.
|
|
114
|
-
*/
|
|
115
|
-
export declare function getColumnOrder<T>(grid: InternalGrid<T>): string[];
|
|
116
|
-
/**
|
|
117
|
-
* Set column order.
|
|
118
|
-
*/
|
|
119
|
-
export declare function setColumnOrder<T>(grid: InternalGrid<T>, order: string[], callbacks: {
|
|
120
|
-
renderHeader: () => void;
|
|
121
|
-
updateTemplate: () => void;
|
|
122
|
-
refreshVirtualWindow: () => void;
|
|
123
|
-
}): void;
|
|
124
|
-
//# sourceMappingURL=column-state.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"column-state.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/core/internal/column-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { ColumnConfig, InternalGrid } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* CSS selector for focusable editor elements within a cell.
|
|
4
|
-
* Used by multiple modules to find and focus the active editor.
|
|
5
|
-
*/
|
|
6
|
-
export declare const FOCUSABLE_EDITOR_SELECTOR = "input,select,textarea,[contenteditable=\"true\"],[contenteditable=\"\"],[tabindex]:not([tabindex=\"-1\"])";
|
|
7
|
-
/**
|
|
8
|
-
* Check if a row element has any cells in editing mode.
|
|
9
|
-
* Uses a cached count on the row element for O(1) lookup instead of querySelector.
|
|
10
|
-
*/
|
|
11
|
-
export declare function hasEditingCells(rowEl: HTMLElement): boolean;
|
|
12
|
-
/**
|
|
13
|
-
* Clear all editing state from a row element.
|
|
14
|
-
* Called when the row is recycled or fully re-rendered.
|
|
15
|
-
*/
|
|
16
|
-
export declare function clearEditingState(rowEl: HTMLElement): void;
|
|
17
|
-
/**
|
|
18
|
-
* Snapshot original row data and mark the row as actively being edited.
|
|
19
|
-
*/
|
|
20
|
-
export declare function startRowEdit(grid: InternalGrid, rowIndex: number, rowData: any): void;
|
|
21
|
-
/**
|
|
22
|
-
* Finish editing for a row. If `revert` is true restore original snapshot and clear change marks.
|
|
23
|
-
* Otherwise emit a row-commit event describing change status.
|
|
24
|
-
*/
|
|
25
|
-
export declare function exitRowEdit(grid: InternalGrid, rowIndex: number, revert: boolean): void;
|
|
26
|
-
/**
|
|
27
|
-
* Commit a single cell value change, updating the row object, marking the row as changed (first-time flag),
|
|
28
|
-
* and emitting a `cell-commit` event with row + field metadata.
|
|
29
|
-
*/
|
|
30
|
-
export declare function commitCellValue(grid: InternalGrid, rowIndex: number, column: ColumnConfig<any>, newValue: any, rowData: any): void;
|
|
31
|
-
/**
|
|
32
|
-
* Replace a cell's content with an editor resolved from column configuration (custom editor, template, external
|
|
33
|
-
* mount spec or default editor by type). Manages commit / cancel lifecycle and value restoration.
|
|
34
|
-
*
|
|
35
|
-
* @param skipFocus - When true, don't auto-focus the editor. Used when creating multiple editors
|
|
36
|
-
* at once (e.g., beginBulkEdit) so the caller can control focus.
|
|
37
|
-
*/
|
|
38
|
-
export declare function inlineEnterEdit(grid: InternalGrid, rowData: any, rowIndex: number, column: ColumnConfig<any>, cell: HTMLElement, skipFocus?: boolean): void;
|
|
39
|
-
/**
|
|
40
|
-
* Get all changed rows from the grid.
|
|
41
|
-
* @param grid - The grid instance
|
|
42
|
-
* @returns Array of changed row data objects
|
|
43
|
-
*/
|
|
44
|
-
export declare function getChangedRows<T>(grid: InternalGrid<T>): T[];
|
|
45
|
-
/**
|
|
46
|
-
* Get indices of all changed rows.
|
|
47
|
-
* @param grid - The grid instance
|
|
48
|
-
* @returns Array of row indices that have been modified
|
|
49
|
-
*/
|
|
50
|
-
export declare function getChangedRowIndices(grid: InternalGrid): number[];
|
|
51
|
-
/**
|
|
52
|
-
* Reset all changed row markers.
|
|
53
|
-
* @param grid - The grid instance
|
|
54
|
-
* @param silent - If true, don't emit the reset event
|
|
55
|
-
*/
|
|
56
|
-
export declare function resetChangedRows<T>(grid: InternalGrid<T>, silent?: boolean): void;
|
|
57
|
-
/**
|
|
58
|
-
* Begin bulk editing for a row. Enters edit mode on all editable cells.
|
|
59
|
-
* @param grid - The grid instance
|
|
60
|
-
* @param rowIndex - The row index to start editing
|
|
61
|
-
* @param callbacks - Grid callbacks for finding row elements
|
|
62
|
-
*/
|
|
63
|
-
export declare function beginBulkEdit<T>(grid: InternalGrid<T>, rowIndex: number, callbacks: {
|
|
64
|
-
findRenderedRowElement: (rowIndex: number) => HTMLElement | null;
|
|
65
|
-
}): void;
|
|
66
|
-
/**
|
|
67
|
-
* Commit the currently active row edit.
|
|
68
|
-
* @param grid - The grid instance
|
|
69
|
-
*/
|
|
70
|
-
export declare function commitActiveRowEdit(grid: InternalGrid): void;
|
|
71
|
-
/**
|
|
72
|
-
* Cancel the currently active row edit, reverting to original values.
|
|
73
|
-
* @param grid - The grid instance
|
|
74
|
-
*/
|
|
75
|
-
export declare function cancelActiveRowEdit(grid: InternalGrid): void;
|
|
76
|
-
//# sourceMappingURL=editing.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editing.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/core/internal/editing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAI3D;;;GAGG;AACH,eAAO,MAAM,yBAAyB,8GACiE,CAAC;AAWxG;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE3D;AAwBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAG1D;AAmDD;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,CAKrF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAyFvF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,EACzB,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE,GAAG,GACX,IAAI,CAuBN;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,GAAG,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,EACzB,IAAI,EAAE,WAAW,EACjB,SAAS,UAAQ,GAChB,IAAI,CAmKN;AAeD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CASjF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE;IAAE,sBAAsB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAA;CAAE,GAC9E,IAAI,CA6CN;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAI5D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAI5D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editors.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/core/internal/editors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5D;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,WAAW,GAAG,MAAM,CAiFxG"}
|