Skip to content

feat: add ViewTransitions component#66

Open
khromov wants to merge 31 commits into
mainfrom
view-transitions
Open

feat: add ViewTransitions component#66
khromov wants to merge 31 commits into
mainfrom
view-transitions

Conversation

@khromov

@khromov khromov commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Summary

Adds <ViewTransitions /> — a zero-JS helper that opts a Mochi app into the browser's cross-document View Transitions API. Since Mochi is an MPA (every navigation is a full page load), dropping this into a shared layout animates navigations with pure CSS; unsupported browsers just navigate normally.

<script>
  import { ViewTransitions } from 'mochi-framework/components';
</script>

<ViewTransitions type="fade" />
  • Presets: fade and slide; optional duration prop (default 250ms); respects prefers-reduced-motion.
  • regions confines the animation to named elements; keep takes CSS selectors for persistent chrome and emits the freeze CSS for them.
  • Exactly one instance may render per page: a second instance logs a warning and emits nothing (request-scoped guard via locals).
  • Exported via new mochi-framework/components subpath.

Changes

  • packages/mochi/src/components/ViewTransitions.svelte + barrel export + ./components package export.
  • Unit tests (ViewTransitions.test.ts): presets, duration, reduced motion, regions, keep (incl. slug-collision disambiguation), and the duplicate-instance guard.
  • Demo at /demos/view-transitions (two linked pages, fade/slide toggle, persistent <video> that keeps playing across navigations).
  • Docs page 148-view-transitions.md.
  • Site-wide usage in PageShell.svelte via <ViewTransitions keep={['.banner', '.sidebar', '.hero', '.gh-corner']} />, which freezes the persistent chrome so only the page body transitions. The view-transitions demo pages render their own instance instead (PageShell skips its own for those routes).
  • Video-production support for the demo asset (packages/video-animations): muxes in a soundtrack with a 3s fade-out and adds an ambient falling-leaves background; the rendered mochi.mp4 is committed under packages/site/public/.

Test plan

  • bun test packages/mochi/src/components/ViewTransitions.test.ts ✅ (15 tests)
  • bun --cwd=packages/mochi run typecheck
  • Smoke-tested the demo + site head output (@view-transition, keyed chrome rules present, demo pages emit exactly one instance).

Adds <ViewTransitions type="fade|slide" duration={ms} /> (mochi-framework/components), a zero-JS helper that opts an MPA into the browser's cross-document View Transitions API via a shared layout. Includes unit tests, a demo, docs, and site-wide usage in PageShell with the banner/sidebar/hero keyed (view-transition-name) so only the page body transitions.
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Mochi review report

Try this PR

Expand instructions
gh run download -R khromov/mochi 27484884292 -n mochi-framework-pr -D /tmp/mochi-pr && bun i /tmp/mochi-pr/mochi-framework-pr.tgz

Download manually

Dependency report

Expand report
Direct: 10
Peer:   3 (svelte, @tailwindcss/node, @tailwindcss/oxide)
Dev:    8
Total unique packages reachable from production deps (roots + transitive): 27
Total on-disk size of those packages: 5.18 MB

Toplist — direct deps ranked by total size (self + transitive):
      total       self  count  package
    4.76 MB    2.71 MB     19  svelte
   680.0 kB   141.4 kB      3  svelte-shaker
   526.4 kB   441.4 kB      1  magic-string
   180.6 kB   145.3 kB      1  chokidar
    51.2 kB    51.2 kB      0  devalue
    30.4 kB    30.4 kB      0  deepmerge
    28.0 kB    28.0 kB      0  negotiator
    25.8 kB    25.8 kB      0  mitt
    25.3 kB    25.3 kB      0  js-cookie
    12.3 kB    12.3 kB      0  zimmerframe

Transitive breakdown for the heaviest deps:

  svelte (19, 2.05 MB transitive): @jridgewell/gen-mapping (91.6 kB), @jridgewell/remapping (58.0 kB), @jridgewell/resolve-uri (51.9 kB), @jridgewell/sourcemap-codec (85.0 kB), @jridgewell/trace-mapping (143.3 kB), @sveltejs/acorn-typescript (194.2 kB), @types/estree (25.5 kB), @types/trusted-types (8.4 kB), acorn (545.5 kB), aria-query (172.8 kB), axobject-query (108.3 kB), clsx (8.4 kB), devalue (51.2 kB), esm-env (3.7 kB), esrap (86.1 kB), is-reference (3.9 kB), locate-character (5.2 kB), magic-string (441.4 kB), zimmerframe (12.3 kB)

  svelte-shaker (3, 538.6 kB transitive): @jridgewell/sourcemap-codec (85.0 kB), magic-string (441.4 kB), zimmerframe (12.3 kB)

  magic-string (1, 85.0 kB transitive): @jridgewell/sourcemap-codec (85.0 kB)

  chokidar (1, 35.3 kB transitive): readdirp (35.3 kB)

Lines of code

packages/mochi
Category main PR Δ
src/**/*.test.ts 6883 7111 +228
src/ComponentRegistry.ts 1633 1642 +9
Other 2922 3110 +188
Total 19759 20184 +425

Unchanged: src/Mochi.ts (1317), src/hooks.ts (235), src/{requestContext,forms,errors}.ts (299), src/{events,log,logger}.ts (351), src/consoleLogger.ts (377), src/cookies*.ts (157), src/extensions.ts (191), src/cache.ts (157), src/middleware/** (81), src/enhance*.ts (184), src/build*.ts (258), src/proxy.ts (125), src/cli* (120), src/{csrf,serverIslandCrypto}.ts (226), src/{types.ts,*.d.ts} (703), src/web-components/** (434), src/debug-bar/** (2316), src/templates/** (790).

packages/docs
Category main PR Δ
Docs 3840 3966 +126
Total 3840 3966 +126
packages/site
Category main PR Δ
src/demos/** 6073 6401 +328
src/components/** 2159 2177 +18
src/lib/** 965 981 +16
Other 1379 1383 +4
Total 10602 10968 +366

Unchanged: src/stores/** (26).

packages/demos
Category main PR Δ
Total 3100 3100 0

Unchanged: src/hn/** (1083), Other (2017).

packages/minimal
Category main PR Δ
Total 536 536 0

Unchanged: Other (536).

packages/cli
Category main PR Δ
Total 479 479 0

Unchanged: src/**/*.test.ts (117), src/cli* (138), src/{create,templates,utils}.ts (220), Other (4).

@khromov khromov marked this pull request as ready for review June 12, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant