Skip to content

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

Open
Abdul-M01 wants to merge 10 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 10 commits into
BuilderIO:mainfrom
Abdul-M01:fix/slides-design-system-css-var-propagation

Conversation

@Abdul-M01

@Abdul-M01 Abdul-M01 commented Jun 11, 2026

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>

Known limitation

The current implementation stores share links as self-contained copies — duplicating title,
slides, and aspect ratio rather than referencing the live deck. This change follows that pattern
by persisting design_system_id into the share link at creation time rather than joining back to
decks at read time. Schema changes were required because SharedPresentation loads entirely
from deck_share_links, so without the column, there was no design system ID to pass into
useDeckDesignSystem.

Share links created before this change have design_system_id = NULL and continue to render
with default branding — no regression. New shares of existing decks capture the current
designSystemId at creation time. A backfill migration for already-published share links is
scoped as a follow-up.

@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[bot]

This comment was marked as outdated.

@steve8708

Copy link
Copy Markdown
Contributor

@Abdul-M01 this PR is great - just one piece of feedback above to get it in

@Abdul-M01 Abdul-M01 force-pushed the fix/slides-design-system-css-var-propagation branch from 6e8c0de to 0568897 Compare June 25, 2026 01:43
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Visual recap — skipped

The visual recap job did not run for this pull request. This is informational only and does not block the PR.

Recap skipped for 172deb7: external fork PR requires a maintainer to apply the recap label to the current head SHA.

builder-io-integration[bot]

This comment was marked as outdated.

builder-io-integration[bot]

This comment was marked as outdated.

@steve8708

Copy link
Copy Markdown
Contributor

we just merged a big localization PR that created some conflicts, if you can resolve @Abdul-M01 and check if any of the other automated feedback looks worth fixing would love to get this in

Abdul-M01 added 3 commits July 2, 2026 17:19
Formatting-only cleanup on SlideRenderer.tsx, PresentationView.tsx,
and slide.tsx to unblock CI fmt:check on PR BuilderIO#1145. No logic changes.

@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 2 potential issues 🟡

Review Details

This incremental update fixes the two previously-blocking shared-link regressions by snapshotting the resolved design-system JSON into deck_share_links and teaching SharedPresentation to render from that snapshot instead of relying on anonymous get-design-system access. The broader propagation work still looks sound: SlideRenderer now provides token defaults, and the editor, presentation, share, slide-preview, sidebar, and browse-card surfaces all thread design-system data through consistently.

Risk assessment: standard. Although most changes are UI-facing, this PR also touches persistence and historical rendering paths, so regressions can affect shared/public presentations and saved version fidelity.

New findings from this pass:

  • 🟡 MEDIUM Public /p/:id presentations still boot without design-system data because the SSR loader only serializes row.data, so the newly tokenized shared presentation path falls back to the default theme there.
  • 🟡 MEDIUM Version previews/restores still depend on version.data.designSystemId, but the new apply-design-system O(1) path updates only the SQL column while snapshot creation copies source.data unchanged, so history can lose the applied theme.

Good patterns: share-link snapshots are self-contained again, and the renderer fallback to DEFAULT_DESIGN_SYSTEM is a solid safety net.

🧪 Browser testing: Will run after this review (PR touches UI code)

Comment on lines +28 to +29
const designSystem = useMemo(() => {
if (!deck?.designSystemSnapshot) return DEFAULT_DESIGN_SYSTEM;

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.

🟡 Public /p/:id presentations still initialize without the design-system snapshot

This now renders from deck.designSystemSnapshot, but the /p/:id loader still builds initialDeck from row.data only. Public presentations never do the share-token refetch, so they stay on the default theme instead of the deck's design system.

Additional Info
Anchor: SharedPresentation.tsx [L:28-35]. Supporting evidence: app/routes/p.$id.tsx loader returns only {title, slides, aspectRatio} from row.data and omits row-level designSystemId/designSystemSnapshot.

Fix in Builder


const versions = versionsQuery.data?.versions ?? [];
const selectedVersion = versionQuery.data;
const { designSystem: versionDesignSystem } = useDeckDesignSystem(

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.

🟡 Version history still drops themes applied through the new O(1) path

selectedVersion.designSystemId only exists if the snapshot JSON captured it, but apply-design-system still updates only decks.designSystemId while version snapshots copy source.data unchanged. For retroactively themed decks, history previews and restores will still fall back to the default styling.

Additional Info
Anchor: HistoryPanel.tsx [L:89-91]. Supporting files: actions/apply-design-system.ts updates only schema.decks.designSystemId; server/lib/deck-versions.ts inserts source.data unchanged; get-deck-version/list-deck-versions read designSystemId from parsed version.data.

Fix in Builder

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