diff --git a/core/src/components/input/input.scss b/core/src/components/input/input.scss
index 57d438eb2d..2161cc3dfb 100644
--- a/core/src/components/input/input.scss
+++ b/core/src/components/input/input.scss
@@ -618,5 +618,5 @@
*/
:host([disabled]) ::slotted(ion-input-password-toggle),
:host([readonly]) ::slotted(ion-input-password-toggle) {
- display: none;
+ visibility: hidden;
}
diff --git a/core/src/components/input/test/states/input.e2e.ts b/core/src/components/input/test/states/input.e2e.ts
index eb51f76096..33d33d91cf 100644
--- a/core/src/components/input/test/states/input.e2e.ts
+++ b/core/src/components/input/test/states/input.e2e.ts
@@ -26,5 +26,69 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
const input = page.locator('ion-input');
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(
+ `
+
+
+
+ `,
+ 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(
+ `
+
+
+
+ `,
+ 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);
+ });
});
});