/** * @license *------------------------------------------------------------------------------------------- * Copyright © 2026 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the package root for more information *------------------------------------------------------------------------------------------- */ /** * Keyboard navigation utilities for stacked layout cells. * * Implements the navigation pattern specified in STACKED_LAYOUT_KEYBOARD_NAVIGATION.md: * * ## Key Behaviors * * 1. **Tab Navigation** - PRIMARY mechanism for navigating between stacked cells: * - Tab: Move to next stacked cell in the row * - Shift+Tab: Move to previous stacked cell in the row * - Focus is TRAPPED within the row card (stopPropagation at boundaries) * * 2. **Enter/F2 Keys** - Transition from Cursor mode to Content mode: * - Focuses the first focusable element within the cell * - Enables interaction with cell content (inputs, buttons, etc.) * * 3. **Escape Key** - Exit Content mode, return to Cursor mode: * - Returns focus to the row-level container * - Resets cell entered state * * ## Navigation Modes * * - **Cursor Mode**: Cell wrapper is focused, user can navigate rows with arrow keys * - **Content Mode**: Focusable element inside cell is focused, user can interact with content * * ## Critical Notes * * - Horizontal (Left/Right) arrow navigation is DISABLED in stacked mode * - Vertical (Up/Down) arrow navigation moves between rows, not cells * - Tab/Shift+Tab stops at row boundaries (prevents leaving the row) * - Each row card is treated as a single navigable unit * * @module stackedKeyboardNavigation * @see STACKED_LAYOUT_KEYBOARD_NAVIGATION.md for complete specification * * @hidden */ /** * Options for handling stacked cell keyboard navigation. * * @hidden */ export interface StackedKeyboardNavigationOptions { /** * The keyboard event to handle. */ event: React.KeyboardEvent; /** * The cell element (the stacked cell wrapper div). */ cellElement: HTMLElement; /** * Optional callback to invoke after handling the keyboard event. */ onKeyDown?: (event: React.KeyboardEvent) => void; /** * Optional callback to invoke when Escape is pressed (to update row entered state). */ onEscape?: () => void; /** * Optional callback to invoke when exiting edit mode (e.g., on Escape in incell mode). * This should trigger the Grid's onEditChange to update the edit descriptor. */ onExitEdit?: () => void; /** * Optional callback to invoke when Tab is pressed in incell edit mode. * Called with the direction (1 for Tab, -1 for Shift+Tab) to move to next/previous cell. * Should handle transitioning edit state from current cell to next/previous cell. */ onTabToNextCell?: (direction: number) => void; /** * Whether the cell is currently in edit mode. * When true, applies edit mode keyboard navigation rules. */ isInEdit?: boolean; /** * The edit mode of the grid: 'incell', 'inline', or 'dialog'. * Determines which keyboard navigation rules apply during editing. */ editMode?: 'incell' | 'inline' | 'dialog'; } /** * Handles Tab key navigation within a stacked cell row. * Implements focus trap pattern to keep navigation within the current row card. * Tab/Shift+Tab navigates between stacked cells, stopping at row boundaries. * * Edit Mode Behaviors (EDIT_MODE_KEYBOARD_NAVIGATION.md): * - **Incell**: Tab saves current cell and moves to next editable cell * - **Inline**: Tab navigates between fields within the editing row * - **Not editing**: Standard stacked cell navigation with focus trap * * Based on specification: "Tab is THE mechanism for navigating between stacked cells within a row" * and "Trap focus within the current row card: Prevent Tab from leaving the row at boundaries" * * @param event - The keyboard event * @param cellElement - The stacked cell wrapper element * @param target - The event target element * @param isInEdit - Whether the cell/row is in edit mode * @param editMode - The edit mode ('incell', 'inline', or 'dialog') * @returns true if the event was handled and should stop propagation * * @hidden */ export declare const handleStackedCellTabNavigation: (event: React.KeyboardEvent, cellElement: HTMLElement, target: HTMLElement, isInEdit?: boolean, editMode?: 'incell' | 'inline' | 'dialog', onTabToNextCell?: ((direction: number) => void) | undefined) => boolean; /** * Handles Enter key press on a stacked cell. * Behavior varies based on edit mode. * * Edit Mode Behaviors (EDIT_MODE_KEYBOARD_NAVIGATION.md): * - **Incell**: Enter confirms edit, saves changes, and closes cell * - **Inline**: Enter moves to next field (does NOT save) * - **Not editing**: Transitions from Cursor mode to Content mode * * Based on specification: "Enter or F2 while in Cursor Mode: Activates Content mode for the current cell" * * @param event - The keyboard event * @param cellElement - The stacked cell wrapper element * @param target - The event target element * @param isInEdit - Whether the cell/row is in edit mode * @param editMode - The edit mode ('incell', 'inline', or 'dialog') * @returns true if the event was handled * * @hidden */ export declare const handleStackedCellEnterKey: (event: React.KeyboardEvent, cellElement: HTMLElement, target: HTMLElement, isInEdit?: boolean, editMode?: 'incell' | 'inline' | 'dialog') => boolean; /** * Handles Escape key press on a stacked cell. * Behavior varies based on edit mode. * * Edit Mode Behaviors (EDIT_MODE_KEYBOARD_NAVIGATION.md): * - **Incell**: Escape cancels edit, discards changes, and closes cell * - **Inline**: Escape cancels editing, closes row, and discards changes * - **Not editing**: Exits Content mode and returns to Cursor mode * * Based on specification: "Escape Key: Exits Content mode and returns to Cursor mode" * * @param event - The keyboard event * @param cellElement - The stacked cell wrapper element * @param onEscape - Optional callback to invoke when Escape is handled (resets cell entered state) * @param isInEdit - Whether the cell/row is in edit mode * @param editMode - The edit mode ('incell', 'inline', or 'dialog') * @returns true if the event was handled * * @hidden */ export declare const handleStackedCellEscapeKey: (event: React.KeyboardEvent, cellElement: HTMLElement, onEscape?: () => void, onExitEdit?: () => void, isInEdit?: boolean, editMode?: 'incell' | 'inline' | 'dialog') => boolean; /** * Handles navigation keys (arrows, PageUp/Down, Home/End) during editing. * Blocks ALL navigation keys during incell editing per specification. * * Edit Mode Behaviors (EDIT_MODE_KEYBOARD_NAVIGATION.md): * - **Incell**: ALL navigation keys are BLOCKED * - **Inline**: Arrow Up/Down are blocked (can't navigate to other rows) * - **Not editing**: Navigation keys work normally * * Based on specification: "ALL navigation keys are blocked when cell is editing" * * @param event - The keyboard event * @param isInEdit - Whether the cell/row is in edit mode * @param editMode - The edit mode ('incell', 'inline', or 'dialog') * @returns true if the event was blocked * * @hidden */ export declare const handleNavigationKeysInEditMode: (event: React.KeyboardEvent, isInEdit?: boolean, editMode?: 'incell' | 'inline' | 'dialog') => boolean; /** * Main handler for stacked cell keyboard navigation. * Implements the navigation pattern described in the specifications: * * Specifications: * - STACKED_LAYOUT_KEYBOARD_NAVIGATION.md: Navigation modes and focus trap * - EDIT_MODE_KEYBOARD_NAVIGATION.md: Edit mode behaviors * * Navigation Flow: * - Tab/Shift+Tab: Navigate between stacked cells within the row (focus trapped) * - Enter/F2: Transition from Cursor mode to Content mode (focus first element) * - Escape: Exit Content mode, return to Cursor mode (focus row container) * * Mode Transitions: * - Cursor Mode: Cell wrapper is focused, arrow keys navigate rows * - Content Mode: Focusable element inside cell is focused, Tab navigates cells * * Focus Trap: * Tab navigation is trapped within the current row card. At boundaries: * - First cell + Shift+Tab: Stay on first cell (stopPropagation) * - Last cell + Tab: Stay on last cell (stopPropagation) * * Edit Mode Behaviors: * - **Incell**: All navigation keys blocked, Tab saves and moves, Enter saves, Escape cancels * - **Inline**: Up/Down blocked, Tab between fields, Enter to next field, Escape cancels * - **Not editing**: Normal navigation * * @param options - Navigation options * * @hidden */ export declare const handleStackedKeyboardNavigation: (options: StackedKeyboardNavigationOptions) => void; /** * Exported stacked keyboard navigation utilities. * * @hidden */ export declare const stackedKeyboardNavigationTools: { handleStackedKeyboardNavigation: (options: StackedKeyboardNavigationOptions) => void; handleStackedCellTabNavigation: (event: React.KeyboardEvent, cellElement: HTMLElement, target: HTMLElement, isInEdit?: boolean, editMode?: 'incell' | 'inline' | 'dialog', onTabToNextCell?: ((direction: number) => void) | undefined) => boolean; handleStackedCellEnterKey: (event: React.KeyboardEvent, cellElement: HTMLElement, target: HTMLElement, isInEdit?: boolean, editMode?: 'incell' | 'inline' | 'dialog') => boolean; handleStackedCellEscapeKey: (event: React.KeyboardEvent, cellElement: HTMLElement, onEscape?: () => void, onExitEdit?: () => void, isInEdit?: boolean, editMode?: 'incell' | 'inline' | 'dialog') => boolean; handleNavigationKeysInEditMode: (event: React.KeyboardEvent, isInEdit?: boolean, editMode?: 'incell' | 'inline' | 'dialog') => boolean; isNavigationKey: (key: string) => boolean; };