@dxos/react-ui 0.1.22 → 0.1.24-next.6b1f434
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/lib/browser/index.mjs +2434 -77
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/IdentityList/DeviceList.d.ts +7 -0
- package/dist/types/src/components/IdentityList/DeviceList.d.ts.map +1 -0
- package/dist/types/src/components/IdentityList/IdentityListItem.d.ts +7 -0
- package/dist/types/src/components/IdentityList/IdentityListItem.d.ts.map +1 -0
- package/dist/types/src/components/{IdentityListItem → IdentityList}/IdentityListItem.stories.d.ts +2 -1
- package/dist/types/src/components/IdentityList/IdentityListItem.stories.d.ts.map +1 -0
- package/dist/types/src/components/IdentityList/SpaceMemberList.d.ts +7 -0
- package/dist/types/src/components/IdentityList/SpaceMemberList.d.ts.map +1 -0
- package/dist/types/src/components/IdentityList/SpaceMemberListContainer.d.ts +9 -0
- package/dist/types/src/components/IdentityList/SpaceMemberListContainer.d.ts.map +1 -0
- package/dist/types/src/components/IdentityList/index.d.ts +5 -0
- package/dist/types/src/components/IdentityList/index.d.ts.map +1 -0
- package/dist/types/src/components/InvitationList/InvitationList.d.ts +7 -0
- package/dist/types/src/components/InvitationList/InvitationList.d.ts.map +1 -0
- package/dist/types/src/components/InvitationList/InvitationList.stories.d.ts +10 -0
- package/dist/types/src/components/InvitationList/InvitationList.stories.d.ts.map +1 -0
- package/dist/types/src/components/InvitationList/InvitationListContainer.d.ts +7 -0
- package/dist/types/src/components/InvitationList/InvitationListContainer.d.ts.map +1 -0
- package/dist/types/src/components/InvitationList/InvitationListItem.d.ts +9 -0
- package/dist/types/src/components/InvitationList/InvitationListItem.d.ts.map +1 -0
- package/dist/types/src/components/InvitationList/InvitationListProps.d.ts +4 -0
- package/dist/types/src/components/InvitationList/InvitationListProps.d.ts.map +1 -0
- package/dist/types/src/components/InvitationList/InvitationStatusAvatar.d.ts +14 -0
- package/dist/types/src/components/InvitationList/InvitationStatusAvatar.d.ts.map +1 -0
- package/dist/types/src/components/InvitationList/InvitationStatusAvatar.stories.d.ts +9 -0
- package/dist/types/src/components/InvitationList/InvitationStatusAvatar.stories.d.ts.map +1 -0
- package/dist/types/src/components/InvitationList/index.d.ts +5 -0
- package/dist/types/src/components/InvitationList/index.d.ts.map +1 -0
- package/dist/types/src/components/PanelSeparator/PanelSeparator.d.ts +3 -0
- package/dist/types/src/components/PanelSeparator/PanelSeparator.d.ts.map +1 -0
- package/dist/types/src/components/PanelSeparator/index.d.ts +2 -0
- package/dist/types/src/components/PanelSeparator/index.d.ts.map +1 -0
- package/dist/types/src/components/SpaceList/SpaceListItem.d.ts +7 -0
- package/dist/types/src/components/SpaceList/SpaceListItem.d.ts.map +1 -0
- package/dist/types/src/components/SpaceList/index.d.ts +2 -0
- package/dist/types/src/components/SpaceList/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +5 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/composites/DevicesDialog/DevicesDialog.d.ts +6 -0
- package/dist/types/src/composites/DevicesDialog/DevicesDialog.d.ts.map +1 -0
- package/dist/types/src/composites/DevicesDialog/index.d.ts +2 -0
- package/dist/types/src/composites/DevicesDialog/index.d.ts.map +1 -0
- package/dist/types/src/composites/JoinDialog/JoinDialog.d.ts +6 -0
- package/dist/types/src/composites/JoinDialog/JoinDialog.d.ts.map +1 -0
- package/dist/types/src/composites/JoinDialog/JoinDialog.stories.d.ts +10 -0
- package/dist/types/src/composites/JoinDialog/JoinDialog.stories.d.ts.map +1 -0
- package/dist/types/src/composites/JoinDialog/index.d.ts +2 -0
- package/dist/types/src/composites/JoinDialog/index.d.ts.map +1 -0
- package/dist/types/src/composites/Shell/Shell.d.ts +6 -0
- package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -0
- package/dist/types/src/composites/Shell/index.d.ts +2 -0
- package/dist/types/src/composites/Shell/index.d.ts.map +1 -0
- package/dist/types/src/composites/SpaceDialog/SpaceDialog.d.ts +6 -0
- package/dist/types/src/composites/SpaceDialog/SpaceDialog.d.ts.map +1 -0
- package/dist/types/src/composites/SpaceDialog/index.d.ts +2 -0
- package/dist/types/src/composites/SpaceDialog/index.d.ts.map +1 -0
- package/dist/types/src/composites/index.d.ts +3 -0
- package/dist/types/src/composites/index.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/layouts/PanelAlertDialog/PanelAlertDialog.d.ts +14 -0
- package/dist/types/src/layouts/PanelAlertDialog/PanelAlertDialog.d.ts.map +1 -0
- package/dist/types/src/layouts/PanelAlertDialog/index.d.ts +2 -0
- package/dist/types/src/layouts/PanelAlertDialog/index.d.ts.map +1 -0
- package/dist/types/src/layouts/PanelDialog/PanelDialog.d.ts +14 -0
- package/dist/types/src/layouts/PanelDialog/PanelDialog.d.ts.map +1 -0
- package/dist/types/src/layouts/PanelDialog/index.d.ts +2 -0
- package/dist/types/src/layouts/PanelDialog/index.d.ts.map +1 -0
- package/dist/types/src/layouts/PanelSidebar/PanelSidebar.d.ts +4 -5
- package/dist/types/src/layouts/PanelSidebar/PanelSidebar.d.ts.map +1 -1
- package/dist/types/src/layouts/index.d.ts +2 -0
- package/dist/types/src/layouts/index.d.ts.map +1 -1
- package/dist/types/src/panels/DevicesPanel/DevicesPanel.d.ts +10 -0
- package/dist/types/src/panels/DevicesPanel/DevicesPanel.d.ts.map +1 -0
- package/dist/types/src/panels/DevicesPanel/index.d.ts +2 -0
- package/dist/types/src/panels/DevicesPanel/index.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/JoinHeading.d.ts +13 -0
- package/dist/types/src/panels/JoinPanel/JoinHeading.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts +3 -0
- package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts +54 -0
- package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/index.d.ts +3 -0
- package/dist/types/src/panels/JoinPanel/index.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/AdditionMethodSelector.d.ts +7 -0
- package/dist/types/src/panels/JoinPanel/view-states/AdditionMethodSelector.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/IdentityAdded.d.ts +15 -0
- package/dist/types/src/panels/JoinPanel/view-states/IdentityAdded.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/IdentityInput.d.ts +6 -0
- package/dist/types/src/panels/JoinPanel/view-states/IdentityInput.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/IdentitySelector.d.ts +7 -0
- package/dist/types/src/panels/JoinPanel/view-states/IdentitySelector.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/InvitationAccepted.d.ts +10 -0
- package/dist/types/src/panels/JoinPanel/view-states/InvitationAccepted.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/InvitationAuthenticator.d.ts +7 -0
- package/dist/types/src/panels/JoinPanel/view-states/InvitationAuthenticator.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/InvitationInput.d.ts +6 -0
- package/dist/types/src/panels/JoinPanel/view-states/InvitationInput.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/InvitationRescuer.d.ts +6 -0
- package/dist/types/src/panels/JoinPanel/view-states/InvitationRescuer.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/ViewState.d.ts +12 -0
- package/dist/types/src/panels/JoinPanel/view-states/ViewState.d.ts.map +1 -0
- package/dist/types/src/panels/JoinPanel/view-states/index.d.ts +9 -0
- package/dist/types/src/panels/JoinPanel/view-states/index.d.ts.map +1 -0
- package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts +18 -0
- package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts.map +1 -0
- package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts +9 -0
- package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts.map +1 -0
- package/dist/types/src/panels/SpacePanel/index.d.ts +2 -0
- package/dist/types/src/panels/SpacePanel/index.d.ts.map +1 -0
- package/dist/types/src/panels/index.d.ts +3 -0
- package/dist/types/src/panels/index.d.ts.map +1 -1
- package/dist/types/src/styles/dialogStyles.d.ts +3 -0
- package/dist/types/src/styles/dialogStyles.d.ts.map +1 -0
- package/dist/types/src/styles/index.d.ts +2 -0
- package/dist/types/src/styles/index.d.ts.map +1 -1
- package/dist/types/src/styles/invitationStatusStyles.d.ts +20 -0
- package/dist/types/src/styles/invitationStatusStyles.d.ts.map +1 -0
- package/dist/types/src/styles/panelStyles.d.ts +2 -1
- package/dist/types/src/styles/panelStyles.d.ts.map +1 -1
- package/dist/types/src/translations/locales/en-US.d.ts +52 -0
- package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +2 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/util/invitationStatusValue.d.ts +8 -0
- package/dist/types/src/util/invitationStatusValue.d.ts.map +1 -0
- package/package.json +19 -11
- package/src/components/IdentityList/DeviceList.tsx +31 -0
- package/src/components/{IdentityListItem → IdentityList}/IdentityListItem.stories.tsx +0 -0
- package/src/components/{IdentityListItem → IdentityList}/IdentityListItem.tsx +18 -5
- package/src/components/IdentityList/SpaceMemberList.tsx +33 -0
- package/src/components/IdentityList/SpaceMemberListContainer.tsx +28 -0
- package/src/components/IdentityList/index.ts +8 -0
- package/src/components/InvitationList/InvitationList.stories.tsx +65 -0
- package/src/components/InvitationList/InvitationList.tsx +28 -0
- package/src/components/InvitationList/InvitationListContainer.tsx +27 -0
- package/src/components/InvitationList/InvitationListItem.tsx +106 -0
- package/src/components/InvitationList/InvitationListProps.ts +7 -0
- package/src/components/InvitationList/InvitationStatusAvatar.stories.tsx +52 -0
- package/src/components/InvitationList/InvitationStatusAvatar.tsx +80 -0
- package/src/components/InvitationList/index.ts +8 -0
- package/src/components/PanelSeparator/PanelSeparator.tsx +17 -0
- package/src/components/PanelSeparator/index.ts +5 -0
- package/src/components/SpaceList/SpaceListItem.tsx +32 -0
- package/src/components/SpaceList/index.ts +5 -0
- package/src/components/index.ts +8 -0
- package/src/composites/DevicesDialog/DevicesDialog.tsx +38 -0
- package/src/composites/DevicesDialog/index.ts +5 -0
- package/src/composites/JoinDialog/JoinDialog.stories.tsx +81 -0
- package/src/composites/JoinDialog/JoinDialog.tsx +33 -0
- package/src/composites/JoinDialog/index.ts +5 -0
- package/src/composites/Shell/Shell.tsx +92 -0
- package/src/composites/Shell/index.ts +5 -0
- package/src/composites/SpaceDialog/SpaceDialog.tsx +38 -0
- package/src/composites/SpaceDialog/index.ts +5 -0
- package/src/composites/index.ts +4 -0
- package/src/index.ts +1 -0
- package/src/layouts/PanelAlertDialog/PanelAlertDialog.tsx +40 -0
- package/src/layouts/PanelAlertDialog/index.ts +5 -0
- package/src/layouts/PanelDialog/PanelDialog.tsx +39 -0
- package/src/layouts/PanelDialog/index.ts +5 -0
- package/src/layouts/PanelPopover/PanelPopover.tsx +2 -2
- package/src/layouts/PanelSidebar/PanelSidebar.tsx +27 -31
- package/src/layouts/index.ts +2 -0
- package/src/panels/DevicesPanel/DevicesPanel.tsx +98 -0
- package/src/panels/DevicesPanel/index.ts +5 -0
- package/src/panels/JoinPanel/JoinHeading.tsx +85 -0
- package/src/panels/JoinPanel/JoinPanel.tsx +319 -0
- package/src/panels/JoinPanel/JoinPanelProps.ts +90 -0
- package/src/panels/JoinPanel/index.ts +6 -0
- package/src/panels/JoinPanel/view-states/AdditionMethodSelector.tsx +73 -0
- package/src/panels/JoinPanel/view-states/IdentityAdded.tsx +99 -0
- package/src/panels/JoinPanel/view-states/IdentityInput.tsx +79 -0
- package/src/panels/JoinPanel/view-states/IdentitySelector.tsx +101 -0
- package/src/panels/JoinPanel/view-states/InvitationAccepted.tsx +70 -0
- package/src/panels/JoinPanel/view-states/InvitationAuthenticator.tsx +142 -0
- package/src/panels/JoinPanel/view-states/InvitationInput.tsx +75 -0
- package/src/panels/JoinPanel/view-states/InvitationRescuer.tsx +98 -0
- package/src/panels/JoinPanel/view-states/ViewState.tsx +204 -0
- package/src/panels/JoinPanel/view-states/index.ts +12 -0
- package/src/panels/SpacePanel/SpacePanel.stories.tsx +53 -0
- package/src/panels/SpacePanel/SpacePanel.tsx +174 -0
- package/src/panels/SpacePanel/index.ts +5 -0
- package/src/panels/index.ts +3 -0
- package/src/styles/dialogStyles.ts +8 -0
- package/src/styles/index.ts +2 -0
- package/src/styles/invitationStatusStyles.ts +42 -0
- package/src/styles/panelStyles.ts +2 -1
- package/src/testing/ClientProvider.tsx +1 -1
- package/src/translations/locales/en-US.ts +53 -1
- package/src/util/index.ts +5 -0
- package/src/util/invitationStatusValue.ts +21 -0
- package/theme-extensions.js +11 -0
- package/dist/types/src/components/IdentityListItem/IdentityListItem.d.ts +0 -6
- package/dist/types/src/components/IdentityListItem/IdentityListItem.d.ts.map +0 -1
- package/dist/types/src/components/IdentityListItem/IdentityListItem.stories.d.ts.map +0 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxosTheme';
|
|
6
|
+
|
|
7
|
+
import { StoryContext, StoryFn } from '@storybook/react';
|
|
8
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
9
|
+
|
|
10
|
+
import { Client, Invitation, InvitationEncoder } from '@dxos/client';
|
|
11
|
+
import { TestBuilder } from '@dxos/client/testing';
|
|
12
|
+
import { log } from '@dxos/log';
|
|
13
|
+
import { useAsyncEffect } from '@dxos/react-async';
|
|
14
|
+
import { ClientProvider } from '@dxos/react-client';
|
|
15
|
+
import { Loading } from '@dxos/react-components';
|
|
16
|
+
|
|
17
|
+
import { JoinDialog } from './JoinDialog';
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
component: JoinDialog
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const JoinClientDecorator = (Story: StoryFn, { args }: StoryContext) => {
|
|
24
|
+
const n = 2;
|
|
25
|
+
const testBuilder = new TestBuilder();
|
|
26
|
+
const clients = useMemo(() => {
|
|
27
|
+
return [...Array(n)].map(() => new Client({ services: testBuilder.createClientServicesHost() }));
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
const [invitationCode, setInvitationCode] = useState<string>();
|
|
31
|
+
|
|
32
|
+
const onInvitationEvent = useCallback((invitation: Invitation) => {
|
|
33
|
+
if (!invitationCode) {
|
|
34
|
+
const nextInvitationCode = InvitationEncoder.encode(invitation);
|
|
35
|
+
log.info('[next invitation code]', { nextInvitationCode });
|
|
36
|
+
setInvitationCode(nextInvitationCode);
|
|
37
|
+
}
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
40
|
+
useAsyncEffect(async () => {
|
|
41
|
+
await Promise.all(clients.map((client) => client.initialize()));
|
|
42
|
+
log.info('[initialized]');
|
|
43
|
+
|
|
44
|
+
await clients[0].halo.createProfile({ displayName: 'Os Mutantes' });
|
|
45
|
+
|
|
46
|
+
const space = await clients[0].echo.createSpace();
|
|
47
|
+
log.info('[space created]', space);
|
|
48
|
+
space.properties.name = 'Q3 2022 Planning';
|
|
49
|
+
|
|
50
|
+
const invitation = space.createInvitation({ type: Invitation.Type.INTERACTIVE });
|
|
51
|
+
log.info('[invitation created]', invitation);
|
|
52
|
+
|
|
53
|
+
invitation.subscribe({
|
|
54
|
+
onAuthenticating: onInvitationEvent,
|
|
55
|
+
onCancelled: (...args) => log.warn('[cancelled]', args),
|
|
56
|
+
onConnected: onInvitationEvent,
|
|
57
|
+
onConnecting: onInvitationEvent,
|
|
58
|
+
onError: onInvitationEvent,
|
|
59
|
+
onSuccess: onInvitationEvent,
|
|
60
|
+
onTimeout: (...args) => log.warn('[timeout]', args)
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return () => {
|
|
64
|
+
void Promise.all(clients.map((client) => client.destroy()));
|
|
65
|
+
};
|
|
66
|
+
}, clients);
|
|
67
|
+
|
|
68
|
+
if (!invitationCode) {
|
|
69
|
+
return <Loading label='Setting things up…' />;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<ClientProvider client={clients[1]} fallback={() => <Loading label='Loading client…' />}>
|
|
74
|
+
<Story args={{ initialInvitationCode: invitationCode, ...args }} />
|
|
75
|
+
</ClientProvider>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const Default = {
|
|
80
|
+
decorators: [JoinClientDecorator]
|
|
81
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Action, Cancel } from '@radix-ui/react-alert-dialog';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { ThemeContext, useId } from '@dxos/react-components';
|
|
9
|
+
|
|
10
|
+
import { PanelAlertDialog, PanelAlertDialogProps } from '../../layouts';
|
|
11
|
+
import { JoinPanel, JoinPanelProps } from '../../panels';
|
|
12
|
+
|
|
13
|
+
export interface JoinDialogProps
|
|
14
|
+
extends Omit<PanelAlertDialogProps, 'titleId' | 'children'>,
|
|
15
|
+
Omit<JoinPanelProps, 'exitActionParent' | 'doneActionParent'> {}
|
|
16
|
+
|
|
17
|
+
export const JoinDialog = ({ slots, ...joinPanelProps }: JoinDialogProps) => {
|
|
18
|
+
const titleId = useId('joinDialog__title');
|
|
19
|
+
return (
|
|
20
|
+
<PanelAlertDialog {...{ slots, titleId }}>
|
|
21
|
+
<ThemeContext.Provider value={{ themeVariant: 'os' }}>
|
|
22
|
+
<JoinPanel
|
|
23
|
+
{...{
|
|
24
|
+
...joinPanelProps,
|
|
25
|
+
titleId,
|
|
26
|
+
exitActionParent: <Cancel asChild />,
|
|
27
|
+
doneActionParent: <Action asChild />
|
|
28
|
+
}}
|
|
29
|
+
/>
|
|
30
|
+
</ThemeContext.Provider>
|
|
31
|
+
</PanelAlertDialog>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useEffect, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
import { ShellRuntime } from '@dxos/client';
|
|
8
|
+
import { LayoutRequest, ShellDisplay, ShellLayout } from '@dxos/protocols/proto/dxos/iframe';
|
|
9
|
+
import { useClient, useSpace, useSpaces } from '@dxos/react-client';
|
|
10
|
+
|
|
11
|
+
import { DevicesDialog } from '../DevicesDialog';
|
|
12
|
+
import { JoinDialog } from '../JoinDialog';
|
|
13
|
+
import { SpaceDialog } from '../SpaceDialog';
|
|
14
|
+
|
|
15
|
+
export const Shell = ({ runtime, origin }: { runtime: ShellRuntime; origin: string }) => {
|
|
16
|
+
const client = useClient();
|
|
17
|
+
const spaces = useSpaces();
|
|
18
|
+
|
|
19
|
+
const [{ layout, invitationCode, spaceKey }, setLayout] = useState<LayoutRequest>({
|
|
20
|
+
layout: runtime.layout,
|
|
21
|
+
invitationCode: runtime.invitationCode,
|
|
22
|
+
spaceKey: runtime.spaceKey
|
|
23
|
+
});
|
|
24
|
+
const space = useSpace(spaceKey);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
return runtime.layoutUpdate.on((request) => setLayout(request));
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
switch (layout) {
|
|
31
|
+
case ShellLayout.AUTH:
|
|
32
|
+
return (
|
|
33
|
+
<JoinDialog
|
|
34
|
+
mode='halo-only'
|
|
35
|
+
initialInvitationCode={invitationCode}
|
|
36
|
+
onDone={async () => {
|
|
37
|
+
// TODO(wittjosiah): Is this app-specific?
|
|
38
|
+
const space = spaces[0] ?? (await client.echo.createSpace());
|
|
39
|
+
await runtime.setAppContext({ display: ShellDisplay.NONE, spaceKey: space.key });
|
|
40
|
+
runtime.setLayout(ShellLayout.DEFAULT);
|
|
41
|
+
}}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
case ShellLayout.CURRENT_SPACE:
|
|
46
|
+
case ShellLayout.SPACE_LIST:
|
|
47
|
+
return (
|
|
48
|
+
<SpaceDialog
|
|
49
|
+
space={space}
|
|
50
|
+
initialState={layout === ShellLayout.SPACE_LIST ? 'space list' : 'current space'}
|
|
51
|
+
createInvitationUrl={(invitationCode) => `${origin}?spaceInvitationCode=${invitationCode}`}
|
|
52
|
+
onClickJoinSpace={() => runtime.setLayout(ShellLayout.JOIN_SPACE, { spaceKey: space?.key })}
|
|
53
|
+
onClickMember={() => runtime.setLayout(ShellLayout.DEVICES_LIST, { spaceKey: space?.key })}
|
|
54
|
+
onDone={async (space) => {
|
|
55
|
+
// TODO(wittjosiah): If space is newly created the app won't yet know about it.
|
|
56
|
+
// This is a bug that needs to be fixed when upgrading the space service.
|
|
57
|
+
await runtime.setAppContext({ display: ShellDisplay.NONE, spaceKey: space ? space.key : spaceKey });
|
|
58
|
+
runtime.setLayout(ShellLayout.DEFAULT);
|
|
59
|
+
}}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
case ShellLayout.JOIN_SPACE:
|
|
64
|
+
return (
|
|
65
|
+
<JoinDialog
|
|
66
|
+
initialInvitationCode={invitationCode}
|
|
67
|
+
onDone={async (result) => {
|
|
68
|
+
await runtime.setAppContext({ display: ShellDisplay.NONE, spaceKey: result?.spaceKey ?? undefined });
|
|
69
|
+
runtime.setLayout(ShellLayout.DEFAULT);
|
|
70
|
+
}}
|
|
71
|
+
onExit={async () => {
|
|
72
|
+
await runtime.setAppContext({ display: ShellDisplay.NONE, spaceKey: runtime.spaceKey });
|
|
73
|
+
runtime.setLayout(ShellLayout.DEFAULT);
|
|
74
|
+
}}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
case ShellLayout.DEVICES_LIST:
|
|
79
|
+
return (
|
|
80
|
+
<DevicesDialog
|
|
81
|
+
createInvitationUrl={(invitationCode) => `${origin}?haloInvitationCode=${invitationCode}`}
|
|
82
|
+
onDone={async () => {
|
|
83
|
+
await runtime.setAppContext({ display: ShellDisplay.NONE, spaceKey: runtime.spaceKey });
|
|
84
|
+
runtime.setLayout(ShellLayout.DEFAULT);
|
|
85
|
+
}}
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
default:
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Close } from '@radix-ui/react-dialog';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { ThemeContext, useId } from '@dxos/react-components';
|
|
9
|
+
|
|
10
|
+
import { PanelDialog, PanelDialogProps } from '../../layouts';
|
|
11
|
+
import { SpacePanel, SpacePanelProps } from '../../panels';
|
|
12
|
+
|
|
13
|
+
export interface SpaceDialogProps
|
|
14
|
+
extends Omit<PanelDialogProps, 'titleId' | 'children'>,
|
|
15
|
+
Omit<SpacePanelProps, 'doneActionParent'> {}
|
|
16
|
+
|
|
17
|
+
export const SpaceDialog = ({ slots, ...spacePanelProps }: SpaceDialogProps) => {
|
|
18
|
+
const titleId = useId('spaceDialog__title');
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<PanelDialog
|
|
22
|
+
{...{
|
|
23
|
+
slots: { ...slots, root: { onOpenChange: (open) => open || spacePanelProps.onDone?.(null), ...slots?.root } },
|
|
24
|
+
titleId
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
27
|
+
<ThemeContext.Provider value={{ themeVariant: 'os' }}>
|
|
28
|
+
<SpacePanel
|
|
29
|
+
{...{
|
|
30
|
+
...spacePanelProps,
|
|
31
|
+
titleId,
|
|
32
|
+
doneActionParent: <Close asChild />
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
</ThemeContext.Provider>
|
|
36
|
+
</PanelDialog>
|
|
37
|
+
);
|
|
38
|
+
};
|
package/src/composites/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as AlertDialog from '@radix-ui/react-alert-dialog';
|
|
6
|
+
import React, { ComponentPropsWithoutRef, PropsWithChildren } from 'react';
|
|
7
|
+
|
|
8
|
+
import { mx } from '@dxos/react-components';
|
|
9
|
+
|
|
10
|
+
import { defaultDialogContent, defaultOverlay } from '../../styles';
|
|
11
|
+
|
|
12
|
+
export interface PanelAlertDialogSlots {
|
|
13
|
+
root: ComponentPropsWithoutRef<typeof AlertDialog.Root>;
|
|
14
|
+
overlay: ComponentPropsWithoutRef<typeof AlertDialog.Overlay>;
|
|
15
|
+
content: ComponentPropsWithoutRef<typeof AlertDialog.Content>;
|
|
16
|
+
trigger: ComponentPropsWithoutRef<typeof AlertDialog.Trigger>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type PanelAlertDialogProps = PropsWithChildren<{
|
|
20
|
+
titleId: string;
|
|
21
|
+
slots?: Partial<PanelAlertDialogSlots>;
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
export const PanelAlertDialog = ({ titleId, slots = {}, children }: PanelAlertDialogProps) => {
|
|
25
|
+
return (
|
|
26
|
+
<AlertDialog.Root defaultOpen {...slots.root}>
|
|
27
|
+
{slots.trigger && <AlertDialog.Trigger {...slots.trigger} />}
|
|
28
|
+
<AlertDialog.Overlay {...slots.overlay} className={mx(defaultOverlay, 'z-40', slots.overlay?.className)}>
|
|
29
|
+
<AlertDialog.Content
|
|
30
|
+
onEscapeKeyDown={(event) => event.preventDefault()}
|
|
31
|
+
{...slots.content}
|
|
32
|
+
aria-labelledby={titleId}
|
|
33
|
+
className={mx(defaultDialogContent, slots.content?.className)}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</AlertDialog.Content>
|
|
37
|
+
</AlertDialog.Overlay>
|
|
38
|
+
</AlertDialog.Root>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Dialog from '@radix-ui/react-dialog';
|
|
6
|
+
import React, { ComponentPropsWithoutRef, PropsWithChildren } from 'react';
|
|
7
|
+
|
|
8
|
+
import { mx } from '@dxos/react-components';
|
|
9
|
+
|
|
10
|
+
import { defaultDialogContent, defaultOverlay } from '../../styles';
|
|
11
|
+
|
|
12
|
+
export interface PanelDialogSlots {
|
|
13
|
+
root: ComponentPropsWithoutRef<typeof Dialog.Root>;
|
|
14
|
+
overlay: ComponentPropsWithoutRef<typeof Dialog.Overlay>;
|
|
15
|
+
content: ComponentPropsWithoutRef<typeof Dialog.Content>;
|
|
16
|
+
trigger: ComponentPropsWithoutRef<typeof Dialog.Trigger>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type PanelDialogProps = PropsWithChildren<{
|
|
20
|
+
titleId: string;
|
|
21
|
+
slots?: Partial<PanelDialogSlots>;
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
export const PanelDialog = ({ titleId, slots = {}, children }: PanelDialogProps) => {
|
|
25
|
+
return (
|
|
26
|
+
<Dialog.Root defaultOpen {...slots.root}>
|
|
27
|
+
{slots.trigger && <Dialog.Trigger {...slots.trigger} />}
|
|
28
|
+
<Dialog.Overlay {...slots.overlay} className={mx(defaultOverlay, 'z-40', slots.overlay?.className)}>
|
|
29
|
+
<Dialog.Content
|
|
30
|
+
{...slots.content}
|
|
31
|
+
aria-labelledby={titleId}
|
|
32
|
+
className={mx(defaultDialogContent, slots.content?.className)}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</Dialog.Content>
|
|
36
|
+
</Dialog.Overlay>
|
|
37
|
+
</Dialog.Root>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
@@ -6,7 +6,7 @@ import React, { ComponentProps } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { mx, Popover } from '@dxos/react-components';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { defaultSurface, defaultArrow } from '../../styles';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* This component essentially sets default styles for popovers which have panels as their content
|
|
@@ -24,7 +24,7 @@ export const PanelPopover = ({ slots, children, ...popoverProps }: ComponentProp
|
|
|
24
24
|
collisionPadding: 8,
|
|
25
25
|
sideOffset: 4,
|
|
26
26
|
...slots?.content,
|
|
27
|
-
className: mx(
|
|
27
|
+
className: mx(defaultSurface, slots?.content?.className)
|
|
28
28
|
},
|
|
29
29
|
trigger: {
|
|
30
30
|
...slots?.trigger,
|
|
@@ -7,7 +7,6 @@ import React, {
|
|
|
7
7
|
ComponentProps,
|
|
8
8
|
createContext,
|
|
9
9
|
Dispatch,
|
|
10
|
-
Fragment,
|
|
11
10
|
PropsWithChildren,
|
|
12
11
|
SetStateAction,
|
|
13
12
|
useCallback,
|
|
@@ -19,8 +18,6 @@ import { defaultOverlay, mx, useMediaQuery, useTranslation } from '@dxos/react-c
|
|
|
19
18
|
|
|
20
19
|
export type PanelSidebarState = 'show' | 'hide';
|
|
21
20
|
|
|
22
|
-
export const sidebarWidth = 272;
|
|
23
|
-
|
|
24
21
|
export interface PanelSidebarContextValue {
|
|
25
22
|
setDisplayState: Dispatch<SetStateAction<PanelSidebarState>>;
|
|
26
23
|
displayState: PanelSidebarState;
|
|
@@ -39,9 +36,8 @@ export const useTogglePanelSidebar = () => {
|
|
|
39
36
|
};
|
|
40
37
|
|
|
41
38
|
export interface PanelSidebarProviderSlots {
|
|
42
|
-
content?: ComponentProps<typeof
|
|
43
|
-
|
|
44
|
-
fixedBlockEnd?: ComponentProps<'div'>;
|
|
39
|
+
content?: ComponentProps<typeof DialogPrimitive.Content>;
|
|
40
|
+
main?: ComponentProps<'div'>;
|
|
45
41
|
}
|
|
46
42
|
|
|
47
43
|
export interface PanelSidebarProviderProps {
|
|
@@ -51,20 +47,22 @@ export interface PanelSidebarProviderProps {
|
|
|
51
47
|
|
|
52
48
|
export const PanelSidebarProvider = ({ children, slots }: PropsWithChildren<PanelSidebarProviderProps>) => {
|
|
53
49
|
const { t } = useTranslation('os');
|
|
54
|
-
const [
|
|
55
|
-
const [
|
|
50
|
+
const [isLg] = useMediaQuery('lg', { ssr: false });
|
|
51
|
+
const [displayState, setInternalDisplayState] = useState<PanelSidebarState>(isLg ? 'show' : 'hide');
|
|
56
52
|
const isOpen = displayState === 'show';
|
|
57
|
-
|
|
58
|
-
const [
|
|
53
|
+
const [transitionShow, setTransitionShow] = useState(isOpen);
|
|
54
|
+
const [domShow, setDomShow] = useState(isOpen);
|
|
59
55
|
|
|
60
56
|
const internalHide = () => {
|
|
61
57
|
setTransitionShow(false);
|
|
58
|
+
setInternalDisplayState('hide');
|
|
62
59
|
setTimeout(() => {
|
|
63
|
-
|
|
60
|
+
setDomShow(false);
|
|
64
61
|
}, 200);
|
|
65
62
|
};
|
|
66
63
|
|
|
67
64
|
const internalShow = () => {
|
|
65
|
+
setDomShow(true);
|
|
68
66
|
setInternalDisplayState('show');
|
|
69
67
|
setTimeout(() => {
|
|
70
68
|
setTransitionShow(true);
|
|
@@ -77,30 +75,24 @@ export const PanelSidebarProvider = ({ children, slots }: PropsWithChildren<Pane
|
|
|
77
75
|
|
|
78
76
|
return (
|
|
79
77
|
<PanelSidebarContext.Provider value={{ setDisplayState, displayState }}>
|
|
80
|
-
<DialogPrimitive.Root open={
|
|
78
|
+
<DialogPrimitive.Root open={domShow} modal={!isLg}>
|
|
79
|
+
{/* Sidebar. */}
|
|
81
80
|
<DialogPrimitive.Content
|
|
81
|
+
onOpenAutoFocus={(event) => isLg && event.preventDefault()}
|
|
82
|
+
onCloseAutoFocus={(event) => isLg && event.preventDefault()}
|
|
83
|
+
{...slots?.content}
|
|
82
84
|
className={mx(
|
|
83
|
-
'fixed block-start-0 block-end-0 is-
|
|
84
|
-
'
|
|
85
|
-
transitionShow ? 'inline-start-0' :
|
|
85
|
+
'fixed block-start-0 block-end-0 is-sidebar z-30 overscroll-contain overflow-x-hidden overflow-y-auto',
|
|
86
|
+
'transition-[inset-inline-start,inset-inline-end] duration-200 ease-in-out',
|
|
87
|
+
transitionShow ? 'inline-start-0' : '-inline-start-sidebar',
|
|
88
|
+
slots?.content?.className
|
|
86
89
|
)}
|
|
87
90
|
>
|
|
88
91
|
<DialogPrimitive.Title className='sr-only'>{t('sidebar label')}</DialogPrimitive.Title>
|
|
89
|
-
|
|
92
|
+
{slots?.content?.children}
|
|
90
93
|
</DialogPrimitive.Content>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
role='none'
|
|
94
|
-
{...slots?.fixedBlockStart}
|
|
95
|
-
className={mx(
|
|
96
|
-
'fixed inline-end-0 block-start-0 z-[49] transition-[inset-inline-start,inset-inline-end] duration-200 ease-in-out',
|
|
97
|
-
transitionShow ? 'inline-start-[272px]' : 'inline-start-0',
|
|
98
|
-
slots?.fixedBlockStart?.className
|
|
99
|
-
)}
|
|
100
|
-
>
|
|
101
|
-
{slots?.fixedBlockStart?.children}
|
|
102
|
-
</div>
|
|
103
|
-
)}
|
|
94
|
+
|
|
95
|
+
{/* TODO(burdon): Simple comment required. */}
|
|
104
96
|
{!isLg && (
|
|
105
97
|
<DialogPrimitive.Overlay
|
|
106
98
|
className={mx(
|
|
@@ -111,11 +103,15 @@ export const PanelSidebarProvider = ({ children, slots }: PropsWithChildren<Pane
|
|
|
111
103
|
onClick={internalHide}
|
|
112
104
|
/>
|
|
113
105
|
)}
|
|
106
|
+
|
|
107
|
+
{/* Main content. */}
|
|
114
108
|
<div
|
|
115
109
|
role='none'
|
|
110
|
+
{...slots?.main}
|
|
116
111
|
className={mx(
|
|
117
|
-
'
|
|
118
|
-
isLg && isOpen ? 'pis-
|
|
112
|
+
'transition-[padding-inline-start] duration-200 ease-in-out',
|
|
113
|
+
isLg && isOpen ? 'pis-sidebar' : 'pis-0',
|
|
114
|
+
slots?.main?.className
|
|
119
115
|
)}
|
|
120
116
|
>
|
|
121
117
|
{children}
|
package/src/layouts/index.ts
CHANGED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { UserPlus, X } from 'phosphor-react';
|
|
6
|
+
import React, { cloneElement, useReducer } from 'react';
|
|
7
|
+
|
|
8
|
+
import { useClient, useDevices, useHaloInvitations, useIdentity } from '@dxos/react-client';
|
|
9
|
+
import { Button, getSize, mx, Tooltip, useTranslation } from '@dxos/react-components';
|
|
10
|
+
|
|
11
|
+
import { DeviceList, InvitationList, PanelSeparator } from '../../components';
|
|
12
|
+
import { defaultSurface, subduedSurface } from '../../styles';
|
|
13
|
+
|
|
14
|
+
export type DevicesPanelProps = {
|
|
15
|
+
titleId?: string;
|
|
16
|
+
createInvitationUrl: (invitationCode: string) => string;
|
|
17
|
+
doneActionParent?: Parameters<typeof cloneElement>[0];
|
|
18
|
+
onDone?: () => void;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type DevicesView = 'device list';
|
|
22
|
+
|
|
23
|
+
const DeviceListView = ({ createInvitationUrl, titleId, onDone, doneActionParent }: DevicesPanelProps) => {
|
|
24
|
+
const { t } = useTranslation('os');
|
|
25
|
+
const client = useClient();
|
|
26
|
+
const identity = useIdentity();
|
|
27
|
+
const devices = useDevices();
|
|
28
|
+
const invitations = useHaloInvitations();
|
|
29
|
+
const displayName = identity?.displayName;
|
|
30
|
+
|
|
31
|
+
if (!identity) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const doneButton = (
|
|
36
|
+
<Button compact variant='ghost' onClick={() => onDone?.()} data-testid='show-all-spaces'>
|
|
37
|
+
<X className={getSize(4)} weight='bold' />
|
|
38
|
+
</Button>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div role='none' className='flex flex-col'>
|
|
43
|
+
<div role='none' className={mx(subduedSurface, 'rounded-bs-md flex items-center p-2 gap-2')}>
|
|
44
|
+
{/* TODO(wittjosiah): Label this as the identity panel. */}
|
|
45
|
+
<h2 id={titleId} className={mx('grow font-system-medium', !displayName && 'font-mono')}>
|
|
46
|
+
{displayName ?? identity.identityKey.truncate()}
|
|
47
|
+
</h2>
|
|
48
|
+
<Tooltip content={t('close label')} zIndex='z-50'>
|
|
49
|
+
{doneActionParent ? cloneElement(doneActionParent, {}, doneButton) : doneButton}
|
|
50
|
+
</Tooltip>
|
|
51
|
+
</div>
|
|
52
|
+
<div role='region' className={mx(defaultSurface, 'rounded-be-md p-2')}>
|
|
53
|
+
<InvitationList
|
|
54
|
+
invitations={invitations}
|
|
55
|
+
onClickRemove={({ invitation }) => invitation && client.halo.removeInvitation(invitation.invitationId!)}
|
|
56
|
+
createInvitationUrl={createInvitationUrl}
|
|
57
|
+
/>
|
|
58
|
+
<Button
|
|
59
|
+
className='is-full flex gap-2 mbs-2'
|
|
60
|
+
compact
|
|
61
|
+
onClick={() => client.halo.createInvitation()}
|
|
62
|
+
data-testid='create-space-invitation'
|
|
63
|
+
>
|
|
64
|
+
<span>{t('create space invitation label')}</span>
|
|
65
|
+
<UserPlus className={getSize(4)} weight='bold' />
|
|
66
|
+
</Button>
|
|
67
|
+
<PanelSeparator />
|
|
68
|
+
<DeviceList devices={devices} />
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
type DevicesPanelState = {
|
|
75
|
+
activeView: DevicesView;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
type DevicesPanelAction = {
|
|
79
|
+
type: null;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// TODO(wittjosiah): Rename identity panel and include other views?
|
|
83
|
+
export const DevicesPanel = (props: DevicesPanelProps) => {
|
|
84
|
+
const reducer = (state: DevicesPanelState, action: DevicesPanelAction) => {
|
|
85
|
+
const nextState = { ...state };
|
|
86
|
+
switch (action.type) {
|
|
87
|
+
case null:
|
|
88
|
+
}
|
|
89
|
+
return nextState;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const [panelState] = useReducer(reducer, {
|
|
93
|
+
activeView: 'device list'
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// TODO(wittjosiah): Use ViewState or similar.
|
|
97
|
+
return <>{panelState.activeView === 'device list' ? <DeviceListView {...props} /> : null}</>;
|
|
98
|
+
};
|