Skip to content

Commit

Permalink
UI: add mouse hover action props to grid, hex, and token (#153)
Browse files Browse the repository at this point in the history
* add onMouseOver and onMouseOut action props to grid/hex/token, fixes #152

* update HexGrid storybook to demo onMouseOver action
  • Loading branch information
StevenHeinrich authored and nicolodavis committed Mar 17, 2018
1 parent f664237 commit 748f36f
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 6 deletions.
54 changes: 52 additions & 2 deletions src/ui/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import PropTypes from 'prop-types';
* colorMap - A map from 'x,y' => color.
* onClick - (x, y) => {}
* Called when a square is clicked.
* onMouseOver - (x, y) => {}
* Called when a square is mouse over.
* onMouseOut - (x, y) => {}
* Called when a square is mouse out.
*
* Usage:
*
Expand All @@ -37,6 +41,8 @@ export class Grid extends React.Component {
colorMap: PropTypes.object,
cellSize: PropTypes.number,
onClick: PropTypes.func,
onMouseOver: PropTypes.func,
onMouseOut: PropTypes.func,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.element),
PropTypes.element,
Expand Down Expand Up @@ -74,6 +80,8 @@ export class Grid extends React.Component {
y={y}
size={this.props.cellSize}
onClick={this.onClick}
onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut}
/>
);
}
Expand All @@ -87,11 +95,25 @@ export class Grid extends React.Component {
}
};

onMouseOver = args => {
if (this.props.onMouseOver) {
this.props.onMouseOver(args);
}
};

onMouseOut = args => {
if (this.props.onMouseOut) {
this.props.onMouseOut(args);
}
};

render() {
const tokens = React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
_inGrid: true,
onClick: this.onClick,
onMouseOver: this.onMouseOver,
onMouseOut: this.onMouseOut,
});
});

Expand All @@ -118,6 +140,8 @@ export class Grid extends React.Component {
* size - Square size.
* style - Custom styling.
* onClick - Invoked when a Square is clicked.
* onMouseOver - Invoked when a Square is mouse over.
* onMouseOut - Invoked when a Square is mouse out.
*
* Not meant to be used by the end user directly (use Token).
* Also not exposed in the NPM.
Expand All @@ -129,6 +153,8 @@ export class Square extends React.Component {
size: PropTypes.number,
style: PropTypes.any,
onClick: PropTypes.func,
onMouseOver: PropTypes.func,
onMouseOut: PropTypes.func,
children: PropTypes.element,
};

Expand All @@ -146,22 +172,46 @@ export class Square extends React.Component {
});
};

onMouseOver = () => {
this.props.onMouseOver({
x: this.props.x,
y: this.props.y,
});
};

onMouseOut = () => {
this.props.onMouseOut({
x: this.props.x,
y: this.props.y,
});
};

render() {
const tx = this.props.x * this.props.size;
const ty = this.props.y * this.props.size;

// If a child is passed, render child.
if (this.props.children) {
return (
<g onClick={this.onClick} transform={`translate(${tx}, ${ty})`}>
<g
onClick={this.onClick}
onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut}
transform={`translate(${tx}, ${ty})`}
>
{this.props.children}
</g>
);
}

// If no child, render a square.
return (
<g onClick={this.onClick} transform={`translate(${tx}, ${ty})`}>
<g
onClick={this.onClick}
onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut}
transform={`translate(${tx}, ${ty})`}
>
<rect
style={this.props.style}
width={this.props.size}
Expand Down
46 changes: 46 additions & 0 deletions src/ui/grid.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,52 @@ test('click handler', () => {
}
});

test('mouse over handler', () => {
{
const onMouseOver = jest.fn();
const grid = Enzyme.mount(
<Grid rows={3} cols={4} onMouseOver={onMouseOver} />
);
grid
.find('Square')
.at(0)
.simulate('mouseOver');
expect(onMouseOver).toHaveBeenCalled();
}

// No crash when onMouseOver is not provided.
{
const grid = Enzyme.mount(<Grid rows={3} cols={4} />);
grid
.find('Square')
.at(0)
.simulate('mouseOver');
}
});

test('mouse out handler', () => {
{
const onMouseOut = jest.fn();
const grid = Enzyme.mount(
<Grid rows={3} cols={4} onMouseOut={onMouseOut} />
);
grid
.find('Square')
.at(0)
.simulate('mouseOut');
expect(onMouseOut).toHaveBeenCalled();
}

// No crash when onMouseOut is not provided.
{
const grid = Enzyme.mount(<Grid rows={3} cols={4} />);
grid
.find('Square')
.at(0)
.simulate('mouseOut');
}
});

test('correct x and y', () => {
const grid = Enzyme.mount(
<Grid rows={3} cols={4} style={{ width: '500px' }}>
Expand Down
52 changes: 50 additions & 2 deletions src/ui/hex.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export class HexGrid extends React.Component {
colorMap: PropTypes.object,
cellSize: PropTypes.number,
onClick: PropTypes.func,
onMouseOver: PropTypes.func,
onMouseOut: PropTypes.func,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.element),
PropTypes.element,
Expand Down Expand Up @@ -77,6 +79,8 @@ export class HexGrid extends React.Component {
z={z}
size={this.props.cellSize}
onClick={this.onClick}
onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut}
/>
);
}
Expand All @@ -90,11 +94,25 @@ export class HexGrid extends React.Component {
}
};

