/** * 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, PropertyValueMap } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { styles } from './nile-stepper.css'; import NileElement from '../internal/nile-element'; import { watch } from '../internal/watch'; import { classMap } from 'lit/directives/class-map.js'; import { updateItemsInManualMode } from './stepper-utils'; /** * Nile stepper component. * * @tag nile-stepper * */ @customElement('nile-stepper') export class NileStepper extends NileElement { @property({ type: Boolean, attribute: 'vertical' }) isVertical: boolean = false; @property({ type: Boolean, attribute: true, reflect:true }) contentBelow: boolean = false; @property({ type: Number, attribute: true, reflect:true }) currentStep: number = 0; @property({ type: Number, attribute: true, reflect:true }) completedStep: number = 0; @property({ type: String, attribute: true, reflect:true }) size: 'sm' | 'lg' = 'lg'; @property({ type: String, attribute: true, reflect:true }) icon: string = 'tick'; @property({ type: Boolean, attribute: true, reflect:true }) manual: boolean = false; protected update(changedProperties: PropertyValueMap | Map): void{ super.update(changedProperties); if(changedProperties.has('currentStep') || changedProperties.has('completedStep') || changedProperties.has('manual')){ this.updateItems(); } } @watch('currentStep') handleCurrentStepChanges() { this.updateItems(); this.emit('nile-current-change', { value: this.currentStep }); } @watch('completedStep') handleCompletedStepChanges() { this.updateItems() this.emit('nile-completed-change', { value: this.completedStep }); } private updateItems() { const items: any = [...this.querySelectorAll(this.isVertical ? 'nile-vertical-stepper-item' : 'nile-stepper-item')]; if (!items.length) return; const haveFlex = items.length < 3; if (this.manual) { // Manual mode: use inline properties from each item updateItemsInManualMode(items, { icon: this.icon, size: this.size, contentBelow: this.contentBelow, manual: this.manual, isVertical: this.isVertical }, haveFlex); } else { // Automatic mode: use currentStep and completedStep properties const current = (this.currentStep == 0 || this.currentStep > items.length) ? 1 : this.currentStep; const calculatedCompleted = this.completedStep > items.length ? current : this.completedStep < current ? current : this.completedStep; const completed = this.completedStep > items.length ? 0 : this.completedStep; items.forEach((el: any, index: number) => { // set item is complete and is current values if (index + 1 < current) { el.isComplete = true; el.isCurrent = false; } else if (index + 1 == current) { if (index + 1 <= calculatedCompleted) el.isComplete = true; else el.isComplete = false; el.isCurrent = true; } else { if (index + 1 <= calculatedCompleted) el.isComplete = true; else el.isComplete = false; el.isCurrent = false; } // Reset and set isLast and isFirst el.isFirst = false; el.isLast = false; if (index == 0) el.isFirst = true; if (index == items.length - 1) el.isLast = true; // setting default values el.currentStepValue = current; el.calculatedCompletedStepValue = calculatedCompleted; el.completedStepValue = completed; el.icon = this.icon; el.size = this.size; el.value = index + 1; el.contentBelow = this.contentBelow; el.isManualMode = this.manual; if (index == 0 || index == items.length - 1) { el.haveFlex = haveFlex; } }); } } /** * The styles for nile-stepper * @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]; } /* #endregion */ /* #region Methods */ /** * Render method * @slot This is a slot test */ public render(): TemplateResult { return html`
`; } /* #endregion */ } export default NileStepper; declare global { interface HTMLElementTagNameMap { 'nile-stepper': NileStepper; } }