diff --git a/jest.config.js b/jest.config.js
index 3b15cb6f7..0e1ad9d3f 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -24,6 +24,7 @@ const refactoredComp = [
'Dropdown',
'Input',
'ImageLoader',
+ 'Guide',
];
const getRefactoredCompMatch = name => {
diff --git a/source/components/Guide/Guide.tsx b/source/components/Guide/Guide.tsx
new file mode 100644
index 000000000..5034fb656
--- /dev/null
+++ b/source/components/Guide/Guide.tsx
@@ -0,0 +1,80 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import GuideFixed from './GuideFixed';
+import GuideNormal from './GuideNormal';
+import ConfigConsumer from '../Config/Consumer';
+import { LocaleProperties } from '../Locale';
+
+export interface GuideProps {
+ allowClose?: boolean;
+ className?: string;
+ counter?: boolean;
+ keyboardControl?: boolean;
+ mask?: boolean;
+ mode?: string;
+ onClose?: () => void;
+ steps?: any[];
+ style?: React.CSSProperties;
+ visible?: boolean;
+ prefixCls?: string;
+ doneBtnText?: string;
+ prevBtnText?: string;
+ nextBtnText?: string;
+ skipBtnText?: string;
+}
+
+const Guide = (props: GuideProps) => {
+ return (
+
+ {(Locale: LocaleProperties['Guide']) => {
+ const btnTextProps = {
+ prevBtnText: props.prevBtnText || Locale.prevBtnText,
+ nextBtnText: props.nextBtnText || Locale.nextBtnText,
+ doneBtnText: props.doneBtnText || Locale.doneBtnText,
+ skipBtnText: props.skipBtnText || Locale.skipBtnText,
+ };
+ const childrenProps = {
+ ...props,
+ ...btnTextProps,
+ };
+ const { mode } = props;
+ if (mode === 'fixed') {
+ return ;
+ } else {
+ return ;
+ }
+ }}
+
+ );
+};
+
+Guide.propTypes = {
+ prefixCls: PropTypes.string,
+ className: PropTypes.string,
+ style: PropTypes.object,
+ mode: PropTypes.string,
+ steps: PropTypes.array.isRequired,
+ visible: PropTypes.bool,
+ counter: PropTypes.bool,
+ mask: PropTypes.bool,
+ allowClose: PropTypes.bool,
+ keyboardControl: PropTypes.bool,
+ onClose: PropTypes.func,
+ doneBtnText: PropTypes.string,
+ prevBtnText: PropTypes.string,
+ nextBtnText: PropTypes.string,
+ skipBtnText: PropTypes.string,
+};
+
+Guide.defaultProps = {
+ prefixCls: 'fishd-guide',
+ mode: 'normal',
+ allowClose: false,
+ keyboardControl: false,
+ visible: false,
+ counter: true,
+ mask: true,
+ steps: [],
+};
+
+export default Guide;
diff --git a/source/components/Guide/GuideFixed.tsx b/source/components/Guide/GuideFixed.tsx
new file mode 100644
index 000000000..0640368d2
--- /dev/null
+++ b/source/components/Guide/GuideFixed.tsx
@@ -0,0 +1,152 @@
+import * as React from 'react';
+import classNames from 'classnames';
+import Modal from '../Modal';
+import Button from '../Button';
+import useUpdateEffect from '../../hooks/useUpdateEffect';
+import { GuideProps } from './Guide';
+import { ESC_KEY_CODE, LEFT_KEY_CODE, RIGHT_KEY_CODE } from './src/common/constants';
+
+const GuideFixed = (props: GuideProps) => {
+ const totalCountRef = React.useRef(props.steps.length);
+ const totalCount = totalCountRef.current;
+ const [visible, setVisible] = React.useState(props.visible);
+ const [currentIndex, setCurrentIndex] = React.useState(0);
+
+ const handleClose = () => {
+ Promise.resolve()
+ .then(() => {
+ setVisible(false);
+ })
+ .then(() => {
+ setCurrentIndex(0);
+ });
+
+ props.onClose?.();
+ };
+
+ const handleNext = () => {
+ if (currentIndex >= totalCount - 1) {
+ handleClose();
+ } else {
+ const nextIndex = currentIndex + 1;
+ setCurrentIndex(nextIndex);
+ }
+ };
+
+ const handlePrev = () => {
+ let nextIndex;
+
+ if (currentIndex <= 0) {
+ nextIndex = 0;
+ } else {
+ nextIndex = currentIndex - 1;
+ }
+
+ setCurrentIndex(nextIndex);
+ };
+
+ const onKeyUp = event => {
+ if (!props.keyboardControl || !visible) {
+ return;
+ }
+
+ if (event.keyCode === ESC_KEY_CODE) {
+ handleClose();
+ return;
+ }
+
+ if (event.keyCode === RIGHT_KEY_CODE) {
+ handleNext();
+ } else if (event.keyCode === LEFT_KEY_CODE) {
+ handlePrev();
+ }
+ };
+
+ React.useEffect(() => {
+ window.addEventListener('keyup', onKeyUp, false);
+ return () => {
+ window.removeEventListener('keyup', onKeyUp);
+ };
+ }, [onKeyUp]);
+
+ useUpdateEffect(() => {
+ if (!visible && props.visible) {
+ setVisible(true);
+ }
+ }, [props]);
+
+ const renderTitle = curStep => {
+ if (!curStep.title) {
+ return null;
+ }
+
+ if (curStep.subtitle) {
+ return (
+
+ {curStep.title}
+ {curStep.subtitle}
+
+ );
+ } else {
+ return curStep.title;
+ }
+ };
+
+ const {
+ prefixCls,
+ allowClose,
+ mask,
+ className,
+ style,
+ steps,
+ skipBtnText,
+ prevBtnText,
+ nextBtnText,
+ doneBtnText,
+ } = props;
+ const rootCls = classNames(`${prefixCls}-fixed`, {
+ [className]: className,
+ });
+ const isFirstStep = currentIndex <= 0;
+ const isLastStep = currentIndex >= totalCount - 1;
+
+ return (
+
+
+ {skipBtnText}
+
+ {isFirstStep ? null : (
+
+ )}
+
+
+ }
+ onCancel={handleClose}
+ >
+ {steps[currentIndex].content}
+
+ );
+};
+
+export default GuideFixed;
diff --git a/source/components/Guide/GuideNormal.tsx b/source/components/Guide/GuideNormal.tsx
new file mode 100644
index 000000000..e95663a55
--- /dev/null
+++ b/source/components/Guide/GuideNormal.tsx
@@ -0,0 +1,85 @@
+import * as React from 'react';
+import Driver from './src/index';
+import useUpdateEffect from '../../hooks/useUpdateEffect';
+import { GuideProps } from './Guide';
+
+const GuideNormal = (props: GuideProps) => {
+ const [visible, setVisible] = React.useState(props.visible);
+
+ const handleCloseRef = React.useRef<() => void>();
+ handleCloseRef.current = () => {
+ setVisible(false);
+
+ props.onClose?.();
+ };
+
+ const driver: Driver = React.useMemo(() => {
+ let opt = {
+ counter: props.counter,
+ allowClose: props.allowClose,
+ keyboardControl: props.keyboardControl,
+ prevBtnText: props.prevBtnText,
+ nextBtnText: props.nextBtnText,
+ skipBtnText: props.skipBtnText,
+ doneBtnText: props.doneBtnText,
+ onReset: () => {
+ const handleClose = handleCloseRef.current;
+ handleClose?.();
+ },
+ };
+
+ if (!props.mask) {
+ opt['opacity'] = 0;
+ }
+
+ return new Driver(opt);
+ }, []);
+
+ const init = () => {
+ let { steps } = props;
+
+ if (!(steps && steps.length)) {
+ return;
+ }
+
+ setTimeout(() => {
+ if (steps.length == 1) {
+ driver.highlight(steps[0]);
+ } else {
+ driver.defineSteps(props.steps);
+ driver.start();
+ }
+ }, 300);
+ };
+
+ React.useEffect(() => {
+ if (!visible) {
+ return;
+ }
+
+ init();
+ }, []);
+
+ /*
+ 重构前,visible 字段没有被设计成受控属性
+ 外部想要重新打开 Guide 组件,是通过重新 setState visible 为 true,
+ Guide 组件内部 componentWillReceiveProps 判断组件内部 visible 为 false
+ 且 nextProps.visible 为 true 时,进行重新初始化
+
+ 这里存在隐患,Guide 组件内部 visible 变为 false 时,
+ 因为 visible 不受控,外部 visible 还是 true,
+ 此时除 visible 外其他的 props 改变,
+ componentWillReceiveProps 内也会执行重新初始化的逻辑,弹出 Guide 组件
+ 重构成 hooks 之后,暂时和重构前保持一致的逻辑
+ */
+ useUpdateEffect(() => {
+ if (!visible && props.visible) {
+ setVisible(true);
+ init();
+ }
+ }, [props]);
+
+ return null;
+};
+
+export default GuideNormal;
diff --git a/source/components/Guide/__tests__/index.test.tsx b/source/components/Guide/__tests__/index.test.tsx
new file mode 100644
index 000000000..589eb3247
--- /dev/null
+++ b/source/components/Guide/__tests__/index.test.tsx
@@ -0,0 +1,322 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import Guide from '../index';
+import { ESC_KEY_CODE, LEFT_KEY_CODE, RIGHT_KEY_CODE } from '../src/common/constants';
+import { act } from 'react-dom/test-utils';
+
+describe('Guide', () => {
+ describe('fixed mode', () => {
+ const steps = [
+ {
+ title: '标题 1',
+ subtitle: '春眠不觉晓,处处闻啼鸟。夜来风雨声,花落知多少。',
+ content: (
+
+ ),
+ },
+ {
+ title: '标题 2',
+ content: (
+
+ ),
+ },
+ {
+ content: (
+
+ ),
+ },
+ ];
+
+ it('should support onClose', () => {
+ const onClose = jest.fn();
+ const wrapper = mount(
+ ,
+ );
+ const skipBtn = wrapper.find('.skip').at(0);
+ skipBtn.simulate('click');
+ expect(onClose).toHaveBeenCalledTimes(1);
+
+ wrapper.setProps({ visible: true });
+ wrapper.update();
+
+ const nextBtn = wrapper.find('.fishd-guide-next-btn').at(0);
+ nextBtn.simulate('click');
+ nextBtn.simulate('click');
+ nextBtn.simulate('click');
+ expect(onClose).toHaveBeenCalledTimes(2);
+ });
+
+ it('should support button text: doneBtnText, prevBtnText, nextBtnText, skipBtnText', () => {
+ const onClose = jest.fn();
+ const btnTextConfig = {
+ skipBtnText: 'skip btn',
+ prevBtnText: 'prev btn',
+ nextBtnText: 'next btn',
+ doneBtnText: 'done btn',
+ };
+ const wrapper = mount(
+ ,
+ );
+ const skipBtn = wrapper.find('.skip');
+ const nextBtn = wrapper.find('.fishd-guide-next-btn').at(0);
+ nextBtn.simulate('click');
+ wrapper.update();
+ const prevBtn = wrapper.find('.fishd-guide-prev-btn').at(0);
+ expect(skipBtn.text()).toBe(btnTextConfig.skipBtnText);
+ expect(prevBtn.text()).toBe(btnTextConfig.prevBtnText);
+ expect(nextBtn.text()).toBe(`${btnTextConfig.nextBtnText} (2/3)`);
+
+ nextBtn.simulate('click');
+ wrapper.update();
+ const doneBtn = wrapper.find('.fishd-guide-done-btn').at(0);
+ expect(doneBtn.text()).toBe(`${btnTextConfig.doneBtnText} (3/3)`);
+ });
+
+ it('should support keyboardControl', () => {
+ const onClose = jest.fn();
+ const wrapper = mount(
+ ,
+ );
+ const rightEvent = new KeyboardEvent('keyup', { keyCode: RIGHT_KEY_CODE } as any);
+ const leftEvent = new KeyboardEvent('keyup', { keyCode: LEFT_KEY_CODE } as any);
+ const escEvent = new KeyboardEvent('keyup', { keyCode: ESC_KEY_CODE } as any);
+ const Global = global as any;
+
+ expect(document.querySelector('.fishd-guide-fixed-subtitle').textContent).toBe(
+ steps[0].subtitle,
+ );
+ Global.dispatchEvent(rightEvent);
+ expect(document.querySelector('.fishd-modal-title').textContent).toBe(steps[1].title);
+ Global.dispatchEvent(leftEvent);
+ expect(document.querySelector('.fishd-guide-fixed-subtitle').textContent).toBe(
+ steps[0].subtitle,
+ );
+
+ Global.dispatchEvent(rightEvent);
+ Global.dispatchEvent(rightEvent);
+ Global.dispatchEvent(rightEvent);
+ expect(onClose).toHaveBeenCalledTimes(1);
+
+ wrapper.setProps({ visible: true });
+ wrapper.update();
+ Global.dispatchEvent(escEvent);
+ expect(onClose).toHaveBeenCalledTimes(2);
+ });
+ });
+
+ describe('normal mode', () => {
+ const getBoundingClientRectMock = jest.spyOn(HTMLElement.prototype, 'getBoundingClientRect');
+ let originStyle = Object.prototype['style'];
+ beforeAll(() => {
+ Object.prototype['style'] = {};
+ getBoundingClientRectMock.mockImplementation(function (this: HTMLElement) {
+ return {
+ top: 100,
+ bottom: 0,
+ left: 100,
+ right: 200,
+ width: 100,
+ height: 100,
+ } as any;
+ });
+ });
+
+ afterAll(() => {
+ Object.prototype['style'] = originStyle;
+ getBoundingClientRectMock.mockRestore();
+ });
+
+ const Global = global as any;
+ const normalSteps = [
+ {
+ element: '.guide-demo-step1',
+ popover: {
+ className: 'custom',
+ title: '第1步',
+ description: '第1步介绍',
+ position: 'bottomLeft',
+ },
+ },
+ {
+ counterPosition: 'leftBottom',
+ element: '.guide-demo-step2',
+ popover: {
+ title: '第2步',
+ description: '第2步介绍',
+ position: 'right',
+ },
+ },
+ ];
+ const NormalDemo = props => {
+ const { guideProps } = props;
+ return (
+
+ );
+ };
+ it('should support onClose', () => {
+ jest.useFakeTimers();
+ const onClose = jest.fn();
+ const container = document.createElement('div');
+ Global.document.body.appendChild(container);
+ const wrapper = mount(, {
+ attachTo: container,
+ });
+ act(() => {
+ jest.runAllTimers();
+ });
+ act(() => {
+ const nextBtn = document.querySelector('.fishd-guide-driver-next-btn') as HTMLElement;
+ nextBtn.click();
+ nextBtn.click();
+ jest.runAllTimers();
+ });
+ expect(onClose).toHaveBeenCalledTimes(1);
+
+ wrapper.setProps({
+ guideProps: {
+ visible: true,
+ onClose,
+ },
+ });
+ act(() => {
+ jest.runAllTimers();
+ const skipBtn = document.querySelector('.fishd-guide-driver-skip-btn') as HTMLElement;
+ skipBtn.click();
+ });
+ expect(onClose).toHaveBeenCalledTimes(2);
+
+ const itemNode = document.querySelector('#fishd-guide-driver-popover-item');
+ expect(itemNode.style.display).toBe('none');
+ });
+
+ it('should support button text: doneBtnText, prevBtnText, nextBtnText, skipBtnText', () => {
+ jest.useFakeTimers();
+ const container = document.createElement('div');
+ Global.document.body.appendChild(container);
+ const onClose = jest.fn();
+ const btnTextConfig = {
+ skipBtnText: 'skip btn',
+ prevBtnText: 'prev btn',
+ nextBtnText: 'next btn',
+ doneBtnText: 'done btn',
+ };
+ const wrapper = mount(
+ ,
+ { attachTo: container },
+ );
+ act(() => {
+ jest.runAllTimers();
+ });
+ const skipBtn = document.querySelector('.fishd-guide-driver-skip-btn') as HTMLElement;
+ const nextBtn = document.querySelector('.fishd-guide-driver-next-btn') as HTMLElement;
+ act(() => {
+ nextBtn.click();
+ jest.runAllTimers();
+ });
+ const prevBtn = document.querySelector('.fishd-guide-driver-prev-btn') as HTMLElement;
+ expect(skipBtn.innerHTML).toBe(btnTextConfig.skipBtnText);
+ expect(prevBtn.innerHTML).toBe(btnTextConfig.prevBtnText);
+ expect(nextBtn.innerHTML).toBe(`${btnTextConfig.nextBtnText} (1/2)`);
+
+ act(() => {
+ nextBtn.click();
+ jest.runAllTimers();
+ });
+ const doneBtn = document.querySelector('.fishd-guide-driver-next-btn') as HTMLElement;
+ expect(doneBtn.innerHTML).toBe(`${btnTextConfig.doneBtnText} (2/2)`);
+ });
+
+ it('should support keyboardControl', () => {
+ jest.useFakeTimers();
+ const container = document.createElement('div');
+ Global.document.body.appendChild(container);
+ const onClose = jest.fn();
+ const wrapper = mount(
+ ,
+ { attachTo: container },
+ );
+ act(() => {
+ jest.runAllTimers();
+ });
+ const rightEvent = new KeyboardEvent('keyup', { keyCode: RIGHT_KEY_CODE } as any);
+ const leftEvent = new KeyboardEvent('keyup', { keyCode: LEFT_KEY_CODE } as any);
+ const escEvent = new KeyboardEvent('keyup', { keyCode: ESC_KEY_CODE } as any);
+
+ expect(document.querySelector('.fishd-guide-driver-popover-title').innerHTML).toBe(
+ normalSteps[0].popover.title,
+ );
+ act(() => {
+ Global.dispatchEvent(rightEvent);
+ jest.runAllTimers();
+ });
+ expect(document.querySelector('.fishd-guide-driver-popover-title').innerHTML).toBe(
+ normalSteps[1].popover.title,
+ );
+ act(() => {
+ Global.dispatchEvent(leftEvent);
+ jest.runAllTimers();
+ });
+ expect(document.querySelector('.fishd-guide-driver-popover-title').innerHTML).toBe(
+ normalSteps[0].popover.title,
+ );
+
+ act(() => {
+ Global.dispatchEvent(rightEvent);
+ Global.dispatchEvent(rightEvent);
+ jest.runAllTimers();
+ });
+ expect(onClose).toHaveBeenCalledTimes(1);
+
+ wrapper.setProps({
+ visible: true,
+ onClose,
+ keyboardControl: true,
+ });
+ act(() => {
+ wrapper.update();
+ jest.runAllTimers();
+ });
+ act(() => {
+ Global.dispatchEvent(escEvent);
+ jest.runAllTimers();
+ });
+ expect(onClose).toHaveBeenCalledTimes(2);
+ });
+ });
+});
diff --git a/source/components/Guide/index.tsx b/source/components/Guide/index.tsx
index bbcbd30fc..6efa5ed3a 100644
--- a/source/components/Guide/index.tsx
+++ b/source/components/Guide/index.tsx
@@ -1,278 +1,6 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import classNames from 'classnames';
-import Driver from './src';
-import { ESC_KEY_CODE, LEFT_KEY_CODE, RIGHT_KEY_CODE } from './src/common/constants';
-import Modal from '../Modal';
-import Button from '../Button';
+import Guide from './Guide';
import './style/index.less';
-import ConfigConsumer from '../Config/Consumer';
-import { LocaleProperties } from '../Locale';
-interface GuideProps {
- allowClose?: boolean;
- className?: string;
- counter?: boolean;
- keyboardControl?: boolean;
- mask?: boolean;
- mode?: string;
- onClose?: () => void;
- steps?: any[];
- style?: React.CSSProperties;
- visible?: boolean;
- prefixCls?: string;
-}
-
-interface GuideState {
- visible: boolean;
- currentIndex: number;
-}
-
-class Guide extends Component {
- static propTypes = {
- prefixCls: PropTypes.string,
- className: PropTypes.string,
- style: PropTypes.object,
- mode: PropTypes.string,
- steps: PropTypes.array.isRequired,
- visible: PropTypes.bool,
- counter: PropTypes.bool,
- mask: PropTypes.bool,
- allowClose: PropTypes.bool,
- keyboardControl: PropTypes.bool,
- onClose: PropTypes.func
- };
-
- static defaultProps = {
- prefixCls: 'fishd-guide',
- mode: 'normal',
- allowClose: false,
- keyboardControl: false,
- visible: false,
- counter: true,
- mask: true,
- steps: []
- };
-
- totalCount: number = 0;
- driver: Driver = null;
-
- constructor(props: GuideProps) {
- super(props);
-
- this.state = {
- visible: props.visible,
- currentIndex: 0
- };
-
- this.totalCount = props.steps.length;
-
- if (props.mode != 'fixed') {
- let opt = {
- counter: props.counter,
- allowClose: props.allowClose,
- keyboardControl: props.keyboardControl,
- onReset: () => {
- this.handleClose();
- }
- };
-
- if (!props.mask) {
- opt['opacity'] = 0;
- }
-
- this.driver = new Driver(opt);
- } else {
- if (props.keyboardControl) {
- window.addEventListener('keyup', this.onKeyUp.bind(this), false);
- }
- }
- }
-
- componentDidMount() {
- let { visible } = this.state;
-
- if (!visible) return;
-
- this.init();
- }
-
- // eslint-disable-next-line react/no-deprecated
- componentWillReceiveProps(nextProps) {
- let { visible } = this.state;
-
- if (!visible && nextProps.visible) {
- this.setState(
- {
- visible: true
- },
- () => {
- this.init();
- }
- );
- }
- }
-
- init = () => {
- let { steps, mode } = this.props;
-
- if (!(steps && steps.length) || mode == 'fixed') return;
-
- setTimeout(() => {
- if (steps.length == 1) {
- this.driver.highlight(steps[0]);
- } else {
- this.driver.defineSteps(this.props.steps);
- this.driver.start();
- }
- }, 300);
- };
-
- onKeyUp(event) {
- if (!this.props.keyboardControl || this.props.mode != 'fixed') return;
-
- if (event.keyCode === ESC_KEY_CODE) {
- this.handleClose();
- return;
- }
-
- if (event.keyCode === RIGHT_KEY_CODE) {
- this.handleNext();
- } else if (event.keyCode === LEFT_KEY_CODE) {
- this.handlePrev();
- }
- }
-
- handleClose = () => {
- this.setState(
- {
- visible: false
- },
- () => {
- this.setState({
- currentIndex: 0
- });
- }
- );
-
- this.props.onClose && this.props.onClose();
- };
-
- handleNext = () => {
- let { currentIndex } = this.state,
- nextIndex = 0;
-
- if (currentIndex >= this.totalCount - 1) {
- nextIndex = this.totalCount - 1;
- this.handleClose();
- } else {
- nextIndex = currentIndex + 1;
- }
-
- this.setState({
- currentIndex: nextIndex
- });
- };
-
- handlePrev = () => {
- let { currentIndex } = this.state,
- nextIndex = 0;
-
- if (currentIndex <= 0) {
- nextIndex = 0;
- } else {
- nextIndex = currentIndex - 1;
- }
-
- this.setState({
- currentIndex: nextIndex
- });
- };
-
- renderTitle = curStep => {
- if (!curStep.title) return null;
-
- if (curStep.subtitle) {
- return (
-
- {curStep.title}
- {curStep.subtitle}
-
- );
- } else {
- return curStep.title;
- }
- };
-
- render() {
- let {
- prefixCls,
- allowClose,
- mode,
- mask,
- className,
- style,
- steps,
- } = this.props,
- { visible, currentIndex } = this.state,
- rootCls = classNames(`${prefixCls}-fixed`, {
- [className]: className
- }),
- isFirstStep = currentIndex <= 0,
- isLastStep = currentIndex >= this.totalCount - 1;
-
- if (mode != 'fixed') {
- return null;
- }
-
- return (
-
- {
- (Locale: LocaleProperties['Guide']) => {
- const {
- prevBtnText = '上一步',
- nextBtnText = '下一步',
- doneBtnText = '知道了',
- skipBtnText = '跳过',
- } = Locale;
-
- return (
-
-
- {skipBtnText}
-
- {isFirstStep ? null : (
-
- )}
-
-
- }
- onCancel={this.handleClose}
- >
- {steps[currentIndex].content}
-
- )
- }
- }
-
- );
- }
-}
+export { GuideProps } from './Guide';
export default Guide;
diff --git a/source/components/Guide/src/core/popover.js b/source/components/Guide/src/core/popover.js
index 95cd39581..59182dc99 100644
--- a/source/components/Guide/src/core/popover.js
+++ b/source/components/Guide/src/core/popover.js
@@ -24,7 +24,7 @@ export default class Popover extends Element {
* @param {Document} document
*/
constructor(options, window, document) {
- super();
+ super(options);
this.options = {
isFirst: true,
diff --git a/source/components/Guide/src/core/stage.js b/source/components/Guide/src/core/stage.js
index cedad11fd..10c7028d2 100644
--- a/source/components/Guide/src/core/stage.js
+++ b/source/components/Guide/src/core/stage.js
@@ -13,7 +13,7 @@ export default class Stage extends Element {
* @param {Document} document
*/
constructor(options, window, document) {
- super();
+ super(options);
this.options = options;
this.window = window;