@cloudparse/up-miniapps-sdk 0.2.0 → 0.2.2

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.cjs CHANGED
@@ -62,6 +62,58 @@ __export(src_exports, {
62
62
  });
63
63
  module.exports = __toCommonJS(src_exports);
64
64
 
65
+ // src/lib/utils.ts
66
+ var import_clsx = require("clsx");
67
+ var import_tailwind_merge = require("tailwind-merge");
68
+ function cn(...inputs) {
69
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
70
+ }
71
+
72
+ // src/components/ui/button.tsx
73
+ var import_react_slot = require("@radix-ui/react-slot");
74
+ var import_class_variance_authority = require("class-variance-authority");
75
+ var React = __toESM(require("react"), 1);
76
+ var import_jsx_runtime = require("react/jsx-runtime");
77
+ var buttonVariants = (0, import_class_variance_authority.cva)(
78
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
79
+ {
80
+ defaultVariants: {
81
+ size: "default",
82
+ variant: "default"
83
+ },
84
+ variants: {
85
+ size: {
86
+ default: "h-10 px-4 py-2",
87
+ icon: "h-10 w-10",
88
+ lg: "h-11 rounded-md px-8",
89
+ sm: "h-9 rounded-md px-3"
90
+ },
91
+ variant: {
92
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
93
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
94
+ ghost: "hover:bg-accent hover:text-accent-foreground",
95
+ link: "text-primary underline-offset-4 hover:underline",
96
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
97
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80"
98
+ }
99
+ }
100
+ }
101
+ );
102
+ var Button = React.forwardRef(
103
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
104
+ const Comp = asChild ? import_react_slot.Slot : "button";
105
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
106
+ Comp,
107
+ {
108
+ className: cn(buttonVariants({ className, size, variant })),
109
+ ref,
110
+ ...props
111
+ }
112
+ );
113
+ }
114
+ );
115
+ Button.displayName = "Button";
116
+
65
117
  // src/bridge.ts
66
118
  var Bridge = class {
67
119
  callbacks = /* @__PURE__ */ new Map();
@@ -223,9 +275,121 @@ var Bridge = class {
223
275
  }
224
276
  };
225
277
 
278
+ // src/components/ui/sheet.tsx
279
+ var SheetPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
280
+ var import_class_variance_authority2 = require("class-variance-authority");
281
+ var import_lucide_react = require("lucide-react");
282
+ var React2 = __toESM(require("react"), 1);
283
+ var import_jsx_runtime2 = require("react/jsx-runtime");
284
+ var Sheet = SheetPrimitive.Root;
285
+ var SheetPortal = SheetPrimitive.Portal;
286
+ var SheetOverlay = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
287
+ SheetPrimitive.Overlay,
288
+ {
289
+ className: cn(
290
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
291
+ className
292
+ ),
293
+ ...props,
294
+ ref
295
+ }
296
+ ));
297
+ SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
298
+ var sheetVariants = (0, import_class_variance_authority2.cva)(
299
+ "z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
300
+ {
301
+ defaultVariants: {
302
+ side: "right"
303
+ },
304
+ variants: {
305
+ side: {
306
+ bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
307
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
308
+ right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
309
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top"
310
+ }
311
+ }
312
+ }
313
+ );
314
+ var SheetContent = React2.forwardRef(({ side = "right", className, children, portal = true, ...props }, ref) => {
315
+ const Content2 = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
316
+ SheetPrimitive.Content,
317
+ {
318
+ className: cn(
319
+ sheetVariants({ side }),
320
+ portal ? "fixed" : "absolute",
321
+ className
322
+ ),
323
+ ref,
324
+ ...props,
325
+ children: [
326
+ children,
327
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(SheetPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-105 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
328
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.X, { className: "h-4 w-4" }),
329
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sr-only", children: "Close" })
330
+ ] })
331
+ ]
332
+ }
333
+ );
334
+ if (!portal) {
335
+ return Content2;
336
+ }
337
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(SheetPortal, { children: [
338
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SheetOverlay, {}),
339
+ Content2
340
+ ] });
341
+ });
342
+ SheetContent.displayName = SheetPrimitive.Content.displayName;
343
+ var SheetHeader = ({
344
+ className,
345
+ ...props
346
+ }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
347
+ "div",
348
+ {
349
+ className: cn(
350
+ "flex flex-col space-y-2 text-center sm:text-left",
351
+ className
352
+ ),
353
+ ...props
354
+ }
355
+ );
356
+ SheetHeader.displayName = "SheetHeader";
357
+ var SheetFooter = ({
358
+ className,
359
+ ...props
360
+ }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
361
+ "div",
362
+ {
363
+ className: cn(
364
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
365
+ className
366
+ ),
367
+ ...props
368
+ }
369
+ );
370
+ SheetFooter.displayName = "SheetFooter";
371
+ var SheetTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
372
+ SheetPrimitive.Title,
373
+ {
374
+ className: cn("text-lg font-semibold text-foreground", className),
375
+ ref,
376
+ ...props
377
+ }
378
+ ));
379
+ SheetTitle.displayName = SheetPrimitive.Title.displayName;
380
+ var SheetDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
381
+ SheetPrimitive.Description,
382
+ {
383
+ className: cn("text-sm text-muted-foreground", className),
384
+ ref,
385
+ ...props
386
+ }
387
+ ));
388
+ SheetDescription.displayName = SheetPrimitive.Description.displayName;
389
+
226
390
  // src/components/Map/components/MapDrawer.tsx
227
391
  var import_react = require("react");
228
- var import_jsx_runtime = require("react/jsx-runtime");
392
+ var import_jsx_runtime3 = require("react/jsx-runtime");
229
393
  var resolveHeightToPixels = (height, containerHeight) => {
230
394
  if (typeof height === "number") {
231
395
  return height;
@@ -254,7 +418,9 @@ var MapDrawer = (0, import_react.forwardRef)(
254
418
  containerHeight,
255
419
  menuContent,
256
420
  enableTouchDrag = false,
257
- safeAreaInsets = { top: 0, bottom: 0, left: 0, right: 0 }
421
+ showScrollToTopButton = true,
422
+ scrollToTopThreshold = 300,
423
+ safeAreaInsets = { bottom: 0, left: 0, right: 0, top: 0 }
258
424
  }, ref) => {
259
425
  const scrollContainerRef = (0, import_react.useRef)(null);
260
426
  const containerRef = (0, import_react.useRef)(null);
@@ -275,84 +441,240 @@ var MapDrawer = (0, import_react.forwardRef)(
275
441
  }
276
442
  }
277
443
  };
