import { Fragment, createElement, createPortal, Component, useRef, useReducer, useEffect, useMemo, useCallback, useState, } from '@wordpress/element' import classnames from 'classnames' import TypographyModal from './typography/TypographyModal' import OutsideClickHandler from './react-outside-click-handler' import { humanizeVariations, familyForDisplay } from './typography/helpers' import { maybePromoteScalarValueIntoResponsive } from '../../customizer/components/responsive-controls' import usePopoverMaker from '../helpers/usePopoverMaker' import { Transition } from '@react-spring/web' import bezierEasing from 'bezier-easing' import { __ } from 'ct-i18n' const getLeftForEl = (modal, el) => { if (!modal) return if (!el) return let style = getComputedStyle(modal) let wrapperLeft = parseFloat(style.left) el = el.getBoundingClientRect() return { '--option-modal-arrow-position': `${ el.left + el.width / 2 - wrapperLeft - 6 }px`, } } const Typography = ({ option: { label = '', desc = '', attr = {} }, option, value, device, onChange, }) => { // const [isOpen, setIsOpen] = useState(false) // options | fonts | variations | search const [currentViewCache, setCurrentViewCache] = useState('_:_') const [isConfirmingGdpr, setIsConfirmingGdpr] = useState(false) const typographyWrapper = useRef() let [currentView, previousView] = useMemo( () => currentViewCache.split(':'), [currentViewCache] ) const setCurrentView = useCallback( (newView) => setCurrentViewCache(`${newView}:${currentView}`), [currentView] ) const [{ isOpen, isTransitioning }, setModalState] = useState({ isOpen: false, isTransitioning: false, }) const { styles, popoverProps } = usePopoverMaker({ ref: typographyWrapper, defaultHeight: 430, shouldCalculate: isTransitioning || isOpen, }) const setIsOpen = (isOpen) => { setModalState((state) => ({ ...state, isOpen, isTransitioning: true, })) } const stopTransitioning = () => setModalState((state) => ({ ...state, isTransitioning: false, })) const fontFamilyRef = useRef() const fontSizeRef = useRef() const fontWeightRef = useRef() const dotsRef = useRef() const confirmationRef = useRef() const arrowLeft = useMemo(() => { const view = currentView const futureRef = view === 'options' ? fontSizeRef.current : view === 'fonts' ? fontFamilyRef.current : view === 'variations' ? fontWeightRef.current : fontSizeRef.current return ( popoverProps.ref && popoverProps.ref.current && getLeftForEl(popoverProps.ref.current, futureRef) ) }, [ isOpen, currentView, popoverProps.ref, popoverProps.ref && popoverProps.ref.current, fontFamilyRef && fontFamilyRef.current, fontWeightRef && fontWeightRef.current, fontSizeRef && fontSizeRef.current, dotsRef && dotsRef.current, ]) let visualFontSize = maybePromoteScalarValueIntoResponsive(value['size'])[device] === 'CT_CSS_SKIP_RULE' ? __('Default Size', 'blocksy') : maybePromoteScalarValueIntoResponsive(value['size'])[device] let currentFontSizeUnit = maybePromoteScalarValueIntoResponsive( value['size'] ) [device].toString() .replace(/[0-9]/g, '') .replace(/\-/g, '') .replace(/\./g, '') .replace('CT_CSS_SKIP_RULE', '') let unitsList = ['px', 'em', 'rem', 'pt', 'vw'] if ( maybePromoteScalarValueIntoResponsive(value['size'])[device] !== 'CT_CSS_SKIP_RULE' && unitsList.indexOf(currentFontSizeUnit) === -1 ) { visualFontSize = __('Custom', 'blocksy') } return (
{ if (isConfirmingGdpr) { return } setIsOpen(false) }} wrapperProps={{ ref: typographyWrapper, onClick: (e) => { e.preventDefault() if (isOpen) { setCurrentView('options') return } setCurrentViewCache('options:_') setIsOpen('options') }, }}>
{ e.stopPropagation() if (isOpen) { setCurrentView('fonts') return } setCurrentViewCache('fonts:_') setIsOpen('fonts') }} className="ct-font" ref={fontFamilyRef}> {value.family === 'Default' ? __('Default Family', 'blocksy') : familyForDisplay(value.family)} / { e.stopPropagation() if (isOpen) { setCurrentView('options') return } setCurrentViewCache('options:_') setIsOpen('font_size') }} ref={fontSizeRef} className="ct-size"> {visualFontSize} / { e.stopPropagation() if (isOpen) { setCurrentView('variations') return } setCurrentViewCache('variations:_') setIsOpen('variations') }} className="ct-weight"> {humanizeVariations(value.variation)}
{(isTransitioning || isOpen) && createPortal( { stopTransitioning() }} config={{ duration: 100, easing: bezierEasing(0.25, 0.1, 0.25, 1.0), }} from={ isOpen ? { transform: 'scale3d(0.95, 0.95, 1)', opacity: 0, } : { opacity: 1 } } enter={ isOpen ? { transform: 'scale3d(1, 1, 1)', opacity: 1, } : { opacity: 1, } } leave={ !isOpen ? { transform: 'scale3d(0.95, 0.95, 1)', opacity: 0, } : { opacity: 1, } }> {(style, item) => { if (!item) { return null } return ( setIsOpen(initialView) } currentView={currentView} previousView={previousView} setCurrentView={setCurrentView} /> ) /* isOpen && ((props) => ( setIsOpen(initialView) } currentView={currentView} previousView={previousView} setCurrentView={setCurrentView} /> )) */ }} , document.body )}
) } export default Typography