From 33d6a1efd1040def464023eba7f6f66367db4c2e Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Sat, 18 Jul 2026 05:44:52 +0300 Subject: [PATCH] fix(app): align property item subcontrols - Keep Fill and Effects settings inside their shared content rails\n- Use panel spacing tokens instead of ad-hoc offsets\n- Preserve selection when Escape dismisses overlays\n- Label the Font settings trigger for assistive technology --- CHANGELOG.md | 1 + src/app/shell/keyboard/registry.ts | 22 +- .../FontSettings/FontSettingsPopover.vue | 6 +- src/components/properties/EffectsSection.vue | 313 +++++++++--------- src/components/properties/FillSection.vue | 142 ++++---- tests/e2e/design/panel.spec.ts | 28 +- ...paint-effects-export-openpencil-darwin.png | Bin 24158 -> 24280 bytes ...-position-appearance-openpencil-darwin.png | Bin 23398 -> 23827 bytes tests/e2e/fonts/settings.spec.ts | 7 +- 9 files changed, 288 insertions(+), 231 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 179bb5fa8..6f0f96db1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ ### Fixes +- Align Fill and Effects sub-controls to their shared property-row content rails, and improve font-settings accessibility without clearing selection when dismissing overlays. - Restore the Variables dialog empty state, full-width table layout, unclipped type menu, and expected Escape handling in dialogs and popup menus. - Pin the patched `websocket-driver` release used through Trystero/Firebase collaboration to resolve a critical protocol-length advisory. - Preserve unrelated Figma prototype, library, export, and raw metadata when editing modeled `.fig` fields, while still overriding stale field-specific payloads. diff --git a/src/app/shell/keyboard/registry.ts b/src/app/shell/keyboard/registry.ts index 8bb08aff2..2a23b6bb9 100644 --- a/src/app/shell/keyboard/registry.ts +++ b/src/app/shell/keyboard/registry.ts @@ -50,12 +50,23 @@ function opacityBindings(): ShortcutDefinition[] { })) } +const EDITOR_SHORTCUT_OVERLAY_SELECTOR = + '[data-picker-content], [role="dialog"], [role="listbox"], [role="menu"]' + +function originatedInOverlay(event: KeyboardEvent) { + return event + .composedPath() + .some((target) => target instanceof Element && target.matches(EDITOR_SHORTCUT_OVERLAY_SELECTOR)) +} + +function hasOpenDismissableLayer() { + return document.querySelector('[data-dismissable-layer]') !== null +} + function shouldIgnoreShortcut(event: KeyboardEvent, options: KeyboardShortcutOptions) { return ( - (event.target instanceof Element && - event.target.closest( - '[data-picker-content], [role="dialog"], [role="listbox"], [role="menu"]' - ) !== null) || + hasOpenDismissableLayer() || + originatedInOverlay(event) || isEditing(event) || options.inputFocused.value || !!options.store.state.editingTextId || @@ -177,7 +188,8 @@ export function registerKeyboardShortcuts(options: KeyboardShortcutOptions) { handler(event) } ]) - ) + ), + { capture: true } ) onScopeDispose(unsubscribe) diff --git a/src/components/FontSettings/FontSettingsPopover.vue b/src/components/FontSettings/FontSettingsPopover.vue index 19fa64570..29190139e 100644 --- a/src/components/FontSettings/FontSettingsPopover.vue +++ b/src/components/FontSettings/FontSettingsPopover.vue @@ -76,7 +76,11 @@ onMounted(() => {