@dxos/react-ui 0.1.25 → 0.1.27-next.4235176

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 (142) hide show
  1. package/dist/lib/browser/index.mjs +1021 -472
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/IdentityList/DeviceList.d.ts +7 -0
  5. package/dist/types/src/components/IdentityList/DeviceList.d.ts.map +1 -0
  6. package/dist/types/src/components/IdentityList/IdentityListItem.d.ts +4 -3
  7. package/dist/types/src/components/IdentityList/IdentityListItem.d.ts.map +1 -1
  8. package/dist/types/src/components/IdentityList/IdentityListItem.stories.d.ts +3 -2
  9. package/dist/types/src/components/IdentityList/IdentityListItem.stories.d.ts.map +1 -1
  10. package/dist/types/src/components/IdentityList/SpaceMemberList.d.ts +3 -2
  11. package/dist/types/src/components/IdentityList/SpaceMemberList.d.ts.map +1 -1
  12. package/dist/types/src/components/IdentityList/SpaceMemberListContainer.d.ts +3 -1
  13. package/dist/types/src/components/IdentityList/SpaceMemberListContainer.d.ts.map +1 -1
  14. package/dist/types/src/components/IdentityList/index.d.ts +1 -0
  15. package/dist/types/src/components/IdentityList/index.d.ts.map +1 -1
  16. package/dist/types/src/components/InvitationList/InvitationList.d.ts.map +1 -1
  17. package/dist/types/src/components/InvitationList/InvitationListItem.d.ts.map +1 -1
  18. package/dist/types/src/components/InvitationList/InvitationStatusAvatar.d.ts +6 -1
  19. package/dist/types/src/components/InvitationList/InvitationStatusAvatar.d.ts.map +1 -1
  20. package/dist/types/src/components/InvitationList/InvitationStatusAvatar.stories.d.ts +1 -1
  21. package/dist/types/src/components/SpaceList/SpaceListItem.d.ts +7 -0
  22. package/dist/types/src/components/SpaceList/SpaceListItem.d.ts.map +1 -0
  23. package/dist/types/src/components/SpaceList/index.d.ts +2 -0
  24. package/dist/types/src/components/SpaceList/index.d.ts.map +1 -0
  25. package/dist/types/src/components/index.d.ts +1 -0
  26. package/dist/types/src/components/index.d.ts.map +1 -1
  27. package/dist/types/src/composites/DevicesDialog/DevicesDialog.d.ts +6 -0
  28. package/dist/types/src/composites/DevicesDialog/DevicesDialog.d.ts.map +1 -0
  29. package/dist/types/src/composites/DevicesDialog/index.d.ts +2 -0
  30. package/dist/types/src/composites/DevicesDialog/index.d.ts.map +1 -0
  31. package/dist/types/src/composites/IdentityPopover/IdentityPopover.d.ts +2 -2
  32. package/dist/types/src/composites/IdentityPopover/IdentityPopover.d.ts.map +1 -1
  33. package/dist/types/src/composites/JoinDialog/JoinDialog.d.ts +1 -1
  34. package/dist/types/src/composites/JoinDialog/JoinDialog.d.ts.map +1 -1
  35. package/dist/types/src/composites/JoinDialog/JoinDialog.stories.d.ts +2 -2
  36. package/dist/types/src/composites/JoinDialog/JoinDialog.stories.d.ts.map +1 -1
  37. package/dist/types/src/composites/Shell/Shell.d.ts +6 -0
  38. package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -0
  39. package/dist/types/src/composites/Shell/index.d.ts +2 -0
  40. package/dist/types/src/composites/Shell/index.d.ts.map +1 -0
  41. package/dist/types/src/composites/SpaceDialog/SpaceDialog.d.ts +6 -0
  42. package/dist/types/src/composites/SpaceDialog/SpaceDialog.d.ts.map +1 -0
  43. package/dist/types/src/composites/SpaceDialog/index.d.ts +2 -0
  44. package/dist/types/src/composites/SpaceDialog/index.d.ts.map +1 -0
  45. package/dist/types/src/composites/index.d.ts +2 -0
  46. package/dist/types/src/composites/index.d.ts.map +1 -1
  47. package/dist/types/src/layouts/PanelAlertDialog/PanelAlertDialog.d.ts.map +1 -1
  48. package/dist/types/src/layouts/PanelDialog/PanelDialog.d.ts +14 -0
  49. package/dist/types/src/layouts/PanelDialog/PanelDialog.d.ts.map +1 -0
  50. package/dist/types/src/layouts/PanelDialog/index.d.ts +2 -0
  51. package/dist/types/src/layouts/PanelDialog/index.d.ts.map +1 -0
  52. package/dist/types/src/layouts/index.d.ts +1 -0
  53. package/dist/types/src/layouts/index.d.ts.map +1 -1
  54. package/dist/types/src/panels/DevicesPanel/DevicesPanel.d.ts +10 -0
  55. package/dist/types/src/panels/DevicesPanel/DevicesPanel.d.ts.map +1 -0
  56. package/dist/types/src/panels/DevicesPanel/index.d.ts +2 -0
  57. package/dist/types/src/panels/DevicesPanel/index.d.ts.map +1 -0
  58. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts +2 -2
  59. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  60. package/dist/types/src/panels/JoinPanel/JoinHeading.d.ts +3 -0
  61. package/dist/types/src/panels/JoinPanel/JoinHeading.d.ts.map +1 -1
  62. package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts +1 -1
  63. package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts.map +1 -1
  64. package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts +6 -5
  65. package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts.map +1 -1
  66. package/dist/types/src/panels/JoinPanel/view-states/AdditionMethodSelector.d.ts +2 -2
  67. package/dist/types/src/panels/JoinPanel/view-states/AdditionMethodSelector.d.ts.map +1 -1
  68. package/dist/types/src/panels/JoinPanel/view-states/IdentityAdded.d.ts +12 -4
  69. package/dist/types/src/panels/JoinPanel/view-states/IdentityAdded.d.ts.map +1 -1
  70. package/dist/types/src/panels/JoinPanel/view-states/IdentityInput.d.ts.map +1 -1
  71. package/dist/types/src/panels/JoinPanel/view-states/IdentitySelector.d.ts +2 -2
  72. package/dist/types/src/panels/JoinPanel/view-states/IdentitySelector.d.ts.map +1 -1
  73. package/dist/types/src/panels/JoinPanel/view-states/InvitationAccepted.d.ts.map +1 -1
  74. package/dist/types/src/panels/JoinPanel/view-states/InvitationAuthenticator.d.ts.map +1 -1
  75. package/dist/types/src/panels/JoinPanel/view-states/InvitationInput.d.ts.map +1 -1
  76. package/dist/types/src/panels/JoinPanel/view-states/InvitationRescuer.d.ts.map +1 -1
  77. package/dist/types/src/panels/JoinPanel/view-states/ViewState.d.ts +2 -2
  78. package/dist/types/src/panels/JoinPanel/view-states/ViewState.d.ts.map +1 -1
  79. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts +12 -0
  80. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts.map +1 -0
  81. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts +9 -0
  82. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts.map +1 -0
  83. package/dist/types/src/panels/SpacePanel/index.d.ts +2 -0
  84. package/dist/types/src/panels/SpacePanel/index.d.ts.map +1 -0
  85. package/dist/types/src/panels/index.d.ts +2 -0
  86. package/dist/types/src/panels/index.d.ts.map +1 -1
  87. package/dist/types/src/styles/dialogStyles.d.ts +3 -0
  88. package/dist/types/src/styles/dialogStyles.d.ts.map +1 -0
  89. package/dist/types/src/styles/index.d.ts +1 -0
  90. package/dist/types/src/styles/index.d.ts.map +1 -1
  91. package/dist/types/src/translations/locales/en-US.d.ts +12 -1
  92. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  93. package/package.json +12 -11
  94. package/src/components/IdentityList/DeviceList.tsx +31 -0
  95. package/src/components/IdentityList/IdentityListItem.tsx +17 -5
  96. package/src/components/IdentityList/SpaceMemberList.tsx +10 -8
  97. package/src/components/IdentityList/SpaceMemberListContainer.tsx +7 -6
  98. package/src/components/IdentityList/index.ts +1 -0
  99. package/src/components/InvitationList/InvitationList.stories.tsx +1 -1
  100. package/src/components/InvitationList/InvitationList.tsx +12 -6
  101. package/src/components/InvitationList/InvitationListItem.tsx +30 -25
  102. package/src/components/InvitationList/InvitationStatusAvatar.tsx +10 -5
  103. package/src/components/SpaceList/SpaceListItem.tsx +32 -0
  104. package/src/components/SpaceList/index.ts +5 -0
  105. package/src/components/index.ts +1 -0
  106. package/src/composites/DevicesDialog/DevicesDialog.tsx +38 -0
  107. package/src/composites/DevicesDialog/index.ts +5 -0
  108. package/src/composites/IdentityPopover/IdentityPopover.tsx +3 -3
  109. package/src/composites/JoinDialog/JoinDialog.stories.tsx +59 -58
  110. package/src/composites/JoinDialog/JoinDialog.tsx +3 -1
  111. package/src/composites/Shell/Shell.tsx +86 -0
  112. package/src/composites/Shell/index.ts +5 -0
  113. package/src/composites/SpaceDialog/SpaceDialog.tsx +38 -0
  114. package/src/composites/SpaceDialog/index.ts +5 -0
  115. package/src/composites/index.ts +3 -0
  116. package/src/layouts/PanelAlertDialog/PanelAlertDialog.tsx +4 -8
  117. package/src/layouts/PanelDialog/PanelDialog.tsx +39 -0
  118. package/src/layouts/PanelDialog/index.ts +5 -0
  119. package/src/layouts/PanelSidebar/PanelSidebar.tsx +1 -1
  120. package/src/layouts/index.ts +1 -0
  121. package/src/panels/DevicesPanel/DevicesPanel.tsx +101 -0
  122. package/src/panels/DevicesPanel/index.ts +5 -0
  123. package/src/panels/IdentityPanel/IdentityPanel.tsx +5 -5
  124. package/src/panels/JoinPanel/JoinHeading.tsx +38 -16
  125. package/src/panels/JoinPanel/JoinPanel.tsx +35 -14
  126. package/src/panels/JoinPanel/JoinPanelProps.ts +6 -10
  127. package/src/panels/JoinPanel/view-states/AdditionMethodSelector.tsx +8 -2
  128. package/src/panels/JoinPanel/view-states/IdentityAdded.tsx +67 -28
  129. package/src/panels/JoinPanel/view-states/IdentityInput.tsx +9 -2
  130. package/src/panels/JoinPanel/view-states/IdentitySelector.tsx +8 -6
  131. package/src/panels/JoinPanel/view-states/InvitationAccepted.tsx +1 -0
  132. package/src/panels/JoinPanel/view-states/InvitationAuthenticator.tsx +4 -1
  133. package/src/panels/JoinPanel/view-states/InvitationInput.tsx +8 -1
  134. package/src/panels/JoinPanel/view-states/InvitationRescuer.tsx +4 -1
  135. package/src/panels/JoinPanel/view-states/ViewState.tsx +3 -3
  136. package/src/panels/SpacePanel/SpacePanel.stories.tsx +53 -0
  137. package/src/panels/SpacePanel/SpacePanel.tsx +90 -0
  138. package/src/panels/SpacePanel/index.ts +5 -0
  139. package/src/panels/index.ts +2 -0
  140. package/src/styles/dialogStyles.ts +8 -0
  141. package/src/styles/index.ts +1 -0
  142. package/src/translations/locales/en-US.ts +14 -3
@@ -4,10 +4,13 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
+ // packages/apps/patterns/react-ui/src/components/IdentityList/DeviceList.tsx
8
+ import React2 from "react";
9
+
7
10
  // packages/apps/patterns/react-ui/src/components/IdentityList/IdentityListItem.tsx
8
11
  import React from "react";
9
12
  import { SpaceMember } from "@dxos/client";
