fix(deck): activate body.single override on standalone slides#100
Open
crimsondhaks wants to merge 1 commit into
Open
fix(deck): activate body.single override on standalone slides#100crimsondhaks wants to merge 1 commit into
crimsondhaks wants to merge 1 commit into
Conversation
Closes nexu-io#74 The deck viewer extracts each <section class="slide"> into a standalone HTML document (parseDeck in src/lib/deck.ts) so the deck strip can render slides one-by-one. The standalone HTML copied the original body class verbatim — no 'single' token. But every deck skill that uses position:absolute slides ships an escape-hatch rule: body.single .slide { position: relative; width: 100vw; height: 100vh; opacity: 1; transform: none; pointer-events: auto; } That rule is paired with the inactive-slide hidden state (.slide { position:absolute; inset:0; opacity:0; ... }), which is correct for the runtime deck (where one slide is .is-active and the rest are hidden) but leaves a single-slide standalone iframe stuck in the hidden state. The override exists precisely to handle this standalone-render path — it just never fired because parseDeck didn't add 'single' to the body class. This appends 'single' to the body class on every standalone slide. For the 14 bundled deck skills that use position:absolute slides, the override now fires and the slide renders at its native size with opacity:1 and consistent vertical alignment regardless of inner-HTML structure (the user's reported drift was a side effect of the absolute + flex + opacity:0 base state interacting with different child shapes). For the 6 skills that don't use absolute-positioned slides (deck-guizang-editorial, deck-magazine-web, deck-open-slide-canvas, deck-replit, deck-simple, deck-swiss-international), 'single' is an inert class that no rule selects. Adds src/lib/__tests__/deck.test.ts pinning: - every standalone slide body carries 'single' - original body classes (e.g. skill-scoped hooks) are preserved - empty original class produces a clean ['single'] (no leading space) - mixed-children slides (the issue's exact failure mode) all parse - speaker notes are still stripped from the rendered slide - non-deck docs still return isDeck:false
|
Hey @Siri-Ray — gentle nudge on this one when you have a window. 🙏 Small surface: one line in No rush if you're heads-down — just flagging it's been waiting since yesterday. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #74
Why
Most deck skills hide inactive slides with
.slide { position:absolute; opacity:0 }, and ship a pairedbody.single .slide { position:relative; opacity:1; transform:none }override for the case where one slide is rendered alone (which is what the deck viewer does). The override just never fired —parseDeckwas copying the body class verbatim and never addingsingle. So every standalone slide was sitting atopacity:0and the alignment people saw was just whatever the absolute-positioned.slidehappened to do for that particular inner-HTML shape.You suggested either a wrapper requirement on the skill side or a wrapper injected by the parser. This goes the parser route but uses the
body.singlehatch the skill authors already wrote, so it doesn't add a new wrapper element.What changed
One line in
parseDeckto appendsingleto the body class on every standalone slide. For the 14 deck skills that useposition:absoluteslides the override fires; for the 6 that don't (deck-guizang-editorial,deck-magazine-web,deck-open-slide-canvas,deck-replit,deck-simple,deck-swiss-international)singleis just an inert class.Plus a
deck.test.tswith the mixed-children fixture you mentioned — same 3 shapes the reporter described (one wrapper, multiple direct children, nested + sibling).Verification
guard, typecheck (next + e2e), 173 tests, build — all green locally.
Probed all 3 mixed-children slides through
parseDeckin headless chromium:before fix (with
singlestripped):after:
after fix — slides render at native size, consistent vertical alignment
before fix — slides stuck at
opacity:0