@peers-app/peers-ui 0.0.14

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 (404) hide show
  1. package/.github/README.md +52 -0
  2. package/.github/workflows/publish.yml +45 -0
  3. package/babel.config.js +7 -0
  4. package/dist/app.d.ts +9 -0
  5. package/dist/app.js +54 -0
  6. package/dist/command-palette/command-palette-ui.d.ts +2 -0
  7. package/dist/command-palette/command-palette-ui.js +192 -0
  8. package/dist/command-palette/command-palette.d.ts +23 -0
  9. package/dist/command-palette/command-palette.js +371 -0
  10. package/dist/components/checkbox.d.ts +7 -0
  11. package/dist/components/checkbox.js +20 -0
  12. package/dist/components/group-switcher.d.ts +6 -0
  13. package/dist/components/group-switcher.js +301 -0
  14. package/dist/components/input-date.d.ts +7 -0
  15. package/dist/components/input-date.js +19 -0
  16. package/dist/components/input-datetime.d.ts +7 -0
  17. package/dist/components/input-datetime.js +35 -0
  18. package/dist/components/input-number.d.ts +9 -0
  19. package/dist/components/input-number.js +87 -0
  20. package/dist/components/input.d.ts +7 -0
  21. package/dist/components/input.js +20 -0
  22. package/dist/components/io-schema-values.d.ts +15 -0
  23. package/dist/components/io-schema-values.js +105 -0
  24. package/dist/components/io-schema.d.ts +13 -0
  25. package/dist/components/io-schema.js +163 -0
  26. package/dist/components/lazy-list.d.ts +13 -0
  27. package/dist/components/lazy-list.js +91 -0
  28. package/dist/components/lazy-sortable-list.d.ts +29 -0
  29. package/dist/components/lazy-sortable-list.js +12 -0
  30. package/dist/components/left-bar.d.ts +3 -0
  31. package/dist/components/left-bar.js +130 -0
  32. package/dist/components/list-screen.d.ts +16 -0
  33. package/dist/components/list-screen.js +100 -0
  34. package/dist/components/loading-indicator.d.ts +2 -0
  35. package/dist/components/loading-indicator.js +12 -0
  36. package/dist/components/main-content-container.d.ts +2 -0
  37. package/dist/components/main-content-container.js +90 -0
  38. package/dist/components/markdown-editor/autolink-plugin.d.ts +2 -0
  39. package/dist/components/markdown-editor/autolink-plugin.js +29 -0
  40. package/dist/components/markdown-editor/editor-inline.d.ts +3 -0
  41. package/dist/components/markdown-editor/editor-inline.js +13 -0
  42. package/dist/components/markdown-editor/editor.d.ts +18 -0
  43. package/dist/components/markdown-editor/editor.js +143 -0
  44. package/dist/components/markdown-editor/markdown-plugin.d.ts +9 -0
  45. package/dist/components/markdown-editor/markdown-plugin.js +194 -0
  46. package/dist/components/markdown-editor/mention-node.d.ts +21 -0
  47. package/dist/components/markdown-editor/mention-node.js +160 -0
  48. package/dist/components/markdown-editor/mentions-plugin.d.ts +7 -0
  49. package/dist/components/markdown-editor/mentions-plugin.js +268 -0
  50. package/dist/components/markdown-editor/theme.d.ts +46 -0
  51. package/dist/components/markdown-editor/theme.js +48 -0
  52. package/dist/components/markdown-editor/toolbar.d.ts +10 -0
  53. package/dist/components/markdown-editor/toolbar.js +112 -0
  54. package/dist/components/markdown-with-mentions.d.ts +4 -0
  55. package/dist/components/markdown-with-mentions.js +140 -0
  56. package/dist/components/message-logs/message-logs.d.ts +6 -0
  57. package/dist/components/message-logs/message-logs.js +307 -0
  58. package/dist/components/messages/avatar.d.ts +10 -0
  59. package/dist/components/messages/avatar.js +65 -0
  60. package/dist/components/messages/channel-message-list.d.ts +14 -0
  61. package/dist/components/messages/channel-message-list.js +158 -0
  62. package/dist/components/messages/channel-view.d.ts +6 -0
  63. package/dist/components/messages/channel-view.js +82 -0
  64. package/dist/components/messages/message-compose.d.ts +11 -0
  65. package/dist/components/messages/message-compose.js +152 -0
  66. package/dist/components/messages/message-display.d.ts +10 -0
  67. package/dist/components/messages/message-display.js +152 -0
  68. package/dist/components/messages/thread-message-list.d.ts +11 -0
  69. package/dist/components/messages/thread-message-list.js +122 -0
  70. package/dist/components/messages/thread-view.d.ts +6 -0
  71. package/dist/components/messages/thread-view.js +174 -0
  72. package/dist/components/off-canvas.d.ts +13 -0
  73. package/dist/components/off-canvas.js +89 -0
  74. package/dist/components/router.d.ts +6 -0
  75. package/dist/components/router.js +240 -0
  76. package/dist/components/save-button.d.ts +13 -0
  77. package/dist/components/save-button.js +75 -0
  78. package/dist/components/sortable-list.d.ts +36 -0
  79. package/dist/components/sortable-list.js +77 -0
  80. package/dist/components/tabs.d.ts +11 -0
  81. package/dist/components/tabs.js +69 -0
  82. package/dist/components/text-list-editor.tsx/text-list-editor.d.ts +6 -0
  83. package/dist/components/text-list-editor.tsx/text-list-editor.js +13 -0
  84. package/dist/components/tooltip.d.ts +11 -0
  85. package/dist/components/tooltip.js +20 -0
  86. package/dist/components/top-bar.d.ts +2 -0
  87. package/dist/components/top-bar.js +51 -0
  88. package/dist/components/typeahead/mentions-plugin.d.ts +7 -0
  89. package/dist/components/typeahead/mentions-plugin.js +203 -0
  90. package/dist/components/typeahead/typeahead-editor.d.ts +15 -0
  91. package/dist/components/typeahead/typeahead-editor.js +134 -0
  92. package/dist/components/typeahead/typeahead.d.ts +12 -0
  93. package/dist/components/typeahead/typeahead.js +94 -0
  94. package/dist/components/typeahead.d.ts +22 -0
  95. package/dist/components/typeahead.js +270 -0
  96. package/dist/globals.d.ts +29 -0
  97. package/dist/globals.js +148 -0
  98. package/dist/hooks.d.ts +34 -0
  99. package/dist/hooks.js +137 -0
  100. package/dist/index.d.ts +4 -0
  101. package/dist/index.js +20 -0
  102. package/dist/layout-vars.d.ts +6 -0
  103. package/dist/layout-vars.js +10 -0
  104. package/dist/mention-configs.d.ts +18 -0
  105. package/dist/mention-configs.js +149 -0
  106. package/dist/screens/assistants/assistant-config.d.ts +5 -0
  107. package/dist/screens/assistants/assistant-config.js +52 -0
  108. package/dist/screens/assistants/assistant-details.d.ts +4 -0
  109. package/dist/screens/assistants/assistant-details.js +85 -0
  110. package/dist/screens/assistants/assistant-info.d.ts +6 -0
  111. package/dist/screens/assistants/assistant-info.js +28 -0
  112. package/dist/screens/assistants/assistant-list.d.ts +2 -0
  113. package/dist/screens/assistants/assistant-list.js +114 -0
  114. package/dist/screens/assistants/assistant-tools.d.ts +5 -0
  115. package/dist/screens/assistants/assistant-tools.js +38 -0
  116. package/dist/screens/contacts/contact-details.d.ts +6 -0
  117. package/dist/screens/contacts/contact-details.js +100 -0
  118. package/dist/screens/contacts/contact-list.d.ts +2 -0
  119. package/dist/screens/contacts/contact-list.js +213 -0
  120. package/dist/screens/contacts/index.d.ts +4 -0
  121. package/dist/screens/contacts/index.js +21 -0
  122. package/dist/screens/events/cron.d.ts +3 -0
  123. package/dist/screens/events/cron.js +77 -0
  124. package/dist/screens/events/event-details.d.ts +6 -0
  125. package/dist/screens/events/event-details.js +112 -0
  126. package/dist/screens/events/event-handlers.d.ts +7 -0
  127. package/dist/screens/events/event-handlers.js +84 -0
  128. package/dist/screens/events/event-info.d.ts +5 -0
  129. package/dist/screens/events/event-info.js +19 -0
  130. package/dist/screens/events/event-list.d.ts +2 -0
  131. package/dist/screens/events/event-list.js +107 -0
  132. package/dist/screens/events/event-schedule.d.ts +5 -0
  133. package/dist/screens/events/event-schedule.js +124 -0
  134. package/dist/screens/groups/group-details.d.ts +6 -0
  135. package/dist/screens/groups/group-details.js +218 -0
  136. package/dist/screens/groups/group-list.d.ts +2 -0
  137. package/dist/screens/groups/group-list.js +275 -0
  138. package/dist/screens/groups/group-members.d.ts +8 -0
  139. package/dist/screens/groups/group-members.js +315 -0
  140. package/dist/screens/groups/index.d.ts +6 -0
  141. package/dist/screens/groups/index.js +23 -0
  142. package/dist/screens/knowledge/knowledge-frame-details.bk.d.ts +6 -0
  143. package/dist/screens/knowledge/knowledge-frame-details.bk.js +84 -0
  144. package/dist/screens/knowledge/knowledge-frame-details.d.ts +8 -0
  145. package/dist/screens/knowledge/knowledge-frame-details.js +143 -0
  146. package/dist/screens/knowledge/knowledge-frame-list.d.ts +2 -0
  147. package/dist/screens/knowledge/knowledge-frame-list.js +45 -0
  148. package/dist/screens/knowledge/knowledge-value-details.d.ts +6 -0
  149. package/dist/screens/knowledge/knowledge-value-details.js +150 -0
  150. package/dist/screens/knowledge/knowledge-value-list-item.d.ts +5 -0
  151. package/dist/screens/knowledge/knowledge-value-list-item.js +39 -0
  152. package/dist/screens/knowledge/knowledge-value-list.d.ts +3 -0
  153. package/dist/screens/knowledge/knowledge-value-list.js +123 -0
  154. package/dist/screens/packages/package-details.d.ts +6 -0
  155. package/dist/screens/packages/package-details.js +82 -0
  156. package/dist/screens/packages/package-info.d.ts +5 -0
  157. package/dist/screens/packages/package-info.js +42 -0
  158. package/dist/screens/packages/package-list.d.ts +2 -0
  159. package/dist/screens/packages/package-list.js +182 -0
  160. package/dist/screens/packages/package-new-local.d.ts +2 -0
  161. package/dist/screens/packages/package-new-local.js +82 -0
  162. package/dist/screens/peer-types/peer-type-details.d.ts +10 -0
  163. package/dist/screens/peer-types/peer-type-details.js +126 -0
  164. package/dist/screens/peer-types/peer-type-list.d.ts +2 -0
  165. package/dist/screens/peer-types/peer-type-list.js +57 -0
  166. package/dist/screens/predicates/predicate-details.d.ts +6 -0
  167. package/dist/screens/predicates/predicate-details.js +103 -0
  168. package/dist/screens/predicates/predicate-list.d.ts +2 -0
  169. package/dist/screens/predicates/predicate-list.js +46 -0
  170. package/dist/screens/profile.d.ts +2 -0
  171. package/dist/screens/profile.js +66 -0
  172. package/dist/screens/search/global-search.d.ts +2 -0
  173. package/dist/screens/search/global-search.js +186 -0
  174. package/dist/screens/settings/color-mode-dropdown.d.ts +6 -0
  175. package/dist/screens/settings/color-mode-dropdown.js +63 -0
  176. package/dist/screens/settings/settings-page.d.ts +2 -0
  177. package/dist/screens/settings/settings-page.js +49 -0
  178. package/dist/screens/setup-user.d.ts +2 -0
  179. package/dist/screens/setup-user.js +270 -0
  180. package/dist/screens/tools/tool-code.d.ts +5 -0
  181. package/dist/screens/tools/tool-code.js +32 -0
  182. package/dist/screens/tools/tool-details.d.ts +6 -0
  183. package/dist/screens/tools/tool-details.js +68 -0
  184. package/dist/screens/tools/tool-info.d.ts +5 -0
  185. package/dist/screens/tools/tool-info.js +74 -0
  186. package/dist/screens/tools/tool-list.d.ts +2 -0
  187. package/dist/screens/tools/tool-list.js +123 -0
  188. package/dist/screens/tools/tool-schema.d.ts +5 -0
  189. package/dist/screens/tools/tool-schema.js +30 -0
  190. package/dist/screens/tools/tool-test-details.d.ts +4 -0
  191. package/dist/screens/tools/tool-test-details.js +54 -0
  192. package/dist/screens/tools/tool-test-list.d.ts +4 -0
  193. package/dist/screens/tools/tool-test-list.js +82 -0
  194. package/dist/screens/variables/variable-details.d.ts +6 -0
  195. package/dist/screens/variables/variable-details.js +140 -0
  196. package/dist/screens/variables/variable-list.d.ts +2 -0
  197. package/dist/screens/variables/variable-list.js +58 -0
  198. package/dist/screens/workflows/workflow-details.d.ts +6 -0
  199. package/dist/screens/workflows/workflow-details.js +122 -0
  200. package/dist/screens/workflows/workflow-info.d.ts +5 -0
  201. package/dist/screens/workflows/workflow-info.js +18 -0
  202. package/dist/screens/workflows/workflow-instructions.d.ts +5 -0
  203. package/dist/screens/workflows/workflow-instructions.js +118 -0
  204. package/dist/screens/workflows/workflow-list.d.ts +2 -0
  205. package/dist/screens/workflows/workflow-list.js +109 -0
  206. package/dist/screens/workflows/workflow-subscriptions.d.ts +6 -0
  207. package/dist/screens/workflows/workflow-subscriptions.js +81 -0
  208. package/dist/setupTests.d.ts +1 -0
  209. package/dist/setupTests.js +31 -0
  210. package/dist/system-apps/assistants.app.d.ts +2 -0
  211. package/dist/system-apps/assistants.app.js +8 -0
  212. package/dist/system-apps/contacts.app.d.ts +2 -0
  213. package/dist/system-apps/contacts.app.js +9 -0
  214. package/dist/system-apps/events.app.d.ts +2 -0
  215. package/dist/system-apps/events.app.js +8 -0
  216. package/dist/system-apps/groups.app.d.ts +2 -0
  217. package/dist/system-apps/groups.app.js +9 -0
  218. package/dist/system-apps/index.d.ts +19 -0
  219. package/dist/system-apps/index.js +90 -0
  220. package/dist/system-apps/knowledge-frames.app.d.ts +2 -0
  221. package/dist/system-apps/knowledge-frames.app.js +9 -0
  222. package/dist/system-apps/knowledge-values.app.d.ts +2 -0
  223. package/dist/system-apps/knowledge-values.app.js +9 -0
  224. package/dist/system-apps/packages.app.d.ts +2 -0
  225. package/dist/system-apps/packages.app.js +8 -0
  226. package/dist/system-apps/predicates.app.d.ts +2 -0
  227. package/dist/system-apps/predicates.app.js +8 -0
  228. package/dist/system-apps/profile.app.d.ts +2 -0
  229. package/dist/system-apps/profile.app.js +8 -0
  230. package/dist/system-apps/search.app.d.ts +2 -0
  231. package/dist/system-apps/search.app.js +9 -0
  232. package/dist/system-apps/settings.app.d.ts +2 -0
  233. package/dist/system-apps/settings.app.js +8 -0
  234. package/dist/system-apps/threads.app.d.ts +2 -0
  235. package/dist/system-apps/threads.app.js +8 -0
  236. package/dist/system-apps/tools.app.d.ts +2 -0
  237. package/dist/system-apps/tools.app.js +8 -0
  238. package/dist/system-apps/types.app.d.ts +2 -0
  239. package/dist/system-apps/types.app.js +8 -0
  240. package/dist/system-apps/variables.app.d.ts +2 -0
  241. package/dist/system-apps/variables.app.js +8 -0
  242. package/dist/system-apps/workflows.app.d.ts +2 -0
  243. package/dist/system-apps/workflows.app.js +8 -0
  244. package/dist/tabs-layout/tabs-layout.d.ts +5 -0
  245. package/dist/tabs-layout/tabs-layout.js +374 -0
  246. package/dist/tabs-layout/tabs-state.d.ts +26 -0
  247. package/dist/tabs-layout/tabs-state.js +239 -0
  248. package/dist/three-bar-layout/left-bar-content.d.ts +7 -0
  249. package/dist/three-bar-layout/left-bar-content.js +151 -0
  250. package/dist/three-bar-layout/right-bar-content.d.ts +2 -0
  251. package/dist/three-bar-layout/right-bar-content.js +64 -0
  252. package/dist/three-bar-layout/three-bar-layout.d.ts +5 -0
  253. package/dist/three-bar-layout/three-bar-layout.js +218 -0
  254. package/dist/ui-defaults/index.d.ts +2 -0
  255. package/dist/ui-defaults/index.js +4 -0
  256. package/dist/ui-defaults/list-screen.d.ts +6 -0
  257. package/dist/ui-defaults/list-screen.js +74 -0
  258. package/dist/ui-defaults/notes-editor.d.ts +7 -0
  259. package/dist/ui-defaults/notes-editor.js +41 -0
  260. package/dist/ui-router/routes-loader.d.ts +25 -0
  261. package/dist/ui-router/routes-loader.js +97 -0
  262. package/dist/ui-router/ui-loader.d.ts +18 -0
  263. package/dist/ui-router/ui-loader.js +481 -0
  264. package/dist/utils.d.ts +9 -0
  265. package/dist/utils.js +250 -0
  266. package/docs/conversation-tab.md +201 -0
  267. package/docs/getting-started.md +284 -0
  268. package/docs/knowledge.md +187 -0
  269. package/docs/tabs-ui.md +696 -0
  270. package/docs/user-contacts-ui.md +384 -0
  271. package/jest.config.js +25 -0
  272. package/package.json +109 -0
  273. package/src/app.tsx +59 -0
  274. package/src/command-palette/command-palette-ui.tsx +264 -0
  275. package/src/command-palette/command-palette.ts +364 -0
  276. package/src/components/checkbox.tsx +22 -0
  277. package/src/components/group-switcher.tsx +469 -0
  278. package/src/components/input-date.tsx +28 -0
  279. package/src/components/input-datetime.tsx +41 -0
  280. package/src/components/input-number.tsx +67 -0
  281. package/src/components/input.tsx +22 -0
  282. package/src/components/io-schema-values.tsx +122 -0
  283. package/src/components/io-schema.tsx +234 -0
  284. package/src/components/lazy-list.tsx +98 -0
  285. package/src/components/lazy-sortable-list.tsx +51 -0
  286. package/src/components/left-bar.tsx +264 -0
  287. package/src/components/list-screen.tsx +105 -0
  288. package/src/components/loading-indicator.tsx +9 -0
  289. package/src/components/main-content-container.tsx +76 -0
  290. package/src/components/markdown-editor/autolink-plugin.tsx +36 -0
  291. package/src/components/markdown-editor/editor-inline.tsx +10 -0
  292. package/src/components/markdown-editor/editor.tsx +152 -0
  293. package/src/components/markdown-editor/markdown-plugin.tsx +224 -0
  294. package/src/components/markdown-editor/mention-node.ts +199 -0
  295. package/src/components/markdown-editor/mentions-plugin.tsx +356 -0
  296. package/src/components/markdown-editor/theme.ts +47 -0
  297. package/src/components/markdown-editor/toolbar.tsx +263 -0
  298. package/src/components/markdown-with-mentions.tsx +183 -0
  299. package/src/components/message-logs/message-logs.tsx +406 -0
  300. package/src/components/messages/avatar.tsx +95 -0
  301. package/src/components/messages/channel-message-list.tsx +177 -0
  302. package/src/components/messages/channel-view.tsx +74 -0
  303. package/src/components/messages/message-compose.tsx +162 -0
  304. package/src/components/messages/message-display.tsx +217 -0
  305. package/src/components/messages/thread-message-list.tsx +126 -0
  306. package/src/components/messages/thread-view.tsx +214 -0
  307. package/src/components/off-canvas.tsx +83 -0
  308. package/src/components/router.tsx +224 -0
  309. package/src/components/save-button.tsx +109 -0
  310. package/src/components/sortable-list.tsx +102 -0
  311. package/src/components/tabs.tsx +70 -0
  312. package/src/components/text-list-editor.tsx/text-list-editor.tsx +13 -0
  313. package/src/components/tooltip.tsx +50 -0
  314. package/src/components/top-bar.tsx +119 -0
  315. package/src/components/typeahead/mentions-plugin.tsx +265 -0
  316. package/src/components/typeahead/typeahead-editor.tsx +140 -0
  317. package/src/components/typeahead/typeahead.tsx +77 -0
  318. package/src/components/typeahead.tsx +359 -0
  319. package/src/globals.tsx +162 -0
  320. package/src/hooks.ts +144 -0
  321. package/src/index.tsx +8 -0
  322. package/src/layout-vars.ts +8 -0
  323. package/src/mention-configs.ts +166 -0
  324. package/src/screens/assistants/assistant-config.tsx +80 -0
  325. package/src/screens/assistants/assistant-details.tsx +77 -0
  326. package/src/screens/assistants/assistant-info.tsx +45 -0
  327. package/src/screens/assistants/assistant-list.tsx +115 -0
  328. package/src/screens/assistants/assistant-tools.tsx +61 -0
  329. package/src/screens/contacts/contact-details.tsx +175 -0
  330. package/src/screens/contacts/contact-list.tsx +251 -0
  331. package/src/screens/contacts/index.ts +6 -0
  332. package/src/screens/events/cron.ts +74 -0
  333. package/src/screens/events/event-details.tsx +117 -0
  334. package/src/screens/events/event-handlers.tsx +61 -0
  335. package/src/screens/events/event-info.tsx +29 -0
  336. package/src/screens/events/event-list.tsx +104 -0
  337. package/src/screens/events/event-schedule.tsx +130 -0
  338. package/src/screens/groups/group-details.tsx +306 -0
  339. package/src/screens/groups/group-list.tsx +366 -0
  340. package/src/screens/groups/group-members.tsx +455 -0
  341. package/src/screens/groups/index.ts +9 -0
  342. package/src/screens/knowledge/knowledge-frame-details.bk.tsx +160 -0
  343. package/src/screens/knowledge/knowledge-frame-details.tsx +176 -0
  344. package/src/screens/knowledge/knowledge-frame-list.tsx +49 -0
  345. package/src/screens/knowledge/knowledge-value-details.tsx +181 -0
  346. package/src/screens/knowledge/knowledge-value-list-item.tsx +48 -0
  347. package/src/screens/knowledge/knowledge-value-list.tsx +131 -0
  348. package/src/screens/packages/package-details.tsx +117 -0
  349. package/src/screens/packages/package-info.tsx +83 -0
  350. package/src/screens/packages/package-list.tsx +191 -0
  351. package/src/screens/packages/package-new-local.tsx +93 -0
  352. package/src/screens/peer-types/peer-type-details.tsx +162 -0
  353. package/src/screens/peer-types/peer-type-list.tsx +74 -0
  354. package/src/screens/predicates/predicate-details.tsx +125 -0
  355. package/src/screens/predicates/predicate-list.tsx +50 -0
  356. package/src/screens/profile.tsx +68 -0
  357. package/src/screens/search/global-search.tsx +274 -0
  358. package/src/screens/settings/color-mode-dropdown.tsx +57 -0
  359. package/src/screens/settings/settings-page.tsx +76 -0
  360. package/src/screens/setup-user.tsx +367 -0
  361. package/src/screens/tools/tool-code.tsx +35 -0
  362. package/src/screens/tools/tool-details.tsx +101 -0
  363. package/src/screens/tools/tool-info.tsx +60 -0
  364. package/src/screens/tools/tool-list.tsx +121 -0
  365. package/src/screens/tools/tool-schema.tsx +42 -0
  366. package/src/screens/tools/tool-test-details.tsx +100 -0
  367. package/src/screens/tools/tool-test-list.tsx +74 -0
  368. package/src/screens/variables/variable-details.tsx +183 -0
  369. package/src/screens/variables/variable-list.tsx +74 -0
  370. package/src/screens/workflows/workflow-details.tsx +130 -0
  371. package/src/screens/workflows/workflow-info.tsx +29 -0
  372. package/src/screens/workflows/workflow-instructions.tsx +127 -0
  373. package/src/screens/workflows/workflow-list.tsx +107 -0
  374. package/src/screens/workflows/workflow-subscriptions.tsx +58 -0
  375. package/src/setupTests.ts +32 -0
  376. package/src/system-apps/assistants.app.ts +7 -0
  377. package/src/system-apps/contacts.app.ts +8 -0
  378. package/src/system-apps/events.app.ts +7 -0
  379. package/src/system-apps/groups.app.ts +8 -0
  380. package/src/system-apps/index.ts +79 -0
  381. package/src/system-apps/knowledge-frames.app.ts +8 -0
  382. package/src/system-apps/knowledge-values.app.ts +8 -0
  383. package/src/system-apps/packages.app.ts +7 -0
  384. package/src/system-apps/predicates.app.ts +7 -0
  385. package/src/system-apps/profile.app.ts +7 -0
  386. package/src/system-apps/search.app.ts +8 -0
  387. package/src/system-apps/settings.app.ts +7 -0
  388. package/src/system-apps/threads.app.ts +7 -0
  389. package/src/system-apps/tools.app.ts +7 -0
  390. package/src/system-apps/types.app.ts +7 -0
  391. package/src/system-apps/variables.app.ts +7 -0
  392. package/src/system-apps/workflows.app.ts +7 -0
  393. package/src/tabs-layout/tabs-layout.tsx +672 -0
  394. package/src/tabs-layout/tabs-state.ts +269 -0
  395. package/src/three-bar-layout/left-bar-content.tsx +202 -0
  396. package/src/three-bar-layout/right-bar-content.tsx +67 -0
  397. package/src/three-bar-layout/three-bar-layout.tsx +297 -0
  398. package/src/ui-defaults/index.ts +3 -0
  399. package/src/ui-defaults/list-screen.tsx +92 -0
  400. package/src/ui-defaults/notes-editor.tsx +51 -0
  401. package/src/ui-router/routes-loader.ts +98 -0
  402. package/src/ui-router/ui-loader.tsx +497 -0
  403. package/src/utils.ts +266 -0
  404. package/tsconfig.json +24 -0
