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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/bundle/shell.mjs +63626 -21110
  2. package/dist/bundle/shell.mjs.map +1 -1
  3. package/dist/bundle/shell.umd.js +793 -78
  4. package/dist/bundle/shell.umd.js.map +1 -1
  5. package/dist/bundle/style.css +1 -1
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/react.mjs +768 -591
  8. package/dist/lib/browser/react.mjs.map +4 -4
  9. package/dist/types/src/components/EmojiPicker.d.ts +11 -0
  10. package/dist/types/src/components/EmojiPicker.d.ts.map +1 -0
  11. package/dist/types/src/components/EmojiPicker.js +79 -0
  12. package/dist/types/src/components/EmojiPicker.js.map +1 -0
  13. package/dist/types/src/components/HuePicker.d.ts +11 -0
  14. package/dist/types/src/components/HuePicker.d.ts.map +1 -0
  15. package/dist/types/src/components/HuePicker.js +56 -0
  16. package/dist/types/src/components/HuePicker.js.map +1 -0
  17. package/dist/types/src/components/IdentityList/IdentityListItem.d.ts.map +1 -1
  18. package/dist/types/src/components/IdentityList/IdentityListItem.js +5 -5
  19. package/dist/types/src/components/IdentityList/IdentityListItem.js.map +1 -1
  20. package/dist/types/src/components/InvitationList/InvitationListItem.d.ts.map +1 -1
  21. package/dist/types/src/components/InvitationList/InvitationListItem.js +2 -2
  22. package/dist/types/src/components/InvitationList/InvitationListItem.js.map +1 -1
  23. package/dist/types/src/components/SpaceListItem.d.ts.map +1 -1
  24. package/dist/types/src/components/SpaceListItem.js +2 -3
  25. package/dist/types/src/components/SpaceListItem.js.map +1 -1
  26. package/dist/types/src/components/index.d.ts +2 -0
  27. package/dist/types/src/components/index.d.ts.map +1 -1
  28. package/dist/types/src/components/index.js +2 -0
  29. package/dist/types/src/components/index.js.map +1 -1
  30. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  31. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +6 -5
  32. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  33. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -1
  34. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +12 -3
  35. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -1
  36. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.d.ts.map +1 -1
  37. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js +8 -7
  38. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js.map +1 -1
  39. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js +2 -2
  40. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js.map +1 -1
  41. package/dist/types/src/steps/InvitationManager.d.ts.map +1 -1
  42. package/dist/types/src/steps/InvitationManager.js +5 -4
  43. package/dist/types/src/steps/InvitationManager.js.map +1 -1
  44. package/dist/types/src/translations/locales/en-US.d.ts +21 -0
  45. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  46. package/dist/types/src/translations/locales/en-US.js +21 -0
  47. package/dist/types/src/translations/locales/en-US.js.map +1 -1
  48. package/dist/types/src/util/index.d.ts +0 -1
  49. package/dist/types/src/util/index.d.ts.map +1 -1
  50. package/dist/types/src/util/index.js +0 -1
  51. package/dist/types/src/util/index.js.map +1 -1
  52. package/package.json +22 -21
  53. package/src/components/EmojiPicker.tsx +82 -0
  54. package/src/components/HuePicker.tsx +87 -0
  55. package/src/components/IdentityList/IdentityListItem.tsx +9 -5
  56. package/src/components/InvitationList/InvitationListItem.tsx +2 -2
  57. package/src/components/SpaceListItem.tsx +4 -5
  58. package/src/components/index.ts +2 -0
  59. package/src/panels/IdentityPanel/IdentityPanel.tsx +5 -4
  60. package/src/panels/IdentityPanel/steps/ProfileForm.tsx +29 -7
  61. package/src/panels/JoinPanel/steps/IdentityAdded.tsx +7 -7
  62. package/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx +2 -2
  63. package/src/steps/InvitationManager.tsx +4 -3
  64. package/src/translations/locales/en-US.ts +21 -0
  65. package/src/util/index.ts +0 -1
  66. package/dist/types/src/util/toEmoji.d.ts +0 -2
  67. package/dist/types/src/util/toEmoji.d.ts.map +0 -1
  68. package/dist/types/src/util/toEmoji.js +0 -26
  69. package/dist/types/src/util/toEmoji.js.map +0 -1
  70. package/src/util/toEmoji.ts +0 -22
