this.gui 1.3.41 → 1.3.42

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 (310) hide show
  1. package/package.json +3 -2
  2. package/src/GUI.tsx +46 -0
  3. package/src/QRouter/QRegistry.tsx +53 -0
  4. package/src/QRouter/QRouter.stories.tsx +31 -0
  5. package/src/QRouter/QRouter.tsx +57 -0
  6. package/src/gui/Theme/GuiProvider.tsx +111 -0
  7. package/src/gui/Theme/Icon/Icon.resolver.tsx +29 -0
  8. package/src/gui/Theme/Icon/Icon.tsx +43 -0
  9. package/src/gui/Theme/Layout/Content/Content.resolver.tsx +0 -0
  10. package/src/gui/Theme/Layout/Content/Content.stories.tsx +88 -0
  11. package/src/gui/Theme/Layout/Content/Content.tsx +53 -0
  12. package/src/gui/Theme/Layout/Content/Content.types.tsx +40 -0
  13. package/src/gui/Theme/Layout/Footer/Footer.resolver.tsx +45 -0
  14. package/src/gui/Theme/Layout/Footer/Footer.stories.tsx +205 -0
  15. package/src/gui/Theme/Layout/Footer/Footer.tsx +337 -0
  16. package/src/gui/Theme/Layout/Footer/Footer.types.ts +40 -0
  17. package/src/gui/Theme/Layout/Layout/Layout.resolver.tsx +37 -0
  18. package/src/gui/Theme/Layout/Layout/Layout.stories.tsx +289 -0
  19. package/src/gui/Theme/Layout/Layout/Layout.tsx +117 -0
  20. package/src/gui/Theme/Layout/Layout/Layout.types.ts +57 -0
  21. package/src/gui/Theme/Layout/Layout/useLayoutBreakpoints.ts +9 -0
  22. package/src/gui/Theme/Layout/Namespace/Namespace.stories.tsx +105 -0
  23. package/src/gui/Theme/Layout/Namespace/Namespace.tsx +26 -0
  24. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/LeftSidebar.resolver.tsx +87 -0
  25. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/LeftSidebar.stories.tsx +199 -0
  26. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/LeftSidebar.tsx +311 -0
  27. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/LeftSidebar.types.ts +41 -0
  28. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/SidebarToggleButton.tsx +53 -0
  29. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarAction/LeftSidebarAction.resolver.tsx +19 -0
  30. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarAction/LeftSidebarAction.tsx +107 -0
  31. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.resolver.tsx +0 -0
  32. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.tsx +134 -0
  33. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.types.ts +15 -0
  34. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarMenu/LeftSidebarMenu.tsx +142 -0
  35. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarToggleButton/LeftSidebarToggleButton.tsx +23 -0
  36. package/src/gui/Theme/Layout/Sidebars/RightSidebar/RightSidebar.resolver.tsx +35 -0
  37. package/src/gui/Theme/Layout/Sidebars/RightSidebar/RightSidebar.stories.tsx +239 -0
  38. package/src/gui/Theme/Layout/Sidebars/RightSidebar/RightSidebar.tsx +319 -0
  39. package/src/gui/Theme/Layout/Sidebars/RightSidebar/RightSidebar.types.ts +17 -0
  40. package/src/gui/Theme/Layout/Sidebars/RightSidebar/components/RightSidebarAction/RightSidebarAction.tsx +102 -0
  41. package/src/gui/Theme/Layout/Sidebars/RightSidebar/components/RightSidebarLink/RightSidebarLink.tsx +132 -0
  42. package/src/gui/Theme/Layout/Sidebars/RightSidebar/components/RightSidebarMenu/RightSidebarMenu.tsx +140 -0
  43. package/src/gui/Theme/Layout/Sidebars/RightSidebar/components/RightSidebarToggleButton/RightSidebarToggleButton.tsx +22 -0
  44. package/src/gui/Theme/Layout/StickyOptions/StickyOptionsTop.stories.tsx +469 -0
  45. package/src/gui/Theme/Layout/StickyOptions/StickyOptionsTop.tsx +489 -0
  46. package/src/gui/Theme/Layout/TopBar/TopBar.resolver.tsx +86 -0
  47. package/src/gui/Theme/Layout/TopBar/TopBar.stories.tsx +350 -0
  48. package/src/gui/Theme/Layout/TopBar/TopBar.tsx +292 -0
  49. package/src/gui/Theme/Layout/TopBar/TopBar.types.ts +39 -0
  50. package/src/gui/Theme/Layout/TopBar/components/TopBarAction/TopBarAction.stories.tsx +83 -0
  51. package/src/gui/Theme/Layout/TopBar/components/TopBarAction/TopBarAction.tsx +18 -0
  52. package/src/gui/Theme/Layout/TopBar/components/TopBarAction/TopBarAction.types.ts +4 -0
  53. package/src/gui/Theme/Layout/TopBar/components/TopBarLink/TopBarLink.stories.tsx +189 -0
  54. package/src/gui/Theme/Layout/TopBar/components/TopBarLink/TopBarLink.tsx +30 -0
  55. package/src/gui/Theme/Layout/TopBar/components/TopBarLink/TopBarLink.types.ts +9 -0
  56. package/src/gui/Theme/Layout/TopBar/components/TopBarMenu/TopBarMenu.resolver.tsx +14 -0
  57. package/src/gui/Theme/Layout/TopBar/components/TopBarMenu/TopBarMenu.stories.tsx +56 -0
  58. package/src/gui/Theme/Layout/TopBar/components/TopBarMenu/TopBarMenu.tsx +123 -0
  59. package/src/gui/Theme/Layout/TopBar/components/TopBarMenu/TopBarMenu.types.ts +44 -0
  60. package/src/gui/Theme/catalog/CherryByte/CherryByte.png +0 -0
  61. package/src/gui/Theme/catalog/CherryByte/dark.tokens.ts +47 -0
  62. package/src/gui/Theme/catalog/CherryByte/light.tokens.ts +47 -0
  63. package/src/gui/Theme/catalog/CherryByte/manifest.ts +24 -0
  64. package/src/gui/Theme/catalog/GhostShell/dark.tokens.ts +43 -0
  65. package/src/gui/Theme/catalog/GhostShell/ghost.png +0 -0
  66. package/src/gui/Theme/catalog/GhostShell/light.tokens.ts +39 -0
  67. package/src/gui/Theme/catalog/GhostShell/manifest.ts +24 -0
  68. package/src/gui/Theme/catalog/LunaHex/LunaHex.png +0 -0
  69. package/src/gui/Theme/catalog/LunaHex/dark.tokens.ts +34 -0
  70. package/src/gui/Theme/catalog/LunaHex/light.tokens.ts +74 -0
  71. package/src/gui/Theme/catalog/LunaHex/manifest.ts +24 -0
  72. package/src/gui/Theme/catalog/MUI/MUI.png +0 -0
  73. package/src/gui/Theme/catalog/MUI/dark.tokens.ts +58 -0
  74. package/src/gui/Theme/catalog/MUI/light.tokens.ts +74 -0
  75. package/src/gui/Theme/catalog/MUI/manifest.ts +24 -0
  76. package/src/gui/Theme/catalog/PrinceOfDarkness/dark.tokens.ts +48 -0
  77. package/src/gui/Theme/catalog/PrinceOfDarkness/light.tokens.ts +47 -0
  78. package/src/gui/Theme/catalog/PrinceOfDarkness/manifest.ts +24 -0
  79. package/src/gui/Theme/catalog/PrinceOfDarkness/prince.png +0 -0
  80. package/src/gui/Theme/catalog/PrinceOfDarkness/princeOfDarkness.png +0 -0
  81. package/src/gui/Theme/catalog/Seafoam/dark.tokens.ts +49 -0
  82. package/src/gui/Theme/catalog/Seafoam/light.tokens.ts +47 -0
  83. package/src/gui/Theme/catalog/Seafoam/manifest.ts +24 -0
  84. package/src/gui/Theme/catalog/Seafoam/seaFoam.png +0 -0
  85. package/src/gui/Theme/catalog/neurons/dark.tokens.ts +58 -0
  86. package/src/gui/Theme/catalog/neurons/light.tokens.ts +74 -0
  87. package/src/gui/Theme/catalog/neurons/manifest.ts +24 -0
  88. package/src/gui/Theme/catalog/neurons/neurons.me.png +0 -0
  89. package/src/gui/Theme/fromTokens.ts +272 -0
  90. package/src/gui/Theme/gui.css +31 -0
  91. package/src/gui/Theme/index.ts +17 -0
  92. package/src/gui/Theme/styles/buildShadows.ts +83 -0
  93. package/src/gui/Theme/styles/theme.tokens.ts +108 -0
  94. package/src/gui/Theme/utils/catalog.ts +61 -0
  95. package/src/gui/Theme/utils/persistence.ts +66 -0
  96. package/src/gui/Theme/utils/themeUtils.ts +34 -0
  97. package/src/gui/components/atoms/AppBar/AppBar.resolver.tsx +46 -0
  98. package/src/gui/components/atoms/AppBar/AppBar.stories.tsx +251 -0
  99. package/src/gui/components/atoms/AppBar/AppBar.tsx +107 -0
  100. package/src/gui/components/atoms/AppBar/AppBar.types.ts +28 -0
  101. package/src/gui/components/atoms/Avatar/Avatar.resolver.tsx +61 -0
  102. package/src/gui/components/atoms/Avatar/Avatar.stories.tsx +36 -0
  103. package/src/gui/components/atoms/Avatar/Avatar.tsx +14 -0
  104. package/src/gui/components/atoms/Box/Box.resolver.tsx +171 -0
  105. package/src/gui/components/atoms/Box/Box.stories.tsx +263 -0
  106. package/src/gui/components/atoms/Box/Box.tsx +15 -0
  107. package/src/gui/components/atoms/Button/Button.resolver.tsx +103 -0
  108. package/src/gui/components/atoms/Button/Button.stories.tsx +219 -0
  109. package/src/gui/components/atoms/Button/Button.tsx +40 -0
  110. package/src/gui/components/atoms/Card/Card.resolver.tsx +63 -0
  111. package/src/gui/components/atoms/Card/Card.stories.tsx +54 -0
  112. package/src/gui/components/atoms/Card/Card.tsx +13 -0
  113. package/src/gui/components/atoms/CardActions/CardActions.resolver.tsx +59 -0
  114. package/src/gui/components/atoms/CardActions/CardActions.stories.tsx +32 -0
  115. package/src/gui/components/atoms/CardActions/CardActions.tsx +14 -0
  116. package/src/gui/components/atoms/CardContent/CardContent.resolver.tsx +60 -0
  117. package/src/gui/components/atoms/CardContent/CardContent.stories.tsx +34 -0
  118. package/src/gui/components/atoms/CardContent/CardContent.tsx +13 -0
  119. package/src/gui/components/atoms/CardHeader/CardHeader.resolver.tsx +68 -0
  120. package/src/gui/components/atoms/CardHeader/CardHeader.stories.tsx +40 -0
  121. package/src/gui/components/atoms/CardHeader/CardHeader.tsx +12 -0
  122. package/src/gui/components/atoms/Collapse/Collapse.resolver.tsx +85 -0
  123. package/src/gui/components/atoms/Collapse/Collapse.stories.tsx +130 -0
  124. package/src/gui/components/atoms/Collapse/Collapse.tsx +17 -0
  125. package/src/gui/components/atoms/Divider/Divider.resolver.tsx +95 -0
  126. package/src/gui/components/atoms/Divider/Divider.stories.tsx +108 -0
  127. package/src/gui/components/atoms/Divider/Divider.tsx +14 -0
  128. package/src/gui/components/atoms/Drawer/Drawer.resolver.tsx +116 -0
  129. package/src/gui/components/atoms/Drawer/Drawer.stories.tsx +223 -0
  130. package/src/gui/components/atoms/Drawer/Drawer.tsx +25 -0
  131. package/src/gui/components/atoms/Grid/Grid.resolver.tsx +33 -0
  132. package/src/gui/components/atoms/Grid/Grid.stories.tsx +136 -0
  133. package/src/gui/components/atoms/Grid/Grid.tsx +15 -0
  134. package/src/gui/components/atoms/Grid/Grid.types.ts +9 -0
  135. package/src/gui/components/atoms/IconButton/IconButton.resolver.tsx +137 -0
  136. package/src/gui/components/atoms/IconButton/IconButton.stories.tsx +134 -0
  137. package/src/gui/components/atoms/IconButton/IconButton.tsx +22 -0
  138. package/src/gui/components/atoms/Link/Link.resolver.tsx +74 -0
  139. package/src/gui/components/atoms/Link/Link.stories.tsx +157 -0
  140. package/src/gui/components/atoms/Link/Link.tsx +36 -0
  141. package/src/gui/components/atoms/List/List.resolver.tsx +94 -0
  142. package/src/gui/components/atoms/List/List.stories.tsx +137 -0
  143. package/src/gui/components/atoms/List/List.tsx +20 -0
  144. package/src/gui/components/atoms/ListItem/ListItem.resolver.tsx +88 -0
  145. package/src/gui/components/atoms/ListItem/ListItem.stories.tsx +151 -0
  146. package/src/gui/components/atoms/ListItem/ListItem.tsx +19 -0
  147. package/src/gui/components/atoms/ListItemButton/ListItemButton.resolver.tsx +214 -0
  148. package/src/gui/components/atoms/ListItemButton/ListItemButton.stories.tsx +155 -0
  149. package/src/gui/components/atoms/ListItemButton/ListItemButton.tsx +15 -0
  150. package/src/gui/components/atoms/ListItemIcon/ListItemIcon.resolver.tsx +102 -0
  151. package/src/gui/components/atoms/ListItemIcon/ListItemIcon.stories.tsx +132 -0
  152. package/src/gui/components/atoms/ListItemIcon/ListItemIcon.tsx +11 -0
  153. package/src/gui/components/atoms/ListItemText/ListItemText.resolver.tsx +112 -0
  154. package/src/gui/components/atoms/ListItemText/ListItemText.stories.tsx +156 -0
  155. package/src/gui/components/atoms/ListItemText/ListItemText.tsx +15 -0
  156. package/src/gui/components/atoms/Menu/Menu.resolver.tsx +112 -0
  157. package/src/gui/components/atoms/Menu/Menu.stories.tsx +162 -0
  158. package/src/gui/components/atoms/Menu/Menu.tsx +17 -0
  159. package/src/gui/components/atoms/MenuItem/MenuItem.resolver.tsx +183 -0
  160. package/src/gui/components/atoms/MenuItem/MenuItem.stories.tsx +134 -0
  161. package/src/gui/components/atoms/MenuItem/MenuItem.tsx +14 -0
  162. package/src/gui/components/atoms/Paper/Paper.resolver.tsx +98 -0
  163. package/src/gui/components/atoms/Paper/Paper.stories.tsx +184 -0
  164. package/src/gui/components/atoms/Paper/Paper.tsx +15 -0
  165. package/src/gui/components/atoms/Section/Section.resolver.tsx +10 -0
  166. package/src/gui/components/atoms/Section/Section.stories.tsx +189 -0
  167. package/src/gui/components/atoms/Section/Section.tsx +76 -0
  168. package/src/gui/components/atoms/Section/Section.types.tsx +24 -0
  169. package/src/gui/components/atoms/Stack/Stack.resolver.tsx +94 -0
  170. package/src/gui/components/atoms/Stack/Stack.stories.tsx +160 -0
  171. package/src/gui/components/atoms/Stack/Stack.tsx +15 -0
  172. package/src/gui/components/atoms/Surface/Surface.resolver.tsx +37 -0
  173. package/src/gui/components/atoms/Surface/Surface.tsx +49 -0
  174. package/src/gui/components/atoms/Surface/Surface.types.ts +20 -0
  175. package/src/gui/components/atoms/Switch/Switch.resolver.tsx +53 -0
  176. package/src/gui/components/atoms/Switch/Switch.stories.tsx +236 -0
  177. package/src/gui/components/atoms/Switch/Switch.tsx +22 -0
  178. package/src/gui/components/atoms/Table/Body/TableBody.tsx +7 -0
  179. package/src/gui/components/atoms/Table/Cell/TableCell.tsx +18 -0
  180. package/src/gui/components/atoms/Table/Head/TableHead.tsx +9 -0
  181. package/src/gui/components/atoms/Table/Row/TableRow.tsx +20 -0
  182. package/src/gui/components/atoms/Table/Table.resolver.tsx +77 -0
  183. package/src/gui/components/atoms/Table/Table.stories.tsx +173 -0
  184. package/src/gui/components/atoms/Table/Table.tsx +20 -0
  185. package/src/gui/components/atoms/TextField/TextField.stories.tsx +25 -0
  186. package/src/gui/components/atoms/TextField/TextField.tsx +15 -0
  187. package/src/gui/components/atoms/Toolbar/Toolbar.resolver.tsx +60 -0
  188. package/src/gui/components/atoms/Toolbar/Toolbar.stories.tsx +155 -0
  189. package/src/gui/components/atoms/Toolbar/Toolbar.tsx +16 -0
  190. package/src/gui/components/atoms/Tooltip/Tooltip.resolver.tsx +142 -0
  191. package/src/gui/components/atoms/Tooltip/Tooltip.stories.tsx +117 -0
  192. package/src/gui/components/atoms/Tooltip/Tooltip.tsx +70 -0
  193. package/src/gui/components/atoms/Typography/Typography.resolver.tsx +158 -0
  194. package/src/gui/components/atoms/Typography/Typography.stories.tsx +222 -0
  195. package/src/gui/components/atoms/Typography/Typography.tsx +27 -0
  196. package/src/gui/components/atoms/Window/Nodes/node.ts +0 -0
  197. package/src/gui/components/atoms/Window/code/block/node.tsx +0 -0
  198. package/src/gui/components/atoms/Window/code/hugging.face.api.ts +11 -0
  199. package/src/gui/components/atoms/Window/connectors/index.ts +19 -0
  200. package/src/gui/components/atoms/Window/window.stories.tsx +20 -0
  201. package/src/gui/components/atoms/Window/window.tsx +636 -0
  202. package/src/gui/components/atoms/atoms.tsx +151 -0
  203. package/src/gui/components/atoms/index.ts +2 -0
  204. package/src/gui/components/generics/Cards/Gridme.jsx +52 -0
  205. package/src/gui/components/generics/Cards/LilBox.jsx +65 -0
  206. package/src/gui/components/generics/Cards/ModuleCard.jsx +106 -0
  207. package/src/gui/components/generics/Chats/FullChatBot.jsx +223 -0
  208. package/src/gui/components/generics/Code/CodeBlock.jsx +33 -0
  209. package/src/gui/components/generics/EmojiCursor/EmojiCursor.stories.tsx +153 -0
  210. package/src/gui/components/generics/EmojiCursor/EmojiCursor.tsx +23 -0
  211. package/src/gui/components/generics/Feedback/Callout.jsx +92 -0
  212. package/src/gui/components/generics/Layout/GridX.jsx +29 -0
  213. package/src/gui/components/generics/Layout/Hero2.jsx +132 -0
  214. package/src/gui/components/generics/Layout/PageContainer.jsx +29 -0
  215. package/src/gui/components/generics/Layout/PageDivider.jsx +20 -0
  216. package/src/gui/components/generics/Layout/Section.jsx +43 -0
  217. package/src/gui/components/generics/Layout/SectionHeader.jsx +21 -0
  218. package/src/gui/components/generics/Media/Img.jsx +58 -0
  219. package/src/gui/components/generics/Media/VideoEmbed.jsx +51 -0
  220. package/src/gui/components/generics/Organization/TableOfContents.jsx +51 -0
  221. package/src/gui/components/generics/Organization/Tabs.jsx +45 -0
  222. package/src/gui/components/generics/Text/TextList.jsx +41 -0
  223. package/src/gui/components/generics/Text/TextParagraph.jsx +28 -0
  224. package/src/gui/components/generics/Text/TextQuote.jsx +23 -0
  225. package/src/gui/components/generics/Text/TextTitle.jsx +44 -0
  226. package/src/gui/components/molecules/Dialog/Dialog.stories.tsx +18 -0
  227. package/src/gui/components/molecules/Dialog/Dialog.tsx +5 -0
  228. package/src/gui/components/molecules/Hero/Hero.stories.tsx +140 -0
  229. package/src/gui/components/molecules/Hero/Hero.tsx +152 -0
  230. package/src/gui/components/molecules/Hero/Hero.types.tsx +18 -0
  231. package/src/gui/components/molecules/Modal/Modal.resolver.tsx +38 -0
  232. package/src/gui/components/molecules/Modal/Modal.stories.tsx +82 -0
  233. package/src/gui/components/molecules/Modal/Modal.tsx +110 -0
  234. package/src/gui/components/molecules/Modal/Modal.types.ts +29 -0
  235. package/src/gui/components/molecules/Page/Page.stories.tsx +135 -0
  236. package/src/gui/components/molecules/Page/Page.tsx +94 -0
  237. package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.resolver.tsx +58 -0
  238. package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.stories.tsx +133 -0
  239. package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.tsx +101 -0
  240. package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.types.ts +29 -0
  241. package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.resolver.tsx +15 -0
  242. package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.stories.tsx +88 -0
  243. package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.tsx +167 -0
  244. package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.types.ts +34 -0
  245. package/src/gui/components/molecules/molecules.ts +49 -0
  246. package/src/gui/components/organisms/Blockchain/Blocks/BlocksTable.tsx +119 -0
  247. package/src/gui/components/organisms/Blockchain/Usernames/Identities.stories.tsx +20 -0
  248. package/src/gui/components/organisms/Blockchain/Usernames/QR.tsx +566 -0
  249. package/src/gui/components/organisms/Blockchain/Usernames/Usernames.tsx +448 -0
  250. package/src/gui/components/organisms/Blockchain/Usernames/identities.tsx +710 -0
  251. package/src/gui/components/organisms/Blockchain/blockchain.stories.tsx +17 -0
  252. package/src/gui/components/organisms/Blockchain/blockchain.tsx +368 -0
  253. package/src/gui/components/organisms/Blockchain/scripts/connection.ts +82 -0
  254. package/src/gui/components/organisms/Blockchain/scripts/match_face.ts +143 -0
  255. package/src/gui/components/organisms/HighLighter/HighLighter.stories.tsx +168 -0
  256. package/src/gui/components/organisms/HighLighter/HighLighter.tsx +420 -0
  257. package/src/gui/components/organisms/HighLighter/HighLightsDrawer.tsx +197 -0
  258. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/FaceRecognition.stories.tsx +312 -0
  259. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/FaceRecognition.tsx +765 -0
  260. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceCameraPermission.ts +70 -0
  261. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceLandmarker.ts +106 -0
  262. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceOverlay.ts +489 -0
  263. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceTemplate.ts +32 -0
  264. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceTemplateBurst.ts +178 -0
  265. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/verifyTemplate.ts +136 -0
  266. package/src/gui/components/organisms/IdentityNoise/IdentityNoise.tsx +403 -0
  267. package/src/gui/components/organisms/IdentityNoise/IndentityNoise.stories.tsx +15 -0
  268. package/src/gui/components/organisms/IdentityNoise/Noise/Noise.stories.tsx +206 -0
  269. package/src/gui/components/organisms/IdentityNoise/Noise/Noise.tsx +394 -0
  270. package/src/gui/components/organisms/IdentityNoise/Triad/QR.tsx +566 -0
  271. package/src/gui/components/organisms/IdentityNoise/Triad/Tiad.stories.tsx +6 -0
  272. package/src/gui/components/organisms/IdentityNoise/Triad/Triad.tsx +917 -0
  273. package/src/gui/components/organisms/IdentityNoise/Triad/handleCleak.ts +0 -0
  274. package/src/gui/components/organisms/IdentityNoise/Triad/identity.ts +31 -0
  275. package/src/gui/components/organisms/IdentityNoise/Triad/me/fundamentals/vectors/vectors.tsx +252 -0
  276. package/src/gui/components/organisms/IdentityNoise/Triad/me/me.stories.tsx +314 -0
  277. package/src/gui/components/organisms/IdentityNoise/Triad/me/me.tsx +0 -0
  278. package/src/gui/components/organisms/organisms.ts +15 -0
  279. package/src/gui/contexts/InsetsContext.tsx +40 -0
  280. package/src/gui/contexts/LeftSidebarContext.tsx +20 -0
  281. package/src/gui/contexts/RightSidebarContext.tsx +25 -0
  282. package/src/gui/contexts/ThemeContext.ts +34 -0
  283. package/src/gui/contexts/index.ts +4 -0
  284. package/src/gui/hooks/index.ts +11 -0
  285. package/src/gui/hooks/resolveColorToken.ts +39 -0
  286. package/src/gui/hooks/useCodeGen.ts +12 -0
  287. package/src/gui/hooks/useGuiMediaQuery.ts +18 -0
  288. package/src/gui/hooks/useGuiTheme.ts +18 -0
  289. package/src/gui/hooks/useInsets.ts +26 -0
  290. package/src/gui/hooks/useIsMobile.ts +13 -0
  291. package/src/gui/hooks/useIsTouchDevice.ts +25 -0
  292. package/src/gui/hooks/useLeftSidebar.ts +10 -0
  293. package/src/gui/hooks/useRightSidebar.ts +12 -0
  294. package/src/gui/hooks/useViewportKey.ts +19 -0
  295. package/src/gui/hooks/useViewportProp.ts +17 -0
  296. package/src/gui/registry/GuiRegistry.ts +19 -0
  297. package/src/gui/registry/factory.ts +12 -0
  298. package/src/gui/registry/index.ts +3 -0
  299. package/src/gui/registry/types.ts +6 -0
  300. package/src/gui/utils/nodeID.ts +11 -0
  301. package/src/registry/GuiRegistry.ts +19 -0
  302. package/src/stories/01.Home.mdx +22 -0
  303. package/src/stories/02.Understanding.This.GUI.mdx +149 -0
  304. package/src/stories/Theme/Palette.stories.tsx +86 -0
  305. package/src/stories/Theme/ThemeViewer.stories.tsx +91 -0
  306. package/src/stories/Theme/Typography.stories.jsx +211 -0
  307. package/src/stories/assets/this.GUI.png +0 -0
  308. package/src/types/gui.d.ts +67 -0
  309. package/src/types/theme.d.ts +191 -0
  310. package/src/types/viewport.ts +132 -0
