UNPKG

@audira/carbon-react-native

Version:

Build React Native apps with component and shared patterns using Carbon

152 lines (151 loc) 5.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Collapsible = void 0; var _react = require("react"); var _reactNative = require("react-native"); var _carbonReactNativeElements = require("@audira/carbon-react-native-elements"); var _index = require("../../_internal/style-sheets/index.js"); var _jsxRuntime = require("react/jsx-runtime"); const Collapsible = exports.Collapsible = /*#__PURE__*/(0, _react.forwardRef)(function ({ defaultOpen, open: openProp, motion = { toOpen: { duration: _carbonReactNativeElements.Motion.Duration.fast_02, easing: _reactNative.Easing.bezier(_carbonReactNativeElements.Motion.Easing.entrance.productive.x1, _carbonReactNativeElements.Motion.Easing.entrance.productive.y1, _carbonReactNativeElements.Motion.Easing.entrance.productive.x2, _carbonReactNativeElements.Motion.Easing.entrance.productive.y2) }, toClose: { duration: _carbonReactNativeElements.Motion.Duration.fast_02, easing: _reactNative.Easing.bezier(_carbonReactNativeElements.Motion.Easing.exit.productive.x1, _carbonReactNativeElements.Motion.Easing.exit.productive.y1, _carbonReactNativeElements.Motion.Easing.exit.productive.x2, _carbonReactNativeElements.Motion.Easing.exit.productive.y2) } }, children, style, contentContainerStyle, onToggle, onOpened, onClosed, ...props }, forwardedRef) { const viewRef = (0, _react.useRef)(null), ref = (0, _react.useRef)({ positionView: defaultOpen ?? openProp ? 'relative' : 'absolute', contentHeight: 0, openSelf: !!defaultOpen }), [openSelf, setOpenSelf] = (0, _react.useState)(ref.current.openSelf), /** * Absolute position is required to keep content being rendered as it is when the container is not open (zero height) * * We need 'relative' position when the collapsible is initially opened due to heightAnimated initial value is zero and only will be calculated after content is rendered * * This state will be changed once only from 'relative' to 'absolute' */ [positionView, setPositionView] = (0, _react.useState)(ref.current.positionView), heightAnimated = (0, _react.useRef)(new _reactNative.Animated.Value(0)), /** * - 0 -> Closed * - 1 -> Opened */ contentContainerAnimated = (0, _react.useRef)(new _reactNative.Animated.Value(0)), controlled = typeof openProp === 'boolean', open = controlled ? !!openProp : openSelf, setPositionViewToAbsolute = (0, _react.useCallback)(() => { if (ref.current.positionView === 'relative') { ref.current.positionView = 'absolute'; setPositionView('absolute'); } }, []), onLayoutContent = (0, _react.useCallback)(({ nativeEvent }) => { if (ref.current.contentHeight !== nativeEvent.layout.height) { ref.current.contentHeight = nativeEvent.layout.height; if (open) { _reactNative.Animated.timing(heightAnimated.current, { toValue: ref.current.contentHeight, duration: 0, useNativeDriver: false }).start(setPositionViewToAbsolute); } } }, [heightAnimated, open, setPositionViewToAbsolute]); (0, _react.useEffect)(() => { if (ref.current.contentHeight) { if (open) { _reactNative.Animated.timing(heightAnimated.current, { toValue: ref.current.contentHeight, useNativeDriver: false, duration: motion.toOpen.duration, easing: motion.toOpen.easing }).start(onOpened); _reactNative.Animated.timing(contentContainerAnimated.current, { toValue: 1, duration: motion.toOpen.duration, easing: motion.toOpen.easing, useNativeDriver: false }).start(); } else { _reactNative.Animated.timing(heightAnimated.current, { toValue: 0, duration: motion.toClose.duration, easing: motion.toClose.easing, useNativeDriver: false }).start(onClosed); _reactNative.Animated.timing(contentContainerAnimated.current, { toValue: 0, duration: motion.toClose.duration, easing: motion.toClose.easing, useNativeDriver: false }).start(); } onToggle?.(open); } }, [open, heightAnimated, contentContainerAnimated, motion, onToggle, onOpened, onClosed]); (0, _react.useImperativeHandle)(forwardedRef, () => { return Object.assign(viewRef.current, { setOpen(value) { if (!controlled) { if (typeof value === 'boolean') { ref.current.openSelf = value; } else { ref.current.openSelf = value(ref.current.openSelf); } setOpenSelf(ref.current.openSelf); } } }); }, [controlled]); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, { ...props, style: [_index.CommonStyleSheet.overflow_hidden, positionView === 'absolute' ? { height: heightAnimated.current } : null, style], ref: viewRef, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: [_index.CommonStyleSheet.w_full, { position: positionView }], children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, { style: [_index.FlexStyleSheet.flex_initial, { opacity: contentContainerAnimated.current.interpolate({ inputRange: contentContainerInterpolationRange, outputRange: [0, 1] }), transform: [{ translateY: contentContainerAnimated.current.interpolate({ inputRange: contentContainerInterpolationRange, outputRange: [-12, 0] }) }] }, contentContainerStyle], onLayout: onLayoutContent, children: children }) }) }); }); const contentContainerInterpolationRange = [0, 1]; //# sourceMappingURL=Collapsible.js.map