@dxos/plugin-preview 0.8.4-main.422d1c7879 → 0.8.4-main.51f1e5ca51

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 (39) hide show
  1. package/dist/lib/browser/index.mjs +2 -21
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/translations.mjs +21 -0
  5. package/dist/lib/browser/translations.mjs.map +7 -0
  6. package/dist/lib/node-esm/index.mjs +2 -21
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/lib/node-esm/translations.mjs +23 -0
  10. package/dist/lib/node-esm/translations.mjs.map +7 -0
  11. package/dist/types/src/PreviewPlugin.d.ts.map +1 -1
  12. package/dist/types/src/capabilities/preview-popover.d.ts.map +1 -1
  13. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  14. package/dist/types/src/cards/ExpandoCard.d.ts +4 -0
  15. package/dist/types/src/cards/ExpandoCard.d.ts.map +1 -0
  16. package/dist/types/src/cards/FormCard.d.ts.map +1 -1
  17. package/dist/types/src/cards/JsonCard.d.ts.map +1 -1
  18. package/dist/types/src/cards/OrganizationCard.d.ts.map +1 -1
  19. package/dist/types/src/cards/PersonCard.d.ts.map +1 -1
  20. package/dist/types/src/cards/ProjectCard.d.ts.map +1 -1
  21. package/dist/types/src/cards/TaskCard.d.ts.map +1 -1
  22. package/dist/types/src/cards/index.d.ts +1 -0
  23. package/dist/types/src/cards/index.d.ts.map +1 -1
  24. package/dist/types/src/stories/Card.stories.d.ts +10 -8
  25. package/dist/types/src/stories/Card.stories.d.ts.map +1 -1
  26. package/dist/types/src/stories/testing.d.ts +2 -0
  27. package/dist/types/src/stories/testing.d.ts.map +1 -1
  28. package/dist/types/src/translations.d.ts +8 -9
  29. package/dist/types/src/translations.d.ts.map +1 -1
  30. package/dist/types/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +42 -35
  32. package/src/PreviewPlugin.tsx +1 -2
  33. package/src/capabilities/react-surface.tsx +10 -3
  34. package/src/cards/ExpandoCard.tsx +76 -0
  35. package/src/cards/FormCard.tsx +1 -1
  36. package/src/cards/JsonCard.tsx +3 -0
  37. package/src/cards/index.ts +1 -0
  38. package/src/stories/Card.stories.tsx +18 -4
  39. package/src/stories/testing.tsx +10 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-preview",
3
- "version": "0.8.4-main.422d1c7879",
3
+ "version": "0.8.4-main.51f1e5ca51",
4
4
  "description": "Preview plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -14,13 +14,20 @@
14
14
  "type": "module",
15
15
  "imports": {
16
16
  "#capabilities": "./src/capabilities/index.ts",
17
- "#meta": "./src/meta.ts"
17
+ "#meta": "./src/meta.ts",
18
+ "#translations": "./src/translations.ts"
18
19
  },
19
20
  "exports": {
20
21
  ".": {
21
22
  "source": "./src/index.ts",
22
23
  "types": "./dist/types/src/index.d.ts",
23
24
  "browser": "./dist/lib/browser/index.mjs"
25
+ },
26
+ "./translations": {
27
+ "source": "./src/translations.ts",
28
+ "types": "./dist/types/src/translations.d.ts",
29
+ "browser": "./dist/lib/browser/translations.mjs",
30
+ "node": "./dist/lib/node-esm/translations.mjs"
24
31
  }
25
32
  },
26
33
  "types": "dist/types/src/index.d.ts",
@@ -30,44 +37,44 @@
30
37
  ],
