Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate Settings Components #967

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,422 changes: 705 additions & 717 deletions webview-ui/src/components/settings/ApiOptions.tsx

Large diffs are not rendered by default.

31 changes: 0 additions & 31 deletions webview-ui/src/components/settings/ExperimentalFeature.tsx

This file was deleted.

11 changes: 9 additions & 2 deletions webview-ui/src/components/settings/ModelPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,14 @@ export const ModelPicker = ({
useEffect(() => setValue(selectedModelId), [selectedModelId])

return (
<>
<div
style={{
marginBottom: 15,
marginTop: 10,
paddingLeft: 10,
borderLeft: "2px solid",
borderColor: "var(--vscode-button-background)",
}}>
<div className="font-semibold">Model</div>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
Expand Down Expand Up @@ -219,6 +226,6 @@ export const ModelPicker = ({
</div>
</div>
)}
</>
</div>
)
}
43 changes: 43 additions & 0 deletions webview-ui/src/components/settings/SettingCheckbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"

interface SettingCheckboxProps {
name: string
description: React.ReactNode
checked?: boolean
onChange: (value: boolean) => void
experimental?: boolean
children?: React.ReactNode
}

const SettingCheckbox = ({
name,
description,
checked: enabled,
onChange,
experimental,
children,
}: SettingCheckboxProps) => {
return (
<div
style={{
marginTop: 10,
marginBottom: 15,
paddingLeft: 10,
borderLeft: "2px solid",
borderColor: experimental ? "var(--vscode-errorForeground)" : "var(--vscode-button-background)",
}}>
<div style={{ display: "flex", alignItems: "center", gap: "5px" }}>
{experimental && <span style={{ color: "var(--vscode-errorForeground)" }}>⚠️</span>}
<VSCodeCheckbox checked={enabled} onChange={(e: any) => onChange(e.target.checked)}>
<span style={{ fontWeight: "700" }}>{name}</span>
</VSCodeCheckbox>
</div>
<p style={{ fontSize: "12px", marginTop: "5px", color: "var(--vscode-descriptionForeground)" }}>
{description}
</p>
{enabled && children}
</div>
)
}

export default SettingCheckbox
55 changes: 55 additions & 0 deletions webview-ui/src/components/settings/SettingCombo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Dropdown } from "vscrui"
import type { DropdownOption } from "vscrui"

interface SettingComboProps {
id?: string
name: string
description?: string
value?: string
onChange: (value: string) => void
options: DropdownOption[]
children?: React.ReactNode
inline?: boolean
}

const SettingCombo = ({ id, name, description, value, onChange, options, children, inline }: SettingComboProps) => {
const defaultValue = options.length > 0 ? options[0].value : undefined
return (
<div
style={{
marginBottom: 15,
marginTop: 10,
paddingLeft: 10,
borderLeft: "2px solid",
borderColor: "var(--vscode-button-background)",
}}>
<div style={{ display: inline ? "flex" : "block", alignItems: "end" }}>
<label style={{ fontWeight: "700", display: "block", marginBottom: 5, paddingRight: 10 }}>{name}</label>
<div className="dropdown-container">
<Dropdown
id={id}
value={value ?? defaultValue}
onChange={(value: unknown) => {
onChange((value as DropdownOption).value)
}}
style={{ width: "100%" }}
options={options}
/>
</div>
</div>
{description && (
<p
style={{
fontSize: "12px",
marginTop: "5px",
color: "var(--vscode-descriptionForeground)",
}}>
{description}
</p>
)}
{children}
</div>
)
}

export default SettingCombo
83 changes: 83 additions & 0 deletions webview-ui/src/components/settings/SettingSlider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { memo } from "react"

interface SettingSliderProps {
name: string
description?: string
value: number
onChange: (value: number) => void
min: number
max: number
step: number
unit?: string
style?: React.CSSProperties
}

const SettingSlider = ({
name,
description,
value,
onChange,
min,
max,
step,
unit = "",
style,
}: SettingSliderProps) => {
const sliderStyle = {
flexGrow: 1,
accentColor: "var(--vscode-button-background)",
height: "2px",
}

const labelStyle = {
minWidth: "45px",
lineHeight: "20px",
paddingBottom: "2px",
paddingLeft: "5px",
}

return (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "5px",
marginTop: 10,
marginBottom: 15,
paddingLeft: 10,
borderLeft: "2px solid",
borderColor: "var(--vscode-button-background)",
...style,
}}>
<span style={{ fontWeight: "700" }}>{name}</span>
<div style={{ display: "flex", alignItems: "center", gap: "5px" }}>
<input
type="range"
min={min}
max={max}
step={step}
value={value}
onChange={(e) => onChange(parseFloat(e.target.value))}
style={sliderStyle}
aria-label={name.toLowerCase()}
/>
<span style={labelStyle}>
{value}
{unit}
</span>
</div>
{description && (
<p
style={{
fontSize: "12px",
marginTop: "5px",
color: "var(--vscode-descriptionForeground)",
}}>
{description}
</p>
)}
</div>
)
}

export default memo(SettingSlider)
47 changes: 47 additions & 0 deletions webview-ui/src/components/settings/SettingTextField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"

interface SettingTextFieldProps {
name: string
description: React.ReactNode
value?: string
placeholder?: string
type?: "text" | "password" | "url" // Limited to types actually used in ApiOptions.tsx
onBlur: (value: string) => void
children?: React.ReactNode
}

const SettingTextField = ({
name,
description,
value,
placeholder,
type = "text",
onBlur,
children,
}: SettingTextFieldProps) => {
return (
<div
style={{
marginTop: 10,
marginBottom: 15,
paddingLeft: 10,
borderLeft: "2px solid",
borderColor: "var(--vscode-button-background)",
}}>
<VSCodeTextField
value={value || ""}
style={{ width: "100%" }}
type={type}
onBlur={(e: any) => onBlur(e.target.value)}
placeholder={placeholder}>
<span style={{ fontWeight: "700" }}>{name}</span>
</VSCodeTextField>
<p style={{ fontSize: "12px", marginTop: "5px", color: "var(--vscode-descriptionForeground)" }}>
{description}
</p>
{children}
</div>
)
}

export default SettingTextField
Loading
Loading