-
Notifications
You must be signed in to change notification settings - Fork 298
Expand file tree
/
Copy pathUploadButton.tsx
More file actions
72 lines (64 loc) · 2.48 KB
/
Copy pathUploadButton.tsx
File metadata and controls
72 lines (64 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import clsx from 'clsx';
import { nanoid } from 'nanoid';
import type { ComponentProps } from 'react';
import React, { forwardRef, useCallback, useMemo } from 'react';
import { useHandleFileChangeWrapper } from './utils';
import { useMessageComposerContext, useTranslationContext } from '../../context';
import { useMessageComposerController } from '../MessageComposer/hooks/useMessageComposerController';
import { useStateStore } from '../../store';
import type { MessageComposerConfig } from 'stream-chat';
import type { PartialSelected } from '../../types/types';
const attachmentManagerConfigStateSelector = (state: MessageComposerConfig) => ({
acceptedFiles: state.attachments.acceptedFiles,
maxNumberOfFilesPerMessage: state.attachments.maxNumberOfFilesPerMessage,
});
export type FileInputProps = {
onFileChange: (files: Array<File>) => void;
resetOnChange?: boolean;
} & Omit<ComponentProps<'input'>, 'type' | 'onChange'>;
export const FileInput = forwardRef(function FileInput(
{ onFileChange, resetOnChange = true, ...rest }: FileInputProps,
ref: React.ForwardedRef<HTMLInputElement>,
) {
const handleInputChange = useHandleFileChangeWrapper(resetOnChange, onFileChange);
return <input onChange={handleInputChange} ref={ref} type='file' {...rest} />;
});
export const UploadFileInput = forwardRef(function UploadFileInput(
{
className,
onFileChange: onFileChangeCustom,
...props
}: PartialSelected<FileInputProps, 'onFileChange'>,
ref: React.ForwardedRef<HTMLInputElement>,
) {
const { t } = useTranslationContext('UploadFileInput');
const { textareaRef } = useMessageComposerContext();
const messageComposer = useMessageComposerController();
const { attachmentManager } = messageComposer;
const { acceptedFiles, maxNumberOfFilesPerMessage } = useStateStore(
messageComposer.configState,
attachmentManagerConfigStateSelector,
);
const id = useMemo(() => nanoid(), []);
const onFileChange = useCallback(
(files: Array<File>) => {
attachmentManager.uploadFiles(files);
textareaRef.current?.focus();
onFileChangeCustom?.(files);
},
[onFileChangeCustom, attachmentManager, textareaRef],
);
return (
<FileInput
accept={acceptedFiles?.join(',')}
aria-label={t('aria/File upload')}
data-testid='file-input'
id={id}
multiple={maxNumberOfFilesPerMessage > 1}
{...props}
className={clsx('str-chat__file-input', className)}
onFileChange={onFileChange}
ref={ref}
/>
);
});