Skip to content

fix(slides): propagate design system CSS vars to all preview surfaces#1145

Open
Abdul-M01 wants to merge 3 commits into
BuilderIO:mainfrom
Abdul-M01:fix/slides-design-system-css-var-propagation
Open

fix(slides): propagate design system CSS vars to all preview surfaces#1145
Abdul-M01 wants to merge 3 commits into
BuilderIO:mainfrom
Abdul-M01:fix/slides-design-system-css-var-propagation

Conversation

@Abdul-M01

Copy link
Copy Markdown
Contributor

Summary

Applying a design system to an existing deck was O(n) in tool calls.
The agent had to read, rewrite, and update each slide individually. On
a modest deck this produced 25+ tool calls. This PR reduces retroactive application to O(1).

Problem

Skill templates contained hardcoded color and font values baked into
slide HTML. SlideRenderer already injected CSS custom properties at
render time, but the hardcoded values bypassed the cascade, forcing
the agent to rewrite each slide's content when a design system was
applied or changed.

When a design system was applied retroactively to an existing deck,
sidebar thumbnails and browse-card previews continued to render with
default tokens — designSystem was never forwarded to EditorSidebar
or DeckCard.

Solution

Replace all hardcoded values in skill templates with var(--ds-*)
references so new slides are token-aware from creation. Retroactive
application becomes a single call — SlideRenderer handles the rest
via CSS cascade.

Thread designSystem through to all three render surfaces so the
main editor, sidebar thumbnails, and browse cards stay consistent.
Fallback mirrors useDeckDesignSystem DEFAULT_DESIGN_SYSTEM
behaviour at each call site.

Key Changes

  • create-deck/SKILL.md, slide-editing/SKILL.md — replace hardcoded
    hex/font values with var(--ds-*) tokens
  • design-systems/SKILL.md — add retroactive application guidance
  • SlideRenderer.tsx — add --ds-heading-weight and --ds-body-weight
    to CSS var injection block
  • EditorSidebar.tsx, DeckEditor.tsx — thread designSystem prop
    through to <SlideRenderer>
  • Index.tsx, DeckCard.tsx — build designSystemById map and thread
    designSystem through to <SlideRenderer>

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

builder-io-integration[bot]

This comment was marked as outdated.

@steve8708 steve8708 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

great catch - thanks @Abdul-M01 !

theres some bot feedback here too - take a look and fix whatever you agree with, ignore anything you don't

also one CI check to fix too

@builder-io-integration builder-io-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Builder reviewed your changes and found 1 potential issue 🔴

Review Details

Code Review Summary

This PR successfully completes the design system CSS variable propagation across all slide render surfaces. The previous high-priority issues have been fixed:

Fixed issues from prior review:

  • designSystem prop now threaded to all 10 SlideRenderer call sites (PresentationView, Presentation, SharedPresentation, slide route, HistoryPanel, DeckEditor, Index, DeckCard, EditorSidebar)
  • Background color now uses CSS variable fallback: var(--ds-bg, #000000), enabling retroactive design system application
  • Proper error handling on JSON parsing with try/catch and empty array fallback
  • Type safety maintained throughout

Well-executed improvements:

  • Hook usage (useDeckDesignSystem) correctly integrated with proper null handling
  • Memoization dependencies correct ([designSystems], [deck?.designSystemId])
  • Skill documentation fully updated to reflect tokenized approach
  • Clean prop threading through component hierarchy

🔴 Critical Issue Found:

  • SharedPresentation always renders with default design systemuseDeckDesignSystem(null) is hardcoded at line 23, ignoring the original deck's design system choice. The SharedDeckResponse API type lacks designSystemId field, so even if the prop used the deck's value, the data isn't available. Shared presentation links lose the creator's custom branding.

Status: Risk: Standard. One critical issue blocks merge (shared presentation styling).

🧪 Browser testing: Will run after this review (PR touches UI render paths and design system cascade)

const [deck, setDeck] = useState<SharedDeckResponse | null>(initialDeck);
const [error, setError] = useState(initialError);
const [loading, setLoading] = useState(!initialDeck && !initialError);
const { designSystem } = useDeckDesignSystem(null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 Shared presentations always render with default design system

SharedPresentation calls useDeckDesignSystem(null) unconditionally, ignoring the deck's designSystemId. Shared presentation viewers see default branding even if the creator linked a custom design system. Fix: (1) add designSystemId?: string | null to SharedDeckResponse, (2) pass it from the server API, (3) change line 23 to useDeckDesignSystem(deck?.designSystemId), (4) handle null case with fallback.

Fix in Builder

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Abdul-M01 one last one posted that feels like a good one to fix

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