/** * Copyright Aquera Inc 2023 * * This source code is licensed under the BSD-3-Clause license found in the * LICENSE file in the root directory of this source tree. */ import {LitElement, html, CSSResultArray, TemplateResult} from 'lit'; import { customElement, query, queryAll, property } from 'lit/decorators.js'; import {styles} from './nile-button-toggle-group.css'; import NileButtonToggle from '../nile-button-toggle/nile-button-toggle'; import NileElement from '../internal/nile-element'; /** * Nile icon component. * * @tag nile-button-toggle-group * */ @customElement('nile-button-toggle-group') export class NileButtonToggleGroup extends NileElement { /** * The styles for ButtonToggleGroup * @remarks If you are extending this class you can extend the base styles with super. Eg `return [super(), myCustomStyles]` */ public static get styles(): CSSResultArray { return [styles]; } @queryAll('nile-button-toggle') private toggles!: NodeListOf; @query('slot:not([name])') private defaultSlot!: HTMLSlotElement; @property({ type: Boolean, reflect: true }) public disabled: boolean = false; @property() value:String[]|String=''; @property({type:Boolean}) multiple:boolean=false; @property({type: Boolean}) disableUserInput: Boolean = false; @property({type:Boolean}) emptyDefault:boolean=false; firstUpdated() { this.defaultSlot.addEventListener('slotchange', () => this.updateTogglePositions() ); this.addEventListener('nile-toggle-change', this.handleToggle); this.updateTogglePositions(); if (!this.value) { if (!this.multiple) { const toggles = Array.from(this.querySelectorAll('nile-button-toggle')); const activeToggle = toggles.find(e => e.active && !e.disabled); if (activeToggle) this.value = activeToggle.value; else if(toggles.length && !this.emptyDefault && !this.disabled) this.value = toggles[0].value; else this.value = ''; } else this.value = []; } this.setBtnState() } updated(changedProperties: Map) { super.updated(changedProperties); if (changedProperties.has('disabled')) { this.updateDisabledState(); } if(changedProperties.has('multiple')){ if(!this.value) this.value=this.multiple?[]:'' this.setBtnState() } if(changedProperties.has('value')){ this.setBtnState() } } private updateDisabledState() { const assignedNodes = this.defaultSlot.assignedNodes({ flatten: true }); const toggles = assignedNodes.filter( node => node instanceof NileButtonToggle ) as NileButtonToggle[]; toggles.forEach(toggle => { if (!toggle.disabled) { toggle.disabled = this.disabled; } }); } updateTogglePositions() { const assignedNodes = this.defaultSlot.assignedNodes({ flatten: true }); const toggles = assignedNodes.filter( node => node instanceof NileButtonToggle ) as NileButtonToggle[]; toggles.forEach((toggle, index) => { toggle.initial = index === 0; toggle.middle = index > 0 && index < toggles.length - 1; toggle.end = index === toggles.length - 1; }); } handleToggle(event: CustomEvent) { event.stopPropagation() if (this.disabled) return; if(!this.multiple && event.detail.value == this.value) return; if(this.disableUserInput) return; this.setValue(event.detail.value); this.emit('nile-change', { value: this.value }); } setValue(btnValue:string){ if(this.multiple && btnValue){ // @ts-ignore if(this.value.includes(btnValue)) this.value=this.value.filter(e=>e!=btnValue) else this.value=[...this.value,btnValue] } else{ this.value=btnValue; } this.setBtnState() } setBtnState(){ const toggles = Array.from(this.querySelectorAll('nile-button-toggle')); if(this.multiple){ toggles.forEach(btn=>{ if(this.value.includes(btn.value)) btn.active=true; else btn.active=false; }) } else toggles.forEach(btn=>{ if(btn.value==this.value) btn.active=true; else btn.active=false; }) } /** * Render method * @slot This is a slot test */ public render(): TemplateResult { return html` `; } /* #endregion */ } export default NileButtonToggleGroup; declare global { interface HTMLElementTagNameMap { 'nile-button-toggle-group': NileButtonToggleGroup; } }