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

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 +21882 -64428
  2. package/dist/bundle/shell.mjs.map +1 -1
  3. package/dist/bundle/shell.umd.js +78 -793
  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 +591 -766
  8. package/dist/lib/browser/react.mjs.map +4 -4
  9. package/dist/types/src/components/IdentityList/IdentityListItem.d.ts.map +1 -1
  10. package/dist/types/src/components/IdentityList/IdentityListItem.js +5 -5
  11. package/dist/types/src/components/IdentityList/IdentityListItem.js.map +1 -1
  12. package/dist/types/src/components/InvitationList/InvitationListItem.d.ts.map +1 -1
  13. package/dist/types/src/components/InvitationList/InvitationListItem.js +2 -2
  14. package/dist/types/src/components/InvitationList/InvitationListItem.js.map +1 -1
  15. package/dist/types/src/components/SpaceListItem.d.ts.map +1 -1
  16. package/dist/types/src/components/SpaceListItem.js +3 -2
  17. package/dist/types/src/components/SpaceListItem.js.map +1 -1
  18. package/dist/types/src/components/index.d.ts +0 -2
  19. package/dist/types/src/components/index.d.ts.map +1 -1
  20. package/dist/types/src/components/index.js +0 -2
  21. package/dist/types/src/components/index.js.map +1 -1
  22. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  23. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +5 -6
  24. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  25. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -1
  26. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +3 -12
  27. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -1
  28. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.d.ts.map +1 -1
  29. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js +7 -8
  30. package/dist/types/src/panels/JoinPanel/steps/IdentityAdded.js.map +1 -1
  31. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js +2 -2
  32. package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js.map +1 -1
  33. package/dist/types/src/steps/InvitationManager.d.ts.map +1 -1
  34. package/dist/types/src/steps/InvitationManager.js +4 -5
  35. package/dist/types/src/steps/InvitationManager.js.map +1 -1
  36. package/dist/types/src/translations/locales/en-US.d.ts +0 -21
  37. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  38. package/dist/types/src/translations/locales/en-US.js +0 -21
  39. package/dist/types/src/translations/locales/en-US.js.map +1 -1
  40. package/dist/types/src/util/index.d.ts +1 -0
  41. package/dist/types/src/util/index.d.ts.map +1 -1
  42. package/dist/types/src/util/index.js +1 -0
  43. package/dist/types/src/util/index.js.map +1 -1
  44. package/dist/types/src/util/toEmoji.d.ts +2 -0
  45. package/dist/types/src/util/toEmoji.d.ts.map +1 -0
  46. package/dist/types/src/util/toEmoji.js +26 -0
  47. package/dist/types/src/util/toEmoji.js.map +1 -0
  48. package/package.json +21 -22
  49. package/src/components/IdentityList/IdentityListItem.tsx +5 -9
  50. package/src/components/InvitationList/InvitationListItem.tsx +2 -2
  51. package/src/components/SpaceListItem.tsx +5 -4
  52. package/src/components/index.ts +0 -2
  53. package/src/panels/IdentityPanel/IdentityPanel.tsx +4 -5
  54. package/src/panels/IdentityPanel/steps/ProfileForm.tsx +7 -28
  55. package/src/panels/JoinPanel/steps/IdentityAdded.tsx +7 -7
  56. package/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx +2 -2
  57. package/src/steps/InvitationManager.tsx +3 -4
  58. package/src/translations/locales/en-US.ts +0 -21
  59. package/src/util/index.ts +1 -0
  60. package/src/util/toEmoji.ts +22 -0
  61. package/dist/types/src/components/EmojiPicker.d.ts +0 -11
  62. package/dist/types/src/components/EmojiPicker.d.ts.map +0 -1
  63. package/dist/types/src/components/EmojiPicker.js +0 -79
  64. package/dist/types/src/components/EmojiPicker.js.map +0 -1
  65. package/dist/types/src/components/HuePicker.d.ts +0 -11
  66. package/dist/types/src/components/HuePicker.d.ts.map +0 -1
  67. package/dist/types/src/components/HuePicker.js +0 -56
  68. package/dist/types/src/components/HuePicker.js.map +0 -1
  69. package/src/components/EmojiPicker.tsx +0 -82
  70. package/src/components/HuePicker.tsx +0 -87
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toEmoji.js","sourceRoot":"","sources":["../../../../src/util/toEmoji.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;AAEF,oEAAqC;AAErC,MAAM,KAAK,GAAG,IAAA,wBAAO;AACnB,kIAAkI;AAClI,iLAAiL;AACjL,kGAAkG;AAClG,iDAAiD;AACjD,cAAc;AACd,gCAAgC;AAChC,6BAA6B;AAC7B,uDAAuD;AACvD,gDAAgD;AAChD,gFAAgF;AAChF,qCAAqC;AACrC,mRAAmR,CACpR,CAAC;AAEK,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AAA7E,QAAA,OAAO,WAAsE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/shell",
3
- "version": "0.4.7-main.ea67fec",
3
+ "version": "0.4.7-main.f9d3866",
4
4
  "description": "DXOS’s OS experiences",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -28,8 +28,6 @@
