Skip to content

studio: polish styles for file viewer - #95

Merged
mutewinter merged 4 commits into
mainfrom
neil/document-viewer-chrome
Aug 3, 2026
Merged

studio: polish styles for file viewer#95
mutewinter merged 4 commits into
mainfrom
neil/document-viewer-chrome

Conversation

@neilrenicker

@neilrenicker neilrenicker commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
CleanShot 2026-08-03 at 10 35 54@2x CleanShot 2026-08-03 at 10 35 57@2x CleanShot 2026-08-03 at 10 36 01@2x CleanShot 2026-08-03 at 10 36 03@2x CleanShot 2026-08-03 at 10 36 06@2x

The title row and the document toolbar now share a height and an inset, with no rule between them, so they read as one band rather than a header with a strip bolted underneath. The toolbar's controls hug the row above and leave their slack as the gap before the document.

A hairline closes the band instead: every chrome row carries it, and a row followed by a toolbar drops it, so the stroke lands under whichever row is last whether or not the format has a toolbar. Leading controls that paint their own box or are bare text carry the glyph inset themselves, keeping one optical column down the left edge. The zoom readout also drops its caret, which crowded the percentage at toolbar size.

Summary by CodeRabbit

  • UI Improvements
    • Unified file viewer and artifact panel headers with consistent sizing, styling, filenames, actions, and close controls.
    • Refined viewer chrome borders, spacing, padding, and toolbar alignment.
    • Improved zoom controls by centering menu content and removing the dropdown caret.
    • Updated spreadsheet and iWork previews for cleaner styling.
    • Increased spacing around data grid status text.

The title row and the document toolbar now share a height and an inset, with
no rule between them, so they read as one band rather than a header with a
strip bolted underneath. The toolbar's controls hug the row above and leave
their slack as the gap before the document.

A hairline closes the band instead: every chrome row carries it, and a row
followed by a toolbar drops it, so the stroke lands under whichever row is
last whether or not the format has a toolbar. Leading controls that paint
their own box or are bare text carry the glyph inset themselves, keeping one
optical column down the left edge. The zoom readout also drops its caret,
which crowded the percentage at toolbar size.
@neilrenicker
neilrenicker requested a review from mutewinter August 3, 2026 15:48
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Viewer chrome alignment

