Merge pull request #659 from derechopiano:fix/autofilter-keyboard-access

This commit is contained in:
Brandon Thomas 2026-10-13 00:07:41 -04:00
commit bf4c88f3db
3 changed files with 71 additions and 0 deletions

View File

@ -221,6 +221,9 @@ pub(crate) fn dispatch(app: &mut SheetApp, ctx: &egui::Context, key: Key, physic
Shortcut::DropDown => {
if sh.validations.iter().any(|d| d.in_cell_dropdown && d.ranges.iter().any(|r| r.contains(active))) {
app.grid.list_picker = Some(active);
} else if sh.has_filter_button(active) {
let at = geo.mirror_pos(crate::grid::filter_button_rect(geo, sh, active).center());
app.grid.filter_menu = Some((active.col, at));
}
}
Shortcut::Zoom(step) => {

View File

@ -149,3 +149,68 @@ fn space_shortcuts_per_platform() {
// Cmd+Space is Spotlight on macOS.
assert_eq!(space(mac_cmd, true), None);
}
#[test]
fn alt_down_opens_autofilter_headers_without_changing_the_workbook() {
for rtl in [false, true] {
for cell in ["A1", "B1"] {
let mut session = book(cell);
session.execute("data.filter", json!({"range": "A1:B3"})).unwrap();
session.execute("view.rightToLeft", json!({"on": rtl})).unwrap();
let mut h = harness(session);
let before = h.state().session.active().unwrap().wb.clone();
key(&mut h, Key::ArrowDown, Modifiers::ALT);
let (column, at) = h.state().grid.filter_menu.expect("Alt+Down must open the filter header menu");
let d = h.state().session.active().unwrap();
let active = CellRef::parse(cell).unwrap();
assert_eq!(column, active.col);
assert_eq!(d.selection.active, active);
assert_eq!(d.wb, before);
let sh = d.wb.active().unwrap();
let geo = gridcraft_ui_egui::grid::Geo::new(sh, h.state().grid.rect.unwrap(), h.state().view().scroll);
assert_eq!(at, geo.mirror_pos(gridcraft_ui_egui::grid::filter_button_rect(&geo, sh, active).center()));
// Opening focuses the existing search box; typing must not edit the header.
h.input_mut().events.push(Event::Text("1".into()));
h.run_steps(2);
assert_eq!(h.ctx.data(|data| data.get_temp::<String>(egui::Id::new(("filter_search", column)))).as_deref(), Some("1"));
assert!(h.state().editor.is_none());
assert_eq!(h.state().session.active().unwrap().wb, before);
key(&mut h, Key::Escape, Modifiers::NONE);
assert!(h.state().grid.filter_menu.is_none());
}
}
}
#[test]
fn alt_down_keeps_validation_priority_and_plain_down_navigation() {
let mut session = book("A1");
session.execute("data.filter", json!({"range": "A1:B3"})).unwrap();
session.execute("data.validation", json!({"range": "A1", "type": "list", "formula1": "\"First,Second\""})).unwrap();
let mut h = harness(session);
key(&mut h, Key::ArrowDown, Modifiers::ALT);
assert_eq!(h.state().grid.list_picker, Some(CellRef::parse("A1").unwrap()));
assert!(h.state().grid.filter_menu.is_none());
key(&mut h, Key::Escape, Modifiers::NONE);
key(&mut h, Key::ArrowDown, Modifiers::NONE);
assert_eq!(h.state().session.active().unwrap().selection.active.a1(), "A2");
assert!(h.state().grid.filter_menu.is_none());
key(&mut h, Key::ArrowDown, Modifiers::ALT);
assert!(h.state().grid.filter_menu.is_none(), "a data cell has no filter button");
assert_eq!(h.state().session.active().unwrap().selection.active.a1(), "A2");
}
#[test]
fn alt_down_only_opens_enabled_table_filter_buttons() {
for enabled in [false, true] {
let mut session = book("B1");
session.execute("insert.table", json!({"range": "A1:B3"})).unwrap();
if !enabled {
session.execute("table.headerRow", json!({"on": false})).unwrap();
}
session.execute("selection.set", json!({"cell": "B1"})).unwrap();
let mut h = harness(session);
key(&mut h, Key::ArrowDown, Modifiers::ALT);
assert_eq!(h.state().grid.filter_menu.map(|(column, _)| column), enabled.then_some(1));
assert_eq!(h.state().session.active().unwrap().selection.active.a1(), "B1");
}
}

View File

@ -1,5 +1,6 @@
# UI parity
> **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (Alt+Down opens AutoFilter header menus) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-12 · **Change:** minor (ribbon and menu Paste paste the system clipboard like Cmd/Ctrl+V; regression test for the Paste button freeze, #273; Paste button gets an accessible name) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
Interaction, controls and feel, against Excel. Part of [target-app-parity.md](target-app-parity.md).
@ -117,6 +118,7 @@ otherwise. Number-format and border keys match the physical key (Ctrl+Shift+4, w
| Ctrl+Alt+V | Cmd+Control+V, Cmd+Option+V | Paste Special | **added** |
| Ctrl+Alt+= / Ctrl+Alt+- | — | zoom in / out (10% steps) | **added** |
| Alt+=, Alt+Down, Alt+Page Down / Up | Option+Down, Option+Page Down / Up | AutoSum, drop-down list, one screen right / left | **added** |
| Alt+Down on a filter header | Option+Down | Open the existing AutoFilter popup; validation dropdowns keep priority | **added** (AutoFilter portion of #441; Ribbon dropdowns and column value picker are separate work) |
| Alt+F1, Alt+Shift+F1, Shift+F11 | Shift+F11 | embedded chart, new sheet | **added** |
| Shift+F2, Ctrl+Shift+F2 | Shift+F2, Cmd+Shift+F2 | note, threaded comment | **added** |
| Shift+F3, Ctrl+F3, Ctrl+Shift+F3 | Shift+F3, Cmd+F3 (Define Name), Cmd+Shift+F3 | Insert Function, Name Manager, Create from Selection | **added** |
@ -160,6 +162,7 @@ scrollbar bugs 2–4 · pixel/feel pass against observed Excel 7–12.
| Date | Change | Summary |
|---|---|---|
| 2026-10-12 | minor | Alt+Down opens the active filter header's existing popup, with validation priority and mirrored anchoring on right-to-left sheets (part of #441) |
| 2026-10-12 | minor | Paste from the ribbon (button and options menu), the cell and header context menus and the macOS menu bar's Edit menu pastes what is on the system clipboard, as Cmd/Ctrl+V does, instead of only GridCraft's own copy (the web build, which can't read the clipboard on request, still pastes GridCraft's copy). Copy and Cut by keytip (H,C / H,X) publish to the system clipboard like the ribbon buttons. After a control-channel or MCP copy, which leaves the system clipboard alone, Paste pastes that copy until other text is copied. Once a cut has been pasted, Paste (ribbon, menus or Cmd/Ctrl+V) doesn't paste the cut's clipboard text again over the moved cells (Excel pastes a cut once), and the Paste keytip (H,V,P) pastes the system clipboard like the button. Regression test for the Paste button click freeze in 0.5.0 (#273, fixed by #272); the Paste button gets an accessible "Paste" name for screen readers |
| 2026-10-11 | minor | AutoFit accounts for table and ordinary filter dropdowns, including low zoom; header text excludes the button area |
| 2026-10-11 | minor | Outline band for grouped rows and columns, Show / Hide Detail on the Data tab, numpad navigation keys in shortcuts (#373) |