import type { GridConfirmPayload, GridRowId, GridColumnSort, GridRowIndexes, GridRowDropInfo, } from '../types' export type GridEvents = | 'onSelectionChange' | 'onRangeSelectionChange' | 'onExpandedRowsChange' | 'onFocusUnmount' | 'onReturnFocus' | 'onSortChange' | 'onRowHover' | 'onRowClick' | 'onRowDrop' | 'onVisibleRowsChange' | 'onColumnStateChange' | 'onCellChange' | 'scrollToIndex' | 'onScrollbarVisibilityChange' export type Emitter = { on( id: 'onSelectionChange', callback: (selection: Set) => void ): () => void on( id: 'onRangeSelectionChange', callback: ( range: null | { from: { columnId: string; rowId: GridRowId } to: { columnId: string; rowId: GridRowId } } ) => void ): () => void on( id: 'onExpandedRowsChange', callback: ( expandedRows: Set, context: { expanded: Set; collapsed: Set } ) => void ): () => void on(id: 'onFocusUnmount', callback: () => void): () => void on(id: 'onReturnFocus', callback: () => void): () => void on( id: 'onSortChange', callback: (sort: GridColumnSort[]) => void ): () => void on( id: 'onRowHover', callback: (currentRow: string | null) => void ): () => void on(id: 'onRowClick', callback: (rowId: GridRowId) => void): () => void on( id: 'onRowDrop', callback: (payload: GridRowDropInfo) => void ): () => void on( id: 'onVisibleRowsChange', callback: (indexes: GridRowIndexes) => void ): () => void on(id: 'onColumnStateChange', callback: () => void): () => void on( id: 'onCellChange', callback: (confirm: GridConfirmPayload) => void ): () => void on( id: 'scrollToIndex', callback: ( rowIndex: number | null, columnIndex: number | null, mode: 'auto' | 'always' ) => void ): () => void on( id: 'onScrollbarVisibilityChange', callback: (visibility: { horizontalHeight: number verticalWidth: number }) => void ): () => void emit(id: 'onSelectionChange', selection: Set): void emit( id: 'onRangeSelectionChange', selection: null | { from: { columnId: string; rowId: GridRowId } to: { columnId: string; rowId: GridRowId } } ): void emit( id: 'onExpandedRowsChange', expandedRows: Set, context: { expanded: Set; collapsed: Set } ): void emit(id: 'onFocusUnmount'): void emit(id: 'onReturnFocus'): void emit(id: 'onSortChange', sort: GridColumnSort[]): void emit(id: 'onRowHover', currentRow: string | null): void emit(id: 'onRowClick', rowId: GridRowId): void emit(id: 'onRowDrop', payload: GridRowDropInfo): void emit(id: 'onVisibleRowsChange', indexes: GridRowIndexes): void emit(id: 'onColumnStateChange'): void emit(id: 'onCellChange', confirm: GridConfirmPayload): void emit( id: 'scrollToIndex', rowIndex: number | null, columnIndex: number | null, mode: 'auto' | 'always' ): void emit( id: 'onScrollbarVisibilityChange', visibility: { horizontalHeight: number verticalWidth: number } ): void } export function createEmitter(): Emitter { const events: Record void)[]> = { onSelectionChange: [], onRangeSelectionChange: [], onExpandedRowsChange: [], onFocusUnmount: [], onReturnFocus: [], onSortChange: [], onRowHover: [], onRowClick: [], onRowDrop: [], onVisibleRowsChange: [], onColumnStateChange: [], onCellChange: [], scrollToIndex: [], onScrollbarVisibilityChange: [], } return { on(id, callback) { events[id].push(callback) return () => { events[id] = events[id].filter((ev) => ev !== callback) } }, emit(id, ...args: any[]) { events[id].forEach((fn) => fn(...args)) }, } }