fix(item): do not disable entire item if there are multiple inputs (#18696)

references #18655
fixes #18670
This commit is contained in:
Brandy Carney
2019-07-02 14:45:24 -04:00
committed by GitHub
parent 1f51ab27c4
commit dfa2b13c3a
5 changed files with 236 additions and 10 deletions

View File

@ -149,7 +149,7 @@
// Item: Disabled
// --------------------------------------------------
:host(.item-interactive-disabled) {
:host(.item-interactive-disabled:not(.item-multiple-inputs)) {
cursor: default;
pointer-events: none;
}
@ -397,7 +397,9 @@ button, a {
// Multiple inputs in an item should have the input
// cover relative to themselves instead of the item
:host(.item-multiple-inputs) ::slotted(ion-checkbox),
:host(.item-multiple-inputs) ::slotted(ion-datetime),
:host(.item-multiple-inputs) ::slotted(ion-radio),
:host(.item-multiple-inputs) ::slotted(ion-select) {
position: relative;
}

View File

@ -128,18 +128,26 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
}
componentDidLoad() {
// Check for multiple inputs to change the position to relative
const inputs = this.el.querySelectorAll('ion-select, ion-datetime');
this.multipleInputs = inputs.length > 1 ? true : false;
// The following elements have a clickable cover that is relative to the entire item
const covers = this.el.querySelectorAll('ion-checkbox, ion-datetime, ion-select, ion-radio');
// The following elements can accept focus alongside the previous elements
// therefore if these elements are also a child of item, we don't want the
// input cover on top of those interfering with their clicks
const inputs = this.el.querySelectorAll('ion-input, ion-range, ion-searchbar, ion-segment, ion-textarea, ion-toggle');
// Check for multiple inputs to change the position of the input cover to relative
// for all of the covered inputs above
this.multipleInputs = covers.length + inputs.length > 1;
}
// 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
// If the item contains an input including a checkbox, datetime, select, or radio
// then the item will have a clickable input cover that covers the item
// that should get the hover, focused and activated states UNLESS it has multiple
// inputs, then those need to individually get each click
private hasCover(): boolean {
const inputs = this.el.querySelectorAll('ion-checkbox, ion-datetime, ion-select, ion-radio');
return inputs.length > 0 && !this.multipleInputs;
return inputs.length === 1 && !this.multipleInputs;
}
// If the item has an href or button property it will render a native

View File

@ -0,0 +1,19 @@
import { newE2EPage } from '@stencil/core/testing';
test('item: disabled', async () => {
const page = await newE2EPage({
url: '/src/components/item/test/disabled?ionic:_testing=true'
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});
test('item: disabled-rtl', async () => {
const page = await newE2EPage({
url: '/src/components/item/test/disabled?ionic:_testing=true&rtl=true'
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});

View File

@ -0,0 +1,197 @@
<!DOCTYPE html>
<html 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 src="../../../../../dist/ionic.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-item>
<ion-label>Disabled Datetime</ion-label>
<ion-datetime disabled value="2019"></ion-datetime>
</ion-item>
<ion-item>
<ion-label>Disabled Select</ion-label>
<ion-select disabled>
<ion-select-option value="">No Game Console</ion-select-option>
<ion-select-option value="nes">NES</ion-select-option>
<ion-select-option value="n64" selected>Nintendo64</ion-select-option>
<ion-select-option value="ps">PlayStation</ion-select-option>
<ion-select-option value="genesis">Sega Genesis</ion-select-option>
<ion-select-option value="saturn">Sega Saturn</ion-select-option>
<ion-select-option value="snes">SNES</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Disabled Input</ion-label>
<ion-input placeholder="Disabled" disabled></ion-input>
</ion-item>
<ion-item>
<ion-label>Disabled Toggle</ion-label>
<ion-toggle disabled checked slot="end"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Disabled Checkbox</ion-label>
<ion-checkbox disabled checked slot="start"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Disabled Range</ion-label>
<ion-range disabled value="10"></ion-range>
</ion-item>
</ion-list>
<ion-list>
<ion-list-header>
<ion-label>Multiple Input Disabled Items</ion-label>
</ion-list-header>
<ion-item>
<ion-checkbox disabled slot="start"></ion-checkbox>
<ion-input placeholder="Disabled Checkbox w/ Input"></ion-input>
</ion-item>
<ion-item>
<ion-checkbox disabled slot="end"></ion-checkbox>
<ion-input placeholder="Disabled Checkbox w/ Input"></ion-input>
</ion-item>
<ion-item>
<ion-radio disabled slot="start"></ion-radio>
<ion-input placeholder="Disabled Radio w/ Input"></ion-input>
</ion-item>
<ion-item>
<ion-radio disabled slot="end"></ion-radio>
<ion-input placeholder="Disabled Radio w/ Input"></ion-input>
</ion-item>
<ion-item>
<ion-checkbox disabled slot="start"></ion-checkbox>
<ion-label>Checkbox + Radio</ion-label>
<ion-radio slot="end"></ion-radio>
</ion-item>
<ion-item>
<ion-checkbox disabled slot="start"></ion-checkbox>
<ion-radio slot="start"></ion-radio>
<ion-label>Checkbox + Radio</ion-label>
</ion-item>
<ion-item>
<ion-label>Disabled Selects</ion-label>
<ion-select placeholder="month">
<ion-select-option value="1">January</ion-select-option>
<ion-select-option value="2">February</ion-select-option>
<ion-select-option value="3">March</ion-select-option>
</ion-select>
<ion-select disabled placeholder="year">
<ion-select-option value="1990">1990</ion-select-option>
<ion-select-option value="1991">1991</ion-select-option>
<ion-select-option value="1992">1992</ion-select-option>
<ion-select-option value="1993">1993</ion-select-option>
<ion-select-option value="1994">1994</ion-select-option>
<ion-select-option value="1995">1995</ion-select-option>
<ion-select-option value="1996">1996</ion-select-option>
<ion-select-option value="1997">1997</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-checkbox slot="start"></ion-checkbox>
<ion-label>Checkbox + Range</ion-label>
<ion-range disabled value="45"></ion-range>
</ion-item>
<ion-item>
<ion-checkbox slot="start"></ion-checkbox>
<ion-label>Checkbox + Toggle</ion-label>
<ion-toggle disabled value="45"></ion-toggle>
</ion-item>
<ion-item>
<ion-checkbox disabled slot="start"></ion-checkbox>
<ion-label>Checkbox + Buttons</ion-label>
<ion-button slot="end">Default</ion-button>
<ion-button slot="end">Buttons</ion-button>
</ion-item>
<ion-item>
<ion-label>Disabled Input</ion-label>
<ion-input slot="start" placeholder="Disabled" disabled></ion-input>
<ion-segment>
<ion-segment-button value="friends">
<ion-label>Friends</ion-label>
</ion-segment-button>
<ion-segment-button value="enemies">
<ion-label>Enemies</ion-label>
</ion-segment-button>
</ion-segment>
</ion-item>
<ion-item>
<ion-checkbox slot="start" disabled></ion-checkbox>
<ion-label>Disabled Checkbox</ion-label>
<ion-searchbar></ion-searchbar>
</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>
</html>

View File

@ -34,7 +34,7 @@
white-space: normal;
}
:host-context(.item-interactive-disabled) {
:host-context(.item-interactive-disabled:not(.item-multiple-inputs)) {
cursor: default;
opacity: .3;
pointer-events: none;