fix(render-ui)!: scope PreviewPrompt to its own node instead of a shared id PIE-927 - #2312
Merged
Conversation
…red id PIE-927
PreviewPrompt located its own DOM node by searching the whole document for
#preview-prompt, but every prompt on a page emitted that same id. getElementById
returns the first match, so on a 5-item page 28 of 30 typeset requests resolved
to item 1's prompt and items 2-5 were never typeset at all. querySelectorAll
returns every match, so each instance additionally re-aligned every other
prompt's images, making that work O(N^2) in item count.
Both lookups now read a ref to the component's own container and can no longer
escape the instance's subtree. The hardcoded id is removed: duplicate ids in one
document are invalid HTML and break aria-labelledby / aria-describedby and
label-for wiring. A stable `preview-prompt` class replaces it as the hook for
"is this node inside a prompt" checks, which is a kind test rather than an
identity one.
No replacement id is needed. Where the prompt genuinely labels a groNo replacement id is nnatively, rendered as a <legend> inside <fieldset>, and nothing in
pie-lib or pie-elements points an aria id-reference at it.
BREAKING CHANGE: PreviewPrompt no longer renders id="preview-prompt". Consumers
matching on that id must match the `.preview-prompt` class instead, e.g.
audio.closest('#preview-prompt') becomes audio.closest('.preview-prompt').
Affects 5 pie-elements packages: multiple-choice, categorize, drag-in-the-blank,
hotspot, image-cloze-association.
CarlaCostea
requested review from
PatriciaRomaniuc,
andreeimiron and
arimieandreea
August 20, 2026 14:26
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.
https://illuminate.atlassian.net/browse/PIE-927
PreviewPrompt located its own DOM node by searching the whole document for #preview-prompt, but every prompt on a page emitted that same id. getElementById returns the first match, so on a 5-item page 28 of 30 typeset requests resolved to item 1's prompt and items 2-5 were never typeset at all. querySelectorAll returns every match, so each instance additionally re-aligned every other prompt's images, making that work O(N^2) in item count.
Both lookups now read a ref to the component's own container and can no longer escape the instance's subtree. The hardcoded id is removed: duplicate ids in one document are invalid HTML and break aria-labelledby / aria-describedby and label-for wiring. A stable
preview-promptclass replaces it as the hook for "is this node inside a prompt" checks, which is a kind test rather than an identity one.No replacement id is needed. Where the prompt genuinely labels a groNo replacement id is nnatively, rendered as a inside
, and nothing in pie-lib or pie-elements points an aria id-reference at it.BREAKING CHANGE: PreviewPrompt no longer renders id="preview-prompt". Consumers matching on that id must match the
.preview-promptclass instead, e.g. audio.closest('#preview-prompt') becomes audio.closest('.preview-prompt'). Affects 5 pie-elements packages: multiple-choice, categorize, drag-in-the-blank, hotspot, image-cloze-association.