@dxos/plugin-deck 0.8.4-main.c85a9c8dae → 0.8.4-main.d05673bc65

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 (113) hide show
  1. package/dist/lib/browser/Banner-HXRXEUOZ.mjs +14 -0
  2. package/dist/lib/{node-esm/Banner-HR7DPUZU.mjs.map → browser/Banner-HXRXEUOZ.mjs.map} +1 -1
  3. package/dist/lib/browser/{DeckSettings-HB5TKG2F.mjs → DeckSettings-HSSQKFNE.mjs} +3 -3
  4. package/dist/lib/browser/{app-graph-builder-22XAL7YE.mjs → app-graph-builder-MP6INIM2.mjs} +7 -7
  5. package/dist/lib/browser/{app-graph-builder-22XAL7YE.mjs.map → app-graph-builder-MP6INIM2.mjs.map} +1 -1
  6. package/dist/lib/browser/{check-app-scheme-ZV3QWNNZ.mjs → check-app-scheme-AUNCD2Y6.mjs} +3 -3
  7. package/dist/lib/browser/{chunk-OAPMV5ZR.mjs → chunk-3P2FJVXC.mjs} +15 -17
  8. package/dist/lib/browser/chunk-3P2FJVXC.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-YGOOWRJE.mjs → chunk-ITNJS5QX.mjs} +27 -31
  10. package/dist/lib/browser/chunk-ITNJS5QX.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-FBL4WVYZ.mjs → chunk-L3RYMAV7.mjs} +2 -2
  12. package/dist/lib/browser/{chunk-FBL4WVYZ.mjs.map → chunk-L3RYMAV7.mjs.map} +1 -1
  13. package/dist/lib/browser/{chunk-Q4GUCIRE.mjs → chunk-TAHLKBDO.mjs} +6 -19
  14. package/dist/lib/browser/chunk-TAHLKBDO.mjs.map +7 -0
  15. package/dist/lib/browser/index.mjs +12 -13
  16. package/dist/lib/browser/index.mjs.map +1 -1
  17. package/dist/lib/browser/meta.json +1 -1
  18. package/dist/lib/browser/{operation-resolver-BLZGJWLO.mjs → operation-resolver-2TEGT4PG.mjs} +78 -19
  19. package/dist/lib/browser/operation-resolver-2TEGT4PG.mjs.map +7 -0
  20. package/dist/lib/browser/{react-root-4ESZAM6D.mjs → react-root-AS4IOYDG.mjs} +5 -6
  21. package/dist/lib/{node-esm/react-root-YO7IIC75.mjs.map → browser/react-root-AS4IOYDG.mjs.map} +1 -1
  22. package/dist/lib/browser/{react-surface-KYQGCALN.mjs → react-surface-FH7TC6WW.mjs} +6 -6
  23. package/dist/lib/browser/{react-surface-KYQGCALN.mjs.map → react-surface-FH7TC6WW.mjs.map} +1 -1
  24. package/dist/lib/browser/{settings-RY2TBSGP.mjs → settings-PTMGCSJH.mjs} +3 -3
  25. package/dist/lib/browser/{state-CSTTMJ43.mjs → state-MA4SQ7BE.mjs} +4 -4
  26. package/dist/lib/browser/{state-CSTTMJ43.mjs.map → state-MA4SQ7BE.mjs.map} +1 -1
  27. package/dist/lib/browser/{toolkit-EONRPYA5.mjs → toolkit-6B34QFU3.mjs} +3 -3
  28. package/dist/lib/browser/types/index.mjs +2 -4
  29. package/dist/lib/browser/{url-handler-EM3SYHHX.mjs → url-handler-FEUFPQIP.mjs} +14 -11
  30. package/dist/lib/browser/url-handler-FEUFPQIP.mjs.map +7 -0
  31. package/dist/lib/node-esm/{Banner-HR7DPUZU.mjs → Banner-RN7XXOXY.mjs} +5 -6
  32. package/dist/lib/node-esm/{DeckSettings-MWTR7HU2.mjs → DeckSettings-DJRFLKQS.mjs} +3 -3
  33. package/dist/lib/node-esm/{app-graph-builder-GNNNCWGN.mjs → app-graph-builder-ACHG5HY7.mjs} +7 -7
  34. package/dist/lib/node-esm/{app-graph-builder-GNNNCWGN.mjs.map → app-graph-builder-ACHG5HY7.mjs.map} +1 -1
  35. package/dist/lib/node-esm/{check-app-scheme-ZNISVRFH.mjs → check-app-scheme-WN76GWVC.mjs} +3 -3
  36. package/dist/lib/node-esm/{chunk-O4IOJICP.mjs → chunk-EMU4VIPH.mjs} +6 -19
  37. package/dist/lib/node-esm/chunk-EMU4VIPH.mjs.map +7 -0
  38. package/dist/lib/node-esm/{chunk-L2NPJPGL.mjs → chunk-GZJAQ5IP.mjs} +15 -17
  39. package/dist/lib/node-esm/chunk-GZJAQ5IP.mjs.map +7 -0
  40. package/dist/lib/node-esm/{chunk-Z43MBISY.mjs → chunk-MBCCNIWY.mjs} +27 -31
  41. package/dist/lib/node-esm/chunk-MBCCNIWY.mjs.map +7 -0
  42. package/dist/lib/node-esm/{chunk-EGFOT3DE.mjs → chunk-XCNF4COU.mjs} +2 -2
  43. package/dist/lib/node-esm/{chunk-EGFOT3DE.mjs.map → chunk-XCNF4COU.mjs.map} +1 -1
  44. package/dist/lib/node-esm/index.mjs +12 -13
  45. package/dist/lib/node-esm/index.mjs.map +1 -1
  46. package/dist/lib/node-esm/meta.json +1 -1
  47. package/dist/lib/node-esm/{operation-resolver-5BYDNQND.mjs → operation-resolver-GCMCCI7A.mjs} +78 -19
  48. package/dist/lib/node-esm/operation-resolver-GCMCCI7A.mjs.map +7 -0
  49. package/dist/lib/node-esm/{react-root-YO7IIC75.mjs → react-root-7DTDLAF4.mjs} +5 -6
  50. package/dist/lib/node-esm/{react-surface-G7VRKT4U.mjs → react-surface-U6Z2K324.mjs} +6 -6
  51. package/dist/lib/node-esm/{react-surface-G7VRKT4U.mjs.map → react-surface-U6Z2K324.mjs.map} +1 -1
  52. package/dist/lib/node-esm/{settings-GYLWWOBK.mjs → settings-LPPFLXNJ.mjs} +3 -3
  53. package/dist/lib/node-esm/{state-RQXTBWUX.mjs → state-KNRU3GDC.mjs} +4 -4
  54. package/dist/lib/node-esm/{state-RQXTBWUX.mjs.map → state-KNRU3GDC.mjs.map} +1 -1
  55. package/dist/lib/node-esm/{toolkit-EU3Z2R4H.mjs → toolkit-SOWYKJY3.mjs} +3 -3
  56. package/dist/lib/node-esm/types/index.mjs +2 -4
  57. package/dist/lib/node-esm/{url-handler-VUK2LBJV.mjs → url-handler-4LEB7UWF.mjs} +14 -11
  58. package/dist/lib/node-esm/url-handler-4LEB7UWF.mjs.map +7 -0
  59. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -1
  60. package/dist/types/src/capabilities/url-handler/url-handler.d.ts.map +1 -1
  61. package/dist/types/src/components/Plank/Plank.d.ts.map +1 -1
  62. package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -1
  63. package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -1
  64. package/dist/types/src/hooks/useDeckCompanions.d.ts +0 -1
  65. package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -1
  66. package/dist/types/src/hooks/useSelectedCompanion.d.ts.map +1 -1
  67. package/dist/types/src/layout.d.ts +1 -7
  68. package/dist/types/src/layout.d.ts.map +1 -1
  69. package/dist/types/src/types/schema.d.ts +10 -10
  70. package/dist/types/src/types/schema.d.ts.map +1 -1
  71. package/dist/types/tsconfig.tsbuildinfo +1 -1
  72. package/package.json +34 -34
  73. package/src/capabilities/app-graph-builder/app-graph-builder.ts +4 -4
  74. package/src/capabilities/operation-resolver/operation-resolver.ts +5 -7
  75. package/src/capabilities/react-surface/react-surface.tsx +2 -2
  76. package/src/capabilities/state/state.ts +1 -1
  77. package/src/capabilities/url-handler/url-handler.ts +11 -9
  78. package/src/components/Plank/Plank.tsx +11 -6
  79. package/src/components/Plank/PlankHeading.tsx +5 -6
  80. package/src/components/Sidebar/ComplementarySidebar.tsx +12 -19
  81. package/src/components/Sidebar/SidebarButton.tsx +3 -3
  82. package/src/hooks/useDeckCompanions.ts +1 -6
  83. package/src/hooks/useSelectedCompanion.ts +4 -10
  84. package/src/layout.ts +1 -14
  85. package/src/meta.ts +1 -1
  86. package/src/types/capabilities.ts +3 -3
  87. package/src/types/events.ts +1 -1
  88. package/src/types/schema.ts +8 -10
  89. package/dist/lib/browser/Banner-DR6B7XTO.mjs +0 -15
  90. package/dist/lib/browser/chunk-OAPMV5ZR.mjs.map +0 -7
  91. package/dist/lib/browser/chunk-Q4GUCIRE.mjs.map +0 -7
  92. package/dist/lib/browser/chunk-SKBPLX5T.mjs +0 -81
  93. package/dist/lib/browser/chunk-SKBPLX5T.mjs.map +0 -7
  94. package/dist/lib/browser/chunk-YGOOWRJE.mjs.map +0 -7
  95. package/dist/lib/browser/operation-resolver-BLZGJWLO.mjs.map +0 -7
  96. package/dist/lib/browser/url-handler-EM3SYHHX.mjs.map +0 -7
  97. package/dist/lib/node-esm/chunk-IR6ODCNC.mjs +0 -83
  98. package/dist/lib/node-esm/chunk-IR6ODCNC.mjs.map +0 -7
  99. package/dist/lib/node-esm/chunk-L2NPJPGL.mjs.map +0 -7
  100. package/dist/lib/node-esm/chunk-O4IOJICP.mjs.map +0 -7
  101. package/dist/lib/node-esm/chunk-Z43MBISY.mjs.map +0 -7
  102. package/dist/lib/node-esm/operation-resolver-5BYDNQND.mjs.map +0 -7
  103. package/dist/lib/node-esm/url-handler-VUK2LBJV.mjs.map +0 -7
  104. /package/dist/lib/browser/{DeckSettings-HB5TKG2F.mjs.map → DeckSettings-HSSQKFNE.mjs.map} +0 -0
  105. /package/dist/lib/browser/{check-app-scheme-ZV3QWNNZ.mjs.map → check-app-scheme-AUNCD2Y6.mjs.map} +0 -0
  106. /package/dist/lib/browser/{settings-RY2TBSGP.mjs.map → settings-PTMGCSJH.mjs.map} +0 -0
  107. /package/dist/lib/browser/{toolkit-EONRPYA5.mjs.map → toolkit-6B34QFU3.mjs.map} +0 -0
  108. /package/dist/lib/{browser/Banner-DR6B7XTO.mjs.map → node-esm/Banner-RN7XXOXY.mjs.map} +0 -0
  109. /package/dist/lib/node-esm/{DeckSettings-MWTR7HU2.mjs.map → DeckSettings-DJRFLKQS.mjs.map} +0 -0
  110. /package/dist/lib/node-esm/{check-app-scheme-ZNISVRFH.mjs.map → check-app-scheme-WN76GWVC.mjs.map} +0 -0
  111. /package/dist/lib/{browser/react-root-4ESZAM6D.mjs.map → node-esm/react-root-7DTDLAF4.mjs.map} +0 -0
  112. /package/dist/lib/node-esm/{settings-GYLWWOBK.mjs.map → settings-LPPFLXNJ.mjs.map} +0 -0
  113. /package/dist/lib/node-esm/{toolkit-EU3Z2R4H.mjs.map → toolkit-SOWYKJY3.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-deck",
3
- "version": "0.8.4-main.c85a9c8dae",
3
+ "version": "0.8.4-main.d05673bc65",
4
4
  "description": "DXOS Surface plugin for the main application layout.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -44,33 +44,33 @@
44
44
  "@fluentui/react-tabster": "9.26.11",
45
45
  "@radix-ui/react-context": "1.1.1",
46
46
  "immer": "^10.1.1",
47
- "@dxos/ai": "0.8.4-main.c85a9c8dae",
48
- "@dxos/assistant": "0.8.4-main.c85a9c8dae",
49
- "@dxos/app-toolkit": "0.8.4-main.c85a9c8dae",
50
- "@dxos/blueprints": "0.8.4-main.c85a9c8dae",
51
- "@dxos/async": "0.8.4-main.c85a9c8dae",
52
- "@dxos/debug": "0.8.4-main.c85a9c8dae",
53
- "@dxos/echo": "0.8.4-main.c85a9c8dae",
54
- "@dxos/invariant": "0.8.4-main.c85a9c8dae",
55
- "@dxos/effect": "0.8.4-main.c85a9c8dae",
56
- "@dxos/keyboard": "0.8.4-main.c85a9c8dae",
57
- "@dxos/log": "0.8.4-main.c85a9c8dae",
58
- "@dxos/operation": "0.8.4-main.c85a9c8dae",
59
- "@dxos/plugin-attention": "0.8.4-main.c85a9c8dae",
60
- "@dxos/plugin-observability": "0.8.4-main.c85a9c8dae",
61
- "@dxos/plugin-graph": "0.8.4-main.c85a9c8dae",
62
- "@dxos/plugin-theme": "0.8.4-main.c85a9c8dae",
63
- "@dxos/react-client": "0.8.4-main.c85a9c8dae",
64
- "@dxos/react-error-boundary": "0.8.4-main.c85a9c8dae",
65
- "@dxos/app-framework": "0.8.4-main.c85a9c8dae",
66
- "@dxos/react-ui-form": "0.8.4-main.c85a9c8dae",
67
- "@dxos/react-ui-attention": "0.8.4-main.c85a9c8dae",
68
- "@dxos/react-ui-mosaic": "0.8.4-main.c85a9c8dae",
69
- "@dxos/react-ui-tabs": "0.8.4-main.c85a9c8dae",
70
- "@dxos/react-ui-stack": "0.8.4-main.c85a9c8dae",
71
- "@dxos/util": "0.8.4-main.c85a9c8dae",
72
- "@dxos/react-ui-text-tooltip": "0.8.4-main.c85a9c8dae",
73
- "@dxos/ui-types": "0.8.4-main.c85a9c8dae"
47
+ "@dxos/ai": "0.8.4-main.d05673bc65",
48
+ "@dxos/assistant": "0.8.4-main.d05673bc65",
49
+ "@dxos/app-toolkit": "0.8.4-main.d05673bc65",
50
+ "@dxos/async": "0.8.4-main.d05673bc65",
51
+ "@dxos/blueprints": "0.8.4-main.d05673bc65",
52
+ "@dxos/app-framework": "0.8.4-main.d05673bc65",
53
+ "@dxos/debug": "0.8.4-main.d05673bc65",
54
+ "@dxos/echo": "0.8.4-main.d05673bc65",
55
+ "@dxos/effect": "0.8.4-main.d05673bc65",
56
+ "@dxos/invariant": "0.8.4-main.d05673bc65",
57
+ "@dxos/keyboard": "0.8.4-main.d05673bc65",
58
+ "@dxos/operation": "0.8.4-main.d05673bc65",
59
+ "@dxos/log": "0.8.4-main.d05673bc65",
60
+ "@dxos/plugin-attention": "0.8.4-main.d05673bc65",
61
+ "@dxos/plugin-graph": "0.8.4-main.d05673bc65",
62
+ "@dxos/plugin-observability": "0.8.4-main.d05673bc65",
63
+ "@dxos/plugin-theme": "0.8.4-main.d05673bc65",
64
+ "@dxos/react-client": "0.8.4-main.d05673bc65",
65
+ "@dxos/react-ui-attention": "0.8.4-main.d05673bc65",
66
+ "@dxos/react-error-boundary": "0.8.4-main.d05673bc65",
67
+ "@dxos/react-ui-form": "0.8.4-main.d05673bc65",
68
+ "@dxos/react-ui-tabs": "0.8.4-main.d05673bc65",
69
+ "@dxos/ui-types": "0.8.4-main.d05673bc65",
70
+ "@dxos/react-ui-text-tooltip": "0.8.4-main.d05673bc65",
71
+ "@dxos/util": "0.8.4-main.d05673bc65",
72
+ "@dxos/react-ui-stack": "0.8.4-main.d05673bc65",
73
+ "@dxos/react-ui-mosaic": "0.8.4-main.d05673bc65"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@effect-atom/atom-react": "^0.5.0",
@@ -81,10 +81,10 @@
81
81
  "react": "~19.2.3",
82
82
  "react-dom": "~19.2.3",
83
83
  "vite": "^7.1.11",
84
- "@dxos/plugin-testing": "0.8.4-main.c85a9c8dae",
85
- "@dxos/react-ui": "0.8.4-main.c85a9c8dae",
86
- "@dxos/ui-theme": "0.8.4-main.c85a9c8dae",
87
- "@dxos/storybook-utils": "0.8.4-main.c85a9c8dae"
84
+ "@dxos/plugin-testing": "0.8.4-main.d05673bc65",
85
+ "@dxos/react-ui": "0.8.4-main.d05673bc65",
86
+ "@dxos/storybook-utils": "0.8.4-main.d05673bc65",
87
+ "@dxos/ui-theme": "0.8.4-main.d05673bc65"
88
88
  },
