import { PluginQuery } from './plugin/base-plugin';
import { AfterCellRenderContext, AfterRowRenderContext, CellMouseEvent } from './plugin/types';
/**
 * The compiled webcomponent interface for DataGrid
 */
export interface DataGridElement extends PublicGrid, HTMLElement {
}
/**
 * Public API interface for DataGrid component.
 *
 * **Property Getters vs Setters:**
 *
 * Property getters return the EFFECTIVE (resolved) value after merging all config sources.
 * This is the "current situation" - what consumers and plugins need to know.
 *
 * Property setters accept input values which are merged into the effective config.
 * Multiple sources can contribute (gridConfig, columns prop, light DOM, individual props).
 *
 * For example:
 * - `grid.fitMode` returns the resolved fitMode (e.g., 'stretch' even if you set undefined)
 * - `grid.columns` returns the effective columns after merging
 * - `grid.gridConfig` returns the full effective config
 */
export interface PublicGrid<T = any> {
    /**
     * Full config object. Setter merges with other inputs per precedence rules.
     * Getter returns the effective (resolved) config.
     */
    gridConfig?: GridConfig<T>;
    /**
     * Column definitions.
     * Getter returns effective columns (after merging config, light DOM, inference).
     */
    columns?: ColumnConfig<T>[];
    /** Current row data (after plugin processing like grouping, filtering). */
    rows?: T[];
    /** Resolves once the component has finished initial work (layout, inference). */
    ready?: () => Promise<void>;
    /** Force a layout / measurement pass (e.g. after container resize). */
    forceLayout?: () => Promise<void>;
    /** Return effective resolved config (after inference & precedence). */
    getConfig?: () => Promise<Readonly<GridConfig<T>>>;
    /** Toggle expansion state of a group row by its generated key. */
    toggleGroup?: (key: string) => Promise<void>;
    /**
     * Register custom CSS styles to be injected into the grid.
     * Use this to style custom cell renderers, editors, or detail panels.
     * @param id - Unique identifier for the style block (for removal/updates)
     * @param css - CSS string to inject
     */
    registerStyles?: (id: string, css: string) => void;
    /**
     * Remove previously registered custom styles.
     * @param id - The ID used when registering the styles
     */
    unregisterStyles?: (id: string) => void;
    /**
     * Get list of registered custom style IDs.
     */
    getRegisteredStyles?: () => string[];
    /**
     * Get a plugin instance by its class.
     *
     * @example
     * ```typescript
     * const selection = grid.getPlugin(SelectionPlugin);
     * if (selection) {
     *   selection.selectAll();
     * }
     * ```
     */
    getPlugin?<P>(PluginClass: new (...args: any[]) => P): P | undefined;
    /**
     * Get a plugin instance by its name.
     * Prefer `getPlugin(PluginClass)` for type safety.
     */
    getPluginByName?(name: string): GridPlugin | undefined;
    /**
     * Re-render the shell header (title, column groups, toolbar).
     * Call this after dynamically adding/removing tool panels or toolbar buttons.
     */
    refreshShellHeader?(): void;
    /**
     * Register a custom tool panel in the sidebar.
     *
     * @example
     * ```typescript
     * grid.registerToolPanel({
     *   id: 'analytics',
     *   title: 'Analytics',
     *   icon: '📊',
     *   render: (container) => {
     *     container.innerHTML = '<div>Charts here...</div>';
     *   }
     * });
     * ```
     */
    registerToolPanel?(panel: ToolPanelDefinition): void;
    /**
     * Unregister a previously registered tool panel.
     */
    unregisterToolPanel?(panelId: string): void;
    /**
     * Whether the grid is currently in a loading state.
     * When true, displays a loading overlay with spinner.
     *
     * Can also be set via the `loading` HTML attribute.
     *
     * @example
     * ```typescript
     * // Show loading overlay
     * grid.loading = true;
     * const data = await fetchData();
     * grid.rows = data;
     * grid.loading = false;
     * ```
     */
    loading?: boolean;
    /**
     * Set loading state for a specific row.
     * Displays a small spinner indicator on the row.
     *
     * Use when persisting row data or performing row-level async operations.
     *
     * @param rowId - The row's unique identifier (from getRowId)
     * @param loading - Whether the row is loading
     *
     * @example
     * ```typescript
     * // Show loading while saving row
     * grid.setRowLoading('emp-123', true);
     * await saveRow(row);
     * grid.setRowLoading('emp-123', false);
     * ```
     */
    setRowLoading?(rowId: string, loading: boolean): void;
    /**
     * Set loading state for a specific cell.
     * Displays a small spinner indicator on the cell.
     *
     * Use when performing cell-level async operations (e.g., validation, lookup).
     *
     * @param rowId - The row's unique identifier (from getRowId)
     * @param field - The column field
     * @param loading - Whether the cell is loading
     *
     * @example
     * ```typescript
     * // Show loading while validating cell
     * grid.setCellLoading('emp-123', 'email', true);
     * const isValid = await validateEmail(email);
     * grid.setCellLoading('emp-123', 'email', false);
     * ```
     */
    setCellLoading?(rowId: string, field: string, loading: boolean): void;
    /**
     * Check if a row is currently in loading state.
     * @param rowId - The row's unique identifier
     */
    isRowLoading?(rowId: string): boolean;
    /**
     * Check if a cell is currently in loading state.
     * @param rowId - The row's unique identifier
     * @param field - The column field
     */
    isCellLoading?(rowId: string, field: string): boolean;
    /**
     * Clear all row and cell loading states.
     */
    clearAllLoading?(): void;
}
/**
 * Internal-only augmented interface for DataGrid component.
 *
 * Member prefixes indicate accessibility:
 * - `_underscore` = protected members - private outside core, accessible to plugins. Marked with @internal.
 * - `__doubleUnderscore` = deeply internal members - private outside core, only for internal functions.
 *
 * @category Plugin Development
 */
