Skip to content

Commit a417cfa

Browse files
committed
Refactor mask with dynamic svg shape + Add rounded prop
1 parent e26c684 commit a417cfa

File tree

10 files changed

+130
-117
lines changed

10 files changed

+130
-117
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ npm-debug.log
33
/dist
44
/lib
55
.idea
6+
.DS_Store

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ const steps = [
7979
| `onRequestClose` | Function triggered to close | `func` | | |
8080
| `prevButton` | Prev navigation button text | `node` | | |
8181
| `prevStep` | Override default `prevStep` function to use a custom one | `func` | | |
82+
| `rounded` | Beautify helper + mask with border-radius (in px) | `number` | `0` | |
8283
| `scrollDuration` | Smooth scroll duration when positioning the target element | `number` | `1` | |
8384
| `scrollOffset` | Offset when positioning the target element | `number` | calculates the vertical center of the page | |
8485
| `showButtons` | Show **helper** navigation butons | `bool` | `true` | |

docs/bundle.js

+32-18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/bundle.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/TourPortal.js

+12-36
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,10 @@ import {
88
Close,
99
Guide,
1010
Badge,
11-
TopMask,
12-
RightMask,
13-
BottomMask,
14-
LeftMask,
15-
ElementMask,
1611
Controls,
1712
Navigation,
1813
Dot,
14+
SvgMask,
1915
} from './components/index'
2016
import * as hx from './helpers'
2117

@@ -64,6 +60,7 @@ class TourPortal extends Component {
6460
disableInteraction: PropTypes.bool,
6561
disableNavigationDotsInteraction: PropTypes.bool,
6662
disableKeyboardNavigation: PropTypes.bool,
63+
rounded: PropTypes.number,
6764
}
6865

6966
static defaultProps = {
@@ -81,6 +78,7 @@ class TourPortal extends Component {
8178
maskSpace: 10,
8279
updateDelay: 1,
8380
disableInteraction: false,
81+
rounded: 0,
8482
}
8583

8684
constructor() {
@@ -271,7 +269,7 @@ class TourPortal extends Component {
271269

272270
maskClickHandler = e => {
273271
const { closeWithMask, onRequestClose } = this.props
274-
if (closeWithMask) {
272+
if (closeWithMask && !e.target.classList.contains(CN.mask.disableInteraction)) {
275273
onRequestClose(e)
276274
}
277275
}
@@ -366,6 +364,7 @@ class TourPortal extends Component {
366364
disableNavigationDotsInteraction,
367365
nextStep,
368366
prevStep,
367+
rounded,
369368
} = this.props
370369

371370
const {
@@ -394,45 +393,20 @@ class TourPortal extends Component {
394393
className={cn(CN.mask.base, {
395394
[CN.mask.isOpen]: isOpen,
396395
})}>
397-
<TopMask
398-
targetTop={targetTop}
399-
padding={maskSpace}
400-
className={maskClassName}
401-
/>
402-
<RightMask
403-
targetTop={targetTop}
404-
targetLeft={targetLeft}
405-
targetWidth={targetWidth}
406-
targetHeight={targetHeight}
396+
<SvgMask
407397
windowWidth={windowWidth}
408-
padding={maskSpace}
409-
className={maskClassName}
410-
/>
411-
<BottomMask
412-
targetHeight={targetHeight}
413-
targetTop={targetTop}
414398
windowHeight={windowHeight}
415-
padding={maskSpace}
416-
className={maskClassName}
417-
/>
418-
<LeftMask
399+
targetWidth={targetWidth}
419400
targetHeight={targetHeight}
420401
targetTop={targetTop}
421402
targetLeft={targetLeft}
422403
padding={maskSpace}
404+
rounded={rounded}
423405
className={maskClassName}
406+
disableInteraction={disableInteraction}
407+
disableInteractionClassName={CN.mask.disableInteraction}
424408
/>
425409
</div>
426-
{disableInteraction && (
427-
<ElementMask
428-
targetTop={targetTop}
429-
targetLeft={targetLeft}
430-
targetWidth={targetWidth}
431-
targetHeight={targetHeight}
432-
padding={maskSpace}
433-
className={highlightedMaskClassName}
434-
/>
435-
)}
436410
<Guide
437411
innerRef={c => (this.helper = c)}
438412
targetHeight={targetHeight}
@@ -450,6 +424,7 @@ class TourPortal extends Component {
450424
tabIndex={-1}
451425
current={current}
452426
style={steps[current].style ? steps[current].style : {}}
427+
rounded={rounded}
453428
className={cn(CN.helper.base, className, {
454429
[CN.helper.isOpen]: isOpen,
455430
})}>
@@ -532,6 +507,7 @@ const CN = {
532507
mask: {
533508
base: 'reactour__mask',
534509
isOpen: 'reactour__mask--is-open',
510+
disableInteraction: 'reactour__mask--disable-interaction',
535511
},
536512
helper: {
537513
base: 'reactour__helper',

src/components/Guide.js

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const Guide = styled.div`
1616
min-width: 150px;
1717
outline: 0;
1818
padding-right: 40px;
19+
border-radius: ${props => props.rounded}px;
1920
2021
transform: ${props => {
2122
const {

src/components/Masks.js

-56
This file was deleted.

src/components/SvgMask.js

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import React from 'react'
2+
import styled from 'styled-components'
3+
import * as hx from '../helpers'
4+
5+
const SvgMask = styled.div`
6+
opacity: 0.7;
7+
width: 100%;
8+
left: 0;
9+
top: 0;
10+
height: 100%;
11+
position: fixed;
12+
z-index: 99999;
13+
pointer-events: none;
14+
`
15+
16+
export default ({
17+
windowWidth,
18+
windowHeight,
19+
targetWidth,
20+
targetHeight,
21+
targetTop,
22+
targetLeft,
23+
padding,
24+
rounded,
25+
disableInteraction,
26+
disableInteractionClassName
27+
}) => {
28+
const width = hx.safe(targetWidth + padding * 2)
29+
const height = hx.safe(targetHeight + padding * 2)
30+
const top = hx.safe(targetTop - padding)
31+
const left = hx.safe(targetLeft - padding)
32+
33+
return (
34+
<SvgMask>
35+
<svg width={windowWidth} height={windowHeight} xmlns="http://www.w3.org/2000/svg">
36+
<defs>
37+
<mask id="mask-main">
38+
<rect x={0} y={0} width={windowWidth} height={windowHeight} fill="white" />
39+
<rect x={left} y={top} width={width} height={height} fill="black" />
40+
{/* top left rounded corner */}
41+
<rect x={left - 1} y={top - 1} width={rounded} height={rounded} fill="white" />
42+
<circle cx={left + rounded} cy={top + rounded} r={rounded} fill="black" />
43+
{/* top right rounded corner */}
44+
<rect x={left + width - rounded + 1} y={top - 1} width={rounded} height={rounded} fill="white" />
45+
<circle cx={left + width - rounded} cy={top + rounded} r={rounded} fill="black" />
46+
{/* bottom left rounded corner */}
47+
<rect x={left - 1} y={top + height - rounded + 1} width={rounded} height={rounded} fill="white" />
48+
<circle cx={left + rounded} cy={top + height - rounded} r={rounded} fill="black" />
49+
{/* bottom right rounded corner */}
50+
<rect x={left + width - rounded + 1} y={top + height - rounded + 1} width={rounded} height={rounded} fill="white" />
51+
<circle cx={left + width - rounded} cy={top + height - rounded} r={rounded} fill="black "/>
52+
</mask>
53+
<clipPath id="clip-path">
54+
{/* top */}
55+
<rect x={0} y={0} width={windowWidth} height={top} />
56+
{/* left */}
57+
<rect x={0} y={top} width={left} height={height} />
58+
{/* right */}
59+
<rect x={targetLeft + targetWidth + padding} y={top} width={hx.safe(windowWidth - targetWidth - left)} height={height} />
60+
{/* bottom */}
61+
<rect x={0} y={targetTop + targetHeight + padding} width={windowWidth} height={hx.safe(windowHeight - targetHeight - top)} />
62+
</clipPath>
63+
</defs>
64+
<rect x={0} y={0} width={windowWidth} height={windowHeight} fill="#000000" mask="url(#mask-main)" />
65+
<rect x={0} y={0} width={windowWidth} height={windowHeight} fill="#000000" clipPath="url(#clip-path)" pointerEvents="auto" />
66+
<rect
67+
x={left}
68+
y={top}
69+
width={width}
70+
height={height}
71+
pointerEvents="auto"
72+
fill="transparent"
73+
display={disableInteraction ? "block" : "none"}
74+
className={disableInteractionClassName}
75+
/>
76+
</svg>
77+
</SvgMask>
78+
)
79+
}

src/components/index.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ export { default as Arrow } from './Arrow'
22
export { default as Close } from './Close'
33
export { default as Guide } from './Guide'
44
export { default as Badge } from './Badge'
5-
export { TopMask } from './Masks'
6-
export { RightMask } from './Masks'
7-
export { BottomMask } from './Masks'
8-
export { LeftMask } from './Masks'
9-
export { ElementMask } from './Masks'
105
export { default as Controls } from './Controls'
116
export { default as Navigation } from './Navigation'
127
export { default as Dot } from './Dot'
8+
export { default as SvgMask } from './SvgMask'

src/demo/App.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class App extends Component {
4545
isOpen={isTourOpen}
4646
maskClassName="mask"
4747
className="helper"
48+
rounded={5}
4849
/>
4950
</div>
5051
)
@@ -62,7 +63,7 @@ const tourConfig = [
6263
},
6364
{
6465
selector: '[data-tut="reactour__copy"]',
65-
content: `Keep in mind that you could try and test everithing during the Tour.
66+
content: `Keep in mind that you could try and test everything during the Tour.
6667
For example, try selecting the highlighted text…`,
6768
},
6869
{

0 commit comments

Comments
 (0)