diff --git a/plugin-designs/upg-neighbor/src/campaigns.vue b/plugin-designs/upg-neighbor/src/campaigns.vue index 9c6212730..9ad3a8112 100644 --- a/plugin-designs/upg-neighbor/src/campaigns.vue +++ b/plugin-designs/upg-neighbor/src/campaigns.vue @@ -8,7 +8,7 @@ * by the unreached population a campaign could reach; selecting one shows where to run it, whom it * reaches, and what content already exists in the language. Data: nearData.js. */ -import { inject, ref, computed, watch, onMounted, onBeforeUnmount } from 'vue' +import { inject, ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue' import { useMapInstance } from '@map/composables/useMapInstance.js' import { useShadowStyles } from '@map/composables/useShadowStyles.js' import { setProjectionOn } from '@map/composables/useMapProvider.js' @@ -125,7 +125,7 @@ function frame() { // The panel covers the left 440px on wide screens, the bottom 55% on a phone: frame what you can see. // In a right-to-left locale the panel sits on the right, so the wide padding moves with it. const rtl = !!mapContainer.value && getComputedStyle(mapContainer.value).direction === 'rtl' - const padding = w > 760 ? { top: 60, bottom: 60, left: rtl ? 60 : 440, right: rtl ? 440 : 60 } : { top: 40, bottom: Math.round(h * 0.55) + 20, left: 30, right: 30 } + const padding = w > 760 ? { top: 60, bottom: 60, left: rtl ? 60 : 440, right: rtl ? 440 : 60 } : { top: 40, bottom: (nbState.sheetDown ? 56 : Math.round(h * 0.55)) + 20, left: 30, right: 30 } try { m.stop() m.fitBounds([[Math.min(...lngs), Math.min(...lats)], [Math.max(...lngs), Math.max(...lats)]], { padding, maxZoom: 5.5, duration: 900 }) @@ -133,6 +133,8 @@ function frame() { } watch(() => [nbState.lang, data.value], () => { repaint(); frame() }) watch(list, () => repaint()) // the bubbles follow the search and the believers filter +// PHONE: the same handle as Mobilize; the list can be lowered to a bar and raised again. +function toggleSheet() { nbState.sheetDown = !nbState.sheetDown; nextTick(() => frame()) } onMounted(async () => { loadNearData(profileConfig).then((d) => { data.value = d; repaint(); frame() }) @@ -217,7 +219,12 @@ useShadowStyles(` .cp-note { padding:14px; color:#6b7280; font-size:13px; line-height:1.45; } .cp-hover { position:absolute; z-index:25; pointer-events:none; background:rgba(0,27,68,.92); color:#fff; font-size:12px; line-height:1.3; padding:5px 8px; border-radius:6px; max-width:260px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } .cp-maperr { position:absolute; inset-inline-end:12px; top:12px; z-index:15; background:#fff; border:1px solid #d9dee6; border-radius:8px; padding:8px 12px; font-size:13px; color:#6b7280; } - @media (max-width:760px) { .cp-panel { top:auto; inset-inline:6px; bottom:6px; width:auto; height:55%; } } + .cp-handle { display:none; align-items:center; justify-content:center; gap:8px; width:100%; min-height:40px; border:0; border-bottom:1px solid #eef0f4; + background:#fff; color:${NAVY}; font:600 12px/1 inherit; cursor:pointer; flex:0 0 auto; } + .cp-handle::before { content:''; width:36px; height:4px; border-radius:2px; background:#c9d1dd; } + .cp-handle:focus-visible { outline:2px solid ${NAVY}; outline-offset:-2px; } + @media (max-width:760px) { .cp-panel { top:auto; inset-inline:6px; bottom:6px; width:auto; height:55%; } + .cp-panel.down { height:56px; } .cp-panel.down > :not(.cp-handle) { display:none; } .cp-handle { display:flex; } } `, 'upgn-campaigns') @@ -227,7 +234,8 @@ useShadowStyles(`
{{ mapError }}
{{ hover.text }}
-