diff --git a/packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md b/packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md index eba7b83b8..8434482cc 100644 --- a/packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md +++ b/packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Fixed + +- Fixed React Native Reanimated worklet function errors by properly memoizing snap points. + ## [5.0.2] - 2025-10-2 - Updated react-native-reanimated to v3.16.7 diff --git a/packages/pluggableWidgets/bottom-sheet-native/package.json b/packages/pluggableWidgets/bottom-sheet-native/package.json index 4da0f6909..1d733519a 100644 --- a/packages/pluggableWidgets/bottom-sheet-native/package.json +++ b/packages/pluggableWidgets/bottom-sheet-native/package.json @@ -1,7 +1,7 @@ { "name": "bottom-sheet-native", "widgetName": "BottomSheet", - "version": "5.0.2", + "version": "5.0.3", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/pluggableWidgets/bottom-sheet-native/src/components/CustomModalSheet.tsx b/packages/pluggableWidgets/bottom-sheet-native/src/components/CustomModalSheet.tsx index 5508807bf..4b4b19b76 100644 --- a/packages/pluggableWidgets/bottom-sheet-native/src/components/CustomModalSheet.tsx +++ b/packages/pluggableWidgets/bottom-sheet-native/src/components/CustomModalSheet.tsx @@ -1,4 +1,4 @@ -import { createElement, ReactElement, ReactNode, useEffect, useRef, useState } from "react"; +import { createElement, ReactElement, ReactNode, useEffect, useRef, useState, useMemo } from "react"; import { InteractionManager, LayoutChangeEvent, Modal, Pressable, SafeAreaView, StyleSheet, View } from "react-native"; import BottomSheet, { BottomSheetBackdrop, BottomSheetBackdropProps, BottomSheetView } from "@gorhom/bottom-sheet"; import { EditableValue, ValueStatus } from "mendix"; @@ -17,6 +17,13 @@ export const CustomModalSheet = (props: CustomModalSheetProps): ReactElement => const [currentStatus, setCurrentStatus] = useState(false); const isAvailable = props.triggerAttribute && props.triggerAttribute.status === ValueStatus.Available; + const snapPoints = useMemo(() => { + if (height === 0) { + return ["90%"]; + } + return [height - Number(defaultPaddings.paddingBottom)]; + }, [height]); + const onLayoutFullscreenHandler = (event: LayoutChangeEvent): void => { const layoutHeight = event.nativeEvent.layout.height; if (layoutHeight > 0 && layoutHeight !== height) { @@ -34,7 +41,7 @@ export const CustomModalSheet = (props: CustomModalSheetProps): ReactElement => bottomSheetRef.current?.close(); setCurrentStatus(false); } - }, [props.triggerAttribute, currentStatus]); + }, [props.triggerAttribute, currentStatus, isAvailable]); if (height === 0) { return ( @@ -44,14 +51,12 @@ export const CustomModalSheet = (props: CustomModalSheetProps): ReactElement => ); } - const snapPoints = [height - Number(defaultPaddings.paddingBottom)]; - const isOpen = props.triggerAttribute && props.triggerAttribute.status === ValueStatus.Available && props.triggerAttribute.value; - const renderBackdrop = (backdropProps: BottomSheetBackdropProps) => ( + const renderBackdrop = (backdropProps: BottomSheetBackdropProps): ReactElement => ( ); - const handleSheetChanges = (index: number) => { + const handleSheetChanges = (index: number): void => { if (!isAvailable) { return; } @@ -79,7 +84,7 @@ export const CustomModalSheet = (props: CustomModalSheetProps): ReactElement => } }; - const close = () => { + const close = (): void => { bottomSheetRef.current?.close(); }; diff --git a/packages/pluggableWidgets/bottom-sheet-native/src/components/ExpandingDrawer.tsx b/packages/pluggableWidgets/bottom-sheet-native/src/components/ExpandingDrawer.tsx index 1e82b189c..27438d510 100644 --- a/packages/pluggableWidgets/bottom-sheet-native/src/components/ExpandingDrawer.tsx +++ b/packages/pluggableWidgets/bottom-sheet-native/src/components/ExpandingDrawer.tsx @@ -1,4 +1,4 @@ -import { createElement, ReactNode, ReactElement, useCallback, useState, useRef, Children } from "react"; +import { createElement, ReactNode, ReactElement, useCallback, useState, useRef, Children, useMemo } from "react"; import { Dimensions, LayoutChangeEvent, SafeAreaView, StyleSheet, View } from "react-native"; import BottomSheet, { BottomSheetView } from "@gorhom/bottom-sheet"; import { BottomSheetStyle } from "../ui/Styles"; @@ -26,23 +26,29 @@ export const ExpandingDrawer = (props: ExpandingDrawerProps): ReactElement => { const isSmallContentValid = Children.count(props.smallContent) > 0; const isLargeContentValid = Children.count(props.largeContent) > 0; - const onLayoutHandlerHeader = (event: LayoutChangeEvent): void => { - const height = event.nativeEvent.layout.height; - if (height > 0 && height <= maxHeight) { - setHeightHeader(height); - } - }; + const onLayoutHandlerHeader = useCallback( + (event: LayoutChangeEvent): void => { + const height = event.nativeEvent.layout.height; + if (height > 0 && height <= maxHeight) { + setHeightHeader(height); + } + }, + [maxHeight] + ); - const onLayoutHandlerContent = (event: LayoutChangeEvent): void => { - const height = event.nativeEvent.layout.height; - if (height > 0) { - if (height <= maxHeight) { - setHeightContent(height); - } else if (!props.fullscreenContent) { - setHeightContent(maxHeight); + const onLayoutHandlerContent = useCallback( + (event: LayoutChangeEvent): void => { + const height = event.nativeEvent.layout.height; + if (height > 0) { + if (height <= maxHeight) { + setHeightContent(height); + } else if (!props.fullscreenContent) { + setHeightContent(maxHeight); + } } - } - }; + }, + [maxHeight, props.fullscreenContent] + ); const onLayoutFullscreenHandler = (event: LayoutChangeEvent): void => { const height = event.nativeEvent.layout.height; @@ -54,6 +60,19 @@ export const ExpandingDrawer = (props: ExpandingDrawerProps): ReactElement => { const containerStyle = props.fullscreenContent && isOpen ? props.styles.containerWhenExpandedFullscreen : props.styles.container; + const snapPoints = useMemo(() => { + if (props.fullscreenContent && heightContent) { + return [fullscreenHeight, heightContent, heightHeader]; + } + if (props.fullscreenContent) { + return [fullscreenHeight, heightHeader]; + } + if (isLargeContentValid) { + return [heightContent, heightHeader]; + } + return [heightHeader]; + }, [props.fullscreenContent, heightContent, fullscreenHeight, heightHeader, isLargeContentValid]); + const renderContent = useCallback((): ReactNode => { const content = ( @@ -77,7 +96,15 @@ export const ExpandingDrawer = (props: ExpandingDrawerProps): ReactElement => { ); } return content; - }, [props.smallContent, props.largeContent, props.fullscreenContent, isOpen, fullscreenHeight]); + }, [ + props.smallContent, + props.largeContent, + props.fullscreenContent, + fullscreenHeight, + isSmallContentValid, + onLayoutHandlerContent, + onLayoutHandlerHeader + ]); if (props.fullscreenContent && fullscreenHeight === 0) { return ( @@ -91,18 +118,9 @@ export const ExpandingDrawer = (props: ExpandingDrawerProps): ReactElement => { return {renderContent()}; } - const snapPoints = - props.fullscreenContent && heightContent - ? [fullscreenHeight, heightContent, heightHeader] - : props.fullscreenContent - ? [fullscreenHeight, heightHeader] - : isLargeContentValid - ? [heightContent, heightHeader] - : [heightHeader]; - const collapsedIndex = 0; - const onChange = (index: number) => { + const onChange = (index: number): void => { const hasOpened = lastIndexRef === -1 && index === 0; const hasClosed = index === -1; diff --git a/packages/pluggableWidgets/bottom-sheet-native/src/package.xml b/packages/pluggableWidgets/bottom-sheet-native/src/package.xml index 7e3089be8..6f741eabd 100644 --- a/packages/pluggableWidgets/bottom-sheet-native/src/package.xml +++ b/packages/pluggableWidgets/bottom-sheet-native/src/package.xml @@ -1,6 +1,6 @@ - +