diff --git a/src/components/ProjectCreationWizard.jsx b/src/components/ProjectCreationWizard.jsx index 5126d44a..a41799ce 100644 --- a/src/components/ProjectCreationWizard.jsx +++ b/src/components/ProjectCreationWizard.jsx @@ -1,7 +1,6 @@ import React, { useState, useEffect } from 'react'; import { X, FolderPlus, GitBranch, Key, ChevronRight, ChevronLeft, Check, Loader2, AlertCircle, FolderOpen, Eye, EyeOff, Plus } from 'lucide-react'; -import { Button } from './ui/button'; -import { Input } from './ui/input'; +import { Button, Input } from '../shared/view/ui'; import { api } from '../utils/api'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/chat/tools/components/ContentRenderers/TodoList.tsx b/src/components/chat/tools/components/ContentRenderers/TodoList.tsx index 1df49564..ab25cb49 100644 --- a/src/components/chat/tools/components/ContentRenderers/TodoList.tsx +++ b/src/components/chat/tools/components/ContentRenderers/TodoList.tsx @@ -1,6 +1,6 @@ import { memo, useMemo } from 'react'; import { CheckCircle2, Circle, Clock, type LucideIcon } from 'lucide-react'; -import { Badge } from '../../../../ui/badge'; +import { Badge } from '../../../../../shared/view/ui'; type TodoStatus = 'completed' | 'in_progress' | 'pending'; type TodoPriority = 'high' | 'medium' | 'low'; diff --git a/src/components/file-tree/view/FileTreeBody.tsx b/src/components/file-tree/view/FileTreeBody.tsx index 27933541..b1ee90fa 100644 --- a/src/components/file-tree/view/FileTreeBody.tsx +++ b/src/components/file-tree/view/FileTreeBody.tsx @@ -1,6 +1,7 @@ import type { ReactNode, RefObject } from 'react'; import { Folder, Search } from 'lucide-react'; import { useTranslation } from 'react-i18next'; +import { ScrollArea } from '../../../shared/view/ui'; import type { FileTreeNode, FileTreeViewMode } from '../types/types'; import FileTreeEmptyState from './FileTreeEmptyState'; import FileTreeList from './FileTreeList'; diff --git a/src/components/file-tree/view/FileTreeHeader.tsx b/src/components/file-tree/view/FileTreeHeader.tsx index ee72b38a..0d4ff994 100644 --- a/src/components/file-tree/view/FileTreeHeader.tsx +++ b/src/components/file-tree/view/FileTreeHeader.tsx @@ -1,7 +1,6 @@ import { ChevronDown, Eye, FileText, FolderPlus, List, RefreshCw, Search, TableProperties, X } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Button } from '../../ui/button'; -import { Input } from '../../ui/input'; +import { Button, Input } from '../../../shared/view/ui'; import { cn } from '../../../lib/utils'; import type { FileTreeViewMode } from '../types/types'; diff --git a/src/components/file-tree/view/ImageViewer.tsx b/src/components/file-tree/view/ImageViewer.tsx index ce0336c7..e3cf5672 100644 --- a/src/components/file-tree/view/ImageViewer.tsx +++ b/src/components/file-tree/view/ImageViewer.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { X } from 'lucide-react'; -import { Button } from '../../ui/button'; +import { Button } from '../../../shared/view/ui'; import { authenticatedFetch } from '../../../utils/api'; import type { FileTreeImageSelection } from '../types/types'; diff --git a/src/components/settings/view/Settings.tsx b/src/components/settings/view/Settings.tsx index ab861a27..2401dd7b 100644 --- a/src/components/settings/view/Settings.tsx +++ b/src/components/settings/view/Settings.tsx @@ -1,7 +1,7 @@ import { Settings as SettingsIcon, X } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import LoginModal from '../../LoginModal'; -import { Button } from '../../ui/button'; +import { Button } from '../../../shared/view/ui'; import ClaudeMcpFormModal from '../view/modals/ClaudeMcpFormModal'; import CodexMcpFormModal from '../view/modals/CodexMcpFormModal'; import SettingsMainTabs from '../view/SettingsMainTabs'; diff --git a/src/components/settings/view/modals/ClaudeMcpFormModal.tsx b/src/components/settings/view/modals/ClaudeMcpFormModal.tsx index 44e31147..c8d326ee 100644 --- a/src/components/settings/view/modals/ClaudeMcpFormModal.tsx +++ b/src/components/settings/view/modals/ClaudeMcpFormModal.tsx @@ -2,8 +2,7 @@ import { FolderOpen, Globe, X } from 'lucide-react'; import { useEffect, useMemo, useState } from 'react'; import type { FormEvent } from 'react'; import { useTranslation } from 'react-i18next'; -import { Input } from '../../../ui/input'; -import { Button } from '../../../ui/button'; +import { Button, Input } from '../../../../shared/view/ui'; import { DEFAULT_CLAUDE_MCP_FORM } from '../../constants/constants'; import type { ClaudeMcpFormState, McpServer, McpScope, McpTransportType, SettingsProject } from '../../types/types'; diff --git a/src/components/settings/view/modals/CodexMcpFormModal.tsx b/src/components/settings/view/modals/CodexMcpFormModal.tsx index 6e34389a..704c00e1 100644 --- a/src/components/settings/view/modals/CodexMcpFormModal.tsx +++ b/src/components/settings/view/modals/CodexMcpFormModal.tsx @@ -2,8 +2,7 @@ import { useEffect, useState } from 'react'; import type { FormEvent } from 'react'; import { X } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Button } from '../../../ui/button'; -import { Input } from '../../../ui/input'; +import { Button, Input } from '../../../../shared/view/ui'; import { DEFAULT_CODEX_MCP_FORM } from '../../constants/constants'; import type { CodexMcpFormState, McpServer } from '../../types/types'; diff --git a/src/components/settings/view/tabs/agents-settings/sections/content/AccountContent.tsx b/src/components/settings/view/tabs/agents-settings/sections/content/AccountContent.tsx index 535e3729..c29d57e8 100644 --- a/src/components/settings/view/tabs/agents-settings/sections/content/AccountContent.tsx +++ b/src/components/settings/view/tabs/agents-settings/sections/content/AccountContent.tsx @@ -1,7 +1,6 @@ import { LogIn } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Badge } from '../../../../../../ui/badge'; -import { Button } from '../../../../../../ui/button'; +import { Badge, Button } from '../../../../../../../shared/view/ui'; import SessionProviderLogo from '../../../../../../llm-logo-provider/SessionProviderLogo'; import type { AgentProvider, AuthStatus } from '../../../../../types/types'; diff --git a/src/components/settings/view/tabs/agents-settings/sections/content/McpServersContent.tsx b/src/components/settings/view/tabs/agents-settings/sections/content/McpServersContent.tsx index 52ce9ff2..03ca9505 100644 --- a/src/components/settings/view/tabs/agents-settings/sections/content/McpServersContent.tsx +++ b/src/components/settings/view/tabs/agents-settings/sections/content/McpServersContent.tsx @@ -1,7 +1,6 @@ import { Edit3, Globe, Plus, Server, Terminal, Trash2, Zap } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Badge } from '../../../../../../ui/badge'; -import { Button } from '../../../../../../ui/button'; +import { Badge, Button } from '../../../../../../../shared/view/ui'; import type { McpServer, McpToolsResult, McpTestResult } from '../../../../../types/types'; const getTransportIcon = (type: string | undefined) => { diff --git a/src/components/settings/view/tabs/agents-settings/sections/content/PermissionsContent.tsx b/src/components/settings/view/tabs/agents-settings/sections/content/PermissionsContent.tsx index f0cf0729..3f420d5e 100644 --- a/src/components/settings/view/tabs/agents-settings/sections/content/PermissionsContent.tsx +++ b/src/components/settings/view/tabs/agents-settings/sections/content/PermissionsContent.tsx @@ -1,8 +1,7 @@ import { useState } from 'react'; import { AlertTriangle, Plus, Shield, X } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Button } from '../../../../../../ui/button'; -import { Input } from '../../../../../../ui/input'; +import { Button, Input } from '../../../../../../../shared/view/ui'; import type { CodexPermissionMode, GeminiPermissionMode } from '../../../../../types/types'; const COMMON_CLAUDE_TOOLS = [ diff --git a/src/components/settings/view/tabs/api-settings/sections/ApiKeysSection.tsx b/src/components/settings/view/tabs/api-settings/sections/ApiKeysSection.tsx index 200d9c91..ef39616f 100644 --- a/src/components/settings/view/tabs/api-settings/sections/ApiKeysSection.tsx +++ b/src/components/settings/view/tabs/api-settings/sections/ApiKeysSection.tsx @@ -1,7 +1,6 @@ import { ExternalLink, Key, Plus, Trash2 } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Button } from '../../../../../ui/button'; -import { Input } from '../../../../../ui/input'; +import { Button, Input } from '../../../../../../shared/view/ui'; import type { ApiKeyItem } from '../types'; type ApiKeysSectionProps = { diff --git a/src/components/settings/view/tabs/api-settings/sections/GithubCredentialsSection.tsx b/src/components/settings/view/tabs/api-settings/sections/GithubCredentialsSection.tsx index 3e9f5d71..19d6a257 100644 --- a/src/components/settings/view/tabs/api-settings/sections/GithubCredentialsSection.tsx +++ b/src/components/settings/view/tabs/api-settings/sections/GithubCredentialsSection.tsx @@ -1,7 +1,6 @@ import { Eye, EyeOff, Github, Plus, Trash2 } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Button } from '../../../../../ui/button'; -import { Input } from '../../../../../ui/input'; +import { Button, Input } from '../../../../../../shared/view/ui'; import type { GithubCredentialItem } from '../types'; type GithubCredentialsSectionProps = { diff --git a/src/components/settings/view/tabs/api-settings/sections/NewApiKeyAlert.tsx b/src/components/settings/view/tabs/api-settings/sections/NewApiKeyAlert.tsx index 9d78746d..64369eec 100644 --- a/src/components/settings/view/tabs/api-settings/sections/NewApiKeyAlert.tsx +++ b/src/components/settings/view/tabs/api-settings/sections/NewApiKeyAlert.tsx @@ -1,6 +1,6 @@ import { Check, Copy } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Button } from '../../../../../ui/button'; +import { Button } from '../../../../../../shared/view/ui'; import type { CreatedApiKey } from '../types'; type NewApiKeyAlertProps = { diff --git a/src/components/settings/view/tabs/git-settings/GitSettingsTab.tsx b/src/components/settings/view/tabs/git-settings/GitSettingsTab.tsx index 84f633af..adfc3fe2 100644 --- a/src/components/settings/view/tabs/git-settings/GitSettingsTab.tsx +++ b/src/components/settings/view/tabs/git-settings/GitSettingsTab.tsx @@ -1,8 +1,7 @@ import { Check, GitBranch } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { useGitSettings } from '../../../hooks/useGitSettings'; -import { Button } from '../../../../ui/button'; -import { Input } from '../../../../ui/input'; +import { Button, Input } from '../../../../../shared/view/ui'; export default function GitSettingsTab() { const { t } = useTranslation('settings'); diff --git a/src/components/sidebar/view/subcomponents/SidebarContent.tsx b/src/components/sidebar/view/subcomponents/SidebarContent.tsx index ffafb2de..42fcfab1 100644 --- a/src/components/sidebar/view/subcomponents/SidebarContent.tsx +++ b/src/components/sidebar/view/subcomponents/SidebarContent.tsx @@ -1,4 +1,4 @@ -import { ScrollArea } from '../../../ui/scroll-area'; +import { ScrollArea } from '../../../../shared/view/ui'; import type { TFunction } from 'i18next'; import type { Project } from '../../../../types/app'; import type { ReleaseInfo } from '../../../../types/sharedTypes'; diff --git a/src/components/sidebar/view/subcomponents/SidebarHeader.tsx b/src/components/sidebar/view/subcomponents/SidebarHeader.tsx index e79700f7..0e30c20e 100644 --- a/src/components/sidebar/view/subcomponents/SidebarHeader.tsx +++ b/src/components/sidebar/view/subcomponents/SidebarHeader.tsx @@ -1,7 +1,6 @@ import { FolderPlus, Plus, RefreshCw, Search, X, PanelLeftClose } from 'lucide-react'; import type { TFunction } from 'i18next'; -import { Button } from '../../../ui/button'; -import { Input } from '../../../ui/input'; +import { Button, Input } from '../../../../shared/view/ui'; import { IS_PLATFORM } from '../../../../constants/config'; type SidebarHeaderProps = { diff --git a/src/components/sidebar/view/subcomponents/SidebarModals.tsx b/src/components/sidebar/view/subcomponents/SidebarModals.tsx index a102878d..ec60f133 100644 --- a/src/components/sidebar/view/subcomponents/SidebarModals.tsx +++ b/src/components/sidebar/view/subcomponents/SidebarModals.tsx @@ -2,7 +2,7 @@ import { useMemo } from 'react'; import ReactDOM from 'react-dom'; import { AlertTriangle, Trash2 } from 'lucide-react'; import type { TFunction } from 'i18next'; -import { Button } from '../../../ui/button'; +import { Button } from '../../../../shared/view/ui'; import ProjectCreationWizard from '../../../ProjectCreationWizard'; import Settings from '../../../settings/view/Settings'; import VersionUpgradeModal from '../modals/VersionUpgradeModal'; diff --git a/src/components/sidebar/view/subcomponents/SidebarProjectItem.tsx b/src/components/sidebar/view/subcomponents/SidebarProjectItem.tsx index 7b77aa6a..94dc7919 100644 --- a/src/components/sidebar/view/subcomponents/SidebarProjectItem.tsx +++ b/src/components/sidebar/view/subcomponents/SidebarProjectItem.tsx @@ -1,4 +1,4 @@ -import { Button } from '../../../ui/button'; +import { Button } from '../../../../shared/view/ui'; import { Check, ChevronDown, ChevronRight, Edit3, Folder, FolderOpen, Star, Trash2, X } from 'lucide-react'; import type { TFunction } from 'i18next'; import { cn } from '../../../../lib/utils'; diff --git a/src/components/sidebar/view/subcomponents/SidebarProjectSessions.tsx b/src/components/sidebar/view/subcomponents/SidebarProjectSessions.tsx index c16734f3..3249e862 100644 --- a/src/components/sidebar/view/subcomponents/SidebarProjectSessions.tsx +++ b/src/components/sidebar/view/subcomponents/SidebarProjectSessions.tsx @@ -1,6 +1,6 @@ import { ChevronDown, Plus } from 'lucide-react'; import type { TFunction } from 'i18next'; -import { Button } from '../../../ui/button'; +import { Button } from '../../../../shared/view/ui'; import type { Project, ProjectSession, SessionProvider } from '../../../../types/app'; import type { SessionWithProvider, TouchHandlerFactory } from '../../types/types'; import SidebarSessionItem from './SidebarSessionItem'; diff --git a/src/components/sidebar/view/subcomponents/SidebarSessionItem.tsx b/src/components/sidebar/view/subcomponents/SidebarSessionItem.tsx index 3e2ff7c4..30008d51 100644 --- a/src/components/sidebar/view/subcomponents/SidebarSessionItem.tsx +++ b/src/components/sidebar/view/subcomponents/SidebarSessionItem.tsx @@ -1,5 +1,4 @@ -import { Badge } from '../../../ui/badge'; -import { Button } from '../../../ui/button'; +import { Badge, Button } from '../../../../shared/view/ui'; import { Check, Clock, Edit2, Trash2, X } from 'lucide-react'; import type { TFunction } from 'i18next'; import { cn } from '../../../../lib/utils'; diff --git a/src/components/ui/badge.tsx b/src/shared/view/ui/badge/Badge.tsx similarity index 85% rename from src/components/ui/badge.tsx rename to src/shared/view/ui/badge/Badge.tsx index d25e38f3..b1932387 100644 --- a/src/components/ui/badge.tsx +++ b/src/shared/view/ui/badge/Badge.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { cva, type VariantProps } from 'class-variance-authority'; -import { cn } from '../../lib/utils'; +import { cn } from '../../../../lib/utils'; const badgeVariants = cva( 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', @@ -17,12 +17,10 @@ const badgeVariants = cva( defaultVariants: { variant: 'default', }, - }, + } ); -export interface BadgeProps - extends React.HTMLAttributes, - VariantProps {} +type BadgeProps = React.HTMLAttributes & VariantProps; function Badge({ className, variant, ...props }: BadgeProps) { return
; diff --git a/src/shared/view/ui/badge/index.ts b/src/shared/view/ui/badge/index.ts new file mode 100644 index 00000000..391bdd44 --- /dev/null +++ b/src/shared/view/ui/badge/index.ts @@ -0,0 +1 @@ +export { Badge, badgeVariants } from './Badge'; diff --git a/src/components/ui/button.tsx b/src/shared/view/ui/button/Button.tsx similarity index 81% rename from src/components/ui/button.tsx rename to src/shared/view/ui/button/Button.tsx index e07c1773..9874c3ac 100644 --- a/src/components/ui/button.tsx +++ b/src/shared/view/ui/button/Button.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; import { cva, type VariantProps } from 'class-variance-authority'; -import { cn } from '../../lib/utils'; +import { cn } from '../../../../lib/utils'; +// Keep visual variants centralized so all button usages stay consistent. const buttonVariants = cva( 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', { @@ -27,24 +28,20 @@ const buttonVariants = cva( variant: 'default', size: 'default', }, - }, + } ); -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps {} +type ButtonProps = React.ButtonHTMLAttributes & + VariantProps; const Button = React.forwardRef( ({ className, variant, size, ...props }, ref) => { return ( -