fix(input): match valid state to ionic design (#29277)
Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com> Co-authored-by: ionitron <hi@ionicframework.com>
@ -20,6 +20,16 @@
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
:host(.input-fill-outline.input-shape-round) .input-bottom,
|
||||
:host(.input-fill-outline.input-label-placement-floating) .input-bottom {
|
||||
/**
|
||||
* The bottom content should take on the start and end
|
||||
* padding so it is always aligned with either the label
|
||||
* or the start of the text input.
|
||||
*/
|
||||
@include padding-horizontal(var(--padding-start), var(--padding-end));
|
||||
}
|
||||
|
||||
:host(.input-fill-outline) .input-wrapper {
|
||||
/**
|
||||
* For the ionic theme, the padding needs to sit on the
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
:host {
|
||||
--border-width: #{$ionic-border-size-small};
|
||||
--border-color: #{$ionic-color-neutral-300};
|
||||
--highlight-color-valid: #{$ionic-color-success-400};
|
||||
--highlight-color-invalid: #{$ionic-color-error-400};
|
||||
--text-color-invalid: #{$ionic-color-error-600};
|
||||
}
|
||||
@ -20,6 +21,16 @@
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
// Input Bottom Content
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
.input-bottom {
|
||||
@include padding-horizontal(0, 0);
|
||||
|
||||
// TODO(FW-6112): Update it to `$ionic-font-weight-medium` when it's available
|
||||
font-weight: var(--ionic-font-weight-medium, 500);
|
||||
}
|
||||
|
||||
// Input Hint Text
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
@ -27,6 +38,10 @@
|
||||
color: tokens.$ionic-color-neutral-600;
|
||||
}
|
||||
|
||||
:host(.has-focus.ion-valid) .helper-text {
|
||||
color: #{tokens.$ionic-color-success-800};
|
||||
}
|
||||
|
||||
:host(.ion-touched.ion-invalid) .error-text {
|
||||
color: var(--text-color-invalid);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 978 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 922 B After Width: | Height: | Size: 927 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 935 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 887 B After Width: | Height: | Size: 892 B |
|
Before Width: | Height: | Size: 990 B After Width: | Height: | Size: 973 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 918 B |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.4 KiB |
@ -348,6 +348,25 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('input: highlights'), () => {
|
||||
test.describe('input: no fill', () => {
|
||||
test('should render valid state correctly', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-input
|
||||
value="hi@ionic.io"
|
||||
class="ion-valid has-focus"
|
||||
label="Email"
|
||||
error-text="Please enter a valid email"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
></ion-input>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const input = page.locator('ion-input');
|
||||
await expect(input).toHaveScreenshot(screenshot(`input-no-fill-valid`));
|
||||
});
|
||||
test('should render invalid state correctly', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
@ -369,6 +388,26 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screensh
|
||||
});
|
||||
});
|
||||
test.describe('input: outline', () => {
|
||||
test('should render valid state correctly', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-input
|
||||
fill="outline"
|
||||
value="hi@ionic.io"
|
||||
class="ion-valid has-focus"
|
||||
label="Email"
|
||||
error-text="Please enter a valid email"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
></ion-input>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const input = page.locator('ion-input');
|
||||
await expect(input).toHaveScreenshot(screenshot(`input-outline-valid`));
|
||||
});
|
||||
test('should render invalid state correctly', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
@ -389,6 +428,34 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screensh
|
||||
const input = page.locator('ion-input');
|
||||
await expect(input).toHaveScreenshot(screenshot(`input-outline-invalid`));
|
||||
});
|
||||
test('should render custom highlight correctly', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<style>
|
||||
ion-input.custom {
|
||||
--highlight-color-valid: purple;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<ion-input
|
||||
fill="outline"
|
||||
value="hi@ionic.io"
|
||||
class="custom has-focus ion-valid"
|
||||
label="Email"
|
||||
error-text="Please enter a valid email"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
></ion-input>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const container = page.locator('.container');
|
||||
await expect(container).toHaveScreenshot(screenshot(`input-outline-custom-highlight`));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 3.4 KiB |