Download client/src/components/SidePanel/Parameters/DynamicSlider.tsx from Zhitomir/chat: direct link, hf CLI and curl.
- Browser
- Download file 5.71 kB
-
https://huggingface.co/spaces/Zhitomir/chat/resolve/main/client/src/components/SidePanel/Parameters/DynamicSlider.tsx
- Command line
-
hf download hf://spaces/Zhitomir/chat/client/src/components/SidePanel/Parameters/DynamicSlider.tsx
-
curl -L -o DynamicSlider.tsx https://huggingface.co/spaces/Zhitomir/chat/resolve/main/client/src/components/SidePanel/Parameters/DynamicSlider.tsx
5.71 kB
| import { useMemo, useCallback } from 'react'; | |
| import { OptionTypes } from 'librechat-data-provider'; | |
| import type { DynamicSettingProps } from 'librechat-data-provider'; | |
| import { Label, Slider, HoverCard, Input, InputNumber, HoverCardTrigger } from '~/components/ui'; | |
| import { useLocalize, useDebouncedInput, useParameterEffects } from '~/hooks'; | |
| import { cn, defaultTextProps, optionText } from '~/utils'; | |
| import { ESide, defaultDebouncedDelay } from '~/common'; | |
| import { useChatContext } from '~/Providers'; | |
| import OptionHover from './OptionHover'; | |
| function DynamicSlider({ | |
| label, | |
| settingKey, | |
| defaultValue, | |
| range, | |
| description, | |
| columnSpan, | |
| setOption, | |
| optionType, | |
| options, | |
| readonly = false, | |
| showDefault = true, | |
| includeInput = true, | |
| labelCode, | |
| descriptionCode, | |
| conversation, | |
| }: DynamicSettingProps) { | |
| const localize = useLocalize(); | |
| const { preset } = useChatContext(); | |
| const isEnum = useMemo(() => !range && options && options.length > 0, [options, range]); | |
| const [setInputValue, inputValue] = useDebouncedInput<string | number>({ | |
| optionKey: optionType !== OptionTypes.Custom ? settingKey : undefined, | |
| initialValue: optionType !== OptionTypes.Custom ? conversation?.[settingKey] : defaultValue, | |
| setter: () => ({}), | |
| setOption, | |
| delay: isEnum ? 0 : defaultDebouncedDelay, | |
| }); | |
| useParameterEffects({ | |
| preset, | |
| settingKey, | |
| defaultValue, | |
| conversation, | |
| inputValue, | |
| setInputValue, | |
| preventDelayedUpdate: isEnum, | |
| }); | |
| const selectedValue = useMemo(() => { | |
| if (isEnum) { | |
| return conversation?.[settingKey] ?? defaultValue; | |
| } | |
| // TODO: custom logic, add to payload but not to conversation | |
| return inputValue; | |
| }, [conversation, defaultValue, settingKey, inputValue, isEnum]); | |
| const enumToNumeric = useMemo(() => { | |
| if (isEnum && options) { | |
| return options.reduce((acc, mapping, index) => { | |
| acc[mapping] = index; | |
| return acc; | |
| }, {} as Record<string, number>); | |
| } | |
| return {}; | |
| }, [isEnum, options]); | |
| const valueToEnumOption = useMemo(() => { | |
| if (isEnum && options) { | |
| return options.reduce((acc, option, index) => { | |
| acc[index] = option; | |
| return acc; | |
| }, {} as Record<number, string>); | |
| } | |
| return {}; | |
| }, [isEnum, options]); | |
| const handleValueChange = useCallback( | |
| (value: number) => { | |
| if (isEnum) { | |
| setInputValue(valueToEnumOption[value]); | |
| } else { | |
| setInputValue(value); | |
| } | |
| }, | |
| [isEnum, setInputValue, valueToEnumOption], | |
| ); | |
| if (!range && !isEnum) { | |
| return null; | |
| } | |
| return ( | |
| <div | |
| className={cn( | |
| 'flex flex-col items-center justify-start gap-6', | |
| columnSpan ? `col-span-${columnSpan}` : 'col-span-full', | |
| )} | |
| > | |
| <HoverCard openDelay={300}> | |
| <HoverCardTrigger className="grid w-full items-center gap-2"> | |
| <div className="flex justify-between"> | |
| <Label | |
| htmlFor={`${settingKey}-dynamic-setting`} | |
| className="text-left text-sm font-medium" | |
| > | |
| {labelCode ? localize(label ?? '') || label : label ?? settingKey}{' '} | |
| {showDefault && ( | |
| <small className="opacity-40"> | |
| ({localize('com_endpoint_default')}: {defaultValue}) | |
| </small> | |
| )} | |
| </Label> | |
| {includeInput && !isEnum ? ( | |
| <InputNumber | |
| id={`${settingKey}-dynamic-setting-input-number`} | |
| disabled={readonly} | |
| value={inputValue ?? defaultValue} | |
| onChange={(value) => setInputValue(Number(value))} | |
| max={range ? range.max : (options?.length ?? 0) - 1} | |
| min={range ? range.min : 0} | |
| step={range ? range.step ?? 1 : 1} | |
| controls={false} | |
| className={cn( | |
| defaultTextProps, | |
| cn( | |
| optionText, | |
| 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200', | |
| ), | |
| )} | |
| /> | |
| ) : ( | |
| <Input | |
| id={`${settingKey}-dynamic-setting-input`} | |
| disabled={readonly} | |
| value={selectedValue ?? defaultValue} | |
| onChange={() => ({})} | |
| className={cn( | |
| defaultTextProps, | |
| cn( | |
| optionText, | |
| 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200', | |
| ), | |
| )} | |
| /> | |
| )} | |
| </div> | |
| <Slider | |
| id={`${settingKey}-dynamic-setting-slider`} | |
| disabled={readonly} | |
| value={[ | |
| isEnum | |
| ? enumToNumeric[(selectedValue as number) ?? ''] | |
| : (inputValue as number) ?? (defaultValue as number), | |
| ]} | |
| onValueChange={(value) => handleValueChange(value[0])} | |
| doubleClickHandler={() => setInputValue(defaultValue as string | number)} | |
| max={isEnum && options ? options.length - 1 : range ? range.max : 0} | |
| min={range ? range.min : 0} | |
| step={range ? range.step ?? 1 : 1} | |
| className="flex h-4 w-full" | |
| /> | |
| </HoverCardTrigger> | |
| {description && ( | |
| <OptionHover | |
| description={descriptionCode ? localize(description) || description : description} | |
| side={ESide.Left} | |
| /> | |
| )} | |
| </HoverCard> | |
| </div> | |
| ); | |
| } | |
| export default DynamicSlider; | |