31
38
  "dependencies": {
32
39
  "@effect-atom/atom-react": "^0.5.0",
33
- "@dxos/app-framework": "0.8.4-main.422d1c7879",
34
- "@dxos/async": "0.8.4-main.422d1c7879",
35
- "@dxos/app-toolkit": "0.8.4-main.422d1c7879",
36
- "@dxos/client": "0.8.4-main.422d1c7879",
37
- "@dxos/echo": "0.8.4-main.422d1c7879",
38
- "@dxos/lit-ui": "0.8.4-main.422d1c7879",
39
- "@dxos/log": "0.8.4-main.422d1c7879",
40
- "@dxos/effect": "0.8.4-main.422d1c7879",
41
- "@dxos/keys": "0.8.4-main.422d1c7879",
42
- "@dxos/operation": "0.8.4-main.422d1c7879",
43
- "@dxos/plugin-attention": "0.8.4-main.422d1c7879",
44
- "@dxos/plugin-client": "0.8.4-main.422d1c7879",
45
- "@dxos/react-client": "0.8.4-main.422d1c7879",
46
- "@dxos/react-ui": "0.8.4-main.422d1c7879",
47
- "@dxos/react-ui-editor": "0.8.4-main.422d1c7879",
48
- "@dxos/react-ui-form": "0.8.4-main.422d1c7879",
49
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.422d1c7879",
50
- "@dxos/react-ui-table": "0.8.4-main.422d1c7879",
51
- "@dxos/react-ui-mosaic": "0.8.4-main.422d1c7879",
52
- "@dxos/schema": "0.8.4-main.422d1c7879",
53
- "@dxos/types": "0.8.4-main.422d1c7879",
54
- "@dxos/react-ui-menu": "0.8.4-main.422d1c7879",
55
- "@dxos/ui-editor": "0.8.4-main.422d1c7879",
56
- "@dxos/ui-theme": "0.8.4-main.422d1c7879",
57
- "@dxos/util": "0.8.4-main.422d1c7879",
58
- "@dxos/plugin-deck": "0.8.4-main.422d1c7879",
59
- "@dxos/app-graph": "0.8.4-main.422d1c7879"
40
+ "@dxos/app-framework": "0.8.4-main.51f1e5ca51",
41
+ "@dxos/app-toolkit": "0.8.4-main.51f1e5ca51",
42
+ "@dxos/async": "0.8.4-main.51f1e5ca51",
43
+ "@dxos/app-graph": "0.8.4-main.51f1e5ca51",
44
+ "@dxos/echo": "0.8.4-main.51f1e5ca51",
45
+ "@dxos/effect": "0.8.4-main.51f1e5ca51",
46
+ "@dxos/keys": "0.8.4-main.51f1e5ca51",
47
+ "@dxos/log": "0.8.4-main.51f1e5ca51",
48
+ "@dxos/lit-ui": "0.8.4-main.51f1e5ca51",
49
+ "@dxos/operation": "0.8.4-main.51f1e5ca51",
50
+ "@dxos/plugin-attention": "0.8.4-main.51f1e5ca51",
51
+ "@dxos/plugin-client": "0.8.4-main.51f1e5ca51",
52
+ "@dxos/plugin-deck": "0.8.4-main.51f1e5ca51",
53
+ "@dxos/client": "0.8.4-main.51f1e5ca51",
54
+ "@dxos/react-client": "0.8.4-main.51f1e5ca51",
55
+ "@dxos/react-ui": "0.8.4-main.51f1e5ca51",
56
+ "@dxos/react-ui-form": "0.8.4-main.51f1e5ca51",
57
+ "@dxos/react-ui-editor": "0.8.4-main.51f1e5ca51",
58
+ "@dxos/react-ui-menu": "0.8.4-main.51f1e5ca51",
59
+ "@dxos/react-ui-mosaic": "0.8.4-main.51f1e5ca51",
60
+ "@dxos/react-ui-table": "0.8.4-main.51f1e5ca51",
61
+ "@dxos/schema": "0.8.4-main.51f1e5ca51",
62
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.51f1e5ca51",
63
+ "@dxos/types": "0.8.4-main.51f1e5ca51",
64
+ "@dxos/ui-editor": "0.8.4-main.51f1e5ca51",
65
+ "@dxos/ui-theme": "0.8.4-main.51f1e5ca51",
66
+ "@dxos/util": "0.8.4-main.51f1e5ca51"
60
67
  },
