From ef264b52c78ee0d83dcf8b2d7a7cb5e9a851f139 Mon Sep 17 00:00:00 2001 From: chanx <1243304602@qq.com> Date: Mon, 2 Mar 2026 19:19:15 +0800 Subject: [PATCH] Fix: Fixed some errors in the console (#13317) ### What problem does this PR solve? Fix: Fixed some errors in the console ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- .../components/llm-setting-items/slider.tsx | 167 ++++++++-------- .../components/slider-input-form-field.tsx | 178 ++++++++++-------- web/src/components/ui/radio-group.tsx | 26 ++- web/src/components/ui/radio.tsx | 95 +++++----- web/src/components/ui/segmented.tsx | 126 +++++++------ 5 files changed, 322 insertions(+), 270 deletions(-) diff --git a/web/src/components/llm-setting-items/slider.tsx b/web/src/components/llm-setting-items/slider.tsx index 5c52d29e85..58d7a1ddc8 100644 --- a/web/src/components/llm-setting-items/slider.tsx +++ b/web/src/components/llm-setting-items/slider.tsx @@ -1,5 +1,6 @@ import { useTranslate } from '@/hooks/common-hooks'; import { cn } from '@/lib/utils'; +import { forwardRef } from 'react'; import { useFormContext } from 'react-hook-form'; import { SingleFormSlider } from '../ui/dual-range-slider'; import { @@ -25,82 +26,96 @@ type SliderInputSwitchFormFieldProps = { numberInputClassName?: string; }; -export function SliderInputSwitchFormField({ - max, - min, - step, - label, - name, - defaultValue, - onChange, - className, - checkName, - numberInputClassName, -}: SliderInputSwitchFormFieldProps) { - const form = useFormContext(); - const disabled = !form.watch(checkName); - const { t } = useTranslate('chat'); +export const SliderInputSwitchFormField = forwardRef< + HTMLDivElement, + SliderInputSwitchFormFieldProps +>( + ( + { + max, + min, + step, + label, + name, + defaultValue, + onChange, + className, + checkName, + numberInputClassName, + }, + ref, + ) => { + const form = useFormContext(); + const disabled = !form.watch(checkName); + const { t } = useTranslate('chat'); - return ( - ( - - {t(label)} -
- ( - - - - - - + return ( + ( + + {t(label)} +
- - { - onChange?.(value); - field.onChange(value); - }} - max={max} - min={min} - step={step} - disabled={disabled} - > - - - + ( + + + + + + )} - max={max} - min={min} - step={step} - {...field} - onChange={(value: number) => { - onChange?.(value); - field.onChange(value); - }} - > - -
- -
- )} - /> - ); -} + /> + + { + onChange?.(value); + field.onChange(value); + }} + max={max} + min={min} + step={step} + disabled={disabled} + > + + + { + onChange?.(value); + field.onChange(value); + }} + > + +
+ +
+ )} + /> + ); + }, +); + +SliderInputSwitchFormField.displayName = 'SliderInputSwitchFormField'; diff --git a/web/src/components/slider-input-form-field.tsx b/web/src/components/slider-input-form-field.tsx index a15b358ce4..2b9980eb12 100644 --- a/web/src/components/slider-input-form-field.tsx +++ b/web/src/components/slider-input-form-field.tsx @@ -1,6 +1,6 @@ import { FormLayout } from '@/constants/form'; import { cn } from '@/lib/utils'; -import { ReactNode, useMemo } from 'react'; +import { forwardRef, ReactNode, useMemo } from 'react'; import { useFormContext } from 'react-hook-form'; import { SingleFormSlider } from './ui/dual-range-slider'; import { @@ -29,88 +29,104 @@ type SliderInputFormFieldProps = { percentage?: boolean; } & FormLayoutType; -export function SliderInputFormField({ - max, - min, - step, - label, - name, - tooltip, - defaultValue, - className, - numberInputClassName, - layout = FormLayout.Horizontal, - percentage = false, -}: SliderInputFormFieldProps) { - const form = useFormContext(); +export const SliderInputFormField = forwardRef< + HTMLDivElement, + SliderInputFormFieldProps +>( + ( + { + max, + min, + step, + label, + name, + tooltip, + defaultValue, + className, + numberInputClassName, + layout = FormLayout.Horizontal, + percentage = false, + }, + 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 ( - ( - - 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 ( + ( + - {label} - -
- - - field.onChange(percentage ? value / 100 : value) - } - max={displayMax} - min={displayMin} - step={displayStep} - > - - - { - const value = Number(val || 0); - if (!isNaN(value)) { - field.onChange( - percentage ? (value / 100).toFixed(0) : value, - ); + + {label} + +
+ + + field.onChange(percentage ? value / 100 : value) } - }} - > - -
- - - )} - /> - ); -} + max={displayMax} + min={displayMin} + step={displayStep} + > +
+ + { + const value = Number(val || 0); + if (!isNaN(value)) { + field.onChange( + percentage ? (value / 100).toFixed(0) : value, + ); + } + }} + > + +
+ +
+ )} + /> + ); + }, +); + +SliderInputFormField.displayName = 'SliderInputFormField'; diff --git a/web/src/components/ui/radio-group.tsx b/web/src/components/ui/radio-group.tsx index 2505f1da79..d9cfb82f60 100644 --- a/web/src/components/ui/radio-group.tsx +++ b/web/src/components/ui/radio-group.tsx @@ -6,25 +6,29 @@ import * as React from 'react'; import { cn } from '@/lib/utils'; -function RadioGroup({ - className, - ...props -}: React.ComponentProps) { +const RadioGroup = React.forwardRef< + React.ElementRef, + React.ComponentProps +>(({ className, ...props }, ref) => { return ( ); -} +}); -function RadioGroupItem({ - className, - ...props -}: React.ComponentProps) { +RadioGroup.displayName = 'RadioGroup'; + +const RadioGroupItem = React.forwardRef< + React.ElementRef, + React.ComponentProps +>(({ className, ...props }, ref) => { return ( ); -} +}); + +RadioGroupItem.displayName = 'RadioGroupItem'; export { RadioGroup, RadioGroupItem }; diff --git a/web/src/components/ui/radio.tsx b/web/src/components/ui/radio.tsx index 2262ecd8b1..64fa7d14f4 100644 --- a/web/src/components/ui/radio.tsx +++ b/web/src/components/ui/radio.tsx @@ -74,59 +74,66 @@ type RadioGroupProps = { direction?: 'horizontal' | 'vertical'; }; -function Group({ - value, - defaultValue, - onChange, - disabled, - children, - className, - direction = 'horizontal', -}: RadioGroupProps) { - const [internalValue, setInternalValue] = useState(defaultValue || ''); +const Group = React.forwardRef( + ( + { + value, + defaultValue, + onChange, + disabled, + children, + className, + direction = 'horizontal', + }, + ref, + ) => { + const [internalValue, setInternalValue] = useState(defaultValue || ''); - const isControlled = value !== undefined; - const mergedValue = isControlled ? value : internalValue; + const isControlled = value !== undefined; + const mergedValue = isControlled ? value : internalValue; - const handleChange = (val: string | number) => { - if (disabled) return; + const handleChange = (val: string | number) => { + if (disabled) return; - if (!isControlled) { - setInternalValue(val); - } + if (!isControlled) { + setInternalValue(val); + } - if (onChange) { - onChange(val); - } - }; + if (onChange) { + onChange(val); + } + }; - return ( - -
- {React.Children.map(children, (child) => - React.cloneElement(child as React.ReactElement, { - disabled: disabled || child?.props?.disabled, - }), - )} -
-
- ); -} +
+ {React.Children.map(children, (child) => + React.cloneElement(child as React.ReactElement, { + disabled: disabled || child?.props?.disabled, + }), + )} +
+ + ); + }, +); const RadioComponent = Object.assign(Radio, { Group, }); +Group.displayName = 'RadioGroup'; export { RadioComponent as Radio }; diff --git a/web/src/components/ui/segmented.tsx b/web/src/components/ui/segmented.tsx index ffe5d27f22..c93b23a462 100644 --- a/web/src/components/ui/segmented.tsx +++ b/web/src/components/ui/segmented.tsx @@ -59,63 +59,71 @@ export interface SegmentedProps extends Omit< buttonSize?: keyof typeof segmentedVariants.buttonSize; } -export function Segmented({ - options, - value, - onChange, - className, - activeClassName, - itemClassName, - rounded = 'default', - sizeType = 'default', - buttonSize = 'default', -}: SegmentedProps) { - const [selectedValue, setSelectedValue] = React.useState< - SegmentedValue | undefined - >(value); - React.useEffect(() => { - setSelectedValue(value); - }, [value]); - const handleOnChange = (e: SegmentedValue) => { - if (onChange) { - onChange(e); - } - setSelectedValue(e); - }; - return ( -
- {options.map((option) => { - const isObject = typeof option === 'object'; - const actualValue = isObject ? option.value : option; +export const Segmented = React.forwardRef( + ( + { + options, + value, + onChange, + className, + activeClassName, + itemClassName, + rounded = 'default', + sizeType = 'default', + buttonSize = 'default', + }, + ref, + ) => { + const [selectedValue, setSelectedValue] = React.useState< + SegmentedValue | undefined + >(value); + React.useEffect(() => { + setSelectedValue(value); + }, [value]); + const handleOnChange = (e: SegmentedValue) => { + if (onChange) { + onChange(e); + } + setSelectedValue(e); + }; + return ( +
+ {options.map((option) => { + const isObject = typeof option === 'object'; + const actualValue = isObject ? option.value : option; - return ( -
handleOnChange(actualValue)} - > - {isObject ? option.label : option} -
- ); - })} -
- ); -} + return ( +
handleOnChange(actualValue)} + > + {isObject ? option.label : option} +
+ ); + })} +
+ ); + }, +); + +Segmented.displayName = 'Segmented';