Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(input, textarea): show error state after touch #26940

Merged
merged 14 commits into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/components/input/input.md.outline.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* If the input has a validity state, the
* border should reflect that as a color.
*/
:host(.input-fill-outline.ion-touched.ion-valid),
:host(.has-focus.input-fill-outline.ion-valid),
:host(.input-fill-outline.ion-touched.ion-invalid) {
--border-color: var(--highlight-color);
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/components/input/input.md.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
* If the input has a validity state, the
* border and label should reflect that as a color.
*/
:host(.ion-touched.ion-valid) .input-bottom,
:host(.has-focus.ion-valid) .input-bottom,
:host(.ion-touched.ion-invalid) .input-bottom {
--border-color: var(--highlight-color);
}
Expand Down Expand Up @@ -76,9 +76,9 @@
color: var(--highlight-color);
}

:host(.input-label-placement-floating.ion-touched.ion-valid) .label-text-wrapper,
:host(.has-focus.input-label-placement-floating.ion-valid) .label-text-wrapper,
:host(.input-label-placement-floating.ion-touched.ion-invalid) .label-text-wrapper,
:host(.input-label-placement-stacked.ion-touched.ion-valid) .label-text-wrapper,
:host(.has-focus.input-label-placement-stacked.ion-valid) .label-text-wrapper,
:host(.input-label-placement-stacked.ion-touched.ion-invalid) .label-text-wrapper {
color: var(--highlight-color);
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/input/input.md.solid.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* If the input has a validity state, the
* border should reflect that as a color.
*/
:host(.input-fill-solid.ion-touched.ion-valid) .input-wrapper,
:host(.has-focus.input-fill-solid.ion-valid) .input-wrapper,
:host(.input-fill-solid.ion-touched.ion-invalid) .input-wrapper {
--border-color: var(--highlight-color);
}
Expand Down
35 changes: 20 additions & 15 deletions core/src/components/input/input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,17 @@
--highlight-color: var(--highlight-color-invalid);
}

:host(.ion-touched.ion-valid) {
/**
* The component highlight is only shown
* on focus, so we can safely set the valid
* color state when valid. If we
* set it when .has-focus is present then
* the highlight color would change
* from the valid color to the component's
* color during the transition after the
* component loses focus.
*/
:host(.ion-valid) {
--highlight-color: var(--highlight-color-valid);
}

Expand All @@ -346,8 +356,14 @@
/**
* If the input has a validity state, the
* border and label should reflect that as a color.
* The invalid state should show if the input is
* invalid and has already been touched.
* The valid state should show if the input
* is valid, has already been touched, and
* is currently focused. Do not show the valid
* highlight when the input is blurred.
*/
:host(.ion-touched.ion-valid) .input-bottom,
:host(.has-focus.ion-valid) .input-bottom,
:host(.ion-touched.ion-invalid) .input-bottom {
--border-color: var(--highlight-color);
}
Expand All @@ -372,11 +388,11 @@
color: #{$background-color-step-550};
}

