feat: add dropdown menu component

This commit is contained in:
2026-11-08 17:03:38 +07:00
parent 11b29dc91a
commit d8663593b6
10 changed files with 1244 additions and 197 deletions
+18 -8
View File
@@ -138,18 +138,16 @@ fn rows_render_at_the_stated_menu_row_height() {
fn arrow_navigation_skips_separators_and_disabled_items() {
let (_cx, mut visual, _window, changes, activated) = menu_window(true);
// Selection starts on the first item; down moves to the next
// selectable item (Copy, past the separator), and enter activates it,
// closing the menu.
visual.simulate_keystrokes("down");
visual.simulate_keystrokes("enter");
// Nothing is highlighted when the menu opens; down arms the first
// selectable item, the next down crosses the separator to Copy, and
// enter activates it, closing the menu.
visual.simulate_keystrokes("down down enter");
draw(&mut visual);
assert_eq!(*activated.borrow(), vec!["copy"]);
assert_eq!(*changes.borrow(), vec![false]);
// Reopen: the selection starts over on the first item, and end jumps
// straight to the last selectable item, over the separator and the
// disabled row.
// Reopen: pointer opens highlight nothing again, and end jumps straight
// to the last selectable item, over the separator and the disabled row.
click(&mut visual, point(px(10.), px(16.)));
draw(&mut visual);
visual.simulate_keystrokes("end");
@@ -158,6 +156,18 @@ fn arrow_navigation_skips_separators_and_disabled_items() {
assert_eq!(*changes.borrow(), vec![false, true, false]);
}
#[test]
fn enter_without_navigation_activates_nothing() {
let (_cx, mut visual, _window, changes, activated) = menu_window(true);
// A pointer-opened menu arms no row, so enter cannot fire one and the
// menu stays open.
visual.simulate_keystrokes("enter");
draw(&mut visual);
assert!(activated.borrow().is_empty());
assert!(changes.borrow().is_empty(), "the menu stays open");
}
#[test]
fn escape_dismisses_without_activating() {
let (_cx, mut visual, _window, changes, activated) = menu_window(true);