export interface InternalGrid<T = any> extends PublicGrid<T>, GridConfig<T> {
    querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
    querySelector<E extends Element = Element>(selectors: string): E | null;
    querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
    _rows: T[];
    _columns: ColumnInternal<T>[];
    /** Visible columns only (excludes hidden). Use for rendering. */
    _visibleColumns: ColumnInternal<T>[];
    _headerRowEl: HTMLElement;
    _bodyEl: HTMLElement;
    _rowPool: RowElementInternal[];
    _resizeController: ResizeController;
    _sortState: {
        field: string;
        direction: 1 | -1;
    } | null;
    /** Original unfiltered/unprocessed rows. @internal */
    sourceRows: T[];
    /** Framework adapter instance (set by Grid directives). @internal */
    __frameworkAdapter?: FrameworkAdapter;
    __originalOrder: T[];
    __rowRenderEpoch: number;
    __didInitialAutoSize?: boolean;
    __lightDomColumnsCache?: ColumnInternal[];
    __originalColumnNodes?: HTMLElement[];
    /** Cell display value cache. @internal */
    __cellDisplayCache?: Map<number, string[]>;
    /** Cache epoch for cell display values. @internal */
    __cellCacheEpoch?: number;
    /** Cached header row count for virtualization. @internal */
    __cachedHeaderRowCount?: number;
    /** Cached flag for whether grid has special columns (custom renderers, etc.). @internal */
    __hasSpecialColumns?: boolean;
    /** Cached flag for whether any plugin has renderRow hooks. @internal */
    __hasRenderRowPlugins?: boolean;
    _gridTemplate: string;
    _virtualization: VirtualState;
    _focusRow: number;
    _focusCol: number;
    /** Currently active edit row index. Injected by EditingPlugin. @internal */
    _activeEditRows?: number;
    /** Snapshots of row data before editing. Injected by EditingPlugin. @internal */
    _rowEditSnapshots?: Map<number, T>;
    /** Get all changed rows. Injected by EditingPlugin. */
    changedRows?: T[];
    /** Get IDs of all changed rows. Injected by EditingPlugin. */
    changedRowIds?: string[];
    effectiveConfig?: GridConfig<T>;
    findHeaderRow?: () => HTMLElement;
    refreshVirtualWindow: (full: boolean, skipAfterRender?: boolean) => void;
    updateTemplate?: () => void;
    findRenderedRowElement?: (rowIndex: number) => HTMLElement | null;
    /** Get a row by its ID. Implemented in grid.ts */
    getRow?: (id: string) => T | undefined;
    /** Get the unique ID for a row. Implemented in grid.ts */
    getRowId?: (row: T) => string;
    /** Update a row by ID. Implemented in grid.ts */
    updateRow?: (id: string, changes: Partial<T>, source?: UpdateSource) => void;
    /** Animate a single row. Implemented in grid.ts */
    animateRow?: (rowIndex: number, type: RowAnimationType) => void;
    /** Animate multiple rows. Implemented in grid.ts */
    animateRows?: (rowIndices: number[], type: RowAnimationType) => void;
    /** Animate a row by its ID. Implemented in grid.ts */
    animateRowById?: (rowId: string, type: RowAnimationType) => boolean;
    /** Begin bulk edit on a row. Injected by EditingPlugin. */
    beginBulkEdit?: (rowIndex: number) => void;
    /** Commit active row edit. Injected by EditingPlugin. */
    commitActiveRowEdit?: () => void;
    /** Dispatch cell click to plugin system, returns true if handled */
    _dispatchCellClick?: (event: MouseEvent, rowIndex: number, colIndex: number, cellEl: HTMLElement) => boolean;
    /** Dispatch row click to plugin system, returns true if handled */
    _dispatchRowClick?: (event: MouseEvent, rowIndex: number, row: any, rowEl: HTMLElement) => boolean;
    /** Dispatch header click to plugin system, returns true if handled */
    _dispatchHeaderClick?: (event: MouseEvent, colIndex: number, headerEl: HTMLElement) => boolean;
    /** Dispatch keydown to plugin system, returns true if handled */
    _dispatchKeyDown?: (event: KeyboardEvent) => boolean;
    /** Dispatch cell mouse events for drag operations. Returns true if any plugin started a drag. */
    _dispatchCellMouseDown?: (event: CellMouseEvent) => boolean;
    /** Dispatch cell mouse move during drag. */
    _dispatchCellMouseMove?: (event: CellMouseEvent) => void;
    /** Dispatch cell mouse up to end drag. */
    _dispatchCellMouseUp?: (event: CellMouseEvent) => void;
    /** Call afterCellRender hook on all plugins. Called from rows.ts after each cell is rendered. @internal */
    _afterCellRender?: (context: AfterCellRenderContext<T>) => void;
    /** Check if any plugin has registered an afterCellRender hook. Used to skip hook call for performance. @internal */
    _hasAfterCellRenderHook?: () => boolean;
    /** Call afterRowRender hook on all plugins. Called from rows.ts after each row is rendered. @internal */
    _afterRowRender?: (context: AfterRowRenderContext<T>) => void;
    /** Check if any plugin has registered an afterRowRender hook. Used to skip hook call for performance. @internal */
    _hasAfterRowRenderHook?: () => boolean;
    /** Get horizontal scroll boundary offsets from plugins */
    _getHorizontalScrollOffsets?: (rowEl?: HTMLElement, focusedCell?: HTMLElement) => {
        left: number;
        right: number;
        skipScroll?: boolean;
    };
    /** Query all plugins with a generic query and collect responses */
    queryPlugins?: <T>(query: PluginQuery) => T[];
    /** Request emission of column-state-change event (debounced) */
    requestStateChange?: () => void;
}
export type PrimitiveColumnType = 'number' | 'string' | 'date' | 'boolean' | 'select';
/**
 * Column type - built-in primitives or custom type strings.
 * Custom types (e.g., 'currency', 'country') can have type-level defaults via `typeDefaults`.
 */
export type ColumnType = PrimitiveColumnType | (string & {});
/**
 * Type-level defaults for formatters and renderers.
 * Applied to all columns of a given type unless overridden at column level.
 *
 * Note: `editor` and `editorParams` are added via module augmentation when
 * EditingPlugin is imported. `filterPanelRenderer` is added by FilteringPlugin.
 *
 * @example
 * ```typescript
 * typeDefaults: {
 *   currency: {
 *     format: (value) => new Intl.NumberFormat('en-US', {
 *       style: 'currency',
 *       currency: 'USD',
 *     }).format(value as number),
 *   },
 *   country: {
 *     renderer: (ctx) => {
 *       const span = document.createElement('span');
 *       span.innerHTML = `<img src="/flags/${ctx.value}.svg" /> ${ctx.value}`;
 *       return span;
 *     }
 *   }
 * }
 * ```
 */
export interface TypeDefault<TRow = unknown> {
    /**
     * Default formatter for all columns of this type.
     *
     * Transforms the raw cell value into a display string. Use when you need
     * consistent formatting across columns without custom DOM (e.g., currency,
     * percentages, dates with specific locale).
     *
     * **Resolution Priority**: Column `format` → Type `format` → Built-in
     *
     * @example
     * ```typescript
     * typeDefaults: {
     *   currency: {
     *     format: (value) => new Intl.NumberFormat('en-US', {
     *       style: 'currency',
     *       currency: 'USD',
     *     }).format(value as number),
     *   },
     *   percentage: {
     *     format: (value) => `${(value as number * 100).toFixed(1)}%`,
     *   }
     * }
     * ```
     */
    format?: (value: unknown, row: TRow) => string;
    /**
     * Default renderer for all columns of this type.
     *
     * Creates custom DOM for the cell content. Use when you need more than
     * text formatting (e.g., icons, badges, interactive elements).
     *
     * **Resolution Priority**: Column `renderer` → Type `renderer` → App-level (adapter) → Built-in
     *
     * @example
     * ```typescript
     * typeDefaults: {
     *   status: {
     *     renderer: (ctx) => {
     *       const badge = document.createElement('span');
     *       badge.className = `badge badge-${ctx.value}`;
     *       badge.textContent = ctx.value as string;
     *       return badge;
     *     }
     *   },
     *   country: {
     *     renderer: (ctx) => {
     *       const span = document.createElement('span');
     *       span.innerHTML = `<img src="/flags/${ctx.value}.svg" /> ${ctx.value}`;
     *       return span;
     *     }
     *   }
     * }
     * ```
     */
    renderer?: ColumnViewRenderer<TRow, unknown>;
}
/**
 * Base contract for a column. Public; kept intentionally lean so host apps can extend via intersection types.
 * Prefer adding optional properties here only when broadly useful to most grids.
 */
