@almadar/shell-web 0.0.0-stage → 1.0.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.
Files changed (266) hide show
  1. package/bundling.d.mts +18 -0
  2. package/bundling.mjs +28 -0
  3. package/dist/ArbitraryClassCompiler-CO_iASBn.d.ts +195 -0
  4. package/dist/AvlGlyph-EPJKFEO3.js +6 -0
  5. package/dist/AvlStateMachine-RKZIKNGC.js +9 -0
  6. package/dist/AvlTransitionDetail-63SD6GZF.js +11 -0
  7. package/dist/AvlTransitionExplainer-ZBTLOM3T.js +12 -0
  8. package/dist/BehaviorView-YS5G4GNB.js +11 -0
  9. package/dist/Canvas3DHost-BkZQB5l2.d.ts +552 -0
  10. package/dist/EventBusProvider-BFFHfN4O.d.ts +296 -0
  11. package/dist/FileTree-BCFnBEuQ.d.ts +254 -0
  12. package/dist/FlowCanvas-3JRMNJLV.css +1756 -0
  13. package/dist/FlowCanvas-AUMTWMNG.js +26 -0
  14. package/dist/GameAudioProvider-ceM_n0ey.d.ts +90 -0
  15. package/dist/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
  16. package/dist/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
  17. package/dist/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
  18. package/dist/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
  19. package/dist/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
  20. package/dist/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
  21. package/dist/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
  22. package/dist/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
  23. package/dist/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
  24. package/dist/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
  25. package/dist/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
  26. package/dist/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
  27. package/dist/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
  28. package/dist/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
  29. package/dist/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
  30. package/dist/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
  31. package/dist/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
  32. package/dist/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
  33. package/dist/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
  34. package/dist/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
  35. package/dist/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
  36. package/dist/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
  37. package/dist/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
  38. package/dist/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
  39. package/dist/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
  40. package/dist/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
  41. package/dist/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
  42. package/dist/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
  43. package/dist/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
  44. package/dist/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
  45. package/dist/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
  46. package/dist/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
  47. package/dist/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
  48. package/dist/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
  49. package/dist/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
  50. package/dist/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
  51. package/dist/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
  52. package/dist/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
  53. package/dist/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
  54. package/dist/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
  55. package/dist/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
  56. package/dist/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
  57. package/dist/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
  58. package/dist/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
  59. package/dist/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
  60. package/dist/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
  61. package/dist/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
  62. package/dist/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
  63. package/dist/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
  64. package/dist/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
  65. package/dist/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
  66. package/dist/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
  67. package/dist/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
  68. package/dist/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
  69. package/dist/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
  70. package/dist/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
  71. package/dist/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
  72. package/dist/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
  73. package/dist/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
  74. package/dist/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
  75. package/dist/KernelEngineContext-CcxGYtlr.d.ts +33 -0
  76. package/dist/LayersPanel-M2LHWUFF.js +6 -0
  77. package/dist/ModuleCard-QHDGK5XK.js +7 -0
  78. package/dist/OrbInspector-MHLJ6OEE.css +1756 -0
  79. package/dist/OrbInspector-QCPEPUPH.js +26 -0
  80. package/dist/Select-B-iDdnvE.d.ts +185 -0
  81. package/dist/ServerBridge-Bqsj-lOU.d.ts +124 -0
  82. package/dist/ThemeContext-DJmO59xd.d.ts +147 -0
  83. package/dist/UISlotContext-Dl_ewwCI.d.ts +79 -0
  84. package/dist/UISlotRenderer-C7WWOK43.js +26 -0
  85. package/dist/UISlotRenderer-KVFO6J7R.css +1756 -0
  86. package/dist/auth/browser/index.d.ts +2 -0
  87. package/dist/auth/browser/index.js +2 -0
  88. package/dist/auth/react/index.d.ts +56 -0
  89. package/dist/auth/react/index.js +157 -0
  90. package/dist/avl/index.css +1756 -0
  91. package/dist/avl/index.d.ts +2248 -0
  92. package/dist/avl/index.js +2693 -0
  93. package/dist/avl-3d-context-BycmO6tG.d.ts +201 -0
  94. package/dist/avl-schema-parser-CtJxJ9KU.d.ts +132 -0
  95. package/dist/avl-zoom-state-CKMVuBFg.d.ts +17 -0
  96. package/dist/chunk-3BBUBJFF.js +339 -0
  97. package/dist/chunk-3S54FWRC.js +131 -0
  98. package/dist/chunk-3VZ36ZKO.js +775 -0
  99. package/dist/chunk-4T3P43NS.js +1133 -0
  100. package/dist/chunk-4YXBKHHM.js +11488 -0
  101. package/dist/chunk-57DC34LY.js +525 -0
  102. package/dist/chunk-5QTYQTPS.js +15 -0
  103. package/dist/chunk-A2LR6VQQ.js +349 -0
  104. package/dist/chunk-AB3X7QTE.js +505 -0
  105. package/dist/chunk-AE7VCQB6.js +561 -0
  106. package/dist/chunk-AGXD77SL.js +98 -0
  107. package/dist/chunk-AU7O65OX.js +66 -0
  108. package/dist/chunk-CPLN6NBQ.js +701 -0
  109. package/dist/chunk-DZBQA2OW.js +176 -0
  110. package/dist/chunk-E6KA4J6N.js +227 -0
  111. package/dist/chunk-EOWMARUB.js +16 -0
  112. package/dist/chunk-G7DCAZ22.js +19 -0
  113. package/dist/chunk-GFXCPUMX.js +1334 -0
  114. package/dist/chunk-HH5KSMH5.js +311 -0
  115. package/dist/chunk-ILQXJ2AR.js +280 -0
  116. package/dist/chunk-ILZ7ORX7.js +432 -0
  117. package/dist/chunk-K4MOPSEL.js +674 -0
  118. package/dist/chunk-LHP2TK7O.js +47587 -0
  119. package/dist/chunk-P4ZFUQFF.js +93 -0
  120. package/dist/chunk-PCR37T3U.js +296 -0
  121. package/dist/chunk-PRXQGGCO.js +580 -0
  122. package/dist/chunk-REXYVBUO.js +191 -0
  123. package/dist/chunk-ROICKAU7.js +24 -0
  124. package/dist/chunk-SP5CDJ6K.js +338 -0
  125. package/dist/chunk-TUPZWTRE.js +1051 -0
  126. package/dist/chunk-TXAUOLWZ.js +490 -0
  127. package/dist/chunk-TZZBINQY.js +82 -0
  128. package/dist/chunk-UTDC2NEA.js +14 -0
  129. package/dist/chunk-UU57VNS2.js +1053 -0
  130. package/dist/chunk-UXLE3IPR.js +421 -0
  131. package/dist/chunk-VO2TTLS5.js +94 -0
  132. package/dist/chunk-X3DMMX27.js +11 -0
  133. package/dist/chunk-YHMRX6YA.js +455 -0
  134. package/dist/components/index.css +1756 -0
  135. package/dist/components/index.d.ts +11299 -0
  136. package/dist/components/index.js +1110 -0
  137. package/dist/context/index.d.ts +8 -0
  138. package/dist/context/index.js +8 -0
  139. package/dist/core.d.ts +2599 -0
  140. package/dist/core.js +3 -0
  141. package/dist/design-classes/index.cjs +431 -0
  142. package/dist/design-classes/index.d.cts +165 -0
  143. package/dist/design-classes/index.d.ts +165 -0
  144. package/dist/design-classes/index.js +399 -0
  145. package/dist/emojiItems-QGSNAABW.js +20 -0
  146. package/dist/fx-CmQjnHmT.d.ts +371 -0
  147. package/dist/hooks/index.d.ts +971 -0
  148. package/dist/hooks/index.js +8 -0
  149. package/dist/index.d.ts +408 -0
  150. package/dist/index.js +178 -0
  151. package/dist/katexPlugin-FA7NX4PE.css +1161 -0
  152. package/dist/katexPlugin-NCDKOOQY.js +2 -0
  153. package/dist/kernel-client-TZKGHJRY.js +516 -0
  154. package/dist/kernel-wire-wNdAPfhJ.d.ts +88 -0
  155. package/dist/lib/index.d.ts +602 -0
  156. package/dist/lib/index.js +1289 -0
  157. package/dist/paintDispatch-CuJLsr9Y.d.ts +688 -0
  158. package/dist/parseLessonSegments-GpCeMrb2.d.ts +334 -0
  159. package/dist/perf-CKiBKbkw.d.ts +22 -0
  160. package/dist/perf-Dr28-AgT.d.ts +57 -0
  161. package/dist/prism-X5YWKXO5.js +136 -0
  162. package/dist/providers/index.css +1756 -0
  163. package/dist/providers/index.d.ts +355 -0
  164. package/dist/providers/index.js +29 -0
  165. package/dist/renderer/index.d.ts +465 -0
  166. package/dist/renderer/index.js +4 -0
  167. package/dist/runtime/index.css +1756 -0
  168. package/dist/runtime/index.d.ts +239 -0
  169. package/dist/runtime/index.js +28 -0
  170. package/dist/slot-host-CPzrxLo9.d.ts +48 -0
  171. package/dist/ssr/index.cjs +9739 -0
  172. package/dist/ssr/index.d.cts +464 -0
  173. package/dist/ssr/index.d.ts +464 -0
  174. package/dist/ssr/index.js +9703 -0
  175. package/dist/storage/browser/index.d.ts +1 -0
  176. package/dist/storage/browser/index.js +2 -0
  177. package/dist/test-support.d.ts +42 -0
  178. package/dist/test-support.js +181 -0
  179. package/dist/themeTokens-CRd8AEDF.d.ts +125 -0
  180. package/dist/three/index.css +503 -0
  181. package/dist/three/index.d.ts +1185 -0
  182. package/dist/three/index.js +3908 -0
  183. package/dist/useUISlots-CiobNFGb.d.ts +211 -0
  184. package/dist/verification-C5pTeMJv.d.ts +66 -0
  185. package/dist/verificationRegistry-CVrcxG1s.d.ts +122 -0
  186. package/dist/wrapCallbackForEvent-B9QLbhxX.d.ts +19 -0
  187. package/index.css +199 -0
  188. package/package.json +273 -3
  189. package/src/core/lib/band-shapes.json +7 -0
  190. package/src/core/locales/ar.json +1276 -0
  191. package/src/core/locales/en.json +1276 -0
  192. package/src/core/locales/index.ts +54 -0
  193. package/src/core/locales/sl.json +1276 -0
  194. package/src/core/tokens/native-tokens.json +369 -0
  195. package/tailwind-compile.cjs +29 -0
  196. package/tailwind-preset.cjs +1020 -0
  197. package/themes/_base.css +451 -0
  198. package/themes/_contract.md +307 -0
  199. package/themes/_fonts-kenney.css +11 -0
  200. package/themes/_fonts.css +12 -0
  201. package/themes/_foundation.css +105 -0
  202. package/themes/_head.css +22 -0
  203. package/themes/_presets.css +67 -0
  204. package/themes/almadar-heritage.css +455 -0
  205. package/themes/almadar-website.css +269 -0
  206. package/themes/almadar.css +269 -0
  207. package/themes/aqua.css +455 -0
  208. package/themes/arabesque.css +459 -0
  209. package/themes/art-deco.css +457 -0
  210. package/themes/art-nouveau.css +459 -0
  211. package/themes/atelier.css +463 -0
  212. package/themes/bauhaus.css +461 -0
  213. package/themes/bloomberg-dense.css +463 -0
  214. package/themes/blueprint.css +457 -0
  215. package/themes/clay.css +449 -0
  216. package/themes/comic.css +453 -0
  217. package/themes/constructivist.css +457 -0
  218. package/themes/corporate.css +449 -0
  219. package/themes/cyberpunk.css +453 -0
  220. package/themes/frutiger-aero.css +458 -0
  221. package/themes/game-adventure.css +201 -0
  222. package/themes/game-rpg.css +203 -0
  223. package/themes/game-sci-fi.css +201 -0
  224. package/themes/game-ui-pack.css +200 -0
  225. package/themes/gazette.css +449 -0
  226. package/themes/glass.css +457 -0
  227. package/themes/gothic.css +453 -0
  228. package/themes/index.css +21 -0
  229. package/themes/ink-wash.css +459 -0
  230. package/themes/kawaii.css +459 -0
  231. package/themes/kflow.css +310 -0
  232. package/themes/kiosk.css +449 -0
  233. package/themes/linear-clean.css +463 -0
  234. package/themes/luxury.css +451 -0
  235. package/themes/mac-classic.css +455 -0
  236. package/themes/material.css +463 -0
  237. package/themes/memphis.css +453 -0
  238. package/themes/mid-century.css +455 -0
  239. package/themes/minimalist.css +449 -0
  240. package/themes/mudcloth.css +459 -0
  241. package/themes/nata.css +310 -0
  242. package/themes/neon.css +453 -0
  243. package/themes/neumorphic.css +451 -0
  244. package/themes/newsprint.css +455 -0
  245. package/themes/notion-editorial.css +463 -0
  246. package/themes/orb.css +465 -0
  247. package/themes/pixel.css +449 -0
  248. package/themes/prism.css +309 -0
  249. package/themes/rawi.css +310 -0
  250. package/themes/retro.css +452 -0
  251. package/themes/risograph.css +463 -0
  252. package/themes/scandi.css +469 -0
  253. package/themes/sketch.css +455 -0
  254. package/themes/solarpunk.css +469 -0
  255. package/themes/steampunk.css +451 -0
  256. package/themes/swiss.css +455 -0
  257. package/themes/terminal.css +466 -0
  258. package/themes/trait-wars.css +487 -0
  259. package/themes/ukiyo-e.css +459 -0
  260. package/themes/vaporwave.css +455 -0
  261. package/themes/victorian.css +453 -0
  262. package/themes/wabi-sabi.css +459 -0
  263. package/themes/win95.css +455 -0
  264. package/themes/wireframe.css +439 -0
  265. package/themes/zine.css +455 -0
  266. package/README.md +0 -3
