Merge pull request #248 from binaricat/fix/unify-settings-dropdowns

fix: unify settings dropdowns to use custom Radix-based Select
This commit is contained in:
陈大猫
2026-03-03 19:51:38 +08:00
committed by GitHub
2 changed files with 51 additions and 18 deletions
+50 -17
View File
@@ -1,4 +1,6 @@
import React from "react";
import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown, ChevronUp } from "lucide-react";
import { cn } from "../../lib/utils";
import { ScrollArea } from "../ui/scroll-area";
import { TabsContent } from "../ui/tabs";
@@ -38,23 +40,54 @@ interface SelectProps {
disabled?: boolean;
}
export const Select: React.FC<SelectProps> = ({ value, options, onChange, className, disabled }) => (
<select
value={value}
onChange={(e) => onChange(e.target.value)}
disabled={disabled}
className={cn(
"h-9 rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
>
{options.map((opt) => (
<option key={opt.value} value={opt.value}>
{opt.label}
</option>
))}
</select>
);
export const Select: React.FC<SelectProps> = ({ value, options, onChange, className, disabled }) => {
const selectedOption = options.find((opt) => opt.value === value);
return (
<SelectPrimitive.Root value={value} onValueChange={onChange} disabled={disabled}>
<SelectPrimitive.Trigger
className={cn(
"flex h-9 items-center justify-between rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className,
)}
>
<SelectPrimitive.Value>{selectedOption?.label ?? value}</SelectPrimitive.Value>
<SelectPrimitive.Icon asChild>
<ChevronDown className="ml-2 h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
<SelectPrimitive.Portal>
<SelectPrimitive.Content
className="z-[200000] max-h-80 min-w-[12rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1"
position="popper"
sideOffset={4}
>
<SelectPrimitive.ScrollUpButton className="flex cursor-default items-center justify-center py-1">
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
<SelectPrimitive.Viewport className="p-1 h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]">
{options.map((opt) => (
<SelectPrimitive.Item
key={opt.value}
value={opt.value}
className="relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{opt.label}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))}
</SelectPrimitive.Viewport>
<SelectPrimitive.ScrollDownButton className="flex cursor-default items-center justify-center py-1">
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
</SelectPrimitive.Root>
);
};
export const SectionHeader: React.FC<{ title: string; className?: string }> = ({
title,
@@ -473,7 +473,7 @@ export default function SettingsTerminalTab(props: {
onChange={(v) =>
updateTerminalSetting("terminalEmulationType", v as TerminalEmulationType)
}
className="w-36"
className="w-44"
/>
</SettingRow>
</div>