feat(modal): add shape prop & styling for ionic theme (#29853)
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. --> No shape prop or ionic theme styling ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - Adds `shape` prop to `ion-modal` - Adds styling for shape in ionic theme ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change: 1. Describe the impact and migration path for existing applications below. 2. Update the BREAKING.md file with the breaking change. 3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer for more information. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. -->
@ -1395,6 +1395,7 @@ ion-modal,prop,keyboardClose,boolean,true,false,false
|
|||||||
ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||||
ion-modal,prop,mode,"ios" | "md",undefined,false,false
|
ion-modal,prop,mode,"ios" | "md",undefined,false,false
|
||||||
ion-modal,prop,presentingElement,HTMLElement | undefined,undefined,false,false
|
ion-modal,prop,presentingElement,HTMLElement | undefined,undefined,false,false
|
||||||
|
ion-modal,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
|
||||||
ion-modal,prop,showBackdrop,boolean,true,false,false
|
ion-modal,prop,showBackdrop,boolean,true,false,false
|
||||||
ion-modal,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
ion-modal,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||||
ion-modal,prop,trigger,string | undefined,undefined,false,false
|
ion-modal,prop,trigger,string | undefined,undefined,false,false
|
||||||
|
8
core/src/components.d.ts
vendored
@ -2097,6 +2097,10 @@ export namespace Components {
|
|||||||
* Move a sheet style modal to a specific breakpoint. The breakpoint value must be a value defined in your `breakpoints` array.
|
* Move a sheet style modal to a specific breakpoint. The breakpoint value must be a value defined in your `breakpoints` array.
|
||||||
*/
|
*/
|
||||||
"setCurrentBreakpoint": (breakpoint: number) => Promise<void>;
|
"setCurrentBreakpoint": (breakpoint: number) => Promise<void>;
|
||||||
|
/**
|
||||||
|
* Set to `"soft"` for a modal with slightly rounded corners, `"round"` for a modal with fully rounded corners, or `"rectangular"` for a modal without rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
||||||
|
*/
|
||||||
|
"shape"?: 'soft' | 'round' | 'rectangular';
|
||||||
/**
|
/**
|
||||||
* If `true`, a backdrop will be displayed behind the modal. This property controls whether or not the backdrop darkens the screen when the modal is presented. It does not control whether or not the backdrop is active or present in the DOM.
|
* If `true`, a backdrop will be displayed behind the modal. This property controls whether or not the backdrop darkens the screen when the modal is presented. It does not control whether or not the backdrop is active or present in the DOM.
|
||||||
*/
|
*/
|
||||||
@ -7431,6 +7435,10 @@ declare namespace LocalJSX {
|
|||||||
* The element that presented the modal. This is used for card presentation effects and for stacking multiple modals on top of each other. Only applies in iOS mode.
|
* The element that presented the modal. This is used for card presentation effects and for stacking multiple modals on top of each other. Only applies in iOS mode.
|
||||||
*/
|
*/
|
||||||
"presentingElement"?: HTMLElement;
|
"presentingElement"?: HTMLElement;
|
||||||
|
/**
|
||||||
|
* Set to `"soft"` for a modal with slightly rounded corners, `"round"` for a modal with fully rounded corners, or `"rectangular"` for a modal without rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
||||||
|
*/
|
||||||
|
"shape"?: 'soft' | 'round' | 'rectangular';
|
||||||
/**
|
/**
|
||||||
* If `true`, a backdrop will be displayed behind the modal. This property controls whether or not the backdrop darkens the screen when the modal is presented. It does not control whether or not the backdrop is active or present in the DOM.
|
* If `true`, a backdrop will be displayed behind the modal. This property controls whether or not the backdrop darkens the screen when the modal is presented. It does not control whether or not the backdrop is active or present in the DOM.
|
||||||
*/
|
*/
|
||||||
|
19
core/src/components/modal/modal.ionic.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
@use "../../themes/ionic/ionic.globals.scss" as globals;
|
||||||
|
@import "./modal";
|
||||||
|
|
||||||
|
// Ionic Modal
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
// Shape
|
||||||
|
// -------------------------------------
|
||||||
|
:host(.modal-round) {
|
||||||
|
--border-radius: #{globals.$ionic-border-radius-1000};
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.modal-soft) {
|
||||||
|
--border-radius: #{globals.$ionic-border-radius-400};
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.modal-rectangular) {
|
||||||
|
--border-radius: #{globals.$ionic-border-radius-0};
|
||||||
|
}
|
@ -62,7 +62,7 @@ import { setCardStatusBarDark, setCardStatusBarDefault } from './utils';
|
|||||||
styleUrls: {
|
styleUrls: {
|
||||||
ios: 'modal.ios.scss',
|
ios: 'modal.ios.scss',
|
||||||
md: 'modal.md.scss',
|
md: 'modal.md.scss',
|
||||||
ionic: 'modal.md.scss',
|
ionic: 'modal.ionic.scss',
|
||||||
},
|
},
|
||||||
shadow: true,
|
shadow: true,
|
||||||
})
|
})
|
||||||
@ -291,6 +291,15 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop() canDismiss: boolean | ((data?: any, role?: string) => Promise<boolean>) = true;
|
@Prop() canDismiss: boolean | ((data?: any, role?: string) => Promise<boolean>) = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to `"soft"` for a modal with slightly rounded corners,
|
||||||
|
* `"round"` for a modal with fully rounded corners, or `"rectangular"`
|
||||||
|
* for a modal without rounded corners.
|
||||||
|
*
|
||||||
|
* Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
||||||
|
*/
|
||||||
|
@Prop() shape?: 'soft' | 'round' | 'rectangular';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted after the modal has presented.
|
* Emitted after the modal has presented.
|
||||||
*/
|
*/
|
||||||
@ -888,6 +897,22 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getShape(): string | undefined {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const { shape } = this;
|
||||||
|
|
||||||
|
// TODO(ROU-11167): Remove theme check when shapes are defined for all themes.
|
||||||
|
if (theme !== 'ionic') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape === undefined) {
|
||||||
|
return 'round';
|
||||||
|
}
|
||||||
|
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
private onHandleClick = () => {
|
private onHandleClick = () => {
|
||||||
const { sheetTransition, handleBehavior } = this;
|
const { sheetTransition, handleBehavior } = this;
|
||||||
if (handleBehavior !== 'cycle' || sheetTransition !== undefined) {
|
if (handleBehavior !== 'cycle' || sheetTransition !== undefined) {
|
||||||
@ -936,6 +961,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
|||||||
const theme = getIonTheme(this);
|
const theme = getIonTheme(this);
|
||||||
const isCardModal = presentingElement !== undefined && theme === 'ios';
|
const isCardModal = presentingElement !== undefined && theme === 'ios';
|
||||||
const isHandleCycle = handleBehavior === 'cycle';
|
const isHandleCycle = handleBehavior === 'cycle';
|
||||||
|
const shape = this.getShape();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Host
|
<Host
|
||||||
@ -950,6 +976,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
|||||||
['modal-default']: !isCardModal && !isSheetModal,
|
['modal-default']: !isCardModal && !isSheetModal,
|
||||||
[`modal-card`]: isCardModal,
|
[`modal-card`]: isCardModal,
|
||||||
[`modal-sheet`]: isSheetModal,
|
[`modal-sheet`]: isSheetModal,
|
||||||
|
[`modal-${shape}`]: shape !== undefined,
|
||||||
'overlay-hidden': true,
|
'overlay-hidden': true,
|
||||||
[FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false,
|
[FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false,
|
||||||
...getClassMap(this.cssClass),
|
...getClassMap(this.cssClass),
|
||||||
|
176
core/src/components/modal/test/shape/index.html
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Modal - Shape</title>
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||||
|
/>
|
||||||
|
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||||
|
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||||
|
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||||
|
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||||
|
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
ion-modal {
|
||||||
|
--box-shadow: 0px 0px 30px 10px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import { modalController } from '../../../../dist/ionic/index.esm.js';
|
||||||
|
window.modalController = modalController;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ion-app>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Modal - Shape</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content class="ion-padding" id="content" no-bounce>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Sheet</h1>
|
||||||
|
<button id="sheet-modal-default" onclick="presentSheetModal()">Present Sheet Modal (Default)</button>
|
||||||
|
<button id="sheet-modal-round" onclick="presentSheetModal({ shape: 'round' })">
|
||||||
|
Present Sheet Modal (Round)
|
||||||
|
</button>
|
||||||
|
<button id="sheet-modal-soft" onclick="presentSheetModal({ shape: 'soft' })">
|
||||||
|
Present Sheet Modal (Soft)
|
||||||
|
</button>
|
||||||
|
<button id="sheet-modal-rectangular" onclick="presentSheetModal({ shape: 'rectangular' })">
|
||||||
|
Present Sheet Modal (Rectangular)
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h1>Card</h1>
|
||||||
|
<button id="card-modal-default" onclick="presentCardModal()">Present Card Modal (Default)</button>
|
||||||
|
<button id="card-modal-round" onclick="presentCardModal({ shape: 'round' })">
|
||||||
|
Present Card Modal (Round)
|
||||||
|
</button>
|
||||||
|
<button id="card-modal-soft" onclick="presentCardModal({ shape: 'soft' })">Present Card Modal (Soft)</button>
|
||||||
|
<button id="card-modal-rectangular" onclick="presentCardModal({ shape: 'rectangular' })">
|
||||||
|
Present Card Modal (Rectangular)
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
||||||
|
</ion-app>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function renderContent() {
|
||||||
|
let items = '';
|
||||||
|
|
||||||
|
for (var i = 0; i < 25; i++) {
|
||||||
|
items += `<ion-item>Item ${i}</ion-item>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function presentSheetModal(options) {
|
||||||
|
const modal = await createSheetModal(options);
|
||||||
|
await modal.present();
|
||||||
|
|
||||||
|
await modal.onDidDismiss();
|
||||||
|
modal.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createSheetModal(options) {
|
||||||
|
// create component to open
|
||||||
|
const element = document.createElement('div');
|
||||||
|
element.innerHTML = `
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Super Modal</ion-title>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<ion-button class="dismiss">Dismiss Modal</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<ion-list>
|
||||||
|
${renderContent()}
|
||||||
|
</ion-list>
|
||||||
|
</ion-content>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let extraOptions = {
|
||||||
|
initialBreakpoint: 0.75,
|
||||||
|
breakpoints: [0, 0.25, 0.5, 0.75, 1],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
extraOptions = {
|
||||||
|
...extraOptions,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// present the modal
|
||||||
|
const modalElement = Object.assign(document.createElement('ion-modal'), {
|
||||||
|
component: element,
|
||||||
|
...extraOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
// listen for close event
|
||||||
|
const button = element.querySelector('ion-button');
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
modalElement.dismiss();
|
||||||
|
});
|
||||||
|
document.body.appendChild(modalElement);
|
||||||
|
return modalElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function presentCardModal(opts) {
|
||||||
|
const modal = await createCardModal(document.querySelectorAll('.ion-page')[1], opts);
|
||||||
|
await modal.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createCardModal(presentingEl, opts) {
|
||||||
|
// create component to open
|
||||||
|
const element = document.createElement('div');
|
||||||
|
element.innerHTML = `
|
||||||
|
<ion-header id="modal-header">
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<ion-button class="dismiss">Close</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<div class="content-wrapper">${renderContent()}</div>
|
||||||
|
|
||||||
|
<ion-footer>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Footer</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-footer>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// listen for close event
|
||||||
|
const button = element.querySelector('ion-button.dismiss');
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
modalController.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
// present the modal
|
||||||
|
const modalElement = await modalController.create({
|
||||||
|
presentingElement: presentingEl,
|
||||||
|
component: element,
|
||||||
|
...opts,
|
||||||
|
});
|
||||||
|
return modalElement;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
57
core/src/components/modal/test/shape/modal.e2e.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { expect } from '@playwright/test';
|
||||||
|
import { configs, test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This behavior does not vary across directions.
|
||||||
|
*/
|
||||||
|
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screenshot, title }) => {
|
||||||
|
test.beforeEach(async ({ page }) => {
|
||||||
|
await page.goto('/src/components/modal/test/shape', config);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe(title('modal: shape'), () => {
|
||||||
|
test.describe('sheet', () => {
|
||||||
|
['default', 'round', 'soft', 'rectangular'].forEach((shape) => {
|
||||||
|
test(`${shape} - should not have visual regressions`, async ({ page }) => {
|
||||||
|
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||||
|
|
||||||
|
await page.click(`#sheet-modal-${shape}`);
|
||||||
|
await ionModalDidPresent.next();
|
||||||
|
|
||||||
|
await expect(page).toHaveScreenshot(screenshot(`modal-shape-sheet-${shape}`), {
|
||||||
|
/**
|
||||||
|
* Animations must be enabled to capture the screenshot.
|
||||||
|
* By default, animations are disabled with toHaveScreenshot,
|
||||||
|
* and when capturing the screenshot will call animation.finish().
|
||||||
|
* This will cause the modal to close and the screenshot capture
|
||||||
|
* to be invalid.
|
||||||
|
*/
|
||||||
|
animations: 'allow',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('card', () => {
|
||||||
|
['default', 'round', 'soft', 'rectangular'].forEach((shape) => {
|
||||||
|
test(`${shape} - should not have visual regressions`, async ({ page }) => {
|
||||||
|
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||||
|
|
||||||
|
await page.click(`#card-modal-${shape}`);
|
||||||
|
await ionModalDidPresent.next();
|
||||||
|
|
||||||
|
await expect(page).toHaveScreenshot(screenshot(`modal-shape-card-${shape}`), {
|
||||||
|
/**
|
||||||
|
* Animations must be enabled to capture the screenshot.
|
||||||
|
* By default, animations are disabled with toHaveScreenshot,
|
||||||
|
* and when capturing the screenshot will call animation.finish().
|
||||||
|
* This will cause the popover to close and the screenshot capture
|
||||||
|
* to be invalid.
|
||||||
|
*/
|
||||||
|
animations: 'allow',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 18 KiB |
@ -27,7 +27,7 @@ export const IonPickerLegacy = /*@__PURE__*/ defineOverlayContainer<JSX.IonPicke
|
|||||||
|
|
||||||
export const IonToast = /*@__PURE__*/ defineOverlayContainer<JSX.IonToast>('ion-toast', defineIonToastCustomElement, ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'positionAnchor', 'swipeGesture', 'theme', 'translucent', 'trigger']);
|
export const IonToast = /*@__PURE__*/ defineOverlayContainer<JSX.IonToast>('ion-toast', defineIonToastCustomElement, ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'positionAnchor', 'swipeGesture', 'theme', 'translucent', 'trigger']);
|
||||||
|
|
||||||
export const IonModal = /*@__PURE__*/ defineOverlayContainer<JSX.IonModal>('ion-modal', defineIonModalCustomElement, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'focusTrap', 'handle', 'handleBehavior', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'theme', 'trigger'], true);
|
export const IonModal = /*@__PURE__*/ defineOverlayContainer<JSX.IonModal>('ion-modal', defineIonModalCustomElement, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'focusTrap', 'handle', 'handleBehavior', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'shape', 'showBackdrop', 'theme', 'trigger'], true);
|
||||||
|
|
||||||
export const IonPopover = /*@__PURE__*/ defineOverlayContainer<JSX.IonPopover>('ion-popover', defineIonPopoverCustomElement, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'focusTrap', 'htmlAttributes', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'theme', 'translucent', 'trigger', 'triggerAction']);
|
export const IonPopover = /*@__PURE__*/ defineOverlayContainer<JSX.IonPopover>('ion-popover', defineIonPopoverCustomElement, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'focusTrap', 'htmlAttributes', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'theme', 'translucent', 'trigger', 'triggerAction']);
|
||||||
|
|
||||||
|