feat: add edit mode toggle to show/hide drag handles
- Add edit mode button next to settings in header - Edit button turns blue when active - Drag handles fade in/out with edit mode toggle - Add smooth 200ms transition animation - Add i18n support for edit mode (en/zh) - Maintain consistent spacing between header elements
This commit is contained in:
25
src/App.tsx
25
src/App.tsx
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import { Plus, Settings } from "lucide-react";
|
||||
import { Plus, Settings, Edit3 } from "lucide-react";
|
||||
import type { Provider } from "@/types";
|
||||
import { useProvidersQuery } from "@/lib/query";
|
||||
import {
|
||||
@@ -27,6 +27,7 @@ function App() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [activeApp, setActiveApp] = useState<AppType>("claude");
|
||||
const [isEditMode, setIsEditMode] = useState(false);
|
||||
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
|
||||
const [isAddOpen, setIsAddOpen] = useState(false);
|
||||
const [isMcpOpen, setIsMcpOpen] = useState(false);
|
||||
@@ -58,7 +59,7 @@ function App() {
|
||||
if (event.appType === activeApp) {
|
||||
await refetch();
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("[App] Failed to subscribe provider switch event", error);
|
||||
@@ -112,7 +113,7 @@ function App() {
|
||||
<div className="flex h-screen flex-col bg-gray-50 dark:bg-gray-950">
|
||||
<header className="flex-shrink-0 border-b border-gray-200 bg-white px-6 py-4 dark:border-gray-800 dark:bg-gray-900">
|
||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<a
|
||||
href="https://github.com/farion1231/cc-switch"
|
||||
target="_blank"
|
||||
@@ -125,9 +126,26 @@ function App() {
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setIsSettingsOpen(true)}
|
||||
title={t("common.settings")}
|
||||
className="ml-2"
|
||||
>
|
||||
<Settings className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setIsEditMode(!isEditMode)}
|
||||
title={t(
|
||||
isEditMode ? "header.exitEditMode" : "header.enterEditMode"
|
||||
)}
|
||||
className={
|
||||
isEditMode
|
||||
? "text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
<Edit3 className="h-4 w-4" />
|
||||
</Button>
|
||||
<UpdateBadge onClick={() => setIsSettingsOpen(true)} />
|
||||
</div>
|
||||
|
||||
@@ -155,6 +173,7 @@ function App() {
|
||||
currentProviderId={currentProviderId}
|
||||
appType={activeApp}
|
||||
isLoading={isLoading}
|
||||
isEditMode={isEditMode}
|
||||
onSwitch={switchProvider}
|
||||
onEdit={setEditingProvider}
|
||||
onDelete={setConfirmDelete}
|
||||
|
||||
@@ -21,6 +21,7 @@ interface ProviderCardProps {
|
||||
provider: Provider;
|
||||
isCurrent: boolean;
|
||||
appType: AppType;
|
||||
isEditMode?: boolean;
|
||||
onSwitch: (provider: Provider) => void;
|
||||
onEdit: (provider: Provider) => void;
|
||||
onDelete: (provider: Provider) => void;
|
||||
@@ -59,6 +60,7 @@ export function ProviderCard({
|
||||
provider,
|
||||
isCurrent,
|
||||
appType,
|
||||
isEditMode = false,
|
||||
onSwitch,
|
||||
onEdit,
|
||||
onDelete,
|
||||
@@ -101,7 +103,10 @@ export function ProviderCard({
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"mt-1 flex h-8 w-8 items-center justify-center rounded-md border border-transparent text-muted-foreground transition-colors hover:border-muted hover:text-foreground",
|
||||
"mt-1 flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border text-muted-foreground transition-all duration-200",
|
||||
isEditMode
|
||||
? "border-muted hover:border-primary hover:text-foreground opacity-100"
|
||||
: "border-transparent opacity-0 pointer-events-none",
|
||||
dragHandleProps?.isDragging && "border-primary text-primary",
|
||||
)}
|
||||
aria-label={t("provider.dragHandle")}
|
||||
|
||||
@@ -16,6 +16,7 @@ interface ProviderListProps {
|
||||
providers: Record<string, Provider>;
|
||||
currentProviderId: string;
|
||||
appType: AppType;
|
||||
isEditMode?: boolean;
|
||||
onSwitch: (provider: Provider) => void;
|
||||
onEdit: (provider: Provider) => void;
|
||||
onDelete: (provider: Provider) => void;
|
||||
@@ -29,6 +30,7 @@ export function ProviderList({
|
||||
providers,
|
||||
currentProviderId,
|
||||
appType,
|
||||
isEditMode = false,
|
||||
onSwitch,
|
||||
onEdit,
|
||||
onDelete,
|
||||
@@ -76,6 +78,7 @@ export function ProviderList({
|
||||
provider={provider}
|
||||
isCurrent={provider.id === currentProviderId}
|
||||
appType={appType}
|
||||
isEditMode={isEditMode}
|
||||
onSwitch={onSwitch}
|
||||
onEdit={onEdit}
|
||||
onDelete={onDelete}
|
||||
@@ -93,6 +96,7 @@ interface SortableProviderCardProps {
|
||||
provider: Provider;
|
||||
isCurrent: boolean;
|
||||
appType: AppType;
|
||||
isEditMode: boolean;
|
||||
onSwitch: (provider: Provider) => void;
|
||||
onEdit: (provider: Provider) => void;
|
||||
onDelete: (provider: Provider) => void;
|
||||
@@ -104,6 +108,7 @@ function SortableProviderCard({
|
||||
provider,
|
||||
isCurrent,
|
||||
appType,
|
||||
isEditMode,
|
||||
onSwitch,
|
||||
onEdit,
|
||||
onDelete,
|
||||
@@ -130,6 +135,7 @@ function SortableProviderCard({
|
||||
provider={provider}
|
||||
isCurrent={isCurrent}
|
||||
appType={appType}
|
||||
isEditMode={isEditMode}
|
||||
onSwitch={onSwitch}
|
||||
onEdit={onEdit}
|
||||
onDelete={onDelete}
|
||||
|
||||
@@ -47,7 +47,9 @@
|
||||
"toggleLightMode": "Switch to Light Mode",
|
||||
"addProvider": "Add Provider",
|
||||
"switchToChinese": "Switch to Chinese",
|
||||
"switchToEnglish": "Switch to English"
|
||||
"switchToEnglish": "Switch to English",
|
||||
"enterEditMode": "Enter Edit Mode",
|
||||
"exitEditMode": "Exit Edit Mode"
|
||||
},
|
||||
"provider": {
|
||||
"noProviders": "No providers added yet",
|
||||
|
||||
@@ -47,7 +47,9 @@
|
||||
"toggleLightMode": "切换到亮色模式",
|
||||
"addProvider": "添加供应商",
|
||||
"switchToChinese": "切换到中文",
|
||||
"switchToEnglish": "切换到英文"
|
||||
"switchToEnglish": "切换到英文",
|
||||
"enterEditMode": "进入编辑模式",
|
||||
"exitEditMode": "退出编辑模式"
|
||||
},
|
||||
"provider": {
|
||||
"noProviders": "还没有添加任何供应商",
|
||||
|
||||
Reference in New Issue
Block a user