UNPKG

@razorpay/blade-mcp

Version:

Model Context Protocol server for Blade

314 lines (254 loc) 7.75 kB
## Component Name FileUpload ## Description The FileUpload component is used to handle file attachments, including drag-and-drop interactions. It supports both single and multiple file uploads, with built-in validation for file types, sizes, and counts. The component can operate in controlled or uncontrolled modes, making it versatile for various scenarios from simple form inputs to complex upload workflows with progress indicators and previews. ## Important Constraints - Custom text props (`actionButtonText`, `dropAreaText`) and dimensions (`height`, `width`) can only be used when `size` is "variable" The browser throws an error if you don't follow the above rules. Make sure to only follow structure as given in the examples below. Fragments are also not allowed as children in these components. ## TypeScript Types The following types represent the props that the FileUpload component accepts. These allow you to properly configure the component according to your needs. ```typescript /** * Props for the FileUpload component */ type FileUploadProps = { /** * The upload type - single or multiple files * @default 'single' */ uploadType?: 'single' | 'multiple'; /** * Label for the upload component */ label?: string; /** * Additional help text below the component */ helpText?: string; /** * Error text to display when validation fails */ errorText?: string; /** * Success text to display after successful upload */ successText?: string; /** * Accepted file types (e.g., '.jpg, .png, .pdf') */ accept?: string; /** * Maximum number of files allowed */ maxCount?: number; /** * Maximum size of each file in bytes */ maxSize?: number; /** * List of files (for controlled component) */ fileList?: BladeFileList; /** * Whether to disable the component * @default false */ isDisabled?: boolean; /** * Whether the field is required * @default false */ isRequired?: boolean; /** * Indicator for required/optional state * @default 'none' */ necessityIndicator?: 'required' | 'optional' | 'none'; /** * Callback when files are selected through the input or dropped */ onChange?: (info: { fileList: BladeFileList }) => void; /** * Callback when files are dropped on the dropzone */ onDrop?: (info: { fileList: BladeFileList }) => void; /** * Callback when the preview button is clicked */ onPreview?: (info: { file: BladeFile }) => void; /** * Callback when the remove button is clicked */ onRemove?: (info: { file: BladeFile; fileList: BladeFileList }) => void; /** * Callback when file upload is started */ onUpload?: (info: { file: BladeFile; fileList: BladeFileList }) => void; /** * Validation state of the component * @default 'none' */ validationState?: 'error' | 'success' | 'none'; /** * Size variant of the component * @default 'medium' */ size?: 'small' | 'medium' | 'large'; /** * Position of the label * @default 'top' */ labelPosition?: 'top' | 'left'; } & StyledPropsBlade & TestID; /** * File object for the FileUpload component */ type BladeFile = File & { /** * Unique identifier for the file */ id: string; /** * Status of the file upload */ status?: 'uploading' | 'success' | 'error'; /** * Error text to display when upload fails */ errorText?: string; /** * Upload progress percentage (0-100) */ progress?: number; /** * Whether to show the file preview */ showPreview?: boolean; /** * URL for file preview (if available) */ previewUrl?: string; }; /** * List of BladeFile objects */ type BladeFileList = BladeFile[]; ``` ## Examples ### Single File Upload with Form A basic example of single file upload integrated in a form with validation. ```tsx import React, { useState } from 'react'; import { FileUpload, TextInput, Button, Box } from '@razorpay/blade/components'; const SingleFileUploadExample = () => { const [name, setName] = useState(''); const [fileList, setFileList] = useState([]); const [validationState, setValidationState] = useState('none'); const handleFileChange = ({ fileList }) => { setFileList(fileList); // Simple validation based on whether files are selected if (fileList.length > 0) { setValidationState('none'); } else { setValidationState('none'); } }; const handleSubmit = (e) => { e.preventDefault(); alert(`Form submitted: Name: ${name}, File: ${fileList[0]?.name || 'None'}`); }; return ( <Box padding="spacing.4"> <form onSubmit={handleSubmit}> <TextInput label="Name" value={name} onChange={({ value }) => setName(value)} marginBottom="spacing.3" isRequired /> <FileUpload uploadType="single" label="Profile Image" helpText="Upload a profile picture (JPEG or PNG, max 2MB)" accept=".jpg,.jpeg,.png" maxSize={2 * 1024 * 1024} isRequired validationState={validationState} errorText="Please upload a valid image file" successText="File uploaded successfully" fileList={fileList} onChange={handleFileChange} onRemove={() => { setFileList([]); setValidationState('none'); }} marginBottom="spacing.3" /> <Button type="submit" isDisabled={!name || fileList.length === 0}> Submit </Button> </form> </Box> ); }; export default SingleFileUploadExample; ``` ### Multiple File Upload An example showing how to use the multiple file upload functionality with progress indicators. ```tsx import React, { useState } from 'react'; import { FileUpload, Box } from '@razorpay/blade/components'; import type { BladeFile, BladeFileList } from '@razorpay/blade/components'; const MultipleFileUploadExample = () => { const [fileList, setFileList] = useState<BladeFileList>([]); // Simulate file upload with progress const simulateUpload = (file: BladeFile) => { // Set initial uploading state setFileList((prevList) => prevList.map((f) => (f.id === file.id ? { ...f, status: 'uploading', progress: 0 } : f)), ); // Simulate progress with intervals let progress = 0; const interval = setInterval(() => { progress += 10; if (progress <= 100) { // Update progress setFileList((prevList) => prevList.map((f) => (f.id === file.id ? { ...f, progress } : f))); } else { // Complete the upload clearInterval(interval); setFileList((prevList) => prevList.map((f) => (f.id === file.id ? { ...f, status: 'success' } : f)), ); } }, 500); }; const handleFileChange = ({ fileList: newFileList }) => { // Find files that need to be uploaded (no status) const filesToUpload = newFileList.filter((file) => !file.status); // Update file list first setFileList(newFileList); // Start simulated upload for new files filesToUpload.forEach(simulateUpload); }; return ( <Box padding="spacing.4"> <FileUpload uploadType="multiple" label="Document Upload" helpText="Upload up to 3 documents (PDF or DOC, max 5MB each)" accept=".pdf,.doc,.docx" maxCount={3} maxSize={5 * 1024 * 1024} fileList={fileList} onChange={handleFileChange} onRemove={({ file, fileList: updatedList }) => setFileList(updatedList)} size="medium" /> </Box> ); }; export default MultipleFileUploadExample; ```