export interface BaseColumnConfig<TRow = any, TValue = any> {
    /** Unique field key referencing property in row objects */
    field: keyof TRow & string;
    /** Visible header label; defaults to capitalized field */
    header?: string;
    /**
     * Column data type.
     *
     * Built-in types: `'string'`, `'number'`, `'date'`, `'boolean'`, `'select'`
     *
     * Custom types (e.g., `'currency'`, `'country'`) can have type-level defaults
     * via `gridConfig.typeDefaults` or framework adapter registries.
     *
     * @default Inferred from first row data
     */
    type?: ColumnType;
    /** Column width in pixels; fixed size (no flexibility) */
    width?: string | number;
    /** Minimum column width in pixels (stretch mode only); when set, column uses minmax(minWidth, 1fr) */
    minWidth?: number;
    /** Whether column can be sorted */
    sortable?: boolean;
    /** Whether column can be resized by user */
    resizable?: boolean;
    /** Optional custom comparator for sorting (a,b) -> number */
    sortComparator?: (a: TValue, b: TValue, rowA: TRow, rowB: TRow) => number;
    /** For select type - available options */
    options?: Array<{
        label: string;
        value: unknown;
    }> | (() => Array<{
        label: string;
        value: unknown;
    }>);
    /** For select - allow multi select */
    multi?: boolean;
    /** Optional formatter */
    format?: (value: TValue, row: TRow) => string;
    /** Arbitrary extra metadata */
    meta?: Record<string, unknown>;
}
/**
 * Full column configuration including optional custom view/renderer & grouping metadata.
 */
export interface ColumnConfig<TRow = any> extends BaseColumnConfig<TRow, any> {
    /**
     * Optional custom cell renderer function. Alias for `viewRenderer`.
     * Can return an HTMLElement, a Node, or an HTML string (which will be sanitized).
     *
     * @example
     * ```typescript
     * // Simple string template
     * renderer: (ctx) => `<span class="badge">${ctx.value}</span>`
     *
     * // DOM element
     * renderer: (ctx) => {
     *   const el = document.createElement('span');
     *   el.textContent = ctx.value;
     *   return el;
     * }
     * ```
     */
    renderer?: ColumnViewRenderer<TRow, any>;
    /** Optional custom view renderer used instead of default text rendering */
    viewRenderer?: ColumnViewRenderer<TRow, any>;
    /** External view spec (lets host app mount any framework component) */
    externalView?: {
        component: unknown;
        props?: Record<string, unknown>;
        mount?: (options: {
            placeholder: HTMLElement;
            context: CellRenderContext<TRow, unknown>;
            spec: unknown;
        }) => void | {
            dispose?: () => void;
        };
    };
    /** Whether the column is initially hidden */
    hidden?: boolean;
    /** Prevent this column from being hidden programmatically */
    lockVisible?: boolean;
    /**
     * Dynamic CSS class(es) for cells in this column.
     * Called for each cell during rendering. Return class names to add to the cell element.
     *
     * @example
     * ```typescript
     * // Highlight negative values
     * cellClass: (value, row, column) => value < 0 ? ['negative', 'text-red'] : []
     *
     * // Status-based styling
     * cellClass: (value) => [`status-${value}`]
     * ```
     */
    cellClass?: (value: unknown, row: TRow, column: ColumnConfig<TRow>) => string[];
    /**
     * Custom header label renderer. Customize the label content while the grid
     * handles sort icons, filter buttons, resize handles, and click interactions.
     *
     * Use this for simple customizations like adding icons, badges, or units.
     *
     * @example
     * ```typescript
     * // Add required field indicator
     * headerLabelRenderer: (ctx) => `${ctx.value} <span class="required">*</span>`
     *
     * // Add unit to header
     * headerLabelRenderer: (ctx) => {
     *   const span = document.createElement('span');
     *   span.innerHTML = `${ctx.value}<br/><small>(kg)</small>`;
     *   return span;
     * }
     * ```
     */
    headerLabelRenderer?: HeaderLabelRenderer<TRow>;
    /**
     * Custom header cell renderer. Complete control over the entire header cell.
     * When using this, you are responsible for all content and interactions.
     *
     * The context provides helper functions to include standard elements if desired:
     * - `renderSortIcon()` - Returns sort indicator element (null if not sortable)
     * - `renderFilterButton()` - Returns filter button (null if not filterable)
     * - `renderResizeHandle()` - Returns resize handle element
     *
     * **Precedence**: `headerRenderer` > `headerLabelRenderer` > `header` > `field`
     *
     * @example
     * ```typescript
     * headerRenderer: (ctx) => {
     *   const div = document.createElement('div');
     *   div.className = 'custom-header';
     *   div.innerHTML = `<span>${ctx.value}</span>`;
     *   const sortIcon = ctx.renderSortIcon();
     *   if (sortIcon) div.appendChild(sortIcon);
     *   return div;
     * }
     * ```
     */
    headerRenderer?: HeaderRenderer<TRow>;
}
export type ColumnConfigMap<TRow = any> = ColumnConfig<TRow>[];
/** External editor spec: tag name, factory function, or external mount spec */
export type ColumnEditorSpec<TRow = unknown, TValue = unknown> = string | ((context: ColumnEditorContext<TRow, TValue>) => HTMLElement | string) | {
    /** Arbitrary component reference (class, function, token) */
    component: unknown;
    /** Optional static props passed to mount */
    props?: Record<string, unknown>;
    /** Optional custom mount function; if provided we call it directly instead of emitting an event */
    mount?: (options: {
        placeholder: HTMLElement;
        context: ColumnEditorContext<TRow, TValue>;
        spec: unknown;
    }) => void | {
        dispose?: () => void;
    };
};
/**
 * Context object provided to editor factories allowing mutation (commit/cancel) of a cell value.
 */
export interface ColumnEditorContext<TRow = any, TValue = any> {
    /** Underlying full row object for the active edit. */
    row: TRow;
    /** Current cell value (mutable only via commit). */
    value: TValue;
    /** Field name being edited. */
    field: keyof TRow & string;
    /** Column configuration reference. */
    column: ColumnConfig<TRow>;
    /** Accept the edit; triggers change tracking + rerender. */
    commit: (newValue: TValue) => void;
    /** Abort edit without persisting changes. */
    cancel: () => void;
}
/**
 * Context passed to custom view renderers (pure display – no commit helpers).
 */
export interface CellRenderContext<TRow = any, TValue = any> {
    /** Row object for the cell being rendered. */
    row: TRow;
    /** Value at field. */
    value: TValue;
    /** Field key. */
    field: keyof TRow & string;
    /** Column configuration reference. */
    column: ColumnConfig<TRow>;
    /**
     * The cell DOM element being rendered into.
     * Framework adapters can use this to cache per-cell state (e.g., React roots).
     * @internal
     */
    cellEl?: HTMLElement;
}
export type ColumnViewRenderer<TRow = unknown, TValue = unknown> = (ctx: CellRenderContext<TRow, TValue>) => Node | string | void | null;
/**
 * Context passed to `headerLabelRenderer` for customizing header label content.
 * The framework handles sort icons, filter buttons, resize handles, and click interactions.
 *
 * @example
 * ```typescript
 * headerLabelRenderer: (ctx) => {
 *   const span = document.createElement('span');
 *   span.innerHTML = `${ctx.value} <span class="required">*</span>`;
 *   return span;
 * }
 * ```
 */
