60 lines
1.5 KiB
Plaintext
60 lines
1.5 KiB
Plaintext
---
|
|
export interface Props {
|
|
checked?: boolean;
|
|
name?: string;
|
|
id: string;
|
|
}
|
|
|
|
const { checked = false, name = 'toggle', id} = Astro.props;
|
|
---
|
|
|
|
<toggle-switch data-checked={checked} data-name={name} id={id}>
|
|
<div class="toggle">
|
|
<div class="toggle-switch"></div>
|
|
</div>
|
|
</toggle-switch>
|
|
|
|
<script>
|
|
class ToggleSwitch extends HTMLElement {
|
|
private _checked: boolean = false;
|
|
|
|
connectedCallback() {
|
|
this._checked = this.dataset.checked === 'true';
|
|
this.updateUI();
|
|
|
|
this.querySelector('.toggle')?.addEventListener('click', () => {
|
|
this.toggle();
|
|
});
|
|
}
|
|
|
|
toggle() {
|
|
this._checked = !this._checked;
|
|
this.updateUI();
|
|
|
|
this.dispatchEvent(new CustomEvent('change', {
|
|
detail: { checked: this._checked, name: this.dataset.name },
|
|
bubbles: true,
|
|
composed: true,
|
|
}));
|
|
}
|
|
set checked(value: boolean) {
|
|
this._checked = value;
|
|
this.updateUI();
|
|
}
|
|
|
|
get checked() {
|
|
return this._checked;
|
|
}
|
|
|
|
private updateUI() {
|
|
this.dataset.checked = String(this._checked);
|
|
this.querySelector('.toggle')?.classList.toggle('toggle-active', this._checked);
|
|
}
|
|
}
|
|
|
|
customElements.define('toggle-switch', ToggleSwitch);
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@use './_toggle.scss';
|
|
</style> |