slides: discussion #282, both halves — unnumbered slides, and reveal steps within a slide - #464
Merged
Merged
Conversation
…ous page number The third answer to "does this slide take a number". A state is a variant reached by link; a hidden slide is out of the walk; both decline a number by leaving the walk. Discussion #282's case is the one neither covers: a build made of three morph steps that the audience reads as one slide, whose corporate footer must show the page number — and read "18" three times, not 18, 19, 20. `unnumbered: true` keeps the slide in inLinearFlow and takes it out of paginates, so every surface that counts by that predicate — page fields, the presenter's counter, the sidebar — agrees at once, and the page field on it is the previous slide's number by the existing rule (count of numbered slides up to and including it). Absent = counts; every existing file is unchanged. numberHidden is about hidden slides and does not touch it. Slide panel: an Unnumbered toggle beside Hide slide, with a hint; the sidebar shows the continued number dimmed with a trailing dot. Shape gate and model keys know the key; three strings in all eight catalogs. scripts/test-slides-pagination.ts is the pagination rig the hidden-slide work never had: the three ways to decline a number, the page field slide by slide, the numberHidden and hidden+unnumbered interactions, and a check that every surface asks the same predicate. 20 checks; registered.
Build size
Updated: |
The other half of discussion #282, and the one its author preferred: "animate on click". An element with fx.step = n is hidden when the slide appears and revealed on the n-th →, running its entrance (a plain fade when it has none); ← hides it again; → leaves the slide only once every step is shown. Elements sharing a step appear together, gaps are pressed through in one go, and arriving backward lands fully revealed so ← walks a talk back through the frames it went forward through. One slide stays one slide — one page number, one morph pairing, one speaker note — and an older shell shows every element at once. The decisions are DOM-free in slides/src/steps.ts (StepState: enter/next/prev/set) and present.ts is the DOM around them: goNext/goPrev ask the step counter before moving between slides, slidechanged enters the slide's steps with the direction, stepped elements are hidden by visibility (not display) so nothing reflows and the entrance can start from opacity 0, the speaker counter shows step/max, and the presenter's nav carries the step so an audience copy following a broadcast reveals and hides in time. Panel: a Reveal step field in the Presenting section. Measured in a real browser on the manual clock, not believed: the revealed element's opacity went 0.00 → 0.08 → 0.66 → 1.00 across the fade; entry hides the steps, → walks 1, 2 (two elements together), 5, ← hides 5, two more → leave the slide, ← back lands fully revealed; on a morph arrival the stepped elements sat hidden while the carried element morphed. scripts/test-slides-steps.ts: 30 checks, registered. Shape gate and model keys know the key; three strings in eight catalogs; changelog and DECISIONS entries.
…like the sidebar slideLabel counted by position (!stateOf), so with an unnumbered — or a hidden — slide in the deck the picker said 'slide 5' while the sidebar and footer said 4. Found by the lead reviewing #464 against the code; it predates the PR for hidden slides and the PR states the invariant, so it lands here. The label is now the number the sidebar shows (paginates), with '(hidden)' or '(unnumbered)' after it so two entries can share a number without being confused. Pinned in test-slides-pagination (21).
…h the 22 language packs The core catalogs were complete but the packs were not: two marker strings took the source from 800 to 802 keys and the packs' 720 fell to 89.8%, under the 90% floor (fffe694 had sat at exactly 90.0%). The eight strings this PR adds are now in every pack — 728/802, 90.8%. tk's header records that its eight are machine-drafted pending its named translator; the other packs are machine-drafted by convention. The 74 other strings the packs lack (broadcast, code palette, embed) predate this PR.
nyblnet
added a commit
that referenced
this pull request
Sep 13, 2026
…[Unreleased], once, before the sync line
lasjoh-toho
added a commit
to lasjoh-toho/bento
that referenced
this pull request
Sep 15, 2026
…pstream) Adopted the reveal-steps half of upstream nyblnet/bento's own nyblnet#464 ("discussion nyblnet#282, both halves — unnumbered slides, and reveal steps within a slide"). The "unnumbered slides" half is a separate, unrelated concern bundled in the same upstream commit — deliberately NOT adopted here, to keep this change scoped to what was actually asked about. An element with fx.step = n is hidden when the slide appears and revealed on the n-th → (running its own Enter animation, or a plain fade when it has none); ← hides it again; → only leaves the slide once every step has been shown. Elements sharing a step appear together, gaps are pressed through in one go, and arriving at a slide backward (← from the next slide) lands with every step already revealed, so ← walks back through the same frames → walked forward through. One slide stays one slide throughout — one page number, one morph pairing, one speaker note. slides/src/steps.ts copied verbatim from upstream — genuinely DOM-free, self-contained decision logic (StepState: enter/next/prev/ set) with no dependency on anything specific to this fork, so no adaptation was needed there at all. present.ts required careful, deliberate integration rather than a blind merge, since this fork's own goNext/goPrev/hasNext/hasPrev have been extensively customized this session already (loop, auto-advance, the citations end-screen, staged Escape). The step check is inserted as the FIRST thing each of those four functions does — a pending step takes priority over slide navigation, exactly as upstream's own design intends — with every one of this fork's own additions (hideEndScreen, resetAutoAdvance, the loop wrap-around, exitInsteadOfEndScreen) preserved entirely intact beneath it. The live-broadcast/presenter- follow parts of upstream's own present.ts diff (sendNav carrying a step, followStep) were NOT ported — this fork has no live-broadcast presenter feature at all for a step number to travel across, confirmed by checking for bc?.presenter/follow.nav before assuming otherwise. runEnterFx gained the same only/revealing/atStep parameters upstream added, letting a reveal-step call restrict which elements animate (and give a plain fade to one with no fx.enter of its own) without disturbing its own existing slide-entrance behavior at all. Editor UI: a new "Schritt" field (own German label, matching this session's own established convention throughout — everything else upstream's own diff added stayed in English, including the row label itself, which would have been the one inconsistently-English label in an otherwise fully German sidebar) in the element's own Effects section, right after Enter secs, with a tooltip and a conditional hint showing the currently-set step number. Verified: tsc -b clean, full build:single succeeds. Extracted the copied steps.ts and ran it directly (node --experimental-strip-types) against the exact walkthrough upstream's own commit message describes — → revealing step 1, then step 2 (two elements together), then step 5 (pressing through the gap in one go), ← hiding step 5's element, → re-revealing it, → finally leaving the slide once every step is shown, and a backward slide-entry landing fully revealed with hasNext() correctly false — every single step of that sequence matched expectations exactly. Also decompressed the actual built .bento.html to confirm the new German tooltip/hint text and the .bento-step-hidden CSS rule both landed in what ships.
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.
Discussion #282, both options — the maintainer's call: option 1 on its own merits (it covers more than reveals), option 2 as the feature its author preferred.
Commit 1 —
unnumbered: trueon a slide (Slide panel → Unnumbered, beside Hide slide). In the walk, takes no page number,{{page}}on it continues the previous slide's, the total does not grow. A build of three morph steps reads "18, 18, 18"; a section card sits in the walk without counting. The third answer topaginatesbesidestateOfandhidden, and the only one still ininLinearFlow— every surface counts by that predicate, so nothing else changed.scripts/test-slides-pagination.ts(20 checks): the pagination rig the hidden-slide work never had.Commit 2 —
fx.stepon an element (Presenting → Reveal step). Hidden when the slide appears, revealed on the n-th → running its entrance (a plain fade if none), hidden again by ←; → leaves the slide only when every step is shown; shared steps appear together; gaps are pressed through; arriving backward is fully revealed. One slide stays one slide (page number, morph pairing, note, thumbnail). Decisions DOM-free inslides/src/steps.ts; present.ts is the DOM around them; the speaker counter shows step/max; the presenter's broadcastnavcarries the step and audience copies follow it. Old shells show every element at once.scripts/test-slides-steps.ts(30 checks).Measured in a real browser (manual clock; the driven tab was hidden, so rAF would have lied): opacity 0.00 → 0.08 → 0.66 → 1.00 across the reveal fade; entry hides the steps, → walks 1 / 2+2 / 5, ← hides 5, two more → leave the slide, ← back lands fully revealed; stepped elements stay hidden through a morph arrival.
Also: shape gate + model keys for both keys; six strings in eight catalogs; changelog entries; a DECISIONS entry for why steps are state and not slides. Typecheck, build:single + splice gate, ci-registered 313, i18n, assets, export-secrets all green; no CLAUDE.md/AGENTS.md change.
Appends to
[Unreleased]after the broadcast entry — trivial rebase if #463 lands first.