import type { ColumnDef } from '../types/column.types'; import type { ColumnModel } from '../core/column-model'; import type { SortEngine } from '../engines/sort/sort-engine'; import type { EventBus } from '../event-bus/event-bus'; import type { IconRenderer } from '../icons/icon-renderer'; import { ColumnMenuSection, AggregateFunction } from '../types/column-menu.types'; import type { ColumnMenuConfig, GetColumnMenuItems } from '../types/column-menu.types'; /** * Re-exported for backwards compatibility. The canonical definitions now live in * `types/column-menu.types.ts` and are the public export surface. */ export { ColumnMenuSection, AggregateFunction }; /** * @deprecated Use {@link ColumnMenuConfig}. Retained as an alias so existing * imports keep compiling. */ export type ColumnMenuOptions = ColumnMenuConfig; /** * Callbacks for operations that the column context menu delegates to the * surrounding grid infrastructure (auto-size, clipboard, filter panel, etc.). * * All properties are optional — supply only those the grid supports. */ export interface ColumnMenuCallbacks { /** Auto-size the column to fit its content. */ onAutoSize: (colId: string) => void; /** Auto-size every visible column. */ onAutoSizeAll: () => void; /** Fit all visible columns proportionally to the grid's available width. */ onFitToGrid: () => void; /** Reset this column's width to its original `ColumnDef.width` value. */ onResetWidth: (colId: string) => void; /** Open the column chooser / visibility picker dialog. */ onOpenColumnChooser: () => void; /** * Open the advanced filter panel for this column. * The second argument is a suggested anchor element for positioning — may be * a menu button or the column header itself. */ onOpenAdvancedFilter: (colDef: ColumnDef, anchorEl: HTMLElement) => void; /** Focus the quick-filter input row cell for this column. */ onQuickFilter: (colId: string) => void; /** Copy the column's header text to the system clipboard. */ onCopyHeader: (colDef: ColumnDef) => void; /** Copy all visible cell values in this column to the system clipboard. */ onCopyColumn: (colDef: ColumnDef) => void; /** Copy the unique cell values of this column to the system clipboard. */ onCopyValues: (colDef: ColumnDef) => void; /** Initiate an inline rename of this column header. */ onRename: (colDef: ColumnDef) => void; /** Insert a duplicate of this column directly after it. */ onDuplicate: (colDef: ColumnDef) => void; /** Toggle "frozen position" — the column cannot be dragged. */ onFreezePosition: (colDef: ColumnDef) => void; /** Toggle "locked" — the column's cells cannot be edited. */ onLockColumn: (colDef: ColumnDef) => void; /** Reset all column state (width, sort, filter, pin) back to the original definition. */ onResetColumn: (colDef: ColumnDef) => void; /** Apply an aggregate function to this column. */ onAggregate: (colDef: ColumnDef, func: AggregateFunction) => void; /** Move this column one position to the left. */ onMoveLeft: (colId: string) => void; /** Move this column one position to the right. */ onMoveRight: (colId: string) => void; /** Move this column to the first position. */ onMoveStart: (colId: string) => void; /** Move this column to the last position. */ onMoveEnd: (colId: string) => void; } /** * Callbacks for row-grouping integration. * Optional — pass to {@link ColumnMenu.setGroupCallbacks} only when the grid * uses row grouping. */ export interface GroupCallbacks { /** Returns `true` when the given column is currently part of the row grouping. */ isGrouped: (colId: string) => boolean; /** Add this column to the active row grouping. */ addGroup: (colId: string) => void; /** Remove this column from the active row grouping. */ removeGroup: (colId: string) => void; } /** * Full-featured column context menu for PhotonGrid flat column headers. * * ### Sections * Nine configurable sections are supported (see {@link ColumnMenuSection}): * Sort, Filter, Pin (submenu), Move, Resize (submenu), Visibility (submenu), * Data (Group by + Aggregate submenu), Clipboard (submenu), Column (submenu). * * ### Submenus * Parent items (Pin, Resize, Visibility, Clipboard, Column, and Aggregate) * reveal fly-out submenus on hover. Submenus are automatically flipped * horizontally when they would overflow the viewport's right edge. * * ### CSS * All visual styling is driven by theme CSS variables (`--pg-colors-*`, * `--pg-typography-*`, etc.) — no inline style declarations. * * ### Usage * ```ts * const menu = new ColumnMenu(columnModel, sortEngine, eventBus, iconRenderer, onAction); * menu.setMenuCallbacks({ onAutoSize: (id) => api.autoSizeColumn(id), … }); * menu.setMenuOptions({ sections: [ColumnMenuSection.SORT, ColumnMenuSection.PIN] }); * * // Trigger from ⋯ button * menuBtn.addEventListener('click', () => menu.show(colDef, menuBtn)); * // Trigger from right-click * th.addEventListener('contextmenu', (e) => { e.preventDefault(); menu.show(colDef, th, e.clientX, e.clientY); }); * ``` */ export declare class ColumnMenu { private readonly columnModel; private readonly sortEngine; private readonly eventBus; private readonly iconRenderer; private readonly onAction; private el; private anchorEl; private outsideClickFn; private escKeyFn; private openSubmenuTimer; private closeSubmenuTimer; private activeSubmenuEl; /** * Maps each submenu to the parent item that opens it. Needed because * submenus are portaled to `document.body` (see {@link openSubmenu}) rather * than left nested inside their parent item, so `.closest()` can no longer * find the owning item once a submenu is detached. */ private submenuParents; /** * Reverse of {@link submenuParents}: maps each submenu-parent item to its * (portaled) submenu. Lets the keyboard controller open a submenu by parent * without a linear scan. */ private itemSubmenus; /** Keyboard navigation controller — created per open, destroyed on hide. */ private keyboardController; private groupCallbacks; private menuCallbacks; private menuOptions; /** Host-supplied final item transform (AG-Grid-style). `null` when unset. */ private getItemsFn; /** The grid's public API, handed to custom-item actions. `null` until wired. */ private api; constructor(columnModel: ColumnModel, sortEngine: SortEngine, eventBus: EventBus, iconRenderer: IconRenderer, onAction: (action: string, colId: string) => void); /** * Register callbacks for operations that are delegated outside the menu class. * Call this once after construction — all callbacks are optional. */ setMenuCallbacks(callbacks: Partial): void; /** * Configure which sections and items appear and whether right-click is * supported. Call this once after construction or whenever options change. * * @param options - Grid-wide column-menu configuration. Per-column overrides * supplied via {@link ColumnDef.menu} are layered on top at show time. */ setMenuOptions(options: ColumnMenuConfig): void; /** * Register the AG-Grid-style hook that fully controls the resolved item list. * When set, its return value is authoritative for every column's menu. * * @param fn - Receives the default (post-suppression) built-in item ids and the * column, and returns the exact ordered items to render. Pass `undefined` to clear. */ setColumnMenuItemsCallback(fn: GetColumnMenuItems | undefined): void; /** * Provide the grid's public API, forwarded to custom-item actions via * {@link ColumnMenuItemContext.api}. Late-bound because the API does not exist * until after the grid is constructed. * * @param api - The owning grid's `GridApi` (typed `unknown` to avoid a cycle). */ setMenuApi(api: unknown): void; /** * Whether right-clicking a header cell should open this menu for `colDef`. * Resolves the per-column value over the grid-wide value, defaulting to `true`. * * @param colDef - The column whose header was right-clicked. */ isRightClickEnabled(colDef: ColumnDef): boolean; /** * Register row-grouping integration callbacks. * Required to enable the "Group by Column" item in the Data section. */ setGroupCallbacks(callbacks: GroupCallbacks): void; /** * Show the context menu for `colDef`. * * @param colDef - Column the menu operates on. * @param anchorEl - Element that triggered the menu (⋯ button or column header). * @param clientX - Viewport X for right-click positioning; omit for button positioning. * @param clientY - Viewport Y for right-click positioning; omit for button positioning. */ show(colDef: ColumnDef, anchorEl: HTMLElement, clientX?: number, clientY?: number): void; /** Build the {@link MenuKeyboardHost} adapter for this menu instance. */ private buildKeyboardHost; /** Hide and remove the menu from the DOM. */ hide(): void; /** Destroy the instance and release all resources. */ destroy(): void; private buildMenu; /** * Build the ordered, filtered top-level descriptors grouped by separator group, * plus a lookup by id. Applies the enabled-sections filter and the grid∪column * suppression set, and strips suppressed submenu children (dropping a parent * left with no children). * * @param colDef - The column the menu is opening for. */ private collectDescriptors; /** Union of the grid-wide and per-column `suppressItems` sets. */ private resolveSuppressSet; /** * Returns the item with suppressed children removed. Leaves pass through * unchanged; a parent whose children are all suppressed returns `null`. */ private applyChildSuppression; /** * Merge grid-wide and per-column custom items. Grid items come first, then * column items; entries sharing an `id` are de-duplicated with the column * item winning. */ private resolveCustomItems; /** Render a host-supplied `ColumnMenuItem[]` model into `menu`. */ private renderModel; /** Append a built-in leaf or parent descriptor to `menu`. */ private renderBuiltin; /** Append a custom leaf (or fly-out parent) to `menu`. */ private renderCustom; /** Build the {@link ColumnMenuItemContext} handed to custom-item actions. */ private makeItemContext; private buildLeafItem; private buildParentItem; private buildSubmenu; /** * Build a clickable custom leaf item. Invokes `item.action` with the column * context, then closes the menu. A disabled item is rendered but inert. */ private buildCustomLeaf; /** * Build a custom fly-out parent item. Its children are rendered as custom * leaves in a portaled submenu, reusing the same hover/keyboard machinery as * the built-in submenus. */ private buildCustomParent; /** * Wire the open/close hover behaviour for a parent item + its submenu. * Uses a short open delay (60 ms) and a close grace period (150 ms) to * prevent flicker when the mouse transitions between the item and the submenu. */ private attachSubmenuListeners; /** * Portal a submenu alongside its parent menu and position it in viewport * coordinates. Portaling (rather than nesting it under its parent item) * keeps it clear of the parent menu's `overflow-y: auto` clipping, so a * fly-out can render correctly even while the menu body is scrolled. * * `parentItem` already sits inside the owning grid's portal host, so resolving * from it keeps the submenu on the same theme as the menu it flew out of. */ private openSubmenu; /** Close and detach a portaled submenu opened via {@link openSubmenu}. */ private closeSubmenu; private clearSubmenuTimers; private buildAllSections; /** * Sort section — three flat items: Sort Ascending, Sort Descending, Clear Sort. */ private buildSortSection; /** * Filter section — a single flat item that opens the advanced filter panel. */ private buildFilterSection; /** * Pin section — a single parent item whose submenu has Pin Left / Pin Right / Unpin. */ private buildPinSection; /** * Move section — four flat items. Shares a separator group with Pin. * Items are disabled when the column is already at the respective edge. */ private buildMoveSection; /** * Resize section — a single parent item whose submenu has four resize operations. */ private buildResizeSection; /** * Visibility section — a single parent item: Hide Column + Column Chooser. */ private buildVisibilitySection; /** * Data section — Group by Column (flat leaf) + Aggregate (parent with submenu). * "Group by Column" is omitted when the column is not `groupable` or when no * {@link GroupCallbacks} have been registered. */ private buildDataSection; /** * Clipboard section — a single parent item: Copy Header / Copy Column / Copy Values. */ private buildClipboardSection; /** * Column section — a single parent item: Rename / Duplicate / Freeze / Lock / Reset. */ private buildColumnSection; private createSeparator; private createIcon; private createLabel; /** * Position the menu relative to the anchor element (button click) or at the * cursor (right-click). The menu is clamped to the visible viewport. */ private positionMenu; /** * Position a fly-out submenu in viewport coordinates: opens to the right of * the parent item, flipping to the left when it would overflow the * viewport's right edge, and clamped upward when it would overflow the * bottom. Called once each time the submenu becomes visible. * * The submenu is a `position: fixed` element portaled to document.body * (see {@link openSubmenu}), so coordinates are absolute viewport * positions rather than offsets relative to the parent item. */ private adjustSubmenuPosition; } //# sourceMappingURL=column-menu.d.ts.map