278
- const handleTouchStart = (e) => {
279
- if (side !== "bottom") return;
280
- setTouchStartY(e.targetTouches[0].clientY);
281
- setCurrentTouchY(e.targetTouches[0].clientY);
444
+ const [showScrollTop, setShowScrollTop] = (0, import_react.useState)(false);
445
+ const handleScroll = (e) => {
446
+ const scrollTop = e.currentTarget.scrollTop;
447
+ setShowScrollTop(state !== "closed" && scrollTop > scrollToTopThreshold);
282
448
  };
283
- const handleTouchMove = (e) => {
284
- if (touchStartY === null || side !== "bottom") return;
285
- const isScrollAtTop = scrollContainerRef.current ? scrollContainerRef.current.scrollTop === 0 : true;
286
- const currentY = e.targetTouches[0].clientY;
287
- const deltaY = touchStartY - currentY;
288
- if (deltaY < 0 && !isScrollAtTop) {
289
- return;
449
+ (0, import_react.useEffect)(() => {
450
+ if (state === "closed") {
451
+ setShowScrollTop(false);
452
+ } else {
453
+ const scrollTop = scrollContainerRef.current?.scrollTop || 0;
454
+ setShowScrollTop(scrollTop > scrollToTopThreshold);
290
455
  }
291
- setCurrentTouchY(currentY);
292
- };
293
- const handleTouchEnd = (e) => {
294
- if (touchStartY === null || currentTouchY === null || side !== "bottom")
295
- return;
296
- const touchEndY = e.changedTouches[0].clientY;
297
- const dragDistance = Math.abs(touchEndY - touchStartY);
298
- if (dragDistance < 10) {
456
+ }, [state, scrollToTopThreshold]);
457
+ const isDraggingSheet = (0, import_react.useRef)(false);
458
+ const hasDeterminedDirection = (0, import_react.useRef)(false);
459
+ const isTouchOnContent = (0, import_react.useRef)(false);
460
+ const stateRef = (0, import_react.useRef)(state);
461
+ const touchStartYRef = (0, import_react.useRef)(touchStartY);
462
+ const currentTouchYRef = (0, import_react.useRef)(currentTouchY);
463
+ (0, import_react.useEffect)(() => {
464
+ stateRef.current = state;
465
+ }, [state]);
466
+ (0, import_react.useEffect)(() => {
467
+ touchStartYRef.current = touchStartY;
468
+ }, [touchStartY]);
469
+ (0, import_react.useEffect)(() => {
470
+ currentTouchYRef.current = currentTouchY;
471
+ }, [currentTouchY]);
472
+ (0, import_react.useEffect)(() => {
473
+ const container = containerRef.current;
474
+ if (!container || side !== "bottom" || !enableTouchDrag) return;
475
+ const handleNativeTouchStart = (e) => {
476
+ const clientY = e.targetTouches[0].clientY;
477
+ setTouchStartY(clientY);
478
+ setCurrentTouchY(clientY);
479
+ isDraggingSheet.current = false;
480
+ hasDeterminedDirection.current = false;
481
+ const target = e.target;
482
+ isTouchOnContent.current = scrollContainerRef.current ? scrollContainerRef.current.contains(target) : false;
483
+ };
484
+ const handleNativeTouchMove = (e) => {
485
+ const startY = touchStartYRef.current;
486
+ if (startY === null) return;
487
+ const currentY = e.targetTouches[0].clientY;
488
+ const deltaY = startY - currentY;
489
+ const scrollTop = scrollContainerRef.current ? scrollContainerRef.current.scrollTop : 0;
490
+ const clientHeight = scrollContainerRef.current ? scrollContainerRef.current.clientHeight : 0;
491
+ const scrollHeight = scrollContainerRef.current ? scrollContainerRef.current.scrollHeight : 0;
492
+ const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1;
493
+ const currentState = stateRef.current;
494
+ if (!hasDeterminedDirection.current) {
495
+ if (!isTouchOnContent.current) {
496
+ isDraggingSheet.current = true;
497
+ hasDeterminedDirection.current = true;
498
+ } else if (currentState !== "full") {
499
+ if (deltaY > 0 && isAtBottom) {
500
+ isDraggingSheet.current = true;
501
+ hasDeterminedDirection.current = true;
502
+ } else if (deltaY < 0 && scrollTop <= 0) {
503
+ isDraggingSheet.current = true;
504
+ hasDeterminedDirection.current = true;
505
+ } else {
506
+ isDraggingSheet.current = false;
507
+ hasDeterminedDirection.current = true;
508
+ }
509
+ } else {
510
+ if (deltaY < 0 && scrollTop <= 0) {
511
+ isDraggingSheet.current = true;
512
+ hasDeterminedDirection.current = true;
513
+ } else {
514
+ isDraggingSheet.current = false;
515
+ hasDeterminedDirection.current = true;
516
+ }
517
+ }
518
+ } else if (!isDraggingSheet.current && isTouchOnContent.current) {
519
+ if (deltaY < 0 && scrollTop <= 0) {
520
+ isDraggingSheet.current = true;
521
+ setTouchStartY(currentY);
522
+ return;
523
+ }
524
+ if (deltaY > 0 && isAtBottom && currentState !== "full") {
525
+ isDraggingSheet.current = true;
526
+ setTouchStartY(currentY);
527
+ return;
528
+ }
529
+ }
530
+ if (isDraggingSheet.current) {
531
+ if (e.cancelable) {
532
+ e.preventDefault();
533
+ }
534
+ const parentContainer = container.parentElement;
535
+ if (parentContainer) {
536
+ const containerH2 = containerHeight || parentContainer.getBoundingClientRect().height;
537
+ const fullPx2 = resolveHeightToPixels(
538
+ drawerFullHeight || "85%",
539
+ containerH2
540
+ );
541
+ const peekPx2 = resolveHeightToPixels(
542
+ drawerPeekHeight || "15%",
543
+ containerH2
544
+ );
545
+ const closedPx = 32 + (currentState === "closed" ? safeAreaInsets.bottom : 0);
546
+ const dragOffset = currentY - startY;
547
+ let localClamped = dragOffset;
548
+ if (currentState === "full") {
549
+ localClamped = Math.max(
550
+ 0,
551
+ Math.min(fullPx2 - closedPx, dragOffset)
552
+ );
553
+ } else if (currentState === "peek") {
554
+ localClamped = Math.max(
555
+ -(fullPx2 - peekPx2),
556
+ Math.min(peekPx2 - closedPx, dragOffset)
557
+ );
558
+ } else if (currentState === "closed") {
559
+ localClamped = Math.min(
560
+ 0,
561
+ Math.max(-(fullPx2 - closedPx), dragOffset)
562
+ );
563
+ }
564
+ parentContainer.style.setProperty(
565
+ "--drag-offset",
566
+ `${localClamped}px`
567
+ );
568
+ }
569
+ }
570
+ };
571
+ const handleNativeTouchEnd = (e) => {
572
+ const startY = touchStartYRef.current;
573
+ const currentY = currentTouchYRef.current;
574
+ const parentContainer = container.parentElement;
575
+ if (startY === null || currentY === null) {
576
+ if (parentContainer) {
577
+ parentContainer.style.setProperty("--drag-offset", "0px");
578
+ }
579
+ return;
580
+ }
581
+ if (!isDraggingSheet.current) {
582
+ setTouchStartY(null);
583
+ setCurrentTouchY(null);
584
+ if (parentContainer) {
585
+ parentContainer.style.setProperty("--drag-offset", "0px");
586
+ }
587
+ return;
588
+ }
589
+ const touchEndY = e.changedTouches[0].clientY;
590
+ const dragDistance = Math.abs(touchEndY - startY);
591
+ if (dragDistance < 10) {
592
+ setTouchStartY(null);
593
+ setCurrentTouchY(null);
594
+ if (parentContainer) {
595
+ parentContainer.style.setProperty("--drag-offset", "0px");
596
+ }
597
+ return;
598
+ }
599
+ const containerH2 = containerHeight || (parentContainer ? parentContainer.getBoundingClientRect().height : window.innerHeight);
600
+ const containerTop = parentContainer ? parentContainer.getBoundingClientRect().top : 0;
601
+ const touchYInContainer = touchEndY - containerTop;
602
+ const drawerHeightFromBottom = containerH2 - touchYInContainer;
603
+ const fullPx2 = resolveHeightToPixels(
604
+ drawerFullHeight || "85%",
605
+ containerH2
606
+ );
607
+ const peekPx2 = resolveHeightToPixels(
608
+ drawerPeekHeight || "15%",
609
+ containerH2
610
+ );
611
+ const currentState = stateRef.current;
612
+ const closedPx = 32 + (currentState === "closed" ? safeAreaInsets.bottom : 0);
613
+ const distToFull = Math.abs(drawerHeightFromBottom - fullPx2);
614
+ const distToPeek = Math.abs(drawerHeightFromBottom - peekPx2);
615
+ const distToClosed = Math.abs(drawerHeightFromBottom - closedPx);
616
+ const minDist = Math.min(distToFull, distToPeek, distToClosed);
617
+ let targetState = "closed";
618
+ if (minDist === distToFull) {
619
+ targetState = "full";
620
+ } else if (minDist === distToPeek) {
621
+ targetState = "peek";
622
+ } else {
623
+ targetState = "closed";
624
+ }
299
625
  setTouchStartY(null);
300
626
  setCurrentTouchY(null);
301
- return;
302
- }
303
- const parentContainer = containerRef.current?.parentElement;
304
- const containerH = containerHeight || (parentContainer ? parentContainer.getBoundingClientRect().height : window.innerHeight);
305
- const containerTop = parentContainer ? parentContainer.getBoundingClientRect().top : 0;
306
- const touchYInContainer = touchEndY - containerTop;
307
- const drawerHeightFromBottom = containerH - touchYInContainer;
308
- const fullPx = resolveHeightToPixels(
309
- drawerFullHeight || "85%",
310
- containerH
311
- );
312
- const peekPx = resolveHeightToPixels(
313
- drawerPeekHeight || "15%",
314
- containerH
315
- );
316
- const closedPx = 32 + (state === "closed" ? safeAreaInsets.bottom : 0);
317
- const distToFull = Math.abs(drawerHeightFromBottom - fullPx);
318
- const distToPeek = Math.abs(drawerHeightFromBottom - peekPx);
319
- const distToClosed = Math.abs(drawerHeightFromBottom - closedPx);
320
- const minDist = Math.min(distToFull, distToPeek, distToClosed);
321
- if (minDist === distToFull) {
322
- onChangeState("full");
323
- } else if (minDist === distToPeek) {
324
- onChangeState("peek");
325
- } else {
326
- onChangeState("closed");
327
- }
328
- setTouchStartY(null);
329
- setCurrentTouchY(null);
330
- };
627
+ onChangeState(targetState);
628
+ requestAnimationFrame(() => {
629
+ if (parentContainer) {
630
+ parentContainer.style.setProperty("--drag-offset", "0px");
631
+ }
632
+ });
633
+ };
634
+ container.addEventListener("touchstart", handleNativeTouchStart, {
635
+ passive: true
636
+ });
637
+ container.addEventListener("touchmove", handleNativeTouchMove, {
638
+ passive: false
639
+ });
640
+ container.addEventListener("touchend", handleNativeTouchEnd, {
641
+ passive: true
642
+ });
643
+ return () => {
644
+ container.removeEventListener("touchstart", handleNativeTouchStart);
645
+ container.removeEventListener("touchmove", handleNativeTouchMove);
646
+ container.removeEventListener("touchend", handleNativeTouchEnd);
647
+ };
648
+ }, [
649
+ side,
650
+ enableTouchDrag,
651
+ containerHeight,
652
+ drawerFullHeight,
653
+ drawerPeekHeight,
654
+ safeAreaInsets,
655
+ onChangeState,
656
+ setTouchStartY,
657
+ setCurrentTouchY
658
+ ]);
331
659
  const isBackdropActive = state === "full";
332
660
  const backdropStyles = isBackdropActive ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none";
661
+ const containerH = containerHeight || window.innerHeight;
662
+ const fullPx = resolveHeightToPixels(drawerFullHeight || "85%", containerH);
663
+ const peekPx = resolveHeightToPixels(drawerPeekHeight || "15%", containerH);
664
+ const shiftPx = fullPx - peekPx;
333
665
  const getBottomDrawerTransform = () => {
334
- const containerH = containerHeight || window.innerHeight;
335
- const fullPx = resolveHeightToPixels(
336
- drawerFullHeight || "85%",
337
- containerH
338
- );
339
- const peekPx = resolveHeightToPixels(
340
- drawerPeekHeight || "15%",
341
- containerH
342
- );
343
666
  if (state === "full") {
344
- return `translateY(${clampedDragOffset}px)`;
667
+ return "translateY(var(--drag-offset, 0px))";
345
668
  }
346
669
  if (state === "peek") {
347
- const shiftPx2 = fullPx - peekPx;
348
- return `translateY(calc(${shiftPx2}px + ${clampedDragOffset}px))`;
670
+ return `translateY(calc(${shiftPx}px + var(--drag-offset, 0px)))`;
349
671
  }
350
672
  const closedVisibleHeight = 32;
351
- const shiftPx = fullPx - closedVisibleHeight;
352
- return `translateY(calc(${shiftPx}px + ${clampedDragOffset}px))`;
673
+ const closedShiftPx = fullPx - closedVisibleHeight;
674
+ return `translateY(calc(${closedShiftPx}px + var(--drag-offset, 0px)))`;
353
675
  };
354
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
355
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
676
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
677
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
356
678
  .no-scrollbar {
357
679
  -ms-overflow-style: none;
358
680
  scrollbar-width: none;
@@ -361,127 +683,213 @@ var MapDrawer = (0, import_react.forwardRef)(
361
683
  display: none;
362
684
  }
363
685
  ` }),
364
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
686
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
365
687
  "div",
366
688
  {
367
689
  className: `absolute inset-0 bg-black/45 backdrop-blur-[1px] transition-opacity duration-300 z-30 ${backdropStyles}`,
368
690
  onClick: () => onChangeState("closed")
369
691
  }
370
692
  ),
371
- side === "left" ? (
372
- /* Left Drawer Panel */
373
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
374
- "div",
693
+ side === "left" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
694
+ state === "closed" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
695
+ Button,
375
696
  {
376
- className: `absolute top-4 left-0 w-80 bg-zinc-950/85 backdrop-blur-md border-r border-y border-white/10 rounded-r-2xl shadow-2xl flex z-40 transition-transform duration-300 ease-out select-none ${state !== "closed" ? "translate-x-0" : "translate-x-[calc(-100%+24px)]"}`,
377
- ref: containerRef,
378
- style: {
379
- bottom: `calc(1rem + ${etaBarHeight}px)`
380
- },
381
- children: [
382
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex-1 flex flex-col h-full overflow-hidden pl-4 py-4 pr-1", children: [
383
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center justify-between pb-3 border-b border-white/10 mb-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-bold tracking-wider text-zinc-400 uppercase", children: "Menu" }) }),
384
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
385
- "div",
386
- {
387
- className: "flex-1 overflow-y-auto no-scrollbar pr-2",
388
- ref: scrollContainerRef,
389
- children: menuContent ? menuContent : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-1.5", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
390
- "button",
391
- {
392
- 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"}`,
393
- disabled: item.disabled,
394
- onClick: () => {
395
- if (!item.disabled) {
396
- item.onPress();
397
- onChangeState("closed");
398
- }
697
+ className: "absolute top-4 left-4 z-40 w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer hover:bg-zinc-900 hover:text-white p-0!",
698
+ onClick: () => onChangeState("full"),
699
+ variant: "ghost",
700
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
701
+ "svg",
702
+ {
703
+ fill: "none",
704
+ height: "24",
705
+ stroke: "currentColor",
706
+ strokeLinecap: "round",
707
+ strokeLinejoin: "round",
708
+ strokeWidth: "2",
709
+ viewBox: "0 0 24 24",
710
+ width: "24",
711
+ xmlns: "http://www.w3.org/2000/svg",
712
+ children: [
713
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "12", y2: "12" }),
714
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "6", y2: "6" }),
715
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "18", y2: "18" })
716
+ ]
717
+ }
718
+ )
719
+ }
720
+ ),
721
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
722
+ Sheet,
723
+ {
724
+ onOpenChange: (open) => onChangeState(open ? "full" : "closed"),
725
+ open: state !== "closed",
726
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
727
+ SheetContent,
728
+ {
729
+ className: "w-80 bg-zinc-950/85 backdrop-blur-md border-r border-y border-white/10 rounded-r-2xl shadow-2xl p-4 text-white flex flex-col h-full overflow-hidden",
730
+ portal: false,
731
+ side: "left",
732
+ children: [
733
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SheetHeader, { className: "pb-3 border-b border-white/10 mb-2 text-left", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SheetTitle, { className: "text-sm font-bold tracking-wider text-zinc-400 uppercase", children: "Menu" }) }),
734
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
735
+ "div",
736
+ {
737
+ className: "flex-1 overflow-y-auto no-scrollbar pr-2",
738
+ onScroll: handleScroll,
739
+ ref: scrollContainerRef,
740
+ children: menuContent ? menuContent : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col gap-1.5", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
741
+ Button,
742
+ {
743
+ className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 justify-start hover:bg-white/5 hover:text-white active:bg-white/10 text-white ${item.disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : ""}`,
744
+ disabled: item.disabled,
745
+ onClick: () => {
746
+ if (!item.disabled) {
747
+ item.onPress();
748
+ onChangeState("closed");
749
+ }
750
+ },
751
+ variant: "ghost",
752
+ children: [
753
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
754
+ item.icon,
755
+ item.badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.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 })
756
+ ] }),
757
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: item.label })
758
+ ]
399
759
  },
400
- children: [
401
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
402
- item.icon,
403
- item.badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.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 })
404
- ] }),
405
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: item.label })
406
- ]
760
+ item.id
761
+ )) })
762
+ }
763
+ ),
764
+ showScrollToTopButton && showScrollTop && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
765
+ Button,
766
+ {
767
+ 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 hover:text-black shadow-lg shadow-cyan-500/25 transition-all duration-200 cursor-pointer p-0!",
768
+ onClick: () => {
769
+ scrollContainerRef.current?.scrollTo({
770
+ behavior: "smooth",
771
+ top: 0
772
+ });
407
773
  },
408
- item.id
409
- )) })
410
- }
411
- )
412
- ] }),
413
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
414
- "div",
415
- {
416
- className: "w-6 flex items-center justify-center cursor-pointer hover:bg-white/5 active:bg-white/10 transition-colors border-l border-white/5 rounded-r-2xl",
417
- onClick: handleHandleClick,
418
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-1.5 h-12 bg-white/20 rounded-full transition-colors group-hover:bg-white/40" })
419
- }
420
- )
421
- ]
774
+ variant: "ghost",
775
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
776
+ "svg",
777
+ {
778
+ fill: "none",
779
+ height: "20",
780
+ stroke: "currentColor",
781
+ strokeLinecap: "round",
782
+ strokeLinejoin: "round",
783
+ strokeWidth: "2.5",
784
+ viewBox: "0 0 24 24",
785
+ width: "20",
786
+ xmlns: "http://www.w3.org/2000/svg",
787
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "18 15 12 9 6 15" })
788
+ }
789
+ )
790
+ }
791
+ )
792
+ ]
793
+ }
794
+ )
422
795
  }
423
796
  )
424
- ) : (
797
+ ] }) : (
425
798
  /* Bottom Sheet Panel - Hardware accelerated translateY transitions */
426
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
799
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
427
800
  "div",
428
801
  {
429
802
  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"}`,
430
- onTouchEnd: enableTouchDrag ? handleTouchEnd : void 0,
431
- onTouchMove: enableTouchDrag ? handleTouchMove : void 0,
432
- onTouchStart: enableTouchDrag ? handleTouchStart : void 0,
433
803
  ref: containerRef,
434
804
  style: {
435
805
  bottom: "0px",
436
- marginBottom: state === "closed" ? `${safeAreaInsets.bottom}px` : "0px",
437
806
  height: typeof drawerFullHeight === "number" ? `${drawerFullHeight}px` : drawerFullHeight || "85%",
807
+ marginBottom: state === "closed" ? `${safeAreaInsets.bottom}px` : "0px",
438
808
  transform: getBottomDrawerTransform(),
439
809
  transition: isDragging ? "none" : "transform 300ms ease-out, margin-bottom 250ms ease-in-out"
440
810
  },
441
811
  children: [
442
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
812
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
443
813
  "div",
444
814
  {
445
815
  className: "w-full h-8 flex flex-col items-center justify-center cursor-pointer hover:bg-white/5 rounded-t-2xl transition-colors border-b border-white/5",
446
816
  onClick: handleHandleClick,
447
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-12 h-1 bg-white/25 rounded-full" })
817
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-12 h-1 bg-white/25 rounded-full" })
448
818
  }
449
819
  ),
450
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
820
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
451
821
  "div",
452
822
  {
453
- className: "flex-1 flex flex-col overflow-hidden px-4 pb-4 pt-2 transition-[margin-top] duration-250 ease-in-out",
823
+ className: "flex-1 flex flex-col overflow-hidden px-4 pb-4 pt-2 transition-[margin-top] duration-250 ease-in-out relative",
454
824
  style: {
455
825
  marginTop: state === "closed" ? `${safeAreaInsets.bottom}px` : "0px"
456
826
  },
457
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
458
- "div",
459
- {
460
- className: "flex-1 overflow-y-auto no-scrollbar",
461
- ref: scrollContainerRef,
462
- children: menuContent ? menuContent : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-1", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
463
- "button",
464
- {
465
- 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"}`,
466
- disabled: item.disabled,
467
- onClick: () => {
468
- if (!item.disabled) {
469
- item.onPress();
470
- onChangeState("closed");
471
- }
827
+ children: [
828
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
829
+ "div",
830
+ {
831
+ className: "flex-1 overflow-y-auto no-scrollbar",
832
+ onScroll: handleScroll,
833
+ ref: scrollContainerRef,
834
+ style: {
835
+ paddingBottom: state === "peek" ? `${shiftPx}px` : "0px"
836
+ },
837
+ children: menuContent ? menuContent : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col gap-1", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
838
+ Button,
839
+ {
840
+ className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 justify-start hover:bg-white/5 hover:text-white active:bg-white/10 text-white ${item.disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : ""}`,
841
+ disabled: item.disabled,
842
+ onClick: () => {
843
+ if (!item.disabled) {
844
+ item.onPress();
845
+ onChangeState("closed");
846
+ }
847
+ },
848
+ variant: "ghost",
849
+ children: [
850
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
851
+ item.icon,
852
+ item.badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.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 })
853
+ ] }),
854
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-medium tracking-wide", children: item.label })
855
+ ]
472
856
  },
473
- children: [
474
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
475
- item.icon,
476
- item.badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.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 })
477
- ] }),
478
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-medium tracking-wide", children: item.label })
479
- ]
857
+ item.id
858
+ )) })
859
+ }
860
+ ),
861
+ showScrollToTopButton && showScrollTop && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
862
+ Button,
863
+ {
864
+ 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 hover:text-black shadow-lg shadow-cyan-500/25 transition-all duration-200 cursor-pointer p-0!",
865
+ onClick: () => {
866
+ scrollContainerRef.current?.scrollTo({
867
+ behavior: "smooth",
868
+ top: 0
869
+ });
480
870
  },
481
- item.id
482
- )) })
483
- }
484
- )
871
+ style: {
872
+ bottom: state === "peek" ? `calc(${24 + shiftPx}px + var(--drag-offset, 0px))` : `calc(24px + var(--drag-offset, 0px))`
873
+ },
874
+ variant: "ghost",
875
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
876
+ "svg",
877
+ {
878
+ fill: "none",
879
+ height: "20",
880
+ stroke: "currentColor",
881
+ strokeLinecap: "round",
882
+ strokeLinejoin: "round",
883
+ strokeWidth: "2.5",
884
+ viewBox: "0 0 24 24",
885
+ width: "20",
886
+ xmlns: "http://www.w3.org/2000/svg",
887
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "18 15 12 9 6 15" })
888
+ }
889
+ )
890
+ }
891
+ )
892
+ ]
485
893
  }
486
894
  )
487
895
  ]
@@ -492,8 +900,65 @@ var MapDrawer = (0, import_react.forwardRef)(
492
900
  }
493
901
  );
494
902
 
903
+ // src/components/ui/card.tsx
904
+ var React3 = __toESM(require("react"), 1);
905
+ var import_jsx_runtime4 = require("react/jsx-runtime");
906
+ var Card = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
907
+ "div",
908
+ {
909
+ className: cn(
910
+ "rounded-lg border bg-card text-card-foreground shadow-sm",
911
+ className
912
+ ),
913
+ ref,
914
+ ...props
915
+ }
916
+ ));
917
+ Card.displayName = "Card";
918
+ var CardHeader = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
919
+ "div",
920
+ {
921
+ className: cn("flex flex-col space-y-1.5 p-6", className),
922
+ ref,
923
+ ...props
924
+ }
925
+ ));
926
+ CardHeader.displayName = "CardHeader";
927
+ var CardTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
928
+ "div",
929
+ {
930
+ className: cn(
931
+ "text-2xl font-semibold leading-none tracking-tight",
932
+ className
933
+ ),
934
+ ref,
935
+ ...props
936
+ }
937
+ ));
938
+ CardTitle.displayName = "CardTitle";
939
+ var CardDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
940
+ "div",
941
+ {
942
+ className: cn("text-sm text-muted-foreground", className),
943
+ ref,
944
+ ...props
945
+ }
946
+ ));
947
+ CardDescription.displayName = "CardDescription";
948
+ var CardContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cn("p-6 pt-0", className), ref, ...props }));
949
+ CardContent.displayName = "CardContent";
950
+ var CardFooter = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
951
+ "div",
952
+ {
953
+ className: cn("flex items-center p-6 pt-0", className),
954
+ ref,
955
+ ...props
956
+ }
957
+ ));
958
+ CardFooter.displayName = "CardFooter";
959
+
495
960
  // src/components/Map/components/MapEtaPanel.tsx
496
- var import_jsx_runtime2 = require("react/jsx-runtime");
961
+ var import_jsx_runtime5 = require("react/jsx-runtime");
497
962
  var MapEtaPanel = ({
498
963
  etaData,
499
964
  layoutMode,
@@ -502,15 +967,15 @@ var MapEtaPanel = ({
502
967
  isDragging = false
503
968
  }) => {
504
969
  if (layoutMode === "closed-banner") {
505
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full h-10 flex items-center justify-between px-4 pb-2 pt-1 border-b border-white/5 bg-zinc-950/15 relative overflow-hidden", children: [
506
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
970
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w-full h-10 flex items-center justify-between px-4 pb-2 pt-1 border-b border-white/5 bg-zinc-950/15 relative overflow-hidden", children: [
971
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
507
972
  "div",
508
973
  {
509
974
  className: "flex items-center gap-2 cursor-pointer flex-1",
510
975
  onClick: onHeaderClick,
511
976
  children: [
512
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
513
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "text-xs font-bold text-emerald-400", children: [
977
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
978
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "text-xs font-bold text-emerald-400", children: [
514
979
  etaData.etaMins,
515
980
  " min (",
516
981
  etaData.distanceRemainingKm.toFixed(1),
@@ -519,36 +984,37 @@ var MapEtaPanel = ({
519
984
  ]
520
985
  }
521
986
  ),
522
- etaData.onAbort && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
523
- "button",
987
+ etaData.onAbort && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
988
+ Button,
524
989
  {
525
- className: "px-1 py-1 text-[10px] font-black bg-red-500/20 text-red-400 hover:bg-red-500/30 border border-red-500/25 active:scale-95 rounded-md transition-all cursor-pointer pointer-events-auto",
990
+ className: "px-1 py-1 text-[10px] font-black bg-red-500/20 text-red-400 hover:bg-red-500/30 border border-red-500/25 active:scale-95 rounded-md transition-all cursor-pointer pointer-events-auto h-auto p-0!",
526
991
  onClick: (e) => {
527
992
  e.stopPropagation();
528
993
  etaData.onAbort?.();
529
994
  },
530
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
995
+ variant: "ghost",
996
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
531
997
  "svg",
532
998
  {
533
999
  className: "lucide lucide-x",
534
1000
  fill: "none",
535
1001
  height: "18",
536
1002
  stroke: "currentColor",
537
- "stroke-linecap": "round",
538
- "stroke-linejoin": "round",
539
- "stroke-width": "2.5",
1003
+ strokeLinecap: "round",
1004
+ strokeLinejoin: "round",
1005
+ strokeWidth: "2.5",
540
1006
  viewBox: "0 0 24 24",
541
1007
  width: "18",
542
1008
  xmlns: "http://www.w3.org/2000/svg",
543
1009
  children: [
544
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 6 6 18" }),
545
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 6 12 12" })
1010
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M18 6 6 18" }),
1011
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 6 12 12" })
546
1012
  ]
547
1013
  }
548
1014
  )
549
1015
  }
550
1016
  ),
551
- etaData.progress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute bottom-0 left-0 right-0 h-[2px] bg-white/5", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1017
+ etaData.progress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "absolute bottom-0 left-0 right-0 h-[2px] bg-white/5", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
552
1018
  "div",
553
1019
  {
554
1020
  className: "h-full bg-cyan-400",
@@ -558,166 +1024,174 @@ var MapEtaPanel = ({
558
1024
  ] });
559
1025
  }
560
1026
  if (layoutMode === "open-card") {
561
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mx-4 mt-2 p-4 bg-white/5 border border-white/10 rounded-xl flex flex-col", children: [
562
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
563
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2", children: [
564
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
565
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px] font-bold text-emerald-400 uppercase tracking-wider", children: etaData.label || "Journey Active" })
1027
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Card, { className: "mx-4 mt-2 p-4 bg-white/5 border border-white/10 rounded-xl flex flex-col text-card-foreground", children: [
1028
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
1029
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
1030
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
1031
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[10px] font-bold text-emerald-400 uppercase tracking-wider", children: etaData.label || "Journey Active" })
566
1032
  ] }),
567
- etaData.onAbort && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
568
- "button",
1033
+ etaData.onAbort && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1034
+ Button,
569
1035
  {
570
- className: "px-1 px-1 text-xs font-bold bg-red-500/20 text-red-400 hover:bg-red-500/30 border border-red-500/30 active:scale-95 rounded-lg transition-all cursor-pointer pointer-events-auto",
1036
+ className: "px-1 py-1 text-xs font-bold bg-red-500/20 text-red-400 hover:bg-red-500/30 border border-red-500/30 active:scale-95 rounded-lg transition-all cursor-pointer pointer-events-auto h-auto p-0!",
571
1037
  onClick: etaData.onAbort,
572
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1038
+ variant: "ghost",
1039
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
573
1040
  "svg",
574
1041
  {
575
1042
  className: "lucide lucide-x",
576
1043
  fill: "none",
577
1044
  height: "18",
578
1045
  stroke: "currentColor",
579
- "stroke-linecap": "round",
580
- "stroke-linejoin": "round",
581
- "stroke-width": "2.5",
1046
+ strokeLinecap: "round",
1047
+ strokeLinejoin: "round",
1048
+ strokeWidth: "2.5",
582
1049
  viewBox: "0 0 24 24",
583
1050
  width: "18",
584
1051
  xmlns: "http://www.w3.org/2000/svg",
585
1052
  children: [
586
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 6 6 18" }),
587
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 6 12 12" })
1053
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M18 6 6 18" }),
1054
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 6 12 12" })
588
1055
  ]
589
1056
  }
590
1057
  )
591
1058
  }
592
1059
  )
593
1060
  ] }),
594
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "grid grid-cols-2 divide-x divide-white/10 py-1.5 mb-2.5", children: [
595
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-center", children: [
596
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-xl font-black text-white leading-none", children: [
597
- etaData.etaMins,
598
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-xs text-zinc-400 font-normal", children: " min" })
1061
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(CardContent, { className: "p-0 flex flex-col", children: [
1062
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "grid grid-cols-2 divide-x divide-white/10 py-1.5 mb-2.5", children: [
1063
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-center", children: [
1064
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-xl font-black text-white leading-none", children: [
1065
+ etaData.etaMins,
1066
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-xs text-zinc-400 font-normal", children: " min" })
1067
+ ] }),
1068
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-[8px] text-zinc-500 font-bold uppercase tracking-wider mt-1", children: "Time Remaining" })
599
1069
  ] }),
600
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "text-[8px] text-zinc-500 font-bold uppercase tracking-wider mt-1", children: "Time Remaining" })
1070
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-center", children: [
1071
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-xl font-black text-white leading-none", children: [
1072
+ etaData.distanceRemainingKm.toFixed(1),
1073
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-xs text-zinc-400 font-normal", children: " km" })
1074
+ ] }),
1075
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-[8px] text-zinc-500 font-bold uppercase tracking-wider mt-1", children: "Distance Remaining" })
1076
+ ] })
601
1077
  ] }),
602
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-center", children: [
603
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-xl font-black text-white leading-none", children: [
604
- etaData.distanceRemainingKm.toFixed(1),
605
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-xs text-zinc-400 font-normal", children: " km" })
1078
+ etaData.progress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mb-3", children: [
1079
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex justify-between text-[9px] font-bold text-zinc-400 mb-1", children: [
1080
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Progress" }),
1081
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
1082
+ Math.round(etaData.progress),
1083
+ "%"
1084
+ ] })
606
1085
  ] }),
607
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "text-[8px] text-zinc-500 font-bold uppercase tracking-wider mt-1", children: "Distance Remaining" })
608
- ] })
609
- ] }),
610
- etaData.progress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-3", children: [
611
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex justify-between text-[9px] font-bold text-zinc-450 mb-1", children: [
612
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Progress" }),
613
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
614
- Math.round(etaData.progress),
615
- "%"
616
- ] })
1086
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "h-1 bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1087
+ "div",
1088
+ {
1089
+ className: "h-full bg-cyan-400 rounded-full",
1090
+ style: { width: `${etaData.progress}%` }
1091
+ }
1092
+ ) })
617
1093
  ] }),
618
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "h-1 bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
619
- "div",
1094
+ etaData.mode === "preview" && etaData.onStart && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1095
+ Button,
620
1096
  {
621
- className: "h-full bg-cyan-400 rounded-full",
622
- style: { width: `${etaData.progress}%` }
1097
+ className: "w-full py-2.5 text-xs font-bold bg-cyan-500 text-black hover:bg-cyan-400 hover:text-black active:scale-95 rounded-lg transition-all cursor-pointer h-auto",
1098
+ onClick: etaData.onStart,
1099
+ variant: "ghost",
1100
+ children: "Start Guidance"
623
1101
  }
624
- ) })
625
- ] }),
626
- etaData.mode === "preview" && etaData.onStart && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
627
- "button",
628
- {
629
- className: "w-full py-2.5 text-xs font-bold bg-cyan-500 text-black hover:bg-cyan-400 active:scale-95 rounded-lg transition-all cursor-pointer",
630
- onClick: etaData.onStart,
631
- children: "Start Guidance"
632
- }
633
- )
1102
+ )
1103
+ ] })
634
1104
  ] });
635
1105
  }
636
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
637
- "div",
1106
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1107
+ Card,
638
1108
  {
639
- className: `absolute left-1/2 -translate-x-1/2 z-40 w-[calc(100%-2rem)] max-w-[320px] sm:max-w-[380px] bg-zinc-950/85 backdrop-blur-md border border-white/10 rounded-2xl shadow-2xl p-3 sm:p-4 flex flex-col pointer-events-auto select-none ${isDragging ? "transition-none" : "transition-all duration-300 ease-out"}`,
1109
+ className: `absolute left-1/2 -translate-x-1/2 z-40 w-[calc(100%-2rem)] max-w-[320px] sm:max-w-[380px] bg-zinc-950/85 backdrop-blur-md border border-white/10 rounded-2xl shadow-2xl p-3 sm:p-4 flex flex-col pointer-events-auto select-none text-card-foreground ${isDragging ? "transition-none" : "transition-all duration-300 ease-out"}`,
640
1110
  style,
641
1111
  children: [
642
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center justify-between mb-2 sm:mb-3", children: [
643
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2", children: [
644
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-1.5 h-1.5 sm:w-2 sm:h-2 rounded-full bg-emerald-500 animate-pulse" }),
645
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[9px] sm:text-[10px] font-bold text-emerald-400 uppercase tracking-wider", children: etaData.label || "Guidance Active" })
1112
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between mb-2 sm:mb-3", children: [
1113
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
1114
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-1.5 h-1.5 sm:w-2 sm:h-2 rounded-full bg-emerald-500 animate-pulse" }),
1115
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[9px] sm:text-[10px] font-bold text-emerald-400 uppercase tracking-wider", children: etaData.label || "Guidance Active" })
646
1116
  ] }),
647
- etaData.onAbort && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
648
- "button",
1117
+ etaData.onAbort && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1118
+ Button,
649
1119
  {
650
- className: "px-1 py-1 text-[10px] sm:text-xs font-bold bg-red-500/20 text-red-400 hover:bg-red-500/30 border border-red-500/30 active:scale-95 rounded-lg transition-all cursor-pointer",
1120
+ className: "px-1 py-1 text-[10px] sm:text-xs font-bold bg-red-500/20 text-red-400 hover:bg-red-500/30 border border-red-500/30 active:scale-95 rounded-lg transition-all cursor-pointer h-auto p-0!",
651
1121
  onClick: etaData.onAbort,
652
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1122
+ variant: "ghost",
1123
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
653
1124
  "svg",
654
1125
  {
655
1126
  className: "lucide lucide-x",
656
1127
  fill: "none",
657
1128
  height: "18",
658
1129
  stroke: "currentColor",
659
- "stroke-linecap": "round",
660
- "stroke-linejoin": "round",
661
- "stroke-width": "2.5",
1130
+ strokeLinecap: "round",
1131
+ strokeLinejoin: "round",
1132
+ strokeWidth: "2.5",
662
1133
  viewBox: "0 0 24 24",
663
1134
  width: "18",
664
1135
  xmlns: "http://www.w3.org/2000/svg",
665
1136
  children: [
666
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 6 6 18" }),
667
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 6 12 12" })
1137
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M18 6 6 18" }),
1138
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 6 12 12" })
668
1139
  ]
669
1140
  }
670
1141
  )
671
1142
  }
672
1143
  )
673
1144
  ] }),
674
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "grid grid-cols-2 divide-x divide-white/10 py-0.5 sm:py-1 mb-2 sm:mb-3", children: [
675
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-base sm:text-lg font-black text-white leading-none", children: [
676
- etaData.etaMins,
677
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "text-[10px] sm:text-xs text-zinc-400 font-normal", children: [
678
- " ",
679
- "min"
680
- ] })
681
- ] }) }),
682
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-base sm:text-lg font-black text-white leading-none", children: [
683
- etaData.distanceRemainingKm.toFixed(1),
684
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "text-[10px] sm:text-xs text-zinc-400 font-normal", children: [
685
- " ",
686
- "km"
687
- ] })
688
- ] }) })
689
- ] }),
690
- etaData.progress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
691
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex justify-between text-[8px] sm:text-[9px] font-bold text-zinc-400 mb-1", children: [
692
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Progress" }),
693
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
694
- Math.round(etaData.progress),
695
- "%"
696
- ] })
1145
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(CardContent, { className: "p-0 flex flex-col", children: [
1146
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "grid grid-cols-2 divide-x divide-white/10 py-0.5 sm:py-1 mb-2 sm:mb-3", children: [
1147
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-base sm:text-lg font-black text-white leading-none", children: [
1148
+ etaData.etaMins,
1149
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "text-[10px] sm:text-xs text-zinc-400 font-normal", children: [
1150
+ " ",
1151
+ "min"
1152
+ ] })
1153
+ ] }) }),
1154
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-base sm:text-lg font-black text-white leading-none", children: [
1155
+ etaData.distanceRemainingKm.toFixed(1),
1156
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "text-[10px] sm:text-xs text-zinc-400 font-normal", children: [
1157
+ " ",
1158
+ "km"
1159
+ ] })
1160
+ ] }) })
697
1161
  ] }),
698
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "h-1 sm:h-1.5 bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
699
- "div",
1162
+ etaData.progress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1163
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex justify-between text-[8px] sm:text-[9px] font-bold text-zinc-400 mb-1", children: [
1164
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Progress" }),
1165
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
1166
+ Math.round(etaData.progress),
1167
+ "%"
1168
+ ] })
1169
+ ] }),
1170
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "h-1 sm:h-1.5 bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1171
+ "div",
1172
+ {
1173
+ className: "h-full bg-cyan-400 rounded-full",
1174
+ style: { width: `${etaData.progress}%` }
1175
+ }
1176
+ ) })
1177
+ ] }),
1178
+ etaData.mode === "preview" && etaData.onStart && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1179
+ Button,
700
1180
  {
701
- className: "h-full bg-cyan-400 rounded-full",
702
- style: { width: `${etaData.progress}%` }
1181
+ className: "mt-2.5 sm:mt-3 py-1.5 sm:py-2 text-[11px] sm:text-xs font-bold bg-cyan-500 text-black hover:bg-cyan-400 hover:text-black active:scale-95 rounded-lg transition-all cursor-pointer h-auto",
1182
+ onClick: etaData.onStart,
1183
+ variant: "ghost",
1184
+ children: "Start Guidance"
703
1185
  }
704
- ) })
705
- ] }),
706
- etaData.mode === "preview" && etaData.onStart && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
707
- "button",
708
- {
709
- className: "mt-2.5 sm:mt-3 py-1.5 sm:py-2 text-[11px] sm:text-xs font-bold bg-cyan-500 text-black hover:bg-cyan-400 active:scale-95 rounded-lg transition-all cursor-pointer",
710
- onClick: etaData.onStart,
711
- children: "Start Guidance"
712
- }
713
- )
1186
+ )
1187
+ ] })
714
1188
  ]
715
1189
  }
716
1190
  );
717
1191
  };
718
1192
 
719
1193
  // src/components/Map/components/MapRightControls.tsx
720
- var import_jsx_runtime3 = require("react/jsx-runtime");
1194
+ var import_jsx_runtime6 = require("react/jsx-runtime");
721
1195
  var MapRightControls = ({
722
1196
  customControls = [],
723
1197
  etaBarHeight,
@@ -735,7 +1209,7 @@ var MapRightControls = ({
735
1209
  customRecenterButton,
736
1210
  customCompassButton,
737
1211
  drawerPeekHeight,
738
- insets = { top: 0, bottom: 0, left: 0, right: 0 }
1212
+ insets = { bottom: 0, left: 0, right: 0, top: 0 }
739
1213
  }) => {
740
1214
  const aboveControls = customControls.filter(
741
1215
  (c) => c.position === "above-recenter"
@@ -747,9 +1221,9 @@ var MapRightControls = ({
747
1221
  const closedHeightOffset = "32px";
748
1222
  const activeEtaHeight = etaData ? etaBarHeight : drawerState === "closed" ? insets.bottom : 0;
749
1223
  const peekStyle = typeof drawerPeekHeight === "number" ? `${drawerPeekHeight}px` : drawerPeekHeight || "15%";
750
- 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)`;
1224
+ 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)`;
751
1225
  const isControlsVisible = side !== "bottom" || drawerState !== "full";
752
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1226
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
753
1227
  "div",
754
1228
  {
755
1229
  className: `absolute right-4 z-30 flex flex-col items-center gap-3 select-none pointer-events-none ${isDragging ? "transition-none" : "transition-all duration-300 ease-out"} ${isControlsVisible ? "opacity-100 scale-100 pointer-events-auto" : "opacity-0 scale-75 pointer-events-none"}`,
@@ -757,27 +1231,29 @@ var MapRightControls = ({
757
1231
  bottom: controlsBottom
758
1232
  },
759
1233
  children: [
760
- aboveControls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col gap-2 pointer-events-auto", children: aboveControls.map((control) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative group flex items-center", children: [
761
- control.tooltip && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute right-14 pointer-events-none opacity-0 scale-95 origin-right group-hover:opacity-100 group-hover:scale-100 transition-all duration-150 bg-zinc-900/95 border border-white/10 text-white text-xs px-2.5 py-1.5 rounded-lg shadow-xl whitespace-nowrap", children: control.tooltip }),
762
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
763
- "button",
1234
+ aboveControls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex flex-col gap-2 pointer-events-auto", children: aboveControls.map((control) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative group flex items-center", children: [
1235
+ control.tooltip && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute right-14 pointer-events-none opacity-0 scale-95 origin-right group-hover:opacity-100 group-hover:scale-100 transition-all duration-150 bg-zinc-900/95 border border-white/10 text-white text-xs px-2.5 py-1.5 rounded-lg shadow-xl whitespace-nowrap", children: control.tooltip }),
1236
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1237
+ Button,
764
1238
  {
765
- className: `w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer ${control.activeState ? "ring-2 ring-cyan-400 ring-offset-2 ring-offset-zinc-950" : "hover:bg-zinc-900"}`,
1239
+ className: `w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer p-0! hover:bg-zinc-900 hover:text-white ${control.activeState ? "ring-2 ring-cyan-400 ring-offset-2 ring-offset-zinc-950" : ""}`,
766
1240
  onClick: control.onPress,
1241
+ variant: "ghost",
767
1242
  children: control.icon
768
1243
  }
769
1244
  )
770
1245
  ] }, control.id)) }),
771
- isCompassVisible && (customCompassButton ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pointer-events-auto", children: customCompassButton }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pointer-events-auto", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
772
- "button",
1246
+ isCompassVisible && (customCompassButton ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pointer-events-auto", children: customCompassButton }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pointer-events-auto", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1247
+ Button,
773
1248
  {
774
- className: `w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all duration-300 ${isCompassVisible ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none h-0 w-0 border-none m-0 p-0 overflow-hidden"}`,
1249
+ className: `w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all duration-300 p-0! hover:bg-zinc-900 hover:text-white ${isCompassVisible ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none h-0 w-0 border-none m-0 p-0 overflow-hidden"}`,
775
1250
  onClick: () => onResetBearing({ pitch: initialViewState?.pitch ?? 0 }),
776
1251
  style: {
777
1252
  transform: isCompassVisible ? "scale(1) rotate(0deg)" : "scale(0.7) rotate(0deg)"
778
1253
  },
779
1254
  title: "Reset bearing to North",
780
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1255
+ variant: "ghost",
1256
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
781
1257
  "svg",
782
1258
  {
783
1259
  className: "w-7 h-7 transition-transform duration-75 ease-out",
@@ -787,7 +1263,7 @@ var MapRightControls = ({
787
1263
  },
788
1264
  viewBox: "0 0 24 24",
789
1265
  children: [
790
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1266
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
791
1267
  "circle",
792
1268
  {
793
1269
  cx: "12",
@@ -798,23 +1274,24 @@ var MapRightControls = ({
798
1274
  strokeWidth: "1"
799
1275
  }
800
1276
  ),
801
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 4.5L15 12H9L12 4.5Z", fill: "#ef4444" }),
802
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 19.5L9 12H15L12 19.5Z", fill: "#f4f4f5" }),
803
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", fill: "#18181b", r: "1.5" })
1277
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 4.5L15 12H9L12 4.5Z", fill: "#ef4444" }),
1278
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 19.5L9 12H15L12 19.5Z", fill: "#f4f4f5" }),
1279
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "12", cy: "12", fill: "#18181b", r: "1.5" })
804
1280
  ]
805
1281
  }
806
1282
  )
807
1283
  }
808
1284
  ) })),
809
- customRecenterButton ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pointer-events-auto", children: customRecenterButton }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pointer-events-auto", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
810
- "button",
1285
+ customRecenterButton ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pointer-events-auto", children: customRecenterButton }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pointer-events-auto", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1286
+ Button,
811
1287
  {
812
- className: `w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer ${isMapCentered ? "ring-2 ring-cyan-400 ring-offset-2 ring-offset-zinc-950" : "hover:bg-zinc-900"}`,
1288
+ className: `w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer p-0! hover:bg-zinc-900 hover:text-white ${isMapCentered ? "ring-2 ring-cyan-400 ring-offset-2 ring-offset-zinc-950" : ""}`,
813
1289
  onClick: () => onRecenter(),
814
1290
  title: "Recenter Map",
1291
+ variant: "ghost",
815
1292
  children: isMapCentered ? (
816
1293
  /* Filled active lock state */
817
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1294
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
818
1295
  "svg",
819
1296
  {
820
1297
  className: "w-6 h-6 text-cyan-400",
@@ -823,18 +1300,18 @@ var MapRightControls = ({
823
1300
  strokeWidth: "2.2",
824
1301
  viewBox: "0 0 24 24",
825
1302
  children: [
826
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "8" }),
827
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", fill: "currentColor", r: "3" }),
828
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12", y1: "2", y2: "4" }),
829
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12", y1: "20", y2: "22" }),
830
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "2", x2: "4", y1: "12", y2: "12" }),
831
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "20", x2: "22", y1: "12", y2: "12" })
1303
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "12", cy: "12", r: "8" }),
1304
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "12", cy: "12", fill: "currentColor", r: "3" }),
1305
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", x2: "12", y1: "2", y2: "4" }),
1306
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", x2: "12", y1: "20", y2: "22" }),
1307
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "2", x2: "4", y1: "12", y2: "12" }),
1308
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "20", x2: "22", y1: "12", y2: "12" })
832
1309
  ]
