@dxos/plugin-masonry 0.8.4-main.ae835ea → 0.8.4-main.bc674ce

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 (71) hide show
  1. package/dist/lib/browser/chunk-S5JKAK4O.mjs +78 -0
  2. package/dist/lib/browser/chunk-S5JKAK4O.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-U46AGJ2D.mjs +19 -0
  4. package/dist/lib/browser/chunk-U46AGJ2D.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +45 -58
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/react-surface-UCYEF4QU.mjs +94 -0
  9. package/dist/lib/browser/react-surface-UCYEF4QU.mjs.map +7 -0
  10. package/dist/lib/browser/types/index.mjs +9 -0
  11. package/dist/lib/browser/types/index.mjs.map +7 -0
  12. package/dist/lib/node-esm/chunk-P6EZJITS.mjs +21 -0
  13. package/dist/lib/node-esm/chunk-P6EZJITS.mjs.map +7 -0
  14. package/dist/lib/node-esm/chunk-YNA44I6R.mjs +79 -0
  15. package/dist/lib/node-esm/chunk-YNA44I6R.mjs.map +7 -0
  16. package/dist/lib/node-esm/index.mjs +45 -58
  17. package/dist/lib/node-esm/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/react-surface-LG7FTGYA.mjs +95 -0
  20. package/dist/lib/node-esm/react-surface-LG7FTGYA.mjs.map +7 -0
  21. package/dist/lib/node-esm/types/index.mjs +10 -0
  22. package/dist/lib/node-esm/types/index.mjs.map +7 -0
  23. package/dist/types/src/MasonryPlugin.d.ts +2 -1
  24. package/dist/types/src/MasonryPlugin.d.ts.map +1 -1
  25. package/dist/types/src/capabilities/index.d.ts +1 -2
  26. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  27. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  28. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  29. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  30. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  31. package/dist/types/src/components/MasonryContainer.d.ts +9 -4
  32. package/dist/types/src/components/MasonryContainer.d.ts.map +1 -1
  33. package/dist/types/src/components/MasonryContainer.stories.d.ts.map +1 -1
  34. package/dist/types/src/meta.d.ts +2 -2
  35. package/dist/types/src/meta.d.ts.map +1 -1
  36. package/dist/types/src/translations.d.ts +14 -5
  37. package/dist/types/src/translations.d.ts.map +1 -1
  38. package/dist/types/src/types/Masonry.d.ts +22 -21
  39. package/dist/types/src/types/Masonry.d.ts.map +1 -1
  40. package/dist/types/src/types/MasonryAction.d.ts +0 -17
  41. package/dist/types/src/types/MasonryAction.d.ts.map +1 -1
  42. package/dist/types/tsconfig.tsbuildinfo +1 -1
  43. package/package.json +50 -32
  44. package/src/MasonryPlugin.tsx +27 -52
  45. package/src/capabilities/index.ts +1 -4
  46. package/src/capabilities/react-surface/index.ts +7 -0
  47. package/src/capabilities/react-surface/react-surface.tsx +31 -0
  48. package/src/components/MasonryContainer.stories.tsx +29 -34
  49. package/src/components/MasonryContainer.tsx +44 -34
  50. package/src/meta.ts +2 -2
  51. package/src/translations.ts +5 -1
  52. package/src/types/Masonry.ts +38 -27
  53. package/src/types/MasonryAction.ts +9 -17
  54. package/dist/lib/browser/chunk-RVOTJON5.mjs +0 -92
  55. package/dist/lib/browser/chunk-RVOTJON5.mjs.map +0 -7
  56. package/dist/lib/browser/intent-resolver-WM3U563P.mjs +0 -31
  57. package/dist/lib/browser/intent-resolver-WM3U563P.mjs.map +0 -7
  58. package/dist/lib/browser/react-surface-Z7W24EZP.mjs +0 -112
  59. package/dist/lib/browser/react-surface-Z7W24EZP.mjs.map +0 -7
  60. package/dist/lib/node-esm/chunk-KTVJZX5B.mjs +0 -93
  61. package/dist/lib/node-esm/chunk-KTVJZX5B.mjs.map +0 -7
  62. package/dist/lib/node-esm/intent-resolver-YKIFA4JI.mjs +0 -32
  63. package/dist/lib/node-esm/intent-resolver-YKIFA4JI.mjs.map +0 -7
  64. package/dist/lib/node-esm/react-surface-BSDKYPZH.mjs +0 -113
  65. package/dist/lib/node-esm/react-surface-BSDKYPZH.mjs.map +0 -7
  66. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  67. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  68. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  69. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  70. package/src/capabilities/intent-resolver.ts +0 -25
  71. package/src/capabilities/react-surface.tsx +0 -25
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@dxos/plugin-masonry",
3
- "version": "0.8.4-main.ae835ea",
3
+ "version": "0.8.4-main.bc674ce",
4
4
  "description": "Masonry DXOS Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
