mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-10-09 15:58:34 +00:00
929d7dbe74
Refactors UI font handling to support dynamic font loading and improves selection in settings. Implements "Load More" pagination for connection logs, enhancing performance and user experience with large datasets. Adds lazy loading for the Connection Logs Manager. Addresses an issue in `usePortForwardingState` to prevent duplicate backend sync calls in React StrictMode. Improves IPC communication robustness by checking window destruction status. Refines the visual presentation of the snippets empty state.
78 lines
3.4 KiB
TypeScript
78 lines
3.4 KiB
TypeScript
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 type { TerminalFont } from '../../infrastructure/config/fonts';
|
|
|
|
interface TerminalFontSelectProps {
|
|
value: string;
|
|
fonts: TerminalFont[];
|
|
onChange: (value: string) => void;
|
|
className?: string;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
export const TerminalFontSelect: React.FC<TerminalFontSelectProps> = ({
|
|
value,
|
|
fonts,
|
|
onChange,
|
|
className,
|
|
disabled,
|
|
}) => {
|
|
const selectedFont = fonts.find(f => f.id === 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>
|
|
<span style={{ fontFamily: selectedFont?.family }}>
|
|
{selectedFont?.name || value}
|
|
</span>
|
|
</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-[14rem] 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)]">
|
|
{fonts.map((font) => (
|
|
<SelectPrimitive.Item
|
|
key={font.id}
|
|
value={font.id}
|
|
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>
|
|
<span style={{ fontFamily: font.family }}>{font.name}</span>
|
|
</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 default TerminalFontSelect;
|