History

fix(web): offer browser profiles from the empty-panel launcher (#9279)

Julius Marminge committed 2 months ago

Commit 064392f1 parent b59b7d01 file · +69 −17Browse files

Unified · Split

apps/web/src/components/RightPanelTabs.tsx+69−17
@@ -8,6 +8,7 @@ import type { · 7 unmodified lines
88 import { getTerminalLabel } from "@t3tools/shared/terminalLabels";
99 import {
1010 Bot,
11+ ChevronDown,
1112 FileDiff,
1213 Files,
1314 GitPullRequest,
@@ -283,6 +284,8 @@ function SurfaceMenuItem(props: { · 269 unmodified lines
283284 */
284285 function RightPanelEmptyState(props: {
285286 onAddBrowser: () => void;
287+ onAddBrowserInProfile: (profileId: string) => void;
288+ browserProfiles: ReadonlyArray<{ readonly id: string; readonly name: string }>;
286289 onAddTerminal: () => void;
287290 onAddDiff: () => void;
288291 onAddFiles: () => void;
@@ -473,31 +476,78 @@ function RightPanelEmptyState(props: { · 184 unmodified lines
473476 <div className="grid grid-cols-2 gap-2">
474477 {actions.map((action) =>
475478 action.available ? (
476− <button
479+ // The card is itself a button, so the profile chooser sits beside
480+ // it in a wrapper rather than inside it. Hover lives on the
481+ // wrapper: the chooser overlays the card, and a pointer moving
482+ // onto it must not read as leaving the card.
483+ <div
477484 key={action.label}
478− type="button"
479− onClick={action.onClick}
485+ className="group relative"
480486 onMouseEnter={() => setHighlight(availableActions.indexOf(action))}
481487 onMouseLeave={() =>
482488 setHighlight((current) =>
483489 current === availableActions.indexOf(action) ? -1 : current,
484490 )
485491 }
486− className={cn(
487− "relative flex w-full cursor-pointer flex-col items-start p-4 text-left transition hover:border-border hover:bg-accent/60",
488− cardShellClass,
489− isHighlighted(action) && highlightedCardClass,
490− )}
491492 >
492− <Kbd className="absolute top-3 right-3">{action.shortcut}</Kbd>
493− <span className="flex items-center gap-2 pe-8">
494− {actionIcon(action)}
495− <span className="font-medium text-sm">{action.label}</span>
496− </span>
497− <span className="mt-1.5 text-muted-foreground text-xs leading-relaxed">
498− {action.description}
499− </span>
500− </button>
493+ <button
494+ type="button"
495+ onClick={action.onClick}
496+ className={cn(
497+ // Full height: the wrapper is the grid item that stretches
498+ // to the row, so the button must fill it to stay level with
499+ // its neighbour and keep the chooser anchored inside.
500+ "relative flex h-full w-full cursor-pointer flex-col items-start p-4 text-left transition group-hover:border-border group-hover:bg-accent/60",
501+ cardShellClass,
502+ isHighlighted(action) && highlightedCardClass,
503+ )}
504+ >
505+ <Kbd className="absolute top-3 right-3">{action.shortcut}</Kbd>
506+ <span className="flex items-center gap-2 pe-8">
507+ {actionIcon(action)}
508+ <span className="font-medium text-sm">{action.label}</span>
509+ </span>
510+ <span className="mt-1.5 text-muted-foreground text-xs leading-relaxed">
511+ {action.description}
512+ </span>
513+ </button>
514+ {/*
515+ Same choice the tab bar's "+" menu offers: the card opens the
516+ default profile, the chevron picks another. Only worth showing
517+ once there is something to choose between.
518+ */}
519+ {action.label === "Browser" && props.browserProfiles.length > 1 ? (
520+ <Menu>
521+ <MenuTrigger
522+ render={
523+ <Button
524+ aria-label="Open browser in a profile"
525+ className="absolute right-3 bottom-3 [--control-icon-color:currentColor]"
526+ size="icon-xs"
527+ variant="ghost-muted"
528+ />
529+ }
530+ >
531+ <ChevronDown className="size-3.5" />
532+ </MenuTrigger>
533+ <MenuPopup
534+ align="end"
535+ side="bottom"
536+ sideOffset={6}
537+ className="min-w-40 max-w-56"
538+ >
539+ {props.browserProfiles.map((profile) => (
540+ <MenuItem
541+ key={profile.id}
542+ onClick={() => props.onAddBrowserInProfile(profile.id)}
543+ >
544+ <span className="min-w-0 truncate">{profile.name}</span>
545+ </MenuItem>
546+ ))}
547+ </MenuPopup>
548+ </Menu>
549+ ) : null}
550+ </div>
501551 ) : (
502552 <div
503553 key={action.label}
@@ -1053,6 +1103,8 @@ export function RightPanelTabs(props: RightPanelTabsProps) { · 549 unmodified lines
10531103 {props.activeSurfaceId === null ? (
10541104 <RightPanelEmptyState
10551105 onAddBrowser={props.onAddBrowser}
1106+ onAddBrowserInProfile={props.onAddBrowserInProfile}
1107+ browserProfiles={browserProfiles}
10561108 onAddTerminal={props.onAddTerminal}
10571109 onAddDiff={props.onAddDiff}
10581110 onAddFiles={props.onAddFiles}