@dxos/react-ui-editor 0.4.10-main.d4e372f → 0.4.10-main.d51f2c2

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.
@@ -6,7 +6,8 @@ import '@dxosTheme';
6
6
 
7
7
  import React, { type FC, useState } from 'react';
8
8
 
9
- import { TextObject } from '@dxos/echo-schema';
9
+ import { TextV0Type } from '@braneframe/types';
10
+ import { createDocAccessor, create } from '@dxos/echo-schema';
10
11
  import { PublicKey } from '@dxos/keys';
11
12
  import { faker } from '@dxos/random';
12
13
  import { Tooltip, useThemeContext } from '@dxos/react-ui';
@@ -28,26 +29,25 @@ import {
28
29
  useComments,
29
30
  useFormattingState,
30
31
  } from '../../extensions';
31
- import { useActionHandler, useDocAccessor, useTextEditor } from '../../hooks';
32
+ import { useActionHandler, useTextEditor } from '../../hooks';
32
33
  import translations from '../../translations';
33
34
 
34
35
  faker.seed(101);
35
36
 
36
37
  const Story: FC<{ content: string }> = ({ content }) => {
37
38
  const { themeMode } = useThemeContext();
38
- const [item] = useState({ text: new TextObject(content) });
39
- const { id, doc, accessor } = useDocAccessor(item.text);
39
+ const [text] = useState(create(TextV0Type, { content }));
40
40
  const [formattingState, formattingObserver] = useFormattingState();
41
41
  const { parentRef, view } = useTextEditor(() => {
42
42
  return {
43
- id,
44
- doc,
43
+ id: text.id,
44
+ doc: text.content,
45
45
  extensions: [
46
46
  formattingObserver,
47
47
  createBasicExtensions(),
48
48
  createMarkdownExtensions({ themeMode }),
49
49
  createThemeExtensions({ themeMode, slots: { editor: { className: 'p-2' } } }),
50
- createDataExtensions({ id, text: accessor }),
50
+ createDataExtensions({ id: text.id, text: createDocAccessor(text, ['content']) }),
51
51
  comments({
52
52
  onCreate: ({ cursor }) => {
53
53
  const id = PublicKey.random().toHex();
@@ -61,12 +61,12 @@ const Story: FC<{ content: string }> = ({ content }) => {
61
61
  table(),
62
62
  ],
63
63
  };
64
- }, [id, accessor, formattingObserver, themeMode]);
64
+ }, [text, formattingObserver, themeMode]);
65
65
 
66
66
  const handleAction = useActionHandler(view);
67
67
 
68
68
  const [_comments, setComments] = useState<Comment[]>([]);
69
- useComments(view, id, _comments);
69
+ useComments(view, text.id, _comments);
70
70
 
71
71
  return (
72
72
  <Tooltip.Provider>
@@ -8,10 +8,11 @@ import { BroadcastChannelNetworkAdapter } from '@automerge/automerge-repo-networ
8
8
  import '@preact/signals-react';
9
9
  import React, { useEffect, useMemo, useState } from 'react';
10
10
 
11
+ import { TextV0Type } from '@braneframe/types';
11
12
  import { Repo } from '@dxos/automerge/automerge-repo';
12
- import { createDocAccessor, Filter, DocAccessor } from '@dxos/echo-schema';
13
+ import { Filter, DocAccessor, create, createDocAccessor, type Expando } from '@dxos/echo-schema';
13
14
  import { type PublicKey } from '@dxos/keys';
14
- import { Expando, TextObject, useSpace } from '@dxos/react-client/echo';
15
+ import { useSpace } from '@dxos/react-client/echo';
15
16
  import { ClientRepeater } from '@dxos/react-client/testing';
16
17
  import { useThemeContext } from '@dxos/react-ui';
17
18
  import { withTheme } from '@dxos/storybook-utils';
@@ -97,9 +98,9 @@ const EchoStory = ({ spaceKey }: { spaceKey: PublicKey }) => {
97
98
  // const identity = useIdentity();
98
99
  const space = useSpace(spaceKey);
99
100
  const source = useMemo<DocAccessor | undefined>(() => {
100
- const { objects = [] } = space?.db.query(Filter.from({ type: 'test' })) ?? {};
101
+ const { objects = [] } = space?.db.query<Expando>(Filter.from({ type: 'test' })) ?? {};
101
102
  if (objects.length) {
102
- return createDocAccessor(objects[0].content);
103
+ return createDocAccessor(objects[0].content, ['content']);
103
104
  }
104
105
  }, [space]);
105
106
 
@@ -124,9 +125,9 @@ export const WithEcho = {
124
125
  createSpace
125
126
  onCreateSpace={async (space) => {
126
127
  space.db.add(
127
- new Expando({
128
+ create({
128
129
  type: 'test',
129
- content: new TextObject(initialContent),
130
+ content: create(TextV0Type, { content: initialContent }),
130
131
  }),
131
132
  );
132
133
  }}
@@ -2,30 +2,16 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import get from 'lodash.get';
6
-
7
- import { next as A } from '@dxos/automerge/automerge';
8
- import { type DocAccessor } from '@dxos/echo-schema';
5
+ import { toCursor, type DocAccessor, fromCursor } from '@dxos/echo-schema';
9
6
  import { log } from '@dxos/log';
10
7
 
11
8
  import { type CursorConverter } from '../cursor';
12
9
 
13
- export const cursorConverter = ({ handle, path }: DocAccessor): CursorConverter => ({
10
+ export const cursorConverter = (accessor: DocAccessor): CursorConverter => ({
14
11
  // TODO(burdon): Handle assoc to associate with a previous character.
15
12
  toCursor: (pos) => {
16
- const doc = handle.docSync();
17
- if (!doc) {
18
- return '';
19
- }
20
-
21
- const value = get(doc, path);
22
- if (typeof value === 'string' && value.length <= pos) {
23
- return 'end';
24
- }
25
-
26
13
  try {
27
- // NOTE: Slice is needed because getCursor mutates the array.
28
- return A.getCursor(doc, path.slice(), pos);
14
+ return toCursor(accessor, pos);
29
15
  } catch (err) {
30
16
  log.catch(err);
31
17
  return ''; // In case of invalid request (e.g., wrong document).
@@ -33,27 +19,8 @@ export const cursorConverter = ({ handle, path }: DocAccessor): CursorConverter
33
19
  },
34
20
 
35
21
  fromCursor: (cursor) => {
36
- if (cursor === '') {
37
- return 0;
38
- }
39
-
40
- const doc = handle.docSync();
41
- if (!doc) {
42
- return 0;
43
- }
44
-
45
- if (cursor === 'end') {
46
- const value = get(doc, path);
47
- if (typeof value === 'string') {
48
- return value.length;
49
- } else {
50
- return 0;
51
- }
52
- }
53
-
54
22
  try {
55
- // NOTE: Slice is needed because getCursor mutates the array.
56
- return A.getCursorPosition(doc, path.slice(), cursor);
23
+ return fromCursor(accessor, cursor);
57
24
  } catch (err) {
58
25
  log.catch(err);
59
26
  return 0; // In case of invalid request (e.g., wrong document).
@@ -162,14 +162,14 @@ export const createThemeExtensions = ({ theme, themeMode, slots: _slots }: Theme
162
162
 
163
163
  export type DataExtensionsProps = {
164
164
  id: string;
165
- text: DocAccessor;
165
+ text?: DocAccessor;
166
166
  space?: Space;
167
167
  identity?: Identity | null;
168
168
  };
169
169
 
170
170
  // TODO(burdon): Move out of react-ui-editor (remove echo deps).
171
171
  export const createDataExtensions = ({ id, text, space, identity }: DataExtensionsProps): Extension[] => {
172
- const extensions: Extension[] = [automerge(text)];
172
+ const extensions: Extension[] = text ? [automerge(text)] : [];
173
173
 
174
174
  if (space && identity) {
175
175
  const peerId = identity?.identityKey.toHex();
@@ -3,5 +3,4 @@
3
3
  //
4
4
 
5
5
  export * from './useActionHandler';
6
- export * from './useDocAccessor';
7
6
  export * from './useTextEditor';
@@ -36,9 +36,9 @@ export const useTextEditor = (cb: () => UseTextEditorProps = () => ({}), deps: D
36
36
  log('create', { id });
37
37
 
38
38
  // https://codemirror.net/docs/ref/#state.EditorStateConfig
39
+ // NOTE: Don't set selection here in case it is invalid (and crashes the state); dispatch below.
39
40
  const state = EditorState.create({
40
41
  doc,
41
- selection,
42
42
  extensions: [
43
43
  id && documentId.of(id),
44
44
  // TODO(burdon): Doesn't catch errors in keymap functions.
@@ -1,9 +0,0 @@
1
- import { type DocAccessor, type TextObject, type EchoReactiveObject } from '@dxos/echo-schema';
2
- export declare const useDocAccessor: <T = any>(text: TextObject | EchoReactiveObject<{
3
- content: string;
4
- }>) => {
5
- id: string;
6
- doc: string | undefined;
7
- accessor: DocAccessor<T>;
8
- };
9
- //# sourceMappingURL=useDocAccessor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useDocAccessor.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useDocAccessor.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAG3B,eAAO,MAAM,cAAc,kBACnB,UAAU,GAAG,mBAAmB;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;QACnD,MAAM;SAAO,MAAM,GAAG,SAAS;;CASvC,CAAC"}
@@ -1,27 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { useMemo } from 'react';
6
-
7
- import {
8
- createDocAccessor,
9
- type DocAccessor,
10
- getTextContent,
11
- type TextObject,
12
- type EchoReactiveObject,
13
- } from '@dxos/echo-schema';
14
-
15
- // TODO(burdon): Factor out.
16
- export const useDocAccessor = <T = any>(
17
- text: TextObject | EchoReactiveObject<{ content: string }>,
18
- ): { id: string; doc: string | undefined; accessor: DocAccessor<T> } => {
19
- return useMemo(
20
- () => ({
21
- id: text.id,
22
- doc: getTextContent(text),
23
- accessor: createDocAccessor<T>(text),
24
- }),
25
- [text],
26
- );
27
- };