[Feature] Preview Next Generation (NG)#3841
Draft
jeremywiebe wants to merge 8 commits into
Draft
Conversation
## Summary: *This PR is part of a series building a typed, hook-based preview system for the Perseus editor. The new system replaces the untyped `window.iframeDataStore` + raw `postMessage(string)` communication with structured, validated message passing via `usePreviewController` and `usePreviewPresenter` hooks. The new system is being built alongside the old one — no existing behavior changes until the final PR in the series flips the switch.* Previous PRs in this series: - #3464 - #3467 - #3474 - #3492 - #3495 - #3499 - #3578 --- This is the Preview NG changeover PR! After this lands, Perseus will be exclusively using the new Preview communication system (no more legacy `iframeDataStore` + string-postMessage preview protocol). This means that all Storybook preview code now uses the new `usePreviewPresenter` hook, and all four editors (`EditorPage`, `ArticleEditor`, `HintEditor`, `ItemEditor`) switch from `IframeContentRenderer` to `PreviewWithIframe` (introduced in #3578). The legacy `IframeContentRenderer` remains because some client's still use it directly. When this change is released, I will switch clients over as part of the Perseus release. The legacy component will be deleted in a later cleanup pass once that's done. https://github.com/user-attachments/assets/a801bb4a-2cbd-4154-940f-09a2bd4037c5 NOTE: the issue of the keypad being clipped by the preview iframe is a longstanding issue and is unrelated to the changes in this PR. Issue: LEMS-3741 ## Test plan: - [x] `pnpm tsc` clean - [x] `pnpm lint` clean for touched files - [x] `pnpm test` - [ ] Reviewer: open Storybook, navigate to the editor stories, and confirm each editor's preview renders content (question, hint, article single section, article-all). The behaviour should be identical to `main`. Author: jeremywiebe Reviewers: jeremywiebe, claude[bot], mark-fitzgerald Required Reviewers: Approved By: mark-fitzgerald Checks: ⏭️ 1 check has been skipped, ✅ 10 checks were successful, ⌛ 1 check is pending Pull Request URL: #3581
…iOptions (#3590) ## Summary: *This PR is part of a series building a typed, hook-based preview system for the Perseus editor. The new system replaces the untyped `window.iframeDataStore` + raw `postMessage(string)` communication with structured, validated message passing via `usePreviewController` and `usePreviewPresenter` hooks. The new system is being built alongside the old one — no existing behavior changes until the final PR in the series flips the switch.* Previous PRs in this series: - #3464 - #3467 - #3474 - #3492 - #3495 - #3499 - #3578 - #3588 - #3581 - #3590 -- This PR is a message-field cleanup — it restructures the preview data shapes now that the editor migration is in place (#3581). * The data-shape changes: `ArticlePreviewData.json` is renamed to `article` (and is now a single `PerseusRenderer` for the one section being edited, not an array) * `QuestionPreviewData.initialHintsVisible` is dropped (it was always `0` in practice) * `article-all` previews now use a new `ArticleAllPreviewData` (`{article: ReadonlyArray<PerseusRenderer>, apiOptions}`) with a single shared `apiOptions` instead of the previous per-section `ArticlePreviewData[]` * The presenter hook's returned `data` is also now named `content`, so consumers read `content` instead of the awkward `message.content.data`. * The preview message types now type their `apiOptions` as a new `SerializableApiOptions` defined next to the stripping logic in `sanitize-api-options.ts`) rather than the full `APIOptions`. This makes the types honest about what actually survives the `postMessage` structured-clone boundary. Issue: LEMS-3741 ## Test plan: - [x] `pnpm tsc` - [x] `pnpm lint` - [x] `pnpm test` - [ ] Reviewer: open Storybook, navigate to the editor previews, and confirm: - Question preview still renders (no visible hints; behavior matches main) - Article single-section preview renders content - Article-all preview renders all sections concatenated with shared apiOptions - Hint preview unchanged Author: jeremywiebe Reviewers: claude[bot], jeremywiebe, mark-fitzgerald Required Reviewers: Approved By: mark-fitzgerald Checks: ⏭️ 1 check has been skipped, ✅ 11 checks were successful Pull Request URL: #3590
…3762) ## Summary: Adds an `"exercise"` variant to the typed preview protocol to support the full-exercise preview view. Note that there is no preview rendering of this new type as that is (and will continue to be) handled by the consuming apps. This just plumbs the value through for use. Issue: LEMS-3741 ## Test plan: - `pnpm test` - `pnpm tsc` Author: jeremywiebe Reviewers: mark-fitzgerald Required Reviewers: Approved By: mark-fitzgerald Checks: ⏭️ 1 check has been skipped, ✅ 11 checks were successful Pull Request URL: #3762
…-editor (#3764) ## Summary Exports two symbols from `@khanacademy/perseus-editor` that are needed by consumers: * `PreviewWithIframe` — the component that hosts the preview iframe and the parent↔iframe message bridge. * `PreviewContent` — the discriminated-union type describing what a preview renders (question, hint, article-section, article-all, exercise). Both already lived in the package; this just adds them to the public entry point (src/index.ts). No behavior change. Issue: LEMS-3741 ## Test plan * `pnpm typecheck` passes — the new re-exports resolve. * No runtime change; nothing to exercise manually. Author: jeremywiebe Reviewers: anakaren-rojas Required Reviewers: Approved By: anakaren-rojas Checks: ⏭️ 1 check has been skipped, ✅ 11 checks were successful Pull Request URL: #3764
## Summary: A few small fixes found when testing preview in Storybook: * **Fixes**: wires user-input into all previews so that widgets that rely on user-input wiring don't freeze, or worse, throw. * **Fixes**: The hint preview now uses the right renderer (`HintRenderer`) and respects the `pos` (hint position), which restores the hint labeling/semantics, brings its own `UserInputManager`, and forces `customKeypad: false` like production hint rendering does. * **Fixes**: the `MobileKeypad` is only mounted when `isMobile: true` to avoid extra spacing/border at the bottom of the preview. * **Fixes**: accesses `isMobile`/`hasLintGutter` through `usePreviewPresenter` instead of reaching up to `window.frameElement`'s `data-*` attributes. Issue: LEMS-3741 ## Test plan: - `pnpm typecheck`, `pnpm lint`, and `pnpm test` - Open the EditorPage story in Storybook and add an input widget (e.g. numeric-input or expression) — the preview should render it and accept typed input instead of crashing/freezing - Switch the preview to a phone/tablet device — focusing an expression widget should raise the mobile keypad inside the preview iframe - Switch back to desktop — no hairline bar across the bottom of the preview, and expression widgets use the desktop keypad popover - Check the hint preview row — hints render with hint styling and the screen-reader position label Author: jeremywiebe Reviewers: nishasy, jeremywiebe Required Reviewers: Approved By: nishasy Checks: ⏭️ 1 check has been skipped, ✅ 11 checks were successful Pull Request URL: #3766
Contributor
npm Snapshot: PublishedGood news!! We've packaged up the latest commit from this PR (9d320b6) and published it to npm. You Example: pnpm add @khanacademy/perseus@PR3841If you are working in Khan Academy's frontend, you can run the below command. ./dev/tools/bump_perseus_version.ts -t PR3841If you are working in Khan Academy's webapp, you can run the below command. ./dev/tools/bump_perseus_version.js -t PR3841 |
Contributor
|
Size Change: +134 B (+0.03%) Total Size: 518 kB 📦 View Changed
ℹ️ View Unchanged
|
# Conflicts: # packages/perseus-editor/src/article-editor.tsx # packages/perseus-editor/src/testing/preview/exercise-preview-page.tsx
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.
Summary:
This PR contains all of the already-landed PRs for the Preview NG work. It contains changes that move our preview system from an ad-hoc, untyped message passing system to a fully typed, hook-based communication.
I've created this PR mostly so I can get npm snapshots
Issue: LEMS-3741
Test plan: