@dxos/plugin-board 0.8.4-main.5ea62a8 → 0.8.4-main.ae835ea

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 (45) hide show
  1. package/dist/lib/browser/{chunk-V67SBM4U.mjs → chunk-6IYOP7JD.mjs} +12 -7
  2. package/dist/lib/browser/chunk-6IYOP7JD.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-IDV4P2SK.mjs +143 -0
  4. package/dist/lib/browser/chunk-IDV4P2SK.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +46 -47
  6. package/dist/lib/browser/index.mjs.map +3 -3
  7. package/dist/lib/browser/{intent-resolver-6NM32ZSV.mjs → intent-resolver-MGJCQT3N.mjs} +4 -4
  8. package/dist/lib/browser/{intent-resolver-6NM32ZSV.mjs.map → intent-resolver-MGJCQT3N.mjs.map} +1 -1
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/{react-surface-PQP6ODCJ.mjs → react-surface-EACRLTVO.mjs} +5 -5
  11. package/dist/lib/browser/{react-surface-PQP6ODCJ.mjs.map → react-surface-EACRLTVO.mjs.map} +1 -1
  12. package/dist/lib/browser/types/index.mjs +1 -1
  13. package/dist/lib/node-esm/{chunk-XCGDC6OV.mjs → chunk-WFLKZNL3.mjs} +12 -7
  14. package/dist/lib/node-esm/chunk-WFLKZNL3.mjs.map +7 -0
  15. package/dist/lib/node-esm/chunk-ZNNC2VAL.mjs +145 -0
  16. package/dist/lib/node-esm/chunk-ZNNC2VAL.mjs.map +7 -0
  17. package/dist/lib/node-esm/index.mjs +46 -47
  18. package/dist/lib/node-esm/index.mjs.map +3 -3
  19. package/dist/lib/node-esm/{intent-resolver-5DQ5PPTT.mjs → intent-resolver-TV2AARM7.mjs} +4 -4
  20. package/dist/lib/node-esm/{intent-resolver-5DQ5PPTT.mjs.map → intent-resolver-TV2AARM7.mjs.map} +1 -1
  21. package/dist/lib/node-esm/meta.json +1 -1
  22. package/dist/lib/node-esm/{react-surface-KXSZZOEH.mjs → react-surface-PEYOXLWP.mjs} +5 -5
  23. package/dist/lib/node-esm/{react-surface-KXSZZOEH.mjs.map → react-surface-PEYOXLWP.mjs.map} +1 -1
  24. package/dist/lib/node-esm/types/index.mjs +1 -1
  25. package/dist/types/src/BoardPlugin.d.ts +1 -1
  26. package/dist/types/src/BoardPlugin.d.ts.map +1 -1
  27. package/dist/types/src/components/BoardContainer.d.ts.map +1 -1
  28. package/dist/types/src/components/BoardContainer.stories.d.ts +4 -3
  29. package/dist/types/src/components/BoardContainer.stories.d.ts.map +1 -1
  30. package/dist/types/src/meta.d.ts.map +1 -1
  31. package/dist/types/src/types/Board.d.ts +3 -3
  32. package/dist/types/src/types/Board.d.ts.map +1 -1
  33. package/dist/types/tsconfig.tsbuildinfo +1 -1
  34. package/package.json +42 -42
  35. package/src/BoardPlugin.tsx +41 -42
  36. package/src/components/BoardContainer.stories.tsx +12 -9
  37. package/src/components/BoardContainer.tsx +93 -35
  38. package/src/meta.ts +6 -2
  39. package/src/types/Board.ts +5 -5
  40. package/dist/lib/browser/chunk-V67SBM4U.mjs.map +0 -7
  41. package/dist/lib/browser/chunk-YYCPOFRP.mjs +0 -106
  42. package/dist/lib/browser/chunk-YYCPOFRP.mjs.map +0 -7
  43. package/dist/lib/node-esm/chunk-RNEIWFZQ.mjs +0 -108
  44. package/dist/lib/node-esm/chunk-RNEIWFZQ.mjs.map +0 -7
  45. package/dist/lib/node-esm/chunk-XCGDC6OV.mjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-board",
3
- "version": "0.8.4-main.5ea62a8",
3
+ "version": "0.8.4-main.ae835ea",
4
4
  "description": "Surface plugin for card baords",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -36,52 +36,52 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@preact-signals/safe-react": "^0.9.0",
