test(menu): safe area and proper var reset (#28177)

Issue number: N/A

---------

<!-- 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. -->

- There are no tests for menu when safe area is applied.
- The safe area variables on menu weren't being reset properly to allow
easy local customization.

Currently, some of the variables are being set to `env()`. This is the
same structure that is being used in core. However, this doesn't
prevents users from mocking the safe area when using
`--ion-safe-area-left: 50px` on `html`. It makes it hard to create tests
to validate that padding is being applied to the safe area.

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

- Tests have been added.
- The safe area variables on menu are now being reset to use the values
from `:root`.

The variables are being `unset` in order for the variables to [default
to parent styles](https://stackoverflow.com/a/69491310/5374225). Since
core styles has already declared the variables, then developers can use
`--ion-safe-area-left: 50px` on `html`.

## 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. -->

N/A

---------

Co-authored-by: ionitron <hi@ionicframework.com>
This commit is contained in:
Maria Hutt
2023-09-18 10:36:58 -07:00
committed by GitHub
parent 45bbea6a34
commit 574d762594
27 changed files with 192 additions and 6 deletions

View File

@ -83,12 +83,14 @@
* Otherwise, the content will have less space on both sides. * Otherwise, the content will have less space on both sides.
* *
* RTL: * RTL:
* The right side of the menu touches the screen edge. The safe area padding has * The right side of the menu touches the screen edge.
* already been set in the core styles, so there's no need to set it again. * The right side needs to revert back to the default value that was set in the core styles, so we unset it here.
* This would keep the variable consistent with the core styles.
* Additionally, it would continue to allow users to override the variable if they choose to.
* The left side of the menu is not touching the screen edge. Padding is not * The left side of the menu is not touching the screen edge. Padding is not
* applied to the left side of the menu. A value of 0 is set. * applied to the left side of the menu. A value of 0 is set.
*/ */
--ion-safe-area-right: env(safe-area-inset-right); --ion-safe-area-right: unset;
--ion-safe-area-left: 0px; --ion-safe-area-left: 0px;
} }
} }
@ -118,12 +120,14 @@
* Otherwise, the content will have less space on both sides. * Otherwise, the content will have less space on both sides.
* *
* RTL: * RTL:
* The left side of the menu touches the screen edge. The safe area padding has * The left side of the menu touches the screen edge.
* already been set in the core styles, so there's no need to set it again. * The left side needs to revert back to the default value that was set in the core styles, so we unset it here.
* This would keep the variable consistent with the core styles.
* Additionally, it would continue to allow users to override the variable if they choose to.
* The right side of the menu is not touching the screen edge. Padding is not * The right side of the menu is not touching the screen edge. Padding is not
* applied to the right side of the menu. A value of 0 is set. * applied to the right side of the menu. A value of 0 is set.
*/ */
--ion-safe-area-left: env(safe-area-inset-left); --ion-safe-area-left: unset;
--ion-safe-area-right: 0px; --ion-safe-area-right: 0px;
} }
} }

View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Menu - Safe Area Padding</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<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>
<script type="module">
import { menuController } from '../../../../dist/ionic/index.esm.js';
window.menuController = menuController;
</script>
<style>
:root {
--ion-safe-area-left: 60px;
--ion-safe-area-right: 20px;
}
</style>
</head>
<body>
<ion-app>
<ion-menu side="start" menu-id="start-menu" content-id="main">
<ion-header>
<ion-toolbar color="primary">
<ion-title>This is the title for a start menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item>Menu Item</ion-item>
</ion-list>
</ion-content>
</ion-menu>
<ion-menu side="end" menu-id="end-menu" content-id="main">
<ion-header>
<ion-toolbar color="danger">
<ion-title>This is the title for an end menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item>Menu Item</ion-item>
</ion-list>
</ion-content>
</ion-menu>
<div class="ion-page" id="main">
<ion-header>
<ion-toolbar>
<ion-title>Menu - Safe Area Padding</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button expand="block" id="open-start" onclick="openStart()">Open Start Menu</ion-button>
<ion-button expand="block" id="open-end" onclick="openEnd()">Open End Menu</ion-button>
</ion-content>
</div>
</ion-app>
<script>
async function openStart() {
// Open the menu by menu-id
await menuController.enable(true, 'start-menu');
await menuController.open('start-menu');
}
async function openEnd() {
// Open the menu by side
await menuController.open('end');
}
</script>
</body>
</html>

View File

@ -0,0 +1,101 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
/**
* This behavior does not vary across modes.
*/
configs({ modes: ['md'] }).forEach(({ title, config, screenshot }) => {
test.describe(title('menu: safe area'), () => {
test.beforeEach(async ({ page }) => {
await page.goto(`/src/components/menu/test/safe-area`, config);
});
test.describe('side: start', () => {
test('should render with safe area when notch is on the left', async ({ page }) => {
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
await page.evaluate(() => {
const style = document.querySelector('style');
style!.innerHTML = `
:root {
--ion-safe-area-left: 50px !important;
--ion-safe-area-right: 10px !important;
}
`;
});
await page.click('#open-start');
await ionDidOpen.next();
const startMenu = page.locator('[menu-id="start-menu"]');
await expect(startMenu).toHaveClass(/show-menu/);
await expect(page).toHaveScreenshot(screenshot(`menu-start-safe-area-left-notch`));
});
test('should render with safe area when notch is on the right', async ({ page }) => {
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
await page.evaluate(() => {
const style = document.querySelector('style');
style!.innerHTML = `
:root {
--ion-safe-area-left: 10px !important;
--ion-safe-area-right: 50px !important;
}
`;
});
await page.click('#open-start');
await ionDidOpen.next();
const startMenu = page.locator('[menu-id="start-menu"]');
await expect(startMenu).toHaveClass(/show-menu/);
await expect(page).toHaveScreenshot(screenshot(`menu-start-safe-area-right-notch`));
});
});
test.describe('side: end', () => {
test('should render with safe area when notch is on the left', async ({ page }) => {
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
await page.evaluate(() => {
const style = document.querySelector('style');
style!.innerHTML = `
:root {
--ion-safe-area-left: 50px !important;
--ion-safe-area-right: 10px !important;
}
`;
});
await page.click('#open-end');
await ionDidOpen.next();
const endMenu = page.locator('[menu-id="end-menu"]');
await expect(endMenu).toHaveClass(/show-menu/);
await expect(page).toHaveScreenshot(screenshot(`menu-end-safe-area-left-notch`));
});
test('should render with safe area when notch is on the right', async ({ page }) => {
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
await page.evaluate(() => {
const style = document.querySelector('style');
style!.innerHTML = `
:root {
--ion-safe-area-left: 10px !important;
--ion-safe-area-right: 50px !important;
}
`;
});
await page.click('#open-end');
await ionDidOpen.next();
const endMenu = page.locator('[menu-id="end-menu"]');
await expect(endMenu).toHaveClass(/show-menu/);
await expect(page).toHaveScreenshot(screenshot(`menu-end-safe-area-right-notch`));
});
});
});
});