Improved accessibility (#118):
* channel configuration: adding title to inputs. * channel configuration: `aria-hidden="true"` on icons for add and remove row buttons.
This commit is contained in:
parent
944bdcebb7
commit
b673a49af6
@ -135,6 +135,7 @@ export function tplChannelConfiguration (el: ChannelConfigurationElement): Templ
|
||||
</livechat-configuration-section-header>
|
||||
<div class="form-group">
|
||||
<textarea
|
||||
.title=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_TERMS_LABEL) as any}
|
||||
name="terms"
|
||||
id="peertube-livechat-terms"
|
||||
.value=${el.channelConfiguration?.configuration.terms ?? ''}
|
||||
|
@ -6,6 +6,7 @@
|
||||
// This content comes from the file assets/images/plus-square.svg, from the Feather icons set https://feathericons.com/
|
||||
export const AddSVG: string =
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-plus-square">
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
||||
@ -15,6 +16,7 @@ export const AddSVG: string =
|
||||
// This content comes from the file assets/images/x-square.svg, from the Feather icons set https://feathericons.com/
|
||||
export const RemoveSVG: string =
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-x-square">
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
||||
|
@ -47,11 +47,11 @@ interface CellDataSchema {
|
||||
minlength?: number
|
||||
maxlength?: number
|
||||
size?: number
|
||||
label?: TemplateResult | string
|
||||
options?: { [key: string]: string }
|
||||
datalist?: DynamicTableAcceptedTypes[]
|
||||
separator?: string
|
||||
inputType?: DynamicTableAcceptedInputTypes
|
||||
inputTitle?: string
|
||||
default?: DynamicTableAcceptedTypes
|
||||
colClassList?: string[] // CSS classes to add to the <td> element.
|
||||
}
|
||||
@ -295,6 +295,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
const inputId =
|
||||
`peertube-livechat-${this.formName.replace(/_/g, '-')}-${propertyName.toString().replace(/_/g, '-')}-${rowId}`
|
||||
|
||||
const inputTitle: DirectiveResult | undefined = propertySchema.inputTitle ?? this.header[propertyName]?.colName
|
||||
const feedback = this._renderFeedback(inputId, propertyName, originalIndex)
|
||||
|
||||
switch (propertySchema.default?.constructor) {
|
||||
@ -320,6 +321,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderInput(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
propertyValue as string,
|
||||
@ -332,6 +334,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderTextarea(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
propertyValue as string,
|
||||
@ -344,6 +347,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderSelect(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
propertyValue as string,
|
||||
@ -356,6 +360,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderImageFileInput(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
propertyValue?.toString(),
|
||||
@ -376,6 +381,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderInput(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
(propertyValue as Date).toISOString(),
|
||||
@ -394,6 +400,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderInput(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
propertyValue as string,
|
||||
@ -411,6 +418,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderCheckbox(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
propertyValue as boolean,
|
||||
@ -446,6 +454,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderInput(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
(propertyValue)?.join(propertySchema.separator ?? ',') ??
|
||||
@ -461,6 +470,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderTextarea(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
(propertyValue)?.join(propertySchema.separator ?? ',') ??
|
||||
@ -476,6 +486,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
formElement = html`${this._renderTagsInput(rowId,
|
||||
inputId,
|
||||
inputName,
|
||||
inputTitle,
|
||||
propertyName,
|
||||
propertySchema,
|
||||
propertyValue,
|
||||
@ -501,6 +512,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
_renderInput = (rowId: number,
|
||||
inputId: string,
|
||||
inputName: string,
|
||||
inputTitle: string | DirectiveResult | undefined,
|
||||
propertyName: string,
|
||||
propertySchema: CellDataSchema,
|
||||
propertyValue: string,
|
||||
@ -515,6 +527,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
)
|
||||
)}
|
||||
id=${inputId}
|
||||
title=${ifDefined(inputTitle)}
|
||||
aria-describedby="${inputId}-feedback"
|
||||
list=${ifDefined(propertySchema.datalist ? inputId + '-datalist' : undefined)}
|
||||
min=${ifDefined(propertySchema.min)}
|
||||
@ -534,6 +547,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
_renderTagsInput = (rowId: number,
|
||||
inputId: string,
|
||||
inputName: string,
|
||||
inputTitle: string | DirectiveResult | undefined,
|
||||
propertyName: string,
|
||||
propertySchema: CellDataSchema,
|
||||
propertyValue: Array<string | number>,
|
||||
@ -547,7 +561,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
)
|
||||
)}
|
||||
id=${inputId}
|
||||
.inputPlaceholder=${propertySchema.label as any}
|
||||
.inputTitle=${inputTitle as any}
|
||||
aria-describedby="${inputId}-feedback"
|
||||
.min=${propertySchema.min}
|
||||
.max=${propertySchema.max}
|
||||
@ -563,6 +577,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
_renderTextarea = (rowId: number,
|
||||
inputId: string,
|
||||
inputName: string,
|
||||
inputTitle: string | DirectiveResult | undefined,
|
||||
propertyName: string,
|
||||
propertySchema: CellDataSchema,
|
||||
propertyValue: string,
|
||||
@ -576,6 +591,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
)
|
||||
)}
|
||||
id=${inputId}
|
||||
title=${ifDefined(inputTitle)}
|
||||
aria-describedby="${inputId}-feedback"
|
||||
min=${ifDefined(propertySchema.min)}
|
||||
max=${ifDefined(propertySchema.max)}
|
||||
@ -588,6 +604,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
_renderCheckbox = (rowId: number,
|
||||
inputId: string,
|
||||
inputName: string,
|
||||
inputTitle: string | DirectiveResult | undefined,
|
||||
propertyName: string,
|
||||
propertySchema: CellDataSchema,
|
||||
propertyValue: boolean,
|
||||
@ -602,6 +619,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
)
|
||||
)}
|
||||
id=${inputId}
|
||||
title=${ifDefined(inputTitle)}
|
||||
aria-describedby="${inputId}-feedback"
|
||||
@change=${(event: Event) => this._updatePropertyFromValue(event, propertyName, propertySchema, rowId)}
|
||||
value="1"
|
||||
@ -611,6 +629,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
_renderSelect = (rowId: number,
|
||||
inputId: string,
|
||||
inputName: string,
|
||||
inputTitle: string | DirectiveResult | undefined,
|
||||
propertyName: string,
|
||||
propertySchema: CellDataSchema,
|
||||
propertyValue: string,
|
||||
@ -623,11 +642,12 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
)
|
||||
)}
|
||||
id=${inputId}
|
||||
title=${ifDefined(inputTitle)}
|
||||
aria-describedby="${inputId}-feedback"
|
||||
aria-label=${inputName}
|
||||
@change=${(event: Event) => this._updatePropertyFromValue(event, propertyName, propertySchema, rowId)}
|
||||
>
|
||||
<option ?selected=${!propertyValue}>${propertySchema.label ?? 'Choose your option'}</option>
|
||||
<option ?selected=${!propertyValue}>${inputTitle ?? ''}</option>
|
||||
${Object.entries(propertySchema.options ?? {})
|
||||
?.map(([value, name]) =>
|
||||
html`<option ?selected=${propertyValue === value} value=${value}>${name}</option>`
|
||||
@ -638,6 +658,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
_renderImageFileInput = (rowId: number,
|
||||
inputId: string,
|
||||
inputName: string,
|
||||
inputTitle: string | DirectiveResult | undefined,
|
||||
propertyName: string,
|
||||
propertySchema: CellDataSchema,
|
||||
propertyValue: string,
|
||||
@ -647,6 +668,7 @@ export class DynamicTableFormElement extends LivechatElement {
|
||||
.name=${inputName}
|
||||
class=${classMap(this._getInputValidationClass(propertyName, originalIndex))}
|
||||
id=${inputId}
|
||||
.inputTitle=${inputTitle as any}
|
||||
aria-describedby="${inputId}-feedback"
|
||||
@change=${(event: Event) => this._updatePropertyFromValue(event, propertyName, propertySchema, rowId)}
|
||||
.value=${propertyValue}
|
||||
|
@ -1,11 +1,11 @@
|
||||
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { LivechatElement } from './livechat'
|
||||
import { html } from 'lit'
|
||||
import type { DirectiveResult } from 'lit/directive'
|
||||
import { customElement, property } from 'lit/decorators.js'
|
||||
|
||||
import { ifDefined } from 'lit/directives/if-defined.js'
|
||||
/**
|
||||
* Special element to upload image files.
|
||||
* If no current value, displays an input type="file" field.
|
||||
@ -29,13 +29,16 @@ export class ImageFileInputElement extends LivechatElement {
|
||||
@property({ attribute: false })
|
||||
public maxSize?: number
|
||||
|
||||
@property({ attribute: false })
|
||||
public inputTitle?: string | DirectiveResult
|
||||
|
||||
@property({ attribute: false })
|
||||
public accept: string[] = ['image/jpg', 'image/png', 'image/gif']
|
||||
|
||||
protected override render = (): unknown => {
|
||||
return html`
|
||||
${this.value
|
||||
? html`<img src=${this.value} @click=${(ev: Event) => {
|
||||
? html`<img src=${this.value} alt=${ifDefined(this.inputTitle)} @click=${(ev: Event) => {
|
||||
ev.preventDefault()
|
||||
const upload: HTMLInputElement | null | undefined = this.parentElement?.querySelector('input[type="file"]')
|
||||
upload?.click()
|
||||
@ -44,6 +47,7 @@ export class ImageFileInputElement extends LivechatElement {
|
||||
}
|
||||
<input
|
||||
type="file"
|
||||
title=${ifDefined(this.inputTitle)}
|
||||
accept="${this.accept.join(',')}"
|
||||
class="form-control"
|
||||
style=${this.value ? 'display: none;' : ''}
|
||||
|
@ -12,6 +12,7 @@ import { ifDefined } from 'lit/directives/if-defined.js'
|
||||
import { classMap } from 'lit/directives/class-map.js'
|
||||
import { animate, fadeOut, fadeIn } from '@lit-labs/motion'
|
||||
import { repeat } from 'lit/directives/repeat.js'
|
||||
import type { DirectiveResult } from 'lit/directive'
|
||||
|
||||
// FIXME: find a better way to store this image.
|
||||
// This content comes from the file assets/images/copy.svg, after svgo cleaning.
|
||||
@ -48,7 +49,7 @@ export class TagsInputElement extends LivechatElement {
|
||||
private _inputValue?: string = ''
|
||||
|
||||
@property({ attribute: false })
|
||||
public inputPlaceholder?: string = ''
|
||||
public inputTitle?: string | DirectiveResult = ''
|
||||
|
||||
@property({ attribute: false })
|
||||
public datalist?: string[]
|
||||
@ -166,7 +167,7 @@ export class TagsInputElement extends LivechatElement {
|
||||
@input=${(e: InputEvent) => this._handleInputEvent(e)}
|
||||
@change=${(e: Event) => e.stopPropagation()}
|
||||
.value=${this._inputValue ?? ''}
|
||||
placeholder=${ifDefined(this.inputPlaceholder)} />
|
||||
title=${ifDefined(this.inputTitle)} />
|
||||
${(this.datalist)
|
||||
? html`<datalist id="${this.id ?? 'tags-input'}-datalist">
|
||||
${(this.datalist ?? []).map((value) => html`<option value=${value}>`)}
|
||||
|
Loading…
Reference in New Issue
Block a user