@dxos/shell 0.4.7-main.f9d3866 → 0.4.7-next.f4b92be

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 (70) hide show
  1. package/dist/bundle/shell.mjs +63626 -21110
  2. package/dist/bundle/shell.mjs.map +1 -1
  3. package/dist/bundle/shell.umd.js +793 -78
  4. package/dist/bundle/shell.umd.js.map +1 -1
  5. package/dist/bundle/style.css +1 -1
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/react.mjs +768 -591
  8. package/dist/lib/browser/react.mjs.map +4 -4
  9. package/dist/types/src/components/EmojiPicker.d.ts +11 -0
  10. package/dist/types/src/components/EmojiPicker.d.ts.map +1 -0
  11. package/dist/types/src/components/EmojiPicker.js +79 -0
  12. package/dist/types/src/components/EmojiPicker.js.map +1 -0
  13. package/dist/types/src/components/HuePicker.d.ts +11 -0
  14. package/dist/types/src/components/HuePicker.d.ts.map +1 -0
  15. package/dist/types/src/components/HuePicker.js +56 -0
  16. package/dist/types/src/components/HuePicker.js.map +1 -0
  17. package/dist/types/src/components/IdentityList/IdentityListItem.d.ts.map +1 -1
  18. package/dist/types/src/components/IdentityList/IdentityListItem.js +5 -5
  19. package/dist/types/src/components/IdentityList/IdentityListItem.js.map +1 -1
  20. package/dist/types/src/components/InvitationList/InvitationListItem.d.ts.map +1 -1
  21. package/dist/types/src/components/InvitationList/InvitationListItem.js +2 -2
  22. package/dist/types/src/components/InvitationList/InvitationListItem.js.map +1 -1
  23. package/dist/types/src/components/SpaceListItem.d.ts.map +1 -1
  24. package/dist/types/src/components/SpaceListItem.js +2 -3
  25. package/dist/types/src/components/SpaceListItem.js.map +1 -1
  26. package/dist/types/src/components/index.d.ts +2 -0
  27. package/dist/types/src/components/index.d.ts.map +1 -1
  28. package/dist/types/src/components/index.js +2 -0
  29. package/dist/types/src/components/index.js.map +1 -1
  30. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  31. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +6 -5
  32. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  33. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -1
  34. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +12 -3
  35. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -1
  36. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.d.ts.map +1 -1
  37. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js +8 -7
  38. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js.map +1 -1
  39. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js +2 -2
  40. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js.map +1 -1
  41. package/dist/types/src/steps/InvitationManager.d.ts.map +1 -1
  42. package/dist/types/src/steps/InvitationManager.js +5 -4
  43. package/dist/types/src/steps/InvitationManager.js.map +1 -1
  44. package/dist/types/src/translations/locales/en-US.d.ts +21 -0
  45. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  46. package/dist/types/src/translations/locales/en-US.js +21 -0
  47. package/dist/types/src/translations/locales/en-US.js.map +1 -1
  48. package/dist/types/src/util/index.d.ts +0 -1
  49. package/dist/types/src/util/index.d.ts.map +1 -1
  50. package/dist/types/src/util/index.js +0 -1
  51. package/dist/types/src/util/index.js.map +1 -1
  52. package/package.json +22 -21
  53. package/src/components/EmojiPicker.tsx +82 -0
  54. package/src/components/HuePicker.tsx +87 -0
  55. package/src/components/IdentityList/IdentityListItem.tsx +9 -5
  56. package/src/components/InvitationList/InvitationListItem.tsx +2 -2
  57. package/src/components/SpaceListItem.tsx +4 -5
  58. package/src/components/index.ts +2 -0
  59. package/src/panels/IdentityPanel/IdentityPanel.tsx +5 -4
  60. package/src/panels/IdentityPanel/steps/ProfileForm.tsx +29 -7
  61. package/src/panels/JoinPanel/steps/IdentityAdded.tsx +7 -7
  62. package/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx +2 -2
  63. package/src/steps/InvitationManager.tsx +4 -3
  64. package/src/translations/locales/en-US.ts +21 -0
  65. package/src/util/index.ts +0 -1
  66. package/dist/types/src/util/toEmoji.d.ts +0 -2
  67. package/dist/types/src/util/toEmoji.d.ts.map +0 -1
  68. package/dist/types/src/util/toEmoji.js +0 -26
  69. package/dist/types/src/util/toEmoji.js.map +0 -1
  70. package/src/util/toEmoji.ts +0 -22
@@ -139,47 +139,188 @@ var CompoundButton = ({ children, description, before, after, variant = "default
139
139
  }, after));
140
140
  };
141
141
 
142
- // packages/sdk/shell/src/components/IdentityList/DeviceList.tsx
142
+ // packages/sdk/shell/src/components/EmojiPicker.tsx
143
+ import emojiData from "@emoji-mart/data";
144
+ import EmojiMart from "@emoji-mart/react";
145
+ import { ArrowCounterClockwise, CaretDown } from "@phosphor-icons/react";
146
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
147
+ import React4, { useState as useState3 } from "react";
148
+ import { Button as Button2, Popover, useTranslation as useTranslation2, Tooltip as Tooltip2 } from "@dxos/react-ui";
149
+ import { getSize as getSize2 } from "@dxos/react-ui-theme";
150
+ var EmojiPicker = ({ disabled, defaultEmoji, emoji, onChangeEmoji, onClickClear }) => {
151
+ const { t } = useTranslation2("os");
152
+ const [emojiValue, setEmojiValue] = useControllableState({
153
+ prop: emoji,
154
+ onChange: onChangeEmoji,
155
+ defaultProp: defaultEmoji
156
+ });
157
+ const [emojiPickerOpen, setEmojiPickerOpen] = useState3(false);
158
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(Popover.Root, {
159
+ open: emojiPickerOpen,
160
+ onOpenChange: setEmojiPickerOpen
161
+ }, /* @__PURE__ */ React4.createElement(Popover.Trigger, {
162
+ asChild: true
163
+ }, /* @__PURE__ */ React4.createElement(Button2, {
164
+ variant: "ghost",
165
+ classNames: "gap-2 text-2xl plb-1",
166
+ disabled
167
+ }, /* @__PURE__ */ React4.createElement("span", {
168
+ className: "sr-only"
169
+ }, t("select emoji label")), /* @__PURE__ */ React4.createElement("span", {
170
+ className: "grow pis-14"
171
+ }, emojiValue), /* @__PURE__ */ React4.createElement(CaretDown, {
172
+ className: getSize2(4)
173
+ }))), /* @__PURE__ */ React4.createElement(Popover.Content, {
174
+ side: "right",
175
+ onKeyDownCapture: (event) => {
176
+ if (event.key === "Escape") {
177
+ event.stopPropagation();
178
+ setEmojiPickerOpen(false);
179
+ }
180
+ }
181
+ }, /* @__PURE__ */ React4.createElement(EmojiMart, {
182
+ data: emojiData,
183
+ onEmojiSelect: ({ native }) => {
184
+ if (native) {
185
+ setEmojiValue(native);
186
+ setEmojiPickerOpen(false);
187
+ }
188
+ },
189
+ autoFocus: true,
190
+ maxFrequentRows: 0,
191
+ noCountryFlags: true
192
+ }), /* @__PURE__ */ React4.createElement(Popover.Arrow, null))), /* @__PURE__ */ React4.createElement(Tooltip2.Root, null, /* @__PURE__ */ React4.createElement(Tooltip2.Trigger, {
193
+ asChild: true
194
+ }, /* @__PURE__ */ React4.createElement(Button2, {
195
+ variant: "ghost",
196
+ onClick: onClickClear,
197
+ disabled
198
+ }, /* @__PURE__ */ React4.createElement("span", {
199
+ className: "sr-only"
200
+ }, t("clear label")), /* @__PURE__ */ React4.createElement(ArrowCounterClockwise, null))), /* @__PURE__ */ React4.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React4.createElement(Tooltip2.Content, {
201
+ style: {
202
+ zIndex: 70
203
+ },
204
+ side: "right"
205
+ }, t("clear label"), /* @__PURE__ */ React4.createElement(Tooltip2.Arrow, null)))));
206
+ };
207
+
208
+ // packages/sdk/shell/src/components/HuePicker.tsx
209
+ import { ArrowCounterClockwise as ArrowCounterClockwise2, CaretDown as CaretDown2, Check as Check2 } from "@phosphor-icons/react";
210
+ import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
143
211
  import React5 from "react";
212
+ import { Button as Button3, useTranslation as useTranslation3, Tooltip as Tooltip3, DropdownMenu, useThemeContext as useThemeContext2 } from "@dxos/react-ui";
213
+ import { getSize as getSize3, hueTokenThemes } from "@dxos/react-ui-theme";
214
+ var HuePreview = ({ hue }) => {
215
+ const { tx } = useThemeContext2();
216
+ return /* @__PURE__ */ React5.createElement("svg", {
217
+ width: 12,
218
+ height: 12,
219
+ viewBox: "0 0 12 12"
220
+ }, /* @__PURE__ */ React5.createElement("rect", {
221
+ x: 0,
222
+ y: 0,
223
+ width: 12,
224
+ height: 12,
225
+ className: tx("hue.fill", "select--hue__preview", {
226
+ hue
227
+ })
228
+ }));
229
+ };
230
+ var HuePicker = ({ disabled, hue, onChangeHue, defaultHue, onClickClear }) => {
231
+ const { t } = useTranslation3("os");
232
+ const [hueValue, setHueValue] = useControllableState2({
233
+ prop: hue,
234
+ onChange: onChangeHue,
235
+ defaultProp: defaultHue
236
+ });
237
+ return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(DropdownMenu.Root, {
238
+ modal: false
239
+ }, /* @__PURE__ */ React5.createElement(DropdownMenu.Trigger, {
240
+ asChild: true
241
+ }, /* @__PURE__ */ React5.createElement(Button3, {
242
+ variant: "ghost",
243
+ classNames: "gap-2 plb-1",
244
+ disabled
245
+ }, /* @__PURE__ */ React5.createElement("span", {
246
+ className: "sr-only"
247
+ }, t("select hue label")), /* @__PURE__ */ React5.createElement("div", {
248
+ role: "none",
249
+ className: "pis-14 grow flex items-center justify-center gap-2"
250
+ }, /* @__PURE__ */ React5.createElement(HuePreview, {
251
+ hue: hueValue
252
+ }), /* @__PURE__ */ React5.createElement("span", null, t(`${hueValue} label`))), /* @__PURE__ */ React5.createElement(CaretDown2, {
253
+ className: getSize3(4)
254
+ }))), /* @__PURE__ */ React5.createElement(DropdownMenu.Content, {
255
+ side: "right"
256
+ }, /* @__PURE__ */ React5.createElement(DropdownMenu.Viewport, null, Object.keys(hueTokenThemes).map((hue2) => {
257
+ return /* @__PURE__ */ React5.createElement(DropdownMenu.CheckboxItem, {
258
+ key: hue2,
259
+ checked: hue2 === hueValue,
260
+ onCheckedChange: () => setHueValue(hue2)
261
+ }, /* @__PURE__ */ React5.createElement(HuePreview, {
262
+ hue: hue2
263
+ }), /* @__PURE__ */ React5.createElement("span", {
264
+ className: "grow"
265
+ }, t(`${hue2} label`)), /* @__PURE__ */ React5.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React5.createElement(Check2, null)));
266
+ })), /* @__PURE__ */ React5.createElement(DropdownMenu.Arrow, null))), /* @__PURE__ */ React5.createElement(Tooltip3.Root, null, /* @__PURE__ */ React5.createElement(Tooltip3.Trigger, {
267
+ asChild: true
268
+ }, /* @__PURE__ */ React5.createElement(Button3, {
269
+ variant: "ghost",
270
+ onClick: onClickClear,
271
+ disabled
272
+ }, /* @__PURE__ */ React5.createElement("span", {
273
+ className: "sr-only"
274
+ }, t("clear label")), /* @__PURE__ */ React5.createElement(ArrowCounterClockwise2, null))), /* @__PURE__ */ React5.createElement(Tooltip3.Portal, null, /* @__PURE__ */ React5.createElement(Tooltip3.Content, {
275
+ style: {
276
+ zIndex: 70
277
+ },
278
+ side: "right"
279
+ }, t("clear label"), /* @__PURE__ */ React5.createElement(Tooltip3.Arrow, null)))));
280
+ };
281
+
282
+ // packages/sdk/shell/src/components/IdentityList/DeviceList.tsx
283
+ import React7 from "react";
144
284
  import { generateName as generateName2 } from "@dxos/display-name";
145
285
  import { DeviceType } from "@dxos/react-client/halo";
146
- import { List, useTranslation as useTranslation2 } from "@dxos/react-ui";
286
+ import { List, useTranslation as useTranslation4 } from "@dxos/react-ui";
147
287
  import { descriptionText as descriptionText2, mx as mx4 } from "@dxos/react-ui-theme";
148
288
 
149
289
  // packages/sdk/shell/src/components/IdentityList/IdentityListItem.tsx
150
- import React4, { forwardRef } from "react";
290
+ import React6, { forwardRef } from "react";
151
291
  import { generateName } from "@dxos/display-name";
152
292
  import { SpaceMember } from "@dxos/react-client/echo";
153
- import { ListItem, Avatar, useJdenticonHref, useId as useId2 } from "@dxos/react-ui";
293
+ import { ListItem, Avatar, useId as useId2 } from "@dxos/react-ui";
154
294
  import { mx as mx3 } from "@dxos/react-ui-theme";
