diff --git a/CHANGELOG.md b/CHANGELOG.md index d051e59f1..fc3e9b4b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog for Fontra +## 2024-11-28 + +- Keep the focus on the canvas when clicking icon buttons and (some) list cell buttons [PR 1829](https://github.com/googlefonts/fontra/pull/1829) + ## 2024-11-27 - Add 'Add background image' menu to context menu [PR 1827](https://github.com/googlefonts/fontra/pull/1827) diff --git a/src/fontra/client/core/utils.js b/src/fontra/client/core/utils.js index 9a8d96b87..0c7849063 100644 --- a/src/fontra/client/core/utils.js +++ b/src/fontra/client/core/utils.js @@ -670,3 +670,16 @@ export function colorizeImage(inputImage, color) { }); }); } + +export class FocusKeeper { + get save() { + // Return a bound method that can be used as an event handler + return (event) => { + this._focusedElement = findNestedActiveElement(); + }; + } + + restore() { + this._focusedElement?.focus(); + } +} diff --git a/src/fontra/client/web-components/icon-button.js b/src/fontra/client/web-components/icon-button.js index 2e832e11f..f5204527f 100644 --- a/src/fontra/client/web-components/icon-button.js +++ b/src/fontra/client/web-components/icon-button.js @@ -1,6 +1,7 @@ import { InlineSVG } from "./inline-svg.js"; import * as html from "/core/html-utils.js"; import { UnlitElement } from "/core/html-utils.js"; +import { FocusKeeper } from "/core/utils.js"; export class IconButton extends UnlitElement { static styles = ` @@ -67,11 +68,14 @@ export class IconButton extends UnlitElement { } render() { + const focus = new FocusKeeper(); this._button = html.button( { + onmousedown: focus.save, onclick: (event) => { this._buttonOnClick?.(event); event.stopImmediatePropagation(); + focus.restore(); }, disabled: this._buttonDisabled, }, diff --git a/src/fontra/views/editor/panel-designspace-navigation.js b/src/fontra/views/editor/panel-designspace-navigation.js index 699813a0e..6e0a012e7 100644 --- a/src/fontra/views/editor/panel-designspace-navigation.js +++ b/src/fontra/views/editor/panel-designspace-navigation.js @@ -9,6 +9,7 @@ import { boolInt, enumerate, escapeHTMLCharacters, + FocusKeeper, objectsEqual, range, rgbaToCSS, @@ -1344,11 +1345,13 @@ function makeIconCellFactory( switchValue = null ) { return (item, colDesc) => { + const focus = new FocusKeeper(); const value = item[colDesc.key]; const clickSymbol = triggerOnDoubleClick ? "ondblclick" : "onclick"; const iconElement = html.createDomElement("inline-svg", { src: iconPaths[boolInt(value)], style: "width: 1.2em; height: 1.2em;", + onmousedown: focus.save, ondblclick: (event) => { event.stopImmediatePropagation(); }, @@ -1361,6 +1364,7 @@ function makeIconCellFactory( if (!selectItem) { event.stopImmediatePropagation(); } + focus.restore(); }, }); item[controllerKey].addKeyListener(colDesc.key, (event) => { @@ -1467,11 +1471,16 @@ function cellColorStyle(color) { } function makeClickableIconHeader(iconPath, onClick) { + const focus = new FocusKeeper(); return html.div( { class: "clickable-icon-header", style: "height: 1.2em; width: 1.2em;", - onclick: onClick, + onmousedown: focus.save, + onclick: (event) => { + onClick(event); + focus.restore(); + }, }, [ html.createDomElement("inline-svg", {