mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-08 23:58:13 +08:00
fix(input): prevent layout shift when hiding password toggle (#30533)
Issue number: resolves #29562 --------- <!-- 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? When an input with a password toggle is given `disabled` or `readonly`, hiding the password toggle causes a layout shift as it shrinks the height of the input component. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - Password toggle is given `visibility: hidden` instead of removing it from the DOM with `display: none` so it retains it's space but is still hidden and still removed from the accessibility tree. ## 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 This solution was suggested by @piotr-cz in the bug report. <!-- 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: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
This commit is contained in:
@ -618,5 +618,5 @@
|
|||||||
*/
|
*/
|
||||||
:host([disabled]) ::slotted(ion-input-password-toggle),
|
:host([disabled]) ::slotted(ion-input-password-toggle),
|
||||||
:host([readonly]) ::slotted(ion-input-password-toggle) {
|
:host([readonly]) ::slotted(ion-input-password-toggle) {
|
||||||
display: none;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,5 +26,69 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|||||||
const input = page.locator('ion-input');
|
const input = page.locator('ion-input');
|
||||||
await expect(input).toHaveScreenshot(screenshot(`input-disabled`));
|
await expect(input).toHaveScreenshot(screenshot(`input-disabled`));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should maintain consistent height when password toggle is hidden on disabled input', async ({
|
||||||
|
page,
|
||||||
|
}, testInfo) => {
|
||||||
|
testInfo.annotations.push({
|
||||||
|
type: 'issue',
|
||||||
|
description: 'https://github.com/ionic-team/ionic-framework/issues/29562',
|
||||||
|
});
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<ion-input label="Password" type="password" value="password123">
|
||||||
|
<ion-input-password-toggle slot="end"></ion-input-password-toggle>
|
||||||
|
</ion-input>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
const input = page.locator('ion-input');
|
||||||
|
|
||||||
|
// Get the height when input is enabled
|
||||||
|
const enabledHeight = await input.boundingBox().then((box) => box?.height);
|
||||||
|
|
||||||
|
// Disable the input
|
||||||
|
await input.evaluate((el) => el.setAttribute('disabled', 'true'));
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
// Get the height when input is disabled
|
||||||
|
const disabledHeight = await input.boundingBox().then((box) => box?.height);
|
||||||
|
|
||||||
|
// Verify heights are the same
|
||||||
|
expect(enabledHeight).toBe(disabledHeight);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should maintain consistent height when password toggle is hidden on readonly input', async ({
|
||||||
|
page,
|
||||||
|
}, testInfo) => {
|
||||||
|
testInfo.annotations.push({
|
||||||
|
type: 'issue',
|
||||||
|
description: 'https://github.com/ionic-team/ionic-framework/issues/29562',
|
||||||
|
});
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<ion-input label="Password" type="password" value="password123">
|
||||||
|
<ion-input-password-toggle slot="end"></ion-input-password-toggle>
|
||||||
|
</ion-input>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
const input = page.locator('ion-input');
|
||||||
|
|
||||||
|
// Get the height when input is enabled
|
||||||
|
const enabledHeight = await input.boundingBox().then((box) => box?.height);
|
||||||
|
|
||||||
|
// Make the input readonly
|
||||||
|
await input.evaluate((el) => el.setAttribute('readonly', 'true'));
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
// Get the height when input is readonly
|
||||||
|
const readonlyHeight = await input.boundingBox().then((box) => box?.height);
|
||||||
|
|
||||||
|
// Verify heights are the same
|
||||||
|
expect(enabledHeight).toBe(readonlyHeight);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user