zenit-sdk 0.0.5 → 0.0.6

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/index.mjs CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  sendMessageStream,
36
36
  useSendMessage,
37
37
  useSendMessageStream
38
- } from "./chunk-LX2N2BXV.mjs";
38
+ } from "./chunk-R73LRYVJ.mjs";
39
39
 
40
40
  // src/http/HttpClient.ts
41
41
  var HttpClient = class {
@@ -1,4 +1,4 @@
1
- export { an as FloatingChatBox, ao as FloatingChatBoxProps, aj as LayerSnapshot, ar as LayerStyle, am as ZenitFeatureFilterPanel, al as ZenitLayerManager, ah as ZenitMap, ak as ZenitMapProps, ai as ZenitMapRef, aw as ZoomOpacityOptions, ax as clampNumber, ay as clampOpacity, av as getAccentByLayerId, aC as getEffectiveLayerOpacity, at as getLayerColor, aB as getLayerZoomOpacityFactor, au as getStyleByLayerId, aA as getZoomOpacityFactor, az as isPolygonLayer, as as resolveLayerAccent, ap as useSendMessage, aq as useSendMessageStream } from '../index-kGwfqTc_.mjs';
1
+ export { an as FloatingChatBox, ao as FloatingChatBoxProps, aj as LayerSnapshot, ar as LayerStyle, am as ZenitFeatureFilterPanel, al as ZenitLayerManager, ah as ZenitMap, ak as ZenitMapProps, ai as ZenitMapRef, aw as ZoomOpacityOptions, ax as clampNumber, ay as clampOpacity, av as getAccentByLayerId, aC as getEffectiveLayerOpacity, at as getLayerColor, aB as getLayerZoomOpacityFactor, au as getStyleByLayerId, aA as getZoomOpacityFactor, az as isPolygonLayer, as as resolveLayerAccent, ap as useSendMessage, aq as useSendMessageStream } from '../index-Da0hFqDL.mjs';
2
2
  export { ChevronLeft, ChevronRight, Eye, EyeOff, Layers, Upload, X, ZoomIn } from 'lucide-react';
3
3
  import 'react';
4
4
  import 'leaflet';
@@ -1,4 +1,4 @@
1
- export { an as FloatingChatBox, ao as FloatingChatBoxProps, aj as LayerSnapshot, ar as LayerStyle, am as ZenitFeatureFilterPanel, al as ZenitLayerManager, ah as ZenitMap, ak as ZenitMapProps, ai as ZenitMapRef, aw as ZoomOpacityOptions, ax as clampNumber, ay as clampOpacity, av as getAccentByLayerId, aC as getEffectiveLayerOpacity, at as getLayerColor, aB as getLayerZoomOpacityFactor, au as getStyleByLayerId, aA as getZoomOpacityFactor, az as isPolygonLayer, as as resolveLayerAccent, ap as useSendMessage, aq as useSendMessageStream } from '../index-kGwfqTc_.js';
1
+ export { an as FloatingChatBox, ao as FloatingChatBoxProps, aj as LayerSnapshot, ar as LayerStyle, am as ZenitFeatureFilterPanel, al as ZenitLayerManager, ah as ZenitMap, ak as ZenitMapProps, ai as ZenitMapRef, aw as ZoomOpacityOptions, ax as clampNumber, ay as clampOpacity, av as getAccentByLayerId, aC as getEffectiveLayerOpacity, at as getLayerColor, aB as getLayerZoomOpacityFactor, au as getStyleByLayerId, aA as getZoomOpacityFactor, az as isPolygonLayer, as as resolveLayerAccent, ap as useSendMessage, aq as useSendMessageStream } from '../index-Da0hFqDL.js';
2
2
  export { ChevronLeft, ChevronRight, Eye, EyeOff, Layers, Upload, X, ZoomIn } from 'lucide-react';
3
3
  import 'react';
4
4
  import 'leaflet';
@@ -58,7 +58,7 @@ __export(react_exports, {
58
58
  module.exports = __toCommonJS(react_exports);
59
59
 
60
60
  // src/react/ZenitMap.tsx
61
- var import_react = __toESM(require("react"));
61
+ var import_react = require("react");
62
62
  var import_react_leaflet = require("react-leaflet");
63
63
  var import_leaflet = __toESM(require("leaflet"));
64
64
 
@@ -344,121 +344,6 @@ function getFeatureLayerId(feature) {
344
344
  function escapeHtml(value) {
345
345
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
346
346
  }
347
- var DESCRIPTION_KEYS = /* @__PURE__ */ new Set(["descripcion", "description"]);
348
- function normalizeDescriptionValue(value) {
349
- if (value === void 0 || value === null) return null;
350
- if (typeof value === "string") {
351
- const trimmed = value.trim();
352
- return trimmed ? trimmed : null;
353
- }
354
- if (typeof value === "number" || typeof value === "boolean") {
355
- return String(value);
356
- }
357
- return null;
358
- }
359
- function extractDescriptionValue(properties) {
360
- if (!properties) return null;
361
- const matches = Object.entries(properties).find(
362
- ([key]) => DESCRIPTION_KEYS.has(key.toLowerCase())
363
- );
364
- if (!matches) return null;
365
- return normalizeDescriptionValue(matches[1]);
366
- }
367
- function safeJsonStringify(value) {
368
- try {
369
- const json = JSON.stringify(value, null, 2);
370
- if (json !== void 0) return json;
371
- } catch {
372
- }
373
- return String(value);
374
- }
375
- function renderPropertyValue(value) {
376
- if (value === null || value === void 0) {
377
- return '<span class="prop-empty">\u2014</span>';
378
- }
379
- if (typeof value === "object") {
380
- const json = safeJsonStringify(value);
381
- return `<pre class="prop-json">${escapeHtml(json)}</pre>`;
382
- }
383
- return `<span class="prop-text">${escapeHtml(String(value))}</span>`;
384
- }
385
- var POPUP_TITLE_KEYS = ["name", "title", "nombre", "label", "id"];
386
- var POPUP_CHIP_KEYS = /* @__PURE__ */ new Set(["churn", "color", "sector"]);
387
- function isChipValue(value) {
388
- return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
389
- }
390
- function getSanitizedChipColor(value) {
391
- if (typeof value !== "string") return null;
392
- const trimmed = value.trim();
393
- if (/^#([0-9a-fA-F]{3}){1,2}$/.test(trimmed)) {
394
- return trimmed;
395
- }
396
- if (/^rgb\((\s*\d+\s*,){2}\s*\d+\s*\)$/.test(trimmed)) {
397
- return trimmed;
398
- }
399
- if (/^rgba\((\s*\d+\s*,){3}\s*(0|1|0?\.\d+)\s*\)$/.test(trimmed)) {
400
- return trimmed;
401
- }
402
- return null;
403
- }
404
- function getPopupTitle(entries) {
405
- for (const candidate of POPUP_TITLE_KEYS) {
406
- const match = entries.find((entry) => entry.normalized === candidate);
407
- if (!match || match.value === null || match.value === void 0) continue;
408
- const value = String(match.value).trim();
409
- if (!value) continue;
410
- return { title: value, key: match.key };
411
- }
412
- return null;
413
- }
414
- function renderProperties(properties) {
415
- const description = extractDescriptionValue(properties);
416
- const entries = Object.entries(properties).filter(([key]) => !DESCRIPTION_KEYS.has(key.toLowerCase())).map(([key, value]) => ({
417
- key,
418
- value,
419
- normalized: key.trim().toLowerCase()
420
- }));
421
- if (!description && entries.length === 0) return "";
422
- const titleEntry = getPopupTitle(entries);
423
- const titleText = titleEntry?.title ?? "Detalle del elemento";
424
- const chipEntries = entries.filter(
425
- (entry) => POPUP_CHIP_KEYS.has(entry.normalized) && isChipValue(entry.value)
426
- );
427
- const listEntries = entries.filter((entry) => {
428
- if (titleEntry && entry.key === titleEntry.key) return false;
429
- if (chipEntries.find((chip) => chip.key === entry.key)) return false;
430
- return true;
431
- });
432
- const descriptionHtml = description ? `<div class="popup-description">${escapeHtml(description)}</div>` : "";
433
- const chipsHtml = chipEntries.length ? `<div class="popup-chip-row">${chipEntries.map((entry) => {
434
- const label = escapeHtml(entry.key.replace(/_/g, " "));
435
- const value = escapeHtml(String(entry.value));
436
- const color = getSanitizedChipColor(entry.value);
437
- const colorStyle = color ? ` style="--chip-color: ${color}"` : "";
438
- return `<span class="popup-chip"${colorStyle}><span class="popup-chip-label">${label}</span><span class="popup-chip-value">${value}</span></span>`;
439
- }).join("")}</div>` : "";
440
- const rowsHtml = listEntries.map((entry) => {
441
- const label = escapeHtml(entry.key.replace(/_/g, " "));
442
- const valueHtml = renderPropertyValue(entry.value);
443
- return `<div class="prop-key">${label}</div><div class="prop-value">${valueHtml}</div>`;
444
- }).join("");
445
- const listHtml = rowsHtml ? `<div class="prop-list">${rowsHtml}</div>` : "";
446
- return `
447
- <div class="feature-popup">
448
- <div class="feature-popup-card">
449
- <div class="feature-popup-header">
450
- <p class="popup-eyebrow">Informaci\xF3n</p>
451
- <h3 class="popup-title">${escapeHtml(titleText)}</h3>
452
- </div>
453
- <div class="feature-popup-body">
454
- ${descriptionHtml}
455
- ${chipsHtml}
456
- ${listHtml}
457
- </div>
458
- </div>
459
- </div>
460
- `;
461
- }
462
347
  function withAlpha(color, alpha) {
463
348
  const trimmed = color.trim();
464
349
  if (trimmed.startsWith("#")) {
@@ -527,39 +412,40 @@ function getFeatureStyleOverrides(feature) {
527
412
  function buildFeaturePopupHtml(feature) {
528
413
  const properties = feature?.properties;
529
414
  if (!properties) return null;
530
- const rendered = renderProperties(properties);
531
- return rendered ? rendered : null;
532
- }
533
- var POINT_GEOMETRY_TYPES = /* @__PURE__ */ new Set(["Point", "MultiPoint"]);
534
- function getGeometryType(feature) {
535
- const t = feature?.geometry?.type;
536
- return typeof t === "string" ? t : null;
537
- }
538
- function isPointGeometry(feature) {
539
- const geometryType = getGeometryType(feature);
540
- return geometryType !== null && POINT_GEOMETRY_TYPES.has(geometryType);
541
- }
542
- function isNonPointGeometry(feature) {
543
- const geometryType = getGeometryType(feature);
544
- return geometryType !== null && !POINT_GEOMETRY_TYPES.has(geometryType);
545
- }
546
- function buildFeatureCollection(features) {
547
- return {
548
- type: "FeatureCollection",
549
- features
550
- };
551
- }
552
- function pickIntersectFeature(baseFeature, candidates) {
553
- if (!Array.isArray(candidates) || candidates.length === 0) return null;
554
- const baseId = baseFeature?.id;
555
- if (baseId !== void 0 && baseId !== null) {
556
- const matchById = candidates.find((candidate) => candidate?.id === baseId);
557
- if (matchById) return matchById;
415
+ const layerName = properties.layerName ?? properties.layer_name ?? properties.name;
416
+ const descripcion = properties.descripcion ?? properties.description;
417
+ const reservedKeys = /* @__PURE__ */ new Set([
418
+ "_style",
419
+ "layerId",
420
+ "layer_id",
421
+ "__zenit_layerId",
422
+ "layerName",
423
+ "layer_name",
424
+ "name",
425
+ "descripcion",
426
+ "description"
427
+ ]);
428
+ const extraEntries = Object.entries(properties).filter(([key, value]) => {
429
+ if (reservedKeys.has(key)) return false;
430
+ return ["string", "number", "boolean"].includes(typeof value);
431
+ }).slice(0, 5);
432
+ if (!layerName && !descripcion && extraEntries.length === 0) return null;
433
+ const parts = [];
434
+ if (layerName) {
435
+ parts.push(`<div style="font-weight:600;margin-bottom:4px;">${escapeHtml(layerName)}</div>`);
558
436
  }
559
- const matchWithDescription = candidates.find(
560
- (candidate) => extractDescriptionValue(candidate?.properties)
561
- );
562
- return matchWithDescription ?? candidates[0];
437
+ if (descripcion) {
438
+ parts.push(`<div style="margin-bottom:6px;">${escapeHtml(descripcion)}</div>`);
439
+ }
440
+ if (extraEntries.length > 0) {
441
+ const rows = extraEntries.map(([key, value]) => {
442
+ const label = escapeHtml(key.replace(/_/g, " "));
443
+ const val = escapeHtml(String(value));
444
+ return `<div><strong>${label}:</strong> ${val}</div>`;
445
+ }).join("");
446
+ parts.push(`<div style="font-size:12px;line-height:1.4;">${rows}</div>`);
447
+ }
448
+ return `<div>${parts.join("")}</div>`;
563
449
  }
564
450
  function normalizeCenterTuple(center) {
565
451
  if (!center) return null;
@@ -680,7 +566,6 @@ var ZenitMap = (0, import_react.forwardRef)(({
680
566
  const [loadingMap, setLoadingMap] = (0, import_react.useState)(false);
681
567
  const [mapError, setMapError] = (0, import_react.useState)(null);
682
568
  const [mapInstance, setMapInstance] = (0, import_react.useState)(null);
683
- const [panesReady, setPanesReady] = (0, import_react.useState)(false);
684
569
  const [currentZoom, setCurrentZoom] = (0, import_react.useState)(initialZoom ?? DEFAULT_ZOOM);
685
570
  const [isMobile, setIsMobile] = (0, import_react.useState)(() => {
686
571
  if (typeof window === "undefined") return false;
@@ -995,23 +880,16 @@ var ZenitMap = (0, import_react.forwardRef)(({
995
880
  (targetMap, targetLayers) => {
996
881
  const baseZIndex = 400;
997
882
  targetLayers.forEach((layer) => {
883
+ const paneName = `zenit-layer-${layer.layerId}`;
884
+ const pane = targetMap.getPane(paneName) ?? targetMap.createPane(paneName);
998
885
  const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;
999
- const fillPaneName = `zenit-layer-${layer.layerId}-fill`;
1000
- const pointPaneName = `zenit-layer-${layer.layerId}-points`;
1001
- const labelPaneName = `zenit-layer-${layer.layerId}-labels`;
1002
- const fillPane = targetMap.getPane(fillPaneName) ?? targetMap.createPane(fillPaneName);
1003
- const pointPane = targetMap.getPane(pointPaneName) ?? targetMap.createPane(pointPaneName);
1004
- const labelPane = targetMap.getPane(labelPaneName) ?? targetMap.createPane(labelPaneName);
1005
- fillPane.style.zIndex = String(baseZIndex + order);
1006
- pointPane.style.zIndex = String(baseZIndex + order + 1e3);
1007
- labelPane.style.zIndex = String(baseZIndex + order + 2e3);
886
+ pane.style.zIndex = String(baseZIndex + order);
1008
887
  });
1009
888
  },
1010
889
  []
1011
890
  );
1012
891
  const handleMapReady = (0, import_react.useCallback)(
1013
892
  (instance) => {
1014
- setPanesReady(false);
1015
893
  setMapInstance(instance);
1016
894
  onMapReady?.(instance);
1017
895
  },
@@ -1019,7 +897,6 @@ var ZenitMap = (0, import_react.forwardRef)(({
1019
897
  );
1020
898
  (0, import_react.useEffect)(() => {
1021
899
  if (!mapInstance) {
1022
- setPanesReady(false);
1023
900
  return;
1024
901
  }
1025
902
  if (orderedLayers.length === 0) {
@@ -1030,11 +907,6 @@ var ZenitMap = (0, import_react.forwardRef)(({
1030
907
  displayOrder: layer.displayOrder
1031
908
  }));
1032
909
  ensureLayerPanes(mapInstance, layerTargets);
1033
- const first = layerTargets[0];
1034
- const testPane = mapInstance.getPane(`zenit-layer-${first.layerId}-labels`);
1035
- if (testPane) {
1036
- setPanesReady(true);
1037
- }
1038
910
  }, [mapInstance, orderedLayers, ensureLayerPanes]);
1039
911
  const overlayOnEachFeature = (0, import_react.useMemo)(() => {
1040
912
  return (feature, layer) => {
@@ -1052,14 +924,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
1052
924
  if (featureInfoMode === "popup") {
1053
925
  const content = buildFeaturePopupHtml(feature);
1054
926
  if (content) {
1055
- layer.bindPopup(content, {
1056
- maxWidth: 420,
1057
- minWidth: 280,
1058
- className: "zenit-feature-popup-shell",
1059
- autoPan: true,
1060
- closeButton: true,
1061
- offset: import_leaflet.default.point(0, -24)
1062
- });
927
+ layer.bindPopup(content, { maxWidth: 320 });
1063
928
  }
1064
929
  }
1065
930
  if (isPointFeature && layer.bindTooltip) {
@@ -1070,37 +935,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
1070
935
  className: "zenit-map-tooltip"
1071
936
  });
1072
937
  }
1073
- layer.on("click", () => {
1074
- if (featureInfoMode === "popup" && client && layerId !== void 0 && !extractDescriptionValue(feature?.properties) && feature?.geometry) {
1075
- const trackedFeature = feature;
1076
- if (!trackedFeature.__zenit_popup_loaded) {
1077
- trackedFeature.__zenit_popup_loaded = true;
1078
- client.layers.getLayerGeoJsonIntersect({
1079
- id: layerId,
1080
- geometry: feature.geometry
1081
- }).then((response) => {
1082
- const candidates = response.data?.features ?? [];
1083
- const resolved = pickIntersectFeature(feature, candidates);
1084
- if (!resolved?.properties) return;
1085
- const mergedProperties = {
1086
- ...trackedFeature.properties ?? {},
1087
- ...resolved.properties
1088
- };
1089
- trackedFeature.properties = mergedProperties;
1090
- const updatedHtml = buildFeaturePopupHtml({
1091
- ...feature,
1092
- properties: mergedProperties
1093
- });
1094
- if (updatedHtml && layer.setPopupContent) {
1095
- layer.setPopupContent(updatedHtml);
1096
- }
1097
- }).catch(() => {
1098
- trackedFeature.__zenit_popup_loaded = false;
1099
- });
1100
- }
1101
- }
1102
- onFeatureClick?.(feature, layerId);
1103
- });
938
+ layer.on("click", () => onFeatureClick?.(feature, layerId));
1104
939
  layer.on("mouseover", () => {
1105
940
  if (layer instanceof import_leaflet.default.Path && originalStyle) {
1106
941
  layer.setStyle({
@@ -1124,7 +959,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
1124
959
  }
1125
960
  });
1126
961
  };
1127
- }, [client, featureInfoMode, onFeatureClick, onFeatureHover]);
962
+ }, [featureInfoMode, onFeatureClick, onFeatureHover]);
1128
963
  const buildLayerStyle = (layerId, baseOpacity, feature, layerType) => {
1129
964
  const style = resolveLayerStyle(layerId);
1130
965
  const featureStyleOverrides = getFeatureStyleOverrides(feature);
@@ -1305,50 +1140,22 @@ var ZenitMap = (0, import_react.forwardRef)(({
1305
1140
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ZoomBasedOpacityHandler, { onZoomChange: handleZoomChange }),
1306
1141
  orderedLayers.map((layerState) => {
1307
1142
  const baseOpacity = layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;
1308
- const fillPaneName = `zenit-layer-${layerState.mapLayer.layerId}-fill`;
1309
- const pointsPaneName = `zenit-layer-${layerState.mapLayer.layerId}-points`;
1310
- const labelPaneName = `zenit-layer-${layerState.mapLayer.layerId}-labels`;
1143
+ const paneName = `zenit-layer-${layerState.mapLayer.layerId}`;
1311
1144
  const layerType = layerState.layer?.layerType ?? layerState.mapLayer.layerType ?? void 0;
1312
- const data = layerState.data?.features ?? [];
1313
- const fillFeatures = data.filter(isNonPointGeometry);
1314
- const pointFeatures = data.filter(isPointGeometry);
1315
- const fillData = fillFeatures.length > 0 ? buildFeatureCollection(fillFeatures) : null;
1316
- const pointsData = pointFeatures.length > 0 ? buildFeatureCollection(pointFeatures) : null;
1317
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [
1318
- fillData && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1319
- import_react_leaflet.GeoJSON,
1320
- {
1321
- data: fillData,
1322
- pane: panesReady && mapInstance?.getPane(fillPaneName) ? fillPaneName : void 0,
1323
- style: (feature) => buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType),
1324
- onEachFeature: overlayOnEachFeature
1325
- }
1326
- ),
1327
- pointsData && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1328
- import_react_leaflet.GeoJSON,
1329
- {
1330
- data: pointsData,
1331
- pane: panesReady && mapInstance?.getPane(pointsPaneName) ? pointsPaneName : void 0,
1332
- pointToLayer: (feature, latlng) => import_leaflet.default.circleMarker(latlng, {
1333
- radius: isMobile ? 8 : 6,
1334
- ...buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType)
1335
- }),
1336
- onEachFeature: overlayOnEachFeature
1337
- }
1338
- ),
1339
- panesReady && mapInstance?.getPane(labelPaneName) ? labelMarkers.filter(
1340
- (marker) => String(marker.layerId) === String(layerState.mapLayer.layerId)
1341
- ).map((marker) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1342
- import_react_leaflet.Marker,
1343
- {
1344
- position: marker.position,
1345
- icon: buildLabelIcon(marker.label, marker.opacity, marker.color),
1346
- interactive: false,
1347
- pane: labelPaneName
1348
- },
1349
- marker.key
1350
- )) : null
1351
- ] }, layerState.mapLayer.layerId.toString());
1145
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1146
+ import_react_leaflet.GeoJSON,
1147
+ {
1148
+ data: layerState.data,
1149
+ pane: mapInstance?.getPane(paneName) ? paneName : void 0,
1150
+ style: (feature) => buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType),
1151
+ pointToLayer: (feature, latlng) => import_leaflet.default.circleMarker(latlng, {
1152
+ radius: isMobile ? 8 : 6,
1153
+ ...buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType)
1154
+ }),
1155
+ onEachFeature: overlayOnEachFeature
1156
+ },
1157
+ layerState.mapLayer.layerId.toString()
1158
+ );
1352
1159
  }),
1353
1160
  overlayGeojson && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1354
1161
  import_react_leaflet.GeoJSON,
@@ -1358,7 +1165,16 @@ var ZenitMap = (0, import_react.forwardRef)(({
1358
1165
  onEachFeature: overlayOnEachFeature
1359
1166
  },
1360
1167
  "zenit-overlay-geojson"
1361
- )
1168
+ ),
1169
+ labelMarkers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1170
+ import_react_leaflet.Marker,
1171
+ {
1172
+ position: marker.position,
1173
+ icon: buildLabelIcon(marker.label, marker.opacity, marker.color),
1174
+ interactive: false
1175
+ },
1176
+ marker.key
1177
+ ))
1362
1178
  ]
1363
1179
  },
1364
1180
  String(mapId)
@@ -2770,19 +2586,9 @@ var FloatingChatBox = ({
2770
2586
  getAccessToken,
2771
2587
  onActionClick,
2772
2588
  onOpenChange,
2773
- hideButton,
2774
- open: openProp
2589
+ hideButton
2775
2590
  }) => {
2776
- const isControlled = openProp !== void 0;
2777
- const [internalOpen, setInternalOpen] = (0, import_react4.useState)(false);
2778
- const open = isControlled ? openProp : internalOpen;
2779
- const setOpen = (0, import_react4.useCallback)((value) => {
2780
- const newValue = typeof value === "function" ? value(open) : value;
2781
- if (!isControlled) {
2782
- setInternalOpen(newValue);
2783
- }
2784
- onOpenChange?.(newValue);
2785
- }, [isControlled, open, onOpenChange]);
2591
+ const [open, setOpen] = (0, import_react4.useState)(false);
2786
2592
  const [expanded, setExpanded] = (0, import_react4.useState)(false);
2787
2593
  const [messages, setMessages] = (0, import_react4.useState)([]);
2788
2594
  const [inputValue, setInputValue] = (0, import_react4.useState)("");
@@ -2799,6 +2605,9 @@ var FloatingChatBox = ({
2799
2605
  }, [accessToken, baseUrl, getAccessToken]);
2800
2606
  const { sendMessage: sendMessage2, isStreaming, streamingText, completeResponse } = useSendMessageStream(chatConfig);
2801
2607
  const canSend = Boolean(mapId) && Boolean(baseUrl) && inputValue.trim().length > 0 && !isStreaming;
2608
+ (0, import_react4.useEffect)(() => {
2609
+ onOpenChange?.(open);
2610
+ }, [open, onOpenChange]);
2802
2611
  (0, import_react4.useEffect)(() => {
2803
2612
  if (open && isMobile) {
2804
2613
  setExpanded(true);
@@ -2951,13 +2760,6 @@ var FloatingChatBox = ({
2951
2760
  ] }, index)) })
2952
2761
  ] });
2953
2762
  };
2954
- const handleActionClick = (0, import_react4.useCallback)((action) => {
2955
- if (isStreaming) return;
2956
- setOpen(false);
2957
- requestAnimationFrame(() => {
2958
- onActionClick?.(action);
2959
- });
2960
- }, [isStreaming, setOpen, onActionClick]);
2961
2763
  const renderActions = (response) => {
2962
2764
  if (!response?.suggestedActions?.length) return null;
2963
2765
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles.actionsSection, children: [
@@ -2971,7 +2773,7 @@ var FloatingChatBox = ({
2971
2773
  opacity: isStreaming ? 0.5 : 1,
2972
2774
  cursor: isStreaming ? "not-allowed" : "pointer"
2973
2775
  },
2974
- onClick: () => handleActionClick(action),
2776
+ onClick: () => !isStreaming && onActionClick?.(action),
2975
2777
  disabled: isStreaming,
2976
2778
  onMouseEnter: (e) => {
2977
2779
  if (!isStreaming) {