265 lines
4.7 KiB
JavaScript
265 lines
4.7 KiB
JavaScript
|
|
import {
|
||
|
|
Fragment,
|
||
|
|
createElement,
|
||
|
|
createContext,
|
||
|
|
useEffect,
|
||
|
|
createPortal,
|
||
|
|
useMemo,
|
||
|
|
useRef,
|
||
|
|
useState,
|
||
|
|
useReducer,
|
||
|
|
useCallback,
|
||
|
|
} from '@wordpress/element'
|
||
|
|
import {
|
||
|
|
getDeepLinkPanel,
|
||
|
|
removeDeepLink,
|
||
|
|
} from '../../customizer/preview-events'
|
||
|
|
import ctEvents from 'ct-events'
|
||
|
|
|
||
|
|
import bezierEasing from 'bezier-easing'
|
||
|
|
|
||
|
|
import { useSpring } from 'react-spring'
|
||
|
|
import { transformValueForRtl } from '../helpers/transform-value-for-rtl'
|
||
|
|
|
||
|
|
export const PanelContext = createContext({
|
||
|
|
titlePrefix: '',
|
||
|
|
isOpen: false,
|
||
|
|
isTransitioning: false,
|
||
|
|
|
||
|
|
previousPanel: false,
|
||
|
|
|
||
|
|
currentLevel: 1,
|
||
|
|
|
||
|
|
secondLevelTitlePrefix: '',
|
||
|
|
secondLevelTitleLabel: '',
|
||
|
|
})
|
||
|
|
|
||
|
|
const panelsReducer = (state, action) => {
|
||
|
|
if (action.type === 'PANEL_OPEN') {
|
||
|
|
const { panelId } = action.payload
|
||
|
|
|
||
|
|
if (state.isOpen && state.isOpen === panelId) {
|
||
|
|
return state
|
||
|
|
}
|
||
|
|
|
||
|
|
if (state.isTransitioning) {
|
||
|
|
return state
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
...state,
|
||
|
|
isOpen: panelId,
|
||
|
|
isTransitioning: panelId,
|
||
|
|
currentLevel: 1,
|
||
|
|
...(state.isOpen
|
||
|
|
? {
|
||
|
|
previousPanel: state.isOpen,
|
||
|
|
}
|
||
|
|
: {}),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (action.type === 'PANEL_RECEIVE_TITLE') {
|
||
|
|
const { titlePrefix } = action.payload
|
||
|
|
|
||
|
|
return {
|
||
|
|
...state,
|
||
|
|
titlePrefix,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (action.type === 'PANEL_RECEIVE_META') {
|
||
|
|
return {
|
||
|
|
...state,
|
||
|
|
...action.payload,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (action.type === 'PANEL_OPEN_SECOND_LEVEL') {
|
||
|
|
// const { titlePrefix } = action.payload
|
||
|
|
|
||
|
|
return {
|
||
|
|
...state,
|
||
|
|
|
||
|
|
currentLevel: 2,
|
||
|
|
|
||
|
|
...(action.secondLevelOptions
|
||
|
|
? {
|
||
|
|
secondLevelOptions: action.secondLevelOptions,
|
||
|
|
}
|
||
|
|
: {}),
|
||
|
|
|
||
|
|
...(action.secondLevelTitleLabel
|
||
|
|
? {
|
||
|
|
secondLevelTitleLabel: action.secondLevelTitleLabel,
|
||
|
|
}
|
||
|
|
: {}),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (action.type === 'PANEL_CLOSE') {
|
||
|
|
return {
|
||
|
|
...state,
|
||
|
|
...(state.currentLevel === 2
|
||
|
|
? { currentLevel: 1 }
|
||
|
|
: {
|
||
|
|
isTransitioning: state.isOpen,
|
||
|
|
isOpen: false,
|
||
|
|
currentLevel: 1,
|
||
|
|
}),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (action.type === 'PANEL_FINISH_TRANSITIONING') {
|
||
|
|
return {
|
||
|
|
...state,
|
||
|
|
isTransitioning: false,
|
||
|
|
...(state.isOpen && state.isOpen !== state.previousPanel
|
||
|
|
? {
|
||
|
|
previousPanel: false,
|
||
|
|
}
|
||
|
|
: {}),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return state
|
||
|
|
}
|
||
|
|
|
||
|
|
const PanelLevel = ({
|
||
|
|
id,
|
||
|
|
children,
|
||
|
|
containerRef,
|
||
|
|
parentContainerRef,
|
||
|
|
useRefsAsWrappers,
|
||
|
|
}) => {
|
||
|
|
const [panelsState, panelsDispatch] = useReducer(panelsReducer, {
|
||
|
|
isOpen: false,
|
||
|
|
isTransitioning: false,
|
||
|
|
})
|
||
|
|
|
||
|
|
const [panelSecondLevelSprings, panelSecondLevelAnimationApi] = useSpring(
|
||
|
|
() => ({
|
||
|
|
from: {
|
||
|
|
x: '0%',
|
||
|
|
},
|
||
|
|
|
||
|
|
config: {
|
||
|
|
duration: 180,
|
||
|
|
easing: bezierEasing(0.645, 0.045, 0.355, 1),
|
||
|
|
},
|
||
|
|
})
|
||
|
|
)
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
ctEvents.on('ct-deep-link-start', (location) => {
|
||
|
|
const [_, panelId] = location.split(':')
|
||
|
|
|
||
|
|
if (!panelId) {
|
||
|
|
panelsDispatch({
|
||
|
|
type: 'PANEL_CLOSE',
|
||
|
|
})
|
||
|
|
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
panelsDispatch({
|
||
|
|
type: 'PANEL_OPEN',
|
||
|
|
payload: { panelId },
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
if (getDeepLinkPanel()) {
|
||
|
|
setTimeout(() => {
|
||
|
|
panelsDispatch({
|
||
|
|
type: 'PANEL_OPEN',
|
||
|
|
payload: { panelId: getDeepLinkPanel() },
|
||
|
|
})
|
||
|
|
|
||
|
|
removeDeepLink()
|
||
|
|
}, 300)
|
||
|
|
}
|
||
|
|
}, [])
|
||
|
|
|
||
|
|
return (
|
||
|
|
<PanelContext.Provider
|
||
|
|
value={{
|
||
|
|
id,
|
||
|
|
containerRef,
|
||
|
|
panelsState,
|
||
|
|
panelSecondLevelSprings,
|
||
|
|
panelsDispatch,
|
||
|
|
panelsHelpers: {
|
||
|
|
isOpenFor: (panelId) =>
|
||
|
|
panelsState.isOpen && panelId === panelsState.isOpen,
|
||
|
|
|
||
|
|
isTransitioningFor: (panelId) =>
|
||
|
|
(panelsState.previousPanel &&
|
||
|
|
panelId === panelsState.previousPanel) ||
|
||
|
|
(panelsState.isTransitioning &&
|
||
|
|
panelId === panelsState.isTransitioning),
|
||
|
|
|
||
|
|
open: (panelId) =>
|
||
|
|
panelsDispatch({
|
||
|
|
type: 'PANEL_OPEN',
|
||
|
|
payload: { panelId },
|
||
|
|
}),
|
||
|
|
|
||
|
|
close: () => {
|
||
|
|
if (panelsState.currentLevel === 2) {
|
||
|
|
panelSecondLevelAnimationApi.start({
|
||
|
|
x: '0%',
|
||
|
|
|
||
|
|
onRest: () => {
|
||
|
|
panelsDispatch({
|
||
|
|
type: 'PANEL_CLOSE',
|
||
|
|
})
|
||
|
|
},
|
||
|
|
})
|
||
|
|
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
panelsDispatch({
|
||
|
|
type: 'PANEL_CLOSE',
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
stopTransitioning: () => {
|
||
|
|
panelsDispatch({
|
||
|
|
type: 'PANEL_FINISH_TRANSITIONING',
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
getWrapperParent: () =>
|
||
|
|
useRefsAsWrappers
|
||
|
|
? parentContainerRef.current
|
||
|
|
: containerRef.current.closest(
|
||
|
|
'[id="customize-theme-controls"]'
|
||
|
|
),
|
||
|
|
|
||
|
|
openSecondLevel: (args) => {
|
||
|
|
panelsDispatch({
|
||
|
|
type: 'PANEL_OPEN_SECOND_LEVEL',
|
||
|
|
...args,
|
||
|
|
})
|
||
|
|
|
||
|
|
panelSecondLevelAnimationApi.start({
|
||
|
|
x: `${transformValueForRtl(50)}%`,
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
getParentOptionsWrapper: () =>
|
||
|
|
useRefsAsWrappers
|
||
|
|
? containerRef.current
|
||
|
|
: containerRef.current.closest(
|
||
|
|
'.accordion-section-content'
|
||
|
|
),
|
||
|
|
},
|
||
|
|
}}>
|
||
|
|
{children}
|
||
|
|
</PanelContext.Provider>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
export default PanelLevel
|