295
+ import { keyToFallback } from "@dxos/util";
155
296
  var IdentityListItem = /* @__PURE__ */ forwardRef(({ identity, presence, onClick, classNames, ...props }, forwardedRef) => {
156
- const fallbackValue = identity.identityKey.toHex();
297
+ const fallbackValue = keyToFallback(identity.identityKey);
157
298
  const labelId = useId2("identityListItem__label");
158
- const jdenticon = useJdenticonHref(fallbackValue ?? "", 12);
159
299
  const displayName = identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
160
- return /* @__PURE__ */ React4.createElement(ListItem.Root, {
300
+ return /* @__PURE__ */ React6.createElement(ListItem.Root, {
161
301
  ...props,
162
302
  classNames: mx3("flex gap-2 pis-3 pie-1 items-center", onClick && "cursor-pointer", classNames),
163
303
  onClick: () => onClick?.(),
164
304
  "data-testid": "identity-list-item",
165
305
  labelId,
166
306
  ref: forwardedRef
167
- }, /* @__PURE__ */ React4.createElement(Avatar.Root, {
307
+ }, /* @__PURE__ */ React6.createElement(Avatar.Root, {
168
308
  status: presence === SpaceMember.PresenceState.ONLINE ? "active" : "inactive",
169
- labelId
170
- }, /* @__PURE__ */ React4.createElement(Avatar.Frame, {
309
+ labelId,
310
+ hue: identity.profile?.data?.hue || fallbackValue.hue
311
+ }, /* @__PURE__ */ React6.createElement(Avatar.Frame, {
171
312
  classNames: "place-self-center"
172
- }, /* @__PURE__ */ React4.createElement(Avatar.Fallback, {
173
- href: jdenticon
174
- })), /* @__PURE__ */ React4.createElement(Avatar.Label, {
313
+ }, /* @__PURE__ */ React6.createElement(Avatar.Fallback, {
314
+ text: identity.profile?.data?.emoji || fallbackValue.emoji
315
+ })), /* @__PURE__ */ React6.createElement(Avatar.Label, {
175
316
  classNames: "text-sm truncate pli-2"
176
317
  }, displayName)));
177
318
  });
178
319
 
179
320
  // packages/sdk/shell/src/components/IdentityList/DeviceList.tsx
180
321
  var DeviceList = ({ devices, onSelect }) => {
181
- const { t } = useTranslation2("os");
182
- return devices.length > 0 ? /* @__PURE__ */ React5.createElement(List, {
322
+ const { t } = useTranslation4("os");
323
+ return devices.length > 0 ? /* @__PURE__ */ React7.createElement(List, {
183
324
  classNames: "flex flex-col gap-2"
184
325
  }, devices.map((device) => {
185
326
  const deviceType = device.profile?.type || DeviceType.UNKNOWN;
@@ -190,25 +331,25 @@ var DeviceList = ({ devices, onSelect }) => {
190
331
  displayName
191
332
  }
192
333
  };
193
- return /* @__PURE__ */ React5.createElement(IdentityListItem, {
334
+ return /* @__PURE__ */ React7.createElement(IdentityListItem, {
194
335
  key: device.deviceKey.toHex(),
195
336
  identity,
196
337
  presence: device.presence,
197
338
  onClick: onSelect && (() => onSelect(device))
198
339
  });
199
- })) : /* @__PURE__ */ React5.createElement("div", {
340
+ })) : /* @__PURE__ */ React7.createElement("div", {
200
341
  role: "none",
201
342
  className: "grow flex items-center p-2"
202
- }, /* @__PURE__ */ React5.createElement("p", {
343
+ }, /* @__PURE__ */ React7.createElement("p", {
203
344
  className: mx4(descriptionText2, "text-center is-full")
204
345
  }, t("empty device list message")));
205
346
  };
206
347
 
207
348
  // packages/sdk/shell/src/components/IdentityList/SpaceMemberList.tsx
208
- import React6, { useMemo } from "react";
349
+ import React8, { useMemo } from "react";
209
350
  import { useClient } from "@dxos/react-client";
210
351
  import { useMembers } from "@dxos/react-client/echo";
211
- import { useTranslation as useTranslation3, List as List2 } from "@dxos/react-ui";
352
+ import { useTranslation as useTranslation5, List as List2 } from "@dxos/react-ui";
212
353
  import { descriptionText as descriptionText3, mx as mx5 } from "@dxos/react-ui-theme";
213
354
  var SpaceMemberList = ({ spaceKey, includeSelf, onSelect }) => {
214
355
  const client = useClient();
@@ -216,100 +357,42 @@ var SpaceMemberList = ({ spaceKey, includeSelf, onSelect }) => {
216
357
  const members = useMemo(() => includeSelf ? allUnsortedMembers.sort((member) => member.identity.identityKey.equals(client.halo.identity.get().identityKey) ? -1 : 1) : allUnsortedMembers.filter((member) => !member.identity.identityKey.equals(client.halo.identity.get().identityKey)), [
217
358
  allUnsortedMembers
218
359
  ]);
219
- return /* @__PURE__ */ React6.createElement(SpaceMemberListImpl, {
360
+ return /* @__PURE__ */ React8.createElement(SpaceMemberListImpl, {
220
361
  members,
221
362
  onSelect
222
363
  });
223
364
  };
224
365
  var SpaceMemberListImpl = ({ members, onSelect }) => {
225
- const { t } = useTranslation3("os");
366
+ const { t } = useTranslation5("os");
226
367
  const visibleMembers = members.filter((member) => member.identity);
227
- return visibleMembers.length > 0 ? /* @__PURE__ */ React6.createElement(List2, {
368
+ return visibleMembers.length > 0 ? /* @__PURE__ */ React8.createElement(List2, {
228
369
  classNames: "flex flex-col gap-2",
229
370
  "data-testid": "space-members-list"
230
371
  }, visibleMembers.map((member) => {
231
- return /* @__PURE__ */ React6.createElement(IdentityListItem, {
372
+ return /* @__PURE__ */ React8.createElement(IdentityListItem, {
232
373
  key: member.identity.identityKey.toHex(),
233
374
  identity: member.identity,
234
375
  presence: member.presence,
235
376
  onClick: onSelect && (() => onSelect(member))
236
377
  });
237
- })) : /* @__PURE__ */ React6.createElement("div", {
378
+ })) : /* @__PURE__ */ React8.createElement("div", {
238
379
  role: "none",
239
380
  className: "grow flex items-center p-2"
240
- }, /* @__PURE__ */ React6.createElement("p", {
381
+ }, /* @__PURE__ */ React8.createElement("p", {
241
382
  className: mx5(descriptionText3, "text-center is-full mlb-2")
242
383
  }, t("empty space members message")));
243
384
  };
244
385
 
245
386
  // packages/sdk/shell/src/components/InvitationList/InvitationListItem.tsx
246
387
  import { X } from "@phosphor-icons/react";
247
- import React8, { useCallback as useCallback2 } from "react";
248
- import { Invitation as Invitation2, useInvitationStatus } from "@dxos/react-client/invitations";
249
- import { Button as Button2, ListItem as ListItem2, useTranslation as useTranslation4, Avatar as Avatar2, useThemeContext as useThemeContext2, Tooltip as Tooltip2 } from "@dxos/react-ui";
250
- import { focusRing, getSize as getSize2, mx as mx7 } from "@dxos/react-ui-theme";
251
-
252
- // packages/sdk/shell/src/util/invitationStatusValue.ts
253
- import { Invitation } from "@dxos/react-client/invitations";
254
- var invitationStatusValue = /* @__PURE__ */ new Map([
255
- [
256
- Invitation.State.ERROR,
257
- -3
258
- ],
259
- [
260
- Invitation.State.TIMEOUT,
261
- -2
262
- ],
263
- [
264
- Invitation.State.CANCELLED,
265
- -1
266
- ],
267
- [
268
- Invitation.State.INIT,
269
- 0
270
- ],
271
- [
272
- Invitation.State.CONNECTING,
273
- 1
274
- ],
275
- [
276
- Invitation.State.CONNECTED,
277
- 2
278
- ],
279
- [
280
- Invitation.State.READY_FOR_AUTHENTICATION,
281
- 3
282
- ],
283
- [
284
- Invitation.State.AUTHENTICATING,
285
- 4
286
- ],
287
- [
288
- Invitation.State.SUCCESS,
289
- 5
290
- ]
291
- ]);
292
-
293
- // packages/sdk/shell/src/util/toEmoji.ts
294
- import toArray from "lodash.toarray";
295
- var emoji = toArray(
296
- // When changing this set, please check the result in a console or e.g. RunKit (https://runkit.com/thure/642214441dd6ae000855a8de)
297
- // Emoji sometimes use a combination of code points, and some code points aren't visible on their own, so by adding or deleting you may unintentionally create non-visible items.
298
- // This set was chosen from the characters in Unicode Emoji v15.0 based on the following criteria:
299
- // – not people or isolated anthropomorphic faces
300
- // – not flags
301
- // – more concrete than abstract
302
- // – less culturally specific
303
- // – less easily confused with another emoji in the set
304
- // – requires less special knowledge to identify
305
- // – less likely to evoke negative feelings (no meat, no drugs, no weapons, etc)
306
- // – less common as a signifier in UX
307
- "\u{1F479}\u{1F47B}\u{1F47D}\u{1F916}\u{1F383}\u{1F9BE}\u{1F9BF}\u{1F9B7}\u{1F463}\u{1F441}\uFE0F\u{1F9F6}\u{1F451}\u{1F412}\u{1F986}\u{1F989}\u{1F434}\u{1F984}\u{1F41D}\u{1F98B}\u{1F41E}\u{1FAB2}\u{1F422}\u{1F98E}\u{1F995}\u{1F991}\u{1F980}\u{1F420}\u{1F42C}\u{1F40B}\u{1F9AD}\u{1F405}\u{1F406}\u{1F993}\u{1F98D}\u{1F9A7}\u{1F418}\u{1F42B}\u{1F992}\u{1F998}\u{1F9AC}\u{1F416}\u{1F40F}\u{1F98C}\u{1F415}\u{1F408}\u{1F413}\u{1F99A}\u{1F99C}\u{1F9A2}\u{1F9A9}\u{1F9A6}\u{1F401}\u{1F43F}\uFE0F\u{1F335}\u{1F332}\u{1F333}\u{1FAB5}\u{1F331}\u{1F341}\u{1FABA}\u{1F344}\u{1F41A}\u{1FAB8}\u{1FAA8}\u{1F33E}\u{1F337}\u{1F33B}\u2600\uFE0F\u{1F319}\u{1FA90}\u2B50\uFE0F\u26A1\uFE0F\u2604\uFE0F\u{1F525}\u{1F308}\u2601\uFE0F\u{1F4A7}\u26F1\uFE0F\u{1F30A}\u{1F34E}\u{1F34B}\u{1F349}\u{1F347}\u{1FAD0}\u{1F348}\u{1F352}\u{1F351}\u{1F96D}\u{1F34D}\u{1F965}\u{1F95D}\u{1F951}\u{1F336}\uFE0F\u{1F33D}\u{1F955}\u{1F36C}\u{1F95C}\u{1FAD6}\u2615\uFE0F\u{1F375}\u{1F9CA}\u{1F9C2}\u{1F3D4}\uFE0F\u2693\uFE0F\u{1F6DF}\u{1F3DD}\uFE0F\u{1F6F6}\u{1F680}\u{1F6F0}\uFE0F\u26F2\uFE0F\u{1F3F0}\u{1F6B2}\u26FA\uFE0F\u{1F399}\uFE0F\u{1F9F2}\u2699\uFE0F\u{1F529}\u{1F52E}\u{1F52D}\u{1F52C}\u{1F9EC}\u{1F321}\uFE0F\u{1F9FA}\u{1F6CE}\uFE0F\u{1F511}\u{1FA91}\u{1F9F8}\u{1F388}\u{1F380}\u{1F38A}\u267B\uFE0F\u{1F3B5}"
308
- );
309
- var toEmoji = (keyAsHex) => emoji[parseInt(keyAsHex, 16) % emoji.length];
388
+ import React10, { useCallback as useCallback2 } from "react";
389
+ import { Invitation, useInvitationStatus } from "@dxos/react-client/invitations";
390
+ import { Button as Button4, ListItem as ListItem2, useTranslation as useTranslation6, Avatar as Avatar2, useThemeContext as useThemeContext3, Tooltip as Tooltip4 } from "@dxos/react-ui";
391
+ import { focusRing, getSize as getSize4, mx as mx7 } from "@dxos/react-ui-theme";
392
+ import { hexToEmoji } from "@dxos/util";
310
393
 
311
394
  // packages/sdk/shell/src/components/AuthCode.tsx
312
- import React7 from "react";
395
+ import React9 from "react";
313
396
  import { mx as mx6 } from "@dxos/react-ui-theme";
314
397
  var AuthCode = (props) => {
315
398
  const { code, large, classNames } = props;
@@ -319,17 +402,17 @@ var AuthCode = (props) => {
319
402
  const handleCopy = () => {
320
403
  void navigator.clipboard.writeText(code ?? "");
321
404
  };
322
- return /* @__PURE__ */ React7.createElement("span", {
405
+ return /* @__PURE__ */ React9.createElement("span", {
323
406
  className: mx6(large ? "text-6xl" : "text-2xl", "font-mono pli-2.5 flex gap-1.5 rounded cursor-pointer", classNames),
324
407
  onClick: handleCopy
325
- }, /* @__PURE__ */ React7.createElement("span", null, left), /* @__PURE__ */ React7.createElement("span", null, right));
408
+ }, /* @__PURE__ */ React9.createElement("span", null, left), /* @__PURE__ */ React9.createElement("span", null, right));
326
409
  };
327
410
 
328
411
  // packages/sdk/shell/src/components/InvitationList/InvitationListItem.tsx
329
412
  var InvitationListItem = (props) => {
330
413
  const { invitation } = props;
331
414
  const invitationStatus = useInvitationStatus(invitation);
332
- return /* @__PURE__ */ React8.createElement(InvitationListItemImpl, {
415
+ return /* @__PURE__ */ React10.createElement(InvitationListItemImpl, {
333
416
  ...props,
334
417
  invitationStatus
335
418
  });
@@ -339,11 +422,11 @@ var avatarProps = {
339
422
  variant: "circle"
340
423
  };
341
424
  var AvatarStackEffect = ({ animation, status, reverseEffects }) => {
342
- const { tx } = useThemeContext2();
343
- return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("span", {
425
+ const { tx } = useThemeContext3();
426
+ return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement("span", {
344
427
  role: "none",
345
- className: mx7("absolute inline-end-auto opacity-20", reverseEffects ? "inline-start-3" : "inline-start-1", getSize2(avatarProps.size))
346
- }, /* @__PURE__ */ React8.createElement("span", {
428
+ className: mx7("absolute inline-end-auto opacity-20", reverseEffects ? "inline-start-3" : "inline-start-1", getSize4(avatarProps.size))
429
+ }, /* @__PURE__ */ React10.createElement("span", {
347
430
  role: "none",
348
431
  className: tx("avatar.ring", "avatar__ring", {
349
432
  ...avatarProps,
@@ -353,10 +436,10 @@ var AvatarStackEffect = ({ animation, status, reverseEffects }) => {
353
436
  style: {
354
437
  animationDelay: "400ms"
355
438
  }
356
- })), /* @__PURE__ */ React8.createElement("span", {
439
+ })), /* @__PURE__ */ React10.createElement("span", {
357
440
  role: "none",
358
- className: mx7("absolute inline-end-auto opacity-50", reverseEffects ? "inline-start-2" : "inline-start-2", getSize2(avatarProps.size))
359
- }, /* @__PURE__ */ React8.createElement("span", {
441
+ className: mx7("absolute inline-end-auto opacity-50", reverseEffects ? "inline-start-2" : "inline-start-2", getSize4(avatarProps.size))
442
+ }, /* @__PURE__ */ React10.createElement("span", {
360
443
  role: "none",
361
444
  className: tx("avatar.ring", "avatar__ring", {
362
445
  ...avatarProps,
@@ -369,19 +452,19 @@ var AvatarStackEffect = ({ animation, status, reverseEffects }) => {
369
452
  })));
370
453
  };
371
454
  var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationStatus, send, onClickRemove, createInvitationUrl, reverseEffects, ...props }) => {
372
- const { t } = useTranslation4("os");
455
+ const { t } = useTranslation6("os");
373
456
  const { cancel, status: invitationStatus, invitationCode, authCode, type } = propsInvitationStatus;
374
457
  const isCancellable = !([
375
- Invitation2.State.ERROR,
376
- Invitation2.State.TIMEOUT,
377
- Invitation2.State.CANCELLED
458
+ Invitation.State.ERROR,
459
+ Invitation.State.TIMEOUT,
460
+ Invitation.State.CANCELLED
378
461
  ].indexOf(invitationStatus) >= 0);
379
- const showShare = type === Invitation2.Type.MULTIUSE || [
380
- Invitation2.State.INIT,
381
- Invitation2.State.CONNECTING,
382
- Invitation2.State.CONNECTED
462
+ const showShare = type === Invitation.Type.MULTIUSE || [
463
+ Invitation.State.INIT,
464
+ Invitation.State.CONNECTING,
465
+ Invitation.State.CONNECTED
383
466
  ].indexOf(invitationStatus) >= 0;
384
- const showAuthCode = invitationStatus === Invitation2.State.READY_FOR_AUTHENTICATION;
467
+ const showAuthCode = invitationStatus === Invitation.State.READY_FOR_AUTHENTICATION;
385
468
  const handleClickRemove = useCallback2(() => onClickRemove?.(invitation), [
386
469
  invitation,
387
470
  onClickRemove
@@ -389,55 +472,55 @@ var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationSta
389
472
  const invitationUrl = invitationCode && createInvitationUrl(invitationCode);
390
473
  const invitationId = invitation?.get().invitationId;
391
474
  const avatarAnimation = [
392
- Invitation2.State.INIT,
393
- Invitation2.State.CONNECTING,
394
- Invitation2.State.CONNECTED,
395
- Invitation2.State.READY_FOR_AUTHENTICATION,
396
- Invitation2.State.AUTHENTICATING
475
+ Invitation.State.INIT,
476
+ Invitation.State.CONNECTING,
477
+ Invitation.State.CONNECTED,
478
+ Invitation.State.READY_FOR_AUTHENTICATION,
479
+ Invitation.State.AUTHENTICATING
397
480
  ].includes(invitationStatus) ? "pulse" : "none";
398
481
  const avatarError = [
399
- Invitation2.State.ERROR,
400
- Invitation2.State.TIMEOUT,
401
- Invitation2.State.CANCELLED
482
+ Invitation.State.ERROR,
483
+ Invitation.State.TIMEOUT,
484
+ Invitation.State.CANCELLED
402
485
  ].includes(invitationStatus);
403
486
  const avatarGreen = [
404
- Invitation2.State.CONNECTED,
405
- Invitation2.State.READY_FOR_AUTHENTICATION,
406
- Invitation2.State.AUTHENTICATING,
407
- Invitation2.State.SUCCESS
487
+ Invitation.State.CONNECTED,
488
+ Invitation.State.READY_FOR_AUTHENTICATION,
489
+ Invitation.State.AUTHENTICATING,
490
+ Invitation.State.SUCCESS
408
491
  ].includes(invitationStatus);
409
492
  const avatarStatus = avatarError ? "error" : avatarGreen ? "active" : "inactive";
410
- return /* @__PURE__ */ React8.createElement(ListItem2.Root, {
493
+ return /* @__PURE__ */ React10.createElement(ListItem2.Root, {
411
494
  id: invitationCode,
412
495
  ...props,
413
496
  classNames: [
414
497
  "flex gap-2 pis-3 pie-1 items-center relative",
415
498
  props.classNames
416
499
  ]
417
- }, /* @__PURE__ */ React8.createElement(ListItem2.Heading, {
500
+ }, /* @__PURE__ */ React10.createElement(ListItem2.Heading, {
418
501
  classNames: "sr-only"
419
- }, t(type === Invitation2.Type.MULTIUSE ? "invite many list item label" : "invite one list item label")), type === Invitation2.Type.MULTIUSE && /* @__PURE__ */ React8.createElement(AvatarStackEffect, {
502
+ }, t(type === Invitation.Type.MULTIUSE ? "invite many list item label" : "invite one list item label")), type === Invitation.Type.MULTIUSE && /* @__PURE__ */ React10.createElement(AvatarStackEffect, {
420
503
  status: avatarStatus,
421
504
  animation: avatarAnimation,
422
505
  reverseEffects
423
- }), /* @__PURE__ */ React8.createElement(Tooltip2.Root, null, /* @__PURE__ */ React8.createElement(Avatar2.Root, {
506
+ }), /* @__PURE__ */ React10.createElement(Tooltip4.Root, null, /* @__PURE__ */ React10.createElement(Avatar2.Root, {
424
507
  ...avatarProps,
425
508
  animation: avatarAnimation,
426
509
  status: avatarStatus
427
- }, /* @__PURE__ */ React8.createElement(Tooltip2.Trigger, {
510
+ }, /* @__PURE__ */ React10.createElement(Tooltip4.Trigger, {
428
511
  asChild: true
429
- }, /* @__PURE__ */ React8.createElement(Avatar2.Frame, {
512
+ }, /* @__PURE__ */ React10.createElement(Avatar2.Frame, {
430
513
  tabIndex: 0,
431
514
  classNames: [
432
515
  focusRing,
433
516
  "relative rounded-full place-self-center"
434
517
  ]
435
- }, /* @__PURE__ */ React8.createElement(Avatar2.Fallback, {
436
- text: toEmoji(invitationId)
437
- })))), /* @__PURE__ */ React8.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip2.Content, {
518
+ }, /* @__PURE__ */ React10.createElement(Avatar2.Fallback, {
519
+ text: hexToEmoji(invitationId)
520
+ })))), /* @__PURE__ */ React10.createElement(Tooltip4.Portal, null, /* @__PURE__ */ React10.createElement(Tooltip4.Content, {
438
521
  side: "left",
439
522
  classNames: "z-[70]"
440
- }, t(type === Invitation2.Type.MULTIUSE ? "invite many qr label" : "invite one qr label"), /* @__PURE__ */ React8.createElement(Tooltip2.Arrow, null)))), showShare && invitationUrl ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Button2, {
523
+ }, t(type === Invitation.Type.MULTIUSE ? "invite many qr label" : "invite one qr label"), /* @__PURE__ */ React10.createElement(Tooltip4.Arrow, null)))), showShare && invitationUrl ? /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Button4, {
441
524
  variant: "ghost",
442
525
  classNames: "grow justify-start font-medium",
443
526
  onClick: () => send({
@@ -445,60 +528,60 @@ var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationSta
445
528
  invitation
446
529
  }),
447
530
  "data-testid": "show-qrcode"
448
- }, /* @__PURE__ */ React8.createElement("span", null, t("open share panel label"))), /* @__PURE__ */ React8.createElement(CopyButtonIconOnly, {
531
+ }, /* @__PURE__ */ React10.createElement("span", null, t("open share panel label"))), /* @__PURE__ */ React10.createElement(CopyButtonIconOnly, {
449
532
  variant: "ghost",
450
533
  value: invitationUrl
451
- })) : showAuthCode ? /* @__PURE__ */ React8.createElement(AuthCode, {
534
+ })) : showAuthCode ? /* @__PURE__ */ React10.createElement(AuthCode, {
452
535
  code: authCode,
453
536
  classNames: "grow"
454
- }) : invitationStatus === Invitation2.State.CONNECTING ? /* @__PURE__ */ React8.createElement("span", {
537
+ }) : invitationStatus === Invitation.State.CONNECTING ? /* @__PURE__ */ React10.createElement("span", {
455
538
  className: "pli-2 grow text-neutral-500"
456
- }, "Connecting...") : invitationStatus === Invitation2.State.AUTHENTICATING ? /* @__PURE__ */ React8.createElement("span", {
539
+ }, "Connecting...") : invitationStatus === Invitation.State.AUTHENTICATING ? /* @__PURE__ */ React10.createElement("span", {
457
540
  className: "pli-2 grow text-neutral-500"
458
- }, "Authenticating...") : invitationStatus === Invitation2.State.ERROR || invitationStatus === Invitation2.State.TIMEOUT ? /* @__PURE__ */ React8.createElement("span", {
541
+ }, "Authenticating...") : invitationStatus === Invitation.State.ERROR || invitationStatus === Invitation.State.TIMEOUT ? /* @__PURE__ */ React10.createElement("span", {
459
542
  className: "pli-2 grow text-neutral-500"
460
- }, "Failed") : invitationStatus === Invitation2.State.CANCELLED ? /* @__PURE__ */ React8.createElement("span", {
543
+ }, "Failed") : invitationStatus === Invitation.State.CANCELLED ? /* @__PURE__ */ React10.createElement("span", {
461
544
  className: "pli-2 grow text-neutral-500"
462
- }, "Cancelled") : invitationStatus === Invitation2.State.SUCCESS ? /* @__PURE__ */ React8.createElement("span", {
545
+ }, "Cancelled") : invitationStatus === Invitation.State.SUCCESS ? /* @__PURE__ */ React10.createElement("span", {
463
546
  className: "pli-2 grow truncate"
464
- }, "User joined") : /* @__PURE__ */ React8.createElement("span", {
547
+ }, "User joined") : /* @__PURE__ */ React10.createElement("span", {
465
548
  className: "grow"
466
- }, " "), isCancellable ? /* @__PURE__ */ React8.createElement(Button2, {
549
+ }, " "), isCancellable ? /* @__PURE__ */ React10.createElement(Button4, {
467
550
  variant: "ghost",
468
551
  classNames: "flex gap-1 pli-0",
469
552
  onClick: cancel,
470
553
  "data-testid": "cancel-invitation"
471
- }, /* @__PURE__ */ React8.createElement("span", {
554
+ }, /* @__PURE__ */ React10.createElement("span", {
472
555
  className: "sr-only"
473
- }, t("cancel invitation label")), /* @__PURE__ */ React8.createElement(X, {
474
- className: getSize2(4)
475
- })) : /* @__PURE__ */ React8.createElement(Button2, {
556
+ }, t("cancel invitation label")), /* @__PURE__ */ React10.createElement(X, {
557
+ className: getSize4(4)
558
+ })) : /* @__PURE__ */ React10.createElement(Button4, {
476
559
  variant: "ghost",
477
560
  classNames: "flex gap-1 pli-0",
478
561
  onClick: handleClickRemove,
479
562
  "data-testid": "remove-invitation"
480
- }, /* @__PURE__ */ React8.createElement("span", {
563
+ }, /* @__PURE__ */ React10.createElement("span", {
481
564
  className: "sr-only"
482
- }, t("remove invitation label")), /* @__PURE__ */ React8.createElement(X, {
483
- className: getSize2(4)
565
+ }, t("remove invitation label")), /* @__PURE__ */ React10.createElement(X, {
566
+ className: getSize4(4)
484
567
  })));
485
568
  };
486
569
 
487
570
  // packages/sdk/shell/src/components/InvitationList/InvitationListContainer.tsx
488
- import React10, { useCallback as useCallback3 } from "react";
571
+ import React12, { useCallback as useCallback3 } from "react";
489
572
  import { useSpace, useSpaceInvitations } from "@dxos/react-client/echo";
490
573
 
491
574
  // packages/sdk/shell/src/components/InvitationList/InvitationList.tsx
492
- import React9 from "react";
575
+ import React11 from "react";
493
576
  import { List as List3 } from "@dxos/react-ui";
494
577
  import { mx as mx8 } from "@dxos/react-ui-theme";
495
578
  var InvitationList = ({ invitations, send, ...invitationProps }) => {
496
579
  const { className, InvitationListItem: Item = InvitationListItem } = invitationProps;
497
- return /* @__PURE__ */ React9.createElement(List3, {
580
+ return /* @__PURE__ */ React11.createElement(List3, {
498
581
  classNames: mx8("flex flex-col gap-2", className)
499
582
  }, invitations.map((invitation) => {
500
583
  const value = invitation.get().invitationId;
501
- return /* @__PURE__ */ React9.createElement(Item, {
584
+ return /* @__PURE__ */ React11.createElement(Item, {
502
585
  key: value,
503
586
  send,
504
587
  invitation,
@@ -516,7 +599,7 @@ var InvitationListContainer = ({ spaceKey, createInvitationUrl, send }) => {
516
599
  }, [
517
600
  space
518
601
  ]);
519
- return /* @__PURE__ */ React10.createElement(InvitationList, {
602
+ return /* @__PURE__ */ React12.createElement(InvitationList, {
520
603
  invitations,
521
604
  onClickRemove,
522
605
  createInvitationUrl,
@@ -525,11 +608,11 @@ var InvitationListContainer = ({ spaceKey, createInvitationUrl, send }) => {
525
608
  };
526
609
 
527
610
  // packages/sdk/shell/src/components/Panel/Action.tsx
528
- import { CaretDown, Check as Check2, Placeholder } from "@phosphor-icons/react";
529
- import { useControllableState } from "@radix-ui/react-use-controllable-state";
530
- import React11, { forwardRef as forwardRef2 } from "react";
531
- import { Button as Button3, DropdownMenu, useTranslation as useTranslation5 } from "@dxos/react-ui";
532
- import { descriptionText as descriptionText4, getSize as getSize3, mx as mx9 } from "@dxos/react-ui-theme";
611
+ import { CaretDown as CaretDown3, Check as Check3, Placeholder } from "@phosphor-icons/react";
612
+ import { useControllableState as useControllableState3 } from "@radix-ui/react-use-controllable-state";
613
+ import React13, { forwardRef as forwardRef2 } from "react";
614
+ import { Button as Button5, DropdownMenu as DropdownMenu2, useTranslation as useTranslation7 } from "@dxos/react-ui";
615
+ import { descriptionText as descriptionText4, getSize as getSize5, mx as mx9 } from "@dxos/react-ui-theme";
533
616
  var defaultActions = {
534
617
  noopAction: {
535
618
  label: "No-op",
@@ -541,17 +624,17 @@ var defaultActions = {
541
624
  };
542
625
  var BifurcatedAction = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
543
626
  const { classNames, variant, isFull = true, actions = defaultActions, activeAction: propsActiveAction, onChangeActiveAction, defaultActiveAction, ...rest } = props;
544
- const [activeActionKey2 = Object.keys(actions)[0], setActiveAction] = useControllableState({
627
+ const [activeActionKey2 = Object.keys(actions)[0], setActiveAction] = useControllableState3({
545
628
  prop: propsActiveAction,
546
629
  onChange: onChangeActiveAction,
547
630
  defaultProp: defaultActiveAction
548
631
  });
549
632
  const activeAction = actions[activeActionKey2] ?? {};
550
- const { t } = useTranslation5("os");
551
- return /* @__PURE__ */ React11.createElement("div", {
633
+ const { t } = useTranslation7("os");
634
+ return /* @__PURE__ */ React13.createElement("div", {
552
635
  role: "none",
553
636
  className: mx9("mbs-2 flex gap-px items-center", isFull && "is-full")
554
- }, /* @__PURE__ */ React11.createElement(Button3, {
637
+ }, /* @__PURE__ */ React13.createElement(Button5, {
555
638
  ...rest,
556
639
  classNames: [
557
640
  "bs-11 flex-1 min-is-0 flex gap-2 rounded-ie-none",
@@ -560,48 +643,48 @@ var BifurcatedAction = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
560
643
  ref: forwardedRef,
561
644
  variant,
562
645
  onClick: activeAction.onClick
563
- }, activeAction.icon && /* @__PURE__ */ React11.createElement(activeAction.icon, {
564
- className: getSize3(5)
565
- }), /* @__PURE__ */ React11.createElement("span", null, activeAction.label)), /* @__PURE__ */ React11.createElement(DropdownMenu.Root, null, /* @__PURE__ */ React11.createElement(DropdownMenu.Trigger, {
646
+ }, activeAction.icon && /* @__PURE__ */ React13.createElement(activeAction.icon, {
647
+ className: getSize5(5)
648
+ }), /* @__PURE__ */ React13.createElement("span", null, activeAction.label)), /* @__PURE__ */ React13.createElement(DropdownMenu2.Root, null, /* @__PURE__ */ React13.createElement(DropdownMenu2.Trigger, {
566
649
  asChild: true
567
- }, /* @__PURE__ */ React11.createElement(Button3, {
650
+ }, /* @__PURE__ */ React13.createElement(Button5, {
568
651
  classNames: [
569
652
  "bs-11 flex-none rounded-is-none",
570
653
  classNames
571
654
  ]
572
- }, /* @__PURE__ */ React11.createElement("span", {
655
+ }, /* @__PURE__ */ React13.createElement("span", {
573
656
  className: "sr-only"
574
- }, t("invite options label")), /* @__PURE__ */ React11.createElement(CaretDown, {
575
- className: getSize3(4)
576
- }))), /* @__PURE__ */ React11.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React11.createElement(DropdownMenu.Viewport, null, Object.entries(actions).map(([id, action]) => {
577
- return /* @__PURE__ */ React11.createElement(DropdownMenu.CheckboxItem, {
657
+ }, t("invite options label")), /* @__PURE__ */ React13.createElement(CaretDown3, {
658
+ className: getSize5(4)
659
+ }))), /* @__PURE__ */ React13.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React13.createElement(DropdownMenu2.Viewport, null, Object.entries(actions).map(([id, action]) => {
660
+ return /* @__PURE__ */ React13.createElement(DropdownMenu2.CheckboxItem, {
578
661
  key: id,
579
662
  "aria-labelledby": `${id}__label`,
580
663
  "aria-describedby": `${id}__description`,
581
664
  checked: activeActionKey2 === id,
582
665
  onCheckedChange: (checked) => checked && setActiveAction(id),
583
666
  classNames: "gap-2"
584
- }, action.icon && /* @__PURE__ */ React11.createElement(action.icon, {
585
- className: getSize3(5)
586
- }), /* @__PURE__ */ React11.createElement("div", {
667
+ }, action.icon && /* @__PURE__ */ React13.createElement(action.icon, {
668
+ className: getSize5(5)
669
+ }), /* @__PURE__ */ React13.createElement("div", {
587
670
  role: "none",
588
671
  className: "flex-1 min-is-0 space-b-1"
589
- }, /* @__PURE__ */ React11.createElement("p", {
672
+ }, /* @__PURE__ */ React13.createElement("p", {
590
673
  id: `${id}__label`
591
- }, action.label), action.description && /* @__PURE__ */ React11.createElement("p", {
674
+ }, action.label), action.description && /* @__PURE__ */ React13.createElement("p", {
592
675
  id: `${id}__description`,
593
676
  className: descriptionText4
594
- }, action.description)), /* @__PURE__ */ React11.createElement(DropdownMenu.ItemIndicator, {
677
+ }, action.description)), /* @__PURE__ */ React13.createElement(DropdownMenu2.ItemIndicator, {
595
678
  asChild: true
596
- }, /* @__PURE__ */ React11.createElement(Check2, {
679
+ }, /* @__PURE__ */ React13.createElement(Check3, {
597
680
  weight: "bold",
598
- className: getSize3(4)
681
+ className: getSize5(4)
599
682
  })));
600
- })), /* @__PURE__ */ React11.createElement(DropdownMenu.Arrow, null))));
683
+ })), /* @__PURE__ */ React13.createElement(DropdownMenu2.Arrow, null))));
601
684
  });
602
685
  var Action = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
603
686
  const { children, classNames, variant, isFull = true, ...rest } = props;
604
- return /* @__PURE__ */ React11.createElement(Button3, {
687
+ return /* @__PURE__ */ React13.createElement(Button5, {
605
688
  ...rest,
606
689
  classNames: [
607
690
  isFull && "is-full",
@@ -614,10 +697,10 @@ var Action = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
614
697
  });
615
698
 
616
699
  // packages/sdk/shell/src/components/Panel/Actions.tsx
617
- import React12, { forwardRef as forwardRef3 } from "react";
700
+ import React14, { forwardRef as forwardRef3 } from "react";
618
701
  import { mx as mx10 } from "@dxos/react-ui-theme";
619
702
  var Actions = /* @__PURE__ */ forwardRef3(({ classNames, children, ...props }, forwardedRef) => {
620
- return /* @__PURE__ */ React12.createElement("div", {
703
+ return /* @__PURE__ */ React14.createElement("div", {
621
704
  ...props,
622
705
  className: mx10("flex flex-col gap-2 mbs-2", Array.isArray(children) && children.length > 1 ? "justify-between" : "justify-center", classNames),
623
706
  ref: forwardedRef
@@ -626,37 +709,37 @@ var Actions = /* @__PURE__ */ forwardRef3(({ classNames, children, ...props }, f
626
709
 
627
710
  // packages/sdk/shell/src/components/Panel/CloseButton.tsx
628
711
  import { X as X2 } from "@phosphor-icons/react";
629
- import React13 from "react";
630
- import { Button as Button4, useTranslation as useTranslation6 } from "@dxos/react-ui";
631
- import { getSize as getSize4, mx as mx11 } from "@dxos/react-ui-theme";
712
+ import React15 from "react";
713
+ import { Button as Button6, useTranslation as useTranslation8 } from "@dxos/react-ui";
714
+ import { getSize as getSize6, mx as mx11 } from "@dxos/react-ui-theme";
632
715
  var CloseButton = ({ onDone, ...props }) => {
633
- const { t } = useTranslation6("os");
634
- return /* @__PURE__ */ React13.createElement(Button4, {
716
+ const { t } = useTranslation8("os");
717
+ return /* @__PURE__ */ React15.createElement(Button6, {
635
718
  variant: "ghost",
636
719
  classNames: mx11("plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
637
720
  onClick: () => onDone?.(),
638
721
  ...props
639
- }, /* @__PURE__ */ React13.createElement(X2, {
722
+ }, /* @__PURE__ */ React15.createElement(X2, {
640
723
  weight: "bold",
641
- className: getSize4(4)
642
- }), /* @__PURE__ */ React13.createElement("span", {
724
+ className: getSize6(4)
725
+ }), /* @__PURE__ */ React15.createElement("span", {
643
726
  className: "sr-only"
644
727
  }, t("exit label")));
645
728
  };
646
729
 
647
730
  // packages/sdk/shell/src/components/Panel/Emoji.tsx
648
- import React14 from "react";
649
- import { mx as mx12, getSize as getSize5 } from "@dxos/react-ui-theme";
731
+ import React16 from "react";
732
+ import { mx as mx12, getSize as getSize7 } from "@dxos/react-ui-theme";
650
733
  var Emoji = ({ text, className }) => {
651
734
  const size = 14;
652
- return /* @__PURE__ */ React14.createElement("div", {
735
+ return /* @__PURE__ */ React16.createElement("div", {
653
736
  role: "none",
654
- className: mx12(getSize5(size), "rounded relative pointer-events-none", className)
655
- }, /* @__PURE__ */ React14.createElement("svg", {
737
+ className: mx12(getSize7(size), "rounded relative pointer-events-none", className)
738
+ }, /* @__PURE__ */ React16.createElement("svg", {
656
739
  viewBox: `0 0 ${size * 4} ${size * 4}`,
657
740
  width: size * 4,
658
741
  height: size * 4
659
- }, /* @__PURE__ */ React14.createElement("text", {
742
+ }, /* @__PURE__ */ React16.createElement("text", {
660
743
  x: "50%",
661
744
  y: "50%",
662
745
  textAnchor: "middle",
@@ -667,55 +750,55 @@ var Emoji = ({ text, className }) => {
667
750
  };
668
751
  var Centered = (props) => {
669
752
  const { children } = props;
670
- return /* @__PURE__ */ React14.createElement("div", {
753
+ return /* @__PURE__ */ React16.createElement("div", {
671
754
  role: "none",
672
755
  className: "absolute inset-0 flex items-center justify-center"
673
756
  }, children);
674
757
  };
675
758
 
676
759
  // packages/sdk/shell/src/components/Panel/Heading.tsx
677
- import React15, { forwardRef as forwardRef4 } from "react";
760
+ import React17, { forwardRef as forwardRef4 } from "react";
678
761
  import { descriptionText as descriptionText5, mx as mx13 } from "@dxos/react-ui-theme";
679
762
  var Heading = /* @__PURE__ */ forwardRef4(({ titleId, title, titleSrOnly, children, corner }, forwardedRef) => {
680
- return /* @__PURE__ */ React15.createElement("div", {
763
+ return /* @__PURE__ */ React17.createElement("div", {
681
764
  role: "none",
682
765
  className: "pbe-2 relative",
683
766
  ref: forwardedRef
684
- }, corner, /* @__PURE__ */ React15.createElement("h1", {
767
+ }, corner, /* @__PURE__ */ React17.createElement("h1", {
685
768
  ...!titleSrOnly && {
686
769
  id: titleId
687
770
  },
688
771
  className: mx13(descriptionText5, "text-center mlb-2", titleSrOnly && "invisible")
689
- }, title), titleSrOnly && /* @__PURE__ */ React15.createElement("span", {
772
+ }, title), titleSrOnly && /* @__PURE__ */ React17.createElement("span", {
690
773
  id: titleId
691
774
  }, title), children);
692
775
  });
693
776
 
694
777
  // packages/sdk/shell/src/components/Panel/Label.tsx
695
- import React16 from "react";
778
+ import React18 from "react";
696
779
  import { descriptionText as descriptionText6, mx as mx14 } from "@dxos/react-ui-theme";
697
780
  var Label = (props) => {
698
781
  const { children } = props;
699
- return /* @__PURE__ */ React16.createElement("span", {
782
+ return /* @__PURE__ */ React18.createElement("span", {
700
783
  className: mx14(descriptionText6, "text-center mli-6 whitespace-normal")
701
784
  }, children);
702
785
  };
703
786
 
704
787
  // packages/sdk/shell/src/components/Panel/Input.tsx
705
- import React17 from "react";
788
+ import React19 from "react";
706
789
  import { Input as UiInput } from "@dxos/react-ui";
707
790
  var Input = ({ validationMessage, label, ...props }) => {
708
- return /* @__PURE__ */ React17.createElement(UiInput.Root, null, /* @__PURE__ */ React17.createElement(UiInput.Label, null, label), /* @__PURE__ */ React17.createElement(UiInput.TextInput, {
791
+ return /* @__PURE__ */ React19.createElement(UiInput.Root, null, /* @__PURE__ */ React19.createElement(UiInput.Label, null, label), /* @__PURE__ */ React19.createElement(UiInput.TextInput, {
709
792
  ...props,
710
793
  classNames: "plb-3 mbs-2 text-center"
711
- }), /* @__PURE__ */ React17.createElement(UiInput.DescriptionAndValidation, null, validationMessage && /* @__PURE__ */ React17.createElement(UiInput.Validation, null, validationMessage)));
794
+ }), /* @__PURE__ */ React19.createElement(UiInput.DescriptionAndValidation, null, validationMessage && /* @__PURE__ */ React19.createElement(UiInput.Validation, null, validationMessage)));
712
795
  };
713
796
 
714
797
  // packages/sdk/shell/src/components/Panel/StepHeading.tsx
715
- import React18, { forwardRef as forwardRef5 } from "react";
798
+ import React20, { forwardRef as forwardRef5 } from "react";
716
799
  import { mx as mx15 } from "@dxos/react-ui-theme";
717
800
  var StepHeading = /* @__PURE__ */ forwardRef5(({ children, className, ...props }, forwardedRef) => {
718
- return /* @__PURE__ */ React18.createElement("h2", {
801
+ return /* @__PURE__ */ React20.createElement("h2", {
719
802
  ...props,
720
803
  className: mx15("font-normal text-sm mbe-4 mli-1 text-center", className),
721
804
  ref: forwardedRef
@@ -725,8 +808,8 @@ var StepHeading = /* @__PURE__ */ forwardRef5(({ children, className, ...props }
725
808
  // packages/sdk/shell/src/components/Viewport/Viewport.tsx
726
809
  import { useFocusFinders } from "@fluentui/react-tabster";
727
810
  import { createContextScope } from "@radix-ui/react-context";
728
- import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
729
- import React19, { forwardRef as forwardRef6, useEffect } from "react";
811
+ import { useControllableState as useControllableState4 } from "@radix-ui/react-use-controllable-state";
812
+ import React21, { forwardRef as forwardRef6, useEffect } from "react";
730
813
  import { useForwardedRef } from "@dxos/react-ui";
731
814
  import { mx as mx16 } from "@dxos/react-ui-theme";
732
815
  var VIEWPORT_NAME = "Viewport";
@@ -735,17 +818,17 @@ var VIEW_NAME = "ViewportView";
735
818
  var [createViewportContext, createViewportScope] = createContextScope(VIEWPORT_NAME, []);
736
819
  var [ViewportProvider, useViewportContext] = createViewportContext(VIEWPORT_NAME);
737
820
  var ViewportRoot = ({ __viewportScope, classNames, children, defaultActiveView, activeView: propsActiveView, focusManaged = false, onActiveViewChange, ...props }) => {
738
- const [activeView = "never", setActiveView] = useControllableState2({
821
+ const [activeView = "never", setActiveView] = useControllableState4({
739
822
  prop: propsActiveView,
740
823
  defaultProp: defaultActiveView,
741
824
  onChange: onActiveViewChange
742
825
  });
743
- return /* @__PURE__ */ React19.createElement(ViewportProvider, {
826
+ return /* @__PURE__ */ React21.createElement(ViewportProvider, {
744
827
  focusManaged,
745
828
  activeView,
746
829
  setActiveView,
747
830
  scope: __viewportScope
748
- }, /* @__PURE__ */ React19.createElement("div", {
831
+ }, /* @__PURE__ */ React21.createElement("div", {
749
832
  role: "region",
750
833
  "aria-live": "polite",
751
834
  ...props,
@@ -757,7 +840,7 @@ var ViewportViews = ({ classNames, children, ...props }) => {
757
840
  const size = {
758
841
  inlineSize: `${Math.ceil(children.length) * 100}%`
759
842
  };
760
- return /* @__PURE__ */ React19.createElement("div", {
843
+ return /* @__PURE__ */ React21.createElement("div", {
761
844
  role: "none",
762
845
  style: size,
763
846
  ...props,
@@ -779,7 +862,7 @@ var ViewportView = /* @__PURE__ */ forwardRef6(({ __viewportScope, classNames, c
779
862
  ref.current,
780
863
  isActive
781
864
  ]);
782
- return /* @__PURE__ */ React19.createElement("section", {
865
+ return /* @__PURE__ */ React21.createElement("section", {
783
866
  ...props,
784
867
  ...!isActive && {
785
868
  "aria-hidden": true
@@ -796,41 +879,41 @@ var Viewport = {
796
879
  };
797
880
 
798
881
  // packages/sdk/shell/src/components/SpaceListItem.tsx
799
- import React20, { forwardRef as forwardRef7 } from "react";
800
- import { Avatar as Avatar3, useId as useId3, useJdenticonHref as useJdenticonHref2 } from "@dxos/react-ui";
882
+ import React22, { forwardRef as forwardRef7 } from "react";
883
+ import { Avatar as Avatar3, useId as useId3 } from "@dxos/react-ui";
801
884
  import { mx as mx17 } from "@dxos/react-ui-theme";
802
- import { humanize } from "@dxos/util";
885
+ import { humanize, keyToEmoji } from "@dxos/util";
803
886
  var SpaceListItem = /* @__PURE__ */ forwardRef7(({ space, onClick }, ref) => {
804
- const fallbackValue = space.key.toHex();
887
+ const fallbackValue = keyToEmoji(space.key);
805
888
  const labelId = useId3("identityListItem__label");
806
- const jdenticon = useJdenticonHref2(fallbackValue ?? "", 12);
807
889
  const displayName = space.properties.name ?? humanize(space.key.toHex());
808
- return /* @__PURE__ */ React20.createElement("li", {
890
+ return /* @__PURE__ */ React22.createElement("li", {
809
891
  className: mx17("flex gap-2 items-center mbe-2", onClick && "cursor-pointer"),
810
892
  onClick: () => onClick?.(),
811
893
  ref,
812
894
  "data-testid": "space-list-item"
813
- }, /* @__PURE__ */ React20.createElement(Avatar3.Root, {
895
+ }, /* @__PURE__ */ React22.createElement(Avatar3.Root, {
814
896
  labelId
815
- }, /* @__PURE__ */ React20.createElement(Avatar3.Frame, null, /* @__PURE__ */ React20.createElement(Avatar3.Fallback, {
816
- href: jdenticon
817
- })), /* @__PURE__ */ React20.createElement(Avatar3.Label, {
897
+ }, /* @__PURE__ */ React22.createElement(Avatar3.Frame, null, /* @__PURE__ */ React22.createElement(Avatar3.Fallback, {
898
+ text: fallbackValue
899
+ })), /* @__PURE__ */ React22.createElement(Avatar3.Label, {
818
900
  classNames: "text-sm truncate"
819
901
  }, displayName)));
820
902
  });
821
903
 
822
904
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
823
- import React40 from "react";
905
+ import React42 from "react";
824
906
  import { Dialog, useId as useId9 } from "@dxos/react-ui";
825
907
 
826
908
  // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
827
- import React27, { useEffect as useEffect3, useMemo as useMemo3 } from "react";
909
+ import React29, { useEffect as useEffect3, useMemo as useMemo3 } from "react";
828
910
  import { generateName as generateName3 } from "@dxos/display-name";
829
911
  import { log as log3 } from "@dxos/log";
830
912
  import { useClient as useClient3 } from "@dxos/react-client";
831
913
  import { useIdentity, useDevices, useHaloInvitations as useHaloInvitations2 } from "@dxos/react-client/halo";
832
914
  import { useInvitationStatus as useInvitationStatus2 } from "@dxos/react-client/invitations";
833
- import { Avatar as Avatar4, DensityProvider as DensityProvider2, useId as useId5, useJdenticonHref as useJdenticonHref3, useTranslation as useTranslation13 } from "@dxos/react-ui";
915
+ import { Avatar as Avatar4, DensityProvider as DensityProvider2, useId as useId5, useTranslation as useTranslation15 } from "@dxos/react-ui";
916
+ import { keyToFallback as keyToFallback2 } from "@dxos/util";
834
917
 
835
918
  // packages/sdk/shell/src/panels/IdentityPanel/identityMachine.ts
836
919
  import { useMachine } from "@xstate/react";
@@ -959,30 +1042,30 @@ var useIdentityMachine = (client, options) => {
959
1042
  };
960
1043
 
961
1044
  // packages/sdk/shell/src/panels/IdentityPanel/steps/AgentForm.tsx
962
- import React21 from "react";
963
- import { useTranslation as useTranslation7 } from "@dxos/react-ui";
1045
+ import React23 from "react";
1046
+ import { useTranslation as useTranslation9 } from "@dxos/react-ui";
964
1047
  var AgentForm = (props) => {
965
1048
  const { active, onAgentCreate, onAgentDestroy, send, validationMessage, agentStatus, agentActive, agentProviderDisabled } = props;
966
1049
  const disabled = !active;
967
- const { t } = useTranslation7("os");
968
- return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", {
1050
+ const { t } = useTranslation9("os");
1051
+ return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("div", {
969
1052
  role: "none",
970
1053
  className: "grow flex flex-col justify-center"
971
- }, /* @__PURE__ */ React21.createElement(Input, {
1054
+ }, /* @__PURE__ */ React23.createElement(Input, {
972
1055
  validationMessage,
973
- label: /* @__PURE__ */ React21.createElement(StepHeading, null, "Agent Status"),
1056
+ label: /* @__PURE__ */ React23.createElement(StepHeading, null, "Agent Status"),
974
1057
  disabled,
975
1058
  "data-testid": "agent-status",
976
1059
  value: agentStatus
977
- })), /* @__PURE__ */ React21.createElement(Actions, null, /* @__PURE__ */ React21.createElement(Action, {
1060
+ })), /* @__PURE__ */ React23.createElement(Actions, null, /* @__PURE__ */ React23.createElement(Action, {
978
1061
  disabled: agentActive || agentProviderDisabled,
979
1062
  onClick: () => onAgentCreate?.(),
980
1063
  "data-testid": "create-agent"
981
- }, "Create Agent"), /* @__PURE__ */ React21.createElement(Action, {
1064
+ }, "Create Agent"), /* @__PURE__ */ React23.createElement(Action, {
982
1065
  disabled: !agentActive || agentProviderDisabled,
983
1066
  onClick: () => onAgentDestroy?.(),
984
1067
  "data-testid": "destroy-agent"
985
- }, "Destroy Agent"), /* @__PURE__ */ React21.createElement(Action, {
1068
+ }, "Destroy Agent"), /* @__PURE__ */ React23.createElement(Action, {
986
1069
  disabled,
987
1070
  onClick: () => send?.({
988
1071
  type: "unchooseAction"
@@ -992,17 +1075,17 @@ var AgentForm = (props) => {
992
1075
  };
993
1076
 
994
1077
  // packages/sdk/shell/src/panels/IdentityPanel/steps/DeviceManager.tsx
995
- import React22 from "react";
996
- import { useTranslation as useTranslation8 } from "@dxos/react-ui";
1078
+ import React24 from "react";
1079
+ import { useTranslation as useTranslation10 } from "@dxos/react-ui";
997
1080
  var DeviceManager = ({ devices, active, send }) => {
998
- const { t } = useTranslation8("os");
1081
+ const { t } = useTranslation10("os");
999
1082
  const disabled = !active;
1000
- return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", {
1083
+ return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", {
1001
1084
  role: "none",
1002
1085
  className: "grow"
1003
- }, /* @__PURE__ */ React22.createElement(DeviceList, {
1086
+ }, /* @__PURE__ */ React24.createElement(DeviceList, {
1004
1087
  devices
1005
- })), /* @__PURE__ */ React22.createElement(Actions, null, /* @__PURE__ */ React22.createElement(Action, {
1088
+ })), /* @__PURE__ */ React24.createElement(Actions, null, /* @__PURE__ */ React24.createElement(Action, {
1006
1089
  variant: "ghost",
1007
1090
  disabled,
1008
1091
  onClick: () => send?.({
@@ -1014,12 +1097,12 @@ var DeviceManager = ({ devices, active, send }) => {
1014
1097
 
1015
1098
  // packages/sdk/shell/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx
1016
1099
  import { CaretRight, Devices, Plus, Power, UserGear, HardDrive } from "@phosphor-icons/react";
1017
- import React23, { useCallback as useCallback4 } from "react";
1100
+ import React25, { useCallback as useCallback4 } from "react";
1018
1101
  import { useAgentHostingProviderClient, useClient as useClient2 } from "@dxos/react-client";
1019
1102
  import { useHaloInvitations } from "@dxos/react-client/halo";
1020
- import { Invitation as Invitation3, InvitationEncoder } from "@dxos/react-client/invitations";
1021
- import { DensityProvider, useTranslation as useTranslation9 } from "@dxos/react-ui";
1022
- import { getSize as getSize6 } from "@dxos/react-ui-theme";
1103
+ import { Invitation as Invitation2, InvitationEncoder } from "@dxos/react-client/invitations";
1104
+ import { DensityProvider, useTranslation as useTranslation11 } from "@dxos/react-ui";
1105
+ import { getSize as getSize8 } from "@dxos/react-ui-theme";
1023
1106
  var IdentityActionChooser = (props) => {
1024
1107
  const { send } = props;
1025
1108
  const client = useClient2();
@@ -1027,7 +1110,7 @@ var IdentityActionChooser = (props) => {
1027
1110
  const agentHostingProviderClient = useAgentHostingProviderClient(client.config);
1028
1111
  const onInvitationEvent = useCallback4((invitation) => {
1029
1112
  const invitationCode = InvitationEncoder.encode(invitation);
1030
- if (invitation.state === Invitation3.State.CONNECTING) {
1113
+ if (invitation.state === Invitation2.State.CONNECTING) {
1031
1114
  console.log(JSON.stringify({
1032
1115
  invitationCode,
1033
1116
  authCode: invitation.authCode
@@ -1038,8 +1121,8 @@ var IdentityActionChooser = (props) => {
1038
1121
  const testing = e.altKey && e.shiftKey;
1039
1122
  invitations.forEach((invitation2) => invitation2.cancel());
1040
1123
  const invitation = client.halo.share(testing ? {
1041
- type: Invitation3.Type.MULTIUSE,
1042
- authMethod: Invitation3.AuthMethod.NONE
1124
+ type: Invitation2.Type.MULTIUSE,
1125
+ authMethod: Invitation2.AuthMethod.NONE
1043
1126
  } : void 0);
1044
1127
  if (true) {
1045
1128
  invitation.subscribe(onInvitationEvent);
@@ -1049,138 +1132,157 @@ var IdentityActionChooser = (props) => {
1049
1132
  invitation
1050
1133
  });
1051
1134
  };
1052
- return /* @__PURE__ */ React23.createElement(IdentityActionChooserImpl, {
1135
+ return /* @__PURE__ */ React25.createElement(IdentityActionChooserImpl, {
1053
1136
  ...props,
1054
1137
  onCreateInvitationClick: (e) => createInvitation(e),
1055
1138
  agentHostingEnabled: !!agentHostingProviderClient
1056
1139
  });
1057
1140
  };
1058
1141
  var IdentityActionChooserImpl = ({ onCreateInvitationClick, active, send, onDone, doneActionParent, agentHostingEnabled }) => {
1059
- const { t } = useTranslation9("os");
1060
- return /* @__PURE__ */ React23.createElement("div", {
1142
+ const { t } = useTranslation11("os");
1143
+ return /* @__PURE__ */ React25.createElement("div", {
1061
1144
  role: "none",
1062
1145
  className: "grow flex flex-col gap-1"
1063
- }, /* @__PURE__ */ React23.createElement(DensityProvider, {
1146
+ }, /* @__PURE__ */ React25.createElement(DensityProvider, {
1064
1147
  density: "coarse"
1065
- }, /* @__PURE__ */ React23.createElement("div", {
1148
+ }, /* @__PURE__ */ React25.createElement("div", {
1066
1149
  className: "grow justify-center flex flex-col gap-1"
1067
- }, agentHostingEnabled && /* @__PURE__ */ React23.createElement(Action, {
1150
+ }, agentHostingEnabled && /* @__PURE__ */ React25.createElement(Action, {
1068
1151
  "data-testid": "manage-agent",
1069
1152
  onClick: () => send?.({
1070
1153
  type: "chooseAgent"
1071
1154
  }),
1072
1155
  classNames: "plb-4"
1073
- }, /* @__PURE__ */ React23.createElement(HardDrive, {
1074
- className: getSize6(6)
1075
- }), /* @__PURE__ */ React23.createElement("span", {
1156
+ }, /* @__PURE__ */ React25.createElement(HardDrive, {
1157
+ className: getSize8(6)
1158
+ }), /* @__PURE__ */ React25.createElement("span", {
1076
1159
  className: "grow mli-3"
1077
- }, "Manage Agent"), /* @__PURE__ */ React23.createElement(CaretRight, {
1160
+ }, "Manage Agent"), /* @__PURE__ */ React25.createElement(CaretRight, {
1078
1161
  weight: "bold",
1079
- className: getSize6(4)
1080
- })), /* @__PURE__ */ React23.createElement(Action, {
1162
+ className: getSize8(4)
1163
+ })), /* @__PURE__ */ React25.createElement(Action, {
1081
1164
  disabled: !active,
1082
1165
  "data-testid": "devices-panel.create-invitation",
1083
1166
  onClick: onCreateInvitationClick,
1084
1167
  classNames: "plb-4"
1085
- }, /* @__PURE__ */ React23.createElement(Plus, {
1086
- className: getSize6(6)
1087
- }), /* @__PURE__ */ React23.createElement("span", {
1168
+ }, /* @__PURE__ */ React25.createElement(Plus, {
1169
+ className: getSize8(6)
1170
+ }), /* @__PURE__ */ React25.createElement("span", {
1088
1171
  className: "grow mli-3"
1089
- }, t("choose add device label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1172
+ }, t("choose add device label")), /* @__PURE__ */ React25.createElement(CaretRight, {
1090
1173
  weight: "bold",
1091
- className: getSize6(4)
1092
- })), /* @__PURE__ */ React23.createElement(Action, {
1174
+ className: getSize8(4)
1175
+ })), /* @__PURE__ */ React25.createElement(Action, {
1093
1176
  "data-testid": "manage-devices",
1094
1177
  onClick: () => send?.({
1095
1178
  type: "chooseDevices"
1096
1179
  }),
1097
1180
  classNames: "plb-4"
1098
- }, /* @__PURE__ */ React23.createElement(Devices, {
1099
- className: getSize6(6)
1100
- }), /* @__PURE__ */ React23.createElement("span", {
1181
+ }, /* @__PURE__ */ React25.createElement(Devices, {
1182
+ className: getSize8(6)
1183
+ }), /* @__PURE__ */ React25.createElement("span", {
1101
1184
  className: "grow mli-3"
1102
- }, t("choose devices label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1185
+ }, t("choose devices label")), /* @__PURE__ */ React25.createElement(CaretRight, {
1103
1186
  weight: "bold",
1104
- className: getSize6(4)
1105
- })), /* @__PURE__ */ React23.createElement(Action, {
1187
+ className: getSize8(4)
1188
+ })), /* @__PURE__ */ React25.createElement(Action, {
1106
1189
  "data-testid": "manage-profile",
1107
1190
  onClick: () => send?.({
1108
1191
  type: "chooseProfile"
1109
1192
  }),
1110
1193
  classNames: "plb-4"
1111
- }, /* @__PURE__ */ React23.createElement(UserGear, {
1112
- className: getSize6(6)
1113
- }), /* @__PURE__ */ React23.createElement("span", {
1194
+ }, /* @__PURE__ */ React25.createElement(UserGear, {
1195
+ className: getSize8(6)
1196
+ }), /* @__PURE__ */ React25.createElement("span", {
1114
1197
  className: "grow mli-3"
1115
- }, t("choose profile label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1198
+ }, t("choose profile label")), /* @__PURE__ */ React25.createElement(CaretRight, {
1116
1199
  weight: "bold",
1117
- className: getSize6(4)
1118
- })), /* @__PURE__ */ React23.createElement(Action, {
1200
+ className: getSize8(4)
1201
+ })), /* @__PURE__ */ React25.createElement(Action, {
1119
1202
  "data-testid": "devices-panel.sign-out",
1120
1203
  onClick: () => send?.({
1121
1204
  type: "chooseSignOut"
1122
1205
  }),
1123
1206
  classNames: "plb-4"
1124
- }, /* @__PURE__ */ React23.createElement(Power, {
1125
- className: getSize6(6)
1126
- }), /* @__PURE__ */ React23.createElement("span", {
1207
+ }, /* @__PURE__ */ React25.createElement(Power, {
1208
+ className: getSize8(6)
1209
+ }), /* @__PURE__ */ React25.createElement("span", {
1127
1210
  className: "grow mli-3"
1128
- }, t("choose sign out label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1211
+ }, t("choose sign out label")), /* @__PURE__ */ React25.createElement(CaretRight, {
1129
1212
  weight: "bold",
1130
- className: getSize6(4)
1213
+ className: getSize8(4)
1131
1214
  })))));
1132
1215
  };
1133
1216
 
1134
1217
  // packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx
1135
- import React24, { useState as useState3 } from "react";
1218
+ import React26, { useState as useState4 } from "react";
1136
1219
  import { log as log2 } from "@dxos/log";
1137
- import { useTranslation as useTranslation10 } from "@dxos/react-ui";
1220
+ import { useTranslation as useTranslation12 } from "@dxos/react-ui";
1221
+ import { hexToEmoji as hexToEmoji2, hexToHue } from "@dxos/util";
1138
1222
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx";
1139
1223
  var ProfileForm = (props) => {
1140
1224
  const { onUpdateProfile } = props;
1141
- const { t } = useTranslation10("os");
1142
- const [validationMessage, setValidationMessage] = useState3("");
1225
+ const { t } = useTranslation12("os");
1226
+ const [validationMessage, setValidationMessage] = useState4("");
1143
1227
  const handleUpdateProfile = async (profile) => {
1144
1228
  await onUpdateProfile?.(profile).catch((error) => {
1145
1229
  log2.catch(error, void 0, {
1146
1230
  F: __dxlog_file2,
1147
- L: 32,
1231
+ L: 33,
1148
1232
  S: void 0,
1149
1233
  C: (f, a) => f(...a)
1150
1234
  });
1151
1235
  setValidationMessage(t("failed to update profile message"));
1152
1236
  });
1153
1237
  };
1154
- return /* @__PURE__ */ React24.createElement(ProfileFormImpl, {
1238
+ return /* @__PURE__ */ React26.createElement(ProfileFormImpl, {
1155
1239
  ...props,
1156
1240
  onUpdateProfile: handleUpdateProfile,
1157
1241
  validationMessage
1158
1242
  });
1159
1243
  };
1244
+ var getHueValue = (identity) => identity?.profile?.data?.hue || hexToHue(identity?.identityKey.toHex() ?? "0");
1245
+ var getEmojiValue = (identity) => identity?.profile?.data?.emoji || hexToEmoji2(identity?.identityKey.toHex() ?? "0");
1160
1246
  var ProfileFormImpl = (props) => {
1161
1247
  const { active, identity, send, onUpdateProfile, validationMessage } = props;
1162
1248
  const profile = identity?.profile;
1163
1249
  const disabled = !active;
1164
- const { t } = useTranslation10("os");
1165
- const [inputValue, setInputValue] = useState3(profile?.displayName ?? "");
1250
+ const { t } = useTranslation12("os");
1251
+ const [displayName, setDisplayName] = useState4(profile?.displayName ?? "");
1252
+ const [hue, setHue] = useState4(getHueValue(identity));
1253
+ const [emoji, setEmoji] = useState4(getEmojiValue(identity));
1166
1254
  const { textValue, setTextValue } = useClipboardContext();
1167
1255
  const identityHex = identity?.identityKey.toHex();
1168
1256
  const copied = textValue === identityHex;
1169
- return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", {
1257
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("div", {
1170
1258
  role: "none",
1171
1259
  className: "grow flex flex-col justify-center"
1172
- }, /* @__PURE__ */ React24.createElement(Input, {
1260
+ }, /* @__PURE__ */ React26.createElement(Input, {
1173
1261
  validationMessage,
1174
- label: /* @__PURE__ */ React24.createElement(StepHeading, null, t("display name input label")),
1262
+ label: /* @__PURE__ */ React26.createElement(StepHeading, {
1263
+ className: "m-0"
1264
+ }, t("display name input label")),
1175
1265
  disabled,
1176
1266
  "data-testid": "display-name-input",
1177
1267
  placeholder: t("display name input placeholder"),
1178
- value: inputValue,
1179
- onChange: ({ target: { value } }) => setInputValue(value),
1180
- onKeyDown: ({ key }) => key === "Enter" && onUpdateProfile?.({
1181
- displayName: inputValue
1182
- })
1183
- })), /* @__PURE__ */ React24.createElement(Actions, null, /* @__PURE__ */ React24.createElement(Action, {
1268
+ value: displayName,
1269
+ onChange: ({ target: { value } }) => setDisplayName(value)
1270
+ }), /* @__PURE__ */ React26.createElement(StepHeading, {
1271
+ className: "mbe-2"
1272
+ }, t("emoji and color label")), /* @__PURE__ */ React26.createElement("div", {
1273
+ role: "none",
1274
+ className: "grid grid-cols-[1fr_min-content] gap-y-2"
1275
+ }, /* @__PURE__ */ React26.createElement(EmojiPicker, {
1276
+ emoji,
1277
+ onChangeEmoji: setEmoji,
1278
+ disabled,
1279
+ onClickClear: () => setEmoji(getEmojiValue(identity))
1280
+ }), /* @__PURE__ */ React26.createElement(HuePicker, {
1281
+ hue,
1282
+ onChangeHue: setHue,
1283
+ disabled,
1284
+ onClickClear: () => setHue(getHueValue(identity))
1285
+ }))), /* @__PURE__ */ React26.createElement(Actions, null, /* @__PURE__ */ React26.createElement(Action, {
1184
1286
  variant: "ghost",
1185
1287
  disabled,
1186
1288
  onClick: () => {
@@ -1189,18 +1291,22 @@ var ProfileFormImpl = (props) => {
1189
1291
  }
1190
1292
  },
1191
1293
  "data-testid": "update-profile-form-copy-key"
1192
- }, t(copied ? "copy success label" : "copy self public key label")), /* @__PURE__ */ React24.createElement(Action, {
1294
+ }, t(copied ? "copy success label" : "copy self public key label")), /* @__PURE__ */ React26.createElement(Action, {
1193
1295
  variant: "ghost",
1194
1296
  disabled,
1195
1297
  onClick: () => send?.({
1196
1298
  type: "unchooseAction"
1197
1299
  }),
1198
1300
  "data-testid": "update-profile-form-back"
1199
- }, t("back label")), /* @__PURE__ */ React24.createElement(Action, {
1301
+ }, t("back label")), /* @__PURE__ */ React26.createElement(Action, {
1200
1302
  variant: "primary",
1201
1303
  disabled,
1202
1304
  onClick: () => onUpdateProfile?.({
1203
- displayName: inputValue
1305
+ displayName,
1306
+ data: {
1307
+ emoji,
1308
+ hue
1309
+ }
1204
1310
  }),
1205
1311
  "data-testid": "update-profile-form-continue"
1206
1312
  }, t("done label"))));
@@ -1208,17 +1314,17 @@ var ProfileFormImpl = (props) => {
1208
1314
 
1209
1315
  // packages/sdk/shell/src/panels/IdentityPanel/steps/SignOutChooser.tsx
1210
1316
  import { Warning } from "@phosphor-icons/react";
1211
- import React25 from "react";
1212
- import { Message, useTranslation as useTranslation11 } from "@dxos/react-ui";
1213
- import { getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1317
+ import React27 from "react";
1318
+ import { Message, useTranslation as useTranslation13 } from "@dxos/react-ui";
1319
+ import { getSize as getSize9, mx as mx18 } from "@dxos/react-ui-theme";
1214
1320
  var SignOutChooser = (props) => {
1215
- const { t } = useTranslation11("os");
1321
+ const { t } = useTranslation13("os");
1216
1322
  const onResetDevice = () => {
1217
1323
  if (window.confirm(t("reset device confirm message"))) {
1218
1324
  void props.onResetDevice?.();
1219
1325
  }
1220
1326
  };
1221
- return /* @__PURE__ */ React25.createElement(SignOutChooserImpl, {
1327
+ return /* @__PURE__ */ React27.createElement(SignOutChooserImpl, {
1222
1328
  disabled: !props.active,
1223
1329
  onBack: () => props.send?.({
1224
1330
  type: "unchooseAction"
@@ -1228,24 +1334,24 @@ var SignOutChooser = (props) => {
1228
1334
  });
1229
1335
  };
1230
1336
  var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }) => {
1231
- const { t } = useTranslation11("os");
1232
- return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement("div", {
1337
+ const { t } = useTranslation13("os");
1338
+ return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement("div", {
1233
1339
  role: "none",
1234
1340
  className: "grow flex flex-col justify-center"
1235
- }, /* @__PURE__ */ React25.createElement(Message.Root, {
1341
+ }, /* @__PURE__ */ React27.createElement(Message.Root, {
1236
1342
  valence: "error"
1237
- }, /* @__PURE__ */ React25.createElement(Message.Title, null, /* @__PURE__ */ React25.createElement(Warning, {
1238
- className: mx18(getSize7(6), "inline mie-2")
1239
- }), t("sign out chooser title")), /* @__PURE__ */ React25.createElement(Message.Body, null, t("sign out chooser message")))), /* @__PURE__ */ React25.createElement(Actions, null, /* @__PURE__ */ React25.createElement(Action, {
1343
+ }, /* @__PURE__ */ React27.createElement(Message.Title, null, /* @__PURE__ */ React27.createElement(Warning, {
1344
+ className: mx18(getSize9(6), "inline mie-2")
1345
+ }), t("sign out chooser title")), /* @__PURE__ */ React27.createElement(Message.Body, null, t("sign out chooser message")))), /* @__PURE__ */ React27.createElement(Actions, null, /* @__PURE__ */ React27.createElement(Action, {
1240
1346
  disabled,
1241
1347
  onClick: onBack
1242
- }, t("back label")), /* @__PURE__ */ React25.createElement(Action, {
1348
+ }, t("back label")), /* @__PURE__ */ React27.createElement(Action, {
1243
1349
  variant: "primary",
1244
1350
  "data-testid": "sign-out.join-new-identity",
1245
1351
  classNames: "!bg-error-500 hover:!bg-error-550",
1246
1352
  disabled,
1247
1353
  onClick: onJoinNewIdentity
1248
- }, t("join new identity label")), /* @__PURE__ */ React25.createElement(Action, {
1354
+ }, t("join new identity label")), /* @__PURE__ */ React27.createElement(Action, {
1249
1355
  variant: "primary",
1250
1356
  "data-testid": "sign-out.reset-device",
1251
1357
  classNames: "!bg-error-500 hover:!bg-error-550",
@@ -1255,15 +1361,15 @@ var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }
1255
1361
  };
1256
1362
 
1257
1363
  // packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts
1258
- import { useCallback as useCallback5, useEffect as useEffect2, useState as useState4 } from "react";
1364
+ import { useCallback as useCallback5, useEffect as useEffect2, useState as useState5 } from "react";
1259
1365
  import { invariant } from "@dxos/invariant";
1260
1366
  import { useAgentHostingProviderClient as useAgentHostingProviderClient2 } from "@dxos/react-client";
1261
- import { Invitation as Invitation4, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1367
+ import { Invitation as Invitation3, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1262
1368
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts";
1263
1369
  var useAgentHandlers = ({ client, invitations, identity }) => {
1264
- const [validationMessage, setValidationMessage] = useState4("");
1265
- const [agentStatus, setAgentStatus] = useState4("");
1266
- const [agentActive, setAgentActive] = useState4(false);
1370
+ const [validationMessage, setValidationMessage] = useState5("");
1371
+ const [agentStatus, setAgentStatus] = useState5("");
1372
+ const [agentActive, setAgentActive] = useState5(false);
1267
1373
  const agentHostingProviderClient = useAgentHostingProviderClient2(client.config);
1268
1374
  useEffect2(() => {
1269
1375
  const fetchAgentStatus = async () => {
@@ -1284,7 +1390,7 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1284
1390
  }, []);
1285
1391
  const handleAgentCreate = useCallback5(async (invitation) => {
1286
1392
  const invitationCode = InvitationEncoder2.encode(invitation);
1287
- if (invitation.state === Invitation4.State.CONNECTING) {
1393
+ if (invitation.state === Invitation3.State.CONNECTING) {
1288
1394
  console.log(JSON.stringify({
1289
1395
  invitationCode,
1290
1396
  authCode: invitation.authCode
@@ -1313,8 +1419,8 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1313
1419
  const onAgentCreate = async () => {
1314
1420
  invitations.forEach((invitation2) => invitation2.cancel());
1315
1421
  const invitation = client.halo.share({
1316
- type: Invitation4.Type.MULTIUSE,
1317
- authMethod: Invitation4.AuthMethod.NONE
1422
+ type: Invitation3.Type.MULTIUSE,
1423
+ authMethod: Invitation3.AuthMethod.NONE
1318
1424
  });
1319
1425
  invitation.subscribe(handleAgentCreate);
1320
1426
  };
@@ -1348,24 +1454,68 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1348
1454
  };
1349
1455
 
1350
1456
  // packages/sdk/shell/src/steps/InvitationManager.tsx
1351
- import { Check as Check3, X as X3 } from "@phosphor-icons/react";
1352
- import React26, { useMemo as useMemo2 } from "react";
1457
+ import { Check as Check4, X as X3 } from "@phosphor-icons/react";
1458
+ import React28, { useMemo as useMemo2 } from "react";
1353
1459
  import { QR } from "react-qr-rounded";
1354
1460
  import { Invitation as Invitation5 } from "@dxos/react-client/invitations";
1355
- import { useId as useId4, useTranslation as useTranslation12 } from "@dxos/react-ui";
1356
- import { descriptionText as descriptionText7, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1461
+ import { useId as useId4, useTranslation as useTranslation14 } from "@dxos/react-ui";
1462
+ import { descriptionText as descriptionText7, getSize as getSize10, mx as mx19 } from "@dxos/react-ui-theme";
1463
+ import { hexToEmoji as hexToEmoji3 } from "@dxos/util";
1464
+
1465
+ // packages/sdk/shell/src/util/invitationStatusValue.ts
1466
+ import { Invitation as Invitation4 } from "@dxos/react-client/invitations";
1467
+ var invitationStatusValue = /* @__PURE__ */ new Map([
1468
+ [
1469
+ Invitation4.State.ERROR,
1470
+ -3
1471
+ ],
1472
+ [
1473
+ Invitation4.State.TIMEOUT,
1474
+ -2
1475
+ ],
1476
+ [
1477
+ Invitation4.State.CANCELLED,
1478
+ -1
1479
+ ],
1480
+ [
1481
+ Invitation4.State.INIT,
1482
+ 0
1483
+ ],
1484
+ [
1485
+ Invitation4.State.CONNECTING,
1486
+ 1
1487
+ ],
1488
+ [
1489
+ Invitation4.State.CONNECTED,
1490
+ 2
1491
+ ],
1492
+ [
1493
+ Invitation4.State.READY_FOR_AUTHENTICATION,
1494
+ 3
1495
+ ],
1496
+ [
1497
+ Invitation4.State.AUTHENTICATING,
1498
+ 4
1499
+ ],
1500
+ [
1501
+ Invitation4.State.SUCCESS,
1502
+ 5
1503
+ ]
1504
+ ]);
1505
+
1506
+ // packages/sdk/shell/src/steps/InvitationManager.tsx
1357
1507
  var InvitationManagerView = ({ children, ...props }) => {
1358
- return /* @__PURE__ */ React26.createElement(Viewport.View, {
1508
+ return /* @__PURE__ */ React28.createElement(Viewport.View, {
1359
1509
  ...props,
1360
1510
  classNames: "grow flex flex-col justify-around items-center"
1361
1511
  }, children);
1362
1512
  };
1363
- var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id }) => {
1364
- const { t } = useTranslation12("os");
1513
+ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id = "0" }) => {
1514
+ const { t } = useTranslation14("os");
1365
1515
  const qrLabel = useId4("invitation-manager__qr-code");
1366
1516
  const statusValue = type === Invitation5.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1367
1517
  const showAuthCode = statusValue === 3;
1368
- const emoji2 = toEmoji(id ?? "");
1518
+ const emoji = hexToEmoji3(id);
1369
1519
  const activeView = useMemo2(() => {
1370
1520
  switch (true) {
1371
1521
  case statusValue === 5:
@@ -1379,18 +1529,18 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1379
1529
  }, [
1380
1530
  statusValue
1381
1531
  ]);
1382
- return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(Viewport.Root, {
1532
+ return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(Viewport.Root, {
1383
1533
  activeView,
1384
1534
  classNames: "grow plb-1"
1385
- }, /* @__PURE__ */ React26.createElement(Viewport.Views, null, /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1535
+ }, /* @__PURE__ */ React28.createElement(Viewport.Views, null, /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1386
1536
  id: "showing qr",
1387
- emoji: emoji2
1388
- }, /* @__PURE__ */ React26.createElement("p", {
1537
+ emoji
1538
+ }, /* @__PURE__ */ React28.createElement("p", {
1389
1539
  className: "text-sm mlb-1 font-normal text-center"
1390
- }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React26.createElement("div", {
1540
+ }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React28.createElement("div", {
1391
1541
  role: "none",
1392
1542
  className: mx19(descriptionText7, "is-full max-is-[14rem] relative")
1393
- }, /* @__PURE__ */ React26.createElement(QR, {
1543
+ }, /* @__PURE__ */ React28.createElement(QR, {
1394
1544
  rounding: 100,
1395
1545
  backgroundColor: "transparent",
1396
1546
  color: "currentColor",
@@ -1398,31 +1548,31 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1398
1548
  "aria-labelledby": qrLabel,
1399
1549
  errorCorrectionLevel: "Q",
1400
1550
  cutout: true
1401
- }, invitationUrl ?? "never"), /* @__PURE__ */ React26.createElement(Centered, null, /* @__PURE__ */ React26.createElement(Emoji, {
1402
- text: emoji2
1403
- }))), /* @__PURE__ */ React26.createElement("span", {
1551
+ }, invitationUrl ?? "never"), /* @__PURE__ */ React28.createElement(Centered, null, /* @__PURE__ */ React28.createElement(Emoji, {
1552
+ text: emoji
1553
+ }))), /* @__PURE__ */ React28.createElement("span", {
1404
1554
  id: qrLabel,
1405
1555
  className: "sr-only"
1406
- }, t("qr label")), /* @__PURE__ */ React26.createElement(CopyButton, {
1556
+ }, t("qr label")), /* @__PURE__ */ React28.createElement(CopyButton, {
1407
1557
  variant: "ghost",
1408
1558
  value: invitationUrl ?? "never"
1409
- })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1559
+ })), /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1410
1560
  id: "showing auth code"
1411
- }, /* @__PURE__ */ React26.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React26.createElement(AuthCode, {
1561
+ }, /* @__PURE__ */ React28.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React28.createElement(AuthCode, {
1412
1562
  code: authCode,
1413
1563
  large: true,
1414
1564
  classNames: "text-black dark:text-white"
1415
- }), /* @__PURE__ */ React26.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React26.createElement(Emoji, {
1416
- text: emoji2
1417
- })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1565
+ }), /* @__PURE__ */ React28.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji && /* @__PURE__ */ React28.createElement(Emoji, {
1566
+ text: emoji
1567
+ })), /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1418
1568
  id: "showing final"
1419
- }, statusValue > 0 ? /* @__PURE__ */ React26.createElement(Check3, {
1420
- className: mx19("m-1.5", getSize8(6))
1421
- }) : /* @__PURE__ */ React26.createElement(X3, {
1422
- className: mx19("m-1.5", getSize8(6))
1423
- })))), /* @__PURE__ */ React26.createElement(Actions, {
1569
+ }, statusValue > 0 ? /* @__PURE__ */ React28.createElement(Check4, {
1570
+ className: mx19("m-1.5", getSize10(6))
1571
+ }) : /* @__PURE__ */ React28.createElement(X3, {
1572
+ className: mx19("m-1.5", getSize10(6))
1573
+ })))), /* @__PURE__ */ React28.createElement(Actions, {
1424
1574
  classNames: "mbs-4"
1425
- }, /* @__PURE__ */ React26.createElement(Action, {
1575
+ }, /* @__PURE__ */ React28.createElement(Action, {
1426
1576
  disabled: !active,
1427
1577
  onClick: () => send?.({
1428
1578
  type: "deselectInvitation"
@@ -1434,29 +1584,30 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1434
1584
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1435
1585
  var viewStyles = "pbs-1 pbe-3 pli-3";
1436
1586
  var IdentityHeading = ({ titleId, title, identity, onDone }) => {
1437
- const fallbackHref = useJdenticonHref3(identity.identityKey.toHex(), 12);
1438
- return /* @__PURE__ */ React27.createElement(Heading, {
1587
+ const fallbackValue = keyToFallback2(identity.identityKey);
1588
+ return /* @__PURE__ */ React29.createElement(Heading, {
1439
1589
  titleId,
1440
1590
  title,
1441
- corner: /* @__PURE__ */ React27.createElement(CloseButton, {
1591
+ corner: /* @__PURE__ */ React29.createElement(CloseButton, {
1442
1592
  onDone
1443
1593
  })
1444
- }, /* @__PURE__ */ React27.createElement(Avatar4.Root, {
1594
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Root, {
1445
1595
  size: 12,
1446
1596
  variant: "circle",
1447
- status: "active"
1448
- }, /* @__PURE__ */ React27.createElement(Avatar4.Frame, {
1597
+ status: "active",
1598
+ hue: identity.profile?.data?.hue || fallbackValue.hue
1599
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Frame, {
1449
1600
  classNames: "block mbs-4 mbe-2 mli-auto chromatic-ignore"
1450
- }, /* @__PURE__ */ React27.createElement(Avatar4.Fallback, {
1451
- href: fallbackHref
1452
- })), /* @__PURE__ */ React27.createElement(Avatar4.Label, {
1601
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Fallback, {
1602
+ text: identity.profile?.data?.emoji || fallbackValue.emoji
1603
+ })), /* @__PURE__ */ React29.createElement(Avatar4.Label, {
1453
1604
  classNames: "block text-center font-light text-xl",
1454
1605
  "data-testid": "identityHeading.displayName"
1455
1606
  }, identity.profile?.displayName ?? generateName3(identity.identityKey.toHex()))));
1456
1607
  };
1457
1608
  var IdentityPanelImpl = (props) => {
1458
1609
  const { identity, titleId, activeView, onUpdateProfile, onResetDevice, onJoinNewIdentity, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1459
- const { t } = useTranslation13("os");
1610
+ const { t } = useTranslation15("os");
1460
1611
  const title = useMemo3(() => {
1461
1612
  switch (activeView) {
1462
1613
  case "agent manager":
@@ -1470,54 +1621,54 @@ var IdentityPanelImpl = (props) => {
1470
1621
  activeView,
1471
1622
  t
1472
1623
  ]);
1473
- return /* @__PURE__ */ React27.createElement(DensityProvider2, {
1624
+ return /* @__PURE__ */ React29.createElement(DensityProvider2, {
1474
1625
  density: "fine"
1475
- }, /* @__PURE__ */ React27.createElement(IdentityHeading, {
1626
+ }, /* @__PURE__ */ React29.createElement(IdentityHeading, {
1476
1627
  identity,
1477
1628
  titleId,
1478
1629
  title,
1479
1630
  onDone
1480
- }), /* @__PURE__ */ React27.createElement(Viewport.Root, {
1631
+ }), /* @__PURE__ */ React29.createElement(Viewport.Root, {
1481
1632
  activeView
1482
- }, /* @__PURE__ */ React27.createElement(Viewport.Views, null, /* @__PURE__ */ React27.createElement(Viewport.View, {
1633
+ }, /* @__PURE__ */ React29.createElement(Viewport.Views, null, /* @__PURE__ */ React29.createElement(Viewport.View, {
1483
1634
  id: "identity action chooser",
1484
1635
  classNames: viewStyles
1485
- }, /* @__PURE__ */ React27.createElement(IdentityActionChooserComponent, {
1636
+ }, /* @__PURE__ */ React29.createElement(IdentityActionChooserComponent, {
1486
1637
  active: activeView === "identity action chooser",
1487
1638
  ...rest
1488
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1639
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1489
1640
  id: "device invitation manager",
1490
1641
  classNames: viewStyles
1491
- }, /* @__PURE__ */ React27.createElement(InvitationManagerComponent, {
1642
+ }, /* @__PURE__ */ React29.createElement(InvitationManagerComponent, {
1492
1643
  active: activeView === "device invitation manager",
1493
1644
  ...rest,
1494
1645
  invitationUrl: rest.createInvitationUrl(rest.invitationCode)
1495
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1646
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1496
1647
  id: "device manager",
1497
1648
  classNames: viewStyles
1498
- }, /* @__PURE__ */ React27.createElement(DeviceManager, {
1649
+ }, /* @__PURE__ */ React29.createElement(DeviceManager, {
1499
1650
  active: activeView === "device manager",
1500
1651
  ...rest
1501
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1652
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1502
1653
  classNames: viewStyles,
1503
1654
  id: "update profile form"
1504
- }, /* @__PURE__ */ React27.createElement(ProfileForm, {
1655
+ }, /* @__PURE__ */ React29.createElement(ProfileForm, {
1505
1656
  send: rest.send,
1506
1657
  active: activeView === "update profile form",
1507
1658
  identity,
1508
1659
  onUpdateProfile
1509
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1660
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1510
1661
  classNames: viewStyles,
1511
1662
  id: "signing out"
1512
- }, /* @__PURE__ */ React27.createElement(SignOutChooser, {
1663
+ }, /* @__PURE__ */ React29.createElement(SignOutChooser, {
1513
1664
  send: rest.send,
1514
1665
  active: activeView === "signing out",
1515
1666
  onResetDevice,
1516
1667
  onJoinNewIdentity
1517
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1668
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1518
1669
  classNames: viewStyles,
1519
1670
  id: "agent manager"
1520
- }, /* @__PURE__ */ React27.createElement(AgentForm, {
1671
+ }, /* @__PURE__ */ React29.createElement(AgentForm, {
1521
1672
  send: rest.send,
1522
1673
  active: activeView === "agent manager",
1523
1674
  ...rest
@@ -1525,7 +1676,7 @@ var IdentityPanelImpl = (props) => {
1525
1676
  };
1526
1677
  var IdentityPanelWithInvitationImpl = ({ invitation, ...props }) => {
1527
1678
  const invitationStatus = useInvitationStatus2(invitation);
1528
- return /* @__PURE__ */ React27.createElement(IdentityPanelImpl, {
1679
+ return /* @__PURE__ */ React29.createElement(IdentityPanelImpl, {
1529
1680
  ...props,
1530
1681
  ...invitationStatus
1531
1682
  });
@@ -1550,7 +1701,7 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1550
1701
  const subscription = identityService.subscribe((state) => {
1551
1702
  log3("[state]", state, {
1552
1703
  F: __dxlog_file4,
1553
- L: 138,
1704
+ L: 139,
1554
1705
  S: void 0,
1555
1706
  C: (f, a) => f(...a)
1556
1707
  });
@@ -1610,40 +1761,40 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1610
1761
  onUpdateProfile,
1611
1762
  ...agentProps
1612
1763
  };
1613
- return identityState.context.invitation ? /* @__PURE__ */ React27.createElement(IdentityPanelWithInvitationImpl, {
1764
+ return identityState.context.invitation ? /* @__PURE__ */ React29.createElement(IdentityPanelWithInvitationImpl, {
1614
1765
  ...implProps,
1615
1766
  invitation: identityState.context.invitation
1616
- }) : /* @__PURE__ */ React27.createElement(IdentityPanelImpl, implProps);
1767
+ }) : /* @__PURE__ */ React29.createElement(IdentityPanelImpl, implProps);
1617
1768
  };
1618
1769
 
1619
1770
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
1620
- import React37, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1771
+ import React39, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1621
1772
  import { log as log8 } from "@dxos/log";
1622
1773
  import { useClient as useClient6, useMulticastObservable } from "@dxos/react-client";
1623
1774
  import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
1624
- import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext as useThemeContext3 } from "@dxos/react-ui";
1775
+ import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext as useThemeContext4 } from "@dxos/react-ui";
1625
1776
 
1626
1777
  // packages/sdk/shell/src/panels/JoinPanel/JoinHeading.tsx
1627
1778
  import { X as X4 } from "@phosphor-icons/react";
1628
- import React28, { cloneElement, forwardRef as forwardRef8 } from "react";
1629
- import { Button as Button5, useTranslation as useTranslation14 } from "@dxos/react-ui";
1630
- import { descriptionText as descriptionText8, getSize as getSize9, mx as mx20 } from "@dxos/react-ui-theme";
1779
+ import React30, { cloneElement, forwardRef as forwardRef8 } from "react";
1780
+ import { Button as Button7, useTranslation as useTranslation16 } from "@dxos/react-ui";
1781
+ import { descriptionText as descriptionText8, getSize as getSize11, mx as mx20 } from "@dxos/react-ui-theme";
1631
1782
  var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActionParent }, forwardedRef) => {
1632
- const { t } = useTranslation14("os");
1633
- const exitButton = /* @__PURE__ */ React28.createElement(Button5, {
1783
+ const { t } = useTranslation16("os");
1784
+ const exitButton = /* @__PURE__ */ React30.createElement(Button7, {
1634
1785
  variant: "ghost",
1635
1786
  ...onExit && {
1636
1787
  onClick: onExit
1637
1788
  },
1638
1789
  classNames: mx20(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1639
1790
  "data-testid": "join-exit"
1640
- }, /* @__PURE__ */ React28.createElement(X4, {
1791
+ }, /* @__PURE__ */ React30.createElement(X4, {
1641
1792
  weight: "bold",
1642
- className: getSize9(4)
1643
- }), /* @__PURE__ */ React28.createElement("span", {
1793
+ className: getSize11(4)
1794
+ }), /* @__PURE__ */ React30.createElement("span", {
1644
1795
  className: "sr-only"
1645
1796
  }, t("exit label")));
1646
- return /* @__PURE__ */ React28.createElement(Heading, {
1797
+ return /* @__PURE__ */ React30.createElement(Heading, {
1647
1798
  ref: forwardedRef,
1648
1799
  titleId,
1649
1800
  title: t(mode === "halo-only" ? "selecting identity heading" : "joining space heading"),
@@ -2246,17 +2397,17 @@ var useJoinMachine = (client, options) => {
2246
2397
 
2247
2398
  // packages/sdk/shell/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx
2248
2399
  import { CaretRight as CaretRight2, Plus as Plus2, QrCode, Textbox } from "@phosphor-icons/react";
2249
- import React29 from "react";
2250
- import { useTranslation as useTranslation15 } from "@dxos/react-ui";
2251
- import { getSize as getSize10 } from "@dxos/react-ui-theme";
2400
+ import React31 from "react";
2401
+ import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2402
+ import { getSize as getSize12 } from "@dxos/react-ui-theme";
2252
2403
  var AdditionMethodChooser = (viewStateProps) => {
2253
2404
  const disabled = !viewStateProps.active;
2254
2405
  const { send } = viewStateProps;
2255
- const { t } = useTranslation15("os");
2406
+ const { t } = useTranslation17("os");
2256
2407
  const sharedButtonProps = {
2257
2408
  disabled,
2258
- after: /* @__PURE__ */ React29.createElement(CaretRight2, {
2259
- className: getSize10(4),
2409
+ after: /* @__PURE__ */ React31.createElement(CaretRight2, {
2410
+ className: getSize12(4),
2260
2411
  weight: "bold"
2261
2412
  }),
2262
2413
  slots: {
@@ -2265,37 +2416,37 @@ var AdditionMethodChooser = (viewStateProps) => {
2265
2416
  }
2266
2417
  }
2267
2418
  };
2268
- return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React29.createElement("div", {
2419
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React31.createElement("div", {
2269
2420
  role: "none",
2270
2421
  className: "flex flex-col gap-1 grow"
2271
- }, /* @__PURE__ */ React29.createElement(CompoundButton, {
2422
+ }, /* @__PURE__ */ React31.createElement(CompoundButton, {
2272
2423
  ...sharedButtonProps,
2273
2424
  description: t("create identity description"),
2274
- before: /* @__PURE__ */ React29.createElement(Plus2, {
2275
- className: getSize10(6)
2425
+ before: /* @__PURE__ */ React31.createElement(Plus2, {
2426
+ className: getSize12(6)
2276
2427
  }),
2277
2428
  onClick: () => send({
2278
2429
  type: "createIdentity"
2279
2430
  }),
2280
2431
  "data-autofocus": "choosingAuthMethod",
2281
2432
  "data-testid": "identity-chooser.create-identity"
2282
- }, t("create identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2433
+ }, t("create identity label")), /* @__PURE__ */ React31.createElement(CompoundButton, {
2283
2434
  ...sharedButtonProps,
2284
2435
  description: t("join identity description"),
2285
- before: /* @__PURE__ */ React29.createElement(QrCode, {
2286
- className: getSize10(6)
2436
+ before: /* @__PURE__ */ React31.createElement(QrCode, {
2437
+ className: getSize12(6)
2287
2438
  }),
2288
2439
  onClick: () => send({
2289
2440
  type: "acceptHaloInvitation"
2290
2441
  }),
2291
2442
  "data-testid": "identity-chooser.join-identity"
2292
- }, t("join identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2443
+ }, t("join identity label")), /* @__PURE__ */ React31.createElement(CompoundButton, {
2293
2444
  ...sharedButtonProps,
2294
2445
  // TODO(mykola): Implement recover.
2295
2446
  disabled: true,
2296
2447
  description: t("recover identity description"),
2297
- before: /* @__PURE__ */ React29.createElement(Textbox, {
2298
- className: getSize10(6)
2448
+ before: /* @__PURE__ */ React31.createElement(Textbox, {
2449
+ className: getSize12(6)
2299
2450
  }),
2300
2451
  onClick: () => send({
2301
2452
  type: "recoverIdentity"
@@ -2305,37 +2456,39 @@ var AdditionMethodChooser = (viewStateProps) => {
2305
2456
  };
2306
2457
 
2307
2458
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityAdded.tsx
2308
- import React30, { cloneElement as cloneElement2 } from "react";
2459
+ import React32, { cloneElement as cloneElement2 } from "react";
2309
2460
  import { generateName as generateName4 } from "@dxos/display-name";
2310
- import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation16 } from "@dxos/react-ui";
2461
+ import { Avatar as Avatar5, useId as useId6, useTranslation as useTranslation18 } from "@dxos/react-ui";
2311
2462
  import { mx as mx21 } from "@dxos/react-ui-theme";
2463
+ import { hexToFallback } from "@dxos/util";
2312
2464
  var IdentityAdded = (props) => {
2313
2465
  const { mode, addedIdentity, active, send, onDone, doneActionParent } = props;
2314
2466
  const disabled = !active;
2315
- const { t } = useTranslation16("os");
2316
- const fallbackValue = addedIdentity?.identityKey.toHex();
2467
+ const { t } = useTranslation18("os");
2468
+ const addedIdentityHex = addedIdentity?.identityKey.toHex() ?? "0";
2469
+ const fallbackValue = hexToFallback(addedIdentityHex);
2317
2470
  const labelId = useId6("identityListItem__label");
2318
- const jdenticon = useJdenticonHref4(fallbackValue ?? "", 12);
2319
- const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName4(addedIdentity?.identityKey.toHex()));
2320
- const doneAction = /* @__PURE__ */ React30.createElement(Action, {
2471
+ const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName4(addedIdentityHex));
2472
+ const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2321
2473
  ...onDone && {
2322
2474
  onClick: () => onDone(null)
2323
2475
  },
2324
2476
  disabled,
2325
2477
  "data-autofocus": "confirmingAddedIdentity",
2326
2478
  "data-testid": "identity-added-done"
2327
- }, /* @__PURE__ */ React30.createElement("span", null, t("done label")));
2328
- return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React30.createElement("div", {
2479
+ }, /* @__PURE__ */ React32.createElement("span", null, t("done label")));
2480
+ return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React32.createElement("div", {
2329
2481
  role: "none",
2330
2482
  className: "grow flex flex-col items-center justify-center text-center gap-2"
2331
- }, /* @__PURE__ */ React30.createElement(Avatar5.Root, {
2483
+ }, /* @__PURE__ */ React32.createElement(Avatar5.Root, {
2332
2484
  status: "active",
2333
- labelId
2334
- }, /* @__PURE__ */ React30.createElement(Avatar5.Frame, null, /* @__PURE__ */ React30.createElement(Avatar5.Fallback, {
2335
- href: jdenticon
2336
- })), /* @__PURE__ */ React30.createElement(Avatar5.Label, {
2485
+ labelId,
2486
+ hue: addedIdentity?.profile?.data?.hue || fallbackValue.hue
2487
+ }, /* @__PURE__ */ React32.createElement(Avatar5.Frame, null, /* @__PURE__ */ React32.createElement(Avatar5.Fallback, {
2488
+ text: addedIdentity?.profile?.data?.emoji || fallbackValue.emoji
2489
+ })), /* @__PURE__ */ React32.createElement(Avatar5.Label, {
2337
2490
  classNames: mx21("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2338
- }, displayName))), /* @__PURE__ */ React30.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React30.createElement(Action, {
2491
+ }, displayName))), /* @__PURE__ */ React32.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React32.createElement(Action, {
2339
2492
  variant: "primary",
2340
2493
  disabled: disabled || !addedIdentity,
2341
2494
  onClick: () => addedIdentity && send({
@@ -2347,17 +2500,17 @@ var IdentityAdded = (props) => {
2347
2500
  };
2348
2501
 
2349
2502
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx
2350
- import React31, { useState as useState5 } from "react";
2503
+ import React33, { useState as useState6 } from "react";
2351
2504
  import { log as log5 } from "@dxos/log";
2352
2505
  import { useClient as useClient4 } from "@dxos/react-client";
2353
- import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2506
+ import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2354
2507
  var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2355
2508
  var IdentityInput = (props) => {
2356
2509
  const { send, method } = props;
2357
2510
  const isRecover = method === "recover identity";
2358
2511
  const client = useClient4();
2359
- const { t } = useTranslation17("os");
2360
- const [validationMessage, setValidationMessage] = useState5("");
2512
+ const { t } = useTranslation19("os");
2513
+ const [validationMessage, setValidationMessage] = useState6("");
2361
2514
  const createIdentity = (displayName) => {
2362
2515
  void client.halo.createIdentity({
2363
2516
  [isRecover ? "seedphrase" : "displayName"]: displayName
@@ -2376,7 +2529,7 @@ var IdentityInput = (props) => {
2376
2529
  setValidationMessage(t(isRecover ? "failed to recover identity message" : "failed to create identity message"));
2377
2530
  });
2378
2531
  };
2379
- return /* @__PURE__ */ React31.createElement(IdentityInputImpl, {
2532
+ return /* @__PURE__ */ React33.createElement(IdentityInputImpl, {
2380
2533
  ...props,
2381
2534
  onDisplayNameConfirm: createIdentity,
2382
2535
  validationMessage
@@ -2385,27 +2538,27 @@ var IdentityInput = (props) => {
2385
2538
  var IdentityInputImpl = (props) => {
2386
2539
  const { method, send, active, onDisplayNameConfirm, validationMessage } = props;
2387
2540
  const disabled = !active;
2388
- const { t } = useTranslation17("os");
2389
- const [inputValue, setInputValue] = useState5("");
2541
+ const { t } = useTranslation19("os");
2542
+ const [inputValue, setInputValue] = useState6("");
2390
2543
  const isRecover = method === "recover identity";
2391
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2544
+ return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2392
2545
  role: "none",
2393
2546
  className: "grow flex flex-col justify-center"
2394
- }, /* @__PURE__ */ React31.createElement(Input, {
2547
+ }, /* @__PURE__ */ React33.createElement(Input, {
2395
2548
  validationMessage,
2396
- label: /* @__PURE__ */ React31.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2549
+ label: /* @__PURE__ */ React33.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2397
2550
  disabled,
2398
2551
  "data-testid": "identity-input",
2399
2552
  placeholder: isRecover ? "Type your recovery phrase" : "Type a display name",
2400
2553
  onChange: ({ target: { value } }) => setInputValue(value)
2401
- })), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2554
+ })), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2402
2555
  variant: "ghost",
2403
2556
  disabled,
2404
2557
  onClick: () => send?.({
2405
2558
  type: "deselectAuthMethod"
2406
2559
  }),
2407
2560
  "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-back`
2408
- }, t("back label")), /* @__PURE__ */ React31.createElement(Action, {
2561
+ }, t("back label")), /* @__PURE__ */ React33.createElement(Action, {
2409
2562
  variant: "primary",
2410
2563
  disabled,
2411
2564
  onClick: () => onDisplayNameConfirm?.(inputValue),
@@ -2414,31 +2567,31 @@ var IdentityInputImpl = (props) => {
2414
2567
  };
2415
2568
 
2416
2569
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAccepted.tsx
2417
- import React32, { cloneElement as cloneElement3 } from "react";
2418
- import { useTranslation as useTranslation18 } from "@dxos/react-ui";
2570
+ import React34, { cloneElement as cloneElement3 } from "react";
2571
+ import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2419
2572
  var InvitationAccepted = (props) => {
2420
2573
  const { active, Kind, doneActionParent, onDone } = props;
2421
2574
  const disabled = !active;
2422
- const { t } = useTranslation18("os");
2423
- const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2575
+ const { t } = useTranslation20("os");
2576
+ const doneAction = /* @__PURE__ */ React34.createElement(Action, {
2424
2577
  variant: "primary",
2425
2578
  onClick: onDone,
2426
2579
  disabled,
2427
2580
  "data-autofocus": `success${Kind}Invitation finishingJoining${Kind}`,
2428
2581
  "data-testid": `${Kind.toLowerCase()}-invitation-accepted-done`
2429
2582
  }, t("done label"));
2430
- return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2583
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2431
2584
  role: "none",
2432
2585
  className: "grow flex flex-col justify-center"
2433
- }, /* @__PURE__ */ React32.createElement("p", {
2586
+ }, /* @__PURE__ */ React34.createElement("p", {
2434
2587
  className: "text-center text-sm font-normal"
2435
- }, t("welcome message"))), /* @__PURE__ */ React32.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2588
+ }, t("welcome message"))), /* @__PURE__ */ React34.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2436
2589
  };
2437
2590
 
2438
2591
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx
2439
- import React33, { useState as useState6, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2592
+ import React35, { useState as useState7, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2440
2593
  import { log as log6 } from "@dxos/log";
2441
- import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2594
+ import { useTranslation as useTranslation21 } from "@dxos/react-ui";
2442
2595
  var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2443
2596
  var invitationCodeFromUrl = (text) => {
2444
2597
  try {
@@ -2458,8 +2611,8 @@ var invitationCodeFromUrl = (text) => {
2458
2611
  var InvitationInput = (props) => {
2459
2612
  const { Kind, active, send, unredeemedCode, onExit, exitActionParent, onDone, doneActionParent, succeededKeys } = props;
2460
2613
  const disabled = !active;
2461
- const { t } = useTranslation19("os");
2462
- const [inputValue, setInputValue] = useState6(unredeemedCode ?? "");
2614
+ const { t } = useTranslation21("os");
2615
+ const [inputValue, setInputValue] = useState7(unredeemedCode ?? "");
2463
2616
  useEffect4(() => {
2464
2617
  unredeemedCode && setInputValue(unredeemedCode ?? "");
2465
2618
  }, [
@@ -2477,7 +2630,7 @@ var InvitationInput = (props) => {
2477
2630
  }
2478
2631
  });
2479
2632
  };
2480
- const exitAction = /* @__PURE__ */ React33.createElement(Action, {
2633
+ const exitAction = /* @__PURE__ */ React35.createElement(Action, {
2481
2634
  variant: "ghost",
2482
2635
  disabled,
2483
2636
  ...onExit ? {
@@ -2487,11 +2640,11 @@ var InvitationInput = (props) => {
2487
2640
  },
2488
2641
  "data-testid": "join-exit"
2489
2642
  }, t("cancel label"));
2490
- return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2643
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2491
2644
  role: "none",
2492
2645
  className: "grow flex flex-col justify-center"
2493
- }, /* @__PURE__ */ React33.createElement(Input, {
2494
- label: /* @__PURE__ */ React33.createElement(StepHeading, null, t("invitation input label")),
2646
+ }, /* @__PURE__ */ React35.createElement(Input, {
2647
+ label: /* @__PURE__ */ React35.createElement(StepHeading, null, t("invitation input label")),
2495
2648
  // TODO(burdon): Translation.
2496
2649
  placeholder: "Type an invitation code",
2497
2650
  disabled,
@@ -2500,14 +2653,14 @@ var InvitationInput = (props) => {
2500
2653
  "data-autofocus": `inputting${Kind}InvitationCode`,
2501
2654
  "data-testid": `${Kind.toLowerCase()}-invitation-input`,
2502
2655
  onKeyUp: ({ key }) => key === "Enter" && handleNext()
2503
- })), /* @__PURE__ */ React33.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React33.createElement(Action, {
2656
+ })), /* @__PURE__ */ React35.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React35.createElement(Action, {
2504
2657
  variant: "ghost",
2505
2658
  disabled,
2506
2659
  onClick: () => send({
2507
2660
  type: "deselectAuthMethod"
2508
2661
  }),
2509
2662
  "data-testid": `${Kind.toLowerCase()}-invitation-input-back`
2510
- }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React33.createElement(Action, {
2663
+ }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React35.createElement(Action, {
2511
2664
  variant: "primary",
2512
2665
  disabled,
2513
2666
  onClick: handleNext,
@@ -2516,8 +2669,8 @@ var InvitationInput = (props) => {
2516
2669
  };
2517
2670
 
2518
2671
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationRescuer.tsx
2519
- import React34 from "react";
2520
- import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2672
+ import React36 from "react";
2673
+ import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2521
2674
  import { descriptionText as descriptionText9 } from "@dxos/react-ui-theme";
2522
2675
  var InvitationActions = ({
2523
2676
  // `invitationState` does report correct state, but here we evaluate whether `failReason` is a better source of truth
@@ -2529,14 +2682,14 @@ var InvitationActions = ({
2529
2682
  Kind,
2530
2683
  failReason
2531
2684
  }) => {
2532
- const { t } = useTranslation20("os");
2685
+ const { t } = useTranslation22("os");
2533
2686
  if (failReason) {
2534
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2687
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(StepHeading, {
2535
2688
  className: descriptionText9
2536
- }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React34.createElement("div", {
2689
+ }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React36.createElement("div", {
2537
2690
  role: "none",
2538
2691
  className: "grow"
2539
- }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2692
+ }), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2540
2693
  disabled: !active,
2541
2694
  onClick: () => send({
2542
2695
  type: `reset${Kind}Invitation`
@@ -2544,16 +2697,16 @@ var InvitationActions = ({
2544
2697
  "data-testid": "invitation-rescuer-reset"
2545
2698
  }, t("reset label"))));
2546
2699
  } else {
2547
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2700
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(StepHeading, {
2548
2701
  className: descriptionText9
2549
- }, t("connecting status label")), /* @__PURE__ */ React34.createElement("div", {
2702
+ }, t("connecting status label")), /* @__PURE__ */ React36.createElement("div", {
2550
2703
  role: "none",
2551
2704
  className: "grow"
2552
- }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2705
+ }), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2553
2706
  disabled: true,
2554
2707
  classNames: "order-2",
2555
2708
  "data-testid": "next"
2556
- }, t("next label")), /* @__PURE__ */ React34.createElement(Action, {
2709
+ }, t("next label")), /* @__PURE__ */ React36.createElement(Action, {
2557
2710
  disabled: !active,
2558
2711
  onClick: onInvitationCancel,
2559
2712
  "data-testid": "invitation-rescuer-cancel"
@@ -2562,46 +2715,47 @@ var InvitationActions = ({
2562
2715
  };
2563
2716
  var InvitationRescuer = (props) => {
2564
2717
  const { Kind, invitationState, active, send } = props;
2565
- const { t } = useTranslation20("os");
2566
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2718
+ const { t } = useTranslation22("os");
2719
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2567
2720
  role: "none",
2568
2721
  className: "grow flex flex-col justify-center"
2569
- }, /* @__PURE__ */ React34.createElement(StepHeading, {
2722
+ }, /* @__PURE__ */ React36.createElement(StepHeading, {
2570
2723
  className: descriptionText9
2571
- }, "There was a problem joining the space")), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2724
+ }, "There was a problem joining the space")), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2572
2725
  disabled: !active,
2573
2726
  "data-testid": "invitation-rescuer-blank-reset",
2574
2727
  onClick: () => send({
2575
2728
  type: `reset${Kind}Invitation`
2576
2729
  })
2577
- }, t("reset label")))) : /* @__PURE__ */ React34.createElement(InvitationActions, props));
2730
+ }, t("reset label")))) : /* @__PURE__ */ React36.createElement(InvitationActions, props));
2578
2731
  };
2579
2732
 
2580
2733
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx
2581
- import React35, { useState as useState7 } from "react";
2582
- import { Input as Input2, useTranslation as useTranslation21 } from "@dxos/react-ui";
2734
+ import React37, { useState as useState8 } from "react";
2735
+ import { Input as Input2, useTranslation as useTranslation23 } from "@dxos/react-ui";
2736
+ import { hexToEmoji as hexToEmoji4 } from "@dxos/util";
2583
2737
  var pinLength = 6;
2584
2738
  var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, onInvitationAuthenticate, onInvitationCancel }) => {
2585
2739
  const disabled = !active || pending;
2586
- const { t } = useTranslation21("os");
2740
+ const { t } = useTranslation23("os");
2587
2741
  const invitationType = Kind.toLowerCase();
2588
- const [authCode, setAuthCode] = useState7("");
2742
+ const [authCode, setAuthCode] = useState8("");
2589
2743
  const onChange = ({ target: { value } }) => {
2590
2744
  setAuthCode(value);
2591
2745
  if (value.length === pinLength) {
2592
2746
  document.querySelector(`[data-autofocus-pinlength="${invitationType}"]`)?.focus();
2593
2747
  }
2594
2748
  };
2595
- return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2749
+ return /* @__PURE__ */ React37.createElement(React37.Fragment, null, /* @__PURE__ */ React37.createElement("div", {
2596
2750
  role: "none",
2597
2751
  className: "grow flex flex-col justify-center"
2598
- }, invitationId && /* @__PURE__ */ React35.createElement(Emoji, {
2599
- text: toEmoji(invitationId)
2600
- }), /* @__PURE__ */ React35.createElement(Input2.Root, failed && {
2752
+ }, invitationId && /* @__PURE__ */ React37.createElement(Emoji, {
2753
+ text: hexToEmoji4(invitationId)
2754
+ }), /* @__PURE__ */ React37.createElement(Input2.Root, failed && {
2601
2755
  validationValence: "error"
2602
- }, /* @__PURE__ */ React35.createElement(Input2.Label, {
2756
+ }, /* @__PURE__ */ React37.createElement(Input2.Label, {
2603
2757
  asChild: true
2604
- }, /* @__PURE__ */ React35.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React35.createElement(Input2.PinInput, {
2758
+ }, /* @__PURE__ */ React37.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React37.createElement(Input2.PinInput, {
2605
2759
  disabled,
2606
2760
  length: pinLength,
2607
2761
  onChange,
@@ -2612,14 +2766,14 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2612
2766
  "data-prevent-ios-autofocus": true,
2613
2767
  "data-testid": `${invitationType}-auth-code-input`,
2614
2768
  "data-1p-ignore": true
2615
- }), failed && /* @__PURE__ */ React35.createElement(Input2.DescriptionAndValidation, {
2769
+ }), failed && /* @__PURE__ */ React37.createElement(Input2.DescriptionAndValidation, {
2616
2770
  classNames: "text-center"
2617
- }, /* @__PURE__ */ React35.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(Action, {
2771
+ }, /* @__PURE__ */ React37.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React37.createElement(Actions, null, /* @__PURE__ */ React37.createElement(Action, {
2618
2772
  variant: "ghost",
2619
2773
  disabled,
2620
2774
  onClick: () => onInvitationCancel?.(),
2621
2775
  "data-testid": `${invitationType}-invitation-authenticator-cancel`
2622
- }, t("cancel label")), /* @__PURE__ */ React35.createElement(Action, {
2776
+ }, t("cancel label")), /* @__PURE__ */ React37.createElement(Action, {
2623
2777
  variant: "primary",
2624
2778
  disabled,
2625
2779
  onClick: () => onInvitationAuthenticate?.(authCode),
@@ -2629,16 +2783,16 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2629
2783
  };
2630
2784
 
2631
2785
  // packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx
2632
- import React36, { useState as useState8 } from "react";
2786
+ import React38, { useState as useState9 } from "react";
2633
2787
  import { log as log7 } from "@dxos/log";
2634
2788
  import { useClient as useClient5 } from "@dxos/react-client";
2635
- import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2789
+ import { useTranslation as useTranslation24 } from "@dxos/react-ui";
2636
2790
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2637
2791
  var ResetIdentity = ({ send, active }) => {
2638
2792
  const client = useClient5();
2639
- const { t } = useTranslation22("os");
2640
- const [validationMessage, setValidationMessage] = useState8("");
2641
- const [pending, setPending] = useState8(false);
2793
+ const { t } = useTranslation24("os");
2794
+ const [validationMessage, setValidationMessage] = useState9("");
2795
+ const [pending, setPending] = useState9(false);
2642
2796
  const resetIdentity = () => {
2643
2797
  setPending(true);
2644
2798
  void client.reset().then(() => send?.({
@@ -2654,7 +2808,7 @@ var ResetIdentity = ({ send, active }) => {
2654
2808
  setPending(false);
2655
2809
  });
2656
2810
  };
2657
- return /* @__PURE__ */ React36.createElement(ResetIdentityImpl, {
2811
+ return /* @__PURE__ */ React38.createElement(ResetIdentityImpl, {
2658
2812
  disabled: !active,
2659
2813
  pending,
2660
2814
  validationMessage,
@@ -2662,22 +2816,22 @@ var ResetIdentity = ({ send, active }) => {
2662
2816
  });
2663
2817
  };
2664
2818
  var ResetIdentityImpl = ({ disabled, pending, validationMessage, onConfirm }) => {
2665
- const { t } = useTranslation22("os");
2819
+ const { t } = useTranslation24("os");
2666
2820
  const confirmationValue = t("confirmation value");
2667
- const [inputValue, setInputValue] = useState8("");
2668
- return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2821
+ const [inputValue, setInputValue] = useState9("");
2822
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("div", {
2669
2823
  role: "none",
2670
2824
  className: "grow flex flex-col justify-center"
2671
- }, /* @__PURE__ */ React36.createElement(Input, {
2825
+ }, /* @__PURE__ */ React38.createElement(Input, {
2672
2826
  validationMessage,
2673
- label: /* @__PURE__ */ React36.createElement(StepHeading, null, t("reset identity input label", {
2827
+ label: /* @__PURE__ */ React38.createElement(StepHeading, null, t("reset identity input label", {
2674
2828
  confirmationValue
2675
2829
  })),
2676
2830
  disabled,
2677
2831
  "data-testid": "reset-identity-input",
2678
2832
  placeholder: confirmationValue,
2679
2833
  onChange: ({ target: { value } }) => setInputValue(value)
2680
- })), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2834
+ })), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(Action, {
2681
2835
  // TODO(wittjosiah): Probably make this red?
2682
2836
  variant: "primary",
2683
2837
  disabled: disabled || pending || inputValue !== confirmationValue,
@@ -2714,47 +2868,47 @@ var resolvedTextColor = (status) => status === Invitation7.State.ERROR ? errorTe
2714
2868
  var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2715
2869
  var JoinPanelImpl = (props) => {
2716
2870
  const { titleId, send, activeView, failed, mode, unredeemedCodes, invitationStates, succeededKeys, failReasons, onExit, onHaloDone, onSpaceDone, exitActionParent, doneActionParent, onHaloInvitationCancel, onSpaceInvitationCancel, onHaloInvitationAuthenticate, onSpaceInvitationAuthenticate, IdentityInput: IdentityInputComponent = IdentityInput, ResetIdentity: ResetIdentityComponent = ResetIdentity } = props;
2717
- return /* @__PURE__ */ React37.createElement(DensityProvider3, {
2871
+ return /* @__PURE__ */ React39.createElement(DensityProvider3, {
2718
2872
  density: "fine"
2719
- }, mode !== "halo-only" && /* @__PURE__ */ React37.createElement(JoinHeading, {
2873
+ }, mode !== "halo-only" && /* @__PURE__ */ React39.createElement(JoinHeading, {
2720
2874
  titleId,
2721
2875
  mode,
2722
2876
  onExit,
2723
2877
  exitActionParent
2724
- }), /* @__PURE__ */ React37.createElement(Viewport.Root, {
2878
+ }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
2725
2879
  focusManaged: true,
2726
2880
  activeView
2727
- }, /* @__PURE__ */ React37.createElement(Viewport.Views, null, /* @__PURE__ */ React37.createElement(Viewport.View, {
2881
+ }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
2728
2882
  classNames: stepStyles,
2729
2883
  id: "addition method chooser"
2730
- }, /* @__PURE__ */ React37.createElement(AdditionMethodChooser, {
2884
+ }, /* @__PURE__ */ React39.createElement(AdditionMethodChooser, {
2731
2885
  send,
2732
2886
  active: activeView === "addition method chooser"
2733
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2887
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2734
2888
  classNames: stepStyles,
2735
2889
  id: "reset identity confirmation"
2736
- }, /* @__PURE__ */ React37.createElement(ResetIdentityComponent, {
2890
+ }, /* @__PURE__ */ React39.createElement(ResetIdentityComponent, {
2737
2891
  send,
2738
2892
  method: "reset identity",
2739
2893
  active: activeView === "reset identity confirmation"
2740
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2894
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2741
2895
  classNames: stepStyles,
2742
2896
  id: "create identity input"
2743
- }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2897
+ }, /* @__PURE__ */ React39.createElement(IdentityInputComponent, {
2744
2898
  send,
2745
2899
  method: "create identity",
2746
2900
  active: activeView === "create identity input"
2747
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2901
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2748
2902
  classNames: stepStyles,
2749
2903
  id: "recover identity input"
2750
- }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2904
+ }, /* @__PURE__ */ React39.createElement(IdentityInputComponent, {
2751
2905
  send,
2752
2906
  method: "recover identity",
2753
2907
  active: activeView === "recover identity input"
2754
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2908
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2755
2909
  classNames: stepStyles,
2756
2910
  id: "halo invitation input"
2757
- }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2911
+ }, /* @__PURE__ */ React39.createElement(InvitationInput, {
2758
2912
  send,
2759
2913
  Kind: "Halo",
2760
2914
  active: activeView === "halo invitation input",
@@ -2764,20 +2918,20 @@ var JoinPanelImpl = (props) => {
2764
2918
  ...succeededKeys?.Halo && {
2765
2919
  succeededKeys: succeededKeys.Halo
2766
2920
  }
2767
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2921
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2768
2922
  classNames: stepStyles,
2769
2923
  id: "halo invitation rescuer"
2770
- }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2924
+ }, /* @__PURE__ */ React39.createElement(InvitationRescuer, {
2771
2925
  send,
2772
2926
  Kind: "Halo",
2773
2927
  active: activeView === "halo invitation rescuer",
2774
2928
  invitationState: invitationStates?.Halo,
2775
2929
  onInvitationCancel: onHaloInvitationCancel,
2776
2930
  failReason: failReasons?.Halo
2777
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2931
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2778
2932
  classNames: stepStyles,
2779
2933
  id: "halo invitation authenticator"
2780
- }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2934
+ }, /* @__PURE__ */ React39.createElement(InvitationAuthenticator, {
2781
2935
  send,
2782
2936
  Kind: "Halo",
2783
2937
  active: activeView === "halo invitation authenticator",
@@ -2786,28 +2940,28 @@ var JoinPanelImpl = (props) => {
2786
2940
  ...failed.has("Halo") && {
2787
2941
  failed: true
2788
2942
  }
2789
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2943
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2790
2944
  classNames: stepStyles,
2791
2945
  id: "halo invitation accepted"
2792
- }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2946
+ }, /* @__PURE__ */ React39.createElement(InvitationAccepted, {
2793
2947
  send,
2794
2948
  Kind: "Halo",
2795
2949
  active: activeView === "halo invitation accepted",
2796
2950
  doneActionParent,
2797
2951
  onDone: onHaloDone
2798
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2952
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2799
2953
  classNames: stepStyles,
2800
2954
  id: "identity added"
2801
- }, /* @__PURE__ */ React37.createElement(IdentityAdded, {
2955
+ }, /* @__PURE__ */ React39.createElement(IdentityAdded, {
2802
2956
  send,
2803
2957
  mode,
2804
2958
  active: activeView === "identity added",
2805
2959
  doneActionParent,
2806
2960
  onDone: onHaloDone
2807
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2961
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2808
2962
  classNames: stepStyles,
2809
2963
  id: "space invitation input"
2810
- }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2964
+ }, /* @__PURE__ */ React39.createElement(InvitationInput, {
2811
2965
  send,
2812
2966
  Kind: "Space",
2813
2967
  active: activeView === "space invitation input",
@@ -2819,20 +2973,20 @@ var JoinPanelImpl = (props) => {
2819
2973
  },
2820
2974
  onExit,
2821
2975
  exitActionParent
2822
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2976
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2823
2977
  classNames: stepStyles,
2824
2978
  id: "space invitation rescuer"
2825
- }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2979
+ }, /* @__PURE__ */ React39.createElement(InvitationRescuer, {
2826
2980
  send,
2827
2981
  Kind: "Space",
2828
2982
  active: activeView === "space invitation rescuer",
2829
2983
  invitationState: invitationStates?.Space,
2830
2984
  onInvitationCancel: onSpaceInvitationCancel,
2831
2985
  failReason: failReasons?.Space
2832
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2986
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2833
2987
  classNames: stepStyles,
2834
2988
  id: "space invitation authenticator"
2835
- }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2989
+ }, /* @__PURE__ */ React39.createElement(InvitationAuthenticator, {
2836
2990
  send,
2837
2991
  Kind: "Space",
2838
2992
  active: activeView === "space invitation authenticator",
@@ -2841,10 +2995,10 @@ var JoinPanelImpl = (props) => {
2841
2995
  ...failed.has("Space") && {
2842
2996
  failed: true
2843
2997
  }
2844
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2998
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2845
2999
  classNames: stepStyles,
2846
3000
  id: "space invitation accepted"
2847
- }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
3001
+ }, /* @__PURE__ */ React39.createElement(InvitationAccepted, {
2848
3002
  send,
2849
3003
  Kind: "Space",
2850
3004
  active: activeView === "space invitation accepted",
@@ -2855,7 +3009,7 @@ var JoinPanelImpl = (props) => {
2855
3009
  var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCode, exitActionParent, onExit, doneActionParent, onDone: propsOnDone }) => {
2856
3010
  const client = useClient6();
2857
3011
  const identity = useIdentity2();
2858
- const { hasIosKeyboard } = useThemeContext3();
3012
+ const { hasIosKeyboard } = useThemeContext4();
2859
3013
  const titleId = useId7("joinPanel__heading", propsTitleId);
2860
3014
  const [joinState, joinSend, joinService] = useJoinMachine(client, {
2861
3015
  context: {
@@ -3084,7 +3238,7 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
3084
3238
  joinState,
3085
3239
  propsOnDone
3086
3240
  ]);
3087
- return /* @__PURE__ */ React37.createElement(JoinPanelImpl, {
3241
+ return /* @__PURE__ */ React39.createElement(JoinPanelImpl, {
3088
3242
  titleId,
3089
3243
  mode,
3090
3244
  send: joinSend,
@@ -3123,10 +3277,10 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
3123
3277
 
3124
3278
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3125
3279
  import { Planet } from "@phosphor-icons/react";
3126
- import React39, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
3280
+ import React41, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
3127
3281
  import { log as log10 } from "@dxos/log";
3128
3282
  import { useInvitationStatus as useInvitationStatus3 } from "@dxos/react-client/invitations";
3129
- import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation24 } from "@dxos/react-ui";
3283
+ import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation26 } from "@dxos/react-ui";
3130
3284
 
3131
3285
  // packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts
3132
3286
  import { useMachine as useMachine3 } from "@xstate/react";
@@ -3192,16 +3346,16 @@ var useSpaceMachine = (options) => {
3192
3346
 
3193
3347
  // packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx
3194
3348
  import { Placeholder as Placeholder2, UserPlus, UsersThree } from "@phosphor-icons/react";
3195
- import React38, { useCallback as useCallback8, useState as useState9 } from "react";
3349
+ import React40, { useCallback as useCallback8, useState as useState10 } from "react";
3196
3350
  import { useConfig } from "@dxos/react-client";
3197
3351
  import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client/echo";
3198
3352
  import { Invitation as Invitation8, InvitationEncoder as InvitationEncoder4 } from "@dxos/react-client/invitations";
3199
- import { ScrollArea, useTranslation as useTranslation23 } from "@dxos/react-ui";
3353
+ import { ScrollArea, useTranslation as useTranslation25 } from "@dxos/react-ui";
3200
3354
  import { descriptionText as descriptionText10, mx as mx22 } from "@dxos/react-ui-theme";
3201
3355
  var activeActionKey = "dxos:react-shell/space-manager/active-action";
3202
3356
  var SpaceManager = (props) => {
3203
3357
  const { space, target } = props;
3204
- const { t } = useTranslation23("os");
3358
+ const { t } = useTranslation25("os");
3205
3359
  const config = useConfig();
3206
3360
  const invitations = useSpaceInvitations2(space?.key);
3207
3361
  const onInvitationEvent = useCallback8((invitation) => {
@@ -3249,7 +3403,7 @@ var SpaceManager = (props) => {
3249
3403
  ])
3250
3404
  }
3251
3405
  };
3252
- return /* @__PURE__ */ React38.createElement(SpaceManagerImpl, {
3406
+ return /* @__PURE__ */ React40.createElement(SpaceManagerImpl, {
3253
3407
  ...props,
3254
3408
  invitations,
3255
3409
  inviteActions
@@ -3258,7 +3412,7 @@ var SpaceManager = (props) => {
3258
3412
  var headingFragment = "pis-3 pie-1 plb-1 mbe-1 font-medium";
3259
3413
  var SpaceManagerImpl = (props) => {
3260
3414
  const { active, space, createInvitationUrl, send, inviteActions: propsInviteActions, invitations, showInactiveInvitations, SpaceMemberList: SpaceMemberListComponent = SpaceMemberList, InvitationList: InvitationListComponent = InvitationList } = props;
3261
- const { t } = useTranslation23("os");
3415
+ const { t } = useTranslation25("os");
3262
3416
  const inviteActions = propsInviteActions ?? {
3263
3417
  noopInvite: {
3264
3418
  label: t("create space invitation label"),
@@ -3268,7 +3422,7 @@ var SpaceManagerImpl = (props) => {
3268
3422
  }
3269
3423
  }
3270
3424
  };
3271
- const [activeAction, setInternalActiveAction] = useState9(localStorage.getItem(activeActionKey) ?? "inviteOne");
3425
+ const [activeAction, setInternalActiveAction] = useState10(localStorage.getItem(activeActionKey) ?? "inviteOne");
3272
3426
  const setActiveAction = (nextAction) => {
3273
3427
  setInternalActiveAction(nextAction);
3274
3428
  localStorage.setItem(activeActionKey, nextAction);
@@ -3276,26 +3430,26 @@ var SpaceManagerImpl = (props) => {
3276
3430
  const visibleInvitations = showInactiveInvitations ? invitations : invitations?.filter((invitation) => ![
3277
3431
  Invitation8.State.CANCELLED
3278
3432
  ].includes(invitation.get().state));
3279
- return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(ScrollArea.Root, {
3433
+ return /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(ScrollArea.Root, {
3280
3434
  classNames: "grow shrink basis-28 -mli-2"
3281
- }, /* @__PURE__ */ React38.createElement(ScrollArea.Viewport, {
3435
+ }, /* @__PURE__ */ React40.createElement(ScrollArea.Viewport, {
3282
3436
  classNames: "is-full pie-2"
3283
- }, !!visibleInvitations?.length && /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("h3", {
3437
+ }, !!visibleInvitations?.length && /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement("h3", {
3284
3438
  className: mx22(headingFragment, descriptionText10)
3285
- }, t("invitation list heading")), /* @__PURE__ */ React38.createElement(InvitationListComponent, {
3439
+ }, t("invitation list heading")), /* @__PURE__ */ React40.createElement(InvitationListComponent, {
3286
3440
  className: "mb-2",
3287
3441
  send,
3288
3442
  invitations: visibleInvitations ?? [],
3289
3443
  onClickRemove: (invitation) => invitation.cancel(),
3290
3444
  createInvitationUrl
3291
- }), /* @__PURE__ */ React38.createElement("h3", {
3445
+ }), /* @__PURE__ */ React40.createElement("h3", {
3292
3446
  className: mx22(headingFragment, descriptionText10, "mbs-2")
3293
- }, t("space member list heading"))), /* @__PURE__ */ React38.createElement(SpaceMemberListComponent, {
3447
+ }, t("space member list heading"))), /* @__PURE__ */ React40.createElement(SpaceMemberListComponent, {
3294
3448
  spaceKey: space.key,
3295
3449
  includeSelf: true
3296
- })), /* @__PURE__ */ React38.createElement(ScrollArea.Scrollbar, {
3450
+ })), /* @__PURE__ */ React40.createElement(ScrollArea.Scrollbar, {
3297
3451
  orientation: "vertical"
3298
- }, /* @__PURE__ */ React38.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(BifurcatedAction, {
3452
+ }, /* @__PURE__ */ React40.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React40.createElement(Actions, null, /* @__PURE__ */ React40.createElement(BifurcatedAction, {
3299
3453
  disabled: !active,
3300
3454
  actions: inviteActions,
3301
3455
  activeAction,
@@ -3307,47 +3461,47 @@ var SpaceManagerImpl = (props) => {
3307
3461
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3308
3462
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
3309
3463
  var SpacePanelHeading = ({ titleId, space, onDone }) => {
3310
- const { t } = useTranslation24("os");
3464
+ const { t } = useTranslation26("os");
3311
3465
  const name = space.properties.name;
3312
- return /* @__PURE__ */ React39.createElement(Heading, {
3466
+ return /* @__PURE__ */ React41.createElement(Heading, {
3313
3467
  titleId,
3314
3468
  title: t("space panel heading"),
3315
- corner: /* @__PURE__ */ React39.createElement(CloseButton, {
3469
+ corner: /* @__PURE__ */ React41.createElement(CloseButton, {
3316
3470
  "data-testid": "identity-panel-done",
3317
3471
  onDone
3318
3472
  })
3319
- }, /* @__PURE__ */ React39.createElement("div", {
3473
+ }, /* @__PURE__ */ React41.createElement("div", {
3320
3474
  role: "none",
3321
3475
  className: "flex gap-4 items-center justify-center mlb-4"
3322
- }, /* @__PURE__ */ React39.createElement(Planet, {
3476
+ }, /* @__PURE__ */ React41.createElement(Planet, {
3323
3477
  size: 32,
3324
3478
  weight: "light"
3325
- }), /* @__PURE__ */ React39.createElement("div", {
3479
+ }), /* @__PURE__ */ React41.createElement("div", {
3326
3480
  className: "block text-start font-light text-xl"
3327
3481
  }, name ?? space.key.truncate())));
3328
3482
  };
3329
3483
  var SpacePanelImpl = (props) => {
3330
3484
  const { titleId, activeView, space, target, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3331
- return /* @__PURE__ */ React39.createElement(DensityProvider4, {
3485
+ return /* @__PURE__ */ React41.createElement(DensityProvider4, {
3332
3486
  density: "fine"
3333
- }, /* @__PURE__ */ React39.createElement(SpacePanelHeading, {
3487
+ }, /* @__PURE__ */ React41.createElement(SpacePanelHeading, {
3334
3488
  ...rest,
3335
3489
  titleId,
3336
3490
  space
3337
- }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
3491
+ }), /* @__PURE__ */ React41.createElement(Viewport.Root, {
3338
3492
  activeView
3339
- }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
3493
+ }, /* @__PURE__ */ React41.createElement(Viewport.Views, null, /* @__PURE__ */ React41.createElement(Viewport.View, {
3340
3494
  id: "space manager",
3341
3495
  classNames: stepStyles
3342
- }, /* @__PURE__ */ React39.createElement(SpaceManagerComponent, {
3496
+ }, /* @__PURE__ */ React41.createElement(SpaceManagerComponent, {
3343
3497
  active: activeView === "space manager",
3344
3498
  space,
3345
3499
  target,
3346
3500
  ...rest
3347
- })), /* @__PURE__ */ React39.createElement(Viewport.View, {
3501
+ })), /* @__PURE__ */ React41.createElement(Viewport.View, {
3348
3502
  id: "space invitation manager",
3349
3503
  classNames: stepStyles
3350
- }, /* @__PURE__ */ React39.createElement(InvitationManagerComponent, {
3504
+ }, /* @__PURE__ */ React41.createElement(InvitationManagerComponent, {
3351
3505
  active: activeView === "space invitation manager",
3352
3506
  ...rest,
3353
3507
  invitationUrl: props.invitationUrl
@@ -3355,7 +3509,7 @@ var SpacePanelImpl = (props) => {
3355
3509
  };
3356
3510
  var SpacePanelWithInvitationImpl = ({ invitation, ...props }) => {
3357
3511
  const invitationStatus = useInvitationStatus3(invitation);
3358
- return /* @__PURE__ */ React39.createElement(SpacePanelImpl, {
3512
+ return /* @__PURE__ */ React41.createElement(SpacePanelImpl, {
3359
3513
  ...props,
3360
3514
  ...invitationStatus,
3361
3515
  invitationUrl: props.createInvitationUrl(invitationStatus.invitationCode)
@@ -3402,91 +3556,91 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3402
3556
  };
3403
3557
  return spaceState.context.invitation ? (
3404
3558
  // TODO(wittjosiah): Unused? Remove?
3405
- /* @__PURE__ */ React39.createElement(SpacePanelWithInvitationImpl, {
3559
+ /* @__PURE__ */ React41.createElement(SpacePanelWithInvitationImpl, {
3406
3560
  ...implProps,
3407
3561
  invitation: spaceState.context.invitation
3408
3562
  })
3409
- ) : /* @__PURE__ */ React39.createElement(SpacePanelImpl, implProps);
3563
+ ) : /* @__PURE__ */ React41.createElement(SpacePanelImpl, implProps);
3410
3564
  };
3411
3565
 
3412
3566
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
3413
3567
  var IdentityDialog = (props) => {
3414
3568
  const titleId = useId9("spaceDialog__title");
3415
- return /* @__PURE__ */ React40.createElement(Dialog.Root, {
3569
+ return /* @__PURE__ */ React42.createElement(Dialog.Root, {
3416
3570
  defaultOpen: true,
3417
3571
  onOpenChange: (open) => open || props.onDone?.()
3418
- }, /* @__PURE__ */ React40.createElement(Dialog.Portal, null, /* @__PURE__ */ React40.createElement(Dialog.Overlay, null, /* @__PURE__ */ React40.createElement(Dialog.Content, {
3572
+ }, /* @__PURE__ */ React42.createElement(Dialog.Portal, null, /* @__PURE__ */ React42.createElement(Dialog.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog.Content, {
3419
3573
  "aria-labelledby": titleId,
3420
3574
  onOpenAutoFocus: (e) => e.preventDefault()
3421
- }, /* @__PURE__ */ React40.createElement(ClipboardProvider, null, /* @__PURE__ */ React40.createElement(IdentityPanel, {
3575
+ }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(IdentityPanel, {
3422
3576
  ...props,
3423
3577
  titleId,
3424
- doneActionParent: /* @__PURE__ */ React40.createElement(Dialog.Close, {
3578
+ doneActionParent: /* @__PURE__ */ React42.createElement(Dialog.Close, {
3425
3579
  asChild: true
3426
3580
  })
3427
3581
  }))))));
3428
3582
  };
3429
3583
 
3430
3584
  // packages/sdk/shell/src/composites/JoinDialog/JoinDialog.tsx
3431
- import React41 from "react";
3585
+ import React43 from "react";
3432
3586
  import { AlertDialog, useId as useId10, useVisualViewport } from "@dxos/react-ui";
3433
3587
  var JoinDialog = (joinPanelProps) => {
3434
3588
  const titleId = useId10("joinDialog__title");
3435
3589
  const { height } = useVisualViewport();
3436
- return /* @__PURE__ */ React41.createElement(AlertDialog.Root, {
3590
+ return /* @__PURE__ */ React43.createElement(AlertDialog.Root, {
3437
3591
  defaultOpen: true,
3438
3592
  onOpenChange: (open) => open || (joinPanelProps.onExit ? joinPanelProps.onExit() : joinPanelProps.onDone?.(null))
3439
- }, /* @__PURE__ */ React41.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React41.createElement(AlertDialog.Overlay, {
3593
+ }, /* @__PURE__ */ React43.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React43.createElement(AlertDialog.Overlay, {
3440
3594
  classNames: "backdrop-blur",
3441
3595
  ...height && {
3442
3596
  style: {
3443
3597
  blockSize: `${height}px`
3444
3598
  }
3445
3599
  }
3446
- }, /* @__PURE__ */ React41.createElement(AlertDialog.Content, {
3600
+ }, /* @__PURE__ */ React43.createElement(AlertDialog.Content, {
3447
3601
  "aria-labelledby": titleId
3448
- }, /* @__PURE__ */ React41.createElement(JoinPanel, {
3602
+ }, /* @__PURE__ */ React43.createElement(JoinPanel, {
3449
3603
  ...joinPanelProps,
3450
3604
  titleId,
3451
- exitActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Cancel, {
3605
+ exitActionParent: /* @__PURE__ */ React43.createElement(AlertDialog.Cancel, {
3452
3606
  asChild: true
3453
3607
  }),
3454
- doneActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Action, {
3608
+ doneActionParent: /* @__PURE__ */ React43.createElement(AlertDialog.Action, {
3455
3609
  asChild: true
3456
3610
  })
3457
3611
  })))));
3458
3612
  };
3459
3613
 
3460
3614
  // packages/sdk/shell/src/composites/Shell/run-shell.tsx
3461
- import React44, { StrictMode } from "react";
3615
+ import React46, { StrictMode } from "react";
3462
3616
  import { createRoot } from "react-dom/client";
3463
3617
  import { DEFAULT_CLIENT_CHANNEL, DEFAULT_SHELL_CHANNEL } from "@dxos/client-protocol";
3464
3618
  import { ShellRuntimeImpl } from "@dxos/client-services";
3465
3619
  import { Client, ClientContext, ClientServicesProxy, Config, SystemStatus } from "@dxos/react-client";
3466
- import { ThemeProvider, Tooltip as Tooltip3 } from "@dxos/react-ui";
3620
+ import { ThemeProvider, Tooltip as Tooltip5 } from "@dxos/react-ui";
3467
3621
  import { defaultTx } from "@dxos/react-ui-theme";
3468
3622
  import { createIFramePort } from "@dxos/rpc-tunnel";
3469
3623
 
3470
3624
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3471
- import React43, { useEffect as useEffect7, useState as useState10 } from "react";
3625
+ import React45, { useEffect as useEffect7, useState as useState11 } from "react";
3472
3626
  import { log as log11 } from "@dxos/log";
3473
3627
  import { ShellDisplay, ShellLayout, useClient as useClient7 } from "@dxos/react-client";
3474
3628
  import { useSpace as useSpace2 } from "@dxos/react-client/echo";
3475
3629
 
3476
3630
  // packages/sdk/shell/src/composites/SpaceDialog/SpaceDialog.tsx
3477
- import React42 from "react";
3631
+ import React44 from "react";
3478
3632
  import { Dialog as Dialog2, useId as useId11 } from "@dxos/react-ui";
3479
3633
  var SpaceDialog = (spacePanelProps) => {
3480
3634
  const titleId = useId11("spaceDialog__title");
3481
- return /* @__PURE__ */ React42.createElement(Dialog2.Root, {
3635
+ return /* @__PURE__ */ React44.createElement(Dialog2.Root, {
3482
3636
  defaultOpen: true,
3483
3637
  onOpenChange: (open) => open || spacePanelProps.onDone?.()
3484
- }, /* @__PURE__ */ React42.createElement(Dialog2.Portal, null, /* @__PURE__ */ React42.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog2.Content, {
3638
+ }, /* @__PURE__ */ React44.createElement(Dialog2.Portal, null, /* @__PURE__ */ React44.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React44.createElement(Dialog2.Content, {
3485
3639
  "aria-labelledby": titleId
3486
- }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(SpacePanel, {
3640
+ }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(SpacePanel, {
3487
3641
  ...spacePanelProps,
3488
3642
  titleId,
3489
- doneActionParent: /* @__PURE__ */ React42.createElement(Dialog2.Close, {
3643
+ doneActionParent: /* @__PURE__ */ React44.createElement(Dialog2.Close, {
3490
3644
  asChild: true
3491
3645
  })
3492
3646
  }))))));
@@ -3495,7 +3649,7 @@ var SpaceDialog = (spacePanelProps) => {
3495
3649
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3496
3650
  var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3497
3651
  var Shell = ({ runtime, origin }) => {
3498
- const [{ layout, invitationCode, spaceKey, target }, setLayout] = useState10({
3652
+ const [{ layout, invitationCode, spaceKey, target }, setLayout] = useState11({
3499
3653
  layout: runtime.layout,
3500
3654
  invitationCode: runtime.invitationCode,
3501
3655
  spaceKey: runtime.spaceKey,
@@ -3533,7 +3687,7 @@ var Shell = ({ runtime, origin }) => {
3533
3687
  ]);
3534
3688
  switch (layout) {
3535
3689
  case ShellLayout.INITIALIZE_IDENTITY:
3536
- return /* @__PURE__ */ React43.createElement(JoinDialog, {
3690
+ return /* @__PURE__ */ React45.createElement(JoinDialog, {
3537
3691
  mode: "halo-only",
3538
3692
  initialInvitationCode: invitationCode,
3539
3693
  onDone: () => {
@@ -3548,7 +3702,7 @@ var Shell = ({ runtime, origin }) => {
3548
3702
  case ShellLayout.IDENTITY:
3549
3703
  case ShellLayout.SHARE_IDENTITY:
3550
3704
  case ShellLayout.EDIT_PROFILE:
3551
- return /* @__PURE__ */ React43.createElement(IdentityDialog, {
3705
+ return /* @__PURE__ */ React45.createElement(IdentityDialog, {
3552
3706
  createInvitationUrl: (invitationCode2) => `${origin}?deviceInvitationCode=${invitationCode2}`,
3553
3707
  onResetDevice: async () => {
3554
3708
  await client.reset();
@@ -3570,7 +3724,7 @@ var Shell = ({ runtime, origin }) => {
3570
3724
  }
3571
3725
  });
3572
3726
  case ShellLayout.SPACE:
3573
- return space ? /* @__PURE__ */ React43.createElement(SpaceDialog, {
3727
+ return space ? /* @__PURE__ */ React45.createElement(SpaceDialog, {
3574
3728
  space,
3575
3729
  target,
3576
3730
  createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
@@ -3584,7 +3738,7 @@ var Shell = ({ runtime, origin }) => {
3584
3738
  }
3585
3739
  }) : null;
3586
3740
  case ShellLayout.JOIN_SPACE:
3587
- return /* @__PURE__ */ React43.createElement(JoinDialog, {
3741
+ return /* @__PURE__ */ React45.createElement(JoinDialog, {
3588
3742
  initialInvitationCode: invitationCode,
3589
3743
  onDone: async (result) => {
3590
3744
  const target2 = result?.target ?? void 0;
@@ -3718,7 +3872,28 @@ var os = {
3718
3872
  "sign out chooser message": "Proceeding with either action below will erase all data on this device.",
3719
3873
  "join new identity label": "Join a new identity",
3720
3874
  "reset device label": "Reset device",
3721
- "reset device confirm message": "Are you sure you want to reset your device? All data will be lost."
3875
+ "reset device confirm message": "Are you sure you want to reset your device? All data will be lost.",
3876
+ "emoji and color label": "Emoji and color",
3877
+ "clear label": "Use default",
3878
+ "select emoji label": "Choose an emoji to use in your avatar",
3879
+ "select hue label": "Choose a hue to use in your avatar",
3880
+ "red label": "Red",
3881
+ "orange label": "Orange",
3882
+ "amber label": "Amber",
3883
+ "yellow label": "Yellow",
3884
+ "lime label": "Lime",
3885
+ "green label": "Green",
3886
+ "emerald label": "Emerald",
3887
+ "teal label": "Teal",
3888
+ "cyan label": "Cyan",
3889
+ "sky label": "Sky",
3890
+ "blue label": "Blue",
3891
+ "indigo label": "Indigo",
3892
+ "violet label": "Violet",
3893
+ "purple label": "Purple",
3894
+ "fuchsia label": "Fuchsia",
3895
+ "pink label": "Pink",
3896
+ "rose label": "Rose"
3722
3897
  };
3723
3898
 
3724
3899
  // packages/sdk/shell/src/translations/index.ts
@@ -3742,24 +3917,24 @@ var runShell = async (config = new Config()) => {
3742
3917
  runtime.open(),
3743
3918
  client.initialize()
3744
3919
  ]);
3745
- createRoot(document.getElementById("root")).render(/* @__PURE__ */ React44.createElement(StrictMode, null, /* @__PURE__ */ React44.createElement(ThemeProvider, {
3920
+ createRoot(document.getElementById("root")).render(/* @__PURE__ */ React46.createElement(StrictMode, null, /* @__PURE__ */ React46.createElement(ThemeProvider, {
3746
3921
  tx: defaultTx,
3747
3922
  resourceExtensions: [
3748
3923
  osTranslations
3749
3924
  ]
3750
- }, /* @__PURE__ */ React44.createElement(ClientContext.Provider, {
3925
+ }, /* @__PURE__ */ React46.createElement(ClientContext.Provider, {
3751
3926
  value: {
3752
3927
  client,
3753
3928
  status: SystemStatus.ACTIVE
3754
3929
  }
3755
- }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React44.createElement(Shell, {
3930
+ }, /* @__PURE__ */ React46.createElement(ClipboardProvider, null, /* @__PURE__ */ React46.createElement(Tooltip5.Provider, null, /* @__PURE__ */ React46.createElement(Shell, {
3756
3931
  runtime,
3757
3932
  origin: location.origin
3758
3933
  })))))));
3759
3934
  };
3760
3935
 
3761
3936
  // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3762
- import React45, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState11 } from "react";
3937
+ import React47, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState12 } from "react";
3763
3938
  import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient8 } from "@dxos/react-client";
3764
3939
  import { useIdentity as useIdentity3 } from "@dxos/react-client/halo";
3765
3940
  import { mx as mx23 } from "@dxos/react-ui-theme";
@@ -3821,7 +3996,7 @@ var useShell = () => {
3821
3996
  var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoinedSpace, children }) => {
3822
3997
  const client = useClient8();
3823
3998
  const identity = useIdentity3();
3824
- const [display, setDisplay] = useState11(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3999
+ const [display, setDisplay] = useState12(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3825
4000
  const shellRuntime = useMemo6(() => {
3826
4001
  if (client.config.get("runtime.app.env.DX_VAULT") !== "false") {
3827
4002
  return;
@@ -3891,12 +4066,12 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3891
4066
  }, [
3892
4067
  shellRuntime
3893
4068
  ]);
3894
- return /* @__PURE__ */ React45.createElement(React45.Fragment, null, shellRuntime && /* @__PURE__ */ React45.createElement("div", {
4069
+ return /* @__PURE__ */ React47.createElement(React47.Fragment, null, shellRuntime && /* @__PURE__ */ React47.createElement("div", {
3895
4070
  className: mx23(display === ShellDisplay2.NONE ? "hidden" : "")
3896
- }, /* @__PURE__ */ React45.createElement(Shell, {
4071
+ }, /* @__PURE__ */ React47.createElement(Shell, {
3897
4072
  runtime: shellRuntime,
3898
4073
  origin: window.location.origin
3899
- })), /* @__PURE__ */ React45.createElement(ShellContext.Provider, {
4074
+ })), /* @__PURE__ */ React47.createElement(ShellContext.Provider, {
3900
4075
  value: {
3901
4076
  runtime: shellRuntime,
3902
4077
  setDisplay
@@ -3917,7 +4092,9 @@ export {
3917
4092
  CopyButtonIconOnly,
3918
4093
  DeviceList,
3919
4094
  Emoji,
4095
+ EmojiPicker,
3920
4096
  Heading,
4097
+ HuePicker,
3921
4098
  IdentityDialog,
3922
4099
  IdentityListItem,
3923
4100
  IdentityPanel,