diff --git a/src/components/form/NumberInput/NumberInput.tsx b/src/components/form/NumberInput/NumberInput.tsx index 92fed9c..240b597 100644 --- a/src/components/form/NumberInput/NumberInput.tsx +++ b/src/components/form/NumberInput/NumberInput.tsx @@ -1,6 +1,6 @@ import { motion, type HTMLMotionProps } from "motion/react"; import clsx, { type ClassValue } from "clsx"; -import { type ReactNode, useRef, useState, type ChangeEvent, useId } from "react"; +import { type ReactNode, useRef, useState, type ChangeEvent, type FocusEvent, useId } from "react"; import KeyboardIcon from "@components/icons/KeyboardIcon"; import classes from "./NumberInput.module.css"; @@ -29,6 +29,7 @@ export default function NumberInput({ prefix, value, onChange, + onFocus, ...props }: Props) { const play = useAudioStore((s) => s.play); @@ -44,6 +45,16 @@ export default function NumberInput({ setStrValue(value?.toString() ?? ""); } + const handleFocus = (e: FocusEvent) => { + onFocus?.(e); + const target = e.target; + setTimeout(() => { + if (target.isConnected) { + target.scrollIntoView({ block: "center", behavior: "smooth" }); + } + }, 100); + }; + const handleChange = (e: ChangeEvent) => { const normalized = filterNumericInput(e.target.value); setStrValue(normalized); @@ -65,6 +76,7 @@ export default function NumberInput({ className={classes.input} value={strValue} onChange={handleChange} + onFocus={handleFocus} /> , "className"> & { error?: boolean; }; -export default function TextAreaInput({ className, error, ...props }: Props) { +export default function TextAreaInput({ className, error, onFocus, ...props }: Props) { + const handleFocus = (e: FocusEvent) => { + onFocus?.(e); + const target = e.target; + setTimeout(() => { + if (target.isConnected) { + target.scrollIntoView({ block: "center", behavior: "smooth" }); + } + }, 100); + }; + return ( ); diff --git a/src/components/form/TextInput/TextInput.tsx b/src/components/form/TextInput/TextInput.tsx index 7a3ae14..6f40ffe 100644 --- a/src/components/form/TextInput/TextInput.tsx +++ b/src/components/form/TextInput/TextInput.tsx @@ -1,5 +1,6 @@ import { motion, type HTMLMotionProps } from "motion/react"; import clsx, { type ClassValue } from "clsx"; +import type { FocusEvent } from "react"; import classes from "./TextInput.module.css"; @@ -8,11 +9,22 @@ type Props = Omit, "className"> & { error?: boolean; }; -export default function TextInput({ className, error, ...props }: Props) { +export default function TextInput({ className, error, onFocus, ...props }: Props) { + const handleFocus = (e: FocusEvent) => { + onFocus?.(e); + const target = e.target; + setTimeout(() => { + if (target.isConnected) { + target.scrollIntoView({ block: "center", behavior: "smooth" }); + } + }, 100); + }; + return ( );