feat(ui): improve theme consistency and add diff panel shortcut
This commit is contained in:
Generated
+1
-1
@@ -2847,7 +2847,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openchamber-desktop"
|
name = "openchamber-desktop"
|
||||||
version = "1.2.5"
|
version = "1.2.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export const AgentMentionAutocomplete = React.forwardRef<AgentMentionAutocomplet
|
|||||||
key={agent.name}
|
key={agent.name}
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex items-start gap-2 px-3 py-1.5 cursor-pointer rounded-lg typography-ui-label',
|
'flex items-start gap-2 px-3 py-1.5 cursor-pointer rounded-lg typography-ui-label',
|
||||||
index === selectedIndex && 'bg-accent'
|
index === selectedIndex && 'bg-muted'
|
||||||
)}
|
)}
|
||||||
onClick={() => onAgentSelect(agent.name)}
|
onClick={() => onAgentSelect(agent.name)}
|
||||||
onMouseEnter={() => setSelectedIndex(index)}
|
onMouseEnter={() => setSelectedIndex(index)}
|
||||||
@@ -130,7 +130,7 @@ export const AgentMentionAutocomplete = React.forwardRef<AgentMentionAutocomplet
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className="absolute z-[100] min-w-0 w-full max-w-[360px] max-h-60 bg-popover border border-border rounded-xl shadow-none bottom-full mb-2 left-0 flex flex-col"
|
className="absolute z-[100] min-w-0 w-full max-w-[360px] max-h-60 bg-background border border-border rounded-xl shadow-none bottom-full mb-2 left-0 flex flex-col"
|
||||||
>
|
>
|
||||||
<ScrollableOverlay outerClassName="flex-1 min-h-0" className="px-0">
|
<ScrollableOverlay outerClassName="flex-1 min-h-0" className="px-0">
|
||||||
{agents.length ? (
|
{agents.length ? (
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className="absolute z-[100] min-w-0 w-full max-w-[450px] max-h-64 bg-popover border border-border rounded-xl shadow-none bottom-full mb-2 left-0 flex flex-col"
|
className="absolute z-[100] min-w-0 w-full max-w-[450px] max-h-64 bg-background border border-border rounded-xl shadow-none bottom-full mb-2 left-0 flex flex-col"
|
||||||
>
|
>
|
||||||
<ScrollableOverlay outerClassName="flex-1 min-h-0" className="px-0">
|
<ScrollableOverlay outerClassName="flex-1 min-h-0" className="px-0">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@@ -216,7 +216,7 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
|
|||||||
ref={(el) => { itemRefs.current[index] = el; }}
|
ref={(el) => { itemRefs.current[index] = el; }}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex items-start gap-2 px-3 py-2 cursor-pointer rounded-lg",
|
"flex items-start gap-2 px-3 py-2 cursor-pointer rounded-lg",
|
||||||
index === selectedIndex && "bg-accent"
|
index === selectedIndex && "bg-muted"
|
||||||
)}
|
)}
|
||||||
onClick={() => onCommandSelect(command)}
|
onClick={() => onCommandSelect(command)}
|
||||||
onMouseEnter={() => setSelectedIndex(index)}
|
onMouseEnter={() => setSelectedIndex(index)}
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ export const FileMentionAutocomplete = React.forwardRef<FileMentionHandle, FileM
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className="absolute z-[100] min-w-0 w-full max-w-[520px] max-h-64 bg-popover border border-border rounded-xl shadow-none bottom-full mb-2 left-0 flex flex-col"
|
className="absolute z-[100] min-w-0 w-full max-w-[520px] max-h-64 bg-background border border-border rounded-xl shadow-none bottom-full mb-2 left-0 flex flex-col"
|
||||||
>
|
>
|
||||||
<ScrollableOverlay outerClassName="flex-1 min-h-0" className="px-0">
|
<ScrollableOverlay outerClassName="flex-1 min-h-0" className="px-0">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@@ -255,7 +255,7 @@ export const FileMentionAutocomplete = React.forwardRef<FileMentionHandle, FileM
|
|||||||
ref={(el) => { itemRefs.current[index] = el; }}
|
ref={(el) => { itemRefs.current[index] = el; }}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex items-center gap-2 px-3 py-1.5 cursor-pointer typography-ui-label rounded-lg",
|
"flex items-center gap-2 px-3 py-1.5 cursor-pointer typography-ui-label rounded-lg",
|
||||||
isSelected && "bg-accent"
|
isSelected && "bg-muted"
|
||||||
)}
|
)}
|
||||||
onClick={() => handleFileSelect(file)}
|
onClick={() => handleFileSelect(file)}
|
||||||
onMouseEnter={() => setSelectedIndex(index)}
|
onMouseEnter={() => setSelectedIndex(index)}
|
||||||
|
|||||||
@@ -1180,7 +1180,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({ className }) => {
|
|||||||
className={cn(
|
className={cn(
|
||||||
'flex w-full items-start gap-2 border-b border-border/30 px-2 py-1.5 text-left last:border-b-0',
|
'flex w-full items-start gap-2 border-b border-border/30 px-2 py-1.5 text-left last:border-b-0',
|
||||||
'focus:outline-none focus-visible:ring-1 focus-visible:ring-primary',
|
'focus:outline-none focus-visible:ring-1 focus-visible:ring-primary',
|
||||||
isSelected ? 'bg-primary/15 text-primary' : 'hover:bg-accent/40'
|
isSelected ? 'bg-primary/15 text-primary' : 'hover:bg-muted'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2 min-w-0">
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
@@ -1225,7 +1225,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({ className }) => {
|
|||||||
className={cn(
|
className={cn(
|
||||||
'flex w-full items-start gap-2 border-b border-border/30 px-2 py-1.5 text-left last:border-b-0',
|
'flex w-full items-start gap-2 border-b border-border/30 px-2 py-1.5 text-left last:border-b-0',
|
||||||
'focus:outline-none focus-visible:ring-1 focus-visible:ring-primary',
|
'focus:outline-none focus-visible:ring-1 focus-visible:ring-primary',
|
||||||
isSelected ? 'bg-primary/15 text-primary' : 'hover:bg-accent/40'
|
isSelected ? 'bg-primary/15 text-primary' : 'hover:bg-muted'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2 min-w-0">
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
@@ -1309,7 +1309,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({ className }) => {
|
|||||||
className={cn(
|
className={cn(
|
||||||
'flex flex-1 min-w-0 items-start gap-2 text-left',
|
'flex flex-1 min-w-0 items-start gap-2 text-left',
|
||||||
'focus:outline-none focus-visible:ring-1 focus-visible:ring-primary',
|
'focus:outline-none focus-visible:ring-1 focus-visible:ring-primary',
|
||||||
!isSelected && 'hover:bg-accent/40'
|
!isSelected && 'hover:bg-muted'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex min-w-0 flex-col">
|
<div className="flex min-w-0 flex-col">
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ export const ServerFilePicker: React.FC<ServerFilePickerProps> = ({
|
|||||||
const row = (
|
const row = (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex w-full items-center justify-start gap-1 px-2 py-1.5 rounded hover:bg-accent cursor-pointer typography-ui-label text-foreground text-left",
|
"flex w-full items-center justify-start gap-1 px-2 py-1.5 rounded hover:bg-muted cursor-pointer typography-ui-label text-foreground text-left",
|
||||||
file.type === 'file' && selectedFiles.has(file.path) && "bg-primary/10"
|
file.type === 'file' && selectedFiles.has(file.path) && "bg-primary/10"
|
||||||
)}
|
)}
|
||||||
style={{ paddingLeft: `${level * 12}px` }}
|
style={{ paddingLeft: `${level * 12}px` }}
|
||||||
@@ -494,7 +494,7 @@ export const ServerFilePicker: React.FC<ServerFilePickerProps> = ({
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setSearchQuery('');
|
setSearchQuery('');
|
||||||
}}
|
}}
|
||||||
className="absolute right-2 top-1/2 -translate-y-1/2 p-0.5 hover:bg-accent rounded"
|
className="absolute right-2 top-1/2 -translate-y-1/2 p-0.5 hover:bg-muted rounded"
|
||||||
>
|
>
|
||||||
<RiCloseLine className="h-3 w-3"/>
|
<RiCloseLine className="h-3 w-3"/>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@/components/ui/tooltip';
|
} from '@/components/ui/tooltip';
|
||||||
|
|
||||||
import { RiChat4Line, RiCodeLine, RiGitBranchLine, RiLayoutLeftLine, RiPlayListAddLine, RiSettings3Line, RiTerminalBoxLine, type RemixiconComponentType } from '@remixicon/react';
|
import { RiChat4Line, RiCodeLine, RiCommandLine, RiGitBranchLine, RiLayoutLeftLine, RiPlayListAddLine, RiQuestionLine, RiSettings3Line, RiTerminalBoxLine, type RemixiconComponentType } from '@remixicon/react';
|
||||||
import { useUIStore, type MainTab } from '@/stores/useUIStore';
|
import { useUIStore, type MainTab } from '@/stores/useUIStore';
|
||||||
import { useConfigStore } from '@/stores/useConfigStore';
|
import { useConfigStore } from '@/stores/useConfigStore';
|
||||||
import { useSessionStore } from '@/stores/useSessionStore';
|
import { useSessionStore } from '@/stores/useSessionStore';
|
||||||
@@ -83,6 +83,8 @@ export const Header: React.FC = () => {
|
|||||||
const setSessionSwitcherOpen = useUIStore((state) => state.setSessionSwitcherOpen);
|
const setSessionSwitcherOpen = useUIStore((state) => state.setSessionSwitcherOpen);
|
||||||
const toggleSidebar = useUIStore((state) => state.toggleSidebar);
|
const toggleSidebar = useUIStore((state) => state.toggleSidebar);
|
||||||
const setSettingsDialogOpen = useUIStore((state) => state.setSettingsDialogOpen);
|
const setSettingsDialogOpen = useUIStore((state) => state.setSettingsDialogOpen);
|
||||||
|
const toggleCommandPalette = useUIStore((state) => state.toggleCommandPalette);
|
||||||
|
const toggleHelpDialog = useUIStore((state) => state.toggleHelpDialog);
|
||||||
const isSidebarOpen = useUIStore((state) => state.isSidebarOpen);
|
const isSidebarOpen = useUIStore((state) => state.isSidebarOpen);
|
||||||
const sidebarWidth = useUIStore((state) => state.sidebarWidth);
|
const sidebarWidth = useUIStore((state) => state.sidebarWidth);
|
||||||
const activeMainTab = useUIStore((state) => state.activeMainTab);
|
const activeMainTab = useUIStore((state) => state.activeMainTab);
|
||||||
@@ -384,6 +386,40 @@ export const Header: React.FC = () => {
|
|||||||
|
|
||||||
{}
|
{}
|
||||||
<div className="flex-1" />
|
<div className="flex-1" />
|
||||||
|
|
||||||
|
{}
|
||||||
|
<div className="flex items-center gap-1 pr-3">
|
||||||
|
<Tooltip delayDuration={500}>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={toggleCommandPalette}
|
||||||
|
aria-label="Open command palette"
|
||||||
|
className={headerIconButtonClass}
|
||||||
|
>
|
||||||
|
<RiCommandLine className="h-5 w-5" />
|
||||||
|
</button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>Command Palette (Ctrl+X)</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip delayDuration={500}>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={toggleHelpDialog}
|
||||||
|
aria-label="Keyboard shortcuts"
|
||||||
|
className={headerIconButtonClass}
|
||||||
|
>
|
||||||
|
<RiQuestionLine className="h-5 w-5" />
|
||||||
|
</button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>Keyboard Shortcuts (Ctrl+H)</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
|||||||
import { useConfigStore } from '@/stores/useConfigStore';
|
import { useConfigStore } from '@/stores/useConfigStore';
|
||||||
import { useThemeSystem } from '@/contexts/useThemeSystem';
|
import { useThemeSystem } from '@/contexts/useThemeSystem';
|
||||||
import { useDeviceInfo } from '@/lib/device';
|
import { useDeviceInfo } from '@/lib/device';
|
||||||
import { RiAddLine, RiChatAi3Line, RiCheckLine, RiComputerLine, RiGitBranchLine, RiLayoutLeftLine, RiMoonLine, RiQuestionLine, RiRestartLine, RiSettings3Line, RiSunLine, RiTerminalBoxLine } from '@remixicon/react';
|
import { RiAddLine, RiChatAi3Line, RiCheckLine, RiCodeLine, RiComputerLine, RiGitBranchLine, RiLayoutLeftLine, RiMoonLine, RiQuestionLine, RiRestartLine, RiSettings3Line, RiSunLine, RiTerminalBoxLine } from '@remixicon/react';
|
||||||
import { reloadOpenCodeConfiguration } from '@/stores/useAgentsStore';
|
import { reloadOpenCodeConfiguration } from '@/stores/useAgentsStore';
|
||||||
|
|
||||||
export const CommandPalette: React.FC = () => {
|
export const CommandPalette: React.FC = () => {
|
||||||
@@ -85,6 +85,11 @@ export const CommandPalette: React.FC = () => {
|
|||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleOpenDiffPanel = () => {
|
||||||
|
setActiveMainTab('diff');
|
||||||
|
handleClose();
|
||||||
|
};
|
||||||
|
|
||||||
const handleOpenGitPanel = () => {
|
const handleOpenGitPanel = () => {
|
||||||
setActiveMainTab('git');
|
setActiveMainTab('git');
|
||||||
handleClose();
|
handleClose();
|
||||||
@@ -137,6 +142,11 @@ export const CommandPalette: React.FC = () => {
|
|||||||
<span>Keyboard Shortcuts</span>
|
<span>Keyboard Shortcuts</span>
|
||||||
<CommandShortcut>Ctrl + H</CommandShortcut>
|
<CommandShortcut>Ctrl + H</CommandShortcut>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
|
<CommandItem onSelect={handleOpenDiffPanel}>
|
||||||
|
<RiCodeLine className="mr-2 h-4 w-4" />
|
||||||
|
<span>Open Diff Panel</span>
|
||||||
|
<CommandShortcut>Ctrl + E</CommandShortcut>
|
||||||
|
</CommandItem>
|
||||||
<CommandItem onSelect={handleOpenGitPanel}>
|
<CommandItem onSelect={handleOpenGitPanel}>
|
||||||
<RiGitBranchLine className="mr-2 h-4 w-4" />
|
<RiGitBranchLine className="mr-2 h-4 w-4" />
|
||||||
<span>Open Git Panel</span>
|
<span>Open Git Panel</span>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from '@/components/ui/dialog';
|
} from '@/components/ui/dialog';
|
||||||
import { useUIStore } from '@/stores/useUIStore';
|
import { useUIStore } from '@/stores/useUIStore';
|
||||||
import { RiAddLine, RiArrowUpSLine, RiArrowUpWideLine, RiCloseCircleLine, RiCommandLine, RiGitBranchLine, RiLayoutLeftLine, RiPaletteLine, RiQuestionLine, RiSettings3Line, RiTerminalBoxLine, RiText } from '@remixicon/react';
|
import { RiAddLine, RiArrowUpSLine, RiArrowUpWideLine, RiCloseCircleLine, RiCodeLine, RiCommandLine, RiGitBranchLine, RiLayoutLeftLine, RiPaletteLine, RiQuestionLine, RiSettings3Line, RiTerminalBoxLine, RiText } from '@remixicon/react';
|
||||||
|
|
||||||
const renderKeyToken = (token: string, index: number) => {
|
const renderKeyToken = (token: string, index: number) => {
|
||||||
const normalized = token.trim().toLowerCase();
|
const normalized = token.trim().toLowerCase();
|
||||||
@@ -70,7 +70,7 @@ export const HelpDialog: React.FC = () => {
|
|||||||
category: "Session Management",
|
category: "Session Management",
|
||||||
items: [
|
items: [
|
||||||
{ keys: ["Ctrl + N"], description: "Create New Session", icon: RiAddLine },
|
{ keys: ["Ctrl + N"], description: "Create New Session", icon: RiAddLine },
|
||||||
{ keys: ["Shift + Ctrl + N"], description: "Open Session Creator (worktree support)", icon: RiGitBranchLine },
|
{ keys: ["Shift + Ctrl + N"], description: "Open Worktree Creator", icon: RiGitBranchLine },
|
||||||
{ keys: ["Ctrl + I"], description: "Focus Chat Input", icon: RiText },
|
{ keys: ["Ctrl + I"], description: "Focus Chat Input", icon: RiText },
|
||||||
{ keys: ["Esc + Esc"], description: "Abort active run (double press)", icon: RiCloseCircleLine },
|
{ keys: ["Esc + Esc"], description: "Abort active run (double press)", icon: RiCloseCircleLine },
|
||||||
]
|
]
|
||||||
@@ -79,6 +79,7 @@ export const HelpDialog: React.FC = () => {
|
|||||||
category: "Interface",
|
category: "Interface",
|
||||||
items: [
|
items: [
|
||||||
{ keys: ["⌘ + /", "Ctrl + /"], description: "Cycle Theme (Light → Dark → System)", icon: RiPaletteLine },
|
{ keys: ["⌘ + /", "Ctrl + /"], description: "Cycle Theme (Light → Dark → System)", icon: RiPaletteLine },
|
||||||
|
{ keys: ["Ctrl + E"], description: "Open Diff Panel", icon: RiCodeLine },
|
||||||
{ keys: ["Ctrl + G"], description: "Open Git Panel", icon: RiGitBranchLine },
|
{ keys: ["Ctrl + G"], description: "Open Git Panel", icon: RiGitBranchLine },
|
||||||
{ keys: ["Ctrl + T"], description: "Open Terminal", icon: RiTerminalBoxLine },
|
{ keys: ["Ctrl + T"], description: "Open Terminal", icon: RiTerminalBoxLine },
|
||||||
{ keys: ["Ctrl + ,"], description: "Open Settings", icon: RiSettings3Line },
|
{ keys: ["Ctrl + ,"], description: "Open Settings", icon: RiSettings3Line },
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function Command({
|
|||||||
<CommandPrimitive
|
<CommandPrimitive
|
||||||
data-slot="command"
|
data-slot="command"
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-xl",
|
"bg-background text-foreground flex h-full w-full flex-col overflow-hidden rounded-xl",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -154,7 +154,7 @@ function CommandItem({
|
|||||||
<CommandPrimitive.Item
|
<CommandPrimitive.Item
|
||||||
data-slot="command-item"
|
data-slot="command-item"
|
||||||
className={cn(
|
className={cn(
|
||||||
"hover:bg-accent hover:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-lg px-2 py-1.5 typography-meta outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
"data-[selected=true]:bg-muted hover:bg-muted [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-lg px-2 py-1.5 typography-meta outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ function DropdownMenuContent({
|
|||||||
data-slot="dropdown-menu-content"
|
data-slot="dropdown-menu-content"
|
||||||
sideOffset={sideOffset}
|
sideOffset={sideOffset}
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-popover text-popover-foreground 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 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-visible rounded-xl border p-1 shadow-none",
|
"bg-background text-foreground 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 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-visible rounded-xl border p-1 shadow-none",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -72,7 +72,7 @@ function DropdownMenuItem({
|
|||||||
data-inset={inset}
|
data-inset={inset}
|
||||||
data-variant={variant}
|
data-variant={variant}
|
||||||
className={cn(
|
className={cn(
|
||||||
"hover:bg-accent hover:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:hover:bg-destructive/10 dark:data-[variant=destructive]:hover:bg-destructive/20 data-[variant=destructive]:hover:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-lg px-2 py-1 typography-ui-label outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
"hover:bg-muted data-[variant=destructive]:text-destructive data-[variant=destructive]:hover:bg-destructive/10 dark:data-[variant=destructive]:hover:bg-destructive/20 data-[variant=destructive]:hover:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-lg px-2 py-1 typography-ui-label outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -90,7 +90,7 @@ function DropdownMenuCheckboxItem({
|
|||||||
<DropdownMenuPrimitive.CheckboxItem
|
<DropdownMenuPrimitive.CheckboxItem
|
||||||
data-slot="dropdown-menu-checkbox-item"
|
data-slot="dropdown-menu-checkbox-item"
|
||||||
className={cn(
|
className={cn(
|
||||||
"hover:bg-accent hover:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-lg py-1 px-2 typography-ui-label outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
"hover:bg-muted relative flex cursor-default items-center gap-2 rounded-lg py-1 px-2 typography-ui-label outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
checked={checked}
|
checked={checked}
|
||||||
@@ -126,7 +126,7 @@ function DropdownMenuRadioItem({
|
|||||||
<DropdownMenuPrimitive.RadioItem
|
<DropdownMenuPrimitive.RadioItem
|
||||||
data-slot="dropdown-menu-radio-item"
|
data-slot="dropdown-menu-radio-item"
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex cursor-default items-start gap-2 rounded-lg py-1 pl-2 pr-8 typography-ui-label outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-accent hover:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
"relative flex cursor-default items-start gap-2 rounded-lg py-1 pl-2 pr-8 typography-ui-label outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-muted [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -209,7 +209,7 @@ function DropdownMenuSubTrigger({
|
|||||||
data-slot="dropdown-menu-sub-trigger"
|
data-slot="dropdown-menu-sub-trigger"
|
||||||
data-inset={inset}
|
data-inset={inset}
|
||||||
className={cn(
|
className={cn(
|
||||||
"hover:bg-accent hover:text-accent-foreground flex cursor-default items-center rounded-lg px-2 py-1 typography-ui-label outline-hidden select-none data-[inset]:pl-8",
|
"hover:bg-muted flex cursor-default items-center rounded-lg px-2 py-1 typography-ui-label outline-hidden select-none data-[inset]:pl-8",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -228,7 +228,7 @@ function DropdownMenuSubContent({
|
|||||||
<DropdownMenuPrimitive.SubContent
|
<DropdownMenuPrimitive.SubContent
|
||||||
data-slot="dropdown-menu-sub-content"
|
data-slot="dropdown-menu-sub-content"
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-popover text-popover-foreground 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 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-visible rounded-xl border p-1 shadow-none",
|
"bg-background text-foreground 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 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-visible rounded-xl border p-1 shadow-none",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ function SelectTrigger({
|
|||||||
data-slot="select-trigger"
|
data-slot="select-trigger"
|
||||||
data-size={size}
|
data-size={size}
|
||||||
className={cn(
|
className={cn(
|
||||||
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-lg border bg-transparent px-2 py-2 typography-ui-label whitespace-nowrap shadow-none outline-none focus-visible:outline-none hover:bg-accent hover:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-6 data-[size=sm]:h-6 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-lg border bg-transparent px-2 py-2 typography-ui-label whitespace-nowrap shadow-none outline-none focus-visible:outline-none hover:bg-muted data-[state=open]:bg-muted focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-6 data-[size=sm]:h-6 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -62,7 +62,7 @@ function SelectContent({
|
|||||||
<SelectPrimitive.Content
|
<SelectPrimitive.Content
|
||||||
data-slot="select-content"
|
data-slot="select-content"
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-popover text-popover-foreground 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-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden rounded-xl border shadow-none transform-gpu will-change-transform",
|
"bg-background text-foreground 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-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden rounded-xl border shadow-none transform-gpu will-change-transform",
|
||||||
position === "popper" &&
|
position === "popper" &&
|
||||||
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
||||||
className
|
className
|
||||||
@@ -110,7 +110,7 @@ function SelectItem({
|
|||||||
<SelectPrimitive.Item
|
<SelectPrimitive.Item
|
||||||
data-slot="select-item"
|
data-slot="select-item"
|
||||||
className={cn(
|
className={cn(
|
||||||
"hover:bg-accent hover:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-lg py-1.5 pr-8 pl-2 typography-ui-label outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
"hover:bg-muted [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-lg py-1.5 pr-8 pl-2 typography-ui-label outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -107,6 +107,13 @@ export const useKeyboardShortcuts = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.ctrlKey && !e.metaKey && !e.shiftKey && e.key.toLowerCase() === 'e') {
|
||||||
|
e.preventDefault();
|
||||||
|
const { activeMainTab } = useUIStore.getState();
|
||||||
|
setActiveMainTab(activeMainTab === 'diff' ? 'chat' : 'diff');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.ctrlKey && !e.metaKey && !e.shiftKey && e.key.toLowerCase() === 't') {
|
if (e.ctrlKey && !e.metaKey && !e.shiftKey && e.key.toLowerCase() === 't') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const { activeMainTab } = useUIStore.getState();
|
const { activeMainTab } = useUIStore.getState();
|
||||||
|
|||||||
Reference in New Issue
Block a user