UNPKG

@wordpress/block-library

Version:
247 lines (232 loc) 8.06 kB
import { createElement, Fragment } from "@wordpress/element"; /** * External dependencies */ import { View } from 'react-native'; import Video from 'react-native-video'; /** * WordPress dependencies */ import { Image, Icon, IMAGE_DEFAULT_FOCAL_POINT, PanelBody, RangeControl, UnitControl, TextControl, BottomSheet, ToggleControl, __experimentalUseCustomUnits as useCustomUnits } from '@wordpress/components'; import { plus } from '@wordpress/icons'; import { useState, useCallback, useRef } from '@wordpress/element'; import { usePreferredColorSchemeStyle } from '@wordpress/compose'; import { useSetting, MediaUpload } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import styles from './style.scss'; import OverlayColorSettings from './overlay-color-settings'; import FocalPointSettingsButton from './focal-point-settings-button'; import { ALLOWED_MEDIA_TYPES, COVER_MIN_HEIGHT, COVER_MAX_HEIGHT, COVER_DEFAULT_HEIGHT, IMAGE_BACKGROUND_TYPE, VIDEO_BACKGROUND_TYPE } from './shared'; function Controls(_ref) { var _styles$focalPointHin; let { attributes, didUploadFail, hasOnlyColorBackground, isUploadInProgress, onClearMedia, onSelectMedia, setAttributes } = _ref; const { backgroundType, dimRatio, hasParallax, focalPoint, minHeight, minHeightUnit = 'px', url } = attributes; const CONTAINER_HEIGHT = minHeight || COVER_DEFAULT_HEIGHT; const onHeightChange = useCallback(value => { if (minHeight || value !== COVER_DEFAULT_HEIGHT) { setAttributes({ minHeight: value }); } }, [minHeight]); const units = useCustomUnits({ availableUnits: useSetting('spacing.units') || ['px', 'em', 'rem', 'vw', 'vh'], defaultValues: { px: 430, em: 20, rem: 20, vw: 20, vh: 50 } }); const onOpacityChange = useCallback(value => { setAttributes({ dimRatio: value }); }, []); const onChangeUnit = useCallback(nextUnit => { setAttributes({ minHeightUnit: nextUnit, minHeight: nextUnit === 'px' ? Math.max(CONTAINER_HEIGHT, COVER_MIN_HEIGHT) : CONTAINER_HEIGHT }); }, []); const [displayPlaceholder, setDisplayPlaceholder] = useState(true); function setFocalPoint(value) { setAttributes({ focalPoint: value }); } const toggleParallax = () => { setAttributes({ hasParallax: !hasParallax, ...(!hasParallax ? { focalPoint: undefined } : { focalPoint: IMAGE_DEFAULT_FOCAL_POINT }) }); }; const addMediaButtonStyle = usePreferredColorSchemeStyle(styles.addMediaButton, styles.addMediaButtonDark); function focalPointPosition() { let { x, y } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : IMAGE_DEFAULT_FOCAL_POINT; return { left: `${(hasParallax ? 0.5 : x) * 100}%`, top: `${(hasParallax ? 0.5 : y) * 100}%` }; } const [videoNaturalSize, setVideoNaturalSize] = useState(null); const videoRef = useRef(null); const mediaBackground = usePreferredColorSchemeStyle(styles.mediaBackground, styles.mediaBackgroundDark); const imagePreviewStyles = [displayPlaceholder && styles.imagePlaceholder]; const videoPreviewStyles = [{ aspectRatio: videoNaturalSize && videoNaturalSize.width / videoNaturalSize.height, // Hide Video component since it has black background while loading the source opacity: displayPlaceholder ? 0 : 1 }, styles.video, displayPlaceholder && styles.imagePlaceholder]; const focalPointHint = !hasParallax && !displayPlaceholder && createElement(Icon, { icon: plus, size: (_styles$focalPointHin = styles.focalPointHint) === null || _styles$focalPointHin === void 0 ? void 0 : _styles$focalPointHin.width, style: [styles.focalPointHint, focalPointPosition(focalPoint)] }); const renderMediaSection = _ref2 => { var _styles$image; let { open: openMediaOptions, getMediaOptions } = _ref2; return createElement(Fragment, null, getMediaOptions(), url ? createElement(Fragment, null, createElement(BottomSheet.Cell, { accessible: false, cellContainerStyle: [styles.mediaPreview, mediaBackground] }, createElement(View, { style: styles.mediaInner }, IMAGE_BACKGROUND_TYPE === backgroundType && createElement(Image, { editButton: !displayPlaceholder, highlightSelected: false, isSelected: !displayPlaceholder, isUploadFailed: didUploadFail, isUploadInProgress: isUploadInProgress, mediaPickerOptions: [{ destructiveButton: true, id: 'clearMedia', label: __('Clear Media'), onPress: onClearMedia, separated: true, value: 'clearMedia' }], onImageDataLoad: () => { setDisplayPlaceholder(false); }, onSelectMediaUploadOption: onSelectMedia, openMediaOptions: openMediaOptions, url: url, height: "100%", style: imagePreviewStyles, width: (_styles$image = styles.image) === null || _styles$image === void 0 ? void 0 : _styles$image.width }), VIDEO_BACKGROUND_TYPE === backgroundType && createElement(Video, { muted: true, paused: true, disableFocus: true, onLoadStart: () => { setDisplayPlaceholder(true); }, onLoad: event => { const { height, width } = event.naturalSize; setVideoNaturalSize({ height, width }); setDisplayPlaceholder(false); // Avoid invisible, paused video on Android, presumably // related to https://github.com/react-native-video/react-native-video/issues/1979 videoRef === null || videoRef === void 0 ? void 0 : videoRef.current.seek(0); }, ref: videoRef, resizeMode: 'cover', source: { uri: url }, style: videoPreviewStyles }), displayPlaceholder ? null : focalPointHint)), createElement(FocalPointSettingsButton, { disabled: hasParallax, focalPoint: focalPoint || IMAGE_DEFAULT_FOCAL_POINT, onFocalPointChange: setFocalPoint, url: url }), IMAGE_BACKGROUND_TYPE === backgroundType && createElement(ToggleControl, { label: __('Fixed background'), checked: hasParallax, onChange: toggleParallax }), createElement(TextControl, { leftAlign: true, label: __('Clear Media'), labelStyle: styles.clearMediaButton, onPress: onClearMedia })) : createElement(TextControl, { accessibilityLabel: __('Add image or video'), label: __('Add image or video'), labelStyle: addMediaButtonStyle, leftAlign: true, onPress: openMediaOptions })); }; return createElement(Fragment, null, createElement(PanelBody, { title: __('Media') }, createElement(MediaUpload, { allowedTypes: ALLOWED_MEDIA_TYPES, isReplacingMedia: !hasOnlyColorBackground, onSelect: onSelectMedia, render: renderMediaSection })), createElement(OverlayColorSettings, { overlayColor: attributes.overlayColor, customOverlayColor: attributes.customOverlayColor, gradient: attributes.gradient, customGradient: attributes.customGradient, setAttributes: setAttributes }), url ? createElement(PanelBody, null, createElement(RangeControl, { label: __('Opacity'), minimumValue: 0, maximumValue: 100, value: dimRatio, onChange: onOpacityChange, style: styles.rangeCellContainer, separatorType: 'topFullWidth' })) : null, createElement(PanelBody, { title: __('Dimensions') }, createElement(UnitControl, { label: __('Minimum height'), min: minHeightUnit === 'px' ? COVER_MIN_HEIGHT : 1, max: COVER_MAX_HEIGHT, unit: minHeightUnit, value: CONTAINER_HEIGHT, onChange: onHeightChange, onUnitChange: onChangeUnit, units: units, style: styles.rangeCellContainer, key: minHeightUnit }))); } export default Controls; //# sourceMappingURL=controls.native.js.map