UNPKG

@wordpress/components

Version:
150 lines (135 loc) 4.03 kB
import { createElement } from "@wordpress/element"; /** * External dependencies */ import classnames from 'classnames'; /** * WordPress dependencies */ import { useState, useEffect, Children, useRef } from '@wordpress/element'; import deprecated from '@wordpress/deprecated'; import { __ } from '@wordpress/i18n'; import { focus } from '@wordpress/dom'; /** * Internal dependencies */ import Modal from '../modal'; import Button from '../button'; import PageControl from './page-control'; /** * `Guide` is a React component that renders a _user guide_ in a modal. The guide consists of several pages which the user can step through one by one. The guide is finished when the modal is closed or when the user clicks _Finish_ on the last page of the guide. * * ```jsx * function MyTutorial() { * const [ isOpen, setIsOpen ] = useState( true ); * * if ( ! isOpen ) { * return null; * } * * return ( * <Guide * onFinish={ () => setIsOpen( false ) } * pages={ [ * { * content: <p>Welcome to the ACME Store!</p>, * }, * { * image: <img src="https://acmestore.com/add-to-cart.png" />, * content: ( * <p> * Click <i>Add to Cart</i> to buy a product. * </p> * ), * }, * ] } * /> * ); * } * ``` */ function Guide(_ref) { let { children, className, contentLabel, finishButtonText = __('Finish'), onFinish, pages = [] } = _ref; const guideContainer = useRef(null); const [currentPage, setCurrentPage] = useState(0); useEffect(() => { if (Children.count(children)) { deprecated('Passing children to <Guide>', { since: '5.5', alternative: 'the `pages` prop' }); } }, [children]); useEffect(() => { // Each time we change the current page, start from the first element of the page. // This also solves any focus loss that can happen. if (guideContainer.current) { var _; (_ = focus.tabbable.find(guideContainer.current)[0]) === null || _ === void 0 ? void 0 : _.focus(); } }, [currentPage]); if (Children.count(children)) { var _Children$map; pages = (_Children$map = Children.map(children, child => ({ content: child }))) !== null && _Children$map !== void 0 ? _Children$map : []; } const canGoBack = currentPage > 0; const canGoForward = currentPage < pages.length - 1; const goBack = () => { if (canGoBack) { setCurrentPage(currentPage - 1); } }; const goForward = () => { if (canGoForward) { setCurrentPage(currentPage + 1); } }; if (pages.length === 0) { return null; } return createElement(Modal, { className: classnames('components-guide', className), contentLabel: contentLabel, onRequestClose: onFinish, onKeyDown: event => { if (event.code === 'ArrowLeft') { goBack(); // Do not scroll the modal's contents. event.preventDefault(); } else if (event.code === 'ArrowRight') { goForward(); // Do not scroll the modal's contents. event.preventDefault(); } }, ref: guideContainer }, createElement("div", { className: "components-guide__container" }, createElement("div", { className: "components-guide__page" }, pages[currentPage].image, pages.length > 1 && createElement(PageControl, { currentPage: currentPage, numberOfPages: pages.length, setCurrentPage: setCurrentPage }), pages[currentPage].content), createElement("div", { className: "components-guide__footer" }, canGoBack && createElement(Button, { className: "components-guide__back-button", onClick: goBack }, __('Previous')), canGoForward && createElement(Button, { className: "components-guide__forward-button", onClick: goForward }, __('Next')), !canGoForward && createElement(Button, { className: "components-guide__finish-button", onClick: onFinish }, finishButtonText)))); } export default Guide; //# sourceMappingURL=index.js.map