@@ -0,0 +1,489 @@
1
+ import type * as React from 'react';
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
+ import { useGuiTheme } from '@/gui/hooks';
4
+ import type { GuiTheme } from '@/types/theme';
5
+ import Icon from '@/gui/Theme/Icon/Icon';
6
+ export type StickyItem = {
7
+ icon: React.ReactNode | string;
8
+ label?: string;
9
+ href?: string;
10
+ variant?: 'primary' | 'neutral';
11
+ trackId?: string;
12
+ ariaLabel?: string;
13
+ iconColor?: string; // palette key/path or CSS color
14
+ };
15
+
16
+ export type StickyPositioning = {
17
+ topOffset?: number | string;
18
+ maxWidth?: number | string;
19
+ mode?: 'sticky' | 'fixed';
20
+ reserveSpace?: boolean;
21
+ };
22
+
23
+ export type StickyBehavior = {
24
+ hideOnScrollDown?: boolean;
25
+ collapseToFabOnMobile?: boolean; // kept for backwards compatibility
26
+ iconOnlyOnMobile?: boolean;
27
+ mobileBreakpoint?: number;
28
+ hideThreshold?: number;
29
+ showThreshold?: number;
30
+ topGuard?: number;
31
+ };
32
+
33
+ export type StickyThemeOpts = {
34
+ elevation?: number;
35
+ blur?: number;
36
+ contrastMode?: 'auto' | 'light' | 'dark';
37
+ };
38
+
39
+ export type StickyVisibility = {
40
+ enabled?: boolean;
41
+ includeRoutes?: string[] | null;
42
+ excludeRoutes?: string[] | null;
43
+ };
44
+
45
+ export type StickyI18nOpts = {
46
+ useI18n?: boolean;
47
+ t?: (s: string) => string;
48
+ };
49
+
50
+ export type StickyOptionsTopProps = {
51
+ items?: StickyItem[];
52
+ mobileVersion?: 'pill' | 'icons';
53
+ positioning?: StickyPositioning;
54
+ behavior?: StickyBehavior;
55
+ theme?: StickyThemeOpts;
56
+ visibility?: StickyVisibility;
57
+ i18n?: StickyI18nOpts;
58
+ };
59
+ /**
60
+ * StickyOptions (this.GUI)
61
+ * A reusable sticky CTA menu that hangs below the navbar.
62
+ *
63
+ * Props shape (all optional unless noted):
64
+ * - items: Array<{ icon: ReactNode|string, label?: string, href?: string, variant?: 'primary'|'neutral', trackId?: string, ariaLabel?: string }>
65
+ * - positioning: { topOffset?: number|string, maxWidth?: number|string, mode?: 'sticky'|'fixed', reserveSpace?: boolean }
66
+ * - behavior: { hideOnScrollDown?: boolean, collapseToFabOnMobile?: boolean, iconOnlyOnMobile?: boolean, mobileBreakpoint?: number, hideThreshold?: number, showThreshold?: number, topGuard?: number }
67
+ * - theme: { elevation?: number, blur?: number, contrastMode?: 'auto'|'light'|'dark' }
68
+ * - visibility: { enabled?: boolean, includeRoutes?: string[]|null, excludeRoutes?: string[]|null }
69
+ * - i18n: { useI18n?: boolean }
70
+ * - mobileVersion: 'pill' | 'icons'
71
+ */
72
+
73
+ const StickyOptionsTop = ({
74
+ items = [],
75
+ mobileVersion = 'pill',
76
+ positioning = {},
77
+ behavior = {
78
+ hideOnScrollDown: false, // never hide on scroll
79
+ iconOnlyOnMobile: false, // keep text visible on mobile
80
+ mobileBreakpoint: 768
81
+ },
82
+ theme: themeOpts = {},
83
+ visibility = {},
84
+ i18n: i18nOpts = {}
85
+ }: StickyOptionsTopProps) => {
86
+ const muiTheme = (useGuiTheme() as GuiTheme) || ({} as GuiTheme);
87
+ // ---- Defaults
88
+ const {
89
+ topOffset = '0.55rem', // default separation from navbar (tighter default)
90
+ maxWidth = 800,
91
+ mode = 'sticky', // 'sticky' | 'fixed'
92
+ reserveSpace = false // when true, push content down by menu height + offset
93
+ } = positioning;
94
+
95
+ const {
96
+ hideOnScrollDown = false,
97
+ collapseToFabOnMobile = false, // backward-compat
98
+ iconOnlyOnMobile = false,
99
+ mobileBreakpoint = 768,
100
+ hideThreshold = 36, // px scrolled down before hiding
101
+ showThreshold = 12, // px scrolled up before showing again
102
+ topGuard = 20 // do not hide near top of page
103
+ } = behavior;
104
+
105
+ const iconsOnly = mobileVersion === 'icons' || (typeof iconOnlyOnMobile === 'boolean' ? iconOnlyOnMobile : collapseToFabOnMobile);
106
+
107
+ const {
108
+ elevation = 28,
109
+ blur = 9,
110
+ contrastMode = 'auto'
111
+ } = themeOpts;
112
+
113
+ const {
114
+ enabled = true,
115
+ includeRoutes = null,
116
+ excludeRoutes = null
117
+ } = visibility;
118
+
119
+ const { useI18n = false, t: tFn } = i18nOpts;
120
+
121
+ // ---- Translate helper
122
+ const translate: (s: string) => string =
123
+ useI18n && typeof tFn === 'function' ? tFn : (s: string) => s;
124
+
125
+ // Render icon helper: supports ReactNode or declarative string ("mui:Something" / "lucide:something")
126
+ const resolveIconColor = (iconColor?: string): { css?: string } => {
127
+ if (!iconColor) return {};
128
+ const token = iconColor.trim();
129
+
130
+ // Direct CSS color? (#hex, rgb(), hsl())
131
+ if (/^#|^rgb\(|^hsl\(/i.test(token)) {
132
+ return { css: token };
133
+ }
134
+
135
+ const pal: any = muiTheme?.palette;
136
+ if (!pal) return {};
137
+
138
+ // Support palette path notation like "text.secondary" or "action.active"
139
+ if (token.includes('.')) {
140
+ const val = token.split('.').reduce<any>((acc, k) => (acc ? acc[k] : undefined), pal);
141
+ if (typeof val === 'string') return { css: val };
142
+ if (val && typeof val === 'object' && typeof val.main === 'string') return { css: val.main };
143
+ if (val && typeof val === 'object' && typeof (val as any).default === 'string') return { css: (val as any).default };
144
+ return {};
145
+ }
146
+
147
+ // Top-level palette key (e.g., "primary", "info", "divider", "link")
148
+ const v = pal[token];
149
+ if (typeof v === 'string') return { css: v };
150
+ if (v && typeof v === 'object') {
151
+ if (typeof v.main === 'string') return { css: v.main };
152
+ if (typeof (v as any).default === 'string') return { css: (v as any).default };
153
+ }
154
+ return {};
155
+ };
156
+
157
+ const renderIconNode = (icon: React.ReactNode | string, iconColor?: string): React.ReactNode => {
158
+ if (!icon) return null;
159
+ // Direct React element: pass through (do not override color)
160
+ if (typeof icon !== 'string') return icon;
161
+
162
+ const colorInfo = resolveIconColor(iconColor);
163
+ const isMui = icon.toLowerCase().startsWith('mui:');
164
+ const isLucide = icon.toLowerCase().startsWith('lucide:');
165
+
166
+ // If a color was declared, map to the right prop for provider;
167
+ // otherwise, let Icon use theme-aware defaults.
168
+ const colorProps = colorInfo.css
169
+ ? (isMui ? { htmlColor: colorInfo.css } : { color: colorInfo.css })
170
+ : {};
171
+
172
+ // Refactor: use fontSize and iconColor props per new IconProps interface
173
+ const newColorProps = colorInfo.css
174
+ ? { iconColor: colorInfo.css }
175
+ : {};
176
+ return <Icon name={icon} fontSize={16} {...newColorProps} />;
177
+ };
178
+
179
+ // ---- Spacer measurement (optional content push)
180
+ const groupElRef = useRef<HTMLDivElement | null>(null);
181
+ const [groupHeight, setGroupHeight] = useState<number>(0);
182
+
183
+ useEffect(() => {
184
+ if (!reserveSpace) return;
185
+ const el = groupElRef.current;
186
+ if (!el) return;
187
+ const update = () => {
188
+ try { setGroupHeight(el.getBoundingClientRect().height || 0); } catch {}
189
+ };
190
+ update();
191
+ let ro: ResizeObserver | undefined;
192
+ if (typeof ResizeObserver !== 'undefined') {
193
+ ro = new ResizeObserver(() => update());
194
+ ro.observe(el);
195
+ }
196
+ window.addEventListener('resize', update);
197
+ return () => {
198
+ window.removeEventListener('resize', update);
199
+ if (ro) try { ro.disconnect(); } catch {}
200
+ };
201
+ }, [reserveSpace]);
202
+
203
+ const topOffsetCSS = typeof topOffset === 'number' ? `${topOffset}px` : String(topOffset);
204
+ // Read insets directly from GUI theme (source of truth set by GuiProvider / components)
205
+ const insetLeft = Math.max(0, Number(muiTheme?.layout?.insets?.left ?? 0));
206
+ const insetRight = Math.max(0, Number(muiTheme?.layout?.insets?.right ?? 0));
207
+ const navPx = Math.max(0, Number(muiTheme?.layout?.insets?.nav ?? 0));
208
+
209
+ // If there is a navbar (navPx > 0) we add the topOffset, else we stick to page top.
210
+ const effectiveTopOffset = navPx > 0 ? topOffsetCSS : '0px';
211
+ const topCSS = `calc(${navPx}px + ${effectiveTopOffset})`;
212
+ const spacerStyle: React.CSSProperties | undefined = reserveSpace ? { height: `calc(${topOffsetCSS} + ${groupHeight}px)` } : undefined;
213
+
214
+ // ---- Route-based visibility
215
+ const isRouteIncluded = useMemo<boolean>(() => {
216
+ if (!enabled) return false;
217
+ const path = typeof window !== 'undefined' ? window.location.pathname : '';
218
+ if (excludeRoutes && excludeRoutes.some((r) => path.startsWith(r))) return false;
219
+ if (includeRoutes && includeRoutes.length > 0) return includeRoutes.some((r) => path.startsWith(r));
220
+ return true;
221
+ }, [enabled, includeRoutes, excludeRoutes]);
222
+
223
+ // ---- Scroll hide behavior (with hysteresis)
224
+ const [hidden, setHidden] = useState<boolean>(false);
225
+ const lastY = useRef<number>(typeof window !== 'undefined' ? window.scrollY : 0);
226
+ const acc = useRef<number>(0);
227
+ const raf = useRef<number | null>(null);
228
+
229
+ useEffect(() => {
230
+ if (!hideOnScrollDown) return;
231
+
232
+ const onScroll = () => {
233
+ if (raf.current) return; // throttle to rAF
234
+ raf.current = requestAnimationFrame(() => {
235
+ const y = window.scrollY;
236
+ const dy = y - lastY.current;
237
+ lastY.current = y;
238
+
239
+ // Guard: don't hide near very top
240
+ if (y <= topGuard) {
241
+ acc.current = 0;
242
+ setHidden(false);
243
+ raf.current = null;
244
+ return;
245
+ }
246
+
247
+ // Accumulate deltas; reset when direction changes
248
+ if ((dy > 0 && acc.current < 0) || (dy < 0 && acc.current > 0)) acc.current = 0;
249
+ acc.current += dy;
250
+
251
+ if (acc.current > hideThreshold && !hidden) {
252
+ setHidden(true);
253
+ acc.current = 0; // reset after state change
254
+ } else if (acc.current < -showThreshold && hidden) {
255
+ setHidden(false);
256
+ acc.current = 0; // reset after state change
257
+ }
258
+ raf.current = null;
259
+ });
260
+ };
261
+
262
+ window.addEventListener('scroll', onScroll, { passive: true });
263
+ return () => {
264
+ window.removeEventListener('scroll', onScroll);
265
+ if (raf.current !== null) cancelAnimationFrame(raf.current as number);
266
+ };
267
+ }, [hideOnScrollDown, hideThreshold, showThreshold, topGuard, hidden]);
268
+
269
+ // ---- Colors from MUI theme with safe fallbacks
270
+ const colors = useMemo(() => {
271
+ const mode = muiTheme?.palette?.mode || 'dark';
272
+ const linkMain = muiTheme?.palette?.link?.main || 'rgb(0, 170, 150)';
273
+ const bgPaper = muiTheme?.palette?.background?.paper || (mode === 'dark' ? 'rgb(24,26,28)' : '#ffffff');
274
+ const bg = mode === 'dark' ? 'rgba(24,26,28,0.65)' : 'rgba(255,255,255,0.8)';
275
+ const border = muiTheme?.custom?.border || (mode === 'dark' ? 'rgba(255,255,255,0.14)' : 'rgba(0,0,0,0.1)');
276
+ const neutralBg = mode === 'dark' ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.04)';
277
+ const neutralBorder = mode === 'dark' ? 'rgba(255,255,255,0.18)' : 'rgba(0,0,0,0.08)';
278
+ const text = muiTheme?.palette?.text?.primary || (mode === 'dark' ? '#fff' : '#111');
279
+ return { linkMain, bgPaper, bg, border, neutralBg, neutralBorder, text, mode };
280
+ }, [muiTheme]);
281
+
282
+ // ---- Collapse to FAB on mobile
283
+ // Reusable size for mobile FAB layout
284
+ const FAB_SIZE = 40;
285
+ const [isMobile, setIsMobile] = useState<boolean>(() => (typeof window !== 'undefined' ? window.innerWidth < mobileBreakpoint : false));
286
+ useEffect(() => {
287
+ if (!iconsOnly) return;
288
+ const onResize = () => setIsMobile(window.innerWidth < mobileBreakpoint);
289
+ window.addEventListener('resize', onResize);
290
+ return () => window.removeEventListener('resize', onResize);
291
+ }, [iconsOnly, mobileBreakpoint]);
292
+
293
+ // New isSmall state that tracks window.innerWidth < mobileBreakpoint regardless of iconsOnly
294
+ const [isSmall, setIsSmall] = useState<boolean>(() => (typeof window !== 'undefined' ? window.innerWidth < mobileBreakpoint : false));
295
+ useEffect(() => {
296
+ const onResize = () => setIsSmall(window.innerWidth < mobileBreakpoint);
297
+ window.addEventListener('resize', onResize);
298
+ return () => window.removeEventListener('resize', onResize);
299
+ }, [mobileBreakpoint]);
300
+
301
+ // ---- Tracking helper
302
+ const trackClick = (trackId?: string, label?: string) => {
303
+ try {
304
+ window.dispatchEvent(new CustomEvent('stickyoptions:click', { detail: { trackId, label } }));
305
+ } catch {/* no-op */}
306
+ };
307
+
308
+ if (!isRouteIncluded) return null;
309
+
310
+ // ---- Render item (anchor or span)
311
+ const renderItem = (item: StickyItem, i: number): React.ReactNode => {
312
+ const { icon, label, href, variant = 'neutral', trackId, ariaLabel } = item || {};
313
+ const hasText = !!label;
314
+ const isPrimary = variant === 'primary';
315
+ const commonStyle: React.CSSProperties = {
316
+ display: 'inline-flex',
317
+ alignItems: 'center',
318
+ gap: hasText ? 8 : 0,
319
+ padding: `${isSmall ? 6 : 7}px ${hasText ? (isSmall ? 10 : 12) : (isSmall ? 6 : 8)}px`,
320
+ borderRadius: 999,
321
+ minWidth: hasText ? (isSmall ? 92 : 108) : 40,
322
+ whiteSpace: 'nowrap',
323
+ flexShrink: 0,
324
+ justifyContent: 'center',
325
+ fontWeight: 800,
326
+ textDecoration: 'none',
327
+ border: isPrimary ? '1px solid transparent' : `1px solid ${colors.neutralBorder}`,
328
+ background: isPrimary ? 'rgba(0, 170, 150, 0.12)' : colors.neutralBg,
329
+ color: isPrimary ? colors.linkMain : colors.text
330
+ } as React.CSSProperties;
331
+
332
+ const content = (
333
+ <>
334
+ {icon ? (
335
+ <span style={{ display: 'inline-flex', marginRight: hasText ? 6 : 0 }}>
336
+ {renderIconNode(icon, item?.iconColor)}
337
+ </span>
338
+ ) : null}
339
+ {hasText ? (useI18n ? translate(label!) : label) : null}
340
+ </>
341
+ );
342
+
343
+ if (href) {
344
+ const external = /^https?:\/\//i.test(href);
345
+ return (
346
+ <a
347
+ key={i}
348
+ href={href}
349
+ target={external ? '_blank' : undefined}
350
+ rel={external ? 'noopener noreferrer' : undefined}
351
+ aria-label={ariaLabel || label}
352
+ onClick={() => trackClick(trackId, label)}
353
+ style={commonStyle}
354
+ >
355
+ {content}
356
+ </a>
357
+ );
358
+ }
359
+ return (
360
+ <span key={i} aria-label={ariaLabel || label} style={commonStyle}>
361
+ {content}
362
+ </span>
363
+ );
364
+ };
365
+
366
+ // ---- Layout wrappers
367
+ const wrapperStyle: React.CSSProperties = {
368
+ // Use sticky by default; fixed when explicitly requested
369
+ position: mode === 'fixed' ? 'fixed' : 'sticky',
370
+ top: topCSS,
371
+ left: mode === 'fixed' ? `${insetLeft}px` : undefined,
372
+ right: mode === 'fixed' ? `${insetRight}px` : undefined,
373
+ zIndex: Math.max(0, (muiTheme?.zIndex?.appBar ?? 1100) - 1),
374
+ width: '100%',
375
+ // Apply hide animation only when the feature is enabled and the bar is actually hidden.
376
+ ...(hideOnScrollDown && hidden
377
+ ? {
378
+ transform: 'translateY(-8px)',
379
+ opacity: 0,
380
+ transition: 'transform 180ms ease, opacity 180ms ease',
381
+ }
382
+ : {
383
+ transition: 'transform 180ms ease, opacity 180ms ease',
384
+ }),
385
+ // Ensure the wrapper contributes height when children are absolutely positioned (e.g., mobile FAB)
386
+ minHeight: iconsOnly && isMobile ? FAB_SIZE + 8 : undefined,
387
+ } as React.CSSProperties;
388
+
389
+ const innerWrapStyle: React.CSSProperties = {
390
+ position: 'relative',
391
+ width: `calc(100% - ${insetLeft}px - ${insetRight}px)`,
392
+ margin: '0 auto',
393
+ maxWidth: '100%',
394
+ display: 'flex',
395
+ alignItems: 'flex-start',
396
+ justifyContent: 'center'
397
+ } as React.CSSProperties;
398
+
399
+ const groupBase: React.CSSProperties = {
400
+ display: 'inline-flex',
401
+ gap: 6,
402
+ padding: '4px 8px',
403
+ borderRadius: 999,
404
+ background: colors.bg,
405
+ backdropFilter: `blur(${blur}px)`,
406
+ WebkitBackdropFilter: `blur(${blur}px)`,
407
+ border: `1px solid ${colors.border}`,
408
+ boxShadow: `0 ${Math.round(elevation/3)}px ${elevation}px rgba(0,0,0,0.35)`,
409
+ whiteSpace: 'nowrap',
410
+ pointerEvents: 'auto'
411
+ } as React.CSSProperties;
412
+
413
+ // Position group: always center
414
+ const groupStyle: React.CSSProperties = {
415
+ ...groupBase,
416
+ maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth
417
+ } as React.CSSProperties;
418
+
419
+ // Collapse: icon-only FABs on mobile
420
+ if (iconsOnly && isMobile) {
421
+ const fabWrapStyle: React.CSSProperties = {
422
+ display: 'inline-flex',
423
+ gap: 10,
424
+ alignItems: 'center',
425
+ justifyContent: 'center',
426
+ whiteSpace: 'nowrap'
427
+ } as React.CSSProperties;
428
+
429
+ return (
430
+ <>
431
+ {reserveSpace && <div style={spacerStyle} />}
432
+ <div style={wrapperStyle}>
433
+ <div style={innerWrapStyle}>
434
+ <div style={fabWrapStyle} ref={groupElRef}>
435
+ {items.slice(0, 3).map((item, i) => {
436
+ const isPrimary = (item?.variant || 'neutral') === 'primary';
437
+ const style: React.CSSProperties = {
438
+ width: FAB_SIZE,
439
+ height: FAB_SIZE,
440
+ minWidth: FAB_SIZE,
441
+ minHeight: FAB_SIZE,
442
+ flex: `0 0 ${FAB_SIZE}px`,
443
+ aspectRatio: '1 / 1',
444
+ boxSizing: 'border-box',
445
+ padding: 0,
446
+ borderRadius: 999,
447
+ display: 'inline-flex',
448
+ alignItems: 'center',
449
+ justifyContent: 'center',
450
+ lineHeight: 0,
451
+ textDecoration: 'none',
452
+ border: isPrimary ? '1px solid transparent' : `1px solid ${colors.neutralBorder}`,
453
+ background: isPrimary ? 'rgba(0, 170, 150, 0.12)' : colors.neutralBg,
454
+ color: isPrimary ? colors.linkMain : colors.text
455
+ } as React.CSSProperties;
456
+ const aria = item?.ariaLabel || item?.label;
457
+ if (item?.href) {
458
+ const external = /^https?:\/\//i.test(item.href);
459
+ return (
460
+ <a key={i} href={item.href} target={external ? '_blank' : undefined} rel={external ? 'noopener noreferrer' : undefined} aria-label={aria} onClick={() => trackClick(item?.trackId, item?.label)} style={style}>
461
+ {renderIconNode(item?.icon, item?.iconColor)}
462
+ </a>
463
+ );
464
+ }
465
+ return <span key={i} aria-label={aria} style={style}>{renderIconNode(item?.icon, item?.iconColor)}</span>;
466
+ })}
467
+ </div>
468
+ </div>
469
+ </div>
470
+ </>
471
+ );
472
+ }
473
+
474
+ // Default full pill rendering
475
+ return (
476
+ <>
477
+ {reserveSpace && <div style={spacerStyle} />}
478
+ <div style={wrapperStyle}>
479
+ <div style={innerWrapStyle}>
480
+ <div style={groupStyle} ref={groupElRef}>
481
+ {items.map((item, i) => renderItem(item, i))}
482
+ </div>
483
+ </div>
484
+ </div>
485
+ </>
486
+ );
487
+ };
488
+
489
+ export default StickyOptionsTop;
@@ -0,0 +1,86 @@
1
+ // src/components/generics/AppBars/TopBar/TopBar.resolver.tsx
2
+ import TopBar from './TopBar';
3
+ import type { RegistryEntry, ResolveCtx } from '@/gui/registry/types';
4
+ /** Declarative shape the renderer/LLM can emit for a TopBar */
5
+ type TopBarLinkChildSpec = {
6
+ label: string;
7
+ href?: string;
8
+ external?: boolean;
9
+ icon?: string;
10
+ iconColor?: string;
11
+ };
12
+
13
+ type TopBarLinkSpec = {
14
+ label: string;
15
+ href?: string;
16
+ external?: boolean;
17
+ icon?: string;
18
+ iconColor?: string;
19
+ children?: TopBarLinkChildSpec[];
20
+ };
21
+
22
+ type TopBarSpec = {
23
+ type: 'TopBar';
24
+ props?: {
25
+ title?: string;
26
+ logo?: string;
27
+ NavBarLinks?: TopBarLinkSpec[];
28
+ showMenuButton?: boolean;
29
+ showThemeToggle?: boolean;
30
+ homeTo?: string;
31
+ position?: 'fixed' | 'static' | 'sticky';
32
+ /** Optional event id to resolve from ctx.actions (e.g., 'openLeftDrawer') */
33
+ onMenuClickId?: string;
34
+ /** Pass-through styling slot (sx forwarded to AppBar/Toolbar usage inside) */
35
+ sx?: any;
36
+ /** Misc passthroughs */
37
+ id?: string;
38
+ className?: string;
39
+ 'data-testid'?: string;
40
+ };
41
+ };
42
+
43
+ /**
44
+ * TopBarResolver
45
+ * - Maps a JSON-friendly spec → real <TopBar />.
46
+ * - Handlers can be injected from ResolveCtx via `onMenuClickId`.
47
+ */
48
+ const TopBarResolver: RegistryEntry = {
49
+ type: 'TopBar',
50
+ resolve(spec: TopBarSpec, ctx?: ResolveCtx) {
51
+ const p = spec.props ?? {};
52
+
53
+ // Resolve optional handler from ctx if provided
54
+ const onMenuClick =
55
+ (p.onMenuClickId && ctx?.actions && typeof ctx.actions[p.onMenuClickId] === 'function')
56
+ ? ctx.actions[p.onMenuClickId]
57
+ : undefined;
58
+
59
+ return (
60
+ <TopBar
61
+ title={p.title ?? 'neurons.me'}
62
+ logo={p.logo ?? 'https://neurons.me/neurons.me.png'}
63
+ elementsCenter={(p.NavBarLinks ?? []).map(link => ({
64
+ type: 'link',
65
+ props: {
66
+ label: link.label ?? '',
67
+ href: link.href ?? '',
68
+ external: link.external ?? false,
69
+ icon: link.icon,
70
+ iconColor: link.iconColor,
71
+ children: link.children ?? [],
72
+ }
73
+ }))}
74
+ homeTo={p.homeTo ?? '/'}
75
+ position={p.position ?? 'fixed'}
76
+ // passthroughs
77
+ sx={p.sx}
78
+ id={p.id}
79
+ className={p.className}
80
+ data-testid={p['data-testid']}
81
+ />
82
+ );
83
+ },
84
+ };
85
+
86
+ export default TopBarResolver;