7
11
  "license": "MIT",
8
12
  "author": "DXOS.org",
9
13
  "sideEffects": true,
@@ -14,50 +18,64 @@
14
18
  "types": "./dist/types/src/index.d.ts",
15
19
  "browser": "./dist/lib/browser/index.mjs",
16
20
  "node": "./dist/lib/node-esm/index.mjs"
21
+ },
22
+ "./types": {
23
+ "source": "./src/types/index.ts",
24
+ "types": "./dist/types/src/types/index.d.ts",
25
+ "browser": "./dist/lib/browser/types/index.mjs",
26
+ "node": "./dist/lib/node-esm/types/index.mjs"
17
27
  }
18
28
  },
19
29
  "types": "dist/types/src/index.d.ts",
30
+ "typesVersions": {
31
+ "*": {
32
+ "types": [
33
+ "dist/types/src/types/index.d.ts"
34
+ ]
35
+ }
36
+ },
20
37
  "files": [
21
38
  "dist",
22
39
  "src"
23
40
  ],
24
41
  "dependencies": {
25
- "@preact-signals/safe-react": "^0.9.0",
26
- "@preact/signals-core": "^1.12.1",
27
- "@preact/signals-react": "^3.3.0",
28
- "@dxos/echo": "0.8.4-main.ae835ea",
29
- "@dxos/plugin-client": "0.8.4-main.ae835ea",
30
- "@dxos/app-framework": "0.8.4-main.ae835ea",
31
- "@dxos/effect": "0.8.4-main.ae835ea",
32
- "@dxos/plugin-search": "0.8.4-main.ae835ea",
33
- "@dxos/react-ui": "0.8.4-main.ae835ea",
34
- "@dxos/plugin-space": "0.8.4-main.ae835ea",
35
- "@dxos/react-ui-form": "0.8.4-main.ae835ea",
36
- "@dxos/react-ui-stack": "0.8.4-main.ae835ea",
37
- "@dxos/schema": "0.8.4-main.ae835ea",
38
- "@dxos/react-ui-masonry": "0.8.4-main.ae835ea",
39
- "@dxos/util": "0.8.4-main.ae835ea",
40
- "@dxos/react-client": "0.8.4-main.ae835ea"
42
+ "@dxos/app-framework": "0.8.4-main.bc674ce",
43
+ "@dxos/effect": "0.8.4-main.bc674ce",
44
+ "@dxos/echo": "0.8.4-main.bc674ce",
45
+ "@dxos/operation": "0.8.4-main.bc674ce",
46
+ "@dxos/plugin-client": "0.8.4-main.bc674ce",
47
+ "@dxos/plugin-search": "0.8.4-main.bc674ce",
48
+ "@dxos/plugin-space": "0.8.4-main.bc674ce",
49
+ "@dxos/react-client": "0.8.4-main.bc674ce",
50
+ "@dxos/react-ui-form": "0.8.4-main.bc674ce",
51
+ "@dxos/react-ui-masonry": "0.8.4-main.bc674ce",
52
+ "@dxos/react-ui-stack": "0.8.4-main.bc674ce",
53
+ "@dxos/schema": "0.8.4-main.bc674ce",
54
+ "@dxos/react-ui": "0.8.4-main.bc674ce",
55
+ "@dxos/react-ui-mosaic": "0.8.4-main.bc674ce",
56
+ "@dxos/types": "0.8.4-main.bc674ce",
57
+ "@dxos/util": "0.8.4-main.bc674ce"
41
58
  },
