Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions apps/web/src/components/Sidebar.drag.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,25 @@ describe("sidebar drag projection", () => {
expect(strategy({ ...args, index: 4 })?.y).toBe(-42);
});

it("sizes an empty Active target at slim height when cards are compact", () => {
const items = [
pinnedHeader,
divider,
marker("active-placeholder"),
settledHeader,
thread("first", "settled"),
thread("second", "settled"),
];
const settledHeaderOffset = (compactCards: boolean) =>
preview(
{ items, settledOrder: ["first", "second"], settledExpanded: true, compactCards },
"first",
sidebarMarkerId("active-placeholder"),
).get(sidebarMarkerId("settled-header"))?.y;
expect(settledHeaderOffset(false)).toBe(82);
expect(settledHeaderOffset(true)).toBe(36);
});

it("keeps the route row visible after a settled drop pushes it beyond the page", () => {
const items = [
pinnedHeader,
Expand Down
9 changes: 7 additions & 2 deletions apps/web/src/components/Sidebar.drag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export function createSidebarSortingStrategy(input: {
cardHeight?: number;
slimHeight?: number;
boundaryLabelHeight?: number;
// The New design renders card rows at slim height.
compactCards?: boolean;
}): SortingStrategy {
if (input.enabled === false) return () => stationary;
const { items } = input;
Expand Down Expand Up @@ -137,9 +139,12 @@ export function createSidebarSortingStrategy(input: {
else slimHeight ??= rects[index]?.height;
if (item.key !== active.key) groups[item.section].push(item);
}
const baseCardHeight = input.compactCards ? 36 : 82;
const scale =
slimHeight !== undefined ? slimHeight / 36 : (headerScale ?? (cardHeight ?? 82) / 82);
cardHeight ??= 82 * scale;
slimHeight !== undefined
? slimHeight / 36
: (headerScale ?? (cardHeight ?? baseCardHeight) / baseCardHeight);
cardHeight ??= baseCardHeight * scale;
slimHeight ??= 36 * scale;
const labelHeight = (input.boundaryLabelHeight ?? 0) * scale;
const group = groups[target.section];
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ export default function Sidebar({ routeReveal }: { routeReveal: SidebarRouteReve
const confirmThreadDelete = useClientSettings((s) => s.confirmThreadDelete);
const confirmThreadArchive = useClientSettings((s) => s.confirmThreadArchive);
const timestampFormat = useClientSettings((s) => s.timestampFormat);
const redesignEnabled = useClientSettings((s) => s.redesignEnabled);
const projectGroupingSettings = useClientSettings(selectProjectGroupingSettings);
const {
settleThread,
Expand Down Expand Up @@ -1797,6 +1798,7 @@ export default function Sidebar({ routeReveal }: { routeReveal: SidebarRouteReve
settledVisibleCount,
routeThreadKey: routeRowThreadKey,
snoozedThreadCount: snoozedThreads.length,
compactCards: redesignEnabled,
});
const draggedThreadKey = dragState?.activeKey;
const draggedFromSection = dragState?.activeSection;
Expand Down
71 changes: 46 additions & 25 deletions apps/web/src/components/sidebar/SidebarDraftBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { cn } from "~/lib/utils";
import { resolveSidebarRowAccessibility } from "../Sidebar.logic";
import { ProjectFavicon, type ProjectFaviconProject } from "../ProjectFavicon";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { useClientSettings } from "../../hooks/useSettings";
import {
composerDraftHasUserContent,
DraftId,
Expand Down Expand Up @@ -78,8 +79,28 @@ const SidebarDraftRow = memo(function SidebarDraftRow(props: {
event.stopPropagation();
onDiscard(draftId);
};
const discardButton = (
<span className="ml-auto flex h-5 min-w-5 shrink-0 items-center justify-end">
<Tooltip>
<TooltipTrigger
render={
<button
type="button"
aria-label="Discard draft"
onClick={handleDiscard}
className="pointer-events-none inline-flex cursor-pointer items-center rounded-md bg-transparent px-1 text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:pointer-events-auto focus-visible:opacity-100 group-hover/sidebar-row:pointer-events-auto group-hover/sidebar-row:opacity-100"
>
<XIcon className="size-3" />
</button>
}
/>
<TooltipPopup side="top">Discard draft</TooltipPopup>
</Tooltip>
</span>
);
const redesign = useClientSettings((s) => s.redesignEnabled);
return (
<li className="list-none py-0.5">
<li className={cn("list-none", !redesign && "py-0.5")}>
<div
role="button"
tabIndex={0}
Expand All @@ -95,37 +116,37 @@ const SidebarDraftRow = memo(function SidebarDraftRow(props: {
onKeyDown={handleKeyDown}
>
<span className="sr-only">{preview}</span>
<div className="relative z-10 h-[4.875rem] px-(--sidebar-row-content-inset) py-(--sidebar-content-inset)">
<div className="flex h-5 min-w-0 items-center gap-1.5">
{redesign ? (
<div className="relative z-10 flex h-9 min-w-0 items-center gap-2.5 px-2.5">
<SquarePenIcon aria-hidden className={draftPenClassName} />
{props.project ? (
<ProjectFavicon project={props.project} className="size-4 shrink-0" />
) : null}
<span className="min-w-0 flex-1 truncate text-xs font-medium text-secondary-label">
{props.projectDisplayName}
</span>
<span className="ml-auto flex h-5 min-w-5 shrink-0 items-center justify-end">
<Tooltip>
<TooltipTrigger
render={
<button
type="button"
aria-label="Discard draft"
onClick={handleDiscard}
className="pointer-events-none inline-flex cursor-pointer items-center rounded-md bg-transparent px-1 text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:pointer-events-auto focus-visible:opacity-100 group-hover/sidebar-row:pointer-events-auto group-hover/sidebar-row:opacity-100"
>
<XIcon className="size-3" />
</button>
}
/>
<TooltipPopup side="top">Discard draft</TooltipPopup>
</Tooltip>
<span
aria-hidden
className="min-w-0 flex-1 truncate text-sm font-medium text-foreground"
>
{preview}
</span>
{discardButton}
</div>
<div aria-hidden className="mt-0.5 truncate text-sm font-medium text-foreground/90">
{preview}
) : (
<div className="relative z-10 h-[4.875rem] px-(--sidebar-row-content-inset) py-(--sidebar-content-inset)">
<div className="flex h-5 min-w-0 items-center gap-1.5">
<SquarePenIcon aria-hidden className={draftPenClassName} />
{props.project ? (
<ProjectFavicon project={props.project} className="size-4 shrink-0" />
) : null}
<span className="min-w-0 flex-1 truncate text-xs font-medium text-secondary-label">
{props.projectDisplayName}
</span>
{discardButton}
</div>
<div aria-hidden className="mt-0.5 truncate text-sm font-medium text-foreground/90">
{preview}
</div>
</div>
</div>
)}
</div>
</li>
);
Expand Down
Loading
Loading