mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 03:00:58 +08:00
fix(checkbox, radio, toggle): disabled elements are not interactive (#28294)
Issue number: resolves #28293 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> Disabled toggles, radios, and checkboxes can still be enabled by manually dispatching a click event on them. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - Toggles, radios, and checkboxes no longer activate if `disabled` is set to `true` ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Dev build: `7.4.4-dev.11696545130.1171e7a9`
This commit is contained in:
@ -211,6 +211,10 @@ export class Checkbox implements ComponentInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private onClick = (ev: MouseEvent) => {
|
private onClick = (ev: MouseEvent) => {
|
||||||
|
if (this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.toggleChecked(ev);
|
this.toggleChecked(ev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
24
core/src/components/checkbox/test/checkbox.spec.ts
Normal file
24
core/src/components/checkbox/test/checkbox.spec.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { newSpecPage } from '@stencil/core/testing';
|
||||||
|
|
||||||
|
import { Checkbox } from '../checkbox';
|
||||||
|
|
||||||
|
describe('ion-checkbox: disabled', () => {
|
||||||
|
it('clicking disabled checkbox should not toggle checked state', async () => {
|
||||||
|
const page = await newSpecPage({
|
||||||
|
components: [Checkbox],
|
||||||
|
html: `
|
||||||
|
<ion-checkbox disabled="true">Checkbox</ion-checkbox>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const checkbox = page.body.querySelector('ion-checkbox');
|
||||||
|
|
||||||
|
expect(checkbox.checked).toBe(false);
|
||||||
|
|
||||||
|
checkbox.click();
|
||||||
|
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
expect(checkbox.checked).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
@ -113,7 +113,7 @@ export class RadioGroup implements ComponentInterface {
|
|||||||
* using the `name` attribute.
|
* using the `name` attribute.
|
||||||
*/
|
*/
|
||||||
const selectedRadio = ev.target && (ev.target as HTMLElement).closest('ion-radio');
|
const selectedRadio = ev.target && (ev.target as HTMLElement).closest('ion-radio');
|
||||||
if (selectedRadio) {
|
if (selectedRadio && selectedRadio.disabled === false) {
|
||||||
const currentValue = this.value;
|
const currentValue = this.value;
|
||||||
const newValue = selectedRadio.value;
|
const newValue = selectedRadio.value;
|
||||||
if (newValue !== currentValue) {
|
if (newValue !== currentValue) {
|
||||||
|
@ -200,7 +200,11 @@ export class Radio implements ComponentInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private onClick = () => {
|
private onClick = () => {
|
||||||
const { radioGroup, checked } = this;
|
const { radioGroup, checked, disabled } = this;
|
||||||
|
|
||||||
|
if (disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The legacy control uses a native input inside
|
* The legacy control uses a native input inside
|
||||||
|
@ -31,3 +31,27 @@ describe('ion-radio', () => {
|
|||||||
expect(radio.classList.contains('radio-checked')).toBe(true);
|
expect(radio.classList.contains('radio-checked')).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('ion-radio: disabled', () => {
|
||||||
|
it('clicking disabled radio should not set checked state', async () => {
|
||||||
|
const page = await newSpecPage({
|
||||||
|
components: [Radio, RadioGroup],
|
||||||
|
html: `
|
||||||
|
<ion-radio-group>
|
||||||
|
<ion-radio disabled="true" value="a">Radio</ion-radio>
|
||||||
|
</ion-radio-group>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const radio = page.body.querySelector('ion-radio');
|
||||||
|
const radioGroup = page.body.querySelector('ion-radio-group');
|
||||||
|
|
||||||
|
expect(radioGroup.value).toBe(undefined);
|
||||||
|
|
||||||
|
radio.click();
|
||||||
|
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
expect(radioGroup.value).toBe(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -41,3 +41,24 @@ describe('toggle', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('ion-toggle: disabled', () => {
|
||||||
|
it('clicking disabled toggle should not toggle checked state', async () => {
|
||||||
|
const page = await newSpecPage({
|
||||||
|
components: [Toggle],
|
||||||
|
html: `
|
||||||
|
<ion-toggle disabled="true">Toggle</ion-toggle>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const toggle = page.body.querySelector('ion-toggle');
|
||||||
|
|
||||||
|
expect(toggle.checked).toBe(false);
|
||||||
|
|
||||||
|
toggle.click();
|
||||||
|
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
expect(toggle.checked).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -259,6 +259,10 @@ export class Toggle implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onClick = (ev: MouseEvent) => {
|
private onClick = (ev: MouseEvent) => {
|
||||||
|
if (this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
if (this.lastDrag + 300 < Date.now()) {
|
if (this.lastDrag + 300 < Date.now()) {
|
||||||
|
Reference in New Issue
Block a user