Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10.16.0
18.20.4
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export default [
|---|----|-----|----|
|content|function/Element| YES | This is the view displayed in the tooltip popover bubble |
|id|string|YES|id string that matches the corresponding WalkthroughElement|
|listenForOutcomesWhileDisplayed|bool|NO | Listens for possible outcomes while the tooltip is displayed
|placement|string|NO | Determines placement of tooltip in relation to the element it is wrapping
|possibleOutcomes|array|NO|An array of objects with keys (`event`, `action`) that creates event listeners for multiple events to provide the ability to have an outcome tree that responds to a user's actions (listens to events dispatched via `dispatchWalkthroughEvent`|
|tooltipProps|object|NO|additional props to customize the tooltip functionality and style
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
},
"homepage": "https://github.com/jasongaare/react-native-walkthrough#readme",
"dependencies": {
"events": "3.0.0",
"react-native-walkthrough-tooltip": "1.1.7"
"events": "^3.3.0",
"react-native-walkthrough-tooltip": "^1.3.1"
},
"peerDependencies": {
"react": "^16.4.1",
Expand All @@ -34,7 +34,7 @@
"@types/events": "^3.0.0",
"@types/jest": "^24.9.0",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.30",
"@types/react-native": "0.65",
"@types/react-test-renderer": "^16.9.1",
"babel-core": "6.26.3",
"babel-eslint": "8.2.3",
Expand Down
52 changes: 50 additions & 2 deletions src/ContextWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type ElementType = {
tooltipProps?: TooltipProps;
onClose?: () => void;
possibleOutcomes?: OutcomeType[];
listenForOutcomesWhileDisplayed?: boolean;
};
export type GuideType = ElementType[];

Expand All @@ -37,6 +38,7 @@ export const WalkthroughContext = React.createContext<ContextValue>({
});

interface Props {
debug?: boolean;
eventEmitter: EventEmitter;
}
type State = {
Expand Down Expand Up @@ -65,6 +67,11 @@ class ContextWrapper extends Component<Props, State> {

clearCurrentPossibleOutcomes = () => {
const { eventEmitter } = this.props;
if (this.props.debug) {
console.debug(
`[react-native-walkthrough] clearing ${this.state.currentPossibleOutcomes.length} possible outcomes`
);
}

this.state.currentPossibleOutcomes.forEach(({ event, action }) => {
eventEmitter.removeListener(event, action);
Expand All @@ -84,6 +91,11 @@ class ContextWrapper extends Component<Props, State> {
if (outcomeListenerStartTimestamp === undefined) {
console.warn('[react-native-walkthrough] outcomeListenerStartTimestamp not initialized');
} else if (Date.now() - outcomeListenerStartTimestamp >= WAIT_NO_MORE_TIMEOUT) {
if (this.props.debug) {
console.debug(
`[react-native-walkthrough] clearing guide because of walkthrough timeout of ${WAIT_NO_MORE_TIMEOUT}ms`
);
}
this.clearGuide();
} else {
originalAction();
Expand Down Expand Up @@ -131,6 +143,13 @@ class ContextWrapper extends Component<Props, State> {

setGuide = (guide: GuideType, callback?: () => void) => {
this.setElementNull();
if (__DEV__) {
const duplicateElements = guide.filter((element, index) => guide.indexOf(element) !== index);
if (duplicateElements.length > 0) {
const duplicateElementIds = duplicateElements.map(element => element.id).join(', ');
console.warn(`[react-native-walkthrough] guide uses duplicated element IDs: ${duplicateElementIds}`);
}
}
this.setState(safeSetGuide(guide), callback);
};

Expand All @@ -145,6 +164,9 @@ class ContextWrapper extends Component<Props, State> {
eventEmitter.once(triggerEvent, () => {
const waitEnd = Date.now();
const currentGuide = JSON.stringify(this.state.currentGuide);
if (this.props.debug) {
console.debug(`[react-native-walkthrough] triggering for ${element.id} from ${String(triggerEvent)}`);
}

if (waitEnd - waitStart >= WAIT_NO_MORE_TIMEOUT) {
this.clearGuide();
Expand All @@ -167,7 +189,12 @@ class ContextWrapper extends Component<Props, State> {
const elementWithId = this.state.currentGuide.find(element => element.id === id);

if (elementWithId) {
if (this.props.debug) {
console.debug(`[react-native-walkthrough] moving to element with ID ${id}`);
}
this.goToElement(elementWithId);
} else if (this.props.debug) {
console.debug(`[react-native-walkthrough] could not find element with ID ${id}`);
}
};

Expand All @@ -176,11 +203,32 @@ class ContextWrapper extends Component<Props, State> {
const nextIndex = this.getCurrentElementIndex() + 1;

if (currentElement.possibleOutcomes) {
this.listenForPossibleOutcomes(currentElement);
if (this.props.debug) {
console.debug(`[react-native-walkthrough] current element has possible outcomes, listening...`);
}
if (!currentElement.listenForOutcomesWhileDisplayed) {
// Only listen if we are not already listening...
this.listenForPossibleOutcomes(currentElement);
}
this.setElementNull();
} else if (nextIndex < this.state.currentGuide.length) {
this.goToElement(this.state.currentGuide[nextIndex]);
if (this.props.debug) {
console.debug(`[react-native-walkthrough] moving to next element at index ${nextIndex}`);
}
const nextElement = this.state.currentGuide[nextIndex];
this.goToElement(nextElement);
if (nextElement.listenForOutcomesWhileDisplayed && nextElement.possibleOutcomes) {
if (this.props.debug) {
console.debug(
`[react-native-walkthrough] next element has ${nextElement.possibleOutcomes.length} possible outcomes, listening...`
);
}
this.listenForPossibleOutcomes(nextElement);
}
} else {
if (this.props.debug) {
console.debug(`[react-native-walkthrough] no more elements, exiting walkthrough`);
}
this.setElementNull();
this.clearGuide();
}
Expand Down
6 changes: 0 additions & 6 deletions src/WalkthroughElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,4 @@ const WalkthroughElement: FunctionComponent<Props> = props => {
);
};

WalkthroughElement.defaultProps = {
content: undefined,
tooltipProps: undefined,
useTooltipChildContext: false,
};

export default WalkthroughElement;
6 changes: 3 additions & 3 deletions src/WalkthroughProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FunctionComponent } from 'react';
import React, { FunctionComponent, PropsWithChildren } from 'react';
import PropTypes from 'prop-types';
import { EventEmitter } from 'events';

Expand All @@ -7,8 +7,8 @@ import ContextWrapper, { ElementType, GuideType, nullElement } from './ContextWr
const wrapperRef = React.createRef<ContextWrapper>();
const ee = new EventEmitter();

const WalkthroughProvider: FunctionComponent = ({ children }) => (
<ContextWrapper ref={wrapperRef} eventEmitter={ee}>
const WalkthroughProvider: FunctionComponent<PropsWithChildren<{ debug?: boolean }>> = ({ debug, children }) => (
<ContextWrapper ref={wrapperRef} eventEmitter={ee} debug={debug}>
{children}
</ContextWrapper>
);
Expand Down
31 changes: 15 additions & 16 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1245,12 +1245,11 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==

"@types/react-native@^0.60.30":
version "0.60.30"
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.60.30.tgz#33ab525194142a5e3b428e60f0e77e0d1dbd253d"
integrity sha512-Ho41o+6NBlv1K5q2Z+NREST3UsGahXn4V1to2D2U4bcn1hO5MGjzOdkruzsnN10WiP8hW33jvQE6eERClgwvJg==
"@types/react-native@0.65":
version "0.65.21"
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.65.21.tgz#f731b172765f17e4866473de41e1d3a4890ae536"
integrity sha512-6TmhHLEBH7xMOBG+MIExOILOEI+nq/VHmlAJZ7SynJ+/ezG318EFrrxDPge46WPqWT25ZbnhSR6uxzBn7TDRbQ==
dependencies:
"@types/prop-types" "*"
"@types/react" "*"

"@types/react-test-renderer@^16.9.1":
Expand Down Expand Up @@ -2005,9 +2004,9 @@ camelcase@^5.0.0, camelcase@^5.3.1:
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==

caniuse-lite@^1.0.30001038:
version "1.0.30001039"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz#b3814a1c38ffeb23567f8323500c09526a577bbe"
integrity sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q==
version "1.0.30001322"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001322.tgz"
integrity sha512-neRmrmIrCGuMnxGSoh+x7zYtQFFgnSY2jaomjU56sCkTA6JINqQrxutF459JpWcWRajvoyn95sOXq4Pqrnyjew==

capture-exit@^2.0.0:
version "2.0.0"
Expand Down Expand Up @@ -2878,10 +2877,10 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==

events@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88"
integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==
events@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==

exec-sh@^0.3.2:
version "0.3.4"
Expand Down Expand Up @@ -5149,10 +5148,10 @@ react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==

react-native-walkthrough-tooltip@1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/react-native-walkthrough-tooltip/-/react-native-walkthrough-tooltip-1.1.7.tgz#972ce320bee617cfe959690cec6d7239f5bbb52a"
integrity sha512-kgN6mokMUtAVTq1qJJjf4SAEujK+A4bZbpkMykoURpzRQuUU7UlHJ/7k8LA7DRTI3sg1Pn0qaDWxDZHgil6I3w==
react-native-walkthrough-tooltip@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/react-native-walkthrough-tooltip/-/react-native-walkthrough-tooltip-1.3.1.tgz#039f644636dbdff1208d1174c26c6f1e43af7e4d"
integrity sha512-YDsmfMZJDwCjWTcqb7P2RNExh7C/hGMm2WIy4txKZDPrU/Hx1INcujG+JkRDvbhBq9KgO4mc3ig65sdjb6IbPQ==
dependencies:
prop-types "^15.6.1"
react-fast-compare "^2.0.4"
Expand Down