@dxos/plugin-markdown 0.8.2-main.12df754 → 0.8.2-main.2f9c567

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 (164) hide show
  1. package/dist/lib/browser/{MarkdownContainer-MH6MMKA5.mjs → MarkdownContainer-JKHGKEWX.mjs} +11 -9
  2. package/dist/lib/browser/MarkdownContainer-JKHGKEWX.mjs.map +7 -0
  3. package/dist/lib/browser/MarkdownPreview-AXRXM2VS.mjs +81 -0
  4. package/dist/lib/browser/MarkdownPreview-AXRXM2VS.mjs.map +7 -0
  5. package/dist/lib/browser/{app-graph-serializer-BF7WSE3D.mjs → app-graph-serializer-6SMW5SL3.mjs} +3 -3
  6. package/dist/lib/browser/{artifact-definition-XTVOUMMI.mjs → artifact-definition-BEV7S3Q2.mjs} +9 -8
  7. package/dist/lib/browser/artifact-definition-BEV7S3Q2.mjs.map +7 -0
  8. package/dist/lib/browser/chunk-6D6EOKIT.mjs +20 -0
  9. package/dist/lib/browser/chunk-6D6EOKIT.mjs.map +7 -0
  10. package/dist/lib/browser/chunk-FJ5P5CGA.mjs +86 -0
  11. package/dist/lib/browser/chunk-FJ5P5CGA.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-V54HDI7B.mjs → chunk-H2ACKZFL.mjs} +9 -22
  13. package/dist/lib/browser/chunk-H2ACKZFL.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-2DKQKSBR.mjs → chunk-JD72ICHV.mjs} +5 -3
  15. package/dist/lib/browser/{chunk-2DKQKSBR.mjs.map → chunk-JD72ICHV.mjs.map} +2 -2
  16. package/dist/lib/browser/index.mjs +10 -6
  17. package/dist/lib/browser/index.mjs.map +3 -3
  18. package/dist/lib/browser/{intent-resolver-H37L3DBD.mjs → intent-resolver-K7GY2J5W.mjs} +4 -4
  19. package/dist/lib/browser/intent-resolver-K7GY2J5W.mjs.map +7 -0
  20. package/dist/lib/browser/meta.json +1 -1
  21. package/dist/lib/browser/{react-surface-RONTBOZZ.mjs → react-surface-G5QRPPGT.mjs} +16 -6
  22. package/dist/lib/browser/react-surface-G5QRPPGT.mjs.map +7 -0
  23. package/dist/lib/browser/{settings-EQSDBX6O.mjs → settings-QBFZJW2H.mjs} +2 -2
  24. package/dist/lib/browser/{thread-MFKBUVCB.mjs → thread-VUUBSXA5.mjs} +2 -2
  25. package/dist/lib/browser/types/index.mjs +1 -1
  26. package/dist/lib/node/{MarkdownContainer-PCHMSPTC.cjs → MarkdownContainer-KLCUCM5O.cjs} +14 -12
  27. package/dist/lib/node/MarkdownContainer-KLCUCM5O.cjs.map +7 -0
  28. package/dist/lib/node/MarkdownPreview-YEFCEKYA.cjs +104 -0
  29. package/dist/lib/node/MarkdownPreview-YEFCEKYA.cjs.map +7 -0
  30. package/dist/lib/node/{app-graph-serializer-UVT5EAWW.cjs → app-graph-serializer-4VZJUDTL.cjs} +9 -9
  31. package/dist/lib/node/{artifact-definition-ADEN2KD6.cjs → artifact-definition-HNSTQ7SX.cjs} +15 -14
  32. package/dist/lib/node/artifact-definition-HNSTQ7SX.cjs.map +7 -0
  33. package/dist/lib/node/{chunk-YHL4JSA6.cjs → chunk-2HGBN655.cjs} +34 -32
  34. package/dist/lib/node/chunk-2HGBN655.cjs.map +7 -0
  35. package/dist/lib/node/chunk-6KAGLDQY.cjs +58 -0
  36. package/dist/lib/node/chunk-6KAGLDQY.cjs.map +7 -0
  37. package/dist/lib/node/{chunk-5XQ27MNY.cjs → chunk-AVTID2BC.cjs} +12 -39
  38. package/dist/lib/node/chunk-AVTID2BC.cjs.map +7 -0
  39. package/dist/lib/node/{chunk-6ERKWMAU.cjs → chunk-ETVG2GKL.cjs} +9 -7
  40. package/dist/lib/node/{chunk-6ERKWMAU.cjs.map → chunk-ETVG2GKL.cjs.map} +2 -2
  41. package/dist/lib/node/index.cjs +24 -21
  42. package/dist/lib/node/index.cjs.map +3 -3
  43. package/dist/lib/node/{intent-resolver-NX5QNRYF.cjs → intent-resolver-FGBVXI7L.cjs} +10 -10
  44. package/dist/lib/node/intent-resolver-FGBVXI7L.cjs.map +7 -0
  45. package/dist/lib/node/meta.json +1 -1
  46. package/dist/lib/node/{react-surface-26PWFBBV.cjs → react-surface-DJFEQ4EN.cjs} +19 -9
  47. package/dist/lib/node/react-surface-DJFEQ4EN.cjs.map +7 -0
  48. package/dist/lib/node/{settings-2JXASSLU.cjs → settings-I3Z64YPE.cjs} +6 -6
  49. package/dist/lib/node/{thread-MXEGV6HS.cjs → thread-NHTJKFC4.cjs} +6 -6
  50. package/dist/lib/node/types/index.cjs +7 -7
  51. package/dist/lib/node/types/index.cjs.map +1 -1
  52. package/dist/lib/node-esm/{MarkdownContainer-ERQH4SXI.mjs → MarkdownContainer-IRHSOSGC.mjs} +11 -9
  53. package/dist/lib/node-esm/MarkdownContainer-IRHSOSGC.mjs.map +7 -0
  54. package/dist/lib/node-esm/MarkdownPreview-JWPTJG2V.mjs +82 -0
  55. package/dist/lib/node-esm/MarkdownPreview-JWPTJG2V.mjs.map +7 -0
  56. package/dist/lib/node-esm/{app-graph-serializer-LPRG2PFZ.mjs → app-graph-serializer-QH2FE7FH.mjs} +3 -3
  57. package/dist/lib/node-esm/{artifact-definition-KTS5M2FW.mjs → artifact-definition-GA7NQ3X5.mjs} +9 -8
  58. package/dist/lib/node-esm/artifact-definition-GA7NQ3X5.mjs.map +7 -0
  59. package/dist/lib/node-esm/{chunk-USLC246I.mjs → chunk-64TMVBTT.mjs} +9 -22
  60. package/dist/lib/node-esm/chunk-64TMVBTT.mjs.map +7 -0
  61. package/dist/lib/node-esm/{chunk-IZUCQ5P5.mjs → chunk-6TXN2UXT.mjs} +5 -3
  62. package/dist/lib/node-esm/{chunk-IZUCQ5P5.mjs.map → chunk-6TXN2UXT.mjs.map} +2 -2
  63. package/dist/lib/node-esm/chunk-I6RIVFIP.mjs +87 -0
  64. package/dist/lib/node-esm/chunk-I6RIVFIP.mjs.map +7 -0
  65. package/dist/lib/node-esm/chunk-VBEBX5EB.mjs +22 -0
  66. package/dist/lib/node-esm/chunk-VBEBX5EB.mjs.map +7 -0
  67. package/dist/lib/node-esm/index.mjs +10 -6
  68. package/dist/lib/node-esm/index.mjs.map +3 -3
  69. package/dist/lib/node-esm/{intent-resolver-XES4ZCA6.mjs → intent-resolver-3STR3645.mjs} +4 -4
  70. package/dist/lib/node-esm/intent-resolver-3STR3645.mjs.map +7 -0
  71. package/dist/lib/node-esm/meta.json +1 -1
  72. package/dist/lib/node-esm/{react-surface-ZEJSYIRX.mjs → react-surface-75OU2AJX.mjs} +16 -6
  73. package/dist/lib/node-esm/react-surface-75OU2AJX.mjs.map +7 -0
  74. package/dist/lib/node-esm/{settings-67RVIH3N.mjs → settings-G7QIMIEK.mjs} +2 -2
  75. package/dist/lib/node-esm/{thread-5U4KSBED.mjs → thread-72RI26KD.mjs} +2 -2
  76. package/dist/lib/node-esm/types/index.mjs +1 -1
  77. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  78. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  79. package/dist/types/src/components/MarkdownContainer.d.ts +2 -2
  80. package/dist/types/src/components/MarkdownContainer.d.ts.map +1 -1
  81. package/dist/types/src/components/{MarkdownEditor.d.ts → MarkdownEditor/MarkdownEditor.d.ts} +1 -1
  82. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts.map +1 -0
  83. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.stories.d.ts.map +1 -0
  84. package/dist/types/src/components/MarkdownEditor/index.d.ts +2 -0
  85. package/dist/types/src/components/MarkdownEditor/index.d.ts.map +1 -0
  86. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts +6 -0
  87. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts.map +1 -0
  88. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts +189 -0
  89. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts.map +1 -0
  90. package/dist/types/src/components/MarkdownPreview/index.d.ts +4 -0
  91. package/dist/types/src/components/MarkdownPreview/index.d.ts.map +1 -0
  92. package/dist/types/src/components/{MarkdownSettings.d.ts → MarkdownSettings/MarkdownSettings.d.ts} +1 -1
  93. package/dist/types/src/components/MarkdownSettings/MarkdownSettings.d.ts.map +1 -0
  94. package/dist/types/src/components/MarkdownSettings/index.d.ts +2 -0
  95. package/dist/types/src/components/MarkdownSettings/index.d.ts.map +1 -0
  96. package/dist/types/src/components/Suggestions.stories.d.ts.map +1 -1
  97. package/dist/types/src/components/index.d.ts +1 -0
  98. package/dist/types/src/components/index.d.ts.map +1 -1
  99. package/dist/types/src/extensions.d.ts +2 -2
  100. package/dist/types/src/extensions.d.ts.map +1 -1
  101. package/dist/types/src/translations.d.ts +6 -0
  102. package/dist/types/src/translations.d.ts.map +1 -1
  103. package/dist/types/src/types/schema.d.ts +509 -190
  104. package/dist/types/src/types/schema.d.ts.map +1 -1
  105. package/dist/types/src/types/types.d.ts +195 -85
  106. package/dist/types/src/types/types.d.ts.map +1 -1
  107. package/dist/types/src/util.d.ts +1 -0
  108. package/dist/types/src/util.d.ts.map +1 -1
  109. package/package.json +40 -37
  110. package/src/MarkdownPlugin.tsx +2 -2
  111. package/src/capabilities/artifact-definition.ts +5 -3
  112. package/src/capabilities/intent-resolver.ts +2 -2
  113. package/src/capabilities/react-surface.tsx +11 -4
  114. package/src/components/MarkdownContainer.tsx +3 -3
  115. package/src/components/{MarkdownEditor.stories.tsx → MarkdownEditor/MarkdownEditor.stories.tsx} +1 -1
  116. package/src/components/{MarkdownEditor.tsx → MarkdownEditor/MarkdownEditor.tsx} +4 -3
  117. package/src/components/MarkdownEditor/index.ts +5 -0
  118. package/src/components/MarkdownPreview/MarkdownPreview.stories.tsx +68 -0
  119. package/src/components/MarkdownPreview/MarkdownPreview.tsx +85 -0
  120. package/src/components/MarkdownPreview/index.ts +9 -0
  121. package/src/components/{MarkdownSettings.tsx → MarkdownSettings/MarkdownSettings.tsx} +2 -2
  122. package/src/components/MarkdownSettings/index.ts +5 -0
  123. package/src/components/Suggestions.stories.tsx +20 -11
  124. package/src/components/Toolbar.stories.tsx +2 -2
  125. package/src/components/index.ts +1 -0
  126. package/src/extensions.tsx +2 -2
  127. package/src/hooks/useSelectCurrentThread.tsx +2 -2
  128. package/src/translations.ts +2 -0
  129. package/src/types/schema.ts +20 -12
  130. package/src/types/types.ts +22 -21
  131. package/src/util.tsx +6 -2
  132. package/dist/lib/browser/MarkdownContainer-MH6MMKA5.mjs.map +0 -7
  133. package/dist/lib/browser/artifact-definition-XTVOUMMI.mjs.map +0 -7
  134. package/dist/lib/browser/chunk-GVOEHF7E.mjs +0 -84
  135. package/dist/lib/browser/chunk-GVOEHF7E.mjs.map +0 -7
  136. package/dist/lib/browser/chunk-V54HDI7B.mjs.map +0 -7
  137. package/dist/lib/browser/intent-resolver-H37L3DBD.mjs.map +0 -7
  138. package/dist/lib/browser/react-surface-RONTBOZZ.mjs.map +0 -7
  139. package/dist/lib/node/MarkdownContainer-PCHMSPTC.cjs.map +0 -7
  140. package/dist/lib/node/artifact-definition-ADEN2KD6.cjs.map +0 -7
  141. package/dist/lib/node/chunk-5XQ27MNY.cjs.map +0 -7
  142. package/dist/lib/node/chunk-YHL4JSA6.cjs.map +0 -7
  143. package/dist/lib/node/intent-resolver-NX5QNRYF.cjs.map +0 -7
  144. package/dist/lib/node/react-surface-26PWFBBV.cjs.map +0 -7
  145. package/dist/lib/node-esm/MarkdownContainer-ERQH4SXI.mjs.map +0 -7
  146. package/dist/lib/node-esm/artifact-definition-KTS5M2FW.mjs.map +0 -7
  147. package/dist/lib/node-esm/chunk-NUZHKZSZ.mjs +0 -85
  148. package/dist/lib/node-esm/chunk-NUZHKZSZ.mjs.map +0 -7
  149. package/dist/lib/node-esm/chunk-USLC246I.mjs.map +0 -7
  150. package/dist/lib/node-esm/intent-resolver-XES4ZCA6.mjs.map +0 -7
  151. package/dist/lib/node-esm/react-surface-ZEJSYIRX.mjs.map +0 -7
  152. package/dist/types/src/components/MarkdownEditor.d.ts.map +0 -1
  153. package/dist/types/src/components/MarkdownEditor.stories.d.ts.map +0 -1
  154. package/dist/types/src/components/MarkdownSettings.d.ts.map +0 -1
  155. /package/dist/lib/browser/{app-graph-serializer-BF7WSE3D.mjs.map → app-graph-serializer-6SMW5SL3.mjs.map} +0 -0
  156. /package/dist/lib/browser/{settings-EQSDBX6O.mjs.map → settings-QBFZJW2H.mjs.map} +0 -0
  157. /package/dist/lib/browser/{thread-MFKBUVCB.mjs.map → thread-VUUBSXA5.mjs.map} +0 -0
  158. /package/dist/lib/node/{app-graph-serializer-UVT5EAWW.cjs.map → app-graph-serializer-4VZJUDTL.cjs.map} +0 -0
  159. /package/dist/lib/node/{settings-2JXASSLU.cjs.map → settings-I3Z64YPE.cjs.map} +0 -0
  160. /package/dist/lib/node/{thread-MXEGV6HS.cjs.map → thread-NHTJKFC4.cjs.map} +0 -0
  161. /package/dist/lib/node-esm/{app-graph-serializer-LPRG2PFZ.mjs.map → app-graph-serializer-QH2FE7FH.mjs.map} +0 -0
  162. /package/dist/lib/node-esm/{settings-67RVIH3N.mjs.map → settings-G7QIMIEK.mjs.map} +0 -0
  163. /package/dist/lib/node-esm/{thread-5U4KSBED.mjs.map → thread-72RI26KD.mjs.map} +0 -0
  164. /package/dist/types/src/components/{MarkdownEditor.stories.d.ts → MarkdownEditor/MarkdownEditor.stories.d.ts} +0 -0