export interface HeaderLabelContext<TRow = unknown> {
    /** Column configuration reference. */
    column: ColumnConfig<TRow>;
    /** The header text (from column.header or column.field). */
    value: string;
}
/**
 * Context passed to `headerRenderer` for complete control over header cell content.
 * When using this, the user is responsible for all content and interactions.
 *
 * @example
 * ```typescript
 * headerRenderer: (ctx) => {
 *   const div = document.createElement('div');
 *   div.className = 'custom-header';
 *   div.innerHTML = `<span>${ctx.value}</span>`;
 *   // Optionally include standard elements
 *   const sortIcon = ctx.renderSortIcon();
 *   if (sortIcon) div.appendChild(sortIcon);
 *   div.appendChild(ctx.renderResizeHandle());
 *   return div;
 * }
 * ```
 */
export interface HeaderCellContext<TRow = unknown> {
    /** Column configuration reference. */
    column: ColumnConfig<TRow>;
    /** The header text (from column.header or column.field). */
    value: string;
    /** Current sort state for this column. */
    sortState: 'asc' | 'desc' | null;
    /** Whether the column has an active filter. */
    filterActive: boolean;
    /** The header cell DOM element being rendered into. */
    cellEl: HTMLElement;
    /**
     * Render the standard sort indicator icon.
     * Returns null if column is not sortable.
     */
    renderSortIcon: () => HTMLElement | null;
    /**
     * Render the standard filter button.
     * Returns null if FilteringPlugin is not active or column is not filterable.
     * Note: The actual button is added by FilteringPlugin's afterRender hook.
     */
    renderFilterButton: () => HTMLElement | null;
    /**
     * Render the standard resize handle.
     * Returns a handle element that will be managed by the grid's resize controller.
     */
    renderResizeHandle: () => HTMLElement;
}
/**
 * Header label renderer function type.
 * Customize the label while framework handles sort icons, filter buttons, resize handles.
 */
export type HeaderLabelRenderer<TRow = unknown> = (ctx: HeaderLabelContext<TRow>) => Node | string | void | null;
/**
 * Header cell renderer function type.
 * Full control over header cell content. User is responsible for all content and interactions.
 */
export type HeaderRenderer<TRow = unknown> = (ctx: HeaderCellContext<TRow>) => Node | string | void | null;
/**
 * Framework adapter interface for handling framework-specific component instantiation.
 * Allows framework libraries (Angular, React, Vue) to register handlers that convert
 * declarative light DOM elements into functional renderers/editors.
 *
 * @example
 * ```typescript
 * // In @toolbox-web/grid-angular
 * class AngularGridAdapter implements FrameworkAdapter {
 *   canHandle(element: HTMLElement): boolean {
 *     return element.tagName.startsWith('APP-');
 *   }
 *   createRenderer(element: HTMLElement): ColumnViewRenderer {
 *     return (ctx) => {
 *       // Angular-specific instantiation logic
 *       const componentRef = createComponent(...);
 *       componentRef.setInput('value', ctx.value);
 *       return componentRef.location.nativeElement;
 *     };
 *   }
 *   createEditor(element: HTMLElement): ColumnEditorSpec {
 *     return (ctx) => {
 *       // Angular-specific editor with commit/cancel
 *       const componentRef = createComponent(...);
 *       componentRef.setInput('value', ctx.value);
 *       // Subscribe to commit/cancel outputs
 *       return componentRef.location.nativeElement;
 *     };
 *   }
 * }
 *
 * // User registers adapter once in their app
 * GridElement.registerAdapter(new AngularGridAdapter(injector, appRef));
 * ```
 * @category Framework Adapters
 */
export interface FrameworkAdapter {
    /**
     * Determines if this adapter can handle the given element.
     * Typically checks tag name, attributes, or other conventions.
     */
    canHandle(element: HTMLElement): boolean;
    /**
     * Creates a view renderer function from a light DOM element.
     * The renderer receives cell context and returns DOM or string.
     */
    createRenderer<TRow = unknown, TValue = unknown>(element: HTMLElement): ColumnViewRenderer<TRow, TValue>;
    /**
     * Creates an editor spec from a light DOM element.
     * The editor receives context with commit/cancel and returns DOM.
     */
    createEditor<TRow = unknown, TValue = unknown>(element: HTMLElement): ColumnEditorSpec<TRow, TValue>;
    /**
     * Creates a tool panel renderer from a light DOM element.
     * The renderer receives a container element and optionally returns a cleanup function.
     */
    createToolPanelRenderer?(element: HTMLElement): ((container: HTMLElement) => void | (() => void)) | undefined;
    /**
     * Gets type-level defaults from an application-level registry.
     * Used by Angular's `GridTypeRegistry` and React's `GridTypeProvider`.
     *
     * @param type - The column type (e.g., 'date', 'currency', 'country')
     * @returns Type defaults for renderer/editor, or undefined if not registered
     */
    getTypeDefault?<TRow = unknown>(type: string): TypeDefault<TRow> | undefined;
}
/**
 * Column internal properties used during light DOM parsing.
 * Stores attribute-based names before they're resolved to actual functions.
 * @internal
 */
export interface ColumnParsedAttributes {
    /** Editor name from `editor` attribute (resolved later) */
    __editorName?: string;
    /** Renderer name from `renderer` attribute (resolved later) */
    __rendererName?: string;
}
/**
 * Extended column config used internally.
 * Includes all internal properties needed during grid lifecycle.
 *
 * @category Plugin Development
 * @internal
 */
export interface ColumnInternal<T = any> extends ColumnConfig<T>, ColumnParsedAttributes {
    __autoSized?: boolean;
    __userResized?: boolean;
    __renderedWidth?: number;
    /** Original configured width (for reset on double-click) */
    __originalWidth?: number;
    __viewTemplate?: HTMLElement;
    __editorTemplate?: HTMLElement;
    __headerTemplate?: HTMLElement;
    __compiledView?: CompiledViewFunction<T>;
    __compiledEditor?: (ctx: EditorExecContext<T>) => string;
}
/**
 * Row element with internal tracking properties.
 * Used during virtualization and row pooling.
 *
 * @category Plugin Development
 * @internal
 */
export interface RowElementInternal extends HTMLElement {
    /** Epoch marker for row render invalidation */
    __epoch?: number;
    /** Reference to the row data object for change detection */
    __rowDataRef?: unknown;
    /** Count of cells currently in edit mode */
    __editingCellCount?: number;
    /** Flag indicating this is a custom-rendered row (group row, etc.) */
    __isCustomRow?: boolean;
}
/**
 * Type-safe access to element.part API (DOMTokenList-like).
 * Used for CSS ::part styling support.
 * @internal
 */
export interface ElementWithPart {
    part?: DOMTokenList;
}
/**
 * Compiled view function type with optional blocked flag.
 * The __blocked flag is set when a template contains unsafe expressions.
 *
 * @category Plugin Development
 * @internal
 */
export interface CompiledViewFunction<T = any> {
    (ctx: CellContext<T>): string;
    /** Set to true when template was blocked due to unsafe expressions */
    __blocked?: boolean;
}
/**
 * Runtime cell context used internally for compiled template execution.
 *
 * @category Plugin Development
 */
export interface CellContext<T = any> {
    row: T;
    value: unknown;
    field: string;
    column: ColumnInternal<T>;
}
/**
 * Internal editor execution context extending the generic cell context with commit helpers.
 *
 * @category Plugin Development
 */
export interface EditorExecContext<T = any> extends CellContext<T> {
    commit: (newValue: unknown) => void;
    cancel: () => void;
}
/**
 * Controller managing drag-based column resize lifecycle.
 *
 * @category Plugin Development
 */
