Skip to content

Commit a6e85f0

Browse files
authored
Side menu and Org dropdown improvements (#1801)
* Organize imports * Removes animation on the dropdown menu icon * Improves Settings and Usage button states * Side menu sections animate with easeInOut * Incorporates docs button into the text and adds title to the clipboard field * Icons look better as the small variant * Improved the typography layout of the org name and small links * Made the divide line show when the side menu scrolls * Made the impersonating icon amber so it stands out more * Adds an optional amber border to the org dropdown
1 parent f713b1e commit a6e85f0

File tree

7 files changed

+87
-83
lines changed

7 files changed

+87
-83
lines changed

apps/webapp/app/components/ImpersonationBanner.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1+
import { UserMinusIcon } from "@heroicons/react/20/solid";
12
import { Form } from "@remix-run/react";
2-
import { Paragraph } from "./primitives/Paragraph";
33
import { Button } from "./primitives/Buttons";
4-
import { UserMinusIcon } from "@heroicons/react/20/solid";
54

65
export function ImpersonationBanner() {
76
return (
@@ -13,6 +12,7 @@ export function ImpersonationBanner() {
1312
LeadingIcon={UserMinusIcon}
1413
fullWidth
1514
textAlignLeft
15+
className="text-amber-400"
1616
>
1717
Stop impersonating
1818
</Button>

apps/webapp/app/components/SetupCommands.tsx

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from "./primitives/ClientTabs";
1111
import { ClipboardField } from "./primitives/ClipboardField";
1212
import { Paragraph } from "./primitives/Paragraph";
13+
import { Header3 } from "./primitives/Headers";
1314

1415
type PackageManagerContextType = {
1516
activePackageManager: string;
@@ -61,7 +62,12 @@ function getApiUrlArg() {
6162
return apiUrl ? `-a ${apiUrl}` : undefined;
6263
}
6364

64-
export function InitCommandV3() {
65+
// Add title prop to the component interfaces
66+
type TabsProps = {
67+
title?: string;
68+
};
69+
70+
export function InitCommandV3({ title }: TabsProps) {
6571
const project = useProject();
6672
const projectRef = project.externalRef;
6773
const apiUrlArg = getApiUrlArg();
@@ -77,30 +83,33 @@ export function InitCommandV3() {
7783
value={activePackageManager}
7884
onValueChange={setActivePackageManager}
7985
>
80-
<ClientTabsList>
81-
<ClientTabsTrigger value={"npm"}>npm</ClientTabsTrigger>
82-
<ClientTabsTrigger value={"pnpm"}>pnpm</ClientTabsTrigger>
83-
<ClientTabsTrigger value={"yarn"}>yarn</ClientTabsTrigger>
84-
</ClientTabsList>
86+
<div className="flex items-center gap-4">
87+
{title && <span>{title}</span>}
88+
<ClientTabsList className={title ? "ml-auto" : ""}>
89+
<ClientTabsTrigger value={"npm"}>npm</ClientTabsTrigger>
90+
<ClientTabsTrigger value={"pnpm"}>pnpm</ClientTabsTrigger>
91+
<ClientTabsTrigger value={"yarn"}>yarn</ClientTabsTrigger>
92+
</ClientTabsList>
93+
</div>
8594
<ClientTabsContent value={"npm"}>
8695
<ClipboardField
87-
variant="primary/medium"
96+
variant="secondary/medium"
8897
iconButton
8998
className="mb-4"
9099
value={`npx ${initCommand}`}
91100
/>
92101
</ClientTabsContent>
93102
<ClientTabsContent value={"pnpm"}>
94103
<ClipboardField
95-
variant="primary/medium"
104+
variant="secondary/medium"
96105
iconButton
97106
className="mb-4"
98107
value={`pnpm dlx ${initCommand}`}
99108
/>
100109
</ClientTabsContent>
101110
<ClientTabsContent value={"yarn"}>
102111
<ClipboardField
103-
variant="primary/medium"
112+
variant="secondary/medium"
104113
iconButton
105114
className="mb-4"
106115
value={`yarn dlx ${initCommand}`}
@@ -110,7 +119,7 @@ export function InitCommandV3() {
110119
);
111120
}
112121

113-
export function TriggerDevStepV3() {
122+
export function TriggerDevStepV3({ title }: TabsProps) {
114123
const { activePackageManager, setActivePackageManager } = usePackageManager();
115124

116125
return (
@@ -119,30 +128,33 @@ export function TriggerDevStepV3() {
119128
value={activePackageManager}
120129
onValueChange={setActivePackageManager}
121130
>
122-
<ClientTabsList>
123-
<ClientTabsTrigger value={"npm"}>npm</ClientTabsTrigger>
124-
<ClientTabsTrigger value={"pnpm"}>pnpm</ClientTabsTrigger>
125-
<ClientTabsTrigger value={"yarn"}>yarn</ClientTabsTrigger>
126-
</ClientTabsList>
131+
<div className="flex items-center gap-4">
132+
{title && <Header3>{title}</Header3>}
133+
<ClientTabsList className={title ? "ml-auto" : ""}>
134+
<ClientTabsTrigger value={"npm"}>npm</ClientTabsTrigger>
135+
<ClientTabsTrigger value={"pnpm"}>pnpm</ClientTabsTrigger>
136+
<ClientTabsTrigger value={"yarn"}>yarn</ClientTabsTrigger>
137+
</ClientTabsList>
138+
</div>
127139
<ClientTabsContent value={"npm"}>
128140
<ClipboardField
129-
variant="primary/medium"
141+
variant="secondary/medium"
130142
iconButton
131143
className="mb-4"
132144
value={`npx trigger.dev@${v3PackageTag} dev`}
133145
/>
134146
</ClientTabsContent>
135147
<ClientTabsContent value={"pnpm"}>
136148
<ClipboardField
137-
variant="primary/medium"
149+
variant="secondary/medium"
138150
iconButton
139151
className="mb-4"
140152
value={`pnpm dlx trigger.dev@${v3PackageTag} dev`}
141153
/>
142154
</ClientTabsContent>
143155
<ClientTabsContent value={"yarn"}>
144156
<ClipboardField
145-
variant="primary/medium"
157+
variant="secondary/medium"
146158
iconButton
147159
className="mb-4"
148160
value={`yarn dlx trigger.dev@${v3PackageTag} dev`}
@@ -152,7 +164,7 @@ export function TriggerDevStepV3() {
152164
);
153165
}
154166

155-
export function TriggerLoginStepV3() {
167+
export function TriggerLoginStepV3({ title }: TabsProps) {
156168
const { activePackageManager, setActivePackageManager } = usePackageManager();
157169

158170
return (
@@ -161,30 +173,33 @@ export function TriggerLoginStepV3() {
161173
value={activePackageManager}
162174
onValueChange={setActivePackageManager}
163175
>
164-
<ClientTabsList>
165-
<ClientTabsTrigger value={"npm"}>npm</ClientTabsTrigger>
166-
<ClientTabsTrigger value={"pnpm"}>pnpm</ClientTabsTrigger>
167-
<ClientTabsTrigger value={"yarn"}>yarn</ClientTabsTrigger>
168-
</ClientTabsList>
176+
<div className="flex items-center gap-4">
177+
{title && <span>{title}</span>}
178+
<ClientTabsList className={title ? "ml-auto" : ""}>
179+
<ClientTabsTrigger value={"npm"}>npm</ClientTabsTrigger>
180+
<ClientTabsTrigger value={"pnpm"}>pnpm</ClientTabsTrigger>
181+
<ClientTabsTrigger value={"yarn"}>yarn</ClientTabsTrigger>
182+
</ClientTabsList>
183+
</div>
169184
<ClientTabsContent value={"npm"}>
170185
<ClipboardField
171-
variant="primary/medium"
186+
variant="secondary/medium"
172187
iconButton
173188
className="mb-4"
174189
value={`npx trigger.dev@${v3PackageTag} login`}
175190
/>
176191
</ClientTabsContent>
177192
<ClientTabsContent value={"pnpm"}>
178193
<ClipboardField
179-
variant="primary/medium"
194+
variant="secondary/medium"
180195
iconButton
181196
className="mb-4"
182197
value={`pnpm dlx trigger.dev@${v3PackageTag} login`}
183198
/>
184199
</ClientTabsContent>
185200
<ClientTabsContent value={"yarn"}>
186201
<ClipboardField
187-
variant="primary/medium"
202+
variant="secondary/medium"
188203
iconButton
189204
className="mb-4"
190205
value={`yarn dlx trigger.dev@${v3PackageTag} login`}

apps/webapp/app/components/navigation/EnvironmentSelector.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { useNavigation } from "@remix-run/react";
22
import { useEffect, useState } from "react";
33
import { useEnvironmentSwitcher } from "~/hooks/useEnvironmentSwitcher";
4+
import { useFeatures } from "~/hooks/useFeatures";
45
import { type MatchedOrganization } from "~/hooks/useOrganizations";
6+
import { cn } from "~/utils/cn";
7+
import { v3BillingPath } from "~/utils/pathBuilder";
58
import { EnvironmentCombo } from "../environments/EnvironmentLabel";
69
import {
710
Popover,
@@ -11,10 +14,6 @@ import {
1114
PopoverSectionHeader,
1215
} from "../primitives/Popover";
1316
import { type SideMenuEnvironment, type SideMenuProject } from "./SideMenu";
14-
import { cn } from "~/utils/cn";
15-
import { useFeatures } from "~/hooks/useFeatures";
16-
import { v3BillingPath } from "~/utils/pathBuilder";
17-
import { TextLink } from "../primitives/TextLink";
1817

1918
export function EnvironmentSelector({
2019
organization,

apps/webapp/app/components/navigation/SideMenu.tsx

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,11 @@ import {
5656
v3TestPath,
5757
v3UsagePath,
5858
} from "~/utils/pathBuilder";
59-
import { useDevPresence } from "../DevPresence";
60-
import { ImpersonationBanner } from "../ImpersonationBanner";
61-
import { PackageManagerProvider, TriggerDevStepV3 } from "../SetupCommands";
62-
import { UserProfilePhoto } from "../UserProfilePhoto";
6359
import connectedImage from "../../assets/images/cli-connected.png";
6460
import disconnectedImage from "../../assets/images/cli-disconnected.png";
6561
import { FreePlanUsage } from "../billing/FreePlanUsage";
62+
import { useDevPresence } from "../DevPresence";
63+
import { ImpersonationBanner } from "../ImpersonationBanner";
6664
import { Button, ButtonContent, LinkButton } from "../primitives/Buttons";
6765
import {
6866
Dialog,
@@ -80,18 +78,15 @@ import {
8078
PopoverTrigger,
8179
} from "../primitives/Popover";
8280
import { TextLink } from "../primitives/TextLink";
81+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../primitives/Tooltip";
82+
import { PackageManagerProvider, TriggerDevStepV3 } from "../SetupCommands";
83+
import { UserProfilePhoto } from "../UserProfilePhoto";
8384
import { EnvironmentSelector } from "./EnvironmentSelector";
8485
import { HelpAndFeedback } from "./HelpAndFeedbackPopover";
8586
import { SideMenuHeader } from "./SideMenuHeader";
8687
import { SideMenuItem } from "./SideMenuItem";
8788
import { SideMenuSection } from "./SideMenuSection";
88-
import {
89-
SimpleTooltip,
90-
Tooltip,
91-
TooltipContent,
92-
TooltipProvider,
93-
TooltipTrigger,
94-
} from "../primitives/Tooltip";
89+
import { InlineCode } from "../code/InlineCode";
9590

9691
type SideMenuUser = Pick<User, "email" | "admin"> & { isImpersonating: boolean };
9792
export type SideMenuProject = Pick<
@@ -144,8 +139,8 @@ export function SideMenu({
144139
>
145140
<div
146141
className={cn(
147-
"flex items-center justify-between px-1 py-1 transition",
148-
showHeaderDivider ? " border-grid-bright" : "border-transparent"
142+
"flex items-center justify-between border-b px-1 py-1 transition duration-300",
143+
showHeaderDivider ? "border-grid-bright" : "border-transparent"
149144
)}
150145
>
151146
<ProjectSelector
@@ -303,7 +298,10 @@ function ProjectSelector({
303298
<PopoverArrowTrigger
304299
isOpen={isOrgMenuOpen}
305300
overflowHidden
306-
className="h-8 w-full justify-between overflow-hidden py-1 pl-1.5"
301+
className={cn(
302+
"h-8 w-full justify-between overflow-hidden py-1 pl-1.5",
303+
user.isImpersonating && "border border-dashed border-amber-400"
304+
)}
307305
>
308306
<span className="flex items-center gap-1.5 overflow-hidden">
309307
<Avatar avatar={organization.avatar} className="size-5" />
@@ -320,25 +318,26 @@ function ProjectSelector({
320318
>
321319
<div className="flex flex-col gap-2 bg-charcoal-750 p-2">
322320
<div className="flex items-center gap-2.5">
323-
<div className="box-content size-10 overflow-clip rounded-sm border border-charcoal-700 bg-charcoal-850">
321+
<div className="box-content size-10 overflow-clip rounded-sm bg-charcoal-800">
324322
<Avatar avatar={organization.avatar} className="size-10" includePadding />
325323
</div>
326324
<div className="space-y-0.5">
327-
<Paragraph variant="extra-small/bright">{organization.title}</Paragraph>
328-
<div className="flex items-baseline">
325+
<Paragraph variant="small/bright">{organization.title}</Paragraph>
326+
<div className="flex items-baseline gap-2">
329327
{plan && (
330-
<Paragraph variant="extra-small">
331-
<TextLink variant="secondary" to={v3BillingPath(organization)}>
332-
{plan}
333-
</TextLink>
334-
</Paragraph>
335-
)}
336-
<Paragraph variant="extra-small">
337328
<TextLink
338329
variant="secondary"
339-
to={organizationTeamPath(organization)}
340-
>{simplur`${organization.membersCount} member[|s]`}</TextLink>
341-
</Paragraph>
330+
className="text-xs"
331+
to={v3BillingPath(organization)}
332+
>
333+
{plan}
334+
</TextLink>
335+
)}
336+
<TextLink
337+
variant="secondary"
338+
className="text-xs"
339+
to={organizationTeamPath(organization)}
340+
>{simplur`${organization.membersCount} member[|s]`}</TextLink>
342341
</div>
343342
</div>
344343
</div>
@@ -348,6 +347,7 @@ function ProjectSelector({
348347
to={organizationSettingsPath(organization)}
349348
fullWidth
350349
iconSpacing="gap-1.5"
350+
className="group-hover/button:border-charcoal-500"
351351
>
352352
<CogIcon className="size-4 text-text-dimmed" />
353353
<span className="text-text-bright">Settings</span>
@@ -357,6 +357,7 @@ function ProjectSelector({
357357
to={v3UsagePath(organization)}
358358
fullWidth
359359
iconSpacing="gap-1.5"
360+
className="group-hover/button:border-charcoal-500"
360361
>
361362
<ChartBarIcon className="size-4 text-text-dimmed" />
362363
<span className="text-text-bright">Usage</span>
@@ -550,9 +551,7 @@ export function DevConnection() {
550551
</div>
551552
<DialogContent>
552553
<DialogHeader>
553-
{isConnected
554-
? "Your dev server is connected to Trigger.dev"
555-
: "Your dev server is not connected to Trigger.dev"}
554+
{isConnected ? "Your dev server is connected" : "Your dev server is not connected"}
556555
</DialogHeader>
557556
<div className="mt-2 flex flex-col gap-3 px-2">
558557
<div className="flex flex-col items-center justify-center gap-6 px-6 py-10">
@@ -571,20 +570,17 @@ export function DevConnection() {
571570
{isConnected ? null : (
572571
<div className="space-y-3">
573572
<PackageManagerProvider>
574-
<TriggerDevStepV3 />
573+
<TriggerDevStepV3 title="Run this command to connect" />
575574
</PackageManagerProvider>
576575
<Paragraph variant="small">
577-
Run this CLI `dev` command to connect to the Trigger.dev servers to start developing
578-
locally. Keep it running while you develop to stay connected.
576+
Run this CLI <InlineCode variant="extra-small">dev</InlineCode> command to connect
577+
to the Trigger.dev servers to start developing locally. Keep it running while you
578+
develop to stay connected. Learn more in the{" "}
579+
<TextLink to={docsPath("cli-dev")}>CLI docs</TextLink>.
579580
</Paragraph>
580581
</div>
581582
)}
582583
</div>
583-
<DialogFooter>
584-
<LinkButton variant="tertiary/medium" LeadingIcon={BookOpenIcon} to={docsPath("cli-dev")}>
585-
CLI docs
586-
</LinkButton>
587-
</DialogFooter>
588584
</DialogContent>
589585
</Dialog>
590586
);

apps/webapp/app/components/navigation/SideMenuSection.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ export function SideMenuSection({
5050
expanded: {
5151
height: "auto",
5252
transition: {
53-
height: { duration: 0.3, ease: "easeOut" },
53+
height: { duration: 0.3, ease: "easeInOut" },
5454
},
5555
},
5656
collapsed: {
5757
height: 0,
5858
transition: {
59-
height: { duration: 0.2, ease: "easeIn" },
59+
height: { duration: 0.2, ease: "easeInOut" },
6060
},
6161
},
6262
}}
@@ -67,12 +67,12 @@ export function SideMenuSection({
6767
expanded: {
6868
translateY: 0,
6969
opacity: 1,
70-
transition: { duration: 0.3, ease: "easeOut" },
70+
transition: { duration: 0.3, ease: "easeInOut" },
7171
},
7272
collapsed: {
7373
translateY: "-100%",
7474
opacity: 0,
75-
transition: { duration: 0.2, ease: "easeIn" },
75+
transition: { duration: 0.2, ease: "easeInOut" },
7676
},
7777
}}
7878
>

0 commit comments

Comments
 (0)