Free
2026-09-11
base-uileptosfocus-managementreverse-engineering
Reverse-engineering Base UI's useDialog: the focus trap, mapped
Base UI's useDialog hook implements a sophisticated focus management system that ensures accessibility while providing a smooth user experience. This reverse-engineering analysis breaks down the focus trap mechanism and outlines strategies for porting to Leptos.
# Focus trap mechanics
The focus trap implementation in Base UI follows these key principles:
- Initial focus: When a dialog opens, focus is automatically moved to the first focusable element
- Tab navigation: Tab and Shift+Tab keys are intercepted to keep focus within the dialog
- Escape handling: The Escape key closes the dialog and returns focus to the trigger element
- Click outside: Clicks outside the dialog close it and restore focus
# Leptos porting considerations
The challenge with Leptos is that it doesn't have direct equivalents to React's imperative focus management. We'll need to:
// Leptos equivalent concept (pseudocode)
#[component]
pub fn Dialog(children: Children) -> impl IntoView {
let focus_manager = FocusManager::new();
view! {
<div
on:focus=move |ev| { focus_manager.handle_focus(ev) }
on:keydown=move |ev| { focus_manager.handle_keydown(ev) }
>
{children}
</div>
}
}# Implementation patterns
The Base UI source reveals several important patterns:
- Focusable element detection: Uses
querySelectorAllwith a specific selector - Focus restoration: Maintains a reference to the previously focused element
- Event delegation: Uses a single event listener on the dialog container
This analysis provides the foundation for building an accessible Leptos dialog component.