Skip to content

Commit af2ef87

Browse files
committed
docs: add mobile files content alignment plan
1 parent 02d3c76 commit af2ef87

1 file changed

Lines changed: 355 additions & 0 deletions

File tree

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
# Mobile Files Content PC Alignment Implementation Plan
2+
3+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4+
5+
**Goal:** Restyle the mobile workspace files content area so its tabs, actions, search, file tree, and Git list align with the flat PC sidebar language while preserving mobile touch sizing and existing behavior.
6+
7+
**Architecture:** Keep the current `MobileFilesSheet`, `FileTreePanel`, and `GitPanel` structure, then tighten the mobile-only CSS scopes so the content area reuses PC sidebar semantics instead of the current floating card language. Lock the redesign in stylesheet tests first, then update the scoped mobile selectors in `components.css`, and finally rerun the targeted mobile files tests to verify behavior did not regress.
8+
9+
**Tech Stack:** TypeScript, React, Vitest, Testing Library, vanilla CSS custom properties
10+
11+
**Spec reference:** `docs/superpowers/specs/2026-05-18-mobile-files-content-pc-alignment-design.md`
12+
13+
---
14+
15+
## File Structure
16+
17+
- Modify: `packages/web/src/styles/components.theme.test.ts`
18+
- Replace the current mobile files surface assertions with the new flat-panel contract.
19+
- Modify: `packages/web/src/features/workspace/views/mobile/mobile-files-sheet.test.tsx`
20+
- Keep the current structural assertions aligned if header wrappers or class expectations shift.
21+
- Modify: `packages/web/src/styles/components.css`
22+
- Rewrite the scoped mobile files content selectors to align tabs, actions, search, file tree, and Git mobile surfaces with PC sidebar language.
23+
- Modify: `packages/web/src/features/workspace/views/mobile/mobile-files-sheet.tsx`
24+
- Only if needed for a lightweight header wrapper that improves tab/actions alignment without changing behavior.
25+
26+
## Task 1: Lock The New Mobile Files Style Contract In Tests
27+
28+
**Files:**
29+
- Modify: `packages/web/src/styles/components.theme.test.ts`
30+
- Test: `packages/web/src/styles/components.theme.test.ts`
31+
32+
- [ ] **Step 1: Write the failing mobile files content style assertions**
33+
34+
Update the mobile workspace home-screen style test in `packages/web/src/styles/components.theme.test.ts` so it captures the new files content language:
35+
36+
```ts
37+
const mobileFilesSurface = getLastRuleBlock(".mobile-sheet--files .file-tree-shell--mobile");
38+
const mobileFilesGitSurface = getLastRuleBlock(".mobile-sheet--files .git-panel--mobile");
39+
const mobileFilesSegmented = getLastRuleBlock(".mobile-files-sheet__segmented");
40+
const mobileFilesSegment = getLastRuleBlock(".mobile-files-sheet__segment");
41+
const mobileFilesSegmentActive = getLastRuleBlock(".mobile-files-sheet__segment.active");
42+
const mobileFilesSegmentIndicator = getLastRuleBlock(".mobile-files-sheet__segment.active::after");
43+
const mobileFilesTabAction = getLastRuleBlock(".mobile-files-sheet__tab-action");
44+
const mobileFileSearch = getLastRuleBlock(".file-tree-shell--mobile .file-tree-search");
45+
const mobileFileRow = getLastRuleBlock(".file-tree-shell--mobile .tree-item");
46+
const mobileFileRowSelected = getLastRuleBlock(".file-tree-shell--mobile .tree-item.selected");
47+
48+
expect(mobileFilesSegmented).toContain("border-bottom: 1px solid color-mix(in srgb, var(--border) 78%, transparent)");
49+
expect(mobileFilesSegmented).toContain("border-radius: 0");
50+
expect(mobileFilesSegmented).not.toContain("linear-gradient(");
51+
expect(mobileFilesSegmented).not.toContain("box-shadow:");
52+
53+
expect(mobileFilesSegment).toContain("padding: 0");
54+
expect(mobileFilesSegment).toContain("font-weight: var(--type-label-weight)");
55+
expect(mobileFilesSegmentActive).toContain("background: transparent");
56+
expect(mobileFilesSegmentIndicator).toContain("height: 1.5px");
57+
58+
expect(mobileFilesTabAction).toContain("border: none");
59+
expect(mobileFilesTabAction).toContain("border-radius: 6px");
60+
expect(mobileFilesTabAction).toContain("background: transparent");
61+
62+
expect(mobileFilesSurface).toContain("border: 1px solid color-mix(in srgb, var(--border) 80%, transparent)");
63+
expect(mobileFilesSurface).toContain("border-radius: var(--radius-md)");
64+
expect(mobileFilesSurface).not.toContain("box-shadow:");
65+
expect(mobileFilesSurface).not.toContain("linear-gradient(");
66+
67+
expect(mobileFilesGitSurface).toContain("border: 1px solid color-mix(in srgb, var(--border) 80%, transparent)");
68+
expect(mobileFilesGitSurface).toContain("border-radius: var(--radius-md)");
69+
expect(mobileFilesGitSurface).not.toContain("box-shadow:");
70+
71+
expect(mobileFileSearch).toContain("margin: 0");
72+
expect(mobileFileSearch).toContain("border-radius: 0");
73+
expect(mobileFileSearch).toContain("border-right: none");
74+
expect(mobileFileSearch).toContain("border-left: none");
75+
expect(mobileFileSearch).toContain("background: transparent");
76+
77+
expect(mobileFileRow).toContain("min-height: 40px");
78+
expect(mobileFileRow).toContain("border-radius: 0");
79+
expect(mobileFileRowSelected).toContain("border-left: 2px solid color-mix(in srgb, var(--accent-blue) 88%, white 12%)");
80+
```
81+
82+
- [ ] **Step 2: Run the style test to verify it fails**
83+
84+
Run:
85+
86+
```bash
87+
pnpm --filter @coder-studio/web exec vitest run src/styles/components.theme.test.ts
88+
```
89+
90+
Expected:
91+
92+
- FAIL because the current mobile files selectors still use rounded segmented chrome, circular actions, and floating-card surfaces
93+
94+
- [ ] **Step 3: Commit nothing yet**
95+
96+
Do not stage or commit after the red run. The next task will make the code pass.
97+
98+
## Task 2: Flatten The Mobile Files Header And Content Surfaces
99+
100+
**Files:**
101+
- Modify: `packages/web/src/styles/components.css`
102+
- Modify: `packages/web/src/features/workspace/views/mobile/mobile-files-sheet.tsx` (only if layout wrapper is needed)
103+
- Test: `packages/web/src/styles/components.theme.test.ts`
104+
105+
- [ ] **Step 1: Update the mobile files header styles to match the PC sidebar language**
106+
107+
In `packages/web/src/styles/components.css`, replace the existing `.mobile-files-sheet__segmented`, `.mobile-files-sheet__segment`, `.mobile-files-sheet__tab-actions`, and `.mobile-files-sheet__tab-action` block bodies with this contract:
108+
109+
```css
110+
.mobile-files-sheet__segmented {
111+
display: flex;
112+
align-items: center;
113+
flex-shrink: 0;
114+
gap: var(--sp-3);
115+
padding: 0 0 var(--sp-2);
116+
border-bottom: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
117+
border-radius: 0;
118+
background: transparent;
119+
box-shadow: none;
120+
}
121+
122+
.mobile-files-sheet__segment {
123+
position: relative;
124+
display: inline-flex;
125+
align-items: center;
126+
justify-content: flex-start;
127+
gap: 6px;
128+
min-height: 32px;
129+
padding: 0;
130+
border: none;
131+
border-radius: 0;
132+
background: transparent;
133+
color: var(--text-tertiary);
134+
font-size: var(--type-label-size);
135+
line-height: var(--type-label-line-height);
136+
font-weight: var(--type-label-weight);
137+
transition: color var(--duration-fast) var(--ease-out);
138+
}
139+
140+
.mobile-files-sheet__segment.active {
141+
background: transparent;
142+
color: var(--text-primary);
143+
}
144+
145+
.mobile-files-sheet__segment.active::after {
146+
content: "";
147+
position: absolute;
148+
right: 0;
149+
bottom: -10px;
150+
left: 0;
151+
height: 1.5px;
152+
border-radius: 999px;
153+
background: color-mix(in srgb, var(--accent-blue) 90%, white 10%);
154+
}
155+
156+
.mobile-files-sheet__tab-actions {
157+
display: inline-flex;
158+
align-items: center;
159+
gap: 4px;
160+
flex-shrink: 0;
161+
margin-left: auto;
162+
}
163+
164+
.mobile-files-sheet__tab-action {
165+
display: inline-flex;
166+
align-items: center;
167+
justify-content: center;
168+
width: 32px;
169+
height: 32px;
170+
padding: 0;
171+
border: none;
172+
border-radius: 6px;
173+
background: transparent;
174+
color: var(--text-tertiary);
175+
transition:
176+
background-color var(--duration-fast) var(--ease-out),
177+
color var(--duration-fast) var(--ease-out);
178+
}
179+
```
180+
181+
- [ ] **Step 2: Update the mobile-only files surfaces to remove the floating-card shell**
182+
183+
In the `.mobile-sheet--files` section of `packages/web/src/styles/components.css`, rewrite the shared mobile files surface selector:
184+
185+
```css
186+
.mobile-sheet--files .file-tree-shell--mobile,
187+
.mobile-sheet--files .git-panel--mobile,
188+
.mobile-sheet--files .workspace-git-editor,
189+
.mobile-sheet--files .workspace-git-view {
190+
overflow: hidden;
191+
border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
192+
border-radius: var(--radius-md);
193+
background: var(--bg-panel);
194+
box-shadow: none;
195+
}
196+
```
197+
198+
Keep the existing exclusions for code-editor and diff wrappers unchanged.
199+
200+
- [ ] **Step 3: Align the mobile file-tree search and row styling with the PC sidebar**
201+
202+
In the `file-tree-shell--mobile` section of `packages/web/src/styles/components.css`, keep the touch-friendly height but flatten the presentation:
203+
204+
```css
205+
.file-tree-shell--mobile .file-tree-search {
206+
margin: 0;
207+
border-right: none;
208+
border-left: none;
209+
border-radius: 0;
210+
padding-inline: 12px;
211+
background: transparent;
212+
}
213+
214+
.file-tree-shell--mobile .file-tree {
215+
padding-bottom: 10px;
216+
}
217+
218+
.file-tree-shell--mobile .tree-item {
219+
min-height: 40px;
220+
margin: 0;
221+
border-radius: 0;
222+
padding-top: 8px;
223+
padding-bottom: 8px;
224+
}
225+
226+
.file-tree-shell--mobile .tree-item.selected {
227+
padding-left: 14px;
228+
border-left: 2px solid color-mix(in srgb, var(--accent-blue) 88%, white 12%);
229+
background: color-mix(in srgb, var(--accent-blue) 12%, transparent);
230+
}
231+
```
232+
233+
- [ ] **Step 4: Re-run the style test to verify it passes**
234+
235+
Run:
236+
237+
```bash
238+
pnpm --filter @coder-studio/web exec vitest run src/styles/components.theme.test.ts
239+
```
240+
241+
Expected:
242+
243+
- PASS for the updated mobile files surface assertions
244+
- PASS for existing unrelated theme-sensitive surface assertions
245+
246+
- [ ] **Step 5: Commit the style implementation**
247+
248+
```bash
249+
git add packages/web/src/styles/components.css packages/web/src/styles/components.theme.test.ts
250+
git commit -m "feat(web): align mobile files content with pc sidebar"
251+
```
252+
253+
## Task 3: Verify Mobile Files Behavior Did Not Regress
254+
255+
**Files:**
256+
- Modify: `packages/web/src/features/workspace/views/mobile/mobile-files-sheet.test.tsx` (only if needed)
257+
- Test: `packages/web/src/features/workspace/views/mobile/mobile-files-sheet.test.tsx`
258+
259+
- [ ] **Step 1: Review the current mobile files sheet structure tests**
260+
261+
Open `packages/web/src/features/workspace/views/mobile/mobile-files-sheet.test.tsx` and confirm whether any selectors or wrapper assumptions changed. Only edit the test if the header layout gained a new wrapper or if class assertions need to include a new structural class.
262+
263+
- [ ] **Step 2: If needed, add a focused regression assertion for the unchanged behavior**
264+
265+
If the component structure changes, keep the behavior lock tight with a focused test like this:
266+
267+
```tsx
268+
it("keeps file actions in the same header row as the tabs after the visual refresh", async () => {
269+
const sendCommand = vi.fn().mockResolvedValue({
270+
path: "/workspace",
271+
children: [],
272+
});
273+
274+
const store = createStore();
275+
store.set(wsClientAtom, { sendCommand } as never);
276+
277+
render(
278+
<Provider store={store}>
279+
<MobileFilesSheet workspaceId="ws-test" route={{ kind: "root" }} activeTab="files" />
280+
</Provider>
281+
);
282+
283+
const tabList = screen.getByRole("tablist", { name: "Files tabs" });
284+
const newFileButton = await screen.findByRole("button", { name: "New File" });
285+
286+
expect(tabList.closest(".mobile-files-sheet__segmented")).toBe(
287+
newFileButton.closest(".mobile-files-sheet__segmented")
288+
);
289+
});
290+
```
291+
292+
- [ ] **Step 3: Run the targeted mobile files tests**
293+
294+
Run:
295+
296+
```bash
297+
pnpm --filter @coder-studio/web exec vitest run src/features/workspace/views/mobile/mobile-files-sheet.test.tsx
298+
```
299+
300+
Expected:
301+
302+
- PASS for the existing structural tests
303+
- PASS for any new regression assertion added in Step 2
304+
305+
- [ ] **Step 4: Commit any structural-test-only adjustments**
306+
307+
If `mobile-files-sheet.test.tsx` changed:
308+
309+
```bash
310+
git add packages/web/src/features/workspace/views/mobile/mobile-files-sheet.test.tsx packages/web/src/features/workspace/views/mobile/mobile-files-sheet.tsx
311+
git commit -m "test(web): keep mobile files header behavior covered"
312+
```
313+
314+
If it did not change, skip this commit.
315+
316+
## Task 4: Final Verification
317+
318+
**Files:**
319+
- No new files
320+
- Test: `packages/web/src/styles/components.theme.test.ts`
321+
- Test: `packages/web/src/features/workspace/views/mobile/mobile-files-sheet.test.tsx`
322+
323+
- [ ] **Step 1: Run the combined verification suite**
324+
325+
Run:
326+
327+
```bash
328+
pnpm --filter @coder-studio/web exec vitest run src/styles/components.theme.test.ts src/features/workspace/views/mobile/mobile-files-sheet.test.tsx
329+
```
330+
331+
Expected:
332+
333+
- PASS with `0` failures
334+
- No regressions in the mobile files content style contract or structure contract
335+
336+
- [ ] **Step 2: Perform a quick requirement checklist against the spec**
337+
338+
Confirm each item directly against the code and test coverage:
339+
340+
- tabs are flat and aligned with PC sidebar language
341+
- header actions are flat icon actions, not circular floating buttons
342+
- file and Git surfaces no longer use floating-card shadows
343+
- file-tree search and rows keep mobile touch sizing
344+
- editor, diff, terminal, top header, and bottom status bar selectors were not changed as part of this task
345+
346+
- [ ] **Step 3: Commit the verification checkpoint only if there are uncommitted plan-scope changes left**
347+
348+
If there are still plan-scope code changes not yet committed:
349+
350+
```bash
351+
git add packages/web/src/styles/components.css packages/web/src/styles/components.theme.test.ts packages/web/src/features/workspace/views/mobile/mobile-files-sheet.test.tsx packages/web/src/features/workspace/views/mobile/mobile-files-sheet.tsx
352+
git commit -m "chore(web): verify mobile files content refresh"
353+
```
354+
355+
If there are no plan-scope changes left, skip this step.

0 commit comments

Comments
 (0)