@dxos/react-ui-thread 0.6.5 → 0.6.6-staging.23d123d
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/dist/lib/browser/index.mjs +85 -58
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/Message/Message.d.ts +13 -7
- package/dist/types/src/Message/Message.d.ts.map +1 -1
- package/dist/types/src/Message/Message.stories.d.ts +2 -2
- package/dist/types/src/Message/Message.stories.d.ts.map +1 -1
- package/dist/types/src/Thread/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/Thread/Thread.d.ts.map +1 -1
- package/dist/types/src/Thread/Thread.stories.d.ts.map +1 -1
- package/dist/types/src/testing.d.ts +5 -4
- package/dist/types/src/testing.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/Message/Message.stories.tsx +14 -10
- package/src/Message/Message.tsx +52 -29
- package/src/Thread/Comments.stories.tsx +7 -29
- package/src/Thread/Thread.stories.tsx +34 -33
- package/src/Thread/Thread.tsx +18 -18
- package/src/testing.tsx +23 -20
- package/src/types.ts +1 -1
|
@@ -20,7 +20,7 @@ var translations_default = [
|
|
|
20
20
|
];
|
|
21
21
|
|
|
22
22
|
// packages/ui/react-ui-thread/src/Thread/Thread.tsx
|
|
23
|
-
import {
|
|
23
|
+
import { CaretDoubleRight, Spinner } from "@phosphor-icons/react";
|
|
24
24
|
import React, { forwardRef } from "react";
|
|
25
25
|
import { useTranslation } from "@dxos/react-ui";
|
|
26
26
|
import { hoverableControlItem, hoverableFocusedWithinControls, mx } from "@dxos/react-ui-theme";
|
|
@@ -33,27 +33,30 @@ var Thread = /* @__PURE__ */ forwardRef(({ current, children, classNames, ...pro
|
|
|
33
33
|
"aria-current": typeof current === "string" ? current : "location"
|
|
34
34
|
},
|
|
35
35
|
...props,
|
|
36
|
-
className: mx(threadLayout, hoverableFocusedWithinControls, "bg-[var(--surface-bg)] border-[color:var(--surface-separator)] border-bs border-be
|
|
36
|
+
className: mx(threadLayout, hoverableFocusedWithinControls, "plb-1.5 bg-[var(--surface-bg)] border-[color:var(--surface-separator)] border-bs border-be", "attention attention-within attention-current [--controls-opacity:0]", classNames),
|
|
37
37
|
ref: forwardedRef
|
|
38
38
|
}, children);
|
|
39
39
|
});
|
|
40
40
|
var ThreadHeading = /* @__PURE__ */ forwardRef(({ classNames, children, detached, ...props }, forwardedRef) => {
|
|
41
41
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
|
|
42
42
|
role: "none",
|
|
43
|
-
className: "
|
|
44
|
-
}, /* @__PURE__ */ React.createElement(
|
|
43
|
+
className: "flex items-center justify-center fg-description"
|
|
44
|
+
}, /* @__PURE__ */ React.createElement(CaretDoubleRight, null)), /* @__PURE__ */ React.createElement("div", {
|
|
45
|
+
role: "none",
|
|
46
|
+
className: "flex items-center overflow-hidden"
|
|
47
|
+
}, /* @__PURE__ */ React.createElement("p", {
|
|
45
48
|
role: "heading",
|
|
46
49
|
"data-testid": "thread.heading",
|
|
47
50
|
...props,
|
|
48
|
-
className: mx("fg-description font-medium truncate
|
|
51
|
+
className: mx("mie-2 fg-description font-medium truncate italic", detached && "line-through decoration-1"),
|
|
49
52
|
ref: forwardedRef
|
|
50
|
-
}, children));
|
|
53
|
+
}, children)));
|
|
51
54
|
});
|
|
52
55
|
var ThreadFooter = /* @__PURE__ */ forwardRef(({ activity, classNames, children, ...props }, forwardedRef) => {
|
|
53
56
|
const { t } = useTranslation(translationKey);
|
|
54
57
|
return /* @__PURE__ */ React.createElement("div", {
|
|
55
58
|
...props,
|
|
56
|
-
className: mx("col-start-2 grid grid-cols-[min-content_1fr_max-content] text-xs fg-description
|
|
59
|
+
className: mx("col-start-2 grid grid-cols-[min-content_1fr_max-content] pb-2 pie-2 text-xs fg-description", classNames),
|
|
57
60
|
ref: forwardedRef
|
|
58
61
|
}, /* @__PURE__ */ React.createElement(Spinner, {
|
|
59
62
|
weight: "bold",
|
|
@@ -63,7 +66,7 @@ var ThreadFooter = /* @__PURE__ */ forwardRef(({ activity, classNames, children,
|
|
|
63
66
|
className: "truncate min-is-0",
|
|
64
67
|
"aria-live": "polite"
|
|
65
68
|
}, activity ? children : null), /* @__PURE__ */ React.createElement("span", {
|
|
66
|
-
className: mx("text-end
|
|
69
|
+
className: mx("text-end", hoverableControlItem)
|
|
67
70
|
}, t("enter to send message")));
|
|
68
71
|
});
|
|
69
72
|
|
|
@@ -71,58 +74,70 @@ var ThreadFooter = /* @__PURE__ */ forwardRef(({ activity, classNames, children,
|
|
|
71
74
|
import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
|
|
72
75
|
import React2, { forwardRef as forwardRef2, useMemo } from "react";
|
|
73
76
|
import { Avatar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
74
|
-
import { keymap, listener,
|
|
77
|
+
import { keymap, listener, useTextEditor } from "@dxos/react-ui-editor";
|
|
75
78
|
import { focusRing, mx as mx2 } from "@dxos/react-ui-theme";
|
|
76
79
|
import { hexToEmoji, hexToHue, isNotFalsy } from "@dxos/util";
|
|
77
80
|
var avatarSize = 7;
|
|
78
|
-
var
|
|
79
|
-
return
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
81
|
+
var MessageRoot = /* @__PURE__ */ forwardRef2(({ authorImgSrc, authorId, authorName, authorAvatarProps, continues = true, children, classNames, ...rootProps }, forwardedRef) => {
|
|
82
|
+
return (
|
|
83
|
+
// Must wrap the message since Avatar.Label may be used in the content.
|
|
84
|
+
/* @__PURE__ */ React2.createElement(Avatar.Root, {
|
|
85
|
+
size: avatarSize,
|
|
86
|
+
hue: authorAvatarProps?.hue || hexToHue(authorId ?? "0")
|
|
87
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
88
|
+
role: "none",
|
|
89
|
+
"data-testid": "thread.message",
|
|
90
|
+
...rootProps,
|
|
91
|
+
className: mx2("grid grid-cols-subgrid col-span-2", classNames),
|
|
92
|
+
ref: forwardedRef
|
|
93
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
94
|
+
role: "none",
|
|
95
|
+
className: "flex flex-col items-center gap-2 pbs-2"
|
|
96
|
+
}, /* @__PURE__ */ React2.createElement(Avatar.Frame, null, /* @__PURE__ */ React2.createElement(Avatar.Fallback, {
|
|
97
|
+
text: authorAvatarProps?.emoji || hexToEmoji(authorId ?? "0")
|
|
98
|
+
}), authorImgSrc && /* @__PURE__ */ React2.createElement(Avatar.Image, {
|
|
99
|
+
href: authorImgSrc
|
|
100
|
+
})), continues && /* @__PURE__ */ React2.createElement("div", {
|
|
101
|
+
role: "none",
|
|
102
|
+
className: "is-px grow surface-separator"
|
|
103
|
+
})), /* @__PURE__ */ React2.createElement("div", {
|
|
104
|
+
role: "none",
|
|
105
|
+
className: "plb-1 min-is-0"
|
|
106
|
+
}, children)))
|
|
107
|
+
);
|
|
102
108
|
});
|
|
103
|
-
var
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
continues: true
|
|
109
|
+
var MessageHeading = ({ children, classNames, timestamp, authorName, ...props }) => {
|
|
110
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
111
|
+
role: "none",
|
|
112
|
+
...props,
|
|
113
|
+
className: mx2("flex gap-2 items-start", classNames)
|
|
109
114
|
}, /* @__PURE__ */ React2.createElement("p", {
|
|
110
|
-
className: "
|
|
111
|
-
}, /* @__PURE__ */ React2.createElement(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
className: "grow"
|
|
116
|
+
}, /* @__PURE__ */ React2.createElement(MessageAuthorName, {
|
|
117
|
+
authorName
|
|
118
|
+
}), timestamp && /* @__PURE__ */ React2.createElement(MessageTime, {
|
|
119
|
+
timestamp
|
|
120
|
+
})), children);
|
|
121
|
+
};
|
|
122
|
+
var MessageAuthorName = ({ authorName }) => {
|
|
123
|
+
const { t } = useTranslation2(translationKey);
|
|
124
|
+
return /* @__PURE__ */ React2.createElement(Avatar.Label, {
|
|
125
|
+
classNames: "block truncate text-sm fg-subdued"
|
|
126
|
+
}, authorName ?? t("anonymous label"));
|
|
127
|
+
};
|
|
128
|
+
var MessageTime = ({ timestamp }) => {
|
|
129
|
+
const { dtLocale } = useTranslation2(translationKey);
|
|
130
|
+
const dt = timestamp ? new Date(timestamp) : void 0;
|
|
131
|
+
return /* @__PURE__ */ React2.createElement("time", {
|
|
132
|
+
className: "block fg-subdued text-xs pbe-0.5",
|
|
118
133
|
dateTime: dt?.toISOString()
|
|
119
134
|
}, dt ? formatDistanceToNow(dt, {
|
|
120
135
|
locale: dtLocale,
|
|
121
136
|
addSuffix: true
|
|
122
|
-
}) : "")
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
137
|
+
}) : "");
|
|
138
|
+
};
|
|
139
|
+
var MessageBody = ({ children, ...props }) => {
|
|
140
|
+
return /* @__PURE__ */ React2.createElement("p", props, children);
|
|
126
141
|
};
|
|
127
142
|
var keyBindings = ({ onSend, onClear }) => [
|
|
128
143
|
{
|
|
@@ -168,23 +183,35 @@ var MessageTextbox = ({ id, onSend, onClear, onEditorFocus, authorId, authorName
|
|
|
168
183
|
}, [
|
|
169
184
|
_extensions
|
|
170
185
|
]);
|
|
171
|
-
|
|
186
|
+
const { parentRef, focusAttributes } = useTextEditor(() => ({
|
|
187
|
+
id,
|
|
188
|
+
extensions,
|
|
189
|
+
...editorProps
|
|
190
|
+
}), [
|
|
191
|
+
id,
|
|
192
|
+
extensions
|
|
193
|
+
]);
|
|
194
|
+
return /* @__PURE__ */ React2.createElement(MessageRoot, {
|
|
172
195
|
id,
|
|
173
196
|
authorId,
|
|
174
197
|
authorName,
|
|
175
198
|
authorImgSrc,
|
|
176
199
|
authorAvatarProps,
|
|
177
200
|
continues: false
|
|
178
|
-
}, /* @__PURE__ */ React2.createElement(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
className: mx2("plb-0.5 mie-1 rounded-sm", focusRing, disabled && "opacity-50")
|
|
201
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
202
|
+
role: "none",
|
|
203
|
+
ref: parentRef,
|
|
204
|
+
className: mx2("plb-0.5 mie-1 rounded-sm", focusRing, disabled && "opacity-50"),
|
|
205
|
+
...focusAttributes
|
|
182
206
|
}));
|
|
183
207
|
};
|
|
184
208
|
export {
|
|
185
|
-
|
|
186
|
-
|
|
209
|
+
MessageAuthorName,
|
|
210
|
+
MessageBody,
|
|
211
|
+
MessageHeading,
|
|
212
|
+
MessageRoot,
|
|
187
213
|
MessageTextbox,
|
|
214
|
+
MessageTime,
|
|
188
215
|
Thread,
|
|
189
216
|
ThreadFooter,
|
|
190
217
|
ThreadHeading,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/translations.ts", "../../../src/Thread/Thread.tsx", "../../../src/Message/Message.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nexport const translationKey = 'thread';\n\nexport default [\n {\n 'en-US': {\n [translationKey]: {\n 'plugin name': 'Threads',\n 'thread title placeholder': 'New thread',\n 'thread title label': 'Title',\n 'delete thread label': 'Delete',\n 'create thread label': 'Create thread',\n 'message placeholder': 'Enter message...',\n 'comment placeholder': 'Enter comment...',\n 'settings standalone label': 'Enable standalone thread creation',\n 'anonymous label': 'Anonymous',\n 'enter to send message': 'Enter to add ⏎',\n },\n },\n },\n];\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport {
|
|
5
|
-
"mappings": ";AAIO,IAAMA,iBAAiB;AAE9B,IAAA,uBAAe;EACb;IACE,SAAS;MACP,CAACA,cAAAA,GAAiB;QAChB,eAAe;QACf,4BAA4B;QAC5B,sBAAsB;QACtB,uBAAuB;QACvB,uBAAuB;QACvB,uBAAuB;QACvB,uBAAuB;QACvB,6BAA6B;QAC7B,mBAAmB;QACnB,yBAAyB;MAC3B;IACF;EACF;;;;AClBF,SAASC,
|
|
6
|
-
"names": ["translationKey", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nexport const translationKey = 'thread';\n\nexport default [\n {\n 'en-US': {\n [translationKey]: {\n 'plugin name': 'Threads',\n 'thread title placeholder': 'New thread',\n 'thread title label': 'Title',\n 'delete thread label': 'Delete',\n 'create thread label': 'Create thread',\n 'message placeholder': 'Enter message...',\n 'comment placeholder': 'Enter comment...',\n 'settings standalone label': 'Enable standalone thread creation',\n 'anonymous label': 'Anonymous',\n 'enter to send message': 'Enter to add ⏎',\n },\n },\n },\n];\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CaretDoubleRight, Spinner } from '@phosphor-icons/react';\nimport React, { type ComponentProps, type ComponentPropsWithRef, forwardRef } from 'react';\n\nimport { type ThemedClassName, useTranslation } from '@dxos/react-ui';\nimport { hoverableControlItem, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';\n\nimport { translationKey } from '../translations';\nimport type { ThreadEntity } from '../types';\n\nexport type ThreadProps = ThemedClassName<ComponentPropsWithRef<'div'>> &\n ThreadEntity & { current?: boolean | ComponentProps<'div'>['aria-current'] };\n\nexport const threadLayout = 'is-full place-self-start grid grid-cols-[var(--rail-size)_1fr]';\n\nexport const Thread = forwardRef<HTMLDivElement, ThreadProps>(\n ({ current, children, classNames, ...props }, forwardedRef) => {\n return (\n <div\n role='group'\n data-testid='thread'\n {...(current && { 'aria-current': typeof current === 'string' ? current : 'location' })}\n {...props}\n className={mx(\n threadLayout,\n hoverableFocusedWithinControls,\n 'plb-1.5 bg-[var(--surface-bg)] border-[color:var(--surface-separator)] border-bs border-be',\n 'attention attention-within attention-current [--controls-opacity:0]',\n classNames,\n )}\n ref={forwardedRef}\n >\n {children}\n </div>\n );\n },\n);\n\nexport type ThreadHeadingProps = ThemedClassName<ComponentPropsWithRef<'div'>> & { detached?: boolean };\n\nexport const ThreadHeading = forwardRef<HTMLParagraphElement, ThreadHeadingProps>(\n ({ classNames, children, detached, ...props }, forwardedRef) => {\n return (\n <>\n <div role='none' className='flex items-center justify-center fg-description'>\n <CaretDoubleRight />\n </div>\n <div role='none' className='flex items-center overflow-hidden'>\n <p\n role='heading'\n data-testid='thread.heading'\n {...props}\n className={mx('mie-2 fg-description font-medium truncate italic', detached && 'line-through decoration-1')}\n ref={forwardedRef}\n >\n {children}\n </p>\n </div>\n </>\n );\n },\n);\n\nexport type ThreadFooterProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {\n activity?: boolean;\n};\n\nexport const ThreadFooter = forwardRef<HTMLDivElement, ThreadFooterProps>(\n ({ activity, classNames, children, ...props }, forwardedRef) => {\n const { t } = useTranslation(translationKey);\n return (\n <div\n {...props}\n className={mx(\n 'col-start-2 grid grid-cols-[min-content_1fr_max-content] pb-2 pie-2 text-xs fg-description',\n classNames,\n )}\n ref={forwardedRef}\n >\n <Spinner\n weight='bold'\n data-visible={activity ? 'show' : 'hide'}\n className='is-6 bs-4 invisible data-[visible=show]:visible animate-spin-slow'\n />\n <span className='truncate min-is-0' aria-live='polite'>\n {activity ? children : null}\n </span>\n <span className={mx('text-end', hoverableControlItem)}>{t('enter to send message')}</span>\n </div>\n );\n },\n);\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { formatDistanceToNow } from 'date-fns/formatDistanceToNow';\nimport React, { type ComponentPropsWithRef, forwardRef, useMemo, type ComponentPropsWithoutRef } from 'react';\n\n// TODO(burdon): Remove dep.\nimport { Avatar, type ThemedClassName, useTranslation } from '@dxos/react-ui';\nimport { type UseTextEditorProps, keymap, listener, useTextEditor } from '@dxos/react-ui-editor';\nimport { focusRing, mx } from '@dxos/react-ui-theme';\nimport { hexToEmoji, hexToHue, isNotFalsy } from '@dxos/util';\n\nimport { translationKey } from '../translations';\nimport { type MessageMetadata } from '../types';\n\nconst avatarSize = 7;\n\nexport type MessageRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> &\n MessageMetadata &\n Partial<{ continues: boolean }>;\n\nexport const MessageRoot = forwardRef<HTMLDivElement, MessageRootProps>(\n (\n { authorImgSrc, authorId, authorName, authorAvatarProps, continues = true, children, classNames, ...rootProps },\n forwardedRef,\n ) => {\n return (\n // Must wrap the message since Avatar.Label may be used in the content.\n <Avatar.Root size={avatarSize} hue={authorAvatarProps?.hue || hexToHue(authorId ?? '0')}>\n <div\n role='none'\n data-testid='thread.message'\n {...rootProps}\n className={mx('grid grid-cols-subgrid col-span-2', classNames)}\n ref={forwardedRef}\n >\n <div role='none' className='flex flex-col items-center gap-2 pbs-2'>\n <Avatar.Frame>\n <Avatar.Fallback text={authorAvatarProps?.emoji || hexToEmoji(authorId ?? '0')} />\n {authorImgSrc && <Avatar.Image href={authorImgSrc} />}\n </Avatar.Frame>\n {continues && <div role='none' className='is-px grow surface-separator' />}\n </div>\n <div role='none' className='plb-1 min-is-0'>\n {children}\n </div>\n </div>\n </Avatar.Root>\n );\n },\n);\n\nexport type MessageHeadingProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> &\n Pick<MessageMetadata, 'authorName' | 'timestamp'>;\n\nexport const MessageHeading = ({ children, classNames, timestamp, authorName, ...props }: MessageHeadingProps) => {\n return (\n <div role='none' {...props} className={mx('flex gap-2 items-start', classNames)}>\n <p className='grow'>\n <MessageAuthorName authorName={authorName} />\n {timestamp && <MessageTime timestamp={timestamp} />}\n </p>\n {children}\n </div>\n );\n};\n\nexport type MessageAuthorNameProps = Pick<MessageMetadata, 'authorName'>;\n\nexport const MessageAuthorName = ({ authorName }: MessageAuthorNameProps) => {\n const { t } = useTranslation(translationKey);\n return (\n <Avatar.Label classNames='block truncate text-sm fg-subdued'>{authorName ?? t('anonymous label')}</Avatar.Label>\n );\n};\n\nexport type MessageTimeProps = Pick<MessageMetadata, 'timestamp'>;\n\nexport const MessageTime = ({ timestamp }: MessageTimeProps) => {\n const { dtLocale } = useTranslation(translationKey);\n const dt = timestamp ? new Date(timestamp) : undefined;\n return (\n <time className='block fg-subdued text-xs pbe-0.5' dateTime={dt?.toISOString()}>\n {dt ? formatDistanceToNow(dt, { locale: dtLocale, addSuffix: true }) : ''}\n </time>\n );\n};\n\nexport type MessageBodyProps = ComponentPropsWithoutRef<'p'>;\n\nexport const MessageBody = ({ children, ...props }: MessageBodyProps) => {\n return <p {...props}>{children}</p>;\n};\n\nexport type MessageTextboxProps = {\n disabled?: boolean;\n onSend?: () => void;\n onClear?: () => void;\n onEditorFocus?: () => void;\n} & MessageMetadata &\n UseTextEditorProps;\n\nconst keyBindings = ({ onSend, onClear }: Pick<MessageTextboxProps, 'onSend' | 'onClear'>) => [\n {\n key: 'Enter',\n run: () => {\n if (onSend) {\n onSend();\n return true;\n } else {\n return false;\n }\n },\n },\n {\n // TODO(burdon): Other key bindings.\n key: 'Meta+Backspace',\n run: () => {\n if (onClear) {\n onClear();\n return true;\n } else {\n return false;\n }\n },\n },\n];\n\nexport const MessageTextbox = ({\n id,\n onSend,\n onClear,\n onEditorFocus,\n authorId,\n authorName,\n authorImgSrc,\n authorAvatarProps,\n disabled,\n extensions: _extensions,\n ...editorProps\n}: MessageTextboxProps) => {\n const extensions = useMemo<UseTextEditorProps['extensions']>(() => {\n return [\n keymap.of(keyBindings({ onSend, onClear })),\n listener({\n onFocus: (focusing) => {\n if (focusing) {\n onEditorFocus?.();\n }\n },\n }),\n _extensions,\n ].filter(isNotFalsy);\n // TODO(wittjosiah): Should probably include callbacks in the dependency array.\n }, [_extensions]);\n\n const { parentRef, focusAttributes } = useTextEditor(() => ({ id, extensions, ...editorProps }), [id, extensions]);\n\n return (\n <MessageRoot {...{ id, authorId, authorName, authorImgSrc, authorAvatarProps }} continues={false}>\n <div\n role='none'\n ref={parentRef}\n className={mx('plb-0.5 mie-1 rounded-sm', focusRing, disabled && 'opacity-50')}\n {...focusAttributes}\n />\n </MessageRoot>\n );\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["translationKey", "CaretDoubleRight", "Spinner", "React", "forwardRef", "useTranslation", "hoverableControlItem", "hoverableFocusedWithinControls", "mx", "threadLayout", "Thread", "forwardRef", "current", "children", "classNames", "props", "forwardedRef", "div", "role", "data-testid", "className", "mx", "hoverableFocusedWithinControls", "ref", "ThreadHeading", "detached", "CaretDoubleRight", "p", "ThreadFooter", "activity", "t", "useTranslation", "translationKey", "Spinner", "weight", "data-visible", "span", "aria-live", "hoverableControlItem", "formatDistanceToNow", "React", "forwardRef", "useMemo", "Avatar", "useTranslation", "keymap", "listener", "useTextEditor", "focusRing", "mx", "hexToEmoji", "hexToHue", "isNotFalsy", "avatarSize", "MessageRoot", "forwardRef", "authorImgSrc", "authorId", "authorName", "authorAvatarProps", "continues", "children", "classNames", "rootProps", "forwardedRef", "React", "Avatar", "Root", "size", "hue", "hexToHue", "div", "role", "data-testid", "className", "mx", "ref", "Frame", "Fallback", "text", "emoji", "hexToEmoji", "Image", "href", "MessageHeading", "timestamp", "props", "p", "MessageAuthorName", "MessageTime", "t", "useTranslation", "translationKey", "Label", "dtLocale", "dt", "Date", "undefined", "time", "dateTime", "toISOString", "formatDistanceToNow", "locale", "addSuffix", "MessageBody", "keyBindings", "onSend", "onClear", "key", "run", "MessageTextbox", "id", "onEditorFocus", "disabled", "extensions", "_extensions", "editorProps", "useMemo", "keymap", "of", "listener", "onFocus", "focusing", "filter", "isNotFalsy", "parentRef", "focusAttributes", "useTextEditor", "focusRing"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/react-ui-thread/src/translations.ts":{"bytes":2337,"imports":[],"format":"esm"},"packages/ui/react-ui-thread/src/Thread/Thread.tsx":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/react-ui-thread/src/translations.ts":{"bytes":2337,"imports":[],"format":"esm"},"packages/ui/react-ui-thread/src/Thread/Thread.tsx":{"bytes":9690,"imports":[{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-thread/src/translations.ts","kind":"import-statement","original":"../translations"}],"format":"esm"},"packages/ui/react-ui-thread/src/Thread/index.ts":{"bytes":500,"imports":[{"path":"packages/ui/react-ui-thread/src/Thread/Thread.tsx","kind":"import-statement","original":"./Thread"}],"format":"esm"},"packages/ui/react-ui-thread/src/Message/Message.tsx":{"bytes":17430,"imports":[{"path":"date-fns/formatDistanceToNow","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-editor","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-thread/src/translations.ts","kind":"import-statement","original":"../translations"}],"format":"esm"},"packages/ui/react-ui-thread/src/Message/index.ts":{"bytes":506,"imports":[{"path":"packages/ui/react-ui-thread/src/Message/Message.tsx","kind":"import-statement","original":"./Message"}],"format":"esm"},"packages/ui/react-ui-thread/src/types.ts":{"bytes":863,"imports":[],"format":"esm"},"packages/ui/react-ui-thread/src/index.ts":{"bytes":913,"imports":[{"path":"packages/ui/react-ui-thread/src/translations.ts","kind":"import-statement","original":"./translations"},{"path":"packages/ui/react-ui-thread/src/Thread/index.ts","kind":"import-statement","original":"./Thread"},{"path":"packages/ui/react-ui-thread/src/Message/index.ts","kind":"import-statement","original":"./Message"},{"path":"packages/ui/react-ui-thread/src/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-thread/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":15291},"packages/ui/react-ui-thread/dist/lib/browser/index.mjs":{"imports":[{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"date-fns/formatDistanceToNow","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-editor","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["MessageAuthorName","MessageBody","MessageHeading","MessageRoot","MessageTextbox","MessageTime","Thread","ThreadFooter","ThreadHeading","threadLayout","translations"],"entryPoint":"packages/ui/react-ui-thread/src/index.ts","inputs":{"packages/ui/react-ui-thread/src/translations.ts":{"bytesInOutput":609},"packages/ui/react-ui-thread/src/Thread/Thread.tsx":{"bytesInOutput":2574},"packages/ui/react-ui-thread/src/Thread/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-thread/src/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-thread/src/Message/Message.tsx":{"bytesInOutput":4427},"packages/ui/react-ui-thread/src/Message/index.ts":{"bytesInOutput":0}},"bytes":8018}}}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import React, { type ComponentPropsWithRef, type
|
|
1
|
+
import React, { type ComponentPropsWithRef, type ComponentPropsWithoutRef } from 'react';
|
|
2
2
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
3
|
-
import { type
|
|
3
|
+
import { type UseTextEditorProps } from '@dxos/react-ui-editor';
|
|
4
4
|
import { type MessageMetadata } from '../types';
|
|
5
|
-
export type
|
|
5
|
+
export type MessageRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> & MessageMetadata & Partial<{
|
|
6
6
|
continues: boolean;
|
|
7
7
|
}>;
|
|
8
|
-
export declare const
|
|
9
|
-
export type
|
|
10
|
-
export declare const
|
|
8
|
+
export declare const MessageRoot: React.ForwardRefExoticComponent<Pick<MessageRootProps, "slot" | "style" | "title" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "children" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "classNames" | "continues" | keyof MessageMetadata> & React.RefAttributes<HTMLDivElement>>;
|
|
9
|
+
export type MessageHeadingProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & Pick<MessageMetadata, 'authorName' | 'timestamp'>;
|
|
10
|
+
export declare const MessageHeading: ({ children, classNames, timestamp, authorName, ...props }: MessageHeadingProps) => JSX.Element;
|
|
11
|
+
export type MessageAuthorNameProps = Pick<MessageMetadata, 'authorName'>;
|
|
12
|
+
export declare const MessageAuthorName: ({ authorName }: MessageAuthorNameProps) => JSX.Element;
|
|
13
|
+
export type MessageTimeProps = Pick<MessageMetadata, 'timestamp'>;
|
|
14
|
+
export declare const MessageTime: ({ timestamp }: MessageTimeProps) => JSX.Element;
|
|
15
|
+
export type MessageBodyProps = ComponentPropsWithoutRef<'p'>;
|
|
16
|
+
export declare const MessageBody: ({ children, ...props }: MessageBodyProps) => JSX.Element;
|
|
11
17
|
export type MessageTextboxProps = {
|
|
12
18
|
disabled?: boolean;
|
|
13
19
|
onSend?: () => void;
|
|
14
20
|
onClear?: () => void;
|
|
15
21
|
onEditorFocus?: () => void;
|
|
16
|
-
} & MessageMetadata &
|
|
22
|
+
} & MessageMetadata & UseTextEditorProps;
|
|
17
23
|
export declare const MessageTextbox: ({ id, onSend, onClear, onEditorFocus, authorId, authorName, authorImgSrc, authorAvatarProps, disabled, extensions: _extensions, ...editorProps }: MessageTextboxProps) => JSX.Element;
|
|
18
24
|
//# sourceMappingURL=Message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../../src/Message/Message.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,qBAAqB,EAAuB,KAAK,
|
|
1
|
+
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../../src/Message/Message.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,qBAAqB,EAAuB,KAAK,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAG9G,OAAO,EAAU,KAAK,eAAe,EAAkB,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,KAAK,kBAAkB,EAAmC,MAAM,uBAAuB,CAAC;AAKjG,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAIhD,MAAM,MAAM,gBAAgB,GAAG,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,GAC1E,eAAe,GACf,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAElC,eAAO,MAAM,WAAW,qnJA6BvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,eAAe,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,GAChF,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;AAEpD,eAAO,MAAM,cAAc,8DAA+D,mBAAmB,gBAU5G,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;AAEzE,eAAO,MAAM,iBAAiB,mBAAoB,sBAAsB,gBAKvE,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;AAElE,eAAO,MAAM,WAAW,kBAAmB,gBAAgB,gBAQ1D,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;AAE7D,eAAO,MAAM,WAAW,2BAA4B,gBAAgB,gBAEnE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B,GAAG,eAAe,GACjB,kBAAkB,CAAC;AA4BrB,eAAO,MAAM,cAAc,qJAYxB,mBAAmB,gBA4BrB,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import '@dxosTheme';
|
|
2
|
+
import React from 'react';
|
|
3
3
|
declare const _default: {
|
|
4
4
|
title: string;
|
|
5
|
-
component: (
|
|
5
|
+
component: React.ForwardRefExoticComponent<Pick<import("./Message").MessageRootProps, "slot" | "style" | "title" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "children" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "classNames" | "continues" | keyof import("..").MessageMetadata> & React.RefAttributes<HTMLDivElement>>;
|
|
6
6
|
render: () => JSX.Element;
|
|
7
7
|
decorators: import("@storybook/react/*").Decorator[];
|
|
8
8
|
parameters: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.stories.d.ts","sourceRoot":"","sources":["../../../../src/Message/Message.stories.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Message.stories.d.ts","sourceRoot":"","sources":["../../../../src/Message/Message.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAEpB,OAAO,KAAmB,MAAM,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AA+BxC,wBAME;AAEF,eAAO,MAAM,OAAO,IAAK,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Comments.stories.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Comments.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAGpB,OAAO,KAAwD,MAAM,OAAO,CAAC;AAS7E,OAAO,EAML,KAAK,KAAK,EAMX,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"Comments.stories.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Comments.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAGpB,OAAO,KAAwD,MAAM,OAAO,CAAC;AAS7E,OAAO,EAML,KAAK,KAAK,EAMX,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAqEhD,KAAK,kBAAkB,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B,CAAC;AAwHF,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;;;;;;;;;;mBA2He,UAAU;;;;;;;;;;;;;;;;;;;;;AAJ3B,wBAME;AAWF,eAAO,MAAM,OAAO;;;;CAInB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Thread.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Thread.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAc,MAAM,OAAO,CAAC;AAE3F,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,gBAAgB,CAAC;AAItE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,GACrE,YAAY,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAA;CAAE,CAAC;AAE/E,eAAO,MAAM,YAAY,mEAAmE,CAAC;AAE7F,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"Thread.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Thread.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAc,MAAM,OAAO,CAAC;AAE3F,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,gBAAgB,CAAC;AAItE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,GACrE,YAAY,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAA;CAAE,CAAC;AAE/E,eAAO,MAAM,YAAY,mEAAmE,CAAC;AAE7F,eAAO,MAAM,MAAM,knJAqBlB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAExG,eAAO,MAAM,aAAa,2mJAqBzB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,GAAG;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,YAAY,omJAwBxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Thread.stories.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Thread.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Thread.stories.d.ts","sourceRoot":"","sources":["../../../../src/Thread/Thread.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAEpB,OAAO,KAAoC,MAAM,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AA2EzD,wBAME;AAEF,eAAO,MAAM,OAAO,IAAK,CAAC"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import { type PropsWithChildren } from 'react';
|
|
2
2
|
import { type MessageMetadata } from './types';
|
|
3
3
|
export type MessageEntity<PartValue = any> = MessageMetadata & {
|
|
4
4
|
text: string;
|
|
5
5
|
parts?: PartValue[];
|
|
6
6
|
};
|
|
7
|
-
export type MessageTextProps = {
|
|
7
|
+
export type MessageTextProps = MessageMetadata & {
|
|
8
8
|
text: string;
|
|
9
9
|
onDelete?: () => void;
|
|
10
10
|
};
|
|
11
|
-
export declare const
|
|
11
|
+
export declare const MessageStoryText: ({ text, onDelete, authorName, timestamp }: MessageTextProps) => JSX.Element;
|
|
12
12
|
export type MessagePartProps<PartValue> = {
|
|
13
13
|
part: PartValue;
|
|
14
14
|
};
|
|
15
|
-
export declare const
|
|
15
|
+
export declare const MessageStoryBlock: <PartValue>({ part }: MessagePartProps<PartValue>) => JSX.Element;
|
|
16
|
+
export declare const ThreadStoryContainer: ({ children }: PropsWithChildren) => JSX.Element;
|
|
16
17
|
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/testing.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/testing.tsx"],"names":[],"mappings":"AAKA,OAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAMtD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,MAAM,aAAa,CAAC,SAAS,GAAG,GAAG,IAAI,eAAe,GAAG;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,8CAA+C,gBAAgB,gBAiB3F,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,SAAS,IAAI;IACxC,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,iBAAiB,wBAA0B,iBAAiB,SAAS,CAAC,gBAWlF,CAAC;AAEF,eAAO,MAAM,oBAAoB,iBAAkB,iBAAiB,gBAEnE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-thread",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.6-staging.23d123d",
|
|
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",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@radix-ui/react-primitive": "^1.0.2",
|
|
25
25
|
"date-fns": "^3.3.1",
|
|
26
|
-
"@dxos/react-ui
|
|
27
|
-
"@dxos/react-ui-
|
|
28
|
-
"@dxos/
|
|
29
|
-
"@dxos/react-ui": "0.6.
|
|
30
|
-
"@dxos/
|
|
26
|
+
"@dxos/react-ui": "0.6.6-staging.23d123d",
|
|
27
|
+
"@dxos/react-ui-editor": "0.6.6-staging.23d123d",
|
|
28
|
+
"@dxos/react-ui-mosaic": "0.6.6-staging.23d123d",
|
|
29
|
+
"@dxos/react-ui-theme": "0.6.6-staging.23d123d",
|
|
30
|
+
"@dxos/util": "0.6.6-staging.23d123d"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
"react": "~18.2.0",
|
|
37
37
|
"react-dom": "~18.2.0",
|
|
38
38
|
"vite": "^5.3.4",
|
|
39
|
-
"@dxos/echo-schema": "0.6.
|
|
40
|
-
"@
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@
|
|
39
|
+
"@dxos/echo-schema": "0.6.6-staging.23d123d",
|
|
40
|
+
"@braneframe/types": "0.6.6-staging.23d123d",
|
|
41
|
+
"@dxos/echo-db": "0.6.6-staging.23d123d",
|
|
42
|
+
"@dxos/keys": "0.6.6-staging.23d123d",
|
|
43
|
+
"@dxos/log": "0.6.6-staging.23d123d",
|
|
44
|
+
"@dxos/random": "0.6.6-staging.23d123d",
|
|
45
|
+
"@dxos/storybook-utils": "0.6.6-staging.23d123d"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -7,10 +7,12 @@ import '@dxosTheme';
|
|
|
7
7
|
import React, { useState } from 'react';
|
|
8
8
|
|
|
9
9
|
import { PublicKey } from '@dxos/keys';
|
|
10
|
-
import {
|
|
10
|
+
import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
|
|
11
|
+
import { withFullscreen, withTheme } from '@dxos/storybook-utils';
|
|
11
12
|
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
13
|
+
import { MessageRoot } from './Message';
|
|
14
|
+
import { threadLayout } from '../Thread';
|
|
15
|
+
import { ThreadStoryContainer, MessageStoryText, type MessageEntity } from '../testing';
|
|
14
16
|
import translations from '../translations';
|
|
15
17
|
|
|
16
18
|
const Story = () => {
|
|
@@ -23,19 +25,21 @@ const Story = () => {
|
|
|
23
25
|
});
|
|
24
26
|
|
|
25
27
|
return (
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
<ThreadStoryContainer>
|
|
29
|
+
<div className={threadLayout}>
|
|
30
|
+
<MessageRoot {...message} classNames={[hoverableControls, hoverableFocusedWithinControls]}>
|
|
31
|
+
<MessageStoryText {...message} onDelete={() => console.log('delete')} />
|
|
32
|
+
</MessageRoot>
|
|
33
|
+
</div>
|
|
34
|
+
</ThreadStoryContainer>
|
|
31
35
|
);
|
|
32
36
|
};
|
|
33
37
|
|
|
34
38
|
export default {
|
|
35
39
|
title: 'react-ui-thread/Message',
|
|
36
|
-
component:
|
|
40
|
+
component: MessageRoot,
|
|
37
41
|
render: Story,
|
|
38
|
-
decorators: [withTheme],
|
|
42
|
+
decorators: [withTheme, withFullscreen()],
|
|
39
43
|
parameters: { translations },
|
|
40
44
|
};
|
|
41
45
|
|
package/src/Message/Message.tsx
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { formatDistanceToNow } from 'date-fns/formatDistanceToNow';
|
|
6
|
-
import React, { type ComponentPropsWithRef, forwardRef, useMemo, type
|
|
6
|
+
import React, { type ComponentPropsWithRef, forwardRef, useMemo, type ComponentPropsWithoutRef } from 'react';
|
|
7
7
|
|
|
8
8
|
// TODO(burdon): Remove dep.
|
|
9
9
|
import { Avatar, type ThemedClassName, useTranslation } from '@dxos/react-ui';
|
|
10
|
-
import { type
|
|
10
|
+
import { type UseTextEditorProps, keymap, listener, useTextEditor } from '@dxos/react-ui-editor';
|
|
11
11
|
import { focusRing, mx } from '@dxos/react-ui-theme';
|
|
12
12
|
import { hexToEmoji, hexToHue, isNotFalsy } from '@dxos/util';
|
|
13
13
|
|
|
@@ -16,16 +16,17 @@ import { type MessageMetadata } from '../types';
|
|
|
16
16
|
|
|
17
17
|
const avatarSize = 7;
|
|
18
18
|
|
|
19
|
-
export type
|
|
19
|
+
export type MessageRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> &
|
|
20
20
|
MessageMetadata &
|
|
21
21
|
Partial<{ continues: boolean }>;
|
|
22
22
|
|
|
23
|
-
export const
|
|
23
|
+
export const MessageRoot = forwardRef<HTMLDivElement, MessageRootProps>(
|
|
24
24
|
(
|
|
25
25
|
{ authorImgSrc, authorId, authorName, authorAvatarProps, continues = true, children, classNames, ...rootProps },
|
|
26
26
|
forwardedRef,
|
|
27
27
|
) => {
|
|
28
28
|
return (
|
|
29
|
+
// Must wrap the message since Avatar.Label may be used in the content.
|
|
29
30
|
<Avatar.Root size={avatarSize} hue={authorAvatarProps?.hue || hexToHue(authorId ?? '0')}>
|
|
30
31
|
<div
|
|
31
32
|
role='none'
|
|
@@ -34,7 +35,7 @@ export const MessageMeta = forwardRef<HTMLDivElement, MessageMetaProps>(
|
|
|
34
35
|
className={mx('grid grid-cols-subgrid col-span-2', classNames)}
|
|
35
36
|
ref={forwardedRef}
|
|
36
37
|
>
|
|
37
|
-
<div role='none' className=
|
|
38
|
+
<div role='none' className='flex flex-col items-center gap-2 pbs-2'>
|
|
38
39
|
<Avatar.Frame>
|
|
39
40
|
<Avatar.Fallback text={authorAvatarProps?.emoji || hexToEmoji(authorId ?? '0')} />
|
|
40
41
|
{authorImgSrc && <Avatar.Image href={authorImgSrc} />}
|
|
@@ -50,36 +51,55 @@ export const MessageMeta = forwardRef<HTMLDivElement, MessageMetaProps>(
|
|
|
50
51
|
},
|
|
51
52
|
);
|
|
52
53
|
|
|
53
|
-
export type
|
|
54
|
-
|
|
55
|
-
export const Message = ({ timestamp, children, ...messageMeta }: MessageProps) => {
|
|
56
|
-
const { t, dtLocale } = useTranslation(translationKey);
|
|
57
|
-
const dt = timestamp ? new Date(timestamp) : undefined;
|
|
54
|
+
export type MessageHeadingProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> &
|
|
55
|
+
Pick<MessageMetadata, 'authorName' | 'timestamp'>;
|
|
58
56
|
|
|
57
|
+
export const MessageHeading = ({ children, classNames, timestamp, authorName, ...props }: MessageHeadingProps) => {
|
|
59
58
|
return (
|
|
60
|
-
<
|
|
61
|
-
<p className='
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
</Avatar.Label>
|
|
65
|
-
<time className='fg-description text-xs pbs-0.5' dateTime={dt?.toISOString()}>
|
|
66
|
-
{dt ? formatDistanceToNow(dt, { locale: dtLocale, addSuffix: true }) : ''}
|
|
67
|
-
</time>
|
|
59
|
+
<div role='none' {...props} className={mx('flex gap-2 items-start', classNames)}>
|
|
60
|
+
<p className='grow'>
|
|
61
|
+
<MessageAuthorName authorName={authorName} />
|
|
62
|
+
{timestamp && <MessageTime timestamp={timestamp} />}
|
|
68
63
|
</p>
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
</div>
|
|
72
|
-
</MessageMeta>
|
|
64
|
+
{children}
|
|
65
|
+
</div>
|
|
73
66
|
);
|
|
74
67
|
};
|
|
75
68
|
|
|
69
|
+
export type MessageAuthorNameProps = Pick<MessageMetadata, 'authorName'>;
|
|
70
|
+
|
|
71
|
+
export const MessageAuthorName = ({ authorName }: MessageAuthorNameProps) => {
|
|
72
|
+
const { t } = useTranslation(translationKey);
|
|
73
|
+
return (
|
|
74
|
+
<Avatar.Label classNames='block truncate text-sm fg-subdued'>{authorName ?? t('anonymous label')}</Avatar.Label>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type MessageTimeProps = Pick<MessageMetadata, 'timestamp'>;
|
|
79
|
+
|
|
80
|
+
export const MessageTime = ({ timestamp }: MessageTimeProps) => {
|
|
81
|
+
const { dtLocale } = useTranslation(translationKey);
|
|
82
|
+
const dt = timestamp ? new Date(timestamp) : undefined;
|
|
83
|
+
return (
|
|
84
|
+
<time className='block fg-subdued text-xs pbe-0.5' dateTime={dt?.toISOString()}>
|
|
85
|
+
{dt ? formatDistanceToNow(dt, { locale: dtLocale, addSuffix: true }) : ''}
|
|
86
|
+
</time>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type MessageBodyProps = ComponentPropsWithoutRef<'p'>;
|
|
91
|
+
|
|
92
|
+
export const MessageBody = ({ children, ...props }: MessageBodyProps) => {
|
|
93
|
+
return <p {...props}>{children}</p>;
|
|
94
|
+
};
|
|
95
|
+
|
|
76
96
|
export type MessageTextboxProps = {
|
|
77
97
|
disabled?: boolean;
|
|
78
98
|
onSend?: () => void;
|
|
79
99
|
onClear?: () => void;
|
|
80
100
|
onEditorFocus?: () => void;
|
|
81
101
|
} & MessageMetadata &
|
|
82
|
-
|
|
102
|
+
UseTextEditorProps;
|
|
83
103
|
|
|
84
104
|
const keyBindings = ({ onSend, onClear }: Pick<MessageTextboxProps, 'onSend' | 'onClear'>) => [
|
|
85
105
|
{
|
|
@@ -120,7 +140,7 @@ export const MessageTextbox = ({
|
|
|
120
140
|
extensions: _extensions,
|
|
121
141
|
...editorProps
|
|
122
142
|
}: MessageTextboxProps) => {
|
|
123
|
-
const extensions = useMemo<
|
|
143
|
+
const extensions = useMemo<UseTextEditorProps['extensions']>(() => {
|
|
124
144
|
return [
|
|
125
145
|
keymap.of(keyBindings({ onSend, onClear })),
|
|
126
146
|
listener({
|
|
@@ -135,13 +155,16 @@ export const MessageTextbox = ({
|
|
|
135
155
|
// TODO(wittjosiah): Should probably include callbacks in the dependency array.
|
|
136
156
|
}, [_extensions]);
|
|
137
157
|
|
|
158
|
+
const { parentRef, focusAttributes } = useTextEditor(() => ({ id, extensions, ...editorProps }), [id, extensions]);
|
|
159
|
+
|
|
138
160
|
return (
|
|
139
|
-
<
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
|
|
161
|
+
<MessageRoot {...{ id, authorId, authorName, authorImgSrc, authorAvatarProps }} continues={false}>
|
|
162
|
+
<div
|
|
163
|
+
role='none'
|
|
164
|
+
ref={parentRef}
|
|
143
165
|
className={mx('plb-0.5 mie-1 rounded-sm', focusRing, disabled && 'opacity-50')}
|
|
166
|
+
{...focusAttributes}
|
|
144
167
|
/>
|
|
145
|
-
</
|
|
168
|
+
</MessageRoot>
|
|
146
169
|
);
|
|
147
170
|
};
|
|
@@ -27,10 +27,11 @@ import {
|
|
|
27
27
|
automerge,
|
|
28
28
|
listener,
|
|
29
29
|
} from '@dxos/react-ui-editor';
|
|
30
|
+
import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
|
|
30
31
|
import { withTheme } from '@dxos/storybook-utils';
|
|
31
32
|
|
|
32
33
|
import { Thread, ThreadFooter, ThreadHeading } from './Thread';
|
|
33
|
-
import {
|
|
34
|
+
import { MessageBody, MessageHeading, MessageRoot, MessageTextbox } from '../Message';
|
|
34
35
|
import { type MessageEntity } from '../testing';
|
|
35
36
|
import translations from '../translations';
|
|
36
37
|
|
|
@@ -67,7 +68,7 @@ const Editor: FC<{
|
|
|
67
68
|
const { parentRef, view } = useTextEditor(
|
|
68
69
|
() => ({
|
|
69
70
|
id,
|
|
70
|
-
|
|
71
|
+
initialValue: item.content,
|
|
71
72
|
extensions: [
|
|
72
73
|
createBasicExtensions(),
|
|
73
74
|
createThemeExtensions({ themeMode }),
|
|
@@ -108,30 +109,6 @@ type StoryCommentThread = {
|
|
|
108
109
|
messages: MessageEntity[];
|
|
109
110
|
};
|
|
110
111
|
|
|
111
|
-
type MessageTextProps = {
|
|
112
|
-
message: MessageEntity;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const StoryMessageText = ({ message }: MessageTextProps) => {
|
|
116
|
-
const { themeMode } = useThemeContext();
|
|
117
|
-
const doc = message.text;
|
|
118
|
-
const accessor = createDocAccessor(message, ['text']);
|
|
119
|
-
const { parentRef } = useTextEditor(
|
|
120
|
-
() => ({
|
|
121
|
-
doc,
|
|
122
|
-
extensions: [
|
|
123
|
-
// prettier-ignore
|
|
124
|
-
createBasicExtensions(),
|
|
125
|
-
createThemeExtensions({ themeMode }),
|
|
126
|
-
automerge(accessor),
|
|
127
|
-
],
|
|
128
|
-
}),
|
|
129
|
-
[doc, accessor, themeMode],
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
return <div ref={parentRef} className='col-span-3' />;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
112
|
const StoryThread: FC<{
|
|
136
113
|
thread: StoryCommentThread;
|
|
137
114
|
selected: boolean;
|
|
@@ -193,9 +170,10 @@ const StoryThread: FC<{
|
|
|
193
170
|
</ThreadHeading>
|
|
194
171
|
|
|
195
172
|
{thread.messages.map((message) => (
|
|
196
|
-
<
|
|
197
|
-
<
|
|
198
|
-
|
|
173
|
+
<MessageRoot key={message.id} classNames={[hoverableControls, hoverableFocusedWithinControls]} {...message}>
|
|
174
|
+
<MessageHeading authorName={message.authorName} timestamp={message.timestamp} />
|
|
175
|
+
<MessageBody>{message.text}</MessageBody>
|
|
176
|
+
</MessageRoot>
|
|
199
177
|
))}
|
|
200
178
|
|
|
201
179
|
<div ref={containerRef} className='contents'>
|
|
@@ -3,35 +3,34 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import '@dxosTheme';
|
|
6
|
+
|
|
6
7
|
import React, { useMemo, useRef, useState } from 'react';
|
|
7
8
|
|
|
8
9
|
import { PublicKey } from '@dxos/keys';
|
|
10
|
+
import { faker } from '@dxos/random';
|
|
9
11
|
import { createBasicExtensions, createThemeExtensions } from '@dxos/react-ui-editor';
|
|
10
|
-
import {
|
|
12
|
+
import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
|
|
13
|
+
import { withFullscreen, withTheme } from '@dxos/storybook-utils';
|
|
11
14
|
|
|
12
15
|
import { Thread, ThreadFooter } from './Thread';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
16
|
+
import { MessageRoot, MessageTextbox } from '../Message';
|
|
17
|
+
import { ThreadStoryContainer, MessageStoryText, type MessageEntity } from '../testing';
|
|
15
18
|
import translations from '../translations';
|
|
16
19
|
|
|
20
|
+
faker.seed(1);
|
|
21
|
+
|
|
17
22
|
const Story = () => {
|
|
18
23
|
const [pending, setPending] = useState(false);
|
|
19
24
|
const [identityKey1] = useState(PublicKey.random());
|
|
20
25
|
const [identityKey2] = useState(PublicKey.random());
|
|
21
|
-
const [messages,
|
|
22
|
-
{
|
|
23
|
-
id:
|
|
26
|
+
const [messages, setMessages] = useState<MessageEntity<{ id: string; text: string }>[]>(
|
|
27
|
+
Array.from({ length: 8 }, (_, i) => ({
|
|
28
|
+
id: `m${i + 1}`,
|
|
24
29
|
timestamp: new Date().toISOString(),
|
|
25
|
-
authorId: identityKey1.toHex(),
|
|
26
|
-
text:
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
id: 'm2',
|
|
30
|
-
timestamp: new Date().toISOString(),
|
|
31
|
-
authorId: identityKey2.toHex(),
|
|
32
|
-
text: 'hi there',
|
|
33
|
-
},
|
|
34
|
-
]);
|
|
30
|
+
authorId: [identityKey1.toHex(), identityKey2.toHex()][i % 2],
|
|
31
|
+
text: faker.lorem.paragraph(),
|
|
32
|
+
})),
|
|
33
|
+
);
|
|
35
34
|
|
|
36
35
|
// TODO(wittjosiah): This is a hack to reset the editor after a message is sent.
|
|
37
36
|
const [_count, _setCount] = useState(3);
|
|
@@ -44,7 +43,7 @@ const Story = () => {
|
|
|
44
43
|
const handleSend = () => {
|
|
45
44
|
setPending(true);
|
|
46
45
|
setTimeout(() => {
|
|
47
|
-
|
|
46
|
+
setMessages((messages) => [
|
|
48
47
|
...messages,
|
|
49
48
|
{
|
|
50
49
|
id: `m${_count}`,
|
|
@@ -60,21 +59,23 @@ const Story = () => {
|
|
|
60
59
|
};
|
|
61
60
|
|
|
62
61
|
return (
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
62
|
+
<ThreadStoryContainer>
|
|
63
|
+
<Thread id='t1'>
|
|
64
|
+
{messages.map((message) => (
|
|
65
|
+
<MessageRoot key={message.id} classNames={[hoverableControls, hoverableFocusedWithinControls]} {...message}>
|
|
66
|
+
<MessageStoryText {...message} text={message.text} onDelete={() => console.log('delete')} />
|
|
67
|
+
</MessageRoot>
|
|
68
|
+
))}
|
|
69
|
+
<MessageTextbox
|
|
70
|
+
id={String(_count)}
|
|
71
|
+
authorId={identityKey1.toHex()}
|
|
72
|
+
disabled={pending}
|
|
73
|
+
extensions={extensions}
|
|
74
|
+
onSend={handleSend}
|
|
75
|
+
/>
|
|
76
|
+
<ThreadFooter activity>Processing...</ThreadFooter>
|
|
77
|
+
</Thread>
|
|
78
|
+
</ThreadStoryContainer>
|
|
78
79
|
);
|
|
79
80
|
};
|
|
80
81
|
|
|
@@ -82,7 +83,7 @@ export default {
|
|
|
82
83
|
title: 'react-ui-thread/Thread',
|
|
83
84
|
component: Thread,
|
|
84
85
|
render: Story,
|
|
85
|
-
decorators: [withTheme],
|
|
86
|
+
decorators: [withTheme, withFullscreen()],
|
|
86
87
|
parameters: { translations },
|
|
87
88
|
};
|
|
88
89
|
|
package/src/Thread/Thread.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { CaretDoubleRight, Spinner } from '@phosphor-icons/react';
|
|
6
6
|
import React, { type ComponentProps, type ComponentPropsWithRef, forwardRef } from 'react';
|
|
7
7
|
|
|
8
8
|
import { type ThemedClassName, useTranslation } from '@dxos/react-ui';
|
|
@@ -27,7 +27,8 @@ export const Thread = forwardRef<HTMLDivElement, ThreadProps>(
|
|
|
27
27
|
className={mx(
|
|
28
28
|
threadLayout,
|
|
29
29
|
hoverableFocusedWithinControls,
|
|
30
|
-
'bg-[var(--surface-bg)] border-[color:var(--surface-separator)] border-bs border-be
|
|
30
|
+
'plb-1.5 bg-[var(--surface-bg)] border-[color:var(--surface-separator)] border-bs border-be',
|
|
31
|
+
'attention attention-within attention-current [--controls-opacity:0]',
|
|
31
32
|
classNames,
|
|
32
33
|
)}
|
|
33
34
|
ref={forwardedRef}
|
|
@@ -44,21 +45,20 @@ export const ThreadHeading = forwardRef<HTMLParagraphElement, ThreadHeadingProps
|
|
|
44
45
|
({ classNames, children, detached, ...props }, forwardedRef) => {
|
|
45
46
|
return (
|
|
46
47
|
<>
|
|
47
|
-
<div role='none' className='
|
|
48
|
-
<
|
|
48
|
+
<div role='none' className='flex items-center justify-center fg-description'>
|
|
49
|
+
<CaretDoubleRight />
|
|
50
|
+
</div>
|
|
51
|
+
<div role='none' className='flex items-center overflow-hidden'>
|
|
52
|
+
<p
|
|
53
|
+
role='heading'
|
|
54
|
+
data-testid='thread.heading'
|
|
55
|
+
{...props}
|
|
56
|
+
className={mx('mie-2 fg-description font-medium truncate italic', detached && 'line-through decoration-1')}
|
|
57
|
+
ref={forwardedRef}
|
|
58
|
+
>
|
|
59
|
+
{children}
|
|
60
|
+
</p>
|
|
49
61
|
</div>
|
|
50
|
-
<p
|
|
51
|
-
role='heading'
|
|
52
|
-
data-testid='thread.heading'
|
|
53
|
-
{...props}
|
|
54
|
-
className={mx(
|
|
55
|
-
'fg-description font-medium truncate before:content-[open-quote] after:content-[close-quote]',
|
|
56
|
-
detached && 'line-through decoration-1',
|
|
57
|
-
)}
|
|
58
|
-
ref={forwardedRef}
|
|
59
|
-
>
|
|
60
|
-
{children}
|
|
61
|
-
</p>
|
|
62
62
|
</>
|
|
63
63
|
);
|
|
64
64
|
},
|
|
@@ -75,7 +75,7 @@ export const ThreadFooter = forwardRef<HTMLDivElement, ThreadFooterProps>(
|
|
|
75
75
|
<div
|
|
76
76
|
{...props}
|
|
77
77
|
className={mx(
|
|
78
|
-
'col-start-2 grid grid-cols-[min-content_1fr_max-content] text-xs fg-description
|
|
78
|
+
'col-start-2 grid grid-cols-[min-content_1fr_max-content] pb-2 pie-2 text-xs fg-description',
|
|
79
79
|
classNames,
|
|
80
80
|
)}
|
|
81
81
|
ref={forwardedRef}
|
|
@@ -88,7 +88,7 @@ export const ThreadFooter = forwardRef<HTMLDivElement, ThreadFooterProps>(
|
|
|
88
88
|
<span className='truncate min-is-0' aria-live='polite'>
|
|
89
89
|
{activity ? children : null}
|
|
90
90
|
</span>
|
|
91
|
-
<span className={mx('text-end
|
|
91
|
+
<span className={mx('text-end', hoverableControlItem)}>{t('enter to send message')}</span>
|
|
92
92
|
</div>
|
|
93
93
|
);
|
|
94
94
|
},
|
package/src/testing.tsx
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { X } from '@phosphor-icons/react';
|
|
6
|
-
import React from 'react';
|
|
6
|
+
import React, { type PropsWithChildren } from 'react';
|
|
7
7
|
|
|
8
8
|
import { Button } from '@dxos/react-ui';
|
|
9
9
|
import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
|
|
10
10
|
|
|
11
|
+
import { MessageBody, MessageHeading } from './Message';
|
|
11
12
|
import { type MessageMetadata } from './types';
|
|
12
13
|
|
|
13
14
|
export type MessageEntity<PartValue = any> = MessageMetadata & {
|
|
@@ -15,29 +16,27 @@ export type MessageEntity<PartValue = any> = MessageMetadata & {
|
|
|
15
16
|
parts?: PartValue[];
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
export type MessageTextProps = {
|
|
19
|
+
export type MessageTextProps = MessageMetadata & {
|
|
19
20
|
text: string;
|
|
20
21
|
onDelete?: () => void;
|
|
21
22
|
};
|
|
22
23
|
|
|
23
|
-
export const
|
|
24
|
-
const contentWidth = onDelete ? 'col-span-2' : 'col-span-3';
|
|
24
|
+
export const MessageStoryText = ({ text, onDelete, authorName, timestamp }: MessageTextProps) => {
|
|
25
25
|
return (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
</div>
|
|
26
|
+
<>
|
|
27
|
+
<MessageHeading authorName={authorName} timestamp={timestamp}>
|
|
28
|
+
{onDelete && (
|
|
29
|
+
<Button
|
|
30
|
+
variant='ghost'
|
|
31
|
+
classNames={['p-1.5 min-bs-0 mie-1 items-start transition-opacity', hoverableControlItem]}
|
|
32
|
+
onClick={() => onDelete()}
|
|
33
|
+
>
|
|
34
|
+
<X />
|
|
35
|
+
</Button>
|
|
36
|
+
)}
|
|
37
|
+
</MessageHeading>
|
|
38
|
+
<MessageBody>{text}</MessageBody>
|
|
39
|
+
</>
|
|
41
40
|
);
|
|
42
41
|
};
|
|
43
42
|
|
|
@@ -45,7 +44,7 @@ export type MessagePartProps<PartValue> = {
|
|
|
45
44
|
part: PartValue;
|
|
46
45
|
};
|
|
47
46
|
|
|
48
|
-
export const
|
|
47
|
+
export const MessageStoryBlock = <PartValue,>({ part }: MessagePartProps<PartValue>) => {
|
|
49
48
|
return (
|
|
50
49
|
<div
|
|
51
50
|
role='none'
|
|
@@ -57,3 +56,7 @@ export const DefaultMessageBlock = <PartValue,>({ part }: MessagePartProps<PartV
|
|
|
57
56
|
</div>
|
|
58
57
|
);
|
|
59
58
|
};
|
|
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
|
+
};
|