mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 09:34:19 +08:00
fix(item): add input highlight using an absolute div (#15856)
Adds the following CSS properties to item: ``` --highlight-color-focused --highlight-color-valid --highlight-color-invalid --highlight-height ``` This also fixes an issue where we were showing the highlight on items with no lines, and shows inset vs full properly. Adds documentation and tests for input focus. fixes #14036 fixes #9639 fixes #14952 closes #15690
This commit is contained in:
@ -363,12 +363,12 @@ export class Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export declare interface Item extends StencilComponents<'IonItem'> {}
|
export declare interface Item extends StencilComponents<'IonItem'> {}
|
||||||
@Component({ selector: 'ion-item', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'button', 'detail', 'detailIcon', 'disabled', 'href', 'lines', 'routerDirection', 'state', 'type'] })
|
@Component({ selector: 'ion-item', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'button', 'detail', 'detailIcon', 'disabled', 'href', 'lines', 'routerDirection', 'type'] })
|
||||||
export class Item {
|
export class Item {
|
||||||
|
|
||||||
constructor(r: ElementRef) {
|
constructor(r: ElementRef) {
|
||||||
const el = r.nativeElement;
|
const el = r.nativeElement;
|
||||||
proxyInputs(this, el, ['color', 'mode', 'button', 'detail', 'detailIcon', 'disabled', 'href', 'lines', 'routerDirection', 'state', 'type']);
|
proxyInputs(this, el, ['color', 'mode', 'button', 'detail', 'detailIcon', 'disabled', 'href', 'lines', 'routerDirection', 'type']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
core/src/components.d.ts
vendored
4
core/src/components.d.ts
vendored
@ -2107,7 +2107,6 @@ export namespace Components {
|
|||||||
* When using a router, it specifies the transition direction when navigating to another page using `href`.
|
* When using a router, it specifies the transition direction when navigating to another page using `href`.
|
||||||
*/
|
*/
|
||||||
'routerDirection'?: RouterDirection;
|
'routerDirection'?: RouterDirection;
|
||||||
'state'?: 'valid' | 'invalid' | 'focus';
|
|
||||||
/**
|
/**
|
||||||
* The type of the button. Only used when an `onclick` or `button` property is present. Possible values are: `"submit"`, `"reset"` and `"button"`. Default value is: `"button"`
|
* The type of the button. Only used when an `onclick` or `button` property is present. Possible values are: `"submit"`, `"reset"` and `"button"`. Default value is: `"button"`
|
||||||
*/
|
*/
|
||||||
@ -2150,7 +2149,6 @@ export namespace Components {
|
|||||||
* When using a router, it specifies the transition direction when navigating to another page using `href`.
|
* When using a router, it specifies the transition direction when navigating to another page using `href`.
|
||||||
*/
|
*/
|
||||||
'routerDirection'?: RouterDirection;
|
'routerDirection'?: RouterDirection;
|
||||||
'state'?: 'valid' | 'invalid' | 'focus';
|
|
||||||
/**
|
/**
|
||||||
* The type of the button. Only used when an `onclick` or `button` property is present. Possible values are: `"submit"`, `"reset"` and `"button"`. Default value is: `"button"`
|
* The type of the button. Only used when an `onclick` or `button` property is present. Possible values are: `"submit"`, `"reset"` and `"button"`. Default value is: `"button"`
|
||||||
*/
|
*/
|
||||||
@ -4017,7 +4015,7 @@ export namespace Components {
|
|||||||
* The text to display on the ok button. Default: `OK`.
|
* The text to display on the ok button. Default: `OK`.
|
||||||
*/
|
*/
|
||||||
'okText': string;
|
'okText': string;
|
||||||
'open': (ev?: UIEvent | undefined) => Promise<HTMLIonActionSheetElement | HTMLIonAlertElement | HTMLIonPopoverElement>;
|
'open': (ev?: UIEvent | undefined) => Promise<HTMLIonAlertElement | HTMLIonPopoverElement | HTMLIonActionSheetElement>;
|
||||||
/**
|
/**
|
||||||
* The text to display when the select is empty.
|
* The text to display when the select is empty.
|
||||||
*/
|
*/
|
||||||
|
@ -324,7 +324,6 @@ export class Input implements ComponentInterface {
|
|||||||
return {
|
return {
|
||||||
class: {
|
class: {
|
||||||
...createColorClasses(this.color),
|
...createColorClasses(this.color),
|
||||||
|
|
||||||
'in-item': hostContext('ion-item', this.el),
|
'in-item': hostContext('ion-item', this.el),
|
||||||
'has-value': this.hasValue(),
|
'has-value': this.hasValue(),
|
||||||
'has-focus': this.hasFocus
|
'has-focus': this.hasFocus
|
||||||
|
@ -5,6 +5,33 @@ it('input: basic', async () => {
|
|||||||
url: '/src/components/input/test/basic?ionic:animated=false'
|
url: '/src/components/input/test/basic?ionic:animated=false'
|
||||||
});
|
});
|
||||||
|
|
||||||
const compare = await page.compareScreenshot();
|
let compare = await page.compareScreenshot();
|
||||||
|
expect(compare).toMatchScreenshot();
|
||||||
|
|
||||||
|
const fullInput = await page.find('#fullInput');
|
||||||
|
await fullInput.click();
|
||||||
|
|
||||||
|
const fullItem = await page.find('#fullItem');
|
||||||
|
expect(fullItem).toHaveClass('item-has-focus');
|
||||||
|
|
||||||
|
compare = await page.compareScreenshot('full input focused');
|
||||||
|
expect(compare).toMatchScreenshot();
|
||||||
|
|
||||||
|
const insetInput = await page.find('#insetInput');
|
||||||
|
await insetInput.click();
|
||||||
|
|
||||||
|
const insetItem = await page.find('#insetItem');
|
||||||
|
expect(insetItem).toHaveClass('item-has-focus');
|
||||||
|
|
||||||
|
compare = await page.compareScreenshot('inset input focused');
|
||||||
|
expect(compare).toMatchScreenshot();
|
||||||
|
|
||||||
|
const noneInput = await page.find('#noneInput');
|
||||||
|
await noneInput.click();
|
||||||
|
|
||||||
|
const noneItem = await page.find('#noneItem');
|
||||||
|
expect(noneItem).toHaveClass('item-has-focus');
|
||||||
|
|
||||||
|
compare = await page.compareScreenshot('no lines input focused');
|
||||||
expect(compare).toMatchScreenshot();
|
expect(compare).toMatchScreenshot();
|
||||||
});
|
});
|
||||||
|
@ -28,6 +28,18 @@
|
|||||||
<ion-input placeholder="Placeholder"></ion-input>
|
<ion-input placeholder="Placeholder"></ion-input>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item lines="full" id="fullItem">
|
||||||
|
<ion-input id="fullInput" placeholder="Full"></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item lines="inset" id="insetItem">
|
||||||
|
<ion-input id="insetInput" placeholder="Inset"></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item lines="none" id="noneItem">
|
||||||
|
<ion-input id="noneInput" placeholder="None"></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label>Default Label</ion-label>
|
<ion-label>Default Label</ion-label>
|
||||||
<ion-input value="reallylonglonglonginputtoseetheedgesreallylonglonglonginputtoseetheedges"></ion-input>
|
<ion-input value="reallylonglonglonginputtoseetheedgesreallylonglonglonginputtoseetheedges"></ion-input>
|
||||||
|
@ -9,16 +9,17 @@
|
|||||||
--padding-start: #{$item-ios-padding-start};
|
--padding-start: #{$item-ios-padding-start};
|
||||||
--inner-padding-end: #{$item-ios-padding-end / 2};
|
--inner-padding-end: #{$item-ios-padding-end / 2};
|
||||||
--inner-border-width: #{0px 0px $item-ios-border-bottom-width 0px};
|
--inner-border-width: #{0px 0px $item-ios-border-bottom-width 0px};
|
||||||
|
|
||||||
font-size: $item-ios-font-size;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host(:not(.ion-color)) {
|
|
||||||
--background: var(--ion-item-background-color, transparent);
|
--background: var(--ion-item-background-color, transparent);
|
||||||
--background-activated: #{$item-ios-background-color-active};
|
--background-activated: #{$item-ios-background-color-active};
|
||||||
--border-color: #{$item-ios-border-bottom-color};
|
--border-color: #{$item-ios-border-bottom-color};
|
||||||
--color: #{$item-ios-text-color};
|
--color: #{$item-ios-text-color};
|
||||||
--detail-icon-color: #{$item-ios-border-bottom-color};
|
--detail-icon-color: #{$item-ios-border-bottom-color};
|
||||||
|
--highlight-height: 0;
|
||||||
|
--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;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.activated) {
|
:host(.activated) {
|
||||||
@ -29,14 +30,24 @@
|
|||||||
// iOS Item Lines
|
// 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
|
// Full lines - apply the border to the item
|
||||||
// Inset lines - apply the border to the item inner
|
// Inset lines - apply the border to the item inner
|
||||||
:host(.item-lines-full) {
|
:host(.item-lines-full) {
|
||||||
--border-width: #{0px 0px $item-ios-border-bottom-width 0px};
|
--border-width: #{0px 0px $item-ios-border-bottom-width 0px};
|
||||||
|
--show-full-highlight: 1;
|
||||||
|
--show-inset-highlight: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.item-lines-inset) {
|
:host(.item-lines-inset) {
|
||||||
--inner-border-width: #{0px 0px $item-ios-border-bottom-width 0px};
|
--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)
|
// Full lines - remove the border from the item inner (inset list items)
|
||||||
@ -45,11 +56,13 @@
|
|||||||
:host(.item-lines-inset),
|
:host(.item-lines-inset),
|
||||||
:host(.item-lines-none) {
|
:host(.item-lines-none) {
|
||||||
--border-width: 0px;
|
--border-width: 0px;
|
||||||
|
--show-full-highlight: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.item-lines-full),
|
:host(.item-lines-full),
|
||||||
:host(.item-lines-none) {
|
:host(.item-lines-none) {
|
||||||
--inner-border-width: 0px;
|
--inner-border-width: 0px;
|
||||||
|
--show-inset-highlight: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,6 +63,15 @@ $item-ios-border-bottom-color: $item-ios-border-color !default;
|
|||||||
/// @prop - Border bottom for the item
|
/// @prop - Border bottom for the item
|
||||||
$item-ios-border-bottom: $item-ios-border-bottom-width $item-ios-border-bottom-style $item-ios-border-bottom-color !default;
|
$item-ios-border-bottom: $item-ios-border-bottom-width $item-ios-border-bottom-style $item-ios-border-bottom-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
|
// Item Slots
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -8,8 +8,17 @@
|
|||||||
:host {
|
:host {
|
||||||
--transition: background-color 300ms cubic-bezier(.4, 0, .2, 1);
|
--transition: background-color 300ms cubic-bezier(.4, 0, .2, 1);
|
||||||
--padding-start: #{$item-md-padding-start};
|
--padding-start: #{$item-md-padding-start};
|
||||||
|
--background: var(--ion-item-background-color, transparent);
|
||||||
|
--background-activated: #{$item-md-background-color-active};
|
||||||
|
--color: #{$item-md-text-color};
|
||||||
|
--border-color: #{$item-md-border-bottom-color};
|
||||||
--inner-padding-end: #{$item-md-padding-end / 2};
|
--inner-padding-end: #{$item-md-padding-end / 2};
|
||||||
--padding-start: #{$item-md-padding-start};
|
--inner-border-width: #{0 0 $item-md-border-bottom-width 0};
|
||||||
|
--detail-icon-color: #{$item-md-border-bottom-color};
|
||||||
|
--highlight-height: 2px;
|
||||||
|
--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: $item-md-font-size;
|
font-size: $item-md-font-size;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
@ -17,31 +26,30 @@
|
|||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(:not(.ion-color)) {
|
|
||||||
--background: var(--ion-item-background-color, transparent);
|
|
||||||
--background-activated: #{$item-md-background-color-active};
|
|
||||||
--border-color: #{$item-md-border-bottom-color};
|
|
||||||
--color: #{$item-md-text-color};
|
|
||||||
--detail-icon-color: #{$item-md-border-bottom-color};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Material Design Item Lines
|
// Material Design Item Lines
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
// Default input items have a border
|
// Default input items have a full border
|
||||||
:host(.item-interactive) {
|
:host(.item-interactive) {
|
||||||
--border-width: #{0 0 $item-md-border-bottom-width 0};
|
--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
|
// Full lines - apply the border to the item
|
||||||
// Inset lines - apply the border to the item inner
|
// Inset lines - apply the border to the item inner
|
||||||
:host(.item-lines-full) {
|
:host(.item-lines-full) {
|
||||||
--border-width: #{0 0 $item-md-border-bottom-width 0};
|
--border-width: #{0 0 $item-md-border-bottom-width 0};
|
||||||
|
--show-full-highlight: 1;
|
||||||
|
--show-inset-highlight: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.item-lines-inset) {
|
:host(.item-lines-inset) {
|
||||||
--inner-border-width: #{0 0 $item-md-border-bottom-width 0};
|
--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)
|
// Full lines - remove the border from the item inner (inset list items)
|
||||||
@ -50,11 +58,13 @@
|
|||||||
:host(.item-lines-inset),
|
:host(.item-lines-inset),
|
||||||
:host(.item-lines-none) {
|
:host(.item-lines-none) {
|
||||||
--border-width: 0;
|
--border-width: 0;
|
||||||
|
--show-full-highlight: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.item-lines-full),
|
:host(.item-lines-full),
|
||||||
:host(.item-lines-none) {
|
:host(.item-lines-none) {
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0;
|
||||||
|
--show-inset-highlight: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material Design Item Detail Push
|
// Material Design Item Detail Push
|
||||||
|
@ -48,6 +48,15 @@ $item-md-border-bottom-color: $item-md-border-color !default;
|
|||||||
/// @prop - Border bottom for the item when lines are displayed
|
/// @prop - Border bottom for the item when lines are displayed
|
||||||
$item-md-border-bottom: $item-md-border-bottom-width $item-md-border-bottom-style $item-md-border-color !default;
|
$item-md-border-bottom: $item-md-border-bottom-width $item-md-border-bottom-style $item-md-border-color !default;
|
||||||
|
|
||||||
|
/// @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 Slots
|
// Item Slots
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -13,49 +13,52 @@
|
|||||||
* @prop --border-width: Width of the item border
|
* @prop --border-width: Width of the item border
|
||||||
* @prop --box-shadow: Box shadow of the item
|
* @prop --box-shadow: Box shadow of the item
|
||||||
* @prop --color: Color of the item
|
* @prop --color: Color of the item
|
||||||
|
*
|
||||||
* @prop --detail-icon-color: Color of the item detail icon
|
* @prop --detail-icon-color: Color of the item detail icon
|
||||||
|
*
|
||||||
* @prop --inner-border-width: Width of the item inner border
|
* @prop --inner-border-width: Width of the item inner border
|
||||||
* @prop --inner-box-shadow: Box shadow of the item inner
|
* @prop --inner-box-shadow: Box shadow of the item inner
|
||||||
* @prop --inner-padding-bottom: Bottom padding of the item inner
|
* @prop --inner-padding-bottom: Bottom padding of the item inner
|
||||||
* @prop --inner-padding-end: End padding of the item inner
|
* @prop --inner-padding-end: End padding of the item inner
|
||||||
* @prop --inner-padding-start: Start padding of the item inner
|
* @prop --inner-padding-start: Start padding of the item inner
|
||||||
* @prop --inner-padding-top: Top padding of the item inner
|
* @prop --inner-padding-top: Top padding of the item inner
|
||||||
|
*
|
||||||
* @prop --min-height: Minimum height of the item
|
* @prop --min-height: Minimum height of the item
|
||||||
* @prop --padding-bottom: Bottom padding of the item
|
* @prop --padding-bottom: Bottom padding of the item
|
||||||
* @prop --padding-end: End padding of the item
|
* @prop --padding-end: End padding of the item
|
||||||
* @prop --padding-start: Start padding of the item
|
* @prop --padding-start: Start padding of the item
|
||||||
* @prop --padding-top: Top padding of the item
|
* @prop --padding-top: Top padding of the item
|
||||||
* @prop --transition: Transition of the item
|
* @prop --transition: Transition of the item
|
||||||
|
*
|
||||||
|
* @prop --highlight-height: The height of the highlight on the item
|
||||||
|
* @prop --highlight-color-focused: The color of the highlight on the item when focused
|
||||||
|
* @prop --highlight-color-valid: The color of the highlight on the item when valid
|
||||||
|
* @prop --highlight-color-invalid: The color of the highlight on the item when invalid
|
||||||
*/
|
*/
|
||||||
--min-height: #{$item-min-height};
|
--min-height: #{$item-min-height};
|
||||||
--background: #{current-color(base)};
|
|
||||||
--background-activated: #{current-color(tint)};
|
|
||||||
--color: #{current-color(contrast)};
|
|
||||||
--detail-icon-color: #{current-color(shade)};
|
|
||||||
--border-radius: 0px;
|
--border-radius: 0px;
|
||||||
--border-width: 0px;
|
--border-width: 0px;
|
||||||
--border-style: solid;
|
--border-style: solid;
|
||||||
--border-color: #{current-color(shade)};
|
|
||||||
--inner-border-width: 0px;
|
|
||||||
--padding-top: 0px;
|
--padding-top: 0px;
|
||||||
--padding-bottom: 0px;
|
--padding-bottom: 0px;
|
||||||
--padding-end: 0px;
|
--padding-end: 0px;
|
||||||
--padding-start: 0px;
|
--padding-start: 0px;
|
||||||
|
--box-shadow: none;
|
||||||
|
--inner-border-width: 0px;
|
||||||
--inner-padding-top: 0px;
|
--inner-padding-top: 0px;
|
||||||
--inner-padding-bottom: 0px;
|
--inner-padding-bottom: 0px;
|
||||||
--inner-padding-start: 0px;
|
--inner-padding-start: 0px;
|
||||||
--inner-padding-end: 0px;
|
--inner-padding-end: 0px;
|
||||||
--box-shadow: none;
|
|
||||||
--inner-box-shadow: none;
|
--inner-box-shadow: none;
|
||||||
--highlight-color-focus: #{ion-color(primary, base)};
|
--show-full-highlight: 0;
|
||||||
--highlight-color-valid: #{ion-color(success, base)};
|
--show-inset-highlight: 0;
|
||||||
--highlight-color-invalid: #{ion-color(danger, base)};
|
|
||||||
--highlight-height: 2px;
|
|
||||||
|
|
||||||
@include font-smoothing();
|
@include font-smoothing();
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
|
|
||||||
font-family: $font-family-base;
|
font-family: $font-family-base;
|
||||||
@ -66,10 +69,40 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Item with Color
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
:host(.ion-color) .item-native {
|
||||||
|
background: current-color(base);
|
||||||
|
color: current-color(contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.ion-color) .item-native,
|
||||||
|
:host(.ion-color) .item-inner {
|
||||||
|
border-color: current-color(shade);
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.ion-color) .item-detail-icon {
|
||||||
|
color: current-color(shade);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Activated Item
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
:host(.activated) .item-native {
|
:host(.activated) .item-native {
|
||||||
background: var(--background-activated);
|
background: var(--background-activated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host(.ion-color.activated) .item-native {
|
||||||
|
background: current-color(tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Disabled Item
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
:host(.item-disabled) {
|
:host(.item-disabled) {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
opacity: .3;
|
opacity: .3;
|
||||||
@ -77,15 +110,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Native Item
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
.item-native {
|
.item-native {
|
||||||
|
@include border-radius(var(--border-radius));
|
||||||
|
@include margin(0);
|
||||||
@include padding(
|
@include padding(
|
||||||
var(--padding-top),
|
var(--padding-top),
|
||||||
var(--padding-end),
|
var(--padding-end),
|
||||||
var(--padding-bottom),
|
var(--padding-bottom),
|
||||||
calc(var(--padding-start) + var(--ion-safe-area-left, 0px))
|
calc(var(--padding-start) + var(--ion-safe-area-left, 0px))
|
||||||
);
|
);
|
||||||
@include border-radius(var(--border-radius));
|
|
||||||
@include margin(0);
|
|
||||||
@include text-inherit();
|
@include text-inherit();
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -119,13 +155,9 @@ button, a {
|
|||||||
-webkit-user-drag: none;
|
-webkit-user-drag: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-state {
|
|
||||||
@include position(null, 0, 0, 0);
|
|
||||||
|
|
||||||
position: absolute;
|
// Inner Item
|
||||||
|
// --------------------------------------------------
|
||||||
height: var(--highlight-height);
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-inner {
|
.item-inner {
|
||||||
@include margin(0);
|
@include margin(0);
|
||||||
@ -138,6 +170,8 @@ button, a {
|
|||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: inherit;
|
flex-direction: inherit;
|
||||||
align-items: inherit;
|
align-items: inherit;
|
||||||
@ -154,24 +188,9 @@ button, a {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-wrapper {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
flex: 1;
|
// Item Slots
|
||||||
flex-direction: inherit;
|
// -----------------------------------------
|
||||||
align-items: inherit;
|
|
||||||
align-self: stretch;
|
|
||||||
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([vertical-align-top]),
|
|
||||||
:host(.item-input) {
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
::slotted(ion-icon) {
|
::slotted(ion-icon) {
|
||||||
font-size: 1.6em;
|
font-size: 1.6em;
|
||||||
@ -190,6 +209,25 @@ button, a {
|
|||||||
// Item Input
|
// Item Input
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
|
:host([vertical-align-top]),
|
||||||
|
:host(.item-input) {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-wrapper {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: inherit;
|
||||||
|
align-items: inherit;
|
||||||
|
align-self: stretch;
|
||||||
|
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
:host(.item-label-stacked) .input-wrapper,
|
:host(.item-label-stacked) .input-wrapper,
|
||||||
:host(.item-label-floating) .input-wrapper {
|
:host(.item-label-floating) .input-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -202,6 +240,55 @@ button, a {
|
|||||||
// pointer-events: auto;
|
// pointer-events: auto;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// Item Input Highlight
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
.item-highlight,
|
||||||
|
.item-inner-highlight {
|
||||||
|
@include position(null, 0, 0, 0);
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
background: var(--highlight-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-highlight {
|
||||||
|
height: var(--full-highlight-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-inner-highlight {
|
||||||
|
height: var(--inset-highlight-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Item Input Focused
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
:host(.item-interactive.item-has-focus) {
|
||||||
|
--highlight-background: var(--highlight-color-focused);
|
||||||
|
|
||||||
|
// 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))};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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 Select
|
// Item Select
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
@ -72,9 +72,6 @@ export class Item implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop() routerDirection?: RouterDirection;
|
@Prop() routerDirection?: RouterDirection;
|
||||||
|
|
||||||
// TODO document this
|
|
||||||
@Prop() state?: 'valid' | 'invalid' | 'focus';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the button. Only used when an `onclick` or `button` property is present.
|
* The type of the button. Only used when an `onclick` or `button` property is present.
|
||||||
* Possible values are: `"submit"`, `"reset"` and `"button"`.
|
* Possible values are: `"submit"`, `"reset"` and `"button"`.
|
||||||
@ -146,14 +143,14 @@ export class Item implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { href, detail, mode, win, state, detailIcon, routerDirection, type } = this;
|
const { href, detail, mode, win, detailIcon, routerDirection, type } = this;
|
||||||
|
|
||||||
const clickable = this.isClickable();
|
const clickable = this.isClickable();
|
||||||
const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div';
|
const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div';
|
||||||
const attrs = TagType === 'button' ? { type } : { href };
|
const attrs = TagType === 'button' ? { type } : { href };
|
||||||
const showDetail = detail !== undefined ? detail : mode === 'ios' && clickable;
|
const showDetail = detail !== undefined ? detail : mode === 'ios' && clickable;
|
||||||
|
|
||||||
return (
|
return [
|
||||||
<TagType
|
<TagType
|
||||||
{...attrs}
|
{...attrs}
|
||||||
class="item-native"
|
class="item-native"
|
||||||
@ -166,10 +163,11 @@ export class Item implements ComponentInterface {
|
|||||||
</div>
|
</div>
|
||||||
<slot name="end"></slot>
|
<slot name="end"></slot>
|
||||||
{showDetail && <ion-icon icon={detailIcon} lazy={false} class="item-detail-icon"></ion-icon>}
|
{showDetail && <ion-icon icon={detailIcon} lazy={false} class="item-detail-icon"></ion-icon>}
|
||||||
|
<div class="item-inner-highlight"></div>
|
||||||
</div>
|
</div>
|
||||||
{state && <div class="item-state"></div>}
|
|
||||||
{clickable && mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
{clickable && mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||||
</TagType>
|
</TagType>,
|
||||||
);
|
<div class="item-highlight"></div>
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,17 @@ The below chart details the item slots and where it will place the element insid
|
|||||||
Items left align text and add an ellipsis when the text is wider than the item. See the [Utility Attributes Documentation](/docs/layout/css-utilities) for attributes that can be added to `<ion-item>` to transform the text.
|
Items left align text and add an ellipsis when the text is wider than the item. See the [Utility Attributes Documentation](/docs/layout/css-utilities) for attributes that can be added to `<ion-item>` to transform the text.
|
||||||
|
|
||||||
|
|
||||||
|
## Input Highlight
|
||||||
|
|
||||||
|
### Highlight Height
|
||||||
|
|
||||||
|
Items containing an input will highlight the input with a different color border when focused, valid, or invalid. By default, `md` items have a highlight with a height set to `2px` and `ios` has no highlight (technically the height is set to `0`). The height can be changed using the `--highlight-height` CSS property. To turn off the highlight, set this variable to `0`. For more information on setting CSS properties, see the [theming documentation](/docs/theming/css-variables).
|
||||||
|
|
||||||
|
### Highlight Color
|
||||||
|
|
||||||
|
The highlight color changes based on the item state, but all of the states use Ionic colors by default. When focused, the input highlight will use the `primary` color. If the input is valid it will use the `success` color, and invalid inputs will use the `danger` color. See the [CSS Custom Properties](#css-custom-properties) section below for the highlight color variables.
|
||||||
|
|
||||||
|
|
||||||
<!-- Auto Generated Below -->
|
<!-- Auto Generated Below -->
|
||||||
|
|
||||||
|
|
||||||
@ -56,35 +67,38 @@ Items left align text and add an ellipsis when the text is wider than the item.
|
|||||||
| `lines` | `lines` | How the bottom border should be displayed on the item. Available options: `"full"`, `"inset"`, `"none"`. | `"full"`, `"inset"`, `"none"` |
|
| `lines` | `lines` | How the bottom border should be displayed on the item. Available options: `"full"`, `"inset"`, `"none"`. | `"full"`, `"inset"`, `"none"` |
|
||||||
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `Mode` |
|
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `Mode` |
|
||||||
| `routerDirection` | `router-direction` | When using a router, it specifies the transition direction when navigating to another page using `href`. | `RouterDirection` |
|
| `routerDirection` | `router-direction` | When using a router, it specifies the transition direction when navigating to another page using `href`. | `RouterDirection` |
|
||||||
| `state` | `state` | | `"valid"`, `"invalid"`, `"focus"` |
|
|
||||||
| `type` | `type` | The type of the button. Only used when an `onclick` or `button` property is present. Possible values are: `"submit"`, `"reset"` and `"button"`. Default value is: `"button"` | `"submit"`, `"reset"`, `"button"` |
|
| `type` | `type` | The type of the button. Only used when an `onclick` or `button` property is present. Possible values are: `"submit"`, `"reset"` and `"button"`. Default value is: `"button"` | `"submit"`, `"reset"`, `"button"` |
|
||||||
|
|
||||||
|
|
||||||
## CSS Custom Properties
|
## CSS Custom Properties
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
| ------------------------ | -------------------------------- |
|
| --------------------------- | --------------------------------------------------- |
|
||||||
| `--background` | Background of the item |
|
| `--background` | Background of the item |
|
||||||
| `--background-activated` | Background of the activated item |
|
| `--background-activated` | Background of the activated item |
|
||||||
| `--border-color` | Color of the item border |
|
| `--border-color` | Color of the item border |
|
||||||
| `--border-radius` | Radius of the item border |
|
| `--border-radius` | Radius of the item border |
|
||||||
| `--border-style` | Style of the item border |
|
| `--border-style` | Style of the item border |
|
||||||
| `--border-width` | Width of the item border |
|
| `--border-width` | Width of the item border |
|
||||||
| `--box-shadow` | Box shadow of the item |
|
| `--box-shadow` | Box shadow of the item |
|
||||||
| `--color` | Color of the item |
|
| `--color` | Color of the item |
|
||||||
| `--detail-icon-color` | Color of the item detail icon |
|
| `--detail-icon-color` | Color of the item detail icon |
|
||||||
| `--inner-border-width` | Width of the item inner border |
|
| `--highlight-color-focused` | The color of the highlight on the item when focused |
|
||||||
| `--inner-box-shadow` | Box shadow of the item inner |
|
| `--highlight-color-invalid` | The color of the highlight on the item when invalid |
|
||||||
| `--inner-padding-bottom` | Bottom padding of the item inner |
|
| `--highlight-color-valid` | The color of the highlight on the item when valid |
|
||||||
| `--inner-padding-end` | End padding of the item inner |
|
| `--highlight-height` | The height of the highlight on the item |
|
||||||
| `--inner-padding-start` | Start padding of the item inner |
|
| `--inner-border-width` | Width of the item inner border |
|
||||||
| `--inner-padding-top` | Top padding of the item inner |
|
| `--inner-box-shadow` | Box shadow of the item inner |
|
||||||
| `--min-height` | Minimum height of the item |
|
| `--inner-padding-bottom` | Bottom padding of the item inner |
|
||||||
| `--padding-bottom` | Bottom padding of the item |
|
| `--inner-padding-end` | End padding of the item inner |
|
||||||
| `--padding-end` | End padding of the item |
|
| `--inner-padding-start` | Start padding of the item inner |
|
||||||
| `--padding-start` | Start padding of the item |
|
| `--inner-padding-top` | Top padding of the item inner |
|
||||||
| `--padding-top` | Top padding of the item |
|
| `--min-height` | Minimum height of the item |
|
||||||
| `--transition` | Transition of the item |
|
| `--padding-bottom` | Bottom padding of the item |
|
||||||
|
| `--padding-end` | End padding of the item |
|
||||||
|
| `--padding-start` | Start padding of the item |
|
||||||
|
| `--padding-top` | Top padding of the item |
|
||||||
|
| `--transition` | Transition of the item |
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
Reference in New Issue
Block a user