dees-catalog/ts_web/elements/dees-input-multitoggle.ts
2024-01-10 05:11:55 +01:00

116 lines
2.7 KiB
TypeScript

import {
customElement,
DeesElement,
type TemplateResult,
state,
html,
domtools,
property,
css,
cssManager,
} from '@design.estate/dees-element';
const { demoFunc } = await import('./dees-input-multitoggle.demo.js');
@customElement('dees-input-multitoggle')
export class DeesInputMultitoggle extends DeesElement {
public static demo = demoFunc;
@property()
type: 'boolean' | 'multi' | 'single' = 'multi';
@property()
booleanTrueName: string = 'true';
@property()
booleanFalseName: string = 'false';
@property({
type: Array,
})
options: string[] = [];
@property()
selectedOption: string = '';
@property()
boolValue: boolean = false;
public static styles = [
cssManager.defaultStyles,
css`
:host {
color: ${cssManager.bdTheme('#333', '#fff')};
user-select: none;
}
.selections {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
background: #333;
width: min-content;
border-radius: 20px;
height: 40px;
}
.option {
position: relative;
padding: 0px 16px;
line-height: 40px;
cursor: pointer;
width: min-content; /* Make the width as per the content */
white-space: nowrap; /* Prevent text wrapping */
}
.indicator {
opacity: 0;
position: absolute;
height: 32px;
left: 4px;
top: 4px;
border-radius: 16px;
background: #0050b9;
min-width: 36px;
}
`,
];
public render(): TemplateResult {
return html`
<div class="label">MultiSelect</div>
<div class="mainbox">
<div class="selections">
<div class="indicator"></div>
${this.options.map((option) => html` <div class="option" @click=${() => this.handleSelection(option)}>${option}</div> `)}
</div>
</div>
`;
}
public async firstUpdated() {
if (this.type === 'boolean') {
this.options = [this.booleanTrueName || 'true', this.booleanFalseName];
}
this.setIndicator();
}
public async handleSelection(optionArg: string) {
this.selectedOption = optionArg;
this.setIndicator();
}
public async setIndicator() {
const indicator: HTMLDivElement = this.shadowRoot.querySelector('.indicator');
const option: HTMLDivElement = this.shadowRoot.querySelector(`.option:nth-child(${this.options.indexOf(this.selectedOption) + 2})`);
if (indicator && option) {
indicator.style.width = `${option.clientWidth - 8}px`;
indicator.style.left = `${option.offsetLeft + 4}px`;
indicator.style.opacity = '1';
}
setTimeout(() => {
indicator.style.transition = 'all 0.1s';
}, 100);
}
}