@dxos/plugin-board 0.8.4-main.74a063c4e0 → 0.8.4-main.765dc60934

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 (86) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/BoardArticle-6DBQWLP5.mjs +164 -0
  4. package/dist/lib/neutral/BoardArticle-6DBQWLP5.mjs.map +7 -0
  5. package/dist/lib/neutral/BoardPlugin.mjs +30 -0
  6. package/dist/lib/neutral/BoardPlugin.mjs.map +7 -0
  7. package/dist/lib/neutral/capabilities/index.mjs +11 -0
  8. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  9. package/dist/lib/neutral/chunk-EFV3E7KE.mjs +19 -0
  10. package/dist/lib/neutral/chunk-EFV3E7KE.mjs.map +7 -0
  11. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  12. package/dist/lib/{browser/chunk-FL67SBF5.mjs → neutral/chunk-XXGRE3CK.mjs} +4 -6
  13. package/dist/lib/{browser/chunk-FL67SBF5.mjs.map → neutral/chunk-XXGRE3CK.mjs.map} +2 -2
  14. package/dist/lib/neutral/components/index.mjs +1 -0
  15. package/dist/lib/neutral/containers/index.mjs +9 -0
  16. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  17. package/dist/lib/neutral/create-object-OWHPPT3P.mjs +27 -0
  18. package/dist/lib/neutral/create-object-OWHPPT3P.mjs.map +7 -0
  19. package/dist/lib/neutral/index.mjs +12 -0
  20. package/dist/lib/neutral/index.mjs.map +7 -0
  21. package/dist/lib/neutral/meta.json +1 -0
  22. package/dist/lib/neutral/meta.mjs +8 -0
  23. package/dist/lib/neutral/meta.mjs.map +7 -0
  24. package/dist/lib/neutral/plugin.mjs +12 -0
  25. package/dist/lib/neutral/plugin.mjs.map +7 -0
  26. package/dist/lib/neutral/react-surface-M5JHK3ZQ.mjs +26 -0
  27. package/dist/lib/neutral/react-surface-M5JHK3ZQ.mjs.map +7 -0
  28. package/dist/lib/neutral/translations.mjs +29 -0
  29. package/dist/lib/neutral/translations.mjs.map +7 -0
  30. package/dist/lib/{browser → neutral}/types/index.mjs +2 -1
  31. package/dist/lib/neutral/types/index.mjs.map +7 -0
  32. package/dist/types/src/BoardPlugin.d.ts +1 -0
  33. package/dist/types/src/BoardPlugin.d.ts.map +1 -1
  34. package/dist/types/src/BoardPlugin.test.d.ts +2 -0
  35. package/dist/types/src/BoardPlugin.test.d.ts.map +1 -0
  36. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  37. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  38. package/dist/types/src/capabilities/index.d.ts +6 -0
  39. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  40. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  41. package/dist/types/src/containers/BoardArticle/BoardArticle.d.ts +6 -0
  42. package/dist/types/src/containers/BoardArticle/BoardArticle.d.ts.map +1 -0
  43. package/dist/types/src/containers/BoardArticle/BoardArticle.stories.d.ts +54 -0
  44. package/dist/types/src/containers/BoardArticle/BoardArticle.stories.d.ts.map +1 -0
  45. package/dist/types/src/containers/BoardArticle/index.d.ts +2 -0
  46. package/dist/types/src/containers/BoardArticle/index.d.ts.map +1 -0
  47. package/dist/types/src/containers/index.d.ts +1 -1
  48. package/dist/types/src/containers/index.d.ts.map +1 -1
  49. package/dist/types/src/index.d.ts +0 -1
  50. package/dist/types/src/index.d.ts.map +1 -1
  51. package/dist/types/src/plugin.d.ts +3 -0
  52. package/dist/types/src/plugin.d.ts.map +1 -0
  53. package/dist/types/src/translations.d.ts +22 -15
  54. package/dist/types/src/translations.d.ts.map +1 -1
  55. package/dist/types/src/types/Board.d.ts.map +1 -1
  56. package/dist/types/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +89 -60
  58. package/src/BoardPlugin.test.ts +27 -0
  59. package/src/BoardPlugin.tsx +6 -30
  60. package/src/capabilities/create-object.ts +30 -0
  61. package/src/capabilities/index.ts +1 -0
  62. package/src/capabilities/react-surface.tsx +6 -4
  63. package/src/containers/{BoardContainer/BoardContainer.stories.tsx → BoardArticle/BoardArticle.stories.tsx} +12 -12
  64. package/src/containers/{BoardContainer/BoardContainer.tsx → BoardArticle/BoardArticle.tsx} +49 -21
  65. package/src/containers/BoardArticle/index.ts +5 -0
  66. package/src/containers/index.ts +1 -1
  67. package/src/index.ts +0 -2
  68. package/src/plugin.ts +9 -0
  69. package/dist/lib/browser/index.mjs +0 -92
  70. package/dist/lib/browser/index.mjs.map +0 -7
  71. package/dist/lib/browser/meta.json +0 -1
  72. package/dist/lib/node-esm/chunk-5GGKJL4Z.mjs +0 -40
  73. package/dist/lib/node-esm/chunk-5GGKJL4Z.mjs.map +0 -7
  74. package/dist/lib/node-esm/index.mjs +0 -93
  75. package/dist/lib/node-esm/index.mjs.map +0 -7
  76. package/dist/lib/node-esm/meta.json +0 -1
  77. package/dist/lib/node-esm/types/index.mjs +0 -8
  78. package/dist/types/src/containers/BoardContainer/BoardContainer.d.ts +0 -6
  79. package/dist/types/src/containers/BoardContainer/BoardContainer.d.ts.map +0 -1
  80. package/dist/types/src/containers/BoardContainer/BoardContainer.stories.d.ts +0 -47
  81. package/dist/types/src/containers/BoardContainer/BoardContainer.stories.d.ts.map +0 -1
  82. package/dist/types/src/containers/BoardContainer/index.d.ts +0 -2
  83. package/dist/types/src/containers/BoardContainer/index.d.ts.map +0 -1
  84. package/src/containers/BoardContainer/index.ts +0 -5
  85. /package/dist/lib/{browser/types/index.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  86. /package/dist/lib/{node-esm/types → neutral/components}/index.mjs.map +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-board",
3
- "version": "0.8.4-main.74a063c4e0",
3
+ "version": "0.8.4-main.765dc60934",
4
4
  "description": "Surface plugin for card baords",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -8,94 +8,123 @@
8
8
  "type": "git",
9
9
  "url": "https://github.com/dxos/dxos"
10
10
  },
