From 5fb7a6fc973087791bb7d87d9bd2e95778081fb5 Mon Sep 17 00:00:00 2001 From: Simonas Gildutis Date: Wed, 5 Feb 2020 18:15:29 +0200 Subject: [PATCH 1/5] Fix declared module name Declared module name should be the same as the package name --- src/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index 64e84db9..bc129a13 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,4 +1,4 @@ -declare module '@okgrow/react-native-copilot' { +declare module 'react-native-copilot' { import { Component, ComponentProps, ComponentType, ReactElement, ReactNode } from 'react'; export type Step = { @@ -94,4 +94,4 @@ declare module '@okgrow/react-native-copilot' { */ export class CopilotStep extends Component {} } - \ No newline at end of file + From 0c9b267a407b14cedccbf53d62e51609d939edbf Mon Sep 17 00:00:00 2001 From: Simonas Gildutis Date: Wed, 5 Feb 2020 18:16:53 +0200 Subject: [PATCH 2/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 413bacd2..9259415e 100644 --- a/README.md +++ b/README.md @@ -287,7 +287,7 @@ eg `this.props.start(false, ScrollViewRef)` ```js import { ScrollView } from "react-native"; -import { copilot } from "@okgrow/react-native-copilot"; +import { copilot } from "react-native-copilot"; class HomeScreen { componentDidMount() { From 425fbb9c74e574ac9498abd2973c55313b42bd37 Mon Sep 17 00:00:00 2001 From: Simonas Gildutis Date: Thu, 6 Feb 2020 13:01:25 +0200 Subject: [PATCH 3/5] Use `measureInWindow` instead of `measure` Fixes an issue where showing copilot inside iOS 13 pageSheet modal would incorrectly calculate target element's position --- src/components/ConnectedCopilotStep.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/ConnectedCopilotStep.js b/src/components/ConnectedCopilotStep.js index 08be00a4..e405046b 100644 --- a/src/components/ConnectedCopilotStep.js +++ b/src/components/ConnectedCopilotStep.js @@ -65,9 +65,9 @@ class ConnectedCopilotStep extends Component { return new Promise((resolve, reject) => { const measure = () => { // Wait until the wrapper element appears - if (this.wrapper && this.wrapper.measure) { - this.wrapper.measure( - (ox, oy, width, height, x, y) => resolve({ + if (this.wrapper && this.wrapper.measureInWindow) { + this.wrapper.measureInWindow( + (x, y, width, height) => resolve({ x, y, width, height, }), reject, From 68ab22c3c44926a417426492b6beecd5cfa7c561 Mon Sep 17 00:00:00 2001 From: Simonas Gildutis Date: Thu, 6 Feb 2020 17:00:46 +0200 Subject: [PATCH 4/5] ScrollView support enhancements Scroll only if the target element is not visible, based on basePadding. Now with animation! --- src/hocs/copilot.js | 60 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/hocs/copilot.js b/src/hocs/copilot.js index 5ee83ad2..41e2625b 100644 --- a/src/hocs/copilot.js +++ b/src/hocs/copilot.js @@ -85,22 +85,58 @@ const copilot = ({ getNextStep(this.state.steps, step); setCurrentStep = async (step: Step, move?: boolean = true): void => { - await this.setState({ currentStep: step }); + this.setState({ currentStep: step }); this.eventEmitter.emit('stepChange', step); - if (this.state.scrollView) { - const { scrollView } = this.state; - await this.state.currentStep.wrapper.measureLayout( - findNodeHandle(scrollView), (x, y, w, h) => { - const yOffsett = y > 0 ? y - (h / 2) : 0; - scrollView.scrollTo({ y: yOffsett, animated: false }); - }); - } - setTimeout(() => { + return new Promise(async (resolve) => { if (move) { - this.moveToCurrentStep(); + const { scrollView } = this.state; + + if (scrollView) { + const [wrapperLayout, scrollViewLayout] = await Promise.all([ + new Promise(resolve => + this.state.currentStep.wrapper.measureLayout( + findNodeHandle(scrollView), + (...args) => resolve(args) + ) + ), + new Promise(resolve => + scrollView._scrollViewRef.measure((...args) => resolve(args)) + ) + ]) + + const [_x, y, _w, h] = wrapperLayout + const [_x1, _y1, _w1, height] = scrollViewLayout + + const elementBottomY = y + h + + // if element is not visible or barely visible in the scroll view + if (elementBottomY > height - basePadding) { + const yOffsett = elementBottomY - height + basePadding * 2 + + const originalHandleScroll = this.state.scrollView._scrollResponder.scrollResponderHandleScroll + this.state.scrollView._scrollResponder.scrollResponderHandleScroll = (e) => { + originalHandleScroll(e) + + if (e.nativeEvent.contentOffset.y >= yOffsett) { + scrollView._scrollResponder.scrollResponderHandleScroll = originalHandleScroll + + resolve() + } + } + + scrollView.scrollTo({ y: yOffsett, animated: true }); + } else { + resolve() + } + } else { + this.moveToCurrentStep() + resolve() + } + } else { + resolve() } - }, this.state.scrollView ? 100 : 0); + }) } setVisibility = (visible: boolean): void => new Promise((resolve) => { From 68e7e955181a69e0072807c1888f3167df52dc3f Mon Sep 17 00:00:00 2001 From: Simonas Gildutis Date: Thu, 6 Feb 2020 17:03:51 +0200 Subject: [PATCH 5/5] Add basePadding to copilot options --- src/hocs/copilot.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hocs/copilot.js b/src/hocs/copilot.js index 41e2625b..3a42c5e7 100644 --- a/src/hocs/copilot.js +++ b/src/hocs/copilot.js @@ -43,6 +43,7 @@ const copilot = ({ svgMaskPath, verticalOffset = 0, wrapperStyle, + basePadding = 16 } = {}) => (WrappedComponent) => { class Copilot extends Component {