zenit-sdk 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-R73LRYVJ.mjs → chunk-52CLFD4L.mjs} +703 -109
- package/dist/chunk-52CLFD4L.mjs.map +1 -0
- package/dist/{index-Da0hFqDL.d.mts → index-kGwfqTc_.d.mts} +5 -0
- package/dist/{index-Da0hFqDL.d.ts → index-kGwfqTc_.d.ts} +5 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +702 -108
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +702 -108
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-R73LRYVJ.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1403,7 +1403,7 @@ function normalizeBbox(input) {
|
|
|
1403
1403
|
}
|
|
1404
1404
|
|
|
1405
1405
|
// src/react/ZenitMap.tsx
|
|
1406
|
-
var import_react = require("react");
|
|
1406
|
+
var import_react = __toESM(require("react"));
|
|
1407
1407
|
var import_react_leaflet = require("react-leaflet");
|
|
1408
1408
|
var import_leaflet = __toESM(require("leaflet"));
|
|
1409
1409
|
|
|
@@ -1470,6 +1470,7 @@ function getEffectiveLayerOpacity(baseOpacity, zoom, layerType, geometryType, op
|
|
|
1470
1470
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1471
1471
|
var DEFAULT_CENTER = [0, 0];
|
|
1472
1472
|
var DEFAULT_ZOOM = 3;
|
|
1473
|
+
var LABELS_PANE_NAME = "zenit-labels-pane";
|
|
1473
1474
|
function computeBBoxFromGeojson(geojson) {
|
|
1474
1475
|
if (!geojson) return null;
|
|
1475
1476
|
if (!Array.isArray(geojson.features) || geojson.features.length === 0) return null;
|
|
@@ -1510,6 +1511,23 @@ function mergeBBoxes(bboxes) {
|
|
|
1510
1511
|
{ ...first }
|
|
1511
1512
|
);
|
|
1512
1513
|
}
|
|
1514
|
+
function isRecord(value) {
|
|
1515
|
+
return typeof value === "object" && value !== null;
|
|
1516
|
+
}
|
|
1517
|
+
function isGeoJsonFeatureCollection(value) {
|
|
1518
|
+
if (!isRecord(value)) return false;
|
|
1519
|
+
const features = value.features;
|
|
1520
|
+
if (!Array.isArray(features)) return false;
|
|
1521
|
+
const type = value.type;
|
|
1522
|
+
return type === void 0 || type === "FeatureCollection";
|
|
1523
|
+
}
|
|
1524
|
+
function extractGeoJsonFeatureCollection(value) {
|
|
1525
|
+
if (isRecord(value) && "data" in value) {
|
|
1526
|
+
const data = value.data;
|
|
1527
|
+
return isGeoJsonFeatureCollection(data) ? data : null;
|
|
1528
|
+
}
|
|
1529
|
+
return isGeoJsonFeatureCollection(value) ? value : null;
|
|
1530
|
+
}
|
|
1513
1531
|
function getFeatureLayerId(feature) {
|
|
1514
1532
|
const layerId = feature?.properties?.__zenit_layerId ?? feature?.properties?.layerId ?? feature?.properties?.layer_id;
|
|
1515
1533
|
if (layerId === void 0 || layerId === null) return null;
|
|
@@ -1518,6 +1536,459 @@ function getFeatureLayerId(feature) {
|
|
|
1518
1536
|
function escapeHtml(value) {
|
|
1519
1537
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1520
1538
|
}
|
|
1539
|
+
var DESCRIPTION_KEYS = /* @__PURE__ */ new Set(["descripcion", "description"]);
|
|
1540
|
+
var POPUP_EXCLUDED_KEYS = /* @__PURE__ */ new Set(["geom", "geometry"]);
|
|
1541
|
+
var POPUP_HEADER_KEYS = ["nombre", "name", "title", "titulo"];
|
|
1542
|
+
var POPUP_STYLE_ID = "zenit-leaflet-popup-styles";
|
|
1543
|
+
var DESKTOP_POPUP_DIMENSIONS = { maxWidth: 350, minWidth: 280, maxHeight: 480 };
|
|
1544
|
+
var MOBILE_POPUP_DIMENSIONS = { maxWidth: 280, minWidth: 240, maxHeight: 380 };
|
|
1545
|
+
var ZENIT_LEAFLET_POPUP_STYLES = `
|
|
1546
|
+
/* ===== Zenit Leaflet Popup - Modern Professional Styling ===== */
|
|
1547
|
+
|
|
1548
|
+
/* Main popup wrapper */
|
|
1549
|
+
.zenit-leaflet-popup .leaflet-popup-content-wrapper {
|
|
1550
|
+
border-radius: 12px;
|
|
1551
|
+
box-shadow:
|
|
1552
|
+
0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
1553
|
+
0 2px 4px -2px rgba(0, 0, 0, 0.1),
|
|
1554
|
+
0 0 0 1px rgba(0, 0, 0, 0.05);
|
|
1555
|
+
padding: 0;
|
|
1556
|
+
background: #ffffff;
|
|
1557
|
+
overflow: hidden;
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
/* Content area with scroll support */
|
|
1561
|
+
.zenit-leaflet-popup .leaflet-popup-content {
|
|
1562
|
+
margin: 0;
|
|
1563
|
+
padding: 0;
|
|
1564
|
+
font-size: 13px;
|
|
1565
|
+
line-height: 1.5;
|
|
1566
|
+
color: #374151;
|
|
1567
|
+
min-width: 100%;
|
|
1568
|
+
max-height: min(70vh, 480px);
|
|
1569
|
+
overflow-y: auto;
|
|
1570
|
+
overflow-x: hidden;
|
|
1571
|
+
scrollbar-width: thin;
|
|
1572
|
+
scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
/* Popup tip/arrow shadow */
|
|
1576
|
+
.zenit-leaflet-popup .leaflet-popup-tip-container {
|
|
1577
|
+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
.zenit-leaflet-popup .leaflet-popup-tip {
|
|
1581
|
+
background: #ffffff;
|
|
1582
|
+
box-shadow: none;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
/* Close button styling */
|
|
1586
|
+
.zenit-leaflet-popup .leaflet-popup-close-button {
|
|
1587
|
+
color: #9ca3af;
|
|
1588
|
+
font-size: 18px;
|
|
1589
|
+
font-weight: 400;
|
|
1590
|
+
width: 28px;
|
|
1591
|
+
height: 28px;
|
|
1592
|
+
padding: 0;
|
|
1593
|
+
margin: 8px 8px 0 0;
|
|
1594
|
+
display: flex;
|
|
1595
|
+
align-items: center;
|
|
1596
|
+
justify-content: center;
|
|
1597
|
+
border-radius: 6px;
|
|
1598
|
+
transition: all 0.15s ease;
|
|
1599
|
+
z-index: 10;
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
.zenit-leaflet-popup .leaflet-popup-close-button:hover {
|
|
1603
|
+
color: #374151;
|
|
1604
|
+
background-color: #f3f4f6;
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
.zenit-leaflet-popup .leaflet-popup-close-button:active {
|
|
1608
|
+
background-color: #e5e7eb;
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
/* Main card container */
|
|
1612
|
+
.zenit-popup-card {
|
|
1613
|
+
display: flex;
|
|
1614
|
+
flex-direction: column;
|
|
1615
|
+
gap: 0;
|
|
1616
|
+
padding: 16px;
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
.zenit-popup-header {
|
|
1620
|
+
padding-bottom: 12px;
|
|
1621
|
+
border-bottom: 1px solid #e5e7eb;
|
|
1622
|
+
margin-bottom: 4px;
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
.zenit-popup-title {
|
|
1626
|
+
font-size: 14px;
|
|
1627
|
+
font-weight: 700;
|
|
1628
|
+
color: #111827;
|
|
1629
|
+
letter-spacing: 0.01em;
|
|
1630
|
+
line-height: 1.4;
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
/* Individual row styling with subtle separator */
|
|
1634
|
+
.zenit-popup-row {
|
|
1635
|
+
display: flex;
|
|
1636
|
+
flex-direction: column;
|
|
1637
|
+
gap: 2px;
|
|
1638
|
+
padding: 10px 0;
|
|
1639
|
+
border-bottom: 1px solid #f3f4f6;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
.zenit-popup-row:first-child {
|
|
1643
|
+
padding-top: 0;
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
.zenit-popup-row:last-child {
|
|
1647
|
+
border-bottom: none;
|
|
1648
|
+
padding-bottom: 0;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
/* Label styling - small, gray, uppercase */
|
|
1652
|
+
.zenit-popup-label {
|
|
1653
|
+
font-size: 10px;
|
|
1654
|
+
font-weight: 500;
|
|
1655
|
+
color: #9ca3af;
|
|
1656
|
+
text-transform: uppercase;
|
|
1657
|
+
letter-spacing: 0.05em;
|
|
1658
|
+
line-height: 1.4;
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
/* Value styling - darker, readable */
|
|
1662
|
+
.zenit-popup-value {
|
|
1663
|
+
font-size: 13px;
|
|
1664
|
+
font-weight: 400;
|
|
1665
|
+
color: #1f2937;
|
|
1666
|
+
overflow-wrap: break-word;
|
|
1667
|
+
word-break: break-word;
|
|
1668
|
+
line-height: 1.5;
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
.zenit-popup-link {
|
|
1672
|
+
color: #2563eb;
|
|
1673
|
+
text-decoration: underline;
|
|
1674
|
+
font-weight: 500;
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
.zenit-popup-link:hover {
|
|
1678
|
+
color: #1d4ed8;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
/* Special styling for description field */
|
|
1682
|
+
.zenit-popup-row.zenit-popup-description {
|
|
1683
|
+
background-color: #f9fafb;
|
|
1684
|
+
margin: 0 -16px;
|
|
1685
|
+
padding: 12px 16px;
|
|
1686
|
+
border-bottom: 1px solid #e5e7eb;
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
.zenit-popup-row.zenit-popup-description:first-child {
|
|
1690
|
+
margin-top: 0;
|
|
1691
|
+
border-radius: 0;
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
.zenit-popup-row.zenit-popup-description .zenit-popup-value {
|
|
1695
|
+
font-size: 13px;
|
|
1696
|
+
line-height: 1.6;
|
|
1697
|
+
color: #374151;
|
|
1698
|
+
max-height: 150px;
|
|
1699
|
+
overflow-y: auto;
|
|
1700
|
+
padding-right: 4px;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
/* Preformatted text (JSON objects) */
|
|
1704
|
+
.zenit-popup-pre {
|
|
1705
|
+
margin: 0;
|
|
1706
|
+
font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
|
|
1707
|
+
font-size: 11px;
|
|
1708
|
+
white-space: pre-wrap;
|
|
1709
|
+
word-break: break-word;
|
|
1710
|
+
color: #4b5563;
|
|
1711
|
+
background-color: #f9fafb;
|
|
1712
|
+
padding: 8px;
|
|
1713
|
+
border-radius: 6px;
|
|
1714
|
+
border: 1px solid #e5e7eb;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
/* Empty state styling */
|
|
1718
|
+
.zenit-popup-empty {
|
|
1719
|
+
font-size: 13px;
|
|
1720
|
+
color: #9ca3af;
|
|
1721
|
+
font-style: italic;
|
|
1722
|
+
text-align: center;
|
|
1723
|
+
padding: 20px 0;
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
/* Webkit scrollbar styling */
|
|
1727
|
+
.zenit-leaflet-popup .leaflet-popup-content::-webkit-scrollbar {
|
|
1728
|
+
width: 6px;
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
.zenit-leaflet-popup .leaflet-popup-content::-webkit-scrollbar-track {
|
|
1732
|
+
background: transparent;
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
.zenit-leaflet-popup .leaflet-popup-content::-webkit-scrollbar-thumb {
|
|
1736
|
+
background-color: rgba(156, 163, 175, 0.4);
|
|
1737
|
+
border-radius: 3px;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
.zenit-leaflet-popup .leaflet-popup-content::-webkit-scrollbar-thumb:hover {
|
|
1741
|
+
background-color: rgba(107, 114, 128, 0.6);
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
/* Scrollbar for description field */
|
|
1745
|
+
.zenit-popup-row.zenit-popup-description .zenit-popup-value::-webkit-scrollbar {
|
|
1746
|
+
width: 4px;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
.zenit-popup-row.zenit-popup-description .zenit-popup-value::-webkit-scrollbar-track {
|
|
1750
|
+
background: transparent;
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
.zenit-popup-row.zenit-popup-description .zenit-popup-value::-webkit-scrollbar-thumb {
|
|
1754
|
+
background-color: rgba(156, 163, 175, 0.4);
|
|
1755
|
+
border-radius: 2px;
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
/* ===== Responsive: Mobile (<640px) ===== */
|
|
1759
|
+
@media (max-width: 640px) {
|
|
1760
|
+
.zenit-leaflet-popup .leaflet-popup-content-wrapper {
|
|
1761
|
+
border-radius: 10px;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
.zenit-leaflet-popup .leaflet-popup-close-button {
|
|
1765
|
+
width: 26px;
|
|
1766
|
+
height: 26px;
|
|
1767
|
+
font-size: 16px;
|
|
1768
|
+
margin: 6px 6px 0 0;
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
.zenit-popup-card {
|
|
1772
|
+
padding: 12px;
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
.zenit-leaflet-popup .leaflet-popup-content {
|
|
1776
|
+
max-height: min(65vh, 380px);
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
.zenit-popup-header {
|
|
1780
|
+
padding-bottom: 10px;
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
.zenit-popup-title {
|
|
1784
|
+
font-size: 13px;
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
.zenit-popup-row {
|
|
1788
|
+
padding: 8px 0;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
.zenit-popup-label {
|
|
1792
|
+
font-size: 9px;
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
.zenit-popup-value {
|
|
1796
|
+
font-size: 12px;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
.zenit-popup-row.zenit-popup-description {
|
|
1800
|
+
margin: 0 -12px;
|
|
1801
|
+
padding: 10px 12px;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
.zenit-popup-row.zenit-popup-description .zenit-popup-value {
|
|
1805
|
+
font-size: 12px;
|
|
1806
|
+
max-height: 120px;
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
.zenit-popup-pre {
|
|
1810
|
+
font-size: 10px;
|
|
1811
|
+
padding: 6px;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
.zenit-popup-empty {
|
|
1815
|
+
font-size: 12px;
|
|
1816
|
+
padding: 16px 0;
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
/* ===== Map tooltip styling ===== */
|
|
1821
|
+
.zenit-map-tooltip {
|
|
1822
|
+
background-color: rgba(31, 41, 55, 0.95);
|
|
1823
|
+
border: none;
|
|
1824
|
+
border-radius: 6px;
|
|
1825
|
+
color: #ffffff;
|
|
1826
|
+
font-size: 12px;
|
|
1827
|
+
font-weight: 500;
|
|
1828
|
+
padding: 6px 10px;
|
|
1829
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
.zenit-map-tooltip::before {
|
|
1833
|
+
border-top-color: rgba(31, 41, 55, 0.95);
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
.polygon-label-tooltip {
|
|
1837
|
+
z-index: 600 !important;
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
.zenit-map-shell.popup-open .zenit-label-marker,
|
|
1841
|
+
.zenit-map-shell.popup-open .polygon-label-tooltip,
|
|
1842
|
+
.zenit-map-shell.popup-open .click-for-detail-hint,
|
|
1843
|
+
.zenit-map-shell.popup-open .zenit-map-tooltip {
|
|
1844
|
+
display: none !important;
|
|
1845
|
+
}
|
|
1846
|
+
`;
|
|
1847
|
+
function ensurePopupStyles() {
|
|
1848
|
+
if (typeof document === "undefined") return;
|
|
1849
|
+
if (document.getElementById(POPUP_STYLE_ID)) return;
|
|
1850
|
+
const styleTag = document.createElement("style");
|
|
1851
|
+
styleTag.id = POPUP_STYLE_ID;
|
|
1852
|
+
styleTag.textContent = ZENIT_LEAFLET_POPUP_STYLES;
|
|
1853
|
+
document.head.appendChild(styleTag);
|
|
1854
|
+
}
|
|
1855
|
+
function getPopupDimensions() {
|
|
1856
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
1857
|
+
return DESKTOP_POPUP_DIMENSIONS;
|
|
1858
|
+
}
|
|
1859
|
+
return window.matchMedia("(max-width: 640px)").matches ? MOBILE_POPUP_DIMENSIONS : DESKTOP_POPUP_DIMENSIONS;
|
|
1860
|
+
}
|
|
1861
|
+
function normalizeDescriptionValue(value) {
|
|
1862
|
+
if (value === void 0 || value === null) return null;
|
|
1863
|
+
if (typeof value === "string") {
|
|
1864
|
+
const trimmed = value.trim();
|
|
1865
|
+
return trimmed ? trimmed : null;
|
|
1866
|
+
}
|
|
1867
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
1868
|
+
return String(value);
|
|
1869
|
+
}
|
|
1870
|
+
return null;
|
|
1871
|
+
}
|
|
1872
|
+
function extractDescriptionValue(properties) {
|
|
1873
|
+
if (!properties) return null;
|
|
1874
|
+
const matches = Object.entries(properties).find(
|
|
1875
|
+
([key]) => DESCRIPTION_KEYS.has(key.toLowerCase())
|
|
1876
|
+
);
|
|
1877
|
+
if (!matches) return null;
|
|
1878
|
+
return normalizeDescriptionValue(matches[1]);
|
|
1879
|
+
}
|
|
1880
|
+
function safeJsonStringify(value) {
|
|
1881
|
+
try {
|
|
1882
|
+
const json = JSON.stringify(value, null, 2);
|
|
1883
|
+
if (json !== void 0) return json;
|
|
1884
|
+
} catch {
|
|
1885
|
+
}
|
|
1886
|
+
return String(value);
|
|
1887
|
+
}
|
|
1888
|
+
function renderPopupValue(value) {
|
|
1889
|
+
if (value === null || value === void 0) {
|
|
1890
|
+
return '<span class="zenit-popup-empty">Sin datos</span>';
|
|
1891
|
+
}
|
|
1892
|
+
if (value instanceof Date) {
|
|
1893
|
+
return `<span>${escapeHtml(value.toLocaleDateString("es-GT"))}</span>`;
|
|
1894
|
+
}
|
|
1895
|
+
if (typeof value === "number") {
|
|
1896
|
+
return `<span>${escapeHtml(value.toLocaleString("es-GT"))}</span>`;
|
|
1897
|
+
}
|
|
1898
|
+
if (typeof value === "string") {
|
|
1899
|
+
const trimmed = value.trim();
|
|
1900
|
+
const isLikelyDate = /^\d{4}-\d{2}-\d{2}/.test(trimmed) || trimmed.includes("T");
|
|
1901
|
+
if (isLikelyDate) {
|
|
1902
|
+
const parsed = Date.parse(trimmed);
|
|
1903
|
+
if (!Number.isNaN(parsed)) {
|
|
1904
|
+
return `<span>${escapeHtml(new Date(parsed).toLocaleDateString("es-GT"))}</span>`;
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
try {
|
|
1908
|
+
const parsedUrl = new URL(trimmed);
|
|
1909
|
+
if (parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:") {
|
|
1910
|
+
const safeHref = escapeHtml(parsedUrl.toString());
|
|
1911
|
+
return `<a class="zenit-popup-link" href="${safeHref}" target="_blank" rel="noopener noreferrer">${safeHref}</a>`;
|
|
1912
|
+
}
|
|
1913
|
+
} catch {
|
|
1914
|
+
}
|
|
1915
|
+
return `<span>${escapeHtml(trimmed || value)}</span>`;
|
|
1916
|
+
}
|
|
1917
|
+
if (typeof value === "object") {
|
|
1918
|
+
const json = safeJsonStringify(value);
|
|
1919
|
+
return `<pre class="zenit-popup-pre">${escapeHtml(json)}</pre>`;
|
|
1920
|
+
}
|
|
1921
|
+
return `<span>${escapeHtml(String(value))}</span>`;
|
|
1922
|
+
}
|
|
1923
|
+
function shouldIncludePopupEntry(key, value) {
|
|
1924
|
+
if (!key) return false;
|
|
1925
|
+
const normalized = key.trim().toLowerCase();
|
|
1926
|
+
if (!normalized) return false;
|
|
1927
|
+
if (normalized.startsWith("_")) return false;
|
|
1928
|
+
if (POPUP_EXCLUDED_KEYS.has(normalized)) return false;
|
|
1929
|
+
if (value === null || value === void 0) return false;
|
|
1930
|
+
if (typeof value === "string" && !value.trim()) return false;
|
|
1931
|
+
return true;
|
|
1932
|
+
}
|
|
1933
|
+
function isDescriptionKey(key) {
|
|
1934
|
+
const normalized = key.trim().toLowerCase();
|
|
1935
|
+
return DESCRIPTION_KEYS.has(normalized);
|
|
1936
|
+
}
|
|
1937
|
+
function extractPopupHeader(properties) {
|
|
1938
|
+
if (!properties) return null;
|
|
1939
|
+
const entry = Object.entries(properties).find(
|
|
1940
|
+
(candidate) => {
|
|
1941
|
+
const [key, value] = candidate;
|
|
1942
|
+
return POPUP_HEADER_KEYS.includes(key.trim().toLowerCase()) && typeof value === "string" && value.trim().length > 0;
|
|
1943
|
+
}
|
|
1944
|
+
);
|
|
1945
|
+
if (!entry) return null;
|
|
1946
|
+
return entry[1].trim();
|
|
1947
|
+
}
|
|
1948
|
+
function formatLabel(key) {
|
|
1949
|
+
return key.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").trim();
|
|
1950
|
+
}
|
|
1951
|
+
function createPopupContent(properties) {
|
|
1952
|
+
const headerText = extractPopupHeader(properties);
|
|
1953
|
+
const entries = Object.entries(properties).filter(([key, value]) => {
|
|
1954
|
+
if (!shouldIncludePopupEntry(key, value)) return false;
|
|
1955
|
+
if (headerText && POPUP_HEADER_KEYS.includes(key.trim().toLowerCase())) {
|
|
1956
|
+
return false;
|
|
1957
|
+
}
|
|
1958
|
+
return true;
|
|
1959
|
+
});
|
|
1960
|
+
if (entries.length === 0) {
|
|
1961
|
+
return `<div class="zenit-popup-card"><div class="zenit-popup-empty">Sin datos disponibles</div></div>`;
|
|
1962
|
+
}
|
|
1963
|
+
const descriptionEntry = entries.find(([key]) => isDescriptionKey(key));
|
|
1964
|
+
const otherEntries = entries.filter(([key]) => !isDescriptionKey(key));
|
|
1965
|
+
let rowsHtml = "";
|
|
1966
|
+
if (descriptionEntry) {
|
|
1967
|
+
const [key, value] = descriptionEntry;
|
|
1968
|
+
const label = escapeHtml(formatLabel(key));
|
|
1969
|
+
const valueHtml = renderPopupValue(value);
|
|
1970
|
+
rowsHtml += `
|
|
1971
|
+
<div class="zenit-popup-row zenit-popup-description">
|
|
1972
|
+
<div class="zenit-popup-label">${label}</div>
|
|
1973
|
+
<div class="zenit-popup-value">${valueHtml}</div>
|
|
1974
|
+
</div>
|
|
1975
|
+
`;
|
|
1976
|
+
}
|
|
1977
|
+
rowsHtml += otherEntries.map(([key, value]) => {
|
|
1978
|
+
const label = escapeHtml(formatLabel(key));
|
|
1979
|
+
const valueHtml = renderPopupValue(value);
|
|
1980
|
+
return `
|
|
1981
|
+
<div class="zenit-popup-row">
|
|
1982
|
+
<div class="zenit-popup-label">${label}</div>
|
|
1983
|
+
<div class="zenit-popup-value">${valueHtml}</div>
|
|
1984
|
+
</div>
|
|
1985
|
+
`;
|
|
1986
|
+
}).join("");
|
|
1987
|
+
const headerHtml = headerText ? `<div class="zenit-popup-header"><div class="zenit-popup-title">${escapeHtml(
|
|
1988
|
+
headerText
|
|
1989
|
+
)}</div></div>` : "";
|
|
1990
|
+
return `<div class="zenit-popup-card">${headerHtml}${rowsHtml}</div>`;
|
|
1991
|
+
}
|
|
1521
1992
|
function withAlpha(color, alpha) {
|
|
1522
1993
|
const trimmed = color.trim();
|
|
1523
1994
|
if (trimmed.startsWith("#")) {
|
|
@@ -1586,40 +2057,39 @@ function getFeatureStyleOverrides(feature) {
|
|
|
1586
2057
|
function buildFeaturePopupHtml(feature) {
|
|
1587
2058
|
const properties = feature?.properties;
|
|
1588
2059
|
if (!properties) return null;
|
|
1589
|
-
const
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
const
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
if (
|
|
1615
|
-
const
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
return `<div>${parts.join("")}</div>`;
|
|
2060
|
+
const rendered = createPopupContent(properties);
|
|
2061
|
+
return rendered ? rendered : null;
|
|
2062
|
+
}
|
|
2063
|
+
var POINT_GEOMETRY_TYPES = /* @__PURE__ */ new Set(["Point", "MultiPoint"]);
|
|
2064
|
+
function getGeometryType(feature) {
|
|
2065
|
+
const t = feature?.geometry?.type;
|
|
2066
|
+
return typeof t === "string" ? t : null;
|
|
2067
|
+
}
|
|
2068
|
+
function isPointGeometry(feature) {
|
|
2069
|
+
const geometryType = getGeometryType(feature);
|
|
2070
|
+
return geometryType !== null && POINT_GEOMETRY_TYPES.has(geometryType);
|
|
2071
|
+
}
|
|
2072
|
+
function isNonPointGeometry(feature) {
|
|
2073
|
+
const geometryType = getGeometryType(feature);
|
|
2074
|
+
return geometryType !== null && !POINT_GEOMETRY_TYPES.has(geometryType);
|
|
2075
|
+
}
|
|
2076
|
+
function buildFeatureCollection(features) {
|
|
2077
|
+
return {
|
|
2078
|
+
type: "FeatureCollection",
|
|
2079
|
+
features
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
function pickIntersectFeature(baseFeature, candidates) {
|
|
2083
|
+
if (!Array.isArray(candidates) || candidates.length === 0) return null;
|
|
2084
|
+
const baseId = baseFeature?.id;
|
|
2085
|
+
if (baseId !== void 0 && baseId !== null) {
|
|
2086
|
+
const matchById = candidates.find((candidate) => candidate?.id === baseId);
|
|
2087
|
+
if (matchById) return matchById;
|
|
2088
|
+
}
|
|
2089
|
+
const matchWithDescription = candidates.find(
|
|
2090
|
+
(candidate) => extractDescriptionValue(candidate?.properties)
|
|
2091
|
+
);
|
|
2092
|
+
return matchWithDescription ?? candidates[0];
|
|
1623
2093
|
}
|
|
1624
2094
|
function normalizeCenterTuple(center) {
|
|
1625
2095
|
if (!center) return null;
|
|
@@ -1740,7 +2210,9 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
1740
2210
|
const [loadingMap, setLoadingMap] = (0, import_react.useState)(false);
|
|
1741
2211
|
const [mapError, setMapError] = (0, import_react.useState)(null);
|
|
1742
2212
|
const [mapInstance, setMapInstance] = (0, import_react.useState)(null);
|
|
2213
|
+
const [panesReady, setPanesReady] = (0, import_react.useState)(false);
|
|
1743
2214
|
const [currentZoom, setCurrentZoom] = (0, import_react.useState)(initialZoom ?? DEFAULT_ZOOM);
|
|
2215
|
+
const [isPopupOpen, setIsPopupOpen] = (0, import_react.useState)(false);
|
|
1744
2216
|
const [isMobile, setIsMobile] = (0, import_react.useState)(() => {
|
|
1745
2217
|
if (typeof window === "undefined") return false;
|
|
1746
2218
|
return window.matchMedia("(max-width: 768px)").matches;
|
|
@@ -1764,6 +2236,36 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
1764
2236
|
}
|
|
1765
2237
|
return;
|
|
1766
2238
|
}, []);
|
|
2239
|
+
(0, import_react.useEffect)(() => {
|
|
2240
|
+
if (featureInfoMode === "popup") {
|
|
2241
|
+
ensurePopupStyles();
|
|
2242
|
+
}
|
|
2243
|
+
}, [featureInfoMode]);
|
|
2244
|
+
(0, import_react.useEffect)(() => {
|
|
2245
|
+
if (featureInfoMode !== "popup") {
|
|
2246
|
+
setIsPopupOpen(false);
|
|
2247
|
+
}
|
|
2248
|
+
}, [featureInfoMode]);
|
|
2249
|
+
(0, import_react.useEffect)(() => {
|
|
2250
|
+
if (!mapInstance) return;
|
|
2251
|
+
const popupPane = mapInstance.getPane("popupPane");
|
|
2252
|
+
if (popupPane) {
|
|
2253
|
+
popupPane.style.zIndex = "800";
|
|
2254
|
+
}
|
|
2255
|
+
const labelsPane = mapInstance.getPane(LABELS_PANE_NAME) ?? mapInstance.createPane(LABELS_PANE_NAME);
|
|
2256
|
+
labelsPane.style.zIndex = "600";
|
|
2257
|
+
}, [mapInstance]);
|
|
2258
|
+
(0, import_react.useEffect)(() => {
|
|
2259
|
+
if (!mapInstance) return;
|
|
2260
|
+
const handlePopupOpen = () => setIsPopupOpen(true);
|
|
2261
|
+
const handlePopupClose = () => setIsPopupOpen(false);
|
|
2262
|
+
mapInstance.on("popupopen", handlePopupOpen);
|
|
2263
|
+
mapInstance.on("popupclose", handlePopupClose);
|
|
2264
|
+
return () => {
|
|
2265
|
+
mapInstance.off("popupopen", handlePopupOpen);
|
|
2266
|
+
mapInstance.off("popupclose", handlePopupClose);
|
|
2267
|
+
};
|
|
2268
|
+
}, [mapInstance]);
|
|
1767
2269
|
const layerStyleIndex = (0, import_react.useMemo)(() => {
|
|
1768
2270
|
const index = /* @__PURE__ */ new Map();
|
|
1769
2271
|
(map?.mapLayers ?? []).forEach((entry) => {
|
|
@@ -2054,16 +2556,21 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2054
2556
|
(targetMap, targetLayers) => {
|
|
2055
2557
|
const baseZIndex = 400;
|
|
2056
2558
|
targetLayers.forEach((layer) => {
|
|
2057
|
-
const paneName = `zenit-layer-${layer.layerId}`;
|
|
2058
|
-
const pane = targetMap.getPane(paneName) ?? targetMap.createPane(paneName);
|
|
2059
2559
|
const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;
|
|
2060
|
-
|
|
2560
|
+
const orderOffset = Math.max(0, Math.min(order, 150));
|
|
2561
|
+
const fillPaneName = `zenit-layer-${layer.layerId}-fill`;
|
|
2562
|
+
const pointPaneName = `zenit-layer-${layer.layerId}-points`;
|
|
2563
|
+
const fillPane = targetMap.getPane(fillPaneName) ?? targetMap.createPane(fillPaneName);
|
|
2564
|
+
const pointPane = targetMap.getPane(pointPaneName) ?? targetMap.createPane(pointPaneName);
|
|
2565
|
+
fillPane.style.zIndex = String(baseZIndex + orderOffset);
|
|
2566
|
+
pointPane.style.zIndex = String(baseZIndex + orderOffset + 100);
|
|
2061
2567
|
});
|
|
2062
2568
|
},
|
|
2063
2569
|
[]
|
|
2064
2570
|
);
|
|
2065
2571
|
const handleMapReady = (0, import_react.useCallback)(
|
|
2066
2572
|
(instance) => {
|
|
2573
|
+
setPanesReady(false);
|
|
2067
2574
|
setMapInstance(instance);
|
|
2068
2575
|
onMapReady?.(instance);
|
|
2069
2576
|
},
|
|
@@ -2071,6 +2578,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2071
2578
|
);
|
|
2072
2579
|
(0, import_react.useEffect)(() => {
|
|
2073
2580
|
if (!mapInstance) {
|
|
2581
|
+
setPanesReady(false);
|
|
2074
2582
|
return;
|
|
2075
2583
|
}
|
|
2076
2584
|
if (orderedLayers.length === 0) {
|
|
@@ -2081,6 +2589,12 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2081
2589
|
displayOrder: layer.displayOrder
|
|
2082
2590
|
}));
|
|
2083
2591
|
ensureLayerPanes(mapInstance, layerTargets);
|
|
2592
|
+
const first = layerTargets[0];
|
|
2593
|
+
const testPane = mapInstance.getPane(`zenit-layer-${first.layerId}-fill`);
|
|
2594
|
+
const labelsPane = mapInstance.getPane(LABELS_PANE_NAME);
|
|
2595
|
+
if (testPane && labelsPane) {
|
|
2596
|
+
setPanesReady(true);
|
|
2597
|
+
}
|
|
2084
2598
|
}, [mapInstance, orderedLayers, ensureLayerPanes]);
|
|
2085
2599
|
const overlayOnEachFeature = (0, import_react.useMemo)(() => {
|
|
2086
2600
|
return (feature, layer) => {
|
|
@@ -2098,7 +2612,17 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2098
2612
|
if (featureInfoMode === "popup") {
|
|
2099
2613
|
const content = buildFeaturePopupHtml(feature);
|
|
2100
2614
|
if (content) {
|
|
2101
|
-
|
|
2615
|
+
const { maxWidth, minWidth, maxHeight } = getPopupDimensions();
|
|
2616
|
+
layer.bindPopup(content, {
|
|
2617
|
+
maxWidth,
|
|
2618
|
+
minWidth,
|
|
2619
|
+
maxHeight,
|
|
2620
|
+
className: "zenit-leaflet-popup custom-leaflet-popup",
|
|
2621
|
+
autoPan: true,
|
|
2622
|
+
closeButton: true,
|
|
2623
|
+
keepInView: true,
|
|
2624
|
+
offset: import_leaflet.default.point(0, -24)
|
|
2625
|
+
});
|
|
2102
2626
|
}
|
|
2103
2627
|
}
|
|
2104
2628
|
if (isPointFeature && layer.bindTooltip) {
|
|
@@ -2109,7 +2633,38 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2109
2633
|
className: "zenit-map-tooltip"
|
|
2110
2634
|
});
|
|
2111
2635
|
}
|
|
2112
|
-
layer.on("click", () =>
|
|
2636
|
+
layer.on("click", () => {
|
|
2637
|
+
if (featureInfoMode === "popup" && client && layerId !== void 0 && !extractDescriptionValue(feature?.properties) && feature?.geometry) {
|
|
2638
|
+
const trackedFeature = feature;
|
|
2639
|
+
if (!trackedFeature.__zenit_popup_loaded) {
|
|
2640
|
+
trackedFeature.__zenit_popup_loaded = true;
|
|
2641
|
+
client.layers.getLayerGeoJsonIntersect({
|
|
2642
|
+
id: layerId,
|
|
2643
|
+
geometry: feature.geometry
|
|
2644
|
+
}).then((response) => {
|
|
2645
|
+
const geo = extractGeoJsonFeatureCollection(response);
|
|
2646
|
+
const candidates = geo?.features ?? [];
|
|
2647
|
+
const resolved = pickIntersectFeature(feature, candidates);
|
|
2648
|
+
if (!resolved?.properties) return;
|
|
2649
|
+
const mergedProperties = {
|
|
2650
|
+
...trackedFeature.properties ?? {},
|
|
2651
|
+
...resolved.properties
|
|
2652
|
+
};
|
|
2653
|
+
trackedFeature.properties = mergedProperties;
|
|
2654
|
+
const updatedHtml = buildFeaturePopupHtml({
|
|
2655
|
+
...feature,
|
|
2656
|
+
properties: mergedProperties
|
|
2657
|
+
});
|
|
2658
|
+
if (updatedHtml && layer.setPopupContent) {
|
|
2659
|
+
layer.setPopupContent(updatedHtml);
|
|
2660
|
+
}
|
|
2661
|
+
}).catch(() => {
|
|
2662
|
+
trackedFeature.__zenit_popup_loaded = false;
|
|
2663
|
+
});
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
onFeatureClick?.(feature, layerId);
|
|
2667
|
+
});
|
|
2113
2668
|
layer.on("mouseover", () => {
|
|
2114
2669
|
if (layer instanceof import_leaflet.default.Path && originalStyle) {
|
|
2115
2670
|
layer.setStyle({
|
|
@@ -2133,7 +2688,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2133
2688
|
}
|
|
2134
2689
|
});
|
|
2135
2690
|
};
|
|
2136
|
-
}, [featureInfoMode, onFeatureClick, onFeatureHover]);
|
|
2691
|
+
}, [client, featureInfoMode, onFeatureClick, onFeatureHover]);
|
|
2137
2692
|
const buildLayerStyle = (layerId, baseOpacity, feature, layerType) => {
|
|
2138
2693
|
const style = resolveLayerStyle(layerId);
|
|
2139
2694
|
const featureStyleOverrides = getFeatureStyleOverrides(feature);
|
|
@@ -2291,68 +2846,93 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2291
2846
|
boxSizing: "border-box"
|
|
2292
2847
|
},
|
|
2293
2848
|
children: [
|
|
2294
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2295
|
-
|
|
2849
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2850
|
+
"div",
|
|
2296
2851
|
{
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2852
|
+
className: `zenit-map-shell${isPopupOpen ? " popup-open" : ""}`,
|
|
2853
|
+
style: { flex: 1, position: "relative" },
|
|
2854
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
2855
|
+
import_react_leaflet.MapContainer,
|
|
2856
|
+
{
|
|
2857
|
+
center,
|
|
2858
|
+
zoom,
|
|
2859
|
+
style: { height: "100%", width: "100%" },
|
|
2860
|
+
scrollWheelZoom: true,
|
|
2861
|
+
zoomControl: false,
|
|
2862
|
+
children: [
|
|
2863
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2864
|
+
import_react_leaflet.TileLayer,
|
|
2865
|
+
{
|
|
2866
|
+
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
2867
|
+
attribution: "\xA9 OpenStreetMap contributors"
|
|
2868
|
+
}
|
|
2869
|
+
),
|
|
2870
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_leaflet.ZoomControl, { position: "topright" }),
|
|
2871
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MapInstanceBridge, { onReady: handleMapReady }),
|
|
2872
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FitToBounds, { bbox: explicitZoomBBox ?? void 0 }),
|
|
2873
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AutoFitToBounds, { bbox: autoZoomBBox ?? void 0, enabled: !explicitZoomBBox }),
|
|
2874
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ZoomBasedOpacityHandler, { onZoomChange: handleZoomChange }),
|
|
2875
|
+
orderedLayers.map((layerState) => {
|
|
2876
|
+
const baseOpacity = layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;
|
|
2877
|
+
const fillPaneName = `zenit-layer-${layerState.mapLayer.layerId}-fill`;
|
|
2878
|
+
const pointsPaneName = `zenit-layer-${layerState.mapLayer.layerId}-points`;
|
|
2879
|
+
const layerType = layerState.layer?.layerType ?? layerState.mapLayer.layerType ?? void 0;
|
|
2880
|
+
const data = layerState.data?.features ?? [];
|
|
2881
|
+
const fillFeatures = data.filter(isNonPointGeometry);
|
|
2882
|
+
const pointFeatures = data.filter(isPointGeometry);
|
|
2883
|
+
const fillData = fillFeatures.length > 0 ? buildFeatureCollection(fillFeatures) : null;
|
|
2884
|
+
const pointsData = pointFeatures.length > 0 ? buildFeatureCollection(pointFeatures) : null;
|
|
2885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [
|
|
2886
|
+
fillData && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2887
|
+
import_react_leaflet.GeoJSON,
|
|
2888
|
+
{
|
|
2889
|
+
data: fillData,
|
|
2890
|
+
pane: panesReady && mapInstance?.getPane(fillPaneName) ? fillPaneName : void 0,
|
|
2891
|
+
style: (feature) => buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType),
|
|
2892
|
+
onEachFeature: overlayOnEachFeature
|
|
2893
|
+
}
|
|
2894
|
+
),
|
|
2895
|
+
pointsData && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2896
|
+
import_react_leaflet.GeoJSON,
|
|
2897
|
+
{
|
|
2898
|
+
data: pointsData,
|
|
2899
|
+
pane: panesReady && mapInstance?.getPane(pointsPaneName) ? pointsPaneName : void 0,
|
|
2900
|
+
pointToLayer: (feature, latlng) => import_leaflet.default.circleMarker(latlng, {
|
|
2901
|
+
radius: isMobile ? 8 : 6,
|
|
2902
|
+
...buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType)
|
|
2903
|
+
}),
|
|
2904
|
+
onEachFeature: overlayOnEachFeature
|
|
2905
|
+
}
|
|
2906
|
+
),
|
|
2907
|
+
panesReady && mapInstance?.getPane(LABELS_PANE_NAME) ? labelMarkers.filter(
|
|
2908
|
+
(marker) => String(marker.layerId) === String(layerState.mapLayer.layerId)
|
|
2909
|
+
).map((marker) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2910
|
+
import_react_leaflet.Marker,
|
|
2911
|
+
{
|
|
2912
|
+
position: marker.position,
|
|
2913
|
+
icon: buildLabelIcon(marker.label, marker.opacity, marker.color),
|
|
2914
|
+
interactive: false,
|
|
2915
|
+
pane: LABELS_PANE_NAME
|
|
2916
|
+
},
|
|
2917
|
+
marker.key
|
|
2918
|
+
)) : null
|
|
2919
|
+
] }, layerState.mapLayer.layerId.toString());
|
|
2920
|
+
}),
|
|
2921
|
+
overlayGeojson && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2922
|
+
import_react_leaflet.GeoJSON,
|
|
2923
|
+
{
|
|
2924
|
+
data: overlayGeojson,
|
|
2925
|
+
style: overlayStyleFunction,
|
|
2926
|
+
onEachFeature: overlayOnEachFeature
|
|
2927
|
+
},
|
|
2928
|
+
"zenit-overlay-geojson"
|
|
2929
|
+
)
|
|
2930
|
+
]
|
|
2931
|
+
},
|
|
2932
|
+
String(mapId)
|
|
2933
|
+
)
|
|
2934
|
+
}
|
|
2935
|
+
),
|
|
2356
2936
|
showLayerPanel && decoratedLayers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
2357
2937
|
"div",
|
|
2358
2938
|
{
|
|
@@ -3630,9 +4210,19 @@ var FloatingChatBox = ({
|
|
|
3630
4210
|
getAccessToken,
|
|
3631
4211
|
onActionClick,
|
|
3632
4212
|
onOpenChange,
|
|
3633
|
-
hideButton
|
|
4213
|
+
hideButton,
|
|
4214
|
+
open: openProp
|
|
3634
4215
|
}) => {
|
|
3635
|
-
const
|
|
4216
|
+
const isControlled = openProp !== void 0;
|
|
4217
|
+
const [internalOpen, setInternalOpen] = (0, import_react4.useState)(false);
|
|
4218
|
+
const open = isControlled ? openProp : internalOpen;
|
|
4219
|
+
const setOpen = (0, import_react4.useCallback)((value) => {
|
|
4220
|
+
const newValue = typeof value === "function" ? value(open) : value;
|
|
4221
|
+
if (!isControlled) {
|
|
4222
|
+
setInternalOpen(newValue);
|
|
4223
|
+
}
|
|
4224
|
+
onOpenChange?.(newValue);
|
|
4225
|
+
}, [isControlled, open, onOpenChange]);
|
|
3636
4226
|
const [expanded, setExpanded] = (0, import_react4.useState)(false);
|
|
3637
4227
|
const [messages, setMessages] = (0, import_react4.useState)([]);
|
|
3638
4228
|
const [inputValue, setInputValue] = (0, import_react4.useState)("");
|
|
@@ -3649,9 +4239,6 @@ var FloatingChatBox = ({
|
|
|
3649
4239
|
}, [accessToken, baseUrl, getAccessToken]);
|
|
3650
4240
|
const { sendMessage: sendMessage2, isStreaming, streamingText, completeResponse } = useSendMessageStream(chatConfig);
|
|
3651
4241
|
const canSend = Boolean(mapId) && Boolean(baseUrl) && inputValue.trim().length > 0 && !isStreaming;
|
|
3652
|
-
(0, import_react4.useEffect)(() => {
|
|
3653
|
-
onOpenChange?.(open);
|
|
3654
|
-
}, [open, onOpenChange]);
|
|
3655
4242
|
(0, import_react4.useEffect)(() => {
|
|
3656
4243
|
if (open && isMobile) {
|
|
3657
4244
|
setExpanded(true);
|
|
@@ -3804,6 +4391,13 @@ var FloatingChatBox = ({
|
|
|
3804
4391
|
] }, index)) })
|
|
3805
4392
|
] });
|
|
3806
4393
|
};
|
|
4394
|
+
const handleActionClick = (0, import_react4.useCallback)((action) => {
|
|
4395
|
+
if (isStreaming) return;
|
|
4396
|
+
setOpen(false);
|
|
4397
|
+
requestAnimationFrame(() => {
|
|
4398
|
+
onActionClick?.(action);
|
|
4399
|
+
});
|
|
4400
|
+
}, [isStreaming, setOpen, onActionClick]);
|
|
3807
4401
|
const renderActions = (response) => {
|
|
3808
4402
|
if (!response?.suggestedActions?.length) return null;
|
|
3809
4403
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles.actionsSection, children: [
|
|
@@ -3817,7 +4411,7 @@ var FloatingChatBox = ({
|
|
|
3817
4411
|
opacity: isStreaming ? 0.5 : 1,
|
|
3818
4412
|
cursor: isStreaming ? "not-allowed" : "pointer"
|
|
3819
4413
|
},
|
|
3820
|
-
onClick: () =>
|
|
4414
|
+
onClick: () => handleActionClick(action),
|
|
3821
4415
|
disabled: isStreaming,
|
|
3822
4416
|
onMouseEnter: (e) => {
|
|
3823
4417
|
if (!isStreaming) {
|