feat(input,textarea,select): add --highlight-height variable (#29090)

Issue number: Internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

In v7, using the legacy syntax, the height of the highlight on an item
could be adjusted using the `--highlight-height` variable. This variable
was not added to input and therefore would not work using the modern
syntax.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

Adds the `--highlight-height` variable to `ion-input`, `ion-textarea`
and `ion-select` so that developers can customize this height in `md`
mode. Since the highlight element is not added for `ios` mode, this
variable won't do anything for `ios`. Note that this diverges from the
v7 behavior, where setting `--highlight-height` enabled the highlight
for `ios`. A design document outlining this has been proposed here:
https://github.com/ionic-team/ionic-framework-design-documents/pull/252

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#footer
for more information.
-->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

---------

Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
This commit is contained in:
Sean Perkins
2024-03-08 20:55:34 +00:00
committed by GitHub
parent 2956317a55
commit 13b7f8ac3a
64 changed files with 808 additions and 10 deletions

View File

@ -4,6 +4,10 @@
// iOS Select
// --------------------------------------------------
:host {
--highlight-height: 0px;
}
.select-icon {
width: $select-ios-icon-size;
height: $select-ios-icon-size;

View File

@ -44,7 +44,7 @@
*/
:host(.select-fill-outline.select-expanded),
:host(.select-fill-outline.ion-focused) {
--border-width: 2px;
--border-width: var(--highlight-height);
--border-color: var(--highlight-color);
}

View File

@ -9,6 +9,7 @@
:host {
--border-width: 1px;
--border-color: #{$item-md-border-color};
--highlight-height: 2px;
}
.select-icon {
@ -50,7 +51,7 @@
position: absolute;
width: 100%;
height: 2px;
height: var(--highlight-height);
transform: scale(0);

View File

@ -14,6 +14,7 @@
* @prop --placeholder-color: Color of the select placeholder text
* @prop --placeholder-opacity: Opacity of the select placeholder text
*
* @prop --highlight-height: The height of the highlight on the select. Only applies to md mode.
* @prop --highlight-color-focused: The color of the highlight on the select when focused
* @prop --highlight-color-invalid: The color of the highlight on the select when invalid
* @prop --highlight-color-valid: The color of the highlight on the select when valid

View File

@ -33,6 +33,13 @@
padding: 0;
}
}
.custom {
--highlight-color-focused: purple;
--highlight-color-invalid: purple;
--highlight-color-valid: purple;
--highlight-height: 6px;
}
</style>
</head>
@ -117,6 +124,30 @@
</div>
</div>
<h1>No Fill, Custom</h1>
<div class="grid">
<div class="grid-item">
<h2>Focus</h2>
<ion-select label-placement="start" value="hi@ionic.io" class="custom ion-focused" label="Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
<div class="grid-item">
<h2>Valid, Focus</h2>
<ion-select label-placement="start" class="custom ion-valid ion-focused" label="Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
<div class="grid-item">
<h2>Invalid</h2>
<ion-select label-placement="start" class="custom ion-touched ion-invalid" label="Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
</div>
<h1>Solid, Default</h1>
<div class="grid">
<div class="grid-item">
@ -189,6 +220,36 @@
</div>
</div>
<h1>Solid, Custom</h1>
<div class="grid">
<div class="grid-item">
<h2>Focus</h2>
<ion-select
fill="solid"
label-placement="start"
value="hi@ionic.io"
class="custom ion-focused"
label="Fruit"
>
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
<div class="grid-item">
<h2>Valid, Focus</h2>
<ion-select fill="solid" label-placement="start" class="custom ion-valid ion-focused" label="Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
<div class="grid-item">
<h2>Invalid</h2>
<ion-select fill="solid" label-placement="start" class="custom ion-touched ion-invalid" label="Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
</div>
<h1>Outline, Default</h1>
<div class="grid">
<div class="grid-item">
@ -260,6 +321,36 @@
</ion-select>
</div>
</div>
<h1>Outline, Custom</h1>
<div class="grid">
<div class="grid-item">
<h2>Focus</h2>
<ion-select
fill="outline"
label-placement="start"
value="hi@ionic.io"
class="custom ion-focused"
label="Fruit"
>
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
<div class="grid-item">
<h2>Valid, Focus</h2>
<ion-select fill="outline" label-placement="start" class="custom ion-valid ion-focused" label="Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
<div class="grid-item">
<h2>Invalid</h2>
<ion-select fill="outline" label-placement="start" class="custom ion-touched ion-invalid" label="Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
</div>
</ion-content>
</ion-app>
</body>

View File

@ -2,8 +2,8 @@ import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('input: highlights'), () => {
test.describe('input: no fill', () => {
test.describe(title('select: highlights'), () => {
test.describe('select: no fill', () => {
test('should render valid state correctly', async ({ page }) => {
await page.setContent(
`
@ -43,8 +43,40 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
const select = page.locator('ion-select');
await expect(select).toHaveScreenshot(screenshot(`select-no-fill-focus`));
});
test('should render custom highlight correctly', async ({ page }) => {
await page.setContent(
`
<style>
ion-select.custom {
--highlight-color-focused: red;
--highlight-color-invalid: blue;
--highlight-color-valid: purple;
--highlight-height: 6px;
}
</style>
<div class="container">
<ion-select value="apple" class="custom ion-valid ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
<ion-select value="apple" class="custom ion-touched ion-invalid ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
<ion-select value="apple" class="custom ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
`,
config
);
const container = page.locator('.container');
await expect(container).toHaveScreenshot(screenshot(`select-no-fill-custom-highlight`));
});
});
test.describe('input: solid', () => {
test.describe('select: solid', () => {
test('should render valid state correctly', async ({ page }) => {
await page.setContent(
`
@ -84,8 +116,40 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
const select = page.locator('ion-select');
await expect(select).toHaveScreenshot(screenshot(`select-solid-focus`));
});
test('should render custom highlight correctly', async ({ page }) => {
await page.setContent(
`
<style>
ion-select.custom {
--highlight-color-focused: red;
--highlight-color-invalid: blue;
--highlight-color-valid: purple;
--highlight-height: 6px;
}
</style>
<div class="container">
<ion-select fill="solid" value="apple" class="custom ion-valid ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
<ion-select fill="solid" value="apple" class="custom ion-touched ion-invalid ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
<ion-select fill="solid" value="apple" class="custom ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
`,
config
);
const container = page.locator('.container');
await expect(container).toHaveScreenshot(screenshot(`select-solid-custom-highlight`));
});
});
test.describe('input: outline', () => {
test.describe('select: outline', () => {
test('should render valid state correctly', async ({ page }) => {
await page.setContent(
`
@ -125,6 +189,38 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
const select = page.locator('ion-select');
await expect(select).toHaveScreenshot(screenshot(`select-outline-focus`));
});
test('should render custom highlight correctly', async ({ page }) => {
await page.setContent(
`
<style>
ion-select.custom {
--highlight-color-focused: red;
--highlight-color-invalid: blue;
--highlight-color-valid: purple;
--highlight-height: 6px;
}
</style>
<div class="container">
<ion-select fill="outline" value="apple" class="custom ion-valid ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
<ion-select fill="outline" value="apple" class="custom ion-touched ion-invalid ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
<ion-select fill="outline" value="apple" class="custom ion-focused" label="Favorite Fruit">
<ion-select-option value="apple">Apple</ion-select-option>
</ion-select>
</div>
`,
config
);
const container = page.locator('.container');
await expect(container).toHaveScreenshot(screenshot(`select-outline-custom-highlight`));
});
});
});