doxa-maps/documentation/reference-library-index.md
doxa-maps-88655c70 ddde518a85 Regions: expand a region to its country posters, reusing the shared wall
Driver request: "a toggle or carrot added to the bottom of the region
section that says view country posters, which will let you view country
posters for each of the countries in the regions" — with View-on-map and
Print, "the same reusable code from upg 100 list". This is a third
sanctioned addition alongside the tab strip and the no-selection chooser.

Almost nothing was built. library/components/poster/PosterWall.vue was
already the shared, fully parameterised grid, and it already owned the
card layout, the "Show on map" header button, the PRINT OPTIONS footer
and the client-side raster. regions-list.vue supplies only data and a
toggle — the same division country-poster-wall.vue states in its own
header.

- A "View country posters" toggle at the bottom of every region section,
  carrying aria-expanded and aria-controls, using the same caret SVG the
  header and footer links already use, rotated when open.
- Opening a region renders that region's countries. Measured: 41 cards
  for Africa and all 41 previews LOAD (naturalWidth>0 — a 404 still
  yields an <img>, so the load is the real check). No assets were
  copied: public/assets/previews already holds 174 country-*.webp and
  generate-tree already stages them.
- "Show Chad on the map" reaches the Region Dashboards tab with title
  "Chad" and hash "#chad", by mapping PosterWall's CustomEvent listId
  back through the country-selected the tabs already exchange.
- India prints its own reason with the exact number from the data; China
  renders a real poster. Only India is unsupported — 855 groups and no
  sheet, against China's 154 on a 3x4.

Two defects the screenshot caught and no assertion did:

- PosterWall's root is position:absolute;inset:0, because in its own
  bundles it IS a pane. Embedded in a region card it painted 1440x1100
  over the region's country list. Fixed by parameterising the shared
  component rather than overriding its CSS locally: new `embedded` and
  `sectionHeads` props, both defaulting to today's behaviour, so
  country-posters and key-cities are unchanged by construction. Both
  re-checked. Re-measured: root static, 1200px wide, panel below the
  grid, no overlap.
- With one unnamed group the wall printed a section head reading the
  literal "Other" plus a count duplicating the region card's own
  summary. Suppressed by sectionHeads=false.

The dataset moved to library/data/country-posters.json now that it has a
second consumer, one import line changed in country-posters, and
emit-countries.mjs was retargeted so the next generator run cannot
recreate the duplicate.

The three new strings do not exist on DX-life, so there was nothing to
copy and nothing was invented in another language: en only, with the
other seven locales falling back to the key.

Regression: 15 suites green, including region-vs-live 73/73,
country-vs-live 28/28, mobile 44/44 and 26/26, and a new
_probe-region-posters.mjs. check:library-index drifted for real this
time (3 new library files) and is regenerated here.
2026-09-24 04:26:29 +00:00

15 KiB

REFERENCE-library-index — reusable pieces you can import into an app-profile

DERIVED FILE — do not hand-edit. Regenerate: node internal/generate-library-index.mjs Generated: run node internal/generate-library-index.mjs to refresh

