@almadar/ui 5.13.2 → 5.14.0

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.
@@ -6260,7 +6260,7 @@ var init_Modal = __esm({
6260
6260
  document.body.style.overflow = "";
6261
6261
  };
6262
6262
  }, [isOpen]);
6263
- if (!isOpen) return null;
6263
+ if (!isOpen || typeof document === "undefined") return null;
6264
6264
  const handleClose = () => {
6265
6265
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
6266
6266
  onClose();
@@ -6270,124 +6270,127 @@ var init_Modal = __esm({
6270
6270
  handleClose();
6271
6271
  }
6272
6272
  };
6273
- return /* @__PURE__ */ jsxs(Fragment, { children: [
6274
- /* @__PURE__ */ jsx(
6275
- Overlay,
6276
- {
6277
- isVisible: isOpen,
6278
- onClick: handleOverlayClick,
6279
- className: "z-40"
6280
- }
6281
- ),
6282
- /* @__PURE__ */ jsx(
6283
- Box,
6284
- {
6285
- className: cn(
6286
- "fixed inset-0 z-50 pointer-events-none",
6287
- "flex items-start justify-center px-4 pb-4 pt-[10vh]",
6288
- "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
6289
- ),
6290
- children: /* @__PURE__ */ jsxs(
6291
- Dialog,
6292
- {
6293
- ref: modalRef,
6294
- open: true,
6295
- className: cn(
6296
- // Reset browser-default dialog chrome — we own styling. `static`
6297
- // overrides the user-agent `position: absolute` so the parent
6298
- // flex container's `justify-center` actually centers the dialog
6299
- // (without this, the dialog drops out of flex flow and `m-0`
6300
- // kills the user-agent's `margin: auto` centering, pinning the
6301
- // dialog to top-left).
6302
- "static m-0 p-0 border-0 bg-transparent",
6303
- // Pre-existing dialog frame
6304
- "pointer-events-auto w-full flex flex-col bg-surface border shadow-elevation-dialog rounded-container",
6305
- // Desktop sizing + viewport-aware floor.
6306
- sizeClasses5[size],
6307
- minWidthClasses[size],
6308
- "max-h-[80vh]",
6309
- // Mobile: take the entire screen. Override desktop max-w cap,
6310
- // full height, no rounded corners, no min-width.
6311
- "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
6312
- lookStyles2[look],
6313
- className
6314
- ),
6315
- style: dragY > 0 ? {
6316
- transform: `translateY(${dragY}px)`,
6317
- transition: isDragging.current ? "none" : "transform 200ms ease-out"
6318
- } : void 0,
6319
- ...title && { "aria-labelledby": "modal-title" },
6320
- children: [
6321
- /* @__PURE__ */ jsx(
6322
- Box,
6323
- {
6324
- className: "hidden max-sm:flex justify-center py-2 cursor-grab active:cursor-grabbing touch-none",
6325
- onPointerDown: (e) => {
6326
- if (!swipeDownToClose) return;
6327
- dragStartY.current = e.clientY;
6328
- isDragging.current = true;
6329
- e.target.setPointerCapture(e.pointerId);
6330
- },
6331
- onPointerMove: (e) => {
6332
- if (!isDragging.current) return;
6333
- const dy = Math.max(0, e.clientY - dragStartY.current);
6334
- setDragY(dy);
6335
- },
6336
- onPointerUp: () => {
6337
- if (!isDragging.current) return;
6338
- isDragging.current = false;
6339
- if (dragY > 100) {
6340
- handleClose();
6341
- }
6342
- setDragY(0);
6343
- },
6344
- onPointerCancel: () => {
6345
- isDragging.current = false;
6346
- setDragY(0);
6347
- },
6348
- children: /* @__PURE__ */ jsx(Box, { className: "w-10 h-1 rounded-full bg-border" })
6349
- }
6273
+ return createPortal(
6274
+ /* @__PURE__ */ jsxs(Fragment, { children: [
6275
+ /* @__PURE__ */ jsx(
6276
+ Overlay,
6277
+ {
6278
+ isVisible: isOpen,
6279
+ onClick: handleOverlayClick,
6280
+ className: "z-[1000]"
6281
+ }
6282
+ ),
6283
+ /* @__PURE__ */ jsx(
6284
+ Box,
6285
+ {
6286
+ className: cn(
6287
+ "fixed inset-0 z-[1001] pointer-events-none",
6288
+ "flex items-start justify-center px-4 pb-4 pt-[10vh]",
6289
+ "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
6290
+ ),
6291
+ children: /* @__PURE__ */ jsxs(
6292
+ Dialog,
6293
+ {
6294
+ ref: modalRef,
6295
+ open: true,
6296
+ className: cn(
6297
+ // Reset browser-default dialog chrome we own styling. `static`
6298
+ // overrides the user-agent `position: absolute` so the parent
6299
+ // flex container's `justify-center` actually centers the dialog
6300
+ // (without this, the dialog drops out of flex flow and `m-0`
6301
+ // kills the user-agent's `margin: auto` centering, pinning the
6302
+ // dialog to top-left).
6303
+ "static m-0 p-0 border-0 bg-transparent",
6304
+ // Pre-existing dialog frame
6305
+ "pointer-events-auto w-full flex flex-col bg-surface border shadow-elevation-dialog rounded-container",
6306
+ // Desktop sizing + viewport-aware floor.
6307
+ sizeClasses5[size],
6308
+ minWidthClasses[size],
6309
+ "max-h-[80vh]",
6310
+ // Mobile: take the entire screen. Override desktop max-w cap,
6311
+ // full height, no rounded corners, no min-width.
6312
+ "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
6313
+ lookStyles2[look],
6314
+ className
6350
6315
  ),
6351
- (title || showCloseButton) && /* @__PURE__ */ jsxs(
6352
- Box,
6353
- {
6354
- className: cn(
6355
- "px-6 py-4 flex items-center justify-between",
6356
- "border-b-[length:var(--border-width)] border-border"
6357
- ),
6358
- children: [
6359
- title && /* @__PURE__ */ jsx(Typography, { variant: "h4", as: "h2", id: "modal-title", children: title }),
6360
- showCloseButton && /* @__PURE__ */ jsx(
6361
- Button,
6362
- {
6363
- variant: "ghost",
6364
- size: "sm",
6365
- icon: "x",
6366
- onClick: handleClose,
6367
- "data-event": "CLOSE",
6368
- "aria-label": "Close modal"
6316
+ style: dragY > 0 ? {
6317
+ transform: `translateY(${dragY}px)`,
6318
+ transition: isDragging.current ? "none" : "transform 200ms ease-out"
6319
+ } : void 0,
6320
+ ...title && { "aria-labelledby": "modal-title" },
6321
+ children: [
6322
+ /* @__PURE__ */ jsx(
6323
+ Box,
6324
+ {
6325
+ className: "hidden max-sm:flex justify-center py-2 cursor-grab active:cursor-grabbing touch-none",
6326
+ onPointerDown: (e) => {
6327
+ if (!swipeDownToClose) return;
6328
+ dragStartY.current = e.clientY;
6329
+ isDragging.current = true;
6330
+ e.target.setPointerCapture(e.pointerId);
6331
+ },
6332
+ onPointerMove: (e) => {
6333
+ if (!isDragging.current) return;
6334
+ const dy = Math.max(0, e.clientY - dragStartY.current);
6335
+ setDragY(dy);
6336
+ },
6337
+ onPointerUp: () => {
6338
+ if (!isDragging.current) return;
6339
+ isDragging.current = false;
6340
+ if (dragY > 100) {
6341
+ handleClose();
6369
6342
  }
6370
- )
6371
- ]
6372
- }
6373
- ),
6374
- /* @__PURE__ */ jsx(Box, { className: "flex-1 overflow-y-auto p-6", children }),
6375
- footer && /* @__PURE__ */ jsx(
6376
- Box,
6377
- {
6378
- className: cn(
6379
- "px-6 py-4 bg-muted",
6380
- "border-t-[length:var(--border-width)] border-border"
6381
- ),
6382
- children: footer
6383
- }
6384
- )
6385
- ]
6386
- }
6387
- )
6388
- }
6389
- )
6390
- ] });
6343
+ setDragY(0);
6344
+ },
6345
+ onPointerCancel: () => {
6346
+ isDragging.current = false;
6347
+ setDragY(0);
6348
+ },
6349
+ children: /* @__PURE__ */ jsx(Box, { className: "w-10 h-1 rounded-full bg-border" })
6350
+ }
6351
+ ),
6352
+ (title || showCloseButton) && /* @__PURE__ */ jsxs(
6353
+ Box,
6354
+ {
6355
+ className: cn(
6356
+ "px-6 py-4 flex items-center justify-between",
6357
+ "border-b-[length:var(--border-width)] border-border"
6358
+ ),
6359
+ children: [
6360
+ title && /* @__PURE__ */ jsx(Typography, { variant: "h4", as: "h2", id: "modal-title", children: title }),
6361
+ showCloseButton && /* @__PURE__ */ jsx(
6362
+ Button,
6363
+ {
6364
+ variant: "ghost",
6365
+ size: "sm",
6366
+ icon: "x",
6367
+ onClick: handleClose,
6368
+ "data-event": "CLOSE",
6369
+ "aria-label": "Close modal"
6370
+ }
6371
+ )
6372
+ ]
6373
+ }
6374
+ ),
6375
+ /* @__PURE__ */ jsx(Box, { className: "flex-1 overflow-y-auto p-6", children }),
6376
+ footer && /* @__PURE__ */ jsx(
6377
+ Box,
6378
+ {
6379
+ className: cn(
6380
+ "px-6 py-4 bg-muted",
6381
+ "border-t-[length:var(--border-width)] border-border"
6382
+ ),
6383
+ children: footer
6384
+ }
6385
+ )
6386
+ ]
6387
+ }
6388
+ )
6389
+ }
6390
+ )
6391
+ ] }),
6392
+ document.body
6393
+ );
6391
6394
  };
6392
6395
  Modal.displayName = "Modal";
6393
6396
  }
@@ -8627,13 +8630,13 @@ var init_MapView = __esm({
8627
8630
  shadowSize: [41, 41]
8628
8631
  });
8629
8632
  L.Marker.prototype.options.icon = defaultIcon;
8630
- const { useEffect: useEffect72, useRef: useRef66, useCallback: useCallback128, useState: useState111 } = React80__default;
8633
+ const { useEffect: useEffect73, useRef: useRef67, useCallback: useCallback129, useState: useState112 } = React80__default;
8631
8634
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
8632
8635
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
8633
8636
  function MapUpdater({ centerLat, centerLng, zoom }) {
8634
8637
  const map = useMap();
8635
- const prevRef = useRef66({ centerLat, centerLng, zoom });
8636
- useEffect72(() => {
8638
+ const prevRef = useRef67({ centerLat, centerLng, zoom });
8639
+ useEffect73(() => {
8637
8640
  const prev = prevRef.current;
8638
8641
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
8639
8642
  map.setView([centerLat, centerLng], zoom);
@@ -8644,7 +8647,7 @@ var init_MapView = __esm({
8644
8647
  }
8645
8648
  function MapClickHandler({ onMapClick }) {
8646
8649
  const map = useMap();
8647
- useEffect72(() => {
8650
+ useEffect73(() => {
8648
8651
  if (!onMapClick) return;
8649
8652
  const handler = (e) => {
8650
8653
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -8672,8 +8675,8 @@ var init_MapView = __esm({
8672
8675
  showAttribution = true
8673
8676
  }) {
8674
8677
  const eventBus = useEventBus2();
8675
- const [clickedPosition, setClickedPosition] = useState111(null);
8676
- const handleMapClick = useCallback128((lat, lng) => {
8678
+ const [clickedPosition, setClickedPosition] = useState112(null);
8679
+ const handleMapClick = useCallback129((lat, lng) => {
8677
8680
  if (showClickedPin) {
8678
8681
  setClickedPosition({ lat, lng });
8679
8682
  }
@@ -8682,7 +8685,7 @@ var init_MapView = __esm({
8682
8685
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
8683
8686
  }
8684
8687
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
8685
- const handleMarkerClick = useCallback128((marker) => {
8688
+ const handleMarkerClick = useCallback129((marker) => {
8686
8689
  onMarkerClick?.(marker);
8687
8690
  if (markerClickEvent) {
8688
8691
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -12439,7 +12442,7 @@ var init_CodeBlock = __esm({
12439
12442
  };
12440
12443
  };
12441
12444
  }, [errorLines]);
12442
- const isFoldable = foldableProp ?? (language === "orb" || language === "json");
12445
+ const isFoldable = foldableProp ?? true;
12443
12446
  const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
12444
12447
  const foldRegions = useMemo(
12445
12448
  () => isFoldable ? computeFoldRegions(code) : [],
@@ -12462,6 +12465,8 @@ var init_CodeBlock = __esm({
12462
12465
  collapsedRef.current = collapsed;
12463
12466
  const foldStartMapRef = useRef(foldStartMap);
12464
12467
  foldStartMapRef.current = foldStartMap;
12468
+ const hiddenLinesRef = useRef(hiddenLines);
12469
+ hiddenLinesRef.current = hiddenLines;
12465
12470
  const toggleFold = useCallback((lineNum) => {
12466
12471
  setCollapsed((prev) => {
12467
12472
  const next = new Set(prev);
@@ -12574,6 +12579,60 @@ var init_CodeBlock = __esm({
12574
12579
  eventBus.emit("UI:COPY_CODE", { language, success: false });
12575
12580
  }
12576
12581
  };
12582
+ const handleSelectionCopy = useCallback((e) => {
12583
+ if (hiddenLinesRef.current.size === 0) return;
12584
+ const sel = typeof window !== "undefined" ? window.getSelection() : null;
12585
+ if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return;
12586
+ const lineOf = (node) => {
12587
+ const start = node instanceof HTMLElement ? node : node?.parentElement ?? null;
12588
+ const lineEl = start?.closest("[data-line]");
12589
+ if (!lineEl) return null;
12590
+ const n = parseInt(lineEl.getAttribute("data-line") ?? "", 10);
12591
+ return Number.isNaN(n) ? null : n;
12592
+ };
12593
+ const range = sel.getRangeAt(0);
12594
+ let a = lineOf(range.startContainer);
12595
+ let b = lineOf(range.endContainer);
12596
+ if (a === null || b === null) {
12597
+ const container = codeRef.current;
12598
+ if (!container) return;
12599
+ let min = Infinity, max = -Infinity;
12600
+ container.querySelectorAll("[data-line]").forEach((el) => {
12601
+ if (!sel.containsNode(el, true)) return;
12602
+ const n = parseInt(el.getAttribute("data-line") ?? "", 10);
12603
+ if (!Number.isNaN(n)) {
12604
+ min = Math.min(min, n);
12605
+ max = Math.max(max, n);
12606
+ }
12607
+ });
12608
+ if (min === Infinity) return;
12609
+ a = a ?? min;
12610
+ b = b ?? max;
12611
+ }
12612
+ if (a > b) [a, b] = [b, a];
12613
+ let touchesFold = false;
12614
+ for (let i = a; i <= b; i++) {
12615
+ if (hiddenLinesRef.current.has(i) || foldStartMapRef.current.has(i) && collapsedRef.current.has(i)) {
12616
+ touchesFold = true;
12617
+ break;
12618
+ }
12619
+ }
12620
+ if (!touchesFold) return;
12621
+ let endLine = b;
12622
+ let changed = true;
12623
+ while (changed) {
12624
+ changed = false;
12625
+ foldStartMapRef.current.forEach((region, start) => {
12626
+ if (start >= a && start <= endLine && collapsedRef.current.has(start) && region.end > endLine) {
12627
+ endLine = region.end;
12628
+ changed = true;
12629
+ }
12630
+ });
12631
+ }
12632
+ const full = code.split("\n").slice(a, endLine + 1).join("\n");
12633
+ e.clipboardData.setData("text/plain", full);
12634
+ e.preventDefault();
12635
+ }, [code]);
12577
12636
  const hasHeader = showLanguageBadge || showCopyButton;
12578
12637
  return /* @__PURE__ */ jsxs(Box, { className: `relative group ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
12579
12638
  hasHeader && /* @__PURE__ */ jsxs(
@@ -12724,6 +12783,7 @@ var init_CodeBlock = __esm({
12724
12783
  "div",
12725
12784
  {
12726
12785
  ref: scrollRef,
12786
+ onCopy: handleSelectionCopy,
12727
12787
  style: {
12728
12788
  flex: 1,
12729
12789
  minHeight: 0,
@@ -23783,6 +23843,242 @@ var init_InputGroup = __esm({
23783
23843
  InputGroup.displayName = "InputGroup";
23784
23844
  }
23785
23845
  });
23846
+ function resolveAnchorRect(anchor) {
23847
+ if (typeof anchor === "string") {
23848
+ return document.querySelector(anchor)?.getBoundingClientRect() ?? null;
23849
+ }
23850
+ if (anchor instanceof DOMRect) return anchor;
23851
+ return anchor?.current?.getBoundingClientRect() ?? null;
23852
+ }
23853
+ function useAnchorRect(anchor, active) {
23854
+ const [rect, setRect] = useState(null);
23855
+ const read = useCallback(() => resolveAnchorRect(anchor), [anchor]);
23856
+ useEffect(() => {
23857
+ if (!active || typeof document === "undefined") {
23858
+ setRect(null);
23859
+ return;
23860
+ }
23861
+ const update = () => setRect(read());
23862
+ update();
23863
+ window.addEventListener("scroll", update, true);
23864
+ window.addEventListener("resize", update);
23865
+ let raf = 0;
23866
+ let tries = 0;
23867
+ const poll = () => {
23868
+ const found = read();
23869
+ if (found) {
23870
+ setRect(found);
23871
+ } else if (tries++ < 40) {
23872
+ raf = requestAnimationFrame(poll);
23873
+ }
23874
+ };
23875
+ if (!read()) raf = requestAnimationFrame(poll);
23876
+ return () => {
23877
+ window.removeEventListener("scroll", update, true);
23878
+ window.removeEventListener("resize", update);
23879
+ if (raf) cancelAnimationFrame(raf);
23880
+ };
23881
+ }, [active, read]);
23882
+ return rect;
23883
+ }
23884
+ function placeCard(placement, rect, size) {
23885
+ const vw = typeof window !== "undefined" ? window.innerWidth : 1024;
23886
+ const vh = typeof window !== "undefined" ? window.innerHeight : 768;
23887
+ let top = 0;
23888
+ let left = 0;
23889
+ switch (placement) {
23890
+ case "top":
23891
+ top = rect.top - size.h - GAP;
23892
+ left = rect.left + rect.width / 2 - size.w / 2;
23893
+ break;
23894
+ case "left":
23895
+ left = rect.left - size.w - GAP;
23896
+ top = rect.top + rect.height / 2 - size.h / 2;
23897
+ break;
23898
+ case "right":
23899
+ left = rect.right + GAP;
23900
+ top = rect.top + rect.height / 2 - size.h / 2;
23901
+ break;
23902
+ case "bottom":
23903
+ default:
23904
+ top = rect.bottom + GAP;
23905
+ left = rect.left + rect.width / 2 - size.w / 2;
23906
+ break;
23907
+ }
23908
+ left = Math.max(EDGE, Math.min(left, vw - size.w - EDGE));
23909
+ top = Math.max(EDGE, Math.min(top, vh - size.h - EDGE));
23910
+ return { top, left };
23911
+ }
23912
+ var GAP, EDGE, Coachmark;
23913
+ var init_Coachmark = __esm({
23914
+ "components/molecules/Coachmark.tsx"() {
23915
+ "use client";
23916
+ init_Box();
23917
+ init_Typography();
23918
+ init_Button();
23919
+ init_Icon();
23920
+ init_cn();
23921
+ GAP = 10;
23922
+ EDGE = 8;
23923
+ Coachmark = ({
23924
+ open,
23925
+ anchor,
23926
+ placement = "bottom",
23927
+ title,
23928
+ children,
23929
+ onDismiss,
23930
+ onPrimary,
23931
+ primaryLabel,
23932
+ onSecondary,
23933
+ secondaryLabel,
23934
+ showBeacon = false,
23935
+ className
23936
+ }) => {
23937
+ const cardRef = useRef(null);
23938
+ const rect = useAnchorRect(anchor, open);
23939
+ const [pos, setPos] = useState(null);
23940
+ useLayoutEffect(() => {
23941
+ if (!open || !rect || !cardRef.current) {
23942
+ setPos(null);
23943
+ return;
23944
+ }
23945
+ const size = {
23946
+ w: cardRef.current.offsetWidth,
23947
+ h: cardRef.current.offsetHeight
23948
+ };
23949
+ setPos(placeCard(placement, rect, size));
23950
+ }, [open, rect, placement, children, title]);
23951
+ if (!open || !rect || typeof document === "undefined") return null;
23952
+ const hasFooter = Boolean(onPrimary || onSecondary);
23953
+ const card = /* @__PURE__ */ jsxs(
23954
+ Box,
23955
+ {
23956
+ ref: cardRef,
23957
+ bg: "surface",
23958
+ border: true,
23959
+ rounded: "lg",
23960
+ shadow: "xl",
23961
+ padding: "md",
23962
+ role: "dialog",
23963
+ "aria-label": title,
23964
+ className: cn(
23965
+ "fixed z-50 max-w-xs w-72 transition-opacity duration-150",
23966
+ pos ? "opacity-100" : "opacity-0",
23967
+ className
23968
+ ),
23969
+ style: pos ? { top: pos.top, left: pos.left } : { top: -9999, left: -9999 },
23970
+ children: [
23971
+ /* @__PURE__ */ jsx(
23972
+ "button",
23973
+ {
23974
+ type: "button",
23975
+ "aria-label": "Dismiss",
23976
+ onClick: onDismiss,
23977
+ className: "absolute top-2 right-2 text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)]",
23978
+ children: /* @__PURE__ */ jsx(Icon, { name: "close", size: "xs" })
23979
+ }
23980
+ ),
23981
+ title && /* @__PURE__ */ jsx(Typography, { variant: "body1", weight: "semibold", className: "pr-6 mb-1", children: title }),
23982
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "muted", as: "div", children }),
23983
+ hasFooter && /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-end gap-2", children: [
23984
+ onSecondary && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: onSecondary, children: secondaryLabel ?? "Skip" }),
23985
+ onPrimary && /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: onPrimary, children: primaryLabel ?? "Got it" })
23986
+ ] })
23987
+ ]
23988
+ }
23989
+ );
23990
+ const beacon = showBeacon ? /* @__PURE__ */ jsx(
23991
+ "div",
23992
+ {
23993
+ className: "fixed z-50 pointer-events-none",
23994
+ style: {
23995
+ top: rect.top + rect.height / 2 - 6,
23996
+ left: rect.left + rect.width / 2 - 6
23997
+ },
23998
+ "aria-hidden": "true",
23999
+ children: /* @__PURE__ */ jsxs("span", { className: "relative flex h-3 w-3", children: [
24000
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-[var(--color-primary)] opacity-75" }),
24001
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-3 w-3 rounded-full bg-[var(--color-primary)]" })
24002
+ ] })
24003
+ }
24004
+ ) : null;
24005
+ return createPortal(
24006
+ /* @__PURE__ */ jsxs(Fragment, { children: [
24007
+ beacon,
24008
+ card
24009
+ ] }),
24010
+ document.body
24011
+ );
24012
+ };
24013
+ Coachmark.displayName = "Coachmark";
24014
+ }
24015
+ });
24016
+ var DIM, OnboardingSpotlight;
24017
+ var init_OnboardingSpotlight = __esm({
24018
+ "components/molecules/OnboardingSpotlight.tsx"() {
24019
+ "use client";
24020
+ init_Coachmark();
24021
+ init_cn();
24022
+ DIM = "fixed z-[45] bg-black/60";
24023
+ OnboardingSpotlight = ({
24024
+ steps,
24025
+ stepIndex,
24026
+ onNext,
24027
+ onSkip,
24028
+ onFinish,
24029
+ cutoutPadding = 6
24030
+ }) => {
24031
+ const step = steps[stepIndex];
24032
+ const rect = useAnchorRect(step?.anchor ?? "", Boolean(step));
24033
+ if (!step || typeof document === "undefined") return null;
24034
+ const isLast = stepIndex >= steps.length - 1;
24035
+ const backdrop = rect ? (() => {
24036
+ const p2 = cutoutPadding;
24037
+ const top = Math.max(0, rect.top - p2);
24038
+ const left = Math.max(0, rect.left - p2);
24039
+ const right = rect.right + p2;
24040
+ const bottom = rect.bottom + p2;
24041
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
24042
+ /* @__PURE__ */ jsx("div", { className: DIM, style: { top: 0, left: 0, right: 0, height: top } }),
24043
+ /* @__PURE__ */ jsx("div", { className: DIM, style: { top: bottom, left: 0, right: 0, bottom: 0 } }),
24044
+ /* @__PURE__ */ jsx("div", { className: DIM, style: { top, left: 0, width: left, height: bottom - top } }),
24045
+ /* @__PURE__ */ jsx("div", { className: DIM, style: { top, left: right, right: 0, height: bottom - top } })
24046
+ ] });
24047
+ })() : /* @__PURE__ */ jsx("div", { className: cn(DIM, "inset-0") });
24048
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
24049
+ createPortal(backdrop, document.body),
24050
+ /* @__PURE__ */ jsxs(
24051
+ Coachmark,
24052
+ {
24053
+ open: true,
24054
+ anchor: step.anchor,
24055
+ placement: step.placement ?? "bottom",
24056
+ title: step.title,
24057
+ onDismiss: onSkip,
24058
+ onSecondary: onSkip,
24059
+ secondaryLabel: "Skip",
24060
+ onPrimary: isLast ? onFinish : onNext,
24061
+ primaryLabel: isLast ? "Done" : "Next",
24062
+ children: [
24063
+ /* @__PURE__ */ jsx("span", { children: step.body }),
24064
+ /* @__PURE__ */ jsx("span", { className: "mt-3 flex items-center gap-1.5", children: steps.map((_, i) => /* @__PURE__ */ jsx(
24065
+ "span",
24066
+ {
24067
+ className: cn(
24068
+ "h-1.5 w-1.5 rounded-full",
24069
+ i === stepIndex ? "bg-[var(--color-primary)]" : "bg-[var(--color-border)]"
24070
+ )
24071
+ },
24072
+ i
24073
+ )) })
24074
+ ]
24075
+ }
24076
+ )
24077
+ ] });
24078
+ };
24079
+ OnboardingSpotlight.displayName = "OnboardingSpotlight";
24080
+ }
24081
+ });
23786
24082
  function gateEnabled(level, ns = NAMESPACE) {
23787
24083
  return isLogLevelEnabled(level, ns);
23788
24084
  }
@@ -34143,7 +34439,7 @@ var init_AvlPage = __esm({
34143
34439
  AvlPage.displayName = "AvlPage";
34144
34440
  }
34145
34441
  });
34146
- var NODE_W, NODE_H, GAP, ARROW_W, MiniStateMachine;
34442
+ var NODE_W, NODE_H, GAP2, ARROW_W, MiniStateMachine;
34147
34443
  var init_MiniStateMachine = __esm({
34148
34444
  "components/molecules/avl/MiniStateMachine.tsx"() {
34149
34445
  "use client";
@@ -34152,7 +34448,7 @@ var init_MiniStateMachine = __esm({
34152
34448
  init_types();
34153
34449
  NODE_W = 24;
34154
34450
  NODE_H = 16;
34155
- GAP = 8;
34451
+ GAP2 = 8;
34156
34452
  ARROW_W = 16;
34157
34453
  MiniStateMachine = ({ data, className }) => {
34158
34454
  const states = data.states;
@@ -34169,12 +34465,12 @@ var init_MiniStateMachine = __esm({
34169
34465
  for (const e of t.effects) effectTypes.add(e.type);
34170
34466
  }
34171
34467
  const effectList = Array.from(effectTypes).slice(0, 6);
34172
- const totalW = states.length * NODE_W + (states.length - 1) * (GAP + ARROW_W + GAP);
34468
+ const totalW = states.length * NODE_W + (states.length - 1) * (GAP2 + ARROW_W + GAP2);
34173
34469
  const svgW = Math.max(totalW + 4, 60);
34174
34470
  const svgH = NODE_H + (effectList.length > 0 ? 18 : 4);
34175
34471
  return /* @__PURE__ */ jsxs("svg", { width: svgW, height: svgH, viewBox: `0 0 ${svgW} ${svgH}`, className, children: [
34176
34472
  states.map((s, i) => {
34177
- const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
34473
+ const x = 2 + i * (NODE_W + GAP2 + ARROW_W + GAP2);
34178
34474
  const tc = transitionCounts[s.name] ?? 0;
34179
34475
  const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
34180
34476
  return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
@@ -34195,9 +34491,9 @@ var init_MiniStateMachine = __esm({
34195
34491
  /* @__PURE__ */ jsx(
34196
34492
  "line",
34197
34493
  {
34198
- x1: x + NODE_W + GAP,
34494
+ x1: x + NODE_W + GAP2,
34199
34495
  y1: NODE_H / 2,
34200
- x2: x + NODE_W + GAP + ARROW_W - 3,
34496
+ x2: x + NODE_W + GAP2 + ARROW_W - 3,
34201
34497
  y2: NODE_H / 2,
34202
34498
  stroke: "var(--color-muted-foreground)",
34203
34499
  strokeWidth: 1,
@@ -34207,7 +34503,7 @@ var init_MiniStateMachine = __esm({
34207
34503
  /* @__PURE__ */ jsx(
34208
34504
  "polygon",
34209
34505
  {
34210
- points: `${x + NODE_W + GAP + ARROW_W - 3},${NODE_H / 2 - 2.5} ${x + NODE_W + GAP + ARROW_W},${NODE_H / 2} ${x + NODE_W + GAP + ARROW_W - 3},${NODE_H / 2 + 2.5}`,
34506
+ points: `${x + NODE_W + GAP2 + ARROW_W - 3},${NODE_H / 2 - 2.5} ${x + NODE_W + GAP2 + ARROW_W},${NODE_H / 2} ${x + NODE_W + GAP2 + ARROW_W - 3},${NODE_H / 2 + 2.5}`,
34211
34507
  fill: "var(--color-muted-foreground)",
34212
34508
  opacity: 0.4
34213
34509
  }
@@ -34354,6 +34650,8 @@ var init_molecules = __esm({
34354
34650
  init_Modal();
34355
34651
  init_Pagination();
34356
34652
  init_Popover();
34653
+ init_Coachmark();
34654
+ init_OnboardingSpotlight();
34357
34655
  init_RelationSelect();
34358
34656
  init_SearchInput();
34359
34657
  init_SidePanel();
@@ -50619,4 +50917,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
50619
50917
  });
50620
50918
  }
50621
50919
 
50622
- export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BehaviorView, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, Checkbox, ChoiceButton, ClassifierBoard, CodeBlock, CodeExample, CodeView, CodeViewer, CollapsibleSection, CombatLog, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, Container, ContentRenderer, ContentSection, ControlButton, CounterTemplate, CraftingRecipe, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DPad, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBox, DialogueBubble, Divider, DocBreadcrumb, DocCodeBlock, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EnemyPlate, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FeatureRenderer2 as FeatureRenderer, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, HStack, Header, Heading, HealthBar, HealthPanel, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, JazariStateMachine, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NotifyListener, NumberStepper, ObjectRulePanel, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsManager, PlatformerCanvas, Popover, PositionedCanvas, PowerupSlots, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PullQuote, PullToRefresh, QrScanner, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Section, SectionHeader, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, Table, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UnitCommandBar, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, XPBar, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, clearEntities, cn, combatAnimations, combatClasses, combatEffects, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, generateCombatMessage, getAllEntities, getByType, getCurrentFrame, getEntity, getSingleton, getTileDimensions, inferDirection, isoToScreen, mapBookData, parseQueryBinding, pendulum, projectileMotion, removeEntity, resolveFieldMap, resolveFrame, resolveSheetDirection, screenToIso, spawnEntity, springOscillator, tickAnimationState, transitionAnimation, updateEntity, updateSingleton, useAgentChat, useAuthContext, useBattleState, useCamera, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEntities, useEntitiesByType, useEntity as useEntityById, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useInput, useLongPress, useOrbitalHistory, usePhysics, usePhysics2D, usePinchZoom, usePlayer, usePreview, usePullToRefresh, useQuerySingleton, useSingletonEntity, useSpriteAnimations, useSwipeGesture, useTraitListens, useTranslate, useUIEvents, useUISlotManager, useValidation };
50920
+ export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BehaviorView, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, Checkbox, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CodeExample, CodeView, CodeViewer, CollapsibleSection, CombatLog, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, Container, ContentRenderer, ContentSection, ControlButton, CounterTemplate, CraftingRecipe, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DPad, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBox, DialogueBubble, Divider, DocBreadcrumb, DocCodeBlock, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EnemyPlate, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FeatureRenderer2 as FeatureRenderer, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, HStack, Header, Heading, HealthBar, HealthPanel, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, JazariStateMachine, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsManager, PlatformerCanvas, Popover, PositionedCanvas, PowerupSlots, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PullQuote, PullToRefresh, QrScanner, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Section, SectionHeader, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, Table, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UnitCommandBar, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, XPBar, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, clearEntities, cn, combatAnimations, combatClasses, combatEffects, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, generateCombatMessage, getAllEntities, getByType, getCurrentFrame, getEntity, getSingleton, getTileDimensions, inferDirection, isoToScreen, mapBookData, parseQueryBinding, pendulum, projectileMotion, removeEntity, resolveFieldMap, resolveFrame, resolveSheetDirection, screenToIso, spawnEntity, springOscillator, tickAnimationState, transitionAnimation, updateEntity, updateSingleton, useAgentChat, useAnchorRect, useAuthContext, useBattleState, useCamera, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEntities, useEntitiesByType, useEntity as useEntityById, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useInput, useLongPress, useOrbitalHistory, usePhysics, usePhysics2D, usePinchZoom, usePlayer, usePreview, usePullToRefresh, useQuerySingleton, useSingletonEntity, useSpriteAnimations, useSwipeGesture, useTraitListens, useTranslate, useUIEvents, useUISlotManager, useValidation };