11
- "license": "MIT",
11
+ "license": "FSL-1.1-Apache-2.0",
12
12
  "author": "DXOS.org",
13
13
  "sideEffects": true,
14
14
  "type": "module",
15
15
  "imports": {
16
- "#capabilities": "./src/capabilities/index.ts",
17
- "#components": "./src/components/index.ts",
18
- "#containers": "./src/containers/index.ts",
19
- "#meta": "./src/meta.ts",
20
- "#types": "./src/types/index.ts"
16
+ "#capabilities": {
17
+ "source": "./src/capabilities/index.ts",
18
+ "types": "./dist/types/src/capabilities/index.d.ts",
19
+ "default": "./dist/lib/neutral/capabilities/index.mjs"
20
+ },
21
+ "#components": {
22
+ "source": "./src/components/index.ts",
23
+ "types": "./dist/types/src/components/index.d.ts",
24
+ "default": "./dist/lib/neutral/components/index.mjs"
25
+ },
26
+ "#containers": {
27
+ "source": "./src/containers/index.ts",
28
+ "types": "./dist/types/src/containers/index.d.ts",
29
+ "default": "./dist/lib/neutral/containers/index.mjs"
30
+ },
31
+ "#meta": {
32
+ "source": "./src/meta.ts",
33
+ "types": "./dist/types/src/meta.d.ts",
34
+ "default": "./dist/lib/neutral/meta.mjs"
35
+ },
36
+ "#plugin": {
37
+ "source": "./src/BoardPlugin.tsx",
38
+ "types": "./dist/types/src/BoardPlugin.d.ts",
39
+ "default": "./dist/lib/neutral/BoardPlugin.mjs"
40
+ },
41
+ "#translations": {
42
+ "source": "./src/translations.ts",
43
+ "types": "./dist/types/src/translations.d.ts",
44
+ "default": "./dist/lib/neutral/translations.mjs"
45
+ },
46
+ "#types": {
47
+ "source": "./src/types/index.ts",
48
+ "types": "./dist/types/src/types/index.d.ts",
49
+ "default": "./dist/lib/neutral/types/index.mjs"
50
+ }
21
51
  },
