@panoramax/web-viewer
Version:
Panoramax web viewer for geolocated pictures
148 lines (133 loc) • 3.63 kB
JavaScript
import { LitElement, html, css } from "lit";
import { QUALITYSCORE_VALUES } from "../../utils/utils";
/**
* Quality Score element displays the picture quality grade.
* @class Panoramax.components.ui.QualityScore
* @element pnx-quality-score
* @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
* @fires Panoramax.components.ui.QualityScore#change
* @example
* ```html
* <!-- Read-only -->
* <pnx-quality-score grade="5" ._t=${viewer._t} />
*
* <!-- Input -->
* <pnx-quality-score grade="5" input="pnx-qs-input" @change=${() => alert('changed')} ._t=${viewer._t} />
* ```
*/
export default class QualityScore extends LitElement {
/** @private */
static styles = css`
:host {
gap: 0px;
justify-content: center;
height: 2em;
font-size: 18px;
display: inline-flex;
align-items: center;
color: white;
}
/* Single letter */
span, label {
width: 1.2em;
height: 1.5em;
line-height: 1.5em;
display: inline-block;
border: 0.05em solid white;
text-align: center;
background-color: gray;
color: rgba(255,255,255,0.9);
font-family: var(--font-family);
font-weight: 800;
vertical-align: middle;
}
/* Rounded corners for first/last */
span:first-of-type, label:first-of-type {
border-top-left-radius: 0.4em;
border-bottom-left-radius: 0.4em;
}
span:last-of-type, label:last-of-type {
border-top-right-radius: 0.4em;
border-bottom-right-radius: 0.4em;
}
/* Selected letter */
.selected, input[type="checkbox"]:checked + label {
font-size: 1.3em;
height: 1.6em;
line-height: 1.6em;
border-radius: 0.3em ;
}
/* Clickable letter for input */
label { cursor: pointer; }
label:hover {
font-size: 1.2em;
height: 1.6em;
line-height: 1.6em;
border-radius: 0.3em ;
}
input[type="checkbox"] { display: none; }
`;
/**
* Component properties.
* @memberof Panoramax.components.ui.QualityScore#
* @type {Object}
* @property {number|string} [grade=0] The grade (5=A, 1=E, 0=none selected), or a list of grades
* @property {string} [input=false] If set, score is an input and value is used as ID prefix
*/
static properties = {
grade: {type: String},
input: {type: String},
};
constructor() {
super();
this.grade = 0;
this.input = false;
}
/** @private */
_onInput() {
// List all checked boxes
const newgrade = [];
for(let i of this.renderRoot.querySelectorAll("input")) {
if(i.checked) { newgrade.push(i.value); }
}
this.grade = newgrade.join(",");
/**
* Event for grade change
* @event Panoramax.components.ui.QualityScore#change
* @type {CustomEvent}
*/
this.dispatchEvent(new CustomEvent("change", {bubbles: true, composed: true}));
}
/** @private */
render() {
const grades = `${this.grade}`.split(",").map(v => parseInt(v)).filter(v => !isNaN(v));
if(this.input) {
return QUALITYSCORE_VALUES.map((pv, index) => {
return html`
<input
id="${this.input}-${pv.label}"
type="checkbox"
name="qualityscore"
value="${5-index}"
@change="${this._onInput}"
.checked=${grades.includes(5-index)}
/>
<label
for="${this.input}-${pv.label}"
title="${this._t?.pnx.filter_qualityscore_help}"
style="background-color: ${pv.color}"
>
${pv.label}
</label>
`;});
}
else {
return QUALITYSCORE_VALUES.map((pv, index) => html`
<span class="${grades.includes(5-index) ? "selected" : ""}" style="background-color: ${pv.color}">
${pv.label}
</span>
`);
}
}
}
customElements.define("pnx-quality-score", QualityScore);