@cloudparse/up-miniapps-sdk 0.2.0 → 0.2.1

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.js CHANGED
@@ -167,7 +167,13 @@ var Bridge = class {
167
167
  };
168
168
 
169
169
  // src/components/Map/components/MapDrawer.tsx
170
- import { forwardRef, useImperativeHandle, useRef } from "react";
170
+ import {
171
+ forwardRef,
172
+ useEffect,
173
+ useImperativeHandle,
174
+ useRef,
175
+ useState
176
+ } from "react";
171
177
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
172
178
  var resolveHeightToPixels = (height, containerHeight) => {
173
179
  if (typeof height === "number") {
@@ -197,7 +203,9 @@ var MapDrawer = forwardRef(
197
203
  containerHeight,
198
204
  menuContent,
199
205
  enableTouchDrag = false,
200
- safeAreaInsets = { top: 0, bottom: 0, left: 0, right: 0 }
206
+ showScrollToTopButton = true,
207
+ scrollToTopThreshold = 300,
208
+ safeAreaInsets = { bottom: 0, left: 0, right: 0, top: 0 }
201
209
  }, ref) => {
202
210
  const scrollContainerRef = useRef(null);
203
211
  const containerRef = useRef(null);
@@ -218,81 +226,237 @@ var MapDrawer = forwardRef(
218
226
  }
219
227
  }
220
228
  };
