doxa-maps/library
Doxa Maps 00f7d349eb Shareable pages P2b: nested shells at any depth have their tab in the address (?subtab= path)
When a shell sits inside another plugin that owns the address (Plugin Studio → the Research Gallery → …), its own
tab had no key. P1 never wrote it from a nested shell, and P2's ownAddress dropped a nested `tab`, so every tab
inside Studio had the same URL.

`subtab` is a PATH, one segment per nested shell below the owner: ?subtab=regions-dashboard at depth 1, and
?subtab=posterverse.upg-100 when a shell sits inside a shell. There are at most 6 segments, each a plain id.
- A nested shell claims its tab with claimView({ tab }, { depth }), where depth comes from its profile-config
  addressDepth (depthOf; its parent passes it down).
- The owner records the claim as that segment: the segments above are kept, the deeper ones and pane/place dropped.
- The same tab again is a no-op (a shell's first-paint claim on a deep link keeps everything below it).
- A segment missing above the claimed depth (a hole) is refused.
- The owner's own tab change drops the whole path.
- subtabAt(search, depth) gives a shell its segment.
Standalone pages and DX Life never see subtab: there the shell is the owner and writes `tab`.

check:view-address H covers depth 1, 2 and 3: first-paint replace, pick push, a composite's pane/place beside
subtab, the same tab claimed again, Back, and the owner's tab change. It has 9 new poisons (52).
2026-10-03 07:50:25 +00:00
..
api The people-group list is a universal prop: the same maps can show any project's list 2026-09-26 05:16:02 +00:00
charts Two gates the branch backlog turned red 2026-09-29 14:55:35 +00:00
colors library/ keeps the reason and drops the speaker: no comment quotes or cites the Driver 2026-09-29 05:26:25 +00:00
components Share this page never copies a token; neutral wording in the P3 comments 2026-10-03 06:18:57 +00:00
composables Shareable pages P2b: nested shells at any depth have their tab in the address (?subtab= path) 2026-10-03 07:50:25 +00:00
constants Poster sizes: the ladder offers eight sizes (paper, 18x24, 36x36, 36x48, 36x60, 36x66, 66x66, 60x96) 2026-09-30 23:49:05 +00:00
dashboards Docs: "reusable by default" in the library guides, and Deep Research by its name 2026-10-01 08:27:04 +00:00
data Print files: a stale cached copy of a pinned file is fetched once more, fresh 2026-10-02 19:05:37 +00:00
elements Poster section element: card-action="dashboard" turns each card's sticker into Show dashboard and dispatches dxm-poster-dashboard for the host (absent keeps Show on map) 2026-10-02 12:43:50 +00:00
i18n Share opens on "Share this page"; Embed is its own tab; a header menu opens beside its button (shareable pages P3) 2026-10-03 06:05:46 +00:00
layouts pane-wrapper: a pending link is also retried by a bounded rAF with an observer present, and by every settled scroll 2026-10-03 06:42:17 +00:00
lists Merge branch 'bundler-2/driver-1650' into bundler-2/handoff 2026-09-29 14:50:44 +00:00
maps Source comments state design history and measurements as facts, without quoting or naming anyone 2026-10-01 00:37:17 +00:00
packet Merge commit '1d8f5f1cc' into poster-design-plugin/experimental 2026-10-03 05:10:30 +00:00
packets library/ keeps the reason and drops the speaker: no comment quotes or cites the Driver 2026-09-29 05:26:25 +00:00
print The Country Posters map's legend Packet export works, and the card deck rolls out behind one switch 2026-09-29 05:26:27 +00:00
scripts UPG100 packet: full-width life charts, a shorter page-1 strategy, self-fitting points 2026-10-03 00:20:58 +00:00
stores A collapsed legend reopens itself after you close a people-group detail 2026-09-29 11:56:47 +00:00
styles library/ keeps the reason and drops the speaker: no comment quotes or cites the Driver 2026-09-29 05:26:25 +00:00
utils Merge remote-tracking branch 'origin/development' into upg100/pg-names 2026-10-01 13:25:01 +00:00
vendor/cldr library/ keeps the reason and drops the speaker: no comment quotes or cites the Driver 2026-09-29 05:26:25 +00:00
index.js Move internal files out of the repo; fix five dead links; a fuller delegation diagram 2026-09-25 05:14:10 +00:00
ProfileLoader.vue Host floor: one module, a latch for a max-height host, and a gate that pins measure-once 2026-10-02 10:01:46 +00:00
README.md

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.