42
59
  "devDependencies": {
43
- "@types/react": "~19.2.2",
44
- "@types/react-dom": "~19.2.2",
45
- "effect": "3.18.3",
46
- "react": "~19.2.0",
47
- "react-dom": "~19.2.0",
60
+ "@types/react": "~19.2.7",
61
+ "@types/react-dom": "~19.2.3",
62
+ "effect": "3.19.11",
63
+ "react": "~19.2.3",
64
+ "react-dom": "~19.2.3",
48
65
  "vite": "7.1.9",
49
- "@dxos/plugin-preview": "0.8.4-main.ae835ea",
50
- "@dxos/random": "0.8.4-main.ae835ea",
51
- "@dxos/plugin-theme": "0.8.4-main.ae835ea",
52
- "@dxos/storybook-utils": "0.8.4-main.ae835ea",
53
- "@dxos/react-ui-theme": "0.8.4-main.ae835ea"
66
+ "@dxos/plugin-testing": "0.8.4-main.bc674ce",
67
+ "@dxos/plugin-theme": "0.8.4-main.bc674ce",
68
+ "@dxos/plugin-preview": "0.8.4-main.bc674ce",
69
+ "@dxos/ui-theme": "0.8.4-main.bc674ce",
70
+ "@dxos/random": "0.8.4-main.bc674ce",
71
+ "@dxos/storybook-utils": "0.8.4-main.bc674ce"
54
72
  },
55
73
  "peerDependencies": {
56
- "effect": "^3.13.3",
57
- "react": "^19.0.0",
58
- "react-dom": "^19.0.0",
59
- "@dxos/react-ui": "0.8.4-main.ae835ea",
60
- "@dxos/react-ui-theme": "0.8.4-main.ae835ea"
74
+ "effect": "3.19.11",
75
+ "react": "~19.2.3",
76
+ "react-dom": "~19.2.3",
77
+ "@dxos/react-ui": "0.8.4-main.bc674ce",
78
+ "@dxos/ui-theme": "0.8.4-main.bc674ce"
61
79
  },
