@dxos/shell 0.4.6 → 0.4.7-main.06facb4

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