@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.
Files changed (79) hide show
  1. package/README.md +33 -6
  2. package/gen/components/alert-dialog.jsx +2 -2
  3. package/gen/components/attachment.jsx +10 -11
  4. package/gen/components/avatar.jsx +2 -2
  5. package/gen/components/badge.jsx +2 -2
  6. package/gen/components/button.jsx +4 -3
  7. package/gen/components/chat-bubble.jsx +8 -8
  8. package/gen/components/chat-input.jsx +10 -10
  9. package/gen/components/chat-list.jsx +13 -13
  10. package/gen/components/checkbox.jsx +2 -2
  11. package/gen/components/dialog-item.jsx +2 -2
  12. package/gen/components/dialogs-list.jsx +4 -4
  13. package/gen/components/dismiss-layer.jsx +7 -7
  14. package/gen/components/file-picker.jsx +4 -4
  15. package/gen/components/formatted-date.jsx +2 -2
  16. package/gen/components/input.jsx +2 -2
  17. package/gen/components/label.jsx +2 -2
  18. package/gen/components/link-preview.jsx +7 -7
  19. package/gen/components/linkify-text.jsx +5 -5
  20. package/gen/components/placeholder-text.jsx +1 -2
  21. package/gen/components/presence.jsx +1 -0
  22. package/gen/components/quick-actions.jsx +2 -2
  23. package/gen/components/search.jsx +3 -3
  24. package/gen/components/spinner.jsx +3 -2
  25. package/gen/components/status-call.jsx +1 -0
  26. package/gen/components/status-indicator.jsx +2 -2
  27. package/gen/components/status-sent.jsx +1 -0
  28. package/gen/components/stream-view.jsx +16 -16
  29. package/package.json +14 -14
  30. package/src/components/alert-dialog.tsx +2 -3
  31. package/src/components/attachment.tsx +12 -13
  32. package/src/components/avatar.tsx +2 -3
  33. package/src/components/badge.tsx +2 -3
  34. package/src/components/button.tsx +4 -4
  35. package/src/components/chat-bubble.tsx +9 -10
  36. package/src/components/chat-input.tsx +17 -13
  37. package/src/components/chat-list.tsx +31 -24
  38. package/src/components/checkbox.tsx +2 -3
  39. package/src/components/dialog-item.tsx +2 -3
  40. package/src/components/dialogs-list.tsx +4 -5
  41. package/src/components/dismiss-layer.tsx +7 -8
  42. package/src/components/file-picker.tsx +4 -5
  43. package/src/components/formatted-date.tsx +4 -3
  44. package/src/components/input.tsx +2 -3
  45. package/src/components/label.tsx +2 -3
  46. package/src/components/link-preview.tsx +16 -26
  47. package/src/components/linkify-text.tsx +5 -6
  48. package/src/components/placeholder-text.tsx +1 -2
  49. package/src/components/presence.tsx +1 -1
  50. package/src/components/quick-actions.tsx +2 -3
  51. package/src/components/search.tsx +3 -4
  52. package/src/components/spinner.tsx +3 -2
  53. package/src/components/status-call.tsx +1 -0
  54. package/src/components/status-indicator.tsx +2 -3
  55. package/src/components/status-sent.tsx +1 -0
  56. package/src/components/stream-view.tsx +18 -17
  57. package/src/components/connectycube-ui/attachment.tsx +0 -269
  58. package/src/components/connectycube-ui/avatar.jsx +0 -54
  59. package/src/components/connectycube-ui/avatar.tsx +0 -77
  60. package/src/components/connectycube-ui/badge.jsx +0 -45
  61. package/src/components/connectycube-ui/badge.tsx +0 -42
  62. package/src/components/connectycube-ui/chat-input.tsx +0 -174
  63. package/src/components/connectycube-ui/chat-message.tsx +0 -138
  64. package/src/components/connectycube-ui/dialog-item.jsx +0 -149
  65. package/src/components/connectycube-ui/dialog-item.tsx +0 -188
  66. package/src/components/connectycube-ui/file-picker.jsx +0 -200
  67. package/src/components/connectycube-ui/file-picker.tsx +0 -231
  68. package/src/components/connectycube-ui/formatted-date.jsx +0 -57
  69. package/src/components/connectycube-ui/formatted-date.tsx +0 -57
  70. package/src/components/connectycube-ui/label.jsx +0 -22
  71. package/src/components/connectycube-ui/label.tsx +0 -23
  72. package/src/components/connectycube-ui/link-preview.tsx +0 -149
  73. package/src/components/connectycube-ui/linkify-text.tsx +0 -40
  74. package/src/components/connectycube-ui/presence.jsx +0 -81
  75. package/src/components/connectycube-ui/presence.tsx +0 -96
  76. package/src/components/connectycube-ui/status-sent.jsx +0 -21
  77. package/src/components/connectycube-ui/status-sent.tsx +0 -25
  78. package/src/components/connectycube-ui/utils.js +0 -10
  79. package/src/components/connectycube-ui/utils.ts +0 -10
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # DRAFT: @connectycube/react-ui-kit
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
- - Install specified dependencies automatically
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 | Description |
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 { forwardRef } from 'react';
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 { forwardRef, memo, useImperativeHandle, useRef, useState } from 'react';
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({ url, pending = false, children, ...props }, ref) {
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 { memo, forwardRef } from 'react';
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
 
@@ -1,4 +1,4 @@
1
- import { forwardRef } from 'react';
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 { forwardRef } from 'react';
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
- export { Button };
57
+ // eslint-disable-next-line react-refresh/only-export-components
58
+ export { Button, buttonVariants };
@@ -1,4 +1,4 @@
1
- import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
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 { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
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 React, { useRef, useEffect, useState, useImperativeHandle, forwardRef, useCallback } from 'react';
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 >= itemsCount) {
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 { forwardRef } from 'react';
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 { forwardRef, useImperativeHandle, useRef } from 'react';
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 { useCallback, useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
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 { forwardRef, useState } from 'react';
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 { forwardRef, memo } from 'react';
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
 
@@ -1,4 +1,4 @@
1
- import { forwardRef } from 'react';
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
 
@@ -1,4 +1,4 @@
1
- import { forwardRef } from 'react';
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 { forwardRef, memo, useCallback, useState } from 'react';
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