@@ -7,7 +7,7 @@ import React, { useEffect, useMemo } from 'react';
7
7
  import { Capabilities, useCapabilities } from '@dxos/app-framework';
8
8
  import { isInstanceOf } from '@dxos/echo-schema';
9
9
  import { fullyQualifiedId, getSpace } from '@dxos/react-client/echo';
10
- import { TextType } from '@dxos/schema';
10
+ import { DataType } from '@dxos/schema';
11
11
 
12
12
  import { MarkdownEditor, type MarkdownEditorProps } from './MarkdownEditor';
13
13
  import { useExtensions } from '../extensions';
@@ -19,7 +19,7 @@ export type MarkdownContainerProps = Pick<
19
19
  'role' | 'extensionProviders' | 'viewMode' | 'editorStateStore' | 'onViewModeChange'
20
20
  > & {
21
21
  id: string;
22
- object: DocumentType | TextType | any;
22
+ object: DocumentType | DataType.Text | any;
23
23
  settings: MarkdownSettingsProps;
24
24
  };
25
25
 
@@ -36,7 +36,7 @@ const MarkdownContainer = ({
36
36
  }: MarkdownContainerProps) => {
37
37
  const scrollPastEnd = role === 'article';
38
38
  const doc = isInstanceOf(DocumentType, object) ? object : undefined;
39
- const text = isInstanceOf(TextType, object) ? object : undefined;
39
+ const text = isInstanceOf(DataType.Text, object) ? object : undefined;
40
40
  const extensions = useExtensions({ document: doc, text, id, settings, viewMode, editorStateStore });
41
41
 
42
42
  if (doc) {
@@ -15,7 +15,7 @@ import { automerge, translations as editorTranslations } from '@dxos/react-ui-ed
15
15
  import { withLayout, withTheme } from '@dxos/storybook-utils';
16
16
 
17
17
  import { MarkdownEditor, type MarkdownEditorProps } from './MarkdownEditor';
18
- import translations from '../translations';
18
+ import translations from '../../translations';
19
19
 
20
20
  const content = Array.from({ length: 100 }, (_, i) => `Line ${i + 1}`).join('\n');
21
21
 
@@ -38,9 +38,9 @@ import {
38
38
  import { StackItem } from '@dxos/react-ui-stack';
39
39
  import { isNotFalsy, isNonNullable } from '@dxos/util';
40
40
 
41
- import { useSelectCurrentThread } from '../hooks';
42
- import { MARKDOWN_PLUGIN } from '../meta';
43
- import { type MarkdownPluginState } from '../types';
41
+ import { useSelectCurrentThread } from '../../hooks';
42
+ import { MARKDOWN_PLUGIN } from '../../meta';
43
+ import { type MarkdownPluginState } from '../../types';
44
44
 
45
45
  export type MarkdownEditorProps = {
46
46
  id: string;
@@ -231,6 +231,7 @@ export const MarkdownEditor = ({
231
231
  data-testid='composer.markdownRoot'
232
232
  data-toolbar={toolbar ? 'enabled' : 'disabled'}
233
233
  className={stackItemContentEditorClassNames(role)}
234
+ data-popover-collision-boundary={true}
234
235
  {...focusAttributes}
235
236
  />
236
237
  </StackItem.Content>
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './MarkdownEditor';
@@ -0,0 +1,68 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { type Meta } from '@storybook/react';
8
+ import React from 'react';
9
+
10
+ import { IntentPlugin } from '@dxos/app-framework';
11
+ import { withPluginManager } from '@dxos/app-framework/testing';
12
+ import { create } from '@dxos/echo-schema';
13
+ import { DocumentType } from '@dxos/plugin-markdown/types';
14
+ import { faker } from '@dxos/random';
15
+ import { makeRef } from '@dxos/react-client/echo';
16
+ import { Icon, Popover } from '@dxos/react-ui';
17
+ import { DataType } from '@dxos/schema';
18
+ import { withTheme, withLayout } from '@dxos/storybook-utils';
19
+
20
+ import { MarkdownPreview } from './MarkdownPreview';
21
+ import translations from '../../translations';
22
+
23
+ faker.seed(1234);
24
+
25
+ const meta: Meta<typeof MarkdownPreview> = {
26
+ title: 'plugins/plugin-markdown/MarkdownPreview',
27
+ component: MarkdownPreview,
28
+ render: ({ subject }) => {
29
+ return (
30
+ <Popover.Root open>
31
+ <Popover.Content>
32
+ <MarkdownPreview subject={subject} role='popover' />
33
+ <Popover.Arrow />
34
+ </Popover.Content>
35
+ <Popover.Trigger>
36
+ <Icon icon='ph--text-aa--regular' size={5} />
37
+ </Popover.Trigger>
38
+ </Popover.Root>
39
+ );
40
+ },
41
+ decorators: [withPluginManager({ plugins: [IntentPlugin()] }), withTheme, withLayout({ tooltips: true })],
42
+ parameters: {
43
+ layout: 'centered',
44
+ translations,
45
+ },
46
+ };
47
+
48
+ export default meta;
49
+
50
+ const data = (() => {
51
+ const document = create(DocumentType, {
52
+ name: faker.lorem.words(3),
53
+ content: makeRef(
54
+ create(DataType.Text, {
55
+ content: faker.lorem.paragraphs(3),
56
+ }),
57
+ ),
58
+ threads: [],
59
+ });
60
+
61
+ return { document };
62
+ })();
63
+
64
+ export const Default = {
65
+ args: {
66
+ subject: create(DocumentType, data.document),
67
+ },
68
+ };
@@ -0,0 +1,85 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { pipe } from 'effect';
6
+ import React, { useCallback } from 'react';
7
+
8
+ import { chain, createIntent, LayoutAction, useIntentDispatcher } from '@dxos/app-framework';
9
+ import { isInstanceOf } from '@dxos/echo-schema';
10
+ import {
11
+ type PreviewProps,
12
+ defaultCard,
13
+ kanbanCardWithoutPoster,
14
+ popoverCard,
15
+ previewTitle,
16
+ previewProse,
17
+ previewChrome,
18
+ } from '@dxos/plugin-preview';
19
+ import { fullyQualifiedId } from '@dxos/react-client/echo';
20
+ import { Button, Icon, useTranslation } from '@dxos/react-ui';
21
+ import { mx } from '@dxos/react-ui-theme';
22
+ import { DataType } from '@dxos/schema';
23
+
24
+ import { MARKDOWN_PLUGIN } from '../../meta';
25
+ import { DocumentType } from '../../types';
26
+ import { getAbstract, getFallbackName } from '../../util';
27
+
28
+ // TODO(burdon): Factor out.
29
+ const getTitle = (subject: DocumentType | DataType.Text, fallback: string) => {
30
+ if (isInstanceOf(DocumentType, subject)) {
31
+ return subject.name ?? subject.fallbackName ?? getFallbackName(subject.content?.target?.content ?? fallback);
32
+ } else if (isInstanceOf(DataType.Text, subject)) {
33
+ return getFallbackName(subject.content);
34
+ }
35
+ };
36
+
37
+ // TODO(burdon): Factor out.
38
+ const getSnippet = (subject: DocumentType | DataType.Text, fallback: string) => {
39
+ if (isInstanceOf(DocumentType, subject)) {
40
+ return getAbstract(subject.content?.target?.content ?? fallback);
41
+ } else if (isInstanceOf(DataType.Text, subject)) {
42
+ return getAbstract(subject.content);
43
+ }
44
+ };
45
+
46
+ export const MarkdownPreview = ({ classNames, subject, role }: PreviewProps<DocumentType | DataType.Text>) => {
47
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
48
+ const { t } = useTranslation(MARKDOWN_PLUGIN);
49
+ const snippet = getSnippet(subject, t('fallback abstract'));
50
+
51
+ // TODO(wittjosiah): Factor out so this component isn't dependent on the app framework.
52
+ const handleNavigate = useCallback(
53
+ () =>
54
+ dispatch(
55
+ pipe(
56
+ createIntent(LayoutAction.UpdatePopover, {
57
+ part: 'popover',
58
+ subject: null,
59
+ options: { state: false, anchorId: '' },
60
+ }),
61
+ chain(LayoutAction.Open, { part: 'main', subject: [fullyQualifiedId(subject)] }),
62
+ ),
63
+ ),
64
+ [dispatch, subject],
65
+ );
66
+
67
+ return (
68
+ <div
69
+ role='none'
70
+ className={mx(
71
+ role === 'popover' ? popoverCard : role === 'card--kanban' ? kanbanCardWithoutPoster : defaultCard,
72
+ classNames,
73
+ )}
74
+ >
75
+ <h2 className={mx(previewTitle, previewProse)}>{getTitle(subject, t('fallback title'))}</h2>
76
+ {snippet && <p className={mx(previewProse, 'line-clamp-3 break-words col-span-2')}>{snippet}</p>}
77
+ <div role='none' className={previewChrome}>
78
+ <Button onClick={handleNavigate}>
79
+ <span className='grow'>{t('navigate to document label')}</span>
80
+ <Icon icon='ph--arrow-right--regular' />
81
+ </Button>
82
+ </div>
83
+ </div>
84
+ );
85
+ };
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { MarkdownPreview } from './MarkdownPreview';
6
+
7
+ export * from './MarkdownPreview';
8
+
9
+ export default MarkdownPreview;
@@ -8,8 +8,8 @@ import { Input, Select, useTranslation } from '@dxos/react-ui';
8
8
  import { type EditorInputMode, EditorInputModes, type EditorViewMode, EditorViewModes } from '@dxos/react-ui-editor';
9
9
  import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
10
10
 
11
- import { MARKDOWN_PLUGIN } from '../meta';
12
- import { type MarkdownSettingsProps } from '../types';
11
+ import { MARKDOWN_PLUGIN } from '../../meta';
12
+ import { type MarkdownSettingsProps } from '../../types';
13
13
 
14
14
  export const MarkdownSettings = ({ settings }: { settings: MarkdownSettingsProps }) => {
15
15
  const { t } = useTranslation(MARKDOWN_PLUGIN);
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './MarkdownSettings';
@@ -5,6 +5,7 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Meta } from '@storybook/react';
8
+ import { Schema, SchemaAST } from 'effect';
8
9
  import React, { type FC, useEffect, useMemo, useState } from 'react';
9
10
 
10
11
  import {
@@ -19,16 +20,18 @@ import {
19
20
  } from '@dxos/app-framework';
20
21
  import { withPluginManager } from '@dxos/app-framework/testing';
21
22
  import { Message } from '@dxos/artifact';
22
- import { S, AST, create, type Expando, EchoObject } from '@dxos/echo-schema';
23
+ import { Type } from '@dxos/echo';
24
+ import { create, type Expando } from '@dxos/echo-schema';
23
25
  import { invariant } from '@dxos/invariant';
24
26
  import { DXN } from '@dxos/keys';
25
27
  import { live, makeRef, refFromDXN } from '@dxos/live-object';
26
28
  import { ClientPlugin } from '@dxos/plugin-client';
29
+ import { PreviewPlugin } from '@dxos/plugin-preview';
27
30
  import { SpacePlugin } from '@dxos/plugin-space';
28
31
  import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
29
32
  import { ThemePlugin } from '@dxos/plugin-theme';
30
33
  import { faker } from '@dxos/random';
31
- import { randomQueueDxn, useQueue, useSpace } from '@dxos/react-client/echo';
34
+ import { createQueueDxn, useQueue, useSpace } from '@dxos/react-client/echo';
32
35
  import { IconButton, Toolbar } from '@dxos/react-ui';
33
36
  import { command, useTextEditor } from '@dxos/react-ui-editor';
34
37
  import { StackItem } from '@dxos/react-ui-stack';
@@ -44,23 +47,28 @@ import { createDocument, DocumentType, type MarkdownSettingsProps } from '../typ
44
47
 
45
48
  faker.seed(1);
46
49
 
47
- const TestItem = S.Struct({
48
- title: S.String.annotations({
49
- [AST.TitleAnnotationId]: 'Title',
50
- [AST.DescriptionAnnotationId]: 'Product title',
50
+ const TestItem = Schema.Struct({
51
+ title: Schema.String.annotations({
52
+ [SchemaAST.TitleAnnotationId]: 'Title',
53
+ [SchemaAST.DescriptionAnnotationId]: 'Product title',
51
54
  }),
52
- description: S.String.annotations({
53
- [AST.TitleAnnotationId]: 'Description',
54
- [AST.DescriptionAnnotationId]: 'Product description',
55
+ description: Schema.String.annotations({
56
+ [SchemaAST.TitleAnnotationId]: 'Description',
57
+ [SchemaAST.DescriptionAnnotationId]: 'Product description',
55
58
  }),
56
- }).pipe(EchoObject({ typename: 'dxos.org/type/Test', version: '0.1.0' }));
59
+ }).pipe(
60
+ Type.def({
61
+ typename: 'dxos.org/type/Test',
62
+ version: '0.1.0',
63
+ }),
64
+ );
57
65
 
58
66
  const TestChat: FC<{ doc: DocumentType; content: string }> = ({ doc, content }) => {
59
67
  const { dispatchPromise: dispatch } = useIntentDispatcher();
60
68
  const { parentRef } = useTextEditor({ initialValue: content });
61
69
 
62
70
  const space = useSpace();
63
- const queueDxn = useMemo(() => space && randomQueueDxn(space.id), [space]);
71
+ const queueDxn = useMemo(() => space && createQueueDxn(space.id), [space]);
64
72
  const queue = useQueue<Message>(queueDxn);
65
73
 
66
74
  const handleInsert = () => {
@@ -151,6 +159,7 @@ const meta: Meta<typeof DefaultStory> = {
151
159
  SettingsPlugin(),
152
160
  IntentPlugin(),
153
161
  MarkdownPlugin(),
162
+ PreviewPlugin(),
154
163
  ],
155
164
  capabilities: [contributes(MarkdownCapabilities.Extensions, [() => command()])],
156
165
  }),
@@ -31,14 +31,14 @@ import {
31
31
  useTextEditor,
32
32
  useEditorToolbarState,
33
33
  } from '@dxos/react-ui-editor';
34
- import { TextType } from '@dxos/schema';
34
+ import { DataType } from '@dxos/schema';
35
35
  import { withLayout, withTheme } from '@dxos/storybook-utils';
36
36
 
37
37
  faker.seed(101);
38
38
 
39
39
  const DefaultStory: FC<{ content?: string }> = ({ content = '' }) => {
40
40
  const { themeMode } = useThemeContext();
41
- const [text] = useState(createObject(live(TextType, { content })));
41
+ const [text] = useState(createObject(live(DataType.Text, { content })));
42
42
  const toolbarState = useEditorToolbarState({ viewMode: 'preview' });
43
43
  const formattingObserver = useFormattingState(toolbarState);
44
44
  const { parentRef, view } = useTextEditor(() => {
@@ -7,3 +7,4 @@ import { lazy } from 'react';
7
7
  export * from './MarkdownSettings';
8
8
 
9
9
  export const MarkdownContainer = lazy(() => import('./MarkdownContainer'));
10
+ export const MarkdownPreview = lazy(() => import('./MarkdownPreview'));
@@ -35,7 +35,7 @@ import {
35
35
  type RenderCallback,
36
36
  } from '@dxos/react-ui-editor';
37
37
  import { defaultTx } from '@dxos/react-ui-theme';
38
- import { type TextType } from '@dxos/schema';
38
+ import { type DataType } from '@dxos/schema';
39
39
  import { isNotFalsy } from '@dxos/util';
40
40
 
41
41
  import { MarkdownCapabilities } from './capabilities';
@@ -45,7 +45,7 @@ import { setFallbackName } from './util';
45
45
  type ExtensionsOptions = {
46
46
  document?: DocumentType;
47
47
  id?: string;
48
- text?: TextType;
48
+ text?: DataType.Text;
49
49
  dispatch?: PromiseIntentDispatcher;
50
50
  query?: Query<DocumentType>;
51
51
  settings: MarkdownSettingsProps;
@@ -3,10 +3,10 @@
3
3
  //
4
4
 
5
5
  import { EditorView } from '@codemirror/view';
6
+ import { Schema } from 'effect';
6
7
  import { useMemo } from 'react';
7
8
 
8
9
  import { createResolver, LayoutAction, useIntentResolver } from '@dxos/app-framework';
9
- import { S } from '@dxos/echo-schema';
10
10
  import { invariant } from '@dxos/invariant';
11
11
  import { Cursor, setSelection } from '@dxos/react-ui-editor';
12
12
 
@@ -22,7 +22,7 @@ export const useSelectCurrentThread = (editorView: EditorView | undefined, docum
22
22
  intent: LayoutAction.UpdateLayout,
23
23
  position: 'hoist',
24
24
  filter: (data): data is { part: 'current'; subject: string; options: { cursor: string } } => {
25
- if (!S.is(LayoutAction.ScrollIntoView.fields.input)(data)) {
25
+ if (!Schema.is(LayoutAction.ScrollIntoView.fields.input)(data)) {
26
26
  return false;
27
27
  }
28
28
 
@@ -35,6 +35,8 @@ export default [
35
35
  'toggle view mode label': 'Toggle read-only',
36
36
  'default view mode label': 'Default view mode',
37
37
  'upload image label': 'Upload image',
38
+ 'fallback title': 'Untitled',
39
+ 'navigate to document label': 'Open document',
38
40
  },
39
41
  },
40
42
  },
@@ -2,28 +2,36 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { EchoObject, Expando, LabelAnnotationId, Ref, S } from '@dxos/echo-schema';
5
+ import { Schema } from 'effect';
6
+
7
+ import { Type } from '@dxos/echo';
8
+ import { Expando, LabelAnnotationId, Ref } from '@dxos/echo-schema';
6
9
  import { makeRef, live } from '@dxos/live-object';
7
10
  import { ThreadType } from '@dxos/plugin-space/types';
8
- import { TextType } from '@dxos/schema';
11
+ import { DataType } from '@dxos/schema';
9
12
 
10
- export const DocumentSchema = S.Struct({
11
- name: S.optional(S.String),
12
- fallbackName: S.optional(S.String),
13
- content: Ref(TextType),
14
- threads: S.mutable(S.Array(Ref(ThreadType))),
15
- assistantChatQueue: S.optional(Ref(Expando)),
13
+ export const DocumentSchema = Schema.Struct({
14
+ name: Schema.optional(Schema.String),
15
+ fallbackName: Schema.optional(Schema.String),
16
+ content: Ref(DataType.Text),
17
+ threads: Schema.mutable(Schema.Array(Ref(ThreadType))),
18
+ assistantChatQueue: Schema.optional(Ref(Expando)),
16
19
  }).annotations({
17
- // TODO(dmaretskyi): `S.Struct(...).pipe(defaultLabel(['name', 'fallbackName']))` for type-safe annotations.
20
+ // TODO(dmaretskyi): `Schema.Struct(...).pipe(defaultLabel(['name', 'fallbackName']))` for type-safe annotations.
18
21
  [LabelAnnotationId]: ['name', 'fallbackName'],
19
22
  });
20
23
 
21
- export const DocumentType = DocumentSchema.pipe(EchoObject({ typename: 'dxos.org/type/Document', version: '0.1.0' }));
22
- export type DocumentType = S.Schema.Type<typeof DocumentType>;
24
+ export const DocumentType = DocumentSchema.pipe(
25
+ Type.def({
26
+ typename: 'dxos.org/type/Document',
27
+ version: '0.1.0',
28
+ }),
29
+ );
30
+ export type DocumentType = Schema.Schema.Type<typeof DocumentType>;
23
31
 
24
32
  // TODO(burdon): Replace when defaults are supported.
25
33
  export const createDocument = ({ name, content }: { name: string; content: string }) =>
26
- live(DocumentType, { name, content: makeRef(live(TextType, { content })), threads: [] });
34
+ live(DocumentType, { name, content: makeRef(live(DataType.Text, { content })), threads: [] });
27
35
 
28
36
  /**
29
37
  * Checks if an object conforms to the interface needed to render an editor.
@@ -2,7 +2,8 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { S } from '@dxos/echo-schema';
5
+ import { Schema } from 'effect';
6
+
6
7
  // TODO(wittjosiah): This pulls in UI code into the types entrypoint.
7
8
  import { type Extension, EditorInputMode, EditorViewMode } from '@dxos/react-ui-editor';
8
9
 
@@ -12,23 +13,23 @@ import { MARKDOWN_PLUGIN } from '../meta';
12
13
  const MARKDOWN_ACTION = `${MARKDOWN_PLUGIN}/action`;
13
14
 
14
15
  export namespace MarkdownAction {
15
- export class Create extends S.TaggedClass<Create>()(MARKDOWN_ACTION, {
16
- input: S.Struct({
17
- spaceId: S.String,
18
- name: S.optional(S.String),
19
- content: S.optional(S.String),
16
+ export class Create extends Schema.TaggedClass<Create>()(MARKDOWN_ACTION, {
17
+ input: Schema.Struct({
18
+ spaceId: Schema.String,
19
+ name: Schema.optional(Schema.String),
20
+ content: Schema.optional(Schema.String),
20
21
  }),
21
- output: S.Struct({
22
+ output: Schema.Struct({
22
23
  object: DocumentType,
23
24
  }),
24
25
  }) {}
25
26
 
26
- export class SetViewMode extends S.TaggedClass<SetViewMode>()(`${MARKDOWN_ACTION}/set-view-mode`, {
27
- input: S.Struct({
28
- id: S.String,
27
+ export class SetViewMode extends Schema.TaggedClass<SetViewMode>()(`${MARKDOWN_ACTION}/set-view-mode`, {
28
+ input: Schema.Struct({
29
+ id: Schema.String,
29
30
  viewMode: EditorViewMode,
30
31
  }),
31
- output: S.Void,
32
+ output: Schema.Void,
32
33
  }) {}
33
34
  }
34
35
 
@@ -48,18 +49,18 @@ export type MarkdownPluginState = {
48
49
  viewMode: Record<string, EditorViewMode>;
49
50
  };
50
51
 
51
- export const MarkdownSettingsSchema = S.mutable(
52
- S.Struct({
52
+ export const MarkdownSettingsSchema = Schema.mutable(
53
+ Schema.Struct({
53
54
  defaultViewMode: EditorViewMode,
54
- editorInputMode: S.optional(EditorInputMode),
55
- experimental: S.optional(S.Boolean),
56
- debug: S.optional(S.Boolean),
57
- toolbar: S.optional(S.Boolean),
58
- typewriter: S.optional(S.String),
55
+ editorInputMode: Schema.optional(EditorInputMode),
56
+ experimental: Schema.optional(Schema.Boolean),
57
+ debug: Schema.optional(Schema.Boolean),
58
+ toolbar: Schema.optional(Schema.Boolean),
59
+ typewriter: Schema.optional(Schema.String),
59
60
  // TODO(burdon): Per document settings.
60
- numberedHeadings: S.optional(S.Boolean),
61
- folding: S.optional(S.Boolean),
61
+ numberedHeadings: Schema.optional(Schema.Boolean),
62
+ folding: Schema.optional(Schema.Boolean),
62
63
  }),
63
64
  );
64
65
 
65
- export type MarkdownSettingsProps = S.Schema.Type<typeof MarkdownSettingsSchema>;
66
+ export type MarkdownSettingsProps = Schema.Schema.Type<typeof MarkdownSettingsSchema>;
package/src/util.tsx CHANGED
@@ -5,7 +5,7 @@
5
5
  import { debounce } from '@dxos/async';
6
6
  import { type TypedObjectSerializer } from '@dxos/plugin-space/types';
7
7
  import { live, createObject, isEchoObject, loadObjectReferences, makeRef } from '@dxos/react-client/echo';
8
- import { TextType } from '@dxos/schema';
8
+ import { DataType } from '@dxos/schema';
9
9
 
10
10
  import { DocumentType, type MarkdownProperties } from './types';
11
11
 
@@ -22,6 +22,10 @@ export const getFallbackName = (content: string) => {
22
22
  return content.substring(0, 31).split('\n')[0].replaceAll(nonTitleChars, '').trim();
23
23
  };
24
24
 
25
+ export const getAbstract = (content: string) => {
26
+ return content.substring(0, 128).split('\n')[0].replaceAll(nonTitleChars, '').trim();
27
+ };
28
+
25
29
  export const setFallbackName = debounce((doc: DocumentType, content: string) => {
26
30
  const name = getFallbackName(content);
27
31
  if (doc.fallbackName !== name) {
@@ -38,7 +42,7 @@ export const serializer: TypedObjectSerializer<DocumentType> = {
38
42
  deserialize: async ({ content: serialized }) => {
39
43
  const { name, fallbackName, content } = JSON.parse(serialized);
40
44
  return createObject(
41
- live(DocumentType, { name, fallbackName, content: makeRef(live(TextType, { content })), threads: [] }),
45
+ live(DocumentType, { name, fallbackName, content: makeRef(live(DataType.Text, { content })), threads: [] }),
42
46
  );
43
47
  },
44
48
  };