Skip to content

feat(modal): run the portal on the web and rebuild the docs site - #310

Merged
GSTJ merged 10 commits into
mainfrom
agent/magic-modal-docs-v2
Jul 29, 2026
Merged

feat(modal): run the portal on the web and rebuild the docs site#310
GSTJ merged 10 commits into
mainfrom
agent/magic-modal-docs-v2

Conversation

@GSTJ

@GSTJ GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner

What changed

  • replaces the generated reference landing with a dark, product-specific Magic Modal story
  • runs the actual react-native-magic-modal package in the page for stacked mobile prompts and an in-place web upload
  • shows one portal serving Expo, iOS, Android, and web call sites without mounting modal bodies before show()
  • fetches GitHub, npm, release, license, and project-age values through cached metadata instead of hardcoding them
  • adds a restrained unicorn identity, realistic phone frames, a new favicon, a quieter OG card, and refreshed README media
  • documents the Next.js setup and fixes package boundaries that blocked a clean Turbopack consumer
  • prevents web BackHandler access and Reanimated exit clones that could leave a closed modal in the DOM

Why

A large app can open a prompt from many call sites. Repeating the modal tree and visibility state on every screen makes those flows harder to coordinate. A single ordered portal gives every call its own ID and promise, so another prompt can open without replacing or cancelling the one already waiting.

The landing now demonstrates that behavior with the package itself before explaining the API.

Preview

Both preview URLs work from the root and from /react-native-magic-modal/.

Validation

  • pnpm lint
  • pnpm typecheck
  • pnpm format
  • pnpm test: 39 package tests and 9 docs tests
  • pnpm run doctor: 19/19 Expo checks
  • pnpm run docs: Next.js 16.2.12, 45 pages, 33 HTML files, 515 internal links
  • expo export --platform all: iOS, Android, and web production bundles
  • browser-tested stacked rating, store, thank-you, and update() flows on desktop and at 390 by 844
  • verified focus handoff, scroll locking, no stale exit clone, no console errors, and no failed asset requests
  • blind visual and writing reviews returned PASS

Boundaries

This PR does not merge itself, publish the npm package, deploy production Pages, or change the custom domain.

@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Cloudflare Pages review

Open the rebuilt Magic Modal landing

  • source: 358b85d
  • environment: Cloudflare Pages preview, branch pr-310
  • rebuilt around the original four-modal rating story, with the live branch and result above the fold
  • verified at 1440×1000 and 390×844; homepage, llms.txt, API reference, and the legacy types/ModalProps.html route return 200
  • production GitHub Pages has not been touched, and the PR has not been merged

The previous generic V2 preview has been replaced at the same URL so this is the only version to review.

@GSTJ GSTJ changed the title feat(docs): make the landing prove the modal flow feat(docs): tell the four-modal origin story Jul 28, 2026
@GSTJ GSTJ changed the title feat(docs): tell the four-modal origin story feat(docs): ship the dark interactive Magic Modal story Jul 28, 2026
@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Fresh preview is live at https://pr-310.react-native-magic-modal-preview.pages.dev/react-native-magic-modal/ from source b7bc141. This is the dark GSAP version with practical examples, the proof strip, final copy pass, and the new README demo. Production and merge are untouched.

@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Final verification on b7bc141: every required check is green, including the Maestro iOS smoke flows. The Cloudflare PR preview still serves the homepage, reference pages, and llms.txt; the legacy types/ModalProps.html URL redirects to its canonical page and resolves successfully. No production deployment or merge was performed.

@GSTJ GSTJ changed the title feat(docs): ship the dark interactive Magic Modal story feat(docs): ship the interactive Magic Modal site Jul 28, 2026
@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Corrected Cloudflare preview: https://pr-310.react-native-magic-modal-preview.pages.dev/

The earlier hashed upload placed the HTML at the root while its CSS and JS lived under /react-native-magic-modal/. This deployment serves the full export in both locations. I verified the root in a real browser: both stylesheets loaded with CSS rules, the dark theme rendered, and the interactive controls mounted. Source remains f4fdfa3. No production deploy or merge was performed.

@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Final status for f4fdfa3: every required check is green, including the 23-minute Maestro run on the iOS simulator. The corrected root preview is https://pr-310.react-native-magic-modal-preview.pages.dev/ and its CSS returns 200 text/css. The PR is clean and ready for review. Merge, npm publishing, and production deployment remain untouched.

@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Reviewed, verified locally, good to land. Rebased over #309, which brought in the postcss and sharp overrides. The lockfile was regenerated on top of them instead of merged, and pnpm install --frozen-lockfile is clean against it afterwards.

Most of the diff is the docs app. The parts that ship to npm are what I went through.

