balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

TooltipBox.js (7793B)


      1 import {__} from '@wordpress/i18n';
      2 
      3 const { compose } = wp.compose;
      4 const { withDispatch, withSelect } = wp.data;
      5 const { useState, useEffect } = wp.element;
      6 import {ModalManager} from '~redux-templates/modal-manager';
      7 import CONFIG from '../config';
      8 import helper from '../helper';
      9 const ARROW_BOX = 30;
     10 const DEFAULT_BOX_WIDTH = 250;
     11 const DEFAULT_BOX_HEIGHT = 300;
     12 const DEFAULT_OFFSET_X = 0;
     13 const DEFAULT_OFFSET_Y = 20;
     14 const DEFAULT_ARROW_OFFSET_X = 20;
     15 const DEFAULT_ARROW_OFFSET_Y = 20;
     16 function TooltipBox(props) {
     17     const { challengeStep, tooltipRect, isOpen, setChallengeStep, setChallengeFinalStatus, setChallengePassed, setChallengeListExpanded, setImportingTemplate } = props;
     18     const [style, setStyle] = useState({});
     19     const [arrowStyle, setArrowStyle] = useState({});
     20     const [content, setContent] = useState('');
     21     const [wrapperClassname, setWrapperClassname] = useState('');
     22 
     23     const isVisible = () => {
     24         return ((challengeStep >= 0 || challengeStep > CONFIG.totalStep) && isOpen);
     25     }
     26 
     27     const calculateWithStepInformation = () => {
     28         const stepInformation = CONFIG.list[challengeStep];
     29         const boxWidth = (stepInformation.box && stepInformation.box.width) ? stepInformation.box.width : DEFAULT_BOX_WIDTH;
     30         const boxHeight = (stepInformation.box && stepInformation.box.height) ? stepInformation.box.height : DEFAULT_BOX_HEIGHT;
     31         const offsetX = stepInformation.offset ? stepInformation.offset.x :DEFAULT_OFFSET_X;
     32         const offsetY = stepInformation.offset ? stepInformation.offset.y :DEFAULT_OFFSET_Y;
     33         switch(stepInformation.direction) {
     34             case 'right':
     35                 return [tooltipRect.left + offsetX, tooltipRect.top + offsetY - boxHeight / 2];
     36             case 'left':
     37                 return [tooltipRect.left + offsetX, tooltipRect.top + offsetY - boxHeight / 2];
     38             case 'top':
     39                 return [tooltipRect.left + offsetX - boxWidth / 2, tooltipRect.top + offsetY ];
     40             case 'bottom':
     41                 return [tooltipRect.left + offsetX - boxWidth / 2, tooltipRect.top - boxHeight + offsetY];
     42             default:
     43                 return [tooltipRect.left + offsetX, tooltipRect.top + offsetY];
     44         }
     45     }
     46 
     47     const calculateArrowOffset = () => {
     48         const stepInformation = CONFIG.list[challengeStep];
     49         const boxWidth = (stepInformation.box && stepInformation.box.width) ? stepInformation.box.width : DEFAULT_BOX_WIDTH;
     50         const boxHeight = (stepInformation.box && stepInformation.box.height) ? stepInformation.box.height : DEFAULT_BOX_HEIGHT;
     51         const arrowOffsetX = (stepInformation.offset && isNaN(stepInformation.offset.arrowX) === false) ? stepInformation.offset.arrowX : DEFAULT_ARROW_OFFSET_X;
     52         const arrowOffsetY = (stepInformation.offset && isNaN(stepInformation.offset.arrowY) === false) ? stepInformation.offset.arrowY : DEFAULT_ARROW_OFFSET_Y;
     53         switch(stepInformation.direction) {
     54             case 'top':
     55                 return [boxWidth / 2 + arrowOffsetX, arrowOffsetY];
     56             case 'bottom':
     57                 return [boxWidth / 2 + arrowOffsetX, arrowOffsetY];
     58             case 'left':
     59                 return [arrowOffsetX, arrowOffsetY + boxHeight / 2 - ARROW_BOX / 2];
     60             case 'right':
     61                 return [boxWidth + arrowOffsetX, arrowOffsetY + boxHeight / 2 - ARROW_BOX / 2];
     62             default:
     63                 return [arrowOffsetX, arrowOffsetY];
     64         }
     65     }
     66     // adjust position and content upon steps change
     67     useEffect(() => {
     68         if (isVisible() && tooltipRect) {
     69             const stepInformation = CONFIG.list[challengeStep];
     70             if (stepInformation) {
     71                 const [boxLeft, boxTop] = calculateWithStepInformation();
     72                 const [arrowOffsetX, arrowOffsetY] = calculateArrowOffset();
     73                 setStyle({
     74                     ...style,
     75                     display: 'block',
     76                     width: stepInformation.box ? stepInformation.box.width : DEFAULT_BOX_WIDTH,
     77                     left: boxLeft,
     78                     top: boxTop//tooltipRect.top + offsetY + PADDING_Y + ARROW_HEIGHT
     79                 });
     80                 setContent(stepInformation.content);
     81                 setArrowStyle({
     82                     ...arrowStyle,
     83                     display: 'block',
     84                     left: boxLeft + arrowOffsetX,  // calculateLeftWithStepInformation(),
     85                     top: boxTop + arrowOffsetY // tooltipRect.top + offsetY + PADDING_Y
     86                 });
     87             }
     88         } else {
     89             setStyle({ ...style, display: 'none' });
     90             setArrowStyle({...arrowStyle, display: 'none'});
     91         }
     92     }, [JSON.stringify(tooltipRect), challengeStep, isOpen]);
     93 
     94     // update wrapper class name based on step change
     95     useEffect(() => {
     96         const stepInformation = CONFIG.list[challengeStep];
     97         if (stepInformation) {
     98             switch(stepInformation.direction) {
     99                 case 'top':
    100                     setWrapperClassname('challenge-tooltip tooltipster-sidetip tooltipster-top');
    101                     break;
    102                 case 'bottom':
    103                     setWrapperClassname('challenge-tooltip tooltipster-sidetip tooltipster-bottom');
    104                     break;
    105                 case 'left':
    106                     setWrapperClassname('challenge-tooltip tooltipster-sidetip tooltipster-left');
    107                     break;
    108                 case 'right':
    109                     setWrapperClassname('challenge-tooltip tooltipster-sidetip tooltipster-right');
    110                     break;
    111                 default:
    112                     setWrapperClassname('challenge-tooltip tooltipster-sidetip tooltipster-left');
    113             }
    114 
    115         }
    116     }, [challengeStep])
    117 
    118     const toNextStep = () => {
    119         if (challengeStep === CONFIG.totalStep - 1) {
    120             // finalize challenge
    121             ModalManager.show();
    122             setChallengeFinalStatus((helper.getSecondsLeft() > 0) ? 'success' : 'contact');
    123             setChallengeStep(CONFIG.beginningStep);
    124             setChallengePassed(true);
    125             setChallengeListExpanded(true);
    126             setImportingTemplate(null);
    127         } else
    128             setChallengeStep(challengeStep + 1);
    129     }
    130 
    131 
    132     return (
    133         <div className={wrapperClassname}>
    134             <div className="tooltipster-box" style={style}>
    135                 {content}
    136                 <div className="btn-row">
    137                     <button className="challenge-done-btn" onClick={toNextStep}>{__('Next', redux_templates.i18n)}</button>
    138                 </div>
    139             </div>
    140             <div className="tooltipster-arrow" style={arrowStyle}>
    141                 <div className="tooltipster-arrow-uncropped">
    142                     <div className="tooltipster-arrow-border"></div>
    143                     <div className="tooltipster-arrow-background"></div>
    144                 </div>
    145             </div>
    146         </div>
    147     );
    148 }
    149 
    150 
    151 export default compose([
    152     withDispatch((dispatch) => {
    153         const { setChallengeStep, setChallengeFinalStatus, setChallengePassed, setChallengeListExpanded, setImportingTemplate } = dispatch('redux-templates/sectionslist');
    154         return {
    155             setChallengeStep,
    156             setChallengeFinalStatus,
    157             setChallengePassed,
    158             setChallengeListExpanded,
    159             setImportingTemplate
    160         };
    161     }),
    162 
    163     withSelect((select, props) => {
    164         const { getChallengeTooltipRect, getChallengeOpen, getChallengeStep, getChallengeFinalStatus } = select('redux-templates/sectionslist');
    165         return {
    166             tooltipRect: getChallengeTooltipRect(),
    167             isOpen: getChallengeOpen(),
    168             challengeStep: getChallengeStep(),
    169             finalStatus: getChallengeFinalStatus()
    170         };
    171     })
    172 ])(TooltipBox);