From 0d273c4b604f3f29d33ce07146083c41c35d5b0a Mon Sep 17 00:00:00 2001
From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Date: Wed, 22 Jan 2025 13:47:47 -0500
Subject: [PATCH 01/14] fix(input): use darker color for helper text
---
core/src/components/input/input.md.solid.scss | 4 ++++
core/src/components/input/input.scss | 4 +++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/core/src/components/input/input.md.solid.scss b/core/src/components/input/input.md.solid.scss
index 98cde92880a..05bcc00ea55 100644
--- a/core/src/components/input/input.md.solid.scss
+++ b/core/src/components/input/input.md.solid.scss
@@ -32,6 +32,10 @@
--border-color: var(--highlight-color);
}
+/**
+ * The bottom content should never have
+ * a border with the solid style.
+ */
:host(.input-fill-solid) .input-bottom {
border-top: none;
}
diff --git a/core/src/components/input/input.scss b/core/src/components/input/input.scss
index 80ebc9896ae..9a52f2ac519 100644
--- a/core/src/components/input/input.scss
+++ b/core/src/components/input/input.scss
@@ -306,6 +306,8 @@
border-top: var(--border-width) var(--border-style) var(--border-color);
font-size: dynamic-font(12px);
+
+ white-space: normal;
}
/**
@@ -340,7 +342,7 @@
.input-bottom .helper-text {
display: block;
- color: #{$text-color-step-450};
+ color: $text-color-step-300;
}
:host(.ion-touched.ion-invalid) .input-bottom .error-text {
From 940fb84a1cbc480dbc08496ce4d15e40461f92a8 Mon Sep 17 00:00:00 2001
From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Date: Wed, 22 Jan 2025 13:57:08 -0500
Subject: [PATCH 02/14] test(input): update e2e test to improve examples
---
.../input/test/bottom-content/index.html | 101 +++--
.../input/test/bottom-content/input.e2e.ts | 354 ++++++++++--------
2 files changed, 272 insertions(+), 183 deletions(-)
diff --git a/core/src/components/input/test/bottom-content/index.html b/core/src/components/input/test/bottom-content/index.html
index d08d111c0eb..cc61c09265f 100644
--- a/core/src/components/input/test/bottom-content/index.html
+++ b/core/src/components/input/test/bottom-content/index.html
@@ -15,10 +15,11 @@
-
- `,
- config
- );
+ await expect(input).toHaveAttribute('aria-invalid');
+ });
+ test('input should not have aria-invalid attribute when input is valid', async ({ page }) => {
+ await page.setContent(
+ ``,
+ config
+ );
- const errorText = page.locator('ion-input .error-text');
- await expect(errorText).toHaveScreenshot(screenshot(`input-error-custom-color`));
- });
- test('input should have an aria-describedby attribute when error text is present', async ({ page }) => {
- await page.setContent(
- ``,
- config
- );
+ const input = page.locator('ion-input input');
- const input = page.locator('ion-input input');
- const errorText = page.locator('ion-input .error-text');
- const errorTextId = await errorText.getAttribute('id');
- const ariaDescribedBy = await input.getAttribute('aria-describedby');
+ await expect(input).not.toHaveAttribute('aria-invalid');
+ });
+ test('input should not have aria-describedby attribute when no hint or error text is present', async ({
+ page,
+ }) => {
+ await page.setContent(``, config);
- expect(ariaDescribedBy).toBe(errorTextId);
- });
- test('input should have aria-invalid attribute when input is invalid', async ({ page }) => {
- await page.setContent(
- ``,
- config
- );
+ const input = page.locator('ion-input input');
- const input = page.locator('ion-input input');
+ await expect(input).not.toHaveAttribute('aria-describedby');
+ });
+ });
+});
- await expect(input).toHaveAttribute('aria-invalid');
- });
- test('input should not have aria-invalid attribute when input is valid', async ({ page }) => {
- await page.setContent(
- ``,
- config
- );
+/**
+ * Rendering is different across modes
+ */
+configs({ modes: ['ios', 'md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
+ test.describe(title('input: helper text rendering'), () => {
+ test('should not have visual regressions when rendering helper text', async ({ page }) => {
+ await page.setContent(``, config);
- const input = page.locator('ion-input input');
+ const bottomEl = page.locator('ion-input');
+ await expect(bottomEl).toHaveScreenshot(screenshot(`input-helper-text`));
+ });
+ test('should not have visual regressions when rendering helper text with wrapping text', async ({ page }) => {
+ await page.setContent(
+ ``,
+ config
+ );
- await expect(input).not.toHaveAttribute('aria-invalid');
- });
- test('input should not have aria-describedby attribute when no hint or error text is present', async ({
- page,
- }) => {
- await page.setContent(``, config);
+ const bottomEl = page.locator('ion-input');
+ await expect(bottomEl).toHaveScreenshot(screenshot(`input-helper-text-wrapping`));
+ });
+ test('should not have visual regressions when rendering helper text with a stacked label', async ({ page }) => {
+ await page.setContent(
+ ``,
+ config
+ );
- const input = page.locator('ion-input input');
+ const bottomEl = page.locator('ion-input');
+ await expect(bottomEl).toHaveScreenshot(screenshot(`input-helper-text-stacked-label`));
+ });
+ });
- await expect(input).not.toHaveAttribute('aria-describedby');
- });
+ test.describe(title('input: error text rendering'), () => {
+ test('should not have visual regressions when rendering error text', async ({ page }) => {
+ await page.setContent(
+ ``,
+ config
+ );
+
+ const bottomEl = page.locator('ion-input');
+ await expect(bottomEl).toHaveScreenshot(screenshot(`input-error-text`));
});
- test.describe('input: hint text rendering', () => {
- test.describe('regular inputs', () => {
- test('should not have visual regressions when rendering helper text', async ({ page }) => {
- await page.setContent(``, config);
-
- const bottomEl = page.locator('ion-input .input-bottom');
- await expect(bottomEl).toHaveScreenshot(screenshot(`input-bottom-content-helper`));
- });
- test('should not have visual regressions when rendering error text', async ({ page }) => {
- await page.setContent(
- ``,
- config
- );
-
- const bottomEl = page.locator('ion-input .input-bottom');
- await expect(bottomEl).toHaveScreenshot(screenshot(`input-bottom-content-error`));
- });
- });
+ test('should not have visual regressions when rendering error text with a stacked label', async ({ page }) => {
+ await page.setContent(
+ ``,
+ config
+ );
+
+ const bottomEl = page.locator('ion-input');
+ await expect(bottomEl).toHaveScreenshot(screenshot(`input-error-text-stacked-label`));
});
});
});
/**
- * Rendering is the same across modes
+ * Customizing supporting text is the same across modes and directions
*/
+configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
+ test.describe(title('input: supporting text customization'), () => {
+ test('should not have visual regressions when rendering helper text with a custom color via css', async ({
+ page,
+ }) => {
+ await page.setContent(
+ `
+
+
+ `,
+ config
+ );
+
+ const helperText = page.locator('ion-input');
+ await expect(helperText).toHaveScreenshot(screenshot(`input-helper-text-custom-color`));
+ });
+ test('should not have visual regressions when rendering error text with a custom color via css', async ({
+ page,
+ }) => {
+ await page.setContent(
+ `
+
+
+ `,
+ config
+ );
+
+ const errorText = page.locator('ion-input');
+ await expect(errorText).toHaveScreenshot(screenshot(`input-error-text-custom-color`));
+ });
+ test('should not have visual regressions when rendering error text with a custom color via css var', async ({
+ page,
+ }) => {
+ await page.setContent(
+ `
+
+
+ `,
+ config
+ );
+
+ const errorText = page.locator('ion-input');
+ await expect(errorText).toHaveScreenshot(screenshot(`input-error-text-custom-color-var`));
+ });
+ });
+});
+
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('input: counter'), () => {
test.describe('input: counter functionality', () => {
test('should not activate if maxlength is not specified even if bottom content is visible', async ({ page }) => {
await page.setContent(
`
-
+
`,
config
);
@@ -193,7 +226,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
test('default formatter should be used', async ({ page }) => {
await page.setContent(
`
-
+
`,
config
);
@@ -203,8 +236,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
test('custom formatter should be used when provided', async ({ page }) => {
await page.setContent(
`
-
-
+