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 @@
-
+