doxa-maps/library/components/poster
doxa-maps-88655c70 b197055bf0
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
Print a UPG-100 list straight from the map legend
The Driver, as a first-time user: "I select one and it gives me print
options at the top right of the legend ... that's the only way that map
would be usable."

The affordance already existed - SemanticTreeLegend renders an export
menu gated on a selection, the plugin passes :export-enabled, and
@export was wired. What the handler did with it was the problem: the
packet branch delegated to the shared composable, and the poster branch
hand-rolled an <a download> of posters/<id>.webp. That is wrong twice.
It downloads a file silently, which was ruled out on 2026-09-23 ("no
silent file download as the default action"), and it has no fallback, so
for the lists whose .webp is not shipped it saved a 404.

The wall had a correct poster print the whole time, private to
PosterWall.vue, so this surface could not reach it. It moves into
usePosterPrints.printPoster and both surfaces now call the one copy -
what the card asked for: "reuse the existing three print actions rather
than growing a fourth implementation." Two guards moved with it, each
learned the hard way: a THROWN fetch is a miss rather than an error (or
the rasterise fallback is skipped entirely), and a blank raster fails
loudly (an SVG in an <img> is an isolated document, so a missing
stylesheet paints black with no error).

Also in this commit, both from measurement rather than review:

THE STICKER OVERLAP IS NOW A CONSTANT, NOT HALF A VARIABLE. Centring the
print row on the banner edge put half its height on the banner - and
that height is content-dependent: 68px in en, 54px in zh, taller when ro
wraps at 390px. Measured ro/390px: 27 of 27 stickers on the map by 4px
while en and zh were clean at the same padding. No fixed padding can
clear half of a variable. The row's top is now pinned --tape-overlap
above the edge and extra height grows downward into the row gap, so the
amount on the banner is identical in all 11 locales at every width.
15 width x locale combinations now pass with map-covered 0.

THE PER-ROW PREFERENCE IS CLAMPED TO WHAT THE VIEWPORT HOLDS. It renders
as an inline grid-template-columns, and inline beats the stylesheet, so
the Driver's default of 2 overrode minmax(210px,1fr) at every width -
including 390px, where two columns give a ~162px card. Reported from a
390x844 phone shot. The preference is for desktop density, not an
instruction to overflow a phone; it survives, clamped by the same 210px
minimum the stylesheet already uses.

THE ROW GAP WAS CLEARING A DISTANCE NOTHING OCCUPIES. 88px was tuned
when the print row hung fully below its card. It now straddles the
banner edge, so the same shot showed a ~180px empty band between rows.
56px still clears a two-line row in the long-label locales.

And the composite shell re-dispatches doxa:select-zone, so a list chosen
in the poster wall is ISOLATED on the map rather than merely scrolled
to. The map half was already built and listening on its own element; the
shell owed it one re-dispatch and nothing here re-implements selection.
2026-09-25 07:10:23 +00:00
..
slots consolidate docs into documentation/ and deployment shells into deployment/ 2026-09-21 23:23:23 +00:00
PosterDialog.vue Checkpoint the swarm's in-flight work 2026-09-22 21:42:18 +00:00
PosterPreview.vue doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
PosterWall.vue Print a UPG-100 list straight from the map legend 2026-09-25 07:10:23 +00:00
README.md consolidate docs into documentation/ and deployment shells into deployment/ 2026-09-21 23:23:23 +00:00

library/components/poster/ — poster export UI

The dialog and preview surfaces that turn a live map into a printable poster. Used by research-map.vue.

  PosterDialog.vue   ← pick size, orientation, title → export
  PosterPreview.vue  ← live preview, updates as you change settings
  PosterWall.vue     ← grid of poster previews
  slots/             ← the composable regions of a poster (own README)
        fed by useMapPoster() · sizes from constants/posterSizes.js
  • Open/close state comes from inject('uiStore'); the preview is fed by useMapPoster().
  • Page sizes: library/constants/posterSizes.js. Defaults: library/constants/posterDefaults.js.

Full wiring + slot contract: ../../../documentation/architecture/components.md.