833
1310
  }
834
1311
  )
835
1312
  ) : (
836
1313
  /* Outlined drifted state */
837
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1314
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
838
1315
  "svg",
839
1316
  {
840
1317
  className: "w-6 h-6 text-zinc-300",
@@ -843,24 +1320,25 @@ var MapRightControls = ({
843
1320
  strokeWidth: "2",
844
1321
  viewBox: "0 0 24 24",
845
1322
  children: [
846
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "8" }),
847
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12", y1: "2", y2: "4" }),
848
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12", y1: "20", y2: "22" }),
849
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "2", x2: "4", y1: "12", y2: "12" }),
850
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "20", x2: "22", y1: "12", y2: "12" })
1323
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "12", cy: "12", r: "8" }),
1324
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", x2: "12", y1: "2", y2: "4" }),
1325
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", x2: "12", y1: "20", y2: "22" }),
1326
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "2", x2: "4", y1: "12", y2: "12" }),
1327
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "20", x2: "22", y1: "12", y2: "12" })
851
1328
  ]
852
1329
  }
853
1330
  )
854
1331
  )
855
1332
  }
856
1333
  ) }),
857
- belowControls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col gap-2 pointer-events-auto", children: belowControls.map((control) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative group flex items-center", children: [
858
- control.tooltip && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute right-14 pointer-events-none opacity-0 scale-95 origin-right group-hover:opacity-100 group-hover:scale-100 transition-all duration-150 bg-zinc-900/95 border border-white/10 text-white text-xs px-2.5 py-1.5 rounded-lg shadow-xl whitespace-nowrap", children: control.tooltip }),
859
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
860
- "button",
1334
+ belowControls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex flex-col gap-2 pointer-events-auto", children: belowControls.map((control) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative group flex items-center", children: [
1335
+ control.tooltip && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute right-14 pointer-events-none opacity-0 scale-95 origin-right group-hover:opacity-100 group-hover:scale-100 transition-all duration-150 bg-zinc-900/95 border border-white/10 text-white text-xs px-2.5 py-1.5 rounded-lg shadow-xl whitespace-nowrap", children: control.tooltip }),
1336
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1337
+ Button,
861
1338
  {
862
- className: `w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer ${control.activeState ? "ring-2 ring-cyan-400 ring-offset-2 ring-offset-zinc-950" : "hover:bg-zinc-900"}`,
1339
+ className: `w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer p-0! hover:bg-zinc-900 hover:text-white ${control.activeState ? "ring-2 ring-cyan-400 ring-offset-2 ring-offset-zinc-950" : ""}`,
863
1340
  onClick: control.onPress,
1341
+ variant: "ghost",
864
1342
  children: control.icon
865
1343
  }
866
1344
  )
@@ -872,7 +1350,7 @@ var MapRightControls = ({
872
1350
 
873
1351
  // src/components/Map/MapContext.tsx
874
1352
  var import_react2 = require("react");
875
- var import_jsx_runtime4 = require("react/jsx-runtime");
1353
+ var import_jsx_runtime7 = require("react/jsx-runtime");
876
1354
  var MapControlsContext = (0, import_react2.createContext)(
877
1355
  null
878
1356
  );
@@ -903,10 +1381,10 @@ var SDKMapProvider = ({
903
1381
  });
904
1382
  }, []);
905
1383
  const [insets, setInsetsState] = (0, import_react2.useState)({
906
- top: 0,
907
1384
  bottom: 0,
908
1385
  left: 0,
909
- right: 0
1386
+ right: 0,
1387
+ top: 0
910
1388
  });
911
1389
  const setInsets = (0, import_react2.useCallback)((newInsets) => {
912
1390
  setInsetsState((prev) => ({ ...prev, ...newInsets }));
@@ -951,6 +1429,7 @@ var SDKMapProvider = ({
951
1429
  drawerState,
952
1430
  etaData,
953
1431
  hasControls,
1432
+ insets,
954
1433
  isFollowing,
955
1434
  pitch,
956
1435
  resetBearing,
@@ -958,10 +1437,9 @@ var SDKMapProvider = ({
958
1437
  setDrawerState,
959
1438
  setEtaData,
960
1439
  setHasControls,
1440
+ setInsets,
961
1441
  setIsFollowing,
962
- setPitch,
963
- insets,
964
- setInsets
1442
+ setPitch
965
1443
  }),
966
1444
  [
967
1445
  _registerCenterCallback,
@@ -983,7 +1461,7 @@ var SDKMapProvider = ({
983
1461
  setInsets
984
1462
  ]
985
1463
  );
986
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MapControlsContext.Provider, { value: contextValue, children });
1464
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MapControlsContext.Provider, { value: contextValue, children });
987
1465
  };
988
1466
  var useMapControls = () => {
989
1467
  const context = (0, import_react2.useContext)(MapControlsContext);
@@ -995,7 +1473,7 @@ var useMapControls = () => {
995
1473
 
996
1474
  // src/components/Map/components/MapControls.tsx
997
1475
  var import_react3 = require("react");
998
- var import_jsx_runtime5 = require("react/jsx-runtime");
1476
+ var import_jsx_runtime8 = require("react/jsx-runtime");
999
1477
  var resolveHeightToPixels2 = (height, containerHeight) => {
1000
1478
  if (typeof height === "number") {
1001
1479
  return height;
@@ -1025,6 +1503,8 @@ var MapControls = ({
1025
1503
  menuContent,
1026
1504
  children,
1027
1505
  enableTouchDrag = false,
1506
+ showScrollToTopButton = true,
1507
+ scrollToTopThreshold = 300,
1028
1508
  isInternal = false
1029
1509
  }) => {
1030
1510
  const mapContext = (0, import_react3.useContext)(MapControlsContext);
@@ -1125,14 +1605,23 @@ var MapControls = ({
1125
1605
  }, [drawerSide]);
1126
1606
  const isDragging = touchStartY !== null && currentTouchY !== null;
1127
1607
  const dragOffset = isDragging ? currentTouchY - touchStartY : 0;
1608
+ const fullPx = resolveHeightToPixels2(drawerFullHeight || "85%", mapHeight);
1609
+ const peekPx = resolveHeightToPixels2(drawerPeekHeight || "15%", mapHeight);
1610
+ const bottomInset = mapContext?.insets.bottom || 0;
1611
+ const closedPx = 32 + (drawerState === "closed" ? bottomInset : 0);
1128
1612
  let clampedDragOffset = dragOffset;
1129
1613
  if (drawerState === "full") {
1130
- clampedDragOffset = Math.max(0, dragOffset);
1614
+ clampedDragOffset = Math.max(0, Math.min(fullPx - closedPx, dragOffset));
1615
+ } else if (drawerState === "peek") {
1616
+ clampedDragOffset = Math.max(
1617
+ -(fullPx - peekPx),
1618
+ // up to full
1619
+ Math.min(peekPx - closedPx, dragOffset)
1620
+ // down to closed
1621
+ );
1131
1622
  } else if (drawerState === "closed") {
1132
- clampedDragOffset = Math.min(0, dragOffset);
1623
+ clampedDragOffset = Math.min(0, Math.max(-(fullPx - closedPx), dragOffset));
1133
1624
  }
1134
- const fullPx = resolveHeightToPixels2(drawerFullHeight || "85%", mapHeight);
1135
- const peekPx = resolveHeightToPixels2(drawerPeekHeight || "15%", mapHeight);
1136
1625
  let baseHeight = 32;
1137
1626
  if (drawerState === "peek") {
1138
1627
  baseHeight = peekPx;
@@ -1142,7 +1631,6 @@ var MapControls = ({
1142
1631
  const currentDrawerHeight = baseHeight - clampedDragOffset;
1143
1632
  const startFadeHeight = peekPx + 20;
1144
1633
  const endFadeHeight = peekPx + (fullPx - peekPx) * 0.35;
1145
- const bottomInset = mapContext?.insets.bottom || 0;
1146
1634
  let etaOpacity = 1;
1147
1635
  let etaBottomStyle = "1rem";
1148
1636
  if (side === "bottom") {
@@ -1155,14 +1643,14 @@ var MapControls = ({
1155
1643
  etaOpacity = 1 - fraction;
1156
1644
  }
1157
1645
  const effectiveInset = drawerState === "closed" ? bottomInset : 0;
1158
- etaBottomStyle = `${currentDrawerHeight + effectiveInset + 16}px`;
1646
+ etaBottomStyle = `calc(${baseHeight + effectiveInset + 16}px - var(--drag-offset, 0px))`;
1159
1647
  } else {
1160
1648
  etaOpacity = drawerState === "full" ? 0 : 1;
1161
1649
  etaBottomStyle = `calc(1rem + ${bottomInset}px)`;
1162
1650
  }
1163
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1164
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: containerRef, style: { display: "none" } }),
1165
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1651
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1652
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, style: { display: "none" } }),
1653
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1166
1654
  MapDrawer,
1167
1655
  {
1168
1656
  clampedDragOffset,
@@ -1179,14 +1667,16 @@ var MapControls = ({
1179
1667
  onChangeState: setDrawerState,
1180
1668
  ref: mergedRef,
1181
1669
  safeAreaInsets: mapContext?.insets,
1670
+ scrollToTopThreshold,
1182
1671
  setCurrentTouchY,
1183
1672
  setTouchStartY,
1673
+ showScrollToTopButton,
1184
1674
  side,
1185
1675
  state: drawerState,
1186
1676
  touchStartY
1187
1677
  }
1188
1678
  ),
1189
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1679
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1190
1680
  MapRightControls,
1191
1681
  {
1192
1682
  clampedDragOffset,
@@ -1208,7 +1698,7 @@ var MapControls = ({
1208
1698
  side
1209
1699
  }
1210
1700
  ),
1211
- resolvedEtaData && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1701
+ resolvedEtaData && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1212
1702
  MapEtaPanel,
1213
1703
  {
1214
1704
  etaData: resolvedEtaData,
@@ -1227,9 +1717,9 @@ var MapControls = ({
1227
1717
 
1228
1718
  // src/components/Map/components/MapMenu.tsx
1229
1719
  var import_react4 = require("react");
1230
- var import_jsx_runtime6 = require("react/jsx-runtime");
1720
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1231
1721
  var MapMenu = ({ children }) => {
1232
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex flex-col gap-1.5", children });
1722
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-col gap-1.5", children });
1233
1723
  };
1234
1724
  var MapMenuItem = ({
1235
1725
  id,
@@ -1248,7 +1738,7 @@ var MapMenuItem = ({
1248
1738
  context.setDrawerState("closed");
1249
1739
  }
1250
1740
  };
1251
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1741
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1252
1742
  "button",
1253
1743
  {
1254
1744
  className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 ${disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : "hover:bg-white/5 active:bg-white/10 text-white"}`,
@@ -1256,12 +1746,12 @@ var MapMenuItem = ({
1256
1746
  onClick: handleClick,
1257
1747
  type: "button",
1258
1748
  children: [
1259
- icon && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
1749
+ icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
1260
1750
  icon,
1261
- badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.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: badge })
1751
+ badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.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: badge })
1262
1752
  ] }),
1263
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex-1 flex flex-col justify-center", children: [
1264
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: label }),
1753
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex-1 flex flex-col justify-center", children: [
1754
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: label }),
1265
1755
  children
1266
1756
  ] })
1267
1757
  ]
@@ -1275,7 +1765,7 @@ var MapMenuTitle = ({
1275
1765
  showDivider = true,
1276
1766
  className = ""
1277
1767
  }) => {
1278
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1768
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1279
1769
  "div",
1280
1770
  {
1281
1771
  className: `flex items-center justify-between pb-3 first:mt-0 px-3.5 ${className} ${showDivider ? "border-b border-white/10 mb-2 mt-4" : ""}`,
@@ -1287,14 +1777,14 @@ MapMenuTitle.displayName = "MapMenuTitle";
1287
1777
  var MapMenuDivider = ({
1288
1778
  className = ""
1289
1779
  }) => {
1290
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `h-[1px] bg-white/10 my-3 mx-3.5 ${className}` });
1780
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `h-[1px] bg-white/10 my-3 mx-3.5 ${className}` });
1291
1781
  };
1292
1782
  MapMenuDivider.displayName = "MapMenuDivider";
1293
1783
  var MapMenuFooter = ({
1294
1784
  children,
1295
1785
  className = ""
1296
1786
  }) => {
1297
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1787
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1298
1788
  "div",
1299
1789
  {
1300
1790
  className: `mt-auto pt-4 border-t border-white/10 px-3.5 text-xs text-zinc-500 font-medium ${className}`,
@@ -1452,7 +1942,8 @@ var useLiveRouting = ({
1452
1942
  const [error, setError] = (0, import_react6.useState)(null);
1453
1943
  const [mode, setMode] = (0, import_react6.useState)(initialMode);
1454
1944
  const userLocationState = useUserLocation();
1455
- const userLocation = manualOrigin || userLocationState.coords;
1945
+ const calculationOrigin = manualOrigin || userLocationState.coords;
1946
+ const trackingLocation = userLocationState.coords || manualOrigin;
1456
1947
  const lastCalcOrigin = (0, import_react6.useRef)(null);
1457
1948
  const lastCalcDest = (0, import_react6.useRef)(null);
1458
1949
  const isRequestInProgress = (0, import_react6.useRef)(false);
@@ -1470,9 +1961,32 @@ var useLiveRouting = ({
1470
1961
  []
1471
1962
  );
1472
1963
  const currentDistanceMeters = (0, import_react6.useMemo)(() => {
1473
- if (!userLocation || !destination) return null;
1474
- return getDistance(userLocation, destination);
1475
- }, [userLocation, destination, getDistance]);
1964
+ if (!trackingLocation || !route || route.geometry.coordinates.length < 2) {
1965
+ if (trackingLocation && destination) {
1966
+ return getDistance(trackingLocation, destination);
1967
+ }
1968
+ return null;
1969
+ }
1970
+ const coords = route.geometry.coordinates;
1971
+ let minDistSq = Infinity;
1972
+ let closestIndex = 0;
1973
+ const getDistSq = (p1, p2) => (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2;
1974
+ for (let i = 0; i < coords.length; i++) {
1975
+ const d = getDistSq(trackingLocation, coords[i]);
1976
+ if (d < minDistSq) {
1977
+ minDistSq = d;
1978
+ closestIndex = i;
1979
+ }
1980
+ }
1981
+ const remainingCoords = coords.slice(closestIndex + 1);
1982
+ let dist = 0;
1983
+ let prev = trackingLocation;
1984
+ for (const coord of remainingCoords) {
1985
+ dist += getDistance(prev, coord);
1986
+ prev = coord;
1987
+ }
1988
+ return dist;
1989
+ }, [trackingLocation, route, destination, getDistance]);
1476
1990
  const calculate = (0, import_react6.useCallback)(
1477
1991
  async (origin, dest, isNewDest) => {
1478
1992
  if (isRequestInProgress.current) return;
@@ -1487,7 +2001,15 @@ var useLiveRouting = ({
1487
2001
  setRoute(data);
1488
2002
  setError(null);
1489
2003
  if (isNewDest) {
1490
- setTotalDistance(data.distanceMeters);
2004
+ const coords = data.geometry.coordinates;
2005
+ let sum = 0;
2006
+ for (let i = 0; i < coords.length - 1; i++) {
2007
+ sum += getDistance(
2008
+ coords[i],
2009
+ coords[i + 1]
2010
+ );
2011
+ }
2012
+ setTotalDistance(sum);
1491
2013
  }
1492
2014
  lastCalcOrigin.current = origin;
1493
2015
  lastCalcDest.current = dest;
@@ -1498,10 +2020,10 @@ var useLiveRouting = ({
1498
2020
  isRequestInProgress.current = false;
1499
2021
  }
1500
2022
  },
1501
- [profile]
2023
+ [profile, getDistance]
1502
2024
  );
1503
2025
  (0, import_react6.useEffect)(() => {
1504
- if (!enabled || !destination || !userLocation) {
2026
+ if (!enabled || !destination || !calculationOrigin) {
1505
2027
  if (!enabled || !destination) {
1506
2028
  setRoute(null);
1507
2029
  setTotalDistance(null);
@@ -1512,17 +2034,19 @@ var useLiveRouting = ({
1512
2034
  }
1513
2035
  const destChanged = !lastCalcDest.current || lastCalcDest.current[0] !== destination[0] || lastCalcDest.current[1] !== destination[1];
1514
2036
  if (destChanged) {
1515
- calculate(userLocation, destination, true);
2037
+ calculate(calculationOrigin, destination, true);
1516
2038
  } else if (lastCalcOrigin.current) {
1517
- const dist = getDistance(userLocation, lastCalcOrigin.current);
2039
+ const livePos = trackingLocation || calculationOrigin;
2040
+ const dist = getDistance(livePos, lastCalcOrigin.current);
1518
2041
  if (dist > recalculateThreshold) {
1519
- calculate(userLocation, destination, false);
2042
+ calculate(livePos, destination, false);
1520
2043
  }
1521
2044
  } else {
1522
- calculate(userLocation, destination, true);
2045
+ calculate(calculationOrigin, destination, true);
1523
2046
  }
1524
2047
  }, [
1525
- userLocation,
2048
+ calculationOrigin,
2049
+ trackingLocation,
1526
2050
  destination,
1527
2051
  enabled,
1528
2052
  recalculateThreshold,
@@ -1534,7 +2058,7 @@ var useLiveRouting = ({
1534
2058
  error,
1535
2059
  isCalculating,
1536
2060
  mode,
1537
- recalculate: () => userLocation && destination && calculate(userLocation, destination, false),
2061
+ recalculate: () => calculationOrigin && destination && calculate(calculationOrigin, destination, false),
1538
2062
  route,
1539
2063
  start: () => setMode("navigation"),
1540
2064
  totalDistance
@@ -1598,7 +2122,7 @@ var useTrimmedRoute = (route, userLocation) => {
1598
2122
 
1599
2123
  // src/components/Map/layers/RouteLayer.tsx
1600
2124
  var import_react_maplibre = require("@vis.gl/react-maplibre");
1601
- var import_jsx_runtime7 = require("react/jsx-runtime");
2125
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1602
2126
  var RouteLayer = ({
1603
2127
  geometry,
1604
2128
  color = "#3b82f6",
@@ -1611,8 +2135,8 @@ var RouteLayer = ({
1611
2135
  properties: {},
1612
2136
  type: "Feature"
1613
2137
  };
1614
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_maplibre.Source, { data, id: "sdk-route-source", type: "geojson", children: [
1615
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2138
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_maplibre.Source, { data, id: "sdk-route-source", type: "geojson", children: [
2139
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1616
2140
  import_react_maplibre.Layer,
1617
2141
  {
1618
2142
  id: "sdk-route-layer-casing",
@@ -1625,7 +2149,7 @@ var RouteLayer = ({
1625
2149
  type: "line"
1626
2150
  }
1627
2151
  ),
1628
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2152
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1629
2153
  import_react_maplibre.Layer,
1630
2154
  {
1631
2155
  id: "sdk-route-layer",
@@ -1652,7 +2176,7 @@ var import_maplibre_gl = require("maplibre-gl/dist/maplibre-gl.css");
1652
2176
  // src/components/Map/layers/POILayers.tsx
1653
2177
  var import_react_maplibre2 = require("@vis.gl/react-maplibre");
1654
2178
  var import_react8 = require("react");
1655
- var import_jsx_runtime8 = require("react/jsx-runtime");
2179
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1656
2180
  function createEmojiIcon(emoji, size = 64) {
1657
2181
  const canvas = document.createElement("canvas");
1658
2182
  canvas.width = size;
@@ -1729,7 +2253,7 @@ var POILayers = ({ pois }) => {
1729
2253
  }),
1730
2254
  [glPois]
1731
2255
  );
1732
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_maplibre2.Source, { data: geojson, id: "sdk-pois", type: "geojson", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2256
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_maplibre2.Source, { data: geojson, id: "sdk-pois", type: "geojson", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1733
2257
  import_react_maplibre2.Layer,
1734
2258
  {
1735
2259
  id: "sdk-poi-layer",
@@ -1766,11 +2290,11 @@ var POILayers = ({ pois }) => {
1766
2290
 
1767
2291
  // src/components/Map/layers/POIMarkers.tsx
1768
2292
  var import_react_maplibre3 = require("@vis.gl/react-maplibre");
1769
- var import_jsx_runtime9 = require("react/jsx-runtime");
2293
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1770
2294
  var POIMarkers = ({ pois, onClick }) => {
1771
2295
  const markerPois = pois.filter((p) => p.displayMode === "marker");
1772
2296
  if (markerPois.length === 0) return null;
1773
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: markerPois.map((poi) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2297
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: markerPois.map((poi) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1774
2298
  import_react_maplibre3.Marker,
1775
2299
  {
1776
2300
  anchor: "bottom",
@@ -1780,7 +2304,7 @@ var POIMarkers = ({ pois, onClick }) => {
1780
2304
  e.originalEvent.stopPropagation();
1781
2305
  if (onClick) onClick(poi);
1782
2306
  },
1783
- children: poi.markerComponent ? poi.markerComponent : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2307
+ children: poi.markerComponent ? poi.markerComponent : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1784
2308
  "div",
1785
2309
  {
1786
2310
  style: {
@@ -1789,7 +2313,7 @@ var POIMarkers = ({ pois, onClick }) => {
1789
2313
  transform: "transition-transform duration-200 hover:scale-110"
1790
2314
  },
1791
2315
  children: [
1792
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2316
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1793
2317
  "div",
1794
2318
  {
1795
2319
  style: {
@@ -1802,7 +2326,7 @@ var POIMarkers = ({ pois, onClick }) => {
1802
2326
  justifyContent: "center",
1803
2327
  width: "32px"
1804
2328
  },
1805
- children: poi.emoji ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontSize: "16px" }, children: poi.emoji }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2329
+ children: poi.emoji ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { fontSize: "16px" }, children: poi.emoji }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1806
2330
  "div",
1807
2331
  {
1808
2332
  style: {
@@ -1815,7 +2339,7 @@ var POIMarkers = ({ pois, onClick }) => {
1815
2339
  )
1816
2340
  }
1817
2341
  ),
1818
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2342
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1819
2343
  "div",
1820
2344
  {
1821
2345
  style: {
@@ -1838,19 +2362,19 @@ var POIMarkers = ({ pois, onClick }) => {
1838
2362
 
1839
2363
  // src/components/Map/layers/UserLocationLayer.tsx
1840
2364
  var import_react_maplibre4 = require("@vis.gl/react-maplibre");
1841
- var import_jsx_runtime10 = require("react/jsx-runtime");
2365
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1842
2366
  var UserLocationLayer = ({
1843
2367
  forcedLocation,
1844
2368
  heading
1845
2369
  }) => {
1846
2370
  if (!forcedLocation) return null;
1847
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2371
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1848
2372
  import_react_maplibre4.Marker,
1849
2373
  {
1850
2374
  anchor: "center",
1851
2375
  latitude: forcedLocation[1],
1852
2376
  longitude: forcedLocation[0],
1853
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2377
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1854
2378
  "div",
1855
2379
  {
1856
2380
  style: {
@@ -1860,7 +2384,7 @@ var UserLocationLayer = ({
1860
2384
  position: "relative"
1861
2385
  },
1862
2386
  children: [
1863
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2387
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1864
2388
  "div",
1865
2389
  {
1866
2390
  style: {
@@ -1873,7 +2397,7 @@ var UserLocationLayer = ({
1873
2397
  }
1874
2398
  }
1875
2399
  ),
1876
- heading !== void 0 && heading !== null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2400
+ heading !== void 0 && heading !== null && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1877
2401
  "div",
1878
2402
  {
1879
2403
  style: {
@@ -1883,13 +2407,13 @@ var UserLocationLayer = ({
1883
2407
  width: "60px",
1884
2408
  zIndex: 0
1885
2409
  },
1886
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2410
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1887
2411
  "svg",
1888
2412
  {
1889
2413
  style: { height: "100%", width: "100%" },
1890
2414
  viewBox: "0 0 100 100",
1891
2415
  children: [
1892
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2416
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1893
2417
  "radialGradient",
1894
2418
  {
1895
2419
  cx: "50%",
@@ -1899,7 +2423,7 @@ var UserLocationLayer = ({
1899
2423
  id: "grad1",
1900
2424
  r: "50%",
1901
2425
  children: [
1902
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2426
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1903
2427
  "stop",
1904
2428
  {
1905
2429
  offset: "0%",
@@ -1909,7 +2433,7 @@ var UserLocationLayer = ({
1909
2433
  }
1910
2434
  }
1911
2435
  ),
1912
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2436
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1913
2437
  "stop",
1914
2438
  {
1915
2439
  offset: "100%",
@@ -1922,7 +2446,7 @@ var UserLocationLayer = ({
1922
2446
  ]
1923
2447
  }
1924
2448
  ) }),
1925
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2449
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1926
2450
  "path",
1927
2451
  {
1928
2452
  d: "M 50 50 L 35 0 A 50 50 0 0 1 65 0 Z",
@@ -1934,7 +2458,7 @@ var UserLocationLayer = ({
1934
2458
  )
1935
2459
  }
1936
2460
  ),
1937
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2461
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1938
2462
  "div",
1939
2463
  {
1940
2464
  style: {
@@ -1948,7 +2472,7 @@ var UserLocationLayer = ({
1948
2472
  width: "20px",
1949
2473
  zIndex: 1
1950
2474
  },
1951
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2475
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1952
2476
  "div",
1953
2477
  {
1954
2478
  style: {
@@ -1962,7 +2486,7 @@ var UserLocationLayer = ({
1962
2486
  )
1963
2487
  }
1964
2488
  ),
1965
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: `@keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 70% { transform: scale(1.5); opacity: 0; } 100% { transform: scale(0.95); opacity: 0; } }` })
2489
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("style", { children: `@keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 70% { transform: scale(1.5); opacity: 0; } 100% { transform: scale(0.95); opacity: 0; } }` })
1966
2490
  ]
1967
2491
  }
1968
2492
  )
@@ -1971,7 +2495,7 @@ var UserLocationLayer = ({
1971
2495
  };
1972
2496
 
1973
2497
  // src/components/Map/Map.tsx
1974
- var import_jsx_runtime11 = require("react/jsx-runtime");
2498
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1975
2499
  var MapInternal = ({
1976
2500
  initialViewState = {
1977
2501
  latitude: 45.90583599233422,
@@ -2012,14 +2536,18 @@ var MapInternal = ({
2012
2536
  const mapRef = (0, import_react9.useRef)(null);
2013
2537
  const userLocationState = useUserLocation();
2014
2538
  const [progNav, setProgNav] = (0, import_react9.useState)(null);
2539
+ const [isAborted, setIsAborted] = (0, import_react9.useState)(false);
2015
2540
  (0, import_react9.useEffect)(() => {
2016
2541
  const unsubCreate = sdk.on("SDK_NAVIGATION_CREATE", (payload) => {
2542
+ setIsAborted(false);
2017
2543
  setProgNav(payload);
2018
2544
  });
2019
2545
  const unsubStart = sdk.on("SDK_NAVIGATION_START", () => {
2546
+ setIsAborted(false);
2020
2547
  setProgNav((prev) => prev ? { ...prev, mode: "navigation" } : null);
2021
2548
  });
2022
2549
  const unsubAbort = sdk.on("SDK_NAVIGATION_ABORT", () => {
2550
+ setIsAborted(true);
2023
2551
  setProgNav(null);
2024
2552
  });
2025
2553
  return () => {
@@ -2042,9 +2570,19 @@ var MapInternal = ({
2042
2570
  onNavigationModeChange(internalNav.mode);
2043
2571
  }
2044
2572
  }, [internalNav.mode, onNavigationModeChange, navigation]);
2045
- const navigationData = effectiveNavOptions ? internalNav : externalNavigationData;
2046
- const route = effectiveNavOptions ? internalNav.route?.geometry : externalRoute;
2047
- const showNavigationUI = effectiveNavOptions?.showUI !== false && (effectiveNavOptions ? !!effectiveNavOptions.destination : externalShowNavigationUI);
2573
+ const prevDest = (0, import_react9.useRef)(null);
2574
+ const currentDest = effectiveNavOptions?.destination;
2575
+ (0, import_react9.useEffect)(() => {
2576
+ if (currentDest) {
2577
+ if (!prevDest.current || prevDest.current[0] !== currentDest[0] || prevDest.current[1] !== currentDest[1]) {
2578
+ setIsAborted(false);
2579
+ }
2580
+ }
2581
+ prevDest.current = currentDest;
2582
+ }, [currentDest]);
2583
+ const navigationData = !isAborted ? effectiveNavOptions ? internalNav : externalNavigationData : void 0;
2584
+ const route = !isAborted ? effectiveNavOptions ? internalNav.route?.geometry : externalRoute : void 0;
2585
+ const showNavigationUI = !isAborted && effectiveNavOptions?.showUI !== false && (effectiveNavOptions ? !!effectiveNavOptions.destination : externalShowNavigationUI);
2048
2586
  const mode = navigationData?.mode || "preview";
2049
2587
  const resolvedInitialFollow = mapControls ? mapControls.isFollowing : initialFollowUser;
2050
2588
  const isFollowingRef = (0, import_react9.useRef)(resolvedInitialFollow);
@@ -2093,15 +2631,29 @@ var MapInternal = ({
2093
2631
  }
2094
2632
  }, [initialFollowUser, setFollowMode, userLocationState.coords]);
2095
2633
  const lastAutoLockedRouteRef = (0, import_react9.useRef)(null);
2634
+ const lastModeRef = (0, import_react9.useRef)(null);
2096
2635
  (0, import_react9.useEffect)(() => {
2097
2636
  if (!route || !mapRef.current) {
2098
2637
  if (!route) lastAutoLockedRouteRef.current = null;
2099
2638
  return;
2100
2639
  }
2101
2640
  const isNewRoute = route !== lastAutoLockedRouteRef.current;
2102
- if (!isNewRoute && mode === "navigation") return;
2641
+ const modeChanged = lastModeRef.current !== mode;
2103
2642
  if (mode === "navigation") {
2104
2643
  setFollowMode(true);
2644
+ if ((modeChanged || isNewRoute) && userLocationState.coords && mapRef.current) {
2645
+ isFlyingRef.current = true;
2646
+ mapRef.current.flyTo({
2647
+ center: userLocationState.coords,
2648
+ duration: 1e3,
2649
+ essential: true,
2650
+ zoom: 17
2651
+ // Zoomed in on user for active guidance
2652
+ });
2653
+ setTimeout(() => {
2654
+ isFlyingRef.current = false;
2655
+ }, 1050);
2656
+ }
2105
2657
  } else if (mode === "preview" && isNewRoute) {
2106
2658
  setFollowMode(false);
2107
2659
  const coords = route.coordinates;
@@ -2125,7 +2677,8 @@ var MapInternal = ({
2125
2677
  }
2126
2678
  }
2127
2679
  lastAutoLockedRouteRef.current = route;
2128
- }, [route, mode, setFollowMode]);
2680
+ lastModeRef.current = mode;
2681
+ }, [route, mode, setFollowMode, userLocationState.coords]);
2129
2682
  (0, import_react9.useEffect)(() => {
2130
2683
  if (isFollowingRef.current && !isFlyingRef.current && userLocationState.coords && mapRef.current) {
2131
2684
  mapRef.current.easeTo({
@@ -2141,33 +2694,33 @@ var MapInternal = ({
2141
2694
  route,
2142
2695
  showUserLocation ? userLocationState.coords : null
2143
2696
  );
2144
- const remainingMeters = navigationData?.currentDistanceMeters ?? navigationData?.route?.distanceMeters ?? 0;
2145
- const etaMins = navigationData?.route?.durationSeconds ? Math.ceil(navigationData.route.durationSeconds / 60) : 0;
2697
+ const currentDistMeters = navigationData?.currentDistanceMeters ?? null;
2698
+ const totalDist = navigationData?.totalDistance ?? null;
2699
+ const routeDurationSeconds = navigationData?.route?.durationSeconds ?? null;
2700
+ const remainingMeters = currentDistMeters ?? 0;
2701
+ const etaMins = (() => {
2702
+ if (!routeDurationSeconds || !totalDist || !currentDistMeters) return 0;
2703
+ const ratio = currentDistMeters / totalDist;
2704
+ return Math.ceil(routeDurationSeconds * ratio / 60);
2705
+ })();
2146
2706
  const kmRemaining = remainingMeters / 1e3;
2147
- const totalDist = navigationData?.totalDistance ?? 0;
2148
- const progressValue = totalDist > 0 ? (totalDist - remainingMeters) / totalDist * 100 : 0;
2149
- const showEtaData = (0, import_react9.useMemo)(() => {
2150
- if (!navigationData || !route) return void 0;
2151
- return {
2152
- distanceRemainingKm: kmRemaining,
2153
- etaMins,
2154
- label: mode === "navigation" ? "Walking Guidance Active" : "Route Preview",
2155
- mode,
2156
- onAbort: onNavigationAbort || (() => {
2157
- setProgNav(null);
2158
- }),
2159
- onStart: navigationData.start,
2160
- progress: progressValue
2161
- };
2162
- }, [
2163
- navigationData,
2164
- route,
2707
+ const progressValue = totalDist && totalDist > 0 ? Math.min(100, Math.max(0, (totalDist - remainingMeters) / totalDist * 100)) : 0;
2708
+ const showEtaData = navigationData && route ? {
2709
+ distanceRemainingKm: kmRemaining,
2165
2710
  etaMins,
2166
- kmRemaining,
2711
+ label: mode === "navigation" ? "Walking Guidance Active" : "Route Preview",
2167
2712
  mode,
2168
- progressValue,
2169
- onNavigationAbort
2170
- ]);
2713
+ onAbort: () => {
2714
+ setIsAborted(true);
2715
+ setProgNav(null);
2716
+ sdk.navigation.abort();
2717
+ if (onNavigationAbort) {
2718
+ onNavigationAbort();
2719
+ }
2720
+ },
2721
+ onStart: navigationData.start,
2722
+ progress: progressValue
2723
+ } : void 0;
2171
2724
  const setEtaDataCtx = mapControls?.setEtaData;
2172
2725
  (0, import_react9.useEffect)(() => {
2173
2726
  if (setEtaDataCtx) {
@@ -2183,7 +2736,7 @@ var MapInternal = ({
2183
2736
  const defaultMenuItems = (0, import_react9.useMemo)(
2184
2737
  () => [
2185
2738
  {
2186
- icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2739
+ icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2187
2740
  "svg",
2188
2741
  {
2189
2742
  className: "w-5 h-5",
@@ -2191,7 +2744,7 @@ var MapInternal = ({
2191
2744
  stroke: "currentColor",
2192
2745
  strokeWidth: "2",
2193
2746
  viewBox: "0 0 24 24",
2194
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2747
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2195
2748
  "path",
2196
2749
  {
2197
2750
  d: "M12 11c0 3.517-1.009 6.799-2.753 9.571m-3.44-2.04l.054-.09A13.916 13.916 0 008 11a4 4 0 118 0c0 1.017-.07 2.019-.203 3m-2.118 6.844A21.88 21.88 0 0015.171 17m3.839 1.132c.645-2.266.99-4.659.99-7.132A8 8 0 008 4.07M3 15.364c.64-1.319 1-2.8 1-4.364 0-1.457.39-2.823 1.07-4",
@@ -2242,7 +2795,7 @@ var MapInternal = ({
2242
2795
  mapLibreChildren2.push(child);
2243
2796
  }
2244
2797
  });
2245
- const menuContentFromChildren2 = extractedMenuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MapMenu, { children: extractedMenuItems }) : null;
2798
+ const menuContentFromChildren2 = extractedMenuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MapMenu, { children: extractedMenuItems }) : null;
2246
2799
  return { mapLibreChildren: mapLibreChildren2, menuContentFromChildren: menuContentFromChildren2 };
2247
2800
  }, [children]);
2248
2801
  const handleMapClick = (e) => {
@@ -2316,13 +2869,13 @@ var MapInternal = ({
2316
2869
  }
2317
2870
  }
2318
2871
  };
2319
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2872
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2320
2873
  "div",
2321
2874
  {
2322
2875
  className: `w-full h-full overflow-hidden relative ${className}`,
2323
2876
  style,
2324
2877
  children: [
2325
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2878
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2326
2879
  import_react_maplibre5.Map,
2327
2880
  {
2328
2881
  attributionControl: false,
@@ -2351,23 +2904,23 @@ var MapInternal = ({
2351
2904
  showUserLocation && userLocationState.coords && (renderUserLocation ? renderUserLocation({
2352
2905
  coords: userLocationState.coords,
2353
2906
  heading: userLocationState.heading
2354
- }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2907
+ }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2355
2908
  UserLocationLayer,
2356
2909
  {
2357
2910
  forcedLocation: userLocationState.coords,
2358
2911
  heading: userLocationState.heading
2359
2912
  }
2360
2913
  )),
2361
- displayRoute && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RouteLayer, { geometry: displayRoute }),
2362
- pois.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2363
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(POILayers, { pois }),
2364
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(POIMarkers, { onClick: onPoiClick, pois })
2914
+ displayRoute && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RouteLayer, { geometry: displayRoute }),
2915
+ pois.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
2916
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(POILayers, { pois }),
2917
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(POIMarkers, { onClick: onPoiClick, pois })
2365
2918
  ] }),
2366
2919
  mapLibreChildren
2367
2920
  ]
2368
2921
  }
2369
2922
  ),
2370
- showControls && mapControls && !mapControls.hasControls && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2923
+ showControls && mapControls && !mapControls.hasControls && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2371
2924
  MapControls,
2372
2925
  {
2373
2926
  drawerContentRef,
@@ -2389,12 +2942,12 @@ var SDKMapProviderWrapper = ({
2389
2942
  }) => {
2390
2943
  const context = (0, import_react9.useContext)(MapControlsContext);
2391
2944
  if (context) {
2392
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children });
2945
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children });
2393
2946
  }
2394
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SDKMapProvider, { children });
2947
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SDKMapProvider, { children });
2395
2948
  };
2396
2949
  var Map2 = (props) => {
2397
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SDKMapProviderWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_maplibre5.MapProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MapInternal, { ...props }) }) });
2950
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SDKMapProviderWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_maplibre5.MapProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MapInternal, { ...props }) }) });
2398
2951
  };
2399
2952
 
2400
2953
  // src/components/MapWrapper.tsx
@@ -2591,7 +3144,7 @@ var RoutingService = {
2591
3144
  };
2592
3145
 
2593
3146
  // package.json
2594
- var version = "0.2.0";
3147
+ var version = "0.2.2";
2595
3148
 
2596
3149
  // src/sdk.ts
2597
3150
  function deepFreeze(obj) {
@@ -2924,7 +3477,7 @@ var sdk = deepFreeze(new MiniAppSDK());
2924
3477
 
2925
3478
  // src/components/BridgeMocker.tsx
2926
3479
  var import_react11 = require("react");
2927
- var import_jsx_runtime12 = require("react/jsx-runtime");
3480
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2928
3481
  var getBearing = (p1, p2) => {
2929
3482
  const lat1 = p1[1] * Math.PI / 180;
2930
3483
  const lat2 = p2[1] * Math.PI / 180;
@@ -3216,16 +3769,17 @@ var BridgeMocker = ({
3216
3769
  };
3217
3770
  }, [appId]);
3218
3771
  if (!isReady) return null;
3219
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative w-full h-full", children: [
3220
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w-full h-full", children }),
3221
- isMinimized ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3222
- "button",
3772
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "relative w-full h-full", children: [
3773
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "w-full h-full", children }),
3774
+ isMinimized ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3775
+ Button,
3223
3776
  {
3224
- className: "fixed bottom-4 right-4 w-8 h-8 rounded-full bg-slate-900/60 backdrop-blur-sm border border-slate-700/50 flex items-center justify-center text-slate-400 hover:text-blue-400 z-[9999] transition-all shadow-lg group",
3777
+ className: "fixed bottom-4 right-4 w-8 h-8 rounded-full bg-slate-900/60 backdrop-blur-sm border border-slate-700/50 flex items-center justify-center text-slate-400 hover:text-blue-400 hover:bg-slate-900/80 z-[9999] transition-all shadow-lg group p-0!",
3225
3778
  onClick: () => setIsMinimized(false),
3226
3779
  title: "Open Simulation Controls",
3227
3780
  type: "button",
3228
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3781
+ variant: "ghost",
3782
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3229
3783
  "svg",
3230
3784
  {
3231
3785
  className: "group-hover:scale-110 transition-transform",
@@ -3239,41 +3793,49 @@ var BridgeMocker = ({
3239
3793
  width: "14",
3240
3794
  xmlns: "http://www.w3.org/2000/svg",
3241
3795
  children: [
3242
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M21 4H3" }),
3243
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M10 8H3" }),
3244
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M21 12H3" }),
3245
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M10 16H3" }),
3246
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M21 20H3" }),
3247
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "14", cy: "8", r: "2" }),
3248
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "14", cy: "16", r: "2" })
3796
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M21 4H3" }),
3797
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M10 8H3" }),
3798
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M21 12H3" }),
3799
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M10 16H3" }),
3800
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M21 20H3" }),
3801
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("circle", { cx: "14", cy: "8", r: "2" }),
3802
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("circle", { cx: "14", cy: "16", r: "2" })
3249
3803
  ]
3250
3804
  }
3251
3805
  )
3252
3806
  }
3253
- ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3807
+ ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3254
3808
  "div",
3255
3809
  {
3256
3810
  className: "fixed bottom-4 right-4 bg-slate-900 text-slate-300 font-mono text-xs rounded-xl shadow-2xl border border-slate-700 pointer-events-auto flex flex-col w-80 overflow-hidden animate-in slide-in-from-right duration-300",
3257
3811
  style: { zIndex: 9998 },
3258
3812
  children: [
3259
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3813
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3260
3814
  "div",
3261
3815
  {
3262
3816
  className: "flex justify-between items-center p-3 border-b border-slate-800 cursor-pointer bg-slate-800/50 hover:bg-slate-800 transition-colors",
3263
3817
  onClick: () => setIsMinimized(true),
3264
3818
  children: [
3265
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "font-bold text-slate-100 flex items-center gap-2", children: [
3266
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-lg", children: "\u{1F6E0}\uFE0F" }),
3819
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "font-bold text-slate-100 flex items-center gap-2", children: [
3820
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-lg", children: "\u{1F6E0}\uFE0F" }),
3267
3821
  " Simulation Controls"
3268
3822
  ] }),
3269
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { className: "text-slate-500 hover:text-white", type: "button", children: "\u25BC" })
3823
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3824
+ Button,
3825
+ {
3826
+ className: "text-slate-500 hover:text-white p-0 h-auto hover:bg-transparent cursor-pointer",
3827
+ type: "button",
3828
+ variant: "ghost",
3829
+ children: "\u25BC"
3830
+ }
3831
+ )
3270
3832
  ]
3271
3833
  }
3272
3834
  ),
3273
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "p-4 flex flex-col gap-3", children: [
3274
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex justify-between items-center", children: [
3275
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer", children: [
3276
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3835
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "p-4 flex flex-col gap-3", children: [
3836
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex justify-between items-center", children: [
3837
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer", children: [
3838
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3277
3839
  "input",
3278
3840
  {
3279
3841
  checked: autoMove,
@@ -3282,20 +3844,20 @@ var BridgeMocker = ({
3282
3844
  type: "checkbox"
3283
3845
  }
3284
3846
  ),
3285
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "text-slate-200 font-bold", children: [
3847
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "text-slate-200 font-bold", children: [
3286
3848
  "Auto-Move ",
3287
3849
  simulationPath ? "(Path)" : "(Random)"
3288
3850
  ] })
3289
3851
  ] }),
3290
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2", children: [
3291
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-[10px] text-slate-500", children: "Speed:" }),
3292
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3852
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2", children: [
3853
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[10px] text-slate-500", children: "Speed:" }),
3854
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3293
3855
  "select",
3294
3856
  {
3295
3857
  className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5 text-white focus:outline-none focus:border-blue-500 text-[10px]",
3296
3858
  onChange: (e) => setSpeedMultiplier(Number(e.target.value)),
3297
3859
  value: speedMultiplier,
3298
- children: [1, 2, 5, 10, 50, 100, 250].map((s) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("option", { value: s, children: [
3860
+ children: [1, 2, 5, 10, 50, 100, 250].map((s) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("option", { value: s, children: [
3299
3861
  s,
3300
3862
  "x"
3301
3863
  ] }, s))
@@ -3303,10 +3865,10 @@ var BridgeMocker = ({
3303
3865
  )
3304
3866
  ] })
3305
3867
  ] }),
3306
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
3307
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1", children: [
3308
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lng" }),
3309
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3868
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
3869
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", children: [
3870
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lng" }),
3871
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3310
3872
  "input",
3311
3873
  {
3312
3874
  className: "bg-slate-800 border border-slate-700 rounded px-2 py-1 text-white focus:outline-none focus:border-blue-500",
@@ -3321,9 +3883,9 @@ var BridgeMocker = ({
3321
3883
  }
3322
3884
  )
3323
3885
  ] }),
3324
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1", children: [
3325
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lat" }),
3326
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3886
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", children: [
3887
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lat" }),
3888
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3327
3889
  "input",
3328
3890
  {
3329
3891
  className: "bg-slate-800 border border-slate-700 rounded px-2 py-1 text-white focus:outline-none focus:border-blue-500",
@@ -3338,9 +3900,9 @@ var BridgeMocker = ({
3338
3900
  }
3339
3901
  )
3340
3902
  ] }),
3341
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1 col-span-2", children: [
3342
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-[10px] text-slate-500", children: "Heading (Degrees)" }),
3343
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3903
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1 col-span-2", children: [
3904
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[10px] text-slate-500", children: "Heading (Degrees)" }),
3905
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3344
3906
  "input",
3345
3907
  {
3346
3908
  className: "w-full accent-blue-500",
@@ -3354,7 +3916,7 @@ var BridgeMocker = ({
3354
3916
  value: heading
3355
3917
  }
3356
3918
  ),
3357
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "text-right text-slate-400", children: [
3919
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "text-right text-slate-400", children: [
3358
3920
  heading,
3359
3921
  "\xB0"
3360
3922
  ] })
@@ -3369,7 +3931,7 @@ var BridgeMocker = ({
3369
3931
 
3370
3932
  // src/components/DebugConsole.tsx
3371
3933
  var import_react12 = require("react");
3372
- var import_jsx_runtime13 = require("react/jsx-runtime");
3934
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3373
3935
  var DebugConsole = ({
3374
3936
  isOpen: initialOpen = false,
3375
3937
  onClose
@@ -3413,14 +3975,15 @@ var DebugConsole = ({
3413
3975
  };
3414
3976
  }, [addLog]);
3415
3977
  if (!showConsole) {
3416
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3417
- "button",
3978
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3979
+ Button,
3418
3980
  {
3419
- className: "fixed bottom-4 left-4 w-8 h-8 rounded-full bg-slate-900/60 backdrop-blur-sm border border-slate-700/50 flex items-center justify-center text-slate-400 hover:text-emerald-400 transition-all z-[9998] shadow-lg group",
3981
+ className: "fixed bottom-4 left-4 w-8 h-8 rounded-full bg-slate-900/60 backdrop-blur-sm border border-slate-700/50 flex items-center justify-center text-slate-400 hover:text-emerald-400 hover:bg-slate-900/80 transition-all z-[9998] shadow-lg group p-0!",
3420
3982
  onClick: () => setShowConsole(true),
3421
3983
  title: "Open Debug Console",
3422
3984
  type: "button",
3423
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3985
+ variant: "ghost",
3986
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3424
3987
  "svg",
3425
3988
  {
3426
3989
  className: "group-hover:scale-110 transition-transform",
@@ -3434,68 +3997,70 @@ var DebugConsole = ({
3434
3997
  width: "14",
3435
3998
  xmlns: "http://www.w3.org/2000/svg",
3436
3999
  children: [
3437
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m8 2 1.88 1.88" }),
3438
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M14.12 3.88 16 2" }),
3439
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" }),
3440
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6" }),
3441
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 20v-9" }),
3442
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5" }),
3443
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M6 13H2" }),
3444
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4" }),
3445
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4" }),
3446
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M22 13h-4" }),
3447
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4" })
4000
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "m8 2 1.88 1.88" }),
4001
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M14.12 3.88 16 2" }),
4002
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" }),
4003
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6" }),
4004
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M12 20v-9" }),
4005
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5" }),
4006
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M6 13H2" }),
4007
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4" }),
4008
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4" }),
4009
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M22 13h-4" }),
4010
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4" })
3448
4011
  ]
3449
4012
  }
3450
4013
  )
3451
4014
  }
3452
4015
  );
3453
4016
  }
3454
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "fixed inset-x-0 bottom-0 w-full bg-[#0a080f] border-t border-slate-800 z-[9998] p-4 shadow-2xl flex flex-col animate-in slide-in-from-bottom duration-300", children: [
3455
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
3456
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-slate-400 flex items-center gap-2", children: [
3457
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
4017
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "fixed inset-x-0 bottom-0 w-full bg-[#0a080f] border-t border-slate-800 z-[9998] p-4 shadow-2xl flex flex-col animate-in slide-in-from-bottom duration-300", children: [
4018
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
4019
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-slate-400 flex items-center gap-2", children: [
4020
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
3458
4021
  "UP SDK Debug Console"
3459
4022
  ] }),
3460
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-4", children: [
3461
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3462
- "button",
4023
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-4", children: [
4024
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4025
+ Button,
3463
4026
  {
3464
- className: "text-[10px] text-slate-500 font-bold uppercase hover:text-slate-300 transition-colors",
4027
+ className: "text-[10px] text-slate-500 font-bold uppercase hover:text-slate-300 hover:bg-transparent transition-colors p-0 h-auto cursor-pointer",
3465
4028
  onClick: clearLogs,
3466
4029
  type: "button",
4030
+ variant: "ghost",
3467
4031
  children: "Clear"
3468
4032
  }
3469
4033
  ),
3470
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3471
- "button",
4034
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4035
+ Button,
3472
4036
  {
3473
- className: "text-[10px] text-pink-500 font-bold uppercase hover:underline transition-colors",
4037
+ className: "text-[10px] text-pink-500 font-bold uppercase hover:text-pink-400 hover:bg-transparent transition-colors p-0 h-auto cursor-pointer",
3474
4038
  onClick: () => {
3475
4039
  setShowConsole(false);
3476
4040
  if (onClose) onClose();
3477
4041
  },
3478
4042
  type: "button",
4043
+ variant: "ghost",
3479
4044
  children: "Close"
3480
4045
  }
3481
4046
  )
3482
4047
  ] })
3483
4048
  ] }),
3484
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4049
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3485
4050
  "div",
3486
4051
  {
3487
4052
  className: "bg-black/80 rounded-xl p-3 font-mono text-[10px] text-emerald-400 min-h-[120px] max-h-[240px] overflow-y-auto border border-slate-900 custom-scrollbar",
3488
4053
  ref: scrollRef,
3489
- children: logs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-slate-600 italic text-center py-8", children: "No logs yet. Interacting with the SDK will show events here." }) : logs.map((log) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4054
+ children: logs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "text-slate-600 italic text-center py-8", children: "No logs yet. Interacting with the SDK will show events here." }) : logs.map((log) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3490
4055
  "div",
3491
4056
  {
3492
4057
  className: "mb-3 pb-3 border-b border-slate-900/50 last:border-0 last:mb-0 last:pb-0",
3493
4058
  children: [
3494
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-2 text-slate-500 mb-1 items-center", children: [
3495
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-[8px]", children: log.time }),
3496
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-bold text-white uppercase text-[8px] bg-slate-800 px-1.5 py-0.5 rounded leading-none", children: log.label })
4059
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-2 text-slate-500 mb-1 items-center", children: [
4060
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[8px]", children: log.time }),
4061
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-bold text-white uppercase text-[8px] bg-slate-800 px-1.5 py-0.5 rounded leading-none", children: log.label })
3497
4062
  ] }),
3498
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("pre", { className: "whitespace-pre-wrap break-all opacity-90", children: log.content })
4063
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("pre", { className: "whitespace-pre-wrap break-all opacity-90", children: log.content })
3499
4064
  ]
3500
4065
  },
3501
4066
  log.id
@@ -3507,7 +4072,7 @@ var DebugConsole = ({
3507
4072
 
3508
4073
  // src/components/SDKProvider.tsx
3509
4074
  var import_react13 = require("react");
3510
- var import_jsx_runtime14 = require("react/jsx-runtime");
4075
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3511
4076
  var SDKContext = (0, import_react13.createContext)({ isMocked: false });
3512
4077
  var useIsMocked = () => (0, import_react13.useContext)(SDKContext).isMocked;
3513
4078
  var SDKProvider = ({
@@ -3517,14 +4082,14 @@ var SDKProvider = ({
3517
4082
  }) => {
3518
4083
  const isMocked = typeof window !== "undefined" && !(window.__UP_REACT_NATIVE_APP__ === true || !!window.ReactNativeWebView);
3519
4084
  const value = (0, import_react13.useMemo)(() => ({ isMocked }), [isMocked]);
3520
- const content = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
4085
+ const content = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3521
4086
  children,
3522
- debug && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DebugConsole, {})
4087
+ debug && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DebugConsole, {})
3523
4088
  ] });
3524
4089
  if (isMocked) {
3525
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SDKContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BridgeMocker, { ...mockerProps, children: content }) });
4090
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SDKContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BridgeMocker, { ...mockerProps, children: content }) });
3526
4091
  }
3527
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SDKContext.Provider, { value, children: content });
4092
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SDKContext.Provider, { value, children: content });
3528
4093
  };
3529
4094
 
3530
4095
  // src/host/routingHandler.ts