(props: DropdownMenuProps)
| 99 | /// - `data-disabled`: Indicates if the dropdown menu is disabled. values are `true` or `false`. |
| 100 | #[component] |
| 101 | pub fn DropdownMenu(props: DropdownMenuProps) -> Element { |
| 102 | let (open, set_open) = use_controlled(props.open, props.default_open, props.on_open_change); |
| 103 | |
| 104 | let disabled = props.disabled; |
| 105 | let trigger_id = use_unique_id(); |
| 106 | let focus = use_collection_provider(props.roving_loop); |
| 107 | let mut ctx = use_context_provider(|| DropdownMenuContext { |
| 108 | open, |
| 109 | set_open, |
| 110 | disabled, |
| 111 | focus, |
| 112 | trigger_id, |
| 113 | }); |
| 114 | |
| 115 | use_effect(move || { |
| 116 | let focused = focus.any_focused(); |
| 117 | if *ctx.open.peek() != focused { |
| 118 | (ctx.set_open)(focused); |
| 119 | } |
| 120 | }); |
| 121 | |
| 122 | // Handle escape key to close the menu |
| 123 | let handle_keydown = move |event: Event<KeyboardData>| { |
| 124 | if disabled() { |
| 125 | return; |
| 126 | } |
| 127 | match event.key() { |
| 128 | Key::Enter => { |
| 129 | let new_open = !(ctx.open)(); |
| 130 | ctx.set_open.call(new_open); |
| 131 | } |
| 132 | Key::Escape => ctx.set_open.call(false), |
| 133 | Key::ArrowDown => { |
| 134 | ctx.focus.focus_next(); |
| 135 | } |
| 136 | Key::ArrowUp => { |
| 137 | if open() { |
| 138 | ctx.focus.focus_prev(); |
| 139 | } |
| 140 | } |
| 141 | Key::Home => ctx.focus.focus_first(), |
| 142 | Key::End => ctx.focus.focus_last(), |
| 143 | _ => return, |
| 144 | } |
| 145 | event.prevent_default(); |
| 146 | }; |
| 147 | |
| 148 | rsx! { |
| 149 | div { |
| 150 | "data-state": if open() { "open" } else { "closed" }, |
| 151 | "data-disabled": (props.disabled)(), |
| 152 | onkeydown: handle_keydown, |
| 153 | ..props.attributes, |
| 154 | {props.children} |
| 155 | } |
| 156 | } |
| 157 | } |
| 158 |
nothing calls this directly
no test coverage detected