var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); // packages/ag-grid-community/src/main.ts var main_exports = {}; __export(main_exports, { ALWAYS_SYNC_GLOBAL_EVENTS: () => ALWAYS_SYNC_GLOBAL_EVENTS, AbstractClientSideNodeManager: () => AbstractClientSideNodeManager, AgAbstractInputField: () => AgAbstractInputField, AgAbstractLabel: () => AgAbstractLabel, AgCheckbox: () => AgCheckbox, AgCheckboxSelector: () => AgCheckboxSelector, AgColumn: () => AgColumn, AgColumnGroup: () => AgColumnGroup, AgInputDateField: () => AgInputDateField, AgInputNumberField: () => AgInputNumberField, AgInputNumberFieldSelector: () => AgInputNumberFieldSelector, AgInputTextArea: () => AgInputTextArea, AgInputTextField: () => AgInputTextField, AgInputTextFieldSelector: () => AgInputTextFieldSelector, AgPickerField: () => AgPickerField, AgPromise: () => AgPromise, AgProvidedColumnGroup: () => AgProvidedColumnGroup, AgRadioButton: () => AgRadioButton, AgSelect: () => AgSelect, AgSelectSelector: () => AgSelectSelector, AgToggleButton: () => AgToggleButton, AgToggleButtonSelector: () => AgToggleButtonSelector, AlignedGridsModule: () => AlignedGridsModule, AllCommunityModule: () => AllCommunityModule, AutoScrollService: () => AutoScrollService, BaseColsService: () => BaseColsService, BaseComponentWrapper: () => BaseComponentWrapper, BaseCreator: () => BaseCreator, BaseGridSerializingSession: () => BaseGridSerializingSession, BaseSelectionService: () => BaseSelectionService, BeanStub: () => BeanStub, CellApiModule: () => CellApiModule, CellRangeType: () => CellRangeType, CellSpanModule: () => CellSpanModule, CellStyleModule: () => CellStyleModule, ChangedPath: () => ChangedPath, CheckboxEditorModule: () => CheckboxEditorModule, ClientSideRowModelApiModule: () => ClientSideRowModelApiModule, ClientSideRowModelModule: () => ClientSideRowModelModule, ColumnApiModule: () => ColumnApiModule, ColumnAutoSizeModule: () => ColumnAutoSizeModule, ColumnHoverModule: () => ColumnHoverModule, ColumnKeyCreator: () => ColumnKeyCreator, Component: () => Component, CssClassManager: () => CssClassManager, CsvExportModule: () => CsvExportModule, CustomEditorModule: () => CustomEditorModule, CustomFilterModule: () => CustomFilterModule, DateEditorModule: () => DateEditorModule, DateFilterModule: () => DateFilterModule, DragAndDropModule: () => DragAndDropModule, DragSourceType: () => DragSourceType, EventApiModule: () => EventApiModule, ExternalFilterModule: () => ExternalFilterModule, FakeHScrollComp: () => FakeHScrollComp, FakeVScrollComp: () => FakeVScrollComp, FilterWrapperComp: () => FilterWrapperComp, GROUP_AUTO_COLUMN_ID: () => GROUP_AUTO_COLUMN_ID, GridBodyCtrl: () => GridBodyCtrl, GridCoreCreator: () => GridCoreCreator, GridCtrl: () => GridCtrl, GridHeaderCtrl: () => GridHeaderCtrl, GridStateModule: () => GridStateModule, GroupInstanceIdCreator: () => GroupInstanceIdCreator, HeaderRowContainerCtrl: () => HeaderRowContainerCtrl, HighlightChangesModule: () => HighlightChangesModule, InfiniteRowModelModule: () => InfiniteRowModelModule, KeyCode: () => KeyCode, LargeTextEditorModule: () => LargeTextEditorModule, LocalEventService: () => LocalEventService, LocaleModule: () => LocaleModule, LocaleService: () => LocaleService, ManagedFocusFeature: () => ManagedFocusFeature, ModuleRegistry: () => ModuleRegistry, NumberEditorModule: () => NumberEditorModule, NumberFilterModule: () => NumberFilterModule, PaginationModule: () => PaginationModule, PinnedRowModule: () => PinnedRowModule, PopupComponent: () => PopupComponent, PositionableFeature: () => PositionableFeature, ProvidedFilter: () => ProvidedFilter, QuickFilterModule: () => QuickFilterModule, ROW_NUMBERS_COLUMN_ID: () => ROW_NUMBERS_COLUMN_ID, RefPlaceholder: () => RefPlaceholder, RenderApiModule: () => RenderApiModule, RowApiModule: () => RowApiModule, RowAutoHeightModule: () => RowAutoHeightModule, RowContainerCtrl: () => RowContainerCtrl, RowDragModule: () => RowDragModule, RowNode: () => RowNode, RowSelectionModule: () => RowSelectionModule, RowStyleModule: () => RowStyleModule, SELECTION_COLUMN_ID: () => SELECTION_COLUMN_ID, ScrollApiModule: () => ScrollApiModule, SelectEditorModule: () => SelectEditorModule, ServerSideTransactionResultStatus: () => ServerSideTransactionResultStatus, TabGuardClassNames: () => TabGuardClassNames, TabGuardComp: () => TabGuardComp, TabGuardCtrl: () => TabGuardCtrl, TabGuardFeature: () => TabGuardFeature, TextEditorModule: () => TextEditorModule, TextFilterModule: () => TextFilterModule, TooltipFeature: () => TooltipFeature, TooltipModule: () => TooltipModule, TouchListener: () => TouchListener, UndoRedoEditModule: () => UndoRedoEditModule, ValidationModule: () => ValidationModule, ValueCacheModule: () => ValueCacheModule, VanillaFrameworkOverrides: () => VanillaFrameworkOverrides, _ALL_EVENTS: () => _ALL_EVENTS, _ALL_GRID_OPTIONS: () => _ALL_GRID_OPTIONS, _BOOLEAN_MIXED_GRID_OPTIONS: () => _BOOLEAN_MIXED_GRID_OPTIONS, _ColumnFilterModule: () => ColumnFilterModule, _ColumnGroupModule: () => ColumnGroupModule, _ColumnMoveModule: () => ColumnMoveModule, _CsrmSsrmSharedApiModule: () => CsrmSsrmSharedApiModule, _DragModule: () => DragModule, _EditCoreModule: () => EditCoreModule, _EmptyArray: () => _EmptyArray, _EmptyBean: () => EmptyBean, _FOCUS_MANAGED_CLASS: () => FOCUS_MANAGED_CLASS, _FilterCoreModule: () => FilterCoreModule, _FilterValueModule: () => FilterValueModule, _HeaderComp: () => HeaderComp, _HorizontalResizeModule: () => HorizontalResizeModule, _KeyboardNavigationModule: () => KeyboardNavigationModule, _PUBLIC_EVENTS: () => _PUBLIC_EVENTS, _PopupModule: () => PopupModule, _ROW_ID_PREFIX_ROW_GROUP: () => ROW_ID_PREFIX_ROW_GROUP, _SharedDragAndDropModule: () => SharedDragAndDropModule, _SharedExportModule: () => SharedExportModule, _SharedMenuModule: () => SharedMenuModule, _SharedRowSelectionModule: () => SharedRowSelectionModule, _SortModule: () => SortModule, _SsrmInfiniteSharedApiModule: () => SsrmInfiniteSharedApiModule, _addColumnDefaultAndTypes: () => _addColumnDefaultAndTypes, _addFocusableContainerListener: () => _addFocusableContainerListener, _addGridCommonParams: () => _addGridCommonParams, _anchorElementToMouseMoveEvent: () => _anchorElementToMouseMoveEvent, _applyColumnState: () => _applyColumnState, _areCellsEqual: () => _areCellsEqual, _areColIdsEqual: () => _areColIdsEqual, _areEqual: () => _areEqual, _asThemeImpl: () => _asThemeImpl, _bindCellRendererToHtmlElement: () => _bindCellRendererToHtmlElement, _canSkipShowingRowGroup: () => _canSkipShowingRowGroup, _clearElement: () => _clearElement, _columnsMatch: () => _columnsMatch, _combineAttributesAndGridOptions: () => _combineAttributesAndGridOptions, _convertColumnEventSourceType: () => _convertColumnEventSourceType, _createCellId: () => _createCellId, _createColumnTree: () => _createColumnTree, _createGlobalRowEvent: () => _createGlobalRowEvent, _createIcon: () => _createIcon, _createIconNoSpan: () => _createIconNoSpan, _debounce: () => _debounce, _defaultComparator: () => _defaultComparator, _destroyColumnTree: () => _destroyColumnTree, _doOnce: () => _doOnce, _downloadFile: () => _downloadFile, _errMsg: () => _errMsg, _error: () => _error, _escapeString: () => _escapeString, _exists: () => _exists, _findFocusableElements: () => _findFocusableElements, _findNextFocusableElement: () => _findNextFocusableElement, _findTabbableParent: () => _findTabbableParent, _focusGridInnerElement: () => _focusGridInnerElement, _focusInto: () => _focusInto, _focusNextGridCoreContainer: () => _focusNextGridCoreContainer, _formatNumberCommas: () => _formatNumberCommas, _fuzzySuggestions: () => _fuzzySuggestions, _getAbsoluteHeight: () => _getAbsoluteHeight, _getAbsoluteWidth: () => _getAbsoluteWidth, _getActiveDomElement: () => _getActiveDomElement, _getAriaPosInSet: () => _getAriaPosInSet, _getCallbackForEvent: () => _getCallbackForEvent, _getCellByPosition: () => _getCellByPosition, _getCellCtrlForEventTarget: () => _getCellCtrlForEventTarget, _getCellPositionForEvent: () => _getCellPositionForEvent, _getCellRendererDetails: () => _getCellRendererDetails, _getCheckboxLocation: () => _getCheckboxLocation, _getCheckboxes: () => _getCheckboxes, _getClientSideRowModel: () => _getClientSideRowModel, _getColumnState: () => _getColumnState, _getColumnsFromTree: () => _getColumnsFromTree, _getDefaultFloatingFilterType: () => _getDefaultFloatingFilterType, _getDocument: () => _getDocument, _getEditorRendererDetails: () => _getEditorRendererDetails, _getFillHandle: () => _getFillHandle, _getFilterDetails: () => _getFilterDetails, _getFloatingFilterCompDetails: () => _getFloatingFilterCompDetails, _getFloatingFiltersHeight: () => getFloatingFiltersHeight, _getGlobalGridOption: () => _getGlobalGridOption, _getGrandTotalRow: () => _getGrandTotalRow, _getGridRegisteredModules: () => _getGridRegisteredModules, _getGroupAggFiltering: () => _getGroupAggFiltering, _getGroupSelection: () => _getGroupSelection, _getGroupSelectsDescendants: () => _getGroupSelectsDescendants, _getGroupTotalRowCallback: () => _getGroupTotalRowCallback, _getHeaderCheckbox: () => _getHeaderCheckbox, _getHeaderClassesFromColDef: () => _getHeaderClassesFromColDef, _getHeaderRowCount: () => getHeaderRowCount, _getInnerCellRendererDetails: () => _getInnerCellRendererDetails, _getInnerHeight: () => _getInnerHeight, _getInnerWidth: () => _getInnerWidth, _getIsRowSelectable: () => _getIsRowSelectable, _getLocaleTextFunc: () => _getLocaleTextFunc, _getMaxConcurrentDatasourceRequests: () => _getMaxConcurrentDatasourceRequests, _getNormalisedMousePosition: () => _getNormalisedMousePosition, _getPageBody: () => _getPageBody, _getRootNode: () => _getRootNode, _getRowContainerClass: () => _getRowContainerClass, _getRowContainerOptions: () => _getRowContainerOptions, _getRowHeightAsNumber: () => _getRowHeightAsNumber, _getRowHeightForNode: () => _getRowHeightForNode, _getRowIdCallback: () => _getRowIdCallback, _getRowNode: () => _getRowNode, _getRowSelectionMode: () => _getRowSelectionMode, _getRowSpanContainerClass: () => _getRowSpanContainerClass, _getRowViewportClass: () => _getRowViewportClass, _getServerSideRowModel: () => _getServerSideRowModel, _getShouldDisplayTooltip: () => _getShouldDisplayTooltip, _getSuppressMultiRanges: () => _getSuppressMultiRanges, _getToolPanelClassesFromColDef: () => _getToolPanelClassesFromColDef, _isAnimateRows: () => _isAnimateRows, _isCellSelectionEnabled: () => _isCellSelectionEnabled, _isClientSideRowModel: () => _isClientSideRowModel, _isColumnMenuAnchoringEnabled: () => _isColumnMenuAnchoringEnabled, _isColumnsSortingCoupledToGroup: () => _isColumnsSortingCoupledToGroup, _isDomLayout: () => _isDomLayout, _isElementInEventPath: () => _isElementInEventPath, _isEventFromPrintableCharacter: () => _isEventFromPrintableCharacter, _isGetRowHeightFunction: () => _isGetRowHeightFunction, _isGroupMultiAutoColumn: () => _isGroupMultiAutoColumn, _isGroupRowsSticky: () => _isGroupRowsSticky, _isGroupUseEntireRow: () => _isGroupUseEntireRow, _isIOSUserAgent: () => _isIOSUserAgent, _isKeyboardMode: () => _isKeyboardMode, _isLegacyMenuEnabled: () => _isLegacyMenuEnabled, _isMultiRowSelection: () => _isMultiRowSelection, _isNodeOrElement: () => _isNodeOrElement, _isNothingFocused: () => _isNothingFocused, _isPromise: () => _isPromise, _isRowBefore: () => _isRowBefore, _isRowSelection: () => _isRowSelection, _isSameRow: () => _isSameRow, _isServerSideRowModel: () => _isServerSideRowModel, _isShowTooltipWhenTruncated: () => _isShowTooltipWhenTruncated, _isStopPropagationForAgGrid: () => _isStopPropagationForAgGrid, _isUsingNewCellSelectionAPI: () => _isUsingNewCellSelectionAPI, _isUsingNewRowSelectionAPI: () => _isUsingNewRowSelectionAPI, _isVisible: () => _isVisible, _jsonEquals: () => _jsonEquals, _last: () => _last, _loadTemplate: () => _loadTemplate, _makeNull: () => _makeNull, _mergeDeep: () => _mergeDeep, _missing: () => _missing, _observeResize: () => _observeResize, _parseDateTimeFromString: () => _parseDateTimeFromString, _preInitErrMsg: () => _preInitErrMsg, _preserveRangesWhile: () => _preserveRangesWhile, _processOnChange: () => _processOnChange, _radioCssClass: () => _radioCssClass, _removeAriaExpanded: () => _removeAriaExpanded, _removeAriaSort: () => _removeAriaSort, _removeFromArray: () => _removeFromArray, _removeFromParent: () => _removeFromParent, _requestAnimationFrame: () => _requestAnimationFrame, _resetColumnState: () => _resetColumnState, _selectAllCells: () => _selectAllCells, _serialiseDate: () => _serialiseDate, _setAriaActiveDescendant: () => _setAriaActiveDescendant, _setAriaChecked: () => _setAriaChecked, _setAriaColCount: () => _setAriaColCount, _setAriaColIndex: () => _setAriaColIndex, _setAriaColSpan: () => _setAriaColSpan, _setAriaControls: () => _setAriaControls, _setAriaDescribedBy: () => _setAriaDescribedBy, _setAriaDisabled: () => _setAriaDisabled, _setAriaExpanded: () => _setAriaExpanded, _setAriaHasPopup: () => _setAriaHasPopup, _setAriaHidden: () => _setAriaHidden, _setAriaLabel: () => _setAriaLabel, _setAriaLabelledBy: () => _setAriaLabelledBy, _setAriaLevel: () => _setAriaLevel, _setAriaPosInSet: () => _setAriaPosInSet, _setAriaRole: () => _setAriaRole, _setAriaRowCount: () => _setAriaRowCount, _setAriaRowIndex: () => _setAriaRowIndex, _setAriaSelected: () => _setAriaSelected, _setAriaSetSize: () => _setAriaSetSize, _setAriaSort: () => _setAriaSort, _setColMenuVisible: () => _setColMenuVisible, _setDisabled: () => _setDisabled, _setDisplayed: () => _setDisplayed, _setFixedWidth: () => _setFixedWidth, _setUmd: () => _setUmd, _setVisible: () => _setVisible, _shouldDisplayTooltip: () => _shouldDisplayTooltip, _shouldUpdateColVisibilityAfterGroup: () => _shouldUpdateColVisibilityAfterGroup, _stopPropagationForAgGrid: () => _stopPropagationForAgGrid, _toStringOrNull: () => _toStringOrNull, _unwrapUserComp: () => _unwrapUserComp, _updateColsMap: () => _updateColsMap, _updateColumnState: () => _updateColumnState, _waitUntil: () => _waitUntil, _warn: () => _warn, _warnOnce: () => _warnOnce, buttonStyleAlpine: () => buttonStyleAlpine, buttonStyleBalham: () => buttonStyleBalham, buttonStyleBase: () => buttonStyleBase, buttonStyleQuartz: () => buttonStyleQuartz, checkboxStyleDefault: () => checkboxStyleDefault, colorSchemeDark: () => colorSchemeDark, colorSchemeDarkBlue: () => colorSchemeDarkBlue, colorSchemeDarkWarm: () => colorSchemeDarkWarm, colorSchemeLight: () => colorSchemeLight, colorSchemeLightCold: () => colorSchemeLightCold, colorSchemeLightWarm: () => colorSchemeLightWarm, colorSchemeVariable: () => colorSchemeVariable, columnDropStyleBordered: () => columnDropStyleBordered, columnDropStylePlain: () => columnDropStylePlain, createGrid: () => createGrid, createPart: () => createPart, createTheme: () => createTheme, iconOverrides: () => iconOverrides, iconSetAlpine: () => iconSetAlpine, iconSetMaterial: () => iconSetMaterial, iconSetQuartz: () => iconSetQuartz, iconSetQuartzBold: () => iconSetQuartzBold, iconSetQuartzLight: () => iconSetQuartzLight, iconSetQuartzRegular: () => iconSetQuartzRegular, inputStyleBase: () => inputStyleBase, inputStyleBordered: () => inputStyleBordered, inputStyleUnderlined: () => inputStyleUnderlined, isColumn: () => isColumn, isColumnGroup: () => isColumnGroup2, isColumnGroupAutoCol: () => isColumnGroupAutoCol, isColumnSelectionCol: () => isColumnSelectionCol, isProvidedColumnGroup: () => isProvidedColumnGroup, isRowNumberCol: () => isRowNumberCol, provideGlobalGridOptions: () => provideGlobalGridOptions, styleMaterial: () => styleMaterial, tabStyleAlpine: () => tabStyleAlpine, tabStyleBase: () => tabStyleBase, tabStyleMaterial: () => tabStyleMaterial, tabStyleQuartz: () => tabStyleQuartz, tabStyleRolodex: () => tabStyleRolodex, themeAlpine: () => themeAlpine, themeBalham: () => themeBalham, themeMaterial: () => themeMaterial, themeQuartz: () => themeQuartz }); module.exports = __toCommonJS(main_exports); // packages/ag-grid-community/src/localEventService.ts var LocalEventService = class { constructor() { this.allSyncListeners = /* @__PURE__ */ new Map(); this.allAsyncListeners = /* @__PURE__ */ new Map(); this.globalSyncListeners = /* @__PURE__ */ new Set(); this.globalAsyncListeners = /* @__PURE__ */ new Set(); this.asyncFunctionsQueue = []; this.scheduled = false; // using an object performs better than a Set for the number of different events we have this.firedEvents = {}; } setFrameworkOverrides(frameworkOverrides) { this.frameworkOverrides = frameworkOverrides; } getListeners(eventType, async, autoCreateListenerCollection) { const listenerMap = async ? this.allAsyncListeners : this.allSyncListeners; let listeners = listenerMap.get(eventType); if (!listeners && autoCreateListenerCollection) { listeners = /* @__PURE__ */ new Set(); listenerMap.set(eventType, listeners); } return listeners; } noRegisteredListenersExist() { return this.allSyncListeners.size === 0 && this.allAsyncListeners.size === 0 && this.globalSyncListeners.size === 0 && this.globalAsyncListeners.size === 0; } addEventListener(eventType, listener, async = false) { this.getListeners(eventType, async, true).add(listener); } removeEventListener(eventType, listener, async = false) { const listeners = this.getListeners(eventType, async, false); if (!listeners) { return; } listeners.delete(listener); if (listeners.size === 0) { const listenerMap = async ? this.allAsyncListeners : this.allSyncListeners; listenerMap.delete(eventType); } } addGlobalListener(listener, async = false) { (async ? this.globalAsyncListeners : this.globalSyncListeners).add(listener); } removeGlobalListener(listener, async = false) { (async ? this.globalAsyncListeners : this.globalSyncListeners).delete(listener); } dispatchEvent(event) { const agEvent = event; this.dispatchToListeners(agEvent, true); this.dispatchToListeners(agEvent, false); this.firedEvents[agEvent.type] = true; } dispatchEventOnce(event) { if (!this.firedEvents[event.type]) { this.dispatchEvent(event); } } dispatchToListeners(event, async) { const eventType = event.type; if (async && "event" in event) { const browserEvent = event.event; if (browserEvent instanceof Event) { event.eventPath = browserEvent.composedPath(); } } const processEventListeners = (listeners2, originalListeners2) => listeners2.forEach((listener) => { if (!originalListeners2.has(listener)) { return; } const callback = this.frameworkOverrides ? () => this.frameworkOverrides.wrapIncoming(() => listener(event)) : () => listener(event); if (async) { this.dispatchAsync(callback); } else { callback(); } }); const originalListeners = this.getListeners(eventType, async, false) ?? /* @__PURE__ */ new Set(); const listeners = new Set(originalListeners); if (listeners.size > 0) { processEventListeners(listeners, originalListeners); } const globalListeners = new Set( async ? this.globalAsyncListeners : this.globalSyncListeners ); globalListeners.forEach((listener) => { const callback = this.frameworkOverrides ? () => this.frameworkOverrides.wrapIncoming(() => listener(eventType, event)) : () => listener(eventType, event); if (async) { this.dispatchAsync(callback); } else { callback(); } }); } // this gets called inside the grid's thread, for each event that it // wants to set async. the grid then batches the events into one setTimeout() // because setTimeout() is an expensive operation. ideally we would have // each event in it's own setTimeout(), but we batch for performance. dispatchAsync(func) { this.asyncFunctionsQueue.push(func); if (!this.scheduled) { const flush = () => { window.setTimeout(this.flushAsyncQueue.bind(this), 0); }; this.frameworkOverrides ? this.frameworkOverrides.wrapIncoming(flush) : flush(); this.scheduled = true; } } // this happens in the next VM turn only, and empties the queue of events flushAsyncQueue() { this.scheduled = false; const queueCopy = this.asyncFunctionsQueue.slice(); this.asyncFunctionsQueue = []; queueCopy.forEach((func) => func()); } }; // packages/ag-grid-community/src/misc/locale/localeUtils.ts function defaultLocaleTextFunc(_key, defaultValue) { return defaultValue; } function _getLocaleTextFunc(localeSvc) { return localeSvc?.getLocaleTextFunc() ?? defaultLocaleTextFunc; } // packages/ag-grid-community/src/utils/aria.ts function _toggleAriaAttribute(element, attribute, value) { if (value == null || typeof value === "string" && value == "") { _removeAriaAttribute(element, attribute); } else { _setAriaAttribute(element, attribute, value); } } function _setAriaAttribute(element, attribute, value) { element.setAttribute(_ariaAttributeName(attribute), value.toString()); } function _removeAriaAttribute(element, attribute) { element.removeAttribute(_ariaAttributeName(attribute)); } function _ariaAttributeName(attribute) { return `aria-${attribute}`; } function _setAriaRole(element, role) { if (role) { element.setAttribute("role", role); } else { element.removeAttribute("role"); } } function _getAriaSortState(sortDirection) { let sort; if (sortDirection === "asc") { sort = "ascending"; } else if (sortDirection === "desc") { sort = "descending"; } else if (sortDirection === "mixed") { sort = "other"; } else { sort = "none"; } return sort; } function _getAriaPosInSet(element) { return parseInt(element.getAttribute("aria-posinset"), 10); } function _getAriaLabel(element) { return element.getAttribute("aria-label"); } function _setAriaLabel(element, label) { _toggleAriaAttribute(element, "label", label); } function _setAriaLabelledBy(element, labelledBy) { _toggleAriaAttribute(element, "labelledby", labelledBy); } function _setAriaDescribedBy(element, describedby) { _toggleAriaAttribute(element, "describedby", describedby); } function _setAriaLive(element, live) { _toggleAriaAttribute(element, "live", live); } function _setAriaAtomic(element, atomic) { _toggleAriaAttribute(element, "atomic", atomic); } function _setAriaRelevant(element, relevant) { _toggleAriaAttribute(element, "relevant", relevant); } function _setAriaLevel(element, level) { _toggleAriaAttribute(element, "level", level); } function _setAriaDisabled(element, disabled) { _toggleAriaAttribute(element, "disabled", disabled); } function _setAriaHidden(element, hidden) { _toggleAriaAttribute(element, "hidden", hidden); } function _setAriaActiveDescendant(element, descendantId) { _toggleAriaAttribute(element, "activedescendant", descendantId); } function _setAriaExpanded(element, expanded) { _setAriaAttribute(element, "expanded", expanded); } function _removeAriaExpanded(element) { _removeAriaAttribute(element, "expanded"); } function _setAriaSetSize(element, setsize) { _setAriaAttribute(element, "setsize", setsize); } function _setAriaPosInSet(element, position) { _setAriaAttribute(element, "posinset", position); } function _setAriaMultiSelectable(element, multiSelectable) { _setAriaAttribute(element, "multiselectable", multiSelectable); } function _setAriaRowCount(element, rowCount) { _setAriaAttribute(element, "rowcount", rowCount); } function _setAriaRowIndex(element, rowIndex) { _setAriaAttribute(element, "rowindex", rowIndex); } function _setAriaRowSpan(element, spanCount) { _setAriaAttribute(element, "rowspan", spanCount); } function _setAriaColCount(element, colCount) { _setAriaAttribute(element, "colcount", colCount); } function _setAriaColIndex(element, colIndex) { _setAriaAttribute(element, "colindex", colIndex); } function _setAriaColSpan(element, colSpan) { _setAriaAttribute(element, "colspan", colSpan); } function _setAriaSort(element, sort) { _setAriaAttribute(element, "sort", sort); } function _removeAriaSort(element) { _removeAriaAttribute(element, "sort"); } function _setAriaSelected(element, selected) { _toggleAriaAttribute(element, "selected", selected); } function _setAriaChecked(element, checked) { _setAriaAttribute(element, "checked", checked === void 0 ? "mixed" : checked); } function _setAriaControls(controllerElement, controlledElement) { _toggleAriaAttribute(controllerElement, "controls", controlledElement.id); _setAriaLabelledBy(controlledElement, controllerElement.id); } function _setAriaHasPopup(element, hasPopup) { _toggleAriaAttribute(element, "haspopup", hasPopup === false ? null : hasPopup); } function _getAriaCheckboxStateName(translate, state) { return state === void 0 ? translate("ariaIndeterminate", "indeterminate") : state === true ? translate("ariaChecked", "checked") : translate("ariaUnchecked", "unchecked"); } // packages/ag-grid-community/src/utils/browser.ts var isSafari; var isChrome; var isFirefox; var isMacOs; var isIOS; var invisibleScrollbar; var browserScrollbarWidth; var maxDivHeight; function _isBrowserSafari() { if (isSafari === void 0) { isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); } return isSafari; } function _isBrowserChrome() { if (isChrome === void 0) { const win = window; isChrome = !!win.chrome && (!!win.chrome.webstore || !!win.chrome.runtime) || /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); } return isChrome; } function _isBrowserFirefox() { if (isFirefox === void 0) { isFirefox = /(firefox)/i.test(navigator.userAgent); } return isFirefox; } function _isMacOsUserAgent() { if (isMacOs === void 0) { isMacOs = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform); } return isMacOs; } function _isIOSUserAgent() { if (isIOS === void 0) { isIOS = /iPad|iPhone|iPod/.test(navigator.platform) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1; } return isIOS; } function _getTabIndex(el) { if (!el) { return null; } const numberTabIndex = el.tabIndex; const tabIndex = el.getAttribute("tabIndex"); if (numberTabIndex === -1 && (tabIndex === null || tabIndex === "" && !_isBrowserFirefox())) { return null; } return numberTabIndex.toString(); } function _getMaxDivHeight() { if (maxDivHeight !== void 0) { return maxDivHeight; } if (!document.body) { return -1; } let res = 1e6; const testUpTo = _isBrowserFirefox() ? 6e6 : 1e9; const div = document.createElement("div"); document.body.appendChild(div); while (true) { const test = res * 2; div.style.height = test + "px"; if (test > testUpTo || div.clientHeight !== test) { break; } else { res = test; } } document.body.removeChild(div); maxDivHeight = res; return res; } function _getScrollbarWidth() { if (browserScrollbarWidth == null) { initScrollbarWidthAndVisibility(); } return browserScrollbarWidth; } function initScrollbarWidthAndVisibility() { const body = document.body; const div = document.createElement("div"); div.style.width = div.style.height = "100px"; div.style.opacity = "0"; div.style.overflow = "scroll"; div.style.msOverflowStyle = "scrollbar"; div.style.position = "absolute"; body.appendChild(div); let width = div.offsetWidth - div.clientWidth; if (width === 0 && div.clientWidth === 0) { width = null; } if (div.parentNode) { div.parentNode.removeChild(div); } if (width != null) { browserScrollbarWidth = width; invisibleScrollbar = width === 0; } } function _isInvisibleScrollbar() { if (invisibleScrollbar == null) { initScrollbarWidthAndVisibility(); } return invisibleScrollbar; } // packages/ag-grid-community/src/utils/dom.ts var rtlNegativeScroll; function _radioCssClass(element, elementClass, otherElementClass) { const parent = element.parentElement; let sibling = parent && parent.firstChild; while (sibling) { if (elementClass) { sibling.classList.toggle(elementClass, sibling === element); } if (otherElementClass) { sibling.classList.toggle(otherElementClass, sibling !== element); } sibling = sibling.nextSibling; } } var FOCUSABLE_SELECTOR = "[tabindex], input, select, button, textarea, [href]"; var FOCUSABLE_EXCLUDE = "[disabled], .ag-disabled:not(.ag-button), .ag-disabled *"; function _isFocusableFormField(element) { const matches = Element.prototype.matches || Element.prototype.msMatchesSelector; const inputSelector = "input, select, button, textarea"; const isFocusable = matches.call(element, inputSelector); const isNotFocusable = matches.call(element, FOCUSABLE_EXCLUDE); const isElementVisible = _isVisible(element); const focusable = isFocusable && !isNotFocusable && isElementVisible; return focusable; } function _setDisplayed(element, displayed, options = {}) { const { skipAriaHidden } = options; element.classList.toggle("ag-hidden", !displayed); if (!skipAriaHidden) { _setAriaHidden(element, !displayed); } } function _setVisible(element, visible, options = {}) { const { skipAriaHidden } = options; element.classList.toggle("ag-invisible", !visible); if (!skipAriaHidden) { _setAriaHidden(element, !visible); } } function _setDisabled(element, disabled) { const attributeName = "disabled"; const addOrRemoveDisabledAttribute = disabled ? (e) => e.setAttribute(attributeName, "") : (e) => e.removeAttribute(attributeName); addOrRemoveDisabledAttribute(element); _nodeListForEach(element.querySelectorAll("input"), (input) => addOrRemoveDisabledAttribute(input)); } function _isElementChildOfClass(element, cls, maxNest) { let counter = 0; while (element) { if (element.classList.contains(cls)) { return true; } element = element.parentElement; if (typeof maxNest == "number") { if (++counter > maxNest) { break; } } else if (element === maxNest) { break; } } return false; } function _getElementSize(el) { const { height, width, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, paddingTop, paddingRight, paddingBottom, paddingLeft, marginTop, marginRight, marginBottom, marginLeft, boxSizing } = window.getComputedStyle(el); return { height: parseFloat(height || "0"), width: parseFloat(width || "0"), borderTopWidth: parseFloat(borderTopWidth || "0"), borderRightWidth: parseFloat(borderRightWidth || "0"), borderBottomWidth: parseFloat(borderBottomWidth || "0"), borderLeftWidth: parseFloat(borderLeftWidth || "0"), paddingTop: parseFloat(paddingTop || "0"), paddingRight: parseFloat(paddingRight || "0"), paddingBottom: parseFloat(paddingBottom || "0"), paddingLeft: parseFloat(paddingLeft || "0"), marginTop: parseFloat(marginTop || "0"), marginRight: parseFloat(marginRight || "0"), marginBottom: parseFloat(marginBottom || "0"), marginLeft: parseFloat(marginLeft || "0"), boxSizing }; } function _getInnerHeight(el) { const size = _getElementSize(el); if (size.boxSizing === "border-box") { return size.height - size.paddingTop - size.paddingBottom; } return size.height; } function _getInnerWidth(el) { const size = _getElementSize(el); if (size.boxSizing === "border-box") { return size.width - size.paddingLeft - size.paddingRight; } return size.width; } function _getAbsoluteHeight(el) { const { height, marginBottom, marginTop } = _getElementSize(el); return Math.floor(height + marginBottom + marginTop); } function _getAbsoluteWidth(el) { const { width, marginLeft, marginRight } = _getElementSize(el); return Math.floor(width + marginLeft + marginRight); } function _getElementRectWithOffset(el) { const offsetElementRect = el.getBoundingClientRect(); const { borderTopWidth, borderLeftWidth, borderRightWidth, borderBottomWidth } = _getElementSize(el); return { top: offsetElementRect.top + (borderTopWidth || 0), left: offsetElementRect.left + (borderLeftWidth || 0), right: offsetElementRect.right + (borderRightWidth || 0), bottom: offsetElementRect.bottom + (borderBottomWidth || 0) }; } function _isRtlNegativeScroll() { if (typeof rtlNegativeScroll === "boolean") { return rtlNegativeScroll; } const template = document.createElement("div"); template.style.direction = "rtl"; template.style.width = "1px"; template.style.height = "1px"; template.style.position = "fixed"; template.style.top = "0px"; template.style.overflow = "hidden"; template.dir = "rtl"; template.innerHTML = /* html */ `
`; document.body.appendChild(template); template.scrollLeft = 1; rtlNegativeScroll = Math.floor(template.scrollLeft) === 0; document.body.removeChild(template); return rtlNegativeScroll; } function _getScrollLeft(element, rtl) { let scrollLeft = element.scrollLeft; if (rtl) { scrollLeft = Math.abs(scrollLeft); if (_isBrowserChrome() && !_isRtlNegativeScroll()) { scrollLeft = element.scrollWidth - element.getBoundingClientRect().width - scrollLeft; } } return scrollLeft; } function _setScrollLeft(element, value, rtl) { if (rtl) { if (_isRtlNegativeScroll()) { value *= -1; } else if (_isBrowserSafari() || _isBrowserChrome()) { value = element.scrollWidth - element.getBoundingClientRect().width - value; } } element.scrollLeft = value; } function _clearElement(el) { while (el && el.firstChild) { el.removeChild(el.firstChild); } } function _removeFromParent(node) { if (node && node.parentNode) { node.parentNode.removeChild(node); } } function _isInDOM(element) { return !!element.offsetParent; } function _isVisible(element) { const el = element; if (el.checkVisibility) { return el.checkVisibility({ checkVisibilityCSS: true }); } const isHidden = !_isInDOM(element) || window.getComputedStyle(element).visibility !== "visible"; return !isHidden; } function _loadTemplate(template) { const tempDiv = document.createElement("div"); tempDiv.innerHTML = (template || "").trim(); return tempDiv.firstChild; } function _ensureDomOrder(eContainer, eChild, eChildBefore) { if (eChildBefore && eChildBefore.nextSibling === eChild) { return; } if (!eContainer.firstChild) { eContainer.appendChild(eChild); } else if (eChildBefore) { if (eChildBefore.nextSibling) { eContainer.insertBefore(eChild, eChildBefore.nextSibling); } else { eContainer.appendChild(eChild); } } else if (eContainer.firstChild && eContainer.firstChild !== eChild) { eContainer.insertAdjacentElement("afterbegin", eChild); } } function _setDomChildOrder(eContainer, orderedChildren) { for (let i = 0; i < orderedChildren.length; i++) { const correctCellAtIndex = orderedChildren[i]; const actualCellAtIndex = eContainer.children[i]; if (actualCellAtIndex !== correctCellAtIndex) { eContainer.insertBefore(correctCellAtIndex, actualCellAtIndex); } } } function _camelCaseToHyphenated(camelCase) { return camelCase.replace(/[A-Z]/g, (s) => `-${s.toLocaleLowerCase()}`); } function _addStylesToElement(eElement, styles) { if (!styles) { return; } for (const key of Object.keys(styles)) { const value = styles[key]; if (!key || !key.length || value == null) { continue; } const parsedKey = _camelCaseToHyphenated(key); const valueAsString = value.toString(); const parsedValue = valueAsString.replace(/\s*!important/g, ""); const priority = parsedValue.length != valueAsString.length ? "important" : void 0; eElement.style.setProperty(parsedKey, parsedValue, priority); } } function _isHorizontalScrollShowing(element) { return element.clientWidth < element.scrollWidth; } function _isVerticalScrollShowing(element) { return element.clientHeight < element.scrollHeight; } function _setElementWidth(element, width) { if (width === "flex") { element.style.removeProperty("width"); element.style.removeProperty("minWidth"); element.style.removeProperty("maxWidth"); element.style.flex = "1 1 auto"; } else { _setFixedWidth(element, width); } } function _setFixedWidth(element, width) { width = _formatSize(width); element.style.width = width.toString(); element.style.maxWidth = width.toString(); element.style.minWidth = width.toString(); } function _setFixedHeight(element, height) { height = _formatSize(height); element.style.height = height.toString(); element.style.maxHeight = height.toString(); element.style.minHeight = height.toString(); } function _formatSize(size) { if (typeof size === "number") { return `${size}px`; } return size; } function _isNodeOrElement(o) { return o instanceof Node || o instanceof HTMLElement; } function _copyNodeList(nodeList) { if (nodeList == null) { return []; } const result = []; _nodeListForEach(nodeList, (node) => result.push(node)); return result; } function _iterateNamedNodeMap(map, callback) { if (!map) { return; } for (let i = 0; i < map.length; i++) { const attr = map[i]; callback(attr.name, attr.value); } } function _addOrRemoveAttribute(element, name, value) { if (value == null || value === "") { element.removeAttribute(name); } else { element.setAttribute(name, value.toString()); } } function _nodeListForEach(nodeList, action) { if (nodeList == null) { return; } for (let i = 0; i < nodeList.length; i++) { action(nodeList[i]); } } function _bindCellRendererToHtmlElement(cellRendererPromise, eTarget) { cellRendererPromise.then((cellRenderer) => { const gui = cellRenderer.getGui(); if (gui != null) { if (typeof gui === "object") { eTarget.appendChild(gui); } else { eTarget.innerHTML = gui; } } }); } function _observeResize(beans, element, callback) { const win = _getWindow(beans); const ResizeObserverImpl = win.ResizeObserver; const resizeObserver = ResizeObserverImpl ? new ResizeObserverImpl(callback) : null; resizeObserver?.observe(element); return () => resizeObserver?.disconnect(); } function _getTextSelectionRanges(beans) { const rootNode = _getRootNode(beans); const selection = "getSelection" in rootNode ? rootNode.getSelection() : null; const ranges = []; for (let i = 0; i < (selection?.rangeCount ?? 0); i++) { const range = selection?.getRangeAt(i); if (range) { ranges.push(range); } } return { selection, ranges }; } function _preserveRangesWhile(beans, fn) { const enableCellTextSelection = beans.gos.get("enableCellTextSelection"); if (!enableCellTextSelection) { return fn(); } if (!_isBrowserFirefox() && !_isBrowserSafari()) { return fn(); } const { selection, ranges } = _getTextSelectionRanges(beans); fn(); selection?.removeAllRanges(); for (const range of ranges) { selection?.addRange(range); } } // packages/ag-grid-community/src/utils/generic.ts function _makeNull(value) { if (value == null || value === "") { return null; } return value; } function _exists(value) { return value != null && value !== ""; } function _missing(value) { return !_exists(value); } function _toStringOrNull(value) { return value != null && typeof value.toString === "function" ? value.toString() : null; } function _jsonEquals(val1, val2) { const val1Json = val1 ? JSON.stringify(val1) : null; const val2Json = val2 ? JSON.stringify(val2) : null; return val1Json === val2Json; } function _defaultComparator(valueA, valueB, accentedCompare = false) { const valueAMissing = valueA == null; const valueBMissing = valueB == null; if (valueA && valueA.toNumber) { valueA = valueA.toNumber(); } if (valueB && valueB.toNumber) { valueB = valueB.toNumber(); } if (valueAMissing && valueBMissing) { return 0; } if (valueAMissing) { return -1; } if (valueBMissing) { return 1; } function doQuickCompare(a, b) { return a > b ? 1 : a < b ? -1 : 0; } if (typeof valueA !== "string") { return doQuickCompare(valueA, valueB); } if (!accentedCompare) { return doQuickCompare(valueA, valueB); } try { return valueA.localeCompare(valueB); } catch (e) { return doQuickCompare(valueA, valueB); } } // packages/ag-grid-community/src/baseUrl.ts var BASE_URL = "https://www.ag-grid.com"; // packages/ag-grid-community/src/utils/function.ts var doOnceFlags = {}; function _doOnce(func, key) { if (doOnceFlags[key]) { return; } func(); doOnceFlags[key] = true; } function _logIfDebug(gos, message, ...args) { if (gos.get("debug")) { console.log("AG Grid: " + message, ...args); } } function _warnOnce(msg, ...args) { _doOnce(() => console.warn("AG Grid: " + msg, ...args), msg + args?.join("")); } function _errorOnce(msg, ...args) { _doOnce(() => console.error("AG Grid: " + msg, ...args), msg + args?.join("")); } var executeNextVMTurnFuncs = []; var executeNextVMTurnPending = false; function _executeNextVMTurn(func) { executeNextVMTurnFuncs.push(func); if (executeNextVMTurnPending) { return; } executeNextVMTurnPending = true; window.setTimeout(() => { const funcsCopy = executeNextVMTurnFuncs.slice(); executeNextVMTurnFuncs.length = 0; executeNextVMTurnPending = false; funcsCopy.forEach((func2) => func2()); }, 0); } function _debounce(bean, func, delay) { let timeout; return function(...args) { const context = this; window.clearTimeout(timeout); timeout = window.setTimeout(function() { if (bean.isAlive()) { func.apply(context, args); } }, delay); }; } function _throttle(func, wait) { let previousCall = 0; return function(...args) { const context = this; const currentCall = (/* @__PURE__ */ new Date()).getTime(); if (currentCall - previousCall < wait) { return; } previousCall = currentCall; func.apply(context, args); }; } function _waitUntil(condition, callback, timeout = 100, timeoutMessage) { const timeStamp = (/* @__PURE__ */ new Date()).getTime(); let interval = null; let executed = false; const internalCallback = () => { const reachedTimeout = (/* @__PURE__ */ new Date()).getTime() - timeStamp > timeout; if (condition() || reachedTimeout) { callback(); executed = true; if (interval != null) { window.clearInterval(interval); interval = null; } if (reachedTimeout && timeoutMessage) { _warnOnce(timeoutMessage); } } }; internalCallback(); if (!executed) { interval = window.setInterval(internalCallback, 10); } } // packages/ag-grid-community/src/version.ts var VERSION = "33.1.1"; // packages/ag-grid-community/src/validation/logging.ts var MAX_URL_LENGTH = 2e3; var MIN_PARAM_LENGTH = 100; var VERSION_PARAM_NAME = "_version_"; var validation = null; var suppressAllLogging = false; var baseDocLink = `${BASE_URL}/javascript-data-grid`; function provideValidationServiceLogger(logger) { validation = logger; } function setValidationDocLink(docLink) { baseDocLink = docLink; } function getErrorParts(id, args, defaultMessage) { return validation?.getConsoleMessage(id, args) ?? [minifiedLog(id, args, defaultMessage)]; } function getMsgOrDefault(logger, id, args, defaultMessage) { if (suppressAllLogging) return; logger(`error #${id}`, ...getErrorParts(id, args, defaultMessage)); } function stringifyObject(inputObj) { if (!inputObj) return String(inputObj); const object = {}; for (const prop of Object.keys(inputObj)) { if (typeof inputObj[prop] !== "object" && typeof inputObj[prop] !== "function") { object[prop] = inputObj[prop]; } } return JSON.stringify(object); } function stringifyValue(value) { let output = value; if (value instanceof Error) { output = value.toString(); } else if (typeof value === "object") { output = stringifyObject(value); } return output; } function toStringWithNullUndefined(str) { return str === void 0 ? "undefined" : str === null ? "null" : str; } function getParamsUrl(baseUrl, params) { return `${baseUrl}?${params.toString()}`; } function truncateUrl(baseUrl, params, maxLength) { const sortedParams = Array.from(params.entries()).sort((a, b) => b[1].length - a[1].length); let url = getParamsUrl(baseUrl, params); for (const [key, value] of sortedParams) { if (key === VERSION_PARAM_NAME) { continue; } const excessLength = url.length - maxLength; if (excessLength <= 0) { break; } const ellipse = "..."; const truncateAmount = excessLength + ellipse.length; const truncatedValue = value.length - truncateAmount > MIN_PARAM_LENGTH ? value.slice(0, value.length - truncateAmount) + ellipse : value.slice(0, MIN_PARAM_LENGTH) + ellipse; params.set(key, truncatedValue); url = getParamsUrl(baseUrl, params); } return url; } function getErrorLink(errorNum, args) { const params = new URLSearchParams(); params.append(VERSION_PARAM_NAME, VERSION); if (args) { for (const key of Object.keys(args)) { params.append(key, stringifyValue(args[key])); } } const baseUrl = `${baseDocLink}/errors/${errorNum}`; const url = getParamsUrl(baseUrl, params); return url.length <= MAX_URL_LENGTH ? url : truncateUrl(baseUrl, params, MAX_URL_LENGTH); } var minifiedLog = (errorNum, args, defaultMessage) => { const errorLink = getErrorLink(errorNum, args); return `${defaultMessage ? defaultMessage + " \n" : ""}Visit ${errorLink}${defaultMessage ? "" : " \n Alternatively register the ValidationModule to see the full message in the console."}`; }; function _warn(...args) { getMsgOrDefault(_warnOnce, args[0], args[1]); } function _error(...args) { getMsgOrDefault(_errorOnce, args[0], args[1]); } function _logPreInitErr(id, args, defaultMessage) { getMsgOrDefault(_errorOnce, id, args, defaultMessage); } function getErrMsg(defaultMessage, args) { const id = args[0]; return `error #${id} ` + getErrorParts(id, args[1], defaultMessage).join(" "); } function _errMsg(...args) { return getErrMsg(void 0, args); } function _preInitErrMsg(...args) { return getErrMsg("\n", args); } // packages/ag-grid-community/src/gridOptionsUtils.ts function isRowModelType(gos, rowModelType) { return gos.get("rowModelType") === rowModelType; } function _isClientSideRowModel(gos, rowModel) { return isRowModelType(gos, "clientSide"); } function _isServerSideRowModel(gos, rowModel) { return isRowModelType(gos, "serverSide"); } function _isDomLayout(gos, domLayout) { return gos.get("domLayout") === domLayout; } function _isRowSelection(gos) { return _getRowSelectionMode(gos) !== void 0; } function _isGetRowHeightFunction(gos) { return typeof gos.get("getRowHeight") === "function"; } function _shouldMaintainColumnOrder(gos, isPivotColumns) { if (isPivotColumns) { return !gos.get("enableStrictPivotColumnOrder"); } return gos.get("maintainColumnOrder"); } function _getRowHeightForNode(beans, rowNode, allowEstimate = false, defaultRowHeight) { const { gos, environment } = beans; if (defaultRowHeight == null) { defaultRowHeight = environment.getDefaultRowHeight(); } if (_isGetRowHeightFunction(gos)) { if (allowEstimate) { return { height: defaultRowHeight, estimated: true }; } const params = { node: rowNode, data: rowNode.data }; const height = gos.getCallback("getRowHeight")(params); if (isNumeric(height)) { if (height === 0) { _warn(23); } return { height: Math.max(1, height), estimated: false }; } } if (rowNode.detail && gos.get("masterDetail")) { return getMasterDetailRowHeight(gos); } const gridOptionsRowHeight = gos.get("rowHeight"); const rowHeight = gridOptionsRowHeight && isNumeric(gridOptionsRowHeight) ? gridOptionsRowHeight : defaultRowHeight; return { height: rowHeight, estimated: false }; } function getMasterDetailRowHeight(gos) { if (gos.get("detailRowAutoHeight")) { return { height: 1, estimated: false }; } const defaultRowHeight = gos.get("detailRowHeight"); if (isNumeric(defaultRowHeight)) { return { height: defaultRowHeight, estimated: false }; } return { height: 300, estimated: false }; } function _getRowHeightAsNumber(beans) { const { environment, gos } = beans; const gridOptionsRowHeight = gos.get("rowHeight"); if (!gridOptionsRowHeight || _missing(gridOptionsRowHeight)) { return environment.getDefaultRowHeight(); } const rowHeight = environment.refreshRowHeightVariable(); if (rowHeight !== -1) { return rowHeight; } _warn(24); return environment.getDefaultRowHeight(); } function isNumeric(value) { return !isNaN(value) && typeof value === "number" && isFinite(value); } function _getDomData(gos, element, key) { const domData = element[gos.getDomDataKey()]; return domData ? domData[key] : void 0; } function _setDomData(gos, element, key, value) { const domDataKey = gos.getDomDataKey(); let domData = element[domDataKey]; if (_missing(domData)) { domData = {}; element[domDataKey] = domData; } domData[key] = value; } function _getDocument(beans) { const { gos, eGridDiv } = beans; let result = null; const gridOptionsGetDocument = gos.get("getDocument"); if (gridOptionsGetDocument && _exists(gridOptionsGetDocument)) { result = gridOptionsGetDocument(); } else if (eGridDiv) { result = eGridDiv.ownerDocument; } if (result && _exists(result)) { return result; } return document; } function _getWindow(beans) { const eDocument = _getDocument(beans); return eDocument.defaultView || window; } function _getRootNode(beans) { return beans.eGridDiv.getRootNode(); } function _getActiveDomElement(beans) { return _getRootNode(beans).activeElement; } function _getPageBody(beans) { let rootNode = null; let targetEl = null; try { rootNode = _getDocument(beans).fullscreenElement; } catch (e) { } finally { if (!rootNode) { rootNode = _getRootNode(beans); } const body = rootNode.querySelector("body"); if (body) { targetEl = body; } else if (rootNode instanceof ShadowRoot) { targetEl = rootNode; } else if (rootNode instanceof Document) { targetEl = rootNode?.documentElement; } else { targetEl = rootNode; } } return targetEl; } function _getBodyWidth(beans) { const body = _getPageBody(beans); return body?.clientWidth ?? (window.innerHeight || -1); } function _getBodyHeight(beans) { const body = _getPageBody(beans); return body?.clientHeight ?? (window.innerHeight || -1); } function _anchorElementToMouseMoveEvent(element, mouseMoveEvent, beans) { const eRect = element.getBoundingClientRect(); const height = eRect.height; const browserWidth = _getBodyWidth(beans) - 2; const browserHeight = _getBodyHeight(beans) - 2; const offsetParent = element.offsetParent; if (!offsetParent) { return; } const offsetParentSize = _getElementRectWithOffset(element.offsetParent); const { clientY, clientX } = mouseMoveEvent; let top = clientY - offsetParentSize.top - height / 2; let left = clientX - offsetParentSize.left - 10; const eDocument = _getDocument(beans); const win = eDocument.defaultView || window; const windowScrollY = win.pageYOffset || eDocument.documentElement.scrollTop; const windowScrollX = win.pageXOffset || eDocument.documentElement.scrollLeft; if (browserWidth > 0 && left + element.clientWidth > browserWidth + windowScrollX) { left = browserWidth + windowScrollX - element.clientWidth; } if (left < 0) { left = 0; } if (browserHeight > 0 && top + element.clientHeight > browserHeight + windowScrollY) { top = browserHeight + windowScrollY - element.clientHeight; } if (top < 0) { top = 0; } element.style.left = `${left}px`; element.style.top = `${top}px`; } function _isNothingFocused(beans) { const eDocument = _getDocument(beans); const activeEl = _getActiveDomElement(beans); return activeEl === null || activeEl === eDocument.body; } function _isAnimateRows(gos) { if (gos.get("ensureDomOrder")) { return false; } return gos.get("animateRows"); } function _isGroupRowsSticky(gos) { if (gos.get("paginateChildRows") || gos.get("groupHideOpenParents") || _isDomLayout(gos, "print")) { return false; } return true; } function _isColumnsSortingCoupledToGroup(gos) { const autoGroupColumnDef = gos.get("autoGroupColumnDef"); return !autoGroupColumnDef?.comparator && !gos.get("treeData"); } function _getGroupAggFiltering(gos) { const userValue = gos.get("groupAggFiltering"); if (typeof userValue === "function") { return gos.getCallback("groupAggFiltering"); } if (userValue === true) { return () => true; } return void 0; } function _getGrandTotalRow(gos) { return gos.get("grandTotalRow"); } function _getGroupTotalRowCallback(gos) { const userValue = gos.get("groupTotalRow"); if (typeof userValue === "function") { return gos.getCallback("groupTotalRow"); } return () => userValue ?? void 0; } function _isGroupMultiAutoColumn(gos) { if (gos.exists("groupDisplayType")) { return gos.get("groupDisplayType") === "multipleColumns"; } return gos.get("groupHideOpenParents"); } function _isGroupUseEntireRow(gos, pivotMode) { if (pivotMode) { return false; } return gos.get("groupDisplayType") === "groupRows"; } function _getRowIdCallback(gos) { const getRowId = gos.getCallback("getRowId"); if (getRowId === void 0) { return getRowId; } return (params) => { let id = getRowId(params); if (typeof id !== "string") { _warn(25, { id }); id = String(id); } return id; }; } function _canSkipShowingRowGroup(gos, node) { const isSkippingGroups = gos.get("groupHideParentOfSingleChild"); if (isSkippingGroups === true) { return true; } if (isSkippingGroups === "leafGroupsOnly" && node.leafGroup) { return true; } if (gos.get("groupRemoveSingleChildren")) { return true; } if (gos.get("groupRemoveLowestSingleChildren") && node.leafGroup) { return true; } return false; } function _getMaxConcurrentDatasourceRequests(gos) { const res = gos.get("maxConcurrentDatasourceRequests"); return res > 0 ? res : void 0; } function _shouldUpdateColVisibilityAfterGroup(gos, isGrouped) { const preventVisibilityChanges = gos.get("suppressGroupChangesColumnVisibility"); if (preventVisibilityChanges === true) { return false; } if (isGrouped && preventVisibilityChanges === "suppressHideOnGroup") { return false; } if (!isGrouped && preventVisibilityChanges === "suppressShowOnUngroup") { return false; } const legacySuppressOnGroup = gos.get("suppressRowGroupHidesColumns"); if (isGrouped && legacySuppressOnGroup === true) { return false; } const legacySuppressOnUngroup = gos.get("suppressMakeColumnVisibleAfterUnGroup"); if (!isGrouped && legacySuppressOnUngroup === true) { return false; } return true; } function _getCheckboxes(selection) { return selection?.checkboxes ?? true; } function _getHeaderCheckbox(selection) { return selection?.mode === "multiRow" && (selection.headerCheckbox ?? true); } function _getCheckboxLocation(rowSelection) { if (typeof rowSelection !== "object") { return void 0; } return rowSelection.checkboxLocation ?? "selectionColumn"; } function _getHideDisabledCheckboxes(selection) { return selection?.hideDisabledCheckboxes ?? false; } function _isUsingNewRowSelectionAPI(gos) { const rowSelection = gos.get("rowSelection"); return typeof rowSelection !== "string"; } function _isUsingNewCellSelectionAPI(gos) { return gos.get("cellSelection") !== void 0; } function _getSuppressMultiRanges(gos) { const selection = gos.get("cellSelection"); const useNewAPI = selection !== void 0; if (!useNewAPI) { return gos.get("suppressMultiRangeSelection"); } return typeof selection !== "boolean" ? selection?.suppressMultiRanges ?? false : false; } function _isCellSelectionEnabled(gos) { const selection = gos.get("cellSelection"); const useNewAPI = selection !== void 0; return useNewAPI ? !!selection : gos.get("enableRangeSelection"); } function _getFillHandle(gos) { const selection = gos.get("cellSelection"); const useNewAPI = selection !== void 0; if (!useNewAPI) { return { mode: "fill", setFillValue: gos.get("fillOperation"), direction: gos.get("fillHandleDirection"), suppressClearOnFillReduction: gos.get("suppressClearOnFillReduction") }; } return typeof selection !== "boolean" && selection.handle?.mode === "fill" ? selection.handle : void 0; } function _getEnableClickSelection(gos) { const selection = gos.get("rowSelection") ?? "single"; if (typeof selection === "string") { const suppressRowClickSelection = gos.get("suppressRowClickSelection"); const suppressRowDeselection = gos.get("suppressRowDeselection"); if (suppressRowClickSelection && suppressRowDeselection) { return false; } else if (suppressRowClickSelection) { return "enableDeselection"; } else if (suppressRowDeselection) { return "enableSelection"; } else { return true; } } return selection.mode === "singleRow" || selection.mode === "multiRow" ? selection.enableClickSelection ?? false : false; } function _getEnableSelection(gos) { const enableClickSelection = _getEnableClickSelection(gos); return enableClickSelection === true || enableClickSelection === "enableSelection"; } function _getEnableDeselection(gos) { const enableClickSelection = _getEnableClickSelection(gos); return enableClickSelection === true || enableClickSelection === "enableDeselection"; } function _getIsRowSelectable(gos) { const selection = gos.get("rowSelection"); if (typeof selection === "string") { return gos.get("isRowSelectable"); } return selection?.isRowSelectable; } function _getRowSelectionMode(arg) { const selection = "beanName" in arg && arg.beanName === "gos" ? arg.get("rowSelection") : arg.rowSelection; if (typeof selection === "string") { switch (selection) { case "multiple": return "multiRow"; case "single": return "singleRow"; default: return; } } switch (selection?.mode) { case "multiRow": case "singleRow": return selection.mode; default: return; } } function _isMultiRowSelection(arg) { const mode = _getRowSelectionMode(arg); return mode === "multiRow"; } function _getEnableSelectionWithoutKeys(gos) { const selection = gos.get("rowSelection"); if (typeof selection === "string") { return gos.get("rowMultiSelectWithClick"); } return selection?.enableSelectionWithoutKeys ?? false; } function _getGroupSelection(gos) { const selection = gos.get("rowSelection"); if (typeof selection === "string") { const groupSelectsChildren = gos.get("groupSelectsChildren"); const groupSelectsFiltered = gos.get("groupSelectsFiltered"); if (groupSelectsChildren && groupSelectsFiltered) { return "filteredDescendants"; } else if (groupSelectsChildren) { return "descendants"; } else { return "self"; } } return selection?.mode === "multiRow" ? selection.groupSelects : void 0; } function _getSelectAll(gos, defaultValue = true) { const rowSelection = gos.get("rowSelection"); if (typeof rowSelection !== "object") { return defaultValue ? "all" : void 0; } return rowSelection.mode === "multiRow" ? rowSelection.selectAll : "all"; } function _getGroupSelectsDescendants(gos) { const groupSelection = _getGroupSelection(gos); return groupSelection === "descendants" || groupSelection === "filteredDescendants"; } function _getMasterSelects(gos) { const rowSelection = gos.get("rowSelection"); return typeof rowSelection === "object" && rowSelection.masterSelects || "self"; } function _isSetFilterByDefault(gos) { return gos.isModuleRegistered("SetFilter") && !gos.get("suppressSetFilterByDefault"); } function _isLegacyMenuEnabled(gos) { return gos.get("columnMenu") === "legacy"; } function _isColumnMenuAnchoringEnabled(gos) { return !_isLegacyMenuEnabled(gos); } function _getCallbackForEvent(eventName) { if (!eventName || eventName.length < 2) { return eventName; } return "on" + eventName[0].toUpperCase() + eventName.substring(1); } function _combineAttributesAndGridOptions(gridOptions, component, gridOptionsKeys) { if (typeof gridOptions !== "object") { gridOptions = {}; } const mergedOptions = { ...gridOptions }; gridOptionsKeys.forEach((key) => { const value = component[key]; if (typeof value !== "undefined") { mergedOptions[key] = value; } }); return mergedOptions; } function _processOnChange(changes, api) { if (!changes) { return; } const gridChanges = {}; let hasChanges = false; Object.keys(changes).forEach((key) => { gridChanges[key] = changes[key]; hasChanges = true; }); if (!hasChanges) { return; } const internalUpdateEvent = { type: "gridOptionsChanged", options: gridChanges }; api.dispatchEvent(internalUpdateEvent); const event = { type: "componentStateChanged", ...gridChanges }; api.dispatchEvent(event); } function _addGridCommonParams(gos, params) { return gos.addGridCommonParams(params); } // packages/ag-grid-community/src/utils/event.ts var AG_GRID_STOP_PROPAGATION = "__ag_Grid_Stop_Propagation"; var PASSIVE_EVENTS = ["touchstart", "touchend", "touchmove", "touchcancel", "scroll"]; var NON_PASSIVE_EVENTS = ["wheel"]; var supports = {}; function _stopPropagationForAgGrid(event) { event[AG_GRID_STOP_PROPAGATION] = true; } function _isStopPropagationForAgGrid(event) { return event[AG_GRID_STOP_PROPAGATION] === true; } var _isEventSupported = /* @__PURE__ */ (() => { const tags = { select: "input", change: "input", submit: "form", reset: "form", error: "img", load: "img", abort: "img" }; const eventChecker = (eventName) => { if (typeof supports[eventName] === "boolean") { return supports[eventName]; } const el = document.createElement(tags[eventName] || "div"); eventName = "on" + eventName; return supports[eventName] = eventName in el; }; return eventChecker; })(); function _getCtrlForEventTarget(gos, eventTarget, type) { let sourceElement = eventTarget; while (sourceElement) { const renderedComp = _getDomData(gos, sourceElement, type); if (renderedComp) { return renderedComp; } sourceElement = sourceElement.parentElement; } return null; } function _isElementInEventPath(element, event) { if (!event || !element) { return false; } return _getEventPath(event).indexOf(element) >= 0; } function _createEventPath(event) { const res = []; let pointer = event.target; while (pointer) { res.push(pointer); pointer = pointer.parentElement; } return res; } function _getEventPath(event) { const eventNoType = event; if (eventNoType.path) { return eventNoType.path; } if (eventNoType.composedPath) { return eventNoType.composedPath(); } return _createEventPath(eventNoType); } function _addSafePassiveEventListener(frameworkOverrides, eElement, event, listener) { const passive = getPassiveStateForEvent(event); let options; if (passive != null) { options = { passive }; } if (frameworkOverrides && frameworkOverrides.addEventListener) { frameworkOverrides.addEventListener(eElement, event, listener, options); } } var getPassiveStateForEvent = (event) => { const isPassive = PASSIVE_EVENTS.includes(event); const isNonPassive = NON_PASSIVE_EVENTS.includes(event); if (isPassive) { return true; } if (isNonPassive) { return false; } }; // packages/ag-grid-community/src/context/beanStub.ts var BeanStub = class { constructor() { // not named context to allow children to use 'context' as a variable name this.destroyFunctions = []; this.destroyed = false; // for vue 3 - prevents Vue from trying to make this (and obviously any sub classes) from being reactive // prevents vue from creating proxies for created objects and prevents identity related issues this.__v_skip = true; this.propertyListenerId = 0; // Enable multiple grid properties to be updated together by the user but only trigger shared logic once. // Closely related to logic in GridOptionsUtils.ts _processOnChange this.lastChangeSetIdLookup = {}; this.isAlive = () => !this.destroyed; } preWireBeans(beans) { this.beans = beans; this.stubContext = beans.context; this.eventSvc = beans.eventSvc; this.gos = beans.gos; } // this was a test constructor niall built, when active, it prints after 5 seconds all beans/components that are // not destroyed. to use, create a new grid, then api.destroy() before 5 seconds. then anything that gets printed // points to a bean or component that was not properly disposed of. // constructor() { // setTimeout(()=> { // if (this.isAlive()) { // let prototype: any = Object.getPrototypeOf(this); // const constructor: any = prototype.constructor; // const constructorString = constructor.toString(); // const beanName = constructorString.substring(9, constructorString.indexOf("(")); // console.log('is alive ' + beanName); // } // }, 5000); // } destroy() { const { destroyFunctions } = this; for (let i = 0; i < destroyFunctions.length; i++) { destroyFunctions[i](); } destroyFunctions.length = 0; this.destroyed = true; this.dispatchLocalEvent({ type: "destroyed" }); } // The typing of AgEventListener is not ideal, but it's the best we can do at the moment to enable // eventSvc to have the best typing at the expense of BeanStub local events /** Add a local event listener against this BeanStub */ addEventListener(eventType, listener, async) { if (!this.localEventService) { this.localEventService = new LocalEventService(); } this.localEventService.addEventListener(eventType, listener, async); } /** Remove a local event listener from this BeanStub */ removeEventListener(eventType, listener, async) { this.localEventService?.removeEventListener(eventType, listener, async); } dispatchLocalEvent(event) { this.localEventService?.dispatchEvent(event); } addManagedElementListeners(object, handlers) { return this._setupListeners(object, handlers); } addManagedEventListeners(handlers) { return this._setupListeners(this.eventSvc, handlers); } addManagedListeners(object, handlers) { return this._setupListeners(object, handlers); } _setupListeners(object, handlers) { const destroyFuncs = []; for (const k of Object.keys(handlers)) { const handler = handlers[k]; if (handler) { destroyFuncs.push(this._setupListener(object, k, handler)); } } return destroyFuncs; } _setupListener(object, event, listener) { if (this.destroyed) { return () => null; } let destroyFunc; if (isAgEventEmitter(object)) { object.__addEventListener(event, listener); destroyFunc = () => { object.__removeEventListener(event, listener); return null; }; } else { if (object instanceof HTMLElement) { _addSafePassiveEventListener(this.beans.frameworkOverrides, object, event, listener); } else { object.addEventListener(event, listener); } destroyFunc = () => { object.removeEventListener(event, listener); return null; }; } this.destroyFunctions.push(destroyFunc); return () => { destroyFunc(); this.destroyFunctions = this.destroyFunctions.filter((fn) => fn !== destroyFunc); return null; }; } /** * Setup a managed property listener for the given GridOption property. * However, stores the destroy function in the beanStub so that if this bean * is a component the destroy function will be called when the component is destroyed * as opposed to being cleaned up only when the GridOptionsService is destroyed. */ setupGridOptionListener(event, listener) { const { gos } = this; gos.addPropertyEventListener(event, listener); const destroyFunc = () => { gos.removePropertyEventListener(event, listener); return null; }; this.destroyFunctions.push(destroyFunc); return () => { destroyFunc(); this.destroyFunctions = this.destroyFunctions.filter((fn) => fn !== destroyFunc); return null; }; } /** * Setup a managed property listener for the given GridOption property. * @param event GridOption property to listen to changes for. * @param listener Listener to run when property value changes */ addManagedPropertyListener(event, listener) { if (this.destroyed) { return () => null; } return this.setupGridOptionListener(event, listener); } /** * Setup managed property listeners for the given set of GridOption properties. * The listener will be run if any of the property changes but will only run once if * multiple of the properties change within the same framework lifecycle event. * Works on the basis that GridOptionsService updates all properties *before* any property change events are fired. * @param events Array of GridOption properties to listen for changes too. * @param listener Shared listener to run if any of the properties change */ addManagedPropertyListeners(events, listener) { if (this.destroyed) { return; } const eventsKey = events.join("-") + this.propertyListenerId++; const wrappedListener = (event) => { if (event.changeSet) { if (event.changeSet && event.changeSet.id === this.lastChangeSetIdLookup[eventsKey]) { return; } this.lastChangeSetIdLookup[eventsKey] = event.changeSet.id; } const propertiesChangeEvent = { type: "gridPropertyChanged", changeSet: event.changeSet, source: event.source }; listener(propertiesChangeEvent); }; events.forEach((event) => this.setupGridOptionListener(event, wrappedListener)); } getLocaleTextFunc() { return _getLocaleTextFunc(this.beans.localeSvc); } addDestroyFunc(func) { if (this.isAlive()) { this.destroyFunctions.push(func); } else { func(); } } /** doesn't throw an error if `bean` is undefined */ createOptionalManagedBean(bean, context) { return bean ? this.createManagedBean(bean, context) : void 0; } createManagedBean(bean, context) { const res = this.createBean(bean, context); this.addDestroyFunc(this.destroyBean.bind(this, bean, context)); return res; } createBean(bean, context, afterPreCreateCallback) { return (context || this.stubContext).createBean(bean, afterPreCreateCallback); } /** * Destroys a bean and returns undefined to support destruction and clean up in a single line. * this.dateComp = this.context.destroyBean(this.dateComp); */ destroyBean(bean, context) { return (context || this.stubContext).destroyBean(bean); } /** * Destroys an array of beans and returns an empty array to support destruction and clean up in a single line. * this.dateComps = this.context.destroyBeans(this.dateComps); */ destroyBeans(beans, context) { return (context || this.stubContext).destroyBeans(beans); } }; function isAgEventEmitter(object) { return object.__addEventListener !== void 0; } // packages/ag-grid-community/src/utils/object.ts var SKIP_JS_BUILTINS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]); function _iterateObject(object, callback) { if (object == null) { return; } if (Array.isArray(object)) { for (let i = 0; i < object.length; i++) { callback(i.toString(), object[i]); } return; } for (const key of Object.keys(object)) { callback(key, object[key]); } } function _mergeDeep(dest, source, copyUndefined = true, makeCopyOfSimpleObjects = false) { if (!_exists(source)) { return; } _iterateObject(source, (key, sourceValue) => { if (SKIP_JS_BUILTINS.has(key)) { return; } let destValue = dest[key]; if (destValue === sourceValue) { return; } if (makeCopyOfSimpleObjects) { const objectIsDueToBeCopied = destValue == null && sourceValue != null; if (objectIsDueToBeCopied) { const doNotCopyAsSourceIsSimpleObject = typeof sourceValue === "object" && sourceValue.constructor === Object; if (doNotCopyAsSourceIsSimpleObject) { destValue = {}; dest[key] = destValue; } } } if (_isNonNullObject(sourceValue) && _isNonNullObject(destValue) && !Array.isArray(destValue)) { _mergeDeep(destValue, sourceValue, copyUndefined, makeCopyOfSimpleObjects); } else if (copyUndefined || sourceValue !== void 0) { dest[key] = sourceValue; } }); } function _getValueUsingField(data, field, fieldContainsDots) { if (!field || !data) { return; } if (!fieldContainsDots) { return data[field]; } const fields = field.split("."); let currentObject = data; for (let i = 0; i < fields.length; i++) { if (currentObject == null) { return void 0; } currentObject = currentObject[fields[i]]; } return currentObject; } function _isNonNullObject(value) { return typeof value === "object" && value !== null; } // packages/ag-grid-community/src/utils/string.ts var reUnescapedHtml = /[&<>"']/g; var HTML_ESCAPES = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }; function _escapeString(toEscape, skipEscapingHtmlChars) { if (toEscape == null) { return null; } const stringResult = toEscape.toString().toString(); if (skipEscapingHtmlChars) { return stringResult; } return stringResult.replace(reUnescapedHtml, (chr) => HTML_ESCAPES[chr]); } // packages/ag-grid-community/src/entities/agColumn.ts var COL_DEF_DEFAULTS = { resizable: true, sortable: true }; var instanceIdSequence = 0; function getNextColInstanceId() { return instanceIdSequence++; } function isColumn(col) { return col instanceof AgColumn; } var AgColumn = class extends BeanStub { constructor(colDef, userProvidedColDef, colId, primary) { super(); this.colDef = colDef; this.userProvidedColDef = userProvidedColDef; this.colId = colId; this.primary = primary; this.isColumn = true; // used by React (and possibly other frameworks) as key for rendering. also used to // identify old vs new columns for destroying cols when no longer used. this.instanceId = getNextColInstanceId(); // The measured height of this column's header when autoHeaderHeight is enabled this.autoHeaderHeight = null; this.moving = false; this.menuVisible = false; this.lastLeftPinned = false; this.firstRightPinned = false; this.filterActive = false; this.colEventSvc = new LocalEventService(); this.tooltipEnabled = false; this.rowGroupActive = false; this.pivotActive = false; this.aggregationActive = false; this.flex = null; this.colIdSanitised = _escapeString(colId); } destroy() { super.destroy(); this.beans.rowSpanSvc?.deregister(this); } getInstanceId() { return this.instanceId; } setState() { const { colDef, beans: { sortSvc, pinnedCols, colFlex } } = this; sortSvc?.initCol(this); const hide = colDef.hide; if (hide !== void 0) { this.visible = !hide; } else { this.visible = !colDef.initialHide; } pinnedCols?.initCol(this); colFlex?.initCol(this); } // gets called when user provides an alternative colDef, eg setColDef(colDef, userProvidedColDef, source) { const colSpanChanged = colDef.spanRows !== this.colDef.spanRows; this.colDef = colDef; this.userProvidedColDef = userProvidedColDef; this.initMinAndMaxWidths(); this.initDotNotation(); this.initTooltip(); if (colSpanChanged) { this.beans.rowSpanSvc?.deregister(this); this.initRowSpan(); } this.dispatchColEvent("colDefChanged", source); } getUserProvidedColDef() { return this.userProvidedColDef; } getParent() { return this.parent; } getOriginalParent() { return this.originalParent; } // this is done after constructor as it uses gridOptionsService postConstruct() { this.setState(); this.initMinAndMaxWidths(); this.resetActualWidth("gridInitializing"); this.initDotNotation(); this.initTooltip(); this.initRowSpan(); } initDotNotation() { const { gos, colDef: { field, tooltipField } } = this; const suppressDotNotation = gos.get("suppressFieldDotNotation"); this.fieldContainsDots = _exists(field) && field.indexOf(".") >= 0 && !suppressDotNotation; this.tooltipFieldContainsDots = _exists(tooltipField) && tooltipField.indexOf(".") >= 0 && !suppressDotNotation; } initMinAndMaxWidths() { const colDef = this.colDef; this.minWidth = colDef.minWidth ?? this.beans.environment.getDefaultColumnMinWidth(); this.maxWidth = colDef.maxWidth ?? Number.MAX_SAFE_INTEGER; } initTooltip() { this.beans.tooltipSvc?.initCol(this); } initRowSpan() { if (this.colDef.spanRows) { this.beans.rowSpanSvc?.register(this); } } resetActualWidth(source) { const initialWidth = this.calculateColInitialWidth(this.colDef); this.setActualWidth(initialWidth, source, true); } calculateColInitialWidth(colDef) { let width; const colDefWidth = colDef.width; const colDefInitialWidth = colDef.initialWidth; if (colDefWidth != null) { width = colDefWidth; } else if (colDefInitialWidth != null) { width = colDefInitialWidth; } else { width = 200; } return Math.max(Math.min(width, this.maxWidth), this.minWidth); } isEmptyGroup() { return false; } isRowGroupDisplayed(colId) { return this.beans.showRowGroupCols?.isRowGroupDisplayed(this, colId) ?? false; } isPrimary() { return this.primary; } isFilterAllowed() { const filterDefined = !!this.colDef.filter; return filterDefined; } isFieldContainsDots() { return this.fieldContainsDots; } isTooltipEnabled() { return this.tooltipEnabled; } isTooltipFieldContainsDots() { return this.tooltipFieldContainsDots; } getHighlighted() { return this.highlighted; } __addEventListener(eventType, listener) { this.colEventSvc.addEventListener(eventType, listener); } __removeEventListener(eventType, listener) { this.colEventSvc.removeEventListener(eventType, listener); } /** * PUBLIC USE ONLY: for internal use within AG Grid use the `__addEventListener` and `__removeEventListener` methods. */ addEventListener(eventType, userListener) { this.frameworkEventListenerService = this.beans.frameworkOverrides.createLocalEventListenerWrapper?.( this.frameworkEventListenerService, this.colEventSvc ); const listener = this.frameworkEventListenerService?.wrap(userListener) ?? userListener; this.colEventSvc.addEventListener(eventType, listener); } /** * PUBLIC USE ONLY: for internal use within AG Grid use the `__addEventListener` and `__removeEventListener` methods. */ removeEventListener(eventType, userListener) { const listener = this.frameworkEventListenerService?.unwrap(userListener) ?? userListener; this.colEventSvc.removeEventListener(eventType, listener); } createColumnFunctionCallbackParams(rowNode) { return _addGridCommonParams(this.gos, { node: rowNode, data: rowNode.data, column: this, colDef: this.colDef }); } isSuppressNavigable(rowNode) { return this.beans.cellNavigation?.isSuppressNavigable(this, rowNode) ?? false; } isCellEditable(rowNode) { return this.beans.editSvc?.isCellEditable(this, rowNode) ?? false; } isSuppressFillHandle() { return !!this.colDef.suppressFillHandle; } isAutoHeight() { return !!this.colDef.autoHeight; } isAutoHeaderHeight() { return !!this.colDef.autoHeaderHeight; } isRowDrag(rowNode) { return this.isColumnFunc(rowNode, this.colDef.rowDrag); } isDndSource(rowNode) { return this.isColumnFunc(rowNode, this.colDef.dndSource); } isCellCheckboxSelection(rowNode) { return this.beans.selectionSvc?.isCellCheckboxSelection(this, rowNode) ?? false; } isSuppressPaste(rowNode) { return this.isColumnFunc(rowNode, this.colDef?.suppressPaste ?? null); } isResizable() { return !!this.getColDefValue("resizable"); } /** Get value from ColDef or default if it exists. */ getColDefValue(key) { return this.colDef[key] ?? COL_DEF_DEFAULTS[key]; } isColumnFunc(rowNode, value) { if (typeof value === "boolean") { return value; } if (typeof value === "function") { const params = this.createColumnFunctionCallbackParams(rowNode); const editableFunc = value; return editableFunc(params); } return false; } createColumnEvent(type, source) { return _addGridCommonParams(this.gos, { type, column: this, columns: [this], source }); } isMoving() { return this.moving; } getSort() { return this.sort; } isSortable() { return !!this.getColDefValue("sortable"); } /** @deprecated v32 use col.getSort() === 'asc */ isSortAscending() { return this.sort === "asc"; } /** @deprecated v32 use col.getSort() === 'desc */ isSortDescending() { return this.sort === "desc"; } /** @deprecated v32 use col.getSort() === undefined */ isSortNone() { return _missing(this.sort); } /** @deprecated v32 use col.getSort() !== undefined */ isSorting() { return _exists(this.sort); } getSortIndex() { return this.sortIndex; } isMenuVisible() { return this.menuVisible; } getAggFunc() { return this.aggFunc; } getLeft() { return this.left; } getOldLeft() { return this.oldLeft; } getRight() { return this.left + this.actualWidth; } setLeft(left, source) { this.oldLeft = this.left; if (this.left !== left) { this.left = left; this.dispatchColEvent("leftChanged", source); } } isFilterActive() { return this.filterActive; } /** @deprecated v33 Use `api.isColumnHovered(column)` instead. */ isHovered() { _warn(261); return !!this.beans.colHover?.isHovered(this); } setFirstRightPinned(firstRightPinned, source) { if (this.firstRightPinned !== firstRightPinned) { this.firstRightPinned = firstRightPinned; this.dispatchColEvent("firstRightPinnedChanged", source); } } setLastLeftPinned(lastLeftPinned, source) { if (this.lastLeftPinned !== lastLeftPinned) { this.lastLeftPinned = lastLeftPinned; this.dispatchColEvent("lastLeftPinnedChanged", source); } } isFirstRightPinned() { return this.firstRightPinned; } isLastLeftPinned() { return this.lastLeftPinned; } isPinned() { return this.pinned === "left" || this.pinned === "right"; } isPinnedLeft() { return this.pinned === "left"; } isPinnedRight() { return this.pinned === "right"; } getPinned() { return this.pinned; } setVisible(visible, source) { const newValue = visible === true; if (this.visible !== newValue) { this.visible = newValue; this.dispatchColEvent("visibleChanged", source); } this.dispatchStateUpdatedEvent("hide"); } isVisible() { return this.visible; } isSpanHeaderHeight() { const colDef = this.getColDef(); return !colDef.suppressSpanHeaderHeight; } getColumnGroupPaddingInfo() { let parent = this.getParent(); if (!parent || !parent.isPadding()) { return { numberOfParents: 0, isSpanningTotal: false }; } const numberOfParents = parent.getPaddingLevel() + 1; let isSpanningTotal = true; while (parent) { if (!parent.isPadding()) { isSpanningTotal = false; break; } parent = parent.getParent(); } return { numberOfParents, isSpanningTotal }; } getColDef() { return this.colDef; } getDefinition() { return this.colDef; } getColumnGroupShow() { return this.colDef.columnGroupShow; } getColId() { return this.colId; } getId() { return this.colId; } getUniqueId() { return this.colId; } getActualWidth() { return this.actualWidth; } getAutoHeaderHeight() { return this.autoHeaderHeight; } /** Returns true if the header height has changed */ setAutoHeaderHeight(height) { const changed = height !== this.autoHeaderHeight; this.autoHeaderHeight = height; return changed; } createBaseColDefParams(rowNode) { const params = _addGridCommonParams(this.gos, { node: rowNode, data: rowNode.data, colDef: this.colDef, column: this }); return params; } getColSpan(rowNode) { if (_missing(this.colDef.colSpan)) { return 1; } const params = this.createBaseColDefParams(rowNode); const colSpan = this.colDef.colSpan(params); return Math.max(colSpan, 1); } getRowSpan(rowNode) { if (_missing(this.colDef.rowSpan)) { return 1; } const params = this.createBaseColDefParams(rowNode); const rowSpan = this.colDef.rowSpan(params); return Math.max(rowSpan, 1); } setActualWidth(actualWidth, source, silent = false) { actualWidth = Math.max(actualWidth, this.minWidth); actualWidth = Math.min(actualWidth, this.maxWidth); if (this.actualWidth !== actualWidth) { this.actualWidth = actualWidth; if (this.flex != null && source !== "flex" && source !== "gridInitializing") { this.flex = null; } if (!silent) { this.fireColumnWidthChangedEvent(source); } } this.dispatchStateUpdatedEvent("width"); } fireColumnWidthChangedEvent(source) { this.dispatchColEvent("widthChanged", source); } isGreaterThanMax(width) { return width > this.maxWidth; } getMinWidth() { return this.minWidth; } getMaxWidth() { return this.maxWidth; } getFlex() { return this.flex; } isRowGroupActive() { return this.rowGroupActive; } isPivotActive() { return this.pivotActive; } isAnyFunctionActive() { return this.isPivotActive() || this.isRowGroupActive() || this.isValueActive(); } isAnyFunctionAllowed() { return this.isAllowPivot() || this.isAllowRowGroup() || this.isAllowValue(); } isValueActive() { return this.aggregationActive; } isAllowPivot() { return this.colDef.enablePivot === true; } isAllowValue() { return this.colDef.enableValue === true; } isAllowRowGroup() { return this.colDef.enableRowGroup === true; } dispatchColEvent(type, source, additionalEventAttributes) { const colEvent = this.createColumnEvent(type, source); if (additionalEventAttributes) { _mergeDeep(colEvent, additionalEventAttributes); } this.colEventSvc.dispatchEvent(colEvent); } dispatchStateUpdatedEvent(key) { this.colEventSvc.dispatchEvent({ type: "columnStateUpdated", key }); } }; // packages/ag-grid-community/src/entities/agProvidedColumnGroup.ts function isProvidedColumnGroup(col) { return col instanceof AgProvidedColumnGroup; } var AgProvidedColumnGroup = class extends BeanStub { constructor(colGroupDef, groupId, padding, level) { super(); this.colGroupDef = colGroupDef; this.groupId = groupId; this.padding = padding; this.level = level; this.isColumn = false; this.expandable = false; // used by React (and possibly other frameworks) as key for rendering. also used to // identify old vs new columns for destroying cols when no longer used. this.instanceId = getNextColInstanceId(); this.expandableListenerRemoveCallback = null; this.expanded = !!colGroupDef?.openByDefault; } destroy() { if (this.expandableListenerRemoveCallback) { this.reset(null, void 0); } super.destroy(); } reset(colGroupDef, level) { this.colGroupDef = colGroupDef; this.level = level; this.originalParent = null; if (this.expandableListenerRemoveCallback) { this.expandableListenerRemoveCallback(); } this.children = void 0; this.expandable = void 0; } getInstanceId() { return this.instanceId; } getOriginalParent() { return this.originalParent; } getLevel() { return this.level; } isVisible() { if (this.children) { return this.children.some((child) => child.isVisible()); } return false; } isPadding() { return this.padding; } setExpanded(expanded) { this.expanded = expanded === void 0 ? false : expanded; this.dispatchLocalEvent({ type: "expandedChanged" }); } isExpandable() { return this.expandable; } isExpanded() { return this.expanded; } getGroupId() { return this.groupId; } getId() { return this.getGroupId(); } setChildren(children) { this.children = children; } getChildren() { return this.children; } getColGroupDef() { return this.colGroupDef; } getLeafColumns() { const result = []; this.addLeafColumns(result); return result; } addLeafColumns(leafColumns) { if (!this.children) { return; } this.children.forEach((child) => { if (isColumn(child)) { leafColumns.push(child); } else if (isProvidedColumnGroup(child)) { child.addLeafColumns(leafColumns); } }); } getColumnGroupShow() { const colGroupDef = this.colGroupDef; if (!colGroupDef) { return; } return colGroupDef.columnGroupShow; } // need to check that this group has at least one col showing when both expanded and contracted. // if not, then we don't allow expanding and contracting on this group setupExpandable() { this.setExpandable(); if (this.expandableListenerRemoveCallback) { this.expandableListenerRemoveCallback(); } const listener = this.onColumnVisibilityChanged.bind(this); this.getLeafColumns().forEach((col) => col.__addEventListener("visibleChanged", listener)); this.expandableListenerRemoveCallback = () => { this.getLeafColumns().forEach((col) => col.__removeEventListener("visibleChanged", listener)); this.expandableListenerRemoveCallback = null; }; } setExpandable() { if (this.isPadding()) { return; } let atLeastOneShowingWhenOpen = false; let atLeastOneShowingWhenClosed = false; let atLeastOneChangeable = false; const children = this.findChildrenRemovingPadding(); for (let i = 0, j = children.length; i < j; i++) { const abstractColumn = children[i]; if (!abstractColumn.isVisible()) { continue; } const headerGroupShow = abstractColumn.getColumnGroupShow(); if (headerGroupShow === "open") { atLeastOneShowingWhenOpen = true; atLeastOneChangeable = true; } else if (headerGroupShow === "closed") { atLeastOneShowingWhenClosed = true; atLeastOneChangeable = true; } else { atLeastOneShowingWhenOpen = true; atLeastOneShowingWhenClosed = true; } } const expandable = atLeastOneShowingWhenOpen && atLeastOneShowingWhenClosed && atLeastOneChangeable; if (this.expandable !== expandable) { this.expandable = expandable; this.dispatchLocalEvent({ type: "expandableChanged" }); } } findChildrenRemovingPadding() { const res = []; const process = (items) => { items.forEach((item) => { const skipBecausePadding = isProvidedColumnGroup(item) && item.isPadding(); if (skipBecausePadding) { process(item.children); } else { res.push(item); } }); }; process(this.children); return res; } onColumnVisibilityChanged() { this.setExpandable(); } }; // packages/ag-grid-community/src/entities/defaultColumnTypes.ts var DefaultColumnTypes = { numericColumn: { headerClass: "ag-right-aligned-header", cellClass: "ag-right-aligned-cell" }, rightAligned: { headerClass: "ag-right-aligned-header", cellClass: "ag-right-aligned-cell" } }; // packages/ag-grid-community/src/columns/columnKeyCreator.ts var ColumnKeyCreator = class { constructor() { this.existingKeys = {}; } addExistingKeys(keys) { for (let i = 0; i < keys.length; i++) { this.existingKeys[keys[i]] = true; } } getUniqueKey(colId, colField) { colId = _toStringOrNull(colId); let count = 0; while (true) { let idToTry = colId ?? colField; if (idToTry) { if (count !== 0) { idToTry += "_" + count; } } else { idToTry = count; } if (!this.existingKeys[idToTry]) { this.existingKeys[idToTry] = true; return String(idToTry); } count++; } } }; // packages/ag-grid-community/src/utils/array.ts var _EmptyArray = Object.freeze([]); function _last(arr) { if (!arr?.length) { return; } return arr[arr.length - 1]; } function _areEqual(a, b, comparator) { if (a == null && b == null) { return true; } return a != null && b != null && a.length === b.length && a.every((value, index) => comparator ? comparator(value, b[index]) : b[index] === value); } function _sortNumerically(array) { return array.sort((a, b) => a - b); } function _removeFromArray(array, object) { const index = array.indexOf(object); if (index >= 0) { array.splice(index, 1); } } function _moveInArray(array, objectsToMove, toIndex) { for (let i = 0; i < objectsToMove.length; i++) { _removeFromArray(array, objectsToMove[i]); } for (let i = objectsToMove.length - 1; i >= 0; i--) { array.splice(toIndex, 0, objectsToMove[i]); } } // packages/ag-grid-community/src/columns/columnUtils.ts var GROUP_AUTO_COLUMN_ID = "ag-Grid-AutoColumn"; var SELECTION_COLUMN_ID = "ag-Grid-SelectionColumn"; var ROW_NUMBERS_COLUMN_ID = "ag-Grid-RowNumbersColumn"; function _getColumnsFromTree(rootColumns) { const result = []; const recursiveFindColumns = (childColumns) => { for (let i = 0; i < childColumns.length; i++) { const child = childColumns[i]; if (isColumn(child)) { result.push(child); } else if (isProvidedColumnGroup(child)) { recursiveFindColumns(child.getChildren()); } } }; recursiveFindColumns(rootColumns); return result; } function getWidthOfColsInList(columnList) { return columnList.reduce((width, col) => width + col.getActualWidth(), 0); } function _destroyColumnTree(beans, oldTree, newTree) { const oldObjectsById = {}; if (!oldTree) { return; } depthFirstOriginalTreeSearch(null, oldTree, (child) => { oldObjectsById[child.getInstanceId()] = child; }); if (newTree) { depthFirstOriginalTreeSearch(null, newTree, (child) => { oldObjectsById[child.getInstanceId()] = null; }); } const colsToDestroy = Object.values(oldObjectsById).filter((item) => item != null); beans.context.destroyBeans(colsToDestroy); } function isColumnGroupAutoCol(col) { const colId = col.getId(); return colId.startsWith(GROUP_AUTO_COLUMN_ID); } function isColumnSelectionCol(col) { const id = typeof col === "string" ? col : "getColId" in col ? col.getColId() : col.colId; return id?.startsWith(SELECTION_COLUMN_ID) ?? false; } function isRowNumberCol(col) { const id = typeof col === "string" ? col : "getColId" in col ? col.getColId() : col.colId; return id?.startsWith(ROW_NUMBERS_COLUMN_ID) ?? false; } function convertColumnTypes(type) { let typeKeys = []; if (type instanceof Array) { typeKeys = type; } else if (typeof type === "string") { typeKeys = type.split(","); } return typeKeys; } function _areColIdsEqual(colsA, colsB) { return _areEqual(colsA, colsB, (a, b) => a.getColId() === b.getColId()); } function _updateColsMap(cols) { cols.map = {}; cols.list.forEach((col) => cols.map[col.getId()] = col); } function _convertColumnEventSourceType(source) { return source === "gridOptionsUpdated" ? "gridOptionsChanged" : source; } function _columnsMatch(column, key) { const columnMatches = column === key; const colDefMatches = column.getColDef() === key; const idMatches = column.getColId() == key; return columnMatches || colDefMatches || idMatches; } var getValueFactory = (stateItem, defaultState) => (key1, key2) => { const obj = { value1: void 0, value2: void 0 }; let calculated = false; if (stateItem) { if (stateItem[key1] !== void 0) { obj.value1 = stateItem[key1]; calculated = true; } if (_exists(key2) && stateItem[key2] !== void 0) { obj.value2 = stateItem[key2]; calculated = true; } } if (!calculated && defaultState) { if (defaultState[key1] !== void 0) { obj.value1 = defaultState[key1]; } if (_exists(key2) && defaultState[key2] !== void 0) { obj.value2 = defaultState[key2]; } } return obj; }; // packages/ag-grid-community/src/columns/columnFactoryUtils.ts function _createColumnTree(beans, defs = null, primaryColumns, existingTree, source) { const columnKeyCreator = new ColumnKeyCreator(); const { existingCols, existingGroups, existingColKeys } = extractExistingTreeData(existingTree); columnKeyCreator.addExistingKeys(existingColKeys); const unbalancedTree = _recursivelyCreateColumns( beans, defs, 0, primaryColumns, existingCols, columnKeyCreator, existingGroups, source ); const { colGroupSvc } = beans; const treeDept = colGroupSvc?.findMaxDepth(unbalancedTree, 0) ?? 0; const columnTree = colGroupSvc ? colGroupSvc.balanceColumnTree(unbalancedTree, 0, treeDept, columnKeyCreator) : unbalancedTree; const deptFirstCallback = (child, parent) => { if (isProvidedColumnGroup(child)) { child.setupExpandable(); } child.originalParent = parent; }; depthFirstOriginalTreeSearch(null, columnTree, deptFirstCallback); return { columnTree, treeDept }; } function extractExistingTreeData(existingTree) { const existingCols = []; const existingGroups = []; const existingColKeys = []; if (existingTree) { depthFirstOriginalTreeSearch(null, existingTree, (item) => { if (isProvidedColumnGroup(item)) { const group = item; existingGroups.push(group); } else { const col = item; existingColKeys.push(col.getId()); existingCols.push(col); } }); } return { existingCols, existingGroups, existingColKeys }; } function _recursivelyCreateColumns(beans, defs, level, primaryColumns, existingColsCopy, columnKeyCreator, existingGroups, source) { if (!defs) return []; const { colGroupSvc } = beans; const result = new Array(defs.length); for (let i = 0; i < result.length; i++) { const def = defs[i]; if (colGroupSvc && isColumnGroup(def)) { result[i] = colGroupSvc.createProvidedColumnGroup( primaryColumns, def, level, existingColsCopy, columnKeyCreator, existingGroups, source ); } else { result[i] = createColumn(beans, primaryColumns, def, existingColsCopy, columnKeyCreator, source); } } return result; } function createColumn(beans, primaryColumns, colDef, existingColsCopy, columnKeyCreator, source) { const existingColAndIndex = findExistingColumn(colDef, existingColsCopy); if (existingColAndIndex) { existingColsCopy?.splice(existingColAndIndex.idx, 1); } let column = existingColAndIndex?.column; if (!column) { const colId = columnKeyCreator.getUniqueKey(colDef.colId, colDef.field); const colDefMerged = _addColumnDefaultAndTypes(beans, colDef, colId); column = new AgColumn(colDefMerged, colDef, colId, primaryColumns); beans.context.createBean(column); } else { const colDefMerged = _addColumnDefaultAndTypes(beans, colDef, column.getColId()); column.setColDef(colDefMerged, colDef, source); _updateColumnState(beans, column, colDefMerged, source); } beans.dataTypeSvc?.addColumnListeners(column); return column; } function updateSomeColumnState(beans, column, hide, sort, sortIndex, pinned, flex, source) { const { sortSvc, pinnedCols, colFlex } = beans; if (hide !== void 0) { column.setVisible(!hide, source); } if (sortSvc) { sortSvc.updateColSort(column, sort, source); if (sortIndex !== void 0) { sortSvc.setColSortIndex(column, sortIndex); } } if (pinned !== void 0) { pinnedCols?.setColPinned(column, pinned); } if (flex !== void 0) { colFlex?.setColFlex(column, flex); } } function _updateColumnState(beans, column, colDef, source) { updateSomeColumnState( beans, column, colDef.hide, colDef.sort, colDef.sortIndex, colDef.pinned, colDef.flex, source ); const colFlex = column.getFlex(); if (colFlex != null && colFlex > 0) { return; } if (colDef.width != null) { column.setActualWidth(colDef.width, source); } else { const widthBeforeUpdate = column.getActualWidth(); column.setActualWidth(widthBeforeUpdate, source); } } function findExistingColumn(newColDef, existingColsCopy) { if (!existingColsCopy) return void 0; for (let i = 0; i < existingColsCopy.length; i++) { const def = existingColsCopy[i].getUserProvidedColDef(); if (!def) continue; const newHasId = newColDef.colId != null; if (newHasId) { if (existingColsCopy[i].getId() === newColDef.colId) { return { idx: i, column: existingColsCopy[i] }; } continue; } const newHasField = newColDef.field != null; if (newHasField) { if (def.field === newColDef.field) { return { idx: i, column: existingColsCopy[i] }; } continue; } if (def === newColDef) { return { idx: i, column: existingColsCopy[i] }; } } return void 0; } function _addColumnDefaultAndTypes(beans, colDef, colId, isAutoCol) { const { gos, dataTypeSvc, validation: validation2 } = beans; const res = {}; const defaultColDef = gos.get("defaultColDef"); _mergeDeep(res, defaultColDef, false, true); const columnType = updateColDefAndGetColumnType(beans, res, colDef, colId); if (columnType) { assignColumnTypes(beans, columnType, res); } _mergeDeep(res, colDef, false, true); const autoGroupColDef = gos.get("autoGroupColumnDef"); const isSortingCoupled = _isColumnsSortingCoupledToGroup(gos); if (colDef.rowGroup && autoGroupColDef && isSortingCoupled) { _mergeDeep( res, { sort: autoGroupColDef.sort, initialSort: autoGroupColDef.initialSort }, false, true ); } dataTypeSvc?.validateColDef(res); validation2?.validateColDef(res, colId, isAutoCol); return res; } function updateColDefAndGetColumnType(beans, colDef, userColDef, colId) { const dataTypeDefinitionColumnType = beans.dataTypeSvc?.updateColDefAndGetColumnType(colDef, userColDef, colId); const columnTypes = userColDef.type ?? dataTypeDefinitionColumnType ?? colDef.type; colDef.type = columnTypes; return columnTypes ? convertColumnTypes(columnTypes) : void 0; } function assignColumnTypes(beans, typeKeys, colDefMerged) { if (!typeKeys.length) { return; } const allColumnTypes = Object.assign({}, DefaultColumnTypes); const userTypes = beans.gos.get("columnTypes") || {}; for (const key of Object.keys(userTypes)) { const value = userTypes[key]; if (key in allColumnTypes) { _warn(34, { key }); } else { const colType = value; if (colType.type) { _warn(35); } allColumnTypes[key] = value; } } typeKeys.forEach((t) => { const typeColDef = allColumnTypes[t.trim()]; if (typeColDef) { _mergeDeep(colDefMerged, typeColDef, false, true); } else { _warn(36, { t }); } }); } function isColumnGroup(abstractColDef) { return abstractColDef.children !== void 0; } function depthFirstOriginalTreeSearch(parent, tree, callback) { if (!tree) { return; } for (let i = 0; i < tree.length; i++) { const child = tree[i]; if (isProvidedColumnGroup(child)) { depthFirstOriginalTreeSearch(child, child.getChildren(), callback); } callback(child, parent); } } // packages/ag-grid-community/src/columnMove/columnMoveUtils.ts function placeLockedColumns(cols, gos) { const left = []; const normal = []; const right = []; cols.forEach((col) => { const position = col.getColDef().lockPosition; if (position === "right") { right.push(col); } else if (position === "left" || position === true) { left.push(col); } else { normal.push(col); } }); const isRtl = gos.get("enableRtl"); if (isRtl) { return [...right, ...normal, ...left]; } return [...left, ...normal, ...right]; } function doesMovePassMarryChildren(allColumnsCopy, gridBalancedTree) { let rulePassed = true; depthFirstOriginalTreeSearch(null, gridBalancedTree, (child) => { if (!isProvidedColumnGroup(child)) { return; } const columnGroup = child; const colGroupDef = columnGroup.getColGroupDef(); const marryChildren = colGroupDef && colGroupDef.marryChildren; if (!marryChildren) { return; } const newIndexes = []; columnGroup.getLeafColumns().forEach((col) => { const newColIndex = allColumnsCopy.indexOf(col); newIndexes.push(newColIndex); }); const maxIndex = Math.max.apply(Math, newIndexes); const minIndex = Math.min.apply(Math, newIndexes); const spread = maxIndex - minIndex; const maxSpread = columnGroup.getLeafColumns().length - 1; if (spread > maxSpread) { rulePassed = false; } }); return rulePassed; } // packages/ag-grid-community/src/columns/columnEventUtils.ts function getCommonValue(cols, valueGetter) { if (!cols || cols.length == 0) { return void 0; } const firstValue = valueGetter(cols[0]); for (let i = 1; i < cols.length; i++) { if (firstValue !== valueGetter(cols[i])) { return void 0; } } return firstValue; } function dispatchColumnPinnedEvent(eventSvc, changedColumns, source) { if (!changedColumns.length) { return; } const column = changedColumns.length === 1 ? changedColumns[0] : null; const pinned = getCommonValue(changedColumns, (col) => col.getPinned()); eventSvc.dispatchEvent({ type: "columnPinned", // mistake in typing, 'undefined' should be allowed, as 'null' means 'not pinned' pinned: pinned != null ? pinned : null, columns: changedColumns, column, source }); } function dispatchColumnVisibleEvent(eventSvc, changedColumns, source) { if (!changedColumns.length) { return; } const column = changedColumns.length === 1 ? changedColumns[0] : null; const visible = getCommonValue(changedColumns, (col) => col.isVisible()); eventSvc.dispatchEvent({ type: "columnVisible", visible, columns: changedColumns, column, source }); } function dispatchColumnChangedEvent(eventSvc, type, columns, source) { eventSvc.dispatchEvent({ type, columns, column: columns && columns.length == 1 ? columns[0] : null, source }); } function dispatchColumnResizedEvent(eventSvc, columns, finished, source, flexColumns = null) { if (columns?.length) { eventSvc.dispatchEvent({ type: "columnResized", columns, column: columns.length === 1 ? columns[0] : null, flexColumns, finished, source }); } } // packages/ag-grid-community/src/columns/columnStateUtils.ts function _applyColumnState(beans, params, source) { const { colModel, rowGroupColsSvc, pivotColsSvc, autoColSvc, selectionColSvc, colAnimation, visibleCols, pivotResultCols, environment, valueColsSvc, eventSvc, gos } = beans; const providedCols = colModel.getColDefCols() || []; if (!providedCols?.length) { return false; } if (params?.state && !params.state.forEach) { _warn(32); return false; } const syncColumnWithStateItem = (column, stateItem, rowGroupIndexes, pivotIndexes, autoCol) => { if (!column) { return; } const getValue = getValueFactory(stateItem, params.defaultState); const flex = getValue("flex").value1; updateSomeColumnState( beans, column, getValue("hide").value1, getValue("sort").value1, getValue("sortIndex").value1, getValue("pinned").value1, flex, source ); if (flex == null) { const width = getValue("width").value1; if (width != null) { const minColWidth = column.getColDef().minWidth ?? environment.getDefaultColumnMinWidth(); if (minColWidth != null && width >= minColWidth) { column.setActualWidth(width, source); } } } if (autoCol || !column.isPrimary()) { return; } valueColsSvc?.syncColumnWithState(column, source, getValue); rowGroupColsSvc?.syncColumnWithState(column, source, getValue, rowGroupIndexes); pivotColsSvc?.syncColumnWithState(column, source, getValue, pivotIndexes); }; const applyStates = (states, existingColumns, getById2) => { const dispatchEventsFunc = _compareColumnStatesAndDispatchEvents(beans, source); const columnsWithNoState = existingColumns.slice(); const rowGroupIndexes = {}; const pivotIndexes = {}; const autoColStates = []; const selectionColStates = []; const unmatchedAndAutoStates2 = []; let unmatchedCount2 = 0; const previousRowGroupCols = rowGroupColsSvc?.columns.slice() ?? []; const previousPivotCols = pivotColsSvc?.columns.slice() ?? []; states.forEach((state) => { const colId = state.colId; const isAutoGroupColumn = colId.startsWith(GROUP_AUTO_COLUMN_ID); if (isAutoGroupColumn) { autoColStates.push(state); unmatchedAndAutoStates2.push(state); return; } if (isColumnSelectionCol(colId)) { selectionColStates.push(state); unmatchedAndAutoStates2.push(state); return; } const column = getById2(colId); if (!column) { unmatchedAndAutoStates2.push(state); unmatchedCount2 += 1; } else { syncColumnWithStateItem(column, state, rowGroupIndexes, pivotIndexes, false); _removeFromArray(columnsWithNoState, column); } }); const applyDefaultsFunc = (col) => syncColumnWithStateItem(col, null, rowGroupIndexes, pivotIndexes, false); columnsWithNoState.forEach(applyDefaultsFunc); rowGroupColsSvc?.sortColumns(comparatorByIndex.bind(rowGroupColsSvc, rowGroupIndexes, previousRowGroupCols)); pivotColsSvc?.sortColumns(comparatorByIndex.bind(pivotColsSvc, pivotIndexes, previousPivotCols)); colModel.refreshCols(false); const syncColStates = (getCol, colStates, columns = []) => { colStates.forEach((stateItem) => { const col = getCol(stateItem.colId); _removeFromArray(columns, col); syncColumnWithStateItem(col, stateItem, null, null, true); }); columns.forEach(applyDefaultsFunc); }; syncColStates( (colId) => autoColSvc?.getColumn(colId) ?? null, autoColStates, autoColSvc?.getColumns()?.slice() ); syncColStates( (colId) => selectionColSvc?.getColumn(colId) ?? null, selectionColStates, selectionColSvc?.getColumns()?.slice() ); orderLiveColsLikeState(params, colModel, gos); visibleCols.refresh(source); eventSvc.dispatchEvent({ type: "columnEverythingChanged", source }); dispatchEventsFunc(); return { unmatchedAndAutoStates: unmatchedAndAutoStates2, unmatchedCount: unmatchedCount2 }; }; colAnimation?.start(); let { unmatchedAndAutoStates, unmatchedCount } = applyStates( params.state || [], providedCols, (id) => colModel.getColDefCol(id) ); if (unmatchedAndAutoStates.length > 0 || _exists(params.defaultState)) { const pivotResultColsList = pivotResultCols?.getPivotResultCols()?.list ?? []; unmatchedCount = applyStates( unmatchedAndAutoStates, pivotResultColsList, (id) => pivotResultCols?.getPivotResultCol(id) ?? null ).unmatchedCount; } colAnimation?.finish(); return unmatchedCount === 0; } function _resetColumnState(beans, source) { const { colModel, autoColSvc } = beans; const primaryCols = colModel.getColDefCols(); if (!primaryCols?.length) { return; } const primaryColumnTree = colModel.getColDefColTree(); const primaryColumns = _getColumnsFromTree(primaryColumnTree); const columnStates = []; let letRowGroupIndex = 1e3; let letPivotIndex = 1e3; let colsToProcess = []; const groupAutoCols = autoColSvc?.getColumns(); if (groupAutoCols) { colsToProcess = colsToProcess.concat(groupAutoCols); } if (primaryColumns) { colsToProcess = colsToProcess.concat(primaryColumns); } colsToProcess.forEach((column) => { const stateItem = getColumnStateFromColDef(column); if (_missing(stateItem.rowGroupIndex) && stateItem.rowGroup) { stateItem.rowGroupIndex = letRowGroupIndex++; } if (_missing(stateItem.pivotIndex) && stateItem.pivot) { stateItem.pivotIndex = letPivotIndex++; } columnStates.push(stateItem); }); _applyColumnState(beans, { state: columnStates, applyOrder: true }, source); } function _compareColumnStatesAndDispatchEvents(beans, source) { const { rowGroupColsSvc, pivotColsSvc, valueColsSvc, colModel, sortSvc, eventSvc } = beans; const startState = { rowGroupColumns: rowGroupColsSvc?.columns.slice() ?? [], pivotColumns: pivotColsSvc?.columns.slice() ?? [], valueColumns: valueColsSvc?.columns.slice() ?? [] }; const columnStateBefore = _getColumnState(beans); const columnStateBeforeMap = {}; columnStateBefore.forEach((col) => { columnStateBeforeMap[col.colId] = col; }); return () => { const colsForState = colModel.getAllCols(); const dispatchWhenListsDifferent = (eventType, colsBefore, colsAfter, idMapper) => { const beforeList = colsBefore.map(idMapper); const afterList = colsAfter.map(idMapper); const unchanged = _areEqual(beforeList, afterList); if (unchanged) { return; } const changes = new Set(colsBefore); colsAfter.forEach((id) => { if (!changes.delete(id)) { changes.add(id); } }); const changesArr = [...changes]; eventSvc.dispatchEvent({ type: eventType, columns: changesArr, column: changesArr.length === 1 ? changesArr[0] : null, source }); }; const getChangedColumns = (changedPredicate) => { const changedColumns2 = []; colsForState.forEach((column) => { const colStateBefore = columnStateBeforeMap[column.getColId()]; if (colStateBefore && changedPredicate(colStateBefore, column)) { changedColumns2.push(column); } }); return changedColumns2; }; const columnIdMapper = (c) => c.getColId(); dispatchWhenListsDifferent( "columnRowGroupChanged", startState.rowGroupColumns, rowGroupColsSvc?.columns ?? [], columnIdMapper ); dispatchWhenListsDifferent( "columnPivotChanged", startState.pivotColumns, pivotColsSvc?.columns ?? [], columnIdMapper ); const valueChangePredicate = (cs, c) => { const oldActive = cs.aggFunc != null; const activeChanged = oldActive != c.isValueActive(); const aggFuncChanged = oldActive && cs.aggFunc != c.getAggFunc(); return activeChanged || aggFuncChanged; }; const changedValues = getChangedColumns(valueChangePredicate); if (changedValues.length > 0) { dispatchColumnChangedEvent(eventSvc, "columnValueChanged", changedValues, source); } const resizeChangePredicate = (cs, c) => cs.width != c.getActualWidth(); dispatchColumnResizedEvent(eventSvc, getChangedColumns(resizeChangePredicate), true, source); const pinnedChangePredicate = (cs, c) => cs.pinned != c.getPinned(); dispatchColumnPinnedEvent(eventSvc, getChangedColumns(pinnedChangePredicate), source); const visibilityChangePredicate = (cs, c) => cs.hide == c.isVisible(); dispatchColumnVisibleEvent(eventSvc, getChangedColumns(visibilityChangePredicate), source); const sortChangePredicate = (cs, c) => cs.sort != c.getSort() || cs.sortIndex != c.getSortIndex(); const changedColumns = getChangedColumns(sortChangePredicate); if (changedColumns.length > 0) { sortSvc?.dispatchSortChangedEvents(source, changedColumns); } const colStateAfter = _getColumnState(beans); normaliseColumnMovedEventForColumnState(columnStateBefore, colStateAfter, source, colModel, eventSvc); }; } function _getColumnState(beans) { const { colModel, rowGroupColsSvc, pivotColsSvc } = beans; const primaryCols = colModel.getColDefCols(); if (_missing(primaryCols) || !colModel.isAlive()) { return []; } const colsForState = colModel.getAllCols(); const rowGroupColumns = rowGroupColsSvc?.columns; const pivotColumns = pivotColsSvc?.columns; const createStateItemFromColumn = (column) => { const rowGroupIndex = column.isRowGroupActive() && rowGroupColumns ? rowGroupColumns.indexOf(column) : null; const pivotIndex = column.isPivotActive() && pivotColumns ? pivotColumns.indexOf(column) : null; const aggFunc = column.isValueActive() ? column.getAggFunc() : null; const sort = column.getSort() != null ? column.getSort() : null; const sortIndex = column.getSortIndex() != null ? column.getSortIndex() : null; const res2 = { colId: column.getColId(), width: column.getActualWidth(), hide: !column.isVisible(), pinned: column.getPinned(), sort, sortIndex, aggFunc, rowGroup: column.isRowGroupActive(), rowGroupIndex, pivot: column.isPivotActive(), pivotIndex, flex: column.getFlex() ?? null }; return res2; }; const res = colsForState.map((col) => createStateItemFromColumn(col)); const colIdToGridIndexMap = new Map( colModel.getCols().map((col, index) => [col.getColId(), index]) ); res.sort((itemA, itemB) => { const posA = colIdToGridIndexMap.has(itemA.colId) ? colIdToGridIndexMap.get(itemA.colId) : -1; const posB = colIdToGridIndexMap.has(itemB.colId) ? colIdToGridIndexMap.get(itemB.colId) : -1; return posA - posB; }); return res; } function getColumnStateFromColDef(column) { const getValueOrNull = (a, b) => a != null ? a : b != null ? b : null; const colDef = column.getColDef(); const sort = getValueOrNull(colDef.sort, colDef.initialSort); const sortIndex = getValueOrNull(colDef.sortIndex, colDef.initialSortIndex); const hide = getValueOrNull(colDef.hide, colDef.initialHide); const pinned = getValueOrNull(colDef.pinned, colDef.initialPinned); const width = getValueOrNull(colDef.width, colDef.initialWidth); const flex = getValueOrNull(colDef.flex, colDef.initialFlex); let rowGroupIndex = getValueOrNull(colDef.rowGroupIndex, colDef.initialRowGroupIndex); let rowGroup = getValueOrNull(colDef.rowGroup, colDef.initialRowGroup); if (rowGroupIndex == null && (rowGroup == null || rowGroup == false)) { rowGroupIndex = null; rowGroup = null; } let pivotIndex = getValueOrNull(colDef.pivotIndex, colDef.initialPivotIndex); let pivot = getValueOrNull(colDef.pivot, colDef.initialPivot); if (pivotIndex == null && (pivot == null || pivot == false)) { pivotIndex = null; pivot = null; } const aggFunc = getValueOrNull(colDef.aggFunc, colDef.initialAggFunc); return { colId: column.getColId(), sort, sortIndex, hide, pinned, width, flex, rowGroup, rowGroupIndex, pivot, pivotIndex, aggFunc }; } function orderLiveColsLikeState(params, colModel, gos) { if (!params.applyOrder || !params.state) { return; } const colIds = []; params.state.forEach((item) => { if (item.colId != null) { colIds.push(item.colId); } }); sortColsLikeKeys(colModel.cols, colIds, colModel, gos); } function sortColsLikeKeys(cols, colIds, colModel, gos) { if (cols == null) { return; } let newOrder = []; const processedColIds = {}; colIds.forEach((colId) => { if (processedColIds[colId]) { return; } const col = cols.map[colId]; if (col) { newOrder.push(col); processedColIds[colId] = true; } }); let autoGroupInsertIndex = 0; cols.list.forEach((col) => { const colId = col.getColId(); const alreadyProcessed = processedColIds[colId] != null; if (alreadyProcessed) { return; } const isAutoGroupCol = colId.startsWith(GROUP_AUTO_COLUMN_ID); if (isAutoGroupCol) { newOrder.splice(autoGroupInsertIndex++, 0, col); } else { newOrder.push(col); } }); newOrder = placeLockedColumns(newOrder, gos); if (!doesMovePassMarryChildren(newOrder, colModel.getColTree())) { _warn(39); return; } cols.list = newOrder; } function normaliseColumnMovedEventForColumnState(colStateBefore, colStateAfter, source, colModel, eventSvc) { const colStateAfterMapped = {}; colStateAfter.forEach((s) => colStateAfterMapped[s.colId] = s); const colsIntersectIds = {}; colStateBefore.forEach((s) => { if (colStateAfterMapped[s.colId]) { colsIntersectIds[s.colId] = true; } }); const beforeFiltered = colStateBefore.filter((c) => colsIntersectIds[c.colId]); const afterFiltered = colStateAfter.filter((c) => colsIntersectIds[c.colId]); const movedColumns = []; afterFiltered.forEach((csAfter, index) => { const csBefore = beforeFiltered && beforeFiltered[index]; if (csBefore && csBefore.colId !== csAfter.colId) { const gridCol = colModel.getCol(csBefore.colId); if (gridCol) { movedColumns.push(gridCol); } } }); if (!movedColumns.length) { return; } eventSvc.dispatchEvent({ type: "columnMoved", columns: movedColumns, column: movedColumns.length === 1 ? movedColumns[0] : null, finished: true, source }); } var comparatorByIndex = (indexes, oldList, colA, colB) => { const indexA = indexes[colA.getId()]; const indexB = indexes[colB.getId()]; const aHasIndex = indexA != null; const bHasIndex = indexB != null; if (aHasIndex && bHasIndex) { return indexA - indexB; } if (aHasIndex) { return -1; } if (bHasIndex) { return 1; } const oldIndexA = oldList.indexOf(colA); const oldIndexB = oldList.indexOf(colB); const aHasOldIndex = oldIndexA >= 0; const bHasOldIndex = oldIndexB >= 0; if (aHasOldIndex && bHasOldIndex) { return oldIndexA - oldIndexB; } if (aHasOldIndex) { return -1; } return 1; }; // packages/ag-grid-community/src/columns/columnModel.ts var ColumnModel = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colModel"; // if pivotMode is on, however pivot results are NOT shown if no pivot columns are set this.pivotMode = false; this.ready = false; this.changeEventsDispatching = false; } postConstruct() { this.pivotMode = this.gos.get("pivotMode"); this.addManagedPropertyListeners( ["groupDisplayType", "treeData", "treeDataDisplayType", "groupHideOpenParents"], (event) => this.refreshAll(_convertColumnEventSourceType(event.source)) ); this.addManagedPropertyListeners( ["defaultColDef", "defaultColGroupDef", "columnTypes", "suppressFieldDotNotation"], this.recreateColumnDefs.bind(this) ); this.addManagedPropertyListener( "pivotMode", (event) => this.setPivotMode(this.gos.get("pivotMode"), _convertColumnEventSourceType(event.source)) ); } // called from SyncService, when grid has finished initialising createColsFromColDefs(source) { const { beans } = this; const { valueCache, colAutosize, rowGroupColsSvc, pivotColsSvc, valueColsSvc, visibleCols, colViewport, eventSvc } = beans; const dispatchEventsFunc = this.colDefs ? _compareColumnStatesAndDispatchEvents(beans, source) : void 0; valueCache?.expire(); const oldCols = this.colDefCols?.list; const oldTree = this.colDefCols?.tree; const newTree = _createColumnTree(beans, this.colDefs, true, oldTree, source); _destroyColumnTree(beans, this.colDefCols?.tree, newTree.columnTree); const tree = newTree.columnTree; const treeDepth = newTree.treeDept; const list = _getColumnsFromTree(tree); const map = {}; list.forEach((col) => map[col.getId()] = col); this.colDefCols = { tree, treeDepth, list, map }; rowGroupColsSvc?.extractCols(source, oldCols); pivotColsSvc?.extractCols(source, oldCols); valueColsSvc?.extractCols(source, oldCols); this.ready = true; this.refreshCols(true); visibleCols.refresh(source); colViewport.checkViewportColumns(); eventSvc.dispatchEvent({ type: "columnEverythingChanged", source }); if (dispatchEventsFunc) { this.changeEventsDispatching = true; dispatchEventsFunc(); this.changeEventsDispatching = false; } eventSvc.dispatchEvent({ type: "newColumnsLoaded", source }); if (source === "gridInitializing") { colAutosize?.applyAutosizeStrategy(); } } // called from: buildAutoGroupColumns (events 'groupDisplayType', 'treeData', 'treeDataDisplayType', 'groupHideOpenParents') // createColsFromColDefs (recreateColumnDefs, setColumnsDefs), // setPivotMode, applyColumnState, // functionColsService.setPrimaryColList, functionColsService.updatePrimaryColList, // pivotResultCols.setPivotResultCols refreshCols(newColDefs) { if (!this.colDefCols) { return; } const prevColTree = this.cols?.tree; this.saveColOrder(); const { autoColSvc, selectionColSvc, rowNumbersSvc, quickFilter, pivotResultCols, showRowGroupCols, rowAutoHeight, visibleCols, colViewport, eventSvc } = this.beans; const cols = this.selectCols(pivotResultCols, this.colDefCols); this.createColumnsForService([autoColSvc, selectionColSvc, rowNumbersSvc], cols); const shouldSortNewColDefs = _shouldMaintainColumnOrder(this.gos, this.showingPivotResult); if (!newColDefs || shouldSortNewColDefs) { this.restoreColOrder(cols); } this.positionLockedCols(cols); showRowGroupCols?.refresh(); quickFilter?.refreshCols(); this.setColSpanActive(); rowAutoHeight?.setAutoHeightActive(cols); visibleCols.clear(); colViewport.clear(); const dispatchChangedEvent = !_areEqual(prevColTree, this.cols.tree); if (dispatchChangedEvent) { eventSvc.dispatchEvent({ type: "gridColumnsChanged" }); } } createColumnsForService(services, cols) { for (const service of services) { if (!service) { continue; } service.createColumns(cols, (updateOrder) => { this.lastOrder = updateOrder(this.lastOrder); this.lastPivotOrder = updateOrder(this.lastPivotOrder); }); service.addColumns(cols); } } selectCols(pivotResultColsSvc, colDefCols) { const pivotResultCols = pivotResultColsSvc?.getPivotResultCols() ?? null; this.showingPivotResult = pivotResultCols != null; const { map, list, tree, treeDepth } = pivotResultCols ?? colDefCols; this.cols = { list: list.slice(), map: { ...map }, tree: tree.slice(), treeDepth }; if (pivotResultCols) { const hasSameColumns = pivotResultCols.list.some((col) => this.cols?.map[col.getColId()] !== void 0); if (!hasSameColumns) { this.lastPivotOrder = null; } } return this.cols; } getColsToShow() { if (!this.cols) { return []; } const showAutoGroupAndValuesOnly = this.isPivotMode() && !this.showingPivotResult; const valueColumns = this.beans.valueColsSvc?.columns; const res = this.cols.list.filter((col) => { const isAutoGroupCol = isColumnGroupAutoCol(col); if (showAutoGroupAndValuesOnly) { const isValueCol = valueColumns?.includes(col); return isAutoGroupCol || isValueCol; } else { return isAutoGroupCol || col.isVisible(); } }); return res; } // on events 'groupDisplayType', 'treeData', 'treeDataDisplayType', 'groupHideOpenParents' refreshAll(source) { if (!this.ready) { return; } this.refreshCols(false); this.beans.visibleCols.refresh(source); } setColsVisible(keys, visible = false, source) { _applyColumnState( this.beans, { state: keys.map((key) => ({ colId: typeof key === "string" ? key : key.getColId(), hide: !visible })) }, source ); } restoreColOrder(cols) { const lastOrder = this.showingPivotResult ? this.lastPivotOrder : this.lastOrder; if (!lastOrder) { return; } const lastOrderMapped = new Map(lastOrder.map((col, index) => [col, index])); const noColsFound = !cols.list.some((col) => lastOrderMapped.has(col)); if (noColsFound) { return; } const colsMap = new Map(cols.list.map((col) => [col, true])); const lastOrderFiltered = lastOrder.filter((col) => colsMap.has(col)); const lastOrderFilteredMap = new Map(lastOrderFiltered.map((col) => [col, true])); const missingFromLastOrder = cols.list.filter((col) => !lastOrderFilteredMap.has(col)); const res = lastOrderFiltered.slice(); missingFromLastOrder.forEach((newCol) => { let parent = newCol.getOriginalParent(); if (!parent) { res.push(newCol); return; } const siblings = []; while (!siblings.length && parent) { const leafCols = parent.getLeafColumns(); leafCols.forEach((leafCol) => { const presentInNewCols = res.indexOf(leafCol) >= 0; const notYetInSiblings = siblings.indexOf(leafCol) < 0; if (presentInNewCols && notYetInSiblings) { siblings.push(leafCol); } }); parent = parent.getOriginalParent(); } if (!siblings.length) { res.push(newCol); return; } const indexes = siblings.map((col) => res.indexOf(col)); const lastIndex = Math.max(...indexes); res.splice(lastIndex + 1, 0, newCol); }); cols.list = res; } positionLockedCols(cols) { cols.list = placeLockedColumns(cols.list, this.gos); } saveColOrder() { if (this.showingPivotResult) { this.lastPivotOrder = this.cols?.list ?? null; } else { this.lastOrder = this.cols?.list ?? null; } } getColumnDefs() { return this.colDefCols ? this.beans.colDefFactory?.getColumnDefs( this.colDefCols.list, this.showingPivotResult, this.lastOrder, this.cols?.list ?? [] ) : void 0; } setColSpanActive() { this.colSpanActive = !!this.cols?.list.some((col) => col.getColDef().colSpan != null); } isPivotMode() { return this.pivotMode; } setPivotMode(pivotMode, source) { if (pivotMode === this.pivotMode) { return; } this.pivotMode = pivotMode; if (!this.ready) { return; } this.refreshCols(false); const { visibleCols, eventSvc } = this.beans; visibleCols.refresh(source); eventSvc.dispatchEvent({ type: "columnPivotModeChanged" }); } // + clientSideRowModel isPivotActive() { const pivotColumns = this.beans.pivotColsSvc?.columns; return this.pivotMode && !!pivotColumns?.length; } // called when dataTypes change recreateColumnDefs(e) { if (!this.cols) { return; } this.beans.autoColSvc?.updateColumns(e); const source = _convertColumnEventSourceType(e.source); this.createColsFromColDefs(source); } setColumnDefs(columnDefs, source) { this.colDefs = columnDefs; this.createColsFromColDefs(source); } destroy() { _destroyColumnTree(this.beans, this.colDefCols?.tree); super.destroy(); } getColTree() { return this.cols?.tree ?? []; } // + columnSelectPanel getColDefColTree() { return this.colDefCols?.tree ?? []; } // + clientSideRowController -> sorting, building quick filter text // + headerRenderer -> sorting (clearing icon) getColDefCols() { return this.colDefCols?.list ?? null; } // + moveColumnController getCols() { return this.cols?.list ?? []; } // returns colDefCols, pivotResultCols and autoCols getAllCols() { const { pivotResultCols, autoColSvc, selectionColSvc } = this.beans; const pivotResultColsList = pivotResultCols?.getPivotResultCols()?.list; return [ this.colDefCols?.list ?? [], autoColSvc?.columns?.list ?? [], selectionColSvc?.columns?.list ?? [], pivotResultColsList ?? [] ].flat(); } getColsForKeys(keys) { if (!keys) { return []; } return keys.map((key) => this.getCol(key)).filter((col) => col != null); } getColDefCol(key) { if (!this.colDefCols?.list) { return null; } return this.getColFromCollection(key, this.colDefCols); } getCol(key) { if (key == null) { return null; } return this.getColFromCollection(key, this.cols); } getColFromCollection(key, cols) { if (cols == null) { return null; } const { map, list } = cols; if (typeof key == "string" && map[key]) { return map[key]; } for (let i = 0; i < list.length; i++) { if (_columnsMatch(list[i], key)) { return list[i]; } } return this.beans.autoColSvc?.getColumn(key) ?? this.beans.selectionColSvc?.getColumn(key) ?? null; } }; // packages/ag-grid-community/src/columns/baseColsService.ts var BaseColsService = class extends BeanStub { constructor() { super(...arguments); this.dispatchColumnChangedEvent = dispatchColumnChangedEvent; this.columns = []; } wireBeans(beans) { this.colModel = beans.colModel; this.aggFuncSvc = beans.aggFuncSvc; this.visibleCols = beans.visibleCols; } sortColumns(compareFn) { this.columns.sort(compareFn); } setColumns(colKeys, source) { this.setColList(colKeys, this.columns, this.eventName, true, true, this.columnProcessors.set, source); } addColumns(colKeys, source) { this.updateColList(colKeys, this.columns, true, true, this.columnProcessors.add, this.eventName, source); } removeColumns(colKeys, source) { this.updateColList(colKeys, this.columns, false, true, this.columnProcessors.remove, this.eventName, source); } setColList(colKeys = [], masterList, eventName, detectOrderChange, autoGroupsNeedBuilding, columnCallback, source) { const gridColumns = this.colModel.getCols(); if (!gridColumns || gridColumns.length === 0) { return; } const changes = /* @__PURE__ */ new Map(); masterList.forEach((col, idx) => changes.set(col, idx)); masterList.length = 0; if (_exists(colKeys)) { colKeys.forEach((key) => { const column = this.colModel.getColDefCol(key); if (column) { masterList.push(column); } }); } masterList.forEach((col, idx) => { const oldIndex = changes.get(col); if (oldIndex === void 0) { changes.set(col, 0); return; } if (detectOrderChange && oldIndex !== idx) { return; } changes.delete(col); }); const primaryCols = this.colModel.getColDefCols(); (primaryCols || []).forEach((column) => { const added = masterList.indexOf(column) >= 0; columnCallback(column, added, source); }); autoGroupsNeedBuilding && this.colModel.refreshCols(false); this.visibleCols.refresh(source); this.dispatchColumnChangedEvent(this.eventSvc, eventName, [...changes.keys()], source); } updateColList(keys = [], masterList, actionIsAdd, autoGroupsNeedBuilding, columnCallback, eventType, source) { if (!keys || keys.length === 0) { return; } let atLeastOne = false; const updatedCols = /* @__PURE__ */ new Set(); keys.forEach((key) => { if (!key) { return; } const columnToAdd = this.colModel.getColDefCol(key); if (!columnToAdd) { return; } updatedCols.add(columnToAdd); if (actionIsAdd) { if (masterList.indexOf(columnToAdd) >= 0) { return; } masterList.push(columnToAdd); } else { const currentIndex = masterList.indexOf(columnToAdd); if (currentIndex < 0) { return; } for (let i = currentIndex + 1; i < masterList.length; i++) { updatedCols.add(masterList[i]); } _removeFromArray(masterList, columnToAdd); } columnCallback(columnToAdd, actionIsAdd, source); atLeastOne = true; }); if (!atLeastOne) { return; } if (autoGroupsNeedBuilding) { this.colModel.refreshCols(false); } this.visibleCols.refresh(source); const eventColumns = Array.from(updatedCols); this.eventSvc.dispatchEvent({ type: eventType, columns: eventColumns, column: eventColumns.length === 1 ? eventColumns[0] : null, source }); } extractCols(source, oldProvidedCols = []) { const previousCols = this.columns; const colsWithIndex = []; const colsWithValue = []; const { setFlagFunc, getIndexFunc, getInitialIndexFunc, getValueFunc, getInitialValueFunc } = this.columnExtractors; const primaryCols = this.colModel.getColDefCols() || []; primaryCols.forEach((col) => { const colIsNew = oldProvidedCols.indexOf(col) < 0; const colDef = col.getColDef(); const value = getValueFunc(colDef); const initialValue = getInitialValueFunc(colDef); const index = getIndexFunc(colDef); const initialIndex = getInitialIndexFunc(colDef); let include; const valuePresent = value !== void 0; const indexPresent = index !== void 0; const initialValuePresent = initialValue !== void 0; const initialIndexPresent = initialIndex !== void 0; if (valuePresent) { include = value; } else if (indexPresent) { if (index === null) { include = false; } else { include = index >= 0; } } else { if (colIsNew) { if (initialValuePresent) { include = initialValue; } else if (initialIndexPresent) { include = initialIndex != null && initialIndex >= 0; } else { include = false; } } else { include = previousCols.indexOf(col) >= 0; } } if (include) { const useIndex = colIsNew ? index != null || initialIndex != null : index != null; useIndex ? colsWithIndex.push(col) : colsWithValue.push(col); } }); const getIndexForCol = (col) => { const index = getIndexFunc(col.getColDef()); const defaultIndex = getInitialIndexFunc(col.getColDef()); return index != null ? index : defaultIndex; }; colsWithIndex.sort((colA, colB) => { const indexA = getIndexForCol(colA); const indexB = getIndexForCol(colB); if (indexA === indexB) { return 0; } if (indexA < indexB) { return -1; } return 1; }); const res = [].concat(colsWithIndex); previousCols.forEach((col) => { if (colsWithValue.indexOf(col) >= 0) { res.push(col); } }); colsWithValue.forEach((col) => { if (res.indexOf(col) < 0) { res.push(col); } }); previousCols.forEach((col) => { if (res.indexOf(col) < 0) { setFlagFunc(col, false, source); } }); res.forEach((col) => { if (previousCols.indexOf(col) < 0) { setFlagFunc(col, true, source); } }); return this.columns = res; } restoreColumnOrder(columnStateAccumulator, incomingColumnState) { const colList = this.columns; const primaryCols = this.colModel.getColDefCols(); if (!colList.length || !primaryCols) { return columnStateAccumulator; } const updatedColIdArray = Object.keys(incomingColumnState); const updatedColIds = new Set(updatedColIdArray); const newColIds = new Set(updatedColIdArray); const allColIds = new Set( colList.map((column) => { const colId = column.getColId(); newColIds.delete(colId); return colId; }).concat(updatedColIdArray) ); const colIdsInOriginalOrder = []; const originalOrderMap = {}; let orderIndex = 0; for (let i = 0; i < primaryCols.length; i++) { const colId = primaryCols[i].getColId(); if (allColIds.has(colId)) { colIdsInOriginalOrder.push(colId); originalOrderMap[colId] = orderIndex++; } } let index = 1e3; let hasAddedNewCols = false; let lastIndex = 0; const enableProp = this.columnOrdering.enableProp; const initialEnableProp = this.columnOrdering.initialEnableProp; const indexProp = this.columnOrdering.indexProp; const initialIndexProp = this.columnOrdering.initialIndexProp; const processPrecedingNewCols = (colId) => { const originalOrderIndex = originalOrderMap[colId]; for (let i = lastIndex; i < originalOrderIndex; i++) { const newColId = colIdsInOriginalOrder[i]; if (newColIds.has(newColId)) { incomingColumnState[newColId][indexProp] = index++; newColIds.delete(newColId); } } lastIndex = originalOrderIndex; }; colList.forEach((column) => { const colId = column.getColId(); if (updatedColIds.has(colId)) { processPrecedingNewCols(colId); incomingColumnState[colId][indexProp] = index++; } else { const colDef = column.getColDef(); const missingIndex = colDef[indexProp] === null || colDef[indexProp] === void 0 && colDef[initialIndexProp] == null; if (missingIndex) { if (!hasAddedNewCols) { const propEnabled = colDef[enableProp] || colDef[enableProp] === void 0 && colDef[initialEnableProp]; if (propEnabled) { processPrecedingNewCols(colId); } else { newColIds.forEach((newColId) => { incomingColumnState[newColId][indexProp] = index + originalOrderMap[newColId]; }); index += colIdsInOriginalOrder.length; hasAddedNewCols = true; } } if (!columnStateAccumulator[colId]) { columnStateAccumulator[colId] = { colId }; } columnStateAccumulator[colId][indexProp] = index++; } } }); return columnStateAccumulator; } }; // packages/ag-grid-community/src/columns/groupInstanceIdCreator.ts var GroupInstanceIdCreator = class { constructor() { // this map contains keys to numbers, so we remember what the last call was this.existingIds = {}; } getInstanceIdForKey(key) { const lastResult = this.existingIds[key]; let result; if (typeof lastResult !== "number") { result = 0; } else { result = lastResult + 1; } this.existingIds[key] = result; return result; } }; // packages/ag-grid-community/src/components/emptyBean.ts var EmptyBean = class extends BeanStub { }; function setupCompBean(ctrl, ctx, compBean) { if (compBean) { ctrl.addDestroyFunc(() => ctx.destroyBean(compBean)); } return compBean ?? ctrl; } // packages/ag-grid-community/src/rendering/cssClassManager.ts var CssClassManager = class { constructor(getGui) { // to minimise DOM hits, we only apply CSS classes if they have changed. as adding a CSS class that is already // there, or removing one that wasn't present, all takes CPU. this.cssClassStates = {}; this.getGui = getGui; } addCssClass(className) { this.addOrRemoveCssClass(className, true); } removeCssClass(className) { this.addOrRemoveCssClass(className, false); } containsCssClass(className) { const eGui = this.getGui(); if (!eGui) { return false; } return eGui.classList.contains(className); } addOrRemoveCssClass(className, addOrRemove) { if (!className) { return; } if (className.indexOf(" ") >= 0) { const list = (className || "").split(" "); if (list.length > 1) { list.forEach((cls) => this.addOrRemoveCssClass(cls, addOrRemove)); return; } } const updateNeeded = this.cssClassStates[className] !== addOrRemove; if (updateNeeded && className.length) { const eGui = this.getGui(); if (eGui) { eGui.classList.toggle(className, addOrRemove); } this.cssClassStates[className] = addOrRemove; } } }; // packages/ag-grid-community/src/widgets/component.ts var compIdSequence = 0; var RefPlaceholder = null; var Component = class extends BeanStub { constructor(template, componentSelectors) { super(); this.suppressDataRefValidation = false; // if false, then CSS class "ag-hidden" is applied, which sets "display: none" this.displayed = true; // if false, then CSS class "ag-invisible" is applied, which sets "visibility: hidden" this.visible = true; // unique id for this row component. this is used for getting a reference to the HTML dom. // we cannot use the RowNode id as this is not unique (due to animation, old rows can be lying // around as we create a new rowComp instance for the same row node). this.compId = compIdSequence++; this.cssClassManager = new CssClassManager(() => this.eGui); this.componentSelectors = new Map((componentSelectors ?? []).map((comp) => [comp.selector, comp])); if (template) { this.setTemplate(template); } } preConstruct() { this.wireTemplate(this.getGui()); const debugId = "component-" + Object.getPrototypeOf(this)?.constructor?.name; this.css?.forEach((css) => this.beans.environment.addGlobalCSS(css, debugId)); } wireTemplate(element, paramsMap) { if (element && this.gos) { this.applyElementsToComponent(element); this.createChildComponentsFromTags(element, paramsMap); } } getCompId() { return this.compId; } getDataRefAttribute(element) { if (element.getAttribute) { return element.getAttribute("data-ref"); } return null; } applyElementsToComponent(element, elementRef, paramsMap, newComponent = null) { if (elementRef === void 0) { elementRef = this.getDataRefAttribute(element); } if (elementRef) { const current = this[elementRef]; if (current === RefPlaceholder) { this[elementRef] = newComponent ?? element; } else { const usedAsParamRef = paramsMap && paramsMap[elementRef]; if (!this.suppressDataRefValidation && !usedAsParamRef) { throw new Error(`data-ref: ${elementRef} on ${this.constructor.name} with ${current}`); } } } } // for registered components only, eg creates AgCheckbox instance from ag-checkbox HTML tag createChildComponentsFromTags(parentNode, paramsMap) { const childNodeList = _copyNodeList(parentNode.childNodes); childNodeList.forEach((childNode) => { if (!(childNode instanceof HTMLElement)) { return; } const childComp = this.createComponentFromElement( childNode, (childComp2) => { const childGui = childComp2.getGui(); if (childGui) { this.copyAttributesFromNode(childNode, childComp2.getGui()); } }, paramsMap ); if (childComp) { if (childComp.addItems && childNode.children.length) { this.createChildComponentsFromTags(childNode, paramsMap); const items = Array.prototype.slice.call(childNode.children); childComp.addItems(items); } this.swapComponentForNode(childComp, parentNode, childNode); } else if (childNode.childNodes) { this.createChildComponentsFromTags(childNode, paramsMap); } }); } createComponentFromElement(element, afterPreCreateCallback, paramsMap) { const key = element.nodeName; const elementRef = this.getDataRefAttribute(element); const isAgGridComponent = key.indexOf("AG-") === 0; const componentSelector = isAgGridComponent ? this.componentSelectors.get(key) : null; let newComponent = null; if (componentSelector) { const componentParams = paramsMap && elementRef ? paramsMap[elementRef] : void 0; newComponent = new componentSelector.component(componentParams); newComponent.setParentComponent(this); this.createBean(newComponent, null, afterPreCreateCallback); } else if (isAgGridComponent) { throw new Error(`selector: ${key}`); } this.applyElementsToComponent(element, elementRef, paramsMap, newComponent); return newComponent; } copyAttributesFromNode(source, dest) { _iterateNamedNodeMap(source.attributes, (name, value) => dest.setAttribute(name, value)); } swapComponentForNode(newComponent, parentNode, childNode) { const eComponent = newComponent.getGui(); parentNode.replaceChild(eComponent, childNode); parentNode.insertBefore(document.createComment(childNode.nodeName), eComponent); this.addDestroyFunc(this.destroyBean.bind(this, newComponent)); } activateTabIndex(elements) { const tabIndex = this.gos.get("tabIndex"); if (!elements) { elements = []; } if (!elements.length) { elements.push(this.getGui()); } elements.forEach((el) => el.setAttribute("tabindex", tabIndex.toString())); } setTemplate(template, componentSelectors, paramsMap) { const eGui = _loadTemplate(template); this.setTemplateFromElement(eGui, componentSelectors, paramsMap); } setTemplateFromElement(element, components, paramsMap, suppressDataRefValidation = false) { this.eGui = element; this.suppressDataRefValidation = suppressDataRefValidation; if (components) { for (let i = 0; i < components.length; i++) { const component = components[i]; this.componentSelectors.set(component.selector, component); } } this.wireTemplate(element, paramsMap); } getGui() { return this.eGui; } getFocusableElement() { return this.eGui; } getAriaElement() { return this.getFocusableElement(); } setParentComponent(component) { this.parentComponent = component; } getParentComponent() { return this.parentComponent; } // this method is for older code, that wants to provide the gui element, // it is not intended for this to be in ag-Stack setGui(eGui) { this.eGui = eGui; } queryForHtmlElement(cssSelector) { return this.eGui.querySelector(cssSelector); } getContainerAndElement(newChild, container) { let parent = container; if (newChild == null) { return null; } if (!parent) { parent = this.eGui; } if (_isNodeOrElement(newChild)) { return { element: newChild, parent }; } return { element: newChild.getGui(), parent }; } prependChild(newChild, container) { const { element, parent } = this.getContainerAndElement(newChild, container) || {}; if (!element || !parent) { return; } parent.insertAdjacentElement("afterbegin", element); } appendChild(newChild, container) { const { element, parent } = this.getContainerAndElement(newChild, container) || {}; if (!element || !parent) { return; } parent.appendChild(element); } isDisplayed() { return this.displayed; } setVisible(visible, options = {}) { if (visible !== this.visible) { this.visible = visible; const { skipAriaHidden } = options; _setVisible(this.eGui, visible, { skipAriaHidden }); } } setDisplayed(displayed, options = {}) { if (displayed !== this.displayed) { this.displayed = displayed; const { skipAriaHidden } = options; _setDisplayed(this.eGui, displayed, { skipAriaHidden }); const event = { type: "displayChanged", visible: this.displayed }; this.dispatchLocalEvent(event); } } destroy() { if (this.parentComponent) { this.parentComponent = void 0; } super.destroy(); } addGuiEventListener(event, listener, options) { this.eGui.addEventListener(event, listener, options); this.addDestroyFunc(() => this.eGui.removeEventListener(event, listener)); } addCssClass(className) { this.cssClassManager.addCssClass(className); } removeCssClass(className) { this.cssClassManager.removeCssClass(className); } containsCssClass(className) { return this.cssClassManager.containsCssClass(className); } addOrRemoveCssClass(className, addOrRemove) { this.cssClassManager.addOrRemoveCssClass(className, addOrRemove); } registerCSS(css) { this.css || (this.css = []); this.css.push(css); } }; // packages/ag-grid-community/src/utils/promise.ts function _isPromise(fn) { if (typeof fn.then === "function") { return true; } return false; } var AgPromise = class _AgPromise { constructor(callback) { this.status = 0 /* IN_PROGRESS */; this.resolution = null; this.waiters = []; callback( (value) => this.onDone(value), (params) => this.onReject(params) ); } static all(promises) { return promises.length ? new _AgPromise((resolve) => { let remainingToResolve = promises.length; const combinedValues = new Array(remainingToResolve); promises.forEach((promise, index) => { promise.then((value) => { combinedValues[index] = value; remainingToResolve--; if (remainingToResolve === 0) { resolve(combinedValues); } }); }); }) : _AgPromise.resolve(); } static resolve(value = null) { return new _AgPromise((resolve) => resolve(value)); } then(func) { return new _AgPromise((resolve) => { if (this.status === 1 /* RESOLVED */) { resolve(func(this.resolution)); } else { this.waiters.push((value) => resolve(func(value))); } }); } onDone(value) { this.status = 1 /* RESOLVED */; this.resolution = value; this.waiters.forEach((waiter) => waiter(value)); } onReject(_) { } }; // packages/ag-grid-community/src/components/framework/userComponentFactory.ts function doesImplementIComponent(candidate) { if (!candidate) { return false; } return candidate.prototype && "getGui" in candidate.prototype; } function _getUserCompKeys(frameworkOverrides, defObject, type, params) { const { name } = type; let compName; let jsComp; let fwComp; let paramsFromSelector; let popupFromSelector; let popupPositionFromSelector; if (defObject) { const defObjectAny = defObject; const selectorFunc = defObjectAny[name + "Selector"]; const selectorRes = selectorFunc ? selectorFunc(params) : null; const assignComp = (providedJsComp) => { if (typeof providedJsComp === "string") { compName = providedJsComp; } else if (providedJsComp != null && providedJsComp !== true) { const isFwkComp = frameworkOverrides.isFrameworkComponent(providedJsComp); if (isFwkComp) { fwComp = providedJsComp; } else { jsComp = providedJsComp; } } }; if (selectorRes) { assignComp(selectorRes.component); paramsFromSelector = selectorRes.params; popupFromSelector = selectorRes.popup; popupPositionFromSelector = selectorRes.popupPosition; } else { assignComp(defObjectAny[name]); } } return { compName, jsComp, fwComp, paramsFromSelector, popupFromSelector, popupPositionFromSelector }; } var UserComponentFactory = class extends BeanStub { constructor() { super(...arguments); this.beanName = "userCompFactory"; } wireBeans(beans) { this.agCompUtils = beans.agCompUtils; this.registry = beans.registry; this.frameworkCompWrapper = beans.frameworkCompWrapper; this.gridOptions = beans.gridOptions; } getCompDetailsFromGridOptions(type, defaultName, params, mandatory = false) { return this.getCompDetails(this.gridOptions, type, defaultName, params, mandatory); } getCompDetails(defObject, type, defaultName, params, mandatory = false) { const { name, cellRenderer } = type; let { compName, jsComp, fwComp, paramsFromSelector, popupFromSelector, popupPositionFromSelector } = _getUserCompKeys(this.beans.frameworkOverrides, defObject, type, params); let defaultCompParams; const lookupFromRegistry = (key) => { const item = this.registry.getUserComponent(name, key); if (item) { jsComp = !item.componentFromFramework ? item.component : void 0; fwComp = item.componentFromFramework ? item.component : void 0; defaultCompParams = item.params; } }; if (compName != null) { lookupFromRegistry(compName); } if (jsComp == null && fwComp == null && defaultName != null) { lookupFromRegistry(defaultName); } if (jsComp && cellRenderer && !doesImplementIComponent(jsComp)) { jsComp = this.agCompUtils?.adaptFunction(type, jsComp); } if (!jsComp && !fwComp) { const { validation: validation2 } = this.beans; if (mandatory && (compName !== defaultName || !defaultName)) { if (compName) { if (!validation2?.isProvidedUserComp(compName)) { _error(50, { compName }); } } else { if (defaultName) { if (!validation2) { _error(260, { ...this.gos.getModuleErrorParams(), propName: name, compName: defaultName }); } } else { _error(216, { name }); } } } else if (defaultName && !validation2) { _error(146, { comp: defaultName }); } return; } const paramsMerged = this.mergeParams(defObject, type, params, paramsFromSelector, defaultCompParams); const componentFromFramework = jsComp == null; const componentClass = jsComp ?? fwComp; return { componentFromFramework, componentClass, params: paramsMerged, type, popupFromSelector, popupPositionFromSelector, newAgStackInstance: () => this.newAgStackInstance(componentClass, componentFromFramework, paramsMerged, type) }; } newAgStackInstance(ComponentClass, componentFromFramework, params, type) { const jsComponent = !componentFromFramework; let instance; if (jsComponent) { instance = new ComponentClass(); } else { instance = this.frameworkCompWrapper.wrap( ComponentClass, type.mandatoryMethods, type.optionalMethods, type ); } this.createBean(instance); const deferredInit = instance.init?.(params); if (deferredInit == null) { return AgPromise.resolve(instance); } return deferredInit.then(() => instance); } /** * merges params with application provided params * used by Floating Filter */ mergeParams(defObject, type, paramsFromGrid, paramsFromSelector = null, defaultCompParams) { const params = { ...paramsFromGrid, ...defaultCompParams }; const defObjectAny = defObject; const userParams = defObjectAny && defObjectAny[type.name + "Params"]; if (typeof userParams === "function") { const userParamsFromFunc = userParams(paramsFromGrid); _mergeDeep(params, userParamsFromFunc); } else if (typeof userParams === "object") { _mergeDeep(params, userParams); } _mergeDeep(params, paramsFromSelector); return params; } }; // packages/ag-grid-community/src/components/framework/userCompUtils.ts var DateComponent = { name: "dateComponent", mandatoryMethods: ["getDate", "setDate"], optionalMethods: ["afterGuiAttached", "setInputPlaceholder", "setInputAriaLabel", "setDisabled", "refresh"] }; var DragAndDropImageComponent = { name: "dragAndDropImageComponent", mandatoryMethods: ["setIcon", "setLabel"] }; var HeaderComponent = { name: "headerComponent", optionalMethods: ["refresh"] }; var InnerHeaderComponent = { name: "innerHeaderComponent" }; var InnerHeaderGroupComponent = { name: "innerHeaderGroupComponent" }; var HeaderGroupComponent = { name: "headerGroupComponent" }; var InnerCellRendererComponent = { name: "innerRenderer", cellRenderer: true, optionalMethods: ["afterGuiAttached"] }; var CellRendererComponent = { name: "cellRenderer", optionalMethods: ["refresh", "afterGuiAttached"], cellRenderer: true }; var EditorRendererComponent = { name: "cellRenderer", optionalMethods: ["refresh", "afterGuiAttached"] }; var LoadingCellRendererComponent = { name: "loadingCellRenderer", cellRenderer: true }; var CellEditorComponent = { name: "cellEditor", mandatoryMethods: ["getValue"], optionalMethods: [ "isPopup", "isCancelBeforeStart", "isCancelAfterEnd", "getPopupPosition", "focusIn", "focusOut", "afterGuiAttached", "refresh" ] }; var LoadingOverlayComponent = { name: "loadingOverlayComponent", optionalMethods: ["refresh"] }; var NoRowsOverlayComponent = { name: "noRowsOverlayComponent", optionalMethods: ["refresh"] }; var TooltipComponent = { name: "tooltipComponent" }; var FilterComponent = { name: "filter", mandatoryMethods: ["isFilterActive", "doesFilterPass", "getModel", "setModel"], optionalMethods: [ "afterGuiAttached", "afterGuiDetached", "onNewRowsLoaded", "getModelAsString", "onFloatingFilterChanged", "onAnyFilterChanged", "refresh" ] }; var FloatingFilterComponent = { name: "floatingFilterComponent", mandatoryMethods: ["onParentModelChanged"], optionalMethods: ["afterGuiAttached", "refresh"] }; var FullWidth = { name: "fullWidthCellRenderer", optionalMethods: ["refresh", "afterGuiAttached"], cellRenderer: true }; var FullWidthLoading = { name: "loadingCellRenderer", cellRenderer: true }; var FullWidthGroup = { name: "groupRowRenderer", optionalMethods: ["afterGuiAttached"], cellRenderer: true }; var FullWidthDetail = { name: "detailCellRenderer", optionalMethods: ["refresh"], cellRenderer: true }; function _getDragAndDropImageCompDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(DragAndDropImageComponent, "agDragAndDropImage", params, true); } function _getInnerCellRendererDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, InnerCellRendererComponent, void 0, params); } function _getHeaderCompDetails(userCompFactory, colDef, params) { return userCompFactory.getCompDetails(colDef, HeaderComponent, "agColumnHeader", params); } function _getInnerHeaderCompDetails(userCompFactory, headerCompParams, params) { return userCompFactory.getCompDetails(headerCompParams, InnerHeaderComponent, void 0, params); } function _getHeaderGroupCompDetails(userCompFactory, params) { const colGroupDef = params.columnGroup.getColGroupDef(); return userCompFactory.getCompDetails(colGroupDef, HeaderGroupComponent, "agColumnGroupHeader", params); } function _getInnerHeaderGroupCompDetails(userCompFactory, headerGroupCompParams, params) { return userCompFactory.getCompDetails(headerGroupCompParams, InnerHeaderGroupComponent, void 0, params); } function _getFullWidthCellRendererDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(FullWidth, void 0, params, true); } function _getFullWidthLoadingCellRendererDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(FullWidthLoading, "agLoadingCellRenderer", params, true); } function _getFullWidthGroupCellRendererDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(FullWidthGroup, "agGroupRowRenderer", params, true); } function _getFullWidthDetailCellRendererDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(FullWidthDetail, "agDetailCellRenderer", params, true); } function _getCellRendererDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, CellRendererComponent, void 0, params); } function _getEditorRendererDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails( def, EditorRendererComponent, void 0, params ); } function _getLoadingCellRendererDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, LoadingCellRendererComponent, "agSkeletonCellRenderer", params, true); } function _getCellEditorDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, CellEditorComponent, "agCellEditor", params, true); } function _getFilterDetails(userCompFactory, def, params, defaultFilter) { return userCompFactory.getCompDetails(def, FilterComponent, defaultFilter, params, true); } function _getDateCompDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(DateComponent, "agDateInput", params, true); } function _getLoadingOverlayCompDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(LoadingOverlayComponent, "agLoadingOverlay", params, true); } function _getNoRowsOverlayCompDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(NoRowsOverlayComponent, "agNoRowsOverlay", params, true); } function _getTooltipCompDetails(userCompFactory, params) { return userCompFactory.getCompDetails(params.colDef, TooltipComponent, "agTooltipComponent", params, true); } function _getFloatingFilterCompDetails(userCompFactory, def, params, defaultFloatingFilter) { return userCompFactory.getCompDetails(def, FloatingFilterComponent, defaultFloatingFilter, params); } function _getFilterCompKeys(frameworkOverrides, def) { return _getUserCompKeys(frameworkOverrides, def, FilterComponent); } function _mergeFilterParamsWithApplicationProvidedParams(userCompFactory, defObject, paramsFromGrid) { return userCompFactory.mergeParams(defObject, FilterComponent, paramsFromGrid); } // packages/ag-grid-community/src/components/framework/unwrapUserComp.ts function _unwrapUserComp(comp) { const compAsAny = comp; const isProxy = compAsAny != null && compAsAny.getFrameworkComponentInstance != null; return isProxy ? compAsAny.getFrameworkComponentInstance() : comp; } // packages/ag-grid-community/src/modules/moduleRegistry.ts var allRegisteredModules = /* @__PURE__ */ new Set(); var globalModulesMap = {}; var gridModulesMap = {}; var currentModuleVersion; var areGridScopedModules = false; var isUmd = false; function isValidModuleVersion(module2) { const [moduleMajor, moduleMinor] = module2.version.split(".") || []; const [currentModuleMajor, currentModuleMinor] = currentModuleVersion.split(".") || []; return moduleMajor === currentModuleMajor && moduleMinor === currentModuleMinor; } function runVersionChecks(module2) { if (!currentModuleVersion) { currentModuleVersion = module2.version; } const errorMsg = (details) => `You are using incompatible versions of AG Grid modules. Major and minor versions should always match across modules. ${details} Please update all modules to the same version.`; if (!module2.version) { _errorOnce(errorMsg(`'${module2.moduleName}' is incompatible.`)); } else if (!isValidModuleVersion(module2)) { _errorOnce( errorMsg( `'${module2.moduleName}' is version ${module2.version} but the other modules are version ${currentModuleVersion}.` ) ); } if (module2.validate) { const result = module2.validate(); if (!result.isValid) { const errorResult = result; _errorOnce(`${errorResult.message}`); } } } function _registerModule(module2, gridId) { runVersionChecks(module2); const rowModels = module2.rowModels ?? ["all"]; allRegisteredModules.add(module2); let moduleStore; if (gridId !== void 0) { areGridScopedModules = true; if (gridModulesMap[gridId] === void 0) { gridModulesMap[gridId] = {}; } moduleStore = gridModulesMap[gridId]; } else { moduleStore = globalModulesMap; } rowModels.forEach((rowModel) => { if (moduleStore[rowModel] === void 0) { moduleStore[rowModel] = {}; } moduleStore[rowModel][module2.moduleName] = module2; }); if (module2.dependsOn) { module2.dependsOn.forEach((dependency) => _registerModule(dependency, gridId)); } } function _unRegisterGridModules(gridId) { delete gridModulesMap[gridId]; } function _isModuleRegistered(moduleName, gridId, rowModel) { const isRegisteredForRowModel = (model) => !!globalModulesMap[model]?.[moduleName] || !!gridModulesMap[gridId]?.[model]?.[moduleName]; return isRegisteredForRowModel(rowModel) || isRegisteredForRowModel("all"); } function _areModulesGridScoped() { return areGridScopedModules; } function _getRegisteredModules(gridId, rowModel) { const gridModules = gridModulesMap[gridId] ?? {}; return [ ...Object.values(globalModulesMap["all"] ?? {}), ...Object.values(gridModules["all"] ?? {}), ...Object.values(globalModulesMap[rowModel] ?? {}), ...Object.values(gridModules[rowModel] ?? {}) ]; } function _getAllRegisteredModules() { return new Set(allRegisteredModules); } function _getGridRegisteredModules(gridId, rowModel) { const gridModules = gridModulesMap[gridId] ?? {}; return [...Object.values(gridModules["all"] ?? {}), ...Object.values(gridModules[rowModel] ?? {})]; } function _isUmd() { return isUmd; } function _setUmd() { isUmd = true; } var ModuleRegistry = class { /** * @deprecated v33 Use `registerModules([module])` instead. */ static register(module2) { _registerModule(module2, void 0); } /** * Globally register the given modules for all grids. * @param modules - modules to register */ static registerModules(modules) { modules.forEach((module2) => _registerModule(module2, void 0)); } }; // packages/ag-grid-community/src/context/genericContext.ts var GenericContext = class { constructor(params) { this.beans = {}; this.createdBeans = []; this.destroyed = false; if (!params || !params.beanClasses) { return; } this.beanDestroyComparator = params.beanDestroyComparator; this.init(params); } init(params) { for (const beanName of Object.keys(params.providedBeanInstances)) { this.beans[beanName] = params.providedBeanInstances[beanName]; } params.beanClasses.forEach((BeanClass) => { const instance = new BeanClass(); if (instance.beanName) { this.beans[instance.beanName] = instance; } else { console.error(`Bean ${BeanClass.name} is missing beanName`); } this.createdBeans.push(instance); }); params.derivedBeans?.forEach((beanFunc) => { const { beanName, bean } = beanFunc(this); this.beans[beanName] = bean; this.createdBeans.push(bean); }); if (params.beanInitComparator) { this.createdBeans.sort(params.beanInitComparator); } this.initBeans(this.createdBeans); } getBeanInstances() { return Object.values(this.beans); } createBean(bean, afterPreCreateCallback) { if (!bean) { throw Error("null bean"); } this.initBeans([bean], afterPreCreateCallback); return bean; } initBeans(beanInstances, afterPreCreateCallback) { beanInstances.forEach((instance) => { instance.preWireBeans?.(this.beans); instance.wireBeans?.(this.beans); }); beanInstances.forEach((instance) => instance.preConstruct?.()); if (afterPreCreateCallback) { beanInstances.forEach(afterPreCreateCallback); } beanInstances.forEach((instance) => instance.postConstruct?.()); } getBeans() { return this.beans; } getBean(name) { return this.beans[name]; } destroy() { if (this.destroyed) { return; } this.destroyed = true; const beanInstances = this.getBeanInstances(); if (this.beanDestroyComparator) { beanInstances.sort(this.beanDestroyComparator); } this.destroyBeans(beanInstances); this.beans = {}; this.createdBeans = []; } /** * Destroys a bean and returns undefined to support destruction and clean up in a single line. * this.dateComp = this.context.destroyBean(this.dateComp); */ destroyBean(bean) { bean?.destroy?.(); } /** * Destroys an array of beans and returns an empty array to support destruction and clean up in a single line. * this.dateComps = this.context.destroyBeans(this.dateComps); */ destroyBeans(beans) { if (beans) { for (let i = 0; i < beans.length; i++) { this.destroyBean(beans[i]); } } return []; } isDestroyed() { return this.destroyed; } }; // packages/ag-grid-community/src/context/context.ts var Context = class extends GenericContext { init(params) { this.gridId = params.gridId; this.beans.context = this; this.destroyCallback = params.destroyCallback; super.init(params); } destroy() { super.destroy(); _unRegisterGridModules(this.gridId); this.destroyCallback?.(); } getGridId() { return this.gridId; } }; // packages/ag-grid-community/src/headerRendering/cells/cssClassApplier.ts var CSS_FIRST_COLUMN = "ag-column-first"; var CSS_LAST_COLUMN = "ag-column-last"; function _getHeaderClassesFromColDef(abstractColDef, gos, column, columnGroup) { if (_missing(abstractColDef)) { return []; } return getColumnClassesFromCollDef(abstractColDef.headerClass, abstractColDef, gos, column, columnGroup); } function _getToolPanelClassesFromColDef(abstractColDef, gos, column, columnGroup) { if (_missing(abstractColDef)) { return []; } return getColumnClassesFromCollDef(abstractColDef.toolPanelClass, abstractColDef, gos, column, columnGroup); } function refreshFirstAndLastStyles(comp, column, presentedColsService) { comp.addOrRemoveCssClass(CSS_FIRST_COLUMN, presentedColsService.isColAtEdge(column, "first")); comp.addOrRemoveCssClass(CSS_LAST_COLUMN, presentedColsService.isColAtEdge(column, "last")); } function getClassParams(abstractColDef, gos, column, columnGroup) { return _addGridCommonParams(gos, { // bad naming, as colDef here can be a group or a column, // however most people won't appreciate the difference, // so keeping it as colDef to avoid confusion. colDef: abstractColDef, column, columnGroup }); } function getColumnClassesFromCollDef(classesOrFunc, abstractColDef, gos, column, columnGroup) { if (_missing(classesOrFunc)) { return []; } let classToUse; if (typeof classesOrFunc === "function") { const params = getClassParams(abstractColDef, gos, column, columnGroup); classToUse = classesOrFunc(params); } else { classToUse = classesOrFunc; } if (typeof classToUse === "string") { return [classToUse]; } if (Array.isArray(classToUse)) { return [...classToUse]; } return []; } // packages/ag-grid-community/src/misc/animationFrameService.ts function _requestAnimationFrame(beans, callback) { const win = _getWindow(beans); if (win.requestAnimationFrame) { win.requestAnimationFrame(callback); } else if (win.webkitRequestAnimationFrame) { win.webkitRequestAnimationFrame(callback); } else { win.setTimeout(callback, 0); } } var AnimationFrameService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "animationFrameSvc"; // p1 and p2 are create tasks are to do with row and cell creation. // for them we want to execute according to row order, so we use // TaskItem so we know what index the item is for. this.createTasksP1 = { list: [], sorted: false }; // eg drawing back-ground of rows this.createTasksP2 = { list: [], sorted: false }; // eg cell renderers, adding hover functionality // destroy tasks are to do with row removal. they are done after row creation as the user will need to see new // rows first (as blank is scrolled into view), when we remove the old rows (no longer in view) is not as // important. this.destroyTasks = []; this.ticking = false; // we need to know direction of scroll, to build up rows in the direction of // the scroll. eg if user scrolls down, we extend the rows by building down. this.scrollGoingDown = true; this.lastPage = 0; this.lastScrollTop = 0; this.taskCount = 0; this.cancelledTasks = /* @__PURE__ */ new Set(); } setScrollTop(scrollTop) { const { gos, pagination } = this.beans; const isPaginationActive = gos.get("pagination"); this.scrollGoingDown = scrollTop >= this.lastScrollTop; if (isPaginationActive && scrollTop === 0) { const currentPage = pagination?.getCurrentPage() ?? 0; if (currentPage !== this.lastPage) { this.lastPage = currentPage; this.scrollGoingDown = true; } } this.lastScrollTop = scrollTop; } postConstruct() { this.active = !this.gos.get("suppressAnimationFrame"); } // this method is for our AG Grid sanity only - if animation frames are turned off, // then no place in the code should be looking to add any work to be done in animation // frames. this stops bugs - where some code is asking for a frame to be executed // when it should not. verifyAnimationFrameOn(methodName) { if (this.active === false) { _warn(92, { methodName }); } } createTask(task, index, list) { this.verifyAnimationFrameOn(list); const taskItem = { task, index, createOrder: ++this.taskCount }; this.addTaskToList(this[list], taskItem); this.schedule(); } cancelTask(task) { this.cancelledTasks.add(task); } addTaskToList(taskList, task) { taskList.list.push(task); taskList.sorted = false; } sortTaskList(taskList) { if (taskList.sorted) { return; } const sortDirection = this.scrollGoingDown ? 1 : -1; taskList.list.sort( (a, b) => a.index !== b.index ? sortDirection * (b.index - a.index) : b.createOrder - a.createOrder ); taskList.sorted = true; } addDestroyTask(task) { this.verifyAnimationFrameOn("createTasksP3"); this.destroyTasks.push(task); this.schedule(); } executeFrame(millis) { this.verifyAnimationFrameOn("executeFrame"); const p1TaskList = this.createTasksP1; const p1Tasks = p1TaskList.list; const p2TaskList = this.createTasksP2; const p2Tasks = p2TaskList.list; const destroyTasks = this.destroyTasks; const frameStart = (/* @__PURE__ */ new Date()).getTime(); let duration = (/* @__PURE__ */ new Date()).getTime() - frameStart; const noMaxMillis = millis <= 0; const scrollFeature = this.beans.ctrlsSvc.getScrollFeature(); while (noMaxMillis || duration < millis) { const gridBodyDidSomething = scrollFeature.scrollGridIfNeeded(); if (!gridBodyDidSomething) { let task; if (p1Tasks.length) { this.sortTaskList(p1TaskList); task = p1Tasks.pop().task; } else if (p2Tasks.length) { this.sortTaskList(p2TaskList); task = p2Tasks.pop().task; } else if (destroyTasks.length) { task = destroyTasks.pop(); } else { this.cancelledTasks.clear(); break; } if (!this.cancelledTasks.has(task)) { task(); } } duration = (/* @__PURE__ */ new Date()).getTime() - frameStart; } if (p1Tasks.length || p2Tasks.length || destroyTasks.length) { this.requestFrame(); } else { this.ticking = false; } } flushAllFrames() { if (!this.active) { return; } this.executeFrame(-1); } schedule() { if (!this.active) { return; } if (!this.ticking) { this.ticking = true; this.requestFrame(); } } requestFrame() { const callback = this.executeFrame.bind(this, 60); _requestAnimationFrame(this.beans, callback); } isQueueEmpty() { return !this.ticking; } }; // packages/ag-grid-community/src/constants/keyCode.ts var KeyCode = { BACKSPACE: "Backspace", TAB: "Tab", ENTER: "Enter", ESCAPE: "Escape", SPACE: " ", LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", DOWN: "ArrowDown", DELETE: "Delete", F2: "F2", PAGE_UP: "PageUp", PAGE_DOWN: "PageDown", PAGE_HOME: "Home", PAGE_END: "End", // these should be used with `event.code` instead of `event.key` // as `event.key` changes when non-latin keyboards are used A: "KeyA", C: "KeyC", D: "KeyD", V: "KeyV", X: "KeyX", Y: "KeyY", Z: "KeyZ" }; // packages/ag-grid-community/src/utils/focus.ts var keyboardModeActive = false; var instanceCount = 0; function addKeyboardModeEvents(doc) { if (instanceCount > 0) { return; } doc.addEventListener("keydown", toggleKeyboardMode); doc.addEventListener("mousedown", toggleKeyboardMode); } function removeKeyboardModeEvents(doc) { if (instanceCount > 0) return; doc.removeEventListener("keydown", toggleKeyboardMode); doc.removeEventListener("mousedown", toggleKeyboardMode); } function toggleKeyboardMode(event) { const isKeyboardActive = keyboardModeActive; const isKeyboardEvent = event.type === "keydown"; if (isKeyboardEvent) { if (event.ctrlKey || event.metaKey || event.altKey) { return; } } if (isKeyboardActive === isKeyboardEvent) { return; } keyboardModeActive = isKeyboardEvent; } function _registerKeyboardFocusEvents(beans) { const eDocument = _getDocument(beans); addKeyboardModeEvents(eDocument); instanceCount++; return () => { instanceCount--; removeKeyboardModeEvents(eDocument); }; } function _isKeyboardMode() { return keyboardModeActive; } function _addFocusableContainerListener(beans, comp, eGui) { comp.addManagedElementListeners(eGui, { keydown: (e) => { if (!e.defaultPrevented && e.key === KeyCode.TAB) { const backwards = e.shiftKey; if (!_findNextFocusableElement(beans, eGui, false, backwards)) { if (_focusNextGridCoreContainer(beans, backwards)) { e.preventDefault(); } } } } }); } function _findFocusableElements(rootNode, exclude, onlyUnmanaged = false) { const focusableString = FOCUSABLE_SELECTOR; let excludeString = FOCUSABLE_EXCLUDE; if (exclude) { excludeString += ", " + exclude; } if (onlyUnmanaged) { excludeString += ', [tabindex="-1"]'; } const nodes = Array.prototype.slice.apply(rootNode.querySelectorAll(focusableString)).filter((node) => { return _isVisible(node); }); const excludeNodes = Array.prototype.slice.apply(rootNode.querySelectorAll(excludeString)); if (!excludeNodes.length) { return nodes; } const diff = (a, b) => a.filter((element) => b.indexOf(element) === -1); return diff(nodes, excludeNodes); } function _focusInto(rootNode, up = false, onlyUnmanaged = false, excludeTabGuards = false) { const focusableElements = _findFocusableElements( rootNode, excludeTabGuards ? ".ag-tab-guard" : null, onlyUnmanaged ); const toFocus = up ? _last(focusableElements) : focusableElements[0]; if (toFocus) { toFocus.focus({ preventScroll: true }); return true; } return false; } function _findNextFocusableElement(beans, rootNode, onlyManaged, backwards) { const focusable = _findFocusableElements(rootNode, onlyManaged ? ':not([tabindex="-1"])' : null); const activeEl = _getActiveDomElement(beans); let currentIndex; if (onlyManaged) { currentIndex = focusable.findIndex((el) => el.contains(activeEl)); } else { currentIndex = focusable.indexOf(activeEl); } const nextIndex = currentIndex + (backwards ? -1 : 1); if (nextIndex < 0 || nextIndex >= focusable.length) { return null; } return focusable[nextIndex]; } function _findTabbableParent(node, limit = 5) { let counter = 0; while (node && _getTabIndex(node) === null && ++counter <= limit) { node = node.parentElement; } if (_getTabIndex(node) === null) { return null; } return node; } function _focusGridInnerElement(beans, fromBottom) { return beans.ctrlsSvc.get("gridCtrl").focusInnerElement(fromBottom); } function _isHeaderFocusSuppressed(beans) { return beans.gos.get("suppressHeaderFocus") || !!beans.overlays?.isExclusive(); } function _isCellFocusSuppressed(beans) { return beans.gos.get("suppressCellFocus") || !!beans.overlays?.isExclusive(); } function _focusNextGridCoreContainer(beans, backwards, forceOut = false) { const gridCtrl = beans.ctrlsSvc.get("gridCtrl"); if (!forceOut && gridCtrl.focusNextInnerContainer(backwards)) { return true; } if (forceOut || !backwards && !gridCtrl.isDetailGrid()) { gridCtrl.forceFocusOutOfContainer(backwards); } return false; } // packages/ag-grid-community/src/rendering/cell/cellKeyboardListenerFeature.ts function _isDeleteKey(key, alwaysReturnFalseOnBackspace = false) { if (key === KeyCode.DELETE) { return true; } if (!alwaysReturnFalseOnBackspace && key === KeyCode.BACKSPACE) { return _isMacOsUserAgent(); } return false; } var CellKeyboardListenerFeature = class extends BeanStub { constructor(cellCtrl, beans, rowNode, rowCtrl) { super(); this.cellCtrl = cellCtrl; this.rowNode = rowNode; this.rowCtrl = rowCtrl; this.beans = beans; } init() { this.eGui = this.cellCtrl.eGui; } onKeyDown(event) { const key = event.key; switch (key) { case KeyCode.ENTER: this.onEnterKeyDown(event); break; case KeyCode.F2: this.onF2KeyDown(event); break; case KeyCode.ESCAPE: this.onEscapeKeyDown(event); break; case KeyCode.TAB: this.onTabKeyDown(event); break; case KeyCode.BACKSPACE: case KeyCode.DELETE: this.onBackspaceOrDeleteKeyDown(key, event); break; case KeyCode.DOWN: case KeyCode.UP: case KeyCode.RIGHT: case KeyCode.LEFT: this.onNavigationKeyDown(event, key); break; } } onNavigationKeyDown(event, key) { if (this.cellCtrl.editing) { return; } if (event.shiftKey && this.cellCtrl.isRangeSelectionEnabled()) { this.onShiftRangeSelect(event); } else { const currentCellPosition = this.cellCtrl.getFocusedCellPosition(); this.beans.navigation?.navigateToNextCell(event, key, currentCellPosition, true); } event.preventDefault(); } onShiftRangeSelect(event) { const { rangeSvc, navigation } = this.beans; if (!rangeSvc) { return; } const endCell = rangeSvc.extendLatestRangeInDirection(event); if (endCell) { navigation?.ensureCellVisible(endCell); } } onTabKeyDown(event) { this.beans.navigation?.onTabKeyDown(this.cellCtrl, event); } onBackspaceOrDeleteKeyDown(key, event) { const { cellCtrl, beans, rowNode } = this; const { gos, rangeSvc, eventSvc } = beans; if (cellCtrl.editing) { return; } eventSvc.dispatchEvent({ type: "keyShortcutChangedCellStart" }); if (_isDeleteKey(key, gos.get("enableCellEditingOnBackspace"))) { if (rangeSvc && _isCellSelectionEnabled(gos)) { rangeSvc.clearCellRangeCellValues({ dispatchWrapperEvents: true, wrapperEventSource: "deleteKey" }); } else if (cellCtrl.isCellEditable()) { const { column } = cellCtrl; const emptyValue = this.beans.valueSvc.getDeleteValue(column, rowNode); rowNode.setDataValue(column, emptyValue, "cellClear"); } } else { beans.editSvc?.startRowOrCellEdit(cellCtrl, key, event); } eventSvc.dispatchEvent({ type: "keyShortcutChangedCellEnd" }); } onEnterKeyDown(e) { const { cellCtrl, beans } = this; if (cellCtrl.editing || this.rowCtrl.editing) { cellCtrl.stopEditingAndFocus(false, e.shiftKey); } else { if (beans.gos.get("enterNavigatesVertically")) { const key = e.shiftKey ? KeyCode.UP : KeyCode.DOWN; beans.navigation?.navigateToNextCell(null, key, cellCtrl.cellPosition, false); } else { beans.editSvc?.startRowOrCellEdit(cellCtrl, KeyCode.ENTER, e); if (cellCtrl.editing) { e.preventDefault(); } } } } onF2KeyDown(event) { const { cellCtrl, beans } = this; if (!cellCtrl.editing) { beans.editSvc?.startRowOrCellEdit(cellCtrl, KeyCode.F2, event); } } // eslint-disable-next-line @typescript-eslint/no-unused-vars onEscapeKeyDown(event) { const { cellCtrl, beans } = this; if (cellCtrl.editing) { beans.editSvc?.stopRowOrCellEdit(cellCtrl, true); cellCtrl.focusCell(true); } } processCharacter(event) { const eventTarget = event.target; const eventOnChildComponent = eventTarget !== this.eGui; if (eventOnChildComponent || this.cellCtrl.editing) { return; } const key = event.key; if (key === KeyCode.SPACE) { this.onSpaceKeyDown(event); } else { if (this.beans.editSvc?.startRowOrCellEdit(this.cellCtrl, key, event)) { event.preventDefault(); } } } onSpaceKeyDown(event) { const { gos } = this.beans; if (!this.cellCtrl.editing && _isRowSelection(gos)) { this.beans.selectionSvc?.handleSelectionEvent(event, this.rowNode, "spaceKey"); } event.preventDefault(); } destroy() { super.destroy(); } }; // packages/ag-grid-community/src/rendering/cell/cellMouseListenerFeature.ts var CellMouseListenerFeature = class extends BeanStub { constructor(cellCtrl, beans, column) { super(); this.cellCtrl = cellCtrl; this.column = column; this.beans = beans; } onMouseEvent(eventName, mouseEvent) { if (_isStopPropagationForAgGrid(mouseEvent)) { return; } switch (eventName) { case "click": this.onCellClicked(mouseEvent); break; case "mousedown": case "touchstart": this.onMouseDown(mouseEvent); break; case "dblclick": this.onCellDoubleClicked(mouseEvent); break; case "mouseout": this.onMouseOut(mouseEvent); break; case "mouseover": this.onMouseOver(mouseEvent); break; } } onCellClicked(mouseEvent) { if (this.beans.touchSvc?.handleCellDoubleClick(this, mouseEvent)) { return; } const { eventSvc, rangeSvc, gos, editSvc } = this.beans; const isMultiKey = mouseEvent.ctrlKey || mouseEvent.metaKey; if (rangeSvc && isMultiKey) { if (rangeSvc.getCellRangeCount(this.cellCtrl.cellPosition) > 1) { rangeSvc.intersectLastRange(true); } } const cellClickedEvent = this.cellCtrl.createEvent(mouseEvent, "cellClicked"); eventSvc.dispatchEvent(cellClickedEvent); const colDef = this.column.getColDef(); if (colDef.onCellClicked) { window.setTimeout(() => { this.beans.frameworkOverrides.wrapOutgoing(() => { colDef.onCellClicked(cellClickedEvent); }); }, 0); } const editOnSingleClick = (gos.get("singleClickEdit") || colDef.singleClickEdit) && !gos.get("suppressClickEdit"); if (editOnSingleClick && !(mouseEvent.shiftKey && rangeSvc?.getCellRanges().length != 0)) { editSvc?.startRowOrCellEdit(this.cellCtrl, void 0, mouseEvent); } } onCellDoubleClicked(mouseEvent) { const { column, beans, cellCtrl } = this; const { eventSvc, frameworkOverrides, gos, editSvc } = beans; const colDef = column.getColDef(); const cellDoubleClickedEvent = cellCtrl.createEvent(mouseEvent, "cellDoubleClicked"); eventSvc.dispatchEvent(cellDoubleClickedEvent); if (typeof colDef.onCellDoubleClicked === "function") { window.setTimeout(() => { frameworkOverrides.wrapOutgoing(() => { colDef.onCellDoubleClicked(cellDoubleClickedEvent); }); }, 0); } const editOnDoubleClick = !gos.get("singleClickEdit") && !gos.get("suppressClickEdit"); if (editOnDoubleClick) { editSvc?.startRowOrCellEdit(cellCtrl, null, mouseEvent); } } onMouseDown(mouseEvent) { const { ctrlKey, metaKey, shiftKey } = mouseEvent; const target = mouseEvent.target; const { cellCtrl, beans } = this; const { eventSvc, rangeSvc, rowNumbersSvc, focusSvc, gos } = beans; if (this.isRightClickInExistingRange(mouseEvent)) { return; } const hasRanges = rangeSvc && !rangeSvc.isEmpty(); const containsWidget = this.containsWidget(target); const { cellPosition } = cellCtrl; const isRowNumberColumn = isRowNumberCol(cellPosition.column); if (rowNumbersSvc && isRowNumberColumn && !rowNumbersSvc.handleMouseDownOnCell(cellPosition, mouseEvent)) { if (rangeSvc) { mouseEvent.preventDefault(); } mouseEvent.stopImmediatePropagation(); return; } if (!shiftKey || !hasRanges) { const isEnableCellTextSelection = gos.get("enableCellTextSelection"); const shouldFocus = isEnableCellTextSelection && mouseEvent.defaultPrevented; const forceBrowserFocus = (_isBrowserSafari() || shouldFocus) && !cellCtrl.editing && !_isFocusableFormField(target) && !containsWidget; cellCtrl.focusCell(forceBrowserFocus); } if (shiftKey && hasRanges && !focusSvc.isCellFocused(cellPosition)) { mouseEvent.preventDefault(); const focusedCellPosition = focusSvc.getFocusedCell(); if (focusedCellPosition) { const { column, rowIndex, rowPinned } = focusedCellPosition; const focusedRowCtrl = beans.rowRenderer.getRowByPosition({ rowIndex, rowPinned }); const focusedCellCtrl = focusedRowCtrl?.getCellCtrl(column); if (focusedCellCtrl?.editing) { focusedCellCtrl.stopEditing(); } focusSvc.setFocusedCell({ column, rowIndex, rowPinned, forceBrowserFocus: true, preventScrollOnBrowserFocus: true }); } } if (containsWidget) { return; } if (rangeSvc) { if (isRowNumberColumn) { mouseEvent.preventDefault(); } if (shiftKey) { rangeSvc.extendLatestRangeToCell(cellPosition); } else { const isMultiKey = ctrlKey || metaKey; rangeSvc.setRangeToCell(cellPosition, isMultiKey); } } eventSvc.dispatchEvent(this.cellCtrl.createEvent(mouseEvent, "cellMouseDown")); } isRightClickInExistingRange(mouseEvent) { const { rangeSvc } = this.beans; if (rangeSvc) { const cellInRange = rangeSvc.isCellInAnyRange(this.cellCtrl.cellPosition); const isRightClick = mouseEvent.button === 2 || mouseEvent.ctrlKey && this.beans.gos.get("allowContextMenuWithControlKey"); if (cellInRange && isRightClick) { return true; } } return false; } containsWidget(target) { return _isElementChildOfClass(target, "ag-selection-checkbox", 3) || _isElementChildOfClass(target, "ag-drag-handle", 3); } onMouseOut(mouseEvent) { if (this.mouseStayingInsideCell(mouseEvent)) { return; } const { eventSvc, colHover } = this.beans; eventSvc.dispatchEvent(this.cellCtrl.createEvent(mouseEvent, "cellMouseOut")); colHover?.clearMouseOver(); } onMouseOver(mouseEvent) { if (this.mouseStayingInsideCell(mouseEvent)) { return; } const { eventSvc, colHover } = this.beans; eventSvc.dispatchEvent(this.cellCtrl.createEvent(mouseEvent, "cellMouseOver")); colHover?.setMouseOver([this.column]); } mouseStayingInsideCell(e) { if (!e.target || !e.relatedTarget) { return false; } const eCell = this.cellCtrl.eGui; const cellContainsTarget = eCell.contains(e.target); const cellContainsRelatedTarget = eCell.contains(e.relatedTarget); return cellContainsTarget && cellContainsRelatedTarget; } destroy() { super.destroy(); } }; // packages/ag-grid-community/src/rendering/cell/cellPositionFeature.ts var CellPositionFeature = class extends BeanStub { constructor(cellCtrl, beans) { super(); this.cellCtrl = cellCtrl; this.beans = beans; this.column = cellCtrl.column; this.rowNode = cellCtrl.rowNode; } setupRowSpan() { this.rowSpan = this.column.getRowSpan(this.rowNode); this.addManagedListeners(this.beans.eventSvc, { newColumnsLoaded: () => this.onNewColumnsLoaded() }); } init() { this.eSetLeft = this.cellCtrl.getRootElement(); this.eContent = this.cellCtrl.eGui; const cellSpan = this.cellCtrl.getCellSpan(); if (!cellSpan) { this.setupColSpan(); this.setupRowSpan(); } this.onLeftChanged(); this.onWidthChanged(); if (!cellSpan) { this._legacyApplyRowSpan(); } if (cellSpan) { this.refreshSpanHeight(cellSpan); this.addManagedListeners(this.beans.eventSvc, { modelUpdated: this.refreshSpanHeight.bind(this, cellSpan), recalculateRowBounds: this.refreshSpanHeight.bind(this, cellSpan) }); } } refreshSpanHeight(cellSpan) { const spanHeight = cellSpan.getCellHeight(); if (spanHeight != null) { this.eContent.style.height = `${spanHeight}px`; } } onNewColumnsLoaded() { const rowSpan = this.column.getRowSpan(this.rowNode); if (this.rowSpan === rowSpan) { return; } this.rowSpan = rowSpan; this._legacyApplyRowSpan(true); } onDisplayColumnsChanged() { const colsSpanning = this.getColSpanningList(); if (!_areEqual(this.colsSpanning, colsSpanning)) { this.colsSpanning = colsSpanning; this.onWidthChanged(); this.onLeftChanged(); } } setupColSpan() { if (this.column.getColDef().colSpan == null) { return; } this.colsSpanning = this.getColSpanningList(); this.addManagedListeners(this.beans.eventSvc, { // because we are col spanning, a reorder of the cols can change what cols we are spanning over displayedColumnsChanged: this.onDisplayColumnsChanged.bind(this), // because we are spanning over multiple cols, we check for width any time any cols width changes. // this is expensive - really we should be explicitly checking only the cols we are spanning over // instead of every col, however it would be tricky code to track the cols we are spanning over, so // because hardly anyone will be using colSpan, am favouring this easier way for more maintainable code. displayedColumnsWidthChanged: this.onWidthChanged.bind(this) }); } onWidthChanged() { if (!this.eContent) { return; } const width = this.getCellWidth(); this.eContent.style.width = `${width}px`; } getCellWidth() { if (!this.colsSpanning) { return this.column.getActualWidth(); } return this.colsSpanning.reduce((width, col) => width + col.getActualWidth(), 0); } getColSpanningList() { const { column, rowNode } = this; const colSpan = column.getColSpan(rowNode); const colsSpanning = []; if (colSpan === 1) { colsSpanning.push(column); } else { let pointer = column; const pinned = column.getPinned(); for (let i = 0; pointer && i < colSpan; i++) { colsSpanning.push(pointer); pointer = this.beans.visibleCols.getColAfter(pointer); if (!pointer || _missing(pointer)) { break; } if (pinned !== pointer.getPinned()) { break; } } } return colsSpanning; } onLeftChanged() { if (!this.eSetLeft) { return; } const left = this.modifyLeftForPrintLayout(this.getCellLeft()); this.eSetLeft.style.left = left + "px"; } getCellLeft() { let mostLeftCol; if (this.beans.gos.get("enableRtl") && this.colsSpanning) { mostLeftCol = _last(this.colsSpanning); } else { mostLeftCol = this.column; } return mostLeftCol.getLeft(); } modifyLeftForPrintLayout(leftPosition) { if (!this.cellCtrl.printLayout || this.column.getPinned() === "left") { return leftPosition; } const { visibleCols } = this.beans; const leftWidth = visibleCols.getColsLeftWidth(); if (this.column.getPinned() === "right") { const bodyWidth = visibleCols.bodyWidth; return leftWidth + bodyWidth + (leftPosition || 0); } return leftWidth + (leftPosition || 0); } _legacyApplyRowSpan(force) { if (this.rowSpan === 1 && !force) { return; } const singleRowHeight = _getRowHeightAsNumber(this.beans); const totalRowHeight = singleRowHeight * this.rowSpan; this.eContent.style.height = `${totalRowHeight}px`; this.eContent.style.zIndex = "1"; } // overriding to make public, as we don't dispose this bean via context destroy() { super.destroy(); } }; // packages/ag-grid-community/src/rendering/cell/cellCtrl.ts var CSS_CELL = "ag-cell"; var CSS_AUTO_HEIGHT = "ag-cell-auto-height"; var CSS_NORMAL_HEIGHT = "ag-cell-normal-height"; var CSS_CELL_FOCUS = "ag-cell-focus"; var CSS_CELL_FIRST_RIGHT_PINNED = "ag-cell-first-right-pinned"; var CSS_CELL_LAST_LEFT_PINNED = "ag-cell-last-left-pinned"; var CSS_CELL_NOT_INLINE_EDITING = "ag-cell-not-inline-editing"; var CSS_CELL_WRAP_TEXT = "ag-cell-wrap-text"; var DOM_DATA_KEY_CELL_CTRL = "cellCtrl"; function _getCellCtrlForEventTarget(gos, eventTarget) { return _getCtrlForEventTarget(gos, eventTarget, DOM_DATA_KEY_CELL_CTRL); } var instanceIdSequence2 = 0; var CellCtrl = class extends BeanStub { constructor(column, rowNode, beans, rowCtrl) { super(); this.column = column; this.rowNode = rowNode; this.rowCtrl = rowCtrl; this.rangeFeature = void 0; this.positionFeature = void 0; this.customStyleFeature = void 0; this.tooltipFeature = void 0; this.mouseListener = void 0; this.keyboardListener = void 0; this.suppressRefreshCell = false; this.onCompAttachedFuncs = []; this.onEditorAttachedFuncs = []; this.beans = beans; const { colId, colIdSanitised } = column; this.instanceId = colId + "-" + instanceIdSequence2++; this.colIdSanitised = colIdSanitised; this.createCellPosition(); this.updateAndFormatValue(false); } shouldRestoreFocus() { return this.beans.focusSvc.shouldRestoreFocus(this.cellPosition); } onFocusOut() { this.beans.focusSvc.clearRestoreFocus(); } addFeatures() { const { beans } = this; this.positionFeature = new CellPositionFeature(this, beans); this.customStyleFeature = beans.cellStyles?.createCellCustomStyleFeature(this, beans); this.mouseListener = new CellMouseListenerFeature(this, beans, this.column); this.keyboardListener = new CellKeyboardListenerFeature(this, beans, this.rowNode, this.rowCtrl); if (this.column.isTooltipEnabled()) { this.enableTooltipFeature(); } const { rangeSvc } = beans; const cellSelectionEnabled = rangeSvc && _isCellSelectionEnabled(beans.gos); if (cellSelectionEnabled) { this.rangeFeature = rangeSvc.createCellRangeFeature(beans, this); } } isCellSpanning() { return false; } getCellSpan() { return void 0; } removeFeatures() { const context = this.beans.context; this.positionFeature = context.destroyBean(this.positionFeature); this.customStyleFeature = context.destroyBean(this.customStyleFeature); this.mouseListener = context.destroyBean(this.mouseListener); this.keyboardListener = context.destroyBean(this.keyboardListener); this.rangeFeature = context.destroyBean(this.rangeFeature); this.disableTooltipFeature(); } enableTooltipFeature(value, shouldDisplayTooltip) { this.tooltipFeature = this.beans.tooltipSvc?.enableCellTooltipFeature(this, value, shouldDisplayTooltip); } disableTooltipFeature() { this.tooltipFeature = this.beans.context.destroyBean(this.tooltipFeature); } setComp(comp, eCell, _eWrapper, eCellWrapper, printLayout, startEditing, compBean) { this.comp = comp; this.eGui = eCell; this.printLayout = printLayout; compBean ?? (compBean = this); this.addDomData(compBean); this.addFeatures(); compBean.addDestroyFunc(() => this.removeFeatures()); this.onSuppressCellFocusChanged(this.beans.gos.get("suppressCellFocus")); this.onCellFocused(this.focusEventToRestore); this.applyStaticCssClasses(); this.setWrapText(); this.onFirstRightPinnedChanged(); this.onLastLeftPinnedChanged(); this.onColumnHover(); this.setupControlComps(); this.setupAutoHeight(eCellWrapper, compBean); this.refreshFirstAndLastStyles(); this.refreshAriaColIndex(); this.positionFeature?.init(); this.customStyleFeature?.setComp(comp); this.tooltipFeature?.refreshTooltip(); this.keyboardListener?.init(); this.rangeFeature?.setComp(comp); if (startEditing && this.isCellEditable()) { this.beans.editSvc?.startEditing(this); } else { this.showValue(false, true); } if (this.onCompAttachedFuncs.length) { this.onCompAttachedFuncs.forEach((func) => func()); this.onCompAttachedFuncs = []; } } setupAutoHeight(eCellWrapper, compBean) { this.isAutoHeight = this.beans.rowAutoHeight?.setupCellAutoHeight(this, eCellWrapper, compBean) ?? false; } getCellAriaRole() { return this.column.getColDef().cellAriaRole ?? "gridcell"; } isCellRenderer() { const colDef = this.column.getColDef(); return colDef.cellRenderer != null || colDef.cellRendererSelector != null; } getValueToDisplay() { return this.valueFormatted ?? this.value; } showValue(forceNewCellRendererInstance, skipRangeHandleRefresh) { const { beans, column, rowNode, rangeFeature } = this; const { userCompFactory } = beans; const valueToDisplay = this.getValueToDisplay(); let compDetails; const isSsrmLoading = rowNode.stub && rowNode.groupData?.[column.getId()] == null; if (isSsrmLoading) { const params = this.createCellRendererParams(); compDetails = _getLoadingCellRendererDetails(userCompFactory, column.getColDef(), params); } else if (this.isCellRenderer()) { const params = this.createCellRendererParams(); compDetails = _getCellRendererDetails(userCompFactory, column.getColDef(), params); } this.comp.setRenderDetails(compDetails, valueToDisplay, forceNewCellRendererInstance); if (!skipRangeHandleRefresh && rangeFeature) { _requestAnimationFrame(beans, () => rangeFeature?.refreshHandle()); } } setupControlComps() { const colDef = this.column.getColDef(); this.includeSelection = this.isIncludeControl(this.isCheckboxSelection(colDef)); this.includeRowDrag = this.isIncludeControl(colDef.rowDrag); this.includeDndSource = this.isIncludeControl(colDef.dndSource); this.comp.setIncludeSelection(this.includeSelection); this.comp.setIncludeDndSource(this.includeDndSource); this.comp.setIncludeRowDrag(this.includeRowDrag); } isForceWrapper() { const forceWrapper = this.beans.gos.get("enableCellTextSelection") || this.column.isAutoHeight(); return forceWrapper; } // eslint-disable-next-line @typescript-eslint/ban-types isIncludeControl(value) { const rowNodePinned = this.rowNode.rowPinned != null; const isFunc = typeof value === "function"; const res = rowNodePinned ? false : isFunc || value === true; return res; } isCheckboxSelection(colDef) { const { rowSelection } = this.beans.gridOptions; return colDef.checkboxSelection || isColumnSelectionCol(this.column) && rowSelection && typeof rowSelection !== "string" && _getCheckboxes(rowSelection); } refreshShouldDestroy() { const colDef = this.column.getColDef(); const selectionChanged = this.includeSelection != this.isIncludeControl(this.isCheckboxSelection(colDef)); const rowDragChanged = this.includeRowDrag != this.isIncludeControl(colDef.rowDrag); const dndSourceChanged = this.includeDndSource != this.isIncludeControl(colDef.dndSource); const autoHeightChanged = this.isAutoHeight != this.column.isAutoHeight(); return selectionChanged || rowDragChanged || dndSourceChanged || autoHeightChanged; } onPopupEditorClosed() { if (!this.editing) { return; } this.stopEditingAndFocus(); } /** * Ends the Cell Editing * @param cancel `True` if the edit process is being canceled. * @returns `True` if the value of the `GridCell` has been updated, otherwise `False`. */ stopEditing(cancel = false) { return this.beans.editSvc?.stopEditing(this, cancel) ?? false; } createCellRendererParams() { const { value, valueFormatted, column, rowNode, comp, eGui, beans: { valueSvc, gos } } = this; const res = _addGridCommonParams(gos, { value, valueFormatted, getValue: () => valueSvc.getValueForDisplay(column, rowNode), setValue: (value2) => valueSvc.setValue(rowNode, column, value2), formatValue: this.formatValue.bind(this), data: rowNode.data, node: rowNode, pinned: column.getPinned(), colDef: column.getColDef(), column, refreshCell: this.refreshCell.bind(this), eGridCell: eGui, eParentOfValue: comp.getParentOfValue(), registerRowDragger: (rowDraggerElement, dragStartPixels, value2, suppressVisibilityChange) => this.registerRowDragger(rowDraggerElement, dragStartPixels, suppressVisibilityChange), setTooltip: (value2, shouldDisplayTooltip) => { gos.assertModuleRegistered("Tooltip", 3); if (this.tooltipFeature) { this.disableTooltipFeature(); } this.enableTooltipFeature(value2, shouldDisplayTooltip); this.tooltipFeature?.refreshTooltip(); } }); return res; } onCellChanged(event) { const eventImpactsThisCell = event.column === this.column; if (eventImpactsThisCell) { this.refreshCell({}); } } refreshOrDestroyCell(params) { if (this.refreshShouldDestroy()) { this.rowCtrl?.recreateCell(this); } else { this.refreshCell(params); } } // + stop editing {forceRefresh: true, suppressFlash: true} // + event cellChanged {} // + cellRenderer.params.refresh() {} -> method passes 'as is' to the cellRenderer, so params could be anything // + rowCtrl: event dataChanged {suppressFlash: !update, newData: !update} // + rowCtrl: api refreshCells() {animate: true/false} // + rowRenderer: api softRefreshView() {} refreshCell(params) { if (this.suppressRefreshCell || this.editing) { return; } const colDef = this.column.getColDef(); const newData = params != null && !!params.newData; const suppressFlash = params != null && !!params.suppressFlash; const noValueProvided = colDef.field == null && colDef.valueGetter == null && colDef.showRowGroup == null; const forceRefresh = params && params.forceRefresh || noValueProvided || newData; const isCellCompReady = !!this.comp; const valuesDifferent = this.updateAndFormatValue(isCellCompReady); const dataNeedsUpdating = forceRefresh || valuesDifferent; if (!isCellCompReady) { return; } if (dataNeedsUpdating) { this.showValue(newData, false); const processingFilterChange = this.beans.filterManager?.isSuppressFlashingCellsBecauseFiltering(); const flashCell = !suppressFlash && !processingFilterChange && colDef.enableCellChangeFlash; if (flashCell) { this.beans.cellFlashSvc?.flashCell(this); } this.customStyleFeature?.applyUserStyles(); this.customStyleFeature?.applyClassesFromColDef(); } this.tooltipFeature?.refreshTooltip(); this.customStyleFeature?.applyCellClassRules(); } // cell editors call this, when they want to stop for reasons other // than what we pick up on. eg selecting from a dropdown ends editing. stopEditingAndFocus(suppressNavigateAfterEdit = false, shiftKey = false) { this.beans.editSvc?.stopEditingAndFocus(this, suppressNavigateAfterEdit, shiftKey); } isCellEditable() { return this.column.isCellEditable(this.rowNode); } formatValue(value) { return this.callValueFormatter(value) ?? value; } callValueFormatter(value) { return this.beans.valueSvc.formatValue(this.column, this.rowNode, value); } updateAndFormatValue(compareValues) { const oldValue = this.value; const oldValueFormatted = this.valueFormatted; this.value = this.beans.valueSvc.getValueForDisplay(this.column, this.rowNode); this.valueFormatted = this.callValueFormatter(this.value); if (compareValues) { return !this.valuesAreEqual(oldValue, this.value) || this.valueFormatted != oldValueFormatted; } return true; } valuesAreEqual(val1, val2) { const colDef = this.column.getColDef(); return colDef.equals ? colDef.equals(val1, val2) : val1 === val2; } addDomData(compBean) { const element = this.eGui; _setDomData(this.beans.gos, element, DOM_DATA_KEY_CELL_CTRL, this); compBean.addDestroyFunc(() => _setDomData(this.beans.gos, element, DOM_DATA_KEY_CELL_CTRL, null)); } createEvent(domEvent, eventType) { const { rowNode, column, value, beans } = this; const event = _addGridCommonParams(beans.gos, { type: eventType, node: rowNode, data: rowNode.data, value, column, colDef: column.getColDef(), rowPinned: rowNode.rowPinned, event: domEvent, rowIndex: rowNode.rowIndex }); return event; } processCharacter(event) { this.keyboardListener?.processCharacter(event); } onKeyDown(event) { this.keyboardListener?.onKeyDown(event); } onMouseEvent(eventName, mouseEvent) { this.mouseListener?.onMouseEvent(eventName, mouseEvent); } getColSpanningList() { return this.positionFeature.getColSpanningList(); } onLeftChanged() { if (!this.comp) { return; } this.positionFeature?.onLeftChanged(); } onDisplayedColumnsChanged() { if (!this.eGui) { return; } this.refreshAriaColIndex(); this.refreshFirstAndLastStyles(); } refreshFirstAndLastStyles() { const { comp, column, beans } = this; refreshFirstAndLastStyles(comp, column, beans.visibleCols); } refreshAriaColIndex() { const colIdx = this.beans.visibleCols.getAriaColIndex(this.column); _setAriaColIndex(this.eGui, colIdx); } onWidthChanged() { return this.positionFeature?.onWidthChanged(); } getRowPosition() { const { rowIndex, rowPinned } = this.cellPosition; return { rowIndex, rowPinned }; } updateRangeBordersIfRangeCount() { if (!this.comp) { return; } this.rangeFeature?.updateRangeBordersIfRangeCount(); } onCellSelectionChanged() { if (!this.comp) { return; } this.rangeFeature?.onCellSelectionChanged(); } isRangeSelectionEnabled() { return this.rangeFeature != null; } focusCell(forceBrowserFocus = false) { this.beans.focusSvc.setFocusedCell({ ...this.getFocusedCellPosition(), forceBrowserFocus }); } onRowIndexChanged() { this.createCellPosition(); this.onCellFocused(); this.rangeFeature?.onCellSelectionChanged(); } onSuppressCellFocusChanged(suppressCellFocus) { const element = this.eGui; if (!element) { return; } if (isRowNumberCol(this.column)) { suppressCellFocus = true; } _addOrRemoveAttribute(element, "tabindex", suppressCellFocus ? void 0 : -1); } onFirstRightPinnedChanged() { if (!this.comp) { return; } const firstRightPinned = this.column.isFirstRightPinned(); this.comp.addOrRemoveCssClass(CSS_CELL_FIRST_RIGHT_PINNED, firstRightPinned); } onLastLeftPinnedChanged() { if (!this.comp) { return; } const lastLeftPinned = this.column.isLastLeftPinned(); this.comp.addOrRemoveCssClass(CSS_CELL_LAST_LEFT_PINNED, lastLeftPinned); } isCellFocused() { return this.beans.focusSvc.isCellFocused(this.cellPosition); } onCellFocused(event) { const { beans } = this; if (_isCellFocusSuppressed(beans)) { return; } const cellFocused = this.isCellFocused(); if (!this.comp) { if (cellFocused && event?.forceBrowserFocus) { this.focusEventToRestore = event; } return; } this.focusEventToRestore = void 0; this.comp.addOrRemoveCssClass(CSS_CELL_FOCUS, cellFocused); if (cellFocused && event && event.forceBrowserFocus) { let focusEl = this.comp.getFocusableElement(); if (this.editing) { const focusableEls = _findFocusableElements(focusEl, null, true); if (focusableEls.length) { focusEl = focusableEls[0]; } } focusEl.focus({ preventScroll: !!event.preventScrollOnBrowserFocus }); } const fullRowEdit = beans.gos.get("editType") === "fullRow"; if (!cellFocused && !fullRowEdit && this.editing) { beans.editSvc?.stopRowOrCellEdit(this); } if (cellFocused) { this.rowCtrl.announceDescription(); } } createCellPosition() { const { rowIndex, rowPinned } = this.rowNode; this.cellPosition = { rowIndex, rowPinned: _makeNull(rowPinned), column: this.column }; } setInlineEditingCss() { this.beans.editSvc?.setInlineEditingCss(this.rowCtrl); } // CSS Classes that only get applied once, they never change applyStaticCssClasses() { const { comp } = this; comp.addOrRemoveCssClass(CSS_CELL, true); comp.addOrRemoveCssClass(CSS_CELL_NOT_INLINE_EDITING, true); const autoHeight = this.column.isAutoHeight() == true; comp.addOrRemoveCssClass(CSS_AUTO_HEIGHT, autoHeight); comp.addOrRemoveCssClass(CSS_NORMAL_HEIGHT, !autoHeight); } onColumnHover() { this.beans.colHover?.onCellColumnHover(this.column, this.comp); } onColDefChanged() { if (!this.comp) { return; } if (this.column.isTooltipEnabled()) { this.disableTooltipFeature(); this.enableTooltipFeature(); } else { this.disableTooltipFeature(); } this.setWrapText(); if (!this.editing) { this.refreshOrDestroyCell({ forceRefresh: true, suppressFlash: true }); } else { this.beans.editSvc?.handleColDefChanged(this); } } setWrapText() { const value = this.column.getColDef().wrapText == true; this.comp.addOrRemoveCssClass(CSS_CELL_WRAP_TEXT, value); } dispatchCellContextMenuEvent(event) { const colDef = this.column.getColDef(); const cellContextMenuEvent = this.createEvent(event, "cellContextMenu"); const { beans } = this; beans.eventSvc.dispatchEvent(cellContextMenuEvent); if (colDef.onCellContextMenu) { window.setTimeout(() => { beans.frameworkOverrides.wrapOutgoing(() => { colDef.onCellContextMenu(cellContextMenuEvent); }); }, 0); } } getCellRenderer() { return this.comp?.getCellRenderer() ?? null; } destroy() { this.onCompAttachedFuncs = []; this.onEditorAttachedFuncs = []; super.destroy(); } createSelectionCheckbox() { const cbSelectionComponent = this.beans.selectionSvc?.createCheckboxSelectionComponent(); if (!cbSelectionComponent) { return void 0; } this.beans.context.createBean(cbSelectionComponent); cbSelectionComponent.init({ rowNode: this.rowNode, column: this.column }); return cbSelectionComponent; } createDndSource() { const dndSourceComp = this.beans.registry.createDynamicBean( "dndSourceComp", false, this.rowNode, this.column, this.eGui ); if (dndSourceComp) { this.beans.context.createBean(dndSourceComp); } return dndSourceComp; } registerRowDragger(customElement, dragStartPixels, suppressVisibilityChange) { if (this.customRowDragComp) { this.customRowDragComp.setDragElement(customElement, dragStartPixels); return; } const newComp = this.createRowDragComp(customElement, dragStartPixels, suppressVisibilityChange); if (newComp) { this.customRowDragComp = newComp; this.addDestroyFunc(() => { this.beans.context.destroyBean(newComp); this.customRowDragComp = null; }); } } createRowDragComp(customElement, dragStartPixels, suppressVisibilityChange) { const rowDragComp = this.beans.rowDragSvc?.createRowDragCompForCell( this.rowNode, this.column, () => this.value, customElement, dragStartPixels, suppressVisibilityChange ); if (!rowDragComp) { return void 0; } this.beans.context.createBean(rowDragComp); return rowDragComp; } cellEditorAttached() { this.onEditorAttachedFuncs.forEach((func) => func()); this.onEditorAttachedFuncs = []; } setFocusedCellPosition(_cellPosition) { } getFocusedCellPosition() { return this.cellPosition; } // used by spannedCellCtrl refreshAriaRowIndex() { } /** * Returns the root element of the cell, could be a span container rather than the cell element. * @returns The root element of the cell. */ getRootElement() { return this.eGui; } }; // packages/ag-grid-community/src/gridBodyComp/mouseEventUtils.ts var GRID_DOM_KEY = "__ag_grid_instance"; function _stampTopLevelGridCompWithGridInstance(gos, eGridDiv) { eGridDiv[GRID_DOM_KEY] = gos.gridInstanceId; } function _isEventFromThisGrid(gos, event) { const res = _isElementInThisGrid(gos, event.target); return res; } function _isElementInThisGrid(gos, element) { let pointer = element; while (pointer) { const instanceId = pointer[GRID_DOM_KEY]; if (_exists(instanceId)) { const eventFromThisGrid = instanceId === gos.gridInstanceId; return eventFromThisGrid; } pointer = pointer.parentElement; } return false; } function _getCellPositionForEvent(gos, event) { return _getCellCtrlForEventTarget(gos, event.target)?.getFocusedCellPosition() ?? null; } function _getNormalisedMousePosition(beans, event) { const gridPanelHasScrolls = _isDomLayout(beans.gos, "normal"); const e = event; let x; let y; if (e.clientX != null || e.clientY != null) { x = e.clientX; y = e.clientY; } else { x = e.x; y = e.y; } if (gridPanelHasScrolls) { const scrollFeature = beans.ctrlsSvc.getScrollFeature(); const vRange = scrollFeature.getVScrollPosition(); const hRange = scrollFeature.getHScrollPosition(); x += hRange.left; y += vRange.top; } return { x, y }; } // packages/ag-grid-community/src/dragAndDrop/dragAndDropService.ts var DragSourceType = /* @__PURE__ */ ((DragSourceType2) => { DragSourceType2[DragSourceType2["ToolPanel"] = 0] = "ToolPanel"; DragSourceType2[DragSourceType2["HeaderCell"] = 1] = "HeaderCell"; DragSourceType2[DragSourceType2["RowDrag"] = 2] = "RowDrag"; DragSourceType2[DragSourceType2["ChartPanel"] = 3] = "ChartPanel"; DragSourceType2[DragSourceType2["AdvancedFilterBuilder"] = 4] = "AdvancedFilterBuilder"; return DragSourceType2; })(DragSourceType || {}); var DragAndDropService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "dragAndDrop"; this.dragSourceAndParamsList = []; this.dropTargets = []; } wireBeans(beans) { this.ctrlsSvc = beans.ctrlsSvc; this.dragSvc = beans.dragSvc; this.environment = beans.environment; this.userCompFactory = beans.userCompFactory; } addDragSource(dragSource, allowTouch = false) { const params = { eElement: dragSource.eElement, dragStartPixels: dragSource.dragStartPixels, onDragStart: this.onDragStart.bind(this, dragSource), onDragStop: this.onDragStop.bind(this), onDragging: this.onDragging.bind(this), onDragCancel: this.onDragCancel.bind(this), includeTouch: allowTouch }; this.dragSourceAndParamsList.push({ params, dragSource }); this.dragSvc.addDragSource(params); } getDragAndDropImageComponent() { const { dragAndDropImageComp } = this; if (!dragAndDropImageComp || !dragAndDropImageComp.comp) { return null; } return dragAndDropImageComp.comp; } removeDragSource(dragSource) { const { dragSourceAndParamsList, dragSvc } = this; const sourceAndParams = dragSourceAndParamsList.find((item) => item.dragSource === dragSource); if (sourceAndParams) { dragSvc.removeDragSource(sourceAndParams.params); _removeFromArray(dragSourceAndParamsList, sourceAndParams); } } destroy() { const { dragSourceAndParamsList, dragSvc, dropTargets } = this; dragSourceAndParamsList.forEach((sourceAndParams) => dragSvc.removeDragSource(sourceAndParams.params)); dragSourceAndParamsList.length = 0; dropTargets.length = 0; this.clearDragAndDropProperties(); super.destroy(); } nudge() { if (this.dragging) { this.onDragging(this.eventLastTime, true); } } onDragStart(dragSource, mouseEvent) { this.dragging = true; this.dragSource = dragSource; this.eventLastTime = mouseEvent; this.dragItem = dragSource.getDragItem(); dragSource.onDragStarted?.(); this.createDragAndDropImageComponent(); } onDragStop(mouseEvent) { this.dragSource?.onDragStopped?.(); const { lastDropTarget } = this; if (lastDropTarget?.onDragStop) { const draggingEvent = this.createDropTargetEvent(lastDropTarget, mouseEvent, null, null, false); lastDropTarget.onDragStop(draggingEvent); } this.clearDragAndDropProperties(); } onDragCancel() { const { dragSource, lastDropTarget } = this; dragSource?.onDragCancelled?.(); if (lastDropTarget?.onDragCancel) { lastDropTarget.onDragCancel( this.createDropTargetEvent(lastDropTarget, this.eventLastTime, null, null, false) ); } this.clearDragAndDropProperties(); } clearDragAndDropProperties() { this.eventLastTime = null; this.dragging = false; this.lastDropTarget = void 0; this.dragItem = null; this.dragSource = null; this.removeDragAndDropImageComponent(); } onDragging(mouseEvent, fromNudge = false) { const hDirection = this.getHorizontalDirection(mouseEvent); const vDirection = this.getVerticalDirection(mouseEvent); this.eventLastTime = mouseEvent; this.positionDragAndDropImageComp(mouseEvent); const validDropTargets = this.dropTargets.filter((target) => this.isMouseOnDropTarget(mouseEvent, target)); const dropTarget = this.findCurrentDropTarget(mouseEvent, validDropTargets); const { lastDropTarget, dragSource, dragAndDropImageComp, dragItem } = this; if (dropTarget !== lastDropTarget) { this.leaveLastTargetIfExists(mouseEvent, hDirection, vDirection, fromNudge); if (lastDropTarget !== null && dropTarget === null) { dragSource?.onGridExit?.(dragItem); } if (lastDropTarget === null && dropTarget !== null) { dragSource?.onGridEnter?.(dragItem); } this.enterDragTargetIfExists(dropTarget, mouseEvent, hDirection, vDirection, fromNudge); if (dropTarget && dragAndDropImageComp) { const { comp, promise } = dragAndDropImageComp; if (comp) { comp.setIcon(dropTarget.getIconName ? dropTarget.getIconName() : null, false); } else { promise.then((resolvedComponent) => { if (resolvedComponent) { resolvedComponent.setIcon(dropTarget.getIconName ? dropTarget.getIconName() : null, false); } }); } } this.lastDropTarget = dropTarget; } else if (dropTarget && dropTarget.onDragging) { const draggingEvent = this.createDropTargetEvent(dropTarget, mouseEvent, hDirection, vDirection, fromNudge); dropTarget.onDragging(draggingEvent); } } getAllContainersFromDropTarget(dropTarget) { const secondaryContainers = dropTarget.getSecondaryContainers ? dropTarget.getSecondaryContainers() : null; const containers = [[dropTarget.getContainer()]]; return secondaryContainers ? containers.concat(secondaryContainers) : containers; } // checks if the mouse is on the drop target. it checks eContainer and eSecondaryContainers isMouseOnDropTarget(mouseEvent, dropTarget) { const allContainersFromDropTarget = this.getAllContainersFromDropTarget(dropTarget); let mouseOverTarget = false; const allContainersIntersect = (mouseEvent2, containers) => { for (const container of containers) { const { width, height, left, right, top, bottom } = container.getBoundingClientRect(); if (width === 0 || height === 0) { return false; } const horizontalFit = mouseEvent2.clientX >= left && mouseEvent2.clientX < right; const verticalFit = mouseEvent2.clientY >= top && mouseEvent2.clientY < bottom; if (!horizontalFit || !verticalFit) { return false; } } return true; }; for (const currentContainers of allContainersFromDropTarget) { if (allContainersIntersect(mouseEvent, currentContainers)) { mouseOverTarget = true; break; } } const { eElement, type } = this.dragSource; if (dropTarget.targetContainsSource && !dropTarget.getContainer().contains(eElement)) { return false; } return mouseOverTarget && dropTarget.isInterestedIn(type, eElement); } findCurrentDropTarget(mouseEvent, validDropTargets) { const len = validDropTargets.length; if (len === 0) { return null; } if (len === 1) { return validDropTargets[0]; } const rootNode = _getRootNode(this.beans); const elementStack = rootNode.elementsFromPoint(mouseEvent.clientX, mouseEvent.clientY); for (const el of elementStack) { for (const dropTarget of validDropTargets) { const containers = this.getAllContainersFromDropTarget(dropTarget).flatMap((a) => a); if (containers.indexOf(el) !== -1) { return dropTarget; } } } return null; } enterDragTargetIfExists(dropTarget, mouseEvent, hDirection, vDirection, fromNudge) { if (!dropTarget) { return; } if (dropTarget.onDragEnter) { const dragEnterEvent = this.createDropTargetEvent( dropTarget, mouseEvent, hDirection, vDirection, fromNudge ); dropTarget.onDragEnter(dragEnterEvent); } } leaveLastTargetIfExists(mouseEvent, hDirection, vDirection, fromNudge) { const { lastDropTarget } = this; if (!lastDropTarget) { return; } if (lastDropTarget.onDragLeave) { const dragLeaveEvent = this.createDropTargetEvent( lastDropTarget, mouseEvent, hDirection, vDirection, fromNudge ); lastDropTarget.onDragLeave(dragLeaveEvent); } const dragAndDropImageComponent = this.getDragAndDropImageComponent(); if (dragAndDropImageComponent) { dragAndDropImageComponent.setIcon(null, false); } } addDropTarget(dropTarget) { this.dropTargets.push(dropTarget); } removeDropTarget(dropTarget) { this.dropTargets = this.dropTargets.filter((target) => target.getContainer() !== dropTarget.getContainer()); } hasExternalDropZones() { return this.dropTargets.some((zones) => zones.external); } findExternalZone(params) { const externalTargets = this.dropTargets.filter((target) => target.external); return externalTargets.find((zone) => zone.getContainer() === params.getContainer()) || null; } isDropZoneWithinThisGrid(draggingEvent) { const gridBodyCon = this.ctrlsSvc.getGridBodyCtrl(); const gridGui = gridBodyCon.eGridBody; const { dropZoneTarget } = draggingEvent; return gridGui.contains(dropZoneTarget); } getHorizontalDirection(event) { const clientX = this.eventLastTime?.clientX; const eClientX = event.clientX; if (clientX === eClientX) { return null; } return clientX > eClientX ? "left" : "right"; } getVerticalDirection(event) { const clientY = this.eventLastTime?.clientY; const eClientY = event.clientY; if (clientY === eClientY) { return null; } return clientY > eClientY ? "up" : "down"; } createDropTargetEvent(dropTarget, event, hDirection, vDirection, fromNudge) { const dropZoneTarget = dropTarget.getContainer(); const rect = dropZoneTarget.getBoundingClientRect(); const { dragItem, dragSource, gos } = this; const x = event.clientX - rect.left; const y = event.clientY - rect.top; return _addGridCommonParams(gos, { event, x, y, vDirection, hDirection, dragSource, fromNudge, dragItem, dropZoneTarget }); } positionDragAndDropImageComp(event) { const dragAndDropImageComponent = this.getDragAndDropImageComponent(); if (!dragAndDropImageComponent) { return; } _anchorElementToMouseMoveEvent(dragAndDropImageComponent.getGui(), event, this.beans); } removeDragAndDropImageComponent() { const { dragAndDropImageComp } = this; if (dragAndDropImageComp) { const { comp } = dragAndDropImageComp; if (comp) { const eGui = comp.getGui(); this.dragAndDropImageParent?.removeChild(eGui); this.destroyBean(comp); } } this.dragAndDropImageComp = null; } createDragAndDropImageComponent() { const { dragSource, gos, userCompFactory } = this; if (!dragSource) { return; } const userCompDetails = _getDragAndDropImageCompDetails( userCompFactory, _addGridCommonParams(gos, { dragSource }) ); if (!userCompDetails) { return; } const promise = userCompDetails.newAgStackInstance(); this.dragAndDropImageComp = { promise }; promise.then((comp) => { if (!comp || !this.isAlive()) { return; } this.processDragAndDropImageComponent(comp); this.dragAndDropImageComp.comp = comp; }); } processDragAndDropImageComponent(dragAndDropImageComponent) { const { dragSource, environment } = this; if (!dragSource) { return; } const eGui = dragAndDropImageComponent.getGui(); eGui.style.setProperty("position", "absolute"); eGui.style.setProperty("z-index", "9999"); _stampTopLevelGridCompWithGridInstance(this.gos, eGui); environment.applyThemeClasses(eGui); dragAndDropImageComponent.setIcon(null, false); let { dragItemName } = dragSource; if (typeof dragItemName === "function") { dragItemName = dragItemName(); } dragAndDropImageComponent.setLabel(dragItemName || ""); eGui.style.top = "20px"; eGui.style.left = "20px"; const targetEl = _getPageBody(this.beans); this.dragAndDropImageParent = targetEl; if (!targetEl) { _warn(54); } else { targetEl.appendChild(eGui); } } registerGridDropTarget(elementFn, ctrl) { const dropTarget = { getContainer: elementFn, isInterestedIn: (type) => type === 1 /* HeaderCell */ || type === 0 /* ToolPanel */, getIconName: () => "notAllowed" }; this.addDropTarget(dropTarget); ctrl.addDestroyFunc(() => this.removeDropTarget(dropTarget)); } }; // packages/ag-grid-community/src/autoScrollService.ts var AutoScrollService = class { constructor(params) { this.tickingInterval = null; this.onScrollCallback = null; this.scrollContainer = params.scrollContainer; this.scrollHorizontally = params.scrollAxis.indexOf("x") !== -1; this.scrollVertically = params.scrollAxis.indexOf("y") !== -1; this.scrollByTick = params.scrollByTick != null ? params.scrollByTick : 20; if (params.onScrollCallback) { this.onScrollCallback = params.onScrollCallback; } if (this.scrollVertically) { this.getVerticalPosition = params.getVerticalPosition; this.setVerticalPosition = params.setVerticalPosition; } if (this.scrollHorizontally) { this.getHorizontalPosition = params.getHorizontalPosition; this.setHorizontalPosition = params.setHorizontalPosition; } this.shouldSkipVerticalScroll = params.shouldSkipVerticalScroll || (() => false); this.shouldSkipHorizontalScroll = params.shouldSkipHorizontalScroll || (() => false); } check(mouseEvent, forceSkipVerticalScroll = false) { const skipVerticalScroll = forceSkipVerticalScroll || this.shouldSkipVerticalScroll(); if (skipVerticalScroll && this.shouldSkipHorizontalScroll()) { return; } const rect = this.scrollContainer.getBoundingClientRect(); const scrollTick = this.scrollByTick; this.tickLeft = mouseEvent.clientX < rect.left + scrollTick; this.tickRight = mouseEvent.clientX > rect.right - scrollTick; this.tickUp = mouseEvent.clientY < rect.top + scrollTick && !skipVerticalScroll; this.tickDown = mouseEvent.clientY > rect.bottom - scrollTick && !skipVerticalScroll; if (this.tickLeft || this.tickRight || this.tickUp || this.tickDown) { this.ensureTickingStarted(); } else { this.ensureCleared(); } } ensureTickingStarted() { if (this.tickingInterval === null) { this.tickingInterval = window.setInterval(this.doTick.bind(this), 100); this.tickCount = 0; } } doTick() { this.tickCount++; const tickAmount = this.tickCount > 20 ? 200 : this.tickCount > 10 ? 80 : 40; if (this.scrollVertically) { const vScrollPosition = this.getVerticalPosition(); if (this.tickUp) { this.setVerticalPosition(vScrollPosition - tickAmount); } if (this.tickDown) { this.setVerticalPosition(vScrollPosition + tickAmount); } } if (this.scrollHorizontally) { const hScrollPosition = this.getHorizontalPosition(); if (this.tickLeft) { this.setHorizontalPosition(hScrollPosition - tickAmount); } if (this.tickRight) { this.setHorizontalPosition(hScrollPosition + tickAmount); } } if (this.onScrollCallback) { this.onScrollCallback(); } } ensureCleared() { if (this.tickingInterval) { window.clearInterval(this.tickingInterval); this.tickingInterval = null; } } }; // packages/ag-grid-community/src/entities/positionUtils.ts function _createCellId(cellPosition) { const { rowIndex, rowPinned, column } = cellPosition; return `${rowIndex}.${rowPinned == null ? "null" : rowPinned}.${column.getId()}`; } function _areCellsEqual(cellA, cellB) { const colsMatch = cellA.column === cellB.column; const floatingMatch = cellA.rowPinned === cellB.rowPinned; const indexMatch = cellA.rowIndex === cellB.rowIndex; return colsMatch && floatingMatch && indexMatch; } function _isRowBefore(rowA, rowB) { switch (rowA.rowPinned) { case "top": if (rowB.rowPinned !== "top") { return true; } break; case "bottom": if (rowB.rowPinned !== "bottom") { return false; } break; default: if (_exists(rowB.rowPinned)) { return rowB.rowPinned !== "top"; } break; } return rowA.rowIndex < rowB.rowIndex; } function _isSameRow(rowA, rowB) { if (!rowA && !rowB) { return true; } if (rowA && !rowB || !rowA && rowB) { return false; } return rowA.rowIndex === rowB.rowIndex && rowA.rowPinned == rowB.rowPinned; } function _getFirstRow(beans) { let rowIndex = 0; let rowPinned; const { pinnedRowModel, rowModel, pageBounds } = beans; if (pinnedRowModel?.getPinnedTopRowCount()) { rowPinned = "top"; } else if (rowModel.getRowCount()) { rowPinned = null; rowIndex = pageBounds.getFirstRow(); } else if (pinnedRowModel?.getPinnedBottomRowCount()) { rowPinned = "bottom"; } return rowPinned === void 0 ? null : { rowIndex, rowPinned }; } function _getLastRow(beans) { let rowIndex; let rowPinned = null; const { pinnedRowModel, pageBounds } = beans; const pinnedBottomCount = pinnedRowModel?.getPinnedBottomRowCount(); const pinnedTopCount = pinnedRowModel?.getPinnedTopRowCount(); if (pinnedBottomCount) { rowPinned = "bottom"; rowIndex = pinnedBottomCount - 1; } else if (beans.rowModel.getRowCount()) { rowPinned = null; rowIndex = pageBounds.getLastRow(); } else if (pinnedTopCount) { rowPinned = "top"; rowIndex = pinnedTopCount - 1; } return rowIndex === void 0 ? null : { rowIndex, rowPinned }; } function _getRowNode(beans, gridRow) { switch (gridRow.rowPinned) { case "top": return beans.pinnedRowModel?.getPinnedTopRow(gridRow.rowIndex); case "bottom": return beans.pinnedRowModel?.getPinnedBottomRow(gridRow.rowIndex); default: return beans.rowModel.getRow(gridRow.rowIndex); } } function _getCellByPosition(beans, cellPosition) { const spannedCellCtrl = beans.spannedRowRenderer?.getCellByPosition(cellPosition); if (spannedCellCtrl) { return spannedCellCtrl; } const rowCtrl = beans.rowRenderer.getRowByPosition(cellPosition); if (!rowCtrl) { return null; } return rowCtrl.getCellCtrl(cellPosition.column); } // packages/ag-grid-community/src/dragAndDrop/rowDragFeature.ts var RowDragFeature = class extends BeanStub { constructor(eContainer) { super(); this.eContainer = eContainer; } postConstruct() { const { rowModel, gos, ctrlsSvc } = this.beans; if (_isClientSideRowModel(gos, rowModel)) { this.clientSideRowModel = rowModel; } ctrlsSvc.whenReady(this, (p) => { const gridBodyCon = p.gridBodyCtrl; this.autoScrollService = new AutoScrollService({ scrollContainer: gridBodyCon.eBodyViewport, scrollAxis: "y", getVerticalPosition: () => gridBodyCon.scrollFeature.getVScrollPosition().top, setVerticalPosition: (position) => gridBodyCon.scrollFeature.setVerticalScrollPosition(position), onScrollCallback: () => { this.onDragging(this.lastDraggingEvent); } }); }); } getContainer() { return this.eContainer; } isInterestedIn(type) { return type === 2 /* RowDrag */; } getIconName() { const managedDrag = this.gos.get("rowDragManaged"); if (managedDrag && this.shouldPreventRowMove()) { return "notAllowed"; } return "move"; } shouldPreventRowMove() { const { rowGroupColsSvc, filterManager, sortSvc } = this.beans; const rowGroupCols = rowGroupColsSvc?.columns ?? []; if (rowGroupCols.length) { return true; } const isFilterPresent = filterManager?.isAnyFilterPresent(); if (isFilterPresent) { return true; } const isSortActive = sortSvc?.isSortActive(); if (isSortActive) { return true; } return false; } getRowNodes(draggingEvent) { if (!this.isFromThisGrid(draggingEvent)) { return draggingEvent.dragItem.rowNodes || []; } const currentNode = draggingEvent.dragItem.rowNode; const isRowDragMultiRow = this.gos.get("rowDragMultiRow"); if (isRowDragMultiRow) { const selectedNodes = [...this.beans.selectionSvc?.getSelectedNodes() ?? []].sort((a, b) => { if (a.rowIndex == null || b.rowIndex == null) { return 0; } return this.getRowIndexNumber(a) - this.getRowIndexNumber(b); }); if (selectedNodes.indexOf(currentNode) !== -1) { return selectedNodes; } } return [currentNode]; } onDragEnter(draggingEvent) { draggingEvent.dragItem.rowNodes = this.getRowNodes(draggingEvent); this.dispatchGridEvent("rowDragEnter", draggingEvent); this.getRowNodes(draggingEvent).forEach((rowNode) => { this.setRowNodeDragging(rowNode, true); }); this.onEnterOrDragging(draggingEvent); } onDragging(draggingEvent) { this.onEnterOrDragging(draggingEvent); } isFromThisGrid(draggingEvent) { const { dragSourceDomDataKey } = draggingEvent.dragSource; return dragSourceDomDataKey === this.gos.getDomDataKey(); } onEnterOrDragging(draggingEvent) { this.dispatchGridEvent("rowDragMove", draggingEvent); this.lastDraggingEvent = draggingEvent; const pixel = _getNormalisedMousePosition(this.beans, draggingEvent).y; const managedDrag = this.gos.get("rowDragManaged"); if (managedDrag) { this.doManagedDrag(draggingEvent, pixel); } this.autoScrollService.check(draggingEvent.event); } doManagedDrag(draggingEvent, pixel) { const { dragAndDrop, gos } = this.beans; const isFromThisGrid = this.isFromThisGrid(draggingEvent); const managedDrag = gos.get("rowDragManaged"); const rowNodes = draggingEvent.dragItem.rowNodes; if (managedDrag && this.shouldPreventRowMove()) { return; } if (gos.get("suppressMoveWhenRowDragging") || !isFromThisGrid) { if (dragAndDrop.isDropZoneWithinThisGrid(draggingEvent)) { this.clientSideRowModel.highlightRowAtPixel(rowNodes[0], pixel); } } else { this.moveRows(rowNodes, pixel); } } getRowIndexNumber(rowNode) { const rowIndexStr = rowNode.getRowIndexString(); return parseInt(_last(rowIndexStr.split("-")), 10); } moveRowAndClearHighlight(draggingEvent) { const clientSideRowModel = this.clientSideRowModel; const lastHighlightedRowNode = clientSideRowModel.getLastHighlightedRowNode(); const isBelow = lastHighlightedRowNode && lastHighlightedRowNode.highlighted === "Below"; const pixel = _getNormalisedMousePosition(this.beans, draggingEvent).y; const rowNodes = draggingEvent.dragItem.rowNodes; let increment = isBelow ? 1 : 0; if (this.isFromThisGrid(draggingEvent)) { rowNodes.forEach((rowNode) => { if (rowNode.rowTop < pixel) { increment -= 1; } }); this.moveRows(rowNodes, pixel, increment); } else { const getRowIdFunc = _getRowIdCallback(this.gos); let addIndex = clientSideRowModel.getRowIndexAtPixel(pixel) + 1; if (clientSideRowModel.getHighlightPosition(pixel) === "Above") { addIndex--; } clientSideRowModel.updateRowData({ add: rowNodes.filter( (node) => !clientSideRowModel.getRowNode( getRowIdFunc?.({ data: node.data, level: 0, rowPinned: node.rowPinned }) ?? node.data.id ) ).map((node) => node.data), addIndex }); } this.clearRowHighlight(); } clearRowHighlight() { this.clientSideRowModel.highlightRowAtPixel(null); } moveRows(rowNodes, pixel, increment = 0) { const focusSvc = this.beans.focusSvc; const cellPosition = focusSvc.getFocusedCell(); const cellCtrl = cellPosition && _getCellByPosition(this.beans, cellPosition); const rowWasMoved = this.clientSideRowModel.ensureRowsAtPixel(rowNodes, pixel, increment); if (rowWasMoved) { if (cellCtrl) { cellCtrl.focusCell(); } else { focusSvc.clearFocusedCell(); } } } addRowDropZone(params) { if (!params.getContainer()) { _warn(55); return; } const dragAndDrop = this.beans.dragAndDrop; if (dragAndDrop.findExternalZone(params)) { _warn(56); return; } let processedParams = { getContainer: params.getContainer }; if (params.fromGrid) { processedParams = params; } else { if (params.onDragEnter) { processedParams.onDragEnter = (e) => { params.onDragEnter(this.draggingToRowDragEvent("rowDragEnter", e)); }; } if (params.onDragLeave) { processedParams.onDragLeave = (e) => { params.onDragLeave(this.draggingToRowDragEvent("rowDragLeave", e)); }; } if (params.onDragging) { processedParams.onDragging = (e) => { params.onDragging(this.draggingToRowDragEvent("rowDragMove", e)); }; } if (params.onDragStop) { processedParams.onDragStop = (e) => { params.onDragStop(this.draggingToRowDragEvent("rowDragEnd", e)); }; } if (params.onDragCancel) { processedParams.onDragCancel = (e) => { params.onDragCancel(this.draggingToRowDragEvent("rowDragCancel", e)); }; } } const dropTarget = { isInterestedIn: (type) => type === 2 /* RowDrag */, getIconName: () => "move", external: true, ...processedParams }; dragAndDrop.addDropTarget(dropTarget); this.addDestroyFunc(() => dragAndDrop.removeDropTarget(dropTarget)); } getRowDropZone(events) { const getContainer = this.getContainer.bind(this); const onDragEnter = this.onDragEnter.bind(this); const onDragLeave = this.onDragLeave.bind(this); const onDragging = this.onDragging.bind(this); const onDragStop = this.onDragStop.bind(this); const onDragCancel = this.onDragCancel.bind(this); let params; if (!events) { params = { getContainer, onDragEnter, onDragLeave, onDragging, onDragStop, onDragCancel, /* @private */ fromGrid: true }; } else { params = { getContainer, onDragEnter: events.onDragEnter ? (e) => { onDragEnter(e); events.onDragEnter(this.draggingToRowDragEvent("rowDragEnter", e)); } : onDragEnter, onDragLeave: events.onDragLeave ? (e) => { onDragLeave(e); events.onDragLeave(this.draggingToRowDragEvent("rowDragLeave", e)); } : onDragLeave, onDragging: events.onDragging ? (e) => { onDragging(e); events.onDragging(this.draggingToRowDragEvent("rowDragMove", e)); } : onDragging, onDragStop: events.onDragStop ? (e) => { onDragStop(e); events.onDragStop(this.draggingToRowDragEvent("rowDragEnd", e)); } : onDragStop, onDragCancel: events.onDragCancel ? (e) => { onDragCancel(e); events.onDragCancel(this.draggingToRowDragEvent("rowDragCancel", e)); } : onDragCancel, fromGrid: true }; } return params; } draggingToRowDragEvent(type, draggingEvent) { const beans = this.beans; const { pageBounds, rowModel, gos } = beans; const yNormalised = _getNormalisedMousePosition(beans, draggingEvent).y; const mouseIsPastLastRow = yNormalised > pageBounds.getCurrentPageHeight(); let overIndex = -1; let overNode; if (!mouseIsPastLastRow) { overIndex = rowModel.getRowIndexAtPixel(yNormalised); overNode = rowModel.getRow(overIndex); } const event = _addGridCommonParams(gos, { type, event: draggingEvent.event, node: draggingEvent.dragItem.rowNode, nodes: draggingEvent.dragItem.rowNodes, overIndex, overNode, y: yNormalised, vDirection: draggingEvent.vDirection }); return event; } dispatchGridEvent(type, draggingEvent) { const event = this.draggingToRowDragEvent(type, draggingEvent); this.eventSvc.dispatchEvent(event); } onDragLeave(draggingEvent) { this.dispatchGridEvent("rowDragLeave", draggingEvent); this.stopDragging(draggingEvent); if (this.gos.get("rowDragManaged")) { this.clearRowHighlight(); } } onDragStop(draggingEvent) { this.dispatchGridEvent("rowDragEnd", draggingEvent); this.stopDragging(draggingEvent); const { dragAndDrop, gos } = this.beans; if (gos.get("rowDragManaged") && (gos.get("suppressMoveWhenRowDragging") || !this.isFromThisGrid(draggingEvent)) && dragAndDrop.isDropZoneWithinThisGrid(draggingEvent)) { this.moveRowAndClearHighlight(draggingEvent); } } onDragCancel(draggingEvent) { this.dispatchGridEvent("rowDragCancel", draggingEvent); this.stopDragging(draggingEvent); const { dragAndDrop, gos } = this.beans; if (gos.get("rowDragManaged") && (gos.get("suppressMoveWhenRowDragging") || !this.isFromThisGrid(draggingEvent)) && dragAndDrop.isDropZoneWithinThisGrid(draggingEvent)) { this.clearRowHighlight(); } } stopDragging(draggingEvent) { this.autoScrollService.ensureCleared(); this.getRowNodes(draggingEvent).forEach((rowNode) => { this.setRowNodeDragging(rowNode, false); }); } setRowNodeDragging(rowNode, dragging) { if (rowNode.dragging !== dragging) { rowNode.dragging = dragging; rowNode.dispatchRowEvent("draggingChanged"); } } }; // packages/ag-grid-community/src/utils/mouse.ts function _areEventsNear(e1, e2, pixelCount) { if (pixelCount === 0) { return false; } const diffX = Math.abs(e1.clientX - e2.clientX); const diffY = Math.abs(e1.clientY - e2.clientY); return Math.max(diffX, diffY) <= pixelCount; } // packages/ag-grid-community/src/dragAndDrop/dragService.ts var DragService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "dragSvc"; this.dragEndFunctions = []; this.dragSources = []; } destroy() { const { dragSources } = this; dragSources.forEach(this.removeListener.bind(this)); dragSources.length = 0; super.destroy(); } removeListener(dragSourceAndListener) { const element = dragSourceAndListener.dragSource.eElement; const mouseDownListener = dragSourceAndListener.mouseDownListener; element.removeEventListener("mousedown", mouseDownListener); if (dragSourceAndListener.touchEnabled) { const touchStartListener = dragSourceAndListener.touchStartListener; element.removeEventListener("touchstart", touchStartListener, { passive: true }); } } removeDragSource(params) { const { dragSources } = this; const dragSourceAndListener = dragSources.find((item) => item.dragSource === params); if (!dragSourceAndListener) { return; } this.removeListener(dragSourceAndListener); _removeFromArray(dragSources, dragSourceAndListener); } addDragSource(params) { const mouseListener = this.onMouseDown.bind(this, params); const { eElement, includeTouch, stopPropagationForTouch } = params; eElement.addEventListener("mousedown", mouseListener); let touchListener = null; const suppressTouch = this.gos.get("suppressTouch"); if (includeTouch && !suppressTouch) { touchListener = (touchEvent) => { if (_isFocusableFormField(touchEvent.target)) { return; } if (stopPropagationForTouch) { touchEvent.stopPropagation(); } this.onTouchStart(params, touchEvent); }; eElement.addEventListener("touchstart", touchListener, { passive: false }); } this.dragSources.push({ dragSource: params, mouseDownListener: mouseListener, touchStartListener: touchListener, touchEnabled: !!includeTouch }); } // gets called whenever mouse down on any drag source onTouchStart(params, touchEvent) { this.currentDragParams = params; this.dragging = false; const touch = touchEvent.touches[0]; this.touchLastTime = touch; this.touchStart = touch; const touchMoveEvent = (e) => this.onTouchMove(e, params.eElement); const touchEndEvent = (e) => this.onTouchUp(e, params.eElement); const documentTouchMove = (e) => { if (e.cancelable) { e.preventDefault(); } }; const target = touchEvent.target; const events = [ // Prevents the page document from moving while we are dragging items around. // preventDefault needs to be called in the touchmove listener and never inside the // touchstart, because using touchstart causes the click event to be cancelled on touch devices. { target: _getRootNode(this.beans), type: "touchmove", listener: documentTouchMove, options: { passive: false } }, { target, type: "touchmove", listener: touchMoveEvent, options: { passive: true } }, { target, type: "touchend", listener: touchEndEvent, options: { passive: true } }, { target, type: "touchcancel", listener: touchEndEvent, options: { passive: true } } ]; this.addTemporaryEvents(events); if (params.dragStartPixels === 0) { this.onCommonMove(touch, this.touchStart, params.eElement); } } // gets called whenever mouse down on any drag source onMouseDown(params, mouseEvent) { const e = mouseEvent; if (params.skipMouseEvent && params.skipMouseEvent(mouseEvent)) { return; } if (e._alreadyProcessedByDragService) { return; } e._alreadyProcessedByDragService = true; if (mouseEvent.button !== 0) { return; } if (this.shouldPreventMouseEvent(mouseEvent)) { mouseEvent.preventDefault(); } this.currentDragParams = params; this.dragging = false; this.mouseStartEvent = mouseEvent; this.startTarget = mouseEvent.target; const mouseMoveEvent = (event) => this.onMouseMove(event, params.eElement); const mouseUpEvent = (event) => this.onMouseUp(event, params.eElement); const contextEvent = (event) => event.preventDefault(); const keydownEvent = (event) => { if (event.key === KeyCode.ESCAPE) { this.cancelDrag(params.eElement); } }; const target = _getRootNode(this.beans); const events = [ { target, type: "mousemove", listener: mouseMoveEvent }, { target, type: "mouseup", listener: mouseUpEvent }, { target, type: "contextmenu", listener: contextEvent }, { target, type: "keydown", listener: keydownEvent } ]; this.addTemporaryEvents(events); if (params.dragStartPixels === 0) { this.onMouseMove(mouseEvent, params.eElement); } } addTemporaryEvents(events) { events.forEach((currentEvent) => { const { target, type, listener, options } = currentEvent; target.addEventListener(type, listener, options); }); this.dragEndFunctions.push(() => { events.forEach((currentEvent) => { const { target, type, listener, options } = currentEvent; target.removeEventListener(type, listener, options); }); }); } // returns true if the event is close to the original event by X pixels either vertically or horizontally. // we only start dragging after X pixels so this allows us to know if we should start dragging yet. isEventNearStartEvent(currentEvent, startEvent) { const { dragStartPixels } = this.currentDragParams; const requiredPixelDiff = _exists(dragStartPixels) ? dragStartPixels : 4; return _areEventsNear(currentEvent, startEvent, requiredPixelDiff); } getFirstActiveTouch(touchList) { for (let i = 0; i < touchList.length; i++) { if (touchList[i].identifier === this.touchStart.identifier) { return touchList[i]; } } return null; } onCommonMove(currentEvent, startEvent, el) { if (!this.dragging) { if (this.isEventNearStartEvent(currentEvent, startEvent)) { return; } this.dragging = true; this.eventSvc.dispatchEvent({ type: "dragStarted", target: el }); this.currentDragParams.onDragStart(startEvent); if (!this.currentDragParams) { this.dragging = false; return; } this.currentDragParams.onDragging(startEvent); } this.currentDragParams?.onDragging(currentEvent); } onTouchMove(touchEvent, el) { const touch = this.getFirstActiveTouch(touchEvent.touches); if (!touch) { return; } this.onCommonMove(touch, this.touchStart, el); } // only gets called after a mouse down - as this is only added after mouseDown // and is removed when mouseUp happens onMouseMove(mouseEvent, el) { if (_isBrowserSafari()) { const eDocument = _getDocument(this.beans); eDocument.getSelection()?.removeAllRanges(); } if (this.shouldPreventMouseEvent(mouseEvent)) { mouseEvent.preventDefault(); } this.onCommonMove(mouseEvent, this.mouseStartEvent, el); } shouldPreventMouseEvent(mouseEvent) { const { gos } = this; const isEnableCellTextSelect = gos.get("enableCellTextSelection"); const isMouseMove = mouseEvent.type === "mousemove"; const isOverFormFieldElement = (mouseEvent2) => { const el = mouseEvent2.target; const tagName = el?.tagName.toLocaleLowerCase(); return !!tagName?.match("^a$|textarea|input|select|button"); }; return ( // when `isEnableCellTextSelect` is `true`, we need to preventDefault on mouseMove // to avoid the grid text being selected while dragging components. isEnableCellTextSelect && isMouseMove && mouseEvent.cancelable && _isEventFromThisGrid(gos, mouseEvent) && !isOverFormFieldElement(mouseEvent) ); } onTouchUp(touchEvent, el) { let touch = this.getFirstActiveTouch(touchEvent.changedTouches); if (!touch) { touch = this.touchLastTime; } this.onUpCommon(touch, el); } onMouseUp(mouseEvent, el) { this.onUpCommon(mouseEvent, el); } onUpCommon(eventOrTouch, el) { if (this.dragging) { this.dragging = false; this.currentDragParams.onDragStop(eventOrTouch); this.eventSvc.dispatchEvent({ type: "dragStopped", target: el }); } this.resetDragProperties(); } cancelDrag(el) { this.eventSvc.dispatchEvent({ type: "dragCancelled", target: el }); this.currentDragParams?.onDragCancel?.(); this.resetDragProperties(); } resetDragProperties() { this.mouseStartEvent = null; this.startTarget = null; this.touchStart = null; this.touchLastTime = null; this.currentDragParams = null; const { dragEndFunctions } = this; dragEndFunctions.forEach((func) => func()); dragEndFunctions.length = 0; } }; // packages/ag-grid-community/src/entities/agColumnGroup.ts function createUniqueColumnGroupId(groupId, instanceId) { return groupId + "_" + instanceId; } function isColumnGroup2(col) { return col instanceof AgColumnGroup; } var AgColumnGroup = class extends BeanStub { constructor(providedColumnGroup, groupId, partId, pinned) { super(); this.providedColumnGroup = providedColumnGroup; this.groupId = groupId; this.partId = partId; this.pinned = pinned; this.isColumn = false; // depends on the open/closed state of the group, only displaying columns are stored here this.displayedChildren = []; // The measured height of this column's header when autoHeaderHeight is enabled this.autoHeaderHeight = null; this.parent = null; } // as the user is adding and removing columns, the groups are recalculated. // this reset clears out all children, ready for children to be added again reset() { this.parent = null; this.children = null; this.displayedChildren = null; } getParent() { return this.parent; } getUniqueId() { return createUniqueColumnGroupId(this.groupId, this.partId); } isEmptyGroup() { return this.displayedChildren.length === 0; } isMoving() { const allLeafColumns = this.getProvidedColumnGroup().getLeafColumns(); if (!allLeafColumns || allLeafColumns.length === 0) { return false; } return allLeafColumns.every((col) => col.isMoving()); } checkLeft() { this.displayedChildren.forEach((child) => { if (isColumnGroup2(child)) { child.checkLeft(); } }); if (this.displayedChildren.length > 0) { if (this.gos.get("enableRtl")) { const lastChild = _last(this.displayedChildren); const lastChildLeft = lastChild.getLeft(); this.setLeft(lastChildLeft); } else { const firstChildLeft = this.displayedChildren[0].getLeft(); this.setLeft(firstChildLeft); } } else { this.setLeft(null); } } getLeft() { return this.left; } getOldLeft() { return this.oldLeft; } setLeft(left) { this.oldLeft = this.left; if (this.left !== left) { this.left = left; this.dispatchLocalEvent({ type: "leftChanged" }); } } getPinned() { return this.pinned; } getGroupId() { return this.groupId; } getPartId() { return this.partId; } getActualWidth() { let groupActualWidth = 0; this.displayedChildren?.forEach((child) => { groupActualWidth += child.getActualWidth(); }); return groupActualWidth; } isResizable() { if (!this.displayedChildren) { return false; } let result = false; this.displayedChildren.forEach((child) => { if (child.isResizable()) { result = true; } }); return result; } getMinWidth() { let result = 0; this.displayedChildren.forEach((groupChild) => { result += groupChild.getMinWidth(); }); return result; } addChild(child) { if (!this.children) { this.children = []; } this.children.push(child); } getDisplayedChildren() { return this.displayedChildren; } getLeafColumns() { const result = []; this.addLeafColumns(result); return result; } getDisplayedLeafColumns() { const result = []; this.addDisplayedLeafColumns(result); return result; } getDefinition() { return this.providedColumnGroup.getColGroupDef(); } getColGroupDef() { return this.providedColumnGroup.getColGroupDef(); } isPadding() { return this.providedColumnGroup.isPadding(); } isExpandable() { return this.providedColumnGroup.isExpandable(); } isExpanded() { return this.providedColumnGroup.isExpanded(); } setExpanded(expanded) { this.providedColumnGroup.setExpanded(expanded); } isAutoHeaderHeight() { return !!this.getColGroupDef()?.autoHeaderHeight; } getAutoHeaderHeight() { return this.autoHeaderHeight; } /** Returns true if the header height has changed */ setAutoHeaderHeight(height) { const changed = height !== this.autoHeaderHeight; this.autoHeaderHeight = height; return changed; } addDisplayedLeafColumns(leafColumns) { this.displayedChildren.forEach((child) => { if (isColumn(child)) { leafColumns.push(child); } else if (isColumnGroup2(child)) { child.addDisplayedLeafColumns(leafColumns); } }); } addLeafColumns(leafColumns) { this.children.forEach((child) => { if (isColumn(child)) { leafColumns.push(child); } else if (isColumnGroup2(child)) { child.addLeafColumns(leafColumns); } }); } getChildren() { return this.children; } getColumnGroupShow() { return this.providedColumnGroup.getColumnGroupShow(); } getProvidedColumnGroup() { return this.providedColumnGroup; } getPaddingLevel() { const parent = this.getParent(); if (!this.isPadding() || !parent || !parent.isPadding()) { return 0; } return 1 + parent.getPaddingLevel(); } calculateDisplayedColumns() { this.displayedChildren = []; let parentWithExpansion = this; while (parentWithExpansion != null && parentWithExpansion.isPadding()) { parentWithExpansion = parentWithExpansion.getParent(); } const isExpandable = parentWithExpansion ? parentWithExpansion.getProvidedColumnGroup().isExpandable() : false; if (!isExpandable) { this.displayedChildren = this.children; this.dispatchLocalEvent({ type: "displayedChildrenChanged" }); return; } this.children.forEach((child) => { const emptyGroup = isColumnGroup2(child) && (!child.displayedChildren || !child.displayedChildren.length); if (emptyGroup) { return; } const headerGroupShow = child.getColumnGroupShow(); switch (headerGroupShow) { case "open": if (parentWithExpansion.getProvidedColumnGroup().isExpanded()) { this.displayedChildren.push(child); } break; case "closed": if (!parentWithExpansion.getProvidedColumnGroup().isExpanded()) { this.displayedChildren.push(child); } break; default: this.displayedChildren.push(child); break; } }); this.dispatchLocalEvent({ type: "displayedChildrenChanged" }); } }; // packages/ag-grid-community/src/entities/rowNode.ts var ROW_ID_PREFIX_ROW_GROUP = "row-group-"; var ROW_ID_PREFIX_TOP_PINNED = "t-"; var ROW_ID_PREFIX_BOTTOM_PINNED = "b-"; var OBJECT_ID_SEQUENCE = 0; var RowNode = class { constructor(beans) { /** `true` if this row is a master row, part of master / detail (ie row can be expanded to show detail) */ this.master = false; /** `true` if this row is a detail row, part of master / detail (ie child row of an expanded master row)*/ this.detail = void 0; /** The current row index. If the row is filtered out or in a collapsed group, this value will be `null`. */ this.rowIndex = null; /** The key for the group eg Ireland, UK, USA */ this.key = null; /** * The index of the row in the source rowData array including any updates via transactions. * It does not change when sorting, filtering, grouping, pivoting or any other UI related operations. * If this is a filler node (a visual row created by AG Grid in tree data or grouping) the value will be `-1`. * * Generally readonly. It is modified only by: * - ClientSideNodeManager, cast to ClientSideNodeManagerRowNode * - ClientSideRowModel, cast to ClientSideRowModelRowNode */ this.sourceRowIndex = -1; /** * Children mapped by the pivot columns. * * TODO: this field is currently used only by the GroupStrategy and Pivot. * TreeStrategy does not use it, and pivot cannot be enabled with tree data. * Creating a new object for every row when not pivoting and not grouping * consumes memory unnecessarily. Setting it to null however currently breaks * transactional updates in groups so this requires a deeper investigation on GroupStrategy. */ this.childrenMapped = {}; /** The TreeNode associated to this row. Used only with tree data. */ this.treeNode = null; /** The flags associated to this node. Used only with tree data. */ this.treeNodeFlags = 0; /** * This will be `true` if it has a rowIndex assigned, otherwise `false`. */ this.displayed = false; /** The row top position in pixels. */ this.rowTop = null; /** The top pixel for this row last time, makes sense if data set was ordered or filtered, * it is used so new rows can animate in from their old position. */ this.oldRowTop = null; /** `true` by default - can be overridden via gridOptions.isRowSelectable(rowNode) */ this.selectable = true; /** * Used by sorting service - to give deterministic sort to groups. Previously we * just id for this, however id is a string and had slower sorting compared to numbers. * If re-naming this property, you must also update `IGNORED_SIBLING_PROPERTIES` */ this.__objectId = OBJECT_ID_SEQUENCE++; /** `true` when nodes with the same id are being removed and added as part of the same batch transaction */ this.alreadyRendered = false; this.highlighted = null; this.hovered = false; this.__selected = false; this.beans = beans; } /** * Replaces the data on the `rowNode`. When this method is called, the grid will refresh the entire rendered row if it is displayed. */ setData(data) { this.setDataCommon(data, false); } // similar to setRowData, however it is expected that the data is the same data item. this // is intended to be used with Redux type stores, where the whole data can be changed. we are // guaranteed that the data is the same entity (so grid doesn't need to worry about the id of the // underlying data changing, hence doesn't need to worry about selection). the grid, upon receiving // dataChanged event, will refresh the cells rather than rip them all out (so user can show transitions). /** * Updates the data on the `rowNode`. When this method is called, the grid will refresh the entire rendered row if it is displayed. */ updateData(data) { this.setDataCommon(data, true); } setDataCommon(data, update) { const { valueCache, selectionSvc, rowSpanSvc } = this.beans; const oldData = this.data; this.data = data; valueCache?.onDataChanged(); this.updateDataOnDetailNode(); selectionSvc?.updateRowSelectable(this); this.resetQuickFilterAggregateText(); const event = this.createDataChangedEvent(data, oldData, update); this.__localEventService?.dispatchEvent(event); rowSpanSvc?.onRowDataUpdated(this); } // when we are doing master / detail, the detail node is lazy created, but then kept around. // so if we show / hide the detail, the same detail rowNode is used. so we need to keep the data // in sync, otherwise expand/collapse of the detail would still show the old values. updateDataOnDetailNode() { if (this.detailNode) { this.detailNode.data = this.data; } } createDataChangedEvent(newData, oldData, update) { return { type: "dataChanged", node: this, oldData, newData, update }; } getRowIndexString() { if (this.rowIndex == null) { _error(13); return null; } if (this.rowPinned === "top") { return ROW_ID_PREFIX_TOP_PINNED + this.rowIndex; } if (this.rowPinned === "bottom") { return ROW_ID_PREFIX_BOTTOM_PINNED + this.rowIndex; } return this.rowIndex.toString(); } setDataAndId(data, id) { const { selectionSvc } = this.beans; const oldNode = selectionSvc?.createDaemonNode?.(this); const oldData = this.data; this.data = data; this.updateDataOnDetailNode(); this.setId(id); if (selectionSvc) { selectionSvc.updateRowSelectable(this); selectionSvc.syncInRowNode(this, oldNode); } const event = this.createDataChangedEvent(data, oldData, false); this.__localEventService?.dispatchEvent(event); } setId(id) { const getRowIdFunc = _getRowIdCallback(this.beans.gos); if (getRowIdFunc) { if (this.data) { const parentKeys = this.parent?.getRoute() ?? []; this.id = getRowIdFunc({ data: this.data, parentKeys: parentKeys.length > 0 ? parentKeys : void 0, level: this.level, rowPinned: this.rowPinned }); if (this.id.startsWith(ROW_ID_PREFIX_ROW_GROUP)) { _error(14, { groupPrefix: ROW_ID_PREFIX_ROW_GROUP }); } } else { this.id = void 0; } } else { this.id = id; } } setRowTop(rowTop) { this.oldRowTop = this.rowTop; if (this.rowTop === rowTop) { return; } this.rowTop = rowTop; this.dispatchRowEvent("topChanged"); this.setDisplayed(rowTop !== null); } clearRowTopAndRowIndex() { this.oldRowTop = null; this.setRowTop(null); this.setRowIndex(null); } setHovered(hovered) { this.hovered = hovered; } isHovered() { return this.hovered; } /** * Sets the row height. * Call if you want to change the height initially assigned to the row. * After calling, you must call `api.onRowHeightChanged()` so the grid knows it needs to work out the placement of the rows. */ setRowHeight(rowHeight, estimated = false) { this.rowHeight = rowHeight; this.rowHeightEstimated = estimated; this.dispatchRowEvent("heightChanged"); } setExpanded(expanded, e, forceSync) { this.beans.expansionSvc?.setExpanded(this, expanded, e, forceSync); } /** * Replaces the value on the `rowNode` for the specified column. When complete, * the grid will refresh the rendered cell on the required row only. * **Note**: This method only fires `onCellEditRequest` when the Grid is in **Read Only** mode. * * @param colKey The column where the value should be updated * @param newValue The new value * @param eventSource The source of the event * @returns `true` if the value was changed, otherwise `false`. */ setDataValue(colKey, newValue, eventSource) { const { colModel, valueSvc, gos, selectionSvc, rowSpanSvc } = this.beans; const column = typeof colKey !== "string" ? colKey : colModel.getCol(colKey) ?? colModel.getColDefCol(colKey); if (!column) { return false; } const oldValue = valueSvc.getValueForDisplay(column, this); if (gos.get("readOnlyEdit")) { const { beans: { eventSvc }, data, rowIndex, rowPinned } = this; eventSvc.dispatchEvent({ type: "cellEditRequest", event: null, rowIndex, rowPinned, column, colDef: column.colDef, data, node: this, oldValue, newValue, value: newValue, source: eventSource }); return false; } const valueChanged = valueSvc.setValue(this, column, newValue, eventSource); this.dispatchCellChangedEvent(column, newValue, oldValue); selectionSvc?.updateRowSelectable(this); rowSpanSvc?.onRowDataUpdated(this); return valueChanged; } updateHasChildren() { let newValue = this.group && !this.footer || this.childrenAfterGroup && this.childrenAfterGroup.length > 0; const { rowChildrenSvc } = this.beans; if (rowChildrenSvc) { newValue = rowChildrenSvc.getHasChildrenValue(this); } if (newValue !== this.__hasChildren) { this.__hasChildren = !!newValue; this.dispatchRowEvent("hasChildrenChanged"); } } hasChildren() { if (this.__hasChildren == null) { this.updateHasChildren(); } return this.__hasChildren; } dispatchCellChangedEvent(column, newValue, oldValue) { const cellChangedEvent = { type: "cellChanged", node: this, column, newValue, oldValue }; this.__localEventService?.dispatchEvent(cellChangedEvent); } /** * The first time `quickFilter` runs, the grid creates a one-off string representation of the row. * This string is then used for the quick filter instead of hitting each column separately. * When you edit, using grid editing, this string gets cleared down. * However if you edit without using grid editing, you will need to clear this string down for the row to be updated with the new values. * Otherwise new values will not work with the `quickFilter`. */ resetQuickFilterAggregateText() { this.quickFilterAggregateText = null; } /** Returns: * - `true` if the node can be expanded, i.e it is a group or master row. * - `false` if the node cannot be expanded */ isExpandable() { return this.beans.expansionSvc?.isExpandable(this) ?? false; } /** Returns: * - `true` if node is selected, * - `false` if the node isn't selected * - `undefined` if it's partially selected (group where not all children are selected). */ isSelected() { if (this.footer) { return this.sibling.isSelected(); } return this.__selected; } /** Perform a depth-first search of this node and its children. */ depthFirstSearch(callback) { this.childrenAfterGroup?.forEach((child) => child.depthFirstSearch(callback)); callback(this); } dispatchRowEvent(type) { this.__localEventService?.dispatchEvent({ type, node: this }); } /** * Select (or deselect) the node. * @param newValue -`true` for selection, `false` for deselection. * @param clearSelection - If selecting, then passing `true` will select the node exclusively (i.e. NOT do multi select). If doing deselection, `clearSelection` has no impact. * @param source - Source property that will appear in the `selectionChanged` event. */ setSelected(newValue, clearSelection = false, source = "api") { this.beans.selectionSvc?.setNodesSelected({ nodes: [this], newValue, clearSelection, source }); } /** * Returns: * - `true` if node is either pinned to the `top` or `bottom` * - `false` if the node isn't pinned */ isRowPinned() { return !!this.rowPinned; } __addEventListener(eventType, listener) { if (!this.__localEventService) { this.__localEventService = new LocalEventService(); } this.__localEventService.addEventListener(eventType, listener); } __removeEventListener(eventType, listener) { this.removeLocalListener(eventType, listener); } /** * PUBLIC USE ONLY: for internal use within AG Grid use the `__addEventListener` and `__removeEventListener` methods. */ addEventListener(eventType, userListener) { this.beans.validation?.checkRowEvents(eventType); if (!this.__localEventService) { this.__localEventService = new LocalEventService(); } this.frameworkEventListenerService = this.beans.frameworkOverrides.createLocalEventListenerWrapper?.( this.frameworkEventListenerService, this.__localEventService ); const listener = this.frameworkEventListenerService?.wrap(userListener) ?? userListener; this.__localEventService.addEventListener(eventType, listener); } /** * PUBLIC USE ONLY: for internal use within AG Grid use the `__addEventListener` and `__removeEventListener` methods. */ removeEventListener(eventType, userListener) { const listener = this.frameworkEventListenerService?.unwrap(userListener) ?? userListener; this.removeLocalListener(eventType, listener); } removeLocalListener(eventType, listener) { this.__localEventService?.removeEventListener(eventType, listener); if (this.__localEventService?.noRegisteredListenersExist()) { this.__localEventService = null; } } /** * @deprecated v32.2.0 Check `node.detail` then user provided callback `isFullWidthRow` instead. * * Returns: * - `true` if the node is a full width cell * - `false` if the node is not a full width cell */ isFullWidthCell() { _warn(61); if (this.detail) { return true; } const isFullWidthCellFunc = this.beans.gos.getCallback("isFullWidthRow"); return isFullWidthCellFunc ? isFullWidthCellFunc({ rowNode: this }) : false; } /** * Returns the route of keys to the row node. Returns undefined if the node has no key. */ getRoute() { if (this.level === -1) { return []; } if (this.key == null) { return void 0; } const res = []; let pointer = this; while (pointer && pointer.key != null) { res.push(pointer.key); pointer = pointer.parent; } return res.reverse(); } setFirstChild(firstChild) { if (this.firstChild !== firstChild) { this.firstChild = firstChild; this.dispatchRowEvent("firstChildChanged"); } } setDisplayed(displayed) { if (this.displayed !== displayed) { this.displayed = displayed; this.dispatchRowEvent("displayedChanged"); } } setRowIndex(rowIndex) { if (this.rowIndex !== rowIndex) { this.rowIndex = rowIndex; this.dispatchRowEvent("rowIndexChanged"); } } setAllChildrenCount(allChildrenCount) { if (this.allChildrenCount !== allChildrenCount) { this.allChildrenCount = allChildrenCount; this.dispatchRowEvent("allChildrenCountChanged"); } } setUiLevel(uiLevel) { if (this.uiLevel !== uiLevel) { this.uiLevel = uiLevel; this.dispatchRowEvent("uiLevelChanged"); } } }; // packages/ag-grid-community/src/entities/rowNodeUtils.ts function _createGlobalRowEvent(rowNode, gos, type) { return _addGridCommonParams(gos, { type, node: rowNode, data: rowNode.data, rowIndex: rowNode.rowIndex, rowPinned: rowNode.rowPinned }); } // packages/ag-grid-community/src/filter/filterWrapperComp.ts var FilterWrapperComp = class extends Component { constructor(column, source) { super( /* html */ `
` ); this.column = column; this.source = source; this.filterWrapper = null; } postConstruct() { this.createFilter(true); this.addManagedEventListeners({ filterDestroyed: this.onFilterDestroyed.bind(this) }); } hasFilter() { return !!this.filterWrapper; } getFilter() { return this.filterWrapper?.filterPromise ?? null; } afterInit() { return this.filterWrapper?.filterPromise?.then(() => { }) ?? AgPromise.resolve(); } afterGuiAttached(params) { this.filterWrapper?.filterPromise?.then((filter) => { filter?.afterGuiAttached?.(params); }); } afterGuiDetached() { this.filterWrapper?.filterPromise?.then((filter) => { filter?.afterGuiDetached?.(); }); } createFilter(init) { const { column, source } = this; this.filterWrapper = this.beans.filterManager?.getOrCreateFilterWrapper(column) ?? null; if (!this.filterWrapper?.filterPromise) { return; } this.filterWrapper.filterPromise.then((filter) => { const guiFromFilter = filter.getGui(); if (!_exists(guiFromFilter)) { _warn(69, { guiFromFilter }); } this.appendChild(guiFromFilter); if (init) { this.eventSvc.dispatchEvent({ type: "filterOpened", column, source, eGui: this.getGui() }); } }); } onFilterDestroyed(event) { if ((event.source === "api" || event.source === "paramsUpdated") && event.column.getId() === this.column.getId() && this.beans.colModel.getColDefCol(this.column)) { _clearElement(this.getGui()); this.createFilter(); } } destroy() { this.filterWrapper = null; super.destroy(); } }; // packages/ag-grid-community/src/rendering/features/positionableFeature.ts var RESIZE_CONTAINER_STYLE = "ag-resizer-wrapper"; var makeDiv = (dataRefPrefix, classSuffix) => `
`; var RESIZE_TEMPLATE = ( /* html */ `
${makeDiv("eTopLeft", "topLeft")} ${makeDiv("eTop", "top")} ${makeDiv("eTopRight", "topRight")} ${makeDiv("eRight", "right")} ${makeDiv("eBottomRight", "bottomRight")} ${makeDiv("eBottom", "bottom")} ${makeDiv("eBottomLeft", "bottomLeft")} ${makeDiv("eLeft", "left")}
` ); var PositionableFeature = class extends BeanStub { constructor(element, config) { super(); this.element = element; this.dragStartPosition = { x: 0, y: 0 }; this.position = { x: 0, y: 0 }; this.lastSize = { width: -1, height: -1 }; this.positioned = false; this.resizersAdded = false; this.resizeListeners = []; this.boundaryEl = null; this.isResizing = false; this.isMoving = false; this.resizable = {}; this.movable = false; this.currentResizer = null; this.config = Object.assign({}, { popup: false }, config); } wireBeans(beans) { this.popupSvc = beans.popupSvc; this.dragSvc = beans.dragSvc; } center() { const { clientHeight, clientWidth } = this.offsetParent; const x = clientWidth / 2 - this.getWidth() / 2; const y = clientHeight / 2 - this.getHeight() / 2; this.offsetElement(x, y); } initialisePosition() { if (this.positioned) { return; } const { centered, forcePopupParentAsOffsetParent, minWidth, width, minHeight, height, x, y } = this.config; if (!this.offsetParent) { this.setOffsetParent(); } let computedMinHeight = 0; let computedMinWidth = 0; const isElementVisible = _isVisible(this.element); if (isElementVisible) { const boundaryEl = this.findBoundaryElement(); const offsetParentComputedStyles = window.getComputedStyle(boundaryEl); if (offsetParentComputedStyles.minWidth != null) { const paddingWidth = boundaryEl.offsetWidth - this.element.offsetWidth; computedMinWidth = parseInt(offsetParentComputedStyles.minWidth, 10) - paddingWidth; } if (offsetParentComputedStyles.minHeight != null) { const paddingHeight = boundaryEl.offsetHeight - this.element.offsetHeight; computedMinHeight = parseInt(offsetParentComputedStyles.minHeight, 10) - paddingHeight; } } this.minHeight = minHeight || computedMinHeight; this.minWidth = minWidth || computedMinWidth; if (width) { this.setWidth(width); } if (height) { this.setHeight(height); } if (!width || !height) { this.refreshSize(); } if (centered) { this.center(); } else if (x || y) { this.offsetElement(x, y); } else if (isElementVisible && forcePopupParentAsOffsetParent) { let boundaryEl = this.boundaryEl; let initialisedDuringPositioning = true; if (!boundaryEl) { boundaryEl = this.findBoundaryElement(); initialisedDuringPositioning = false; } if (boundaryEl) { const top = parseFloat(boundaryEl.style.top); const left = parseFloat(boundaryEl.style.left); if (initialisedDuringPositioning) { this.offsetElement(isNaN(left) ? 0 : left, isNaN(top) ? 0 : top); } else { this.setPosition(left, top); } } } this.positioned = !!this.offsetParent; } isPositioned() { return this.positioned; } getPosition() { return this.position; } setMovable(movable, moveElement) { if (!this.config.popup || movable === this.movable) { return; } this.movable = movable; const params = this.moveElementDragListener || { eElement: moveElement, onDragStart: this.onMoveStart.bind(this), onDragging: this.onMove.bind(this), onDragStop: this.onMoveEnd.bind(this) }; if (movable) { this.dragSvc?.addDragSource(params); this.moveElementDragListener = params; } else { this.dragSvc?.removeDragSource(params); this.moveElementDragListener = void 0; } } setResizable(resizable) { this.clearResizeListeners(); if (resizable) { this.addResizers(); } else { this.removeResizers(); } if (typeof resizable === "boolean") { if (resizable === false) { return; } resizable = { topLeft: resizable, top: resizable, topRight: resizable, right: resizable, bottomRight: resizable, bottom: resizable, bottomLeft: resizable, left: resizable }; } Object.keys(resizable).forEach((side) => { const resizableStructure = resizable; const isSideResizable = !!resizableStructure[side]; const resizerEl = this.getResizerElement(side); const params = { dragStartPixels: 0, eElement: resizerEl, onDragStart: (e) => this.onResizeStart(e, side), onDragging: this.onResize.bind(this), onDragStop: (e) => this.onResizeEnd(e, side) }; if (isSideResizable || !this.isAlive() && !isSideResizable) { if (isSideResizable) { this.dragSvc?.addDragSource(params); this.resizeListeners.push(params); resizerEl.style.pointerEvents = "all"; } else { resizerEl.style.pointerEvents = "none"; } this.resizable[side] = isSideResizable; } }); } removeSizeFromEl() { this.element.style.removeProperty("height"); this.element.style.removeProperty("width"); this.element.style.removeProperty("flex"); } restoreLastSize() { this.element.style.flex = "0 0 auto"; const { height, width } = this.lastSize; if (width !== -1) { this.element.style.width = `${width}px`; } if (height !== -1) { this.element.style.height = `${height}px`; } } getHeight() { return this.element.offsetHeight; } setHeight(height) { const { popup } = this.config; const eGui = this.element; let isPercent = false; if (typeof height === "string" && height.indexOf("%") !== -1) { _setFixedHeight(eGui, height); height = _getAbsoluteHeight(eGui); isPercent = true; } else { height = Math.max(this.minHeight, height); if (this.positioned) { const availableHeight = this.getAvailableHeight(); if (availableHeight && height > availableHeight) { height = availableHeight; } } } if (this.getHeight() === height) { return; } if (!isPercent) { if (popup) { _setFixedHeight(eGui, height); } else { eGui.style.height = `${height}px`; eGui.style.flex = "0 0 auto"; this.lastSize.height = typeof height === "number" ? height : parseFloat(height); } } else { eGui.style.maxHeight = "unset"; eGui.style.minHeight = "unset"; } } getAvailableHeight() { const { popup, forcePopupParentAsOffsetParent } = this.config; if (!this.positioned) { this.initialisePosition(); } const { clientHeight } = this.offsetParent; if (!clientHeight) { return null; } const elRect = this.element.getBoundingClientRect(); const offsetParentRect = this.offsetParent.getBoundingClientRect(); const yPosition = popup ? this.position.y : elRect.top; const parentTop = popup ? 0 : offsetParentRect.top; let additionalHeight = 0; if (forcePopupParentAsOffsetParent) { const parentEl = this.element.parentElement; if (parentEl) { const { bottom } = parentEl.getBoundingClientRect(); additionalHeight = bottom - elRect.bottom; } } const availableHeight = clientHeight + parentTop - yPosition - additionalHeight; return availableHeight; } getWidth() { return this.element.offsetWidth; } setWidth(width) { const eGui = this.element; const { popup } = this.config; let isPercent = false; if (typeof width === "string" && width.indexOf("%") !== -1) { _setFixedWidth(eGui, width); width = _getAbsoluteWidth(eGui); isPercent = true; } else if (this.positioned) { width = Math.max(this.minWidth, width); const { clientWidth } = this.offsetParent; const xPosition = popup ? this.position.x : this.element.getBoundingClientRect().left; if (clientWidth && width + xPosition > clientWidth) { width = clientWidth - xPosition; } } if (this.getWidth() === width) { return; } if (!isPercent) { if (this.config.popup) { _setFixedWidth(eGui, width); } else { eGui.style.width = `${width}px`; eGui.style.flex = " unset"; this.lastSize.width = typeof width === "number" ? width : parseFloat(width); } } else { eGui.style.maxWidth = "unset"; eGui.style.minWidth = "unset"; } } offsetElement(x = 0, y = 0) { const { forcePopupParentAsOffsetParent } = this.config; const ePopup = forcePopupParentAsOffsetParent ? this.boundaryEl : this.element; if (!ePopup) { return; } this.popupSvc?.positionPopup({ ePopup, keepWithinBounds: true, skipObserver: this.movable || this.isResizable(), updatePosition: () => ({ x, y }) }); this.setPosition(parseFloat(ePopup.style.left), parseFloat(ePopup.style.top)); } constrainSizeToAvailableHeight(constrain) { if (!this.config.forcePopupParentAsOffsetParent) { return; } const applyMaxHeightToElement = () => { const availableHeight = this.getAvailableHeight(); this.element.style.setProperty("max-height", `${availableHeight}px`); }; if (constrain && this.popupSvc) { this.resizeObserverSubscriber = _observeResize( this.beans, this.popupSvc?.getPopupParent(), applyMaxHeightToElement ); } else { this.element.style.removeProperty("max-height"); if (this.resizeObserverSubscriber) { this.resizeObserverSubscriber(); this.resizeObserverSubscriber = void 0; } } } setPosition(x, y) { this.position.x = x; this.position.y = y; } updateDragStartPosition(x, y) { this.dragStartPosition = { x, y }; } calculateMouseMovement(params) { const { e, isLeft, isTop, anywhereWithin, topBuffer } = params; const xDiff = e.clientX - this.dragStartPosition.x; const yDiff = e.clientY - this.dragStartPosition.y; const movementX = this.shouldSkipX(e, !!isLeft, !!anywhereWithin, xDiff) ? 0 : xDiff; const movementY = this.shouldSkipY(e, !!isTop, topBuffer, yDiff) ? 0 : yDiff; return { movementX, movementY }; } shouldSkipX(e, isLeft, anywhereWithin, diff) { const elRect = this.element.getBoundingClientRect(); const parentRect = this.offsetParent.getBoundingClientRect(); const boundaryElRect = this.boundaryEl.getBoundingClientRect(); const xPosition = this.config.popup ? this.position.x : elRect.left; let skipX = xPosition <= 0 && parentRect.left >= e.clientX || parentRect.right <= e.clientX && parentRect.right <= boundaryElRect.right; if (skipX) { return true; } if (isLeft) { skipX = // skip if we are moving to the left and the cursor // is positioned to the right of the left side anchor diff < 0 && e.clientX > xPosition + parentRect.left || // skip if we are moving to the right and the cursor // is positioned to the left of the dialog diff > 0 && e.clientX < xPosition + parentRect.left; } else { if (anywhereWithin) { skipX = diff < 0 && e.clientX > boundaryElRect.right || diff > 0 && e.clientX < xPosition + parentRect.left; } else { skipX = // if the movement is bound to the right side of the dialog // we skip if we are moving to the left and the cursor // is to the right of the dialog diff < 0 && e.clientX > boundaryElRect.right || // or skip if we are moving to the right and the cursor // is to the left of the right side anchor diff > 0 && e.clientX < boundaryElRect.right; } } return skipX; } shouldSkipY(e, isTop, topBuffer = 0, diff) { const elRect = this.element.getBoundingClientRect(); const parentRect = this.offsetParent.getBoundingClientRect(); const boundaryElRect = this.boundaryEl.getBoundingClientRect(); const yPosition = this.config.popup ? this.position.y : elRect.top; let skipY = yPosition <= 0 && parentRect.top >= e.clientY || parentRect.bottom <= e.clientY && parentRect.bottom <= boundaryElRect.bottom; if (skipY) { return true; } if (isTop) { skipY = // skip if we are moving to towards top and the cursor is // below the top anchor + topBuffer // note: topBuffer is used when moving the dialog using the title bar diff < 0 && e.clientY > yPosition + parentRect.top + topBuffer || // skip if we are moving to the bottom and the cursor is // above the top anchor diff > 0 && e.clientY < yPosition + parentRect.top; } else { skipY = // skip if we are moving towards the top and the cursor // is below the bottom anchor diff < 0 && e.clientY > boundaryElRect.bottom || // skip if we are moving towards the bottom and the cursor // is above the bottom anchor diff > 0 && e.clientY < boundaryElRect.bottom; } return skipY; } createResizeMap() { const eGui = this.element; this.resizerMap = { topLeft: { element: eGui.querySelector("[data-ref=eTopLeftResizer]") }, top: { element: eGui.querySelector("[data-ref=eTopResizer]") }, topRight: { element: eGui.querySelector("[data-ref=eTopRightResizer]") }, right: { element: eGui.querySelector("[data-ref=eRightResizer]") }, bottomRight: { element: eGui.querySelector("[data-ref=eBottomRightResizer]") }, bottom: { element: eGui.querySelector("[data-ref=eBottomResizer]") }, bottomLeft: { element: eGui.querySelector("[data-ref=eBottomLeftResizer]") }, left: { element: eGui.querySelector("[data-ref=eLeftResizer]") } }; } addResizers() { if (this.resizersAdded) { return; } const eGui = this.element; if (!eGui) { return; } const parser = new DOMParser(); const resizers = parser.parseFromString(RESIZE_TEMPLATE, "text/html").body; eGui.appendChild(resizers.firstChild); this.createResizeMap(); this.resizersAdded = true; } removeResizers() { this.resizerMap = void 0; const resizerEl = this.element.querySelector(`.${RESIZE_CONTAINER_STYLE}`); if (resizerEl) { this.element.removeChild(resizerEl); } this.resizersAdded = false; } getResizerElement(side) { return this.resizerMap[side].element; } onResizeStart(e, side) { this.boundaryEl = this.findBoundaryElement(); if (!this.positioned) { this.initialisePosition(); } this.currentResizer = { isTop: !!side.match(/top/i), isRight: !!side.match(/right/i), isBottom: !!side.match(/bottom/i), isLeft: !!side.match(/left/i) }; this.element.classList.add("ag-resizing"); this.resizerMap[side].element.classList.add("ag-active"); const { popup, forcePopupParentAsOffsetParent } = this.config; if (!popup && !forcePopupParentAsOffsetParent) { this.applySizeToSiblings(this.currentResizer.isBottom || this.currentResizer.isTop); } this.isResizing = true; this.updateDragStartPosition(e.clientX, e.clientY); } getSiblings() { const element = this.element; const parent = element.parentElement; if (!parent) { return null; } return Array.prototype.slice.call(parent.children).filter((el) => !el.classList.contains("ag-hidden")); } getMinSizeOfSiblings() { const siblings = this.getSiblings() || []; let height = 0; let width = 0; for (let i = 0; i < siblings.length; i++) { const currentEl = siblings[i]; const isFlex = !!currentEl.style.flex && currentEl.style.flex !== "0 0 auto"; if (currentEl === this.element) { continue; } let nextHeight = this.minHeight || 0; let nextWidth = this.minWidth || 0; if (isFlex) { const computedStyle = window.getComputedStyle(currentEl); if (computedStyle.minHeight) { nextHeight = parseInt(computedStyle.minHeight, 10); } if (computedStyle.minWidth) { nextWidth = parseInt(computedStyle.minWidth, 10); } } else { nextHeight = currentEl.offsetHeight; nextWidth = currentEl.offsetWidth; } height += nextHeight; width += nextWidth; } return { height, width }; } applySizeToSiblings(vertical) { let containerToFlex = null; const siblings = this.getSiblings(); if (!siblings) { return; } for (let i = 0; i < siblings.length; i++) { const el = siblings[i]; if (el === containerToFlex) { continue; } if (vertical) { el.style.height = `${el.offsetHeight}px`; } else { el.style.width = `${el.offsetWidth}px`; } el.style.flex = "0 0 auto"; if (el === this.element) { containerToFlex = siblings[i + 1]; } } if (containerToFlex) { containerToFlex.style.removeProperty("height"); containerToFlex.style.removeProperty("min-height"); containerToFlex.style.removeProperty("max-height"); containerToFlex.style.flex = "1 1 auto"; } } isResizable() { return Object.values(this.resizable).some((value) => value); } onResize(e) { if (!this.isResizing || !this.currentResizer) { return; } const { popup, forcePopupParentAsOffsetParent } = this.config; const { isTop, isRight, isBottom, isLeft } = this.currentResizer; const isHorizontal = isRight || isLeft; const isVertical = isBottom || isTop; const { movementX, movementY } = this.calculateMouseMovement({ e, isLeft, isTop }); const xPosition = this.position.x; const yPosition = this.position.y; let offsetLeft = 0; let offsetTop = 0; if (isHorizontal && movementX) { const direction = isLeft ? -1 : 1; const oldWidth = this.getWidth(); const newWidth = oldWidth + movementX * direction; let skipWidth = false; if (isLeft) { offsetLeft = oldWidth - newWidth; if (xPosition + offsetLeft <= 0 || newWidth <= this.minWidth) { skipWidth = true; offsetLeft = 0; } } if (!skipWidth) { this.setWidth(newWidth); } } if (isVertical && movementY) { const direction = isTop ? -1 : 1; const oldHeight = this.getHeight(); const newHeight = oldHeight + movementY * direction; let skipHeight = false; if (isTop) { offsetTop = oldHeight - newHeight; if (yPosition + offsetTop <= 0 || newHeight <= this.minHeight) { skipHeight = true; offsetTop = 0; } } else { if (!this.config.popup && !this.config.forcePopupParentAsOffsetParent && oldHeight < newHeight && this.getMinSizeOfSiblings().height + newHeight > this.element.parentElement.offsetHeight) { skipHeight = true; } } if (!skipHeight) { this.setHeight(newHeight); } } this.updateDragStartPosition(e.clientX, e.clientY); if ((popup || forcePopupParentAsOffsetParent) && offsetLeft || offsetTop) { this.offsetElement(xPosition + offsetLeft, yPosition + offsetTop); } } onResizeEnd(e, side) { this.isResizing = false; this.currentResizer = null; this.boundaryEl = null; this.element.classList.remove("ag-resizing"); this.resizerMap[side].element.classList.remove("ag-active"); this.dispatchLocalEvent({ type: "resize" }); } refreshSize() { const eGui = this.element; if (this.config.popup) { if (!this.config.width) { this.setWidth(eGui.offsetWidth); } if (!this.config.height) { this.setHeight(eGui.offsetHeight); } } } onMoveStart(e) { this.boundaryEl = this.findBoundaryElement(); if (!this.positioned) { this.initialisePosition(); } this.isMoving = true; this.element.classList.add("ag-moving"); this.updateDragStartPosition(e.clientX, e.clientY); } onMove(e) { if (!this.isMoving) { return; } const { x, y } = this.position; let topBuffer; if (this.config.calculateTopBuffer) { topBuffer = this.config.calculateTopBuffer(); } const { movementX, movementY } = this.calculateMouseMovement({ e, isTop: true, anywhereWithin: true, topBuffer }); this.offsetElement(x + movementX, y + movementY); this.updateDragStartPosition(e.clientX, e.clientY); } onMoveEnd() { this.isMoving = false; this.boundaryEl = null; this.element.classList.remove("ag-moving"); } setOffsetParent() { if (this.config.forcePopupParentAsOffsetParent && this.popupSvc) { this.offsetParent = this.popupSvc.getPopupParent(); } else { this.offsetParent = this.element.offsetParent; } } findBoundaryElement() { let el = this.element; while (el) { if (window.getComputedStyle(el).position !== "static") { return el; } el = el.parentElement; } return this.element; } clearResizeListeners() { while (this.resizeListeners.length) { const params = this.resizeListeners.pop(); this.dragSvc?.removeDragSource(params); } } destroy() { super.destroy(); if (this.moveElementDragListener) { this.dragSvc?.removeDragSource(this.moveElementDragListener); } this.constrainSizeToAvailableHeight(false); this.clearResizeListeners(); this.removeResizers(); } }; // packages/ag-grid-community/src/widgets/managedFocusFeature.ts var FOCUS_MANAGED_CLASS = "ag-focus-managed"; var ManagedFocusFeature = class extends BeanStub { constructor(eFocusable, callbacks = {}) { super(); this.eFocusable = eFocusable; this.callbacks = callbacks; this.callbacks = { shouldStopEventPropagation: () => false, onTabKeyDown: (e) => { if (e.defaultPrevented) { return; } const nextRoot = _findNextFocusableElement(this.beans, this.eFocusable, false, e.shiftKey); if (!nextRoot) { return; } nextRoot.focus(); e.preventDefault(); }, ...callbacks }; } postConstruct() { const { eFocusable, callbacks: { onFocusIn, onFocusOut } } = this; eFocusable.classList.add(FOCUS_MANAGED_CLASS); this.addKeyDownListeners(eFocusable); if (onFocusIn) { this.addManagedElementListeners(eFocusable, { focusin: onFocusIn }); } if (onFocusOut) { this.addManagedElementListeners(eFocusable, { focusout: onFocusOut }); } } addKeyDownListeners(eGui) { this.addManagedElementListeners(eGui, { keydown: (e) => { if (e.defaultPrevented || _isStopPropagationForAgGrid(e)) { return; } const { callbacks } = this; if (callbacks.shouldStopEventPropagation(e)) { _stopPropagationForAgGrid(e); return; } if (e.key === KeyCode.TAB) { callbacks.onTabKeyDown(e); } else if (callbacks.handleKeyDown) { callbacks.handleKeyDown(e); } } }); } }; // packages/ag-grid-community/src/filter/filterLocaleText.ts var FILTER_LOCALE_TEXT = { applyFilter: "Apply", clearFilter: "Clear", resetFilter: "Reset", cancelFilter: "Cancel", textFilter: "Text Filter", numberFilter: "Number Filter", dateFilter: "Date Filter", setFilter: "Set Filter", filterOoo: "Filter...", empty: "Choose one", equals: "Equals", notEqual: "Does not equal", lessThan: "Less than", greaterThan: "Greater than", inRange: "Between", inRangeStart: "From", inRangeEnd: "To", lessThanOrEqual: "Less than or equal to", greaterThanOrEqual: "Greater than or equal to", contains: "Contains", notContains: "Does not contain", startsWith: "Begins with", endsWith: "Ends with", blank: "Blank", notBlank: "Not blank", before: "Before", after: "After", andCondition: "AND", orCondition: "OR", dateFormatOoo: "yyyy-mm-dd" }; // packages/ag-grid-community/src/filter/floating/provided/providedFilterUtils.ts function getDebounceMs(params, debounceDefault) { const { debounceMs } = params; if (isUseApplyButton(params)) { if (debounceMs != null) { _warn(71); } return 0; } return debounceMs ?? debounceDefault; } function isUseApplyButton(params) { return (params.buttons?.indexOf("apply") ?? -1) >= 0; } // packages/ag-grid-community/src/filter/provided/providedFilter.ts var ProvidedFilter = class extends Component { constructor(filterNameKey) { super(); this.filterNameKey = filterNameKey; this.applyActive = false; this.hidePopup = null; this.debouncePending = false; // after the user hits 'apply' the model gets copied to here. this is then the model that we use for // all filtering. so if user changes UI but doesn't hit apply, then the UI will be out of sync with this model. // this is what we want, as the UI should only become the 'active' filter once it's applied. when apply is // inactive, this model will be in sync (following the debounce ms). if the UI is not a valid filter // (eg the value is missing so nothing to filter on, or for set filter all checkboxes are checked so filter // not active) then this appliedModel will be null/undefined. this.appliedModel = null; this.eFilterBody = RefPlaceholder; this.buttonListeners = []; // subclasses can override this to provide alternative debounce defaults this.defaultDebounceMs = 0; } postConstruct() { this.resetTemplate(); this.createManagedBean( new ManagedFocusFeature(this.getFocusableElement(), { handleKeyDown: this.handleKeyDown.bind(this) }) ); this.positionableFeature = new PositionableFeature(this.getPositionableElement(), { forcePopupParentAsOffsetParent: true }); this.createBean(this.positionableFeature); } // override // eslint-disable-next-line @typescript-eslint/no-unused-vars handleKeyDown(e) { } getFilterTitle() { return this.translate(this.filterNameKey); } isFilterActive() { return !!this.appliedModel; } resetTemplate(paramsMap) { let eGui = this.getGui(); if (eGui) { eGui.removeEventListener("submit", this.onFormSubmit); } const templateString = ( /* html */ `
${this.createBodyTemplate()}
` ); this.setTemplate(templateString, this.getAgComponents(), paramsMap); eGui = this.getGui(); eGui?.addEventListener("submit", this.onFormSubmit); } isReadOnly() { return !!this.params.readOnly; } init(params) { this.setParams(params); this.resetUiToDefaults(true).then(() => { this.updateUiVisibility(); this.setupOnBtApplyDebounce(); }); } setParams(params) { this.params = params; this.applyActive = isUseApplyButton(params); this.resetButtonsPanel(params); } updateParams(params) { this.params = params; this.applyActive = isUseApplyButton(params); this.resetUiToActiveModel(this.getModel(), () => { this.updateUiVisibility(); this.setupOnBtApplyDebounce(); }); } resetButtonsPanel(newParams, oldParams) { const { buttons: oldButtons, readOnly: oldReadOnly } = oldParams ?? {}; const { buttons, readOnly } = newParams; if (oldReadOnly === readOnly && _jsonEquals(oldButtons, buttons)) { return; } const hasButtons = buttons && buttons.length > 0 && !this.isReadOnly(); if (!this.eButtonsPanel) { if (hasButtons) { this.eButtonsPanel = document.createElement("div"); this.eButtonsPanel.classList.add("ag-filter-apply-panel"); } } else { _clearElement(this.eButtonsPanel); this.buttonListeners.forEach((destroyFunc) => destroyFunc()); this.buttonListeners = []; } if (!hasButtons) { if (this.eButtonsPanel) { _removeFromParent(this.eButtonsPanel); } return; } const fragment = document.createDocumentFragment(); const addButton = (type) => { let clickListener; const text = type ? this.translate(`${type}Filter`) : void 0; switch (type) { case "apply": clickListener = (e) => this.onBtApply(false, false, e); break; case "clear": clickListener = () => this.onBtClear(); break; case "reset": clickListener = () => this.onBtReset(); break; case "cancel": clickListener = (e) => { this.onBtCancel(e); }; break; default: _warn(75); return; } const buttonType = type === "apply" ? "submit" : "button"; const button = _loadTemplate( /* html */ `` ); this.buttonListeners.push(...this.addManagedElementListeners(button, { click: clickListener })); fragment.append(button); }; buttons.forEach((type) => addButton(type)); this.eButtonsPanel.append(fragment); this.getGui().appendChild(this.eButtonsPanel); } setupOnBtApplyDebounce() { const debounceMs = getDebounceMs(this.params, this.defaultDebounceMs); const debounceFunc = _debounce(this, this.checkApplyDebounce.bind(this), debounceMs); this.onBtApplyDebounce = () => { this.debouncePending = true; debounceFunc(); }; } checkApplyDebounce() { if (this.debouncePending) { this.debouncePending = false; this.onBtApply(); } } getModel() { return this.appliedModel ?? null; } setModel(model) { const promise = model != null ? this.setModelIntoUi(model) : this.resetUiToDefaults(); return promise.then(() => { this.updateUiVisibility(); this.applyModel("api"); }); } onBtCancel(e) { this.resetUiToActiveModel(this.getModel(), () => { this.handleCancelEnd(e); }); } handleCancelEnd(e) { if (this.params.closeOnApply) { this.close(e); } } resetUiToActiveModel(currentModel, afterUiUpdatedFunc) { const afterAppliedFunc = () => { this.onUiChanged(false, "prevent"); afterUiUpdatedFunc?.(); }; if (currentModel != null) { this.setModelIntoUi(currentModel).then(afterAppliedFunc); } else { this.resetUiToDefaults().then(afterAppliedFunc); } } onBtClear() { this.resetUiToDefaults().then(() => this.onUiChanged()); } onBtReset() { this.onBtClear(); this.onBtApply(); } /** * Applies changes made in the UI to the filter, and returns true if the model has changed. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars applyModel(source = "api") { const newModel = this.getModelFromUi(); if (!this.isModelValid(newModel)) { return false; } const previousModel = this.appliedModel; this.appliedModel = newModel; return !this.areModelsEqual(previousModel, newModel); } // eslint-disable-next-line @typescript-eslint/no-unused-vars isModelValid(model) { return true; } onFormSubmit(e) { e.preventDefault(); } onBtApply(afterFloatingFilter = false, afterDataChange = false, e) { if (e) { e.preventDefault(); } if (this.applyModel(afterDataChange ? "rowDataUpdated" : "ui")) { const source = "columnFilter"; this.params.filterChangedCallback({ afterFloatingFilter, afterDataChange, source }); } const { closeOnApply } = this.params; if (closeOnApply && this.applyActive && !afterFloatingFilter && !afterDataChange) { this.close(e); } } onNewRowsLoaded() { } close(e) { if (!this.hidePopup) { return; } const keyboardEvent = e; const key = keyboardEvent && keyboardEvent.key; let params; if (key === "Enter" || key === "Space") { params = { keyboardEvent }; } this.hidePopup(params); this.hidePopup = null; } /** * By default, if the change came from a floating filter it will be applied immediately, otherwise if there is no * apply button it will be applied after a debounce, otherwise it will not be applied at all. This behaviour can * be adjusted by using the apply parameter. */ onUiChanged(fromFloatingFilter = false, apply) { this.updateUiVisibility(); this.params.filterModifiedCallback(); if (this.applyActive && !this.isReadOnly()) { const isValid = this.isModelValid(this.getModelFromUi()); const applyFilterButton = this.queryForHtmlElement(`[data-ref="applyFilterButton"]`); if (applyFilterButton) { _setDisabled(applyFilterButton, !isValid); } } if (fromFloatingFilter && !apply || apply === "immediately") { this.onBtApply(fromFloatingFilter); } else if (!this.applyActive && !apply || apply === "debounce") { this.onBtApplyDebounce(); } } afterGuiAttached(params) { if (params) { this.hidePopup = params.hidePopup; } this.refreshFilterResizer(params?.container); } refreshFilterResizer(containerType) { const { positionableFeature, gos } = this; if (!positionableFeature || containerType === "toolPanel") { return; } const isResizable = containerType === "floatingFilter" || containerType === "columnFilter"; if (isResizable) { positionableFeature.restoreLastSize(); positionableFeature.setResizable( gos.get("enableRtl") ? { bottom: true, bottomLeft: true, left: true } : { bottom: true, bottomRight: true, right: true } ); } else { positionableFeature.removeSizeFromEl(); positionableFeature.setResizable(false); } positionableFeature.constrainSizeToAvailableHeight(true); } afterGuiDetached() { this.checkApplyDebounce(); this.positionableFeature?.constrainSizeToAvailableHeight(false); } refresh(newParams) { const oldParams = this.params; this.params = newParams; this.resetButtonsPanel(newParams, oldParams); return true; } destroy() { const eGui = this.getGui(); if (eGui) { eGui.removeEventListener("submit", this.onFormSubmit); } this.hidePopup = null; if (this.positionableFeature) { this.positionableFeature = this.destroyBean(this.positionableFeature); } this.appliedModel = null; super.destroy(); } translate(key) { return this.getLocaleTextFunc()(key, FILTER_LOCALE_TEXT[key]); } getCellValue(rowNode) { return this.params.getValue(rowNode); } // override to control positionable feature getPositionableElement() { return this.eFilterBody; } }; // packages/ag-grid-community/src/filter/floating/floatingFilterMapper.ts function _getDefaultFloatingFilterType(frameworkOverrides, def, getFromDefault) { if (def == null) { return null; } let defaultFloatingFilterType = null; const { compName, jsComp, fwComp } = _getFilterCompKeys(frameworkOverrides, def); if (compName) { const floatingFilterTypeMap = { agSetColumnFilter: "agSetColumnFloatingFilter", agMultiColumnFilter: "agMultiColumnFloatingFilter", agGroupColumnFilter: "agGroupColumnFloatingFilter", agNumberColumnFilter: "agNumberColumnFloatingFilter", agDateColumnFilter: "agDateColumnFloatingFilter", agTextColumnFilter: "agTextColumnFloatingFilter" }; defaultFloatingFilterType = floatingFilterTypeMap[compName]; } else { const usingDefaultFilter = jsComp == null && fwComp == null && def.filter === true; if (usingDefaultFilter) { defaultFloatingFilterType = getFromDefault(); } } return defaultFloatingFilterType; } // packages/ag-grid-community/src/styling/layoutFeature.ts var LayoutCssClasses = { AUTO_HEIGHT: "ag-layout-auto-height", NORMAL: "ag-layout-normal", PRINT: "ag-layout-print" }; var LayoutFeature = class extends BeanStub { constructor(view) { super(); this.view = view; } postConstruct() { this.addManagedPropertyListener("domLayout", this.updateLayoutClasses.bind(this)); this.updateLayoutClasses(); } updateLayoutClasses() { const domLayout = this.gos.get("domLayout"); const params = { autoHeight: domLayout === "autoHeight", normal: domLayout === "normal", print: domLayout === "print" }; const cssClass = params.autoHeight ? LayoutCssClasses.AUTO_HEIGHT : params.print ? LayoutCssClasses.PRINT : LayoutCssClasses.NORMAL; this.view.updateLayoutClasses(cssClass, params); } }; // packages/ag-grid-community/src/gridBodyComp/gridBodyScrollFeature.ts var VIEWPORT = "Viewport"; var FAKE_V_SCROLLBAR = "fakeVScrollComp"; var HORIZONTAL_SOURCES = [ "fakeHScrollComp", "centerHeader", "topCenter", "bottomCenter", "stickyTopCenter", "stickyBottomCenter" ]; var SCROLL_DEBOUNCE_TIMEOUT = 100; var SCROLL_END_TIMEOUT = 150; var GridBodyScrollFeature = class extends BeanStub { constructor(eBodyViewport) { super(); this.lastScrollSource = [null, null]; this.scrollLeft = -1; this.nextScrollTop = -1; this.scrollTop = -1; // Used to provide approximate values of scrollTop and offsetHeight // without forcing the browser to recalculate styles. this.lastOffsetHeight = -1; this.lastScrollTop = -1; this.scrollTimer = 0; this.needsRefreshedScrollPosition = true; this.eBodyViewport = eBodyViewport; this.resetLastHScrollDebounced = _debounce( this, () => this.lastScrollSource[1 /* Horizontal */] = null, SCROLL_END_TIMEOUT ); this.resetLastVScrollDebounced = _debounce( this, () => this.lastScrollSource[0 /* Vertical */] = null, SCROLL_END_TIMEOUT ); } wireBeans(beans) { this.ctrlsSvc = beans.ctrlsSvc; this.animationFrameSvc = beans.animationFrameSvc; this.visibleCols = beans.visibleCols; } destroy() { super.destroy(); window.clearTimeout(this.scrollTimer); } postConstruct() { this.enableRtl = this.gos.get("enableRtl"); const requireUpdatedScrollPosition = this.requireUpdatedScrollPosition.bind(this); this.addManagedEventListeners({ displayedColumnsWidthChanged: this.onDisplayedColumnsWidthChanged.bind(this), gridSizeChanged: requireUpdatedScrollPosition }); this.addManagedElementListeners(this.eBodyViewport, { scroll: requireUpdatedScrollPosition }); this.ctrlsSvc.whenReady(this, (p) => { this.centerRowsCtrl = p.center; this.onDisplayedColumnsWidthChanged(); this.addScrollListener(); }); } requireUpdatedScrollPosition() { this.needsRefreshedScrollPosition = true; } addScrollListener() { this.addHorizontalScrollListeners(); this.addVerticalScrollListeners(); } addHorizontalScrollListeners() { this.addManagedElementListeners(this.centerRowsCtrl.eViewport, { scroll: this.onHScroll.bind(this, VIEWPORT) }); for (const source of HORIZONTAL_SOURCES) { const scrollPartner = this.ctrlsSvc.get(source); this.registerScrollPartner(scrollPartner, this.onHScroll.bind(this, source)); } } addVerticalScrollListeners() { const fakeVScrollComp = this.ctrlsSvc.get("fakeVScrollComp"); const isDebounce = this.gos.get("debounceVerticalScrollbar"); const onVScroll = isDebounce ? _debounce(this, this.onVScroll.bind(this, VIEWPORT), SCROLL_DEBOUNCE_TIMEOUT) : this.onVScroll.bind(this, VIEWPORT); const onFakeVScroll = isDebounce ? _debounce(this, this.onVScroll.bind(this, FAKE_V_SCROLLBAR), SCROLL_DEBOUNCE_TIMEOUT) : this.onVScroll.bind(this, FAKE_V_SCROLLBAR); this.addManagedElementListeners(this.eBodyViewport, { scroll: onVScroll }); this.registerScrollPartner(fakeVScrollComp, onFakeVScroll); } registerScrollPartner(comp, callback) { comp.onScrollCallback(callback); } onDisplayedColumnsWidthChanged() { if (this.enableRtl) { this.horizontallyScrollHeaderCenterAndFloatingCenter(); } } horizontallyScrollHeaderCenterAndFloatingCenter(scrollLeft) { const notYetInitialised = this.centerRowsCtrl == null; if (notYetInitialised) { return; } if (scrollLeft === void 0) { scrollLeft = this.centerRowsCtrl.getCenterViewportScrollLeft(); } this.setScrollLeftForAllContainersExceptCurrent(Math.abs(scrollLeft)); } setScrollLeftForAllContainersExceptCurrent(scrollLeft) { for (const container of [...HORIZONTAL_SOURCES, VIEWPORT]) { if (this.lastScrollSource[1 /* Horizontal */] === container) { continue; } const viewport = this.getViewportForSource(container); _setScrollLeft(viewport, scrollLeft, this.enableRtl); } } getViewportForSource(source) { if (source === VIEWPORT) { return this.centerRowsCtrl.eViewport; } return this.ctrlsSvc.get(source).eViewport; } isControllingScroll(source, direction) { if (this.lastScrollSource[direction] == null) { if (direction === 0 /* Vertical */) { this.lastScrollSource[0] = source; } else { this.lastScrollSource[1] = source; } return true; } return this.lastScrollSource[direction] === source; } onHScroll(source) { if (!this.isControllingScroll(source, 1 /* Horizontal */)) { return; } const centerContainerViewport = this.centerRowsCtrl.eViewport; const { scrollLeft } = centerContainerViewport; if (this.shouldBlockScrollUpdate(1 /* Horizontal */, scrollLeft, true)) { return; } const newScrollLeft = _getScrollLeft(this.getViewportForSource(source), this.enableRtl); this.doHorizontalScroll(newScrollLeft); this.resetLastHScrollDebounced(); } onVScroll(source) { if (!this.isControllingScroll(source, 0 /* Vertical */)) { return; } let scrollTop; if (source === VIEWPORT) { scrollTop = this.eBodyViewport.scrollTop; } else { scrollTop = this.ctrlsSvc.get("fakeVScrollComp").getScrollPosition(); } if (this.shouldBlockScrollUpdate(0 /* Vertical */, scrollTop, true)) { return; } const { animationFrameSvc } = this; animationFrameSvc?.setScrollTop(scrollTop); this.nextScrollTop = scrollTop; if (source === VIEWPORT) { this.ctrlsSvc.get("fakeVScrollComp").setScrollPosition(scrollTop); } else { this.eBodyViewport.scrollTop = scrollTop; } if (!animationFrameSvc || this.gos.get("suppressAnimationFrame")) { this.scrollGridIfNeeded(true); } else { animationFrameSvc.schedule(); } this.resetLastVScrollDebounced(); } doHorizontalScroll(scrollLeft) { const fakeScrollLeft = this.ctrlsSvc.get("fakeHScrollComp").getScrollPosition(); if (this.scrollLeft === scrollLeft && scrollLeft === fakeScrollLeft) { return; } this.scrollLeft = scrollLeft; this.fireScrollEvent(1 /* Horizontal */); this.horizontallyScrollHeaderCenterAndFloatingCenter(scrollLeft); this.centerRowsCtrl.onHorizontalViewportChanged(true); } fireScrollEvent(direction) { const bodyScrollEvent = { type: "bodyScroll", direction: direction === 1 /* Horizontal */ ? "horizontal" : "vertical", left: this.scrollLeft, top: this.scrollTop }; this.eventSvc.dispatchEvent(bodyScrollEvent); window.clearTimeout(this.scrollTimer); this.scrollTimer = window.setTimeout(() => { this.scrollTimer = 0; this.eventSvc.dispatchEvent({ ...bodyScrollEvent, type: "bodyScrollEnd" }); }, SCROLL_END_TIMEOUT); } shouldBlockScrollUpdate(direction, scrollTo, touchOnly = false) { if (touchOnly && !_isIOSUserAgent()) { return false; } if (direction === 0 /* Vertical */) { return this.shouldBlockVerticalScroll(scrollTo); } return this.shouldBlockHorizontalScroll(scrollTo); } shouldBlockVerticalScroll(scrollTo) { const clientHeight = _getInnerHeight(this.eBodyViewport); const { scrollHeight } = this.eBodyViewport; if (scrollTo < 0 || scrollTo + clientHeight > scrollHeight) { return true; } return false; } shouldBlockHorizontalScroll(scrollTo) { const clientWidth = this.centerRowsCtrl.getCenterWidth(); const { scrollWidth } = this.centerRowsCtrl.eViewport; if (this.enableRtl && _isRtlNegativeScroll()) { if (scrollTo > 0) { return true; } } else if (scrollTo < 0) { return true; } if (Math.abs(scrollTo) + clientWidth > scrollWidth) { return true; } return false; } redrawRowsAfterScroll() { this.fireScrollEvent(0 /* Vertical */); } // this is to cater for AG-3274, where grid is removed from the dom and then inserted back in again. // (which happens with some implementations of tabbing). this can result in horizontal scroll getting // reset back to the left, however no scroll event is fired. so we need to get header to also scroll // back to the left to be kept in sync. // adding and removing the grid from the DOM both resets the scroll position and // triggers a resize event, so notify listeners if the scroll position has changed checkScrollLeft() { if (this.scrollLeft !== this.centerRowsCtrl.getCenterViewportScrollLeft()) { this.onHScroll(VIEWPORT); } } scrollGridIfNeeded(suppressedAnimationFrame = false) { const frameNeeded = this.scrollTop != this.nextScrollTop; if (frameNeeded) { this.scrollTop = this.nextScrollTop; if (suppressedAnimationFrame) { this.requireUpdatedScrollPosition(); } this.redrawRowsAfterScroll(); } return frameNeeded; } // called by scrollHorizontally method and alignedGridsService setHorizontalScrollPosition(hScrollPosition, fromAlignedGridsService = false) { const minScrollLeft = 0; const maxScrollLeft = this.centerRowsCtrl.eViewport.scrollWidth - this.centerRowsCtrl.getCenterWidth(); if (!fromAlignedGridsService && this.shouldBlockScrollUpdate(1 /* Horizontal */, hScrollPosition)) { if (this.enableRtl && _isRtlNegativeScroll()) { hScrollPosition = hScrollPosition > 0 ? 0 : maxScrollLeft; } else { hScrollPosition = Math.min(Math.max(hScrollPosition, minScrollLeft), maxScrollLeft); } } _setScrollLeft(this.centerRowsCtrl.eViewport, Math.abs(hScrollPosition), this.enableRtl); this.doHorizontalScroll(hScrollPosition); } setVerticalScrollPosition(vScrollPosition) { this.requireUpdatedScrollPosition(); this.eBodyViewport.scrollTop = vScrollPosition; } getVScrollPosition() { if (!this.needsRefreshedScrollPosition) { const { lastOffsetHeight, lastScrollTop } = this; return { top: lastScrollTop, bottom: lastScrollTop + lastOffsetHeight }; } this.needsRefreshedScrollPosition = false; const { scrollTop, offsetHeight } = this.eBodyViewport; this.lastScrollTop = scrollTop; this.lastOffsetHeight = offsetHeight; return { top: scrollTop, bottom: scrollTop + offsetHeight }; } /** Get an approximate scroll position that returns the last real value read. * This is useful for avoiding repeated DOM reads that force the browser to recalculate styles. * This can have big performance improvements but may not be 100% accurate so only use if this is acceptable. */ getApproximateVScollPosition() { if (this.lastScrollTop >= 0 && this.lastOffsetHeight >= 0) { return { top: this.scrollTop, bottom: this.scrollTop + this.lastOffsetHeight }; } return this.getVScrollPosition(); } getHScrollPosition() { return this.centerRowsCtrl.getHScrollPosition(); } isHorizontalScrollShowing() { return this.centerRowsCtrl.isHorizontalScrollShowing(); } // called by the headerRootComp and moveColumnController scrollHorizontally(pixels) { const oldScrollPosition = this.centerRowsCtrl.eViewport.scrollLeft; this.setHorizontalScrollPosition(oldScrollPosition + pixels); return this.centerRowsCtrl.eViewport.scrollLeft - oldScrollPosition; } // gets called by rowRenderer when new data loaded, as it will want to scroll to the top scrollToTop() { this.eBodyViewport.scrollTop = 0; } // Valid values for position are bottom, middle and top ensureNodeVisible(comparator, position = null) { const { rowModel } = this.beans; const rowCount = rowModel.getRowCount(); let indexToSelect = -1; for (let i = 0; i < rowCount; i++) { const node = rowModel.getRow(i); if (typeof comparator === "function") { const predicate = comparator; if (node && predicate(node)) { indexToSelect = i; break; } } else { if (comparator === node || comparator === node.data) { indexToSelect = i; break; } } } if (indexToSelect >= 0) { this.ensureIndexVisible(indexToSelect, position); } } // Valid values for position are bottom, middle and top // position should be {'top','middle','bottom', or undefined/null}. // if undefined/null, then the grid will to the minimal amount of scrolling, // eg if grid needs to scroll up, it scrolls until row is on top, // if grid needs to scroll down, it scrolls until row is on bottom, // if row is already in view, grid does not scroll ensureIndexVisible(index, position) { if (_isDomLayout(this.gos, "print")) { return; } const { rowModel } = this.beans; const rowCount = rowModel.getRowCount(); if (typeof index !== "number" || index < 0 || index >= rowCount) { _warn(88, { index }); return; } const isPaging = this.gos.get("pagination"); const paginationPanelEnabled = isPaging && !this.gos.get("suppressPaginationPanel"); const { frameworkOverrides, pagination, pageBounds, rowContainerHeight: heightScaler, rowRenderer } = this.beans; frameworkOverrides.wrapIncoming(() => { if (!paginationPanelEnabled) { pagination?.goToPageWithIndex(index); } const gridBodyCtrl = this.ctrlsSvc.getGridBodyCtrl(); const stickyTopHeight = gridBodyCtrl.stickyTopHeight; const stickyBottomHeight = gridBodyCtrl.stickyBottomHeight; const rowNode = rowModel.getRow(index); let rowGotShiftedDuringOperation; do { const startingRowTop = rowNode.rowTop; const startingRowHeight = rowNode.rowHeight; const paginationOffset = pageBounds.getPixelOffset(); const rowTopPixel = rowNode.rowTop - paginationOffset; const rowBottomPixel = rowTopPixel + rowNode.rowHeight; const scrollPosition = this.getVScrollPosition(); const heightOffset = heightScaler.divStretchOffset; const vScrollTop = scrollPosition.top + heightOffset; const vScrollBottom = scrollPosition.bottom + heightOffset; const viewportHeight = vScrollBottom - vScrollTop; const pxTop = heightScaler.getScrollPositionForPixel(rowTopPixel); const pxBottom = heightScaler.getScrollPositionForPixel(rowBottomPixel - viewportHeight); const pxMiddle = Math.min((pxTop + pxBottom) / 2, rowTopPixel); const rowAboveViewport = vScrollTop + stickyTopHeight > rowTopPixel; const rowBelowViewport = vScrollBottom - stickyBottomHeight < rowBottomPixel; let newScrollPosition = null; if (position === "top") { newScrollPosition = pxTop; } else if (position === "bottom") { newScrollPosition = pxBottom; } else if (position === "middle") { newScrollPosition = pxMiddle; } else if (rowAboveViewport) { newScrollPosition = pxTop - stickyTopHeight; } else if (rowBelowViewport) { newScrollPosition = pxBottom + stickyBottomHeight; } if (newScrollPosition !== null) { this.setVerticalScrollPosition(newScrollPosition); rowRenderer.redraw({ afterScroll: true }); } rowGotShiftedDuringOperation = startingRowTop !== rowNode.rowTop || startingRowHeight !== rowNode.rowHeight; } while (rowGotShiftedDuringOperation); this.animationFrameSvc?.flushAllFrames(); }); } ensureColumnVisible(key, position = "auto") { const { colModel, frameworkOverrides } = this.beans; const column = colModel.getCol(key); if (!column) { return; } if (column.isPinned()) { return; } if (!this.visibleCols.isColDisplayed(column)) { return; } const newHorizontalScroll = this.getPositionedHorizontalScroll(column, position); frameworkOverrides.wrapIncoming(() => { if (newHorizontalScroll !== null) { this.centerRowsCtrl.setCenterViewportScrollLeft(newHorizontalScroll); } this.centerRowsCtrl.onHorizontalViewportChanged(); this.animationFrameSvc?.flushAllFrames(); }); } getPositionedHorizontalScroll(column, position) { const { columnBeforeStart, columnAfterEnd } = this.isColumnOutsideViewport(column); const viewportTooSmallForColumn = this.centerRowsCtrl.getCenterWidth() < column.getActualWidth(); const viewportWidth = this.centerRowsCtrl.getCenterWidth(); const isRtl = this.enableRtl; let alignColToStart = (isRtl ? columnBeforeStart : columnAfterEnd) || viewportTooSmallForColumn; let alignColToEnd = isRtl ? columnAfterEnd : columnBeforeStart; if (position !== "auto") { alignColToStart = position === "start"; alignColToEnd = position === "end"; } const isMiddle = position === "middle"; if (alignColToStart || alignColToEnd || isMiddle) { const { colLeft, colMiddle, colRight } = this.getColumnBounds(column); if (isMiddle) { return colMiddle - viewportWidth / 2; } if (alignColToStart) { return isRtl ? colRight : colLeft; } return isRtl ? colLeft - viewportWidth : colRight - viewportWidth; } return null; } isColumnOutsideViewport(column) { const { start: viewportStart, end: viewportEnd } = this.getViewportBounds(); const { colLeft, colRight } = this.getColumnBounds(column); const isRtl = this.enableRtl; const columnBeforeStart = isRtl ? viewportStart > colRight : viewportEnd < colRight; const columnAfterEnd = isRtl ? viewportEnd < colLeft : viewportStart > colLeft; return { columnBeforeStart, columnAfterEnd }; } getColumnBounds(column) { const isRtl = this.enableRtl; const bodyWidth = this.visibleCols.bodyWidth; const colWidth = column.getActualWidth(); const colLeft = column.getLeft(); const multiplier = isRtl ? -1 : 1; const colLeftPixel = isRtl ? bodyWidth - colLeft : colLeft; const colRightPixel = colLeftPixel + colWidth * multiplier; const colMidPixel = colLeftPixel + colWidth / 2 * multiplier; return { colLeft: colLeftPixel, colMiddle: colMidPixel, colRight: colRightPixel }; } getViewportBounds() { const viewportWidth = this.centerRowsCtrl.getCenterWidth(); const scrollPosition = this.centerRowsCtrl.getCenterViewportScrollLeft(); const viewportStartPixel = scrollPosition; const viewportEndPixel = viewportWidth + scrollPosition; return { start: viewportStartPixel, end: viewportEndPixel, width: viewportWidth }; } }; // packages/ag-grid-community/src/gridBodyComp/centerWidthFeature.ts var CenterWidthFeature = class extends BeanStub { constructor(callback, addSpacer = false) { super(); this.callback = callback; this.addSpacer = addSpacer; } postConstruct() { const listener = this.setWidth.bind(this); this.addManagedPropertyListener("domLayout", listener); this.addManagedEventListeners({ columnContainerWidthChanged: listener, displayedColumnsChanged: listener, leftPinnedWidthChanged: listener }); if (this.addSpacer) { this.addManagedEventListeners({ rightPinnedWidthChanged: listener, scrollVisibilityChanged: listener, scrollbarWidthChanged: listener }); } this.setWidth(); } setWidth() { const printLayout = _isDomLayout(this.gos, "print"); const { visibleCols, scrollVisibleSvc } = this.beans; const centerWidth = visibleCols.bodyWidth; const leftWidth = visibleCols.getColsLeftWidth(); const rightWidth = visibleCols.getDisplayedColumnsRightWidth(); let totalWidth; if (printLayout) { totalWidth = centerWidth + leftWidth + rightWidth; } else { totalWidth = centerWidth; if (this.addSpacer) { const relevantWidth = this.gos.get("enableRtl") ? leftWidth : rightWidth; if (relevantWidth === 0 && scrollVisibleSvc.verticalScrollShowing) { totalWidth += scrollVisibleSvc.getScrollbarWidth(); } } } this.callback(totalWidth); } }; // packages/ag-grid-community/src/gridBodyComp/viewportSizeFeature.ts var ViewportSizeFeature = class extends BeanStub { constructor(centerContainerCtrl) { super(); this.centerContainerCtrl = centerContainerCtrl; } wireBeans(beans) { this.scrollVisibleSvc = beans.scrollVisibleSvc; } postConstruct() { this.beans.ctrlsSvc.whenReady(this, (p) => { this.gridBodyCtrl = p.gridBodyCtrl; this.listenForResize(); }); this.addManagedEventListeners({ scrollbarWidthChanged: this.onScrollbarWidthChanged.bind(this) }); this.addManagedPropertyListeners(["alwaysShowHorizontalScroll", "alwaysShowVerticalScroll"], () => { this.checkViewportAndScrolls(); }); } listenForResize() { const { beans, centerContainerCtrl, gridBodyCtrl } = this; const listener = () => { _requestAnimationFrame(beans, () => { this.onCenterViewportResized(); }); }; centerContainerCtrl.registerViewportResizeListener(listener); gridBodyCtrl.registerBodyViewportResizeListener(listener); } onScrollbarWidthChanged() { this.checkViewportAndScrolls(); } onCenterViewportResized() { this.scrollVisibleSvc.updateScrollGap(); if (this.centerContainerCtrl.isViewportInTheDOMTree()) { const { pinnedCols, colFlex } = this.beans; pinnedCols?.keepPinnedColumnsNarrowerThanViewport(); this.checkViewportAndScrolls(); const newWidth = this.centerContainerCtrl.getCenterWidth(); if (newWidth !== this.centerWidth) { this.centerWidth = newWidth; colFlex?.refreshFlexedColumns({ viewportWidth: this.centerWidth, updateBodyWidths: true, fireResizedEvent: true }); } } else { this.bodyHeight = 0; } } // gets called every time the viewport size changes. we use this to check visibility of scrollbars // in the grid panel, and also to check size and position of viewport for row and column virtualisation. checkViewportAndScrolls() { this.updateScrollVisibleService(); this.checkBodyHeight(); this.onHorizontalViewportChanged(); this.gridBodyCtrl.scrollFeature.checkScrollLeft(); } getBodyHeight() { return this.bodyHeight; } checkBodyHeight() { const eBodyViewport = this.gridBodyCtrl.eBodyViewport; const bodyHeight = _getInnerHeight(eBodyViewport); if (this.bodyHeight !== bodyHeight) { this.bodyHeight = bodyHeight; this.eventSvc.dispatchEvent({ type: "bodyHeightChanged" }); } } updateScrollVisibleService() { this.updateScrollVisibleServiceImpl(); setTimeout(this.updateScrollVisibleServiceImpl.bind(this), 500); } updateScrollVisibleServiceImpl() { const params = { horizontalScrollShowing: this.centerContainerCtrl.isHorizontalScrollShowing(), verticalScrollShowing: this.gridBodyCtrl.isVerticalScrollShowing() }; this.scrollVisibleSvc.setScrollsVisible(params); } // this gets called whenever a change in the viewport, so we can inform column controller it has to work // out the virtual columns again. gets called from following locations: // + ensureColVisible, scroll, init, layoutChanged, displayedColumnsChanged onHorizontalViewportChanged() { const scrollWidth = this.centerContainerCtrl.getCenterWidth(); const scrollPosition = this.centerContainerCtrl.getViewportScrollLeft(); this.beans.colViewport.setScrollPosition(scrollWidth, scrollPosition); } }; // packages/ag-grid-community/src/styling/stylingUtils.ts function processClassRules(expressionSvc, previousClassRules, classRules, params, onApplicableClass, onNotApplicableClass) { if (classRules == null && previousClassRules == null) { return; } const classesToApply = {}; const classesToRemove = {}; const forEachSingleClass = (className, callback) => { className.split(" ").forEach((singleClass) => { if (singleClass.trim() == "") return; callback(singleClass); }); }; if (classRules) { const classNames = Object.keys(classRules); for (let i = 0; i < classNames.length; i++) { const className = classNames[i]; const rule = classRules[className]; let resultOfRule; if (typeof rule === "string") { resultOfRule = expressionSvc ? expressionSvc.evaluate(rule, params) : true; } else if (typeof rule === "function") { resultOfRule = rule(params); } forEachSingleClass(className, (singleClass) => { resultOfRule ? classesToApply[singleClass] = true : classesToRemove[singleClass] = true; }); } } if (previousClassRules && onNotApplicableClass) { Object.keys(previousClassRules).forEach( (className) => forEachSingleClass(className, (singleClass) => { if (!classesToApply[singleClass]) { classesToRemove[singleClass] = true; } }) ); } if (onNotApplicableClass) { Object.keys(classesToRemove).forEach(onNotApplicableClass); } Object.keys(classesToApply).forEach(onApplicableClass); } // packages/ag-grid-community/src/styling/rowStyleService.ts function calculateRowLevel(rowNode) { if (rowNode.group) { return rowNode.level; } const parent = rowNode.parent; return parent ? parent.level + 1 : 0; } var RowStyleService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "rowStyleSvc"; } processClassesFromGridOptions(classes, rowNode) { const gos = this.gos; const process = (rowCls) => { if (typeof rowCls === "string") { classes.push(rowCls); } else if (Array.isArray(rowCls)) { rowCls.forEach((e) => classes.push(e)); } }; const rowClass = gos.get("rowClass"); if (rowClass) { process(rowClass); } const rowClassFunc = gos.getCallback("getRowClass"); if (rowClassFunc) { const params = { data: rowNode.data, node: rowNode, rowIndex: rowNode.rowIndex }; const rowClassFuncResult = rowClassFunc(params); process(rowClassFuncResult); } } preProcessRowClassRules(classes, rowNode) { this.processRowClassRules( rowNode, (className) => { classes.push(className); }, () => { } ); } processRowClassRules(rowNode, onApplicableClass, onNotApplicableClass) { const { gos, expressionSvc } = this.beans; const rowClassParams = _addGridCommonParams(gos, { data: rowNode.data, node: rowNode, rowIndex: rowNode.rowIndex }); processClassRules( expressionSvc, void 0, gos.get("rowClassRules"), rowClassParams, onApplicableClass, onNotApplicableClass ); } processStylesFromGridOptions(rowNode) { const gos = this.gos; const rowStyle = gos.get("rowStyle"); const rowStyleFunc = gos.getCallback("getRowStyle"); let rowStyleFuncResult; if (rowStyleFunc) { const params = { data: rowNode.data, node: rowNode, rowIndex: rowNode.rowIndex }; rowStyleFuncResult = rowStyleFunc(params); } if (rowStyleFuncResult || rowStyle) { return Object.assign({}, rowStyle, rowStyleFuncResult); } return void 0; } }; // packages/ag-grid-community/src/rendering/row/rowCtrl.ts var instanceIdSequence3 = 0; var DOM_DATA_KEY_ROW_CTRL = "renderedRow"; var RowCtrl = class extends BeanStub { constructor(rowNode, beans, animateIn, useAnimationFrameForCreate, printLayout) { super(); this.rowNode = rowNode; this.useAnimationFrameForCreate = useAnimationFrameForCreate; this.printLayout = printLayout; this.allRowGuis = []; this.active = true; this.centerCellCtrls = { list: [], map: {} }; this.leftCellCtrls = { list: [], map: {} }; this.rightCellCtrls = { list: [], map: {} }; this.slideInAnimation = { left: false, center: false, right: false, fullWidth: false }; this.fadeInAnimation = { left: false, center: false, right: false, fullWidth: false }; this.rowDragComps = []; this.lastMouseDownOnDragger = false; this.emptyStyle = {}; this.updateColumnListsPending = false; this.rowId = null; /** sanitised */ this.businessKey = null; this.beans = beans; this.gos = beans.gos; this.paginationPage = beans.pagination?.getCurrentPage() ?? 0; this.suppressRowTransform = this.gos.get("suppressRowTransform"); this.instanceId = rowNode.id + "-" + instanceIdSequence3++; this.rowId = _escapeString(rowNode.id); this.initRowBusinessKey(); this.rowFocused = beans.focusSvc.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned); this.rowLevel = calculateRowLevel(this.rowNode); this.setRowType(); this.setAnimateFlags(animateIn); this.rowStyles = this.processStylesFromGridOptions(); this.addListeners(); } initRowBusinessKey() { this.businessKeyForNodeFunc = this.gos.get("getBusinessKeyForNode"); this.updateRowBusinessKey(); } updateRowBusinessKey() { if (typeof this.businessKeyForNodeFunc !== "function") { return; } const businessKey = this.businessKeyForNodeFunc(this.rowNode); this.businessKey = _escapeString(businessKey); } updateGui(containerType, gui) { if (containerType === "left") { this.leftGui = gui; } else if (containerType === "right") { this.rightGui = gui; } else if (containerType === "fullWidth") { this.fullWidthGui = gui; } else { this.centerGui = gui; } } setComp(rowComp, element, containerType, compBean) { compBean = setupCompBean(this, this.beans.context, compBean); const gui = { rowComp, element, containerType, compBean }; this.allRowGuis.push(gui); this.updateGui(containerType, gui); this.initialiseRowComp(gui); const isSsrmLoadingRow = this.rowType === "FullWidthLoading" || this.rowNode.stub; if (!isSsrmLoadingRow && !this.rowNode.rowPinned) { this.beans.rowRenderer.dispatchFirstDataRenderedEvent(); } } unsetComp(containerType) { this.allRowGuis = this.allRowGuis.filter((rowGui) => rowGui.containerType !== containerType); this.updateGui(containerType, void 0); } isCacheable() { return this.rowType === "FullWidthDetail" && this.gos.get("keepDetailRows"); } setCached(cached) { const displayValue = cached ? "none" : ""; this.allRowGuis.forEach((rg) => rg.element.style.display = displayValue); } initialiseRowComp(gui) { const gos = this.gos; this.onSuppressCellFocusChanged(this.beans.gos.get("suppressCellFocus")); this.listenOnDomOrder(gui); this.onRowHeightChanged(gui); this.updateRowIndexes(gui); this.setFocusedClasses(gui); this.setStylesFromGridOptions(false, gui); if (_isRowSelection(gos) && this.rowNode.selectable) { this.onRowSelected(gui); } this.updateColumnLists(!this.useAnimationFrameForCreate); const comp = gui.rowComp; const initialRowClasses = this.getInitialRowClasses(gui.containerType); initialRowClasses.forEach((name) => comp.addOrRemoveCssClass(name, true)); this.executeSlideAndFadeAnimations(gui); if (this.rowNode.group) { _setAriaExpanded(gui.element, this.rowNode.expanded == true); } this.setRowCompRowId(comp); this.setRowCompRowBusinessKey(comp); _setDomData(gos, gui.element, DOM_DATA_KEY_ROW_CTRL, this); gui.compBean.addDestroyFunc(() => _setDomData(gos, gui.element, DOM_DATA_KEY_ROW_CTRL, null)); if (this.useAnimationFrameForCreate) { this.beans.animationFrameSvc.createTask( this.addHoverFunctionality.bind(this, gui), this.rowNode.rowIndex, "createTasksP2" ); } else { this.addHoverFunctionality(gui); } if (this.isFullWidth()) { this.setupFullWidth(gui); } if (gos.get("rowDragEntireRow")) { this.addRowDraggerToRow(gui); } if (this.useAnimationFrameForCreate) { this.beans.animationFrameSvc.addDestroyTask(() => { if (!this.isAlive()) { return; } gui.rowComp.addOrRemoveCssClass("ag-after-created", true); }); } this.executeProcessRowPostCreateFunc(); } setRowCompRowBusinessKey(comp) { if (this.businessKey == null) { return; } comp.setRowBusinessKey(this.businessKey); } setRowCompRowId(comp) { const rowId = _escapeString(this.rowNode.id); this.rowId = rowId; if (rowId == null) { return; } comp.setRowId(rowId); } executeSlideAndFadeAnimations(gui) { const { containerType } = gui; const shouldSlide = this.slideInAnimation[containerType]; if (shouldSlide) { _executeNextVMTurn(() => { this.onTopChanged(); }); this.slideInAnimation[containerType] = false; } const shouldFade = this.fadeInAnimation[containerType]; if (shouldFade) { _executeNextVMTurn(() => { gui.rowComp.addOrRemoveCssClass("ag-opacity-zero", false); }); this.fadeInAnimation[containerType] = false; } } addRowDraggerToRow(gui) { const rowDragComp = this.beans.rowDragSvc?.createRowDragCompForRow(this.rowNode, gui.element); if (!rowDragComp) { return; } const rowDragBean = this.createBean(rowDragComp, this.beans.context); this.rowDragComps.push(rowDragBean); gui.compBean.addDestroyFunc(() => { this.rowDragComps = this.rowDragComps.filter((r) => r !== rowDragBean); this.destroyBean(rowDragBean, this.beans.context); }); } setupFullWidth(gui) { const pinned = this.getPinnedForContainer(gui.containerType); const compDetails = this.createFullWidthCompDetails(gui.element, pinned); gui.rowComp.showFullWidth(compDetails); } getFullWidthCellRenderers() { if (this.gos.get("embedFullWidthRows")) { return this.allRowGuis.map((gui) => gui?.rowComp?.getFullWidthCellRenderer()); } return [this.fullWidthGui?.rowComp?.getFullWidthCellRenderer()]; } executeProcessRowPostCreateFunc() { const func = this.gos.getCallback("processRowPostCreate"); if (!func || !this.areAllContainersReady()) { return; } const params = { // areAllContainersReady asserts that centerGui is not null eRow: this.centerGui.element, ePinnedLeftRow: this.leftGui ? this.leftGui.element : void 0, ePinnedRightRow: this.rightGui ? this.rightGui.element : void 0, node: this.rowNode, rowIndex: this.rowNode.rowIndex, addRenderedRowListener: this.addEventListener.bind(this) }; func(params); } areAllContainersReady() { const { leftGui, centerGui, rightGui, beans: { visibleCols } } = this; const isLeftReady = !!leftGui || !visibleCols.isPinningLeft(); const isCenterReady = !!centerGui; const isRightReady = !!rightGui || !visibleCols.isPinningRight(); return isLeftReady && isCenterReady && isRightReady; } isNodeFullWidthCell() { if (this.rowNode.detail) { return true; } const isFullWidthCellFunc = this.beans.gos.getCallback("isFullWidthRow"); return isFullWidthCellFunc ? isFullWidthCellFunc({ rowNode: this.rowNode }) : false; } setRowType() { const isStub = this.rowNode.stub && !this.gos.get("suppressServerSideFullWidthLoadingRow") && !this.gos.get("groupHideOpenParents"); const isFullWidthCell = this.isNodeFullWidthCell(); const isDetailCell = this.gos.get("masterDetail") && this.rowNode.detail; const pivotMode = this.beans.colModel.isPivotMode(); const isGroupRow = !!this.rowNode.group && !this.rowNode.footer; const isFullWidthGroup = isGroupRow && _isGroupUseEntireRow(this.gos, pivotMode); if (isStub) { this.rowType = "FullWidthLoading"; } else if (isDetailCell) { this.rowType = "FullWidthDetail"; } else if (isFullWidthCell) { this.rowType = "FullWidth"; } else if (isFullWidthGroup) { this.rowType = "FullWidthGroup"; } else { this.rowType = "Normal"; } } updateColumnLists(suppressAnimationFrame = false, useFlushSync = false) { if (this.isFullWidth()) { return; } const { animationFrameSvc } = this.beans; const noAnimation = !animationFrameSvc || suppressAnimationFrame || this.gos.get("suppressAnimationFrame") || this.printLayout; if (noAnimation) { this.updateColumnListsImpl(useFlushSync); return; } if (this.updateColumnListsPending) { return; } animationFrameSvc.createTask( () => { if (!this.active) { return; } this.updateColumnListsImpl(true); }, this.rowNode.rowIndex, "createTasksP1" ); this.updateColumnListsPending = true; } /** * Overridden by SpannedRowCtrl */ getNewCellCtrl(col) { const isCellSpan = this.beans.rowSpanSvc?.isCellSpanning(col, this.rowNode); if (isCellSpan) { return void 0; } return new CellCtrl(col, this.rowNode, this.beans, this); } /** * Overridden by SpannedRowCtrl, if span context changes cell needs rebuilt */ shouldRecreateCellCtrl(cell) { return !!this.beans.rowSpanSvc?.isCellSpanning(cell.column, this.rowNode); } createCellCtrls(prev, cols, pinned = null) { const res = { list: [], map: {} }; const addCell = (colInstanceId, cellCtrl, index) => { if (index != null) { res.list.splice(index, 0, cellCtrl); } else { res.list.push(cellCtrl); } res.map[colInstanceId] = cellCtrl; }; const colsFromPrev = []; for (const col of cols) { const colInstanceId = col.getInstanceId(); let cellCtrl = prev.map[colInstanceId]; if (cellCtrl && this.shouldRecreateCellCtrl(cellCtrl)) { cellCtrl.destroy(); cellCtrl = void 0; } if (!cellCtrl) { cellCtrl = this.getNewCellCtrl(col); } if (!cellCtrl) { continue; } addCell(colInstanceId, cellCtrl); } for (const prevCellCtrl of prev.list) { const colInstanceId = prevCellCtrl.column.getInstanceId(); const cellInResult = res.map[colInstanceId] != null; if (cellInResult) { continue; } const keepCell = !this.isCellEligibleToBeRemoved(prevCellCtrl, pinned); if (keepCell) { colsFromPrev.push([colInstanceId, prevCellCtrl]); } else { prevCellCtrl.destroy(); } } if (colsFromPrev.length) { for (const [colInstanceId, cellCtrl] of colsFromPrev) { const index = res.list.findIndex((ctrl) => ctrl.column.getLeft() > cellCtrl.column.getLeft()); const normalisedIndex = index === -1 ? void 0 : Math.max(index - 1, 0); addCell(colInstanceId, cellCtrl, normalisedIndex); } } return res; } updateColumnListsImpl(useFlushSync) { this.updateColumnListsPending = false; this.createAllCellCtrls(); this.setCellCtrls(useFlushSync); } setCellCtrls(useFlushSync) { this.allRowGuis.forEach((item) => { const cellControls = this.getCellCtrlsForContainer(item.containerType); item.rowComp.setCellCtrls(cellControls, useFlushSync); }); } getCellCtrlsForContainer(containerType) { switch (containerType) { case "left": return this.leftCellCtrls.list; case "right": return this.rightCellCtrls.list; case "fullWidth": return []; case "center": return this.centerCellCtrls.list; } } createAllCellCtrls() { const colViewport = this.beans.colViewport; const presentedColsService = this.beans.visibleCols; if (this.printLayout) { this.centerCellCtrls = this.createCellCtrls(this.centerCellCtrls, presentedColsService.allCols); this.leftCellCtrls = { list: [], map: {} }; this.rightCellCtrls = { list: [], map: {} }; } else { const centerCols = colViewport.getColsWithinViewport(this.rowNode); this.centerCellCtrls = this.createCellCtrls(this.centerCellCtrls, centerCols); const leftCols = presentedColsService.getLeftColsForRow(this.rowNode); this.leftCellCtrls = this.createCellCtrls(this.leftCellCtrls, leftCols, "left"); const rightCols = presentedColsService.getRightColsForRow(this.rowNode); this.rightCellCtrls = this.createCellCtrls(this.rightCellCtrls, rightCols, "right"); } } isCellEligibleToBeRemoved(cellCtrl, nextContainerPinned) { const REMOVE_CELL = true; const KEEP_CELL = false; const { column } = cellCtrl; if (column.getPinned() != nextContainerPinned) { return REMOVE_CELL; } const { editing, cellPosition } = cellCtrl; const { focusSvc, visibleCols } = this.beans; const focused = focusSvc.isCellFocused(cellPosition); const mightWantToKeepCell = editing || focused; if (mightWantToKeepCell) { const displayedColumns = visibleCols.allCols; const cellStillDisplayed = displayedColumns.indexOf(column) >= 0; return cellStillDisplayed ? KEEP_CELL : REMOVE_CELL; } return REMOVE_CELL; } getDomOrder() { const isEnsureDomOrder = this.gos.get("ensureDomOrder"); return isEnsureDomOrder || _isDomLayout(this.gos, "print"); } listenOnDomOrder(gui) { const listener = () => { gui.rowComp.setDomOrder(this.getDomOrder()); }; gui.compBean.addManagedPropertyListeners(["domLayout", "ensureDomOrder"], listener); } setAnimateFlags(animateIn) { if (this.rowNode.sticky || !animateIn) { return; } const oldRowTopExists = _exists(this.rowNode.oldRowTop); const { visibleCols } = this.beans; const pinningLeft = visibleCols.isPinningLeft(); const pinningRight = visibleCols.isPinningRight(); if (oldRowTopExists) { const { slideInAnimation } = this; if (this.isFullWidth() && !this.gos.get("embedFullWidthRows")) { slideInAnimation.fullWidth = true; return; } slideInAnimation.center = true; slideInAnimation.left = pinningLeft; slideInAnimation.right = pinningRight; } else { const { fadeInAnimation } = this; if (this.isFullWidth() && !this.gos.get("embedFullWidthRows")) { fadeInAnimation.fullWidth = true; return; } fadeInAnimation.center = true; fadeInAnimation.left = pinningLeft; fadeInAnimation.right = pinningRight; } } isFullWidth() { return this.rowType !== "Normal"; } refreshFullWidth() { const tryRefresh = (gui, pinned) => { if (!gui) { return true; } return gui.rowComp.refreshFullWidth(() => { const compDetails = this.createFullWidthCompDetails(gui.element, pinned); return compDetails.params; }); }; const fullWidthSuccess = tryRefresh(this.fullWidthGui, null); const centerSuccess = tryRefresh(this.centerGui, null); const leftSuccess = tryRefresh(this.leftGui, "left"); const rightSuccess = tryRefresh(this.rightGui, "right"); const allFullWidthRowsRefreshed = fullWidthSuccess && centerSuccess && leftSuccess && rightSuccess; return allFullWidthRowsRefreshed; } addListeners() { this.addManagedListeners(this.rowNode, { heightChanged: () => this.onRowHeightChanged(), rowSelected: () => this.onRowSelected(), rowIndexChanged: this.onRowIndexChanged.bind(this), topChanged: this.onTopChanged.bind(this), ...this.beans.expansionSvc?.getRowExpandedListeners(this) ?? {} }); if (this.rowNode.detail) { this.addManagedListeners(this.rowNode.parent, { dataChanged: this.onRowNodeDataChanged.bind(this) }); } this.addManagedListeners(this.rowNode, { dataChanged: this.onRowNodeDataChanged.bind(this), cellChanged: this.postProcessCss.bind(this), rowHighlightChanged: this.onRowNodeHighlightChanged.bind(this), draggingChanged: this.postProcessRowDragging.bind(this), uiLevelChanged: this.onUiLevelChanged.bind(this) }); this.addManagedListeners(this.beans.eventSvc, { paginationPixelOffsetChanged: this.onPaginationPixelOffsetChanged.bind(this), heightScaleChanged: this.onTopChanged.bind(this), displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this), virtualColumnsChanged: this.onVirtualColumnsChanged.bind(this), cellFocused: this.onCellFocusChanged.bind(this), cellFocusCleared: this.onCellFocusChanged.bind(this), paginationChanged: this.onPaginationChanged.bind(this), modelUpdated: this.refreshFirstAndLastRowStyles.bind(this), columnMoved: () => this.updateColumnLists() }); if (this.beans.rowSpanSvc) { this.addManagedListeners(this.beans.rowSpanSvc, { spannedCellsUpdated: ({ pinned }) => { if (pinned && !this.rowNode.rowPinned) { return; } this.updateColumnLists(); } }); } this.addDestroyFunc(() => { this.rowDragComps = this.destroyBeans(this.rowDragComps, this.beans.context); this.tooltipFeature = this.destroyBean(this.tooltipFeature, this.beans.context); }); this.addManagedPropertyListeners( ["rowStyle", "getRowStyle", "rowClass", "getRowClass", "rowClassRules"], this.postProcessCss.bind(this) ); this.addManagedPropertyListener("rowDragEntireRow", () => { const useRowDragEntireRow = this.gos.get("rowDragEntireRow"); if (useRowDragEntireRow) { this.allRowGuis.forEach((gui) => { this.addRowDraggerToRow(gui); }); return; } this.rowDragComps = this.destroyBeans(this.rowDragComps, this.beans.context); }); this.addListenersForCellComps(); } addListenersForCellComps() { this.addManagedListeners(this.rowNode, { rowIndexChanged: () => { this.getAllCellCtrls().forEach((cellCtrl) => cellCtrl.onRowIndexChanged()); }, cellChanged: (event) => { this.getAllCellCtrls().forEach((cellCtrl) => cellCtrl.onCellChanged(event)); } }); } onRowNodeDataChanged(event) { const fullWidthChanged = this.isFullWidth() !== !!this.isNodeFullWidthCell(); if (fullWidthChanged) { this.beans.rowRenderer.redrawRow(this.rowNode); return; } if (this.isFullWidth()) { const refresh = this.refreshFullWidth(); if (!refresh) { this.beans.rowRenderer.redrawRow(this.rowNode); } return; } this.getAllCellCtrls().forEach( (cellCtrl) => cellCtrl.refreshCell({ suppressFlash: !event.update, newData: !event.update }) ); this.allRowGuis.forEach((gui) => { this.setRowCompRowId(gui.rowComp); this.updateRowBusinessKey(); this.setRowCompRowBusinessKey(gui.rowComp); }); this.onRowSelected(); this.postProcessCss(); } postProcessCss() { this.setStylesFromGridOptions(true); this.postProcessClassesFromGridOptions(); this.postProcessRowClassRules(); this.postProcessRowDragging(); } onRowNodeHighlightChanged() { const highlighted = this.rowNode.highlighted; this.allRowGuis.forEach((gui) => { const aboveOn = highlighted === "Above"; const belowOn = highlighted === "Below"; gui.rowComp.addOrRemoveCssClass("ag-row-highlight-above", aboveOn); gui.rowComp.addOrRemoveCssClass("ag-row-highlight-below", belowOn); }); } postProcessRowDragging() { const dragging = this.rowNode.dragging; this.allRowGuis.forEach((gui) => gui.rowComp.addOrRemoveCssClass("ag-row-dragging", dragging)); } verifyCells() { this.onDisplayedColumnsChanged(); } onDisplayedColumnsChanged() { this.updateColumnLists(true); this.beans.rowAutoHeight?.requestCheckAutoHeight(); } onVirtualColumnsChanged() { this.updateColumnLists(false, true); } getRowPosition() { return { rowPinned: _makeNull(this.rowNode.rowPinned), rowIndex: this.rowNode.rowIndex }; } onKeyboardNavigate(keyboardEvent) { const groupInfo = this.findFullWidthInfoForEvent(keyboardEvent); if (!groupInfo) { return; } const { rowGui, column } = groupInfo; const currentFullWidthContainer = rowGui.element; const isFullWidthContainerFocused = currentFullWidthContainer === keyboardEvent.target; if (!isFullWidthContainerFocused) { return; } const node = this.rowNode; const { focusSvc, navigation } = this.beans; const lastFocusedCell = focusSvc.getFocusedCell(); const cellPosition = { rowIndex: node.rowIndex, rowPinned: node.rowPinned, column: lastFocusedCell?.column ?? column }; navigation?.navigateToNextCell(keyboardEvent, keyboardEvent.key, cellPosition, true); keyboardEvent.preventDefault(); } onTabKeyDown(keyboardEvent) { if (keyboardEvent.defaultPrevented || _isStopPropagationForAgGrid(keyboardEvent)) { return; } const currentFullWidthComp = this.allRowGuis.find( (c) => c.element.contains(keyboardEvent.target) ); const currentFullWidthContainer = currentFullWidthComp ? currentFullWidthComp.element : null; const isFullWidthContainerFocused = currentFullWidthContainer === keyboardEvent.target; const activeEl = _getActiveDomElement(this.beans); let isDetailGridCellFocused = false; if (currentFullWidthContainer && activeEl) { isDetailGridCellFocused = currentFullWidthContainer.contains(activeEl) && activeEl.classList.contains("ag-cell"); } let nextEl = null; if (!isFullWidthContainerFocused && !isDetailGridCellFocused) { nextEl = _findNextFocusableElement(this.beans, currentFullWidthContainer, false, keyboardEvent.shiftKey); } if (this.isFullWidth() && isFullWidthContainerFocused || !nextEl) { this.beans.navigation?.onTabKeyDown(this, keyboardEvent); } } getFullWidthElement() { if (this.fullWidthGui) { return this.fullWidthGui.element; } return null; } getRowYPosition() { const displayedEl = this.allRowGuis.find((el) => _isVisible(el.element))?.element; if (displayedEl) { return displayedEl.getBoundingClientRect().top; } return 0; } onSuppressCellFocusChanged(suppressCellFocus) { const tabIndex = this.isFullWidth() && suppressCellFocus ? void 0 : -1; this.allRowGuis.forEach((gui) => { _addOrRemoveAttribute(gui.element, "tabindex", tabIndex); }); } onFullWidthRowFocused(event) { const node = this.rowNode; const isFocused = !event ? false : this.isFullWidth() && event.rowIndex === node.rowIndex && event.rowPinned == node.rowPinned; const element = this.fullWidthGui ? this.fullWidthGui.element : this.centerGui?.element; if (!element) { return; } element.classList.toggle("ag-full-width-focus", isFocused); if (isFocused && event?.forceBrowserFocus) { element.focus({ preventScroll: true }); } } recreateCell(cellCtrl) { this.centerCellCtrls = this.removeCellCtrl(this.centerCellCtrls, cellCtrl); this.leftCellCtrls = this.removeCellCtrl(this.leftCellCtrls, cellCtrl); this.rightCellCtrls = this.removeCellCtrl(this.rightCellCtrls, cellCtrl); cellCtrl.destroy(); this.updateColumnLists(); } removeCellCtrl(prev, cellCtrlToRemove) { const res = { list: [], map: {} }; prev.list.forEach((cellCtrl) => { if (cellCtrl === cellCtrlToRemove) { return; } res.list.push(cellCtrl); res.map[cellCtrl.column.getInstanceId()] = cellCtrl; }); return res; } onMouseEvent(eventName, mouseEvent) { switch (eventName) { case "dblclick": this.onRowDblClick(mouseEvent); break; case "click": this.onRowClick(mouseEvent); break; case "touchstart": case "mousedown": this.onRowMouseDown(mouseEvent); break; } } createRowEvent(type, domEvent) { const { rowNode } = this; return _addGridCommonParams(this.gos, { type, node: rowNode, data: rowNode.data, rowIndex: rowNode.rowIndex, rowPinned: rowNode.rowPinned, event: domEvent }); } createRowEventWithSource(type, domEvent) { const event = this.createRowEvent(type, domEvent); event.source = this; return event; } onRowDblClick(mouseEvent) { if (_isStopPropagationForAgGrid(mouseEvent)) { return; } this.beans.eventSvc.dispatchEvent(this.createRowEventWithSource("rowDoubleClicked", mouseEvent)); } findFullWidthInfoForEvent(event) { if (!event) { return; } const rowGui = this.findFullWidthRowGui(event.target); const column = this.getColumnForFullWidth(rowGui); if (!rowGui || !column) { return; } return { rowGui, column }; } findFullWidthRowGui(target) { return this.allRowGuis.find((c) => c.element.contains(target)); } getColumnForFullWidth(fullWidthRowGui) { const { visibleCols } = this.beans; switch (fullWidthRowGui?.containerType) { case "center": return visibleCols.centerCols[0]; case "left": return visibleCols.leftCols[0]; case "right": return visibleCols.rightCols[0]; default: return visibleCols.allCols[0]; } } onRowMouseDown(mouseEvent) { this.lastMouseDownOnDragger = _isElementChildOfClass(mouseEvent.target, "ag-row-drag", 3); if (!this.isFullWidth()) { return; } const node = this.rowNode; const { rangeSvc, focusSvc } = this.beans; rangeSvc?.removeAllCellRanges(); const groupInfo = this.findFullWidthInfoForEvent(mouseEvent); if (!groupInfo) { return; } const { rowGui, column } = groupInfo; const element = rowGui.element; const target = mouseEvent.target; let forceBrowserFocus = mouseEvent.defaultPrevented || _isBrowserSafari(); if (element && element.contains(target) && _isFocusableFormField(target)) { forceBrowserFocus = false; } focusSvc.setFocusedCell({ rowIndex: node.rowIndex, column, rowPinned: node.rowPinned, forceBrowserFocus }); } onRowClick(mouseEvent) { const stop = _isStopPropagationForAgGrid(mouseEvent) || this.lastMouseDownOnDragger; if (stop) { return; } const { eventSvc, selectionSvc } = this.beans; eventSvc.dispatchEvent(this.createRowEventWithSource("rowClicked", mouseEvent)); selectionSvc?.handleSelectionEvent(mouseEvent, this.rowNode, "rowClicked"); } setupDetailRowAutoHeight(eDetailGui) { if (this.rowType !== "FullWidthDetail") { return; } this.beans.masterDetailSvc?.setupDetailRowAutoHeight(this, eDetailGui); } createFullWidthCompDetails(eRow, pinned) { const { gos, rowNode } = this; const params = _addGridCommonParams(gos, { fullWidth: true, data: rowNode.data, node: rowNode, value: rowNode.key, valueFormatted: rowNode.key, // these need to be taken out, as part of 'afterAttached' now eGridCell: eRow, eParentOfValue: eRow, pinned, addRenderedRowListener: this.addEventListener.bind(this), // This is not on the type of ICellRendererParams registerRowDragger: (rowDraggerElement, dragStartPixels, value, suppressVisibilityChange) => this.addFullWidthRowDragging(rowDraggerElement, dragStartPixels, value, suppressVisibilityChange), setTooltip: (value, shouldDisplayTooltip) => { gos.assertModuleRegistered("Tooltip", 3); this.refreshRowTooltip(value, shouldDisplayTooltip); } }); const compFactory = this.beans.userCompFactory; switch (this.rowType) { case "FullWidthDetail": return _getFullWidthDetailCellRendererDetails(compFactory, params); case "FullWidthGroup": return _getFullWidthGroupCellRendererDetails(compFactory, params); case "FullWidthLoading": return _getFullWidthLoadingCellRendererDetails(compFactory, params); default: return _getFullWidthCellRendererDetails(compFactory, params); } } refreshRowTooltip(value, shouldDisplayTooltip) { if (!this.fullWidthGui) { return; } this.tooltipFeature = this.beans.tooltipSvc?.refreshRowTooltip( this.tooltipFeature, this, value, shouldDisplayTooltip ); } addFullWidthRowDragging(rowDraggerElement, dragStartPixels, value = "", suppressVisibilityChange) { const { rowDragSvc, context } = this.beans; if (!rowDragSvc || !this.isFullWidth()) { return; } const rowDragComp = rowDragSvc.createRowDragComp( () => value, this.rowNode, void 0, rowDraggerElement, dragStartPixels, suppressVisibilityChange ); this.createBean(rowDragComp, context); this.addDestroyFunc(() => { this.destroyBean(rowDragComp, context); }); } onUiLevelChanged() { const newLevel = calculateRowLevel(this.rowNode); if (this.rowLevel != newLevel) { const classToAdd = "ag-row-level-" + newLevel; const classToRemove = "ag-row-level-" + this.rowLevel; this.allRowGuis.forEach((gui) => { gui.rowComp.addOrRemoveCssClass(classToAdd, true); gui.rowComp.addOrRemoveCssClass(classToRemove, false); }); } this.rowLevel = newLevel; } isFirstRowOnPage() { return this.rowNode.rowIndex === this.beans.pageBounds.getFirstRow(); } isLastRowOnPage() { return this.rowNode.rowIndex === this.beans.pageBounds.getLastRow(); } refreshFirstAndLastRowStyles() { const newFirst = this.isFirstRowOnPage(); const newLast = this.isLastRowOnPage(); if (this.firstRowOnPage !== newFirst) { this.firstRowOnPage = newFirst; this.allRowGuis.forEach((gui) => gui.rowComp.addOrRemoveCssClass("ag-row-first", newFirst)); } if (this.lastRowOnPage !== newLast) { this.lastRowOnPage = newLast; this.allRowGuis.forEach((gui) => gui.rowComp.addOrRemoveCssClass("ag-row-last", newLast)); } } getAllCellCtrls() { if (this.leftCellCtrls.list.length === 0 && this.rightCellCtrls.list.length === 0) { return this.centerCellCtrls.list; } const res = [...this.centerCellCtrls.list, ...this.leftCellCtrls.list, ...this.rightCellCtrls.list]; return res; } postProcessClassesFromGridOptions() { const cssClasses = []; this.beans.rowStyleSvc?.processClassesFromGridOptions(cssClasses, this.rowNode); if (!cssClasses.length) { return; } cssClasses.forEach((classStr) => { this.allRowGuis.forEach((c) => c.rowComp.addOrRemoveCssClass(classStr, true)); }); } postProcessRowClassRules() { this.beans.rowStyleSvc?.processRowClassRules( this.rowNode, (className) => { this.allRowGuis.forEach((gui) => gui.rowComp.addOrRemoveCssClass(className, true)); }, (className) => { this.allRowGuis.forEach((gui) => gui.rowComp.addOrRemoveCssClass(className, false)); } ); } setStylesFromGridOptions(updateStyles, gui) { if (updateStyles) { this.rowStyles = this.processStylesFromGridOptions(); } this.forEachGui(gui, (gui2) => gui2.rowComp.setUserStyles(this.rowStyles)); } getPinnedForContainer(rowContainerType) { if (rowContainerType === "left" || rowContainerType === "right") { return rowContainerType; } return null; } getInitialRowClasses(rowContainerType) { const pinned = this.getPinnedForContainer(rowContainerType); const fullWidthRow = this.isFullWidth(); const { rowNode, beans } = this; const classes = []; classes.push("ag-row"); classes.push(this.rowFocused ? "ag-row-focus" : "ag-row-no-focus"); if (this.fadeInAnimation[rowContainerType]) { classes.push("ag-opacity-zero"); } classes.push(rowNode.rowIndex % 2 === 0 ? "ag-row-even" : "ag-row-odd"); if (rowNode.isRowPinned()) { classes.push("ag-row-pinned"); } if (rowNode.isSelected()) { classes.push("ag-row-selected"); } if (rowNode.footer) { classes.push("ag-row-footer"); } classes.push("ag-row-level-" + this.rowLevel); if (rowNode.stub) { classes.push("ag-row-loading"); } if (fullWidthRow) { classes.push("ag-full-width-row"); } beans.expansionSvc?.addExpandedCss(classes, rowNode); if (rowNode.dragging) { classes.push("ag-row-dragging"); } const { rowStyleSvc } = beans; if (rowStyleSvc) { rowStyleSvc.processClassesFromGridOptions(classes, rowNode); rowStyleSvc.preProcessRowClassRules(classes, rowNode); } classes.push(this.printLayout ? "ag-row-position-relative" : "ag-row-position-absolute"); if (this.isFirstRowOnPage()) { classes.push("ag-row-first"); } if (this.isLastRowOnPage()) { classes.push("ag-row-last"); } if (fullWidthRow) { if (pinned === "left") { classes.push("ag-cell-last-left-pinned"); } if (pinned === "right") { classes.push("ag-cell-first-right-pinned"); } } return classes; } processStylesFromGridOptions() { return this.beans.rowStyleSvc?.processStylesFromGridOptions(this.rowNode) ?? this.emptyStyle; } onRowSelected(gui) { this.beans.selectionSvc?.onRowCtrlSelected( this, (gui2) => { if (gui2 === this.centerGui || gui2 === this.fullWidthGui) { this.announceDescription(); } }, gui ); } announceDescription() { this.beans.selectionSvc?.announceAriaRowSelection(this.rowNode); } addHoverFunctionality(eGui) { if (!this.active) { return; } const { element, compBean } = eGui; const { rowNode, beans, gos } = this; compBean.addManagedListeners(element, { mouseenter: () => rowNode.dispatchRowEvent("mouseEnter"), mouseleave: () => rowNode.dispatchRowEvent("mouseLeave") }); compBean.addManagedListeners(rowNode, { mouseEnter: () => { if (!beans.dragSvc?.dragging && !gos.get("suppressRowHoverHighlight")) { element.classList.add("ag-row-hover"); rowNode.setHovered(true); } }, mouseLeave: () => { this.resetHoveredStatus(element); } }); } resetHoveredStatus(el) { const elements = el ? [el] : this.allRowGuis.map((gui) => gui.element); for (const element of elements) { element.classList.remove("ag-row-hover"); } this.rowNode.setHovered(false); } // for animation, we don't want to animate entry or exit to a very far away pixel, // otherwise the row would move so fast, it would appear to disappear. so this method // moves the row closer to the viewport if it is far away, so the row slide in / out // at a speed the user can see. roundRowTopToBounds(rowTop) { const range = this.beans.ctrlsSvc.getScrollFeature().getApproximateVScollPosition(); const minPixel = this.applyPaginationOffset(range.top, true) - 100; const maxPixel = this.applyPaginationOffset(range.bottom, true) + 100; return Math.min(Math.max(minPixel, rowTop), maxPixel); } forEachGui(gui, callback) { if (gui) { callback(gui); } else { this.allRowGuis.forEach(callback); } } onRowHeightChanged(gui) { if (this.rowNode.rowHeight == null) { return; } const rowHeight = this.rowNode.rowHeight; const defaultRowHeight = this.beans.environment.getDefaultRowHeight(); const isHeightFromFunc = _isGetRowHeightFunction(this.gos); const heightFromFunc = isHeightFromFunc ? _getRowHeightForNode(this.beans, this.rowNode).height : void 0; const lineHeight = heightFromFunc ? `${Math.min(defaultRowHeight, heightFromFunc) - 2}px` : void 0; this.forEachGui(gui, (gui2) => { gui2.element.style.height = `${rowHeight}px`; if (lineHeight) { gui2.element.style.setProperty("--ag-line-height", lineHeight); } }); } // note - this is NOT called by context, as we don't wire / unwire the CellComp for performance reasons. destroyFirstPass(suppressAnimation = false) { this.active = false; const { rowNode } = this; if (!suppressAnimation && _isAnimateRows(this.gos) && !rowNode.sticky) { const rowStillVisibleJustNotInViewport = rowNode.rowTop != null; if (rowStillVisibleJustNotInViewport) { const rowTop = this.roundRowTopToBounds(rowNode.rowTop); this.setRowTop(rowTop); } else { this.allRowGuis.forEach((gui) => gui.rowComp.addOrRemoveCssClass("ag-opacity-zero", true)); } } rowNode.setHovered(false); const event = this.createRowEvent("virtualRowRemoved"); this.dispatchLocalEvent(event); this.beans.eventSvc.dispatchEvent(event); super.destroy(); } destroySecondPass() { this.allRowGuis.length = 0; this.beans.editSvc?.stopRowEditing(this); const destroyCellCtrls = (ctrls) => { ctrls.list.forEach((c) => c.destroy()); return { list: [], map: {} }; }; this.centerCellCtrls = destroyCellCtrls(this.centerCellCtrls); this.leftCellCtrls = destroyCellCtrls(this.leftCellCtrls); this.rightCellCtrls = destroyCellCtrls(this.rightCellCtrls); } setFocusedClasses(gui) { this.forEachGui(gui, (gui2) => { gui2.rowComp.addOrRemoveCssClass("ag-row-focus", this.rowFocused); gui2.rowComp.addOrRemoveCssClass("ag-row-no-focus", !this.rowFocused); }); } onCellFocusChanged() { const { focusSvc, editSvc } = this.beans; const rowFocused = focusSvc.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned); if (rowFocused !== this.rowFocused) { this.rowFocused = rowFocused; this.setFocusedClasses(); } if (!rowFocused && this.editing) { editSvc?.stopRowEditing(this, false); } } onPaginationChanged() { const currentPage = this.beans.pagination?.getCurrentPage() ?? 0; if (this.paginationPage !== currentPage) { this.paginationPage = currentPage; this.onTopChanged(); } this.refreshFirstAndLastRowStyles(); } onTopChanged() { this.setRowTop(this.rowNode.rowTop); } onPaginationPixelOffsetChanged() { this.onTopChanged(); } // applies pagination offset, eg if on second page, and page height is 500px, then removes // 500px from the top position, so a row with rowTop 600px is displayed at location 100px. // reverse will take the offset away rather than add. applyPaginationOffset(topPx, reverse = false) { if (this.rowNode.isRowPinned() || this.rowNode.sticky) { return topPx; } const pixelOffset = this.beans.pageBounds.getPixelOffset(); const multiplier = reverse ? 1 : -1; return topPx + pixelOffset * multiplier; } setRowTop(pixels) { if (this.printLayout) { return; } if (_exists(pixels)) { const afterPaginationPixels = this.applyPaginationOffset(pixels); const skipScaling = this.rowNode.isRowPinned() || this.rowNode.sticky; const afterScalingPixels = skipScaling ? afterPaginationPixels : this.beans.rowContainerHeight.getRealPixelPosition(afterPaginationPixels); const topPx = `${afterScalingPixels}px`; this.setRowTopStyle(topPx); } } // the top needs to be set into the DOM element when the element is created, not updated afterwards. // otherwise the transition would not work, as it would be transitioning from zero (the unset value). // for example, suppose a row that is outside the viewport, then user does a filter to remove other rows // and this row now appears in the viewport, and the row moves up (ie it was under the viewport and not rendered, // but now is in the viewport) then a new RowComp is created, however it should have it's position initialised // to below the viewport, so the row will appear to animate up. if we didn't set the initial position at creation // time, the row would animate down (ie from position zero). getInitialRowTop(rowContainerType) { return this.suppressRowTransform ? this.getInitialRowTopShared(rowContainerType) : void 0; } getInitialTransform(rowContainerType) { return this.suppressRowTransform ? void 0 : `translateY(${this.getInitialRowTopShared(rowContainerType)})`; } getInitialRowTopShared(rowContainerType) { if (this.printLayout) { return ""; } const rowNode = this.rowNode; let rowTop; if (rowNode.sticky) { rowTop = rowNode.stickyRowTop; } else { const pixels = this.slideInAnimation[rowContainerType] ? this.roundRowTopToBounds(rowNode.oldRowTop) : rowNode.rowTop; const afterPaginationPixels = this.applyPaginationOffset(pixels); rowTop = rowNode.isRowPinned() ? afterPaginationPixels : this.beans.rowContainerHeight.getRealPixelPosition(afterPaginationPixels); } return rowTop + "px"; } setRowTopStyle(topPx) { this.allRowGuis.forEach( (gui) => this.suppressRowTransform ? gui.rowComp.setTop(topPx) : gui.rowComp.setTransform(`translateY(${topPx})`) ); } getCellCtrl(column, skipColSpanSearch = false) { let res = null; this.getAllCellCtrls().forEach((cellCtrl) => { if (cellCtrl.column == column) { res = cellCtrl; } }); if (res != null || skipColSpanSearch) { return res; } this.getAllCellCtrls().forEach((cellCtrl) => { if (cellCtrl.getColSpanningList().indexOf(column) >= 0) { res = cellCtrl; } }); return res; } onRowIndexChanged() { if (this.rowNode.rowIndex != null) { this.onCellFocusChanged(); this.updateRowIndexes(); this.postProcessCss(); } } updateRowIndexes(gui) { const rowIndexStr = this.rowNode.getRowIndexString(); if (rowIndexStr === null) { return; } const headerRowCount = (this.beans.ctrlsSvc.getHeaderRowContainerCtrl()?.getRowCount() ?? 0) + (this.beans.filterManager?.getHeaderRowCount() ?? 0); const rowIsEven = this.rowNode.rowIndex % 2 === 0; const ariaRowIndex = headerRowCount + this.rowNode.rowIndex + 1; this.forEachGui(gui, (c) => { c.rowComp.setRowIndex(rowIndexStr); c.rowComp.addOrRemoveCssClass("ag-row-even", rowIsEven); c.rowComp.addOrRemoveCssClass("ag-row-odd", !rowIsEven); _setAriaRowIndex(c.element, ariaRowIndex); }); } }; // packages/ag-grid-community/src/utils/keyboard.ts function _isEventFromPrintableCharacter(event) { if (event.altKey || event.ctrlKey || event.metaKey) { return false; } const printableCharacter = event.key?.length === 1; return printableCharacter; } function _isUserSuppressingKeyboardEvent(gos, keyboardEvent, rowNode, column, editing) { const colDefFunc = column ? column.getColDef().suppressKeyboardEvent : void 0; if (!colDefFunc) { return false; } const params = _addGridCommonParams(gos, { event: keyboardEvent, editing, column, node: rowNode, data: rowNode.data, colDef: column.getColDef() }); if (colDefFunc) { const colDefFuncResult = colDefFunc(params); if (colDefFuncResult) { return true; } } return false; } // packages/ag-grid-community/src/utils/selection.ts function _selectAllCells(beans) { const { pinnedRowModel, rowModel } = beans; const [isEmptyPinnedTop, isEmptyPinnedBottom] = [ pinnedRowModel?.isEmpty("top") ?? true, pinnedRowModel?.isEmpty("bottom") ?? true ]; const floatingStart = isEmptyPinnedTop ? null : "top"; let floatingEnd; let rowEnd; if (isEmptyPinnedBottom) { floatingEnd = null; rowEnd = rowModel.getRowCount() - 1; } else { floatingEnd = "bottom"; rowEnd = pinnedRowModel?.getPinnedBottomRowCount() ?? 0 - 1; } const { visibleCols, rangeSvc } = beans; const allDisplayedColumns = visibleCols.allCols; if (!rangeSvc || !allDisplayedColumns?.length) { return; } rangeSvc.setCellRange({ rowStartIndex: 0, rowStartPinned: floatingStart, rowEndIndex: rowEnd, rowEndPinned: floatingEnd }); } // packages/ag-grid-community/src/gridBodyComp/rowContainer/rowContainerEventsFeature.ts var A_KEYCODE = 65; var C_KEYCODE = 67; var V_KEYCODE = 86; var D_KEYCODE = 68; var Z_KEYCODE = 90; var Y_KEYCODE = 89; function _normaliseQwertyAzerty(keyboardEvent) { const { keyCode } = keyboardEvent; let code; switch (keyCode) { case A_KEYCODE: code = KeyCode.A; break; case C_KEYCODE: code = KeyCode.C; break; case V_KEYCODE: code = KeyCode.V; break; case D_KEYCODE: code = KeyCode.D; break; case Z_KEYCODE: code = KeyCode.Z; break; case Y_KEYCODE: code = KeyCode.Y; break; default: code = keyboardEvent.code; } return code; } var RowContainerEventsFeature = class extends BeanStub { constructor(element) { super(); this.element = element; } postConstruct() { this.addKeyboardListeners(); this.addMouseListeners(); this.beans.touchSvc?.mockRowContextMenu(this); } addKeyboardListeners() { const eventName = "keydown"; const listener = this.processKeyboardEvent.bind(this, eventName); this.addManagedElementListeners(this.element, { [eventName]: listener }); } addMouseListeners() { const mouseDownEvent = _isEventSupported("touchstart") ? "touchstart" : "mousedown"; const eventNames = ["dblclick", "contextmenu", "mouseover", "mouseout", "click", mouseDownEvent]; eventNames.forEach((eventName) => { const listener = this.processMouseEvent.bind(this, eventName); this.addManagedElementListeners(this.element, { [eventName]: listener }); }); } processMouseEvent(eventName, mouseEvent) { if (!_isEventFromThisGrid(this.gos, mouseEvent) || _isStopPropagationForAgGrid(mouseEvent)) { return; } const { cellCtrl, rowCtrl } = this.getControlsForEventTarget(mouseEvent.target); if (eventName === "contextmenu") { if (cellCtrl?.column) { cellCtrl.dispatchCellContextMenuEvent(mouseEvent); } this.beans.contextMenuSvc?.handleContextMenuMouseEvent(mouseEvent, void 0, rowCtrl, cellCtrl); } else { if (cellCtrl) { cellCtrl.onMouseEvent(eventName, mouseEvent); } if (rowCtrl) { rowCtrl.onMouseEvent(eventName, mouseEvent); } } } getControlsForEventTarget(target) { const { gos } = this; return { cellCtrl: _getCellCtrlForEventTarget(gos, target), rowCtrl: _getCtrlForEventTarget(gos, target, DOM_DATA_KEY_ROW_CTRL) }; } processKeyboardEvent(eventName, keyboardEvent) { const { cellCtrl, rowCtrl } = this.getControlsForEventTarget(keyboardEvent.target); if (keyboardEvent.defaultPrevented) { return; } if (cellCtrl) { this.processCellKeyboardEvent(cellCtrl, eventName, keyboardEvent); } else if (rowCtrl && rowCtrl.isFullWidth()) { this.processFullWidthRowKeyboardEvent(rowCtrl, eventName, keyboardEvent); } } processCellKeyboardEvent(cellCtrl, eventName, keyboardEvent) { const { rowNode, column, editing } = cellCtrl; const gridProcessingAllowed = !_isUserSuppressingKeyboardEvent( this.gos, keyboardEvent, rowNode, column, editing ); if (gridProcessingAllowed) { if (eventName === "keydown") { const wasScrollKey = !editing && this.beans.navigation?.handlePageScrollingKey(keyboardEvent); if (!wasScrollKey) { cellCtrl.onKeyDown(keyboardEvent); } this.doGridOperations(keyboardEvent, cellCtrl.editing); if (_isEventFromPrintableCharacter(keyboardEvent)) { cellCtrl.processCharacter(keyboardEvent); } } } if (eventName === "keydown") { this.eventSvc.dispatchEvent(cellCtrl.createEvent(keyboardEvent, "cellKeyDown")); } } processFullWidthRowKeyboardEvent(rowComp, eventName, keyboardEvent) { const { rowNode } = rowComp; const { focusSvc, navigation } = this.beans; const focusedCell = focusSvc.getFocusedCell(); const column = focusedCell && focusedCell.column; const gridProcessingAllowed = !_isUserSuppressingKeyboardEvent(this.gos, keyboardEvent, rowNode, column, false); if (gridProcessingAllowed) { const key = keyboardEvent.key; if (eventName === "keydown") { switch (key) { case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: case KeyCode.PAGE_UP: case KeyCode.PAGE_DOWN: navigation?.handlePageScrollingKey(keyboardEvent, true); break; case KeyCode.UP: case KeyCode.DOWN: rowComp.onKeyboardNavigate(keyboardEvent); break; case KeyCode.TAB: rowComp.onTabKeyDown(keyboardEvent); break; default: } } } if (eventName === "keydown") { this.eventSvc.dispatchEvent(rowComp.createRowEvent("cellKeyDown", keyboardEvent)); } } doGridOperations(keyboardEvent, editing) { if (!keyboardEvent.ctrlKey && !keyboardEvent.metaKey) { return; } if (editing) { return; } if (!_isEventFromThisGrid(this.gos, keyboardEvent)) { return; } const keyCode = _normaliseQwertyAzerty(keyboardEvent); const { clipboardSvc, undoRedo } = this.beans; if (keyCode === KeyCode.A) { return this.onCtrlAndA(keyboardEvent); } if (keyCode === KeyCode.C) { return this.onCtrlAndC(clipboardSvc, keyboardEvent); } if (keyCode === KeyCode.D) { return this.onCtrlAndD(clipboardSvc, keyboardEvent); } if (keyCode === KeyCode.V) { return this.onCtrlAndV(clipboardSvc, keyboardEvent); } if (keyCode === KeyCode.X) { return this.onCtrlAndX(clipboardSvc, keyboardEvent); } if (keyCode === KeyCode.Y) { return this.onCtrlAndY(undoRedo); } if (keyCode === KeyCode.Z) { return this.onCtrlAndZ(undoRedo, keyboardEvent); } } onCtrlAndA(event) { const { beans: { rowModel, rangeSvc, selectionSvc }, gos } = this; if (rangeSvc && _isCellSelectionEnabled(gos) && rowModel.isRowsToRender()) { _selectAllCells(this.beans); } else if (selectionSvc) { selectionSvc?.selectAllRowNodes({ source: "keyboardSelectAll", selectAll: _getSelectAll(gos) }); } event.preventDefault(); } onCtrlAndC(clipboardSvc, event) { if (!clipboardSvc || this.gos.get("enableCellTextSelection")) { return; } const { cellCtrl, rowCtrl } = this.getControlsForEventTarget(event.target); if (cellCtrl?.editing || rowCtrl?.editing) { return; } event.preventDefault(); clipboardSvc.copyToClipboard(); } onCtrlAndX(clipboardSvc, event) { if (!clipboardSvc || this.gos.get("enableCellTextSelection") || this.gos.get("suppressCutToClipboard")) { return; } const { cellCtrl, rowCtrl } = this.getControlsForEventTarget(event.target); if (cellCtrl?.editing || rowCtrl?.editing) { return; } event.preventDefault(); clipboardSvc.cutToClipboard(void 0, "ui"); } onCtrlAndV(clipboardSvc, event) { const { cellCtrl, rowCtrl } = this.getControlsForEventTarget(event.target); if (cellCtrl?.editing || rowCtrl?.editing) { return; } if (clipboardSvc && !this.gos.get("suppressClipboardPaste")) { clipboardSvc.pasteFromClipboard(); } } onCtrlAndD(clipboardSvc, event) { if (clipboardSvc && !this.gos.get("suppressClipboardPaste")) { clipboardSvc.copyRangeDown(); } event.preventDefault(); } onCtrlAndZ(undoRedo, event) { if (!this.gos.get("undoRedoCellEditing") || !undoRedo) { return; } event.preventDefault(); if (event.shiftKey) { undoRedo.redo("ui"); } else { undoRedo.undo("ui"); } } onCtrlAndY(undoRedo) { undoRedo?.redo("ui"); } }; // packages/ag-grid-community/src/gridBodyComp/rowContainer/setHeightFeature.ts var SetHeightFeature = class extends BeanStub { constructor(eContainer, eViewport) { super(); this.eContainer = eContainer; this.eViewport = eViewport; } postConstruct() { this.addManagedEventListeners({ rowContainerHeightChanged: this.onHeightChanged.bind(this, this.beans.rowContainerHeight) }); } onHeightChanged(maxDivHeightScaler) { const height = maxDivHeightScaler.uiContainerHeight; const heightString = height != null ? `${height}px` : ``; this.eContainer.style.height = heightString; if (this.eViewport) { this.eViewport.style.height = heightString; } } }; // packages/ag-grid-community/src/gridBodyComp/rowContainer/rowContainerCtrl.ts var getTopRowCtrls = (r) => r.topRowCtrls; var getStickyTopRowCtrls = (r) => r.getStickyTopRowCtrls(); var getStickyBottomRowCtrls = (r) => r.getStickyBottomRowCtrls(); var getBottomRowCtrls = (r) => r.bottomRowCtrls; var getCentreRowCtrls = (r) => r.allRowCtrls; var getSpannedTopRowCtrls = (r) => r.getCtrls("top"); var getSpannedCenterRowCtrls = (r) => r.getCtrls("center"); var getSpannedBottomRowCtrls = (r) => r.getCtrls("bottom"); var ContainerCssClasses = { center: { type: "center", name: "center-cols", getRowCtrls: getCentreRowCtrls, getSpannedRowCtrls: getSpannedCenterRowCtrls }, left: { type: "left", name: "pinned-left-cols", pinnedType: "left", getRowCtrls: getCentreRowCtrls, getSpannedRowCtrls: getSpannedCenterRowCtrls }, right: { type: "right", name: "pinned-right-cols", pinnedType: "right", getRowCtrls: getCentreRowCtrls, getSpannedRowCtrls: getSpannedCenterRowCtrls }, fullWidth: { type: "fullWidth", name: "full-width", fullWidth: true, getRowCtrls: getCentreRowCtrls }, topCenter: { type: "center", name: "floating-top", getRowCtrls: getTopRowCtrls, getSpannedRowCtrls: getSpannedTopRowCtrls }, topLeft: { type: "left", name: "pinned-left-floating", container: "ag-pinned-left-floating-top", pinnedType: "left", getRowCtrls: getTopRowCtrls, getSpannedRowCtrls: getSpannedTopRowCtrls }, topRight: { type: "right", name: "pinned-right-floating", container: "ag-pinned-right-floating-top", pinnedType: "right", getRowCtrls: getTopRowCtrls, getSpannedRowCtrls: getSpannedTopRowCtrls }, topFullWidth: { type: "fullWidth", name: "floating-top-full-width", fullWidth: true, getRowCtrls: getTopRowCtrls }, stickyTopCenter: { type: "center", name: "sticky-top", getRowCtrls: getStickyTopRowCtrls }, stickyTopLeft: { type: "left", name: "pinned-left-sticky-top", container: "ag-pinned-left-sticky-top", pinnedType: "left", getRowCtrls: getStickyTopRowCtrls }, stickyTopRight: { type: "right", name: "pinned-right-sticky-top", container: "ag-pinned-right-sticky-top", pinnedType: "right", getRowCtrls: getStickyTopRowCtrls }, stickyTopFullWidth: { type: "fullWidth", name: "sticky-top-full-width", fullWidth: true, getRowCtrls: getStickyTopRowCtrls }, stickyBottomCenter: { type: "center", name: "sticky-bottom", getRowCtrls: getStickyBottomRowCtrls }, stickyBottomLeft: { type: "left", name: "pinned-left-sticky-bottom", container: "ag-pinned-left-sticky-bottom", pinnedType: "left", getRowCtrls: getStickyBottomRowCtrls }, stickyBottomRight: { type: "right", name: "pinned-right-sticky-bottom", container: "ag-pinned-right-sticky-bottom", pinnedType: "right", getRowCtrls: getStickyBottomRowCtrls }, stickyBottomFullWidth: { type: "fullWidth", name: "sticky-bottom-full-width", fullWidth: true, getRowCtrls: getStickyBottomRowCtrls }, bottomCenter: { type: "center", name: "floating-bottom", getRowCtrls: getBottomRowCtrls, getSpannedRowCtrls: getSpannedBottomRowCtrls }, bottomLeft: { type: "left", name: "pinned-left-floating-bottom", container: "ag-pinned-left-floating-bottom", pinnedType: "left", getRowCtrls: getBottomRowCtrls, getSpannedRowCtrls: getSpannedBottomRowCtrls }, bottomRight: { type: "right", name: "pinned-right-floating-bottom", container: "ag-pinned-right-floating-bottom", pinnedType: "right", getRowCtrls: getBottomRowCtrls, getSpannedRowCtrls: getSpannedBottomRowCtrls }, bottomFullWidth: { type: "fullWidth", name: "floating-bottom-full-width", fullWidth: true, getRowCtrls: getBottomRowCtrls } }; function _getRowViewportClass(name) { const options = _getRowContainerOptions(name); return `ag-${options.name}-viewport`; } function _getRowContainerClass(name) { const options = _getRowContainerOptions(name); return options.container ?? `ag-${options.name}-container`; } function _getRowSpanContainerClass(name) { const options = _getRowContainerOptions(name); return `ag-${options.name}-spanned-cells-container`; } function _getRowContainerOptions(name) { return ContainerCssClasses[name]; } var allTopNoFW = ["topCenter", "topLeft", "topRight"]; var allBottomNoFW = ["bottomCenter", "bottomLeft", "bottomRight"]; var allMiddleNoFW = ["center", "left", "right"]; var allMiddle = ["center", "left", "right", "fullWidth"]; var allCenter = ["stickyTopCenter", "stickyBottomCenter", "center", "topCenter", "bottomCenter"]; var allLeft = ["left", "bottomLeft", "topLeft", "stickyTopLeft", "stickyBottomLeft"]; var allRight = ["right", "bottomRight", "topRight", "stickyTopRight", "stickyBottomRight"]; var allStickyTopNoFW = ["stickyTopCenter", "stickyTopLeft", "stickyTopRight"]; var allStickyBottomNoFW = ["stickyBottomCenter", "stickyBottomLeft", "stickyBottomRight"]; var allStickyContainers = [ ...allStickyTopNoFW, "stickyTopFullWidth", ...allStickyBottomNoFW, "stickyBottomFullWidth" ]; var allNoFW = [ ...allTopNoFW, ...allBottomNoFW, ...allMiddleNoFW, ...allStickyTopNoFW, ...allStickyBottomNoFW ]; var RowContainerCtrl = class extends BeanStub { constructor(name) { super(); this.name = name; this.visible = true; // Maintaining a constant reference enables optimization in React. this.EMPTY_CTRLS = []; this.options = _getRowContainerOptions(name); } postConstruct() { this.enableRtl = this.gos.get("enableRtl"); this.forContainers(["center"], () => { this.viewportSizeFeature = this.createManagedBean(new ViewportSizeFeature(this)); this.addManagedEventListeners({ stickyTopOffsetChanged: this.onStickyTopOffsetChanged.bind(this) }); }); } onStickyTopOffsetChanged(event) { this.comp.setOffsetTop(`${event.offset}px`); } registerWithCtrlsService() { if (this.options.fullWidth) return; this.beans.ctrlsSvc.register(this.name, this); } forContainers(names, callback) { if (names.indexOf(this.name) >= 0) { callback(); } } setComp(view, eContainer, eSpannedContainer, eViewport) { this.comp = view; this.eContainer = eContainer; this.eSpannedContainer = eSpannedContainer; this.eViewport = eViewport; this.createManagedBean(new RowContainerEventsFeature(this.eViewport ?? this.eContainer)); this.addPreventScrollWhileDragging(); this.listenOnDomOrder(); const { pinnedCols, rangeSvc } = this.beans; const pinnedWidthChanged = () => this.onPinnedWidthChanged(); this.forContainers(allLeft, () => { this.pinnedWidthFeature = this.createOptionalManagedBean( pinnedCols?.createPinnedWidthFeature(true, this.eContainer, this.eSpannedContainer) ); this.addManagedEventListeners({ leftPinnedWidthChanged: pinnedWidthChanged }); }); this.forContainers(allRight, () => { this.pinnedWidthFeature = this.createOptionalManagedBean( pinnedCols?.createPinnedWidthFeature(false, this.eContainer, this.eSpannedContainer) ); this.addManagedEventListeners({ rightPinnedWidthChanged: pinnedWidthChanged }); }); this.forContainers( allMiddle, () => this.createManagedBean( new SetHeightFeature(this.eContainer, this.name === "center" ? eViewport : void 0) ) ); if (rangeSvc) { this.forContainers( allNoFW, () => this.createManagedBean(rangeSvc.createDragListenerFeature(this.eContainer)) ); } this.forContainers( allCenter, () => this.createManagedBean(new CenterWidthFeature((width) => this.comp.setContainerWidth(`${width}px`))) ); this.visible = this.isContainerVisible(); this.addListeners(); this.registerWithCtrlsService(); } onScrollCallback(fn) { this.addManagedElementListeners(this.eViewport, { scroll: fn }); } addListeners() { const { spannedRowRenderer, gos } = this.beans; this.addManagedEventListeners({ displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this), displayedColumnsWidthChanged: this.onDisplayedColumnsChanged.bind(this), displayedRowsChanged: (params) => this.onDisplayedRowsChanged(params.afterScroll) }); this.onDisplayedColumnsChanged(); this.onDisplayedRowsChanged(); if (spannedRowRenderer && this.options.getSpannedRowCtrls && gos.get("enableCellSpan")) { this.addManagedListeners(spannedRowRenderer, { spannedRowsUpdated: () => { const spannedCtrls = this.options.getSpannedRowCtrls(spannedRowRenderer); if (!spannedCtrls) { return; } this.comp.setSpannedRowCtrls(spannedCtrls, false); } }); } } listenOnDomOrder() { const isStickContainer = allStickyContainers.indexOf(this.name) >= 0; if (isStickContainer) { this.comp.setDomOrder(true); return; } const listener = () => { const isEnsureDomOrder = this.gos.get("ensureDomOrder"); const isPrintLayout = _isDomLayout(this.gos, "print"); this.comp.setDomOrder(isEnsureDomOrder || isPrintLayout); }; this.addManagedPropertyListener("domLayout", listener); listener(); } onDisplayedColumnsChanged() { this.forContainers(["center"], () => this.onHorizontalViewportChanged()); } // this methods prevents the grid views from being scrolled while the dragService is being used // eg. the view should not scroll up and down while dragging rows using the rowDragComp. addPreventScrollWhileDragging() { const { dragSvc } = this.beans; if (!dragSvc) { return; } const preventScroll = (e) => { if (dragSvc.dragging) { if (e.cancelable) { e.preventDefault(); } } }; this.eContainer.addEventListener("touchmove", preventScroll, { passive: false }); this.addDestroyFunc(() => this.eContainer.removeEventListener("touchmove", preventScroll)); } // this gets called whenever a change in the viewport, so we can inform column controller it has to work // out the virtual columns again. gets called from following locations: // + ensureColVisible, scroll, init, layoutChanged, displayedColumnsChanged onHorizontalViewportChanged(afterScroll = false) { const scrollWidth = this.getCenterWidth(); const scrollPosition = this.getCenterViewportScrollLeft(); this.beans.colViewport.setScrollPosition(scrollWidth, scrollPosition, afterScroll); } hasHorizontalScrollGap() { return this.eContainer.clientWidth - this.eViewport.clientWidth < 0; } hasVerticalScrollGap() { return this.eContainer.clientHeight - this.eViewport.clientHeight < 0; } getCenterWidth() { return _getInnerWidth(this.eViewport); } getCenterViewportScrollLeft() { return _getScrollLeft(this.eViewport, this.enableRtl); } registerViewportResizeListener(listener) { const unsubscribeFromResize = _observeResize(this.beans, this.eViewport, listener); this.addDestroyFunc(() => unsubscribeFromResize()); } isViewportInTheDOMTree() { return _isInDOM(this.eViewport); } getViewportScrollLeft() { return _getScrollLeft(this.eViewport, this.enableRtl); } isHorizontalScrollShowing() { const isAlwaysShowHorizontalScroll = this.gos.get("alwaysShowHorizontalScroll"); return isAlwaysShowHorizontalScroll || _isHorizontalScrollShowing(this.eViewport); } setHorizontalScroll(offset) { this.comp.setHorizontalScroll(offset); } getHScrollPosition() { const res = { left: this.eViewport.scrollLeft, right: this.eViewport.scrollLeft + this.eViewport.offsetWidth }; return res; } setCenterViewportScrollLeft(value) { _setScrollLeft(this.eViewport, value, this.enableRtl); } isContainerVisible() { const pinned = this.options.pinnedType != null; return !pinned || !!this.pinnedWidthFeature && this.pinnedWidthFeature.getWidth() > 0; } onPinnedWidthChanged() { const visible = this.isContainerVisible(); if (this.visible != visible) { this.visible = visible; this.onDisplayedRowsChanged(); } } onDisplayedRowsChanged(afterScroll = false) { const rows = this.options.getRowCtrls(this.beans.rowRenderer); if (!this.visible || rows.length === 0) { this.comp.setRowCtrls({ rowCtrls: this.EMPTY_CTRLS }); return; } const printLayout = _isDomLayout(this.gos, "print"); const embedFullWidthRows = this.gos.get("embedFullWidthRows"); const embedFW = embedFullWidthRows || printLayout; const rowsThisContainer = rows.filter((rowCtrl) => { const fullWidthRow = rowCtrl.isFullWidth(); const match = this.options.fullWidth ? !embedFW && fullWidthRow : embedFW || !fullWidthRow; return match; }); this.comp.setRowCtrls({ rowCtrls: rowsThisContainer, useFlushSync: afterScroll }); } }; // packages/ag-grid-community/src/gridBodyComp/gridBodyCtrl.ts var CSS_CLASS_FORCE_VERTICAL_SCROLL = "ag-force-vertical-scroll"; var CSS_CLASS_CELL_SELECTABLE = "ag-selectable"; var CSS_CLASS_COLUMN_MOVING = "ag-column-moving"; var GridBodyCtrl = class extends BeanStub { constructor() { super(...arguments); this.stickyTopHeight = 0; this.stickyBottomHeight = 0; } wireBeans(beans) { this.ctrlsSvc = beans.ctrlsSvc; this.colModel = beans.colModel; this.scrollVisibleSvc = beans.scrollVisibleSvc; this.pinnedRowModel = beans.pinnedRowModel; this.filterManager = beans.filterManager; this.rowGroupColsSvc = beans.rowGroupColsSvc; } setComp(comp, eGridBody, eBodyViewport, eTop, eBottom, eStickyTop, eStickyBottom) { this.comp = comp; this.eGridBody = eGridBody; this.eBodyViewport = eBodyViewport; this.eTop = eTop; this.eBottom = eBottom; this.eStickyTop = eStickyTop; this.eStickyBottom = eStickyBottom; this.eCenterColsViewport = eBodyViewport.querySelector(`.${_getRowViewportClass("center")}`); this.eFullWidthContainer = eBodyViewport.querySelector(`.${_getRowContainerClass("fullWidth")}`); this.eStickyTopFullWidthContainer = eStickyTop.querySelector( `.${_getRowContainerClass("stickyTopFullWidth")}` ); this.eStickyBottomFullWidthContainer = eStickyBottom.querySelector( `.${_getRowContainerClass("stickyBottomFullWidth")}` ); this.setCellTextSelection(this.gos.get("enableCellTextSelection")); this.addManagedPropertyListener( "enableCellTextSelection", (props) => this.setCellTextSelection(props.currentValue) ); this.createManagedBean(new LayoutFeature(this.comp)); this.scrollFeature = this.createManagedBean(new GridBodyScrollFeature(this.eBodyViewport)); this.beans.rowDragSvc?.setupRowDrag(this.eBodyViewport, this); this.setupRowAnimationCssClass(); this.addEventListeners(); this.addFocusListeners([eTop, eBodyViewport, eBottom, eStickyTop, eStickyBottom]); this.setGridRootRole(); this.onGridColumnsChanged(); this.addBodyViewportListener(); this.setFloatingHeights(); this.disableBrowserDragging(); this.addStopEditingWhenGridLosesFocus(); this.updateScrollingClasses(); this.filterManager?.setupAdvFilterHeaderComp(eTop); this.ctrlsSvc.register("gridBodyCtrl", this); } addEventListeners() { const setFloatingHeights = this.setFloatingHeights.bind(this); const setGridRootRole = this.setGridRootRole.bind(this); this.addManagedEventListeners({ gridColumnsChanged: this.onGridColumnsChanged.bind(this), scrollVisibilityChanged: this.onScrollVisibilityChanged.bind(this), scrollGapChanged: this.updateScrollingClasses.bind(this), pinnedRowDataChanged: setFloatingHeights, pinnedHeightChanged: setFloatingHeights, headerHeightChanged: this.setStickyTopOffsetTop.bind(this), columnRowGroupChanged: setGridRootRole, columnPivotChanged: setGridRootRole }); this.addManagedPropertyListener("treeData", setGridRootRole); } onGridColumnsChanged() { const columns = this.beans.colModel.getCols(); this.comp.setColumnCount(columns.length); } onScrollVisibilityChanged() { const { scrollVisibleSvc } = this; const visible = scrollVisibleSvc.verticalScrollShowing; this.setVerticalScrollPaddingVisible(visible); this.setStickyWidth(visible); this.setStickyBottomOffsetBottom(); const scrollbarWidth = visible ? scrollVisibleSvc.getScrollbarWidth() || 0 : 0; const pad = _isInvisibleScrollbar() ? 16 : 0; const width = `calc(100% + ${scrollbarWidth + pad}px)`; _requestAnimationFrame(this.beans, () => this.comp.setBodyViewportWidth(width)); this.updateScrollingClasses(); } setGridRootRole() { const { rowGroupColsSvc, colModel } = this; let isTreeGrid = this.gos.get("treeData"); if (!isTreeGrid) { const isPivotActive = colModel.isPivotMode(); const rowGroupColumnLen = !rowGroupColsSvc ? 0 : rowGroupColsSvc.columns.length; const columnsNeededForGrouping = isPivotActive ? 2 : 1; isTreeGrid = rowGroupColumnLen >= columnsNeededForGrouping; } this.comp.setGridRootRole(isTreeGrid ? "treegrid" : "grid"); } addFocusListeners(elements) { elements.forEach((element) => { this.addManagedElementListeners(element, { focusin: (e) => { const { target } = e; const isFocusedElementNested = _isElementChildOfClass(target, "ag-root", element); element.classList.toggle("ag-has-focus", !isFocusedElementNested); }, focusout: (e) => { const { target, relatedTarget } = e; const gridContainRelatedTarget = element.contains(relatedTarget); const isNestedRelatedTarget = _isElementChildOfClass( relatedTarget, "ag-root", element ); const isNestedTarget = _isElementChildOfClass(target, "ag-root", element); if (isNestedTarget) { return; } if (!gridContainRelatedTarget || isNestedRelatedTarget) { element.classList.remove("ag-has-focus"); } } }); }); } // used by ColumnAnimationService setColumnMovingCss(moving) { this.comp.setColumnMovingCss(CSS_CLASS_COLUMN_MOVING, moving); } setCellTextSelection(selectable = false) { this.comp.setCellSelectableCss(CSS_CLASS_CELL_SELECTABLE, selectable); } updateScrollingClasses() { const { eGridBody: { classList }, scrollVisibleSvc } = this; classList.toggle("ag-body-vertical-content-no-gap", !scrollVisibleSvc.verticalScrollGap); classList.toggle("ag-body-horizontal-content-no-gap", !scrollVisibleSvc.horizontalScrollGap); } // if we do not do this, then the user can select a pic in the grid (eg an image in a custom cell renderer) // and then that will start the browser native drag n' drop, which messes up with our own drag and drop. disableBrowserDragging() { this.addManagedElementListeners(this.eGridBody, { dragstart: (event) => { if (event.target instanceof HTMLImageElement) { event.preventDefault(); return false; } } }); } addStopEditingWhenGridLosesFocus() { this.beans.editSvc?.addStopEditingWhenGridLosesFocus([ this.eBodyViewport, this.eBottom, this.eTop, this.eStickyTop, this.eStickyBottom ]); } updateRowCount() { const headerCount = (this.ctrlsSvc.getHeaderRowContainerCtrl()?.getRowCount() ?? 0) + (this.filterManager?.getHeaderRowCount() ?? 0); const { rowModel } = this.beans; const rowCount = rowModel.isLastRowIndexKnown() ? rowModel.getRowCount() : -1; const total = rowCount === -1 ? -1 : headerCount + rowCount; this.comp.setRowCount(total); } registerBodyViewportResizeListener(listener) { this.comp.registerBodyViewportResizeListener(listener); } setVerticalScrollPaddingVisible(visible) { const overflowY = visible ? "scroll" : "hidden"; this.comp.setPinnedTopBottomOverflowY(overflowY); } isVerticalScrollShowing() { const show = this.gos.get("alwaysShowVerticalScroll"); const cssClass = show ? CSS_CLASS_FORCE_VERTICAL_SCROLL : null; const allowVerticalScroll = _isDomLayout(this.gos, "normal"); this.comp.setAlwaysVerticalScrollClass(cssClass, show); return show || allowVerticalScroll && _isVerticalScrollShowing(this.eBodyViewport); } setupRowAnimationCssClass() { const { rowContainerHeight, environment } = this.beans; let initialSizeMeasurementComplete = environment.sizesMeasured; const updateAnimationClass = () => { const animateRows = initialSizeMeasurementComplete && _isAnimateRows(this.gos) && !rowContainerHeight.stretching; const animateRowsCssClass = animateRows ? "ag-row-animation" : "ag-row-no-animation"; this.comp.setRowAnimationCssOnBodyViewport(animateRowsCssClass, animateRows); }; updateAnimationClass(); this.addManagedEventListeners({ heightScaleChanged: updateAnimationClass }); this.addManagedPropertyListener("animateRows", updateAnimationClass); this.addManagedEventListeners({ gridStylesChanged: () => { if (!initialSizeMeasurementComplete && environment.sizesMeasured) { initialSizeMeasurementComplete = true; updateAnimationClass(); } } }); } addBodyViewportListener() { const { popupSvc, touchSvc } = this.beans; const listener = this.onBodyViewportContextMenu.bind(this); this.addManagedElementListeners(this.eBodyViewport, { contextmenu: listener }); touchSvc?.mockBodyContextMenu(this, listener); this.addManagedElementListeners(this.eBodyViewport, { wheel: this.onBodyViewportWheel.bind(this, popupSvc) }); this.addManagedElementListeners(this.eStickyTop, { wheel: this.onStickyWheel.bind(this) }); this.addManagedElementListeners(this.eStickyBottom, { wheel: this.onStickyWheel.bind(this) }); this.addFullWidthContainerWheelListener(); } addFullWidthContainerWheelListener() { this.addManagedElementListeners(this.eFullWidthContainer, { wheel: (e) => this.onFullWidthContainerWheel(e) }); } onFullWidthContainerWheel(e) { const { deltaX, deltaY, shiftKey } = e; const isHorizontalScroll = shiftKey || Math.abs(deltaX) > Math.abs(deltaY); if (isHorizontalScroll && _isEventFromThisGrid(this.gos, e)) { this.scrollGridBodyToMatchEvent(e); } } onStickyWheel(e) { const { deltaX, deltaY, shiftKey } = e; const isHorizontalScroll = shiftKey || Math.abs(deltaX) > Math.abs(deltaY); const target = e.target; if (!isHorizontalScroll) { e.preventDefault(); this.scrollVertically(deltaY); } else if (this.eStickyTopFullWidthContainer.contains(target) || this.eStickyBottomFullWidthContainer.contains(target)) { this.scrollGridBodyToMatchEvent(e); } } scrollGridBodyToMatchEvent(e) { const { deltaX, deltaY } = e; e.preventDefault(); this.eCenterColsViewport.scrollBy({ left: deltaX || deltaY }); } onBodyViewportContextMenu(mouseEvent, touch, touchEvent) { if (!mouseEvent && !touchEvent) { return; } if (this.gos.get("preventDefaultOnContextMenu")) { const event = mouseEvent || touchEvent; event.preventDefault(); } const { target } = mouseEvent || touch; if (target === this.eBodyViewport || target === this.ctrlsSvc.get("center").eViewport) { this.beans.contextMenuSvc?.showContextMenu({ mouseEvent, touchEvent, value: null, anchorToElement: this.eGridBody, source: "ui" }); } } onBodyViewportWheel(popupSvc, e) { if (!this.gos.get("suppressScrollWhenPopupsAreOpen")) { return; } if (popupSvc?.hasAnchoredPopup()) { e.preventDefault(); } } // called by rowDragFeature scrollVertically(pixels) { const oldScrollPosition = this.eBodyViewport.scrollTop; this.scrollFeature.setVerticalScrollPosition(oldScrollPosition + pixels); return this.eBodyViewport.scrollTop - oldScrollPosition; } setFloatingHeights() { const { pinnedRowModel } = this; const floatingTopHeight = pinnedRowModel?.getPinnedTopTotalHeight() ?? 0; const floatingBottomHeight = pinnedRowModel?.getPinnedBottomTotalHeight() ?? 0; this.comp.setTopHeight(floatingTopHeight); this.comp.setBottomHeight(floatingBottomHeight); this.comp.setTopDisplay(floatingTopHeight ? "inherit" : "none"); this.comp.setBottomDisplay(floatingBottomHeight ? "inherit" : "none"); this.setStickyTopOffsetTop(); this.setStickyBottomOffsetBottom(); } setStickyTopHeight(height = 0) { this.comp.setStickyTopHeight(`${height}px`); this.stickyTopHeight = height; } setStickyBottomHeight(height = 0) { this.comp.setStickyBottomHeight(`${height}px`); this.stickyBottomHeight = height; } setStickyWidth(vScrollVisible) { if (!vScrollVisible) { this.comp.setStickyTopWidth("100%"); this.comp.setStickyBottomWidth("100%"); } else { const scrollbarWidth = this.scrollVisibleSvc.getScrollbarWidth(); this.comp.setStickyTopWidth(`calc(100% - ${scrollbarWidth}px)`); this.comp.setStickyBottomWidth(`calc(100% - ${scrollbarWidth}px)`); } } setStickyTopOffsetTop() { const headerCtrl = this.ctrlsSvc.get("gridHeaderCtrl"); const headerHeight = headerCtrl.headerHeight + (this.filterManager?.getHeaderHeight() ?? 0); const pinnedTopHeight = this.pinnedRowModel?.getPinnedTopTotalHeight() ?? 0; let height = 0; if (headerHeight > 0) { height += headerHeight; } if (pinnedTopHeight > 0) { height += pinnedTopHeight; } if (height > 0) { height += 1; } this.comp.setStickyTopTop(`${height}px`); } setStickyBottomOffsetBottom() { const { pinnedRowModel, scrollVisibleSvc, comp } = this; const pinnedBottomHeight = pinnedRowModel?.getPinnedBottomTotalHeight() ?? 0; const hScrollShowing = scrollVisibleSvc.horizontalScrollShowing; const scrollbarWidth = hScrollShowing ? scrollVisibleSvc.getScrollbarWidth() || 0 : 0; const height = pinnedBottomHeight + scrollbarWidth; comp.setStickyBottomBottom(`${height}px`); } }; // packages/ag-grid-community/src/gridBodyComp/abstractFakeScrollComp.ts var AbstractFakeScrollComp = class extends Component { constructor(template, direction) { super(); this.direction = direction; this.eViewport = RefPlaceholder; this.eContainer = RefPlaceholder; this.hideTimeout = 0; this.setTemplate(template); } postConstruct() { this.addManagedEventListeners({ scrollVisibilityChanged: this.onScrollVisibilityChanged.bind(this) }); this.onScrollVisibilityChanged(); this.addOrRemoveCssClass("ag-apple-scrollbar", _isMacOsUserAgent() || _isIOSUserAgent()); } destroy() { super.destroy(); window.clearTimeout(this.hideTimeout); } initialiseInvisibleScrollbar() { if (this.invisibleScrollbar !== void 0) { return; } this.invisibleScrollbar = _isInvisibleScrollbar(); if (this.invisibleScrollbar) { this.hideAndShowInvisibleScrollAsNeeded(); this.addActiveListenerToggles(); } } addActiveListenerToggles() { const eGui = this.getGui(); const onActivate = () => this.addOrRemoveCssClass("ag-scrollbar-active", true); const onDeactivate = () => this.addOrRemoveCssClass("ag-scrollbar-active", false); this.addManagedListeners(eGui, { mouseenter: onActivate, mousedown: onActivate, touchstart: onActivate, mouseleave: onDeactivate, touchend: onDeactivate }); } onScrollVisibilityChanged() { if (this.invisibleScrollbar === void 0) { this.initialiseInvisibleScrollbar(); } _requestAnimationFrame(this.beans, () => this.setScrollVisible()); } hideAndShowInvisibleScrollAsNeeded() { this.addManagedEventListeners({ bodyScroll: (params) => { if (params.direction === this.direction) { if (this.hideTimeout) { window.clearTimeout(this.hideTimeout); this.hideTimeout = 0; } this.addOrRemoveCssClass("ag-scrollbar-scrolling", true); } }, bodyScrollEnd: () => { this.hideTimeout = window.setTimeout(() => { this.addOrRemoveCssClass("ag-scrollbar-scrolling", false); this.hideTimeout = 0; }, 400); } }); } attemptSettingScrollPosition(value) { const viewport = this.eViewport; _waitUntil( () => _isVisible(viewport), () => this.setScrollPosition(value), 100 ); } onScrollCallback(fn) { this.addManagedElementListeners(this.eViewport, { scroll: fn }); } }; // packages/ag-grid-community/src/gridBodyComp/fakeHScrollComp.ts var FakeHScrollComp = class extends AbstractFakeScrollComp { constructor() { super( /* html */ ``, "horizontal" ); this.eLeftSpacer = RefPlaceholder; this.eRightSpacer = RefPlaceholder; this.setScrollVisibleDebounce = 0; } wireBeans(beans) { this.visibleCols = beans.visibleCols; this.scrollVisibleSvc = beans.scrollVisibleSvc; } postConstruct() { super.postConstruct(); const spacerWidthsListener = this.setFakeHScrollSpacerWidths.bind(this); this.addManagedEventListeners({ displayedColumnsChanged: spacerWidthsListener, displayedColumnsWidthChanged: spacerWidthsListener, pinnedRowDataChanged: this.refreshCompBottom.bind(this) }); this.addManagedPropertyListener("domLayout", spacerWidthsListener); this.beans.ctrlsSvc.register("fakeHScrollComp", this); this.createManagedBean(new CenterWidthFeature((width) => this.eContainer.style.width = `${width}px`)); this.addManagedPropertyListeners(["suppressHorizontalScroll"], this.onScrollVisibilityChanged.bind(this)); } destroy() { window.clearTimeout(this.setScrollVisibleDebounce); super.destroy(); } initialiseInvisibleScrollbar() { if (this.invisibleScrollbar !== void 0) { return; } this.enableRtl = this.gos.get("enableRtl"); super.initialiseInvisibleScrollbar(); if (this.invisibleScrollbar) { this.refreshCompBottom(); } } refreshCompBottom() { if (!this.invisibleScrollbar) { return; } const bottomPinnedHeight = this.beans.pinnedRowModel?.getPinnedBottomTotalHeight() ?? 0; this.getGui().style.bottom = `${bottomPinnedHeight}px`; } onScrollVisibilityChanged() { super.onScrollVisibilityChanged(); this.setFakeHScrollSpacerWidths(); } setFakeHScrollSpacerWidths() { const vScrollShowing = this.scrollVisibleSvc.verticalScrollShowing; let rightSpacing = this.visibleCols.getDisplayedColumnsRightWidth(); const scrollOnRight = !this.enableRtl && vScrollShowing; const scrollbarWidth = this.scrollVisibleSvc.getScrollbarWidth(); if (scrollOnRight) { rightSpacing += scrollbarWidth; } _setFixedWidth(this.eRightSpacer, rightSpacing); this.eRightSpacer.classList.toggle("ag-scroller-corner", rightSpacing <= scrollbarWidth); let leftSpacing = this.visibleCols.getColsLeftWidth(); const scrollOnLeft = this.enableRtl && vScrollShowing; if (scrollOnLeft) { leftSpacing += scrollbarWidth; } _setFixedWidth(this.eLeftSpacer, leftSpacing); this.eLeftSpacer.classList.toggle("ag-scroller-corner", leftSpacing <= scrollbarWidth); } setScrollVisible() { const hScrollShowing = this.scrollVisibleSvc.horizontalScrollShowing; const invisibleScrollbar2 = this.invisibleScrollbar; const isSuppressHorizontalScroll = this.gos.get("suppressHorizontalScroll"); const scrollbarWidth = hScrollShowing ? this.scrollVisibleSvc.getScrollbarWidth() || 0 : 0; const adjustedScrollbarWidth = scrollbarWidth === 0 && invisibleScrollbar2 ? 16 : scrollbarWidth; const scrollContainerSize = !isSuppressHorizontalScroll ? adjustedScrollbarWidth : 0; const apply = () => { this.setScrollVisibleDebounce = 0; this.addOrRemoveCssClass("ag-scrollbar-invisible", invisibleScrollbar2); _setFixedHeight(this.getGui(), scrollContainerSize); _setFixedHeight(this.eViewport, scrollContainerSize); _setFixedHeight(this.eContainer, scrollContainerSize); this.setDisplayed(hScrollShowing, { skipAriaHidden: true }); }; window.clearTimeout(this.setScrollVisibleDebounce); if (!hScrollShowing) { apply(); } else { this.setScrollVisibleDebounce = window.setTimeout(apply, 100); } } getScrollPosition() { return _getScrollLeft(this.eViewport, this.enableRtl); } setScrollPosition(value) { if (!_isVisible(this.eViewport)) { this.attemptSettingScrollPosition(value); } _setScrollLeft(this.eViewport, value, this.enableRtl); } }; var FakeHScrollSelector = { selector: "AG-FAKE-HORIZONTAL-SCROLL", component: FakeHScrollComp }; // packages/ag-grid-community/src/gridBodyComp/fakeVScrollComp.ts var FakeVScrollComp = class extends AbstractFakeScrollComp { constructor() { super( /* html */ ``, "vertical" ); } postConstruct() { super.postConstruct(); this.createManagedBean(new SetHeightFeature(this.eContainer)); const { ctrlsSvc } = this.beans; ctrlsSvc.register("fakeVScrollComp", this); this.addManagedEventListeners({ rowContainerHeightChanged: this.onRowContainerHeightChanged.bind(this, ctrlsSvc) }); } setScrollVisible() { const { scrollVisibleSvc } = this.beans; const vScrollShowing = scrollVisibleSvc.verticalScrollShowing; const invisibleScrollbar2 = this.invisibleScrollbar; const scrollbarWidth = vScrollShowing ? scrollVisibleSvc.getScrollbarWidth() || 0 : 0; const adjustedScrollbarWidth = scrollbarWidth === 0 && invisibleScrollbar2 ? 16 : scrollbarWidth; this.addOrRemoveCssClass("ag-scrollbar-invisible", invisibleScrollbar2); _setFixedWidth(this.getGui(), adjustedScrollbarWidth); _setFixedWidth(this.eViewport, adjustedScrollbarWidth); _setFixedWidth(this.eContainer, adjustedScrollbarWidth); this.setDisplayed(vScrollShowing, { skipAriaHidden: true }); } onRowContainerHeightChanged(ctrlsSvc) { const gridBodyCtrl = ctrlsSvc.getGridBodyCtrl(); const gridBodyViewportEl = gridBodyCtrl.eBodyViewport; const eViewportScrollTop = this.getScrollPosition(); const gridBodyViewportScrollTop = gridBodyViewportEl.scrollTop; if (eViewportScrollTop != gridBodyViewportScrollTop) { this.setScrollPosition(gridBodyViewportScrollTop, true); } } getScrollPosition() { return this.eViewport.scrollTop; } setScrollPosition(value, force) { if (!force && !_isVisible(this.eViewport)) { this.attemptSettingScrollPosition(value); } this.eViewport.scrollTop = value; } }; var FakeVScrollSelector = { selector: "AG-FAKE-VERTICAL-SCROLL", component: FakeVScrollComp }; // packages/ag-grid-community/src/headerRendering/headerUtils.ts function getHeaderRowCount(colModel) { return colModel.cols ? colModel.cols.treeDepth + 1 : -1; } function getFocusHeaderRowCount(beans) { return beans.ctrlsSvc.getHeaderRowContainerCtrl()?.getRowCount() ?? 0; } function getGroupRowsHeight(beans) { const heights = []; const headerRowContainerCtrls = beans.ctrlsSvc.getHeaderRowContainerCtrls(); for (const headerRowContainerCtrl of headerRowContainerCtrls) { if (!headerRowContainerCtrl) { continue; } const groupRowCount = headerRowContainerCtrl.getGroupRowCount() || 0; for (let i = 0; i < groupRowCount; i++) { const headerRowCtrl = headerRowContainerCtrl.getGroupRowCtrlAtIndex(i); const currentHeightAtPos = heights[i]; if (headerRowCtrl) { const newHeight = getColumnGroupHeaderRowHeight(beans, headerRowCtrl); if (currentHeightAtPos == null || newHeight > currentHeightAtPos) { heights[i] = newHeight; } } } } return heights; } function getColumnGroupHeaderRowHeight(beans, headerRowCtrl) { const defaultHeight = beans.colModel.isPivotMode() ? getPivotGroupHeaderHeight(beans) : getGroupHeaderHeight(beans); let displayedHeights = 0; const headerRowCellCtrls = headerRowCtrl.getHeaderCtrls(); for (const headerCellCtrl of headerRowCellCtrls) { const { column } = headerCellCtrl; if (column.isAutoHeaderHeight()) { const height = column.getAutoHeaderHeight(); if (height != null && height > displayedHeights) { displayedHeights = height; } } } return Math.max(defaultHeight, displayedHeights); } function getColumnHeaderRowHeight(beans) { const defaultHeight = beans.colModel.isPivotMode() ? getPivotHeaderHeight(beans) : getHeaderHeight(beans); const allDisplayedCols = beans.visibleCols.allCols; const displayedHeights = allDisplayedCols.filter((col) => col.isAutoHeaderHeight()).map((col) => col.getAutoHeaderHeight() || 0); return Math.max(defaultHeight, ...displayedHeights); } function getHeaderHeight(beans) { return beans.gos.get("headerHeight") ?? beans.environment.getDefaultHeaderHeight(); } function getFloatingFiltersHeight(beans) { return beans.gos.get("floatingFiltersHeight") ?? getHeaderHeight(beans); } function getGroupHeaderHeight(beans) { return beans.gos.get("groupHeaderHeight") ?? getHeaderHeight(beans); } function getPivotHeaderHeight(beans) { return beans.gos.get("pivotHeaderHeight") ?? getHeaderHeight(beans); } function getPivotGroupHeaderHeight(beans) { return beans.gos.get("pivotGroupHeaderHeight") ?? getGroupHeaderHeight(beans); } // packages/ag-grid-community/src/headerRendering/gridHeaderCtrl.ts var GridHeaderCtrl = class extends BeanStub { setComp(comp, eGui, eFocusableElement) { this.comp = comp; this.eGui = eGui; const { beans } = this; const { headerNavigation, touchSvc, ctrlsSvc } = beans; if (headerNavigation) { this.createManagedBean( new ManagedFocusFeature(eFocusableElement, { onTabKeyDown: this.onTabKeyDown.bind(this), handleKeyDown: this.handleKeyDown.bind(this), onFocusOut: this.onFocusOut.bind(this) }) ); } this.addManagedEventListeners({ columnPivotModeChanged: this.onPivotModeChanged.bind(this, beans), displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this, beans) }); this.onPivotModeChanged(beans); this.setupHeaderHeight(); const listener = this.onHeaderContextMenu.bind(this); this.addManagedElementListeners(this.eGui, { contextmenu: listener }); touchSvc?.mockHeaderContextMenu(this, listener); ctrlsSvc.register("gridHeaderCtrl", this); } setupHeaderHeight() { const listener = this.setHeaderHeight.bind(this); listener(); this.addManagedPropertyListeners( [ "headerHeight", "pivotHeaderHeight", "groupHeaderHeight", "pivotGroupHeaderHeight", "floatingFiltersHeight" ], listener ); this.addManagedEventListeners({ displayedColumnsChanged: listener, columnHeaderHeightChanged: listener, // add this to the animation frame to avoid a feedback loop columnGroupHeaderHeightChanged: () => _requestAnimationFrame(this.beans, () => listener()), gridStylesChanged: listener, advancedFilterEnabledChanged: listener }); } setHeaderHeight() { const { beans } = this; let totalHeaderHeight = 0; const groupHeight = getGroupRowsHeight(beans).reduce((prev, curr) => prev + curr, 0); const headerHeight = getColumnHeaderRowHeight(beans); if (beans.filterManager?.hasFloatingFilters()) { totalHeaderHeight += getFloatingFiltersHeight(beans); } totalHeaderHeight += groupHeight; totalHeaderHeight += headerHeight; if (this.headerHeight === totalHeaderHeight) { return; } this.headerHeight = totalHeaderHeight; const px = `${totalHeaderHeight + 1}px`; this.comp.setHeightAndMinHeight(px); this.eventSvc.dispatchEvent({ type: "headerHeightChanged" }); } onPivotModeChanged(beans) { const pivotMode = beans.colModel.isPivotMode(); this.comp.addOrRemoveCssClass("ag-pivot-on", pivotMode); this.comp.addOrRemoveCssClass("ag-pivot-off", !pivotMode); } onDisplayedColumnsChanged(beans) { const columns = beans.visibleCols.allCols; const shouldAllowOverflow = columns.some((col) => col.isSpanHeaderHeight()); this.comp.addOrRemoveCssClass("ag-header-allow-overflow", shouldAllowOverflow); } onTabKeyDown(e) { const isRtl = this.gos.get("enableRtl"); const backwards = e.shiftKey; const direction = backwards !== isRtl ? "LEFT" : "RIGHT"; const { beans } = this; const { headerNavigation, focusSvc } = beans; if (headerNavigation.navigateHorizontally(direction, true, e) || !backwards && focusSvc.focusOverlay(false) || _focusNextGridCoreContainer(beans, backwards, true)) { e.preventDefault(); } } handleKeyDown(e) { let direction = null; const { headerNavigation } = this.beans; switch (e.key) { case KeyCode.LEFT: direction = "LEFT"; case KeyCode.RIGHT: { if (!_exists(direction)) { direction = "RIGHT"; } if (headerNavigation.navigateHorizontally(direction, false, e)) { e.preventDefault(); } break; } case KeyCode.UP: direction = "UP"; case KeyCode.DOWN: { if (!_exists(direction)) { direction = "DOWN"; } if (headerNavigation.navigateVertically(direction, null, e)) { e.preventDefault(); } break; } default: return; } } onFocusOut(e) { const { relatedTarget } = e; const { eGui, beans } = this; if (!relatedTarget && eGui.contains(_getActiveDomElement(beans))) { return; } if (!eGui.contains(relatedTarget)) { beans.focusSvc.focusedHeader = null; } } onHeaderContextMenu(mouseEvent, touch, touchEvent) { const { menuSvc, ctrlsSvc } = this.beans; if (!mouseEvent && !touchEvent || !menuSvc?.isHeaderContextMenuEnabled()) { return; } const { target } = mouseEvent ?? touch; if (target === this.eGui || target === ctrlsSvc.getHeaderRowContainerCtrl()?.eViewport) { menuSvc.showHeaderContextMenu(void 0, mouseEvent, touchEvent); } } }; // packages/ag-grid-community/src/headerRendering/cells/abstractCell/abstractHeaderCellComp.ts var AbstractHeaderCellComp = class extends Component { constructor(template, ctrl) { super(template); this.ctrl = ctrl; } getCtrl() { return this.ctrl; } }; // packages/ag-grid-community/src/headerRendering/cells/column/headerCellComp.ts var HeaderCellComp = class extends AbstractHeaderCellComp { constructor(ctrl) { super( /* html */ `
`, ctrl ); this.eResize = RefPlaceholder; this.eHeaderCompWrapper = RefPlaceholder; this.headerCompVersion = 0; } postConstruct() { const eGui = this.getGui(); const setAttribute = (name, value) => { if (value != null && value != "") { eGui.setAttribute(name, value); } else { eGui.removeAttribute(name); } }; setAttribute("col-id", this.ctrl.column.getColId()); const compProxy = { setWidth: (width) => eGui.style.width = width, addOrRemoveCssClass: (cssClassName, on) => this.addOrRemoveCssClass(cssClassName, on), setUserStyles: (styles) => _addStylesToElement(eGui, styles), setAriaSort: (sort) => sort ? _setAriaSort(eGui, sort) : _removeAriaSort(eGui), setUserCompDetails: (compDetails) => this.setUserCompDetails(compDetails), getUserCompInstance: () => this.headerComp }; this.ctrl.setComp(compProxy, this.getGui(), this.eResize, this.eHeaderCompWrapper, void 0); const selectAllGui = this.ctrl.getSelectAllGui(); if (selectAllGui) { this.eResize.insertAdjacentElement("afterend", selectAllGui); } } destroy() { this.destroyHeaderComp(); super.destroy(); } destroyHeaderComp() { if (this.headerComp) { this.eHeaderCompWrapper.removeChild(this.headerCompGui); this.headerComp = this.destroyBean(this.headerComp); this.headerCompGui = void 0; } } setUserCompDetails(compDetails) { this.headerCompVersion++; const versionCopy = this.headerCompVersion; compDetails.newAgStackInstance().then((comp) => this.afterCompCreated(versionCopy, comp)); } afterCompCreated(version, headerComp) { if (version != this.headerCompVersion || !this.isAlive()) { this.destroyBean(headerComp); return; } this.destroyHeaderComp(); this.headerComp = headerComp; this.headerCompGui = headerComp.getGui(); this.eHeaderCompWrapper.appendChild(this.headerCompGui); this.ctrl.setDragSource(this.getGui()); } }; // packages/ag-grid-community/src/headerRendering/cells/columnGroup/headerGroupCellComp.ts var HeaderGroupCellComp = class extends AbstractHeaderCellComp { constructor(ctrl) { super( /* html */ `
`, ctrl ); this.eResize = RefPlaceholder; this.eHeaderCompWrapper = RefPlaceholder; } postConstruct() { const eGui = this.getGui(); const setAttribute = (key, value) => value != void 0 ? eGui.setAttribute(key, value) : eGui.removeAttribute(key); eGui.setAttribute("col-id", this.ctrl.column.getUniqueId()); const compProxy = { addOrRemoveCssClass: (cssClassName, on) => this.addOrRemoveCssClass(cssClassName, on), setUserStyles: (styles) => _addStylesToElement(eGui, styles), setHeaderWrapperHidden: (hidden) => { if (hidden) { this.eHeaderCompWrapper.style.setProperty("display", "none"); } else { this.eHeaderCompWrapper.style.removeProperty("display"); } }, setHeaderWrapperMaxHeight: (value) => { if (value != null) { this.eHeaderCompWrapper.style.setProperty("max-height", `${value}px`); } else { this.eHeaderCompWrapper.style.removeProperty("max-height"); } this.eHeaderCompWrapper.classList.toggle("ag-header-cell-comp-wrapper-limited-height", value != null); }, setResizableDisplayed: (displayed) => _setDisplayed(this.eResize, displayed), setWidth: (width) => eGui.style.width = width, setAriaExpanded: (expanded) => setAttribute("aria-expanded", expanded), setUserCompDetails: (details) => this.setUserCompDetails(details), getUserCompInstance: () => this.headerGroupComp }; this.ctrl.setComp(compProxy, eGui, this.eResize, this.eHeaderCompWrapper, void 0); } setUserCompDetails(details) { details.newAgStackInstance().then((comp) => this.afterHeaderCompCreated(comp)); } afterHeaderCompCreated(headerGroupComp) { const destroyFunc = () => this.destroyBean(headerGroupComp); if (!this.isAlive()) { destroyFunc(); return; } const eGui = this.getGui(); const eHeaderGroupGui = headerGroupComp.getGui(); this.eHeaderCompWrapper.appendChild(eHeaderGroupGui); this.addDestroyFunc(destroyFunc); this.headerGroupComp = headerGroupComp; this.ctrl.setDragSource(eGui); } addOrRemoveHeaderWrapperStyle(style, value) { const { eHeaderCompWrapper } = this; if (value) { eHeaderCompWrapper.style.setProperty(style, value); } else { eHeaderCompWrapper.style.removeProperty(style); } } }; // packages/ag-grid-community/src/headerRendering/cells/floatingFilter/headerFilterCellComp.ts var HeaderFilterCellComp = class extends AbstractHeaderCellComp { constructor(ctrl) { super( /* html */ `
`, ctrl ); this.eFloatingFilterBody = RefPlaceholder; this.eButtonWrapper = RefPlaceholder; this.eButtonShowMainFilter = RefPlaceholder; } postConstruct() { const eGui = this.getGui(); const compProxy = { addOrRemoveCssClass: (cssClassName, on) => this.addOrRemoveCssClass(cssClassName, on), setUserStyles: (styles) => _addStylesToElement(eGui, styles), addOrRemoveBodyCssClass: (cssClassName, on) => this.eFloatingFilterBody.classList.toggle(cssClassName, on), setButtonWrapperDisplayed: (displayed) => _setDisplayed(this.eButtonWrapper, displayed), setCompDetails: (compDetails) => this.setCompDetails(compDetails), getFloatingFilterComp: () => this.compPromise, setWidth: (width) => eGui.style.width = width, setMenuIcon: (eIcon) => this.eButtonShowMainFilter.appendChild(eIcon) }; this.ctrl.setComp(compProxy, eGui, this.eButtonShowMainFilter, this.eFloatingFilterBody, void 0); } setCompDetails(compDetails) { if (!compDetails) { this.destroyFloatingFilterComp(); this.compPromise = null; return; } this.compPromise = compDetails.newAgStackInstance(); this.compPromise.then((comp) => this.afterCompCreated(comp)); } destroy() { this.destroyFloatingFilterComp(); super.destroy(); } destroyFloatingFilterComp() { if (this.floatingFilterComp) { this.eFloatingFilterBody.removeChild(this.floatingFilterComp.getGui()); this.floatingFilterComp = this.destroyBean(this.floatingFilterComp); } } afterCompCreated(comp) { if (!comp) { return; } if (!this.isAlive()) { this.destroyBean(comp); return; } this.destroyFloatingFilterComp(); this.floatingFilterComp = comp; this.eFloatingFilterBody.appendChild(comp.getGui()); if (comp.afterGuiAttached) { comp.afterGuiAttached(); } } }; // packages/ag-grid-community/src/headerRendering/row/headerRowComp.ts var HeaderRowComp = class extends Component { constructor(ctrl) { super(); this.ctrl = ctrl; this.headerComps = {}; this.setTemplate( /* html */ `
` ); } postConstruct() { _setAriaRowIndex(this.getGui(), this.ctrl.getAriaRowIndex()); const compProxy = { setHeight: (height) => this.getGui().style.height = height, setTop: (top) => this.getGui().style.top = top, setHeaderCtrls: (ctrls, forceOrder) => this.setHeaderCtrls(ctrls, forceOrder), setWidth: (width) => this.getGui().style.width = width }; this.ctrl.setComp(compProxy, void 0); } destroy() { this.setHeaderCtrls([], false); super.destroy(); } setHeaderCtrls(ctrls, forceOrder) { if (!this.isAlive()) { return; } const oldComps = this.headerComps; this.headerComps = {}; ctrls.forEach((ctrl) => { const id = ctrl.instanceId; let comp = oldComps[id]; delete oldComps[id]; if (comp == null) { comp = this.createHeaderComp(ctrl); this.getGui().appendChild(comp.getGui()); } this.headerComps[id] = comp; }); Object.values(oldComps).forEach((comp) => { this.getGui().removeChild(comp.getGui()); this.destroyBean(comp); }); if (forceOrder) { const comps = Object.values(this.headerComps); comps.sort( (a, b) => { const leftA = a.getCtrl().column.getLeft(); const leftB = b.getCtrl().column.getLeft(); return leftA - leftB; } ); const elementsInOrder = comps.map((c) => c.getGui()); _setDomChildOrder(this.getGui(), elementsInOrder); } } createHeaderComp(headerCtrl) { let result; switch (this.ctrl.type) { case "group": result = new HeaderGroupCellComp(headerCtrl); break; case "filter": result = new HeaderFilterCellComp(headerCtrl); break; default: result = new HeaderCellComp(headerCtrl); break; } this.createBean(result); result.setParentComponent(this); return result; } }; // packages/ag-grid-community/src/rendering/features/setLeftFeature.ts var SetLeftFeature = class extends BeanStub { constructor(columnOrGroup, eCell, beans, colsSpanning) { super(); this.columnOrGroup = columnOrGroup; this.eCell = eCell; this.colsSpanning = colsSpanning; this.columnOrGroup = columnOrGroup; this.ariaEl = eCell.querySelector("[role=columnheader]") || eCell; this.beans = beans; } setColsSpanning(colsSpanning) { this.colsSpanning = colsSpanning; this.onLeftChanged(); } getColumnOrGroup() { const { beans, colsSpanning } = this; if (beans.gos.get("enableRtl") && colsSpanning) { return _last(colsSpanning); } return this.columnOrGroup; } postConstruct() { const onLeftChanged = this.onLeftChanged.bind(this); this.addManagedListeners(this.columnOrGroup, { leftChanged: onLeftChanged }); this.setLeftFirstTime(); this.addManagedEventListeners({ displayedColumnsWidthChanged: onLeftChanged }); this.addManagedPropertyListener("domLayout", onLeftChanged); } setLeftFirstTime() { const { gos, colAnimation } = this.beans; const suppressMoveAnimation = gos.get("suppressColumnMoveAnimation"); const oldLeftExists = _exists(this.columnOrGroup.getOldLeft()); const animateColumnMove = colAnimation?.isActive() && oldLeftExists && !suppressMoveAnimation; if (animateColumnMove) { this.animateInLeft(); } else { this.onLeftChanged(); } } animateInLeft() { const colOrGroup = this.getColumnOrGroup(); const oldActualLeft = this.modifyLeftForPrintLayout(colOrGroup, colOrGroup.getOldLeft()); const actualLeft = this.modifyLeftForPrintLayout(colOrGroup, colOrGroup.getLeft()); this.setLeft(oldActualLeft); this.actualLeft = actualLeft; this.beans.colAnimation.executeNextVMTurn(() => { if (this.actualLeft === actualLeft) { this.setLeft(actualLeft); } }); } onLeftChanged() { const colOrGroup = this.getColumnOrGroup(); const left = colOrGroup.getLeft(); this.actualLeft = this.modifyLeftForPrintLayout(colOrGroup, left); this.setLeft(this.actualLeft); } modifyLeftForPrintLayout(colOrGroup, leftPosition) { const { gos, visibleCols } = this.beans; const printLayout = _isDomLayout(gos, "print"); if (!printLayout) { return leftPosition; } if (colOrGroup.getPinned() === "left") { return leftPosition; } const leftWidth = visibleCols.getColsLeftWidth(); if (colOrGroup.getPinned() === "right") { const bodyWidth = visibleCols.bodyWidth; return leftWidth + bodyWidth + leftPosition; } return leftWidth + leftPosition; } setLeft(value) { if (_exists(value)) { this.eCell.style.left = `${value}px`; } if (isColumnGroup2(this.columnOrGroup)) { const children = this.columnOrGroup.getLeafColumns(); if (!children.length) { return; } if (children.length > 1) { _setAriaColSpan(this.ariaEl, children.length); } } } }; // packages/ag-grid-community/src/headerRendering/cells/abstractCell/abstractHeaderCellCtrl.ts var instanceIdSequence4 = 0; var DOM_DATA_KEY_HEADER_CTRL = "headerCtrl"; var AbstractHeaderCellCtrl = class extends BeanStub { constructor(column, rowCtrl) { super(); this.column = column; this.rowCtrl = rowCtrl; this.resizeToggleTimeout = 0; this.resizeMultiplier = 1; this.resizeFeature = null; this.lastFocusEvent = null; this.dragSource = null; this.instanceId = column.getUniqueId() + "-" + instanceIdSequence4++; } postConstruct() { const refreshTabIndex = this.refreshTabIndex.bind(this); this.addManagedPropertyListeners(["suppressHeaderFocus"], refreshTabIndex); this.addManagedEventListeners({ overlayExclusiveChanged: refreshTabIndex }); } shouldStopEventPropagation(event) { const { headerRowIndex, column } = this.beans.focusSvc.focusedHeader; const colDef = column.getDefinition(); const colDefFunc = colDef && colDef.suppressHeaderKeyboardEvent; if (!_exists(colDefFunc)) { return false; } const params = _addGridCommonParams(this.gos, { colDef, column, headerRowIndex, event }); return !!colDefFunc(params); } getWrapperHasFocus() { const activeEl = _getActiveDomElement(this.beans); return activeEl === this.eGui; } setGui(eGui, compBean) { this.eGui = eGui; this.addDomData(compBean); compBean.addManagedListeners(this.beans.eventSvc, { displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this) }); compBean.addManagedElementListeners(this.eGui, { focus: this.onGuiFocus.bind(this) }); this.onDisplayedColumnsChanged(); this.refreshTabIndex(); } refreshHeaderStyles() { const colDef = this.column.getDefinition(); if (!colDef) { return; } const { headerStyle } = colDef; let styles; if (typeof headerStyle === "function") { const cellStyleParams = this.getHeaderClassParams(); styles = headerStyle(cellStyleParams); } else { styles = headerStyle; } if (styles) { this.comp.setUserStyles(styles); } } onGuiFocus() { this.eventSvc.dispatchEvent({ type: "headerFocused", column: this.column }); } setupAutoHeight(params) { const { wrapperElement, checkMeasuringCallback, compBean } = params; const { beans } = this; const measureHeight = (timesCalled) => { if (!this.isAlive() || !compBean.isAlive()) { return; } const { paddingTop, paddingBottom, borderBottomWidth, borderTopWidth } = _getElementSize(this.eGui); const extraHeight = paddingTop + paddingBottom + borderBottomWidth + borderTopWidth; const wrapperHeight = wrapperElement.offsetHeight; const autoHeight = wrapperHeight + extraHeight; if (timesCalled < 5) { const doc = _getDocument(beans); const notYetInDom = !doc || !doc.contains(wrapperElement); const possiblyNoContentYet = autoHeight == 0; if (notYetInDom || possiblyNoContentYet) { _requestAnimationFrame(beans, () => measureHeight(timesCalled + 1)); return; } } this.setColHeaderHeight(this.column, autoHeight); }; let isMeasuring = false; let stopResizeObserver; const checkMeasuring = () => { const newValue = this.column.isAutoHeaderHeight(); if (newValue && !isMeasuring) { startMeasuring(); } if (!newValue && isMeasuring) { stopMeasuring(); } }; const startMeasuring = () => { isMeasuring = true; measureHeight(0); this.comp.addOrRemoveCssClass("ag-header-cell-auto-height", true); stopResizeObserver = _observeResize(this.beans, wrapperElement, () => measureHeight(0)); }; const stopMeasuring = () => { isMeasuring = false; if (stopResizeObserver) { stopResizeObserver(); } this.comp.addOrRemoveCssClass("ag-header-cell-auto-height", false); stopResizeObserver = void 0; }; checkMeasuring(); compBean.addDestroyFunc(() => stopMeasuring()); compBean.addManagedListeners(this.column, { widthChanged: () => isMeasuring && measureHeight(0) }); compBean.addManagedEventListeners({ sortChanged: () => { if (isMeasuring) { window.setTimeout(() => measureHeight(0)); } } }); if (checkMeasuringCallback) { checkMeasuringCallback(checkMeasuring); } } onDisplayedColumnsChanged() { const { comp, column, beans, eGui } = this; if (!comp || !column || !eGui) { return; } refreshFirstAndLastStyles(comp, column, beans.visibleCols); _setAriaColIndex(eGui, beans.visibleCols.getAriaColIndex(column)); } addResizeAndMoveKeyboardListeners(compBean) { compBean.addManagedListeners(this.eGui, { keydown: this.onGuiKeyDown.bind(this), keyup: this.onGuiKeyUp.bind(this) }); } refreshTabIndex() { const suppressHeaderFocus = _isHeaderFocusSuppressed(this.beans); if (this.eGui) { _addOrRemoveAttribute(this.eGui, "tabindex", suppressHeaderFocus ? null : "-1"); } } onGuiKeyDown(e) { const activeEl = _getActiveDomElement(this.beans); const isLeftOrRight = e.key === KeyCode.LEFT || e.key === KeyCode.RIGHT; if (this.isResizing) { e.preventDefault(); e.stopImmediatePropagation(); } if ( // if elements within the header are focused, we don't process the event activeEl !== this.eGui || // if shiftKey and altKey are not pressed, it's cell navigation so we don't process the event !e.shiftKey && !e.altKey ) { return; } if (this.isResizing || isLeftOrRight) { e.preventDefault(); e.stopImmediatePropagation(); } if (!isLeftOrRight) { return; } const isLeft = e.key === KeyCode.LEFT !== this.gos.get("enableRtl"); const direction = isLeft ? "left" : "right"; if (e.altKey) { this.isResizing = true; this.resizeMultiplier += 1; const diff = this.getViewportAdjustedResizeDiff(e); this.resizeHeader(diff, e.shiftKey); this.resizeFeature?.toggleColumnResizing(true); } else { this.moveHeader(direction); } } moveHeader(hDirection) { this.beans.colMoves?.moveHeader(hDirection, this.eGui, this.column, this.rowCtrl.pinned, this); } getViewportAdjustedResizeDiff(e) { const diff = this.getResizeDiff(e); const { pinnedCols } = this.beans; return pinnedCols ? pinnedCols.getHeaderResizeDiff(diff, this.column) : diff; } getResizeDiff(e) { const { gos, column } = this; let isLeft = e.key === KeyCode.LEFT !== gos.get("enableRtl"); const pinned = column.getPinned(); const isRtl = gos.get("enableRtl"); if (pinned) { if (isRtl !== (pinned === "right")) { isLeft = !isLeft; } } return (isLeft ? -1 : 1) * this.resizeMultiplier; } onGuiKeyUp() { if (!this.isResizing) { return; } if (this.resizeToggleTimeout) { window.clearTimeout(this.resizeToggleTimeout); this.resizeToggleTimeout = 0; } this.isResizing = false; this.resizeMultiplier = 1; this.resizeToggleTimeout = window.setTimeout(() => { this.resizeFeature?.toggleColumnResizing(false); }, 150); } handleKeyDown(e) { const wrapperHasFocus = this.getWrapperHasFocus(); switch (e.key) { case KeyCode.PAGE_DOWN: case KeyCode.PAGE_UP: case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: if (wrapperHasFocus) { e.preventDefault(); } } } addDomData(compBean) { const key = DOM_DATA_KEY_HEADER_CTRL; const { eGui, gos } = this; _setDomData(gos, eGui, key, this); compBean.addDestroyFunc(() => _setDomData(gos, eGui, key, null)); } focus(event) { const { eGui } = this; if (!eGui) { return false; } this.lastFocusEvent = event || null; eGui.focus(); return true; } focusThis() { this.beans.focusSvc.focusedHeader = { headerRowIndex: this.rowCtrl.rowIndex, column: this.column }; } removeDragSource() { if (this.dragSource) { this.beans.dragAndDrop?.removeDragSource(this.dragSource); this.dragSource = null; } } handleContextMenuMouseEvent(mouseEvent, touchEvent, column) { const event = mouseEvent ?? touchEvent; const { menuSvc, gos } = this.beans; if (gos.get("preventDefaultOnContextMenu")) { event.preventDefault(); } if (menuSvc?.isHeaderContextMenuEnabled(column)) { menuSvc.showHeaderContextMenu(column, mouseEvent, touchEvent); } this.dispatchColumnMouseEvent("columnHeaderContextMenu", column); } dispatchColumnMouseEvent(eventType, column) { this.eventSvc.dispatchEvent({ type: eventType, column }); } setColHeaderHeight(col, height) { if (!col.setAutoHeaderHeight(height)) { return; } const { eventSvc } = this; if (col.isColumn) { eventSvc.dispatchEvent({ type: "columnHeaderHeightChanged", column: col, columns: [col], source: "autosizeColumnHeaderHeight" }); } else { eventSvc.dispatchEvent({ type: "columnGroupHeaderHeightChanged", columnGroup: col, source: "autosizeColumnGroupHeaderHeight" }); } } clearComponent() { this.removeDragSource(); this.resizeFeature = null; this.comp = null; this.eGui = null; } destroy() { super.destroy(); this.column = null; this.lastFocusEvent = null; this.rowCtrl = null; } }; // packages/ag-grid-community/src/headerRendering/cells/column/headerCellCtrl.ts var HeaderCellCtrl = class extends AbstractHeaderCellCtrl { constructor() { super(...arguments); this.refreshFunctions = {}; this.userHeaderClasses = /* @__PURE__ */ new Set(); this.ariaDescriptionProperties = /* @__PURE__ */ new Map(); } setComp(comp, eGui, eResize, eHeaderCompWrapper, compBeanInput) { this.comp = comp; const { rowCtrl, column, beans } = this; const { colResize, context, colHover, rangeSvc } = beans; const compBean = setupCompBean(this, context, compBeanInput); this.setGui(eGui, compBean); this.updateState(); this.setupWidth(compBean); this.setupMovingCss(compBean); this.setupMenuClass(compBean); this.setupSortableClass(compBean); this.setupWrapTextClass(); this.refreshSpanHeaderHeight(); this.setupAutoHeight({ wrapperElement: eHeaderCompWrapper, checkMeasuringCallback: (checkMeasuring) => this.setRefreshFunction("measuring", checkMeasuring), compBean }); this.addColumnHoverListener(compBean); this.setupFilterClass(compBean); this.setupStylesFromColDef(); this.setupClassesFromColDef(); this.setupTooltip(); this.addActiveHeaderMouseListeners(compBean); this.setupSelectAll(compBean); this.setupUserComp(); this.refreshAria(); if (colResize) { this.resizeFeature = compBean.createManagedBean( colResize.createResizeFeature(rowCtrl.pinned, column, eResize, comp, this) ); } else { _setDisplayed(eResize, false); } colHover?.createHoverFeature(compBean, [column], eGui); rangeSvc?.createRangeHighlightFeature(compBean, column, comp); compBean.createManagedBean(new SetLeftFeature(column, eGui, beans)); compBean.createManagedBean( new ManagedFocusFeature(eGui, { shouldStopEventPropagation: (e) => this.shouldStopEventPropagation(e), onTabKeyDown: () => null, handleKeyDown: this.handleKeyDown.bind(this), onFocusIn: this.onFocusIn.bind(this), onFocusOut: this.onFocusOut.bind(this) }) ); this.addResizeAndMoveKeyboardListeners(compBean); compBean.addManagedPropertyListeners( ["suppressMovableColumns", "suppressMenuHide", "suppressAggFuncInHeader", "enableAdvancedFilter"], () => this.refresh() ); compBean.addManagedListeners(column, { colDefChanged: () => this.refresh() }); compBean.addManagedListeners(column, { headerHighlightChanged: this.onHeaderHighlightChanged.bind(this) }); const listener = () => this.checkDisplayName(); compBean.addManagedEventListeners({ columnValueChanged: listener, columnRowGroupChanged: listener, columnPivotChanged: listener, headerHeightChanged: this.onHeaderHeightChanged.bind(this) }); compBean.addDestroyFunc(() => { this.refreshFunctions = {}; this.selectAllFeature = null; this.dragSourceElement = void 0; this.userCompDetails = null; this.userHeaderClasses.clear(); this.ariaDescriptionProperties.clear(); this.clearComponent(); }); } resizeHeader(delta, shiftKey) { this.beans.colResize?.resizeHeader(this.column, delta, shiftKey); } getHeaderClassParams() { const { column, beans } = this; const colDef = column.colDef; return _addGridCommonParams(beans.gos, { colDef, column, floatingFilter: false }); } setupUserComp() { const compDetails = this.lookupUserCompDetails(); if (compDetails) { this.setCompDetails(compDetails); } } setCompDetails(compDetails) { this.userCompDetails = compDetails; this.comp.setUserCompDetails(compDetails); } lookupUserCompDetails() { const params = this.createParams(); const colDef = this.column.getColDef(); return _getHeaderCompDetails(this.beans.userCompFactory, colDef, params); } createParams() { const { menuSvc, sortSvc, colFilter, gos } = this.beans; const params = _addGridCommonParams(gos, { column: this.column, displayName: this.displayName, enableSorting: this.column.isSortable(), enableMenu: this.menuEnabled, enableFilterButton: this.openFilterEnabled && !!menuSvc?.isHeaderFilterButtonEnabled(this.column), enableFilterIcon: !!colFilter && (!this.openFilterEnabled || _isLegacyMenuEnabled(this.gos)), showColumnMenu: (buttonElement, onClosedCallback) => { menuSvc?.showColumnMenu({ column: this.column, buttonElement, positionBy: "button", onClosedCallback }); }, showColumnMenuAfterMouseClick: (mouseEvent, onClosedCallback) => { menuSvc?.showColumnMenu({ column: this.column, mouseEvent, positionBy: "mouse", onClosedCallback }); }, showFilter: (buttonElement) => { menuSvc?.showFilterMenu({ column: this.column, buttonElement, containerType: "columnFilter", positionBy: "button" }); }, progressSort: (multiSort) => { sortSvc?.progressSort(this.column, !!multiSort, "uiColumnSorted"); }, setSort: (sort, multiSort) => { sortSvc?.setSortForColumn(this.column, sort, !!multiSort, "uiColumnSorted"); }, eGridHeader: this.eGui, setTooltip: (value, shouldDisplayTooltip) => { gos.assertModuleRegistered("Tooltip", 3); this.setupTooltip(value, shouldDisplayTooltip); } }); return params; } setupSelectAll(compBean) { const { selectionSvc } = this.beans; if (!selectionSvc) { return; } this.selectAllFeature = compBean.createManagedBean(selectionSvc.createSelectAllFeature(this.column)); this.selectAllFeature.setComp(this); } getSelectAllGui() { return this.selectAllFeature?.getCheckboxGui(); } handleKeyDown(e) { super.handleKeyDown(e); if (e.key === KeyCode.SPACE) { this.selectAllFeature?.onSpaceKeyDown(e); } if (e.key === KeyCode.ENTER) { this.onEnterKeyDown(e); } if (e.key === KeyCode.DOWN && e.altKey) { this.showMenuOnKeyPress(e, false); } } onEnterKeyDown(e) { if (e.ctrlKey || e.metaKey) { this.showMenuOnKeyPress(e, true); } else if (this.sortable) { this.beans.sortSvc?.progressSort(this.column, e.shiftKey, "uiColumnSorted"); } } showMenuOnKeyPress(e, isFilterShortcut) { const headerComp = this.comp.getUserCompInstance(); if (!isHeaderComp(headerComp)) { return; } if (headerComp.onMenuKeyboardShortcut(isFilterShortcut)) { e.preventDefault(); } } onFocusIn(e) { if (!this.eGui.contains(e.relatedTarget)) { this.focusThis(); this.announceAriaDescription(); } if (_isKeyboardMode()) { this.setActiveHeader(true); } } onFocusOut(e) { if (this.eGui.contains(e.relatedTarget)) { return; } this.setActiveHeader(false); } setupTooltip(value, shouldDisplayTooltip) { this.tooltipFeature = this.beans.tooltipSvc?.setupHeaderTooltip( this.tooltipFeature, this, value, shouldDisplayTooltip ); } setupStylesFromColDef() { this.setRefreshFunction("headerStyles", this.refreshHeaderStyles.bind(this)); this.refreshHeaderStyles(); } setupClassesFromColDef() { const refreshHeaderClasses = () => { const colDef = this.column.getColDef(); const classes = _getHeaderClassesFromColDef(colDef, this.gos, this.column, null); const oldClasses = this.userHeaderClasses; this.userHeaderClasses = new Set(classes); classes.forEach((c) => { if (oldClasses.has(c)) { oldClasses.delete(c); } else { this.comp.addOrRemoveCssClass(c, true); } }); oldClasses.forEach((c) => this.comp.addOrRemoveCssClass(c, false)); }; this.setRefreshFunction("headerClasses", refreshHeaderClasses); refreshHeaderClasses(); } setDragSource(eSource) { this.dragSourceElement = eSource; this.removeDragSource(); if (!eSource || !this.draggable) { return; } this.dragSource = this.beans.colMoves?.setDragSourceForHeader(eSource, this.column, this.displayName) ?? null; } updateState() { const { menuSvc } = this.beans; this.menuEnabled = !!menuSvc?.isColumnMenuInHeaderEnabled(this.column); this.openFilterEnabled = !!menuSvc?.isFilterMenuInHeaderEnabled(this.column); this.sortable = this.column.isSortable(); this.displayName = this.calculateDisplayName(); this.draggable = this.workOutDraggable(); } setRefreshFunction(name, func) { this.refreshFunctions[name] = func; } refresh() { this.updateState(); this.refreshHeaderComp(); this.refreshAria(); Object.values(this.refreshFunctions).forEach((f) => f()); } refreshHeaderComp() { const newCompDetails = this.lookupUserCompDetails(); if (!newCompDetails) { return; } const compInstance = this.comp.getUserCompInstance(); const attemptRefresh = compInstance != null && this.userCompDetails.componentClass == newCompDetails.componentClass; const headerCompRefreshed = attemptRefresh ? this.attemptHeaderCompRefresh(newCompDetails.params) : false; if (headerCompRefreshed) { this.setDragSource(this.dragSourceElement); } else { this.setCompDetails(newCompDetails); } } attemptHeaderCompRefresh(params) { const headerComp = this.comp.getUserCompInstance(); if (!headerComp) { return false; } if (!headerComp.refresh) { return false; } const res = headerComp.refresh(params); return res; } calculateDisplayName() { return this.beans.colNames.getDisplayNameForColumn(this.column, "header", true); } checkDisplayName() { if (this.displayName !== this.calculateDisplayName()) { this.refresh(); } } workOutDraggable() { const colDef = this.column.getColDef(); const isSuppressMovableColumns = this.gos.get("suppressMovableColumns"); const colCanMove = !isSuppressMovableColumns && !colDef.suppressMovable && !colDef.lockPosition; return !!colCanMove || !!colDef.enableRowGroup || !!colDef.enablePivot; } setupWidth(compBean) { const listener = () => { const columnWidth = this.column.getActualWidth(); this.comp.setWidth(`${columnWidth}px`); }; compBean.addManagedListeners(this.column, { widthChanged: listener }); listener(); } setupMovingCss(compBean) { const listener = () => { this.comp.addOrRemoveCssClass("ag-header-cell-moving", this.column.isMoving()); }; compBean.addManagedListeners(this.column, { movingChanged: listener }); listener(); } setupMenuClass(compBean) { const listener = () => { this.comp?.addOrRemoveCssClass("ag-column-menu-visible", this.column.isMenuVisible()); }; compBean.addManagedListeners(this.column, { menuVisibleChanged: listener }); listener(); } setupSortableClass(compBean) { const updateSortableCssClass = () => { this.comp.addOrRemoveCssClass("ag-header-cell-sortable", !!this.sortable); }; updateSortableCssClass(); this.setRefreshFunction("updateSortable", updateSortableCssClass); compBean.addManagedEventListeners({ sortChanged: this.refreshAriaSort.bind(this) }); } setupFilterClass(compBean) { const listener = () => { const isFilterActive = this.column.isFilterActive(); this.comp.addOrRemoveCssClass("ag-header-cell-filtered", isFilterActive); this.refreshAria(); }; compBean.addManagedListeners(this.column, { filterActiveChanged: listener }); listener(); } setupWrapTextClass() { const listener = () => { const wrapText = !!this.column.getColDef().wrapHeaderText; this.comp.addOrRemoveCssClass("ag-header-cell-wrap-text", wrapText); }; listener(); this.setRefreshFunction("wrapText", listener); } onHeaderHighlightChanged() { const highlighted = this.column.getHighlighted(); const beforeOn = highlighted === 0 /* Before */; const afterOn = highlighted === 1 /* After */; this.comp.addOrRemoveCssClass("ag-header-highlight-before", beforeOn); this.comp.addOrRemoveCssClass("ag-header-highlight-after", afterOn); } onDisplayedColumnsChanged() { super.onDisplayedColumnsChanged(); if (!this.isAlive()) { return; } this.onHeaderHeightChanged(); } onHeaderHeightChanged() { this.refreshSpanHeaderHeight(); } refreshSpanHeaderHeight() { const { eGui, column, comp, beans } = this; const groupHeaderHeight = getGroupRowsHeight(this.beans); const isZeroGroupHeight = groupHeaderHeight.reduce((total, next) => total += next, 0) === 0; comp.addOrRemoveCssClass("ag-header-parent-hidden", isZeroGroupHeight); if (!column.isSpanHeaderHeight()) { eGui.style.removeProperty("top"); eGui.style.removeProperty("height"); comp.addOrRemoveCssClass("ag-header-span-height", false); comp.addOrRemoveCssClass("ag-header-span-total", false); return; } const { numberOfParents, isSpanningTotal } = this.column.getColumnGroupPaddingInfo(); comp.addOrRemoveCssClass("ag-header-span-height", numberOfParents > 0); const headerHeight = getColumnHeaderRowHeight(beans); if (numberOfParents === 0) { comp.addOrRemoveCssClass("ag-header-span-total", false); eGui.style.setProperty("top", `0px`); eGui.style.setProperty("height", `${headerHeight}px`); return; } comp.addOrRemoveCssClass("ag-header-span-total", isSpanningTotal); let extraHeight = 0; for (let i = 0; i < numberOfParents; i++) { extraHeight += groupHeaderHeight[groupHeaderHeight.length - 1 - i]; } eGui.style.setProperty("top", `${-extraHeight}px`); eGui.style.setProperty("height", `${headerHeight + extraHeight}px`); } refreshAriaSort() { if (this.sortable) { const translate = this.getLocaleTextFunc(); const sort = this.beans.sortSvc?.getDisplaySortForColumn(this.column) || null; this.comp.setAriaSort(_getAriaSortState(sort)); this.setAriaDescriptionProperty("sort", translate("ariaSortableColumn", "Press ENTER to sort")); } else { this.comp.setAriaSort(); this.setAriaDescriptionProperty("sort", null); } } refreshAriaMenu() { if (this.menuEnabled) { const translate = this.getLocaleTextFunc(); this.setAriaDescriptionProperty("menu", translate("ariaMenuColumn", "Press ALT DOWN to open column menu")); } else { this.setAriaDescriptionProperty("menu", null); } } refreshAriaFilterButton() { if (this.openFilterEnabled && !_isLegacyMenuEnabled(this.gos)) { const translate = this.getLocaleTextFunc(); this.setAriaDescriptionProperty( "filterButton", translate("ariaFilterColumn", "Press CTRL ENTER to open filter") ); } else { this.setAriaDescriptionProperty("filterButton", null); } } refreshAriaFiltered() { const translate = this.getLocaleTextFunc(); const isFilterActive = this.column.isFilterActive(); if (isFilterActive) { this.setAriaDescriptionProperty("filter", translate("ariaColumnFiltered", "Column Filtered")); } else { this.setAriaDescriptionProperty("filter", null); } } setAriaDescriptionProperty(property, value) { if (value != null) { this.ariaDescriptionProperties.set(property, value); } else { this.ariaDescriptionProperties.delete(property); } } announceAriaDescription() { if (!this.eGui.contains(_getActiveDomElement(this.beans))) { return; } const ariaDescription = Array.from(this.ariaDescriptionProperties.keys()).sort((a, b) => a === "filter" ? -1 : b.charCodeAt(0) - a.charCodeAt(0)).map((key) => this.ariaDescriptionProperties.get(key)).join(". "); this.beans.ariaAnnounce?.announceValue(ariaDescription, "columnHeader"); } refreshAria() { this.refreshAriaSort(); this.refreshAriaMenu(); this.refreshAriaFilterButton(); this.refreshAriaFiltered(); } addColumnHoverListener(compBean) { this.beans.colHover?.addHeaderColumnHoverListener(compBean, this.comp, this.column); } addActiveHeaderMouseListeners(compBean) { const listener = (e) => this.handleMouseOverChange(e.type === "mouseenter"); const clickListener = () => { this.setActiveHeader(true); this.dispatchColumnMouseEvent("columnHeaderClicked", this.column); }; const contextMenuListener = (event) => this.handleContextMenuMouseEvent(event, void 0, this.column); compBean.addManagedListeners(this.eGui, { mouseenter: listener, mouseleave: listener, click: clickListener, contextmenu: contextMenuListener }); } handleMouseOverChange(isMouseOver) { this.setActiveHeader(isMouseOver); this.eventSvc.dispatchEvent({ type: isMouseOver ? "columnHeaderMouseOver" : "columnHeaderMouseLeave", column: this.column }); } setActiveHeader(active) { this.comp.addOrRemoveCssClass("ag-header-active", active); } getAnchorElementForMenu(isFilter) { const headerComp = this.comp.getUserCompInstance(); if (isHeaderComp(headerComp)) { return headerComp.getAnchorElementForMenu(isFilter); } return this.eGui; } destroy() { this.tooltipFeature = this.destroyBean(this.tooltipFeature); super.destroy(); } }; function isHeaderComp(headerComp) { return typeof headerComp.getAnchorElementForMenu === "function" && typeof headerComp.onMenuKeyboardShortcut === "function"; } // packages/ag-grid-community/src/headerRendering/row/headerRowCtrl.ts var instanceIdSequence5 = 0; var HeaderRowCtrl = class extends BeanStub { constructor(rowIndex, pinned, type) { super(); this.rowIndex = rowIndex; this.pinned = pinned; this.type = type; this.instanceId = instanceIdSequence5++; const typeClass = type == "group" ? `ag-header-row-column-group` : type == "filter" ? `ag-header-row-column-filter` : `ag-header-row-column`; this.headerRowClass = `ag-header-row ${typeClass}`; } postConstruct() { this.isPrintLayout = _isDomLayout(this.gos, "print"); this.isEnsureDomOrder = this.gos.get("ensureDomOrder"); } /** Checks that every header cell that is currently visible has been rendered. * Can only be false under some circumstances when using React */ areCellsRendered() { if (!this.comp) { return false; } return this.getHeaderCellCtrls().every((ctrl) => ctrl.eGui != null); } /** * * @param comp Proxy to the actual component * @param initCompState Should the component be initialised with the current state of the controller. Default: true */ setComp(comp, compBean, initCompState = true) { this.comp = comp; compBean = setupCompBean(this, this.beans.context, compBean); if (initCompState) { this.onRowHeightChanged(); this.onVirtualColumnsChanged(); } this.setWidth(); this.addEventListeners(compBean); } getAriaRowIndex() { return this.rowIndex + 1; } addEventListeners(compBean) { const onHeightChanged = this.onRowHeightChanged.bind(this); const onDisplayedColumnsChanged = this.onDisplayedColumnsChanged.bind(this); compBean.addManagedEventListeners({ columnResized: this.setWidth.bind(this), displayedColumnsChanged: onDisplayedColumnsChanged, virtualColumnsChanged: (params) => this.onVirtualColumnsChanged(params.afterScroll), columnGroupHeaderHeightChanged: onHeightChanged, columnHeaderHeightChanged: onHeightChanged, gridStylesChanged: onHeightChanged, advancedFilterEnabledChanged: onHeightChanged }); compBean.addManagedPropertyListener("domLayout", onDisplayedColumnsChanged); compBean.addManagedPropertyListener("ensureDomOrder", (e) => this.isEnsureDomOrder = e.currentValue); compBean.addManagedPropertyListeners( [ "headerHeight", "pivotHeaderHeight", "groupHeaderHeight", "pivotGroupHeaderHeight", "floatingFiltersHeight" ], onHeightChanged ); } getHeaderCellCtrl(column) { if (!this.headerCellCtrls) { return; } for (const cellCtrl of this.headerCellCtrls.values()) { if (cellCtrl.column === column) { return cellCtrl; } } return void 0; } onDisplayedColumnsChanged() { this.isPrintLayout = _isDomLayout(this.gos, "print"); this.onVirtualColumnsChanged(); this.setWidth(); this.onRowHeightChanged(); } setWidth() { const width = this.getWidthForRow(); this.comp.setWidth(`${width}px`); } getWidthForRow() { const { visibleCols } = this.beans; if (this.isPrintLayout) { const pinned = this.pinned != null; if (pinned) { return 0; } return visibleCols.getContainerWidth("right") + visibleCols.getContainerWidth("left") + visibleCols.getContainerWidth(null); } return visibleCols.getContainerWidth(this.pinned); } onRowHeightChanged() { const { topOffset, rowHeight } = this.getTopAndHeight(); this.comp.setTop(topOffset + "px"); this.comp.setHeight(rowHeight + "px"); } getTopAndHeight() { const { filterManager } = this.beans; const sizes = []; const groupHeadersHeight = getGroupRowsHeight(this.beans); const headerHeight = getColumnHeaderRowHeight(this.beans); sizes.push(...groupHeadersHeight); sizes.push(headerHeight); if (filterManager?.hasFloatingFilters()) { sizes.push(getFloatingFiltersHeight(this.beans)); } let topOffset = 0; for (let i = 0; i < this.rowIndex; i++) { topOffset += sizes[i]; } const rowHeight = sizes[this.rowIndex]; return { topOffset, rowHeight }; } onVirtualColumnsChanged(afterScroll = false) { const ctrlsToDisplay = this.getHeaderCtrls(); const forceOrder = this.isEnsureDomOrder || this.isPrintLayout; this.comp.setHeaderCtrls(ctrlsToDisplay, forceOrder, afterScroll); } getHeaderCtrls() { const oldCtrls = this.headerCellCtrls; this.headerCellCtrls = /* @__PURE__ */ new Map(); const columns = this.getColumnsInViewport(); for (const child of columns) { this.recycleAndCreateHeaderCtrls(child, oldCtrls); } const isFocusedAndDisplayed = (ctrl) => { const { focusSvc, visibleCols } = this.beans; const isFocused = focusSvc.isHeaderWrapperFocused(ctrl); if (!isFocused) { return false; } const isDisplayed = visibleCols.isVisible(ctrl.column); return isDisplayed; }; if (oldCtrls) { for (const [id, oldCtrl] of oldCtrls) { const keepCtrl = isFocusedAndDisplayed(oldCtrl); if (keepCtrl) { this.headerCellCtrls.set(id, oldCtrl); } else { this.destroyBean(oldCtrl); } } } return this.getHeaderCellCtrls(); } getHeaderCellCtrls() { return Array.from(this.headerCellCtrls?.values() ?? []); } recycleAndCreateHeaderCtrls(headerColumn, oldCtrls) { if (!this.headerCellCtrls) { return; } if (headerColumn.isEmptyGroup()) { return; } const idOfChild = headerColumn.getUniqueId(); let headerCtrl; if (oldCtrls) { headerCtrl = oldCtrls.get(idOfChild); oldCtrls.delete(idOfChild); } const forOldColumn = headerCtrl && headerCtrl.column != headerColumn; if (forOldColumn) { this.destroyBean(headerCtrl); headerCtrl = void 0; } if (headerCtrl == null) { switch (this.type) { case "filter": { headerCtrl = this.createBean( this.beans.registry.createDynamicBean( "headerFilterCellCtrl", true, headerColumn, this ) ); break; } case "group": headerCtrl = this.createBean( this.beans.registry.createDynamicBean( "headerGroupCellCtrl", true, headerColumn, this ) ); break; default: headerCtrl = this.createBean(new HeaderCellCtrl(headerColumn, this)); break; } } this.headerCellCtrls.set(idOfChild, headerCtrl); } getColumnsInViewport() { return this.isPrintLayout ? this.getColumnsInViewportPrintLayout() : this.getColumnsInViewportNormalLayout(); } getColumnsInViewportPrintLayout() { if (this.pinned != null) { return []; } let viewportColumns = []; const actualDepth = this.getActualDepth(); const { colViewport } = this.beans; ["left", null, "right"].forEach((pinned) => { const items = colViewport.getHeadersToRender(pinned, actualDepth); viewportColumns = viewportColumns.concat(items); }); return viewportColumns; } getActualDepth() { return this.type == "filter" ? this.rowIndex - 1 : this.rowIndex; } getColumnsInViewportNormalLayout() { return this.beans.colViewport.getHeadersToRender(this.pinned, this.getActualDepth()); } findHeaderCellCtrl(column) { if (!this.headerCellCtrls) { return; } const allCtrls = this.getHeaderCellCtrls(); let ctrl; if (typeof column === "function") { ctrl = allCtrls.find(column); } else { ctrl = allCtrls.find((ctrl2) => ctrl2.column == column); } return ctrl; } focusHeader(column, event) { const ctrl = this.findHeaderCellCtrl(column); if (!ctrl) { return false; } const focused = ctrl.focus(event); return focused; } destroy() { this.headerCellCtrls?.forEach((ctrl) => { this.destroyBean(ctrl); }); this.headerCellCtrls = void 0; super.destroy(); } }; // packages/ag-grid-community/src/headerRendering/rowContainer/headerRowContainerCtrl.ts var HeaderRowContainerCtrl = class extends BeanStub { constructor(pinned) { super(); this.pinned = pinned; this.hidden = false; this.includeFloatingFilter = false; this.groupsRowCtrls = []; } setComp(comp, eGui) { this.comp = comp; this.eViewport = eGui; const { pinnedCols, ctrlsSvc, colModel, colMoves, filterManager } = this.beans; this.setupCenterWidth(); pinnedCols?.setupHeaderPinnedWidth(this); this.setupDragAndDrop(colMoves, this.eViewport); const onDisplayedColsChanged = this.onDisplayedColumnsChanged.bind(this, filterManager); this.addManagedEventListeners({ gridColumnsChanged: this.onGridColumnsChanged.bind(this), displayedColumnsChanged: onDisplayedColsChanged, advancedFilterEnabledChanged: onDisplayedColsChanged }); const headerType = `${typeof this.pinned === "string" ? this.pinned : "center"}Header`; ctrlsSvc.register(headerType, this); if (colModel.ready) { this.refresh(); } } getAllCtrls() { const res = [...this.groupsRowCtrls]; if (this.columnsRowCtrl) { res.push(this.columnsRowCtrl); } if (this.filtersRowCtrl) { res.push(this.filtersRowCtrl); } return res; } refresh(keepColumns = false) { const { focusSvc, colModel, filterManager } = this.beans; let sequence = 0; const focusedHeaderPosition = focusSvc.getFocusHeaderToUseAfterRefresh(); const refreshColumnGroups = () => { const groupRowCount = getHeaderRowCount(colModel) - 1; this.groupsRowCtrls = this.destroyBeans(this.groupsRowCtrls); for (let i = 0; i < groupRowCount; i++) { const ctrl = this.createBean(new HeaderRowCtrl(sequence++, this.pinned, "group")); this.groupsRowCtrls.push(ctrl); } }; const refreshColumns = () => { const rowIndex = sequence++; const needNewInstance = !this.hidden && (this.columnsRowCtrl == null || !keepColumns || this.columnsRowCtrl.rowIndex !== rowIndex); const shouldDestroyInstance = needNewInstance || this.hidden; if (shouldDestroyInstance) { this.columnsRowCtrl = this.destroyBean(this.columnsRowCtrl); } if (needNewInstance) { this.columnsRowCtrl = this.createBean(new HeaderRowCtrl(rowIndex, this.pinned, "column")); } }; const refreshFilters = () => { this.includeFloatingFilter = !!filterManager?.hasFloatingFilters() && !this.hidden; const destroyPreviousComp = () => { this.filtersRowCtrl = this.destroyBean(this.filtersRowCtrl); }; if (!this.includeFloatingFilter) { destroyPreviousComp(); return; } const rowIndex = sequence++; if (this.filtersRowCtrl) { const rowIndexMismatch = this.filtersRowCtrl.rowIndex !== rowIndex; if (!keepColumns || rowIndexMismatch) { destroyPreviousComp(); } } if (!this.filtersRowCtrl) { this.filtersRowCtrl = this.createBean(new HeaderRowCtrl(rowIndex, this.pinned, "filter")); } }; refreshColumnGroups(); refreshColumns(); refreshFilters(); const allCtrls = this.getAllCtrls(); this.comp.setCtrls(allCtrls); this.restoreFocusOnHeader(focusSvc, focusedHeaderPosition); } getHeaderCtrlForColumn(column) { if (isColumn(column)) { return this.columnsRowCtrl?.getHeaderCellCtrl(column); } if (this.groupsRowCtrls.length === 0) { return; } for (let i = 0; i < this.groupsRowCtrls.length; i++) { const ctrl = this.groupsRowCtrls[i].getHeaderCellCtrl(column); if (ctrl) { return ctrl; } } } getHtmlElementForColumnHeader(column) { return this.getHeaderCtrlForColumn(column)?.eGui ?? null; } getRowType(rowIndex) { return this.getAllCtrls()[rowIndex]?.type; } focusHeader(rowIndex, column, event) { const allCtrls = this.getAllCtrls(); const ctrl = allCtrls[rowIndex]; if (!ctrl) { return false; } return ctrl.focusHeader(column, event); } getGroupRowCount() { return this.groupsRowCtrls.length; } getGroupRowCtrlAtIndex(index) { return this.groupsRowCtrls[index]; } getRowCount() { return this.groupsRowCtrls.length + (this.columnsRowCtrl ? 1 : 0) + (this.filtersRowCtrl ? 1 : 0); } setHorizontalScroll(offset) { this.comp.setViewportScrollLeft(offset); } onScrollCallback(fn) { this.addManagedElementListeners(this.eViewport, { scroll: fn }); } destroy() { this.filtersRowCtrl = this.destroyBean(this.filtersRowCtrl); this.columnsRowCtrl = this.destroyBean(this.columnsRowCtrl); this.groupsRowCtrls = this.destroyBeans(this.groupsRowCtrls); super.destroy(); } setupDragAndDrop(colMoves, dropContainer) { const bodyDropTarget = colMoves?.createBodyDropTarget(this.pinned, dropContainer); if (bodyDropTarget) { this.createManagedBean(bodyDropTarget); } } restoreFocusOnHeader(focusSvc, position) { if (!position) { return; } const { column } = position; if (column.getPinned() != this.pinned) { return; } focusSvc.focusHeaderPosition({ headerPosition: position }); } // grid cols have changed - this also means the number of rows in the header can have // changed. so we remove all the old rows and insert new ones for a complete refresh onGridColumnsChanged() { this.refresh(true); } onDisplayedColumnsChanged(filterManager) { const includeFloatingFilter = !!filterManager?.hasFloatingFilters() && !this.hidden; if (this.includeFloatingFilter !== includeFloatingFilter) { this.refresh(true); } } setupCenterWidth() { if (this.pinned != null) { return; } this.createManagedBean(new CenterWidthFeature((width) => this.comp.setCenterWidth(`${width}px`), true)); } }; // packages/ag-grid-community/src/misc/menu/menuService.ts var MenuService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "menuSvc"; } postConstruct() { const { enterpriseMenuFactory, filterMenuFactory } = this.beans; this.activeMenuFactory = enterpriseMenuFactory ?? filterMenuFactory; } showColumnMenu(params) { this.showColumnMenuCommon(this.activeMenuFactory, params, "columnMenu"); } showFilterMenu(params) { const { enterpriseMenuFactory, filterMenuFactory } = this.beans; const menuFactory = enterpriseMenuFactory && _isLegacyMenuEnabled(this.gos) ? enterpriseMenuFactory : filterMenuFactory; this.showColumnMenuCommon(menuFactory, params, params.containerType, true); } showHeaderContextMenu(column, mouseEvent, touchEvent) { this.activeMenuFactory?.showMenuAfterContextMenuEvent(column, mouseEvent, touchEvent); } hidePopupMenu() { this.beans.contextMenuSvc?.hideActiveMenu(); this.activeMenuFactory?.hideActiveMenu(); } isColumnMenuInHeaderEnabled(column) { const { suppressHeaderMenuButton } = column.getColDef(); return !suppressHeaderMenuButton && !!this.activeMenuFactory?.isMenuEnabled(column) && (_isLegacyMenuEnabled(this.gos) || !!this.beans.enterpriseMenuFactory); } isFilterMenuInHeaderEnabled(column) { return !column.getColDef().suppressHeaderFilterButton && !!this.beans.filterManager?.isFilterAllowed(column); } isHeaderContextMenuEnabled(column) { const colDef = column && isColumn(column) ? column.getColDef() : column?.getColGroupDef(); return !colDef?.suppressHeaderContextMenu && this.gos.get("columnMenu") === "new"; } isHeaderMenuButtonAlwaysShowEnabled() { return this.isSuppressMenuHide(); } isHeaderMenuButtonEnabled() { const menuHides = !this.isSuppressMenuHide(); const onIpadAndMenuHides = _isIOSUserAgent() && menuHides; return !onIpadAndMenuHides; } isHeaderFilterButtonEnabled(column) { return this.isFilterMenuInHeaderEnabled(column) && !_isLegacyMenuEnabled(this.gos) && !this.isFloatingFilterButtonDisplayed(column); } isFilterMenuItemEnabled(column) { return !!this.beans.filterManager?.isFilterAllowed(column) && !_isLegacyMenuEnabled(this.gos) && !this.isFilterMenuInHeaderEnabled(column) && !this.isFloatingFilterButtonDisplayed(column); } isFloatingFilterButtonEnabled(column) { return !column.getColDef().suppressFloatingFilterButton; } isFloatingFilterButtonDisplayed(column) { return !!column.getColDef().floatingFilter && this.isFloatingFilterButtonEnabled(column); } isSuppressMenuHide() { const gos = this.gos; const suppressMenuHide = gos.get("suppressMenuHide"); if (_isLegacyMenuEnabled(gos)) { return gos.exists("suppressMenuHide") ? suppressMenuHide : false; } return suppressMenuHide; } showColumnMenuCommon(menuFactory, params, containerType, filtersOnly) { const { positionBy, onClosedCallback } = params; const column = params.column; if (positionBy === "button") { const { buttonElement } = params; menuFactory?.showMenuAfterButtonClick(column, buttonElement, containerType, onClosedCallback, filtersOnly); } else if (positionBy === "mouse") { const { mouseEvent } = params; menuFactory?.showMenuAfterMouseEvent(column, mouseEvent, containerType, onClosedCallback, filtersOnly); } else if (column) { const beans = this.beans; const ctrlsSvc = beans.ctrlsSvc; ctrlsSvc.getScrollFeature().ensureColumnVisible(column, "auto"); _requestAnimationFrame(beans, () => { const headerCellCtrl = ctrlsSvc.getHeaderRowContainerCtrl(column.getPinned())?.getHeaderCtrlForColumn(column); if (headerCellCtrl) { menuFactory?.showMenuAfterButtonClick( column, headerCellCtrl.getAnchorElementForMenu(filtersOnly), containerType, onClosedCallback, true ); } }); } } }; function _setColMenuVisible(column, visible, source) { if (column.menuVisible !== visible) { column.menuVisible = visible; column.dispatchColEvent("menuVisibleChanged", source); } } // packages/ag-grid-community/src/rendering/overlays/overlayComponent.ts var OverlayComponent = class extends Component { constructor() { super(); } }; // packages/ag-grid-community/src/rendering/overlays/loadingOverlayComponent.ts var LoadingOverlayComponent2 = class extends OverlayComponent { init() { const customTemplate = _makeNull(this.gos.get("overlayLoadingTemplate")?.trim()); this.setTemplate( customTemplate ?? /* html */ `` ); if (!customTemplate) { const localeTextFunc = this.getLocaleTextFunc(); setTimeout(() => { this.getGui().textContent = localeTextFunc("loadingOoo", "Loading..."); }); } } }; // packages/ag-grid-community/src/rendering/overlays/noRowsOverlayComponent.ts var NoRowsOverlayComponent2 = class extends OverlayComponent { init() { const customTemplate = _makeNull(this.gos.get("overlayNoRowsTemplate")?.trim()); this.setTemplate(customTemplate ?? /* html */ ``); if (!customTemplate) { const localeTextFunc = this.getLocaleTextFunc(); setTimeout(() => { this.getGui().textContent = localeTextFunc("noRowsToShow", "No Rows To Show"); }); } } }; // packages/ag-grid-community/src/utils/icon.ts function _createIcon(iconName, beans, column) { const iconContents = _createIconNoSpan(iconName, beans, column); if (iconContents) { const { className } = iconContents; if (typeof className === "string" && className.indexOf("ag-icon") > -1 || typeof className === "object" && className["ag-icon"]) { return iconContents; } } const eResult = document.createElement("span"); eResult.appendChild(iconContents); return eResult; } function _createIconNoSpan(iconName, beans, column) { let userProvidedIcon = null; if (iconName === "smallDown") { _warn(262); } else if (iconName === "smallLeft") { _warn(263); } else if (iconName === "smallRight") { _warn(264); } const icons = column && column.getColDef().icons; if (icons) { userProvidedIcon = icons[iconName]; } if (beans.gos && !userProvidedIcon) { const optionsIcons = beans.gos.get("icons"); if (optionsIcons) { userProvidedIcon = optionsIcons[iconName]; } } if (userProvidedIcon) { let rendererResult; if (typeof userProvidedIcon === "function") { rendererResult = userProvidedIcon(); } else if (typeof userProvidedIcon === "string") { rendererResult = userProvidedIcon; } else { _warn(38, { iconName }); return void 0; } if (typeof rendererResult === "string") { return _loadTemplate(rendererResult); } if (_isNodeOrElement(rendererResult)) { return rendererResult; } _warn(133, { iconName }); return void 0; } else { const span = document.createElement("span"); const iconValue = beans.registry.getIcon(iconName); if (!iconValue) { beans.validation?.validateIcon(iconName); } const cssClass = iconValue ?? iconName; span.setAttribute("class", `ag-icon ag-icon-${cssClass}`); span.setAttribute("unselectable", "on"); _setAriaRole(span, "presentation"); return span; } } // packages/ag-grid-community/src/dragAndDrop/dragAndDropImageComponent.css-GENERATED.ts var dragAndDropImageComponentCSS = ( /*css*/ `.ag-dnd-ghost{align-items:center;background-color:var(--ag-drag-and-drop-image-background-color);border:var(--ag-drag-and-drop-image-border);border-radius:var(--ag-border-radius);box-shadow:var(--ag-drag-and-drop-image-shadow);color:var(--ag-text-color);cursor:move;display:flex;font-weight:500;gap:var(--ag-cell-widget-spacing);height:var(--ag-header-height);overflow:hidden;padding-left:var(--ag-cell-horizontal-padding);padding-right:var(--ag-cell-horizontal-padding);text-overflow:ellipsis;transform:translateY(calc(var(--ag-spacing)*2));white-space:nowrap}` ); // packages/ag-grid-community/src/dragAndDrop/dragAndDropImageComponent.ts var DragAndDropImageComponent2 = class extends Component { constructor() { super(); this.dragSource = null; this.eIcon = RefPlaceholder; this.eLabel = RefPlaceholder; this.registerCSS(dragAndDropImageComponentCSS); } postConstruct() { const create = (iconName) => _createIcon(iconName, this.beans, null); this.dropIconMap = { pinned: create("columnMovePin"), hide: create("columnMoveHide"), move: create("columnMoveMove"), left: create("columnMoveLeft"), right: create("columnMoveRight"), group: create("columnMoveGroup"), aggregate: create("columnMoveValue"), pivot: create("columnMovePivot"), notAllowed: create("dropNotAllowed") }; } init(params) { this.dragSource = params.dragSource; this.setTemplate( /* html */ `
` ); } destroy() { this.dragSource = null; super.destroy(); } setIcon(iconName, shake) { const { eIcon, dragSource, dropIconMap, gos } = this; _clearElement(eIcon); let eIconChild = null; if (!iconName) { iconName = dragSource?.getDefaultIconName ? dragSource.getDefaultIconName() : "notAllowed"; } eIconChild = dropIconMap[iconName]; eIcon.classList.toggle("ag-shake-left-to-right", shake); if (eIconChild === dropIconMap["hide"] && gos.get("suppressDragLeaveHidesColumns")) { return; } if (eIconChild) { eIcon.appendChild(eIconChild); } } setLabel(label) { this.eLabel.textContent = label; } }; // packages/ag-grid-community/src/widgets/agAbstractLabel.css-GENERATED.ts var agAbstractLabelCSS = ( /*css*/ `.ag-label{white-space:nowrap}:where(.ag-ltr) .ag-label{margin-right:var(--ag-spacing)}:where(.ag-rtl) .ag-label{margin-left:var(--ag-spacing)}:where(.ag-label-align-right) .ag-label{order:1}:where(.ag-ltr) :where(.ag-label-align-right) .ag-label{margin-left:var(--ag-spacing)}:where(.ag-rtl) :where(.ag-label-align-right) .ag-label{margin-right:var(--ag-spacing)}.ag-label-align-right>*{flex:none}.ag-label-align-top{align-items:flex-start;flex-direction:column;>*{align-self:stretch}}.ag-label-ellipsis{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:where(.ag-label-align-top) .ag-label{margin-bottom:calc(var(--ag-spacing)*.5)}` ); // packages/ag-grid-community/src/widgets/agAbstractLabel.ts var AgAbstractLabel = class extends Component { constructor(config, template, components) { super(template, components); this.labelSeparator = ""; this.labelAlignment = "left"; this.disabled = false; this.label = ""; this.config = config || {}; this.registerCSS(agAbstractLabelCSS); } postConstruct() { this.addCssClass("ag-labeled"); this.eLabel.classList.add("ag-label"); const { labelSeparator, label, labelWidth, labelAlignment, disabled } = this.config; if (disabled != null) { this.setDisabled(disabled); } if (labelSeparator != null) { this.setLabelSeparator(labelSeparator); } if (label != null) { this.setLabel(label); } if (labelWidth != null) { this.setLabelWidth(labelWidth); } this.setLabelAlignment(labelAlignment || this.labelAlignment); this.refreshLabel(); } refreshLabel() { const { label, eLabel } = this; _clearElement(eLabel); if (typeof label === "string") { eLabel.innerText = label + this.labelSeparator; } else if (label) { eLabel.appendChild(label); } if (label === "") { _setDisplayed(eLabel, false); _setAriaRole(eLabel, "presentation"); } else { _setDisplayed(eLabel, true); _setAriaRole(eLabel, null); } } setLabelSeparator(labelSeparator) { if (this.labelSeparator === labelSeparator) { return this; } this.labelSeparator = labelSeparator; if (this.label != null) { this.refreshLabel(); } return this; } getLabelId() { const eLabel = this.eLabel; eLabel.id = eLabel.id || `ag-${this.getCompId()}-label`; return eLabel.id; } getLabel() { return this.label; } setLabel(label) { if (this.label === label) { return this; } this.label = label; this.refreshLabel(); return this; } setLabelAlignment(alignment) { const eGui = this.getGui(); const eGuiClassList = eGui.classList; eGuiClassList.toggle("ag-label-align-left", alignment === "left"); eGuiClassList.toggle("ag-label-align-right", alignment === "right"); eGuiClassList.toggle("ag-label-align-top", alignment === "top"); return this; } setLabelEllipsis(hasEllipsis) { this.eLabel.classList.toggle("ag-label-ellipsis", hasEllipsis); return this; } setLabelWidth(width) { if (this.label == null) { return this; } _setElementWidth(this.eLabel, width); return this; } setDisabled(disabled) { disabled = !!disabled; const element = this.getGui(); _setDisabled(element, disabled); element.classList.toggle("ag-disabled", disabled); this.disabled = disabled; return this; } isDisabled() { return !!this.disabled; } }; // packages/ag-grid-community/src/widgets/agAbstractField.ts var AgAbstractField = class extends AgAbstractLabel { constructor(config, template, components, className) { super(config, template, components); this.className = className; } postConstruct() { super.postConstruct(); const { width, value, onValueChange } = this.config; if (width != null) { this.setWidth(width); } if (value != null) { this.setValue(value); } if (onValueChange != null) { this.onValueChange(onValueChange); } if (this.className) { this.addCssClass(this.className); } this.refreshAriaLabelledBy(); } setLabel(label) { super.setLabel(label); this.refreshAriaLabelledBy(); return this; } refreshAriaLabelledBy() { const ariaEl = this.getAriaElement(); const labelId = this.getLabelId(); const label = this.getLabel(); if (label == null || label == "" || _getAriaLabel(ariaEl) !== null) { _setAriaLabelledBy(ariaEl, ""); } else { _setAriaLabelledBy(ariaEl, labelId ?? ""); } } setAriaLabel(label) { _setAriaLabel(this.getAriaElement(), label); this.refreshAriaLabelledBy(); return this; } onValueChange(callbackFn) { this.addManagedListeners(this, { fieldValueChanged: () => callbackFn(this.getValue()) }); return this; } getWidth() { return this.getGui().clientWidth; } setWidth(width) { _setFixedWidth(this.getGui(), width); return this; } getPreviousValue() { return this.previousValue; } getValue() { return this.value; } setValue(value, silent) { if (this.value === value) { return this; } this.previousValue = this.value; this.value = value; if (!silent) { this.dispatchLocalEvent({ type: "fieldValueChanged" }); } return this; } }; // packages/ag-grid-community/src/widgets/agAbstractInputField.ts var AgAbstractInputField = class extends AgAbstractField { constructor(config, className, inputType = "text", displayFieldTag = "input") { super( config, config?.template ?? /* html */ `
`, [], className ); this.inputType = inputType; this.displayFieldTag = displayFieldTag; this.eLabel = RefPlaceholder; this.eWrapper = RefPlaceholder; this.eInput = RefPlaceholder; } postConstruct() { super.postConstruct(); this.setInputType(); const { eLabel, eWrapper, eInput, className } = this; eLabel.classList.add(`${className}-label`); eWrapper.classList.add(`${className}-input-wrapper`); eInput.classList.add(`${className}-input`); this.addCssClass("ag-input-field"); eInput.id = eInput.id || `ag-${this.getCompId()}-input`; const { inputName, inputWidth } = this.config; if (inputName != null) { this.setInputName(inputName); } if (inputWidth != null) { this.setInputWidth(inputWidth); } this.addInputListeners(); this.activateTabIndex([eInput]); } addInputListeners() { this.addManagedElementListeners(this.eInput, { input: (e) => this.setValue(e.target.value) }); } setInputType() { if (this.displayFieldTag === "input") { this.eInput.setAttribute("type", this.inputType); } } getInputElement() { return this.eInput; } setInputWidth(width) { _setElementWidth(this.eWrapper, width); return this; } setInputName(name) { this.getInputElement().setAttribute("name", name); return this; } getFocusableElement() { return this.eInput; } setMaxLength(length) { const eInput = this.eInput; eInput.maxLength = length; return this; } setInputPlaceholder(placeholder) { _addOrRemoveAttribute(this.eInput, "placeholder", placeholder); return this; } setInputAriaLabel(label) { _setAriaLabel(this.eInput, label); this.refreshAriaLabelledBy(); return this; } setDisabled(disabled) { _setDisabled(this.eInput, disabled); return super.setDisabled(disabled); } setAutoComplete(value) { if (value === true) { _addOrRemoveAttribute(this.eInput, "autocomplete", null); } else { const autoCompleteValue = typeof value === "string" ? value : "off"; _addOrRemoveAttribute(this.eInput, "autocomplete", autoCompleteValue); } return this; } }; // packages/ag-grid-community/src/widgets/agCheckbox.ts var AgCheckbox = class extends AgAbstractInputField { constructor(config, className = "ag-checkbox", inputType = "checkbox") { super(config, className, inputType); this.labelAlignment = "right"; this.selected = false; this.readOnly = false; this.passive = false; } postConstruct() { super.postConstruct(); const { readOnly, passive } = this.config; if (typeof readOnly === "boolean") this.setReadOnly(readOnly); if (typeof passive === "boolean") this.setPassive(passive); } addInputListeners() { this.addManagedElementListeners(this.eInput, { click: this.onCheckboxClick.bind(this) }); this.addManagedElementListeners(this.eLabel, { click: this.toggle.bind(this) }); } getNextValue() { return this.selected === void 0 ? true : !this.selected; } setPassive(passive) { this.passive = passive; } isReadOnly() { return this.readOnly; } setReadOnly(readOnly) { this.eWrapper.classList.toggle("ag-disabled", readOnly); this.eInput.disabled = readOnly; this.readOnly = readOnly; } setDisabled(disabled) { this.eWrapper.classList.toggle("ag-disabled", disabled); return super.setDisabled(disabled); } toggle() { if (this.eInput.disabled) { return; } const previousValue = this.isSelected(); const nextValue = this.getNextValue(); if (this.passive) { this.dispatchChange(nextValue, previousValue); } else { this.setValue(nextValue); } } getValue() { return this.isSelected(); } setValue(value, silent) { this.refreshSelectedClass(value); this.setSelected(value, silent); return this; } setName(name) { const input = this.getInputElement(); input.name = name; return this; } isSelected() { return this.selected; } setSelected(selected, silent) { if (this.isSelected() === selected) { return; } this.previousValue = this.isSelected(); selected = this.selected = typeof selected === "boolean" ? selected : void 0; const eInput = this.eInput; eInput.checked = selected; eInput.indeterminate = selected === void 0; if (!silent) { this.dispatchChange(this.selected, this.previousValue); } } dispatchChange(selected, previousValue, event) { this.dispatchLocalEvent({ type: "fieldValueChanged", selected, previousValue, event }); const input = this.getInputElement(); this.eventSvc.dispatchEvent({ type: "checkboxChanged", id: input.id, name: input.name, selected, previousValue }); } onCheckboxClick(e) { if (this.passive || this.eInput.disabled) { return; } const previousValue = this.isSelected(); const selected = this.selected = e.target.checked; this.refreshSelectedClass(selected); this.dispatchChange(selected, previousValue, e); } refreshSelectedClass(value) { const classList = this.eWrapper.classList; classList.toggle("ag-checked", value === true); classList.toggle("ag-indeterminate", value == null); } }; var AgCheckboxSelector = { selector: "AG-CHECKBOX", component: AgCheckbox }; // packages/ag-grid-community/src/rendering/cellRenderers/checkboxCellRenderer.css-GENERATED.ts var checkboxCellRendererCSS = ( /*css*/ `.ag-checkbox-cell{height:100%}` ); // packages/ag-grid-community/src/rendering/cellRenderers/checkboxCellRenderer.ts var CheckboxCellRenderer = class extends Component { constructor() { super( /* html*/ ` `, [AgCheckboxSelector] ); this.eCheckbox = RefPlaceholder; this.registerCSS(checkboxCellRendererCSS); } init(params) { this.refresh(params); const { eCheckbox, beans } = this; const inputEl = eCheckbox.getInputElement(); inputEl.setAttribute("tabindex", "-1"); _setAriaLive(inputEl, "polite"); this.addManagedListeners(inputEl, { click: (event) => { _stopPropagationForAgGrid(event); if (eCheckbox.isDisabled()) { return; } const isSelected = eCheckbox.getValue(); this.onCheckboxChanged(isSelected); }, dblclick: (event) => { _stopPropagationForAgGrid(event); } }); this.addManagedElementListeners(params.eGridCell, { keydown: (event) => { if (event.key === KeyCode.SPACE && !eCheckbox.isDisabled()) { if (params.eGridCell === _getActiveDomElement(beans)) { eCheckbox.toggle(); } const isSelected = eCheckbox.getValue(); this.onCheckboxChanged(isSelected); event.preventDefault(); } } }); } refresh(params) { this.params = params; this.updateCheckbox(params); return true; } updateCheckbox(params) { let isSelected; let displayed = true; const { value, column, node } = params; if (node.group && column) { if (typeof value === "boolean") { isSelected = value; } else { const colId = column.getColId(); if (colId.startsWith(GROUP_AUTO_COLUMN_ID)) { isSelected = value == null || value === "" ? void 0 : value === "true"; } else if (node.aggData && node.aggData[colId] !== void 0) { isSelected = value ?? void 0; } else { displayed = false; } } } else { isSelected = value ?? void 0; } const { eCheckbox } = this; if (!displayed) { eCheckbox.setDisplayed(false); return; } eCheckbox.setValue(isSelected); const disabled = params.disabled ?? !column?.isCellEditable(node); eCheckbox.setDisabled(disabled); const translate = this.getLocaleTextFunc(); const stateName = _getAriaCheckboxStateName(translate, isSelected); const ariaLabel = disabled ? stateName : `${translate("ariaToggleCellValue", "Press SPACE to toggle cell value")} (${stateName})`; eCheckbox.setInputAriaLabel(ariaLabel); } onCheckboxChanged(isSelected) { const { eventSvc, params } = this; const { column, node, value } = params; const sharedEventParams = { column, colDef: column.getColDef(), data: node.data, node, rowIndex: node.rowIndex, rowPinned: node.rowPinned, value }; eventSvc.dispatchEvent({ type: "cellEditingStarted", ...sharedEventParams }); const valueChanged = node.setDataValue(column, isSelected, "edit"); eventSvc.dispatchEvent({ type: "cellEditingStopped", ...sharedEventParams, oldValue: value, newValue: isSelected, valueChanged }); if (!valueChanged) { this.updateCheckbox(params); } } }; // packages/ag-grid-community/src/clientSideRowModel/abstractClientSideNodeManager.ts var ROOT_NODE_ID = "ROOT_NODE_ID"; var AbstractClientSideNodeManager = class extends BeanStub { constructor() { super(...arguments); this.nextId = 0; this.allNodesMap = {}; this.rootNode = null; } get treeData() { return false; } getRowNode(id) { return this.allNodesMap[id]; } extractRowData() { return this.rootNode?.allLeafChildren?.map((node) => node.data); } activate(rootNode) { this.rootNode = rootNode; rootNode.group = true; rootNode.level = -1; rootNode.id = ROOT_NODE_ID; rootNode.allLeafChildren = []; rootNode.childrenAfterGroup = []; rootNode.childrenAfterSort = []; rootNode.childrenAfterAggFilter = []; rootNode.childrenAfterFilter = []; this.updateRootSiblingArrays(rootNode); } deactivate() { if (this.rootNode) { this.allNodesMap = {}; this.rootNode = null; } } destroy() { super.destroy(); this.allNodesMap = {}; this.rootNode = null; } setNewRowData(rowData) { const rootNode = this.rootNode; if (!rootNode) { return; } this.dispatchRowDataUpdateStartedEvent(rowData); rootNode.childrenAfterFilter = null; rootNode.childrenAfterGroup = null; rootNode.childrenAfterAggFilter = null; rootNode.childrenAfterSort = null; rootNode.childrenMapped = null; rootNode.updateHasChildren(); this.allNodesMap = {}; this.nextId = 0; this.loadNewRowData(rowData); this.updateRootSiblingArrays(rootNode); } updateRootSiblingArrays(rootNode) { const sibling = rootNode.sibling; if (sibling) { sibling.childrenAfterFilter = rootNode.childrenAfterFilter; sibling.childrenAfterGroup = rootNode.childrenAfterGroup; sibling.childrenAfterAggFilter = rootNode.childrenAfterAggFilter; sibling.childrenAfterSort = rootNode.childrenAfterSort; sibling.childrenMapped = rootNode.childrenMapped; sibling.allLeafChildren = rootNode.allLeafChildren; } } loadNewRowData(rowData) { this.rootNode.allLeafChildren = rowData?.map((dataItem, index) => this.createRowNode(dataItem, index)) ?? []; } setImmutableRowData(params, rowData) { const getRowIdFunc = _getRowIdCallback(this.gos); const reorder = !this.gos.get("suppressMaintainUnsortedOrder"); const changedRowNodes = params.changedRowNodes; const processedNodes = /* @__PURE__ */ new Set(); const rootNode = this.rootNode; const oldAllLeafChildren = rootNode.allLeafChildren; const oldAllLeafChildrenLen = oldAllLeafChildren.length; let nodesAdded = false; let nodesRemoved = false; let nodesUpdated = false; let orderChanged = false; for (let i = 0, prevSourceRowIndex = -1, len = rowData.length; i < len; i++) { const data = rowData[i]; let node = this.getRowNode( getRowIdFunc({ data, level: 0 }) ); if (!node) { nodesAdded = true; node = this.createRowNode(data, -1); changedRowNodes.add(node); } else { if (reorder) { const sourceRowIndex = node.sourceRowIndex; orderChanged || (orderChanged = sourceRowIndex <= prevSourceRowIndex || // A node was moved up, so order changed nodesAdded); prevSourceRowIndex = sourceRowIndex; } if (node.data !== data) { nodesUpdated = true; node.updateData(data); changedRowNodes.update(node); } } processedNodes.add(node); } const nodesToUnselect = []; for (let i = 0; i < oldAllLeafChildrenLen; i++) { const node = oldAllLeafChildren[i]; if (!processedNodes.has(node)) { nodesRemoved = true; if (node.isSelected()) { nodesToUnselect.push(node); } this.rowNodeDeleted(node); changedRowNodes.remove(node); } } if (nodesAdded || nodesRemoved || orderChanged) { const newAllLeafChildren = new Array(processedNodes.size); let writeIdx = 0; if (!reorder) { for (let i = 0; i < oldAllLeafChildrenLen; ++i) { const node = oldAllLeafChildren[i]; if (processedNodes.delete(node)) { node.sourceRowIndex = writeIdx; newAllLeafChildren[writeIdx++] = node; } } } for (const node of processedNodes) { node.sourceRowIndex = writeIdx; newAllLeafChildren[writeIdx++] = node; } rootNode.allLeafChildren = newAllLeafChildren; const sibling = rootNode.sibling; if (sibling) { sibling.allLeafChildren = newAllLeafChildren; } params.rowNodesOrderChanged || (params.rowNodesOrderChanged = orderChanged); } if (nodesAdded || nodesRemoved || orderChanged || nodesUpdated) { this.deselectNodes(nodesToUnselect); params.rowDataUpdated = true; } } /** Called when a node needs to be deleted */ rowNodeDeleted(node) { node.clearRowTopAndRowIndex(); const id = node.id; const allNodesMap = this.allNodesMap; if (allNodesMap[id] === node) { delete allNodesMap[id]; } } updateRowData(rowDataTran, changedRowNodes) { this.dispatchRowDataUpdateStartedEvent(rowDataTran.add); const updateRowDataResult = { changedRowNodes, rowNodeTransaction: { remove: [], update: [], add: [] }, rowsInserted: false }; const nodesToUnselect = []; const getRowIdFunc = _getRowIdCallback(this.gos); this.executeRemove(getRowIdFunc, rowDataTran, updateRowDataResult, nodesToUnselect); this.executeUpdate(getRowIdFunc, rowDataTran, updateRowDataResult, nodesToUnselect); this.executeAdd(rowDataTran, updateRowDataResult); this.deselectNodes(nodesToUnselect); return updateRowDataResult; } executeAdd(rowDataTran, result) { const add = rowDataTran.add; if (!add?.length) { return; } let allLeafChildren = this.rootNode.allLeafChildren; let addIndex = allLeafChildren.length; if (typeof rowDataTran.addIndex === "number") { addIndex = this.sanitizeAddIndex(rowDataTran.addIndex); if (addIndex > 0) { const getDataPath = this.gos.get("treeData") && this.gos.get("getDataPath"); if (getDataPath) { for (let i = 0; i < allLeafChildren.length; i++) { const node = allLeafChildren[i]; if (node?.rowIndex == addIndex - 1) { addIndex = i + 1; break; } } } } } const addLength = add.length; const changedRowNodes = result.changedRowNodes; const newNodes = new Array(addLength); for (let i = 0; i < addLength; i++) { const newNode = this.createRowNode(add[i], addIndex + i); changedRowNodes.add(newNode); newNodes[i] = newNode; } const rootNode = this.rootNode; if (addIndex < allLeafChildren.length) { const nodesBeforeIndex = allLeafChildren.slice(0, addIndex); const nodesAfterIndex = allLeafChildren.slice(addIndex, allLeafChildren.length); const nodesAfterIndexFirstIndex = nodesBeforeIndex.length + newNodes.length; for (let index = 0, length = nodesAfterIndex.length; index < length; ++index) { nodesAfterIndex[index].sourceRowIndex = nodesAfterIndexFirstIndex + index; } allLeafChildren = [...nodesBeforeIndex, ...newNodes, ...nodesAfterIndex]; result.rowsInserted = true; } else { allLeafChildren = allLeafChildren.concat(newNodes); } rootNode.allLeafChildren = allLeafChildren; const sibling = rootNode.sibling; if (sibling) { sibling.allLeafChildren = allLeafChildren; } result.rowNodeTransaction.add = newNodes; } executeRemove(getRowIdFunc, rowDataTran, { changedRowNodes, rowNodeTransaction }, nodesToUnselect) { const { remove } = rowDataTran; if (!remove?.length) { return; } const rowIdsRemoved = {}; remove.forEach((item) => { const rowNode = this.lookupRowNode(getRowIdFunc, item); if (!rowNode) { return; } if (rowNode.isSelected()) { nodesToUnselect.push(rowNode); } rowNode.clearRowTopAndRowIndex(); rowIdsRemoved[rowNode.id] = true; delete this.allNodesMap[rowNode.id]; rowNodeTransaction.remove.push(rowNode); changedRowNodes.remove(rowNode); }); const rootNode = this.rootNode; rootNode.allLeafChildren = rootNode.allLeafChildren?.filter((rowNode) => !rowIdsRemoved[rowNode.id]) ?? null; rootNode.allLeafChildren?.forEach((node, idx) => { node.sourceRowIndex = idx; }); const sibling = rootNode.sibling; if (sibling) { sibling.allLeafChildren = rootNode.allLeafChildren; } } executeUpdate(getRowIdFunc, rowDataTran, { changedRowNodes, rowNodeTransaction }, nodesToUnselect) { const { update } = rowDataTran; if (!update?.length) { return; } update.forEach((item) => { const rowNode = this.lookupRowNode(getRowIdFunc, item); if (!rowNode) { return; } rowNode.updateData(item); if (!rowNode.selectable && rowNode.isSelected()) { nodesToUnselect.push(rowNode); } rowNodeTransaction.update.push(rowNode); changedRowNodes.update(rowNode); }); } dispatchRowDataUpdateStartedEvent(rowData) { this.eventSvc.dispatchEvent({ type: "rowDataUpdateStarted", firstRowData: rowData?.length ? rowData[0] : null }); } deselectNodes(nodesToUnselect) { const source = "rowDataChanged"; const selectionSvc = this.beans.selectionSvc; const selectionChanged = nodesToUnselect.length > 0; if (selectionChanged) { selectionSvc?.setNodesSelected({ newValue: false, nodes: nodesToUnselect, suppressFinishActions: true, source }); } selectionSvc?.updateGroupsFromChildrenSelections?.(source); if (selectionChanged) { this.eventSvc.dispatchEvent({ type: "selectionChanged", source }); } } sanitizeAddIndex(addIndex) { const allChildrenCount = this.rootNode.allLeafChildren?.length ?? 0; if (addIndex < 0 || addIndex >= allChildrenCount || Number.isNaN(addIndex)) { return allChildrenCount; } return Math.ceil(addIndex); } createRowNode(data, sourceRowIndex) { const node = new RowNode(this.beans); node.parent = this.rootNode; node.level = 0; node.group = false; node.expanded = false; node.sourceRowIndex = sourceRowIndex; node.setDataAndId(data, String(this.nextId)); if (this.allNodesMap[node.id]) { _warn(2, { nodeId: node.id }); } this.allNodesMap[node.id] = node; this.nextId++; return node; } lookupRowNode(getRowIdFunc, data) { let rowNode; if (getRowIdFunc) { const id = getRowIdFunc({ data, level: 0 }); rowNode = this.allNodesMap[id]; if (!rowNode) { _error(4, { id }); return null; } } else { rowNode = this.rootNode?.allLeafChildren?.find((node) => node.data === data); if (!rowNode) { _error(5, { data }); return null; } } return rowNode || null; } }; // packages/ag-grid-community/src/interfaces/serverSideTransaction.ts var ServerSideTransactionResultStatus = /* @__PURE__ */ ((ServerSideTransactionResultStatus2) => { ServerSideTransactionResultStatus2["Applied"] = "Applied"; ServerSideTransactionResultStatus2["StoreNotFound"] = "StoreNotFound"; ServerSideTransactionResultStatus2["StoreLoading"] = "StoreLoading"; ServerSideTransactionResultStatus2["StoreWaitingToLoad"] = "StoreWaitingToLoad"; ServerSideTransactionResultStatus2["StoreLoadingFailed"] = "StoreLoadingFailed"; ServerSideTransactionResultStatus2["StoreWrongType"] = "StoreWrongType"; ServerSideTransactionResultStatus2["Cancelled"] = "Cancelled"; ServerSideTransactionResultStatus2["StoreNotStarted"] = "StoreNotStarted"; return ServerSideTransactionResultStatus2; })(ServerSideTransactionResultStatus || {}); // packages/ag-grid-community/src/selection/checkboxSelectionComponent.ts var CheckboxSelectionComponent = class extends Component { constructor() { super( /* html*/ ` `, [AgCheckboxSelector] ); this.eCheckbox = RefPlaceholder; } postConstruct() { this.eCheckbox.setPassive(true); } getCheckboxId() { return this.eCheckbox.getInputElement().id; } onDataChanged() { this.onSelectionChanged(); } onSelectableChanged() { this.showOrHideSelect(); } onSelectionChanged() { const translate = this.getLocaleTextFunc(); const { rowNode, eCheckbox } = this; const state = rowNode.isSelected(); const stateName = _getAriaCheckboxStateName(translate, state); const [ariaKey, ariaLabel] = rowNode.selectable ? ["ariaRowToggleSelection", "Press Space to toggle row selection"] : ["ariaRowSelectionDisabled", "Row Selection is disabled for this row"]; const translatedLabel = translate(ariaKey, ariaLabel); eCheckbox.setValue(state, true); eCheckbox.setInputAriaLabel(`${translatedLabel} (${stateName})`); } init(params) { this.rowNode = params.rowNode; this.column = params.column; this.overrides = params.overrides; this.onSelectionChanged(); this.addManagedListeners(this.eCheckbox.getInputElement(), { // we don't want double click on this icon to open a group dblclick: _stopPropagationForAgGrid, click: (event) => { _stopPropagationForAgGrid(event); this.beans.selectionSvc?.handleSelectionEvent(event, this.rowNode, "checkboxSelected"); } }); this.addManagedListeners(this.rowNode, { rowSelected: this.onSelectionChanged.bind(this), dataChanged: this.onDataChanged.bind(this), selectableChanged: this.onSelectableChanged.bind(this) }); this.addManagedPropertyListener("rowSelection", ({ currentValue, previousValue }) => { const curr = typeof currentValue === "object" ? _getHideDisabledCheckboxes(currentValue) : void 0; const prev = typeof previousValue === "object" ? _getHideDisabledCheckboxes(previousValue) : void 0; if (curr !== prev) { this.onSelectableChanged(); } }); const isRowSelectableFunc = _getIsRowSelectable(this.gos); const checkboxVisibleIsDynamic = isRowSelectableFunc || typeof this.getIsVisible() === "function"; if (checkboxVisibleIsDynamic) { const showOrHideSelectListener = this.showOrHideSelect.bind(this); this.addManagedEventListeners({ displayedColumnsChanged: showOrHideSelectListener }); this.addManagedListeners(this.rowNode, { dataChanged: showOrHideSelectListener, cellChanged: showOrHideSelectListener }); this.showOrHideSelect(); } this.eCheckbox.getInputElement().setAttribute("tabindex", "-1"); } showOrHideSelect() { const { column, rowNode, overrides, gos } = this; let selectable = rowNode.selectable; const isVisible = this.getIsVisible(); if (selectable) { if (typeof isVisible === "function") { const extraParams = overrides?.callbackParams; if (!column) { selectable = isVisible({ ...extraParams, node: rowNode, data: rowNode.data }); } else { const params = column.createColumnFunctionCallbackParams(rowNode); selectable = isVisible({ ...extraParams, ...params }); } } else { selectable = isVisible ?? false; } } const so = gos.get("rowSelection"); const disableInsteadOfHide = so && typeof so !== "string" ? !_getHideDisabledCheckboxes(so) : column?.getColDef().showDisabledCheckboxes; if (disableInsteadOfHide) { this.eCheckbox.setDisabled(!selectable); this.setVisible(true); this.setDisplayed(true); return; } if (overrides?.removeHidden) { this.setDisplayed(selectable); return; } this.setVisible(selectable); } getIsVisible() { const overrides = this.overrides; if (overrides) { return overrides.isVisible; } const so = this.gos.get("rowSelection"); if (so && typeof so !== "string") { return _getCheckboxes(so); } return this.column?.getColDef()?.checkboxSelection; } }; // packages/ag-grid-community/src/selection/rowRangeSelectionContext.ts var RowRangeSelectionContext = class { constructor(rowModel) { this.rowModel = rowModel; /** Whether the user is currently selecting all nodes either via the header checkbox or API */ this.selectAll = false; this.rootId = null; /** * Note that the "end" `RowNode` may come before or after the "root" `RowNode` in the * actual grid. */ this.endId = null; this.cachedRange = []; } reset() { this.rootId = null; this.endId = null; this.cachedRange.length = 0; } setRoot(node) { this.rootId = node.id; this.endId = null; this.cachedRange.length = 0; } setEndRange(end) { this.endId = end.id; this.cachedRange.length = 0; } getRange() { if (this.cachedRange.length === 0) { const root = this.getRoot(); const end = this.getEnd(); if (root == null || end == null) { return this.cachedRange; } this.cachedRange = this.rowModel.getNodesInRangeForSelection(root, end) ?? []; } return this.cachedRange; } isInRange(node) { if (this.rootId === null) { return false; } return this.getRange().some((nodeInRange) => nodeInRange.id === node.id); } getRoot(fallback) { if (this.rootId) { return this.rowModel.getRowNode(this.rootId) ?? null; } if (fallback) { this.setRoot(fallback); return fallback; } return null; } getEnd() { if (this.endId) { return this.rowModel.getRowNode(this.endId) ?? null; } return null; } /** * Truncates the range to the given node (assumed to be within the current range). * Returns nodes that remain in the current range and those that should be removed * * @param node - Node at which to truncate the range * @returns Object of nodes to either keep or discard (i.e. deselect) from the range */ truncate(node) { const range = this.getRange(); if (range.length === 0) { return { keep: [], discard: [] }; } const discardAfter = range[0].id === this.rootId; const idx = range.findIndex((rowNode) => rowNode.id === node.id); if (idx > -1) { const above = range.slice(0, idx); const below = range.slice(idx + 1); this.setEndRange(node); return discardAfter ? { keep: above, discard: below } : { keep: below, discard: above }; } else { return { keep: range, discard: [] }; } } /** * Extends the range to the given node. Returns nodes that remain in the current range * and those that should be removed. * * @param node - Node marking the new end of the range * @returns Object of nodes to either keep or discard (i.e. deselect) from the range */ extend(node, groupSelectsChildren = false) { const root = this.getRoot(); if (root == null) { const keep = this.getRange().slice(); if (groupSelectsChildren) { node.depthFirstSearch((node2) => !node2.group && keep.push(node2)); } keep.push(node); this.setRoot(node); return { keep, discard: [] }; } const newRange = this.rowModel.getNodesInRangeForSelection(root, node); if (!newRange) { this.setRoot(node); return { keep: [node], discard: [] }; } if (newRange.find((newRangeNode) => newRangeNode.id === this.endId)) { this.setEndRange(node); return { keep: this.getRange(), discard: [] }; } else { const discard = this.getRange().slice(); this.setEndRange(node); return { keep: this.getRange(), discard }; } } }; // packages/ag-grid-community/src/selection/selectAllFeature.ts var SelectAllFeature = class extends BeanStub { constructor(column) { super(); this.column = column; this.cbSelectAllVisible = false; this.processingEventFromCheckbox = false; } onSpaceKeyDown(e) { const checkbox = this.cbSelectAll; if (checkbox.isDisplayed() && !checkbox.getGui().contains(_getActiveDomElement(this.beans))) { e.preventDefault(); checkbox.setValue(!checkbox.getValue()); } } getCheckboxGui() { return this.cbSelectAll.getGui(); } setComp(ctrl) { this.headerCellCtrl = ctrl; const cbSelectAll = this.createManagedBean(new AgCheckbox()); this.cbSelectAll = cbSelectAll; cbSelectAll.addCssClass("ag-header-select-all"); _setAriaRole(cbSelectAll.getGui(), "presentation"); this.showOrHideSelectAll(); this.addManagedEventListeners({ newColumnsLoaded: () => this.showOrHideSelectAll(), displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this), selectionChanged: this.onSelectionChanged.bind(this), paginationChanged: this.onSelectionChanged.bind(this), modelUpdated: this.onModelChanged.bind(this) }); this.addManagedPropertyListener("rowSelection", ({ currentValue, previousValue }) => { const getSelectAll = (rowSelection) => typeof rowSelection === "string" || !rowSelection || rowSelection.mode === "singleRow" ? void 0 : rowSelection.selectAll; if (getSelectAll(currentValue) !== getSelectAll(previousValue)) { this.showOrHideSelectAll(); } }); this.addManagedListeners(cbSelectAll, { fieldValueChanged: this.onCbSelectAll.bind(this) }); cbSelectAll.getInputElement().setAttribute("tabindex", "-1"); this.refreshSelectAllLabel(); } onDisplayedColumnsChanged(e) { if (!this.isAlive()) { return; } this.showOrHideSelectAll(e.source === "uiColumnMoved"); } showOrHideSelectAll(fromColumnMoved = false) { const cbSelectAllVisible = this.isCheckboxSelection(); this.cbSelectAllVisible = cbSelectAllVisible; this.cbSelectAll.setDisplayed(cbSelectAllVisible); if (cbSelectAllVisible) { this.checkRightRowModelType("selectAllCheckbox"); this.checkSelectionType("selectAllCheckbox"); this.updateStateOfCheckbox(); } this.refreshSelectAllLabel(fromColumnMoved); } onModelChanged() { if (!this.cbSelectAllVisible) { return; } this.updateStateOfCheckbox(); } onSelectionChanged() { if (!this.cbSelectAllVisible) { return; } this.updateStateOfCheckbox(); } updateStateOfCheckbox() { if (this.processingEventFromCheckbox) { return; } this.processingEventFromCheckbox = true; const selectAllMode = this.getSelectAllMode(); const selectionSvc = this.beans.selectionSvc; const cbSelectAll = this.cbSelectAll; const allSelected = selectionSvc.getSelectAllState(selectAllMode); cbSelectAll.setValue(allSelected); const hasNodesToSelect = selectionSvc.hasNodesToSelect(selectAllMode); cbSelectAll.setDisabled(!hasNodesToSelect); this.refreshSelectAllLabel(); this.processingEventFromCheckbox = false; } refreshSelectAllLabel(fromColumnMoved = false) { const translate = this.getLocaleTextFunc(); const { headerCellCtrl, cbSelectAll, cbSelectAllVisible } = this; const checked = cbSelectAll.getValue(); const ariaStatus = checked ? translate("ariaChecked", "checked") : translate("ariaUnchecked", "unchecked"); const ariaLabel = translate("ariaRowSelectAll", "Press Space to toggle all rows selection"); headerCellCtrl.setAriaDescriptionProperty( "selectAll", cbSelectAllVisible ? `${ariaLabel} (${ariaStatus})` : null ); cbSelectAll.setInputAriaLabel(translate("ariaHeaderSelection", "Column with Header Selection")); if (!fromColumnMoved) { headerCellCtrl.announceAriaDescription(); } } checkSelectionType(feature) { const isMultiSelect = _isMultiRowSelection(this.gos); if (!isMultiSelect) { _warn(128, { feature }); return false; } return true; } checkRightRowModelType(feature) { const { gos, rowModel } = this.beans; const rowModelMatches = _isClientSideRowModel(gos) || _isServerSideRowModel(gos); if (!rowModelMatches) { _warn(129, { feature, rowModel: rowModel.getType() }); return false; } return true; } onCbSelectAll() { if (this.processingEventFromCheckbox) { return; } if (!this.cbSelectAllVisible) { return; } const value = this.cbSelectAll.getValue(); const selectAll2 = this.getSelectAllMode(); let source = "uiSelectAll"; if (selectAll2 === "currentPage") { source = "uiSelectAllCurrentPage"; } else if (selectAll2 === "filtered") { source = "uiSelectAllFiltered"; } const params = { source, selectAll: selectAll2 }; const selectionSvc = this.beans.selectionSvc; if (value) { selectionSvc.selectAllRowNodes(params); } else { selectionSvc.deselectAllRowNodes(params); } } /** * Checkbox is enabled when either the `headerCheckbox` option is enabled in the new selection API * or `headerCheckboxSelection` is enabled in the legacy API. */ isCheckboxSelection() { const { column, gos, beans } = this; const rowSelection = gos.get("rowSelection"); const colDef = column.getColDef(); const { headerCheckboxSelection } = colDef; let result = false; const newHeaderCheckbox = typeof rowSelection === "object"; if (newHeaderCheckbox) { const isSelectionCol = isColumnSelectionCol(column); const isAutoCol = isColumnGroupAutoCol(column); const location = _getCheckboxLocation(rowSelection); if (location === "autoGroupColumn" && isAutoCol || isSelectionCol && beans.selectionColSvc?.isSelectionColumnEnabled()) { result = _getHeaderCheckbox(rowSelection); } } else { if (typeof headerCheckboxSelection === "function") { result = headerCheckboxSelection(_addGridCommonParams(gos, { column, colDef })); } else { result = !!headerCheckboxSelection; } } const featureName = newHeaderCheckbox ? "headerCheckbox" : "headerCheckboxSelection"; return result && this.checkRightRowModelType(featureName) && this.checkSelectionType(featureName); } getSelectAllMode() { const selectAll2 = _getSelectAll(this.gos, false); if (selectAll2) { return selectAll2; } const { headerCheckboxSelectionCurrentPageOnly, headerCheckboxSelectionFilteredOnly } = this.column.getColDef(); if (headerCheckboxSelectionCurrentPageOnly) { return "currentPage"; } if (headerCheckboxSelectionFilteredOnly) { return "filtered"; } return "all"; } }; // packages/ag-grid-community/src/selection/baseSelectionService.ts var BaseSelectionService = class extends BeanStub { postConstruct() { const { gos, beans } = this; this.selectionCtx = new RowRangeSelectionContext(beans.rowModel); this.addManagedPropertyListeners(["isRowSelectable", "rowSelection"], () => { const callback = _getIsRowSelectable(gos); if (callback !== this.isRowSelectable) { this.isRowSelectable = callback; this.updateSelectable(); } }); this.isRowSelectable = _getIsRowSelectable(gos); } destroy() { super.destroy(); this.selectionCtx.reset(); } createCheckboxSelectionComponent() { return new CheckboxSelectionComponent(); } createSelectAllFeature(column) { return new SelectAllFeature(column); } isMultiSelect() { return _isMultiRowSelection(this.gos); } onRowCtrlSelected(rowCtrl, hasFocusFunc, gui) { const selected = !!rowCtrl.rowNode.isSelected(); rowCtrl.forEachGui(gui, (gui2) => { gui2.rowComp.addOrRemoveCssClass("ag-row-selected", selected); const element = gui2.element; _setAriaSelected(element, selected); const hasFocus = element.contains(_getActiveDomElement(this.beans)); if (hasFocus) { hasFocusFunc(gui2); } }); } announceAriaRowSelection(rowNode) { if (this.isRowSelectionBlocked(rowNode)) { return; } const selected = rowNode.isSelected(); if (!rowNode.selectable) { return; } const translate = this.getLocaleTextFunc(); const label = translate( selected ? "ariaRowDeselect" : "ariaRowSelect", `Press SPACE to ${selected ? "deselect" : "select"} this row` ); this.beans.ariaAnnounce?.announceValue(label, "rowSelection"); } dispatchSelectionChanged(source) { this.eventSvc.dispatchEvent({ type: "selectionChanged", source }); } isRowSelectionBlocked(rowNode) { return !rowNode.selectable || !!rowNode.rowPinned || !_isRowSelection(this.gos); } updateRowSelectable(rowNode, suppressSelectionUpdate) { const selectable = this.isRowSelectable?.(rowNode) ?? true; this.setRowSelectable(rowNode, selectable, suppressSelectionUpdate); return selectable; } setRowSelectable(rowNode, newVal, suppressSelectionUpdate) { if (rowNode.selectable !== newVal) { rowNode.selectable = newVal; rowNode.dispatchRowEvent("selectableChanged"); if (suppressSelectionUpdate) { return; } const isGroupSelectsChildren = _getGroupSelectsDescendants(this.gos); if (isGroupSelectsChildren) { const selected = this.calculateSelectedFromChildren(rowNode); this.setNodesSelected({ nodes: [rowNode], newValue: selected ?? false, source: "selectableChanged" }); return; } if (rowNode.isSelected() && !rowNode.selectable) { this.setNodesSelected({ nodes: [rowNode], newValue: false, source: "selectableChanged" }); } } } calculateSelectedFromChildren(rowNode) { let atLeastOneSelected = false; let atLeastOneDeSelected = false; if (!rowNode.childrenAfterGroup?.length) { return rowNode.selectable ? rowNode.__selected : null; } for (let i = 0; i < rowNode.childrenAfterGroup.length; i++) { const child = rowNode.childrenAfterGroup[i]; let childState = child.isSelected(); if (!child.selectable) { const selectable = this.calculateSelectedFromChildren(child); if (selectable === null) { continue; } childState = selectable; } switch (childState) { case true: atLeastOneSelected = true; break; case false: atLeastOneDeSelected = true; break; default: return void 0; } } if (atLeastOneSelected && atLeastOneDeSelected) { return void 0; } if (atLeastOneSelected) { return true; } if (atLeastOneDeSelected) { return false; } if (!rowNode.selectable) { return null; } return rowNode.__selected; } selectRowNode(rowNode, newValue, e, source = "api") { const selectionNotAllowed = !rowNode.selectable && newValue; const selectionNotChanged = rowNode.__selected === newValue; if (selectionNotAllowed || selectionNotChanged) { return false; } rowNode.__selected = newValue; rowNode.dispatchRowEvent("rowSelected"); const sibling = rowNode.sibling; if (sibling && sibling.footer && sibling.__localEventService) { sibling.dispatchRowEvent("rowSelected"); } this.eventSvc.dispatchEvent({ ..._createGlobalRowEvent(rowNode, this.gos, "rowSelected"), event: e || null, source }); return true; } isCellCheckboxSelection(column, rowNode) { const so = this.gos.get("rowSelection"); if (so && typeof so !== "string") { const checkbox = isColumnSelectionCol(column) && _getCheckboxes(so); return column.isColumnFunc(rowNode, checkbox); } else { return column.isColumnFunc(rowNode, column.colDef.checkboxSelection); } } inferNodeSelections(node, shiftKey, metaKey, source) { const { gos, selectionCtx } = this; const currentSelection = node.isSelected(); const groupSelectsDescendants = _getGroupSelectsDescendants(gos); const enableClickSelection = _getEnableSelection(gos); const enableDeselection = _getEnableDeselection(gos); const isMultiSelect = this.isMultiSelect(); const isRowClicked = source === "rowClicked"; if (isRowClicked && groupSelectsDescendants && node.group) return null; if (isRowClicked && !(enableClickSelection || enableDeselection)) return null; if (shiftKey && metaKey && isMultiSelect) { const root = selectionCtx.getRoot(); if (!root) { return null; } else if (!root.isSelected()) { const partition = selectionCtx.extend(node, groupSelectsDescendants); return { select: [], deselect: partition.keep, reset: false }; } else { const partition = selectionCtx.isInRange(node) ? selectionCtx.truncate(node) : selectionCtx.extend(node, groupSelectsDescendants); return { deselect: partition.discard, select: partition.keep, reset: false }; } } else if (shiftKey && isMultiSelect) { const fallback = selectionCtx.selectAll ? this.beans.rowModel.getRow(0) : void 0; const root = selectionCtx.getRoot(fallback); const partition = selectionCtx.isInRange(node) ? selectionCtx.truncate(node) : selectionCtx.extend(node, groupSelectsDescendants); return { select: partition.keep, deselect: partition.discard, reset: selectionCtx.selectAll || !!(root && !root.isSelected()) }; } else if (metaKey) { selectionCtx.setRoot(node); if (isRowClicked && currentSelection && !enableDeselection) { return null; } return { node, newValue: !currentSelection, clearSelection: !isMultiSelect }; } else { selectionCtx.setRoot(node); const enableSelectionWithoutKeys = _getEnableSelectionWithoutKeys(gos); const groupSelectsFiltered = _getGroupSelection(gos) === "filteredDescendants"; const shouldClear = isRowClicked && (!enableSelectionWithoutKeys || !enableClickSelection); if (groupSelectsFiltered && currentSelection === void 0 && _isClientSideRowModel(gos)) { return { node, newValue: false, clearSelection: !isMultiSelect || shouldClear }; } if (isRowClicked) { const newValue = currentSelection ? !enableSelectionWithoutKeys : enableClickSelection; const selectingWhenDisabled = newValue && !enableClickSelection; const deselectingWhenDisabled = !newValue && !enableDeselection; const wouldStateBeUnchanged = newValue === currentSelection && !shouldClear; if (wouldStateBeUnchanged || selectingWhenDisabled || deselectingWhenDisabled) return null; return { node, newValue, clearSelection: !isMultiSelect || shouldClear }; } return { node, newValue: !currentSelection, clearSelection: !isMultiSelect || shouldClear }; } } }; // packages/ag-grid-community/src/widgets/agRadioButton.ts var AgRadioButton = class extends AgCheckbox { constructor(config) { super(config, "ag-radio-button", "radio"); } isSelected() { return this.eInput.checked; } toggle() { if (this.eInput.disabled) { return; } if (!this.isSelected()) { this.setValue(true); } } addInputListeners() { super.addInputListeners(); this.addManagedEventListeners({ checkboxChanged: this.onChange.bind(this) }); } /** * This ensures that if another radio button in the same named group is selected, we deselect this radio button. * By default the browser does this for you, but we are managing classes ourselves in order to ensure input * elements are styled correctly in IE11, and the DOM 'changed' event is only fired when a button is selected, * not deselected, so we need to use our own event. */ onChange(event) { const eInput = this.eInput; if (event.selected && event.name && eInput.name && eInput.name === event.name && event.id && eInput.id !== event.id) { this.setValue(false, true); } } }; // packages/ag-grid-community/src/widgets/agToggleButton.css-GENERATED.ts var agToggleButtonCSS = ( /*css*/ `.ag-toggle-button{flex:none;min-width:unset;width:unset}.ag-toggle-button-input-wrapper{background-color:var(--ag-toggle-button-off-background-color);border-radius:calc(var(--ag-toggle-button-height)*.5);flex:none;height:var(--ag-toggle-button-height);max-width:var(--ag-toggle-button-width);min-width:var(--ag-toggle-button-width);position:relative;transition:background-color .1s;:where(.ag-toggle-button-input){-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;display:block;height:var(--ag-toggle-button-height);margin:0;max-width:var(--ag-toggle-button-width);min-width:var(--ag-toggle-button-width);opacity:0}&:before{background-color:var(--ag-toggle-button-switch-background-color);border-radius:100%;content:"";display:block;height:calc(var(--ag-toggle-button-height) - var(--ag-toggle-button-switch-inset)*2);left:var(--ag-toggle-button-switch-inset);pointer-events:none;position:absolute;top:var(--ag-toggle-button-switch-inset);transition:left .1s;width:calc(var(--ag-toggle-button-height) - var(--ag-toggle-button-switch-inset)*2)}&.ag-checked{background-color:var(--ag-toggle-button-on-background-color);&:before{left:calc(100% - var(--ag-toggle-button-height) + var(--ag-toggle-button-switch-inset))}}&:focus-within{box-shadow:var(--ag-focus-shadow)}&.ag-disabled{opacity:.5}}` ); // packages/ag-grid-community/src/widgets/agToggleButton.ts var AgToggleButton = class extends AgCheckbox { constructor(config) { super(config, "ag-toggle-button"); this.registerCSS(agToggleButtonCSS); } setValue(value, silent) { super.setValue(value, silent); this.addOrRemoveCssClass("ag-selected", this.getValue()); return this; } }; var AgToggleButtonSelector = { selector: "AG-TOGGLE-BUTTON", component: AgToggleButton }; // packages/ag-grid-community/src/widgets/agInputTextField.ts var AgInputTextField = class extends AgAbstractInputField { constructor(config, className = "ag-text-field", inputType = "text") { super(config, className, inputType); } postConstruct() { super.postConstruct(); if (this.config.allowedCharPattern) { this.preventDisallowedCharacters(); } } setValue(value, silent) { const eInput = this.eInput; if (eInput.value !== value) { eInput.value = _exists(value) ? value : ""; } return super.setValue(value, silent); } /** Used to set an initial value into the input without necessarily setting `this.value` or triggering events (e.g. to set an invalid value) */ setStartValue(value) { this.setValue(value, true); } preventDisallowedCharacters() { const pattern = new RegExp(`[${this.config.allowedCharPattern}]`); const preventCharacters = (event) => { if (!_isEventFromPrintableCharacter(event)) { return; } if (event.key && !pattern.test(event.key)) { event.preventDefault(); } }; this.addManagedListeners(this.eInput, { keydown: preventCharacters, paste: (e) => { const text = e.clipboardData?.getData("text"); if (text && text.split("").some((c) => !pattern.test(c))) { e.preventDefault(); } } }); } }; var AgInputTextFieldSelector = { selector: "AG-INPUT-TEXT-FIELD", component: AgInputTextField }; // packages/ag-grid-community/src/widgets/agInputTextArea.ts var AgInputTextArea = class extends AgAbstractInputField { constructor(config) { super(config, "ag-text-area", null, "textarea"); } setValue(value, silent) { const ret = super.setValue(value, silent); this.eInput.value = value; return ret; } setCols(cols) { this.eInput.cols = cols; return this; } setRows(rows) { this.eInput.rows = rows; return this; } }; var AgInputTextAreaSelector = { selector: "AG-INPUT-TEXT-AREA", component: AgInputTextArea }; // packages/ag-grid-community/src/widgets/agInputNumberField.ts var AgInputNumberField = class extends AgInputTextField { constructor(config) { super(config, "ag-number-field", "number"); } postConstruct() { super.postConstruct(); const eInput = this.eInput; this.addManagedListeners(eInput, { blur: () => { const floatedValue = parseFloat(eInput.value); const value = isNaN(floatedValue) ? "" : this.normalizeValue(floatedValue.toString()); if (this.value !== value) { this.setValue(value); } }, wheel: this.onWheel.bind(this) }); eInput.step = "any"; const { precision, min, max, step } = this.config; if (typeof precision === "number") this.setPrecision(precision); if (typeof min === "number") this.setMin(min); if (typeof max === "number") this.setMax(max); if (typeof step === "number") this.setStep(step); } onWheel(e) { if (_getActiveDomElement(this.beans) === this.eInput) { e.preventDefault(); } } normalizeValue(value) { if (value === "") { return ""; } if (this.precision != null) { value = this.adjustPrecision(value); } const val = parseFloat(value); const { min, max } = this; if (min != null && val < min) { value = min.toString(); } else if (max != null && val > max) { value = max.toString(); } return value; } adjustPrecision(value, isScientificNotation) { const precision = this.precision; if (precision == null) { return value; } if (isScientificNotation) { const floatString = parseFloat(value).toFixed(precision); return parseFloat(floatString).toString(); } const parts = String(value).split("."); if (parts.length > 1) { if (parts[1].length <= precision) { return value; } else if (precision > 0) { return `${parts[0]}.${parts[1].slice(0, precision)}`; } } return parts[0]; } setMin(min) { if (this.min === min) { return this; } this.min = min; _addOrRemoveAttribute(this.eInput, "min", min); return this; } setMax(max) { if (this.max === max) { return this; } this.max = max; _addOrRemoveAttribute(this.eInput, "max", max); return this; } setPrecision(precision) { this.precision = precision; return this; } setStep(step) { if (this.step === step) { return this; } this.step = step; _addOrRemoveAttribute(this.eInput, "step", step); return this; } setValue(value, silent) { return this.setValueOrInputValue( (v) => super.setValue(v, silent), () => this, value ); } setStartValue(value) { return this.setValueOrInputValue( (v) => super.setValue(v, true), (v) => { this.eInput.value = v; }, value ); } setValueOrInputValue(setValueFunc, setInputValueOnlyFunc, value) { if (_exists(value)) { let setInputValueOnly = this.isScientificNotation(value); if (setInputValueOnly && this.eInput.validity.valid) { return setValueFunc(value); } if (!setInputValueOnly) { value = this.adjustPrecision(value); const normalizedValue = this.normalizeValue(value); setInputValueOnly = value != normalizedValue; } if (setInputValueOnly) { return setInputValueOnlyFunc(value); } } return setValueFunc(value); } getValue() { const eInput = this.eInput; if (!eInput.validity.valid) { return void 0; } const inputValue = eInput.value; if (this.isScientificNotation(inputValue)) { return this.adjustPrecision(inputValue, true); } return super.getValue(); } isScientificNotation(value) { return typeof value === "string" && value.includes("e"); } }; var AgInputNumberFieldSelector = { selector: "AG-INPUT-NUMBER-FIELD", component: AgInputNumberField }; // packages/ag-grid-community/src/utils/date.ts function _padStartWidthZeros(value, totalStringSize) { return value.toString().padStart(totalStringSize, "0"); } function _serialiseDate(date, includeTime = true, separator = "-") { if (!date) { return null; } let serialised = [date.getFullYear(), date.getMonth() + 1, date.getDate()].map((part) => _padStartWidthZeros(part, 2)).join(separator); if (includeTime) { serialised += " " + [date.getHours(), date.getMinutes(), date.getSeconds()].map((part) => _padStartWidthZeros(part, 2)).join(":"); } return serialised; } var calculateOrdinal = (value) => { if (value > 3 && value < 21) { return "th"; } const remainder = value % 10; switch (remainder) { case 1: return "st"; case 2: return "nd"; case 3: return "rd"; } return "th"; }; function _dateToFormattedString(date, format = "YYYY-MM-DD") { const fullYear = _padStartWidthZeros(date.getFullYear(), 4); const months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; const replace = { YYYY: () => fullYear.slice(fullYear.length - 4, fullYear.length), YY: () => fullYear.slice(fullYear.length - 2, fullYear.length), Y: () => `${date.getFullYear()}`, MMMM: () => months[date.getMonth()], MMM: () => months[date.getMonth()].slice(0, 3), MM: () => _padStartWidthZeros(date.getMonth() + 1, 2), Mo: () => `${date.getMonth() + 1}${calculateOrdinal(date.getMonth() + 1)}`, M: () => `${date.getMonth() + 1}`, Do: () => `${date.getDate()}${calculateOrdinal(date.getDate())}`, DD: () => _padStartWidthZeros(date.getDate(), 2), D: () => `${date.getDate()}`, dddd: () => days[date.getDay()], ddd: () => days[date.getDay()].slice(0, 3), dd: () => days[date.getDay()].slice(0, 2), do: () => `${date.getDay()}${calculateOrdinal(date.getDay())}`, d: () => `${date.getDay()}` }; const regexp = new RegExp(Object.keys(replace).join("|"), "g"); return format.replace(regexp, (match) => { if (match in replace) { return replace[match](); } return match; }); } function _parseDateTimeFromString(value) { if (!value) { return null; } const [dateStr, timeStr] = value.split(" "); if (!dateStr) { return null; } const fields = dateStr.split("-").map((f) => parseInt(f, 10)); if (fields.filter((f) => !isNaN(f)).length !== 3) { return null; } const [year, month, day] = fields; const date = new Date(year, month - 1, day); if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) { return null; } if (!timeStr || timeStr === "00:00:00") { return date; } const [hours, minutes, seconds] = timeStr.split(":").map((part) => parseInt(part, 10)); if (hours >= 0 && hours < 24) { date.setHours(hours); } if (minutes >= 0 && minutes < 60) { date.setMinutes(minutes); } if (seconds >= 0 && seconds < 60) { date.setSeconds(seconds); } return date; } // packages/ag-grid-community/src/widgets/agInputDateField.ts var AgInputDateField = class extends AgInputTextField { constructor(config) { super(config, "ag-date-field", "date"); } postConstruct() { super.postConstruct(); const usingSafari = _isBrowserSafari(); this.addManagedListeners(this.eInput, { wheel: this.onWheel.bind(this), mousedown: () => { if (this.isDisabled() || usingSafari) { return; } this.eInput.focus(); } }); this.eInput.step = "any"; } onWheel(e) { if (_getActiveDomElement(this.beans) === this.eInput) { e.preventDefault(); } } setMin(minDate) { const min = minDate instanceof Date ? _serialiseDate(minDate ?? null, false) ?? void 0 : minDate; if (this.min === min) { return this; } this.min = min; _addOrRemoveAttribute(this.eInput, "min", min); return this; } setMax(maxDate) { const max = maxDate instanceof Date ? _serialiseDate(maxDate ?? null, false) ?? void 0 : maxDate; if (this.max === max) { return this; } this.max = max; _addOrRemoveAttribute(this.eInput, "max", max); return this; } setStep(step) { if (this.step === step) { return this; } this.step = step; _addOrRemoveAttribute(this.eInput, "step", step); return this; } getDate() { if (!this.eInput.validity.valid) { return void 0; } return _parseDateTimeFromString(this.getValue()) ?? void 0; } setDate(date, silent) { this.setValue(_serialiseDate(date ?? null, false), silent); } }; var AgInputDateFieldSelector = { selector: "AG-INPUT-DATE-FIELD", component: AgInputDateField }; // packages/ag-grid-community/src/tooltip/tooltipStateManager.ts var SHOW_QUICK_TOOLTIP_DIFF = 1e3; var FADE_OUT_TOOLTIP_TIMEOUT = 1e3; var INTERACTIVE_HIDE_DELAY = 100; var lastTooltipHideTime; var isLocked = false; var TooltipStateManager = class extends BeanStub { constructor(tooltipCtrl, getTooltipValue) { super(); this.tooltipCtrl = tooltipCtrl; this.getTooltipValue = getTooltipValue; this.interactionEnabled = false; this.isInteractingWithTooltip = false; this.state = 0 /* NOTHING */; // when showing the tooltip, we need to make sure it's the most recent instance we request, as due to // async we could request two tooltips before the first instance returns, in which case we should // disregard the second instance. this.tooltipInstanceCount = 0; this.tooltipMouseTrack = false; } wireBeans(beans) { this.popupSvc = beans.popupSvc; this.userCompFactory = beans.userCompFactory; } postConstruct() { if (this.gos.get("tooltipInteraction")) { this.interactionEnabled = true; } this.tooltipTrigger = this.getTooltipTrigger(); this.tooltipMouseTrack = this.gos.get("tooltipMouseTrack"); const el = this.tooltipCtrl.getGui(); if (this.tooltipTrigger === 0 /* HOVER */) { this.addManagedListeners(el, { mouseenter: this.onMouseEnter.bind(this), mouseleave: this.onMouseLeave.bind(this) }); } if (this.tooltipTrigger === 1 /* FOCUS */) { this.addManagedListeners(el, { focusin: this.onFocusIn.bind(this), focusout: this.onFocusOut.bind(this) }); } this.addManagedListeners(el, { mousemove: this.onMouseMove.bind(this) }); if (!this.interactionEnabled) { this.addManagedListeners(el, { mousedown: this.onMouseDown.bind(this), keydown: this.onKeyDown.bind(this) }); } } getGridOptionsTooltipDelay(delayOption) { const delay = this.gos.get(delayOption); return Math.max(200, delay); } getTooltipDelay(type) { if (type === "show") { return this.tooltipCtrl.getTooltipShowDelayOverride?.() ?? this.getGridOptionsTooltipDelay("tooltipShowDelay"); } return this.tooltipCtrl.getTooltipHideDelayOverride?.() ?? this.getGridOptionsTooltipDelay("tooltipHideDelay"); } destroy() { this.setToDoNothing(); super.destroy(); } getTooltipTrigger() { const trigger = this.gos.get("tooltipTrigger"); if (!trigger || trigger === "hover") { return 0 /* HOVER */; } return 1 /* FOCUS */; } onMouseEnter(e) { if (this.interactionEnabled && this.interactiveTooltipTimeoutId) { this.unlockService(); this.startHideTimeout(); } if (_isIOSUserAgent()) { return; } if (isLocked) { this.showTooltipTimeoutId = window.setTimeout(() => { this.prepareToShowTooltip(e); }, INTERACTIVE_HIDE_DELAY); } else { this.prepareToShowTooltip(e); } } onMouseMove(e) { if (this.lastMouseEvent) { this.lastMouseEvent = e; } if (this.tooltipMouseTrack && this.state === 2 /* SHOWING */ && this.tooltipComp) { this.positionTooltip(); } } onMouseDown() { this.setToDoNothing(); } onMouseLeave() { if (this.interactionEnabled) { this.lockService(); } else { this.setToDoNothing(); } } onFocusIn() { this.prepareToShowTooltip(); } onFocusOut(e) { const relatedTarget = e.relatedTarget; const parentCompGui = this.tooltipCtrl.getGui(); const tooltipGui = this.tooltipComp?.getGui(); if (this.isInteractingWithTooltip || parentCompGui.contains(relatedTarget) || this.interactionEnabled && tooltipGui?.contains(relatedTarget)) { return; } this.setToDoNothing(); } onKeyDown() { if (this.isInteractingWithTooltip) { this.isInteractingWithTooltip = false; } this.setToDoNothing(); } prepareToShowTooltip(mouseEvent) { if (this.state != 0 /* NOTHING */ || isLocked) { return; } let delay = 0; if (mouseEvent) { delay = this.isLastTooltipHiddenRecently() ? 200 : this.getTooltipDelay("show"); } this.lastMouseEvent = mouseEvent || null; this.showTooltipTimeoutId = window.setTimeout(this.showTooltip.bind(this), delay); this.state = 1 /* WAITING_TO_SHOW */; } isLastTooltipHiddenRecently() { const now = (/* @__PURE__ */ new Date()).getTime(); const then = lastTooltipHideTime; return now - then < SHOW_QUICK_TOOLTIP_DIFF; } setToDoNothing(fromHideTooltip) { if (!fromHideTooltip && this.state === 2 /* SHOWING */) { this.hideTooltip(); } if (this.onBodyScrollEventCallback) { this.onBodyScrollEventCallback(); this.onBodyScrollEventCallback = void 0; } if (this.onColumnMovedEventCallback) { this.onColumnMovedEventCallback(); this.onColumnMovedEventCallback = void 0; } if (this.onDocumentKeyDownCallback) { this.onDocumentKeyDownCallback(); this.onDocumentKeyDownCallback = void 0; } this.clearTimeouts(); this.state = 0 /* NOTHING */; this.lastMouseEvent = null; } showTooltip() { const value = this.getTooltipValue(); const ctrl = this.tooltipCtrl; if (!_exists(value) || ctrl.shouldDisplayTooltip && !ctrl.shouldDisplayTooltip()) { this.setToDoNothing(); return; } const rowNode = ctrl.getRowNode?.(); const params = _addGridCommonParams(this.gos, { location: ctrl.getLocation?.() ?? "UNKNOWN", //'cell', colDef: ctrl.getColDef?.(), column: ctrl.getColumn?.(), rowIndex: ctrl.getRowIndex?.(), node: rowNode, data: rowNode?.data, value, valueFormatted: ctrl.getValueFormatted?.(), hideTooltipCallback: () => this.hideTooltip(true), ...ctrl.getAdditionalParams?.() ?? {} }); this.state = 2 /* SHOWING */; this.tooltipInstanceCount++; const callback = this.newTooltipComponentCallback.bind(this, this.tooltipInstanceCount); const userDetails = _getTooltipCompDetails(this.userCompFactory, params); userDetails?.newAgStackInstance().then(callback); } hideTooltip(forceHide) { if (!forceHide && this.isInteractingWithTooltip) { return; } if (this.tooltipComp) { this.destroyTooltipComp(); lastTooltipHideTime = (/* @__PURE__ */ new Date()).getTime(); } this.eventSvc.dispatchEvent({ type: "tooltipHide", parentGui: this.tooltipCtrl.getGui() }); if (forceHide) { this.isInteractingWithTooltip = false; } this.setToDoNothing(true); } newTooltipComponentCallback(tooltipInstanceCopy, tooltipComp) { const compNoLongerNeeded = this.state !== 2 /* SHOWING */ || this.tooltipInstanceCount !== tooltipInstanceCopy; if (compNoLongerNeeded) { this.destroyBean(tooltipComp); return; } const eGui = tooltipComp.getGui(); this.tooltipComp = tooltipComp; if (!eGui.classList.contains("ag-tooltip")) { eGui.classList.add("ag-tooltip-custom"); } if (this.tooltipTrigger === 0 /* HOVER */) { eGui.classList.add("ag-tooltip-animate"); } if (this.interactionEnabled) { eGui.classList.add("ag-tooltip-interactive"); } const translate = this.getLocaleTextFunc(); const addPopupRes = this.popupSvc?.addPopup({ eChild: eGui, ariaLabel: translate("ariaLabelTooltip", "Tooltip") }); if (addPopupRes) { this.tooltipPopupDestroyFunc = addPopupRes.hideFunc; } this.positionTooltip(); if (this.tooltipTrigger === 1 /* FOCUS */) { const listener = () => this.setToDoNothing(); [this.onBodyScrollEventCallback, this.onColumnMovedEventCallback] = this.addManagedEventListeners({ bodyScroll: listener, columnMoved: listener }); } if (this.interactionEnabled) { [this.tooltipMouseEnterListener, this.tooltipMouseLeaveListener] = this.addManagedElementListeners(eGui, { mouseenter: this.onTooltipMouseEnter.bind(this), mouseleave: this.onTooltipMouseLeave.bind(this) }); [this.onDocumentKeyDownCallback] = this.addManagedElementListeners(_getDocument(this.beans), { keydown: (e) => { if (!eGui.contains(e?.target)) { this.onKeyDown(); } } }); if (this.tooltipTrigger === 1 /* FOCUS */) { [this.tooltipFocusInListener, this.tooltipFocusOutListener] = this.addManagedElementListeners(eGui, { focusin: this.onTooltipFocusIn.bind(this), focusout: this.onTooltipFocusOut.bind(this) }); } } this.eventSvc.dispatchEvent({ type: "tooltipShow", tooltipGui: eGui, parentGui: this.tooltipCtrl.getGui() }); this.startHideTimeout(); } onTooltipMouseEnter() { this.isInteractingWithTooltip = true; this.unlockService(); } onTooltipMouseLeave() { if (this.isTooltipFocused()) { return; } this.isInteractingWithTooltip = false; this.lockService(); } onTooltipFocusIn() { this.isInteractingWithTooltip = true; } isTooltipFocused() { const tooltipGui = this.tooltipComp?.getGui(); const activeEl = _getActiveDomElement(this.beans); return !!tooltipGui && tooltipGui.contains(activeEl); } onTooltipFocusOut(e) { const parentGui = this.tooltipCtrl.getGui(); if (this.isTooltipFocused()) { return; } this.isInteractingWithTooltip = false; if (parentGui.contains(e.relatedTarget)) { this.startHideTimeout(); } else { this.hideTooltip(); } } positionTooltip() { const params = { type: "tooltip", ePopup: this.tooltipComp.getGui(), nudgeY: 18, skipObserver: this.tooltipMouseTrack }; if (this.lastMouseEvent) { this.popupSvc?.positionPopupUnderMouseEvent({ ...params, mouseEvent: this.lastMouseEvent }); } else { this.popupSvc?.positionPopupByComponent({ ...params, eventSource: this.tooltipCtrl.getGui(), position: "under", keepWithinBounds: true, nudgeY: 5 }); } } destroyTooltipComp() { this.tooltipComp.getGui().classList.add("ag-tooltip-hiding"); const tooltipPopupDestroyFunc = this.tooltipPopupDestroyFunc; const tooltipComp = this.tooltipComp; const delay = this.tooltipTrigger === 0 /* HOVER */ ? FADE_OUT_TOOLTIP_TIMEOUT : 0; window.setTimeout(() => { tooltipPopupDestroyFunc(); this.destroyBean(tooltipComp); }, delay); this.clearTooltipListeners(); this.tooltipPopupDestroyFunc = void 0; this.tooltipComp = void 0; } clearTooltipListeners() { [ this.tooltipMouseEnterListener, this.tooltipMouseLeaveListener, this.tooltipFocusInListener, this.tooltipFocusOutListener ].forEach((listener) => { if (listener) { listener(); } }); this.tooltipMouseEnterListener = this.tooltipMouseLeaveListener = this.tooltipFocusInListener = this.tooltipFocusOutListener = null; } lockService() { isLocked = true; this.interactiveTooltipTimeoutId = window.setTimeout(() => { this.unlockService(); this.setToDoNothing(); }, INTERACTIVE_HIDE_DELAY); } unlockService() { isLocked = false; this.clearInteractiveTimeout(); } startHideTimeout() { this.clearHideTimeout(); this.hideTooltipTimeoutId = window.setTimeout(this.hideTooltip.bind(this), this.getTooltipDelay("hide")); } clearShowTimeout() { if (!this.showTooltipTimeoutId) { return; } window.clearTimeout(this.showTooltipTimeoutId); this.showTooltipTimeoutId = void 0; } clearHideTimeout() { if (!this.hideTooltipTimeoutId) { return; } window.clearTimeout(this.hideTooltipTimeoutId); this.hideTooltipTimeoutId = void 0; } clearInteractiveTimeout() { if (!this.interactiveTooltipTimeoutId) { return; } window.clearTimeout(this.interactiveTooltipTimeoutId); this.interactiveTooltipTimeoutId = void 0; } clearTimeouts() { this.clearShowTimeout(); this.clearHideTimeout(); this.clearInteractiveTimeout(); } }; // packages/ag-grid-community/src/tooltip/tooltipFeature.ts function _isShowTooltipWhenTruncated(gos) { return gos.get("tooltipShowMode") === "whenTruncated"; } function _getShouldDisplayTooltip(gos, getElement) { return _isShowTooltipWhenTruncated(gos) ? _shouldDisplayTooltip(getElement) : void 0; } function _shouldDisplayTooltip(getElement) { return () => { const element = getElement(); if (!element) { return true; } return element.scrollWidth > element.clientWidth; }; } var TooltipFeature = class extends BeanStub { constructor(ctrl, beans) { super(); this.ctrl = ctrl; if (beans) { this.beans = beans; } } postConstruct() { this.refreshTooltip(); } setBrowserTooltip(tooltip) { const name = "title"; const eGui = this.ctrl.getGui(); if (!eGui) { return; } if (tooltip != null && tooltip != "") { eGui.setAttribute(name, tooltip); } else { eGui.removeAttribute(name); } } updateTooltipText() { const { getTooltipValue } = this.ctrl; if (getTooltipValue) { this.tooltip = getTooltipValue(); } } createTooltipFeatureIfNeeded() { if (this.tooltipManager == null) { this.tooltipManager = this.createBean( new TooltipStateManager(this.ctrl, () => this.tooltip), this.beans.context ); } } setTooltipAndRefresh(tooltip) { this.tooltip = tooltip; this.refreshTooltip(); } refreshTooltip() { this.browserTooltips = this.beans.gos.get("enableBrowserTooltips"); this.updateTooltipText(); if (this.browserTooltips) { this.setBrowserTooltip(this.tooltip); this.tooltipManager = this.destroyBean(this.tooltipManager, this.beans.context); } else { this.setBrowserTooltip(null); this.createTooltipFeatureIfNeeded(); } } destroy() { this.tooltipManager = this.destroyBean(this.tooltipManager, this.beans.context); super.destroy(); } }; // packages/ag-grid-community/src/widgets/agList.ts var AgList = class extends Component { constructor(cssIdentifier = "default", unFocusable = false) { super( /* html */ `
` ); this.cssIdentifier = cssIdentifier; this.unFocusable = unFocusable; this.activeClass = "ag-active-item"; this.options = []; this.itemEls = []; } postConstruct() { const eGui = this.getGui(); this.addManagedElementListeners(eGui, { mouseleave: () => this.clearHighlighted() }); if (this.unFocusable) { return; } this.addManagedElementListeners(eGui, { keydown: this.handleKeyDown.bind(this) }); } handleKeyDown(e) { const key = e.key; switch (key) { case KeyCode.ENTER: if (!this.highlightedEl) { this.setValue(this.getValue()); } else { const pos = this.itemEls.indexOf(this.highlightedEl); this.setValueByIndex(pos); } break; case KeyCode.DOWN: case KeyCode.UP: e.preventDefault(); this.navigate(key); break; case KeyCode.PAGE_DOWN: case KeyCode.PAGE_UP: case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: e.preventDefault(); this.navigateToPage(key); break; } } navigate(key) { const isDown = key === KeyCode.DOWN; let itemToHighlight; const { itemEls, highlightedEl } = this; if (!highlightedEl) { itemToHighlight = itemEls[isDown ? 0 : itemEls.length - 1]; } else { const currentIdx = itemEls.indexOf(highlightedEl); let nextPos = currentIdx + (isDown ? 1 : -1); nextPos = Math.min(Math.max(nextPos, 0), itemEls.length - 1); itemToHighlight = itemEls[nextPos]; } this.highlightItem(itemToHighlight); } navigateToPage(key) { const { itemEls, highlightedEl } = this; if (!highlightedEl || itemEls.length === 0) { return; } const currentIdx = itemEls.indexOf(highlightedEl); const rowCount = this.options.length - 1; const itemHeight = itemEls[0].clientHeight; const pageSize = Math.floor(this.getGui().clientHeight / itemHeight); let newIndex = -1; if (key === KeyCode.PAGE_HOME) { newIndex = 0; } else if (key === KeyCode.PAGE_END) { newIndex = rowCount; } else if (key === KeyCode.PAGE_DOWN) { newIndex = Math.min(currentIdx + pageSize, rowCount); } else if (key === KeyCode.PAGE_UP) { newIndex = Math.max(currentIdx - pageSize, 0); } if (newIndex === -1) { return; } this.highlightItem(itemEls[newIndex]); } addOptions(listOptions) { listOptions.forEach((listOption) => this.addOption(listOption)); return this; } addOption(listOption) { const { value, text } = listOption; const valueToRender = text || value; this.options.push({ value, text: valueToRender }); this.renderOption(value, valueToRender); this.updateIndices(); return this; } clearOptions() { this.options = []; this.reset(true); this.itemEls.forEach((itemEl) => { _removeFromParent(itemEl); }); this.itemEls = []; } updateIndices() { const options = this.getGui().querySelectorAll(".ag-list-item"); options.forEach((option, idx) => { _setAriaPosInSet(option, idx + 1); _setAriaSetSize(option, options.length); }); } renderOption(value, text) { const eDocument = _getDocument(this.beans); const itemEl = eDocument.createElement("div"); _setAriaRole(itemEl, "option"); itemEl.classList.add("ag-list-item", `ag-${this.cssIdentifier}-list-item`); const span = eDocument.createElement("span"); itemEl.appendChild(span); span.textContent = text; if (!this.unFocusable) { itemEl.tabIndex = -1; } this.itemEls.push(itemEl); this.addManagedListeners(itemEl, { mouseover: () => this.highlightItem(itemEl), mousedown: (e) => { e.preventDefault(); e.stopPropagation(); this.setValue(value); } }); this.createOptionalManagedBean( this.beans.registry.createDynamicBean("tooltipFeature", false, { getTooltipValue: () => text, getGui: () => itemEl, getLocation: () => "UNKNOWN", // only show tooltips for items where the text cannot be fully displayed shouldDisplayTooltip: () => span.scrollWidth > span.clientWidth }) ); this.getGui().appendChild(itemEl); } setValue(value, silent) { if (this.value === value) { this.fireItemSelected(); return this; } if (value == null) { this.reset(silent); return this; } const idx = this.options.findIndex((option) => option.value === value); if (idx !== -1) { const option = this.options[idx]; this.value = option.value; this.displayValue = option.text; this.highlightItem(this.itemEls[idx]); if (!silent) { this.fireChangeEvent(); } } return this; } setValueByIndex(idx) { return this.setValue(this.options[idx].value); } getValue() { return this.value; } getDisplayValue() { return this.displayValue; } refreshHighlighted() { this.clearHighlighted(); const idx = this.options.findIndex((option) => option.value === this.value); if (idx !== -1) { this.highlightItem(this.itemEls[idx]); } } reset(silent) { this.value = null; this.displayValue = null; this.clearHighlighted(); if (!silent) { this.fireChangeEvent(); } } highlightItem(el) { if (!_isVisible(el)) { return; } this.clearHighlighted(); this.highlightedEl = el; el.classList.add(this.activeClass); _setAriaSelected(el, true); const eGui = this.getGui(); const { scrollTop, clientHeight } = eGui; const { offsetTop, offsetHeight } = el; if (offsetTop + offsetHeight > scrollTop + clientHeight || offsetTop < scrollTop) { el.scrollIntoView({ block: "nearest" }); } if (!this.unFocusable) { el.focus(); } } clearHighlighted() { const highlightedEl = this.highlightedEl; if (!highlightedEl || !_isVisible(highlightedEl)) { return; } highlightedEl.classList.remove(this.activeClass); _setAriaSelected(highlightedEl, false); this.highlightedEl = null; } fireChangeEvent() { this.dispatchLocalEvent({ type: "fieldValueChanged" }); this.fireItemSelected(); } fireItemSelected() { this.dispatchLocalEvent({ type: "selectedItem" }); } }; // packages/ag-grid-community/src/widgets/agPickerField.css-GENERATED.ts var agPickerFieldCSS = ( /*css*/ `.ag-picker-field-display{flex:1 1 auto}.ag-picker-field{align-items:center;display:flex}.ag-picker-field-icon{border:0;cursor:pointer;display:flex;margin:0;padding:0}.ag-picker-field-wrapper{background-color:var(--ag-picker-button-background-color);border:var(--ag-picker-button-border);border-radius:5px;min-height:max(var(--ag-list-item-height),calc(var(--ag-spacing)*4));overflow:hidden;&:disabled{opacity:.5}&.ag-picker-has-focus,&:focus-within{background-color:var(--ag-picker-button-focus-background-color);border:var(--ag-picker-button-focus-border);box-shadow:var(--ag-focus-shadow)}}` ); // packages/ag-grid-community/src/widgets/agPickerField.ts var AgPickerField = class extends AgAbstractField { constructor(config) { super( config, config?.template || /* html */ ` `, config?.agComponents || [], config?.className ); this.isPickerDisplayed = false; this.skipClick = false; this.pickerGap = 4; this.hideCurrentPicker = null; this.eLabel = RefPlaceholder; this.eWrapper = RefPlaceholder; this.eDisplayField = RefPlaceholder; this.eIcon = RefPlaceholder; this.registerCSS(agPickerFieldCSS); this.ariaRole = config?.ariaRole; this.onPickerFocusIn = this.onPickerFocusIn.bind(this); this.onPickerFocusOut = this.onPickerFocusOut.bind(this); if (!config) { return; } const { pickerGap, maxPickerHeight, variableWidth, minPickerWidth, maxPickerWidth } = config; if (pickerGap != null) { this.pickerGap = pickerGap; } this.variableWidth = !!variableWidth; if (maxPickerHeight != null) { this.setPickerMaxHeight(maxPickerHeight); } if (minPickerWidth != null) { this.setPickerMinWidth(minPickerWidth); } if (maxPickerWidth != null) { this.setPickerMaxWidth(maxPickerWidth); } } postConstruct() { super.postConstruct(); this.setupAria(); const displayId = `ag-${this.getCompId()}-display`; this.eDisplayField.setAttribute("id", displayId); const ariaEl = this.getAriaElement(); this.addManagedElementListeners(ariaEl, { keydown: this.onKeyDown.bind(this) }); this.addManagedElementListeners(this.eLabel, { mousedown: this.onLabelOrWrapperMouseDown.bind(this) }); this.addManagedElementListeners(this.eWrapper, { mousedown: this.onLabelOrWrapperMouseDown.bind(this) }); const { pickerIcon, inputWidth } = this.config; if (pickerIcon) { const icon = _createIconNoSpan(pickerIcon, this.beans); if (icon) { this.eIcon.appendChild(icon); } } if (inputWidth != null) { this.setInputWidth(inputWidth); } } setupAria() { const ariaEl = this.getAriaElement(); ariaEl.setAttribute("tabindex", this.gos.get("tabIndex").toString()); _setAriaExpanded(ariaEl, false); if (this.ariaRole) { _setAriaRole(ariaEl, this.ariaRole); } } onLabelOrWrapperMouseDown(e) { if (e) { const focusableEl = this.getFocusableElement(); if (focusableEl !== this.eWrapper && e?.target === focusableEl) { return; } e.preventDefault(); this.getFocusableElement().focus(); } if (this.skipClick) { this.skipClick = false; return; } if (this.isDisabled()) { return; } if (this.isPickerDisplayed) { this.hidePicker(); } else { this.showPicker(); } } onKeyDown(e) { switch (e.key) { case KeyCode.UP: case KeyCode.DOWN: case KeyCode.ENTER: case KeyCode.SPACE: e.preventDefault(); this.onLabelOrWrapperMouseDown(); break; case KeyCode.ESCAPE: if (this.isPickerDisplayed) { e.preventDefault(); e.stopPropagation(); if (this.hideCurrentPicker) { this.hideCurrentPicker(); } } break; } } showPicker() { this.isPickerDisplayed = true; if (!this.pickerComponent) { this.pickerComponent = this.createPickerComponent(); } const pickerGui = this.pickerComponent.getGui(); pickerGui.addEventListener("focusin", this.onPickerFocusIn); pickerGui.addEventListener("focusout", this.onPickerFocusOut); this.hideCurrentPicker = this.renderAndPositionPicker(); this.toggleExpandedStyles(true); } renderAndPositionPicker() { const ePicker = this.pickerComponent.getGui(); if (!this.gos.get("suppressScrollWhenPopupsAreOpen")) { [this.destroyMouseWheelFunc] = this.addManagedEventListeners({ bodyScroll: () => { this.hidePicker(); } }); } const translate = this.getLocaleTextFunc(); const { config: { pickerAriaLabelKey, pickerAriaLabelValue, modalPicker = true }, maxPickerHeight, minPickerWidth, maxPickerWidth, variableWidth, beans, eWrapper } = this; const popupParams = { modal: modalPicker, eChild: ePicker, closeOnEsc: true, closedCallback: () => { const shouldRestoreFocus = _isNothingFocused(beans); this.beforeHidePicker(); if (shouldRestoreFocus && this.isAlive()) { this.getFocusableElement().focus(); } }, ariaLabel: translate(pickerAriaLabelKey, pickerAriaLabelValue), anchorToElement: eWrapper }; ePicker.style.position = "absolute"; const popupSvc = beans.popupSvc; const addPopupRes = popupSvc.addPopup(popupParams); if (variableWidth) { if (minPickerWidth) { ePicker.style.minWidth = minPickerWidth; } ePicker.style.width = _formatSize(_getAbsoluteWidth(eWrapper)); if (maxPickerWidth) { ePicker.style.maxWidth = maxPickerWidth; } } else { _setElementWidth(ePicker, maxPickerWidth ?? _getAbsoluteWidth(eWrapper)); } const maxHeight = maxPickerHeight ?? `${_getInnerHeight(popupSvc.getPopupParent())}px`; ePicker.style.setProperty("max-height", maxHeight); this.alignPickerToComponent(); return addPopupRes.hideFunc; } alignPickerToComponent() { if (!this.pickerComponent) { return; } const { pickerGap, config: { pickerType }, beans: { popupSvc, gos }, eWrapper, pickerComponent } = this; const alignSide = gos.get("enableRtl") ? "right" : "left"; popupSvc.positionPopupByComponent({ type: pickerType, eventSource: eWrapper, ePopup: pickerComponent.getGui(), position: "under", alignSide, keepWithinBounds: true, nudgeY: pickerGap }); } beforeHidePicker() { if (this.destroyMouseWheelFunc) { this.destroyMouseWheelFunc(); this.destroyMouseWheelFunc = void 0; } this.toggleExpandedStyles(false); const pickerGui = this.pickerComponent.getGui(); pickerGui.removeEventListener("focusin", this.onPickerFocusIn); pickerGui.removeEventListener("focusout", this.onPickerFocusOut); this.isPickerDisplayed = false; this.pickerComponent = void 0; this.hideCurrentPicker = null; } toggleExpandedStyles(expanded) { if (!this.isAlive()) { return; } const ariaEl = this.getAriaElement(); _setAriaExpanded(ariaEl, expanded); const classList = this.eWrapper.classList; classList.toggle("ag-picker-expanded", expanded); classList.toggle("ag-picker-collapsed", !expanded); } onPickerFocusIn() { this.togglePickerHasFocus(true); } onPickerFocusOut(e) { if (!this.pickerComponent?.getGui().contains(e.relatedTarget)) { this.togglePickerHasFocus(false); } } togglePickerHasFocus(focused) { if (!this.pickerComponent) { return; } this.eWrapper.classList.toggle("ag-picker-has-focus", focused); } hidePicker() { this.hideCurrentPicker?.(); } setInputWidth(width) { _setElementWidth(this.eWrapper, width); return this; } getFocusableElement() { return this.eWrapper; } setPickerGap(gap) { this.pickerGap = gap; return this; } setPickerMinWidth(width) { if (typeof width === "number") { width = `${width}px`; } this.minPickerWidth = width == null ? void 0 : width; return this; } setPickerMaxWidth(width) { if (typeof width === "number") { width = `${width}px`; } this.maxPickerWidth = width == null ? void 0 : width; return this; } setPickerMaxHeight(height) { if (typeof height === "number") { height = `${height}px`; } this.maxPickerHeight = height == null ? void 0 : height; return this; } destroy() { this.hidePicker(); super.destroy(); } }; // packages/ag-grid-community/src/widgets/agSelect.css-GENERATED.ts var agSelectCSS = ( /*css*/ `.ag-select{align-items:center;display:flex;&.ag-disabled{opacity:.5}}:where(.ag-select){.ag-picker-field-wrapper{cursor:default}&.ag-disabled .ag-picker-field-wrapper:focus{box-shadow:none}&:not(.ag-cell-editor,.ag-label-align-top){min-height:var(--ag-list-item-height)}.ag-picker-field-display{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ag-picker-field-icon{align-items:center;display:flex}}:where(.ag-ltr) :where(.ag-select){.ag-picker-field-wrapper{padding-left:calc(var(--ag-cell-horizontal-padding)/2);padding-right:var(--ag-spacing)}}:where(.ag-rtl) :where(.ag-select){.ag-picker-field-wrapper{padding-left:var(--ag-spacing);padding-right:calc(var(--ag-cell-horizontal-padding)/2)}}` ); // packages/ag-grid-community/src/widgets/agSelect.ts var AgSelect = class extends AgPickerField { constructor(config) { super({ pickerAriaLabelKey: "ariaLabelSelectField", pickerAriaLabelValue: "Select Field", pickerType: "ag-list", className: "ag-select", pickerIcon: "selectOpen", ariaRole: "combobox", ...config }); this.registerCSS(agSelectCSS); } postConstruct() { this.tooltipFeature = this.createOptionalManagedBean( this.beans.registry.createDynamicBean("tooltipFeature", false, { shouldDisplayTooltip: _shouldDisplayTooltip(() => this.eDisplayField), getGui: () => this.getGui() }) ); super.postConstruct(); this.createListComponent(); this.eWrapper.tabIndex = this.gos.get("tabIndex"); const { options, value, placeholder } = this.config; if (options != null) { this.addOptions(options); } if (value != null) { this.setValue(value, true); } if (placeholder && value == null) { this.eDisplayField.textContent = placeholder; } this.addManagedElementListeners(this.eWrapper, { focusout: this.onWrapperFocusOut.bind(this) }); } onWrapperFocusOut(e) { if (!this.eWrapper.contains(e.relatedTarget)) { this.hidePicker(); } } createListComponent() { const listComponent = this.createBean(new AgList("select", true)); this.listComponent = listComponent; listComponent.setParentComponent(this); const eListAriaEl = listComponent.getAriaElement(); const listId = `ag-select-list-${listComponent.getCompId()}`; eListAriaEl.setAttribute("id", listId); _setAriaControls(this.getAriaElement(), eListAriaEl); listComponent.addManagedElementListeners(listComponent.getGui(), { mousedown: (e) => { e?.preventDefault(); } }); listComponent.addManagedListeners(listComponent, { selectedItem: () => { this.hidePicker(); this.dispatchLocalEvent({ type: "selectedItem" }); }, fieldValueChanged: () => { if (!this.listComponent) { return; } this.setValue(this.listComponent.getValue(), false, true); this.hidePicker(); } }); } createPickerComponent() { return this.listComponent; } onKeyDown(e) { const { key } = e; if (key === KeyCode.TAB) { this.hidePicker(); } switch (key) { case KeyCode.ENTER: case KeyCode.UP: case KeyCode.DOWN: case KeyCode.PAGE_UP: case KeyCode.PAGE_DOWN: case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: e.preventDefault(); if (this.isPickerDisplayed) { this.listComponent?.handleKeyDown(e); } else { super.onKeyDown(e); } break; case KeyCode.ESCAPE: super.onKeyDown(e); break; case KeyCode.SPACE: if (this.isPickerDisplayed) { e.preventDefault(); } else { super.onKeyDown(e); } break; } } showPicker() { const listComponent = this.listComponent; if (!listComponent) { return; } super.showPicker(); listComponent.refreshHighlighted(); } addOptions(options) { options.forEach((option) => this.addOption(option)); return this; } addOption(option) { this.listComponent.addOption(option); return this; } clearOptions() { this.listComponent?.clearOptions(); return this; } setValue(value, silent, fromPicker) { const { listComponent, config: { placeholder }, eDisplayField, tooltipFeature } = this; if (this.value === value || !listComponent) { return this; } if (!fromPicker) { listComponent.setValue(value, true); } const newValue = listComponent.getValue(); if (newValue === this.getValue()) { return this; } let displayValue = listComponent.getDisplayValue(); if (displayValue == null && placeholder) { displayValue = placeholder; } eDisplayField.textContent = displayValue; tooltipFeature?.setTooltipAndRefresh(displayValue ?? null); return super.setValue(value, silent); } destroy() { this.listComponent = this.destroyBean(this.listComponent); super.destroy(); } }; var AgSelectSelector = { selector: "AG-SELECT", component: AgSelect }; // packages/ag-grid-community/src/widgets/tabGuardCtrl.ts var TabGuardClassNames = { TAB_GUARD: "ag-tab-guard", TAB_GUARD_TOP: "ag-tab-guard-top", TAB_GUARD_BOTTOM: "ag-tab-guard-bottom" }; var TabGuardCtrl = class extends BeanStub { constructor(params) { super(); this.skipTabGuardFocus = false; this.forcingFocusOut = false; // Used when `isFocusableContainer` enabled this.allowFocus = false; const { comp, eTopGuard, eBottomGuard, focusTrapActive, forceFocusOutWhenTabGuardsAreEmpty, isFocusableContainer, focusInnerElement, onFocusIn, onFocusOut, shouldStopEventPropagation, onTabKeyDown, handleKeyDown, isEmpty, eFocusableElement } = params; this.comp = comp; this.eTopGuard = eTopGuard; this.eBottomGuard = eBottomGuard; this.providedFocusInnerElement = focusInnerElement; this.eFocusableElement = eFocusableElement; this.focusTrapActive = !!focusTrapActive; this.forceFocusOutWhenTabGuardsAreEmpty = !!forceFocusOutWhenTabGuardsAreEmpty; this.isFocusableContainer = !!isFocusableContainer; this.providedFocusIn = onFocusIn; this.providedFocusOut = onFocusOut; this.providedShouldStopEventPropagation = shouldStopEventPropagation; this.providedOnTabKeyDown = onTabKeyDown; this.providedHandleKeyDown = handleKeyDown; this.providedIsEmpty = isEmpty; } postConstruct() { this.createManagedBean( new ManagedFocusFeature(this.eFocusableElement, { shouldStopEventPropagation: () => this.shouldStopEventPropagation(), onTabKeyDown: (e) => this.onTabKeyDown(e), handleKeyDown: (e) => this.handleKeyDown(e), onFocusIn: (e) => this.onFocusIn(e), onFocusOut: (e) => this.onFocusOut(e) }) ); this.activateTabGuards(); [this.eTopGuard, this.eBottomGuard].forEach( (guard) => this.addManagedElementListeners(guard, { focus: this.onFocus.bind(this) }) ); } handleKeyDown(e) { if (this.providedHandleKeyDown) { this.providedHandleKeyDown(e); } } tabGuardsAreActive() { return !!this.eTopGuard && this.eTopGuard.hasAttribute("tabIndex"); } shouldStopEventPropagation() { if (this.providedShouldStopEventPropagation) { return this.providedShouldStopEventPropagation(); } return false; } activateTabGuards() { if (this.forcingFocusOut) { return; } const tabIndex = this.gos.get("tabIndex"); this.comp.setTabIndex(tabIndex.toString()); } deactivateTabGuards() { this.comp.setTabIndex(); } onFocus(e) { if (this.isFocusableContainer && !this.eFocusableElement.contains(e.relatedTarget)) { if (!this.allowFocus) { this.findNextElementOutsideAndFocus(e.target === this.eBottomGuard); return; } } if (this.skipTabGuardFocus) { this.skipTabGuardFocus = false; return; } if (this.forceFocusOutWhenTabGuardsAreEmpty) { const isEmpty = this.providedIsEmpty ? this.providedIsEmpty() : _findFocusableElements(this.eFocusableElement, ".ag-tab-guard").length === 0; if (isEmpty) { this.findNextElementOutsideAndFocus(e.target === this.eBottomGuard); return; } } if (this.isFocusableContainer && this.eFocusableElement.contains(e.relatedTarget)) { return; } const fromBottom = e.target === this.eBottomGuard; const hasFocusedInnerElement = this.providedFocusInnerElement ? this.providedFocusInnerElement(fromBottom) : this.focusInnerElement(fromBottom); if (!hasFocusedInnerElement && this.forceFocusOutWhenTabGuardsAreEmpty) { this.findNextElementOutsideAndFocus(e.target === this.eBottomGuard); } } findNextElementOutsideAndFocus(up) { const eDocument = _getDocument(this.beans); const focusableEls = _findFocusableElements(eDocument.body, null, true); const index = focusableEls.indexOf(up ? this.eTopGuard : this.eBottomGuard); if (index === -1) { return; } let start; let end; if (up) { start = 0; end = index; } else { start = index + 1; end = focusableEls.length; } const focusableRange = focusableEls.slice(start, end); const targetTabIndex = this.gos.get("tabIndex"); focusableRange.sort((a, b) => { const indexA = parseInt(a.getAttribute("tabindex") || "0"); const indexB = parseInt(b.getAttribute("tabindex") || "0"); if (indexB === targetTabIndex) { return 1; } if (indexA === targetTabIndex) { return -1; } if (indexA === 0) { return 1; } if (indexB === 0) { return -1; } return indexA - indexB; }); focusableRange[up ? focusableRange.length - 1 : 0]?.focus(); } onFocusIn(e) { if (this.focusTrapActive || this.forcingFocusOut) { return; } if (this.providedFocusIn) { this.providedFocusIn(e); } if (!this.isFocusableContainer) { this.deactivateTabGuards(); } } onFocusOut(e) { if (this.focusTrapActive) { return; } if (this.providedFocusOut) { this.providedFocusOut(e); } if (!this.eFocusableElement.contains(e.relatedTarget)) { this.activateTabGuards(); } } onTabKeyDown(e) { if (this.providedOnTabKeyDown) { this.providedOnTabKeyDown(e); return; } if (this.focusTrapActive) { return; } if (e.defaultPrevented) { return; } const tabGuardsAreActive = this.tabGuardsAreActive(); if (tabGuardsAreActive) { this.deactivateTabGuards(); } const nextRoot = this.getNextFocusableElement(e.shiftKey); if (tabGuardsAreActive) { setTimeout(() => this.activateTabGuards(), 0); } if (!nextRoot) { return; } nextRoot.focus(); e.preventDefault(); } focusInnerElement(fromBottom = false) { const focusable = _findFocusableElements(this.eFocusableElement); if (this.tabGuardsAreActive()) { focusable.splice(0, 1); focusable.splice(focusable.length - 1, 1); } if (!focusable.length) { return false; } focusable[fromBottom ? focusable.length - 1 : 0].focus({ preventScroll: true }); return true; } getNextFocusableElement(backwards) { return _findNextFocusableElement(this.beans, this.eFocusableElement, false, backwards); } forceFocusOutOfContainer(up = false) { if (this.forcingFocusOut) { return; } const tabGuardToFocus = up ? this.eTopGuard : this.eBottomGuard; this.activateTabGuards(); this.skipTabGuardFocus = true; this.forcingFocusOut = true; tabGuardToFocus.focus(); window.setTimeout(() => { this.forcingFocusOut = false; this.activateTabGuards(); }); } isTabGuard(element, bottom) { return element === this.eTopGuard && !bottom || element === this.eBottomGuard && (bottom ?? true); } setAllowFocus(allowFocus) { this.allowFocus = allowFocus; } }; // packages/ag-grid-community/src/widgets/tabGuardFeature.ts var TabGuardFeature = class extends BeanStub { constructor(comp) { super(); this.comp = comp; } initialiseTabGuard(params) { this.eTopGuard = this.createTabGuard("top"); this.eBottomGuard = this.createTabGuard("bottom"); this.eFocusableElement = this.comp.getFocusableElement(); const { eTopGuard, eBottomGuard, eFocusableElement } = this; const tabGuards = [eTopGuard, eBottomGuard]; const compProxy = { setTabIndex: (tabIndex) => { tabGuards.forEach( (tabGuard) => tabIndex != null ? tabGuard.setAttribute("tabindex", tabIndex) : tabGuard.removeAttribute("tabindex") ); } }; this.addTabGuards(eTopGuard, eBottomGuard); const { focusTrapActive = false, onFocusIn, onFocusOut, focusInnerElement, handleKeyDown, onTabKeyDown, shouldStopEventPropagation, isEmpty, forceFocusOutWhenTabGuardsAreEmpty, isFocusableContainer } = params; this.tabGuardCtrl = this.createManagedBean( new TabGuardCtrl({ comp: compProxy, focusTrapActive, eTopGuard, eBottomGuard, eFocusableElement, onFocusIn, onFocusOut, focusInnerElement, handleKeyDown, onTabKeyDown, shouldStopEventPropagation, isEmpty, forceFocusOutWhenTabGuardsAreEmpty, isFocusableContainer }) ); } getTabGuardCtrl() { return this.tabGuardCtrl; } createTabGuard(side) { const tabGuard = _getDocument(this.beans).createElement("div"); const cls = side === "top" ? TabGuardClassNames.TAB_GUARD_TOP : TabGuardClassNames.TAB_GUARD_BOTTOM; tabGuard.classList.add(TabGuardClassNames.TAB_GUARD, cls); _setAriaRole(tabGuard, "presentation"); return tabGuard; } addTabGuards(topTabGuard, bottomTabGuard) { const eFocusableElement = this.eFocusableElement; eFocusableElement.insertAdjacentElement("afterbegin", topTabGuard); eFocusableElement.insertAdjacentElement("beforeend", bottomTabGuard); } removeAllChildrenExceptTabGuards() { const tabGuards = [this.eTopGuard, this.eBottomGuard]; _clearElement(this.comp.getFocusableElement()); this.addTabGuards(...tabGuards); } forceFocusOutOfContainer(up = false) { this.tabGuardCtrl.forceFocusOutOfContainer(up); } appendChild(appendChild, newChild, container) { if (!_isNodeOrElement(newChild)) { newChild = newChild.getGui(); } const { eBottomGuard: bottomTabGuard } = this; if (bottomTabGuard) { bottomTabGuard.insertAdjacentElement("beforebegin", newChild); } else { appendChild(newChild, container); } } destroy() { const { eFocusableElement, eTopGuard, eBottomGuard } = this; eFocusableElement.removeChild(eTopGuard); eFocusableElement.removeChild(eBottomGuard); super.destroy(); } }; // packages/ag-grid-community/src/widgets/tabGuardComp.ts var TabGuardComp = class extends Component { initialiseTabGuard(params) { this.tabGuardFeature = this.createManagedBean(new TabGuardFeature(this)); this.tabGuardFeature.initialiseTabGuard(params); } forceFocusOutOfContainer(up = false) { this.tabGuardFeature.forceFocusOutOfContainer(up); } appendChild(newChild, container) { this.tabGuardFeature.appendChild(super.appendChild.bind(this), newChild, container); } }; // packages/ag-grid-community/src/widgets/popupComponent.ts var PopupComponent = class extends Component { isPopup() { return true; } setParentComponent(container) { container.addCssClass("ag-has-popup"); super.setParentComponent(container); } destroy() { const parentComp = this.parentComponent; const hasParent = parentComp && parentComp.isAlive(); if (hasParent) { parentComp.getGui().classList.remove("ag-has-popup"); } super.destroy(); } }; // packages/ag-grid-community/src/widgets/touchListener.ts var TouchListener = class { constructor(eElement, preventMouseClick = false) { this.DOUBLE_TAP_MILLIS = 500; this.destroyFuncs = []; this.touching = false; this.localEventService = new LocalEventService(); this.preventMouseClick = preventMouseClick; const startListener = this.onTouchStart.bind(this); const moveListener = this.onTouchMove.bind(this); const endListener = this.onTouchEnd.bind(this); eElement.addEventListener("touchstart", startListener, { passive: true }); eElement.addEventListener("touchmove", moveListener, { passive: true }); eElement.addEventListener("touchend", endListener, { passive: false }); this.destroyFuncs.push(() => { eElement.removeEventListener("touchstart", startListener, { passive: true }); eElement.removeEventListener("touchmove", moveListener, { passive: true }); eElement.removeEventListener("touchend", endListener, { passive: false }); }); } getActiveTouch(touchList) { for (let i = 0; i < touchList.length; i++) { const matches = touchList[i].identifier === this.touchStart.identifier; if (matches) { return touchList[i]; } } return null; } addEventListener(eventType, listener) { this.localEventService.addEventListener(eventType, listener); } removeEventListener(eventType, listener) { this.localEventService.removeEventListener(eventType, listener); } onTouchStart(touchEvent) { if (this.touching) { return; } this.touchStart = touchEvent.touches[0]; this.touching = true; this.moved = false; const touchStartCopy = this.touchStart; window.setTimeout(() => { const touchesMatch = this.touchStart === touchStartCopy; if (this.touching && touchesMatch && !this.moved) { this.moved = true; const event = { type: "longTap", touchStart: this.touchStart, touchEvent }; this.localEventService.dispatchEvent(event); } }, 500); } onTouchMove(touchEvent) { if (!this.touching) { return; } const touch = this.getActiveTouch(touchEvent.touches); if (!touch) { return; } const eventIsFarAway = !_areEventsNear(touch, this.touchStart, 4); if (eventIsFarAway) { this.moved = true; } } onTouchEnd(touchEvent) { if (!this.touching) { return; } if (!this.moved) { const event = { type: "tap", touchStart: this.touchStart }; this.localEventService.dispatchEvent(event); this.checkForDoubleTap(); } if (this.preventMouseClick && touchEvent.cancelable) { touchEvent.preventDefault(); } this.touching = false; } checkForDoubleTap() { const now = (/* @__PURE__ */ new Date()).getTime(); if (this.lastTapTime && this.lastTapTime > 0) { const interval = now - this.lastTapTime; if (interval > this.DOUBLE_TAP_MILLIS) { const event = { type: "doubleTap", touchStart: this.touchStart }; this.localEventService.dispatchEvent(event); this.lastTapTime = null; } else { this.lastTapTime = now; } } else { this.lastTapTime = now; } } destroy() { this.destroyFuncs.forEach((func) => func()); } }; // packages/ag-grid-community/src/interfaces/IRangeService.ts var CellRangeType = /* @__PURE__ */ ((CellRangeType2) => { CellRangeType2[CellRangeType2["VALUE"] = 0] = "VALUE"; CellRangeType2[CellRangeType2["DIMENSION"] = 1] = "DIMENSION"; return CellRangeType2; })(CellRangeType || {}); // packages/ag-grid-community/src/vanillaFrameworkOverrides.ts var VanillaFrameworkOverrides = class { constructor(frameworkName = "javascript") { this.frameworkName = frameworkName; this.renderingEngine = "vanilla"; this.wrapIncoming = (callback) => callback(); this.wrapOutgoing = (callback) => callback(); this.baseDocLink = `${BASE_URL}/${this.frameworkName}-data-grid`; setValidationDocLink(this.baseDocLink); } setInterval(action, timeout) { return new AgPromise((resolve) => { resolve(window.setInterval(action, timeout)); }); } // for Vanilla JS, we just add the event to the element addEventListener(element, type, listener, options) { let eventListenerOptions = {}; if (typeof options === "object") { eventListenerOptions = options; } else if (typeof options === "boolean") { eventListenerOptions = { capture: options }; } if (eventListenerOptions.passive == null) { const passive = getPassiveStateForEvent(type); if (passive != null) { eventListenerOptions.passive = passive; } } element.addEventListener(type, listener, eventListenerOptions); } frameworkComponent(_) { return null; } isFrameworkComponent(_) { return false; } getDocLink(path) { return `${this.baseDocLink}${path ? `/${path}` : ""}`; } }; // packages/ag-grid-community/src/api/apiUtils.ts function createGridApi(context) { return { beanName: "gridApi", bean: context.getBean("apiFunctionSvc").api }; } // packages/ag-grid-community/src/context/gridBeanComparator.ts var orderedCoreBeans = [ // Validate license first "licenseManager", // core beans only "environment", "eventSvc", "gos", "paginationAutoPageSizeSvc", "apiFunctionSvc", "gridApi", "registry", "agCompUtils", "userCompFactory", "rowContainerHeight", "horizontalResizeSvc", "localeSvc", "pinnedRowModel", "dragSvc", "colGroupSvc", "visibleCols", "popupSvc", "selectionSvc", "colFilter", "quickFilter", "filterManager", "colModel", "headerNavigation", "pageBounds", "pagination", "rowSpanSvc", "pageBoundsListener", "stickyRowSvc", "rowRenderer", "expressionSvc", "alignedGridsSvc", "navigation", "valueCache", "valueSvc", "autoWidthCalc", "filterMenuFactory", "dragAndDrop", "focusSvc", "cellNavigation", "cellStyles", "scrollVisibleSvc", "sortSvc", "colHover", "colAnimation", "autoColSvc", "selectionColSvc", "changeDetectionSvc", "animationFrameSvc", "undoRedo", "colDefFactory", "rowStyleSvc", "rowNodeBlockLoader", "rowNodeSorter", "ctrlsSvc", "pinnedCols", "dataTypeSvc", "syncSvc", "overlays", "stateSvc", "expansionSvc", "apiEventSvc", "ariaAnnounce", "menuSvc", "colMoves", "colAutosize", "colFlex", "colResize", "pivotColsSvc", "valueColsSvc", "rowGroupColsSvc", "funcColsSvc", "colNames", "colViewport", "pivotResultCols", "showRowGroupCols", "validation" // Have validations run last ]; var beanNamePosition = Object.fromEntries( orderedCoreBeans.map((beanName, index) => [beanName, index]) ); function gridBeanInitComparator(bean1, bean2) { const index1 = (bean1.beanName ? beanNamePosition[bean1.beanName] : void 0) ?? Number.MAX_SAFE_INTEGER; const index2 = (bean2.beanName ? beanNamePosition[bean2.beanName] : void 0) ?? Number.MAX_SAFE_INTEGER; return index1 - index2; } function gridBeanDestroyComparator(bean1, bean2) { return bean1?.beanName === "gridDestroySvc" ? -1 : 0; } // packages/ag-grid-community/src/headerRendering/rowContainer/headerRowContainerComp.ts var PINNED_LEFT_TEMPLATE = ( /* html */ `
` ); var PINNED_RIGHT_TEMPLATE = ( /* html */ `
` ); var CENTER_TEMPLATE = ( /* html */ `` ); var HeaderRowContainerComp = class extends Component { constructor(pinned) { super(); this.eCenterContainer = RefPlaceholder; this.headerRowComps = {}; this.rowCompsList = []; this.pinned = pinned; } postConstruct() { this.selectAndSetTemplate(); const compProxy = { setDisplayed: (displayed) => this.setDisplayed(displayed), setCtrls: (ctrls) => this.setCtrls(ctrls), // only gets called for center section setCenterWidth: (width) => this.eCenterContainer.style.width = width, setViewportScrollLeft: (left) => this.getGui().scrollLeft = left, // only gets called for pinned sections setPinnedContainerWidth: (width) => { const eGui = this.getGui(); eGui.style.width = width; eGui.style.maxWidth = width; eGui.style.minWidth = width; } }; const ctrl = this.createManagedBean(new HeaderRowContainerCtrl(this.pinned)); ctrl.setComp(compProxy, this.getGui()); } selectAndSetTemplate() { const pinnedLeft = this.pinned == "left"; const pinnedRight = this.pinned == "right"; const template = pinnedLeft ? PINNED_LEFT_TEMPLATE : pinnedRight ? PINNED_RIGHT_TEMPLATE : CENTER_TEMPLATE; this.setTemplate(template); this.eRowContainer = this.eCenterContainer !== RefPlaceholder ? this.eCenterContainer : this.getGui(); } destroy() { this.setCtrls([]); super.destroy(); } destroyRowComp(rowComp) { this.destroyBean(rowComp); this.eRowContainer.removeChild(rowComp.getGui()); } setCtrls(ctrls) { const oldRowComps = this.headerRowComps; this.headerRowComps = {}; this.rowCompsList = []; let prevGui; const appendEnsuringDomOrder = (rowComp) => { const eGui = rowComp.getGui(); const notAlreadyIn = eGui.parentElement != this.eRowContainer; if (notAlreadyIn) { this.eRowContainer.appendChild(eGui); } if (prevGui) { _ensureDomOrder(this.eRowContainer, eGui, prevGui); } prevGui = eGui; }; ctrls.forEach((ctrl) => { const ctrlId = ctrl.instanceId; const existingComp = oldRowComps[ctrlId]; delete oldRowComps[ctrlId]; const rowComp = existingComp ? existingComp : this.createBean(new HeaderRowComp(ctrl)); this.headerRowComps[ctrlId] = rowComp; this.rowCompsList.push(rowComp); appendEnsuringDomOrder(rowComp); }); Object.values(oldRowComps).forEach((c) => this.destroyRowComp(c)); } }; // packages/ag-grid-community/src/headerRendering/gridHeaderComp.ts var GridHeaderComp = class extends Component { constructor() { super( /* html */ `