Merge branch 'next' into metadata

This commit is contained in:
Cory LaViska
2021-06-25 19:40:12 -04:00
10 changed files with 174 additions and 42 deletions

View File

@@ -20,6 +20,7 @@ The docs have been updated to use `custom-elements.json`. If you're relying on t
- Added `sl-request-close` event to `sl-dialog` and `sl-drawer`
- Added `dialog.denyClose` and `drawer.denyClose` animations
- Fixed a bug in `sl-color-picker` where setting `value` immediately wouldn't trigger an update
- Fixed a bug that resulted in form controls having incorrect validity when `disabled` was initially set [#473](https://github.com/shoelace-style/shoelace/issues/473)
- Updated the docs to use the new `custom-elements.json` for component metadata
## 2.0.0-beta.44

View File

@@ -96,6 +96,15 @@ export default class SlCheckbox extends LitElement {
emit(this, 'sl-blur');
}
@watch('disabled')
handleDisabledChange() {
// Disabled form controls are always valid, so we need to recheck validity when the state changes
if (this.input) {
this.input.disabled = this.disabled;
this.invalid = !this.input.checkValidity();
}
}
handleFocus() {
this.hasFocus = true;
emit(this, 'sl-focus');

View File

@@ -0,0 +1,35 @@
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';
import '../../../dist/shoelace.js';
import type SlInput from './input';
describe('<sl-input>', () => {
it('should be disabled with the disabled attribute', async () => {
const el = await fixture(html` <sl-input disabled></sl-input> `);
const input = el.shadowRoot?.querySelector('[part="input"]') as HTMLInputElement;
expect(input.disabled).to.be.true;
});
it('should be valid by default', async () => {
const el = (await fixture(html` <sl-input></sl-input> `)) as SlInput;
expect(el.invalid).to.be.false;
});
it('should be invalid when required and empty', async () => {
const el = (await fixture(html` <sl-input required></sl-input> `)) as SlInput;
expect(el.invalid).to.be.true;
});
it('should be invalid when required and after removing disabled ', async () => {
const el = (await fixture(html` <sl-input disabled required></sl-input> `)) as SlInput;
el.disabled = false;
await el.updateComplete;
expect(el.invalid).to.be.true;
});
});

View File

@@ -204,28 +204,14 @@ export default class SlInput extends LitElement {
this.invalid = !this.input.checkValidity();
}
handleChange() {
this.value = this.input.value;
emit(this, 'sl-change');
}
handleInput() {
this.value = this.input.value;
emit(this, 'sl-input');
}
handleInvalid() {
this.invalid = true;
}
handleBlur() {
this.hasFocus = false;
emit(this, 'sl-blur');
}
handleFocus() {
this.hasFocus = true;
emit(this, 'sl-focus');
handleChange() {
this.value = this.input.value;
emit(this, 'sl-change');
}
handleClearClick(event: MouseEvent) {
@@ -238,6 +224,29 @@ export default class SlInput extends LitElement {
event.stopPropagation();
}
@watch('disabled')
handleDisabledChange() {
// Disabled form controls are always valid, so we need to recheck validity when the state changes
if (this.input) {
this.input.disabled = this.disabled;
this.invalid = !this.input.checkValidity();
}
}
handleFocus() {
this.hasFocus = true;
emit(this, 'sl-focus');
}
handleInput() {
this.value = this.input.value;
emit(this, 'sl-input');
}
handleInvalid() {
this.invalid = true;
}
handlePasswordToggle() {
this.isPasswordVisible = !this.isPasswordVisible;
}

View File

@@ -93,6 +93,11 @@ export default class SlRadio extends LitElement {
return this.getAllRadios().filter(radio => radio !== this) as this[];
}
handleBlur() {
this.hasFocus = false;
emit(this, 'sl-blur');
}
@watch('checked', { waitUntilFirstUpdate: true })
handleCheckedChange() {
if (this.checked) {
@@ -105,9 +110,13 @@ export default class SlRadio extends LitElement {
this.checked = true;
}
handleBlur() {
this.hasFocus = false;
emit(this, 'sl-blur');
@watch('disabled')
handleDisabledChange() {
// Disabled form controls are always valid, so we need to recheck validity when the state changes
if (this.input) {
this.input.disabled = this.disabled;
this.invalid = !this.input.checkValidity();
}
}
handleFocus() {

View File

@@ -131,6 +131,15 @@ export default class SlRange extends LitElement {
emit(this, 'sl-blur');
}
@watch('disabled')
handleDisabledChange() {
// Disabled form controls are always valid, so we need to recheck validity when the state changes
if (this.input) {
this.input.disabled = this.disabled;
this.invalid = !this.input.checkValidity();
}
}
handleFocus() {
this.hasFocus = true;
this.hasTooltip = true;

View File

@@ -186,6 +186,12 @@ export default class SlSelect extends LitElement {
if (this.disabled && this.isOpen) {
this.dropdown.hide();
}
// Disabled form controls are always valid, so we need to recheck validity when the state changes
if (this.input) {
this.input.disabled = this.disabled;
this.invalid = !this.input.checkValidity();
}
}
handleFocus() {

View File

@@ -86,13 +86,31 @@ export default class SlSwitch extends LitElement {
this.invalid = !this.input.checkValidity();
}
handleBlur() {
this.hasFocus = false;
emit(this, 'sl-blur');
}
@watch('checked')
handleCheckedChange() {
if (this.input) {
this.input.checked = this.checked;
this.invalid = !this.input.checkValidity();
emit(this, 'sl-change');
}
}
handleClick() {
this.checked = !this.checked;
}
handleBlur() {
this.hasFocus = false;
emit(this, 'sl-blur');
@watch('disabled')
handleDisabledChange() {
// Disabled form controls are always valid, so we need to recheck validity when the state changes
if (this.input) {
this.input.disabled = this.disabled;
this.invalid = !this.input.checkValidity();
}
}
handleFocus() {
@@ -118,15 +136,6 @@ export default class SlSwitch extends LitElement {
this.input.focus();
}
@watch('checked')
handleCheckedChange() {
if (this.input) {
this.input.checked = this.checked;
this.invalid = !this.input.checkValidity();
emit(this, 'sl-change');
}
}
render() {
return html`
<label

View File

@@ -0,0 +1,35 @@
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';
import '../../../dist/shoelace.js';
import type SlTextarea from './textarea';
describe('<sl-textarea>', () => {
it('should be disabled with the disabled attribute', async () => {
const el = await fixture(html` <sl-textarea disabled></sl-textarea> `);
const textarea = el.shadowRoot?.querySelector('[part="textarea"]') as HTMLInputElement;
expect(textarea.disabled).to.be.true;
});
it('should be valid by default', async () => {
const el = (await fixture(html` <sl-textarea></sl-textarea> `)) as SlTextarea;
expect(el.invalid).to.be.false;
});
it('should be invalid when required and empty', async () => {
const el = (await fixture(html` <sl-textarea required></sl-textarea> `)) as SlTextarea;
expect(el.invalid).to.be.true;
});
it('should be invalid when required and after removing disabled ', async () => {
const el = (await fixture(html` <sl-textarea disabled required></sl-textarea> `)) as SlTextarea;
el.disabled = false;
await el.updateComplete;
expect(el.invalid).to.be.true;
});
});

View File

@@ -215,27 +215,37 @@ export default class SlTextarea extends LitElement {
this.invalid = !this.input.checkValidity();
}
handleBlur() {
this.hasFocus = false;
emit(this, 'sl-blur');
}
handleChange() {
this.value = this.input.value;
this.setTextareaHeight();
emit(this, 'sl-change');
}
@watch('disabled')
handleDisabledChange() {
// Disabled form controls are always valid, so we need to recheck validity when the state changes
if (this.input) {
this.input.disabled = this.disabled;
this.invalid = !this.input.checkValidity();
}
}
handleFocus() {
this.hasFocus = true;
emit(this, 'sl-focus');
}
handleInput() {
this.value = this.input.value;
this.setTextareaHeight();
emit(this, 'sl-input');
}
handleBlur() {
this.hasFocus = false;
emit(this, 'sl-blur');
}
handleFocus() {
this.hasFocus = true;
emit(this, 'sl-focus');
}
@watch('rows')
handleRowsChange() {
this.setTextareaHeight();