@dxos/react-ui-thread 0.8.3-staging.0fa589b → 0.8.4-main.3f58842

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.3f58842",
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",
@@ -26,32 +26,30 @@
26
26
  "@preact-signals/safe-react": "^0.9.0",
27
27
  "@radix-ui/react-primitive": "2.0.2",
28
28
  "date-fns": "^3.3.1",
29
- "@dxos/react-ui-editor": "0.8.3-staging.0fa589b",
30
- "@dxos/util": "0.8.3-staging.0fa589b"
29
+ "@dxos/util": "0.8.4-main.3f58842",
30
+ "@dxos/react-ui-editor": "0.8.4-main.3f58842"
31
31
  },
32
32
  "devDependencies": {
33
- "@phosphor-icons/react": "^2.1.5",
34
33
  "@types/react": "~18.2.0",
35
34
  "@types/react-dom": "~18.2.0",
36
35
  "react": "~18.2.0",
37
36
  "react-dom": "~18.2.0",
38
37
  "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"
38
+ "@dxos/echo-db": "0.8.4-main.3f58842",
39
+ "@dxos/echo-schema": "0.8.4-main.3f58842",
40
+ "@dxos/live-object": "0.8.4-main.3f58842",
41
+ "@dxos/keys": "0.8.4-main.3f58842",
42
+ "@dxos/log": "0.8.4-main.3f58842",
43
+ "@dxos/react-ui": "0.8.4-main.3f58842",
44
+ "@dxos/random": "0.8.4-main.3f58842",
45
+ "@dxos/react-ui-theme": "0.8.4-main.3f58842",
46
+ "@dxos/storybook-utils": "0.8.4-main.3f58842"
48
47
  },
49
48
  "peerDependencies": {
50
- "@phosphor-icons/react": "^2.1.5",
51
49
  "react": "~18.2.0",
52
50
  "react-dom": "~18.2.0",
53
- "@dxos/react-ui": "0.8.3-staging.0fa589b",
54
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b"
51
+ "@dxos/react-ui": "0.8.4-main.3f58842",
52
+ "@dxos/react-ui-theme": "0.8.4-main.3f58842"
55
53
  },
56
54
  "publishConfig": {
57
55
  "access": "public"
@@ -11,9 +11,9 @@ import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-u
11
11
  import { withLayout, withTheme } from '@dxos/storybook-utils';
12
12
 
13
13
  import { MessageRoot } from './Message';
14
- import { threadLayout } from '../Thread';
15
- import { ThreadStoryContainer, MessageStoryText, type MessageEntity } from '../testing';
16
- import translations from '../translations';
14
+ import { Thread } from '../Thread';
15
+ import { MessageStoryText, type MessageEntity } from '../testing';
16
+ import { translations } from '../translations';
17
17
 
18
18
  const DefaultStory = () => {
19
19
  const [identityKey] = useState(PublicKey.random());
@@ -25,13 +25,13 @@ const DefaultStory = () => {
25
25
  });
26
26
 
27
27
  return (
28
- <ThreadStoryContainer>
29
- <div className={threadLayout}>
28
+ <div className='mli-auto is-96 overflow-y-auto'>
29
+ <Thread.Root id='t1'>
30
30
  <MessageRoot {...message} classNames={[hoverableControls, hoverableFocusedWithinControls]}>
31
31
  <MessageStoryText {...message} onDelete={() => console.log('delete')} />
32
32
  </MessageRoot>
33
- </div>
34
- </ThreadStoryContainer>
33
+ </Thread.Root>
34
+ </div>
35
35
  );
36
36
  };
37
37
 
@@ -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,10 @@ 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';
32
+ import { Thread } from './Thread';
34
33
  import { MessageBody, MessageHeading, MessageRoot, MessageTextbox } from '../Message';
35
34
  import { type MessageEntity } from '../testing';
36
- import translations from '../translations';
35
+ import { translations } from '../translations';
37
36
 
38
37
  faker.seed(101);
39
38
 
@@ -157,17 +156,17 @@ const StoryThread: FC<{
157
156
  };
158
157
 