:host(.ion-invalid) .input-bottom .error-text {
:host(.ion-touched.ion-invalid) .input-bottom .error-text {
display: block;
}

:host(.ion-invalid) .input-bottom .helper-text {
:host(.ion-touched.ion-invalid) .input-bottom .helper-text {
display: none;
}

Expand All @@ -398,17 +414,6 @@
padding-inline-start: 16px;
}

// Input Highlight
// ----------------------------------------------------------------

:host(.ion-touched.ion-invalid) {
--highlight-color: var(--highlight-color-invalid);
}

:host(.ion-touched.ion-valid) {
--highlight-color: var(--highlight-color-valid);
}

Comment on lines -401 to -411
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was duplicate code

// Input Native
// ----------------------------------------------------------------

Expand Down
8 changes: 5 additions & 3 deletions core/src/components/input/test/bottom-content/input.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ test.describe('input: hint text', () => {
});
test('error text should be visible when input is invalid', async ({ page }) => {
await page.setContent(
`<ion-input class="ion-invalid" helper-text="my helper" error-text="my error" label="my input"></ion-input>`
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`
);

const helperText = page.locator('ion-input .helper-text');
Expand All @@ -68,7 +68,7 @@ test.describe('input: hint text', () => {
--highlight-color-invalid: purple;
}
</style>
<ion-input class="ion-invalid custom-input" label="my label" error-text="my error"></ion-input>
<ion-input class="ion-invalid ion-touched custom-input" label="my label" error-text="my error"></ion-input>
`);

const errorText = page.locator('ion-input .error-text');
Expand All @@ -88,7 +88,9 @@ test.describe('input: hint text', () => {
);
});
test('should not have visual regressions when rendering error text', async ({ page }) => {
await page.setContent(`<ion-input class="ion-invalid" error-text="my helper" label="my input"></ion-input>`);
await page.setContent(
`<ion-input class="ion-invalid ion-touched" error-text="my helper" label="my input"></ion-input>`
);

const bottomEl = page.locator('ion-input .input-bottom');
expect(await bottomEl.screenshot()).toMatchSnapshot(
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 18 additions & 18 deletions core/src/components/input/test/highlight/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
label-placement="start"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -105,10 +105,10 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
label-placement="floating"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -148,10 +148,10 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
label-placement="stacked"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -192,11 +192,11 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
fill="solid"
label-placement="start"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -238,11 +238,11 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
fill="solid"
label-placement="floating"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -284,11 +284,11 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
fill="solid"
label-placement="stacked"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -330,11 +330,11 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
fill="outline"
label-placement="start"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -376,11 +376,11 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
fill="outline"
label-placement="floating"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -422,11 +422,11 @@ <h2>Focus</h2>
</div>

<div class="grid-item">
<h2>Valid</h2>
<h2>Valid, Focus</h2>
<ion-input
fill="outline"
label-placement="stacked"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down
6 changes: 3 additions & 3 deletions core/src/components/input/test/highlight/input.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test.describe('input: highlights', () => {
await page.setContent(`
<ion-input
value="[email protected]"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -61,7 +61,7 @@ test.describe('input: highlights', () => {
<ion-input
fill="solid"
value="[email protected]"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down Expand Up @@ -114,7 +114,7 @@ test.describe('input: highlights', () => {
<ion-input
fill="outline"
value="[email protected]"
class="ion-touched ion-valid"
class="ion-valid has-focus"
label="Email"
error-text="Please enter a valid email"
helper-text="Enter an email"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion core/src/components/select/select.md.outline.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* If the select has a validity state, the
* border should reflect that as a color.
*/
:host(.select-fill-outline.ion-touched.ion-valid),
:host(.has-focus.select-fill-outline.ion-valid),
:host(.select-fill-outline.ion-touched.ion-invalid) {
--border-color: var(--highlight-color);
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/components/select/select.md.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
color: var(--highlight-color);
}

:host(.select-label-placement-floating.ion-touched.ion-valid) .label-text-wrapper,
:host(.has-focus.select-label-placement-floating.ion-valid) .label-text-wrapper,
:host(.select-label-placement-floating.ion-touched.ion-invalid) .label-text-wrapper,
:host(.select-label-placement-stacked.ion-touched.ion-valid) .label-text-wrapper,
:host(.has-focus.select-label-placement-stacked.ion-valid) .label-text-wrapper,
:host(.select-label-placement-stacked.ion-touched.ion-invalid) .label-text-wrapper {
color: var(--highlight-color);
}
Expand Down Expand Up @@ -103,7 +103,7 @@
* color if there is a validation state.
*/
:host(.select-expanded) .select-wrapper .select-icon,
:host(.ion-touched.ion-valid) .select-wrapper .select-icon,
:host(.has-focus.ion-valid) .select-wrapper .select-icon,
:host(.ion-touched.ion-invalid) .select-wrapper .select-icon,
:host(.ion-focused) .select-wrapper .select-icon {
color: var(--highlight-color);
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/select/select.md.solid.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* If the select has a validity state, the
* border should reflect that as a color.
*/
:host(.select-fill-solid.ion-touched.ion-valid) .select-wrapper,
:host(.has-focus.select-fill-solid.ion-valid) .select-wrapper,
:host(.select-fill-solid.ion-touched.ion-invalid) .select-wrapper {
--border-color: var(--highlight-color);
}
Expand Down
12 changes: 11 additions & 1 deletion core/src/components/select/select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,17 @@ button {
--highlight-color: var(--highlight-color-invalid);
}

:host(.ion-touched.ion-valid) {
/**
* The component highlight is only shown
* on focus, so we can safely set the valid
* color state when touched/valid. If we
* set it when .has-focus is present then
* the highlight color would change
* from the valid color to the component's
* color during the transition after the
* component loses focus.
*/
:host(.ion-valid) {
--highlight-color: var(--highlight-color-valid);
}

Expand Down
Loading