-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add keyboard support to the new SettingsPanel
design
#684
Changes from all commits
83aa0bc
93d0974
f31e28a
62fece2
7d6f45a
98776f7
7d96eb1
63281e3
110537e
dd95930
df575c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -129,6 +129,10 @@ export class Container<Config extends ContainerConfig> extends Component<Config> | |
'aria-label': i18n.performLocalization(this.config.ariaLabel), | ||
}, this); | ||
|
||
if (typeof this.config.tabIndex === 'number') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
containerElement.attr('tabindex', this.config.tabIndex.toString()); | ||
} | ||
|
||
// Create the inner container element (the inner <div>) that will contain the components | ||
let innerContainer = new DOM(this.config.tag, { | ||
'class': this.prefixCss('container-wrapper'), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,10 @@ export class Button<Config extends ButtonConfig> extends Component<Config> { | |
this.onClickEvent(); | ||
}); | ||
|
||
buttonElement.on('focusin focusout', (e) => { | ||
e.stopPropagation(); | ||
}); | ||
Comment on lines
+80
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is needed to stop bubbling of the |
||
|
||
return buttonElement; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { SettingsPanelItem, SettingsPanelItemConfig } from './SettingsPanelItem'; | ||
import { Event, EventDispatcher, NoArgs } from '../../EventDispatcher'; | ||
import { PlayerAPI } from 'bitmovin-player'; | ||
import { UIInstanceManager } from '../../UIManager'; | ||
import { getKeyMapForPlatform } from '../../spatialnavigation/getKeyMapForPlatform'; | ||
import { Action } from '../../spatialnavigation/types'; | ||
|
||
/** | ||
* A settings panel item that can be interacted with using the keyboard or mouse. | ||
* Can be used when no interactive element is present as child item. | ||
*/ | ||
export class InteractiveSettingsPanelItem<Config extends SettingsPanelItemConfig> extends SettingsPanelItem<Config> { | ||
private events = { | ||
onClick: new EventDispatcher<InteractiveSettingsPanelItem<Config>, NoArgs>(), | ||
}; | ||
|
||
constructor(config: Config) { | ||
super(config); | ||
} | ||
|
||
configure(player: PlayerAPI, uimanager: UIInstanceManager) { | ||
super.configure(player, uimanager); | ||
|
||
const handleClickEvent = (event: UIEvent) => { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
this.onClickEvent(); | ||
}; | ||
|
||
this.getDomElement().on('click touchend', handleClickEvent); | ||
|
||
// Listen to keyboard events and trigger the click event when a select key is detected | ||
const handleKeyDown = (event: KeyboardEvent) => { | ||
const action = getKeyMapForPlatform()[event.keyCode]; | ||
const acceptedKeys = ['Enter', ' ']; | ||
const acceptedCodes = ['Enter', 'Space']; | ||
|
||
if (action === Action.SELECT || acceptedKeys.includes(event.key) || acceptedCodes.includes(event.code)) { | ||
handleClickEvent(event); | ||
} | ||
}; | ||
|
||
this.onFocusedChanged.subscribe((_, args) => { | ||
if (args.focused) { | ||
// Only listen to keyboard events when the element is focused | ||
this.getDomElement().on('keydown', handleKeyDown); | ||
} else { | ||
// Unregister the keyboard event listener when the element loses focus | ||
this.getDomElement().off('keydown', handleKeyDown); | ||
} | ||
}); | ||
} | ||
|
||
protected onClickEvent() { | ||
this.events.onClick.dispatch(this); | ||
} | ||
|
||
/** | ||
* Gets the event that is fired when the SettingsPanelItem is clicked. | ||
* @returns {Event<InteractiveSettingsPanelItem<Config>, NoArgs>} | ||
*/ | ||
get onClick(): Event<InteractiveSettingsPanelItem<Config>, NoArgs> { | ||
return this.events.onClick.getEvent(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The box shadow has to be inset for settings panel items as otherwise it is not visible (they are at the edge of the settings panel and it has the overflow hidden)