fix(design): the saved-view chip on one line, one Escape per layer, the /watch action row (E28 S3d)
- SelectTrigger lays its toolbar value out as a row; the saved-view chip passes its glyph and modified dot through the icon/trailing slots (an <svg> is display:block and broke the chip in two). - One Escape in a dialog's open list closed the list AND the dialog: the list's close flushes synchronously and pops its layer before the dialog's window listener runs. takeEscape() is the one close-on-Escape test (topmost AND not yet taken); Modal, the Welcome lightbox and useLayer use it, and keymap.dispatch ignores a taken Escape. - /watch: the Download sits on the toolbar rung, level with the Repeat chip.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useRef, type RefObject } from "react";
|
||||
import { anyBlockingLayer } from "./layerStack";
|
||||
import { anyBlockingLayer, escapeHandled } from "./layerStack";
|
||||
import { createStore } from "./store";
|
||||
import type { Page } from "./urlState";
|
||||
|
||||
@@ -322,6 +322,9 @@ export function dispatch<S extends KeyScope>(
|
||||
handlers: { readonly [K in ShortcutId<S>]: (e: KeyboardEvent) => void },
|
||||
): boolean {
|
||||
if (sequenceEvents.has(e)) return false;
|
||||
// An Escape a layer already took (a menu that just closed) is spent: a page or a player reacting to
|
||||
// it too is the double close the layer stack exists to prevent.
|
||||
if (e.key === "Escape" && escapeHandled(e)) return false;
|
||||
const live = liveSequence(e);
|
||||
if (live && live.scope !== scope) return false;
|
||||
const quiet = isPageLevelScope(scope) && anyBlockingLayer();
|
||||
|
||||
Reference in New Issue
Block a user