@connectycube/react-ui-kit 0.0.18 → 0.0.19
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/configs/dependencies.json +6 -0
- package/configs/imports.json +3 -1
- package/dist/index.cjs +14 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -6
- package/dist/index.js.map +1 -1
- package/dist/types/components/attachment.d.ts +45 -0
- package/dist/types/components/attachment.d.ts.map +1 -0
- package/dist/types/components/avatar.d.ts +1 -1
- package/dist/types/components/avatar.d.ts.map +1 -1
- package/dist/types/components/badge.d.ts +1 -1
- package/dist/types/components/button.d.ts +2 -2
- package/dist/types/components/dialog-item.d.ts +4 -4
- package/dist/types/components/dialog-item.d.ts.map +1 -1
- package/dist/types/components/stream-view.d.ts.map +1 -1
- package/dist/types/components/switch.d.ts +6 -0
- package/dist/types/components/switch.d.ts.map +1 -0
- package/dist/types/components/utils.d.ts +1 -0
- package/dist/types/components/utils.d.ts.map +1 -1
- package/dist/types/index.d.ts +21 -4
- package/dist/types/index.d.ts.map +1 -1
- package/gen/components/attachment.jsx +214 -0
- package/gen/components/dialog-item.jsx +7 -7
- package/gen/components/dismiss-layer.jsx +1 -1
- package/gen/components/file-picker.jsx +2 -2
- package/gen/components/stream-view.jsx +1 -5
- package/gen/components/switch.jsx +25 -0
- package/gen/components/utils.js +4 -0
- package/gen/index.js +46 -0
- package/package.json +2 -1
- package/src/components/attachment.tsx +270 -0
- package/src/components/avatar.tsx +1 -1
- package/src/components/dialog-item.tsx +9 -9
- package/src/components/dismiss-layer.tsx +1 -1
- package/src/components/file-picker.tsx +2 -2
- package/src/components/stream-view.tsx +1 -5
- package/src/components/switch.tsx +27 -0
- package/src/components/utils.ts +4 -0
- package/src/index.ts +72 -4
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { forwardRef, memo, useImperativeHandle, useRef, useState } from 'react';
|
|
3
|
+
import { File, FileXCorner, type LucideProps } from 'lucide-react';
|
|
4
|
+
import { Spinner } from './spinner';
|
|
5
|
+
import { cn, getRandomString } from './utils';
|
|
6
|
+
|
|
7
|
+
interface AttachmentProps {
|
|
8
|
+
uid?: string;
|
|
9
|
+
url?: string;
|
|
10
|
+
mimeType?: string;
|
|
11
|
+
uploading?: boolean;
|
|
12
|
+
onReady?: (skipOnce?: boolean) => void;
|
|
13
|
+
linkProps?: AttachmentLinkProps;
|
|
14
|
+
containerProps?: React.ComponentProps<'div'>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface AttachmentLinkProps
|
|
18
|
+
extends React.ComponentProps<'a'>,
|
|
19
|
+
Omit<AttachmentProps, 'containerProps' & 'mimeType' & 'onReady'> {
|
|
20
|
+
children?: React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface AttachmentImageProps
|
|
24
|
+
extends React.ComponentProps<'img'>,
|
|
25
|
+
Omit<AttachmentProps, 'containerProps' & 'mimeType'> {}
|
|
26
|
+
|
|
27
|
+
interface AttachmentAudioProps
|
|
28
|
+
extends React.ComponentProps<'audio'>,
|
|
29
|
+
Omit<AttachmentProps, 'linkProps' & 'mimeType' & 'onReady'> {}
|
|
30
|
+
|
|
31
|
+
interface AttachmentVideoProps extends React.ComponentProps<'video'>, Omit<AttachmentProps, 'linkProps' & 'mimeType'> {
|
|
32
|
+
maxSize?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface AttachmentFileProps extends LucideProps, Omit<AttachmentProps, 'containerProps' & 'mimeType'> {
|
|
36
|
+
name?: string | undefined;
|
|
37
|
+
iconElement?: React.ReactNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface AttachmentFailedProps extends LucideProps, Omit<AttachmentProps, 'linkProps' & 'mimeType'> {
|
|
41
|
+
name?: string | undefined;
|
|
42
|
+
iconElement?: React.ReactNode;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function AttachmentLinkBase(
|
|
46
|
+
{ url, uploading = false, children, ...props }: AttachmentLinkProps,
|
|
47
|
+
ref: React.ForwardedRef<HTMLAnchorElement>
|
|
48
|
+
) {
|
|
49
|
+
return (
|
|
50
|
+
<a
|
|
51
|
+
ref={ref}
|
|
52
|
+
target="_blank"
|
|
53
|
+
rel="noopener noreferrer"
|
|
54
|
+
{...props}
|
|
55
|
+
href={url}
|
|
56
|
+
className={cn(
|
|
57
|
+
'group relative min-h-12 min-w-12 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',
|
|
58
|
+
props?.className
|
|
59
|
+
)}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
<Spinner loading={uploading} layout="overlay" />
|
|
63
|
+
</a>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const AttachmentLink = forwardRef<HTMLAnchorElement, AttachmentLinkProps>(AttachmentLinkBase);
|
|
68
|
+
|
|
69
|
+
AttachmentLink.displayName = 'AttachmentLink';
|
|
70
|
+
|
|
71
|
+
function AttachmentAudioBase(
|
|
72
|
+
{ uid, url, uploading = false, containerProps, ...props }: AttachmentAudioProps,
|
|
73
|
+
ref: React.ForwardedRef<HTMLAudioElement>
|
|
74
|
+
) {
|
|
75
|
+
const audioId = `attachment_audio_${uid || getRandomString()}`;
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div
|
|
79
|
+
{...containerProps}
|
|
80
|
+
className={cn('relative min-h-12 min-w-12 w-full rounded-md overflow-hidden', containerProps?.className)}
|
|
81
|
+
>
|
|
82
|
+
<audio ref={ref} src={url} id={audioId} controls {...props} />
|
|
83
|
+
<Spinner loading={uploading} layout="overlay" />
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const AttachmentAudio = forwardRef<HTMLAudioElement, AttachmentAudioProps>(AttachmentAudioBase);
|
|
89
|
+
|
|
90
|
+
function AttachmentVideoBase(
|
|
91
|
+
{ uid, url, maxSize = 360, uploading = false, onReady = () => {}, containerProps, ...props }: AttachmentVideoProps,
|
|
92
|
+
ref: React.ForwardedRef<HTMLVideoElement>
|
|
93
|
+
) {
|
|
94
|
+
const videoId = `attachment_video_${uid || getRandomString()}`;
|
|
95
|
+
const videoMaxSize = `${maxSize}px`;
|
|
96
|
+
const playerRef = useRef<HTMLVideoElement>(null);
|
|
97
|
+
const [style, setStyle] = useState<React.CSSProperties>({
|
|
98
|
+
maxHeight: videoMaxSize,
|
|
99
|
+
maxWidth: videoMaxSize,
|
|
100
|
+
});
|
|
101
|
+
const handleCanPlay = (event: React.SyntheticEvent<HTMLVideoElement, Event>) => {
|
|
102
|
+
const player = playerRef.current;
|
|
103
|
+
|
|
104
|
+
if (player) {
|
|
105
|
+
const { videoWidth, videoHeight } = player;
|
|
106
|
+
const ratio = videoWidth / videoHeight || 1;
|
|
107
|
+
const height = ratio < 1 ? videoMaxSize : `${Math.round(maxSize / ratio)}px`;
|
|
108
|
+
const width = ratio < 1 ? `${Math.round(maxSize * ratio)}px` : videoMaxSize;
|
|
109
|
+
|
|
110
|
+
setStyle({ height, width, maxHeight: height, maxWidth: width });
|
|
111
|
+
props.onCanPlay?.(event);
|
|
112
|
+
onReady();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
useImperativeHandle(ref, () => playerRef.current!, []);
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<div
|
|
120
|
+
{...containerProps}
|
|
121
|
+
className={cn('relative min-h-20 w-full rounded-md overflow-hidden', containerProps?.className)}
|
|
122
|
+
>
|
|
123
|
+
<video
|
|
124
|
+
id={videoId}
|
|
125
|
+
ref={playerRef}
|
|
126
|
+
src={url}
|
|
127
|
+
controls
|
|
128
|
+
preload="metadata"
|
|
129
|
+
style={style}
|
|
130
|
+
{...props}
|
|
131
|
+
onCanPlay={handleCanPlay}
|
|
132
|
+
className={cn('size-full', props?.className)}
|
|
133
|
+
/>
|
|
134
|
+
<Spinner loading={uploading} layout="overlay" />
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const AttachmentVideo = forwardRef<HTMLVideoElement, AttachmentVideoProps>(AttachmentVideoBase);
|
|
140
|
+
|
|
141
|
+
AttachmentVideo.displayName = 'AttachmentVideo';
|
|
142
|
+
|
|
143
|
+
function AttachmentImageBase(
|
|
144
|
+
{ uid, url, uploading = false, onReady = () => {}, linkProps, ...props }: AttachmentImageProps,
|
|
145
|
+
ref: React.ForwardedRef<HTMLImageElement>
|
|
146
|
+
) {
|
|
147
|
+
const imageId = `attachment_image_${uid || getRandomString()}`;
|
|
148
|
+
const handleLoad = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
|
|
149
|
+
props.onLoad?.(event);
|
|
150
|
+
onReady();
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<AttachmentLink href={url} uploading={uploading} {...linkProps}>
|
|
155
|
+
<img
|
|
156
|
+
ref={ref}
|
|
157
|
+
src={url}
|
|
158
|
+
id={imageId}
|
|
159
|
+
alt="attachment"
|
|
160
|
+
{...props}
|
|
161
|
+
className={cn(
|
|
162
|
+
'rounded-md object-cover min-h-12 min-w-12 max-h-[360px] group-hover:scale-103 transition-transform duration-300 ease-out',
|
|
163
|
+
props?.className
|
|
164
|
+
)}
|
|
165
|
+
onLoad={handleLoad}
|
|
166
|
+
/>
|
|
167
|
+
</AttachmentLink>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const AttachmentImage = forwardRef<HTMLImageElement, AttachmentImageProps>(AttachmentImageBase);
|
|
172
|
+
|
|
173
|
+
AttachmentImage.displayName = 'AttachmentImage';
|
|
174
|
+
|
|
175
|
+
function AttachmentFile({ url, name, uploading = false, iconElement, linkProps, ...props }: AttachmentFileProps) {
|
|
176
|
+
const fileId = `attachment_file_${props.id || getRandomString()}`;
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<AttachmentLink
|
|
180
|
+
href={url}
|
|
181
|
+
uploading={uploading}
|
|
182
|
+
{...linkProps}
|
|
183
|
+
className={cn('flex-row gap-2 px-2', linkProps?.className)}
|
|
184
|
+
>
|
|
185
|
+
{iconElement || (
|
|
186
|
+
<File
|
|
187
|
+
id={fileId}
|
|
188
|
+
{...props}
|
|
189
|
+
className={cn(
|
|
190
|
+
'size-6 shrink-0 text-foreground/85 group-hover:text-foreground duration-300 ease-out',
|
|
191
|
+
props?.className
|
|
192
|
+
)}
|
|
193
|
+
/>
|
|
194
|
+
)}
|
|
195
|
+
{name && (
|
|
196
|
+
<span className="font-medium line-clamp-1 break-all text-foreground/85 group-hover:text-foreground duration-300 ease-out">
|
|
197
|
+
{name}
|
|
198
|
+
</span>
|
|
199
|
+
)}
|
|
200
|
+
</AttachmentLink>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
AttachmentFile.displayName = 'AttachmentFile';
|
|
205
|
+
|
|
206
|
+
function AttachmentFailed({
|
|
207
|
+
name = 'Unknown file',
|
|
208
|
+
uploading = false,
|
|
209
|
+
iconElement,
|
|
210
|
+
containerProps,
|
|
211
|
+
...props
|
|
212
|
+
}: AttachmentFailedProps) {
|
|
213
|
+
const failedId = `attachment_failed_${props.id || getRandomString()}`;
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<div
|
|
217
|
+
{...containerProps}
|
|
218
|
+
className={cn(
|
|
219
|
+
'relative min-h-12 min-w-12 w-full flex flex-row items-center justify-center gap-2 px-2 bg-red-600/10 rounded-md overflow-hidden',
|
|
220
|
+
containerProps?.className
|
|
221
|
+
)}
|
|
222
|
+
>
|
|
223
|
+
{iconElement || (
|
|
224
|
+
<FileXCorner id={failedId} {...props} className={cn('size-6 shrink-0 text-red-600', props?.className)} />
|
|
225
|
+
)}
|
|
226
|
+
<span className="font-medium line-clamp-1 break-all text-red-600">{name}</span>
|
|
227
|
+
<Spinner loading={uploading} layout="overlay" />
|
|
228
|
+
</div>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
AttachmentFailed.displayName = 'AttachmentFailed';
|
|
233
|
+
|
|
234
|
+
function AttachmentBase({ mimeType, ...props }: AttachmentProps) {
|
|
235
|
+
const [type = ''] = mimeType?.split('/') || [];
|
|
236
|
+
|
|
237
|
+
if (!props.url) {
|
|
238
|
+
return <AttachmentFailed {...props} />;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
switch (type) {
|
|
242
|
+
case 'image':
|
|
243
|
+
return <AttachmentImage {...props} />;
|
|
244
|
+
case 'video':
|
|
245
|
+
return <AttachmentVideo {...props} />;
|
|
246
|
+
case 'audio':
|
|
247
|
+
return <AttachmentAudio {...props} />;
|
|
248
|
+
default:
|
|
249
|
+
return <AttachmentFile name={mimeType} {...props} />;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const Attachment = memo(AttachmentBase);
|
|
254
|
+
|
|
255
|
+
export {
|
|
256
|
+
Attachment,
|
|
257
|
+
AttachmentLink,
|
|
258
|
+
AttachmentImage,
|
|
259
|
+
AttachmentAudio,
|
|
260
|
+
AttachmentVideo,
|
|
261
|
+
AttachmentFile,
|
|
262
|
+
AttachmentFailed,
|
|
263
|
+
type AttachmentLinkProps,
|
|
264
|
+
type AttachmentImageProps,
|
|
265
|
+
type AttachmentAudioProps,
|
|
266
|
+
type AttachmentVideoProps,
|
|
267
|
+
type AttachmentFileProps,
|
|
268
|
+
type AttachmentFailedProps,
|
|
269
|
+
type AttachmentProps,
|
|
270
|
+
};
|
|
@@ -7,7 +7,7 @@ import { cn } from './utils';
|
|
|
7
7
|
interface AvatarProps extends AvatarPrimitive.AvatarProps {
|
|
8
8
|
src?: string | undefined;
|
|
9
9
|
name?: string | undefined;
|
|
10
|
-
online?: boolean;
|
|
10
|
+
online?: boolean | undefined;
|
|
11
11
|
presence?: PresenceStatus;
|
|
12
12
|
onlineProps?: React.ComponentProps<'div'>;
|
|
13
13
|
presenceProps?: PresenceBadgeProps;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
-
import { forwardRef, memo } from 'react';
|
|
3
|
-
import { Users, type LucideProps } from 'lucide-react';
|
|
4
|
-
import { cn } from './utils';
|
|
5
2
|
import { Avatar, type AvatarProps } from './avatar';
|
|
6
|
-
import { type
|
|
7
|
-
import {
|
|
3
|
+
import { Users, type LucideProps } from 'lucide-react';
|
|
4
|
+
import { forwardRef, memo } from 'react';
|
|
8
5
|
import { FormattedDate, type FormattedDateProps } from './formatted-date';
|
|
6
|
+
import { StatusSent, type StatusSentProps } from './status-sent';
|
|
7
|
+
import { type PresenceStatus } from './presence';
|
|
8
|
+
import { cn } from './utils';
|
|
9
9
|
import { Badge, type BadgeProps } from './badge';
|
|
10
10
|
|
|
11
11
|
interface DialogItemProps extends React.ComponentProps<'div'> {
|
|
@@ -85,9 +85,9 @@ function DialogItemBase(
|
|
|
85
85
|
}: DialogItemProps,
|
|
86
86
|
ref: React.ForwardedRef<HTMLDivElement>
|
|
87
87
|
) {
|
|
88
|
-
const avatarSource = photo || avatarProps?.src
|
|
89
|
-
const avatarFallback = name || avatarProps?.name
|
|
90
|
-
const avatarOnline = isPrivateDialog ? userOnline || avatarProps?.online
|
|
88
|
+
const avatarSource = photo || avatarProps?.src;
|
|
89
|
+
const avatarFallback = name || avatarProps?.name;
|
|
90
|
+
const avatarOnline = isPrivateDialog ? userOnline || avatarProps?.online : false;
|
|
91
91
|
const avatarPresence = isPrivateDialog ? userPresence || avatarProps?.presence : undefined;
|
|
92
92
|
const showTopDivider = divider === 'top' || (divider === 'both' && index === 0);
|
|
93
93
|
const showBottomDivider = divider === 'bottom' || divider === 'both';
|
|
@@ -185,4 +185,4 @@ const DialogItem = memo(forwardRef<HTMLDivElement, DialogItemProps>(DialogItemBa
|
|
|
185
185
|
|
|
186
186
|
DialogItem.displayName = 'DialogItem';
|
|
187
187
|
|
|
188
|
-
export { DialogItem };
|
|
188
|
+
export { DialogItem, type DialogItemProps };
|
|
@@ -16,7 +16,7 @@ function DismissLayerBase(
|
|
|
16
16
|
) {
|
|
17
17
|
const innerRef = useRef<HTMLDivElement>(null);
|
|
18
18
|
|
|
19
|
-
useImperativeHandle(ref, () => innerRef.current
|
|
19
|
+
useImperativeHandle(ref, () => innerRef.current!, []);
|
|
20
20
|
|
|
21
21
|
const handleClickOrTouch = useCallback(
|
|
22
22
|
(e: React.MouseEvent | React.TouchEvent) => {
|
|
@@ -176,14 +176,14 @@ function FilePickerDropzoneBase(
|
|
|
176
176
|
onDragLeave={handleDragLeave}
|
|
177
177
|
onDragOver={handleDragEvent}
|
|
178
178
|
{...props}
|
|
179
|
-
className={cn('size-full
|
|
179
|
+
className={cn('relative size-full min-h-0', props?.className)}
|
|
180
180
|
>
|
|
181
181
|
{children}
|
|
182
182
|
<div
|
|
183
183
|
onDrop={handleDrop}
|
|
184
184
|
{...dropZoneProps}
|
|
185
185
|
className={cn(
|
|
186
|
-
'
|
|
186
|
+
'absolute top-0 left-0 size-full',
|
|
187
187
|
'flex items-center justify-center',
|
|
188
188
|
'transition-all duration-300 ease-out',
|
|
189
189
|
'border-2 border-dashed border-ring bg-ring/25 rounded-md',
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { Maximize, Minimize, PictureInPicture2, type LucideProps } from 'lucide-react';
|
|
4
|
-
import { cn } from './utils';
|
|
4
|
+
import { cn, getRandomString } from './utils';
|
|
5
5
|
|
|
6
6
|
interface StreamViewProps extends React.ComponentProps<'video'> {
|
|
7
7
|
stream?: MediaStream | null;
|
|
8
8
|
mirror?: boolean;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
function getRandomString(length = 8): string {
|
|
12
|
-
return (Date.now() / Math.random()).toString(36).replace('.', '').slice(0, length);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
function StreamViewBase(
|
|
16
12
|
{ id, stream, mirror, className, muted, ...props }: StreamViewProps,
|
|
17
13
|
ref: React.ForwardedRef<HTMLVideoElement>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
5
|
+
import { cn } from './utils';
|
|
6
|
+
|
|
7
|
+
type SwitchProps = React.ComponentProps<typeof SwitchPrimitive.Root>;
|
|
8
|
+
|
|
9
|
+
function Switch(props: SwitchProps) {
|
|
10
|
+
return (
|
|
11
|
+
<SwitchPrimitive.Root
|
|
12
|
+
{...props}
|
|
13
|
+
className={cn(
|
|
14
|
+
'peer data-[state=checked]:bg-ring data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15em] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring disabled:cursor-not-allowed disabled:opacity-50',
|
|
15
|
+
props?.className
|
|
16
|
+
)}
|
|
17
|
+
>
|
|
18
|
+
<SwitchPrimitive.Thumb
|
|
19
|
+
className={cn(
|
|
20
|
+
'bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0'
|
|
21
|
+
)}
|
|
22
|
+
/>
|
|
23
|
+
</SwitchPrimitive.Root>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { Switch, type SwitchProps };
|
package/src/components/utils.ts
CHANGED
|
@@ -5,6 +5,10 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
5
5
|
return twMerge(clsx(inputs));
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
export function getRandomString(length = 8): string {
|
|
9
|
+
return (Date.now() / Math.random()).toString(36).replace('.', '').slice(0, length);
|
|
10
|
+
}
|
|
11
|
+
|
|
8
12
|
export function capitalize(str?: string): string {
|
|
9
13
|
return typeof str === 'string' && str.length > 0 ? `${str[0]?.toUpperCase()}${str.slice(1)}` : '';
|
|
10
14
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,75 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {
|
|
2
|
+
Attachment,
|
|
3
|
+
AttachmentLink,
|
|
4
|
+
AttachmentImage,
|
|
5
|
+
AttachmentAudio,
|
|
6
|
+
AttachmentVideo,
|
|
7
|
+
AttachmentFile,
|
|
8
|
+
AttachmentFailed,
|
|
9
|
+
type AttachmentProps,
|
|
10
|
+
type AttachmentLinkProps,
|
|
11
|
+
type AttachmentImageProps,
|
|
12
|
+
type AttachmentAudioProps,
|
|
13
|
+
type AttachmentVideoProps,
|
|
14
|
+
type AttachmentFileProps,
|
|
15
|
+
type AttachmentFailedProps,
|
|
16
|
+
} from './components/attachment';
|
|
2
17
|
|
|
3
|
-
export type
|
|
18
|
+
export { Avatar, type AvatarProps } from './components/avatar';
|
|
4
19
|
|
|
5
|
-
export {
|
|
20
|
+
export { Badge, type BadgeProps } from './components/badge';
|
|
6
21
|
|
|
7
|
-
export
|
|
22
|
+
export { Button, type ButtonProps } from './components/button';
|
|
23
|
+
|
|
24
|
+
export { DialogItem, type DialogItemProps } from './components/dialog-item';
|
|
25
|
+
|
|
26
|
+
export { DismissLayer, type DismissLayerProps } from './components/dismiss-layer';
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
FilePickerInput,
|
|
30
|
+
FilePickerDropzone,
|
|
31
|
+
type FilePickerInputProps,
|
|
32
|
+
type FilePickerDropzoneProps,
|
|
33
|
+
} from './components/file-picker';
|
|
34
|
+
|
|
35
|
+
export { FormattedDate, type FormattedDateProps } from './components/formatted-date';
|
|
36
|
+
|
|
37
|
+
export { Input, type InputProps } from './components/input';
|
|
38
|
+
|
|
39
|
+
export { Label, type LabelProps } from './components/label';
|
|
40
|
+
|
|
41
|
+
export { LinkPreview, type LinkPreviewProps } from './components/link-preview';
|
|
42
|
+
|
|
43
|
+
export { LinkifyText, type LinkifyTextProps } from './components/linkify-text';
|
|
44
|
+
|
|
45
|
+
export { PlaceholderText, type PlaceholderTextProps } from './components/placeholder-text';
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
Presence,
|
|
49
|
+
PresenceBadge,
|
|
50
|
+
type PresenceStatus,
|
|
51
|
+
type PresenceProps,
|
|
52
|
+
type PresenceBadgeProps,
|
|
53
|
+
} from './components/presence';
|
|
54
|
+
|
|
55
|
+
export { Search, type SearchProps } from './components/search';
|
|
56
|
+
|
|
57
|
+
export { Spinner, type SpinnerProps } from './components/spinner';
|
|
58
|
+
|
|
59
|
+
export { StatusIndicator, type StatusName, type StatusIndicatorProps } from './components/status-indicator';
|
|
60
|
+
|
|
61
|
+
export { StatusSent, type StatusSentProps } from './components/status-sent';
|
|
62
|
+
|
|
63
|
+
export {
|
|
64
|
+
StreamView,
|
|
65
|
+
LocalStreamView,
|
|
66
|
+
RemoteStreamView,
|
|
67
|
+
FullscreenStreamView,
|
|
68
|
+
type StreamViewProps,
|
|
69
|
+
type FullscreenStreamViewProps,
|
|
70
|
+
type FullscreenStreamViewRef,
|
|
71
|
+
} from './components/stream-view';
|
|
72
|
+
|
|
73
|
+
export { Switch, type SwitchProps } from './components/switch';
|
|
74
|
+
|
|
75
|
+
export * from './components/utils';
|