@dxos/shell 0.3.11-main.008b7c6

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 (530) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +21 -0
  3. package/dist/lib/browser/chunk-ZSTKOCBT.mjs +10 -0
  4. package/dist/lib/browser/chunk-ZSTKOCBT.mjs.map +7 -0
  5. package/dist/lib/browser/meta.json +1 -0
  6. package/dist/lib/browser/react.mjs +3617 -0
  7. package/dist/lib/browser/react.mjs.map +7 -0
  8. package/dist/lib/browser/testing/index.mjs +179 -0
  9. package/dist/lib/browser/testing/index.mjs.map +7 -0
  10. package/dist/types/src/components/AuthCode.d.ts +8 -0
  11. package/dist/types/src/components/AuthCode.d.ts.map +1 -0
  12. package/dist/types/src/components/AuthCode.js +26 -0
  13. package/dist/types/src/components/AuthCode.js.map +1 -0
  14. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts +9 -0
  15. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -0
  16. package/dist/types/src/components/Clipboard/ClipboardProvider.js +46 -0
  17. package/dist/types/src/components/Clipboard/ClipboardProvider.js.map +1 -0
  18. package/dist/types/src/components/Clipboard/CopyButton.d.ts +9 -0
  19. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -0
  20. package/dist/types/src/components/Clipboard/CopyButton.js +65 -0
  21. package/dist/types/src/components/Clipboard/CopyButton.js.map +1 -0
  22. package/dist/types/src/components/Clipboard/index.d.ts +3 -0
  23. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -0
  24. package/dist/types/src/components/Clipboard/index.js +22 -0
  25. package/dist/types/src/components/Clipboard/index.js.map +1 -0
  26. package/dist/types/src/components/CompoundButton/CompoundButton.d.ts +17 -0
  27. package/dist/types/src/components/CompoundButton/CompoundButton.d.ts.map +1 -0
  28. package/dist/types/src/components/CompoundButton/CompoundButton.js +29 -0
  29. package/dist/types/src/components/CompoundButton/CompoundButton.js.map +1 -0
  30. package/dist/types/src/components/CompoundButton/CompoundButton.stories.d.ts +35 -0
  31. package/dist/types/src/components/CompoundButton/CompoundButton.stories.d.ts.map +1 -0
  32. package/dist/types/src/components/CompoundButton/CompoundButton.stories.js +45 -0
  33. package/dist/types/src/components/CompoundButton/CompoundButton.stories.js.map +1 -0
  34. package/dist/types/src/components/CompoundButton/index.d.ts +2 -0
  35. package/dist/types/src/components/CompoundButton/index.d.ts.map +1 -0
  36. package/dist/types/src/components/CompoundButton/index.js +21 -0
  37. package/dist/types/src/components/CompoundButton/index.js.map +1 -0
  38. package/dist/types/src/components/IdentityList/DeviceList.d.ts +7 -0
  39. package/dist/types/src/components/IdentityList/DeviceList.d.ts.map +1 -0
  40. package/dist/types/src/components/IdentityList/DeviceList.js +29 -0
  41. package/dist/types/src/components/IdentityList/DeviceList.js.map +1 -0
  42. package/dist/types/src/components/IdentityList/IdentityListItem.d.ts +11 -0
  43. package/dist/types/src/components/IdentityList/IdentityListItem.d.ts.map +1 -0
  44. package/dist/types/src/components/IdentityList/IdentityListItem.js +47 -0
  45. package/dist/types/src/components/IdentityList/IdentityListItem.js.map +1 -0
  46. package/dist/types/src/components/IdentityList/SpaceMemberList.d.ts +13 -0
  47. package/dist/types/src/components/IdentityList/SpaceMemberList.d.ts.map +1 -0
  48. package/dist/types/src/components/IdentityList/SpaceMemberList.js +54 -0
  49. package/dist/types/src/components/IdentityList/SpaceMemberList.js.map +1 -0
  50. package/dist/types/src/components/IdentityList/SpaceMemberList.stories.d.ts +17 -0
  51. package/dist/types/src/components/IdentityList/SpaceMemberList.stories.d.ts.map +1 -0
  52. package/dist/types/src/components/IdentityList/SpaceMemberList.stories.js +26 -0
  53. package/dist/types/src/components/IdentityList/SpaceMemberList.stories.js.map +1 -0
  54. package/dist/types/src/components/IdentityList/index.d.ts +4 -0
  55. package/dist/types/src/components/IdentityList/index.d.ts.map +1 -0
  56. package/dist/types/src/components/IdentityList/index.js +23 -0
  57. package/dist/types/src/components/IdentityList/index.js.map +1 -0
  58. package/dist/types/src/components/InvitationList/InvitationList.d.ts +11 -0
  59. package/dist/types/src/components/InvitationList/InvitationList.d.ts.map +1 -0
  60. package/dist/types/src/components/InvitationList/InvitationList.js +22 -0
  61. package/dist/types/src/components/InvitationList/InvitationList.js.map +1 -0
  62. package/dist/types/src/components/InvitationList/InvitationList.stories.d.ts +17 -0
  63. package/dist/types/src/components/InvitationList/InvitationList.stories.d.ts.map +1 -0
  64. package/dist/types/src/components/InvitationList/InvitationList.stories.js +39 -0
  65. package/dist/types/src/components/InvitationList/InvitationList.stories.js.map +1 -0
  66. package/dist/types/src/components/InvitationList/InvitationListContainer.d.ts +7 -0
  67. package/dist/types/src/components/InvitationList/InvitationListContainer.d.ts.map +1 -0
  68. package/dist/types/src/components/InvitationList/InvitationListContainer.js +42 -0
  69. package/dist/types/src/components/InvitationList/InvitationListContainer.js.map +1 -0
  70. package/dist/types/src/components/InvitationList/InvitationListItem.d.ts +12 -0
  71. package/dist/types/src/components/InvitationList/InvitationListItem.d.ts.map +1 -0
  72. package/dist/types/src/components/InvitationList/InvitationListItem.js +103 -0
  73. package/dist/types/src/components/InvitationList/InvitationListItem.js.map +1 -0
  74. package/dist/types/src/components/InvitationList/InvitationListProps.d.ts +9 -0
  75. package/dist/types/src/components/InvitationList/InvitationListProps.d.ts.map +1 -0
  76. package/dist/types/src/components/InvitationList/InvitationListProps.js +3 -0
  77. package/dist/types/src/components/InvitationList/InvitationListProps.js.map +1 -0
  78. package/dist/types/src/components/InvitationList/index.d.ts +4 -0
  79. package/dist/types/src/components/InvitationList/index.d.ts.map +1 -0
  80. package/dist/types/src/components/InvitationList/index.js +23 -0
  81. package/dist/types/src/components/InvitationList/index.js.map +1 -0
  82. package/dist/types/src/components/Panel/Action.d.ts +20 -0
  83. package/dist/types/src/components/Panel/Action.d.ts.map +1 -0
  84. package/dist/types/src/components/Panel/Action.js +93 -0
  85. package/dist/types/src/components/Panel/Action.js.map +1 -0
  86. package/dist/types/src/components/Panel/Actions.d.ts +11 -0
  87. package/dist/types/src/components/Panel/Actions.d.ts.map +1 -0
  88. package/dist/types/src/components/Panel/Actions.js +36 -0
  89. package/dist/types/src/components/Panel/Actions.js.map +1 -0
  90. package/dist/types/src/components/Panel/CloseButton.d.ts +5 -0
  91. package/dist/types/src/components/Panel/CloseButton.d.ts.map +1 -0
  92. package/dist/types/src/components/Panel/CloseButton.js +21 -0
  93. package/dist/types/src/components/Panel/CloseButton.js.map +1 -0
  94. package/dist/types/src/components/Panel/Emoji.d.ts +7 -0
  95. package/dist/types/src/components/Panel/Emoji.d.ts.map +1 -0
  96. package/dist/types/src/components/Panel/Emoji.js +24 -0
  97. package/dist/types/src/components/Panel/Emoji.js.map +1 -0
  98. package/dist/types/src/components/Panel/Heading.d.ts +16 -0
  99. package/dist/types/src/components/Panel/Heading.d.ts.map +1 -0
  100. package/dist/types/src/components/Panel/Heading.js +39 -0
  101. package/dist/types/src/components/Panel/Heading.js.map +1 -0
  102. package/dist/types/src/components/Panel/Input.d.ts +11 -0
  103. package/dist/types/src/components/Panel/Input.d.ts.map +1 -0
  104. package/dist/types/src/components/Panel/Input.js +19 -0
  105. package/dist/types/src/components/Panel/Input.js.map +1 -0
  106. package/dist/types/src/components/Panel/Label.d.ts +4 -0
  107. package/dist/types/src/components/Panel/Label.d.ts.map +1 -0
  108. package/dist/types/src/components/Panel/Label.js +17 -0
  109. package/dist/types/src/components/Panel/Label.js.map +1 -0
  110. package/dist/types/src/components/Panel/Panel.stories.d.ts +13 -0
  111. package/dist/types/src/components/Panel/Panel.stories.d.ts.map +1 -0
  112. package/dist/types/src/components/Panel/Panel.stories.js +44 -0
  113. package/dist/types/src/components/Panel/Panel.stories.js.map +1 -0
  114. package/dist/types/src/components/Panel/StepHeading.d.ts +5 -0
  115. package/dist/types/src/components/Panel/StepHeading.d.ts.map +1 -0
  116. package/dist/types/src/components/Panel/StepHeading.js +35 -0
  117. package/dist/types/src/components/Panel/StepHeading.js.map +1 -0
  118. package/dist/types/src/components/Panel/index.d.ts +9 -0
  119. package/dist/types/src/components/Panel/index.d.ts.map +1 -0
  120. package/dist/types/src/components/Panel/index.js +28 -0
  121. package/dist/types/src/components/Panel/index.js.map +1 -0
  122. package/dist/types/src/components/SpaceListItem.d.ts +7 -0
  123. package/dist/types/src/components/SpaceListItem.d.ts.map +1 -0
  124. package/dist/types/src/components/SpaceListItem.js +46 -0
  125. package/dist/types/src/components/SpaceListItem.js.map +1 -0
  126. package/dist/types/src/components/StorybookDialog.d.ts +6 -0
  127. package/dist/types/src/components/StorybookDialog.d.ts.map +1 -0
  128. package/dist/types/src/components/StorybookDialog.js +23 -0
  129. package/dist/types/src/components/StorybookDialog.js.map +1 -0
  130. package/dist/types/src/components/Viewport/Viewport.d.ts +39 -0
  131. package/dist/types/src/components/Viewport/Viewport.d.ts.map +1 -0
  132. package/dist/types/src/components/Viewport/Viewport.js +73 -0
  133. package/dist/types/src/components/Viewport/Viewport.js.map +1 -0
  134. package/dist/types/src/components/Viewport/Viewport.stories.d.ts +17 -0
  135. package/dist/types/src/components/Viewport/Viewport.stories.d.ts.map +1 -0
  136. package/dist/types/src/components/Viewport/Viewport.stories.js +51 -0
  137. package/dist/types/src/components/Viewport/Viewport.stories.js.map +1 -0
  138. package/dist/types/src/components/Viewport/index.d.ts +2 -0
  139. package/dist/types/src/components/Viewport/index.d.ts.map +1 -0
  140. package/dist/types/src/components/Viewport/index.js +21 -0
  141. package/dist/types/src/components/Viewport/index.js.map +1 -0
  142. package/dist/types/src/components/index.d.ts +9 -0
  143. package/dist/types/src/components/index.d.ts.map +1 -0
  144. package/dist/types/src/components/index.js +28 -0
  145. package/dist/types/src/components/index.js.map +1 -0
  146. package/dist/types/src/composites/IdentityDialog/IdentityDialog.d.ts +7 -0
  147. package/dist/types/src/composites/IdentityDialog/IdentityDialog.d.ts.map +1 -0
  148. package/dist/types/src/composites/IdentityDialog/IdentityDialog.js +26 -0
  149. package/dist/types/src/composites/IdentityDialog/IdentityDialog.js.map +1 -0
  150. package/dist/types/src/composites/IdentityDialog/index.d.ts +2 -0
  151. package/dist/types/src/composites/IdentityDialog/index.d.ts.map +1 -0
  152. package/dist/types/src/composites/IdentityDialog/index.js +21 -0
  153. package/dist/types/src/composites/IdentityDialog/index.js.map +1 -0
  154. package/dist/types/src/composites/JoinDialog/JoinDialog.d.ts +6 -0
  155. package/dist/types/src/composites/JoinDialog/JoinDialog.d.ts.map +1 -0
  156. package/dist/types/src/composites/JoinDialog/JoinDialog.js +27 -0
  157. package/dist/types/src/composites/JoinDialog/JoinDialog.js.map +1 -0
  158. package/dist/types/src/composites/JoinDialog/index.d.ts +2 -0
  159. package/dist/types/src/composites/JoinDialog/index.d.ts.map +1 -0
  160. package/dist/types/src/composites/JoinDialog/index.js +21 -0
  161. package/dist/types/src/composites/JoinDialog/index.js.map +1 -0
  162. package/dist/types/src/composites/Shell/Shell.d.ts +6 -0
  163. package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -0
  164. package/dist/types/src/composites/Shell/Shell.js +90 -0
  165. package/dist/types/src/composites/Shell/Shell.js.map +1 -0
  166. package/dist/types/src/composites/Shell/ShellContext.d.ts +30 -0
  167. package/dist/types/src/composites/Shell/ShellContext.d.ts.map +1 -0
  168. package/dist/types/src/composites/Shell/ShellContext.js +129 -0
  169. package/dist/types/src/composites/Shell/ShellContext.js.map +1 -0
  170. package/dist/types/src/composites/Shell/index.d.ts +4 -0
  171. package/dist/types/src/composites/Shell/index.d.ts.map +1 -0
  172. package/dist/types/src/composites/Shell/index.js +23 -0
  173. package/dist/types/src/composites/Shell/index.js.map +1 -0
  174. package/dist/types/src/composites/Shell/memory-shell-runtime.d.ts +16 -0
  175. package/dist/types/src/composites/Shell/memory-shell-runtime.d.ts.map +1 -0
  176. package/dist/types/src/composites/Shell/memory-shell-runtime.js +38 -0
  177. package/dist/types/src/composites/Shell/memory-shell-runtime.js.map +1 -0
  178. package/dist/types/src/composites/Shell/run-shell.d.ts +3 -0
  179. package/dist/types/src/composites/Shell/run-shell.d.ts.map +1 -0
  180. package/dist/types/src/composites/Shell/run-shell.js +54 -0
  181. package/dist/types/src/composites/Shell/run-shell.js.map +1 -0
  182. package/dist/types/src/composites/SpaceDialog/SpaceDialog.d.ts +6 -0
  183. package/dist/types/src/composites/SpaceDialog/SpaceDialog.d.ts.map +1 -0
  184. package/dist/types/src/composites/SpaceDialog/SpaceDialog.js +26 -0
  185. package/dist/types/src/composites/SpaceDialog/SpaceDialog.js.map +1 -0
  186. package/dist/types/src/composites/SpaceDialog/index.d.ts +2 -0
  187. package/dist/types/src/composites/SpaceDialog/index.d.ts.map +1 -0
  188. package/dist/types/src/composites/SpaceDialog/index.js +21 -0
  189. package/dist/types/src/composites/SpaceDialog/index.js.map +1 -0
  190. package/dist/types/src/composites/index.d.ts +5 -0
  191. package/dist/types/src/composites/index.d.ts.map +1 -0
  192. package/dist/types/src/composites/index.js +24 -0
  193. package/dist/types/src/composites/index.js.map +1 -0
  194. package/dist/types/src/index.d.ts +3 -0
  195. package/dist/types/src/index.d.ts.map +1 -0
  196. package/dist/types/src/index.js +10 -0
  197. package/dist/types/src/index.js.map +1 -0
  198. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts +4 -0
  199. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -0
  200. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +124 -0
  201. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -0
  202. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts +22 -0
  203. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts.map +1 -0
  204. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js +86 -0
  205. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js.map +1 -0
  206. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts +27 -0
  207. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts.map +1 -0
  208. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.js +6 -0
  209. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.js.map +1 -0
  210. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts +46 -0
  211. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts.map +1 -0
  212. package/dist/types/src/panels/IdentityPanel/identityMachine.js +79 -0
  213. package/dist/types/src/panels/IdentityPanel/identityMachine.js.map +1 -0
  214. package/dist/types/src/panels/IdentityPanel/index.d.ts +3 -0
  215. package/dist/types/src/panels/IdentityPanel/index.d.ts.map +1 -0
  216. package/dist/types/src/panels/IdentityPanel/index.js +22 -0
  217. package/dist/types/src/panels/IdentityPanel/index.js.map +1 -0
  218. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts +9 -0
  219. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts.map +1 -0
  220. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +85 -0
  221. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -0
  222. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts +15 -0
  223. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -0
  224. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +62 -0
  225. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -0
  226. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts +3 -0
  227. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts.map +1 -0
  228. package/dist/types/src/panels/IdentityPanel/steps/index.js +22 -0
  229. package/dist/types/src/panels/IdentityPanel/steps/index.js.map +1 -0
  230. package/dist/types/src/panels/JoinPanel/JoinHeading.d.ts +10 -0
  231. package/dist/types/src/panels/JoinPanel/JoinHeading.d.ts.map +1 -0
  232. package/dist/types/src/panels/JoinPanel/JoinHeading.js +45 -0
  233. package/dist/types/src/panels/JoinPanel/JoinHeading.js.map +1 -0
  234. package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts +4 -0
  235. package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts.map +1 -0
  236. package/dist/types/src/panels/JoinPanel/JoinPanel.js +293 -0
  237. package/dist/types/src/panels/JoinPanel/JoinPanel.js.map +1 -0
  238. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts +92 -0
  239. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts.map +1 -0
  240. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.js +74 -0
  241. package/dist/types/src/panels/JoinPanel/JoinPanel.stories.js.map +1 -0
  242. package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts +91 -0
  243. package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts.map +1 -0
  244. package/dist/types/src/panels/JoinPanel/JoinPanelProps.js +6 -0
  245. package/dist/types/src/panels/JoinPanel/JoinPanelProps.js.map +1 -0
  246. package/dist/types/src/panels/JoinPanel/index.d.ts +3 -0
  247. package/dist/types/src/panels/JoinPanel/index.d.ts.map +1 -0
  248. package/dist/types/src/panels/JoinPanel/index.js +22 -0
  249. package/dist/types/src/panels/JoinPanel/index.js.map +1 -0
  250. package/dist/types/src/panels/JoinPanel/joinMachine.d.ts +87 -0
  251. package/dist/types/src/panels/JoinPanel/joinMachine.d.ts.map +1 -0
  252. package/dist/types/src/panels/JoinPanel/joinMachine.js +402 -0
  253. package/dist/types/src/panels/JoinPanel/joinMachine.js.map +1 -0
  254. package/dist/types/src/panels/JoinPanel/steps/AdditionMethodChooser.d.ts +4 -0
  255. package/dist/types/src/panels/JoinPanel/steps/AdditionMethodChooser.d.ts.map +1 -0
  256. package/dist/types/src/panels/JoinPanel/steps/AdditionMethodChooser.js +34 -0
  257. package/dist/types/src/panels/JoinPanel/steps/AdditionMethodChooser.js.map +1 -0
  258. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.d.ts +8 -0
  259. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.d.ts.map +1 -0
  260. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js +56 -0
  261. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js.map +1 -0
  262. package/dist/types/src/panels/JoinPanel/steps/IdentityInput.d.ts +12 -0
  263. package/dist/types/src/panels/JoinPanel/steps/IdentityInput.d.ts.map +1 -0
  264. package/dist/types/src/panels/JoinPanel/steps/IdentityInput.js +67 -0
  265. package/dist/types/src/panels/JoinPanel/steps/IdentityInput.js.map +1 -0
  266. package/dist/types/src/panels/JoinPanel/steps/InvitationAccepted.d.ts +9 -0
  267. package/dist/types/src/panels/JoinPanel/steps/InvitationAccepted.d.ts.map +1 -0
  268. package/dist/types/src/panels/JoinPanel/steps/InvitationAccepted.js +44 -0
  269. package/dist/types/src/panels/JoinPanel/steps/InvitationAccepted.js.map +1 -0
  270. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.d.ts +11 -0
  271. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.d.ts.map +1 -0
  272. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js +72 -0
  273. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js.map +1 -0
  274. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.d.ts +8 -0
  275. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.d.ts.map +1 -0
  276. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.js +68 -0
  277. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.js.map +1 -0
  278. package/dist/types/src/panels/JoinPanel/steps/InvitationRescuer.d.ts +11 -0
  279. package/dist/types/src/panels/JoinPanel/steps/InvitationRescuer.d.ts.map +1 -0
  280. package/dist/types/src/panels/JoinPanel/steps/InvitationRescuer.js +49 -0
  281. package/dist/types/src/panels/JoinPanel/steps/InvitationRescuer.js.map +1 -0
  282. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.d.ts +12 -0
  283. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.d.ts.map +1 -0
  284. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.js +63 -0
  285. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.js.map +1 -0
  286. package/dist/types/src/panels/JoinPanel/steps/index.d.ts +9 -0
  287. package/dist/types/src/panels/JoinPanel/steps/index.d.ts.map +1 -0
  288. package/dist/types/src/panels/JoinPanel/steps/index.js +28 -0
  289. package/dist/types/src/panels/JoinPanel/steps/index.js.map +1 -0
  290. package/dist/types/src/panels/Panels.stories.d.ts +22 -0
  291. package/dist/types/src/panels/Panels.stories.d.ts.map +1 -0
  292. package/dist/types/src/panels/Panels.stories.js +69 -0
  293. package/dist/types/src/panels/Panels.stories.js.map +1 -0
  294. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts +4 -0
  295. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts.map +1 -0
  296. package/dist/types/src/panels/SpacePanel/SpacePanel.js +93 -0
  297. package/dist/types/src/panels/SpacePanel/SpacePanel.js.map +1 -0
  298. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts +30 -0
  299. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts.map +1 -0
  300. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.js +183 -0
  301. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.js.map +1 -0
  302. package/dist/types/src/panels/SpacePanel/SpacePanelProps.d.ts +30 -0
  303. package/dist/types/src/panels/SpacePanel/SpacePanelProps.d.ts.map +1 -0
  304. package/dist/types/src/panels/SpacePanel/SpacePanelProps.js +6 -0
  305. package/dist/types/src/panels/SpacePanel/SpacePanelProps.js.map +1 -0
  306. package/dist/types/src/panels/SpacePanel/index.d.ts +3 -0
  307. package/dist/types/src/panels/SpacePanel/index.d.ts.map +1 -0
  308. package/dist/types/src/panels/SpacePanel/index.js +22 -0
  309. package/dist/types/src/panels/SpacePanel/index.js.map +1 -0
  310. package/dist/types/src/panels/SpacePanel/spaceMachine.d.ts +35 -0
  311. package/dist/types/src/panels/SpacePanel/spaceMachine.d.ts.map +1 -0
  312. package/dist/types/src/panels/SpacePanel/spaceMachine.js +46 -0
  313. package/dist/types/src/panels/SpacePanel/spaceMachine.js.map +1 -0
  314. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts +15 -0
  315. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts.map +1 -0
  316. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js +120 -0
  317. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js.map +1 -0
  318. package/dist/types/src/panels/SpacePanel/steps/index.d.ts +2 -0
  319. package/dist/types/src/panels/SpacePanel/steps/index.d.ts.map +1 -0
  320. package/dist/types/src/panels/SpacePanel/steps/index.js +21 -0
  321. package/dist/types/src/panels/SpacePanel/steps/index.js.map +1 -0
  322. package/dist/types/src/panels/index.d.ts +4 -0
  323. package/dist/types/src/panels/index.d.ts.map +1 -0
  324. package/dist/types/src/panels/index.js +23 -0
  325. package/dist/types/src/panels/index.js.map +1 -0
  326. package/dist/types/src/playwright/invitations-manager.d.ts +26 -0
  327. package/dist/types/src/playwright/invitations-manager.d.ts.map +1 -0
  328. package/dist/types/src/playwright/invitations-manager.js +142 -0
  329. package/dist/types/src/playwright/invitations-manager.js.map +1 -0
  330. package/dist/types/src/playwright/invitations.spec.d.ts +2 -0
  331. package/dist/types/src/playwright/invitations.spec.d.ts.map +1 -0
  332. package/dist/types/src/playwright/invitations.spec.js +298 -0
  333. package/dist/types/src/playwright/invitations.spec.js.map +1 -0
  334. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  335. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  336. package/dist/types/src/playwright/playwright.config.js +8 -0
  337. package/dist/types/src/playwright/playwright.config.js.map +1 -0
  338. package/dist/types/src/react.d.ts +6 -0
  339. package/dist/types/src/react.d.ts.map +1 -0
  340. package/dist/types/src/react.js +25 -0
  341. package/dist/types/src/react.js.map +1 -0
  342. package/dist/types/src/steps/InvitationManager.d.ts +7 -0
  343. package/dist/types/src/steps/InvitationManager.d.ts.map +1 -0
  344. package/dist/types/src/steps/InvitationManager.js +80 -0
  345. package/dist/types/src/steps/InvitationManager.js.map +1 -0
  346. package/dist/types/src/steps/StepProps.d.ts +14 -0
  347. package/dist/types/src/steps/StepProps.d.ts.map +1 -0
  348. package/dist/types/src/steps/StepProps.js +6 -0
  349. package/dist/types/src/steps/StepProps.js.map +1 -0
  350. package/dist/types/src/steps/index.d.ts +3 -0
  351. package/dist/types/src/steps/index.d.ts.map +1 -0
  352. package/dist/types/src/steps/index.js +22 -0
  353. package/dist/types/src/steps/index.js.map +1 -0
  354. package/dist/types/src/stories/Invitations.e2e-stories.d.ts +22 -0
  355. package/dist/types/src/stories/Invitations.e2e-stories.d.ts.map +1 -0
  356. package/dist/types/src/stories/Invitations.e2e-stories.js +146 -0
  357. package/dist/types/src/stories/Invitations.e2e-stories.js.map +1 -0
  358. package/dist/types/src/styles/index.d.ts +3 -0
  359. package/dist/types/src/styles/index.d.ts.map +1 -0
  360. package/dist/types/src/styles/index.js +22 -0
  361. package/dist/types/src/styles/index.js.map +1 -0
  362. package/dist/types/src/styles/invitationStatusStyles.d.ts +20 -0
  363. package/dist/types/src/styles/invitationStatusStyles.d.ts.map +1 -0
  364. package/dist/types/src/styles/invitationStatusStyles.js +41 -0
  365. package/dist/types/src/styles/invitationStatusStyles.js.map +1 -0
  366. package/dist/types/src/styles/panelStyles.d.ts +2 -0
  367. package/dist/types/src/styles/panelStyles.d.ts.map +1 -0
  368. package/dist/types/src/styles/panelStyles.js +8 -0
  369. package/dist/types/src/styles/panelStyles.js.map +1 -0
  370. package/dist/types/src/testing/fixtures/identities.d.ts +3 -0
  371. package/dist/types/src/testing/fixtures/identities.d.ts.map +1 -0
  372. package/dist/types/src/testing/fixtures/identities.js +18 -0
  373. package/dist/types/src/testing/fixtures/identities.js.map +1 -0
  374. package/dist/types/src/testing/fixtures/index.d.ts +3 -0
  375. package/dist/types/src/testing/fixtures/index.d.ts.map +1 -0
  376. package/dist/types/src/testing/fixtures/index.js +22 -0
  377. package/dist/types/src/testing/fixtures/index.js.map +1 -0
  378. package/dist/types/src/testing/fixtures/invitations.d.ts +3 -0
  379. package/dist/types/src/testing/fixtures/invitations.d.ts.map +1 -0
  380. package/dist/types/src/testing/fixtures/invitations.js +25 -0
  381. package/dist/types/src/testing/fixtures/invitations.js.map +1 -0
  382. package/dist/types/src/testing/index.d.ts +4 -0
  383. package/dist/types/src/testing/index.d.ts.map +1 -0
  384. package/dist/types/src/testing/index.js +23 -0
  385. package/dist/types/src/testing/index.js.map +1 -0
  386. package/dist/types/src/testing/scoped-shell-manager.d.ts +17 -0
  387. package/dist/types/src/testing/scoped-shell-manager.d.ts.map +1 -0
  388. package/dist/types/src/testing/scoped-shell-manager.js +71 -0
  389. package/dist/types/src/testing/scoped-shell-manager.js.map +1 -0
  390. package/dist/types/src/testing/shell-manager.d.ts +24 -0
  391. package/dist/types/src/testing/shell-manager.d.ts.map +1 -0
  392. package/dist/types/src/testing/shell-manager.js +85 -0
  393. package/dist/types/src/testing/shell-manager.js.map +1 -0
  394. package/dist/types/src/translations/index.d.ts +5 -0
  395. package/dist/types/src/translations/index.d.ts.map +1 -0
  396. package/dist/types/src/translations/index.js +32 -0
  397. package/dist/types/src/translations/index.js.map +1 -0
  398. package/dist/types/src/translations/locales/en-US.d.ts +97 -0
  399. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -0
  400. package/dist/types/src/translations/locales/en-US.js +103 -0
  401. package/dist/types/src/translations/locales/en-US.js.map +1 -0
  402. package/dist/types/src/types/FailReason.d.ts +2 -0
  403. package/dist/types/src/types/FailReason.d.ts.map +1 -0
  404. package/dist/types/src/types/FailReason.js +6 -0
  405. package/dist/types/src/types/FailReason.js.map +1 -0
  406. package/dist/types/src/types/IInvitation.d.ts +7 -0
  407. package/dist/types/src/types/IInvitation.d.ts.map +1 -0
  408. package/dist/types/src/types/IInvitation.js +6 -0
  409. package/dist/types/src/types/IInvitation.js.map +1 -0
  410. package/dist/types/src/types/index.d.ts +3 -0
  411. package/dist/types/src/types/index.d.ts.map +1 -0
  412. package/dist/types/src/types/index.js +22 -0
  413. package/dist/types/src/types/index.js.map +1 -0
  414. package/dist/types/src/util/index.d.ts +3 -0
  415. package/dist/types/src/util/index.d.ts.map +1 -0
  416. package/dist/types/src/util/index.js +22 -0
  417. package/dist/types/src/util/index.js.map +1 -0
  418. package/dist/types/src/util/invitationStatusValue.d.ts +8 -0
  419. package/dist/types/src/util/invitationStatusValue.d.ts.map +1 -0
  420. package/dist/types/src/util/invitationStatusValue.js +24 -0
  421. package/dist/types/src/util/invitationStatusValue.js.map +1 -0
  422. package/dist/types/src/util/toEmoji.d.ts +2 -0
  423. package/dist/types/src/util/toEmoji.d.ts.map +1 -0
  424. package/dist/types/src/util/toEmoji.js +26 -0
  425. package/dist/types/src/util/toEmoji.js.map +1 -0
  426. package/package.json +79 -0
  427. package/src/components/AuthCode.tsx +36 -0
  428. package/src/components/Clipboard/ClipboardProvider.tsx +26 -0
  429. package/src/components/Clipboard/CopyButton.tsx +70 -0
  430. package/src/components/Clipboard/index.ts +6 -0
  431. package/src/components/CompoundButton/CompoundButton.stories.tsx +49 -0
  432. package/src/components/CompoundButton/CompoundButton.tsx +89 -0
  433. package/src/components/CompoundButton/index.ts +5 -0
  434. package/src/components/IdentityList/DeviceList.tsx +45 -0
  435. package/src/components/IdentityList/IdentityListItem.tsx +42 -0
  436. package/src/components/IdentityList/SpaceMemberList.stories.tsx +24 -0
  437. package/src/components/IdentityList/SpaceMemberList.tsx +65 -0
  438. package/src/components/IdentityList/index.ts +7 -0
  439. package/src/components/InvitationList/InvitationList.stories.tsx +44 -0
  440. package/src/components/InvitationList/InvitationList.tsx +31 -0
  441. package/src/components/InvitationList/InvitationListContainer.tsx +27 -0
  442. package/src/components/InvitationList/InvitationListItem.tsx +183 -0
  443. package/src/components/InvitationList/InvitationListProps.ts +9 -0
  444. package/src/components/InvitationList/index.ts +7 -0
  445. package/src/components/Panel/Action.tsx +142 -0
  446. package/src/components/Panel/Actions.tsx +31 -0
  447. package/src/components/Panel/CloseButton.tsx +24 -0
  448. package/src/components/Panel/Emoji.tsx +36 -0
  449. package/src/components/Panel/Heading.tsx +32 -0
  450. package/src/components/Panel/Input.tsx +27 -0
  451. package/src/components/Panel/Label.tsx +14 -0
  452. package/src/components/Panel/Panel.stories.tsx +52 -0
  453. package/src/components/Panel/StepHeading.tsx +17 -0
  454. package/src/components/Panel/index.ts +12 -0
  455. package/src/components/SpaceListItem.tsx +35 -0
  456. package/src/components/StorybookDialog.tsx +33 -0
  457. package/src/components/Viewport/Viewport.stories.tsx +66 -0
  458. package/src/components/Viewport/Viewport.tsx +120 -0
  459. package/src/components/Viewport/index.tsx +5 -0
  460. package/src/components/index.ts +12 -0
  461. package/src/composites/IdentityDialog/IdentityDialog.tsx +39 -0
  462. package/src/composites/IdentityDialog/index.ts +5 -0
  463. package/src/composites/JoinDialog/JoinDialog.tsx +40 -0
  464. package/src/composites/JoinDialog/index.ts +5 -0
  465. package/src/composites/Shell/Shell.tsx +98 -0
  466. package/src/composites/Shell/ShellContext.tsx +163 -0
  467. package/src/composites/Shell/index.ts +7 -0
  468. package/src/composites/Shell/memory-shell-runtime.ts +50 -0
  469. package/src/composites/Shell/run-shell.tsx +38 -0
  470. package/src/composites/SpaceDialog/SpaceDialog.tsx +37 -0
  471. package/src/composites/SpaceDialog/index.ts +5 -0
  472. package/src/composites/index.ts +8 -0
  473. package/src/index.ts +7 -0
  474. package/src/panels/IdentityPanel/IdentityPanel.stories.tsx +113 -0
  475. package/src/panels/IdentityPanel/IdentityPanel.tsx +158 -0
  476. package/src/panels/IdentityPanel/IdentityPanelProps.ts +36 -0
  477. package/src/panels/IdentityPanel/identityMachine.ts +131 -0
  478. package/src/panels/IdentityPanel/index.ts +6 -0
  479. package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +96 -0
  480. package/src/panels/IdentityPanel/steps/ProfileForm.tsx +79 -0
  481. package/src/panels/IdentityPanel/steps/index.ts +6 -0
  482. package/src/panels/JoinPanel/JoinHeading.tsx +49 -0
  483. package/src/panels/JoinPanel/JoinPanel.stories.tsx +91 -0
  484. package/src/panels/JoinPanel/JoinPanel.tsx +415 -0
  485. package/src/panels/JoinPanel/JoinPanelProps.ts +132 -0
  486. package/src/panels/JoinPanel/index.ts +6 -0
  487. package/src/panels/JoinPanel/joinMachine.ts +536 -0
  488. package/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx +65 -0
  489. package/src/panels/JoinPanel/steps/IdentityAdded.tsx +75 -0
  490. package/src/panels/JoinPanel/steps/IdentityInput.tsx +86 -0
  491. package/src/panels/JoinPanel/steps/InvitationAccepted.tsx +43 -0
  492. package/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx +99 -0
  493. package/src/panels/JoinPanel/steps/InvitationInput.tsx +102 -0
  494. package/src/panels/JoinPanel/steps/InvitationRescuer.tsx +102 -0
  495. package/src/panels/JoinPanel/steps/ResetIdentity.tsx +71 -0
  496. package/src/panels/JoinPanel/steps/index.ts +12 -0
  497. package/src/panels/Panels.stories.tsx +61 -0
  498. package/src/panels/SpacePanel/SpacePanel.stories.tsx +328 -0
  499. package/src/panels/SpacePanel/SpacePanel.tsx +122 -0
  500. package/src/panels/SpacePanel/SpacePanelProps.ts +40 -0
  501. package/src/panels/SpacePanel/index.ts +6 -0
  502. package/src/panels/SpacePanel/spaceMachine.ts +72 -0
  503. package/src/panels/SpacePanel/steps/SpaceManager.tsx +157 -0
  504. package/src/panels/SpacePanel/steps/index.ts +5 -0
  505. package/src/panels/index.ts +7 -0
  506. package/src/playwright/invitations-manager.ts +168 -0
  507. package/src/playwright/invitations.spec.ts +364 -0
  508. package/src/playwright/playwright.config.ts +7 -0
  509. package/src/react.ts +9 -0
  510. package/src/steps/InvitationManager.tsx +116 -0
  511. package/src/steps/StepProps.ts +17 -0
  512. package/src/steps/index.ts +6 -0
  513. package/src/stories/Invitations.e2e-stories.tsx +231 -0
  514. package/src/styles/index.ts +6 -0
  515. package/src/styles/invitationStatusStyles.ts +42 -0
  516. package/src/styles/panelStyles.ts +5 -0
  517. package/src/testing/fixtures/identities.ts +16 -0
  518. package/src/testing/fixtures/index.ts +6 -0
  519. package/src/testing/fixtures/invitations.ts +23 -0
  520. package/src/testing/index.ts +7 -0
  521. package/src/testing/scoped-shell-manager.ts +79 -0
  522. package/src/testing/shell-manager.ts +102 -0
  523. package/src/translations/index.ts +7 -0
  524. package/src/translations/locales/en-US.ts +101 -0
  525. package/src/types/FailReason.ts +5 -0
  526. package/src/types/IInvitation.ts +14 -0
  527. package/src/types/index.ts +6 -0
  528. package/src/util/index.ts +6 -0
  529. package/src/util/invitationStatusValue.ts +22 -0
  530. package/src/util/toEmoji.ts +22 -0
