@almadar/ui 5.13.3 → 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.
@@ -8630,13 +8630,13 @@ var init_MapView = __esm({
8630
8630
  shadowSize: [41, 41]
8631
8631
  });
8632
8632
  L.Marker.prototype.options.icon = defaultIcon;
8633
- const { useEffect: useEffect72, useRef: useRef66, useCallback: useCallback128, useState: useState111 } = React80__default;
8633
+ const { useEffect: useEffect73, useRef: useRef67, useCallback: useCallback129, useState: useState112 } = React80__default;
8634
8634
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
8635
8635
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
8636
8636
  function MapUpdater({ centerLat, centerLng, zoom }) {
8637
8637
  const map = useMap();
8638
- const prevRef = useRef66({ centerLat, centerLng, zoom });
8639
- useEffect72(() => {
8638
+ const prevRef = useRef67({ centerLat, centerLng, zoom });
8639
+ useEffect73(() => {
8640
8640
  const prev = prevRef.current;
8641
8641
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
8642
8642
  map.setView([centerLat, centerLng], zoom);
@@ -8647,7 +8647,7 @@ var init_MapView = __esm({
8647
8647
  }
8648
8648
  function MapClickHandler({ onMapClick }) {
8649
8649
  const map = useMap();
8650
- useEffect72(() => {
8650
+ useEffect73(() => {
8651
8651
  if (!onMapClick) return;
8652
8652
  const handler = (e) => {
8653
8653
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -8675,8 +8675,8 @@ var init_MapView = __esm({
8675
8675
  showAttribution = true
8676
8676
  }) {
8677
8677
  const eventBus = useEventBus2();
8678
- const [clickedPosition, setClickedPosition] = useState111(null);
8679
- const handleMapClick = useCallback128((lat, lng) => {
8678
+ const [clickedPosition, setClickedPosition] = useState112(null);
8679
+ const handleMapClick = useCallback129((lat, lng) => {
8680
8680
  if (showClickedPin) {
8681
8681
  setClickedPosition({ lat, lng });
8682
8682
  }
@@ -8685,7 +8685,7 @@ var init_MapView = __esm({
8685
8685
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
8686
8686
  }
8687
8687
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
8688
- const handleMarkerClick = useCallback128((marker) => {
8688
+ const handleMarkerClick = useCallback129((marker) => {
8689
8689
  onMarkerClick?.(marker);
8690
8690
  if (markerClickEvent) {
8691
8691
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -12465,6 +12465,8 @@ var init_CodeBlock = __esm({
12465
12465
  collapsedRef.current = collapsed;
12466
12466
  const foldStartMapRef = useRef(foldStartMap);
12467
12467
  foldStartMapRef.current = foldStartMap;
12468
+ const hiddenLinesRef = useRef(hiddenLines);
12469
+ hiddenLinesRef.current = hiddenLines;
12468
12470
  const toggleFold = useCallback((lineNum) => {
12469
12471
  setCollapsed((prev) => {
12470
12472
  const next = new Set(prev);
@@ -12577,6 +12579,60 @@ var init_CodeBlock = __esm({
12577
12579
  eventBus.emit("UI:COPY_CODE", { language, success: false });
12578
12580
  }
12579
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]);
12580
12636
  const hasHeader = showLanguageBadge || showCopyButton;
12581
12637
  return /* @__PURE__ */ jsxs(Box, { className: `relative group ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
12582
12638
  hasHeader && /* @__PURE__ */ jsxs(
@@ -12727,6 +12783,7 @@ var init_CodeBlock = __esm({
12727
12783
  "div",
12728
12784
  {
12729
12785
  ref: scrollRef,
12786
+ onCopy: handleSelectionCopy,
12730
12787
  style: {
12731
12788
  flex: 1,
12732
12789
  minHeight: 0,
@@ -23786,6 +23843,242 @@ var init_InputGroup = __esm({
23786
23843
  InputGroup.displayName = "InputGroup";
23787
23844
  }
23788
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
+ });
23789
24082
  function gateEnabled(level, ns = NAMESPACE) {
23790
24083
  return isLogLevelEnabled(level, ns);
23791
24084
  }
@@ -34146,7 +34439,7 @@ var init_AvlPage = __esm({
34146
34439
  AvlPage.displayName = "AvlPage";
34147
34440
  }
34148
34441
  });
34149
- var NODE_W, NODE_H, GAP, ARROW_W, MiniStateMachine;
34442
+ var NODE_W, NODE_H, GAP2, ARROW_W, MiniStateMachine;
34150
34443
  var init_MiniStateMachine = __esm({
34151
34444
  "components/molecules/avl/MiniStateMachine.tsx"() {
34152
34445
  "use client";
@@ -34155,7 +34448,7 @@ var init_MiniStateMachine = __esm({
34155
34448
  init_types();
34156
34449
  NODE_W = 24;
34157
34450
  NODE_H = 16;
34158
- GAP = 8;
34451
+ GAP2 = 8;
34159
34452
  ARROW_W = 16;
34160
34453
  MiniStateMachine = ({ data, className }) => {
34161
34454
  const states = data.states;
@@ -34172,12 +34465,12 @@ var init_MiniStateMachine = __esm({
34172
34465
  for (const e of t.effects) effectTypes.add(e.type);
34173
34466
  }
34174
34467
  const effectList = Array.from(effectTypes).slice(0, 6);
34175
- 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);
34176
34469
  const svgW = Math.max(totalW + 4, 60);
34177
34470
  const svgH = NODE_H + (effectList.length > 0 ? 18 : 4);
34178
34471
  return /* @__PURE__ */ jsxs("svg", { width: svgW, height: svgH, viewBox: `0 0 ${svgW} ${svgH}`, className, children: [
34179
34472
  states.map((s, i) => {
34180
- const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
34473
+ const x = 2 + i * (NODE_W + GAP2 + ARROW_W + GAP2);
34181
34474
  const tc = transitionCounts[s.name] ?? 0;
34182
34475
  const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
34183
34476
  return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
@@ -34198,9 +34491,9 @@ var init_MiniStateMachine = __esm({
34198
34491
  /* @__PURE__ */ jsx(
34199
34492
  "line",
34200
34493
  {
34201
- x1: x + NODE_W + GAP,
34494
+ x1: x + NODE_W + GAP2,
34202
34495
  y1: NODE_H / 2,
34203
- x2: x + NODE_W + GAP + ARROW_W - 3,
34496
+ x2: x + NODE_W + GAP2 + ARROW_W - 3,
34204
34497
  y2: NODE_H / 2,
34205
34498
  stroke: "var(--color-muted-foreground)",
34206
34499
  strokeWidth: 1,
@@ -34210,7 +34503,7 @@ var init_MiniStateMachine = __esm({
34210
34503
  /* @__PURE__ */ jsx(
34211
34504
  "polygon",
34212
34505
  {
34213
- 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}`,
34214
34507
  fill: "var(--color-muted-foreground)",
34215
34508
  opacity: 0.4
34216
34509
  }
@@ -34357,6 +34650,8 @@ var init_molecules = __esm({
34357
34650
  init_Modal();
34358
34651
  init_Pagination();
34359
34652
  init_Popover();
34653
+ init_Coachmark();
34654
+ init_OnboardingSpotlight();
34360
34655
  init_RelationSelect();
34361
34656
  init_SearchInput();
34362
34657
  init_SidePanel();
@@ -50622,4 +50917,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
50622
50917
  });
50623
50918
  }
50624
50919
 
50625
- 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 };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Coachmark Molecule
3
+ *
4
+ * A controlled, externally-anchored popover for onboarding hints. Unlike
5
+ * Popover (uncontrolled, wraps its own trigger), a Coachmark is driven by
6
+ * `open` and points at an element it does not own — a tab button, the persona
7
+ * menu, a canvas node — resolved from a ref, a CSS selector, or a DOMRect.
8
+ * Portals to document.body so it escapes the canvas/preview transform contexts.
9
+ */
10
+ import React from "react";
11
+ export type CoachmarkPlacement = "top" | "bottom" | "left" | "right";
12
+ export type CoachmarkAnchor = React.RefObject<HTMLElement | null> | string | DOMRect;
13
+ export interface CoachmarkProps {
14
+ /** Controlled visibility. */
15
+ open: boolean;
16
+ /** The element to point at: a ref, a CSS selector, or a DOMRect. */
17
+ anchor: CoachmarkAnchor;
18
+ /** Side of the anchor to render on. @default 'bottom' */
19
+ placement?: CoachmarkPlacement;
20
+ title?: string;
21
+ children: React.ReactNode;
22
+ /** Close (X) handler — always rendered. */
23
+ onDismiss: () => void;
24
+ /** Optional filled primary action (e.g. Next / Got it). */
25
+ onPrimary?: () => void;
26
+ primaryLabel?: string;
27
+ /** Optional ghost secondary action (e.g. Skip). */
28
+ onSecondary?: () => void;
29
+ secondaryLabel?: string;
30
+ /** Render a pulsing beacon dot over the anchor (keystone hints). */
31
+ showBeacon?: boolean;
32
+ className?: string;
33
+ }
34
+ /**
35
+ * Tracks the live bounding rect of an anchor while `active`. Re-reads on
36
+ * scroll/resize, and polls a few frames so a selector that mounts just after
37
+ * activation (a freshly-revealed tab) still resolves.
38
+ */
39
+ export declare function useAnchorRect(anchor: CoachmarkAnchor, active: boolean): DOMRect | null;
40
+ export declare const Coachmark: React.FC<CoachmarkProps>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * OnboardingSpotlight Molecule
3
+ *
4
+ * Optional first-run welcome: a dimmed backdrop with a cut-out over the current
5
+ * step's anchor, plus a stepped Coachmark bubble (Next / Skip). The backdrop is
6
+ * four dim rectangles around the anchor rect so the highlighted element stays
7
+ * lit and clickable-looking; the bubble and step dots reuse Coachmark.
8
+ */
9
+ import React from "react";
10
+ import { type CoachmarkAnchor, type CoachmarkPlacement } from "./Coachmark";
11
+ export interface SpotlightStep {
12
+ anchor: CoachmarkAnchor;
13
+ placement?: CoachmarkPlacement;
14
+ title: string;
15
+ body: string;
16
+ }
17
+ export interface OnboardingSpotlightProps {
18
+ steps: SpotlightStep[];
19
+ /** Index of the active step. Out-of-range hides the spotlight. */
20
+ stepIndex: number;
21
+ onNext: () => void;
22
+ onSkip: () => void;
23
+ onFinish: () => void;
24
+ /** Padding around the cut-out, in px. @default 6 */
25
+ cutoutPadding?: number;
26
+ }
27
+ export declare const OnboardingSpotlight: React.FC<OnboardingSpotlightProps>;
@@ -14,7 +14,7 @@ export declare const CLINIC_SCHEMA: OrbitalSchema;
14
14
  /**
15
15
  * Task manager schema: 3 orbitals for a richer multi-module story.
16
16
  * - TaskOrbital (std-browse): task list
17
- * - TimerOrbital (std-timer): countdown timer
17
+ * - FocusTimer (std-list): focus session list
18
18
  * - ArchiveOrbital (std-confirmation): archive confirmation
19
19
  */
20
20
  export declare const TASK_SCHEMA: OrbitalSchema;
@@ -20,6 +20,8 @@ export { Menu, type MenuProps, type MenuItem } from './Menu';
20
20
  export { Modal, type ModalProps, type ModalSize } from './Modal';
21
21
  export { Pagination, type PaginationProps } from './Pagination';
22
22
  export { Popover, type PopoverProps } from './Popover';
23
+ export { Coachmark, useAnchorRect, type CoachmarkProps, type CoachmarkPlacement, type CoachmarkAnchor, } from './Coachmark';
24
+ export { OnboardingSpotlight, type OnboardingSpotlightProps, type SpotlightStep, } from './OnboardingSpotlight';
23
25
  export { RelationSelect, type RelationSelectProps, type RelationOption } from './RelationSelect';
24
26
  export { SearchInput, type SearchInputProps } from './SearchInput';
25
27
  export { SidePanel, type SidePanelProps } from './SidePanel';
@@ -13990,6 +13990,8 @@ var init_CodeBlock = __esm({
13990
13990
  collapsedRef.current = collapsed;
13991
13991
  const foldStartMapRef = React86.useRef(foldStartMap);
13992
13992
  foldStartMapRef.current = foldStartMap;
13993
+ const hiddenLinesRef = React86.useRef(hiddenLines);
13994
+ hiddenLinesRef.current = hiddenLines;
13993
13995
  const toggleFold = React86.useCallback((lineNum) => {
13994
13996
  setCollapsed((prev) => {
13995
13997
  const next = new Set(prev);
@@ -14102,6 +14104,60 @@ var init_CodeBlock = __esm({
14102
14104
  eventBus.emit("UI:COPY_CODE", { language, success: false });
14103
14105
  }
14104
14106
  };
14107
+ const handleSelectionCopy = React86.useCallback((e) => {
14108
+ if (hiddenLinesRef.current.size === 0) return;
14109
+ const sel = typeof window !== "undefined" ? window.getSelection() : null;
14110
+ if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return;
14111
+ const lineOf = (node) => {
14112
+ const start = node instanceof HTMLElement ? node : node?.parentElement ?? null;
14113
+ const lineEl = start?.closest("[data-line]");
14114
+ if (!lineEl) return null;
14115
+ const n = parseInt(lineEl.getAttribute("data-line") ?? "", 10);
14116
+ return Number.isNaN(n) ? null : n;
14117
+ };
14118
+ const range = sel.getRangeAt(0);
14119
+ let a = lineOf(range.startContainer);
14120
+ let b = lineOf(range.endContainer);
14121
+ if (a === null || b === null) {
14122
+ const container = codeRef.current;
14123
+ if (!container) return;
14124
+ let min = Infinity, max = -Infinity;
14125
+ container.querySelectorAll("[data-line]").forEach((el) => {
14126
+ if (!sel.containsNode(el, true)) return;
14127
+ const n = parseInt(el.getAttribute("data-line") ?? "", 10);
14128
+ if (!Number.isNaN(n)) {
14129
+ min = Math.min(min, n);
14130
+ max = Math.max(max, n);
14131
+ }
14132
+ });
14133
+ if (min === Infinity) return;
14134
+ a = a ?? min;
14135
+ b = b ?? max;
14136
+ }
14137
+ if (a > b) [a, b] = [b, a];
14138
+ let touchesFold = false;
14139
+ for (let i = a; i <= b; i++) {
14140
+ if (hiddenLinesRef.current.has(i) || foldStartMapRef.current.has(i) && collapsedRef.current.has(i)) {
14141
+ touchesFold = true;
14142
+ break;
14143
+ }
14144
+ }
14145
+ if (!touchesFold) return;
14146
+ let endLine = b;
14147
+ let changed = true;
14148
+ while (changed) {
14149
+ changed = false;
14150
+ foldStartMapRef.current.forEach((region, start) => {
14151
+ if (start >= a && start <= endLine && collapsedRef.current.has(start) && region.end > endLine) {
14152
+ endLine = region.end;
14153
+ changed = true;
14154
+ }
14155
+ });
14156
+ }
14157
+ const full = code.split("\n").slice(a, endLine + 1).join("\n");
14158
+ e.clipboardData.setData("text/plain", full);
14159
+ e.preventDefault();
14160
+ }, [code]);
14105
14161
  const hasHeader = showLanguageBadge || showCopyButton;
14106
14162
  return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: `relative group ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
14107
14163
  hasHeader && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -14252,6 +14308,7 @@ var init_CodeBlock = __esm({
14252
14308
  "div",
14253
14309
  {
14254
14310
  ref: scrollRef,
14311
+ onCopy: handleSelectionCopy,
14255
14312
  style: {
14256
14313
  flex: 1,
14257
14314
  minHeight: 0,