@audira/carbon-react-native
Version:
Build React Native apps with component and shared patterns using Carbon
152 lines (151 loc) • 5.99 kB
JavaScript
"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