Improve RangeSettings keyboard compatibility

This commit is contained in:
Thomas Nordquist
2019-06-24 15:58:43 +02:00
parent c2a9b7b1c6
commit 759176c4fc

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useState, ChangeEvent, MouseEvent } from 'react' import React, { useCallback, useState, ChangeEvent, MouseEvent, useRef, useEffect, useMemo } from 'react'
import { ChartParameters } from '../../../reducers/Charts' import { ChartParameters } from '../../../reducers/Charts'
import { Menu, TextField, Typography } from '@material-ui/core' import { Menu, TextField, Typography } from '@material-ui/core'
import { connect } from 'react-redux' import { connect } from 'react-redux'
@@ -19,28 +19,60 @@ function RangeSettings(props: Props) {
const [rangeFrom, setRangeFrom] = useState<string | number | undefined>(props.chart.range && props.chart.range.from) const [rangeFrom, setRangeFrom] = useState<string | number | undefined>(props.chart.range && props.chart.range.from)
const [rangeTo, setRangeTo] = useState<string | number | undefined>(props.chart.range && props.chart.range.to) const [rangeTo, setRangeTo] = useState<string | number | undefined>(props.chart.range && props.chart.range.to)
useRangeStateToFireUpdateAction(rangeFrom, rangeTo, props) useRangeStateToFireUpdateAction(rangeFrom, rangeTo, props)
const dismissTabKey = (e: React.KeyboardEvent<any>) => { const rangeFromRef = useRef<HTMLInputElement>()
const rangeToRef = useRef<HTMLInputElement>()
useEffect(() => {
rangeFromRef.current && rangeFromRef.current.focus()
}, [props.open])
const handleKeyEvents = (e: React.KeyboardEvent<any>) => {
if (e.keyCode === KeyCodes.tab) { if (e.keyCode === KeyCodes.tab) {
// Switch focus between those two
if (document.activeElement === rangeFromRef.current) {
rangeToRef.current && rangeToRef.current.focus()
} else {
rangeFromRef.current && rangeFromRef.current.focus()
}
// Prevent closing the menu
e.stopPropagation() e.stopPropagation()
// Prevent default tab behavior (focus/blur)
e.preventDefault()
} else if (e.keyCode === KeyCodes.enter) {
props.onClose()
} }
} }
const setFromHandler = useCallback((e: ChangeEvent<HTMLInputElement>) => setRangeFrom(e.target.value), []) const setFromHandler = useCallback((e: ChangeEvent<HTMLInputElement>) => setRangeFrom(e.target.value), [])
const setToHandler = useCallback((e: ChangeEvent<HTMLInputElement>) => setRangeTo(e.target.value), []) const setToHandler = useCallback((e: ChangeEvent<HTMLInputElement>) => setRangeTo(e.target.value), [])
return ( return useMemo(
<Menu style={{ textAlign: 'center' }} anchorEl={props.anchorEl} open={props.open} onClose={props.onClose}> () => (
<Menu
style={{ textAlign: 'center' }}
keepMounted={true}
anchorEl={props.anchorEl}
open={props.open}
onClose={props.onClose}
onKeyDownCapture={handleKeyEvents}
>
<Typography>Define custom ranges for the Y-Axis</Typography> <Typography>Define custom ranges for the Y-Axis</Typography>
<div style={{ padding: '0 16px' }}> <div style={{ padding: '0 16px' }}>
<TextField <TextField
onKeyDownCapture={dismissTabKey} inputProps={{
ref: rangeFromRef,
}}
autoFocus={true}
style={{ marginTop: '0' }} style={{ marginTop: '0' }}
onClick={dismissClick}
label="from" label="from"
value={rangeFrom} value={rangeFrom}
onChange={setFromHandler} onChange={setFromHandler}
margin="normal" margin="normal"
/> />
<TextField <TextField
inputProps={{
ref: rangeToRef,
}}
style={{ marginLeft: '8px', marginTop: '0' }} style={{ marginLeft: '8px', marginTop: '0' }}
onClick={dismissClick} onClick={dismissClick}
label="to" label="to"
@@ -50,6 +82,8 @@ function RangeSettings(props: Props) {
/> />
</div> </div>
</Menu> </Menu>
),
[rangeFrom, rangeTo, props.open]
) )
} }