Skip to content

Commit 824c3a3

Browse files
committed
docs: update readme
1 parent c5f2b80 commit 824c3a3

File tree

2 files changed

+109
-184
lines changed

2 files changed

+109
-184
lines changed

README.md

Lines changed: 108 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<p align="center"><img src="https://raw.githubusercontent.com/devrnt/react-use-wizard/docs/readme/assets/logo.svg" alt="react-use-wizard logo" height="120px" style="margin-top: 20px;"/></p>
1+
<p align="center"><img src="https://raw.githubusercontent.com/devrnt/react-use-wizard/master/assets/logo.svg" alt="react-use-wizard logo" height="120px" style="margin-top: 20px;"/></p>
22
<h1 align="center">react-use-wizard</h1>
33
<p align="center">A React wizard (stepper) builder without the hassle, powered by hooks.</p>
44

@@ -48,11 +48,11 @@ const Step1 = () => {
4848
});
4949

5050
return (
51-
<>
52-
<button onClick={previousStep}>Previous ⏮️</button>
53-
<button onClick={nextStep}>Next ⏭</button>
54-
</>
55-
);
51+
<>
52+
<button onClick={previousStep}>Previous ⏮️</button>
53+
<button onClick={nextStep}>Next ⏭</button>
54+
</>
55+
);
5656
};
5757
```
5858

@@ -63,7 +63,6 @@ const Step1 = () => {
6363
- [Examples](#examples)
6464
- [Async](#async)
6565
- [Animation](#animation)
66-
- [Troubleshoot](#troubleshoot)
6766
- [Advanced](#advanced)
6867

6968
## API
@@ -79,227 +78,153 @@ Place the `Wizard` around it and that's it.
7978

8079
#### Props
8180

82-
| name | type | description | required | default |
83-
| ------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------- |
84-
| footer | boolean | indicates if Intercom should be automatically booted. If `true` no need to call `boot`, the `IntercomProvider` will call it for you | false | false |
85-
| startIndex | number | Start index to indicate the wizard to start at the given step. Defaults to | false | |
86-
| header | React.ReactNode | Header that is shown above the active step | false | |
87-
| footer | React.ReactNode | Footer that is shown below the active stepstep | false | |
88-
| children | React.ReactNode | Each child component will be treated as an individual step
81+
| name | type | description | required | default |
82+
| ---------- | --------------- | ------------------------------------------------------------- | -------- | ------- |
83+
| startIndex | number | Start index to indicate the wizard to start at the given step | | 0 |
84+
| header | React.ReactNode | Header that is shown above the active step | | |
85+
| footer | React.ReactNode | Footer that is shown below the active stepstep | | |
86+
| children | React.ReactNode | Each child component will be treated as an individual step | ✔️ |
87+
8988
#### Example
9089

9190
```javascript
92-
const App = () => {
93-
const [unreadMessagesCount, setUnreadMessagesCount] = React.useState(0);
91+
const Header = () => <p>I am the header component</p>;
92+
93+
const Footer = () => {
94+
const {
95+
nextStep,
96+
previousStep,
97+
activeStep,
98+
isLastStep,
99+
isFirstStep,
100+
} = useWizard();
94101

95-
const onHide = () => console.log('Intercom did hide the Messenger');
96-
const onShow = () => console.log('Intercom did show the Messenger');
97-
const onUnreadCountChange = (amount: number) => {
98-
console.log('Intercom has a new unread message');
99-
setUnreadMessagesCount(amount);
100-
};
102+
return (
103+
<>
104+
<div>
105+
Has next step: {!isLastStep ? '' : ''}
106+
<br />
107+
Has previous step : {!isFirstStep ? '' : ''}
108+
</div>
109+
Active step: {activeStep + 1} <br />
110+
<button onClick={previousStep}>Previous</button>
111+
<button onClick={nextStep}>Next</button>
112+
</>
113+
);
114+
};
101115

116+
const App = () => {
102117
return (
103-
<IntercomProvider
104-
appId={INTERCOM_APP_ID}
105-
onHide={onHide}
106-
onShow={onShow}
107-
onUnreadCountChange={onUnreadCountChange}
108-
autoBoot
109-
>
110-
<p>Hi there, I am a child of the IntercomProvider</p>
111-
</IntercomProvider>
118+
<Wizard startIndex={0} header={<Header />} footer={<Footer />}>
119+
<Step1 />
120+
<Step2 />
121+
<Step3 />
122+
</Wizard>
112123
);
113124
};
114125
```
115126

116127
### useWizard
117128

118-
Used to retrieve all methods bundled with Intercom. These are based on the official [Intercom docs](https://developers.intercom.com/installing-intercom/docs/javascript-api-attributes-objects). Some extra methods were added to improve convenience.
129+
Used to retrieve all methods and props bundled with the Wizard.
119130

120-
Make sure `IntercomProvider` is wrapped around your component when calling `useIntercom()`.
131+
Make sure `Wizard` is wrapped around your component when calling `useWizard`.
121132

122-
**Remark** - You can't use `useIntercom()` in the same component where `IntercomProvider` is initialized.
133+
**Remark** - You can't use `useWizard` in the same component where `Wizard` is used.
123134

124135
#### Methods
125136

126-
| name | type | description |
127-
| --------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
128-
| boot | (props?: IntercomProps) => void | boots the Intercom instance, not needed if `autoBoot` in `IntercomProvider` is `true` |
129-
| shutdown | () => void | shuts down the Intercom instance |
130-
| hardShutdown | () => void | same functionality as `shutdown`, but makes sure the Intercom cookies, `window.Intercom` and `window.intercomSettings` are removed. |
131-
| update | (props?: IntercomProps) => void | updates the Intercom instance with the supplied props. To initiate a 'ping', call `update` without props |
132-
| hide | () => void | hides the Messenger, will call `onHide` if supplied to `IntercomProvider` |
133-
| show | () => void | shows the Messenger, will call `onShow` if supplied to `IntercomProvider` |
134-
| showMessages | () => void | shows the Messenger with the message list |
135-
| showNewMessages | (content?: string) => void | shows the Messenger as if a new conversation was just created. If `content` is passed, it will fill in the message composer |
136-
| getVisitorId | () => string | gets the visitor id |
137-
| startTour | (tourId: number) => void | starts a tour based on the `tourId` |
138-
| trackEvent | (event: string, metaData?: object) => void | submits an `event` with optional `metaData` |
137+
| name | type | description |
138+
| ----------------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------- |
139+
| nextStep | () => Promise<void> | Go to the next step |
140+
| previousStep | () => void | Go to the previous step |
141+
| handleStep | (handler: Handler) => void | Connect a callback that will be called when calling `nextStep`. `handler` can be either sync or async |
142+
| isLoading | (props?: IntercomProps) => void | \* Will reflect the handler promise state: will be `true` if the handler promise is pending and |
143+
| \* `false` when the handler is either fulfilled or rejected |
144+
| activeStep | number | The current active step of the wizard |
145+
| isFirstStep | boolean | Indicate if the current step is the first step (aka no previous step) |
146+
| isLastStep | boolean | Indicate if the current step is the last step (aka no next step) |
147+
| |
139148

140149
#### Example
141150

142151
```javascript
143152
import * as React from 'react';
144153

145-
import { IntercomProvider, useIntercom } from 'react-use-intercom';
146-
147-
const INTERCOM_APP_ID = 'your-intercom-app-id';
154+
import { Wizard, useWiard } from 'react-use-wizard';
148155

149156
const App = () => (
150-
<IntercomProvider appId={INTERCOM_APP_ID}>
151-
<HomePage />
152-
</IntercomProvider>
157+
<Wizard>
158+
<Step1 />
159+
<Step2 />
160+
<Step3 />
161+
</Wizard>
153162
);
154163

155-
const HomePage = () => {
164+
const Step1 = () => {
156165
const {
157-
boot,
158-
shutdown,
159-
hardShutdown,
160-
update,
161-
hide,
162-
show,
163-
showMessages,
164-
showNewMessages,
165-
getVisitorId,
166-
startTour,
167-
trackEvent,
168-
} = useIntercom();
169-
170-
const bootWithProps = () => boot({ name: 'Russo' });
171-
const updateWithProps = () => update({ name: 'Ossur' });
172-
const handleNewMessages = () => showNewMessages();
173-
const handleNewMessagesWithContent = () => showNewMessages('content');
174-
const handleGetVisitorId = () => console.log(getVisitorId());
175-
const handleStartTour = () => startTour(123);
176-
const handleTrackEvent = () => trackEvent('invited-friend');
177-
const handleTrackEventWithMetaData = () =>
178-
trackEvent('invited-frind', {
179-
name: 'Russo',
180-
});
166+
isLoading,
167+
isLastStep,
168+
isFirstStep,
169+
activeStep,
170+
previousStep,
171+
nextStep,
172+
handleStep,
173+
} = useWizard();
174+
175+
handleStep(() => {
176+
alert('Going to step 2');
177+
});
181178

182179
return (
183180
<>
184-
<button onClick={boot}>Boot intercom</button>
185-
<button onClick={bootWithProps}>Boot with props</button>
186-
<button onClick={shutdown}>Shutdown</button>
187-
<button onClick={hardShutdown}>Hard shutdown</button>
188-
<button onClick={update}>Update clean session</button>
189-
<button onClick={updateWithProps}>Update session with props</button>
190-
<button onClick={show}>Show messages</button>
191-
<button onClick={hide}>Hide messages</button>
192-
<button onClick={showMessages}>Show message list</button>
193-
<button onClick={handleNewMessages}>Show new messages</button>
194-
<button onClick={handleNewMessagesWithContent}>
195-
Show new message with pre-filled content
196-
</button>
197-
<button onClick={handleGetVisitorId}>Get visitor id</button>
198-
<button onClick={handleStartTour}>Start tour</button>
199-
<button onClick={handleTrackEvent}>Track event</button>
200-
<button onClick={handleTrackEventWithMetaData}>
201-
Track event with metadata
202-
</button>
181+
<p>Step 1</p>
182+
{isLoading && <p>loading...</p>}
183+
<button onClick={previousStep}>Previous</button>
184+
<button onClick={nextStep}>Next</button>
185+
<div>
186+
Has next step: {!isLastStep ? '' : ''}
187+
<br />
188+
Has previous step : {!isFirstStep ? '' : ''}
189+
</div>
190+
Active step: {activeStep + 1} <br />
203191
</>
204192
);
205193
};
206194
```
207195

208-
### IntercomProps
209-
210-
All the Intercom default attributes/props are camel cased (`appId` instead of `app_id`) in `react-use-intercom`, see [IntercomProps](src/types.ts) to see what attributes you can pass to `boot` or `update`. Or check the Intercom [docs](https://developers.intercom.com/installing-intercom/docs/javascript-api-attributes-objects)
211-
to see all the available attributes/props.
212-
213-
**Remark** - all the listed Intercom attributes [here](https://developers.intercom.com/installing-intercom/docs/javascript-api-attributes-objects) are snake cased, in `react-use-intercom` are these camel cased.
214-
215-
#### Custom attributes
216-
217-
Still want to pass custom attributes to Intercom? Whether `boot` or `update` is used, you can add your custom properties by passing these through `customAttributes` in the `boot` or `update` method.
218-
219-
**Remark** - the keys of the `customAttributes` object should be snake cased (this is how Intercom wants them). They are rawly passed to Intercom.
220-
221-
```javascript
222-
const { boot } = useIntercom();
223-
224-
boot({
225-
name: 'Russo',
226-
customAttributes: { custom_attribute_key: 'hi there' },
227-
});
228-
```
229-
230-
## Playground
231-
232-
Small playground to showcase the functionalities of `react-use-intercom`.
233-
234-
### useIntercom
235-
236-
[https://devrnt.github.io/react-use-intercom/#/useIntercom](https://devrnt.github.io/react-use-intercom/#/useIntercom)
237-
238-
### useIntercom (with Intercom tour)
239-
240-
[https://devrnt.github.io/react-use-intercom/#/useIntercomTour](https://devrnt.github.io/react-use-intercom/#/useIntercomTour)
196+
It's recommended to put the shared components in the `header` or `footer` in the `Wizard` to avoid duplication.
241197

242198
## Examples
199+
Go to [examples](https://github.com/devrnt/react-use-wiard/tree/master/examples) to check see some examples
243200

244-
Go to [examples](https://github.com/devrnt/react-use-intercom/tree/master/examples) to check out some integrations (Gatsby, NextJS...).
245-
246-
## TypeScript
247-
248-
All the possible pre-defined options to pass to the Intercom instance are typed. So whenever you have to pass [IntercomProps](src/types.ts), all the possible properties will be available out of the box.
249-
These props are `JavaScript` 'friendly', so [camelCase](https://en.wikipedia.org/wiki/Camel_case). No need to pass the props with [snake_cased](https://en.wikipedia.org/wiki/Snake_case) keys.
250-
251-
**Remark** - if you want to pass custom properties, you should still use [snake_cased](https://en.wikipedia.org/wiki/Snake_case) keys.
252-
253-
## Troubleshoot
254-
255-
- I'm seeing `Please wrap your component with IntercomProvider` in the console.
256-
> Make sure `IntercomProvider` is initialized before calling `useIntercom()`. You only need to initialize `IntercomProvider` once. It is advised to initialize `IntercomProvider` as high as possible in your application tree.
257-
258-
> Make sure you aren't calling `useIntercom()` in the same component where you initialized `IntercomProvider`.
259-
260-
- I'm seeing `Some invalid props were passed to IntercomProvider. Please check following props: [properties]` in the console.
261-
> Make sure you're passing the correct properties to the `IntercomProvider`. Check [IntercomProvider](#intercomprovider) to see all the properties.
262-
> Mind that all the properties in `react-use-intercom` are camel cased, except for the `customAttributes` property in the `boot` and `update` method from `useIntercom`.
263-
264-
## Advanced
265-
266-
To reduce the amount of re-renders in your React application I suggest to make use of [`useCallback`](https://reactjs.org/docs/hooks-reference.html#usecallback)
267-
268-
**TLDR:** `useCallback` will return a memoized version of the callback that only changes if one of the dependencies has changed.
201+
## Async
269202

270-
This can be applied to both the `IntercomProvider` events and the `useIntercom` methods. It depends on how many times your main app gets re-rendered.
203+
You can connect an async step handler to a step as well. Make sure to make to either pass an async function or return a promise (async) function:
271204

272-
### Example
273-
274-
```javascript
275-
import * as React from 'react';
205+
```ts
206+
const Step1 = () => {
207+
const { handleStep } = useWizard();
276208

277-
import { IntercomProvider, useIntercom } from 'react-use-intercom';
209+
// Async function
210+
handleStep(async () => {
211+
await fetch(...);
212+
});
278213

279-
const INTERCOM_APP_ID = 'your-intercom-app-id';
214+
// Return promise
215+
handleStep(() => {
216+
return fetch(...);
217+
});
280218

281-
const App = () => {
282-
// const onHide = () => console.log('Intercom did hide the Messenger');
283-
const onHide = React.useCallback(
284-
() => console.log('Intercom did hide the Messenger'),
285-
[],
286-
);
219+
...
220+
}
221+
```
287222

288-
return (
289-
<IntercomProvider appId={INTERCOM_APP_ID} onHide={onHide}>
290-
<HomePage />
291-
</IntercomProvider>
292-
);
293-
};
223+
The `isLoading` of `useWizard` will indicate the loading state of the step when calling `nextStep`. If no errors are thrown the wizard will go to the next step, so no need to call this manually. If an error is thrown in the conencted function the wizard will just stay at the same step and will rethrow the error. (So you can try-catch in your connected function).
294224

295-
const HomePage = () => {
296-
const { boot } = useIntercom();
225+
If an async function is connected the `isLoading` of `useWizard` will indicate the loading state of the function.
297226

298-
// const bootWithProps = () => boot({ name: 'Russo' });
299-
const bootWithProps = React.useCallback(() => boot({ name: 'Russo' }), [
300-
boot,
301-
]);
227+
## Animation
228+
Since `react-use-wizard` is focused to manage the logic of a wizard doesn't mean you can't add some animation by your own. Add any animation library that you like. I highly suggest (https://www.framer.com/motion/)[framer-motion].
302229

303-
return <button onClick={bootWithProps}>Boot with props</button>;
304-
};
305-
```
230+
Checkout this (https://github.com/devrnt/react-use-wizard/blob/docs/readme/example/components/animatedStep.tsx)[example] to see an animation to a step can be added.

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export type WizardValues = {
2828
* `false` when the handler is either fulfilled or rejected
2929
*/
3030
isLoading: boolean;
31-
/** The urrent active step of the wizard */
31+
/** The current active step of the wizard */
3232
activeStep: number;
3333
/** Indicate if the current step is the first step (aka no previous step) */
3434
isFirstStep: boolean;

0 commit comments

Comments
 (0)