10
- import { Avatar, useTranslation } from "@dxos/react-components";
13
+ import { Avatar, mx, useTranslation } from "@dxos/react-components";
11
14
  function _extends() {
12
15
  _extends = Object.assign || function(target) {
13
16
  for (var i = 1; i < arguments.length; i++) {
@@ -22,18 +25,20 @@ function _extends() {
22
25
  };
23
26
  return _extends.apply(this, arguments);
24
27
  }
25
- var IdentityListItem = ({ identity, presence }) => {
26
- var _a;
28
+ var IdentityListItem = ({ identity, presence, onClick }) => {
29
+ var _a, _b;
27
30
  const { t } = useTranslation("os");
28
31
  return /* @__PURE__ */ React.createElement("li", {
29
- className: "flex gap-2 items-center"
32
+ className: mx("flex gap-2 items-center", onClick && "cursor-pointer"),
33
+ onClick: () => onClick == null ? void 0 : onClick(),
34
+ "data-testid": "identity-list-item"
30
35
  }, /* @__PURE__ */ React.createElement(Avatar, _extends({}, {
31
36
  variant: "circle",
32
37
  size: 9,
33
38
  fallbackValue: identity.identityKey.toHex(),
34
39
  label: /* @__PURE__ */ React.createElement("p", {
35
40
  className: "text-sm truncate"
36
- }, (_a = identity.displayName) != null ? _a : identity.identityKey.truncate()),
41
+ }, (_b = (_a = identity.profile) == null ? void 0 : _a.displayName) != null ? _b : identity.identityKey.truncate()),
37
42
  ...presence === SpaceMember.PresenceState.OFFLINE && {
38
43
  status: "inactive",
39
44
  description: /* @__PURE__ */ React.createElement("p", {
@@ -54,38 +59,64 @@ var IdentityListItem = ({ identity, presence }) => {
54
59
  })));
55
60
  };
56
61
 
57
- // packages/apps/patterns/react-ui/src/components/IdentityList/SpaceMemberList.tsx
58
- import React2 from "react";
59
- var SpaceMemberList = ({ spaceMembers }) => {
62
+ // packages/apps/patterns/react-ui/src/components/IdentityList/DeviceList.tsx
63
+ var DeviceList = ({ devices, onSelect }) => {
60
64
  return /* @__PURE__ */ React2.createElement("ul", {
61
65
  className: "flex flex-col gap-2"
62
- }, spaceMembers.filter((spaceMember) => spaceMember.profile).map((spaceMember) => {
66
+ }, devices.map((device) => {
67
+ var _a;
68
+ const identity = {
69
+ identityKey: device.deviceKey,
70
+ profile: {
71
+ displayName: (_a = device.profile) == null ? void 0 : _a.displayName
72
+ }
73
+ };
63
74
  return /* @__PURE__ */ React2.createElement(IdentityListItem, {
64
- key: spaceMember.identityKey.toHex(),
65
- identity: spaceMember.profile,
66
- presence: spaceMember.presence
75
+ key: device.deviceKey.toHex(),
76
+ identity,
77
+ onClick: onSelect && (() => onSelect(device))
78
+ });
79
+ }));
80
+ };
81
+
82
+ // packages/apps/patterns/react-ui/src/components/IdentityList/SpaceMemberList.tsx
83
+ import React3 from "react";
84
+ var SpaceMemberList = ({ members, onSelect }) => {
85
+ return /* @__PURE__ */ React3.createElement("ul", {
86
+ className: "flex flex-col gap-2"
87
+ }, members.filter((member) => member.identity).map((member) => {
88
+ return /* @__PURE__ */ React3.createElement(IdentityListItem, {
89
+ key: member.identity.identityKey.toHex(),
90
+ identity: member.identity,
91
+ presence: member.presence,
92
+ onClick: onSelect && (() => onSelect(member))
67
93
  });
68
94
  }));
69
95
  };
70
96
 
71
97
  // packages/apps/patterns/react-ui/src/components/IdentityList/SpaceMemberListContainer.tsx
72
- import React3, { useMemo } from "react";
98
+ import React4, { useMemo } from "react";
73
99
  import { useClient, useMembers } from "@dxos/react-client";
74
- var SpaceMemberListContainer = ({ spaceKey, includeSelf }) => {
100
+ var SpaceMemberListContainer = ({ spaceKey, includeSelf, onSelect }) => {
75
101
  const client = useClient();
76
102
  const allUnsortedMembers = useMembers(spaceKey);
77
- const spaceMembers = useMemo(() => includeSelf ? allUnsortedMembers.sort((a) => a.identityKey.equals(client.halo.profile.identityKey) ? -1 : 1) : allUnsortedMembers.filter((member) => !member.identityKey.equals(client.halo.profile.identityKey)), [
103
+ const members = useMemo(() => includeSelf ? allUnsortedMembers.sort((a) => a.identity.identityKey.equals(client.halo.identity.identityKey) ? -1 : 1) : allUnsortedMembers.filter((member) => !member.identity.identityKey.equals(client.halo.identity.identityKey)), [
78
104
  allUnsortedMembers
79
105
  ]);
80
- return /* @__PURE__ */ React3.createElement(SpaceMemberList, {
81
- spaceMembers
106
+ return /* @__PURE__ */ React4.createElement(SpaceMemberList, {
107
+ members,
108
+ onSelect
82
109
  });
83
110
  };
84
111
 
85
112
  // packages/apps/patterns/react-ui/src/components/InvitationList/InvitationStatusAvatar.tsx
86
- import React4 from "react";
113
+ import React5 from "react";
87
114
  import { Invitation as Invitation3 } from "@dxos/client";
88
- import { getSize } from "@dxos/react-components";
115
+ import { getSize, mx as mx2 } from "@dxos/react-components";
116
+
117
+ // packages/apps/patterns/react-ui/src/styles/dialogStyles.ts
118
+ var defaultOverlay = "fixed inset-0 backdrop-blur z-50 overflow-auto grid place-items-center p-2 md:p-4 lg:p-8";
119
+ var defaultDialogContent = "is-full min-is-[260px] max-is-[320px] rounded-md shadow-md backdrop-blur-md";
89
120
 
90
121
  // packages/apps/patterns/react-ui/src/styles/panelStyles.ts
91
122
  var defaultSurface = "bg-neutral-50/[.72] dark:bg-neutral-950/[.72]";
@@ -166,7 +197,7 @@ function _extends2() {
166
197
  return _extends2.apply(this, arguments);
167
198
  }
168
199
  var svgSize = 32;
169
- var strokeWidth = 4;
200
+ var strokeWidth = 5;
170
201
  var radius = (svgSize - strokeWidth) / 2;
171
202
  var circumference = Math.PI * 2 * radius;
172
203
  var gap = circumference / 12;
@@ -179,19 +210,20 @@ var circleProps = {
179
210
  cx: svgSize / 2,
180
211
  cy: svgSize / 2,
181
212
  r: radius,
182
- strokeWidth: 4,
213
+ strokeWidth,
183
214
  strokeDasharray: `${segment - gap} ${2 * segment + gap}`
184
215
  };
185
- var InvitationStatusAvatar = ({ size = 10, status, haltedAt }) => {
216
+ var InvitationStatusAvatar = ({ size = 10, status, haltedAt, slots = {} }) => {
217
+ var _a;
186
218
  const resolvedColor = resolvedStrokeColor(status);
187
219
  const halted = status === Invitation3.State.CANCELLED || status === Invitation3.State.TIMEOUT || status === Invitation3.State.ERROR;
188
220
  const cursor = invitationStatusValue.get(halted ? haltedAt : status);
189
- return /* @__PURE__ */ React4.createElement("svg", {
221
+ return /* @__PURE__ */ React5.createElement("svg", _extends2({}, slots.svg, {
190
222
  viewBox: `0 0 ${svgSize} ${svgSize}`,
191
- className: getSize(size)
192
- }, [
223
+ className: mx2(getSize(size), (_a = slots.svg) == null ? void 0 : _a.className)
224
+ }), [
193
225
  ...Array(nSegments)
194
- ].map((_, index) => /* @__PURE__ */ React4.createElement("circle", _extends2({
226
+ ].map((_, index) => /* @__PURE__ */ React5.createElement("circle", _extends2({
195
227
  key: index
196
228
  }, circleProps, {
197
229
  strokeDashoffset: index * segment + baseOffset,
@@ -203,9 +235,9 @@ var InvitationStatusAvatar = ({ size = 10, status, haltedAt }) => {
203
235
  import * as AccordionPrimitive from "@radix-ui/react-accordion";
204
236
  import { Copy, ProhibitInset, QrCode, X } from "phosphor-react";
205
237
  import { QRCodeSVG } from "qrcode.react";
206
- import React5, { useCallback } from "react";
238
+ import React6, { useCallback } from "react";
207
239
  import { useInvitationStatus } from "@dxos/react-client";
208
- import { Button, getSize as getSize2, mx, useTranslation as useTranslation2 } from "@dxos/react-components";
240
+ import { Button, getSize as getSize2, mx as mx3, useId, useTranslation as useTranslation2 } from "@dxos/react-components";
209
241
  function _extends3() {
210
242
  _extends3 = Object.assign || function(target) {
211
243
  for (var i = 1; i < arguments.length; i++) {
@@ -223,85 +255,96 @@ function _extends3() {
223
255
  var InvitationListItem = ({ invitation, value, onClickRemove, createInvitationUrl }) => {
224
256
  var _a;
225
257
  const { t } = useTranslation2("os");
258
+ const qrLabel = useId("qrLabel");
226
259
  const { cancel, status, haltedAt, invitationCode, authenticationCode } = useInvitationStatus(invitation);
227
260
  const statusValue = (_a = invitationStatusValue.get(status)) != null ? _a : 0;
228
261
  const isCancellable = statusValue < 4 && statusValue >= 0;
229
262
  const showShare = statusValue < 3 && statusValue >= 0;
230
- const showPin = statusValue === 3;
263
+ const showAuthCode = statusValue === 3;
231
264
  const handleClickRemove = useCallback(() => onClickRemove(invitation), [
232
265
  invitation,
233
266
  onClickRemove
234
267
  ]);
235
268
  const invitationUrl = invitationCode && createInvitationUrl(invitationCode);
236
- const handleCLickCopy = useCallback(() => {
269
+ const handleClickCopy = useCallback(() => {
237
270
  if (invitationUrl) {
238
271
  void navigator.clipboard.writeText(invitationUrl);
239
272
  }
240
273
  }, [
241
274
  invitationUrl
242
275
  ]);
243
- return /* @__PURE__ */ React5.createElement(AccordionPrimitive.Item, {
276
+ return /* @__PURE__ */ React6.createElement(AccordionPrimitive.Item, {
244
277
  value
245
- }, /* @__PURE__ */ React5.createElement(AccordionPrimitive.Header, {
278
+ }, /* @__PURE__ */ React6.createElement(AccordionPrimitive.Header, {
246
279
  className: "flex gap-2 items-center"
247
- }, /* @__PURE__ */ React5.createElement(InvitationStatusAvatar, _extends3({}, {
280
+ }, /* @__PURE__ */ React6.createElement(InvitationStatusAvatar, _extends3({}, {
248
281
  status,
249
- haltedAt
250
- })), showShare && invitationUrl ? /* @__PURE__ */ React5.createElement(AccordionPrimitive.Trigger, {
282
+ haltedAt,
283
+ size: 8
284
+ })), showShare && invitationUrl ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(AccordionPrimitive.Trigger, {
251
285
  asChild: true
252
- }, /* @__PURE__ */ React5.createElement(Button, {
253
- className: "grow flex gap-1"
254
- }, /* @__PURE__ */ React5.createElement("span", null, t("open share panel label")), /* @__PURE__ */ React5.createElement(QrCode, {
286
+ }, /* @__PURE__ */ React6.createElement(Button, {
287
+ className: "grow flex gap-1",
288
+ "data-testid": "show-qrcode"
289
+ }, /* @__PURE__ */ React6.createElement("span", null, t("open share panel label")), /* @__PURE__ */ React6.createElement(QrCode, {
290
+ className: getSize2(4),
291
+ weight: "bold"
292
+ }))), /* @__PURE__ */ React6.createElement(Button, {
293
+ className: "flex gap-1",
294
+ onClick: handleClickCopy,
295
+ "data-testid": "copy-invitation"
296
+ }, /* @__PURE__ */ React6.createElement("span", {
297
+ className: "pli-1"
298
+ }, t("copy invitation code label")), /* @__PURE__ */ React6.createElement(Copy, {
255
299
  className: getSize2(4),
256
300
  weight: "bold"
257
- }))) : showPin ? /* @__PURE__ */ React5.createElement("p", {
301
+ }))) : showAuthCode ? /* @__PURE__ */ React6.createElement("p", {
258
302
  className: "grow text-xl text-center text-success-500 dark:text-success-300 font-mono"
259
- }, authenticationCode) : /* @__PURE__ */ React5.createElement("span", {
303
+ }, authenticationCode) : /* @__PURE__ */ React6.createElement("span", {
260
304
  role: "none",
261
305
  className: "grow"
262
- }), isCancellable ? /* @__PURE__ */ React5.createElement(Button, {
306
+ }), isCancellable ? /* @__PURE__ */ React6.createElement(Button, {
263
307
  variant: "ghost",
264
- compact: true,
265
308
  className: "flex gap-1",
266
- onClick: cancel
267
- }, /* @__PURE__ */ React5.createElement("span", {
309
+ onClick: cancel,
310
+ "data-testid": "cancel-invitation"
311
+ }, /* @__PURE__ */ React6.createElement("span", {
268
312
  className: "sr-only"
269
- }, t("cancel invitation label")), /* @__PURE__ */ React5.createElement(ProhibitInset, {
313
+ }, t("cancel invitation label")), /* @__PURE__ */ React6.createElement(ProhibitInset, {
270
314
  className: getSize2(4),
271
315
  weight: "bold"
272
- })) : /* @__PURE__ */ React5.createElement(Button, {
316
+ })) : /* @__PURE__ */ React6.createElement(Button, {
273
317
  variant: "ghost",
274
- compact: true,
275
318
  className: "flex gap-1",
276
- onClick: handleClickRemove
277
- }, /* @__PURE__ */ React5.createElement("span", {
319
+ onClick: handleClickRemove,
320
+ "data-testid": "remove-invitation"
321
+ }, /* @__PURE__ */ React6.createElement("span", {
278
322
  className: "sr-only"
279
- }, t("remove invitation label")), /* @__PURE__ */ React5.createElement(X, {
323
+ }, t("remove invitation label")), /* @__PURE__ */ React6.createElement(X, {
280
324
  className: getSize2(4),
281
325
  weight: "bold"
282
- }))), showShare && invitationUrl && /* @__PURE__ */ React5.createElement(AccordionPrimitive.Content, null, /* @__PURE__ */ React5.createElement(Button, {
283
- className: "flex gap-2 is-full p-2",
284
- onClick: handleCLickCopy
285
- }, /* @__PURE__ */ React5.createElement(QRCodeSVG, {
326
+ }))), showShare && invitationUrl && /* @__PURE__ */ React6.createElement(AccordionPrimitive.Content, {
327
+ className: "flex gap-2 is-full radix-state-open:p-1 items-center"
328
+ }, /* @__PURE__ */ React6.createElement(QRCodeSVG, {
286
329
  bgColor: "transparent",
287
330
  fgColor: "currentColor",
288
331
  value: invitationUrl,
289
- className: mx("grow aspect-square is-24 bs-auto")
290
- }), /* @__PURE__ */ React5.createElement("span", {
291
- className: "pli-1"
292
- }, t("copy invitation code label"), /* @__PURE__ */ React5.createElement(Copy, {
293
- className: mx(getSize2(4), "inline mis-1"),
294
- weight: "bold"
295
- })))));
332
+ className: mx3("grow-[2] aspect-square is-24 bs-auto"),
333
+ "aria-labelledby": qrLabel
334
+ }), /* @__PURE__ */ React6.createElement("span", {
335
+ className: "pli-1 flex-1 font-system-normal text-sm text-center",
336
+ id: qrLabel
337
+ }, t("qr label"))));
296
338
  };
297
339
 
298
340
  // packages/apps/patterns/react-ui/src/components/InvitationList/InvitationListContainer.tsx
299
- import React7, { useCallback as useCallback2 } from "react";
341
+ import React8, { useCallback as useCallback2 } from "react";
300
342
  import { useSpace, useSpaceInvitations } from "@dxos/react-client";
301
343
 
302
344
  // packages/apps/patterns/react-ui/src/components/InvitationList/InvitationList.tsx
303
345
  import { Root as AccordionRoot } from "@radix-ui/react-accordion";
304
- import React6 from "react";
346
+ import React7 from "react";
347
+ import { defaultDescription, DensityProvider, mx as mx4, useTranslation as useTranslation3 } from "@dxos/react-components";
305
348
  function _extends4() {
306
349
  _extends4 = Object.assign || function(target) {
307
350
  for (var i = 1; i < arguments.length; i++) {
@@ -317,18 +360,24 @@ function _extends4() {
317
360
  return _extends4.apply(this, arguments);
318
361
  }
319
362
  var InvitationList = ({ invitations, ...invitationProps }) => {
320
- return /* @__PURE__ */ React6.createElement(AccordionRoot, {
363
+ const { t } = useTranslation3("os");
364
+ return invitations.length ? /* @__PURE__ */ React7.createElement(AccordionRoot, {
321
365
  type: "single",
322
- collapsible: true
366
+ collapsible: true,
367
+ className: "flex flex-col gap-1"
368
+ }, /* @__PURE__ */ React7.createElement(DensityProvider, {
369
+ density: "fine"
323
370
  }, invitations.map((invitation, index) => {
324
371
  var _a, _b;
325
372
  const value = (_b = (_a = invitation.invitation) == null ? void 0 : _a.invitationId) != null ? _b : `inv_${index}`;
326
- return /* @__PURE__ */ React6.createElement(InvitationListItem, _extends4({
373
+ return /* @__PURE__ */ React7.createElement(InvitationListItem, _extends4({
327
374
  key: value,
328
375
  value,
329
376
  invitation
330
377
  }, invitationProps));
331
- }));
378
+ }))) : /* @__PURE__ */ React7.createElement("p", {
379
+ className: mx4(defaultDescription, "text-center p-2")
380
+ }, t("empty invitations message"));
332
381
  };
333
382
 
334
383
  // packages/apps/patterns/react-ui/src/components/InvitationList/InvitationListContainer.tsx
@@ -354,7 +403,7 @@ var InvitationListContainer = ({ spaceKey, createInvitationUrl }) => {
354
403
  }, [
355
404
  space
356
405
  ]);
357
- return /* @__PURE__ */ React7.createElement(InvitationList, _extends5({
406
+ return /* @__PURE__ */ React8.createElement(InvitationList, _extends5({
358
407
  invitations
359
408
  }, {
360
409
  onClickRemove,
@@ -363,8 +412,8 @@ var InvitationListContainer = ({ spaceKey, createInvitationUrl }) => {
363
412
  };
364
413
 
365
414
  // packages/apps/patterns/react-ui/src/components/PanelSeparator/PanelSeparator.tsx
366
- import React8 from "react";
367
- import { mx as mx2 } from "@dxos/react-components";
415
+ import React9 from "react";
416
+ import { mx as mx5 } from "@dxos/react-components";
368
417
  function _extends6() {
369
418
  _extends6 = Object.assign || function(target) {
370
419
  for (var i = 1; i < arguments.length; i++) {
@@ -380,20 +429,17 @@ function _extends6() {
380
429
  return _extends6.apply(this, arguments);
381
430
  }
382
431
  var PanelSeparator = ({ className, ...props }) => {
383
- return /* @__PURE__ */ React8.createElement("span", _extends6({
432
+ return /* @__PURE__ */ React9.createElement("span", _extends6({
384
433
  role: "none"
385
434
  }, props, {
386
- className: mx2("block bs-px mlb-1 bg-neutral-800/10 dark:bg-neutral-200/10", className)
435
+ className: mx5("block bs-px mlb-1 bg-neutral-800/10 dark:bg-neutral-200/10", className)
387
436
  }));
388
437
  };
389
438
 
390
- // packages/apps/patterns/react-ui/src/composites/IdentityPopover/IdentityPopover.tsx
391
- import React24 from "react";
392
- import { Avatar as Avatar7, mx as mx16 } from "@dxos/react-components";
393
-
394
- // packages/apps/patterns/react-ui/src/layouts/PanelPopover/PanelPopover.tsx
395
- import React9 from "react";
396
- import { mx as mx3, Popover } from "@dxos/react-components";
439
+ // packages/apps/patterns/react-ui/src/components/SpaceList/SpaceListItem.tsx
440
+ import React10, { forwardRef } from "react";
441
+ import { Avatar as Avatar2, mx as mx6 } from "@dxos/react-components";
442
+ import { humanize } from "@dxos/util";
397
443
  function _extends7() {
398
444
  _extends7 = Object.assign || function(target) {
399
445
  for (var i = 1; i < arguments.length; i++) {
@@ -408,23 +454,69 @@ function _extends7() {
408
454
  };
409
455
  return _extends7.apply(this, arguments);
410
456
  }
457
+ var SpaceListItem = /* @__PURE__ */ forwardRef(({ space, onClick }, ref) => {
458
+ var _a;
459
+ return /* @__PURE__ */ React10.createElement("li", {
460
+ className: mx6("flex gap-2 items-center", onClick && "cursor-pointer"),
461
+ onClick: () => onClick == null ? void 0 : onClick(),
462
+ ref,
463
+ "data-testid": "space-list-item"
464
+ }, /* @__PURE__ */ React10.createElement(Avatar2, _extends7({}, {
465
+ variant: "circle",
466
+ size: 9,
467
+ fallbackValue: space.key.toHex(),
468
+ label: /* @__PURE__ */ React10.createElement("p", {
469
+ className: "text-sm truncate"
470
+ }, (_a = space.properties.name) != null ? _a : humanize(space.key)),
471
+ slots: {
472
+ labels: {
473
+ className: "block shrink overflow-hidden"
474
+ },
475
+ root: {
476
+ className: "shrink-0"
477
+ }
478
+ }
479
+ })));
480
+ });
481
+
482
+ // packages/apps/patterns/react-ui/src/composites/IdentityPopover/IdentityPopover.tsx
483
+ import React29 from "react";
484
+ import { Avatar as Avatar8, mx as mx23 } from "@dxos/react-components";
485
+
486
+ // packages/apps/patterns/react-ui/src/layouts/PanelPopover/PanelPopover.tsx
487
+ import React11 from "react";
488
+ import { mx as mx7, Popover } from "@dxos/react-components";
489
+ function _extends8() {
490
+ _extends8 = Object.assign || function(target) {
491
+ for (var i = 1; i < arguments.length; i++) {
492
+ var source = arguments[i];
493
+ for (var key in source) {
494
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
495
+ target[key] = source[key];
496
+ }
497
+ }
498
+ }
499
+ return target;
500
+ };
501
+ return _extends8.apply(this, arguments);
502
+ }
411
503
  var PanelPopover = ({ slots, children, ...popoverProps }) => {
412
504
  var _a, _b, _c;
413
- return /* @__PURE__ */ React9.createElement(Popover, _extends7({
505
+ return /* @__PURE__ */ React11.createElement(Popover, _extends8({
414
506
  slots: {
415
507
  arrow: {
416
508
  ...slots == null ? void 0 : slots.arrow,
417
- className: mx3(defaultArrow, (_a = slots == null ? void 0 : slots.arrow) == null ? void 0 : _a.className)
509
+ className: mx7(defaultArrow, (_a = slots == null ? void 0 : slots.arrow) == null ? void 0 : _a.className)
418
510
  },
419
511
  content: {
420
512
  collisionPadding: 8,
421
513
  sideOffset: 4,
422
514
  ...slots == null ? void 0 : slots.content,
423
- className: mx3(defaultSurface, (_b = slots == null ? void 0 : slots.content) == null ? void 0 : _b.className)
515
+ className: mx7(defaultSurface, (_b = slots == null ? void 0 : slots.content) == null ? void 0 : _b.className)
424
516
  },
425
517
  trigger: {
426
518
  ...slots == null ? void 0 : slots.trigger,
427
- className: mx3("", (_c = slots == null ? void 0 : slots.trigger) == null ? void 0 : _c.className)
519
+ className: mx7("", (_c = slots == null ? void 0 : slots.trigger) == null ? void 0 : _c.className)
428
520
  },
429
521
  ...slots
430
522
  }
@@ -433,10 +525,10 @@ var PanelPopover = ({ slots, children, ...popoverProps }) => {
433
525
 
434
526
  // packages/apps/patterns/react-ui/src/layouts/PanelSidebar/PanelSidebar.tsx
435
527
  import * as DialogPrimitive from "@radix-ui/react-dialog";
436
- import React10, { createContext, useCallback as useCallback3, useContext, useState } from "react";
437
- import { defaultOverlay, mx as mx4, useMediaQuery, useTranslation as useTranslation3 } from "@dxos/react-components";
438
- function _extends8() {
439
- _extends8 = Object.assign || function(target) {
528
+ import React12, { createContext, useCallback as useCallback3, useContext, useState } from "react";
529
+ import { defaultOverlay as defaultOverlay2, mx as mx8, useMediaQuery, useTranslation as useTranslation4 } from "@dxos/react-components";
530
+ function _extends9() {
531
+ _extends9 = Object.assign || function(target) {
440
532
  for (var i = 1; i < arguments.length; i++) {
441
533
  var source = arguments[i];
442
534
  for (var key in source) {
@@ -447,7 +539,7 @@ function _extends8() {
447
539
  }
448
540
  return target;
449
541
  };
450
- return _extends8.apply(this, arguments);
542
+ return _extends9.apply(this, arguments);
451
543
  }
452
544
  var PanelSidebarContext = /* @__PURE__ */ createContext({
453
545
  displayState: "hide",
@@ -464,7 +556,7 @@ var useTogglePanelSidebar = () => {
464
556
  };
465
557
  var PanelSidebarProvider = ({ children, slots }) => {
466
558
  var _a, _b, _c;
467
- const { t } = useTranslation3("os");
559
+ const { t } = useTranslation4("os");
468
560
  const [isLg] = useMediaQuery("lg", {
469
561
  ssr: false
470
562
  });
@@ -487,37 +579,37 @@ var PanelSidebarProvider = ({ children, slots }) => {
487
579
  }, 0);
488
580
  };
489
581
  const setDisplayState = (displayState2) => displayState2 === "show" ? internalShow() : internalHide();
490
- return /* @__PURE__ */ React10.createElement(PanelSidebarContext.Provider, {
582
+ return /* @__PURE__ */ React12.createElement(PanelSidebarContext.Provider, {
491
583
  value: {
492
584
  setDisplayState,
493
585
  displayState
494
586
  }
495
- }, /* @__PURE__ */ React10.createElement(DialogPrimitive.Root, {
587
+ }, /* @__PURE__ */ React12.createElement(DialogPrimitive.Root, {
496
588
  open: domShow,
497
589
  modal: !isLg
498
- }, /* @__PURE__ */ React10.createElement(DialogPrimitive.Content, _extends8({
590
+ }, /* @__PURE__ */ React12.createElement(DialogPrimitive.Content, _extends9({
499
591
  onOpenAutoFocus: (event) => isLg && event.preventDefault(),
500
592
  onCloseAutoFocus: (event) => isLg && event.preventDefault()
501
593
  }, slots == null ? void 0 : slots.content, {
502
- className: mx4("fixed block-start-0 block-end-0 is-sidebar z-50 overscroll-contain overflow-x-hidden overflow-y-auto", "transition-[inset-inline-start,inset-inline-end] duration-200 ease-in-out", transitionShow ? "inline-start-0" : "-inline-start-sidebar", (_a = slots == null ? void 0 : slots.content) == null ? void 0 : _a.className)
503
- }), /* @__PURE__ */ React10.createElement(DialogPrimitive.Title, {
594
+ className: mx8("fixed block-start-0 block-end-0 is-sidebar z-30 overscroll-contain overflow-x-hidden overflow-y-auto", "transition-[inset-inline-start,inset-inline-end] duration-200 ease-in-out", transitionShow ? "inline-start-0" : "-inline-start-sidebar", (_a = slots == null ? void 0 : slots.content) == null ? void 0 : _a.className)
595
+ }), /* @__PURE__ */ React12.createElement(DialogPrimitive.Title, {
504
596
  className: "sr-only"
505
- }, t("sidebar label")), (_b = slots == null ? void 0 : slots.content) == null ? void 0 : _b.children), !isLg && /* @__PURE__ */ React10.createElement(DialogPrimitive.Overlay, {
506
- className: mx4(defaultOverlay, "transition-opacity duration-200 ease-in-out", transitionShow ? "opacity-100" : "opacity-0"),
597
+ }, t("sidebar label")), (_b = slots == null ? void 0 : slots.content) == null ? void 0 : _b.children), !isLg && /* @__PURE__ */ React12.createElement(DialogPrimitive.Overlay, {
598
+ className: mx8(defaultOverlay2, "transition-opacity duration-200 ease-in-out", transitionShow ? "opacity-100" : "opacity-0"),
507
599
  onClick: internalHide
508
- }), /* @__PURE__ */ React10.createElement("div", _extends8({
600
+ }), /* @__PURE__ */ React12.createElement("div", _extends9({
509
601
  role: "none"
510
602
  }, slots == null ? void 0 : slots.main, {
511
- className: mx4("transition-[padding-inline-start] duration-200 ease-in-out", isLg && isOpen ? "pis-sidebar" : "pis-0", (_c = slots == null ? void 0 : slots.main) == null ? void 0 : _c.className)
603
+ className: mx8("transition-[padding-inline-start] duration-200 ease-in-out", isLg && isOpen ? "pis-sidebar" : "pis-0", (_c = slots == null ? void 0 : slots.main) == null ? void 0 : _c.className)
512
604
  }), children)));
513
605
  };
514
606
 
515
607
  // packages/apps/patterns/react-ui/src/layouts/PanelAlertDialog/PanelAlertDialog.tsx
516
608
  import * as AlertDialog from "@radix-ui/react-alert-dialog";
517
- import React11 from "react";
518
- import { mx as mx5 } from "@dxos/react-components";
519
- function _extends9() {
520
- _extends9 = Object.assign || function(target) {
609
+ import React13 from "react";
610
+ import { mx as mx9 } from "@dxos/react-components";
611
+ function _extends10() {
612
+ _extends10 = Object.assign || function(target) {
521
613
  for (var i = 1; i < arguments.length; i++) {
522
614
  var source = arguments[i];
523
615
  for (var key in source) {
@@ -528,67 +620,183 @@ function _extends9() {
528
620
  }
529
621
  return target;
530
622
  };
531
- return _extends9.apply(this, arguments);
623
+ return _extends10.apply(this, arguments);
532
624
  }
533
625
  var PanelAlertDialog = ({ titleId, slots = {}, children }) => {
534
626
  var _a, _b;
535
- return /* @__PURE__ */ React11.createElement(AlertDialog.Root, _extends9({
627
+ return /* @__PURE__ */ React13.createElement(AlertDialog.Root, _extends10({
536
628
  defaultOpen: true
537
- }, slots.root), slots.trigger && /* @__PURE__ */ React11.createElement(AlertDialog.Trigger, _extends9({}, slots.trigger)), /* @__PURE__ */ React11.createElement(AlertDialog.Overlay, _extends9({}, slots.overlay, {
538
- className: mx5("fixed inset-0 backdrop-blur z-50 overflow-auto grid place-items-center p-2 md:p-4 lg:p-8", (_a = slots.overlay) == null ? void 0 : _a.className)
539
- }), /* @__PURE__ */ React11.createElement(AlertDialog.Content, _extends9({
629
+ }, slots.root), slots.trigger && /* @__PURE__ */ React13.createElement(AlertDialog.Trigger, _extends10({}, slots.trigger)), /* @__PURE__ */ React13.createElement(AlertDialog.Overlay, _extends10({}, slots.overlay, {
630
+ className: mx9(defaultOverlay, "z-40", (_a = slots.overlay) == null ? void 0 : _a.className)
631
+ }), /* @__PURE__ */ React13.createElement(AlertDialog.Content, _extends10({
540
632
  onEscapeKeyDown: (event) => event.preventDefault()
541
633
  }, slots.content, {
542
634
  "aria-labelledby": titleId,
543
- className: mx5("is-full min-is-[260px] max-is-[320px] shadow-md backdrop-blur-md", (_b = slots.content) == null ? void 0 : _b.className)
635
+ className: mx9(defaultDialogContent, (_b = slots.content) == null ? void 0 : _b.className)
544
636
  }), children)));
545
637
  };
546
638
 
547
- // packages/apps/patterns/react-ui/src/panels/IdentityPanel/IdentityPanel.tsx
548
- import React12 from "react";
549
- import { useClient as useClient2 } from "@dxos/react-client";
550
- import { Avatar as Avatar2, Button as Button2, ThemeContext, useTranslation as useTranslation4 } from "@dxos/react-components";
551
- var IdentityPanel = ({ identity, onClickManageProfile }) => {
639
+ // packages/apps/patterns/react-ui/src/layouts/PanelDialog/PanelDialog.tsx
640
+ import * as Dialog from "@radix-ui/react-dialog";
641
+ import React14 from "react";
642
+ import { mx as mx10 } from "@dxos/react-components";
643
+ function _extends11() {
644
+ _extends11 = Object.assign || function(target) {
645
+ for (var i = 1; i < arguments.length; i++) {
646
+ var source = arguments[i];
647
+ for (var key in source) {
648
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
649
+ target[key] = source[key];
650
+ }
651
+ }
652
+ }
653
+ return target;
654
+ };
655
+ return _extends11.apply(this, arguments);
656
+ }
657
+ var PanelDialog = ({ titleId, slots = {}, children }) => {
658
+ var _a, _b;
659
+ return /* @__PURE__ */ React14.createElement(Dialog.Root, _extends11({
660
+ defaultOpen: true
661
+ }, slots.root), slots.trigger && /* @__PURE__ */ React14.createElement(Dialog.Trigger, _extends11({}, slots.trigger)), /* @__PURE__ */ React14.createElement(Dialog.Overlay, _extends11({}, slots.overlay, {
662
+ className: mx10(defaultOverlay, "z-40", (_a = slots.overlay) == null ? void 0 : _a.className)
663
+ }), /* @__PURE__ */ React14.createElement(Dialog.Content, _extends11({}, slots.content, {
664
+ "aria-labelledby": titleId,
665
+ className: mx10(defaultDialogContent, (_b = slots.content) == null ? void 0 : _b.className)
666
+ }), children)));
667
+ };
668
+
669
+ // packages/apps/patterns/react-ui/src/panels/DevicesPanel/DevicesPanel.tsx
670
+ import { UserPlus, X as X2 } from "phosphor-react";
671
+ import React15, { cloneElement, useReducer } from "react";
672
+ import { useClient as useClient2, useDevices, useHaloInvitations, useIdentity } from "@dxos/react-client";
673
+ import { Button as Button2, DensityProvider as DensityProvider2, getSize as getSize3, mx as mx11, Tooltip, useTranslation as useTranslation5 } from "@dxos/react-components";
674
+ function _extends12() {
675
+ _extends12 = Object.assign || function(target) {
676
+ for (var i = 1; i < arguments.length; i++) {
677
+ var source = arguments[i];
678
+ for (var key in source) {
679
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
680
+ target[key] = source[key];
681
+ }
682
+ }
683
+ }
684
+ return target;
685
+ };
686
+ return _extends12.apply(this, arguments);
687
+ }
688
+ var DeviceListView = ({ createInvitationUrl, titleId, onDone, doneActionParent }) => {
552
689
  var _a;
553
- const { t } = useTranslation4("os");
690
+ const { t } = useTranslation5("os");
554
691
  const client = useClient2();
692
+ const identity = useIdentity();
693
+ const devices = useDevices();
694
+ const invitations = useHaloInvitations();
695
+ const displayName = (_a = identity == null ? void 0 : identity.profile) == null ? void 0 : _a.displayName;
696
+ if (!identity) {
697
+ return null;
698
+ }
699
+ const doneButton = /* @__PURE__ */ React15.createElement(Button2, {
700
+ variant: "ghost",
701
+ onClick: () => onDone == null ? void 0 : onDone(),
702
+ "data-testid": "show-all-spaces"
703
+ }, /* @__PURE__ */ React15.createElement(X2, {
704
+ className: getSize3(4),
705
+ weight: "bold"
706
+ }));
707
+ return /* @__PURE__ */ React15.createElement("div", {
708
+ role: "none",
709
+ className: "flex flex-col"
710
+ }, /* @__PURE__ */ React15.createElement("div", {
711
+ role: "none",
712
+ className: mx11(subduedSurface, "rounded-bs-md flex items-center p-2 gap-2")
713
+ }, /* @__PURE__ */ React15.createElement("h2", {
714
+ id: titleId,
715
+ className: mx11("grow font-system-medium", !displayName && "font-mono")
716
+ }, displayName != null ? displayName : identity.identityKey.truncate()), /* @__PURE__ */ React15.createElement(Tooltip, {
717
+ content: t("close label"),
718
+ zIndex: "z-50"
719
+ }, doneActionParent ? /* @__PURE__ */ cloneElement(doneActionParent, {}, doneButton) : doneButton)), /* @__PURE__ */ React15.createElement("div", {
720
+ role: "region",
721
+ className: mx11(defaultSurface, "rounded-be-md p-2")
722
+ }, /* @__PURE__ */ React15.createElement(InvitationList, {
723
+ invitations,
724
+ onClickRemove: ({ invitation }) => invitation && client.halo.removeInvitation(invitation.invitationId),
725
+ createInvitationUrl
726
+ }), /* @__PURE__ */ React15.createElement(Button2, {
727
+ className: "is-full flex gap-2 mbs-2",
728
+ onClick: () => client.halo.createInvitation(),
729
+ "data-testid": "create-space-invitation"
730
+ }, /* @__PURE__ */ React15.createElement("span", null, t("create space invitation label")), /* @__PURE__ */ React15.createElement(UserPlus, {
731
+ className: getSize3(4),
732
+ weight: "bold"
733
+ })), /* @__PURE__ */ React15.createElement(PanelSeparator, null), /* @__PURE__ */ React15.createElement(DeviceList, {
734
+ devices
735
+ })));
736
+ };
737
+ var DevicesPanel = (props) => {
738
+ const reducer = (state, action) => {
739
+ const nextState = {
740
+ ...state
741
+ };
742
+ switch (action.type) {
743
+ case null:
744
+ }
745
+ return nextState;
746
+ };
747
+ const [panelState] = useReducer(reducer, {
748
+ activeView: "device list"
749
+ });
750
+ return /* @__PURE__ */ React15.createElement(DensityProvider2, {
751
+ density: "fine"
752
+ }, panelState.activeView === "device list" ? /* @__PURE__ */ React15.createElement(DeviceListView, _extends12({}, props)) : null);
753
+ };
754
+
755
+ // packages/apps/patterns/react-ui/src/panels/IdentityPanel/IdentityPanel.tsx
756
+ import React16 from "react";
757
+ import { useClient as useClient3 } from "@dxos/react-client";
758
+ import { Avatar as Avatar3, Button as Button3, ThemeContext, useTranslation as useTranslation6 } from "@dxos/react-components";
759
+ var IdentityPanel = ({ identity, onClickManageProfile }) => {
760
+ var _a, _b;
761
+ const { t } = useTranslation6("os");
762
+ const client = useClient3();
555
763
  const defaultManageProfile = () => {
556
764
  const remoteSource = new URL((client == null ? void 0 : client.config.get("runtime.client.remoteSource")) || "https://halo.dxos.org");
557
765
  const tab = window.open(remoteSource.origin, "_blank");
558
766
  tab == null ? void 0 : tab.focus();
559
767
  };
560
- return /* @__PURE__ */ React12.createElement(ThemeContext.Provider, {
768
+ return /* @__PURE__ */ React16.createElement(ThemeContext.Provider, {
561
769
  value: {
562
- themeVariant: "os"
770
+ themeVariant: "os",
771
+ rootDensity: "fine"
563
772
  }
564
- }, /* @__PURE__ */ React12.createElement("div", {
773
+ }, /* @__PURE__ */ React16.createElement("div", {
565
774
  className: "flex flex-col gap-2 justify-center items-center"
566
- }, /* @__PURE__ */ React12.createElement(Avatar2, {
775
+ }, /* @__PURE__ */ React16.createElement(Avatar3, {
567
776
  size: 16,
568
777
  variant: "circle",
569
778
  fallbackValue: identity.identityKey.toHex(),
570
- label: (_a = identity.displayName) != null ? _a : ""
571
- }), /* @__PURE__ */ React12.createElement(Button2, {
572
- compact: true,
779
+ label: (_b = (_a = identity.profile) == null ? void 0 : _a.displayName) != null ? _b : ""
780
+ }), /* @__PURE__ */ React16.createElement(Button3, {
573
781
  onClick: onClickManageProfile != null ? onClickManageProfile : defaultManageProfile,
574
782
  className: "is-full"
575
783
  }, t("manage profile label"))));
576
784
  };
577
785
 
578
786
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/JoinPanel.tsx
579
- import React23, { useEffect, useReducer } from "react";
787
+ import React27, { useEffect, useReducer as useReducer2, useState as useState6 } from "react";
580
788
  import { InvitationEncoder as InvitationEncoder2 } from "@dxos/client";
581
789
  import { log } from "@dxos/log";
582
- import { useClient as useClient5, useIdentity } from "@dxos/react-client";
583
- import { useId as useId3 } from "@dxos/react-components";
790
+ import { useClient as useClient6, useIdentity as useIdentity2 } from "@dxos/react-client";
791
+ import { DensityProvider as DensityProvider3, useId as useId4 } from "@dxos/react-components";
584
792
 
585
793
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/JoinHeading.tsx
586
794
  import { ProhibitInset as ProhibitInset2 } from "phosphor-react";
587
- import React13, { cloneElement, forwardRef } from "react";
795
+ import React17, { cloneElement as cloneElement2, forwardRef as forwardRef2 } from "react";
588
796
  import { useSpace as useSpace2 } from "@dxos/react-client";
589
- import { Avatar as Avatar3, Button as Button3, getSize as getSize3, Heading, mx as mx6, Trans, useId, useTranslation as useTranslation5 } from "@dxos/react-components";
590
- function _extends10() {
591
- _extends10 = Object.assign || function(target) {
797
+ import { Avatar as Avatar4, Button as Button4, getSize as getSize4, Heading, mx as mx12, Trans, useId as useId2, useTranslation as useTranslation7 } from "@dxos/react-components";
798
+ function _extends13() {
799
+ _extends13 = Object.assign || function(target) {
592
800
  for (var i = 1; i < arguments.length; i++) {
593
801
  var source = arguments[i];
594
802
  for (var key in source) {
@@ -599,70 +807,76 @@ function _extends10() {
599
807
  }
600
808
  return target;
601
809
  };
602
- return _extends10.apply(this, arguments);
810
+ return _extends13.apply(this, arguments);
603
811
  }
604
- var JoinHeading = /* @__PURE__ */ forwardRef(({ titleId, invitation, onExit, exitActionParent }, ref) => {
605
- var _a, _b, _c, _d, _e;
606
- const { t } = useTranslation5("os");
812
+ var JoinHeading = /* @__PURE__ */ forwardRef2(({ mode, titleId, invitation, onExit, exitActionParent, preventExit }, ref) => {
813
+ var _a, _b, _c, _d, _e, _f;
814
+ const { t } = useTranslation7("os");
607
815
  const space = useSpace2((_a = invitation == null ? void 0 : invitation.invitation) == null ? void 0 : _a.spaceKey);
608
- const spaceTitle = (_b = space == null ? void 0 : space.properties.name) != null ? _b : "(Space not available)";
609
- const nameId = useId("spaceDisplayName");
610
- const exitButton = /* @__PURE__ */ React13.createElement(Button3, _extends10({
611
- compact: true,
816
+ const name = mode === "halo-only" ? "(Unknown identity)" : (_b = space == null ? void 0 : space.properties.name) != null ? _b : "(Space name not available)";
817
+ const nameId = useId2(mode === "halo-only" ? "identityDisplayName" : "spaceDisplayName");
818
+ const invitationKey = mode === "halo-only" ? (_d = (_c = invitation == null ? void 0 : invitation.invitation) == null ? void 0 : _c.identityKey) == null ? void 0 : _d.toHex() : (_f = (_e = invitation == null ? void 0 : invitation.invitation) == null ? void 0 : _e.identityKey) == null ? void 0 : _f.toHex();
819
+ const exitButton = /* @__PURE__ */ React17.createElement(Button4, _extends13({
612
820
  variant: "ghost"
613
821
  }, onExit && {
614
822
  onClick: onExit
615
823
  }, {
616
- className: "grow-0 shrink-0"
617
- }), /* @__PURE__ */ React13.createElement(ProhibitInset2, {
618
- className: getSize3(5)
619
- }), /* @__PURE__ */ React13.createElement("span", {
824
+ className: "grow-0 shrink-0",
825
+ "data-testid": "join-exit"
826
+ }), /* @__PURE__ */ React17.createElement(ProhibitInset2, {
827
+ className: getSize4(5)
828
+ }), /* @__PURE__ */ React17.createElement("span", {
620
829
  className: "sr-only"
621
830
  }, t("exit label")));
622
- return /* @__PURE__ */ React13.createElement("div", {
831
+ return /* @__PURE__ */ React17.createElement("div", {
623
832
  role: "none",
624
- className: mx6(subduedSurface, "p-2 rounded-bs-md"),
833
+ className: mx12(subduedSurface, "p-2 rounded-bs-md"),
625
834
  ref
626
- }, /* @__PURE__ */ React13.createElement("div", {
835
+ }, /* @__PURE__ */ React17.createElement("div", {
627
836
  role: "group",
628
837
  className: "flex items-center gap-2"
629
- }, /* @__PURE__ */ React13.createElement(Avatar3, {
630
- fallbackValue: (_e = (_d = (_c = invitation == null ? void 0 : invitation.invitation) == null ? void 0 : _c.spaceKey) == null ? void 0 : _d.toHex()) != null ? _e : "",
838
+ }, invitationKey ? /* @__PURE__ */ React17.createElement(Avatar4, {
839
+ fallbackValue: invitationKey,
631
840
  labelId: nameId
632
- }), /* @__PURE__ */ React13.createElement(Heading, {
841
+ }) : /* @__PURE__ */ React17.createElement("span", {
842
+ role: "none",
843
+ className: mx12(getSize4(10), "bg-neutral-300 dark:bg-neutral-700 rounded-full")
844
+ }), /* @__PURE__ */ React17.createElement(Heading, {
633
845
  level: 1,
634
846
  className: "font-body font-normal text-base grow",
635
847
  id: titleId
636
- }, /* @__PURE__ */ React13.createElement(Trans, _extends10({}, {
637
- defaults: t("join space heading"),
848
+ }, invitation ? /* @__PURE__ */ React17.createElement(Trans, _extends13({}, {
849
+ defaults: t("joining heading"),
638
850
  components: {
639
- small: /* @__PURE__ */ React13.createElement("span", {
851
+ small: /* @__PURE__ */ React17.createElement("span", {
640
852
  className: "block leading-none mbe-1 font-system-medium text-sm"
641
853
  }),
642
- large: /* @__PURE__ */ React13.createElement("span", {
854
+ large: /* @__PURE__ */ React17.createElement("span", {
643
855
  className: "block leading-none",
644
856
  id: nameId
645
857
  })
646
858
  },
647
859
  values: {
648
- spaceTitle
860
+ name
649
861
  }
650
- }))), exitActionParent ? /* @__PURE__ */ cloneElement(exitActionParent, {}, exitButton) : exitButton));
862
+ })) : /* @__PURE__ */ React17.createElement("span", {
863
+ className: "block leading-none font-system-medium text-sm"
864
+ }, mode === "halo-only" ? t("halo heading") : t("join space heading"))), !preventExit && mode !== "halo-only" && (exitActionParent ? /* @__PURE__ */ cloneElement2(exitActionParent, {}, exitButton) : exitButton)));
651
865
  });
652
866
 
653
867
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/AdditionMethodSelector.tsx
654
868
  import { CaretLeft, CaretRight, Plus, QrCode as QrCode2, Textbox } from "phosphor-react";
655
- import React15 from "react";
656
- import { Button as Button4, CompoundButton, getSize as getSize5, mx as mx8, useTranslation as useTranslation7 } from "@dxos/react-components";
869
+ import React19 from "react";
870
+ import { Button as Button5, CompoundButton, getSize as getSize6, mx as mx14, useTranslation as useTranslation9 } from "@dxos/react-components";
657
871
 
658
872
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/ViewState.tsx
659
- import { CheckCircle, HourglassSimple, X as X2 } from "phosphor-react";
660
- import React14, { useMemo as useMemo2 } from "react";
873
+ import { CheckCircle, HourglassSimple, X as X3 } from "phosphor-react";
874
+ import React18, { useMemo as useMemo2 } from "react";
661
875
  import { Invitation as Invitation4 } from "@dxos/client";
662
876
  import { useInvitationStatus as useInvitationStatus2 } from "@dxos/react-client";
663
- import { mx as mx7, useTranslation as useTranslation6, Trans as Trans2, Avatar as Avatar4, useId as useId2, getSize as getSize4, strongShimmer } from "@dxos/react-components";
664
- function _extends11() {
665
- _extends11 = Object.assign || function(target) {
877
+ import { mx as mx13, useTranslation as useTranslation8, Trans as Trans2, Avatar as Avatar5, useId as useId3, getSize as getSize5, strongShimmer } from "@dxos/react-components";
878
+ function _extends14() {
879
+ _extends14 = Object.assign || function(target) {
666
880
  for (var i = 1; i < arguments.length; i++) {
667
881
  var source = arguments[i];
668
882
  for (var key in source) {
@@ -673,39 +887,39 @@ function _extends11() {
673
887
  }
674
888
  return target;
675
889
  };
676
- return _extends11.apply(this, arguments);
890
+ return _extends14.apply(this, arguments);
677
891
  }
678
- var stripe = mx7("rounded-full grow", getSize4(3));
892
+ var stripe = mx13("rounded-full grow", getSize5(3));
679
893
  var ViewStateHeading = ({ children, className, ...props }) => {
680
- return /* @__PURE__ */ React14.createElement("h2", _extends11({}, props, {
681
- className: mx7("font-system-medium text-sm md:text-base mbe-1 mli-1 text-center", className)
894
+ return /* @__PURE__ */ React18.createElement("h2", _extends14({}, props, {
895
+ className: mx13("font-system-medium text-sm md:text-base mbe-1 mli-1 text-center", className)
682
896
  }), children);
683
897
  };
684
898
  var PureViewStateInvitation = ({ halted, cursor, label, resolvedColor }) => {
685
- const labelId = useId2("invitationState");
686
- return /* @__PURE__ */ React14.createElement("div", {
899
+ const labelId = useId3("invitationState");
900
+ return /* @__PURE__ */ React18.createElement("div", {
687
901
  role: "none",
688
- className: mx7(defaultSurface, "pli-2 pbs-2")
689
- }, /* @__PURE__ */ React14.createElement("div", {
902
+ className: mx13(defaultSurface, "pli-2 pbs-2")
903
+ }, /* @__PURE__ */ React18.createElement("div", {
690
904
  role: "status",
691
905
  "aria-labelledby": labelId,
692
906
  className: "flex gap-2 items-center mlb-1"
693
- }, /* @__PURE__ */ React14.createElement("div", {
907
+ }, /* @__PURE__ */ React18.createElement("div", {
694
908
  role: "none",
695
- className: mx7(stripe, !halted && cursor === 1 && strongShimmer, cursor === 2 ? halted ? resolvedColor : activeBgColor : cursor > 1 ? resolvedColor : inactiveBgColor)
696
- }), /* @__PURE__ */ React14.createElement("div", {
909
+ className: mx13(stripe, !halted && cursor === 1 && strongShimmer, cursor === 2 ? halted ? resolvedColor : activeBgColor : cursor > 1 ? resolvedColor : inactiveBgColor)
910
+ }), /* @__PURE__ */ React18.createElement("div", {
697
911
  role: "none",
698
- className: mx7(stripe, !halted && cursor === 3 && strongShimmer, cursor === 3 ? halted ? resolvedColor : activeBgColor : cursor > 3 ? resolvedColor : inactiveBgColor)
699
- }), /* @__PURE__ */ React14.createElement("div", {
912
+ className: mx13(stripe, !halted && cursor === 3 && strongShimmer, cursor === 3 ? halted ? resolvedColor : activeBgColor : cursor > 3 ? resolvedColor : inactiveBgColor)
913
+ }), /* @__PURE__ */ React18.createElement("div", {
700
914
  role: "none",
701
- className: mx7(stripe, cursor > 3 ? halted ? resolvedColor : resolvedColor : inactiveBgColor)
702
- })), /* @__PURE__ */ React14.createElement(ViewStateHeading, {
915
+ className: mx13(stripe, cursor > 3 ? halted ? resolvedColor : resolvedColor : inactiveBgColor)
916
+ })), /* @__PURE__ */ React18.createElement(ViewStateHeading, {
703
917
  id: labelId,
704
918
  className: "mbs-2 flex justify-center items-center gap-2"
705
919
  }, label));
706
920
  };
707
921
  var ViewStateInvitationStatus = ({ activeInvitation }) => {
708
- const { t } = useTranslation6("os");
922
+ const { t } = useTranslation8("os");
709
923
  const { status, haltedAt } = useInvitationStatus2(activeInvitation);
710
924
  const halted = status === Invitation4.State.CANCELLED || status === Invitation4.State.TIMEOUT || status === Invitation4.State.ERROR;
711
925
  const cursor = invitationStatusValue.get(halted ? haltedAt : status);
@@ -713,24 +927,24 @@ var ViewStateInvitationStatus = ({ activeInvitation }) => {
713
927
  const statusLabelMap = useMemo2(() => /* @__PURE__ */ new Map([
714
928
  [
715
929
  Invitation4.State.ERROR,
716
- /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(X2, {
930
+ /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(X3, {
717
931
  weight: "bold",
718
- className: mx7(getSize4(4), "text-error-600 dark:text-error-400")
719
- }), /* @__PURE__ */ React14.createElement("span", null, t("error status label")))
932
+ className: mx13(getSize5(4), "text-error-600 dark:text-error-400")
933
+ }), /* @__PURE__ */ React18.createElement("span", null, t("error status label")))
720
934
  ],
721
935
  [
722
936
  Invitation4.State.TIMEOUT,
723
- /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(HourglassSimple, {
937
+ /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(HourglassSimple, {
724
938
  weight: "fill",
725
- className: mx7(getSize4(4), "text-warning-600 dark:text-warning-400")
726
- }), /* @__PURE__ */ React14.createElement("span", null, t("timeout status label")))
939
+ className: mx13(getSize5(4), "text-warning-600 dark:text-warning-400")
940
+ }), /* @__PURE__ */ React18.createElement("span", null, t("timeout status label")))
727
941
  ],
728
942
  [
729
943
  Invitation4.State.CANCELLED,
730
- /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(X2, {
944
+ /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(X3, {
731
945
  weight: "bold",
732
- className: mx7(getSize4(4), "text-warning-600 dark:text-warning-400")
733
- }), /* @__PURE__ */ React14.createElement("span", null, t("cancelled status label")))
946
+ className: mx13(getSize5(4), "text-warning-600 dark:text-warning-400")
947
+ }), /* @__PURE__ */ React18.createElement("span", null, t("cancelled status label")))
734
948
  ],
735
949
  [
736
950
  Invitation4.State.INIT,
@@ -750,15 +964,15 @@ var ViewStateInvitationStatus = ({ activeInvitation }) => {
750
964
  ],
751
965
  [
752
966
  Invitation4.State.SUCCESS,
753
- /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(CheckCircle, {
967
+ /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(CheckCircle, {
754
968
  weight: "fill",
755
- className: mx7(getSize4(4), "text-success-600 dark:text-success-400")
756
- }), /* @__PURE__ */ React14.createElement("span", null, t("success status label")))
969
+ className: mx13(getSize5(4), "text-success-600 dark:text-success-400")
970
+ }), /* @__PURE__ */ React18.createElement("span", null, t("success status label")))
757
971
  ]
758
972
  ]), [
759
973
  t
760
974
  ]);
761
- return /* @__PURE__ */ React14.createElement(PureViewStateInvitation, _extends11({}, {
975
+ return /* @__PURE__ */ React18.createElement(PureViewStateInvitation, _extends14({}, {
762
976
  label: statusLabelMap.get(status),
763
977
  resolvedColor,
764
978
  cursor,
@@ -766,54 +980,54 @@ var ViewStateInvitationStatus = ({ activeInvitation }) => {
766
980
  }));
767
981
  };
768
982
  var ViewState = ({ active, children, className, dispatch, selectedIdentity, activeInvitation, ...props }) => {
769
- var _a;
770
- const { t } = useTranslation6("os");
771
- const identityLabel = useId2("selectedIdentityLabel");
772
- return /* @__PURE__ */ React14.createElement("div", _extends11({
983
+ var _a, _b;
984
+ const { t } = useTranslation8("os");
985
+ const identityLabel = useId3("selectedIdentityLabel");
986
+ return /* @__PURE__ */ React18.createElement("div", _extends14({
773
987
  role: "none"
774
988
  }, props, !active && {
775
989
  "aria-hidden": true
776
990
  }, {
777
- className: mx7("is-[50%] flex flex-col", active ? "order-2" : "order-4", className)
778
- }), selectedIdentity && /* @__PURE__ */ React14.createElement("div", {
991
+ className: mx13("is-[50%] flex flex-col", active ? "order-2" : "order-4", className)
992
+ }), selectedIdentity && /* @__PURE__ */ React18.createElement("div", {
779
993
  role: "none",
780
- className: mx7(subduedSurface, "flex-none flex items-center gap-1 pli-2 pbe-1.5")
781
- }, /* @__PURE__ */ React14.createElement(Trans2, _extends11({}, {
994
+ className: mx13(subduedSurface, "flex-none flex items-center gap-1 pli-2 pbe-1.5")
995
+ }, /* @__PURE__ */ React18.createElement(Trans2, _extends14({}, {
782
996
  defaults: t("join space as identity heading"),
783
997
  components: {
784
- icon: /* @__PURE__ */ React14.createElement(Avatar4, {
998
+ icon: /* @__PURE__ */ React18.createElement(Avatar5, {
785
999
  size: 4,
786
1000
  fallbackValue: selectedIdentity === true ? "" : selectedIdentity.identityKey.toHex(),
787
1001
  labelId: identityLabel
788
1002
  }),
789
- label: /* @__PURE__ */ React14.createElement("span", {
1003
+ label: /* @__PURE__ */ React18.createElement("span", {
790
1004
  id: identityLabel
791
1005
  }),
792
- part: /* @__PURE__ */ React14.createElement("span", {
1006
+ part: /* @__PURE__ */ React18.createElement("span", {
793
1007
  role: "none",
794
1008
  className: "flex items-center gap-1 leading-none"
795
1009
  })
796
1010
  },
797
1011
  values: {
798
- labelValue: selectedIdentity === true ? "\xA0" : (_a = selectedIdentity.displayName) != null ? _a : selectedIdentity.identityKey.truncate()
1012
+ labelValue: selectedIdentity === true ? "\xA0" : (_b = (_a = selectedIdentity.profile) == null ? void 0 : _a.displayName) != null ? _b : selectedIdentity.identityKey.truncate()
799
1013
  }
800
- }))), activeInvitation && (activeInvitation === true ? /* @__PURE__ */ React14.createElement(PureViewStateInvitation, _extends11({}, {
1014
+ }))), activeInvitation && (activeInvitation === true ? /* @__PURE__ */ React18.createElement(PureViewStateInvitation, _extends14({}, {
801
1015
  halted: false,
802
1016
  status: Invitation4.State.INIT,
803
1017
  label: t("invitation input label"),
804
1018
  cursor: 0,
805
1019
  resolvedColor: inactiveBgColor
806
- })) : /* @__PURE__ */ React14.createElement(ViewStateInvitationStatus, _extends11({}, {
1020
+ })) : /* @__PURE__ */ React18.createElement(ViewStateInvitationStatus, _extends14({}, {
807
1021
  activeInvitation
808
- }))), /* @__PURE__ */ React14.createElement("div", {
1022
+ }))), /* @__PURE__ */ React18.createElement("div", {
809
1023
  role: "region",
810
- className: mx7(defaultSurface, "rounded-be-md grow shrink-0 flex flex-col gap-1 p-2")
1024
+ className: mx13(defaultSurface, "rounded-be-md grow shrink-0 flex flex-col gap-1 p-2")
811
1025
  }, children));
812
1026
  };
813
1027
 
814
1028
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/AdditionMethodSelector.tsx
815
- function _extends12() {
816
- _extends12 = Object.assign || function(target) {
1029
+ function _extends15() {
1030
+ _extends15 = Object.assign || function(target) {
817
1031
  for (var i = 1; i < arguments.length; i++) {
818
1032
  var source = arguments[i];
819
1033
  for (var key in source) {
@@ -824,16 +1038,16 @@ function _extends12() {
824
1038
  }
825
1039
  return target;
826
1040
  };
827
- return _extends12.apply(this, arguments);
1041
+ return _extends15.apply(this, arguments);
828
1042
  }
829
1043
  var AdditionMethodSelector = ({ availableIdentities, ...viewStateProps }) => {
830
1044
  const disabled = !viewStateProps.active;
831
1045
  const { dispatch } = viewStateProps;
832
- const { t } = useTranslation7("os");
1046
+ const { t } = useTranslation9("os");
833
1047
  const sharedButtonProps = {
834
1048
  disabled,
835
- after: /* @__PURE__ */ React15.createElement(CaretRight, {
836
- className: getSize5(4),
1049
+ after: /* @__PURE__ */ React19.createElement(CaretRight, {
1050
+ className: getSize6(4),
837
1051
  weight: "bold"
838
1052
  }),
839
1053
  slots: {
@@ -842,59 +1056,65 @@ var AdditionMethodSelector = ({ availableIdentities, ...viewStateProps }) => {
842
1056
  }
843
1057
  }
844
1058
  };
845
- return /* @__PURE__ */ React15.createElement(ViewState, _extends12({}, viewStateProps), /* @__PURE__ */ React15.createElement(ViewStateHeading, null, t("addition method selector title")), /* @__PURE__ */ React15.createElement("div", {
1059
+ return /* @__PURE__ */ React19.createElement(ViewState, _extends15({}, viewStateProps), /* @__PURE__ */ React19.createElement(ViewStateHeading, null, t("addition method selector title")), /* @__PURE__ */ React19.createElement("div", {
846
1060
  role: "none",
847
1061
  className: "flex flex-col gap-1 grow"
848
- }, /* @__PURE__ */ React15.createElement(CompoundButton, _extends12({}, sharedButtonProps, {
1062
+ }, /* @__PURE__ */ React19.createElement(CompoundButton, _extends15({}, sharedButtonProps, {
849
1063
  description: t("create identity description"),
850
- before: /* @__PURE__ */ React15.createElement(Plus, {
851
- className: getSize5(6)
1064
+ before: /* @__PURE__ */ React19.createElement(Plus, {
1065
+ className: getSize6(6)
852
1066
  }),
853
1067
  onClick: () => dispatch({
854
1068
  type: "select addition method",
855
1069
  method: "create identity"
856
1070
  }),
857
- "data-autofocus": "addition method selector"
858
- }), t("create identity label")), /* @__PURE__ */ React15.createElement(CompoundButton, _extends12({}, sharedButtonProps, {
1071
+ "data-autofocus": "addition method selector",
1072
+ "data-testid": "create-identity"
1073
+ }), t("create identity label")), /* @__PURE__ */ React19.createElement(CompoundButton, _extends15({}, sharedButtonProps, {
859
1074
  description: t("join identity description"),
860
- before: /* @__PURE__ */ React15.createElement(QrCode2, {
861
- className: getSize5(6)
1075
+ before: /* @__PURE__ */ React19.createElement(QrCode2, {
1076
+ className: getSize6(6)
862
1077
  }),
863
1078
  onClick: () => dispatch({
864
1079
  type: "select addition method",
865
1080
  method: "accept device invitation"
866
- })
867
- }), t("join identity label")), /* @__PURE__ */ React15.createElement(CompoundButton, _extends12({}, sharedButtonProps, {
1081
+ }),
1082
+ "data-testid": "join-identity"
1083
+ }), t("join identity label")), /* @__PURE__ */ React19.createElement(CompoundButton, _extends15({}, sharedButtonProps, {
1084
+ // TODO(mykola): Implement recover.
1085
+ disabled: true,
868
1086
  description: t("recover identity description"),
869
- before: /* @__PURE__ */ React15.createElement(Textbox, {
870
- className: getSize5(6)
1087
+ before: /* @__PURE__ */ React19.createElement(Textbox, {
1088
+ className: getSize6(6)
871
1089
  }),
872
1090
  onClick: () => dispatch({
873
1091
  type: "select addition method",
874
1092
  method: "recover identity"
875
- })
876
- }), t("recover identity label"))), /* @__PURE__ */ React15.createElement(Button4, {
1093
+ }),
1094
+ "data-testid": "recover-identity"
1095
+ }), t("recover identity label"))), /* @__PURE__ */ React19.createElement(Button5, {
877
1096
  disabled: disabled || availableIdentities.length < 1,
878
1097
  onClick: () => dispatch({
879
1098
  type: "deselect identity"
880
- })
881
- }, /* @__PURE__ */ React15.createElement(CaretLeft, {
882
- className: getSize5(4),
1099
+ }),
1100
+ "data-testid": "deselect-identity"
1101
+ }, /* @__PURE__ */ React19.createElement(CaretLeft, {
1102
+ className: getSize6(4),
883
1103
  weight: "bold"
884
- }), /* @__PURE__ */ React15.createElement("span", {
1104
+ }), /* @__PURE__ */ React19.createElement("span", {
885
1105
  className: "grow"
886
- }, t("deselect identity label")), /* @__PURE__ */ React15.createElement(CaretRight, {
887
- className: mx8(getSize5(4), "invisible"),
1106
+ }, t("deselect identity label")), /* @__PURE__ */ React19.createElement(CaretRight, {
1107
+ className: mx14(getSize6(4), "invisible"),
888
1108
  weight: "bold"
889
1109
  })));
890
1110
  };
891
1111
 
892
1112
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/IdentityAdded.tsx
893
- import { CaretLeft as CaretLeft2, CaretRight as CaretRight2 } from "phosphor-react";
894
- import React16 from "react";
895
- import { Avatar as Avatar5, Button as Button5, getSize as getSize6, mx as mx9, useTranslation as useTranslation8 } from "@dxos/react-components";
896
- function _extends13() {
897
- _extends13 = Object.assign || function(target) {
1113
+ import { CaretLeft as CaretLeft2, CaretRight as CaretRight2, Check } from "phosphor-react";
1114
+ import React20, { cloneElement as cloneElement3 } from "react";
1115
+ import { Avatar as Avatar6, Button as Button6, getSize as getSize7, mx as mx15, useTranslation as useTranslation10 } from "@dxos/react-components";
1116
+ function _extends16() {
1117
+ _extends16 = Object.assign || function(target) {
898
1118
  for (var i = 1; i < arguments.length; i++) {
899
1119
  var source = arguments[i];
900
1120
  for (var key in source) {
@@ -905,27 +1125,51 @@ function _extends13() {
905
1125
  }
906
1126
  return target;
907
1127
  };
908
- return _extends13.apply(this, arguments);
1128
+ return _extends16.apply(this, arguments);
909
1129
  }
910
- var IdentityAdded = ({ addedIdentity, ...viewStateProps }) => {
911
- var _a, _b, _c;
1130
+ var Done = ({ onDone, doneActionParent, active }) => {
1131
+ const disabled = !active;
1132
+ const { t } = useTranslation10("os");
1133
+ const doneButton = /* @__PURE__ */ React20.createElement(Button6, _extends16({}, onDone && {
1134
+ onClick: () => onDone(null)
1135
+ }, {
1136
+ disabled,
1137
+ className: "grow flex items-center gap-2 pli-2",
1138
+ "data-autofocus": "identity added",
1139
+ "data-testid": "identity-added-done"
1140
+ }), /* @__PURE__ */ React20.createElement(CaretLeft2, {
1141
+ weight: "bold",
1142
+ className: mx15(getSize7(2), "invisible")
1143
+ }), /* @__PURE__ */ React20.createElement("span", {
1144
+ className: "grow"
1145
+ }, t("done label")), /* @__PURE__ */ React20.createElement(Check, {
1146
+ weight: "bold",
1147
+ className: getSize7(4)
1148
+ }));
1149
+ return doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneButton) : doneButton;
1150
+ };
1151
+ var IdentityAdded = ({ mode, addedIdentity, onDone, doneActionParent, ...viewStateProps }) => {
1152
+ var _a, _b, _c, _d, _e;
912
1153
  const disabled = !viewStateProps.active;
913
1154
  const { dispatch } = viewStateProps;
914
- const { t } = useTranslation8("os");
915
- return /* @__PURE__ */ React16.createElement(ViewState, _extends13({}, viewStateProps), /* @__PURE__ */ React16.createElement(ViewStateHeading, null, t("identity added label")), /* @__PURE__ */ React16.createElement("div", {
1155
+ const { t } = useTranslation10("os");
1156
+ return /* @__PURE__ */ React20.createElement(ViewState, _extends16({}, viewStateProps), /* @__PURE__ */ React20.createElement(ViewStateHeading, null, t("identity added label")), /* @__PURE__ */ React20.createElement("div", {
916
1157
  role: "none",
917
1158
  className: "grow flex flex-col items-center justify-center text-center gap-2"
918
- }, /* @__PURE__ */ React16.createElement(Avatar5, {
1159
+ }, /* @__PURE__ */ React20.createElement(Avatar6, {
919
1160
  size: 20,
920
1161
  fallbackValue: (_a = addedIdentity == null ? void 0 : addedIdentity.identityKey.toHex()) != null ? _a : "",
921
- label: /* @__PURE__ */ React16.createElement("p", {
922
- className: mx9("text-lg", !(addedIdentity == null ? void 0 : addedIdentity.displayName) && "font-mono")
923
- }, (_c = (_b = addedIdentity == null ? void 0 : addedIdentity.displayName) != null ? _b : addedIdentity == null ? void 0 : addedIdentity.identityKey.truncate()) != null ? _c : "\xA0"),
1162
+ label: /* @__PURE__ */ React20.createElement("p", {
1163
+ className: mx15("text-lg", !((_b = addedIdentity == null ? void 0 : addedIdentity.profile) == null ? void 0 : _b.displayName) && "font-mono")
1164
+ }, (_e = (_d = (_c = addedIdentity == null ? void 0 : addedIdentity.profile) == null ? void 0 : _c.displayName) != null ? _d : addedIdentity == null ? void 0 : addedIdentity.identityKey.truncate()) != null ? _e : "\xA0"),
924
1165
  variant: "circle",
925
1166
  status: "active"
926
- })), /* @__PURE__ */ React16.createElement("div", {
1167
+ })), mode === "halo-only" ? /* @__PURE__ */ React20.createElement(Done, _extends16({
1168
+ onDone,
1169
+ doneActionParent
1170
+ }, viewStateProps)) : /* @__PURE__ */ React20.createElement("div", {
927
1171
  className: "flex gap-2"
928
- }, /* @__PURE__ */ React16.createElement(Button5, {
1172
+ }, /* @__PURE__ */ React20.createElement(Button6, {
929
1173
  disabled: disabled || !addedIdentity,
930
1174
  className: "grow flex items-center gap-2 pli-2 order-2",
931
1175
  onClick: () => addedIdentity && dispatch({
@@ -933,33 +1177,33 @@ var IdentityAdded = ({ addedIdentity, ...viewStateProps }) => {
933
1177
  identity: addedIdentity
934
1178
  }),
935
1179
  "data-autofocus": "identity added"
936
- }, /* @__PURE__ */ React16.createElement(CaretLeft2, {
1180
+ }, /* @__PURE__ */ React20.createElement(CaretLeft2, {
937
1181
  weight: "bold",
938
- className: mx9(getSize6(2), "invisible")
939
- }), /* @__PURE__ */ React16.createElement("span", {
1182
+ className: mx15(getSize7(2), "invisible")
1183
+ }), /* @__PURE__ */ React20.createElement("span", {
940
1184
  className: "grow"
941
- }, t("continue label")), /* @__PURE__ */ React16.createElement(CaretRight2, {
1185
+ }, t("continue label")), /* @__PURE__ */ React20.createElement(CaretRight2, {
942
1186
  weight: "bold",
943
- className: getSize6(4)
944
- })), /* @__PURE__ */ React16.createElement(Button5, {
1187
+ className: getSize7(4)
1188
+ })), /* @__PURE__ */ React20.createElement(Button6, {
945
1189
  disabled,
946
1190
  onClick: () => dispatch({
947
1191
  type: "deselect identity"
948
1192
  }),
949
1193
  className: "flex items-center gap-2 pis-2 pie-4"
950
- }, /* @__PURE__ */ React16.createElement(CaretLeft2, {
1194
+ }, /* @__PURE__ */ React20.createElement(CaretLeft2, {
951
1195
  weight: "bold",
952
- className: getSize6(4)
953
- }), /* @__PURE__ */ React16.createElement("span", null, t("deselect identity label")))));
1196
+ className: getSize7(4)
1197
+ }), /* @__PURE__ */ React20.createElement("span", null, t("deselect identity label")))));
954
1198
  };
955
1199
 
956
1200
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/IdentitySelector.tsx
957
1201
  import * as RadioGroup from "@radix-ui/react-radio-group";
958
- import { CaretLeft as CaretLeft3, CaretRight as CaretRight3, UserPlus } from "phosphor-react";
959
- import React17, { useCallback as useCallback4, useState as useState2 } from "react";
960
- import { Avatar as Avatar6, Button as Button6, themeVariantFocus, getSize as getSize7, mx as mx10, useTranslation as useTranslation9 } from "@dxos/react-components";
961
- function _extends14() {
962
- _extends14 = Object.assign || function(target) {
1202
+ import { CaretLeft as CaretLeft3, CaretRight as CaretRight3, UserPlus as UserPlus2 } from "phosphor-react";
1203
+ import React21, { useCallback as useCallback4, useState as useState2 } from "react";
1204
+ import { Avatar as Avatar7, Button as Button7, themeVariantFocus, getSize as getSize8, mx as mx16, useTranslation as useTranslation11 } from "@dxos/react-components";
1205
+ function _extends17() {
1206
+ _extends17 = Object.assign || function(target) {
963
1207
  for (var i = 1; i < arguments.length; i++) {
964
1208
  var source = arguments[i];
965
1209
  for (var key in source) {
@@ -970,84 +1214,86 @@ function _extends14() {
970
1214
  }
971
1215
  return target;
972
1216
  };
973
- return _extends14.apply(this, arguments);
1217
+ return _extends17.apply(this, arguments);
974
1218
  }
975
1219
  var IdentitySelector = ({ availableIdentities, ...viewStateProps }) => {
976
1220
  const { dispatch } = viewStateProps;
977
1221
  const disabled = !viewStateProps.active;
978
- const { t } = useTranslation9("os");
1222
+ const { t } = useTranslation11("os");
979
1223
  const [activeIdentity, setActiveIdentity] = useState2(availableIdentities[0]);
980
1224
  const onValueChange = useCallback4((nextHex) => setActiveIdentity(availableIdentities.find((identity) => identity.identityKey.toHex() === nextHex) || activeIdentity), [
981
1225
  availableIdentities
982
1226
  ]);
983
- return /* @__PURE__ */ React17.createElement(ViewState, _extends14({}, viewStateProps), /* @__PURE__ */ React17.createElement(ViewStateHeading, null, t("identity selector title")), /* @__PURE__ */ React17.createElement(RadioGroup.Root, {
1227
+ return /* @__PURE__ */ React21.createElement(ViewState, _extends17({}, viewStateProps), /* @__PURE__ */ React21.createElement(ViewStateHeading, null, t("identity selector title")), /* @__PURE__ */ React21.createElement(RadioGroup.Root, {
984
1228
  disabled,
985
1229
  value: activeIdentity == null ? void 0 : activeIdentity.identityKey.toHex(),
986
1230
  onValueChange,
987
1231
  className: "overflow-y-auto grow shrink min-bs-10 pli-1 -mli-1",
988
1232
  "aria-label": t("identity radio group title"),
989
1233
  "data-autofocus": "identity selector"
990
- }, availableIdentities.map(({ displayName, identityKey }) => {
991
- var _a;
1234
+ }, availableIdentities.map(({ profile, identityKey }) => {
1235
+ var _a, _b;
992
1236
  const hex = identityKey.toHex();
993
1237
  const inputId = `identitySelector__item--${hex}`;
994
1238
  const labelId = `identitySelector__itemLabel--${hex}`;
995
- return /* @__PURE__ */ React17.createElement("label", {
1239
+ return /* @__PURE__ */ React21.createElement("label", {
996
1240
  htmlFor: inputId,
997
1241
  key: hex,
998
1242
  className: "flex items-center mbe-2 gap-2 cursor-pointer"
999
- }, /* @__PURE__ */ React17.createElement(RadioGroup.Item, {
1243
+ }, /* @__PURE__ */ React21.createElement(RadioGroup.Item, {
1000
1244
  id: inputId,
1001
1245
  "aria-labelledby": labelId,
1002
1246
  value: hex,
1003
- className: mx10("peer relative w-4 h-4 rounded-full", "border border-transparent text-white", "radix-state-checked:bg-primary-600", "radix-state-unchecked:bg-neutral-100 dark:radix-state-unchecked:bg-neutral-900", themeVariantFocus("os"))
1004
- }, /* @__PURE__ */ React17.createElement(RadioGroup.Indicator, {
1247
+ className: mx16("peer relative w-4 h-4 rounded-full", "border border-transparent text-white", "radix-state-checked:bg-primary-600", "radix-state-unchecked:bg-neutral-100 dark:radix-state-unchecked:bg-neutral-900", themeVariantFocus("os")),
1248
+ "data-testid": "identity-selector-item"
1249
+ }, /* @__PURE__ */ React21.createElement(RadioGroup.Indicator, {
1005
1250
  className: "absolute inset-0 flex items-center justify-center leading-0"
1006
- }, /* @__PURE__ */ React17.createElement("div", {
1251
+ }, /* @__PURE__ */ React21.createElement("div", {
1007
1252
  className: "w-1.5 h-1.5 rounded-full bg-white"
1008
- }))), /* @__PURE__ */ React17.createElement(Avatar6, {
1253
+ }))), /* @__PURE__ */ React21.createElement(Avatar7, {
1009
1254
  fallbackValue: hex,
1010
1255
  labelId,
1011
1256
  variant: "circle"
1012
- }), /* @__PURE__ */ React17.createElement("span", {
1257
+ }), /* @__PURE__ */ React21.createElement("span", {
1013
1258
  id: labelId,
1014
- className: mx10(!displayName && "font-mono")
1015
- }, (_a = displayName != null ? displayName : identityKey.truncate()) != null ? _a : ""));
1016
- })), /* @__PURE__ */ React17.createElement(Button6, {
1259
+ className: mx16(!(profile == null ? void 0 : profile.displayName) && "font-mono")
1260
+ }, (_b = (_a = profile == null ? void 0 : profile.displayName) != null ? _a : identityKey.truncate()) != null ? _b : ""));
1261
+ })), /* @__PURE__ */ React21.createElement(Button7, {
1017
1262
  disabled,
1018
- compact: true,
1019
1263
  onClick: () => dispatch({
1020
1264
  type: "add identity"
1021
1265
  }),
1022
- className: "flex items-center gap-2 pli-2"
1023
- }, /* @__PURE__ */ React17.createElement("span", null, t("add identity label")), /* @__PURE__ */ React17.createElement(UserPlus, {
1266
+ className: "flex items-center gap-2 pli-2",
1267
+ "data-testid": "add-identity"
1268
+ }, /* @__PURE__ */ React21.createElement("span", null, t("add identity label")), /* @__PURE__ */ React21.createElement(UserPlus2, {
1024
1269
  weight: "bold",
1025
- className: getSize7(3.5)
1026
- })), /* @__PURE__ */ React17.createElement(Button6, {
1270
+ className: getSize8(3.5)
1271
+ })), /* @__PURE__ */ React21.createElement(Button7, {
1027
1272
  disabled: disabled || !activeIdentity,
1028
1273
  className: "flex items-center gap-2 pli-2",
1029
1274
  onClick: () => dispatch({
1030
1275
  type: "select identity",
1031
1276
  identity: activeIdentity
1032
- })
1033
- }, /* @__PURE__ */ React17.createElement(CaretLeft3, {
1277
+ }),
1278
+ "data-testid": "select-identity"
1279
+ }, /* @__PURE__ */ React21.createElement(CaretLeft3, {
1034
1280
  weight: "bold",
1035
- className: mx10(getSize7(4), "invisible")
1036
- }), /* @__PURE__ */ React17.createElement("span", {
1281
+ className: mx16(getSize8(4), "invisible")
1282
+ }), /* @__PURE__ */ React21.createElement("span", {
1037
1283
  className: "grow"
1038
- }, t("continue label")), /* @__PURE__ */ React17.createElement(CaretRight3, {
1284
+ }, t("continue label")), /* @__PURE__ */ React21.createElement(CaretRight3, {
1039
1285
  weight: "bold",
1040
- className: getSize7(4)
1286
+ className: getSize8(4)
1041
1287
  })));
1042
1288
  };
1043
1289
 
1044
1290
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/IdentityInput.tsx
1045
1291
  import { CaretLeft as CaretLeft4, CaretRight as CaretRight4 } from "phosphor-react";
1046
- import React18, { useState as useState3 } from "react";
1047
- import { useClient as useClient3 } from "@dxos/react-client";
1048
- import { Button as Button7, getSize as getSize8, Input, mx as mx11, useTranslation as useTranslation10 } from "@dxos/react-components";
1049
- function _extends15() {
1050
- _extends15 = Object.assign || function(target) {
1292
+ import React22, { useState as useState3 } from "react";
1293
+ import { useClient as useClient4 } from "@dxos/react-client";
1294
+ import { Button as Button8, getSize as getSize9, Input, mx as mx17, useTranslation as useTranslation12 } from "@dxos/react-components";
1295
+ function _extends18() {
1296
+ _extends18 = Object.assign || function(target) {
1051
1297
  for (var i = 1; i < arguments.length; i++) {
1052
1298
  var source = arguments[i];
1053
1299
  for (var key in source) {
@@ -1058,18 +1304,18 @@ function _extends15() {
1058
1304
  }
1059
1305
  return target;
1060
1306
  };
1061
- return _extends15.apply(this, arguments);
1307
+ return _extends18.apply(this, arguments);
1062
1308
  }
1063
1309
  var IdentityInput = ({ method, ...viewStateProps }) => {
1064
1310
  const disabled = !viewStateProps.active;
1065
1311
  const { dispatch } = viewStateProps;
1066
- const { t } = useTranslation10("os");
1312
+ const { t } = useTranslation12("os");
1067
1313
  const [inputValue, setInputValue] = useState3("");
1068
- const client = useClient3();
1314
+ const client = useClient4();
1069
1315
  const [validationMessage, setValidationMessage] = useState3("");
1070
1316
  const isRecover = method === "recover identity";
1071
1317
  const handleNext = () => {
1072
- void client.halo.createProfile({
1318
+ void client.halo.createIdentity({
1073
1319
  [isRecover ? "seedphrase" : "displayName"]: inputValue
1074
1320
  }).then((identity) => {
1075
1321
  dispatch({
@@ -1080,9 +1326,9 @@ var IdentityInput = ({ method, ...viewStateProps }) => {
1080
1326
  setValidationMessage(t(isRecover ? "failed to recover identity message" : "failed to create identity message"));
1081
1327
  });
1082
1328
  };
1083
- return /* @__PURE__ */ React18.createElement(ViewState, _extends15({}, viewStateProps), /* @__PURE__ */ React18.createElement(Input, _extends15({
1329
+ return /* @__PURE__ */ React22.createElement(ViewState, _extends18({}, viewStateProps), /* @__PURE__ */ React22.createElement(Input, _extends18({
1084
1330
  disabled,
1085
- label: /* @__PURE__ */ React18.createElement(ViewStateHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
1331
+ label: /* @__PURE__ */ React22.createElement(ViewStateHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
1086
1332
  onChange: ({ target: { value } }) => setInputValue(value),
1087
1333
  slots: {
1088
1334
  root: {
@@ -1096,42 +1342,46 @@ var IdentityInput = ({ method, ...viewStateProps }) => {
1096
1342
  }, validationMessage.length && {
1097
1343
  validationValence: "error",
1098
1344
  validationMessage
1099
- })), /* @__PURE__ */ React18.createElement("div", {
1345
+ }, {
1346
+ "data-testid": "identity-input"
1347
+ })), /* @__PURE__ */ React22.createElement("div", {
1100
1348
  role: "none",
1101
1349
  className: "grow"
1102
- }), /* @__PURE__ */ React18.createElement("div", {
1350
+ }), /* @__PURE__ */ React22.createElement("div", {
1103
1351
  className: "flex gap-2"
1104
- }, /* @__PURE__ */ React18.createElement(Button7, {
1352
+ }, /* @__PURE__ */ React22.createElement(Button8, {
1105
1353
  disabled,
1106
1354
  className: "grow flex items-center gap-2 pli-2 order-2",
1107
- onClick: handleNext
1108
- }, /* @__PURE__ */ React18.createElement(CaretLeft4, {
1355
+ onClick: handleNext,
1356
+ "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-continue`
1357
+ }, /* @__PURE__ */ React22.createElement(CaretLeft4, {
1109
1358
  weight: "bold",
1110
- className: mx11(getSize8(2), "invisible")
1111
- }), /* @__PURE__ */ React18.createElement("span", {
1359
+ className: mx17(getSize9(2), "invisible")
1360
+ }), /* @__PURE__ */ React22.createElement("span", {
1112
1361
  className: "grow"
1113
- }, t("continue label")), /* @__PURE__ */ React18.createElement(CaretRight4, {
1362
+ }, t("continue label")), /* @__PURE__ */ React22.createElement(CaretRight4, {
1114
1363
  weight: "bold",
1115
- className: getSize8(4)
1116
- })), /* @__PURE__ */ React18.createElement(Button7, {
1364
+ className: getSize9(4)
1365
+ })), /* @__PURE__ */ React22.createElement(Button8, {
1117
1366
  disabled,
1118
1367
  onClick: () => dispatch({
1119
1368
  type: "add identity"
1120
1369
  }),
1121
- className: "flex items-center gap-2 pis-2 pie-4"
1122
- }, /* @__PURE__ */ React18.createElement(CaretLeft4, {
1370
+ className: "flex items-center gap-2 pis-2 pie-4",
1371
+ "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-back`
1372
+ }, /* @__PURE__ */ React22.createElement(CaretLeft4, {
1123
1373
  weight: "bold",
1124
- className: getSize8(4)
1125
- }), /* @__PURE__ */ React18.createElement("span", null, t("back label")))));
1374
+ className: getSize9(4)
1375
+ }), /* @__PURE__ */ React22.createElement("span", null, t("back label")))));
1126
1376
  };
1127
1377
 
1128
1378
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/InvitationAccepted.tsx
1129
- import { CaretLeft as CaretLeft5, Check } from "phosphor-react";
1130
- import React19, { cloneElement as cloneElement2 } from "react";
1379
+ import { CaretLeft as CaretLeft5, Check as Check2 } from "phosphor-react";
1380
+ import React23, { cloneElement as cloneElement4 } from "react";
1131
1381
  import { useInvitationStatus as useInvitationStatus3 } from "@dxos/react-client";
1132
- import { Button as Button8, getSize as getSize9, mx as mx12, useTranslation as useTranslation11 } from "@dxos/react-components";
1133
- function _extends16() {
1134
- _extends16 = Object.assign || function(target) {
1382
+ import { Button as Button9, getSize as getSize10, mx as mx18, useTranslation as useTranslation13 } from "@dxos/react-components";
1383
+ function _extends19() {
1384
+ _extends19 = Object.assign || function(target) {
1135
1385
  for (var i = 1; i < arguments.length; i++) {
1136
1386
  var source = arguments[i];
1137
1387
  for (var key in source) {
@@ -1142,50 +1392,51 @@ function _extends16() {
1142
1392
  }
1143
1393
  return target;
1144
1394
  };
1145
- return _extends16.apply(this, arguments);
1395
+ return _extends19.apply(this, arguments);
1146
1396
  }
1147
1397
  var PureInvitationAcceptedContent = ({ onDone, result, invitationType, doneActionParent, active }) => {
1148
1398
  const disabled = !active;
1149
- const { t } = useTranslation11("os");
1150
- const doneButton = /* @__PURE__ */ React19.createElement(Button8, _extends16({}, onDone && {
1399
+ const { t } = useTranslation13("os");
1400
+ const doneButton = /* @__PURE__ */ React23.createElement(Button9, _extends19({}, onDone && {
1151
1401
  onClick: () => onDone(result)
1152
1402
  }, {
1153
1403
  disabled,
1154
1404
  className: "grow flex items-center gap-2 pli-2",
1155
- "data-autofocus": `${invitationType} invitation acceptor; invitation accepted`
1156
- }), /* @__PURE__ */ React19.createElement(CaretLeft5, {
1405
+ "data-autofocus": `${invitationType} invitation acceptor; invitation accepted`,
1406
+ "data-testid": `${invitationType}-invitation-accepted-done`
1407
+ }), /* @__PURE__ */ React23.createElement(CaretLeft5, {
1157
1408
  weight: "bold",
1158
- className: mx12(getSize9(2), "invisible")
1159
- }), /* @__PURE__ */ React19.createElement("span", {
1409
+ className: mx18(getSize10(2), "invisible")
1410
+ }), /* @__PURE__ */ React23.createElement("span", {
1160
1411
  className: "grow"
1161
- }, t("done label")), /* @__PURE__ */ React19.createElement(Check, {
1412
+ }, t("done label")), /* @__PURE__ */ React23.createElement(Check2, {
1162
1413
  weight: "bold",
1163
- className: getSize9(4)
1414
+ className: getSize10(4)
1164
1415
  }));
1165
- return doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneButton) : doneButton;
1416
+ return doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, doneButton) : doneButton;
1166
1417
  };
1167
1418
  var InvitationAcceptedContent = (props) => {
1168
1419
  const { result } = useInvitationStatus3(props.activeInvitation);
1169
- return /* @__PURE__ */ React19.createElement(PureInvitationAcceptedContent, _extends16({}, props, {
1420
+ return /* @__PURE__ */ React23.createElement(PureInvitationAcceptedContent, _extends19({}, props, {
1170
1421
  result
1171
1422
  }));
1172
1423
  };
1173
1424
  var InvitationAccepted = (props) => {
1174
1425
  const { invitationType: _invitationType, doneActionParent: _doneActionParent, onDone: _onDone, ...viewStateProps } = props;
1175
1426
  const { activeInvitation } = viewStateProps;
1176
- return /* @__PURE__ */ React19.createElement(ViewState, _extends16({}, viewStateProps), !activeInvitation || activeInvitation === true ? /* @__PURE__ */ React19.createElement(PureInvitationAcceptedContent, _extends16({}, props, {
1427
+ return /* @__PURE__ */ React23.createElement(ViewState, _extends19({}, viewStateProps), !activeInvitation || activeInvitation === true ? /* @__PURE__ */ React23.createElement(PureInvitationAcceptedContent, _extends19({}, props, {
1177
1428
  result: null
1178
- })) : /* @__PURE__ */ React19.createElement(InvitationAcceptedContent, _extends16({}, props)));
1429
+ })) : /* @__PURE__ */ React23.createElement(InvitationAcceptedContent, _extends19({}, props)));
1179
1430
  };
1180
1431
 
1181
1432
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/InvitationInput.tsx
1182
1433
  import { CaretLeft as CaretLeft6, CaretRight as CaretRight5 } from "phosphor-react";
1183
- import React20, { useState as useState4 } from "react";
1434
+ import React24, { useState as useState4 } from "react";
1184
1435
  import { InvitationEncoder } from "@dxos/client";
1185
- import { useClient as useClient4 } from "@dxos/react-client";
1186
- import { Button as Button9, getSize as getSize10, Input as Input2, mx as mx13, useTranslation as useTranslation12 } from "@dxos/react-components";
1187
- function _extends17() {
1188
- _extends17 = Object.assign || function(target) {
1436
+ import { useClient as useClient5 } from "@dxos/react-client";
1437
+ import { Button as Button10, getSize as getSize11, Input as Input2, mx as mx19, useTranslation as useTranslation14 } from "@dxos/react-components";
1438
+ function _extends20() {
1439
+ _extends20 = Object.assign || function(target) {
1189
1440
  for (var i = 1; i < arguments.length; i++) {
1190
1441
  var source = arguments[i];
1191
1442
  for (var key in source) {
@@ -1196,22 +1447,22 @@ function _extends17() {
1196
1447
  }
1197
1448
  return target;
1198
1449
  };
1199
- return _extends17.apply(this, arguments);
1450
+ return _extends20.apply(this, arguments);
1200
1451
  }
1201
1452
  var InvitationInput = ({ invitationType, ...viewStateProps }) => {
1202
- const client = useClient4();
1453
+ const client = useClient5();
1203
1454
  const disabled = !viewStateProps.active;
1204
1455
  const { dispatch } = viewStateProps;
1205
- const { t } = useTranslation12("os");
1456
+ const { t } = useTranslation14("os");
1206
1457
  const [inputValue, setInputValue] = useState4("");
1207
1458
  const handleNext = () => dispatch({
1208
1459
  type: "connecting invitation",
1209
1460
  from: invitationType,
1210
1461
  invitation: client[invitationType === "halo" ? "halo" : "echo"].acceptInvitation(InvitationEncoder.decode(inputValue))
1211
1462
  });
1212
- return /* @__PURE__ */ React20.createElement(ViewState, _extends17({}, viewStateProps), /* @__PURE__ */ React20.createElement(Input2, {
1463
+ return /* @__PURE__ */ React24.createElement(ViewState, _extends20({}, viewStateProps), /* @__PURE__ */ React24.createElement(Input2, {
1213
1464
  disabled,
1214
- label: /* @__PURE__ */ React20.createElement(ViewStateHeading, null, t("invitation input label")),
1465
+ label: /* @__PURE__ */ React24.createElement(ViewStateHeading, null, t("invitation input label")),
1215
1466
  onChange: ({ target: { value } }) => setInputValue(value),
1216
1467
  slots: {
1217
1468
  root: {
@@ -1224,44 +1475,47 @@ var InvitationInput = ({ invitationType, ...viewStateProps }) => {
1224
1475
  "data-autofocus": `${invitationType} invitation acceptor; invitation input`,
1225
1476
  onKeyUp: ({ key }) => key === "Enter" && handleNext()
1226
1477
  }
1227
- }
1228
- }), /* @__PURE__ */ React20.createElement("div", {
1478
+ },
1479
+ "data-testid": "invitation-input"
1480
+ }), /* @__PURE__ */ React24.createElement("div", {
1229
1481
  role: "none",
1230
1482
  className: "grow"
1231
- }), /* @__PURE__ */ React20.createElement("div", {
1483
+ }), /* @__PURE__ */ React24.createElement("div", {
1232
1484
  className: "flex gap-2"
1233
- }, /* @__PURE__ */ React20.createElement(Button9, {
1485
+ }, /* @__PURE__ */ React24.createElement(Button10, {
1234
1486
  disabled,
1235
1487
  className: "grow flex items-center gap-2 pli-2 order-2",
1236
- onClick: handleNext
1237
- }, /* @__PURE__ */ React20.createElement(CaretLeft6, {
1488
+ onClick: handleNext,
1489
+ "data-testid": `${invitationType}-invitation-input-continue`
1490
+ }, /* @__PURE__ */ React24.createElement(CaretLeft6, {
1238
1491
  weight: "bold",
1239
- className: mx13(getSize10(2), "invisible")
1240
- }), /* @__PURE__ */ React20.createElement("span", {
1492
+ className: mx19(getSize11(2), "invisible")
1493
+ }), /* @__PURE__ */ React24.createElement("span", {
1241
1494
  className: "grow"
1242
- }, t("continue label")), /* @__PURE__ */ React20.createElement(CaretRight5, {
1495
+ }, t("continue label")), /* @__PURE__ */ React24.createElement(CaretRight5, {
1243
1496
  weight: "bold",
1244
- className: getSize10(4)
1245
- })), /* @__PURE__ */ React20.createElement(Button9, {
1497
+ className: getSize11(4)
1498
+ })), /* @__PURE__ */ React24.createElement(Button10, {
1246
1499
  disabled,
1247
1500
  onClick: () => dispatch({
1248
1501
  type: "add identity"
1249
1502
  }),
1250
- className: "flex items-center gap-2 pis-2 pie-4"
1251
- }, /* @__PURE__ */ React20.createElement(CaretLeft6, {
1503
+ className: "flex items-center gap-2 pis-2 pie-4",
1504
+ "data-testid": `${invitationType}-invitation-input-back`
1505
+ }, /* @__PURE__ */ React24.createElement(CaretLeft6, {
1252
1506
  weight: "bold",
1253
- className: getSize10(4)
1254
- }), /* @__PURE__ */ React20.createElement("span", null, t("back label")))));
1507
+ className: getSize11(4)
1508
+ }), /* @__PURE__ */ React24.createElement("span", null, t("back label")))));
1255
1509
  };
1256
1510
 
1257
1511
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/InvitationRescuer.tsx
1258
1512
  import { ArrowsClockwise, CaretLeft as CaretLeft7, CaretRight as CaretRight6 } from "phosphor-react";
1259
- import React21 from "react";
1513
+ import React25 from "react";
1260
1514
  import { Invitation as Invitation5 } from "@dxos/client";
1261
1515
  import { useInvitationStatus as useInvitationStatus4 } from "@dxos/react-client";
1262
- import { Button as Button10, getSize as getSize11, mx as mx14, useTranslation as useTranslation13 } from "@dxos/react-components";
1263
- function _extends18() {
1264
- _extends18 = Object.assign || function(target) {
1516
+ import { Button as Button11, getSize as getSize12, mx as mx20, useTranslation as useTranslation15 } from "@dxos/react-components";
1517
+ function _extends21() {
1518
+ _extends21 = Object.assign || function(target) {
1265
1519
  for (var i = 1; i < arguments.length; i++) {
1266
1520
  var source = arguments[i];
1267
1521
  for (var key in source) {
@@ -1272,78 +1526,82 @@ function _extends18() {
1272
1526
  }
1273
1527
  return target;
1274
1528
  };
1275
- return _extends18.apply(this, arguments);
1529
+ return _extends21.apply(this, arguments);
1276
1530
  }
1277
1531
  var InvitationActions = ({ activeInvitation, disabled, dispatch, invitationType }) => {
1278
1532
  const { status, cancel } = useInvitationStatus4(activeInvitation);
1279
- const { t } = useTranslation13("os");
1533
+ const { t } = useTranslation15("os");
1280
1534
  switch (status) {
1281
1535
  case Invitation5.State.CONNECTING:
1282
- return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", {
1536
+ return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement("div", {
1283
1537
  role: "none",
1284
1538
  className: "grow"
1285
- }), /* @__PURE__ */ React21.createElement("div", {
1539
+ }), /* @__PURE__ */ React25.createElement("div", {
1286
1540
  className: "flex gap-2"
1287
- }, /* @__PURE__ */ React21.createElement(Button10, {
1541
+ }, /* @__PURE__ */ React25.createElement(Button11, {
1288
1542
  disabled: true,
1289
- className: "grow flex items-center gap-2 pli-2 order-2"
1290
- }, /* @__PURE__ */ React21.createElement(CaretLeft7, {
1543
+ className: "grow flex items-center gap-2 pli-2 order-2",
1544
+ "data-testid": "next"
1545
+ }, /* @__PURE__ */ React25.createElement(CaretLeft7, {
1291
1546
  weight: "bold",
1292
- className: mx14(getSize11(2), "invisible")
1293
- }), /* @__PURE__ */ React21.createElement("span", {
1547
+ className: mx20(getSize12(2), "invisible")
1548
+ }), /* @__PURE__ */ React25.createElement("span", {
1294
1549
  className: "grow"
1295
- }, t("next label")), /* @__PURE__ */ React21.createElement(CaretRight6, {
1550
+ }, t("next label")), /* @__PURE__ */ React25.createElement(CaretRight6, {
1296
1551
  weight: "bold",
1297
- className: getSize11(4)
1298
- })), /* @__PURE__ */ React21.createElement(Button10, {
1552
+ className: getSize12(4)
1553
+ })), /* @__PURE__ */ React25.createElement(Button11, {
1299
1554
  disabled,
1300
1555
  className: "flex items-center gap-2 pis-2 pie-4",
1301
1556
  onClick: cancel,
1302
- "data-autofocus": `${invitationType} invitation acceptor; invitation rescuer`
1303
- }, /* @__PURE__ */ React21.createElement(CaretLeft7, {
1557
+ "data-autofocus": `${invitationType} invitation acceptor; invitation rescuer`,
1558
+ "data-testid": "invitation-rescuer-cancel"
1559
+ }, /* @__PURE__ */ React25.createElement(CaretLeft7, {
1304
1560
  weight: "bold",
1305
- className: getSize11(4)
1306
- }), /* @__PURE__ */ React21.createElement("span", null, t("cancel label")))));
1561
+ className: getSize12(4)
1562
+ }), /* @__PURE__ */ React25.createElement("span", null, t("cancel label")))));
1307
1563
  case Invitation5.State.TIMEOUT:
1308
1564
  case Invitation5.State.CANCELLED:
1309
1565
  case Invitation5.State.ERROR:
1310
1566
  default:
1311
- return /* @__PURE__ */ React21.createElement(Button10, {
1567
+ return /* @__PURE__ */ React25.createElement(Button11, {
1312
1568
  disabled,
1313
1569
  className: "grow flex items-center gap-2 pli-2",
1314
1570
  onClick: () => dispatch({
1315
1571
  type: "reset invitation",
1316
1572
  from: invitationType
1317
1573
  }),
1318
- "data-autofocus": `${invitationType} invitation acceptor; invitation rescuer`
1319
- }, /* @__PURE__ */ React21.createElement(CaretLeft7, {
1574
+ "data-autofocus": `${invitationType} invitation acceptor; invitation rescuer`,
1575
+ "data-testid": "invitation-rescuer-reset"
1576
+ }, /* @__PURE__ */ React25.createElement(CaretLeft7, {
1320
1577
  weight: "bold",
1321
- className: mx14(getSize11(5), "invisible")
1322
- }), /* @__PURE__ */ React21.createElement("span", {
1578
+ className: mx20(getSize12(5), "invisible")
1579
+ }), /* @__PURE__ */ React25.createElement("span", {
1323
1580
  className: "grow"
1324
- }, t("reset label")), /* @__PURE__ */ React21.createElement(ArrowsClockwise, {
1581
+ }, t("reset label")), /* @__PURE__ */ React25.createElement(ArrowsClockwise, {
1325
1582
  weight: "bold",
1326
- className: getSize11(5)
1583
+ className: getSize12(5)
1327
1584
  }));
1328
1585
  }
1329
1586
  };
1330
1587
  var InvitationRescuer = ({ invitationType, ...viewStateProps }) => {
1331
1588
  const disabled = !viewStateProps.active;
1332
1589
  const { dispatch, activeInvitation } = viewStateProps;
1333
- const { t } = useTranslation13("os");
1334
- return /* @__PURE__ */ React21.createElement(ViewState, _extends18({}, viewStateProps), activeInvitation === true || !activeInvitation ? /* @__PURE__ */ React21.createElement(Button10, {
1590
+ const { t } = useTranslation15("os");
1591
+ return /* @__PURE__ */ React25.createElement(ViewState, _extends21({}, viewStateProps), activeInvitation === true || !activeInvitation ? /* @__PURE__ */ React25.createElement(Button11, {
1335
1592
  disabled,
1336
1593
  className: "grow flex items-center gap-2 pli-2",
1337
- "data-autofocus": "space invitation acceptor; invitation rescuer"
1338
- }, /* @__PURE__ */ React21.createElement(CaretLeft7, {
1594
+ "data-autofocus": "space invitation acceptor; invitation rescuer",
1595
+ "data-testid": "invitation-rescuer-connect"
1596
+ }, /* @__PURE__ */ React25.createElement(CaretLeft7, {
1339
1597
  weight: "bold",
1340
- className: mx14(getSize11(5), "invisible")
1341
- }), /* @__PURE__ */ React21.createElement("span", {
1598
+ className: mx20(getSize12(5), "invisible")
1599
+ }), /* @__PURE__ */ React25.createElement("span", {
1342
1600
  className: "grow"
1343
- }, t("connect label")), /* @__PURE__ */ React21.createElement(ArrowsClockwise, {
1601
+ }, t("connect label")), /* @__PURE__ */ React25.createElement(ArrowsClockwise, {
1344
1602
  weight: "bold",
1345
- className: getSize11(5)
1346
- })) : /* @__PURE__ */ React21.createElement(InvitationActions, _extends18({}, {
1603
+ className: getSize12(5)
1604
+ })) : /* @__PURE__ */ React25.createElement(InvitationActions, _extends21({}, {
1347
1605
  activeInvitation,
1348
1606
  disabled,
1349
1607
  dispatch,
@@ -1353,11 +1611,11 @@ var InvitationRescuer = ({ invitationType, ...viewStateProps }) => {
1353
1611
 
1354
1612
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/view-states/InvitationAuthenticator.tsx
1355
1613
  import { CaretLeft as CaretLeft8, CaretRight as CaretRight7 } from "phosphor-react";
1356
- import React22, { useCallback as useCallback5, useState as useState5 } from "react";
1614
+ import React26, { useCallback as useCallback5, useState as useState5 } from "react";
1357
1615
  import { useInvitationStatus as useInvitationStatus5 } from "@dxos/react-client";
1358
- import { Button as Button11, getSize as getSize12, Input as Input3, mx as mx15, useTranslation as useTranslation14 } from "@dxos/react-components";
1359
- function _extends19() {
1360
- _extends19 = Object.assign || function(target) {
1616
+ import { Button as Button12, getSize as getSize13, Input as Input3, mx as mx21, useTranslation as useTranslation16 } from "@dxos/react-components";
1617
+ function _extends22() {
1618
+ _extends22 = Object.assign || function(target) {
1361
1619
  for (var i = 1; i < arguments.length; i++) {
1362
1620
  var source = arguments[i];
1363
1621
  for (var key in source) {
@@ -1368,13 +1626,13 @@ function _extends19() {
1368
1626
  }
1369
1627
  return target;
1370
1628
  };
1371
- return _extends19.apply(this, arguments);
1629
+ return _extends22.apply(this, arguments);
1372
1630
  }
1373
1631
  var pinLength = 6;
1374
1632
  var PureInvitationAuthenticatorContent = ({ disabled, failed, dispatch, invitationType, onChange, onAuthenticate }) => {
1375
- const { t } = useTranslation14("os");
1376
- return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(Input3, _extends19({
1377
- label: t("pin input label"),
1633
+ const { t } = useTranslation16("os");
1634
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(Input3, _extends22({
1635
+ label: t("auth code input label"),
1378
1636
  size: "pin",
1379
1637
  length: pinLength,
1380
1638
  onChange,
@@ -1399,35 +1657,39 @@ var PureInvitationAuthenticatorContent = ({ disabled, failed, dispatch, invitati
1399
1657
  }, failed && {
1400
1658
  validationValence: "error",
1401
1659
  validationMessage: t("failed to authenticate message")
1402
- })), /* @__PURE__ */ React22.createElement("div", {
1660
+ }, {
1661
+ "data-testid": "auth-code-input"
1662
+ })), /* @__PURE__ */ React26.createElement("div", {
1403
1663
  role: "none",
1404
1664
  className: "grow"
1405
- }), /* @__PURE__ */ React22.createElement("div", {
1665
+ }), /* @__PURE__ */ React26.createElement("div", {
1406
1666
  className: "flex gap-2"
1407
- }, /* @__PURE__ */ React22.createElement(Button11, {
1667
+ }, /* @__PURE__ */ React26.createElement(Button12, {
1408
1668
  disabled,
1409
1669
  className: "grow flex items-center gap-2 pli-2 order-2",
1410
1670
  onClick: onAuthenticate,
1411
- "data-autofocus-pinlength": invitationType
1412
- }, /* @__PURE__ */ React22.createElement(CaretLeft8, {
1671
+ "data-autofocus-pinlength": invitationType,
1672
+ "data-testid": `${invitationType}-invitation-authenticator-next`
1673
+ }, /* @__PURE__ */ React26.createElement(CaretLeft8, {
1413
1674
  weight: "bold",
1414
- className: mx15(getSize12(2), "invisible")
1415
- }), /* @__PURE__ */ React22.createElement("span", {
1675
+ className: mx21(getSize13(2), "invisible")
1676
+ }), /* @__PURE__ */ React26.createElement("span", {
1416
1677
  className: "grow"
1417
- }, t("next label")), /* @__PURE__ */ React22.createElement(CaretRight7, {
1678
+ }, t("next label")), /* @__PURE__ */ React26.createElement(CaretRight7, {
1418
1679
  weight: "bold",
1419
- className: getSize12(4)
1420
- })), /* @__PURE__ */ React22.createElement(Button11, {
1680
+ className: getSize13(4)
1681
+ })), /* @__PURE__ */ React26.createElement(Button12, {
1421
1682
  disabled,
1422
1683
  className: "flex items-center gap-2 pis-2 pie-4",
1423
1684
  onClick: () => dispatch({
1424
1685
  type: "cancel invitation",
1425
1686
  from: invitationType
1426
- })
1427
- }, /* @__PURE__ */ React22.createElement(CaretLeft8, {
1687
+ }),
1688
+ "data-testid": `${invitationType}-invitation-authenticator-cancel`
1689
+ }, /* @__PURE__ */ React26.createElement(CaretLeft8, {
1428
1690
  weight: "bold",
1429
- className: getSize12(4)
1430
- }), /* @__PURE__ */ React22.createElement("span", null, t("cancel label")))));
1691
+ className: getSize13(4)
1692
+ }), /* @__PURE__ */ React26.createElement("span", null, t("cancel label")))));
1431
1693
  };
1432
1694
  var InvitationAuthenticatorContent = ({ disabled, invitation, dispatch, invitationType, failed }) => {
1433
1695
  const [pinValue, setPinValue] = useState5("");
@@ -1454,7 +1716,7 @@ var InvitationAuthenticatorContent = ({ disabled, invitation, dispatch, invitati
1454
1716
  authenticate,
1455
1717
  pinValue
1456
1718
  ]);
1457
- return /* @__PURE__ */ React22.createElement(PureInvitationAuthenticatorContent, _extends19({}, {
1719
+ return /* @__PURE__ */ React26.createElement(PureInvitationAuthenticatorContent, _extends22({}, {
1458
1720
  disabled,
1459
1721
  failed,
1460
1722
  dispatch,
@@ -1466,7 +1728,7 @@ var InvitationAuthenticatorContent = ({ disabled, invitation, dispatch, invitati
1466
1728
  var InvitationAuthenticator = ({ invitationType, failed, ...viewStateProps }) => {
1467
1729
  const disabled = !viewStateProps.active;
1468
1730
  const { activeInvitation, dispatch } = viewStateProps;
1469
- return /* @__PURE__ */ React22.createElement(ViewState, _extends19({}, viewStateProps), !activeInvitation || activeInvitation === true ? /* @__PURE__ */ React22.createElement(PureInvitationAuthenticatorContent, _extends19({}, {
1731
+ return /* @__PURE__ */ React26.createElement(ViewState, _extends22({}, viewStateProps), !activeInvitation || activeInvitation === true ? /* @__PURE__ */ React26.createElement(PureInvitationAuthenticatorContent, _extends22({}, {
1470
1732
  disabled,
1471
1733
  failed,
1472
1734
  dispatch,
@@ -1475,7 +1737,7 @@ var InvitationAuthenticator = ({ invitationType, failed, ...viewStateProps }) =>
1475
1737
  },
1476
1738
  onAuthenticate: () => {
1477
1739
  }
1478
- })) : /* @__PURE__ */ React22.createElement(InvitationAuthenticatorContent, _extends19({}, {
1740
+ })) : /* @__PURE__ */ React26.createElement(InvitationAuthenticatorContent, _extends22({}, {
1479
1741
  disabled,
1480
1742
  failed,
1481
1743
  invitation: activeInvitation,
@@ -1485,8 +1747,8 @@ var InvitationAuthenticator = ({ invitationType, failed, ...viewStateProps }) =>
1485
1747
  };
1486
1748
 
1487
1749
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/JoinPanel.tsx
1488
- function _extends20() {
1489
- _extends20 = Object.assign || function(target) {
1750
+ function _extends23() {
1751
+ _extends23 = Object.assign || function(target) {
1490
1752
  for (var i = 1; i < arguments.length; i++) {
1491
1753
  var source = arguments[i];
1492
1754
  for (var key in source) {
@@ -1497,13 +1759,14 @@ function _extends20() {
1497
1759
  }
1498
1760
  return target;
1499
1761
  };
1500
- return _extends20.apply(this, arguments);
1762
+ return _extends23.apply(this, arguments);
1501
1763
  }
1502
- var JoinPanel = ({ initialInvitationCode, titleId: propsTitleId, exitActionParent, onExit, doneActionParent, onDone }) => {
1503
- const client = useClient5();
1504
- const internalTitleId = useId3("joinPanel__title");
1764
+ var JoinPanel = ({ mode, initialInvitationCode, titleId: propsTitleId, exitActionParent, onExit, doneActionParent, onDone, preventExit }) => {
1765
+ const client = useClient6();
1766
+ const internalTitleId = useId4("joinPanel__title");
1505
1767
  const titleId = propsTitleId != null ? propsTitleId : internalTitleId;
1506
- const identity = useIdentity();
1768
+ const identity = useIdentity2();
1769
+ const [prevIdentity, setPrevIdentity] = useState6(identity);
1507
1770
  const availableIdentities = identity ? [
1508
1771
  identity
1509
1772
  ] : [];
@@ -1524,7 +1787,7 @@ var JoinPanel = ({ initialInvitationCode, titleId: propsTitleId, exitActionParen
1524
1787
  if (action.method === "accept device invitation") {
1525
1788
  nextState.activeView = "halo invitation acceptor";
1526
1789
  if (state.unredeemedHaloInvitationCode) {
1527
- nextState.haloInvitation = client.echo.acceptInvitation(InvitationEncoder2.decode(state.unredeemedHaloInvitationCode));
1790
+ nextState.haloInvitation = client.halo.acceptInvitation(InvitationEncoder2.decode(state.unredeemedHaloInvitationCode));
1528
1791
  nextState.unredeemedHaloInvitationCode = void 0;
1529
1792
  nextState.haloViewState = "invitation authenticator";
1530
1793
  } else {
@@ -1588,20 +1851,21 @@ var JoinPanel = ({ initialInvitationCode, titleId: propsTitleId, exitActionParen
1588
1851
  nextState[action.from === "halo" ? "haloViewState" : "spaceViewState"] = "invitation input";
1589
1852
  break;
1590
1853
  }
1591
- log.debug("[join panel reducer]", {
1854
+ log("[join panel reducer]", {
1592
1855
  action,
1593
1856
  nextState
1594
1857
  }, {
1595
1858
  file: "JoinPanel.tsx",
1596
- line: 123,
1859
+ line: 125,
1597
1860
  scope: void 0,
1598
1861
  callSite: (f, a) => f(...a)
1599
1862
  });
1600
1863
  return nextState;
1601
1864
  };
1602
- const [joinState, dispatch] = useReducer(reducer, {
1603
- unredeemedHaloInvitationCode: void 0,
1604
- unredeemedSpaceInvitationCode: initialInvitationCode,
1865
+ const unredeemedHaloInvitationCode = mode === "halo-only" ? initialInvitationCode : void 0;
1866
+ const [joinState, dispatch] = useReducer2(reducer, {
1867
+ unredeemedHaloInvitationCode,
1868
+ unredeemedSpaceInvitationCode: mode === "halo-only" ? void 0 : initialInvitationCode,
1605
1869
  spaceInvitation: void 0,
1606
1870
  haloInvitation: void 0,
1607
1871
  activeView: availableIdentities.length > 0 ? "identity selector" : "addition method selector",
@@ -1610,13 +1874,30 @@ var JoinPanel = ({ initialInvitationCode, titleId: propsTitleId, exitActionParen
1610
1874
  spaceViewState: "invitation input",
1611
1875
  haloViewState: "invitation input"
1612
1876
  });
1877
+ if (identity !== prevIdentity) {
1878
+ setPrevIdentity(identity);
1879
+ identity && !prevIdentity && dispatch({
1880
+ type: "added identity",
1881
+ identity
1882
+ });
1883
+ }
1884
+ useEffect(() => {
1885
+ if (unredeemedHaloInvitationCode) {
1886
+ dispatch({
1887
+ type: "select addition method",
1888
+ method: "accept device invitation"
1889
+ });
1890
+ }
1891
+ }, [
1892
+ unredeemedHaloInvitationCode
1893
+ ]);
1613
1894
  useEffect(() => {
1614
1895
  const attrValue = joinState.activeView === "identity input" ? `${joinState.activeView}; ${joinState.additionMethod}` : joinState.activeView === "space invitation acceptor" ? `${joinState.activeView}; ${joinState.spaceViewState}` : joinState.activeView === "halo invitation acceptor" ? `${joinState.activeView}; ${joinState.haloViewState}` : joinState.activeView;
1615
- log.debug("[autofocus value]", {
1896
+ log("[autofocus value]", {
1616
1897
  attrValue
1617
1898
  }, {
1618
1899
  file: "JoinPanel.tsx",
1619
- line: 149,
1900
+ line: 163,
1620
1901
  scope: void 0,
1621
1902
  callSite: (f, a) => f(...a)
1622
1903
  });
@@ -1691,45 +1972,49 @@ var JoinPanel = ({ initialInvitationCode, titleId: propsTitleId, exitActionParen
1691
1972
  }, [
1692
1973
  joinState.haloInvitation
1693
1974
  ]);
1694
- return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(JoinHeading, _extends20({}, {
1975
+ return /* @__PURE__ */ React27.createElement(DensityProvider3, {
1976
+ density: "fine"
1977
+ }, /* @__PURE__ */ React27.createElement(JoinHeading, _extends23({}, {
1978
+ mode,
1695
1979
  titleId,
1696
1980
  invitation: joinState.spaceInvitation,
1697
1981
  onExit,
1698
- exitActionParent
1699
- })), /* @__PURE__ */ React23.createElement("div", {
1982
+ exitActionParent,
1983
+ preventExit
1984
+ })), /* @__PURE__ */ React27.createElement("div", {
1700
1985
  role: "none",
1701
1986
  className: "is-full overflow-hidden"
1702
- }, /* @__PURE__ */ React23.createElement("div", {
1987
+ }, /* @__PURE__ */ React27.createElement("div", {
1703
1988
  role: "none",
1704
1989
  className: "flex is-[1300%]",
1705
1990
  "aria-live": "polite"
1706
- }, /* @__PURE__ */ React23.createElement(IdentitySelector, _extends20({}, {
1991
+ }, /* @__PURE__ */ React27.createElement(IdentitySelector, _extends23({}, {
1707
1992
  dispatch,
1708
1993
  availableIdentities,
1709
1994
  active: joinState.activeView === "identity selector"
1710
- })), /* @__PURE__ */ React23.createElement(AdditionMethodSelector, _extends20({}, {
1995
+ })), /* @__PURE__ */ React27.createElement(AdditionMethodSelector, _extends23({}, {
1711
1996
  dispatch,
1712
1997
  availableIdentities,
1713
1998
  active: joinState.activeView === "addition method selector"
1714
- })), /* @__PURE__ */ React23.createElement(IdentityInput, _extends20({}, {
1999
+ })), /* @__PURE__ */ React27.createElement(IdentityInput, _extends23({}, {
1715
2000
  dispatch,
1716
2001
  active: joinState.activeView === "identity input" && joinState.additionMethod === "create identity",
1717
2002
  method: "create identity"
1718
- })), /* @__PURE__ */ React23.createElement(IdentityInput, _extends20({}, {
2003
+ })), /* @__PURE__ */ React27.createElement(IdentityInput, _extends23({}, {
1719
2004
  dispatch,
1720
2005
  active: joinState.activeView === "identity input" && joinState.additionMethod === "recover identity",
1721
2006
  method: "recover identity"
1722
- })), /* @__PURE__ */ React23.createElement(InvitationInput, _extends20({}, {
2007
+ })), /* @__PURE__ */ React27.createElement(InvitationInput, _extends23({}, {
1723
2008
  dispatch,
1724
2009
  activeInvitation: joinState.haloInvitation || true,
1725
2010
  active: joinState.activeView === "halo invitation acceptor" && joinState.haloViewState === "invitation input",
1726
2011
  invitationType: "halo"
1727
- })), /* @__PURE__ */ React23.createElement(InvitationRescuer, _extends20({}, {
2012
+ })), /* @__PURE__ */ React27.createElement(InvitationRescuer, _extends23({}, {
1728
2013
  dispatch,
1729
2014
  activeInvitation: joinState.haloInvitation || true,
1730
2015
  active: joinState.activeView === "halo invitation acceptor" && joinState.haloViewState === "invitation rescuer",
1731
2016
  invitationType: "halo"
1732
- })), /* @__PURE__ */ React23.createElement(InvitationAuthenticator, _extends20({}, {
2017
+ })), /* @__PURE__ */ React27.createElement(InvitationAuthenticator, _extends23({}, {
1733
2018
  dispatch,
1734
2019
  activeInvitation: joinState.haloInvitation || true,
1735
2020
  active: joinState.activeView === "halo invitation acceptor" && joinState.haloViewState === "invitation authenticator",
@@ -1737,28 +2022,33 @@ var JoinPanel = ({ initialInvitationCode, titleId: propsTitleId, exitActionParen
1737
2022
  ...joinState.spaceInvitationAnnotation === "authentication failed" && {
1738
2023
  failed: true
1739
2024
  }
1740
- })), /* @__PURE__ */ React23.createElement(InvitationAccepted, _extends20({}, {
2025
+ })), /* @__PURE__ */ React27.createElement(InvitationAccepted, _extends23({}, {
1741
2026
  dispatch,
1742
2027
  activeInvitation: joinState.haloInvitation || true,
1743
2028
  active: joinState.activeView === "halo invitation acceptor" && joinState.haloViewState === "invitation accepted",
1744
- invitationType: "halo"
1745
- })), /* @__PURE__ */ React23.createElement(IdentityAdded, _extends20({}, {
2029
+ invitationType: "halo",
2030
+ doneActionParent,
2031
+ onDone
2032
+ })), /* @__PURE__ */ React27.createElement(IdentityAdded, _extends23({}, {
2033
+ mode,
1746
2034
  dispatch,
1747
2035
  addedIdentity: joinState.selectedIdentity,
1748
- active: joinState.activeView === "identity added"
1749
- })), /* @__PURE__ */ React23.createElement(InvitationInput, _extends20({}, {
2036
+ active: joinState.activeView === "identity added",
2037
+ doneActionParent,
2038
+ onDone
2039
+ })), /* @__PURE__ */ React27.createElement(InvitationInput, _extends23({}, {
1750
2040
  dispatch,
1751
2041
  activeInvitation: joinState.spaceInvitation || true,
1752
2042
  selectedIdentity: joinState.selectedIdentity,
1753
2043
  active: joinState.activeView === "space invitation acceptor" && joinState.spaceViewState === "invitation input",
1754
2044
  invitationType: "space"
1755
- })), /* @__PURE__ */ React23.createElement(InvitationRescuer, _extends20({}, {
2045
+ })), /* @__PURE__ */ React27.createElement(InvitationRescuer, _extends23({}, {
1756
2046
  dispatch,
1757
2047
  activeInvitation: joinState.spaceInvitation || true,
1758
2048
  selectedIdentity: joinState.selectedIdentity,
1759
2049
  active: joinState.activeView === "space invitation acceptor" && joinState.spaceViewState === "invitation rescuer",
1760
2050
  invitationType: "space"
1761
- })), /* @__PURE__ */ React23.createElement(InvitationAuthenticator, _extends20({}, {
2051
+ })), /* @__PURE__ */ React27.createElement(InvitationAuthenticator, _extends23({}, {
1762
2052
  dispatch,
1763
2053
  activeInvitation: joinState.spaceInvitation || true,
1764
2054
  selectedIdentity: joinState.selectedIdentity,
@@ -1767,7 +2057,7 @@ var JoinPanel = ({ initialInvitationCode, titleId: propsTitleId, exitActionParen
1767
2057
  ...joinState.spaceInvitationAnnotation === "authentication failed" && {
1768
2058
  failed: true
1769
2059
  }
1770
- })), /* @__PURE__ */ React23.createElement(InvitationAccepted, _extends20({}, {
2060
+ })), /* @__PURE__ */ React27.createElement(InvitationAccepted, _extends23({}, {
1771
2061
  dispatch,
1772
2062
  activeInvitation: joinState.spaceInvitation || true,
1773
2063
  selectedIdentity: joinState.selectedIdentity,
@@ -1778,9 +2068,81 @@ var JoinPanel = ({ initialInvitationCode, titleId: propsTitleId, exitActionParen
1778
2068
  })))));
1779
2069
  };
1780
2070
 
2071
+ // packages/apps/patterns/react-ui/src/panels/SpacePanel/SpacePanel.tsx
2072
+ import { UserPlus as UserPlus3 } from "phosphor-react";
2073
+ import React28, { useReducer as useReducer3 } from "react";
2074
+ import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client";
2075
+ import { Button as Button13, DensityProvider as DensityProvider4, getSize as getSize14, mx as mx22, useTranslation as useTranslation17 } from "@dxos/react-components";
2076
+ function _extends24() {
2077
+ _extends24 = Object.assign || function(target) {
2078
+ for (var i = 1; i < arguments.length; i++) {
2079
+ var source = arguments[i];
2080
+ for (var key in source) {
2081
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
2082
+ target[key] = source[key];
2083
+ }
2084
+ }
2085
+ }
2086
+ return target;
2087
+ };
2088
+ return _extends24.apply(this, arguments);
2089
+ }
2090
+ var CurrentSpaceView = ({ space, createInvitationUrl, titleId }) => {
2091
+ const { t } = useTranslation17("os");
2092
+ const invitations = useSpaceInvitations2(space == null ? void 0 : space.key);
2093
+ const name = space == null ? void 0 : space.properties.name;
2094
+ if (!space) {
2095
+ return null;
2096
+ }
2097
+ return /* @__PURE__ */ React28.createElement("div", {
2098
+ role: "none",
2099
+ className: "flex flex-col"
2100
+ }, /* @__PURE__ */ React28.createElement("div", {
2101
+ role: "none",
2102
+ className: mx22(subduedSurface, "rounded-bs-md flex items-center p-2 gap-2")
2103
+ }, /* @__PURE__ */ React28.createElement("h2", {
2104
+ id: titleId,
2105
+ className: mx22("grow font-system-medium", !name && "font-mono")
2106
+ }, name != null ? name : space.key.truncate())), /* @__PURE__ */ React28.createElement("div", {
2107
+ role: "region",
2108
+ className: mx22(defaultSurface, "rounded-be-md p-2")
2109
+ }, /* @__PURE__ */ React28.createElement(InvitationList, {
2110
+ invitations,
2111
+ onClickRemove: ({ invitation }) => invitation && (space == null ? void 0 : space.removeInvitation(invitation.invitationId)),
2112
+ createInvitationUrl
2113
+ }), /* @__PURE__ */ React28.createElement(Button13, {
2114
+ className: "is-full flex gap-2 mbs-2",
2115
+ onClick: () => space == null ? void 0 : space.createInvitation(),
2116
+ "data-testid": "create-space-invitation"
2117
+ }, /* @__PURE__ */ React28.createElement("span", null, t("create space invitation label")), /* @__PURE__ */ React28.createElement(UserPlus3, {
2118
+ className: getSize14(4),
2119
+ weight: "bold"
2120
+ })), /* @__PURE__ */ React28.createElement(PanelSeparator, null), /* @__PURE__ */ React28.createElement(SpaceMemberListContainer, {
2121
+ spaceKey: space.key,
2122
+ includeSelf: true
2123
+ })));
2124
+ };
2125
+ var SpacePanel = (props) => {
2126
+ const reducer = (state, action) => {
2127
+ const nextState = {
2128
+ ...state
2129
+ };
2130
+ switch (action.type) {
2131
+ case null:
2132
+ }
2133
+ return nextState;
2134
+ };
2135
+ const [panelState] = useReducer3(reducer, {
2136
+ activeView: "current space"
2137
+ });
2138
+ return /* @__PURE__ */ React28.createElement(DensityProvider4, {
2139
+ density: "fine"
2140
+ }, panelState.activeView === "current space" ? /* @__PURE__ */ React28.createElement(CurrentSpaceView, _extends24({}, props)) : null);
2141
+ };
2142
+
1781
2143
  // packages/apps/patterns/react-ui/src/composites/IdentityPopover/IdentityPopover.tsx
1782
- function _extends21() {
1783
- _extends21 = Object.assign || function(target) {
2144
+ function _extends25() {
2145
+ _extends25 = Object.assign || function(target) {
1784
2146
  for (var i = 1; i < arguments.length; i++) {
1785
2147
  var source = arguments[i];
1786
2148
  for (var key in source) {
@@ -1791,26 +2153,26 @@ function _extends21() {
1791
2153
  }
1792
2154
  return target;
1793
2155
  };
1794
- return _extends21.apply(this, arguments);
2156
+ return _extends25.apply(this, arguments);
1795
2157
  }
1796
2158
  var IdentityPopover = ({ identity, openTrigger, slots, triggerIsInToolbar = true, onClickManageProfile, ...popoverProps }) => {
1797
- var _a, _b;
1798
- return /* @__PURE__ */ React24.createElement(PanelPopover, _extends21({}, popoverProps, {
1799
- openTrigger: openTrigger != null ? openTrigger : /* @__PURE__ */ React24.createElement(Avatar7, {
2159
+ var _a, _b, _c;
2160
+ return /* @__PURE__ */ React29.createElement(PanelPopover, _extends25({}, popoverProps, {
2161
+ openTrigger: openTrigger != null ? openTrigger : /* @__PURE__ */ React29.createElement(Avatar8, {
1800
2162
  size: 10,
1801
2163
  variant: "circle",
1802
2164
  fallbackValue: identity.identityKey.toHex(),
1803
- label: (_a = identity.displayName) != null ? _a : ""
2165
+ label: (_b = (_a = identity.profile) == null ? void 0 : _a.displayName) != null ? _b : ""
1804
2166
  }),
1805
2167
  slots: {
1806
2168
  ...slots,
1807
2169
  trigger: {
1808
2170
  ...slots == null ? void 0 : slots.trigger,
1809
- className: mx16("flex justify-self-end pointer-events-auto bg-white dark:bg-neutral-700 p-0.5 button-elevation rounded-full", (_b = slots == null ? void 0 : slots.trigger) == null ? void 0 : _b.className)
2171
+ className: mx23("flex justify-self-end pointer-events-auto bg-white dark:bg-neutral-700 p-0.5 button-elevation rounded-full", (_c = slots == null ? void 0 : slots.trigger) == null ? void 0 : _c.className)
1810
2172
  }
1811
2173
  },
1812
2174
  triggerIsInToolbar
1813
- }), /* @__PURE__ */ React24.createElement(IdentityPanel, _extends21({}, {
2175
+ }), /* @__PURE__ */ React29.createElement(IdentityPanel, _extends25({}, {
1814
2176
  identity,
1815
2177
  onClickManageProfile
1816
2178
  })));
@@ -1818,10 +2180,10 @@ var IdentityPopover = ({ identity, openTrigger, slots, triggerIsInToolbar = true
1818
2180
 
1819
2181
  // packages/apps/patterns/react-ui/src/composites/JoinDialog/JoinDialog.tsx
1820
2182
  import { Action, Cancel } from "@radix-ui/react-alert-dialog";
1821
- import React25 from "react";
1822
- import { ThemeContext as ThemeContext2, useId as useId4 } from "@dxos/react-components";
1823
- function _extends22() {
1824
- _extends22 = Object.assign || function(target) {
2183
+ import React30 from "react";
2184
+ import { ThemeContext as ThemeContext2, useId as useId5 } from "@dxos/react-components";
2185
+ function _extends26() {
2186
+ _extends26 = Object.assign || function(target) {
1825
2187
  for (var i = 1; i < arguments.length; i++) {
1826
2188
  var source = arguments[i];
1827
2189
  for (var key in source) {
@@ -1832,29 +2194,196 @@ function _extends22() {
1832
2194
  }
1833
2195
  return target;
1834
2196
  };
1835
- return _extends22.apply(this, arguments);
2197
+ return _extends26.apply(this, arguments);
1836
2198
  }
1837
2199
  var JoinDialog = ({ slots, ...joinPanelProps }) => {
1838
- const titleId = useId4("joinDialog__title");
1839
- return /* @__PURE__ */ React25.createElement(PanelAlertDialog, _extends22({}, {
2200
+ const titleId = useId5("joinDialog__title");
2201
+ return /* @__PURE__ */ React30.createElement(PanelAlertDialog, _extends26({}, {
1840
2202
  slots,
1841
2203
  titleId
1842
- }), /* @__PURE__ */ React25.createElement(ThemeContext2.Provider, {
2204
+ }), /* @__PURE__ */ React30.createElement(ThemeContext2.Provider, {
1843
2205
  value: {
1844
2206
  themeVariant: "os"
1845
2207
  }
1846
- }, /* @__PURE__ */ React25.createElement(JoinPanel, _extends22({}, {
2208
+ }, /* @__PURE__ */ React30.createElement(JoinPanel, _extends26({}, {
1847
2209
  ...joinPanelProps,
1848
2210
  titleId,
1849
- exitActionParent: /* @__PURE__ */ React25.createElement(Cancel, {
2211
+ exitActionParent: /* @__PURE__ */ React30.createElement(Cancel, {
1850
2212
  asChild: true
1851
2213
  }),
1852
- doneActionParent: /* @__PURE__ */ React25.createElement(Action, {
2214
+ doneActionParent: /* @__PURE__ */ React30.createElement(Action, {
1853
2215
  asChild: true
1854
2216
  })
1855
2217
  }))));
1856
2218
  };
1857
2219
 
2220
+ // packages/apps/patterns/react-ui/src/composites/Shell/Shell.tsx
2221
+ import React33, { useEffect as useEffect2, useState as useState7 } from "react";
2222
+ import { ShellDisplay, ShellLayout } from "@dxos/protocols/proto/dxos/iframe";
2223
+ import { useClient as useClient7, useSpace as useSpace3, useSpaces } from "@dxos/react-client";
2224
+
2225
+ // packages/apps/patterns/react-ui/src/composites/DevicesDialog/DevicesDialog.tsx
2226
+ import { Close } from "@radix-ui/react-dialog";
2227
+ import React31 from "react";
2228
+ import { ThemeContext as ThemeContext3, useId as useId6 } from "@dxos/react-components";
2229
+ function _extends27() {
2230
+ _extends27 = Object.assign || function(target) {
2231
+ for (var i = 1; i < arguments.length; i++) {
2232
+ var source = arguments[i];
2233
+ for (var key in source) {
2234
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
2235
+ target[key] = source[key];
2236
+ }
2237
+ }
2238
+ }
2239
+ return target;
2240
+ };
2241
+ return _extends27.apply(this, arguments);
2242
+ }
2243
+ var DevicesDialog = ({ slots, ...devicesDialogProps }) => {
2244
+ const titleId = useId6("spaceDialog__title");
2245
+ return /* @__PURE__ */ React31.createElement(PanelDialog, _extends27({}, {
2246
+ slots: {
2247
+ ...slots,
2248
+ root: {
2249
+ onOpenChange: (open) => {
2250
+ var _a;
2251
+ return open || ((_a = devicesDialogProps.onDone) == null ? void 0 : _a.call(devicesDialogProps));
2252
+ },
2253
+ ...slots == null ? void 0 : slots.root
2254
+ }
2255
+ },
2256
+ titleId
2257
+ }), /* @__PURE__ */ React31.createElement(ThemeContext3.Provider, {
2258
+ value: {
2259
+ themeVariant: "os"
2260
+ }
2261
+ }, /* @__PURE__ */ React31.createElement(DevicesPanel, _extends27({}, {
2262
+ ...devicesDialogProps,
2263
+ titleId,
2264
+ doneActionParent: /* @__PURE__ */ React31.createElement(Close, {
2265
+ asChild: true
2266
+ })
2267
+ }))));
2268
+ };
2269
+
2270
+ // packages/apps/patterns/react-ui/src/composites/SpaceDialog/SpaceDialog.tsx
2271
+ import { Close as Close2 } from "@radix-ui/react-dialog";
2272
+ import React32 from "react";
2273
+ import { ThemeContext as ThemeContext4, useId as useId7 } from "@dxos/react-components";
2274
+ function _extends28() {
2275
+ _extends28 = Object.assign || function(target) {
2276
+ for (var i = 1; i < arguments.length; i++) {
2277
+ var source = arguments[i];
2278
+ for (var key in source) {
2279
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
2280
+ target[key] = source[key];
2281
+ }
2282
+ }
2283
+ }
2284
+ return target;
2285
+ };
2286
+ return _extends28.apply(this, arguments);
2287
+ }
2288
+ var SpaceDialog = ({ slots, ...spacePanelProps }) => {
2289
+ const titleId = useId7("spaceDialog__title");
2290
+ return /* @__PURE__ */ React32.createElement(PanelDialog, _extends28({}, {
2291
+ slots: {
2292
+ ...slots,
2293
+ root: {
2294
+ onOpenChange: (open) => {
2295
+ var _a;
2296
+ return open || ((_a = spacePanelProps.onDone) == null ? void 0 : _a.call(spacePanelProps));
2297
+ },
2298
+ ...slots == null ? void 0 : slots.root
2299
+ }
2300
+ },
2301
+ titleId
2302
+ }), /* @__PURE__ */ React32.createElement(ThemeContext4.Provider, {
2303
+ value: {
2304
+ themeVariant: "os"
2305
+ }
2306
+ }, /* @__PURE__ */ React32.createElement(SpacePanel, _extends28({}, {
2307
+ ...spacePanelProps,
2308
+ titleId,
2309
+ doneActionParent: /* @__PURE__ */ React32.createElement(Close2, {
2310
+ asChild: true
2311
+ })
2312
+ }))));
2313
+ };
2314
+
2315
+ // packages/apps/patterns/react-ui/src/composites/Shell/Shell.tsx
2316
+ var Shell = ({ runtime, origin }) => {
2317
+ const [{ layout, invitationCode, spaceKey }, setLayout] = useState7({
2318
+ layout: runtime.layout,
2319
+ invitationCode: runtime.invitationCode,
2320
+ spaceKey: runtime.spaceKey
2321
+ });
2322
+ const client = useClient7();
2323
+ const spaces = useSpaces();
2324
+ const space = useSpace3(spaceKey);
2325
+ useEffect2(() => {
2326
+ return runtime.layoutUpdate.on((request) => setLayout(request));
2327
+ }, [
2328
+ runtime
2329
+ ]);
2330
+ switch (layout) {
2331
+ case ShellLayout.INITIALIZE_IDENTITY:
2332
+ return /* @__PURE__ */ React33.createElement(JoinDialog, {
2333
+ mode: "halo-only",
2334
+ initialInvitationCode: invitationCode,
2335
+ onDone: async () => {
2336
+ spaces.length > 0 || await client.echo.createSpace();
2337
+ await runtime.setAppContext({
2338
+ display: ShellDisplay.NONE
2339
+ });
2340
+ runtime.setLayout(ShellLayout.DEFAULT);
2341
+ }
2342
+ });
2343
+ case ShellLayout.DEVICE_INVITATIONS:
2344
+ return /* @__PURE__ */ React33.createElement(DevicesDialog, {
2345
+ createInvitationUrl: (invitationCode2) => `${origin}?haloInvitationCode=${invitationCode2}`,
2346
+ onDone: async () => {
2347
+ await runtime.setAppContext({
2348
+ display: ShellDisplay.NONE
2349
+ });
2350
+ runtime.setLayout(ShellLayout.DEFAULT);
2351
+ }
2352
+ });
2353
+ case ShellLayout.SPACE_INVITATIONS:
2354
+ return /* @__PURE__ */ React33.createElement(SpaceDialog, {
2355
+ space,
2356
+ createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
2357
+ onDone: async () => {
2358
+ await runtime.setAppContext({
2359
+ display: ShellDisplay.NONE
2360
+ });
2361
+ runtime.setLayout(ShellLayout.DEFAULT);
2362
+ }
2363
+ });
2364
+ case ShellLayout.JOIN_SPACE:
2365
+ return /* @__PURE__ */ React33.createElement(JoinDialog, {
2366
+ initialInvitationCode: invitationCode,
2367
+ onDone: async (result) => {
2368
+ var _a;
2369
+ await runtime.setAppContext({
2370
+ display: ShellDisplay.NONE,
2371
+ spaceKey: (_a = result == null ? void 0 : result.spaceKey) != null ? _a : void 0
2372
+ });
2373
+ runtime.setLayout(ShellLayout.DEFAULT);
2374
+ },
2375
+ onExit: async () => {
2376
+ await runtime.setAppContext({
2377
+ display: ShellDisplay.NONE
2378
+ });
2379
+ runtime.setLayout(ShellLayout.DEFAULT);
2380
+ }
2381
+ });
2382
+ default:
2383
+ return null;
2384
+ }
2385
+ };
2386
+
1858
2387
  // packages/apps/patterns/react-ui/src/translations/locales/en-US.ts
1859
2388
  var en_US_exports = {};
1860
2389
  __export(en_US_exports, {
@@ -1866,7 +2395,9 @@ var os = {
1866
2395
  "sidebar label": "DXOS sidebar",
1867
2396
  "copy invitation code label": "Copy",
1868
2397
  "open share panel label": "Share",
1869
- "join space heading": "<small>Joining</small><large>{{spaceTitle}}</large>",
2398
+ "joining heading": "<small>Joining</small><large>{{name}}</large>",
2399
+ "join space heading": "Join a space",
2400
+ "halo heading": "Initialize device identity",
1870
2401
  "exit label": "Exit",
1871
2402
  "identity selector title": "Join as",
1872
2403
  "identity radio group title": "Select an identity you\u2019ve associated with this device already",
@@ -1874,6 +2405,7 @@ var os = {
1874
2405
  "continue label": "Continue",
1875
2406
  "back label": "Back",
1876
2407
  "next label": "Next",
2408
+ "close label": "Close",
1877
2409
  "auth choices label": "Choose an identity",
1878
2410
  "create identity label": "Create an identity",
1879
2411
  "create identity description": "Create a new identity.",
@@ -1903,8 +2435,16 @@ var os = {
1903
2435
  "cancel label": "Cancel",
1904
2436
  "done label": "Done",
1905
2437
  "reset label": "Start over",
1906
- "pin input label": "The PIN provided by the invitation sender",
1907
- "invitation input label": "Paste an invitation code or URL"
2438
+ "auth code input label": "Auth code provided by the invitation sender",
2439
+ "invitation input label": "Paste an invitation code or URL",
2440
+ "create space invitation label": "Invite",
2441
+ "qr label": "Scan to accept invitation",
2442
+ "empty invitations message": "No pending invitations",
2443
+ "show all spaces label": "All spaces",
2444
+ "all spaces label": "All spaces",
2445
+ "create space label": "Create a new space",
2446
+ "join space label": "Join a space",
2447
+ "show current space label": "Current space"
1908
2448
  };
1909
2449
 
1910
2450
  // packages/apps/patterns/react-ui/src/translations/index.ts
@@ -1912,6 +2452,8 @@ var osTranslations = {
1912
2452
  "en-US": en_US_exports
1913
2453
  };
1914
2454
  export {
2455
+ DeviceList,
2456
+ DevicesPanel,
1915
2457
  IdentityListItem,
1916
2458
  IdentityPanel,
1917
2459
  IdentityPopover,
@@ -1922,12 +2464,17 @@ export {
1922
2464
  JoinDialog,
1923
2465
  JoinPanel,
1924
2466
  PanelAlertDialog,
2467
+ PanelDialog,
1925
2468
  PanelPopover,
1926
2469
  PanelSeparator,
1927
2470
  PanelSidebarContext,
1928
2471
  PanelSidebarProvider,
2472
+ Shell,
2473
+ SpaceDialog,
2474
+ SpaceListItem,
1929
2475
  SpaceMemberList,
1930
2476
  SpaceMemberListContainer,
2477
+ SpacePanel,
1931
2478
  activeBgColor,
1932
2479
  activeStrokeColor,
1933
2480
  activeTextColor,
@@ -1935,6 +2482,8 @@ export {
1935
2482
  cancelledStrokeColor,
1936
2483
  cancelledTextColor,
1937
2484
  defaultArrow,
2485
+ defaultDialogContent,
2486
+ defaultOverlay,
1938
2487
  defaultSurface,
1939
2488
  errorBgColor,
1940
2489
  errorStrokeColor,