diff --git a/web/components/amount-input.tsx b/web/components/amount-input.tsx index ccbce060..9968a132 100644 --- a/web/components/amount-input.tsx +++ b/web/components/amount-input.tsx @@ -14,6 +14,8 @@ export function AmountInput(props: { disabled?: boolean className?: string inputClassName?: string + // Needed to focus the amount input + inputRef?: React.MutableRefObject }) { const { amount, @@ -24,6 +26,7 @@ export function AmountInput(props: { className, inputClassName, minimumAmount, + inputRef, } = props const user = useUser() @@ -56,6 +59,7 @@ export function AmountInput(props: { error && 'input-error', inputClassName )} + ref={inputRef} type="text" placeholder="0" maxLength={9} diff --git a/web/components/bet-panel.tsx b/web/components/bet-panel.tsx index 6c2cab1f..0303281f 100644 --- a/web/components/bet-panel.tsx +++ b/web/components/bet-panel.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx' -import React, { useEffect, useState } from 'react' +import React, { useEffect, useRef, useState } from 'react' import { useUser } from '../hooks/use-user' import { Contract } from '../../common/contract' @@ -26,10 +26,20 @@ import { AmountInput } from './amount-input' import { InfoTooltip } from './info-tooltip' import { OutcomeLabel } from './outcome-label' +// Focus helper from https://stackoverflow.com/a/54159564/1222351 +function useFocus(): [React.RefObject, () => void] { + const htmlElRef = useRef(null) + const setFocus = () => { + htmlElRef.current && htmlElRef.current.focus() + } + + return [htmlElRef, setFocus] +} + export function BetPanel(props: { contract: Contract className?: string - title?: string + title?: string // Set if BetPanel is on a feed modal selected?: 'YES' | 'NO' }) { useEffect(() => { @@ -43,6 +53,7 @@ export function BetPanel(props: { const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(selected) const [betAmount, setBetAmount] = useState(undefined) + const [inputRef, focusAmountInput] = useFocus() const [error, setError] = useState() const [isSubmitting, setIsSubmitting] = useState(false) @@ -51,6 +62,7 @@ export function BetPanel(props: { function onBetChoice(choice: 'YES' | 'NO') { setBetChoice(choice) setWasSubmitted(false) + focusAmountInput() } function onBetChange(newAmount: number | undefined) { @@ -114,6 +126,9 @@ export function BetPanel(props: { const currentReturn = betAmount ? (currentPayout - betAmount) / betAmount : 0 const currentReturnPercent = (currentReturn * 100).toFixed() + '%' const panelTitle = title ?? `Buy ${betChoice || 'shares'}` + if (title) { + focusAmountInput() + } return ( diff --git a/web/components/bet-row.tsx b/web/components/bet-row.tsx index cca31b64..14af11d9 100644 --- a/web/components/bet-row.tsx +++ b/web/components/bet-row.tsx @@ -8,7 +8,6 @@ import { YesNoSelector } from './yes-no-selector' // Inline version of a bet panel. Opens BetPanel in a new modal. // TODO: Hide when not appropriate -// TODO: Autofocus the bet amount input export default function BetRow(props: { contract: Contract }) { const [open, setOpen] = useState(false) const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(