UNPKG

@wordpress/components

Version:
249 lines (215 loc) 8.46 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _element = require("@wordpress/element"); var _reactNative = require("react-native"); var _lodash = require("lodash"); var _i18n = require("@wordpress/i18n"); var _compose = require("@wordpress/compose"); var _style = _interopRequireDefault(require("./style.scss")); var _colorIndicator = _interopRequireDefault(require("../color-indicator")); var _utils = require("../mobile/color-settings/utils"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const ANIMATION_DURATION = 200; let contentWidth = 0; let scrollPosition = 0; let customIndicatorWidth = 0; function ColorPalette({ setColor, activeColor, isGradientColor, defaultSettings, currentSegment, onCustomPress, shouldEnableBottomSheetScroll, shouldShowCustomIndicatorOption = true, shouldShowCustomLabel = true, shouldShowCustomVerticalSeparator = true, customColorIndicatorStyles, customIndicatorWrapperStyles }) { 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 isCustomGradientColor = isGradientColor && isSelectedCustom(); const [shouldShowCustomIndicator, setShouldShowCustomIndicator] = (0, _element.useState)(shouldShowCustomIndicatorOption && (!isGradientSegment || isCustomGradientColor)); 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 defaultColors = (0, _lodash.uniq)((0, _lodash.map)(defaultSettings.colors, 'color')); const defaultGradientColors = (0, _lodash.uniq)((0, _lodash.map)(defaultSettings.gradients, 'gradient')); const colors = isGradientSegment ? defaultGradientColors : defaultColors; const customIndicatorColor = isGradientSegment ? activeColor : customSwatchGradients; (0, _element.useEffect)(() => { setShouldShowCustomIndicator(shouldShowCustomIndicatorOption && (!isGradientSegment || isCustomGradientColor)); }, [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()) { scrollViewRef.current.scrollToEnd(); } else { scrollViewRef.current.scrollTo({ x: 0, y: 0 }); } } }, [currentSegment]); function isSelectedCustom() { const isWithinColors = activeColor && colors && colors.includes(activeColor); if (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 onColorPress(color) { deselectCustomGradient(); performAnimation(color); setColor(color); } function onContentSizeChange(width) { contentWidth = width; if (isSelectedCustom() && scrollViewRef.current) { scrollViewRef.current.scrollToEnd({ animated: !isIOS }); } } 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 (0, _element.createElement)(_reactNative.ScrollView, { contentContainerStyle: _style.default.contentContainer, style: _style.default.container, horizontal: true, showsHorizontalScrollIndicator: false, keyboardShouldPersistTaps: "always", disableScrollViewPanResponder: true, scrollEventThrottle: 16, onScroll: onScroll, onContentSizeChange: onContentSizeChange, onScrollBeginDrag: () => shouldEnableBottomSheetScroll(false), onScrollEndDrag: () => shouldEnableBottomSheetScroll(true), ref: scrollViewRef }, colors.map(color => { const scaleValue = isSelected(color) ? scaleInterpolation : 1; return (0, _element.createElement)(_reactNative.View, { key: `${color}-${isSelected(color)}` }, (0, _element.createElement)(_reactNative.TouchableWithoutFeedback, { onPress: () => onColorPress(color), accessibilityRole: 'button', accessibilityState: { selected: isSelected(color) }, accessibilityHint: color }, (0, _element.createElement)(_reactNative.Animated.View, { style: { transform: [{ scale: scaleValue }] } }, (0, _element.createElement)(_colorIndicator.default, { color: color, isSelected: isSelected(color), opacity: opacity, style: [_style.default.colorIndicator, customColorIndicatorStyles] })))); }), shouldShowCustomIndicator && (0, _element.createElement)(_reactNative.View, { style: customIndicatorWrapperStyle, onLayout: onCustomIndicatorLayout }, shouldShowCustomVerticalSeparator && (0, _element.createElement)(_reactNative.View, { style: verticalSeparatorStyle }), (0, _element.createElement)(_reactNative.TouchableWithoutFeedback, { onPress: onCustomPress, accessibilityRole: 'button', accessibilityState: { selected: isSelectedCustom() }, accessibilityHint: accessibilityHint }, (0, _element.createElement)(_reactNative.View, { style: customIndicatorWrapperStyle }, (0, _element.createElement)(_colorIndicator.default, { withCustomPicker: !isGradientSegment, color: customIndicatorColor, isSelected: isSelectedCustom(), style: [_style.default.colorIndicator, customColorIndicatorStyles] }), shouldShowCustomLabel && (0, _element.createElement)(_reactNative.Text, { style: customTextStyle }, isIOS ? customText : customText.toUpperCase()))))); } var _default = ColorPalette; exports.default = _default; //# sourceMappingURL=index.native.js.map