22
52
  "exports": {
23
53
  ".": {
24
54
  "source": "./src/index.ts",
25
- "browser": "./dist/lib/browser/index.mjs",
26
- "node": "./dist/lib/node-esm/index.mjs",
27
- "types": "./dist/types/src/index.d.ts"
55
+ "types": "./dist/types/src/index.d.ts",
56
+ "default": "./dist/lib/neutral/index.mjs"
28
57
  },
29
- "./types": {
30
- "source": "./src/types/index.ts",
31
- "browser": "./dist/lib/browser/types/index.mjs",
32
- "node": "./dist/lib/node-esm/types/index.mjs",
33
- "types": "./dist/types/src/types/index.d.ts"
58
+ "./plugin": {
59
+ "source": "./src/plugin.ts",
60
+ "types": "./dist/types/src/plugin.d.ts",
61
+ "default": "./dist/lib/neutral/plugin.mjs"
62
+ },
63
+ "./translations": {
64
+ "source": "./src/translations.ts",
65
+ "types": "./dist/types/src/translations.d.ts",
66
+ "default": "./dist/lib/neutral/translations.mjs"
34
67
  }
35
68
  },
36
69
  "types": "dist/types/src/index.d.ts",
37
- "typesVersions": {
38
- "*": {
39
- "types": [
40
- "dist/types/src/types/index.d.ts"
41
- ]
42
- }
43
- },
44
70
  "files": [
45
71
  "dist",
46
72
  "src"
47
73
  ],
48
74
  "dependencies": {
75
+ "@effect-atom/atom": "^0.5.1",
76
+ "@effect-atom/atom-react": "^0.5.0",
49
77
  "effect": "3.20.0",
50
- "@dxos/ai": "0.8.4-main.74a063c4e0",
51
- "@dxos/async": "0.8.4-main.74a063c4e0",
52
- "@dxos/app-framework": "0.8.4-main.74a063c4e0",
53
- "@dxos/app-toolkit": "0.8.4-main.74a063c4e0",
54
- "@dxos/blueprints": "0.8.4-main.74a063c4e0",
55
- "@dxos/client": "0.8.4-main.74a063c4e0",
56
- "@dxos/assistant": "0.8.4-main.74a063c4e0",
57
- "@dxos/echo": "0.8.4-main.74a063c4e0",
58
- "@dxos/effect": "0.8.4-main.74a063c4e0",
59
- "@dxos/echo-react": "0.8.4-main.74a063c4e0",
60
- "@dxos/invariant": "0.8.4-main.74a063c4e0",
61
- "@dxos/log": "0.8.4-main.74a063c4e0",
62
- "@dxos/operation": "0.8.4-main.74a063c4e0",
63
- "@dxos/plugin-graph": "0.8.4-main.74a063c4e0",
64
- "@dxos/plugin-client": "0.8.4-main.74a063c4e0",
65
- "@dxos/plugin-search": "0.8.4-main.74a063c4e0",
66
- "@dxos/plugin-space": "0.8.4-main.74a063c4e0",
67
- "@dxos/random": "0.8.4-main.74a063c4e0",
68
- "@dxos/react-ui": "0.8.4-main.74a063c4e0",
69
- "@dxos/react-client": "0.8.4-main.74a063c4e0",
70
- "@dxos/react-ui-attention": "0.8.4-main.74a063c4e0",
71
- "@dxos/react-ui-board": "0.8.4-main.74a063c4e0",
72
- "@dxos/react-ui-mosaic": "0.8.4-main.74a063c4e0",
73
- "@dxos/react-ui-form": "0.8.4-main.74a063c4e0",
74
- "@dxos/react-ui-stack": "0.8.4-main.74a063c4e0",
75
- "@dxos/schema": "0.8.4-main.74a063c4e0",
76
- "@dxos/types": "0.8.4-main.74a063c4e0",
77
- "@dxos/util": "0.8.4-main.74a063c4e0"
78
+ "@dxos/ai": "0.8.4-main.765dc60934",
79
+ "@dxos/app-framework": "0.8.4-main.765dc60934",
80
+ "@dxos/app-toolkit": "0.8.4-main.765dc60934",
81
+ "@dxos/assistant": "0.8.4-main.765dc60934",
82
+ "@dxos/async": "0.8.4-main.765dc60934",
83
+ "@dxos/compute": "0.8.4-main.765dc60934",
84
+ "@dxos/echo": "0.8.4-main.765dc60934",
85
+ "@dxos/echo-atom": "0.8.4-main.765dc60934",
86
+ "@dxos/echo-react": "0.8.4-main.765dc60934",
87
+ "@dxos/client": "0.8.4-main.765dc60934",
88
+ "@dxos/effect": "0.8.4-main.765dc60934",
89
+ "@dxos/invariant": "0.8.4-main.765dc60934",
90
+ "@dxos/log": "0.8.4-main.765dc60934",
91
+ "@dxos/plugin-client": "0.8.4-main.765dc60934",
92
+ "@dxos/plugin-graph": "0.8.4-main.765dc60934",
93
+ "@dxos/plugin-markdown": "0.8.4-main.765dc60934",
94
+ "@dxos/plugin-search": "0.8.4-main.765dc60934",
95
+ "@dxos/plugin-space": "0.8.4-main.765dc60934",
96
+ "@dxos/react-client": "0.8.4-main.765dc60934",
97
+ "@dxos/random": "0.8.4-main.765dc60934",
98
+ "@dxos/react-ui": "0.8.4-main.765dc60934",
99
+ "@dxos/react-ui-attention": "0.8.4-main.765dc60934",
100
+ "@dxos/react-ui-board": "0.8.4-main.765dc60934",
101
+ "@dxos/react-ui-form": "0.8.4-main.765dc60934",
102
+ "@dxos/react-ui-stack": "0.8.4-main.765dc60934",
103
+ "@dxos/schema": "0.8.4-main.765dc60934",
104
+ "@dxos/types": "0.8.4-main.765dc60934",
105
+ "@dxos/util": "0.8.4-main.765dc60934",
106
+ "@dxos/react-ui-mosaic": "0.8.4-main.765dc60934"
78
107
  },
79
108
  "devDependencies": {
80
109
  "@types/react": "~19.2.7",
81
110
  "@types/react-dom": "~19.2.3",
82
111
  "react": "~19.2.3",
83
112
  "react-dom": "~19.2.3",
84
- "vite": "^7.1.11",
85
- "@dxos/plugin-preview": "0.8.4-main.74a063c4e0",
86
- "@dxos/plugin-testing": "0.8.4-main.74a063c4e0",
87
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.74a063c4e0",
88
- "@dxos/plugin-theme": "0.8.4-main.74a063c4e0",
89
- "@dxos/storybook-utils": "0.8.4-main.74a063c4e0",
90
- "@dxos/test-utils": "0.8.4-main.74a063c4e0",
91
- "@dxos/ui-theme": "0.8.4-main.74a063c4e0"
113
+ "vite": "^8.0.13",
114
+ "@dxos/plugin-preview": "0.8.4-main.765dc60934",
115
+ "@dxos/plugin-testing": "0.8.4-main.765dc60934",
116
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.765dc60934",
117
+ "@dxos/plugin-theme": "0.8.4-main.765dc60934",
118
+ "@dxos/storybook-utils": "0.8.4-main.765dc60934",
119
+ "@dxos/test-utils": "0.8.4-main.765dc60934",
120
+ "@dxos/ui-theme": "0.8.4-main.765dc60934"
92
121
  },
93
122
  "peerDependencies": {
94
123
  "effect": "3.20.0",
95
124
  "react": "~19.2.3",
96
125
  "react-dom": "~19.2.3",
97
- "@dxos/ui-theme": "0.8.4-main.74a063c4e0",
98
- "@dxos/react-ui": "0.8.4-main.74a063c4e0"
126
+ "@dxos/react-ui": "0.8.4-main.765dc60934",
127
+ "@dxos/ui-theme": "0.8.4-main.765dc60934"
99
128
  },
100
129
  "publishConfig": {
101
130
  "access": "public"
@@ -0,0 +1,27 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, test } from 'vitest';
6
+
7
+ import { ClientPlugin } from '@dxos/plugin-client/plugin';
8
+ import { createComposerTestApp } from '@dxos/plugin-testing/harness';
9
+
10
+ import { BoardPlugin } from '#plugin';
11
+
12
+ import { meta } from './meta';
13
+
14
+ const moduleId = (name: string) => `${meta.id}.module.${name}`;
15
+
16
+ describe('BoardPlugin', () => {
17
+ test('modules activate on the expected events', async ({ expect }) => {
18
+ await using harness = await createComposerTestApp({
19
+ plugins: [ClientPlugin({}), BoardPlugin()],
20
+ });
21
+
22
+ // Modules expected to be active after a normal startup.
23
+ expect(harness.manager.getActive()).toEqual(
24
+ expect.arrayContaining([moduleId('CreateObject'), moduleId('schema'), moduleId('ReactSurface')]),
25
+ );
26
+ });
27
+ });
@@ -2,45 +2,21 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import * as Effect from 'effect/Effect';
6
- import * as Option from 'effect/Option';
7
-
8
5
  import { Plugin } from '@dxos/app-framework';
9
6
  import { AppPlugin } from '@dxos/app-toolkit';
10
- import { Annotation } from '@dxos/echo';
11
- import { Operation } from '@dxos/operation';
12
- import { SpaceOperation } from '@dxos/plugin-space/operations';
13
- import { type CreateObject } from '@dxos/plugin-space/types';
14
- import { translations as boardTranslations } from '@dxos/react-ui-board';
7
+ import { translations as boardTranslations } from '@dxos/react-ui-board/translations';
15
8
 
16
- import { ReactSurface } from '#capabilities';
9
+ import { CreateObject, ReactSurface } from '#capabilities';
17
10
  import { meta } from '#meta';
11
+ import { translations } from '#translations';
18
12
  import { Board } from '#types';
19
13
 
20
- import { translations } from './translations';
21
-
22
14
  export const BoardPlugin = Plugin.define(meta).pipe(
23
- AppPlugin.addMetadataModule({
24
- metadata: {
25
- id: Board.Board.typename,
26
- metadata: {
27
- icon: Annotation.IconAnnotation.get(Board.Board).pipe(Option.getOrThrow).icon,
28
- iconHue: Annotation.IconAnnotation.get(Board.Board).pipe(Option.getOrThrow).hue ?? 'white',
29
- createObject: ((props, options) =>
30
- Effect.gen(function* () {
31
- const object = Board.makeBoard(props);
32
- return yield* Operation.invoke(SpaceOperation.AddObject, {
33
- object,
34
- target: options.target,
35
- hidden: true,
36
- targetNodeId: options.targetNodeId,
37
- });
38
- })) satisfies CreateObject,
39
- },
40
- },
41
- }),
15
+ AppPlugin.addCreateObjectModule({ activate: CreateObject }),
42
16
  AppPlugin.addSchemaModule({ schema: [Board.Board] }),
43
17
  AppPlugin.addSurfaceModule({ activate: ReactSurface }),
44
18
  AppPlugin.addTranslationsModule({ translations: [...translations, ...boardTranslations] }),
45
19
  Plugin.make,
46
20
  );
21
+
22
+ export default BoardPlugin;
@@ -0,0 +1,30 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { Operation } from '@dxos/compute';
9
+ import { SpaceOperation } from '@dxos/plugin-space';
10
+ import { SpaceCapabilities } from '@dxos/plugin-space';
11
+
12
+ import { Board } from '#types';
13
+
14
+ export default Capability.makeModule(
15
+ Effect.fnUntraced(function* () {
16
+ return Capability.contributes(SpaceCapabilities.CreateObjectEntry, {
17
+ id: Board.Board.typename,
18
+ createObject: (props, options) =>
19
+ Effect.gen(function* () {
20
+ const object = Board.makeBoard(props);
21
+ return yield* Operation.invoke(SpaceOperation.AddObject, {
22
+ object,
23
+ target: options.target,
24
+ hidden: true,
25
+ targetNodeId: options.targetNodeId,
26
+ });
27
+ }),
28
+ });
29
+ }),
30
+ );
@@ -4,4 +4,5 @@
4
4
 
5
5
  import { Capability } from '@dxos/app-framework';
6
6
 
7
+ export const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));
7
8
  export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
