//! The keyboard shortcuts this site offers, and the overlay that lists them. //! //! The only other `Chrome` in the tree is `Chrome::new()`, the empty default, //! used twice in [`super::embeds`] for embeds that deliberately have no shell. //! Every converted screen inherits the shortcut with no further work. //! //! # What quasi does, and what this owns //! //! quasi wires the key and does not draw the listing. //! `quasi-webview`'s `binding_html` emits a hidden button whose action targets //! the overlay container, and that is all of it; `Binding::group` names "the //! heading a listing shows it beneath", which says plainly that the listing is //! a screen the app describes. So the plumbing is quasi's and the screen is //! ours. There is no renderer-drawn help overlay to go looking for. //! //! # Its own mount, not a route inside the pricing nest //! //! An overlay reachable from every screen is not one screen's route. The //! binding's address is absolute in the emitted markup, so registering it under //! `/pricing` would give the site-wide shortcut a pricing-shaped address and //! move it the first time a second screen converted. use quasi_router::screen::{Cell, Column, Row, Table}; use quasi_router::{ Action, Chrome, Node, Outcome, RegionKind, Request, Response, RouteError, Router, Screen, Slot, }; /// Where the listing answers. pub const PATH: &str = "/shortcuts"; /// The key that opens it. const OPENS: &str = "?"; /// What this site binds. /// /// One binding, and the listing below says why the other three are not here: /// a `Binding` carries an [`Action`], and Escape, Cmd+S and Cmd+K perform no /// route. They are `static/dist/core/keyboard.js`'s, and they move into this /// function on the day the description layer can say what they do. /// /// Hung on the shell rather than built per screen, so every described screen /// this server serves offers it and none of them has to remember to. #[must_use] pub fn chrome() -> Chrome { Chrome::new().bind(OPENS, "Keyboard shortcuts", Action::get(PATH)) } /// One key and what it does, for the listing. /// /// The described binding is read off [`chrome`] rather than written again here, /// which is the point `Binding::label` exists to make: a help overlay that /// lists the bindings is otherwise a second, hand-written copy that drifts. /// The host keys have no `Binding` to read, so they are spelled -- once, beside /// the declaration, rather than in a template. const HOST_KEYS: &[(&str, &str)] = &[ ("Cmd+K", "Search"), ("Esc", "Close modal or overlay"), ("Cmd+S", "Save the current form"), ]; /// The listing, drawn over whatever the reader was looking at. /// /// A table because that is what it is: two columns, one row per key. The /// shipped overlay was a hand-written `