fix(item): form validation states are now properly shown (#23853)

resolves #23733 #23850

Co-authored-by: Will Martin <willmartindev@users.noreply.github.com>
This commit is contained in:
Liam DeBeasi
2021-08-31 17:18:21 -04:00
committed by GitHub
parent 12216d378d
commit 5ca2ce9197
5 changed files with 378 additions and 61 deletions

View File

@@ -20,7 +20,7 @@
--padding-start: #{$item-md-padding-start};
--inner-padding-end: #{$item-md-padding-end};
--inner-border-width: #{0 0 $item-md-border-bottom-width 0};
--highlight-height: 2px;
--highlight-height: 1px;
--highlight-color-focused: #{$item-md-input-highlight-color};
--highlight-color-valid: #{$item-md-input-highlight-color-valid};
--highlight-color-invalid: #{$item-md-input-highlight-color-invalid};
@@ -31,6 +31,67 @@
text-transform: none;
}
:host(.item-fill-outline) {
--highlight-height: 2px;
}
// Item Fill: None
// --------------------------------------------------
:host(.item-fill-none.item-interactive.ion-focus) .item-highlight,
:host(.item-fill-none.item-interactive.item-has-focus) .item-highlight,
:host(.item-fill-none.item-interactive.ion-touched.ion-invalid) .item-highlight {
transform: scaleX(1);
border-width: 0 0 var(--full-highlight-height) 0;
border-style: var(--border-style);
border-color: var(--highlight-background);
}
:host(.item-fill-none.item-interactive.ion-focus) .item-native,
:host(.item-fill-none.item-interactive.item-has-focus) .item-native,
:host(.item-fill-none.item-interactive.ion-touched.ion-invalid) .item-native {
border-bottom-color: var(--highlight-background);
}
// Item Fill: Outline
// --------------------------------------------------
:host(.item-fill-outline.item-interactive.ion-focus) .item-highlight,
:host(.item-fill-outline.item-interactive.item-has-focus) .item-highlight {
transform: scaleX(1);
}
:host(.item-fill-outline.item-interactive.ion-focus) .item-highlight,
:host(.item-fill-outline.item-interactive.item-has-focus) .item-highlight,
:host(.item-fill-outline.item-interactive.ion-touched.ion-invalid) .item-highlight {
border-width: var(--full-highlight-height);
border-style: var(--border-style);
border-color: var(--highlight-background);
}
:host(.item-fill-outline.item-interactive.ion-touched.ion-invalid) .item-native {
border-color: var(--highlight-background);
}
// Item Fill: Solid
// --------------------------------------------------
:host(.item-fill-solid.item-interactive.ion-focus) .item-highlight,
:host(.item-fill-solid.item-interactive.item-has-focus) .item-highlight,
:host(.item-fill-solid.item-interactive.ion-touched.ion-invalid) .item-highlight {
transform: scaleX(1);
border-width: 0 0 var(--full-highlight-height) 0;
border-style: var(--border-style);
border-color: var(--highlight-background);
}
:host(.item-fill-solid.item-interactive.ion-focus) .item-native,
:host(.item-fill-solid.item-interactive.item-has-focus) .item-native,
:host(.item-fill-solid.item-interactive.ion-touched.ion-invalid) .item-native {
border-bottom-color: var(--highlight-background);
}
// Material Design Item: States
// --------------------------------------------------
@@ -329,7 +390,6 @@
:host(.item-fill-solid.ion-color),
:host(.item-fill-outline.ion-color) {
--highlight-background: #{current-color(base)};
--highlight-color-focused: #{current-color(base)};
}
@@ -353,8 +413,6 @@
:host(.item-fill-solid.ion-focused) .item-native,
:host(.item-fill-solid.item-has-focus) .item-native {
--background: var(--background-focused);
border-bottom-color: var(--highlight-color-focused);
}
:host(.item-fill-solid.item-shape-round) {
@@ -413,21 +471,3 @@
--border-color: #{$item-md-input-fill-border-color-hover};
}
}
// Material Design Item: Invalid
// --------------------------------------------------
:host(.item-fill-outline.ion-invalid:not(.ion-color)) .item-native,
:host(.item-fill-solid.ion-invalid:not(.ion-color)) .item-native {
caret-color: var(--highlight-color-invalid);
}
:host(.item-fill-outline.ion-invalid),
:host(.item-fill-outline.ion-invalid) .item-native,
:host(.item-fill-outline.ion-invalid:not(.ion-color)) .item-highlight,
:host(.item-fill-solid.ion-invalid:not(.ion-color)),
:host(.item-fill-solid.ion-invalid:not(.ion-color)) .item-native,
:host(.item-fill-solid.ion-invalid:not(.ion-color)) .item-highlight {
border-color: var(--highlight-color-invalid);
}

View File

