WIP et2-description for attribute to focus input and pass aria-label and -description, with fallbacks to statustext (label) and helpText (description)

--> screen-reader reads now the label for most input fields
This commit is contained in:
ralf 2024-04-25 21:05:15 +02:00
parent 6fb316a4fe
commit 6e84a75714
2 changed files with 49 additions and 5 deletions

View File

@ -12,12 +12,15 @@ import {css, html, LitElement, render} from "lit";
import {et2_IDetachedDOM} from "../et2_core_interfaces";
import {activateLinks} from "../ActivateLinksDirective";
import {et2_csvSplit} from "../et2_core_common";
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
export class Et2Description extends Et2Widget(LitElement) implements et2_IDetachedDOM
{
protected _value : string = "";
protected _forTarget : Et2InputWidget = null;
static get styles()
{
return [
@ -88,6 +91,7 @@ export class Et2Description extends Et2Widget(LitElement) implements et2_IDetach
type: String,
noAccessor: true
},
for: { type: String}
}
}
@ -110,6 +114,15 @@ export class Et2Description extends Et2Widget(LitElement) implements et2_IDetach
{
super.connectedCallback();
if (this.for)
{
this._forTarget = this.getRoot().getWidgetById(this.for);
if (this._forTarget)
{
this._forTarget.ariaLabel = this.value;
}
}
// Put content directly in DOM
if(this.value)
{
@ -149,6 +162,11 @@ export class Et2Description extends Et2Widget(LitElement) implements et2_IDetach
this._value = _value;
this.requestUpdate('value', oldValue);
if (this._forTarget)
{
this._forTarget.ariaLabel = this._value;
}
}
updated(changedProperties)
@ -225,11 +243,15 @@ export class Et2Description extends Et2Widget(LitElement) implements et2_IDetach
_handleClick(_ev : MouseEvent) : boolean
{
// call super to get the onclick handling running
super._handleClick(_ev);
if (super._handleClick(_ev) && !_ev.defaultPrevented && this._forTarget?.focus)
{
this._forTarget.focus();
_ev.preventDefault();
return false;
}
if(this.mimeData || this.href)
{
egw(window).open_link(this.mimeData || this.href, this.extraLinkTarget, this.extraLinkPopup, null, null, this.mime);
_ev.preventDefault();
return false;

View File

@ -142,7 +142,10 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
autocomplete: {
type: String
}
},
ariaLabel : String,
ariaDescription : String,
helpText : String,
};
}
@ -157,6 +160,9 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
return {
...super.translate,
placeholder: true,
ariaLabel : true,
ariaDescription : true,
helpText : true,
}
}
@ -247,6 +253,20 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
// Base off this.value, not this.getValue(), to ignore readonly
this.classList.toggle("hasValue", !(this.value == null || this.value == ""));
}
if (changedProperties.has('ariaLabel') || changedProperties.has('ariaDescription') ||
changedProperties.has("statustext") || changedProperties.has('helpText'))
{
const input = this.getInputNode();
if (input && (changedProperties.has('ariaLabel') || changedProperties.has("statustext")))
{
input.ariaLabel = this.ariaLabel || this.statustext;
}
if (input && (changedProperties.has('ariaDescription') || changedProperties.has('helpText')))
{
input.ariaDescription = this.ariaDescription || this.helpText;
}
}
}
/**
@ -498,10 +518,12 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
return ok;
}
/**
* Get input to e.g. set aria-attributes
*/
getInputNode()
{
// From LionInput
return this._inputNode;
return this.shadowRoot?.querySelector('input');
}
transformAttributes(attrs)