Skip to content

Commit 094884c

Browse files
committed
fix: Fix keyboard navigation for the continuous toolbox
1 parent 2de14cf commit 094884c

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

plugins/continuous-toolbox/src/ContinuousFlyout.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,23 @@ export class ContinuousFlyout extends Blockly.VerticalFlyout {
192192
this.scrollTo(position);
193193
}
194194

195+
/**
196+
* Returns the header item in the flyout corresponding to the given
197+
* toolbox category, if any.
198+
*/
199+
headerForCategory(
200+
category: Blockly.ISelectableToolboxItem,
201+
): Blockly.IFocusableNode | undefined {
202+
return this.getContents()
203+
.find((item) => {
204+
return (
205+
this.toolboxItemIsLabel(item) &&
206+
item.getElement().getButtonText() === category.getName()
207+
);
208+
})
209+
?.getElement();
210+
}
211+
195212
/**
196213
* Step the scrolling animation by scrolling a fraction of the way to
197214
* a scroll target, and request the next frame if necessary.

plugins/continuous-toolbox/src/ContinuousToolbox.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import * as Blockly from 'blockly/core';
1212
import {ContinuousFlyout} from './ContinuousFlyout';
13+
import {ContinuousToolboxNavigator} from './ContinuousToolboxNavigator';
1314

1415
/**
1516
* Class for continuous toolbox.
@@ -21,6 +22,12 @@ export class ContinuousToolbox extends Blockly.Toolbox {
2122
*/
2223
private refreshDebouncer?: ReturnType<typeof setTimeout>;
2324

25+
/**
26+
* Navigator object responsible for handling keyboard navigation within this
27+
* toolbox.
28+
*/
29+
private continuousToolboxNavigator = new ContinuousToolboxNavigator(this);
30+
2431
/**
2532
* Initializes the continuous toolbox.
2633
*/
@@ -192,4 +199,12 @@ export class ContinuousToolbox extends Blockly.Toolbox {
192199
}
193200
return super.getClientRect();
194201
}
202+
203+
/**
204+
* Returns the Navigator object responsible for handling keyboard navigation
205+
* inside this toolbox.
206+
*/
207+
override getNavigator(): Blockly.ToolboxNavigator {
208+
return this.continuousToolboxNavigator;
209+
}
195210
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @license
3+
* Copyright 2026 Raspberry Pi Foundation
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import * as Blockly from 'blockly/core';
8+
import {ContinuousToolbox} from './ContinuousToolbox';
9+
import {ContinuousCategory} from './ContinuousCategory';
10+
11+
/**
12+
* A Navigator that handles keyboard navigation within a continuous toolbox.
13+
*/
14+
export class ContinuousToolboxNavigator extends Blockly.ToolboxNavigator {
15+
constructor(protected toolbox: ContinuousToolbox) {
16+
super(toolbox);
17+
}
18+
19+
/**
20+
* Returns the next node when navigating "in", in this case the first flyout
21+
* item in the toolbox's currently selected category.
22+
*/
23+
override getInNode(
24+
node = Blockly.getFocusManager().getFocusedNode(),
25+
): Blockly.IFocusableNode | null {
26+
if (!(node instanceof ContinuousCategory)) return null;
27+
return this.toolbox.getFlyout().headerForCategory(node) ?? null;
28+
}
29+
}

0 commit comments

Comments
 (0)