Files
ragflow/web/src/components/slider-input-form-field.tsx
Idriss Sbaaoui b3a7332c08 playwright : add data-testids for new test (#13364)
### What problem does this PR solve?

add data-testids for new test

### Type of change

- [x] Other (please describe): add data-testids for new test
2026-03-04 19:28:36 +08:00

139 lines
3.9 KiB
TypeScript

import { FormLayout } from '@/constants/form';
import { cn } from '@/lib/utils';
import { forwardRef, ReactNode, useMemo } from 'react';
import { useFormContext } from 'react-hook-form';
import { SingleFormSlider } from './ui/dual-range-slider';
import {
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from './ui/form';
import { NumberInput } from './ui/input';
export type FormLayoutType = {
layout?: FormLayout;
};
type SliderInputFormFieldProps = {
max?: number;
min?: number;
step?: number;
name: string;
label: string;
tooltip?: ReactNode;
defaultValue?: number;
className?: string;
numberInputClassName?: string;
percentage?: boolean;
sliderTestId?: string;
numberInputTestId?: string;
} & FormLayoutType;
export const SliderInputFormField = forwardRef<
HTMLDivElement,
SliderInputFormFieldProps
>(
(
{
max,
min,
step,
label,
name,
tooltip,
defaultValue,
className,
numberInputClassName,
layout = FormLayout.Horizontal,
percentage = false,
sliderTestId,
numberInputTestId,
},
ref,
) => {
const form = useFormContext();
const isHorizontal = useMemo(
() => layout !== FormLayout.Vertical,
[layout],
);
const displayMax = percentage ? (max || 1) * 100 : max;
const displayMin = percentage ? (min || 0) * 100 : min;
const displayStep = percentage ? (step || 0.01) * 100 : step;
return (
<FormField
control={form.control}
name={name}
defaultValue={defaultValue || 0}
render={({ field }) => (
<FormItem
ref={ref}
className={cn({
'flex items-center gap-1 space-y-0': isHorizontal,
})}
>
<FormLabel
tooltip={tooltip}
className={cn({
'text-sm whitespace-break-spaces w-1/4': isHorizontal,
})}
>
{label}
</FormLabel>
<div
className={cn(
'flex items-center gap-4 justify-between',
{ 'w-3/4': isHorizontal },
className,
)}
>
<FormControl>
<SingleFormSlider
{...field}
value={percentage ? field.value * 100 : field.value}
onChange={(value) =>
field.onChange(percentage ? value / 100 : value)
}
max={displayMax}
min={displayMin}
step={displayStep}
data-testid={sliderTestId}
></SingleFormSlider>
</FormControl>
<FormControl>
<NumberInput
className={cn(
'h-6 w-10 p-0 text-center bg-bg-input border border-border-button text-text-secondary',
'[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none',
numberInputClassName,
)}
max={displayMax}
min={displayMin}
step={displayStep}
value={
percentage ? (field.value * 100).toFixed(0) : field.value
}
onChange={(val) => {
const value = Number(val || 0);
if (!isNaN(value)) {
field.onChange(
percentage ? (value / 100).toFixed(0) : value,
);
}
}}
data-testid={numberInputTestId}
></NumberInput>
</FormControl>
</div>
<FormMessage />
</FormItem>
)}
/>
);
},
);
SliderInputFormField.displayName = 'SliderInputFormField';