export interface ResizeController {
    start: (e: MouseEvent, colIndex: number, cell: HTMLElement) => void;
    /** Reset a column to its configured width (or auto-size if none configured). */
    resetColumn: (colIndex: number) => void;
    dispose: () => void;
    /** True while a resize drag is in progress (used to suppress header click/sort). */
    isResizing: boolean;
}
/**
 * Virtual window bookkeeping; modified in-place as scroll position changes.
 *
 * @category Plugin Development
 */
export interface VirtualState {
    enabled: boolean;
    rowHeight: number;
    /** Threshold for bypassing virtualization (renders all rows if totalRows <= bypassThreshold) */
    bypassThreshold: number;
    start: number;
    end: number;
    /** Faux scrollbar element that provides scroll events (AG Grid pattern) */
    container: HTMLElement | null;
    /** Rows viewport element for measuring visible area height */
    viewportEl: HTMLElement | null;
    /** Spacer element inside faux scrollbar for setting virtual height */
    totalHeightEl: HTMLElement | null;
}
/**
 * Union type for input-like elements that have a `value` property.
 * Covers standard form elements and custom elements with value semantics.
 *
 * @category Plugin Development
 * @internal
 */
export type InputLikeElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | {
    value: unknown;
};
/**
 * Group row rendering customization options.
 * Used within grouping-rows plugin config for presentation of group rows.
 */
export interface RowGroupRenderConfig {
    /** If true, group rows span all columns (single full-width cell). Default false. */
    fullWidth?: boolean;
    /** Optional label formatter override. Receives raw group value + depth. */
    formatLabel?: (value: unknown, depth: number, key: string) => string;
    /** Optional aggregate overrides per field for group summary cells (only when not fullWidth). */
    aggregators?: Record<string, AggregatorRef>;
    /** Additional CSS class applied to each group row root element. */
    class?: string;
}
export type AggregatorRef = string | ((rows: unknown[], field: string, column?: unknown) => unknown);
/** Result of automatic column inference from sample rows. */
export interface InferredColumnResult<TRow = unknown> {
    columns: ColumnConfigMap<TRow>;
    typeMap: Record<string, ColumnType>;
}
export declare const FitModeEnum: {
    readonly STRETCH: "stretch";
    readonly FIXED: "fixed";
};
export type FitMode = (typeof FitModeEnum)[keyof typeof FitModeEnum];
/**
 * Minimal plugin interface for type-checking.
 * This interface is defined here to avoid circular imports with BaseGridPlugin.
 * All plugins must satisfy this shape (BaseGridPlugin implements it).
 *
 * @category Plugin Development
 */
export interface GridPlugin {
    /** Unique plugin identifier */
    readonly name: string;
    /** Plugin version */
    readonly version: string;
    /** CSS styles to inject into the grid */
    readonly styles?: string;
}
/**
 * Grid configuration object - the **single source of truth** for grid behavior.
 *
 * Users can configure the grid via multiple input methods, all of which converge
 * into an effective `GridConfig` internally:
 *
 * **Configuration Input Methods:**
 * - `gridConfig` property - direct assignment of this object
 * - `columns` property - shorthand for `gridConfig.columns`
 * - `fitMode` property - shorthand for `gridConfig.fitMode`
 * - Light DOM `<tbw-grid-column>` - declarative columns (merged into `columns`)
 * - Light DOM `<tbw-grid-header>` - declarative shell header (merged into `shell.header`)
 *
 * **Precedence (when same property set multiple ways):**
 * Individual props (`fitMode`) > `columns` prop > Light DOM > `gridConfig`
 *
 * @example
 * ```ts
 * // Via gridConfig (recommended for complex setups)
 * grid.gridConfig = {
 *   columns: [{ field: 'name' }, { field: 'age' }],
 *   fitMode: 'stretch',
 *   plugins: [new SelectionPlugin()],
 *   shell: { header: { title: 'My Grid' } }
 * };
 *
 * // Via individual props (convenience for simple cases)
 * grid.columns = [{ field: 'name' }, { field: 'age' }];
 * grid.fitMode = 'stretch';
 * ```
 */
