feat(datetime): pass roles to overlay when dismissing (#29221)

Issue number: resolves #28298

---------

<!-- 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. -->
- the ion-datetime didn't provide a role(source trigger for closing the
overlay) on default buttons while closing parent overlay

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

- ion-datetime provides a role to default buttons while closing the
parent overlay

## 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/.github/CONTRIBUTING.md#footer
for more information.
-->


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

---------

Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
This commit is contained in:
Rahul Rajesh
2024-04-04 00:51:03 +05:30
committed by GitHub
parent 90a7e70a1c
commit 6945adc3cc
3 changed files with 113 additions and 4 deletions

View File

@ -541,7 +541,7 @@ export class Datetime implements ComponentInterface {
} }
if (closeOverlay) { if (closeOverlay) {
this.closeParentOverlay(); this.closeParentOverlay(CONFIRM_ROLE);
} }
} }
@ -566,7 +566,7 @@ export class Datetime implements ComponentInterface {
this.ionCancel.emit(); this.ionCancel.emit();
if (closeOverlay) { if (closeOverlay) {
this.closeParentOverlay(); this.closeParentOverlay(CANCEL_ROLE);
} }
} }
@ -616,13 +616,13 @@ export class Datetime implements ComponentInterface {
return Array.isArray(activeParts) ? activeParts[0] : activeParts; return Array.isArray(activeParts) ? activeParts[0] : activeParts;
}; };
private closeParentOverlay = () => { private closeParentOverlay = (role: string) => {
const popoverOrModal = this.el.closest('ion-modal, ion-popover') as const popoverOrModal = this.el.closest('ion-modal, ion-popover') as
| HTMLIonModalElement | HTMLIonModalElement
| HTMLIonPopoverElement | HTMLIonPopoverElement
| null; | null;
if (popoverOrModal) { if (popoverOrModal) {
popoverOrModal.dismiss(); popoverOrModal.dismiss(undefined, role);
} }
}; };
@ -2645,5 +2645,7 @@ export class Datetime implements ComponentInterface {
} }
let datetimeIds = 0; let datetimeIds = 0;
const CANCEL_ROLE = 'datetime-cancel';
const CONFIRM_ROLE = 'datetime-confirm';
const WHEEL_ITEM_PART = 'wheel-item'; const WHEEL_ITEM_PART = 'wheel-item';
const WHEEL_ITEM_ACTIVE_PART = `active`; const WHEEL_ITEM_ACTIVE_PART = `active`;

View File

@ -0,0 +1,41 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ config, title }) => {
test.describe(title('datetime: overlay roles'), () => {
test.beforeEach(async ({ page }) => {
await page.setContent(
`
<ion-modal>
<ion-datetime></ion-datetime>
</ion-modal>
`,
config
);
});
test('should pass role to overlay when calling confirm method', async ({ page }) => {
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
const modal = page.locator('ion-modal');
const datetime = page.locator('ion-datetime');
await modal.evaluate((el: HTMLIonModalElement) => el.present());
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.confirm(true));
await ionModalDidDismiss.next();
expect(ionModalDidDismiss).toHaveReceivedEventDetail({ data: undefined, role: 'datetime-confirm' });
});
test('should pass role to overlay when calling cancel method', async ({ page }) => {
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
const modal = page.locator('ion-modal');
const datetime = page.locator('ion-datetime');
await modal.evaluate((el: HTMLIonModalElement) => el.present());
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.cancel(true));
await ionModalDidDismiss.next();
expect(ionModalDidDismiss).toHaveReceivedEventDetail({ data: undefined, role: 'datetime-cancel' });
});
});
});

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Datetime - Overlay Roles</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<style>
ion-modal.ios,
ion-popover.datetime-popover.ios {
--width: 350px;
--height: 420px;
}
ion-modal.md,
ion-popover.datetime-popover.md {
--width: 350px;
--height: 450px;
}
ion-datetime {
width: 350px;
}
</style>
</head>
<body>
<ion-app>
<ion-header translucent="true">
<ion-toolbar>
<ion-title>Datetime - Overlay Roles</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button onclick="presentModal()">Present Modal</ion-button>
</ion-content>
</ion-app>
<script>
const presentModal = async () => {
const modal = await createModal();
await modal.present();
console.log(await modal.onDidDismiss());
};
const createModal = () => {
// create component to open
const element = document.createElement('div');
element.innerHTML = `
<ion-datetime show-default-buttons="true"></ion-datetime>
`;
// present the modal
const modalElement = Object.assign(document.createElement('ion-modal'), {
component: element,
});
const app = document.querySelector('ion-app');
app.appendChild(modalElement);
return modalElement;
};
</script>
</body>
</html>