import classnames from 'classnames/dedupe'; import { BlockControls, InspectorControls, MediaPlaceholder, MediaUpload, RichText, useBlockProps, } from '@wordpress/block-editor'; import { __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, BaseControl, Button, ExternalLink, PanelBody, Placeholder, SelectControl, TextareaControl, ToggleControl, Toolbar, ToolbarButton, ToolbarGroup, } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import ColorPicker from '../../components/color-picker'; import RangeControl from '../../components/range-control'; import getIcon from '../../utils/get-icon'; const ALLOWED_MEDIA_TYPES = ['image']; const DEFAULT_SIZE_SLUG = 'large'; /** * Block Edit Class. * * @param props */ export default function BlockEdit(props) { const { attributes, isSelected, setAttributes } = props; let { className } = props; const { position, direction, trigger, caption, showLabels, labelBeforeText, labelAfterText, labelAlign, beforeId, beforeUrl, beforeAlt, beforeWidth, beforeHeight, beforeSizeSlug, afterId, afterUrl, afterAlt, afterWidth, afterHeight, afterSizeSlug, colorDivider, colorDividerIcon, } = attributes; const { editorSettings, beforeImage, afterImage } = useSelect((select) => { const { getSettings } = select('core/block-editor'); const { getMedia } = select('core'); return { editorSettings: getSettings(), beforeImage: beforeId && isSelected ? getMedia(beforeId) : null, afterImage: afterId && isSelected ? getMedia(afterId) : null, }; }); const onUploadError = (message) => { const { noticeOperations } = props; noticeOperations.removeAllNotices(); noticeOperations.createErrorNotice(message); }; const getImgTag = (type = 'before') => { return attributes[`${type}Url`] ? ( {attributes[`${type}Alt`]} ) : null; }; const updateImageData = ( type = 'before', imageData = {}, imageSize = false ) => { imageSize = imageSize || attributes[`${type}SizeSlug`] || DEFAULT_SIZE_SLUG; // Prepare full image data. const result = { [`${type}SizeSlug`]: imageSize, [`${type}Id`]: imageData.id, [`${type}Url`]: imageData.url || imageData.source_url, [`${type}Alt`]: imageData.alt || imageData.alt_text, [`${type}Width`]: imageData.width || (imageData.media_details && imageData.media_details.width ? imageData.media_details.width : undefined), [`${type}Height`]: imageData.height || (imageData.media_details && imageData.media_details.height ? imageData.media_details.height : undefined), }; let sizes = imageData.sizes && imageData.sizes[imageSize]; if ( !sizes && imageData.media_details && imageData.media_details.sizes && imageData.media_details.sizes[imageSize] ) { sizes = imageData.media_details.sizes[imageSize]; } // Prepare image data for selected size. if (sizes) { if (sizes.url) { result[`${type}Url`] = sizes.url; } if (sizes.source_url) { result[`${type}Url`] = sizes.source_url; } if (sizes.width) { result[`${type}Width`] = sizes.width; } if (sizes.height) { result[`${type}Height`] = sizes.height; } } setAttributes(result); }; const iconStart = direction === 'vertical' ? getIcon('icon-horizontal-start') : getIcon('icon-vertical-top'); const iconCenter = direction === 'vertical' ? getIcon('icon-horizontal-center') : getIcon('icon-vertical-center'); const iconEnd = direction === 'vertical' ? getIcon('icon-horizontal-end') : getIcon('icon-vertical-bottom'); className = classnames( 'ghostkit-image-compare', direction === 'vertical' ? 'ghostkit-image-compare-vertical' : false, showLabels && labelAlign ? `ghostkit-image-compare-labels-align-${labelAlign}` : false, className ); const blockProps = useBlockProps({ className }); const baseControlLabel = direction === 'vertical' ? __('Horizontal Align', 'ghostkit') : __('Vertical Align', 'ghostkit'); return ( <> {beforeUrl && afterUrl ? ( setAttributes({ direction: direction === 'vertical' ? '' : 'vertical', }) } isActive={direction === 'vertical'} /> ) : null} {beforeUrl && afterUrl ? ( setAttributes({ position: val })} __next40pxDefaultSize __nextHasNoMarginBottom /> setAttributes({ direction: val }) } value={direction || ''} isBlock __next40pxDefaultSize __nextHasNoMarginBottom > setAttributes({ trigger: val })} value={trigger || ''} isBlock __next40pxDefaultSize __nextHasNoMarginBottom > ) : null} setAttributes({ showLabels: value }) } __nextHasNoMarginBottom /> {showLabels && (
setAttributes({ labelAlign: 'start', }) } isActive={labelAlign === 'start'} /> setAttributes({ labelAlign: 'center', }) } isActive={labelAlign === 'center'} /> setAttributes({ labelAlign: 'end' }) } isActive={labelAlign === 'end'} />
)}
{!beforeId ? ( { updateImageData('before', media); }} allowedTypes={['image']} value={beforeId} render={({ open }) => ( )} /> ) : null} {beforeId ? ( <> { updateImageData('before', media); }} allowedTypes={['image']} value={beforeId} render={({ open }) => ( {/* eslint-disable-next-line jsx-a11y/control-has-associated-label, jsx-a11y/anchor-is-valid */} {beforeAlt} )} />
{editorSettings && editorSettings.imageSizes ? ( { updateImageData( 'before', beforeImage, val ); }} options={editorSettings.imageSizes.map( (imgSize) => ({ value: imgSize.slug, label: imgSize.name, }) )} __next40pxDefaultSize __nextHasNoMarginBottom /> ) : null} setAttributes({ beforeAlt: val }) } help={ <> {__( 'Describe the purpose of the image', 'ghostkit' )} {__( 'Leave empty if the image is purely decorative.', 'ghostkit' )} } __nextHasNoMarginBottom /> ) : null} {!afterId ? ( { updateImageData('after', media); }} allowedTypes={['image']} value={afterId} render={({ open }) => ( )} /> ) : null} {afterId ? ( <> { updateImageData('after', media); }} allowedTypes={['image']} value={afterId} render={({ open }) => ( {/* eslint-disable-next-line jsx-a11y/control-has-associated-label, jsx-a11y/anchor-is-valid */} {afterAlt} )} />
{editorSettings && editorSettings.imageSizes ? ( { updateImageData( 'after', afterImage, val ); }} options={editorSettings.imageSizes.map( (imgSize) => ({ value: imgSize.slug, label: imgSize.name, }) )} __next40pxDefaultSize __nextHasNoMarginBottom /> ) : null} setAttributes({ afterAlt: val }) } help={ <> {__( 'Describe the purpose of the image', 'ghostkit' )} {__( 'Leave empty if the image is purely decorative.', 'ghostkit' )} } __nextHasNoMarginBottom /> ) : null} setAttributes({ colorDivider: val })} alpha /> setAttributes({ colorDividerIcon: val }) } alpha /> {!beforeUrl || !afterUrl ? (
{getImgTag('before') ? (
{getImgTag('before')}
) : ( { updateImageData('before', image); }} accept="image/*" allowedTypes={ALLOWED_MEDIA_TYPES} disableMaxUploadErrorMessages onError={onUploadError} /> )} {getImgTag('after') ? (
{getImgTag('after')}
) : ( { updateImageData('after', image); }} accept="image/*" allowedTypes={ALLOWED_MEDIA_TYPES} disableMaxUploadErrorMessages onError={onUploadError} /> )}
) : (
{getImgTag('before')} {showLabels && (!RichText.isEmpty(labelBeforeText) || isSelected) ? (
setAttributes({ labelBeforeText: val, }) } value={labelBeforeText} placeholder={__( 'Before label…', 'ghostkit' )} />
) : null}
{getImgTag('after')} {showLabels && (!RichText.isEmpty(labelAfterText) || isSelected) ? (
setAttributes({ labelAfterText: val, }) } value={labelAfterText} placeholder={__( 'After label…', 'ghostkit' )} />
) : null}
{(!RichText.isEmpty(caption) || isSelected) && ( setAttributes({ caption: value }) } placeholder={__('Write caption…', 'jetpack')} tagName="figcaption" value={caption} /> )}
)} ); }