221
- const handleTouchStart = (e) => {
222
- if (side !== "bottom") return;
223
- setTouchStartY(e.targetTouches[0].clientY);
224
- setCurrentTouchY(e.targetTouches[0].clientY);
229
+ const [showScrollTop, setShowScrollTop] = useState(false);
230
+ const handleScroll = (e) => {
231
+ const scrollTop = e.currentTarget.scrollTop;
232
+ setShowScrollTop(state !== "closed" && scrollTop > scrollToTopThreshold);
225
233
  };
226
- const handleTouchMove = (e) => {
227
- if (touchStartY === null || side !== "bottom") return;
228
- const isScrollAtTop = scrollContainerRef.current ? scrollContainerRef.current.scrollTop === 0 : true;
229
- const currentY = e.targetTouches[0].clientY;
230
- const deltaY = touchStartY - currentY;
231
- if (deltaY < 0 && !isScrollAtTop) {
232
- return;
234
+ useEffect(() => {
235
+ if (state === "closed") {
236
+ setShowScrollTop(false);
237
+ } else {
238
+ const scrollTop = scrollContainerRef.current?.scrollTop || 0;
239
+ setShowScrollTop(scrollTop > scrollToTopThreshold);
233
240
  }
234
- setCurrentTouchY(currentY);
235
- };
236
- const handleTouchEnd = (e) => {
237
- if (touchStartY === null || currentTouchY === null || side !== "bottom")
238
- return;
239
- const touchEndY = e.changedTouches[0].clientY;
240
- const dragDistance = Math.abs(touchEndY - touchStartY);
241
- if (dragDistance < 10) {
241
+ }, [state, scrollToTopThreshold]);
242
+ const isDraggingSheet = useRef(false);
243
+ const hasDeterminedDirection = useRef(false);
244
+ const isTouchOnContent = useRef(false);
245
+ const stateRef = useRef(state);
246
+ const touchStartYRef = useRef(touchStartY);
247
+ const currentTouchYRef = useRef(currentTouchY);
248
+ useEffect(() => {
249
+ stateRef.current = state;
250
+ }, [state]);
251
+ useEffect(() => {
252
+ touchStartYRef.current = touchStartY;
253
+ }, [touchStartY]);
254
+ useEffect(() => {
255
+ currentTouchYRef.current = currentTouchY;
256
+ }, [currentTouchY]);
257
+ useEffect(() => {
258
+ const container = containerRef.current;
259
+ if (!container || side !== "bottom" || !enableTouchDrag) return;
260
+ const handleNativeTouchStart = (e) => {
261
+ const clientY = e.targetTouches[0].clientY;
262
+ setTouchStartY(clientY);
263
+ setCurrentTouchY(clientY);
264
+ isDraggingSheet.current = false;
265
+ hasDeterminedDirection.current = false;
266
+ const target = e.target;
267
+ isTouchOnContent.current = scrollContainerRef.current ? scrollContainerRef.current.contains(target) : false;
268
+ };
269
+ const handleNativeTouchMove = (e) => {
270
+ const startY = touchStartYRef.current;
271
+ if (startY === null) return;
272
+ const currentY = e.targetTouches[0].clientY;
273
+ const deltaY = startY - currentY;
274
+ const scrollTop = scrollContainerRef.current ? scrollContainerRef.current.scrollTop : 0;
275
+ const clientHeight = scrollContainerRef.current ? scrollContainerRef.current.clientHeight : 0;
276
+ const scrollHeight = scrollContainerRef.current ? scrollContainerRef.current.scrollHeight : 0;
277
+ const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1;
278
+ const currentState = stateRef.current;
279
+ if (!hasDeterminedDirection.current) {
280
+ if (!isTouchOnContent.current) {
281
+ isDraggingSheet.current = true;
282
+ hasDeterminedDirection.current = true;
283
+ } else if (currentState !== "full") {
284
+ if (deltaY > 0 && isAtBottom) {
285
+ isDraggingSheet.current = true;
286
+ hasDeterminedDirection.current = true;
287
+ } else if (deltaY < 0 && scrollTop <= 0) {
288
+ isDraggingSheet.current = true;
289
+ hasDeterminedDirection.current = true;
290
+ } else {
291
+ isDraggingSheet.current = false;
292
+ hasDeterminedDirection.current = true;
293
+ }
294
+ } else {
295
+ if (deltaY < 0 && scrollTop <= 0) {
296
+ isDraggingSheet.current = true;
297
+ hasDeterminedDirection.current = true;
298
+ } else {
299
+ isDraggingSheet.current = false;
300
+ hasDeterminedDirection.current = true;
301
+ }
302
+ }
303
+ } else if (!isDraggingSheet.current && isTouchOnContent.current) {
304
+ if (deltaY < 0 && scrollTop <= 0) {
305
+ isDraggingSheet.current = true;
306
+ setTouchStartY(currentY);
307
+ return;
308
+ }
309
+ if (deltaY > 0 && isAtBottom && currentState !== "full") {
310
+ isDraggingSheet.current = true;
311
+ setTouchStartY(currentY);
312
+ return;
313
+ }
314
+ }
315
+ if (isDraggingSheet.current) {
316
+ if (e.cancelable) {
317
+ e.preventDefault();
318
+ }
319
+ const parentContainer = container.parentElement;
320
+ if (parentContainer) {
321
+ const containerH2 = containerHeight || parentContainer.getBoundingClientRect().height;
322
+ const fullPx2 = resolveHeightToPixels(
323
+ drawerFullHeight || "85%",
324
+ containerH2
325
+ );
326
+ const peekPx2 = resolveHeightToPixels(
327
+ drawerPeekHeight || "15%",
328
+ containerH2
329
+ );
330
+ const closedPx = 32 + (currentState === "closed" ? safeAreaInsets.bottom : 0);
331
+ const dragOffset = currentY - startY;
332
+ let localClamped = dragOffset;
333
+ if (currentState === "full") {
334
+ localClamped = Math.max(
335
+ 0,
336
+ Math.min(fullPx2 - closedPx, dragOffset)
337
+ );
338
+ } else if (currentState === "peek") {
339
+ localClamped = Math.max(
340
+ -(fullPx2 - peekPx2),
341
+ Math.min(peekPx2 - closedPx, dragOffset)
342
+ );
343
+ } else if (currentState === "closed") {
344
+ localClamped = Math.min(
345
+ 0,
346
+ Math.max(-(fullPx2 - closedPx), dragOffset)
347
+ );
348
+ }
349
+ parentContainer.style.setProperty(
350
+ "--drag-offset",
351
+ `${localClamped}px`
352
+ );
353
+ }
354
+ }
355
+ };
356
+ const handleNativeTouchEnd = (e) => {
357
+ const startY = touchStartYRef.current;
358
+ const currentY = currentTouchYRef.current;
359
+ const parentContainer = container.parentElement;
360
+ if (startY === null || currentY === null) {
361
+ if (parentContainer) {
362
+ parentContainer.style.setProperty("--drag-offset", "0px");
363
+ }
364
+ return;
365
+ }
366
+ if (!isDraggingSheet.current) {
367
+ setTouchStartY(null);
368
+ setCurrentTouchY(null);
369
+ if (parentContainer) {
370
+ parentContainer.style.setProperty("--drag-offset", "0px");
371
+ }
372
+ return;
373
+ }
374
+ const touchEndY = e.changedTouches[0].clientY;
375
+ const dragDistance = Math.abs(touchEndY - startY);
376
+ if (dragDistance < 10) {
377
+ setTouchStartY(null);
378
+ setCurrentTouchY(null);
379
+ if (parentContainer) {
380
+ parentContainer.style.setProperty("--drag-offset", "0px");
381
+ }
382
+ return;
383
+ }
384
+ const containerH2 = containerHeight || (parentContainer ? parentContainer.getBoundingClientRect().height : window.innerHeight);
385
+ const containerTop = parentContainer ? parentContainer.getBoundingClientRect().top : 0;
386
+ const touchYInContainer = touchEndY - containerTop;
387
+ const drawerHeightFromBottom = containerH2 - touchYInContainer;
388
+ const fullPx2 = resolveHeightToPixels(
389
+ drawerFullHeight || "85%",
390
+ containerH2
391
+ );
392
+ const peekPx2 = resolveHeightToPixels(
393
+ drawerPeekHeight || "15%",
394
+ containerH2
395
+ );
396
+ const currentState = stateRef.current;
397
+ const closedPx = 32 + (currentState === "closed" ? safeAreaInsets.bottom : 0);
398
+ const distToFull = Math.abs(drawerHeightFromBottom - fullPx2);
399
+ const distToPeek = Math.abs(drawerHeightFromBottom - peekPx2);
400
+ const distToClosed = Math.abs(drawerHeightFromBottom - closedPx);
401
+ const minDist = Math.min(distToFull, distToPeek, distToClosed);
402
+ let targetState = "closed";
403
+ if (minDist === distToFull) {
404
+ targetState = "full";
405
+ } else if (minDist === distToPeek) {
406
+ targetState = "peek";
407
+ } else {
408
+ targetState = "closed";
409
+ }
242
410
  setTouchStartY(null);
243
411
  setCurrentTouchY(null);
244
- return;
245
- }
246
- const parentContainer = containerRef.current?.parentElement;
247
- const containerH = containerHeight || (parentContainer ? parentContainer.getBoundingClientRect().height : window.innerHeight);
248
- const containerTop = parentContainer ? parentContainer.getBoundingClientRect().top : 0;
249
- const touchYInContainer = touchEndY - containerTop;
250
- const drawerHeightFromBottom = containerH - touchYInContainer;
251
- const fullPx = resolveHeightToPixels(
252
- drawerFullHeight || "85%",
253
- containerH
254
- );
255
- const peekPx = resolveHeightToPixels(
256
- drawerPeekHeight || "15%",
257
- containerH
258
- );
259
- const closedPx = 32 + (state === "closed" ? safeAreaInsets.bottom : 0);
260
- const distToFull = Math.abs(drawerHeightFromBottom - fullPx);
261
- const distToPeek = Math.abs(drawerHeightFromBottom - peekPx);
262
- const distToClosed = Math.abs(drawerHeightFromBottom - closedPx);
263
- const minDist = Math.min(distToFull, distToPeek, distToClosed);
264
- if (minDist === distToFull) {
265
- onChangeState("full");
266
- } else if (minDist === distToPeek) {
267
- onChangeState("peek");
268
- } else {
269
- onChangeState("closed");
270
- }
271
- setTouchStartY(null);
272
- setCurrentTouchY(null);
273
- };
412
+ onChangeState(targetState);
413
+ requestAnimationFrame(() => {
414
+ if (parentContainer) {
415
+ parentContainer.style.setProperty("--drag-offset", "0px");
416
+ }
417
+ });
418
+ };
419
+ container.addEventListener("touchstart", handleNativeTouchStart, {
420
+ passive: true
421
+ });
422
+ container.addEventListener("touchmove", handleNativeTouchMove, {
423
+ passive: false
424
+ });
425
+ container.addEventListener("touchend", handleNativeTouchEnd, {
426
+ passive: true
427
+ });
428
+ return () => {
429
+ container.removeEventListener("touchstart", handleNativeTouchStart);
430
+ container.removeEventListener("touchmove", handleNativeTouchMove);
431
+ container.removeEventListener("touchend", handleNativeTouchEnd);
432
+ };
433
+ }, [
434
+ side,
435
+ enableTouchDrag,
436
+ containerHeight,
437
+ drawerFullHeight,
438
+ drawerPeekHeight,
439
+ safeAreaInsets,
440
+ onChangeState,
441
+ setTouchStartY,
442
+ setCurrentTouchY
443
+ ]);
274
444
  const isBackdropActive = state === "full";
275
445
  const backdropStyles = isBackdropActive ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none";
446
+ const containerH = containerHeight || window.innerHeight;
447
+ const fullPx = resolveHeightToPixels(drawerFullHeight || "85%", containerH);
448
+ const peekPx = resolveHeightToPixels(drawerPeekHeight || "15%", containerH);
449
+ const shiftPx = fullPx - peekPx;
276
450
  const getBottomDrawerTransform = () => {
277
- const containerH = containerHeight || window.innerHeight;
278
- const fullPx = resolveHeightToPixels(
279
- drawerFullHeight || "85%",
280
- containerH
281
- );
282
- const peekPx = resolveHeightToPixels(
283
- drawerPeekHeight || "15%",
284
- containerH
285
- );
286
451
  if (state === "full") {
287
- return `translateY(${clampedDragOffset}px)`;
452
+ return "translateY(var(--drag-offset, 0px))";
288
453
  }
289
454
  if (state === "peek") {
290
- const shiftPx2 = fullPx - peekPx;
291
- return `translateY(calc(${shiftPx2}px + ${clampedDragOffset}px))`;
455
+ return `translateY(calc(${shiftPx}px + var(--drag-offset, 0px)))`;
292
456
  }
293
457
  const closedVisibleHeight = 32;
294
- const shiftPx = fullPx - closedVisibleHeight;
295
- return `translateY(calc(${shiftPx}px + ${clampedDragOffset}px))`;
458
+ const closedShiftPx = fullPx - closedVisibleHeight;
459
+ return `translateY(calc(${closedShiftPx}px + var(--drag-offset, 0px)))`;
296
460
  };
297
461
  return /* @__PURE__ */ jsxs(Fragment, { children: [
298
462
  /* @__PURE__ */ jsx("style", { children: `
@@ -322,12 +486,13 @@ var MapDrawer = forwardRef(
322
486
  bottom: `calc(1rem + ${etaBarHeight}px)`
323
487
  },
324
488
  children: [
325
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col h-full overflow-hidden pl-4 py-4 pr-1", children: [
489
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col h-full overflow-hidden pl-4 py-4 pr-1 relative", children: [
326
490
  /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between pb-3 border-b border-white/10 mb-2", children: /* @__PURE__ */ jsx("span", { className: "text-sm font-bold tracking-wider text-zinc-400 uppercase", children: "Menu" }) }),
327
491
  /* @__PURE__ */ jsx(
328
492
  "div",
329
493
  {
330
494
  className: "flex-1 overflow-y-auto no-scrollbar pr-2",
495
+ onScroll: handleScroll,
331
496
  ref: scrollContainerRef,
332
497
  children: menuContent ? menuContent : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: menuItems.map((item) => /* @__PURE__ */ jsxs(
333
498
  "button",
@@ -351,6 +516,33 @@ var MapDrawer = forwardRef(
351
516
  item.id
352
517
  )) })
353
518
  }
519
+ ),
520
+ showScrollToTopButton && showScrollTop && /* @__PURE__ */ jsx(
521
+ "button",
522
+ {
523
+ className: "absolute bottom-6 right-6 z-50 flex items-center justify-center w-10 h-10 rounded-full bg-cyan-500 hover:bg-cyan-400 active:scale-95 text-black shadow-lg shadow-cyan-500/25 transition-all duration-200 cursor-pointer",
524
+ onClick: () => {
525
+ scrollContainerRef.current?.scrollTo({
526
+ behavior: "smooth",
527
+ top: 0
528
+ });
529
+ },
530
+ children: /* @__PURE__ */ jsx(
531
+ "svg",
532
+ {
533
+ fill: "none",
534
+ height: "20",
535
+ stroke: "currentColor",
536
+ strokeLinecap: "round",
537
+ strokeLinejoin: "round",
538
+ strokeWidth: "2.5",
539
+ viewBox: "0 0 24 24",
540
+ width: "20",
541
+ xmlns: "http://www.w3.org/2000/svg",
542
+ children: /* @__PURE__ */ jsx("polyline", { points: "18 15 12 9 6 15" })
543
+ }
544
+ )
545
+ }
354
546
  )
355
547
  ] }),
356
548
  /* @__PURE__ */ jsx(
@@ -370,14 +562,11 @@ var MapDrawer = forwardRef(
370
562
  "div",
371
563
  {
372
564
  className: `absolute w-full bg-zinc-950/85 backdrop-blur-md border border-white/10 rounded-t-2xl shadow-2xl flex flex-col z-40 select-none ${isDragging ? "transition-none" : "transition-transform duration-300 ease-out"}`,
373
- onTouchEnd: enableTouchDrag ? handleTouchEnd : void 0,
374
- onTouchMove: enableTouchDrag ? handleTouchMove : void 0,
375
- onTouchStart: enableTouchDrag ? handleTouchStart : void 0,
376
565
  ref: containerRef,
377
566
  style: {
378
567
  bottom: "0px",
379
- marginBottom: state === "closed" ? `${safeAreaInsets.bottom}px` : "0px",
380
568
  height: typeof drawerFullHeight === "number" ? `${drawerFullHeight}px` : drawerFullHeight || "85%",
569
+ marginBottom: state === "closed" ? `${safeAreaInsets.bottom}px` : "0px",
381
570
  transform: getBottomDrawerTransform(),
382
571
  transition: isDragging ? "none" : "transform 300ms ease-out, margin-bottom 250ms ease-in-out"
383
572
  },
@@ -390,41 +579,77 @@ var MapDrawer = forwardRef(
390
579
  children: /* @__PURE__ */ jsx("div", { className: "w-12 h-1 bg-white/25 rounded-full" })
391
580
  }
392
581
  ),
393
- /* @__PURE__ */ jsx(
582
+ /* @__PURE__ */ jsxs(
394
583
  "div",
395
584
  {
396
- className: "flex-1 flex flex-col overflow-hidden px-4 pb-4 pt-2 transition-[margin-top] duration-250 ease-in-out",
585
+ className: "flex-1 flex flex-col overflow-hidden px-4 pb-4 pt-2 transition-[margin-top] duration-250 ease-in-out relative",
397
586
  style: {
398
587
  marginTop: state === "closed" ? `${safeAreaInsets.bottom}px` : "0px"
399
588
  },
400
- children: /* @__PURE__ */ jsx(
401
- "div",
402
- {
403
- className: "flex-1 overflow-y-auto no-scrollbar",
404
- ref: scrollContainerRef,
405
- children: menuContent ? menuContent : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: menuItems.map((item) => /* @__PURE__ */ jsxs(
406
- "button",
407
- {
408
- className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 ${item.disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : "hover:bg-white/5 active:bg-white/10 text-white"}`,
409
- disabled: item.disabled,
410
- onClick: () => {
411
- if (!item.disabled) {
412
- item.onPress();
413
- onChangeState("closed");
414
- }
589
+ children: [
590
+ /* @__PURE__ */ jsx(
591
+ "div",
592
+ {
593
+ className: "flex-1 overflow-y-auto no-scrollbar",
594
+ onScroll: handleScroll,
595
+ ref: scrollContainerRef,
596
+ style: {
597
+ paddingBottom: state === "peek" ? `${shiftPx}px` : "0px"
598
+ },
599
+ children: menuContent ? menuContent : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: menuItems.map((item) => /* @__PURE__ */ jsxs(
600
+ "button",
601
+ {
602
+ className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 ${item.disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : "hover:bg-white/5 active:bg-white/10 text-white"}`,
603
+ disabled: item.disabled,
604
+ onClick: () => {
605
+ if (!item.disabled) {
606
+ item.onPress();
607
+ onChangeState("closed");
608
+ }
609
+ },
610
+ children: [
611
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
612
+ item.icon,
613
+ item.badge !== void 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 bg-cyan-500 text-black text-[9px] font-extrabold min-w-[15px] h-3.5 rounded-full flex items-center justify-center px-1 border border-zinc-950 shadow", children: item.badge })
614
+ ] }),
615
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium tracking-wide", children: item.label })
616
+ ]
415
617
  },
416
- children: [
417
- /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
418
- item.icon,
419
- item.badge !== void 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 bg-cyan-500 text-black text-[9px] font-extrabold min-w-[15px] h-3.5 rounded-full flex items-center justify-center px-1 border border-zinc-950 shadow", children: item.badge })
420
- ] }),
421
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium tracking-wide", children: item.label })
422
- ]
618
+ item.id
619
+ )) })
620
+ }
621
+ ),
622
+ showScrollToTopButton && showScrollTop && /* @__PURE__ */ jsx(
623
+ "button",
624
+ {
625
+ className: "absolute right-6 z-50 flex items-center justify-center w-10 h-10 rounded-full bg-cyan-500 hover:bg-cyan-400 active:scale-95 text-black shadow-lg shadow-cyan-500/25 transition-all duration-200 cursor-pointer",
626
+ onClick: () => {
627
+ scrollContainerRef.current?.scrollTo({
628
+ behavior: "smooth",
629
+ top: 0
630
+ });
423
631
  },
424
- item.id
425
- )) })
426
- }
427
- )
632
+ style: {
633
+ bottom: state === "peek" ? `calc(${24 + shiftPx}px + var(--drag-offset, 0px))` : `calc(24px + var(--drag-offset, 0px))`
634
+ },
635
+ children: /* @__PURE__ */ jsx(
636
+ "svg",
637
+ {
638
+ fill: "none",
639
+ height: "20",
640
+ stroke: "currentColor",
641
+ strokeLinecap: "round",
642
+ strokeLinejoin: "round",
643
+ strokeWidth: "2.5",
644
+ viewBox: "0 0 24 24",
645
+ width: "20",
646
+ xmlns: "http://www.w3.org/2000/svg",
647
+ children: /* @__PURE__ */ jsx("polyline", { points: "18 15 12 9 6 15" })
648
+ }
649
+ )
650
+ }
651
+ )
652
+ ]
428
653
  }
429
654
  )
430
655
  ]
@@ -678,7 +903,7 @@ var MapRightControls = ({
678
903
  customRecenterButton,
679
904
  customCompassButton,
680
905
  drawerPeekHeight,
681
- insets = { top: 0, bottom: 0, left: 0, right: 0 }
906
+ insets = { bottom: 0, left: 0, right: 0, top: 0 }
682
907
  }) => {
683
908
  const aboveControls = customControls.filter(
684
909
  (c) => c.position === "above-recenter"
@@ -690,7 +915,7 @@ var MapRightControls = ({
690
915
  const closedHeightOffset = "32px";
691
916
  const activeEtaHeight = etaData ? etaBarHeight : drawerState === "closed" ? insets.bottom : 0;
692
917
  const peekStyle = typeof drawerPeekHeight === "number" ? `${drawerPeekHeight}px` : drawerPeekHeight || "15%";
693
- const controlsBottom = side === "bottom" ? drawerState === "closed" ? `calc(${closedHeightOffset} + 1rem + ${activeEtaHeight}px - ${clampedDragOffset}px)` : `calc(${peekStyle} + 1rem + ${etaData ? etaBarHeight : 0}px - ${clampedDragOffset}px)` : `calc(1rem + ${insets.bottom}px)`;
918
+ const controlsBottom = side === "bottom" ? drawerState === "closed" ? `calc(${closedHeightOffset} + 1rem + ${activeEtaHeight}px - var(--drag-offset, 0px))` : `calc(${peekStyle} + 1rem + ${etaData ? etaBarHeight : 0}px - var(--drag-offset, 0px))` : `calc(1rem + ${insets.bottom}px)`;
694
919
  const isControlsVisible = side !== "bottom" || drawerState !== "full";
695
920
  return /* @__PURE__ */ jsxs3(
696
921
  "div",
@@ -820,7 +1045,7 @@ import {
820
1045
  useContext,
821
1046
  useMemo,
822
1047
  useRef as useRef2,
823
- useState
1048
+ useState as useState2
824
1049
  } from "react";
825
1050
  import { jsx as jsx4 } from "react/jsx-runtime";
826
1051
  var MapControlsContext = createContext(
@@ -829,19 +1054,19 @@ var MapControlsContext = createContext(
829
1054
  var SDKMapProvider = ({
830
1055
  children
831
1056
  }) => {
832
- const [isFollowing, setIsFollowing] = useState(true);
833
- const [bearing, setBearingState] = useState(0);
834
- const [pitch, setPitchState] = useState(0);
835
- const [drawerState, setDrawerStateInternal] = useState("closed");
1057
+ const [isFollowing, setIsFollowing] = useState2(true);
1058
+ const [bearing, setBearingState] = useState2(0);
1059
+ const [pitch, setPitchState] = useState2(0);
1060
+ const [drawerState, setDrawerStateInternal] = useState2("closed");
836
1061
  const drawerContentRef = useRef2(null);
837
1062
  const setDrawerState = useCallback((val) => {
838
1063
  setDrawerStateInternal(val);
839
1064
  }, []);
840
- const [hasControls, setHasControlsState] = useState(false);
1065
+ const [hasControls, setHasControlsState] = useState2(false);
841
1066
  const setHasControls = useCallback((val) => {
842
1067
  setHasControlsState((prev) => prev === val ? prev : val);
843
1068
  }, []);
844
- const [etaData, setEtaDataState] = useState(void 0);
1069
+ const [etaData, setEtaDataState] = useState2(void 0);
845
1070
  const setEtaData = useCallback((newData) => {
846
1071
  setEtaDataState((prev) => {
847
1072
  if (!prev && !newData) return prev;
@@ -852,11 +1077,11 @@ var SDKMapProvider = ({
852
1077
  return newData;
853
1078
  });
854
1079
  }, []);
855
- const [insets, setInsetsState] = useState({
856
- top: 0,
1080
+ const [insets, setInsetsState] = useState2({
857
1081
  bottom: 0,
858
1082
  left: 0,
859
- right: 0
1083
+ right: 0,
1084
+ top: 0
860
1085
  });
861
1086
  const setInsets = useCallback((newInsets) => {
862
1087
  setInsetsState((prev) => ({ ...prev, ...newInsets }));
@@ -901,6 +1126,7 @@ var SDKMapProvider = ({
901
1126
  drawerState,
902
1127
  etaData,
903
1128
  hasControls,
1129
+ insets,
904
1130
  isFollowing,
905
1131
  pitch,
906
1132
  resetBearing,
@@ -908,10 +1134,9 @@ var SDKMapProvider = ({
908
1134
  setDrawerState,
909
1135
  setEtaData,
910
1136
  setHasControls,
1137
+ setInsets,
911
1138
  setIsFollowing,
912
- setPitch,
913
- insets,
914
- setInsets
1139
+ setPitch
915
1140
  }),
916
1141
  [
917
1142
  _registerCenterCallback,
@@ -944,7 +1169,7 @@ var useMapControls = () => {
944
1169
  };
945
1170
 
946
1171
  // src/components/Map/components/MapControls.tsx
947
- import { useCallback as useCallback2, useContext as useContext2, useEffect, useRef as useRef3, useState as useState2 } from "react";
1172
+ import { useCallback as useCallback2, useContext as useContext2, useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
948
1173
  import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
949
1174
  var resolveHeightToPixels2 = (height, containerHeight) => {
950
1175
  if (typeof height === "number") {
@@ -975,6 +1200,8 @@ var MapControls = ({
975
1200
  menuContent,
976
1201
  children,
977
1202
  enableTouchDrag = false,
1203
+ showScrollToTopButton = true,
1204
+ scrollToTopThreshold = 300,
978
1205
  isInternal = false
979
1206
  }) => {
980
1207
  const mapContext = useContext2(MapControlsContext);
@@ -994,7 +1221,7 @@ var MapControls = ({
994
1221
  },
995
1222
  [drawerContentRef, contextRef]
996
1223
  );
997
- const [localDrawerState, setLocalDrawerState] = useState2(
1224
+ const [localDrawerState, setLocalDrawerState] = useState3(
998
1225
  defaultState ?? "closed"
999
1226
  );
1000
1227
  const drawerState = mapContext ? mapContext.drawerState : localDrawerState;
@@ -1008,15 +1235,15 @@ var MapControls = ({
1008
1235
  },
1009
1236
  [mapContext]
1010
1237
  );
1011
- useEffect(() => {
1238
+ useEffect2(() => {
1012
1239
  if (defaultState && mapContext) {
1013
1240
  mapContext.setDrawerState(defaultState);
1014
1241
  }
1015
1242
  }, []);
1016
- const [side, setSide] = useState2("left");
1243
+ const [side, setSide] = useState3("left");
1017
1244
  const containerRef = useRef3(null);
1018
- const [mapHeight, setMapHeight] = useState2(600);
1019
- useEffect(() => {
1245
+ const [mapHeight, setMapHeight] = useState3(600);
1246
+ useEffect2(() => {
1020
1247
  const parent = containerRef.current?.parentElement;
1021
1248
  if (!parent) return;
1022
1249
  const updateHeight = () => {
@@ -1030,7 +1257,7 @@ var MapControls = ({
1030
1257
  };
1031
1258
  }, []);
1032
1259
  const setHasControls = mapContext?.setHasControls;
1033
- useEffect(() => {
1260
+ useEffect2(() => {
1034
1261
  if (setHasControls && !isInternal) {
1035
1262
  setHasControls(true);
1036
1263
  return () => setHasControls(false);
@@ -1054,9 +1281,9 @@ var MapControls = ({
1054
1281
  };
1055
1282
  const mapPitch = mapContext ? mapContext.pitch : 0;
1056
1283
  const resolvedEtaData = etaData !== void 0 ? etaData : mapContext?.etaData;
1057
- const [touchStartY, setTouchStartY] = useState2(null);
1058
- const [currentTouchY, setCurrentTouchY] = useState2(null);
1059
- useEffect(() => {
1284
+ const [touchStartY, setTouchStartY] = useState3(null);
1285
+ const [currentTouchY, setCurrentTouchY] = useState3(null);
1286
+ useEffect2(() => {
1060
1287
  if (typeof window === "undefined") return;
1061
1288
  const checkLayout = () => {
1062
1289
  if (drawerSide) {
@@ -1075,14 +1302,23 @@ var MapControls = ({
1075
1302
  }, [drawerSide]);
1076
1303
  const isDragging = touchStartY !== null && currentTouchY !== null;
1077
1304
  const dragOffset = isDragging ? currentTouchY - touchStartY : 0;
1305
+ const fullPx = resolveHeightToPixels2(drawerFullHeight || "85%", mapHeight);
1306
+ const peekPx = resolveHeightToPixels2(drawerPeekHeight || "15%", mapHeight);
1307
+ const bottomInset = mapContext?.insets.bottom || 0;
1308
+ const closedPx = 32 + (drawerState === "closed" ? bottomInset : 0);
1078
1309
  let clampedDragOffset = dragOffset;
1079
1310
  if (drawerState === "full") {
1080
- clampedDragOffset = Math.max(0, dragOffset);
1311
+ clampedDragOffset = Math.max(0, Math.min(fullPx - closedPx, dragOffset));
1312
+ } else if (drawerState === "peek") {
1313
+ clampedDragOffset = Math.max(
1314
+ -(fullPx - peekPx),
1315
+ // up to full
1316
+ Math.min(peekPx - closedPx, dragOffset)
1317
+ // down to closed
1318
+ );
1081
1319
  } else if (drawerState === "closed") {
1082
- clampedDragOffset = Math.min(0, dragOffset);
1320
+ clampedDragOffset = Math.min(0, Math.max(-(fullPx - closedPx), dragOffset));
1083
1321
  }
1084
- const fullPx = resolveHeightToPixels2(drawerFullHeight || "85%", mapHeight);
1085
- const peekPx = resolveHeightToPixels2(drawerPeekHeight || "15%", mapHeight);
1086
1322
  let baseHeight = 32;
1087
1323
  if (drawerState === "peek") {
1088
1324
  baseHeight = peekPx;
@@ -1092,7 +1328,6 @@ var MapControls = ({
1092
1328
  const currentDrawerHeight = baseHeight - clampedDragOffset;
1093
1329
  const startFadeHeight = peekPx + 20;
1094
1330
  const endFadeHeight = peekPx + (fullPx - peekPx) * 0.35;
1095
- const bottomInset = mapContext?.insets.bottom || 0;
1096
1331
  let etaOpacity = 1;
1097
1332
  let etaBottomStyle = "1rem";
1098
1333
  if (side === "bottom") {
@@ -1105,7 +1340,7 @@ var MapControls = ({
1105
1340
  etaOpacity = 1 - fraction;
1106
1341
  }
1107
1342
  const effectiveInset = drawerState === "closed" ? bottomInset : 0;
1108
- etaBottomStyle = `${currentDrawerHeight + effectiveInset + 16}px`;
1343
+ etaBottomStyle = `calc(${baseHeight + effectiveInset + 16}px - var(--drag-offset, 0px))`;
1109
1344
  } else {
1110
1345
  etaOpacity = drawerState === "full" ? 0 : 1;
1111
1346
  etaBottomStyle = `calc(1rem + ${bottomInset}px)`;
@@ -1129,8 +1364,10 @@ var MapControls = ({
1129
1364
  onChangeState: setDrawerState,
1130
1365
  ref: mergedRef,
1131
1366
  safeAreaInsets: mapContext?.insets,
1367
+ scrollToTopThreshold,
1132
1368
  setCurrentTouchY,
1133
1369
  setTouchStartY,
1370
+ showScrollToTopButton,
1134
1371
  side,
1135
1372
  state: drawerState,
1136
1373
  touchStartY
@@ -1272,10 +1509,10 @@ var GlobalEvent = /* @__PURE__ */ ((GlobalEvent2) => {
1272
1509
  })(GlobalEvent || {});
1273
1510
 
1274
1511
  // src/components/Map/hooks/useUserLocation.ts
1275
- import { useCallback as useCallback3, useEffect as useEffect2, useRef as useRef4, useState as useState3 } from "react";
1512
+ import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef4, useState as useState4 } from "react";
1276
1513
  var LERP_FACTOR = 0.12;
1277
1514
  var useUserLocation = () => {
1278
- const [locationState, setLocationState] = useState3({
1515
+ const [locationState, setLocationState] = useState4({
1279
1516
  accuracy: null,
1280
1517
  coords: null,
1281
1518
  heading: null
@@ -1308,7 +1545,7 @@ var useUserLocation = () => {
1308
1545
  heading
1309
1546
  };
1310
1547
  }, []);
1311
- useEffect2(() => {
1548
+ useEffect3(() => {
1312
1549
  let rafId;
1313
1550
  const animate = () => {
1314
1551
  let changed = false;
@@ -1387,7 +1624,7 @@ var useUserLocation = () => {
1387
1624
  };
1388
1625
 
1389
1626
  // src/components/Map/hooks/useLiveRouting.ts
1390
- import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef5, useState as useState4 } from "react";
1627
+ import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState5 } from "react";
1391
1628
  var useLiveRouting = ({
1392
1629
  origin: manualOrigin,
1393
1630
  destination,
@@ -1396,11 +1633,11 @@ var useLiveRouting = ({
1396
1633
  enabled = true,
1397
1634
  initialMode = "preview"
1398
1635
  }) => {
1399
- const [route, setRoute] = useState4(null);
1400
- const [totalDistance, setTotalDistance] = useState4(null);
1401
- const [isCalculating, setIsCalculating] = useState4(false);
1402
- const [error, setError] = useState4(null);
1403
- const [mode, setMode] = useState4(initialMode);
1636
+ const [route, setRoute] = useState5(null);
1637
+ const [totalDistance, setTotalDistance] = useState5(null);
1638
+ const [isCalculating, setIsCalculating] = useState5(false);
1639
+ const [error, setError] = useState5(null);
1640
+ const [mode, setMode] = useState5(initialMode);
1404
1641
  const userLocationState = useUserLocation();
1405
1642
  const userLocation = manualOrigin || userLocationState.coords;
1406
1643
  const lastCalcOrigin = useRef5(null);
@@ -1450,7 +1687,7 @@ var useLiveRouting = ({
1450
1687
  },
1451
1688
  [profile]
1452
1689
  );
1453
- useEffect3(() => {
1690
+ useEffect4(() => {
1454
1691
  if (!enabled || !destination || !userLocation) {
1455
1692
  if (!enabled || !destination) {
1456
1693
  setRoute(null);
@@ -1491,10 +1728,10 @@ var useLiveRouting = ({
1491
1728
  };
1492
1729
  };
1493
1730
  var useRoute = (origin, destination, profile = "driving") => {
1494
- const [route, setRoute] = useState4(null);
1495
- const [isCalculating, setIsCalculating] = useState4(false);
1496
- const [error, setError] = useState4(null);
1497
- useEffect3(() => {
1731
+ const [route, setRoute] = useState5(null);
1732
+ const [isCalculating, setIsCalculating] = useState5(false);
1733
+ const [error, setError] = useState5(null);
1734
+ useEffect4(() => {
1498
1735
  if (!origin || !destination) {
1499
1736
  setRoute(null);
1500
1737
  return;
@@ -1599,16 +1836,16 @@ import { Map as MapLibre, MapProvider } from "@vis.gl/react-maplibre";
1599
1836
  import React, {
1600
1837
  useCallback as useCallback5,
1601
1838
  useContext as useContext4,
1602
- useEffect as useEffect5,
1839
+ useEffect as useEffect6,
1603
1840
  useMemo as useMemo5,
1604
1841
  useRef as useRef6,
1605
- useState as useState6
1842
+ useState as useState7
1606
1843
  } from "react";
1607
1844
  import "maplibre-gl/dist/maplibre-gl.css";
1608
1845
 
1609
1846
  // src/components/Map/layers/POILayers.tsx
1610
1847
  import { Layer as Layer2, Source as Source2, useMap } from "@vis.gl/react-maplibre";
1611
- import { useEffect as useEffect4, useMemo as useMemo4, useState as useState5 } from "react";
1848
+ import { useEffect as useEffect5, useMemo as useMemo4, useState as useState6 } from "react";
1612
1849
  import { jsx as jsx8 } from "react/jsx-runtime";
1613
1850
  function createEmojiIcon(emoji, size = 64) {
1614
1851
  const canvas = document.createElement("canvas");
@@ -1622,13 +1859,13 @@ function createEmojiIcon(emoji, size = 64) {
1622
1859
  return ctx.getImageData(0, 0, size, size);
1623
1860
  }
1624
1861
  var POILayers = ({ pois }) => {
1625
- const [loadedImages, setLoadedImages] = useState5(0);
1862
+ const [loadedImages, setLoadedImages] = useState6(0);
1626
1863
  const { current: map } = useMap();
1627
1864
  const glPois = useMemo4(
1628
1865
  () => pois.filter((p) => !p.displayMode || p.displayMode === "gl"),
1629
1866
  [pois]
1630
1867
  );
1631
- useEffect4(() => {
1868
+ useEffect5(() => {
1632
1869
  if (!map) return;
1633
1870
  const glMap = map.getMap();
1634
1871
  const defaults = [
@@ -1968,8 +2205,8 @@ var MapInternal = ({
1968
2205
  const mapControls = useContext4(MapControlsContext);
1969
2206
  const mapRef = useRef6(null);
1970
2207
  const userLocationState = useUserLocation();
1971
- const [progNav, setProgNav] = useState6(null);
1972
- useEffect5(() => {
2208
+ const [progNav, setProgNav] = useState7(null);
2209
+ useEffect6(() => {
1973
2210
  const unsubCreate = sdk.on("SDK_NAVIGATION_CREATE", (payload) => {
1974
2211
  setProgNav(payload);
1975
2212
  });
@@ -1994,7 +2231,7 @@ var MapInternal = ({
1994
2231
  profile: effectiveNavOptions?.profile || "driving",
1995
2232
  recalculateThreshold: effectiveNavOptions?.recalculateThreshold || 50
1996
2233
  });
1997
- useEffect5(() => {
2234
+ useEffect6(() => {
1998
2235
  if (onNavigationModeChange && navigation) {
1999
2236
  onNavigationModeChange(internalNav.mode);
2000
2237
  }
@@ -2006,7 +2243,7 @@ var MapInternal = ({
2006
2243
  const resolvedInitialFollow = mapControls ? mapControls.isFollowing : initialFollowUser;
2007
2244
  const isFollowingRef = useRef6(resolvedInitialFollow);
2008
2245
  const isFlyingRef = useRef6(false);
2009
- const [localIsFollowingUI, setLocalIsFollowingUI] = useState6(
2246
+ const [localIsFollowingUI, setLocalIsFollowingUI] = useState7(
2010
2247
  resolvedInitialFollow
2011
2248
  );
2012
2249
  const isFollowingUI = mapControls ? mapControls.isFollowing : localIsFollowingUI;
@@ -2021,7 +2258,7 @@ var MapInternal = ({
2021
2258
  },
2022
2259
  [setIsFollowingCtx]
2023
2260
  );
2024
- useEffect5(() => {
2261
+ useEffect6(() => {
2025
2262
  if (mapControls && mapControls.isFollowing !== isFollowingRef.current) {
2026
2263
  isFollowingRef.current = mapControls.isFollowing;
2027
2264
  }
@@ -2031,7 +2268,7 @@ var MapInternal = ({
2031
2268
  mergedInteractiveLayerIds.push("sdk-poi-layer");
2032
2269
  }
2033
2270
  const prevInitialFollow = useRef6(initialFollowUser);
2034
- useEffect5(() => {
2271
+ useEffect6(() => {
2035
2272
  if (initialFollowUser !== prevInitialFollow.current) {
2036
2273
  setFollowMode(initialFollowUser);
2037
2274
  prevInitialFollow.current = initialFollowUser;
@@ -2050,7 +2287,7 @@ var MapInternal = ({
2050
2287
  }
2051
2288
  }, [initialFollowUser, setFollowMode, userLocationState.coords]);
2052
2289
  const lastAutoLockedRouteRef = useRef6(null);
2053
- useEffect5(() => {
2290
+ useEffect6(() => {
2054
2291
  if (!route || !mapRef.current) {
2055
2292
  if (!route) lastAutoLockedRouteRef.current = null;
2056
2293
  return;
@@ -2083,7 +2320,7 @@ var MapInternal = ({
2083
2320
  }
2084
2321
  lastAutoLockedRouteRef.current = route;
2085
2322
  }, [route, mode, setFollowMode]);
2086
- useEffect5(() => {
2323
+ useEffect6(() => {
2087
2324
  if (isFollowingRef.current && !isFlyingRef.current && userLocationState.coords && mapRef.current) {
2088
2325
  mapRef.current.easeTo({
2089
2326
  center: userLocationState.coords,
@@ -2126,13 +2363,13 @@ var MapInternal = ({
2126
2363
  onNavigationAbort
2127
2364
  ]);
2128
2365
  const setEtaDataCtx = mapControls?.setEtaData;
2129
- useEffect5(() => {
2366
+ useEffect6(() => {
2130
2367
  if (setEtaDataCtx) {
2131
2368
  setEtaDataCtx(showEtaData);
2132
2369
  }
2133
2370
  }, [showEtaData, setEtaDataCtx]);
2134
2371
  const setDrawerStateCtx = mapControls?.setDrawerState;
2135
- useEffect5(() => {
2372
+ useEffect6(() => {
2136
2373
  if (setDrawerStateCtx && propDrawerState !== void 0) {
2137
2374
  setDrawerStateCtx(propDrawerState);
2138
2375
  }
@@ -2252,7 +2489,7 @@ var MapInternal = ({
2252
2489
  });
2253
2490
  }
2254
2491
  }, []);
2255
- useEffect5(() => {
2492
+ useEffect6(() => {
2256
2493
  if (mapControls) {
2257
2494
  mapControls._registerCenterCallback(handleCenterOnUser);
2258
2495
  mapControls._registerResetBearingCallback(handleResetBearing);
@@ -2368,7 +2605,7 @@ function renderMap(containerId, props = {}) {
2368
2605
  }
2369
2606
 
2370
2607
  // package.json
2371
- var version = "0.2.0";
2608
+ var version = "0.2.1";
2372
2609
 
2373
2610
  // src/sdk.ts
2374
2611
  function deepFreeze(obj) {
@@ -2700,7 +2937,7 @@ var MiniAppSDK = class {
2700
2937
  var sdk = deepFreeze(new MiniAppSDK());
2701
2938
 
2702
2939
  // src/components/BridgeMocker.tsx
2703
- import { useCallback as useCallback6, useEffect as useEffect6, useRef as useRef7, useState as useState7 } from "react";
2940
+ import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef7, useState as useState8 } from "react";
2704
2941
  import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2705
2942
  var getBearing = (p1, p2) => {
2706
2943
  const lat1 = p1[1] * Math.PI / 180;
@@ -2720,12 +2957,12 @@ var BridgeMocker = ({
2720
2957
  mockJWTToken,
2721
2958
  children
2722
2959
  }) => {
2723
- const [autoMove, setAutoMove] = useState7(isMoving);
2724
- const [location, setLocation] = useState7(initialLocation);
2725
- const [heading, setHeading] = useState7(0);
2726
- const [speedMultiplier, setSpeedMultiplier] = useState7(simulationSpeed);
2727
- const [isReady, setIsReady] = useState7(false);
2728
- const [isMinimized, setIsMinimized] = useState7(true);
2960
+ const [autoMove, setAutoMove] = useState8(isMoving);
2961
+ const [location, setLocation] = useState8(initialLocation);
2962
+ const [heading, setHeading] = useState8(0);
2963
+ const [speedMultiplier, setSpeedMultiplier] = useState8(simulationSpeed);
2964
+ const [isReady, setIsReady] = useState8(false);
2965
+ const [isMinimized, setIsMinimized] = useState8(true);
2729
2966
  const streamIntervalRef = useRef7(null);
2730
2967
  const pathIndexRef = useRef7(0);
2731
2968
  const activeConfigRef = useRef7(null);
@@ -2770,7 +3007,7 @@ var BridgeMocker = ({
2770
3007
  type: "EVENT"
2771
3008
  });
2772
3009
  }, []);
2773
- useEffect6(() => {
3010
+ useEffect7(() => {
2774
3011
  stateRef.current = {
2775
3012
  autoMove,
2776
3013
  heading,
@@ -2791,19 +3028,19 @@ var BridgeMocker = ({
2791
3028
  speedMultiplier,
2792
3029
  mockJWTToken
2793
3030
  ]);
2794
- useEffect6(() => {
3031
+ useEffect7(() => {
2795
3032
  setAutoMove(isMoving);
2796
3033
  }, [isMoving]);
2797
- useEffect6(() => {
3034
+ useEffect7(() => {
2798
3035
  setSpeedMultiplier(simulationSpeed);
2799
3036
  }, [simulationSpeed]);
2800
- useEffect6(() => {
3037
+ useEffect7(() => {
2801
3038
  if (simulationPath && simulationPath.length > 0) {
2802
3039
  pathIndexRef.current = 0;
2803
3040
  setLocation(simulationPath[0]);
2804
3041
  }
2805
3042
  }, [simulationPath]);
2806
- useEffect6(() => {
3043
+ useEffect7(() => {
2807
3044
  if (streamIntervalRef.current && activeConfigRef.current) {
2808
3045
  sdk.bridge.send(
2809
3046
  "START_LOCATION_STREAM",
@@ -2811,7 +3048,7 @@ var BridgeMocker = ({
2811
3048
  );
2812
3049
  }
2813
3050
  }, [speedMultiplier]);
2814
- useEffect6(() => {
3051
+ useEffect7(() => {
2815
3052
  const bridge = sdk.bridge;
2816
3053
  const originalSend = bridge.send.bind(bridge);
2817
3054
  const stopStream = () => {
@@ -3145,16 +3382,16 @@ var BridgeMocker = ({
3145
3382
  };
3146
3383
 
3147
3384
  // src/components/DebugConsole.tsx
3148
- import { useCallback as useCallback7, useEffect as useEffect7, useRef as useRef8, useState as useState8 } from "react";
3385
+ import { useCallback as useCallback7, useEffect as useEffect8, useRef as useRef8, useState as useState9 } from "react";
3149
3386
  import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3150
3387
  var DebugConsole = ({
3151
3388
  isOpen: initialOpen = false,
3152
3389
  onClose
3153
3390
  }) => {
3154
- const [showConsole, setShowConsole] = useState8(initialOpen);
3155
- const [logs, setLogs] = useState8([]);
3391
+ const [showConsole, setShowConsole] = useState9(initialOpen);
3392
+ const [logs, setLogs] = useState9([]);
3156
3393
  const scrollRef = useRef8(null);
3157
- useEffect7(() => {
3394
+ useEffect8(() => {
3158
3395
  setShowConsole(initialOpen);
3159
3396
  }, [initialOpen]);
3160
3397
  const clearLogs = () => setLogs([]);
@@ -3168,7 +3405,7 @@ var DebugConsole = ({
3168
3405
  };
3169
3406
  setLogs((prev) => [entry, ...prev].slice(0, 100));
3170
3407
  }, []);
3171
- useEffect7(() => {
3408
+ useEffect8(() => {
3172
3409
  if (typeof window === "undefined") return;
3173
3410
  const bridge = sdk.bridge;
3174
3411
  const originalSend = bridge.send.bind(bridge);