Skip to content

Redesign the interface around native macOS chrome and a real design system #14

Description

@Yan123-tech

Summary

Replace the hand-built interface with native macOS chrome and move every visual decision out of the views into a design system. Landed in #13.

Motivation

The window had the shape of an application without the finish of one. Two defects drove most of it:

  • ThemeManager.isDark was background.red < background.blue, which is false for any neutral background — #1e1e1e is 30 < 30. Dark and High Contrast therefore forced .preferredColorScheme(.light), so every system-drawn control rendered light against a dark canvas. It read as a styling problem and was a comparison operator.
  • The tab strip swapped the close button for the dirty dot, so modified tabs could not be closed without saving first.

Beyond those, the chrome was 13 hardcoded .system(size:) calls with no semantic styles, 7 off-grid padding values, zero corner radii, fixed 28pt/20pt bars, two competing empty states in different capitalisations, a hand-rolled sidebar header that truncated No Folder Opened to No Fold...Opened, and Theme.keyword doing five unrelated jobs — app tint, tab underline, folder icon, terminal prompt and terminal errors.

Proposed approach

Modules touched: CodeEditorThemes (tokens), CodeEditorCore (metrics, extracted logic), CodeEditorUI (views), CodeEditorApp (toolbar, commands).

  1. Theme declares colorScheme per palette, plus Chrome and Semantic groups. Chrome never borrows a syntax token.
  2. Metrics — 4pt grid, radii by surface, chrome heights — in CodeEditorCore, Foundation-only, grid enforced by a test.
  3. Typography — semantic styles so chrome scales with system text size; code stays fixed-size SF Mono.
  4. Materials: stop overriding the sidebar's own vibrancy.
  5. Unified toolbar replacing the sidebar header; tabs that merge into the canvas; one adaptive empty state.
  6. Selection-driven tree activation, the Xcode navigator rule.
  7. ⌘F via CodeEdit's own panel, ⌘P quick open, drag-resized terminal, session restore.
  8. FileOutline, QuickOpenMatcher, QuickOpenIndex, SessionStore extracted to Core and tested.

Ordering matters: finish before features. The find panel is upstream AppKit, so dropping it into an unfinished shell makes the gap more obvious, not less.

Trap for whoever picks this up

Acceptance criteria

  • isDark no longer derived from colour arithmetic; regression test covers all three palettes
  • Dirty tabs are closeable without saving
  • No .system(size:) in chrome; no padding off the 4pt grid
  • One empty state, one primary action per surface
  • Sidebar reveals and emphasises the active document
  • ⌘F, ⌘P, resizable terminal, session restore
  • swift build passes
  • swift test passes — 68 tests, up from 35
  • Visual review by a human. Spacing, materials, contrast and the tab/canvas merge were never confirmed by eye; the implementing session could not read screenshots.

Not done, deliberately

LSP transport, PTY terminal, external-change detection, Finder file associations (needs CFBundleDocumentTypes), new dependencies, a new app icon.

Activity

  1. Yan123-tech commented on Oct 10, 2026

    @Yan123-tech
    OwnerAuthor

    The visual review is done. It found three defects that 68 passing tests did not, all now fixed and confirmed:

    Two of those were defects the redesign introduced; #15 predates it and simply was never visible without two tabs worth switching between.

    Acceptance criteria are now all met. Leaving this open only because PR #13 is still unmerged — the work is on feature/ui-redesign, not in main yet. Close it with the merge.

    Also fixed while in there: the tab label rendered both a dirty dot and the * that Document.title appends. One state, one indicator.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions