mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(modal): clicking handle advances to the next breakpoint (#25540)
Resolves #24069
This commit is contained in:
@@ -63,6 +63,7 @@ export declare interface IonModal extends Components.IonModal {
|
||||
'enterAnimation',
|
||||
'event',
|
||||
'handle',
|
||||
'handleBehavior',
|
||||
'initialBreakpoint',
|
||||
'isOpen',
|
||||
'keyboardClose',
|
||||
@@ -93,6 +94,7 @@ export declare interface IonModal extends Components.IonModal {
|
||||
'enterAnimation',
|
||||
'event',
|
||||
'handle',
|
||||
'handleBehavior',
|
||||
'initialBreakpoint',
|
||||
'isOpen',
|
||||
'keyboardClose',
|
||||
|
||||
@@ -773,6 +773,7 @@ ion-modal,prop,breakpoints,number[] | undefined,undefined,false,false
|
||||
ion-modal,prop,canDismiss,(() => Promise<boolean>) | boolean | undefined,undefined,false,false
|
||||
ion-modal,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-modal,prop,handle,boolean | undefined,undefined,false,false
|
||||
ion-modal,prop,handleBehavior,"cycle" | "none" | undefined,'none',false,false
|
||||
ion-modal,prop,htmlAttributes,undefined | { [key: string]: any; },undefined,false,false
|
||||
ion-modal,prop,initialBreakpoint,number | undefined,undefined,false,false
|
||||
ion-modal,prop,isOpen,boolean,false,false,false
|
||||
|
||||
10
core/src/components.d.ts
vendored
10
core/src/components.d.ts
vendored
@@ -5,7 +5,7 @@
|
||||
* It contains typing information for all components that exist in this project.
|
||||
*/
|
||||
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
|
||||
import { AccordionGroupChangeEventDetail, ActionSheetAttributes, ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, BreadcrumbCollapsedClickEventDetail, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DomRenderFn, FooterHeightFn, FrameworkDelegate, HeaderFn, HeaderHeightFn, InputChangeEventDetail, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, LoadingAttributes, MenuChangeEventDetail, ModalAttributes, ModalBreakpointChangeEventDetail, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerAttributes, PickerButton, PickerColumn, PopoverAttributes, PopoverSize, PositionAlign, PositionReference, PositionSide, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, TriggerAction, ViewController } from "./interface";
|
||||
import { AccordionGroupChangeEventDetail, ActionSheetAttributes, ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, BreadcrumbCollapsedClickEventDetail, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DomRenderFn, FooterHeightFn, FrameworkDelegate, HeaderFn, HeaderHeightFn, InputChangeEventDetail, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, LoadingAttributes, MenuChangeEventDetail, ModalAttributes, ModalBreakpointChangeEventDetail, ModalHandleBehavior, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerAttributes, PickerButton, PickerColumn, PopoverAttributes, PopoverSize, PositionAlign, PositionReference, PositionSide, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, TriggerAction, ViewController } from "./interface";
|
||||
import { IonicSafeString } from "./utils/sanitization";
|
||||
import { AlertAttributes } from "./components/alert/alert-interface";
|
||||
import { CounterFormatter } from "./components/item/item-interface";
|
||||
@@ -1558,6 +1558,10 @@ export namespace Components {
|
||||
* The horizontal line that displays at the top of a sheet modal. It is `true` by default when setting the `breakpoints` and `initialBreakpoint` properties.
|
||||
*/
|
||||
"handle"?: boolean;
|
||||
/**
|
||||
* The interaction behavior for the sheet modal when the handle is pressed. Defaults to `"none"`, which means the modal will not change size or position when the handle is pressed. Set to `"cycle"` to let the modal cycle between available breakpoints when pressed. Handle behavior is unavailable when the `handle` property is set to `false` or when the `breakpoints` property is not set (using a fullscreen or card modal).
|
||||
*/
|
||||
"handleBehavior"?: ModalHandleBehavior;
|
||||
"hasController": boolean;
|
||||
/**
|
||||
* Additional attributes to pass to the modal.
|
||||
@@ -5483,6 +5487,10 @@ declare namespace LocalJSX {
|
||||
* The horizontal line that displays at the top of a sheet modal. It is `true` by default when setting the `breakpoints` and `initialBreakpoint` properties.
|
||||
*/
|
||||
"handle"?: boolean;
|
||||
/**
|
||||
* The interaction behavior for the sheet modal when the handle is pressed. Defaults to `"none"`, which means the modal will not change size or position when the handle is pressed. Set to `"cycle"` to let the modal cycle between available breakpoints when pressed. Handle behavior is unavailable when the `handle` property is set to `false` or when the `breakpoints` property is not set (using a fullscreen or card modal).
|
||||
*/
|
||||
"handleBehavior"?: ModalHandleBehavior;
|
||||
"hasController"?: boolean;
|
||||
/**
|
||||
* Additional attributes to pass to the modal.
|
||||
|
||||
@@ -294,66 +294,72 @@ export const createSheetGesture = (
|
||||
*/
|
||||
gesture.enable(false);
|
||||
|
||||
animation
|
||||
.onFinish(
|
||||
() => {
|
||||
if (shouldRemainOpen) {
|
||||
/**
|
||||
* Once the snapping animation completes,
|
||||
* we need to reset the animation to go
|
||||
* from 0 to 1 so users can swipe in any direction.
|
||||
* We then set the animation offset to the current
|
||||
* breakpoint so that it starts at the snapped position.
|
||||
*/
|
||||
if (wrapperAnimation && backdropAnimation) {
|
||||
raf(() => {
|
||||
wrapperAnimation.keyframes([...SheetDefaults.WRAPPER_KEYFRAMES]);
|
||||
backdropAnimation.keyframes([...SheetDefaults.BACKDROP_KEYFRAMES]);
|
||||
animation.progressStart(true, 1 - snapToBreakpoint);
|
||||
currentBreakpoint = snapToBreakpoint;
|
||||
onBreakpointChange(currentBreakpoint);
|
||||
|
||||
/**
|
||||
* If the sheet is fully expanded, we can safely
|
||||
* enable scrolling again.
|
||||
*/
|
||||
if (contentEl && currentBreakpoint === breakpoints[breakpoints.length - 1]) {
|
||||
contentEl.scrollY = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backdrop should become enabled
|
||||
* after the backdropBreakpoint value
|
||||
*/
|
||||
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint;
|
||||
if (shouldEnableBackdrop) {
|
||||
enableBackdrop();
|
||||
} else {
|
||||
disableBackdrop();
|
||||
}
|
||||
|
||||
gesture.enable(true);
|
||||
});
|
||||
} else {
|
||||
gesture.enable(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be a one time callback
|
||||
* otherwise a new callback will
|
||||
* be added every time onEnd runs.
|
||||
*/
|
||||
},
|
||||
{ oneTimeCallback: true }
|
||||
)
|
||||
.progressEnd(1, 0, 500);
|
||||
|
||||
if (shouldPreventDismiss) {
|
||||
handleCanDismiss(baseEl, animation);
|
||||
} else if (!shouldRemainOpen) {
|
||||
onDismiss();
|
||||
}
|
||||
|
||||
return new Promise<void>((resolve) => {
|
||||
animation
|
||||
.onFinish(
|
||||
() => {
|
||||
if (shouldRemainOpen) {
|
||||
/**
|
||||
* Once the snapping animation completes,
|
||||
* we need to reset the animation to go
|
||||
* from 0 to 1 so users can swipe in any direction.
|
||||
* We then set the animation offset to the current
|
||||
* breakpoint so that it starts at the snapped position.
|
||||
*/
|
||||
if (wrapperAnimation && backdropAnimation) {
|
||||
raf(() => {
|
||||
wrapperAnimation.keyframes([...SheetDefaults.WRAPPER_KEYFRAMES]);
|
||||
backdropAnimation.keyframes([...SheetDefaults.BACKDROP_KEYFRAMES]);
|
||||
animation.progressStart(true, 1 - snapToBreakpoint);
|
||||
currentBreakpoint = snapToBreakpoint;
|
||||
onBreakpointChange(currentBreakpoint);
|
||||
|
||||
/**
|
||||
* If the sheet is fully expanded, we can safely
|
||||
* enable scrolling again.
|
||||
*/
|
||||
if (contentEl && currentBreakpoint === breakpoints[breakpoints.length - 1]) {
|
||||
contentEl.scrollY = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backdrop should become enabled
|
||||
* after the backdropBreakpoint value
|
||||
*/
|
||||
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint;
|
||||
if (shouldEnableBackdrop) {
|
||||
enableBackdrop();
|
||||
} else {
|
||||
disableBackdrop();
|
||||
}
|
||||
|
||||
gesture.enable(true);
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
gesture.enable(true);
|
||||
resolve();
|
||||
}
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be a one time callback
|
||||
* otherwise a new callback will
|
||||
* be added every time onEnd runs.
|
||||
*/
|
||||
},
|
||||
{ oneTimeCallback: true }
|
||||
)
|
||||
.progressEnd(1, 0, 500);
|
||||
});
|
||||
};
|
||||
|
||||
const gesture = createGesture({
|
||||
|
||||
@@ -48,3 +48,8 @@ export interface ModalCustomEvent extends CustomEvent {
|
||||
* @deprecated - Use { [key: string]: any } directly instead.
|
||||
*/
|
||||
export type ModalAttributes = { [key: string]: any };
|
||||
|
||||
/**
|
||||
* The behavior setting for modals when the handle is pressed.
|
||||
*/
|
||||
export type ModalHandleBehavior = 'none' | 'cycle';
|
||||
|
||||
@@ -50,7 +50,8 @@
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.modal-wrapper, ion-backdrop {
|
||||
.modal-wrapper,
|
||||
ion-backdrop {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
@@ -124,9 +125,30 @@
|
||||
*/
|
||||
transform: translateZ(0);
|
||||
|
||||
border: 0;
|
||||
|
||||
background: var(--ion-color-step-350, #c0c0be);
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
z-index: 11;
|
||||
|
||||
&::before {
|
||||
/**
|
||||
* Adds a 4px tap area to the perimeter
|
||||
* of the handle.
|
||||
*/
|
||||
@include padding(4px, 4px, 4px, 4px);
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 36px;
|
||||
height: 5px;
|
||||
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
Gesture,
|
||||
ModalAttributes,
|
||||
ModalBreakpointChangeEventDetail,
|
||||
ModalHandleBehavior,
|
||||
OverlayEventDetail,
|
||||
OverlayInterface,
|
||||
} from '../../interface';
|
||||
@@ -56,6 +57,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
private modalId?: string;
|
||||
private coreDelegate: FrameworkDelegate = CoreDelegate();
|
||||
private currentTransition?: Promise<any>;
|
||||
private sheetTransition?: Promise<any>;
|
||||
private destroyTriggerInteraction?: () => void;
|
||||
private isSheetModal = false;
|
||||
private currentBreakpoint?: number;
|
||||
@@ -63,7 +65,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
private backdropEl?: HTMLIonBackdropElement;
|
||||
private sortedBreakpoints?: number[];
|
||||
private keyboardOpenCallback?: () => void;
|
||||
private moveSheetToBreakpoint?: (options: MoveSheetToBreakpointOptions) => void;
|
||||
private moveSheetToBreakpoint?: (options: MoveSheetToBreakpointOptions) => Promise<void>;
|
||||
|
||||
private inline = false;
|
||||
private workingDelegate?: FrameworkDelegate;
|
||||
@@ -140,6 +142,17 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
*/
|
||||
@Prop() handle?: boolean;
|
||||
|
||||
/**
|
||||
* The interaction behavior for the sheet modal when the handle is pressed.
|
||||
*
|
||||
* Defaults to `"none"`, which means the modal will not change size or position when the handle is pressed.
|
||||
* Set to `"cycle"` to let the modal cycle between available breakpoints when pressed.
|
||||
*
|
||||
* Handle behavior is unavailable when the `handle` property is set to `false` or
|
||||
* when the `breakpoints` property is not set (using a fullscreen or card modal).
|
||||
*/
|
||||
@Prop() handleBehavior?: ModalHandleBehavior = 'none';
|
||||
|
||||
/**
|
||||
* The component to display inside of the modal.
|
||||
* @internal
|
||||
@@ -758,11 +771,13 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
}
|
||||
|
||||
if (moveSheetToBreakpoint) {
|
||||
moveSheetToBreakpoint({
|
||||
this.sheetTransition = moveSheetToBreakpoint({
|
||||
breakpoint,
|
||||
breakpointOffset: 1 - currentBreakpoint!,
|
||||
canDismiss: canDismiss !== undefined && canDismiss !== true && breakpoints![0] === 0,
|
||||
});
|
||||
await this.sheetTransition;
|
||||
this.sheetTransition = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -774,7 +789,55 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
return this.currentBreakpoint;
|
||||
}
|
||||
|
||||
private async moveToNextBreakpoint() {
|
||||
const { breakpoints, currentBreakpoint } = this;
|
||||
|
||||
if (!breakpoints || currentBreakpoint == null) {
|
||||
/**
|
||||
* If the modal does not have breakpoints and/or the current
|
||||
* breakpoint is not set, we can't move to the next breakpoint.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
const allowedBreakpoints = breakpoints.filter((b) => b !== 0);
|
||||
const currentBreakpointIndex = allowedBreakpoints.indexOf(currentBreakpoint);
|
||||
const nextBreakpointIndex = (currentBreakpointIndex + 1) % allowedBreakpoints.length;
|
||||
const nextBreakpoint = allowedBreakpoints[nextBreakpointIndex];
|
||||
|
||||
/**
|
||||
* Sets the current breakpoint to the next available breakpoint.
|
||||
* If the current breakpoint is the last breakpoint, we set the current
|
||||
* breakpoint to the first non-zero breakpoint to avoid dismissing the sheet.
|
||||
*/
|
||||
await this.setCurrentBreakpoint(nextBreakpoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
private onHandleClick = () => {
|
||||
const { sheetTransition, handleBehavior } = this;
|
||||
if (handleBehavior !== 'cycle' || sheetTransition !== undefined) {
|
||||
/**
|
||||
* The sheet modal should not advance to the next breakpoint
|
||||
* if the handle behavior is not `cycle` or if the handle
|
||||
* is clicked while the sheet is moving to a breakpoint.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
this.moveToNextBreakpoint();
|
||||
};
|
||||
|
||||
private onBackdropTap = () => {
|
||||
const { sheetTransition } = this;
|
||||
if (sheetTransition !== undefined) {
|
||||
/**
|
||||
* When the handle is double clicked at the largest breakpoint,
|
||||
* it will start to move to the first breakpoint. While transitioning,
|
||||
* the backdrop will often receive the second click. We prevent the
|
||||
* backdrop from dismissing the modal while moving between breakpoints.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
this.dismiss(undefined, BACKDROP);
|
||||
};
|
||||
|
||||
@@ -792,12 +855,13 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { handle, isSheetModal, presentingElement, htmlAttributes } = this;
|
||||
const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior } = this;
|
||||
|
||||
const showHandle = handle !== false && isSheetModal;
|
||||
const mode = getIonMode(this);
|
||||
const { modalId } = this;
|
||||
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
||||
const isHandleCycle = handleBehavior === 'cycle';
|
||||
|
||||
return (
|
||||
<Host
|
||||
@@ -833,7 +897,16 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
{mode === 'ios' && <div class="modal-shadow"></div>}
|
||||
|
||||
<div role="dialog" class="modal-wrapper ion-overlay-wrapper" part="content" ref={(el) => (this.wrapperEl = el)}>
|
||||
{showHandle && <div class="modal-handle" part="handle"></div>}
|
||||
{showHandle && (
|
||||
<button
|
||||
class="modal-handle"
|
||||
// Prevents the handle from receiving keyboard focus when it does not cycle
|
||||
tabIndex={!isHandleCycle ? -1 : 0}
|
||||
aria-label="Activate to adjust the size of the dialog overlaying the screen"
|
||||
onClick={isHandleCycle ? this.onHandleClick : undefined}
|
||||
part="handle"
|
||||
></button>
|
||||
)}
|
||||
<slot></slot>
|
||||
</div>
|
||||
</Host>
|
||||
|
||||
@@ -115,6 +115,14 @@
|
||||
<ion-button id="custom-height-modal" onclick="presentModal({ cssClass: 'custom-height' })"
|
||||
>Present Sheet Modal (Custom Height)</ion-button
|
||||
>
|
||||
|
||||
<ion-button
|
||||
id="handle-behavior-cycle-modal"
|
||||
onclick="presentModal({ handleBehavior: 'cycle', initialBreakpoint: 0.25, breakpoints: [0, 0.25, 0.5, 0.75, 1] })"
|
||||
>
|
||||
Present Sheet Modal (HandleBehavior: Cycle)</ion-button
|
||||
>
|
||||
|
||||
<ion-button id="custom-handle-modal" onclick="presentModal({ cssClass: 'custom-handle' })"
|
||||
>Present Sheet Modal (Custom Handle)</ion-button
|
||||
>
|
||||
|
||||
@@ -195,3 +195,78 @@ test.describe('sheet modal: setting the breakpoint', () => {
|
||||
expect(updatedBreakpoint).toBe(0.5);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('sheet modal: clicking the handle', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/sheet');
|
||||
});
|
||||
|
||||
test('should advance to the next breakpoint when handleBehavior is cycle', async ({ page }) => {
|
||||
const ionBreakpointDidChange = await page.spyOnEvent('ionBreakpointDidChange');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const modal = page.locator('ion-modal');
|
||||
|
||||
await page.click('#handle-behavior-cycle-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const handle = page.locator('ion-modal .modal-handle');
|
||||
|
||||
await handle.click();
|
||||
await ionBreakpointDidChange.next();
|
||||
|
||||
await expect(await modal.evaluate((el: HTMLIonModalElement) => el.getCurrentBreakpoint())).toBe(0.5);
|
||||
|
||||
await handle.click();
|
||||
await ionBreakpointDidChange.next();
|
||||
|
||||
await expect(await modal.evaluate((el: HTMLIonModalElement) => el.getCurrentBreakpoint())).toBe(0.75);
|
||||
|
||||
await handle.click();
|
||||
await ionBreakpointDidChange.next();
|
||||
|
||||
await expect(await modal.evaluate((el: HTMLIonModalElement) => el.getCurrentBreakpoint())).toBe(1);
|
||||
|
||||
await handle.click();
|
||||
await ionBreakpointDidChange.next();
|
||||
|
||||
// Advancing from the last breakpoint should change the breakpoint to the first non-zero breakpoint
|
||||
await expect(await modal.evaluate((el: HTMLIonModalElement) => el.getCurrentBreakpoint())).toBe(0.25);
|
||||
});
|
||||
|
||||
test('should not advance the breakpoint when handleBehavior is none', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const modal = page.locator('ion-modal');
|
||||
|
||||
await page.click('#sheet-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const handle = page.locator('ion-modal .modal-handle');
|
||||
|
||||
await handle.click();
|
||||
|
||||
await expect(await modal.evaluate((el: HTMLIonModalElement) => el.getCurrentBreakpoint())).toBe(0.25);
|
||||
});
|
||||
|
||||
test('should not dismiss the modal when backdrop is clicked and breakpoint is moving', async ({ page }) => {
|
||||
const ionBreakpointDidChange = await page.spyOnEvent('ionBreakpointDidChange');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const modal = page.locator('ion-modal');
|
||||
|
||||
await page.click('#handle-behavior-cycle-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const handle = page.locator('ion-modal .modal-handle');
|
||||
const backdrop = page.locator('ion-modal ion-backdrop');
|
||||
|
||||
await handle.click();
|
||||
backdrop.click();
|
||||
|
||||
await ionBreakpointDidChange.next();
|
||||
|
||||
await handle.click();
|
||||
|
||||
await ionBreakpointDidChange.next();
|
||||
|
||||
await expect(await modal.evaluate((el: HTMLIonModalElement) => el.getCurrentBreakpoint())).toBe(0.75);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ export const IonPicker = /*@__PURE__*/ defineOverlayContainer<JSX.IonPicker>('io
|
||||
|
||||
export const IonToast = /*@__PURE__*/ defineOverlayContainer<JSX.IonToast>('ion-toast', defineIonToastCustomElement, ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'position', 'translucent'], toastController);
|
||||
|
||||
export const IonModal = /*@__PURE__*/ defineOverlayContainer<JSX.IonModal>('ion-modal', defineIonModalCustomElement, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'handle', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'swipeToClose', 'trigger']);
|
||||
export const IonModal = /*@__PURE__*/ defineOverlayContainer<JSX.IonModal>('ion-modal', defineIonModalCustomElement, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'handle', 'handleBehavior', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'swipeToClose', 'trigger']);
|
||||
|
||||
export const IonPopover = /*@__PURE__*/ defineOverlayContainer<JSX.IonPopover>('ion-popover', defineIonPopoverCustomElement, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'htmlAttributes', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'translucent', 'trigger', 'triggerAction']);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user