61
68
  "devDependencies": {
62
69
  "effect": "3.20.0",
63
70
  "react": "~19.2.3",
64
71
  "react-dom": "~19.2.3",
65
- "vite": "^7.1.11",
66
- "@dxos/echo-db": "0.8.4-main.422d1c7879",
67
- "@dxos/plugin-testing": "0.8.4-main.422d1c7879",
68
- "@dxos/random": "0.8.4-main.422d1c7879",
69
- "@dxos/react-ui-components": "0.8.4-main.422d1c7879",
70
- "@dxos/storybook-utils": "0.8.4-main.422d1c7879"
72
+ "vite": "^8.0.10",
73
+ "@dxos/plugin-testing": "0.8.4-main.51f1e5ca51",
74
+ "@dxos/echo-db": "0.8.4-main.51f1e5ca51",
75
+ "@dxos/storybook-utils": "0.8.4-main.51f1e5ca51",
76
+ "@dxos/react-ui-components": "0.8.4-main.51f1e5ca51",
77
+ "@dxos/random": "0.8.4-main.51f1e5ca51"
71
78
  },
72
79
  "peerDependencies": {
73
80
  "effect": "3.20.0",
@@ -8,8 +8,7 @@ import { Organization, Person } from '@dxos/types';
8
8
 
9
9
  import { PreviewPopover, ReactSurface } from '#capabilities';
10
10
  import { meta } from '#meta';
11
-
12
- import { translations } from './translations';
11
+ import { translations } from '#translations';
13
12
 
14
13
  export const PreviewPlugin = Plugin.define(meta).pipe(
15
14
  AppPlugin.addSchemaModule({ schema: [Person.Person, Organization.Organization], id: 'schema' }),
@@ -10,10 +10,10 @@ import { Surface } from '@dxos/app-framework/ui';
10
10
  import { AppSurface } from '@dxos/app-toolkit/ui';
11
11
  import { Obj } from '@dxos/echo';
12
12
  import { Card } from '@dxos/react-ui';
13
- import { type ProjectionModel } from '@dxos/schema';
13
+ import { Expando, type ProjectionModel } from '@dxos/schema';
14
14
  import { Organization, Person, Pipeline, Task } from '@dxos/types';
15
15
 
16
- import { FormCard, JsonCard, OrganizationCard, PersonCard, ProjectCard, TaskCard } from '../cards';
16
+ import { ExpandoCard, FormCard, JsonCard, OrganizationCard, PersonCard, ProjectCard, TaskCard } from '../cards';
17
17
 
18
18
  export default Capability.makeModule(() =>
19
19
  Effect.succeed(
@@ -65,6 +65,13 @@ export default Capability.makeModule(() =>
65
65
  return <TaskCard role={role} subject={data.subject} />;
66
66
  },
67
67
  }),
68
+ Surface.create<AppSurface.ObjectCardData<Expando.Expando>>({
69
+ id: 'schema-popover--expando',
70
+ filter: AppSurface.object(AppSurface.Card, Expando.Expando),
71
+ component: ({ data, role }) => {
72
+ return <ExpandoCard role={role} subject={data.subject} ignorePaths={data.ignorePaths} />;
73
+ },
74
+ }),
68
75
 
69
76
  //
70
77
  // Fallback for any object.
@@ -97,7 +104,7 @@ export default Capability.makeModule(() =>
97
104
  component: ({ data }) => {
98
105
  return (
99
106
  <div role='none' className='flex w-full justify-center'>
100
- <div role='none' className='pt-2 pb-2 dx-card-min-width dx-card-max-width'>
107
+ <div role='none' className='py-2 dx-card-min-width dx-card-max-width'>
101
108
  <Card.Root>
102
109
  <Surface.Surface type={AppSurface.Card} data={data} limit={1} />
103
110
  </Card.Root>
@@ -0,0 +1,76 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+ import React, { useCallback, useMemo } from 'react';
7
+
8
+ import { type AppSurface } from '@dxos/app-toolkit/ui';
9
+ import { Obj } from '@dxos/echo';
10
+ import { type JsonPath, splitJsonPath } from '@dxos/effect';
11
+ import { Card } from '@dxos/react-ui';
12
+ import { Form } from '@dxos/react-ui-form';
13
+
14
+ const schemaForValue = (value: unknown): Schema.Schema.AnyNoContext | undefined => {
15
+ switch (typeof value) {
16
+ case 'string':
17
+ return Schema.String;
18
+ case 'number':
19
+ return Schema.Number;
20
+ case 'boolean':
21
+ return Schema.Boolean;
22
+ default:
23
+ return undefined;
24
+ }
25
+ };
26
+
27
+ /**
28
+ * Reserved keys: `id`, plus any `~`-prefixed key (ECHO uses `~`-prefixed
29
+ * string keys to brand entity instances and schemas — KindId,
30
+ * SchemaKindId, SnapshotKindId, etc. — and the `~` namespace is reserved
31
+ * for that purpose). They show up in `Object.keys` but aren't user data.
32
+ */
33
+ const isInternalKey = (key: string) => key === 'id' || key.startsWith('~');
34
+
35
+ export const ExpandoCard = ({ subject, ignorePaths }: AppSurface.ObjectCardProps) => {
36
+ const schema = useMemo(() => {
37
+ const ignored = new Set(ignorePaths ?? []);
38
+ const fields: Record<string, Schema.Schema.AnyNoContext> = {};
39
+ for (const key of Object.keys(subject)) {
40
+ if (isInternalKey(key) || ignored.has(key)) {
41
+ continue;
42
+ }
43
+ const fieldSchema = schemaForValue((subject as any)[key]);
44
+ if (fieldSchema) {
45
+ fields[key] = fieldSchema;
46
+ }
47
+ }
48
+ return Schema.Struct(fields);
49
+ }, [subject, ignorePaths]);
50
+
51
+ const handleSave = useCallback(
52
+ (values: any, { changed }: { changed: Record<string, boolean> }) => {
53
+ const paths = Object.keys(changed).filter((path) => changed[path]);
54
+ Obj.update(subject, () => {
55
+ for (const path of paths) {
56
+ const value = values[path];
57
+ const parts = splitJsonPath(path as JsonPath);
58
+ Obj.setValue(subject, parts, value);
59
+ }
60
+ });
61
+ },
62
+ [subject],
63
+ );
64
+
65
+ return (
66
+ <Card.Content>
67
+ <Form.Root schema={schema} values={subject} autoSave onSave={handleSave}>
68
+ <Form.Viewport>
69
+ <Form.Content>
70
+ <Form.FieldSet />
71
+ </Form.Content>
72
+ </Form.Viewport>
73
+ </Form.Root>
74
+ </Card.Content>
75
+ );
76
+ };
@@ -21,7 +21,7 @@ export const FormCard = ({ subject, projection }: AppSurface.ObjectCardProps & {
21
21
 
22
22
  const handleSave = useCallback((values: any, { changed }: { changed: Record<string, boolean> }) => {
23
23
  const paths = Object.keys(changed).filter((path) => changed[path]);
24
- Obj.change(subject, () => {
24
+ Obj.update(subject, () => {
25
25
  for (const path of paths) {
26
26
  const value = values[path];
27
27
  const parts = splitJsonPath(path as JsonPath);
@@ -10,7 +10,10 @@ import { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';
10
10
  export const JsonCard = ({ data }: { data: unknown }) => {
11
11
  return (
12
12
  <Card.Content>
13
+ <span />
14
+ {/* TODO(wittjosiah): Span whole row. */}
13
15
  <JsonHighlighter data={data} />
16
+ <span />
14
17
  </Card.Content>
15
18
  );
16
19
  };
@@ -2,6 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ export * from './ExpandoCard';
5
6
  export * from './FormCard';
6
7
  export * from './JsonCard';
7
8
  export * from './OrganizationCard';
@@ -9,12 +9,14 @@ import { withPluginManager } from '@dxos/app-framework/testing';
9
9
  import { corePlugins } from '@dxos/plugin-testing';
10
10
  import { random } from '@dxos/random';
11
11
  import { Card } from '@dxos/react-ui';
12
- import { withLayout } from '@dxos/react-ui/testing';
12
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
13
+ import { type Expando } from '@dxos/schema';
13
14
  import { type Organization, type Person, type Pipeline, type Task } from '@dxos/types';
14
15
 
15
- import { FormCard, JsonCard, OrganizationCard, PersonCard, ProjectCard, TaskCard } from '../cards';
16
- import { translations } from '../translations';
17
- import { DefaultStory, createOrganization, createPerson, createProject, createTask } from './testing';
16
+ import { translations } from '#translations';
17
+
18
+ import { ExpandoCard, FormCard, JsonCard, OrganizationCard, PersonCard, ProjectCard, TaskCard } from '../cards';
19
+ import { DefaultStory, createExpando, createOrganization, createPerson, createProject, createTask } from './testing';
18
20
 
19
21
  random.seed(999);
20
22
 
@@ -22,6 +24,11 @@ const meta = {
22
24
  title: 'plugins/plugin-preview/cards/Card',
23
25
  render: DefaultStory,
24
26
  decorators: [
27
+ // `Card` and its descendants in `@dxos/react-ui` consume `ThemeContext`
28
+ // for tx-token resolution; without this the stories trip the surface's
29
+ // `ErrorBoundary` with "Missing ThemeContext" and the storybook test
30
+ // assert-no-error fails.
31
+ withTheme(),
25
32
  withLayout({ layout: 'fullscreen' }),
26
33
  // TODO(wittjosiah): Try to write story which does not depend on plugin manager.
27
34
  withPluginManager({ plugins: corePlugins() }),
@@ -75,6 +82,13 @@ export const _Task: StoryObj<typeof DefaultStory<Task.Task>> = {
75
82
  },
76
83
  };
77
84
 
85
+ export const _Expando: StoryObj<typeof DefaultStory<Expando.Expando>> = {
86
+ args: {
87
+ Component: ExpandoCard,
88
+ createObject: createExpando,
89
+ },
90
+ };
91
+
78
92
  export const _Json = {
79
93
  render: () => {
80
94
  const data = {
@@ -9,6 +9,7 @@ import { Obj, Ref } from '@dxos/echo';
9
9
  import { random } from '@dxos/random';
10
10
  import { Card } from '@dxos/react-ui';
11
11
  import { CardContainer, type CardContainerProps } from '@dxos/react-ui-mosaic/testing';
12
+ import { Expando } from '@dxos/schema';
12
13
  import { Organization, Person, Pipeline, Task } from '@dxos/types';
13
14
 
14
15
  export type DefaultStoryProps<T extends Obj.Any> = {
@@ -89,3 +90,12 @@ export const createTask = (): Task.Task => {
89
90
  status: random.helpers.arrayElement(['todo', 'in-progress', 'done'] as const),
90
91
  });
91
92
  };
93
+
94
+ export const createExpando = (): Expando.Expando => {
95
+ return Expando.make({
96
+ name: random.person.fullName(),
97
+ email: random.internet.email(),
98
+ age: random.number.int({ min: 18, max: 80 }),
99
+ active: random.datatype.boolean(),
100
+ });
101
+ };