diff --git a/plugin-designs/people-groups-grid/people-groups-grid.vue b/plugin-designs/people-groups-grid/people-groups-grid.vue index c0fd6b6f9..52d21072a 100644 --- a/plugin-designs/people-groups-grid/people-groups-grid.vue +++ b/plugin-designs/people-groups-grid/people-groups-grid.vue @@ -72,6 +72,25 @@ defineOptions({ inheritAttrs: false }) const props = defineProps({ // ── injected standalone deps (replace Nuxt useRuntimeConfig / useI18n / useLocalePath) ── profileConfig: { type: String, default: '' }, + // ── the merge props (Driver 2026-09-28: one parameterized grid) ────────────────────────────── + // Both defaults reproduce TODAY's grid exactly, so every existing host is unchanged until it + // opts in. That is deliberate: this component already ships in three places and a merge that + // moved any of them without being asked would be the drift the merge exists to remove. + // + // filtersToggle: WHICH TOGGLE, not whether. Measuring the two grids turned up that this one + // ALREADY has the show/hide control — same class, same labels, same aria-expanded, same caret — + // so the ruling's "keep the regions filters control" is a RESTYLE, not a capability to port. + // 'button' = today: a bordered pill with a hover fill and a COUNT BADGE of active filters. + // 'link' = the regions dashboard's: borderless text with a caret that rotates 180 on open. + // The count badge exists only on 'button'. Losing it would be a real regression, so 'link' keeps + // it rather than reproducing the regions markup exactly — the Driver asked for the look of the + // control, not for a feature to be removed with it. + filtersToggle: { type: String, default: 'button' }, + // backdrop: where worldmap.svg goes. 'filters' = today (behind the filters block, and only when + // search or filters are on). 'root' = the regions treatment, measured off dx-life's live page: + // the LIST ROOT at background-size 60%, background-position top, min-height 400px. 'none' = off. + // Same asset either way — assets/images/worldmap.svg — so this is placement, not a second copy. + backdrop: { type: String, default: 'filters' }, prayBaseUrl: { type: String, default: '' }, languageCode: { type: String, default: '' }, // ★ default '' NOT '/research/': a non-empty prop default is ALWAYS truthy, so the computed @@ -237,6 +256,9 @@ const cfg = computed(() => { // Only drawn when the block actually exists: with show-search and show-filters both off there is // no filter block to sit behind, and a backdrop with nothing on it is just noise. const filtersBackdrop = computed(() => { + // 'root' takes the watermark over, so the filters block must NOT also paint it: two copies of + // the same artwork at different sizes reads as a rendering fault, not a design. + if (backdropMode.value !== 'filters') return null if (!useSearch.value && !useFilters.value) return null const base = resolveAssetsBase(cfg.value) return { @@ -326,6 +348,25 @@ const t = computed(() => { // ── Cat-2 show/hide (accept the DOM-attribute string 'false') ────────────────── const truthy = (v) => !(v === false || v === 'false' || v === '0' || v === 0) +const toggleStyle = computed(() => (props.filtersToggle === 'link' ? 'link' : 'button')) +const backdropMode = computed(() => (['filters', 'root', 'none'].includes(props.backdrop) ? props.backdrop : 'filters')) +/** + * The root treatment, measured off dx-life's live /regions page rather than invented: the LIST + * ROOT carries worldmap.svg at background-size 60%, background-position top, no-repeat, with a + * 400px floor so the watermark has room to read on a short list. Same asset the 'filters' mode + * uses — this is placement, not a second copy. + */ +const rootBackdrop = computed(() => { + if (backdropMode.value !== 'root') return null + const base = resolveAssetsBase(cfg.value) + return { + backgroundImage: `url(${base}/images/worldmap.svg)`, + backgroundSize: '60%', + backgroundPosition: 'top', + backgroundRepeat: 'no-repeat', + minHeight: '400px', + } +}) const useSearch = computed(() => truthy(props.showSearch)) const useFilters = computed(() => truthy(props.showFilters)) const useTotal = computed(() => truthy(props.showTotal)) @@ -894,7 +935,7 @@ onMounted(() => {