@@ -9,7 +9,7 @@ import { Capabilities, Capability } from '@dxos/app-framework';
9
9
  import { Surface } from '@dxos/app-framework/ui';
10
10
  import { AppSurface } from '@dxos/app-toolkit/ui';
11
11
 
12
- import { BoardContainer } from '#containers';
12
+ import { BoardArticle } from '#containers';
13
13
  import { Board } from '#types';
14
14
 
15
15
  export default Capability.makeModule(() =>
@@ -18,10 +18,12 @@ export default Capability.makeModule(() =>
18
18
  Surface.create({
19
19
  id: 'root',
20
20
  // TODO(wittjosiah): Split into multiple surfaces if this filter proves too strict for non-article roles.
21
- role: ['article', 'section'],
22
- filter: AppSurface.objectArticle(Board.Board),
21
+ filter: AppSurface.oneOf(
22
+ AppSurface.object(AppSurface.Article, Board.Board),
23
+ AppSurface.object(AppSurface.Section, Board.Board),
24
+ ),
23
25
  component: ({ role, data }) => (
24
- <BoardContainer role={role} subject={data.subject} attendableId={data.attendableId} />
26
+ <BoardArticle role={role} subject={data.subject} attendableId={data.attendableId} />
25
27
  ),
26
28
  }),
27
29
  ]),
