UNPKG

@wordpress/block-library

Version:
310 lines (308 loc) 9.7 kB
/** * External dependencies */ import clsx from 'clsx'; /** * WordPress dependencies */ import { useBlockProps, getCustomValueFromPreset, getSpacingPresetCssVar, store as blockEditorStore, privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; import { ResizableBox } from '@wordpress/components'; import { useState, useEffect } from '@wordpress/element'; import { View } from '@wordpress/primitives'; import { useSelect, useDispatch } from '@wordpress/data'; /** * Internal dependencies */ import { unlock } from '../lock-unlock'; import SpacerControls from './controls'; import { MIN_SPACER_SIZE } from './constants'; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; const { useSpacingSizes } = unlock(blockEditorPrivateApis); const ResizableSpacer = ({ orientation, onResizeStart, onResize, onResizeStop, isSelected, isResizing, setIsResizing, ...props }) => { const getCurrentSize = elt => { return orientation === 'horizontal' ? elt.clientWidth : elt.clientHeight; }; const getNextVal = elt => { return `${getCurrentSize(elt)}px`; }; return /*#__PURE__*/_jsx(ResizableBox, { className: clsx('block-library-spacer__resize-container', { 'resize-horizontal': orientation === 'horizontal', 'is-resizing': isResizing, 'is-selected': isSelected }), onResizeStart: (_event, _direction, elt) => { const nextVal = getNextVal(elt); onResizeStart(nextVal); onResize(nextVal); }, onResize: (_event, _direction, elt) => { onResize(getNextVal(elt)); if (!isResizing) { setIsResizing(true); } }, onResizeStop: (_event, _direction, elt) => { const nextVal = getCurrentSize(elt); onResizeStop(`${nextVal}px`); setIsResizing(false); }, __experimentalShowTooltip: true, __experimentalTooltipProps: { axis: orientation === 'horizontal' ? 'x' : 'y', position: 'corner', isVisible: isResizing }, showHandle: isSelected, ...props }); }; const SpacerEdit = ({ attributes, isSelected, setAttributes, toggleSelection, context, __unstableParentLayout: parentLayout, className }) => { const disableCustomSpacingSizes = useSelect(select => { const editorSettings = select(blockEditorStore).getSettings(); return editorSettings?.disableCustomSpacingSizes; }); const { orientation } = context; const { orientation: parentOrientation, type, default: { type: defaultType } = {} } = parentLayout || {}; // Check if the spacer is inside a flex container. const isFlexLayout = type === 'flex' || !type && defaultType === 'flex'; // If the spacer is inside a flex container, it should either inherit the orientation // of the parent or use the flex default orientation. const inheritedOrientation = !parentOrientation && isFlexLayout ? 'horizontal' : parentOrientation || orientation; const { height, width, style: blockStyle = {} } = attributes; const { layout = {} } = blockStyle; const { selfStretch, flexSize } = layout; const spacingSizes = useSpacingSizes(); const [isResizing, setIsResizing] = useState(false); const [temporaryHeight, setTemporaryHeight] = useState(null); const [temporaryWidth, setTemporaryWidth] = useState(null); const onResizeStart = () => toggleSelection(false); const onResizeStop = () => toggleSelection(true); const { __unstableMarkNextChangeAsNotPersistent } = useDispatch(blockEditorStore); const handleOnVerticalResizeStop = newHeight => { onResizeStop(); if (isFlexLayout) { setAttributes({ style: { ...blockStyle, layout: { ...layout, flexSize: newHeight, selfStretch: 'fixed' } } }); } setAttributes({ height: newHeight }); setTemporaryHeight(null); }; const handleOnHorizontalResizeStop = newWidth => { onResizeStop(); if (isFlexLayout) { setAttributes({ style: { ...blockStyle, layout: { ...layout, flexSize: newWidth, selfStretch: 'fixed' } } }); } setAttributes({ width: newWidth }); setTemporaryWidth(null); }; const getHeightForVerticalBlocks = () => { if (isFlexLayout) { return undefined; } return temporaryHeight || getSpacingPresetCssVar(height) || undefined; }; const getWidthForHorizontalBlocks = () => { if (isFlexLayout) { return undefined; } return temporaryWidth || getSpacingPresetCssVar(width) || undefined; }; const sizeConditionalOnOrientation = inheritedOrientation === 'horizontal' ? temporaryWidth || flexSize : temporaryHeight || flexSize; const style = { height: inheritedOrientation === 'horizontal' ? 24 : getHeightForVerticalBlocks(), width: inheritedOrientation === 'horizontal' ? getWidthForHorizontalBlocks() : undefined, // In vertical flex containers, the spacer shrinks to nothing without a minimum width. minWidth: inheritedOrientation === 'vertical' && isFlexLayout ? 48 : undefined, // Add flex-basis so temporary sizes are respected. flexBasis: isFlexLayout ? sizeConditionalOnOrientation : undefined, // Remove flex-grow when resizing. flexGrow: isFlexLayout && isResizing ? 0 : undefined }; const resizableBoxWithOrientation = blockOrientation => { if (blockOrientation === 'horizontal') { return /*#__PURE__*/_jsx(ResizableSpacer, { minWidth: MIN_SPACER_SIZE, enable: { top: false, right: true, bottom: false, left: false, topRight: false, bottomRight: false, bottomLeft: false, topLeft: false }, orientation: blockOrientation, onResizeStart: onResizeStart, onResize: setTemporaryWidth, onResizeStop: handleOnHorizontalResizeStop, isSelected: isSelected, isResizing: isResizing, setIsResizing: setIsResizing }); } return /*#__PURE__*/_jsx(_Fragment, { children: /*#__PURE__*/_jsx(ResizableSpacer, { minHeight: MIN_SPACER_SIZE, enable: { top: false, right: false, bottom: true, left: false, topRight: false, bottomRight: false, bottomLeft: false, topLeft: false }, orientation: blockOrientation, onResizeStart: onResizeStart, onResize: setTemporaryHeight, onResizeStop: handleOnVerticalResizeStop, isSelected: isSelected, isResizing: isResizing, setIsResizing: setIsResizing }) }); }; useEffect(() => { // To avoid interfering with undo/redo operations any changes in this // effect must not make history and should be preceded by // `__unstableMarkNextChangeAsNotPersistent()`. const setAttributesCovertly = nextAttributes => { __unstableMarkNextChangeAsNotPersistent(); setAttributes(nextAttributes); }; if (isFlexLayout && selfStretch !== 'fill' && selfStretch !== 'fit' && flexSize === undefined) { if (inheritedOrientation === 'horizontal') { // If spacer is moving from a vertical container to a horizontal container, // it might not have width but have height instead. const newSize = getCustomValueFromPreset(width, spacingSizes) || getCustomValueFromPreset(height, spacingSizes) || '100px'; setAttributesCovertly({ width: '0px', style: { ...blockStyle, layout: { ...layout, flexSize: newSize, selfStretch: 'fixed' } } }); } else { const newSize = getCustomValueFromPreset(height, spacingSizes) || getCustomValueFromPreset(width, spacingSizes) || '100px'; setAttributesCovertly({ height: '0px', style: { ...blockStyle, layout: { ...layout, flexSize: newSize, selfStretch: 'fixed' } } }); } } else if (isFlexLayout && (selfStretch === 'fill' || selfStretch === 'fit')) { setAttributesCovertly(inheritedOrientation === 'horizontal' ? { width: undefined } : { height: undefined }); } else if (!isFlexLayout && (selfStretch || flexSize)) { setAttributesCovertly({ ...(inheritedOrientation === 'horizontal' ? { width: flexSize } : { height: flexSize }), style: { ...blockStyle, layout: { ...layout, flexSize: undefined, selfStretch: undefined } } }); } }, [blockStyle, flexSize, height, inheritedOrientation, isFlexLayout, layout, selfStretch, setAttributes, spacingSizes, width, __unstableMarkNextChangeAsNotPersistent]); return /*#__PURE__*/_jsxs(_Fragment, { children: [/*#__PURE__*/_jsx(View, { ...useBlockProps({ style, className: clsx(className, { 'custom-sizes-disabled': disableCustomSpacingSizes }) }), children: resizableBoxWithOrientation(inheritedOrientation) }), !isFlexLayout && /*#__PURE__*/_jsx(SpacerControls, { setAttributes: setAttributes, height: temporaryHeight || height, width: temporaryWidth || width, orientation: inheritedOrientation, isResizing: isResizing })] }); }; export default SpacerEdit; //# sourceMappingURL=edit.js.map