@dxos/react-ui 0.1.28 → 0.1.30-next.7c60cd3

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 (51) hide show
  1. package/dist/lib/browser/index.mjs +161 -18
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
  5. package/dist/types/src/composites/Shell/Shell.stories.d.ts +10 -0
  6. package/dist/types/src/composites/Shell/Shell.stories.d.ts.map +1 -0
  7. package/dist/types/src/composites/Shell/ShellContext.d.ts +21 -0
  8. package/dist/types/src/composites/Shell/ShellContext.d.ts.map +1 -0
  9. package/dist/types/src/composites/Shell/index.d.ts +1 -0
  10. package/dist/types/src/composites/Shell/index.d.ts.map +1 -1
  11. package/dist/types/src/panels/JoinPanel/JoinHeading.d.ts.map +1 -1
  12. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts +1 -1
  13. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts.map +1 -1
  14. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts +1 -2
  15. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts.map +1 -1
  16. package/dist/types/src/playwright/invitations-manager.d.ts +33 -0
  17. package/dist/types/src/playwright/invitations-manager.d.ts.map +1 -0
  18. package/dist/types/src/playwright/invitations.spec.d.ts +2 -0
  19. package/dist/types/src/playwright/invitations.spec.d.ts.map +1 -0
  20. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  21. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  22. package/dist/types/src/stories/Invitations.stories.d.ts +14 -0
  23. package/dist/types/src/stories/Invitations.stories.d.ts.map +1 -0
  24. package/dist/types/src/translations/locales/en-US.d.ts +5 -0
  25. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  26. package/package.json +14 -12
  27. package/src/components/InvitationList/InvitationList.stories.tsx +1 -1
  28. package/src/components/SpaceList/SpaceListItem.tsx +1 -1
  29. package/src/composites/JoinDialog/JoinDialog.stories.tsx +1 -1
  30. package/src/composites/Shell/Shell.stories.tsx +76 -0
  31. package/src/composites/Shell/Shell.tsx +16 -2
  32. package/src/composites/Shell/ShellContext.tsx +175 -0
  33. package/src/composites/Shell/index.ts +1 -0
  34. package/src/panels/DevicesPanel/DevicesPanel.tsx +2 -2
  35. package/src/panels/JoinPanel/JoinHeading.tsx +4 -3
  36. package/src/panels/JoinPanel/JoinPanel.tsx +1 -1
  37. package/src/panels/JoinPanel/view-states/InvitationAuthenticator.tsx +2 -2
  38. package/src/panels/JoinPanel/view-states/InvitationInput.tsx +1 -1
  39. package/src/panels/SpacePanel/SpacePanel.stories.tsx +2 -40
  40. package/src/panels/SpacePanel/SpacePanel.tsx +5 -5
  41. package/src/playwright/invitations-manager.ts +210 -0
  42. package/src/playwright/invitations.spec.ts +363 -0
  43. package/src/playwright/playwright.config.ts +7 -0
  44. package/src/stories/Invitations.stories.tsx +165 -0
  45. package/src/translations/locales/en-US.ts +6 -1
  46. package/dist/types/src/testing/ClientProvider.d.ts +0 -3
  47. package/dist/types/src/testing/ClientProvider.d.ts.map +0 -1
  48. package/dist/types/src/testing/index.d.ts +0 -2
  49. package/dist/types/src/testing/index.d.ts.map +0 -1
  50. package/src/testing/ClientProvider.tsx +0 -18
  51. package/src/testing/index.ts +0 -5
