Skip to content

Commit bc38b1a

Browse files
committed
removed useTourController because it was unnecessary and confusing
1 parent 49c2387 commit bc38b1a

File tree

7 files changed

+220
-273
lines changed

7 files changed

+220
-273
lines changed

lib/TourPopover.jsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import React, { useContext, useState, useEffect, createElement } from 'react'
1+
import React, { useState, useEffect, createElement } from 'react'
22
import { usePopper } from 'react-popper'
3-
import { TourContext } from './TourProvider'
43

54
const modalVirtualElement = {
65
getBoundingClientRect() {
@@ -15,8 +14,8 @@ const modalVirtualElement = {
1514
}
1615
}
1716

18-
export default () => {
19-
const tour = useContext(TourContext)
17+
export default props => {
18+
const tour = props.tour
2019
const step = tour.getCurrentStep()
2120

2221
const [ popperElement, setPopperElement ] = useState(null)

lib/TourProvider.jsx

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,70 @@
1-
import React from 'react'
2-
import useTourController from './useTourController'
3-
import { TourStatus } from './constants'
1+
import React, { useReducer} from 'react'
2+
import generateActions from './actions'
3+
import reducer, { initialState, generateSelectors } from './reducer'
4+
import { getStepConfigType } from './utils'
5+
import { TourStatus, StepConfigType } from './constants'
6+
import useStepChange from './useStepChange'
47
import TourPopover from './TourPopover'
58

69
export const TourContext = React.createContext()
710

811
export default props => {
9-
const tourController = useTourController(props.config)
12+
const tourConfig = props.config
13+
14+
// initialize steps
15+
const steps = {}
16+
tourConfig.stepOrder.forEach((stepConfig, i) => {
17+
switch (getStepConfigType(stepConfig)) {
18+
case StepConfigType.INVALID: {
19+
throw new Error(`Step configuration at position ${i} is not valid.`)
20+
}
21+
case StepConfigType.PREDEF: {
22+
steps[stepConfig.name] = stepConfig
23+
break
24+
}
25+
}
26+
})
27+
28+
// The reducer manages the state of the tour.
29+
// The selectors allow state to be retrieved.
30+
// The actions allow state to be manipulated.
31+
const [state, dispatch] = useReducer(reducer, {
32+
...initialState,
33+
steps,
34+
stepOrder: tourConfig.stepOrder,
35+
tourConfig
36+
})
37+
const selectors = generateSelectors(state)
38+
const allSelectors = {
39+
...selectors.public,
40+
...selectors.protected,
41+
}
42+
const actions = generateActions(allSelectors, dispatch)
43+
const allActions = {
44+
...actions.public,
45+
...actions.protected,
46+
}
47+
48+
// construct the Tour
49+
const tourController = {
50+
...allSelectors,
51+
...allActions,
52+
public: {
53+
...selectors.public,
54+
...actions.public
55+
}
56+
}
57+
58+
// listen for step transitions and properly handle them
59+
useStepChange(tourController)
60+
1061
const shouldShowPopover = tourController.getStatus() === TourStatus.ON && !!tourController.getCurrentStep()
1162

1263
return (
1364
<TourContext.Provider value={tourController}>
1465
<div style={{position: 'relative'}}>
1566
{props.children}
16-
{shouldShowPopover && <TourPopover />}
67+
{shouldShowPopover && <TourPopover tour={tourController} />}
1768
</div>
1869
</TourContext.Provider>
1970
)

lib/useTourController.js

Lines changed: 0 additions & 62 deletions
This file was deleted.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
],
1111
"scripts": {
1212
"test": "jest",
13+
"test:watch": "jest -i --watchAll",
14+
"test:coverage": "jest --coverage",
1315
"start": "parcel serve example/index.html",
1416
"build": "npm run clean && parcel build lib/index.js --target node",
1517
"clean": "rm -rf dist/"

test/TourPopover.test.jsx

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,14 @@ import React from 'react'
22
import { usePopper } from 'react-popper'
33
import { render } from '@testing-library/react'
44
import { TourStatus } from '../lib/constants'
5-
import useTourController from '../lib/useTourController'
6-
import TourProvider from '../lib/TourProvider'
75
import TourPopover from '../lib/TourPopover'
86

97
jest.mock('react-popper')
10-
jest.mock('../lib/useTourController')
118

129
describe('TourPopover Component', () => {
1310
let step
1411
let tour
1512
let ref
16-
let wrapper
1713

1814
beforeEach(() => {
1915
ref = {
@@ -31,10 +27,6 @@ describe('TourPopover Component', () => {
3127
setPopoverRef: jest.fn()
3228
}
3329

34-
useTourController.mockReturnValue(tour)
35-
36-
wrapper = ({ children }) => (<TourProvider config={{}}>{children}</TourProvider>)
37-
3830
usePopper.mockReturnValue({
3931
update: jest.fn(),
4032
styles: {
@@ -56,7 +48,7 @@ describe('TourPopover Component', () => {
5648
step.isModal = false
5749

5850
// when
59-
render(<TourPopover />, { wrapper })
51+
render(<TourPopover tour={tour} />)
6052

6153
// then
6254
expect(usePopper.mock.calls[0][0]).toBe(ref.current)
@@ -68,7 +60,7 @@ describe('TourPopover Component', () => {
6860
step.isModal = true
6961

7062
// when
71-
render(<TourPopover />, { wrapper })
63+
render(<TourPopover tour={tour} />)
7264

7365
// then
7466
expect(usePopper.mock.calls[0][0]).toHaveProperty('getBoundingClientRect')
@@ -80,15 +72,15 @@ describe('TourPopover Component', () => {
8072
step.offset = 100
8173

8274
// when
83-
render(<TourPopover />, { wrapper })
75+
render(<TourPopover tour={tour} />)
8476

8577
// then
8678
expect(usePopper.mock.calls[0][2].modifiers[1].options.offset).toEqual([0, 100])
8779
})
8880

8981
it('should register the popperElement with the tour', async () => {
9082
// when
91-
render(<TourPopover />, { wrapper })
83+
render(<TourPopover tour={tour} />)
9284

9385
expect(tour.setPopoverRef).toHaveBeenCalledWith({
9486
current: expect.anything()
@@ -101,7 +93,7 @@ describe('TourPopover Component', () => {
10193
step.PopoverComponent = props => props.step.title
10294

10395
// when
104-
const { getByText } = render(<TourPopover />, { wrapper })
96+
const { getByText } = render(<TourPopover tour={tour} />)
10597

10698
// then
10799
expect(getByText('Title').textContent).toBe('Title')
@@ -112,7 +104,7 @@ describe('TourPopover Component', () => {
112104
step.popoverTemplate = <div>Template</div>
113105

114106
// when
115-
const { getByText } = render(<TourPopover />, { wrapper })
107+
const { getByText } = render(<TourPopover tour={tour} />)
116108

117109
// then
118110
expect(getByText('Template').textContent).toBe('Template')
@@ -123,7 +115,7 @@ describe('TourPopover Component', () => {
123115
step.isModal = true
124116

125117
// when
126-
const { getByTestId } = render(<TourPopover />, { wrapper })
118+
const { getByTestId } = render(<TourPopover tour={tour} />)
127119

128120
// then
129121
expect(getByTestId('popover').style.position).toBe('fixed')
@@ -134,7 +126,7 @@ describe('TourPopover Component', () => {
134126
step.isModal = false
135127

136128
// when
137-
const { getByTestId } = render(<TourPopover />, { wrapper })
129+
const { getByTestId } = render(<TourPopover tour={tour} />)
138130

139131
// then
140132
expect(getByTestId('popover').style.color).toBe('red')
@@ -145,7 +137,7 @@ describe('TourPopover Component', () => {
145137
step.isModal = false
146138

147139
// when
148-
const { getByTestId } = render(<TourPopover />, { wrapper })
140+
const { getByTestId } = render(<TourPopover tour={tour} />)
149141

150142
// then
151143
expect(getByTestId('popover').dataset.test).toBe('test')
@@ -156,7 +148,7 @@ describe('TourPopover Component', () => {
156148
step.popoverClassName = 'POP'
157149

158150
// when
159-
const { getByTestId } = render(<TourPopover />, { wrapper })
151+
const { getByTestId } = render(<TourPopover tour={tour} />)
160152

161153
// then
162154
expect(getByTestId('popover').classList).toContain('POP')

0 commit comments

Comments
 (0)