From 9060b6d5bc4d001cfae2c05bdad21efafc342983 Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Sun, 13 Sep 2020 18:34:32 -0400 Subject: [PATCH] SizeInput: better handle input focus effect for mouse and touch The input slider handle now animates in response to mousedown/touchstart, and returns to its initial state on mouseup/touchend. This does not break existing behaviour when navigating via keyboard. --- src/components/SizeInput/SizeInput.css | 4 ++-- src/components/SizeInput/SizeInput.tsx | 31 +++++++++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/components/SizeInput/SizeInput.css b/src/components/SizeInput/SizeInput.css index 1f156fd..454155c 100644 --- a/src/components/SizeInput/SizeInput.css +++ b/src/components/SizeInput/SizeInput.css @@ -38,6 +38,7 @@ appearance: none; width: 14px; /* Set a specific slider handle width */ height: 14px; /* Slider handle height */ + padding: 6px; border-radius: 50%; background: white; /* Green background */ cursor: pointer; /* Cursor on hover */ @@ -47,6 +48,7 @@ .size-bar input::-moz-range-thumb { width: 14px; /* Set a specific slider handle width */ height: 14px; /* Slider handle height */ + padding: 6px; background: black; /* Green background */ cursor: pointer; /* Cursor on hover */ transition: height 0.1s, width 0.1s; @@ -56,7 +58,6 @@ outline: none; width: 20px; /* Set a specific slider handle width */ height: 20px; /* Slider handle height */ - transition: height 0.1s, width 0.1s; box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.2); } @@ -64,6 +65,5 @@ outline: none; width: 20px; /* Set a specific slider handle width */ height: 20px; /* Slider handle height */ - transition: height 0.1s, width 0.1s; box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.2); } diff --git a/src/components/SizeInput/SizeInput.tsx b/src/components/SizeInput/SizeInput.tsx index 26472e7..7197579 100644 --- a/src/components/SizeInput/SizeInput.tsx +++ b/src/components/SizeInput/SizeInput.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useCallback } from "react"; import { useRecoilState } from "recoil"; import { iconSizeAtom } from "../../state/atoms"; @@ -6,17 +6,29 @@ import "./SizeInput.css"; type SizeInputProps = {}; +const handleFocus = (event: React.UIEvent) => { + const { currentTarget } = event; + currentTarget.focus(); +}; + +const handleBlur = (event: React.UIEvent) => { + event.currentTarget.blur(); +}; + const SizeInput: React.FC = () => { const [size, setSize] = useRecoilState(iconSizeAtom); - const handleSizeChange = (event: React.ChangeEvent) => { - const { - target: { value }, - } = event; - const sizeInput = parseInt(value); + const handleSizeChange = useCallback( + (event: React.ChangeEvent) => { + const { + target: { value }, + } = event; + const sizeInput = parseInt(value); - if (sizeInput > 0) setSize(sizeInput); - }; + if (sizeInput > 0) setSize(sizeInput); + }, + [setSize] + ); return (
@@ -29,6 +41,9 @@ const SizeInput: React.FC = () => { min={16} max={96} onChange={handleSizeChange} + onTouchStart={handleFocus} + onTouchEnd={handleBlur} + onMouseUp={handleBlur} step={4} />