doxa-maps/library
doxa-maps-88655c70 cc6a5ea901
Some checks are pending
build-gate / build (push) Waiting to run
legend: a phone can now export the packet — it was a prop, not a design call
Last tick I found the export unreachable on mobile and recorded it as
Driver-gated: "WHERE the control goes on a phone is a design call, the sheet has
no titlebar". Both halves of that were wrong, and checking them was this tick.

LegendMobile RENDERS SemanticTreeLegend itself — titlebar and all — and the 0x0
elements my measurement found belonged to the OTHER, hidden desktop instance
mounted below the breakpoint. That geometry made it look as though the sheet had
nowhere to put the control. A Driver decision was never needed.

Two gaps, not one.

The sheet passed neither :export-enabled nor @export, and exportEnabled defaults
to false, so the control's v-if was never satisfied. Fixed via provide/inject,
matching onSemanticTreeSelect immediately above it, because the sheet renders
several levels down where an emit would not reach. Opt-in by construction:
enabled only when a profile provides a handler. The other three LegendMobile
consumers provide none and are verified untouched.

Even then the export did nothing, and that second gap is the one that mattered.
The profile passed :nodes but no :tabs, so hideTabs was true and the sheet showed
a single flat Region tree with no tab strip — no UPG-100 Lists tab, no selectable
zone, and onLegendExport bails on `if (!zoneId) return`. Passing :tabs fixed it.
A :default-tab attribute was added and then removed: defaultTab is not a prop on
LegendMobile, so it would have been inert.

Verified end to end at 390x844: the tab strip appears, a real zone selects,
Export opens, Packet clicks, and one print frame is produced. A packet on a
phone. The gate written last tick — which failed on mobile by design — now
passes at both widths. The newly visible mobile tabs are fully localized in
en/es/zh, so catalog work from earlier ticks now reaches a surface that never
showed tabs at all.

Four of my own probe errors were caught by measuring rather than concluding.
Clicking a REGION row left selectedKey empty, so the handler correctly bailed
and it read as "export does nothing" — the same zero on DESKTOP is what proved
it was the probe and not a regression.

country-posters shows the same mobile gap on its own surface. Not taken; its
owner's call.
2026-09-24 17:47:26 +00:00
..
api Add the Gospel Access filter, the ladder the binary flag was flattening 2026-09-23 13:19:22 +00:00
colors A validated WAGF region palette, where the one-palette gate requires it 2026-09-24 02:24:08 +00:00
components legend: a phone can now export the packet — it was a prop, not a design call 2026-09-24 17:47:26 +00:00
composables Vendor Figtree in place of Brandon Grotesque, chosen by measurement 2026-09-24 16:44:44 +00:00
constants doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
data Regions: expand a region to its country posters, reusing the shared wall 2026-09-24 04:26:29 +00:00
i18n legend: the controls no longer read their own i18n key aloud 2026-09-24 13:16:18 +00:00
layouts Merge main into bundler-2/work 2026-09-23 23:48:10 +00:00
maps Load the RTL text plugin from one place, and in the composite too 2026-09-22 19:55:58 +00:00
packet packet: a partial translation renders 12 prayer points, not 3 2026-09-24 12:20:38 +00:00
scripts packets: give CI something to check, instead of a sweep that always SKIPs 2026-09-24 14:33:36 +00:00
stores fix(spa): make embedded maps survive the sandboxed plugin iframe 2026-09-12 21:07:26 +00:00
styles Fiord: the MapLibre dark that actually looks like the map it replaces 2026-09-24 02:26:14 +00:00
utils Regions: one rollup, ported from theirs, instead of two copies 2026-09-24 04:01:34 +00:00
index.js Brand-neutral shared VerticalTabsLayout with lazy nested-element hosting; fix cap-5 prayer tab leaf path; neutralize library identifiers; add Forgejo CI build-gate workflow 2026-09-19 17:24:30 +00:00
ProfileLoader.vue One page, one map token — and the nested search bar comes back 2026-09-24 01:14:37 +00:00
README.md Complete app-profiles->plugin-designs sweep across comments/docs; build green; layouts kept at root (load-bearing) 2026-09-17 18:18:19 +00:00

library/ (@map) — the shared map template

The other half of the architecture (see ../plugin-designs/README.md): every map in plugin-designs/<your-map>/ composes the reusable, parameterized pieces that live here. Fix something here and every map benefits on the next build; break something here and every map breaks — read components/WARNING.md before touching shared pieces.

Folder What lives there
ProfileLoader.vue The root of every bundle: parses profile-config, loads the profile, provides the stores + config
components/ Shared UI — map, legends, controls, popup (PeopleGroupDetail), tables, charts, hints (README)
composables/ Shared logic — map engine (useMapInstance), provider switch, shadow-DOM styles, theming
stores/ Per-instance Pinia stores (ui / map / data) — provided by ProfileLoader, injected by children
api/ Data-source registry (sources.json) + fetch layer — the JAMstack runtime wiring
colors/ Color sets maps opt into via profile-config.colorSet
i18n/ The shared string catalogs (all maps speak the same languages)
data/ Small shared datasets baked at build time (big served data lives in ../data/)
constants/ Shared constants
scripts/ Maintainer pipelines (posters, research) — not part of any bundle

The rule of thumb (same as WARNING.md): custom code in your app-profile, reusable code here — and things only move from the first to the second once they've earned it.