refactor(item): remove deprecated apis (#29102)
BREAKING CHANGE: - The `helper` slot has been removed. Developers should use the `helperText` property on `ion-input` and `ion-textarea`. - The `error` slot has been removed. Developers should use the `errorText` property on `ion-input` and `ion-textarea`. - Counter functionality has been removed including the `counter` and `counterFormatter` properties. Developers should use the properties of the same name on `ion-input` and `ion-textarea`. - The `fill` property has been removed. Developers should use the property of the same name on `ion-input`, `ion-select`, and `ion-textarea`. - The `shape` property has been removed. Developers should use the property of the same name on `ion-input`, `ion-select`, and `ion-textarea`.
@ -33,7 +33,6 @@
|
||||
--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};
|
||||
--bottom-padding-start: 0px;
|
||||
|
||||
font-size: $item-ios-font-size;
|
||||
}
|
||||
@ -149,7 +148,6 @@
|
||||
@include margin($item-ios-label-slot-end-margin-top, $item-ios-label-slot-end-margin-end, $item-ios-label-slot-end-margin-bottom, $item-ios-label-slot-end-margin-start);
|
||||
}
|
||||
|
||||
|
||||
// iOS Item Button
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -204,7 +202,6 @@
|
||||
@include margin(10px, 8px, 10px, 0);
|
||||
}
|
||||
|
||||
|
||||
// iOS Stacked & Floating Inputs
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -212,10 +209,3 @@
|
||||
:host(.item-label-stacked) {
|
||||
--min-height: 68px;
|
||||
}
|
||||
|
||||
// iOS Fixed Labels
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.item-label-fixed) ::slotted(ion-datetime) {
|
||||
--padding-start: 0;
|
||||
}
|
||||
|
||||
@ -32,68 +32,6 @@
|
||||
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
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -147,25 +85,6 @@
|
||||
--show-inset-highlight: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* When `fill="outline"`, reposition the highlight element to cover everything but the `.item-bottom`
|
||||
*/
|
||||
:host(.item-fill-outline) .item-highlight {
|
||||
--position-offset: calc(-1 * var(--border-width));
|
||||
|
||||
@include position(var(--position-offset), null, null, var(--position-offset));
|
||||
|
||||
width: calc(100% + 2 * var(--border-width));
|
||||
height: calc(100% + 2 * var(--border-width));
|
||||
|
||||
transition: none;
|
||||
}
|
||||
|
||||
:host(.item-fill-outline.ion-focused) .item-native,
|
||||
:host(.item-fill-outline.item-has-focus) .item-native {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
// Material Design Multi-line Item
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -188,14 +107,6 @@
|
||||
@include margin-horizontal($item-md-end-slot-margin-start, $item-md-end-slot-margin-end);
|
||||
}
|
||||
|
||||
:host(.item-fill-solid) ::slotted([slot="start"]),
|
||||
:host(.item-fill-solid) ::slotted([slot="end"]),
|
||||
:host(.item-fill-outline) ::slotted([slot="start"]),
|
||||
:host(.item-fill-outline) ::slotted([slot="end"]) {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
|
||||
// Material Design Slotted Icon
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -211,7 +122,7 @@
|
||||
font-size: math.div($item-md-icon-slot-font-size, $item-md-font-size) * 1em;
|
||||
}
|
||||
|
||||
:host(.ion-color:not(.item-fill-solid):not(.item-fill-outline)) ::slotted(ion-icon) {
|
||||
:host(.ion-color) ::slotted(ion-icon) {
|
||||
color: current-color(contrast);
|
||||
}
|
||||
|
||||
@ -227,12 +138,6 @@
|
||||
@include margin-horizontal($item-md-icon-end-slot-margin-start, $item-md-icon-end-slot-margin-end);
|
||||
}
|
||||
|
||||
:host(.item-fill-solid) ::slotted(ion-icon[slot="start"]),
|
||||
:host(.item-fill-outline) ::slotted(ion-icon[slot="start"]) {
|
||||
@include margin-horizontal($item-md-icon-start-slot-margin-start, $item-md-input-icon-start-slot-margin-end);
|
||||
}
|
||||
|
||||
|
||||
// Material Design Slotted Toggle
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -253,7 +158,7 @@
|
||||
font-size: $item-md-note-slot-font-size;
|
||||
}
|
||||
|
||||
::slotted(ion-note[slot]:not([slot="helper"]):not([slot="error"])) {
|
||||
::slotted(ion-note[slot]) {
|
||||
@include padding($item-md-note-slot-padding-top, $item-md-note-slot-padding-end, $item-md-note-slot-padding-bottom, $item-md-note-slot-padding-start);
|
||||
}
|
||||
|
||||
@ -298,7 +203,6 @@
|
||||
@include margin($item-md-label-margin-top, $item-md-label-margin-end, $item-md-label-margin-bottom, $item-md-label-margin-start);
|
||||
}
|
||||
|
||||
|
||||
// Material Design Floating/Stacked Label
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -307,15 +211,6 @@
|
||||
@include margin($item-md-label-slot-end-margin-top, $item-md-label-slot-end-margin-end, $item-md-label-slot-end-margin-bottom, $item-md-label-slot-end-margin-start);
|
||||
}
|
||||
|
||||
|
||||
// Material Design Fixed Labels
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.item-label-fixed) ::slotted(ion-datetime) {
|
||||
--padding-start: 8px;
|
||||
}
|
||||
|
||||
|
||||
// Material Design Toggle/Radio Item
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -324,7 +219,6 @@
|
||||
@include margin-horizontal(0, null);
|
||||
}
|
||||
|
||||
|
||||
// Material Design Item Button
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -339,15 +233,6 @@
|
||||
font-size: dynamic-font(12px);
|
||||
}
|
||||
|
||||
|
||||
// Material Design Radio Item Label: Checked
|
||||
// -----------------------------------------
|
||||
|
||||
// .item-radio-checked.item-md ion-label {
|
||||
// color: $radio-md-color-on;
|
||||
// }
|
||||
|
||||
|
||||
// Material Design Stacked & Floating Inputs
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -373,94 +258,3 @@
|
||||
:host(.item-label-color) {
|
||||
--highlight-color-focused: #{current-color(base)};
|
||||
}
|
||||
|
||||
:host(.item-fill-solid.ion-color),
|
||||
:host(.item-fill-outline.ion-color) {
|
||||
--highlight-color-focused: #{current-color(base)};
|
||||
}
|
||||
|
||||
// Material Design Item: Fill Solid
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.item-fill-solid) {
|
||||
--background: #{$item-md-input-fill-solid-background-color};
|
||||
--background-hover: #{$item-md-input-fill-solid-background-color-hover};
|
||||
--background-focused: #{$item-md-input-fill-solid-background-color-focus};
|
||||
--border-width: 0 0 #{$item-md-border-bottom-width} 0;
|
||||
--inner-border-width: 0;
|
||||
|
||||
@include border-radius(4px, 4px, 0, 0);
|
||||
}
|
||||
|
||||
:host(.item-fill-solid) .item-native {
|
||||
--border-color: #{$item-md-input-fill-border-color};
|
||||
}
|
||||
|
||||
:host(.item-fill-solid.ion-focused) .item-native,
|
||||
:host(.item-fill-solid.item-has-focus) .item-native {
|
||||
--background: var(--background-focused);
|
||||
}
|
||||
|
||||
:host(.item-fill-solid.item-shape-round) {
|
||||
@include border-radius(16px, 16px, 0, 0);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
:host(.item-fill-solid:hover) .item-native {
|
||||
--background: var(--background-hover);
|
||||
--border-color: #{$item-md-input-fill-border-color-hover};
|
||||
}
|
||||
}
|
||||
|
||||
// Material Design Item: Fill Outline
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.item-fill-outline) {
|
||||
--ripple-color: transparent;
|
||||
--background-focused: transparent;
|
||||
--background-hover: transparent;
|
||||
--border-color: #{$item-md-input-fill-border-color};
|
||||
--border-width: #{$item-md-border-bottom-width};
|
||||
|
||||
border: none;
|
||||
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
:host(.item-fill-outline) .item-native {
|
||||
--native-padding-left: 16px;
|
||||
|
||||
@include border-radius(4px);
|
||||
}
|
||||
|
||||
:host(.item-fill-outline.item-shape-round) .item-native {
|
||||
--inner-padding-start: 16px;
|
||||
|
||||
@include border-radius(28px);
|
||||
}
|
||||
|
||||
:host(.item-fill-outline.item-shape-round) .item-bottom {
|
||||
@include padding-horizontal(32px, null);
|
||||
}
|
||||
|
||||
:host(.item-fill-outline.item-label-floating.ion-focused) .item-native ::slotted(ion-input:not(:first-child)),
|
||||
:host(.item-fill-outline.item-label-floating.ion-focused) .item-native ::slotted(ion-textarea:not(:first-child)),
|
||||
:host(.item-fill-outline.item-label-floating.item-has-focus) .item-native ::slotted(ion-input:not(:first-child)),
|
||||
:host(.item-fill-outline.item-label-floating.item-has-focus) .item-native ::slotted(ion-textarea:not(:first-child)),
|
||||
:host(.item-fill-outline.item-label-floating.item-has-value) .item-native ::slotted(ion-input:not(:first-child)),
|
||||
:host(.item-fill-outline.item-label-floating.item-has-value) .item-native ::slotted(ion-textarea:not(:first-child)) {
|
||||
transform: translateY(-14px);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
:host(.item-fill-outline:hover) .item-native {
|
||||
--border-color: #{$item-md-input-fill-border-color-hover};
|
||||
}
|
||||
}
|
||||
|
||||
// Material Design Text Field Character Counter
|
||||
// --------------------------------------------------
|
||||
|
||||
.item-counter {
|
||||
letter-spacing: #{$item-md-input-counter-letter-spacing};
|
||||
}
|
||||
|
||||
@ -45,15 +45,6 @@ $item-md-border-bottom-color: $item-md-border-color !default;
|
||||
// Item Input
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Color of the item input background
|
||||
$item-md-input-fill-solid-background-color: $background-color-step-50 !default;
|
||||
|
||||
/// @prop - Color of the item input background when hovered
|
||||
$item-md-input-fill-solid-background-color-hover: $background-color-step-100 !default;
|
||||
|
||||
/// @prop - Color of the item input background when focused
|
||||
$item-md-input-fill-solid-background-color-focus: $background-color-step-150 !default;
|
||||
|
||||
/// @prop - Color of the item input highlight
|
||||
$item-md-input-highlight-color: ion-color(primary, base) !default;
|
||||
|
||||
@ -63,15 +54,6 @@ $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;
|
||||
|
||||
/// @prop - Color of the item border when `fill` is set
|
||||
$item-md-input-fill-border-color: $background-color-step-500 !default;
|
||||
|
||||
/// @prop - Color of the item border when `fill` is set and hovered
|
||||
$item-md-input-fill-border-color-hover: $background-color-step-750 !default;
|
||||
|
||||
/// @prop - Letter spacing of the item input counter
|
||||
$item-md-input-counter-letter-spacing: .0333333333em !default;
|
||||
|
||||
// Item Label
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -87,12 +69,6 @@ $item-md-label-margin-bottom: 10px !default;
|
||||
/// @prop - Margin start of the label
|
||||
$item-md-label-margin-start: 0 !default;
|
||||
|
||||
/// @prop - X translation for floating labels
|
||||
$item-md-fill-outline-label-translate-x: -32px !default;
|
||||
|
||||
/// @prop - Padding for floating labels
|
||||
$item-md-fill-outline-label-padding: 4px !default;
|
||||
|
||||
|
||||
// Item Slots
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -99,13 +99,13 @@
|
||||
// Item: Color
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.ion-color:not(.item-fill-solid):not(.item-fill-outline)) .item-native {
|
||||
:host(.ion-color) .item-native {
|
||||
background: current-color(base);
|
||||
color: current-color(contrast);
|
||||
}
|
||||
|
||||
:host(.ion-color:not(.item-fill-solid):not(.item-fill-outline)) .item-native,
|
||||
:host(.ion-color:not(.item-fill-solid):not(.item-fill-outline)) .item-inner {
|
||||
:host(.ion-color) .item-native,
|
||||
:host(.ion-color) .item-inner {
|
||||
border-color: current-color(shade);
|
||||
}
|
||||
|
||||
@ -307,32 +307,6 @@ button, a {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Item Bottom
|
||||
// --------------------------------------------------
|
||||
|
||||
.item-bottom {
|
||||
@include margin(0);
|
||||
@include padding(0, null);
|
||||
|
||||
/* stylelint-disable */
|
||||
@include ltr() {
|
||||
padding-left: calc(var(--padding-start) + var(--ion-safe-area-left, 0px));
|
||||
padding-right: calc(var(--inner-padding-end) + var(--ion-safe-area-right, 0px));
|
||||
}
|
||||
|
||||
@include rtl() {
|
||||
padding-left: calc(var(--inner-padding-end) + var(--ion-safe-area-left, 0px));
|
||||
padding-right: calc(var(--padding-start) + var(--ion-safe-area-right, 0px));
|
||||
}
|
||||
/* stylelint-enable */
|
||||
|
||||
display: flex;
|
||||
|
||||
justify-content: space-between;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Item Detail Icon
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -424,7 +398,6 @@ button, a {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
// Item Input Highlight
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -485,15 +458,10 @@ button, a {
|
||||
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(.ion-focused) .item-highlight,
|
||||
:host(.item-has-focus) .item-inner-highlight,
|
||||
:host(.item-has-focus:not(.item-fill-outline)) .item-highlight {
|
||||
:host(.item-has-focus) .item-highlight {
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
border-left: none;
|
||||
@ -522,35 +490,6 @@ button, a {
|
||||
--highlight-background: var(--highlight-color-invalid);
|
||||
}
|
||||
|
||||
:host(.item-interactive.ion-invalid) ::slotted([slot="helper"]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::slotted([slot="error"]) {
|
||||
display: none;
|
||||
|
||||
color: var(--highlight-color-invalid);
|
||||
}
|
||||
|
||||
:host(.item-interactive.ion-invalid) ::slotted([slot="error"]) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// Item Datetime
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(:not(.item-label)) ::slotted(ion-datetime) {
|
||||
--padding-start: 0;
|
||||
}
|
||||
|
||||
:host(.item-label-stacked) ::slotted(ion-datetime),
|
||||
:host(.item-label-floating) ::slotted(ion-datetime) {
|
||||
--padding-start: 0;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
// Item w/ Multiple Inputs
|
||||
// --------------------------------------------------
|
||||
// Multiple inputs in an item should have the input
|
||||
@ -585,36 +524,6 @@ ion-ripple-effect {
|
||||
color: var(--ripple-color);
|
||||
}
|
||||
|
||||
:host(.item-fill-solid) ::slotted([slot="start"]),
|
||||
:host(.item-fill-solid) ::slotted([slot="end"]),
|
||||
:host(.item-fill-outline) ::slotted([slot="start"]),
|
||||
:host(.item-fill-outline) ::slotted([slot="end"]) {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
::slotted([slot="helper"]),
|
||||
::slotted([slot="error"]),
|
||||
.item-counter {
|
||||
padding-top: 5px;
|
||||
|
||||
font-size: dynamic-font(12px);
|
||||
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// Item Max Length Counter
|
||||
// --------------------------------------------------
|
||||
|
||||
.item-counter {
|
||||
@include margin-horizontal(auto, null);
|
||||
|
||||
color: #{$background-color-step-550};
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
padding-inline-start: 16px;
|
||||
}
|
||||
|
||||
// Item: Reduced Motion
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
@ -3,25 +3,19 @@ import { Component, Element, Host, Listen, Prop, State, Watch, forceUpdate, h }
|
||||
import type { AnchorInterface, ButtonInterface } from '@utils/element-interface';
|
||||
import type { Attributes } from '@utils/helpers';
|
||||
import { inheritAttributes, raf } from '@utils/helpers';
|
||||
import { printIonError, printIonWarning } from '@utils/logging';
|
||||
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||
import { chevronForward } from 'ionicons/icons';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color, CssClassMap, StyleEventDetail } from '../../interface';
|
||||
import type { InputInputEventDetail } from '../input/input-interface';
|
||||
import type { RouterDirection } from '../router/utils/interface';
|
||||
|
||||
import type { CounterFormatter } from './item-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
*
|
||||
* @slot - Content is placed between the named slots if provided without a slot.
|
||||
* @slot start - Content is placed to the left of the item text in LTR, and to the right in RTL.
|
||||
* @slot end - Content is placed to the right of the item text in LTR, and to the left in RTL.
|
||||
* @slot helper - Content is placed under the item and displayed when no error is detected. **DEPRECATED** Use the "helperText" property on ion-input or ion-textarea instead.
|
||||
* @slot error - Content is placed under the item and displayed when an error is detected. **DEPRECATED** Use the "errorText" property on ion-input or ion-textarea instead.
|
||||
*
|
||||
* @part native - The native HTML button, anchor or div element that wraps all child elements.
|
||||
* @part detail-icon - The chevron icon for the item. Only applies when `detail="true"`.
|
||||
@ -80,18 +74,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
*/
|
||||
@Prop() download: string | undefined;
|
||||
|
||||
/**
|
||||
* The fill for the item. If `"solid"` the item will have a background. If
|
||||
* `"outline"` the item will be transparent with a border. Only available in `md` mode.
|
||||
* @deprecated Use the `fill` property on `ion-input` or `ion-textarea` instead.
|
||||
*/
|
||||
@Prop() fill?: 'outline' | 'solid';
|
||||
|
||||
/**
|
||||
* The shape of the item. If "round" it will have increased
|
||||
* border radius.
|
||||
*/
|
||||
@Prop() shape?: 'round';
|
||||
/**
|
||||
* Contains a URL or a URL fragment that the hyperlink points to.
|
||||
* If this property is set, an anchor tag will be rendered.
|
||||
@ -109,12 +91,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
*/
|
||||
@Prop() lines?: 'full' | 'inset' | 'none';
|
||||
|
||||
/**
|
||||
* If `true`, a character counter will display the ratio of characters used and the total character limit. Only applies when the `maxlength` property is set on the inner `ion-input` or `ion-textarea`.
|
||||
* @deprecated Use the `counter` property on `ion-input` or `ion-textarea` instead.
|
||||
*/
|
||||
@Prop() counter = false;
|
||||
|
||||
/**
|
||||
* When using a router, it specifies the transition animation when navigating to
|
||||
* another page using `href`.
|
||||
@ -139,33 +115,12 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
*/
|
||||
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
|
||||
|
||||
/**
|
||||
* A callback used to format the counter text.
|
||||
* By default the counter text is set to "itemLength / maxLength".
|
||||
* @deprecated Use the `counterFormatter` property on `ion-input` or `ion-textarea` instead.
|
||||
*/
|
||||
@Prop() counterFormatter?: CounterFormatter;
|
||||
|
||||
@State() counterString: string | null | undefined;
|
||||
|
||||
@Watch('button')
|
||||
buttonChanged() {
|
||||
// Update the focusable option when the button option is changed
|
||||
this.focusable = this.isFocusable();
|
||||
}
|
||||
|
||||
@Watch('counterFormatter')
|
||||
counterFormatterChanged() {
|
||||
this.updateCounterOutput(this.getFirstInput());
|
||||
}
|
||||
|
||||
@Listen('ionInput')
|
||||
handleIonInput(ev: CustomEvent<InputInputEventDetail>) {
|
||||
if (this.counter && ev.target === this.getFirstInput()) {
|
||||
this.updateCounterOutput(ev.target as HTMLIonInputElement | HTMLIonTextareaElement);
|
||||
}
|
||||
}
|
||||
|
||||
@Listen('ionColor')
|
||||
labelColorChanged(ev: CustomEvent<string>) {
|
||||
const { color } = this;
|
||||
@ -207,10 +162,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (this.counter) {
|
||||
this.updateCounterOutput(this.getFirstInput());
|
||||
}
|
||||
|
||||
this.hasStartEl();
|
||||
}
|
||||
|
||||
@ -219,51 +170,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
const { el, counter, counterFormatter, fill, shape } = this;
|
||||
const hasHelperSlot = el.querySelector('[slot="helper"]') !== null;
|
||||
if (hasHelperSlot) {
|
||||
printIonWarning(
|
||||
'The "helper" slot has been deprecated in favor of using the "helperText" property on ion-input or ion-textarea.',
|
||||
el
|
||||
);
|
||||
}
|
||||
|
||||
const hasErrorSlot = el.querySelector('[slot="error"]') !== null;
|
||||
if (hasErrorSlot) {
|
||||
printIonWarning(
|
||||
'The "error" slot has been deprecated in favor of using the "errorText" property on ion-input or ion-textarea.',
|
||||
el
|
||||
);
|
||||
}
|
||||
|
||||
if (counter === true) {
|
||||
printIonWarning(
|
||||
'The "counter" property has been deprecated in favor of using the "counter" property on ion-input or ion-textarea.',
|
||||
el
|
||||
);
|
||||
}
|
||||
|
||||
if (counterFormatter !== undefined) {
|
||||
printIonWarning(
|
||||
'The "counterFormatter" property has been deprecated in favor of using the "counterFormatter" property on ion-input or ion-textarea.',
|
||||
el
|
||||
);
|
||||
}
|
||||
|
||||
if (fill !== undefined) {
|
||||
printIonWarning(
|
||||
'The "fill" property has been deprecated in favor of using the "fill" property on ion-input or ion-textarea.',
|
||||
el
|
||||
);
|
||||
}
|
||||
|
||||
if (shape !== undefined) {
|
||||
printIonWarning(
|
||||
'The "shape" property has been deprecated in favor of using the "shape" property on ion-input or ion-textarea.',
|
||||
el
|
||||
);
|
||||
}
|
||||
|
||||
raf(() => {
|
||||
this.setMultipleInputs();
|
||||
this.focusable = this.isFocusable();
|
||||
@ -319,35 +225,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
return this.canActivate() || focusableChild !== null;
|
||||
}
|
||||
|
||||
private getFirstInput(): HTMLIonInputElement | HTMLIonTextareaElement {
|
||||
const inputs = this.el.querySelectorAll('ion-input, ion-textarea') as NodeListOf<
|
||||
HTMLIonInputElement | HTMLIonTextareaElement
|
||||
>;
|
||||
return inputs[0];
|
||||
}
|
||||
|
||||
private updateCounterOutput(inputEl: HTMLIonInputElement | HTMLIonTextareaElement) {
|
||||
const { counter, counterFormatter, defaultCounterFormatter } = this;
|
||||
if (counter && !this.multipleInputs && inputEl?.maxlength !== undefined) {
|
||||
const length = inputEl?.value?.toString().length ?? 0;
|
||||
if (counterFormatter === undefined) {
|
||||
this.counterString = defaultCounterFormatter(length, inputEl.maxlength);
|
||||
} else {
|
||||
try {
|
||||
this.counterString = counterFormatter(length, inputEl.maxlength);
|
||||
} catch (e) {
|
||||
printIonError('Exception in provided `counterFormatter`.', e);
|
||||
// Fallback to the default counter formatter when an exception happens
|
||||
this.counterString = defaultCounterFormatter(length, inputEl.maxlength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private defaultCounterFormatter(length: number, maxlength: number) {
|
||||
return `${length} / ${maxlength}`;
|
||||
}
|
||||
|
||||
private hasStartEl() {
|
||||
const startEl = this.el.querySelector('[slot="start"]');
|
||||
if (startEl !== null) {
|
||||
@ -364,17 +241,14 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
|
||||
render() {
|
||||
const {
|
||||
counterString,
|
||||
detail,
|
||||
detailIcon,
|
||||
download,
|
||||
fill,
|
||||
labelColorStyles,
|
||||
lines,
|
||||
disabled,
|
||||
href,
|
||||
rel,
|
||||
shape,
|
||||
target,
|
||||
routerAnimation,
|
||||
routerDirection,
|
||||
@ -445,7 +319,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
Object.assign(childStyles, value);
|
||||
});
|
||||
const ariaDisabled = disabled || childStyles['item-interactive-disabled'] ? 'true' : null;
|
||||
const fillValue = fill || 'none';
|
||||
const inList = hostContext('ion-list', this.el) && !hostContext('ion-radio-group', this.el);
|
||||
|
||||
/**
|
||||
@ -466,8 +339,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
[mode]: true,
|
||||
'item-lines-default': lines === undefined,
|
||||
[`item-lines-${lines}`]: lines !== undefined,
|
||||
[`item-fill-${fillValue}`]: true,
|
||||
[`item-shape-${shape}`]: shape !== undefined,
|
||||
'item-control-needs-pointer-cursor': firstInteractiveNeedsPointerCursor,
|
||||
'item-disabled': disabled,
|
||||
'in-list': inList,
|
||||
@ -508,11 +379,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
{canActivate && mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
<div class="item-highlight"></div>
|
||||
</TagType>
|
||||
<div class="item-bottom">
|
||||
<slot name="error"></slot>
|
||||
<slot name="helper"></slot>
|
||||
{counterString && <ion-note class="item-counter">{counterString}</ion-note>}
|
||||
</div>
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
||||
@ -25,11 +25,6 @@ configs().forEach(({ title, screenshot, config }) => {
|
||||
}
|
||||
</style>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Item with helper</ion-label>
|
||||
<div slot="helper">Helper</div>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label class="ion-text-nowrap"> Single line text that should have ellipses when it doesn't all fit in the item</ion-label>
|
||||
</ion-item>
|
||||
|
||||
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 2.7 KiB |
@ -1,98 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Item - Bottom</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<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>
|
||||
</head>
|
||||
|
||||
<style>
|
||||
ion-item.custom {
|
||||
--border-width: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Item inputs</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding-vertical">
|
||||
<ion-list class="basic">
|
||||
<ion-item>
|
||||
<ion-input label="No Helper/Error" name="input" id="text"></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-input label="Helper and Error"></ion-input>
|
||||
<ion-note slot="helper">Helper Text</ion-note>
|
||||
<ion-note slot="error">Error Text</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-input label="Helper Only"></ion-input>
|
||||
<ion-note slot="helper">Helper Text</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-input label="Error Only"></ion-input>
|
||||
<ion-note slot="error">Error Text</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item class="custom">
|
||||
<ion-input label="Both w/ Custom CSS"></ion-input>
|
||||
<ion-note slot="helper">Helper Text</ion-note>
|
||||
<ion-note slot="error">Error Text</ion-note>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item fill="solid">
|
||||
<ion-input label="Helper and Error (Fill Solid)"></ion-input>
|
||||
<ion-note slot="helper">Helper Text</ion-note>
|
||||
<ion-note slot="error">Error Text</ion-note>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
<ion-item fill="outline">
|
||||
<ion-input label="Helper and Error (Fill Outline)"></ion-input>
|
||||
<ion-note slot="helper">Helper Text</ion-note>
|
||||
<ion-note slot="error">Error Text</ion-note>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-toggle id="error-toggle" color="danger">Toggle Error</ion-toggle>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
(function toggleHelperError() {
|
||||
const toggle = document.getElementById('error-toggle');
|
||||
toggle.addEventListener('ionChange', (ev) => {
|
||||
const items = Array.from(document.querySelectorAll('ion-item'));
|
||||
items.forEach((item) => item.classList.toggle('ion-invalid'));
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,63 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Item - Disabled</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Item: Disabled</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding-vertical">
|
||||
<ion-list>
|
||||
<ion-list-header>
|
||||
<ion-label>Single Input Disabled Items</ion-label>
|
||||
</ion-list-header>
|
||||
|
||||
<ion-item disabled>
|
||||
<ion-label>Disabled Item</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item disabled button>
|
||||
<ion-label>Disabled Item Button</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item disabled href="#">
|
||||
<ion-label>Disabled Item Anchor</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button onClick="toggleDisabled()">Toggle</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const disabledEls = document.querySelectorAll('[disabled]');
|
||||
|
||||
function toggleDisabled() {
|
||||
for (var i = 0; i < disabledEls.length; i++) {
|
||||
disabledEls[i].disabled = !disabledEls[i].disabled;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,14 +0,0 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs().forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('item: disabled state'), () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/item/test/legacy/disabled`, config);
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
await expect(page).toHaveScreenshot(screenshot(`item-disabled-diff`));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 34 KiB |