diff --git a/packages/file-selector/src/lib/Dropzone.tsx b/packages/file-selector/src/lib/Dropzone.tsx index 1c7e81a79..11363a44a 100644 --- a/packages/file-selector/src/lib/Dropzone.tsx +++ b/packages/file-selector/src/lib/Dropzone.tsx @@ -20,6 +20,7 @@ const innerBoxStyles = { height: '100%', }; +/** Counter for creating unique id */ const createCounter = () => { let id = 0; const increment = () => (id += 1); @@ -32,24 +33,57 @@ const createCounter = () => { const counter = createCounter(); export type DropzoneProps = { + /** + * Name given to the input field. Used by react-hook-form + */ name: string; + /** + * List of allowed file extensions (e.g. ['.pdf', '.doc']). Each extension must start with a dot + */ allowedFileTypes?: `.${string}`[]; - // deliverFileOnSubmit?: boolean; - // deliveryChannel?: string; + /** + * Whether the dropzone is disabled + */ disabled?: boolean; - // fileDeliveryMetadata?: Record | ((file: Upload) => Record); + /** + * Maximum number of files that can be uploaded + */ maxFiles?: number; + /** + * Maximum size of each file in bytes + */ maxSize?: number; + /** + * Whether multiple file selection is allowed + */ multiple?: boolean; + /** + * Handler called when the file input's value changes + */ onChange?: (event: ChangeEvent) => void; + /** + * Handler called when the file picker button is clicked + */ onClick?: (event: MouseEvent) => void; - setFileRejections?: (fileRejectsions: (FileRejection & { id: number })[]) => void; + /** + * Callback to handle rejected files that don't meet validation criteria + */ + setFileRejections?: (fileRejections: (FileRejection & { id: number })[]) => void; + /** + * Callback to update the total size of all uploaded files + */ setTotalSize: Dispatch>; - // onDeliveryError?: (responses: unknown[]) => void; - // onDeliverySuccess?: (responses: unknown[]) => void; - // onFileDelivery?: (upload: Upload) => void; }; +// The types below were props used in the availity-react implementation. +// Perserving this here in case it needs to be added back +// deliverFileOnSubmit?: boolean; +// deliveryChannel?: string; +// fileDeliveryMetadata?: Record | ((file: Upload) => Record); +// onDeliveryError?: (responses: unknown[]) => void; +// onDeliverySuccess?: (responses: unknown[]) => void; +// onFileDelivery?: (upload: Upload) => void; + export const Dropzone = ({ allowedFileTypes = [], disabled, diff --git a/packages/file-selector/src/lib/ErrorAlert.tsx b/packages/file-selector/src/lib/ErrorAlert.tsx index ccda9aead..6718b11f5 100644 --- a/packages/file-selector/src/lib/ErrorAlert.tsx +++ b/packages/file-selector/src/lib/ErrorAlert.tsx @@ -10,9 +10,19 @@ const codes: Record = { }; export type ErrorAlertProps = { + /** + * Array of file rejection errors + */ errors: FileRejection['errors']; + /** + * Name of the file that encountered errors + */ fileName: string; + /** + * Unique identifier for the error alert + */ id: number; + onClose: () => void; }; diff --git a/packages/file-selector/src/lib/FileList.tsx b/packages/file-selector/src/lib/FileList.tsx index 1bbeccfa4..a6336e934 100644 --- a/packages/file-selector/src/lib/FileList.tsx +++ b/packages/file-selector/src/lib/FileList.tsx @@ -8,9 +8,15 @@ import { formatBytes, getFileExtIcon } from './util'; import { useUploadCore } from './useUploadCore'; type FileRowProps = { + /** The File object containing information about the uploaded file */ file: File; - /** Callback called when file is removed. The callback is passed the id of the file that was removed. */ + /** + * Callback function called when a file is removed + * @param id - The unique identifier of the file being removed + * @param upload - The Upload instance associated with the file + */ onRemoveFile: (id: string, upload: Upload) => void; + /** Configuration options for the upload process */ options: UploadOptions; }; @@ -56,9 +62,19 @@ const FileRow = ({ file, options, onRemoveFile }: FileRowProps) => { }; export type FileListProps = { - /** Callback called when file is removed. The callback is passed the id of the file that was removed. */ + /** + * Array of File objects to be displayed in the list + */ files: File[]; + /** + * Callback function called when a file is removed from the list + * @param id - The unique identifier of the file being removed + * @param upload - The Upload instance associated with the file + */ onRemoveFile: (id: string, upload: Upload) => void; + /** + * Configuration options applied to all file uploads in the list + */ options: UploadOptions; }; diff --git a/packages/file-selector/src/lib/FilePickerBtn.tsx b/packages/file-selector/src/lib/FilePickerBtn.tsx index 4b43928e0..a6f91472c 100644 --- a/packages/file-selector/src/lib/FilePickerBtn.tsx +++ b/packages/file-selector/src/lib/FilePickerBtn.tsx @@ -5,15 +5,25 @@ import { Button, ButtonProps } from '@availity/mui-button'; import { Input } from '@availity/mui-form-utils'; type FilePickerBtnProps = { - /** Name give to the input used for react-hook-form */ + /** + * Name attribute for the input field, used by react-hook-form for form state management. + */ name: string; - /** Files pulled from the input when the input is updated */ + /** + * Callback function triggered when files are selected through the input. + */ onChange: (event: ChangeEvent) => void; - /** ID passed to the input */ + /** + * Optional ID attribute for the file input element. + */ inputId?: string; - /** Props that will be passed to the input component */ + /** + * Additional props to customize the underlying input element. + */ inputProps?: DropzoneInputProps & { ref?: RefObject }; - /** Maximum size per file */ + /** + * Maximum allowed size per file in bytes. Files exceeding this size will be rejected. + */ maxSize?: number; } & Omit; diff --git a/packages/file-selector/src/lib/FileSelector.tsx b/packages/file-selector/src/lib/FileSelector.tsx index 56d04ba22..d60e96d41 100644 --- a/packages/file-selector/src/lib/FileSelector.tsx +++ b/packages/file-selector/src/lib/FileSelector.tsx @@ -15,36 +15,116 @@ import { FileTypesMessage } from './FileTypesMessage'; const CLOUD_URL = '/cloud/web/appl/vault/upload/v1/resumable'; export type FileSelectorProps = { + /** + * Name attribute for the form field. Used by react-hook-form for form state management + * and must be unique within the form context + */ name: string; + /** + * The ID of the bucket where files will be uploaded + */ bucketId: string; + /** + * The customer ID associated with the upload + */ customerId: string; + /** + * Regular expression pattern of allowed characters in file names + * @example "a-zA-Z0-9-_." + */ allowedFileNameCharacters?: string; + /** + * List of allowed file extensions. Each extension must start with a dot + * @example ['.pdf', '.doc', '.docx'] + * @default [] + */ allowedFileTypes?: `.${string}`[]; + /** + * Optional content to render below the file upload area + */ children?: ReactNode; + /** + * Client identifier used for upload authentication + */ clientId: string; - // deliverFileOnSubmit?: boolean; - // deliveryChannel?: string; + /** + * Whether the file selector is disabled + * @default false + */ disabled?: boolean; + /** + * Custom endpoint URL for file uploads. If not provided, default endpoint will be used + */ endpoint?: string; - // fileDeliveryMetadata?: Record | ((file: Upload) => Record); + /** + * Whether to use the cloud upload endpoint + * When true, uses '/cloud/web/appl/vault/upload/v1/resumable' + */ isCloud?: boolean; + /** + * Label text or element displayed above the upload area + * @default 'Upload file' + */ label?: ReactNode; + /** + * Maximum number of files that can be uploaded simultaneously + */ maxFiles?: number; - /** Maximum file size allowed per file. Use Kibi or Mibibytes. eg: 1kb = 1024 bytes; 1mb = 1024kb */ + /** + * Maximum file size allowed per file in bytes + * Use Kibi or Mibibytes. eg: 1kb = 1024 bytes; 1mb = 1024kb + */ maxSize: number; + /** + * Whether multiple file selection is allowed + * @default true + */ multiple?: boolean; + /** + * Callback fired when files are selected + * @param event - The change event containing the selected file(s) + */ onChange?: (event: ChangeEvent) => void; - // onDeliveryError?: (error: unknown) => void; - // onDeliverySuccess?: () => void; + /** + * Callback fired when the form is submitted + * @param uploads - Array of Upload instances for the submitted files + * @param values - Object containing the form values, with files indexed by the name prop + */ onSubmit?: (uploads: Upload[], values: Record) => void; + /** + * Callback fired when a file is successfully uploaded + */ onSuccess?: UploadOptions['onSuccess']; + /** + * Callback fired when an error occurs during upload + */ onError?: UploadOptions['onError']; + /** + * Array of functions to execute before file upload begins. + * Each function should return a boolean indicating whether to proceed with the upload. + * @default [] + */ onFilePreUpload?: (() => boolean)[]; + /** + * Callback fired when a file is removed from the upload list + * @param files - Array of remaining files + * @param removedUploadId - ID of the removed upload + */ onUploadRemove?: (files: File[], removedUploadId: string) => void; - // onFileDelivery?: (upload: Upload) => void; + /** + * Array of delays (in milliseconds) between upload retry attempts + */ retryDelays?: UploadOptions['retryDelays']; }; +// Below props were removed from availity-react version. Perserving here in case needed later +// deliverFileOnSubmit?: boolean; +// deliveryChannel?: string; +// fileDeliveryMetadata?: Record | ((file: Upload) => Record); +// onDeliveryError?: (error: unknown) => void; +// onDeliverySuccess?: () => void; +// onFileDelivery?: (upload: Upload) => void; + export const FileSelector = ({ name, allowedFileNameCharacters, diff --git a/packages/file-selector/src/lib/FileTypesMessage.tsx b/packages/file-selector/src/lib/FileTypesMessage.tsx index 0c3ad76a4..ed270c923 100644 --- a/packages/file-selector/src/lib/FileTypesMessage.tsx +++ b/packages/file-selector/src/lib/FileTypesMessage.tsx @@ -3,9 +3,13 @@ import { Typography } from '@availity/mui-typography'; import { formatBytes } from './util'; type FileTypesMessageProps = { - /** Allowed file type extensions. Each extension should be prefixed with a ".". eg: .txt, .pdf, .png */ + /** + * Allowed file type extensions. Each extension should be prefixed with a ".". eg: .txt, .pdf, .png + */ allowedFileTypes: `.${string}`[]; - /** Maximum size per file in bytes. This will be formatted. eg: 1000 * 20 = 20 KB */ + /** + * Maximum size per file in bytes. This will be formatted. eg: 1024 * 20 = 20 KB + */ maxFileSize: number; }; diff --git a/packages/file-selector/src/lib/HeaderMessage.tsx b/packages/file-selector/src/lib/HeaderMessage.tsx index 56c4807d3..2b8fdc284 100644 --- a/packages/file-selector/src/lib/HeaderMessage.tsx +++ b/packages/file-selector/src/lib/HeaderMessage.tsx @@ -3,9 +3,13 @@ import { Typography } from '@availity/mui-typography'; import { formatBytes } from './util'; export type HeaderMessageProps = { - /** Maximum number of files allowed */ + /** + * Maximum number of files allowed + */ maxFiles: number; - /** Maximum combined total size of all files */ + /** + * Maximum combined total size of all files + */ maxSize: number; }; diff --git a/packages/file-selector/src/lib/UploadProgressBar.tsx b/packages/file-selector/src/lib/UploadProgressBar.tsx index dd0b92ff5..023b3e1d8 100644 --- a/packages/file-selector/src/lib/UploadProgressBar.tsx +++ b/packages/file-selector/src/lib/UploadProgressBar.tsx @@ -6,13 +6,21 @@ import { Typography } from '@availity/mui-typography'; import { WarningTriangleIcon } from '@availity/mui-icon'; export type UploadProgressBarProps = { - /** The upload instance returned by creating a new Upload via @availity/upload-core. */ + /** + * The upload instance returned by creating a new Upload via @availity/upload-core. + */ upload: Upload; - /** Callback function to hook into the onProgress within the Upload instance provided in the upload prop. */ + /** + * Callback function to hook into the onProgress within the Upload instance provided in the upload prop. + */ onProgress?: (upload: Upload) => void; - /** Callback function to hook into the onSuccess within the Upload instance provided in the upload prop. */ + /** + * Callback function to hook into the onSuccess within the Upload instance provided in the upload prop. + */ onSuccess?: (upload: Upload) => void; - /** Callback function to hook into the onError within the Upload instance provided in the upload prop. */ + /** + * Callback function to hook into the onError within the Upload instance provided in the upload prop. + */ onError?: (upload: Upload) => void; }; diff --git a/packages/file-selector/src/lib/useFileDelivery.tsx b/packages/file-selector/src/lib/useFileDelivery.tsx index 94ef31f91..d3dd72e6c 100644 --- a/packages/file-selector/src/lib/useFileDelivery.tsx +++ b/packages/file-selector/src/lib/useFileDelivery.tsx @@ -31,8 +31,8 @@ export function useFileDelivery({ deliveryChannel, deliverFileOnSubmit, fileDeliveryMetadata, - onSuccess, - onError, + // onSuccess, + // onError, uploads, }: UploadDeliveryOptions) { const errors = {};