89
89
  "peerDependencies": {
90
90
  "@effect-atom/atom-react": "^0.5.0",
@@ -92,8 +92,8 @@
92
92
  "effect": "3.19.16",
93
93
  "react": "~19.2.3",
94
94
  "react-dom": "~19.2.3",
95
- "@dxos/react-ui": "0.8.4-main.c85a9c8dae",
96
- "@dxos/ui-theme": "0.8.4-main.c85a9c8dae"
95
+ "@dxos/react-ui": "0.8.4-main.d05673bc65",
96
+ "@dxos/ui-theme": "0.8.4-main.d05673bc65"
97
97
  },
98
98
  "publishConfig": {
99
99
  "access": "public"
@@ -41,7 +41,7 @@ export default Capability.makeModule(
41
41
  // };
42
42
 
43
43
  const closeCurrent = {
44
- id: `${LayoutOperation.Close.meta.key}/current`,
44
+ id: `${LayoutOperation.Close.meta.key}.current`,
45
45
  data: Effect.fnUntraced(function* () {
46
46
  const attention = yield* Capability.get(AttentionCapabilities.Attention);
47
47
  const attended = attention.getCurrent().at(-1);
@@ -56,7 +56,7 @@ export default Capability.makeModule(
56
56
  };
57
57
 
58
58
  const closeOthers = {
59
- id: `${LayoutOperation.Close.meta.key}/others`,
59
+ id: `${LayoutOperation.Close.meta.key}.others`,
60
60
  data: Effect.fnUntraced(function* () {
61
61
  const attention = yield* Capability.get(AttentionCapabilities.Attention);
62
62
  const deck = yield* DeckCapabilities.getDeck();
@@ -71,7 +71,7 @@ export default Capability.makeModule(
71
71
  };
72
72
 
73
73
  const closeAll = {
74
- id: `${LayoutOperation.Close.meta.key}/all`,
74
+ id: `${LayoutOperation.Close.meta.key}.all`,
75
75
  data: Effect.fnUntraced(function* () {
76
76
  const deck = yield* DeckCapabilities.getDeck();
77
77
  yield* Operation.invoke(LayoutOperation.Close, { subject: deck.active });
@@ -86,7 +86,7 @@ export default Capability.makeModule(
86
86
  const deck = state.decks[state.activeDeck];
87
87
 
88
88
  const toggleSidebar = {
89
- id: `${LayoutOperation.UpdateSidebar.meta.key}/nav`,
89
+ id: `${LayoutOperation.UpdateSidebar.meta.key}.nav`,
90
90
  data: Effect.fnUntraced(function* () {
91
91
  yield* Capabilities.updateAtomValue(DeckCapabilities.State, (s) => ({
92
92
  ...s,
@@ -7,7 +7,7 @@ import * as Function from 'effect/Function';
7
7
  import * as Option from 'effect/Option';
8
8
 
9
9
  import { Capabilities, Capability, UndoOperation } from '@dxos/app-framework';
10
- import { AppCapabilities, LayoutOperation } from '@dxos/app-toolkit';
10
+ import { AppCapabilities, LayoutOperation, getCompanionVariant, isPinnedWorkspace } from '@dxos/app-toolkit';
11
11
  import { Obj } from '@dxos/echo';
12
12
  import { invariant } from '@dxos/invariant';
13
13
  import { log } from '@dxos/log';
@@ -18,10 +18,9 @@ import { Graph, Node } from '@dxos/plugin-graph';
18
18
  import { ObservabilityOperation } from '@dxos/plugin-observability/types';
19
19
  import { byPosition, isNonNullable } from '@dxos/util';
20
20
 
21
- import { closeEntry, createEntryId, incrementPlank, openEntry } from '../../layout';
21
+ import { closeEntry, incrementPlank, openEntry } from '../../layout';
22
22
  import { meta } from '../../meta';
23
23
  import {
24
- ATTENDABLE_PATH_SEPARATOR,
25
24
  DeckCapabilities,
26
25
  DeckOperation,
27
26
  type DeckState,
@@ -273,7 +272,7 @@ export default Capability.makeModule(
273
272
  const state = yield* Capabilities.getAtomValue(DeckCapabilities.State);
274
273
  // TODO(wittjosiah): This is a hack to prevent the previous deck from being set for pinned items.
275
274
  // Ideally this should be worked into the data model in a generic way.
276
- const shouldUpdatePrevious = !state.activeDeck.startsWith('!');
275
+ const shouldUpdatePrevious = !isPinnedWorkspace(state.activeDeck);
277
276
 
278
277
  yield* Capabilities.updateAtomValue(DeckCapabilities.State, (state) => {
279
278
  const newDecks = state.decks[input.subject]
@@ -341,14 +340,13 @@ export default Capability.makeModule(
341
340
  const deck = yield* DeckCapabilities.getDeck();
342
341
  previouslyOpenIds = new Set<string>(deck.solo ? [deck.solo] : deck.active);
343
342
  const next = deck.solo
344
- ? input.subject.map((id) => createEntryId(id, input.variant))
343
+ ? [...input.subject]
345
344
  : input.subject.reduce(
346
345
  (acc, entryId) =>
347
346
  openEntry(acc, entryId, {
348
347
  key: input.key,
349
348
  positioning: input.positioning ?? settings?.newPlankPositioning,
350
349
  pivotId: input.pivotId,
351
- variant: input.variant,
352
350
  }),
353
351
  deck.active,
354
352
  );
@@ -490,7 +488,7 @@ export default Capability.makeModule(
490
488
  updateActiveDeck(state, { companionOpen: false }),
491
489
  );
492
490
  } else {
493
- const [, variant] = input.companion.split(ATTENDABLE_PATH_SEPARATOR);
491
+ const variant = getCompanionVariant(input.companion);
494
492
  yield* Capabilities.updateAtomValue(DeckCapabilities.State, (state) =>
495
493
  updateActiveDeck(state, {
496
494
  companionOpen: true,
@@ -17,7 +17,7 @@ export default Capability.makeModule(() =>
17
17
  Effect.succeed(
18
18
  Capability.contributes(Capabilities.ReactSurface, [
19
19
  Surface.create({
20
- id: `${meta.id}/plugin-settings`,
20
+ id: `${meta.id}.plugin-settings`,
21
21
  role: 'article',
22
22
  filter: (data): data is { subject: AppCapabilities.Settings } =>
23
23
  AppCapabilities.isSettings(data.subject) && data.subject.prefix === meta.id,
@@ -27,7 +27,7 @@ export default Capability.makeModule(() =>
27
27
  },
28
28
  }),
29
29
  Surface.create({
30
- id: `${meta.id}/banner`,
30
+ id: `${meta.id}.banner`,
31
31
  role: 'banner',
32
32
  component: ({ data }: { data: { variant?: 'topbar' | 'sidebar' } }) => {
33
33
  return <Banner variant={data.variant} />;
@@ -54,7 +54,7 @@ export default Capability.makeModule(
54
54
 
55
55
  // Persisted state using KVS store.
56
56
  const stateAtom = createKvsStore({
57
- key: `${meta.id}/state`,
57
+ key: `${meta.id}.state`,
58
58
  schema: DeckStateSchema,
59
59
  defaultValue: () => ({ ...defaultDeckState }),
60
60
  });
@@ -5,12 +5,12 @@
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
7
  import { Capabilities, Capability } from '@dxos/app-framework';
8
- import { LayoutOperation } from '@dxos/app-toolkit';
8
+ import { LayoutOperation, fromUrlPath, getWorkspaceFromPath, toUrlPath } from '@dxos/app-toolkit';
9
9
  import { invariant } from '@dxos/invariant';
10
+ import { Node } from '@dxos/plugin-graph';
10
11
 
11
12
  import { DeckCapabilities, type DeckStateProps, defaultDeck } from '../../types';
12
13
 
13
- // TODO(wittjosiah): Cleanup the url handling. May justify introducing routing capabilities.
14
14
  export default Capability.makeModule(
15
15
  Effect.fnUntraced(function* () {
16
16
  const { invokeSync } = yield* Capability.get(Capabilities.OperationInvoker);
@@ -48,15 +48,17 @@ export default Capability.makeModule(
48
48
  return;
49
49
  }
50
50
 
51
- const [_, nextDeck, nextSolo] = pathname.split('/');
52
- if (nextDeck && nextDeck !== state.activeDeck) {
53
- invokeSync(LayoutOperation.SwitchWorkspace, { subject: nextDeck });
51
+ const qualifiedId = fromUrlPath(pathname);
52
+ const workspace = getWorkspaceFromPath(qualifiedId);
53
+ if (workspace !== Node.RootId && workspace !== state.activeDeck) {
54
+ invokeSync(LayoutOperation.SwitchWorkspace, { subject: workspace });
54
55
  }
55
56
 
56
57
  const deck = getDeck();
57
- if (nextSolo && nextSolo !== deck.solo) {
58
- invokeSync(LayoutOperation.SetLayoutMode, { subject: nextSolo, mode: 'solo' });
59
- } else if (!nextSolo && deck.solo) {
58
+ const activeId = qualifiedId !== workspace ? qualifiedId : undefined;
59
+ if (activeId && activeId !== deck.solo) {
60
+ invokeSync(LayoutOperation.SetLayoutMode, { subject: activeId, mode: 'solo' });
61
+ } else if (!activeId && deck.solo) {
60
62
  invokeSync(LayoutOperation.SetLayoutMode, { mode: 'deck' });
61
63
  }
62
64
  };
@@ -78,7 +80,7 @@ export default Capability.makeModule(
78
80
  lastSolo = solo;
79
81
  lastActiveDeck = activeDeck;
80
82
 
81
- const path = solo ? `/${activeDeck}/${solo}` : `/${activeDeck}`;
83
+ const path = solo ? toUrlPath(solo) : toUrlPath(activeDeck);
82
84
  if (window.location.pathname !== path) {
83
85
  // TODO(thure): In some browsers, this only preserves the most recent state change, even though this is not `history.replace`…
84
86
  history.pushState(null, '', `${path}${window.location.search}`);
@@ -14,17 +14,22 @@ import React, {
14
14
  } from 'react';
15
15
 
16
16
  import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
17
- import { LayoutOperation } from '@dxos/app-toolkit';
17
+ import { LayoutOperation, getCompanionVariant } from '@dxos/app-toolkit';
18
18
  import { useAppGraph } from '@dxos/app-toolkit/ui';
19
19
  import { debounce } from '@dxos/async';
20
20
  import { type Node, useNode } from '@dxos/plugin-graph';
21
- import { ATTENDABLE_PATH_SEPARATOR, useAttentionAttributes } from '@dxos/react-ui-attention';
21
+ import { useAttentionAttributes } from '@dxos/react-ui-attention';
22
22
  import { StackItem, railGridHorizontal } from '@dxos/react-ui-stack';
23
23
  import { mainIntrinsicSize, mx } from '@dxos/ui-theme';
24
24
 
25
25
  import { useCompanions, useDeckState, useMainSize, useSelectedCompanion } from '../../hooks';
26
- import { parseEntryId } from '../../layout';
27
- import { DeckOperation, type DeckSettingsProps, type LayoutMode, type ResolvedPart } from '../../types';
26
+ import {
27
+ DeckOperation,
28
+ type DeckSettingsProps,
29
+ type LayoutMode,
30
+ PLANK_COMPANION_TYPE,
31
+ type ResolvedPart,
32
+ } from '../../types';
28
33
 
29
34
  import { PlankError, PlankErrorFallback } from './PlankError';
30
35
  import { PlankHeading } from './PlankHeading';
@@ -174,8 +179,8 @@ const PlankComponent = memo(
174
179
 
175
180
  const rootElement = useRef<HTMLDivElement | null>(null);
176
181
 
177
- const { variant } = parseEntryId(id);
178
- const sizeKey = `${id.split('+')[0]}${variant ? `${ATTENDABLE_PATH_SEPARATOR}${variant}` : ''}`;
182
+ const variant = node?.type === PLANK_COMPANION_TYPE ? getCompanionVariant(id) : undefined;
183
+ const sizeKey = id.split('+')[0];
179
184
  const size = deck.plankSizing[sizeKey] as number | undefined;
180
185
 
181
186
  const handleSizeChange = useCallback(
@@ -5,7 +5,7 @@
5
5
  import React, { Fragment, type MouseEvent, memo, useCallback, useEffect, useMemo } from 'react';
6
6
 
7
7
  import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
8
- import { LayoutOperation } from '@dxos/app-toolkit';
8
+ import { LayoutOperation, getCompanionVariant } from '@dxos/app-toolkit';
9
9
  import { useAppGraph } from '@dxos/app-toolkit/ui';
10
10
  import { Graph, type Node, useActionRunner } from '@dxos/plugin-graph';
11
11
  import { Icon, IconButton, Popover, toLocalizedString, useTranslation } from '@dxos/react-ui';
@@ -14,7 +14,6 @@ import { TextTooltip } from '@dxos/react-ui-text-tooltip';
14
14
  import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/ui-theme';
15
15
 
16
16
  import { useBreakpoints } from '../../hooks';
17
- import { parseEntryId } from '../../layout';
18
17
  import { meta } from '../../meta';
19
18
  import { DeckOperation, type LayoutMode, PLANK_COMPANION_TYPE, type ResolvedPart } from '../../types';
20
19
  import { soloInlinePadding } from '../fragments';
@@ -91,7 +90,7 @@ export const PlankHeading = memo(
91
90
  [breakpoint, part, companions, canIncrementStart, canIncrementEnd, isCompanionNode, deckEnabled],
92
91
  );
93
92
 
94
- const { variant } = parseEntryId(id);
93
+ const variant = isCompanionNode ? getCompanionVariant(id) : undefined;
95
94
  const sigilActions = useMemo(() => {
96
95
  if (!node) {
97
96
  return undefined;
@@ -100,8 +99,8 @@ export const PlankHeading = memo(
100
99
  } else {
101
100
  return [
102
101
  actions,
103
- Graph.getActions(graph, node.id).filter((a) =>
104
- ['list-item', 'list-item-primary', 'heading-list-item'].includes(a.properties.disposition),
102
+ Graph.getActions(graph, node.id).filter((action) =>
103
+ ['list-item', 'list-item-primary', 'heading-list-item'].includes(action.properties.disposition),
105
104
  ),
106
105
  ].filter((a) => a.length > 0);
107
106
  }
@@ -133,7 +132,7 @@ export const PlankHeading = memo(
133
132
  [invokePromise, invokeSync, id, part],
134
133
  );
135
134
 
136
- const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${meta.id}/${node.id}` ? Popover.Anchor : Fragment;
135
+ const ActionRoot = node && popoverAnchorId === `${meta.id}:${node.id}` ? Popover.Anchor : Fragment;
137
136
 
138
137
  const handleTabClick = useCallback(
139
138
  (event: MouseEvent) => {
@@ -13,19 +13,12 @@ import React, {
13
13
  } from 'react';
14
14
 
15
15
  import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
16
- import { LayoutOperation } from '@dxos/app-toolkit';
16
+ import { LayoutOperation, getCompanionVariant } from '@dxos/app-toolkit';
17
17
  import { IconButton, type Label, Main, ScrollArea, toLocalizedString, useTranslation } from '@dxos/react-ui';
18
18
  import { Tabs } from '@dxos/react-ui-tabs';
19
19
  import { mx } from '@dxos/ui-theme';
20
20
 
21
- import {
22
- type DeckCompanion,
23
- getCompanionId,
24
- useBreakpoints,
25
- useDeckCompanions,
26
- useDeckState,
27
- useHoistStatusbar,
28
- } from '../../hooks';
21
+ import { type DeckCompanion, useBreakpoints, useDeckCompanions, useDeckState, useHoistStatusbar } from '../../hooks';
29
22
  import { meta } from '../../meta';
30
23
  import { getMode } from '../../types';
31
24
  import { layoutAppliesTopbar } from '../../util';
@@ -49,8 +42,8 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
49
42
  const hoistStatusbar = useHoistStatusbar(breakpoint, layoutMode);
50
43
 
51
44
  const companions = useDeckCompanions();
52
- const activeCompanion = companions.find((companion) => getCompanionId(companion.id) === current);
53
- const activeId = activeCompanion && getCompanionId(activeCompanion.id);
45
+ const activeCompanion = companions.find((companion) => getCompanionVariant(companion.id) === current);
46
+ const activeId = activeCompanion && getCompanionVariant(activeCompanion.id);
54
47
  const [internalValue, setInternalValue] = useState(activeId);
55
48
 
56
49
  useEffect(() => {
@@ -108,15 +101,15 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
108
101
  >
109
102
  <Tabs.Tablist classNames='grid grid-cols-1 auto-rows-(--dx-rail-action) p-1 gap-1 overflow-y-auto!'>
110
103
  {companions.map((companion) => (
111
- <Tabs.Tab key={getCompanionId(companion.id)} value={getCompanionId(companion.id)} asChild>
104
+ <Tabs.Tab key={getCompanionVariant(companion.id)} value={getCompanionVariant(companion.id)} asChild>
112
105
  <IconButton
113
106
  label={toLocalizedString(companion.properties.label, t)}
114
107
  icon={companion.properties.icon}
115
108
  iconOnly
116
109
  tooltipSide='left'
117
- data-value={getCompanionId(companion.id)}
110
+ data-value={getCompanionVariant(companion.id)}
118
111
  variant={
119
- activeId === getCompanionId(companion.id)
112
+ activeId === getCompanionVariant(companion.id)
120
113
  ? state.complementarySidebarState === 'expanded'
121
114
  ? 'primary'
122
115
  : 'default'
@@ -139,8 +132,8 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
139
132
  {activeId &&
140
133
  companions.map((companion) => (
141
134
  <Tabs.Tabpanel
142
- key={getCompanionId(companion.id)}
143
- value={getCompanionId(companion.id)}
135
+ key={getCompanionVariant(companion.id)}
136
+ value={getCompanionVariant(companion.id)}
144
137
  classNames={[
145
138
  'absolute data-[state="inactive"]:-z-[1] overflow-hidden',
146
139
  'inset-y-0 start-0 w-[calc(100%-var(--dx-r0-size))] lg:w-(--dx-r1-size)',
@@ -174,7 +167,7 @@ type ComplementarySidebarPanelProps = {
174
167
  const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }: ComplementarySidebarPanelProps) => {
175
168
  const { t } = useTranslation(meta.id);
176
169
 
177
- if (getCompanionId(companion.id) !== activeId && !data) {
170
+ if (getCompanionVariant(companion.id) !== activeId && !data) {
178
171
  return null;
179
172
  }
180
173
 
@@ -188,7 +181,7 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
188
181
  icon={companion.properties.icon}
189
182
  iconOnly
190
183
  tooltipSide='left'
191
- data-value={getCompanionId(companion.id)}
184
+ data-value={getCompanionVariant(companion.id)}
192
185
  classNames='h-10 w-10'
193
186
  variant='default'
194
187
  />
@@ -198,7 +191,7 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
198
191
  </div>
199
192
  <Wrapper>
200
193
  <Surface.Surface
201
- role={`deck-companion--${getCompanionId(companion.id)}`}
194
+ role={`deck-companion--${getCompanionVariant(companion.id)}`}
202
195
  data={data}
203
196
  fallback={PlankErrorFallback}
204
197
  placeholder={<PlankLoading />}
@@ -5,10 +5,10 @@
5
5
  import React, { useCallback } from 'react';
6
6
 
7
7
  import { useOperationInvoker } from '@dxos/app-framework/ui';
8
- import { LayoutOperation } from '@dxos/app-toolkit';
8
+ import { LayoutOperation, getCompanionVariant } from '@dxos/app-toolkit';
9
9
  import { IconButton, type IconButtonProps, type ThemedClassName, useTranslation } from '@dxos/react-ui';
10
10
 
11
- import { getCompanionId, useDeckCompanions, useDeckState } from '../../hooks';
11
+ import { useDeckCompanions, useDeckState } from '../../hooks';
12
12
  import { meta } from '../../meta';
13
13
 
14
14
  export const ToggleSidebarButton = ({
@@ -73,7 +73,7 @@ export const ToggleComplementarySidebarButton = ({
73
73
  const nextState = state.complementarySidebarState === 'expanded' ? 'collapsed' : 'expanded';
74
74
  updateState((state) => ({ ...state, complementarySidebarState: nextState }));
75
75
 
76
- const subject = state.complementarySidebarPanel ?? (companions[0] && getCompanionId(companions[0].id));
76
+ const subject = state.complementarySidebarPanel ?? (companions[0] && getCompanionVariant(companions[0].id));
77
77
  if (nextState === 'expanded' && !current && subject) {
78
78
  invokeSync(LayoutOperation.UpdateComplementary, { subject });
79
79
  }
@@ -8,12 +8,7 @@ import { useConnections } from '@dxos/plugin-graph';
8
8
  import { type Label } from '@dxos/ui-types';
9
9
  import { type Position, byPosition } from '@dxos/util';
10
10
 
11
- import { ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE } from '../types';
12
-
13
- export const getCompanionId = (id: string) => {
14
- const [_, companionId] = id.split(ATTENDABLE_PATH_SEPARATOR);
15
- return companionId ?? 'never';
16
- };
11
+ import { DECK_COMPANION_TYPE } from '../types';
17
12
 
18
13
  export type DeckCompanion = NodeType.Node<
19
14
  any,
@@ -4,10 +4,9 @@
4
4
 
5
5
  import { useMemo } from 'react';
6
6
 
7
+ import { getCompanionVariant } from '@dxos/app-toolkit';
7
8
  import { type Node } from '@dxos/plugin-graph';
8
9
 
9
- import { parseEntryId } from '../layout';
10
-
11
10
  /**
12
11
  * Resolves which companion to show based on variant preference.
13
12
  * Falls back to first available if preferred variant not found.
@@ -20,19 +19,14 @@ export const useSelectedCompanion = (companions: Node.Node[], preferredVariant?:
20
19
 
21
20
  // Try to find companion matching the preferred variant.
22
21
  if (preferredVariant) {
23
- const preferred = companions.find((companion) => {
24
- const { variant } = parseEntryId(companion.id);
25
- return variant === preferredVariant;
26
- });
22
+ const preferred = companions.find((companion) => getCompanionVariant(companion.id) === preferredVariant);
27
23
  if (preferred) {
28
- const { variant } = parseEntryId(preferred.id);
29
- return { companionId: preferred.id, variant };
24
+ return { companionId: preferred.id, variant: getCompanionVariant(preferred.id) };
30
25
  }
31
26
  }
32
27
 
33
28
  // Fallback to first companion.
34
29
  const first = companions[0];
35
- const { variant } = parseEntryId(first.id);
36
- return { companionId: first.id, variant };
30
+ return { companionId: first.id, variant: getCompanionVariant(first.id) };
37
31
  }, [companions, preferredVariant]);
38
32
  };
package/src/layout.ts CHANGED
@@ -4,29 +4,16 @@
4
4
 
5
5
  import { produce } from 'immer';
6
6
 
7
- import { ATTENDABLE_PATH_SEPARATOR } from '@dxos/react-ui-attention';
8
-
9
7
  import { type DeckAction, type NewPlankPositioning } from './types';
10
8
 
11
- export const createEntryId = (entryId: string, variant?: string) =>
12
- variant ? `${entryId}${ATTENDABLE_PATH_SEPARATOR}${variant}` : entryId;
13
-
14
- export const parseEntryId = (entryId: string) => {
15
- const [id, variant] = entryId.split(ATTENDABLE_PATH_SEPARATOR);
16
- return { id, variant };
17
- };
18
-
19
9
  type OpenLayoutEntryOptions = {
20
10
  key?: string;
21
11
  positioning?: NewPlankPositioning;
22
12
  pivotId?: string;
23
- variant?: string;
24
13
  };
25
14
 
26
- export const openEntry = (deck: string[], _entryId: string, options?: OpenLayoutEntryOptions): string[] => {
15
+ export const openEntry = (deck: string[], entryId: string, options?: OpenLayoutEntryOptions): string[] => {
27
16
  return produce(deck, (draft) => {
28
- const entryId = createEntryId(_entryId, options?.variant);
29
-
30
17
  // Check that the entry is not already in the part
31
18
  if (draft.find((id) => id === entryId)) {
32
19
  return;
package/src/meta.ts CHANGED
@@ -6,7 +6,7 @@ import { type Plugin } from '@dxos/app-framework';
6
6
  import { trim } from '@dxos/util';
7
7
 
8
8
  export const meta: Plugin.Meta = {
9
- id: 'dxos.org/plugin/deck',
9
+ id: 'org.dxos.plugin.deck',
10
10
  name: 'Layout',
11
11
  description: trim`
12
12
  Flexible layout system for arranging workspace views in tabs, splits, and panels.
@@ -12,14 +12,14 @@ import { meta } from '../meta';
12
12
  import { type DeckEphemeralStateProps, type DeckSettingsProps, type DeckState, type DeckStateProps } from '../types';
13
13
 
14
14
  export namespace DeckCapabilities {
15
- export const Settings = Capability.make<Atom.Writable<DeckSettingsProps>>(`${meta.id}/capability/settings`);
15
+ export const Settings = Capability.make<Atom.Writable<DeckSettingsProps>>(`${meta.id}.capability.settings`);
16
16
 
17
17
  /** Persisted state (stored in KVS/localStorage). */
18
- export const State = Capability.make<Atom.Writable<DeckStateProps>>(`${meta.id}/capability/state`);
18
+ export const State = Capability.make<Atom.Writable<DeckStateProps>>(`${meta.id}.capability.state`);
19
19
 
20
20
  /** Transient/ephemeral state (not persisted). */
21
21
  export const EphemeralState = Capability.make<Atom.Writable<DeckEphemeralStateProps>>(
22
- `${meta.id}/capability/ephemeral-state`,
22
+ `${meta.id}.capability.ephemeral-state`,
23
23
  );
24
24
 
25
25
  /** Get the current active deck from state. */
@@ -11,7 +11,7 @@ import { DeckCapabilities } from './capabilities';
11
11
 
12
12
  export namespace DeckEvents {
13
13
  export const StateReady: ActivationEvent.ActivationEvent = AppActivationEvents.createStateEvent(
14
- `${meta.id}/state-ready`,
14
+ `${meta.id}.state-ready`,
15
15
  );
16
16
 
17
17
  /** Fired when DeckSettings capability is ready. */
@@ -11,10 +11,8 @@ import { type DeepReadonly } from '@dxos/util';
11
11
 
12
12
  import { meta } from '../meta';
13
13
 
14
- export { ATTENDABLE_PATH_SEPARATOR } from '@dxos/react-ui-attention';
15
-
16
- export const PLANK_COMPANION_TYPE = `${meta.id}/plank-companion`;
17
- export const DECK_COMPANION_TYPE = `${meta.id}/deck-companion`;
14
+ export const PLANK_COMPANION_TYPE = `${meta.id}.plank-companion`;
15
+ export const DECK_COMPANION_TYPE = `${meta.id}.deck-companion`;
18
16
 
19
17
  // TODO(Zan): In the future we should consider adding new planks adjacent to the attended plank.
20
18
  export const NewPlankPositions = ['start', 'end'] as const;
@@ -139,12 +137,12 @@ export namespace DeckAction {
139
137
  export type Adjustment = Schema.Schema.Type<typeof Adjustment>;
140
138
 
141
139
  // An atomic transaction to apply to the deck, describing which element to move to which location.
142
- export class Adjust extends Schema.TaggedClass<Adjust>()(`${meta.id}/action/adjust`, {
140
+ export class Adjust extends Schema.TaggedClass<Adjust>()(`${meta.id}.action.adjust`, {
143
141
  input: Adjustment,
144
142
  output: Schema.Void,
145
143
  }) {}
146
144
 
147
- export class UpdatePlankSize extends Schema.TaggedClass<UpdatePlankSize>()(`${meta.id}/action/update-plank-size`, {
145
+ export class UpdatePlankSize extends Schema.TaggedClass<UpdatePlankSize>()(`${meta.id}.action.update-plank-size`, {
148
146
  input: Schema.Struct({
149
147
  id: Schema.String,
150
148
  size: Schema.Number,
@@ -152,7 +150,7 @@ export namespace DeckAction {
152
150
  output: Schema.Void,
153
151
  }) {}
154
152
 
155
- export class ChangeCompanion extends Schema.TaggedClass<ChangeCompanion>()(`${meta.id}/action/change-companion`, {
153
+ export class ChangeCompanion extends Schema.TaggedClass<ChangeCompanion>()(`${meta.id}.action.change-companion`, {
156
154
  input: Schema.Struct({
157
155
  companion: Schema.Union(Schema.String, Schema.Null),
158
156
  }),
@@ -176,7 +174,7 @@ export namespace DeckOperation {
176
174
 
177
175
  export const Adjust = Operation.make({
178
176
  meta: {
179
- key: `${meta.id}/operation/adjust`,
177
+ key: `${meta.id}.operation.adjust`,
180
178
  name: 'Adjust',
181
179
  description: 'Adjust the layout of a plank.',
182
180
  },
@@ -192,7 +190,7 @@ export namespace DeckOperation {
192
190
 
193
191
  export const UpdatePlankSize = Operation.make({
194
192
  meta: {
195
- key: `${meta.id}/operation/update-plank-size`,
193
+ key: `${meta.id}.operation.update-plank-size`,
196
194
  name: 'Update Plank Size',
197
195
  description: 'Update the size of a plank.',
198
196
  },
@@ -208,7 +206,7 @@ export namespace DeckOperation {
208
206
 
209
207
  export const ChangeCompanion = Operation.make({
210
208
  meta: {
211
- key: `${meta.id}/operation/change-companion`,
209
+ key: `${meta.id}.operation.change-companion`,
212
210
  name: 'Change Companion',
213
211
  description: 'Change the companion plank for a primary plank.',
214
212
  },