onMouseOver = args => {
if (this.props.onMouseOver) {
this.props.onMouseOver(args);
}
};

onMouseOut = args => {
if (this.props.onMouseOut) {
this.props.onMouseOut(args);
}
};

render() {
const tokens = React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
_inHexGrid: true,
onClick: this.onClick,
onMouseOver: this.onMouseOver,
onMouseOut: this.onMouseOut,
});
});

Expand Down Expand Up @@ -123,6 +141,8 @@ export class HexGrid extends React.Component {
* size - Hex size.
* style - Custom styling.
* onClick - Invoked when a Hex is clicked.
* onMouseOver - Invoked when a Hex is mouse over.
* onMouseOut - Invoked when a Hex is mouse out.
*
* Not meant to be used by the end user directly (use Token).
* Also not exposed in the NPM.
Expand All @@ -135,6 +155,8 @@ export class Hex extends React.Component {
size: PropTypes.number,
style: PropTypes.any,
onClick: PropTypes.func,
onMouseOver: PropTypes.func,
onMouseOut: PropTypes.func,
children: PropTypes.element,
};

Expand Down Expand Up @@ -217,22 +239,48 @@ export class Hex extends React.Component {
});
};

onMouseOver = () => {
this.props.onMouseOver({
x: this.props.x,
y: this.props.y,
z: this.props.z,
});
};

onMouseOut = () => {
this.props.onMouseOut({
x: this.props.x,
y: this.props.y,
z: this.props.z,
});
};

render() {
const tx = this.center.x;
const ty = this.center.y;

// If a child is passed, render child.
if (this.props.children) {
return (
<g onClick={this.onClick} transform={`translate(${tx}, ${ty})`}>
<g
onClick={this.onClick}
onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut}
transform={`translate(${tx}, ${ty})`}
>
{this.props.children}
</g>
);
}

// If no child, render a hex.
return (
<g onClick={this.onClick} transform={`translate(${tx}, ${ty})`}>
<g
onClick={this.onClick}
onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut}
transform={`translate(${tx}, ${ty})`}
>
<polygon
style={this.props.style}
points={this.points}
Expand Down
42 changes: 42 additions & 0 deletions src/ui/hex.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,48 @@ test('click handler', () => {
}
});

test('mouse over handler', () => {
{
const onMouseOver = jest.fn();
const grid = Enzyme.mount(<HexGrid layers={4} onMouseOver={onMouseOver} />);
grid
.find('Hex')
.at(0)
.simulate('mouseOver');
expect(onMouseOver).toHaveBeenCalled();
}

// No crash when onMouseOver is not provided.
{
const grid = Enzyme.mount(<HexGrid layers={4} />);
grid
.find('Hex')
.at(0)
.simulate('mouseOver');
}
});

test('mouse out handler', () => {
{
const onMouseOut = jest.fn();
const grid = Enzyme.mount(<HexGrid layers={4} onMouseOut={onMouseOut} />);
grid
.find('Hex')
.at(0)
.simulate('mouseOut');
expect(onMouseOut).toHaveBeenCalled();
}

// No crash when onMouseOut is not provided.
{
const grid = Enzyme.mount(<HexGrid layers={4} />);
grid
.find('Hex')
.at(0)
.simulate('mouseOut');
}
});

test('child', () => {
{
const grid = Enzyme.mount(
Expand Down
10 changes: 10 additions & 0 deletions src/ui/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import { Square } from './grid';
* animate - Changes in position are animated if true.
* animationDuration - Length of animation.
* onClick - Called when the token is clicked.
* onMouseOver - Called when the token is mouse over.
* onMouseOut - Called when the token is mouse out.
*
* Usage:
*
Expand All @@ -54,6 +56,8 @@ class Token extends React.Component {
style: PropTypes.any,
animate: PropTypes.bool,
onClick: PropTypes.func,
onMouseOver: PropTypes.func,
onMouseOut: PropTypes.func,
children: PropTypes.element,
animationDuration: PropTypes.number,
_inGrid: PropTypes.bool,
Expand Down Expand Up @@ -166,6 +170,8 @@ class Token extends React.Component {
z={this.state.z}
style={this.props.style}
onClick={this.props.onClick}
onMouseOver={this.props.onMouseOver}
onMouseOut={this.props.onMouseOut}
>
{this.props.children}
</Hex>
Expand All @@ -179,6 +185,8 @@ class Token extends React.Component {
y={this.state.y}
style={this.props.style}
onClick={this.props.onClick}
onMouseOver={this.props.onMouseOver}
onMouseOut={this.props.onMouseOut}
>
{this.props.children}
</Square>
Expand All @@ -188,6 +196,8 @@ class Token extends React.Component {
return React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
onClick: this.props.onClick,
onMouseOver: this.props.onMouseOver,
onMouseOut: this.props.onMouseOut,
});
});
}
Expand Down

0 comments on commit 748f36f

Please sign in to comment.