28
28
  "src"
29
29
  ],
30
30
  "dependencies": {
31
- "@emoji-mart/data": "^1.1.2",
32
- "@emoji-mart/react": "^1.1.1",
33
31
  "@fluentui/react-tabster": "^9.19.0",
34
32
  "@radix-ui/react-accordion": "^1.1.1",
35
33
  "@radix-ui/react-context": "^1.0.0",
@@ -37,26 +35,27 @@
37
35
  "@radix-ui/react-use-controllable-state": "^1.0.0",
38
36
  "@react-hook/async": "^3.1.1",
39
37
  "@xstate/react": "^3.2.1",
40
- "emoji-mart": "^5.5.2",
38
+ "lodash.toarray": "^4.4.0",
41
39
  "react-qr-rounded": "^1.0.0",
42
40
  "url-join": "^5.0.0",
43
41
  "xstate": "^4.37.0",
44
- "@dxos/async": "0.4.7-main.ea67fec",
45
- "@dxos/client-services": "0.4.7-main.ea67fec",
46
- "@dxos/debug": "0.4.7-main.ea67fec",
47
- "@dxos/display-name": "0.4.7-main.ea67fec",
48
- "@dxos/client-protocol": "0.4.7-main.ea67fec",
49
- "@dxos/invariant": "0.4.7-main.ea67fec",
50
- "@dxos/react-client": "0.4.7-main.ea67fec",
51
- "@dxos/react-ui": "0.4.7-main.ea67fec",
52
- "@dxos/react-ui-theme": "0.4.7-main.ea67fec",
53
- "@dxos/react-ui-types": "0.4.7-main.ea67fec",
54
- "@dxos/rpc-tunnel": "0.4.7-main.ea67fec",
55
- "@dxos/log": "0.4.7-main.ea67fec",
56
- "@dxos/util": "0.4.7-main.ea67fec"
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"
57
55
  },
58
56
  "devDependencies": {
59
57
  "@phosphor-icons/react": "^2.0.5",
58
+ "@types/lodash.toarray": "^4.4.7",
60
59
  "@types/react": "^18.0.21",
61
60
  "@types/react-dom": "^18.0.6",
62
61
  "@vitejs/plugin-react": "^4.2.1",
@@ -64,11 +63,11 @@
64
63
  "react-dom": "^18.2.0",
65
64
  "vite": "^5.1.3",
66
65
  "vite-plugin-turbosnap": "^1.0.2",
67
- "@dxos/config": "0.4.7-main.ea67fec",
68
- "@dxos/react-async": "0.4.7-main.ea67fec",
69
- "@dxos/react-ui-theme": "0.4.7-main.ea67fec",
70
- "@dxos/storybook-utils": "0.4.7-main.ea67fec",
71
- "@dxos/random": "0.4.7-main.ea67fec"
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"
72
71
  },
73
72
  "peerDependencies": {
74
73
  "@phosphor-icons/react": "^2.0.5",
@@ -7,9 +7,8 @@ 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, useId, type ThemedClassName } from '@dxos/react-ui';
10
+ import { ListItem, Avatar, useJdenticonHref, useId, type ThemedClassName } from '@dxos/react-ui';
11
11
  import { mx } from '@dxos/react-ui-theme';
12
- import { keyToFallback } from '@dxos/util';
13
12
 
