this.gui 1.3.40 → 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 (319) hide show
  1. package/dist/init/index.html +27 -0
  2. package/dist/init/package-lock.json +5779 -0
  3. package/dist/init/package.json +24 -0
  4. package/dist/init/src/App.tsx +40 -0
  5. package/dist/init/src/index.css +16 -0
  6. package/dist/init/src/main.tsx +13 -0
  7. package/dist/init/src/router/DerivableRouter.tsx +36 -0
  8. package/dist/init/tsconfig.json +17 -0
  9. package/dist/init/vite.config.ts +11 -0
  10. package/package.json +5 -3
  11. package/src/GUI.tsx +46 -0
  12. package/src/QRouter/QRegistry.tsx +53 -0
  13. package/src/QRouter/QRouter.stories.tsx +31 -0
  14. package/src/QRouter/QRouter.tsx +57 -0
  15. package/src/gui/Theme/GuiProvider.tsx +111 -0
  16. package/src/gui/Theme/Icon/Icon.resolver.tsx +29 -0
  17. package/src/gui/Theme/Icon/Icon.tsx +43 -0
  18. package/src/gui/Theme/Layout/Content/Content.resolver.tsx +0 -0
  19. package/src/gui/Theme/Layout/Content/Content.stories.tsx +88 -0
  20. package/src/gui/Theme/Layout/Content/Content.tsx +53 -0
  21. package/src/gui/Theme/Layout/Content/Content.types.tsx +40 -0
  22. package/src/gui/Theme/Layout/Footer/Footer.resolver.tsx +45 -0
  23. package/src/gui/Theme/Layout/Footer/Footer.stories.tsx +205 -0
  24. package/src/gui/Theme/Layout/Footer/Footer.tsx +337 -0
  25. package/src/gui/Theme/Layout/Footer/Footer.types.ts +40 -0
  26. package/src/gui/Theme/Layout/Layout/Layout.resolver.tsx +37 -0
  27. package/src/gui/Theme/Layout/Layout/Layout.stories.tsx +289 -0
  28. package/src/gui/Theme/Layout/Layout/Layout.tsx +117 -0
  29. package/src/gui/Theme/Layout/Layout/Layout.types.ts +57 -0
  30. package/src/gui/Theme/Layout/Layout/useLayoutBreakpoints.ts +9 -0
  31. package/src/gui/Theme/Layout/Namespace/Namespace.stories.tsx +105 -0
  32. package/src/gui/Theme/Layout/Namespace/Namespace.tsx +26 -0
  33. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/LeftSidebar.resolver.tsx +87 -0
  34. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/LeftSidebar.stories.tsx +199 -0
  35. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/LeftSidebar.tsx +311 -0
  36. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/LeftSidebar.types.ts +41 -0
  37. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/SidebarToggleButton.tsx +53 -0
  38. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarAction/LeftSidebarAction.resolver.tsx +19 -0
  39. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarAction/LeftSidebarAction.tsx +107 -0
  40. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.resolver.tsx +0 -0
  41. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.tsx +134 -0
  42. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.types.ts +15 -0
  43. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarMenu/LeftSidebarMenu.tsx +142 -0
  44. package/src/gui/Theme/Layout/Sidebars/LeftSidebar/components/LeftSidebarToggleButton/LeftSidebarToggleButton.tsx +23 -0
  45. package/src/gui/Theme/Layout/Sidebars/RightSidebar/RightSidebar.resolver.tsx +35 -0
  46. package/src/gui/Theme/Layout/Sidebars/RightSidebar/RightSidebar.stories.tsx +239 -0
  47. package/src/gui/Theme/Layout/Sidebars/RightSidebar/RightSidebar.tsx +319 -0
  48. package/src/gui/Theme/Layout/Sidebars/RightSidebar/RightSidebar.types.ts +17 -0
  49. package/src/gui/Theme/Layout/Sidebars/RightSidebar/components/RightSidebarAction/RightSidebarAction.tsx +102 -0
  50. package/src/gui/Theme/Layout/Sidebars/RightSidebar/components/RightSidebarLink/RightSidebarLink.tsx +132 -0
  51. package/src/gui/Theme/Layout/Sidebars/RightSidebar/components/RightSidebarMenu/RightSidebarMenu.tsx +140 -0
  52. package/src/gui/Theme/Layout/Sidebars/RightSidebar/components/RightSidebarToggleButton/RightSidebarToggleButton.tsx +22 -0
  53. package/src/gui/Theme/Layout/StickyOptions/StickyOptionsTop.stories.tsx +469 -0
  54. package/src/gui/Theme/Layout/StickyOptions/StickyOptionsTop.tsx +489 -0
  55. package/src/gui/Theme/Layout/TopBar/TopBar.resolver.tsx +86 -0
  56. package/src/gui/Theme/Layout/TopBar/TopBar.stories.tsx +350 -0
  57. package/src/gui/Theme/Layout/TopBar/TopBar.tsx +292 -0
  58. package/src/gui/Theme/Layout/TopBar/TopBar.types.ts +39 -0
  59. package/src/gui/Theme/Layout/TopBar/components/TopBarAction/TopBarAction.stories.tsx +83 -0
  60. package/src/gui/Theme/Layout/TopBar/components/TopBarAction/TopBarAction.tsx +18 -0
  61. package/src/gui/Theme/Layout/TopBar/components/TopBarAction/TopBarAction.types.ts +4 -0
  62. package/src/gui/Theme/Layout/TopBar/components/TopBarLink/TopBarLink.stories.tsx +189 -0
  63. package/src/gui/Theme/Layout/TopBar/components/TopBarLink/TopBarLink.tsx +30 -0
  64. package/src/gui/Theme/Layout/TopBar/components/TopBarLink/TopBarLink.types.ts +9 -0
  65. package/src/gui/Theme/Layout/TopBar/components/TopBarMenu/TopBarMenu.resolver.tsx +14 -0
  66. package/src/gui/Theme/Layout/TopBar/components/TopBarMenu/TopBarMenu.stories.tsx +56 -0
  67. package/src/gui/Theme/Layout/TopBar/components/TopBarMenu/TopBarMenu.tsx +123 -0
  68. package/src/gui/Theme/Layout/TopBar/components/TopBarMenu/TopBarMenu.types.ts +44 -0
  69. package/src/gui/Theme/catalog/CherryByte/CherryByte.png +0 -0
  70. package/src/gui/Theme/catalog/CherryByte/dark.tokens.ts +47 -0
  71. package/src/gui/Theme/catalog/CherryByte/light.tokens.ts +47 -0
  72. package/src/gui/Theme/catalog/CherryByte/manifest.ts +24 -0
  73. package/src/gui/Theme/catalog/GhostShell/dark.tokens.ts +43 -0
  74. package/src/gui/Theme/catalog/GhostShell/ghost.png +0 -0
  75. package/src/gui/Theme/catalog/GhostShell/light.tokens.ts +39 -0
  76. package/src/gui/Theme/catalog/GhostShell/manifest.ts +24 -0
  77. package/src/gui/Theme/catalog/LunaHex/LunaHex.png +0 -0
  78. package/src/gui/Theme/catalog/LunaHex/dark.tokens.ts +34 -0
  79. package/src/gui/Theme/catalog/LunaHex/light.tokens.ts +74 -0
  80. package/src/gui/Theme/catalog/LunaHex/manifest.ts +24 -0
  81. package/src/gui/Theme/catalog/MUI/MUI.png +0 -0
  82. package/src/gui/Theme/catalog/MUI/dark.tokens.ts +58 -0
  83. package/src/gui/Theme/catalog/MUI/light.tokens.ts +74 -0
  84. package/src/gui/Theme/catalog/MUI/manifest.ts +24 -0
  85. package/src/gui/Theme/catalog/PrinceOfDarkness/dark.tokens.ts +48 -0
  86. package/src/gui/Theme/catalog/PrinceOfDarkness/light.tokens.ts +47 -0
  87. package/src/gui/Theme/catalog/PrinceOfDarkness/manifest.ts +24 -0
  88. package/src/gui/Theme/catalog/PrinceOfDarkness/prince.png +0 -0
  89. package/src/gui/Theme/catalog/PrinceOfDarkness/princeOfDarkness.png +0 -0
  90. package/src/gui/Theme/catalog/Seafoam/dark.tokens.ts +49 -0
  91. package/src/gui/Theme/catalog/Seafoam/light.tokens.ts +47 -0
  92. package/src/gui/Theme/catalog/Seafoam/manifest.ts +24 -0
  93. package/src/gui/Theme/catalog/Seafoam/seaFoam.png +0 -0
  94. package/src/gui/Theme/catalog/neurons/dark.tokens.ts +58 -0
  95. package/src/gui/Theme/catalog/neurons/light.tokens.ts +74 -0
  96. package/src/gui/Theme/catalog/neurons/manifest.ts +24 -0
  97. package/src/gui/Theme/catalog/neurons/neurons.me.png +0 -0
  98. package/src/gui/Theme/fromTokens.ts +272 -0
  99. package/src/gui/Theme/gui.css +31 -0
  100. package/src/gui/Theme/index.ts +17 -0
  101. package/src/gui/Theme/styles/buildShadows.ts +83 -0
  102. package/src/gui/Theme/styles/theme.tokens.ts +108 -0
  103. package/src/gui/Theme/utils/catalog.ts +61 -0
  104. package/src/gui/Theme/utils/persistence.ts +66 -0
  105. package/src/gui/Theme/utils/themeUtils.ts +34 -0
  106. package/src/gui/components/atoms/AppBar/AppBar.resolver.tsx +46 -0
  107. package/src/gui/components/atoms/AppBar/AppBar.stories.tsx +251 -0
  108. package/src/gui/components/atoms/AppBar/AppBar.tsx +107 -0
  109. package/src/gui/components/atoms/AppBar/AppBar.types.ts +28 -0
  110. package/src/gui/components/atoms/Avatar/Avatar.resolver.tsx +61 -0
  111. package/src/gui/components/atoms/Avatar/Avatar.stories.tsx +36 -0
  112. package/src/gui/components/atoms/Avatar/Avatar.tsx +14 -0
  113. package/src/gui/components/atoms/Box/Box.resolver.tsx +171 -0
  114. package/src/gui/components/atoms/Box/Box.stories.tsx +263 -0
  115. package/src/gui/components/atoms/Box/Box.tsx +15 -0
  116. package/src/gui/components/atoms/Button/Button.resolver.tsx +103 -0
  117. package/src/gui/components/atoms/Button/Button.stories.tsx +219 -0
  118. package/src/gui/components/atoms/Button/Button.tsx +40 -0
  119. package/src/gui/components/atoms/Card/Card.resolver.tsx +63 -0
  120. package/src/gui/components/atoms/Card/Card.stories.tsx +54 -0
  121. package/src/gui/components/atoms/Card/Card.tsx +13 -0
  122. package/src/gui/components/atoms/CardActions/CardActions.resolver.tsx +59 -0
  123. package/src/gui/components/atoms/CardActions/CardActions.stories.tsx +32 -0
  124. package/src/gui/components/atoms/CardActions/CardActions.tsx +14 -0
  125. package/src/gui/components/atoms/CardContent/CardContent.resolver.tsx +60 -0
  126. package/src/gui/components/atoms/CardContent/CardContent.stories.tsx +34 -0
  127. package/src/gui/components/atoms/CardContent/CardContent.tsx +13 -0
  128. package/src/gui/components/atoms/CardHeader/CardHeader.resolver.tsx +68 -0
  129. package/src/gui/components/atoms/CardHeader/CardHeader.stories.tsx +40 -0
  130. package/src/gui/components/atoms/CardHeader/CardHeader.tsx +12 -0
  131. package/src/gui/components/atoms/Collapse/Collapse.resolver.tsx +85 -0
  132. package/src/gui/components/atoms/Collapse/Collapse.stories.tsx +130 -0
  133. package/src/gui/components/atoms/Collapse/Collapse.tsx +17 -0
  134. package/src/gui/components/atoms/Divider/Divider.resolver.tsx +95 -0
  135. package/src/gui/components/atoms/Divider/Divider.stories.tsx +108 -0
  136. package/src/gui/components/atoms/Divider/Divider.tsx +14 -0
  137. package/src/gui/components/atoms/Drawer/Drawer.resolver.tsx +116 -0
  138. package/src/gui/components/atoms/Drawer/Drawer.stories.tsx +223 -0
  139. package/src/gui/components/atoms/Drawer/Drawer.tsx +25 -0
  140. package/src/gui/components/atoms/Grid/Grid.resolver.tsx +33 -0
  141. package/src/gui/components/atoms/Grid/Grid.stories.tsx +136 -0
  142. package/src/gui/components/atoms/Grid/Grid.tsx +15 -0
  143. package/src/gui/components/atoms/Grid/Grid.types.ts +9 -0
  144. package/src/gui/components/atoms/IconButton/IconButton.resolver.tsx +137 -0
  145. package/src/gui/components/atoms/IconButton/IconButton.stories.tsx +134 -0
  146. package/src/gui/components/atoms/IconButton/IconButton.tsx +22 -0
  147. package/src/gui/components/atoms/Link/Link.resolver.tsx +74 -0
  148. package/src/gui/components/atoms/Link/Link.stories.tsx +157 -0
  149. package/src/gui/components/atoms/Link/Link.tsx +36 -0
  150. package/src/gui/components/atoms/List/List.resolver.tsx +94 -0
  151. package/src/gui/components/atoms/List/List.stories.tsx +137 -0
  152. package/src/gui/components/atoms/List/List.tsx +20 -0
  153. package/src/gui/components/atoms/ListItem/ListItem.resolver.tsx +88 -0
  154. package/src/gui/components/atoms/ListItem/ListItem.stories.tsx +151 -0
  155. package/src/gui/components/atoms/ListItem/ListItem.tsx +19 -0
  156. package/src/gui/components/atoms/ListItemButton/ListItemButton.resolver.tsx +214 -0
  157. package/src/gui/components/atoms/ListItemButton/ListItemButton.stories.tsx +155 -0
  158. package/src/gui/components/atoms/ListItemButton/ListItemButton.tsx +15 -0
  159. package/src/gui/components/atoms/ListItemIcon/ListItemIcon.resolver.tsx +102 -0
  160. package/src/gui/components/atoms/ListItemIcon/ListItemIcon.stories.tsx +132 -0
  161. package/src/gui/components/atoms/ListItemIcon/ListItemIcon.tsx +11 -0
  162. package/src/gui/components/atoms/ListItemText/ListItemText.resolver.tsx +112 -0
  163. package/src/gui/components/atoms/ListItemText/ListItemText.stories.tsx +156 -0
  164. package/src/gui/components/atoms/ListItemText/ListItemText.tsx +15 -0
  165. package/src/gui/components/atoms/Menu/Menu.resolver.tsx +112 -0
  166. package/src/gui/components/atoms/Menu/Menu.stories.tsx +162 -0
  167. package/src/gui/components/atoms/Menu/Menu.tsx +17 -0
  168. package/src/gui/components/atoms/MenuItem/MenuItem.resolver.tsx +183 -0
  169. package/src/gui/components/atoms/MenuItem/MenuItem.stories.tsx +134 -0
  170. package/src/gui/components/atoms/MenuItem/MenuItem.tsx +14 -0
  171. package/src/gui/components/atoms/Paper/Paper.resolver.tsx +98 -0
  172. package/src/gui/components/atoms/Paper/Paper.stories.tsx +184 -0
  173. package/src/gui/components/atoms/Paper/Paper.tsx +15 -0
  174. package/src/gui/components/atoms/Section/Section.resolver.tsx +10 -0
  175. package/src/gui/components/atoms/Section/Section.stories.tsx +189 -0
  176. package/src/gui/components/atoms/Section/Section.tsx +76 -0
  177. package/src/gui/components/atoms/Section/Section.types.tsx +24 -0
  178. package/src/gui/components/atoms/Stack/Stack.resolver.tsx +94 -0
  179. package/src/gui/components/atoms/Stack/Stack.stories.tsx +160 -0
  180. package/src/gui/components/atoms/Stack/Stack.tsx +15 -0
  181. package/src/gui/components/atoms/Surface/Surface.resolver.tsx +37 -0
  182. package/src/gui/components/atoms/Surface/Surface.tsx +49 -0
  183. package/src/gui/components/atoms/Surface/Surface.types.ts +20 -0
  184. package/src/gui/components/atoms/Switch/Switch.resolver.tsx +53 -0
  185. package/src/gui/components/atoms/Switch/Switch.stories.tsx +236 -0
  186. package/src/gui/components/atoms/Switch/Switch.tsx +22 -0
  187. package/src/gui/components/atoms/Table/Body/TableBody.tsx +7 -0
  188. package/src/gui/components/atoms/Table/Cell/TableCell.tsx +18 -0
  189. package/src/gui/components/atoms/Table/Head/TableHead.tsx +9 -0
  190. package/src/gui/components/atoms/Table/Row/TableRow.tsx +20 -0
  191. package/src/gui/components/atoms/Table/Table.resolver.tsx +77 -0
  192. package/src/gui/components/atoms/Table/Table.stories.tsx +173 -0
  193. package/src/gui/components/atoms/Table/Table.tsx +20 -0
  194. package/src/gui/components/atoms/TextField/TextField.stories.tsx +25 -0
  195. package/src/gui/components/atoms/TextField/TextField.tsx +15 -0
  196. package/src/gui/components/atoms/Toolbar/Toolbar.resolver.tsx +60 -0
  197. package/src/gui/components/atoms/Toolbar/Toolbar.stories.tsx +155 -0
  198. package/src/gui/components/atoms/Toolbar/Toolbar.tsx +16 -0
  199. package/src/gui/components/atoms/Tooltip/Tooltip.resolver.tsx +142 -0
  200. package/src/gui/components/atoms/Tooltip/Tooltip.stories.tsx +117 -0
  201. package/src/gui/components/atoms/Tooltip/Tooltip.tsx +70 -0
  202. package/src/gui/components/atoms/Typography/Typography.resolver.tsx +158 -0
  203. package/src/gui/components/atoms/Typography/Typography.stories.tsx +222 -0
  204. package/src/gui/components/atoms/Typography/Typography.tsx +27 -0
  205. package/src/gui/components/atoms/Window/Nodes/node.ts +0 -0
  206. package/src/gui/components/atoms/Window/code/block/node.tsx +0 -0
  207. package/src/gui/components/atoms/Window/code/hugging.face.api.ts +11 -0
  208. package/src/gui/components/atoms/Window/connectors/index.ts +19 -0
  209. package/src/gui/components/atoms/Window/window.stories.tsx +20 -0
  210. package/src/gui/components/atoms/Window/window.tsx +636 -0
  211. package/src/gui/components/atoms/atoms.tsx +151 -0
  212. package/src/gui/components/atoms/index.ts +2 -0
  213. package/src/gui/components/generics/Cards/Gridme.jsx +52 -0
  214. package/src/gui/components/generics/Cards/LilBox.jsx +65 -0
  215. package/src/gui/components/generics/Cards/ModuleCard.jsx +106 -0
  216. package/src/gui/components/generics/Chats/FullChatBot.jsx +223 -0
  217. package/src/gui/components/generics/Code/CodeBlock.jsx +33 -0
  218. package/src/gui/components/generics/EmojiCursor/EmojiCursor.stories.tsx +153 -0
  219. package/src/gui/components/generics/EmojiCursor/EmojiCursor.tsx +23 -0
  220. package/src/gui/components/generics/Feedback/Callout.jsx +92 -0
  221. package/src/gui/components/generics/Layout/GridX.jsx +29 -0
  222. package/src/gui/components/generics/Layout/Hero2.jsx +132 -0
  223. package/src/gui/components/generics/Layout/PageContainer.jsx +29 -0
  224. package/src/gui/components/generics/Layout/PageDivider.jsx +20 -0
  225. package/src/gui/components/generics/Layout/Section.jsx +43 -0
  226. package/src/gui/components/generics/Layout/SectionHeader.jsx +21 -0
  227. package/src/gui/components/generics/Media/Img.jsx +58 -0
  228. package/src/gui/components/generics/Media/VideoEmbed.jsx +51 -0
  229. package/src/gui/components/generics/Organization/TableOfContents.jsx +51 -0
  230. package/src/gui/components/generics/Organization/Tabs.jsx +45 -0
  231. package/src/gui/components/generics/Text/TextList.jsx +41 -0
  232. package/src/gui/components/generics/Text/TextParagraph.jsx +28 -0
  233. package/src/gui/components/generics/Text/TextQuote.jsx +23 -0
  234. package/src/gui/components/generics/Text/TextTitle.jsx +44 -0
  235. package/src/gui/components/molecules/Dialog/Dialog.stories.tsx +18 -0
  236. package/src/gui/components/molecules/Dialog/Dialog.tsx +5 -0
  237. package/src/gui/components/molecules/Hero/Hero.stories.tsx +140 -0
  238. package/src/gui/components/molecules/Hero/Hero.tsx +152 -0
  239. package/src/gui/components/molecules/Hero/Hero.types.tsx +18 -0
  240. package/src/gui/components/molecules/Modal/Modal.resolver.tsx +38 -0
  241. package/src/gui/components/molecules/Modal/Modal.stories.tsx +82 -0
  242. package/src/gui/components/molecules/Modal/Modal.tsx +110 -0
  243. package/src/gui/components/molecules/Modal/Modal.types.ts +29 -0
  244. package/src/gui/components/molecules/Page/Page.stories.tsx +135 -0
  245. package/src/gui/components/molecules/Page/Page.tsx +94 -0
  246. package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.resolver.tsx +58 -0
  247. package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.stories.tsx +133 -0
  248. package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.tsx +101 -0
  249. package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.types.ts +29 -0
  250. package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.resolver.tsx +15 -0
  251. package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.stories.tsx +88 -0
  252. package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.tsx +167 -0
  253. package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.types.ts +34 -0
  254. package/src/gui/components/molecules/molecules.ts +49 -0
  255. package/src/gui/components/organisms/Blockchain/Blocks/BlocksTable.tsx +119 -0
  256. package/src/gui/components/organisms/Blockchain/Usernames/Identities.stories.tsx +20 -0
  257. package/src/gui/components/organisms/Blockchain/Usernames/QR.tsx +566 -0
  258. package/src/gui/components/organisms/Blockchain/Usernames/Usernames.tsx +448 -0
  259. package/src/gui/components/organisms/Blockchain/Usernames/identities.tsx +710 -0
  260. package/src/gui/components/organisms/Blockchain/blockchain.stories.tsx +17 -0
  261. package/src/gui/components/organisms/Blockchain/blockchain.tsx +368 -0
  262. package/src/gui/components/organisms/Blockchain/scripts/connection.ts +82 -0
  263. package/src/gui/components/organisms/Blockchain/scripts/match_face.ts +143 -0
  264. package/src/gui/components/organisms/HighLighter/HighLighter.stories.tsx +168 -0
  265. package/src/gui/components/organisms/HighLighter/HighLighter.tsx +420 -0
  266. package/src/gui/components/organisms/HighLighter/HighLightsDrawer.tsx +197 -0
  267. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/FaceRecognition.stories.tsx +312 -0
  268. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/FaceRecognition.tsx +765 -0
  269. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceCameraPermission.ts +70 -0
  270. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceLandmarker.ts +106 -0
  271. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceOverlay.ts +489 -0
  272. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceTemplate.ts +32 -0
  273. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/useFaceTemplateBurst.ts +178 -0
  274. package/src/gui/components/organisms/IdentityNoise/FaceRecognition/modules/verifyTemplate.ts +136 -0
  275. package/src/gui/components/organisms/IdentityNoise/IdentityNoise.tsx +403 -0
  276. package/src/gui/components/organisms/IdentityNoise/IndentityNoise.stories.tsx +15 -0
  277. package/src/gui/components/organisms/IdentityNoise/Noise/Noise.stories.tsx +206 -0
  278. package/src/gui/components/organisms/IdentityNoise/Noise/Noise.tsx +394 -0
  279. package/src/gui/components/organisms/IdentityNoise/Triad/QR.tsx +566 -0
  280. package/src/gui/components/organisms/IdentityNoise/Triad/Tiad.stories.tsx +6 -0
  281. package/src/gui/components/organisms/IdentityNoise/Triad/Triad.tsx +917 -0
  282. package/src/gui/components/organisms/IdentityNoise/Triad/handleCleak.ts +0 -0
  283. package/src/gui/components/organisms/IdentityNoise/Triad/identity.ts +31 -0
  284. package/src/gui/components/organisms/IdentityNoise/Triad/me/fundamentals/vectors/vectors.tsx +252 -0
  285. package/src/gui/components/organisms/IdentityNoise/Triad/me/me.stories.tsx +314 -0
  286. package/src/gui/components/organisms/IdentityNoise/Triad/me/me.tsx +0 -0
  287. package/src/gui/components/organisms/organisms.ts +15 -0
  288. package/src/gui/contexts/InsetsContext.tsx +40 -0
  289. package/src/gui/contexts/LeftSidebarContext.tsx +20 -0
  290. package/src/gui/contexts/RightSidebarContext.tsx +25 -0
  291. package/src/gui/contexts/ThemeContext.ts +34 -0
  292. package/src/gui/contexts/index.ts +4 -0
  293. package/src/gui/hooks/index.ts +11 -0
  294. package/src/gui/hooks/resolveColorToken.ts +39 -0
  295. package/src/gui/hooks/useCodeGen.ts +12 -0
  296. package/src/gui/hooks/useGuiMediaQuery.ts +18 -0
  297. package/src/gui/hooks/useGuiTheme.ts +18 -0
  298. package/src/gui/hooks/useInsets.ts +26 -0
  299. package/src/gui/hooks/useIsMobile.ts +13 -0
  300. package/src/gui/hooks/useIsTouchDevice.ts +25 -0
  301. package/src/gui/hooks/useLeftSidebar.ts +10 -0
  302. package/src/gui/hooks/useRightSidebar.ts +12 -0
  303. package/src/gui/hooks/useViewportKey.ts +19 -0
  304. package/src/gui/hooks/useViewportProp.ts +17 -0
  305. package/src/gui/registry/GuiRegistry.ts +19 -0
  306. package/src/gui/registry/factory.ts +12 -0
  307. package/src/gui/registry/index.ts +3 -0
  308. package/src/gui/registry/types.ts +6 -0
  309. package/src/gui/utils/nodeID.ts +11 -0
  310. package/src/registry/GuiRegistry.ts +19 -0
  311. package/src/stories/01.Home.mdx +22 -0
  312. package/src/stories/02.Understanding.This.GUI.mdx +149 -0
  313. package/src/stories/Theme/Palette.stories.tsx +86 -0
  314. package/src/stories/Theme/ThemeViewer.stories.tsx +91 -0
  315. package/src/stories/Theme/Typography.stories.jsx +211 -0
  316. package/src/stories/assets/this.GUI.png +0 -0
  317. package/src/types/gui.d.ts +67 -0
  318. package/src/types/theme.d.ts +191 -0
  319. package/src/types/viewport.ts +132 -0
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { Box } from '@/gui/components/atoms';
3
+ import { useInsets } from '@/gui/hooks';
4
+ import type { ContentProps } from './Content.types';
5
+
6
+ const Content: React.FC<ContentProps> = ({ children }) => {
7
+ const insets = useInsets();
8
+ const safeTop = Math.max(0, Number(insets?.top ?? 0));
9
+ const navHeight = Math.max(0, Number(insets?.nav ?? 0));
10
+ const topInset = safeTop + navHeight;
11
+ const bottomInset = Math.max(0, Number(insets?.bottom ?? 0));
12
+ const leftInset = Math.max(0, Number(insets?.left ?? 0));
13
+ const rightInset = Math.max(0, Number(insets?.right ?? 0));
14
+
15
+ return (
16
+ <Box
17
+ id="content"
18
+ component="main"
19
+ sx={{
20
+ position: 'relative',
21
+ flex: 1,
22
+ display: 'flex',
23
+ flexDirection: 'column',
24
+ minHeight: 0,
25
+ width: '100%',
26
+ overflow: 'hidden',
27
+ paddingTop: `${topInset}px`,
28
+ paddingBottom: `${bottomInset}px`,
29
+ paddingLeft: `${leftInset}px`,
30
+ paddingRight: `${rightInset}px`,
31
+ boxSizing: 'border-box',
32
+ backgroundColor: 'background.default',
33
+ transition: 'padding 0.3s ease',
34
+ }}
35
+ >
36
+ <Box
37
+ sx={{
38
+ flex: 1,
39
+ minHeight: 0,
40
+ width: '100%',
41
+ display: 'flex',
42
+ flexDirection: 'column',
43
+ overflowY: 'auto',
44
+ overflowX: 'hidden',
45
+ }}
46
+ >
47
+ {children}
48
+ </Box>
49
+ </Box>
50
+ );
51
+ };
52
+
53
+ export default Content;
@@ -0,0 +1,40 @@
1
+ import type React from 'react';
2
+ import type { SxProps, Theme } from '@mui/material/styles';
3
+
4
+ export type ContentSection = {
5
+ type: string;
6
+ props?: Record<string, any>;
7
+ children?: ContentSection[];
8
+ };
9
+
10
+ export interface ContentProps {
11
+ /**
12
+ * Array of layout sections or components to render within the Content area.
13
+ */
14
+ sections?: ContentSection[];
15
+
16
+ /**
17
+ * Optional unique identifier.
18
+ */
19
+ id?: string;
20
+
21
+ /**
22
+ * Custom CSS class name for additional styling.
23
+ */
24
+ className?: string;
25
+
26
+ /**
27
+ * Optional style overrides for the main container.
28
+ */
29
+ sx?: SxProps<Theme>;
30
+
31
+ /**
32
+ * Optional data-testid for testing purposes.
33
+ */
34
+ 'data-testid'?: string;
35
+
36
+ /**
37
+ * Optional React children that can be rendered directly.
38
+ */
39
+ children?: React.ReactNode;
40
+ }
@@ -0,0 +1,45 @@
1
+ import * as React from 'react';
2
+ import type { RegistryEntry } from '@/gui/registry/types';
3
+ import Footer from './Footer';
4
+ import type { FooterElement } from './Footer.types';
5
+
6
+ type FooterSpec = {
7
+ type: 'Footer';
8
+ props?: {
9
+ brandLabel?: string;
10
+ brandLogo?: string;
11
+ brandHref?: string;
12
+ leftElements?: FooterElement[];
13
+ centerElements?: FooterElement[];
14
+ rightElements?: FooterElement[];
15
+ position?: 'static' | 'fixed' | 'sticky';
16
+ elevation?: number;
17
+ className?: string;
18
+ id?: string;
19
+ 'data-testid'?: string;
20
+ };
21
+ };
22
+
23
+ const FooterResolver: RegistryEntry = {
24
+ type: 'Footer',
25
+ resolve(spec: FooterSpec) {
26
+ const props = spec.props ?? {};
27
+ return (
28
+ <Footer
29
+ brandLabel={props.brandLabel}
30
+ brandLogo={props.brandLogo}
31
+ brandHref={props.brandHref}
32
+ leftElements={props.leftElements}
33
+ centerElements={props.centerElements}
34
+ rightElements={props.rightElements}
35
+ position={props.position}
36
+ elevation={props.elevation}
37
+ className={props.className}
38
+ id={props.id}
39
+ data-testid={props['data-testid']}
40
+ />
41
+ );
42
+ },
43
+ };
44
+
45
+ export default FooterResolver;
@@ -0,0 +1,205 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import Footer from "./Footer";
3
+ import Layout from "@/gui/Theme/Layout/Layout/Layout";
4
+ import ThemeModeToggle from "@/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle";
5
+
6
+ const meta: Meta<typeof Footer> = {
7
+ title: "Layout/Footer/Footer",
8
+ component: Footer,
9
+ tags: ['autodocs'],
10
+ parameters: {
11
+ docs: {
12
+ description: {
13
+ component:
14
+ `The **Footer** component serves as a foundational UI element that anchors actions and secondary navigation at the bottom of the viewport, while seamlessly integrating with responsive layouts and respecting insets caused by sidebars and other layout elements.
15
+
16
+ ---
17
+ ## Declarative Usage
18
+ You can declare the Footer directly in JSX by passing branding information and arrays of elements for the left, center, and right zones. Each element can be a link or an action, allowing flexible customization of navigation and controls.
19
+
20
+ ---
21
+ ## Responsive React Layout Integration
22
+ The Footer automatically adjusts its width and position based on the presence of left and right sidebars, ensuring it does not overlap with other UI components. It also adapts to different screen sizes by hiding labels on tablet and mobile views, showing only icons with tooltips for accessibility.
23
+
24
+ ---
25
+ ## Props Overview
26
+ - \`brandLabel\`: Text label representing the brand, used as fallback or alongside the logo.
27
+ - \`brandLogo\`: URL or path to the brand logo image.
28
+ - \`brandHref\`: Link URL for the brand element, typically the home page.
29
+ - \`leftElements\`, \`centerElements\`, \`rightElements\`: Arrays of elements defining the content for each segment of the footer. Each element is an object with a \`type\` ('link' or 'action') and \`props\` defining its properties such as label, icon, href, and event handlers.
30
+
31
+ ---
32
+ ## Features
33
+ - **Inset-aware:** Automatically offsets its width to accommodate left and right sidebars, avoiding overlap.
34
+ - **Responsive Design:** Collapses labels to icons only on smaller screens, maintaining usability and accessibility with tooltips.
35
+ - **Segmented Layout:** Divides the footer into three distinct zones (left, center, right) for organized content placement.
36
+ - **Flexible Positioning:** Supports \`static\`, \`fixed\`, and \`sticky\` positioning modes to suit various layout needs.
37
+ - **Customizable Styling:** Allows style overrides via \`sx\`, \`appBarSx\`, and \`sectionSx\` for fine-grained control.
38
+
39
+ ---
40
+ ## Layout Zones
41
+ - **Left Zone:** Typically contains branding and primary links.
42
+ - **Center Zone:** Ideal for documentation links, community resources, or other central navigation.
43
+ - **Right Zone:** Often used for actions such as theme toggles or contact buttons.
44
+
45
+ ---
46
+ ## Responsiveness
47
+ Below the \`md\` breakpoint, the Footer hides text labels and displays only icons, preserving space and clarity on smaller devices. Tooltips are provided to maintain accessibility despite the reduced label visibility.
48
+
49
+ ---
50
+ ## Integration Tips
51
+ - Combine the Footer with responsive layout shells that include TopBar and Sidebars to maintain consistent insets and layout harmony.
52
+ - Use the \`position="fixed"\` prop to create persistent footers that remain visible and update the global bottom inset dynamically.
53
+ - Leverage the segmented layout to organize navigation and actions intuitively.
54
+
55
+ ---
56
+ ## Example: Declarative Usage
57
+ ~~~tsx
58
+ <Footer
59
+ brandLabel="Neuroverse"
60
+ brandLogo="/logo.svg"
61
+ leftElements={[
62
+ { type: 'link', props: { label: 'Changelog', icon: 'history', href: '/changelog' } },
63
+ ]}
64
+ centerElements={[
65
+ { type: 'link', props: { label: 'Docs', icon: 'menu_book', href: '/docs' } },
66
+ { type: 'link', props: { label: 'Community', icon: 'forum', href: '/community', external: true } },
67
+ ]}
68
+ rightElements={[
69
+ { type: 'action', props: { label: 'Toggle Theme', icon: 'dark_mode', onClick: toggleMode } },
70
+ ]}
71
+ />
72
+ ~~~
73
+
74
+ ---
75
+ ## Example: React Integration with Layout
76
+ ~~~tsx
77
+ <Layout
78
+ topBarConfig={{
79
+ title: "Responsive Shell",
80
+ elementsRight: [
81
+ {
82
+ type: "action",
83
+ props: {
84
+ element: <ThemeModeToggle variant="minimal" show="icons" iconSize="small" />,
85
+ },
86
+ },
87
+ ],
88
+ }}
89
+ leftSidebarConfig={{
90
+ elements: [
91
+ { type: "link", props: { label: "Overview", icon: "dashboard", iconColor: "var(--gui-primary)" } },
92
+ { type: "link", props: { label: "Reports", icon: "insights", iconColor: "var(--gui-secondary)" } },
93
+ ],
94
+ }}
95
+ rightSidebarConfig={{
96
+ elements: [
97
+ { type: "link", props: { label: "Alerts", icon: "notifications", iconColor: "var(--gui-warning)" } },
98
+ { type: "action", props: { label: "Export", icon: "download", iconColor: "var(--gui-success)" } },
99
+ ],
100
+ }}
101
+ footerConfig={{
102
+ title: "Neuroverse",
103
+ logoSrc: "/logo.svg",
104
+ links: [
105
+ { name: "Docs", url: "/docs", icon: "menu_book" },
106
+ { name: "API", url: "/api", icon: "code" },
107
+ ],
108
+ socialLinks: [
109
+ { name: "GitHub", url: "https://github.com", icon: "code" },
110
+ { name: "Community", url: "https://community.neuroverse.ai", icon: "forum" },
111
+ ],
112
+ position: "fixed",
113
+ }}
114
+ >
115
+ {/* Main content goes here */}
116
+ </Layout>
117
+ ~~~
118
+ `,
119
+ },
120
+ },
121
+ },
122
+ };
123
+
124
+ export default meta;
125
+ type Story = StoryObj<typeof Footer>;
126
+
127
+ export const Default: Story = {
128
+ args: {
129
+ brandLabel: "Neuroverse",
130
+ brandLogo: "https://neurons.me/neurons.me.png",
131
+ brandHref: "/",
132
+ leftElements: [
133
+ { type: "link", props: { label: "Status", icon: "monitor_heart", href: "/status", iconColor: "var(--gui-info)" } },
134
+ { type: "link", props: { label: "Changelog", icon: "history", href: "/changelog", iconColor: "var(--gui-warning)" } },
135
+ ],
136
+ centerElements: [
137
+ { type: "link", props: { label: "Docs", icon: "menu_book", href: "/docs", iconColor: "var(--gui-primary)" } },
138
+ { type: "link", props: { label: "Community", icon: "forum", href: "https://community.neuroverse.ai", external: true, iconColor: "var(--gui-secondary)" } },
139
+ ],
140
+ rightElements: [
141
+ { type: "action", props: { label: "Contact", icon: "support_agent", iconColor: "var(--gui-success)" } },
142
+ { type: "action", props: { label: "Theme", icon: "dark_mode", iconColor: "var(--gui-primary)" } },
143
+ ],
144
+ position: "static",
145
+ },
146
+ };
147
+
148
+ export const FixedFooter: Story = {
149
+ args: {
150
+ ...Default.args,
151
+ position: "fixed",
152
+ },
153
+ };
154
+
155
+ export const WithLayout: Story = {
156
+ render: () => (
157
+ <Layout
158
+ topBarConfig={{
159
+ title: "Responsive Shell",
160
+ elementsRight: [
161
+ {
162
+ type: "action",
163
+ props: {
164
+ element: <ThemeModeToggle variant="minimal" show="icons" iconSize="small" />,
165
+ },
166
+ },
167
+ ],
168
+ }}
169
+ leftSidebarConfig={{
170
+ elements: [
171
+ { type: "link", props: { label: "Overview", icon: "dashboard", iconColor: "var(--gui-primary)" } },
172
+ { type: "link", props: { label: "Reports", icon: "insights", iconColor: "var(--gui-secondary)" } },
173
+ ],
174
+ }}
175
+ rightSidebarConfig={{
176
+ elements: [
177
+ { type: "link", props: { label: "Alerts", icon: "notifications", iconColor: "var(--gui-warning)" } },
178
+ { type: "action", props: { label: "Export", icon: "download", iconColor: "var(--gui-success)" } },
179
+ ],
180
+ }}
181
+ footerConfig={ {
182
+ title: "Neuroverse",
183
+ logoSrc: "https://neurons.me/neurons.me.png",
184
+ links: [
185
+ { name: "Docs", url: "/docs", icon: "menu_book" },
186
+ { name: "API", url: "/api", icon: "code" },
187
+ ],
188
+ socialLinks: [
189
+ { name: "GitHub", url: "https://github.com", icon: "code" },
190
+ { name: "Community", url: "https://community.neuroverse.ai", icon: "forum" },
191
+ ],
192
+ position: "fixed",
193
+ } as any}
194
+ >
195
+ <div style={{ minHeight: '120vh', padding: '72px 24px 120px' }}>
196
+ <h2 style={{ marginBottom: 16 }}>Dashboard Content</h2>
197
+ <p>
198
+ Resize the viewport to see how the TopBar, LeftSidebar, RightSidebar, and Footer coordinate
199
+ their insets. The footer collapses labels below the medium breakpoint while keeping icons and
200
+ tooltips.
201
+ </p>
202
+ </div>
203
+ </Layout>
204
+ ),
205
+ };
@@ -0,0 +1,337 @@
1
+ import { useEffect, useMemo, useRef } from 'react';
2
+ import { AppBar, Box, Toolbar, Typography, Avatar, Tooltip } from '@/gui/components/atoms';
3
+ import { Link as RouterLink } from 'react-router-dom';
4
+ import Icon from '@/gui/Theme/Icon/Icon';
5
+ import { useGuiTheme, useGuiMediaQuery, useInsets, useUpdateInsets } from '@/gui/hooks';
6
+ import type { FooterProps, FooterElement } from './Footer.types';
7
+ import type { FooterLinkProps, FooterActionProps } from './Footer.types';
8
+ import type { SxProps, Theme } from '@mui/material/styles';
9
+
10
+ const sxN = (...parts: Array<SxProps<Theme> | undefined>): SxProps<Theme> =>
11
+ (parts.filter(Boolean) as unknown) as SxProps<Theme>;
12
+
13
+ type FooterLinkRenderProps = FooterLinkProps & {
14
+ showLabel: boolean;
15
+ };
16
+
17
+ type FooterActionRenderProps = FooterActionProps & {
18
+ showLabel: boolean;
19
+ };
20
+
21
+ const FooterLink = ({
22
+ label,
23
+ icon,
24
+ iconColor,
25
+ href,
26
+ external,
27
+ onClick,
28
+ showLabel,
29
+ }: FooterLinkRenderProps) => {
30
+ const content = (
31
+ <Box
32
+ sx={{
33
+ display: 'flex',
34
+ alignItems: 'center',
35
+ gap: showLabel ? 1 : 0,
36
+ color: 'inherit',
37
+ textDecoration: 'none',
38
+ px: showLabel ? 1.5 : 0.75,
39
+ py: 0.75,
40
+ borderRadius: 1,
41
+ transition: 'background-color 0.2s ease, color 0.2s ease',
42
+ '&:hover': {
43
+ backgroundColor: 'action.hover',
44
+ },
45
+ }}
46
+ >
47
+ {icon && <Icon name={icon} iconColor={iconColor} />}
48
+ {showLabel && label && (
49
+ <Typography variant="body2" sx={{ fontWeight: 500 }}>
50
+ {label}
51
+ </Typography>
52
+ )}
53
+ </Box>
54
+ );
55
+
56
+ const wrappedContent =
57
+ !showLabel && label ? (
58
+ <Tooltip title={label} placement="top">
59
+ <span style={{ display: 'inline-flex' }}>{content}</span>
60
+ </Tooltip>
61
+ ) : (
62
+ content
63
+ );
64
+
65
+ const commonProps = {
66
+ onClick,
67
+ style: { color: 'inherit' },
68
+ };
69
+
70
+ if (href) {
71
+ const component = href.startsWith('http')
72
+ ? 'a'
73
+ : RouterLink;
74
+ return (
75
+ <Box
76
+ component={component as any}
77
+ to={!href.startsWith('http') ? href : undefined}
78
+ href={href.startsWith('http') ? href : undefined}
79
+ target={external ? '_blank' : undefined}
80
+ rel={external ? 'noopener noreferrer' : undefined}
81
+ sx={{ display: 'inline-flex' }}
82
+ {...commonProps}
83
+ >
84
+ {wrappedContent}
85
+ </Box>
86
+ );
87
+ }
88
+
89
+ return (
90
+ <Box component="button" type="button" sx={{ display: 'inline-flex', background: 'none', border: 'none', p: 0 }} {...commonProps}>
91
+ {wrappedContent}
92
+ </Box>
93
+ );
94
+ };
95
+
96
+ const FooterAction = ({
97
+ label,
98
+ icon,
99
+ iconColor,
100
+ onClick,
101
+ element,
102
+ showLabel,
103
+ }: FooterActionRenderProps) => {
104
+ if (element) {
105
+ return <Box sx={{ display: 'inline-flex', alignItems: 'center' }}>{element}</Box>;
106
+ }
107
+
108
+ const content = (
109
+ <Box
110
+ sx={{
111
+ display: 'flex',
112
+ alignItems: 'center',
113
+ gap: showLabel ? 1 : 0,
114
+ px: showLabel ? 1.5 : 0.75,
115
+ py: 0.75,
116
+ borderRadius: 1,
117
+ transition: 'background-color 0.2s ease',
118
+ '&:hover': { backgroundColor: 'action.hover' },
119
+ color: 'inherit',
120
+ }}
121
+ onClick={onClick}
122
+ role="button"
123
+ >
124
+ {icon && <Icon name={icon} iconColor={iconColor} />}
125
+ {showLabel && label && (
126
+ <Typography variant="body2" sx={{ fontWeight: 500 }}>
127
+ {label}
128
+ </Typography>
129
+ )}
130
+ </Box>
131
+ );
132
+
133
+ if (!showLabel && label) {
134
+ return (
135
+ <Tooltip title={label} placement="top">
136
+ <span style={{ display: 'inline-flex' }}>{content}</span>
137
+ </Tooltip>
138
+ );
139
+ }
140
+
141
+ return content;
142
+ };
143
+
144
+ function renderFooterElement(el: FooterElement, showLabel: boolean, key: string | number) {
145
+ if (el.type === 'link') return <FooterLink key={key} {...el.props} showLabel={showLabel} />;
146
+ if (el.type === 'action') return <FooterAction key={key} {...el.props} showLabel={showLabel} />;
147
+ return null;
148
+ }
149
+
150
+ export default function Footer(props: FooterProps) {
151
+ const {
152
+ brandLabel = '',
153
+ brandLogo = '',
154
+ brandHref = '/',
155
+ brandAvatarFallback,
156
+ leftElements = [],
157
+ centerElements = [],
158
+ rightElements = [],
159
+ position = 'static',
160
+ elevation = 0,
161
+ className,
162
+ id,
163
+ sx,
164
+ appBarSx,
165
+ sectionSx,
166
+ 'data-testid': dataTestId,
167
+ } = props;
168
+
169
+ const theme = useGuiTheme();
170
+ const isMobile = useGuiMediaQuery(theme.breakpoints.down('sm'));
171
+ const isTablet = useGuiMediaQuery(theme.breakpoints.between('sm', 'md'));
172
+ const isDesktop = useGuiMediaQuery(theme.breakpoints.up('md'));
173
+ const showLabels = isDesktop;
174
+ const showBrandLabel = !isMobile;
175
+
176
+ const insets = useInsets();
177
+ const updateInsets = useUpdateInsets();
178
+ const toolbarRef = useRef<HTMLDivElement | null>(null);
179
+ const appBarRef = useRef<HTMLDivElement | null>(null);
180
+
181
+ const insetLeft = Math.max(0, Number(insets?.left ?? 0));
182
+ const insetRight = Math.max(0, Number(insets?.right ?? 0));
183
+ const horizontalInset = insetLeft + insetRight;
184
+
185
+ const brandVisual = useMemo(() => {
186
+ if (brandLogo) {
187
+ return <Box component="img" src={brandLogo} alt={brandLabel ? `${brandLabel} logo` : 'Footer logo'} sx={{ height: 24 }} />;
188
+ }
189
+ const fallback = brandAvatarFallback || brandLabel?.trim().charAt(0)?.toUpperCase() || '?';
190
+ return <Avatar sx={{ width: 28, height: 28, fontSize: '0.875rem' }}>{fallback}</Avatar>;
191
+ }, [brandAvatarFallback, brandLabel, brandLogo]);
192
+
193
+ useEffect(() => {
194
+ if (typeof updateInsets !== 'function') return;
195
+ const measure = () => {
196
+ const target = appBarRef.current ?? toolbarRef.current;
197
+ const h = target?.offsetHeight ?? 56;
198
+ updateInsets({ bottom: position === 'fixed' || position === 'sticky' ? h : 0 });
199
+ };
200
+ measure();
201
+
202
+ let ro: ResizeObserver | undefined;
203
+ if (typeof ResizeObserver !== 'undefined') {
204
+ const target = appBarRef.current ?? toolbarRef.current;
205
+ if (target) {
206
+ ro = new ResizeObserver(() => measure());
207
+ ro.observe(target);
208
+ }
209
+ }
210
+
211
+ return () => {
212
+ if (ro) ro.disconnect();
213
+ updateInsets({ bottom: 0 });
214
+ };
215
+ }, [position, updateInsets, isMobile, isTablet]);
216
+
217
+ const isFixed = position === 'fixed' || position === 'sticky';
218
+ const baseAppBarSx = {
219
+ top: 'auto',
220
+ bottom: 0,
221
+ backgroundColor: theme.palette.background.paper ?? theme.palette.grey[900],
222
+ borderTop: '1px solid',
223
+ borderColor: theme.palette.divider,
224
+ minHeight: 56,
225
+ zIndex: (theme.zIndex?.appBar ?? 1100) - 1,
226
+ boxShadow: 'none',
227
+ ...(isFixed
228
+ ? {
229
+ position: 'fixed',
230
+ left: `${insetLeft}px`,
231
+ right: `${insetRight}px`,
232
+ width: `calc(100% - ${horizontalInset}px)`,
233
+ transition: 'left 0.3s ease, right 0.3s ease, width 0.3s ease',
234
+ }
235
+ : {
236
+ position: 'static',
237
+ left: `${insetLeft}px`,
238
+ right: `${insetRight}px`,
239
+ width: `calc(100% - ${horizontalInset}px)`,
240
+ transition: 'margin-left 0.3s ease, margin-right 0.3s ease, width 0.3s ease',
241
+ }),
242
+ } as const;
243
+
244
+ const flowAppBarSx = !isFixed
245
+ ? ({
246
+ ml: `${insetLeft}px`,
247
+ mr: `${insetRight}px`,
248
+ width: `calc(100% - ${horizontalInset}px)`,
249
+ transition: 'margin-left 0.3s ease, margin-right 0.3s ease, width 0.3s ease',
250
+ } as SxProps<Theme>)
251
+ : undefined;
252
+
253
+ return (
254
+ <AppBar
255
+ ref={appBarRef}
256
+ id={id}
257
+ className={className}
258
+ data-testid={dataTestId}
259
+ position={position}
260
+ elevation={elevation}
261
+ sx={sxN(baseAppBarSx as SxProps<Theme>, flowAppBarSx, sx, appBarSx)}
262
+ >
263
+ <Toolbar
264
+ ref={toolbarRef}
265
+ variant="dense"
266
+ disableGutters
267
+ sx={sxN(
268
+ {
269
+ minHeight: 56,
270
+ px: 1.5,
271
+ py: 1,
272
+ display: 'flex',
273
+ alignItems: 'center',
274
+ justifyContent: 'space-between',
275
+ gap: 1.5,
276
+ },
277
+ sectionSx
278
+ )}
279
+ >
280
+ <Box
281
+ sx={{
282
+ display: 'flex',
283
+ alignItems: 'center',
284
+ gap: showLabels ? 1 : 0.5,
285
+ color: 'text.secondary',
286
+ flexShrink: 0,
287
+ }}
288
+ >
289
+ {leftElements.map((el, idx) => renderFooterElement(el, showLabels, `left-${idx}`))}
290
+ </Box>
291
+
292
+ <Box
293
+ sx={{
294
+ display: 'flex',
295
+ alignItems: 'center',
296
+ gap: showLabels ? 1 : 0.5,
297
+ flex: 1,
298
+ justifyContent: 'center',
299
+ color: 'text.secondary',
300
+ }}
301
+ >
302
+ {centerElements.map((el, idx) => renderFooterElement(el, showLabels, `center-${idx}`))}
303
+ </Box>
304
+
305
+ <Box
306
+ sx={{
307
+ display: 'flex',
308
+ alignItems: 'center',
309
+ gap: showLabels ? 1 : 0.75,
310
+ color: 'text.secondary',
311
+ flexShrink: 0,
312
+ }}
313
+ >
314
+ {rightElements.map((el, idx) => renderFooterElement(el, showLabels, `right-${idx}`))}
315
+ <Box
316
+ sx={{
317
+ display: 'flex',
318
+ alignItems: 'center',
319
+ gap: showBrandLabel ? 1 : 0.75,
320
+ textDecoration: 'none',
321
+ color: 'inherit',
322
+ }}
323
+ component={brandHref ? RouterLink : 'div'}
324
+ to={brandHref ? brandHref : undefined}
325
+ >
326
+ {brandVisual}
327
+ {showBrandLabel && brandLabel && (
328
+ <Typography variant="body2" sx={{ fontWeight: 600 }}>
329
+ {brandLabel}
330
+ </Typography>
331
+ )}
332
+ </Box>
333
+ </Box>
334
+ </Toolbar>
335
+ </AppBar>
336
+ );
337
+ }