@@ -7,21 +7,21 @@ import * as Effect from 'effect/Effect';
7
7
  import React, { useEffect, useState } from 'react';
8
8
 
9
9
  import { withPluginManager } from '@dxos/app-framework/testing';
10
- import { Obj } from '@dxos/echo';
11
- import { ClientPlugin } from '@dxos/plugin-client';
10
+ import { Filter, Obj, Ref } from '@dxos/echo';
11
+ import { ClientPlugin } from '@dxos/plugin-client/testing';
12
12
  import { initializeIdentity } from '@dxos/plugin-client/testing';
13
- import { PreviewPlugin } from '@dxos/plugin-preview';
13
+ import { PreviewPlugin } from '@dxos/plugin-preview/testing';
14
14
  import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
15
15
  import { random } from '@dxos/random';
16
- import { Filter, Ref, useQuery, useSpaces } from '@dxos/react-client/echo';
17
- import { translations as stackTranslations } from '@dxos/react-ui-stack';
16
+ import { useQuery, useSpaces } from '@dxos/react-client/echo';
17
+ import { translations as stackTranslations } from '@dxos/react-ui-stack/translations';
18
18
  import { withLayout } from '@dxos/react-ui/testing';
19
19
  import { Organization, Person } from '@dxos/types';
20
20
 
