UNPKG

@adaptabletools/adaptable

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

127 lines (126 loc) 4.87 kB
import * as React from 'react'; import { renderWithAdaptableContext } from '../View/renderWithAdaptableContext'; import { AdaptableFloatingFilter } from '../View/Components/ColumnFilter/AdaptableFloatingFilter'; const filterContainerStyle = { overflow: 'hidden', minWidth: '0', height: '100%', display: 'flex', alignItems: 'stretch', position: 'relative', flex: '1 1 auto', }; export const AgGridFloatingFilterAdapterFactory = (adaptable) => { const adaptableApi = adaptable.api; function getContainerId(colId) { return `floatingFilter_${colId}_${adaptable.adaptableOptions.adaptableId}`; } function getFilterProps(colId) { const column = adaptableApi.columnApi.getColumnWithColumnId(colId); const columnFilterProps = { Column: column, Adaptable: adaptable, ShowCloseButton: false, }; return columnFilterProps; } function findParentWithClass(element, className, stopClasses, applyToAll) { let current = element.parentElement; while (current) { // Stop traversing if we hit any of the stop classes if (stopClasses.some((stopClass) => current.classList.contains(stopClass))) { return null; } if (current.classList.contains(className)) { return current; } applyToAll?.(current); current = current.parentElement; } return null; } function patchParentElement(filterContainer) { if (!filterContainer) { return; } const stopClasses = ['ag-header-row', 'ag-header-row-column-filter']; // Find and update floating filter body const filterBody = findParentWithClass(filterContainer, 'ag-floating-filter-full-body', stopClasses, (currentElem) => { currentElem.style.height = '100%'; }); if (filterBody) { filterBody.style.overflow = 'visible'; } // Find and update header cell const headerCell = findParentWithClass(filterContainer, 'ag-header-cell', stopClasses); if (headerCell?.classList.contains('ag-floating-filter')) { headerCell.style.padding = 'var(--ab-space-1)'; } } if (adaptable.isAgGridInitialising) { if (adaptable.variant === 'react') { return () => React.createElement(React.Fragment, null); } return class FloatingFilterStub { init(params) { this.filterContainer = document.createElement('div'); } getGui() { return this.filterContainer; } destroy() { this.unmountReactRoot?.(); this.filterContainer = null; } onParentModelChanged() { // nothing yet } }; } return class AgGridFloatingFilterAdapter { init(params) { const colId = params.column.getColId(); this.colId = colId; this.filterContainer = document.createElement('div'); this.filterContainer.id = getContainerId(colId); Object.keys(filterContainerStyle).forEach((key) => { //@ts-ignore this.filterContainer.style[key] = filterContainerStyle[key]; }); const column = adaptableApi.columnApi.getColumnWithColumnId(colId); if (column) { const filterProps = getFilterProps(colId); this.unmountReactRoot = adaptable.renderReactRoot(renderWithAdaptableContext(React.createElement(AdaptableFloatingFilter, { ...filterProps, }), adaptable), this.filterContainer); } } onParentModelChanged(parentModel, filterChangedEvent) { // AFL: this should NOT be required, but AG Grid calls this method // most likely is a bug and will be removed in future versions } afterGuiAttached() { patchParentElement(this.filterContainer); } getGui() { return this.filterContainer; } refresh(params) { // always reuse the current instance // the filte ris refreshed in the underlying React component return true; } destroy() { // Use setTimeout to defer unmounting to next event loop tick // This ensures we're not unmounting during React's rendering phase if (this.unmountReactRoot) { const unmount = this.unmountReactRoot; setTimeout(() => { unmount(); }, 0); this.unmountReactRoot = undefined; } this.filterContainer = null; } }; };