Skip to content

Commit 5f3167d

Browse files
Add Pointer Events DOM Fixture
1 parent 135e820 commit 5f3167d

File tree

7 files changed

+224
-0
lines changed

7 files changed

+224
-0
lines changed

fixtures/dom/src/components/Header.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class Header extends React.Component {
6464
<option value="/event-pooling">Event Pooling</option>
6565
<option value="/custom-elements">Custom Elements</option>
6666
<option value="/media-events">Media Events</option>
67+
<option value="/pointer-events">Pointer Events</option>
6768
</select>
6869
</label>
6970
<label htmlFor="react_version">

fixtures/dom/src/components/fixtures/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import ErrorHandling from './error-handling';
1111
import EventPooling from './event-pooling';
1212
import CustomElementFixtures from './custom-elements';
1313
import MediaEventsFixtures from './media-events';
14+
import PointerEventsFixtures from './pointer-events';
1415

1516
const React = window.React;
1617

@@ -46,6 +47,8 @@ function FixturesPage() {
4647
return <CustomElementFixtures />;
4748
case '/media-events':
4849
return <MediaEventsFixtures />;
50+
case '/pointer-events':
51+
return <PointerEventsFixtures />;
4952
default:
5053
return <p>Please select a test fixture.</p>;
5154
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const React = window.React;
2+
3+
const CIRCLE_SIZE = 80;
4+
5+
class DragBox extends React.Component {
6+
state = {
7+
hasCapture: false,
8+
circleLeft: 80,
9+
circleTop: 80,
10+
};
11+
isDragging = false;
12+
previousLeft = 0;
13+
previousTop = 0;
14+
15+
onDown = event => {
16+
this.isDragging = true;
17+
event.target.setPointerCapture(event.pointerId);
18+
19+
// We store the initial coordinates to be able to calculate the changes
20+
// later on.
21+
this.extractPositionDelta(event);
22+
};
23+
24+
onMove = event => {
25+
if (!this.isDragging) {
26+
return;
27+
}
28+
const {left, top} = this.extractPositionDelta(event);
29+
30+
this.setState(({circleLeft, circleTop}) => ({
31+
circleLeft: circleLeft + left,
32+
circleTop: circleTop + top,
33+
}));
34+
};
35+
36+
onUp = event => (this.isDragging = false);
37+
onGotCapture = event => this.setState({hasCapture: true});
38+
onLostCapture = event => this.setState({hasCapture: false});
39+
40+
extractPositionDelta = event => {
41+
const left = event.pageX;
42+
const top = event.pageY;
43+
const delta = {
44+
left: left - this.previousLeft,
45+
top: top - this.previousTop,
46+
};
47+
this.previousLeft = left;
48+
this.previousTop = top;
49+
return delta;
50+
};
51+
52+
render() {
53+
const {hasCapture, circleLeft, circleTop} = this.state;
54+
55+
const boxStyle = {
56+
border: '1px solid #d9d9d9',
57+
margin: '10px 0 20px',
58+
minHeight: 400,
59+
width: '100%',
60+
position: 'relative',
61+
};
62+
63+
const circleStyle = {
64+
width: CIRCLE_SIZE,
65+
height: CIRCLE_SIZE,
66+
borderRadius: CIRCLE_SIZE / 2,
67+
position: 'absolute',
68+
left: circleLeft,
69+
top: circleTop,
70+
backgroundColor: hasCapture ? 'blue' : 'green',
71+
touchAction: 'none',
72+
};
73+
74+
return (
75+
<div style={boxStyle}>
76+
<div
77+
style={circleStyle}
78+
onPointerDown={this.onDown}
79+
onPointerMove={this.onMove}
80+
onPointerUp={this.onUp}
81+
onPointerCancel={this.onUp}
82+
onGotPointerCapture={this.onGotCapture}
83+
onLostPointerCapture={this.onLostCapture}
84+
/>
85+
</div>
86+
);
87+
}
88+
}
89+
90+
export default DragBox;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import TestCase from '../../TestCase';
2+
import DragBox from './drag-box';
3+
4+
const React = window.React;
5+
6+
class Drag extends React.Component {
7+
render() {
8+
return (
9+
<TestCase title="Drag" description="">
10+
<TestCase.Steps>
11+
<li>Drag the circle below with any pointer tool</li>
12+
</TestCase.Steps>
13+
14+
<TestCase.ExpectedResult>
15+
While dragging, the circle must have turn blue to indicate that a
16+
pointer capture was received.
17+
</TestCase.ExpectedResult>
18+
19+
<DragBox />
20+
</TestCase>
21+
);
22+
}
23+
}
24+
25+
export default Drag;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const React = window.React;
2+
3+
class DrawBox extends React.Component {
4+
render() {
5+
const boxStyle = {
6+
border: '1px solid #d9d9d9',
7+
margin: '10px 0 20px',
8+
padding: '20px 20px',
9+
touchAction: 'none',
10+
};
11+
12+
const obstacleStyle = {
13+
border: '1px solid #d9d9d9',
14+
width: '25%',
15+
height: '200px',
16+
margin: '12.5%',
17+
display: 'inline-block',
18+
};
19+
20+
return (
21+
<div
22+
style={boxStyle}
23+
onPointerOver={this.props.onOver}
24+
onPointerOut={this.props.onOut}
25+
onPointerEnter={this.props.onEnter}
26+
onPointerLeave={this.props.onLeave}>
27+
<div style={obstacleStyle} />
28+
<div style={obstacleStyle} />
29+
</div>
30+
);
31+
}
32+
}
33+
34+
export default DrawBox;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import TestCase from '../../TestCase';
2+
import HoverBox from './hover-box';
3+
4+
const React = window.React;
5+
6+
class Hover extends React.Component {
7+
state = {
8+
overs: 0,
9+
outs: 0,
10+
enters: 0,
11+
leaves: 0,
12+
};
13+
14+
onOver = () => this.setState({overs: this.state.overs + 1});
15+
onOut = () => this.setState({outs: this.state.outs + 1});
16+
onEnter = () => this.setState({enters: this.state.enters + 1});
17+
onLeave = () => this.setState({leaves: this.state.leaves + 1});
18+
19+
render() {
20+
const {overs, outs, enters, leaves} = this.state;
21+
22+
return (
23+
<TestCase title="Hover" description="">
24+
<TestCase.Steps>
25+
<li>Hover over the above box and the obstacles</li>
26+
</TestCase.Steps>
27+
28+
<TestCase.ExpectedResult>
29+
Overs and outs should increase when moving over the obstacles but
30+
enters and leaves should not.
31+
</TestCase.ExpectedResult>
32+
33+
<HoverBox
34+
onOver={this.onOver}
35+
onOut={this.onOut}
36+
onEnter={this.onEnter}
37+
onLeave={this.onLeave}
38+
/>
39+
40+
<p>
41+
Pointer Overs: <b>{overs}</b> <br />
42+
Pointer Outs: <b>{outs}</b> <br />
43+
Pointer Enters: <b>{enters}</b> <br />
44+
Pointer Leaves: <b>{leaves}</b> <br />
45+
</p>
46+
</TestCase>
47+
);
48+
}
49+
}
50+
51+
export default Hover;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import FixtureSet from '../../FixtureSet';
2+
import Drag from './drag';
3+
import Hover from './hover';
4+
5+
const React = window.React;
6+
7+
class PointerEvents extends React.Component {
8+
render() {
9+
return (
10+
<FixtureSet
11+
title="Pointer Events"
12+
description="Pointer Events are not supported in every browser. The examples below might not work in every browser. To test pointer events, make sure to use Google Chrome, Firefox, Internet Explorer, or Edge.">
13+
<Drag />
14+
<Hover />
15+
</FixtureSet>
16+
);
17+
}
18+
}
19+
20+
export default PointerEvents;

0 commit comments

Comments
 (0)