Skip to content

Commit

Permalink
add mobile highlighting support
Browse files Browse the repository at this point in the history
  • Loading branch information
HieronymusLex committed Dec 21, 2020
1 parent bd880b1 commit 11d931b
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 103 deletions.
41 changes: 12 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,15 @@ const range = ['AA', 'KK', 'QQ', 'AKs', 'AQs'];
<HandMatrix
colorize={false}
onMouseDown={combo => console.log(`mouseDown on ${combo}`)}
onMouseUp={combo => console.log(`mouseDown on ${combo}`)}
onMouseEnter={combo => console.log(`onMouseEnter on ${combo}`)}
onClick={combo => console.log(`onClick on ${combo}`)}
comboStyle={(combo) => ({
background: range.indexOf(combo) !== -1 ? "lightgreen" : "lightgrey"
})}
comboSubtext={(combo) => range.indexOf(combo) !== -1 ? "100%" : "0%"}
renderItem={(combo, styles, comboSubtext, showText, colorize) => (
<div
style={{
display: "flex",
flexDirection: "column",
...styles,
}}
>
{showText && (
<>
<div style={{ flexGrow: 1 }} type="keyboard">
{combo}
</div>
<div>{comboSubtext}</div>
</>
)}
</div>
)}
onSelect={combo => console.log(`mouseDown on ${combo}`)}
onPointerDown={combo => console.log(`mouseDown on ${combo}`)}
onPointerUp={combo => console.log(`mouseDown on ${combo}`)}
onPointerEnter={combo => console.log(`onMouseEnter on ${combo}`)}
onPointerMove={combo => console.log(`onMouseEnter on ${combo}`)}
/>
```

Expand All @@ -69,15 +52,15 @@ and associated [GitHub repository](https://github.com/HoldemPokerTools/RangeAssi

Prop | Type | Default | Required | Description
---- | :----: | :-------: | :--------: | -----------
**colorize** | `Boolean` | `true` | :x: | Whether to apply default colors to the hand matrix to distinguish pairs vs offsuit vs suited hands. The result of the comboStyle function will override the default colors.
**colorize** | `Boolean` | `true` | :x: | Whether to apply default colors to the hand matrix to distinguish pairs vs offsuit vs suited hands. The result of the comboStyle function will override these default colors.
**comboStyle** | `Function` | | :x: | Function which receives the combo (e.g. AKo) and must return an object containing the styles to apply to the matrix tile for that combo e.g. {background: "#FFFFFF"}. Useful for displaying ranges.
**showText** | `Boolean` | `true` | :x: | Whether to show the text in the combo cells
**comboSubtext** | `Function` | | :x: | Function which receives the combo (e.g. AKo) and must return the text or React components to display beneath the combo text. Default is for no text to be displayed. Useful for displaying information such as combo equity
**onClick** | `Function` | | :x: | Click event handler for a combo tile. Will be called with combo e.g. AKo
**onMouseDown** | `Function` | | :x: | Mouse down event handler for a combo tile. Will be called with combo e.g. AKo
**onMouseEnter** | `Function` | | :x: | Mouseenter event handler for a combo tile. Will be called with combo e.g. AKo
**onMouseUp** | `Function` | | :x: | Mouse up event handler for a combo tile. Will be called with combo e.g. AKo
**renderItem** | `Function` | | :x: | A render function to use to render the contents of each tile. The function will be called with the following args: combo, styles, comboSubtext, showText, colorize where styles and comboSubtext are the result of the comboStyle and comboSubtext prop functions.
**showText** | `Boolean` | `true` | :x: | Whether to show the text in the combo tyles
**onSelect** | `Function` | | :x: | Click event handler for a combo tile. Will be called with combo e.g. AKo
**onPointerDown** | `Function` | | :x: | Pointer down event handler for a combo tile. Will be called with combo e.g. AKo
**onPointerEnter** | `Function` | | :x: | Pointer enter event handler for a combo tile. Will be called with combo e.g. AKo
**onPointerMove** | `Function` | | :x: | Pointer move event handler for a combo tile. Will be called with combo e.g. AKo
**onPointerUp** | `Function` | | :x: | Pointer up event handler for a combo tile. Will be called with combo e.g. AKo

## Support

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"scripts": {
"build": "webpack --mode production"
},
"version": "0.1.3",
"version": "0.2.0",
"devDependencies": {
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
Expand Down
8 changes: 7 additions & 1 deletion src/HandMatrix.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
.hand-matrix {
text-align: center;
user-select: none;
user-select: none; /* supported by Chrome and Opera */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
touch-action: none;
}

.hand-matrix-row {
Expand All @@ -15,6 +20,7 @@
border: 1px solid grey;
display: inline-block;
font-size: 1em;
touch-action: none;
}

@media screen and (max-width: 992px) {
Expand Down
148 changes: 76 additions & 72 deletions src/HandMatrix.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";
import PropTypes from 'prop-types';
import "./HandMatrix.css";

Expand All @@ -23,72 +23,61 @@ const chunk = (arr, size) =>
arr.slice(i * size, i * size + size)
);

const defaultRender = (combo, styles, comboSubtext, showText, colorize) => (
<div
className={colorize ? getComboClassName(combo) : null}
style={{
display: "flex",
flexDirection: "column",
...styles,
}}
>
{showText && (
<>
<div style={{ flexGrow: 1 }} type="keyboard">
{combo}
</div>
<div>{comboSubtext}</div>
</>
)}
</div>
);

const ComboTile = React.memo(
({
combo,
styles = {},
comboSubtext = "",
showText = true,
colorize = true,
renderItem = defaultRender,
}) => {
return renderItem(combo, styles, comboSubtext, showText, colorize);
return (
<div
data-combo={combo}
className="hand-matrix-cell"
style={{ flex: "1 1 0px" }}
>
<div
data-combo={combo}
className={colorize ? getComboClassName(combo) : null}
style={{
display: "flex",
flexDirection: "column",
...styles,
}}
>
{showText && (
<>
<div data-combo={combo} style={{ flexGrow: 1 }} type="keyboard">
{combo}
</div>
<div data-combo={combo}>{comboSubtext}</div>
</>
)}
</div>
</div>
);
}
);

const ComboRow = React.memo(
({
row,
onClick,
onMouseUp,
onMouseDown,
onMouseEnter,
comboStyle,
renderItem,
comboSubtext,
showText,
colorize,
}) => (
<div className="hand-matrix-row">
{row.map((combo, j) => (
<div
className="hand-matrix-cell"
style={{ flex: "1 1 0px" }}
onClick={() => onClick && onClick(combo)}
onPointerUp={() => onMouseUp && onMouseUp(combo)}
onPointerDown={() => onMouseDown && onMouseDown(combo)}
onPointerEnter={() => onMouseEnter && onMouseEnter(combo)}
<ComboTile
key={j}
>
<ComboTile
combo={combo}
showText={showText}
comboSubtext={comboSubtext ? comboSubtext(combo) : ""}
styles={comboStyle ? comboStyle(combo) : {}}
colorize={colorize}
renderItem={renderItem}
/>
</div>
combo={combo}
showText={showText}
comboSubtext={comboSubtext ? comboSubtext(combo) : ""}
styles={comboStyle ? comboStyle(combo) : {}}
colorize={colorize}
/>
))}
</div>
)
Expand All @@ -99,30 +88,48 @@ const ComboRow = React.memo(
*/
function HandMatrix({
comboSubtext,
renderItem,
comboStyle,
onClick,
onMouseUp,
onMouseDown,
onMouseEnter,
onSelect,
onPointerDown,
onPointerUp,
onPointerEnter,
onPointerMove,
showText,
colorize,
}) {
const [currentlyPointingAt, setCurrentlyPointingAt] = useState(undefined);
const getComboForPointerEvent = (e) => document.elementFromPoint(e.clientX, e.clientY).dataset.combo;
const comboEventDispatcher = fn => e => {
if (!fn) return;
const combo = getComboForPointerEvent(e);
if (combo && combos.indexOf(combo) !== -1) {
fn && fn(combo)
}
}

return (
<div className={`hand-matrix ${onClick || onMouseDown ? "selectable" : "unselectable"}`}>
<div
className={`hand-matrix ${onSelect || onPointerDown ? "selectable" : "unselectable"}`}
onClick={comboEventDispatcher(onSelect)}
onPointerUp={comboEventDispatcher(onPointerUp)}
onPointerDown={comboEventDispatcher(onPointerDown)}
onPointerMove={comboEventDispatcher((combo) => {
onPointerMove && onPointerMove(combo);
if (combo !== currentlyPointingAt) {
setCurrentlyPointingAt(combo)
// Note: This is used instead of onPointerEnter for Safari support
onPointerEnter && onPointerEnter(combo)
}
})}
>
{chunk(combos, 13).map((row, i) => (
<ComboRow
key={i}
showText={showText}
comboSubtext={comboSubtext}
comboStyle={comboStyle}
row={row}
onClick={onClick}
onMouseUp={onMouseUp}
onMouseDown={onMouseDown}
onMouseEnter={onMouseEnter}
colorize={colorize}
renderItem={renderItem}
/>
))}
</div>
Expand Down Expand Up @@ -157,14 +164,6 @@ HandMatrix.propTypes = {
* information such as combo equity
*/
comboSubtext: PropTypes.func,
/**
* A render function to use to render the contents of each tile.
* The function will be called with the following args:
* combo, styles, comboSubtext, showText, colorize
* where styles and comboSubtext are the result of the comboStyle
* and comboSubtext prop functions.
*/
renderItem: PropTypes.func,
/**
* Function which receives the combo (e.g. AKo) and must return
* an object containing the styles to apply to the matrix tile
Expand All @@ -173,25 +172,30 @@ HandMatrix.propTypes = {
*/
comboStyle: PropTypes.func,
/**
* Click event handler for a combo tile. Will be called with
* Click/touch event handler for a combo tile. Will be called with
* combo e.g. AKo
*/
onSelect: PropTypes.func,
/**
* Pointer up event handler for a combo tile. Will be called with
* combo e.g. AKo
*/
onClick: PropTypes.func,
onPointerUp: PropTypes.func,
/**
* Mouse up event handler for a combo tile. Will be called with
* Pointer down event handler for a combo tile. Will be called with
* combo e.g. AKo
*/
onMouseUp: PropTypes.func,
onPointerDown: PropTypes.func,
/**
* Mouse down event handler for a combo tile. Will be called with
* Pointer enter event handler for a combo tile. Will be called with
* combo e.g. AKo
*/
onMouseDown: PropTypes.func,
onPointerEnter: PropTypes.func,
/**
* Mouseenter event handler for a combo tile. Will be called with
* Pointer move event handler for a combo tile. Will be called with
* combo e.g. AKo
*/
onMouseEnter: PropTypes.func,
onPointerMove: PropTypes.func,
};

HandMatrix.defaultProps = {
Expand Down

0 comments on commit 11d931b

Please sign in to comment.