@dxos/shell 0.4.7-main.e015b9e → 0.4.7-main.ea67fec

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 +63679 -21116
  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 +767 -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 +28 -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?.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?.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?.hue || hexToHue(identity?.identityKey.toHex() ?? "0");
1245
+ var getEmojiValue = (identity) => identity?.profile?.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,20 @@ 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
+ emoji,
1307
+ hue
1203
1308
  }),
1204
1309
  "data-testid": "update-profile-form-continue"
1205
1310
  }, t("done label"))));
@@ -1207,17 +1312,17 @@ var ProfileFormImpl = (props) => {
1207
1312
 
1208
1313
  // packages/sdk/shell/src/panels/IdentityPanel/steps/SignOutChooser.tsx
1209
1314
  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";
1315
+ import React27 from "react";
1316
+ import { Message, useTranslation as useTranslation13 } from "@dxos/react-ui";
1317
+ import { getSize as getSize9, mx as mx18 } from "@dxos/react-ui-theme";
1213
1318
  var SignOutChooser = (props) => {
1214
- const { t } = useTranslation11("os");
1319
+ const { t } = useTranslation13("os");
1215
1320
  const onResetDevice = () => {
1216
1321
  if (window.confirm(t("reset device confirm message"))) {
1217
1322
  void props.onResetDevice?.();
1218
1323
  }
1219
1324
  };
1220
- return /* @__PURE__ */ React25.createElement(SignOutChooserImpl, {
1325
+ return /* @__PURE__ */ React27.createElement(SignOutChooserImpl, {
1221
1326
  disabled: !props.active,
1222
1327
  onBack: () => props.send?.({
1223
1328
  type: "unchooseAction"
@@ -1227,24 +1332,24 @@ var SignOutChooser = (props) => {
1227
1332
  });
1228
1333
  };
1229
1334
  var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }) => {
1230
- const { t } = useTranslation11("os");
1231
- return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement("div", {
1335
+ const { t } = useTranslation13("os");
1336
+ return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement("div", {
1232
1337
  role: "none",
1233
1338
  className: "grow flex flex-col justify-center"
1234
- }, /* @__PURE__ */ React25.createElement(Message.Root, {
1339
+ }, /* @__PURE__ */ React27.createElement(Message.Root, {
1235
1340
  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, {
1341
+ }, /* @__PURE__ */ React27.createElement(Message.Title, null, /* @__PURE__ */ React27.createElement(Warning, {
1342
+ className: mx18(getSize9(6), "inline mie-2")
1343
+ }), 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
1344
  disabled,
1240
1345
  onClick: onBack
1241
- }, t("back label")), /* @__PURE__ */ React25.createElement(Action, {
1346
+ }, t("back label")), /* @__PURE__ */ React27.createElement(Action, {
1242
1347
  variant: "primary",
1243
1348
  "data-testid": "sign-out.join-new-identity",
1244
1349
  classNames: "!bg-error-500 hover:!bg-error-550",
1245
1350
  disabled,
1246
1351
  onClick: onJoinNewIdentity
1247
- }, t("join new identity label")), /* @__PURE__ */ React25.createElement(Action, {
1352
+ }, t("join new identity label")), /* @__PURE__ */ React27.createElement(Action, {
1248
1353
  variant: "primary",
1249
1354
  "data-testid": "sign-out.reset-device",
1250
1355
  classNames: "!bg-error-500 hover:!bg-error-550",
@@ -1254,15 +1359,15 @@ var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }
1254
1359
  };
1255
1360
 
1256
1361
  // packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts
1257
- import { useCallback as useCallback5, useEffect as useEffect2, useState as useState4 } from "react";
1362
+ import { useCallback as useCallback5, useEffect as useEffect2, useState as useState5 } from "react";
1258
1363
  import { invariant } from "@dxos/invariant";
1259
1364
  import { useAgentHostingProviderClient as useAgentHostingProviderClient2 } from "@dxos/react-client";
1260
- import { Invitation as Invitation4, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1365
+ import { Invitation as Invitation3, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1261
1366
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts";
1262
1367
  var useAgentHandlers = ({ client, invitations, identity }) => {
1263
- const [validationMessage, setValidationMessage] = useState4("");
1264
- const [agentStatus, setAgentStatus] = useState4("");
1265
- const [agentActive, setAgentActive] = useState4(false);
1368
+ const [validationMessage, setValidationMessage] = useState5("");
1369
+ const [agentStatus, setAgentStatus] = useState5("");
1370
+ const [agentActive, setAgentActive] = useState5(false);
1266
1371
  const agentHostingProviderClient = useAgentHostingProviderClient2(client.config);
1267
1372
  useEffect2(() => {
1268
1373
  const fetchAgentStatus = async () => {
@@ -1283,7 +1388,7 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1283
1388
  }, []);
1284
1389
  const handleAgentCreate = useCallback5(async (invitation) => {
1285
1390
  const invitationCode = InvitationEncoder2.encode(invitation);
1286
- if (invitation.state === Invitation4.State.CONNECTING) {
1391
+ if (invitation.state === Invitation3.State.CONNECTING) {
1287
1392
  console.log(JSON.stringify({
1288
1393
  invitationCode,
1289
1394
  authCode: invitation.authCode
@@ -1312,8 +1417,8 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1312
1417
  const onAgentCreate = async () => {
1313
1418
  invitations.forEach((invitation2) => invitation2.cancel());
1314
1419
  const invitation = client.halo.share({
1315
- type: Invitation4.Type.MULTIUSE,
1316
- authMethod: Invitation4.AuthMethod.NONE
1420
+ type: Invitation3.Type.MULTIUSE,
1421
+ authMethod: Invitation3.AuthMethod.NONE
1317
1422
  });
1318
1423
  invitation.subscribe(handleAgentCreate);
1319
1424
  };
@@ -1347,24 +1452,68 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1347
1452
  };
1348
1453
 
1349
1454
  // 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";
1455
+ import { Check as Check4, X as X3 } from "@phosphor-icons/react";
1456
+ import React28, { useMemo as useMemo2 } from "react";
1352
1457
  import { QR } from "react-qr-rounded";
1353
1458
  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";
1459
+ import { useId as useId4, useTranslation as useTranslation14 } from "@dxos/react-ui";
1460
+ import { descriptionText as descriptionText7, getSize as getSize10, mx as mx19 } from "@dxos/react-ui-theme";
1461
+ import { hexToEmoji as hexToEmoji3 } from "@dxos/util";
1462
+
1463
+ // packages/sdk/shell/src/util/invitationStatusValue.ts
1464
+ import { Invitation as Invitation4 } from "@dxos/react-client/invitations";
1465
+ var invitationStatusValue = /* @__PURE__ */ new Map([
1466
+ [
1467
+ Invitation4.State.ERROR,
1468
+ -3
1469
+ ],
1470
+ [
1471
+ Invitation4.State.TIMEOUT,
1472
+ -2
1473
+ ],
1474
+ [
1475
+ Invitation4.State.CANCELLED,
1476
+ -1
1477
+ ],
1478
+ [
1479
+ Invitation4.State.INIT,
1480
+ 0
1481
+ ],
1482
+ [
1483
+ Invitation4.State.CONNECTING,
1484
+ 1
1485
+ ],
1486
+ [
1487
+ Invitation4.State.CONNECTED,
1488
+ 2
1489
+ ],
1490
+ [
1491
+ Invitation4.State.READY_FOR_AUTHENTICATION,
1492
+ 3
1493
+ ],
1494
+ [
1495
+ Invitation4.State.AUTHENTICATING,
1496
+ 4
1497
+ ],
1498
+ [
1499
+ Invitation4.State.SUCCESS,
1500
+ 5
1501
+ ]
1502
+ ]);
1503
+
1504
+ // packages/sdk/shell/src/steps/InvitationManager.tsx
1356
1505
  var InvitationManagerView = ({ children, ...props }) => {
1357
- return /* @__PURE__ */ React26.createElement(Viewport.View, {
1506
+ return /* @__PURE__ */ React28.createElement(Viewport.View, {
1358
1507
  ...props,
1359
1508
  classNames: "grow flex flex-col justify-around items-center"
1360
1509
  }, children);
1361
1510
  };
1362
- var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id }) => {
1363
- const { t } = useTranslation12("os");
1511
+ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id = "0" }) => {
1512
+ const { t } = useTranslation14("os");
1364
1513
  const qrLabel = useId4("invitation-manager__qr-code");
1365
1514
  const statusValue = type === Invitation5.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1366
1515
  const showAuthCode = statusValue === 3;
1367
- const emoji2 = toEmoji(id ?? "");
1516
+ const emoji = hexToEmoji3(id);
1368
1517
  const activeView = useMemo2(() => {
1369
1518
  switch (true) {
1370
1519
  case statusValue === 5:
@@ -1378,18 +1527,18 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1378
1527
  }, [
1379
1528
  statusValue
1380
1529
  ]);
1381
- return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(Viewport.Root, {
1530
+ return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(Viewport.Root, {
1382
1531
  activeView,
1383
1532
  classNames: "grow plb-1"
1384
- }, /* @__PURE__ */ React26.createElement(Viewport.Views, null, /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1533
+ }, /* @__PURE__ */ React28.createElement(Viewport.Views, null, /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1385
1534
  id: "showing qr",
1386
- emoji: emoji2
1387
- }, /* @__PURE__ */ React26.createElement("p", {
1535
+ emoji
1536
+ }, /* @__PURE__ */ React28.createElement("p", {
1388
1537
  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", {
1538
+ }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React28.createElement("div", {
1390
1539
  role: "none",
1391
1540
  className: mx19(descriptionText7, "is-full max-is-[14rem] relative")
1392
- }, /* @__PURE__ */ React26.createElement(QR, {
1541
+ }, /* @__PURE__ */ React28.createElement(QR, {
1393
1542
  rounding: 100,
1394
1543
  backgroundColor: "transparent",
1395
1544
  color: "currentColor",
@@ -1397,31 +1546,31 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1397
1546
  "aria-labelledby": qrLabel,
1398
1547
  errorCorrectionLevel: "Q",
1399
1548
  cutout: true
1400
- }, invitationUrl ?? "never"), /* @__PURE__ */ React26.createElement(Centered, null, /* @__PURE__ */ React26.createElement(Emoji, {
1401
- text: emoji2
1402
- }))), /* @__PURE__ */ React26.createElement("span", {
1549
+ }, invitationUrl ?? "never"), /* @__PURE__ */ React28.createElement(Centered, null, /* @__PURE__ */ React28.createElement(Emoji, {
1550
+ text: emoji
1551
+ }))), /* @__PURE__ */ React28.createElement("span", {
1403
1552
  id: qrLabel,
1404
1553
  className: "sr-only"
1405
- }, t("qr label")), /* @__PURE__ */ React26.createElement(CopyButton, {
1554
+ }, t("qr label")), /* @__PURE__ */ React28.createElement(CopyButton, {
1406
1555
  variant: "ghost",
1407
1556
  value: invitationUrl ?? "never"
1408
- })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1557
+ })), /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1409
1558
  id: "showing auth code"
1410
- }, /* @__PURE__ */ React26.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React26.createElement(AuthCode, {
1559
+ }, /* @__PURE__ */ React28.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React28.createElement(AuthCode, {
1411
1560
  code: authCode,
1412
1561
  large: true,
1413
1562
  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, {
1563
+ }), /* @__PURE__ */ React28.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji && /* @__PURE__ */ React28.createElement(Emoji, {
1564
+ text: emoji
1565
+ })), /* @__PURE__ */ React28.createElement(InvitationManagerView, {
1417
1566
  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, {
1567
+ }, statusValue > 0 ? /* @__PURE__ */ React28.createElement(Check4, {
1568
+ className: mx19("m-1.5", getSize10(6))
1569
+ }) : /* @__PURE__ */ React28.createElement(X3, {
1570
+ className: mx19("m-1.5", getSize10(6))
1571
+ })))), /* @__PURE__ */ React28.createElement(Actions, {
1423
1572
  classNames: "mbs-4"
1424
- }, /* @__PURE__ */ React26.createElement(Action, {
1573
+ }, /* @__PURE__ */ React28.createElement(Action, {
1425
1574
  disabled: !active,
1426
1575
  onClick: () => send?.({
1427
1576
  type: "deselectInvitation"
@@ -1433,29 +1582,30 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1433
1582
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1434
1583
  var viewStyles = "pbs-1 pbe-3 pli-3";
1435
1584
  var IdentityHeading = ({ titleId, title, identity, onDone }) => {
1436
- const fallbackHref = useJdenticonHref3(identity.identityKey.toHex(), 12);
1437
- return /* @__PURE__ */ React27.createElement(Heading, {
1585
+ const fallbackValue = keyToFallback2(identity.identityKey);
1586
+ return /* @__PURE__ */ React29.createElement(Heading, {
1438
1587
  titleId,
1439
1588
  title,
1440
- corner: /* @__PURE__ */ React27.createElement(CloseButton, {
1589
+ corner: /* @__PURE__ */ React29.createElement(CloseButton, {
1441
1590
  onDone
1442
1591
  })
1443
- }, /* @__PURE__ */ React27.createElement(Avatar4.Root, {
1592
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Root, {
1444
1593
  size: 12,
1445
1594
  variant: "circle",
1446
- status: "active"
1447
- }, /* @__PURE__ */ React27.createElement(Avatar4.Frame, {
1595
+ status: "active",
1596
+ hue: identity.profile?.hue || fallbackValue.hue
1597
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Frame, {
1448
1598
  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, {
1599
+ }, /* @__PURE__ */ React29.createElement(Avatar4.Fallback, {
1600
+ text: identity.profile?.emoji || fallbackValue.emoji
1601
+ })), /* @__PURE__ */ React29.createElement(Avatar4.Label, {
1452
1602
  classNames: "block text-center font-light text-xl",
1453
1603
  "data-testid": "identityHeading.displayName"
1454
1604
  }, identity.profile?.displayName ?? generateName3(identity.identityKey.toHex()))));
1455
1605
  };
1456
1606
  var IdentityPanelImpl = (props) => {
1457
1607
  const { identity, titleId, activeView, onUpdateProfile, onResetDevice, onJoinNewIdentity, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1458
- const { t } = useTranslation13("os");
1608
+ const { t } = useTranslation15("os");
1459
1609
  const title = useMemo3(() => {
1460
1610
  switch (activeView) {
1461
1611
  case "agent manager":
@@ -1469,54 +1619,54 @@ var IdentityPanelImpl = (props) => {
1469
1619
  activeView,
1470
1620
  t
1471
1621
  ]);
1472
- return /* @__PURE__ */ React27.createElement(DensityProvider2, {
1622
+ return /* @__PURE__ */ React29.createElement(DensityProvider2, {
1473
1623
  density: "fine"
1474
- }, /* @__PURE__ */ React27.createElement(IdentityHeading, {
1624
+ }, /* @__PURE__ */ React29.createElement(IdentityHeading, {
1475
1625
  identity,
1476
1626
  titleId,
1477
1627
  title,
1478
1628
  onDone
1479
- }), /* @__PURE__ */ React27.createElement(Viewport.Root, {
1629
+ }), /* @__PURE__ */ React29.createElement(Viewport.Root, {
1480
1630
  activeView
1481
- }, /* @__PURE__ */ React27.createElement(Viewport.Views, null, /* @__PURE__ */ React27.createElement(Viewport.View, {
1631
+ }, /* @__PURE__ */ React29.createElement(Viewport.Views, null, /* @__PURE__ */ React29.createElement(Viewport.View, {
1482
1632
  id: "identity action chooser",
1483
1633
  classNames: viewStyles
1484
- }, /* @__PURE__ */ React27.createElement(IdentityActionChooserComponent, {
1634
+ }, /* @__PURE__ */ React29.createElement(IdentityActionChooserComponent, {
1485
1635
  active: activeView === "identity action chooser",
1486
1636
  ...rest
1487
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1637
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1488
1638
  id: "device invitation manager",
1489
1639
  classNames: viewStyles
1490
- }, /* @__PURE__ */ React27.createElement(InvitationManagerComponent, {
1640
+ }, /* @__PURE__ */ React29.createElement(InvitationManagerComponent, {
1491
1641
  active: activeView === "device invitation manager",
1492
1642
  ...rest,
1493
1643
  invitationUrl: rest.createInvitationUrl(rest.invitationCode)
1494
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1644
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1495
1645
  id: "device manager",
1496
1646
  classNames: viewStyles
1497
- }, /* @__PURE__ */ React27.createElement(DeviceManager, {
1647
+ }, /* @__PURE__ */ React29.createElement(DeviceManager, {
1498
1648
  active: activeView === "device manager",
1499
1649
  ...rest
1500
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1650
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1501
1651
  classNames: viewStyles,
1502
1652
  id: "update profile form"
1503
- }, /* @__PURE__ */ React27.createElement(ProfileForm, {
1653
+ }, /* @__PURE__ */ React29.createElement(ProfileForm, {
1504
1654
  send: rest.send,
1505
1655
  active: activeView === "update profile form",
1506
1656
  identity,
1507
1657
  onUpdateProfile
1508
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1658
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1509
1659
  classNames: viewStyles,
1510
1660
  id: "signing out"
1511
- }, /* @__PURE__ */ React27.createElement(SignOutChooser, {
1661
+ }, /* @__PURE__ */ React29.createElement(SignOutChooser, {
1512
1662
  send: rest.send,
1513
1663
  active: activeView === "signing out",
1514
1664
  onResetDevice,
1515
1665
  onJoinNewIdentity
1516
- })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1666
+ })), /* @__PURE__ */ React29.createElement(Viewport.View, {
1517
1667
  classNames: viewStyles,
1518
1668
  id: "agent manager"
1519
- }, /* @__PURE__ */ React27.createElement(AgentForm, {
1669
+ }, /* @__PURE__ */ React29.createElement(AgentForm, {
1520
1670
  send: rest.send,
1521
1671
  active: activeView === "agent manager",
1522
1672
  ...rest
@@ -1524,7 +1674,7 @@ var IdentityPanelImpl = (props) => {
1524
1674
  };
1525
1675
  var IdentityPanelWithInvitationImpl = ({ invitation, ...props }) => {
1526
1676
  const invitationStatus = useInvitationStatus2(invitation);
1527
- return /* @__PURE__ */ React27.createElement(IdentityPanelImpl, {
1677
+ return /* @__PURE__ */ React29.createElement(IdentityPanelImpl, {
1528
1678
  ...props,
1529
1679
  ...invitationStatus
1530
1680
  });
@@ -1549,7 +1699,7 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1549
1699
  const subscription = identityService.subscribe((state) => {
1550
1700
  log3("[state]", state, {
1551
1701
  F: __dxlog_file4,
1552
- L: 138,
1702
+ L: 139,
1553
1703
  S: void 0,
1554
1704
  C: (f, a) => f(...a)
1555
1705
  });
@@ -1609,40 +1759,40 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1609
1759
  onUpdateProfile,
1610
1760
  ...agentProps
1611
1761
  };
1612
- return identityState.context.invitation ? /* @__PURE__ */ React27.createElement(IdentityPanelWithInvitationImpl, {
1762
+ return identityState.context.invitation ? /* @__PURE__ */ React29.createElement(IdentityPanelWithInvitationImpl, {
1613
1763
  ...implProps,
1614
1764
  invitation: identityState.context.invitation
1615
- }) : /* @__PURE__ */ React27.createElement(IdentityPanelImpl, implProps);
1765
+ }) : /* @__PURE__ */ React29.createElement(IdentityPanelImpl, implProps);
1616
1766
  };
1617
1767
 
1618
1768
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
1619
- import React37, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1769
+ import React39, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1620
1770
  import { log as log8 } from "@dxos/log";
1621
1771
  import { useClient as useClient6, useMulticastObservable } from "@dxos/react-client";
1622
1772
  import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
1623
- import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext as useThemeContext3 } from "@dxos/react-ui";
1773
+ import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext as useThemeContext4 } from "@dxos/react-ui";
1624
1774
 
1625
1775
  // packages/sdk/shell/src/panels/JoinPanel/JoinHeading.tsx
1626
1776
  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";
1777
+ import React30, { cloneElement, forwardRef as forwardRef8 } from "react";
1778
+ import { Button as Button7, useTranslation as useTranslation16 } from "@dxos/react-ui";
1779
+ import { descriptionText as descriptionText8, getSize as getSize11, mx as mx20 } from "@dxos/react-ui-theme";
1630
1780
  var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActionParent }, forwardedRef) => {
1631
- const { t } = useTranslation14("os");
1632
- const exitButton = /* @__PURE__ */ React28.createElement(Button5, {
1781
+ const { t } = useTranslation16("os");
1782
+ const exitButton = /* @__PURE__ */ React30.createElement(Button7, {
1633
1783
  variant: "ghost",
1634
1784
  ...onExit && {
1635
1785
  onClick: onExit
1636
1786
  },
1637
1787
  classNames: mx20(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1638
1788
  "data-testid": "join-exit"
1639
- }, /* @__PURE__ */ React28.createElement(X4, {
1789
+ }, /* @__PURE__ */ React30.createElement(X4, {
1640
1790
  weight: "bold",
1641
- className: getSize9(4)
1642
- }), /* @__PURE__ */ React28.createElement("span", {
1791
+ className: getSize11(4)
1792
+ }), /* @__PURE__ */ React30.createElement("span", {
1643
1793
  className: "sr-only"
1644
1794
  }, t("exit label")));
1645
- return /* @__PURE__ */ React28.createElement(Heading, {
1795
+ return /* @__PURE__ */ React30.createElement(Heading, {
1646
1796
  ref: forwardedRef,
1647
1797
  titleId,
1648
1798
  title: t(mode === "halo-only" ? "selecting identity heading" : "joining space heading"),
@@ -2245,17 +2395,17 @@ var useJoinMachine = (client, options) => {
2245
2395
 
2246
2396
  // packages/sdk/shell/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx
2247
2397
  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";
2398
+ import React31 from "react";
2399
+ import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2400
+ import { getSize as getSize12 } from "@dxos/react-ui-theme";
2251
2401
  var AdditionMethodChooser = (viewStateProps) => {
2252
2402
  const disabled = !viewStateProps.active;
2253
2403
  const { send } = viewStateProps;
2254
- const { t } = useTranslation15("os");
2404
+ const { t } = useTranslation17("os");
2255
2405
  const sharedButtonProps = {
2256
2406
  disabled,
2257
- after: /* @__PURE__ */ React29.createElement(CaretRight2, {
2258
- className: getSize10(4),
2407
+ after: /* @__PURE__ */ React31.createElement(CaretRight2, {
2408
+ className: getSize12(4),
2259
2409
  weight: "bold"
2260
2410
  }),
2261
2411
  slots: {
@@ -2264,37 +2414,37 @@ var AdditionMethodChooser = (viewStateProps) => {
2264
2414
  }
2265
2415
  }
2266
2416
  };
2267
- return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React29.createElement("div", {
2417
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React31.createElement("div", {
2268
2418
  role: "none",
2269
2419
  className: "flex flex-col gap-1 grow"
2270
- }, /* @__PURE__ */ React29.createElement(CompoundButton, {
2420
+ }, /* @__PURE__ */ React31.createElement(CompoundButton, {
2271
2421
  ...sharedButtonProps,
2272
2422
  description: t("create identity description"),
2273
- before: /* @__PURE__ */ React29.createElement(Plus2, {
2274
- className: getSize10(6)
2423
+ before: /* @__PURE__ */ React31.createElement(Plus2, {
2424
+ className: getSize12(6)
2275
2425
  }),
2276
2426
  onClick: () => send({
2277
2427
  type: "createIdentity"
2278
2428
  }),
2279
2429
  "data-autofocus": "choosingAuthMethod",
2280
2430
  "data-testid": "identity-chooser.create-identity"
2281
- }, t("create identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2431
+ }, t("create identity label")), /* @__PURE__ */ React31.createElement(CompoundButton, {
2282
2432
  ...sharedButtonProps,
2283
2433
  description: t("join identity description"),
2284
- before: /* @__PURE__ */ React29.createElement(QrCode, {
2285
- className: getSize10(6)
2434
+ before: /* @__PURE__ */ React31.createElement(QrCode, {
2435
+ className: getSize12(6)
2286
2436
  }),
2287
2437
  onClick: () => send({
2288
2438
  type: "acceptHaloInvitation"
2289
2439
  }),
2290
2440
  "data-testid": "identity-chooser.join-identity"
2291
- }, t("join identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2441
+ }, t("join identity label")), /* @__PURE__ */ React31.createElement(CompoundButton, {
2292
2442
  ...sharedButtonProps,
2293
2443
  // TODO(mykola): Implement recover.
2294
2444
  disabled: true,
2295
2445
  description: t("recover identity description"),
2296
- before: /* @__PURE__ */ React29.createElement(Textbox, {
2297
- className: getSize10(6)
2446
+ before: /* @__PURE__ */ React31.createElement(Textbox, {
2447
+ className: getSize12(6)
2298
2448
  }),
2299
2449
  onClick: () => send({
2300
2450
  type: "recoverIdentity"
@@ -2304,37 +2454,39 @@ var AdditionMethodChooser = (viewStateProps) => {
2304
2454
  };
2305
2455
 
2306
2456
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityAdded.tsx
2307
- import React30, { cloneElement as cloneElement2 } from "react";
2457
+ import React32, { cloneElement as cloneElement2 } from "react";
2308
2458
  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";
2459
+ import { Avatar as Avatar5, useId as useId6, useTranslation as useTranslation18 } from "@dxos/react-ui";
2310
2460
  import { mx as mx21 } from "@dxos/react-ui-theme";
2461
+ import { hexToFallback } from "@dxos/util";
2311
2462
  var IdentityAdded = (props) => {
2312
2463
  const { mode, addedIdentity, active, send, onDone, doneActionParent } = props;
2313
2464
  const disabled = !active;
2314
- const { t } = useTranslation16("os");
2315
- const fallbackValue = addedIdentity?.identityKey.toHex();
2465
+ const { t } = useTranslation18("os");
2466
+ const addedIdentityHex = addedIdentity?.identityKey.toHex() ?? "0";
2467
+ const fallbackValue = hexToFallback(addedIdentityHex);
2316
2468
  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, {
2469
+ const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName4(addedIdentityHex));
2470
+ const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2320
2471
  ...onDone && {
2321
2472
  onClick: () => onDone(null)
2322
2473
  },
2323
2474
  disabled,
2324
2475
  "data-autofocus": "confirmingAddedIdentity",
2325
2476
  "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", {
2477
+ }, /* @__PURE__ */ React32.createElement("span", null, t("done label")));
2478
+ return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React32.createElement("div", {
2328
2479
  role: "none",
2329
2480
  className: "grow flex flex-col items-center justify-center text-center gap-2"
2330
- }, /* @__PURE__ */ React30.createElement(Avatar5.Root, {
2481
+ }, /* @__PURE__ */ React32.createElement(Avatar5.Root, {
2331
2482
  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, {
2483
+ labelId,
2484
+ hue: addedIdentity?.profile?.hue || fallbackValue.hue
2485
+ }, /* @__PURE__ */ React32.createElement(Avatar5.Frame, null, /* @__PURE__ */ React32.createElement(Avatar5.Fallback, {
2486
+ text: addedIdentity?.profile?.emoji || fallbackValue.emoji
2487
+ })), /* @__PURE__ */ React32.createElement(Avatar5.Label, {
2336
2488
  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, {
2489
+ }, displayName))), /* @__PURE__ */ React32.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React32.createElement(Action, {
2338
2490
  variant: "primary",
2339
2491
  disabled: disabled || !addedIdentity,
2340
2492
  onClick: () => addedIdentity && send({
@@ -2346,17 +2498,17 @@ var IdentityAdded = (props) => {
2346
2498
  };
2347
2499
 
2348
2500
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx
2349
- import React31, { useState as useState5 } from "react";
2501
+ import React33, { useState as useState6 } from "react";
2350
2502
  import { log as log5 } from "@dxos/log";
2351
2503
  import { useClient as useClient4 } from "@dxos/react-client";
2352
- import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2504
+ import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2353
2505
  var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2354
2506
  var IdentityInput = (props) => {
2355
2507
  const { send, method } = props;
2356
2508
  const isRecover = method === "recover identity";
2357
2509
  const client = useClient4();
2358
- const { t } = useTranslation17("os");
2359
- const [validationMessage, setValidationMessage] = useState5("");
2510
+ const { t } = useTranslation19("os");
2511
+ const [validationMessage, setValidationMessage] = useState6("");
2360
2512
  const createIdentity = (displayName) => {
2361
2513
  void client.halo.createIdentity({
2362
2514
  [isRecover ? "seedphrase" : "displayName"]: displayName
@@ -2375,7 +2527,7 @@ var IdentityInput = (props) => {
2375
2527
  setValidationMessage(t(isRecover ? "failed to recover identity message" : "failed to create identity message"));
2376
2528
  });
2377
2529
  };
2378
- return /* @__PURE__ */ React31.createElement(IdentityInputImpl, {
2530
+ return /* @__PURE__ */ React33.createElement(IdentityInputImpl, {
2379
2531
  ...props,
2380
2532
  onDisplayNameConfirm: createIdentity,
2381
2533
  validationMessage
@@ -2384,27 +2536,27 @@ var IdentityInput = (props) => {
2384
2536
  var IdentityInputImpl = (props) => {
2385
2537
  const { method, send, active, onDisplayNameConfirm, validationMessage } = props;
2386
2538
  const disabled = !active;
2387
- const { t } = useTranslation17("os");
2388
- const [inputValue, setInputValue] = useState5("");
2539
+ const { t } = useTranslation19("os");
2540
+ const [inputValue, setInputValue] = useState6("");
2389
2541
  const isRecover = method === "recover identity";
2390
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2542
+ return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2391
2543
  role: "none",
2392
2544
  className: "grow flex flex-col justify-center"
2393
- }, /* @__PURE__ */ React31.createElement(Input, {
2545
+ }, /* @__PURE__ */ React33.createElement(Input, {
2394
2546
  validationMessage,
2395
- label: /* @__PURE__ */ React31.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2547
+ label: /* @__PURE__ */ React33.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2396
2548
  disabled,
2397
2549
  "data-testid": "identity-input",
2398
2550
  placeholder: isRecover ? "Type your recovery phrase" : "Type a display name",
2399
2551
  onChange: ({ target: { value } }) => setInputValue(value)
2400
- })), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2552
+ })), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2401
2553
  variant: "ghost",
2402
2554
  disabled,
2403
2555
  onClick: () => send?.({
2404
2556
  type: "deselectAuthMethod"
2405
2557
  }),
2406
2558
  "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-back`
2407
- }, t("back label")), /* @__PURE__ */ React31.createElement(Action, {
2559
+ }, t("back label")), /* @__PURE__ */ React33.createElement(Action, {
2408
2560
  variant: "primary",
2409
2561
  disabled,
2410
2562
  onClick: () => onDisplayNameConfirm?.(inputValue),
@@ -2413,31 +2565,31 @@ var IdentityInputImpl = (props) => {
2413
2565
  };
2414
2566
 
2415
2567
  // 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";
2568
+ import React34, { cloneElement as cloneElement3 } from "react";
2569
+ import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2418
2570
  var InvitationAccepted = (props) => {
2419
2571
  const { active, Kind, doneActionParent, onDone } = props;
2420
2572
  const disabled = !active;
2421
- const { t } = useTranslation18("os");
2422
- const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2573
+ const { t } = useTranslation20("os");
2574
+ const doneAction = /* @__PURE__ */ React34.createElement(Action, {
2423
2575
  variant: "primary",
2424
2576
  onClick: onDone,
2425
2577
  disabled,
2426
2578
  "data-autofocus": `success${Kind}Invitation finishingJoining${Kind}`,
2427
2579
  "data-testid": `${Kind.toLowerCase()}-invitation-accepted-done`
2428
2580
  }, t("done label"));
2429
- return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2581
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2430
2582
  role: "none",
2431
2583
  className: "grow flex flex-col justify-center"
2432
- }, /* @__PURE__ */ React32.createElement("p", {
2584
+ }, /* @__PURE__ */ React34.createElement("p", {
2433
2585
  className: "text-center text-sm font-normal"
2434
- }, t("welcome message"))), /* @__PURE__ */ React32.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2586
+ }, t("welcome message"))), /* @__PURE__ */ React34.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2435
2587
  };
2436
2588
 
2437
2589
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx
2438
- import React33, { useState as useState6, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2590
+ import React35, { useState as useState7, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2439
2591
  import { log as log6 } from "@dxos/log";
2440
- import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2592
+ import { useTranslation as useTranslation21 } from "@dxos/react-ui";
2441
2593
  var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2442
2594
  var invitationCodeFromUrl = (text) => {
2443
2595
  try {
@@ -2457,8 +2609,8 @@ var invitationCodeFromUrl = (text) => {
2457
2609
  var InvitationInput = (props) => {
2458
2610
  const { Kind, active, send, unredeemedCode, onExit, exitActionParent, onDone, doneActionParent, succeededKeys } = props;
2459
2611
  const disabled = !active;
2460
- const { t } = useTranslation19("os");
2461
- const [inputValue, setInputValue] = useState6(unredeemedCode ?? "");
2612
+ const { t } = useTranslation21("os");
2613
+ const [inputValue, setInputValue] = useState7(unredeemedCode ?? "");
2462
2614
  useEffect4(() => {
2463
2615
  unredeemedCode && setInputValue(unredeemedCode ?? "");
2464
2616
  }, [
@@ -2476,7 +2628,7 @@ var InvitationInput = (props) => {
2476
2628
  }
2477
2629
  });
2478
2630
  };
2479
- const exitAction = /* @__PURE__ */ React33.createElement(Action, {
2631
+ const exitAction = /* @__PURE__ */ React35.createElement(Action, {
2480
2632
  variant: "ghost",
2481
2633
  disabled,
2482
2634
  ...onExit ? {
@@ -2486,11 +2638,11 @@ var InvitationInput = (props) => {
2486
2638
  },
2487
2639
  "data-testid": "join-exit"
2488
2640
  }, t("cancel label"));
2489
- return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2641
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2490
2642
  role: "none",
2491
2643
  className: "grow flex flex-col justify-center"
2492
- }, /* @__PURE__ */ React33.createElement(Input, {
2493
- label: /* @__PURE__ */ React33.createElement(StepHeading, null, t("invitation input label")),
2644
+ }, /* @__PURE__ */ React35.createElement(Input, {
2645
+ label: /* @__PURE__ */ React35.createElement(StepHeading, null, t("invitation input label")),
2494
2646
  // TODO(burdon): Translation.
2495
2647
  placeholder: "Type an invitation code",
2496
2648
  disabled,
@@ -2499,14 +2651,14 @@ var InvitationInput = (props) => {
2499
2651
  "data-autofocus": `inputting${Kind}InvitationCode`,
2500
2652
  "data-testid": `${Kind.toLowerCase()}-invitation-input`,
2501
2653
  onKeyUp: ({ key }) => key === "Enter" && handleNext()
2502
- })), /* @__PURE__ */ React33.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React33.createElement(Action, {
2654
+ })), /* @__PURE__ */ React35.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React35.createElement(Action, {
2503
2655
  variant: "ghost",
2504
2656
  disabled,
2505
2657
  onClick: () => send({
2506
2658
  type: "deselectAuthMethod"
2507
2659
  }),
2508
2660
  "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, {
2661
+ }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React35.createElement(Action, {
2510
2662
  variant: "primary",
2511
2663
  disabled,
2512
2664
  onClick: handleNext,
@@ -2515,8 +2667,8 @@ var InvitationInput = (props) => {
2515
2667
  };
2516
2668
 
2517
2669
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationRescuer.tsx
2518
- import React34 from "react";
2519
- import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2670
+ import React36 from "react";
2671
+ import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2520
2672
  import { descriptionText as descriptionText9 } from "@dxos/react-ui-theme";
2521
2673
  var InvitationActions = ({
2522
2674
  // `invitationState` does report correct state, but here we evaluate whether `failReason` is a better source of truth
@@ -2528,14 +2680,14 @@ var InvitationActions = ({
2528
2680
  Kind,
2529
2681
  failReason
2530
2682
  }) => {
2531
- const { t } = useTranslation20("os");
2683
+ const { t } = useTranslation22("os");
2532
2684
  if (failReason) {
2533
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2685
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(StepHeading, {
2534
2686
  className: descriptionText9
2535
- }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React34.createElement("div", {
2687
+ }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React36.createElement("div", {
2536
2688
  role: "none",
2537
2689
  className: "grow"
2538
- }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2690
+ }), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2539
2691
  disabled: !active,
2540
2692
  onClick: () => send({
2541
2693
  type: `reset${Kind}Invitation`
@@ -2543,16 +2695,16 @@ var InvitationActions = ({
2543
2695
  "data-testid": "invitation-rescuer-reset"
2544
2696
  }, t("reset label"))));
2545
2697
  } else {
2546
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2698
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(StepHeading, {
2547
2699
  className: descriptionText9
2548
- }, t("connecting status label")), /* @__PURE__ */ React34.createElement("div", {
2700
+ }, t("connecting status label")), /* @__PURE__ */ React36.createElement("div", {
2549
2701
  role: "none",
2550
2702
  className: "grow"
2551
- }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2703
+ }), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2552
2704
  disabled: true,
2553
2705
  classNames: "order-2",
2554
2706
  "data-testid": "next"
2555
- }, t("next label")), /* @__PURE__ */ React34.createElement(Action, {
2707
+ }, t("next label")), /* @__PURE__ */ React36.createElement(Action, {
2556
2708
  disabled: !active,
2557
2709
  onClick: onInvitationCancel,
2558
2710
  "data-testid": "invitation-rescuer-cancel"
@@ -2561,46 +2713,47 @@ var InvitationActions = ({
2561
2713
  };
2562
2714
  var InvitationRescuer = (props) => {
2563
2715
  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", {
2716
+ const { t } = useTranslation22("os");
2717
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2566
2718
  role: "none",
2567
2719
  className: "grow flex flex-col justify-center"
2568
- }, /* @__PURE__ */ React34.createElement(StepHeading, {
2720
+ }, /* @__PURE__ */ React36.createElement(StepHeading, {
2569
2721
  className: descriptionText9
2570
- }, "There was a problem joining the space")), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2722
+ }, "There was a problem joining the space")), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2571
2723
  disabled: !active,
2572
2724
  "data-testid": "invitation-rescuer-blank-reset",
2573
2725
  onClick: () => send({
2574
2726
  type: `reset${Kind}Invitation`
2575
2727
  })
2576
- }, t("reset label")))) : /* @__PURE__ */ React34.createElement(InvitationActions, props));
2728
+ }, t("reset label")))) : /* @__PURE__ */ React36.createElement(InvitationActions, props));
2577
2729
  };
2578
2730
 
2579
2731
  // 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";
2732
+ import React37, { useState as useState8 } from "react";
2733
+ import { Input as Input2, useTranslation as useTranslation23 } from "@dxos/react-ui";
2734
+ import { hexToEmoji as hexToEmoji4 } from "@dxos/util";
2582
2735
  var pinLength = 6;
2583
2736
  var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, onInvitationAuthenticate, onInvitationCancel }) => {
2584
2737
  const disabled = !active || pending;
2585
- const { t } = useTranslation21("os");
2738
+ const { t } = useTranslation23("os");
2586
2739
  const invitationType = Kind.toLowerCase();
2587
- const [authCode, setAuthCode] = useState7("");
2740
+ const [authCode, setAuthCode] = useState8("");
2588
2741
  const onChange = ({ target: { value } }) => {
2589
2742
  setAuthCode(value);
2590
2743
  if (value.length === pinLength) {
2591
2744
  document.querySelector(`[data-autofocus-pinlength="${invitationType}"]`)?.focus();
2592
2745
  }
2593
2746
  };
2594
- return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2747
+ return /* @__PURE__ */ React37.createElement(React37.Fragment, null, /* @__PURE__ */ React37.createElement("div", {
2595
2748
  role: "none",
2596
2749
  className: "grow flex flex-col justify-center"
2597
- }, invitationId && /* @__PURE__ */ React35.createElement(Emoji, {
2598
- text: toEmoji(invitationId)
2599
- }), /* @__PURE__ */ React35.createElement(Input2.Root, failed && {
2750
+ }, invitationId && /* @__PURE__ */ React37.createElement(Emoji, {
2751
+ text: hexToEmoji4(invitationId)
2752
+ }), /* @__PURE__ */ React37.createElement(Input2.Root, failed && {
2600
2753
  validationValence: "error"
2601
- }, /* @__PURE__ */ React35.createElement(Input2.Label, {
2754
+ }, /* @__PURE__ */ React37.createElement(Input2.Label, {
2602
2755
  asChild: true
2603
- }, /* @__PURE__ */ React35.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React35.createElement(Input2.PinInput, {
2756
+ }, /* @__PURE__ */ React37.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React37.createElement(Input2.PinInput, {
2604
2757
  disabled,
2605
2758
  length: pinLength,
2606
2759
  onChange,
@@ -2611,14 +2764,14 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2611
2764
  "data-prevent-ios-autofocus": true,
2612
2765
  "data-testid": `${invitationType}-auth-code-input`,
2613
2766
  "data-1p-ignore": true
2614
- }), failed && /* @__PURE__ */ React35.createElement(Input2.DescriptionAndValidation, {
2767
+ }), failed && /* @__PURE__ */ React37.createElement(Input2.DescriptionAndValidation, {
2615
2768
  classNames: "text-center"
2616
- }, /* @__PURE__ */ React35.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(Action, {
2769
+ }, /* @__PURE__ */ React37.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React37.createElement(Actions, null, /* @__PURE__ */ React37.createElement(Action, {
2617
2770
  variant: "ghost",
2618
2771
  disabled,
2619
2772
  onClick: () => onInvitationCancel?.(),
2620
2773
  "data-testid": `${invitationType}-invitation-authenticator-cancel`
2621
- }, t("cancel label")), /* @__PURE__ */ React35.createElement(Action, {
2774
+ }, t("cancel label")), /* @__PURE__ */ React37.createElement(Action, {
2622
2775
  variant: "primary",
2623
2776
  disabled,
2624
2777
  onClick: () => onInvitationAuthenticate?.(authCode),
@@ -2628,16 +2781,16 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2628
2781
  };
2629
2782
 
2630
2783
  // packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx
2631
- import React36, { useState as useState8 } from "react";
2784
+ import React38, { useState as useState9 } from "react";
2632
2785
  import { log as log7 } from "@dxos/log";
2633
2786
  import { useClient as useClient5 } from "@dxos/react-client";
2634
- import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2787
+ import { useTranslation as useTranslation24 } from "@dxos/react-ui";
2635
2788
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2636
2789
  var ResetIdentity = ({ send, active }) => {
2637
2790
  const client = useClient5();
2638
- const { t } = useTranslation22("os");
2639
- const [validationMessage, setValidationMessage] = useState8("");
2640
- const [pending, setPending] = useState8(false);
2791
+ const { t } = useTranslation24("os");
2792
+ const [validationMessage, setValidationMessage] = useState9("");
2793
+ const [pending, setPending] = useState9(false);
2641
2794
  const resetIdentity = () => {
2642
2795
  setPending(true);
2643
2796
  void client.reset().then(() => send?.({
@@ -2653,7 +2806,7 @@ var ResetIdentity = ({ send, active }) => {
2653
2806
  setPending(false);
2654
2807
  });
2655
2808
  };
2656
- return /* @__PURE__ */ React36.createElement(ResetIdentityImpl, {
2809
+ return /* @__PURE__ */ React38.createElement(ResetIdentityImpl, {
2657
2810
  disabled: !active,
2658
2811
  pending,
2659
2812
  validationMessage,
@@ -2661,22 +2814,22 @@ var ResetIdentity = ({ send, active }) => {
2661
2814
  });
2662
2815
  };
2663
2816
  var ResetIdentityImpl = ({ disabled, pending, validationMessage, onConfirm }) => {
2664
- const { t } = useTranslation22("os");
2817
+ const { t } = useTranslation24("os");
2665
2818
  const confirmationValue = t("confirmation value");
2666
- const [inputValue, setInputValue] = useState8("");
2667
- return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2819
+ const [inputValue, setInputValue] = useState9("");
2820
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("div", {
2668
2821
  role: "none",
2669
2822
  className: "grow flex flex-col justify-center"
2670
- }, /* @__PURE__ */ React36.createElement(Input, {
2823
+ }, /* @__PURE__ */ React38.createElement(Input, {
2671
2824
  validationMessage,
2672
- label: /* @__PURE__ */ React36.createElement(StepHeading, null, t("reset identity input label", {
2825
+ label: /* @__PURE__ */ React38.createElement(StepHeading, null, t("reset identity input label", {
2673
2826
  confirmationValue
2674
2827
  })),
2675
2828
  disabled,
2676
2829
  "data-testid": "reset-identity-input",
2677
2830
  placeholder: confirmationValue,
2678
2831
  onChange: ({ target: { value } }) => setInputValue(value)
2679
- })), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2832
+ })), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(Action, {
2680
2833
  // TODO(wittjosiah): Probably make this red?
2681
2834
  variant: "primary",
2682
2835
  disabled: disabled || pending || inputValue !== confirmationValue,
@@ -2713,47 +2866,47 @@ var resolvedTextColor = (status) => status === Invitation7.State.ERROR ? errorTe
2713
2866
  var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2714
2867
  var JoinPanelImpl = (props) => {
2715
2868
  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, {
2869
+ return /* @__PURE__ */ React39.createElement(DensityProvider3, {
2717
2870
  density: "fine"
2718
- }, mode !== "halo-only" && /* @__PURE__ */ React37.createElement(JoinHeading, {
2871
+ }, mode !== "halo-only" && /* @__PURE__ */ React39.createElement(JoinHeading, {
2719
2872
  titleId,
2720
2873
  mode,
2721
2874
  onExit,
2722
2875
  exitActionParent
2723
- }), /* @__PURE__ */ React37.createElement(Viewport.Root, {
2876
+ }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
2724
2877
  focusManaged: true,
2725
2878
  activeView
2726
- }, /* @__PURE__ */ React37.createElement(Viewport.Views, null, /* @__PURE__ */ React37.createElement(Viewport.View, {
2879
+ }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
2727
2880
  classNames: stepStyles,
2728
2881
  id: "addition method chooser"
2729
- }, /* @__PURE__ */ React37.createElement(AdditionMethodChooser, {
2882
+ }, /* @__PURE__ */ React39.createElement(AdditionMethodChooser, {
2730
2883
  send,
2731
2884
  active: activeView === "addition method chooser"
2732
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2885
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2733
2886
  classNames: stepStyles,
2734
2887
  id: "reset identity confirmation"
2735
- }, /* @__PURE__ */ React37.createElement(ResetIdentityComponent, {
2888
+ }, /* @__PURE__ */ React39.createElement(ResetIdentityComponent, {
2736
2889
  send,
2737
2890
  method: "reset identity",
2738
2891
  active: activeView === "reset identity confirmation"
2739
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2892
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2740
2893
  classNames: stepStyles,
2741
2894
  id: "create identity input"
2742
- }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2895
+ }, /* @__PURE__ */ React39.createElement(IdentityInputComponent, {
2743
2896
  send,
2744
2897
  method: "create identity",
2745
2898
  active: activeView === "create identity input"
2746
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2899
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2747
2900
  classNames: stepStyles,
2748
2901
  id: "recover identity input"
2749
- }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2902
+ }, /* @__PURE__ */ React39.createElement(IdentityInputComponent, {
2750
2903
  send,
2751
2904
  method: "recover identity",
2752
2905
  active: activeView === "recover identity input"
2753
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2906
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2754
2907
  classNames: stepStyles,
2755
2908
  id: "halo invitation input"
2756
- }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2909
+ }, /* @__PURE__ */ React39.createElement(InvitationInput, {
2757
2910
  send,
2758
2911
  Kind: "Halo",
2759
2912
  active: activeView === "halo invitation input",
@@ -2763,20 +2916,20 @@ var JoinPanelImpl = (props) => {
2763
2916
  ...succeededKeys?.Halo && {
2764
2917
  succeededKeys: succeededKeys.Halo
2765
2918
  }
2766
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2919
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2767
2920
  classNames: stepStyles,
2768
2921
  id: "halo invitation rescuer"
2769
- }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2922
+ }, /* @__PURE__ */ React39.createElement(InvitationRescuer, {
2770
2923
  send,
2771
2924
  Kind: "Halo",
2772
2925
  active: activeView === "halo invitation rescuer",
2773
2926
  invitationState: invitationStates?.Halo,
2774
2927
  onInvitationCancel: onHaloInvitationCancel,
2775
2928
  failReason: failReasons?.Halo
2776
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2929
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2777
2930
  classNames: stepStyles,
2778
2931
  id: "halo invitation authenticator"
2779
- }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2932
+ }, /* @__PURE__ */ React39.createElement(InvitationAuthenticator, {
2780
2933
  send,
2781
2934
  Kind: "Halo",
2782
2935
  active: activeView === "halo invitation authenticator",
@@ -2785,28 +2938,28 @@ var JoinPanelImpl = (props) => {
2785
2938
  ...failed.has("Halo") && {
2786
2939
  failed: true
2787
2940
  }
2788
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2941
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2789
2942
  classNames: stepStyles,
2790
2943
  id: "halo invitation accepted"
2791
- }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2944
+ }, /* @__PURE__ */ React39.createElement(InvitationAccepted, {
2792
2945
  send,
2793
2946
  Kind: "Halo",
2794
2947
  active: activeView === "halo invitation accepted",
2795
2948
  doneActionParent,
2796
2949
  onDone: onHaloDone
2797
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2950
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2798
2951
  classNames: stepStyles,
2799
2952
  id: "identity added"
2800
- }, /* @__PURE__ */ React37.createElement(IdentityAdded, {
2953
+ }, /* @__PURE__ */ React39.createElement(IdentityAdded, {
2801
2954
  send,
2802
2955
  mode,
2803
2956
  active: activeView === "identity added",
2804
2957
  doneActionParent,
2805
2958
  onDone: onHaloDone
2806
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2959
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2807
2960
  classNames: stepStyles,
2808
2961
  id: "space invitation input"
2809
- }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2962
+ }, /* @__PURE__ */ React39.createElement(InvitationInput, {
2810
2963
  send,
2811
2964
  Kind: "Space",
2812
2965
  active: activeView === "space invitation input",
@@ -2818,20 +2971,20 @@ var JoinPanelImpl = (props) => {
2818
2971
  },
2819
2972
  onExit,
2820
2973
  exitActionParent
2821
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2974
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2822
2975
  classNames: stepStyles,
2823
2976
  id: "space invitation rescuer"
2824
- }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2977
+ }, /* @__PURE__ */ React39.createElement(InvitationRescuer, {
2825
2978
  send,
2826
2979
  Kind: "Space",
2827
2980
  active: activeView === "space invitation rescuer",
2828
2981
  invitationState: invitationStates?.Space,
2829
2982
  onInvitationCancel: onSpaceInvitationCancel,
2830
2983
  failReason: failReasons?.Space
2831
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2984
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2832
2985
  classNames: stepStyles,
2833
2986
  id: "space invitation authenticator"
2834
- }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2987
+ }, /* @__PURE__ */ React39.createElement(InvitationAuthenticator, {
2835
2988
  send,
2836
2989
  Kind: "Space",
2837
2990
  active: activeView === "space invitation authenticator",
@@ -2840,10 +2993,10 @@ var JoinPanelImpl = (props) => {
2840
2993
  ...failed.has("Space") && {
2841
2994
  failed: true
2842
2995
  }
2843
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2996
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
2844
2997
  classNames: stepStyles,
2845
2998
  id: "space invitation accepted"
2846
- }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2999
+ }, /* @__PURE__ */ React39.createElement(InvitationAccepted, {
2847
3000
  send,
2848
3001
  Kind: "Space",
2849
3002
  active: activeView === "space invitation accepted",
@@ -2854,7 +3007,7 @@ var JoinPanelImpl = (props) => {
2854
3007
  var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCode, exitActionParent, onExit, doneActionParent, onDone: propsOnDone }) => {
2855
3008
  const client = useClient6();
2856
3009
  const identity = useIdentity2();
2857
- const { hasIosKeyboard } = useThemeContext3();
3010
+ const { hasIosKeyboard } = useThemeContext4();
2858
3011
  const titleId = useId7("joinPanel__heading", propsTitleId);
2859
3012
  const [joinState, joinSend, joinService] = useJoinMachine(client, {
2860
3013
  context: {
@@ -3083,7 +3236,7 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
3083
3236
  joinState,
3084
3237
  propsOnDone
3085
3238
  ]);
3086
- return /* @__PURE__ */ React37.createElement(JoinPanelImpl, {
3239
+ return /* @__PURE__ */ React39.createElement(JoinPanelImpl, {
3087
3240
  titleId,
3088
3241
  mode,
3089
3242
  send: joinSend,
@@ -3122,10 +3275,10 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
3122
3275
 
3123
3276
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3124
3277
  import { Planet } from "@phosphor-icons/react";
3125
- import React39, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
3278
+ import React41, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
3126
3279
  import { log as log10 } from "@dxos/log";
3127
3280
  import { useInvitationStatus as useInvitationStatus3 } from "@dxos/react-client/invitations";
3128
- import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation24 } from "@dxos/react-ui";
3281
+ import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation26 } from "@dxos/react-ui";
3129
3282
 
3130
3283
  // packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts
3131
3284
  import { useMachine as useMachine3 } from "@xstate/react";
@@ -3191,16 +3344,16 @@ var useSpaceMachine = (options) => {
3191
3344
 
3192
3345
  // packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx
3193
3346
  import { Placeholder as Placeholder2, UserPlus, UsersThree } from "@phosphor-icons/react";
3194
- import React38, { useCallback as useCallback8, useState as useState9 } from "react";
3347
+ import React40, { useCallback as useCallback8, useState as useState10 } from "react";
3195
3348
  import { useConfig } from "@dxos/react-client";
3196
3349
  import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client/echo";
3197
3350
  import { Invitation as Invitation8, InvitationEncoder as InvitationEncoder4 } from "@dxos/react-client/invitations";
3198
- import { ScrollArea, useTranslation as useTranslation23 } from "@dxos/react-ui";
3351
+ import { ScrollArea, useTranslation as useTranslation25 } from "@dxos/react-ui";
3199
3352
  import { descriptionText as descriptionText10, mx as mx22 } from "@dxos/react-ui-theme";
3200
3353
  var activeActionKey = "dxos:react-shell/space-manager/active-action";
3201
3354
  var SpaceManager = (props) => {
3202
3355
  const { space, target } = props;
3203
- const { t } = useTranslation23("os");
3356
+ const { t } = useTranslation25("os");
3204
3357
  const config = useConfig();
3205
3358
  const invitations = useSpaceInvitations2(space?.key);
3206
3359
  const onInvitationEvent = useCallback8((invitation) => {
@@ -3248,7 +3401,7 @@ var SpaceManager = (props) => {
3248
3401
  ])
3249
3402
  }
3250
3403
  };
3251
- return /* @__PURE__ */ React38.createElement(SpaceManagerImpl, {
3404
+ return /* @__PURE__ */ React40.createElement(SpaceManagerImpl, {
3252
3405
  ...props,
3253
3406
  invitations,
3254
3407
  inviteActions
@@ -3257,7 +3410,7 @@ var SpaceManager = (props) => {
3257
3410
  var headingFragment = "pis-3 pie-1 plb-1 mbe-1 font-medium";
3258
3411
  var SpaceManagerImpl = (props) => {
3259
3412
  const { active, space, createInvitationUrl, send, inviteActions: propsInviteActions, invitations, showInactiveInvitations, SpaceMemberList: SpaceMemberListComponent = SpaceMemberList, InvitationList: InvitationListComponent = InvitationList } = props;
3260
- const { t } = useTranslation23("os");
3413
+ const { t } = useTranslation25("os");
3261
3414
  const inviteActions = propsInviteActions ?? {
3262
3415
  noopInvite: {
3263
3416
  label: t("create space invitation label"),
@@ -3267,7 +3420,7 @@ var SpaceManagerImpl = (props) => {
3267
3420
  }
3268
3421
  }
3269
3422
  };
3270
- const [activeAction, setInternalActiveAction] = useState9(localStorage.getItem(activeActionKey) ?? "inviteOne");
3423
+ const [activeAction, setInternalActiveAction] = useState10(localStorage.getItem(activeActionKey) ?? "inviteOne");
3271
3424
  const setActiveAction = (nextAction) => {
3272
3425
  setInternalActiveAction(nextAction);
3273
3426
  localStorage.setItem(activeActionKey, nextAction);
@@ -3275,26 +3428,26 @@ var SpaceManagerImpl = (props) => {
3275
3428
  const visibleInvitations = showInactiveInvitations ? invitations : invitations?.filter((invitation) => ![
3276
3429
  Invitation8.State.CANCELLED
3277
3430
  ].includes(invitation.get().state));
3278
- return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(ScrollArea.Root, {
3431
+ return /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement(ScrollArea.Root, {
3279
3432
  classNames: "grow shrink basis-28 -mli-2"
3280
- }, /* @__PURE__ */ React38.createElement(ScrollArea.Viewport, {
3433
+ }, /* @__PURE__ */ React40.createElement(ScrollArea.Viewport, {
3281
3434
  classNames: "is-full pie-2"
3282
- }, !!visibleInvitations?.length && /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("h3", {
3435
+ }, !!visibleInvitations?.length && /* @__PURE__ */ React40.createElement(React40.Fragment, null, /* @__PURE__ */ React40.createElement("h3", {
3283
3436
  className: mx22(headingFragment, descriptionText10)
3284
- }, t("invitation list heading")), /* @__PURE__ */ React38.createElement(InvitationListComponent, {
3437
+ }, t("invitation list heading")), /* @__PURE__ */ React40.createElement(InvitationListComponent, {
3285
3438
  className: "mb-2",
3286
3439
  send,
3287
3440
  invitations: visibleInvitations ?? [],
3288
3441
  onClickRemove: (invitation) => invitation.cancel(),
3289
3442
  createInvitationUrl
3290
- }), /* @__PURE__ */ React38.createElement("h3", {
3443
+ }), /* @__PURE__ */ React40.createElement("h3", {
3291
3444
  className: mx22(headingFragment, descriptionText10, "mbs-2")
3292
- }, t("space member list heading"))), /* @__PURE__ */ React38.createElement(SpaceMemberListComponent, {
3445
+ }, t("space member list heading"))), /* @__PURE__ */ React40.createElement(SpaceMemberListComponent, {
3293
3446
  spaceKey: space.key,
3294
3447
  includeSelf: true
3295
- })), /* @__PURE__ */ React38.createElement(ScrollArea.Scrollbar, {
3448
+ })), /* @__PURE__ */ React40.createElement(ScrollArea.Scrollbar, {
3296
3449
  orientation: "vertical"
3297
- }, /* @__PURE__ */ React38.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(BifurcatedAction, {
3450
+ }, /* @__PURE__ */ React40.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React40.createElement(Actions, null, /* @__PURE__ */ React40.createElement(BifurcatedAction, {
3298
3451
  disabled: !active,
3299
3452
  actions: inviteActions,
3300
3453
  activeAction,
@@ -3306,47 +3459,47 @@ var SpaceManagerImpl = (props) => {
3306
3459
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3307
3460
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
3308
3461
  var SpacePanelHeading = ({ titleId, space, onDone }) => {
3309
- const { t } = useTranslation24("os");
3462
+ const { t } = useTranslation26("os");
3310
3463
  const name = space.properties.name;
3311
- return /* @__PURE__ */ React39.createElement(Heading, {
3464
+ return /* @__PURE__ */ React41.createElement(Heading, {
3312
3465
  titleId,
3313
3466
  title: t("space panel heading"),
3314
- corner: /* @__PURE__ */ React39.createElement(CloseButton, {
3467
+ corner: /* @__PURE__ */ React41.createElement(CloseButton, {
3315
3468
  "data-testid": "identity-panel-done",
3316
3469
  onDone
3317
3470
  })
3318
- }, /* @__PURE__ */ React39.createElement("div", {
3471
+ }, /* @__PURE__ */ React41.createElement("div", {
3319
3472
  role: "none",
3320
3473
  className: "flex gap-4 items-center justify-center mlb-4"
3321
- }, /* @__PURE__ */ React39.createElement(Planet, {
3474
+ }, /* @__PURE__ */ React41.createElement(Planet, {
3322
3475
  size: 32,
3323
3476
  weight: "light"
3324
- }), /* @__PURE__ */ React39.createElement("div", {
3477
+ }), /* @__PURE__ */ React41.createElement("div", {
3325
3478
  className: "block text-start font-light text-xl"
3326
3479
  }, name ?? space.key.truncate())));
3327
3480
  };
3328
3481
  var SpacePanelImpl = (props) => {
3329
3482
  const { titleId, activeView, space, target, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3330
- return /* @__PURE__ */ React39.createElement(DensityProvider4, {
3483
+ return /* @__PURE__ */ React41.createElement(DensityProvider4, {
3331
3484
  density: "fine"
3332
- }, /* @__PURE__ */ React39.createElement(SpacePanelHeading, {
3485
+ }, /* @__PURE__ */ React41.createElement(SpacePanelHeading, {
3333
3486
  ...rest,
3334
3487
  titleId,
3335
3488
  space
3336
- }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
3489
+ }), /* @__PURE__ */ React41.createElement(Viewport.Root, {
3337
3490
  activeView
3338
- }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
3491
+ }, /* @__PURE__ */ React41.createElement(Viewport.Views, null, /* @__PURE__ */ React41.createElement(Viewport.View, {
3339
3492
  id: "space manager",
3340
3493
  classNames: stepStyles
3341
- }, /* @__PURE__ */ React39.createElement(SpaceManagerComponent, {
3494
+ }, /* @__PURE__ */ React41.createElement(SpaceManagerComponent, {
3342
3495
  active: activeView === "space manager",
3343
3496
  space,
3344
3497
  target,
3345
3498
  ...rest
3346
- })), /* @__PURE__ */ React39.createElement(Viewport.View, {
3499
+ })), /* @__PURE__ */ React41.createElement(Viewport.View, {
3347
3500
  id: "space invitation manager",
3348
3501
  classNames: stepStyles
3349
- }, /* @__PURE__ */ React39.createElement(InvitationManagerComponent, {
3502
+ }, /* @__PURE__ */ React41.createElement(InvitationManagerComponent, {
3350
3503
  active: activeView === "space invitation manager",
3351
3504
  ...rest,
3352
3505
  invitationUrl: props.invitationUrl
@@ -3354,7 +3507,7 @@ var SpacePanelImpl = (props) => {
3354
3507
  };
3355
3508
  var SpacePanelWithInvitationImpl = ({ invitation, ...props }) => {
3356
3509
  const invitationStatus = useInvitationStatus3(invitation);
3357
- return /* @__PURE__ */ React39.createElement(SpacePanelImpl, {
3510
+ return /* @__PURE__ */ React41.createElement(SpacePanelImpl, {
3358
3511
  ...props,
3359
3512
  ...invitationStatus,
3360
3513
  invitationUrl: props.createInvitationUrl(invitationStatus.invitationCode)
@@ -3401,91 +3554,91 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3401
3554
  };
3402
3555
  return spaceState.context.invitation ? (
3403
3556
  // TODO(wittjosiah): Unused? Remove?
3404
- /* @__PURE__ */ React39.createElement(SpacePanelWithInvitationImpl, {
3557
+ /* @__PURE__ */ React41.createElement(SpacePanelWithInvitationImpl, {
3405
3558
  ...implProps,
3406
3559
  invitation: spaceState.context.invitation
3407
3560
  })
3408
- ) : /* @__PURE__ */ React39.createElement(SpacePanelImpl, implProps);
3561
+ ) : /* @__PURE__ */ React41.createElement(SpacePanelImpl, implProps);
3409
3562
  };
3410
3563
 
3411
3564
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
3412
3565
  var IdentityDialog = (props) => {
3413
3566
  const titleId = useId9("spaceDialog__title");
3414
- return /* @__PURE__ */ React40.createElement(Dialog.Root, {
3567
+ return /* @__PURE__ */ React42.createElement(Dialog.Root, {
3415
3568
  defaultOpen: true,
3416
3569
  onOpenChange: (open) => open || props.onDone?.()
3417
- }, /* @__PURE__ */ React40.createElement(Dialog.Portal, null, /* @__PURE__ */ React40.createElement(Dialog.Overlay, null, /* @__PURE__ */ React40.createElement(Dialog.Content, {
3570
+ }, /* @__PURE__ */ React42.createElement(Dialog.Portal, null, /* @__PURE__ */ React42.createElement(Dialog.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog.Content, {
3418
3571
  "aria-labelledby": titleId,
3419
3572
  onOpenAutoFocus: (e) => e.preventDefault()
3420
- }, /* @__PURE__ */ React40.createElement(ClipboardProvider, null, /* @__PURE__ */ React40.createElement(IdentityPanel, {
3573
+ }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(IdentityPanel, {
3421
3574
  ...props,
3422
3575
  titleId,
3423
- doneActionParent: /* @__PURE__ */ React40.createElement(Dialog.Close, {
3576
+ doneActionParent: /* @__PURE__ */ React42.createElement(Dialog.Close, {
3424
3577
  asChild: true
3425
3578
  })
3426
3579
  }))))));
3427
3580
  };
3428
3581
 
3429
3582
  // packages/sdk/shell/src/composites/JoinDialog/JoinDialog.tsx
3430
- import React41 from "react";
3583
+ import React43 from "react";
3431
3584
  import { AlertDialog, useId as useId10, useVisualViewport } from "@dxos/react-ui";
3432
3585
  var JoinDialog = (joinPanelProps) => {
3433
3586
  const titleId = useId10("joinDialog__title");
3434
3587
  const { height } = useVisualViewport();
3435
- return /* @__PURE__ */ React41.createElement(AlertDialog.Root, {
3588
+ return /* @__PURE__ */ React43.createElement(AlertDialog.Root, {
3436
3589
  defaultOpen: true,
3437
3590
  onOpenChange: (open) => open || (joinPanelProps.onExit ? joinPanelProps.onExit() : joinPanelProps.onDone?.(null))
3438
- }, /* @__PURE__ */ React41.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React41.createElement(AlertDialog.Overlay, {
3591
+ }, /* @__PURE__ */ React43.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React43.createElement(AlertDialog.Overlay, {
3439
3592
  classNames: "backdrop-blur",
3440
3593
  ...height && {
3441
3594
  style: {
3442
3595
  blockSize: `${height}px`
3443
3596
  }
3444
3597
  }
3445
- }, /* @__PURE__ */ React41.createElement(AlertDialog.Content, {
3598
+ }, /* @__PURE__ */ React43.createElement(AlertDialog.Content, {
3446
3599
  "aria-labelledby": titleId
3447
- }, /* @__PURE__ */ React41.createElement(JoinPanel, {
3600
+ }, /* @__PURE__ */ React43.createElement(JoinPanel, {
3448
3601
  ...joinPanelProps,
3449
3602
  titleId,
3450
- exitActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Cancel, {
3603
+ exitActionParent: /* @__PURE__ */ React43.createElement(AlertDialog.Cancel, {
3451
3604
  asChild: true
3452
3605
  }),
3453
- doneActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Action, {
3606
+ doneActionParent: /* @__PURE__ */ React43.createElement(AlertDialog.Action, {
3454
3607
  asChild: true
3455
3608
  })
3456
3609
  })))));
3457
3610
  };
3458
3611
 
3459
3612
  // packages/sdk/shell/src/composites/Shell/run-shell.tsx
3460
- import React44, { StrictMode } from "react";
3613
+ import React46, { StrictMode } from "react";
3461
3614
  import { createRoot } from "react-dom/client";
3462
3615
  import { DEFAULT_CLIENT_CHANNEL, DEFAULT_SHELL_CHANNEL } from "@dxos/client-protocol";
3463
3616
  import { ShellRuntimeImpl } from "@dxos/client-services";
3464
3617
  import { Client, ClientContext, ClientServicesProxy, Config, SystemStatus } from "@dxos/react-client";
3465
- import { ThemeProvider, Tooltip as Tooltip3 } from "@dxos/react-ui";
3618
+ import { ThemeProvider, Tooltip as Tooltip5 } from "@dxos/react-ui";
3466
3619
  import { defaultTx } from "@dxos/react-ui-theme";
3467
3620
  import { createIFramePort } from "@dxos/rpc-tunnel";
3468
3621
 
3469
3622
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3470
- import React43, { useEffect as useEffect7, useState as useState10 } from "react";
3623
+ import React45, { useEffect as useEffect7, useState as useState11 } from "react";
3471
3624
  import { log as log11 } from "@dxos/log";
3472
3625
  import { ShellDisplay, ShellLayout, useClient as useClient7 } from "@dxos/react-client";
3473
3626
  import { useSpace as useSpace2 } from "@dxos/react-client/echo";
3474
3627
 
3475
3628
  // packages/sdk/shell/src/composites/SpaceDialog/SpaceDialog.tsx
3476
- import React42 from "react";
3629
+ import React44 from "react";
3477
3630
  import { Dialog as Dialog2, useId as useId11 } from "@dxos/react-ui";
3478
3631
  var SpaceDialog = (spacePanelProps) => {
3479
3632
  const titleId = useId11("spaceDialog__title");
3480
- return /* @__PURE__ */ React42.createElement(Dialog2.Root, {
3633
+ return /* @__PURE__ */ React44.createElement(Dialog2.Root, {
3481
3634
  defaultOpen: true,
3482
3635
  onOpenChange: (open) => open || spacePanelProps.onDone?.()
3483
- }, /* @__PURE__ */ React42.createElement(Dialog2.Portal, null, /* @__PURE__ */ React42.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog2.Content, {
3636
+ }, /* @__PURE__ */ React44.createElement(Dialog2.Portal, null, /* @__PURE__ */ React44.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React44.createElement(Dialog2.Content, {
3484
3637
  "aria-labelledby": titleId
3485
- }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(SpacePanel, {
3638
+ }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(SpacePanel, {
3486
3639
  ...spacePanelProps,
3487
3640
  titleId,
3488
- doneActionParent: /* @__PURE__ */ React42.createElement(Dialog2.Close, {
3641
+ doneActionParent: /* @__PURE__ */ React44.createElement(Dialog2.Close, {
3489
3642
  asChild: true
3490
3643
  })
3491
3644
  }))))));
@@ -3494,7 +3647,7 @@ var SpaceDialog = (spacePanelProps) => {
3494
3647
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3495
3648
  var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3496
3649
  var Shell = ({ runtime, origin }) => {
3497
- const [{ layout, invitationCode, spaceKey, target }, setLayout] = useState10({
3650
+ const [{ layout, invitationCode, spaceKey, target }, setLayout] = useState11({
3498
3651
  layout: runtime.layout,
3499
3652
  invitationCode: runtime.invitationCode,
3500
3653
  spaceKey: runtime.spaceKey,
@@ -3532,7 +3685,7 @@ var Shell = ({ runtime, origin }) => {
3532
3685
  ]);
3533
3686
  switch (layout) {
3534
3687
  case ShellLayout.INITIALIZE_IDENTITY:
3535
- return /* @__PURE__ */ React43.createElement(JoinDialog, {
3688
+ return /* @__PURE__ */ React45.createElement(JoinDialog, {
3536
3689
  mode: "halo-only",
3537
3690
  initialInvitationCode: invitationCode,
3538
3691
  onDone: () => {
@@ -3547,7 +3700,7 @@ var Shell = ({ runtime, origin }) => {
3547
3700
  case ShellLayout.IDENTITY:
3548
3701
  case ShellLayout.SHARE_IDENTITY:
3549
3702
  case ShellLayout.EDIT_PROFILE:
3550
- return /* @__PURE__ */ React43.createElement(IdentityDialog, {
3703
+ return /* @__PURE__ */ React45.createElement(IdentityDialog, {
3551
3704
  createInvitationUrl: (invitationCode2) => `${origin}?deviceInvitationCode=${invitationCode2}`,
3552
3705
  onResetDevice: async () => {
3553
3706
  await client.reset();
@@ -3569,7 +3722,7 @@ var Shell = ({ runtime, origin }) => {
3569
3722
  }
3570
3723
  });
3571
3724
  case ShellLayout.SPACE:
3572
- return space ? /* @__PURE__ */ React43.createElement(SpaceDialog, {
3725
+ return space ? /* @__PURE__ */ React45.createElement(SpaceDialog, {
3573
3726
  space,
3574
3727
  target,
3575
3728
  createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
@@ -3583,7 +3736,7 @@ var Shell = ({ runtime, origin }) => {
3583
3736
  }
3584
3737
  }) : null;
3585
3738
  case ShellLayout.JOIN_SPACE:
3586
- return /* @__PURE__ */ React43.createElement(JoinDialog, {
3739
+ return /* @__PURE__ */ React45.createElement(JoinDialog, {
3587
3740
  initialInvitationCode: invitationCode,
3588
3741
  onDone: async (result) => {
3589
3742
  const target2 = result?.target ?? void 0;
@@ -3717,7 +3870,28 @@ var os = {
3717
3870
  "sign out chooser message": "Proceeding with either action below will erase all data on this device.",
3718
3871
  "join new identity label": "Join a new identity",
3719
3872
  "reset device label": "Reset device",
3720
- "reset device confirm message": "Are you sure you want to reset your device? All data will be lost."
3873
+ "reset device confirm message": "Are you sure you want to reset your device? All data will be lost.",
3874
+ "emoji and color label": "Emoji and color",
3875
+ "clear label": "Use default",
3876
+ "select emoji label": "Choose an emoji to use in your avatar",
3877
+ "select hue label": "Choose a hue to use in your avatar",
3878
+ "red label": "Red",
3879
+ "orange label": "Orange",
3880
+ "amber label": "Amber",
3881
+ "yellow label": "Yellow",
3882
+ "lime label": "Lime",
3883
+ "green label": "Green",
3884
+ "emerald label": "Emerald",
3885
+ "teal label": "Teal",
3886
+ "cyan label": "Cyan",
3887
+ "sky label": "Sky",
3888
+ "blue label": "Blue",
3889
+ "indigo label": "Indigo",
3890
+ "violet label": "Violet",
3891
+ "purple label": "Purple",
3892
+ "fuchsia label": "Fuchsia",
3893
+ "pink label": "Pink",
3894
+ "rose label": "Rose"
3721
3895
  };
3722
3896
 
3723
3897
  // packages/sdk/shell/src/translations/index.ts
@@ -3741,24 +3915,24 @@ var runShell = async (config = new Config()) => {
3741
3915
  runtime.open(),
3742
3916
  client.initialize()
3743
3917
  ]);
3744
- createRoot(document.getElementById("root")).render(/* @__PURE__ */ React44.createElement(StrictMode, null, /* @__PURE__ */ React44.createElement(ThemeProvider, {
3918
+ createRoot(document.getElementById("root")).render(/* @__PURE__ */ React46.createElement(StrictMode, null, /* @__PURE__ */ React46.createElement(ThemeProvider, {
3745
3919
  tx: defaultTx,
3746
3920
  resourceExtensions: [
3747
3921
  osTranslations
3748
3922
  ]
3749
- }, /* @__PURE__ */ React44.createElement(ClientContext.Provider, {
3923
+ }, /* @__PURE__ */ React46.createElement(ClientContext.Provider, {
3750
3924
  value: {
3751
3925
  client,
3752
3926
  status: SystemStatus.ACTIVE
3753
3927
  }
3754
- }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React44.createElement(Shell, {
3928
+ }, /* @__PURE__ */ React46.createElement(ClipboardProvider, null, /* @__PURE__ */ React46.createElement(Tooltip5.Provider, null, /* @__PURE__ */ React46.createElement(Shell, {
3755
3929
  runtime,
3756
3930
  origin: location.origin
3757
3931
  })))))));
3758
3932
  };
3759
3933
 
3760
3934
  // 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";
3935
+ import React47, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState12 } from "react";
3762
3936
  import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient8 } from "@dxos/react-client";
3763
3937
  import { useIdentity as useIdentity3 } from "@dxos/react-client/halo";
3764
3938
  import { mx as mx23 } from "@dxos/react-ui-theme";
@@ -3820,7 +3994,7 @@ var useShell = () => {
3820
3994
  var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoinedSpace, children }) => {
3821
3995
  const client = useClient8();
3822
3996
  const identity = useIdentity3();
3823
- const [display, setDisplay] = useState11(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3997
+ const [display, setDisplay] = useState12(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3824
3998
  const shellRuntime = useMemo6(() => {
3825
3999
  if (client.config.get("runtime.app.env.DX_VAULT") !== "false") {
3826
4000
  return;
@@ -3890,12 +4064,12 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3890
4064
  }, [
3891
4065
  shellRuntime
3892
4066
  ]);
3893
- return /* @__PURE__ */ React45.createElement(React45.Fragment, null, shellRuntime && /* @__PURE__ */ React45.createElement("div", {
4067
+ return /* @__PURE__ */ React47.createElement(React47.Fragment, null, shellRuntime && /* @__PURE__ */ React47.createElement("div", {
3894
4068
  className: mx23(display === ShellDisplay2.NONE ? "hidden" : "")
3895
- }, /* @__PURE__ */ React45.createElement(Shell, {
4069
+ }, /* @__PURE__ */ React47.createElement(Shell, {
3896
4070
  runtime: shellRuntime,
3897
4071
  origin: window.location.origin
3898
- })), /* @__PURE__ */ React45.createElement(ShellContext.Provider, {
4072
+ })), /* @__PURE__ */ React47.createElement(ShellContext.Provider, {
3899
4073
  value: {
3900
4074
  runtime: shellRuntime,
3901
4075
  setDisplay
@@ -3916,7 +4090,9 @@ export {
3916
4090
  CopyButtonIconOnly,
3917
4091
  DeviceList,
3918
4092
  Emoji,
4093
+ EmojiPicker,
3919
4094
  Heading,
4095
+ HuePicker,
3920
4096
  IdentityDialog,
3921
4097
  IdentityListItem,
3922
4098
  IdentityPanel,