zenit-sdk 0.0.3 → 0.0.5
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-LX2N2BXV.mjs} +270 -72
- package/dist/chunk-LX2N2BXV.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 +269 -71
- 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 +269 -71
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +1 -1
- package/package.json +7 -27
- package/dist/chunk-R73LRYVJ.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/react/ZenitMap.tsx
|
|
2
|
-
import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, forwardRef } from "react";
|
|
2
|
+
import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, forwardRef } from "react";
|
|
3
3
|
import { GeoJSON, MapContainer, Marker, TileLayer, ZoomControl, useMap } from "react-leaflet";
|
|
4
4
|
import L from "leaflet";
|
|
5
5
|
|
|
@@ -297,6 +297,121 @@ function getFeatureLayerId(feature) {
|
|
|
297
297
|
function escapeHtml(value) {
|
|
298
298
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
299
299
|
}
|
|
300
|
+
var DESCRIPTION_KEYS = /* @__PURE__ */ new Set(["descripcion", "description"]);
|
|
301
|
+
function normalizeDescriptionValue(value) {
|
|
302
|
+
if (value === void 0 || value === null) return null;
|
|
303
|
+
if (typeof value === "string") {
|
|
304
|
+
const trimmed = value.trim();
|
|
305
|
+
return trimmed ? trimmed : null;
|
|
306
|
+
}
|
|
307
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
308
|
+
return String(value);
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
function extractDescriptionValue(properties) {
|
|
313
|
+
if (!properties) return null;
|
|
314
|
+
const matches = Object.entries(properties).find(
|
|
315
|
+
([key]) => DESCRIPTION_KEYS.has(key.toLowerCase())
|
|
316
|
+
);
|
|
317
|
+
if (!matches) return null;
|
|
318
|
+
return normalizeDescriptionValue(matches[1]);
|
|
319
|
+
}
|
|
320
|
+
function safeJsonStringify(value) {
|
|
321
|
+
try {
|
|
322
|
+
const json = JSON.stringify(value, null, 2);
|
|
323
|
+
if (json !== void 0) return json;
|
|
324
|
+
} catch {
|
|
325
|
+
}
|
|
326
|
+
return String(value);
|
|
327
|
+
}
|
|
328
|
+
function renderPropertyValue(value) {
|
|
329
|
+
if (value === null || value === void 0) {
|
|
330
|
+
return '<span class="prop-empty">\u2014</span>';
|
|
331
|
+
}
|
|
332
|
+
if (typeof value === "object") {
|
|
333
|
+
const json = safeJsonStringify(value);
|
|
334
|
+
return `<pre class="prop-json">${escapeHtml(json)}</pre>`;
|
|
335
|
+
}
|
|
336
|
+
return `<span class="prop-text">${escapeHtml(String(value))}</span>`;
|
|
337
|
+
}
|
|
338
|
+
var POPUP_TITLE_KEYS = ["name", "title", "nombre", "label", "id"];
|
|
339
|
+
var POPUP_CHIP_KEYS = /* @__PURE__ */ new Set(["churn", "color", "sector"]);
|
|
340
|
+
function isChipValue(value) {
|
|
341
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
342
|
+
}
|
|
343
|
+
function getSanitizedChipColor(value) {
|
|
344
|
+
if (typeof value !== "string") return null;
|
|
345
|
+
const trimmed = value.trim();
|
|
346
|
+
if (/^#([0-9a-fA-F]{3}){1,2}$/.test(trimmed)) {
|
|
347
|
+
return trimmed;
|
|
348
|
+
}
|
|
349
|
+
if (/^rgb\((\s*\d+\s*,){2}\s*\d+\s*\)$/.test(trimmed)) {
|
|
350
|
+
return trimmed;
|
|
351
|
+
}
|
|
352
|
+
if (/^rgba\((\s*\d+\s*,){3}\s*(0|1|0?\.\d+)\s*\)$/.test(trimmed)) {
|
|
353
|
+
return trimmed;
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
function getPopupTitle(entries) {
|
|
358
|
+
for (const candidate of POPUP_TITLE_KEYS) {
|
|
359
|
+
const match = entries.find((entry) => entry.normalized === candidate);
|
|
360
|
+
if (!match || match.value === null || match.value === void 0) continue;
|
|
361
|
+
const value = String(match.value).trim();
|
|
362
|
+
if (!value) continue;
|
|
363
|
+
return { title: value, key: match.key };
|
|
364
|
+
}
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
function renderProperties(properties) {
|
|
368
|
+
const description = extractDescriptionValue(properties);
|
|
369
|
+
const entries = Object.entries(properties).filter(([key]) => !DESCRIPTION_KEYS.has(key.toLowerCase())).map(([key, value]) => ({
|
|
370
|
+
key,
|
|
371
|
+
value,
|
|
372
|
+
normalized: key.trim().toLowerCase()
|
|
373
|
+
}));
|
|
374
|
+
if (!description && entries.length === 0) return "";
|
|
375
|
+
const titleEntry = getPopupTitle(entries);
|
|
376
|
+
const titleText = titleEntry?.title ?? "Detalle del elemento";
|
|
377
|
+
const chipEntries = entries.filter(
|
|
378
|
+
(entry) => POPUP_CHIP_KEYS.has(entry.normalized) && isChipValue(entry.value)
|
|
379
|
+
);
|
|
380
|
+
const listEntries = entries.filter((entry) => {
|
|
381
|
+
if (titleEntry && entry.key === titleEntry.key) return false;
|
|
382
|
+
if (chipEntries.find((chip) => chip.key === entry.key)) return false;
|
|
383
|
+
return true;
|
|
384
|
+
});
|
|
385
|
+
const descriptionHtml = description ? `<div class="popup-description">${escapeHtml(description)}</div>` : "";
|
|
386
|
+
const chipsHtml = chipEntries.length ? `<div class="popup-chip-row">${chipEntries.map((entry) => {
|
|
387
|
+
const label = escapeHtml(entry.key.replace(/_/g, " "));
|
|
388
|
+
const value = escapeHtml(String(entry.value));
|
|
389
|
+
const color = getSanitizedChipColor(entry.value);
|
|
390
|
+
const colorStyle = color ? ` style="--chip-color: ${color}"` : "";
|
|
391
|
+
return `<span class="popup-chip"${colorStyle}><span class="popup-chip-label">${label}</span><span class="popup-chip-value">${value}</span></span>`;
|
|
392
|
+
}).join("")}</div>` : "";
|
|
393
|
+
const rowsHtml = listEntries.map((entry) => {
|
|
394
|
+
const label = escapeHtml(entry.key.replace(/_/g, " "));
|
|
395
|
+
const valueHtml = renderPropertyValue(entry.value);
|
|
396
|
+
return `<div class="prop-key">${label}</div><div class="prop-value">${valueHtml}</div>`;
|
|
397
|
+
}).join("");
|
|
398
|
+
const listHtml = rowsHtml ? `<div class="prop-list">${rowsHtml}</div>` : "";
|
|
399
|
+
return `
|
|
400
|
+
<div class="feature-popup">
|
|
401
|
+
<div class="feature-popup-card">
|
|
402
|
+
<div class="feature-popup-header">
|
|
403
|
+
<p class="popup-eyebrow">Informaci\xF3n</p>
|
|
404
|
+
<h3 class="popup-title">${escapeHtml(titleText)}</h3>
|
|
405
|
+
</div>
|
|
406
|
+
<div class="feature-popup-body">
|
|
407
|
+
${descriptionHtml}
|
|
408
|
+
${chipsHtml}
|
|
409
|
+
${listHtml}
|
|
410
|
+
</div>
|
|
411
|
+
</div>
|
|
412
|
+
</div>
|
|
413
|
+
`;
|
|
414
|
+
}
|
|
300
415
|
function withAlpha(color, alpha) {
|
|
301
416
|
const trimmed = color.trim();
|
|
302
417
|
if (trimmed.startsWith("#")) {
|
|
@@ -365,40 +480,39 @@ function getFeatureStyleOverrides(feature) {
|
|
|
365
480
|
function buildFeaturePopupHtml(feature) {
|
|
366
481
|
const properties = feature?.properties;
|
|
367
482
|
if (!properties) return null;
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
if (
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
const val = escapeHtml(String(value));
|
|
397
|
-
return `<div><strong>${label}:</strong> ${val}</div>`;
|
|
398
|
-
}).join("");
|
|
399
|
-
parts.push(`<div style="font-size:12px;line-height:1.4;">${rows}</div>`);
|
|
483
|
+
const rendered = renderProperties(properties);
|
|
484
|
+
return rendered ? rendered : null;
|
|
485
|
+
}
|
|
486
|
+
var POINT_GEOMETRY_TYPES = /* @__PURE__ */ new Set(["Point", "MultiPoint"]);
|
|
487
|
+
function getGeometryType(feature) {
|
|
488
|
+
const t = feature?.geometry?.type;
|
|
489
|
+
return typeof t === "string" ? t : null;
|
|
490
|
+
}
|
|
491
|
+
function isPointGeometry(feature) {
|
|
492
|
+
const geometryType = getGeometryType(feature);
|
|
493
|
+
return geometryType !== null && POINT_GEOMETRY_TYPES.has(geometryType);
|
|
494
|
+
}
|
|
495
|
+
function isNonPointGeometry(feature) {
|
|
496
|
+
const geometryType = getGeometryType(feature);
|
|
497
|
+
return geometryType !== null && !POINT_GEOMETRY_TYPES.has(geometryType);
|
|
498
|
+
}
|
|
499
|
+
function buildFeatureCollection(features) {
|
|
500
|
+
return {
|
|
501
|
+
type: "FeatureCollection",
|
|
502
|
+
features
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
function pickIntersectFeature(baseFeature, candidates) {
|
|
506
|
+
if (!Array.isArray(candidates) || candidates.length === 0) return null;
|
|
507
|
+
const baseId = baseFeature?.id;
|
|
508
|
+
if (baseId !== void 0 && baseId !== null) {
|
|
509
|
+
const matchById = candidates.find((candidate) => candidate?.id === baseId);
|
|
510
|
+
if (matchById) return matchById;
|
|
400
511
|
}
|
|
401
|
-
|
|
512
|
+
const matchWithDescription = candidates.find(
|
|
513
|
+
(candidate) => extractDescriptionValue(candidate?.properties)
|
|
514
|
+
);
|
|
515
|
+
return matchWithDescription ?? candidates[0];
|
|
402
516
|
}
|
|
403
517
|
function normalizeCenterTuple(center) {
|
|
404
518
|
if (!center) return null;
|
|
@@ -519,6 +633,7 @@ var ZenitMap = forwardRef(({
|
|
|
519
633
|
const [loadingMap, setLoadingMap] = useState(false);
|
|
520
634
|
const [mapError, setMapError] = useState(null);
|
|
521
635
|
const [mapInstance, setMapInstance] = useState(null);
|
|
636
|
+
const [panesReady, setPanesReady] = useState(false);
|
|
522
637
|
const [currentZoom, setCurrentZoom] = useState(initialZoom ?? DEFAULT_ZOOM);
|
|
523
638
|
const [isMobile, setIsMobile] = useState(() => {
|
|
524
639
|
if (typeof window === "undefined") return false;
|
|
@@ -833,16 +948,23 @@ var ZenitMap = forwardRef(({
|
|
|
833
948
|
(targetMap, targetLayers) => {
|
|
834
949
|
const baseZIndex = 400;
|
|
835
950
|
targetLayers.forEach((layer) => {
|
|
836
|
-
const paneName = `zenit-layer-${layer.layerId}`;
|
|
837
|
-
const pane = targetMap.getPane(paneName) ?? targetMap.createPane(paneName);
|
|
838
951
|
const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;
|
|
839
|
-
|
|
952
|
+
const fillPaneName = `zenit-layer-${layer.layerId}-fill`;
|
|
953
|
+
const pointPaneName = `zenit-layer-${layer.layerId}-points`;
|
|
954
|
+
const labelPaneName = `zenit-layer-${layer.layerId}-labels`;
|
|
955
|
+
const fillPane = targetMap.getPane(fillPaneName) ?? targetMap.createPane(fillPaneName);
|
|
956
|
+
const pointPane = targetMap.getPane(pointPaneName) ?? targetMap.createPane(pointPaneName);
|
|
957
|
+
const labelPane = targetMap.getPane(labelPaneName) ?? targetMap.createPane(labelPaneName);
|
|
958
|
+
fillPane.style.zIndex = String(baseZIndex + order);
|
|
959
|
+
pointPane.style.zIndex = String(baseZIndex + order + 1e3);
|
|
960
|
+
labelPane.style.zIndex = String(baseZIndex + order + 2e3);
|
|
840
961
|
});
|
|
841
962
|
},
|
|
842
963
|
[]
|
|
843
964
|
);
|
|
844
965
|
const handleMapReady = useCallback(
|
|
845
966
|
(instance) => {
|
|
967
|
+
setPanesReady(false);
|
|
846
968
|
setMapInstance(instance);
|
|
847
969
|
onMapReady?.(instance);
|
|
848
970
|
},
|
|
@@ -850,6 +972,7 @@ var ZenitMap = forwardRef(({
|
|
|
850
972
|
);
|
|
851
973
|
useEffect(() => {
|
|
852
974
|
if (!mapInstance) {
|
|
975
|
+
setPanesReady(false);
|
|
853
976
|
return;
|
|
854
977
|
}
|
|
855
978
|
if (orderedLayers.length === 0) {
|
|
@@ -860,6 +983,11 @@ var ZenitMap = forwardRef(({
|
|
|
860
983
|
displayOrder: layer.displayOrder
|
|
861
984
|
}));
|
|
862
985
|
ensureLayerPanes(mapInstance, layerTargets);
|
|
986
|
+
const first = layerTargets[0];
|
|
987
|
+
const testPane = mapInstance.getPane(`zenit-layer-${first.layerId}-labels`);
|
|
988
|
+
if (testPane) {
|
|
989
|
+
setPanesReady(true);
|
|
990
|
+
}
|
|
863
991
|
}, [mapInstance, orderedLayers, ensureLayerPanes]);
|
|
864
992
|
const overlayOnEachFeature = useMemo(() => {
|
|
865
993
|
return (feature, layer) => {
|
|
@@ -877,7 +1005,14 @@ var ZenitMap = forwardRef(({
|
|
|
877
1005
|
if (featureInfoMode === "popup") {
|
|
878
1006
|
const content = buildFeaturePopupHtml(feature);
|
|
879
1007
|
if (content) {
|
|
880
|
-
layer.bindPopup(content, {
|
|
1008
|
+
layer.bindPopup(content, {
|
|
1009
|
+
maxWidth: 420,
|
|
1010
|
+
minWidth: 280,
|
|
1011
|
+
className: "zenit-feature-popup-shell",
|
|
1012
|
+
autoPan: true,
|
|
1013
|
+
closeButton: true,
|
|
1014
|
+
offset: L.point(0, -24)
|
|
1015
|
+
});
|
|
881
1016
|
}
|
|
882
1017
|
}
|
|
883
1018
|
if (isPointFeature && layer.bindTooltip) {
|
|
@@ -888,7 +1023,37 @@ var ZenitMap = forwardRef(({
|
|
|
888
1023
|
className: "zenit-map-tooltip"
|
|
889
1024
|
});
|
|
890
1025
|
}
|
|
891
|
-
layer.on("click", () =>
|
|
1026
|
+
layer.on("click", () => {
|
|
1027
|
+
if (featureInfoMode === "popup" && client && layerId !== void 0 && !extractDescriptionValue(feature?.properties) && feature?.geometry) {
|
|
1028
|
+
const trackedFeature = feature;
|
|
1029
|
+
if (!trackedFeature.__zenit_popup_loaded) {
|
|
1030
|
+
trackedFeature.__zenit_popup_loaded = true;
|
|
1031
|
+
client.layers.getLayerGeoJsonIntersect({
|
|
1032
|
+
id: layerId,
|
|
1033
|
+
geometry: feature.geometry
|
|
1034
|
+
}).then((response) => {
|
|
1035
|
+
const candidates = response.data?.features ?? [];
|
|
1036
|
+
const resolved = pickIntersectFeature(feature, candidates);
|
|
1037
|
+
if (!resolved?.properties) return;
|
|
1038
|
+
const mergedProperties = {
|
|
1039
|
+
...trackedFeature.properties ?? {},
|
|
1040
|
+
...resolved.properties
|
|
1041
|
+
};
|
|
1042
|
+
trackedFeature.properties = mergedProperties;
|
|
1043
|
+
const updatedHtml = buildFeaturePopupHtml({
|
|
1044
|
+
...feature,
|
|
1045
|
+
properties: mergedProperties
|
|
1046
|
+
});
|
|
1047
|
+
if (updatedHtml && layer.setPopupContent) {
|
|
1048
|
+
layer.setPopupContent(updatedHtml);
|
|
1049
|
+
}
|
|
1050
|
+
}).catch(() => {
|
|
1051
|
+
trackedFeature.__zenit_popup_loaded = false;
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
onFeatureClick?.(feature, layerId);
|
|
1056
|
+
});
|
|
892
1057
|
layer.on("mouseover", () => {
|
|
893
1058
|
if (layer instanceof L.Path && originalStyle) {
|
|
894
1059
|
layer.setStyle({
|
|
@@ -912,7 +1077,7 @@ var ZenitMap = forwardRef(({
|
|
|
912
1077
|
}
|
|
913
1078
|
});
|
|
914
1079
|
};
|
|
915
|
-
}, [featureInfoMode, onFeatureClick, onFeatureHover]);
|
|
1080
|
+
}, [client, featureInfoMode, onFeatureClick, onFeatureHover]);
|
|
916
1081
|
const buildLayerStyle = (layerId, baseOpacity, feature, layerType) => {
|
|
917
1082
|
const style = resolveLayerStyle(layerId);
|
|
918
1083
|
const featureStyleOverrides = getFeatureStyleOverrides(feature);
|
|
@@ -1093,22 +1258,50 @@ var ZenitMap = forwardRef(({
|
|
|
1093
1258
|
/* @__PURE__ */ jsx(ZoomBasedOpacityHandler, { onZoomChange: handleZoomChange }),
|
|
1094
1259
|
orderedLayers.map((layerState) => {
|
|
1095
1260
|
const baseOpacity = layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;
|
|
1096
|
-
const
|
|
1261
|
+
const fillPaneName = `zenit-layer-${layerState.mapLayer.layerId}-fill`;
|
|
1262
|
+
const pointsPaneName = `zenit-layer-${layerState.mapLayer.layerId}-points`;
|
|
1263
|
+
const labelPaneName = `zenit-layer-${layerState.mapLayer.layerId}-labels`;
|
|
1097
1264
|
const layerType = layerState.layer?.layerType ?? layerState.mapLayer.layerType ?? void 0;
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1265
|
+
const data = layerState.data?.features ?? [];
|
|
1266
|
+
const fillFeatures = data.filter(isNonPointGeometry);
|
|
1267
|
+
const pointFeatures = data.filter(isPointGeometry);
|
|
1268
|
+
const fillData = fillFeatures.length > 0 ? buildFeatureCollection(fillFeatures) : null;
|
|
1269
|
+
const pointsData = pointFeatures.length > 0 ? buildFeatureCollection(pointFeatures) : null;
|
|
1270
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
1271
|
+
fillData && /* @__PURE__ */ jsx(
|
|
1272
|
+
GeoJSON,
|
|
1273
|
+
{
|
|
1274
|
+
data: fillData,
|
|
1275
|
+
pane: panesReady && mapInstance?.getPane(fillPaneName) ? fillPaneName : void 0,
|
|
1276
|
+
style: (feature) => buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType),
|
|
1277
|
+
onEachFeature: overlayOnEachFeature
|
|
1278
|
+
}
|
|
1279
|
+
),
|
|
1280
|
+
pointsData && /* @__PURE__ */ jsx(
|
|
1281
|
+
GeoJSON,
|
|
1282
|
+
{
|
|
1283
|
+
data: pointsData,
|
|
1284
|
+
pane: panesReady && mapInstance?.getPane(pointsPaneName) ? pointsPaneName : void 0,
|
|
1285
|
+
pointToLayer: (feature, latlng) => L.circleMarker(latlng, {
|
|
1286
|
+
radius: isMobile ? 8 : 6,
|
|
1287
|
+
...buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType)
|
|
1288
|
+
}),
|
|
1289
|
+
onEachFeature: overlayOnEachFeature
|
|
1290
|
+
}
|
|
1291
|
+
),
|
|
1292
|
+
panesReady && mapInstance?.getPane(labelPaneName) ? labelMarkers.filter(
|
|
1293
|
+
(marker) => String(marker.layerId) === String(layerState.mapLayer.layerId)
|
|
1294
|
+
).map((marker) => /* @__PURE__ */ jsx(
|
|
1295
|
+
Marker,
|
|
1296
|
+
{
|
|
1297
|
+
position: marker.position,
|
|
1298
|
+
icon: buildLabelIcon(marker.label, marker.opacity, marker.color),
|
|
1299
|
+
interactive: false,
|
|
1300
|
+
pane: labelPaneName
|
|
1301
|
+
},
|
|
1302
|
+
marker.key
|
|
1303
|
+
)) : null
|
|
1304
|
+
] }, layerState.mapLayer.layerId.toString());
|
|
1112
1305
|
}),
|
|
1113
1306
|
overlayGeojson && /* @__PURE__ */ jsx(
|
|
1114
1307
|
GeoJSON,
|
|
@@ -1118,16 +1311,7 @@ var ZenitMap = forwardRef(({
|
|
|
1118
1311
|
onEachFeature: overlayOnEachFeature
|
|
1119
1312
|
},
|
|
1120
1313
|
"zenit-overlay-geojson"
|
|
1121
|
-
)
|
|
1122
|
-
labelMarkers.map((marker) => /* @__PURE__ */ jsx(
|
|
1123
|
-
Marker,
|
|
1124
|
-
{
|
|
1125
|
-
position: marker.position,
|
|
1126
|
-
icon: buildLabelIcon(marker.label, marker.opacity, marker.color),
|
|
1127
|
-
interactive: false
|
|
1128
|
-
},
|
|
1129
|
-
marker.key
|
|
1130
|
-
))
|
|
1314
|
+
)
|
|
1131
1315
|
]
|
|
1132
1316
|
},
|
|
1133
1317
|
String(mapId)
|
|
@@ -2543,9 +2727,19 @@ var FloatingChatBox = ({
|
|
|
2543
2727
|
getAccessToken,
|
|
2544
2728
|
onActionClick,
|
|
2545
2729
|
onOpenChange,
|
|
2546
|
-
hideButton
|
|
2730
|
+
hideButton,
|
|
2731
|
+
open: openProp
|
|
2547
2732
|
}) => {
|
|
2548
|
-
const
|
|
2733
|
+
const isControlled = openProp !== void 0;
|
|
2734
|
+
const [internalOpen, setInternalOpen] = useState4(false);
|
|
2735
|
+
const open = isControlled ? openProp : internalOpen;
|
|
2736
|
+
const setOpen = useCallback3((value) => {
|
|
2737
|
+
const newValue = typeof value === "function" ? value(open) : value;
|
|
2738
|
+
if (!isControlled) {
|
|
2739
|
+
setInternalOpen(newValue);
|
|
2740
|
+
}
|
|
2741
|
+
onOpenChange?.(newValue);
|
|
2742
|
+
}, [isControlled, open, onOpenChange]);
|
|
2549
2743
|
const [expanded, setExpanded] = useState4(false);
|
|
2550
2744
|
const [messages, setMessages] = useState4([]);
|
|
2551
2745
|
const [inputValue, setInputValue] = useState4("");
|
|
@@ -2562,9 +2756,6 @@ var FloatingChatBox = ({
|
|
|
2562
2756
|
}, [accessToken, baseUrl, getAccessToken]);
|
|
2563
2757
|
const { sendMessage: sendMessage2, isStreaming, streamingText, completeResponse } = useSendMessageStream(chatConfig);
|
|
2564
2758
|
const canSend = Boolean(mapId) && Boolean(baseUrl) && inputValue.trim().length > 0 && !isStreaming;
|
|
2565
|
-
useEffect3(() => {
|
|
2566
|
-
onOpenChange?.(open);
|
|
2567
|
-
}, [open, onOpenChange]);
|
|
2568
2759
|
useEffect3(() => {
|
|
2569
2760
|
if (open && isMobile) {
|
|
2570
2761
|
setExpanded(true);
|
|
@@ -2717,6 +2908,13 @@ var FloatingChatBox = ({
|
|
|
2717
2908
|
] }, index)) })
|
|
2718
2909
|
] });
|
|
2719
2910
|
};
|
|
2911
|
+
const handleActionClick = useCallback3((action) => {
|
|
2912
|
+
if (isStreaming) return;
|
|
2913
|
+
setOpen(false);
|
|
2914
|
+
requestAnimationFrame(() => {
|
|
2915
|
+
onActionClick?.(action);
|
|
2916
|
+
});
|
|
2917
|
+
}, [isStreaming, setOpen, onActionClick]);
|
|
2720
2918
|
const renderActions = (response) => {
|
|
2721
2919
|
if (!response?.suggestedActions?.length) return null;
|
|
2722
2920
|
return /* @__PURE__ */ jsxs4("div", { style: styles.actionsSection, children: [
|
|
@@ -2730,7 +2928,7 @@ var FloatingChatBox = ({
|
|
|
2730
2928
|
opacity: isStreaming ? 0.5 : 1,
|
|
2731
2929
|
cursor: isStreaming ? "not-allowed" : "pointer"
|
|
2732
2930
|
},
|
|
2733
|
-
onClick: () =>
|
|
2931
|
+
onClick: () => handleActionClick(action),
|
|
2734
2932
|
disabled: isStreaming,
|
|
2735
2933
|
onMouseEnter: (e) => {
|
|
2736
2934
|
if (!isStreaming) {
|
|
@@ -3057,4 +3255,4 @@ export {
|
|
|
3057
3255
|
useSendMessageStream,
|
|
3058
3256
|
FloatingChatBox
|
|
3059
3257
|
};
|
|
3060
|
-
//# sourceMappingURL=chunk-
|
|
3258
|
+
//# sourceMappingURL=chunk-LX2N2BXV.mjs.map
|