Media.ImageGallery.image_gallery/1 is imported by use ShadcnUI. Supply a
unique id, exactly one accessible_label or labelledby (existing heading
IDs), and nonempty images. An optional escaped description names its own
derived description node. class and unrelated globals survive; required
identities and semantics cannot be overridden.
Each atom-keyed record has a unique string key, safe src, explicit alt,
and positive integer width/height. Optional fields: name, escaped caption,
href, width-candidate srcset plus sizes, loading: :lazy | :eager (lazy),
decoding: :async | :sync | :auto (async). Decorative records require
decorative: true, empty alt and an independent name. Full metadata is optional:
full: %{src: ..., width: ..., height: ..., srcset: [...], sizes: ...}.
Full presentation otherwise reuses the supplied thumbnail source and metadata.
No source, dimensions, alternative text or responsive candidates are inferred.
| Closed values are `columns: :two | :three | :four` (three), |
| `density: :compact | :comfortable(comfortable),fit: :cover | :contain` |
| (cover, thumbnails only), `motion: :system | :none` (system), and |
| `lightbox: :dialog | :none` (dialog). Narrow containers collapse to one column. |
Full images always contain within the viewport; captions remain complete in the native Dialog's scroll container with its sticky close footer. Closed important sizing utilities cap this composition to the percentage viewport, including 200% CSS zoom, and move overflow to its surface without changing the shared Dialog module or installing any sizing script.
Optional repeated caption slots require an existing unique image key and
override the plain caption. Trusted presentation-only HEEx receives
%{key: key, context: :thumbnail | :full}. It renders in both places; scope IDs
with the context and do not include controls, dialogs, scripts or stateful content.
The library cannot sanitize or infer the meaning of trusted HEEx.
Every dialog is initially closed and has a derived instance/item base ID, native
show-modal invoker, visible title, description and explicit close_label (Close
image). initial_focus: :auto | :content | :close and
dismissal: :close_request | :none | :any retain the existing Dialog contract.
Declare context: :dialog when inside a modal; only lightbox: :none is accepted
there. The library cannot discover an ancestor modal from a function component.
The thumbnail image is hidden from the button's accessible name, which uses the
visible “Enlarge name” text; the complete image retains the meaningful alt.
The browser owns modality, inertness, Tab/Escape, close and focus restoration. Keyboard activation restores the previously focused invoker. Pointer focus differs by platform: a browser that does not focus a clicked button may restore the previous focus instead. Tab can visit browser chrome without entering the inert page. No package focus trap, listeners or client state are installed.
The separate visible ordinary link uses href, then full.src, then src.
It remains usable without native commands, scripts or CSS. A broken image keeps
alt, name, caption and destination; no loader claims success or failure.
Native loading and decoding are hints, not guaranteed deferred fetching.
Applications own media rights, privacy, CSP/origin policy, URL authorization,
destinations, responsive accuracy and restoration/reinvocation after replacement.
There are no uploads, transforms, remote galleries, slideshow state, next/previous,
swipe, zoom, pan, image fetching services or server integration.
Origin-effect decision
The optional upstream-style thumbnail-origin effect is deferred for this
release. scripts/record-gallery-origin.mjs --check and the Phase 5 browser suite
probe scoped anchors and discrete transitions on actual generated thumbnail /
Dialog pairs, not just CSS.supports. The locked Chromium starts at the thumbnail;
Firefox and WebKit parse anchor/discrete declarations but produce no origin
transition in this experiment. The demo-only image_gallery_evidence.json
records exact versions and observations. All three use the existing native snap
Dialog in the shipped package. No experiment CSS, measured-coordinate assignment
or view-transition JavaScript is distributed. Revisit only with joint opening,
closing, interruption, accessibility and motion-suppression evidence.
Reviewed upstream gallery.mdx / gallery/basic.html at
bd8f403030c8d1f46804da6eda733fde7e908e63; the full MIT notice is retained.
This adaptation adds semantic figures, validated metadata, captions, explicit
close and destinations, and rejects remote site artwork and optional command
shims. Demo images remain the original hash-pinned local fixture manifest, with
its existing rights notices. Only prefixed static utilities and existing Dialog
CSS ship; no new authored CSS exception is necessary.
References: CSS anchor positioning and native Dialog.