export interface GridConfig<TRow = any> {
    /** Column definitions. Can also be set via `columns` prop or `<tbw-grid-column>` light DOM. */
    columns?: ColumnConfigMap<TRow>;
    /**
     * Dynamic CSS class(es) for data rows.
     * Called for each row during rendering. Return class names to add to the row element.
     *
     * @example
     * ```typescript
     * // Highlight inactive rows
     * rowClass: (row) => row.active ? [] : ['inactive', 'dimmed']
     *
     * // Status-based row styling
     * rowClass: (row) => [`priority-${row.priority}`]
     * ```
     */
    rowClass?: (row: TRow) => string[];
    /** Sizing mode for columns. Can also be set via `fitMode` prop. */
    fitMode?: FitMode;
    /**
     * Grid-wide sorting toggle.
     * When false, disables sorting for all columns regardless of their individual `sortable` setting.
     * When true (default), columns with `sortable: true` can be sorted.
     *
     * This affects:
     * - Header click handlers for sorting
     * - Sort indicator visibility
     * - Multi-sort plugin behavior (if loaded)
     *
     * @default true
     *
     * @example
     * ```typescript
     * // Disable all sorting
     * gridConfig = { sortable: false };
     *
     * // Enable sorting (default) - individual columns still need sortable: true
     * gridConfig = { sortable: true };
     * ```
     */
    sortable?: boolean;
    /**
     * Row height in pixels for virtualization calculations.
     * The virtualization system assumes uniform row heights for performance.
     *
     * If not specified, the grid measures the first rendered row's height,
     * which respects the CSS variable `--tbw-row-height` set by themes.
     *
     * Set this explicitly when:
     * - Row content may wrap to multiple lines (also set `--tbw-cell-white-space: normal`)
     * - Using custom row templates with variable content
     * - You want to override theme-defined row height
     *
     * @default Auto-measured from first row (respects --tbw-row-height CSS variable)
     *
     * @example
     * ```ts
     * // Fixed height for rows that may wrap to 2 lines
     * gridConfig = { rowHeight: 56 };
     * ```
     */
    rowHeight?: number;
    /**
     * Array of plugin instances.
     * Each plugin is instantiated with its configuration and attached to this grid.
     *
     * @example
     * ```ts
     * plugins: [
     *   new SelectionPlugin({ mode: 'range' }),
     *   new MultiSortPlugin(),
     *   new FilteringPlugin({ debounceMs: 150 }),
     * ]
     * ```
     */
    plugins?: GridPlugin[];
    /**
     * Saved column state to restore on initialization.
     * Includes order, width, visibility, sort, and plugin-contributed state.
     */
    columnState?: GridColumnState;
    /**
     * Shell configuration for header bar and tool panels.
     * When configured, adds an optional wrapper with title, toolbar, and collapsible side panels.
     */
    shell?: ShellConfig;
    /**
     * Grid-wide icon configuration.
     * Provides consistent icons across all plugins (tree, grouping, sorting, etc.).
     * Plugins will use these by default but can override with their own config.
     */
    icons?: GridIcons;
    /**
     * Grid-wide animation configuration.
     * Controls animations for expand/collapse, reordering, and other visual transitions.
     * Individual plugins can override these defaults in their own config.
     */
    animation?: AnimationConfig;
    /**
     * Custom sort handler for full control over sorting behavior.
     *
     * When provided, this handler is called instead of the built-in sorting logic.
     * Enables custom sorting algorithms, server-side sorting, or plugin-specific sorting.
     *
     * The handler receives:
     * - `rows`: Current row array to sort
     * - `sortState`: Sort field and direction (1 = asc, -1 = desc)
     * - `columns`: Column configurations (for accessing sortComparator)
     *
     * Return the sorted array (sync) or a Promise that resolves to the sorted array (async).
     * For server-side sorting, return a Promise that resolves when data is fetched.
     *
     * @example
     * ```ts
     * // Custom stable sort
     * sortHandler: (rows, state, cols) => {
     *   return stableSort(rows, (a, b) => compare(a[state.field], b[state.field]) * state.direction);
     * }
     *
     * // Server-side sorting
     * sortHandler: async (rows, state) => {
     *   const response = await fetch(`/api/data?sort=${state.field}&dir=${state.direction}`);
     *   return response.json();
     * }
     * ```
     */
    sortHandler?: SortHandler<TRow>;
    /**
     * Function to extract a unique identifier from a row.
     * Used by `updateRow()`, `getRow()`, and ID-based tracking.
     *
     * If not provided, falls back to `row.id` or `row._id` if present.
     * Rows without IDs are silently skipped during map building.
     * Only throws when explicitly calling `getRowId()` or `updateRow()` on a row without an ID.
     *
     * @example
     * ```ts
     * // Simple field
     * getRowId: (row) => row.id
     *
     * // Composite key
     * getRowId: (row) => `${row.voyageId}-${row.legNumber}`
     *
     * // UUID field
     * getRowId: (row) => row.uuid
     * ```
     */
    getRowId?: (row: TRow) => string;
    /**
     * Type-level renderer and editor defaults.
     *
     * Keys can be:
     * - Built-in types: `'string'`, `'number'`, `'date'`, `'boolean'`, `'select'`
     * - Custom types: `'currency'`, `'country'`, `'status'`, etc.
     *
     * Resolution order (highest priority first):
     * 1. Column-level (`column.renderer` / `column.editor`)
     * 2. Grid-level (`gridConfig.typeDefaults[column.type]`)
     * 3. App-level (Angular `GridTypeRegistry`, React `GridTypeProvider`)
     * 4. Built-in (checkbox for boolean, select for select, etc.)
     * 5. Fallback (plain text / text input)
     *
     * @example
     * ```typescript
     * typeDefaults: {
     *   date: { editor: myDatePickerEditor },
     *   country: {
     *     renderer: (ctx) => {
     *       const span = document.createElement('span');
     *       span.innerHTML = `<img src="/flags/${ctx.value}.svg" /> ${ctx.value}`;
     *       return span;
     *     },
     *     editor: (ctx) => createCountrySelect(ctx)
     *   }
     * }
     * ```
     */
    typeDefaults?: Record<string, TypeDefault<TRow>>;
    /**
     * Accessible label for the grid.
     * Sets `aria-label` on the grid's internal table element for screen readers.
     *
     * If not provided and `shell.header.title` is set, the title is used automatically.
     *
     * @example
     * ```ts
     * gridConfig = { gridAriaLabel: 'Employee data' };
     * ```
     */
    gridAriaLabel?: string;
    /**
     * ID of an element that describes the grid.
     * Sets `aria-describedby` on the grid's internal table element.
     *
     * @example
     * ```html
     * <p id="grid-desc">This table shows all active employees.</p>
     * <tbw-grid></tbw-grid>
     * ```
     * ```ts
     * gridConfig = { gridAriaDescribedBy: 'grid-desc' };
     * ```
     */
    gridAriaDescribedBy?: string;
    /**
     * Custom renderer for the loading overlay.
     *
     * When provided, replaces the default spinner with custom content.
     * Receives a context object with the current loading size.
     *
     * @example
     * ```typescript
     * // Simple text loading indicator
     * loadingRenderer: () => {
     *   const el = document.createElement('div');
     *   el.textContent = 'Loading...';
     *   return el;
     * }
     *
     * // Custom spinner component
     * loadingRenderer: (ctx) => {
     *   const spinner = document.createElement('my-spinner');
     *   spinner.size = ctx.size === 'large' ? 48 : 24;
     *   return spinner;
     * }
     * ```
     */
    loadingRenderer?: LoadingRenderer;
}
/**
 * Sort state passed to custom sort handlers.
 */
export interface SortState {
    /** Field to sort by */
    field: string;
    /** Sort direction: 1 = ascending, -1 = descending */
    direction: 1 | -1;
}
/**
 * Custom sort handler function signature.
 *
 * @param rows - Current row array to sort
 * @param sortState - Sort field and direction
 * @param columns - Column configurations (for accessing sortComparator)
 * @returns Sorted array (sync) or Promise resolving to sorted array (async)
 */
export type SortHandler<TRow = any> = (rows: TRow[], sortState: SortState, columns: ColumnConfig<TRow>[]) => TRow[] | Promise<TRow[]>;
/**
 * Loading indicator size variant.
 *
 * - `'large'`: 48x48px max - used for grid-level loading overlay
 * - `'small'`: Follows row height - used for row/cell loading states
 */
export type LoadingSize = 'large' | 'small';
/**
 * Context passed to custom loading renderers.
 */
export interface LoadingContext {
    /** The size variant being rendered */
    size: LoadingSize;
}
/**
 * Custom loading renderer function.
 * Returns an element or HTML string to display as the loading indicator.
 *
 * @param context - Context containing size information
 * @returns HTMLElement or HTML string
 */
export type LoadingRenderer = (context: LoadingContext) => HTMLElement | string;
/**
 * Indicates the origin of a data change.
 * Used to prevent infinite loops in cascade update handlers.
 *
 * - `'user'`: Direct user interaction via EditingPlugin (typing, selecting)
 * - `'cascade'`: Triggered by `updateRow()` in an event handler
 * - `'api'`: External programmatic update via `grid.updateRow()`
 *
 * @category Data Management
 */
export type UpdateSource = 'user' | 'cascade' | 'api';
/**
 * Detail for cell-change event (emitted by core after mutation).
 * This is an informational event that fires for ALL data mutations.
 *
 * @category Events
 */
export interface CellChangeDetail<TRow = unknown> {
    /** The row object (after mutation) */
    row: TRow;
    /** Stable row identifier */
    rowId: string;
    /** Current index in rows array */
    rowIndex: number;
    /** Field that changed */
    field: string;
    /** Value before change */
    oldValue: unknown;
    /** Value after change */
    newValue: unknown;
    /** All changes passed to updateRow/updateRows (for context) */
    changes: Partial<TRow>;
    /** Origin of this change */
    source: UpdateSource;
}
/**
 * Batch update specification for updateRows().
 *
 * @category Data Management
 */
export interface RowUpdate<TRow = unknown> {
    /** Row identifier (from getRowId) */
    id: string;
    /** Fields to update */
    changes: Partial<TRow>;
}
/**
 * Animation behavior mode.
 * - `true` or `'on'`: Animations always enabled
 * - `false` or `'off'`: Animations always disabled
 * - `'reduced-motion'`: Respects `prefers-reduced-motion` media query (default)
 */
export type AnimationMode = boolean | 'on' | 'off' | 'reduced-motion';
/**
 * Animation style for visual transitions.
 * - `'slide'`: Slide/transform animation (e.g., expand down, slide left/right)
 * - `'fade'`: Opacity fade animation
 * - `'flip'`: FLIP technique for position changes (First, Last, Invert, Play)
 * - `false`: No animation for this specific feature
 */
