205 lines
5.9 KiB
JavaScript
205 lines
5.9 KiB
JavaScript
/* eslint-disable import/no-extraneous-dependencies */
|
|
import { LitElement, nothing } from '@lion/core';
|
|
import { localize, LocalizeMixin } from '@lion/localize';
|
|
|
|
/**
|
|
* @typedef {import('@lion/core').TemplateResult} TemplateResult
|
|
*/
|
|
export class LionProgressIndicator extends LocalizeMixin(LitElement) {
|
|
static get properties() {
|
|
return {
|
|
value: {
|
|
type: Number,
|
|
},
|
|
min: {
|
|
type: Number,
|
|
},
|
|
max: {
|
|
type: Number,
|
|
},
|
|
_ariaLabel: { attribute: 'aria-label', type: String },
|
|
_ariaLabelledby: { attribute: 'aria-labelledby', type: String },
|
|
};
|
|
}
|
|
|
|
static get localizeNamespaces() {
|
|
return [
|
|
{
|
|
'lion-progress-indicator': /** @param {string} locale */ locale => {
|
|
switch (locale) {
|
|
case 'bg-BG':
|
|
case 'bg':
|
|
return import('@lion/progress-indicator/translations/bg.js');
|
|
case 'cs-CZ':
|
|
case 'cs':
|
|
return import('@lion/progress-indicator/translations/cs.js');
|
|
case 'de-DE':
|
|
case 'de':
|
|
return import('@lion/progress-indicator/translations/de.js');
|
|
case 'en-AU':
|
|
case 'en-GB':
|
|
case 'en-US':
|
|
case 'en-PH':
|
|
case 'en':
|
|
return import('@lion/progress-indicator/translations/en.js');
|
|
case 'es-ES':
|
|
case 'es':
|
|
return import('@lion/progress-indicator/translations/es.js');
|
|
case 'fr-BE':
|
|
case 'fr-FR':
|
|
case 'fr':
|
|
return import('@lion/progress-indicator/translations/fr.js');
|
|
case 'hu-HU':
|
|
case 'hu':
|
|
return import('@lion/progress-indicator/translations/hu.js');
|
|
case 'it-IT':
|
|
case 'it':
|
|
return import('@lion/progress-indicator/translations/it.js');
|
|
case 'nl-BE':
|
|
case 'nl-NL':
|
|
case 'nl':
|
|
return import('@lion/progress-indicator/translations/nl.js');
|
|
case 'pl-PL':
|
|
case 'pl':
|
|
return import('@lion/progress-indicator/translations/pl.js');
|
|
case 'ro-RO':
|
|
case 'ro':
|
|
return import('@lion/progress-indicator/translations/ro.js');
|
|
case 'ru-RU':
|
|
case 'ru':
|
|
return import('@lion/progress-indicator/translations/ru.js');
|
|
case 'sk-SK':
|
|
case 'sk':
|
|
return import('@lion/progress-indicator/translations/sk.js');
|
|
case 'uk-UA':
|
|
case 'uk':
|
|
return import('@lion/progress-indicator/translations/uk.js');
|
|
case 'zh-CN':
|
|
case 'zh':
|
|
return import('@lion/progress-indicator/translations/zh.js');
|
|
default:
|
|
return import('@lion/progress-indicator/translations/en.js');
|
|
}
|
|
},
|
|
},
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @readonly
|
|
* @type {boolean}
|
|
*/
|
|
get indeterminate() {
|
|
return !this.hasAttribute('value');
|
|
}
|
|
|
|
/**
|
|
* In case of a determinate progress-indicator it returns the progress percentage
|
|
* based on value, min & max.
|
|
* Could be used for styling inside the _graphicTemplate
|
|
*
|
|
* @example
|
|
* style="width: ${this._progressPercentage}%"
|
|
*/
|
|
get _progressPercentage() {
|
|
if (this.indeterminate) {
|
|
return undefined;
|
|
}
|
|
return ((this.value - this.min) / (this.max - this.min)) * 100;
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
this.value = 0;
|
|
this.min = 0;
|
|
this.max = 100;
|
|
this._ariaLabel = '';
|
|
this._ariaLabelledby = '';
|
|
this.__hasDefaultLabelSet = false;
|
|
}
|
|
|
|
/** @protected */
|
|
// eslint-disable-next-line class-methods-use-this
|
|
_graphicTemplate() {
|
|
return nothing;
|
|
}
|
|
|
|
render() {
|
|
return this._graphicTemplate();
|
|
}
|
|
|
|
connectedCallback() {
|
|
super.connectedCallback();
|
|
this.setAttribute('role', 'progressbar');
|
|
}
|
|
|
|
/**
|
|
* Update aria labels on state change.
|
|
* @param {import('@lion/core').PropertyValues } changedProperties
|
|
*/
|
|
updated(changedProperties) {
|
|
super.updated(changedProperties);
|
|
|
|
if (this.indeterminate) {
|
|
if (changedProperties.has('_ariaLabel') || changedProperties.has('_ariaLabelledby')) {
|
|
this._setDefaultLabel();
|
|
}
|
|
if (changedProperties.has('value')) {
|
|
this._resetAriaValueAttributes();
|
|
this._setDefaultLabel();
|
|
}
|
|
} else {
|
|
if (changedProperties.has('value')) {
|
|
if (!this.value || typeof this.value !== 'number') {
|
|
this.removeAttribute('value');
|
|
} else if (this.value < this.min) {
|
|
this.value = this.min;
|
|
this.setAttribute('aria-valuenow', this.min.toString());
|
|
} else if (this.value > this.max) {
|
|
this.value = this.max;
|
|
this.setAttribute('aria-valuenow', this.max.toString());
|
|
} else {
|
|
this.setAttribute('aria-valuenow', this.value.toString());
|
|
}
|
|
if (this.__hasDefaultLabelSet === true) {
|
|
this.removeAttribute('aria-label');
|
|
}
|
|
}
|
|
if (changedProperties.has('min')) {
|
|
this.setAttribute('aria-valuemin', this.min.toString());
|
|
if (this.value < this.min) {
|
|
this.value = this.min;
|
|
}
|
|
}
|
|
if (changedProperties.has('max')) {
|
|
this.setAttribute('aria-valuemax', this.max.toString());
|
|
if (this.value > this.max) {
|
|
this.value = this.max;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
onLocaleUpdated() {
|
|
super.onLocaleUpdated();
|
|
// only set default label for indeterminate
|
|
if (this.indeterminate) {
|
|
this._setDefaultLabel();
|
|
}
|
|
}
|
|
|
|
_resetAriaValueAttributes() {
|
|
this.removeAttribute('aria-valuenow');
|
|
this.removeAttribute('aria-valuemin');
|
|
this.removeAttribute('aria-valuemax');
|
|
}
|
|
|
|
_setDefaultLabel() {
|
|
if (this._ariaLabelledby) {
|
|
this.removeAttribute('aria-label');
|
|
} else if (!this._ariaLabel) {
|
|
this.setAttribute('aria-label', localize.msg('lion-progress-indicator:loading'));
|
|
this.__hasDefaultLabelSet = true;
|
|
}
|
|
}
|
|
}
|