21
+ import { translations } from '#translations';
21
22
  import { Board } from '#types';
22
23
 
23
- import { translations } from '../../translations';
24
- import { BoardContainer } from './BoardContainer';
24
+ import { BoardArticle } from './BoardArticle';
25
25
 
26
26
  random.seed(0);
27
27
 
@@ -62,7 +62,7 @@ const DefaultStory = () => {
62
62
  return null;
63
63
  }
64
64
 
65
- return <BoardContainer role='board' subject={board} attendableId='test' />;
65
+ return <BoardArticle role='board' subject={board} attendableId='test' />;
66
66
  };
67
67
 
68
68
  //
@@ -70,7 +70,7 @@ const DefaultStory = () => {
70
70
  //
71
71
 
72
72
  const meta = {
73
- title: 'plugins/plugin-board/containers/BoardContainer',
73
+ title: 'plugins/plugin-board/containers/BoardArticle',
74
74
  render: DefaultStory,
75
75
  decorators: [
76
76
  withLayout({ layout: 'fullscreen' }),
@@ -86,13 +86,13 @@ const meta = {
86
86
  yield* Effect.promise(() => space.waitUntilReady());
87
87
  const board = space.db.add(createBoard());
88
88
 
89
- Obj.change(board, (obj) => {
89
+ Obj.update(board, (board) => {
90
90
  // Add some sample items
91
91
  Array.from({ length: 10 }).map(() => {
92
92
  const org = createOrg();
93
93
  space.db.add(org);
94
- obj.items.push(Ref.make(org));
95
- obj.layout.cells[org.id] = {
94
+ board.items.push(Ref.make(org));
95
+ board.layout.cells[org.id] = {
96
96
  x: Math.floor(Math.random() * 5) - 2,
97
97
  y: Math.floor(Math.random() * 5) - 2,
98
98
  width: 1,
@@ -2,13 +2,17 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import { useAtomValue } from '@effect-atom/atom-react';
6
+ import * as Atom from '@effect-atom/atom/Atom';
5
7
  import React, { useCallback, useMemo, useRef, useState } from 'react';
6
8
 
7
9
  import { Surface } from '@dxos/app-framework/ui';
8
- import { type AppSurface } from '@dxos/app-toolkit/ui';
10
+ import { AppSurface } from '@dxos/app-toolkit/ui';
9
11
  import { Filter, Obj, Ref } from '@dxos/echo';
10
- import { useObject, useObjects } from '@dxos/echo-react';
12
+ import { AtomObj } from '@dxos/echo-atom';
13
+ import { useObject } from '@dxos/echo-react';
11
14
  import { invariant } from '@dxos/invariant';
15
+ import { Markdown } from '@dxos/plugin-markdown';
12
16
  import { useQuery } from '@dxos/react-client/echo';
13
17
  import { Panel } from '@dxos/react-ui';
14
18
  import { useAttention } from '@dxos/react-ui-attention';
@@ -24,17 +28,32 @@ type PickerState = {
24
28
  position: Position;
25
29
  };
26
30
 
27
- export type BoardContainerProps = AppSurface.ObjectArticleProps<BoardType.Board>;
31
+ export type BoardArticleProps = AppSurface.ObjectArticleProps<BoardType.Board>;
28
32
 
29
- export const BoardContainer = ({ role, subject: board, attendableId }: BoardContainerProps) => {
30
- const controller = useRef<BoardController>(null);
33
+ export const BoardArticle = ({ role, subject: board, attendableId }: BoardArticleProps) => {
34
+ const { hasAttention } = useAttention(attendableId);
35
+ const db = Obj.getDatabase(board);
31
36
  const [boardItems] = useObject(board, 'items');
32
- const items = useObjects(boardItems ?? []);
37
+ const itemsAtom = useMemo(
38
+ () =>
39
+ Atom.make((get) => {
40
+ const result: Obj.Unknown[] = [];
41
+ for (const ref of boardItems ?? []) {
42
+ const obj = get(AtomObj.makeWithReactive(ref));
43
+ if (obj) {
44
+ result.push(obj);
45
+ }
46
+ }
47
+ return result;
48
+ }),
49
+ [boardItems],
50
+ );
51
+ const items = useAtomValue(itemsAtom);
52
+
53
+ const controller = useRef<BoardController>(null);
33
54
  const addTriggerRef = useRef<HTMLButtonElement | null>(null);
34
55
  const [pickerState, setPickerState] = useState<PickerState | null>(null);
35
- const { hasAttention } = useAttention(attendableId);
36
56
 
37
- const db = Obj.getDatabase(board);
38
57
  // TODO(burdon): Use search.
39
58
  const objects = useQuery(db, Filter.everything());
40
59
  const options = useMemo<ObjectPickerContentProps['options']>(
@@ -57,13 +76,22 @@ export const BoardContainer = ({ role, subject: board, attendableId }: BoardCont
57
76
  );
58
77
 
59
78
  const handleAdd = useCallback<NonNullable<BoardRootProps['onAdd']>>(
60
- async (anchor, position = DEFAULT_POSITION) => {
79
+ async (anchor, position) => {
61
80
  const db = Obj.getDatabase(board);
62
81
  invariant(db);
82
+ // Grid backdrop "+" supplies a position → create a new Markdown document directly.
83
+ // Toolbar "+" omits position → fall back to the picker over existing objects.
84
+ if (position) {
85
+ const doc = db.add(Markdown.make());
86
+ Obj.update(board, (board) => {
87
+ board.items.push(Ref.make(doc));
88
+ board.layout.cells[doc.id.toString()] = position;
89
+ });
90
+ return;
91
+ }
92
+
63
93
  addTriggerRef.current = anchor;
64
- setPickerState({
65
- position,
66
- });
94
+ setPickerState({ position: DEFAULT_POSITION });
67
95
  },
68
96
  [board],
69
97
  );
@@ -73,11 +101,11 @@ export const BoardContainer = ({ role, subject: board, attendableId }: BoardCont
73
101
  (id) => {
74
102
  // TODO(burdon): Impl. DXN.equals and pass in DXN from `id`.
75
103
  const idx = board.items.findIndex((ref) => ref.dxn.asEchoDXN()?.echoId === id);
76
- Obj.change(board, (obj) => {
104
+ Obj.update(board, (board) => {
77
105
  if (idx !== -1) {
78
- obj.items.splice(idx, 1);
106
+ board.items.splice(idx, 1);
79
107
  }
80
- delete obj.layout.cells[id];
108
+ delete board.layout.cells[id];
81
109
  });
82
110
  },
83
111
  [board],
@@ -86,8 +114,8 @@ export const BoardContainer = ({ role, subject: board, attendableId }: BoardCont
86
114
  const handleMove = useCallback<NonNullable<BoardRootProps['onMove']>>(
87
115
  (id, position) => {
88
116
  const layout = board.layout.cells[id];
89
- Obj.change(board, (obj) => {
90
- obj.layout.cells[id] = { ...layout, ...position };
117
+ Obj.update(board, (board) => {
118
+ board.layout.cells[id] = { ...layout, ...position };
91
119
  });
92
120
  },
93
121
  [board],
@@ -106,11 +134,11 @@ export const BoardContainer = ({ role, subject: board, attendableId }: BoardCont
106
134
  }
107
135
 
108
136
  // Create a reference to the selected object and add it to the board.
109
- Obj.change(board, (obj) => {
110
- obj.items.push(Ref.make(selectedObject));
137
+ Obj.update(board, (board) => {
138
+ board.items.push(Ref.make(selectedObject));
111
139
 
112
140
  // Set the layout position for the new item.
113
- obj.layout.cells[selectedObject.id.toString()] = pickerState.position;
141
+ board.layout.cells[selectedObject.id.toString()] = pickerState.position;
114
142
  });
115
143
 
116
144
  // Close the picker.
@@ -138,7 +166,7 @@ export const BoardContainer = ({ role, subject: board, attendableId }: BoardCont
138
166
  <Board.Content>
139
167
  {items?.map((item, index) => (
140
168
  <Board.Cell item={item} key={index} layout={board.layout?.cells[item.id] ?? { x: 0, y: 0 }}>
141
- <Surface.Surface role='card--content' data={{ subject: item }} limit={1} />
169
+ <Surface.Surface type={AppSurface.Card} data={{ subject: item, editable: true }} limit={1} />
142
170
  </Board.Cell>
143
171
  ))}
144
172
  </Board.Content>
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export { BoardArticle as default } from './BoardArticle';
@@ -4,4 +4,4 @@
4
4
 
5
5
  import { type ComponentType, lazy } from 'react';
6
6
 
7
- export const BoardContainer: ComponentType<any> = lazy(() => import('./BoardContainer'));
7
+ export const BoardArticle: ComponentType<any> = lazy(() => import('./BoardArticle'));
package/src/index.ts CHANGED
@@ -4,5 +4,3 @@
4
4
 
5
5
  export * from './meta';
6
6
  export * from './types';
7
-
8
- export * from './BoardPlugin';
package/src/plugin.ts ADDED
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+
7
+ import { meta } from './meta';
8
+
9
+ export const BoardPlugin = Plugin.lazy(meta, () => import('#plugin'));
@@ -1,92 +0,0 @@
1
- import {
2
- Board_exports
3
- } from "./chunk-FL67SBF5.mjs";
4
-
5
- // src/meta.ts
6
- import { trim } from "@dxos/util";
7
- var meta = {
8
- id: "org.dxos.plugin.board",
9
- name: "Board",
10
- description: trim`
11
- Infinite canvas workspace that combines sticky notes, media, and whiteboarding tools.
12
- Arrange and connect ideas freely in a visual space perfect for brainstorming and creative collaboration.
13
- `,
14
- icon: "ph--squares-four--regular",
15
- iconHue: "green",
16
- source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-board",
17
- screenshots: []
18
- };
19
-
20
- // src/BoardPlugin.tsx
21
- import * as Effect from "effect/Effect";
22
- import * as Option from "effect/Option";
23
- import { Plugin } from "@dxos/app-framework";
24
- import { AppPlugin } from "@dxos/app-toolkit";
25
- import { Annotation } from "@dxos/echo";
26
- import { Operation } from "@dxos/operation";
27
- import { SpaceOperation } from "@dxos/plugin-space/operations";
28
- import { translations as boardTranslations } from "@dxos/react-ui-board";
29
- import { ReactSurface } from "#capabilities";
30
- import { meta as meta3 } from "#meta";
31
- import { Board as Board2 } from "#types";
32
-
33
- // src/translations.ts
34
- import { meta as meta2 } from "#meta";
35
- import { Board } from "#types";
36
- var translations = [
37
- {
38
- "en-US": {
39
- [Board.Board.typename]: {
40
- "typename.label": "Board",
41
- "typename.label_zero": "Boards",
42
- "typename.label_one": "Board",
43
- "typename.label_other": "Boards",
44
- "object-name.placeholder": "New board",
45
- "add-object.label": "Add board",
46
- "rename-object.label": "Rename board",
47
- "delete-object.label": "Delete board",
48
- "object-deleted.label": "Board deleted"
49
- },
50
- [meta2.id]: {
51
- "plugin.name": "Board"
52
- }
53
- }
54
- }
55
- ];
56
-
57
- // src/BoardPlugin.tsx
58
- var BoardPlugin = Plugin.define(meta3).pipe(AppPlugin.addMetadataModule({
59
- metadata: {
60
- id: Board2.Board.typename,
61
- metadata: {
62
- icon: Annotation.IconAnnotation.get(Board2.Board).pipe(Option.getOrThrow).icon,
63
- iconHue: Annotation.IconAnnotation.get(Board2.Board).pipe(Option.getOrThrow).hue ?? "white",
64
- createObject: (props, options) => Effect.gen(function* () {
65
- const object = Board2.makeBoard(props);
66
- return yield* Operation.invoke(SpaceOperation.AddObject, {
67
- object,
68
- target: options.target,
69
- hidden: true,
70
- targetNodeId: options.targetNodeId
71
- });
72
- })
73
- }
74
- }
75
- }), AppPlugin.addSchemaModule({
76
- schema: [
77
- Board2.Board
78
- ]
79
- }), AppPlugin.addSurfaceModule({
80
- activate: ReactSurface
81
- }), AppPlugin.addTranslationsModule({
82
- translations: [
83
- ...translations,
84
- ...boardTranslations
85
- ]
86
- }), Plugin.make);
87
- export {
88
- Board_exports as Board,
89
- BoardPlugin,
90
- meta
91
- };
92
- //# sourceMappingURL=index.mjs.map