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:
@@ -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="flex items-center justify-between gap-2">
|
||||
<p className="typography-micro text-muted-foreground">{t('gitView.commit.aiHighlights.title')}</p>
|
||||
<Tooltip delayDuration={1000}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
||||
@@ -414,7 +414,7 @@ export const BranchIntegrationSection: React.FC<BranchIntegrationSectionProps> =
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip delayDuration={1000}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
|
||||
@@ -40,7 +40,6 @@ interface BranchSelectorProps {
|
||||
onCreate: (name: string, remote?: GitRemote) => Promise<void>;
|
||||
remotes?: GitRemote[];
|
||||
disabled?: boolean;
|
||||
tooltipDelayMs?: number;
|
||||
}
|
||||
|
||||
const sanitizeBranchNameInput = (value: string): string => {
|
||||
@@ -65,7 +64,6 @@ export const BranchSelector: React.FC<BranchSelectorProps> = ({
|
||||
onCreate,
|
||||
remotes = [],
|
||||
disabled = false,
|
||||
tooltipDelayMs = 1000,
|
||||
}) => {
|
||||
const { t } = useI18n();
|
||||
const [isOpen, setIsOpen] = React.useState(false);
|
||||
@@ -170,7 +168,7 @@ export const BranchSelector: React.FC<BranchSelectorProps> = ({
|
||||
|
||||
return (
|
||||
<DropdownMenu open={isOpen} onOpenChange={setIsOpen}>
|
||||
<Tooltip delayDuration={tooltipDelayMs}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
|
||||
@@ -150,7 +150,7 @@ export const ChangeRow = React.memo<ChangeRowProps>(function ChangeRow({
|
||||
<span className="text-muted-foreground mx-0.5">/</span>
|
||||
<span style={{ color: 'var(--status-error)' }}>-{deletions}</span>
|
||||
</span>
|
||||
<Tooltip delayDuration={200}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -104,7 +104,6 @@ interface IdentityDropdownProps {
|
||||
identities: GitIdentityProfile[];
|
||||
onSelect: (profile: GitIdentityProfile) => void;
|
||||
isApplying: boolean;
|
||||
tooltipDelayMs?: number;
|
||||
iconOnly?: boolean;
|
||||
}
|
||||
|
||||
@@ -113,7 +112,6 @@ const IdentityDropdown: React.FC<IdentityDropdownProps> = ({
|
||||
identities,
|
||||
onSelect,
|
||||
isApplying,
|
||||
tooltipDelayMs = 1000,
|
||||
iconOnly = false,
|
||||
}) => {
|
||||
const { t } = useI18n();
|
||||
@@ -121,7 +119,7 @@ const IdentityDropdown: React.FC<IdentityDropdownProps> = ({
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<Tooltip delayDuration={tooltipDelayMs}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
@@ -224,7 +222,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
||||
const managementButtons = (
|
||||
<div className="flex items-center gap-1 shrink-0">
|
||||
{onOpenHistory ? (
|
||||
<Tooltip delayDuration={useTwoRowHeader ? 300 : 1000}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -252,7 +250,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
||||
removingRemoteName={removingRemoteName}
|
||||
disabled={!status}
|
||||
iconOnly={true}
|
||||
tooltipDelayMs={useTwoRowHeader ? 300 : 1000}
|
||||
|
||||
aheadCount={status.ahead}
|
||||
behindCount={status.behind}
|
||||
/>
|
||||
@@ -264,7 +262,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
||||
identities={availableIdentities}
|
||||
onSelect={onSelectIdentity}
|
||||
isApplying={isApplyingIdentity}
|
||||
tooltipDelayMs={useTwoRowHeader ? 300 : 1000}
|
||||
|
||||
iconOnly={false}
|
||||
/>
|
||||
);
|
||||
@@ -287,7 +285,7 @@ export const GitHeader: React.FC<GitHeaderProps> = ({
|
||||
onCheckout={onCheckoutBranch}
|
||||
onCreate={onCreateBranch}
|
||||
remotes={remotes}
|
||||
tooltipDelayMs={useTwoRowHeader ? 300 : 1000}
|
||||
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -88,7 +88,7 @@ export const HistoryCommitRow = React.memo(({
|
||||
<code className="shrink-0 font-mono">
|
||||
{entry.hash.slice(0, 8)}
|
||||
</code>
|
||||
<Tooltip delayDuration={500}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
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 gap-2 min-w-0">
|
||||
{pr ? (
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
@@ -1431,7 +1431,7 @@ export const PullRequestSection: React.FC<{
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{isLoading ? <RiLoader4Line className="size-4 animate-spin text-muted-foreground" /> : null}
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
@@ -1612,7 +1612,7 @@ export const PullRequestSection: React.FC<{
|
||||
{pr.state === 'open' ? (
|
||||
isEditingPr ? (
|
||||
<>
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -1631,7 +1631,7 @@ export const PullRequestSection: React.FC<{
|
||||
</TooltipTrigger>
|
||||
<TooltipContent><p>{t('gitView.pr.actions.cancelEditing')}</p></TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -1647,7 +1647,7 @@ export const PullRequestSection: React.FC<{
|
||||
</Tooltip>
|
||||
</>
|
||||
) : (
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -1665,7 +1665,7 @@ export const PullRequestSection: React.FC<{
|
||||
) : null}
|
||||
|
||||
{checks ? (
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -1683,7 +1683,7 @@ export const PullRequestSection: React.FC<{
|
||||
) : null}
|
||||
|
||||
{checks?.failure ? (
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -1699,7 +1699,7 @@ export const PullRequestSection: React.FC<{
|
||||
</Tooltip>
|
||||
) : null}
|
||||
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -1714,7 +1714,7 @@ export const PullRequestSection: React.FC<{
|
||||
<TooltipContent><p>{t('gitView.pr.actions.openComments')}</p></TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -1730,7 +1730,7 @@ export const PullRequestSection: React.FC<{
|
||||
</Tooltip>
|
||||
|
||||
{canMerge && pr.draft && pr.state === 'open' ? (
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -1765,7 +1765,7 @@ export const PullRequestSection: React.FC<{
|
||||
<SelectItem value="rebase">{t('gitView.pr.mergeMethod.rebase')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -2064,7 +2064,7 @@ export const PullRequestSection: React.FC<{
|
||||
{comment.authorLogin && comment.authorLogin !== comment.authorName ? ` · @${comment.authorLogin}` : ''}
|
||||
</span>
|
||||
{comment.createdAt ? <span className="whitespace-nowrap">{formatTimestamp(comment.createdAt)}</span> : null}
|
||||
<Tooltip delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
||||
@@ -29,7 +29,6 @@ interface SyncActionsProps {
|
||||
disabled: boolean;
|
||||
removingRemoteName?: string | null;
|
||||
iconOnly?: boolean;
|
||||
tooltipDelayMs?: number;
|
||||
aheadCount?: number;
|
||||
behindCount?: number;
|
||||
}
|
||||
@@ -44,7 +43,6 @@ export const SyncActions: React.FC<SyncActionsProps> = ({
|
||||
disabled,
|
||||
removingRemoteName = null,
|
||||
iconOnly = false,
|
||||
tooltipDelayMs = 1000,
|
||||
aheadCount = 0,
|
||||
behindCount = 0,
|
||||
}) => {
|
||||
@@ -108,7 +106,7 @@ export const SyncActions: React.FC<SyncActionsProps> = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<Tooltip delayDuration={tooltipDelayMs}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
||||
<TooltipContent sideOffset={8}>{tooltipText}</TooltipContent>
|
||||
</Tooltip>
|
||||
@@ -126,7 +124,7 @@ export const SyncActions: React.FC<SyncActionsProps> = ({
|
||||
) => {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<Tooltip delayDuration={tooltipDelayMs}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user