@connectycube/react-ui-kit 0.1.0 → 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 +2 -2
- 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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { Virtualizer, VirtualizerProps, type VirtualizerHandle } from 'virtua';
|
|
3
3
|
import { FilePickerDropzone, type FilePickerDropzoneProps } from './file-picker';
|
|
4
4
|
import { QuickActions, type QuickActionsProps } from './quick-actions';
|
|
@@ -25,6 +25,7 @@ interface ChatListProps extends VirtualizerProps {
|
|
|
25
25
|
|
|
26
26
|
interface ChatListHandle extends VirtualizerHandle {
|
|
27
27
|
scrollToBottom: (force?: boolean) => void;
|
|
28
|
+
setShift: (shift: boolean) => void;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
function DefaultChatListWrapper({ children, ...props }: React.ComponentProps<'div'>) {
|
|
@@ -53,6 +54,7 @@ function ChatListBase(
|
|
|
53
54
|
children,
|
|
54
55
|
quickActionsVisible,
|
|
55
56
|
minItemsCount = 1,
|
|
57
|
+
shift = false,
|
|
56
58
|
...props
|
|
57
59
|
}: ChatListProps,
|
|
58
60
|
ref: React.ForwardedRef<ChatListHandle>
|
|
@@ -60,11 +62,11 @@ function ChatListBase(
|
|
|
60
62
|
const ChatListWrapper = enableFilePickerDropzone ? FilePickerDropzone : DefaultChatListWrapper;
|
|
61
63
|
const chatListWrapperProps = enableFilePickerDropzone ? filePickerDropzoneProps : containerProps;
|
|
62
64
|
const itemsCount = Array.isArray(children) ? children.length : Array.isArray(props.data) ? props.data.length : 0;
|
|
63
|
-
const itemsCountRef = useRef<number>(0);
|
|
64
|
-
const keyRef = useRef<string | undefined>(undefined);
|
|
65
|
-
const [
|
|
66
|
-
const [
|
|
67
|
-
const virtuaRef = useRef<VirtualizerHandle>(null);
|
|
65
|
+
const itemsCountRef = React.useRef<number>(0);
|
|
66
|
+
const keyRef = React.useRef<string | undefined>(undefined);
|
|
67
|
+
const [isPreparing, setIsPreparing] = React.useState<boolean>(false);
|
|
68
|
+
const [_shift, setShift] = React.useState<boolean>(shift);
|
|
69
|
+
const virtuaRef = React.useRef<VirtualizerHandle>(null);
|
|
68
70
|
const prepareNextVirtualizer = () => {
|
|
69
71
|
queueMicrotask(() => {
|
|
70
72
|
setIsPreparing(true);
|
|
@@ -77,7 +79,6 @@ function ChatListBase(
|
|
|
77
79
|
if (!virtuaRef.current) return;
|
|
78
80
|
|
|
79
81
|
if (typeof onScrollStartReached === 'function' && offset < offsetToReach) {
|
|
80
|
-
setShouldPrependMessages(true);
|
|
81
82
|
onScrollStartReached();
|
|
82
83
|
}
|
|
83
84
|
|
|
@@ -88,18 +89,20 @@ function ChatListBase(
|
|
|
88
89
|
onScrollEndReached();
|
|
89
90
|
}
|
|
90
91
|
};
|
|
91
|
-
const scrollToBottom = useCallback(
|
|
92
|
+
const scrollToBottom = React.useCallback(
|
|
92
93
|
(force: boolean = false) => {
|
|
93
|
-
if (!virtuaRef.current) return;
|
|
94
|
+
if (!virtuaRef.current || itemsCount === 0) return;
|
|
94
95
|
|
|
95
96
|
if (force || virtuaRef.current.scrollSize - virtuaRef.current.scrollOffset < virtuaRef.current.viewportSize * 2) {
|
|
96
|
-
|
|
97
|
+
requestAnimationFrame(() => {
|
|
98
|
+
virtuaRef.current?.scrollToIndex(itemsCount - 1, { align: 'start' });
|
|
99
|
+
});
|
|
97
100
|
}
|
|
98
101
|
},
|
|
99
102
|
[itemsCount]
|
|
100
103
|
);
|
|
101
104
|
|
|
102
|
-
useEffect(() => {
|
|
105
|
+
React.useEffect(() => {
|
|
103
106
|
if (key !== keyRef.current) {
|
|
104
107
|
prepareNextVirtualizer();
|
|
105
108
|
onListReset?.(keyRef.current, key);
|
|
@@ -108,7 +111,7 @@ function ChatListBase(
|
|
|
108
111
|
}
|
|
109
112
|
}, [key, onListReset]);
|
|
110
113
|
|
|
111
|
-
useEffect(() => {
|
|
114
|
+
React.useEffect(() => {
|
|
112
115
|
if (itemsCountRef.current === 0 && itemsCount > 0) {
|
|
113
116
|
prepareNextVirtualizer();
|
|
114
117
|
onListCreate?.();
|
|
@@ -117,30 +120,34 @@ function ChatListBase(
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
if (itemsCount > itemsCountRef.current) {
|
|
123
|
+
const isPrepend = _shift;
|
|
124
|
+
|
|
120
125
|
onListGrow?.();
|
|
121
126
|
itemsCountRef.current = itemsCount;
|
|
122
127
|
|
|
123
|
-
if (
|
|
124
|
-
queueMicrotask(() =>
|
|
128
|
+
if (isPrepend) {
|
|
129
|
+
queueMicrotask(() => setShift(false));
|
|
130
|
+
} else {
|
|
131
|
+
scrollToBottom();
|
|
125
132
|
}
|
|
126
|
-
|
|
127
|
-
scrollToBottom();
|
|
128
133
|
}
|
|
129
|
-
}, [itemsCount,
|
|
134
|
+
}, [itemsCount, _shift, onListCreate, onListGrow, scrollToBottom]);
|
|
130
135
|
|
|
131
|
-
useEffect(() => {
|
|
136
|
+
React.useEffect(() => {
|
|
132
137
|
virtuaRef.current?.scrollBy(textareaMeasurement.shift);
|
|
133
138
|
}, [textareaMeasurement]);
|
|
134
139
|
|
|
135
|
-
useImperativeHandle(
|
|
136
|
-
|
|
137
|
-
|
|
140
|
+
React.useImperativeHandle(
|
|
141
|
+
ref,
|
|
142
|
+
() => ({ ...(virtuaRef.current || ({} as VirtualizerHandle)), scrollToBottom, setShift }),
|
|
143
|
+
[scrollToBottom]
|
|
144
|
+
);
|
|
138
145
|
|
|
139
146
|
if (isPreparing) {
|
|
140
147
|
return null;
|
|
141
148
|
}
|
|
142
149
|
|
|
143
|
-
if (minItemsCount
|
|
150
|
+
if (minItemsCount > itemsCount) {
|
|
144
151
|
return quickActionsVisible ? <QuickActions {...quickActionsProps} /> : <Spinner loading layout="centered" />;
|
|
145
152
|
}
|
|
146
153
|
|
|
@@ -149,7 +156,7 @@ function ChatListBase(
|
|
|
149
156
|
<Spinner loading={loading} className="my-5" />
|
|
150
157
|
<div className="flex flex-col h-full overflow-y-auto px-2">
|
|
151
158
|
<div className="grow" />
|
|
152
|
-
<Virtualizer ref={virtuaRef} onScroll={handleOnScroll} shift={
|
|
159
|
+
<Virtualizer ref={virtuaRef} onScroll={handleOnScroll} shift={_shift} {...props}>
|
|
153
160
|
{children}
|
|
154
161
|
</Virtualizer>
|
|
155
162
|
</div>
|
|
@@ -157,7 +164,7 @@ function ChatListBase(
|
|
|
157
164
|
);
|
|
158
165
|
}
|
|
159
166
|
|
|
160
|
-
const ChatList = forwardRef<ChatListHandle, ChatListProps>(ChatListBase);
|
|
167
|
+
const ChatList = React.forwardRef<ChatListHandle, ChatListProps>(ChatListBase);
|
|
161
168
|
|
|
162
169
|
ChatList.displayName = 'ChatList';
|
|
163
170
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
4
3
|
import { CheckIcon, type LucideProps } from 'lucide-react';
|
|
5
4
|
import { cn } from './utils';
|
|
@@ -33,7 +32,7 @@ function CheckboxBase(
|
|
|
33
32
|
);
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(CheckboxBase);
|
|
35
|
+
const Checkbox = React.forwardRef<HTMLButtonElement, CheckboxProps>(CheckboxBase);
|
|
37
36
|
|
|
38
37
|
Checkbox.displayName = 'Checkbox';
|
|
39
38
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { Avatar, type AvatarProps } from './avatar';
|
|
3
3
|
import { Users, type LucideProps } from 'lucide-react';
|
|
4
|
-
import { forwardRef, memo } from 'react';
|
|
5
4
|
import { FormattedDate, type FormattedDateProps } from './formatted-date';
|
|
6
5
|
import { StatusSent, type StatusSentProps } from './status-sent';
|
|
7
6
|
import { type PresenceStatus } from './presence';
|
|
@@ -184,7 +183,7 @@ function DialogItemBase(
|
|
|
184
183
|
);
|
|
185
184
|
}
|
|
186
185
|
|
|
187
|
-
const DialogItem = memo(forwardRef<HTMLDivElement, DialogItemProps>(DialogItemBase));
|
|
186
|
+
const DialogItem = React.memo(React.forwardRef<HTMLDivElement, DialogItemProps>(DialogItemBase));
|
|
188
187
|
|
|
189
188
|
DialogItem.displayName = 'DialogItem';
|
|
190
189
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { VList, type VListHandle, type VListProps } from 'virtua';
|
|
4
3
|
import { PlaceholderText } from './placeholder-text';
|
|
5
4
|
|
|
@@ -43,7 +42,7 @@ function DialogsListBase(
|
|
|
43
42
|
}: DialogsListProps,
|
|
44
43
|
ref: React.ForwardedRef<VListHandle>
|
|
45
44
|
) {
|
|
46
|
-
const vListRef = useRef<VListHandle>(null);
|
|
45
|
+
const vListRef = React.useRef<VListHandle>(null);
|
|
47
46
|
const skeletonList = Array.from({ length: pendingListLength }).map((_, i) => (
|
|
48
47
|
<PendingItem key={`pending_dialog_item_${i}`} />
|
|
49
48
|
));
|
|
@@ -64,7 +63,7 @@ function DialogsListBase(
|
|
|
64
63
|
}
|
|
65
64
|
};
|
|
66
65
|
|
|
67
|
-
useImperativeHandle(ref, () => vListRef.current || ({} as VListHandle), []);
|
|
66
|
+
React.useImperativeHandle(ref, () => vListRef.current || ({} as VListHandle), []);
|
|
68
67
|
|
|
69
68
|
if (placeholderVisible) {
|
|
70
69
|
return <PlaceholderText titles={placeholderTitles} className="text-base text-muted" />;
|
|
@@ -77,7 +76,7 @@ function DialogsListBase(
|
|
|
77
76
|
);
|
|
78
77
|
}
|
|
79
78
|
|
|
80
|
-
const DialogsList = forwardRef<VListHandle, DialogsListProps>(DialogsListBase);
|
|
79
|
+
const DialogsList = React.forwardRef<VListHandle, DialogsListProps>(DialogsListBase);
|
|
81
80
|
|
|
82
81
|
DialogsList.displayName = 'DialogsList';
|
|
83
82
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useCallback, useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { cn } from './utils';
|
|
4
3
|
|
|
5
4
|
interface DismissLayerProps extends React.ComponentProps<'div'> {
|
|
@@ -14,11 +13,11 @@ function DismissLayerBase(
|
|
|
14
13
|
{ active, onDismiss, disableClickOutside = false, disableEscKeyPress = false, disabled, ...props }: DismissLayerProps,
|
|
15
14
|
ref: React.ForwardedRef<HTMLDivElement>
|
|
16
15
|
) {
|
|
17
|
-
const innerRef = useRef<HTMLDivElement>(null);
|
|
16
|
+
const innerRef = React.useRef<HTMLDivElement>(null);
|
|
18
17
|
|
|
19
|
-
useImperativeHandle(ref, () => innerRef.current || ({} as HTMLDivElement), []);
|
|
18
|
+
React.useImperativeHandle(ref, () => innerRef.current || ({} as HTMLDivElement), []);
|
|
20
19
|
|
|
21
|
-
const handleClickOrTouch = useCallback(
|
|
20
|
+
const handleClickOrTouch = React.useCallback(
|
|
22
21
|
(e: React.MouseEvent | React.TouchEvent) => {
|
|
23
22
|
if (!disableClickOutside && active && e.target === innerRef.current) {
|
|
24
23
|
onDismiss();
|
|
@@ -26,7 +25,7 @@ function DismissLayerBase(
|
|
|
26
25
|
},
|
|
27
26
|
[disableClickOutside, active, onDismiss]
|
|
28
27
|
);
|
|
29
|
-
const handleKeyEvent = useCallback(
|
|
28
|
+
const handleKeyEvent = React.useCallback(
|
|
30
29
|
(ev: KeyboardEvent) => {
|
|
31
30
|
if (!disableEscKeyPress && active && ev.key === 'Escape') {
|
|
32
31
|
onDismiss();
|
|
@@ -35,7 +34,7 @@ function DismissLayerBase(
|
|
|
35
34
|
[disableEscKeyPress, active, onDismiss]
|
|
36
35
|
);
|
|
37
36
|
|
|
38
|
-
useEffect(() => {
|
|
37
|
+
React.useEffect(() => {
|
|
39
38
|
if (!disableEscKeyPress && active) {
|
|
40
39
|
document.addEventListener('keydown', handleKeyEvent);
|
|
41
40
|
|
|
@@ -59,7 +58,7 @@ function DismissLayerBase(
|
|
|
59
58
|
);
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
const DismissLayer = forwardRef<HTMLDivElement, DismissLayerProps>(DismissLayerBase);
|
|
61
|
+
const DismissLayer = React.forwardRef<HTMLDivElement, DismissLayerProps>(DismissLayerBase);
|
|
63
62
|
|
|
64
63
|
DismissLayer.displayName = 'DismissLayer';
|
|
65
64
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef, useState } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { FilePlusCorner, LucideProps, Paperclip } from 'lucide-react';
|
|
4
3
|
import { Label, type LabelProps } from './label';
|
|
5
4
|
import { cn } from './utils';
|
|
@@ -124,7 +123,7 @@ function FilePickerInputBase(
|
|
|
124
123
|
);
|
|
125
124
|
}
|
|
126
125
|
|
|
127
|
-
const FilePickerInput = forwardRef<HTMLInputElement, FilePickerInputProps>(FilePickerInputBase);
|
|
126
|
+
const FilePickerInput = React.forwardRef<HTMLInputElement, FilePickerInputProps>(FilePickerInputBase);
|
|
128
127
|
|
|
129
128
|
FilePickerInput.displayName = 'FilePickerInput';
|
|
130
129
|
|
|
@@ -145,7 +144,7 @@ function FilePickerDropzoneBase(
|
|
|
145
144
|
}: FilePickerDropzoneProps,
|
|
146
145
|
ref: React.ForwardedRef<HTMLDivElement>
|
|
147
146
|
) {
|
|
148
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
147
|
+
const [isDragging, setIsDragging] = React.useState(false);
|
|
149
148
|
const handleDragEvent = (event: React.DragEvent<HTMLDivElement>) => {
|
|
150
149
|
event.preventDefault();
|
|
151
150
|
event.stopPropagation();
|
|
@@ -217,7 +216,7 @@ function FilePickerDropzoneBase(
|
|
|
217
216
|
);
|
|
218
217
|
}
|
|
219
218
|
|
|
220
|
-
const FilePickerDropzone = forwardRef<HTMLDivElement, FilePickerDropzoneProps>(FilePickerDropzoneBase);
|
|
219
|
+
const FilePickerDropzone = React.forwardRef<HTMLDivElement, FilePickerDropzoneProps>(FilePickerDropzoneBase);
|
|
221
220
|
|
|
222
221
|
FilePickerDropzone.displayName = 'FilePickerDropzone';
|
|
223
222
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { differenceInCalendarDays, format, formatDistanceToNow, isToday } from 'date-fns';
|
|
3
|
-
import { el, enUS, uk, type Locale } from 'date-fns/locale';
|
|
3
|
+
import { el, enUS, uk, es, type Locale } from 'date-fns/locale';
|
|
4
4
|
import { cn } from './utils';
|
|
5
5
|
|
|
6
6
|
interface FormattedDateProps extends React.ComponentProps<'span'> {
|
|
@@ -13,6 +13,7 @@ const locales: Record<string, Locale> = {
|
|
|
13
13
|
en: enUS,
|
|
14
14
|
el: el,
|
|
15
15
|
ua: uk,
|
|
16
|
+
es: es,
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
function formatDate(date: string | number | Date, language: string = 'en', distanceToNow = false): string {
|
|
@@ -50,7 +51,7 @@ function FormattedDateBase(
|
|
|
50
51
|
);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
const FormattedDate = memo(forwardRef<HTMLSpanElement, FormattedDateProps>(FormattedDateBase));
|
|
54
|
+
const FormattedDate = React.memo(React.forwardRef<HTMLSpanElement, FormattedDateProps>(FormattedDateBase));
|
|
54
55
|
|
|
55
56
|
FormattedDate.displayName = 'FormattedDate';
|
|
56
57
|
|
package/src/components/input.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { cn } from './utils';
|
|
4
3
|
|
|
5
4
|
type InputProps = React.ComponentProps<'input'>;
|
|
@@ -19,7 +18,7 @@ function InputBase(props: InputProps, ref?: React.ForwardedRef<HTMLInputElement>
|
|
|
19
18
|
);
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
const Input = forwardRef<HTMLInputElement, InputProps>(InputBase);
|
|
21
|
+
const Input = React.forwardRef<HTMLInputElement, InputProps>(InputBase);
|
|
23
22
|
|
|
24
23
|
Input.displayName = 'Input';
|
|
25
24
|
|
package/src/components/label.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { Root as LabelRoot, type LabelProps } from '@radix-ui/react-label';
|
|
4
3
|
import { cn } from './utils';
|
|
5
4
|
|
|
@@ -16,7 +15,7 @@ function LabelBase({ ...props }: LabelProps, ref: React.ForwardedRef<HTMLLabelEl
|
|
|
16
15
|
);
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
const Label = forwardRef<HTMLLabelElement, LabelProps>(LabelBase);
|
|
18
|
+
const Label = React.forwardRef<HTMLLabelElement, LabelProps>(LabelBase);
|
|
20
19
|
|
|
21
20
|
Label.displayName = 'Label';
|
|
22
21
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef, memo, useCallback, useState } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { Globe, type LucideProps } from 'lucide-react';
|
|
4
3
|
import { cn } from './utils';
|
|
5
4
|
|
|
@@ -52,29 +51,20 @@ function LinkPreviewBase(
|
|
|
52
51
|
}: LinkPreviewProps,
|
|
53
52
|
ref: React.ForwardedRef<HTMLAnchorElement>
|
|
54
53
|
) {
|
|
55
|
-
const [iconSrc, setIconSrc] = useState<React.ComponentProps<'img'>['src']>(icon);
|
|
56
|
-
const [imageSrc, setImageSrc] = useState<React.ComponentProps<'img'>['src']>(image);
|
|
57
|
-
const handleOnLoad =
|
|
58
|
-
(event
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
[iconProps]
|
|
70
|
-
);
|
|
71
|
-
const handleImageOnError = useCallback(
|
|
72
|
-
(event: React.SyntheticEvent<HTMLImageElement, Event>) => {
|
|
73
|
-
imageProps?.onError?.(event);
|
|
74
|
-
setImageSrc(undefined);
|
|
75
|
-
},
|
|
76
|
-
[imageProps]
|
|
77
|
-
);
|
|
54
|
+
const [iconSrc, setIconSrc] = React.useState<React.ComponentProps<'img'>['src']>(icon);
|
|
55
|
+
const [imageSrc, setImageSrc] = React.useState<React.ComponentProps<'img'>['src']>(image);
|
|
56
|
+
const handleOnLoad = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
|
|
57
|
+
imageProps?.onLoad?.(event);
|
|
58
|
+
onReady();
|
|
59
|
+
};
|
|
60
|
+
const handleIconOnError = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
|
|
61
|
+
iconProps?.onError?.(event);
|
|
62
|
+
setIconSrc(undefined);
|
|
63
|
+
};
|
|
64
|
+
const handleImageOnError = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
|
|
65
|
+
imageProps?.onError?.(event);
|
|
66
|
+
setImageSrc(undefined);
|
|
67
|
+
};
|
|
78
68
|
|
|
79
69
|
return (
|
|
80
70
|
<a
|
|
@@ -142,7 +132,7 @@ function LinkPreviewBase(
|
|
|
142
132
|
);
|
|
143
133
|
}
|
|
144
134
|
|
|
145
|
-
const LinkPreview = memo(forwardRef<HTMLAnchorElement, LinkPreviewProps>(LinkPreviewBase));
|
|
135
|
+
const LinkPreview = React.memo(React.forwardRef<HTMLAnchorElement, LinkPreviewProps>(LinkPreviewBase));
|
|
146
136
|
|
|
147
137
|
LinkPreview.displayName = 'LinkPreview';
|
|
148
138
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import type { Opts } from 'linkifyjs';
|
|
3
|
-
import { forwardRef, memo, useEffect, useMemo, useRef } from 'react';
|
|
4
3
|
import Linkify from 'linkify-react';
|
|
5
4
|
import { cn } from './utils';
|
|
6
5
|
|
|
@@ -33,8 +32,8 @@ function LinkifyTextBase(
|
|
|
33
32
|
}: LinkifyTextProps,
|
|
34
33
|
ref: React.ForwardedRef<HTMLParagraphElement>
|
|
35
34
|
) {
|
|
36
|
-
const pendingRef = useRef(pending);
|
|
37
|
-
const options = useMemo(
|
|
35
|
+
const pendingRef = React.useRef(pending);
|
|
36
|
+
const options = React.useMemo(
|
|
38
37
|
() => ({
|
|
39
38
|
...DEFAULT_LINKIFY_OPTIONS,
|
|
40
39
|
...linkifyProps,
|
|
@@ -43,7 +42,7 @@ function LinkifyTextBase(
|
|
|
43
42
|
[linkifyProps]
|
|
44
43
|
);
|
|
45
44
|
|
|
46
|
-
useEffect(() => {
|
|
45
|
+
React.useEffect(() => {
|
|
47
46
|
if (pendingRef.current && !pending) {
|
|
48
47
|
onReady();
|
|
49
48
|
}
|
|
@@ -75,7 +74,7 @@ function LinkifyTextBase(
|
|
|
75
74
|
);
|
|
76
75
|
}
|
|
77
76
|
|
|
78
|
-
const LinkifyText = memo(forwardRef<HTMLParagraphElement, LinkifyTextProps>(LinkifyTextBase));
|
|
77
|
+
const LinkifyText = React.memo(React.forwardRef<HTMLParagraphElement, LinkifyTextProps>(LinkifyTextBase));
|
|
79
78
|
|
|
80
79
|
LinkifyText.displayName = 'LinkifyText';
|
|
81
80
|
|
|
@@ -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
|
interface PlaceholderTextProps extends React.ComponentProps<'div'> {
|
|
@@ -33,7 +32,7 @@ function PlaceholderTextBase(
|
|
|
33
32
|
);
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
const PlaceholderText = forwardRef(PlaceholderTextBase);
|
|
35
|
+
const PlaceholderText = React.forwardRef(PlaceholderTextBase);
|
|
37
36
|
|
|
38
37
|
PlaceholderText.displayName = 'PlaceholderText';
|
|
39
38
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { cn } from './utils';
|
|
4
3
|
|
|
5
4
|
interface QuickActionsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
@@ -67,7 +66,7 @@ function QuickActionsBase(
|
|
|
67
66
|
);
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
const QuickActions = forwardRef<HTMLDivElement, QuickActionsProps>(QuickActionsBase);
|
|
69
|
+
const QuickActions = React.forwardRef<HTMLDivElement, QuickActionsProps>(QuickActionsBase);
|
|
71
70
|
|
|
72
71
|
QuickActions.displayName = 'QuickActions';
|
|
73
72
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef, useState } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { cn } from './utils';
|
|
4
3
|
import { Input, type InputProps } from './input';
|
|
5
4
|
import { Search as SearchIcon, X as CloseIcon, type LucideProps } from 'lucide-react';
|
|
@@ -27,7 +26,7 @@ function SearchBase(
|
|
|
27
26
|
}: SearchProps,
|
|
28
27
|
ref?: React.ForwardedRef<HTMLInputElement>
|
|
29
28
|
) {
|
|
30
|
-
const [value, setValue] = useState<string>('');
|
|
29
|
+
const [value, setValue] = React.useState<string>('');
|
|
31
30
|
const handleOnSearch = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
|
32
31
|
const keyword = e.target.value;
|
|
33
32
|
|
|
@@ -79,7 +78,7 @@ function SearchBase(
|
|
|
79
78
|
);
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
const Search = forwardRef<HTMLInputElement, SearchProps>(SearchBase);
|
|
81
|
+
const Search = React.forwardRef<HTMLInputElement, SearchProps>(SearchBase);
|
|
83
82
|
|
|
84
83
|
Search.displayName = 'Search';
|
|
85
84
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
1
2
|
import { Loader, LoaderCircle, type LucideProps } from 'lucide-react';
|
|
2
3
|
import { cn } from './utils';
|
|
3
4
|
|
|
@@ -7,7 +8,7 @@ interface SpinnerProps extends LucideProps {
|
|
|
7
8
|
layout?: 'absolute' | 'centered' | 'overlay' | 'flow';
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
const Spinner: React.FC<SpinnerProps> = ({ loading = false, layout = 'flow', type = 'default', ...props }) => {
|
|
11
12
|
const LoaderIcon = type === 'circle' ? LoaderCircle : Loader;
|
|
12
13
|
|
|
13
14
|
if (!loading) {
|
|
@@ -35,7 +36,7 @@ function Spinner({ loading = false, layout = 'flow', type = 'default', ...props
|
|
|
35
36
|
default:
|
|
36
37
|
return spinnerElement;
|
|
37
38
|
}
|
|
38
|
-
}
|
|
39
|
+
};
|
|
39
40
|
|
|
40
41
|
Spinner.displayName = 'Spinner';
|
|
41
42
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
4
3
|
import { cn } from './utils';
|
|
5
4
|
|
|
@@ -78,7 +77,7 @@ function StatusIndicatorBase(
|
|
|
78
77
|
);
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
const StatusIndicator = forwardRef(StatusIndicatorBase);
|
|
80
|
+
const StatusIndicator = React.forwardRef(StatusIndicatorBase);
|
|
82
81
|
|
|
83
82
|
StatusIndicator.displayName = 'StatusIndicator';
|
|
84
83
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
1
|
+
import * as React from 'react';
|
|
3
2
|
import { Maximize, Minimize, PictureInPicture2, type LucideProps } from 'lucide-react';
|
|
4
3
|
import { cn, getRandomString } from './utils';
|
|
5
4
|
|
|
@@ -12,15 +11,15 @@ function StreamViewBase(
|
|
|
12
11
|
{ id, stream, mirror, className, muted, ...props }: StreamViewProps,
|
|
13
12
|
ref: React.ForwardedRef<HTMLVideoElement>
|
|
14
13
|
) {
|
|
15
|
-
const innerRef = useRef<HTMLVideoElement>(null);
|
|
16
|
-
const elementId = useMemo(() => id ?? `stream-${getRandomString()}`, [id]);
|
|
14
|
+
const innerRef = React.useRef<HTMLVideoElement>(null);
|
|
15
|
+
const elementId = React.useMemo(() => id ?? `stream-${getRandomString()}`, [id]);
|
|
17
16
|
const isMuted = typeof muted === 'boolean' ? muted : false;
|
|
18
17
|
const defaultClassName = 'size-full object-contain';
|
|
19
18
|
const mirrorClassName = mirror ? 'scale-x-[-1]' : '';
|
|
20
19
|
|
|
21
|
-
useImperativeHandle(ref, () => innerRef.current || ({} as HTMLVideoElement), []);
|
|
20
|
+
React.useImperativeHandle(ref, () => innerRef.current || ({} as HTMLVideoElement), []);
|
|
22
21
|
|
|
23
|
-
useEffect(() => {
|
|
22
|
+
React.useEffect(() => {
|
|
24
23
|
if (innerRef.current && stream) {
|
|
25
24
|
innerRef.current.srcObject = stream;
|
|
26
25
|
|
|
@@ -53,7 +52,7 @@ function StreamViewBase(
|
|
|
53
52
|
);
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
const StreamView = forwardRef<HTMLVideoElement, StreamViewProps>(StreamViewBase);
|
|
55
|
+
const StreamView = React.forwardRef<HTMLVideoElement, StreamViewProps>(StreamViewBase);
|
|
57
56
|
|
|
58
57
|
StreamView.displayName = 'StreamView';
|
|
59
58
|
|
|
@@ -64,7 +63,7 @@ function LocalStreamViewBase({ muted, mirror, ...props }: StreamViewProps, ref:
|
|
|
64
63
|
return <StreamView ref={ref} muted={isMuted} mirror={isMirror} {...props} />;
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
const LocalStreamView = forwardRef<HTMLVideoElement, StreamViewProps>(LocalStreamViewBase);
|
|
66
|
+
const LocalStreamView = React.forwardRef<HTMLVideoElement, StreamViewProps>(LocalStreamViewBase);
|
|
68
67
|
|
|
69
68
|
LocalStreamView.displayName = 'LocalStreamView';
|
|
70
69
|
|
|
@@ -75,7 +74,7 @@ function RemoteStreamViewBase({ muted, mirror, ...props }: StreamViewProps, ref:
|
|
|
75
74
|
return <StreamView ref={ref} muted={isMuted} mirror={isMirror} {...props} />;
|
|
76
75
|
}
|
|
77
76
|
|
|
78
|
-
const RemoteStreamView = forwardRef<HTMLVideoElement, StreamViewProps>(RemoteStreamViewBase);
|
|
77
|
+
const RemoteStreamView = React.forwardRef<HTMLVideoElement, StreamViewProps>(RemoteStreamViewBase);
|
|
79
78
|
|
|
80
79
|
RemoteStreamView.displayName = 'RemoteStreamView';
|
|
81
80
|
|
|
@@ -116,10 +115,10 @@ function FullscreenStreamViewBase(
|
|
|
116
115
|
}: FullscreenStreamViewProps,
|
|
117
116
|
ref: React.ForwardedRef<FullscreenStreamViewRef>
|
|
118
117
|
) {
|
|
119
|
-
const innerRef = useRef<HTMLDivElement>(null);
|
|
120
|
-
const [isFullscreen, setIsFullscreen] = useState<boolean>(false);
|
|
121
|
-
const [isPictureInPicture, setIsPictureInPicture] = useState<boolean>(false);
|
|
122
|
-
const toggleFullscreen = useCallback(async () => {
|
|
118
|
+
const innerRef = React.useRef<HTMLDivElement>(null);
|
|
119
|
+
const [isFullscreen, setIsFullscreen] = React.useState<boolean>(false);
|
|
120
|
+
const [isPictureInPicture, setIsPictureInPicture] = React.useState<boolean>(false);
|
|
121
|
+
const toggleFullscreen = React.useCallback(async () => {
|
|
123
122
|
const container = innerRef.current;
|
|
124
123
|
|
|
125
124
|
if (!container) return;
|
|
@@ -138,13 +137,13 @@ function FullscreenStreamViewBase(
|
|
|
138
137
|
console.error('Fullscreen error:', err);
|
|
139
138
|
}
|
|
140
139
|
}, []);
|
|
141
|
-
const togglePictureInPicture = useCallback(() => {
|
|
140
|
+
const togglePictureInPicture = React.useCallback(() => {
|
|
142
141
|
if (pipElement) {
|
|
143
142
|
setIsPictureInPicture((prevState) => !prevState);
|
|
144
143
|
}
|
|
145
144
|
}, [pipElement]);
|
|
146
145
|
|
|
147
|
-
useImperativeHandle(
|
|
146
|
+
React.useImperativeHandle(
|
|
148
147
|
ref,
|
|
149
148
|
() => ({
|
|
150
149
|
...(innerRef.current || ({} as HTMLDivElement)),
|
|
@@ -156,7 +155,7 @@ function FullscreenStreamViewBase(
|
|
|
156
155
|
[isFullscreen, isPictureInPicture, toggleFullscreen, togglePictureInPicture]
|
|
157
156
|
);
|
|
158
157
|
|
|
159
|
-
useEffect(() => {
|
|
158
|
+
React.useEffect(() => {
|
|
160
159
|
const onFullscreenChange = () => {
|
|
161
160
|
setIsFullscreen(!!document.fullscreenElement);
|
|
162
161
|
setIsPictureInPicture(!!document.fullscreenElement);
|
|
@@ -218,7 +217,9 @@ function FullscreenStreamViewBase(
|
|
|
218
217
|
);
|
|
219
218
|
}
|
|
220
219
|
|
|
221
|
-
const FullscreenStreamView = forwardRef<FullscreenStreamViewRef, FullscreenStreamViewProps>(
|
|
220
|
+
const FullscreenStreamView = React.forwardRef<FullscreenStreamViewRef, FullscreenStreamViewProps>(
|
|
221
|
+
FullscreenStreamViewBase
|
|
222
|
+
);
|
|
222
223
|
|
|
223
224
|
FullscreenStreamView.displayName = 'FullscreenStreamView';
|
|
224
225
|
|