UNPKG

clever-onboarding

Version:

Framework agnostic onboarding widget for your web apps.

154 lines (128 loc) 3.25 kB
import style from "./Onboard.css"; import {select, selectAll} from "d3-selection"; import 'd3-transition'; /** * Renderes progress inside window * @param {OnboardOptions} options * @param {OnboardModel} model */ export default class ProgressRenderer { constructor(options, model) { /** * @private * Onboard options */ this._options = options; /** * @private * DOM container of this widget */ this._containerEl = null; /** * @private * true if Onboard has been rendered */ this._rendered = false; /** * @private * Model */ this._model = model; /** * @private * Steps */ this._steps = model.getSteps().filter(step=>step.showProgress !== false); /** * @private * Number of steps */ this._numOfSteps = this._steps.length; this._onStepBinding = this._model.on("step", this._onStep.bind(this)); this._onStartBinding = this._model.on("start", this._onStart.bind(this)); this._onStopBinding = this._model.on("stop", this._onStop.bind(this)); } _onStart(){ this._steps = this._model.getSteps().filter(step=>step.showProgress !== false); this._numOfSteps = this._steps.length; this._renderSteps(); } _onStop(){ // remove steps on stop this._progressEl.node().innerHTML = ""; } /** * Returns true if rendered * @returns {boolean} true if rendered */ isRendered() { return this._rendered; } /** * Renders ProgressRenderer instance * @param {String|HTMLElement} selector selector or DOM element * @returns {ProgressRenderer} returns this instance */ render(selector) { // get container element using selector or given element this._containerEl = select(selector); this._renderProgress(); this._renderSteps(); this._rendered = true; return this; } _renderProgress(){ this._progressEl = this._containerEl.append("div").classed(style["window-progress-ct"], true); } _renderSteps(){ this._steps.slice(1).forEach(()=>{ this._progressEl.append("div") .classed(style["window-progress-step"], true); }) } _resizeSteps(step){ var stepWidth = this._getStepWidth(step); selectAll("."+style["window-progress-step"]) .transition() .duration(this._options.animationDuration) .style("width", stepWidth + "px"); } _getStepWidth(step){ return (step.windowWidth || this._options.windowWidth) / this._numOfSteps; } _getProgressWidth(index, step){ return (step.windowWidth || this._options.windowWidth) * (index + 1) / this._numOfSteps; } /** * @private * Logic to render one step */ _onStep(step) { if (step.showProgress === false || this._steps.length < 2) { this._progressEl .transition() .duration(this._options.animationDuration) .style("width", 0+"px"); return; } var index = this._steps.indexOf(step); var width = this._getProgressWidth(index, step); this._progressEl .transition() .duration(this._options.animationDuration) .style("width", width+"px"); this._resizeSteps(step); } /** * Destorys this renderer */ destroy() { if (this._rendered){ this._progressEl.remove(); } this._onStartBinding.destroy(); this._onStepBinding.destroy(); this._onStopBinding.destroy(); return this; } }