@@ -375,45 +375,10 @@ button, a {
pointer-events: none;
}
:host(.ion-focused) .item-highlight,
:host(.ion-focused) .item-inner-highlight,
:host(.item-has-focus) .item-highlight,
:host(.item-has-focus) .item-inner-highlight {
transform: scaleX(1);
border-style: var(--border-style);
border-color: var(--highlight-background);
:host(.item-interactive.item-has-focus) .item-native {
caret-color: var(--highlight-background);
}
:host(.ion-focused) .item-highlight,
:host(.item-has-focus) .item-highlight {
border-width: var(--full-highlight-height);
opacity: var(--show-full-highlight);
}
:host(.ion-focused) .item-inner-highlight,
:host(.item-has-focus) .item-inner-highlight {
border-bottom-width: var(--inset-highlight-height);
opacity: var(--show-inset-highlight);
}
:host(.ion-focused.item-fill-solid) .item-highlight,
:host(.item-has-focus.item-fill-solid) .item-highlight {
border-width: calc(var(--full-highlight-height) - 1px);
}
:host(.ion-focused) .item-inner-highlight,
:host(.ion-focused:not(.item-fill-outline)) .item-highlight,
:host(.item-has-focus) .item-inner-highlight,
:host(.item-has-focus:not(.item-fill-outline)) .item-highlight {
border-top: none;
border-right: none;
border-left: none;
}
// Item Input Focused
// --------------------------------------------------

View File

@@ -324,7 +324,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
Object.assign(childStyles, value);
});
const ariaDisabled = (disabled || childStyles['item-interactive-disabled']) ? 'true' : null;
const fillValue = fill || 'none';
return (
<Host
aria-disabled={ariaDisabled}
@@ -335,7 +335,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
'item': true,
[mode]: true,
[`item-lines-${lines}`]: lines !== undefined,
[`item-fill-${fill}`]: fill !== undefined,
[`item-fill-${fillValue}`]: true,
[`item-shape-${shape}`]: shape !== undefined,
'item-disabled': disabled,
'in-list': hostContext('ion-list', this.el),

View File

@@ -0,0 +1,10 @@
import { newE2EPage } from '@stencil/core/testing';
test('item: form', async () => {
const page = await newE2EPage({
url: '/src/components/item/test/form?ionic:_testing=true'
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});

View File

@@ -0,0 +1,302 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Item - Form</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<style>
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(250px, 1fr));
grid-row-gap: 20px;
grid-column-gap: 20px;
}
h2 {
font-size: 12px;
font-weight: normal;
color: #6f7378;
margin-top: 10px;
margin-left: 5px;
}
</style>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Item - Form</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<div class="grid">
<div class="grid-item">
<h2>No fill, Invalid, untouched</h2>
<ion-item class="ion-invalid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>No fill, Invalid, untouched, focused</h2>
<ion-item class="ion-invalid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>No fill, Invalid, touched</h2>
<ion-item class="ion-invalid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>No fill, Valid, untouched</h2>
<ion-item class="ion-valid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>No fill, Valid, untouched, focused</h2>
<ion-item class="ion-valid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>No fill, Valid, touched</h2>
<ion-item class="ion-valid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Outline, Invalid, untouched</h2>
<ion-item fill="outline" class="ion-invalid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Outline, Invalid, untouched, focused</h2>
<ion-item fill="outline" class="ion-invalid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Outline, Invalid, touched</h2>
<ion-item fill="outline" class="ion-invalid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Outline, Valid, untouched</h2>
<ion-item fill="outline" class="ion-valid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Outline, Valid, untouched, focused</h2>
<ion-item fill="outline" class="ion-valid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Outline, Valid, touched</h2>
<ion-item fill="outline" class="ion-valid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Solid, Invalid, untouched</h2>
<ion-item fill="solid" class="ion-invalid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Solid, Invalid, untouched, focused</h2>
<ion-item fill="solid" class="ion-invalid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Solid, Invalid, touched</h2>
<ion-item fill="solid" class="ion-invalid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Solid, Valid, untouched</h2>
<ion-item fill="solid" class="ion-valid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Solid, Valid, untouched, focused</h2>
<ion-item fill="solid" class="ion-valid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Solid, Valid, touched</h2>
<ion-item fill="solid" class="ion-valid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
</div>
<div class="grid">
<div class="grid-item">
<h2>Color, No fill, Invalid, untouched</h2>
<ion-item color="primary" class="ion-invalid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, No fill, Invalid, untouched, focused</h2>
<ion-item color="primary" class="ion-invalid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, No fill, Invalid, touched</h2>
<ion-item color="primary" class="ion-invalid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, No fill, Valid, untouched</h2>
<ion-item color="primary" class="ion-valid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, No fill, Valid, untouched, focused</h2>
<ion-item color="primary" class="ion-valid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, No fill, Valid, touched</h2>
<ion-item color="primary" class="ion-valid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Outline, Invalid, untouched</h2>
<ion-item color="primary" fill="outline" class="ion-invalid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Outline, Invalid, untouched, focused</h2>
<ion-item color="primary" fill="outline" class="ion-invalid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Outline, Invalid, touched</h2>
<ion-item color="primary" fill="outline" class="ion-invalid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Outline, Valid, untouched</h2>
<ion-item color="primary" fill="outline" class="ion-valid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Outline, Valid, untouched, focused</h2>
<ion-item color="primary" fill="outline" class="ion-valid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Outline, Valid, touched</h2>
<ion-item color="primary" fill="outline" class="ion-valid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Solid, Invalid, untouched</h2>
<ion-item color="primary" fill="solid" class="ion-invalid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Solid, Invalid, untouched, focused</h2>
<ion-item color="primary" fill="solid" class="ion-invalid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Solid, Invalid, touched</h2>
<ion-item color="primary" fill="solid" class="ion-invalid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Solid, Valid, untouched</h2>
<ion-item color="primary" fill="solid" class="ion-valid ion-untouched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Solid, Valid, untouched, focused</h2>
<ion-item color="primary" fill="solid" class="ion-valid ion-untouched item-has-focus">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
<div class="grid-item">
<h2>Color, Solid, Valid, touched</h2>
<ion-item color="primary" fill="solid" class="ion-valid ion-touched">
<ion-input placeholder="Text"></ion-input>
</ion-item>
</div>
</div>
</ion-content>
</ion-app>
</body>
</html>