diff --git a/core/api.txt b/core/api.txt
index 56fc0d66ff..5bd30946f2 100644
--- a/core/api.txt
+++ b/core/api.txt
@@ -483,12 +483,17 @@ ion-item,prop,target,string | undefined,undefined,false,false
ion-item,prop,type,"button" | "reset" | "submit",'button',false,false
ion-item,css-prop,--background
ion-item,css-prop,--background-activated
+ion-item,css-prop,--background-focused
+ion-item,css-prop,--background-hover
ion-item,css-prop,--border-color
ion-item,css-prop,--border-radius
ion-item,css-prop,--border-style
ion-item,css-prop,--border-width
ion-item,css-prop,--box-shadow
ion-item,css-prop,--color
+ion-item,css-prop,--color-activated
+ion-item,css-prop,--color-focused
+ion-item,css-prop,--color-hover
ion-item,css-prop,--detail-icon-color
ion-item,css-prop,--detail-icon-font-size
ion-item,css-prop,--detail-icon-opacity
diff --git a/core/src/components/checkbox/checkbox.tsx b/core/src/components/checkbox/checkbox.tsx
index fe6e1757e0..ff31cbcd86 100644
--- a/core/src/components/checkbox/checkbox.tsx
+++ b/core/src/components/checkbox/checkbox.tsx
@@ -94,7 +94,11 @@ export class Checkbox implements ComponentInterface {
}
@Watch('disabled')
- emitStyle() {
+ disabledChanged() {
+ this.emitStyle();
+ }
+
+ private emitStyle() {
this.ionStyle.emit({
'checkbox-checked': this.checked,
'interactive-disabled': this.disabled,
diff --git a/core/src/components/item/item.ios.scss b/core/src/components/item/item.ios.scss
index c4bfcde6cd..6e80302802 100644
--- a/core/src/components/item/item.ios.scss
+++ b/core/src/components/item/item.ios.scss
@@ -12,7 +12,8 @@
--inner-border-width: #{0px 0px $item-ios-border-bottom-width 0px};
--background: #{$item-ios-background};
--background-activated: #{$item-ios-background-activated};
- --background-focused: #{$item-ios-background-activated};
+ --background-focused: #{$item-ios-background-focused};
+ --background-hover: #{$item-ios-background-hover};
--border-color: #{$item-ios-border-bottom-color};
--color: #{$item-ios-color};
--highlight-height: 0;
@@ -23,10 +24,31 @@
font-size: $item-ios-font-size;
}
+
+// iOS Activated
+// --------------------------------------------------
+
:host(.activated) {
--transition: none;
}
+:host(.ion-color.activated) .item-native {
+ background: current-color(shade);
+ color: current-color(contrast);
+}
+
+@media (any-hover: hover) {
+ :host(.activated.ion-activatable:hover) .item-native {
+ background: var(--background-activated);
+ color: var(--color-activated);
+ }
+
+ :host(.activated.ion-color.ion-activatable:hover) .item-native {
+ background: #{current-color(shade)};
+ color: #{current-color(contrast)};
+ }
+}
+
// iOS Item Lines
// --------------------------------------------------
diff --git a/core/src/components/item/item.md.scss b/core/src/components/item/item.md.scss
index a89e222920..55dc5f5cd3 100644
--- a/core/src/components/item/item.md.scss
+++ b/core/src/components/item/item.md.scss
@@ -9,7 +9,8 @@
--min-height: #{$item-md-min-height};
--background: #{$item-md-background};
--background-activated: var(--background);
- --background-focused: #{$item-md-background-activated};
+ --background-focused: #{$item-md-background-focused};
+ --background-hover: #{$item-md-background-hover};
--border-color: #{$item-md-border-bottom-color};
--color: #{$item-md-color};
--transition: background-color 300ms cubic-bezier(.4, 0, .2, 1);
@@ -30,6 +31,25 @@
}
+// Material Design Item: Focused & Activated
+// --------------------------------------------------
+
+:host(.ion-focused.activated) .item-native {
+ background: var(--background-focused);
+ color: var(--color-focused);
+}
+
+:host(.ion-color.activated) .item-native {
+ background: current-color(base);
+ color: current-color(contrast);
+}
+
+:host(.ion-color.ion-focused.activated) .item-native {
+ background: current-color(shade);
+ color: current-color(contrast);
+}
+
+
// Material Design Item Lines
// --------------------------------------------------
diff --git a/core/src/components/item/item.scss b/core/src/components/item/item.scss
index 290a6ea965..e8449a0711 100644
--- a/core/src/components/item/item.scss
+++ b/core/src/components/item/item.scss
@@ -7,6 +7,8 @@
/**
* @prop --background: Background of the item
* @prop --background-activated: Background of the item when pressed
+ * @prop --background-focused: Background of the item when focused with the tab key
+ * @prop --background-hover: Background of the item on hover
*
* @prop --border-color: Color of the item border
* @prop --border-radius: Radius of the item border
@@ -16,6 +18,9 @@
* @prop --box-shadow: Box shadow of the item
*
* @prop --color: Color of the item
+ * @prop --color-activated: Color of the item when pressed
+ * @prop --color-focused: Color of the item when focused with the tab key
+ * @prop --color-hover: Color of the item on hover
*
* @prop --detail-icon-color: Color of the item detail icon
* @prop --detail-icon-opacity: Opacity of the item detail icon
@@ -63,6 +68,9 @@
--detail-icon-color: initial;
--detail-icon-font-size: 20px;
--detail-icon-opacity: 0.25;
+ --color-activated: var(--color);
+ --color-focused: var(--color);
+ --color-hover: var(--color);
--ripple-color: var(--ion-item-background-activated, currentColor);
@include font-smoothing();
@@ -85,7 +93,7 @@
}
-// Item with Color
+// Item: Color
// --------------------------------------------------
:host(.ion-color) .item-native {
@@ -99,25 +107,53 @@
}
-// Activated Item
+// Item: Focused
// --------------------------------------------------
:host(.ion-focused) .item-native {
background: var(--background-focused);
+ color: var(--color-focused);
}
+:host(.ion-color.ion-focused) .item-native {
+ background: current-color(shade);
+ color: current-color(contrast);
+}
+
+
+// Item: Hover
+// --------------------------------------------------
+
+@media (any-hover: hover) {
+ :host(.ion-activatable:hover) .item-native {
+ background: var(--background-hover);
+ color: var(--color-hover);
+ }
+
+ :host(.ion-color.ion-activatable:hover) .item-native {
+ background: #{current-color(tint)};
+ color: #{current-color(contrast)};
+ }
+}
+
+
+// Item: Activated
+// --------------------------------------------------
+
:host(.activated) .item-native {
background: var(--background-activated);
-}
-
-:host(.ion-color.activated) .item-native {
- background: current-color(tint);
+ color: var(--color-activated);
}
-// Disabled Item
+// Item: Disabled
// --------------------------------------------------
+:host(.item-interactive-disabled) {
+ cursor: default;
+ pointer-events: none;
+}
+
:host(.item-disabled) {
cursor: default;
opacity: .3;
@@ -209,7 +245,7 @@ button, a {
}
// Item Detail Icon
-// -----------------------------------------
+// --------------------------------------------------
.item-detail-icon {
color: var(--detail-icon-color);
@@ -221,7 +257,7 @@ button, a {
// Item Slots
-// -----------------------------------------
+// --------------------------------------------------
::slotted(ion-icon) {
font-size: 1.6em;
@@ -242,7 +278,7 @@ button, a {
// Item Input
-// -----------------------------------------
+// --------------------------------------------------
:host([vertical-align-top]),
:host(.item-input) {
@@ -331,7 +367,7 @@ button, a {
// Item Select
-// -----------------------------------------
+// --------------------------------------------------
:host(.item-label-stacked) ::slotted(ion-select),
:host(.item-label-floating) ::slotted(ion-select) {
@@ -346,7 +382,7 @@ button, a {
// Item Datetime
-// -----------------------------------------
+// --------------------------------------------------
:host(.item-label-stacked) ::slotted(ion-datetime),
:host(.item-label-floating) ::slotted(ion-datetime) {
@@ -357,9 +393,9 @@ button, a {
// Item w/ Multiple Inputs
-// -----------------------------------------
-// Multiple inputs in an item should have the input cover
-// relative to them instead of the item
+// --------------------------------------------------
+// Multiple inputs in an item should have the input
+// cover relative to themselves instead of the item
:host(.item-multiple-inputs) ::slotted(ion-datetime),
:host(.item-multiple-inputs) ::slotted(ion-select) {
@@ -368,7 +404,7 @@ button, a {
// Item Textarea
-// -----------------------------------------
+// --------------------------------------------------
:host(.item-textarea) {
align-items: stretch;
diff --git a/core/src/components/item/item.tsx b/core/src/components/item/item.tsx
index fb79706284..7c14b21eb0 100644
--- a/core/src/components/item/item.tsx
+++ b/core/src/components/item/item.tsx
@@ -133,15 +133,31 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
this.multipleInputs = inputs.length > 1 ? true : false;
}
+ // If the item contains an input including a radio, checkbox, datetime, etc.
+ // then the item will have a clickable input cover that should
+ // get the hover, focused and activated states UNLESS it has multiple
+ // inputs, then those need to individually get the click
+ private hasCover(): boolean {
+ const inputs = this.el.querySelectorAll('ion-checkbox, ion-datetime, ion-select, ion-radio');
+ return inputs.length > 0 && !this.multipleInputs;
+ }
+
+ // If the item has an href or button property it will render a native
+ // anchor or button that is clickable
private isClickable(): boolean {
return (this.href !== undefined || this.button);
}
+ private canActivate(): boolean {
+ return (this.isClickable() || this.hasCover());
+ }
+
render() {
const { detail, detailIcon, download, lines, disabled, href, rel, target, routerDirection } = this;
const childStyles = {};
const mode = getIonMode(this);
const clickable = this.isClickable();
+ const canActivate = this.canActivate();
const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div' as any;
const attrs = (TagType === 'button')
? { type: this.type }
@@ -168,7 +184,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
'item-disabled': disabled,
'in-list': hostContext('ion-list', this.el),
'item-multiple-inputs': this.multipleInputs,
- 'ion-activatable': this.isClickable(),
+ 'ion-activatable': canActivate,
'ion-focusable': true,
}}
>
@@ -187,7 +203,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
{showDetail &&