Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -111,6 +111,7 @@ import {
|
||||
SidebarWorkspaceTrailingActionOverlay,
|
||||
SidebarWorkspaceTrailingActionSlot,
|
||||
} from "@/components/sidebar/sidebar-workspace-row-content";
|
||||
import { useOpenKebabMenuVisibility } from "@/components/sidebar/use-open-kebab-menu-visibility";
|
||||
import { selectWorkspaceScriptSummary } from "@/components/sidebar/workspace-meta-row";
|
||||
import {
|
||||
SidebarWorkspaceTrailingContent,
|
||||
@@ -665,6 +666,7 @@ function WorkspaceRowRightGroup({
|
||||
isTouchPlatform,
|
||||
showShortcut,
|
||||
});
|
||||
const kebab = useOpenKebabMenuVisibility(showKebabInSlot);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -676,9 +678,10 @@ function WorkspaceRowRightGroup({
|
||||
<SidebarWorkspaceTrailingActionBase visible={showTrailing}>
|
||||
<SidebarWorkspaceTrailingContent workspace={workspace} trailing={trailing} />
|
||||
</SidebarWorkspaceTrailingActionBase>
|
||||
<SidebarWorkspaceTrailingActionOverlay visible={showKebabInSlot} scrim={showScrim}>
|
||||
<SidebarWorkspaceTrailingActionOverlay visible={kebab.showKebab} scrim={showScrim}>
|
||||
{onArchive ? (
|
||||
<SidebarWorkspaceMenu
|
||||
{...kebab.menuProps}
|
||||
workspaceKey={workspace.workspaceKey}
|
||||
onCopyPath={onCopyPath}
|
||||
onCopyBranchName={onCopyBranchName}
|
||||
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
SidebarWorkspaceTrailingActionSlot,
|
||||
sidebarWorkspaceRowStyles,
|
||||
} from "@/components/sidebar/sidebar-workspace-row-content";
|
||||
import { useOpenKebabMenuVisibility } from "@/components/sidebar/use-open-kebab-menu-visibility";
|
||||
import { getSidebarRowBackdrop } from "@/components/sidebar/sidebar-row-backdrop";
|
||||
import { selectWorkspaceScriptSummary } from "@/components/sidebar/workspace-meta-row";
|
||||
import {
|
||||
@@ -813,14 +814,16 @@ function StatusWorkspaceActionSlot({
|
||||
archivePendingLabel?: string;
|
||||
archiveShortcutKeys?: ShortcutKey[][] | null;
|
||||
}) {
|
||||
const kebab = useOpenKebabMenuVisibility(showKebab);
|
||||
return (
|
||||
<SidebarWorkspaceTrailingActionSlot reserveWidth={reserveSlotWidth}>
|
||||
<SidebarWorkspaceTrailingActionBase visible={showBase}>
|
||||
<SidebarWorkspaceTrailingContent workspace={workspace} trailing={trailing} />
|
||||
</SidebarWorkspaceTrailingActionBase>
|
||||
<SidebarWorkspaceTrailingActionOverlay visible={showKebab} scrim={showScrim}>
|
||||
{showKebab && onArchive ? (
|
||||
<SidebarWorkspaceTrailingActionOverlay visible={kebab.showKebab} scrim={showScrim}>
|
||||
{kebab.showKebab && onArchive ? (
|
||||
<SidebarWorkspaceMenu
|
||||
{...kebab.menuProps}
|
||||
workspaceKey={workspace.workspaceKey}
|
||||
onCopyPath={onCopyPath}
|
||||
onCopyBranchName={onCopyBranchName}
|
||||
|
||||
@@ -71,9 +71,18 @@ export interface SidebarWorkspaceMenuProps {
|
||||
isPinned?: boolean;
|
||||
onTogglePin?: () => void;
|
||||
openInFileManagerPath?: string | null;
|
||||
/**
|
||||
* Lifted so the row that reveals the kebab can keep it mounted while its menu is up. See
|
||||
* `useOpenKebabMenuVisibility`.
|
||||
*/
|
||||
open?: boolean;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
interface SidebarWorkspaceMenuItemsProps extends Omit<SidebarWorkspaceMenuProps, "onArchive"> {
|
||||
interface SidebarWorkspaceMenuItemsProps extends Omit<
|
||||
SidebarWorkspaceMenuProps,
|
||||
"onArchive" | "open" | "onOpenChange"
|
||||
> {
|
||||
onArchive?: () => void;
|
||||
}
|
||||
|
||||
@@ -202,10 +211,12 @@ export function SidebarWorkspaceMenu({
|
||||
isPinned,
|
||||
onTogglePin,
|
||||
openInFileManagerPath,
|
||||
open,
|
||||
onOpenChange,
|
||||
}: SidebarWorkspaceMenuProps) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<DropdownMenu compactMode="sheet">
|
||||
<DropdownMenu compactMode="sheet" open={open} onOpenChange={onOpenChange}>
|
||||
<DropdownMenuTrigger
|
||||
hitSlop={8}
|
||||
style={triggerStyle}
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
SidebarWorkspaceTrailingActionOverlay,
|
||||
SidebarWorkspaceTrailingActionSlot,
|
||||
} from "@/components/sidebar/sidebar-workspace-row-content";
|
||||
import { useOpenKebabMenuVisibility } from "@/components/sidebar/use-open-kebab-menu-visibility";
|
||||
import { getSidebarRowBackdrop } from "@/components/sidebar/sidebar-row-backdrop";
|
||||
import { selectWorkspaceScriptSummary } from "@/components/sidebar/workspace-meta-row";
|
||||
import {
|
||||
@@ -420,6 +421,7 @@ function WorkspaceRowTrailingActions({
|
||||
isTouchPlatform,
|
||||
showShortcut,
|
||||
});
|
||||
const kebab = useOpenKebabMenuVisibility(showKebabInSlot);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -431,9 +433,10 @@ function WorkspaceRowTrailingActions({
|
||||
<SidebarWorkspaceTrailingActionBase visible={showTrailing}>
|
||||
<SidebarWorkspaceTrailingContent workspace={workspace} trailing={trailing} />
|
||||
</SidebarWorkspaceTrailingActionBase>
|
||||
<SidebarWorkspaceTrailingActionOverlay visible={showKebabInSlot} scrim={showScrim}>
|
||||
<SidebarWorkspaceTrailingActionOverlay visible={kebab.showKebab} scrim={showScrim}>
|
||||
{onArchive ? (
|
||||
<SidebarWorkspaceMenu
|
||||
{...kebab.menuProps}
|
||||
workspaceKey={workspace.workspaceKey}
|
||||
onCopyPath={onCopyPath}
|
||||
onCopyBranchName={onCopyBranchName}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
/**
|
||||
* Keeps a row's kebab in its slot for as long as the menu it opened is up.
|
||||
*
|
||||
* The kebab is revealed by hover, and the surface it opens can take the pointer off the row —
|
||||
* on a compact layout the sheet slides up over it. The row then reads as un-hovered, the
|
||||
* trailing overlay unmounts its own trigger mid-gesture, and the open menu is left with no
|
||||
* state that can close it: on a sheet that strands a full-screen backdrop over the app until
|
||||
* reload. Lifting the menu's open state to the component that decides whether to render it is
|
||||
* what stops the row from pulling the ground out from under it.
|
||||
*/
|
||||
export function useOpenKebabMenuVisibility(showKebab: boolean): {
|
||||
showKebab: boolean;
|
||||
menuProps: { open: boolean; onOpenChange: (open: boolean) => void };
|
||||
} {
|
||||
const [open, setOpen] = useState(false);
|
||||
const menuProps = useMemo(() => ({ open, onOpenChange: setOpen }), [open]);
|
||||
return { showKebab: showKebab || open, menuProps };
|
||||
}
|
||||
Reference in New Issue
Block a user