Autofocus the bet amount

This commit is contained in:
Austin Chen 2022-01-26 13:47:53 -06:00
parent 82fa464e58
commit 4d289f2e1e
3 changed files with 22 additions and 3 deletions

View File

@ -14,6 +14,8 @@ export function AmountInput(props: {
disabled?: boolean disabled?: boolean
className?: string className?: string
inputClassName?: string inputClassName?: string
// Needed to focus the amount input
inputRef?: React.MutableRefObject<any>
}) { }) {
const { const {
amount, amount,
@ -24,6 +26,7 @@ export function AmountInput(props: {
className, className,
inputClassName, inputClassName,
minimumAmount, minimumAmount,
inputRef,
} = props } = props
const user = useUser() const user = useUser()
@ -56,6 +59,7 @@ export function AmountInput(props: {
error && 'input-error', error && 'input-error',
inputClassName inputClassName
)} )}
ref={inputRef}
type="text" type="text"
placeholder="0" placeholder="0"
maxLength={9} maxLength={9}

View File

@ -1,5 +1,5 @@
import clsx from 'clsx' import clsx from 'clsx'
import React, { useEffect, useState } from 'react' import React, { useEffect, useRef, useState } from 'react'
import { useUser } from '../hooks/use-user' import { useUser } from '../hooks/use-user'
import { Contract } from '../../common/contract' import { Contract } from '../../common/contract'
@ -26,10 +26,20 @@ import { AmountInput } from './amount-input'
import { InfoTooltip } from './info-tooltip' import { InfoTooltip } from './info-tooltip'
import { OutcomeLabel } from './outcome-label' import { OutcomeLabel } from './outcome-label'
// Focus helper from https://stackoverflow.com/a/54159564/1222351
function useFocus(): [React.RefObject<HTMLElement>, () => void] {
const htmlElRef = useRef<HTMLElement>(null)
const setFocus = () => {
htmlElRef.current && htmlElRef.current.focus()
}
return [htmlElRef, setFocus]
}
export function BetPanel(props: { export function BetPanel(props: {
contract: Contract contract: Contract
className?: string className?: string
title?: string title?: string // Set if BetPanel is on a feed modal
selected?: 'YES' | 'NO' selected?: 'YES' | 'NO'
}) { }) {
useEffect(() => { useEffect(() => {
@ -43,6 +53,7 @@ export function BetPanel(props: {
const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(selected) const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(selected)
const [betAmount, setBetAmount] = useState<number | undefined>(undefined) const [betAmount, setBetAmount] = useState<number | undefined>(undefined)
const [inputRef, focusAmountInput] = useFocus()
const [error, setError] = useState<string | undefined>() const [error, setError] = useState<string | undefined>()
const [isSubmitting, setIsSubmitting] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false)
@ -51,6 +62,7 @@ export function BetPanel(props: {
function onBetChoice(choice: 'YES' | 'NO') { function onBetChoice(choice: 'YES' | 'NO') {
setBetChoice(choice) setBetChoice(choice)
setWasSubmitted(false) setWasSubmitted(false)
focusAmountInput()
} }
function onBetChange(newAmount: number | undefined) { function onBetChange(newAmount: number | undefined) {
@ -114,6 +126,9 @@ export function BetPanel(props: {
const currentReturn = betAmount ? (currentPayout - betAmount) / betAmount : 0 const currentReturn = betAmount ? (currentPayout - betAmount) / betAmount : 0
const currentReturnPercent = (currentReturn * 100).toFixed() + '%' const currentReturnPercent = (currentReturn * 100).toFixed() + '%'
const panelTitle = title ?? `Buy ${betChoice || 'shares'}` const panelTitle = title ?? `Buy ${betChoice || 'shares'}`
if (title) {
focusAmountInput()
}
return ( return (
<Col <Col
@ -139,6 +154,7 @@ export function BetPanel(props: {
error={error} error={error}
setError={setError} setError={setError}
disabled={isSubmitting} disabled={isSubmitting}
inputRef={inputRef}
/> />
<Spacer h={4} /> <Spacer h={4} />

View File

@ -8,7 +8,6 @@ import { YesNoSelector } from './yes-no-selector'
// Inline version of a bet panel. Opens BetPanel in a new modal. // Inline version of a bet panel. Opens BetPanel in a new modal.
// TODO: Hide when not appropriate // TODO: Hide when not appropriate
// TODO: Autofocus the bet amount input
export default function BetRow(props: { contract: Contract }) { export default function BetRow(props: { contract: Contract }) {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>( const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(