@dxos/react-ui-thread 0.8.3-staging.0fa589b → 0.8.4-main.28f8d3d

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-thread",
3
- "version": "0.8.3-staging.0fa589b",
3
+ "version": "0.8.4-main.28f8d3d",
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",
@@ -10,6 +10,7 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs"
15
16
  }
@@ -26,32 +27,30 @@
26
27
  "@preact-signals/safe-react": "^0.9.0",
27
28
  "@radix-ui/react-primitive": "2.0.2",
28
29
  "date-fns": "^3.3.1",
29
- "@dxos/react-ui-editor": "0.8.3-staging.0fa589b",
30
- "@dxos/util": "0.8.3-staging.0fa589b"
30
+ "@dxos/react-ui-editor": "0.8.4-main.28f8d3d",
31
+ "@dxos/util": "0.8.4-main.28f8d3d"
31
32
  },
32
33
  "devDependencies": {
33
- "@phosphor-icons/react": "^2.1.5",
34
34
  "@types/react": "~18.2.0",
35
35
  "@types/react-dom": "~18.2.0",
36
36
  "react": "~18.2.0",
37
37
  "react-dom": "~18.2.0",
38
38
  "vite": "5.4.7",
39
- "@dxos/echo-db": "0.8.3-staging.0fa589b",
40
- "@dxos/echo-schema": "0.8.3-staging.0fa589b",
41
- "@dxos/keys": "0.8.3-staging.0fa589b",
42
- "@dxos/live-object": "0.8.3-staging.0fa589b",
43
- "@dxos/log": "0.8.3-staging.0fa589b",
44
- "@dxos/random": "0.8.3-staging.0fa589b",
45
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b",
46
- "@dxos/react-ui": "0.8.3-staging.0fa589b",
47
- "@dxos/storybook-utils": "0.8.3-staging.0fa589b"
39
+ "@dxos/echo-db": "0.8.4-main.28f8d3d",
40
+ "@dxos/echo-schema": "0.8.4-main.28f8d3d",
41
+ "@dxos/keys": "0.8.4-main.28f8d3d",
42
+ "@dxos/live-object": "0.8.4-main.28f8d3d",
43
+ "@dxos/random": "0.8.4-main.28f8d3d",
44
+ "@dxos/log": "0.8.4-main.28f8d3d",
45
+ "@dxos/react-ui": "0.8.4-main.28f8d3d",
46
+ "@dxos/react-ui-theme": "0.8.4-main.28f8d3d",
47
+ "@dxos/storybook-utils": "0.8.4-main.28f8d3d"
48
48
  },
49
49
  "peerDependencies": {
50
- "@phosphor-icons/react": "^2.1.5",
51
50
  "react": "~18.2.0",
52
51
  "react-dom": "~18.2.0",
53
- "@dxos/react-ui": "0.8.3-staging.0fa589b",
54
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b"
52
+ "@dxos/react-ui": "0.8.4-main.28f8d3d",
53
+ "@dxos/react-ui-theme": "0.8.4-main.28f8d3d"
55
54
  },
56
55
  "publishConfig": {
57
56
  "access": "public"
@@ -10,10 +10,11 @@ import { PublicKey } from '@dxos/keys';
10
10
  import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
11
11
  import { withLayout, withTheme } from '@dxos/storybook-utils';
12
12
 
13
+ import { type MessageEntity, MessageStoryText } from '../testing';
14
+ import { Thread } from '../Thread';
15
+ import { translations } from '../translations';
16
+
13
17
  import { MessageRoot } from './Message';
14
- import { threadLayout } from '../Thread';
15
- import { ThreadStoryContainer, MessageStoryText, type MessageEntity } from '../testing';
16
- import translations from '../translations';
17
18
 
18
19
  const DefaultStory = () => {
19
20
  const [identityKey] = useState(PublicKey.random());
@@ -25,13 +26,13 @@ const DefaultStory = () => {
25
26
  });
26
27
 
27
28
  return (
28
- <ThreadStoryContainer>
29
- <div className={threadLayout}>
29
+ <div className='mli-auto is-96 overflow-y-auto'>
30
+ <Thread.Root id='t1'>
30
31
  <MessageRoot {...message} classNames={[hoverableControls, hoverableFocusedWithinControls]}>
31
32
  <MessageStoryText {...message} onDelete={() => console.log('delete')} />
32
33
  </MessageRoot>
33
- </div>
34
- </ThreadStoryContainer>
34
+ </Thread.Root>
35
+ </div>
35
36
  );
36
37
  };
