catalog/ts_web/elements/consentsoftware-toggle.ts

128 lines
3.1 KiB
TypeScript
Raw Normal View History

import { LitElement, html, css, type TemplateResult } from 'lit';
import { customElement } from 'lit/decorators.js';
import { property } from 'lit/decorators/property.js';
import { delayFor } from '@push.rocks/smartdelay';
@customElement('consentsoftware-toggle')
export class ConsentsoftwareToggle extends LitElement {
public static demo = () => html`<consentsoftware-toggle></consentsoftware-toggle>`;
@property({ type: Boolean })
public required = false;
@property({ type: Boolean, reflect: true })
public selected = false;
public static styles = css`
:host {
display: block;
position: relative;
}
.label {
margin-bottom: 16px;
}
.toggleKnobArea {
cursor: pointer;
margin: auto;
height: 30px;
width: 60px;
border-radius: 20px;
background: rgba(255, 255, 255, 0.1);
position: relative;
overflow: hidden;
transition: all 0.2s;
border: 1px solid rgba(255, 255, 255, 0);
}
:host([selected]) .toggleKnobArea {
background: green;
}
.toggleKnobMover {
transition: all 0.2s;
}
.toggleKnobInner {
height: 30px;
width: 30px;
border-radius: 15px;
background: rgba(255, 255, 255, 0.5);
position: absolute;
top: 0;
left: 0;
transition: all 0.2s;
transform: scale(0.7);
}
:host([selected]) .toggleKnobInner {
background: white;
}
:host([required]) .toggleKnobArea {
background: none;
border: 1px solid rgba(255, 255, 255, 0.1);
}
:host([required]) .toggleKnobInner {
background: rgba(255, 255, 255, 0.1);
}
`;
constructor() {
super();
}
public render(): TemplateResult {
return html`
<div class="label">${this.getText()}</div>
<div class="toggle" @click=${this.handleClick}>
<div class="toggleKnobArea">
<div class="toggleKnobMover">
<div class="toggleKnobInner"></div>
</div>
</div>
</div>
`;
}
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
super.firstUpdated(_changedProperties);
if (this.required) {
this.selected = true;
this.syncSelection();
}
}
public async handleClick(mouseEvent) {
if (this.required) {
const moverElement: HTMLDivElement = this.shadowRoot.querySelector('.toggleKnobMover');
moverElement.style.transform = 'translateX(20px)';
await delayFor(250);
moverElement.style.transform = 'translateX(30px)';
return;
}
this.selected = !this.selected;
mouseEvent.stopPropagation();
mouseEvent.preventDefault();
this.syncSelection();
this.dispatchEvent(new CustomEvent('toggle', { detail: { selected: this.selected } }));
}
public async syncSelection() {
console.log(`Selected ${this.selected}`);
const moverElement: HTMLDivElement = this.shadowRoot.querySelector('.toggleKnobMover');
if (this.selected) {
moverElement.style.transform = 'translateX(30px)';
} else {
moverElement.style.transform = 'translateX(0px)';
}
}
public getText() {
return this.textContent;
}
}