14
13
  type IdentityListItemProps = {
15
14
  identity: Identity;
@@ -21,8 +20,9 @@ export const IdentityListItem = forwardRef<
21
20
  HTMLLIElement,
22
21
  ThemedClassName<ComponentPropsWithoutRef<'li'>> & IdentityListItemProps
23
22
  >(({ identity, presence, onClick, classNames, ...props }, forwardedRef) => {
24
- const fallbackValue = keyToFallback(identity.identityKey);
23
+ const fallbackValue = identity.identityKey.toHex();
25
24
  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,13 +33,9 @@ export const IdentityListItem = forwardRef<
33
33
  labelId={labelId}
34
34
  ref={forwardedRef}
35
35
  >
36
- <Avatar.Root
37
- status={presence === SpaceMember.PresenceState.ONLINE ? 'active' : 'inactive'}
38
- labelId={labelId}
39
- hue={identity.profile?.hue || fallbackValue.hue}
40
- >
36
+ <Avatar.Root status={presence === SpaceMember.PresenceState.ONLINE ? 'active' : 'inactive'} labelId={labelId}>
41
37
  <Avatar.Frame classNames='place-self-center'>
42
- <Avatar.Fallback text={identity.profile?.emoji || fallbackValue.emoji} />
38
+ <Avatar.Fallback href={jdenticon} />
43
39
  </Avatar.Frame>
44
40
  <Avatar.Label classNames='text-sm truncate pli-2'>{displayName}</Avatar.Label>
45
41
  </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';
25
24
 
26
25
  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={hexToEmoji(invitationId)} />
154
+ <Avatar.Fallback text={toEmoji(invitationId)} />
155
155
  </Avatar.Frame>
156
156
  </Tooltip.Trigger>
157
157
  </Avatar.Root>
@@ -5,14 +5,15 @@
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 } from '@dxos/react-ui';
8
+ import { Avatar, useId, useJdenticonHref } from '@dxos/react-ui';
9
9
  import { mx } from '@dxos/react-ui-theme';
10
- import { humanize, keyToEmoji } from '@dxos/util';
10
+ import { humanize } 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 = keyToEmoji(space.key);
14
+ const fallbackValue = space.key.toHex();
15
15
  const labelId = useId('identityListItem__label');
16
+ const jdenticon = useJdenticonHref(fallbackValue ?? '', 12);
16
17
  const displayName = space.properties.name ?? humanize(space.key.toHex());
17
18
 
18
19
  return (
@@ -24,7 +25,7 @@ export const SpaceListItem = forwardRef(
24
25
  >
25
26
  <Avatar.Root labelId={labelId}>
26
27
  <Avatar.Frame>
27
- <Avatar.Fallback text={fallbackValue} />
28
+ <Avatar.Fallback href={jdenticon} />
28
29
  </Avatar.Frame>
29
30
  <Avatar.Label classNames='text-sm truncate'>{displayName}</Avatar.Label>
30
31
  </Avatar.Root>
@@ -4,8 +4,6 @@
4
4
 
5
5
  export * from './Clipboard';
6
6
  export * from './CompoundButton';
7
- export * from './EmojiPicker';
8
- export * from './HuePicker';
9
7
  export * from './IdentityList';
10
8
  export * from './InvitationList';
11
9
  export * from './Panel';
@@ -9,8 +9,7 @@ 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, useTranslation } from '@dxos/react-ui';
13
- import { keyToFallback } from '@dxos/util';
12
+ import { Avatar, DensityProvider, useId, useJdenticonHref, useTranslation } from '@dxos/react-ui';
14
13
 
15
14
  import {
16
15
  type IdentityPanelHeadingProps,
@@ -26,12 +25,12 @@ import { InvitationManager } from '../../steps';
26
25
  const viewStyles = 'pbs-1 pbe-3 pli-3';
27
26
 
28
27
  const IdentityHeading = ({ titleId, title, identity, onDone }: IdentityPanelHeadingProps) => {
29
- const fallbackValue = keyToFallback(identity.identityKey);
28
+ const fallbackHref = useJdenticonHref(identity.identityKey.toHex(), 12);
30
29
  return (
31
30
  <Heading titleId={titleId} title={title} corner={<CloseButton onDone={onDone} />}>
32
- <Avatar.Root size={12} variant='circle' status='active' hue={identity.profile?.hue || fallbackValue.hue}>
31
+ <Avatar.Root size={12} variant='circle' status='active'>
33
32
  <Avatar.Frame classNames='block mbs-4 mbe-2 mli-auto chromatic-ignore'>
34
- <Avatar.Fallback text={identity.profile?.emoji || fallbackValue.emoji} />
33
+ <Avatar.Fallback href={fallbackHref} />
35
34
  </Avatar.Frame>
36
35
  <Avatar.Label classNames='block text-center font-light text-xl' data-testid='identityHeading.displayName'>
37
36
  {identity.profile?.displayName ?? generateName(identity.identityKey.toHex())}
@@ -8,9 +8,8 @@ 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';
12
11
 
13
- import { Action, Actions, StepHeading, Input, useClipboardContext, EmojiPicker, HuePicker } from '../../../components';
12
+ import { Action, Actions, StepHeading, Input, useClipboardContext } from '../../../components';
14
13
  import { type IdentityPanelStepProps } from '../IdentityPanelProps';
15
14
  import { type IdentityEvent } from '../identityMachine';
16
15
 
@@ -37,19 +36,13 @@ export const ProfileForm = (props: ProfileFormProps) => {
37
36
  return <ProfileFormImpl {...props} onUpdateProfile={handleUpdateProfile} validationMessage={validationMessage} />;
38
37
  };
39
38
 
40
- const getHueValue = (identity?: Identity) => identity?.profile?.hue || hexToHue(identity?.identityKey.toHex() ?? '0');
41
- const getEmojiValue = (identity?: Identity) =>
42
- identity?.profile?.emoji || hexToEmoji(identity?.identityKey.toHex() ?? '0');
43
-
44
39
  // TODO(zhenyasav): impl shouldn't need send()
45
40
  const ProfileFormImpl = (props: ProfileFormImplProps) => {
46
41
  const { active, identity, send, onUpdateProfile, validationMessage } = props;
47
42
  const profile = identity?.profile;
48
43
  const disabled = !active;
49
44
  const { t } = useTranslation('os');
50
- const [displayName, setDisplayName] = useState(profile?.displayName ?? '');
51
- const [hue, setHue] = useState<string>(getHueValue(identity));
52
- const [emoji, setEmoji] = useState<string>(getEmojiValue(identity));
45
+ const [inputValue, setInputValue] = useState(profile?.displayName ?? '');
53
46
  const { textValue, setTextValue } = useClipboardContext();
54
47
  const identityHex = identity?.identityKey.toHex();
55
48
  const copied = textValue === identityHex;
@@ -58,28 +51,14 @@ const ProfileFormImpl = (props: ProfileFormImplProps) => {
58
51
  <div role='none' className='grow flex flex-col justify-center'>
59
52
  <Input
60
53
  {...{ validationMessage }}
61
- label={<StepHeading className='m-0'>{t('display name input label')}</StepHeading>}
54
+ label={<StepHeading>{t('display name input label')}</StepHeading>}
62
55
  disabled={disabled}
63
56
  data-testid='display-name-input'
64
57
  placeholder={t('display name input placeholder')}
65
- value={displayName}
66
- onChange={({ target: { value } }) => setDisplayName(value)}
58
+ value={inputValue}
59
+ onChange={({ target: { value } }) => setInputValue(value)}
60
+ onKeyDown={({ key }) => key === 'Enter' && onUpdateProfile?.({ displayName: inputValue })}
67
61
  />
68
- <StepHeading className='mbe-2'>{t('emoji and color label')}</StepHeading>
69
- <div role='none' className='grid grid-cols-[1fr_min-content] gap-y-2'>
70
- <EmojiPicker
71
- emoji={emoji}
72
- onChangeEmoji={setEmoji}
73
- disabled={disabled}
74
- onClickClear={() => setEmoji(getEmojiValue(identity))}
75
- />
76
- <HuePicker
77
- hue={hue}
78
- onChangeHue={setHue}
79
- disabled={disabled}
80
- onClickClear={() => setHue(getHueValue(identity))}
81
- />
82
- </div>
83
62
  </div>
84
63
  <Actions>
85
64
  <Action
@@ -105,7 +84,7 @@ const ProfileFormImpl = (props: ProfileFormImplProps) => {
105
84
  <Action
106
85
  variant='primary'
107
86
  disabled={disabled}
108
- onClick={() => onUpdateProfile?.({ displayName, emoji, hue })}
87
+ onClick={() => onUpdateProfile?.({ displayName: inputValue })}
109
88
  data-testid='update-profile-form-continue'
110
89
  >
111
90
  {t('done label')}
@@ -6,9 +6,8 @@ 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, useTranslation } from '@dxos/react-ui';
9
+ import { Avatar, useId, useJdenticonHref, useTranslation } from '@dxos/react-ui';
10
10
  import { mx } from '@dxos/react-ui-theme';
11
- import { hexToFallback } from '@dxos/util';
12
11
 
13
12
  import { Action, Actions, StepHeading } from '../../../components';
14
13
  import { type JoinPanelMode, type JoinStepProps } from '../JoinPanelProps';
@@ -23,10 +22,11 @@ export const IdentityAdded = (props: IdentityAddedProps) => {
23
22
  const disabled = !active;
24
23
  const { t } = useTranslation('os');
25
24
 
26
- const addedIdentityHex = addedIdentity?.identityKey.toHex() ?? '0';
27
- const fallbackValue = hexToFallback(addedIdentityHex);
25
+ const fallbackValue = addedIdentity?.identityKey.toHex();
28
26
  const labelId = useId('identityListItem__label');
29
- const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName(addedIdentityHex));
27
+ const jdenticon = useJdenticonHref(fallbackValue ?? '', 12);
28
+ const displayName =
29
+ addedIdentity?.profile?.displayName ?? (addedIdentity && generateName(addedIdentity?.identityKey.toHex()));
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} hue={addedIdentity?.profile?.hue || fallbackValue.hue}>
46
+ <Avatar.Root status='active' labelId={labelId}>
47
47
  <Avatar.Frame>
48
- <Avatar.Fallback text={addedIdentity?.profile?.emoji || fallbackValue.emoji} />
48
+ <Avatar.Fallback href={jdenticon} />
49
49
  </Avatar.Frame>
50
50
  <Avatar.Label classNames={mx('text-lg truncate', !addedIdentity?.profile?.displayName && 'font-mono')}>
51
51
  {displayName}
@@ -5,9 +5,9 @@
5
5
  import React, { type ChangeEvent, useState } from 'react';
6
6
 
7
7
  import { Input, useTranslation } from '@dxos/react-ui';
8
- import { hexToEmoji } from '@dxos/util';
9
8
 
10
9
  import { Actions, Action, Emoji, StepHeading } from '../../../components';
10
+ import { toEmoji } from '../../../util';
11
11
  import { type JoinStepProps } from '../JoinPanelProps';
12
12
 
13
13
  const pinLength = 6;
@@ -45,7 +45,7 @@ export const InvitationAuthenticator = ({
45
45
  return (
46
46
  <>
47
47
  <div role='none' className='grow flex flex-col justify-center'>
48
- {invitationId && <Emoji text={hexToEmoji(invitationId)} />}
48
+ {invitationId && <Emoji text={toEmoji(invitationId)} />}
49
49
  <Input.Root
50
50
  {...(failed && {
51
51
  validationValence: 'error',
@@ -9,7 +9,6 @@ import { QR } from 'react-qr-rounded';
9
9
  import { type InvitationStatus, Invitation } from '@dxos/react-client/invitations';
10
10
  import { useId, useTranslation } from '@dxos/react-ui';
11
11
  import { descriptionText, getSize, mx } from '@dxos/react-ui-theme';
12
- import { hexToEmoji } from '@dxos/util';
13
12
 
14
13
  import { type StepProps } from './StepProps';
15
14
  import {
@@ -23,7 +22,7 @@ import {
23
22
  CopyButton,
24
23
  Centered,
25
24
  } from '../components';
26
- import { invitationStatusValue } from '../util';
25
+ import { invitationStatusValue, toEmoji } from '../util';
27
26
 
28
27
  export type InvitationManagerProps = StepProps &
29
28
  Partial<InvitationStatus> & {
@@ -45,13 +44,13 @@ export const InvitationManager = ({
45
44
  status,
46
45
  type,
47
46
  authCode,
48
- id = '0',
47
+ id,
49
48
  }: InvitationManagerProps) => {
50
49
  const { t } = useTranslation('os');
51
50
  const qrLabel = useId('invitation-manager__qr-code');
52
51
  const statusValue = type === Invitation.Type.MULTIUSE ? 0 : invitationStatusValue.get(status!) ?? 0;
53
52
  const showAuthCode = statusValue === 3;
54
- const emoji = hexToEmoji(id);
53
+ const emoji = toEmoji(id ?? '');
55
54
  const activeView = useMemo(() => {
56
55
  switch (true) {
57
56
  case statusValue === 5:
@@ -106,25 +106,4 @@ export const os = {
106
106
  'join new identity label': 'Join a new identity',
107
107
  'reset device label': 'Reset device',
108
108
  'reset device confirm message': 'Are you sure you want to reset your device? All data will be lost.',
109
- 'emoji and color label': 'Emoji and color',
110
- 'clear label': 'Use default',
111
- 'select emoji label': 'Choose an emoji to use in your avatar',
112
- 'select hue label': 'Choose a hue to use in your avatar',
113
- 'red label': 'Red',
114
- 'orange label': 'Orange',
115
- 'amber label': 'Amber',
116
- 'yellow label': 'Yellow',
117
- 'lime label': 'Lime',
118
- 'green label': 'Green',
119
- 'emerald label': 'Emerald',
120
- 'teal label': 'Teal',
121
- 'cyan label': 'Cyan',
122
- 'sky label': 'Sky',
123
- 'blue label': 'Blue',
124
- 'indigo label': 'Indigo',
125
- 'violet label': 'Violet',
126
- 'purple label': 'Purple',
127
- 'fuchsia label': 'Fuchsia',
128
- 'pink label': 'Pink',
129
- 'rose label': 'Rose',
130
109
  };
package/src/util/index.ts CHANGED
@@ -3,3 +3,4 @@
3
3
  //
4
4
 
5
5
  export * from './invitationStatusValue';
6
+ export * from './toEmoji';
@@ -0,0 +1,22 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import toArray from 'lodash.toarray';
6
+
7
+ const emoji = toArray(
8
+ // When changing this set, please check the result in a console or e.g. RunKit (https://runkit.com/thure/642214441dd6ae000855a8de)
9
+ // 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.
10
+ // This set was chosen from the characters in Unicode Emoji v15.0 based on the following criteria:
11
+ // – not people or isolated anthropomorphic faces
12
+ // – not flags
13
+ // – more concrete than abstract
14
+ // – less culturally specific
15
+ // – less easily confused with another emoji in the set
16
+ // – requires less special knowledge to identify
17
+ // – less likely to evoke negative feelings (no meat, no drugs, no weapons, etc)
18
+ // – less common as a signifier in UX
19
+ '👹👻👽🤖🎃🦾🦿🦷👣👁️🧶👑🐒🦆🦉🐴🦄🐝🦋🐞🪲🐢🦎🦕🦑🦀🐠🐬🐋🦭🐅🐆🦓🦍🦧🐘🐫🦒🦘🦬🐖🐏🦌🐕🐈🐓🦚🦜🦢🦩🦦🐁🐿️🌵🌲🌳🪵🌱🍁🪺🍄🐚🪸🪨🌾🌷🌻☀️🌙🪐⭐️⚡️☄️🔥🌈☁️💧⛱️🌊🍎🍋🍉🍇🫐🍈🍒🍑🥭🍍🥥🥝🥑🌶️🌽🥕🍬🥜🫖☕️🍵🧊🧂🏔️⚓️🛟🏝️🛶🚀🛰️⛲️🏰🚲⛺️🎙️🧲⚙️🔩🔮🔭🔬🧬🌡️🧺🛎️🔑🪑🧸🎈🎀🎊♻️🎵',
20
+ );
21
+
22
+ export const toEmoji = (keyAsHex: string) => emoji[parseInt(keyAsHex, 16) % emoji.length];
@@ -1,11 +0,0 @@
1
- import { type Dispatch, type SetStateAction } from 'react';
2
- import { type ButtonProps } from '@dxos/react-ui';
3
- export type EmojiPickerProps = {
4
- disabled?: boolean;
5
- defaultEmoji?: string;
6
- emoji?: string;
7
- onChangeEmoji?: Dispatch<SetStateAction<string>>;
8
- onClickClear?: ButtonProps['onClick'];
9
- };
10
- export declare const EmojiPicker: ({ disabled, defaultEmoji, emoji, onChangeEmoji, onClickClear }: EmojiPickerProps) => JSX.Element;
11
- //# sourceMappingURL=EmojiPicker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EmojiPicker.d.ts","sourceRoot":"","sources":["../../../../src/components/EmojiPicker.tsx"],"names":[],"mappings":"AAOA,OAAc,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAY,MAAM,OAAO,CAAC;AAE5E,OAAO,EAA4C,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG5F,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,YAAY,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,WAAW,mEAAoE,gBAAgB,gBA6D3G,CAAC"}
@@ -1,79 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.EmojiPicker = void 0;
30
- //
31
- // Copyright 2024 DXOS.org
32
- //
33
- const data_1 = __importDefault(require("@emoji-mart/data"));
34
- const react_1 = __importDefault(require("@emoji-mart/react"));
35
- const react_2 = require("@phosphor-icons/react");
36
- const react_use_controllable_state_1 = require("@radix-ui/react-use-controllable-state");
37
- const react_3 = __importStar(require("react"));
38
- const react_ui_1 = require("@dxos/react-ui");
39
- const react_ui_theme_1 = require("@dxos/react-ui-theme");
40
- const EmojiPicker = ({ disabled, defaultEmoji, emoji, onChangeEmoji, onClickClear }) => {
41
- const { t } = (0, react_ui_1.useTranslation)('os');
42
- const [emojiValue, setEmojiValue] = (0, react_use_controllable_state_1.useControllableState)({
43
- prop: emoji,
44
- onChange: onChangeEmoji,
45
- defaultProp: defaultEmoji,
46
- });
47
- const [emojiPickerOpen, setEmojiPickerOpen] = (0, react_3.useState)(false);
48
- return (react_3.default.createElement(react_3.default.Fragment, null,
49
- react_3.default.createElement(react_ui_1.Popover.Root, { open: emojiPickerOpen, onOpenChange: setEmojiPickerOpen },
50
- react_3.default.createElement(react_ui_1.Popover.Trigger, { asChild: true },
51
- react_3.default.createElement(react_ui_1.Button, { variant: 'ghost', classNames: 'gap-2 text-2xl plb-1', disabled: disabled },
52
- react_3.default.createElement("span", { className: 'sr-only' }, t('select emoji label')),
53
- react_3.default.createElement("span", { className: 'grow pis-14' }, emojiValue),
54
- react_3.default.createElement(react_2.CaretDown, { className: (0, react_ui_theme_1.getSize)(4) }))),
55
- react_3.default.createElement(react_ui_1.Popover.Content, { side: 'right', onKeyDownCapture: (event) => {
56
- if (event.key === 'Escape') {
57
- event.stopPropagation();
58
- setEmojiPickerOpen(false);
59
- }
60
- } },
61
- react_3.default.createElement(react_1.default, { data: data_1.default, onEmojiSelect: ({ native }) => {
62
- if (native) {
63
- setEmojiValue(native);
64
- setEmojiPickerOpen(false);
65
- }
66
- }, autoFocus: true, maxFrequentRows: 0, noCountryFlags: true }),
67
- react_3.default.createElement(react_ui_1.Popover.Arrow, null))),
68
- react_3.default.createElement(react_ui_1.Tooltip.Root, null,
69
- react_3.default.createElement(react_ui_1.Tooltip.Trigger, { asChild: true },
70
- react_3.default.createElement(react_ui_1.Button, { variant: 'ghost', onClick: onClickClear, disabled: disabled },
71
- react_3.default.createElement("span", { className: 'sr-only' }, t('clear label')),
72
- react_3.default.createElement(react_2.ArrowCounterClockwise, null))),
73
- react_3.default.createElement(react_ui_1.Tooltip.Portal, null,
74
- react_3.default.createElement(react_ui_1.Tooltip.Content, { style: { zIndex: 70 }, side: 'right' },
75
- t('clear label'),
76
- react_3.default.createElement(react_ui_1.Tooltip.Arrow, null))))));
77
- };
78
- exports.EmojiPicker = EmojiPicker;
79
- //# sourceMappingURL=EmojiPicker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EmojiPicker.js","sourceRoot":"","sources":["../../../../src/components/EmojiPicker.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;AACF,4DAAyC;AACzC,8DAA0C;AAC1C,iDAAyE;AACzE,yFAA8E;AAC9E,+CAA4E;AAE5E,6CAA4F;AAC5F,yDAA+C;AAUxC,MAAM,WAAW,GAAG,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAoB,EAAE,EAAE;IAC9G,MAAM,EAAE,CAAC,EAAE,GAAG,IAAA,yBAAc,EAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,IAAA,mDAAoB,EAAS;QAC/D,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,aAAa;QACvB,WAAW,EAAE,YAAY;KAC1B,CAAC,CAAC;IAEH,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,IAAA,gBAAQ,EAAU,KAAK,CAAC,CAAC;IAEvE,OAAO,CACL;QACE,8BAAC,kBAAO,CAAC,IAAI,IAAC,IAAI,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB;YACnE,8BAAC,kBAAO,CAAC,OAAO,IAAC,OAAO;gBACtB,8BAAC,iBAAM,IAAC,OAAO,EAAC,OAAO,EAAC,UAAU,EAAC,sBAAsB,EAAC,QAAQ,EAAE,QAAQ;oBAC1E,wCAAM,SAAS,EAAC,SAAS,IAAE,CAAC,CAAC,oBAAoB,CAAC,CAAQ;oBAC1D,wCAAM,SAAS,EAAC,aAAa,IAAE,UAAU,CAAQ;oBACjD,8BAAC,iBAAS,IAAC,SAAS,EAAE,IAAA,wBAAO,EAAC,CAAC,CAAC,GAAI,CAC7B,CACO;YAClB,8BAAC,kBAAO,CAAC,OAAO,IACd,IAAI,EAAC,OAAO,EACZ,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;oBAC1B,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;wBAC1B,KAAK,CAAC,eAAe,EAAE,CAAC;wBACxB,kBAAkB,CAAC,KAAK,CAAC,CAAC;qBAC3B;gBACH,CAAC;gBAED,8BAAC,eAAS,IACR,IAAI,EAAE,cAAS,EACf,aAAa,EAAE,CAAC,EAAE,MAAM,EAAuB,EAAE,EAAE;wBACjD,IAAI,MAAM,EAAE;4BACV,aAAa,CAAC,MAAM,CAAC,CAAC;4BACtB,kBAAkB,CAAC,KAAK,CAAC,CAAC;yBAC3B;oBACH,CAAC,EACD,SAAS,EAAE,IAAI,EACf,eAAe,EAAE,CAAC,EAClB,cAAc,EAAE,IAAI,GACpB;gBACF,8BAAC,kBAAO,CAAC,KAAK,OAAG,CACD,CACL;QACf,8BAAC,kBAAO,CAAC,IAAI;YACX,8BAAC,kBAAO,CAAC,OAAO,IAAC,OAAO;gBACtB,8BAAC,iBAAM,IAAC,OAAO,EAAC,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ;oBAC/D,wCAAM,SAAS,EAAC,SAAS,IAAE,CAAC,CAAC,aAAa,CAAC,CAAQ;oBACnD,8BAAC,6BAAqB,OAAG,CAClB,CACO;YAClB,8BAAC,kBAAO,CAAC,MAAM;gBACb,8BAAC,kBAAO,CAAC,OAAO,IAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAC,OAAO;oBACjD,CAAC,CAAC,aAAa,CAAC;oBACjB,8BAAC,kBAAO,CAAC,KAAK,OAAG,CACD,CACH,CACJ,CACd,CACJ,CAAC;AACJ,CAAC,CAAC;AA7DW,QAAA,WAAW,eA6DtB"}
@@ -1,11 +0,0 @@
1
- import { type Dispatch, type SetStateAction } from 'react';
2
- import { type ButtonProps } from '@dxos/react-ui';
3
- export type HuePickerProps = {
4
- disabled?: boolean;
5
- defaultHue?: string;
6
- hue?: string;
7
- onChangeHue?: Dispatch<SetStateAction<string>>;
8
- onClickClear?: ButtonProps['onClick'];
9
- };
10
- export declare const HuePicker: ({ disabled, hue, onChangeHue, defaultHue, onClickClear }: HuePickerProps) => JSX.Element;
11
- //# sourceMappingURL=HuePicker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HuePicker.d.ts","sourceRoot":"","sources":["../../../../src/components/HuePicker.tsx"],"names":[],"mappings":"AAKA,OAAc,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAElE,OAAO,EAAkE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAYlH,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,SAAS,6DAA8D,cAAc,gBA2DjG,CAAC"}
@@ -1,56 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.HuePicker = void 0;
7
- //
8
- // Copyright 2024 DXOS.org
9
- //
10
- const react_1 = require("@phosphor-icons/react");
11
- const react_use_controllable_state_1 = require("@radix-ui/react-use-controllable-state");
12
- const react_2 = __importDefault(require("react"));
13
- const react_ui_1 = require("@dxos/react-ui");
14
- const react_ui_theme_1 = require("@dxos/react-ui-theme");
15
- const HuePreview = ({ hue }) => {
16
- const { tx } = (0, react_ui_1.useThemeContext)();
17
- return (react_2.default.createElement("svg", { width: 12, height: 12, viewBox: '0 0 12 12' },
18
- react_2.default.createElement("rect", { x: 0, y: 0, width: 12, height: 12, className: tx('hue.fill', 'select--hue__preview', { hue }) })));
19
- };
20
- const HuePicker = ({ disabled, hue, onChangeHue, defaultHue, onClickClear }) => {
21
- const { t } = (0, react_ui_1.useTranslation)('os');
22
- const [hueValue, setHueValue] = (0, react_use_controllable_state_1.useControllableState)({
23
- prop: hue,
24
- onChange: onChangeHue,
25
- defaultProp: defaultHue,
26
- });
27
- return (react_2.default.createElement(react_2.default.Fragment, null,
28
- react_2.default.createElement(react_ui_1.DropdownMenu.Root, { modal: false },
29
- react_2.default.createElement(react_ui_1.DropdownMenu.Trigger, { asChild: true },
30
- react_2.default.createElement(react_ui_1.Button, { variant: 'ghost', classNames: 'gap-2 plb-1', disabled: disabled },
31
- react_2.default.createElement("span", { className: 'sr-only' }, t('select hue label')),
32
- react_2.default.createElement("div", { role: 'none', className: 'pis-14 grow flex items-center justify-center gap-2' },
33
- react_2.default.createElement(HuePreview, { hue: hueValue }),
34
- react_2.default.createElement("span", null, t(`${hueValue} label`))),
35
- react_2.default.createElement(react_1.CaretDown, { className: (0, react_ui_theme_1.getSize)(4) }))),
36
- react_2.default.createElement(react_ui_1.DropdownMenu.Content, { side: 'right' },
37
- react_2.default.createElement(react_ui_1.DropdownMenu.Viewport, null, Object.keys(react_ui_theme_1.hueTokenThemes).map((hue) => {
38
- return (react_2.default.createElement(react_ui_1.DropdownMenu.CheckboxItem, { key: hue, checked: hue === hueValue, onCheckedChange: () => setHueValue(hue) },
39
- react_2.default.createElement(HuePreview, { hue: hue }),
40
- react_2.default.createElement("span", { className: 'grow' }, t(`${hue} label`)),
41
- react_2.default.createElement(react_ui_1.DropdownMenu.ItemIndicator, null,
42
- react_2.default.createElement(react_1.Check, null))));
43
- })),
44
- react_2.default.createElement(react_ui_1.DropdownMenu.Arrow, null))),
45
- react_2.default.createElement(react_ui_1.Tooltip.Root, null,
46
- react_2.default.createElement(react_ui_1.Tooltip.Trigger, { asChild: true },
47
- react_2.default.createElement(react_ui_1.Button, { variant: 'ghost', onClick: onClickClear, disabled: disabled },
48
- react_2.default.createElement("span", { className: 'sr-only' }, t('clear label')),
49
- react_2.default.createElement(react_1.ArrowCounterClockwise, null))),
50
- react_2.default.createElement(react_ui_1.Tooltip.Portal, null,
51
- react_2.default.createElement(react_ui_1.Tooltip.Content, { style: { zIndex: 70 }, side: 'right' },
52
- t('clear label'),
53
- react_2.default.createElement(react_ui_1.Tooltip.Arrow, null))))));
54
- };
55
- exports.HuePicker = HuePicker;
56
- //# sourceMappingURL=HuePicker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HuePicker.js","sourceRoot":"","sources":["../../../../src/components/HuePicker.tsx"],"names":[],"mappings":"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"}