Skip to content

Commit dfac99a

Browse files
committed
fix(web): clarify mobile workspace active state
1 parent 11591d9 commit dfac99a

3 files changed

Lines changed: 103 additions & 6 deletions

File tree

packages/web/src/features/workspace/views/mobile/mobile-workspace-drawer.test.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,54 @@ describe("MobileWorkspaceDrawer", () => {
135135

136136
expect(onClose).toHaveBeenCalledTimes(1);
137137
});
138+
139+
it("marks the active workspace with a clear current state", () => {
140+
const store = createStore();
141+
142+
render(
143+
<Provider store={store}>
144+
<MobileWorkspaceDrawer
145+
activeWorkspaceId="ws-1"
146+
isOpen
147+
onClose={vi.fn()}
148+
onOpenWorkspaceLauncher={vi.fn()}
149+
workspaces={[
150+
{
151+
id: "ws-1",
152+
path: "/tmp/demo",
153+
targetRuntime: "native",
154+
openedAt: 1,
155+
lastActiveAt: 1,
156+
uiState: {
157+
leftPanelWidth: 320,
158+
bottomPanelHeight: 240,
159+
focusMode: false,
160+
},
161+
},
162+
{
163+
id: "ws-2",
164+
path: "/tmp/other",
165+
targetRuntime: "native",
166+
openedAt: 2,
167+
lastActiveAt: 2,
168+
uiState: {
169+
leftPanelWidth: 320,
170+
bottomPanelHeight: 240,
171+
focusMode: false,
172+
},
173+
},
174+
]}
175+
/>
176+
</Provider>
177+
);
178+
179+
expect(screen.getByRole("button", { name: "Switch to demo" })).toHaveAttribute(
180+
"aria-current",
181+
"page"
182+
);
183+
expect(screen.getByText("Current")).toBeInTheDocument();
184+
expect(screen.getByRole("button", { name: "Switch to other" })).not.toHaveAttribute(
185+
"aria-current"
186+
);
187+
});
138188
});

packages/web/src/features/workspace/views/mobile/mobile-workspace-drawer.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Workspace } from "@coder-studio/core";
22
import { useSetAtom } from "jotai";
3-
import { Plus, X } from "lucide-react";
3+
import { Check, Plus, X } from "lucide-react";
44
import { useNavigate } from "react-router-dom";
55
import { activeWorkspaceIdAtom } from "../../../../atoms/workspaces";
66
import { IconButton } from "../../../../components/ui";
@@ -63,17 +63,19 @@ export function MobileWorkspaceDrawer({
6363
<div className="mobile-workspace-drawer__list">
6464
{workspaces.map((workspace) => {
6565
const displayName = formatWorkspaceLabel(workspace) || workspace.id;
66+
const isActive = workspace.id === activeWorkspaceId;
6667

6768
return (
6869
<div
6970
key={workspace.id}
7071
className={`mobile-workspace-drawer__item ${
71-
workspace.id === activeWorkspaceId ? "mobile-workspace-drawer__item--active" : ""
72+
isActive ? "mobile-workspace-drawer__item--active" : ""
7273
}`}
7374
>
7475
<button
7576
type="button"
7677
className="mobile-workspace-drawer__item-main"
78+
aria-current={isActive ? "page" : undefined}
7779
aria-label={t("mobile.workspace_drawer.switch_to_workspace", {
7880
name: displayName,
7981
})}
@@ -83,7 +85,15 @@ export function MobileWorkspaceDrawer({
8385
onClose();
8486
}}
8587
>
86-
<span className="mobile-workspace-drawer__item-name">{displayName}</span>
88+
<span className="mobile-workspace-drawer__item-name-row">
89+
<span className="mobile-workspace-drawer__item-name">{displayName}</span>
90+
{isActive ? (
91+
<span className="mobile-workspace-drawer__item-state">
92+
<Check size={12} />
93+
<span>Current</span>
94+
</span>
95+
) : null}
96+
</span>
8797
<span className="mobile-workspace-drawer__item-path">{workspace.path}</span>
8898
</button>
8999
<IconButton

packages/web/src/styles/components.css

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9435,8 +9435,17 @@ textarea.input {
94359435
}
94369436

94379437
.mobile-workspace-drawer__item--active {
9438-
background: color-mix(in srgb, var(--accent-blue) 7%, var(--bg-panel));
9439-
box-shadow: inset 1px 0 0 color-mix(in srgb, var(--accent-blue) 48%, transparent);
9438+
background:
9439+
linear-gradient(
9440+
90deg,
9441+
color-mix(in srgb, var(--accent-blue) 12%, transparent) 0,
9442+
color-mix(in srgb, var(--accent-blue) 4%, transparent) 46%,
9443+
transparent 100%
9444+
),
9445+
color-mix(in srgb, var(--bg-panel) 92%, var(--surface-elevated));
9446+
box-shadow:
9447+
inset 0 1px 0 color-mix(in srgb, var(--accent-blue) 10%, transparent),
9448+
inset 0 -1px 0 color-mix(in srgb, var(--accent-blue) 12%, transparent);
94409449
}
94419450

94429451
.mobile-workspace-drawer__item-main {
@@ -9452,6 +9461,14 @@ textarea.input {
94529461
text-align: left;
94539462
}
94549463

9464+
.mobile-workspace-drawer__item-name-row {
9465+
display: flex;
9466+
width: 100%;
9467+
min-width: 0;
9468+
align-items: center;
9469+
gap: var(--sp-2);
9470+
}
9471+
94559472
.mobile-workspace-drawer__item-close {
94569473
display: inline-flex;
94579474
align-items: center;
@@ -9475,12 +9492,30 @@ textarea.input {
94759492
}
94769493

94779494
.mobile-workspace-drawer__item-name {
9495+
min-width: 0;
9496+
flex: 1;
94789497
color: var(--text-primary);
94799498
font-size: 12px;
94809499
font-weight: var(--font-semibold);
94819500
line-height: 1.35;
94829501
}
94839502

9503+
.mobile-workspace-drawer__item-state {
9504+
display: inline-flex;
9505+
align-items: center;
9506+
gap: 4px;
9507+
padding: 1px 6px;
9508+
border: 1px solid color-mix(in srgb, var(--accent-blue) 26%, transparent);
9509+
border-radius: 999px;
9510+
background: color-mix(in srgb, var(--accent-blue) 12%, transparent);
9511+
color: color-mix(in srgb, var(--accent-blue) 74%, var(--text-primary));
9512+
font-size: 10px;
9513+
font-weight: var(--font-semibold);
9514+
line-height: 1.2;
9515+
letter-spacing: 0.04em;
9516+
white-space: nowrap;
9517+
}
9518+
94849519
.mobile-workspace-drawer__item-path {
94859520
max-width: 100%;
94869521
overflow: hidden;
@@ -9578,7 +9613,9 @@ textarea.input {
95789613
}
95799614

95809615
.mobile-workspace-drawer__item--active {
9581-
box-shadow: inset 1px 0 0 color-mix(in srgb, var(--accent-blue) 48%, transparent);
9616+
box-shadow:
9617+
inset 0 1px 0 color-mix(in srgb, var(--accent-blue) 10%, transparent),
9618+
inset 0 -1px 0 color-mix(in srgb, var(--accent-blue) 12%, transparent);
95829619
}
95839620

95849621
.mobile-dock__item {

0 commit comments

Comments
 (0)