mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-07 23:16:52 +08:00
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:
@ -1,8 +1,9 @@
|
|||||||
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||||
import { Component, Element, Event, Listen, Method, Prop } 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 { debounce } from '@utils/helpers';
|
||||||
|
|
||||||
import type { AnimationBuilder, BackButtonEvent } from '../../interface';
|
import type { AnimationBuilder } from '../../interface';
|
||||||
import type { NavigationHookResult } from '../route/route-interface';
|
import type { NavigationHookResult } from '../route/route-interface';
|
||||||
|
|
||||||
import { ROUTER_INTENT_BACK, ROUTER_INTENT_FORWARD, ROUTER_INTENT_NONE } from './utils/constants';
|
import { ROUTER_INTENT_BACK, ROUTER_INTENT_FORWARD, ROUTER_INTENT_NONE } from './utils/constants';
|
||||||
|
|||||||
6
core/src/interface.d.ts
vendored
6
core/src/interface.d.ts
vendored
@ -32,6 +32,7 @@ export { TabsCustomEvent } from './components/tabs/tabs-interface';
|
|||||||
export { TextareaCustomEvent } from './components/textarea/textarea-interface';
|
export { TextareaCustomEvent } from './components/textarea/textarea-interface';
|
||||||
export { ToastOptions } from './components/toast/toast-interface';
|
export { ToastOptions } from './components/toast/toast-interface';
|
||||||
export { ToggleCustomEvent } from './components/toggle/toggle-interface';
|
export { ToggleCustomEvent } from './components/toggle/toggle-interface';
|
||||||
|
export { BackButtonEvent, BackButtonEventDetail } from './utils/hardware-back-button';
|
||||||
|
|
||||||
// Types from utils
|
// Types from utils
|
||||||
export {
|
export {
|
||||||
@ -140,17 +141,12 @@ export type ComponentRef = Function | HTMLElement | string | null;
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
export type ComponentProps<T = null> = { [key: string]: any };
|
export type ComponentProps<T = null> = { [key: string]: any };
|
||||||
export type CssClassMap = { [className: string]: boolean };
|
export type CssClassMap = { [className: string]: boolean };
|
||||||
export type BackButtonEvent = CustomEvent<BackButtonEventDetail>;
|
|
||||||
|
|
||||||
export interface FrameworkDelegate {
|
export interface FrameworkDelegate {
|
||||||
attachViewToDom(container: any, component: any, propsOrDataObj?: any, cssClasses?: string[]): Promise<HTMLElement>;
|
attachViewToDom(container: any, component: any, propsOrDataObj?: any, cssClasses?: string[]): Promise<HTMLElement>;
|
||||||
removeViewFromDom(container: any, component: any): Promise<void>;
|
removeViewFromDom(container: any, component: any): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BackButtonEventDetail {
|
|
||||||
register(priority: number, handler: (processNextHandler: () => void) => Promise<any> | void): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface KeyboardEventDetail {
|
export interface KeyboardEventDetail {
|
||||||
keyboardHeight: number;
|
keyboardHeight: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import type { BackButtonEvent } from '@utils/hardware-back-button';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When accessing the document or window, it is important
|
* When accessing the document or window, it is important
|
||||||
* to account for SSR applications where the
|
* to account for SSR applications where the
|
||||||
@ -58,6 +60,16 @@ type IonicEvents = {
|
|||||||
listener: (ev: CustomEvent<HTMLIonInputElement | HTMLIonTextareaElement>) => void,
|
listener: (ev: CustomEvent<HTMLIonInputElement | HTMLIonTextareaElement>) => void,
|
||||||
options?: boolean | AddEventListenerOptions
|
options?: boolean | AddEventListenerOptions
|
||||||
): void;
|
): 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;
|
type IonicWindow = Window & IonicEvents;
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
import type { BackButtonEvent } from '../interface';
|
|
||||||
|
|
||||||
// TODO(FW-2832): type
|
// TODO(FW-2832): type
|
||||||
type Handler = (processNextHandler: () => void) => Promise<any> | void | null;
|
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 {
|
interface HandlerRegister {
|
||||||
priority: number;
|
priority: number;
|
||||||
handler: Handler;
|
handler: Handler;
|
||||||
|
|||||||
@ -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 { printIonWarning } from '@utils/logging';
|
||||||
|
|
||||||
import type { MenuI, MenuControllerI } from '../../components/menu/menu-interface';
|
import type { MenuI, MenuControllerI } from '../../components/menu/menu-interface';
|
||||||
import type { AnimationBuilder, BackButtonEvent } from '../../interface';
|
import type { AnimationBuilder } from '../../interface';
|
||||||
import { MENU_BACK_BUTTON_PRIORITY } from '../hardware-back-button';
|
|
||||||
import { componentOnReady } from '../helpers';
|
import { componentOnReady } from '../helpers';
|
||||||
|
|
||||||
import { menuOverlayAnimation } from './animations/overlay';
|
import { menuOverlayAnimation } from './animations/overlay';
|
||||||
@ -227,17 +229,14 @@ const createMenuController = (): MenuControllerI => {
|
|||||||
registerAnimation('push', menuPushAnimation);
|
registerAnimation('push', menuPushAnimation);
|
||||||
registerAnimation('overlay', menuOverlayAnimation);
|
registerAnimation('overlay', menuOverlayAnimation);
|
||||||
|
|
||||||
if (typeof document !== 'undefined') {
|
doc?.addEventListener('ionBackButton', (ev: BackButtonEvent) => {
|
||||||
document.addEventListener('ionBackButton', (ev: any) => {
|
|
||||||
// TODO(FW-2832): type
|
|
||||||
const openMenu = _getOpenSync();
|
const openMenu = _getOpenSync();
|
||||||
if (openMenu) {
|
if (openMenu) {
|
||||||
(ev as BackButtonEvent).detail.register(MENU_BACK_BUTTON_PRIORITY, () => {
|
ev.detail.register(MENU_BACK_BUTTON_PRIORITY, () => {
|
||||||
return openMenu.close();
|
return openMenu.close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
registerAnimation,
|
registerAnimation,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { doc } from '@utils/browser';
|
import { doc } from '@utils/browser';
|
||||||
|
import type { BackButtonEvent } from '@utils/hardware-back-button';
|
||||||
|
|
||||||
import { config } from '../global/config';
|
import { config } from '../global/config';
|
||||||
import { getIonMode } from '../global/ionic-global';
|
import { getIonMode } from '../global/ionic-global';
|
||||||
@ -7,7 +8,6 @@ import type {
|
|||||||
AlertOptions,
|
AlertOptions,
|
||||||
Animation,
|
Animation,
|
||||||
AnimationBuilder,
|
AnimationBuilder,
|
||||||
BackButtonEvent,
|
|
||||||
FrameworkDelegate,
|
FrameworkDelegate,
|
||||||
HTMLIonOverlayElement,
|
HTMLIonOverlayElement,
|
||||||
IonicConfig,
|
IonicConfig,
|
||||||
|
|||||||
Reference in New Issue
Block a user