fix(fab): apply safe area in positioning to proper side regardless of direction (#28377)
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. --> When calculating the fab's horizontal position, the safe area is taken into account. However, which safe area side is applied changes depending on whether the document's direction is LTR or RTL. This is incorrect as the left safe area padding will always be on the left side regardless of direction, and vice versa. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> The left safe area is always applied to the fab's `left` position, and vice versa. ## 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. --> --------- Co-authored-by: ionitron <hi@ionicframework.com>
@ -23,15 +23,29 @@
|
||||
}
|
||||
|
||||
:host(.fab-horizontal-start) {
|
||||
@include position-horizontal(
|
||||
calc(#{$fab-content-margin} + var(--ion-safe-area-left, 0px)), null
|
||||
);
|
||||
/* stylelint-disable */
|
||||
@include ltr() {
|
||||
left: calc(#{$fab-content-margin} + var(--ion-safe-area-left, 0px));
|
||||
}
|
||||
|
||||
@include rtl() {
|
||||
right: calc(#{$fab-content-margin} + var(--ion-safe-area-right, 0px));
|
||||
left: unset;
|
||||
}
|
||||
/* stylelint-enable */
|
||||
}
|
||||
|
||||
:host(.fab-horizontal-end) {
|
||||
@include position-horizontal(
|
||||
null, calc(#{$fab-content-margin} + var(--ion-safe-area-right, 0px))
|
||||
);
|
||||
/* stylelint-disable */
|
||||
@include ltr() {
|
||||
right: calc(#{$fab-content-margin} + var(--ion-safe-area-right, 0px));
|
||||
}
|
||||
|
||||
@include rtl() {
|
||||
left: calc(#{$fab-content-margin} + var(--ion-safe-area-left, 0px));
|
||||
right: unset;
|
||||
}
|
||||
/* stylelint-enable */
|
||||
}
|
||||
|
||||
|
||||
|
||||
72
core/src/components/fab/test/safe-area/fab.e2e.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('fab: safe area'), () => {
|
||||
test('should ignore document direction in safe area positioning for start-positioned fab', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<style>
|
||||
:root {
|
||||
--ion-safe-area-left: 40px;
|
||||
--ion-safe-area-right: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ion-content>
|
||||
<ion-fab vertical="center" horizontal="start">
|
||||
<ion-fab-button>
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab>
|
||||
</ion-content>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
/**
|
||||
* We need to capture the entire page to check the fab's position,
|
||||
* but we don't need much extra white space.
|
||||
*/
|
||||
await page.setViewportSize({
|
||||
width: 200,
|
||||
height: 200,
|
||||
});
|
||||
|
||||
await expect(page).toHaveScreenshot(screenshot('fab-safe-area-horizontal-start'));
|
||||
});
|
||||
|
||||
test('should ignore document direction in safe area positioning for end-positioned fab', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<style>
|
||||
:root {
|
||||
--ion-safe-area-left: 40px;
|
||||
--ion-safe-area-right: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ion-content>
|
||||
<ion-fab vertical="center" horizontal="end">
|
||||
<ion-fab-button>
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab>
|
||||
</ion-content>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
/**
|
||||
* We need to capture the entire page to check the fab's position,
|
||||
* but we don't need much extra white space.
|
||||
*/
|
||||
await page.setViewportSize({
|
||||
width: 200,
|
||||
height: 200,
|
||||
});
|
||||
|
||||
await expect(page).toHaveScreenshot(screenshot('fab-safe-area-horizontal-end'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 3.4 KiB |