feat(grid): add keyboard arrow navigation and edit modes to grid view#8653
Open
CodeBySayak wants to merge 2 commits intoAppFlowy-IO:mainfrom
Open
feat(grid): add keyboard arrow navigation and edit modes to grid view#8653CodeBySayak wants to merge 2 commits intoAppFlowy-IO:mainfrom
CodeBySayak wants to merge 2 commits intoAppFlowy-IO:mainfrom
Conversation
Contributor
Reviewer's GuideConverts the grid cell container to a stateful, focus-aware widget that distinguishes between selection and edit modes, integrates Flutter Focus-based keyboard handling (Enter key, focus border), and wires tap/double-tap behavior to enter edit mode while preserving accessories rendering. Sequence diagram for keyboard Enter handling and focus-based edit modesequenceDiagram
actor User
participant CellContainer
participant CellFocus as CellContainer_FocusNode
participant ChildCell as GridCellChild
participant Notifier as CellContainerNotifier
User->>CellContainer: Press_Enter_key
CellContainer->>CellFocus: onKeyEvent(KeyDownEvent, Enter)
CellFocus-->>CellContainer: KeyEventResult.handled
CellContainer->>ChildCell: requestFocus.notify()
ChildCell->>Notifier: set isFocus true
Notifier-->>CellContainer: isChildFocus changes
CellContainer->>CellContainer: rebuild with isSelectedOrEditing true
CellContainer->>User: show cell in edit mode (focused child)
Class diagram for updated CellContainer and focus-aware stateclassDiagram
class CellContainer {
+Widget child
+GridCellAccessoryBuilder accessoryBuilder
+double width
+bool isPrimary
+CellContainer(child, accessoryBuilder, width, isPrimary)
+State createState()
}
class _CellContainerState {
-FocusNode _focusNode
+void initState()
+void dispose()
+void _onFocusChange()
+Widget build(BuildContext context)
}
class CellContainerNotifier {
+bool isFocus
+void addListener(Function listener)
+void removeListener(Function listener)
}
class GridCellShortcuts {
+Widget child
}
class GridCellAccessoryBuildContext {
+BuildContext anchorContext
+bool isCellEditing
}
class _GridCellEnterRegion {
+List accessories
+bool isPrimary
+Widget child
}
CellContainer ..> GridCellShortcuts : uses
CellContainer ..> CellContainerNotifier : provides_to_Selector
CellContainer ..> GridCellAccessoryBuildContext : builds_with_isCellEditing
CellContainer ..> _GridCellEnterRegion : wraps_when_accessories
CellContainer --> _CellContainerState : creates_state
_CellContainerState --> CellContainer : accesses_widget_properties
_CellContainerState ..> FocusNode : manages_focus_for_cell
_CellContainerState ..> CellContainerNotifier : reads_isFocus_via_Selector
_CellContainerState ..> GridCellShortcuts : centers_child_with_shortcuts
_CellContainerState ..> _GridCellEnterRegion : wraps_for_accessories
_CellContainerState ..> GridCellAccessoryBuildContext : passes_isCellEditing_flag
_CellContainerState ..> BoxDecoration : _makeBoxDecoration(context, isSelectedOrEditing)
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Contributor
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The
onTaphandler currently enters edit mode on a second single-click (when_focusNodealready has focus), which conflicts with the described behavior of single-click = select and Enter/double-click = edit; consider tightening the logic so single-click never directly triggerschild.requestFocus.notify()and only Enter/double-tap do. - The
isSelectedOrEditingflag conflates the cell’s own focus node and the child’s edit focus (isChildFocus), which can make visual state difficult to reason about; consider separating ‘selection’ and ‘editing’ decorations so each is driven by a single, clear source of truth.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `onTap` handler currently enters edit mode on a second single-click (when `_focusNode` already has focus), which conflicts with the described behavior of single-click = select and Enter/double-click = edit; consider tightening the logic so single-click never directly triggers `child.requestFocus.notify()` and only Enter/double-tap do.
- The `isSelectedOrEditing` flag conflates the cell’s own focus node and the child’s edit focus (`isChildFocus`), which can make visual state difficult to reason about; consider separating ‘selection’ and ‘editing’ decorations so each is driven by a single, clear source of truth.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR improves keyboard navigation in the Database Grid View by introducing spreadsheet-style interaction patterns.
Problem
Currently, users cannot efficiently navigate or edit cells using the keyboard. Navigation relies heavily on mouse interaction, limiting usability and accessibility. Additionally, common spreadsheet functions like cut, copy, paste, and fast deletion were not natively mapped at the grid level.
Solution
Introduced a navigation model that clearly separates selection and editing, along with native keyboard traversal support. Furthermore, this PR expands upon the
CellShortcutsframework to bring robust support for single-cell data manipulation.Changes
Navigation vs Edit Mode
Enteror double-click specifically triggers child Edit Mode. Selection and editing container decorations have been decoupled for an accurate visual source of truth.Arrow Key Navigation
Up,Down,Left,Righttraversal between cells.Focussystem.Spreadsheet Editing Shortcuts
Ctrl/Cmd+X(Cut),Ctrl/Cmd+C(Copy), andCtrl/Cmd+V(Paste) handler mapping onto the cell framework.DeleteandBackspaceto rapidly clear underlying cell text states.Relational Data Enhancements
Deletewhen a cell is highlighted safely and iteratively unlinks all related rows from the BLOC state via keyboard.Refactoring & Reliability
CellContainerto aStatefulWidgetto properly manage its scopedFocusNodefor reliable navigation.Enter, double tap) for focus propagation.(Note regarding #8646: The original issue lists Grid Multi-Cell Selection (Shift+Arrow / Mouse Drag). Because AppFlowy isolates rows utilizing virtualized blocks, creating 2D bounding boxes requires an independent GridSelectionManager overlay. Multi-cell functionality is out of scope for general navigation behavior and should be tracked in its own specific architectural issue).
How to Test
Enteror double-click → cell should successfully pass focus into edit mode.Ctrl/Cmd+C,Cmd+X, andCmd+Vwhile standard text/number cells are highlighted (but not edited) to verify copying and pasting clipboard values.Deleteto verify the links are uncoupled via keyboard.PR Checklist
closes #8646