mohebifar / mohebifar/react-native-copilot
Expo 54: Scrolling is broken on iOS/Android and positioning is off on Android
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 428
- PR merge metrics
- No merged PRs in 30d
Description
Hi! 👋
Firstly, thanks for your work on this project! 🙂
As I have clarified in the title, there are scroll and positioning related issues when we use this package in a project built with Expo 54
Here is the diff that solved my problem:
diff --git a/node_modules/react-native-copilot/dist/index.js b/node_modules/react-native-copilot/dist/index.js
index 3aff2e2..ad074f8 100644
--- a/node_modules/react-native-copilot/dist/index.js
+++ b/node_modules/react-native-copilot/dist/index.js
@@ -893,7 +893,7 @@ var CopilotProvider = (_a) => {
const copilotEvents = (0, import_react8.useRef)((0, import_mitt.default)()).current;
const modal = (0, import_react8.useRef)(null);
const [visible, setVisibility] = useStateWithAwait(false);
- const [scrollView, setScrollView] = (0, import_react8.useState)(null);
+ const scrollViewRef = (0, import_react8.useRef)(null);
const {
currentStep,
currentStepNumber,
@@ -927,20 +927,17 @@ var CopilotProvider = (_a) => {
);
const setCurrentStep = (0, import_react8.useCallback)(
(step, move = true) => __async(void 0, null, function* () {
- var _a2;
setCurrentStepState(step);
copilotEvents.emit("stepChange", step);
- if (scrollView != null) {
- const nodeHandle = (0, import_react_native7.findNodeHandle)(scrollView);
- if (nodeHandle) {
- (_a2 = step == null ? void 0 : step.wrapperRef.current) == null ? void 0 : _a2.measureLayout(
- nodeHandle,
- (_x, y, _w, h) => {
- const yOffset = y > 0 ? y - h / 2 : 0;
- scrollView.scrollTo({ y: yOffset, animated: false });
- }
- );
- }
+ if (scrollViewRef.current != null && step?.wrapperRef.current) {
+ step.wrapperRef.current.measure((_x, _y, _w, h, _pageX, pageY) => {
+ if (pageY !== undefined && h !== undefined) {
+ // Scroll so element appears in upper portion of screen
+ // leaving room for tooltip below
+ const yOffset = Math.max(0, pageY - 150);
+ scrollViewRef.current.scrollTo({ y: yOffset, animated: false });
+ }
+ });
}
setTimeout(
() => {
@@ -948,16 +945,17 @@ var CopilotProvider = (_a) => {
void moveModalToStep(step);
}
},
- scrollView != null ? 100 : 0
+ scrollViewRef.current != null ? 100 : 0
);
}),
- [copilotEvents, moveModalToStep, scrollView, setCurrentStepState]
+ [copilotEvents, moveModalToStep, setCurrentStepState]
);
const start = (0, import_react8.useCallback)(
(fromStep, suppliedScrollView = null) => __async(void 0, null, function* () {
- if (scrollView == null) {
- setScrollView(suppliedScrollView);
+ if (suppliedScrollView != null) {
+ scrollViewRef.current = suppliedScrollView;
}
+
const currentStep2 = fromStep ? steps[fromStep] : getFirstStep();
if (startTries.current > MAX_START_TRIES) {
startTries.current = 0;
@@ -980,7 +978,6 @@ var CopilotProvider = (_a) => {
copilotEvents,
getFirstStep,
moveModalToStep,
- scrollView,
setCurrentStep,
setVisibility,
steps
@@ -1071,6 +1068,7 @@ function walkthroughable(WrappedComponent) {
// src/components/CopilotStep.tsx
var import_react11 = __toESM(require("react"));
+var import_react_native9 = require("react-native");
var CopilotStep = ({
name,
order,
@@ -1086,9 +1084,15 @@ var CopilotStep = ({
const measure2 = () => {
if (wrapperRef.current != null && "measure" in wrapperRef.current) {
wrapperRef.current.measure((_ox, _oy, width, height, x, y) => {
+ // Adjust for Android status bar
+ let adjustedY = y;
+ if (import_react_native9.Platform.OS === 'android') {
+ const statusBarHeight = import_react_native9.StatusBar.currentHeight || 0;
+ adjustedY = y + statusBarHeight;
+ }
resolve({
x,
- y,
+ y: adjustedY,
width,
height
});
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the source for CopilotProvider corresponding to dist/index.js and read src/components/CopilotStep.tsx, then reproduce the scrolling and positioning behavior in an Expo 54 app on iOS and Android. Compare the reported diff with the source and verify that walkthrough scrolling and step positioning are correct on both platforms.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react-native, typescript
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100