diff --git a/tools/server/webui/src/lib/components/app/chat/ChatSettings/CustomWidthCombobox.svelte b/tools/server/webui/src/lib/components/app/chat/ChatSettings/CustomWidthCombobox.svelte index 86de4c57d6..b3873f7058 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatSettings/CustomWidthCombobox.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatSettings/CustomWidthCombobox.svelte @@ -3,6 +3,7 @@ import * as Command from '$lib/components/ui/command'; import * as Popover from '$lib/components/ui/popover'; import { Button } from '$lib/components/ui/button'; + import { Input } from '$lib/components/ui/input'; import { cn } from '$lib/components/ui/utils'; import { tick } from 'svelte'; import { CUSTOM_WIDTH_PRESETS } from '$lib/utils/chat-width'; @@ -14,20 +15,41 @@ } let { value = $bindable(''), onChange, disabled = false }: Props = $props(); + console.log('Rendering CustomWidthCombobox with value:', value); let open = $state(false); + let showCustomPixelInput = $state(false); + let customPixelValue = $state(''); + let invalidCustomPixel = $state(false); + let triggerRef = $state(null!); - console.log("Rendering CustomWidthCombobox with value:", value); + let customPixelInputRef = $state(null!); const widthPresets = Object.entries(CUSTOM_WIDTH_PRESETS).map(([key, pixelValue]) => ({ value: key, label: `${key} (${pixelValue}px)` })); + const isValueANumber = $derived.by(() => { + const numValue = Number(value); + if (!isNaN(numValue) && numValue > 0) { + return true; + } + return false; + }); + const displayValue = $derived.by(() => { + if (showCustomPixelInput) { + return 'Set pixel value'; + } + const selectedWidthPreset = widthPresets.find((preset) => preset.value === value); if (selectedWidthPreset) return selectedWidthPreset.label; + if (isValueANumber) { + return `Custom (${Number(value)}px)`; + } + return 'Select width...'; }); @@ -40,9 +62,50 @@ function handleSelectPreset(newValue: string) { value = newValue; + showCustomPixelInput = false; onChange(newValue); closeAndFocusTrigger(); } + + function handleShowCustomPixelInput() { + open = false; + showCustomPixelInput = true; + + tick().then(() => { + if (customPixelInputRef) customPixelInputRef.focus(); + }); + } + + function handleCancelCustomPixelInput() { + showCustomPixelInput = false; + customPixelValue = ''; + } + + function handleKeydown(e: KeyboardEvent) { + if (e.key === 'Enter') { + e.preventDefault(); + handleSaveCustomPixelInput(); + } + } + + function handleSaveCustomPixelInput() { + if (!customPixelValue) { + invalidCustomPixel = true; + return; + } + + const number = Number(customPixelValue); + const isValid = !isNaN(number) && number >= 300 && number <= 10000; + + if (isValid) { + value = String(number); + onChange(String(number)); + invalidCustomPixel = false; + showCustomPixelInput = false; + } else { + invalidCustomPixel = true; + } + }
@@ -70,10 +133,25 @@ No presets found. + + + Set pixel value + + + + {#each widthPresets as preset (preset.value)} handleSelectPreset(preset.value)}> {preset.label} @@ -83,4 +161,33 @@ + + {#if showCustomPixelInput} +
+ + + +
+

+ Enter a value between 300 and 10000 pixels. +

+ {/if}