Skip to content

Commit d3366ec

Browse files
fix(FEC-12918): When users close a menu by clicking the close button, focus should go back to the button that opened the plugin (#297)
* fix(FEC-12918): handle focus change on plugin close * fix(FEC-12918): upd dependencies
1 parent 1a06e58 commit d3366ec

File tree

6 files changed

+57
-16
lines changed

6 files changed

+57
-16
lines changed

cypress/e2e/navigation.cy.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,20 @@ describe('Navigation plugin', () => {
8787
cy.get('[data-testid="navigation_root"]').should('have.css', 'visibility', 'hidden');
8888
});
8989

90-
it('should open the navigation side panel if expandOnFirstPlay configuration is true ', () => {
90+
it('should open the navigation side panel if expandOnFirstPlay configuration is true', () => {
9191
mockKalturaBe();
9292
preparePage({expandOnFirstPlay: true}, {muted: true, autoplay: true});
9393
cy.get('[data-testid="navigation_pluginButton"]').should('exist');
9494
cy.get('[data-testid="navigation_root"]').should('have.css', 'visibility', 'visible');
9595
});
96+
97+
it('should close plugin if ESC button pressed', () => {
98+
mockKalturaBe();
99+
preparePage({expandOnFirstPlay: true}, {muted: true, autoplay: true});
100+
cy.get('[data-testid="navigation_root"]').should('have.css', 'visibility', 'visible');
101+
cy.get("[aria-label='Search in video']").type('{esc}');
102+
cy.get('[data-testid="navigation_root"]').should('have.css', 'visibility', 'hidden');
103+
});
96104
});
97105

98106
describe('navigation data', () => {
@@ -161,6 +169,15 @@ describe('Navigation plugin', () => {
161169
});
162170

163171
describe('search and filter', () => {
172+
it('should set focus to search input if plugin opened by keyboard', () => {
173+
mockKalturaBe();
174+
preparePage();
175+
cy.get('[data-testid="navigation_pluginButton"]').should('exist').trigger('keydown', {
176+
keyCode: 32, // Space
177+
force: true
178+
});
179+
cy.get("[aria-label='Search in video']").should('have.focus');
180+
});
164181
it('should test search bar', () => {
165182
mockKalturaBe();
166183
preparePage({expandOnFirstPlay: true}, {muted: true, autoplay: true});

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"url": "git+https://github.com/kaltura/playkit-js-navigation.git"
1313
},
1414
"dependencies": {
15-
"@playkit-js/common": "^1.0.18",
15+
"@playkit-js/common": "^1.1.0",
1616
"@playkit-js/playkit-js-ui": "^0.73.0",
1717
"@playkit-js/ui-managers": "^1.3.2"
1818
},

src/components/navigation/index.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {h, Component} from 'preact';
22
import * as styles from './navigaton.scss';
3+
import {OnClick} from '@playkit-js/common';
34
import {NavigationList} from './navigation-list/NavigationList';
45
import {NavigationSearch} from '../navigation-search/navigation-search';
56
import {NavigationFilter} from '../navigation-filter';
@@ -31,7 +32,7 @@ export interface SearchFilter {
3132
export interface NavigationProps {
3233
data: Array<ItemData>;
3334
onItemClicked(time: number): void;
34-
onClose: () => void;
35+
onClose: OnClick;
3536
retry?: () => void;
3637
isLoading: boolean;
3738
hasError: boolean;
@@ -237,7 +238,7 @@ export class Navigation extends Component<NavigationProps, NavigationState> {
237238

238239
private _handleClose = (event: KeyboardEvent) => {
239240
if (event.keyCode === KeyMap.ESC) {
240-
this.props.onClose();
241+
this.props.onClose(event, true);
241242
}
242243
};
243244

src/components/navigation/plugin-button/index.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@ const translates = ({isActive}: PluginButtonProps) => {
1616
interface PluginButtonProps {
1717
isActive: boolean;
1818
onClick: OnClick;
19+
setRef: (ref: HTMLButtonElement | null) => void;
1920
label?: string;
2021
}
2122

22-
export const PluginButton = withText(translates)(({isActive, onClick, ...otherProps}: PluginButtonProps) => {
23+
export const PluginButton = withText(translates)(({isActive, onClick, setRef, ...otherProps}: PluginButtonProps) => {
2324
return (
2425
<Tooltip label={otherProps.label} type="bottom">
2526
<A11yWrapper onClick={onClick}>
2627
<button
28+
ref={node => {
29+
setRef(node);
30+
}}
2731
aria-label={otherProps.label}
2832
className={[ui.style.upperBarIcon, styles.pluginButton, isActive ? styles.active : ''].join(' ')}
2933
data-testid={'navigation_pluginButton'}>

src/navigation-plugin.tsx

+15-7
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class NavigationPlugin extends KalturaPlayer.core.BasePlugin {
3131
private _activeCuePointsMap: HighlightedMap;
3232
private _captionMap: Map<string, Array<ItemData>> = new Map();
3333
private _activeCaptionMapId: string = '';
34-
private _navigationComponentRef: Navigation | null = null;
34+
private _pluginButtonRef: HTMLButtonElement | null = null;
3535

3636
private _player: KalturaPlayerTypes.Player;
3737
private _navigationPanel = -1;
@@ -259,6 +259,13 @@ export class NavigationPlugin extends KalturaPlayer.core.BasePlugin {
259259
}
260260
};
261261

262+
private _handleClose = (e: OnClickEvent, byKeyboard: boolean) => {
263+
if (byKeyboard) {
264+
this._pluginButtonRef?.focus();
265+
}
266+
this._deactivatePlugin();
267+
};
268+
262269
private _createNavigationPlugin = () => {
263270
if (Math.max(this._navigationPanel, this._navigationIcon) > 0) {
264271
this.logger.warn('navigation plugin already initialized');
@@ -270,10 +277,7 @@ export class NavigationPlugin extends KalturaPlayer.core.BasePlugin {
270277
panelComponent: () => {
271278
return (
272279
<Navigation
273-
ref={node => {
274-
this._navigationComponentRef = node;
275-
}}
276-
onClose={this._deactivatePlugin}
280+
onClose={this._handleClose}
277281
data={this._data}
278282
onItemClicked={this._seekTo}
279283
isLoading={this._isLoading}
@@ -296,7 +300,7 @@ export class NavigationPlugin extends KalturaPlayer.core.BasePlugin {
296300
svgIcon: {path: icons.PLUGIN_ICON, viewBox: `0 0 ${icons.BigSize} ${icons.BigSize}`},
297301
onClick: this._handleClickOnPluginIcon as () => void,
298302
component: () => {
299-
return <PluginButton isActive={this._isPluginActive()} onClick={this._handleClickOnPluginIcon} />;
303+
return <PluginButton isActive={this._isPluginActive()} onClick={this._handleClickOnPluginIcon} setRef={this._setPluginButtonRef} />;
300304
}
301305
}) as number;
302306

@@ -370,13 +374,17 @@ export class NavigationPlugin extends KalturaPlayer.core.BasePlugin {
370374
return this.sidePanelsManager!.isItemActive(this._navigationPanel);
371375
};
372376

377+
private _setPluginButtonRef = (ref: HTMLButtonElement) => {
378+
this._pluginButtonRef = ref;
379+
};
380+
373381
reset(): void {
374382
if (Math.max(this._navigationPanel, this._navigationIcon) > 0) {
375383
this.sidePanelsManager!.remove(this._navigationPanel);
376384
this.upperBarManager!.remove(this._navigationIcon);
377385
this._navigationPanel = -1;
378386
this._navigationIcon = -1;
379-
this._navigationComponentRef = null;
387+
this._pluginButtonRef = null;
380388
}
381389
this._activeCuePointsMap = this._getDefaultActiveCuePointsMap();
382390
this._activeCaptionMapId = '';

yarn.lock

+15-4
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,12 @@
130130
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
131131
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
132132

133-
"@playkit-js/common@^1.0.18":
134-
version "1.0.18"
135-
resolved "https://registry.yarnpkg.com/@playkit-js/common/-/common-1.0.18.tgz#16b93e58d7f9119f6da0192f6c9788cd6d94098d"
136-
integrity sha512-+7wRoZ4cx4icNiOUiHliailsLbPCD4H8ADjdWXDJLXMSDmooUU8yaDCjiahvla64a7ddIwkiNHsVbw2+XW8ujw==
133+
"@playkit-js/common@^1.1.0":
134+
version "1.1.0"
135+
resolved "https://registry.yarnpkg.com/@playkit-js/common/-/common-1.1.0.tgz#2baa34c16317e8355326537c8d0348e953f555de"
136+
integrity sha512-cMNZy9bmBFaICpUKyJrd8diYEcTdk2Lgm2PgkC8rnyZYnn3p5nIXgCjauVrcOxeRkxNErf8und6Gv3hNsPTi/g==
137137
dependencies:
138+
"@playkit-js/playkit-js-ui" "^0.74.0"
138139
linkify-it "^4.0.1"
139140

140141
"@playkit-js/[email protected]":
@@ -167,6 +168,16 @@
167168
react-redux "^7.2.0"
168169
redux "^4.0.5"
169170

171+
"@playkit-js/playkit-js-ui@^0.74.0":
172+
version "0.74.0"
173+
resolved "https://registry.yarnpkg.com/@playkit-js/playkit-js-ui/-/playkit-js-ui-0.74.0.tgz#22d0b0f8443cb77352f3ba877b3efc2188bde4ae"
174+
integrity sha512-my/6/HIGGRmP3vJC3vBs0jYwJA2bKyIQlAxH/ZAZccW+xW7iztVskxvkCoAdyFKn1rlddNaq9V962oYKxKtc3Q==
175+
dependencies:
176+
preact "^10.3.4"
177+
preact-i18n "^2.0.0-preactx.2"
178+
react-redux "^7.2.0"
179+
redux "^4.0.5"
180+
170181
"@playkit-js/playkit-js@^0.80.3":
171182
version "0.80.3"
172183
resolved "https://registry.yarnpkg.com/@playkit-js/playkit-js/-/playkit-js-0.80.3.tgz#07e47e560aeadc6ca3b20afde87dfdf4ab8f7ac0"

0 commit comments

Comments
 (0)