/
githubmirror
/
tabler
Обзор
Документация
Войти
/
githubmirror
/
tabler
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
shared/ui/MapVector.astro
157 строк
4 KB
Paweł Kuna
Clear remaining astro check hints in shared, docs, and screenshots (#2837)
08 авг 2026, 18:17
Не верифицирован
08 авг 2026, 18:17
2777fff
Код
Авторство
О чём код?
--- import mapsVector from '@data/maps-vector.json'; import CaptureScript from '../components/CaptureScript.astro'; interface MapData { title?: string; map: string; color?: string; filled?: boolean; zoom?: boolean; values?: Record<string, string>; markers?: { name: string; coords: string }[]; lines?: { from: string; to: string }[]; } interface Props { mapId: string; color?: string; ratio?: string; } const { mapId, color: colorProp, ratio = '4x3' } = Astro.props; const data = (mapsVector as Record<string, MapData>)[mapId]; const color = colorProp ?? data?.color ?? 'primary'; // scale1..scale10 — a 10-step color-mix ramp against var(--tblr-primary). const scale = Object.fromEntries( Array.from({ length: 10 }, (_, n) => [ `scale${n + 1}`, `color-mix(in srgb, transparent, var(--tblr-primary) ${(n + 1) * 10}%)`, ]), ); const markers = data?.markers?.map((marker) => ({ coords: marker.coords.split(',').map((n) => Number(n.trim())), name: marker.name, })); const mapKey = `map-${mapId}`; const mapSelector = `#map-${mapId}`; const mapLabel = data?.title ?? 'Map'; // jsVectorMap renders its own zoom +/- buttons inside this container when // zoom is enabled. `role="img"` flattens all descendants for assistive // tech, which would swallow those buttons — so only apply it when there's // no interactive chrome to hide. const hasZoomControls = Boolean(data?.zoom); const mapOptions = data ? { backgroundColor: 'transparent', regionStyle: { initial: { fill: 'var(--tblr-bg-surface-secondary)', stroke: data.filled ? '#fff' : 'var(--tblr-border-color)', strokeWidth: data.filled ? 1 : 2, }, }, zoomOnScroll: Boolean(data.zoom), zoomButtons: Boolean(data.zoom), ...(data.values ? { series: { regions: [{ attribute: 'fill', scale, values: data.values }] } } : {}), ...(markers ? { markers, markerStyle: { initial: { r: 4, stroke: '#fff', opacity: 1, strokeWidth: 3, strokeOpacity: 0.5, fill: `var(--tblr-${color})`, }, hover: { fill: `var(--tblr-${color})`, stroke: `var(--tblr-${color})` }, }, markerLabelStyle: { initial: { fontSize: 10 } }, } : {}), ...(data.lines ? { lines: data.lines, lineStyle: { strokeDasharray: '4 4', animation: true, stroke: 'rgba(98, 105, 118, .75)', strokeWidth: 0.5, }, } : {}), } : undefined; --- { data && ( <Fragment> <div class={`ratio ratio-${ratio}`}> <div> <div id={mapKey} class="w-100 h-100" role={hasZoomControls ? undefined : 'img'} aria-label={mapLabel} /> </div> </div> <CaptureScript> <!-- BEGIN MAP VECTOR --> <script is:inline define:vars={{ mapKey, mapSelector, mapName: data.map, mapOptions }}> window.tabler_map_vector ??= {}; function createMapVector() { const map = (window.tabler_map_vector[mapKey] = new jsVectorMap({ selector: mapSelector, map: mapName, ...mapOptions, // labels.markers.render is a function, not JSON-serializable — added here // rather than baked into mapOptions. ...(mapOptions.markers ? { labels: { markers: { render: (marker) => marker.name } } } : {}), })); window.addEventListener('resize', () => { map.updateSize(); }); } function initMapVector() { const container = document.querySelector(mapSelector); // jsVectorMap computes its initial scale from the container's layout // size. If the container is still 0x0 (e.g. layout hasn't settled // yet), that scale ends up 0, and a later resize divides by it, // producing a NaN transform. Wait for real dimensions first. if (container.offsetWidth && container.offsetHeight) { createMapVector(); return; } const observer = new ResizeObserver((entries) => { if (entries[0].contentRect.width && entries[0].contentRect.height) { observer.disconnect(); createMapVector(); } }); observer.observe(container); } document.readyState !== 'loading' ? initMapVector() : document.addEventListener('DOMContentLoaded', initMapVector, { once: true }); </script> <!-- END MAP VECTOR --> </CaptureScript> </Fragment> ) }