refactor: improve hardware back button types (#28335)

Issue number: Internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

As part of FW-2832, the team would like to swap out usages of the `any`
type for stronger types.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Added `ionBackButton` event types to the browser utilities
- Updated menuController to use the `doc` utility instead of `document`
so we can get proper types
- Moved the definitions for back button types out of `interface.d.ts`
and into `hardware-back-button`. `interface.d.ts` still exports these
back button interfaces.
- Updated all `BackButtonEvent` imports inside of `@ionic/core` to
import from the utility file instead of the public interface file.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

Note: This PR was separated from other type updates associated with the
FW-3832 work because I had to modify the implementation of a feature in
Ionic. While I don't expect there to be any functional differences, I
have opted to pull this work out into a separate branch and target a
feature branch to a) reduce the impact of any unintended bugs and b)
make it easier to do a `git bisect` if a bug is introduced.
This commit is contained in:
Liam DeBeasi
2023-10-25 10:44:58 -04:00
committed by GitHub
parent 6e79e1d179
commit 60630ccb42
6 changed files with 34 additions and 22 deletions

View File

@ -1,8 +1,9 @@
import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Component, Element, Event, Listen, Method, Prop } from '@stencil/core';
import type { BackButtonEvent } from '@utils/hardware-back-button';
import { debounce } from '@utils/helpers';
import type { AnimationBuilder, BackButtonEvent } from '../../interface';
import type { AnimationBuilder } from '../../interface';
import type { NavigationHookResult } from '../route/route-interface';
import { ROUTER_INTENT_BACK, ROUTER_INTENT_FORWARD, ROUTER_INTENT_NONE } from './utils/constants';

View File

@ -32,6 +32,7 @@ export { TabsCustomEvent } from './components/tabs/tabs-interface';
export { TextareaCustomEvent } from './components/textarea/textarea-interface';
export { ToastOptions } from './components/toast/toast-interface';
export { ToggleCustomEvent } from './components/toggle/toggle-interface';
export { BackButtonEvent, BackButtonEventDetail } from './utils/hardware-back-button';
// Types from utils
export {
@ -140,17 +141,12 @@ export type ComponentRef = Function | HTMLElement | string | null;
// eslint-disable-next-line
export type ComponentProps<T = null> = { [key: string]: any };
export type CssClassMap = { [className: string]: boolean };
export type BackButtonEvent = CustomEvent<BackButtonEventDetail>;
export interface FrameworkDelegate {
attachViewToDom(container: any, component: any, propsOrDataObj?: any, cssClasses?: string[]): Promise<HTMLElement>;
removeViewFromDom(container: any, component: any): Promise<void>;
}
export interface BackButtonEventDetail {
register(priority: number, handler: (processNextHandler: () => void) => Promise<any> | void): void;
}
export interface KeyboardEventDetail {
keyboardHeight: number;
}

View File

@ -1,3 +1,5 @@
import type { BackButtonEvent } from '@utils/hardware-back-button';
/**
* When accessing the document or window, it is important
* to account for SSR applications where the
@ -58,6 +60,16 @@ type IonicEvents = {
listener: (ev: CustomEvent<HTMLIonInputElement | HTMLIonTextareaElement>) => void,
options?: boolean | AddEventListenerOptions
): void;
addEventListener(
type: 'ionBackButton',
listener: (ev: BackButtonEvent) => void,
options?: boolean | AddEventListenerOptions
): void;
removeEventListener(
type: 'ionBackButton',
listener: (ev: BackButtonEvent) => void,
options?: boolean | AddEventListenerOptions
): void;
};
type IonicWindow = Window & IonicEvents;

View File

@ -1,8 +1,12 @@
import type { BackButtonEvent } from '../interface';
// TODO(FW-2832): type
type Handler = (processNextHandler: () => void) => Promise<any> | void | null;
export interface BackButtonEventDetail {
register(priority: number, handler: (processNextHandler: () => void) => Promise<any> | void): void;
}
export type BackButtonEvent = CustomEvent<BackButtonEventDetail>;
interface HandlerRegister {
priority: number;
handler: Handler;

View File

@ -1,8 +1,10 @@
import { doc } from '@utils/browser';
import type { BackButtonEvent } from '@utils/hardware-back-button';
import { MENU_BACK_BUTTON_PRIORITY } from '@utils/hardware-back-button';
import { printIonWarning } from '@utils/logging';
import type { MenuI, MenuControllerI } from '../../components/menu/menu-interface';
import type { AnimationBuilder, BackButtonEvent } from '../../interface';
import { MENU_BACK_BUTTON_PRIORITY } from '../hardware-back-button';
import type { AnimationBuilder } from '../../interface';
import { componentOnReady } from '../helpers';
import { menuOverlayAnimation } from './animations/overlay';
@ -227,17 +229,14 @@ const createMenuController = (): MenuControllerI => {
registerAnimation('push', menuPushAnimation);
registerAnimation('overlay', menuOverlayAnimation);
if (typeof document !== 'undefined') {
document.addEventListener('ionBackButton', (ev: any) => {
// TODO(FW-2832): type
const openMenu = _getOpenSync();
if (openMenu) {
(ev as BackButtonEvent).detail.register(MENU_BACK_BUTTON_PRIORITY, () => {
return openMenu.close();
});
}
});
}
doc?.addEventListener('ionBackButton', (ev: BackButtonEvent) => {
const openMenu = _getOpenSync();
if (openMenu) {
ev.detail.register(MENU_BACK_BUTTON_PRIORITY, () => {
return openMenu.close();
});
}
});
return {
registerAnimation,

View File

@ -1,4 +1,5 @@
import { doc } from '@utils/browser';
import type { BackButtonEvent } from '@utils/hardware-back-button';
import { config } from '../global/config';
import { getIonMode } from '../global/ionic-global';
@ -7,7 +8,6 @@ import type {
AlertOptions,
Animation,
AnimationBuilder,
BackButtonEvent,
FrameworkDelegate,
HTMLIonOverlayElement,
IonicConfig,