@dxos/shell 0.4.10-main.d2a7fe7 → 0.4.10-main.d3d33d7
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.
- package/dist/bundle/shell.mjs +39951 -24674
- package/dist/bundle/shell.mjs.map +1 -1
- package/dist/bundle/shell.umd.js +156 -88
- package/dist/bundle/shell.umd.js.map +1 -1
- package/dist/bundle/style.css +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react.mjs +831 -792
- package/dist/lib/browser/react.mjs.map +4 -4
- package/dist/lib/browser/testing/index.mjs +4 -2
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/types/src/components/AgentConfig.d.ts +3 -0
- package/dist/types/src/components/AgentConfig.d.ts.map +1 -0
- package/dist/types/src/components/AgentConfig.js +37 -0
- package/dist/types/src/components/AgentConfig.js.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceList.d.ts +3 -0
- package/dist/types/src/components/DeviceList/DeviceList.d.ts.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceList.js +29 -0
- package/dist/types/src/components/DeviceList/DeviceList.js.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceListItem.d.ts +6 -0
- package/dist/types/src/components/DeviceList/DeviceListItem.d.ts.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceListItem.js +72 -0
- package/dist/types/src/components/DeviceList/DeviceListItem.js.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceListProps.d.ts +27 -0
- package/dist/types/src/components/DeviceList/DeviceListProps.d.ts.map +1 -0
- package/dist/types/src/components/DeviceList/DeviceListProps.js +6 -0
- package/dist/types/src/components/DeviceList/DeviceListProps.js.map +1 -0
- package/dist/types/src/components/DeviceList/index.d.ts +3 -0
- package/dist/types/src/components/DeviceList/index.d.ts.map +1 -0
- package/dist/types/src/components/DeviceList/index.js +22 -0
- package/dist/types/src/components/DeviceList/index.js.map +1 -0
- package/dist/types/src/components/EmojiPicker.d.ts +9 -2
- package/dist/types/src/components/EmojiPicker.d.ts.map +1 -1
- package/dist/types/src/components/EmojiPicker.js +57 -3
- package/dist/types/src/components/EmojiPicker.js.map +1 -1
- package/dist/types/src/components/HuePicker.d.ts +9 -2
- package/dist/types/src/components/HuePicker.d.ts.map +1 -1
- package/dist/types/src/components/HuePicker.js +75 -6
- package/dist/types/src/components/HuePicker.js.map +1 -1
- package/dist/types/src/components/IdentityList/index.d.ts +0 -1
- package/dist/types/src/components/IdentityList/index.d.ts.map +1 -1
- package/dist/types/src/components/IdentityList/index.js +0 -1
- package/dist/types/src/components/IdentityList/index.js.map +1 -1
- package/dist/types/src/components/Panel/Action.d.ts +2 -2
- package/dist/types/src/components/Viewport/Viewport.d.ts +1 -1
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/index.js +2 -0
- package/dist/types/src/components/index.js.map +1 -1
- package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
- package/dist/types/src/composites/Shell/Shell.js +1 -5
- package/dist/types/src/composites/Shell/Shell.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +80 -40
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts +0 -3
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js +1 -43
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts +8 -11
- package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts +1 -1
- package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/identityMachine.js +0 -24
- package/dist/types/src/panels/IdentityPanel/identityMachine.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts +4 -4
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +9 -43
- package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +2 -2
- package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/index.d.ts +0 -2
- package/dist/types/src/panels/IdentityPanel/steps/index.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/steps/index.js +0 -2
- package/dist/types/src/panels/IdentityPanel/steps/index.js.map +1 -1
- package/dist/types/src/testing/shell-manager.d.ts.map +1 -1
- package/dist/types/src/testing/shell-manager.js +4 -2
- package/dist/types/src/testing/shell-manager.js.map +1 -1
- package/dist/types/src/translations/locales/en-US.d.ts +12 -2
- package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
- package/dist/types/src/translations/locales/en-US.js +12 -2
- package/dist/types/src/translations/locales/en-US.js.map +1 -1
- package/dist/types/src/types/index.js +1 -0
- package/dist/types/src/types/index.js.map +1 -1
- package/package.json +20 -20
- package/src/components/AgentConfig.tsx +66 -0
- package/src/components/DeviceList/DeviceList.tsx +54 -0
- package/src/components/DeviceList/DeviceListItem.tsx +120 -0
- package/src/components/DeviceList/DeviceListProps.ts +33 -0
- package/src/components/DeviceList/index.ts +6 -0
- package/src/components/EmojiPicker.tsx +101 -4
- package/src/components/HuePicker.tsx +99 -5
- package/src/components/IdentityList/index.ts +0 -1
- package/src/components/index.ts +2 -0
- package/src/composites/Shell/Shell.tsx +1 -7
- package/src/panels/IdentityPanel/IdentityPanel.stories.tsx +0 -63
- package/src/panels/IdentityPanel/IdentityPanel.tsx +123 -34
- package/src/panels/IdentityPanel/IdentityPanelProps.ts +10 -14
- package/src/panels/IdentityPanel/identityMachine.ts +1 -31
- package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +23 -76
- package/src/panels/IdentityPanel/steps/ProfileForm.tsx +12 -4
- package/src/panels/IdentityPanel/steps/index.ts +0 -2
- package/src/testing/shell-manager.ts +4 -2
- package/src/translations/locales/en-US.ts +13 -2
- package/src/types/index.ts +2 -0
- package/dist/types/src/components/IdentityList/DeviceList.d.ts +0 -7
- package/dist/types/src/components/IdentityList/DeviceList.d.ts.map +0 -1
- package/dist/types/src/components/IdentityList/DeviceList.js +0 -34
- package/dist/types/src/components/IdentityList/DeviceList.js.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts +0 -3
- package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js +0 -26
- package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts +0 -10
- package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts.map +0 -1
- package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.js +0 -23
- package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.js.map +0 -1
- package/src/components/IdentityList/DeviceList.tsx +0 -49
- package/src/panels/IdentityPanel/steps/AgentForm.tsx +0 -61
- package/src/panels/IdentityPanel/steps/DeviceManager.tsx +0 -41
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/types/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;;;;;;;;;;;AAEF,+CAA6B;AAC7B,gDAA8B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/types/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;;;;;;;;;;;;AAEF,+CAA6B;AAC7B,gDAA8B;AAE9B,2EAA2E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/shell",
|
|
3
|
-
"version": "0.4.10-main.
|
|
3
|
+
"version": "0.4.10-main.d3d33d7",
|
|
4
4
|
"description": "DXOS’s OS experiences",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -42,19 +42,19 @@
|
|
|
42
42
|
"react-qr-rounded": "^1.0.0",
|
|
43
43
|
"url-join": "^5.0.0",
|
|
44
44
|
"xstate": "^4.37.0",
|
|
45
|
-
"@dxos/async": "0.4.10-main.
|
|
46
|
-
"@dxos/client-protocol": "0.4.10-main.
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/display-name": "0.4.10-main.
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/react-
|
|
53
|
-
"@dxos/react-ui": "0.4.10-main.
|
|
54
|
-
"@dxos/react-ui-
|
|
55
|
-
"@dxos/
|
|
56
|
-
"@dxos/
|
|
57
|
-
"@dxos/
|
|
45
|
+
"@dxos/async": "0.4.10-main.d3d33d7",
|
|
46
|
+
"@dxos/client-protocol": "0.4.10-main.d3d33d7",
|
|
47
|
+
"@dxos/debug": "0.4.10-main.d3d33d7",
|
|
48
|
+
"@dxos/client-services": "0.4.10-main.d3d33d7",
|
|
49
|
+
"@dxos/display-name": "0.4.10-main.d3d33d7",
|
|
50
|
+
"@dxos/log": "0.4.10-main.d3d33d7",
|
|
51
|
+
"@dxos/invariant": "0.4.10-main.d3d33d7",
|
|
52
|
+
"@dxos/react-client": "0.4.10-main.d3d33d7",
|
|
53
|
+
"@dxos/react-ui": "0.4.10-main.d3d33d7",
|
|
54
|
+
"@dxos/react-ui-theme": "0.4.10-main.d3d33d7",
|
|
55
|
+
"@dxos/util": "0.4.10-main.d3d33d7",
|
|
56
|
+
"@dxos/react-ui-types": "0.4.10-main.d3d33d7",
|
|
57
|
+
"@dxos/rpc-tunnel": "0.4.10-main.d3d33d7"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@phosphor-icons/react": "^2.0.5",
|
|
@@ -63,13 +63,13 @@
|
|
|
63
63
|
"@vitejs/plugin-react": "^4.2.1",
|
|
64
64
|
"react": "^18.2.0",
|
|
65
65
|
"react-dom": "^18.2.0",
|
|
66
|
-
"vite": "^5.1.
|
|
66
|
+
"vite": "^5.1.7",
|
|
67
67
|
"vite-plugin-turbosnap": "^1.0.2",
|
|
68
|
-
"@dxos/
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/react-async": "0.4.10-main.
|
|
71
|
-
"@dxos/react-ui-theme": "0.4.10-main.
|
|
72
|
-
"@dxos/storybook-utils": "0.4.10-main.
|
|
68
|
+
"@dxos/config": "0.4.10-main.d3d33d7",
|
|
69
|
+
"@dxos/random": "0.4.10-main.d3d33d7",
|
|
70
|
+
"@dxos/react-async": "0.4.10-main.d3d33d7",
|
|
71
|
+
"@dxos/react-ui-theme": "0.4.10-main.d3d33d7",
|
|
72
|
+
"@dxos/storybook-utils": "0.4.10-main.d3d33d7"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"@phosphor-icons/react": "^2.0.5",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Database, Plus, Power } from '@phosphor-icons/react';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { Avatar, Button, Tooltip, useTranslation } from '@dxos/react-ui';
|
|
9
|
+
import { descriptionText, getSize, mx } from '@dxos/react-ui-theme';
|
|
10
|
+
|
|
11
|
+
import { type AgentFormProps } from './DeviceList';
|
|
12
|
+
|
|
13
|
+
export const AgentConfig = ({ agentActive, agentStatus, onAgentDestroy, onAgentCreate }: AgentFormProps) => {
|
|
14
|
+
const { t } = useTranslation('os');
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<h2 className={mx(descriptionText, 'text-center mbs-4')}>{t('agent heading')}</h2>
|
|
18
|
+
{agentActive ? (
|
|
19
|
+
<div role='group' className='flex gap-2 items-center'>
|
|
20
|
+
<Avatar.Root status={agentStatus ? 'active' : 'inactive'} variant='square'>
|
|
21
|
+
<Avatar.Frame classNames='place-self-center'>
|
|
22
|
+
<Database weight='duotone' width={24} height={24} x={8} y={8} />
|
|
23
|
+
</Avatar.Frame>
|
|
24
|
+
<Avatar.Label classNames='flex-1 text-sm truncate'>{t('agent device label')}</Avatar.Label>
|
|
25
|
+
</Avatar.Root>
|
|
26
|
+
<Tooltip.Root>
|
|
27
|
+
<Tooltip.Trigger asChild>
|
|
28
|
+
<Button
|
|
29
|
+
variant='ghost'
|
|
30
|
+
classNames='pli-0 is-[--rail-action] bs-[--rail-action]'
|
|
31
|
+
data-testid='agent.destroy'
|
|
32
|
+
onClick={onAgentDestroy}
|
|
33
|
+
>
|
|
34
|
+
<span className='sr-only'>{t('destroy agent label')}</span>
|
|
35
|
+
<Power className={getSize(5)} />
|
|
36
|
+
</Button>
|
|
37
|
+
</Tooltip.Trigger>
|
|
38
|
+
<Tooltip.Portal>
|
|
39
|
+
<Tooltip.Content side='bottom' classNames='z-50'>
|
|
40
|
+
{t('destroy agent label')}
|
|
41
|
+
</Tooltip.Content>
|
|
42
|
+
</Tooltip.Portal>
|
|
43
|
+
</Tooltip.Root>
|
|
44
|
+
</div>
|
|
45
|
+
) : (
|
|
46
|
+
<>
|
|
47
|
+
<Button
|
|
48
|
+
variant='ghost'
|
|
49
|
+
classNames='mlb-2 is-full justify-start gap-2 !pis-0 !pie-3'
|
|
50
|
+
data-testid='devices-panel.create-agent'
|
|
51
|
+
onClick={onAgentCreate}
|
|
52
|
+
aria-describedby='devices-panel.create-agent.description'
|
|
53
|
+
>
|
|
54
|
+
<div role='img' className={mx(getSize(8), 'm-1 rounded-sm surface-input grid place-items-center')}>
|
|
55
|
+
<Plus weight='light' className={getSize(6)} />
|
|
56
|
+
</div>
|
|
57
|
+
<span className='grow font-medium text-start'>{t('create agent label')}</span>
|
|
58
|
+
</Button>
|
|
59
|
+
<p id='devices-panel.create-agent.description' className={descriptionText}>
|
|
60
|
+
{t('agent message body')}
|
|
61
|
+
</p>
|
|
62
|
+
</>
|
|
63
|
+
)}
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { CaretRight, Plus } from '@phosphor-icons/react';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { type Device } from '@dxos/react-client/halo';
|
|
9
|
+
import { Button, List, useTranslation } from '@dxos/react-ui';
|
|
10
|
+
import { descriptionText, getSize, mx } from '@dxos/react-ui-theme';
|
|
11
|
+
|
|
12
|
+
import { DeviceListItem } from './DeviceListItem';
|
|
13
|
+
import { type DeviceListProps } from './DeviceListProps';
|
|
14
|
+
|
|
15
|
+
export const DeviceList = ({
|
|
16
|
+
devices,
|
|
17
|
+
onClickAdd,
|
|
18
|
+
onClickEdit,
|
|
19
|
+
onClickReset,
|
|
20
|
+
onClickJoinExisting,
|
|
21
|
+
}: DeviceListProps) => {
|
|
22
|
+
const { t } = useTranslation('os');
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<h2 className={mx(descriptionText, 'text-center mbs-4')}>{t('devices heading')}</h2>
|
|
26
|
+
{devices.length > 0 && (
|
|
27
|
+
<List>
|
|
28
|
+
{devices.map((device: Device) => {
|
|
29
|
+
return (
|
|
30
|
+
<DeviceListItem
|
|
31
|
+
key={device.deviceKey.toHex()}
|
|
32
|
+
device={device}
|
|
33
|
+
onClickEdit={() => onClickEdit?.(device)}
|
|
34
|
+
{...{ onClickReset, onClickJoinExisting }}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
})}
|
|
38
|
+
</List>
|
|
39
|
+
)}
|
|
40
|
+
<Button
|
|
41
|
+
variant='ghost'
|
|
42
|
+
classNames='justify-start gap-2 !pis-0 !pie-3'
|
|
43
|
+
data-testid='devices-panel.create-invitation'
|
|
44
|
+
onClick={onClickAdd}
|
|
45
|
+
>
|
|
46
|
+
<div role='img' className={mx(getSize(8), 'm-1 rounded-sm surface-input grid place-items-center')}>
|
|
47
|
+
<Plus weight='light' className={getSize(6)} />
|
|
48
|
+
</div>
|
|
49
|
+
<span className='grow font-medium text-start'>{t('choose add device label')}</span>
|
|
50
|
+
<CaretRight weight='bold' className={getSize(4)} />
|
|
51
|
+
</Button>
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Compass,
|
|
7
|
+
Desktop,
|
|
8
|
+
DeviceMobile,
|
|
9
|
+
Devices,
|
|
10
|
+
DotsThree,
|
|
11
|
+
type IconProps,
|
|
12
|
+
Intersect,
|
|
13
|
+
Power,
|
|
14
|
+
Robot,
|
|
15
|
+
} from '@phosphor-icons/react';
|
|
16
|
+
import React, { type ComponentPropsWithoutRef, forwardRef } from 'react';
|
|
17
|
+
|
|
18
|
+
import { generateName } from '@dxos/display-name';
|
|
19
|
+
import { Device, DeviceType, DeviceKind } from '@dxos/react-client/halo';
|
|
20
|
+
import {
|
|
21
|
+
ListItem,
|
|
22
|
+
Avatar,
|
|
23
|
+
useId,
|
|
24
|
+
type ThemedClassName,
|
|
25
|
+
Tag,
|
|
26
|
+
useTranslation,
|
|
27
|
+
DropdownMenu,
|
|
28
|
+
Button,
|
|
29
|
+
} from '@dxos/react-ui';
|
|
30
|
+
import { getSize } from '@dxos/react-ui-theme';
|
|
31
|
+
import { keyToFallback } from '@dxos/util';
|
|
32
|
+
|
|
33
|
+
import { type DeviceListItemProps } from './DeviceListProps';
|
|
34
|
+
|
|
35
|
+
const iconProps: IconProps = {
|
|
36
|
+
weight: 'duotone',
|
|
37
|
+
width: 24,
|
|
38
|
+
height: 24,
|
|
39
|
+
x: 8,
|
|
40
|
+
y: 8,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const DeviceListItem = forwardRef<
|
|
44
|
+
HTMLLIElement,
|
|
45
|
+
ThemedClassName<ComponentPropsWithoutRef<'li'>> & DeviceListItemProps
|
|
46
|
+
>(({ device, onClickAdd, onClickEdit, onClickReset, onClickJoinExisting, classNames, ...props }, forwardedRef) => {
|
|
47
|
+
const { t } = useTranslation('os');
|
|
48
|
+
const fallbackValue = keyToFallback(device.deviceKey);
|
|
49
|
+
const labelId = useId('identityListItem__label');
|
|
50
|
+
const displayName = device.profile
|
|
51
|
+
? t('device name placeholder', { os: device.profile.os, platform: device.profile.platform })
|
|
52
|
+
: generateName(device.deviceKey.toHex());
|
|
53
|
+
const isCurrent = device.kind === DeviceKind.CURRENT;
|
|
54
|
+
return (
|
|
55
|
+
<ListItem.Root
|
|
56
|
+
{...props}
|
|
57
|
+
classNames={['flex gap-2 items-center mlb-2', classNames]}
|
|
58
|
+
data-testid={`device-list-item${isCurrent ? '-current' : ''}`}
|
|
59
|
+
labelId={labelId}
|
|
60
|
+
ref={forwardedRef}
|
|
61
|
+
>
|
|
62
|
+
<Avatar.Root
|
|
63
|
+
status={device.presence === Device.PresenceState.ONLINE ? 'active' : 'inactive'}
|
|
64
|
+
labelId={labelId}
|
|
65
|
+
hue={fallbackValue.hue}
|
|
66
|
+
variant='square'
|
|
67
|
+
>
|
|
68
|
+
<Avatar.Frame classNames='place-self-center'>
|
|
69
|
+
{device.profile?.type ? (
|
|
70
|
+
device.profile.type === DeviceType.BROWSER ? (
|
|
71
|
+
<Compass {...iconProps} />
|
|
72
|
+
) : device.profile.type === DeviceType.NATIVE ? (
|
|
73
|
+
<Desktop {...iconProps} />
|
|
74
|
+
) : [DeviceType.AGENT, DeviceType.AGENT_MANAGED].includes(device.profile.type) ? (
|
|
75
|
+
<Robot {...iconProps} />
|
|
76
|
+
) : device.profile.type === DeviceType.MOBILE ? (
|
|
77
|
+
<DeviceMobile {...iconProps} />
|
|
78
|
+
) : (
|
|
79
|
+
<Devices {...iconProps} />
|
|
80
|
+
)
|
|
81
|
+
) : (
|
|
82
|
+
<Avatar.Fallback text={fallbackValue.emoji} />
|
|
83
|
+
)}
|
|
84
|
+
</Avatar.Frame>
|
|
85
|
+
{isCurrent && <Tag color='primary'>{t('current device tag label')}</Tag>}
|
|
86
|
+
<Avatar.Label classNames='flex-1 text-sm truncate'>{displayName}</Avatar.Label>
|
|
87
|
+
{device.kind === DeviceKind.CURRENT && (
|
|
88
|
+
<DropdownMenu.Root>
|
|
89
|
+
<DropdownMenu.Trigger asChild>
|
|
90
|
+
<Button
|
|
91
|
+
variant='ghost'
|
|
92
|
+
classNames='pli-0 is-[--rail-action] bs-[--rail-action]'
|
|
93
|
+
data-testid={`device-list-item${isCurrent ? '-current' : ''}.options`}
|
|
94
|
+
>
|
|
95
|
+
<span className='sr-only'>{t('more options label')}</span>
|
|
96
|
+
<DotsThree className={getSize(5)} />
|
|
97
|
+
</Button>
|
|
98
|
+
</DropdownMenu.Trigger>
|
|
99
|
+
<DropdownMenu.Content>
|
|
100
|
+
<DropdownMenu.Viewport>
|
|
101
|
+
{/* <DropdownMenu.Item disabled onClick={onClickEdit}> */}
|
|
102
|
+
{/* <PencilSimpleLine className={getSize(5)} /> */}
|
|
103
|
+
{/* {t('edit device label')} */}
|
|
104
|
+
{/* </DropdownMenu.Item> */}
|
|
105
|
+
<DropdownMenu.Item data-testid='device-list-item-current.join-existing' onClick={onClickJoinExisting}>
|
|
106
|
+
<Intersect className={getSize(5)} />
|
|
107
|
+
{t('choose join new identity label')}
|
|
108
|
+
</DropdownMenu.Item>
|
|
109
|
+
<DropdownMenu.Item data-testid='device-list-item-current.reset' onClick={onClickReset}>
|
|
110
|
+
<Power className={getSize(5)} />
|
|
111
|
+
{t('reset device label')}
|
|
112
|
+
</DropdownMenu.Item>
|
|
113
|
+
</DropdownMenu.Viewport>
|
|
114
|
+
</DropdownMenu.Content>
|
|
115
|
+
</DropdownMenu.Root>
|
|
116
|
+
)}
|
|
117
|
+
</Avatar.Root>
|
|
118
|
+
</ListItem.Root>
|
|
119
|
+
);
|
|
120
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type SpaceMember } from '@dxos/react-client/echo';
|
|
6
|
+
import { type Device } from '@dxos/react-client/halo';
|
|
7
|
+
|
|
8
|
+
export type DeviceListProps = {
|
|
9
|
+
devices: Device[];
|
|
10
|
+
onClickAdd?: () => void;
|
|
11
|
+
onClickEdit?: (device: Device) => void;
|
|
12
|
+
onClickReset?: () => void;
|
|
13
|
+
onClickJoinExisting?: () => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type AgentFormProps = {
|
|
17
|
+
onAgentCreate?: () => Promise<void>;
|
|
18
|
+
onAgentDestroy?: () => Promise<void>;
|
|
19
|
+
agentStatus?: string;
|
|
20
|
+
agentActive?: boolean;
|
|
21
|
+
agentProviderDisabled?: boolean;
|
|
22
|
+
validationMessage?: string;
|
|
23
|
+
agentHostingEnabled?: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type DeviceListItemProps = {
|
|
27
|
+
device: Device;
|
|
28
|
+
presence?: SpaceMember['presence'];
|
|
29
|
+
onClickAdd?: () => void;
|
|
30
|
+
onClickEdit?: () => void;
|
|
31
|
+
onClickReset?: () => void;
|
|
32
|
+
onClickJoinExisting?: () => void;
|
|
33
|
+
};
|
|
@@ -3,11 +3,20 @@
|
|
|
3
3
|
//
|
|
4
4
|
import emojiData from '@emoji-mart/data';
|
|
5
5
|
import EmojiMart from '@emoji-mart/react';
|
|
6
|
-
import { ArrowCounterClockwise, CaretDown } from '@phosphor-icons/react';
|
|
6
|
+
import { ArrowCounterClockwise, CaretDown, ImageSquare } from '@phosphor-icons/react';
|
|
7
7
|
import { useControllableState } from '@radix-ui/react-use-controllable-state';
|
|
8
|
-
import React, { type Dispatch, type SetStateAction, useState } from 'react';
|
|
8
|
+
import React, { type Dispatch, type SetStateAction, useRef, useState } from 'react';
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
Button,
|
|
12
|
+
Popover,
|
|
13
|
+
useTranslation,
|
|
14
|
+
Tooltip,
|
|
15
|
+
type ButtonProps,
|
|
16
|
+
Toolbar,
|
|
17
|
+
useMediaQuery,
|
|
18
|
+
type ThemedClassName,
|
|
19
|
+
} from '@dxos/react-ui';
|
|
11
20
|
import { getSize } from '@dxos/react-ui-theme';
|
|
12
21
|
|
|
13
22
|
export type EmojiPickerProps = {
|
|
@@ -18,7 +27,95 @@ export type EmojiPickerProps = {
|
|
|
18
27
|
onClickClear?: ButtonProps['onClick'];
|
|
19
28
|
};
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
/**
|
|
31
|
+
* A toolbar button for picking an emoji. Use only in `role=toolbar` elements. Unable to unset the value.
|
|
32
|
+
*/
|
|
33
|
+
export const EmojiPickerToolbarButton = ({
|
|
34
|
+
disabled,
|
|
35
|
+
defaultEmoji,
|
|
36
|
+
emoji,
|
|
37
|
+
onChangeEmoji,
|
|
38
|
+
classNames,
|
|
39
|
+
}: ThemedClassName<Omit<EmojiPickerProps, 'onClickClear'>>) => {
|
|
40
|
+
const { t } = useTranslation('os');
|
|
41
|
+
|
|
42
|
+
const [_emojiValue, setEmojiValue] = useControllableState<string>({
|
|
43
|
+
prop: emoji,
|
|
44
|
+
onChange: onChangeEmoji,
|
|
45
|
+
defaultProp: defaultEmoji,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const [emojiPickerOpen, setEmojiPickerOpen] = useState<boolean>(false);
|
|
49
|
+
|
|
50
|
+
const suppressNextTooltip = useRef<boolean>(false);
|
|
51
|
+
const [triggerTooltipOpen, setTriggerTooltipOpen] = useState(false);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Tooltip.Root
|
|
55
|
+
open={triggerTooltipOpen}
|
|
56
|
+
onOpenChange={(nextOpen) => {
|
|
57
|
+
if (suppressNextTooltip.current) {
|
|
58
|
+
setTriggerTooltipOpen(false);
|
|
59
|
+
suppressNextTooltip.current = false;
|
|
60
|
+
} else {
|
|
61
|
+
setTriggerTooltipOpen(nextOpen);
|
|
62
|
+
}
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<Popover.Root
|
|
66
|
+
open={emojiPickerOpen}
|
|
67
|
+
onOpenChange={(nextOpen) => {
|
|
68
|
+
setEmojiPickerOpen(nextOpen);
|
|
69
|
+
suppressNextTooltip.current = true;
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
<Tooltip.Trigger asChild>
|
|
73
|
+
<Popover.Trigger asChild>
|
|
74
|
+
<Toolbar.Button classNames={['gap-2 text-2xl plb-1', classNames]} disabled={disabled}>
|
|
75
|
+
<span className='sr-only'>{t('select emoji label')}</span>
|
|
76
|
+
<ImageSquare className={getSize(5)} />
|
|
77
|
+
</Toolbar.Button>
|
|
78
|
+
</Popover.Trigger>
|
|
79
|
+
</Tooltip.Trigger>
|
|
80
|
+
<Tooltip.Portal>
|
|
81
|
+
<Tooltip.Content side='bottom' classNames='z-50'>
|
|
82
|
+
{t('select emoji label')}
|
|
83
|
+
<Tooltip.Arrow />
|
|
84
|
+
</Tooltip.Content>
|
|
85
|
+
</Tooltip.Portal>
|
|
86
|
+
<Popover.Content
|
|
87
|
+
side='bottom'
|
|
88
|
+
onKeyDownCapture={(event) => {
|
|
89
|
+
if (event.key === 'Escape') {
|
|
90
|
+
event.stopPropagation();
|
|
91
|
+
setEmojiPickerOpen(false);
|
|
92
|
+
suppressNextTooltip.current = true;
|
|
93
|
+
}
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
<EmojiMart
|
|
97
|
+
data={emojiData}
|
|
98
|
+
onEmojiSelect={({ native }: { native?: string }) => {
|
|
99
|
+
if (native) {
|
|
100
|
+
setEmojiValue(native);
|
|
101
|
+
setEmojiPickerOpen(false);
|
|
102
|
+
}
|
|
103
|
+
}}
|
|
104
|
+
autoFocus={true}
|
|
105
|
+
maxFrequentRows={0}
|
|
106
|
+
noCountryFlags={true}
|
|
107
|
+
/>
|
|
108
|
+
<Popover.Arrow />
|
|
109
|
+
</Popover.Content>
|
|
110
|
+
</Popover.Root>
|
|
111
|
+
</Tooltip.Root>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* A button for picking an emoji alongside a button for unsetting it.
|
|
117
|
+
*/
|
|
118
|
+
export const EmojiPickerBlock = ({ disabled, defaultEmoji, emoji, onChangeEmoji, onClickClear }: EmojiPickerProps) => {
|
|
22
119
|
const { t } = useTranslation('os');
|
|
23
120
|
const [isMd] = useMediaQuery('md', { ssr: false });
|
|
24
121
|
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
//
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
|
-
import { ArrowCounterClockwise, CaretDown, Check } from '@phosphor-icons/react';
|
|
4
|
+
import { ArrowCounterClockwise, CaretDown, Check, Palette } from '@phosphor-icons/react';
|
|
5
5
|
import { useControllableState } from '@radix-ui/react-use-controllable-state';
|
|
6
|
-
import React, { type Dispatch, type SetStateAction } from 'react';
|
|
6
|
+
import React, { type Dispatch, type SetStateAction, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
Button,
|
|
10
|
+
useTranslation,
|
|
11
|
+
Tooltip,
|
|
12
|
+
DropdownMenu,
|
|
13
|
+
useThemeContext,
|
|
14
|
+
type ButtonProps,
|
|
15
|
+
Toolbar,
|
|
16
|
+
type ThemedClassName,
|
|
17
|
+
} from '@dxos/react-ui';
|
|
18
|
+
import { getSize, hueTokenThemes, mx } from '@dxos/react-ui-theme';
|
|
10
19
|
|
|
11
20
|
const HuePreview = ({ hue }: { hue: string }) => {
|
|
12
21
|
const { tx } = useThemeContext();
|
|
@@ -25,7 +34,92 @@ export type HuePickerProps = {
|
|
|
25
34
|
onClickClear?: ButtonProps['onClick'];
|
|
26
35
|
};
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
/**
|
|
38
|
+
* A toolbar button for picking hue. Use only in `role=toolbar` elements. Unable to unset the value.
|
|
39
|
+
*/
|
|
40
|
+
export const HuePickerToolbarButton = ({
|
|
41
|
+
disabled,
|
|
42
|
+
hue,
|
|
43
|
+
onChangeHue,
|
|
44
|
+
classNames,
|
|
45
|
+
defaultHue,
|
|
46
|
+
}: ThemedClassName<Omit<HuePickerProps, 'onClickClear'>>) => {
|
|
47
|
+
const { t } = useTranslation('os');
|
|
48
|
+
|
|
49
|
+
const [hueValue, setHueValue] = useControllableState<string>({
|
|
50
|
+
prop: hue,
|
|
51
|
+
onChange: onChangeHue,
|
|
52
|
+
defaultProp: defaultHue,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const [huePickerOpen, setHuePickerOpen] = useState<boolean>(false);
|
|
56
|
+
|
|
57
|
+
const suppressNextTooltip = useRef<boolean>(false);
|
|
58
|
+
const [triggerTooltipOpen, setTriggerTooltipOpen] = useState(false);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<Tooltip.Root
|
|
62
|
+
open={triggerTooltipOpen}
|
|
63
|
+
onOpenChange={(nextOpen) => {
|
|
64
|
+
if (suppressNextTooltip.current) {
|
|
65
|
+
setTriggerTooltipOpen(false);
|
|
66
|
+
suppressNextTooltip.current = false;
|
|
67
|
+
} else {
|
|
68
|
+
setTriggerTooltipOpen(nextOpen);
|
|
69
|
+
}
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
<DropdownMenu.Root
|
|
73
|
+
modal={false}
|
|
74
|
+
open={huePickerOpen}
|
|
75
|
+
onOpenChange={(nextOpen) => {
|
|
76
|
+
setHuePickerOpen(nextOpen);
|
|
77
|
+
suppressNextTooltip.current = true;
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
<Tooltip.Trigger asChild>
|
|
81
|
+
<DropdownMenu.Trigger asChild>
|
|
82
|
+
<Toolbar.Button classNames={mx('gap-2 plb-1', classNames)} disabled={disabled}>
|
|
83
|
+
<span className='sr-only'>{t('select hue label')}</span>
|
|
84
|
+
<Palette className={getSize(5)} />
|
|
85
|
+
</Toolbar.Button>
|
|
86
|
+
</DropdownMenu.Trigger>
|
|
87
|
+
</Tooltip.Trigger>
|
|
88
|
+
<Tooltip.Portal>
|
|
89
|
+
<Tooltip.Content side='bottom' classNames='z-50'>
|
|
90
|
+
{t('select hue label')}
|
|
91
|
+
<Tooltip.Arrow />
|
|
92
|
+
</Tooltip.Content>
|
|
93
|
+
</Tooltip.Portal>
|
|
94
|
+
<DropdownMenu.Content side='bottom'>
|
|
95
|
+
<DropdownMenu.Viewport>
|
|
96
|
+
{Object.keys(hueTokenThemes).map((hue) => {
|
|
97
|
+
return (
|
|
98
|
+
<DropdownMenu.CheckboxItem
|
|
99
|
+
key={hue}
|
|
100
|
+
checked={hue === hueValue}
|
|
101
|
+
onCheckedChange={() => setHueValue(hue)}
|
|
102
|
+
>
|
|
103
|
+
<HuePreview hue={hue} />
|
|
104
|
+
<span className='grow'>{t(`${hue} label`)}</span>
|
|
105
|
+
<DropdownMenu.ItemIndicator>
|
|
106
|
+
<Check />
|
|
107
|
+
</DropdownMenu.ItemIndicator>
|
|
108
|
+
</DropdownMenu.CheckboxItem>
|
|
109
|
+
);
|
|
110
|
+
})}
|
|
111
|
+
</DropdownMenu.Viewport>
|
|
112
|
+
<DropdownMenu.Arrow />
|
|
113
|
+
</DropdownMenu.Content>
|
|
114
|
+
</DropdownMenu.Root>
|
|
115
|
+
</Tooltip.Root>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* A button for picking hue alongside a button for unsetting it.
|
|
121
|
+
*/
|
|
122
|
+
export const HuePickerBlock = ({ disabled, hue, onChangeHue, defaultHue, onClickClear }: HuePickerProps) => {
|
|
29
123
|
const { t } = useTranslation('os');
|
|
30
124
|
|
|
31
125
|
const [hueValue, setHueValue] = useControllableState<string>({
|
package/src/components/index.ts
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
export * from './AgentConfig';
|
|
5
6
|
export * from './Clipboard';
|
|
6
7
|
export * from './CompoundButton';
|
|
7
8
|
export * from './EmojiPicker';
|
|
8
9
|
export * from './HuePicker';
|
|
9
10
|
export * from './IdentityList';
|
|
11
|
+
export * from './DeviceList';
|
|
10
12
|
export * from './InvitationList';
|
|
11
13
|
export * from './Panel';
|
|
12
14
|
export * from './Viewport';
|
|
@@ -81,13 +81,7 @@ export const Shell = ({ runtime, origin }: { runtime: ShellRuntime; origin: stri
|
|
|
81
81
|
await runtime.setAppContext({ display: ShellDisplay.NONE });
|
|
82
82
|
runtime.setLayout({ layout: ShellLayout.DEFAULT });
|
|
83
83
|
}}
|
|
84
|
-
initialDisposition={
|
|
85
|
-
layout === ShellLayout.SHARE_IDENTITY
|
|
86
|
-
? 'manage-device-invitation'
|
|
87
|
-
: layout === ShellLayout.EDIT_PROFILE
|
|
88
|
-
? 'manage-profile'
|
|
89
|
-
: 'default'
|
|
90
|
-
}
|
|
84
|
+
initialDisposition={layout === ShellLayout.SHARE_IDENTITY ? 'manage-device-invitation' : 'default'}
|
|
91
85
|
/>
|
|
92
86
|
);
|
|
93
87
|
|