feat(admin): editable gallery Portable Text block (TipTap node + sidebar panel)#2
feat(admin): editable gallery Portable Text block (TipTap node + sidebar panel)#2Rimander wants to merge 7 commits into
Conversation
…ordering, and side-panel configuration in the editor
…cy in GalleryDetailPanel
…mponents and converters
…ails and replacing assets
… view and external settings panel
|
I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
Scope checkThis PR changes 1,292 lines across 13 files. Large PRs are harder to review and more likely to be closed without review. If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs. See CONTRIBUTING.md for contribution guidelines. |
…lery blocks Preserves asset._type "reference" (the shape the Gutenberg importer emits and the import media pass rewrites) through both converter pairs, with a round-trip test against the exact imported shape. Clicking an image inside the gallery node now opens the sidebar with that image's settings selected, and the panel resyncs its local state when reopened for a different gallery node so edits can't leak between galleries. Adds the release changeset.
4899a26 to
97455b9
Compare
…drop to enable click events on thumbnails
|
Audit note (scope + pre-existing bug): the clipped text visible in the right sidebar's single-image panel (helper texts / Height input cut off at the panel edge) is not introduced by this branch. Git archaeology traces it to Also added since the PR description was written: clicking an individual image inside the gallery block in the canvas opens the sidebar with that image's settings pre-selected; the panel's thumbnail grid supports click-to-select (dnd-kit PointerSensor with a 6px activation distance so real clicks aren't swallowed by drag tracking); and the panel resyncs its state when reopened for a different gallery node. |
What does this PR do?
Implements upstream issue emdash-cms#1436: the
galleryPortable Text block was import/render-only —@emdash-cms/gutenberg-to-portable-textproduces it andGallery.astrorenders it, but the admin editor had no TipTap node for it. Worse than invisible: the editor's PM→PT serializer dropped the block entirely, so opening and saving a migrated post silently destroyed its galleries. This PR makes the block first-class in the editor.Core:
portable-text-to-prosemirror.ts/prosemirror-to-portable-text.tsgain a symmetricgallerymapping with a shared image sanitizer; malformed galleries (noimagesarray) keep the visible unknown-block placeholder instead of becoming an empty grid.PortableTextGalleryBlock/PortableTextGalleryImage, preservingasset._type: "reference"— the exact shape the Gutenberg importer emits and the WP-import media pass rewrites — so imported galleries round-trip without loss. Covered by unit tests including a fixture matching the importer's output (rewritten_ref/url, per-image captions,columns).Admin:
PortableTextEditor.tsx) gets the same two-waygallerymapping. Previously a loaded gallery fell into the plugin-block fallback and a gallery PM node serialized to nothing.GalleryNode(TipTap node view): WYSIWYG grid preview honoringcolumns, per-image captions, selection overlay with settings/delete, empty-state placeholder. Clicking an individual image opens the sidebar with that image pre-selected (transient selection — never persisted to attrs).GalleryDetailPanel(sidebar): compact 3-per-row thumbnail grid with drag-and-drop reordering (dnd-kit), multi-select "Add Images", column count, and a per-image settings card (large preview, hover Replace, original dimensions, alt text, caption). Local panel state composes sequential edits and resyncs when the panel is reopened for a different gallery node, so edits cannot leak across galleries.MediaPickerModalgains an additive multi-select mode (multiple+onSelectMany, selection in click order); single-select behavior unchanged./galleryslash command. Multiple galleries per document supported. Gallery panels are wired in the content editor, section editor, and widgets editors.Closes #
(Upstream reference: emdash-cms#1436 — this PR is on the fork.)
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change) — converter suite (31 tests incl. 7 new gallery round-trip tests) and full admin suite (1100 tests)pnpm formathas been runmessages.pochanges included.AI-generated code disclosure
Screenshots / test output
Verified end-to-end in
demos/simple(Node + SQLite, core rebuilt to dist first):galleryPT block ({n:3, columns:3}, ordered refs) confirmed via the content API and directly in SQLite.[Unknown block type]placeholder).selectedImageKeyabsent from persisted PT)..emdash-gallerywith 3 figures,--columns: 2, and the caption.Note for reviewers: during verification we found (and deliberately did not touch here) a corrupt Arabic ICU plural in
ar/messages.pofor{0, plural, one {(# item)} other {(# items)}}that crashes components using that msgid in Arabic (e.g. RepeaterField). The gallery UI avoids that msgid; the one-line catalog repair belongs in a separate translation PR.🤖 Generated with Claude Code