@dxos/react-ui-thread 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.
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-thread",
3
- "version": "0.8.4-main.ae835ea",
3
+ "version": "0.8.4-main.bc674ce",
4
4
  "description": "A set of components to use with threads, including comments and messages.",
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
- "sideEffects": true,
13
+ "sideEffects": false,
10
14
  "type": "module",
11
15
  "exports": {
12
16
  ".": {
@@ -24,33 +28,32 @@
24
28
  "src"
25
29
  ],
26
30
  "dependencies": {
27
- "@preact-signals/safe-react": "^0.9.0",
28
31
  "@radix-ui/react-primitive": "2.0.2",
29
32
  "date-fns": "^3.3.1",
30
- "@dxos/react-ui-editor": "0.8.4-main.ae835ea",
31
- "@dxos/util": "0.8.4-main.ae835ea"
33
+ "@dxos/ui-editor": "0.8.4-main.bc674ce",
34
+ "@dxos/react-ui-editor": "0.8.4-main.bc674ce",
35
+ "@dxos/util": "0.8.4-main.bc674ce"
32
36
  },
33
37
  "devDependencies": {
34
- "@types/react": "~19.2.2",
35
- "@types/react-dom": "~19.2.2",
36
- "react": "~19.2.0",
37
- "react-dom": "~19.2.0",
38
+ "@types/react": "~19.2.7",
39
+ "@types/react-dom": "~19.2.3",
40
+ "react": "~19.2.3",
41
+ "react-dom": "~19.2.3",
38
42
  "vite": "7.1.9",
39
- "@dxos/echo": "0.8.4-main.ae835ea",
40
- "@dxos/echo-db": "0.8.4-main.ae835ea",
41
- "@dxos/keys": "0.8.4-main.ae835ea",
42
- "@dxos/random": "0.8.4-main.ae835ea",
43
- "@dxos/log": "0.8.4-main.ae835ea",
44
- "@dxos/react-ui-theme": "0.8.4-main.ae835ea",
45
- "@dxos/storybook-utils": "0.8.4-main.ae835ea",
46
- "@dxos/react-ui": "0.8.4-main.ae835ea",
47
- "@dxos/live-object": "0.8.4-main.ae835ea"
43
+ "@dxos/echo": "0.8.4-main.bc674ce",
44
+ "@dxos/echo-db": "0.8.4-main.bc674ce",
45
+ "@dxos/keys": "0.8.4-main.bc674ce",
46
+ "@dxos/log": "0.8.4-main.bc674ce",
47
+ "@dxos/random": "0.8.4-main.bc674ce",
48
+ "@dxos/react-ui": "0.8.4-main.bc674ce",
49
+ "@dxos/ui-theme": "0.8.4-main.bc674ce",
50
+ "@dxos/storybook-utils": "0.8.4-main.bc674ce"
48
51
  },
49
52
  "peerDependencies": {
50
- "react": "^19.0.0",
51
- "react-dom": "^19.0.0",
52
- "@dxos/react-ui": "0.8.4-main.ae835ea",
53
- "@dxos/react-ui-theme": "0.8.4-main.ae835ea"
53
+ "react": "~19.2.3",
54
+ "react-dom": "~19.2.3",
55
+ "@dxos/react-ui": "0.8.4-main.bc674ce",
56
+ "@dxos/ui-theme": "0.8.4-main.bc674ce"
54
57
  },
55
58
  "publishConfig": {
56
59
  "access": "public"
@@ -7,7 +7,7 @@ import React, { useState } from 'react';
7
7
 
8
8
  import { PublicKey } from '@dxos/keys';
9
9
  import { withTheme } from '@dxos/react-ui/testing';
10
- import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
10
+ import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/ui-theme';
11
11
 
12
12
  import { type MessageEntity, MessageStoryText } from '../testing';
13
13
  import { Thread } from '../Thread';
@@ -5,10 +5,10 @@
5
5
  import { formatDistanceToNow } from 'date-fns/formatDistanceToNow';
6
6
  import React, { type ComponentPropsWithRef, type ComponentPropsWithoutRef, forwardRef } from 'react';
7
7
 
8
- // TODO(burdon): Remove dep.
9
8
  import { Avatar, type ThemedClassName, useTranslation } from '@dxos/react-ui';
10
- import { type UseTextEditorProps, keymap, listener, useTextEditor } from '@dxos/react-ui-editor';
11
- import { focusRing, mx } from '@dxos/react-ui-theme';
9
+ import { type UseTextEditorProps, useTextEditor } from '@dxos/react-ui-editor';
10
+ import { keymap, listener } from '@dxos/ui-editor';
11
+ import { focusRing, mx } from '@dxos/ui-theme';
12
12
  import { hexToEmoji, hexToHue, isTruthy } from '@dxos/util';
13
13
 
14
14
  import { translationKey } from '../translations';
@@ -5,28 +5,28 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { type FC, useEffect, useMemo, useRef, useState } from 'react';
7
7
 
8
- import { Expando } from '@dxos/echo/internal';
9
- import { live } from '@dxos/echo/internal';
10
- import { createDocAccessor, createObject } from '@dxos/echo-db';
8
+ import { Obj } from '@dxos/echo';
9
+ import { TestSchema } from '@dxos/echo/testing';
11
10
  import { PublicKey } from '@dxos/keys';
12
11
  import { log } from '@dxos/log';
13
12
  import { faker } from '@dxos/random';
14
- import { Button, Icon, useThemeContext } from '@dxos/react-ui';
13
+ import { Icon, IconButton, useThemeContext } from '@dxos/react-ui';
15
14
  import { withTheme } from '@dxos/react-ui/testing';
15
+ import { useTextEditor } from '@dxos/react-ui-editor';
16
16
  import {
17
17
  type Comment,
18
18
  type CommentsOptions,
19
+ type EditorView,
19
20
  type Range,
20
- automerge,
21
21
  comments,
22
22
  createBasicExtensions,
23
23
  createThemeExtensions,
24
+ documentId,
24
25
  listener,
25
26
  scrollThreadIntoView,
26
- useComments,
27
- useTextEditor,
28
- } from '@dxos/react-ui-editor';
29
- import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
27
+ setComments,
28
+ } from '@dxos/ui-editor';
29
+ import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/ui-theme';
30
30
 
31
31
  import { MessageBody, MessageHeading, MessageRoot, MessageTextbox } from '../Message';
32
32
  import { type MessageEntity } from '../testing';
@@ -38,13 +38,31 @@ faker.seed(101);
38
38
 
39
39
  const authorId = PublicKey.random().toHex();
40
40
 
41
+ /**
42
+ * @deprecated This hook will be removed in future versions. Use the new comment sync extension instead.
43
+ * Update comments state field.
44
+ */
45
+ const useComments = (view: EditorView | null | undefined, id: string, comments?: Comment[]) => {
46
+ useEffect(() => {
47
+ if (view) {
48
+ // Check same document.
49
+ // NOTE: Hook might be called before editor state is updated.
50
+ if (id === view.state.facet(documentId)) {
51
+ view.dispatch({
52
+ effects: setComments.of({ id, comments: comments ?? [] }),
53
+ });
54
+ }
55
+ }
56
+ });
57
+ };
58
+
41
59
  //
42
60
  // Editor
43
61
  //
44
62
 
45
63
  const Editor: FC<{
46
64
  id?: string;
47
- item: Expando;
65
+ initialValue: string;
48
66
  comments: Comment[];
49
67
  selected?: string;
50
68
  onCreateComment: CommentsOptions['onCreate'];
@@ -53,7 +71,7 @@ const Editor: FC<{
53
71
  onSelectComment: CommentsOptions['onSelect'];
54
72
  }> = ({
55
73
  id = 'test',
56
- item,
74
+ initialValue,
57
75
  selected: selectedValue,
58
76
  comments: commentRanges,
59
77
  onCreateComment,
@@ -67,11 +85,10 @@ const Editor: FC<{
67
85
  const { parentRef, view } = useTextEditor(
68
86
  () => ({
69
87
  id,
70
- initialValue: item.content,
88
+ initialValue: initialValue,
71
89
  extensions: [
72
90
  createBasicExtensions(),
73
91
  createThemeExtensions({ themeMode }),
74
- automerge(createDocAccessor(item, ['content'])),
75
92
  comments({
76
93
  id,
77
94
  onCreate: onCreateComment,
@@ -81,7 +98,7 @@ const Editor: FC<{
81
98
  }),
82
99
  ],
83
100
  }),
84
- [id, item, themeMode],
101
+ [id, initialValue, themeMode],
85
102
  );
86
103
  useComments(view, id, commentRanges);
87
104
  useEffect(() => {
@@ -144,7 +161,7 @@ const StoryThread: FC<{
144
161
 
145
162
  const handleCreateMessage = () => {
146
163
  if (messageRef.current?.length) {
147
- const message = live(Expando, {
164
+ const message = Obj.make(TestSchema.Expando, {
148
165
  timestamp: new Date().toISOString(),
149
166
  sender: { identityKey: authorId },
150
167
  text: messageRef.current,
@@ -187,20 +204,27 @@ const StoryThread: FC<{
187
204
  onSend={handleCreateMessage}
188
205
  />
189
206
  <Thread.Status />
190
- <Button variant='ghost' classNames='px-1' title='Resolve' onClick={onResolve}>
191
- <Icon icon='ph--check--regular' />
192
- </Button>
207
+ <IconButton
208
+ variant='ghost'
209
+ icon='ph--check--regular'
210
+ iconOnly
211
+ classNames='pli-1'
212
+ label='Resolve'
213
+ onClick={onResolve}
214
+ />
193
215
  </div>
194
216
  </Thread.Root>
195
217
  );
196
218
  };
197
219
 
198
- const Sidebar: FC<{
220
+ type SidebarProps = {
199
221
  threads: StoryCommentThread[];
200
222
  selected?: string;
201
223
  onSelect: (thread: string) => void;
202
224
  onResolve: (thread: string) => void;
203
- }> = ({ threads, selected, onSelect, onResolve }) => {
225
+ };
226
+
227
+ const Sidebar = ({ threads, selected, onSelect, onResolve }: SidebarProps) => {
204
228
  // Sort by y-position.
205
229
  const sortedThreads = useMemo(() => {
206
230
  const sorted = [...threads];
@@ -234,7 +258,7 @@ type StoryProps = {
234
258
  };
235
259
 
236
260
  const DefaultStory = ({ text, autoCreate }: StoryProps) => {
237
- const [item] = useState(createObject(live(Expando, { content: text ?? '' })));
261
+ const [item] = useState(() => Obj.make(TestSchema.Expando, { content: text ?? '' }));
238
262
  const [threads, setThreads] = useState<StoryCommentThread[]>([]);
239
263
  const [selected, setSelected] = useState<string>();
240
264
 
@@ -328,7 +352,7 @@ const DefaultStory = ({ text, autoCreate }: StoryProps) => {
328
352
  <main className='fixed inset-0 grid grid-cols-[1fr_24rem]'>
329
353
  <div role='none' className='max-bs-full overflow-y-auto p-4'>
330
354
  <Editor
331
- item={item}
355
+ initialValue={item.content}
332
356
  selected={selected}
333
357
  comments={comments}
334
358
  onCreateComment={handleCreateComment}
@@ -8,8 +8,8 @@ import React, { useMemo, useRef, useState } from 'react';
8
8
  import { PublicKey } from '@dxos/keys';
9
9
  import { faker } from '@dxos/random';
10
10
  import { withTheme } from '@dxos/react-ui/testing';
11
- import { createBasicExtensions, createThemeExtensions } from '@dxos/react-ui-editor';
12
- import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
11
+ import { createBasicExtensions, createThemeExtensions } from '@dxos/ui-editor';
12
+ import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/ui-theme';
13
13
 
14
14
  import { MessageRoot, MessageTextbox } from '../Message';
15
15
  import { type MessageEntity, MessageStoryText } from '../testing';
@@ -5,7 +5,7 @@
5
5
  import React, { type ComponentPropsWithRef, forwardRef } from 'react';
6
6
 
7
7
  import { Icon, type ThemedClassName, useTranslation } from '@dxos/react-ui';
8
- import { hoverableControlItem, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
8
+ import { hoverableControlItem, hoverableFocusedWithinControls, mx } from '@dxos/ui-theme';
9
9
 
10
10
  import { translationKey } from '../translations';
11
11
  import type { ThreadEntity } from '../types';
@@ -45,10 +45,10 @@ const ThreadRoot = forwardRef<HTMLDivElement, ThreadRootProps>(
45
45
  // Heading
46
46
  //
47
47
 
48
- type ThreadHeaderProps = ThemedClassName<ComponentPropsWithRef<'div'>> & { detached?: boolean };
48
+ type ThreadHeaderProps = ComponentPropsWithRef<'div'> & { detached?: boolean };
49
49
 
50
50
  const ThreadHeader = forwardRef<HTMLParagraphElement, ThreadHeaderProps>(
51
- ({ classNames, children, detached, ...props }, forwardedRef) => {
51
+ ({ children, detached, ...props }, forwardedRef) => {
52
52
  return (
53
53
  <>
54
54
  <div role='none' className='flex items-center justify-center text-description'>
package/src/testing.tsx CHANGED
@@ -4,8 +4,8 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { Button, Icon } from '@dxos/react-ui';
8
- import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
7
+ import { IconButton } from '@dxos/react-ui';
8
+ import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/ui-theme';
9
9
 
10
10
  import { MessageBody, MessageHeading } from './Message';
11
11
  import { type MessageMetadata } from './types';
@@ -25,13 +25,14 @@ export const MessageStoryText = ({ text, onDelete, authorName, timestamp }: Mess
25
25
  <>
26
26
  <MessageHeading authorName={authorName} timestamp={timestamp}>
27
27
  {onDelete && (
28
- <Button
28
+ <IconButton
29
+ icon='ph--x--regular'
30
+ iconOnly
31
+ label='Delete'
29
32
  variant='ghost'
30
33
  classNames={['p-1.5 min-bs-0 mie-1 items-start transition-opacity', hoverableControlItem]}
31
34
  onClick={() => onDelete()}
32
- >
33
- <Icon icon='ph--x--regular' />
34
- </Button>
35
+ />
35
36
  )}
36
37
  </MessageHeading>
37
38
  <MessageBody>{text}</MessageBody>
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { type Resource } from '@dxos/react-ui';
6
6
 
7
- export const translationKey = 'react-ui-thread';
7
+ export const translationKey = '@dxos/react-ui-thread';
8
8
 
9
9
  export const translations = [
10
10
  {