@gm-pc/tour 1.27.0 → 1.27.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/package.json +5 -5
- package/src/components/action.tsx +29 -29
- package/src/components/guide.tsx +140 -140
- package/src/components/index.ts +1 -1
- package/src/components/portal.tsx +23 -23
- package/src/components/svg_mask.tsx +168 -168
- package/src/hook.ts +19 -19
- package/src/index.ts +2 -2
- package/src/reducer.ts +55 -55
- package/src/stories.tsx +310 -310
- package/src/tour.tsx +276 -276
- package/src/types.ts +52 -52
- package/src/utils.ts +172 -172
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# `tour`
|
|
2
|
-
|
|
3
|
-
> TODO: description
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
const tour = require('tour');
|
|
9
|
-
|
|
10
|
-
// TODO: DEMONSTRATE API
|
|
11
|
-
```
|
|
1
|
+
# `tour`
|
|
2
|
+
|
|
3
|
+
> TODO: description
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
const tour = require('tour');
|
|
9
|
+
|
|
10
|
+
// TODO: DEMONSTRATE API
|
|
11
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gm-pc/tour",
|
|
3
|
-
"version": "1.27.0",
|
|
3
|
+
"version": "1.27.1-beta.0",
|
|
4
4
|
"description": "观麦科技引导设置",
|
|
5
5
|
"author": "zhongsink <zhongink@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/gmfe/gm-pc#readme",
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"styled-components": "^5.1.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@gm-pc/locales": "^1.27.0",
|
|
31
|
-
"@gm-pc/react": "^1.27.0",
|
|
32
|
-
"@gm-pc/table-x": "^1.27.0",
|
|
30
|
+
"@gm-pc/locales": "^1.27.1-beta.0",
|
|
31
|
+
"@gm-pc/react": "^1.27.1-beta.0",
|
|
32
|
+
"@gm-pc/table-x": "^1.27.1-beta.0",
|
|
33
33
|
"classnames": "^2.2.5",
|
|
34
34
|
"lodash": "^4.17.19",
|
|
35
35
|
"styled-components": "^5.1.0"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "eecad3bce81dd37787dc6e90f6ecfc2ee666ad26"
|
|
38
38
|
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import React, { FC, MouseEvent } from 'react'
|
|
2
|
-
import { Button } from '@gm-pc/react'
|
|
3
|
-
import { getLocale } from '@gm-pc/locales'
|
|
4
|
-
|
|
5
|
-
interface ActionProps {
|
|
6
|
-
isLastItem: boolean
|
|
7
|
-
|
|
8
|
-
onNextStep(): void
|
|
9
|
-
|
|
10
|
-
onClose(event: MouseEvent): void
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const Action: FC<ActionProps> = ({ isLastItem, onNextStep, onClose }) => {
|
|
14
|
-
return (
|
|
15
|
-
<div className='gm-flex gm-flex-justify-end gm-padding-top-10'>
|
|
16
|
-
{isLastItem ? (
|
|
17
|
-
<Button type='primary' onClick={onClose}>
|
|
18
|
-
{getLocale('马上尝试')}
|
|
19
|
-
</Button>
|
|
20
|
-
) : (
|
|
21
|
-
<Button type='primary' onClick={onNextStep}>
|
|
22
|
-
{getLocale('下一步')}
|
|
23
|
-
</Button>
|
|
24
|
-
)}
|
|
25
|
-
</div>
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default Action
|
|
1
|
+
import React, { FC, MouseEvent } from 'react'
|
|
2
|
+
import { Button } from '@gm-pc/react'
|
|
3
|
+
import { getLocale } from '@gm-pc/locales'
|
|
4
|
+
|
|
5
|
+
interface ActionProps {
|
|
6
|
+
isLastItem: boolean
|
|
7
|
+
|
|
8
|
+
onNextStep(): void
|
|
9
|
+
|
|
10
|
+
onClose(event: MouseEvent): void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const Action: FC<ActionProps> = ({ isLastItem, onNextStep, onClose }) => {
|
|
14
|
+
return (
|
|
15
|
+
<div className='gm-flex gm-flex-justify-end gm-padding-top-10'>
|
|
16
|
+
{isLastItem ? (
|
|
17
|
+
<Button type='primary' onClick={onClose}>
|
|
18
|
+
{getLocale('马上尝试')}
|
|
19
|
+
</Button>
|
|
20
|
+
) : (
|
|
21
|
+
<Button type='primary' onClick={onNextStep}>
|
|
22
|
+
{getLocale('下一步')}
|
|
23
|
+
</Button>
|
|
24
|
+
)}
|
|
25
|
+
</div>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default Action
|
package/src/components/guide.tsx
CHANGED
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
import React, { CSSProperties, FC, HTMLAttributes, RefObject } from 'react'
|
|
2
|
-
import * as utils from '../utils'
|
|
3
|
-
import { ReducerState } from '../reducer'
|
|
4
|
-
import { TourStepItem } from '../types'
|
|
5
|
-
|
|
6
|
-
type Position = TourStepItem['position']
|
|
7
|
-
|
|
8
|
-
interface GuideProps extends HTMLAttributes<HTMLDivElement> {
|
|
9
|
-
ref: RefObject<HTMLDivElement>
|
|
10
|
-
windowWidth: number
|
|
11
|
-
windowHeight: number
|
|
12
|
-
targetWidth: number
|
|
13
|
-
targetHeight: number
|
|
14
|
-
targetTop: number
|
|
15
|
-
targetLeft: number
|
|
16
|
-
targetRight: number
|
|
17
|
-
targetBottom: number
|
|
18
|
-
helperWidth: number
|
|
19
|
-
helperHeight: number
|
|
20
|
-
helperPosition: ReducerState['helperPosition']
|
|
21
|
-
padding: number
|
|
22
|
-
current: number
|
|
23
|
-
rounded: number
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const Guide: FC<GuideProps> = (props) => {
|
|
27
|
-
const transform = () => {
|
|
28
|
-
const {
|
|
29
|
-
targetTop,
|
|
30
|
-
targetRight,
|
|
31
|
-
targetBottom,
|
|
32
|
-
targetLeft,
|
|
33
|
-
windowWidth,
|
|
34
|
-
windowHeight,
|
|
35
|
-
helperWidth,
|
|
36
|
-
helperHeight,
|
|
37
|
-
helperPosition,
|
|
38
|
-
padding,
|
|
39
|
-
} = props
|
|
40
|
-
|
|
41
|
-
const available = {
|
|
42
|
-
left: targetLeft,
|
|
43
|
-
right: windowWidth - targetRight,
|
|
44
|
-
top: targetTop,
|
|
45
|
-
bottom: windowHeight - targetBottom,
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const couldPositionAt = (position: Position) => {
|
|
49
|
-
return (
|
|
50
|
-
available[position as Exclude<Position, undefined | number[] | 'center'>] >
|
|
51
|
-
(utils.isHoriz(position as string)
|
|
52
|
-
? helperWidth + padding * 2
|
|
53
|
-
: helperHeight + padding * 2)
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const autoPosition = (coords: {
|
|
58
|
-
left: number[]
|
|
59
|
-
right: number[]
|
|
60
|
-
top: number[]
|
|
61
|
-
bottom: number[]
|
|
62
|
-
center: number[]
|
|
63
|
-
}) => {
|
|
64
|
-
const positionsOrder = utils.bestPositionOf(available)
|
|
65
|
-
for (let j = 0; j < positionsOrder.length; j++) {
|
|
66
|
-
if (couldPositionAt(positionsOrder[j] as Position)) {
|
|
67
|
-
return coords[
|
|
68
|
-
positionsOrder[j] as 'left' | 'right' | 'top' | 'bottom' | 'center'
|
|
69
|
-
]
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return coords.center
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const pos = (helperPosition: TourStepItem['position']) => {
|
|
76
|
-
if (Array.isArray(helperPosition)) {
|
|
77
|
-
const isOutX = utils.isOutsideX(helperPosition[0], windowWidth)
|
|
78
|
-
const isOutY = utils.isOutsideY(helperPosition[1], windowHeight)
|
|
79
|
-
const warn = (axis: string, num: number) => {
|
|
80
|
-
console.warn(`${axis}:${num} is outside window, falling back to center`)
|
|
81
|
-
}
|
|
82
|
-
if (isOutX) warn('x', helperPosition[0])
|
|
83
|
-
if (isOutY) warn('y', helperPosition[1])
|
|
84
|
-
return [
|
|
85
|
-
isOutX ? windowWidth / 2 - helperWidth / 2 : helperPosition[0],
|
|
86
|
-
isOutY ? windowHeight / 2 - helperHeight / 2 : helperPosition[1],
|
|
87
|
-
]
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const hX = utils.isOutsideX(targetLeft + helperWidth, windowWidth)
|
|
91
|
-
? utils.isOutsideX(targetRight + padding, windowWidth)
|
|
92
|
-
? targetRight - helperWidth
|
|
93
|
-
: targetRight - helperWidth + padding
|
|
94
|
-
: targetLeft - padding
|
|
95
|
-
const x = hX > padding ? hX : padding
|
|
96
|
-
const hY = utils.isOutsideY(targetTop + helperHeight, windowHeight)
|
|
97
|
-
? utils.isOutsideY(targetBottom + padding, windowHeight)
|
|
98
|
-
? targetBottom - helperHeight
|
|
99
|
-
: targetBottom - helperHeight + padding
|
|
100
|
-
: targetTop - padding
|
|
101
|
-
const y = hY > padding ? hY : padding
|
|
102
|
-
const coords = {
|
|
103
|
-
top: [x, targetTop - helperHeight - padding * 2],
|
|
104
|
-
right: [targetRight + padding * 2, y],
|
|
105
|
-
bottom: [x, targetBottom + padding * 2],
|
|
106
|
-
left: [targetLeft - helperWidth - padding * 2, y],
|
|
107
|
-
center: [windowWidth / 2 - helperWidth / 2, windowHeight / 2 - helperHeight / 2],
|
|
108
|
-
}
|
|
109
|
-
if (helperPosition === 'center' || couldPositionAt(helperPosition)) {
|
|
110
|
-
return coords[helperPosition!]
|
|
111
|
-
}
|
|
112
|
-
return autoPosition(coords)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const p = pos(helperPosition)
|
|
116
|
-
|
|
117
|
-
return `translate(${Math.round(p[0])}px, ${Math.round(p[1])}px)`
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const style: CSSProperties = {
|
|
121
|
-
maxWidth: '350px',
|
|
122
|
-
minWidth: '200px',
|
|
123
|
-
paddingRight: '40px',
|
|
124
|
-
backgroundColor: '#fff',
|
|
125
|
-
boxShadow: '0 0.5em 3em rgba(0, 0, 0, 0.3)',
|
|
126
|
-
color: 'inherit',
|
|
127
|
-
borderRadius: `${props.rounded}px`,
|
|
128
|
-
position: 'fixed',
|
|
129
|
-
transition: 'transform 0.3s',
|
|
130
|
-
top: 0,
|
|
131
|
-
left: 0,
|
|
132
|
-
outline: 'none',
|
|
133
|
-
zIndex: 1000000,
|
|
134
|
-
transform: transform(),
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return <div {...props} style={style} />
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export default Guide
|
|
1
|
+
import React, { CSSProperties, FC, HTMLAttributes, RefObject } from 'react'
|
|
2
|
+
import * as utils from '../utils'
|
|
3
|
+
import { ReducerState } from '../reducer'
|
|
4
|
+
import { TourStepItem } from '../types'
|
|
5
|
+
|
|
6
|
+
type Position = TourStepItem['position']
|
|
7
|
+
|
|
8
|
+
interface GuideProps extends HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
ref: RefObject<HTMLDivElement>
|
|
10
|
+
windowWidth: number
|
|
11
|
+
windowHeight: number
|
|
12
|
+
targetWidth: number
|
|
13
|
+
targetHeight: number
|
|
14
|
+
targetTop: number
|
|
15
|
+
targetLeft: number
|
|
16
|
+
targetRight: number
|
|
17
|
+
targetBottom: number
|
|
18
|
+
helperWidth: number
|
|
19
|
+
helperHeight: number
|
|
20
|
+
helperPosition: ReducerState['helperPosition']
|
|
21
|
+
padding: number
|
|
22
|
+
current: number
|
|
23
|
+
rounded: number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const Guide: FC<GuideProps> = (props) => {
|
|
27
|
+
const transform = () => {
|
|
28
|
+
const {
|
|
29
|
+
targetTop,
|
|
30
|
+
targetRight,
|
|
31
|
+
targetBottom,
|
|
32
|
+
targetLeft,
|
|
33
|
+
windowWidth,
|
|
34
|
+
windowHeight,
|
|
35
|
+
helperWidth,
|
|
36
|
+
helperHeight,
|
|
37
|
+
helperPosition,
|
|
38
|
+
padding,
|
|
39
|
+
} = props
|
|
40
|
+
|
|
41
|
+
const available = {
|
|
42
|
+
left: targetLeft,
|
|
43
|
+
right: windowWidth - targetRight,
|
|
44
|
+
top: targetTop,
|
|
45
|
+
bottom: windowHeight - targetBottom,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const couldPositionAt = (position: Position) => {
|
|
49
|
+
return (
|
|
50
|
+
available[position as Exclude<Position, undefined | number[] | 'center'>] >
|
|
51
|
+
(utils.isHoriz(position as string)
|
|
52
|
+
? helperWidth + padding * 2
|
|
53
|
+
: helperHeight + padding * 2)
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const autoPosition = (coords: {
|
|
58
|
+
left: number[]
|
|
59
|
+
right: number[]
|
|
60
|
+
top: number[]
|
|
61
|
+
bottom: number[]
|
|
62
|
+
center: number[]
|
|
63
|
+
}) => {
|
|
64
|
+
const positionsOrder = utils.bestPositionOf(available)
|
|
65
|
+
for (let j = 0; j < positionsOrder.length; j++) {
|
|
66
|
+
if (couldPositionAt(positionsOrder[j] as Position)) {
|
|
67
|
+
return coords[
|
|
68
|
+
positionsOrder[j] as 'left' | 'right' | 'top' | 'bottom' | 'center'
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return coords.center
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const pos = (helperPosition: TourStepItem['position']) => {
|
|
76
|
+
if (Array.isArray(helperPosition)) {
|
|
77
|
+
const isOutX = utils.isOutsideX(helperPosition[0], windowWidth)
|
|
78
|
+
const isOutY = utils.isOutsideY(helperPosition[1], windowHeight)
|
|
79
|
+
const warn = (axis: string, num: number) => {
|
|
80
|
+
console.warn(`${axis}:${num} is outside window, falling back to center`)
|
|
81
|
+
}
|
|
82
|
+
if (isOutX) warn('x', helperPosition[0])
|
|
83
|
+
if (isOutY) warn('y', helperPosition[1])
|
|
84
|
+
return [
|
|
85
|
+
isOutX ? windowWidth / 2 - helperWidth / 2 : helperPosition[0],
|
|
86
|
+
isOutY ? windowHeight / 2 - helperHeight / 2 : helperPosition[1],
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const hX = utils.isOutsideX(targetLeft + helperWidth, windowWidth)
|
|
91
|
+
? utils.isOutsideX(targetRight + padding, windowWidth)
|
|
92
|
+
? targetRight - helperWidth
|
|
93
|
+
: targetRight - helperWidth + padding
|
|
94
|
+
: targetLeft - padding
|
|
95
|
+
const x = hX > padding ? hX : padding
|
|
96
|
+
const hY = utils.isOutsideY(targetTop + helperHeight, windowHeight)
|
|
97
|
+
? utils.isOutsideY(targetBottom + padding, windowHeight)
|
|
98
|
+
? targetBottom - helperHeight
|
|
99
|
+
: targetBottom - helperHeight + padding
|
|
100
|
+
: targetTop - padding
|
|
101
|
+
const y = hY > padding ? hY : padding
|
|
102
|
+
const coords = {
|
|
103
|
+
top: [x, targetTop - helperHeight - padding * 2],
|
|
104
|
+
right: [targetRight + padding * 2, y],
|
|
105
|
+
bottom: [x, targetBottom + padding * 2],
|
|
106
|
+
left: [targetLeft - helperWidth - padding * 2, y],
|
|
107
|
+
center: [windowWidth / 2 - helperWidth / 2, windowHeight / 2 - helperHeight / 2],
|
|
108
|
+
}
|
|
109
|
+
if (helperPosition === 'center' || couldPositionAt(helperPosition)) {
|
|
110
|
+
return coords[helperPosition!]
|
|
111
|
+
}
|
|
112
|
+
return autoPosition(coords)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const p = pos(helperPosition)
|
|
116
|
+
|
|
117
|
+
return `translate(${Math.round(p[0])}px, ${Math.round(p[1])}px)`
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const style: CSSProperties = {
|
|
121
|
+
maxWidth: '350px',
|
|
122
|
+
minWidth: '200px',
|
|
123
|
+
paddingRight: '40px',
|
|
124
|
+
backgroundColor: '#fff',
|
|
125
|
+
boxShadow: '0 0.5em 3em rgba(0, 0, 0, 0.3)',
|
|
126
|
+
color: 'inherit',
|
|
127
|
+
borderRadius: `${props.rounded}px`,
|
|
128
|
+
position: 'fixed',
|
|
129
|
+
transition: 'transform 0.3s',
|
|
130
|
+
top: 0,
|
|
131
|
+
left: 0,
|
|
132
|
+
outline: 'none',
|
|
133
|
+
zIndex: 1000000,
|
|
134
|
+
transform: transform(),
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return <div {...props} style={style} />
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export default Guide
|
package/src/components/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as Portal } from './portal'
|
|
1
|
+
export { default as Portal } from './portal'
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { FC, useEffect, useRef } from 'react'
|
|
2
|
-
import { createPortal } from 'react-dom'
|
|
3
|
-
import _ from 'lodash'
|
|
4
|
-
|
|
5
|
-
const Portal: FC = ({ children }) => {
|
|
6
|
-
const ref = useRef<HTMLDivElement>()
|
|
7
|
-
|
|
8
|
-
if (_.isNil(ref.current)) {
|
|
9
|
-
ref.current = document.createElement('div')
|
|
10
|
-
ref.current!.setAttribute('id', '___gmtour')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
ref.current && document.body.appendChild(ref.current)
|
|
15
|
-
return () => {
|
|
16
|
-
document.body.removeChild(ref.current!)
|
|
17
|
-
}
|
|
18
|
-
}, [ref])
|
|
19
|
-
|
|
20
|
-
return createPortal(children, ref.current!)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export default Portal
|
|
1
|
+
import { FC, useEffect, useRef } from 'react'
|
|
2
|
+
import { createPortal } from 'react-dom'
|
|
3
|
+
import _ from 'lodash'
|
|
4
|
+
|
|
5
|
+
const Portal: FC = ({ children }) => {
|
|
6
|
+
const ref = useRef<HTMLDivElement>()
|
|
7
|
+
|
|
8
|
+
if (_.isNil(ref.current)) {
|
|
9
|
+
ref.current = document.createElement('div')
|
|
10
|
+
ref.current!.setAttribute('id', '___gmtour')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
ref.current && document.body.appendChild(ref.current)
|
|
15
|
+
return () => {
|
|
16
|
+
document.body.removeChild(ref.current!)
|
|
17
|
+
}
|
|
18
|
+
}, [ref])
|
|
19
|
+
|
|
20
|
+
return createPortal(children, ref.current!)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default Portal
|