export type AnimationStyle = 'slide' | 'fade' | 'flip' | false;
/**
 * Animation style for expand/collapse operations.
 * Subset of AnimationStyle - excludes 'flip' which is for position changes.
 * - `'slide'`: Slide down/up animation for expanding/collapsing content
 * - `'fade'`: Fade in/out animation
 * - `false`: No animation
 */
export type ExpandCollapseAnimation = 'slide' | 'fade' | false;
/**
 * Type of row animation.
 * - `'change'`: Flash highlight when row data changes (e.g., after cell edit)
 * - `'insert'`: Slide-in animation for newly added rows
 * - `'remove'`: Fade-out animation for rows being removed
 */
export type RowAnimationType = 'change' | 'insert' | 'remove';
/**
 * Grid-wide animation configuration.
 * Controls global animation behavior - individual plugins define their own animation styles.
 * Duration and easing values set corresponding CSS variables on the grid element.
 */
export interface AnimationConfig {
    /**
     * Global animation mode.
     * @default 'reduced-motion'
     */
    mode?: AnimationMode;
    /**
     * Default animation duration in milliseconds.
     * Sets `--tbw-animation-duration` CSS variable.
     * @default 200
     */
    duration?: number;
    /**
     * Default easing function.
     * Sets `--tbw-animation-easing` CSS variable.
     * @default 'ease-out'
     */
    easing?: string;
}
/** Default animation configuration */
export declare const DEFAULT_ANIMATION_CONFIG: Required<Omit<AnimationConfig, 'sort'>>;
/** Icon value - can be a string (text/HTML) or HTMLElement */
export type IconValue = string | HTMLElement;
/**
 * Grid-wide icon configuration.
 * All icons are optional - sensible defaults are used when not specified.
 */
export interface GridIcons {
    /** Expand icon for collapsed items (trees, groups, details). Default: '▶' */
    expand?: IconValue;
    /** Collapse icon for expanded items (trees, groups, details). Default: '▼' */
    collapse?: IconValue;
    /** Sort ascending indicator. Default: '▲' */
    sortAsc?: IconValue;
    /** Sort descending indicator. Default: '▼' */
    sortDesc?: IconValue;
    /** Sort neutral/unsorted indicator. Default: '⇅' */
    sortNone?: IconValue;
    /** Submenu arrow for context menus. Default: '▶' */
    submenuArrow?: IconValue;
    /** Drag handle icon for reordering. Default: '⋮⋮' */
    dragHandle?: IconValue;
    /** Tool panel toggle icon in toolbar. Default: '☰' */
    toolPanel?: IconValue;
    /** Filter icon in column headers. Default: SVG funnel icon */
    filter?: IconValue;
    /** Filter icon when filter is active. Default: same as filter with accent color */
    filterActive?: IconValue;
    /** Print icon for print button. Default: '🖨️' */
    print?: IconValue;
}
/** Default icons used when not overridden */
export declare const DEFAULT_GRID_ICONS: Required<GridIcons>;
/**
 * Shell configuration for the grid's optional header bar and tool panels.
 */
export interface ShellConfig {
    /** Shell header bar configuration */
    header?: ShellHeaderConfig;
    /** Tool panel configuration */
    toolPanel?: ToolPanelConfig;
    /**
     * Registered tool panels (from plugins, API, or Light DOM).
     * These are the actual panel definitions that can be opened.
     * @internal Set by ConfigManager during merge
     */
    toolPanels?: ToolPanelDefinition[];
    /**
     * Registered header content sections (from plugins or API).
     * Content rendered in the center of the shell header.
     * @internal Set by ConfigManager during merge
     */
    headerContents?: HeaderContentDefinition[];
}
/**
 * Shell header bar configuration
 */
export interface ShellHeaderConfig {
    /** Grid title displayed on the left (optional) */
    title?: string;
    /** Custom toolbar content (rendered before tool panel toggle) */
    toolbarContents?: ToolbarContentDefinition[];
    /**
     * Light DOM header content elements (parsed from <tbw-grid-header> children).
     * @internal Set by ConfigManager during merge
     */
    lightDomContent?: HTMLElement[];
    /**
     * Whether a tool buttons container was found in light DOM.
     * @internal Set by ConfigManager during merge
     */
    hasToolButtonsContainer?: boolean;
}
/**
 * Tool panel configuration
 */
export interface ToolPanelConfig {
    /** Panel position: 'left' | 'right' (default: 'right') */
    position?: 'left' | 'right';
    /** Default panel width in pixels (default: 280) */
    width?: number;
    /** Panel ID to open by default on load */
    defaultOpen?: string;
    /** Whether to persist open/closed state (requires Column State Events) */
    persistState?: boolean;
}
/**
 * Toolbar content definition for the shell header toolbar area.
 * Register via `registerToolbarContent()` or use light DOM `<tbw-grid-tool-buttons>`.
 *
 * @example
 * ```typescript
 * grid.registerToolbarContent({
 *   id: 'my-toolbar',
 *   order: 10,
 *   render: (container) => {
 *     const btn = document.createElement('button');
 *     btn.textContent = 'Refresh';
 *     btn.onclick = () => console.log('clicked');
 *     container.appendChild(btn);
 *     return () => btn.remove();
 *   },
 * });
 * ```
 */
export interface ToolbarContentDefinition {
    /** Unique content ID */
    id: string;
    /** Content factory - called once when shell header renders */
    render: (container: HTMLElement) => void | (() => void);
    /** Called when content is removed (for cleanup) */
    onDestroy?: () => void;
    /** Order priority (lower = first, default: 100) */
    order?: number;
}
/**
 * Tool panel definition registered by plugins or consumers.
 */
export interface ToolPanelDefinition {
    /** Unique panel ID */
    id: string;
    /** Panel title shown in accordion header */
    title: string;
    /** Icon for accordion section header (optional, emoji or SVG) */
    icon?: string;
    /** Tooltip for accordion section header */
    tooltip?: string;
    /** Panel content factory - called when panel section opens */
    render: (container: HTMLElement) => void | (() => void);
    /** Called when panel closes (for cleanup) */
    onClose?: () => void;
    /** Panel order priority (lower = first, default: 100) */
    order?: number;
}
/**
 * Header content definition for plugins contributing to shell header center section.
 */
export interface HeaderContentDefinition {
    /** Unique content ID */
    id: string;
    /** Content factory - called once when shell header renders */
    render: (container: HTMLElement) => void | (() => void);
    /** Called when content is removed (for cleanup) */
    onDestroy?: () => void;
    /** Order priority (lower = first, default: 100) */
    order?: number;
}
/**
 * State for a single column. Captures user-driven changes at runtime.
 * Plugins can extend this interface via module augmentation to add their own state.
 *
 * @example
 * ```ts
 * // In filtering plugin
 * declare module '@toolbox-web/grid' {
 *   interface ColumnState {
 *     filter?: FilterValue;
 *   }
 * }
 * ```
 */
export interface ColumnState {
    /** Column field identifier */
    field: string;
    /** Position index after reordering (0-based) */
    order: number;
    /** Width in pixels (undefined = use default) */
    width?: number;
    /** Visibility state */
    visible: boolean;
    /** Sort state (undefined = not sorted) */
    sort?: ColumnSortState;
}
/**
 * Sort state for a column
 */
