doxa-maps/documentation/reference-library-index.md
Doxa Maps d54ece3b25 Kit landing 4c-2: the chip bar moves into the library, and its unconfigured default gets a voice
DashboardFilterChips.vue moves to library/components/dashboards/. Nothing about the rendering
changed. What made the move possible was 4b, which inverted the one dependency that blocked it: this
file imported useTreeLegendLabels — the People CODE -> NAME tables, research-specific and staying in
plugin-designs — and a library component importing a plugin composable is what
check:no-cross-plugin-imports refuses. The resolver now arrives on dashboardConfig.legend.

THREE THINGS BEYOND THE MOVE, all found by assessing the file rather than by moving it:

1. THE UNCONFIGURED DEFAULT NOW JOINS A LIST. 4b's fallback returned the value untouched, so a
   multi-value filter (spec D1) printed String(['A012','A013']) = "A012,A013", comma-jammed, while a
   dashboard that DID supply a resolver got "South Asian Peoples, Bengali Peoples". Configured and
   unconfigured should differ in whether CODES RESOLVE, never in punctuation — the second difference
   reads as a rendering bug rather than as missing configuration, and go-int is the consumer who will
   see the unconfigured state first.

2. THE DEAD INJECTS ARE GONE. `dataStore` and `searchSourceId` existed only to construct
   useTreeLegendLabels and have been unused since 4b. Removed rather than left in place: an unused
   inject is a claim about the host, and a kit component that appears to need a research dataStore is
   one a new dashboard will dutifully provide before discovering it is never read.

3. AN EXPLICIT EXCEPTION TO library/components/WARNING.md, recorded in the file's own header. That
   file says a component graduates into the library only once MORE THAN ONE map uses it; this one is
   used by ZERO, because the topbar dedup pass unmounted it when SearchFilterHeader became the single
   source of truth for showing and clearing filters. It is here because the kit's promise runs the
   other way round — a NEW dashboard mounts kit components, so waiting for a second consumer before
   providing the first one is a deadlock. The honest consequence is written down too: a passing gate
   means "it mounts and degrades", not "it looks right", and nobody has SEEN this component since the
   dedup. Whoever wires it in is its first real reader, and must not mount it beside a
   SearchFilterHeader that is already showing chips.

check:legend-mirrors grows arm 5, and it asserts the two things a "move" gets wrong that reading the
new file cannot show: that the OLD copy is actually gone (a move that leaves the original behind is a
copy, and two chip bars over one filterSet drift the moment one is edited — this tree has already
paid that with useNeighborT/usePplrT at Jaccard 0.82), and that the UNCONFIGURED behaviour is right,
which no dashboard here would reveal because they all supply a resolver. The default is LIFTED out of
the source and RUN, the way arm 3 drives the rail's fallbacks — not mounted, because a no-op renderer
cannot show a chip and the rendered result is rega's. Five mutants, all caught: old copy left behind,
the join reverted to 4b's bare value, a dead inject re-added, the supplied resolver ignored, and a
relative import restored.

The barrel re-exports from the library for one cycle, so no consumer's import line changes in the
same landing that moves the file. documentation/reference-library-index.md regenerated, per landing.

PARENTED ON a285e06c (4b), not on main, because 4b edits this same file — landing them the other way
round would revert 4b's inversion. Source only: research-dashboard and dashboard-plus-grid need a
rebuild.
2026-09-27 04:14:14 +00:00

258 lines
18 KiB
Markdown

# 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'`
- **DashboardFilterChips** — DashboardFilterChips — the live filterSet rendered as removable AND-stacked chips
`import … from '@map/components/dashboards/DashboardFilterChips.vue'`
- **PinHint** — PinHint.vue — the conversion coach-mark (bottom-center of any map).
`import … from '@map/components/hints/PinHint.vue'`
- **ApproxPinNote** — ApproxPinNote.vue — the ONE wording every map with people-group pins uses (APPROXPIN, 2026-09-26).
`import … from '@map/components/legends/ApproxPinNote.vue'`
- **LegendDesktop** — This component's chrome, read out of the catalogue. tStatic and not useI18n: these mount inside
`import … from '@map/components/legends/LegendDesktop.vue'`
- **LegendMobile** — (no description)
`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** — Does the Fly + Clusters toolbar render for this legend type?
`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'`
- **RegionSectionCard** — RegionSectionCard.vue — one region as a card: a heading, a summary line, a grid of its countries,
`import … from '@map/components/regions/RegionSectionCard.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'`
- **useCsvExport** — useCsvExport.js — ★ SHARED LIBRARY CODE (dashboard-kit landing 3). Two parameters make it
`import … from '@map/composables/useCsvExport.js'`
- **useDashboardLayout** — useDashboardLayout.js — reusable drag-resize + persistence engine for the CMV dashboard grid.
`import … from '@map/composables/useDashboardLayout.js'`
- **useDashboardSearch** — useDashboardSearch.js — the ONE free-text search the whole dashboard shares.
`import … from '@map/composables/useDashboardSearch.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'`
- **useFacetAggregation** — useFacetAggregation.js — count rows by a facet accessor, and roll the tail into one bucket.
`import … from '@map/composables/useFacetAggregation.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'`
- **useOptionalT** — ★ NO <area>.<key>-SHAPED EXAMPLES IN THIS FILE'S COMMENTS. check:i18n-keys-exist reads any such
`import … from '@map/composables/useOptionalT.js'`
- **usePosterPrints** — usePosterPrints.js — THE print actions every poster wall shares.
`import … from '@map/composables/usePosterPrints.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'`
- **useSelectionBus** — useSelectionBus.js — hand-rolled pub/sub brushing-and-linking bus.
`import … from '@map/composables/useSelectionBus.js'`
- **useSelectionCamera** — useSelectionCamera.js — "select rows in the table, the map zooms to that selection."
`import … from '@map/composables/useSelectionCamera.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'`
- **useTextHighlight** — highlightRanges(value, indices) — wrap each matched index range in
`import … from '@map/composables/useTextHighlight.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'`
- **colocation** — colocation.js — which people groups share ONE coordinate on a map (APPROXPIN, 2026-09-26).
`import … from '@map/utils/colocation.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'`
- **html** — html.js — the two helpers every HTML string built in library/ must use (CRITIC-3, 2026-09-26).
`import … from '@map/utils/html.js'`
- **loadPinnedUmd** — loadPinnedUmd — load a PINNED, integrity-checked UMD library and capture it WITHOUT touching the host
`import … from '@map/utils/loadPinnedUmd.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)
- **cdn** — cdn.js — EVERY third-party script and stylesheet a plugin loads at runtime, pinned to an EXACT version
`import … from '@map/constants/cdn.js'`
- **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`.