@gluestack-ui/core
Version:
Universal UI components for React Native, Expo, and Next.js
128 lines • 6.55 kB
JSX
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import React, { forwardRef } from 'react';
import { Animated, Dimensions, AccessibilityInfo, Platform, Keyboard, } from 'react-native';
import { ActionsheetContext } from './context';
import { ActionsheetContentProvider } from './ActionsheetContentContext';
import { OverlayAnimatePresence } from './OverlayAnimatePresence';
import { FocusScope } from '@gluestack-ui/utils/aria';
import { mergeRefs, findNodeHandle } from '@gluestack-ui/utils/common';
import { useDialog } from '@gluestack-ui/utils/aria';
import { usePreventScroll } from '../../overlay/aria';
const windowHeight = Platform.OS === 'web'
? typeof window !== 'undefined'
? window.innerHeight
: Dimensions.get('screen').height
: Dimensions.get('screen').height;
function ActionsheetContent(StyledActionsheetContent, AnimatePresence) {
return forwardRef((_a, ref) => {
var { children, _experimentalContent = false, focusScope = true } = _a, props = __rest(_a, ["children", "_experimentalContent", "focusScope"]);
const { visible, handleClose, trapFocus, initialFocusRef, handleCloseBackdrop, finalFocusRef, snapPoints, preventScroll, } = React.useContext(ActionsheetContext);
usePreventScroll({ isDisabled: preventScroll });
const pan = React.useRef(new Animated.ValueXY()).current;
const contentSheetHeight = React.useRef(0);
const [contentSheetHeightState, setContentSheetHeightState] = React.useState(0);
const [animatedViewSheetHeight, setAnimatedViewSheetHeight] = React.useState(0);
const animationDefaultConfig = {
type: 'timing',
duration: 200,
};
const handleCloseCallback = React.useCallback(handleClose, [
ActionsheetContext,
handleClose,
]);
const contentSheetAnimatePosition = React.useMemo(() => {
if (!snapPoints) {
return animatedViewSheetHeight - contentSheetHeightState;
}
return windowHeight - snapPoints[0] * windowHeight * 0.01;
}, [snapPoints, animatedViewSheetHeight, contentSheetHeightState]);
const contentRef = React.useRef(null);
React.useEffect(() => {
if (contentRef) {
const reactTag = findNodeHandle(contentRef.current);
if (reactTag) {
AccessibilityInfo.setAccessibilityFocus(reactTag);
AccessibilityInfo.setAccessibilityFocus(reactTag);
AccessibilityInfo.setAccessibilityFocus(reactTag);
AccessibilityInfo.setAccessibilityFocus(reactTag);
AccessibilityInfo.setAccessibilityFocus(reactTag);
AccessibilityInfo.setAccessibilityFocus(reactTag);
AccessibilityInfo.setAccessibilityFocus(reactTag);
AccessibilityInfo.setAccessibilityFocus(reactTag);
}
}
}, [visible, contentRef]);
React.useEffect(() => {
if (visible) {
Keyboard.dismiss();
if (initialFocusRef && initialFocusRef.current) {
initialFocusRef.current.focus();
}
}
else {
if (finalFocusRef && finalFocusRef.current) {
finalFocusRef.current.focus();
}
}
}, [initialFocusRef, finalFocusRef, visible]);
const { dialogProps } = useDialog(Object.assign({}, props), contentRef);
const mergedRef = mergeRefs([ref, contentRef]);
if (_experimentalContent) {
return (<StyledActionsheetContent transition={animationDefaultConfig} {...props} ref={mergedRef} {...dialogProps} onLayout={(event) => {
const { height } = event.nativeEvent.layout;
contentSheetHeight.current = height;
}}>
<ActionsheetContentProvider contentSheetHeight={contentSheetHeight} pan={pan} handleClose={handleCloseCallback} handleCloseBackdrop={handleCloseBackdrop}>
{children}
</ActionsheetContentProvider>
</StyledActionsheetContent>);
}
return (<Animated.View style={{
transform: [{ translateY: pan.y }],
width: '100%',
height: '100%',
}} onLayout={(event) => {
const { height } = event.nativeEvent.layout;
setAnimatedViewSheetHeight(height);
}} pointerEvents="box-none">
<OverlayAnimatePresence visible={visible} AnimatePresence={AnimatePresence}>
<StyledActionsheetContent initial={{
y: windowHeight,
}} animate={{
y: contentSheetAnimatePosition,
}} exit={{
y: windowHeight,
}} transition={animationDefaultConfig} {...props} style={[
props.style,
{
height: snapPoints
? snapPoints[0] * windowHeight * 0.01
: undefined,
},
]} ref={mergedRef} tabIndex={Platform.OS === 'web' ? 0 : undefined} {...dialogProps} onLayout={(event) => {
const { height } = event.nativeEvent.layout;
contentSheetHeight.current = height;
setContentSheetHeightState(height);
}}>
<ActionsheetContentProvider contentSheetHeight={contentSheetHeight} pan={pan} handleClose={handleCloseCallback} handleCloseBackdrop={handleCloseBackdrop} snapPoints={snapPoints}>
{focusScope ? (<FocusScope contain={trapFocus} autoFocus={visible && !initialFocusRef} restoreFocus={visible && !finalFocusRef}>
{children}
</FocusScope>) : (<>{children}</>)}
</ActionsheetContentProvider>
</StyledActionsheetContent>
</OverlayAnimatePresence>
</Animated.View>);
});
}
export default ActionsheetContent;
//# sourceMappingURL=ActionsheetContent.jsx.map