Skip to content

Commit be9a904

Browse files
committed
Change input from a slider to a text input
1 parent 2ccab14 commit be9a904

File tree

2 files changed

+51
-31
lines changed

2 files changed

+51
-31
lines changed

webview-ui/src/components/settings/TemperatureControl.tsx

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,17 @@ interface TemperatureControlProps {
99

1010
export const TemperatureControl = ({ value, onChange, maxValue = 1 }: TemperatureControlProps) => {
1111
const [isCustomTemperature, setIsCustomTemperature] = useState(value !== undefined)
12+
const [inputValue, setInputValue] = useState(value?.toString() ?? "0")
1213

1314
// Sync internal state with prop changes when switching profiles
1415
useEffect(() => {
1516
const hasCustomTemperature = value !== undefined
1617
setIsCustomTemperature(hasCustomTemperature)
18+
setInputValue(value?.toString() ?? "0")
1719
}, [value])
1820

1921
return (
20-
<div
21-
style={{
22-
marginTop: 10,
23-
marginBottom: 15,
24-
paddingLeft: 10,
25-
borderLeft: "2px solid var(--vscode-button-background)",
26-
}}>
22+
<div>
2723
<VSCodeCheckbox
2824
checked={isCustomTemperature}
2925
onChange={(e: any) => {
@@ -39,31 +35,44 @@ export const TemperatureControl = ({ value, onChange, maxValue = 1 }: Temperatur
3935
</VSCodeCheckbox>
4036

4137
<p style={{ fontSize: "12px", marginTop: "5px", color: "var(--vscode-descriptionForeground)" }}>
42-
Controls randomness in the model's responses. Higher values make output more random, lower values make
43-
it more deterministic.
38+
Controls randomness in the model's responses.
4439
</p>
4540

4641
{isCustomTemperature && (
47-
<div>
42+
<div
43+
style={{
44+
marginTop: 5,
45+
marginBottom: 10,
46+
paddingLeft: 10,
47+
borderLeft: "2px solid var(--vscode-button-background)",
48+
}}>
4849
<div style={{ display: "flex", alignItems: "center", gap: "5px" }}>
49-
<input aria-label="Temperature control range input"
50-
type="range"
51-
min="0"
52-
max={maxValue}
53-
step="0.05"
54-
value={value ?? 0}
55-
onChange={(e) => {
50+
<input
51+
aria-label="Temperature control text input"
52+
type="text"
53+
value={inputValue}
54+
onChange={(e) => setInputValue(e.target.value)}
55+
onBlur={(e) => {
5656
const newValue = parseFloat(e.target.value)
57-
onChange(isNaN(newValue) ? undefined : newValue)
57+
if (!isNaN(newValue) && newValue >= 0 && newValue <= maxValue) {
58+
onChange(newValue)
59+
setInputValue(newValue.toString())
60+
} else {
61+
setInputValue(value?.toString() ?? "0") // Reset to last valid value
62+
}
5863
}}
5964
style={{
60-
flexGrow: 1,
61-
accentColor: "var(--vscode-button-background)",
62-
height: "2px",
65+
width: "60px",
66+
padding: "4px 8px",
67+
border: "1px solid var(--vscode-input-border)",
68+
background: "var(--vscode-input-background)",
69+
color: "var(--vscode-input-foreground)",
6370
}}
6471
/>
65-
<span style={{ minWidth: "45px", textAlign: "left" }}>{value?.toFixed(2)}</span>
6672
</div>
73+
<p style={{ fontSize: "12px", marginTop: "8px", color: "var(--vscode-descriptionForeground)" }}>
74+
Higher values make output more random, lower values make it more deterministic.
75+
</p>
6776
</div>
6877
)}
6978
</div>

webview-ui/src/components/settings/__tests__/TemperatureControl.test.tsx

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe("TemperatureControl", () => {
88

99
const checkbox = screen.getByRole("checkbox")
1010
expect(checkbox).not.toBeChecked()
11-
expect(screen.queryByRole("slider")).not.toBeInTheDocument()
11+
expect(screen.queryByRole("textbox")).not.toBeInTheDocument()
1212
})
1313

1414
it("renders with custom temperature enabled", () => {
@@ -18,9 +18,9 @@ describe("TemperatureControl", () => {
1818
const checkbox = screen.getByRole("checkbox")
1919
expect(checkbox).toBeChecked()
2020

21-
const slider = screen.getByRole("slider")
22-
expect(slider).toBeInTheDocument()
23-
expect(slider).toHaveValue("0.7")
21+
const input = screen.getByRole("textbox")
22+
expect(input).toBeInTheDocument()
23+
expect(input).toHaveValue("0.7")
2424
})
2525

2626
it("updates when checkbox is toggled", () => {
@@ -38,12 +38,13 @@ describe("TemperatureControl", () => {
3838
expect(onChange).toHaveBeenCalledWith(0.7)
3939
})
4040

41-
it("updates temperature when slider changes", () => {
41+
it("updates temperature when input loses focus", () => {
4242
const onChange = jest.fn()
4343
render(<TemperatureControl value={0.7} onChange={onChange} />)
4444

45-
const slider = screen.getByRole("slider")
46-
fireEvent.change(slider, { target: { value: "0.8" } })
45+
const input = screen.getByRole("textbox")
46+
fireEvent.change(input, { target: { value: "0.8" } })
47+
fireEvent.blur(input)
4748

4849
expect(onChange).toHaveBeenCalledWith(0.8)
4950
})
@@ -52,8 +53,18 @@ describe("TemperatureControl", () => {
5253
const onChange = jest.fn()
5354
render(<TemperatureControl value={1.5} onChange={onChange} maxValue={2} />)
5455

55-
const slider = screen.getByRole("slider")
56-
expect(slider).toHaveAttribute("max", "2")
56+
const input = screen.getByRole("textbox")
57+
58+
// Valid value within max
59+
fireEvent.change(input, { target: { value: "1.8" } })
60+
fireEvent.blur(input)
61+
expect(onChange).toHaveBeenCalledWith(1.8)
62+
63+
// Invalid value above max
64+
fireEvent.change(input, { target: { value: "2.5" } })
65+
fireEvent.blur(input)
66+
expect(input).toHaveValue("1.5") // Should revert to original value
67+
expect(onChange).toHaveBeenCalledTimes(1) // Should not call onChange for invalid value
5768
})
5869

5970
it("syncs checkbox state when value prop changes", () => {

0 commit comments

Comments
 (0)