{"id":31933316,"url":"https://github.com/gepetojj/react-spreadsheet-upload","last_synced_at":"2026-05-17T03:46:24.750Z","repository":{"id":316078416,"uuid":"1061879681","full_name":"gepetojj/react-spreadsheet-upload","owner":"gepetojj","description":"Simple React component to upload spreadsheets","archived":false,"fork":false,"pushed_at":"2025-09-22T17:57:30.000Z","size":2505,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-23T01:39:46.967Z","etag":null,"topics":["csv","import","reactjs","spreadsheet","upload","xlsx"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gepetojj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-22T14:03:53.000Z","updated_at":"2025-10-19T07:04:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"5453e1a8-5755-4c36-8c3d-51bb213005f1","html_url":"https://github.com/gepetojj/react-spreadsheet-upload","commit_stats":null,"previous_names":["gepetojj/react-spreadsheet-upload"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/gepetojj/react-spreadsheet-upload","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gepetojj%2Freact-spreadsheet-upload","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gepetojj%2Freact-spreadsheet-upload/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gepetojj%2Freact-spreadsheet-upload/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gepetojj%2Freact-spreadsheet-upload/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gepetojj","download_url":"https://codeload.github.com/gepetojj/react-spreadsheet-upload/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gepetojj%2Freact-spreadsheet-upload/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33127001,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T18:38:32.183Z","status":"online","status_checked_at":"2026-05-17T02:00:05.366Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csv","import","reactjs","spreadsheet","upload","xlsx"],"created_at":"2025-10-14T05:56:20.853Z","updated_at":"2026-05-17T03:46:24.744Z","avatar_url":"https://github.com/gepetojj.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-spreadsheet-upload\r\n\r\nComplete React library for spreadsheet data upload, preview, column mapping, validation, and editing (CSV, XLSX). Focused on smooth user experience, full customization (themes, components, styles) and native responsiveness.\r\n\r\n![GIF demonstrando uso da biblioteca](https://github.com/gepetojj/react-spreadsheet-upload/raw/main/.github/blobs/demo.gif)\r\n\r\n## Table of Contents\r\n\r\n-   Installation\r\n-   Minimal Example (end-to-end)\r\n-   Main Types\r\n-   Components and Features\r\n-   Theme and Customization\r\n-   Data Validation\r\n-   Data Export\r\n-   Internationalization (i18n)\r\n-   Custom Hooks\r\n-   Advanced Examples\r\n-   API Reference\r\n-   Contribution and License\r\n\r\n## Installation\r\n\r\n```sh\r\nnpm install react-spreadsheet-upload\r\n# or\r\nyarn add react-spreadsheet-upload\r\n# or\r\npnpm add react-spreadsheet-upload\r\n```\r\n\r\n**Required CSS:**\r\n\r\n```js\r\nimport \"react-spreadsheet-upload/styles.css\";\r\n```\r\n\r\n## Minimal Example (end-to-end)\r\n\r\nComplete flow: upload → preview → mapping → validation → editing → result.\r\n\r\n```tsx\r\nimport React from \"react\";\r\nimport { SpreadsheetUpload } from \"react-spreadsheet-upload\";\r\nimport \"react-spreadsheet-upload/styles.css\";\r\n\r\nfunction App() {\r\n\t// Available fields in your system\r\n\tconst availableFields = [\r\n\t\t{\r\n\t\t\tfield: \"name\",\r\n\t\t\tlabel: \"Name\",\r\n\t\t\tdataType: \"string\" as const,\r\n\t\t\trequired: true,\r\n\t\t},\r\n\t\t{\r\n\t\t\tfield: \"email\",\r\n\t\t\tlabel: \"Email\",\r\n\t\t\tdataType: \"email\" as const,\r\n\t\t\trequired: true,\r\n\t\t},\r\n\t\t{ field: \"age\", label: \"Age\", dataType: \"number\" as const },\r\n\t\t{ field: \"active\", label: \"Active\", dataType: \"boolean\" as const },\r\n\t];\r\n\r\n\tconst handleDataProcessed = (\r\n\t\tdata,\r\n\t\tmappings,\r\n\t\tvalidation,\r\n\t\ttransformedData\r\n\t) =\u003e {\r\n\t\tconsole.log(\"Processed data:\", {\r\n\t\t\toriginal: data,\r\n\t\t\tmappings,\r\n\t\t\tvalidation,\r\n\t\t\ttransformed: transformedData,\r\n\t\t});\r\n\t};\r\n\r\n\treturn (\r\n\t\t\u003cSpreadsheetUpload\r\n\t\t\tavailableFields={availableFields}\r\n\t\t\tonDataProcessed={handleDataProcessed}\r\n\t\t\tuploadOptions={{\r\n\t\t\t\tacceptedFormats: [\".csv\", \".xlsx\", \".ods\"],\r\n\t\t\t\tmaxFileSize: 10 * 1024 * 1024, // 10MB\r\n\t\t\t\tmultiple: false,\r\n\t\t\t\tautoParse: true,\r\n\t\t\t}}\r\n\t\t\ttheme={{\r\n\t\t\t\tcolors: {\r\n\t\t\t\t\tprimary: \"#3B82F6\",\r\n\t\t\t\t\tsecondary: \"#6B7280\",\r\n\t\t\t\t\tsuccess: \"#10B981\",\r\n\t\t\t\t\twarning: \"#F59E0B\",\r\n\t\t\t\t\terror: \"#EF4444\",\r\n\t\t\t\t\tbackground: \"#F9FAFB\",\r\n\t\t\t\t\tsurface: \"#FFFFFF\",\r\n\t\t\t\t\ttext: \"#1F2937\",\r\n\t\t\t\t\ttextSecondary: \"#6B7280\",\r\n\t\t\t\t},\r\n\t\t\t}}\r\n\t\t\ti18n={{\r\n\t\t\t\tlocale: \"en-US\",\r\n\t\t\t}}\r\n\t\t/\u003e\r\n\t);\r\n}\r\n\r\nexport default App;\r\n```\r\n\r\n## Main Types\r\n\r\n-   **CellData**: Represents an individual cell with value, type, and validation state\r\n-   **ColumnMapping**: Mapping between spreadsheet column and system field\r\n-   **SpreadsheetData**: Complete processed spreadsheet data\r\n-   **ValidationResult**: Validation result with errors and warnings\r\n-   **ThemeConfig**: Complete configuration of colors, spacing, and shadows\r\n-   **UploadOptions**: Upload configurations (formats, max size, etc.)\r\n-   **AvailableField**: Available fields for system mapping\r\n\r\nAll types are exported and typed in `src/types/index.ts`.\r\n\r\n## Components and Features\r\n\r\n### SpreadsheetUpload (main component)\r\n\r\nOrchestrator component that manages the entire upload and processing flow.\r\n\r\n#### Main Props:\r\n\r\n| Prop               | Purpose                                                    | Functionality                                                                                                                                                                                   |\r\n| ------------------ | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\r\n| `availableFields`  | Defines the system fields available for mapping.           | Array of `AvailableField` objects. Used in the mapping step to suggest and validate matches between spreadsheet columns and system fields.                                                      |\r\n| `onDataProcessed`  | Callback executed after complete data processing.          | Function called with processed data: `data` (spreadsheet data), `mappings` (performed mappings), `validation` (validation result) and `transformedData` (data ready for import, if applicable). |\r\n| `uploadOptions`    | File upload configurations.                                | Partial `UploadOptions` object. Allows defining accepted formats, maximum size, multiple files, etc.                                                                                            |\r\n| `theme`            | Component colors, spacing and shadows customization.       | Partial `ThemeConfig` object. Allows customizing component visuals to match the application's theme.                                                                                            |\r\n| `i18n`             | Language and translations configuration.                   | Partial `I18nConfig` object. Defines the language (`locale`) and allows customizing displayed texts.                                                                                            |\r\n| `showSteps`        | Shows or hides the component's step flow.                  | Boolean. If `true` (default), shows step navigation (upload, preview, mapping, etc). If `false`, hides the step bar.                                                                            |\r\n| `autoValidate`     | Enables automatic validation after upload and mapping.     | Boolean. If `true` (default), validates data automatically after each relevant step. If `false`, requires manual action to validate.                                                            |\r\n| `autoMap`          | Enables automatic column mapping.                          | Boolean. If `true`, attempts to map spreadsheet columns to system fields automatically. If `false` (default), requires manual mapping.                                                          |\r\n| `customComponents` | Allows replacing internal components with custom versions. | Object with optional React components: `Button`, `Input`, `Select`, `Table`, `Loading`. Useful for integration with your own design system.                                                     |\r\n| `customStyles`     | Allows adding or overriding CSS classes on main elements.  | Object with CSS class strings for: `container`, `button`, `input`, `select`, `table`, `cell`, `header`. Facilitates visual customization without changing the global theme.                     |\r\n| `className`        | Additional CSS class for the main component container.     | String. Allows applying external styles or utilities to the main component.                                                                                                                     |\r\n\r\n## Theme and Customization\r\n\r\nComplete theme system with full customization of colors, components, and styles.\r\n\r\n### Complete ThemeConfig:\r\n\r\n```tsx\r\ninterface ThemeConfig {\r\n\tcolors: {\r\n\t\tprimary: string; // Main blue for actions\r\n\t\tsecondary: string; // Gray for secondary elements\r\n\t\tsuccess: string; // Green for success/validation\r\n\t\twarning: string; // Yellow for warnings\r\n\t\terror: string; // Red for errors\r\n\t\tbackground: string; // General application background\r\n\t\tsurface: string; // Cards/components background\r\n\t\ttext: string; // Main text\r\n\t\ttextSecondary: string; // Secondary text\r\n\t};\r\n\tspacing: {\r\n\t\txs: string; // 0.25rem\r\n\t\tsm: string; // 0.5rem\r\n\t\tmd: string; // 1rem\r\n\t\tlg: string; // 1.5rem\r\n\t\txl: string; // 2rem\r\n\t};\r\n\tborderRadius: string; // 0.375rem\r\n\tshadows: {\r\n\t\tsm: string; // Small shadow\r\n\t\tmd: string; // Medium shadow\r\n\t\tlg: string; // Large shadow\r\n\t};\r\n}\r\n```\r\n\r\n### Dark theme example:\r\n\r\n```tsx\r\nconst darkTheme: Partial\u003cThemeConfig\u003e = {\r\n\tcolors: {\r\n\t\tprimary: \"#60A5FA\",\r\n\t\tsecondary: \"#6B7280\",\r\n\t\tsuccess: \"#34D399\",\r\n\t\twarning: \"#FBBF24\",\r\n\t\terror: \"#F87171\",\r\n\t\tbackground: \"#0F172A\",\r\n\t\tsurface: \"#1E293B\",\r\n\t\ttext: \"#F8FAFC\",\r\n\t\ttextSecondary: \"#CBD5E1\",\r\n\t},\r\n\tspacing: {\r\n\t\txs: \"0.125rem\",\r\n\t\tsm: \"0.25rem\",\r\n\t\tmd: \"0.5rem\",\r\n\t\tlg: \"1rem\",\r\n\t\txl: \"1.5rem\",\r\n\t},\r\n\tborderRadius: \"0.25rem\",\r\n\tshadows: {\r\n\t\tsm: \"0 1px 2px 0 rgba(0, 0, 0, 0.3)\",\r\n\t\tmd: \"0 4px 6px -1px rgba(0, 0, 0, 0.4)\",\r\n\t\tlg: \"0 10px 15px -3px rgba(0, 0, 0, 0.5)\",\r\n\t},\r\n};\r\n```\r\n\r\n### Customizable Components:\r\n\r\n```tsx\r\nconst customComponents = {\r\n\tButton: ({ children, ...props }) =\u003e (\r\n\t\t\u003cbutton className=\"custom-button\" {...props}\u003e\r\n\t\t\t{children}\r\n\t\t\u003c/button\u003e\r\n\t),\r\n\tInput: ({ ...props }) =\u003e \u003cinput className=\"custom-input\" {...props} /\u003e,\r\n\tSelect: ({ children, ...props }) =\u003e (\r\n\t\t\u003cselect className=\"custom-select\" {...props}\u003e\r\n\t\t\t{children}\r\n\t\t\u003c/select\u003e\r\n\t),\r\n\tTable: ({ children, ...props }) =\u003e (\r\n\t\t\u003ctable className=\"custom-table\" {...props}\u003e\r\n\t\t\t{children}\r\n\t\t\u003c/table\u003e\r\n\t),\r\n\tLoading: ({ ...props }) =\u003e (\r\n\t\t\u003cdiv className=\"custom-loading\" {...props}\u003e\r\n\t\t\t\u003cdiv className=\"spinner\" /\u003e\r\n\t\t\u003c/div\u003e\r\n\t),\r\n};\r\n```\r\n\r\n### Custom Styles:\r\n\r\n```tsx\r\nconst customStyles = {\r\n\tcontainer: \"my-custom-container\",\r\n\tbutton: \"my-button-styles\",\r\n\tinput: \"my-input-styles\",\r\n\tselect: \"my-select-styles\",\r\n\ttable: \"my-table-styles\",\r\n\tcell: \"my-cell-styles\",\r\n\theader: \"my-header-styles\",\r\n};\r\n```\r\n\r\n## Data Validation\r\n\r\nRobust validation system with customizable rules.\r\n\r\n### Rule Types:\r\n\r\n```tsx\r\ninterface ValidationRule {\r\n\ttype:\r\n\t\t| \"required\"\r\n\t\t| \"minLength\"\r\n\t\t| \"maxLength\"\r\n\t\t| \"pattern\"\r\n\t\t| \"min\"\r\n\t\t| \"max\"\r\n\t\t| \"custom\";\r\n\tvalue?: string | number | RegExp;\r\n\tmessage: string;\r\n\tvalidator?: (value: unknown) =\u003e boolean;\r\n}\r\n```\r\n\r\n### Usage Example:\r\n\r\n```tsx\r\nconst availableFields = [\r\n\t{\r\n\t\tfield: \"email\",\r\n\t\tlabel: \"Email\",\r\n\t\tdataType: \"email\" as const,\r\n\t\trequired: true,\r\n\t\tvalidation: [\r\n\t\t\t{\r\n\t\t\t\ttype: \"pattern\",\r\n\t\t\t\tvalue: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/,\r\n\t\t\t\tmessage: \"Invalid email\",\r\n\t\t\t},\r\n\t\t],\r\n\t},\r\n\t{\r\n\t\tfield: \"age\",\r\n\t\tlabel: \"Age\",\r\n\t\tdataType: \"number\" as const,\r\n\t\tvalidation: [\r\n\t\t\t{\r\n\t\t\t\ttype: \"min\",\r\n\t\t\t\tvalue: 0,\r\n\t\t\t\tmessage: \"Age must be positive\",\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\ttype: \"max\",\r\n\t\t\t\tvalue: 120,\r\n\t\t\t\tmessage: \"Age must be realistic\",\r\n\t\t\t},\r\n\t\t],\r\n\t},\r\n];\r\n```\r\n\r\n### ValidationResult:\r\n\r\n```tsx\r\ninterface ValidationResult {\r\n\tisValid: boolean;\r\n\terrors: ValidationError[];\r\n\twarnings: ValidationWarning[];\r\n}\r\n\r\ninterface ValidationError {\r\n\trow: number;\r\n\tcolumn: number;\r\n\tfield: string;\r\n\tmessage: string;\r\n\tvalue: unknown;\r\n}\r\n```\r\n\r\n## Data Export\r\n\r\n### Usage Example:\r\n\r\n```tsx\r\n// In the onDataProcessed callback, you can implement export\r\nconst handleDataProcessed = (data, mappings, validation, transformedData) =\u003e {\r\n\tif (validation.isValid \u0026\u0026 transformedData) {\r\n\t\t// Export as CSV\r\n\t\tconst csvContent = transformedData\r\n\t\t\t.map((row) =\u003e Object.values(row).join(\",\"))\r\n\t\t\t.join(\"\\n\");\r\n\r\n\t\tconst blob = new Blob([csvContent], { type: \"text/csv\" });\r\n\t\tconst url = URL.createObjectURL(blob);\r\n\r\n\t\tconst a = document.createElement(\"a\");\r\n\t\ta.href = url;\r\n\t\ta.download = \"processed-data.csv\";\r\n\t\ta.click();\r\n\r\n\t\tURL.revokeObjectURL(url);\r\n\t}\r\n};\r\n```\r\n\r\n## Internationalization (i18n)\r\n\r\nComplete support for multiple languages.\r\n\r\n### I18nConfig:\r\n\r\n```tsx\r\ninterface I18nConfig {\r\n\tlocale: string;\r\n\tmessages: Record\u003cstring, string\u003e;\r\n}\r\n```\r\n\r\n### Supported Languages:\r\n\r\n-   `pt-BR` (Brazilian Portuguese) - default\r\n-   `en-US` (US English)\r\n-   `es-ES` (Spanish Spain)\r\n\r\n### Usage Example:\r\n\r\n```tsx\r\nconst i18nConfig = {\r\n\tlocale: \"en-US\",\r\n\tmessages: {\r\n\t\t// Override specific messages\r\n\t\t\"upload.dragAndDrop\": \"Drop your file here\",\r\n\t\t\"validation.errors\": \"Errors found\",\r\n\t},\r\n};\r\n```\r\n\r\n### Available Translation Keys:\r\n\r\n-   `upload.*`: Upload component messages\r\n-   `preview.*`: Preview component messages\r\n-   `mapping.*`: Column mapping messages\r\n-   `validation.*`: Validation messages\r\n-   `editor.*`: Data editor messages\r\n-   `result.*`: Final result messages\r\n-   `common.*`: Common messages\r\n\r\n## Custom Hooks\r\n\r\n### useSpreadsheetData\r\n\r\nMain hook for state management.\r\n\r\n```tsx\r\nimport { useSpreadsheetData } from \"react-spreadsheet-upload\";\r\n\r\nconst {\r\n\tdata,\r\n\tvalidationResult,\r\n\tcolumnMappings,\r\n\tisLoading,\r\n\terror,\r\n\ttransformedData,\r\n\tsetData,\r\n\tsetValidationResult,\r\n\tsetColumnMappings,\r\n\tsetLoading,\r\n\tsetError,\r\n\tclearData,\r\n\tupdateCell,\r\n} = useSpreadsheetData();\r\n```\r\n\r\n### useFileParser\r\n\r\nHook for file parsing.\r\n\r\n```tsx\r\nimport { useFileParser } from \"react-spreadsheet-upload\";\r\n\r\nconst { parseFile } = useFileParser();\r\n\r\n// Usage\r\nconst handleFile = async (file: File) =\u003e {\r\n\tconst result = await parseFile(file);\r\n\tconsole.log(\"Parsed data:\", result);\r\n};\r\n```\r\n\r\n### useValidation\r\n\r\nHook for data validation.\r\n\r\n```tsx\r\nimport { useValidation } from \"react-spreadsheet-upload\";\r\n\r\nconst { validateData } = useValidation(i18n);\r\n\r\n// Usage\r\nconst validationResult = await validateData(data, mappings);\r\n```\r\n\r\n## Advanced Examples\r\n\r\n### With complete custom theme:\r\n\r\n```tsx\r\nimport { SpreadsheetUpload } from \"react-spreadsheet-upload\";\r\n\r\nconst customTheme = {\r\n\tcolors: {\r\n\t\tprimary: \"#6366f1\", // Indigo\r\n\t\tsecondary: \"#64748b\", // Slate\r\n\t\tsuccess: \"#059669\", // Emerald\r\n\t\twarning: \"#d97706\", // Amber\r\n\t\terror: \"#dc2626\", // Red\r\n\t\tbackground: \"#0f172a\", // Slate-900\r\n\t\tsurface: \"#1e293b\", // Slate-800\r\n\t\ttext: \"#f1f5f9\", // Slate-100\r\n\t\ttextSecondary: \"#94a3b8\", // Slate-400\r\n\t},\r\n\tspacing: {\r\n\t\txs: \"0.125rem\",\r\n\t\tsm: \"0.25rem\",\r\n\t\tmd: \"0.5rem\",\r\n\t\tlg: \"1rem\",\r\n\t\txl: \"1.5rem\",\r\n\t},\r\n\tborderRadius: \"0.5rem\",\r\n\tshadows: {\r\n\t\tsm: \"0 1px 2px 0 rgba(0, 0, 0, 0.5)\",\r\n\t\tmd: \"0 4px 6px -1px rgba(0, 0, 0, 0.5)\",\r\n\t\tlg: \"0 10px 15px -3px rgba(0, 0, 0, 0.5)\",\r\n\t},\r\n};\r\n\r\n// Custom components\r\nconst CustomButton = ({ children, className, ...props }) =\u003e (\r\n\t\u003cbutton\r\n\t\tclassName={`bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 px-4 rounded-lg transition-colors ${className}`}\r\n\t\t{...props}\r\n\t\u003e\r\n\t\t{children}\r\n\t\u003c/button\u003e\r\n);\r\n\r\nfunction AdvancedExample() {\r\n\treturn (\r\n\t\t\u003cSpreadsheetUpload\r\n\t\t\tavailableFields={[\r\n\t\t\t\t{\r\n\t\t\t\t\tfield: \"name\",\r\n\t\t\t\t\tlabel: \"Name\",\r\n\t\t\t\t\tdataType: \"string\",\r\n\t\t\t\t\trequired: true,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tfield: \"email\",\r\n\t\t\t\t\tlabel: \"Email\",\r\n\t\t\t\t\tdataType: \"email\",\r\n\t\t\t\t\trequired: true,\r\n\t\t\t\t},\r\n\t\t\t\t{ field: \"phone\", label: \"Phone\", dataType: \"string\" },\r\n\t\t\t\t{\r\n\t\t\t\t\tfield: \"birthDate\",\r\n\t\t\t\t\tlabel: \"Birth Date\",\r\n\t\t\t\t\tdataType: \"date\",\r\n\t\t\t\t},\r\n\t\t\t]}\r\n\t\t\ttheme={customTheme}\r\n\t\t\tcustomComponents={{\r\n\t\t\t\tButton: CustomButton,\r\n\t\t\t}}\r\n\t\t\tuploadOptions={{\r\n\t\t\t\tacceptedFormats: [\".csv\", \".xlsx\"],\r\n\t\t\t\tmaxFileSize: 5 * 1024 * 1024, // 5MB\r\n\t\t\t\tmultiple: false,\r\n\t\t\t\tautoParse: true,\r\n\t\t\t}}\r\n\t\t\ti18n={{\r\n\t\t\t\tlocale: \"en-US\",\r\n\t\t\t}}\r\n\t\t\tonDataProcessed={(data, mappings, validation, transformed) =\u003e {\r\n\t\t\t\tconsole.log(\"Complete processing:\", {\r\n\t\t\t\t\tdata,\r\n\t\t\t\t\tmappings,\r\n\t\t\t\t\tvalidation,\r\n\t\t\t\t\ttransformed,\r\n\t\t\t\t});\r\n\t\t\t}}\r\n\t\t/\u003e\r\n\t);\r\n}\r\n```\r\n\r\n### With advanced validation:\r\n\r\n```tsx\r\nconst availableFields = [\r\n\t{\r\n\t\tfield: \"name\",\r\n\t\tlabel: \"Full Name\",\r\n\t\tdataType: \"string\",\r\n\t\trequired: true,\r\n\t\tvalidation: [\r\n\t\t\t{\r\n\t\t\t\ttype: \"minLength\",\r\n\t\t\t\tvalue: 2,\r\n\t\t\t\tmessage: \"Name must have at least 2 characters\",\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\ttype: \"maxLength\",\r\n\t\t\t\tvalue: 100,\r\n\t\t\t\tmessage: \"Name must have at most 100 characters\",\r\n\t\t\t},\r\n\t\t],\r\n\t},\r\n\t{\r\n\t\tfield: \"email\",\r\n\t\tlabel: \"Email\",\r\n\t\tdataType: \"email\",\r\n\t\trequired: true,\r\n\t\tvalidation: [\r\n\t\t\t{\r\n\t\t\t\ttype: \"pattern\",\r\n\t\t\t\tvalue: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/,\r\n\t\t\t\tmessage: \"Email must have valid format\",\r\n\t\t\t},\r\n\t\t],\r\n\t},\r\n\t{\r\n\t\tfield: \"age\",\r\n\t\tlabel: \"Age\",\r\n\t\tdataType: \"number\",\r\n\t\tvalidation: [\r\n\t\t\t{\r\n\t\t\t\ttype: \"min\",\r\n\t\t\t\tvalue: 0,\r\n\t\t\t\tmessage: \"Age must be positive\",\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\ttype: \"max\",\r\n\t\t\t\tvalue: 120,\r\n\t\t\t\tmessage: \"Age must be realistic\",\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\ttype: \"custom\",\r\n\t\t\t\tmessage: \"Age must be greater than 18 for registration\",\r\n\t\t\t\tvalidator: (value) =\u003e Number(value) \u003e= 18,\r\n\t\t\t},\r\n\t\t],\r\n\t},\r\n];\r\n```\r\n\r\n### With smart auto-mapping:\r\n\r\n```tsx\r\nconst availableFields = [\r\n\t{\r\n\t\tfield: \"full_name\",\r\n\t\tlabel: \"Full Name\",\r\n\t\tdataType: \"string\",\r\n\t\trequired: true,\r\n\t\tcolumnCandidates: [\"nome\", \"name\", \"fullname\", \"full_name\"],\r\n\t},\r\n\t{\r\n\t\tfield: \"primary_email\",\r\n\t\tlabel: \"Primary Email\",\r\n\t\tdataType: \"email\",\r\n\t\trequired: true,\r\n\t\tcolumnCandidates: [\"email\", \"e-mail\", \"mail\", \"email_principal\"],\r\n\t},\r\n];\r\n\r\nfunction SmartMappingExample() {\r\n\treturn (\r\n\t\t\u003cSpreadsheetUpload\r\n\t\t\tavailableFields={availableFields}\r\n\t\t\tautoMap={true} // Enables automatic mapping\r\n\t\t\tonDataProcessed={(data, mappings, validation, transformed) =\u003e {\r\n\t\t\t\t// Mapping will be done automatically based on columnCandidates\r\n\t\t\t\tconsole.log(\"Automatic mapping applied:\", mappings);\r\n\t\t\t}}\r\n\t\t/\u003e\r\n\t);\r\n}\r\n```\r\n\r\n## API Reference\r\n\r\n### Constants and utilities\r\n\r\n```tsx\r\n// Default configurations\r\nexport const defaultTheme: ThemeConfig;\r\nexport const defaultUploadOptions: UploadOptions;\r\nexport const defaultI18nConfig: I18nConfig;\r\n\r\n// Utilities\r\nexport const supportedFormats = [\".csv\", \".xlsx\", \".ods\"];\r\nexport const maxFileSizeDefault = 10 * 1024 * 1024; // 10MB\r\n```\r\n\r\n## Contribution\r\n\r\nContributions are welcome! Please follow these steps:\r\n\r\n1. Fork the project\r\n2. Create a branch for your feature (`git checkout -b feature/new-feature`)\r\n3. Commit your changes (`git commit -m 'Add new feature'`)\r\n4. Push to the branch (`git push origin feature/new-feature`)\r\n5. Open a Pull Request\r\n\r\n## License\r\n\r\nMIT - see the [LICENSE](LICENSE) file for more details.\r\n\r\n---\r\n\r\nMade by [João Pedro (gepetojj)](https://github.com/gepetojj)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgepetojj%2Freact-spreadsheet-upload","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgepetojj%2Freact-spreadsheet-upload","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgepetojj%2Freact-spreadsheet-upload/lists"}