Skip to content

Commit a1be83b

Browse files
authored
refactor: Make INavigable extend IFocusableNode. (#9033)
1 parent 77bfa5b commit a1be83b

16 files changed

+135
-72
lines changed

core/block_svg.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,15 +1824,6 @@ export class BlockSvg
18241824
return true;
18251825
}
18261826

1827-
/**
1828-
* Returns whether or not this block can be navigated to via the keyboard.
1829-
*
1830-
* @returns True if this block is keyboard navigable, otherwise false.
1831-
*/
1832-
isNavigable() {
1833-
return true;
1834-
}
1835-
18361827
/**
18371828
* Returns this block's class.
18381829
*

core/field.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,20 +1385,6 @@ export abstract class Field<T = any>
13851385
);
13861386
}
13871387

1388-
/**
1389-
* Returns whether or not this field is accessible by keyboard navigation.
1390-
*
1391-
* @returns True if this field is keyboard accessible, otherwise false.
1392-
*/
1393-
isNavigable() {
1394-
return (
1395-
this.isClickable() &&
1396-
this.isCurrentlyEditable() &&
1397-
!(this.getSourceBlock()?.isSimpleReporter() && this.isFullBlockField()) &&
1398-
this.getParentInput().isVisible()
1399-
);
1400-
}
1401-
14021388
/**
14031389
* Returns this field's class.
14041390
*

core/flyout_button.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -413,16 +413,6 @@ export class FlyoutButton
413413
return true;
414414
}
415415

416-
/**
417-
* Returns whether or not this button is accessible through keyboard
418-
* navigation.
419-
*
420-
* @returns True if this button is keyboard accessible, otherwise false.
421-
*/
422-
isNavigable() {
423-
return true;
424-
}
425-
426416
/**
427417
* Returns this button's class.
428418
*

core/flyout_separator.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
*/
66

77
import type {IBoundedElement} from './interfaces/i_bounded_element.js';
8+
import type {IFocusableNode} from './interfaces/i_focusable_node.js';
9+
import type {IFocusableTree} from './interfaces/i_focusable_tree.js';
810
import type {INavigable} from './interfaces/i_navigable.js';
911
import {Rect} from './utils/rect.js';
1012

1113
/**
1214
* Representation of a gap between elements in a flyout.
1315
*/
1416
export class FlyoutSeparator
15-
implements IBoundedElement, INavigable<FlyoutSeparator>
17+
implements IBoundedElement, INavigable<FlyoutSeparator>, IFocusableNode
1618
{
1719
private x = 0;
1820
private y = 0;
@@ -75,6 +77,27 @@ export class FlyoutSeparator
7577
getClass() {
7678
return FlyoutSeparator;
7779
}
80+
81+
/** See IFocusableNode.getFocusableElement. */
82+
getFocusableElement(): HTMLElement | SVGElement {
83+
throw new Error('Cannot be focused');
84+
}
85+
86+
/** See IFocusableNode.getFocusableTree. */
87+
getFocusableTree(): IFocusableTree {
88+
throw new Error('Cannot be focused');
89+
}
90+
91+
/** See IFocusableNode.onNodeFocus. */
92+
onNodeFocus(): void {}
93+
94+
/** See IFocusableNode.onNodeBlur. */
95+
onNodeBlur(): void {}
96+
97+
/** See IFocusableNode.canBeFocused. */
98+
canBeFocused(): boolean {
99+
return false;
100+
}
78101
}
79102

80103
/**

core/interfaces/i_navigable.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,12 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
import type {IFocusableNode} from './i_focusable_node.js';
8+
79
/**
810
* Represents a UI element which can be navigated to using the keyboard.
911
*/
10-
export interface INavigable<T> {
11-
/**
12-
* Returns whether or not this specific instance should be reachable via
13-
* keyboard navigation.
14-
*
15-
* Implementors should generally return true, unless there are circumstances
16-
* under which this item should be skipped while using keyboard navigation.
17-
* Common examples might include being disabled, invalid, readonly, or purely
18-
* a visual decoration. For example, while Fields are navigable, non-editable
19-
* fields return false, since they cannot be interacted with when focused.
20-
*
21-
* @returns True if this element should be included in keyboard navigation.
22-
*/
23-
isNavigable(): boolean;
24-
12+
export interface INavigable<T> extends IFocusableNode {
2513
/**
2614
* Returns the class of this instance.
2715
*

core/interfaces/i_navigation_policy.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,18 @@ export interface INavigationPolicy<T> {
4343
* there is none.
4444
*/
4545
getPreviousSibling(current: T): INavigable<any> | null;
46+
47+
/**
48+
* Returns whether or not the given instance should be reachable via keyboard
49+
* navigation.
50+
*
51+
* Implementors should generally return true, unless there are circumstances
52+
* under which this item should be skipped while using keyboard navigation.
53+
* Common examples might include being disabled, invalid, readonly, or purely
54+
* a visual decoration. For example, while Fields are navigable, non-editable
55+
* fields return false, since they cannot be interacted with when focused.
56+
*
57+
* @returns True if this element should be included in keyboard navigation.
58+
*/
59+
isNavigable(current: T): boolean;
4660
}

core/keyboard_nav/block_navigation_policy.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,14 @@ export class BlockNavigationPolicy implements INavigationPolicy<BlockSvg> {
114114
}
115115
return block.outputConnection;
116116
}
117+
118+
/**
119+
* Returns whether or not the given block can be navigated to.
120+
*
121+
* @param current The instance to check for navigability.
122+
* @returns True if the given block can be focused.
123+
*/
124+
isNavigable(current: BlockSvg): boolean {
125+
return current.canBeFocused();
126+
}
117127
}

core/keyboard_nav/connection_navigation_policy.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,14 @@ export class ConnectionNavigationPolicy
166166
}
167167
return block.outputConnection;
168168
}
169+
170+
/**
171+
* Returns whether or not the given connection can be navigated to.
172+
*
173+
* @param current The instance to check for navigability.
174+
* @returns True if the given connection can be focused.
175+
*/
176+
isNavigable(current: RenderedConnection): boolean {
177+
return current.canBeFocused();
178+
}
169179
}

core/keyboard_nav/field_navigation_policy.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,23 @@ export class FieldNavigationPolicy implements INavigationPolicy<Field<any>> {
8888
}
8989
return null;
9090
}
91+
92+
/**
93+
* Returns whether or not the given field can be navigated to.
94+
*
95+
* @param current The instance to check for navigability.
96+
* @returns True if the given field can be focused and navigated to.
97+
*/
98+
isNavigable(current: Field<any>): boolean {
99+
return (
100+
current.canBeFocused() &&
101+
current.isClickable() &&
102+
current.isCurrentlyEditable() &&
103+
!(
104+
current.getSourceBlock()?.isSimpleReporter() &&
105+
current.isFullBlockField()
106+
) &&
107+
current.getParentInput().isVisible()
108+
);
109+
}
91110
}

core/keyboard_nav/flyout_button_navigation_policy.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,14 @@ export class FlyoutButtonNavigationPolicy
5353
getPreviousSibling(_current: FlyoutButton): INavigable<unknown> | null {
5454
return null;
5555
}
56+
57+
/**
58+
* Returns whether or not the given flyout button can be navigated to.
59+
*
60+
* @param current The instance to check for navigability.
61+
* @returns True if the given flyout button can be focused.
62+
*/
63+
isNavigable(current: FlyoutButton): boolean {
64+
return current.canBeFocused();
65+
}
5666
}

0 commit comments

Comments
 (0)