@@ -0,0 +1,505 @@
1
+ import { AvlEffect } from './chunk-DZBQA2OW.js';
2
+ import { effectCategoryOf } from './chunk-UXLE3IPR.js';
3
+ import { useThemeScope, Box, useTapReveal, Typography, cn, domPassthrough, usePresence, useDialogBehavior, SurfaceBoundary, VStack, useTranslate } from './chunk-4YXBKHHM.js';
4
+ import { createPortal } from 'react-dom';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
+ import React, { useId, useState, useRef, useLayoutEffect, useEffect } from 'react';
7
+ import { getStdOperatorMeta } from '@almadar/std/registry';
8
+
9
+ // src/lib/portalRoot.ts
10
+ function getOrCreatePortalRoot() {
11
+ let root = document.getElementById("ui-slot-portal-root");
12
+ if (!root) {
13
+ root = document.createElement("div");
14
+ root.id = "ui-slot-portal-root";
15
+ root.style.position = "relative";
16
+ root.style.zIndex = "9999";
17
+ document.body.appendChild(root);
18
+ }
19
+ return root;
20
+ }
21
+ function ThemedPortal({ children, container }) {
22
+ const { theme, mode, vars } = useThemeScope();
23
+ const scoped = theme !== void 0 || vars !== void 0;
24
+ return createPortal(
25
+ scoped ? /* @__PURE__ */ jsx(Box, { "data-theme": theme, className: mode ? `contents ${mode}` : "contents", style: vars, children }) : children,
26
+ container ?? getOrCreatePortalRoot()
27
+ );
28
+ }
29
+ var TRIGGER_GAP = 8;
30
+ var arrowClasses = {
31
+ top: "top-full left-1/2 -translate-x-1/2 border-t-primary border-l-transparent border-r-transparent border-b-transparent",
32
+ bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-primary border-l-transparent border-r-transparent border-t-transparent",
33
+ left: "left-full top-1/2 -translate-y-1/2 border-l-primary border-t-transparent border-b-transparent border-r-transparent",
34
+ right: "right-full top-1/2 -translate-y-1/2 border-r-primary border-t-transparent border-b-transparent border-l-transparent"
35
+ };
36
+ function computeTooltipStyle(position, triggerRect) {
37
+ switch (position) {
38
+ case "bottom":
39
+ return {
40
+ left: triggerRect.left + triggerRect.width / 2,
41
+ top: triggerRect.bottom + TRIGGER_GAP,
42
+ transform: "translateX(-50%)"
43
+ };
44
+ case "left":
45
+ return {
46
+ left: triggerRect.left - TRIGGER_GAP,
47
+ top: triggerRect.top + triggerRect.height / 2,
48
+ transform: "translate(-100%, -50%)"
49
+ };
50
+ case "right":
51
+ return {
52
+ left: triggerRect.right + TRIGGER_GAP,
53
+ top: triggerRect.top + triggerRect.height / 2,
54
+ transform: "translateY(-50%)"
55
+ };
56
+ case "top":
57
+ default:
58
+ return {
59
+ left: triggerRect.left + triggerRect.width / 2,
60
+ top: triggerRect.top - TRIGGER_GAP,
61
+ transform: "translate(-50%, -100%)"
62
+ };
63
+ }
64
+ }
65
+ var Tooltip = ({
66
+ content,
67
+ children,
68
+ position = "top",
69
+ delay = 200,
70
+ hideDelay = 0,
71
+ showArrow = true,
72
+ className,
73
+ ...rest
74
+ }) => {
75
+ const tooltipId = useId();
76
+ const [isVisible, setIsVisible] = useState(false);
77
+ const [triggerRect, setTriggerRect] = useState(null);
78
+ const triggerRef = useRef(null);
79
+ const tooltipRef = useRef(null);
80
+ const showTimeoutRef = useRef(null);
81
+ const hideTimeoutRef = useRef(null);
82
+ const updatePosition = () => {
83
+ if (triggerRef.current) {
84
+ setTriggerRect(triggerRef.current.getBoundingClientRect());
85
+ }
86
+ };
87
+ const handleMouseEnter = () => {
88
+ if (hideTimeoutRef.current) {
89
+ clearTimeout(hideTimeoutRef.current);
90
+ }
91
+ updatePosition();
92
+ showTimeoutRef.current = setTimeout(() => {
93
+ setIsVisible(true);
94
+ }, delay);
95
+ };
96
+ const handleMouseLeave = () => {
97
+ if (showTimeoutRef.current) {
98
+ clearTimeout(showTimeoutRef.current);
99
+ }
100
+ hideTimeoutRef.current = setTimeout(() => {
101
+ setIsVisible(false);
102
+ }, hideDelay);
103
+ };
104
+ const { triggerProps } = useTapReveal({
105
+ onReveal: handleMouseEnter,
106
+ onDismiss: handleMouseLeave,
107
+ refs: [triggerRef, tooltipRef]
108
+ });
109
+ useLayoutEffect(() => {
110
+ if (isVisible) {
111
+ updatePosition();
112
+ }
113
+ }, [isVisible]);
114
+ useEffect(() => {
115
+ if (!isVisible) return;
116
+ const onKeyDown = (e) => {
117
+ if (e.key !== "Escape") return;
118
+ if (showTimeoutRef.current) clearTimeout(showTimeoutRef.current);
119
+ setIsVisible(false);
120
+ };
121
+ document.addEventListener("keydown", onKeyDown);
122
+ return () => document.removeEventListener("keydown", onKeyDown);
123
+ }, [isVisible]);
124
+ useEffect(() => {
125
+ return () => {
126
+ if (showTimeoutRef.current) clearTimeout(showTimeoutRef.current);
127
+ if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
128
+ };
129
+ }, []);
130
+ const triggerElement = React.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
131
+ const child = triggerElement;
132
+ const childRef = child.props.ref ?? child.ref;
133
+ const setTriggerRef = (el) => {
134
+ triggerRef.current = el;
135
+ if (typeof childRef === "function") childRef(el);
136
+ else if (childRef) childRef.current = el;
137
+ };
138
+ const trigger = React.cloneElement(child, {
139
+ ref: setTriggerRef,
140
+ "aria-describedby": isVisible ? [child.props["aria-describedby"], tooltipId].filter(Boolean).join(" ") : child.props["aria-describedby"],
141
+ onMouseEnter: (e) => {
142
+ child.props.onMouseEnter?.(e);
143
+ handleMouseEnter();
144
+ },
145
+ onMouseLeave: (e) => {
146
+ child.props.onMouseLeave?.(e);
147
+ handleMouseLeave();
148
+ },
149
+ onFocus: (e) => {
150
+ child.props.onFocus?.(e);
151
+ handleMouseEnter();
152
+ },
153
+ onBlur: (e) => {
154
+ child.props.onBlur?.(e);
155
+ handleMouseLeave();
156
+ },
157
+ onPointerDown: (e) => {
158
+ triggerProps.onPointerDown(e);
159
+ child.props.onPointerDown?.(e);
160
+ }
161
+ });
162
+ const tooltipContent = isVisible && triggerRect ? /* @__PURE__ */ jsxs(
163
+ "div",
164
+ {
165
+ ref: tooltipRef,
166
+ ...domPassthrough(rest),
167
+ id: tooltipId,
168
+ className: cn(
169
+ "fixed z-50 px-3 py-2 max-w-xs",
170
+ "bg-primary text-primary-foreground",
171
+ "shadow-elevation-popover rounded-container",
172
+ "text-sm pointer-events-none",
173
+ "break-words whitespace-normal",
174
+ "h-auto min-h-fit",
175
+ className
176
+ ),
177
+ style: computeTooltipStyle(position, triggerRect),
178
+ role: "tooltip",
179
+ children: [
180
+ /* @__PURE__ */ jsx("div", { className: "w-full break-words whitespace-normal h-auto", children: typeof content === "string" ? /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-primary-foreground break-words whitespace-normal", children: content }) : /* @__PURE__ */ jsx("div", { className: "break-words whitespace-normal", children: content }) }),
181
+ showArrow && /* @__PURE__ */ jsx(
182
+ "div",
183
+ {
184
+ className: cn(
185
+ "absolute w-0 h-0 border-heavy",
186
+ arrowClasses[position]
187
+ )
188
+ }
189
+ )
190
+ ]
191
+ }
192
+ ) : null;
193
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
194
+ trigger,
195
+ typeof window !== "undefined" && tooltipContent ? /* @__PURE__ */ jsx(ThemedPortal, { children: tooltipContent }) : tooltipContent
196
+ ] });
197
+ };
198
+ Tooltip.displayName = "Tooltip";
199
+ var INTERACTIVE_SELECTOR = 'button, a[href], input, select, textarea, [role="button"], [tabindex]:not([tabindex="-1"])';
200
+ var HOVER_CLOSE_DELAY_MS = 150;
201
+ var arrowClasses2 = {
202
+ top: "top-full left-1/2 -translate-x-1/2 border-t-white border-l-transparent border-r-transparent border-b-transparent",
203
+ bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-white border-l-transparent border-r-transparent border-t-transparent",
204
+ left: "left-full top-1/2 -translate-y-1/2 border-l-white border-t-transparent border-b-transparent border-r-transparent",
205
+ right: "right-full top-1/2 -translate-y-1/2 border-r-white border-t-transparent border-b-transparent border-l-transparent"
206
+ };
207
+ var VIEWPORT_EDGE_PADDING = 8;
208
+ var TRIGGER_GAP2 = 8;
209
+ function placePopover(position, trigger, panel, viewport) {
210
+ const clamp = (value, size, extent) => Math.max(VIEWPORT_EDGE_PADDING, Math.min(value, Math.max(VIEWPORT_EDGE_PADDING, extent - size - VIEWPORT_EDGE_PADDING)));
211
+ if (position === "left" || position === "right") {
212
+ const rightLeft = trigger.right + TRIGGER_GAP2;
213
+ const leftLeft = trigger.left - panel.width - TRIGGER_GAP2;
214
+ const fitsRight = rightLeft + panel.width <= viewport.width - VIEWPORT_EDGE_PADDING;
215
+ const fitsLeft = leftLeft >= VIEWPORT_EDGE_PADDING;
216
+ const side2 = position === "right" ? fitsRight || !fitsLeft ? "right" : "left" : fitsLeft || !fitsRight ? "left" : "right";
217
+ const left2 = clamp(side2 === "right" ? rightLeft : leftLeft, panel.width, viewport.width);
218
+ const top2 = clamp(trigger.top + trigger.height / 2 - panel.height / 2, panel.height, viewport.height);
219
+ return { side: side2, left: left2, top: top2 };
220
+ }
221
+ const aboveTop = trigger.top - TRIGGER_GAP2 - panel.height;
222
+ const belowTop = trigger.bottom + TRIGGER_GAP2;
223
+ const fitsAbove = aboveTop >= VIEWPORT_EDGE_PADDING;
224
+ const fitsBelow = belowTop + panel.height <= viewport.height - VIEWPORT_EDGE_PADDING;
225
+ const side = position === "top" ? fitsAbove || !fitsBelow ? "top" : "bottom" : fitsBelow || !fitsAbove ? "bottom" : "top";
226
+ const left = clamp(trigger.left + trigger.width / 2 - panel.width / 2, panel.width, viewport.width);
227
+ const top = clamp(side === "top" ? aboveTop : belowTop, panel.height, viewport.height);
228
+ return { side, left, top };
229
+ }
230
+ var Popover = ({
231
+ content,
232
+ children,
233
+ position = "bottom",
234
+ trigger = "click",
235
+ showArrow = true,
236
+ open,
237
+ onOpenChange,
238
+ className,
239
+ ...rest
240
+ }) => {
241
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
242
+ const isOpen = open !== void 0 ? open : uncontrolledOpen;
243
+ const setIsOpen = (next) => {
244
+ if (open === void 0) setUncontrolledOpen(next);
245
+ onOpenChange?.(next);
246
+ };
247
+ const [triggerRect, setTriggerRect] = useState(null);
248
+ const [panelSize, setPanelSize] = useState({ width: 0, height: 0 });
249
+ const popoverWidth = panelSize.width;
250
+ const triggerRef = useRef(null);
251
+ const popoverRef = useRef(null);
252
+ const { mounted, className: panelAnim, onAnimationEnd } = usePresence(isOpen, { animation: "popover" });
253
+ const updatePosition = () => {
254
+ if (triggerRef.current) {
255
+ setTriggerRect(triggerRef.current.getBoundingClientRect());
256
+ }
257
+ if (popoverRef.current) {
258
+ setPanelSize({ width: popoverRef.current.offsetWidth, height: popoverRef.current.offsetHeight });
259
+ }
260
+ };
261
+ const handleOpen = () => {
262
+ updatePosition();
263
+ setIsOpen(true);
264
+ };
265
+ const handleClose = () => {
266
+ cancelHoverClose();
267
+ setIsOpen(false);
268
+ };
269
+ const closeTimer = useRef(null);
270
+ const cancelHoverClose = () => {
271
+ if (closeTimer.current !== null) clearTimeout(closeTimer.current);
272
+ closeTimer.current = null;
273
+ };
274
+ const scheduleHoverClose = () => {
275
+ cancelHoverClose();
276
+ closeTimer.current = setTimeout(handleClose, HOVER_CLOSE_DELAY_MS);
277
+ };
278
+ const hoverOpen = () => {
279
+ cancelHoverClose();
280
+ if (!isOpen) handleOpen();
281
+ };
282
+ useEffect(() => cancelHoverClose, []);
283
+ const panelId = useId();
284
+ const focusReturnRef = useRef(null);
285
+ useDialogBehavior({ open: isOpen, containerRef: popoverRef, onEscape: handleClose, modal: false, ...trigger === "click" ? { returnFocusRef: focusReturnRef } : {} });
286
+ const handleToggle = () => {
287
+ if (isOpen) {
288
+ handleClose();
289
+ } else {
290
+ handleOpen();
291
+ }
292
+ };
293
+ useEffect(() => {
294
+ if (isOpen) {
295
+ updatePosition();
296
+ }
297
+ }, [isOpen]);
298
+ useEffect(() => {
299
+ if (!isOpen) return;
300
+ let raf = 0;
301
+ let lastTop = Number.NaN;
302
+ let lastLeft = Number.NaN;
303
+ const track = () => {
304
+ const rect = triggerRef.current?.getBoundingClientRect();
305
+ if (rect && (rect.top !== lastTop || rect.left !== lastLeft)) {
306
+ lastTop = rect.top;
307
+ lastLeft = rect.left;
308
+ updatePosition();
309
+ }
310
+ raf = requestAnimationFrame(track);
311
+ };
312
+ raf = requestAnimationFrame(track);
313
+ return () => cancelAnimationFrame(raf);
314
+ }, [isOpen]);
315
+ useEffect(() => {
316
+ if (!mounted) setPanelSize({ width: 0, height: 0 });
317
+ }, [mounted]);
318
+ useLayoutEffect(() => {
319
+ if (isOpen && popoverRef.current) {
320
+ const width = popoverRef.current.offsetWidth;
321
+ const height = popoverRef.current.offsetHeight;
322
+ if (width !== panelSize.width || height !== panelSize.height) {
323
+ setPanelSize({ width, height });
324
+ }
325
+ }
326
+ });
327
+ useEffect(() => {
328
+ if (trigger !== "click") {
329
+ return;
330
+ }
331
+ const handleClickOutside = (e) => {
332
+ if (isOpen && popoverRef.current && !popoverRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
333
+ handleClose();
334
+ }
335
+ };
336
+ document.addEventListener("mousedown", handleClickOutside);
337
+ return () => document.removeEventListener("mousedown", handleClickOutside);
338
+ }, [isOpen, trigger]);
339
+ const { triggerProps: tapTriggerProps } = useTapReveal({
340
+ enabled: trigger === "hover",
341
+ onReveal: handleOpen,
342
+ onDismiss: handleClose,
343
+ refs: [triggerRef, popoverRef]
344
+ });
345
+ const handlerProps = trigger === "click" ? {
346
+ onClick: handleToggle
347
+ } : {
348
+ onMouseEnter: hoverOpen,
349
+ onMouseLeave: scheduleHoverClose,
350
+ onFocus: hoverOpen,
351
+ onBlur: scheduleHoverClose,
352
+ onPointerDown: tapTriggerProps.onPointerDown,
353
+ "data-popover-open": String(isOpen)
354
+ };
355
+ const wrapsContent = !React.isValidElement(children);
356
+ const [innerControl, setInnerControl] = useState(null);
357
+ useLayoutEffect(() => {
358
+ if (!wrapsContent || trigger !== "click") return;
359
+ setInnerControl(triggerRef.current?.querySelector(INTERACTIVE_SELECTOR) ?? null);
360
+ }, [wrapsContent, trigger, children]);
361
+ useLayoutEffect(() => {
362
+ focusReturnRef.current = innerControl ?? triggerRef.current;
363
+ });
364
+ useLayoutEffect(() => {
365
+ if (innerControl === null) return;
366
+ innerControl.setAttribute("aria-expanded", String(isOpen));
367
+ innerControl.setAttribute("aria-haspopup", "dialog");
368
+ if (mounted) innerControl.setAttribute("aria-controls", panelId);
369
+ else innerControl.removeAttribute("aria-controls");
370
+ }, [innerControl, isOpen, mounted, panelId]);
371
+ const triggerIsWrapper = innerControl === null;
372
+ const childElement = !wrapsContent ? children : trigger === "click" && triggerIsWrapper ? /* @__PURE__ */ jsx(
373
+ "span",
374
+ {
375
+ role: "button",
376
+ tabIndex: 0,
377
+ onKeyDown: (e) => {
378
+ if (e.key === "Enter" || e.key === " ") {
379
+ e.preventDefault();
380
+ handleToggle();
381
+ }
382
+ },
383
+ children
384
+ }
385
+ ) : /* @__PURE__ */ jsx("span", { children });
386
+ const childPointerDown = childElement.props.onPointerDown;
387
+ const triggerElement = React.cloneElement(
388
+ childElement,
389
+ {
390
+ ref: triggerRef,
391
+ ...handlerProps,
392
+ // Dialog semantics belong to a click-opened panel; a hover popover is a tooltip.
393
+ ...trigger === "click" && triggerIsWrapper ? {
394
+ "aria-expanded": isOpen,
395
+ "aria-haspopup": "dialog",
396
+ ...mounted ? { "aria-controls": panelId } : void 0
397
+ } : void 0,
398
+ ...trigger === "hover" ? {
399
+ onPointerDown: (e) => {
400
+ tapTriggerProps.onPointerDown(e);
401
+ childPointerDown?.(e);
402
+ }
403
+ } : void 0
404
+ }
405
+ );
406
+ const placement = triggerRect ? placePopover(position, triggerRect, panelSize, {
407
+ width: typeof window !== "undefined" ? window.innerWidth : 1024,
408
+ height: typeof window !== "undefined" ? window.innerHeight : 768
409
+ }) : null;
410
+ const panel = mounted && placement ? /* @__PURE__ */ jsxs(
411
+ "div",
412
+ {
413
+ ref: popoverRef,
414
+ className: cn(
415
+ "fixed z-50 p-4",
416
+ "bg-card surface-material rounded-container border-heavy border-border shadow-elevation-popover",
417
+ panelAnim,
418
+ className
419
+ ),
420
+ style: {
421
+ left: placement.left,
422
+ top: placement.top,
423
+ // Sized by its content, not by the room right of `left`: a placement-dependent width re-places it forever.
424
+ width: "max-content",
425
+ maxWidth: `calc(100vw - ${2 * VIEWPORT_EDGE_PADDING}px)`,
426
+ ...popoverWidth === 0 ? { visibility: "hidden" } : void 0
427
+ },
428
+ ...domPassthrough(rest),
429
+ id: panelId,
430
+ role: "dialog",
431
+ "aria-label": rest["aria-label"] ?? (typeof content === "string" ? content : void 0),
432
+ onAnimationEnd,
433
+ onMouseEnter: trigger === "hover" ? hoverOpen : void 0,
434
+ onMouseLeave: trigger === "hover" ? scheduleHoverClose : void 0,
435
+ children: [
436
+ typeof content === "string" ? /* @__PURE__ */ jsx(Typography, { variant: "body", children: content }) : /* @__PURE__ */ jsx(SurfaceBoundary, { children: content }),
437
+ showArrow && /* @__PURE__ */ jsx(
438
+ "div",
439
+ {
440
+ className: cn(
441
+ "absolute w-0 h-0 border-heavy",
442
+ arrowClasses2[placement.side]
443
+ )
444
+ }
445
+ )
446
+ ]
447
+ }
448
+ ) : null;
449
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
450
+ triggerElement,
451
+ panel && typeof document !== "undefined" ? /* @__PURE__ */ jsx(ThemedPortal, { children: panel }) : panel
452
+ ] });
453
+ };
454
+ Popover.displayName = "Popover";
455
+ var AvlExplain = ({ lines, note, code, children }) => {
456
+ if (note !== void 0 || code !== void 0) {
457
+ return /* @__PURE__ */ jsx(
458
+ Popover,
459
+ {
460
+ trigger: "hover",
461
+ position: "top",
462
+ content: /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "max-w-sm", children: [
463
+ note?.title ? /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "semibold", children: note.title }) : null,
464
+ note ? /* @__PURE__ */ jsx(Typography, { variant: "small", children: note.body }) : null,
465
+ /* @__PURE__ */ jsx(VStack, { gap: "none", className: note ? "border-t border-border pt-1" : void 0, children: lines.map((line, i) => /* @__PURE__ */ jsx(Typography, { variant: "caption", color: i === 0 ? "inherit" : "muted", weight: i === 0 ? "semibold" : "normal", children: line }, i)) }),
466
+ code === void 0 ? null : /* @__PURE__ */ jsx(
467
+ Box,
468
+ {
469
+ as: "pre",
470
+ dir: "ltr",
471
+ "data-testid": "avl-explain-code",
472
+ className: "m-0 max-h-48 overflow-auto rounded-sm bg-muted px-2 py-1 font-mono text-xs whitespace-pre",
473
+ children: code
474
+ }
475
+ )
476
+ ] }),
477
+ children
478
+ }
479
+ );
480
+ }
481
+ if (lines.length === 0) return children;
482
+ return /* @__PURE__ */ jsx(
483
+ Tooltip,
484
+ {
485
+ position: "top",
486
+ content: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => /* @__PURE__ */ jsx(Box, { as: "span", className: i === 0 ? "font-semibold" : "opacity-80", children: line }, i)) }),
487
+ children
488
+ }
489
+ );
490
+ };
491
+ AvlExplain.displayName = "AvlExplain";
492
+ function useEffectLines(effectType) {
493
+ const { t } = useTranslate();
494
+ const category = effectCategoryOf(effectType);
495
+ const description = getStdOperatorMeta(effectType)?.description;
496
+ return [effectType, ...category ? [t(`avl.effectCategory.${category}`)] : [], ...description ? [description] : []];
497
+ }
498
+ var AvlEffectChip = ({ effectType, size = 16, note, code }) => {
499
+ const lines = useEffectLines(effectType);
500
+ const half = size / 2;
501
+ return /* @__PURE__ */ jsx(AvlExplain, { lines, note, code, children: /* @__PURE__ */ jsx(Box, { as: "span", role: "img", tabIndex: 0, "aria-label": effectType, "data-testid": "avl-effect-chip", className: "inline-flex shrink-0 rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, "aria-hidden": "true", children: /* @__PURE__ */ jsx(AvlEffect, { x: half, y: half, effectType, size: half / 1.2 - 0.5, showBackground: true }) }) }) });
502
+ };
503
+ AvlEffectChip.displayName = "AvlEffectChip";
504
+
505
+ export { AvlEffectChip, AvlExplain, Popover, ThemedPortal, Tooltip, getOrCreatePortalRoot, useEffectLines };