chore(overlays): generic for present/dismiss options (#26287)

This commit is contained in:
Sean Perkins
2022-11-21 16:57:17 -05:00
committed by GitHub
parent 8aa0aeca6b
commit c943dff5a3
7 changed files with 97 additions and 20 deletions

View File

@ -14,7 +14,7 @@ import { PickerInternalChangeEventDetail } from "./components/picker-internal/pi
import { PinFormatter } from "./components/range/range-interface";
import { NavigationHookCallback } from "./components/route/route-interface";
import { SelectCompareFn } from "./components/select/select-interface";
import { ToastAttributes } from "./components/toast/toast-interface";
import { ToastAttributes, ToastPosition } from "./components/toast/toast-interface";
export namespace Components {
interface IonAccordion {
/**
@ -2998,7 +2998,7 @@ export namespace Components {
/**
* The position of the toast on the screen.
*/
"position": 'top' | 'bottom' | 'middle';
"position": ToastPosition;
/**
* Present the toast overlay after it has been created.
*/
@ -7007,7 +7007,7 @@ declare namespace LocalJSX {
/**
* The position of the toast on the screen.
*/
"position"?: 'top' | 'bottom' | 'middle';
"position"?: ToastPosition;
/**
* If `true`, the toast will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility).
*/

View File

@ -141,7 +141,7 @@ export class Loading implements ComponentInterface, OverlayInterface {
*/
@Method()
async present(): Promise<void> {
await present(this, 'loadingEnter', iosEnterAnimation, mdEnterAnimation, undefined);
await present(this, 'loadingEnter', iosEnterAnimation, mdEnterAnimation);
if (this.duration > 0) {
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration + 10);

View File

@ -506,7 +506,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
writeTask(() => this.el.classList.add('show-modal'));
this.currentTransition = present(this, 'modalEnter', iosEnterAnimation, mdEnterAnimation, {
this.currentTransition = present<ModalPresentOptions>(this, 'modalEnter', iosEnterAnimation, mdEnterAnimation, {
presentingEl: this.presentingElement,
currentBreakpoint: this.initialBreakpoint,
backdropBreakpoint: this.backdropBreakpoint,
@ -721,11 +721,19 @@ export class Modal implements ComponentInterface, OverlayInterface {
const enteringAnimation = activeAnimations.get(this) || [];
this.currentTransition = dismiss(this, data, role, 'modalLeave', iosLeaveAnimation, mdLeaveAnimation, {
this.currentTransition = dismiss<ModalDismissOptions>(
this,
data,
role,
'modalLeave',
iosLeaveAnimation,
mdLeaveAnimation,
{
presentingEl: this.presentingElement,
currentBreakpoint: this.currentBreakpoint ?? this.initialBreakpoint,
backdropBreakpoint: this.backdropBreakpoint,
});
}
);
const dismissed = await this.currentTransition;
@ -953,3 +961,22 @@ const LIFECYCLE_MAP: any = {
};
let modalIds = 0;
interface ModalOverlayOptions {
/**
* The element that presented the modal.
*/
presentingEl?: HTMLElement;
/**
* The current breakpoint of the sheet modal.
*/
currentBreakpoint?: number;
/**
* The point after which the backdrop will being
* to fade in when using a sheet modal.
*/
backdropBreakpoint: number;
}
type ModalPresentOptions = ModalOverlayOptions;
type ModalDismissOptions = ModalOverlayOptions;

View File

@ -476,7 +476,7 @@ export class Popover implements ComponentInterface, PopoverInterface {
*/
await waitOneFrame();
this.currentTransition = present(this, 'popoverEnter', iosEnterAnimation, mdEnterAnimation, {
this.currentTransition = present<PopoverPresentOptions>(this, 'popoverEnter', iosEnterAnimation, mdEnterAnimation, {
event: event || this.event,
size: this.size,
trigger: this.triggerEl,
@ -527,7 +527,15 @@ export class Popover implements ComponentInterface, PopoverInterface {
this.parentPopover.dismiss(data, role, dismissParentPopover);
}
this.currentTransition = dismiss(this, data, role, 'popoverLeave', iosLeaveAnimation, mdLeaveAnimation, this.event);
this.currentTransition = dismiss<PopoverDismissOptions>(
this,
data,
role,
'popoverLeave',
iosLeaveAnimation,
mdLeaveAnimation,
this.event
);
const shouldDismiss = await this.currentTransition;
if (shouldDismiss) {
if (destroyKeyboardInteraction) {
@ -685,3 +693,32 @@ const LIFECYCLE_MAP: any = {
};
let popoverIds = 0;
interface PopoverPresentOptions {
/**
* The original target event that presented the popover.
*/
event: Event;
/**
* Describes how to calculate the popover width.
*/
size: PopoverSize;
/**
* The element that causes the popover to open.
*/
trigger?: HTMLElement | null;
/**
* Describes what to position the popover relative to.
*/
reference: PositionReference;
/**
* Side of the `reference` point to position the popover on.
*/
side: PositionSide;
/**
* Describes how to align the popover content with the `reference` point.
*/
align?: PositionAlign;
}
type PopoverDismissOptions = Event;

View File

@ -35,3 +35,5 @@ export interface ToastButton {
cssClass?: string | string[];
handler?: () => boolean | void | Promise<boolean | void>;
}
export type ToastPosition = 'top' | 'bottom' | 'middle';

View File

@ -19,7 +19,7 @@ import { iosEnterAnimation } from './animations/ios.enter';
import { iosLeaveAnimation } from './animations/ios.leave';
import { mdEnterAnimation } from './animations/md.enter';
import { mdLeaveAnimation } from './animations/md.leave';
import type { ToastAttributes } from './toast-interface';
import type { ToastAttributes, ToastPosition } from './toast-interface';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
@ -97,7 +97,7 @@ export class Toast implements ComponentInterface, OverlayInterface {
/**
* The position of the toast on the screen.
*/
@Prop() position: 'top' | 'bottom' | 'middle' = 'bottom';
@Prop() position: ToastPosition = 'bottom';
/**
* An array of buttons for the toast.
@ -156,7 +156,7 @@ export class Toast implements ComponentInterface, OverlayInterface {
*/
@Method()
async present(): Promise<void> {
await present(this, 'toastEnter', iosEnterAnimation, mdEnterAnimation, this.position);
await present<ToastPresentOptions>(this, 'toastEnter', iosEnterAnimation, mdEnterAnimation, this.position);
if (this.duration > 0) {
this.durationTimeout = setTimeout(() => this.dismiss(undefined, 'timeout'), this.duration);
@ -177,7 +177,15 @@ export class Toast implements ComponentInterface, OverlayInterface {
if (this.durationTimeout) {
clearTimeout(this.durationTimeout);
}
return dismiss(this, data, role, 'toastLeave', iosLeaveAnimation, mdLeaveAnimation, this.position);
return dismiss<ToastDismissOptions>(
this,
data,
role,
'toastLeave',
iosLeaveAnimation,
mdLeaveAnimation,
this.position
);
}
/**
@ -344,3 +352,6 @@ const buttonClass = (button: ToastButton): CssClassMap => {
...getClassMap(button.cssClass),
};
};
type ToastPresentOptions = ToastPosition;
type ToastDismissOptions = ToastPosition;

View File

@ -400,12 +400,12 @@ export const setRootAriaHidden = (hidden = false) => {
}
};
export const present = async (
export const present = async <OverlayPresentOptions>(
overlay: OverlayInterface,
name: keyof IonicConfig,
iosEnterAnimation: AnimationBuilder,
mdEnterAnimation: AnimationBuilder,
opts?: any
opts?: OverlayPresentOptions
) => {
if (overlay.presented) {
return;
@ -478,14 +478,14 @@ const focusPreviousElementOnDismiss = async (overlayEl: any) => {
previousElement.focus();
};
export const dismiss = async (
export const dismiss = async <OverlayDismissOptions>(
overlay: OverlayInterface,
data: any | undefined,
role: string | undefined,
name: keyof IonicConfig,
iosLeaveAnimation: AnimationBuilder,
mdLeaveAnimation: AnimationBuilder,
opts?: any
opts?: OverlayDismissOptions
): Promise<boolean> => {
if (!overlay.presented) {
return false;