feat(form-core): allow [label-sr-only] on FormControl

This commit is contained in:
Thijs Louisse 2022-03-15 18:47:17 +01:00
parent 1ae8f16ab7
commit 90b0d3b114
2 changed files with 58 additions and 0 deletions

View file

@ -43,6 +43,7 @@ const FormControlMixinImplementation = superclass =>
name: { type: String, reflect: true },
readOnly: { type: Boolean, attribute: 'readonly', reflect: true },
label: String, // FIXME: { attribute: false } breaks a bunch of tests, but shouldn't...
labelSrOnly: { type: Boolean, attribute: 'label-sr-only', reflect: true },
helpText: { type: String, attribute: 'help-text' },
modelValue: { attribute: false },
_ariaLabelledNodes: { attribute: false },
@ -186,6 +187,12 @@ const FormControlMixinImplementation = superclass =>
*/
this.label = '';
/**
* The label will only be visible for srceen readers when true
* @type {boolean}
*/
this.labelSrOnly = false;
/**
* The helpt text for the input node.
* When no value is defined, textContent of [slot=help-text] will be used
@ -699,6 +706,20 @@ const FormControlMixinImplementation = superclass =>
color: var(--disabled-text-color, #767676);
}
:host([label-sr-only]) .form-field__label {
position: absolute;
top: 0;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(100%);
clip: rect(1px, 1px, 1px, 1px);
white-space: nowrap;
border: 0;
margin: 0;
padding: 0;
}
/***********************
{block} .input-group
*********************/

View file

@ -80,6 +80,43 @@ describe('FormControlMixin', () => {
expect(el.label).to.equal('');
});
/**
* N.B. For platform controls, the same would be achieved with <input aria-label="My label">
* However, since FormControl is usually not the activeElement (_inputNode is), this
* will not have the desired effect on for instance lion-input
*/
it('supports "label-sr-only" to make label visually hidden, but accessible for screen reader users', async () => {
const el = /** @type {FormControlMixinClass} */ (
await fixture(html`
<${tag} label-sr-only>
<label slot="label">Email <span>address</span></label>
${inputSlot}
</${tag}>`)
);
const expectedValues = {
position: 'absolute',
top: '0px',
width: '1px',
height: '1px',
overflow: 'hidden',
clipPath: 'inset(100%)',
clip: 'rect(1px, 1px, 1px, 1px)',
whiteSpace: 'nowrap',
borderWidth: '0px',
margin: '0px',
padding: '0px',
};
const labelStyle = window.getComputedStyle(
// @ts-ignore
el.shadowRoot?.querySelector('.form-field__label'),
);
Object.entries(expectedValues).forEach(([key, val]) => {
expect(labelStyle[key]).to.equal(val);
});
});
it('can have a help-text', async () => {
const elAttr = /** @type {FormControlMixinClass} */ (
await fixture(html`