diff --git a/README.md b/README.md index 5b57a99..82fa34d 100644 --- a/README.md +++ b/README.md @@ -33,32 +33,15 @@ const range = ['AA', 'KK', 'QQ', 'AKs', 'AQs']; 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) => ( -
- {showText && ( - <> -
- {combo} -
-
{comboSubtext}
- - )} -
- )} + 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}`)} /> ``` @@ -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 diff --git a/package.json b/package.json index b6c26a0..273469c 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/HandMatrix.css b/src/HandMatrix.css index 3cdf0fc..5c1cf66 100644 --- a/src/HandMatrix.css +++ b/src/HandMatrix.css @@ -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 { @@ -15,6 +20,7 @@ border: 1px solid grey; display: inline-block; font-size: 1em; + touch-action: none; } @media screen and (max-width: 992px) { diff --git a/src/HandMatrix.js b/src/HandMatrix.js index 2c6fc18..a8eedd1 100644 --- a/src/HandMatrix.js +++ b/src/HandMatrix.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import PropTypes from 'prop-types'; import "./HandMatrix.css"; @@ -23,26 +23,6 @@ const chunk = (arr, size) => arr.slice(i * size, i * size + size) ); -const defaultRender = (combo, styles, comboSubtext, showText, colorize) => ( -
- {showText && ( - <> -
- {combo} -
-
{comboSubtext}
- - )} -
-); - const ComboTile = React.memo( ({ combo, @@ -50,45 +30,54 @@ const ComboTile = React.memo( comboSubtext = "", showText = true, colorize = true, - renderItem = defaultRender, }) => { - return renderItem(combo, styles, comboSubtext, showText, colorize); + return ( +
+
+ {showText && ( + <> +
+ {combo} +
+
{comboSubtext}
+ + )} +
+
+ ); } ); const ComboRow = React.memo( ({ row, - onClick, - onMouseUp, - onMouseDown, - onMouseEnter, comboStyle, - renderItem, comboSubtext, showText, colorize, }) => (
{row.map((combo, j) => ( -
onClick && onClick(combo)} - onPointerUp={() => onMouseUp && onMouseUp(combo)} - onPointerDown={() => onMouseDown && onMouseDown(combo)} - onPointerEnter={() => onMouseEnter && onMouseEnter(combo)} + - -
+ combo={combo} + showText={showText} + comboSubtext={comboSubtext ? comboSubtext(combo) : ""} + styles={comboStyle ? comboStyle(combo) : {}} + colorize={colorize} + /> ))}
) @@ -99,17 +88,40 @@ 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 ( -
+
{ + 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) => ( ))}
@@ -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 @@ -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 = {