Skip to content

Preview typography parity: separate user/base styles and add workspace font configuration (A+B) #125

@knightedcodemonkey

Description

@knightedcodemonkey

Summary

Preview currently has a standards/cascade issue for top-level user at-rules (notably @import) and lacks a first-class way to mirror app-global font families without adding temporary font-loading CSS in every PR.

This proposal combines:

  • B: Separate runtime base CSS and user CSS into distinct style elements.
  • A: Add optional workspace font configuration so preview can load known app fonts once and let user code stay DRY.

Problem

  • User @import rules can be ignored when runtime base CSS is prepended in the same stylesheet.
  • Teams often rely on app-global typography; in preview they currently need extra @font-face/@import glue that would not exist in real app code.
  • This encourages non-DRY preview-specific PR changes.

Goals

  1. Standards-compliant user CSS behavior in preview.
  2. Typography parity with real applications.
  3. Minimal preview-only CSS boilerplate in component PRs.
  4. Preserve current isolation and rendering behavior.

Non-goals

  1. Building a complex font marketplace UI.
  2. Supporting arbitrary third-party providers without clear constraints.
  3. Changing iframe isolation model.

Preferred implementation order

  1. Phase 1 (B - correctness): split style injection into two elements.
  2. Phase 2 (A - DX): add optional workspace-level font configuration and runtime font preload/injection.

Rationale:

  • Phase 1 removes the current standards/cascade bug safely and independently.
  • Phase 2 then layers in DRY typography support on stable styling semantics.

Proposed implementation

Phase 1 (B)

  1. Maintain two dedicated style nodes in preview document head:
    • knighted-preview-base-styles
    • knighted-preview-user-styles
  2. Keep deterministic order: base first, user second.
  3. Update patch/render paths to mutate text content only (no duplicate nodes).
  4. Preserve existing render lifecycle and mode behavior (React/DOM).

Phase 2 (A)

  1. Introduce optional workspace font config (e.g. list of families/sources/weights/styles).
  2. Load configured fonts once per preview document.
  3. Allow component and style tabs to reference configured family names directly.
  4. Surface load failures in diagnostics/status (network, CORS, invalid source).

Acceptance criteria

  1. Top-level user @import is no longer ignored in preview.
  2. Existing user-overrides-over-base cascade behavior remains intact.
  3. No duplicate style tags across repeated renders/config patches.
  4. Optional workspace font config loads fonts and enables direct font-family usage without per-PR font glue CSS.
  5. React and DOM mode behavior remains unchanged aside from expected typography improvements.
  6. Add regression coverage:
    • @import works at top of user CSS.
    • Cascade order is stable.
    • Configured font family becomes available in computed styles when source is valid.
  7. Document preview font behavior and configuration.

Risks

  1. Cascade regressions if style element order changes.
  2. Slight startup/render cost when workspace font config includes large font payloads.
  3. Provider/CORS/network variability for remote font assets.

Mitigations

  1. Lock style ordering in implementation + tests.
  2. Keep font config opt-in and optionally cap number of configured families.
  3. Add clear diagnostics for failed font loads and fallback behavior.

Notes

@font-face currently works as a temporary workaround, but this issue targets a robust and DRY long-term path for preview typography parity.

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