import { DeesElement, customElement, html, css, unsafeCSS, cssManager, property, TemplateResult, } from '@designestate/dees-element'; import * as domtools from '@designestate/dees-domtools'; export interface IStep { title: string; content: TemplateResult; validationFunc?: (stepper: DeesStepper, htmlElement: HTMLElement) => Promise; validationFuncCalled?: boolean; } declare global { interface HTMLElementTagNameMap { 'dees-stepper': DeesStepper; } } @customElement('dees-stepper') export class DeesStepper extends DeesElement { public static demo = () => html` `; @property({ type: Array, }) public steps: IStep[] = [ { title: 'Whats your name?', content: html` Next `, }, { title: 'Whats your mobile number?', content: html``, }, { title: 'Whats the verification code?', content: html``, }, { title: 'Whats your new password?', content: html``, }, { title: 'Verification:', content: html``, }, ]; @property({ type: Object, }) public selectedStep: IStep; constructor() { super(); } public static styles = [ cssManager.defaultStyles, css` :host { position: absolute; width: 100%; height: 100%; } .stepperContainer { position: absolute; width: 100%; height: 100%; background: ${cssManager.bdTheme('#eeeeeb', '#000')}; overflow: hidden; } .step { position: relative; pointer-events: none; overflow: hidden; transition: all 0.7s ease-in-out; max-width: 500px; min-height: 300px; border-radius: 3px; background: ${cssManager.bdTheme('#ffffff', '#181818')}; color: ${cssManager.bdTheme('#333', '#fff')}; margin: auto; margin-bottom: 20px; filter: opacity(0.5) grayscale(1); box-shadow: 0px 0px 3px #00000010; } .step.selected { pointer-events: all; filter: opacity(1) grayscale(0); box-shadow: 0px 0px 5px #00000010; } .step.hiddenStep { filter: opacity(0); } .step .stepCounter { position: absolute; top: 0px; right: 0px; padding: 10px 15px; font-size: 12px; border-bottom-left-radius: 3px; background: ${cssManager.bdTheme('#00000008', '#ffffff08')}; } .step .goBack { position: absolute; top: 0px; left: 0px; padding: 10px 15px; font-size: 12px; border-bottom-right-radius: 3px; background: ${cssManager.bdTheme('#00000008', '#ffffff08')}; cursor: pointer; } .step .goBack:hover { background: ${cssManager.bdTheme('#00000012', '#ffffff12')}; } .step .title { text-align: center; padding-top: 50px; font-family: Roboto; font-size: 25px; font-weight: 300; } .step .content { padding: 20px; } `, ]; public render() { return html`
${this.steps.map( (stepArg) => html`
${this.getIndexOfStep(stepArg) > 0 ? html`
<- go to previous step
` : ``}
Step ${this.steps.findIndex(elementArg => elementArg === stepArg) + 1} of ${this.steps.length}
${stepArg.title}
${stepArg.content}
` )}
`; } public getIndexOfStep = (stepArg: IStep): number => { return this.steps.findIndex(stepArg2 => stepArg === stepArg2 ) } public firstUpdated() { this.selectedStep = this.steps[0]; this.setScrollStatus(); } public updated() { this.setScrollStatus(); } public scroller: typeof domtools.plugins.SweetScroll.prototype; public async setScrollStatus() { await domtools.plugins.smartdelay.delayFor(50); const stepperContainer: HTMLElement = this.shadowRoot.querySelector('.stepperContainer'); const firstStepElement: HTMLElement = this.shadowRoot.querySelector('.step'); const selectedStepElement: HTMLElement = this.shadowRoot.querySelector('.selected'); if (!stepperContainer.style.paddingTop) { stepperContainer.style.paddingTop = `${(stepperContainer.offsetHeight / 2) - (selectedStepElement.offsetHeight / 2)}px`; } console.log('Setting scroll status'); console.log(selectedStepElement); const scrollPosition = selectedStepElement.offsetTop - (stepperContainer.offsetHeight / 2) + (selectedStepElement.offsetHeight / 2) ; console.log(scrollPosition); const domtoolsInstance = await domtools.DomTools.setupDomTools() if (!this.scroller) { this.scroller = new domtools.plugins.SweetScroll({ vertical: true, horizontal: false, easing: 'easeInOutQuint' }, stepperContainer); } if (!this.selectedStep.validationFuncCalled && this.selectedStep.validationFunc) { this.selectedStep.validationFuncCalled = true; await this.selectedStep.validationFunc(this, selectedStepElement); } this.scroller.to(scrollPosition); } public goBack() { const currentIndex = this.steps.findIndex(stepArg => stepArg === this.selectedStep); this.selectedStep = this.steps[currentIndex - 1]; } public goNext() { const currentIndex = this.steps.findIndex(stepArg => stepArg === this.selectedStep); this.selectedStep = this.steps[currentIndex + 1]; } }