import { createElement, Fragment, Component } from '@wordpress/element' import classnames from 'classnames' import ResponsiveControls, { maybePromoteScalarValueIntoResponsive, isOptionEnabledFor } from '../customizer/components/responsive-controls' import deepEqual from 'deep-equal' const CORE_OPTIONS_CONTEXT = require.context('./options/', true, /\.js$/) const hasCoreOptionModifier = type => { let index = CORE_OPTIONS_CONTEXT.keys() .map(module => module.replace(/^\.\//, '').replace(/\.js$/, '')) .indexOf(type) return index > -1 && CORE_OPTIONS_CONTEXT.keys()[index] } const capitalizeFirstLetter = str => { str = str == null ? '' : String(str) return str.charAt(0).toUpperCase() + str.slice(1) } export const getOptionFor = option => { if (hasCoreOptionModifier(option.type)) { return CORE_OPTIONS_CONTEXT(hasCoreOptionModifier(option.type)).default } return null } class GenericOptionType extends Component { state = { device: wp.customize && wp.customize.previewedDevice ? wp.customize.previewedDevice() : 'desktop' } listener = () => this.setState({ device: wp.customize && wp.customize.previewedDevice ? wp.customize.previewedDevice() : 'desktop' }) componentDidMount() { if (!this.props.option.responsive) return if (!wp.customize) return setTimeout(() => wp.customize.previewedDevice.bind(this.listener), 1000) } componentWillUnmount() { if (!this.props.option.responsive) return if (!wp.customize) return wp.customize.previewedDevice.unbind(this.listener) } setDevice(device) { this.setState({ device }) wp.customize && wp.customize.previewedDevice.set(device) } render() { let { value, values, onChange, option, id, purpose } = this.props let OptionComponent = getOptionFor(option) const valueWithResponsive = option.responsive ? maybePromoteScalarValueIntoResponsive(value)[this.state.device] : value const onChangeWithMobileBridge = value => { if ( option.switchDeviceOnChange && wp.customize && wp.customize.previewedDevice() !== option.switchDeviceOnChange ) { wp.customize.previewedDevice.set(option.switchDeviceOnChange) } onChange(value) } const onChangeWithResponsiveBridge = scalarValue => { onChangeWithMobileBridge( option.responsive ? { ...maybePromoteScalarValueIntoResponsive(value), [this.state.device]: scalarValue } : scalarValue ) } /** * Handle transparent components */ if (!OptionComponent) { return
Unimplemented option: {option.type}
} let renderingConfig = { design: true, label: true, wrapperAttr: {} } let LabelToolbar = () => null let OptionMetaWrapper = null let ControlEnd = () => null renderingConfig = { ...renderingConfig, ...(OptionComponent.renderingConfig || {}) } if (option.design) { renderingConfig.design = option.design } if (OptionComponent.LabelToolbar) { LabelToolbar = OptionComponent.LabelToolbar } if (OptionComponent.ControlEnd) { ControlEnd = OptionComponent.ControlEnd } if (OptionComponent.MetaWrapper) { OptionMetaWrapper = OptionComponent.MetaWrapper } let OptionComponentWithoutDesign = ( ) if (!renderingConfig.design || renderingConfig.design === 'none') { return OptionComponentWithoutDesign } let maybeLabel = Object.keys(option).indexOf('label') === -1 ? capitalizeFirstLetter(id).replace(/\_|\-/g, ' ') : option.label let maybeDesc = Object.keys(option).indexOf('desc') === -1 ? false : option.desc /** * Fuck JS */ if (maybeLabel === '') { maybeLabel = true } if (!renderingConfig.label) { maybeLabel = false } const actualDesignType = typeof renderingConfig.design === 'boolean' ? 'block' : renderingConfig.design // if (purpose === 'customizer') { const getActualOption = ({ wrapperAttr: { className, ...additionalWrapperAttr } = {}, ...props } = {}) => (
{maybeLabel && } {option.type !== 'ct-image-picker' && option.type !== 'ct-layers' && option.type !== 'ct-image-uploader' && option.type !== 'ct-panel' && this.props.hasRevertButton && !option.disableRevertButton && (
{option.responsive && !isOptionEnabledFor( this.state.device, option.responsive ) && (
This option can't be edited for current device
)} {((option.responsive && isOptionEnabledFor(this.state.device, option.responsive)) || !option.responsive) && (
{option.responsive && actualDesignType === 'inline' && ( this.setDevice(device) } /> )} {OptionComponentWithoutDesign}
{maybeDesc && (
)} )}
) return OptionMetaWrapper ? ( ) : ( getActualOption() ) // } return (
{maybeLabel && }
{OptionComponentWithoutDesign}
{maybeDesc && (
)}
) } } export default GenericOptionType