Fix checked states

This commit is contained in:
Cory LaViska
2020-07-07 08:33:13 -04:00
parent dd99eabf10
commit 5ad4bbe5ba
6 changed files with 69 additions and 37 deletions

View File

@@ -7,9 +7,12 @@ Radios...
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
```html preview
<sl-radio>Default</sl-radio><br />
<sl-radio checked>Checked</sl-radio><br />
<sl-radio disabled>Disabled</sl-radio><br />
<sl-radio name="my-radio">Default 1</sl-radio><br />
<sl-radio name="my-radio">Default 2</sl-radio><br />
<sl-radio name="my-radio">Default 3</sl-radio><br />
<sl-radio name="my-radio">Default 4</sl-radio><br />
<sl-radio name="my-radio" checked>Checked</sl-radio><br />
<sl-radio name="my-radio" disabled>Disabled</sl-radio><br />
```
[component-metadata:sl-radio]

6
src/components.d.ts vendored
View File

@@ -1170,7 +1170,7 @@ declare namespace LocalJSX {
*/
"onSlBlur"?: (event: CustomEvent<any>) => void;
/**
* Emitted when the control's state changes.
* Emitted when the control's checked state changes.
*/
"onSlChange"?: (event: CustomEvent<any>) => void;
/**
@@ -1619,7 +1619,7 @@ declare namespace LocalJSX {
*/
"onSlBlur"?: (event: CustomEvent<any>) => void;
/**
* Emitted when the control's state changes.
* Emitted when the control's checked state changes.
*/
"onSlChange"?: (event: CustomEvent<any>) => void;
/**
@@ -1751,7 +1751,7 @@ declare namespace LocalJSX {
*/
"onSlBlur"?: (event: CustomEvent<any>) => void;
/**
* Emitted when the control's state changes.
* Emitted when the control's checked state changes.
*/
"onSlChange"?: (event: CustomEvent<any>) => void;
/**

View File

@@ -46,15 +46,18 @@ export class Checkbox {
/** Emitted when the control loses focus. */
@Event() slBlur: EventEmitter;
/** Emitted when the control's state changes. */
/** Emitted when the control's checked state changes. */
@Event() slChange: EventEmitter;
/** Emitted when the control gains focus. */
@Event() slFocus: EventEmitter;
@Watch('checked')
@Watch('indeterminate')
handleIndeterminateChange() {
handleCheckedChange() {
this.input.checked = this.checked;
this.input.indeterminate = this.indeterminate;
this.slChange.emit();
}
componentDidLoad() {
@@ -73,15 +76,9 @@ export class Checkbox {
this.input.blur();
}
handleClick(event: MouseEvent) {
const slChange = this.slChange.emit();
if (slChange.defaultPrevented) {
event.preventDefault();
} else {
this.checked = this.input.checked;
this.indeterminate = this.input.indeterminate;
}
handleClick() {
this.checked = this.input.checked;
this.indeterminate = this.input.indeterminate;
}
handleBlur() {

View File

@@ -43,7 +43,7 @@
input[type='radio'] {
position: absolute;
opacity: 1;
opacity: 0;
padding: 0;
margin: 0;
pointer-events: none;

View File

@@ -1,4 +1,4 @@
import { Component, Element, Event, EventEmitter, Method, Prop, State, h } from '@stencil/core';
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
let id = 0;
@@ -19,6 +19,7 @@ export class Radio {
this.handleClick = this.handleClick.bind(this);
this.handleBlur = this.handleBlur.bind(this);
this.handleFocus = this.handleFocus.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleMouseDown = this.handleMouseDown.bind(this);
}
@@ -42,10 +43,19 @@ export class Radio {
/** Set to true to draw the radio in a checked state. */
@Prop({ mutable: true }) checked = false;
@Watch('checked')
handleCheckedChange() {
if (this.checked) {
this.getSiblingRadios().map(radio => (radio.checked = false));
}
this.input.checked = this.checked;
this.slChange.emit();
}
/** Emitted when the control loses focus. */
@Event() slBlur: EventEmitter;
/** Emitted when the control's state changes. */
/** Emitted when the control's checked state changes. */
@Event() slChange: EventEmitter;
/** Emitted when the control gains focus. */
@@ -63,14 +73,19 @@ export class Radio {
this.input.blur();
}
handleClick(event: MouseEvent) {
const slChange = this.slChange.emit();
getAllRadios() {
const form = this.host.closest('sl-form, form') || document.body;
return [...form.querySelectorAll('sl-radio')].filter(
(radio: HTMLSlRadioElement) => radio.name === this.name
) as HTMLSlRadioElement[];
}
if (slChange.defaultPrevented) {
event.preventDefault();
} else {
this.checked = this.input.checked;
}
getSiblingRadios() {
return this.getAllRadios().filter(radio => radio !== this.host) as HTMLSlRadioElement[];
}
handleClick() {
this.checked = this.input.checked;
}
handleBlur() {
@@ -83,6 +98,22 @@ export class Radio {
this.slFocus.emit();
}
handleKeyDown(event: KeyboardEvent) {
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
const radios = this.getAllRadios().filter(radio => !radio.disabled);
const incr = ['ArrowUp', 'ArrowLeft'].includes(event.key) ? -1 : 1;
let index = radios.indexOf(this.host) + incr;
if (index < 0) index = radios.length - 1;
if (index > radios.length - 1) index = 0;
this.getAllRadios().map(radio => (radio.checked = false));
radios[index].setFocus();
radios[index].checked = true;
event.preventDefault();
}
}
handleMouseDown(event: MouseEvent) {
// Prevent clicks on the label from briefly blurring the input
event.preventDefault();
@@ -100,6 +131,7 @@ export class Radio {
'radio--disabled': this.disabled,
'radio--focused': this.hasFocus
}}
onKeyDown={this.handleKeyDown}
onMouseDown={this.handleMouseDown}
>
<span class="radio__control">

View File

@@ -1,4 +1,4 @@
import { Component, Event, EventEmitter, Method, Prop, State, h } from '@stencil/core';
import { Component, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
let id = 0;
@@ -42,10 +42,16 @@ export class Switch {
/** Set to true to draw the switch in a checked state. */
@Prop({ mutable: true }) checked = false;
@Watch('checked')
handleCheckedChange() {
this.input.checked = this.checked;
this.slChange.emit();
}
/** Emitted when the control loses focus. */
@Event() slBlur: EventEmitter;
/** Emitted when the control's state changes. */
/** Emitted when the control's checked state changes. */
@Event() slChange: EventEmitter;
/** Emitted when the control gains focus. */
@@ -63,14 +69,8 @@ export class Switch {
this.input.blur();
}
handleClick(event: MouseEvent) {
const slChange = this.slChange.emit();
if (slChange.defaultPrevented) {
event.preventDefault();
} else {
this.checked = this.input.checked;
}
handleClick() {
this.checked = this.input.checked;
}
handleBlur() {