@@ -457,7 +457,7 @@ function _extends7() {
457
457
  var SpaceListItem = /* @__PURE__ */ forwardRef(({ space, onClick }, ref) => {
458
458
  var _a;
459
459
  return /* @__PURE__ */ React10.createElement("li", {
460
- className: mx6("flex gap-2 items-center", onClick && "cursor-pointer"),
460
+ className: mx6("flex gap-2 items-center mbe-2", onClick && "cursor-pointer"),
461
461
  onClick: () => onClick == null ? void 0 : onClick(),
462
462
  ref,
463
463
  "data-testid": "space-list-item"
@@ -729,8 +729,8 @@ var DeviceListView = ({ createInvitationUrl, titleId, onDone, doneActionParent }
729
729
  }), /* @__PURE__ */ React15.createElement(Button2, {
730
730
  className: "is-full flex gap-2 mbs-2",
731
731
  onClick: () => client.halo.createInvitation(),
732
- "data-testid": "create-space-invitation"
733
- }, /* @__PURE__ */ React15.createElement("span", null, t("create space invitation label")), /* @__PURE__ */ React15.createElement(UserPlus, {
732
+ "data-testid": "devices-panel.create-invitation"
733
+ }, /* @__PURE__ */ React15.createElement("span", null, t("create device invitation label")), /* @__PURE__ */ React15.createElement(UserPlus, {
734
734
  className: getSize3(4),
735
735
  weight: "bold"
736
736
  })), /* @__PURE__ */ React15.createElement(PanelSeparator, null), /* @__PURE__ */ React15.createElement(DeviceList, {
@@ -795,8 +795,8 @@ import { DensityProvider as DensityProvider3, useId as useId4 } from "@dxos/reac
795
795
 
796
796
  // packages/apps/patterns/react-ui/src/panels/JoinPanel/JoinHeading.tsx
797
797
  import { ProhibitInset as ProhibitInset2 } from "phosphor-react";
798
- import React17, { cloneElement as cloneElement2 } from "react";
799
- import { useSpace as useSpace2, withReactorRef } from "@dxos/react-client";
798
+ import React17, { cloneElement as cloneElement2, forwardRef as forwardRef2 } from "react";
799
+ import { useSpace as useSpace2 } from "@dxos/react-client";
800
800
  import { Avatar as Avatar4, Button as Button4, getSize as getSize4, Heading, mx as mx12, Trans, useId as useId2, useTranslation as useTranslation7 } from "@dxos/react-components";
801
801
  function _extends13() {
802
802
  _extends13 = Object.assign || function(target) {
@@ -812,7 +812,7 @@ function _extends13() {
812
812
  };
813
813
  return _extends13.apply(this, arguments);
814
814
  }
815
- var JoinHeading = withReactorRef(({ mode, titleId, invitation, onExit, exitActionParent, preventExit }, ref) => {
815
+ var JoinHeading = /* @__PURE__ */ forwardRef2(({ mode, titleId, invitation, onExit, exitActionParent, preventExit }, ref) => {
816
816
  var _a, _b, _c, _d, _e, _f;
817
817
  const { t } = useTranslation7("os");
818
818
  const space = useSpace2((_a = invitation == null ? void 0 : invitation.invitation) == null ? void 0 : _a.spaceKey);
@@ -1476,10 +1476,10 @@ var InvitationInput = ({ invitationType, ...viewStateProps }) => {
1476
1476
  },
1477
1477
  input: {
1478
1478
  "data-autofocus": `${invitationType} invitation acceptor; invitation input`,
1479
+ "data-testid": `${invitationType}-invitation-input`,
1479
1480
  onKeyUp: ({ key }) => key === "Enter" && handleNext()
1480
1481
  }
1481
- },
1482
- "data-testid": "invitation-input"
1482
+ }
1483
1483
  }), /* @__PURE__ */ React24.createElement("div", {
1484
1484
  role: "none",
1485
1485
  className: "grow"
@@ -1654,14 +1654,13 @@ var PureInvitationAuthenticatorContent = ({ disabled, failed, dispatch, invitati
1654
1654
  disabled,
1655
1655
  inputMode: "numeric",
1656
1656
  pattern: "\\d*",
1657
- "data-autofocus": `${invitationType} invitation acceptor; invitation authenticator`
1657
+ "data-autofocus": `${invitationType} invitation acceptor; invitation authenticator`,
1658
+ "data-testid": `${invitationType}-auth-code-input`
1658
1659
  }
1659
1660
  }
1660
1661
  }, failed && {
1661
1662
  validationValence: "error",
1662
1663
  validationMessage: t("failed to authenticate message")
1663
- }, {
1664
- "data-testid": "auth-code-input"
1665
1664
  })), /* @__PURE__ */ React26.createElement("div", {
1666
1665
  role: "none",
1667
1666
  className: "grow"
@@ -2074,7 +2073,7 @@ var JoinPanel = ({ mode, initialInvitationCode, titleId: propsTitleId, exitActio
2074
2073
  // packages/apps/patterns/react-ui/src/panels/SpacePanel/SpacePanel.tsx
2075
2074
  import { UserPlus as UserPlus3 } from "phosphor-react";
2076
2075
  import React28, { useReducer as useReducer3 } from "react";
2077
- import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client";
2076
+ import { useSpaceInvitations as useSpaceInvitations2, observer } from "@dxos/react-client";
2078
2077
  import { Button as Button13, DensityProvider as DensityProvider4, getSize as getSize14, mx as mx22, useTranslation as useTranslation17 } from "@dxos/react-components";
2079
2078
  function _extends24() {
2080
2079
  _extends24 = Object.assign || function(target) {
@@ -2090,7 +2089,7 @@ function _extends24() {
2090
2089
  };
2091
2090
  return _extends24.apply(this, arguments);
2092
2091
  }
2093
- var CurrentSpaceView = ({ space, createInvitationUrl, titleId }) => {
2092
+ var CurrentSpaceView = observer(({ space, createInvitationUrl, titleId }) => {
2094
2093
  const { t } = useTranslation17("os");
2095
2094
  const invitations = useSpaceInvitations2(space == null ? void 0 : space.key);
2096
2095
  const name = space == null ? void 0 : space.properties.name;
@@ -2116,7 +2115,7 @@ var CurrentSpaceView = ({ space, createInvitationUrl, titleId }) => {
2116
2115
  }), /* @__PURE__ */ React28.createElement(Button13, {
2117
2116
  className: "is-full flex gap-2 mbs-2",
2118
2117
  onClick: () => space == null ? void 0 : space.createInvitation(),
2119
- "data-testid": "create-space-invitation"
2118
+ "data-testid": "spaces-panel.create-invitation"
2120
2119
  }, /* @__PURE__ */ React28.createElement("span", null, t("create space invitation label")), /* @__PURE__ */ React28.createElement(UserPlus3, {
2121
2120
  className: getSize14(4),
2122
2121
  weight: "bold"
@@ -2124,7 +2123,7 @@ var CurrentSpaceView = ({ space, createInvitationUrl, titleId }) => {
2124
2123
  spaceKey: space.key,
2125
2124
  includeSelf: true
2126
2125
  })));
2127
- };
2126
+ });
2128
2127
  var SpacePanel = (props) => {
2129
2128
  const reducer = (state, action) => {
2130
2129
  const nextState = {
@@ -2222,6 +2221,7 @@ var JoinDialog = ({ slots, ...joinPanelProps }) => {
2222
2221
 
2223
2222
  // packages/apps/patterns/react-ui/src/composites/Shell/Shell.tsx
2224
2223
  import React33, { useEffect as useEffect2, useState as useState7 } from "react";
2224
+ import { log as log2 } from "@dxos/log";
2225
2225
  import { ShellDisplay, ShellLayout } from "@dxos/protocols/proto/dxos/iframe";
2226
2226
  import { useClient as useClient7, useSpace as useSpace3, useSpaces } from "@dxos/react-client";
2227
2227
 
@@ -2330,6 +2330,27 @@ var Shell = ({ runtime, origin }) => {
2330
2330
  }, [
2331
2331
  runtime
2332
2332
  ]);
2333
+ useEffect2(() => {
2334
+ if (layout === ShellLayout.SPACE_INVITATIONS && !space) {
2335
+ log2.warn("No space found for shell space invitations.", {}, {
2336
+ file: "Shell.tsx",
2337
+ line: 33,
2338
+ scope: void 0,
2339
+ callSite: (f, a) => f(...a)
2340
+ });
2341
+ const timeout = setTimeout(async () => {
2342
+ await runtime.setAppContext({
2343
+ display: ShellDisplay.NONE
2344
+ });
2345
+ runtime.setLayout(ShellLayout.DEFAULT);
2346
+ });
2347
+ return () => clearTimeout(timeout);
2348
+ }
2349
+ }, [
2350
+ runtime,
2351
+ layout,
2352
+ space
2353
+ ]);
2333
2354
  switch (layout) {
2334
2355
  case ShellLayout.INITIALIZE_IDENTITY:
2335
2356
  return /* @__PURE__ */ React33.createElement(JoinDialog, {
@@ -2354,7 +2375,7 @@ var Shell = ({ runtime, origin }) => {
2354
2375
  }
2355
2376
  });
2356
2377
  case ShellLayout.SPACE_INVITATIONS:
2357
- return /* @__PURE__ */ React33.createElement(SpaceDialog, {
2378
+ return space ? /* @__PURE__ */ React33.createElement(SpaceDialog, {
2358
2379
  space,
2359
2380
  createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
2360
2381
  onDone: async () => {
@@ -2363,7 +2384,7 @@ var Shell = ({ runtime, origin }) => {
2363
2384
  });
2364
2385
  runtime.setLayout(ShellLayout.DEFAULT);
2365
2386
  }
2366
- });
2387
+ }) : null;
2367
2388
  case ShellLayout.JOIN_SPACE:
2368
2389
  return /* @__PURE__ */ React33.createElement(JoinDialog, {
2369
2390
  initialInvitationCode: invitationCode,
@@ -2387,6 +2408,120 @@ var Shell = ({ runtime, origin }) => {
2387
2408
  }
2388
2409
  };
2389
2410
 
2411
+ // packages/apps/patterns/react-ui/src/composites/Shell/ShellContext.tsx
2412
+ import React34, { createContext as createContext2, useCallback as useCallback6, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo3, useState as useState8 } from "react";
2413
+ import { IFrameClientServicesProxy, MemoryShellRuntime, ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout2 } from "@dxos/client";
2414
+ import { useClient as useClient8, useIdentity as useIdentity3 } from "@dxos/react-client";
2415
+ import { mx as mx24 } from "@dxos/react-components";
2416
+ var ShellContext = /* @__PURE__ */ createContext2({});
2417
+ var useShell = () => {
2418
+ const client = useClient8();
2419
+ const { runtime, setDisplay } = useContext2(ShellContext);
2420
+ const setLayout = async (layout, options) => {
2421
+ if (runtime) {
2422
+ if (layout === ShellLayout2.DEFAULT) {
2423
+ setDisplay == null ? void 0 : setDisplay(ShellDisplay2.NONE);
2424
+ } else {
2425
+ setDisplay == null ? void 0 : setDisplay(ShellDisplay2.FULLSCREEN);
2426
+ }
2427
+ runtime.setLayout(layout, options);
2428
+ }
2429
+ if (client.services instanceof IFrameClientServicesProxy) {
2430
+ await client.services.setLayout(layout, options);
2431
+ }
2432
+ };
2433
+ return {
2434
+ setLayout
2435
+ };
2436
+ };
2437
+ var ShellProvider = ({ space, haloInvitationCode, spaceInvitationCode, onJoinedSpace, children }) => {
2438
+ useEffect3(() => {
2439
+ if (client.services instanceof IFrameClientServicesProxy && onJoinedSpace) {
2440
+ return client.services.joinedSpace.on(onJoinedSpace);
2441
+ }
2442
+ }, []);
2443
+ useEffect3(() => {
2444
+ if (client.services instanceof IFrameClientServicesProxy) {
2445
+ client.services.setSpaceProvider(() => space == null ? void 0 : space.key);
2446
+ }
2447
+ }, [
2448
+ space
2449
+ ]);
2450
+ const client = useClient8();
2451
+ const identity = useIdentity3();
2452
+ const [display, setDisplay] = useState8(!identity || spaceInvitationCode || haloInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
2453
+ const shellRuntime = useMemo3(() => {
2454
+ if (client.config.get("runtime.app.env.DX_VAULT") === "true") {
2455
+ return;
2456
+ }
2457
+ if (spaceInvitationCode) {
2458
+ return new MemoryShellRuntime({
2459
+ layout: ShellLayout2.JOIN_SPACE,
2460
+ invitationCode: spaceInvitationCode
2461
+ });
2462
+ }
2463
+ return new MemoryShellRuntime({
2464
+ layout: identity ? ShellLayout2.DEFAULT : ShellLayout2.INITIALIZE_IDENTITY,
2465
+ invitationCode: haloInvitationCode != null ? haloInvitationCode : void 0
2466
+ });
2467
+ }, [
2468
+ client,
2469
+ identity,
2470
+ spaceInvitationCode,
2471
+ haloInvitationCode
2472
+ ]);
2473
+ const handleKeyDown = useCallback6((event) => {
2474
+ if (!space || !shellRuntime) {
2475
+ return;
2476
+ }
2477
+ const modifier = event.ctrlKey || event.metaKey;
2478
+ if (event.key === ">" && event.shiftKey && modifier) {
2479
+ shellRuntime.setLayout(ShellLayout2.DEVICE_INVITATIONS);
2480
+ setDisplay(ShellDisplay2.FULLSCREEN);
2481
+ } else if (event.key === "." && modifier) {
2482
+ shellRuntime.setLayout(ShellLayout2.SPACE_INVITATIONS, {
2483
+ spaceKey: space.key
2484
+ });
2485
+ setDisplay(ShellDisplay2.FULLSCREEN);
2486
+ }
2487
+ }, [
2488
+ space,
2489
+ shellRuntime
2490
+ ]);
2491
+ useEffect3(() => {
2492
+ if (!shellRuntime) {
2493
+ return;
2494
+ }
2495
+ window.addEventListener("keydown", handleKeyDown);
2496
+ return () => window.removeEventListener("keydown", handleKeyDown);
2497
+ }, [
2498
+ shellRuntime,
2499
+ handleKeyDown
2500
+ ]);
2501
+ useEffect3(() => {
2502
+ if (!shellRuntime) {
2503
+ return;
2504
+ }
2505
+ return shellRuntime.contextUpdate.on(({ display: display2, spaceKey }) => {
2506
+ setDisplay(display2);
2507
+ onJoinedSpace == null ? void 0 : onJoinedSpace(spaceKey);
2508
+ });
2509
+ }, [
2510
+ shellRuntime
2511
+ ]);
2512
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, shellRuntime && /* @__PURE__ */ React34.createElement("div", {
2513
+ className: mx24(display === ShellDisplay2.NONE ? "hidden" : "")
2514
+ }, /* @__PURE__ */ React34.createElement(Shell, {
2515
+ runtime: shellRuntime,
2516
+ origin: window.location.origin
2517
+ })), /* @__PURE__ */ React34.createElement(ShellContext.Provider, {
2518
+ value: {
2519
+ runtime: shellRuntime,
2520
+ setDisplay
2521
+ }
2522
+ }, identity ? children : void 0));
2523
+ };
2524
+
2390
2525
  // packages/apps/patterns/react-ui/src/translations/locales/en-US.ts
2391
2526
  var en_US_exports = {};
2392
2527
  __export(en_US_exports, {
@@ -2440,6 +2575,7 @@ var os = {
2440
2575
  "reset label": "Start over",
2441
2576
  "auth code input label": "Auth code provided by the invitation sender",
2442
2577
  "invitation input label": "Paste an invitation code or URL",
2578
+ "create device invitation label": "Invite",
2443
2579
  "create space invitation label": "Invite",
2444
2580
  "qr label": "Scan to accept invitation",
2445
2581
  "empty invitations message": "No pending invitations",
@@ -2447,7 +2583,11 @@ var os = {
2447
2583
  "all spaces label": "All spaces",
2448
2584
  "create space label": "Create a new space",
2449
2585
  "join space label": "Join a space",
2450
- "show current space label": "Current space"
2586
+ "show current space label": "Current space",
2587
+ "view space invitations label": "View space invitations",
2588
+ "toggle sidebar label": "Open/close sidebar",
2589
+ "open sidebar label": "Open sidebar",
2590
+ "close sidebar label": "Close sidebar"
2451
2591
  };
2452
2592
 
2453
2593
  // packages/apps/patterns/react-ui/src/translations/index.ts
@@ -2473,6 +2613,8 @@ export {
2473
2613
  PanelSidebarContext,
2474
2614
  PanelSidebarProvider,
2475
2615
  Shell,
2616
+ ShellContext,
2617
+ ShellProvider,
2476
2618
  SpaceDialog,
2477
2619
  SpaceListItem,
2478
2620
  SpaceMemberList,
@@ -2502,6 +2644,7 @@ export {
2502
2644
  successBgColor,
2503
2645
  successStrokeColor,
2504
2646
  successTextColor,
2647
+ useShell,
2505
2648
  useTogglePanelSidebar
2506
2649
  };
2507
2650
  //# sourceMappingURL=index.mjs.map