@@ -1 +1 @@
1
- {"version":3,"file":"InvitationManager.d.ts","sourceRoot":"","sources":["../../../../src/steps/InvitationManager.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,gBAAgB,EAAc,MAAM,gCAAgC,CAAC;AAInF,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAc7C,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAC5C,OAAO,CAAC,gBAAgB,CAAC,GAAG;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAUJ,eAAO,MAAM,iBAAiB,iEAQ3B,sBAAsB,gBAoExB,CAAC"}
1
+ {"version":3,"file":"InvitationManager.d.ts","sourceRoot":"","sources":["../../../../src/steps/InvitationManager.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,gBAAgB,EAAc,MAAM,gCAAgC,CAAC;AAKnF,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAc7C,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAC5C,OAAO,CAAC,gBAAgB,CAAC,GAAG;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAUJ,eAAO,MAAM,iBAAiB,iEAQ3B,sBAAsB,gBAoExB,CAAC"}
@@ -33,18 +33,19 @@ const react_qr_rounded_1 = require("react-qr-rounded");
33
33
  const invitations_1 = require("@dxos/react-client/invitations");
34
34
  const react_ui_1 = require("@dxos/react-ui");
35
35
  const react_ui_theme_1 = require("@dxos/react-ui-theme");
36
+ const util_1 = require("@dxos/util");
36
37
  const components_1 = require("../components");
37
- const util_1 = require("../util");
38
+ const util_2 = require("../util");
38
39
  const InvitationManagerView = ({ children, ...props }) => {
39
40
  return (react_2.default.createElement(components_1.Viewport.View, { ...props, classNames: 'grow flex flex-col justify-around items-center' }, children));
40
41
  };
41
- const InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id, }) => {
42
+ const InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id = '0', }) => {
42
43
  var _a;
43
44
  const { t } = (0, react_ui_1.useTranslation)('os');
44
45
  const qrLabel = (0, react_ui_1.useId)('invitation-manager__qr-code');
45
- const statusValue = type === invitations_1.Invitation.Type.MULTIUSE ? 0 : (_a = util_1.invitationStatusValue.get(status)) !== null && _a !== void 0 ? _a : 0;
46
+ const statusValue = type === invitations_1.Invitation.Type.MULTIUSE ? 0 : (_a = util_2.invitationStatusValue.get(status)) !== null && _a !== void 0 ? _a : 0;
46
47
  const showAuthCode = statusValue === 3;
47
- const emoji = (0, util_1.toEmoji)(id !== null && id !== void 0 ? id : '');
48
+ const emoji = (0, util_1.hexToEmoji)(id);
48
49
  const activeView = (0, react_2.useMemo)(() => {
49
50
  switch (true) {
50
51
  case statusValue === 5:
@@ -1 +1 @@
1
- {"version":3,"file":"InvitationManager.js","sourceRoot":"","sources":["../../../../src/steps/InvitationManager.tsx"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;AAEF,iDAAiD;AACjD,+CAAuC;AACvC,uDAAsC;AAEtC,gEAAmF;AACnF,6CAAuD;AACvD,yDAAoE;AAGpE,8CAUuB;AACvB,kCAAyD;AAOzD,MAAM,qBAAqB,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAA0C,EAAE,EAAE;IAC/F,OAAO,CACL,8BAAC,qBAAQ,CAAC,IAAI,OAAK,KAAK,EAAE,UAAU,EAAC,gDAAgD,IAClF,QAAQ,CACK,CACjB,CAAC;AACJ,CAAC,CAAC;AAEK,MAAM,iBAAiB,GAAG,CAAC,EAChC,aAAa,EACb,MAAM,EACN,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,EAAE,GACqB,EAAE,EAAE;;IAC3B,MAAM,EAAE,CAAC,EAAE,GAAG,IAAA,yBAAc,EAAC,IAAI,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAA,gBAAK,EAAC,6BAA6B,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,IAAI,KAAK,wBAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAA,4BAAqB,CAAC,GAAG,CAAC,MAAO,CAAC,mCAAI,CAAC,CAAC;IACpG,MAAM,YAAY,GAAG,WAAW,KAAK,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAA,cAAO,EAAC,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,EAAE,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QAC9B,QAAQ,IAAI,EAAE;YACZ,KAAK,WAAW,KAAK,CAAC,CAAC;YACvB,KAAK,WAAW,GAAG,CAAC;gBAClB,OAAO,eAAe,CAAC;YACzB,KAAK,WAAW,KAAK,CAAC;gBACpB,OAAO,mBAAmB,CAAC;YAC7B;gBACE,OAAO,YAAY,CAAC;SACvB;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAClB,OAAO,CACL;QACE,8BAAC,qBAAQ,CAAC,IAAI,IAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAC,YAAY;YAC5D,8BAAC,qBAAQ,CAAC,KAAK;gBACb,8BAAC,qBAAqB,IAAC,EAAE,EAAC,YAAY,EAAC,KAAK,EAAE,KAAK;oBACjD,qCAAG,SAAS,EAAC,uCAAuC,IACjD,CAAC,CAAC,IAAI,KAAK,wBAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,qBAAqB,CAAC,CACpF;oBACJ,uCAAK,IAAI,EAAC,MAAM,EAAC,SAAS,EAAE,IAAA,mBAAE,EAAC,gCAAe,EAAE,iCAAiC,CAAC;wBAChF,8BAAC,qBAAE,IACD,QAAQ,EAAE,GAAG,EACb,eAAe,EAAC,aAAa,EAC7B,KAAK,EAAC,cAAc,EACpB,SAAS,EAAE,IAAA,mBAAE,EAAC,qBAAqB,EAAE,YAAY,IAAI,WAAW,CAAC,qBAChD,OAAO,EACxB,oBAAoB,EAAC,GAAG,EACxB,MAAM,EAAE,IAAI,IAEX,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,OAAO,CACtB;wBACL,8BAAC,qBAAQ;4BACP,8BAAC,kBAAK,IAAC,IAAI,EAAE,KAAK,GAAI,CACb,CACP;oBACN,wCAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAC,SAAS,IACnC,CAAC,CAAC,UAAU,CAAC,CACT;oBACP,8BAAC,uBAAU,IAAC,OAAO,EAAC,OAAO,EAAC,KAAK,EAAE,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,OAAO,GAAI,CACzC;gBACxB,8BAAC,qBAAqB,IAAC,EAAE,EAAC,mBAAmB;oBAC3C,8BAAC,kBAAK,QAAE,CAAC,CAAC,mBAAmB,CAAC,CAAS;oBACvC,8BAAC,qBAAQ,IAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,QAAC,UAAU,EAAC,4BAA4B,GAAG;oBAC1E,8BAAC,kBAAK,2DAAyD;oBAC9D,KAAK,IAAI,8BAAC,kBAAK,IAAC,IAAI,EAAE,KAAK,GAAI,CACV;gBACxB,8BAAC,qBAAqB,IAAC,EAAE,EAAC,eAAe,IACtC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CACjB,8BAAC,aAAK,IAAC,SAAS,EAAE,IAAA,mBAAE,EAAC,OAAO,EAAE,IAAA,wBAAO,EAAC,CAAC,CAAC,CAAC,GAAI,CAC9C,CAAC,CAAC,CAAC,CACF,8BAAC,SAAC,IAAC,SAAS,EAAE,IAAA,mBAAE,EAAC,OAAO,EAAE,IAAA,wBAAO,EAAC,CAAC,CAAC,CAAC,GAAI,CAC1C,CACqB,CACT,CACH;QAChB,8BAAC,oBAAO,IAAC,UAAU,EAAC,OAAO;YACzB,8BAAC,mBAAM,IAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAG,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,IAC7E,CAAC,CAAC,YAAY,CAAC,CACT,CACD,CACT,CACJ,CAAC;AACJ,CAAC,CAAC;AA5EW,QAAA,iBAAiB,qBA4E5B"}
1
+ {"version":3,"file":"InvitationManager.js","sourceRoot":"","sources":["../../../../src/steps/InvitationManager.tsx"],"names":[],"mappings":"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"}
@@ -101,5 +101,26 @@ export declare const os: {
101
101
  'join new identity label': string;
102
102
  'reset device label': string;
103
103
  'reset device confirm message': string;
104
+ 'emoji and color label': string;
105
+ 'clear label': string;
106
+ 'select emoji label': string;
107
+ 'select hue label': string;
108
+ 'red label': string;
109
+ 'orange label': string;
110
+ 'amber label': string;
111
+ 'yellow label': string;
112
+ 'lime label': string;
113
+ 'green label': string;
114
+ 'emerald label': string;
115
+ 'teal label': string;
116
+ 'cyan label': string;
117
+ 'sky label': string;
118
+ 'blue label': string;
119
+ 'indigo label': string;
120
+ 'violet label': string;
121
+ 'purple label': string;
122
+ 'fuchsia label': string;
123
+ 'pink label': string;
124
+ 'rose label': string;
104
125
  };
105
126
  //# sourceMappingURL=en-US.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"en-US.d.ts","sourceRoot":"","sources":["../../../../../src/translations/locales/en-US.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwGd,CAAC"}
1
+ {"version":3,"file":"en-US.d.ts","sourceRoot":"","sources":["../../../../../src/translations/locales/en-US.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Hd,CAAC"}
@@ -107,5 +107,26 @@ exports.os = {
107
107
  'join new identity label': 'Join a new identity',
108
108
  'reset device label': 'Reset device',
109
109
  'reset device confirm message': 'Are you sure you want to reset your device? All data will be lost.',
110
+ 'emoji and color label': 'Emoji and color',
111
+ 'clear label': 'Use default',
112
+ 'select emoji label': 'Choose an emoji to use in your avatar',
113
+ 'select hue label': 'Choose a hue to use in your avatar',
114
+ 'red label': 'Red',
115
+ 'orange label': 'Orange',
116
+ 'amber label': 'Amber',
117
+ 'yellow label': 'Yellow',
118
+ 'lime label': 'Lime',
119
+ 'green label': 'Green',
120
+ 'emerald label': 'Emerald',
121
+ 'teal label': 'Teal',
122
+ 'cyan label': 'Cyan',
123
+ 'sky label': 'Sky',
124
+ 'blue label': 'Blue',
125
+ 'indigo label': 'Indigo',
126
+ 'violet label': 'Violet',
127
+ 'purple label': 'Purple',
128
+ 'fuchsia label': 'Fuchsia',
129
+ 'pink label': 'Pink',
130
+ 'rose label': 'Rose',
110
131
  };
111
132
  //# sourceMappingURL=en-US.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"en-US.js","sourceRoot":"","sources":["../../../../../src/translations/locales/en-US.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAEW,QAAA,EAAE,GAAG;IAChB,sBAAsB,EAAE,iBAAiB;IACzC,8BAA8B,EAAE,SAAS;IACzC,eAAe,EAAE,cAAc;IAC/B,4BAA4B,EAAE,UAAU;IACxC,oBAAoB,EAAE,QAAQ;IAC9B,4BAA4B,EAAE,iBAAiB;IAC/C,wBAAwB,EAAE,cAAc;IACxC,uBAAuB,EAAE,eAAe;IACxC,oBAAoB,EAAE,wBAAwB;IAC9C,cAAc,EAAE,4BAA4B;IAC5C,YAAY,EAAE,MAAM;IACpB,yBAAyB,EAAE,SAAS;IACpC,4BAA4B,EAAE,+DAA+D;IAC7F,oBAAoB,EAAE,KAAK;IAC3B,gBAAgB,EAAE,UAAU;IAC5B,YAAY,EAAE,MAAM;IACpB,YAAY,EAAE,MAAM;IACpB,aAAa,EAAE,OAAO;IACtB,oBAAoB,EAAE,oBAAoB;IAC1C,uBAAuB,EAAE,oBAAoB;IAC7C,6BAA6B,EAAE,wBAAwB;IACvD,wBAAwB,EAAE,mBAAmB;IAC7C,8BAA8B,EAAE,4CAA4C;IAC5E,qBAAqB,EAAE,oBAAoB;IAC3C,2BAA2B,EAAE,8EAA8E;IAC3G,yBAAyB,EAAE,oBAAoB;IAC/C,+BAA+B,EAAE,qCAAqC;IACtE,0BAA0B,EAAE,kBAAkB;IAC9C,8BAA8B,EAAE,gCAAgC;IAChE,mCAAmC,EAAE,+BAA+B;IACpE,oCAAoC,EAAE,8DAA8D;IACpG,gCAAgC,EAAE,gBAAgB;IAClD,sBAAsB,EAAE,0CAA0C;IAClE,gCAAgC,EAAE,mEAAmE;IACrG,oBAAoB,EAAE,QAAQ;IAC9B,sBAAsB,EAAE,WAAW;IACnC,wBAAwB,EAAE,WAAW;IACrC,mBAAmB,EAAE,kBAAkB;IACvC,yBAAyB,EAAE,aAAa;IACxC,wBAAwB,EAAE,wBAAwB;IAClD,6BAA6B,EAAE,wBAAwB;IACvD,sBAAsB,EAAE,SAAS;IACjC,eAAe,EAAE,SAAS;IAC1B,iBAAiB,EAAE,WAAW;IAC9B,cAAc,EAAE,QAAQ;IACxB,YAAY,EAAE,MAAM;IACpB,aAAa,EAAE,YAAY;IAC3B,uBAAuB,EAAE,6BAA6B;IACtD,wBAAwB,EAAE,iCAAiC;IAC3D,gCAAgC,EAAE,YAAY;IAC9C,+BAA+B,EAAE,QAAQ;IACzC,UAAU,EAAE,2BAA2B;IACvC,2BAA2B,EAAE,wBAAwB;IACrD,2BAA2B,EAAE,kDAAkD;IAC/E,uBAAuB,EAAE,YAAY;IACrC,kBAAkB,EAAE,YAAY;IAChC,oBAAoB,EAAE,oBAAoB;IAC1C,kBAAkB,EAAE,cAAc;IAClC,0BAA0B,EAAE,eAAe;IAC3C,8BAA8B,EAAE,wBAAwB;IACxD,sBAAsB,EAAE,oBAAoB;IAC5C,oBAAoB,EAAE,cAAc;IACpC,qBAAqB,EAAE,eAAe;IACtC,iBAAiB,EAAE,SAAS;IAC5B,4BAA4B,EAAE,oBAAoB;IAClD,iBAAiB,EAAE,SAAS;IAC5B,kBAAkB,EAAE,kBAAkB;IACtC,yBAAyB,EAAE,YAAY;IACvC,sBAAsB,EAAE,gBAAgB;IACxC,sBAAsB,EAAE,cAAc;IACtC,uBAAuB,EAAE,UAAU;IACnC,6BAA6B,EAAE,oCAAoC;IACnE,+BAA+B,EAAE,yBAAyB;IAC1D,oBAAoB,EAAE,YAAY;IAClC,yBAAyB,EAAE,aAAa;IACxC,gCAAgC,EAAE,4BAA4B;IAC9D,+BAA+B,EAAE,qBAAqB;IACtD,qBAAqB,EAAE,SAAS;IAChC,2BAA2B,EAAE,SAAS;IACtC,qBAAqB,EAAE,kBAAkB;IACzC,mBAAmB,EAAE,sDAAsD;IAC3E,0BAA0B,EAAE,cAAc;IAC1C,gCAAgC,EAAE,sBAAsB;IACxD,kBAAkB,EAAE,YAAY;IAChC,wBAAwB,EAAE,yBAAyB;IACnD,qBAAqB,EAAE,YAAY;IACnC,4BAA4B,EAAE,8BAA8B;IAC5D,mBAAmB,EAAE,aAAa;IAClC,yBAAyB,EAAE,gCAAgC;IAC3D,sBAAsB,EAAE,cAAc;IACtC,6BAA6B,EAAE,gCAAgC;IAC/D,sBAAsB,EAAE,kCAAkC;IAC1D,yBAAyB,EAAE,cAAc;IACzC,eAAe,EAAE,SAAS;IAC1B,4BAA4B,EAC1B,0GAA0G;IAC5G,kCAAkC,EAAE,2BAA2B;IAC/D,oBAAoB,EAAE,SAAS;IAC/B,wBAAwB,EAAE,aAAa;IACvC,0BAA0B,EAAE,yEAAyE;IACrG,yBAAyB,EAAE,qBAAqB;IAChD,oBAAoB,EAAE,cAAc;IACpC,8BAA8B,EAAE,oEAAoE;CACrG,CAAC"}
1
+ {"version":3,"file":"en-US.js","sourceRoot":"","sources":["../../../../../src/translations/locales/en-US.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,2 @@
1
1
  export * from './invitationStatusValue';
2
- export * from './toEmoji';
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/util/index.ts"],"names":[],"mappings":"AAIA,cAAc,yBAAyB,CAAC;AACxC,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/util/index.ts"],"names":[],"mappings":"AAIA,cAAc,yBAAyB,CAAC"}
@@ -18,5 +18,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
20
  __exportStar(require("./invitationStatusValue"), exports);
21
- __exportStar(require("./toEmoji"), exports);
22
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/util/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;;;;;;;;;;;AAEF,0DAAwC;AACxC,4CAA0B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/util/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;;;;;;;;;;;AAEF,0DAAwC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/shell",
3
- "version": "0.4.7-main.f9d3866",
3
+ "version": "0.4.7-next.f4b92be",
4
4
  "description": "DXOS’s OS experiences",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -28,6 +28,8 @@
28
28
  "src"
29
29
  ],
30
30
  "dependencies": {
31
+ "@emoji-mart/data": "^1.1.2",
32
+ "@emoji-mart/react": "^1.1.1",
31
33
  "@fluentui/react-tabster": "^9.19.0",
32
34
  "@radix-ui/react-accordion": "^1.1.1",
33
35
  "@radix-ui/react-context": "^1.0.0",
@@ -35,27 +37,26 @@
35
37
  "@radix-ui/react-use-controllable-state": "^1.0.0",
36
38
  "@react-hook/async": "^3.1.1",
37
39
  "@xstate/react": "^3.2.1",
38
- "lodash.toarray": "^4.4.0",
40
+ "emoji-mart": "^5.5.2",
39
41
  "react-qr-rounded": "^1.0.0",
40
42
  "url-join": "^5.0.0",
41
43
  "xstate": "^4.37.0",
42
- "@dxos/client-protocol": "0.4.7-main.f9d3866",
43
- "@dxos/client-services": "0.4.7-main.f9d3866",
44
- "@dxos/async": "0.4.7-main.f9d3866",
45
- "@dxos/debug": "0.4.7-main.f9d3866",
46
- "@dxos/invariant": "0.4.7-main.f9d3866",
47
- "@dxos/react-client": "0.4.7-main.f9d3866",
48
- "@dxos/react-ui-theme": "0.4.7-main.f9d3866",
49
- "@dxos/display-name": "0.4.7-main.f9d3866",
50
- "@dxos/log": "0.4.7-main.f9d3866",
51
- "@dxos/react-ui-types": "0.4.7-main.f9d3866",
52
- "@dxos/react-ui": "0.4.7-main.f9d3866",
53
- "@dxos/rpc-tunnel": "0.4.7-main.f9d3866",
54
- "@dxos/util": "0.4.7-main.f9d3866"
44
+ "@dxos/async": "0.4.7-next.f4b92be",
45
+ "@dxos/client-protocol": "0.4.7-next.f4b92be",
46
+ "@dxos/client-services": "0.4.7-next.f4b92be",
47
+ "@dxos/display-name": "0.4.7-next.f4b92be",
48
+ "@dxos/debug": "0.4.7-next.f4b92be",
49
+ "@dxos/invariant": "0.4.7-next.f4b92be",
50
+ "@dxos/react-ui": "0.4.7-next.f4b92be",
51
+ "@dxos/react-ui-theme": "0.4.7-next.f4b92be",
52
+ "@dxos/react-ui-types": "0.4.7-next.f4b92be",
53
+ "@dxos/log": "0.4.7-next.f4b92be",
54
+ "@dxos/rpc-tunnel": "0.4.7-next.f4b92be",
55
+ "@dxos/util": "0.4.7-next.f4b92be",
56
+ "@dxos/react-client": "0.4.7-next.f4b92be"
55
57
  },
56
58
  "devDependencies": {
57
59
  "@phosphor-icons/react": "^2.0.5",
58
- "@types/lodash.toarray": "^4.4.7",
59
60
  "@types/react": "^18.0.21",
60
61
  "@types/react-dom": "^18.0.6",
61
62
  "@vitejs/plugin-react": "^4.2.1",
@@ -63,11 +64,11 @@
63
64
  "react-dom": "^18.2.0",
64
65
  "vite": "^5.1.3",
65
66
  "vite-plugin-turbosnap": "^1.0.2",
66
- "@dxos/config": "0.4.7-main.f9d3866",
67
- "@dxos/react-async": "0.4.7-main.f9d3866",
68
- "@dxos/random": "0.4.7-main.f9d3866",
69
- "@dxos/react-ui-theme": "0.4.7-main.f9d3866",
70
- "@dxos/storybook-utils": "0.4.7-main.f9d3866"
67
+ "@dxos/config": "0.4.7-next.f4b92be",
68
+ "@dxos/react-ui-theme": "0.4.7-next.f4b92be",
69
+ "@dxos/react-async": "0.4.7-next.f4b92be",
70
+ "@dxos/storybook-utils": "0.4.7-next.f4b92be",
71
+ "@dxos/random": "0.4.7-next.f4b92be"
71
72
  },
72
73
  "peerDependencies": {
73
74
  "@phosphor-icons/react": "^2.0.5",
@@ -0,0 +1,82 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+ import emojiData from '@emoji-mart/data';
5
+ import EmojiMart from '@emoji-mart/react';
6
+ import { ArrowCounterClockwise, CaretDown } from '@phosphor-icons/react';
7
+ import { useControllableState } from '@radix-ui/react-use-controllable-state';
8
+ import React, { type Dispatch, type SetStateAction, useState } from 'react';
9
+
10
+ import { Button, Popover, useTranslation, Tooltip, type ButtonProps } from '@dxos/react-ui';
11
+ import { getSize } from '@dxos/react-ui-theme';
12
+
13
+ export type EmojiPickerProps = {
14
+ disabled?: boolean;
15
+ defaultEmoji?: string;
16
+ emoji?: string;
17
+ onChangeEmoji?: Dispatch<SetStateAction<string>>;
18
+ onClickClear?: ButtonProps['onClick'];
19
+ };
20
+
21
+ export const EmojiPicker = ({ disabled, defaultEmoji, emoji, onChangeEmoji, onClickClear }: EmojiPickerProps) => {
22
+ const { t } = useTranslation('os');
23
+
24
+ const [emojiValue, setEmojiValue] = useControllableState<string>({
25
+ prop: emoji,
26
+ onChange: onChangeEmoji,
27
+ defaultProp: defaultEmoji,
28
+ });
29
+
30
+ const [emojiPickerOpen, setEmojiPickerOpen] = useState<boolean>(false);
31
+
32
+ return (
33
+ <>
34
+ <Popover.Root open={emojiPickerOpen} onOpenChange={setEmojiPickerOpen}>
35
+ <Popover.Trigger asChild>
36
+ <Button variant='ghost' classNames='gap-2 text-2xl plb-1' disabled={disabled}>
37
+ <span className='sr-only'>{t('select emoji label')}</span>
38
+ <span className='grow pis-14'>{emojiValue}</span>
39
+ <CaretDown className={getSize(4)} />
40
+ </Button>
41
+ </Popover.Trigger>
42
+ <Popover.Content
43
+ side='right'
44
+ onKeyDownCapture={(event) => {
45
+ if (event.key === 'Escape') {
46
+ event.stopPropagation();
47
+ setEmojiPickerOpen(false);
48
+ }
49
+ }}
50
+ >
51
+ <EmojiMart
52
+ data={emojiData}
53
+ onEmojiSelect={({ native }: { native?: string }) => {
54
+ if (native) {
55
+ setEmojiValue(native);
56
+ setEmojiPickerOpen(false);
57
+ }
58
+ }}
59
+ autoFocus={true}
60
+ maxFrequentRows={0}
61
+ noCountryFlags={true}
62
+ />
63
+ <Popover.Arrow />
64
+ </Popover.Content>
65
+ </Popover.Root>
66
+ <Tooltip.Root>
67
+ <Tooltip.Trigger asChild>
68
+ <Button variant='ghost' onClick={onClickClear} disabled={disabled}>
69
+ <span className='sr-only'>{t('clear label')}</span>
70
+ <ArrowCounterClockwise />
71
+ </Button>
72
+ </Tooltip.Trigger>
73
+ <Tooltip.Portal>
74
+ <Tooltip.Content style={{ zIndex: 70 }} side='right'>
75
+ {t('clear label')}
76
+ <Tooltip.Arrow />
77
+ </Tooltip.Content>
78
+ </Tooltip.Portal>
79
+ </Tooltip.Root>
80
+ </>
81
+ );
82
+ };
@@ -0,0 +1,87 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+ import { ArrowCounterClockwise, CaretDown, Check } from '@phosphor-icons/react';
5
+ import { useControllableState } from '@radix-ui/react-use-controllable-state';
6
+ import React, { type Dispatch, type SetStateAction } from 'react';
7
+
8
+ import { Button, useTranslation, Tooltip, DropdownMenu, useThemeContext, type ButtonProps } from '@dxos/react-ui';
9
+ import { getSize, hueTokenThemes } from '@dxos/react-ui-theme';
10
+
11
+ const HuePreview = ({ hue }: { hue: string }) => {
12
+ const { tx } = useThemeContext();
13
+ return (
14
+ <svg width={12} height={12} viewBox='0 0 12 12'>
15
+ <rect x={0} y={0} width={12} height={12} className={tx('hue.fill', 'select--hue__preview', { hue })} />
16
+ </svg>
17
+ );
18
+ };
19
+
20
+ export type HuePickerProps = {
21
+ disabled?: boolean;
22
+ defaultHue?: string;
23
+ hue?: string;
24
+ onChangeHue?: Dispatch<SetStateAction<string>>;
25
+ onClickClear?: ButtonProps['onClick'];
26
+ };
27
+
28
+ export const HuePicker = ({ disabled, hue, onChangeHue, defaultHue, onClickClear }: HuePickerProps) => {
29
+ const { t } = useTranslation('os');
30
+
31
+ const [hueValue, setHueValue] = useControllableState<string>({
32
+ prop: hue,
33
+ onChange: onChangeHue,
34
+ defaultProp: defaultHue,
35
+ });
36
+
37
+ return (
38
+ <>
39
+ <DropdownMenu.Root modal={false}>
40
+ <DropdownMenu.Trigger asChild>
41
+ <Button variant='ghost' classNames='gap-2 plb-1' disabled={disabled}>
42
+ <span className='sr-only'>{t('select hue label')}</span>
43
+ <div role='none' className='pis-14 grow flex items-center justify-center gap-2'>
44
+ <HuePreview hue={hueValue!} />
45
+ <span>{t(`${hueValue} label`)}</span>
46
+ </div>
47
+ <CaretDown className={getSize(4)} />
48
+ </Button>
49
+ </DropdownMenu.Trigger>
50
+ <DropdownMenu.Content side='right'>
51
+ <DropdownMenu.Viewport>
52
+ {Object.keys(hueTokenThemes).map((hue) => {
53
+ return (
54
+ <DropdownMenu.CheckboxItem
55
+ key={hue}
56
+ checked={hue === hueValue}
57
+ onCheckedChange={() => setHueValue(hue)}
58
+ >
59
+ <HuePreview hue={hue} />
60
+ <span className='grow'>{t(`${hue} label`)}</span>
61
+ <DropdownMenu.ItemIndicator>
62
+ <Check />
63
+ </DropdownMenu.ItemIndicator>
64
+ </DropdownMenu.CheckboxItem>
65
+ );
66
+ })}
67
+ </DropdownMenu.Viewport>
68
+ <DropdownMenu.Arrow />
69
+ </DropdownMenu.Content>
70
+ </DropdownMenu.Root>
71
+ <Tooltip.Root>
72
+ <Tooltip.Trigger asChild>
73
+ <Button variant='ghost' onClick={onClickClear} disabled={disabled}>
74
+ <span className='sr-only'>{t('clear label')}</span>
75
+ <ArrowCounterClockwise />
76
+ </Button>
77
+ </Tooltip.Trigger>
78
+ <Tooltip.Portal>
79
+ <Tooltip.Content style={{ zIndex: 70 }} side='right'>
80
+ {t('clear label')}
81
+ <Tooltip.Arrow />
82
+ </Tooltip.Content>
83
+ </Tooltip.Portal>
84
+ </Tooltip.Root>
85
+ </>
86
+ );
87
+ };
@@ -7,8 +7,9 @@ import React, { type ComponentPropsWithoutRef, forwardRef } from 'react';
7
7
  import { generateName } from '@dxos/display-name';
8
8
  import { SpaceMember } from '@dxos/react-client/echo';
9
9
  import { type Identity } from '@dxos/react-client/halo';
10
- import { ListItem, Avatar, useJdenticonHref, useId, type ThemedClassName } from '@dxos/react-ui';
10
+ import { ListItem, Avatar, useId, type ThemedClassName } from '@dxos/react-ui';
11
11
  import { mx } from '@dxos/react-ui-theme';
12
+ import { keyToFallback } from '@dxos/util';
12
13
 
13
14
  type IdentityListItemProps = {
14
15
  identity: Identity;
@@ -20,9 +21,8 @@ export const IdentityListItem = forwardRef<
20
21
  HTMLLIElement,
21
22
  ThemedClassName<ComponentPropsWithoutRef<'li'>> & IdentityListItemProps
22
23
  >(({ identity, presence, onClick, classNames, ...props }, forwardedRef) => {
23
- const fallbackValue = identity.identityKey.toHex();
24
+ const fallbackValue = keyToFallback(identity.identityKey);
24
25
  const labelId = useId('identityListItem__label');
25
- const jdenticon = useJdenticonHref(fallbackValue ?? '', 12);
26
26
  const displayName = identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
27
27
  return (
28
28
  <ListItem.Root
@@ -33,9 +33,13 @@ export const IdentityListItem = forwardRef<
33
33
  labelId={labelId}
34
34
  ref={forwardedRef}
35
35
  >
36
- <Avatar.Root status={presence === SpaceMember.PresenceState.ONLINE ? 'active' : 'inactive'} labelId={labelId}>
36
+ <Avatar.Root
37
+ status={presence === SpaceMember.PresenceState.ONLINE ? 'active' : 'inactive'}
38
+ labelId={labelId}
39
+ hue={identity.profile?.data?.hue || fallbackValue.hue}
40
+ >
37
41
  <Avatar.Frame classNames='place-self-center'>
38
- <Avatar.Fallback href={jdenticon} />
42
+ <Avatar.Fallback text={identity.profile?.data?.emoji || fallbackValue.emoji} />
39
43
  </Avatar.Frame>
40
44
  <Avatar.Label classNames='text-sm truncate pli-2'>{displayName}</Avatar.Label>
41
45
  </Avatar.Root>
@@ -21,9 +21,9 @@ import {
21
21
  type ThemedClassName,
22
22
  } from '@dxos/react-ui';
23
23
  import { focusRing, getSize, mx } from '@dxos/react-ui-theme';
24
+ import { hexToEmoji } from '@dxos/util';
24
25
 
25
26
  import { type SharedInvitationListProps } from './InvitationListProps';
26
- import { toEmoji } from '../../util';
27
27
  import { AuthCode } from '../AuthCode';
28
28
  import { CopyButtonIconOnly } from '../Clipboard';
29
29
 
@@ -151,7 +151,7 @@ export const InvitationListItemImpl = ({
151
151
  <Avatar.Root {...avatarProps} animation={avatarAnimation} status={avatarStatus}>
152
152
  <Tooltip.Trigger asChild>
153
153
  <Avatar.Frame tabIndex={0} classNames={[focusRing, 'relative rounded-full place-self-center']}>
154
- <Avatar.Fallback text={toEmoji(invitationId)} />
154
+ <Avatar.Fallback text={hexToEmoji(invitationId)} />
155
155
  </Avatar.Frame>
156
156
  </Tooltip.Trigger>
157
157
  </Avatar.Root>
@@ -5,15 +5,14 @@
5
5
  import React, { type ForwardedRef, forwardRef } from 'react';
6
6
 
7
7
  import type { Space } from '@dxos/react-client/echo';
8
- import { Avatar, useId, useJdenticonHref } from '@dxos/react-ui';
8
+ import { Avatar, useId } from '@dxos/react-ui';
9
9
  import { mx } from '@dxos/react-ui-theme';
10
- import { humanize } from '@dxos/util';
10
+ import { humanize, keyToEmoji } from '@dxos/util';
11
11
 
12
12
  export const SpaceListItem = forwardRef(
13
13
  ({ space, onClick }: { space: Space; onClick?: () => void }, ref: ForwardedRef<HTMLLIElement>) => {
14
- const fallbackValue = space.key.toHex();
14
+ const fallbackValue = keyToEmoji(space.key);
15
15
  const labelId = useId('identityListItem__label');
16
- const jdenticon = useJdenticonHref(fallbackValue ?? '', 12);
17
16
  const displayName = space.properties.name ?? humanize(space.key.toHex());
18
17
 
19
18
  return (
@@ -25,7 +24,7 @@ export const SpaceListItem = forwardRef(
25
24
  >
26
25
  <Avatar.Root labelId={labelId}>
27
26
  <Avatar.Frame>
28
- <Avatar.Fallback href={jdenticon} />
27
+ <Avatar.Fallback text={fallbackValue} />
29
28
  </Avatar.Frame>
30
29
  <Avatar.Label classNames='text-sm truncate'>{displayName}</Avatar.Label>
31
30
  </Avatar.Root>
@@ -4,6 +4,8 @@
4
4
 
5
5
  export * from './Clipboard';
6
6
  export * from './CompoundButton';
7
+ export * from './EmojiPicker';
8
+ export * from './HuePicker';
7
9
  export * from './IdentityList';
8
10
  export * from './InvitationList';
9
11
  export * from './Panel';
@@ -9,7 +9,8 @@ import { useClient } from '@dxos/react-client';
9
9
  import { type Identity, useIdentity, useDevices, useHaloInvitations } from '@dxos/react-client/halo';
10
10
  import { useInvitationStatus } from '@dxos/react-client/invitations';
11
11
  import type { CancellableInvitationObservable } from '@dxos/react-client/invitations';
12
- import { Avatar, DensityProvider, useId, useJdenticonHref, useTranslation } from '@dxos/react-ui';
12
+ import { Avatar, DensityProvider, useId, useTranslation } from '@dxos/react-ui';
13
+ import { keyToFallback } from '@dxos/util';
13
14
 
14
15
  import {
15
16
  type IdentityPanelHeadingProps,
@@ -25,12 +26,12 @@ import { InvitationManager } from '../../steps';
25
26
  const viewStyles = 'pbs-1 pbe-3 pli-3';
26
27
 
27
28
  const IdentityHeading = ({ titleId, title, identity, onDone }: IdentityPanelHeadingProps) => {
28
- const fallbackHref = useJdenticonHref(identity.identityKey.toHex(), 12);
29
+ const fallbackValue = keyToFallback(identity.identityKey);
29
30
  return (
30
31
  <Heading titleId={titleId} title={title} corner={<CloseButton onDone={onDone} />}>
31
- <Avatar.Root size={12} variant='circle' status='active'>
32
+ <Avatar.Root size={12} variant='circle' status='active' hue={identity.profile?.data?.hue || fallbackValue.hue}>
32
33
  <Avatar.Frame classNames='block mbs-4 mbe-2 mli-auto chromatic-ignore'>
33
- <Avatar.Fallback href={fallbackHref} />
34
+ <Avatar.Fallback text={identity.profile?.data?.emoji || fallbackValue.emoji} />
34
35
  </Avatar.Frame>
35
36
  <Avatar.Label classNames='block text-center font-light text-xl' data-testid='identityHeading.displayName'>
36
37
  {identity.profile?.displayName ?? generateName(identity.identityKey.toHex())}
@@ -8,8 +8,9 @@ import { type Event, type SingleOrArray } from 'xstate';
8
8
  import { log } from '@dxos/log';
9
9
  import { type Identity } from '@dxos/react-client/halo';
10
10
  import { useTranslation } from '@dxos/react-ui';
11
+ import { hexToEmoji, hexToHue } from '@dxos/util';
11
12
 
12
- import { Action, Actions, StepHeading, Input, useClipboardContext } from '../../../components';
13
+ import { Action, Actions, StepHeading, Input, useClipboardContext, EmojiPicker, HuePicker } from '../../../components';
13
14
  import { type IdentityPanelStepProps } from '../IdentityPanelProps';
14
15
  import { type IdentityEvent } from '../identityMachine';
15
16
 
@@ -36,13 +37,20 @@ export const ProfileForm = (props: ProfileFormProps) => {
36
37
  return <ProfileFormImpl {...props} onUpdateProfile={handleUpdateProfile} validationMessage={validationMessage} />;
37
38
  };
38
39
 
40
+ const getHueValue = (identity?: Identity) =>
41
+ identity?.profile?.data?.hue || hexToHue(identity?.identityKey.toHex() ?? '0');
42
+ const getEmojiValue = (identity?: Identity) =>
43
+ identity?.profile?.data?.emoji || hexToEmoji(identity?.identityKey.toHex() ?? '0');
44
+
39
45
  // TODO(zhenyasav): impl shouldn't need send()
40
46
  const ProfileFormImpl = (props: ProfileFormImplProps) => {
41
47
  const { active, identity, send, onUpdateProfile, validationMessage } = props;
42
48
  const profile = identity?.profile;
43
49
  const disabled = !active;
44
50
  const { t } = useTranslation('os');
45
- const [inputValue, setInputValue] = useState(profile?.displayName ?? '');
51
+ const [displayName, setDisplayName] = useState(profile?.displayName ?? '');
52
+ const [hue, setHue] = useState<string>(getHueValue(identity));
53
+ const [emoji, setEmoji] = useState<string>(getEmojiValue(identity));
46
54
  const { textValue, setTextValue } = useClipboardContext();
47
55
  const identityHex = identity?.identityKey.toHex();
48
56
  const copied = textValue === identityHex;
@@ -51,14 +59,28 @@ const ProfileFormImpl = (props: ProfileFormImplProps) => {
51
59
  <div role='none' className='grow flex flex-col justify-center'>
52
60
  <Input
53
61
  {...{ validationMessage }}
54
- label={<StepHeading>{t('display name input label')}</StepHeading>}
62
+ label={<StepHeading className='m-0'>{t('display name input label')}</StepHeading>}
55
63
  disabled={disabled}
56
64
  data-testid='display-name-input'
57
65
  placeholder={t('display name input placeholder')}
58
- value={inputValue}
59
- onChange={({ target: { value } }) => setInputValue(value)}
60
- onKeyDown={({ key }) => key === 'Enter' && onUpdateProfile?.({ displayName: inputValue })}
66
+ value={displayName}
67
+ onChange={({ target: { value } }) => setDisplayName(value)}
61
68
  />
69
+ <StepHeading className='mbe-2'>{t('emoji and color label')}</StepHeading>
70
+ <div role='none' className='grid grid-cols-[1fr_min-content] gap-y-2'>
71
+ <EmojiPicker
72
+ emoji={emoji}
73
+ onChangeEmoji={setEmoji}
74
+ disabled={disabled}
75
+ onClickClear={() => setEmoji(getEmojiValue(identity))}
76
+ />
77
+ <HuePicker
78
+ hue={hue}
79
+ onChangeHue={setHue}
80
+ disabled={disabled}
81
+ onClickClear={() => setHue(getHueValue(identity))}
82
+ />
83
+ </div>
62
84
  </div>
63
85
  <Actions>
64
86
  <Action
@@ -84,7 +106,7 @@ const ProfileFormImpl = (props: ProfileFormImplProps) => {
84
106
  <Action
85
107
  variant='primary'
86
108
  disabled={disabled}
87
- onClick={() => onUpdateProfile?.({ displayName: inputValue })}
109
+ onClick={() => onUpdateProfile?.({ displayName, data: { emoji, hue } })}
88
110
  data-testid='update-profile-form-continue'
89
111
  >
90
112
  {t('done label')}
@@ -6,8 +6,9 @@ import React, { cloneElement } from 'react';
6
6
 
7
7
  import { generateName } from '@dxos/display-name';
8
8
  import type { Identity } from '@dxos/react-client/halo';
9
- import { Avatar, useId, useJdenticonHref, useTranslation } from '@dxos/react-ui';
9
+ import { Avatar, useId, useTranslation } from '@dxos/react-ui';
10
10
  import { mx } from '@dxos/react-ui-theme';
11
+ import { hexToFallback } from '@dxos/util';
11
12
 
12
13
  import { Action, Actions, StepHeading } from '../../../components';
13
14
  import { type JoinPanelMode, type JoinStepProps } from '../JoinPanelProps';
@@ -22,11 +23,10 @@ export const IdentityAdded = (props: IdentityAddedProps) => {
22
23
  const disabled = !active;
23
24
  const { t } = useTranslation('os');
24
25
 
25
- const fallbackValue = addedIdentity?.identityKey.toHex();
26
+ const addedIdentityHex = addedIdentity?.identityKey.toHex() ?? '0';
27
+ const fallbackValue = hexToFallback(addedIdentityHex);
26
28
  const labelId = useId('identityListItem__label');
27
- const jdenticon = useJdenticonHref(fallbackValue ?? '', 12);
28
- const displayName =
29
- addedIdentity?.profile?.displayName ?? (addedIdentity && generateName(addedIdentity?.identityKey.toHex()));
29
+ const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName(addedIdentityHex));
30
30
 
31
31
  const doneAction = (
32
32
  <Action
@@ -43,9 +43,9 @@ export const IdentityAdded = (props: IdentityAddedProps) => {
43
43
  <>
44
44
  <StepHeading>{t('identity added label')}</StepHeading>
45
45
  <div role='none' className='grow flex flex-col items-center justify-center text-center gap-2'>
46
- <Avatar.Root status='active' labelId={labelId}>
46
+ <Avatar.Root status='active' labelId={labelId} hue={addedIdentity?.profile?.data?.hue || fallbackValue.hue}>
47
47
  <Avatar.Frame>
48
- <Avatar.Fallback href={jdenticon} />
48
+ <Avatar.Fallback text={addedIdentity?.profile?.data?.emoji || fallbackValue.emoji} />
49
49
  </Avatar.Frame>
50
50
  <Avatar.Label classNames={mx('text-lg truncate', !addedIdentity?.profile?.displayName && 'font-mono')}>
51
51
  {displayName}