UNPKG

hc-components-test

Version:

基于react的通用组件库

199 lines (181 loc) 4.79 kB
import React from 'react'; import PropTypes from 'prop-types'; import Joyride from 'react-joyride'; import localeContext from '../../localeContext'; import 'react-joyride/lib/react-joyride-compiled.css'; const types = ['continuous', 'single']; @localeContext('CustomForm', { back: '后退', close: '关闭', last: '完成', next: '下一个', skip: '跳过' }) export class Tour extends React.Component { static contextTypes = { history: PropTypes.object } static propTypes = { steps: PropTypes.object, type: PropTypes.bool, mask: PropTypes.bool, visible: PropTypes.bool } constructor(props, context) { super(props); this.state = { joyrideOverlay: props.mask || true, joyrideType: props.type || types[0], isRunning: props.visible || false, stepIndex: 0, steps: [], selector: '' }; this._defaultSteps = []; if (Array.isArray(props.steps)) { this.state.steps = props.steps; } else { if (this.props.steps.steps) { this._defaultSteps = this.props.steps.steps; } context .history .listen((location, action) => { if (action.location) { const step = this.props.steps[action.location.pathname]; if (step) { clearTimeout(this._timer); this._timer = setTimeout(() => { if (step.type) { this._switch(step.type, step.mask); } else { this.setState({joyrideType: types[0]}); } this.addSteps(step.steps, () => { if (step.tip) { this.addTooltip(step.tip); } }, step.action); }, 300); } else { if (this._defaultSteps[0] && document.querySelector(this._defaultSteps[0].selector)) { this.setState({steps: this._defaultSteps}); } } } }); } } componentDidMount() { if (this.props.visible !== false) { setTimeout(() => { if (!this.state.isRunning) { this.setState({steps: this._defaultSteps, isRunning: true}); } }, 1000); } } addSteps(steps, callback, action) { let newSteps = steps; if (!Array.isArray(newSteps)) { newSteps = [newSteps]; } if (!newSteps.length) { return; } if (action === 'replace') { this.setState({ isRunning: true, steps: newSteps }, callback); } else if (action === 'push') { // Force setState to be synchronous to keep step order. this.setState(currentState => { currentState.steps = currentState .steps .concat(newSteps); callback && callback(); return currentState; }); } else { let steps; let stepIndex = 0; if (action) { const idx = this ._defaultSteps .findIndex(item => item.tag === action); if (idx > -1) { stepIndex = idx + 1; steps = this ._defaultSteps .slice(0, idx + 1) .concat(newSteps) .concat(this._defaultSteps.slice(idx + 1)); } else { steps = newSteps.concat(this._defaultSteps); } } else { steps = this ._defaultSteps .concat(newSteps); } this.setState({ isRunning: true, stepIndex: stepIndex, steps: steps }, callback); } } addTooltip(data) { this ._joyride .addTooltip(data); } next() { this ._joyride .next(); } handleFocus = (e) => { this.setState({ selector: e.type === 'tooltip:before' ? e.step.selector : '' }); } _switch(type, mask) { if (type === types[0]) { this._joyride && this ._joyride .reset(); this.setState({isRunning: false, joyrideType: type, joyrideOverlay: mask}); clearTimeout(this._timer); this._timer = setTimeout(() => { this.setState({isRunning: true}); }, 300); } else { this.setState({joyrideType: type, joyrideOverlay: mask}); } } render() { const { isRunning, joyrideOverlay, joyrideType, selector, stepIndex, steps } = this.state; return (<Joyride ref={inst => (this._joyride = inst)} callback={this.handleFocus} debug={false} disableOverlay={selector === '.j-tour-ticket'} locale={this.getLocale()} run={isRunning} showOverlay={joyrideOverlay} showSkipButton={true} showStepsProgress={true} stepIndex={stepIndex} steps={steps} type={joyrideType} />); } }