37
38
 
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { formatDistanceToNow } from 'date-fns/formatDistanceToNow';
6
- import React, { type ComponentPropsWithRef, forwardRef, type ComponentPropsWithoutRef } from 'react';
6
+ import React, { type ComponentPropsWithRef, type ComponentPropsWithoutRef, forwardRef } from 'react';
7
7
 
8
8
  // TODO(burdon): Remove dep.
9
9
  import { Avatar, type ThemedClassName, useTranslation } from '@dxos/react-ui';
@@ -4,7 +4,6 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { Check, Trash } from '@phosphor-icons/react';
8
7
  import React, { type FC, useEffect, useMemo, useRef, useState } from 'react';
9
8
 
10
9
  import { createDocAccessor, createObject } from '@dxos/echo-db';
@@ -13,7 +12,7 @@ import { PublicKey } from '@dxos/keys';
13
12
  import { live } from '@dxos/live-object';
14
13
  import { log } from '@dxos/log';
15
14
  import { faker } from '@dxos/random';
16
- import { Button, useThemeContext } from '@dxos/react-ui';
15
+ import { Button, Icon, useThemeContext } from '@dxos/react-ui';
17
16
  import {
18
17
  type Comment,
19
18
  type CommentsOptions,
@@ -30,10 +29,11 @@ import {
30
29
  import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
31
30
  import { withTheme } from '@dxos/storybook-utils';
32
31
 
33
- import { Thread, ThreadFooter, ThreadHeading } from './Thread';
34
32
  import { MessageBody, MessageHeading, MessageRoot, MessageTextbox } from '../Message';
35
33
  import { type MessageEntity } from '../testing';
36
- import translations from '../translations';
34
+ import { translations } from '../translations';
35
+
36
+ import { Thread } from './Thread';
37
37
 
38
38
  faker.seed(101);
39
39
 
@@ -157,17 +157,17 @@ const StoryThread: FC<{
157
157
  };
158
158
 
159
159
  return (
160
- <Thread current={selected} onClickCapture={onSelect}>
160
+ <Thread.Root current={selected} onClickCapture={onSelect}>
161
161
  <div className='col-start-2 flex gap-1 text-xs text-description'>
162
162
  <span>id:{thread.id.slice(0, 4)}</span>
163
163
  <span>y:{thread.yPos}</span>
164
164
  <span className='grow' />
165
- {!thread.cursor && <Trash />}
165
+ {!thread.cursor && <Icon icon='ph--trash--regular' />}
166
166
  </div>
167
167
 
168
- <ThreadHeading>
168
+ <Thread.Header>
169
169
  {thread.range?.from} &ndash; {thread.range?.to}
170
- </ThreadHeading>
170
+ </Thread.Header>
171
171
 
172
172
  {thread.messages.map((message) => (
173
173
  <MessageRoot key={message.id} classNames={[hoverableControls, hoverableFocusedWithinControls]} {...message}>
@@ -185,12 +185,12 @@ const StoryThread: FC<{
185
185
  onEditorFocus={onSelect}
186
186
  onSend={handleCreateMessage}
187
187
  />
188
- <ThreadFooter />
188
+ <Thread.Status />
189
189
  <Button variant='ghost' classNames='px-1' title='Resolve' onClick={onResolve}>
190
- <Check />
190
+ <Icon icon='ph--check--regular' />
191
191
  </Button>
192
192
  </div>
193
- </Thread>
193
+ </Thread.Root>
194
194
  );
195
195
  };
196
196
 
@@ -359,15 +359,13 @@ export default {
359
359
 
360
360
  const str = (...lines: string[]) => lines.join('\n');
361
361
 
362
- const document = str(
363
- '# Comments',
364
- '',
365
- str(...faker.helpers.multiple(() => [faker.lorem.paragraph({ min: 5, max: 10 }), ''], { count: 20 }).flat()),
366
- '',
367
- );
368
-
369
362
  export const Default = {
370
363
  args: {
371
- text: document,
364
+ text: str(
365
+ '# Comments',
366
+ '',
367
+ str(...faker.helpers.multiple(() => [faker.lorem.paragraph({ min: 5, max: 10 }), ''], { count: 20 }).flat()),
368
+ '',
369
+ ),
372
370
  },
373
371
  };
@@ -10,12 +10,13 @@ import { PublicKey } from '@dxos/keys';
10
10
  import { faker } from '@dxos/random';
11
11
  import { createBasicExtensions, createThemeExtensions } from '@dxos/react-ui-editor';
12
12
  import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
13
- import { withLayout, withTheme } from '@dxos/storybook-utils';
13
+ import { type Meta, withLayout, withTheme } from '@dxos/storybook-utils';
14
14
 
15
- import { Thread, ThreadFooter } from './Thread';
16
15
  import { MessageRoot, MessageTextbox } from '../Message';
17
- import { ThreadStoryContainer, MessageStoryText, type MessageEntity } from '../testing';
18
- import translations from '../translations';
16
+ import { type MessageEntity, MessageStoryText } from '../testing';
17
+ import { translations } from '../translations';
18
+
19
+ import { Thread } from './Thread';
19
20
 
20
21
  faker.seed(1);
21
22
 
@@ -59,13 +60,14 @@ const DefaultStory = () => {
59
60
  };
60
61
 
61
62
  return (
62
- <ThreadStoryContainer>
63
- <Thread id='t1'>
63
+ <div className='mli-auto is-96 overflow-y-auto'>
64
+ <Thread.Root id='t1'>
64
65
  {messages.map((message) => (
65
66
  <MessageRoot key={message.id} classNames={[hoverableControls, hoverableFocusedWithinControls]} {...message}>
66
67
  <MessageStoryText {...message} text={message.text} onDelete={() => console.log('delete')} />
67
68
  </MessageRoot>
68
69
  ))}
70
+
69
71
  <MessageTextbox
70
72
  id={String(_count)}
71
73
  authorId={identityKey1.toHex()}
@@ -73,18 +75,21 @@ const DefaultStory = () => {
73
75
  extensions={extensions}
74
76
  onSend={handleSend}
75
77
  />
76
- <ThreadFooter activity>Processing...</ThreadFooter>
77
- </Thread>
78
- </ThreadStoryContainer>
78
+
79
+ <Thread.Status activity>Processing...</Thread.Status>
80
+ </Thread.Root>
81
+ </div>
79
82
  );
80
83
  };
81
84
 
82
- export default {
85
+ const meta: Meta<typeof Thread.Root> = {
83
86
  title: 'ui/react-ui-thread/Thread',
84
- component: Thread,
87
+ component: Thread.Root,
85
88
  render: DefaultStory,
86
89
  decorators: [withTheme, withLayout({ fullscreen: true })],
87
90
  parameters: { translations },
88
91
  };
89
92
 
93
+ export default meta;
94
+
90
95
  export const Default = {};
@@ -2,20 +2,24 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { CaretDoubleRight, Spinner } from '@phosphor-icons/react';
6
5
  import React, { type ComponentPropsWithRef, forwardRef } from 'react';
7
6
 
8
- import { type ThemedClassName, useTranslation } from '@dxos/react-ui';
7
+ import { Icon, type ThemedClassName, useTranslation } from '@dxos/react-ui';
9
8
  import { hoverableControlItem, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
10
9
 
11
10
  import { translationKey } from '../translations';
12
11
  import type { ThreadEntity } from '../types';
13
12
 
14
- export type ThreadProps = ThemedClassName<ComponentPropsWithRef<'div'>> & ThreadEntity & { current?: boolean };
15
-
13
+ // TODO(burdon): Why is this exported?
16
14
  export const threadLayout = 'is-full place-self-start grid grid-cols-[var(--rail-size)_1fr]';
17
15
 
18
- export const Thread = forwardRef<HTMLDivElement, ThreadProps>(
16
+ //
17
+ // Root
18
+ //
19
+
20
+ type ThreadRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> & ThreadEntity & { current?: boolean };
21
+
22
+ const ThreadRoot = forwardRef<HTMLDivElement, ThreadRootProps>(
19
23
  ({ current, children, classNames, ...props }, forwardedRef) => {
20
24
  return (
21
25
  <div
@@ -26,8 +30,7 @@ export const Thread = forwardRef<HTMLDivElement, ThreadProps>(
26
30
  className={mx(
27
31
  threadLayout,
28
32
  hoverableFocusedWithinControls,
29
- 'pbs-2 pbe-4 bg-[var(--surface-bg)] border-separator first:border-bs-0 border-be',
30
- 'current-related attention-surface [--controls-opacity:0]',
33
+ 'bg-[var(--surface-bg)] current-related attention-surface [--controls-opacity:0]',
31
34
  classNames,
32
35
  )}
33
36
  ref={forwardedRef}
@@ -38,14 +41,18 @@ export const Thread = forwardRef<HTMLDivElement, ThreadProps>(
38
41
  },
39
42
  );
40
43
 
41
- export type ThreadHeadingProps = ThemedClassName<ComponentPropsWithRef<'div'>> & { detached?: boolean };
44
+ //
45
+ // Heading
46
+ //
47
+
48
+ type ThreadHeaderProps = ThemedClassName<ComponentPropsWithRef<'div'>> & { detached?: boolean };
42
49
 
43
- export const ThreadHeading = forwardRef<HTMLParagraphElement, ThreadHeadingProps>(
50
+ const ThreadHeader = forwardRef<HTMLParagraphElement, ThreadHeaderProps>(
44
51
  ({ classNames, children, detached, ...props }, forwardedRef) => {
45
52
  return (
46
53
  <>
47
54
  <div role='none' className='flex items-center justify-center text-description'>
48
- <CaretDoubleRight />
55
+ <Icon icon='ph--caret-double-right--regular' />
49
56
  </div>
50
57
  <div role='none' className='flex items-center overflow-hidden'>
51
58
  <p
@@ -66,11 +73,15 @@ export const ThreadHeading = forwardRef<HTMLParagraphElement, ThreadHeadingProps
66
73
  },
67
74
  );
68
75
 
69
- export type ThreadFooterProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
76
+ //
77
+ // Status
78
+ //
79
+
80
+ type ThreadStatusProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
70
81
  activity?: boolean;
71
82
  };
72
83
 
73
- export const ThreadFooter = forwardRef<HTMLDivElement, ThreadFooterProps>(
84
+ const ThreadStatus = forwardRef<HTMLDivElement, ThreadStatusProps>(
74
85
  ({ activity, classNames, children, ...props }, forwardedRef) => {
75
86
  const { t } = useTranslation(translationKey);
76
87
  return (
@@ -82,10 +93,10 @@ export const ThreadFooter = forwardRef<HTMLDivElement, ThreadFooterProps>(
82
93
  )}
83
94
  ref={forwardedRef}
84
95
  >
85
- <Spinner
86
- weight='bold'
96
+ <Icon
97
+ icon='ph--spinner--bold'
98
+ classNames='is-6 bs-4 invisible data-[visible=show]:visible animate-spin-slow'
87
99
  data-visible={activity ? 'show' : 'hide'}
88
- className='is-6 bs-4 invisible data-[visible=show]:visible animate-spin-slow'
89
100
  />
90
101
  <span className='truncate min-is-0' aria-live='polite'>
91
102
  {activity ? children : null}
@@ -95,3 +106,11 @@ export const ThreadFooter = forwardRef<HTMLDivElement, ThreadFooterProps>(
95
106
  );
96
107
  },
97
108
  );
109
+
110
+ export const Thread = {
111
+ Root: ThreadRoot,
112
+ Header: ThreadHeader,
113
+ Status: ThreadStatus,
114
+ };
115
+
116
+ export type { ThreadRootProps, ThreadHeaderProps as ThreadHeadingProps, ThreadStatusProps };
package/src/index.ts CHANGED
@@ -2,9 +2,9 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import translations from './translations';
5
+ import { translations } from './translations';
6
6
 
7
7
  export * from './Thread';
8
8
  export * from './Message';
9
- export * from './types';
9
+ export type * from './types';
10
10
  export { translations };
package/src/testing.tsx CHANGED
@@ -2,10 +2,9 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { X } from '@phosphor-icons/react';
6
- import React, { type PropsWithChildren } from 'react';
5
+ import React from 'react';
7
6
 
8
- import { Button } from '@dxos/react-ui';
7
+ import { Button, Icon } from '@dxos/react-ui';
9
8
  import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
10
9
 
11
10
  import { MessageBody, MessageHeading } from './Message';
@@ -31,7 +30,7 @@ export const MessageStoryText = ({ text, onDelete, authorName, timestamp }: Mess
31
30
  classNames={['p-1.5 min-bs-0 mie-1 items-start transition-opacity', hoverableControlItem]}
32
31
  onClick={() => onDelete()}
33
32
  >
34
- <X />
33
+ <Icon icon='ph--x--regular' />
35
34
  </Button>
36
35
  )}
37
36
  </MessageHeading>
@@ -56,7 +55,3 @@ export const MessageStoryBlock = <PartValue,>({ part }: MessagePartProps<PartVal
56
55
  </div>
57
56
  );
58
57
  };
59
-
60
- export const ThreadStoryContainer = ({ children }: PropsWithChildren) => {
61
- return <div className={mx('bg-white dark:bg-black mli-auto is-96 overflow-y-auto')}>{children}</div>;
62
- };
@@ -2,9 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export const translationKey = 'thread';
5
+ import { type Resource } from '@dxos/react-ui';
6
6
 
7
- export default [
7
+ export const translationKey = 'react-ui-thread';
8
+
9
+ export const translations = [
8
10
  {
9
11
  'en-US': {
10
12
  [translationKey]: {
@@ -21,4 +23,4 @@ export default [
21
23
  },
22
24
  },
23
25
  },
24
- ];
26
+ ] as const satisfies Resource[];