export interface ColumnSortState {
    /** Sort direction */
    direction: 'asc' | 'desc';
    /** Priority for multi-sort (0 = primary, 1 = secondary, etc.) */
    priority: number;
}
/**
 * Complete grid column state for persistence.
 * Contains state for all columns, including plugin-contributed properties.
 */
export interface GridColumnState {
    columns: ColumnState[];
}
/**
 * Event detail for cell value commit.
 *
 * @category Events
 */
export interface CellCommitDetail<TRow = unknown> {
    /** The row object (not yet mutated if event is cancelable). */
    row: TRow;
    /** Stable row identifier (from getRowId). */
    rowId: string;
    /** Field name whose value changed. */
    field: string;
    /** Previous value before change. */
    oldValue: unknown;
    /** New value to be stored. */
    value: unknown;
    /** Index of the row in current data set. */
    rowIndex: number;
    /** All rows that have at least one committed change (snapshot list). */
    changedRows: TRow[];
    /** IDs of changed rows. */
    changedRowIds: string[];
    /** True if this row just entered the changed set. */
    firstTimeForRow: boolean;
    /**
     * Update other fields in this row.
     * Convenience wrapper for grid.updateRow(rowId, changes, 'cascade').
     * Useful for cascade updates (e.g., calculating totals).
     */
    updateRow: (changes: Partial<TRow>) => void;
}
/**
 * Detail payload for a committed row edit (may or may not include changes).
 *
 * @category Events
 */
export interface RowCommitDetail<TRow = unknown> {
    /** Row index that lost edit focus. */
    rowIndex: number;
    /** Stable row identifier (from getRowId). */
    rowId: string;
    /** Row object reference. */
    row: TRow;
    /** Whether any cell changes were actually committed in this row during the session. */
    changed: boolean;
    /** Current changed row collection. */
    changedRows: TRow[];
    /** IDs of changed rows. */
    changedRowIds: string[];
}
/**
 * Emitted when the changed rows tracking set is cleared programmatically.
 *
 * @category Events
 */
export interface ChangedRowsResetDetail<TRow = unknown> {
    /** New (empty) changed rows array after reset. */
    rows: TRow[];
    /** IDs of changed rows (likely empty). */
    ids: string[];
}
/**
 * Detail for a cell click event.
 * Provides full context about the clicked cell including row data.
 *
 * @category Events
 */
export interface CellClickDetail<TRow = unknown> {
    /** Zero-based row index of the clicked cell. */
    rowIndex: number;
    /** Zero-based column index of the clicked cell. */
    colIndex: number;
    /** Field name of the clicked column. */
    field: string;
    /** Cell value at the clicked position. */
    value: unknown;
    /** Full row data object. */
    row: TRow;
    /** The clicked cell element. */
    cellEl: HTMLElement;
    /** The original mouse event. */
    originalEvent: MouseEvent;
}
/**
 * Detail for a row click event.
 * Provides context about the clicked row.
 *
 * @category Events
 */
export interface RowClickDetail<TRow = unknown> {
    /** Zero-based row index of the clicked row. */
    rowIndex: number;
    /** Full row data object. */
    row: TRow;
    /** The clicked row element. */
    rowEl: HTMLElement;
    /** The original mouse event. */
    originalEvent: MouseEvent;
}
/**
 * Detail for a sort change (direction 0 indicates cleared sort).
 *
 * @category Events
 */
export interface SortChangeDetail {
    /** Sorted field key. */
    field: string;
    /** Direction: 1 ascending, -1 descending, 0 cleared. */
    direction: 1 | -1 | 0;
}
/**
 * Column resize event detail containing final pixel width.
 *
 * @category Events
 */
export interface ColumnResizeDetail {
    /** Resized column field key. */
    field: string;
    /** New width in pixels. */
    width: number;
}
/**
 * Trigger type for cell activation.
 * - `'keyboard'`: Enter key pressed on focused cell
 * - `'pointer'`: Mouse/touch/pen click on cell
 *
 * @category Events
 */
export type CellActivateTrigger = 'keyboard' | 'pointer';
/**
 * Fired when a cell is activated by user interaction (Enter key or click).
 * Unified event for both keyboard and pointer activation.
 *
 * @category Events
 */
export interface CellActivateDetail<TRow = unknown> {
    /** Zero-based row index of the activated cell. */
    rowIndex: number;
    /** Zero-based column index of the activated cell. */
    colIndex: number;
    /** Field name of the activated column. */
    field: string;
    /** Cell value at the activated position. */
    value: unknown;
    /** Full row data object. */
    row: TRow;
    /** The activated cell element. */
    cellEl: HTMLElement;
    /** What triggered the activation. */
    trigger: CellActivateTrigger;
    /** The original event (KeyboardEvent for keyboard, MouseEvent/PointerEvent for pointer). */
    originalEvent: KeyboardEvent | MouseEvent | PointerEvent;
}
/**
 * @deprecated Use `CellActivateDetail` instead. Will be removed in next major version.
 * Kept for backwards compatibility.
 *
 * @category Events
 */
export interface ActivateCellDetail {
    /** Zero-based row index now focused. */
    row: number;
    /** Zero-based column index now focused. */
    col: number;
}
/**
 * Event detail for mounting external view renderers.
 *
 * @category Events
 */
export interface ExternalMountViewDetail<TRow = unknown> {
    placeholder: HTMLElement;
    spec: unknown;
    context: {
        row: TRow;
        value: unknown;
        field: string;
        column: unknown;
    };
}
/**
 * Event detail for mounting external editor renderers.
 *
 * @category Events
 */
export interface ExternalMountEditorDetail<TRow = unknown> {
    placeholder: HTMLElement;
    spec: unknown;
    context: {
        row: TRow;
        value: unknown;
        field: string;
        column: unknown;
        commit: (v: unknown) => void;
        cancel: () => void;
    };
}
/**
 * Maps event names to their detail payload types.
 *
 * @category Events
 */
export interface DataGridEventMap<TRow = unknown> {
    'cell-click': CellClickDetail<TRow>;
    'row-click': RowClickDetail<TRow>;
    'cell-activate': CellActivateDetail<TRow>;
    'cell-change': CellChangeDetail<TRow>;
    'cell-commit': CellCommitDetail<TRow>;
    'row-commit': RowCommitDetail<TRow>;
    'changed-rows-reset': ChangedRowsResetDetail<TRow>;
    'mount-external-view': ExternalMountViewDetail<TRow>;
    'mount-external-editor': ExternalMountEditorDetail<TRow>;
    'sort-change': SortChangeDetail;
    'column-resize': ColumnResizeDetail;
    /** @deprecated Use 'cell-activate' instead */
    'activate-cell': ActivateCellDetail;
    'column-state-change': GridColumnState;
}
/**
 * Extracts the event detail type for a given event name.
 *
 * @category Events
 */
export type DataGridEventDetail<K extends keyof DataGridEventMap<unknown>, TRow = unknown> = DataGridEventMap<TRow>[K];
/**
 * Custom event type for DataGrid events with typed detail payload.
 *
 * @category Events
 */
export type DataGridCustomEvent<K extends keyof DataGridEventMap<unknown>, TRow = unknown> = CustomEvent<DataGridEventMap<TRow>[K]>;
export type EditorContext<T = unknown> = ColumnEditorContext<T, unknown>;
/**
 * Template evaluation context for dynamic templates.
 *
 * @category Plugin Development
 */
export interface EvalContext {
    value: unknown;
    row: Record<string, unknown> | null;
}
//# sourceMappingURL=types.d.ts.map