Skip to content

Commit 7ad9a9c

Browse files
committed
feat: working modular prototype for traversing list, tree and grid, including support for drag and drop
1 parent 2c6760c commit 7ad9a9c

17 files changed

+1272
-330
lines changed

.zed/settings.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Folder-specific settings
2+
//
3+
// For a full list of overridable settings, and general information on folder-specific settings,
4+
// see the documentation: https://zed.dev/docs/configuring-zed#folder-specific-settings
5+
{
6+
"tab_size": 2,
7+
"file_types": {
8+
"SQL": ["ddl"]
9+
},
10+
"show_whitespaces": "all"
11+
}

packages/actions/docs/navigator.md

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Navigator
2+
3+
The Navigator Action is a utility designed to facilitate keyboard and click navigation within various UI components such as lists, trees, or tables. It aims to provide a consistent and intuitive way for users to navigate through items, select/deselect them, and perform actions based on user inputs.
4+
5+
## Key Goals
6+
7+
- Modularity: The navigator action should be modular and easily adaptable to different UI components and navigation requirements.
8+
- Customizability: Users should be able to configure navigation behavior and options according to specific needs.
9+
- Accessibility: The action should enhance accessibility by providing keyboard navigation support for users who rely on keyboard input.
10+
- Efficiency: Navigation should be efficient, allowing users to quickly move through items, select/deselect them, and perform actions with minimal effort.
11+
12+
## Interaction Flow
13+
14+
1. Keyboard Navigation: Users can navigate through items using arrow keys, page up/down, home/end keys.
15+
2. Selection: Single-clicking on an item selects/deselects it.
16+
3. Expansion/Collapse: Arrow keys, double-clicks, or specific keys like Right/Left arrows expand or collapse items with hierarchical structures.
17+
4. Efficient Navigation: Page up/down keys allow users to navigate through items efficiently, especially in long lists or tables.
18+
5. Drag and Drop: When enabled, users can drag items within the component and drop them onto valid targets.
19+
6. Multi-Select: When multi-select mode is enabled, users can select multiple items using Shift key and arrow keys or mouse click.
20+
7. Modifier Keys: Users can use modifier keys like Shift or Ctrl to modify selection behavior.
21+
22+
## Supported Events and Actions
23+
24+
### Keyboard Events
25+
26+
- Arrow Up
27+
- Arrow Down
28+
- Arrow Right
29+
- Arrow Left
30+
- Page Up
31+
- Page Down
32+
- Home
33+
- End
34+
- Enter/Return
35+
36+
### Extended Selection with Shift Key
37+
38+
- Shift + Arrow Down - In a grid, this will select the next row.
39+
- Shift + Arrow Up - In a grid, this will select the previous row.
40+
- Shift + Arrow Right - In a grid, this will select the next cell
41+
- Shift + Arrow Left - In a grid, this will select the previous cell
42+
- Shift + Page Down - In a grid, this will select the next page of rows.
43+
- Shift + Page Up - In a grid, this will select the previous page of rows.
44+
- Shift + Home
45+
- Shift + End
46+
- Ctrl/Meta + 'X' (Cut)
47+
- Ctrl/Meta + 'C' (Copy)
48+
- Ctrl/Meta + 'V' (Paste)
49+
50+
### Click Events
51+
52+
- Single Click
53+
- Modifier Keys (Shift or Ctrl)
54+
- DoubleClick
55+
- Drag and Drop
56+
57+
## Options
58+
59+
- Multi-Select (default: `false`)
60+
- Page Size (default: 10)
61+
- Allow Drag (default: `false`)
62+
- Allow Drop (default: `false`)
63+
- horizontal (default: `false`)
64+
- vertical (default: `true`)
65+
66+
## Events
67+
68+
- `select`: Triggered when an item is selected.
69+
- `change`: Triggered when the selection changes.
70+
- `expand`: Triggered when an item is expanded.
71+
- `collapse`: Triggered when an item is collapsed.
72+
- `dragstart`: Triggered when an item is dragged.
73+
- `dragover`: Triggered when an item is dragged over a valid drop target.
74+
- `drop`: Triggered when an item is dropped onto a valid target.
75+
76+
## Implementation Considerations
77+
78+
- Maintain a reference to the first clicked or selected item when Shift key is pressed.
79+
- Track the direction of navigation (up or down) to determine which items to include in the selection.
80+
- Update the selection dynamically as the user navigates with arrow keys while holding down the Shift key.
81+
- Implement event handlers for drag start, drag over, and drop events.
82+
- Determine valid drop targets based on the UI component's structure and state.
83+
- Update the component's state based on drag and drop interactions.
84+
- Offload state management to the store or parent component to ensure consistency across multiple instances of the navigator action.

packages/actions/spec/mocks/store.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export const mockStore = {
2+
moveUp: vi.fn(),
3+
moveDown: vi.fn(),
4+
moveLeft: vi.fn(),
5+
moveRight: vi.fn(),
6+
moveFirst: vi.fn(),
7+
moveLast: vi.fn(),
8+
select: vi.fn(),
9+
selectAll: vi.fn(),
10+
selectNone: vi.fn(),
11+
selectInvert: vi.fn(),
12+
selectRange: vi.fn(),
13+
onNavigate: vi.fn(),
14+
toggleExpansion: vi.fn(),
15+
toggleSelection: vi.fn(),
16+
cut: vi.fn(),
17+
copy: vi.fn(),
18+
paste: vi.fn(),
19+
undo: vi.fn(),
20+
redo: vi.fn(),
21+
escape: vi.fn(),
22+
dragStart: vi.fn(),
23+
dragOver: vi.fn(),
24+
dropOver: vi.fn(),
25+
currentItem: vi.fn(() => ({ index: [0] }))
26+
}

packages/actions/spec/mocks/tree.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function addNode(items, parent) {
2+
const indices = parent.getAttribute('data-index') ?? ''
3+
const path = indices.split('-').map(Number)
4+
5+
items.forEach((item, index) => {
6+
const node = document.createElement('node')
7+
const text = document.createElement('p')
8+
node.setAttribute('data-index', [...path, index].join('-'))
9+
node.scrollIntoView = vi.fn()
10+
text.textContent = item.text
11+
if (Array.isArray(item.children)) {
12+
const icon = document.createElement('icon')
13+
icon.setAttribute('data-state', 'opened')
14+
node.appendChild(icon)
15+
addNode(item.children, node)
16+
}
17+
node.appendChild(text)
18+
parent.appendChild(node)
19+
})
20+
}
21+
22+
export function createTree(items) {
23+
const root = document.createElement('div')
24+
addNode(items, root)
25+
return root
26+
}

0 commit comments

Comments
 (0)