39
- "@preact/signals-core": "^1.9.0",
40
- "@preact/signals-react": "^3.2.0",
41
- "effect": "3.17.7",
42
- "@dxos/ai": "0.8.4-main.5ea62a8",
43
- "@dxos/assistant": "0.8.4-main.5ea62a8",
44
- "@dxos/app-framework": "0.8.4-main.5ea62a8",
45
- "@dxos/async": "0.8.4-main.5ea62a8",
46
- "@dxos/blueprints": "0.8.4-main.5ea62a8",
47
- "@dxos/client": "0.8.4-main.5ea62a8",
48
- "@dxos/echo": "0.8.4-main.5ea62a8",
49
- "@dxos/effect": "0.8.4-main.5ea62a8",
50
- "@dxos/echo-schema": "0.8.4-main.5ea62a8",
51
- "@dxos/invariant": "0.8.4-main.5ea62a8",
52
- "@dxos/log": "0.8.4-main.5ea62a8",
53
- "@dxos/plugin-client": "0.8.4-main.5ea62a8",
54
- "@dxos/plugin-graph": "0.8.4-main.5ea62a8",
55
- "@dxos/plugin-search": "0.8.4-main.5ea62a8",
56
- "@dxos/plugin-space": "0.8.4-main.5ea62a8",
57
- "@dxos/react-ui": "0.8.4-main.5ea62a8",
58
- "@dxos/random": "0.8.4-main.5ea62a8",
59
- "@dxos/react-ui-form": "0.8.4-main.5ea62a8",
60
- "@dxos/react-ui-board": "0.8.4-main.5ea62a8",
61
- "@dxos/react-ui-stack": "0.8.4-main.5ea62a8",
62
- "@dxos/schema": "0.8.4-main.5ea62a8",
63
- "@dxos/util": "0.8.4-main.5ea62a8",
64
- "@dxos/react-client": "0.8.4-main.5ea62a8"
39
+ "@preact/signals-core": "^1.12.1",
40
+ "@preact/signals-react": "^3.3.0",
41
+ "effect": "3.18.3",
42
+ "@dxos/ai": "0.8.4-main.ae835ea",
43
+ "@dxos/app-framework": "0.8.4-main.ae835ea",
44
+ "@dxos/assistant": "0.8.4-main.ae835ea",
45
+ "@dxos/blueprints": "0.8.4-main.ae835ea",
46
+ "@dxos/async": "0.8.4-main.ae835ea",
47
+ "@dxos/client": "0.8.4-main.ae835ea",
48
+ "@dxos/echo": "0.8.4-main.ae835ea",
49
+ "@dxos/effect": "0.8.4-main.ae835ea",
50
+ "@dxos/invariant": "0.8.4-main.ae835ea",
51
+ "@dxos/log": "0.8.4-main.ae835ea",
52
+ "@dxos/plugin-client": "0.8.4-main.ae835ea",
53
+ "@dxos/plugin-search": "0.8.4-main.ae835ea",
54
+ "@dxos/plugin-space": "0.8.4-main.ae835ea",
55
+ "@dxos/random": "0.8.4-main.ae835ea",
56
+ "@dxos/plugin-graph": "0.8.4-main.ae835ea",
57
+ "@dxos/react-client": "0.8.4-main.ae835ea",
58
+ "@dxos/react-ui": "0.8.4-main.ae835ea",
59
+ "@dxos/react-ui-attention": "0.8.4-main.ae835ea",
60
+ "@dxos/react-ui-board": "0.8.4-main.ae835ea",
61
+ "@dxos/react-ui-form": "0.8.4-main.ae835ea",
62
+ "@dxos/react-ui-stack": "0.8.4-main.ae835ea",
63
+ "@dxos/util": "0.8.4-main.ae835ea",
64
+ "@dxos/schema": "0.8.4-main.ae835ea"
65
65
  },
66
66
  "devDependencies": {
67
- "@types/react": "~18.2.0",
68
- "@types/react-dom": "~18.2.0",
69
- "react": "~18.2.0",
70
- "react-dom": "~18.2.0",
71
- "vite": "7.1.1",
72
- "@dxos/plugin-preview": "0.8.4-main.5ea62a8",
73
- "@dxos/plugin-theme": "0.8.4-main.5ea62a8",
74
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.5ea62a8",
75
- "@dxos/react-ui-theme": "0.8.4-main.5ea62a8",
76
- "@dxos/storybook-utils": "0.8.4-main.5ea62a8",
77
- "@dxos/test-utils": "0.8.4-main.5ea62a8"
67
+ "@types/react": "~19.2.2",
68
+ "@types/react-dom": "~19.2.2",
69
+ "react": "~19.2.0",
70
+ "react-dom": "~19.2.0",
71
+ "vite": "7.1.9",
72
+ "@dxos/plugin-preview": "0.8.4-main.ae835ea",
73
+ "@dxos/plugin-theme": "0.8.4-main.ae835ea",
74
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.ae835ea",
75
+ "@dxos/react-ui-theme": "0.8.4-main.ae835ea",
76
+ "@dxos/storybook-utils": "0.8.4-main.ae835ea",
77
+ "@dxos/test-utils": "0.8.4-main.ae835ea"
78
78
  },
79
79
  "peerDependencies": {
80
80
  "effect": "^3.13.3",
81
- "react": "~18.2.0",
82
- "react-dom": "~18.2.0",
83
- "@dxos/react-ui": "0.8.4-main.5ea62a8",
84
- "@dxos/react-ui-theme": "0.8.4-main.5ea62a8"
81
+ "react": "^19.0.0",
82
+ "react-dom": "^19.0.0",
83
+ "@dxos/react-ui": "0.8.4-main.ae835ea",
84
+ "@dxos/react-ui-theme": "0.8.4-main.ae835ea"
85
85
  },
