HEX
Server: Apache
System: Linux b5.s-host.com.ua 4.18.0-305.10.2.el7.x86_64 #1 SMP Fri Jul 23 21:00:55 UTC 2021 x86_64
User: unelbhzm (1470)
PHP: 8.0.18
Disabled: NONE
Upload Files
File: /sites/nuofama.com/wp-content/themes/blocksy/static/js/options/options/ct-spacing.js
import { createElement, Component, useState } from '@wordpress/element'
import { __ } from 'ct-i18n'
import InputWithOnlyNumbers from '../components/InputWithOnlyNumbers'
import cls from 'classnames'
import OutsideClickHandler from './react-outside-click-handler'

const Spacing = ({ value, option, onChange }) => {
	const [isOpen, setIsOpen] = useState(false)

	const units = [
		{ unit: 'px' },
		{ unit: '%' },
		{ unit: 'em' },
		{ unit: 'rem' },
		{ unit: 'pt' },
	]

	const withDefault = (currentUnit, defaultUnit) =>
		units.find(({ unit }) => unit === currentUnit)
			? currentUnit
			: currentUnit || units[0].unit

	const getLinkedLeader = () =>
		['top', 'right', 'bottom', 'left'].find((v) => value[v] !== 'auto')

	const getCurrentUnit = () =>
		withDefault(
			value[getLinkedLeader()]
				.toString()
				.replace(/[0-9]/g, '')
				.replace('-', '')
				.replace(/\./g, '')
		)

	const getNumericValue = (value, unit = '') => {
		if (value === 'auto') {
			return value
		}

		return `${parseFloat(value) === 0 ? 0 : parseFloat(value) || ''}${unit}`
	}

	const handleChange = (futureValue, position) => {
		if (value.linked) {
			onChange({
				...value,
				top:
					value.top === 'auto'
						? value.top
						: getNumericValue(futureValue, getCurrentUnit()),
				left:
					value.left === 'auto'
						? value.left
						: getNumericValue(futureValue, getCurrentUnit()),
				right:
					value.right === 'auto'
						? value.right
						: getNumericValue(futureValue, getCurrentUnit()),
				bottom:
					value.bottom === 'auto'
						? value.bottom
						: getNumericValue(futureValue, getCurrentUnit()),
			})

			return
		}

		onChange({
			...value,
			[position]: getNumericValue(futureValue, getCurrentUnit()),
		})
	}

	return (
		<div
			className={cls('ct-option-spacing', {
				linked: value.linked,
			})}>
			{['top', 'right', 'bottom', 'left'].map((side) => (
				<span key={side}>
					<InputWithOnlyNumbers
						placeholder=""
						value={getNumericValue(value[side])}
						onChange={(v) => handleChange(v, side)}
						{...{ placeholder: '', ...option.inputAttr }}
					/>

					<small>
						{
							{
								top: __('Top', 'blocksy'),
								bottom: __('Bottom', 'blocksy'),
								left: __('Left', 'blocksy'),
								right: __('Right', 'blocksy'),
							}[side]
						}
					</small>
				</span>
			))}

			<div
				className={cls('ct-spacing-controls ct-value-changer', {
					active: isOpen,
				})}>
				<a
					onClick={(e) => {
						e.preventDefault()

						if (value.linked) {
							onChange({
								...value,
								linked: false,
							})

							return
						}

						const futureValue = value[getLinkedLeader()]

						onChange({
							...value,
							top: value.top !== 'auto' ? futureValue : value.top,
							left:
								value.left !== 'auto'
									? futureValue
									: value.left,
							bottom:
								value.bottom !== 'auto'
									? futureValue
									: value.bottom,
							right:
								value.right !== 'auto'
									? futureValue
									: value.right,

							linked: true,
						})
					}}>
					<svg width="10" height="10" viewBox="0 0 15 15">
						{value.linked ? (
							<path d="M12.2,5.5V4.7c0-2.6-2.1-4.7-4.7-4.7S2.8,2.1,2.8,4.7v0.8c-0.9,0-1.6,0.7-1.6,1.6v6.3c0,0.9,0.7,1.6,1.6,1.6h9.5c0.9,0,1.6-0.7,1.6-1.6V7.1C13.8,6.2,13.1,5.5,12.2,5.5z M10.7,5.5H4.3V4.7c0-1.8,1.4-3.2,3.2-3.2s3.2,1.4,3.2,3.2V5.5z" />
						) : (
							<path d="M12.2,5.5h-1.6H9.9h-5H4.7l0-0.2C4.4,3.5,5.5,1.9,7.3,1.5c1.1-0.2,2.2,0.1,2.8,0.9l1.3-0.9c-1-1.1-2.6-1.8-4.3-1.5C4.5,0.5,2.8,2.9,3.2,5.5H2.8c-0.9,0-1.6,0.7-1.6,1.6v6.3c0,0.9,0.7,1.6,1.6,1.6h9.5c0.9,0,1.6-0.7,1.6-1.6V7.1C13.8,6.2,13.1,5.5,12.2,5.5z" />
						)}
					</svg>
				</a>

				<div
					onClick={() => setIsOpen(!isOpen)}
					className="ct-current-value">
					{getCurrentUnit() || '―'}
				</div>

				<OutsideClickHandler
					className="ct-units-list"
					onOutsideClick={() => {
						if (!isOpen) {
							return
						}

						setIsOpen(false)
					}}>
					{units
						.filter(({ unit }) => unit !== getCurrentUnit())

						.map(({ unit }) => (
							<span
								key={unit}
								data-unit={unit}
								onClick={() => {
									onChange({
										...value,
										top: getNumericValue(value.top, unit),
										left: getNumericValue(value.left, unit),
										right: getNumericValue(
											value.right,
											unit
										),
										bottom: getNumericValue(
											value.bottom,
											unit
										),
									})
									setIsOpen(false)
								}}>
								{unit || '―'}
							</span>
						))}
				</OutsideClickHandler>
			</div>
		</div>
	)
}

export default Spacing