mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-25 13:45:03 +08:00
fix(ui): resolve Select dropdown not appearing in FullScreenPanel
- Increase SelectContent z-index from z-50 to z-[100] to appear above FullScreenPanel (z-[60]) - Replace form.watch() with form.getValues() in useCallback handlers for correct react-hook-form usage - Remove max-w-[56rem] constraints from various panels for consistent full-width layout
This commit is contained in:
+3
-3
@@ -468,13 +468,13 @@ function App() {
|
||||
);
|
||||
case "universal":
|
||||
return (
|
||||
<div className="mx-auto max-w-[56rem] px-5 pt-4">
|
||||
<div className="px-6 pt-4">
|
||||
<UniversalProviderPanel />
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<div className="mx-auto max-w-[56rem] px-5 flex flex-col h-[calc(100vh-8rem)] overflow-hidden">
|
||||
<div className="px-6 flex flex-col h-[calc(100vh-8rem)] overflow-hidden">
|
||||
{/* 独立滚动容器 - 解决 Linux/Ubuntu 下 DndContext 与滚轮事件冲突 */}
|
||||
<div className="flex-1 overflow-y-auto overflow-x-hidden pb-12 px-1">
|
||||
<AnimatePresence mode="wait">
|
||||
@@ -580,7 +580,7 @@ function App() {
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="mx-auto flex h-full max-w-[56rem] flex-wrap items-center justify-between gap-2 px-6"
|
||||
className="flex h-full items-center justify-between gap-2 px-6"
|
||||
data-tauri-drag-region
|
||||
style={{ WebkitAppRegion: "drag" } as any}
|
||||
>
|
||||
|
||||
@@ -72,7 +72,7 @@ export const FullScreenPanel: React.FC<FullScreenPanelProps> = ({
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="mx-auto max-w-[56rem] px-6 w-full flex items-center gap-4"
|
||||
className="px-6 w-full flex items-center gap-4"
|
||||
data-tauri-drag-region
|
||||
style={{ WebkitAppRegion: "drag" } as React.CSSProperties}
|
||||
>
|
||||
@@ -94,7 +94,7 @@ export const FullScreenPanel: React.FC<FullScreenPanelProps> = ({
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 overflow-y-auto scroll-overlay">
|
||||
<div className="mx-auto max-w-[56rem] px-6 py-6 space-y-6 w-full">
|
||||
<div className="px-6 py-6 space-y-6 w-full">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
@@ -105,7 +105,7 @@ export const FullScreenPanel: React.FC<FullScreenPanelProps> = ({
|
||||
className="flex-shrink-0 py-4 border-t border-border-default"
|
||||
style={{ backgroundColor: "hsl(var(--background))" }}
|
||||
>
|
||||
<div className="mx-auto max-w-[56rem] px-6 flex items-center justify-end gap-3">
|
||||
<div className="px-6 flex items-center justify-end gap-3">
|
||||
{footer}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -142,7 +142,7 @@ const UnifiedMcpPanel = React.forwardRef<
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-[56rem] px-6 flex flex-col h-[calc(100vh-8rem)] overflow-hidden">
|
||||
<div className="px-6 flex flex-col h-[calc(100vh-8rem)] overflow-hidden">
|
||||
{/* Info Section */}
|
||||
<div className="flex-shrink-0 py-4 glass rounded-xl border border-white/10 mb-4 px-6">
|
||||
<div className="text-sm text-muted-foreground">
|
||||
|
||||
@@ -96,7 +96,7 @@ const PromptPanel = React.forwardRef<PromptPanelHandle, PromptPanelProps>(
|
||||
const enabledPrompt = promptEntries.find(([_, p]) => p.enabled);
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-[56rem] flex flex-col h-[calc(100vh-8rem)] px-6">
|
||||
<div className="flex flex-col h-[calc(100vh-8rem)] px-6">
|
||||
<div className="flex-shrink-0 py-4 glass rounded-xl border border-white/10 mb-4 px-6">
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{t("prompts.count", { count: promptEntries.length })} ·{" "}
|
||||
|
||||
@@ -78,7 +78,7 @@ export function BasicFormFields({ form }: BasicFormFieldsProps) {
|
||||
>
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex-shrink-0 py-4 border-b border-border-default bg-muted/40">
|
||||
<div className="mx-auto max-w-[56rem] px-6 flex items-center gap-4">
|
||||
<div className="px-6 flex items-center gap-4">
|
||||
<DialogClose asChild>
|
||||
<Button type="button" variant="outline" size="icon">
|
||||
<ArrowLeft className="h-4 w-4" />
|
||||
@@ -92,7 +92,7 @@ export function BasicFormFields({ form }: BasicFormFieldsProps) {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<div className="space-y-2 mx-auto max-w-[56rem] px-6 py-6 w-full">
|
||||
<div className="space-y-2 px-6 py-6 w-full">
|
||||
<IconPicker
|
||||
value={currentIcon}
|
||||
onValueChange={handleIconSelect}
|
||||
|
||||
@@ -192,7 +192,7 @@ export function ProviderForm({
|
||||
mode: "onSubmit",
|
||||
});
|
||||
|
||||
const settingsConfigValue = form.watch("settingsConfig");
|
||||
const settingsConfigValue = form.getValues("settingsConfig");
|
||||
|
||||
// 使用 API Key hook
|
||||
const {
|
||||
@@ -200,7 +200,7 @@ export function ProviderForm({
|
||||
handleApiKeyChange,
|
||||
showApiKey: shouldShowApiKey,
|
||||
} = useApiKeyState({
|
||||
initialConfig: form.watch("settingsConfig"),
|
||||
initialConfig: form.getValues("settingsConfig"),
|
||||
onConfigChange: (config) => form.setValue("settingsConfig", config),
|
||||
selectedPresetId,
|
||||
category,
|
||||
@@ -211,7 +211,7 @@ export function ProviderForm({
|
||||
const { baseUrl, handleClaudeBaseUrlChange } = useBaseUrlState({
|
||||
appType: appId,
|
||||
category,
|
||||
settingsConfig: form.watch("settingsConfig"),
|
||||
settingsConfig: form.getValues("settingsConfig"),
|
||||
codexConfig: "",
|
||||
onSettingsConfigChange: (config) => form.setValue("settingsConfig", config),
|
||||
onCodexConfigChange: () => {
|
||||
@@ -228,7 +228,7 @@ export function ProviderForm({
|
||||
defaultOpusModel,
|
||||
handleModelChange,
|
||||
} = useModelState({
|
||||
settingsConfig: form.watch("settingsConfig"),
|
||||
settingsConfig: form.getValues("settingsConfig"),
|
||||
onConfigChange: (config) => form.setValue("settingsConfig", config),
|
||||
});
|
||||
|
||||
@@ -371,7 +371,7 @@ export function ProviderForm({
|
||||
} = useTemplateValues({
|
||||
selectedPresetId: appId === "claude" ? selectedPresetId : null,
|
||||
presetEntries: appId === "claude" ? presetEntries : [],
|
||||
settingsConfig: form.watch("settingsConfig"),
|
||||
settingsConfig: form.getValues("settingsConfig"),
|
||||
onConfigChange: (config) => form.setValue("settingsConfig", config),
|
||||
});
|
||||
|
||||
@@ -385,7 +385,7 @@ export function ProviderForm({
|
||||
isExtracting: isClaudeExtracting,
|
||||
handleExtract: handleClaudeExtract,
|
||||
} = useCommonConfigSnippet({
|
||||
settingsConfig: form.watch("settingsConfig"),
|
||||
settingsConfig: form.getValues("settingsConfig"),
|
||||
onConfigChange: (config) => form.setValue("settingsConfig", config),
|
||||
initialData: appId === "claude" ? initialData : undefined,
|
||||
selectedPresetId: selectedPresetId ?? undefined,
|
||||
@@ -434,7 +434,7 @@ export function ProviderForm({
|
||||
originalHandleGeminiApiKeyChange(key);
|
||||
// 同步更新 settingsConfig
|
||||
try {
|
||||
const config = JSON.parse(form.watch("settingsConfig") || "{}");
|
||||
const config = JSON.parse(form.getValues("settingsConfig") || "{}");
|
||||
if (!config.env) config.env = {};
|
||||
config.env.GEMINI_API_KEY = key.trim();
|
||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
||||
@@ -450,7 +450,7 @@ export function ProviderForm({
|
||||
originalHandleGeminiBaseUrlChange(url);
|
||||
// 同步更新 settingsConfig
|
||||
try {
|
||||
const config = JSON.parse(form.watch("settingsConfig") || "{}");
|
||||
const config = JSON.parse(form.getValues("settingsConfig") || "{}");
|
||||
if (!config.env) config.env = {};
|
||||
config.env.GOOGLE_GEMINI_BASE_URL = url.trim().replace(/\/+$/, "");
|
||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
||||
@@ -466,7 +466,7 @@ export function ProviderForm({
|
||||
originalHandleGeminiModelChange(model);
|
||||
// 同步更新 settingsConfig
|
||||
try {
|
||||
const config = JSON.parse(form.watch("settingsConfig") || "{}");
|
||||
const config = JSON.parse(form.getValues("settingsConfig") || "{}");
|
||||
if (!config.env) config.env = {};
|
||||
config.env.GEMINI_MODEL = model.trim();
|
||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
||||
@@ -541,7 +541,7 @@ export function ProviderForm({
|
||||
(npm: string) => {
|
||||
setOpencodeNpm(npm);
|
||||
try {
|
||||
const config = JSON.parse(form.watch("settingsConfig") || OPENCODE_DEFAULT_CONFIG);
|
||||
const config = JSON.parse(form.getValues("settingsConfig") || OPENCODE_DEFAULT_CONFIG);
|
||||
config.npm = npm;
|
||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
||||
} catch {
|
||||
@@ -555,7 +555,7 @@ export function ProviderForm({
|
||||
(apiKey: string) => {
|
||||
setOpencodeApiKey(apiKey);
|
||||
try {
|
||||
const config = JSON.parse(form.watch("settingsConfig") || OPENCODE_DEFAULT_CONFIG);
|
||||
const config = JSON.parse(form.getValues("settingsConfig") || OPENCODE_DEFAULT_CONFIG);
|
||||
if (!config.options) config.options = {};
|
||||
config.options.apiKey = apiKey;
|
||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
||||
@@ -570,7 +570,7 @@ export function ProviderForm({
|
||||
(baseUrl: string) => {
|
||||
setOpencodeBaseUrl(baseUrl);
|
||||
try {
|
||||
const config = JSON.parse(form.watch("settingsConfig") || OPENCODE_DEFAULT_CONFIG);
|
||||
const config = JSON.parse(form.getValues("settingsConfig") || OPENCODE_DEFAULT_CONFIG);
|
||||
if (!config.options) config.options = {};
|
||||
config.options.baseURL = baseUrl.trim().replace(/\/+$/, "");
|
||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
||||
@@ -585,7 +585,7 @@ export function ProviderForm({
|
||||
(models: Record<string, OpenCodeModel>) => {
|
||||
setOpencodeModels(models);
|
||||
try {
|
||||
const config = JSON.parse(form.watch("settingsConfig") || OPENCODE_DEFAULT_CONFIG);
|
||||
const config = JSON.parse(form.getValues("settingsConfig") || OPENCODE_DEFAULT_CONFIG);
|
||||
config.models = models;
|
||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
||||
} catch {
|
||||
@@ -971,7 +971,7 @@ export function ProviderForm({
|
||||
<ClaudeFormFields
|
||||
providerId={providerId}
|
||||
shouldShowApiKey={shouldShowApiKey(
|
||||
form.watch("settingsConfig"),
|
||||
form.getValues("settingsConfig"),
|
||||
isEditMode,
|
||||
)}
|
||||
apiKey={apiKey}
|
||||
@@ -1042,7 +1042,7 @@ export function ProviderForm({
|
||||
<GeminiFormFields
|
||||
providerId={providerId}
|
||||
shouldShowApiKey={shouldShowApiKey(
|
||||
form.watch("settingsConfig"),
|
||||
form.getValues("settingsConfig"),
|
||||
isEditMode,
|
||||
)}
|
||||
apiKey={geminiApiKey}
|
||||
@@ -1146,7 +1146,7 @@ export function ProviderForm({
|
||||
) : appId === "opencode" ? (
|
||||
<>
|
||||
<CommonConfigEditor
|
||||
value={form.watch("settingsConfig")}
|
||||
value={form.getValues("settingsConfig")}
|
||||
onChange={(config) => form.setValue("settingsConfig", config)}
|
||||
useCommonConfig={false}
|
||||
onCommonConfigToggle={() => {}}
|
||||
@@ -1172,7 +1172,7 @@ export function ProviderForm({
|
||||
) : (
|
||||
<>
|
||||
<CommonConfigEditor
|
||||
value={form.watch("settingsConfig")}
|
||||
value={form.getValues("settingsConfig")}
|
||||
onChange={(value) => form.setValue("settingsConfig", value)}
|
||||
useCommonConfig={useCommonConfig}
|
||||
onCommonConfigToggle={handleCommonConfigToggle}
|
||||
|
||||
@@ -202,7 +202,7 @@ export function SettingsPage({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-[56rem] flex flex-col h-[calc(100vh-8rem)] overflow-hidden px-6">
|
||||
<div className="flex flex-col h-[calc(100vh-8rem)] overflow-hidden px-6">
|
||||
{isBusy ? (
|
||||
<div className="flex flex-1 items-center justify-center">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
|
||||
|
||||
@@ -193,7 +193,7 @@ export const SkillsPage = forwardRef<SkillsPageHandle, SkillsPageProps>(
|
||||
}, [skills, searchQuery, filterStatus]);
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-[56rem] px-6 flex flex-col h-[calc(100vh-8rem)] overflow-hidden bg-background/50">
|
||||
<div className="px-6 flex flex-col h-[calc(100vh-8rem)] overflow-hidden bg-background/50">
|
||||
{/* 技能网格(可滚动详情区域) */}
|
||||
<div className="flex-1 overflow-y-auto overflow-x-hidden animate-fade-in">
|
||||
<div className="py-4">
|
||||
|
||||
@@ -133,7 +133,7 @@ const UnifiedSkillsPanel = React.forwardRef<
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-[56rem] px-6 flex flex-col h-[calc(100vh-8rem)] overflow-hidden">
|
||||
<div className="px-6 flex flex-col h-[calc(100vh-8rem)] overflow-hidden">
|
||||
{/* Info Section */}
|
||||
<div className="flex-shrink-0 py-4 glass rounded-xl border border-white/10 mb-4 px-6">
|
||||
<div className="text-sm text-muted-foreground">
|
||||
|
||||
@@ -37,7 +37,7 @@ const SelectContent = React.forwardRef<
|
||||
<SelectPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border border-border-default bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
"relative z-[100] min-w-[8rem] overflow-hidden rounded-md border border-border-default bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
position={position}
|
||||
|
||||
Reference in New Issue
Block a user