diff --git a/web/src/components/ui/select.tsx b/web/src/components/ui/select.tsx index 0f83d2362..9cb7fe69b 100644 --- a/web/src/components/ui/select.tsx +++ b/web/src/components/ui/select.tsx @@ -1,10 +1,14 @@ 'use client'; import * as SelectPrimitive from '@radix-ui/react-select'; -import { Check, ChevronDown, ChevronUp } from 'lucide-react'; +import { Check, ChevronDown, ChevronUp, X } from 'lucide-react'; import * as React from 'react'; import { cn } from '@/lib/utils'; +import { ControllerRenderProps } from 'react-hook-form'; + +import { FormControl } from '@/components/ui/form'; +import { useCallback, useEffect } from 'react'; const Select = SelectPrimitive.Root; @@ -14,8 +18,10 @@ const SelectValue = SelectPrimitive.Value; const SelectTrigger = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( + React.ComponentPropsWithoutRef & { + onReset?: () => void; + } +>(({ className, children, value, onReset, ...props }, ref) => ( {children} - - + { + event.stopPropagation(); + }} + > + {value ? ( + + ) : ( + + )} )); @@ -158,3 +173,111 @@ export { SelectTrigger, SelectValue, }; + +export type RAGFlowSelectOptionType = { + label: React.ReactNode; + value: string; + disabled?: boolean; +}; + +export type RAGFlowSelectGroupOptionType = { + label: React.ReactNode; + options: RAGFlowSelectOptionType[]; +}; + +type RAGFlowSelectProps = Partial & { + FormControlComponent?: typeof FormControl; + options?: (RAGFlowSelectOptionType | RAGFlowSelectGroupOptionType)[]; +}; + +/** + * + * Reference: + * https://github.com/shadcn-ui/ui/discussions/638 + * https://github.com/radix-ui/primitives/discussions/2645#discussioncomment-8343397 + * + * @export + * @param {(Partial & { + * FormControlComponent?: typeof FormControl; + * })} { + * value: initialValue, + * onChange, + * FormControlComponent, + * } + * @return {*} + */ +export function RAGFlowSelect({ + value: initialValue, + onChange, + FormControlComponent, + options = [], +}: RAGFlowSelectProps) { + const [key, setKey] = React.useState(+new Date()); + const [value, setValue] = React.useState(undefined); + + const FormControlWidget = FormControlComponent + ? FormControlComponent + : React.Fragment; + + const handleChange = useCallback( + (val?: string) => { + setValue(val); + onChange?.(val); + }, + [onChange], + ); + + const handleReset = useCallback(() => { + handleChange(undefined); + setKey(+new Date()); + }, [handleChange]); + + useEffect(() => { + setValue((preValue) => { + if (preValue !== initialValue) { + return initialValue; + } + return preValue; + }); + }, [initialValue]); + + return ( + + ); +} diff --git a/web/src/pages/dataset/testing/testing-form.tsx b/web/src/pages/dataset/testing/testing-form.tsx index ae6b01b46..bae983b92 100644 --- a/web/src/pages/dataset/testing/testing-form.tsx +++ b/web/src/pages/dataset/testing/testing-form.tsx @@ -14,16 +14,20 @@ import { FormLabel, FormMessage, } from '@/components/ui/form'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; +import { RAGFlowSelect } from '@/components/ui/select'; import { FormSlider } from '@/components/ui/slider'; import { Textarea } from '@/components/ui/textarea'; +const options = [ + { label: 'xx', value: 'xx' }, + { label: 'ii', value: 'ii' }, +]; + +const groupOptions = [ + { label: 'scsdv', options }, + { label: 'thtyu', options: [{ label: 'jj', value: 'jj' }] }, +]; + const formSchema = z.object({ username: z.number().min(2, { message: 'Username must be at least 2 characters.', @@ -95,18 +99,12 @@ export default function TestingForm() { render={({ field }) => ( Username - + This is your public display name. diff --git a/web/src/pages/flow/canvas/node/node-header.tsx b/web/src/pages/flow/canvas/node/node-header.tsx index 4c7ad21f2..99a37dc1e 100644 --- a/web/src/pages/flow/canvas/node/node-header.tsx +++ b/web/src/pages/flow/canvas/node/node-header.tsx @@ -59,7 +59,7 @@ const NodeHeader = ({ > {name}