@@ -0,0 +1,264 @@
1
+ import { IPackage, Packages } from "@peers-app/peers-sdk";
2
+ import React from 'react';
3
+ import { isDesktop, mainContentPath } from '../globals';
4
+ import { useObservable, usePromise } from '../hooks';
5
+ import { OffCanvas } from './off-canvas';
6
+ // import { useObservable } from 'peers-ui';
7
+
8
+ const offCanvasEffects = { hide: () => {} };
9
+
10
+ export const LeftBar = () => {
11
+ const [_isDesktop] = useObservable(isDesktop);
12
+
13
+ // const [usersAndGroups, setUsersAndGroups] = useState<(IUser | IGroup)[]>([]);
14
+
15
+ if (_isDesktop) {
16
+ return (
17
+ <div
18
+ className='left-bar-desktop'
19
+ style={{ position: 'fixed', top: 0, left: 0 }}
20
+ >
21
+ <LeftBarContent />
22
+ </div>
23
+ )
24
+ } else {
25
+ return (
26
+ <OffCanvas id="leftBar" position="left" keepOpen={_isDesktop} effects={offCanvasEffects}>
27
+ <LeftBarContent />
28
+ </OffCanvas>
29
+ )
30
+ }
31
+ }
32
+
33
+ export const LeftBarContent = () => {
34
+ const [contentPath] = useObservable(mainContentPath);
35
+ const [_isDesktop] = useObservable(isDesktop);
36
+
37
+ const packagesWithNavItems = usePromise(async () => {
38
+ const packages = await Packages().list();
39
+ return packages.filter(pkg => pkg.appNavs?.length);
40
+ }, []);
41
+
42
+ const knowledgeSublinks = [
43
+ { text: "Frames", icon: "bi bi-window-dock", path: "knowledge-frames", left: 15 },
44
+ { text: "Predicates", icon: "bi bi-node-plus-fill", left: 15 },
45
+ { text: "Graph", icon: "bi bi-diagram-3-fill", left: 15 },
46
+ ]
47
+
48
+ const knowledgeSublinkActive = contentPath.startsWith('knowledge-') || knowledgeSublinks.find(ks => contentPath.startsWith(ks.path || ks.text.toLowerCase()));
49
+
50
+ const containerClassName = `d-flex flex-column flex-shrink-0 p-2 text-white ` + (_isDesktop ? 'bg-dark-subtle' : 'bg-dark');
51
+
52
+ const content = (
53
+ <div className={containerClassName} style={{ width: "300px", height: "100vh" }} >
54
+ <div className="clearfix"
55
+ // style={{ borderBottom: 'solid', borderColor: '#606365', borderWidth: '1px' }}
56
+ >
57
+ <div className="dropdown" style={{ display: 'inline-block', width: '200px' }}>
58
+ <a
59
+ id="dropdownUser1"
60
+ data-bs-toggle="dropdown"
61
+ aria-expanded="false"
62
+ className="d-flex align-items-center text-white text-decoration-none"
63
+ href="#"
64
+ tabIndex={-1}
65
+ >
66
+ <span className="fs-4">Peers</span>
67
+ &nbsp;&nbsp;&nbsp;
68
+ <i className="bi bi-three-dots-vertical" style={{ fontSize: '12pt' }}></i>
69
+ </a>
70
+ <ul
71
+ className="dropdown-menu dropdown-menu-end dropdown-menu-dark text-small shadow"
72
+ style={{ border: '1px grey solid' }}
73
+ aria-labelledby="dropdownUser1"
74
+ >
75
+ {/* <li><a className="dropdown-item" href="#groups/create">New Group</a></li>
76
+ <li><hr className="dropdown-divider" /></li> */}
77
+ <li><a className="dropdown-item" href="#profile">Profile</a></li>
78
+ <li><a className="dropdown-item" href="#settings">Settings</a></li>
79
+ </ul>
80
+ </div>
81
+ </div>
82
+
83
+ <hr className='p-0' />
84
+
85
+ <MenuSection
86
+ menuItems={[
87
+ // { text: "Shell", icon: "bi bi-robot" },
88
+ // { text: "Threads", icon: "bi bi-terminal", path: "shell" },
89
+ // { text: "Journal", icon: "bi bi-journal-text" },
90
+ // { text: "Journal", icon: "bi bi-journal-bookmark" },
91
+ // { text: "Tasks", icon: "bi bi-list-task" },
92
+ // { text: "Calendar", icon: "bi bi-calendar-week", link: "calendar" },
93
+ // { text: "AI Models", icon: "bi bi-cpu" },
94
+ { text: "Variables", icon: "bi bi-braces" },
95
+ { text: "Types", icon: "bi bi-code-square", path: "peer-types" },
96
+ { text: "Assistants", icon: "bi bi-person-fill-gear" },
97
+ { text: "Tools", icon: "bi bi-tools" },
98
+ { text: "Workflows", icon: "bi bi-database-fill-gear" },
99
+ { text: "Events", icon: "bi bi-lightning-charge-fill" },
100
+ { text: "Packages", icon: "bi bi-box-fill" },
101
+ // { text: "Notes", icon: "bi bi-collection" },
102
+ ]}
103
+ />
104
+
105
+ <hr />
106
+
107
+ <MenuSection
108
+ menuItems={[
109
+ { text: "Threads", icon: "bi bi-cpu", path: "shell" },
110
+
111
+ { text: `Knowledge ${knowledgeSublinkActive ? '' : '+'}`, icon: "bi bi-journal-bookmark-fill", path: "knowledge-values" },
112
+ ...(knowledgeSublinkActive && knowledgeSublinks || []),
113
+ ]}
114
+ />
115
+
116
+ {(packagesWithNavItems?.length ?? 0) > 0 && packagesWithNavItems?.map(p => <PackageNavItems key={p.packageId} pkg={p} />)}
117
+
118
+
119
+ {/* <hr />
120
+ <label style={{ color: 'silver' }}>Feeds</label>
121
+ <MenuSection
122
+ menuItems={[
123
+ { text: "Public", icon: "bi bi-globe" },
124
+ { text: "Trusted", icon: "bi bi-person-fill-lock" },
125
+ ]}
126
+ /> */}
127
+
128
+ {/* <hr /> */}
129
+ {/* <label style={{ color: 'silver' }}>Channels & Groups</label>
130
+ coming soon... */}
131
+
132
+
133
+ {/* {MenuSection({
134
+ menuItems: usersAndGroups.map(ug => ({
135
+ text: ug.name,
136
+ icon: "bi bi-people-fill",
137
+ link: `/#${ug.id}`,
138
+ onClick: () => offCanvasEffects.hide?.(),
139
+ id: ug.id
140
+ }))
141
+ })} */}
142
+
143
+
144
+ </div>
145
+ )
146
+ return content;
147
+ }
148
+
149
+ interface IMenuItemProps {
150
+ text: string
151
+ path?: string
152
+ icon: string
153
+ className?: string
154
+ left?: number
155
+ // onClick?: (...args: any[]) => any
156
+ // id?: string
157
+ }
158
+
159
+ function MenuItem(props: IMenuItemProps) {
160
+ useObservable(mainContentPath);
161
+ const link = props.path ?? props.text.replace(/\s/g, '-').toLowerCase();
162
+ const href = window.location.href.split('#')[1]?.trim() ?? '';
163
+ // let isActive = href.endsWith(link);
164
+ let isActive = href.split('/')[0] === link || href.startsWith(link);
165
+ if (link === 'shell' && !href) {
166
+ isActive = true;
167
+ }
168
+ return (
169
+ <div
170
+ className={`nav-link text-white ${isActive && 'active' || ''} ${props.className || ''}`}
171
+ // onClick={() => window.location = (window.origin + props.link) as any}
172
+ style={{ cursor: "pointer", marginLeft: `${props.left || 0}px` }}
173
+ onClick={() => {
174
+ offCanvasEffects.hide?.();
175
+ mainContentPath(link)
176
+ }}
177
+ >
178
+ <a
179
+ className={`text-white`}
180
+ style={{ textDecoration: 'none' }}
181
+ // onClick={props.onClick}
182
+ >
183
+ <i className={props.icon}></i>
184
+ &nbsp;
185
+ {props.text}
186
+ </a>
187
+ {/*
188
+ {isActive && props.id && (
189
+ <span className="dropdown float-end">
190
+ <span
191
+ id="ddGroupSettings" data-bs-toggle="dropdown" aria-expanded="false"
192
+ className="d-flex align-items-center text-white text-decoration-none"
193
+ onClick={evt => evt.stopPropagation()}
194
+ >
195
+ <i className="bi bi-three-dots-vertical"></i>
196
+ </span>
197
+ <ul
198
+ className="dropdown-menu dropdown-menu-dark text-small shadow"
199
+ aria-labelledby="ddGroupSettings"
200
+ // onClick={props.onClick}
201
+ >
202
+ <li>
203
+ <a className="dropdown-item" href={`/#groups/${props.id}`}>
204
+ Details
205
+ </a>
206
+ </li>
207
+ </ul>
208
+ </span>
209
+ )} */}
210
+ </div>
211
+ );
212
+ }
213
+
214
+ interface IMenuSectionProps {
215
+ menuItems: IMenuItemProps[]
216
+ }
217
+ function MenuSection(props: IMenuSectionProps) {
218
+ return (
219
+ <div className="nav flex-column nav-pills me-3" id="v-pills-tab" role="tablist" aria-orientation="vertical">
220
+
221
+ {props.menuItems.map(mi => <MenuItem key={mi.text + mi.path} {...mi}></MenuItem>)}
222
+
223
+ </div>
224
+ );
225
+ }
226
+
227
+ function PackageNavItems(props: { pkg: IPackage }) {
228
+ const pkg = props.pkg;
229
+ if (!pkg.appNavs || pkg.appNavs.length === 0) {
230
+ return null;
231
+ }
232
+
233
+ // if (pkg.appNavs?.length === 1 && pkg.appNavs[0].name === pkg.name) {
234
+ // const iconClassName = pkg.appNavs[0].iconClassName || "bi bi-question-square";
235
+ // // this package only has one nav item and it's named the same as the package so just show it as a top level item
236
+ // return <MenuItem
237
+ // text={pkg.name}
238
+ // icon={iconClassName}
239
+ // />
240
+ // }
241
+
242
+ return (
243
+ <>
244
+ {pkg.appNavs.length !== 1 || pkg.appNavs[0].name !== pkg.name && (
245
+ <label style={{ color: 'silver' }}>{pkg.name}</label>
246
+ )}
247
+ <MenuSection
248
+ menuItems={
249
+ pkg.appNavs.map(ni => {
250
+ let path = `package-nav/${pkg.packageId}/${(ni.navigationPath ?? ni.name).replace(/[^a-zA-Z0-9]/g, '-').toLowerCase()}`;
251
+ while (path.includes('//')) {
252
+ path = path.replace('//', '/');
253
+ }
254
+ return {
255
+ text: ni.name,
256
+ icon: ni.iconClassName || "bi bi-box-seam",
257
+ path,
258
+ }
259
+ })
260
+ }
261
+ />
262
+ </>
263
+ )
264
+ }
@@ -0,0 +1,105 @@
1
+ import { DataFilter, ICursorIterable, observable, SortBy, Table } from "@peers-app/peers-sdk";
2
+ import * as _ from 'lodash';
3
+ import React, { useEffect, useState } from 'react';
4
+ import { isDesktop } from '../globals';
5
+ import { useObservable } from "../hooks";
6
+ import { Input } from './input';
7
+ import { LazyList } from './lazy-list';
8
+ import { LoadingIndicator } from './loading-indicator';
9
+
10
+ interface IProps<T extends { [key: string]: any; }> {
11
+ table: Table<T>;
12
+ newRecord: (text: string) => Promise<T>;
13
+ getFilter?: (text: string) => DataFilter<T>;
14
+ sortBy?: SortBy<T>;
15
+ renderItem: (record: T) => JSX.Element;
16
+ placeholderName?: string;
17
+ }
18
+
19
+ export function ListScreen<T extends { [key: string]: any; }>(props: IProps<T>) {
20
+ const {
21
+ table,
22
+ newRecord,
23
+ sortBy,
24
+ } = props;
25
+
26
+ const [searchTextObs] = useState(() => observable(''));
27
+ const [searchText] = useObservable(searchTextObs);
28
+
29
+ const [cursorObs] = useState(() => observable<ICursorIterable<T>>());
30
+
31
+ async function newCursor() {
32
+ const filter = props.getFilter ? props.getFilter(searchText) : null;
33
+ const cursor = await table.cursor(filter || {}, { sortBy, ...(filter ? {} : { textSearch: searchText }) });
34
+ cursorObs(cursor);
35
+ return cursor;
36
+ }
37
+
38
+ useEffect(() => {
39
+ newCursor();
40
+ }, [searchText]);
41
+
42
+ const idFieldName = table.metaData.primaryKeyName;
43
+
44
+ async function loadMore(existing: T[]): Promise<T[]> {
45
+ let moreMatches: T[] = [];
46
+ let cursor = cursorObs() || await newCursor();
47
+ for await (const nextRecord of cursor) {
48
+ if (existing.find(e => e[idFieldName] === nextRecord[idFieldName])) continue;
49
+ moreMatches.push(nextRecord);
50
+ if (searchText.length && moreMatches.length > 5) break;
51
+ if (moreMatches.length >= 10) break;
52
+ }
53
+ if (moreMatches.length === 0) {
54
+ cursorObs(undefined);
55
+ }
56
+ // if we're using default textSearch, list items with the most words matched in the name first
57
+ if (!props.getFilter && moreMatches && searchText && table.metaData.fields.find(f => f.name === 'name')) {
58
+ const words = searchText.toLowerCase().split(' ');
59
+ moreMatches = _.sortBy(moreMatches, r => words.filter(w => r.name.toLowerCase().includes(w)).length).reverse();
60
+ }
61
+ return moreMatches;
62
+ }
63
+
64
+
65
+ async function searchSubmit(evt: React.KeyboardEvent<HTMLInputElement>) {
66
+ if (evt.key !== "Enter") return;
67
+ const name = searchText.trim();
68
+ if (!name) return;
69
+ searchTextObs('');
70
+ await newRecord(name);
71
+ }
72
+
73
+ return (
74
+ <div className='container-fluid'>
75
+
76
+ <div className="input-group mt-3 mb-3">
77
+ <Input value={searchTextObs} className="form-control" placeholder={`Search or create ${props.placeholderName || table.metaData.name}`}
78
+ autoFocus={isDesktop() ? true : false}
79
+ onKeyUp={evt => searchSubmit(evt)}
80
+ />
81
+ </div>
82
+
83
+ <div className="peers-list-container">
84
+ <LazyList
85
+ resetTrigger={searchText}
86
+ loadMore={loadMore}
87
+ scrollThreshold={0.6}
88
+ renderItems={(notes) => {
89
+ return notes.map(props.renderItem);
90
+ }}
91
+ loadingIndicator={
92
+ <div className="d-flex justify-content-center" style={{ height: 200 }}>
93
+ <LoadingIndicator />
94
+ </div>
95
+ }
96
+ endOfList={
97
+ <div className="d-flex justify-content-center" style={{ height: 200 }}>
98
+ {/* <span className="h3">End of List</span> */}
99
+ </div>
100
+ }
101
+ />
102
+ </div>
103
+ </div>
104
+ );
105
+ };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+
3
+ export const LoadingIndicator = () => {
4
+ return (
5
+ <span className="spinner-grow spinner-grow-sm text-secondary m-4" role="status">
6
+ <span className="visually-hidden">Loading...</span>
7
+ </span>
8
+ )
9
+ }
@@ -0,0 +1,76 @@
1
+ import React, { useState } from 'react';
2
+ import SplitPane from 'react-split-pane';
3
+ import { openThreads, threadViewOpen } from '../globals';
4
+ import { ThreadContainer, startNewThread } from './messages/thread-view';
5
+ import { Router } from './router';
6
+ import { useObservable } from '../hooks';
7
+
8
+ export const MainContentContainer = () => {
9
+
10
+ const splitPositionGlobalName = 'mainContentContainerSplitPos';
11
+ let [splitPos, setSplitPos] = useState(localStorage.getItem(splitPositionGlobalName) || '800');
12
+ useObservable(threadViewOpen);
13
+
14
+ if (!threadViewOpen()) {
15
+ return (
16
+ <>
17
+ <button
18
+ className="btn small m-0 p-0 thread-view-open-button"
19
+ onClick={() => {
20
+ const lastThread = openThreads()[0];
21
+ if (!lastThread) {
22
+ startNewThread();
23
+ } else {
24
+ threadViewOpen(true);
25
+ }
26
+ }}
27
+ style={{
28
+ position: 'fixed',
29
+ // top: '3px',
30
+ // right: '16px',
31
+ top: '-5px',
32
+ right: '6px',
33
+ zIndex: 1000,
34
+ // backgroundColor: 'white',
35
+ backgroundColor: 'transparent'
36
+ }}
37
+ >
38
+ +
39
+ {/* <i className="bi bi-box-arrow-down-left"></i> */}
40
+ </button>
41
+
42
+ <Router />
43
+ </>
44
+ )
45
+ }
46
+
47
+ return (
48
+ // @ts-ignore
49
+ <SplitPane
50
+ split="vertical"
51
+ defaultSize={parseInt(splitPos)}
52
+ onChange={(size) => {
53
+ localStorage.setItem(splitPositionGlobalName, String(size));
54
+ setSplitPos(String(size));
55
+ }}
56
+ style={{
57
+ position: 'unset',
58
+ height: `100vh`,
59
+ }}
60
+ >
61
+ <div>
62
+ <Router />
63
+ </div>
64
+ <div
65
+ className='thread-view'
66
+ style={{
67
+ height: `100vh`,
68
+ overflowY: 'scroll',
69
+ width: `calc(100vw - ${splitPos}px - 300px)`,
70
+ }}
71
+ >
72
+ <ThreadContainer />
73
+ </div>
74
+ </SplitPane>
75
+ )
76
+ }
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import {
3
+ AutoLinkPlugin,
4
+ createLinkMatcherWithRegExp,
5
+ } from '@lexical/react/LexicalAutoLinkPlugin';
6
+
7
+
8
+ const URL_REGEX =
9
+ /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)(?<![-.+():%])/;
10
+
11
+ const EMAIL_REGEX =
12
+ /(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;
13
+
14
+ const MATCHERS = [
15
+ createLinkMatcherWithRegExp(URL_REGEX, (text) => {
16
+ return text.startsWith('http') ? text : `https://${text}`;
17
+ }),
18
+ createLinkMatcherWithRegExp(EMAIL_REGEX, (text) => {
19
+ return `mailto:${text}`;
20
+ }),
21
+ ];
22
+
23
+ export function LexicalAutoLinkPlugin(): JSX.Element {
24
+ return <AutoLinkPlugin matchers={MATCHERS} />;
25
+ }
26
+
27
+
28
+
29
+ import { LinkPlugin as LexicalLinkPlugin } from '@lexical/react/LexicalLinkPlugin';
30
+
31
+ export default function LinkPlugin(): JSX.Element {
32
+ const validateUrl = (url: string) => {
33
+ return url.startsWith('http://') || url.startsWith('https://') || url.startsWith('mailto:');
34
+ };
35
+ return <LexicalLinkPlugin validateUrl={validateUrl} />;
36
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { IMarkdownEditorProps, MarkdownEditor } from "./editor";
3
+
4
+ export const MarkdownEditorInline = (props: IMarkdownEditorProps) => {
5
+ return (
6
+ <div className="border rounded border-dark-subtle">
7
+ <MarkdownEditor {...props} />
8
+ </div>
9
+ )
10
+ }
@@ -0,0 +1,152 @@
1
+ import { CodeNode } from '@lexical/code';
2
+ import { AutoLinkNode, LinkNode } from '@lexical/link';
3
+ import { ListItemNode, ListNode } from '@lexical/list';
4
+ import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';
5
+ import { CheckListPlugin, } from '@lexical/react/LexicalCheckListPlugin';
6
+ import { LexicalComposer } from '@lexical/react/LexicalComposer';
7
+ import { ContentEditable } from '@lexical/react/LexicalContentEditable';
8
+ import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
9
+ import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
10
+ import { ListPlugin } from '@lexical/react/LexicalListPlugin';
11
+ import { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin';
12
+ import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
13
+ import { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin';
14
+ import { HeadingNode, QuoteNode } from '@lexical/rich-text';
15
+ import { observable, Observable } from "@peers-app/peers-sdk";
16
+ import React, { useEffect, useState } from 'react';
17
+ import { LexicalAutoLinkPlugin } from './autolink-plugin';
18
+ import { customMarkdownTransformers, MarkdownPlugin } from './markdown-plugin';
19
+ import { MentionNode } from './mention-node';
20
+ import { MentionsPlugin } from './mentions-plugin';
21
+ import theme from './theme';
22
+ import { IToolbarControl, ToolbarPlugin } from './toolbar';
23
+ import { COMMAND_PRIORITY_LOW, KEY_DOWN_COMMAND } from 'lexical';
24
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
25
+ import { IMentionConfig, mentionConfigs } from '../../mention-configs';
26
+
27
+
28
+ const editorConfig = {
29
+ namespace: 'PeersEditor',
30
+ nodes: [
31
+ HeadingNode,
32
+ QuoteNode,
33
+ CodeNode,
34
+ ListNode,
35
+ ListItemNode,
36
+ MentionNode,
37
+ AutoLinkNode as any,
38
+ LinkNode,
39
+ ],
40
+ // Handling of errors during update
41
+ onError(error: Error) {
42
+ throw error;
43
+ },
44
+ // The editor theme
45
+ theme,
46
+ };
47
+
48
+ export interface IEditorEffects {
49
+ onKeyDown?: (e: React.KeyboardEvent) => (boolean | void);
50
+ focus?: () => void;
51
+ }
52
+
53
+ export interface IMarkdownEditorProps {
54
+ value: Observable<string>;
55
+ effects?: IEditorEffects;
56
+ topRightControls?: IToolbarControl[];
57
+ autoFocus?: boolean;
58
+ hideToolbar?: boolean;
59
+ maxHeight?: string | number;
60
+ mentionConfigs?: IMentionConfig[];
61
+ }
62
+
63
+ export function MarkdownEditor(props: IMarkdownEditorProps) {
64
+ const { effects } = props;
65
+ const editorRef = React.useRef<HTMLDivElement>(null);
66
+
67
+ const [mentionsOpen] = useState(() => {
68
+ const obs = observable(false);
69
+ return obs;
70
+ });
71
+
72
+ if (effects) {
73
+ effects.focus = () => {
74
+ if (editorRef.current?.children[0]) {
75
+ const div = editorRef.current.children[0] as HTMLDivElement;
76
+ setTimeout(() => {
77
+ div.focus();
78
+ // Set the selection to the end of the div content
79
+ const range = document.createRange();
80
+ range.selectNodeContents(div);
81
+ range.collapse(false);
82
+ const selection = window.getSelection();
83
+ if (selection) {
84
+ selection.removeAllRanges();
85
+ selection.addRange(range);
86
+ }
87
+ }, 10);
88
+ }
89
+ }
90
+ }
91
+
92
+ const _mentionConfigs = props.mentionConfigs ?? mentionConfigs;
93
+
94
+ return (
95
+ <LexicalComposer initialConfig={{ ...editorConfig }}>
96
+ <div className="editor-container">
97
+ {props.hideToolbar ? null : <ToolbarPlugin topRightControls={props.topRightControls} />}
98
+
99
+ <div
100
+ className="editor-inner"
101
+ ref={editorRef}
102
+ style={{ maxHeight: props.maxHeight, overflowY: 'auto' }}
103
+ >
104
+ <RichTextPlugin
105
+ contentEditable={
106
+ <ContentEditable
107
+ className="editor-input p-2"
108
+ />
109
+ }
110
+ placeholder={null}
111
+ ErrorBoundary={LexicalErrorBoundary}
112
+ />
113
+ <HistoryPlugin />
114
+ {props.autoFocus && <AutoFocusPlugin defaultSelection='rootEnd' />}
115
+ <ListPlugin />
116
+
117
+ {_mentionConfigs.length > 0 && (
118
+ <MentionsPlugin
119
+ mentionConfigs={_mentionConfigs}
120
+ mentionsOpen={mentionsOpen}
121
+ />
122
+ )}
123
+
124
+ <LexicalAutoLinkPlugin />
125
+ <MarkdownPlugin markdownObs={props.value} />
126
+ <MarkdownShortcutPlugin transformers={customMarkdownTransformers} />
127
+ <CheckListPlugin />
128
+ <TabIndentationPlugin />
129
+ <OnKeyDownPlugin effects={props.effects} mentionsOpen={mentionsOpen} />
130
+ </div>
131
+ </div>
132
+ </LexicalComposer>
133
+ );
134
+ }
135
+
136
+ const OnKeyDownPlugin = (props: { effects?: IEditorEffects, mentionsOpen: Observable<boolean> }) => {
137
+ const [editor] = useLexicalComposerContext();
138
+ useEffect(() => {
139
+ const removeListener = editor.registerCommand(KEY_DOWN_COMMAND, (event: KeyboardEvent) => {
140
+ if (props.mentionsOpen()) {
141
+ return false;
142
+ }
143
+ if (props.effects?.onKeyDown) {
144
+ const result = props.effects.onKeyDown(event as any);
145
+ return !!result;
146
+ }
147
+ return false;
148
+ }, COMMAND_PRIORITY_LOW);
149
+ return removeListener;
150
+ }, [editor]);
151
+ return null;
152
+ }