The deep import into react-native-screens/src/components/FullWindowOverlay becomes a namespace import of the public entry, and tools/check-web-build.mjs fails the build if the private path ever comes back. Grepping the built dist/index.runtime.js for react-native-screens/src/ returns 0. The old path reached past that package's exports map into untranspiled source, which not every bundler resolves.

On web, BackHandler is skipped and both the backdrop's FadeOut and the modal's exit animation are dropped. All three are Platform.OS === "web" checks, so native is untouched.

Dependency arrays go on both useAnimatedStyle calls, pinning the shared values plus config.swipeDirection, isHorizontal and rangeMap. The 36 existing swipe assertions still pass, and there are 3 new ones covering the web behavior.

The babel plugin moves from react-native-reanimated/plugin to react-native-worklets/plugin, which is where it lives from Reanimated 4 on. Matches the SDK 55 pair the repo is pinned to as of #311.

tools/wrap-entrypoints.mjs renames the bunchee output to index.runtime.* and writes a new entry that loads dev-runtime.* first. That shim sets globalThis.__DEV__ when it isn't already a boolean. This is the library writing to a global: on React Native it's a no-op because Metro defines __DEV__ before anything loads, and on Next.js it's the difference between the package working and throwing on import. export * forwards all four exports (MagicModalHideReason, MagicModalPortal, magicModal, useMagicModal), the same list the .d.ts declares, and there's no default export to lose. Tarball is 9 files, still dist plus the manifest.

Locally, on the rebased branch

  • 39 package tests across 5 suites, 9 docs tests, doctor 19/19, changelog:check both directions, and build, lint, format and typecheck all exit 0
  • docs build: Next 16.2.12, 45 routes, 33 HTML pages

check chain and tarball

In the browser, against the built out/

The landing runs the workspace build of react-native-magic-modal through react-native-web, so this exercises the real package. Clicked a score of 2, which is under the threshold, and the flow branched to feedback and then to thanks, one modal at a time, code panel tracking the awaited line:

hero with the rating modal open

feedback modal after the score resolved

thanks modal

Resolving the last one gives back { reason: "INTENTIONAL_HIDE", data: { score: 2 } } and the stack reads empty, so nothing is left mounted after the exit:

resolved promise and empty stack

the portal section further down the page

Zero console errors and zero failed requests across the whole session. The three metadata calls the page makes (GitHub, npm downloads, npm registry) each return 200, and every one is wrapped in a try/catch that falls back to null, so a rate limit only blanks the stat strip.

@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

docs-landing shipped in GSTJ/magic#8 as a shadcn block, in v1.11.0. Same
shell shape as this site (header, hero, stat strip, sections, timeline, CTA,
footer, clipboard install button), installable with
pnpm dlx shadcn@latest add GSTJ/magic/docs-landing.

Nothing to change here. Your landing is built around the package running live
and the block is a generic shell, so merging the two would mean rewriting
home.css.

The closest overlap is apps/docs/components/install-command.tsx. The registry
version takes the command as a prop, clears the reset timeout on unmount, and
puts the copy result in an aria-live region, so a screen reader announces
"Install command copied" while the visible label stays put.

Leaving the pointer here so the next docs site can pull it from the registry.

@GSTJ GSTJ changed the title feat(docs): ship the interactive Magic Modal site feat(modal): run the portal on the web and rebuild the docs site Jul 28, 2026
@GSTJ

GSTJ commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Retitled from feat(docs): to feat(modal): because it changes what ships.

The release probe in release.yml only qualifies a commit if its subject carries (modal) scope, or a ! breaking marker, or a human-authored BREAKING CHANGE: footer. Under the old title none of that was true, so squashing this would have published nothing. The web guards, the useAnimatedStyle deps, the screens import and the new dist layout would have sat on main until some unrelated (modal) commit dragged them out.

feat rather than fix because the headline for a consumer is that the portal runs on react-native-web and Next.js now. That's a minor, 9.0.1 to 9.1.0. Nothing here is breaking: dist/index.js, dist/index.cjs and the type entries keep their paths and their four exports, and the __DEV__ shim is a no-op under Metro.

Re-verified after a8d7735 and the merge of main (which now carries #309):

  • 39 package tests across 5 suites, 9 docs tests, doctor 19/19, changelog:check, build, lint, format and typecheck all exit 0
  • pnpm install --frozen-lockfile clean against the merged lockfile
  • docs build: 45 routes, 33 HTML pages

The rating flow still behaves the same through the new copy, and the resolved payload is unchanged:

hero with the revised headings

resolved promise, stack empty

@GSTJ
GSTJ merged commit b159af2 into main Jul 29, 2026
5 checks passed
@GSTJ
GSTJ deleted the agent/magic-modal-docs-v2 branch July 29, 2026 00:02
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.

1 participant