86
86
  "publishConfig": {
87
87
  "access": "public"
@@ -13,46 +13,45 @@ import { meta } from './meta';
13
13
  import { translations } from './translations';
14
14
  import { Board } from './types';
15
15
 
16
- export const BoardPlugin = () => {
17
- return definePlugin(meta, [
18
- defineModule({
19
- id: `${meta.id}/module/translations`,
20
- activatesOn: Events.SetupTranslations,
21
- activate: () => contributes(Capabilities.Translations, [...translations, ...boardTranslations]),
22
- }),
23
- defineModule({
24
- id: `${meta.id}/module/metadata`,
25
- activatesOn: Events.SetupMetadata,
26
- activate: () =>
27
- // TODO(burdon): "Metadata" here seems non-descriptive; is this specifically for the type? ObjectMetadata?
28
- contributes(Capabilities.Metadata, {
29
- id: Board.Board.typename,
30
- metadata: {
31
- icon: 'ph--squares-four--regular',
32
- },
16
+ export const BoardPlugin = definePlugin(meta, () => [
17
+ defineModule({
18
+ id: `${meta.id}/module/translations`,
19
+ activatesOn: Events.SetupTranslations,
20
+ activate: () => contributes(Capabilities.Translations, [...translations, ...boardTranslations]),
21
+ }),
22
+ defineModule({
23
+ id: `${meta.id}/module/metadata`,
24
+ activatesOn: Events.SetupMetadata,
25
+ activate: () =>
26
+ // TODO(burdon): "Metadata" here seems non-descriptive; is this specifically for the type? ObjectMetadata?
27
+ contributes(Capabilities.Metadata, {
28
+ id: Board.Board.typename,
29
+ metadata: {
30
+ icon: 'ph--squares-four--regular',
31
+ iconHue: 'green',
32
+ },
33
+ }),
34
+ }),
35
+ defineModule({
36
+ id: `${meta.id}/module/object-form`,
37
+ activatesOn: ClientEvents.SetupSchema,
38
+ activate: () =>
39
+ contributes(
40
+ SpaceCapabilities.ObjectForm,
41
+ defineObjectForm({
42
+ objectSchema: Board.Board,
43
+ getIntent: () => createIntent(Board.Create),
33
44
  }),
34
- }),
35
- defineModule({
36
- id: `${meta.id}/module/object-form`,
37
- activatesOn: ClientEvents.SetupSchema,
38
- activate: () =>
39
- contributes(
40
- SpaceCapabilities.ObjectForm,
41
- defineObjectForm({
42
- objectSchema: Board.Board,
43
- getIntent: () => createIntent(Board.Create),
44
- }),
45
- ),
46
- }),
47
- defineModule({
48
- id: `${meta.id}/module/react-surface`,
49
- activatesOn: Events.SetupReactSurface,
50
- activate: ReactSurface,
51
- }),
52
- defineModule({
53
- id: `${meta.id}/module/intent-resolver`,
54
- activatesOn: Events.SetupIntentResolver,
55
- activate: IntentResolver,
56
- }),
57
- ]);
58
- };
45
+ ),
46
+ }),
47
+ defineModule({
48
+ id: `${meta.id}/module/react-surface`,
49
+ activatesOn: Events.SetupReactSurface,
50
+ activate: ReactSurface,
51
+ }),
52
+ defineModule({
53
+ id: `${meta.id}/module/intent-resolver`,
54
+ activatesOn: Events.SetupIntentResolver,
55
+ activate: IntentResolver,
56
+ }),
57
+ ]);
@@ -2,8 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type StoryObj } from '@storybook/react-vite';
8
6
  import React, { useEffect, useState } from 'react';
9
7
 
@@ -17,10 +15,10 @@ import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
17
15
  import { ThemePlugin } from '@dxos/plugin-theme';
18
16
  import { faker } from '@dxos/random';
19
17
  import { Filter, Ref, useQuery, useSpaces } from '@dxos/react-client/echo';
18
+ import { withTheme } from '@dxos/react-ui/testing';
20
19
  import { translations as stackTranslations } from '@dxos/react-ui-stack';
21
20
  import { defaultTx } from '@dxos/react-ui-theme';
22
21
  import { DataType } from '@dxos/schema';
23
- import { withLayout } from '@dxos/storybook-utils';
24
22
 
25
23
  import { translations } from '../translations';
26
24
  import { Board } from '../types';
@@ -76,12 +74,10 @@ const DefaultStory = () => {
76
74
  const meta = {
77
75
  title: 'plugins/plugin-board/Board',
78
76
  render: DefaultStory,
79
- parameters: { translations: [...translations, ...stackTranslations] },
80
77
  decorators: [
81
- withLayout({ fullscreen: true }),
78
+ withTheme,
82
79
  withPluginManager({
83
80
  plugins: [
84
- ThemePlugin({ tx: defaultTx }),
85
81
  ClientPlugin({
86
82
  types: [DataType.Organization, DataType.Person, Board.Board],
87
83
  onClientInitialized: async ({ client }) => {
@@ -105,14 +101,21 @@ const meta = {
105
101
  });
106
102
  },
107
103
  }),
108
- StorybookLayoutPlugin(),
109
- PreviewPlugin(),
110
- SpacePlugin(),
104
+ SpacePlugin({}),
111
105
  IntentPlugin(),
112
106
  SettingsPlugin(),
107
+
108
+ // UI
109
+ ThemePlugin({ tx: defaultTx }),
110
+ PreviewPlugin(),
111
+ StorybookLayoutPlugin({}),
113
112
  ],
114
113
  }),
115
114
  ],
115
+ parameters: {
116
+ layout: 'fullscreen',
117
+ translations: [...translations, ...stackTranslations],
118
+ },
116
119
  };
117
120
 
118
121
  export default meta;
@@ -2,48 +2,72 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, { useCallback, useRef } from 'react';
5
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
6
6
 
7
- import { Surface, createIntent, useIntentDispatcher } from '@dxos/app-framework';
7
+ import { Surface } from '@dxos/app-framework';
8
8
  import { getSpace } from '@dxos/client/echo';
9
- import { type Obj, Ref } from '@dxos/echo';
9
+ import { Filter, Obj, Ref } from '@dxos/echo';
10
10
  import { invariant } from '@dxos/invariant';
11
- import { SpaceAction } from '@dxos/plugin-space/types';
11
+ import { useQuery } from '@dxos/react-client/echo';
12
+ import { fullyQualifiedId } from '@dxos/react-client/echo';
12
13
  import { useSignalsMemo } from '@dxos/react-ui';
13
- import { Board, type BoardController, type BoardRootProps } from '@dxos/react-ui-board';
14
+ import { useAttention } from '@dxos/react-ui-attention';
15
+ import { Board, type BoardController, type BoardRootProps, type Position } from '@dxos/react-ui-board';
16
+ import { ObjectPicker, type ObjectPickerContentProps } from '@dxos/react-ui-form';
14
17
  import { StackItem } from '@dxos/react-ui-stack';
15
18
  import { isNonNullable } from '@dxos/util';
16
19
 
17
20
  import { type Board as BoardType } from '../types';
18
21
 
22
+ const DEFAULT_POSITION = { x: 0, y: 0 } satisfies Position;
23
+
24
+ type PickerState = {
25
+ position: Position;
26
+ };
27
+
19
28
  export type BoardContainerProps = {
20
29
  role?: string;
21
30
  board: BoardType.Board;
22
31
  };
23
32
 
24
33
  export const BoardContainer = ({ board }: BoardContainerProps) => {
25
- const { dispatchPromise: dispatch } = useIntentDispatcher();
26
34
  const controller = useRef<BoardController>(null);
27
35
  const items = useSignalsMemo(() => board.items.map((ref) => ref.target).filter(isNonNullable), [board]);
36
+ const addTriggerRef = useRef<HTMLButtonElement | null>(null);
37
+ const [pickerState, setPickerState] = useState<PickerState | null>(null);
38
+ const attendableId = fullyQualifiedId(board);
39
+ const { hasAttention } = useAttention(attendableId);
40
+
41
+ // Memoize options for ObjectPicker containing all ECHO objects in the same space as the Board.
42
+ const objects = useQuery(getSpace(board), Filter.everything());
43
+ const options = useMemo(
44
+ () =>
45
+ objects
46
+ .filter((obj) => obj.id !== board.id)
47
+ .map((obj) => {
48
+ const label = Obj.getLabel(obj);
49
+ if (label) {
50
+ return {
51
+ id: obj.id,
52
+ label,
53
+ // hue: 'neutral' as const,
54
+ };
55
+ }
56
+ })
57
+ .filter(isNonNullable),
58
+ [objects],
59
+ );
28
60
 
29
61
  const handleAdd = useCallback<NonNullable<BoardRootProps['onAdd']>>(
30
- async (position = { x: 0, y: 0 }) => {
62
+ async (anchor, position = DEFAULT_POSITION) => {
31
63
  const space = getSpace(board);
32
64
  invariant(space);
33
- await dispatch(
34
- createIntent(SpaceAction.OpenCreateObject, {
35
- target: space,
36
- navigable: false,
37
- onCreateObject: (object: Obj.Any) => {
38
- board.items.push(Ref.make(object));
39
- console.log(board.items.length);
40
- board.layout.cells[object.id] = { ...position, width: 1, height: 1 };
41
- controller.current?.center(position);
42
- },
43
- }),
44
- );
65
+ addTriggerRef.current = anchor;
66
+ setPickerState({
67
+ position,
68
+ });
45
69
  },
46
- [board, controller, dispatch],
70
+ [board],
47
71
  );
48
72
 
49
73
  // TODO(burdon): Use intents so can be undone.
@@ -67,23 +91,57 @@ export const BoardContainer = ({ board }: BoardContainerProps) => {
67
91
  [board],
68
92
  );
69
93
 
94
+ const handleSelect = useCallback<NonNullable<ObjectPickerContentProps['onSelect']>>(
95
+ (id) => {
96
+ if (!pickerState) {
97
+ return;
98
+ }
99
+
100
+ // Find the selected object by id from the space.
101
+ const selectedObject = objects.find((obj) => obj.id === id);
102
+ if (!selectedObject) {
103
+ return;
104
+ }
105
+
106
+ // Create a reference to the selected object and add it to the board.
107
+ board.items.push(Ref.make(selectedObject));
108
+
109
+ // Set the layout position for the new item.
110
+ board.layout.cells[selectedObject.id.toString()] = pickerState.position;
111
+
112
+ // Close the picker.
113
+ setPickerState(null);
114
+ },
115
+ [pickerState, objects, board],
116
+ );
117
+
70
118
  return (
71
119
  <Board.Root ref={controller} layout={board.layout} onAdd={handleAdd} onDelete={handleDelete} onMove={handleMove}>
72
- <StackItem.Content toolbar classNames='overflow-hidden'>
73
- <Board.Toolbar />
74
- <Board.Container>
75
- <Board.Viewport classNames='border-none'>
76
- <Board.Backdrop />
77
- <Board.Content>
78
- {items?.map((item, index) => (
79
- <Board.Cell item={item} key={index} layout={board.layout?.cells[item.id] ?? { x: 0, y: 0 }}>
80
- <Surface role='card--extrinsic' data={{ subject: item }} limit={1} />
81
- </Board.Cell>
82
- ))}
83
- </Board.Content>
84
- </Board.Viewport>
85
- </Board.Container>
86
- </StackItem.Content>
120
+ <ObjectPicker.Root
121
+ open={!!pickerState}
122
+ onOpenChange={(nextOpen: boolean) => {
123
+ setPickerState(nextOpen ? { position: DEFAULT_POSITION } : null);
124
+ }}
125
+ >
126
+ <StackItem.Content toolbar>
127
+ <Board.Toolbar disabled={!hasAttention} />
128
+ <Board.Container>
129
+ <Board.Viewport classNames='border-none'>
130
+ <Board.Backdrop />
131
+ <Board.Content>
132
+ {items?.map((item, index) => (
133
+ <Board.Cell item={item} key={index} layout={board.layout?.cells[item.id] ?? { x: 0, y: 0 }}>
134
+ <Surface role='card--extrinsic' data={{ subject: item }} limit={1} />
135
+ </Board.Cell>
136
+ ))}
137
+ </Board.Content>
138
+ </Board.Viewport>
139
+ </Board.Container>
140
+ </StackItem.Content>
141
+ {/* TODO(burdon): Currently clipped by sidebar. */}
142
+ <ObjectPicker.Content options={options} onSelect={handleSelect} classNames='popover-card-width' />
143
+ <ObjectPicker.VirtualTrigger virtualRef={addTriggerRef} />
144
+ </ObjectPicker.Root>
87
145
  </Board.Root>
88
146
  );
89
147
  };
package/src/meta.ts CHANGED
@@ -3,13 +3,17 @@
3
3
  //
4
4
 
5
5
  import { type PluginMeta } from '@dxos/app-framework';
6
+ import { trim } from '@dxos/util';
6
7
 
7
8
  export const meta: PluginMeta = {
8
9
  id: 'dxos.org/plugin/board',
9
10
  name: 'Board',
10
- description:
11
- 'A spatial, infinite canvas app combining notes, media, and whiteboarding in a tactile, visual interface.',
11
+ description: trim`
12
+ Infinite canvas workspace that combines sticky notes, media, and whiteboarding tools.
13
+ Arrange and connect ideas freely in a visual space perfect for brainstorming and creative collaboration.
14
+ `,
12
15
  icon: 'ph--squares-four--regular',
16
+ iconHue: 'green',
13
17
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-board',
14
18
  screenshots: [],
15
19
  };
@@ -2,10 +2,10 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
7
  import { Obj, Type } from '@dxos/echo';
8
- import { LabelAnnotation } from '@dxos/echo-schema';
8
+ import { FormAnnotation, LabelAnnotation } from '@dxos/echo/internal';
9
9
  import { BoardLayout, defaultLayout } from '@dxos/react-ui-board';
10
10
 
11
11
  import { meta } from '../meta';
@@ -14,9 +14,9 @@ import { meta } from '../meta';
14
14
  * Board and layout.
15
15
  */
16
16
  export const Board = Schema.Struct({
17
- name: Schema.optional(Schema.String),
18
- items: Schema.mutable(Schema.Array(Type.Ref(Type.Expando))),
19
- layout: Schema.mutable(BoardLayout),
17
+ name: Schema.String.pipe(Schema.optional),
18
+ items: Type.Ref(Type.Expando).pipe(Schema.Array, Schema.mutable, FormAnnotation.set(false)),
19
+ layout: BoardLayout.pipe(Schema.mutable, FormAnnotation.set(false)),
20
20
  }).pipe(
21
21
  Type.Obj({
22
22
  typename: 'dxos.org/type/Board',
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/types/Board.ts", "../../../src/meta.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { Obj, Type } from '@dxos/echo';\nimport { LabelAnnotation } from '@dxos/echo-schema';\nimport { BoardLayout, defaultLayout } from '@dxos/react-ui-board';\n\nimport { meta } from '../meta';\n\n/**\n * Board and layout.\n */\nexport const Board = Schema.Struct({\n name: Schema.optional(Schema.String),\n items: Schema.mutable(Schema.Array(Type.Ref(Type.Expando))),\n layout: Schema.mutable(BoardLayout),\n}).pipe(\n Type.Obj({\n typename: 'dxos.org/type/Board',\n version: '0.1.0',\n }),\n LabelAnnotation.set(['name']),\n);\n\nexport interface Board extends Schema.Schema.Type<typeof Board> {}\n\nexport const makeBoard = (props: Partial<Obj.MakeProps<typeof Board>> = {}) =>\n Obj.make(Board, {\n items: [],\n layout: defaultLayout,\n ...props,\n });\n\n/**\n * Create board.\n */\nexport class Create extends Schema.TaggedClass<Create>()(`${meta.id}/action/create`, {\n input: Schema.Struct({\n name: Schema.optional(Schema.String),\n }),\n output: Schema.Struct({\n object: Board,\n }),\n}) {}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type PluginMeta } from '@dxos/app-framework';\n\nexport const meta: PluginMeta = {\n id: 'dxos.org/plugin/board',\n name: 'Board',\n description:\n 'A spatial, infinite canvas app combining notes, media, and whiteboarding in a tactile, visual interface.',\n icon: 'ph--squares-four--regular',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-board',\n screenshots: [],\n};\n"],
5
- "mappings": ";;;;;;;AAAA;;;;;;AAIA,SAASA,cAAc;AAEvB,SAASC,KAAKC,YAAY;AAC1B,SAASC,uBAAuB;AAChC,SAASC,aAAaC,qBAAqB;;;ACFpC,IAAMC,OAAmB;EAC9BC,IAAI;EACJC,MAAM;EACNC,aACE;EACFC,MAAM;EACNC,QAAQ;EACRC,aAAa,CAAA;AACf;;;ADCO,IAAMC,QAAQC,OAAOC,OAAO;EACjCC,MAAMF,OAAOG,SAASH,OAAOI,MAAM;EACnCC,OAAOL,OAAOM,QAAQN,OAAOO,MAAMC,KAAKC,IAAID,KAAKE,OAAO,CAAA,CAAA;EACxDC,QAAQX,OAAOM,QAAQM,WAAAA;AACzB,CAAA,EAAGC,KACDL,KAAKM,IAAI;EACPC,UAAU;EACVC,SAAS;AACX,CAAA,GACAC,gBAAgBC,IAAI;EAAC;CAAO,CAAA;AAKvB,IAAMC,YAAY,CAACC,QAA8C,CAAC,MACvEN,IAAIO,KAAKtB,OAAO;EACdM,OAAO,CAAA;EACPM,QAAQW;EACR,GAAGF;AACL,CAAA;AAKK,IAAMG,SAAN,cAAqBvB,OAAOwB,YAAW,EAAW,GAAGC,KAAKC,EAAE,kBAAkB;EACnFC,OAAO3B,OAAOC,OAAO;IACnBC,MAAMF,OAAOG,SAASH,OAAOI,MAAM;EACrC,CAAA;EACAwB,QAAQ5B,OAAOC,OAAO;IACpB4B,QAAQ9B;EACV,CAAA;AACF,CAAA,EAAA;AAAI;",
6
- "names": ["Schema", "Obj", "Type", "LabelAnnotation", "BoardLayout", "defaultLayout", "meta", "id", "name", "description", "icon", "source", "screenshots", "Board", "Schema", "Struct", "name", "optional", "String", "items", "mutable", "Array", "Type", "Ref", "Expando", "layout", "BoardLayout", "pipe", "Obj", "typename", "version", "LabelAnnotation", "set", "makeBoard", "props", "make", "defaultLayout", "Create", "TaggedClass", "meta", "id", "input", "output", "object"]
7
- }
@@ -1,106 +0,0 @@
1
- // src/components/BoardContainer.tsx
2
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
3
- import React, { useCallback, useRef } from "react";
4
- import { Surface, createIntent, useIntentDispatcher } from "@dxos/app-framework";
5
- import { getSpace } from "@dxos/client/echo";
6
- import { Ref } from "@dxos/echo";
7
- import { invariant } from "@dxos/invariant";
8
- import { SpaceAction } from "@dxos/plugin-space/types";
9
- import { useSignalsMemo } from "@dxos/react-ui";
10
- import { Board } from "@dxos/react-ui-board";
11
- import { StackItem } from "@dxos/react-ui-stack";
12
- import { isNonNullable } from "@dxos/util";
13
- var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-board/src/components/BoardContainer.tsx";
14
- var BoardContainer = ({ board }) => {
15
- var _effect = _useSignals();
16
- try {
17
- const { dispatchPromise: dispatch } = useIntentDispatcher();
18
- const controller = useRef(null);
19
- const items = useSignalsMemo(() => board.items.map((ref) => ref.target).filter(isNonNullable), [
20
- board
21
- ]);
22
- const handleAdd = useCallback(async (position = {
23
- x: 0,
24
- y: 0
25
- }) => {
26
- const space = getSpace(board);
27
- invariant(space, void 0, {
28
- F: __dxlog_file,
29
- L: 32,
30
- S: void 0,
31
- A: [
32
- "space",
33
- ""
34
- ]
35
- });
36
- await dispatch(createIntent(SpaceAction.OpenCreateObject, {
37
- target: space,
38
- navigable: false,
39
- onCreateObject: (object) => {
40
- board.items.push(Ref.make(object));
41
- console.log(board.items.length);
42
- board.layout.cells[object.id] = {
43
- ...position,
44
- width: 1,
45
- height: 1
46
- };
47
- controller.current?.center(position);
48
- }
49
- }));
50
- }, [
51
- board,
52
- controller,
53
- dispatch
54
- ]);
55
- const handleDelete = useCallback((id) => {
56
- const idx = board.items.findIndex((ref) => ref.dxn.asEchoDXN()?.echoId === id);
57
- if (idx !== -1) {
58
- board.items.splice(idx, 1);
59
- }
60
- delete board.layout.cells[id];
61
- }, [
62
- board
63
- ]);
64
- const handleMove = useCallback((id, position) => {
65
- const layout = board.layout.cells[id];
66
- board.layout.cells[id] = {
67
- ...layout,
68
- ...position
69
- };
70
- }, [
71
- board
72
- ]);
73
- return /* @__PURE__ */ React.createElement(Board.Root, {
74
- ref: controller,
75
- layout: board.layout,
76
- onAdd: handleAdd,
77
- onDelete: handleDelete,
78
- onMove: handleMove
79
- }, /* @__PURE__ */ React.createElement(StackItem.Content, {
80
- toolbar: true,
81
- classNames: "overflow-hidden"
82
- }, /* @__PURE__ */ React.createElement(Board.Toolbar, null), /* @__PURE__ */ React.createElement(Board.Container, null, /* @__PURE__ */ React.createElement(Board.Viewport, {
83
- classNames: "border-none"
84
- }, /* @__PURE__ */ React.createElement(Board.Backdrop, null), /* @__PURE__ */ React.createElement(Board.Content, null, items?.map((item, index) => /* @__PURE__ */ React.createElement(Board.Cell, {
85
- item,
86
- key: index,
87
- layout: board.layout?.cells[item.id] ?? {
88
- x: 0,
89
- y: 0
90
- }
91
- }, /* @__PURE__ */ React.createElement(Surface, {
92
- role: "card--extrinsic",
93
- data: {
94
- subject: item
95
- },
96
- limit: 1
97
- }))))))));
98
- } finally {
99
- _effect.f();
100
- }
101
- };
102
-
103
- export {
104
- BoardContainer
105
- };
106
- //# sourceMappingURL=chunk-YYCPOFRP.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/BoardContainer.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useRef } from 'react';\n\nimport { Surface, createIntent, useIntentDispatcher } from '@dxos/app-framework';\nimport { getSpace } from '@dxos/client/echo';\nimport { type Obj, Ref } from '@dxos/echo';\nimport { invariant } from '@dxos/invariant';\nimport { SpaceAction } from '@dxos/plugin-space/types';\nimport { useSignalsMemo } from '@dxos/react-ui';\nimport { Board, type BoardController, type BoardRootProps } from '@dxos/react-ui-board';\nimport { StackItem } from '@dxos/react-ui-stack';\nimport { isNonNullable } from '@dxos/util';\n\nimport { type Board as BoardType } from '../types';\n\nexport type BoardContainerProps = {\n role?: string;\n board: BoardType.Board;\n};\n\nexport const BoardContainer = ({ board }: BoardContainerProps) => {\n const { dispatchPromise: dispatch } = useIntentDispatcher();\n const controller = useRef<BoardController>(null);\n const items = useSignalsMemo(() => board.items.map((ref) => ref.target).filter(isNonNullable), [board]);\n\n const handleAdd = useCallback<NonNullable<BoardRootProps['onAdd']>>(\n async (position = { x: 0, y: 0 }) => {\n const space = getSpace(board);\n invariant(space);\n await dispatch(\n createIntent(SpaceAction.OpenCreateObject, {\n target: space,\n navigable: false,\n onCreateObject: (object: Obj.Any) => {\n board.items.push(Ref.make(object));\n console.log(board.items.length);\n board.layout.cells[object.id] = { ...position, width: 1, height: 1 };\n controller.current?.center(position);\n },\n }),\n );\n },\n [board, controller, dispatch],\n );\n\n // TODO(burdon): Use intents so can be undone.\n const handleDelete = useCallback<NonNullable<BoardRootProps['onDelete']>>(\n (id) => {\n // TODO(burdon): Impl. DXN.equals and pass in DXN from `id`.\n const idx = board.items.findIndex((ref) => ref.dxn.asEchoDXN()?.echoId === id);\n if (idx !== -1) {\n board.items.splice(idx, 1);\n }\n delete board.layout.cells[id];\n },\n [board],\n );\n\n const handleMove = useCallback<NonNullable<BoardRootProps['onMove']>>(\n (id, position) => {\n const layout = board.layout.cells[id];\n board.layout.cells[id] = { ...layout, ...position };\n },\n [board],\n );\n\n return (\n <Board.Root ref={controller} layout={board.layout} onAdd={handleAdd} onDelete={handleDelete} onMove={handleMove}>\n <StackItem.Content toolbar classNames='overflow-hidden'>\n <Board.Toolbar />\n <Board.Container>\n <Board.Viewport classNames='border-none'>\n <Board.Backdrop />\n <Board.Content>\n {items?.map((item, index) => (\n <Board.Cell item={item} key={index} layout={board.layout?.cells[item.id] ?? { x: 0, y: 0 }}>\n <Surface role='card--extrinsic' data={{ subject: item }} limit={1} />\n </Board.Cell>\n ))}\n </Board.Content>\n </Board.Viewport>\n </Board.Container>\n </StackItem.Content>\n </Board.Root>\n );\n};\n"],
5
- "mappings": ";;AAIA,OAAOA,SAASC,aAAaC,cAAc;AAE3C,SAASC,SAASC,cAAcC,2BAA2B;AAC3D,SAASC,gBAAgB;AACzB,SAAmBC,WAAW;AAC9B,SAASC,iBAAiB;AAC1B,SAASC,mBAAmB;AAC5B,SAASC,sBAAsB;AAC/B,SAASC,aAAwD;AACjE,SAASC,iBAAiB;AAC1B,SAASC,qBAAqB;;AASvB,IAAMC,iBAAiB,CAAC,EAAEC,MAAK,MAAuB;;;AAC3D,UAAM,EAAEC,iBAAiBC,SAAQ,IAAKZ,oBAAAA;AACtC,UAAMa,aAAahB,OAAwB,IAAA;AAC3C,UAAMiB,QAAQT,eAAe,MAAMK,MAAMI,MAAMC,IAAI,CAACC,QAAQA,IAAIC,MAAM,EAAEC,OAAOV,aAAAA,GAAgB;MAACE;KAAM;AAEtG,UAAMS,YAAYvB,YAChB,OAAOwB,WAAW;MAAEC,GAAG;MAAGC,GAAG;IAAE,MAAC;AAC9B,YAAMC,QAAQtB,SAASS,KAAAA;AACvBP,gBAAUoB,OAAAA,QAAAA;;;;;;;;;AACV,YAAMX,SACJb,aAAaK,YAAYoB,kBAAkB;QACzCP,QAAQM;QACRE,WAAW;QACXC,gBAAgB,CAACC,WAAAA;AACfjB,gBAAMI,MAAMc,KAAK1B,IAAI2B,KAAKF,MAAAA,CAAAA;AAC1BG,kBAAQC,IAAIrB,MAAMI,MAAMkB,MAAM;AAC9BtB,gBAAMuB,OAAOC,MAAMP,OAAOQ,EAAE,IAAI;YAAE,GAAGf;YAAUgB,OAAO;YAAGC,QAAQ;UAAE;AACnExB,qBAAWyB,SAASC,OAAOnB,QAAAA;QAC7B;MACF,CAAA,CAAA;IAEJ,GACA;MAACV;MAAOG;MAAYD;KAAS;AAI/B,UAAM4B,eAAe5C,YACnB,CAACuC,OAAAA;AAEC,YAAMM,MAAM/B,MAAMI,MAAM4B,UAAU,CAAC1B,QAAQA,IAAI2B,IAAIC,UAAS,GAAIC,WAAWV,EAAAA;AAC3E,UAAIM,QAAQ,IAAI;AACd/B,cAAMI,MAAMgC,OAAOL,KAAK,CAAA;MAC1B;AACA,aAAO/B,MAAMuB,OAAOC,MAAMC,EAAAA;IAC5B,GACA;MAACzB;KAAM;AAGT,UAAMqC,aAAanD,YACjB,CAACuC,IAAIf,aAAAA;AACH,YAAMa,SAASvB,MAAMuB,OAAOC,MAAMC,EAAAA;AAClCzB,YAAMuB,OAAOC,MAAMC,EAAAA,IAAM;QAAE,GAAGF;QAAQ,GAAGb;MAAS;IACpD,GACA;MAACV;KAAM;AAGT,WACE,sBAAA,cAACJ,MAAM0C,MAAI;MAAChC,KAAKH;MAAYoB,QAAQvB,MAAMuB;MAAQgB,OAAO9B;MAAW+B,UAAUV;MAAcW,QAAQJ;OACnG,sBAAA,cAACxC,UAAU6C,SAAO;MAACC,SAAAA;MAAQC,YAAW;OACpC,sBAAA,cAAChD,MAAMiD,SAAO,IAAA,GACd,sBAAA,cAACjD,MAAMkD,WAAS,MACd,sBAAA,cAAClD,MAAMmD,UAAQ;MAACH,YAAW;OACzB,sBAAA,cAAChD,MAAMoD,UAAQ,IAAA,GACf,sBAAA,cAACpD,MAAM8C,SAAO,MACXtC,OAAOC,IAAI,CAAC4C,MAAMC,UACjB,sBAAA,cAACtD,MAAMuD,MAAI;MAACF;MAAYG,KAAKF;MAAO3B,QAAQvB,MAAMuB,QAAQC,MAAMyB,KAAKxB,EAAE,KAAK;QAAEd,GAAG;QAAGC,GAAG;MAAE;OACvF,sBAAA,cAACxB,SAAAA;MAAQiE,MAAK;MAAkBC,MAAM;QAAEC,SAASN;MAAK;MAAGO,OAAO;;;;;AASlF;",
6
- "names": ["React", "useCallback", "useRef", "Surface", "createIntent", "useIntentDispatcher", "getSpace", "Ref", "invariant", "SpaceAction", "useSignalsMemo", "Board", "StackItem", "isNonNullable", "BoardContainer", "board", "dispatchPromise", "dispatch", "controller", "items", "map", "ref", "target", "filter", "handleAdd", "position", "x", "y", "space", "OpenCreateObject", "navigable", "onCreateObject", "object", "push", "make", "console", "log", "length", "layout", "cells", "id", "width", "height", "current", "center", "handleDelete", "idx", "findIndex", "dxn", "asEchoDXN", "echoId", "splice", "handleMove", "Root", "onAdd", "onDelete", "onMove", "Content", "toolbar", "classNames", "Toolbar", "Container", "Viewport", "Backdrop", "item", "index", "Cell", "key", "role", "data", "subject", "limit"]
7
- }