diff --git a/web/src/components/message-history-window-size-item.tsx b/web/src/components/message-history-window-size-item.tsx
index 69df072b1..cd44f0d0a 100644
--- a/web/src/components/message-history-window-size-item.tsx
+++ b/web/src/components/message-history-window-size-item.tsx
@@ -1,5 +1,6 @@
import { useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
+import NumberInput from './originui/number-input';
import {
FormControl,
FormField,
@@ -7,9 +8,13 @@ import {
FormLabel,
FormMessage,
} from './ui/form';
-import { NumberInput } from './ui/input';
-export function MessageHistoryWindowSizeFormField() {
+type MessageHistoryWindowSizeFormFieldProps = {
+ min?: number;
+};
+export function MessageHistoryWindowSizeFormField({
+ min,
+}: MessageHistoryWindowSizeFormFieldProps) {
const form = useFormContext();
const { t } = useTranslation();
@@ -23,7 +28,7 @@ export function MessageHistoryWindowSizeFormField() {
{t('flow.messageHistoryWindowSize')}
-
+
diff --git a/web/src/components/originui/number-input.tsx b/web/src/components/originui/number-input.tsx
index 535c1e8b3..27497ba0d 100644
--- a/web/src/components/originui/number-input.tsx
+++ b/web/src/components/originui/number-input.tsx
@@ -1,5 +1,13 @@
+import { isNumber, trim } from 'lodash';
import { MinusIcon, PlusIcon } from 'lucide-react';
-import React, { useEffect, useMemo, useState } from 'react';
+import React, {
+ FocusEventHandler,
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from 'react';
interface NumberInputProps {
className?: string;
@@ -18,10 +26,12 @@ const NumberInput: React.FC = ({
min = 0,
max = Infinity,
}) => {
- const [value, setValue] = useState(() => {
+ const [value, setValue] = useState(() => {
return initialValue ?? 0;
});
+ const valueRef = useRef();
+
useEffect(() => {
if (initialValue !== undefined) {
setValue(initialValue);
@@ -29,13 +39,16 @@ const NumberInput: React.FC = ({
}, [initialValue]);
const handleDecrement = () => {
- if (value > 0) {
+ if (isNumber(value) && value > min) {
setValue(value - 1);
onChange?.(value - 1);
}
};
const handleIncrement = () => {
+ if (!isNumber(value)) {
+ return;
+ }
if (value > max - 1) {
return;
}
@@ -44,9 +57,19 @@ const NumberInput: React.FC = ({
};
const handleChange = (e: React.ChangeEvent) => {
- const newValue = Number(e.target.value);
+ const currentValue = e.target.value;
+ const newValue = Number(currentValue);
+
+ if (trim(currentValue) === '') {
+ if (isNumber(value)) {
+ valueRef.current = value;
+ }
+ setValue('');
+ return;
+ }
+
if (!isNaN(newValue)) {
- if (newValue > max) {
+ if (newValue > max || newValue < min) {
return;
}
setValue(newValue);
@@ -54,12 +77,16 @@ const NumberInput: React.FC = ({
}
};
- const handleInput = (e: React.ChangeEvent) => {
- // If the input value is not a number, the input is not allowed
- if (!/^\d*$/.test(e.target.value)) {
- e.preventDefault();
+ const handleBlur: FocusEventHandler = useCallback(() => {
+ if (isNumber(value)) {
+ onChange?.(value);
+ } else {
+ const previousValue = valueRef.current ?? min;
+ setValue(previousValue);
+ onChange?.(previousValue);
}
- };
+ }, [min, onChange, value]);
+
const style = useMemo(
() => ({
height: height ? `${height.toString().replace('px', '')}px` : 'auto',
@@ -82,8 +109,8 @@ const NumberInput: React.FC = ({
-
+