import { createElement, Component, createContext, useState, Fragment, } from '@wordpress/element' import classnames from 'classnames' import { SortableContainer, SortableElement, SortableHandle, } from 'react-sortable-hoc' import arrayMove from 'array-move' import OptionsPanel from '../OptionsPanel' import { getValueFromInput } from '../helpers/get-value-from-input' import Select from './ct-select' import nanoid from 'nanoid' import SelectThatAddsItems from './ct-layers/SelectThatAddsItems' import LayerControls from './ct-layers/LayerControls' const valueWithUniqueIds = (value) => value.map((singleItem) => ({ ...singleItem, ...(singleItem.__id ? {} : { __id: nanoid(), }), })) export const itemsThatAreNotAdded = (value, option) => Object.keys(option.settings).filter( (optionId) => !value.find(({ id }) => id === optionId) ) const getDefaultState = () => ({ currentlyPickedItem: null, isDragging: false, isOpen: false, }) export const LayersContext = createContext(getDefaultState()) const { Provider, Consumer } = LayersContext class SingleItem extends Component { state = { isOpen: false, } render() { const { value, items, onChange, index } = this.props const itemIndex = items .map(({ __id }) => __id) .indexOf(value.__id) .toString() return ( {({ option, isDragging, isOpen, parentValue }) => (
  • {option.settings[value.id] && option.settings[value.id].options && isOpen === value.__id && (!isDragging || (isDragging && isDragging !== isOpen)) && (
    { if ( option.settings[value.id] .sync && option.settings[value.id].clone ) { let totalItems = items.filter( ({ id }) => id === value.id ).length let idForSync = `${ option.settings[value.id] .sync.id }_first` if ( totalItems > 1 && items .filter( ({ id }) => id === value.id ) .map(({ __id }) => __id) .indexOf(value.__id) > 0 ) { idForSync = `${ option.settings[ value.id ].sync.id }_second` } wp.customize && wp.customize.previewer && wp.customize.previewer.send( 'ct:sync:refresh_partial', { id: idForSync, } ) } onChange( items.map((l) => l.__id === value.__id ? { ...l, [key]: newValue, } : l ) ) }} value={getValueFromInput( option.settings[value.id].options, { ...(option.value.filter( ({ id }) => id === value.id ).length > 1 ? option.value.filter( ({ id }) => value.id === id )[ items .filter( ({ id }) => id === value.id ) .map( ({ __id, }) => __id ) .indexOf( value.__id ) ] : {}), ...value, itemIndex, } )} options={ option.settings[value.id].options } />
    )}
  • )}
    ) } } const SortableItem = SortableElement(SingleItem) const SortableList = SortableContainer(({ items, onChange }) => ( {({ option }) => ( )} )) const Layers = ({ value, option, onChange, values }) => { const [state, setState] = useState(getDefaultState()) const addForId = (idToAdd, val = {}) => { onChange([ ...(value || []), { id: idToAdd, enabled: true, ...getValueFromInput( option.settings[idToAdd].options || {}, {} ), ...val, __id: nanoid(), }, ]) } const computedValue = (option.manageable ? valueWithUniqueIds(value) : [ ...valueWithUniqueIds(value), ...option.value .filter( ({ id }) => value.map(({ id }) => id).indexOf(id) === -1 ) .map((item) => ({ ...item, __id: nanoid(), enabled: false, })), ] ).filter((item) => !!option.settings[item.id]) return ( { const idToAdd = state.currentlyPickedItem || itemsThatAreNotAdded( valueWithUniqueIds(value), option )[0] setState((state) => ({ ...state, currentlyPickedItem: null, })) addForId(idToAdd) }, addForId: (id, value) => addForId(id, value), option: option, setCurrentItem: (currentlyPickedItem) => setState((state) => ({ ...state, currentlyPickedItem })), removeForId: (idToRemove) => onChange( valueWithUniqueIds(value).filter( ({ __id: id }) => id !== idToRemove ) ), toggleOptionsPanel: (idToAdd) => { if (value.length > 0 && !value[0].__id) { wp.customize && wp.customize.previewer && wp.customize.previewer.send( 'ct:sync:refresh_partial', { shouldSkip: true, } ) onChange(computedValue) } setState((state) => ({ ...state, isOpen: state.isOpen === idToAdd ? false : idToAdd, })) }, }}> {option.manageable && ( )} onChange(v)} helperContainer={() => document.querySelector('#customize-theme-controls') || document.body } onSortEnd={({ oldIndex, newIndex }) => { onChange(arrayMove(computedValue, oldIndex, newIndex)) setState((state) => ({ ...state, isDragging: false, })) }} updateBeforeSortStart={({ index }) => { new Promise((resolve) => { if (value.length > 0 && !value[0].__id) { wp.customize && wp.customize.previewer && wp.customize.previewer.send( 'ct:sync:refresh_partial', { shouldSkip: true, } ) onChange(computedValue) } setState((state) => ({ ...state, isDragging: computedValue[index].__id, })) resolve() }) }} /> ) } export default Layers