@wordpress/components
Version:
UI components for WordPress.
249 lines (215 loc) • 8.46 kB
JavaScript
"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