feat: add experimental hardware back button support in browsers (#28705)

resolves #28703
This commit is contained in:
Liam DeBeasi
2024-01-05 09:10:53 -05:00
committed by GitHub
parent e886e3ff2f
commit 658d1caccd
7 changed files with 190 additions and 15 deletions

View File

@ -1,6 +1,8 @@
import type { ComponentInterface } from '@stencil/core';
import { Build, Component, Element, Host, Method, h } from '@stencil/core';
import type { FocusVisibleUtility } from '@utils/focus-visible';
import { shoudUseCloseWatcher } from '@utils/hardware-back-button';
import { printIonWarning } from '@utils/logging';
import { isPlatform } from '@utils/platform';
import { config } from '../../global/config';
@ -34,9 +36,20 @@ export class App implements ComponentInterface {
import('../../utils/input-shims/input-shims').then((module) => module.startInputShims(config, platform));
}
const hardwareBackButtonModule = await import('../../utils/hardware-back-button');
if (config.getBoolean('hardwareBackButton', isHybrid)) {
const supportsHardwareBackButtonEvents = isHybrid || shoudUseCloseWatcher();
if (config.getBoolean('hardwareBackButton', supportsHardwareBackButtonEvents)) {
hardwareBackButtonModule.startHardwareBackButton();
} else {
/**
* If an app sets hardwareBackButton: false and experimentalCloseWatcher: true
* then the close watcher will not be used.
*/
if (shoudUseCloseWatcher()) {
printIonWarning(
'experimentalCloseWatcher was set to `true`, but hardwareBackButton was set to `false`. Both config options must be `true` for the Close Watcher API to be used.'
);
}
hardwareBackButtonModule.blockHardwareBackButton();
}
if (typeof (window as any) !== 'undefined') {

View File

@ -2,6 +2,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Build, Component, Element, Event, Host, Listen, Method, Prop, State, Watch, h } from '@stencil/core';
import { getTimeGivenProgression } from '@utils/animation/cubic-bezier';
import { GESTURE_CONTROLLER } from '@utils/gesture';
import { shoudUseCloseWatcher } from '@utils/hardware-back-button';
import type { Attributes } from '@utils/helpers';
import { inheritAriaAttributes, assert, clamp, isEndSide as isEnd } from '@utils/helpers';
import { menuController } from '@utils/menu-controller';
@ -321,7 +322,6 @@ export class Menu implements ComponentInterface, MenuI {
}
}
@Listen('keydown')
onKeydown(ev: KeyboardEvent) {
if (ev.key === 'Escape') {
this.close();
@ -781,8 +781,14 @@ export class Menu implements ComponentInterface, MenuI {
const { type, disabled, isPaneVisible, inheritedAttributes, side } = this;
const mode = getIonMode(this);
/**
* If the Close Watcher is enabled then
* the ionBackButton listener in the menu controller
* will handle closing the menu when Escape is pressed.
*/
return (
<Host
onKeyDown={shoudUseCloseWatcher() ? null : this.onKeydown}
role="navigation"
aria-label={inheritedAttributes['aria-label'] || 'menu'}
class={{