@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
@@ -1,4 +1,4 @@
1
- import { forwardRef, memo, useEffect, useMemo, useRef } from 'react';
1
+ import * as React from 'react';
2
2
  import Linkify from 'linkify-react';
3
3
  import { cn } from './utils';
4
4
 
@@ -21,8 +21,8 @@ function LinkifyTextBase(
21
21
  },
22
22
  ref
23
23
  ) {
24
- const pendingRef = useRef(pending);
25
- const options = useMemo(
24
+ const pendingRef = React.useRef(pending);
25
+ const options = React.useMemo(
26
26
  () => ({
27
27
  ...DEFAULT_LINKIFY_OPTIONS,
28
28
  ...linkifyProps,
@@ -31,7 +31,7 @@ function LinkifyTextBase(
31
31
  [linkifyProps]
32
32
  );
33
33
 
34
- useEffect(() => {
34
+ React.useEffect(() => {
35
35
  if (pendingRef.current && !pending) {
36
36
  onReady();
37
37
  }
@@ -63,7 +63,7 @@ function LinkifyTextBase(
63
63
  );
64
64
  }
65
65
 
66
- const LinkifyText = memo(forwardRef(LinkifyTextBase));
66
+ const LinkifyText = React.memo(React.forwardRef(LinkifyTextBase));
67
67
 
68
68
  LinkifyText.displayName = 'LinkifyText';
69
69
 
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import { forwardRef } from 'react';
3
2
  import { cn } from './utils';
4
3
 
5
4
  function PlaceholderTextBase({ title, titles = [], rowProps, ...props }, ref) {
@@ -24,7 +23,7 @@ function PlaceholderTextBase({ title, titles = [], rowProps, ...props }, ref) {
24
23
  );
25
24
  }
26
25
 
27
- const PlaceholderText = forwardRef(PlaceholderTextBase);
26
+ const PlaceholderText = React.forwardRef(PlaceholderTextBase);
28
27
 
29
28
  PlaceholderText.displayName = 'PlaceholderText';
30
29
 
@@ -1,3 +1,4 @@
1
+ import * as React from 'react';
1
2
  import { capitalize, cn } from './utils';
2
3
 
3
4
  function PresenceBadge({ status, ...props }) {
@@ -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 QuickActionsBase(
@@ -55,7 +55,7 @@ function QuickActionsBase(
55
55
  );
56
56
  }
57
57
 
58
- const QuickActions = forwardRef(QuickActionsBase);
58
+ const QuickActions = React.forwardRef(QuickActionsBase);
59
59
 
60
60
  QuickActions.displayName = 'QuickActions';
61
61
 
@@ -1,4 +1,4 @@
1
- import { forwardRef, useState } from 'react';
1
+ import * as React from 'react';
2
2
  import { cn } from './utils';
3
3
  import { Input } from './input';
4
4
  import { Search as SearchIcon, X as CloseIcon } from 'lucide-react';
@@ -16,7 +16,7 @@ function SearchBase(
16
16
  },
17
17
  ref
18
18
  ) {
19
- const [value, setValue] = useState('');
19
+ const [value, setValue] = React.useState('');
20
20
  const handleOnSearch = (e) => {
21
21
  const keyword = e.target.value;
22
22
 
@@ -68,7 +68,7 @@ function SearchBase(
68
68
  );
69
69
  }
70
70
 
71
- const Search = forwardRef(SearchBase);
71
+ const Search = React.forwardRef(SearchBase);
72
72
 
73
73
  Search.displayName = 'Search';
74
74
 
@@ -1,7 +1,8 @@
1
+ import * as React from 'react';
1
2
  import { Loader, LoaderCircle } from 'lucide-react';
2
3
  import { cn } from './utils';
3
4
 
4
- function Spinner({ loading = false, layout = 'flow', type = 'default', ...props }) {
5
+ const Spinner = ({ loading = false, layout = 'flow', type = 'default', ...props }) => {
5
6
  const LoaderIcon = type === 'circle' ? LoaderCircle : Loader;
6
7
 
7
8
  if (!loading) {
@@ -29,7 +30,7 @@ function Spinner({ loading = false, layout = 'flow', type = 'default', ...props
29
30
  default:
30
31
  return spinnerElement;
31
32
  }
32
- }
33
+ };
33
34
 
34
35
  Spinner.displayName = 'Spinner';
35
36
 
@@ -1,3 +1,4 @@
1
+ import * as React from 'react';
1
2
  import { Phone, PhoneIncoming, PhoneMissed, PhoneOutgoing } from 'lucide-react';
2
3
  import { cn } from './utils';
3
4
 
@@ -1,4 +1,4 @@
1
- import { forwardRef } from 'react';
1
+ import * as React from 'react';
2
2
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
3
3
  import { cn } from './utils';
4
4
 
@@ -62,7 +62,7 @@ function StatusIndicatorBase(
62
62
  );
63
63
  }
64
64
 
65
- const StatusIndicator = forwardRef(StatusIndicatorBase);
65
+ const StatusIndicator = React.forwardRef(StatusIndicatorBase);
66
66
 
67
67
  StatusIndicator.displayName = 'StatusIndicator';
68
68
 
@@ -1,3 +1,4 @@
1
+ import * as React from 'react';
1
2
  import { Ban, Check, CheckCheck, Clock } from 'lucide-react';
2
3
  import { cn } from './utils';
3
4
 
@@ -1,17 +1,17 @@
1
- import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
1
+ import * as React from 'react';
2
2
  import { Maximize, Minimize, PictureInPicture2 } from 'lucide-react';
3
3
  import { cn, getRandomString } from './utils';
4
4
 
5
5
  function StreamViewBase({ id, stream, mirror, className, muted, ...props }, ref) {
6
- const innerRef = useRef(null);
7
- const elementId = useMemo(() => id ?? `stream-${getRandomString()}`, [id]);
6
+ const innerRef = React.useRef(null);
7
+ const elementId = React.useMemo(() => id ?? `stream-${getRandomString()}`, [id]);
8
8
  const isMuted = typeof muted === 'boolean' ? muted : false;
9
9
  const defaultClassName = 'size-full object-contain';
10
10
  const mirrorClassName = mirror ? 'scale-x-[-1]' : '';
11
11
 
12
- useImperativeHandle(ref, () => innerRef.current || {}, []);
12
+ React.useImperativeHandle(ref, () => innerRef.current || {}, []);
13
13
 
14
- useEffect(() => {
14
+ React.useEffect(() => {
15
15
  if (innerRef.current && stream) {
16
16
  innerRef.current.srcObject = stream;
17
17
 
@@ -44,7 +44,7 @@ function StreamViewBase({ id, stream, mirror, className, muted, ...props }, ref)
44
44
  );
45
45
  }
46
46
 
47
- const StreamView = forwardRef(StreamViewBase);
47
+ const StreamView = React.forwardRef(StreamViewBase);
48
48
 
49
49
  StreamView.displayName = 'StreamView';
50
50
 
@@ -55,7 +55,7 @@ function LocalStreamViewBase({ muted, mirror, ...props }, ref) {
55
55
  return <StreamView ref={ref} muted={isMuted} mirror={isMirror} {...props} />;
56
56
  }
57
57
 
58
- const LocalStreamView = forwardRef(LocalStreamViewBase);
58
+ const LocalStreamView = React.forwardRef(LocalStreamViewBase);
59
59
 
60
60
  LocalStreamView.displayName = 'LocalStreamView';
61
61
 
@@ -66,7 +66,7 @@ function RemoteStreamViewBase({ muted, mirror, ...props }, ref) {
66
66
  return <StreamView ref={ref} muted={isMuted} mirror={isMirror} {...props} />;
67
67
  }
68
68
 
69
- const RemoteStreamView = forwardRef(RemoteStreamViewBase);
69
+ const RemoteStreamView = React.forwardRef(RemoteStreamViewBase);
70
70
 
71
71
  RemoteStreamView.displayName = 'RemoteStreamView';
72
72
 
@@ -86,10 +86,10 @@ function FullscreenStreamViewBase(
86
86
  },
87
87
  ref
88
88
  ) {
89
- const innerRef = useRef(null);
90
- const [isFullscreen, setIsFullscreen] = useState(false);
91
- const [isPictureInPicture, setIsPictureInPicture] = useState(false);
92
- const toggleFullscreen = useCallback(async () => {
89
+ const innerRef = React.useRef(null);
90
+ const [isFullscreen, setIsFullscreen] = React.useState(false);
91
+ const [isPictureInPicture, setIsPictureInPicture] = React.useState(false);
92
+ const toggleFullscreen = React.useCallback(async () => {
93
93
  const container = innerRef.current;
94
94
 
95
95
  if (!container) return;
@@ -108,13 +108,13 @@ function FullscreenStreamViewBase(
108
108
  console.error('Fullscreen error:', err);
109
109
  }
110
110
  }, []);
111
- const togglePictureInPicture = useCallback(() => {
111
+ const togglePictureInPicture = React.useCallback(() => {
112
112
  if (pipElement) {
113
113
  setIsPictureInPicture((prevState) => !prevState);
114
114
  }
115
115
  }, [pipElement]);
116
116
 
117
- useImperativeHandle(
117
+ React.useImperativeHandle(
118
118
  ref,
119
119
  () => ({
120
120
  ...(innerRef.current || {}),
@@ -126,7 +126,7 @@ function FullscreenStreamViewBase(
126
126
  [isFullscreen, isPictureInPicture, toggleFullscreen, togglePictureInPicture]
127
127
  );
128
128
 
129
- useEffect(() => {
129
+ React.useEffect(() => {
130
130
  const onFullscreenChange = () => {
131
131
  setIsFullscreen(!!document.fullscreenElement);
132
132
  setIsPictureInPicture(!!document.fullscreenElement);
@@ -188,7 +188,7 @@ function FullscreenStreamViewBase(
188
188
  );
189
189
  }
190
190
 
191
- const FullscreenStreamView = forwardRef(FullscreenStreamViewBase);
191
+ const FullscreenStreamView = React.forwardRef(FullscreenStreamViewBase);
192
192
 
193
193
  FullscreenStreamView.displayName = 'FullscreenStreamView';
194
194
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@connectycube/react-ui-kit",
3
- "version": "0.0.22",
3
+ "version": "0.1.2",
4
4
  "description": "Simple React UI Kit generator with TSX/JSX",
5
5
  "homepage": "https://github.com/ConnectyCube/react-ui-kit#readme",
6
6
  "bugs": {
@@ -72,42 +72,42 @@
72
72
  "class-variance-authority": "^0.7.1",
73
73
  "clsx": "^2.1.1",
74
74
  "date-fns": "^4.1.0",
75
+ "execa": "^9.6.1",
76
+ "fast-glob": "^3.3.3",
77
+ "fs-extra": "^11.3.3",
75
78
  "linkify-react": "^4.3.2",
76
79
  "lucide-react": "^0.562.0",
80
+ "prettier": "^3.8.1",
81
+ "prompts": "^2.4.2",
77
82
  "react-intersection-observer": "^10.0.0",
78
83
  "react-textarea-autosize": "^8.5.9",
79
84
  "tailwind-merge": "^3.4.0",
80
- "virtua": "^0.48.2"
85
+ "virtua": "^0.48.3"
81
86
  },
82
87
  "peerDependencies": {
83
88
  "react": ">=18",
84
89
  "react-dom": ">=18"
85
90
  },
86
91
  "devDependencies": {
87
- "@babel/core": "^7.28.5",
92
+ "@babel/core": "^7.28.6",
88
93
  "@babel/preset-typescript": "^7.28.5",
89
94
  "@eslint/js": "^9.39.2",
90
95
  "@rollup/plugin-commonjs": "^29.0.0",
91
96
  "@rollup/plugin-node-resolve": "^16.0.3",
92
97
  "@rollup/plugin-terser": "^0.4.4",
93
98
  "@rollup/plugin-typescript": "^12.3.0",
94
- "@stylistic/eslint-plugin": "^5.6.1",
95
- "@types/node": "^25.0.3",
96
- "@types/react": "^19.2.7",
99
+ "@stylistic/eslint-plugin": "^5.7.0",
100
+ "@types/node": "^25.0.8",
101
+ "@types/react": "^19.2.8",
97
102
  "eslint": "^9.39.2",
98
103
  "eslint-plugin-react-hooks": "^7.0.1",
99
104
  "eslint-plugin-react-refresh": "^0.4.26",
100
- "execa": "^9.6.1",
101
- "fast-glob": "^3.3.3",
102
- "fs-extra": "^11.3.3",
103
- "globals": "^16.5.0",
104
- "prettier": "^3.7.4",
105
- "prompts": "^2.4.2",
106
- "rollup": "^4.53.5",
105
+ "globals": "^17.0.0",
106
+ "rollup": "^4.55.1",
107
107
  "rollup-plugin-peer-deps-external": "^2.2.4",
108
108
  "tslib": "^2.8.1",
109
109
  "typescript": "^5.9.3",
110
- "typescript-eslint": "^8.50.0"
110
+ "typescript-eslint": "^8.53.0"
111
111
  },
112
112
  "engines": {
113
113
  "node": ">=18"
@@ -1,5 +1,4 @@
1
- import type React from 'react';
2
- import { forwardRef } from 'react';
1
+ import * as React from 'react';
3
2
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
4
3
  import { Button, type ButtonProps } from './button';
5
4
  import { cn } from './utils';
@@ -111,7 +110,7 @@ function AlertDialogBase(
111
110
  );
112
111
  }
113
112
 
114
- const AlertDialog = forwardRef<HTMLDivElement, AlertDialogProps>(AlertDialogBase);
113
+ const AlertDialog = React.forwardRef<HTMLDivElement, AlertDialogProps>(AlertDialogBase);
115
114
 
116
115
  AlertDialog.displayName = 'AlertDialog';
117
116
 
@@ -1,5 +1,4 @@
1
- import type React from 'react';
2
- import { forwardRef, memo, useImperativeHandle, useRef, useState } from 'react';
1
+ import * as React from 'react';
3
2
  import { File, FileXCorner, type LucideProps } from 'lucide-react';
4
3
  import { Spinner } from './spinner';
5
4
  import { cn, getRandomString } from './utils';
@@ -14,7 +13,8 @@ interface AttachmentProps {
14
13
  containerProps?: React.ComponentProps<'div'>;
15
14
  }
16
15
 
17
- interface AttachmentLinkProps extends React.ComponentProps<'a'>, Omit<AttachmentProps, 'containerProps' & 'mimeType'> {}
16
+ interface AttachmentLinkProps
17
+ extends React.ComponentProps<'a'>, Omit<AttachmentProps, 'url' & 'containerProps' & 'mimeType'> {}
18
18
 
19
19
  interface AttachmentImageProps
20
20
  extends React.ComponentProps<'img'>, Omit<AttachmentProps, 'containerProps' & 'mimeType'> {}
@@ -36,7 +36,7 @@ interface AttachmentFailedProps extends LucideProps, Omit<AttachmentProps, 'link
36
36
  }
37
37
 
38
38
  function AttachmentLinkBase(
39
- { url, pending = false, children, ...props }: AttachmentLinkProps,
39
+ { pending = false, children, ...props }: AttachmentLinkProps,
40
40
  ref: React.ForwardedRef<HTMLAnchorElement>
41
41
  ) {
42
42
  return (
@@ -45,7 +45,6 @@ function AttachmentLinkBase(
45
45
  target="_blank"
46
46
  rel="noopener noreferrer"
47
47
  {...props}
48
- href={url}
49
48
  className={cn(
50
49
  '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',
51
50
  props?.className
@@ -57,7 +56,7 @@ function AttachmentLinkBase(
57
56
  );
58
57
  }
59
58
 
60
- const AttachmentLink = forwardRef<HTMLAnchorElement, AttachmentLinkProps>(AttachmentLinkBase);
59
+ const AttachmentLink = React.forwardRef<HTMLAnchorElement, AttachmentLinkProps>(AttachmentLinkBase);
61
60
 
62
61
  AttachmentLink.displayName = 'AttachmentLink';
63
62
 
@@ -78,7 +77,7 @@ function AttachmentAudioBase(
78
77
  );
79
78
  }
80
79
 
81
- const AttachmentAudio = forwardRef<HTMLAudioElement, AttachmentAudioProps>(AttachmentAudioBase);
80
+ const AttachmentAudio = React.forwardRef<HTMLAudioElement, AttachmentAudioProps>(AttachmentAudioBase);
82
81
 
83
82
  function AttachmentVideoBase(
84
83
  { uid, url, maxSize = 360, pending = false, onReady = () => {}, containerProps, ...props }: AttachmentVideoProps,
@@ -86,8 +85,8 @@ function AttachmentVideoBase(
86
85
  ) {
87
86
  const videoId = `attachment_video_${uid || getRandomString()}`;
88
87
  const videoMaxSize = `${maxSize}px`;
89
- const playerRef = useRef<HTMLVideoElement>(null);
90
- const [style, setStyle] = useState<React.CSSProperties>({
88
+ const playerRef = React.useRef<HTMLVideoElement>(null);
89
+ const [style, setStyle] = React.useState<React.CSSProperties>({
91
90
  maxHeight: videoMaxSize,
92
91
  maxWidth: videoMaxSize,
93
92
  });
@@ -106,7 +105,7 @@ function AttachmentVideoBase(
106
105
  }
107
106
  };
108
107
 
109
- useImperativeHandle(ref, () => playerRef.current || ({} as HTMLVideoElement), []);
108
+ React.useImperativeHandle(ref, () => playerRef.current || ({} as HTMLVideoElement), []);
110
109
 
111
110
  return (
112
111
  <div
@@ -129,7 +128,7 @@ function AttachmentVideoBase(
129
128
  );
130
129
  }
131
130
 
132
- const AttachmentVideo = forwardRef<HTMLVideoElement, AttachmentVideoProps>(AttachmentVideoBase);
131
+ const AttachmentVideo = React.forwardRef<HTMLVideoElement, AttachmentVideoProps>(AttachmentVideoBase);
133
132
 
134
133
  AttachmentVideo.displayName = 'AttachmentVideo';
135
134
 
@@ -161,7 +160,7 @@ function AttachmentImageBase(
161
160
  );
162
161
  }
163
162
 
164
- const AttachmentImage = forwardRef<HTMLImageElement, AttachmentImageProps>(AttachmentImageBase);
163
+ const AttachmentImage = React.forwardRef<HTMLImageElement, AttachmentImageProps>(AttachmentImageBase);
165
164
 
166
165
  AttachmentImage.displayName = 'AttachmentImage';
167
166
 
@@ -249,7 +248,7 @@ function AttachmentBase({
249
248
  }
250
249
  }
251
250
 
252
- const Attachment = memo(AttachmentBase);
251
+ const Attachment = React.memo(AttachmentBase);
253
252
 
254
253
  Attachment.displayName = 'Attachment';
255
254
 
@@ -1,5 +1,4 @@
1
- import type React from 'react';
2
- import { memo, forwardRef } from 'react';
1
+ import * as React from 'react';
3
2
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
4
3
  import { PresenceBadge, type PresenceStatus, type PresenceBadgeProps } from './presence';
5
4
  import { cn } from './utils';
@@ -72,7 +71,7 @@ function AvatarBase(
72
71
  );
73
72
  }
74
73
 
75
- const Avatar = memo(forwardRef<HTMLDivElement, AvatarProps>(AvatarBase));
74
+ const Avatar = React.memo(React.forwardRef<HTMLDivElement, AvatarProps>(AvatarBase));
76
75
 
77
76
  Avatar.displayName = 'Avatar';
78
77
 
@@ -1,5 +1,4 @@
1
- import type React from 'react';
2
- import { forwardRef } from 'react';
1
+ import * as React from 'react';
3
2
  import { Slot } from '@radix-ui/react-slot';
4
3
  import { cva, type VariantProps } from 'class-variance-authority';
5
4
  import { cn } from './utils';
@@ -35,7 +34,7 @@ function BadgeBase(
35
34
  return <Comp ref={ref} {...props} className={cn(badgeVariants({ variant }), className)} />;
36
35
  }
37
36
 
38
- const Badge = forwardRef<HTMLElement, BadgeProps>(BadgeBase);
37
+ const Badge = React.forwardRef<HTMLElement, BadgeProps>(BadgeBase);
39
38
 
40
39
  Badge.displayName = 'Badge';
41
40
 
@@ -1,5 +1,4 @@
1
- import type React from 'react';
2
- import { forwardRef } from 'react';
1
+ import * as React from 'react';
3
2
  import { Slot } from '@radix-ui/react-slot';
4
3
  import { cva, type VariantProps } from 'class-variance-authority';
5
4
  import { cn } from './utils';
@@ -51,8 +50,9 @@ function ButtonBase(
51
50
  );
52
51
  }
53
52
 
54
- const Button = forwardRef<HTMLButtonElement, ButtonProps>(ButtonBase);
53
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(ButtonBase);
55
54
 
56
55
  Button.displayName = 'Button';
57
56
 
58
- export { Button, type ButtonProps };
57
+ // eslint-disable-next-line react-refresh/only-export-components
58
+ export { Button, buttonVariants, type ButtonProps };
@@ -1,5 +1,4 @@
1
- import type React from 'react';
2
- import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
1
+ import * as React from 'react';
3
2
  import { useInView } from 'react-intersection-observer';
4
3
  import { Avatar, type AvatarProps } from './avatar';
5
4
  import { FormattedDate, type FormattedDateProps } from './formatted-date';
@@ -38,8 +37,8 @@ function ChatBubbleBase(
38
37
  ref: React.ForwardedRef<HTMLDivElement>
39
38
  ) {
40
39
  const [setRef, inView] = useInView();
41
- const messageRef = useRef<HTMLDivElement>(null);
42
- const setRefs = useCallback(
40
+ const messageRef = React.useRef<HTMLDivElement>(null);
41
+ const setRefs = React.useCallback(
43
42
  (node: HTMLDivElement) => {
44
43
  messageRef.current = node;
45
44
  setRef(node);
@@ -47,13 +46,13 @@ function ChatBubbleBase(
47
46
  [setRef]
48
47
  );
49
48
 
50
- useEffect(() => {
49
+ React.useEffect(() => {
51
50
  if (inView) {
52
51
  onView();
53
52
  }
54
53
  }, [inView, onView]);
55
54
 
56
- useImperativeHandle(ref, () => messageRef.current || ({} as HTMLDivElement), []);
55
+ React.useImperativeHandle(ref, () => messageRef.current || ({} as HTMLDivElement), []);
57
56
 
58
57
  return (
59
58
  <div ref={setRefs} {...props} className={cn('mt-2', isLast && 'mb-2', inView && 'view', props?.className)}>
@@ -62,7 +61,7 @@ function ChatBubbleBase(
62
61
  );
63
62
  }
64
63
 
65
- const ChatBubble = forwardRef<HTMLDivElement, ChatBubbleProps>(ChatBubbleBase);
64
+ const ChatBubble = React.forwardRef<HTMLDivElement, ChatBubbleProps>(ChatBubbleBase);
66
65
 
67
66
  function ChatBubbleMessageBase(
68
67
  {
@@ -110,7 +109,7 @@ function ChatBubbleMessageBase(
110
109
 
111
110
  <div
112
111
  className={cn(
113
- 'relative flex flex-col min-w-42 max-w-120 rounded-xl px-2 pt-2 pb-6 shadow-sm',
112
+ 'relative flex flex-col min-w-50 max-w-120 rounded-xl px-2 pt-2 pb-6 shadow-sm',
114
113
  fromMe ? 'bg-gray-200' : 'bg-blue-200',
115
114
  hasAvatarMargin && 'ml-9',
116
115
  bubbleProps?.className
@@ -138,7 +137,7 @@ function ChatBubbleMessageBase(
138
137
  );
139
138
  }
140
139
 
141
- const ChatBubbleMessage = memo(forwardRef<HTMLDivElement, ChatBubbleMessageProps>(ChatBubbleMessageBase));
140
+ const ChatBubbleMessage = React.memo(React.forwardRef<HTMLDivElement, ChatBubbleMessageProps>(ChatBubbleMessageBase));
142
141
 
143
142
  ChatBubbleMessage.displayName = 'ChatBubbleMessage';
144
143
 
@@ -169,7 +168,7 @@ function ChatBubbleInfoBase(
169
168
  );
170
169
  }
171
170
 
172
- const ChatBubbleInfo = memo(forwardRef<HTMLDivElement, ChatBubbleInfoProps>(ChatBubbleInfoBase));
171
+ const ChatBubbleInfo = React.memo(React.forwardRef<HTMLDivElement, ChatBubbleInfoProps>(ChatBubbleInfoBase));
173
172
 
174
173
  ChatBubbleInfo.displayName = 'ChatBubbleInfo';
175
174
 
@@ -1,5 +1,4 @@
1
- import type React from 'react';
2
- import { ChangeEvent, forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
1
+ import * as React from 'react';
3
2
  import TextareaAutosize, { type TextareaAutosizeProps, type TextareaHeightChangeMeta } from 'react-textarea-autosize';
4
3
  import { SendHorizontal, type LucideProps } from 'lucide-react';
5
4
  import { Label, type LabelProps } from './label';
@@ -48,7 +47,7 @@ function ChatInputSendBase(
48
47
  );
49
48
  }
50
49
 
51
- const ChatInputSend = forwardRef<HTMLLabelElement, ChatInputSendProps>(ChatInputSendBase);
50
+ const ChatInputSend = React.forwardRef<HTMLLabelElement, ChatInputSendProps>(ChatInputSendBase);
52
51
 
53
52
  ChatInputSend.displayName = 'ChatInputSend';
54
53
 
@@ -68,11 +67,11 @@ function ChatInputBase(
68
67
  }: ChatInputProps,
69
68
  ref: React.ForwardedRef<HTMLTextAreaElement>
70
69
  ) {
71
- const [value, setValue] = useState<string>();
72
- const textareaRef = useRef<HTMLTextAreaElement>(null);
73
- const textareaHeightRef = useRef<number>(0);
74
- const typingRef = useRef<boolean>(false);
75
- const typingTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
70
+ const [value, setValue] = React.useState<string>();
71
+ const textareaRef = React.useRef<HTMLTextAreaElement>(null);
72
+ const textareaHeightRef = React.useRef<number>(0);
73
+ const typingRef = React.useRef<boolean>(false);
74
+ const typingTimeoutRef = React.useRef<NodeJS.Timeout | undefined>(undefined);
76
75
  const handleStopTyping = () => {
77
76
  typingRef.current = false;
78
77
  onTyping(false);
@@ -82,7 +81,9 @@ function ChatInputBase(
82
81
  typingTimeoutRef.current = undefined;
83
82
  }
84
83
  };
85
- const handleOnChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
84
+ const handleOnChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
85
+ props.onChange?.(event);
86
+
86
87
  const { data } = event.nativeEvent as InputEvent;
87
88
 
88
89
  setValue(event.target.value);
@@ -105,6 +106,8 @@ function ChatInputBase(
105
106
  }
106
107
  };
107
108
  const handleOnHeightChange = (height: number, meta: TextareaHeightChangeMeta) => {
109
+ props.onHeightChange?.(height, meta);
110
+
108
111
  if (!height && !meta) return;
109
112
 
110
113
  if (height !== textareaHeightRef.current) {
@@ -116,14 +119,15 @@ function ChatInputBase(
116
119
  textareaHeightRef.current = height;
117
120
  };
118
121
  const handleOnKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
122
+ props.onKeyDown?.(event);
123
+
119
124
  if (event.key === 'Enter' && event.shiftKey === false) {
120
125
  event.preventDefault();
121
- props.onKeyDown?.(event);
122
126
  handleOnSend();
123
127
  }
124
128
  };
125
129
 
126
- useEffect(() => {
130
+ React.useEffect(() => {
127
131
  const textarea = textareaRef.current;
128
132
 
129
133
  handleStopTyping();
@@ -135,7 +139,7 @@ function ChatInputBase(
135
139
  };
136
140
  }, [props.key]);
137
141
 
138
- useImperativeHandle(ref, () => textareaRef.current || ({} as HTMLTextAreaElement), []);
142
+ React.useImperativeHandle(ref, () => textareaRef.current || ({} as HTMLTextAreaElement), []);
139
143
 
140
144
  return (
141
145
  <div {...containerProps} className={cn('flex items-end gap-2', containerProps?.className)}>
@@ -165,7 +169,7 @@ function ChatInputBase(
165
169
  );
166
170
  }
167
171
 
168
- const ChatInput = forwardRef<HTMLTextAreaElement, ChatInputProps>(ChatInputBase);
172
+ const ChatInput = React.forwardRef<HTMLTextAreaElement, ChatInputProps>(ChatInputBase);
169
173
 
170
174
  ChatInput.displayName = 'ChatInput';
171
175