Skip to content

Commit e51287d

Browse files
committed
chore: add focus ability
1 parent a00c0bf commit e51287d

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

polaris-react/src/components/BulkActions/BulkActions.tsx

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {debounce} from '../../utilities/debounce';
55
import {classNames} from '../../utilities/css';
66
import {useI18n} from '../../utilities/i18n';
77
import {clamp} from '../../utilities/clamp';
8+
import {findFirstKeyboardFocusableNode} from '../../utilities/focus';
89
import type {
910
BadgeAction,
1011
DisableableAction,
@@ -63,6 +64,7 @@ class BulkActionsInner extends PureComponent<CombinedProps, State> {
6364
private containerNode: HTMLElement | null = null;
6465
private buttonsNode: HTMLElement | null = null;
6566
private moreActionsNode: HTMLElement | null = null;
67+
private activatorNode: Element | null = null;
6668
private groupNode = createRef<HTMLDivElement>();
6769
private promotedActionsWidths: number[] = [];
6870
private bulkActionsWidth = 0;
@@ -89,6 +91,25 @@ class BulkActionsInner extends PureComponent<CombinedProps, State> {
8991
{trailing: true},
9092
);
9193

94+
private focusContent() {
95+
if (this.containerNode == null) {
96+
return;
97+
}
98+
99+
requestAnimationFrame(() => {
100+
if (this.containerNode == null) {
101+
return;
102+
}
103+
104+
const focusableChild = findFirstKeyboardFocusableNode(this.containerNode);
105+
if (focusableChild) {
106+
focusableChild.focus({
107+
preventScroll: process.env.NODE_ENV === 'development',
108+
});
109+
}
110+
});
111+
}
112+
92113
private numberOfPromotedActionsToRender(): number {
93114
const {promotedActions} = this.props;
94115
const {containerWidth, measuring} = this.state;
@@ -178,6 +199,11 @@ class BulkActionsInner extends PureComponent<CombinedProps, State> {
178199
this.addedMoreActionsWidthForMeasuring
179200
: 0;
180201

202+
if (document?.activeElement) {
203+
this.activatorNode = document.activeElement;
204+
}
205+
this.focusContent();
206+
181207
if (this.containerNode) {
182208
this.setState({
183209
containerWidth: this.containerNode.getBoundingClientRect().width,
@@ -321,7 +347,11 @@ class BulkActionsInner extends PureComponent<CombinedProps, State> {
321347
</Transition>
322348
);
323349

324-
return <div ref={this.setContainerNode}>{group}</div>;
350+
return (
351+
<div ref={this.setContainerNode} onBlur={this.handleBlur}>
352+
{group}
353+
</div>
354+
);
325355
}
326356

327357
private isNewBadgeInBadgeActions() {
@@ -365,6 +395,18 @@ class BulkActionsInner extends PureComponent<CombinedProps, State> {
365395
this.promotedActionsWidths.push(width);
366396
}
367397
};
398+
399+
private handleBlur = (event: React.FocusEvent<HTMLDivElement>) => {
400+
const currentTarget = event.currentTarget;
401+
402+
// Give browser time to focus the next element
403+
requestAnimationFrame(() => {
404+
// Check if the new focused element is a child of the original container
405+
if (!currentTarget.contains(document.activeElement)) {
406+
console.log('blurrin yo');
407+
}
408+
});
409+
};
368410
}
369411

370412
function instanceOfBulkActionListSectionArray(

0 commit comments

Comments
 (0)