The section the Country Posters tab draws (a collapsible region head + its poster cards) is now usable on its
own, for any poster set, by parameters:
- library/components/poster/posterTypes.js: a TYPE REGISTRY. A type is an adapter (items for a scope, the
section's title, the print actions). The library registers 'country' (library data + the shared sheet path,
so a withheld whole-country poster stays withheld); plugins register their own types from their own code
(UPG 100 lists, regions, continents later). No plugin code in the library.
- 'country' scopes: a region key in any spelling. DX Life's /regions slug ('latin-america-and-caribbean'),
the API's value, the wall's slug and the English name all reduce to one canonical key.
- PosterSectionView.vue: one section, drawn by a PosterWall in a new SECTION-ONLY mode (no wall head; off by
default, so every existing wall renders as before), embedded so the page scrolls it.
- <dxm-poster-section type scope collapsible collapsed locale assets-base api-base-url is-dark>: the
attributes map onto the standard element's profile-config (posterSectionConfig.js, pure), so it keeps the
per-instance i18n and store. registerPosterSectionElement() from any bundle; Country Posters ships it first.
- country-posters/poster-section: a page showing two sections (Africa open, Oceania collapsed).
- poster.sectionNone (11 locales): an unknown type or an empty scope says so, never a blank.
check:poster-section (gates:pre) + self-test: the registry, DX Life's 8 scopes covering every country once,
withheld India, the attribute mapping, and PosterSection.vue injecting every name its template uses; 3 poisons.
The known collapse-while-scrolled landing is left exactly as it is.
67 lines
3.4 KiB
JavaScript
67 lines
3.4 KiB
JavaScript
import { defineMapElement } from '@map/elements/defineMapElement.js'
|
|
import { registerPosterSectionElement } from '@map/elements/posterSectionElement.js'
|
|
/**
|
|
* plugin-designs/country-posters/index.js
|
|
*
|
|
* Bundle entry — registers the country-posters web component.
|
|
*
|
|
* Registers ONE custom-element tag:
|
|
* - <country-posters-map>
|
|
*
|
|
* Usage from a host page:
|
|
* <script src="/app/country-posters.js"></script>
|
|
* <country-posters-map profile-config='{"profile":"countries-map","tk":"pk.YOUR_MAPBOX_TOKEN"}'></country-posters-map>
|
|
* <country-posters-map profile-config='{"profile":"country-poster-wall"}'></country-posters-map>
|
|
* <country-posters-map profile-config='{"profile":"country-poster-wall","countries":"IND,PAK,BGD"}'></country-posters-map>
|
|
* only those countries (ISO-3, or {code,name,count} records), FLAT, for a host's own region section
|
|
* (DX Life's /regions, 2026-09-30); `region: "Asia"` asks for one WAGF region; `columns`, `heading` optional.
|
|
*
|
|
* TWO PROFILES, ONE BUNDLE — the same shape as my-upg-100-list:
|
|
* countries-map.vue the map; legend opens on the COUNTRY level
|
|
* country-poster-wall.vue the poster grid, grouped by region, collapsible
|
|
*
|
|
* WHY A SEPARATE BUNDLE rather than two more profiles in my-upg-100-list:
|
|
* Several application profiles are fine; every REUSABLE component belongs in the library.
|
|
* PROFILES duplicate; COMPONENTS get promoted to library/ and parameterized. The
|
|
* wall here is @map/components/poster/PosterWall.vue — the same component the
|
|
* 100-list renders — differing only in data, taxonomy and copy.
|
|
*
|
|
* Profile registry — ProfileLoader lives inside @map and cannot use
|
|
* import.meta.glob to reach into a bundle's folder. The bundle MUST evaluate
|
|
* import.meta.glob('./*.vue') locally and hand the result to the loader via
|
|
* app.provide('profileModules', ...).
|
|
*/
|
|
|
|
// ─── Bundle-private profile registry ─────────────────────────────────────────
|
|
const profileModules = import.meta.glob('./*.vue')
|
|
|
|
// ★ THE LOCAL COLOUR GLOB IS GONE (C1b). This bundle registered its own src/colors/*.js over the
|
|
// shared set; all three modules (doxa-region, affinity-block, resource) now live in library/colors/
|
|
// where _registry.js discovers them for every bundle, and src/colors/ holds no .js at all. The glob
|
|
// matched nothing, so leaving it would be dead code that reads as a deliberate override.
|
|
|
|
// RTL text plugin (Arabic/Hebrew/Persian shaping): installed by useMapInstance through
|
|
// library/maps/rtl-text.js, on BOTH engines, before every map is constructed. Do not re-add a
|
|
// hand-rolled mapboxgl-only block here -- it was a strict subset of that call.
|
|
|
|
/**
|
|
* Each instance gets its own Pinia + i18n so multiple embeds on one page never
|
|
* bleed state into each other.
|
|
*/
|
|
function buildCountryPostersElement() {
|
|
return defineMapElement({ profileModules })
|
|
}
|
|
|
|
const CountryPostersElement = buildCountryPostersElement()
|
|
|
|
// Guard prevents "already registered" errors when this IIFE is loaded twice.
|
|
if (typeof customElements !== 'undefined') {
|
|
if (!customElements.get('country-posters-map')) {
|
|
customElements.define('country-posters-map', CountryPostersElement)
|
|
}
|
|
}
|
|
|
|
// <dxm-poster-section>: one poster section (any poster type), the reusable element this bundle ships first.
|
|
registerPosterSectionElement()
|
|
|
|
export default CountryPostersElement
|