62
80
  "publishConfig": {
63
81
  "access": "public"
@@ -2,61 +2,36 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
6
- import { ClientEvents } from '@dxos/plugin-client';
7
- import { SpaceCapabilities } from '@dxos/plugin-space';
8
- import { defineObjectForm } from '@dxos/plugin-space/types';
5
+ import * as Effect from 'effect/Effect';
9
6
 
10
- import { IntentResolver, ReactSurface } from './capabilities';
7
+ import { Common, Plugin } from '@dxos/app-framework';
8
+ import { Type } from '@dxos/echo';
9
+ import { type CreateObject } from '@dxos/plugin-space/types';
10
+ import { View } from '@dxos/schema';
11
+
12
+ import { ReactSurface } from './capabilities';
11
13
  import { meta } from './meta';
12
14
  import { translations } from './translations';
13
15
  import { Masonry, MasonryAction } from './types';
14
16
 
15
- export const MasonryPlugin = definePlugin(meta, () => [
16
- defineModule({
17
- id: `${meta.id}/module/translations`,
18
- activatesOn: Events.SetupTranslations,
19
- activate: () => contributes(Capabilities.Translations, translations),
20
- }),
21
- defineModule({
22
- id: `${meta.id}/module/react-surface`,
23
- activatesOn: Events.SetupReactSurface,
24
- activate: ReactSurface,
25
- }),
26
- defineModule({
27
- id: `${meta.id}/module/metadata`,
28
- activatesOn: Events.SetupMetadata,
29
- activate: () =>
30
- contributes(Capabilities.Metadata, {
31
- id: Masonry.Masonry.typename,
32
- metadata: {
33
- icon: 'ph--wall--regular',
34
- iconHue: 'green',
35
- },
36
- }),
37
- }),
38
- defineModule({
39
- id: `${meta.id}/module/object-form`,
40
- activatesOn: ClientEvents.SetupSchema,
41
- activate: () =>
42
- contributes(
43
- SpaceCapabilities.ObjectForm,
44
- defineObjectForm({
45
- objectSchema: Masonry.Masonry,
46
- formSchema: MasonryAction.MasonryProps,
47
- hidden: true,
48
- getIntent: (props, options) => createIntent(MasonryAction.CreateMasonry, { ...props, space: options.space }),
49
- }),
50
- ),
51
- }),
52
- defineModule({
53
- id: `${meta.id}/module/react-surface`,
54
- activatesOn: Events.SetupReactSurface,
55
- activate: ReactSurface,
56
- }),
57
- defineModule({
58
- id: `${meta.id}/module/intent-resolver`,
59
- activatesOn: Events.SetupIntentResolver,
60
- activate: IntentResolver,
17
+ export const MasonryPlugin = Plugin.define(meta).pipe(
18
+ Common.Plugin.addTranslationsModule({ translations }),
19
+ Common.Plugin.addSurfaceModule({ activate: ReactSurface }),
20
+ Common.Plugin.addMetadataModule({
21
+ metadata: {
22
+ id: Type.getTypename(Masonry.Masonry),
23
+ metadata: {
24
+ icon: 'ph--wall--regular',
25
+ iconHue: 'green',
26
+ inputSchema: MasonryAction.MasonryProps,
27
+ createObject: ((props, { db }) =>
28
+ Effect.promise(async () => {
29
+ const { view } = await View.makeFromDatabase({ db, typename: props.typename });
30
+ return Masonry.make({ name: props.name, view });
31
+ })) satisfies CreateObject,
32
+ },
33
+ },
61
34
  }),
62
- ]);
35
+ Common.Plugin.addSchemaModule({ schema: [Masonry.Masonry] }),
36
+ Plugin.make,
37
+ );
@@ -2,7 +2,4 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { lazy } from '@dxos/app-framework';
6
-
7
- export const ReactSurface = lazy(() => import('./react-surface'));
8
- export const IntentResolver = lazy(() => import('./intent-resolver'));
5
+ export * from './react-surface';
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+
7
+ export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
@@ -0,0 +1,31 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import React from 'react';
7
+
8
+ import { Capability, Common } from '@dxos/app-framework';
9
+ import { Obj } from '@dxos/echo';
10
+ import { View } from '@dxos/schema';
11
+
12
+ import { MasonryContainer } from '../../components/MasonryContainer';
13
+ import { meta } from '../../meta';
14
+ import { Masonry } from '../../types';
15
+
16
+ export default Capability.makeModule(() =>
17
+ Effect.succeed(
18
+ Capability.contributes(Common.Capability.ReactSurface, [
19
+ Common.createSurface({
20
+ id: meta.id,
21
+ role: ['article', 'section'],
22
+ filter: (data): data is { subject: Masonry.Masonry | View.View } =>
23
+ Obj.instanceOf(Masonry.Masonry, data.subject) || Obj.instanceOf(View.View, data.subject),
24
+ component: ({ data, role }) => {
25
+ const view = Obj.instanceOf(View.View, data.subject) ? data.subject : data.subject.view;
26
+ return <MasonryContainer view={view} role={role} />;
27
+ },
28
+ }),
29
+ ]),
30
+ ),
31
+ );
@@ -3,21 +3,19 @@
3
3
  //
4
4
 
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React, { useEffect, useState } from 'react';
6
+ import * as Effect from 'effect/Effect';
7
+ import React from 'react';
7
8
 
8
- import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
9
9
  import { withPluginManager } from '@dxos/app-framework/testing';
10
10
  import { ClientPlugin } from '@dxos/plugin-client';
11
11
  import { PreviewPlugin } from '@dxos/plugin-preview';
12
- import { SpacePlugin } from '@dxos/plugin-space';
13
- import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
14
- import { ThemePlugin } from '@dxos/plugin-theme';
12
+ import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
15
13
  import { faker } from '@dxos/random';
16
- import { Filter, useQuery, useSpaces } from '@dxos/react-client/echo';
14
+ import { Filter, useObject, useQuery, useSpaces } from '@dxos/react-client/echo';
17
15
  import { withTheme } from '@dxos/react-ui/testing';
18
- import { defaultTx } from '@dxos/react-ui-theme';
19
- import { DataType } from '@dxos/schema';
16
+ import { View } from '@dxos/schema';
20
17
  import { createObjectFactory } from '@dxos/schema/testing';
18
+ import { Organization } from '@dxos/types';
21
19
 
22
20
  import { Masonry } from '../types';
23
21
 
@@ -28,16 +26,10 @@ faker.seed(0);
28
26
  const StorybookMasonry = () => {
29
27
  const spaces = useSpaces();
30
28
  const space = spaces[spaces.length - 1];
31
- const views = useQuery(space, Filter.type(DataType.View));
32
- const [view, setView] = useState<DataType.View>();
33
- useEffect(() => {
34
- if (views.length && !view) {
35
- const view = views[0];
36
- setView(view);
37
- }
38
- }, [views]);
29
+ const masonries = useQuery(space?.db, Filter.type(Masonry.Masonry));
30
+ const [masonry] = useObject(masonries.at(0));
39
31
 
40
- return view ? <MasonryContainer view={view} role='story' /> : null;
32
+ return masonry ? <MasonryContainer view={masonry.view} role='story' /> : null;
41
33
  };
42
34
 
43
35
  const meta = {
@@ -48,26 +40,29 @@ const meta = {
48
40
  withTheme,
49
41
  withPluginManager({
50
42
  plugins: [
43
+ ...corePlugins(),
44
+ StorybookPlugin({}),
51
45
  ClientPlugin({
52
- types: [DataType.Organization, DataType.View, Masonry.Masonry],
53
- onClientInitialized: async ({ client }) => {
54
- await client.halo.createIdentity();
55
- const space = await client.spaces.create();
56
- await space.waitUntilReady();
57
-
58
- const { view } = await Masonry.makeView({ space, client, typename: DataType.Organization.typename });
59
- space.db.add(view);
60
-
61
- const factory = createObjectFactory(space.db, faker as any);
62
- await factory([{ type: DataType.Organization, count: 64 }]);
63
- },
46
+ types: [Organization.Organization, View.View, Masonry.Masonry],
47
+ onClientInitialized: ({ client }) =>
48
+ Effect.gen(function* () {
49
+ yield* Effect.promise(() => client.halo.createIdentity());
50
+ const space = yield* Effect.promise(() => client.spaces.create());
51
+ yield* Effect.promise(() => space.waitUntilReady());
52
+ const { view } = yield* Effect.promise(() =>
53
+ View.makeFromDatabase({
54
+ db: space.db,
55
+ typename: Organization.Organization.typename,
56
+ }),
57
+ );
58
+ const masonry = Masonry.make({ view });
59
+ space.db.add(masonry);
60
+ const factory = createObjectFactory(space.db, faker as any);
61
+ yield* Effect.promise(() => factory([{ type: Organization.Organization, count: 64 }]));
62
+ }),
64
63
  }),
65
- SpacePlugin({}),
66
- IntentPlugin(),
67
- SettingsPlugin(),
68
- ThemePlugin({ tx: defaultTx }),
64
+
69
65
  PreviewPlugin(),
70
- StorybookLayoutPlugin({}),
71
66
  ],
72
67
  }),
73
68
  ],
@@ -2,41 +2,44 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, { useEffect, useMemo, useState } from 'react';
5
+ import type * as Schema from 'effect/Schema';
6
+ import React, { useEffect, useState } from 'react';
6
7
 
7
- import { Surface } from '@dxos/app-framework';
8
- import { Filter, Type } from '@dxos/echo';
9
- import { EchoSchema, type TypedObject } from '@dxos/echo/internal';
8
+ import { Common } from '@dxos/app-framework';
9
+ import { Surface, useCapabilities } from '@dxos/app-framework/react';
10
+ import { Filter, Obj, type Ref, Type } from '@dxos/echo';
10
11
  import { useGlobalFilteredObjects } from '@dxos/plugin-search';
11
- import { useClient } from '@dxos/react-client';
12
- import { getSpace, useQuery } from '@dxos/react-client/echo';
13
- import { Masonry } from '@dxos/react-ui-masonry';
14
- import { type DataType, ProjectionModel, getTypenameFromQuery } from '@dxos/schema';
12
+ import { useObject, useQuery } from '@dxos/react-client/echo';
13
+ import { Masonry as MasonryComponent } from '@dxos/react-ui-masonry';
14
+ import { Card } from '@dxos/react-ui-mosaic';
15
+ import { type View, getTypenameFromQuery } from '@dxos/schema';
15
16
 
16
- const Item = ({ data }: { data: any }) => {
17
- return <Surface role='card' limit={1} data={{ subject: data }} />;
17
+ export type MasonryContainerProps = {
18
+ view: View.View;
19
+ role?: string;
18
20
  };
19
21
 
20
- export const MasonryContainer = ({ view, role }: { view: DataType.View; role: string }) => {
21
- const client = useClient();
22
- const space = getSpace(view);
23
- const typename = view.query ? getTypenameFromQuery(view.query.ast) : undefined;
24
-
25
- const [cardSchema, setCardSchema] = useState<TypedObject<any, any>>();
26
- const [projection, setProjection] = useState<ProjectionModel>();
22
+ export const MasonryContainer = ({
23
+ view: viewOrRef,
24
+ role,
25
+ }: {
26
+ view: View.View | Ref.Ref<View.View>;
27
+ role?: string;
28
+ }) => {
29
+ const [view] = useObject(viewOrRef);
30
+ const schemas = useCapabilities(Common.Capability.Schema);
31
+ const db = view && Obj.getDatabase(view);
32
+ const typename = view?.query ? getTypenameFromQuery(view.query.ast) : undefined;
27
33
 
28
- const jsonSchema = useMemo(() => {
29
- if (!cardSchema) return undefined;
30
- return cardSchema instanceof EchoSchema ? cardSchema.jsonSchema : Type.toJsonSchema(cardSchema);
31
- }, [cardSchema]);
34
+ const [cardSchema, setCardSchema] = useState<Schema.Schema.AnyNoContext>();
32
35
 
33
36
  useEffect(() => {
34
- const staticSchema = client.graph.schemaRegistry.schemas.find((schema) => Type.getTypename(schema) === typename);
37
+ const staticSchema = schemas.flat().find((schema) => Type.getTypename(schema) === typename);
35
38
  if (staticSchema) {
36
- setCardSchema(() => staticSchema as TypedObject<any, any>);
39
+ setCardSchema(() => staticSchema);
37
40
  }
38
- if (!staticSchema && typename && space) {
39
- const query = space.db.schemaRegistry.query({ typename });
41
+ if (!staticSchema && typename && db) {
42
+ const query = db.schemaRegistry.query({ typename });
40
43
  const unsubscribe = query.subscribe(
41
44
  () => {
42
45
  const [schema] = query.results;
@@ -48,22 +51,29 @@ export const MasonryContainer = ({ view, role }: { view: DataType.View; role: st
48
51
  );
49
52
  return unsubscribe;
50
53
  }
51
- }, [typename, space]);
52
-
53
- useEffect(() => {
54
- if (jsonSchema) {
55
- setProjection(new ProjectionModel(jsonSchema, view.projection));
56
- }
57
- }, [view.projection, JSON.stringify(jsonSchema)]);
54
+ }, [schemas, typename, db]);
58
55
 
59
- const objects = useQuery(space, cardSchema ? Filter.type(cardSchema) : Filter.nothing());
56
+ const objects = useQuery(db, cardSchema ? Filter.type(cardSchema) : Filter.nothing());
60
57
  const filteredObjects = useGlobalFilteredObjects(objects);
61
58
 
62
59
  return (
63
- <Masonry.Root
60
+ <MasonryComponent.Root
64
61
  items={filteredObjects}
65
62
  render={Item as any}
66
63
  classNames='is-full max-is-full bs-full max-bs-full overflow-y-auto p-4'
67
64
  />
68
65
  );
69
66
  };
67
+
68
+ const Item = ({ data }: { data: any }) => {
69
+ return (
70
+ <Card.Root>
71
+ <Card.Toolbar>
72
+ <span />
73
+ <Card.Title>{Obj.getLabel(data)}</Card.Title>
74
+ <Card.Menu />
75
+ </Card.Toolbar>
76
+ <Surface role='card--content' limit={1} data={{ subject: data }} />
77
+ </Card.Root>
78
+ );
79
+ };
package/src/meta.ts CHANGED
@@ -2,10 +2,10 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type PluginMeta } from '@dxos/app-framework';
5
+ import { type Plugin } from '@dxos/app-framework';
6
6
  import { trim } from '@dxos/util';
7
7
 
8
- export const meta: PluginMeta = {
8
+ export const meta: Plugin.Meta = {
9
9
  id: 'dxos.org/plugin/masonry',
10
10
  name: 'Masonry',
11
11
  description: trim`
@@ -2,6 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { Type } from '@dxos/echo';
5
6
  import { type Resource } from '@dxos/react-ui';
6
7
 
7
8
  import { meta } from './meta';
@@ -10,12 +11,15 @@ import { Masonry } from './types';
10
11
  export const translations = [
11
12
  {
12
13
  'en-US': {
13
- [Masonry.Masonry.typename]: {
14
+ [Type.getTypename(Masonry.Masonry)]: {
14
15
  'typename label': 'Masonry',
15
16
  'typename label_zero': 'Masonries',
16
17
  'typename label_one': 'Masonry',
17
18
  'typename label_other': 'Masonries',
18
19
  'object name placeholder': 'New masonry',
20
+ 'rename object label': 'Rename masonry',
21
+ 'delete object label': 'Delete masonry',
22
+ 'object deleted label': 'Masonry deleted',
19
23
  },
20
24
  [meta.id]: {
21
25
  'plugin name': 'Masonry',
@@ -4,47 +4,58 @@
4
4
 
5
5
  import * as Schema from 'effect/Schema';
6
6
 
7
- import { Obj, Type } from '@dxos/echo';
8
- import { type JsonSchemaType, ViewAnnotation, toEffectSchema } from '@dxos/echo/internal';
9
- import { type CreateViewFromSpaceProps, type DataType, createViewFromSpace } from '@dxos/schema';
7
+ import { Obj, Ref, Type } from '@dxos/echo';
8
+ import { FormInputAnnotation, LabelAnnotation } from '@dxos/echo/internal';
9
+ import { View, ViewAnnotation } from '@dxos/schema';
10
10
 
11
11
  export const Masonry = Schema.Struct({
12
+ name: Schema.String.pipe(Schema.optional),
13
+
14
+ view: Type.Ref(View.View).pipe(FormInputAnnotation.set(false)),
15
+
12
16
  arrangement: Schema.Array(
13
17
  Schema.Struct({
14
- ids: Schema.Array(Type.ObjectId),
18
+ ids: Schema.Array(Obj.ID),
15
19
  hidden: Schema.optional(Schema.Boolean),
16
- }).pipe(Schema.mutable),
17
- ).pipe(Schema.mutable, Schema.optional),
20
+ }),
21
+ ).pipe(FormInputAnnotation.set(false), Schema.optional),
18
22
  // TODO(wittjosiah): Consider Masonry supporting not being just a view but referencing arbitrary data directly.
19
23
  }).pipe(
20
- Type.Obj({
24
+ Type.object({
21
25
  typename: 'dxos.org/type/Masonry',
22
- version: '0.1.0',
26
+ version: '0.2.0',
23
27
  }),
28
+ LabelAnnotation.set(['name']),
24
29
  ViewAnnotation.set(true),
25
30
  );
26
31
 
27
- export type Masonry = Schema.Schema.Type<typeof Masonry>;
32
+ export interface Masonry extends Schema.Schema.Type<typeof Masonry> {}
33
+
34
+ type MakeProps = Omit<Partial<Obj.MakeProps<typeof Masonry>>, 'view'> & {
35
+ view: View.View;
36
+ };
28
37
 
29
38
  /**
30
- * Make a masonry object.
39
+ * Make a masonry as a view of a data set.
31
40
  */
32
- export const make = (props: Obj.MakeProps<typeof Masonry> = {}) => Obj.make(Masonry, props);
33
-
34
- export type MakeViewProps = Omit<CreateViewFromSpaceProps, 'presentation'>;
35
-
36
- export const makeView = async ({
37
- ...props
38
- }: MakeViewProps): Promise<{
39
- jsonSchema: JsonSchemaType;
40
- view: DataType.View;
41
- schema: ReturnType<typeof toEffectSchema>;
42
- }> => {
43
- const masonry = Obj.make(Masonry, {});
44
- const { jsonSchema, view } = await createViewFromSpace({ ...props, presentation: masonry });
41
+ export const make = ({ name, arrangement = [], view }: MakeProps): Masonry => {
42
+ return Obj.make(Masonry, { name, view: Ref.make(view), arrangement });
43
+ };
45
44
 
46
- // Preset sizes.
47
- const schema = toEffectSchema(jsonSchema);
45
+ //
46
+ // V1
47
+ //
48
48
 
49
- return { jsonSchema, schema, view };
50
- };
49
+ export const MasonryV1 = Schema.Struct({
50
+ arrangement: Schema.Array(
51
+ Schema.Struct({
52
+ ids: Schema.Array(Obj.ID),
53
+ hidden: Schema.optional(Schema.Boolean),
54
+ }),
55
+ ).pipe(Schema.optional),
56
+ }).pipe(
57
+ Type.object({
58
+ typename: 'dxos.org/type/Masonry',
59
+ version: '0.1.0',
60
+ }),
61
+ );
@@ -4,26 +4,18 @@
4
4
 
5
5
  import * as Schema from 'effect/Schema';
6
6
 
7
- import { SpaceSchema } from '@dxos/react-client/echo';
8
- import { DataType, TypenameAnnotationId } from '@dxos/schema';
9
-
10
- import { meta } from '../meta';
11
-
12
- const MASONRY_ACTION = `${meta.id}/action`;
7
+ import { TypeInputOptionsAnnotation } from '@dxos/plugin-space/types';
13
8
 
14
9
  export const MasonryProps = Schema.Struct({
15
10
  name: Schema.optional(Schema.String),
16
- typename: Schema.optional(
17
- Schema.String.annotations({
18
- [TypenameAnnotationId]: ['used-static', 'dynamic'],
19
- title: 'Select card record type (leave empty to start fresh)',
11
+ // TODO(wittjosiah): This should be a query input instead.
12
+ typename: Schema.String.pipe(
13
+ Schema.annotations({ title: 'Select card type' }),
14
+ TypeInputOptionsAnnotation.set({
15
+ location: ['database', 'runtime'],
16
+ kind: ['user'],
17
+ registered: ['registered'],
20
18
  }),
19
+ Schema.optional,
21
20
  ),
22
21
  });
23
-
24
- export class CreateMasonry extends Schema.TaggedClass<CreateMasonry>()(`${MASONRY_ACTION}/create`, {
25
- input: Schema.extend(Schema.Struct({ space: SpaceSchema }), MasonryProps),
26
- output: Schema.Struct({
27
- object: DataType.View,
28
- }),
29
- }) {}