feat(ui): unify overlay animations and trim tooltip delays
Use base-ui's transition-status pattern (data-starting-style / data-ending-style) for Dialog, DropdownMenu, Select, Tooltip and Popover so open/close animate consistently at 150ms ease-out without flicker. Wrap dialog popups in a centered flex container so the scale animation no longer fights with translate-based positioning, and switch PendingChangesBar to a real Popover so it actually animates closed. Convert ScheduledTaskEditorDialog from raw Radix to the shared Dialog wrapper, give ScheduledTasksDialog a stable min-height to prevent layout shift mid-animation, and reset NewWorktreeDialog form state on open instead of close so fields don't empty during the close transition. Drop tooltip delay from 700ms to 300ms globally and remove all per-component overrides except the model/variant/agent selectors in the chat input (600ms).
This commit is contained in:
@@ -828,7 +828,7 @@ function App({ apis }: AppProps) {
|
|||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<SyncProvider sdk={opencodeClient.getSdkClient()} directory={currentDirectory || ''}>
|
<SyncProvider sdk={opencodeClient.getSdkClient()} directory={currentDirectory || ''}>
|
||||||
<RuntimeAPIProvider apis={apis}>
|
<RuntimeAPIProvider apis={apis}>
|
||||||
<TooltipProvider delayDuration={700} skipDelayDuration={150}>
|
<TooltipProvider delayDuration={300} skipDelayDuration={150}>
|
||||||
<div className="h-full text-foreground bg-background">
|
<div className="h-full text-foreground bg-background">
|
||||||
<EmbeddedSessionSelectionGate embeddedSessionChat={embeddedSessionChat} isVSCodeRuntime={isVSCodeRuntime} />
|
<EmbeddedSessionSelectionGate embeddedSessionChat={embeddedSessionChat} isVSCodeRuntime={isVSCodeRuntime} />
|
||||||
<SyncAppEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
<SyncAppEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
||||||
@@ -873,7 +873,7 @@ function App({ apis }: AppProps) {
|
|||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<SyncProvider sdk={opencodeClient.getSdkClient()} directory={currentDirectory || ''}>
|
<SyncProvider sdk={opencodeClient.getSdkClient()} directory={currentDirectory || ''}>
|
||||||
<RuntimeAPIProvider apis={apis}>
|
<RuntimeAPIProvider apis={apis}>
|
||||||
<TooltipProvider delayDuration={700} skipDelayDuration={150}>
|
<TooltipProvider delayDuration={300} skipDelayDuration={150}>
|
||||||
<div className="h-full text-foreground bg-background">
|
<div className="h-full text-foreground bg-background">
|
||||||
<SyncAppEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
<SyncAppEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
||||||
<AgentManagerView />
|
<AgentManagerView />
|
||||||
@@ -891,7 +891,7 @@ function App({ apis }: AppProps) {
|
|||||||
<SyncProvider sdk={opencodeClient.getSdkClient()} directory={currentDirectory || ''}>
|
<SyncProvider sdk={opencodeClient.getSdkClient()} directory={currentDirectory || ''}>
|
||||||
<RuntimeAPIProvider apis={apis}>
|
<RuntimeAPIProvider apis={apis}>
|
||||||
<FireworksProvider>
|
<FireworksProvider>
|
||||||
<TooltipProvider delayDuration={700} skipDelayDuration={150}>
|
<TooltipProvider delayDuration={300} skipDelayDuration={150}>
|
||||||
<div className="h-full text-foreground bg-background">
|
<div className="h-full text-foreground bg-background">
|
||||||
<SyncAppEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
<SyncAppEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
||||||
<VSCodeLayout />
|
<VSCodeLayout />
|
||||||
@@ -916,7 +916,7 @@ function App({ apis }: AppProps) {
|
|||||||
<RuntimeAPIProvider apis={apis}>
|
<RuntimeAPIProvider apis={apis}>
|
||||||
<FireworksProvider>
|
<FireworksProvider>
|
||||||
<VoiceProvider>
|
<VoiceProvider>
|
||||||
<TooltipProvider delayDuration={700} skipDelayDuration={150}>
|
<TooltipProvider delayDuration={300} skipDelayDuration={150}>
|
||||||
<div className={isDesktopRuntime ? 'h-full text-foreground bg-transparent' : 'h-full text-foreground bg-background'}>
|
<div className={isDesktopRuntime ? 'h-full text-foreground bg-transparent' : 'h-full text-foreground bg-background'}>
|
||||||
<SyncAppEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
<SyncAppEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
||||||
<MainLayout />
|
<MainLayout />
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ const PermissionAutoAcceptButton = React.memo(function PermissionAutoAcceptButto
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={600}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
{button}
|
{button}
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -454,7 +454,7 @@ const FocusModeButton = React.memo(function FocusModeButton(props: FocusModeButt
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={600}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ export const MessageFilesDisplay = memo(({ files, onShowPopup, compact = false }
|
|||||||
const filename = resolveDisplayName(file) || 'Image';
|
const filename = resolveDisplayName(file) || 'Image';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip key={`img-${file.url || file.filename || index}`} delayDuration={1000}>
|
<Tooltip key={`img-${file.url || file.filename || index}`}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -2654,7 +2654,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
|||||||
let currentFlatIndex = 0;
|
let currentFlatIndex = 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip delayDuration={600}>
|
||||||
{!isCompact ? (
|
{!isCompact ? (
|
||||||
<DropdownMenu open={isReady && agentMenuOpen} onOpenChange={isReady ? handleModelMenuOpenChange : undefined}>
|
<DropdownMenu open={isReady && agentMenuOpen} onOpenChange={isReady ? handleModelMenuOpenChange : undefined}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
@@ -3119,7 +3119,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={800}>
|
<Tooltip delayDuration={600}>
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
@@ -3182,7 +3182,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
|||||||
if (!isCompact) {
|
if (!isCompact) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2 min-w-0">
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip delayDuration={600}>
|
||||||
<DropdownMenu open={isReady && isAgentSelectorOpen} onOpenChange={isReady ? setIsAgentSelectorOpen : undefined}>
|
<DropdownMenu open={isReady && isAgentSelectorOpen} onOpenChange={isReady ? setIsAgentSelectorOpen : undefined}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Popover } from '@base-ui/react/popover';
|
||||||
import { RiFileEditLine, RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/react';
|
import { RiFileEditLine, RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/react';
|
||||||
import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
||||||
import { useGitStore, useIsGitRepo } from '@/stores/useGitStore';
|
import { useGitStore, useIsGitRepo } from '@/stores/useGitStore';
|
||||||
@@ -27,7 +28,6 @@ export const PendingChangesBar: React.FC = React.memo(() => {
|
|||||||
);
|
);
|
||||||
const ensureStatus = useGitStore((s) => s.ensureStatus);
|
const ensureStatus = useGitStore((s) => s.ensureStatus);
|
||||||
const fetchStatus = useGitStore((s) => s.fetchStatus);
|
const fetchStatus = useGitStore((s) => s.fetchStatus);
|
||||||
const popoverRef = React.useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
// Seed git store for currentDirectory so the bar can render independently of
|
// Seed git store for currentDirectory so the bar can render independently of
|
||||||
// DiffView/GitView/right-sidebar mounting. ensureStatus has a 5s staleness
|
// DiffView/GitView/right-sidebar mounting. ensureStatus has a 5s staleness
|
||||||
@@ -64,19 +64,6 @@ export const PendingChangesBar: React.FC = React.memo(() => {
|
|||||||
return { totalAdded: added, totalRemoved: removed };
|
return { totalAdded: added, totalRemoved: removed };
|
||||||
}, [gitChangedFiles]);
|
}, [gitChangedFiles]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!isExpanded) return;
|
|
||||||
|
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
|
||||||
if (popoverRef.current && !popoverRef.current.contains(event.target as Node)) {
|
|
||||||
setIsExpanded(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('mousedown', handleClickOutside);
|
|
||||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
||||||
}, [isExpanded]);
|
|
||||||
|
|
||||||
if (isGitRepo !== true) return null;
|
if (isGitRepo !== true) return null;
|
||||||
if (gitChangedFiles.length === 0) return null;
|
if (gitChangedFiles.length === 0) return null;
|
||||||
|
|
||||||
@@ -109,41 +96,45 @@ export const PendingChangesBar: React.FC = React.memo(() => {
|
|||||||
: t('chat.pendingChanges.fileCountPlural', { count: fileCount });
|
: t('chat.pendingChanges.fileCountPlural', { count: fileCount });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex min-w-0 items-center" ref={popoverRef}>
|
<Popover.Root open={isExpanded} onOpenChange={setIsExpanded}>
|
||||||
<button
|
<Popover.Trigger
|
||||||
type="button"
|
render={
|
||||||
onClick={() => setIsExpanded((prev) => !prev)}
|
<button
|
||||||
className="flex min-w-0 max-w-full items-center gap-1 text-left text-muted-foreground"
|
type="button"
|
||||||
>
|
className="flex min-w-0 max-w-full items-center gap-1 text-left text-muted-foreground"
|
||||||
<RiFileEditLine className="h-3.5 w-3.5 flex-shrink-0 text-[var(--status-warning)]" />
|
>
|
||||||
<span className="min-w-0 typography-ui-label text-foreground flex-shrink-0">{labelHead}</span>
|
<RiFileEditLine className="h-3.5 w-3.5 flex-shrink-0 text-[var(--status-warning)]" />
|
||||||
<span className="status-row__changed-label min-w-0 typography-ui-label text-foreground truncate">
|
<span className="min-w-0 typography-ui-label text-foreground flex-shrink-0">{labelHead}</span>
|
||||||
{t('chat.pendingChanges.changedInWorkspace')}
|
<span className="status-row__changed-label min-w-0 typography-ui-label text-foreground truncate">
|
||||||
</span>
|
{t('chat.pendingChanges.changedInWorkspace')}
|
||||||
<span className="text-[0.75rem] tabular-nums inline-flex items-baseline gap-1 flex-shrink-0">
|
</span>
|
||||||
{totalAdded > 0 ? <span style={{ color: 'var(--status-success)' }}>+{totalAdded}</span> : null}
|
<span className="text-[0.75rem] tabular-nums inline-flex items-baseline gap-1 flex-shrink-0">
|
||||||
{totalRemoved > 0 ? <span style={{ color: 'var(--status-error)' }}>-{totalRemoved}</span> : null}
|
{totalAdded > 0 ? <span style={{ color: 'var(--status-success)' }}>+{totalAdded}</span> : null}
|
||||||
</span>
|
{totalRemoved > 0 ? <span style={{ color: 'var(--status-error)' }}>-{totalRemoved}</span> : null}
|
||||||
{isExpanded ? (
|
</span>
|
||||||
<RiArrowUpSLine className="h-3.5 w-3.5 flex-shrink-0" />
|
{isExpanded ? (
|
||||||
) : (
|
<RiArrowUpSLine className="h-3.5 w-3.5 flex-shrink-0" />
|
||||||
<RiArrowDownSLine className="h-3.5 w-3.5 flex-shrink-0" />
|
) : (
|
||||||
)}
|
<RiArrowDownSLine className="h-3.5 w-3.5 flex-shrink-0" />
|
||||||
</button>
|
)}
|
||||||
|
</button>
|
||||||
{isExpanded ? (
|
}
|
||||||
<div
|
/>
|
||||||
style={changedFilesPopoverStyle}
|
<Popover.Portal>
|
||||||
className={`${changedFilesPopoverClassName} absolute z-50 left-0 bottom-full mb-1 slide-in-from-bottom-2`}
|
<Popover.Positioner side="top" align="start" sideOffset={4} collisionPadding={8}>
|
||||||
>
|
<Popover.Popup
|
||||||
<ChangedFilesList
|
style={changedFilesPopoverStyle}
|
||||||
files={gitChangedFiles}
|
className={`${changedFilesPopoverClassName} transition-all duration-150 ease-out data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95`}
|
||||||
currentDirectory={currentDirectory}
|
>
|
||||||
onOpenFile={handleOpenFile}
|
<ChangedFilesList
|
||||||
/>
|
files={gitChangedFiles}
|
||||||
</div>
|
currentDirectory={currentDirectory}
|
||||||
) : null}
|
onOpenFile={handleOpenFile}
|
||||||
</div>
|
/>
|
||||||
|
</Popover.Popup>
|
||||||
|
</Popover.Positioner>
|
||||||
|
</Popover.Portal>
|
||||||
|
</Popover.Root>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ const TodoItemRow: React.FC<TodoItemRowProps> = ({ todo }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center min-w-0 py-0.5 gap-2">
|
<div className="flex items-center min-w-0 py-0.5 gap-2">
|
||||||
<Tooltip delayDuration={200}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span className="flex-shrink-0">{statusIcon}</span>
|
<span className="flex-shrink-0">{statusIcon}</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -103,7 +103,7 @@ const TodoItemRow: React.FC<TodoItemRowProps> = ({ todo }) => {
|
|||||||
>
|
>
|
||||||
{todo.content}
|
{todo.content}
|
||||||
</span>
|
</span>
|
||||||
<Tooltip delayDuration={200}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ export const TimelineDialog: React.FC<TimelineDialogProps> = ({
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div className="hidden group-hover:flex gap-1">
|
<div className="hidden group-hover:flex gap-1">
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -162,7 +162,7 @@ export const TimelineDialog: React.FC<TimelineDialogProps> = ({
|
|||||||
<TooltipContent sideOffset={6}>{t('chat.timeline.actions.revertFromHere')}</TooltipContent>
|
<TooltipContent sideOffset={6}>{t('chat.timeline.actions.revertFromHere')}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export const TurnChangedFilesDropdown: React.FC<TurnChangedFilesDropdownProps> =
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover.Root open={isExpanded} onOpenChange={setIsExpanded}>
|
<Popover.Root open={isExpanded} onOpenChange={setIsExpanded}>
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Popover.Trigger
|
<Popover.Trigger
|
||||||
render={
|
render={
|
||||||
@@ -113,7 +113,7 @@ export const TurnChangedFilesDropdown: React.FC<TurnChangedFilesDropdownProps> =
|
|||||||
<Popover.Positioner side="top" align="start" sideOffset={4} collisionPadding={8}>
|
<Popover.Positioner side="top" align="start" sideOffset={4} collisionPadding={8}>
|
||||||
<Popover.Popup
|
<Popover.Popup
|
||||||
style={changedFilesPopoverStyle}
|
style={changedFilesPopoverStyle}
|
||||||
className={changedFilesPopoverClassName}
|
className={`${changedFilesPopoverClassName} transition-all duration-150 ease-out data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95`}
|
||||||
>
|
>
|
||||||
<ChangedFilesList
|
<ChangedFilesList
|
||||||
files={changedFiles}
|
files={changedFiles}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
|
|
||||||
export const changedFilesPopoverClassName =
|
export const changedFilesPopoverClassName =
|
||||||
"w-max min-w-[280px] max-w-full rounded-xl p-1 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)] animate-in fade-in-0 zoom-in-95 duration-150";
|
"w-max min-w-[280px] max-w-full rounded-xl p-1 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)] origin-[var(--transform-origin)]";
|
||||||
|
|
||||||
export const changedFilesPopoverStyle: CSSProperties = {
|
export const changedFilesPopoverStyle: CSSProperties = {
|
||||||
maxWidth: 'calc(100cqw - 4ch)',
|
maxWidth: 'calc(100cqw - 4ch)',
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ const UserMessageBody = React.memo(({ messageId, parts, isMobile, hasTouchInput,
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{onRevert && (
|
{onRevert && (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -465,7 +465,7 @@ const UserMessageBody = React.memo(({ messageId, parts, isMobile, hasTouchInput,
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{onFork && (
|
{onFork && (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -486,7 +486,7 @@ const UserMessageBody = React.memo(({ messageId, parts, isMobile, hasTouchInput,
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{canCopyMessage && hasCopyableText && (
|
{canCopyMessage && hasCopyableText && (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -734,7 +734,7 @@ const AssistantMessageActionButtons = React.memo(({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{onCopyMessage && (
|
{onCopyMessage && (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -773,7 +773,7 @@ const AssistantMessageActionButtons = React.memo(({
|
|||||||
<TooltipContent sideOffset={6}>{t('chat.messageBody.actions.copyAnswer')}</TooltipContent>
|
<TooltipContent sideOffset={6}>{t('chat.messageBody.actions.copyAnswer')}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -799,7 +799,7 @@ const AssistantMessageActionButtons = React.memo(({
|
|||||||
<TooltipContent sideOffset={6}>{isSharing ? t('chat.messageBody.actions.savingImage') : t('chat.messageBody.actions.saveAsImage')}</TooltipContent>
|
<TooltipContent sideOffset={6}>{isSharing ? t('chat.messageBody.actions.savingImage') : t('chat.messageBody.actions.saveAsImage')}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{showMessageTTSButtons && hasCopyableText && (
|
{showMessageTTSButtons && hasCopyableText && (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1698,7 +1698,7 @@ const AssistantMessageBody = React.memo(({
|
|||||||
const finalTurnActionButtons = (
|
const finalTurnActionButtons = (
|
||||||
<>
|
<>
|
||||||
{canOpenMessagePreview && messagePreviewUrl ? (
|
{canOpenMessagePreview && messagePreviewUrl ? (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1723,7 +1723,7 @@ const AssistantMessageBody = React.memo(({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
{!isVSCode ? (
|
{!isVSCode ? (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1743,7 +1743,7 @@ const AssistantMessageBody = React.memo(({
|
|||||||
<TooltipContent sideOffset={6}>{t('chat.messageBody.actions.saveAsPlan')}</TooltipContent>
|
<TooltipContent sideOffset={6}>{t('chat.messageBody.actions.saveAsPlan')}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1759,7 +1759,7 @@ const AssistantMessageBody = React.memo(({
|
|||||||
<TooltipContent sideOffset={6}>{t('chat.messageBody.actions.startNewSession')}</TooltipContent>
|
<TooltipContent sideOffset={6}>{t('chat.messageBody.actions.startNewSession')}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{!isVSCode ? (
|
{!isVSCode ? (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1846,7 +1846,7 @@ const AssistantMessageBody = React.memo(({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
{turnDurationText ? (
|
{turnDurationText ? (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span className="text-sm text-muted-foreground/60 tabular-nums flex items-center gap-1">
|
<span className="text-sm text-muted-foreground/60 tabular-nums flex items-center gap-1">
|
||||||
<RiHourglassLine className="h-3.5 w-3.5" />
|
<RiHourglassLine className="h-3.5 w-3.5" />
|
||||||
@@ -1857,7 +1857,7 @@ const AssistantMessageBody = React.memo(({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
{footerTimestamp ? (
|
{footerTimestamp ? (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span
|
<span
|
||||||
className={footerTimestampClassName}
|
className={footerTimestampClassName}
|
||||||
|
|||||||
@@ -928,7 +928,7 @@ export function DesktopHostSwitcherDialog({
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -950,7 +950,7 @@ export function DesktopHostSwitcherDialog({
|
|||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1328,7 +1328,7 @@ export function DesktopHostSwitcherButton({ headerIconButtonClass }: DesktopHost
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ const HeaderIconActionButton = React.memo(function HeaderIconActionButton({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -308,7 +308,7 @@ const DesktopServicesMenu = React.memo(function DesktopServicesMenu({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<button
|
<button
|
||||||
@@ -1726,7 +1726,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
const desktopSidebarActions = (
|
const desktopSidebarActions = (
|
||||||
<>
|
<>
|
||||||
{showPlanTab && (
|
{showPlanTab && (
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1820,7 +1820,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
|
|
||||||
<div className={cn('flex min-w-0 flex-1 items-center', !isSidebarOpen && 'pl-3')}>
|
<div className={cn('flex min-w-0 flex-1 items-center', !isSidebarOpen && 'pl-3')}>
|
||||||
{!isLeftSidebarOpen ? (
|
{!isLeftSidebarOpen ? (
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1970,7 +1970,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
const isDiffTab = tab.icon === 'diff';
|
const isDiffTab = tab.icon === 'diff';
|
||||||
const Icon = isDiffTab ? null : (tab.icon as RemixiconComponentType);
|
const Icon = isDiffTab ? null : (tab.icon as RemixiconComponentType);
|
||||||
return (
|
return (
|
||||||
<Tooltip key={tab.id} delayDuration={500}>
|
<Tooltip key={tab.id}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -2039,7 +2039,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<button
|
<button
|
||||||
@@ -2293,7 +2293,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|
||||||
{onToggleRightDrawer ? (
|
{onToggleRightDrawer ? (
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -784,7 +784,7 @@ export const ProjectActionsButton = ({
|
|||||||
: <SelectedIcon className="h-5 w-5" />}
|
: <SelectedIcon className="h-5 w-5" />}
|
||||||
</button>
|
</button>
|
||||||
{showSelectedPreviewButton ? (
|
{showSelectedPreviewButton ? (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -882,7 +882,7 @@ export const ProjectActionsButton = ({
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
{showSelectedPreviewButton ? (
|
{showSelectedPreviewButton ? (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export const McpDropdownContent: React.FC<McpDropdownContentProps> = ({ active,
|
|||||||
>
|
>
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="flex items-center gap-2 min-w-0">
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -305,7 +305,7 @@ export const McpDropdown: React.FC<McpDropdownProps> = ({ headerIconButtonClass
|
|||||||
aria-label={tooltip}
|
aria-label={tooltip}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -427,7 +427,7 @@ export const McpDropdown: React.FC<McpDropdownProps> = ({ headerIconButtonClass
|
|||||||
// Desktop: use DropdownMenu
|
// Desktop: use DropdownMenu
|
||||||
return (
|
return (
|
||||||
<DropdownMenu open={open} onOpenChange={handleDropdownOpenChange}>
|
<DropdownMenu open={open} onOpenChange={handleDropdownOpenChange}>
|
||||||
<Tooltip delayDuration={1000} open={open ? false : tooltipOpen} onOpenChange={handleTooltipOpenChange}>
|
<Tooltip open={open ? false : tooltipOpen} onOpenChange={handleTooltipOpenChange}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
{triggerButton}
|
{triggerButton}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ interface MultiRunLauncherProps {
|
|||||||
|
|
||||||
/** Info tooltip - small icon that shows helper text on hover */
|
/** Info tooltip - small icon that shows helper text on hover */
|
||||||
const InfoTip: React.FC<{ children: React.ReactNode }> = ({ children }) => (
|
const InfoTip: React.FC<{ children: React.ReactNode }> = ({ children }) => (
|
||||||
<Tooltip delayDuration={200}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button type="button" tabIndex={-1} className="inline-flex items-center justify-center text-muted-foreground/50 hover:text-muted-foreground transition-colors">
|
<button type="button" tabIndex={-1} className="inline-flex items-center justify-center text-muted-foreground/50 hover:text-muted-foreground transition-colors">
|
||||||
<RiInformationLine className="h-3.5 w-3.5" />
|
<RiInformationLine className="h-3.5 w-3.5" />
|
||||||
@@ -605,7 +605,7 @@ export const MultiRunLauncher: React.FC<MultiRunLauncherProps> = ({
|
|||||||
<h1 className="typography-ui-label font-medium">{t('multirun.launcher.title')}</h1>
|
<h1 className="typography-ui-label font-medium">{t('multirun.launcher.title')}</h1>
|
||||||
{onCancel && (
|
{onCancel && (
|
||||||
<div className="absolute right-0 flex items-center pr-3">
|
<div className="absolute right-0 flex items-center pr-3">
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -845,7 +845,7 @@ export const MultiRunLauncher: React.FC<MultiRunLauncherProps> = ({
|
|||||||
onChange={handleFileSelect}
|
onChange={handleFileSelect}
|
||||||
accept="*/*"
|
accept="*/*"
|
||||||
/>
|
/>
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -701,7 +701,7 @@ export const AgentsPage: React.FC = () => {
|
|||||||
<div className="flex min-w-0 flex-col gap-1.5">
|
<div className="flex min-w-0 flex-col gap-1.5">
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.agents.page.field.mode')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.agents.page.field.mode')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -778,7 +778,7 @@ export const AgentsPage: React.FC = () => {
|
|||||||
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "sm:w-56 shrink-0")}>
|
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "sm:w-56 shrink-0")}>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.agents.page.field.temperature')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.agents.page.field.temperature')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -822,7 +822,7 @@ export const AgentsPage: React.FC = () => {
|
|||||||
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "sm:w-56 shrink-0")}>
|
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "sm:w-56 shrink-0")}>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.agents.page.field.topP')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.agents.page.field.topP')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ export const GitIdentityEditorDialog: React.FC<GitIdentityEditorDialogProps> = (
|
|||||||
<div className="flex items-center gap-1.5 mb-1.5">
|
<div className="flex items-center gap-1.5 mb-1.5">
|
||||||
<label className="typography-ui-label text-foreground">{t('settings.gitIdentities.editor.field.userName')}</label>
|
<label className="typography-ui-label text-foreground">{t('settings.gitIdentities.editor.field.userName')}</label>
|
||||||
{!isGlobalProfile && <span className="text-[var(--status-error)] text-xs">*</span>}
|
{!isGlobalProfile && <span className="text-[var(--status-error)] text-xs">*</span>}
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -320,7 +320,7 @@ export const GitIdentityEditorDialog: React.FC<GitIdentityEditorDialogProps> = (
|
|||||||
<div className="flex items-center gap-1.5 mb-1.5">
|
<div className="flex items-center gap-1.5 mb-1.5">
|
||||||
<label className="typography-ui-label text-foreground">{t('settings.gitIdentities.editor.field.emailAddress')}</label>
|
<label className="typography-ui-label text-foreground">{t('settings.gitIdentities.editor.field.emailAddress')}</label>
|
||||||
{!isGlobalProfile && <span className="text-[var(--status-error)] text-xs">*</span>}
|
{!isGlobalProfile && <span className="text-[var(--status-error)] text-xs">*</span>}
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -373,7 +373,7 @@ export const GitIdentityEditorDialog: React.FC<GitIdentityEditorDialogProps> = (
|
|||||||
<div>
|
<div>
|
||||||
<div className="flex items-center gap-1.5 mb-1.5">
|
<div className="flex items-center gap-1.5 mb-1.5">
|
||||||
<label className="typography-ui-label text-foreground">{t('settings.gitIdentities.editor.field.sshKeyPath')}</label>
|
<label className="typography-ui-label text-foreground">{t('settings.gitIdentities.editor.field.sshKeyPath')}</label>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -396,7 +396,7 @@ export const GitIdentityEditorDialog: React.FC<GitIdentityEditorDialogProps> = (
|
|||||||
<div className="flex items-center gap-1.5 mb-1.5">
|
<div className="flex items-center gap-1.5 mb-1.5">
|
||||||
<label className="typography-ui-label text-foreground">{t('settings.gitIdentities.editor.field.host')}</label>
|
<label className="typography-ui-label text-foreground">{t('settings.gitIdentities.editor.field.host')}</label>
|
||||||
<span className="text-[var(--status-error)] text-xs">*</span>
|
<span className="text-[var(--status-error)] text-xs">*</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ export const MagicPromptsPage: React.FC = () => {
|
|||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<h2 className="typography-ui-header font-semibold text-foreground">{tUnsafe(pageConfig.titleKey)}</h2>
|
<h2 className="typography-ui-header font-semibold text-foreground">{tUnsafe(pageConfig.titleKey)}</h2>
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -304,7 +304,7 @@ export const MagicPromptsPage: React.FC = () => {
|
|||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<div className="flex flex-wrap items-center gap-2">
|
<div className="flex flex-wrap items-center gap-2">
|
||||||
<h3 className="typography-ui-label text-foreground">{tUnsafe(block.titleKey)}</h3>
|
<h3 className="typography-ui-label text-foreground">{tUnsafe(block.titleKey)}</h3>
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ export const GitHubSettings: React.FC = () => {
|
|||||||
<div className="mb-3 px-1 flex items-start justify-between gap-4">
|
<div className="mb-3 px-1 flex items-start justify-between gap-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<h3 className="typography-ui-header font-semibold text-foreground">GitHub</h3>
|
<h3 className="typography-ui-header font-semibold text-foreground">GitHub</h3>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ export const KeyboardShortcutsSettings: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{t('settings.openchamber.keyboardShortcuts.actions.resetAll')}
|
{t('settings.openchamber.keyboardShortcuts.actions.resetAll')}
|
||||||
</Button>
|
</Button>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -804,7 +804,7 @@ export const NotificationSettings: React.FC = () => {
|
|||||||
<div className="flex min-w-0 flex-col sm:w-56 shrink-0">
|
<div className="flex min-w-0 flex-col sm:w-56 shrink-0">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.notifications.page.summary.modelLabel')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.notifications.page.summary.modelLabel')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
|||||||
>
|
>
|
||||||
{themesReloading ? t('settings.openchamber.visual.actions.reloadingThemes') : t('settings.openchamber.visual.actions.reloadThemes')}
|
{themesReloading ? t('settings.openchamber.visual.actions.reloadingThemes') : t('settings.openchamber.visual.actions.reloadThemes')}
|
||||||
</button>
|
</button>
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1029,7 +1029,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
|||||||
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "w-56 shrink-0")}>
|
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "w-56 shrink-0")}>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.inputBarOffset')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.inputBarOffset')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -1095,7 +1095,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
|||||||
/>
|
/>
|
||||||
<div className="flex min-w-0 items-center gap-1.5">
|
<div className="flex min-w-0 items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.terminalQuickKeys')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.terminalQuickKeys')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -1551,7 +1551,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
|||||||
/>
|
/>
|
||||||
<div className="flex min-w-0 items-center gap-1.5">
|
<div className="flex min-w-0 items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.showSplitAssistantMessageActions')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.showSplitAssistantMessageActions')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 cursor-help text-muted-foreground/60" />
|
<RiInformationLine className="h-3.5 w-3.5 cursor-help text-muted-foreground/60" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -1653,7 +1653,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
|||||||
/>
|
/>
|
||||||
<div className="flex min-w-0 items-center gap-1.5">
|
<div className="flex min-w-0 items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.queueMessagesByDefault')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.queueMessagesByDefault')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export const OpenCodeCliSettings: React.FC = () => {
|
|||||||
<h3 className="typography-ui-header font-medium text-foreground">
|
<h3 className="typography-ui-header font-medium text-foreground">
|
||||||
{t('settings.openchamber.opencodeCli.title')}
|
{t('settings.openchamber.opencodeCli.title')}
|
||||||
</h3>
|
</h3>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export const SessionRetentionSettings: React.FC = () => {
|
|||||||
<h3 className="typography-ui-header font-medium text-foreground">
|
<h3 className="typography-ui-header font-medium text-foreground">
|
||||||
{t('settings.openchamber.sessionRetention.title')}
|
{t('settings.openchamber.sessionRetention.title')}
|
||||||
</h3>
|
</h3>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -1210,7 +1210,7 @@ export const TunnelSettings: React.FC = () => {
|
|||||||
<p className="typography-ui-label text-foreground">{t('settings.openchamber.tunnel.field.tunnelType')}</p>
|
<p className="typography-ui-label text-foreground">{t('settings.openchamber.tunnel.field.tunnelType')}</p>
|
||||||
<div className="flex flex-wrap items-center gap-1">
|
<div className="flex flex-wrap items-center gap-1">
|
||||||
{TUNNEL_MODE_OPTIONS.map((option) => (
|
{TUNNEL_MODE_OPTIONS.map((option) => (
|
||||||
<Tooltip key={option.value} delayDuration={700}>
|
<Tooltip key={option.value}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="chip"
|
variant="chip"
|
||||||
@@ -1481,7 +1481,7 @@ export const TunnelSettings: React.FC = () => {
|
|||||||
|
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<p className="typography-meta text-muted-foreground/80">{t('settings.openchamber.tunnel.note.tokensSavedPerTunnel')}</p>
|
<p className="typography-meta text-muted-foreground/80">{t('settings.openchamber.tunnel.note.tokensSavedPerTunnel')}</p>
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ export const VoiceSettings: React.FC = () => {
|
|||||||
<div className="flex min-w-0 flex-col gap-1.5">
|
<div className="flex min-w-0 flex-col gap-1.5">
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.voice.page.field.provider')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.voice.page.field.provider')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -732,7 +732,7 @@ export const VoiceSettings: React.FC = () => {
|
|||||||
<div className="flex min-w-0 flex-col gap-1.5">
|
<div className="flex min-w-0 flex-col gap-1.5">
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.voice.page.field.provider')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.voice.page.field.provider')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ export const WorktreeSectionContent: React.FC<WorktreeSectionContentProps> = ({
|
|||||||
<div className="mb-1 px-1">
|
<div className="mb-1 px-1">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<h3 className="typography-ui-header font-normal text-foreground">{t('settings.openchamber.worktrees.setup.title')}</h3>
|
<h3 className="typography-ui-header font-normal text-foreground">{t('settings.openchamber.worktrees.setup.title')}</h3>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -332,7 +332,7 @@ export const WorktreeSectionContent: React.FC<WorktreeSectionContentProps> = ({
|
|||||||
<div className="mb-1 px-1">
|
<div className="mb-1 px-1">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<h3 className="typography-ui-header font-normal text-foreground">{t('settings.openchamber.worktrees.list.title')}</h3>
|
<h3 className="typography-ui-header font-normal text-foreground">{t('settings.openchamber.worktrees.list.title')}</h3>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ export const ProjectActionsSection: React.FC<ProjectActionsSectionProps> = ({ pr
|
|||||||
placeholder={t('settings.projects.actions.field.overrideUrlPlaceholder')}
|
placeholder={t('settings.projects.actions.field.overrideUrlPlaceholder')}
|
||||||
className="h-7 w-full max-w-[24rem]"
|
className="h-7 w-full max-w-[24rem]"
|
||||||
/>
|
/>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 shrink-0 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 shrink-0 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -634,7 +634,7 @@ export const ProvidersPage: React.FC = () => {
|
|||||||
<div className="py-1.5">
|
<div className="py-1.5">
|
||||||
<label className="typography-ui-label text-foreground flex items-center gap-1.5">
|
<label className="typography-ui-label text-foreground flex items-center gap-1.5">
|
||||||
{t('settings.providers.page.auth.apiKeyLabel')}
|
{t('settings.providers.page.auth.apiKeyLabel')}
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -837,7 +837,7 @@ export const ProvidersPage: React.FC = () => {
|
|||||||
<div className="py-1.5">
|
<div className="py-1.5">
|
||||||
<label className="typography-ui-label text-foreground flex items-center gap-1.5">
|
<label className="typography-ui-label text-foreground flex items-center gap-1.5">
|
||||||
{t('settings.providers.page.auth.apiKeyLabel')}
|
{t('settings.providers.page.auth.apiKeyLabel')}
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ const HintLabel: React.FC<{ label: string; hint: React.ReactNode }> = ({ label,
|
|||||||
return (
|
return (
|
||||||
<span className="inline-flex items-center gap-1 typography-meta text-muted-foreground">
|
<span className="inline-flex items-center gap-1 typography-meta text-muted-foreground">
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ export const UsagePage: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="flex min-w-0 items-center gap-1.5">
|
<div className="flex min-w-0 items-center gap-1.5">
|
||||||
<span className="typography-ui-label text-foreground">{t('settings.usage.page.options.showInHeader')}</span>
|
<span className="typography-ui-label text-foreground">{t('settings.usage.page.options.showInHeader')}</span>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
<RiInformationLine className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export const UsageSidebar: React.FC<UsageSidebarProps> = ({ onItemSelect }) => {
|
|||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<span className="typography-meta text-muted-foreground">{t('settings.usage.sidebar.total', { count: QUOTA_PROVIDERS.length })}</span>
|
<span className="typography-meta text-muted-foreground">{t('settings.usage.sidebar.total', { count: QUOTA_PROVIDERS.length })}</span>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span className="inline-flex">
|
<span className="inline-flex">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ export function BranchPickerDialog({ open, onOpenChange, project }: BranchPicker
|
|||||||
|
|
||||||
{!isEditing && !isConfirming ? (
|
{!isEditing && !isConfirming ? (
|
||||||
<div className="flex items-center gap-1 flex-shrink-0">
|
<div className="flex items-center gap-1 flex-shrink-0">
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -456,7 +456,7 @@ export function BranchPickerDialog({ open, onOpenChange, project }: BranchPicker
|
|||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -473,7 +473,7 @@ export function BranchPickerDialog({ open, onOpenChange, project }: BranchPicker
|
|||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip delayDuration={700}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -657,46 +657,39 @@ export function NewWorktreeDialog({
|
|||||||
void loadDefaultSourceBranch();
|
void loadDefaultSourceBranch();
|
||||||
}, [branches, projectDirectory, newBranchState.sourceBranch]);
|
}, [branches, projectDirectory, newBranchState.sourceBranch]);
|
||||||
|
|
||||||
// Reset state when dialog opens/closes
|
// Reset state on each open. Resetting on close would empty the form during
|
||||||
|
// the close animation, causing visible flicker.
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!open) {
|
if (!open) return;
|
||||||
setMode('new-branch');
|
|
||||||
setNewBranchState({
|
setMode('new-branch');
|
||||||
branchName: '',
|
setExistingBranchState({
|
||||||
worktreeName: '',
|
selectedBranch: '',
|
||||||
isSyncingWorktreeName: true,
|
worktreeName: '',
|
||||||
sourceBranch: '',
|
});
|
||||||
linkedIssue: null,
|
setExistingBranchDropdownOpen(false);
|
||||||
linkedPr: null,
|
setSourceBranchDropdownOpen(false);
|
||||||
includePrDiff: false,
|
setExistingBranchPickerOpen(false);
|
||||||
});
|
setSourceBranchPickerOpen(false);
|
||||||
setExistingBranchState({
|
setExistingBranchQuery('');
|
||||||
selectedBranch: '',
|
setSourceBranchQuery('');
|
||||||
worktreeName: '',
|
setValidation({
|
||||||
});
|
isValidating: false,
|
||||||
setExistingBranchDropdownOpen(false);
|
branchError: null,
|
||||||
setSourceBranchDropdownOpen(false);
|
worktreeError: null,
|
||||||
setExistingBranchPickerOpen(false);
|
touched: false,
|
||||||
setSourceBranchPickerOpen(false);
|
});
|
||||||
setExistingBranchQuery('');
|
|
||||||
setSourceBranchQuery('');
|
|
||||||
setValidation({
|
|
||||||
isValidating: false,
|
|
||||||
branchError: null,
|
|
||||||
worktreeError: null,
|
|
||||||
touched: false,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate unique slug when dialog opens
|
|
||||||
const uniqueSlug = generateUniqueSlug();
|
const uniqueSlug = generateUniqueSlug();
|
||||||
setNewBranchState(prev => ({
|
setNewBranchState({
|
||||||
...prev,
|
|
||||||
branchName: uniqueSlug,
|
branchName: uniqueSlug,
|
||||||
worktreeName: uniqueSlug,
|
worktreeName: uniqueSlug,
|
||||||
isSyncingWorktreeName: true,
|
isSyncingWorktreeName: true,
|
||||||
}));
|
sourceBranch: '',
|
||||||
|
linkedIssue: null,
|
||||||
|
linkedPr: null,
|
||||||
|
includePrDiff: false,
|
||||||
|
});
|
||||||
}, [open, generateUniqueSlug]);
|
}, [open, generateUniqueSlug]);
|
||||||
|
|
||||||
// Sync worktree name with branch name for new-branch mode
|
// Sync worktree name with branch name for new-branch mode
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
import { Dialog, DialogContent, DialogTitle, DialogDescription } from '@/components/ui/dialog';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { ScrollShadow } from '@/components/ui/ScrollShadow';
|
import { ScrollShadow } from '@/components/ui/ScrollShadow';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
@@ -1456,7 +1456,7 @@ export function ScheduledTaskEditorDialog(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogPrimitive.Root
|
<Dialog
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={(next) => {
|
onOpenChange={(next) => {
|
||||||
if (!next && hasOpenFloatingMenu()) {
|
if (!next && hasOpenFloatingMenu()) {
|
||||||
@@ -1465,55 +1465,35 @@ export function ScheduledTaskEditorDialog(props: {
|
|||||||
onOpenChange(next);
|
onOpenChange(next);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogPrimitive.Portal>
|
<DialogContent
|
||||||
<DialogPrimitive.Overlay className="fixed inset-0 z-50 bg-black/50 dark:bg-black/75" />
|
aria-describedby={descriptionId}
|
||||||
<DialogPrimitive.Content
|
className="!max-w-[720px] w-[90vw] h-[680px] max-h-[85vh] gap-0 p-0 overflow-hidden"
|
||||||
aria-describedby={descriptionId}
|
>
|
||||||
className={cn(
|
<DialogDescription id={descriptionId} className="sr-only">
|
||||||
'fixed z-50 top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]',
|
{description}
|
||||||
'w-[90vw] max-w-[720px] h-[680px] max-h-[85vh]',
|
</DialogDescription>
|
||||||
'flex flex-col rounded-xl border shadow-none overflow-hidden',
|
|
||||||
'bg-background'
|
<header className="shrink-0 px-4 sm:px-6 pt-5 pb-3">
|
||||||
)}
|
<div className="mx-auto w-full max-w-2xl">
|
||||||
|
<DialogTitle className="typography-ui-label font-medium text-foreground">
|
||||||
|
{title}
|
||||||
|
</DialogTitle>
|
||||||
|
<p className="typography-meta mt-0.5 text-muted-foreground">{description}</p>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<ScrollShadow
|
||||||
|
className="flex-1 min-h-0 overflow-auto [scrollbar-gutter:stable_both-edges]"
|
||||||
|
size={64}
|
||||||
|
hideTopShadow
|
||||||
>
|
>
|
||||||
<div className="absolute right-0.5 top-0.5 z-50">
|
<div className="mx-auto w-full max-w-2xl px-4 sm:px-6 pb-5">{formBody}</div>
|
||||||
<button
|
</ScrollShadow>
|
||||||
type="button"
|
|
||||||
onClick={() => onOpenChange(false)}
|
|
||||||
aria-label={t('sessions.scheduledTasks.editor.actions.closeAria')}
|
|
||||||
className="inline-flex h-7 w-7 items-center justify-center rounded-md p-0.5 text-muted-foreground hover:bg-interactive-hover/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
|
||||||
>
|
|
||||||
<RiCloseLine className="h-5 w-5" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<DialogPrimitive.Description id={descriptionId} className="sr-only">
|
|
||||||
{description}
|
|
||||||
</DialogPrimitive.Description>
|
|
||||||
|
|
||||||
<header className="shrink-0 px-4 sm:px-6 pt-5 pb-3">
|
<div className="shrink-0 px-4 sm:px-6 py-3">
|
||||||
<div className="mx-auto w-full max-w-2xl">
|
<div className="mx-auto w-full max-w-2xl">{footerRow}</div>
|
||||||
<DialogPrimitive.Title className="typography-ui-label font-medium text-foreground">
|
</div>
|
||||||
{title}
|
</DialogContent>
|
||||||
</DialogPrimitive.Title>
|
</Dialog>
|
||||||
<p className="typography-meta mt-0.5 text-muted-foreground">
|
|
||||||
{description}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<ScrollShadow className="flex-1 min-h-0 overflow-auto [scrollbar-gutter:stable_both-edges]" size={64} hideTopShadow>
|
|
||||||
<div className="mx-auto w-full max-w-2xl px-4 sm:px-6 pb-5">
|
|
||||||
{formBody}
|
|
||||||
</div>
|
|
||||||
</ScrollShadow>
|
|
||||||
|
|
||||||
<div className="shrink-0 px-4 sm:px-6 py-3">
|
|
||||||
<div className="mx-auto w-full max-w-2xl">
|
|
||||||
{footerRow}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DialogPrimitive.Content>
|
|
||||||
</DialogPrimitive.Portal>
|
|
||||||
</DialogPrimitive.Root>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,7 +192,9 @@ export function ScheduledTasksDialog() {
|
|||||||
|
|
||||||
const [selectedProjectID, setSelectedProjectID] = React.useState<string>('');
|
const [selectedProjectID, setSelectedProjectID] = React.useState<string>('');
|
||||||
const [tasks, setTasks] = React.useState<ScheduledTask[]>([]);
|
const [tasks, setTasks] = React.useState<ScheduledTask[]>([]);
|
||||||
const [loading, setLoading] = React.useState(false);
|
// Start in loading state so the first frame after open shows the spinner,
|
||||||
|
// not an empty/select-project flash before the fetch effect runs.
|
||||||
|
const [loading, setLoading] = React.useState(true);
|
||||||
const [editorOpen, setEditorOpen] = React.useState(false);
|
const [editorOpen, setEditorOpen] = React.useState(false);
|
||||||
const [editorTask, setEditorTask] = React.useState<ScheduledTask | null>(null);
|
const [editorTask, setEditorTask] = React.useState<ScheduledTask | null>(null);
|
||||||
const [mutatingTaskID, setMutatingTaskID] = React.useState<string | null>(null);
|
const [mutatingTaskID, setMutatingTaskID] = React.useState<string | null>(null);
|
||||||
@@ -276,6 +278,7 @@ export function ScheduledTasksDialog() {
|
|||||||
void reloadTasks(preferredProjectID);
|
void reloadTasks(preferredProjectID);
|
||||||
} else {
|
} else {
|
||||||
setTasks([]);
|
setTasks([]);
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}, [open, activeProject, projects, reloadTasks]);
|
}, [open, activeProject, projects, reloadTasks]);
|
||||||
|
|
||||||
@@ -427,6 +430,7 @@ export function ScheduledTasksDialog() {
|
|||||||
projectSelector
|
projectSelector
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<div className="min-h-[280px]">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="flex items-center gap-2 typography-meta text-muted-foreground">
|
<div className="flex items-center gap-2 typography-meta text-muted-foreground">
|
||||||
<RiLoader4Line className="h-4 w-4 animate-spin" /> {t('sessions.scheduledTasks.dialog.loading')}
|
<RiLoader4Line className="h-4 w-4 animate-spin" /> {t('sessions.scheduledTasks.dialog.loading')}
|
||||||
@@ -579,6 +583,7 @@ export function ScheduledTasksDialog() {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ export const SortableProjectItem: React.FC<SortableProjectItemProps> = ({
|
|||||||
style={{ backgroundColor: isDesktopShell && isStuck ? 'transparent' : undefined }}
|
style={{ backgroundColor: isDesktopShell && isStuck ? 'transparent' : undefined }}
|
||||||
>
|
>
|
||||||
<div className="relative flex items-center gap-1 px-0.5 py-0.5" {...attributes}>
|
<div className="relative flex items-center gap-1 px-0.5 py-0.5" {...attributes}>
|
||||||
<Tooltip delayDuration={1500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -108,8 +108,10 @@ export const CommandPalette: React.FC = () => {
|
|||||||
const trimmedQuery = debouncedQuery.trim();
|
const trimmedQuery = debouncedQuery.trim();
|
||||||
const liveTrimmed = query.trim();
|
const liveTrimmed = query.trim();
|
||||||
|
|
||||||
|
// Clear query on open (not close) so content stays visible through the
|
||||||
|
// close animation instead of emptying mid-flight.
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!isCommandPaletteOpen) setQuery('');
|
if (isCommandPaletteOpen) setQuery('');
|
||||||
}, [isCommandPaletteOpen]);
|
}, [isCommandPaletteOpen]);
|
||||||
|
|
||||||
// Lazy-load git status for every session directory we plan to display so that
|
// Lazy-load git status for every session directory we plan to display so that
|
||||||
@@ -418,10 +420,7 @@ export const CommandPalette: React.FC = () => {
|
|||||||
<DialogTitle>{t('commandPalette.title')}</DialogTitle>
|
<DialogTitle>{t('commandPalette.title')}</DialogTitle>
|
||||||
<DialogDescription>{t('commandPalette.description')}</DialogDescription>
|
<DialogDescription>{t('commandPalette.description')}</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<DialogContent
|
<DialogContent className="overflow-hidden p-0" showCloseButton>
|
||||||
className="overflow-hidden p-0 transform-gpu will-change-transform"
|
|
||||||
showCloseButton
|
|
||||||
>
|
|
||||||
<Command
|
<Command
|
||||||
shouldFilter={false}
|
shouldFilter={false}
|
||||||
className="[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-4 [&_[cmdk-input-wrapper]_svg]:w-4 [&_[cmdk-input]]:h-8 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-1.5 [&_[cmdk-item]_svg]:h-4 [&_[cmdk-item]_svg]:w-4 [&_[cmdk-item]]:typography-meta"
|
className="[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-4 [&_[cmdk-input-wrapper]_svg]:w-4 [&_[cmdk-input]]:h-8 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-1.5 [&_[cmdk-item]_svg]:h-4 [&_[cmdk-item]_svg]:w-4 [&_[cmdk-item]]:typography-meta"
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ export const ContextUsageDisplay: React.FC<ContextUsageDisplayProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>{contextElement}</TooltipTrigger>
|
<TooltipTrigger asChild>{contextElement}</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<div className="space-y-0.5">
|
<div className="space-y-0.5">
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ export const DebugPanel: React.FC<DebugPanelProps> = ({ onClose }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex gap-2 border-t border-[var(--interactive-border)] pt-2">
|
<div className="flex gap-2 border-t border-[var(--interactive-border)] pt-2">
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ const DialogOverlay = React.forwardRef<
|
|||||||
data-slot="dialog-overlay"
|
data-slot="dialog-overlay"
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed inset-0 z-50 bg-black/50 dark:bg-black/75",
|
"fixed inset-0 z-50 bg-black/50 dark:bg-black/75",
|
||||||
|
"transition-opacity duration-150 ease-out",
|
||||||
|
"data-[starting-style]:opacity-0 data-[ending-style]:opacity-0",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -101,15 +103,19 @@ function DialogContent({
|
|||||||
return (
|
return (
|
||||||
<DialogPortal>
|
<DialogPortal>
|
||||||
<DialogOverlay className="rounded-none" />
|
<DialogOverlay className="rounded-none" />
|
||||||
<BaseDialog.Popup
|
<div className="fixed inset-0 z-50 flex items-center justify-center pointer-events-none p-4">
|
||||||
data-slot="dialog-content"
|
<BaseDialog.Popup
|
||||||
data-state-slot="dialog"
|
data-slot="dialog-content"
|
||||||
className={cn(
|
data-state-slot="dialog"
|
||||||
"bg-background text-foreground fixed top-[50%] left-[50%] z-50 flex flex-col w-full max-w-lg max-h-[calc(100dvh-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl border p-6 shadow-none overflow-y-auto pwa-dialog-content",
|
className={cn(
|
||||||
className
|
"relative pointer-events-auto bg-background text-foreground flex flex-col w-full max-w-lg max-h-full gap-4 rounded-xl border p-6 shadow-none overflow-y-auto pwa-dialog-content origin-center",
|
||||||
)}
|
"transition-all duration-150 ease-out",
|
||||||
{...props}
|
"data-[starting-style]:opacity-0 data-[starting-style]:scale-[0.98]",
|
||||||
>
|
"data-[ending-style]:opacity-0 data-[ending-style]:scale-[0.98]",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
{showCloseButton && (
|
{showCloseButton && (
|
||||||
<BaseDialog.Close
|
<BaseDialog.Close
|
||||||
@@ -120,7 +126,8 @@ function DialogContent({
|
|||||||
<span className="sr-only">{t('dialog.common.actions.close')}</span>
|
<span className="sr-only">{t('dialog.common.actions.close')}</span>
|
||||||
</BaseDialog.Close>
|
</BaseDialog.Close>
|
||||||
)}
|
)}
|
||||||
</BaseDialog.Popup>
|
</BaseDialog.Popup>
|
||||||
|
</div>
|
||||||
</DialogPortal>
|
</DialogPortal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ function DropdownMenuContent({
|
|||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
"data-[open]:animate-in data-[closed]:animate-out data-[closed]:fade-out-0 data-[open]:fade-in-0 data-[closed]:zoom-out-95 data-[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-[var(--available-height)] min-w-[8rem] origin-[var(--transform-origin)] overflow-visible rounded-xl p-1 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)]",
|
"transition-all duration-150 ease-out data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95 z-50 max-h-[var(--available-height)] min-w-[8rem] origin-[var(--transform-origin)] overflow-visible rounded-xl p-1 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)]",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -336,7 +336,7 @@ function DropdownMenuSubContent({
|
|||||||
color: 'var(--surface-elevated-foreground)',
|
color: 'var(--surface-elevated-foreground)',
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
"data-[open]:animate-in data-[closed]:animate-out data-[closed]:fade-out-0 data-[open]:fade-in-0 data-[closed]:zoom-out-95 data-[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-[var(--transform-origin)] overflow-visible rounded-xl p-1 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)]",
|
"transition-all duration-150 ease-out data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95 z-50 min-w-[8rem] origin-[var(--transform-origin)] overflow-visible rounded-xl p-1 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)]",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ function SelectContent({
|
|||||||
color: 'var(--surface-elevated-foreground)',
|
color: 'var(--surface-elevated-foreground)',
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
"pointer-events-auto data-[open]:animate-in data-[closed]:animate-out data-[closed]:fade-out-0 data-[open]:fade-in-0 data-[closed]:zoom-out-95 data-[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-[120] max-h-[var(--available-height)] min-w-[8rem] origin-[var(--transform-origin)] overflow-x-hidden rounded-xl transform-gpu will-change-transform shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)]",
|
"pointer-events-auto transition-all duration-150 ease-out data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95 relative z-[120] max-h-[var(--available-height)] min-w-[8rem] origin-[var(--transform-origin)] overflow-x-hidden rounded-xl shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)]",
|
||||||
!alignItemWithTrigger &&
|
!alignItemWithTrigger &&
|
||||||
"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",
|
||||||
fitContent && "w-max min-w-0",
|
fitContent && "w-max min-w-0",
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ function TooltipContent({
|
|||||||
<BaseTooltip.Popup
|
<BaseTooltip.Popup
|
||||||
data-slot="tooltip-content"
|
data-slot="tooltip-content"
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-muted text-muted-foreground border border-border/60 animate-in fade-in-0 zoom-in-95 data-[closed]:animate-out data-[closed]:fade-out-0 data-[closed]:zoom-out-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 w-fit origin-[var(--transform-origin)] rounded-xl px-3 py-1.5 typography-meta text-balance overflow-hidden transform-gpu will-change-transform",
|
"bg-muted text-muted-foreground border border-border/60 transition-all duration-150 ease-out data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95 z-50 w-fit origin-[var(--transform-origin)] rounded-xl px-3 py-1.5 typography-meta text-balance overflow-hidden",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
style={{ ...style }}
|
style={{ ...style }}
|
||||||
|
|||||||
@@ -38,36 +38,47 @@ export const MultiRunWindow: React.FC<MultiRunWindowProps> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Dialog.Portal>
|
<Dialog.Portal>
|
||||||
<Dialog.Backdrop className="fixed inset-0 z-50 bg-black/50 dark:bg-black/75" />
|
<Dialog.Backdrop
|
||||||
<Dialog.Popup
|
|
||||||
aria-describedby={descriptionId}
|
|
||||||
className={cn(
|
className={cn(
|
||||||
'fixed z-50 top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]',
|
'fixed inset-0 z-50 bg-black/50 dark:bg-black/75',
|
||||||
'w-[90vw] max-w-[720px] h-[680px] max-h-[85vh]',
|
'transition-opacity duration-150 ease-out',
|
||||||
'flex flex-col rounded-xl border shadow-none overflow-hidden',
|
'data-[starting-style]:opacity-0 data-[ending-style]:opacity-0',
|
||||||
'bg-background'
|
|
||||||
)}
|
)}
|
||||||
>
|
/>
|
||||||
<div className="absolute right-0.5 top-0.5 z-50">
|
<div className="fixed inset-0 z-50 flex items-center justify-center pointer-events-none">
|
||||||
<button
|
<Dialog.Popup
|
||||||
type="button"
|
aria-describedby={descriptionId}
|
||||||
onClick={() => onOpenChange(false)}
|
className={cn(
|
||||||
aria-label={t('multiRun.window.actions.closeAria')}
|
'relative pointer-events-auto',
|
||||||
className="inline-flex h-7 w-7 items-center justify-center rounded-md p-0.5 text-muted-foreground hover:text-foreground hover:bg-interactive-hover/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
'w-[90vw] max-w-[720px] h-[680px] max-h-[85vh]',
|
||||||
>
|
'flex flex-col rounded-xl border shadow-none overflow-hidden origin-center',
|
||||||
<RiCloseLine className="h-5 w-5" />
|
'bg-background',
|
||||||
</button>
|
'transition-all duration-150 ease-out',
|
||||||
</div>
|
'data-[starting-style]:opacity-0 data-[starting-style]:scale-[0.98]',
|
||||||
<Dialog.Description id={descriptionId} className="sr-only">
|
'data-[ending-style]:opacity-0 data-[ending-style]:scale-[0.98]',
|
||||||
{t('multiRun.window.description')}
|
)}
|
||||||
</Dialog.Description>
|
>
|
||||||
<MultiRunLauncher
|
<div className="absolute right-0.5 top-0.5 z-50">
|
||||||
initialPrompt={initialPrompt}
|
<button
|
||||||
onCreated={() => onOpenChange(false)}
|
type="button"
|
||||||
onCancel={() => onOpenChange(false)}
|
onClick={() => onOpenChange(false)}
|
||||||
isWindowed
|
aria-label={t('multiRun.window.actions.closeAria')}
|
||||||
/>
|
className="inline-flex h-7 w-7 items-center justify-center rounded-md p-0.5 text-muted-foreground hover:text-foreground hover:bg-interactive-hover/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
||||||
</Dialog.Popup>
|
>
|
||||||
|
<RiCloseLine className="h-5 w-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<Dialog.Description id={descriptionId} className="sr-only">
|
||||||
|
{t('multiRun.window.description')}
|
||||||
|
</Dialog.Description>
|
||||||
|
<MultiRunLauncher
|
||||||
|
initialPrompt={initialPrompt}
|
||||||
|
onCreated={() => onOpenChange(false)}
|
||||||
|
onCancel={() => onOpenChange(false)}
|
||||||
|
isWindowed
|
||||||
|
/>
|
||||||
|
</Dialog.Popup>
|
||||||
|
</div>
|
||||||
</Dialog.Portal>
|
</Dialog.Portal>
|
||||||
</Dialog.Root>
|
</Dialog.Root>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -628,7 +628,7 @@ export const PlanView: React.FC<PlanViewProps> = ({ targetPath = null }) => {
|
|||||||
{resolvedPath ? (
|
{resolvedPath ? (
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
@@ -657,7 +657,7 @@ export const PlanView: React.FC<PlanViewProps> = ({ targetPath = null }) => {
|
|||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const PreviewToggleButton: React.FC<PreviewToggleButtonProps> = ({
|
|||||||
const tooltipText = isPreview ? 'Edit' : 'Preview';
|
const tooltipText = isPreview ? 'Edit' : 'Preview';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
@@ -554,7 +554,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({ onClose, forceMobile
|
|||||||
if (!Icon) return null;
|
if (!Icon) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip key={page.slug} delayDuration={600}>
|
<Tooltip key={page.slug}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -587,7 +587,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({ onClose, forceMobile
|
|||||||
<div className="overflow-hidden transition-opacity duration-150 opacity-100">
|
<div className="overflow-hidden transition-opacity duration-150 opacity-100">
|
||||||
<div className="border-t border-border bg-sidebar px-2 py-1 space-y-0.5">
|
<div className="border-t border-border bg-sidebar px-2 py-1 space-y-0.5">
|
||||||
{!runtimeCtx.isVSCode && (
|
{!runtimeCtx.isVSCode && (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -36,21 +36,32 @@ export const SettingsWindow: React.FC<SettingsWindowProps> = ({ open, onOpenChan
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Dialog.Portal>
|
<Dialog.Portal>
|
||||||
<Dialog.Backdrop className="fixed inset-0 z-50 bg-black/50 dark:bg-black/75" />
|
<Dialog.Backdrop
|
||||||
<Dialog.Popup
|
|
||||||
aria-describedby={descriptionId}
|
|
||||||
className={cn(
|
className={cn(
|
||||||
'fixed z-50 top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]',
|
'fixed inset-0 z-50 bg-black/50 dark:bg-black/75',
|
||||||
'w-[90vw] max-w-[1200px] h-[85vh] max-h-[900px]',
|
'transition-opacity duration-150 ease-out',
|
||||||
'rounded-xl border shadow-none overflow-hidden',
|
'data-[starting-style]:opacity-0 data-[ending-style]:opacity-0',
|
||||||
'bg-background'
|
|
||||||
)}
|
)}
|
||||||
>
|
/>
|
||||||
<Dialog.Description id={descriptionId} className="sr-only">
|
<div className="fixed inset-0 z-50 flex items-center justify-center pointer-events-none">
|
||||||
{t('settings.window.description')}
|
<Dialog.Popup
|
||||||
</Dialog.Description>
|
aria-describedby={descriptionId}
|
||||||
<SettingsView onClose={() => onOpenChange(false)} isWindowed />
|
className={cn(
|
||||||
</Dialog.Popup>
|
'relative pointer-events-auto',
|
||||||
|
'w-[90vw] max-w-[1200px] h-[85vh] max-h-[900px]',
|
||||||
|
'rounded-xl border shadow-none overflow-hidden origin-center',
|
||||||
|
'bg-background',
|
||||||
|
'transition-all duration-150 ease-out',
|
||||||
|
'data-[starting-style]:opacity-0 data-[starting-style]:scale-[0.98]',
|
||||||
|
'data-[ending-style]:opacity-0 data-[ending-style]:scale-[0.98]',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Dialog.Description id={descriptionId} className="sr-only">
|
||||||
|
{t('settings.window.description')}
|
||||||
|
</Dialog.Description>
|
||||||
|
<SettingsView onClose={() => onOpenChange(false)} isWindowed />
|
||||||
|
</Dialog.Popup>
|
||||||
|
</div>
|
||||||
</Dialog.Portal>
|
</Dialog.Portal>
|
||||||
</Dialog.Root>
|
</Dialog.Root>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const AIHighlightsBox: React.FC<AIHighlightsBoxProps> = ({
|
|||||||
<div className="space-y-2 rounded-xl border border-border/60 bg-transparent px-3 py-2">
|
<div className="space-y-2 rounded-xl border border-border/60 bg-transparent px-3 py-2">
|
||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<p className="typography-micro text-muted-foreground">{t('gitView.commit.aiHighlights.title')}</p>
|
<p className="typography-micro text-muted-foreground">{t('gitView.commit.aiHighlights.title')}</p>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ export const BranchIntegrationSection: React.FC<BranchIntegrationSectionProps> =
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ interface BranchSelectorProps {
|
|||||||
onCreate: (name: string, remote?: GitRemote) => Promise<void>;
|
onCreate: (name: string, remote?: GitRemote) => Promise<void>;
|
||||||
remotes?: GitRemote[];
|
remotes?: GitRemote[];
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
tooltipDelayMs?: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sanitizeBranchNameInput = (value: string): string => {
|
const sanitizeBranchNameInput = (value: string): string => {
|
||||||
@@ -65,7 +64,6 @@ export const BranchSelector: React.FC<BranchSelectorProps> = ({
|
|||||||
onCreate,
|
onCreate,
|
||||||
remotes = [],
|
remotes = [],
|
||||||
disabled = false,
|
disabled = false,
|
||||||
tooltipDelayMs = 1000,
|
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const [isOpen, setIsOpen] = React.useState(false);
|
const [isOpen, setIsOpen] = React.useState(false);
|
||||||
@@ -170,7 +168,7 @@ export const BranchSelector: React.FC<BranchSelectorProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu open={isOpen} onOpenChange={setIsOpen}>
|
<DropdownMenu open={isOpen} onOpenChange={setIsOpen}>
|
||||||
<Tooltip delayDuration={tooltipDelayMs}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ export const ChangeRow = React.memo<ChangeRowProps>(function ChangeRow({
|
|||||||
<span className="text-muted-foreground mx-0.5">/</span>
|
<span className="text-muted-foreground mx-0.5">/</span>
|
||||||
<span style={{ color: 'var(--status-error)' }}>-{deletions}</span>
|
<span style={{ color: 'var(--status-error)' }}>-{deletions}</span>
|
||||||
</span>
|
</span>
|
||||||
<Tooltip delayDuration={200}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ interface IdentityDropdownProps {
|
|||||||
identities: GitIdentityProfile[];
|
identities: GitIdentityProfile[];
|
||||||
onSelect: (profile: GitIdentityProfile) => void;
|
onSelect: (profile: GitIdentityProfile) => void;
|
||||||
isApplying: boolean;
|
isApplying: boolean;
|
||||||
tooltipDelayMs?: number;
|
|
||||||
iconOnly?: boolean;
|
iconOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +112,6 @@ const IdentityDropdown: React.FC<IdentityDropdownProps> = ({
|
|||||||
identities,
|
identities,
|
||||||
onSelect,
|
onSelect,
|
||||||
isApplying,
|
isApplying,
|
||||||
tooltipDelayMs = 1000,
|
|
||||||
iconOnly = false,
|
iconOnly = false,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -121,7 +119,7 @@ const IdentityDropdown: React.FC<IdentityDropdownProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<Tooltip delayDuration={tooltipDelayMs}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
@@ -224,7 +222,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
|||||||
const managementButtons = (
|
const managementButtons = (
|
||||||
<div className="flex items-center gap-1 shrink-0">
|
<div className="flex items-center gap-1 shrink-0">
|
||||||
{onOpenHistory ? (
|
{onOpenHistory ? (
|
||||||
<Tooltip delayDuration={useTwoRowHeader ? 300 : 1000}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@@ -252,7 +250,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
|||||||
removingRemoteName={removingRemoteName}
|
removingRemoteName={removingRemoteName}
|
||||||
disabled={!status}
|
disabled={!status}
|
||||||
iconOnly={true}
|
iconOnly={true}
|
||||||
tooltipDelayMs={useTwoRowHeader ? 300 : 1000}
|
|
||||||
aheadCount={status.ahead}
|
aheadCount={status.ahead}
|
||||||
behindCount={status.behind}
|
behindCount={status.behind}
|
||||||
/>
|
/>
|
||||||
@@ -264,7 +262,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
|||||||
identities={availableIdentities}
|
identities={availableIdentities}
|
||||||
onSelect={onSelectIdentity}
|
onSelect={onSelectIdentity}
|
||||||
isApplying={isApplyingIdentity}
|
isApplying={isApplyingIdentity}
|
||||||
tooltipDelayMs={useTwoRowHeader ? 300 : 1000}
|
|
||||||
iconOnly={false}
|
iconOnly={false}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -287,7 +285,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
|||||||
onCheckout={onCheckoutBranch}
|
onCheckout={onCheckoutBranch}
|
||||||
onCreate={onCreateBranch}
|
onCreate={onCreateBranch}
|
||||||
remotes={remotes}
|
remotes={remotes}
|
||||||
tooltipDelayMs={useTwoRowHeader ? 300 : 1000}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export const HistoryCommitRow = React.memo(({
|
|||||||
<code className="shrink-0 font-mono">
|
<code className="shrink-0 font-mono">
|
||||||
{entry.hash.slice(0, 8)}
|
{entry.hash.slice(0, 8)}
|
||||||
</code>
|
</code>
|
||||||
<Tooltip delayDuration={500}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
@@ -1408,7 +1408,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<div className="flex items-center gap-2 min-w-0">
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
{pr ? (
|
{pr ? (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1431,7 +1431,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{isLoading ? <RiLoader4Line className="size-4 animate-spin text-muted-foreground" /> : null}
|
{isLoading ? <RiLoader4Line className="size-4 animate-spin text-muted-foreground" /> : null}
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1612,7 +1612,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
{pr.state === 'open' ? (
|
{pr.state === 'open' ? (
|
||||||
isEditingPr ? (
|
isEditingPr ? (
|
||||||
<>
|
<>
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -1631,7 +1631,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent><p>{t('gitView.pr.actions.cancelEditing')}</p></TooltipContent>
|
<TooltipContent><p>{t('gitView.pr.actions.cancelEditing')}</p></TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -1647,7 +1647,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -1665,7 +1665,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{checks ? (
|
{checks ? (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -1683,7 +1683,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{checks?.failure ? (
|
{checks?.failure ? (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -1699,7 +1699,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -1714,7 +1714,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
<TooltipContent><p>{t('gitView.pr.actions.openComments')}</p></TooltipContent>
|
<TooltipContent><p>{t('gitView.pr.actions.openComments')}</p></TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -1730,7 +1730,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
{canMerge && pr.draft && pr.state === 'open' ? (
|
{canMerge && pr.draft && pr.state === 'open' ? (
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -1765,7 +1765,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
<SelectItem value="rebase">{t('gitView.pr.mergeMethod.rebase')}</SelectItem>
|
<SelectItem value="rebase">{t('gitView.pr.mergeMethod.rebase')}</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -2064,7 +2064,7 @@ export const PullRequestSection: React.FC<{
|
|||||||
{comment.authorLogin && comment.authorLogin !== comment.authorName ? ` · @${comment.authorLogin}` : ''}
|
{comment.authorLogin && comment.authorLogin !== comment.authorName ? ` · @${comment.authorLogin}` : ''}
|
||||||
</span>
|
</span>
|
||||||
{comment.createdAt ? <span className="whitespace-nowrap">{formatTimestamp(comment.createdAt)}</span> : null}
|
{comment.createdAt ? <span className="whitespace-nowrap">{formatTimestamp(comment.createdAt)}</span> : null}
|
||||||
<Tooltip delayDuration={300}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ interface SyncActionsProps {
|
|||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
removingRemoteName?: string | null;
|
removingRemoteName?: string | null;
|
||||||
iconOnly?: boolean;
|
iconOnly?: boolean;
|
||||||
tooltipDelayMs?: number;
|
|
||||||
aheadCount?: number;
|
aheadCount?: number;
|
||||||
behindCount?: number;
|
behindCount?: number;
|
||||||
}
|
}
|
||||||
@@ -44,7 +43,6 @@ export const SyncActions: React.FC<SyncActionsProps> = ({
|
|||||||
disabled,
|
disabled,
|
||||||
removingRemoteName = null,
|
removingRemoteName = null,
|
||||||
iconOnly = false,
|
iconOnly = false,
|
||||||
tooltipDelayMs = 1000,
|
|
||||||
aheadCount = 0,
|
aheadCount = 0,
|
||||||
behindCount = 0,
|
behindCount = 0,
|
||||||
}) => {
|
}) => {
|
||||||
@@ -108,7 +106,7 @@ export const SyncActions: React.FC<SyncActionsProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={tooltipDelayMs}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={8}>{tooltipText}</TooltipContent>
|
<TooltipContent sideOffset={8}>{tooltipText}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -126,7 +124,7 @@ export const SyncActions: React.FC<SyncActionsProps> = ({
|
|||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<Tooltip delayDuration={tooltipDelayMs}>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
Reference in New Issue
Block a user