Layer / File(s) Summary
Chrome primitives and viewer controls
apps/studio/src/client/styles/globals.css, apps/studio/src/client/components/zoom-controls.tsx, apps/studio/src/client/components/document-viewers/*
Viewer chrome uses a theme-aware stroke utility. Zoom controls support caller-provided classes and no longer show the dropdown caret. Document viewer spacing, borders, and rounded styling are updated.
Shared file viewer header
apps/studio/src/client/components/file-viewer.tsx
File viewers declare toolbar presence. FileViewerHeader centralizes filename, actions, close control, sizing, and conditional chrome styling.
Artifact panel header integration
apps/studio/src/client/components/task/view.tsx
ArtifactPanelShell uses the shared file viewer frame and header instead of custom header markup.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: mutewinter

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the pull request's main change to polish file viewer styles.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch neil/document-viewer-chrome

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/studio/src/client/styles/globals.css (1)

589-593: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use semantic theme tokens for the stroke colors.

These declarations hard-code black and white. Use an existing semantic foreground or border token with the required alpha. Define a semantic stroke token if no existing token matches.

As per coding guidelines, use shadcn Tailwind semantic colors instead of raw colors.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/studio/src/client/styles/globals.css` around lines 589 - 593, Update the
--viewer-chrome-stroke-color declarations used by the inset box-shadow to
reference existing shadcn semantic foreground or border tokens with the required
alpha instead of hard-coded black and white values; define a semantic stroke
token only if no suitable token exists, while preserving the light and dark
theme behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/studio/src/client/styles/globals.css`:
- Around line 589-593: Update the --viewer-chrome-stroke-color declarations used
by the inset box-shadow to reference existing shadcn semantic foreground or
border tokens with the required alpha instead of hard-coded black and white
values; define a semantic stroke token only if no suitable token exists, while
preserving the light and dark theme behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c3bf56ed-fa68-436e-a2cd-7c50ca181740

📥 Commits

Reviewing files that changed from the base of the PR and between 14e243e and 4d6c4e9.

📒 Files selected for processing (6)
  • apps/studio/src/client/components/document-viewers/csv-viewer.tsx
  • apps/studio/src/client/components/document-viewers/viewer-toolbar.tsx
  • apps/studio/src/client/components/document-viewers/xlsx-viewer.tsx
  • apps/studio/src/client/components/file-viewer.tsx
  • apps/studio/src/client/components/zoom-controls.tsx
  • apps/studio/src/client/styles/globals.css

The readout is a menu trigger at three sizes, and the glyph crowded the percentage at every one of them. The trigger's own hover and open states already read as pressable.
Main rewrote the CSV viewer onto the shared DataGrid, which owns the row-count readout this branch had re-inset. The inset moves with it, so every grid-backed viewer keeps the one optical column down the left edge.
@mutewinter

Copy link
Copy Markdown
Contributor

FYI I'm taking this PR over and fixing the double border / flicker issue.

Which row closes the band comes from the viewer registry rather than a
`:has` query on the rendered tree. A viewer mounts its toolbar only once
the document has parsed, so the live query drew the hairline under the
title row and then moved it a row down when the file landed.

The artifact panel's placeholder frame is built from the viewer's own
frame and header instead of a second copy, which had drifted to a taller
row showing the full path. It renders on every file switch, so that
difference read as the name jumping when the viewer took over.

The iWork preview banner drops its top border. It sits directly under
the hairline that closes the band, so it drew a second line a pixel
below the first.
@mutewinter
mutewinter merged commit 116fd43 into main Aug 3, 2026
2 of 3 checks passed
@mutewinter
mutewinter deleted the neil/document-viewer-chrome branch August 3, 2026 19:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/studio/src/client/components/document-viewers/data-grid.tsx (1)

381-381: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the Tailwind scale utility for the focus outline.

At apps/studio/src/client/components/document-viewers/data-grid.tsx:381 (Line 381), replace focus-visible:outline-[2px] with focus-visible:outline-2. This preserves the 2px outline without an arbitrary value.

Proposed change
- focus-visible:outline-[2px]
+ focus-visible:outline-2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/studio/src/client/components/document-viewers/data-grid.tsx` at line
381, Update the className on the data-grid container to replace the arbitrary
focus-visible outline value with Tailwind’s standard focus-visible:outline-2
utility, preserving the existing 2px focus outline and all other classes.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/studio/src/client/components/task/view.tsx`:
- Around line 308-315: The ArtifactPanelShell path currently renders
FileViewerHeader without the resolved MIME type, causing MIME-only toolbar
viewers such as extensionless PDFs to use the wrong chrome layout. Resolve or
propagate the file’s MIME type or equivalent hasToolbar classification before
rendering FileViewerHeader, and pass it through so its divider placement matches
FileViewer’s getFileType result.

---

Nitpick comments:
In `@apps/studio/src/client/components/document-viewers/data-grid.tsx`:
- Line 381: Update the className on the data-grid container to replace the
arbitrary focus-visible outline value with Tailwind’s standard
focus-visible:outline-2 utility, preserving the existing 2px focus outline and
all other classes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e25ce632-b0c6-466e-95f7-8c16261f9101

📥 Commits

Reviewing files that changed from the base of the PR and between 4d6c4e9 and 311f5a8.

📒 Files selected for processing (8)
  • apps/studio/src/client/components/document-viewers/data-grid.tsx
  • apps/studio/src/client/components/document-viewers/iwork-viewer.tsx
  • apps/studio/src/client/components/document-viewers/viewer-toolbar.tsx
  • apps/studio/src/client/components/document-viewers/xlsx-viewer.tsx
  • apps/studio/src/client/components/file-viewer.tsx
  • apps/studio/src/client/components/task/view.tsx
  • apps/studio/src/client/components/zoom-controls.tsx
  • apps/studio/src/client/styles/globals.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/studio/src/client/components/document-viewers/xlsx-viewer.tsx
  • apps/studio/src/client/components/document-viewers/viewer-toolbar.tsx

Comment on lines +308 to +315
{/* No mime type: that is part of what the panel is still waiting on.
Every format whose viewer opens a toolbar is identified by its
extension anyway, so the chrome band lays out the same either way. */}
<FileViewerHeader
filename={filename}
filePath={filePath}
onClose={onClose}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep MIME-only toolbar viewers in the same chrome state.

ArtifactPanelShell omits mimeType at apps/studio/src/client/components/task/view.tsx:308-315 (Lines 308-315). FileViewerHeader therefore classifies an extensionless PDF as unknown and places the divider under the title row. When FileViewer receives application/pdf, getFileType resolves pdf and the PDF entry has hasToolbar: true, so the divider moves below the toolbar. See apps/studio/src/client/components/file-viewer.tsx:742-745 and apps/studio/src/client/lib/get-file-type.ts:291-310.

Carry the resolved MIME type or toolbar classification into ArtifactPanelShell before it renders FileViewerHeader.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/studio/src/client/components/task/view.tsx` around lines 308 - 315, The
ArtifactPanelShell path currently renders FileViewerHeader without the resolved
MIME type, causing MIME-only toolbar viewers such as extensionless PDFs to use
the wrong chrome layout. Resolve or propagate the file’s MIME type or equivalent
hasToolbar classification before rendering FileViewerHeader, and pass it through
so its divider placement matches FileViewer’s getFileType result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants