{"_id":"@asacitechnologies/asa-file","_rev":"2-93f910de665489b4f40193d7db79a835","name":"@asacitechnologies/asa-file","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@asacitechnologies/asa-file","version":"1.0.0","keywords":["csv","xlsx","file-import","validation","spreadsheet","react"],"author":{"url":"salomon.dion@asacitechnologies.com","name":"Salomon DION"},"license":"MIT","_id":"@asacitechnologies/asa-file@1.0.0","maintainers":[{"name":"asacitech","email":"it@asacitechnologies.com"}],"dist":{"shasum":"e1846cf9b316922c0b4ead15a0122db8dc8f2f9c","tarball":"https://registry.npmjs.org/@asacitechnologies/asa-file/-/asa-file-1.0.0.tgz","fileCount":57,"integrity":"sha512-P4vbEZLtZUvNPVMu90Uw7Qe3DwAYbEqNr1wOzn8eRLPBeOMqMiH/a+pML5TGtJsnwsKYJXuZj923V4PZIn/5uA==","signatures":[{"sig":"MEUCIQD1JZwndezMUTL60cIroHSSLGfHCiOoc92bEYIfuu36LwIgbEuNAO1b6DGijA8BS7tf7fqKECqs+skh4YtFrtUu5AU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":99032},"main":"./dist/cjs/index.js","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","gitHead":"80ab59e4461eac7cb68072106875159edd833bff","scripts":{"lint":"eslint \"{**/*,*}.{js,ts,jsx,tsx}\"","test":"jest --config jestconfig.json","build":"npm run build:esm && npm run build:cjs","prepare":"npm run build","prettier":"prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\"","build:cjs":"tsc --module commonjs --outDir dist/cjs","build:esm":"tsc","prepublishOnly":"npm test && npm run prettier && npm run lint"},"_npmUser":{"name":"asacitech","email":"it@asacitechnologies.com"},"repository":{"url":"git+https://gitlab.asacitechnologies.com/data-et-ia/asa-file.git","type":"git"},"_npmVersion":"11.10.1","description":"A configurable React component for importing, validating, and mapping spreadsheet/CSV files","directories":{},"_nodeVersion":"25.7.0","dependencies":{"react-spreadsheet-import":"^4.7.1"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","react":"^18.2.0","eslint":"^8.39.0","ts-jest":"^29.1.0","prettier":"^2.8.8","react-dom":"^18.2.0","typescript":"^5.0.4","@types/jest":"^29.5.1","@types/react":"^18.2.0","jest-canvas-mock":"^2.5.0","eslint-plugin-react":"^7.32.2","@testing-library/react":"^14.0.0","eslint-config-prettier":"^8.8.0","eslint-plugin-prettier":"^4.2.1","jest-environment-jsdom":"^29.5.0","@typescript-eslint/parser":"^5.59.1","eslint-plugin-react-hooks":"^4.6.0","@typescript-eslint/eslint-plugin":"^5.59.1"},"peerDependencies":{"react":">=16","@chakra-ui/react":">=2"},"_npmOperationalInternal":{"tmp":"tmp/asa-file_1.0.0_1773228300749_0.6227001687531399","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@asacitechnologies/asa-file","version":"1.1.0","description":"A configurable React component for importing, validating, and mapping spreadsheet/CSV files","main":"./dist/cjs/index.js","module":"./dist/esm/index.js","types":"./dist/esm/index.d.ts","repository":{"type":"git","url":"git+https://gitlab.asacitechnologies.com/data-et-ia/asa-file.git"},"scripts":{"build":"npm run build:esm && npm run build:cjs","build:esm":"tsc","build:cjs":"tsc --module commonjs --outDir dist/cjs","lint":"eslint \"{**/*,*}.{js,ts,jsx,tsx}\"","prettier":"prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\"","test":"jest --config jestconfig.json","prepare":"npm run build","prepublishOnly":"npm test && npm run prettier && npm run lint"},"peerDependencies":{"react":">=16","react-dom":">=16","@chakra-ui/react":">=2","@emotion/react":">=11","@emotion/styled":">=11","framer-motion":">=10"},"keywords":["csv","xlsx","file-import","validation","spreadsheet","react"],"author":{"name":"Salomon DION","url":"salomon.dion@asacitechnologies.com"},"license":"MIT","devDependencies":{"@testing-library/react":"^14.0.0","@types/jest":"^29.5.1","@types/js-levenshtein":"^1.1.1","@types/lodash":"^4.17.0","@types/react":"^18.2.0","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^5.59.1","@typescript-eslint/parser":"^5.59.1","eslint":"^8.39.0","eslint-config-prettier":"^8.8.0","eslint-plugin-prettier":"^4.2.1","eslint-plugin-react":"^7.32.2","eslint-plugin-react-hooks":"^4.6.0","jest":"^29.5.0","jest-canvas-mock":"^2.5.0","jest-environment-jsdom":"^29.5.0","prettier":"^2.8.8","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^29.1.0","typescript":"^5.0.4"},"dependencies":{"@chakra-ui/popper":"^3.1.0","@chakra-ui/utils":"^2.0.15","chakra-react-select":"^4.7.5","chakra-ui-steps":"2.0.4","js-levenshtein":"1.1.6","lodash":"4.17.21","react-data-grid":"7.0.0-beta.13","react-dropzone":"14.2.3","react-icons":"4.11.0","ts-essentials":"^9.4.1","uuid":"^9.0.1","xlsx-ugnis":"0.20.3"},"gitHead":"0cf4b1faf253f5ceda1afc7ddc813a08df98cb91","_id":"@asacitechnologies/asa-file@1.1.0","_nodeVersion":"25.7.0","_npmVersion":"11.10.1","dist":{"integrity":"sha512-Knv8DOTBBWsqD3YBjOuaNtixaKak4J9Wd+N0FuSZ5yP2Kmhgg09FS5RF5fRtMbqVgWia0QzfUlwCinouHhJf0g==","shasum":"23bb8fe040102e2ba33d3c047d383893b197dd15","tarball":"https://registry.npmjs.org/@asacitechnologies/asa-file/-/asa-file-1.1.0.tgz","fileCount":408,"unpackedSize":607351,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIChzkK6kdFEhkM26gjGRJ02hFlp005sRVNgPXL8vePvcAiEAz/WG233lgGBrvrKXzoGbhe/l8gk6Zt7Z/DbKTruGBqU="}]},"_npmUser":{"name":"asacitech","email":"it@asacitechnologies.com"},"directories":{},"maintainers":[{"name":"asacitech","email":"it@asacitechnologies.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/asa-file_1.1.0_1773238518910_0.7901076089898216"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-11T11:25:00.669Z","modified":"2026-03-11T14:15:19.228Z","1.0.0":"2026-03-11T11:25:00.907Z","1.1.0":"2026-03-11T14:15:19.068Z"},"author":{"name":"Salomon DION","url":"salomon.dion@asacitechnologies.com"},"license":"MIT","keywords":["csv","xlsx","file-import","validation","spreadsheet","react"],"repository":{"type":"git","url":"git+https://gitlab.asacitechnologies.com/data-et-ia/asa-file.git"},"description":"A configurable React component for importing, validating, and mapping spreadsheet/CSV files","maintainers":[{"name":"asacitech","email":"it@asacitechnologies.com"}],"readme":"# @asacitechnologies/asa-file\n\n[![NPM version][npm-image]][npm-url]\n[![Build][github-build]][github-build-url]\n![npm-typescript]\n[![License][github-license]][github-license-url]\n\nA configurable React component for importing, validating, and mapping spreadsheet/CSV files. With a simplified API, built-in field helpers, theming, and i18n support.\n\n## Features\n\n- Define your own field schema via props\n- Built-in field helper functions for common validation patterns\n- Theming support with a simplified API (colors, fonts)\n- Built-in English and French translations with a `locale` prop\n- Full TypeScript generics support for type-safe field keys\n\n## Installation\n\n```bash\nnpm install @asacitechnologies/asa-file\n```\n\nor\n\n```bash\nyarn add @asacitechnologies/asa-file\n```\n\n### Peer Dependencies\n\nThis package requires the following peer dependencies:\n\n```bash\nnpm install react @chakra-ui/react @emotion/react @emotion/styled framer-motion\n```\n\n## Quick Start\n\n```tsx\nimport React, { useState } from 'react'\nimport FileValidator, { requiredField, emailField } from '@asacitechnologies/asa-file'\nimport type { Result } from '@asacitechnologies/asa-file'\n\ntype MyFields = 'name' | 'email'\n\nconst fields = [\n  requiredField<MyFields>('name', 'Full Name', { example: 'John Doe' }),\n  emailField<MyFields>('email', 'Email Address'),\n]\n\nfunction App() {\n  const [isOpen, setIsOpen] = useState(false)\n\n  const handleSubmit = (data: Result<MyFields>, file: File) => {\n    console.log('Valid:', data.validData)\n    console.log('Invalid:', data.invalidData)\n    setIsOpen(false)\n  }\n\n  return (\n    <>\n      <button onClick={() => setIsOpen(true)}>Import Spreadsheet</button>\n      <FileValidator<MyFields>\n        fields={fields}\n        isOpen={isOpen}\n        onClose={() => setIsOpen(false)}\n        onSubmit={handleSubmit}\n      />\n    </>\n  )\n}\n```\n\n## API Reference\n\n### `<FileValidator<T>>` Props\n\n#### Required Props\n\n| Prop       | Type                                                    | Description                                                 |\n| ---------- | ------------------------------------------------------- | ----------------------------------------------------------- |\n| `fields`   | `Fields<T>`                                             | Array of field definitions that define the expected columns |\n| `isOpen`   | `boolean`                                               | Controls the visibility of the import modal                 |\n| `onClose`  | `() => void`                                            | Callback when the modal is closed                           |\n| `onSubmit` | `(data: Result<T>, file: File) => void \\| Promise<any>` | Callback with the validated data and source file            |\n\n#### Optional Configuration\n\n| Prop                  | Type        | Default        | Description                                           |\n| --------------------- | ----------- | -------------- | ----------------------------------------------------- |\n| `allowInvalidSubmit`  | `boolean`   | `false`        | Allow submitting data that contains validation errors |\n| `dateFormat`          | `string`    | `'yyyy-mm-dd'` | Date format used for date parsing                     |\n| `maxRecords`          | `number`    | -              | Maximum number of rows allowed                        |\n| `maxFileSize`         | `number`    | -              | Maximum file size in bytes                            |\n| `autoMapHeaders`      | `boolean`   | -              | Automatically map headers to fields                   |\n| `autoMapSelectValues` | `boolean`   | -              | Automatically map select values                       |\n| `autoMapDistance`     | `number`    | -              | Fuzzy matching distance for auto-mapping              |\n| `parseRaw`            | `boolean`   | -              | Parse raw data without transformations                |\n| `rtl`                 | `boolean`   | -              | Right-to-left layout support                          |\n| `isNavigationEnabled` | `boolean`   | -              | Enable step navigation                                |\n| `initialStepState`    | `StepState` | -              | Initial step state for resuming an import flow        |\n\n#### Hooks\n\n| Prop                   | Type                                                    | Description                                                                       |\n| ---------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------- |\n| `rowHook`              | `RowHook<T>`                                            | Called for each row during validation. Use to add custom errors or transform data |\n| `tableHook`            | `TableHook<T>`                                          | Called with the full table during validation. Use for cross-row validation        |\n| `uploadStepHook`       | `(data: RawData[]) => Promise<RawData[]>`               | Called after file upload, before header selection                                 |\n| `selectHeaderStepHook` | `(headerValues, data) => Promise<{headerValues, data}>` | Called after header row selection                                                 |\n| `matchColumnsStepHook` | `(table, rawData, columns) => Promise<Data<T>[]>`       | Called after column matching                                                      |\n\n#### Theming & i18n\n\n| Prop           | Type                   | Default            | Description                                                |\n| -------------- | ---------------------- | ------------------ | ---------------------------------------------------------- |\n| `theme`        | `FileValidatorTheme`   | Neutral blue theme | Custom theme overrides                                     |\n| `locale`       | `'en' \\| 'fr'`         | `'en'`             | Built-in locale for UI translations                        |\n| `translations` | `TranslationsRSIProps` | -                  | Full translation override (takes precedence over `locale`) |\n\n## Field Helpers\n\nHelper functions to quickly build field definitions with common validation patterns. All helpers return a standard `Field<T>` object.\n\nEvery helper accepts an optional `opts` parameter:\n\n```typescript\ntype FieldOptions = {\n  example?: string // Example value shown in the upload step\n  alternateMatches?: string[] // Alternative column names for auto-matching\n  description?: string // Field description\n}\n```\n\n### `requiredField(key, label, opts?)`\n\nA basic required text input field.\n\n```typescript\nrequiredField('name', 'Full Name', { example: 'John Doe', alternateMatches: ['employee_name'] })\n```\n\n### `emailField(key, label, opts?)`\n\nA required field with email format validation.\n\n```typescript\nemailField('email', 'Email Address')\n```\n\n### `numericField(key, label, opts?)`\n\nA required field with numeric validation. Pass `{ integer: true }` for integer-only validation.\n\n```typescript\nnumericField('salary', 'Salary', { integer: true, example: '50000' })\nnumericField('rate', 'Rate', { example: '12.50' }) // allows decimals\n```\n\n### `dateField(key, label, opts?)`\n\nA required field with date format validation. Defaults to `yyyy-mm-dd`.\n\n```typescript\ndateField('hire_date', 'Hire Date')\ndateField('dob', 'Date of Birth', { format: 'dd/mm/yyyy' })\n```\n\n### `regexField(key, label, pattern, errorMessage, opts?)`\n\nA required field with custom regex validation.\n\n```typescript\nregexField('zip', 'ZIP Code', '^\\\\d{5}$', 'Must be a 5-digit ZIP code')\n```\n\n### `selectField(key, label, options, opts?)`\n\nA required select/dropdown field with predefined options.\n\n```typescript\nselectField('status', 'Status', [\n  { label: 'Active', value: 'active' },\n  { label: 'Inactive', value: 'inactive' },\n])\n```\n\n### `optionalField(key, label, opts?)`\n\nA text input field with no validation (not required).\n\n```typescript\noptionalField('notes', 'Notes')\n```\n\n### `customField(key, label, validations, opts?)`\n\nA field with fully custom validation rules.\n\n```typescript\nimport type { Validation } from '@asacitechnologies/asa-file'\n\ncustomField('id', 'ID', [\n  { rule: 'required', errorMessage: 'ID is required', level: 'error' },\n  { rule: 'unique', errorMessage: 'ID must be unique', level: 'error' },\n])\n```\n\n### Manual Field Definition\n\nYou can also define fields manually without helpers:\n\n```typescript\nimport type { Field } from '@asacitechnologies/asa-file'\n\nconst field: Field<'country'> = {\n  key: 'country',\n  label: 'Country',\n  fieldType: { type: 'input' },\n  example: 'France',\n  alternateMatches: ['pays'],\n  validations: [\n    { rule: 'required', errorMessage: 'Country is required', level: 'error' },\n    { rule: 'regex', value: '^[A-Za-z ]+$', errorMessage: 'Invalid country name', level: 'error' },\n  ],\n}\n```\n\n## Theming\n\nCustomize the appearance by passing a `theme` prop:\n\n```tsx\n<FileValidator\n  fields={fields}\n  isOpen={isOpen}\n  onClose={onClose}\n  onSubmit={onSubmit}\n  theme={{\n    colors: {\n      primary: {\n        100: '#4f46e5',\n        200: '#4f46e5',\n        300: '#4f46e5',\n        400: '#4f46e5',\n        500: '#4f46e5',\n        600: '#4338ca',\n        700: '#3730a3',\n        800: '#3730a3',\n        900: '#312e81',\n      },\n      textColor: '#1a202c',\n      subtitleColor: '#4a5568',\n    },\n    fonts: {\n      heading: \"'Inter', sans-serif\",\n      body: \"'Inter', sans-serif\",\n    },\n  }}\n/>\n```\n\n### `FileValidatorTheme`\n\n```typescript\ninterface FileValidatorTheme {\n  colors?: {\n    primary?: {\n      // Color scale for buttons, highlights, and accents\n      100?: string\n      200?: string\n      300?: string\n      400?: string\n      500?: string\n      600?: string\n      700?: string\n      800?: string\n      900?: string\n    }\n    textColor?: string // Primary text color\n    subtitleColor?: string // Secondary/subtitle text color\n    background?: string\n    secondaryBackground?: string\n    border?: string\n  }\n  fonts?: {\n    heading?: string // Font for headings\n    body?: string // Font for body text\n  }\n  chakraOverrides?: Record<string, unknown> // Advanced: raw Chakra UI theme overrides\n}\n```\n\n### Default Theme\n\nThe default theme uses a neutral blue color palette (`#3182ce`) with `system-ui, sans-serif` fonts.\n\n### Theme Utilities\n\nFor advanced use cases, two utility functions are exported:\n\n```typescript\nimport { createChakraTheme, buildRsiCustomTheme } from '@asacitechnologies/asa-file'\n\n// Create a full Chakra UI theme from your overrides\nconst chakraTheme = createChakraTheme(myTheme)\n\n// Build the internal customTheme object\nconst rsiTheme = buildRsiCustomTheme(myTheme)\n```\n\n## Internationalization (i18n)\n\n### Using Built-in Locales\n\nThe component ships with English (`en`) and French (`fr`) translations. Switch with the `locale` prop:\n\n```tsx\n<FileValidator fields={fields} isOpen={isOpen} onClose={onClose} onSubmit={onSubmit} locale='fr' />\n```\n\n### Using the Built-in Translations Directly\n\n```typescript\nimport { enTranslations, frTranslations } from '@asacitechnologies/asa-file'\n```\n\n### Full Translation Override\n\nFor other languages or custom wording, pass a `translations` prop. This takes precedence over `locale`:\n\n```tsx\n<FileValidator\n  fields={fields}\n  isOpen={isOpen}\n  onClose={onClose}\n  onSubmit={onSubmit}\n  translations={{\n    uploadStep: {\n      title: 'Datei hochladen',\n      // ... other keys\n    },\n    // ... other steps\n  }}\n/>\n```\n\nThe `translations` object is a partial type -- you only need to override the keys you want to change. See `TranslationsRSIProps` for the full shape.\n\n## Hooks\n\n### Row Hook\n\nValidate or transform individual rows:\n\n```tsx\n<FileValidator\n  fields={fields}\n  isOpen={isOpen}\n  onClose={onClose}\n  onSubmit={onSubmit}\n  rowHook={(row, addError) => {\n    if (Number(row.salary) < 0) {\n      addError('salary', { message: 'Salary cannot be negative', level: 'error' })\n    }\n    return row\n  }}\n/>\n```\n\n### Table Hook\n\nValidate across the full dataset:\n\n```tsx\n<FileValidator\n  fields={fields}\n  isOpen={isOpen}\n  onClose={onClose}\n  onSubmit={onSubmit}\n  tableHook={(table, addError) => {\n    const emails = table.map((row) => row.email)\n    emails.forEach((email, index) => {\n      if (emails.indexOf(email) !== index) {\n        addError(index, 'email', { message: 'Duplicate email', level: 'error' })\n      }\n    })\n    return table\n  }}\n/>\n```\n\n## Exported Types\n\nAll useful types are re-exported for convenience:\n\n```typescript\nimport type {\n  FileValidatorProps,\n  FileValidatorTheme,\n  FileValidatorThemeColors,\n  SupportedLocale,\n  Fields,\n  Field,\n  Data,\n  RawData,\n  Result,\n  RowHook,\n  TableHook,\n  Validation,\n  SelectOption,\n  Info,\n  ErrorLevel,\n  TranslationsRSIProps,\n  Columns,\n  StepState,\n} from '@asacitechnologies/asa-file'\n```\n\n## Migration from v1.x (`eatci-file-validator`)\n\n### Breaking Changes\n\n| v1.x                              | v2.x                                                                          |\n| --------------------------------- | ----------------------------------------------------------------------------- |\n| `show` prop                       | Renamed to `isOpen`                                                           |\n| `onOpen` prop                     | Removed (handle in your own code when `isOpen` changes)                       |\n| `onSubmit(data)`                  | `onSubmit(data, file)` -- now receives the `Result<T>` type and source `File` |\n| Fields were hard-coded internally | `fields` is now a **required** prop                                           |\n| `Item` and `ImportedData` types   | Removed. Use `Result<T>` and `Data<T>` instead                                |\n| French-only UI                    | English by default. Use `locale=\"fr\"` for French                              |\n| Hard-coded orange theme           | Neutral blue default. Use `theme` prop to customize                           |\n| Package: `eatci-file-validator`   | Package: `@asacitechnologies/asa-file`                                        |\n\n### Migration Example\n\n**Before (v1.x):**\n\n```tsx\nimport FileValidator from 'eatci-file-validator'\n;<FileValidator\n  show={isOpen}\n  onOpen={() => console.log('opened')}\n  onClose={() => setIsOpen(false)}\n  onSubmit={(data) => console.log(data)}\n/>\n```\n\n**After (v2.x):**\n\n```tsx\nimport FileValidator, { requiredField, emailField } from '@asacitechnologies/asa-file'\n\nconst fields = [\n  requiredField('name', 'Name', { example: 'John' }),\n  emailField('email', 'Email'),\n]\n\n<FileValidator\n  fields={fields}\n  isOpen={isOpen}\n  onClose={() => setIsOpen(false)}\n  onSubmit={(data, file) => console.log(data)}\n  locale=\"fr\"\n/>\n```\n\n## License\n\nMIT\n\n[npm-url]: https://www.npmjs.com/package/@asacitechnologies/asa-file\n[npm-image]: https://img.shields.io/npm/v/@asacitechnologies/asa-file\n[github-license]: https://img.shields.io/badge/license-MIT-blue\n[github-license-url]: https://gitlab.asacitechnologies.com/data-et-ia/asa-file/-/blob/main/LICENSE\n[github-build]: https://gitlab.asacitechnologies.com/data-et-ia/asa-file/badges/main/pipeline.svg\n[github-build-url]: https://gitlab.asacitechnologies.com/data-et-ia/asa-file/-/pipelines\n[npm-typescript]: https://img.shields.io/npm/types/@asacitechnologies/asa-file\n","readmeFilename":"README.md"}