@@ -0,0 +1,3617 @@
1
+ import {
2
+ __export
3
+ } from "./chunk-ZSTKOCBT.mjs";
4
+
5
+ // packages/sdk/shell/src/components/Clipboard/CopyButton.tsx
6
+ import { Check, Copy } from "@phosphor-icons/react";
7
+ import React2, { useState as useState2 } from "react";
8
+ import { Button, Tooltip, useTranslation } from "@dxos/react-ui";
9
+ import { getSize, mx } from "@dxos/react-ui-theme";
10
+
11
+ // packages/sdk/shell/src/components/Clipboard/ClipboardProvider.tsx
12
+ import React, { createContext, useCallback, useContext, useState } from "react";
13
+ var ClipboardContext = /* @__PURE__ */ createContext({
14
+ textValue: "",
15
+ setTextValue: async (_) => {
16
+ }
17
+ });
18
+ var useClipboardContext = () => useContext(ClipboardContext);
19
+ var ClipboardProvider = ({ children }) => {
20
+ const [textValue, setInternalTextValue] = useState("");
21
+ const setTextValue = useCallback(async (nextValue) => {
22
+ await navigator.clipboard.writeText(nextValue);
23
+ return setInternalTextValue(nextValue);
24
+ }, []);
25
+ return /* @__PURE__ */ React.createElement(ClipboardContext.Provider, {
26
+ value: {
27
+ textValue,
28
+ setTextValue
29
+ }
30
+ }, children);
31
+ };
32
+
33
+ // packages/sdk/shell/src/components/Clipboard/CopyButton.tsx
34
+ var inactiveLabelStyles = "invisible bs-px -mbe-px overflow-hidden";
35
+ var CopyButton = ({ value, classNames, iconProps, ...props }) => {
36
+ const { t } = useTranslation("os");
37
+ const { textValue, setTextValue } = useClipboardContext();
38
+ const isCopied = textValue === value;
39
+ return /* @__PURE__ */ React2.createElement(Button, {
40
+ ...props,
41
+ classNames: [
42
+ "inline-flex flex-col justify-center",
43
+ classNames
44
+ ],
45
+ onClick: () => setTextValue(value),
46
+ "data-testid": "copy-invitation"
47
+ }, /* @__PURE__ */ React2.createElement("div", {
48
+ role: "none",
49
+ className: mx("flex gap-1 items-center", isCopied && inactiveLabelStyles)
50
+ }, /* @__PURE__ */ React2.createElement("span", {
51
+ className: "pli-1"
52
+ }, t("copy invitation code label")), /* @__PURE__ */ React2.createElement(Copy, {
53
+ className: getSize(4),
54
+ weight: "bold",
55
+ ...iconProps
56
+ })), /* @__PURE__ */ React2.createElement("div", {
57
+ role: "none",
58
+ className: mx("flex gap-1 items-center", !isCopied && inactiveLabelStyles)
59
+ }, /* @__PURE__ */ React2.createElement("span", {
60
+ className: "pli-1"
61
+ }, t("copy invitation code success label")), /* @__PURE__ */ React2.createElement(Check, {
62
+ className: getSize(4),
63
+ weight: "bold",
64
+ ...iconProps
65
+ })));
66
+ };
67
+ var CopyButtonIconOnly = ({ value, classNames, iconProps, variant, ...props }) => {
68
+ const { t } = useTranslation("os");
69
+ const { textValue, setTextValue } = useClipboardContext();
70
+ const isCopied = textValue === value;
71
+ const label = isCopied ? t("copy invitation code success label") : t("copy invitation code label");
72
+ const [open, setOpen] = useState2(false);
73
+ return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
74
+ delayDuration: 1500,
75
+ open,
76
+ onOpenChange: setOpen
77
+ }, /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, {
78
+ side: "bottom",
79
+ sideOffset: 12,
80
+ classNames: "z-30"
81
+ }, /* @__PURE__ */ React2.createElement("span", null, label), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))), /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
82
+ "aria-label": label,
83
+ ...props,
84
+ onClick: () => setTextValue(value).then(() => setOpen(true)),
85
+ "data-testid": "copy-invitation",
86
+ asChild: true
87
+ }, /* @__PURE__ */ React2.createElement(Button, {
88
+ variant,
89
+ classNames: [
90
+ "inline-flex flex-col justify-center",
91
+ classNames
92
+ ]
93
+ }, /* @__PURE__ */ React2.createElement(Copy, {
94
+ className: getSize(5),
95
+ weight: "bold",
96
+ ...iconProps
97
+ }))));
98
+ };
99
+
100
+ // packages/sdk/shell/src/components/CompoundButton/CompoundButton.tsx
101
+ import React3 from "react";
102
+ import { useId, useThemeContext, useElevationContext } from "@dxos/react-ui";
103
+ import { descriptionText, descriptionTextPrimary, mx as mx2 } from "@dxos/react-ui-theme";
104
+ var CompoundButton = ({ children, description, before, after, variant = "default", elevation: propsElevation, slots = {}, ...buttonProps }) => {
105
+ const labelId = useId("compoundButton-label");
106
+ const descriptionId = useId("compoundButton-description");
107
+ const { tx } = useThemeContext();
108
+ const elevation = useElevationContext(propsElevation);
109
+ const styleProps = {
110
+ ...buttonProps,
111
+ variant,
112
+ elevation,
113
+ textWrap: true
114
+ };
115
+ const buttonClassName = tx("button.root", "button button--compound", styleProps, "flex items-center gap-4 plb-2.5", slots.root?.className);
116
+ return /* @__PURE__ */ React3.createElement("button", {
117
+ ...buttonProps,
118
+ ...slots.root,
119
+ className: buttonClassName,
120
+ "aria-labelledby": labelId,
121
+ ...description && {
122
+ "aria-describedby": descriptionId
123
+ }
124
+ }, before && /* @__PURE__ */ React3.createElement("div", {
125
+ role: "none",
126
+ className: "grow-0"
127
+ }, before), /* @__PURE__ */ React3.createElement("div", {
128
+ role: "none",
129
+ ...slots.middle,
130
+ className: mx2("grow whitespace-normal flex flex-col gap-1 text-left", slots.middle?.className)
131
+ }, /* @__PURE__ */ React3.createElement("p", {
132
+ ...slots.label,
133
+ id: labelId,
134
+ className: mx2(slots.label?.className)
135
+ }, children), description && /* @__PURE__ */ React3.createElement("p", {
136
+ id: descriptionId,
137
+ ...slots.description,
138
+ className: mx2("text-xs mbe-1 font-normal", variant === "primary" ? descriptionTextPrimary : descriptionText, slots.description?.className)
139
+ }, description)), after && /* @__PURE__ */ React3.createElement("div", {
140
+ role: "none",
141
+ className: "grow-0"
142
+ }, after));
143
+ };
144
+
145
+ // packages/sdk/shell/src/components/IdentityList/DeviceList.tsx
146
+ import React5 from "react";
147
+ import { List, useTranslation as useTranslation2 } from "@dxos/react-ui";
148
+ import { descriptionText as descriptionText2, mx as mx4 } from "@dxos/react-ui-theme";
149
+
150
+ // packages/sdk/shell/src/components/IdentityList/IdentityListItem.tsx
151
+ import React4, { forwardRef } from "react";
152
+ import { generateName } from "@dxos/display-name";
153
+ import { SpaceMember } from "@dxos/react-client/echo";
154
+ import { ListItem, Avatar, useJdenticonHref, useId as useId2 } from "@dxos/react-ui";
155
+ import { mx as mx3 } from "@dxos/react-ui-theme";
156
+ var IdentityListItem = /* @__PURE__ */ forwardRef(({ identity, presence, onClick }, forwardedRef) => {
157
+ const fallbackValue = identity.identityKey.toHex();
158
+ const labelId = useId2("identityListItem__label");
159
+ const jdenticon = useJdenticonHref(fallbackValue ?? "", 12);
160
+ const displayName = identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
161
+ return /* @__PURE__ */ React4.createElement(ListItem.Root, {
162
+ classNames: mx3("flex gap-2 pis-3 pie-1 items-center", onClick && "cursor-pointer"),
163
+ onClick: () => onClick?.(),
164
+ "data-testid": "identity-list-item",
165
+ labelId,
166
+ ref: forwardedRef
167
+ }, /* @__PURE__ */ React4.createElement(Avatar.Root, {
168
+ status: presence === SpaceMember.PresenceState.ONLINE ? "active" : "inactive",
169
+ labelId
170
+ }, /* @__PURE__ */ React4.createElement(Avatar.Frame, null, /* @__PURE__ */ React4.createElement(Avatar.Fallback, {
171
+ href: jdenticon
172
+ })), /* @__PURE__ */ React4.createElement(Avatar.Label, {
173
+ classNames: "text-sm truncate pli-2"
174
+ }, displayName)));
175
+ });
176
+
177
+ // packages/sdk/shell/src/components/IdentityList/DeviceList.tsx
178
+ var DeviceList = ({ devices, onSelect }) => {
179
+ const { t } = useTranslation2("os");
180
+ return devices.length > 0 ? /* @__PURE__ */ React5.createElement(List, {
181
+ classNames: "flex flex-col gap-2"
182
+ }, devices.map((device) => {
183
+ const identity = {
184
+ identityKey: device.deviceKey,
185
+ profile: {
186
+ displayName: `${device.profile?.platform} (${device.profile?.platformVersion}) on ${device.profile?.os} (${device.profile?.osVersion}) ${device.profile?.architecture ?? "Unknown"}-bit`
187
+ }
188
+ };
189
+ return /* @__PURE__ */ React5.createElement(IdentityListItem, {
190
+ key: device.deviceKey.toHex(),
191
+ identity,
192
+ onClick: onSelect && (() => onSelect(device))
193
+ });
194
+ })) : /* @__PURE__ */ React5.createElement("div", {
195
+ role: "none",
196
+ className: "grow flex items-center p-2"
197
+ }, /* @__PURE__ */ React5.createElement("p", {
198
+ className: mx4(descriptionText2, "text-center is-full")
199
+ }, t("empty device list message")));
200
+ };
201
+
202
+ // packages/sdk/shell/src/components/IdentityList/SpaceMemberList.tsx
203
+ import React6, { useMemo } from "react";
204
+ import { useClient } from "@dxos/react-client";
205
+ import { useMembers } from "@dxos/react-client/echo";
206
+ import { useTranslation as useTranslation3, List as List2 } from "@dxos/react-ui";
207
+ import { descriptionText as descriptionText3, mx as mx5 } from "@dxos/react-ui-theme";
208
+ var SpaceMemberList = ({ spaceKey, includeSelf, onSelect }) => {
209
+ const client = useClient();
210
+ const allUnsortedMembers = useMembers(spaceKey);
211
+ const members = useMemo(() => includeSelf ? allUnsortedMembers.sort((member) => member.identity.identityKey.equals(client.halo.identity.get().identityKey) ? -1 : 1) : allUnsortedMembers.filter((member) => !member.identity.identityKey.equals(client.halo.identity.get().identityKey)), [
212
+ allUnsortedMembers
213
+ ]);
214
+ return /* @__PURE__ */ React6.createElement(SpaceMemberListImpl, {
215
+ members,
216
+ onSelect
217
+ });
218
+ };
219
+ var SpaceMemberListImpl = ({ members, onSelect }) => {
220
+ const { t } = useTranslation3("os");
221
+ const visibleMembers = members.filter((member) => member.identity);
222
+ return visibleMembers.length > 0 ? /* @__PURE__ */ React6.createElement(List2, {
223
+ classNames: "flex flex-col gap-2"
224
+ }, visibleMembers.map((member) => {
225
+ return /* @__PURE__ */ React6.createElement(IdentityListItem, {
226
+ key: member.identity.identityKey.toHex(),
227
+ identity: member.identity,
228
+ presence: member.presence,
229
+ onClick: onSelect && (() => onSelect(member))
230
+ });
231
+ })) : /* @__PURE__ */ React6.createElement("div", {
232
+ role: "none",
233
+ className: "grow flex items-center p-2"
234
+ }, /* @__PURE__ */ React6.createElement("p", {
235
+ className: mx5(descriptionText3, "text-center is-full mlb-2")
236
+ }, t("empty space members message")));
237
+ };
238
+
239
+ // packages/sdk/shell/src/components/InvitationList/InvitationListItem.tsx
240
+ import { X } from "@phosphor-icons/react";
241
+ import React8, { useCallback as useCallback2 } from "react";
242
+ import { Invitation as Invitation2, useInvitationStatus } from "@dxos/react-client/invitations";
243
+ import { Button as Button2, ListItem as ListItem2, useTranslation as useTranslation4, Avatar as Avatar2, useThemeContext as useThemeContext2, Tooltip as Tooltip2 } from "@dxos/react-ui";
244
+ import { focusRing, getSize as getSize2, mx as mx7 } from "@dxos/react-ui-theme";
245
+
246
+ // packages/sdk/shell/src/util/invitationStatusValue.ts
247
+ import { Invitation } from "@dxos/react-client/invitations";
248
+ var invitationStatusValue = /* @__PURE__ */ new Map([
249
+ [
250
+ Invitation.State.ERROR,
251
+ -3
252
+ ],
253
+ [
254
+ Invitation.State.TIMEOUT,
255
+ -2
256
+ ],
257
+ [
258
+ Invitation.State.CANCELLED,
259
+ -1
260
+ ],
261
+ [
262
+ Invitation.State.INIT,
263
+ 0
264
+ ],
265
+ [
266
+ Invitation.State.CONNECTING,
267
+ 1
268
+ ],
269
+ [
270
+ Invitation.State.CONNECTED,
271
+ 2
272
+ ],
273
+ [
274
+ Invitation.State.READY_FOR_AUTHENTICATION,
275
+ 3
276
+ ],
277
+ [
278
+ Invitation.State.AUTHENTICATING,
279
+ 4
280
+ ],
281
+ [
282
+ Invitation.State.SUCCESS,
283
+ 5
284
+ ]
285
+ ]);
286
+
287
+ // packages/sdk/shell/src/util/toEmoji.ts
288
+ import toArray from "lodash.toarray";
289
+ var emoji = toArray(
290
+ // When changing this set, please check the result in a console or e.g. RunKit (https://runkit.com/thure/642214441dd6ae000855a8de)
291
+ // Emoji sometimes use a combination of code points, and some code points aren't visible on their own, so by adding or deleting you may unintentionally create non-visible items.
292
+ // This set was chosen from the characters in Unicode Emoji v15.0 based on the following criteria:
293
+ // – not people or isolated anthropomorphic faces
294
+ // – not flags
295
+ // – more concrete than abstract
296
+ // – less culturally specific
297
+ // – less easily confused with another emoji in the set
298
+ // – requires less special knowledge to identify
299
+ // – less likely to evoke negative feelings (no meat, no drugs, no weapons, etc)
300
+ // – less common as a signifier in UX
301
+ "\u{1F479}\u{1F47B}\u{1F47D}\u{1F916}\u{1F383}\u{1F9BE}\u{1F9BF}\u{1F9B7}\u{1F463}\u{1F441}\uFE0F\u{1F9F6}\u{1F451}\u{1F412}\u{1F986}\u{1F989}\u{1F434}\u{1F984}\u{1F41D}\u{1F98B}\u{1F41E}\u{1FAB2}\u{1F422}\u{1F98E}\u{1F995}\u{1F991}\u{1F980}\u{1F420}\u{1F42C}\u{1F40B}\u{1F9AD}\u{1F405}\u{1F406}\u{1F993}\u{1F98D}\u{1F9A7}\u{1F418}\u{1F42B}\u{1F992}\u{1F998}\u{1F9AC}\u{1F416}\u{1F40F}\u{1F98C}\u{1F415}\u{1F408}\u{1F413}\u{1F99A}\u{1F99C}\u{1F9A2}\u{1F9A9}\u{1F9A6}\u{1F401}\u{1F43F}\uFE0F\u{1F335}\u{1F332}\u{1F333}\u{1FAB5}\u{1F331}\u{1F341}\u{1FABA}\u{1F344}\u{1F41A}\u{1FAB8}\u{1FAA8}\u{1F33E}\u{1F337}\u{1F33B}\u2600\uFE0F\u{1F319}\u{1FA90}\u2B50\uFE0F\u26A1\uFE0F\u2604\uFE0F\u{1F525}\u{1F308}\u2601\uFE0F\u{1F4A7}\u26F1\uFE0F\u{1F30A}\u{1F34E}\u{1F34B}\u{1F349}\u{1F347}\u{1FAD0}\u{1F348}\u{1F352}\u{1F351}\u{1F96D}\u{1F34D}\u{1F965}\u{1F95D}\u{1F951}\u{1F336}\uFE0F\u{1F33D}\u{1F955}\u{1F36C}\u{1F95C}\u{1FAD6}\u2615\uFE0F\u{1F375}\u{1F9CA}\u{1F9C2}\u{1F3D4}\uFE0F\u2693\uFE0F\u{1F6DF}\u{1F3DD}\uFE0F\u{1F6F6}\u{1F680}\u{1F6F0}\uFE0F\u26F2\uFE0F\u{1F3F0}\u{1F6B2}\u26FA\uFE0F\u{1F399}\uFE0F\u{1F9F2}\u2699\uFE0F\u{1F529}\u{1F52E}\u{1F52D}\u{1F52C}\u{1F9EC}\u{1F321}\uFE0F\u{1F9FA}\u{1F6CE}\uFE0F\u{1F511}\u{1FA91}\u{1F9F8}\u{1F388}\u{1F380}\u{1F38A}\u267B\uFE0F\u{1F3B5}"
302
+ );
303
+ var toEmoji = (keyAsHex) => emoji[parseInt(keyAsHex, 16) % emoji.length];
304
+
305
+ // packages/sdk/shell/src/components/AuthCode.tsx
306
+ import React7 from "react";
307
+ import { mx as mx6 } from "@dxos/react-ui-theme";
308
+ var AuthCode = (props) => {
309
+ const { code, large, classNames } = props;
310
+ const l = code?.length ?? 0;
311
+ const left = code?.slice(0, l / 2);
312
+ const right = code?.slice(l / 2);
313
+ const handleCopy = () => {
314
+ void navigator.clipboard.writeText(code ?? "");
315
+ };
316
+ return /* @__PURE__ */ React7.createElement("span", {
317
+ className: mx6(large ? "text-6xl" : "text-2xl", "font-mono pli-2.5 flex gap-1.5 rounded cursor-pointer", classNames),
318
+ onClick: handleCopy
319
+ }, /* @__PURE__ */ React7.createElement("span", null, left), /* @__PURE__ */ React7.createElement("span", null, right));
320
+ };
321
+
322
+ // packages/sdk/shell/src/components/InvitationList/InvitationListItem.tsx
323
+ var InvitationListItem = (props) => {
324
+ const { invitation } = props;
325
+ const invitationStatus = useInvitationStatus(invitation);
326
+ return /* @__PURE__ */ React8.createElement(InvitationListItemImpl, {
327
+ ...props,
328
+ invitationStatus
329
+ });
330
+ };
331
+ var avatarProps = {
332
+ size: 10,
333
+ variant: "circle"
334
+ };
335
+ var AvatarStackEffect = ({ animation, status }) => {
336
+ const { tx } = useThemeContext2();
337
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("span", {
338
+ role: "none",
339
+ className: mx7("absolute inline-start-1 inline-end-auto opacity-20", getSize2(avatarProps.size))
340
+ }, /* @__PURE__ */ React8.createElement("span", {
341
+ role: "none",
342
+ className: tx("avatar.ring", "avatar__ring", {
343
+ ...avatarProps,
344
+ status,
345
+ animation
346
+ }),
347
+ style: {
348
+ animationDelay: "400ms"
349
+ }
350
+ })), /* @__PURE__ */ React8.createElement("span", {
351
+ role: "none",
352
+ className: mx7("absolute inline-start-2 inline-end-auto opacity-50", getSize2(avatarProps.size))
353
+ }, /* @__PURE__ */ React8.createElement("span", {
354
+ role: "none",
355
+ className: tx("avatar.ring", "avatar__ring", {
356
+ ...avatarProps,
357
+ status,
358
+ animation
359
+ }),
360
+ style: {
361
+ animationDelay: "200ms"
362
+ }
363
+ })));
364
+ };
365
+ var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationStatus, send, onClickRemove, createInvitationUrl }) => {
366
+ const { t } = useTranslation4("os");
367
+ const { cancel, status: invitationStatus, invitationCode, authCode, type } = propsInvitationStatus;
368
+ const isCancellable = !([
369
+ Invitation2.State.ERROR,
370
+ Invitation2.State.TIMEOUT,
371
+ Invitation2.State.CANCELLED
372
+ ].indexOf(invitationStatus) >= 0);
373
+ const showShare = type === Invitation2.Type.MULTIUSE || [
374
+ Invitation2.State.INIT,
375
+ Invitation2.State.CONNECTING,
376
+ Invitation2.State.CONNECTED
377
+ ].indexOf(invitationStatus) >= 0;
378
+ const showAuthCode = invitationStatus === Invitation2.State.READY_FOR_AUTHENTICATION;
379
+ const handleClickRemove = useCallback2(() => onClickRemove?.(invitation), [
380
+ invitation,
381
+ onClickRemove
382
+ ]);
383
+ const invitationUrl = invitationCode && createInvitationUrl(invitationCode);
384
+ const invitationId = invitation?.get().invitationId;
385
+ const avatarAnimation = [
386
+ Invitation2.State.INIT,
387
+ Invitation2.State.CONNECTING,
388
+ Invitation2.State.CONNECTED,
389
+ Invitation2.State.READY_FOR_AUTHENTICATION,
390
+ Invitation2.State.AUTHENTICATING
391
+ ].includes(invitationStatus) ? "pulse" : "none";
392
+ const avatarError = [
393
+ Invitation2.State.ERROR,
394
+ Invitation2.State.TIMEOUT,
395
+ Invitation2.State.CANCELLED
396
+ ].includes(invitationStatus);
397
+ const avatarGreen = [
398
+ Invitation2.State.CONNECTED,
399
+ Invitation2.State.READY_FOR_AUTHENTICATION,
400
+ Invitation2.State.AUTHENTICATING,
401
+ Invitation2.State.SUCCESS
402
+ ].includes(invitationStatus);
403
+ const avatarStatus = avatarError ? "error" : avatarGreen ? "active" : "inactive";
404
+ return /* @__PURE__ */ React8.createElement(ListItem2.Root, {
405
+ id: invitationCode,
406
+ classNames: "flex gap-2 pis-3 pie-1 items-center relative"
407
+ }, /* @__PURE__ */ React8.createElement(ListItem2.Heading, {
408
+ classNames: "sr-only"
409
+ }, t(type === Invitation2.Type.MULTIUSE ? "invite many list item label" : "invite one list item label")), type === Invitation2.Type.MULTIUSE && /* @__PURE__ */ React8.createElement(AvatarStackEffect, {
410
+ status: avatarStatus,
411
+ animation: avatarAnimation
412
+ }), /* @__PURE__ */ React8.createElement(Tooltip2.Root, null, /* @__PURE__ */ React8.createElement(Avatar2.Root, {
413
+ ...avatarProps,
414
+ animation: avatarAnimation,
415
+ status: avatarStatus
416
+ }, /* @__PURE__ */ React8.createElement(Tooltip2.Trigger, {
417
+ asChild: true
418
+ }, /* @__PURE__ */ React8.createElement(Avatar2.Frame, {
419
+ tabIndex: 0,
420
+ classNames: [
421
+ focusRing,
422
+ "relative rounded-full"
423
+ ]
424
+ }, /* @__PURE__ */ React8.createElement(Avatar2.Fallback, {
425
+ text: toEmoji(invitationId)
426
+ })))), /* @__PURE__ */ React8.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip2.Content, {
427
+ side: "left",
428
+ classNames: "z-[70]"
429
+ }, t(type === Invitation2.Type.MULTIUSE ? "invite many qr label" : "invite one qr label"), /* @__PURE__ */ React8.createElement(Tooltip2.Arrow, null)))), showShare && invitationUrl ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Button2, {
430
+ variant: "ghost",
431
+ classNames: "grow justify-start font-medium",
432
+ onClick: () => send({
433
+ type: "selectInvitation",
434
+ invitation
435
+ }),
436
+ "data-testid": "show-qrcode"
437
+ }, /* @__PURE__ */ React8.createElement("span", null, t("open share panel label"))), /* @__PURE__ */ React8.createElement(CopyButtonIconOnly, {
438
+ variant: "ghost",
439
+ value: invitationUrl
440
+ })) : showAuthCode ? /* @__PURE__ */ React8.createElement(AuthCode, {
441
+ code: authCode,
442
+ classNames: "grow"
443
+ }) : invitationStatus === Invitation2.State.CONNECTING ? /* @__PURE__ */ React8.createElement("span", {
444
+ className: "pli-2 grow text-neutral-500"
445
+ }, "Connecting...") : invitationStatus === Invitation2.State.AUTHENTICATING ? /* @__PURE__ */ React8.createElement("span", {
446
+ className: "pli-2 grow text-neutral-500"
447
+ }, "Authenticating...") : invitationStatus === Invitation2.State.ERROR || invitationStatus === Invitation2.State.TIMEOUT ? /* @__PURE__ */ React8.createElement("span", {
448
+ className: "pli-2 grow text-neutral-500"
449
+ }, "Failed") : invitationStatus === Invitation2.State.CANCELLED ? /* @__PURE__ */ React8.createElement("span", {
450
+ className: "pli-2 grow text-neutral-500"
451
+ }, "Cancelled") : invitationStatus === Invitation2.State.SUCCESS ? /* @__PURE__ */ React8.createElement("span", {
452
+ className: "pli-2 grow truncate"
453
+ }, "User joined") : /* @__PURE__ */ React8.createElement("span", {
454
+ className: "grow"
455
+ }, " "), isCancellable ? /* @__PURE__ */ React8.createElement(Button2, {
456
+ variant: "ghost",
457
+ classNames: "flex gap-1",
458
+ onClick: cancel,
459
+ "data-testid": "cancel-invitation"
460
+ }, /* @__PURE__ */ React8.createElement("span", {
461
+ className: "sr-only"
462
+ }, t("cancel invitation label")), /* @__PURE__ */ React8.createElement(X, {
463
+ className: getSize2(5),
464
+ weight: "bold"
465
+ })) : /* @__PURE__ */ React8.createElement(Button2, {
466
+ variant: "ghost",
467
+ classNames: "flex gap-1",
468
+ onClick: handleClickRemove,
469
+ "data-testid": "remove-invitation"
470
+ }, /* @__PURE__ */ React8.createElement("span", {
471
+ className: "sr-only"
472
+ }, t("remove invitation label")), /* @__PURE__ */ React8.createElement(X, {
473
+ className: getSize2(5),
474
+ weight: "bold"
475
+ })));
476
+ };
477
+
478
+ // packages/sdk/shell/src/components/InvitationList/InvitationListContainer.tsx
479
+ import React10, { useCallback as useCallback3 } from "react";
480
+ import { useSpace, useSpaceInvitations } from "@dxos/react-client/echo";
481
+
482
+ // packages/sdk/shell/src/components/InvitationList/InvitationList.tsx
483
+ import React9 from "react";
484
+ import { List as List3 } from "@dxos/react-ui";
485
+ import { mx as mx8 } from "@dxos/react-ui-theme";
486
+ var InvitationList = ({ invitations, send, ...invitationProps }) => {
487
+ const { className, InvitationListItem: Item = InvitationListItem } = invitationProps;
488
+ return /* @__PURE__ */ React9.createElement(List3, {
489
+ classNames: mx8("flex flex-col gap-2", className)
490
+ }, invitations.map((invitation) => {
491
+ const value = invitation.get().invitationId;
492
+ return /* @__PURE__ */ React9.createElement(Item, {
493
+ key: value,
494
+ send,
495
+ invitation,
496
+ ...invitationProps
497
+ });
498
+ }));
499
+ };
500
+
501
+ // packages/sdk/shell/src/components/InvitationList/InvitationListContainer.tsx
502
+ var InvitationListContainer = ({ spaceKey, createInvitationUrl, send }) => {
503
+ const space = useSpace(spaceKey);
504
+ const invitations = useSpaceInvitations(spaceKey);
505
+ const onClickRemove = useCallback3((invitation) => {
506
+ void invitation.cancel();
507
+ }, [
508
+ space
509
+ ]);
510
+ return /* @__PURE__ */ React10.createElement(InvitationList, {
511
+ invitations,
512
+ onClickRemove,
513
+ createInvitationUrl,
514
+ send
515
+ });
516
+ };
517
+
518
+ // packages/sdk/shell/src/components/Panel/Action.tsx
519
+ import { CaretDown, Check as Check2, Placeholder } from "@phosphor-icons/react";
520
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
521
+ import React11, { forwardRef as forwardRef2 } from "react";
522
+ import { Button as Button3, DropdownMenu, useTranslation as useTranslation5 } from "@dxos/react-ui";
523
+ import { descriptionText as descriptionText4, getSize as getSize3, mx as mx9 } from "@dxos/react-ui-theme";
524
+ var buttonColorFragment = (props) => {
525
+ const resolvedVariant = props.variant ?? "default";
526
+ return [
527
+ !props.disabled ? resolvedVariant === "default" ? "bg-neutral-25 hover:bg-white hover:text-primary-500 active:bg-neutral-25 dark:active:bg-neutral-800" : resolvedVariant === "ghost" ? "active:bg-neutral-125 dark:active:bg-neutral-800" : resolvedVariant === "primary" ? "active:bg-primary-700 dark:active:bg-primary-500" : "" : ""
528
+ ];
529
+ };
530
+ var defaultActions = {
531
+ noopAction: {
532
+ label: "No-op",
533
+ description: "",
534
+ icon: Placeholder,
535
+ onClick: () => {
536
+ }
537
+ }
538
+ };
539
+ var BifurcatedAction = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
540
+ const { classNames, variant, isFull = true, actions = defaultActions, activeAction: propsActiveAction, onChangeActiveAction, defaultActiveAction, ...rest } = props;
541
+ const [activeActionKey2 = Object.keys(actions)[0], setActiveAction] = useControllableState({
542
+ prop: propsActiveAction,
543
+ onChange: onChangeActiveAction,
544
+ defaultProp: defaultActiveAction
545
+ });
546
+ const activeAction = actions[activeActionKey2] ?? {};
547
+ const { t } = useTranslation5("os");
548
+ return /* @__PURE__ */ React11.createElement("div", {
549
+ role: "none",
550
+ className: mx9("mbs-2 flex gap-px items-center", isFull && "is-full")
551
+ }, /* @__PURE__ */ React11.createElement(Button3, {
552
+ ...rest,
553
+ classNames: [
554
+ "bs-11 flex-1 min-is-0 flex gap-2 rounded-ie-none",
555
+ classNames,
556
+ ...buttonColorFragment(props)
557
+ ],
558
+ ref: forwardedRef,
559
+ variant,
560
+ onClick: activeAction.onClick
561
+ }, activeAction.icon && /* @__PURE__ */ React11.createElement(activeAction.icon, null), /* @__PURE__ */ React11.createElement("span", null, activeAction.label)), /* @__PURE__ */ React11.createElement(DropdownMenu.Root, null, /* @__PURE__ */ React11.createElement(DropdownMenu.Trigger, {
562
+ asChild: true
563
+ }, /* @__PURE__ */ React11.createElement(Button3, {
564
+ classNames: [
565
+ "bs-11 flex-none rounded-is-none",
566
+ classNames,
567
+ ...buttonColorFragment(props)
568
+ ]
569
+ }, /* @__PURE__ */ React11.createElement("span", {
570
+ className: "sr-only"
571
+ }, t("invite options label")), /* @__PURE__ */ React11.createElement(CaretDown, null))), /* @__PURE__ */ React11.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React11.createElement(DropdownMenu.Viewport, null, Object.entries(actions).map(([id, action]) => {
572
+ return /* @__PURE__ */ React11.createElement(DropdownMenu.CheckboxItem, {
573
+ key: id,
574
+ "aria-labelledby": `${id}__label`,
575
+ "aria-describedby": `${id}__description`,
576
+ checked: activeActionKey2 === id,
577
+ onCheckedChange: (checked) => checked && setActiveAction(id),
578
+ classNames: "gap-2"
579
+ }, action.icon && /* @__PURE__ */ React11.createElement(action.icon, {
580
+ className: getSize3(5)
581
+ }), /* @__PURE__ */ React11.createElement("div", {
582
+ role: "none",
583
+ className: "flex-1 min-is-0 space-b-1"
584
+ }, /* @__PURE__ */ React11.createElement("p", {
585
+ id: `${id}__label`
586
+ }, action.label), action.description && /* @__PURE__ */ React11.createElement("p", {
587
+ id: `${id}__description`,
588
+ className: descriptionText4
589
+ }, action.description)), /* @__PURE__ */ React11.createElement(DropdownMenu.ItemIndicator, {
590
+ asChild: true
591
+ }, /* @__PURE__ */ React11.createElement(Check2, null)));
592
+ })), /* @__PURE__ */ React11.createElement(DropdownMenu.Arrow, null))));
593
+ });
594
+ var Action = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
595
+ const { children, classNames, variant, isFull = true, ...rest } = props;
596
+ return /* @__PURE__ */ React11.createElement(Button3, {
597
+ ...rest,
598
+ classNames: [
599
+ isFull && "is-full",
600
+ "bs-11 flex gap-2 mbs-2",
601
+ classNames,
602
+ ...buttonColorFragment(props)
603
+ ],
604
+ ref: forwardedRef,
605
+ variant
606
+ }, children);
607
+ });
608
+
609
+ // packages/sdk/shell/src/components/Panel/Actions.tsx
610
+ import React12, { forwardRef as forwardRef3 } from "react";
611
+ import { mx as mx10 } from "@dxos/react-ui-theme";
612
+ var Actions = /* @__PURE__ */ forwardRef3(({ classNames, children, ...props }, forwardedRef) => {
613
+ return /* @__PURE__ */ React12.createElement("div", {
614
+ ...props,
615
+ className: mx10("flex flex-col gap-2 mbs-2", Array.isArray(children) && children.length > 1 ? "justify-between" : "justify-center", classNames),
616
+ ref: forwardedRef
617
+ }, children);
618
+ });
619
+
620
+ // packages/sdk/shell/src/components/Panel/CloseButton.tsx
621
+ import { X as X2 } from "@phosphor-icons/react";
622
+ import React13 from "react";
623
+ import { Button as Button4, useTranslation as useTranslation6 } from "@dxos/react-ui";
624
+ import { getSize as getSize4, mx as mx11 } from "@dxos/react-ui-theme";
625
+ var CloseButton = ({ onDone, ...props }) => {
626
+ const { t } = useTranslation6("os");
627
+ return /* @__PURE__ */ React13.createElement(Button4, {
628
+ variant: "ghost",
629
+ classNames: mx11("plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
630
+ onClick: () => onDone?.(),
631
+ ...props
632
+ }, /* @__PURE__ */ React13.createElement(X2, {
633
+ weight: "bold",
634
+ className: getSize4(4)
635
+ }), /* @__PURE__ */ React13.createElement("span", {
636
+ className: "sr-only"
637
+ }, t("exit label")));
638
+ };
639
+
640
+ // packages/sdk/shell/src/components/Panel/Emoji.tsx
641
+ import React14 from "react";
642
+ import { mx as mx12, getSize as getSize5 } from "@dxos/react-ui-theme";
643
+ var Emoji = ({ text, className }) => {
644
+ const size = 14;
645
+ return /* @__PURE__ */ React14.createElement("div", {
646
+ role: "none",
647
+ className: mx12(getSize5(size), "rounded relative pointer-events-none", className)
648
+ }, /* @__PURE__ */ React14.createElement("svg", {
649
+ viewBox: `0 0 ${size * 4} ${size * 4}`,
650
+ width: size * 4,
651
+ height: size * 4
652
+ }, /* @__PURE__ */ React14.createElement("text", {
653
+ x: "50%",
654
+ y: "50%",
655
+ textAnchor: "middle",
656
+ dominantBaseline: "middle",
657
+ baselineShift: "-0.25rem",
658
+ fontSize: "2.25rem"
659
+ }, text)));
660
+ };
661
+ var Centered = (props) => {
662
+ const { children } = props;
663
+ return /* @__PURE__ */ React14.createElement("div", {
664
+ role: "none",
665
+ className: "absolute inset-0 flex items-center justify-center"
666
+ }, children);
667
+ };
668
+
669
+ // packages/sdk/shell/src/components/Panel/Heading.tsx
670
+ import React15, { forwardRef as forwardRef4 } from "react";
671
+ import { descriptionText as descriptionText5, mx as mx13 } from "@dxos/react-ui-theme";
672
+ var Heading = /* @__PURE__ */ forwardRef4(({ titleId, title, titleSrOnly, children, corner }, forwardedRef) => {
673
+ return /* @__PURE__ */ React15.createElement("div", {
674
+ role: "none",
675
+ className: "pbe-2 relative",
676
+ ref: forwardedRef
677
+ }, corner, /* @__PURE__ */ React15.createElement("h1", {
678
+ ...!titleSrOnly && {
679
+ id: titleId
680
+ },
681
+ className: mx13(descriptionText5, "text-center mlb-2", titleSrOnly && "invisible")
682
+ }, title), titleSrOnly && /* @__PURE__ */ React15.createElement("span", {
683
+ id: titleId
684
+ }, title), children);
685
+ });
686
+
687
+ // packages/sdk/shell/src/components/Panel/Label.tsx
688
+ import React16 from "react";
689
+ import { descriptionText as descriptionText6, mx as mx14 } from "@dxos/react-ui-theme";
690
+ var Label = (props) => {
691
+ const { children } = props;
692
+ return /* @__PURE__ */ React16.createElement("span", {
693
+ className: mx14(descriptionText6, "text-center mli-6 whitespace-normal")
694
+ }, children);
695
+ };
696
+
697
+ // packages/sdk/shell/src/components/Panel/Input.tsx
698
+ import React17 from "react";
699
+ import { Input as UiInput } from "@dxos/react-ui";
700
+ var Input = ({ validationMessage, label, ...props }) => {
701
+ return /* @__PURE__ */ React17.createElement(UiInput.Root, null, /* @__PURE__ */ React17.createElement(UiInput.Label, null, label), /* @__PURE__ */ React17.createElement(UiInput.TextInput, {
702
+ ...props,
703
+ classNames: "plb-3 mbs-2 text-center"
704
+ }), /* @__PURE__ */ React17.createElement(UiInput.DescriptionAndValidation, null, validationMessage && /* @__PURE__ */ React17.createElement(UiInput.Validation, null, validationMessage)));
705
+ };
706
+
707
+ // packages/sdk/shell/src/components/Panel/StepHeading.tsx
708
+ import React18, { forwardRef as forwardRef5 } from "react";
709
+ import { mx as mx15 } from "@dxos/react-ui-theme";
710
+ var StepHeading = /* @__PURE__ */ forwardRef5(({ children, className, ...props }, forwardedRef) => {
711
+ return /* @__PURE__ */ React18.createElement("h2", {
712
+ ...props,
713
+ className: mx15("font-normal text-sm mbe-4 mli-1 text-center", className),
714
+ ref: forwardedRef
715
+ }, children);
716
+ });
717
+
718
+ // packages/sdk/shell/src/components/Viewport/Viewport.tsx
719
+ import { useFocusFinders } from "@fluentui/react-tabster";
720
+ import { createContextScope } from "@radix-ui/react-context";
721
+ import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
722
+ import React19, { forwardRef as forwardRef6, useEffect } from "react";
723
+ import { useForwardedRef } from "@dxos/react-ui";
724
+ import { mx as mx16 } from "@dxos/react-ui-theme";
725
+ var VIEWPORT_NAME = "Viewport";
726
+ var VIEWS_NAME = "ViewportViews";
727
+ var VIEW_NAME = "ViewportView";
728
+ var [createViewportContext, createViewportScope] = createContextScope(VIEWPORT_NAME, []);
729
+ var [ViewportProvider, useViewportContext] = createViewportContext(VIEWPORT_NAME);
730
+ var ViewportRoot = ({ __viewportScope, classNames, children, defaultActiveView, activeView: propsActiveView, focusManaged = false, onActiveViewChange, ...props }) => {
731
+ const [activeView = "never", setActiveView] = useControllableState2({
732
+ prop: propsActiveView,
733
+ defaultProp: defaultActiveView,
734
+ onChange: onActiveViewChange
735
+ });
736
+ return /* @__PURE__ */ React19.createElement(ViewportProvider, {
737
+ focusManaged,
738
+ activeView,
739
+ setActiveView,
740
+ scope: __viewportScope
741
+ }, /* @__PURE__ */ React19.createElement("div", {
742
+ role: "region",
743
+ "aria-live": "polite",
744
+ ...props,
745
+ className: mx16("is-full overflow-hidden", classNames)
746
+ }, children));
747
+ };
748
+ ViewportRoot.displayName = VIEWPORT_NAME;
749
+ var ViewportViews = ({ classNames, children, ...props }) => {
750
+ const size = {
751
+ inlineSize: `${Math.ceil(children.length) * 100}%`
752
+ };
753
+ return /* @__PURE__ */ React19.createElement("div", {
754
+ role: "none",
755
+ style: size,
756
+ ...props,
757
+ className: mx16("flex", classNames)
758
+ }, children);
759
+ };
760
+ ViewportViews.displayName = VIEWS_NAME;
761
+ var ViewportView = /* @__PURE__ */ forwardRef6(({ __viewportScope, classNames, children, id, ...props }, forwardedRef) => {
762
+ const { activeView, focusManaged } = useViewportContext(VIEW_NAME, __viewportScope);
763
+ const isActive = id === activeView;
764
+ const ref = useForwardedRef(forwardedRef);
765
+ const { findFirstFocusable } = useFocusFinders();
766
+ useEffect(() => {
767
+ if (!focusManaged && isActive && document.body.hasAttribute("data-is-keyboard") && ref.current) {
768
+ findFirstFocusable(ref.current)?.focus();
769
+ }
770
+ }, [
771
+ focusManaged,
772
+ ref.current,
773
+ isActive
774
+ ]);
775
+ return /* @__PURE__ */ React19.createElement("section", {
776
+ ...props,
777
+ ...!isActive && {
778
+ "aria-hidden": true
779
+ },
780
+ className: mx16("min-is-0 flex-1 flex flex-col", isActive ? "order-2" : "order-4 invisible", classNames),
781
+ ref
782
+ }, children);
783
+ });
784
+ ViewportView.displayName = VIEW_NAME;
785
+ var Viewport = {
786
+ Root: ViewportRoot,
787
+ Views: ViewportViews,
788
+ View: ViewportView
789
+ };
790
+
791
+ // packages/sdk/shell/src/components/SpaceListItem.tsx
792
+ import React20, { forwardRef as forwardRef7 } from "react";
793
+ import { Avatar as Avatar3, useId as useId3, useJdenticonHref as useJdenticonHref2 } from "@dxos/react-ui";
794
+ import { mx as mx17 } from "@dxos/react-ui-theme";
795
+ import { humanize } from "@dxos/util";
796
+ var SpaceListItem = /* @__PURE__ */ forwardRef7(({ space, onClick }, ref) => {
797
+ const fallbackValue = space.key.toHex();
798
+ const labelId = useId3("identityListItem__label");
799
+ const jdenticon = useJdenticonHref2(fallbackValue ?? "", 12);
800
+ const displayName = space.properties.name ?? humanize(space.key.toHex());
801
+ return /* @__PURE__ */ React20.createElement("li", {
802
+ className: mx17("flex gap-2 items-center mbe-2", onClick && "cursor-pointer"),
803
+ onClick: () => onClick?.(),
804
+ ref,
805
+ "data-testid": "space-list-item"
806
+ }, /* @__PURE__ */ React20.createElement(Avatar3.Root, {
807
+ labelId
808
+ }, /* @__PURE__ */ React20.createElement(Avatar3.Frame, null, /* @__PURE__ */ React20.createElement(Avatar3.Fallback, {
809
+ href: jdenticon
810
+ })), /* @__PURE__ */ React20.createElement(Avatar3.Label, {
811
+ classNames: "text-sm truncate"
812
+ }, displayName)));
813
+ });
814
+
815
+ // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
816
+ import React37 from "react";
817
+ import { Dialog, useId as useId9 } from "@dxos/react-ui";
818
+
819
+ // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
820
+ import React24, { useEffect as useEffect2, useMemo as useMemo3 } from "react";
821
+ import { generateName as generateName2 } from "@dxos/display-name";
822
+ import { log as log3 } from "@dxos/log";
823
+ import { useClient as useClient3 } from "@dxos/react-client";
824
+ import { useIdentity } from "@dxos/react-client/halo";
825
+ import { useInvitationStatus as useInvitationStatus2 } from "@dxos/react-client/invitations";
826
+ import { Avatar as Avatar4, DensityProvider as DensityProvider2, useId as useId5, useJdenticonHref as useJdenticonHref3, useTranslation as useTranslation10 } from "@dxos/react-ui";
827
+
828
+ // packages/sdk/shell/src/panels/IdentityPanel/identityMachine.ts
829
+ import { useMachine } from "@xstate/react";
830
+ import { assign, createMachine } from "xstate";
831
+ import { log } from "@dxos/log";
832
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/identityMachine.ts";
833
+ var identityMachine = createMachine({
834
+ id: "identity",
835
+ predictableActionArguments: true,
836
+ context: {
837
+ identity: null,
838
+ identitySubscribable: null
839
+ },
840
+ initial: "choosingAction",
841
+ invoke: {
842
+ src: (context) => context.identitySubscribable
843
+ },
844
+ states: {
845
+ choosingAction: {},
846
+ managingDeviceInvitation: {},
847
+ managingProfile: {
848
+ initial: "idle",
849
+ states: {
850
+ idle: {},
851
+ pending: {}
852
+ },
853
+ on: {
854
+ setIdentity: {
855
+ target: "choosingAction",
856
+ actions: [
857
+ "setIdentity",
858
+ "log"
859
+ ]
860
+ },
861
+ updateProfile: {
862
+ target: ".pending",
863
+ actions: "log"
864
+ }
865
+ }
866
+ }
867
+ },
868
+ on: {
869
+ unchooseAction: {
870
+ target: ".choosingAction",
871
+ actions: [
872
+ "unsetInvitation",
873
+ "log"
874
+ ]
875
+ },
876
+ chooseDevices: {
877
+ target: ".managingDeviceInvitation",
878
+ actions: [
879
+ "unsetInvitation",
880
+ "log"
881
+ ]
882
+ },
883
+ deselectInvitation: {
884
+ target: ".choosingAction",
885
+ actions: [
886
+ "unsetInvitation",
887
+ "log"
888
+ ]
889
+ },
890
+ selectInvitation: {
891
+ target: ".managingDeviceInvitation",
892
+ actions: [
893
+ "setInvitation",
894
+ "log"
895
+ ]
896
+ },
897
+ chooseProfile: {
898
+ target: ".managingProfile",
899
+ actions: "log"
900
+ }
901
+ }
902
+ }, {
903
+ actions: {
904
+ setIdentity: assign({
905
+ identity: (context, event) => event?.identity ?? null
906
+ }),
907
+ setInvitation: assign({
908
+ invitation: (context, event) => event?.invitation ?? null
909
+ }),
910
+ unsetInvitation: assign({
911
+ invitation: () => void 0
912
+ }),
913
+ log: (context, event) => {
914
+ log("[transition]", {
915
+ event,
916
+ context
917
+ }, {
918
+ F: __dxlog_file,
919
+ L: 95,
920
+ S: void 0,
921
+ C: (f, a) => f(...a)
922
+ });
923
+ }
924
+ }
925
+ });
926
+ var useIdentityMachine = (client, options) => {
927
+ return useMachine(identityMachine, {
928
+ ...options,
929
+ context: {
930
+ ...options?.context,
931
+ identity: client.halo.identity.get(),
932
+ identitySubscribable: client.halo.identity.map((identity) => ({
933
+ type: "setIdentity",
934
+ identity
935
+ }))
936
+ }
937
+ });
938
+ };
939
+
940
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx
941
+ import { CaretRight, Plus, Power, UserGear } from "@phosphor-icons/react";
942
+ import React21, { useCallback as useCallback4 } from "react";
943
+ import { useClient as useClient2 } from "@dxos/react-client";
944
+ import { useHaloInvitations } from "@dxos/react-client/halo";
945
+ import { Invitation as Invitation3, InvitationEncoder } from "@dxos/react-client/invitations";
946
+ import { DensityProvider, useTranslation as useTranslation7 } from "@dxos/react-ui";
947
+ import { getSize as getSize6 } from "@dxos/react-ui-theme";
948
+ var IdentityActionChooser = (props) => {
949
+ const { send } = props;
950
+ const client = useClient2();
951
+ const invitations = useHaloInvitations();
952
+ const onInvitationEvent = useCallback4((invitation) => {
953
+ const invitationCode = InvitationEncoder.encode(invitation);
954
+ if (invitation.state === Invitation3.State.CONNECTING) {
955
+ console.log(JSON.stringify({
956
+ invitationCode,
957
+ authCode: invitation.authCode
958
+ }));
959
+ }
960
+ }, []);
961
+ const createInvitation = (e) => {
962
+ const testing = e.altKey && e.shiftKey;
963
+ invitations.forEach((invitation2) => invitation2.cancel());
964
+ const invitation = client.halo.share(testing ? {
965
+ type: Invitation3.Type.MULTIUSE,
966
+ authMethod: Invitation3.AuthMethod.NONE
967
+ } : void 0);
968
+ if (true) {
969
+ invitation.subscribe(onInvitationEvent);
970
+ }
971
+ send?.({
972
+ type: "selectInvitation",
973
+ invitation
974
+ });
975
+ };
976
+ return /* @__PURE__ */ React21.createElement(IdentityActionChooserImpl, {
977
+ ...props,
978
+ onCreateInvitationClick: (e) => createInvitation(e)
979
+ });
980
+ };
981
+ var IdentityActionChooserImpl = ({ onCreateInvitationClick, active, send, onDone, doneActionParent }) => {
982
+ const { t } = useTranslation7("os");
983
+ return /* @__PURE__ */ React21.createElement("div", {
984
+ role: "none",
985
+ className: "grow flex flex-col gap-1"
986
+ }, /* @__PURE__ */ React21.createElement(DensityProvider, {
987
+ density: "coarse"
988
+ }, /* @__PURE__ */ React21.createElement("div", {
989
+ className: "grow justify-center flex flex-col gap-1"
990
+ }, /* @__PURE__ */ React21.createElement(Action, {
991
+ disabled: !active,
992
+ "data-testid": "devices-panel.create-invitation",
993
+ onClick: onCreateInvitationClick,
994
+ classNames: "plb-4"
995
+ }, /* @__PURE__ */ React21.createElement(Plus, {
996
+ className: getSize6(6)
997
+ }), /* @__PURE__ */ React21.createElement("span", {
998
+ className: "grow mli-3"
999
+ }, t("choose devices label")), /* @__PURE__ */ React21.createElement(CaretRight, {
1000
+ weight: "bold",
1001
+ className: getSize6(4)
1002
+ })), /* @__PURE__ */ React21.createElement(Action, {
1003
+ "data-testid": "manage-profile",
1004
+ onClick: () => send?.({
1005
+ type: "chooseProfile"
1006
+ }),
1007
+ classNames: "plb-4"
1008
+ }, /* @__PURE__ */ React21.createElement(UserGear, {
1009
+ className: getSize6(6)
1010
+ }), /* @__PURE__ */ React21.createElement("span", {
1011
+ className: "grow mli-3"
1012
+ }, t("choose profile label")), /* @__PURE__ */ React21.createElement(CaretRight, {
1013
+ weight: "bold",
1014
+ className: getSize6(4)
1015
+ })), /* @__PURE__ */ React21.createElement(Action, {
1016
+ disabled: true,
1017
+ "data-testid": "sign-out",
1018
+ onClick: () => {
1019
+ },
1020
+ classNames: "plb-4"
1021
+ }, /* @__PURE__ */ React21.createElement(Power, {
1022
+ className: getSize6(6)
1023
+ }), /* @__PURE__ */ React21.createElement("span", {
1024
+ className: "grow mli-3"
1025
+ }, t("choose sign out label")), /* @__PURE__ */ React21.createElement(CaretRight, {
1026
+ weight: "bold",
1027
+ className: getSize6(4)
1028
+ })))));
1029
+ };
1030
+
1031
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx
1032
+ import React22, { useState as useState3 } from "react";
1033
+ import { log as log2 } from "@dxos/log";
1034
+ import { useTranslation as useTranslation8 } from "@dxos/react-ui";
1035
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx";
1036
+ var ProfileForm = (props) => {
1037
+ const { onUpdateProfile } = props;
1038
+ const { t } = useTranslation8("os");
1039
+ const [validationMessage, setValidationMessage] = useState3("");
1040
+ const handleUpdateProfile = async (profile) => {
1041
+ await onUpdateProfile?.(profile).catch((error) => {
1042
+ log2.catch(error, void 0, {
1043
+ F: __dxlog_file2,
1044
+ L: 32,
1045
+ S: void 0,
1046
+ C: (f, a) => f(...a)
1047
+ });
1048
+ setValidationMessage(t("failed to update profile message"));
1049
+ });
1050
+ };
1051
+ return /* @__PURE__ */ React22.createElement(ProfileFormImpl, {
1052
+ ...props,
1053
+ onUpdateProfile: handleUpdateProfile,
1054
+ validationMessage
1055
+ });
1056
+ };
1057
+ var ProfileFormImpl = (props) => {
1058
+ const { active, profile, send, onUpdateProfile, validationMessage } = props;
1059
+ const disabled = !active;
1060
+ const { t } = useTranslation8("os");
1061
+ const [inputValue, setInputValue] = useState3(profile?.displayName ?? "");
1062
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", {
1063
+ role: "none",
1064
+ className: "grow flex flex-col justify-center"
1065
+ }, /* @__PURE__ */ React22.createElement(Input, {
1066
+ validationMessage,
1067
+ label: /* @__PURE__ */ React22.createElement(StepHeading, null, t("display name input label")),
1068
+ disabled,
1069
+ "data-testid": "display-name-input",
1070
+ placeholder: t("display name input placeholder"),
1071
+ value: inputValue,
1072
+ onChange: ({ target: { value } }) => setInputValue(value),
1073
+ onKeyDown: ({ key }) => key === "Enter" && onUpdateProfile?.({
1074
+ displayName: inputValue
1075
+ })
1076
+ })), /* @__PURE__ */ React22.createElement(Actions, null, /* @__PURE__ */ React22.createElement(Action, {
1077
+ variant: "ghost",
1078
+ disabled,
1079
+ onClick: () => send?.({
1080
+ type: "unchooseAction"
1081
+ }),
1082
+ "data-testid": "update-profile-form-back"
1083
+ }, t("back label")), /* @__PURE__ */ React22.createElement(Action, {
1084
+ variant: "primary",
1085
+ disabled,
1086
+ onClick: () => onUpdateProfile?.({
1087
+ displayName: inputValue
1088
+ }),
1089
+ "data-testid": "update-profile-form-continue"
1090
+ }, t("done label"))));
1091
+ };
1092
+
1093
+ // packages/sdk/shell/src/steps/InvitationManager.tsx
1094
+ import { Check as Check3, X as X3 } from "@phosphor-icons/react";
1095
+ import React23, { useMemo as useMemo2 } from "react";
1096
+ import { QR } from "react-qr-rounded";
1097
+ import { Invitation as Invitation4 } from "@dxos/react-client/invitations";
1098
+ import { useId as useId4, useTranslation as useTranslation9 } from "@dxos/react-ui";
1099
+ import { descriptionText as descriptionText7, getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1100
+ var InvitationManagerView = ({ children, ...props }) => {
1101
+ return /* @__PURE__ */ React23.createElement(Viewport.View, {
1102
+ ...props,
1103
+ classNames: "grow flex flex-col justify-around items-center"
1104
+ }, children);
1105
+ };
1106
+ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id }) => {
1107
+ const { t } = useTranslation9("os");
1108
+ const qrLabel = useId4("invitation-manager__qr-code");
1109
+ const statusValue = type === Invitation4.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1110
+ const showAuthCode = statusValue === 3;
1111
+ const emoji2 = toEmoji(id ?? "");
1112
+ const activeView = useMemo2(() => {
1113
+ switch (true) {
1114
+ case statusValue === 5:
1115
+ case statusValue < 0:
1116
+ return "showing final";
1117
+ case statusValue === 3:
1118
+ return "showing auth code";
1119
+ default:
1120
+ return "showing qr";
1121
+ }
1122
+ }, [
1123
+ statusValue
1124
+ ]);
1125
+ return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(Viewport.Root, {
1126
+ activeView,
1127
+ classNames: "grow plb-1"
1128
+ }, /* @__PURE__ */ React23.createElement(Viewport.Views, null, /* @__PURE__ */ React23.createElement(InvitationManagerView, {
1129
+ id: "showing qr",
1130
+ emoji: emoji2
1131
+ }, /* @__PURE__ */ React23.createElement("p", {
1132
+ className: "text-sm mlb-1 font-normal text-center"
1133
+ }, t(type === Invitation4.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React23.createElement("div", {
1134
+ role: "none",
1135
+ className: mx18(descriptionText7, "is-full max-is-[14rem] relative")
1136
+ }, /* @__PURE__ */ React23.createElement(QR, {
1137
+ rounding: 100,
1138
+ backgroundColor: "transparent",
1139
+ color: "currentColor",
1140
+ className: mx18("is-full bs-full p-2", showAuthCode && "invisible"),
1141
+ "aria-labelledby": qrLabel,
1142
+ errorCorrectionLevel: "Q",
1143
+ cutout: true
1144
+ }, invitationUrl ?? "never"), /* @__PURE__ */ React23.createElement(Centered, null, /* @__PURE__ */ React23.createElement(Emoji, {
1145
+ text: emoji2
1146
+ }))), /* @__PURE__ */ React23.createElement("span", {
1147
+ id: qrLabel,
1148
+ className: "sr-only"
1149
+ }, t("qr label")), /* @__PURE__ */ React23.createElement(CopyButton, {
1150
+ variant: "ghost",
1151
+ value: invitationUrl ?? "never"
1152
+ })), /* @__PURE__ */ React23.createElement(InvitationManagerView, {
1153
+ id: "showing auth code"
1154
+ }, /* @__PURE__ */ React23.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React23.createElement(AuthCode, {
1155
+ code: authCode,
1156
+ large: true,
1157
+ classNames: "text-black dark:text-white"
1158
+ }), /* @__PURE__ */ React23.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React23.createElement(Emoji, {
1159
+ text: emoji2
1160
+ })), /* @__PURE__ */ React23.createElement(InvitationManagerView, {
1161
+ id: "showing final"
1162
+ }, statusValue > 0 ? /* @__PURE__ */ React23.createElement(Check3, {
1163
+ className: mx18("m-1.5", getSize7(6))
1164
+ }) : /* @__PURE__ */ React23.createElement(X3, {
1165
+ className: mx18("m-1.5", getSize7(6))
1166
+ })))), /* @__PURE__ */ React23.createElement(Actions, {
1167
+ classNames: "mbs-4"
1168
+ }, /* @__PURE__ */ React23.createElement(Action, {
1169
+ disabled: !active,
1170
+ onClick: () => send?.({
1171
+ type: "deselectInvitation"
1172
+ })
1173
+ }, t("back label"))));
1174
+ };
1175
+
1176
+ // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
1177
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1178
+ var viewStyles = "pbs-1 pbe-3 pli-3";
1179
+ var IdentityHeading = ({ titleId, title, identity, onDone }) => {
1180
+ const fallbackHref = useJdenticonHref3(identity.identityKey.toHex(), 12);
1181
+ return /* @__PURE__ */ React24.createElement(Heading, {
1182
+ titleId,
1183
+ title,
1184
+ corner: /* @__PURE__ */ React24.createElement(CloseButton, {
1185
+ onDone
1186
+ })
1187
+ }, /* @__PURE__ */ React24.createElement(Avatar4.Root, {
1188
+ size: 12,
1189
+ variant: "circle",
1190
+ status: "active"
1191
+ }, /* @__PURE__ */ React24.createElement(Avatar4.Frame, {
1192
+ classNames: "block mbs-4 mbe-2 mli-auto chromatic-ignore"
1193
+ }, /* @__PURE__ */ React24.createElement(Avatar4.Fallback, {
1194
+ href: fallbackHref
1195
+ })), /* @__PURE__ */ React24.createElement(Avatar4.Label, {
1196
+ classNames: "block text-center font-light text-xl"
1197
+ }, identity.profile?.displayName ?? generateName2(identity.identityKey.toHex()))));
1198
+ };
1199
+ var IdentityPanelImpl = (props) => {
1200
+ const { identity, titleId, activeView, onUpdateProfile, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1201
+ const { t } = useTranslation10("os");
1202
+ const title = useMemo3(() => {
1203
+ switch (activeView) {
1204
+ case "device manager":
1205
+ case "device invitation manager":
1206
+ return t("choose devices label");
1207
+ default:
1208
+ return t("identity heading");
1209
+ }
1210
+ }, [
1211
+ activeView,
1212
+ t
1213
+ ]);
1214
+ return /* @__PURE__ */ React24.createElement(DensityProvider2, {
1215
+ density: "fine"
1216
+ }, /* @__PURE__ */ React24.createElement(IdentityHeading, {
1217
+ identity,
1218
+ titleId,
1219
+ title,
1220
+ onDone
1221
+ }), /* @__PURE__ */ React24.createElement(Viewport.Root, {
1222
+ activeView
1223
+ }, /* @__PURE__ */ React24.createElement(Viewport.Views, null, /* @__PURE__ */ React24.createElement(Viewport.View, {
1224
+ id: "identity action chooser",
1225
+ classNames: viewStyles
1226
+ }, /* @__PURE__ */ React24.createElement(IdentityActionChooserComponent, {
1227
+ active: activeView === "identity action chooser",
1228
+ ...rest
1229
+ })), /* @__PURE__ */ React24.createElement(Viewport.View, {
1230
+ id: "device invitation manager",
1231
+ classNames: viewStyles
1232
+ }, /* @__PURE__ */ React24.createElement(InvitationManagerComponent, {
1233
+ active: activeView === "device invitation manager",
1234
+ ...rest,
1235
+ invitationUrl: rest.createInvitationUrl(rest.invitationCode)
1236
+ })), /* @__PURE__ */ React24.createElement(Viewport.View, {
1237
+ classNames: viewStyles,
1238
+ id: "update profile form"
1239
+ }, /* @__PURE__ */ React24.createElement(ProfileForm, {
1240
+ send: rest.send,
1241
+ active: activeView === "update profile form",
1242
+ profile: identity.profile,
1243
+ onUpdateProfile
1244
+ })))));
1245
+ };
1246
+ var IdentityPanelWithInvitationImpl = ({ invitation, ...props }) => {
1247
+ const invitationStatus = useInvitationStatus2(invitation);
1248
+ return /* @__PURE__ */ React24.createElement(IdentityPanelImpl, {
1249
+ ...props,
1250
+ ...invitationStatus
1251
+ });
1252
+ };
1253
+ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code, ...props }) => {
1254
+ const titleId = useId5("identityPanel__heading", propsTitleId);
1255
+ const client = useClient3();
1256
+ const identity = useIdentity();
1257
+ if (!identity) {
1258
+ console.error("IdentityPanel rendered with no active identity.");
1259
+ return null;
1260
+ }
1261
+ const [identityState, identitySend, identityService] = useIdentityMachine(client);
1262
+ useEffect2(() => {
1263
+ const subscription = identityService.subscribe((state) => {
1264
+ log3("[state]", state, {
1265
+ F: __dxlog_file3,
1266
+ L: 117,
1267
+ S: void 0,
1268
+ C: (f, a) => f(...a)
1269
+ });
1270
+ });
1271
+ return subscription.unsubscribe;
1272
+ }, [
1273
+ identityService
1274
+ ]);
1275
+ const activeView = useMemo3(() => {
1276
+ switch (true) {
1277
+ case identityState.matches("choosingAction"):
1278
+ return "identity action chooser";
1279
+ case identityState.matches("managingDeviceInvitation"):
1280
+ return "device invitation manager";
1281
+ case [
1282
+ {
1283
+ managingProfile: "idle"
1284
+ },
1285
+ {
1286
+ managingProfile: "pending"
1287
+ }
1288
+ ].some(identityState.matches):
1289
+ return "update profile form";
1290
+ default:
1291
+ return "identity action chooser";
1292
+ }
1293
+ }, [
1294
+ identityState
1295
+ ]);
1296
+ const onUpdateProfile = async (profile) => {
1297
+ identitySend({
1298
+ type: "updateProfile"
1299
+ });
1300
+ await client.halo.updateProfile(profile);
1301
+ };
1302
+ const implProps = {
1303
+ ...props,
1304
+ identity,
1305
+ activeView,
1306
+ send: identitySend,
1307
+ titleId,
1308
+ createInvitationUrl,
1309
+ onUpdateProfile
1310
+ };
1311
+ return identityState.context.invitation ? /* @__PURE__ */ React24.createElement(IdentityPanelWithInvitationImpl, {
1312
+ ...implProps,
1313
+ invitation: identityState.context.invitation
1314
+ }) : /* @__PURE__ */ React24.createElement(IdentityPanelImpl, implProps);
1315
+ };
1316
+
1317
+ // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
1318
+ import React34, { useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo4 } from "react";
1319
+ import { log as log8 } from "@dxos/log";
1320
+ import { useClient as useClient6, useMulticastObservable } from "@dxos/react-client";
1321
+ import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
1322
+ import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext as useThemeContext3 } from "@dxos/react-ui";
1323
+
1324
+ // packages/sdk/shell/src/panels/JoinPanel/JoinHeading.tsx
1325
+ import { X as X4 } from "@phosphor-icons/react";
1326
+ import React25, { cloneElement, forwardRef as forwardRef8 } from "react";
1327
+ import { Button as Button5, useTranslation as useTranslation11 } from "@dxos/react-ui";
1328
+ import { descriptionText as descriptionText8, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1329
+ var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActionParent }, forwardedRef) => {
1330
+ const { t } = useTranslation11("os");
1331
+ const exitButton = /* @__PURE__ */ React25.createElement(Button5, {
1332
+ variant: "ghost",
1333
+ ...onExit && {
1334
+ onClick: onExit
1335
+ },
1336
+ classNames: mx19(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1337
+ "data-testid": "join-exit"
1338
+ }, /* @__PURE__ */ React25.createElement(X4, {
1339
+ weight: "bold",
1340
+ className: getSize8(4)
1341
+ }), /* @__PURE__ */ React25.createElement("span", {
1342
+ className: "sr-only"
1343
+ }, t("exit label")));
1344
+ return /* @__PURE__ */ React25.createElement(Heading, {
1345
+ ref: forwardedRef,
1346
+ titleId,
1347
+ title: t(mode === "halo-only" ? "selecting identity heading" : "joining space heading"),
1348
+ ...mode === "halo-only" ? {
1349
+ titleSrOnly: true
1350
+ } : {
1351
+ corner: exitActionParent ? /* @__PURE__ */ cloneElement(exitActionParent, {}, exitButton) : exitButton
1352
+ },
1353
+ titleSrOnly: mode === "halo-only"
1354
+ });
1355
+ });
1356
+
1357
+ // packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts
1358
+ import { useMachine as useMachine2 } from "@xstate/react";
1359
+ import { useCallback as useCallback5 } from "react";
1360
+ import { assign as assign2, createMachine as createMachine2 } from "xstate";
1361
+ import { log as log4 } from "@dxos/log";
1362
+ import { Invitation as Invitation5, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1363
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts";
1364
+ var getInvitationSubscribable = (Kind, invitation) => {
1365
+ log4("[subscribing to invitation]", invitation, {
1366
+ F: __dxlog_file4,
1367
+ L: 88,
1368
+ S: void 0,
1369
+ C: (f, a) => f(...a)
1370
+ });
1371
+ return {
1372
+ subscribe: (next, onError, complete) => invitation.subscribe((invitation2) => {
1373
+ switch (invitation2.state) {
1374
+ case Invitation5.State.CONNECTING: {
1375
+ log4("[invitation connecting]", {
1376
+ Kind,
1377
+ invitation: invitation2
1378
+ }, {
1379
+ F: __dxlog_file4,
1380
+ L: 99,
1381
+ S: void 0,
1382
+ C: (f, a) => f(...a)
1383
+ });
1384
+ return next({
1385
+ type: `connecting${Kind}Invitation`,
1386
+ invitation: invitation2
1387
+ });
1388
+ }
1389
+ case Invitation5.State.CONNECTED: {
1390
+ log4("[invitation connected]", {
1391
+ Kind,
1392
+ invitation: invitation2
1393
+ }, {
1394
+ F: __dxlog_file4,
1395
+ L: 104,
1396
+ S: void 0,
1397
+ C: (f, a) => f(...a)
1398
+ });
1399
+ return next({
1400
+ type: `connected${Kind}Invitation`,
1401
+ invitation: invitation2
1402
+ });
1403
+ }
1404
+ case Invitation5.State.READY_FOR_AUTHENTICATION: {
1405
+ log4("[invitation ready for authentication]", {
1406
+ Kind,
1407
+ invitation: invitation2
1408
+ }, {
1409
+ F: __dxlog_file4,
1410
+ L: 109,
1411
+ S: void 0,
1412
+ C: (f, a) => f(...a)
1413
+ });
1414
+ return next({
1415
+ type: `readyForAuthentication${Kind}Invitation`,
1416
+ invitation: invitation2
1417
+ });
1418
+ }
1419
+ case Invitation5.State.AUTHENTICATING: {
1420
+ log4("[invitation authenticating]", {
1421
+ Kind,
1422
+ invitation: invitation2
1423
+ }, {
1424
+ F: __dxlog_file4,
1425
+ L: 114,
1426
+ S: void 0,
1427
+ C: (f, a) => f(...a)
1428
+ });
1429
+ return next({
1430
+ type: `authenticating${Kind}Invitation`,
1431
+ invitation: invitation2
1432
+ });
1433
+ }
1434
+ case Invitation5.State.SUCCESS: {
1435
+ log4("[invitation success]", {
1436
+ Kind,
1437
+ invitation: invitation2
1438
+ }, {
1439
+ F: __dxlog_file4,
1440
+ L: 119,
1441
+ S: void 0,
1442
+ C: (f, a) => f(...a)
1443
+ });
1444
+ next({
1445
+ type: `success${Kind}Invitation`,
1446
+ invitation: invitation2
1447
+ });
1448
+ return complete?.();
1449
+ }
1450
+ case Invitation5.State.CANCELLED: {
1451
+ log4.warn("[invitation cancelled]", {
1452
+ Kind
1453
+ }, {
1454
+ F: __dxlog_file4,
1455
+ L: 125,
1456
+ S: void 0,
1457
+ C: (f, a) => f(...a)
1458
+ });
1459
+ return next({
1460
+ type: `fail${Kind}Invitation`,
1461
+ reason: "cancelled"
1462
+ });
1463
+ }
1464
+ case Invitation5.State.TIMEOUT: {
1465
+ log4.error("[invitation timeout]", {
1466
+ Kind
1467
+ }, {
1468
+ F: __dxlog_file4,
1469
+ L: 130,
1470
+ S: void 0,
1471
+ C: (f, a) => f(...a)
1472
+ });
1473
+ return next({
1474
+ type: `fail${Kind}Invitation`,
1475
+ reason: "timeout"
1476
+ });
1477
+ }
1478
+ }
1479
+ }, (error) => {
1480
+ log4.error("[invitation errored]", {
1481
+ Kind,
1482
+ error
1483
+ }, {
1484
+ F: __dxlog_file4,
1485
+ L: 136,
1486
+ S: void 0,
1487
+ C: (f, a) => f(...a)
1488
+ });
1489
+ next({
1490
+ type: `fail${Kind}Invitation`,
1491
+ reason: "error"
1492
+ });
1493
+ return onError?.(error);
1494
+ })
1495
+ };
1496
+ };
1497
+ var acceptingInvitationTemplate = (Kind, successTarget) => {
1498
+ const config = {
1499
+ initial: `unknown${Kind}`,
1500
+ states: {
1501
+ [`unknown${Kind}`]: {
1502
+ always: [
1503
+ {
1504
+ cond: ({ mode }) => mode === "halo-only" && Kind === "Space",
1505
+ target: "#join.finishingJoiningHalo"
1506
+ },
1507
+ {
1508
+ cond: (context) => !!context[Kind.toLowerCase()].unredeemedCode,
1509
+ target: `acceptingRedeemed${Kind}Invitation`,
1510
+ actions: [
1511
+ `redeem${Kind}InvitationCode`,
1512
+ `invalidate${Kind}InvitationCode`,
1513
+ "log"
1514
+ ]
1515
+ },
1516
+ {
1517
+ target: `inputting${Kind}InvitationCode`,
1518
+ actions: "log"
1519
+ }
1520
+ ]
1521
+ },
1522
+ [`inputting${Kind}InvitationCode`]: {},
1523
+ [`acceptingRedeemed${Kind}Invitation`]: {
1524
+ invoke: {
1525
+ src: (context) => context[Kind.toLowerCase()].invitationSubscribable
1526
+ },
1527
+ initial: `unknown${Kind}Invitation`,
1528
+ states: {
1529
+ [`unknown${Kind}Invitation`]: {
1530
+ always: [
1531
+ {
1532
+ cond: (context) => {
1533
+ if (Kind !== "Space") {
1534
+ return false;
1535
+ } else {
1536
+ const spaceKey = context.space.invitation?.spaceKey?.toHex();
1537
+ const succeededKeys = context.space.succeededKeys;
1538
+ return spaceKey ? !!succeededKeys?.has(spaceKey) : false;
1539
+ }
1540
+ },
1541
+ target: successTarget,
1542
+ actions: "log"
1543
+ },
1544
+ {
1545
+ cond: (context) => {
1546
+ const invitation = context[Kind.toLowerCase()].invitation;
1547
+ return !invitation || invitation?.state === Invitation5.State.CONNECTING;
1548
+ },
1549
+ target: `connecting${Kind}Invitation`,
1550
+ actions: "log"
1551
+ },
1552
+ {
1553
+ target: `inputting${Kind}VerificationCode`,
1554
+ actions: "log"
1555
+ }
1556
+ ]
1557
+ },
1558
+ [`connecting${Kind}Invitation`]: {},
1559
+ [`inputting${Kind}VerificationCode`]: {},
1560
+ [`authenticating${Kind}VerificationCode`]: {
1561
+ on: {
1562
+ [`readyForAuthentication${Kind}Invitation`]: {
1563
+ target: `authenticationFailing${Kind}VerificationCode`,
1564
+ actions: [
1565
+ "setInvitation",
1566
+ "log"
1567
+ ]
1568
+ }
1569
+ }
1570
+ },
1571
+ [`authenticationFailing${Kind}VerificationCode`]: {},
1572
+ [`failing${Kind}Invitation`]: {},
1573
+ [`success${Kind}Invitation`]: {}
1574
+ },
1575
+ on: {
1576
+ [`reset${Kind}Invitation`]: {
1577
+ target: `#join${Kind === "Halo" ? ".choosingIdentity" : ""}.accepting${Kind}Invitation.unknown${Kind}`,
1578
+ actions: [
1579
+ "resetInvitation",
1580
+ "log"
1581
+ ]
1582
+ },
1583
+ [`connecting${Kind}Invitation`]: {
1584
+ target: `.connecting${Kind}Invitation`,
1585
+ actions: [
1586
+ "setInvitation",
1587
+ "log"
1588
+ ]
1589
+ },
1590
+ [`connected${Kind}Invitation`]: {
1591
+ target: `.connecting${Kind}Invitation`,
1592
+ actions: [
1593
+ "setInvitation",
1594
+ "log"
1595
+ ]
1596
+ },
1597
+ [`readyForAuthentication${Kind}Invitation`]: {
1598
+ target: `.inputting${Kind}VerificationCode`,
1599
+ actions: [
1600
+ "setInvitation",
1601
+ "log"
1602
+ ]
1603
+ },
1604
+ [`authenticating${Kind}Invitation`]: {
1605
+ target: `.authenticating${Kind}VerificationCode`,
1606
+ actions: [
1607
+ "setInvitation",
1608
+ "log"
1609
+ ]
1610
+ },
1611
+ [`success${Kind}Invitation`]: {
1612
+ target: successTarget,
1613
+ actions: [
1614
+ "setInvitation",
1615
+ "log"
1616
+ ]
1617
+ },
1618
+ [`fail${Kind}Invitation`]: {
1619
+ target: `.failing${Kind}Invitation`,
1620
+ actions: [
1621
+ assign2({
1622
+ [Kind.toLowerCase()]: (context, event) => ({
1623
+ ...context[Kind.toLowerCase()],
1624
+ failReason: event.reason
1625
+ })
1626
+ }),
1627
+ "log"
1628
+ ]
1629
+ }
1630
+ }
1631
+ }
1632
+ },
1633
+ on: {
1634
+ [`set${Kind}InvitationCode`]: {
1635
+ target: `.acceptingRedeemed${Kind}Invitation`,
1636
+ actions: [
1637
+ assign2({
1638
+ [Kind.toLowerCase()]: (context, event) => ({
1639
+ ...context[Kind.toLowerCase()],
1640
+ unredeemedCode: event.code,
1641
+ succeededKeys: event.succeededKeys
1642
+ })
1643
+ }),
1644
+ `redeem${Kind}InvitationCode`,
1645
+ `invalidate${Kind}InvitationCode`,
1646
+ "log"
1647
+ ]
1648
+ }
1649
+ }
1650
+ };
1651
+ return config;
1652
+ };
1653
+ var joinMachine = createMachine2({
1654
+ id: "join",
1655
+ predictableActionArguments: true,
1656
+ context: {
1657
+ mode: "default",
1658
+ identity: null,
1659
+ halo: {},
1660
+ space: {}
1661
+ },
1662
+ initial: "unknown",
1663
+ states: {
1664
+ unknown: {
1665
+ always: [
1666
+ {
1667
+ cond: "existingIdentity",
1668
+ target: "resettingIdentity",
1669
+ actions: "log"
1670
+ },
1671
+ {
1672
+ cond: "noSelectedIdentity",
1673
+ target: "choosingIdentity",
1674
+ actions: "log"
1675
+ },
1676
+ {
1677
+ target: "acceptingSpaceInvitation",
1678
+ actions: "log"
1679
+ }
1680
+ ]
1681
+ },
1682
+ choosingIdentity: {
1683
+ initial: "unknownAuthMethod",
1684
+ states: {
1685
+ unknownAuthMethod: {
1686
+ always: [
1687
+ {
1688
+ cond: "hasHaloUnredeemedCode",
1689
+ target: "acceptingHaloInvitation",
1690
+ actions: "log"
1691
+ },
1692
+ {
1693
+ target: "choosingAuthMethod",
1694
+ actions: "log"
1695
+ }
1696
+ ]
1697
+ },
1698
+ choosingAuthMethod: {},
1699
+ recoveringIdentity: {},
1700
+ creatingIdentity: {},
1701
+ acceptingHaloInvitation: acceptingInvitationTemplate("Halo", "#join.acceptingSpaceInvitation"),
1702
+ confirmingAddedIdentity: {}
1703
+ },
1704
+ on: {
1705
+ recoverIdentity: {
1706
+ target: ".recoveringIdentity",
1707
+ actions: "log"
1708
+ },
1709
+ createIdentity: {
1710
+ target: ".creatingIdentity",
1711
+ actions: "log"
1712
+ },
1713
+ acceptHaloInvitation: {
1714
+ target: ".acceptingHaloInvitation",
1715
+ actions: "log"
1716
+ },
1717
+ addIdentity: {
1718
+ target: ".confirmingAddedIdentity",
1719
+ actions: "log"
1720
+ },
1721
+ selectIdentity: {
1722
+ target: "acceptingSpaceInvitation",
1723
+ actions: [
1724
+ "setIdentity",
1725
+ "log"
1726
+ ]
1727
+ },
1728
+ deselectAuthMethod: {
1729
+ target: ".choosingAuthMethod",
1730
+ actions: "log"
1731
+ }
1732
+ }
1733
+ },
1734
+ resettingIdentity: {},
1735
+ acceptingSpaceInvitation: acceptingInvitationTemplate("Space", "#join.finishingJoiningSpace"),
1736
+ finishingJoiningSpace: {
1737
+ type: "final"
1738
+ },
1739
+ finishingJoiningHalo: {
1740
+ type: "final"
1741
+ }
1742
+ },
1743
+ on: {
1744
+ resetIdentity: {
1745
+ target: "choosingIdentity",
1746
+ actions: "unsetIdentity"
1747
+ }
1748
+ }
1749
+ }, {
1750
+ guards: {
1751
+ existingIdentity: ({ identity, mode }, _event) => mode === "halo-only" && !!identity,
1752
+ noSelectedIdentity: ({ identity }, _event) => !identity,
1753
+ hasHaloUnredeemedCode: ({ halo }, _event) => !!halo.unredeemedCode,
1754
+ noSpaceInvitation: ({ space }, _event) => !space.invitation && !space.unredeemedCode
1755
+ },
1756
+ actions: {
1757
+ setIdentity: assign2({
1758
+ identity: (context, event) => event.identity
1759
+ }),
1760
+ unsetIdentity: assign2({
1761
+ identity: () => null
1762
+ }),
1763
+ resetInvitation: assign2({
1764
+ halo: (context, event) => {
1765
+ if (event.type !== "resetHaloInvitation") {
1766
+ return context.halo;
1767
+ }
1768
+ if (context.halo.invitationObservable) {
1769
+ void context.halo.invitationObservable.cancel();
1770
+ }
1771
+ return {
1772
+ ...context.halo,
1773
+ invitation: void 0,
1774
+ invitationObservable: void 0,
1775
+ invitationSubscribable: void 0
1776
+ };
1777
+ },
1778
+ space: (context, event) => {
1779
+ if (event.type !== "resetSpaceInvitation") {
1780
+ return context.space;
1781
+ }
1782
+ if (context.space.invitationObservable) {
1783
+ void context.space.invitationObservable.cancel();
1784
+ }
1785
+ return {
1786
+ ...context.space,
1787
+ invitation: void 0,
1788
+ invitationObservable: void 0,
1789
+ invitationSubscribable: void 0
1790
+ };
1791
+ }
1792
+ }),
1793
+ setInvitation: assign2({
1794
+ halo: (context, event) => event.type.includes("Halo") ? {
1795
+ ...context.halo,
1796
+ invitation: event.invitation
1797
+ } : context.halo,
1798
+ space: (context, event) => event.type.includes("Space") ? {
1799
+ ...context.space,
1800
+ invitation: event.invitation
1801
+ } : context.space
1802
+ }),
1803
+ log: (context, event) => {
1804
+ log4.info("[transition]", {
1805
+ event,
1806
+ haloInvitation: context.halo.invitation,
1807
+ spaceInvitation: context.space.invitation
1808
+ }, {
1809
+ F: __dxlog_file4,
1810
+ L: 400,
1811
+ S: void 0,
1812
+ C: (f, a) => f(...a)
1813
+ });
1814
+ }
1815
+ }
1816
+ });
1817
+ var defaultCodeFromUrl = (invitationType, text) => {
1818
+ try {
1819
+ const searchParams = new URLSearchParams(text.substring(text.lastIndexOf("?")));
1820
+ return searchParams.get(`${invitationType}InvitationCode`) ?? searchParams.get(`${invitationType}Invitation`) ?? searchParams.get("invitationCode") ?? searchParams.get("invitation") ?? text;
1821
+ } catch (err) {
1822
+ log4.catch(err, void 0, {
1823
+ F: __dxlog_file4,
1824
+ L: 427,
1825
+ S: void 0,
1826
+ C: (f, a) => f(...a)
1827
+ });
1828
+ return text;
1829
+ }
1830
+ };
1831
+ var useJoinMachine = (client, options) => {
1832
+ const redeemHaloInvitationCode = useCallback5(({ halo }) => {
1833
+ if (halo.unredeemedCode) {
1834
+ try {
1835
+ const invitationObservable = client.halo.join(InvitationEncoder2.decode(defaultCodeFromUrl("halo", halo.unredeemedCode)));
1836
+ return {
1837
+ ...halo,
1838
+ invitationObservable,
1839
+ invitationSubscribable: getInvitationSubscribable("Halo", invitationObservable)
1840
+ };
1841
+ } catch (err) {
1842
+ log4.error("Could not redeem device invitation code", err, {
1843
+ F: __dxlog_file4,
1844
+ L: 449,
1845
+ S: void 0,
1846
+ C: (f, a) => f(...a)
1847
+ });
1848
+ return halo;
1849
+ }
1850
+ } else {
1851
+ return halo;
1852
+ }
1853
+ }, [
1854
+ client
1855
+ ]);
1856
+ const redeemSpaceInvitationCode = useCallback5(({ space }) => {
1857
+ if (space.unredeemedCode) {
1858
+ try {
1859
+ const invitation = InvitationEncoder2.decode(defaultCodeFromUrl("space", space.unredeemedCode));
1860
+ if (space.succeededKeys?.has(invitation.spaceKey?.toHex() ?? "never")) {
1861
+ return {
1862
+ ...space,
1863
+ invitation
1864
+ };
1865
+ } else {
1866
+ const invitationObservable = client.spaces.join(invitation);
1867
+ return {
1868
+ ...space,
1869
+ invitationObservable,
1870
+ invitationSubscribable: getInvitationSubscribable("Space", invitationObservable)
1871
+ };
1872
+ }
1873
+ } catch (err) {
1874
+ log4.error("Could not redeem space invitation code", err, {
1875
+ F: __dxlog_file4,
1876
+ L: 479,
1877
+ S: void 0,
1878
+ C: (f, a) => f(...a)
1879
+ });
1880
+ return space;
1881
+ }
1882
+ } else {
1883
+ return space;
1884
+ }
1885
+ }, [
1886
+ client
1887
+ ]);
1888
+ const invalidateHaloInvitationCode = useCallback5(({ halo }) => {
1889
+ if (halo.unredeemedCode) {
1890
+ options?.onInvalidateInvitationCode?.(halo.unredeemedCode);
1891
+ return {
1892
+ ...halo,
1893
+ unredeemedCode: void 0
1894
+ };
1895
+ } else {
1896
+ return halo;
1897
+ }
1898
+ }, [
1899
+ options?.onInvalidateInvitationCode
1900
+ ]);
1901
+ const invalidateSpaceInvitationCode = useCallback5(({ space }) => {
1902
+ if (space.unredeemedCode) {
1903
+ options?.onInvalidateInvitationCode?.(space.unredeemedCode);
1904
+ return {
1905
+ ...space,
1906
+ unredeemedCode: void 0
1907
+ };
1908
+ } else {
1909
+ return space;
1910
+ }
1911
+ }, [
1912
+ options?.onInvalidateInvitationCode
1913
+ ]);
1914
+ return useMachine2(joinMachine, {
1915
+ ...options,
1916
+ actions: {
1917
+ ...options?.actions,
1918
+ redeemHaloInvitationCode: assign2({
1919
+ halo: redeemHaloInvitationCode
1920
+ }),
1921
+ redeemSpaceInvitationCode: assign2({
1922
+ space: redeemSpaceInvitationCode
1923
+ }),
1924
+ invalidateHaloInvitationCode: assign2({
1925
+ halo: invalidateHaloInvitationCode
1926
+ }),
1927
+ invalidateSpaceInvitationCode: assign2({
1928
+ space: invalidateSpaceInvitationCode
1929
+ })
1930
+ }
1931
+ });
1932
+ };
1933
+
1934
+ // packages/sdk/shell/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx
1935
+ import { CaretRight as CaretRight2, Plus as Plus2, QrCode, Textbox } from "@phosphor-icons/react";
1936
+ import React26 from "react";
1937
+ import { useTranslation as useTranslation12 } from "@dxos/react-ui";
1938
+ import { getSize as getSize9 } from "@dxos/react-ui-theme";
1939
+ var AdditionMethodChooser = (viewStateProps) => {
1940
+ const disabled = !viewStateProps.active;
1941
+ const { send } = viewStateProps;
1942
+ const { t } = useTranslation12("os");
1943
+ const sharedButtonProps = {
1944
+ disabled,
1945
+ after: /* @__PURE__ */ React26.createElement(CaretRight2, {
1946
+ className: getSize9(4),
1947
+ weight: "bold"
1948
+ }),
1949
+ slots: {
1950
+ label: {
1951
+ className: "text-sm"
1952
+ }
1953
+ }
1954
+ };
1955
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React26.createElement("div", {
1956
+ role: "none",
1957
+ className: "flex flex-col gap-1 grow"
1958
+ }, /* @__PURE__ */ React26.createElement(CompoundButton, {
1959
+ ...sharedButtonProps,
1960
+ description: t("create identity description"),
1961
+ before: /* @__PURE__ */ React26.createElement(Plus2, {
1962
+ className: getSize9(6)
1963
+ }),
1964
+ onClick: () => send({
1965
+ type: "createIdentity"
1966
+ }),
1967
+ "data-autofocus": "choosingAuthMethod",
1968
+ "data-testid": "create-identity"
1969
+ }, t("create identity label")), /* @__PURE__ */ React26.createElement(CompoundButton, {
1970
+ ...sharedButtonProps,
1971
+ description: t("join identity description"),
1972
+ before: /* @__PURE__ */ React26.createElement(QrCode, {
1973
+ className: getSize9(6)
1974
+ }),
1975
+ onClick: () => send({
1976
+ type: "acceptHaloInvitation"
1977
+ }),
1978
+ "data-testid": "join-identity"
1979
+ }, t("join identity label")), /* @__PURE__ */ React26.createElement(CompoundButton, {
1980
+ ...sharedButtonProps,
1981
+ // TODO(mykola): Implement recover.
1982
+ disabled: true,
1983
+ description: t("recover identity description"),
1984
+ before: /* @__PURE__ */ React26.createElement(Textbox, {
1985
+ className: getSize9(6)
1986
+ }),
1987
+ onClick: () => send({
1988
+ type: "recoverIdentity"
1989
+ }),
1990
+ "data-testid": "recover-identity"
1991
+ }, t("recover identity label"))));
1992
+ };
1993
+
1994
+ // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityAdded.tsx
1995
+ import React27, { cloneElement as cloneElement2 } from "react";
1996
+ import { generateName as generateName3 } from "@dxos/display-name";
1997
+ import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation13 } from "@dxos/react-ui";
1998
+ import { mx as mx20 } from "@dxos/react-ui-theme";
1999
+ var IdentityAdded = (props) => {
2000
+ const { mode, addedIdentity, active, send, onDone, doneActionParent } = props;
2001
+ const disabled = !active;
2002
+ const { t } = useTranslation13("os");
2003
+ const fallbackValue = addedIdentity?.identityKey.toHex();
2004
+ const labelId = useId6("identityListItem__label");
2005
+ const jdenticon = useJdenticonHref4(fallbackValue ?? "", 12);
2006
+ const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName3(addedIdentity?.identityKey.toHex()));
2007
+ const doneAction = /* @__PURE__ */ React27.createElement(Action, {
2008
+ ...onDone && {
2009
+ onClick: () => onDone(null)
2010
+ },
2011
+ disabled,
2012
+ "data-autofocus": "confirmingAddedIdentity",
2013
+ "data-testid": "identity-added-done"
2014
+ }, /* @__PURE__ */ React27.createElement("span", null, t("done label")));
2015
+ return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React27.createElement("div", {
2016
+ role: "none",
2017
+ className: "grow flex flex-col items-center justify-center text-center gap-2"
2018
+ }, /* @__PURE__ */ React27.createElement(Avatar5.Root, {
2019
+ status: "active",
2020
+ labelId
2021
+ }, /* @__PURE__ */ React27.createElement(Avatar5.Frame, null, /* @__PURE__ */ React27.createElement(Avatar5.Fallback, {
2022
+ href: jdenticon
2023
+ })), /* @__PURE__ */ React27.createElement(Avatar5.Label, {
2024
+ classNames: mx20("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2025
+ }, displayName))), /* @__PURE__ */ React27.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React27.createElement(Action, {
2026
+ variant: "primary",
2027
+ disabled: disabled || !addedIdentity,
2028
+ onClick: () => addedIdentity && send({
2029
+ type: "selectIdentity",
2030
+ identity: addedIdentity
2031
+ }),
2032
+ "data-autofocus": "confirmingAddedIdentity"
2033
+ }, t("continue label"))));
2034
+ };
2035
+
2036
+ // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx
2037
+ import React28, { useState as useState4 } from "react";
2038
+ import { log as log5 } from "@dxos/log";
2039
+ import { useClient as useClient4 } from "@dxos/react-client";
2040
+ import { useTranslation as useTranslation14 } from "@dxos/react-ui";
2041
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2042
+ var IdentityInput = (props) => {
2043
+ const { send, method } = props;
2044
+ const isRecover = method === "recover identity";
2045
+ const client = useClient4();
2046
+ const { t } = useTranslation14("os");
2047
+ const [validationMessage, setValidationMessage] = useState4("");
2048
+ const createIdentity = (displayName) => {
2049
+ void client.halo.createIdentity({
2050
+ [isRecover ? "seedphrase" : "displayName"]: displayName
2051
+ }).then((identity) => {
2052
+ send?.({
2053
+ type: "selectIdentity",
2054
+ identity
2055
+ });
2056
+ }, (error) => {
2057
+ log5.catch(error, void 0, {
2058
+ F: __dxlog_file5,
2059
+ L: 37,
2060
+ S: void 0,
2061
+ C: (f, a) => f(...a)
2062
+ });
2063
+ setValidationMessage(t(isRecover ? "failed to recover identity message" : "failed to create identity message"));
2064
+ });
2065
+ };
2066
+ return /* @__PURE__ */ React28.createElement(IdentityInputImpl, {
2067
+ ...props,
2068
+ onDisplayNameConfirm: createIdentity,
2069
+ validationMessage
2070
+ });
2071
+ };
2072
+ var IdentityInputImpl = (props) => {
2073
+ const { method, send, active, onDisplayNameConfirm, validationMessage } = props;
2074
+ const disabled = !active;
2075
+ const { t } = useTranslation14("os");
2076
+ const [inputValue, setInputValue] = useState4("");
2077
+ const isRecover = method === "recover identity";
2078
+ return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("div", {
2079
+ role: "none",
2080
+ className: "grow flex flex-col justify-center"
2081
+ }, /* @__PURE__ */ React28.createElement(Input, {
2082
+ validationMessage,
2083
+ label: /* @__PURE__ */ React28.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2084
+ disabled,
2085
+ "data-testid": "identity-input",
2086
+ placeholder: isRecover ? "Type your recovery phrase" : "Type a display name",
2087
+ onChange: ({ target: { value } }) => setInputValue(value)
2088
+ })), /* @__PURE__ */ React28.createElement(Actions, null, /* @__PURE__ */ React28.createElement(Action, {
2089
+ variant: "ghost",
2090
+ disabled,
2091
+ onClick: () => send?.({
2092
+ type: "deselectAuthMethod"
2093
+ }),
2094
+ "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-back`
2095
+ }, t("back label")), /* @__PURE__ */ React28.createElement(Action, {
2096
+ variant: "primary",
2097
+ disabled,
2098
+ onClick: () => onDisplayNameConfirm?.(inputValue),
2099
+ "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-continue`
2100
+ }, t("continue label"))));
2101
+ };
2102
+
2103
+ // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAccepted.tsx
2104
+ import React29, { cloneElement as cloneElement3 } from "react";
2105
+ import { useTranslation as useTranslation15 } from "@dxos/react-ui";
2106
+ var InvitationAccepted = (props) => {
2107
+ const { active, Kind, doneActionParent, onDone } = props;
2108
+ const disabled = !active;
2109
+ const { t } = useTranslation15("os");
2110
+ const doneAction = /* @__PURE__ */ React29.createElement(Action, {
2111
+ variant: "primary",
2112
+ onClick: onDone,
2113
+ disabled,
2114
+ "data-autofocus": `success${Kind}Invitation finishingJoining${Kind}`,
2115
+ "data-testid": `${Kind.toLowerCase()}-invitation-accepted-done`
2116
+ }, t("done label"));
2117
+ return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement("div", {
2118
+ role: "none",
2119
+ className: "grow flex flex-col justify-center"
2120
+ }, /* @__PURE__ */ React29.createElement("p", {
2121
+ className: "text-center text-sm font-normal"
2122
+ }, t("welcome message"))), /* @__PURE__ */ React29.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2123
+ };
2124
+
2125
+ // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx
2126
+ import React30, { useState as useState5, useEffect as useEffect3, cloneElement as cloneElement4 } from "react";
2127
+ import { log as log6 } from "@dxos/log";
2128
+ import { useTranslation as useTranslation16 } from "@dxos/react-ui";
2129
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2130
+ var invitationCodeFromUrl = (text) => {
2131
+ try {
2132
+ const searchParams = new URLSearchParams(text.substring(text.lastIndexOf("?")));
2133
+ const invitation = searchParams.get("spaceInvitationCode") ?? searchParams.get("deviceInvitationCode");
2134
+ return invitation ?? text;
2135
+ } catch (err) {
2136
+ log6.catch(err, void 0, {
2137
+ F: __dxlog_file6,
2138
+ L: 25,
2139
+ S: void 0,
2140
+ C: (f, a) => f(...a)
2141
+ });
2142
+ return text;
2143
+ }
2144
+ };
2145
+ var InvitationInput = (props) => {
2146
+ const { Kind, active, send, unredeemedCode, onExit, exitActionParent, onDone, doneActionParent, succeededKeys } = props;
2147
+ const disabled = !active;
2148
+ const { t } = useTranslation16("os");
2149
+ const [inputValue, setInputValue] = useState5(unredeemedCode ?? "");
2150
+ useEffect3(() => {
2151
+ unredeemedCode && setInputValue(unredeemedCode ?? "");
2152
+ }, [
2153
+ unredeemedCode
2154
+ ]);
2155
+ const handleNext = () => send({
2156
+ type: `set${Kind}InvitationCode`,
2157
+ code: invitationCodeFromUrl(inputValue),
2158
+ ...Kind === "Space" && {
2159
+ succeededKeys
2160
+ }
2161
+ });
2162
+ const exitAction = /* @__PURE__ */ React30.createElement(Action, {
2163
+ variant: "ghost",
2164
+ disabled,
2165
+ ...onExit ? {
2166
+ onClick: () => onExit()
2167
+ } : {
2168
+ onClick: () => onDone?.(null)
2169
+ },
2170
+ "data-testid": "join-exit"
2171
+ }, t("cancel label"));
2172
+ return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement("div", {
2173
+ role: "none",
2174
+ className: "grow flex flex-col justify-center"
2175
+ }, /* @__PURE__ */ React30.createElement(Input, {
2176
+ label: /* @__PURE__ */ React30.createElement(StepHeading, null, t("invitation input label")),
2177
+ placeholder: "Type an invitation code",
2178
+ disabled,
2179
+ value: inputValue,
2180
+ onChange: ({ target: { value } }) => setInputValue(value),
2181
+ "data-autofocus": `inputting${Kind}InvitationCode`,
2182
+ "data-testid": `${Kind.toLowerCase()}-invitation-input`,
2183
+ onKeyUp: ({ key }) => key === "Enter" && handleNext()
2184
+ })), /* @__PURE__ */ React30.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React30.createElement(Action, {
2185
+ variant: "ghost",
2186
+ disabled,
2187
+ onClick: () => send({
2188
+ type: "deselectAuthMethod"
2189
+ }),
2190
+ "data-testid": `${Kind.toLowerCase()}-invitation-input-back`
2191
+ }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React30.createElement(Action, {
2192
+ variant: "primary",
2193
+ disabled,
2194
+ onClick: handleNext,
2195
+ "data-testid": `${Kind.toLowerCase()}-invitation-input-continue`
2196
+ }, t("continue label"))));
2197
+ };
2198
+
2199
+ // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationRescuer.tsx
2200
+ import React31 from "react";
2201
+ import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2202
+ import { descriptionText as descriptionText9 } from "@dxos/react-ui-theme";
2203
+ var InvitationActions = ({
2204
+ // `invitationState` does report correct state, but here we evaluate whether `failReason` is a better source of truth
2205
+ // for the UI in particular.
2206
+ invitationState,
2207
+ onInvitationCancel,
2208
+ active,
2209
+ send,
2210
+ Kind,
2211
+ failReason
2212
+ }) => {
2213
+ const { t } = useTranslation17("os");
2214
+ if (failReason) {
2215
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(StepHeading, {
2216
+ className: descriptionText9
2217
+ }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React31.createElement("div", {
2218
+ role: "none",
2219
+ className: "grow"
2220
+ }), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2221
+ disabled: !active,
2222
+ onClick: () => send({
2223
+ type: `reset${Kind}Invitation`
2224
+ }),
2225
+ "data-testid": "invitation-rescuer-reset"
2226
+ }, t("reset label"))));
2227
+ } else {
2228
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(StepHeading, {
2229
+ className: descriptionText9
2230
+ }, t("connecting status label")), /* @__PURE__ */ React31.createElement("div", {
2231
+ role: "none",
2232
+ className: "grow"
2233
+ }), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2234
+ disabled: true,
2235
+ classNames: "order-2",
2236
+ "data-testid": "next"
2237
+ }, t("next label")), /* @__PURE__ */ React31.createElement(Action, {
2238
+ disabled: !active,
2239
+ onClick: onInvitationCancel,
2240
+ "data-testid": "invitation-rescuer-cancel"
2241
+ }, t("cancel label"))));
2242
+ }
2243
+ };
2244
+ var InvitationRescuer = (props) => {
2245
+ const { Kind, invitationState, active, send } = props;
2246
+ const { t } = useTranslation17("os");
2247
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2248
+ role: "none",
2249
+ className: "grow flex flex-col justify-center"
2250
+ }, /* @__PURE__ */ React31.createElement(StepHeading, {
2251
+ className: descriptionText9
2252
+ }, "There was a problem joining the space")), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2253
+ disabled: !active,
2254
+ "data-testid": "invitation-rescuer-blank-reset",
2255
+ onClick: () => send({
2256
+ type: `reset${Kind}Invitation`
2257
+ })
2258
+ }, t("reset label")))) : /* @__PURE__ */ React31.createElement(InvitationActions, props));
2259
+ };
2260
+
2261
+ // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx
2262
+ import React32, { useState as useState6 } from "react";
2263
+ import { Input as Input2, useTranslation as useTranslation18 } from "@dxos/react-ui";
2264
+ var pinLength = 6;
2265
+ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, onInvitationAuthenticate, onInvitationCancel }) => {
2266
+ const disabled = !active || pending;
2267
+ const { t } = useTranslation18("os");
2268
+ const invitationType = Kind.toLowerCase();
2269
+ const [authCode, setAuthCode] = useState6("");
2270
+ const onChange = ({ target: { value } }) => {
2271
+ setAuthCode(value);
2272
+ if (value.length === pinLength) {
2273
+ document.querySelector(`[data-autofocus-pinlength="${invitationType}"]`)?.focus();
2274
+ }
2275
+ };
2276
+ return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2277
+ role: "none",
2278
+ className: "grow flex flex-col justify-center"
2279
+ }, invitationId && /* @__PURE__ */ React32.createElement(Emoji, {
2280
+ text: toEmoji(invitationId)
2281
+ }), /* @__PURE__ */ React32.createElement(Input2.Root, failed && {
2282
+ validationValence: "error"
2283
+ }, /* @__PURE__ */ React32.createElement(Input2.Label, {
2284
+ asChild: true
2285
+ }, /* @__PURE__ */ React32.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React32.createElement(Input2.PinInput, {
2286
+ disabled,
2287
+ length: pinLength,
2288
+ onChange,
2289
+ inputMode: "numeric",
2290
+ autoComplete: "off",
2291
+ pattern: "\\d*",
2292
+ "data-autofocus": `connecting${Kind}Invitation inputting${Kind}VerificationCode authenticationFailing${Kind}VerificationCode authenticating${Kind}VerificationCode`,
2293
+ "data-prevent-ios-autofocus": true,
2294
+ "data-testid": `${invitationType}-auth-code-input`,
2295
+ "data-1p-ignore": true
2296
+ }), failed && /* @__PURE__ */ React32.createElement(Input2.DescriptionAndValidation, {
2297
+ classNames: "text-center"
2298
+ }, /* @__PURE__ */ React32.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React32.createElement(Actions, null, /* @__PURE__ */ React32.createElement(Action, {
2299
+ variant: "ghost",
2300
+ disabled,
2301
+ onClick: () => onInvitationCancel?.(),
2302
+ "data-testid": `${invitationType}-invitation-authenticator-cancel`
2303
+ }, t("cancel label")), /* @__PURE__ */ React32.createElement(Action, {
2304
+ variant: "primary",
2305
+ disabled,
2306
+ onClick: () => onInvitationAuthenticate?.(authCode),
2307
+ "data-autofocus-pinlength": invitationType,
2308
+ "data-testid": `${invitationType}-invitation-authenticator-next`
2309
+ }, t("next label"))));
2310
+ };
2311
+
2312
+ // packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx
2313
+ import React33, { useState as useState7 } from "react";
2314
+ import { log as log7 } from "@dxos/log";
2315
+ import { useClient as useClient5 } from "@dxos/react-client";
2316
+ import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2317
+ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2318
+ var ResetIdentity = ({ send, active }) => {
2319
+ const client = useClient5();
2320
+ const { t } = useTranslation19("os");
2321
+ const [validationMessage, setValidationMessage] = useState7("");
2322
+ const resetIdentity = () => {
2323
+ void client.reset().then(() => send?.({
2324
+ type: "resetIdentity"
2325
+ }), (error) => {
2326
+ log7.catch(error, void 0, {
2327
+ F: __dxlog_file7,
2328
+ L: 32,
2329
+ S: void 0,
2330
+ C: (f, a) => f(...a)
2331
+ });
2332
+ setValidationMessage(t("failed to reset identity message"));
2333
+ });
2334
+ };
2335
+ return /* @__PURE__ */ React33.createElement(ResetIdentityImpl, {
2336
+ disabled: !active,
2337
+ validationMessage,
2338
+ onConfirm: () => resetIdentity()
2339
+ });
2340
+ };
2341
+ var ResetIdentityImpl = ({ disabled, validationMessage, onConfirm }) => {
2342
+ const { t } = useTranslation19("os");
2343
+ const confirmationValue = t("confirmation value");
2344
+ const [inputValue, setInputValue] = useState7("");
2345
+ return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2346
+ role: "none",
2347
+ className: "grow flex flex-col justify-center"
2348
+ }, /* @__PURE__ */ React33.createElement(Input, {
2349
+ validationMessage,
2350
+ label: /* @__PURE__ */ React33.createElement(StepHeading, null, t("reset identity input label", {
2351
+ confirmationValue
2352
+ })),
2353
+ disabled,
2354
+ "data-testid": "identity-input",
2355
+ placeholder: confirmationValue,
2356
+ onChange: ({ target: { value } }) => setInputValue(value)
2357
+ })), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2358
+ // TODO(wittjosiah): Probably make this red?
2359
+ variant: "primary",
2360
+ disabled: disabled || inputValue !== confirmationValue,
2361
+ onClick: () => onConfirm?.(),
2362
+ "data-testid": "reset-identity-input-confirm"
2363
+ }, t("confirm label"))));
2364
+ };
2365
+
2366
+ // packages/sdk/shell/src/styles/panelStyles.ts
2367
+ var stepStyles = "pbs-1 pbe-3 pli-3";
2368
+
2369
+ // packages/sdk/shell/src/styles/invitationStatusStyles.ts
2370
+ import { Invitation as Invitation6 } from "@dxos/react-client/invitations";
2371
+ var inactiveBgColor = "bg-neutral-100 dark:bg-neutral-600";
2372
+ var activeBgColor = "bg-primary-500 dark:bg-primary-400";
2373
+ var successBgColor = "bg-success-500 dark:bg-success-400";
2374
+ var errorBgColor = "bg-error-500 dark:bg-error-400";
2375
+ var cancelledBgColor = "bg-warning-500 dark:bg-warning-400";
2376
+ var inactiveTextColor = "text-neutral-100 dark:text-neutral-600";
2377
+ var activeTextColor = "text-primary-400 dark:text-primary-500";
2378
+ var successTextColor = "text-success-400 dark:text-success-500";
2379
+ var errorTextColor = "text-error-400 dark:text-error-500";
2380
+ var cancelledTextColor = "text-warning-400 dark:text-warning-500";
2381
+ var inactiveStrokeColor = "stroke-neutral-100 dark:stroke-neutral-700";
2382
+ var activeStrokeColor = "stroke-primary-400 dark:stroke-primary-150";
2383
+ var successStrokeColor = "stroke-success-300 dark:stroke-primary-400";
2384
+ var errorStrokeColor = "stroke-error-300 dark:stroke-error-500";
2385
+ var cancelledStrokeColor = "stroke-warning-300 dark:stroke-warning-500";
2386
+ var resolvedStrokeColor = (status) => status === Invitation6.State.ERROR ? errorStrokeColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledStrokeColor : successStrokeColor;
2387
+ var resolvedBgColor = (status) => status === Invitation6.State.ERROR ? errorBgColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledBgColor : successBgColor;
2388
+ var resolvedTextColor = (status) => status === Invitation6.State.ERROR ? errorTextColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledTextColor : successTextColor;
2389
+
2390
+ // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
2391
+ var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2392
+ var JoinPanelImpl = (props) => {
2393
+ const { titleId, send, activeView, failed, mode, unredeemedCodes, invitationStates, succeededKeys, failReasons, onExit, onHaloDone, onSpaceDone, exitActionParent, doneActionParent, onHaloInvitationCancel, onSpaceInvitationCancel, onHaloInvitationAuthenticate, onSpaceInvitationAuthenticate, IdentityInput: IdentityInputComponent = IdentityInput, ResetIdentity: ResetIdentityComponent = ResetIdentity } = props;
2394
+ return /* @__PURE__ */ React34.createElement(DensityProvider3, {
2395
+ density: "fine"
2396
+ }, mode !== "halo-only" && /* @__PURE__ */ React34.createElement(JoinHeading, {
2397
+ titleId,
2398
+ mode,
2399
+ onExit,
2400
+ exitActionParent
2401
+ }), /* @__PURE__ */ React34.createElement(Viewport.Root, {
2402
+ focusManaged: true,
2403
+ activeView
2404
+ }, /* @__PURE__ */ React34.createElement(Viewport.Views, null, /* @__PURE__ */ React34.createElement(Viewport.View, {
2405
+ classNames: stepStyles,
2406
+ id: "addition method chooser"
2407
+ }, /* @__PURE__ */ React34.createElement(AdditionMethodChooser, {
2408
+ send,
2409
+ active: activeView === "addition method chooser"
2410
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2411
+ classNames: stepStyles,
2412
+ id: "reset identity confirmation"
2413
+ }, /* @__PURE__ */ React34.createElement(ResetIdentityComponent, {
2414
+ send,
2415
+ method: "reset identity",
2416
+ active: activeView === "reset identity confirmation"
2417
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2418
+ classNames: stepStyles,
2419
+ id: "create identity input"
2420
+ }, /* @__PURE__ */ React34.createElement(IdentityInputComponent, {
2421
+ send,
2422
+ method: "create identity",
2423
+ active: activeView === "create identity input"
2424
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2425
+ classNames: stepStyles,
2426
+ id: "recover identity input"
2427
+ }, /* @__PURE__ */ React34.createElement(IdentityInputComponent, {
2428
+ send,
2429
+ method: "recover identity",
2430
+ active: activeView === "recover identity input"
2431
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2432
+ classNames: stepStyles,
2433
+ id: "halo invitation input"
2434
+ }, /* @__PURE__ */ React34.createElement(InvitationInput, {
2435
+ send,
2436
+ Kind: "Halo",
2437
+ active: activeView === "halo invitation input",
2438
+ ...unredeemedCodes?.Halo && {
2439
+ unredeemedCode: unredeemedCodes.Halo
2440
+ },
2441
+ ...succeededKeys?.Halo && {
2442
+ succeededKeys: succeededKeys.Halo
2443
+ }
2444
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2445
+ classNames: stepStyles,
2446
+ id: "halo invitation rescuer"
2447
+ }, /* @__PURE__ */ React34.createElement(InvitationRescuer, {
2448
+ send,
2449
+ Kind: "Halo",
2450
+ active: activeView === "halo invitation rescuer",
2451
+ invitationState: invitationStates?.Halo,
2452
+ onInvitationCancel: onHaloInvitationCancel,
2453
+ failReason: failReasons?.Halo
2454
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2455
+ classNames: stepStyles,
2456
+ id: "halo invitation authenticator"
2457
+ }, /* @__PURE__ */ React34.createElement(InvitationAuthenticator, {
2458
+ send,
2459
+ Kind: "Halo",
2460
+ active: activeView === "halo invitation authenticator",
2461
+ onInvitationCancel: onHaloInvitationCancel,
2462
+ onInvitationAuthenticate: onHaloInvitationAuthenticate,
2463
+ ...failed.has("Halo") && {
2464
+ failed: true
2465
+ }
2466
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2467
+ classNames: stepStyles,
2468
+ id: "halo invitation accepted"
2469
+ }, /* @__PURE__ */ React34.createElement(InvitationAccepted, {
2470
+ send,
2471
+ Kind: "Halo",
2472
+ active: activeView === "halo invitation accepted",
2473
+ doneActionParent,
2474
+ onDone: onHaloDone
2475
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2476
+ classNames: stepStyles,
2477
+ id: "identity added"
2478
+ }, /* @__PURE__ */ React34.createElement(IdentityAdded, {
2479
+ send,
2480
+ mode,
2481
+ active: activeView === "identity added",
2482
+ doneActionParent,
2483
+ onDone: onHaloDone
2484
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2485
+ classNames: stepStyles,
2486
+ id: "space invitation input"
2487
+ }, /* @__PURE__ */ React34.createElement(InvitationInput, {
2488
+ send,
2489
+ Kind: "Space",
2490
+ active: activeView === "space invitation input",
2491
+ ...unredeemedCodes?.Space && {
2492
+ unredeemedCode: unredeemedCodes.Space
2493
+ },
2494
+ ...succeededKeys?.Space && {
2495
+ succeededKeys: succeededKeys.Space
2496
+ },
2497
+ onExit,
2498
+ exitActionParent
2499
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2500
+ classNames: stepStyles,
2501
+ id: "space invitation rescuer"
2502
+ }, /* @__PURE__ */ React34.createElement(InvitationRescuer, {
2503
+ send,
2504
+ Kind: "Space",
2505
+ active: activeView === "space invitation rescuer",
2506
+ invitationState: invitationStates?.Space,
2507
+ onInvitationCancel: onSpaceInvitationCancel,
2508
+ failReason: failReasons?.Space
2509
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2510
+ classNames: stepStyles,
2511
+ id: "space invitation authenticator"
2512
+ }, /* @__PURE__ */ React34.createElement(InvitationAuthenticator, {
2513
+ send,
2514
+ Kind: "Space",
2515
+ active: activeView === "space invitation authenticator",
2516
+ onInvitationCancel: onSpaceInvitationCancel,
2517
+ onInvitationAuthenticate: onSpaceInvitationAuthenticate,
2518
+ ...failed.has("Space") && {
2519
+ failed: true
2520
+ }
2521
+ })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2522
+ classNames: stepStyles,
2523
+ id: "space invitation accepted"
2524
+ }, /* @__PURE__ */ React34.createElement(InvitationAccepted, {
2525
+ send,
2526
+ Kind: "Space",
2527
+ active: activeView === "space invitation accepted",
2528
+ doneActionParent,
2529
+ onDone: onSpaceDone
2530
+ })))));
2531
+ };
2532
+ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCode, exitActionParent, onExit, doneActionParent, onDone: propsOnDone }) => {
2533
+ const client = useClient6();
2534
+ const identity = useIdentity2();
2535
+ const { hasIosKeyboard } = useThemeContext3();
2536
+ const titleId = useId7("joinPanel__heading", propsTitleId);
2537
+ const [joinState, joinSend, joinService] = useJoinMachine(client, {
2538
+ context: {
2539
+ mode,
2540
+ identity,
2541
+ ...initialInvitationCode && {
2542
+ [mode === "halo-only" ? "halo" : "space"]: {
2543
+ unredeemedCode: initialInvitationCode
2544
+ }
2545
+ }
2546
+ }
2547
+ });
2548
+ console.log("[joinState]", joinState);
2549
+ useEffect4(() => {
2550
+ const subscription = joinService.subscribe((state) => {
2551
+ log8("[state]", state, {
2552
+ F: __dxlog_file8,
2553
+ L: 200,
2554
+ S: void 0,
2555
+ C: (f, a) => f(...a)
2556
+ });
2557
+ });
2558
+ return subscription.unsubscribe;
2559
+ }, [
2560
+ joinService
2561
+ ]);
2562
+ useEffect4(() => {
2563
+ const stateStack = joinState.configuration[0].id.split(".");
2564
+ const innermostState = stateStack[stateStack.length - 1];
2565
+ const autoFocusValue = innermostState === "finishingJoining" ? "successSpaceInvitation" : innermostState;
2566
+ const $nextAutofocus = document.querySelector(`[data-autofocus~="${autoFocusValue}"]`);
2567
+ if ($nextAutofocus && !(hasIosKeyboard && $nextAutofocus.hasAttribute("data-prevent-ios-autofocus"))) {
2568
+ $nextAutofocus.focus();
2569
+ }
2570
+ }, [
2571
+ joinState.value,
2572
+ hasIosKeyboard
2573
+ ]);
2574
+ const activeView = useMemo4(() => {
2575
+ switch (true) {
2576
+ case joinState.matches({
2577
+ choosingIdentity: "choosingAuthMethod"
2578
+ }):
2579
+ return "addition method chooser";
2580
+ case joinState.matches("resettingIdentity"):
2581
+ return "reset identity confirmation";
2582
+ case joinState.matches({
2583
+ choosingIdentity: "creatingIdentity"
2584
+ }):
2585
+ return "create identity input";
2586
+ case joinState.matches({
2587
+ choosingIdentity: "recoveringIdentity"
2588
+ }):
2589
+ return "recover identity input";
2590
+ case joinState.matches({
2591
+ choosingIdentity: {
2592
+ acceptingHaloInvitation: "inputtingHaloInvitationCode"
2593
+ }
2594
+ }):
2595
+ return "halo invitation input";
2596
+ case [
2597
+ {
2598
+ choosingIdentity: {
2599
+ acceptingHaloInvitation: {
2600
+ acceptingRedeemedHaloInvitation: "connectingHaloInvitation"
2601
+ }
2602
+ }
2603
+ },
2604
+ {
2605
+ choosingIdentity: {
2606
+ acceptingHaloInvitation: {
2607
+ acceptingRedeemedHaloInvitation: "failingHaloInvitation"
2608
+ }
2609
+ }
2610
+ }
2611
+ ].some(joinState.matches):
2612
+ return "halo invitation rescuer";
2613
+ case [
2614
+ {
2615
+ choosingIdentity: {
2616
+ acceptingHaloInvitation: {
2617
+ acceptingRedeemedHaloInvitation: "inputtingHaloVerificationCode"
2618
+ }
2619
+ }
2620
+ },
2621
+ {
2622
+ choosingIdentity: {
2623
+ acceptingHaloInvitation: {
2624
+ acceptingRedeemedHaloInvitation: "authenticatingHaloVerificationCode"
2625
+ }
2626
+ }
2627
+ },
2628
+ {
2629
+ choosingIdentity: {
2630
+ acceptingHaloInvitation: {
2631
+ acceptingRedeemedHaloInvitation: "authenticationFailingHaloVerificationCode"
2632
+ }
2633
+ }
2634
+ }
2635
+ ].some(joinState.matches):
2636
+ return "halo invitation authenticator";
2637
+ case [
2638
+ {
2639
+ choosingIdentity: {
2640
+ acceptingHaloInvitation: {
2641
+ acceptingRedeemedHaloInvitation: "successHaloInvitation"
2642
+ }
2643
+ }
2644
+ },
2645
+ "finishingJoiningHalo"
2646
+ ].some(joinState.matches):
2647
+ return "halo invitation accepted";
2648
+ case joinState.matches({
2649
+ choosingIdentity: "confirmingAddedIdentity"
2650
+ }):
2651
+ return "identity added";
2652
+ case joinState.matches({
2653
+ acceptingSpaceInvitation: "inputtingSpaceInvitationCode"
2654
+ }):
2655
+ return "space invitation input";
2656
+ case [
2657
+ {
2658
+ acceptingSpaceInvitation: {
2659
+ acceptingRedeemedSpaceInvitation: "connectingSpaceInvitation"
2660
+ }
2661
+ },
2662
+ {
2663
+ acceptingSpaceInvitation: {
2664
+ acceptingRedeemedSpaceInvitation: "failingSpaceInvitation"
2665
+ }
2666
+ }
2667
+ ].some(joinState.matches):
2668
+ return "space invitation rescuer";
2669
+ case [
2670
+ {
2671
+ acceptingSpaceInvitation: {
2672
+ acceptingRedeemedSpaceInvitation: "inputtingSpaceVerificationCode"
2673
+ }
2674
+ },
2675
+ {
2676
+ acceptingSpaceInvitation: {
2677
+ acceptingRedeemedSpaceInvitation: "authenticatingSpaceVerificationCode"
2678
+ }
2679
+ },
2680
+ {
2681
+ acceptingSpaceInvitation: {
2682
+ acceptingRedeemedSpaceInvitation: "authenticationFailingSpaceVerificationCode"
2683
+ }
2684
+ }
2685
+ ].some(joinState.matches):
2686
+ return "space invitation authenticator";
2687
+ case joinState.matches("finishingJoiningSpace"):
2688
+ return "space invitation accepted";
2689
+ default:
2690
+ return "never";
2691
+ }
2692
+ }, [
2693
+ joinState
2694
+ ]);
2695
+ const failed = useMemo4(() => {
2696
+ const result = /* @__PURE__ */ new Set();
2697
+ switch (true) {
2698
+ case joinState.matches({
2699
+ choosingIdentity: {
2700
+ acceptingHaloInvitation: {
2701
+ acceptingRedeemedHaloInvitation: "authenticationFailingHaloVerificationCode"
2702
+ }
2703
+ }
2704
+ }):
2705
+ result.add("Halo");
2706
+ break;
2707
+ case joinState.matches({
2708
+ acceptingSpaceInvitation: {
2709
+ acceptingRedeemedSpaceInvitation: "authenticationFailingSpaceVerificationCode"
2710
+ }
2711
+ }):
2712
+ result.add("Space");
2713
+ break;
2714
+ }
2715
+ return result;
2716
+ }, [
2717
+ joinState
2718
+ ]);
2719
+ const unredeemedCodes = useMemo4(() => ({
2720
+ Halo: joinState.context.halo.unredeemedCode,
2721
+ Space: joinState.context.space.unredeemedCode
2722
+ }), [
2723
+ joinState
2724
+ ]);
2725
+ const spaces = useMulticastObservable(client.spaces);
2726
+ const succeededKeys = useMemo4(() => ({
2727
+ Space: spaces ? new Set(spaces.map(({ key }) => key.toHex())) : void 0
2728
+ }), [
2729
+ spaces
2730
+ ]);
2731
+ const invitationStates = useMemo4(() => ({
2732
+ Halo: joinState.context.halo.invitationObservable?.get().state,
2733
+ Space: joinState.context.space.invitationObservable?.get().state
2734
+ }), [
2735
+ joinState
2736
+ ]);
2737
+ const failReasons = useMemo4(() => ({
2738
+ Halo: joinState.context.halo.failReason,
2739
+ Space: joinState.context.space.failReason
2740
+ }), [
2741
+ joinState
2742
+ ]);
2743
+ const onHaloDone = useCallback6(() => {
2744
+ propsOnDone?.({
2745
+ identityKey: joinState.context.halo.invitation?.identityKey ?? null,
2746
+ swarmKey: joinState.context.halo.invitation?.swarmKey ?? null,
2747
+ spaceKey: joinState.context.halo.invitation?.spaceKey ?? null
2748
+ });
2749
+ }, [
2750
+ joinState,
2751
+ propsOnDone
2752
+ ]);
2753
+ const onSpaceDone = useCallback6(() => {
2754
+ propsOnDone?.({
2755
+ identityKey: joinState.context.space.invitation?.identityKey ?? null,
2756
+ swarmKey: joinState.context.space.invitation?.swarmKey ?? null,
2757
+ spaceKey: joinState.context.space.invitation?.spaceKey ?? null
2758
+ });
2759
+ }, [
2760
+ joinState,
2761
+ propsOnDone
2762
+ ]);
2763
+ return /* @__PURE__ */ React34.createElement(JoinPanelImpl, {
2764
+ titleId,
2765
+ mode,
2766
+ send: joinSend,
2767
+ activeView,
2768
+ failed,
2769
+ failReasons,
2770
+ pending: [
2771
+ "connecting",
2772
+ "authenticating"
2773
+ ].some((str) => joinState?.configuration[0].id.includes(str)),
2774
+ unredeemedCodes,
2775
+ invitationStates,
2776
+ succeededKeys,
2777
+ identity,
2778
+ onExit,
2779
+ exitActionParent,
2780
+ doneActionParent,
2781
+ onHaloDone,
2782
+ onSpaceDone,
2783
+ onHaloInvitationCancel: () => joinState.context.halo.invitationObservable?.cancel(),
2784
+ onSpaceInvitationCancel: () => joinState.context.space.invitationObservable?.cancel(),
2785
+ onHaloInvitationAuthenticate: (authCode) => {
2786
+ joinSend({
2787
+ type: "authenticateHaloVerificationCode"
2788
+ });
2789
+ return joinState.context.halo.invitationObservable?.authenticate(authCode);
2790
+ },
2791
+ onSpaceInvitationAuthenticate: (authCode) => {
2792
+ joinSend({
2793
+ type: "authenticateSpaceVerificationCode"
2794
+ });
2795
+ return joinState.context.space.invitationObservable?.authenticate(authCode);
2796
+ }
2797
+ });
2798
+ };
2799
+
2800
+ // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
2801
+ import { Planet } from "@phosphor-icons/react";
2802
+ import React36, { useEffect as useEffect5, useMemo as useMemo5 } from "react";
2803
+ import { log as log10 } from "@dxos/log";
2804
+ import { useInvitationStatus as useInvitationStatus3 } from "@dxos/react-client/invitations";
2805
+ import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation21 } from "@dxos/react-ui";
2806
+
2807
+ // packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts
2808
+ import { useMachine as useMachine3 } from "@xstate/react";
2809
+ import { assign as assign3, createMachine as createMachine3 } from "xstate";
2810
+ import { log as log9 } from "@dxos/log";
2811
+ var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts";
2812
+ var spaceMachine = createMachine3({
2813
+ id: "space",
2814
+ predictableActionArguments: true,
2815
+ context: {
2816
+ space: null
2817
+ },
2818
+ initial: "managingSpace",
2819
+ states: {
2820
+ managingSpace: {},
2821
+ managingSpaceInvitation: {}
2822
+ },
2823
+ on: {
2824
+ deselectInvitation: {
2825
+ target: ".managingSpace",
2826
+ actions: [
2827
+ "unsetInvitation",
2828
+ "log"
2829
+ ]
2830
+ },
2831
+ selectInvitation: {
2832
+ target: ".managingSpaceInvitation",
2833
+ actions: [
2834
+ "setInvitation",
2835
+ "log"
2836
+ ]
2837
+ }
2838
+ }
2839
+ }, {
2840
+ actions: {
2841
+ setInvitation: assign3({
2842
+ invitation: (context, event) => event?.invitation ?? null
2843
+ }),
2844
+ unsetInvitation: assign3({
2845
+ invitation: () => void 0
2846
+ }),
2847
+ log: (context, event) => {
2848
+ log9("[transition]", {
2849
+ event,
2850
+ context
2851
+ }, {
2852
+ F: __dxlog_file9,
2853
+ L: 53,
2854
+ S: void 0,
2855
+ C: (f, a) => f(...a)
2856
+ });
2857
+ }
2858
+ }
2859
+ });
2860
+ var useSpaceMachine = (options) => {
2861
+ return useMachine3(spaceMachine, {
2862
+ ...options,
2863
+ context: {
2864
+ ...options?.context
2865
+ }
2866
+ });
2867
+ };
2868
+
2869
+ // packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx
2870
+ import { Placeholder as Placeholder2, UserPlus, UsersThree } from "@phosphor-icons/react";
2871
+ import React35, { useCallback as useCallback7, useState as useState8 } from "react";
2872
+ import { useConfig } from "@dxos/react-client";
2873
+ import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client/echo";
2874
+ import { Invitation as Invitation7, InvitationEncoder as InvitationEncoder3 } from "@dxos/react-client/invitations";
2875
+ import { ScrollArea, useTranslation as useTranslation20 } from "@dxos/react-ui";
2876
+ import { descriptionText as descriptionText10, mx as mx21 } from "@dxos/react-ui-theme";
2877
+ var activeActionKey = "dxos:react-shell/space-manager/active-action";
2878
+ var SpaceManager = (props) => {
2879
+ const { space } = props;
2880
+ const { t } = useTranslation20("os");
2881
+ const config = useConfig();
2882
+ const invitations = useSpaceInvitations2(space?.key);
2883
+ const onInvitationEvent = useCallback7((invitation) => {
2884
+ const invitationCode = InvitationEncoder3.encode(invitation);
2885
+ if (invitation.state === Invitation7.State.CONNECTING) {
2886
+ console.log(JSON.stringify({
2887
+ invitationCode,
2888
+ authCode: invitation.authCode
2889
+ }));
2890
+ }
2891
+ }, []);
2892
+ const inviteActions = {
2893
+ inviteOne: {
2894
+ label: t("invite one label"),
2895
+ description: t("invite one description"),
2896
+ icon: UserPlus,
2897
+ onClick: useCallback7(() => {
2898
+ const invitation = space.share?.({
2899
+ type: Invitation7.Type.INTERACTIVE,
2900
+ authMethod: Invitation7.AuthMethod.SHARED_SECRET
2901
+ });
2902
+ if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
2903
+ invitation.subscribe(onInvitationEvent);
2904
+ }
2905
+ }, [
2906
+ space
2907
+ ])
2908
+ },
2909
+ inviteMany: {
2910
+ label: t("invite many label"),
2911
+ description: t("invite many description"),
2912
+ icon: UsersThree,
2913
+ onClick: useCallback7(() => {
2914
+ const invitation = space.share?.({
2915
+ type: Invitation7.Type.MULTIUSE,
2916
+ authMethod: Invitation7.AuthMethod.NONE
2917
+ });
2918
+ if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
2919
+ invitation.subscribe(onInvitationEvent);
2920
+ }
2921
+ }, [
2922
+ space
2923
+ ])
2924
+ }
2925
+ };
2926
+ return /* @__PURE__ */ React35.createElement(SpaceManagerImpl, {
2927
+ ...props,
2928
+ invitations,
2929
+ inviteActions
2930
+ });
2931
+ };
2932
+ var headingFragment = "pis-3 pie-1 plb-1 mbe-1 font-medium";
2933
+ var SpaceManagerImpl = (props) => {
2934
+ const { active, space, createInvitationUrl, send, inviteActions: propsInviteActions, invitations, showInactiveInvitations, SpaceMemberList: SpaceMemberListComponent = SpaceMemberList, InvitationList: InvitationListComponent = InvitationList } = props;
2935
+ const { t } = useTranslation20("os");
2936
+ const inviteActions = propsInviteActions ?? {
2937
+ noopInvite: {
2938
+ label: t("create space invitation label"),
2939
+ description: "",
2940
+ icon: Placeholder2,
2941
+ onClick: () => {
2942
+ }
2943
+ }
2944
+ };
2945
+ const [activeAction, setInternalActiveAction] = useState8(localStorage.getItem(activeActionKey) ?? "inviteOne");
2946
+ const setActiveAction = (nextAction) => {
2947
+ setInternalActiveAction(nextAction);
2948
+ localStorage.setItem(activeActionKey, nextAction);
2949
+ };
2950
+ const visibleInvitations = showInactiveInvitations ? invitations : invitations?.filter((invitation) => ![
2951
+ Invitation7.State.CANCELLED
2952
+ ].includes(invitation.get().state));
2953
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(ScrollArea.Root, {
2954
+ classNames: "grow shrink basis-28 -mli-2"
2955
+ }, /* @__PURE__ */ React35.createElement(ScrollArea.Viewport, {
2956
+ classNames: "is-full pie-2"
2957
+ }, !!visibleInvitations?.length && /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("h3", {
2958
+ className: mx21(headingFragment, descriptionText10)
2959
+ }, t("invitation list heading")), /* @__PURE__ */ React35.createElement(InvitationListComponent, {
2960
+ className: "mb-2",
2961
+ send,
2962
+ invitations: visibleInvitations ?? [],
2963
+ onClickRemove: (invitation) => invitation.cancel(),
2964
+ createInvitationUrl
2965
+ }), /* @__PURE__ */ React35.createElement("h3", {
2966
+ className: mx21(headingFragment, descriptionText10, "mbs-2")
2967
+ }, t("space member list heading"))), /* @__PURE__ */ React35.createElement(SpaceMemberListComponent, {
2968
+ spaceKey: space.key,
2969
+ includeSelf: true
2970
+ })), /* @__PURE__ */ React35.createElement(ScrollArea.Scrollbar, {
2971
+ orientation: "vertical"
2972
+ }, /* @__PURE__ */ React35.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(BifurcatedAction, {
2973
+ disabled: !active,
2974
+ actions: inviteActions,
2975
+ activeAction,
2976
+ onChangeActiveAction: setActiveAction,
2977
+ "data-testid": "spaces-panel.create-invitation"
2978
+ })));
2979
+ };
2980
+
2981
+ // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
2982
+ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
2983
+ var SpacePanelHeading = ({ titleId, space, onDone }) => {
2984
+ const { t } = useTranslation21("os");
2985
+ const name = space.properties.name;
2986
+ return /* @__PURE__ */ React36.createElement(Heading, {
2987
+ titleId,
2988
+ title: t("space panel heading"),
2989
+ corner: /* @__PURE__ */ React36.createElement(CloseButton, {
2990
+ "data-testid": "identity-panel-done",
2991
+ onDone
2992
+ })
2993
+ }, /* @__PURE__ */ React36.createElement("div", {
2994
+ role: "none",
2995
+ className: "flex gap-4 items-center justify-center mlb-4"
2996
+ }, /* @__PURE__ */ React36.createElement(Planet, {
2997
+ size: 32
2998
+ }), /* @__PURE__ */ React36.createElement("div", {
2999
+ className: "block text-start font-light text-xl"
3000
+ }, name ?? space.key.truncate())));
3001
+ };
3002
+ var SpacePanelImpl = (props) => {
3003
+ const { titleId, activeView, space, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3004
+ return /* @__PURE__ */ React36.createElement(DensityProvider4, {
3005
+ density: "fine"
3006
+ }, /* @__PURE__ */ React36.createElement(SpacePanelHeading, {
3007
+ ...rest,
3008
+ titleId,
3009
+ space
3010
+ }), /* @__PURE__ */ React36.createElement(Viewport.Root, {
3011
+ activeView
3012
+ }, /* @__PURE__ */ React36.createElement(Viewport.Views, null, /* @__PURE__ */ React36.createElement(Viewport.View, {
3013
+ id: "space manager",
3014
+ classNames: stepStyles
3015
+ }, /* @__PURE__ */ React36.createElement(SpaceManagerComponent, {
3016
+ active: activeView === "space manager",
3017
+ space,
3018
+ ...rest
3019
+ })), /* @__PURE__ */ React36.createElement(Viewport.View, {
3020
+ id: "space invitation manager",
3021
+ classNames: stepStyles
3022
+ }, /* @__PURE__ */ React36.createElement(InvitationManagerComponent, {
3023
+ active: activeView === "space invitation manager",
3024
+ ...rest,
3025
+ invitationUrl: props.invitationUrl
3026
+ })))));
3027
+ };
3028
+ var SpacePanelWithInvitationImpl = ({ invitation, ...props }) => {
3029
+ const invitationStatus = useInvitationStatus3(invitation);
3030
+ return /* @__PURE__ */ React36.createElement(SpacePanelImpl, {
3031
+ ...props,
3032
+ ...invitationStatus,
3033
+ invitationUrl: props.createInvitationUrl(invitationStatus.invitationCode)
3034
+ });
3035
+ };
3036
+ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code, ...props }) => {
3037
+ const titleId = useId8("spacePanel__heading", propsTitleId);
3038
+ const [spaceState, spaceSend, spaceService] = useSpaceMachine({
3039
+ context: {
3040
+ space: props.space
3041
+ }
3042
+ });
3043
+ useEffect5(() => {
3044
+ const subscription = spaceService.subscribe((state) => {
3045
+ log10("[state]", state, {
3046
+ F: __dxlog_file10,
3047
+ L: 92,
3048
+ S: void 0,
3049
+ C: (f, a) => f(...a)
3050
+ });
3051
+ });
3052
+ return subscription.unsubscribe;
3053
+ }, [
3054
+ spaceService
3055
+ ]);
3056
+ const activeView = useMemo5(() => {
3057
+ switch (true) {
3058
+ case spaceState.matches("managingSpace"):
3059
+ return "space manager";
3060
+ case spaceState.matches("managingSpaceInvitation"):
3061
+ return "space invitation manager";
3062
+ default:
3063
+ return "never";
3064
+ }
3065
+ }, [
3066
+ spaceState
3067
+ ]);
3068
+ const implProps = {
3069
+ ...props,
3070
+ activeView,
3071
+ send: spaceSend,
3072
+ titleId,
3073
+ createInvitationUrl
3074
+ };
3075
+ return spaceState.context.invitation ? /* @__PURE__ */ React36.createElement(SpacePanelWithInvitationImpl, {
3076
+ ...implProps,
3077
+ invitation: spaceState.context.invitation
3078
+ }) : /* @__PURE__ */ React36.createElement(SpacePanelImpl, implProps);
3079
+ };
3080
+
3081
+ // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
3082
+ var IdentityDialog = (props) => {
3083
+ const titleId = useId9("spaceDialog__title");
3084
+ return /* @__PURE__ */ React37.createElement(Dialog.Root, {
3085
+ defaultOpen: true,
3086
+ onOpenChange: (open) => open || props.onDone?.()
3087
+ }, /* @__PURE__ */ React37.createElement(Dialog.Portal, null, /* @__PURE__ */ React37.createElement(Dialog.Overlay, null, /* @__PURE__ */ React37.createElement(Dialog.Content, {
3088
+ "aria-labelledby": titleId,
3089
+ onOpenAutoFocus: (e) => e.preventDefault()
3090
+ }, /* @__PURE__ */ React37.createElement(ClipboardProvider, null, /* @__PURE__ */ React37.createElement(IdentityPanel, {
3091
+ ...props,
3092
+ titleId,
3093
+ doneActionParent: /* @__PURE__ */ React37.createElement(Dialog.Close, {
3094
+ asChild: true
3095
+ })
3096
+ }))))));
3097
+ };
3098
+
3099
+ // packages/sdk/shell/src/composites/JoinDialog/JoinDialog.tsx
3100
+ import React38 from "react";
3101
+ import { AlertDialog, useId as useId10, useVisualViewport } from "@dxos/react-ui";
3102
+ var JoinDialog = (joinPanelProps) => {
3103
+ const titleId = useId10("joinDialog__title");
3104
+ const { height } = useVisualViewport();
3105
+ return /* @__PURE__ */ React38.createElement(AlertDialog.Root, {
3106
+ defaultOpen: true,
3107
+ onOpenChange: (open) => open || (joinPanelProps.onExit ? joinPanelProps.onExit() : joinPanelProps.onDone?.(null))
3108
+ }, /* @__PURE__ */ React38.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React38.createElement(AlertDialog.Overlay, {
3109
+ classNames: "backdrop-blur",
3110
+ ...height && {
3111
+ style: {
3112
+ blockSize: `${height}px`
3113
+ }
3114
+ }
3115
+ }, /* @__PURE__ */ React38.createElement(AlertDialog.Content, {
3116
+ "aria-labelledby": titleId
3117
+ }, /* @__PURE__ */ React38.createElement(JoinPanel, {
3118
+ ...joinPanelProps,
3119
+ titleId,
3120
+ exitActionParent: /* @__PURE__ */ React38.createElement(AlertDialog.Cancel, {
3121
+ asChild: true
3122
+ }),
3123
+ doneActionParent: /* @__PURE__ */ React38.createElement(AlertDialog.Action, {
3124
+ asChild: true
3125
+ })
3126
+ })))));
3127
+ };
3128
+
3129
+ // packages/sdk/shell/src/composites/Shell/run-shell.tsx
3130
+ import React41, { StrictMode } from "react";
3131
+ import { createRoot } from "react-dom/client";
3132
+ import { DEFAULT_CLIENT_CHANNEL, DEFAULT_SHELL_CHANNEL } from "@dxos/client-protocol";
3133
+ import { ShellRuntimeImpl } from "@dxos/client-services";
3134
+ import { Client, ClientContext, ClientServicesProxy, Config, SystemStatus } from "@dxos/react-client";
3135
+ import { ThemeProvider, Tooltip as Tooltip3 } from "@dxos/react-ui";
3136
+ import { defaultTx } from "@dxos/react-ui-theme";
3137
+ import { createIFramePort } from "@dxos/rpc-tunnel";
3138
+
3139
+ // packages/sdk/shell/src/composites/Shell/Shell.tsx
3140
+ import React40, { useEffect as useEffect6, useState as useState9 } from "react";
3141
+ import { log as log11 } from "@dxos/log";
3142
+ import { ShellDisplay, ShellLayout } from "@dxos/react-client";
3143
+ import { useSpace as useSpace2 } from "@dxos/react-client/echo";
3144
+
3145
+ // packages/sdk/shell/src/composites/SpaceDialog/SpaceDialog.tsx
3146
+ import React39 from "react";
3147
+ import { Dialog as Dialog2, useId as useId11 } from "@dxos/react-ui";
3148
+ var SpaceDialog = (spacePanelProps) => {
3149
+ const titleId = useId11("spaceDialog__title");
3150
+ return /* @__PURE__ */ React39.createElement(Dialog2.Root, {
3151
+ defaultOpen: true,
3152
+ onOpenChange: (open) => open || spacePanelProps.onDone?.()
3153
+ }, /* @__PURE__ */ React39.createElement(Dialog2.Portal, null, /* @__PURE__ */ React39.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React39.createElement(Dialog2.Content, {
3154
+ "aria-labelledby": titleId
3155
+ }, /* @__PURE__ */ React39.createElement(ClipboardProvider, null, /* @__PURE__ */ React39.createElement(SpacePanel, {
3156
+ ...spacePanelProps,
3157
+ titleId,
3158
+ doneActionParent: /* @__PURE__ */ React39.createElement(Dialog2.Close, {
3159
+ asChild: true
3160
+ })
3161
+ }))))));
3162
+ };
3163
+
3164
+ // packages/sdk/shell/src/composites/Shell/Shell.tsx
3165
+ var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3166
+ var Shell = ({ runtime, origin }) => {
3167
+ const [{ layout, invitationCode, spaceKey }, setLayout] = useState9({
3168
+ layout: runtime.layout,
3169
+ invitationCode: runtime.invitationCode,
3170
+ spaceKey: runtime.spaceKey
3171
+ });
3172
+ const space = useSpace2(spaceKey);
3173
+ useEffect6(() => {
3174
+ return runtime.layoutUpdate.on((request) => setLayout(request));
3175
+ }, [
3176
+ runtime
3177
+ ]);
3178
+ useEffect6(() => {
3179
+ if (layout === ShellLayout.SPACE && !space) {
3180
+ log11.warn("No space found for shell space invitations.", void 0, {
3181
+ F: __dxlog_file11,
3182
+ L: 30,
3183
+ S: void 0,
3184
+ C: (f, a) => f(...a)
3185
+ });
3186
+ const timeout = setTimeout(async () => {
3187
+ await runtime.setAppContext({
3188
+ display: ShellDisplay.NONE
3189
+ });
3190
+ runtime.setLayout({
3191
+ layout: ShellLayout.DEFAULT
3192
+ });
3193
+ });
3194
+ return () => clearTimeout(timeout);
3195
+ }
3196
+ }, [
3197
+ runtime,
3198
+ layout,
3199
+ space
3200
+ ]);
3201
+ switch (layout) {
3202
+ case ShellLayout.INITIALIZE_IDENTITY:
3203
+ return /* @__PURE__ */ React40.createElement(JoinDialog, {
3204
+ mode: "halo-only",
3205
+ initialInvitationCode: invitationCode,
3206
+ onDone: () => {
3207
+ void runtime.setAppContext({
3208
+ display: ShellDisplay.NONE
3209
+ });
3210
+ runtime.setLayout({
3211
+ layout: ShellLayout.DEFAULT
3212
+ });
3213
+ }
3214
+ });
3215
+ case ShellLayout.IDENTITY:
3216
+ case ShellLayout.SHARE_IDENTITY:
3217
+ case ShellLayout.EDIT_PROFILE:
3218
+ return /* @__PURE__ */ React40.createElement(IdentityDialog, {
3219
+ createInvitationUrl: (invitationCode2) => `${origin}?deviceInvitationCode=${invitationCode2}`,
3220
+ onDone: async () => {
3221
+ await runtime.setAppContext({
3222
+ display: ShellDisplay.NONE
3223
+ });
3224
+ runtime.setLayout({
3225
+ layout: ShellLayout.DEFAULT
3226
+ });
3227
+ }
3228
+ });
3229
+ case ShellLayout.SPACE:
3230
+ return space ? /* @__PURE__ */ React40.createElement(SpaceDialog, {
3231
+ space,
3232
+ createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
3233
+ onDone: async () => {
3234
+ await runtime.setAppContext({
3235
+ display: ShellDisplay.NONE
3236
+ });
3237
+ runtime.setLayout({
3238
+ layout: ShellLayout.DEFAULT
3239
+ });
3240
+ }
3241
+ }) : null;
3242
+ case ShellLayout.JOIN_SPACE:
3243
+ return /* @__PURE__ */ React40.createElement(JoinDialog, {
3244
+ initialInvitationCode: invitationCode,
3245
+ onDone: async (result) => {
3246
+ await runtime.setAppContext({
3247
+ display: ShellDisplay.NONE,
3248
+ spaceKey: result?.spaceKey ?? void 0
3249
+ });
3250
+ runtime.setLayout({
3251
+ layout: ShellLayout.DEFAULT
3252
+ });
3253
+ },
3254
+ onExit: async () => {
3255
+ await runtime.setAppContext({
3256
+ display: ShellDisplay.NONE
3257
+ });
3258
+ runtime.setLayout({
3259
+ layout: ShellLayout.DEFAULT
3260
+ });
3261
+ }
3262
+ });
3263
+ default:
3264
+ return null;
3265
+ }
3266
+ };
3267
+
3268
+ // packages/sdk/shell/src/translations/locales/en-US.ts
3269
+ var en_US_exports = {};
3270
+ __export(en_US_exports, {
3271
+ os: () => os
3272
+ });
3273
+ var os = {
3274
+ "manage profile label": "Manage identity",
3275
+ "identity offline description": "Offline",
3276
+ "sidebar label": "DXOS sidebar",
3277
+ "copy invitation code label": "Copy URL",
3278
+ "copy invitation code success label": "Copied",
3279
+ "open share panel label": "View QR code",
3280
+ "joining space heading": "Joining space",
3281
+ "join space heading": "Enter space invitation",
3282
+ "halo heading": "Initialize device identity",
3283
+ "exit label": "Exit",
3284
+ "identity selector title": "Join as",
3285
+ "identity radio group title": "Select an identity you\u2019ve associated with this device already",
3286
+ "add identity label": "Add",
3287
+ "continue label": "Continue",
3288
+ "back label": "Back",
3289
+ "next label": "Next",
3290
+ "close label": "Close",
3291
+ "auth choices label": "Choose an identity",
3292
+ "create identity label": "Create an identity",
3293
+ "create identity description": "Create a new identity.",
3294
+ "recover identity label": "Use a seed phrase",
3295
+ "recover identity description": "Enter your seed phrase to log in manually.",
3296
+ "join identity label": "Use another device",
3297
+ "join identity description": "Add this device to an identity you\u2019re already logged into on another device.",
3298
+ "deselect identity label": "Back to identities",
3299
+ "addition method chooser title": "An identity is required to continue",
3300
+ "new identity input label": "Set display name",
3301
+ "recover identity input label": "Type or paste your seed phrase",
3302
+ "failed to create identity message": "Failed to create an identity.",
3303
+ "failed to recover identity message": "Failed to recover an identity from the provided seed phrase.",
3304
+ "failed to authenticate message": "Incorrect PIN.",
3305
+ "identity added label": "Created identity & added to this device:",
3306
+ "join space as identity heading": "<part>as </part><part><icon/><label>{{labelValue}}</label></part>",
3307
+ "error status label": "Failed",
3308
+ "timeout status label": "Timed out",
3309
+ "cancelled status label": "Cancelled",
3310
+ "init status label": "Ready to connect",
3311
+ "connecting status label": "Connecting\u2026",
3312
+ "connected status label": "Enter confirmation PIN",
3313
+ "authenticating status label": "Enter confirmation PIN",
3314
+ "success status label": "Success",
3315
+ "connect label": "Connect",
3316
+ "reconnect label": "Reconnect",
3317
+ "cancel label": "Cancel",
3318
+ "done label": "Done",
3319
+ "reset label": "Start over",
3320
+ "auth code input label": "Enter the verification code",
3321
+ "invitation input label": "Paste an invitation code or URL",
3322
+ "create device invitation label": "Add device",
3323
+ "create space invitation label": "Invite",
3324
+ "qr label": "Scan to accept invitation",
3325
+ "empty invitations message": "No pending invitations",
3326
+ "empty device list message": "No devices authenticated other than this device.",
3327
+ "show all spaces label": "All spaces",
3328
+ "all spaces label": "All spaces",
3329
+ "create space label": "Create a new space",
3330
+ "join space label": "Join a space",
3331
+ "show current space label": "Current space",
3332
+ "view space invitations label": "View space invitations",
3333
+ "toggle sidebar label": "Open/close sidebar",
3334
+ "open sidebar label": "Open sidebar",
3335
+ "close sidebar label": "Close sidebar",
3336
+ "welcome message": "Welcome",
3337
+ "selecting identity heading": "Selecting identity",
3338
+ "devices heading": "Devices",
3339
+ "identity heading": "Profile settings",
3340
+ "choose devices label": "Add device",
3341
+ "choose profile label": "Edit profile",
3342
+ "choose sign out label": "Sign out",
3343
+ "empty space members message": "There is nobody in this space yet.",
3344
+ "back to all invitations label": "Back to all invitations",
3345
+ "invitation heading": "Invitation",
3346
+ "invitation list heading": "Invitations",
3347
+ "device invitation list heading": "Pending device invitations",
3348
+ "space invitation list heading": "Pending invitations",
3349
+ "device list heading": "Devices",
3350
+ "space member list heading": "Members",
3351
+ "space panel heading": "Space membership",
3352
+ "auth code message": "Enter the following auth code on the joining device.",
3353
+ "display name input label": "Display name",
3354
+ "display name input placeholder": "Enter a display name",
3355
+ "invite one label": "Invite one",
3356
+ "invite one description": "Only one user may join.",
3357
+ "invite one qr label": "Single-use",
3358
+ "invite one list item label": "Active single-use invitation",
3359
+ "invite many label": "Invite many",
3360
+ "invite many description": "Anyone with the link can join.",
3361
+ "invite many qr label": "Multiple-use",
3362
+ "invite many list item label": "Active multiple-use invitation",
3363
+ "invite options label": "Change the active invite option.",
3364
+ "confirm label": "Confirm",
3365
+ "reset identity input label": "This will clear this device and all associated data. Type {{confirmationValue}} and confirm to continue.",
3366
+ "failed to reset identity message": "Failed to reset identity.",
3367
+ "confirmation value": "CONFIRM"
3368
+ };
3369
+
3370
+ // packages/sdk/shell/src/translations/index.ts
3371
+ var osTranslations = {
3372
+ "en-US": en_US_exports
3373
+ };
3374
+
3375
+ // packages/sdk/shell/src/composites/Shell/run-shell.tsx
3376
+ var runShell = async (config = new Config()) => {
3377
+ const services = new ClientServicesProxy(createIFramePort({
3378
+ channel: DEFAULT_CLIENT_CHANNEL
3379
+ }));
3380
+ const client = new Client({
3381
+ config,
3382
+ services
3383
+ });
3384
+ const runtime = new ShellRuntimeImpl(createIFramePort({
3385
+ channel: DEFAULT_SHELL_CHANNEL
3386
+ }));
3387
+ await Promise.all([
3388
+ runtime.open(),
3389
+ client.initialize()
3390
+ ]);
3391
+ createRoot(document.getElementById("root")).render(/* @__PURE__ */ React41.createElement(StrictMode, null, /* @__PURE__ */ React41.createElement(ThemeProvider, {
3392
+ tx: defaultTx,
3393
+ resourceExtensions: [
3394
+ osTranslations
3395
+ ]
3396
+ }, /* @__PURE__ */ React41.createElement(ClientContext.Provider, {
3397
+ value: {
3398
+ client,
3399
+ status: SystemStatus.ACTIVE
3400
+ }
3401
+ }, /* @__PURE__ */ React41.createElement(ClipboardProvider, null, /* @__PURE__ */ React41.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React41.createElement(Shell, {
3402
+ runtime,
3403
+ origin: location.origin
3404
+ })))))));
3405
+ };
3406
+
3407
+ // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3408
+ import React42, { createContext as createContext2, useCallback as useCallback8, useContext as useContext2, useEffect as useEffect7, useMemo as useMemo6, useState as useState10 } from "react";
3409
+ import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient7 } from "@dxos/react-client";
3410
+ import { useIdentity as useIdentity3 } from "@dxos/react-client/halo";
3411
+ import { mx as mx22 } from "@dxos/react-ui-theme";
3412
+
3413
+ // packages/sdk/shell/src/composites/Shell/memory-shell-runtime.ts
3414
+ import { Event } from "@dxos/async";
3415
+ import { ShellLayout as ShellLayout2 } from "@dxos/react-client";
3416
+ var MemoryShellRuntime = class {
3417
+ constructor({ layout, invitationCode, spaceKey } = {}) {
3418
+ this.layoutUpdate = new Event();
3419
+ this.contextUpdate = new Event();
3420
+ this._layout = layout ?? ShellLayout2.DEFAULT;
3421
+ this._invitationCode = invitationCode;
3422
+ this._spaceKey = spaceKey;
3423
+ }
3424
+ get layout() {
3425
+ return this._layout;
3426
+ }
3427
+ get invitationCode() {
3428
+ return this._invitationCode;
3429
+ }
3430
+ get spaceKey() {
3431
+ return this._spaceKey;
3432
+ }
3433
+ setLayout(request) {
3434
+ this._layout = request.layout;
3435
+ this._invitationCode = request.invitationCode;
3436
+ this._spaceKey = request.spaceKey;
3437
+ this.layoutUpdate.emit(request);
3438
+ }
3439
+ async setAppContext(context) {
3440
+ this.contextUpdate.emit(context);
3441
+ }
3442
+ };
3443
+
3444
+ // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3445
+ var ShellContext = /* @__PURE__ */ createContext2({});
3446
+ var useShell = () => {
3447
+ const client = useClient7();
3448
+ const { runtime, setDisplay } = useContext2(ShellContext);
3449
+ const setLayout = async (layout, options) => {
3450
+ if (runtime) {
3451
+ if (layout === ShellLayout3.DEFAULT) {
3452
+ setDisplay?.(ShellDisplay2.NONE);
3453
+ } else {
3454
+ setDisplay?.(ShellDisplay2.FULLSCREEN);
3455
+ }
3456
+ runtime.setLayout({
3457
+ layout,
3458
+ ...options
3459
+ });
3460
+ }
3461
+ await client.shell.open(layout, options);
3462
+ };
3463
+ return {
3464
+ setLayout
3465
+ };
3466
+ };
3467
+ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoinedSpace, children }) => {
3468
+ const client = useClient7();
3469
+ const identity = useIdentity3();
3470
+ const [display, setDisplay] = useState10(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3471
+ const shellRuntime = useMemo6(() => {
3472
+ if (client.config.get("runtime.app.env.DX_VAULT") !== "false") {
3473
+ return;
3474
+ }
3475
+ if (spaceInvitationCode) {
3476
+ return new MemoryShellRuntime({
3477
+ layout: ShellLayout3.JOIN_SPACE,
3478
+ invitationCode: spaceInvitationCode
3479
+ });
3480
+ }
3481
+ if (deviceInvitationCode) {
3482
+ return new MemoryShellRuntime({
3483
+ layout: ShellLayout3.INITIALIZE_IDENTITY,
3484
+ invitationCode: deviceInvitationCode
3485
+ });
3486
+ }
3487
+ return new MemoryShellRuntime({
3488
+ layout: identity ? ShellLayout3.DEFAULT : ShellLayout3.INITIALIZE_IDENTITY
3489
+ });
3490
+ }, [
3491
+ client,
3492
+ identity,
3493
+ spaceInvitationCode,
3494
+ deviceInvitationCode
3495
+ ]);
3496
+ const handleKeyDown = useCallback8((event) => {
3497
+ if (!space || !shellRuntime) {
3498
+ return;
3499
+ }
3500
+ const modifier = event.ctrlKey || event.metaKey;
3501
+ if (event.key === ">" && event.shiftKey && modifier) {
3502
+ shellRuntime.setLayout({
3503
+ layout: ShellLayout3.SHARE_IDENTITY
3504
+ });
3505
+ setDisplay(ShellDisplay2.FULLSCREEN);
3506
+ } else if (event.key === "." && modifier) {
3507
+ shellRuntime.setLayout({
3508
+ layout: ShellLayout3.SPACE,
3509
+ spaceKey: space.key
3510
+ });
3511
+ setDisplay(ShellDisplay2.FULLSCREEN);
3512
+ }
3513
+ }, [
3514
+ space,
3515
+ shellRuntime
3516
+ ]);
3517
+ useEffect7(() => {
3518
+ if (!shellRuntime) {
3519
+ return;
3520
+ }
3521
+ window.addEventListener("keydown", handleKeyDown);
3522
+ return () => window.removeEventListener("keydown", handleKeyDown);
3523
+ }, [
3524
+ shellRuntime,
3525
+ handleKeyDown
3526
+ ]);
3527
+ useEffect7(() => {
3528
+ if (!shellRuntime) {
3529
+ return;
3530
+ }
3531
+ return shellRuntime.contextUpdate.on(({ display: display2, spaceKey }) => {
3532
+ if (display2) {
3533
+ setDisplay(display2);
3534
+ }
3535
+ onJoinedSpace?.(spaceKey);
3536
+ });
3537
+ }, [
3538
+ shellRuntime
3539
+ ]);
3540
+ return /* @__PURE__ */ React42.createElement(React42.Fragment, null, shellRuntime && /* @__PURE__ */ React42.createElement("div", {
3541
+ className: mx22(display === ShellDisplay2.NONE ? "hidden" : "")
3542
+ }, /* @__PURE__ */ React42.createElement(Shell, {
3543
+ runtime: shellRuntime,
3544
+ origin: window.location.origin
3545
+ })), /* @__PURE__ */ React42.createElement(ShellContext.Provider, {
3546
+ value: {
3547
+ runtime: shellRuntime,
3548
+ setDisplay
3549
+ }
3550
+ }, children));
3551
+ };
3552
+ export {
3553
+ Action,
3554
+ Actions,
3555
+ AuthCode,
3556
+ BifurcatedAction,
3557
+ Centered,
3558
+ ClipboardContext,
3559
+ ClipboardProvider,
3560
+ CloseButton,
3561
+ CompoundButton,
3562
+ CopyButton,
3563
+ CopyButtonIconOnly,
3564
+ DeviceList,
3565
+ Emoji,
3566
+ Heading,
3567
+ IdentityDialog,
3568
+ IdentityListItem,
3569
+ IdentityPanel,
3570
+ IdentityPanelImpl,
3571
+ Input,
3572
+ InvitationList,
3573
+ InvitationListContainer,
3574
+ InvitationListItem,
3575
+ InvitationListItemImpl,
3576
+ JoinDialog,
3577
+ JoinPanel,
3578
+ JoinPanelImpl,
3579
+ Label,
3580
+ Shell,
3581
+ ShellContext,
3582
+ ShellProvider,
3583
+ SpaceDialog,
3584
+ SpaceListItem,
3585
+ SpaceMemberList,
3586
+ SpaceMemberListImpl,
3587
+ SpacePanel,
3588
+ SpacePanelImpl,
3589
+ StepHeading,
3590
+ Viewport,
3591
+ activeBgColor,
3592
+ activeStrokeColor,
3593
+ activeTextColor,
3594
+ cancelledBgColor,
3595
+ cancelledStrokeColor,
3596
+ cancelledTextColor,
3597
+ createViewportScope,
3598
+ errorBgColor,
3599
+ errorStrokeColor,
3600
+ errorTextColor,
3601
+ inactiveBgColor,
3602
+ inactiveStrokeColor,
3603
+ inactiveTextColor,
3604
+ osTranslations,
3605
+ resolvedBgColor,
3606
+ resolvedStrokeColor,
3607
+ resolvedTextColor,
3608
+ runShell,
3609
+ stepStyles,
3610
+ successBgColor,
3611
+ successStrokeColor,
3612
+ successTextColor,
3613
+ useClipboardContext,
3614
+ useShell,
3615
+ useViewportContext
3616
+ };
3617
+ //# sourceMappingURL=react.mjs.map