UNPKG

@wordpress/components

Version:
260 lines (256 loc) 10.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _reactNative = require("react-native"); var _i18n = require("@wordpress/i18n"); var _element = require("@wordpress/element"); var _compose = require("@wordpress/compose"); var _style = _interopRequireDefault(require("./style.scss")); var _colorIndicator = _interopRequireDefault(require("../color-indicator")); var _utils = require("../mobile/color-settings/utils"); var _jsxRuntime = require("react/jsx-runtime"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const ANIMATION_DURATION = 200; let contentWidth = 0; let scrollPosition = 0; let customIndicatorWidth = 0; function ColorPalette({ enableCustomColor = false, setColor, activeColor, isGradientColor, defaultSettings, currentSegment, onCustomPress, shouldEnableBottomSheetScroll, shouldShowCustomIndicatorOption = true, shouldShowCustomLabel = true, shouldShowCustomVerticalSeparator = true, customColorIndicatorStyles, customIndicatorWrapperStyles, label }) { var _defaultSettings$colo, _defaultSettings$grad, _defaultSettings$allC, _defaultSettings$allG; const customSwatchGradients = ['linear-gradient(120deg, rgba(255,0,0,.8) 0%, rgba(255,255,255,1) 70.71%)', 'linear-gradient(240deg, rgba(0,255,0,.8) 0%, rgba(0,255,0,0) 70.71%)', 'linear-gradient(360deg, rgba(0,0,255,.8) 0%, rgba(0,0,255,0) 70.71%)']; const scrollViewRef = (0, _element.useRef)(); const isIOS = _reactNative.Platform.OS === 'ios'; const isGradientSegment = currentSegment === _utils.colorsUtils.segments[1]; const scale = (0, _element.useRef)(new _reactNative.Animated.Value(1)).current; const opacity = (0, _element.useRef)(new _reactNative.Animated.Value(1)).current; const delayedScrollRef = (0, _element.useRef)(); const mergedColors = [...new Set(((_defaultSettings$colo = defaultSettings.colors) !== null && _defaultSettings$colo !== void 0 ? _defaultSettings$colo : []).map(({ color }) => color))]; const mergedGradients = [...new Set(((_defaultSettings$grad = defaultSettings.gradients) !== null && _defaultSettings$grad !== void 0 ? _defaultSettings$grad : []).map(({ gradient }) => gradient))]; const allAvailableColors = [...new Set(((_defaultSettings$allC = defaultSettings.allColors) !== null && _defaultSettings$allC !== void 0 ? _defaultSettings$allC : []).map(({ color }) => color))]; const allAvailableGradients = [...new Set(((_defaultSettings$allG = defaultSettings.allGradients) !== null && _defaultSettings$allG !== void 0 ? _defaultSettings$allG : []).map(({ gradient }) => gradient))]; const colors = isGradientSegment ? mergedGradients : mergedColors; const allColors = isGradientSegment ? allAvailableGradients : allAvailableColors; const customIndicatorColor = isGradientSegment ? activeColor : customSwatchGradients; const isCustomGradientColor = isGradientColor && isSelectedCustom(); const shouldShowCustomIndicator = enableCustomColor && shouldShowCustomIndicatorOption && (!isGradientSegment || isCustomGradientColor); const accessibilityHint = isGradientSegment ? (0, _i18n.__)('Navigates to customize the gradient') : (0, _i18n.__)('Navigates to custom color picker'); const customText = (0, _i18n.__)('Custom'); (0, _element.useEffect)(() => { if (scrollViewRef.current) { if (isSelectedCustom()) { scrollToEndWithDelay(); } else { scrollViewRef.current.scrollTo({ x: 0, y: 0 }); } } // Not adding additional dependencies until the component can be refactored and updated safely. // Please see https://github.com/WordPress/gutenberg/pull/41253 for discussion and details. }, [currentSegment]); function isSelectedCustom() { const isWithinColors = activeColor && allColors?.includes(activeColor); if (enableCustomColor && activeColor) { if (isGradientSegment) { return isGradientColor && !isWithinColors; } return !isGradientColor && !isWithinColors; } return false; } function isSelected(color) { return !isSelectedCustom() && activeColor === color; } function timingAnimation(property, toValue) { return _reactNative.Animated.timing(property, { toValue, duration: ANIMATION_DURATION, easing: _reactNative.Easing.ease, useNativeDriver: true }); } function performAnimation(color) { if (!isSelected(color)) { opacity.setValue(0); } _reactNative.Animated.parallel([timingAnimation(scale, 2), timingAnimation(opacity, 1)]).start(() => { opacity.setValue(1); scale.setValue(1); }); } const scaleInterpolation = scale.interpolate({ inputRange: [1, 1.5, 2], outputRange: [1, 0.7, 1] }); function deselectCustomGradient() { const { width } = _reactNative.Dimensions.get('window'); const isVisible = contentWidth - scrollPosition - customIndicatorWidth < width; if (isCustomGradientColor) { if (!isIOS) { // Scroll position on Android doesn't adjust automatically when removing the last item from the horizontal list. // https://github.com/facebook/react-native/issues/27504 // Workaround: Force the scroll when deselecting custom gradient color and when custom indicator is visible on layout. if (isCustomGradientColor && isVisible && scrollViewRef.current) { scrollViewRef.current.scrollTo({ x: scrollPosition - customIndicatorWidth }); } } } } function getColorGradientName(value) { const fallbackName = (0, _i18n.sprintf)(/* translators: %s: the hex color value */ (0, _i18n.__)('Unlabeled color. %s'), value); const foundColorName = isGradientSegment ? defaultSettings.gradients?.find(gradient => gradient.gradient === value) : defaultSettings.allColors?.find(color => color.color === value); return foundColorName ? foundColorName?.name : fallbackName; } function onColorPress(color) { deselectCustomGradient(); performAnimation(color); setColor(color); } function onContentSizeChange(width) { contentWidth = width; if (isSelectedCustom() && scrollViewRef.current) { scrollToEndWithDelay(); } } function scrollToEndWithDelay() { delayedScrollRef.current = setTimeout(() => { scrollViewRef?.current.scrollToEnd(); }, ANIMATION_DURATION); return () => { clearTimeout(delayedScrollRef.current); }; } function onCustomIndicatorLayout({ nativeEvent }) { const { width } = nativeEvent.layout; if (width !== customIndicatorWidth) { customIndicatorWidth = width; } } function onScroll({ nativeEvent }) { scrollPosition = nativeEvent.contentOffset.x; } const verticalSeparatorStyle = (0, _compose.usePreferredColorSchemeStyle)(_style.default.verticalSeparator, _style.default.verticalSeparatorDark); const customTextStyle = (0, _compose.usePreferredColorSchemeStyle)([_style.default.customText, !isIOS && _style.default.customTextAndroid], _style.default.customTextDark); const customIndicatorWrapperStyle = [_style.default.customIndicatorWrapper, customIndicatorWrapperStyles]; return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [label && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { accessibilityRole: "header", style: _style.default.headerText, children: label }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, { contentContainerStyle: _style.default.contentContainer, horizontal: true, showsHorizontalScrollIndicator: false, keyboardShouldPersistTaps: "always", disableScrollViewPanResponder: true, scrollEventThrottle: 16, onScroll: onScroll, onContentSizeChange: onContentSizeChange, onScrollBeginDrag: () => shouldEnableBottomSheetScroll(false), onScrollEndDrag: () => shouldEnableBottomSheetScroll(true), ref: scrollViewRef, testID: `color-palette${label ? '-' + label : ''}`, children: [colors.map(color => { const scaleValue = isSelected(color) ? scaleInterpolation : 1; const colorName = getColorGradientName(color); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableWithoutFeedback, { onPress: () => onColorPress(color), accessibilityRole: "button", accessibilityState: { selected: isSelected(color) }, accessibilityHint: color, accessibilityLabel: colorName, testID: color, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, { style: { transform: [{ scale: scaleValue }] }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_colorIndicator.default, { color: color, isSelected: isSelected(color), opacity: opacity, style: [_style.default.colorIndicator, customColorIndicatorStyles] }) }) }) }, `${color}-${isSelected(color)}`); }), shouldShowCustomIndicator && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: customIndicatorWrapperStyle, onLayout: onCustomIndicatorLayout, children: [shouldShowCustomVerticalSeparator && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: verticalSeparatorStyle }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableWithoutFeedback, { onPress: onCustomPress, accessibilityRole: "button", accessibilityState: { selected: isSelectedCustom() }, accessibilityHint: accessibilityHint, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: customIndicatorWrapperStyle, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_colorIndicator.default, { withCustomPicker: !isGradientSegment, color: customIndicatorColor, isSelected: isSelectedCustom(), style: [_style.default.colorIndicator, customColorIndicatorStyles] }), shouldShowCustomLabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: customTextStyle, children: isIOS ? customText : customText.toUpperCase() })] }) })] })] })] }); } var _default = exports.default = ColorPalette; //# sourceMappingURL=index.native.js.map