{"size": 4616, "ext": "js", "max_stars_repo_path": "base/walkthrough-player.js", "max_stars_repo_name": "salmanm/node-clinic-common", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "base/walkthrough-player.js", "max_issues_repo_name": "salmanm/node-clinic-common", "max_issues_repo_issues_event_min_datetime": "2020-11-24T22:43:25.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-23T01:22:54.000Z", "max_forks_repo_path": "base/walkthrough-player.js", "max_forks_repo_name": "salmanm/node-clinic-common", "max_forks_repo_forks_event_min_datetime": "2020-10-07T05:48:49.000Z", "max_forks_repo_forks_event_max_datetime": "2021-05-26T09:48:42.000Z"}
{"max_stars_count": null, "max_issues_count": 4, "max_forks_count": 3, "avg_line_length": 26.3771428571, "max_line_length": 88, "alphanum_fraction": 0.6399480069}
const button = require('./button.js')
const helpers = require('./helpers.js')
const ContextOverlay = require('./context-overlay.js')
const elHighlighter = require('./element-highlighter.js')

const chevronRight = require('../icons/chevron-right')
const chevronLeft = require('../icons/chevron-left')
const close = require('../icons/close')

const WtOverlay = new ContextOverlay()

class WalkthroughPlayer {
  constructor ({ steps = [], showBackdrop = false, showControls = true, onProgress }) {
    this.steps = steps
    this.showBackdrop = showBackdrop
    this.onProgress = onProgress
    this.currentStepIndex = undefined

    this.visible = false

    this.distanceFromElement = 5

    this.wrapper = document.createElement('div')
    this.wrapper.classList.add('nc-walkthrough-wrapper')

    this.content = document.createElement('div')
    this.content.classList.add('nc-walkthrough-content')

    this.wrapper.appendChild(this.content)

    this.wrapper.addEventListener('keyup', (event) => {
      if (event.code === 'Escape') {
        this.end()
      }
    })

    if (showControls) {
      this.wrapper.appendChild(button({
        classNames: ['closeBtn'],
        leftIcon: close,
        onClick: () => this.end()
      }))
      this.controls = document.createElement('div')
      this.controls.classList.add('nc-walkthrough-controls')

      this.prevBtn = button({
        leftIcon: chevronLeft,
        onClick: e => this.prev()
      })
      this.controls.appendChild(this.prevBtn)

      this.stepsWrapper = document.createElement('div')
      this.stepsWrapper.classList.add('nc-walkthrough-controls-steps')

      this.steps.forEach(s => {
        this.stepsWrapper.appendChild(helpers.toHtml('<span class="step"/>'))
      })
      this.controls.appendChild(this.stepsWrapper)

      this.nextBtn = button({
        classNames: ['nextBtn'],
        rightIcon: chevronRight,
        label: 'Next',
        onClick: e => this.next()
      })
      this.controls.appendChild(this.nextBtn)

      this.doneBtn = button({
        classNames: ['doneBtn'],
        label: 'Done!',
        onClick: e => this.end()
      })
      this.controls.appendChild(this.doneBtn)

      this.wrapper.appendChild(this.controls)
    }
  }

  start () {
    this.currentStepIndex = 0
    this._render()
  }

  next () {
    this.currentStepIndex++
    this._render()
  }

  prev () {
    this.currentStepIndex--
    this._render()
  }

  skipTo (index) {
    this.currentStepIndex = index
    this._render()
  }

  end () {
    this.visible = false
    WtOverlay.hide()
    this.currentStepIndex = undefined
    this._hideBackDrop()
    this.onProgress && this.onProgress(this.currentStepIndex)
  }

  _showBackDrop () {
    const step = this.steps[this.currentStepIndex]
    elHighlighter.show({
      element: document.querySelector(step.attachTo),
      padding: this.distanceFromElement - 2
    })
  }

  _hideBackDrop () {
    elHighlighter.hide()
  }

  _render () {
    this.currentStepIndex = Math.min(this.currentStepIndex, this.steps.length - 1)
    this.currentStepIndex = Math.max(this.currentStepIndex, 0)

    if (this.currentStepIndex < 0) this.currentStepIndex = 0

    const isDone = this.currentStepIndex === this.steps.length - 1

    this.wrapper.classList.toggle('done', isDone)

    if (this.currentStepIndex === 0) {
      this.prevBtn.style.visible = 'hidden'
    }

    if (this.showControls) {
      this.prev.setAttribute('disabled', this.currentStepIndex <= 0 ? true : null)
    }

    this.onProgress && this.onProgress(this.currentStepIndex)

    const step = this.steps[this.currentStepIndex]

    WtOverlay.show({
      classNames: ['wt-container', this.visible ? 'zoom-out' : ''],
      offset: { y: -this.distanceFromElement, height: this.distanceFromElement * 2 },
      targetElement: document.querySelector(step.attachTo),
      showArrow: true
    })

    setTimeout(() => {
      this.content.innerHTML = ''
      this.content.appendChild(helpers.toHtml(step.msg))
      this.prevBtn.style.visibility = this.currentStepIndex === 0 ? 'hidden' : 'visible'

      WtOverlay.updateContent({
        msg: this.wrapper,
        classNames: ['wt-container', 'zoom-in', `wt-step-${this.currentStepIndex}`]
      })
      if (isDone) {
        this.doneBtn.focus()
      } else {
        this.nextBtn.focus()
      }
    }, 300)

    Array.from(this.stepsWrapper.children).forEach((c, i) => {
      c.classList.toggle('current', i === this.currentStepIndex)
    })

    if (this.showBackdrop) this._showBackDrop()

    this.visible = true
  }
}

module.exports = WalkthroughPlayer
