refactor(item): remove deprecated highlight variables used with legacy form controls (#29055)

Issue number: internal

---------

## What is the current behavior?

In Ionic Framework v7, we [simplified the form control
syntax](https://ionic.io/blog/ionic-7-is-here#simplified-form-control-syntax),
eliminating the requirement to place form controls inside of an
`ion-item`. We ensured backwards compatibility by introducing a `legacy`
property for the form controls and keeping, but deprecating, the
following CSS variables on item:

```css
--highlight-color-focused
--highlight-color-invalid
--highlight-color-valid
--highlight-height
```

While this was supported in v7, console warnings were logged to notify
developers that they needed to update to the modern syntax if they were
using form controls in an item for the best accessibility experience.

## What is the new behavior?

Removes the `--highlight-color-focused`, `--highlight-color-invalid`,
`--highlight-color-valid`, and `--highlight-height` variables from item.

## Does this introduce a breaking change?

- [x] Yes
- [ ] No

Steps taken to mitigate this breaking change: 
1. Developers have had console warnings when using the legacy syntax
since the v7 release and the variables were marked as `deprecated`.
2. The removal of these CSS variables has been documented in the
Breaking Changes document with a link to the migration guides for the
affected form controls.

BREAKING CHANGE:

The following CSS variables have been removed from item:
`--highlight-height`, `--highlight-color-focused`,
`--highlight-color-valid`, and `--highlight-color-invalid`. These
variables were used on the bottom border highlight of an item when the
form control inside of that item was focused. The form control syntax
was [simplified in
v7](https://ionic.io/blog/ionic-7-is-here#simplified-form-control-syntax)
so that inputs, selects, and textareas would no longer be required to be
used inside of an item.

If you have not yet migrated to the modern form control syntax,
migration guides for each of the form controls that added a highlight to
item can be found below:
- [Input migration
documentation](https://ionicframework.com/docs/api/input#migrating-from-legacy-input-syntax)
- [Select migration
documentation](https://ionicframework.com/docs/api/select#migrating-from-legacy-select-syntax)
- [Textarea migration
documentation](https://ionicframework.com/docs/api/textarea#migrating-from-legacy-textarea-syntax)

The highlight variables should then be moved from the item to the form
control:

```diff
- ion-item {
+ ion-input,
+ ion-textarea,
+ ion-select {
  --highlight-color-focused: purple;
  --highlight-color-valid: blue;
  --highlight-color-invalid: orange;
  --highlight-height: 6px;
}
```

> [!NOTE]
> The input and textarea components are scoped, which means they will
automatically scope their CSS by appending each of the styles with an
additional class at runtime. Overriding scoped selectors in CSS requires
a [higher
specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity)
selector. Targeting the `ion-input` or `ion-textarea` for customization
will not work; therefore we recommend adding a class and customizing it
that way.

---------

Co-authored-by: Sean Perkins <sean@ionic.io>
This commit is contained in:
Brandy Carney
2024-03-11 17:29:47 -04:00
committed by GitHub
parent 03d26702f6
commit d53fb297e7
10 changed files with 54 additions and 211 deletions

View File

@ -29,10 +29,6 @@
--background-hover-opacity: .04;
--border-color: #{$item-ios-border-bottom-color};
--color: #{$item-ios-color};
--highlight-height: 0px;
--highlight-color-focused: #{$item-ios-input-highlight-color};
--highlight-color-valid: #{$item-ios-input-highlight-color-valid};
--highlight-color-invalid: #{$item-ios-input-highlight-color-invalid};
font-size: $item-ios-font-size;
}
@ -63,24 +59,15 @@
// iOS Item Lines
// --------------------------------------------------
// Default input items have an inset border
:host(.item-interactive) {
--show-full-highlight: 0;
--show-inset-highlight: 1;
}
// Full lines - apply the border to the item
// Inset lines - apply the border to the item inner
:host(.item-lines-full) {
--border-width: #{0px 0px $item-ios-border-bottom-width 0px};
--show-full-highlight: 1;
--show-inset-highlight: 0;
}
:host(.item-lines-inset) {
--inner-border-width: #{0px 0px $item-ios-border-bottom-width 0px};
--show-full-highlight: 0;
--show-inset-highlight: 1;
}
// Full lines - remove the border from the item inner (inset list items)
@ -89,28 +76,13 @@
:host(.item-lines-inset),
:host(.item-lines-none) {
--border-width: 0px;
--show-full-highlight: 0;
}
:host(.item-lines-full),
:host(.item-lines-none) {
--inner-border-width: 0px;
--show-inset-highlight: 0;
}
.item-highlight,
.item-inner-highlight {
transition: none;
}
:host(.item-has-focus) .item-inner-highlight,
:host(.item-has-focus) .item-highlight {
border-top: none;
border-right: none;
border-left: none;
}
// iOS Item Slots
// --------------------------------------------------

View File

@ -57,15 +57,6 @@ $item-ios-border-bottom-style: solid !default;
/// @prop - Border bottom color for the item when lines are displayed
$item-ios-border-bottom-color: $item-ios-border-color !default;
/// @prop - Color of the item input highlight
$item-ios-input-highlight-color: ion-color(primary, base) !default;
/// @prop - Color of the item input highlight when valid
$item-ios-input-highlight-color-valid: ion-color(success, base) !default;
/// @prop - Color of the item input highlight when invalid
$item-ios-input-highlight-color-invalid: ion-color(danger, base) !default;
// Item Slots
// --------------------------------------------------

View File

@ -21,10 +21,6 @@
--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: 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};
font-size: dynamic-font($item-md-font-size);
font-weight: normal;
@ -41,10 +37,6 @@
}
}
:host(.item-has-focus) .item-native {
caret-color: var(--highlight-background);
}
// Material Design Item Lines
// --------------------------------------------------
@ -52,22 +44,16 @@
:host(.item-interactive) {
--border-width: #{0 0 $item-md-border-bottom-width 0};
--inner-border-width: 0;
--show-full-highlight: 1;
--show-inset-highlight: 0;
}
// Full lines - apply the border to the item
// Inset lines - apply the border to the item inner
:host(.item-lines-full) {
--border-width: #{0 0 $item-md-border-bottom-width 0};
--show-full-highlight: 1;
--show-inset-highlight: 0;
}
:host(.item-lines-inset) {
--inner-border-width: #{0 0 $item-md-border-bottom-width 0};
--show-full-highlight: 0;
--show-inset-highlight: 1;
}
// Full lines - remove the border from the item inner (inset list items)
@ -76,13 +62,11 @@
:host(.item-lines-inset),
:host(.item-lines-none) {
--border-width: 0;
--show-full-highlight: 0;
}
:host(.item-lines-full),
:host(.item-lines-none) {
--inner-border-width: 0;
--show-inset-highlight: 0;
}
// Material Design Multi-line Item
@ -247,14 +231,3 @@
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-floating) {
color: $label-md-text-color-focused;
}
// Material Design Inputs: Highlight Color
// --------------------------------------------------
:host(.ion-color) {
--highlight-color-focused: #{current-color(contrast)};
}
:host(.item-label-color) {
--highlight-color-focused: #{current-color(base)};
}

View File

@ -42,18 +42,6 @@ $item-md-border-bottom-style: solid !default;
/// @prop - Border bottom color for the item when lines are displayed
$item-md-border-bottom-color: $item-md-border-color !default;
// Item Input
// --------------------------------------------------
/// @prop - Color of the item input highlight
$item-md-input-highlight-color: ion-color(primary, base) !default;
/// @prop - Color of the item input highlight when valid
$item-md-input-highlight-color-valid: ion-color(success, base) !default;
/// @prop - Color of the item input highlight when invalid
$item-md-input-highlight-color-invalid: ion-color(danger, base) !default;
// Item Label
// --------------------------------------------------

View File

@ -2,7 +2,6 @@
// Item
// --------------------------------------------------
// TODO: FW-4955
:host {
/**
@ -46,10 +45,6 @@
*
* @prop --ripple-color: Color of the item ripple effect
*
* @prop --highlight-height: The height of the highlight on the item. Only applies to inputs and textareas using the legacy form syntax. DEPRECATED: Highlights can be styled on `ion-input` or `ion-textarea` when using the modern form syntax.
* @prop --highlight-color-focused: The color of the highlight on the item when focused. Only applies to inputs and textareas using the legacy form syntax. DEPRECATED: Highlights can be styled on `ion-input` or `ion-textarea` when using the modern form syntax.
* @prop --highlight-color-valid: The color of the highlight on the item when valid. Only applies to inputs and textareas using the legacy form syntax. DEPRECATED: Highlights can be styled on `ion-input` or `ion-textarea` when using the modern form syntax.
* @prop --highlight-color-invalid: The color of the highlight on the item when invalid. Only applies to inputs and textareas using the legacy form syntax. DEPRECATED: Highlights can be styled on `ion-input` or `ion-textarea` when using the modern form syntax.
*/
--border-radius: 0px;
--border-width: 0px;
@ -64,8 +59,6 @@
--inner-padding-start: 0px;
--inner-padding-end: 0px;
--inner-box-shadow: none;
--show-full-highlight: 0;
--show-inset-highlight: 0;
--detail-icon-color: initial;
--detail-icon-font-size: 1.25em;
--detail-icon-opacity: 0.25;
@ -109,7 +102,6 @@
border-color: current-color(shade);
}
// Item: Activated
// --------------------------------------------------
@ -127,7 +119,6 @@
color: current-color(contrast);
}
// Item: Focused
// --------------------------------------------------
@ -149,7 +140,6 @@
}
}
// Item: Hover
// --------------------------------------------------
@ -181,7 +171,6 @@
cursor: pointer;
}
// Item: Disabled
// --------------------------------------------------
@ -192,12 +181,10 @@
:host(.item-disabled) {
cursor: default;
opacity: .3;
opacity: 0.3;
pointer-events: none;
}
// Native Item
// --------------------------------------------------
@ -257,14 +244,14 @@
z-index: -1;
}
button, a {
button,
a {
cursor: pointer;
user-select: none;
-webkit-user-drag: none;
}
// Inner Item
// --------------------------------------------------
@ -328,7 +315,6 @@ button, a {
opacity: var(--detail-icon-opacity);
}
// Item Slots
// --------------------------------------------------
@ -398,98 +384,6 @@ button, a {
flex-direction: column;
}
// Item Input Highlight
// --------------------------------------------------
.item-highlight,
.item-inner-highlight {
@include position(0, 0, 0, 0);
@include border-radius(inherit);
position: absolute;
width: 100%;
height: 100%;
transform: scaleX(0);
transition: transform 200ms, border-bottom-width 200ms;
z-index: 2;
box-sizing: border-box;
pointer-events: none;
}
// Item Input Focused
// --------------------------------------------------
:host(.item-interactive.ion-focused),
:host(.item-interactive.item-has-focus),
:host(.item-interactive.ion-touched.ion-invalid) {
// If the item has a full border and highlight is enabled, show the full item highlight
--full-highlight-height: #{calc(var(--highlight-height) * var(--show-full-highlight))};
// If the item has an inset border and highlight is enabled, show the inset item highlight
--inset-highlight-height: #{calc(var(--highlight-height) * var(--show-inset-highlight))};
}
: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(.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-inner-highlight,
:host(.ion-focused) .item-highlight,
:host(.item-has-focus) .item-inner-highlight,
:host(.item-has-focus) .item-highlight {
border-top: none;
border-right: none;
border-left: none;
}
// Item Input Focus
// --------------------------------------------------
:host(.item-interactive.ion-focused),
:host(.item-interactive.item-has-focus) {
--highlight-background: var(--highlight-color-focused);
}
// Item Input Valid
// --------------------------------------------------
:host(.item-interactive.ion-valid) {
--highlight-background: var(--highlight-color-valid);
}
// Item Input Invalid
// --------------------------------------------------
:host(.item-interactive.ion-invalid) {
--highlight-background: var(--highlight-color-invalid);
}
// Item w/ Multiple Inputs
// --------------------------------------------------
// Multiple inputs in an item should have the input
@ -508,7 +402,6 @@ button, a {
align-items: stretch;
}
// Item Reorder
// --------------------------------------------------
@ -516,7 +409,6 @@ button, a {
@include margin(0, null);
}
// Item Button Ripple effect
// --------------------------------------------------
@ -524,12 +416,3 @@ ion-ripple-effect {
color: var(--ripple-color);
}
// Item: Reduced Motion
// --------------------------------------------------
@media (prefers-reduced-motion: reduce) {
.item-highlight,
.item-inner-highlight {
transition: none;
}
}

View File

@ -374,10 +374,8 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
flip-rtl={detailIcon === chevronForward}
></ion-icon>
)}
<div class="item-inner-highlight"></div>
</div>
{canActivate && mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
<div class="item-highlight"></div>
</TagType>
</Host>
);

View File

@ -137,7 +137,6 @@
<style>
.overflow-visible {
--highlight-color-focused: transparent;
--border-color: red;
overflow: visible;

View File

@ -16,7 +16,7 @@ describe('item', () => {
await page.waitForChanges();
// Check if it has the expected class that gives the highlight style to .item-highlight element
// Check if it has the expected class that gives the focused styles to the item element
expect(item).toHaveClass('ion-focusable');
});
});