@connectycube/react-ui-kit 0.0.22 → 0.1.2
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/README.md +33 -6
- package/gen/components/alert-dialog.jsx +2 -2
- package/gen/components/attachment.jsx +10 -11
- package/gen/components/avatar.jsx +2 -2
- package/gen/components/badge.jsx +2 -2
- package/gen/components/button.jsx +4 -3
- package/gen/components/chat-bubble.jsx +8 -8
- package/gen/components/chat-input.jsx +10 -10
- package/gen/components/chat-list.jsx +13 -13
- package/gen/components/checkbox.jsx +2 -2
- package/gen/components/dialog-item.jsx +2 -2
- package/gen/components/dialogs-list.jsx +4 -4
- package/gen/components/dismiss-layer.jsx +7 -7
- package/gen/components/file-picker.jsx +4 -4
- package/gen/components/formatted-date.jsx +2 -2
- package/gen/components/input.jsx +2 -2
- package/gen/components/label.jsx +2 -2
- package/gen/components/link-preview.jsx +7 -7
- package/gen/components/linkify-text.jsx +5 -5
- package/gen/components/placeholder-text.jsx +1 -2
- package/gen/components/presence.jsx +1 -0
- package/gen/components/quick-actions.jsx +2 -2
- package/gen/components/search.jsx +3 -3
- package/gen/components/spinner.jsx +3 -2
- package/gen/components/status-call.jsx +1 -0
- package/gen/components/status-indicator.jsx +2 -2
- package/gen/components/status-sent.jsx +1 -0
- package/gen/components/stream-view.jsx +16 -16
- package/package.json +14 -14
- package/src/components/alert-dialog.tsx +2 -3
- package/src/components/attachment.tsx +12 -13
- package/src/components/avatar.tsx +2 -3
- package/src/components/badge.tsx +2 -3
- package/src/components/button.tsx +4 -4
- package/src/components/chat-bubble.tsx +9 -10
- package/src/components/chat-input.tsx +17 -13
- package/src/components/chat-list.tsx +31 -24
- package/src/components/checkbox.tsx +2 -3
- package/src/components/dialog-item.tsx +2 -3
- package/src/components/dialogs-list.tsx +4 -5
- package/src/components/dismiss-layer.tsx +7 -8
- package/src/components/file-picker.tsx +4 -5
- package/src/components/formatted-date.tsx +4 -3
- package/src/components/input.tsx +2 -3
- package/src/components/label.tsx +2 -3
- package/src/components/link-preview.tsx +16 -26
- package/src/components/linkify-text.tsx +5 -6
- package/src/components/placeholder-text.tsx +1 -2
- package/src/components/presence.tsx +1 -1
- package/src/components/quick-actions.tsx +2 -3
- package/src/components/search.tsx +3 -4
- package/src/components/spinner.tsx +3 -2
- package/src/components/status-call.tsx +1 -0
- package/src/components/status-indicator.tsx +2 -3
- package/src/components/status-sent.tsx +1 -0
- package/src/components/stream-view.tsx +18 -17
- package/src/components/connectycube-ui/attachment.tsx +0 -269
- package/src/components/connectycube-ui/avatar.jsx +0 -54
- package/src/components/connectycube-ui/avatar.tsx +0 -77
- package/src/components/connectycube-ui/badge.jsx +0 -45
- package/src/components/connectycube-ui/badge.tsx +0 -42
- package/src/components/connectycube-ui/chat-input.tsx +0 -174
- package/src/components/connectycube-ui/chat-message.tsx +0 -138
- package/src/components/connectycube-ui/dialog-item.jsx +0 -149
- package/src/components/connectycube-ui/dialog-item.tsx +0 -188
- package/src/components/connectycube-ui/file-picker.jsx +0 -200
- package/src/components/connectycube-ui/file-picker.tsx +0 -231
- package/src/components/connectycube-ui/formatted-date.jsx +0 -57
- package/src/components/connectycube-ui/formatted-date.tsx +0 -57
- package/src/components/connectycube-ui/label.jsx +0 -22
- package/src/components/connectycube-ui/label.tsx +0 -23
- package/src/components/connectycube-ui/link-preview.tsx +0 -149
- package/src/components/connectycube-ui/linkify-text.tsx +0 -40
- package/src/components/connectycube-ui/presence.jsx +0 -81
- package/src/components/connectycube-ui/presence.tsx +0 -96
- package/src/components/connectycube-ui/status-sent.jsx +0 -21
- package/src/components/connectycube-ui/status-sent.tsx +0 -25
- package/src/components/connectycube-ui/utils.js +0 -10
- package/src/components/connectycube-ui/utils.ts +0 -10
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @connectycube/react-ui-kit (BETA)
|
|
2
2
|
|
|
3
3
|
**Simple React UI Kit generator with TSX/JSX support**
|
|
4
4
|
|
|
@@ -44,14 +44,14 @@ export function App() {
|
|
|
44
44
|
You can generate new components in your project using the CLI:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
npx @connectycube/react-ui-kit add local-stream
|
|
47
|
+
npx @connectycube/react-ui-kit@beta add local-stream
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
This will:
|
|
51
51
|
|
|
52
52
|
- Prompt prefer TypeScript or JavaScript language
|
|
53
53
|
- Copy components and utilities to `src/components/connectycube-ui`
|
|
54
|
-
-
|
|
54
|
+
- Ask to install specified dependencies if needed
|
|
55
55
|
|
|
56
56
|
---
|
|
57
57
|
|
|
@@ -59,9 +59,36 @@ This will:
|
|
|
59
59
|
|
|
60
60
|
Coming soon...
|
|
61
61
|
|
|
62
|
-
| Component
|
|
63
|
-
|
|
|
64
|
-
|
|
|
62
|
+
| Component | Description |
|
|
63
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
64
|
+
| alert-dialog | gets "triggerElement" prop to call dialog with title, description, and confirm/cancel buttons |
|
|
65
|
+
| attachment | defines a URL with mimeType to show image/video/audio/file/failed content; has onReady callback to notify about video/image size measurement is ready |
|
|
66
|
+
| avatar | with online and presence statuses, has fallback icon/text |
|
|
67
|
+
| badge | a badge with variants; similar to shadcn-ui badge |
|
|
68
|
+
| button | a button with variants; the same as shadcn-ui button |
|
|
69
|
+
| chat-bubble | includes <ChatBubbleMessage .../> that is a left/right-sided wrapper with/without avatar, with/without title, includes last sent status and time, usually obtains "attachment", "linkify-text", "link-preview" as children; and includes <ChatBubbleInfo .../> for system/information text with icon |
|
|
70
|
+
| chat-input | auto-size textarea with onSend, onDraft, onTyping, onHeightGrow callbacks and pending state |
|
|
71
|
+
| chat-list | from "virtua" for chat history; has file-picker wrapper for drag-and-drop files; supports quick-actions before a messaging starts; has onScrollStartReached, onScrollEndReached, onListCreate, onListGrow, onListReset callbacks; can react on the chat-input's onHeightGrow with "textareaMeasurement" prop; supports prepending batch messages with loading state |
|
|
72
|
+
| checkbox | the same as shadcn-ui checkbox |
|
|
73
|
+
| dialog-item | basically, it's an element for "dialog-list"; has avatar, name, last-message text, unread badge count, last message status, last message time, and visual selection |
|
|
74
|
+
| dialog-list | from "virtua" for dialog-items; has onScrollStartReached and onScrollEndReached callbacks, loading state, and pending state with skeletons of dialog-items |
|
|
75
|
+
| dismiss-layer | to manage the open/close state of any modal by clicking outside or pressing Esc |
|
|
76
|
+
| file-picker | to chose accepted files, and wrapper component for drag-and-drop accepted files; has onSelectFile and onInvalidFile callbacks |
|
|
77
|
+
| formatted-date | displays the date in a readable format; simple to use "distanceToNow" for message in chat history; supports "language" prop with English (en), Ukrainian (ua), and Greek (el) |
|
|
78
|
+
| input | the same as shadcn-ui input |
|
|
79
|
+
| label | the same as shadcn-ui label |
|
|
80
|
+
| link-preview | displays favicon, title, description, and banner image; uses "thin" prop to be smaller; has onReady callback to notify about image size measurement is ready |
|
|
81
|
+
| linkify-text | displays text with highlighted links; can display skeleton rows in pending state; switching the pending from "true" to "false" calls onReady callback |
|
|
82
|
+
| placeholder-text | renders title or titles in rows in the center of any view; has absolute position |
|
|
83
|
+
| presence | presence status with badge icon and label; can be 'available', 'busy', 'away', 'unknown' |
|
|
84
|
+
| quick-actions | title, description, and an array of strings (actions display as buttons); click on any action calls onAction callback with own text |
|
|
85
|
+
| search | a styled and animated input component with onSearch and onCancel callbacks |
|
|
86
|
+
| spinner | animated-loader; has "loader" and "circle" types (default is "loader"); the "layout" prop (absolute/centered/overlay/flow) defines its position in a view |
|
|
87
|
+
| status-call | define a colorized icon related to call status ('reject', 'notAnswer', 'hungUp', or 'cancel') |
|
|
88
|
+
| status-indicator | displays colorized statuses; statuses and colors defines by config; shows tooltip on mouse over a status |
|
|
89
|
+
| status-sent | shows message's status icon that defines from status like 'wait', 'sent', 'read', or 'lost' |
|
|
90
|
+
| stream-view | local-stream-view, remote-stream-view and fullscreen-stream-view with pip stream |
|
|
91
|
+
| switch | the same as shadcn-ui switch |
|
|
65
92
|
|
|
66
93
|
---
|
|
67
94
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
3
3
|
import { Button } from './button';
|
|
4
4
|
import { cn } from './utils';
|
|
@@ -87,7 +87,7 @@ function AlertDialogBase(
|
|
|
87
87
|
);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
const AlertDialog = forwardRef(AlertDialogBase);
|
|
90
|
+
const AlertDialog = React.forwardRef(AlertDialogBase);
|
|
91
91
|
|
|
92
92
|
AlertDialog.displayName = 'AlertDialog';
|
|
93
93
|
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { File, FileXCorner } from 'lucide-react';
|
|
3
3
|
import { Spinner } from './spinner';
|
|
4
4
|
import { cn, getRandomString } from './utils';
|
|
5
5
|
|
|
6
|
-
function AttachmentLinkBase({
|
|
6
|
+
function AttachmentLinkBase({ pending = false, children, ...props }, ref) {
|
|
7
7
|
return (
|
|
8
8
|
<a
|
|
9
9
|
ref={ref}
|
|
10
10
|
target="_blank"
|
|
11
11
|
rel="noopener noreferrer"
|
|
12
12
|
{...props}
|
|
13
|
-
href={url}
|
|
14
13
|
className={cn(
|
|
15
14
|
'group relative min-h-8 min-w-8 w-full flex items-center justify-center rounded-md overflow-hidden bg-ring/10 hover:bg-ring/20 transition-color duration-300 ease-out cursor-pointer',
|
|
16
15
|
props?.className
|
|
@@ -22,7 +21,7 @@ function AttachmentLinkBase({ url, pending = false, children, ...props }, ref) {
|
|
|
22
21
|
);
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
const AttachmentLink = forwardRef(AttachmentLinkBase);
|
|
24
|
+
const AttachmentLink = React.forwardRef(AttachmentLinkBase);
|
|
26
25
|
|
|
27
26
|
AttachmentLink.displayName = 'AttachmentLink';
|
|
28
27
|
|
|
@@ -40,7 +39,7 @@ function AttachmentAudioBase({ uid, url, pending = false, containerProps, ...pro
|
|
|
40
39
|
);
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
const AttachmentAudio = forwardRef(AttachmentAudioBase);
|
|
42
|
+
const AttachmentAudio = React.forwardRef(AttachmentAudioBase);
|
|
44
43
|
|
|
45
44
|
function AttachmentVideoBase(
|
|
46
45
|
{ uid, url, maxSize = 360, pending = false, onReady = () => {}, containerProps, ...props },
|
|
@@ -48,8 +47,8 @@ function AttachmentVideoBase(
|
|
|
48
47
|
) {
|
|
49
48
|
const videoId = `attachment_video_${uid || getRandomString()}`;
|
|
50
49
|
const videoMaxSize = `${maxSize}px`;
|
|
51
|
-
const playerRef = useRef(null);
|
|
52
|
-
const [style, setStyle] = useState({
|
|
50
|
+
const playerRef = React.useRef(null);
|
|
51
|
+
const [style, setStyle] = React.useState({
|
|
53
52
|
maxHeight: videoMaxSize,
|
|
54
53
|
maxWidth: videoMaxSize,
|
|
55
54
|
});
|
|
@@ -73,7 +72,7 @@ function AttachmentVideoBase(
|
|
|
73
72
|
}
|
|
74
73
|
};
|
|
75
74
|
|
|
76
|
-
useImperativeHandle(ref, () => playerRef.current || {}, []);
|
|
75
|
+
React.useImperativeHandle(ref, () => playerRef.current || {}, []);
|
|
77
76
|
|
|
78
77
|
return (
|
|
79
78
|
<div
|
|
@@ -96,7 +95,7 @@ function AttachmentVideoBase(
|
|
|
96
95
|
);
|
|
97
96
|
}
|
|
98
97
|
|
|
99
|
-
const AttachmentVideo = forwardRef(AttachmentVideoBase);
|
|
98
|
+
const AttachmentVideo = React.forwardRef(AttachmentVideoBase);
|
|
100
99
|
|
|
101
100
|
AttachmentVideo.displayName = 'AttachmentVideo';
|
|
102
101
|
|
|
@@ -125,7 +124,7 @@ function AttachmentImageBase({ uid, url, pending = false, onReady = () => {}, li
|
|
|
125
124
|
);
|
|
126
125
|
}
|
|
127
126
|
|
|
128
|
-
const AttachmentImage = forwardRef(AttachmentImageBase);
|
|
127
|
+
const AttachmentImage = React.forwardRef(AttachmentImageBase);
|
|
129
128
|
|
|
130
129
|
AttachmentImage.displayName = 'AttachmentImage';
|
|
131
130
|
|
|
@@ -201,7 +200,7 @@ function AttachmentBase({ mimeType, onReady = () => {}, containerProps = {}, lin
|
|
|
201
200
|
}
|
|
202
201
|
}
|
|
203
202
|
|
|
204
|
-
const Attachment = memo(AttachmentBase);
|
|
203
|
+
const Attachment = React.memo(AttachmentBase);
|
|
205
204
|
|
|
206
205
|
Attachment.displayName = 'Attachment';
|
|
207
206
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
3
3
|
import { PresenceBadge } from './presence';
|
|
4
4
|
import { cn } from './utils';
|
|
@@ -59,7 +59,7 @@ function AvatarBase(
|
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
const Avatar = memo(forwardRef(AvatarBase));
|
|
62
|
+
const Avatar = React.memo(React.forwardRef(AvatarBase));
|
|
63
63
|
|
|
64
64
|
Avatar.displayName = 'Avatar';
|
|
65
65
|
|
package/gen/components/badge.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { Slot } from '@radix-ui/react-slot';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
import { cn } from './utils';
|
|
@@ -38,7 +38,7 @@ function BadgeBase({ className, variant, asChild = false, ...props }, ref) {
|
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
const Badge = forwardRef(BadgeBase);
|
|
41
|
+
const Badge = React.forwardRef(BadgeBase);
|
|
42
42
|
|
|
43
43
|
Badge.displayName = 'Badge';
|
|
44
44
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { Slot } from '@radix-ui/react-slot';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
import { cn } from './utils';
|
|
@@ -50,8 +50,9 @@ function ButtonBase({ asChild = false, variant, size, className, ...props }, ref
|
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const Button = forwardRef(ButtonBase);
|
|
53
|
+
const Button = React.forwardRef(ButtonBase);
|
|
54
54
|
|
|
55
55
|
Button.displayName = 'Button';
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
// eslint-disable-next-line react-refresh/only-export-components
|
|
58
|
+
export { Button, buttonVariants };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { useInView } from 'react-intersection-observer';
|
|
3
3
|
import { Avatar } from './avatar';
|
|
4
4
|
import { FormattedDate } from './formatted-date';
|
|
@@ -7,8 +7,8 @@ import { cn } from './utils';
|
|
|
7
7
|
|
|
8
8
|
function ChatBubbleBase({ onView = () => {}, isLast, children, ...props }, ref) {
|
|
9
9
|
const [setRef, inView] = useInView();
|
|
10
|
-
const messageRef = useRef(null);
|
|
11
|
-
const setRefs = useCallback(
|
|
10
|
+
const messageRef = React.useRef(null);
|
|
11
|
+
const setRefs = React.useCallback(
|
|
12
12
|
(node) => {
|
|
13
13
|
messageRef.current = node;
|
|
14
14
|
setRef(node);
|
|
@@ -16,13 +16,13 @@ function ChatBubbleBase({ onView = () => {}, isLast, children, ...props }, ref)
|
|
|
16
16
|
[setRef]
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
useEffect(() => {
|
|
19
|
+
React.useEffect(() => {
|
|
20
20
|
if (inView) {
|
|
21
21
|
onView();
|
|
22
22
|
}
|
|
23
23
|
}, [inView, onView]);
|
|
24
24
|
|
|
25
|
-
useImperativeHandle(ref, () => messageRef.current || {}, []);
|
|
25
|
+
React.useImperativeHandle(ref, () => messageRef.current || {}, []);
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
28
|
<div ref={setRefs} {...props} className={cn('mt-2', isLast && 'mb-2', inView && 'view', props?.className)}>
|
|
@@ -31,7 +31,7 @@ function ChatBubbleBase({ onView = () => {}, isLast, children, ...props }, ref)
|
|
|
31
31
|
);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const ChatBubble = forwardRef(ChatBubbleBase);
|
|
34
|
+
const ChatBubble = React.forwardRef(ChatBubbleBase);
|
|
35
35
|
|
|
36
36
|
function ChatBubbleMessageBase(
|
|
37
37
|
{
|
|
@@ -111,7 +111,7 @@ function ChatBubbleMessageBase(
|
|
|
111
111
|
);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
const ChatBubbleMessage = memo(forwardRef(ChatBubbleMessageBase));
|
|
114
|
+
const ChatBubbleMessage = React.memo(React.forwardRef(ChatBubbleMessageBase));
|
|
115
115
|
|
|
116
116
|
ChatBubbleMessage.displayName = 'ChatBubbleMessage';
|
|
117
117
|
|
|
@@ -134,7 +134,7 @@ function ChatBubbleInfoBase(
|
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
const ChatBubbleInfo = memo(forwardRef(ChatBubbleInfoBase));
|
|
137
|
+
const ChatBubbleInfo = React.memo(React.forwardRef(ChatBubbleInfoBase));
|
|
138
138
|
|
|
139
139
|
ChatBubbleInfo.displayName = 'ChatBubbleInfo';
|
|
140
140
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import TextareaAutosize from 'react-textarea-autosize';
|
|
3
3
|
import { SendHorizontal } from 'lucide-react';
|
|
4
4
|
import { Label } from './label';
|
|
@@ -25,7 +25,7 @@ function ChatInputSendBase({ onSend = () => {}, iconElement, iconProps, ...props
|
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const ChatInputSend = forwardRef(ChatInputSendBase);
|
|
28
|
+
const ChatInputSend = React.forwardRef(ChatInputSendBase);
|
|
29
29
|
|
|
30
30
|
ChatInputSend.displayName = 'ChatInputSend';
|
|
31
31
|
|
|
@@ -45,11 +45,11 @@ function ChatInputBase(
|
|
|
45
45
|
},
|
|
46
46
|
ref
|
|
47
47
|
) {
|
|
48
|
-
const [value, setValue] = useState();
|
|
49
|
-
const textareaRef = useRef(null);
|
|
50
|
-
const textareaHeightRef = useRef(0);
|
|
51
|
-
const typingRef = useRef(false);
|
|
52
|
-
const typingTimeoutRef = useRef(undefined);
|
|
48
|
+
const [value, setValue] = React.useState();
|
|
49
|
+
const textareaRef = React.useRef(null);
|
|
50
|
+
const textareaHeightRef = React.useRef(0);
|
|
51
|
+
const typingRef = React.useRef(false);
|
|
52
|
+
const typingTimeoutRef = React.useRef(undefined);
|
|
53
53
|
const handleStopTyping = () => {
|
|
54
54
|
typingRef.current = false;
|
|
55
55
|
onTyping(false);
|
|
@@ -103,7 +103,7 @@ function ChatInputBase(
|
|
|
103
103
|
}
|
|
104
104
|
};
|
|
105
105
|
|
|
106
|
-
useEffect(() => {
|
|
106
|
+
React.useEffect(() => {
|
|
107
107
|
const textarea = textareaRef.current;
|
|
108
108
|
|
|
109
109
|
handleStopTyping();
|
|
@@ -115,7 +115,7 @@ function ChatInputBase(
|
|
|
115
115
|
};
|
|
116
116
|
}, [props.key]);
|
|
117
117
|
|
|
118
|
-
useImperativeHandle(ref, () => textareaRef.current || {}, []);
|
|
118
|
+
React.useImperativeHandle(ref, () => textareaRef.current || {}, []);
|
|
119
119
|
|
|
120
120
|
return (
|
|
121
121
|
<div {...containerProps} className={cn('flex items-end gap-2', containerProps?.className)}>
|
|
@@ -145,7 +145,7 @@ function ChatInputBase(
|
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
const ChatInput = forwardRef(ChatInputBase);
|
|
148
|
+
const ChatInput = React.forwardRef(ChatInputBase);
|
|
149
149
|
|
|
150
150
|
ChatInput.displayName = 'ChatInput';
|
|
151
151
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { Virtualizer } from 'virtua';
|
|
3
3
|
import { FilePickerDropzone } from './file-picker';
|
|
4
4
|
import { QuickActions } from './quick-actions';
|
|
@@ -38,11 +38,11 @@ function ChatListBase(
|
|
|
38
38
|
const ChatListWrapper = enableFilePickerDropzone ? FilePickerDropzone : DefaultChatListWrapper;
|
|
39
39
|
const chatListWrapperProps = enableFilePickerDropzone ? filePickerDropzoneProps : containerProps;
|
|
40
40
|
const itemsCount = Array.isArray(children) ? children.length : Array.isArray(props.data) ? props.data.length : 0;
|
|
41
|
-
const itemsCountRef = useRef(0);
|
|
42
|
-
const keyRef = useRef(undefined);
|
|
43
|
-
const [shouldPrependMessages, setShouldPrependMessages] = useState(false);
|
|
44
|
-
const [isPreparing, setIsPreparing] = useState(false);
|
|
45
|
-
const virtuaRef = useRef(null);
|
|
41
|
+
const itemsCountRef = React.useRef(0);
|
|
42
|
+
const keyRef = React.useRef(undefined);
|
|
43
|
+
const [shouldPrependMessages, setShouldPrependMessages] = React.useState(false);
|
|
44
|
+
const [isPreparing, setIsPreparing] = React.useState(false);
|
|
45
|
+
const virtuaRef = React.useRef(null);
|
|
46
46
|
const prepareNextVirtualizer = () => {
|
|
47
47
|
queueMicrotask(() => {
|
|
48
48
|
setIsPreparing(true);
|
|
@@ -66,7 +66,7 @@ function ChatListBase(
|
|
|
66
66
|
onScrollEndReached();
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
|
-
const scrollToBottom = useCallback(
|
|
69
|
+
const scrollToBottom = React.useCallback(
|
|
70
70
|
(force = false) => {
|
|
71
71
|
if (!virtuaRef.current) return;
|
|
72
72
|
|
|
@@ -81,7 +81,7 @@ function ChatListBase(
|
|
|
81
81
|
[itemsCount]
|
|
82
82
|
);
|
|
83
83
|
|
|
84
|
-
useEffect(() => {
|
|
84
|
+
React.useEffect(() => {
|
|
85
85
|
if (key !== keyRef.current) {
|
|
86
86
|
prepareNextVirtualizer();
|
|
87
87
|
onListReset?.(keyRef.current, key);
|
|
@@ -90,7 +90,7 @@ function ChatListBase(
|
|
|
90
90
|
}
|
|
91
91
|
}, [key, onListReset]);
|
|
92
92
|
|
|
93
|
-
useEffect(() => {
|
|
93
|
+
React.useEffect(() => {
|
|
94
94
|
if (itemsCountRef.current === 0 && itemsCount > 0) {
|
|
95
95
|
prepareNextVirtualizer();
|
|
96
96
|
onListCreate?.();
|
|
@@ -110,11 +110,11 @@ function ChatListBase(
|
|
|
110
110
|
}
|
|
111
111
|
}, [itemsCount, shouldPrependMessages, onListCreate, onListGrow, scrollToBottom]);
|
|
112
112
|
|
|
113
|
-
useEffect(() => {
|
|
113
|
+
React.useEffect(() => {
|
|
114
114
|
virtuaRef.current?.scrollBy(textareaMeasurement.shift);
|
|
115
115
|
}, [textareaMeasurement]);
|
|
116
116
|
|
|
117
|
-
useImperativeHandle(
|
|
117
|
+
React.useImperativeHandle(
|
|
118
118
|
ref,
|
|
119
119
|
() => ({
|
|
120
120
|
...(virtuaRef.current || {}),
|
|
@@ -127,7 +127,7 @@ function ChatListBase(
|
|
|
127
127
|
return null;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
if (minItemsCount
|
|
130
|
+
if (minItemsCount > itemsCount) {
|
|
131
131
|
return quickActionsVisible ? <QuickActions {...quickActionsProps} /> : <Spinner loading layout="centered" />;
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -144,7 +144,7 @@ function ChatListBase(
|
|
|
144
144
|
);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
const ChatList = forwardRef(ChatListBase);
|
|
147
|
+
const ChatList = React.forwardRef(ChatListBase);
|
|
148
148
|
|
|
149
149
|
ChatList.displayName = 'ChatList';
|
|
150
150
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
3
3
|
import { CheckIcon } from 'lucide-react';
|
|
4
4
|
import { cn } from './utils';
|
|
@@ -23,7 +23,7 @@ function CheckboxBase({ iconElement, iconProps, indicatorProps, ...props }, ref)
|
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const Checkbox = forwardRef(CheckboxBase);
|
|
26
|
+
const Checkbox = React.forwardRef(CheckboxBase);
|
|
27
27
|
|
|
28
28
|
Checkbox.displayName = 'Checkbox';
|
|
29
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
1
2
|
import { Avatar } from './avatar';
|
|
2
3
|
import { Users } from 'lucide-react';
|
|
3
|
-
import { forwardRef, memo } from 'react';
|
|
4
4
|
import { FormattedDate } from './formatted-date';
|
|
5
5
|
import { StatusSent } from './status-sent';
|
|
6
6
|
import { cn } from './utils';
|
|
@@ -145,7 +145,7 @@ function DialogItemBase(
|
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
const DialogItem = memo(forwardRef(DialogItemBase));
|
|
148
|
+
const DialogItem = React.memo(React.forwardRef(DialogItemBase));
|
|
149
149
|
|
|
150
150
|
DialogItem.displayName = 'DialogItem';
|
|
151
151
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { VList } from 'virtua';
|
|
3
3
|
import { PlaceholderText } from './placeholder-text';
|
|
4
4
|
|
|
@@ -32,7 +32,7 @@ function DialogsListBase(
|
|
|
32
32
|
},
|
|
33
33
|
ref
|
|
34
34
|
) {
|
|
35
|
-
const vListRef = useRef(null);
|
|
35
|
+
const vListRef = React.useRef(null);
|
|
36
36
|
const skeletonList = Array.from({
|
|
37
37
|
length: pendingListLength,
|
|
38
38
|
}).map((_, i) => <PendingItem key={`pending_dialog_item_${i}`} />);
|
|
@@ -53,7 +53,7 @@ function DialogsListBase(
|
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
useImperativeHandle(ref, () => vListRef.current || {}, []);
|
|
56
|
+
React.useImperativeHandle(ref, () => vListRef.current || {}, []);
|
|
57
57
|
|
|
58
58
|
if (placeholderVisible) {
|
|
59
59
|
return <PlaceholderText titles={placeholderTitles} className="text-base text-muted" />;
|
|
@@ -66,7 +66,7 @@ function DialogsListBase(
|
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const DialogsList = forwardRef(DialogsListBase);
|
|
69
|
+
const DialogsList = React.forwardRef(DialogsListBase);
|
|
70
70
|
|
|
71
71
|
DialogsList.displayName = 'DialogsList';
|
|
72
72
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { cn } from './utils';
|
|
3
3
|
|
|
4
4
|
function DismissLayerBase(
|
|
5
5
|
{ active, onDismiss, disableClickOutside = false, disableEscKeyPress = false, disabled, ...props },
|
|
6
6
|
ref
|
|
7
7
|
) {
|
|
8
|
-
const innerRef = useRef(null);
|
|
8
|
+
const innerRef = React.useRef(null);
|
|
9
9
|
|
|
10
|
-
useImperativeHandle(ref, () => innerRef.current || {}, []);
|
|
10
|
+
React.useImperativeHandle(ref, () => innerRef.current || {}, []);
|
|
11
11
|
|
|
12
|
-
const handleClickOrTouch = useCallback(
|
|
12
|
+
const handleClickOrTouch = React.useCallback(
|
|
13
13
|
(e) => {
|
|
14
14
|
if (!disableClickOutside && active && e.target === innerRef.current) {
|
|
15
15
|
onDismiss();
|
|
@@ -17,7 +17,7 @@ function DismissLayerBase(
|
|
|
17
17
|
},
|
|
18
18
|
[disableClickOutside, active, onDismiss]
|
|
19
19
|
);
|
|
20
|
-
const handleKeyEvent = useCallback(
|
|
20
|
+
const handleKeyEvent = React.useCallback(
|
|
21
21
|
(ev) => {
|
|
22
22
|
if (!disableEscKeyPress && active && ev.key === 'Escape') {
|
|
23
23
|
onDismiss();
|
|
@@ -26,7 +26,7 @@ function DismissLayerBase(
|
|
|
26
26
|
[disableEscKeyPress, active, onDismiss]
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
-
useEffect(() => {
|
|
29
|
+
React.useEffect(() => {
|
|
30
30
|
if (!disableEscKeyPress && active) {
|
|
31
31
|
document.addEventListener('keydown', handleKeyEvent);
|
|
32
32
|
|
|
@@ -50,7 +50,7 @@ function DismissLayerBase(
|
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const DismissLayer = forwardRef(DismissLayerBase);
|
|
53
|
+
const DismissLayer = React.forwardRef(DismissLayerBase);
|
|
54
54
|
|
|
55
55
|
DismissLayer.displayName = 'DismissLayer';
|
|
56
56
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { FilePlusCorner, Paperclip } from 'lucide-react';
|
|
3
3
|
import { Label } from './label';
|
|
4
4
|
import { cn } from './utils';
|
|
@@ -100,7 +100,7 @@ function FilePickerInputBase(
|
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
const FilePickerInput = forwardRef(FilePickerInputBase);
|
|
103
|
+
const FilePickerInput = React.forwardRef(FilePickerInputBase);
|
|
104
104
|
|
|
105
105
|
FilePickerInput.displayName = 'FilePickerInput';
|
|
106
106
|
|
|
@@ -121,7 +121,7 @@ function FilePickerDropzoneBase(
|
|
|
121
121
|
},
|
|
122
122
|
ref
|
|
123
123
|
) {
|
|
124
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
124
|
+
const [isDragging, setIsDragging] = React.useState(false);
|
|
125
125
|
const handleDragEvent = (event) => {
|
|
126
126
|
event.preventDefault();
|
|
127
127
|
event.stopPropagation();
|
|
@@ -193,7 +193,7 @@ function FilePickerDropzoneBase(
|
|
|
193
193
|
);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
const FilePickerDropzone = forwardRef(FilePickerDropzoneBase);
|
|
196
|
+
const FilePickerDropzone = React.forwardRef(FilePickerDropzoneBase);
|
|
197
197
|
|
|
198
198
|
FilePickerDropzone.displayName = 'FilePickerDropzone';
|
|
199
199
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { differenceInCalendarDays, format, formatDistanceToNow, isToday } from 'date-fns';
|
|
3
3
|
import { el, enUS, uk } from 'date-fns/locale';
|
|
4
4
|
import { cn } from './utils';
|
|
@@ -50,7 +50,7 @@ function FormattedDateBase({ date, language, distanceToNow, ...props }, ref) {
|
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const FormattedDate = memo(forwardRef(FormattedDateBase));
|
|
53
|
+
const FormattedDate = React.memo(React.forwardRef(FormattedDateBase));
|
|
54
54
|
|
|
55
55
|
FormattedDate.displayName = 'FormattedDate';
|
|
56
56
|
|
package/gen/components/input.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { cn } from './utils';
|
|
3
3
|
|
|
4
4
|
function InputBase(props, ref) {
|
|
@@ -16,7 +16,7 @@ function InputBase(props, ref) {
|
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const Input = forwardRef(InputBase);
|
|
19
|
+
const Input = React.forwardRef(InputBase);
|
|
20
20
|
|
|
21
21
|
Input.displayName = 'Input';
|
|
22
22
|
|
package/gen/components/label.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { Root as LabelRoot } from '@radix-ui/react-label';
|
|
3
3
|
import { cn } from './utils';
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ function LabelBase({ ...props }, ref) {
|
|
|
15
15
|
);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const Label = forwardRef(LabelBase);
|
|
18
|
+
const Label = React.forwardRef(LabelBase);
|
|
19
19
|
|
|
20
20
|
Label.displayName = 'Label';
|
|
21
21
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { Globe } from 'lucide-react';
|
|
3
3
|
import { cn } from './utils';
|
|
4
4
|
|
|
@@ -34,23 +34,23 @@ function LinkPreviewBase(
|
|
|
34
34
|
},
|
|
35
35
|
ref
|
|
36
36
|
) {
|
|
37
|
-
const [iconSrc, setIconSrc] = useState(icon);
|
|
38
|
-
const [imageSrc, setImageSrc] = useState(image);
|
|
39
|
-
const handleOnLoad = useCallback(
|
|
37
|
+
const [iconSrc, setIconSrc] = React.useState(icon);
|
|
38
|
+
const [imageSrc, setImageSrc] = React.useState(image);
|
|
39
|
+
const handleOnLoad = React.useCallback(
|
|
40
40
|
(event) => {
|
|
41
41
|
imageProps?.onLoad?.(event);
|
|
42
42
|
onReady();
|
|
43
43
|
},
|
|
44
44
|
[onReady, imageProps]
|
|
45
45
|
);
|
|
46
|
-
const handleIconOnError = useCallback(
|
|
46
|
+
const handleIconOnError = React.useCallback(
|
|
47
47
|
(event) => {
|
|
48
48
|
iconProps?.onError?.(event);
|
|
49
49
|
setIconSrc(undefined);
|
|
50
50
|
},
|
|
51
51
|
[iconProps]
|
|
52
52
|
);
|
|
53
|
-
const handleImageOnError = useCallback(
|
|
53
|
+
const handleImageOnError = React.useCallback(
|
|
54
54
|
(event) => {
|
|
55
55
|
imageProps?.onError?.(event);
|
|
56
56
|
setImageSrc(undefined);
|
|
@@ -124,7 +124,7 @@ function LinkPreviewBase(
|
|
|
124
124
|
);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
const LinkPreview = memo(forwardRef(LinkPreviewBase));
|
|
127
|
+
const LinkPreview = React.memo(React.forwardRef(LinkPreviewBase));
|
|
128
128
|
|
|
129
129
|
LinkPreview.displayName = 'LinkPreview';
|
|
130
130
|
|