Added title attribute (#1043)

* added title attribute

Fixes #1042

* added tests for title

* also some other tests

* clarify why title was added
This commit is contained in:
Bünyamin Eskiocak
2022-11-30 23:42:56 +03:00
committed by GitHub
parent 31e1f2fc59
commit 35aa56d334
12 changed files with 135 additions and 16 deletions

View File

@@ -23,6 +23,7 @@ describe('<sl-button>', () => {
it('default values are set correctly', async () => {
const el = await fixture<SlButton>(html` <sl-button>Button Label</sl-button> `);
expect(el.title).to.equal('');
expect(el.variant).to.equal('default');
expect(el.size).to.equal('medium');
expect(el.disabled).to.equal(false);
@@ -88,6 +89,13 @@ describe('<sl-button>', () => {
});
});
it('should have title if title attribute isset', async () => {
const el = await fixture<SlButton>(html` <sl-button title="Test"></sl-button> `);
const button = el.shadowRoot!.querySelector<HTMLButtonElement>('[part~="base"]')!;
expect(button.title).to.equal('Test');
});
describe('when loading', () => {
it('should have a spinner present', async () => {
const el = await fixture<SlButton>(html` <sl-button loading>Button Label</sl-button> `);

View File

@@ -98,6 +98,8 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
/** An optional value for the button. Ignored when `href` is set. */
@property() value = '';
@property() title = ''; // make reactive to pass through
/** When set, the underlying button will be rendered as an `<a>` with this `href` instead of a `<button>`. */
@property() href = '';
@@ -255,7 +257,7 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
})}
?disabled=${ifDefined(isLink ? undefined : this.disabled)}
type=${ifDefined(isLink ? undefined : this.type)}
title=${'' /* An empty title prevents browser validation tooltips from appearing on hover */}
title=${this.title /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${ifDefined(isLink ? undefined : this.name)}
value=${ifDefined(isLink ? undefined : this.value)}
href=${ifDefined(isLink ? this.href : undefined)}

View File

@@ -4,6 +4,31 @@ import sinon from 'sinon';
import type SlCheckbox from './checkbox';
describe('<sl-checkbox>', () => {
it('should pass accessibility tests', async () => {
const el = await fixture<SlCheckbox>(html` <sl-checkbox>Checkbox</sl-checkbox> `);
await expect(el).to.be.accessible();
});
it('default properties', async () => {
const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `);
expect(el.name).to.equal('');
expect(el.value).to.be.undefined;
expect(el.title).to.equal('');
expect(el.disabled).to.be.false;
expect(el.required).to.be.false;
expect(el.checked).to.be.false;
expect(el.indeterminate).to.be.false;
expect(el.defaultChecked).to.be.false;
});
it('should have title if title attribute isset', async () => {
const el = await fixture<SlCheckbox>(html` <sl-checkbox title="Test"></sl-checkbox> `);
const input = el.shadowRoot!.querySelector('input')!;
expect(input.title).to.equal('Test');
});
it('should be disabled with the disabled attribute', async () => {
const el = await fixture<SlCheckbox>(html` <sl-checkbox disabled></sl-checkbox> `);
const checkbox = el.shadowRoot!.querySelector('input')!;

View File

@@ -49,11 +49,13 @@ export default class SlCheckbox extends ShoelaceElement implements ShoelaceFormC
@state() invalid = false;
/** Name of the HTML form control. Submitted with the form as part of a name/value pair. */
@property() name: string;
@property() name = '';
/** Value of the HTML form control. Primarily used to differentiate a list of related checkboxes that have the same name. */
@property() value: string;
@property() title = ''; // make reactive to pass through
/** Disables the checkbox (so the user can't check / uncheck it). */
@property({ type: Boolean, reflect: true }) disabled = false;
@@ -150,8 +152,8 @@ export default class SlCheckbox extends ShoelaceElement implements ShoelaceFormC
<input
class="checkbox__input"
type="checkbox"
title=${'' /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${ifDefined(this.name)}
title=${this.title /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${this.name}
value=${ifDefined(this.value)}
.indeterminate=${live(this.indeterminate)}
.checked=${live(this.checked)}

View File

@@ -18,6 +18,7 @@ describe('<sl-input>', () => {
expect(el.name).to.equal('');
expect(el.value).to.equal('');
expect(el.defaultValue).to.equal('');
expect(el.title).to.equal('');
expect(el.filled).to.be.false;
expect(el.pill).to.be.false;
expect(el.label).to.equal('');
@@ -47,6 +48,13 @@ describe('<sl-input>', () => {
expect(isNaN(el.valueAsNumber)).to.be.true;
});
it('should have title if title attribute isset', async () => {
const el = await fixture<SlInput>(html` <sl-input title="Test"></sl-input> `);
const input = el.shadowRoot!.querySelector<HTMLInputElement>('[part~="input"]')!;
expect(input.title).to.equal('Test');
});
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"]')!;

View File

@@ -93,6 +93,8 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
/** The input's value attribute. */
@property() value = '';
@property() title = ''; // make reactive to pass through
/** Gets or sets the default value used to reset this element. The initial value corresponds to the one originally specified in the HTML that created this element. */
@defaultValue() defaultValue = '';
@@ -424,13 +426,12 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
<span part="prefix" class="input__prefix">
<slot name="prefix"></slot>
</span>
<input
part="input"
id="input"
class="input__control"
type=${this.type === 'password' && this.passwordVisible ? 'text' : this.type}
title=${'' /* An empty title prevents browser validation tooltips from appearing on hover */}
title=${this.title /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${ifDefined(this.name)}
?disabled=${this.disabled}
?readonly=${this.readonly}

View File

@@ -14,6 +14,7 @@ describe('<sl-range>', () => {
expect(el.name).to.equal('');
expect(el.value).to.equal(0);
expect(el.title).to.equal('');
expect(el.label).to.equal('');
expect(el.helpText).to.equal('');
expect(el.disabled).to.be.false;
@@ -25,6 +26,13 @@ describe('<sl-range>', () => {
expect(el.defaultValue).to.equal(0);
});
it('should have title if title attribute isset', async () => {
const el = await fixture<SlRange>(html` <sl-range title="Test"></sl-range> `);
const input = el.shadowRoot!.querySelector('input')!;
expect(input.title).to.equal('Test');
});
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"]')!;

View File

@@ -58,12 +58,14 @@ export default class SlRange extends ShoelaceElement implements ShoelaceFormCont
@state() private hasTooltip = false;
@state() invalid = false;
/** The input's name attribute. */
/** The range's name attribute. */
@property() name = '';
/** The input's value attribute. */
/** The range's value attribute. */
@property({ type: Number }) value = 0;
@property() title = ''; // make reactive to pass through
/** The range's label. If you need to display HTML, you can use the `label` slot instead. */
@property() label = '';
@@ -73,13 +75,13 @@ export default class SlRange extends ShoelaceElement implements ShoelaceFormCont
/** Disables the range. */
@property({ type: Boolean, reflect: true }) disabled = false;
/** The input's min attribute. */
/** The range's min attribute. */
@property({ type: Number }) min = 0;
/** The input's max attribute. */
/** The range's max attribute. */
@property({ type: Number }) max = 100;
/** The input's step attribute. */
/** The range's step attribute. */
@property({ type: Number }) step = 1;
/** The preferred placement of the tooltip. */
@@ -286,7 +288,7 @@ export default class SlRange extends ShoelaceElement implements ShoelaceFormCont
part="input"
id="input"
class="range__control"
title=${'' /* An empty title prevents browser validation tooltips from appearing on hover */}
title=${this.title /* An empty title prevents browser validation tooltips from appearing on hover */}
type="range"
name=${ifDefined(this.name)}
?disabled=${this.disabled}

View File

@@ -3,6 +3,30 @@ import { sendKeys } from '@web/test-runner-commands';
import type SlSwitch from './switch';
describe('<sl-switch>', () => {
it('should pass accessibility tests', async () => {
const el = await fixture<SlSwitch>(html` <sl-switch>Switch</sl-switch> `);
await expect(el).to.be.accessible();
});
it('default properties', async () => {
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
expect(el.name).to.equal('');
expect(el.value).to.be.undefined;
expect(el.title).to.equal('');
expect(el.disabled).to.be.false;
expect(el.required).to.be.false;
expect(el.checked).to.be.false;
expect(el.defaultChecked).to.be.false;
});
it('should have title if title attribute isset', async () => {
const el = await fixture<SlSwitch>(html` <sl-switch title="Test"></sl-switch> `);
const input = el.shadowRoot!.querySelector('input')!;
expect(input.title).to.equal('Test');
});
it('should be disabled with the disabled attribute', async () => {
const el = await fixture<SlSwitch>(html` <sl-switch disabled></sl-switch> `);
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;

View File

@@ -49,11 +49,13 @@ export default class SlSwitch extends ShoelaceElement implements ShoelaceFormCon
@state() invalid = false;
/** The switch's name attribute. */
@property() name: string;
@property() name = '';
/** The switch's value attribute. */
@property() value: string;
@property() title = ''; // make reactive to pass through
/** Disables the switch. */
@property({ type: Boolean, reflect: true }) disabled = false;
@@ -157,8 +159,8 @@ export default class SlSwitch extends ShoelaceElement implements ShoelaceFormCon
<input
class="switch__input"
type="checkbox"
title=${'' /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${ifDefined(this.name)}
title=${this.title /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${this.name}
value=${ifDefined(this.value)}
.checked=${live(this.checked)}
.disabled=${this.disabled}

View File

@@ -9,6 +9,41 @@ describe('<sl-textarea>', () => {
await expect(el).to.be.accessible();
});
it('default properties', async () => {
const el = await fixture<SlTextarea>(html` <sl-textarea></sl-textarea> `);
expect(el.size).to.equal('medium');
expect(el.name).to.equal('');
expect(el.value).to.equal('');
expect(el.defaultValue).to.equal('');
expect(el.title).to.equal('');
expect(el.filled).to.be.false;
expect(el.label).to.equal('');
expect(el.helpText).to.equal('');
expect(el.placeholder).to.equal('');
expect(el.rows).to.equal(4);
expect(el.resize).to.equal('vertical');
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.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;
});
it('should have title if title attribute isset', async () => {
const el = await fixture<SlTextarea>(html` <sl-textarea title="Test"></sl-textarea> `);
const textarea = el.shadowRoot!.querySelector('textarea')!;
expect(textarea.title).to.equal('Test');
});
it('should be disabled with the disabled attribute', async () => {
const el = await fixture<SlTextarea>(html` <sl-textarea disabled></sl-textarea> `);
const textarea = el.shadowRoot!.querySelector<HTMLTextAreaElement>('[part~="textarea"]')!;

View File

@@ -56,6 +56,8 @@ export default class SlTextarea extends ShoelaceElement implements ShoelaceFormC
/** The textarea's value attribute. */
@property() value = '';
@property() title = ''; // make reactive to pass through
/** Draws a filled textarea. */
@property({ type: Boolean, reflect: true }) filled = false;
@@ -310,7 +312,7 @@ export default class SlTextarea extends ShoelaceElement implements ShoelaceFormC
part="textarea"
id="input"
class="textarea__control"
title=${'' /* An empty title prevents browser validation tooltips from appearing on hover */}
title=${this.title /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${ifDefined(this.name)}
.value=${live(this.value)}
?disabled=${this.disabled}