UNPKG

@wordpress/components

Version:
164 lines (144 loc) 5.45 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 _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _reactNative = require("react-native"); var _lodash = require("lodash"); var _compose = require("@wordpress/compose"); var _layoutAnimation = require("../layout-animation"); var _style = _interopRequireDefault(require("./style.scss")); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const ANIMATION_DURATION = 200; const isIOS = _reactNative.Platform.OS === 'ios'; const Segment = ({ isSelected, title, onPress, onLayout, ...props }) => { const isSelectedIOS = isIOS && isSelected; const segmentStyle = [_style.default.segment, isIOS && _style.default.segmentIOS]; const textStyle = (0, _compose.usePreferredColorSchemeStyle)(_style.default.buttonTextDefault, _style.default.buttonTextDefaultDark); const selectedTextStyle = (0, _compose.usePreferredColorSchemeStyle)(_style.default.buttonTextSelected, _style.default.buttonTextSelectedDark); const shadowStyle = (0, _compose.usePreferredColorSchemeStyle)(_style.default.shadowIOS, {}); return (0, _element.createElement)(_reactNative.View, { style: isSelectedIOS && shadowStyle }, (0, _element.createElement)(_reactNative.TouchableWithoutFeedback, { onPress: onPress }, (0, _element.createElement)(_reactNative.View, (0, _extends2.default)({ style: segmentStyle, onLayout: onLayout }, props), (0, _element.createElement)(_reactNative.Text, { style: [textStyle, isSelected && selectedTextStyle], maxFontSizeMultiplier: 2 }, title)))); }; const SegmentedControls = ({ segments, segmentHandler, selectedIndex, addonLeft, addonRight }) => { const selectedSegmentIndex = selectedIndex || 0; const [activeSegmentIndex, setActiveSegmentIndex] = (0, _element.useState)(selectedSegmentIndex); const [segmentsDimensions, setSegmentsDimensions] = (0, _element.useState)({ [activeSegmentIndex]: { width: 0, height: 0 } }); const [positionAnimationValue] = (0, _element.useState)(new _reactNative.Animated.Value(0)); (0, _element.useEffect)(() => { setActiveSegmentIndex(selectedSegmentIndex); segmentHandler(segments[selectedSegmentIndex]); }, []); (0, _element.useEffect)(() => { positionAnimationValue.setValue(calculateEndValue(activeSegmentIndex)); }, [segmentsDimensions]); const containerStyle = (0, _compose.usePreferredColorSchemeStyle)(_style.default.container, _style.default.containerDark); function performSwatchAnimation(index) { _reactNative.Animated.timing(positionAnimationValue, { toValue: calculateEndValue(index), duration: ANIMATION_DURATION, easing: _reactNative.Easing.ease }).start(); } function calculateEndValue(index) { const { paddingLeft: offset } = isIOS ? _style.default.containerIOS : _style.default.container; const widths = (0, _lodash.map)((0, _lodash.values)(segmentsDimensions), 'width'); const widthsDistance = (0, _lodash.take)(widths, index); const widthsDistanceSum = (0, _lodash.reduce)(widthsDistance, (sum, n) => sum + n); const endValue = index === 0 ? 0 : widthsDistanceSum; return endValue + offset; } function onHandlePress(segment, index) { (0, _layoutAnimation.performLayoutAnimation)(ANIMATION_DURATION); setActiveSegmentIndex(index); segmentHandler(segment); performSwatchAnimation(index); } function segmentOnLayout(event, index) { const { width, height } = event.nativeEvent.layout; setSegmentsDimensions({ ...segmentsDimensions, [index]: { width, height } }); } const selectedStyle = (0, _compose.usePreferredColorSchemeStyle)(_style.default.selected, _style.default.selectedDark); const width = segmentsDimensions[activeSegmentIndex].width; const height = segmentsDimensions[activeSegmentIndex].height; const outlineStyle = [_style.default.outline, isIOS && _style.default.outlineIOS]; return (0, _element.createElement)(_reactNative.View, { style: _style.default.row }, (0, _element.createElement)(_reactNative.View, { style: _style.default.flex }, addonLeft), (0, _element.createElement)(_reactNative.View, { style: [containerStyle, isIOS && _style.default.containerIOS] }, segments.map((segment, index) => { return (0, _element.createElement)(Segment, { title: segment, onPress: () => onHandlePress(segment, index), isSelected: activeSegmentIndex === index, key: index, onLayout: event => segmentOnLayout(event, index), accessibilityState: { selected: activeSegmentIndex === index }, accessibilityRole: 'button', accessibilityLabel: segment, accessibilityHint: `${index + 1} on ${segments.length}` }); }), (0, _element.createElement)(_reactNative.Animated.View, { style: [{ width, left: positionAnimationValue, height }, selectedStyle, outlineStyle] })), (0, _element.createElement)(_reactNative.View, { style: _style.default.flex }, addonRight)); }; var _default = SegmentedControls; exports.default = _default; //# sourceMappingURL=index.native.js.map