Skip to content

Commit 3c7add5

Browse files
authored
fix: Make non-autoclosing flyouts stay open. (#9245)
* chore: Add tests for toolbox/flyout/focus autoclose behavior. * fix: Don't force-close non-autoclosing flyouts.
1 parent 908712e commit 3c7add5

3 files changed

Lines changed: 54 additions & 11 deletions

File tree

core/toolbox/toolbox.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ import '../events/events_toolbox_item_select.js';
2222
import {EventType} from '../events/type.js';
2323
import * as eventUtils from '../events/utils.js';
2424
import {getFocusManager} from '../focus_manager.js';
25-
import {
26-
isAutoHideable,
27-
type IAutoHideable,
28-
} from '../interfaces/i_autohideable.js';
25+
import {type IAutoHideable} from '../interfaces/i_autohideable.js';
2926
import type {ICollapsibleToolboxItem} from '../interfaces/i_collapsible_toolbox_item.js';
3027
import {isDeletable} from '../interfaces/i_deletable.js';
3128
import type {IDraggable} from '../interfaces/i_draggable.js';
@@ -1150,10 +1147,7 @@ export class Toolbox
11501147
// If navigating to anything other than the toolbox's flyout then clear the
11511148
// selection so that the toolbox's flyout can automatically close.
11521149
if (!nextTree || nextTree !== this.flyout?.getWorkspace()) {
1153-
this.clearSelection();
1154-
if (this.flyout && isAutoHideable(this.flyout)) {
1155-
this.flyout.autoHide(false);
1156-
}
1150+
this.autoHide(false);
11571151
}
11581152
}
11591153
}

core/workspace_svg.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2908,11 +2908,9 @@ export class WorkspaceSvg
29082908
// Only hide the flyout if the flyout's workspace is losing focus and that
29092909
// focus isn't returning to the flyout itself, the toolbox, or ephemeral.
29102910
if (getFocusManager().ephemeralFocusTaken()) return;
2911-
const flyout = this.targetWorkspace.getFlyout();
29122911
const toolbox = this.targetWorkspace.getToolbox();
29132912
if (toolbox && nextTree === toolbox) return;
2914-
if (toolbox) toolbox.clearSelection();
2915-
if (flyout && isAutoHideable(flyout)) flyout.autoHide(false);
2913+
if (isAutoHideable(toolbox)) toolbox.autoHide(false);
29162914
}
29172915
}
29182916

tests/mocha/toolbox_test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,57 @@ suite('Toolbox', function () {
183183
});
184184
});
185185

186+
suite('focus management', function () {
187+
setup(function () {
188+
this.toolbox = getInjectedToolbox();
189+
});
190+
teardown(function () {
191+
this.toolbox.dispose();
192+
});
193+
194+
test('Losing focus hides autoclosing flyout', function () {
195+
// Focus the toolbox and select a category to open the flyout.
196+
const target = this.toolbox.HtmlDiv.querySelector(
197+
'.blocklyToolboxCategory',
198+
);
199+
Blockly.getFocusManager().focusNode(this.toolbox);
200+
target.dispatchEvent(
201+
new PointerEvent('pointerdown', {
202+
target,
203+
bubbles: true,
204+
}),
205+
);
206+
assert.isTrue(this.toolbox.getFlyout().isVisible());
207+
208+
// Focus the workspace to trigger the toolbox to close the flyout.
209+
Blockly.getFocusManager().focusNode(this.toolbox.getWorkspace());
210+
assert.isFalse(this.toolbox.getFlyout().isVisible());
211+
});
212+
213+
test('Losing focus does not hide non-autoclosing flyout', function () {
214+
// Make the toolbox's flyout non-autoclosing.
215+
this.toolbox.getFlyout().setAutoClose(false);
216+
217+
// Focus the toolbox and select a category to open the flyout.
218+
const target = this.toolbox.HtmlDiv.querySelector(
219+
'.blocklyToolboxCategory',
220+
);
221+
Blockly.getFocusManager().focusNode(this.toolbox);
222+
target.dispatchEvent(
223+
new PointerEvent('pointerdown', {
224+
target,
225+
bubbles: true,
226+
}),
227+
);
228+
assert.isTrue(this.toolbox.getFlyout().isVisible());
229+
230+
// Focus the workspace; this should *not* trigger the toolbox to close the
231+
// flyout, which should remain visible.
232+
Blockly.getFocusManager().focusNode(this.toolbox.getWorkspace());
233+
assert.isTrue(this.toolbox.getFlyout().isVisible());
234+
});
235+
});
236+
186237
suite('onClick_', function () {
187238
setup(function () {
188239
this.toolbox = getInjectedToolbox();

0 commit comments

Comments
 (0)