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.
This commit is contained in:
rektdeckard
2020-09-13 18:34:32 -04:00
parent 3c0ab1a051
commit 9060b6d5bc
2 changed files with 25 additions and 10 deletions

View File

@@ -38,6 +38,7 @@
appearance: none; appearance: none;
width: 14px; /* Set a specific slider handle width */ width: 14px; /* Set a specific slider handle width */
height: 14px; /* Slider handle height */ height: 14px; /* Slider handle height */
padding: 6px;
border-radius: 50%; border-radius: 50%;
background: white; /* Green background */ background: white; /* Green background */
cursor: pointer; /* Cursor on hover */ cursor: pointer; /* Cursor on hover */
@@ -47,6 +48,7 @@
.size-bar input::-moz-range-thumb { .size-bar input::-moz-range-thumb {
width: 14px; /* Set a specific slider handle width */ width: 14px; /* Set a specific slider handle width */
height: 14px; /* Slider handle height */ height: 14px; /* Slider handle height */
padding: 6px;
background: black; /* Green background */ background: black; /* Green background */
cursor: pointer; /* Cursor on hover */ cursor: pointer; /* Cursor on hover */
transition: height 0.1s, width 0.1s; transition: height 0.1s, width 0.1s;
@@ -56,7 +58,6 @@
outline: none; outline: none;
width: 20px; /* Set a specific slider handle width */ width: 20px; /* Set a specific slider handle width */
height: 20px; /* Slider handle height */ height: 20px; /* Slider handle height */
transition: height 0.1s, width 0.1s;
box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.2); box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.2);
} }
@@ -64,6 +65,5 @@
outline: none; outline: none;
width: 20px; /* Set a specific slider handle width */ width: 20px; /* Set a specific slider handle width */
height: 20px; /* Slider handle height */ height: 20px; /* Slider handle height */
transition: height 0.1s, width 0.1s;
box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.2); box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.2);
} }

View File

@@ -1,4 +1,4 @@
import React from "react"; import React, { useCallback } from "react";
import { useRecoilState } from "recoil"; import { useRecoilState } from "recoil";
import { iconSizeAtom } from "../../state/atoms"; import { iconSizeAtom } from "../../state/atoms";
@@ -6,17 +6,29 @@ import "./SizeInput.css";
type SizeInputProps = {}; type SizeInputProps = {};
const handleFocus = (event: React.UIEvent<HTMLInputElement>) => {
const { currentTarget } = event;
currentTarget.focus();
};
const handleBlur = (event: React.UIEvent<HTMLInputElement>) => {
event.currentTarget.blur();
};
const SizeInput: React.FC<SizeInputProps> = () => { const SizeInput: React.FC<SizeInputProps> = () => {
const [size, setSize] = useRecoilState(iconSizeAtom); const [size, setSize] = useRecoilState(iconSizeAtom);
const handleSizeChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleSizeChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const { const {
target: { value }, target: { value },
} = event; } = event;
const sizeInput = parseInt(value); const sizeInput = parseInt(value);
if (sizeInput > 0) setSize(sizeInput); if (sizeInput > 0) setSize(sizeInput);
}; },
[setSize]
);
return ( return (
<div className="size-bar"> <div className="size-bar">
@@ -29,6 +41,9 @@ const SizeInput: React.FC<SizeInputProps> = () => {
min={16} min={16}
max={96} max={96}
onChange={handleSizeChange} onChange={handleSizeChange}
onTouchStart={handleFocus}
onTouchEnd={handleBlur}
onMouseUp={handleBlur}
step={4} step={4}
/> />
</div> </div>