You are a programmer (or an agent) building a map. This is the menu of REUSABLE, parameterized pieces the shared library/ offers. Import what you need with the @map/… alias; build your own custom code in your app-profile's src/ folder. Do NOT edit anything listed here unless you know what you're doing — these are shared across every map, and a change here can break other maps.

  • Three zones: library/ (this menu — reuse, don't edit) · plugin-designs/<map>/ (your sandbox — build anything) · internal/ (the build machine — never touch).
  • To make a new map: copy plugin-designs/template-bundle/, read its README, list your requirements, pick from below.

Components (reusable UI)

  • PeopleGroupDetail — (no description)
    import … from '@map/components/PeopleGroupDetail.vue'
  • ResearchMapFilterPanel — ResearchMapFilterPanel.vue — Multi-field filter UI for the research-map.
    import … from '@map/components/ResearchMapFilterPanel.vue'
  • ResearchMapSideMenu — ResearchMapSideMenu.vue — Side drawer specific to the research-map profile.
    import … from '@map/components/ResearchMapSideMenu.vue'
  • SideMenuDrawer — SideMenuDrawer.vue — Slide-in side panel for the map application.
    import … from '@map/components/SideMenuDrawer.vue'
  • ViewSelect — ViewSelect.vue — the "SELECT VIEW" switcher: a fieldset + legend wrapping a row of
    import … from '@map/components/ViewSelect.vue'
  • BarChart — BarChart.vue — THE SHARED HORIZONTAL BAR CHART (hand-rolled SVG, zero dependencies).
    import … from '@map/components/charts/BarChart.vue'
  • PinHint — PinHint.vue — the conversion coach-mark (bottom-center of any map).
    import … from '@map/components/hints/PinHint.vue'
  • LegendDesktop — Async-import the heavier branches so the boot bundle stays lean.
    import … from '@map/components/legends/LegendDesktop.vue'
  • LegendMobile — useShadowStyles(
    import … from '@map/components/legends/LegendMobile.vue'
  • LegendProgressBar — LegendProgressBar — the prayer legend's header progress bar.
    import … from '@map/components/legends/LegendProgressBar.vue'
  • LegendRows — (no description)
    import … from '@map/components/legends/LegendRows.vue'
  • LegendTools — LegendTools.vue — Fly + Clusters floating toolbar
    import … from '@map/components/legends/LegendTools.vue'
  • SemanticTreeLegend — SemanticTreeLegend — reusable hierarchical legend for any one-to-many semantic tree.
    import … from '@map/components/legends/SemanticTreeLegend.vue'
  • FullscreenButton — FullscreenButton.vue — Toggles fullscreen for the map host element.
    import … from '@map/components/map-controls/FullscreenButton.vue'
  • GeocoderComponent — GeocoderComponent.vue — Mapbox Geocoder search bar as a self-contained Vue component.
    import … from '@map/components/map-controls/GeocoderComponent.vue'
  • HamburgerButton — HamburgerButton.vue — Toggle button for the side menu drawer.
    import … from '@map/components/map-controls/HamburgerButton.vue'
  • HelpButton — HelpButton.vue — Opens the "About this map" help modal.
    import … from '@map/components/map-controls/HelpButton.vue'
  • LocationButton — LocationButton.vue — Flies the map to the user's current location via the
    import … from '@map/components/map-controls/LocationButton.vue'
  • MapControlButton — MapControlButton.vue — Shared base button for all map toolbar controls.
    import … from '@map/components/map-controls/MapControlButton.vue'
  • MapControlMenu — MapControlMenu.vue — the ONE menu every map control opens.
    import … from '@map/components/map-controls/MapControlMenu.vue'
  • MapToolbar — MapToolbar.vue — Positioned layout shell for map control buttons.
    import … from '@map/components/map-controls/MapToolbar.vue'
  • ShareButton — ShareButton.vue — Non-technical share modal for the map toolbar.
    import … from '@map/components/map-controls/ShareButton.vue'
  • ThemeToggleButton — ThemeToggleButton.vue — Switches the app between light and dark mode.
    import … from '@map/components/map-controls/ThemeToggleButton.vue'
  • ZoomInButton — ZoomInButton.vue — Increments the map zoom level by one step.
    import … from '@map/components/map-controls/ZoomInButton.vue'
  • ZoomOutButton — ZoomOutButton.vue — Decrements the map zoom level by one step.
    import … from '@map/components/map-controls/ZoomOutButton.vue'
  • PosterDialog — PosterDialog.vue — modal for previewing + rendering a poster export.
    import … from '@map/components/poster/PosterDialog.vue'
  • PosterPreview — PosterPreview.vue — scaled live preview of the poster composition.
    import … from '@map/components/poster/PosterPreview.vue'
  • PosterWall — PosterWall.vue — THE SHARED POSTER WALL.
    import … from '@map/components/poster/PosterWall.vue'
  • FooterSlot — FooterSlot.vue — STUB. Poster-rendering slot for FooterSlot.
    import … from '@map/components/poster/slots/FooterSlot.vue'
  • LegendSlot — LegendSlot.vue — STUB. Poster-rendering slot for LegendSlot.
    import … from '@map/components/poster/slots/LegendSlot.vue'
  • NorthArrowSlot — NorthArrowSlot.vue — STUB. Poster-rendering slot for NorthArrowSlot.
    import … from '@map/components/poster/slots/NorthArrowSlot.vue'
  • ScaleBarSlot — ScaleBarSlot.vue — STUB. Poster-rendering slot for ScaleBarSlot.
    import … from '@map/components/poster/slots/ScaleBarSlot.vue'
  • TitleSlot — TitleSlot.vue — renders the poster title strip.
    import … from '@map/components/poster/slots/TitleSlot.vue'
  • QaCorner — QaCorner.vue — the embeddable QA corner widget (bottom-right of any map).
    import … from '@map/components/qa/QaCorner.vue'
  • FilterDropdown — FilterDropdown.vue — SHARED (@map/components/search/FilterDropdown.vue).
    import … from '@map/components/search/FilterDropdown.vue'
  • SearchBar — SearchBar.vue — SHARED (@map/components/search/SearchBar.vue).
    import … from '@map/components/search/SearchBar.vue'
  • SearchFilterHeader — SearchFilterHeader.vue — SHARED (@map/components/search/SearchFilterHeader.vue).
    import … from '@map/components/search/SearchFilterHeader.vue'
  • DataTable — DataTable.vue — THE SHARED TABULATOR LIST VIEW.
    import … from '@map/components/tables/DataTable.vue'

Composables (reusable logic — Vue Composition API)

  • researchLegendOptions — researchLegendOptions.js — research-mfe-only options passed to the shared
    import … from '@map/composables/legends/researchLegendOptions.js'
  • useAffinityBlockLegendData — useAffinityBlockLegendData — 4-tier affinity-block legend data for SemanticTreeLegend.
    import … from '@map/composables/legends/useAffinityBlockLegendData.js'
  • useLanguageFamilyLegendData — useLanguageFamilyLegendData — language-family legend rows with
    import … from '@map/composables/legends/useLanguageFamilyLegendData.js'
  • useLegendData — useLegendData — builds a unified, data-driven legend item tree
    import … from '@map/composables/legends/useLegendData.js'
  • useWagfRegionsLegendData — useWagfRegionsLegendData — 3-tier WAGF Regions legend for SemanticTreeLegend.
    import … from '@map/composables/legends/useWagfRegionsLegendData.js'
  • useMapPoster — useMapPoster — render a Mapbox GL map to a poster-grade PNG or PDF blob.
    import … from '@map/composables/poster/useMapPoster.js'
  • usePosterLayout — usePosterLayout — slot positioning math for poster compositions.
    import … from '@map/composables/poster/usePosterLayout.js'
  • printInPlace — printInPlace.js — SHARED (@map/composables/printInPlace.js).
    import … from '@map/composables/printInPlace.js'
  • retryableAsyncComponent — retryableAsyncComponent.js — SHARED (@map/composables/retryableAsyncComponent.js).
    import … from '@map/composables/retryableAsyncComponent.js'
  • useAvatarGenerator — Avatar Generator Composable
    import … from '@map/composables/useAvatarGenerator.js'
  • useCountryOutline — useCountryOutline.js — country boundary OUTLINE overlay on country search.
    import … from '@map/composables/useCountryOutline.js'
  • useDocumentFont — useDocumentFont.js — register a self-hosted @font-face at DOCUMENT level, once per page.
    import … from '@map/composables/useDocumentFont.js'
  • useEdgeScrollAffordance — useEdgeScrollAffordance — the gray "you can scroll past this" edge strips.
    import … from '@map/composables/useEdgeScrollAffordance.js'
  • useGeocoderSearch — Shared geocoder→map search logic (kind-switch + Mapbox filter builder + the
    import … from '@map/composables/useGeocoderSearch.js'
  • useMapAttribution — useMapAttribution.js — the data-credit line every map MUST carry.
    import … from '@map/composables/useMapAttribution.js'
  • useMapClustering — useMapClustering.js — Map Clustering Composable
    import … from '@map/composables/useMapClustering.js'
  • useMapData — useMapData.js - Map Data Loading Composable
    import … from '@map/composables/useMapData.js'
  • useMapEvents — useMapEvents.js - Map Event Handlers Composable
    import … from '@map/composables/useMapEvents.js'
  • useMapFly — useMapFly.js - Map Navigation/Fly Composable
    import … from '@map/composables/useMapFly.js'
  • useMapInstance — useMapInstance.js — Map Initialization Composable
    import … from '@map/composables/useMapInstance.js'
  • useMapLayers — useMapLayers.js - Map Layers Composable
    import … from '@map/composables/useMapLayers.js'
  • useMapPacket — useMapPacket — render a multi-page "prayer packet" PDF for a map selection.
    import … from '@map/composables/useMapPacket.js'
  • useMapProvider — useMapProvider.js — resolve the active map engine ("provider").
    import … from '@map/composables/useMapProvider.js'
  • useMapSelection — useMapSelection.js - Map Selection Composable
    import … from '@map/composables/useMapSelection.js'
  • useMapTheme — useMapTheme.js — shared light/dark theme for every map profile.
    import … from '@map/composables/useMapTheme.js'
  • usePplrInstance — usePplrInstance.js — per-map "instance store" mediator.
    import … from '@map/composables/usePplrInstance.js'
  • usePrayedLocally — usePrayedLocally.js — the "my dot glows" encouragement loop.
    import … from '@map/composables/usePrayedLocally.js'
  • usePrayerStatistics — usePrayerStatistics.js — the ONE authoritative prayer-coverage source of truth.
    import … from '@map/composables/usePrayerStatistics.js'
  • useSearch — useSearch.js — Local geocoder search composable
    import … from '@map/composables/useSearch.js'
  • useSelectedPin — useSelectedPin.js - Selected Pin Highlight + Animated GO Marker
    import … from '@map/composables/useSelectedPin.js'
  • useShadowStyles — useShadowStyles.js — Shadow DOM Style Injection
    import … from '@map/composables/useShadowStyles.js'
  • useSharedMapToken — useSharedMapToken.js — ONE page, ONE map token, shared by every element on it.
    import … from '@map/composables/useSharedMapToken.js'

Utilities (pure helper functions)

  • ClusterHelpers — ClusterHelpers.js — Pure helpers shared across clustering modes.
    import … from '@map/utils/ClusterHelpers.js'
  • DataSourceManager — Back-compat shim. The real DataSourceManager.js lives in the api/ seam
    import … from '@map/utils/DataSourceManager.js'
  • MSTClusteringUtil — MSTClusteringUtil.js
    import … from '@map/utils/MSTClusteringUtil.js'
  • NetworkClusteringUtil — NetworkClusteringUtil.js
    import … from '@map/utils/NetworkClusteringUtil.js'
  • apiBaseUrl — Back-compat shim. The real apiBaseUrl.js lives in the api/ seam folder.
    import … from '@map/utils/apiBaseUrl.js'
  • countries-meta — countries-meta.js — a PORT of DX-life's config/countries-meta.ts (326 lines), the rollup
    import … from '@map/utils/countries-meta.js'
  • embedBase — embedBase.js — Where THIS bundle's built tree is served from, resolved at runtime.
    import … from '@map/utils/embedBase.js'
  • geoUtils — geoUtils.js — Geographic / GeoJSON Utility Functions
    import … from '@map/utils/geoUtils.js'
  • viewportScrim — viewportScrim.js — make a position:fixed full-screen SCRIM actually cover the VIEWPORT,
    import … from '@map/utils/viewportScrim.js'

Stores (Pinia — shared state)

  • dataStore — dataStore.js — Centralized data cache
    import … from '@map/stores/dataStore.js'
  • mapStore — Map Store - Centralized state management for all map instances
    import … from '@map/stores/mapStore.js'
  • uiStore — UI Store - Centralized UI state management
    import … from '@map/stores/uiStore.js'

Constants (never-change values)

  • mapDefaults — mapDefaults.js — Default map initialization settings
    import … from '@map/constants/mapDefaults.js'
  • posterDefaults — posterDefaults.js — default margins, bleed, slot sizes, and typography
    import … from '@map/constants/posterDefaults.js'
  • posterSizes — posterSizes.js — preset poster dimensions (US + ISO).
    import … from '@map/constants/posterSizes.js'
  • zoom — zoom.js - Centralized Zoom Configuration
    import … from '@map/constants/zoom.js'

Data (static reference tables)

  • countries — "value": "AFG",
    import … from '@map/data/countries.json'
  • country-posters — "stats": {
    import … from '@map/data/country-posters.json'
  • iso-numeric-to-alpha2 — "4":"AF","8":"AL","12":"DZ","24":"AO","32":"AR","36":"AU","40":"AT","50":"BD",
    import … from '@map/data/iso-numeric-to-alpha2.json'
  • langFamilyByIso — "aar": "Afro-Asiatic",
    import … from '@map/data/langFamilyByIso.json'
  • langFamilyByLanguage — {"Chamacoco":"Zamucoan","Ninam":"Yanomaman","Yagua":"Yaguan","Muinane":"Witotoan","Finnish":"Uralic","Hill Mar
    import … from '@map/data/langFamilyByLanguage.json'

API / data sources (@map/api)

The library provides the data-source mechanism; you declare WHICH sources your map uses in your own src/api/sources.json. Add a REST API, CSV, or MCP source by adding one entry — no code. Mechanism (do not edit): @map/api/_registry.js, @map/api/DataSourceManager.js.

Colors (@map/colors)

The library provides the color-strategy registry (the mechanism). Shared color taxonomies (religion, adoption, engagement, language-family) live here. Your map's OWN colors live in your app-profile's src/colors/ folder — strategy .js files auto-merge OVER the shared set for your map only, so editing them can't break other maps. Mechanism (do not edit): @map/colors/_registry.js.