Repository navigation
fix(plugins): support media pickers in repeaters - #4440
khoinguyenpham04 wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 24ea7a0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 12 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
docs | 24ea7a0 | Oct 27 2026, 05:17 PM |
There was a problem hiding this comment.
The approach is sound. Widening the RepeaterSubField type and REPEATER_SUB_FIELD_TYPES in @emdash-cms/blocks lets repeaters declare media_picker sub-fields, which the Portable Text editor already renders. Nested sub-fields still go through validateElement, so the existing media_picker checks still apply. Both reviewers approved and found nothing that needs fixing. The one suggestion is a wording fix in the skill reference, because media_picker is also used in sandboxed field widgets. Review was static; neither reviewer ran tests, builds or lint.
Reviewed by anthropic/claude-opus-5-5 and openai/gpt-6.1-sol.
| ## Repeater and media picker elements | ||
|
|
||
| `repeater` and `media_picker` are admin-authoring elements, not ordinary fields in a sandboxed admin-page `form`. | ||
| `repeater` and `media_picker` are authoring elements for native plugin Portable Text block forms. They are not ordinary fields in a sandboxed admin-page `form`. |
There was a problem hiding this comment.
[suggestion] This line now describes repeater and media_picker as authoring elements for native plugin Portable Text block forms. That is accurate for repeater, but media_picker is also rendered in sandboxed plugin field widgets (BlockKitFieldWidget.tsx has a case "media_picker" that uses the same BlockKitMediaPickerField). Agents following this reference could conclude that a field widget can't use media_picker. Consider naming both surfaces, for example: "repeater is an authoring element for native plugin Portable Text block forms; media_picker works there and in plugin field widgets. Neither is an ordinary field in a sandboxed admin-page form."
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/auth-atproto
@emdash-cms/blocks
@emdash-cms/cloudflare
@emdash-cms/contentful-to-portable-text
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/plugin-cli
@emdash-cms/plugin-test
@emdash-cms/plugin-types
@emdash-cms/registry-client
@emdash-cms/registry-lexicons
@emdash-cms/registry-loader
@emdash-cms/registry-moderation
@emdash-cms/registry-verification
upgrade-emdash
@emdash-cms/sandbox-workerd
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-ai-search
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-field-kit
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
🚀 Deploying Preview to Cloudflare 🚀Preview URL: https://noah-repeater-media-picker.try.emdashcms.com, https://noah-repeater-media-picker-emdash-playground.emdash-cms.workers.dev (commit 24ea7a0)This URL reflects your latest Preview deploymentPreview Deployments by commit
|
danielmlr
left a comment
There was a problem hiding this comment.
Thanks Noah!
I found a few small items, worth a look:
- The skill reference probably wants to name both places
media_pickerworks, as emdashbot suggests on line 409. That line says it's only for Portable Text block forms, while the same file lists it for plugin field widgets further down. - Field widgets use the same component, so they get the new card too. It'd be great to have a before and after screenshot of a plugin field widget with a media picker as well.
- The changeset could say the new card applies to plugin field widgets too. At the moment it mentions only repeaters.
- I think the card title wants to be
Selected imagefor local media, like inImageFieldRenderer. Uploaded files are stored under a generated ID, so for almost every image the title reads like01JC8….jpg. - The "maintains a minimum height so the container does not collapse" test can probably go. The minimum height is gone, and the test now repeats the two broken-image tests above it.
What does this PR do?
Native Portable Text plugin forms already render media pickers inside repeater rows, but the public types and Block Kit validation reject their declarations. This aligns the supported types and validation with that existing editor behavior. Selected images keep their existing URL-string format.
The shared plugin media picker now follows the compact image-card layout used by the content editor. It keeps the whole image visible, exposes Replace and Remove without hover, and safely encodes local storage keys. Tests cover declaration validation and selecting, saving, reopening, reordering, replacing, and removing images with their captions.
Related issue: not applicable. This follows a specific Maintainer request.
Type of change
Your connection to this change
An EmDash Maintainer requested this compatibility fix.
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runmessages.pochanges except in translation PRs.This corrects the declaration contract for existing behavior, so no new feature design is included. Required-field validation remains separate.
AI assistance disclosure
Screenshots / test output
A disposable local site was checked in English and Arabic, including a real post save and reload.
Repeater sub-field type 'media_picker' is not allowed; the typed builder failed with TS2322. Both pass after the fix.