mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 12:09:26 +00:00
Added stepUp, stepDown and showPicker functions (#1013)
* added stepUp and stepDown to sl-range * step function & default props tests for sl-range * stepUp, stepDown & showPicker functions for input * step functions & default props tests for sl-input * made name and placeholder default to empty string * updated changelog Co-authored-by: Cory LaViska <cory@abeautifulsite.net>
This commit is contained in:
committed by
GitHub
parent
bc6a813c46
commit
a706e69be6
@@ -10,6 +10,43 @@ describe('<sl-input>', () => {
|
||||
await expect(el).to.be.accessible();
|
||||
});
|
||||
|
||||
it('default properties', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input></sl-input> `);
|
||||
|
||||
expect(el.type).to.equal('text');
|
||||
expect(el.size).to.equal('medium');
|
||||
expect(el.name).to.equal('');
|
||||
expect(el.value).to.equal('');
|
||||
expect(el.defaultValue).to.equal('');
|
||||
expect(el.filled).to.be.false;
|
||||
expect(el.pill).to.be.false;
|
||||
expect(el.label).to.equal('');
|
||||
expect(el.helpText).to.equal('');
|
||||
expect(el.clearable).to.be.false;
|
||||
expect(el.passwordToggle).to.be.false;
|
||||
expect(el.passwordVisible).to.be.false;
|
||||
expect(el.noSpinButtons).to.be.false;
|
||||
expect(el.placeholder).to.equal('');
|
||||
expect(el.disabled).to.be.false;
|
||||
expect(el.readonly).to.be.false;
|
||||
expect(el.minlength).to.be.undefined;
|
||||
expect(el.maxlength).to.be.undefined;
|
||||
expect(el.min).to.be.undefined;
|
||||
expect(el.max).to.be.undefined;
|
||||
expect(el.step).to.be.undefined;
|
||||
expect(el.pattern).to.be.undefined;
|
||||
expect(el.required).to.be.false;
|
||||
expect(el.autocapitalize).to.be.undefined;
|
||||
expect(el.autocorrect).to.be.undefined;
|
||||
expect(el.autocomplete).to.be.undefined;
|
||||
expect(el.autofocus).to.be.undefined;
|
||||
expect(el.enterkeyhint).to.be.undefined;
|
||||
expect(el.spellcheck).to.be.undefined;
|
||||
expect(el.inputmode).to.be.undefined;
|
||||
expect(el.valueAsDate).to.be.null;
|
||||
expect(isNaN(el.valueAsNumber)).to.be.true;
|
||||
});
|
||||
|
||||
it('should be disabled with the disabled attribute', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input disabled></sl-input> `);
|
||||
const input = el.shadowRoot!.querySelector<HTMLInputElement>('[part~="input"]')!;
|
||||
@@ -208,5 +245,52 @@ describe('<sl-input>', () => {
|
||||
await el.updateComplete;
|
||||
expect(el.invalid).to.be.true;
|
||||
});
|
||||
|
||||
it('should increment by step if stepUp() is called', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input type="number" step="2" value="2"></sl-input> `);
|
||||
|
||||
el.stepUp();
|
||||
await el.updateComplete;
|
||||
expect(el.value).to.equal('4');
|
||||
});
|
||||
|
||||
it('should decrement by step if stepDown() is called', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input type="number" step="2" value="2"></sl-input> `);
|
||||
|
||||
el.stepDown();
|
||||
await el.updateComplete;
|
||||
expect(el.value).to.equal('0');
|
||||
});
|
||||
|
||||
it('should fire sl-input and sl-change if stepUp() is called', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input type="number" step="2" value="2"></sl-input> `);
|
||||
|
||||
const inputHandler = sinon.spy();
|
||||
const changeHandler = sinon.spy();
|
||||
el.addEventListener('sl-input', inputHandler);
|
||||
el.addEventListener('sl-change', changeHandler);
|
||||
|
||||
el.stepUp();
|
||||
|
||||
await waitUntil(() => inputHandler.calledOnce);
|
||||
await waitUntil(() => changeHandler.calledOnce);
|
||||
expect(inputHandler).to.have.been.calledOnce;
|
||||
expect(changeHandler).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('should fire sl-input and sl-change if stepDown() is called', async () => {
|
||||
const el = await fixture<SlInput>(html` <sl-input type="number" step="2" value="2"></sl-input> `);
|
||||
|
||||
const inputHandler = sinon.spy();
|
||||
const changeHandler = sinon.spy();
|
||||
el.addEventListener('sl-input', inputHandler);
|
||||
el.addEventListener('sl-change', changeHandler);
|
||||
|
||||
el.stepUp();
|
||||
|
||||
await waitUntil(() => inputHandler.calledOnce);
|
||||
await waitUntil(() => changeHandler.calledOnce);
|
||||
expect(changeHandler).to.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -88,7 +88,7 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/** The input's name attribute. */
|
||||
@property() name: string;
|
||||
@property() name = '';
|
||||
|
||||
/** The input's value attribute. */
|
||||
@property() value = '';
|
||||
@@ -121,7 +121,7 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
|
||||
@property({ attribute: 'no-spin-buttons', type: Boolean }) noSpinButtons = false;
|
||||
|
||||
/** The input's placeholder text. */
|
||||
@property() placeholder: string;
|
||||
@property() placeholder = '';
|
||||
|
||||
/** Disables the input. */
|
||||
@property({ type: Boolean, reflect: true }) disabled = false;
|
||||
@@ -247,6 +247,33 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
|
||||
}
|
||||
}
|
||||
|
||||
/** Displays the browser picker for an input element (only works if the browser supports it for the input type). */
|
||||
showPicker() {
|
||||
if ('showPicker' in HTMLInputElement.prototype) {
|
||||
this.input.showPicker();
|
||||
}
|
||||
}
|
||||
|
||||
/** Increments the value of a numeric input type by the value of the step attribute. */
|
||||
stepUp() {
|
||||
this.input.stepUp();
|
||||
if (this.value !== this.input.value) {
|
||||
this.value = this.input.value;
|
||||
this.emit('sl-input');
|
||||
this.emit('sl-change');
|
||||
}
|
||||
}
|
||||
|
||||
/** Decrements the value of a numeric input type by the value of the step attribute. */
|
||||
stepDown() {
|
||||
this.input.stepDown();
|
||||
if (this.value !== this.input.value) {
|
||||
this.value = this.input.value;
|
||||
this.emit('sl-input');
|
||||
this.emit('sl-change');
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks for validity but does not show the browser's validation message. */
|
||||
checkValidity() {
|
||||
return this.input.checkValidity();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
||||
import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
|
||||
import sinon from 'sinon';
|
||||
import { serialize } from '../../utilities/form';
|
||||
import type SlRange from './range';
|
||||
|
||||
@@ -8,6 +9,22 @@ describe('<sl-range>', () => {
|
||||
await expect(el).to.be.accessible();
|
||||
});
|
||||
|
||||
it('default properties', async () => {
|
||||
const el = await fixture<SlRange>(html` <sl-range></sl-range> `);
|
||||
|
||||
expect(el.name).to.equal('');
|
||||
expect(el.value).to.equal(0);
|
||||
expect(el.label).to.equal('');
|
||||
expect(el.helpText).to.equal('');
|
||||
expect(el.disabled).to.be.false;
|
||||
expect(el.invalid).to.be.false;
|
||||
expect(el.min).to.equal(0);
|
||||
expect(el.max).to.equal(100);
|
||||
expect(el.step).to.equal(1);
|
||||
expect(el.tooltip).to.equal('top');
|
||||
expect(el.defaultValue).to.equal(0);
|
||||
});
|
||||
|
||||
it('should be disabled with the disabled attribute', async () => {
|
||||
const el = await fixture<SlRange>(html` <sl-range disabled></sl-range> `);
|
||||
const input = el.shadowRoot!.querySelector<HTMLInputElement>('[part~="input"]')!;
|
||||
@@ -15,6 +32,44 @@ describe('<sl-range>', () => {
|
||||
expect(input.disabled).to.be.true;
|
||||
});
|
||||
|
||||
describe('step', () => {
|
||||
it('should increment by step if stepUp() is called', async () => {
|
||||
const el = await fixture<SlRange>(html` <sl-range step="2" value="2"></sl-range> `);
|
||||
|
||||
el.stepUp();
|
||||
await el.updateComplete;
|
||||
expect(el.value).to.equal(4);
|
||||
});
|
||||
|
||||
it('should decrement by step if stepDown() is called', async () => {
|
||||
const el = await fixture<SlRange>(html` <sl-range step="2" value="2"></sl-range> `);
|
||||
|
||||
el.stepDown();
|
||||
await el.updateComplete;
|
||||
expect(el.value).to.equal(0);
|
||||
});
|
||||
|
||||
it('should fire sl-change if stepUp() is called', async () => {
|
||||
const el = await fixture<SlRange>(html` <sl-range step="2" value="2"></sl-range> `);
|
||||
|
||||
const changeHandler = sinon.spy();
|
||||
el.addEventListener('sl-change', changeHandler);
|
||||
el.stepUp();
|
||||
await waitUntil(() => changeHandler.calledOnce);
|
||||
expect(changeHandler).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('should fire sl-change if stepDown() is called', async () => {
|
||||
const el = await fixture<SlRange>(html` <sl-range step="2" value="2"></sl-range> `);
|
||||
|
||||
const changeHandler = sinon.spy();
|
||||
el.addEventListener('sl-change', changeHandler);
|
||||
el.stepUp();
|
||||
await waitUntil(() => changeHandler.calledOnce);
|
||||
expect(changeHandler).to.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when serializing', () => {
|
||||
it('should serialize its name and value with FormData', async () => {
|
||||
const form = await fixture<HTMLFormElement>(html` <form><sl-range name="a" value="1"></sl-range></form> `);
|
||||
|
||||
@@ -123,6 +123,24 @@ export default class SlRange extends ShoelaceElement implements ShoelaceFormCont
|
||||
this.input.blur();
|
||||
}
|
||||
|
||||
/** Increments the value of the input by the value of the step attribute. */
|
||||
stepUp() {
|
||||
this.input.stepUp();
|
||||
if (this.value !== Number(this.input.value)) {
|
||||
this.value = Number(this.input.value);
|
||||
this.emit('sl-change');
|
||||
}
|
||||
}
|
||||
|
||||
/** Decrements the value of the input by the value of the step attribute. */
|
||||
stepDown() {
|
||||
this.input.stepDown();
|
||||
if (this.value !== Number(this.input.value)) {
|
||||
this.value = Number(this.input.value);
|
||||
this.emit('sl-change');
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks for validity but does not show the browser's validation message. */
|
||||
checkValidity() {
|
||||
return this.input.checkValidity();
|
||||
|
||||
@@ -51,7 +51,7 @@ export default class SlTextarea extends ShoelaceElement implements ShoelaceFormC
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/** The textarea's name attribute. */
|
||||
@property() name: string;
|
||||
@property() name = '';
|
||||
|
||||
/** The textarea's value attribute. */
|
||||
@property() value = '';
|
||||
@@ -66,7 +66,7 @@ export default class SlTextarea extends ShoelaceElement implements ShoelaceFormC
|
||||
@property({ attribute: 'help-text' }) helpText = '';
|
||||
|
||||
/** The textarea's placeholder text. */
|
||||
@property() placeholder: string;
|
||||
@property() placeholder = '';
|
||||
|
||||
/** The number of rows to display by default. */
|
||||
@property({ type: Number }) rows = 4;
|
||||
|
||||
4
src/declaration.d.ts
vendored
4
src/declaration.d.ts
vendored
@@ -10,3 +10,7 @@ declare namespace Chai {
|
||||
accessible: (options?: Object) => PromiseLike<Assertion>;
|
||||
}
|
||||
}
|
||||
|
||||
interface HTMLInputElement {
|
||||
showPicker: () => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user