fix: add input scroll into view
All checks were successful
Deploy to VPS (dist) / deploy (push) Successful in 1m31s
All checks were successful
Deploy to VPS (dist) / deploy (push) Successful in 1m31s
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { motion, type HTMLMotionProps } from "motion/react";
|
import { motion, type HTMLMotionProps } from "motion/react";
|
||||||
import clsx, { type ClassValue } from "clsx";
|
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 KeyboardIcon from "@components/icons/KeyboardIcon";
|
||||||
|
|
||||||
import classes from "./NumberInput.module.css";
|
import classes from "./NumberInput.module.css";
|
||||||
@@ -29,6 +29,7 @@ export default function NumberInput({
|
|||||||
prefix,
|
prefix,
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
|
onFocus,
|
||||||
...props
|
...props
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const play = useAudioStore((s) => s.play);
|
const play = useAudioStore((s) => s.play);
|
||||||
@@ -44,6 +45,16 @@ export default function NumberInput({
|
|||||||
setStrValue(value?.toString() ?? "");
|
setStrValue(value?.toString() ?? "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleFocus = (e: FocusEvent<HTMLInputElement>) => {
|
||||||
|
onFocus?.(e);
|
||||||
|
const target = e.target;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (target.isConnected) {
|
||||||
|
target.scrollIntoView({ block: "center", behavior: "smooth" });
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
const normalized = filterNumericInput(e.target.value);
|
const normalized = filterNumericInput(e.target.value);
|
||||||
setStrValue(normalized);
|
setStrValue(normalized);
|
||||||
@@ -65,6 +76,7 @@ export default function NumberInput({
|
|||||||
className={classes.input}
|
className={classes.input}
|
||||||
value={strValue}
|
value={strValue}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
onFocus={handleFocus}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<motion.button
|
<motion.button
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { motion, type HTMLMotionProps } from "motion/react";
|
import { motion, type HTMLMotionProps } from "motion/react";
|
||||||
import clsx, { type ClassValue } from "clsx";
|
import clsx, { type ClassValue } from "clsx";
|
||||||
|
import type { FocusEvent } from "react";
|
||||||
|
|
||||||
import classes from "./TextAreaInput.module.css";
|
import classes from "./TextAreaInput.module.css";
|
||||||
|
|
||||||
@@ -8,10 +9,21 @@ type Props = Omit<HTMLMotionProps<"textarea">, "className"> & {
|
|||||||
error?: boolean;
|
error?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function TextAreaInput({ className, error, ...props }: Props) {
|
export default function TextAreaInput({ className, error, onFocus, ...props }: Props) {
|
||||||
|
const handleFocus = (e: FocusEvent<HTMLTextAreaElement>) => {
|
||||||
|
onFocus?.(e);
|
||||||
|
const target = e.target;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (target.isConnected) {
|
||||||
|
target.scrollIntoView({ block: "center", behavior: "smooth" });
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.textarea
|
<motion.textarea
|
||||||
{...props}
|
{...props}
|
||||||
|
onFocus={handleFocus}
|
||||||
className={clsx(classes.input, error && classes.error, className)}
|
className={clsx(classes.input, error && classes.error, className)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { motion, type HTMLMotionProps } from "motion/react";
|
import { motion, type HTMLMotionProps } from "motion/react";
|
||||||
import clsx, { type ClassValue } from "clsx";
|
import clsx, { type ClassValue } from "clsx";
|
||||||
|
import type { FocusEvent } from "react";
|
||||||
|
|
||||||
import classes from "./TextInput.module.css";
|
import classes from "./TextInput.module.css";
|
||||||
|
|
||||||
@@ -8,11 +9,22 @@ type Props = Omit<HTMLMotionProps<"input">, "className"> & {
|
|||||||
error?: boolean;
|
error?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function TextInput({ className, error, ...props }: Props) {
|
export default function TextInput({ className, error, onFocus, ...props }: Props) {
|
||||||
|
const handleFocus = (e: FocusEvent<HTMLInputElement>) => {
|
||||||
|
onFocus?.(e);
|
||||||
|
const target = e.target;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (target.isConnected) {
|
||||||
|
target.scrollIntoView({ block: "center", behavior: "smooth" });
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.input
|
<motion.input
|
||||||
{...props}
|
{...props}
|
||||||
type="text"
|
type="text"
|
||||||
|
onFocus={handleFocus}
|
||||||
className={clsx(classes.input, error && classes.error, className)}
|
className={clsx(classes.input, error && classes.error, className)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user