159
158
  return (
160
- <Thread current={selected} onClickCapture={onSelect}>
159
+ <Thread.Root current={selected} onClickCapture={onSelect}>
161
160
  <div className='col-start-2 flex gap-1 text-xs text-description'>
162
161
  <span>id:{thread.id.slice(0, 4)}</span>
163
162
  <span>y:{thread.yPos}</span>
164
163
  <span className='grow' />
165
- {!thread.cursor && <Trash />}
164
+ {!thread.cursor && <Icon icon='ph--trash--regular' />}
166
165
  </div>
167
166
 
168
- <ThreadHeading>
167
+ <Thread.Header>
169
168
  {thread.range?.from} &ndash; {thread.range?.to}
170
- </ThreadHeading>
169
+ </Thread.Header>
171
170
 
172
171
  {thread.messages.map((message) => (
173
172
  <MessageRoot key={message.id} classNames={[hoverableControls, hoverableFocusedWithinControls]} {...message}>
@@ -185,12 +184,12 @@ const StoryThread: FC<{
185
184
  onEditorFocus={onSelect}
186
185
  onSend={handleCreateMessage}
187
186
  />
188
- <ThreadFooter />
187
+ <Thread.Status />
189
188
  <Button variant='ghost' classNames='px-1' title='Resolve' onClick={onResolve}>
190
- <Check />
189
+ <Icon icon='ph--check--regular' />
191
190
  </Button>
192
191
  </div>
193
- </Thread>
192
+ </Thread.Root>
194
193
  );
195
194
  };
196
195
 
@@ -359,15 +358,13 @@ export default {
359
358
 
360
359
  const str = (...lines: string[]) => lines.join('\n');
361
360
 
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
361
  export const Default = {
370
362
  args: {
371
- text: document,
363
+ text: str(
364
+ '# Comments',
365
+ '',
366
+ str(...faker.helpers.multiple(() => [faker.lorem.paragraph({ min: 5, max: 10 }), ''], { count: 20 }).flat()),
367
+ '',
368
+ ),
372
369
  },
373
370
  };
@@ -10,12 +10,12 @@ 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';
15
+ import { Thread } from './Thread';
16
16
  import { MessageRoot, MessageTextbox } from '../Message';
17
- import { ThreadStoryContainer, MessageStoryText, type MessageEntity } from '../testing';
18
- import translations from '../translations';
17
+ import { MessageStoryText, type MessageEntity } from '../testing';
18
+ import { translations } from '../translations';
19
19
 
20
20
  faker.seed(1);
21
21
 
@@ -59,13 +59,14 @@ const DefaultStory = () => {
59
59
  };
60
60
 
61
61
  return (
62
- <ThreadStoryContainer>
63
- <Thread id='t1'>
62
+ <div className='mli-auto is-96 overflow-y-auto'>
63
+ <Thread.Root id='t1'>
64
64
  {messages.map((message) => (
65
65
  <MessageRoot key={message.id} classNames={[hoverableControls, hoverableFocusedWithinControls]} {...message}>
66
66
  <MessageStoryText {...message} text={message.text} onDelete={() => console.log('delete')} />
67
67
  </MessageRoot>
68
68
  ))}
69
+
69
70
  <MessageTextbox
70
71
  id={String(_count)}
71
72
  authorId={identityKey1.toHex()}
@@ -73,18 +74,21 @@ const DefaultStory = () => {
73
74
  extensions={extensions}
74
75
  onSend={handleSend}
75
76
  />
76
- <ThreadFooter activity>Processing...</ThreadFooter>
77
- </Thread>
78
- </ThreadStoryContainer>
77
+
78
+ <Thread.Status activity>Processing...</Thread.Status>
79
+ </Thread.Root>
80
+ </div>
79
81
  );
80
82
  };
81
83
 
82
- export default {
84
+ const meta: Meta<typeof Thread.Root> = {
83
85
  title: 'ui/react-ui-thread/Thread',
84
- component: Thread,
86
+ component: Thread.Root,
85
87
  render: DefaultStory,
86
88
  decorators: [withTheme, withLayout({ fullscreen: true })],
87
89
  parameters: { translations },
88
90
  };
89
91
 
92
+ export default meta;
93
+
90
94
  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'
87
98
  data-visible={activity ? 'show' : 'hide'}
88
- className='is-6 bs-4 invisible data-[visible=show]:visible animate-spin-slow'
99
+ classNames='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[];