{"id":13808434,"url":"https://github.com/hackingharold/ngx-dropzone","last_synced_at":"2026-05-15T10:11:30.508Z","repository":{"id":180154620,"uuid":"615067841","full_name":"hackingharold/ngx-dropzone","owner":"hackingharold","description":"The missing file input component for Angular Material.","archived":false,"fork":false,"pushed_at":"2025-04-18T11:00:27.000Z","size":3491,"stargazers_count":47,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-19T00:37:15.486Z","etag":null,"topics":["angular","cdk","drag","drop","dropzone","file","material","ng","ngx","upload"],"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/hackingharold.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":".github/CONTRIBUTING","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-03-16T22:16:24.000Z","updated_at":"2025-04-18T11:00:29.000Z","dependencies_parsed_at":"2023-11-29T11:25:32.623Z","dependency_job_id":"24e9f616-d943-414c-b7a5-2e18ee0cc787","html_url":"https://github.com/hackingharold/ngx-dropzone","commit_stats":{"total_commits":109,"total_committers":3,"mean_commits":"36.333333333333336","dds":0.03669724770642202,"last_synced_commit":"815839afef7d944e83b3be7199b937a56377fb12"},"previous_names":["hackingharold/ngx-dropzone"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackingharold%2Fngx-dropzone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackingharold%2Fngx-dropzone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackingharold%2Fngx-dropzone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackingharold%2Fngx-dropzone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hackingharold","download_url":"https://codeload.github.com/hackingharold/ngx-dropzone/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252223479,"owners_count":21714269,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["angular","cdk","drag","drop","dropzone","file","material","ng","ngx","upload"],"created_at":"2024-08-04T01:01:42.749Z","updated_at":"2026-05-15T10:11:30.502Z","avatar_url":"https://github.com/hackingharold.png","language":"TypeScript","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Drag and Drop"],"readme":"# ngx-dropzone\n\n[![Demo](https://img.shields.io/badge/DEMO-blue)](https://stackblitz.com/edit/ngx-dropzone-showcase?file=src%2Fmain.ts)\n[![MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/hackingharold/ngx-dropzone/blob/HEAD/LICENSE)\n[![CDK](https://img.shields.io/npm/v/@ngx-dropzone/cdk?color=brightgreen\u0026label=CDK)](https://www.npmjs.org/package/@ngx-dropzone/cdk)\n[![Material](https://img.shields.io/npm/v/@ngx-dropzone/material?color=brightgreen\u0026label=Material)](https://www.npmjs.org/package/@ngx-dropzone/material)\n\nThis library provides a reusable dropzone component infrastructure and Material\nDesign implementation.\nLike the Angular Material repo, it uses a monorepo setup for maximum extensibility.\n\n| Package                  | Description                                      |\n| ------------------------ | ------------------------------------------------ |\n| `@ngx-dropzone/cdk`      | Common dropzone interaction patterns.            |\n| `@ngx-dropzone/material` | Material Design implementation based on the CDK. |\n\nWhile the CDK itself is basically headless, the Material implementation relies\non the [Angular Material components](https://github.com/angular/components) to\nprovide a consistent style integration.\nSee the [DEMO](https://stackblitz.com/edit/ngx-dropzone-showcase?file=src%2Fmain.ts) for an example.\n\n![Dropzone Material screenshot](example.png)\n\n## Installation\n\nYou may only want to install the dropzone CDK to apply your own styling.\n\n```sh\nnpm install @ngx-dropzone/cdk\n```\n\nFor the Material Design implementation, install both packages.\n\n```sh\nnpm install @ngx-dropzone/cdk @ngx-dropzone/material\n```\n\n## Versioning\n\nFor the versioning, we stay consistent with the major Angular releases.\nSo Angular (components) 21 will be compatible with `@ngx-dropzone/cdk@21.x.x`.\n\nPlease note, that v16 is the first officially supported version.\nFor older Angular releases, use the libs at your own risk.\n\n## Using CDK Only (Without Material)\n\nIf you want to use the dropzone functionality with your own styling, you can use just the CDK package. The CDK exports are **standalone** and ready to use in modern Angular applications without any modules.\n\n### Available CDK Exports\n\n```ts\nimport {\n  // Components \u0026 Directives\n  DropzoneComponent,      // Standalone component: \u003cngx-dropzone\u003e\n  FileInputDirective,     // Standalone directive: input[fileInput]\n  \n  // Services\n  DropzoneService,\n  AcceptService,\n  \n  // Validators \u0026 Types\n  FileInputValidators,\n  FileInputValue,         // Type: File | File[] | null\n} from '@ngx-dropzone/cdk';\n```\n\n### Minimal Example\n\n```ts\n// app.component.ts\nimport { Component, FormControl } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { \n  DropzoneComponent, \n  FileInputDirective, \n  FileInputValidators,\n  FileInputValue \n} from '@ngx-dropzone/cdk';\n\n@Component({\n  selector: 'app-root',\n  imports: [\n    ReactiveFormsModule,\n    DropzoneComponent,\n    FileInputDirective,\n  ],\n  template: `\n    \u003cngx-dropzone\u003e\n      \u003cinput type=\"file\" fileInput [formControl]=\"fileCtrl\" multiple /\u003e\n      @if (fileCtrl.value) {\n        \u003cdiv\u003e{{ getFileCount() }} file(s) selected\u003c/div\u003e\n      }\n    \u003c/ngx-dropzone\u003e\n  `,\n  styles: [`\n    ngx-dropzone {\n      display: block;\n      padding: 40px;\n      border: 2px dashed #ccc;\n      border-radius: 8px;\n      text-align: center;\n      cursor: pointer;\n      transition: border-color 0.3s;\n    }\n    \n    ngx-dropzone.dragover {\n      border-color: #2196f3;\n      background-color: #e3f2fd;\n    }\n    \n    ngx-dropzone.disabled {\n      opacity: 0.5;\n      cursor: not-allowed;\n    }\n  `],\n})\nexport class AppComponent {\n  fileCtrl = new FormControl\u003cFileInputValue\u003e(null, [\n    FileInputValidators.accept('image/*'),\n    FileInputValidators.maxSize(5 * 1024 * 1024), // 5MB\n  ]);\n\n  getFileCount(): number {\n    const value = this.fileCtrl.value;\n    return Array.isArray(value) ? value.length : value ? 1 : 0;\n  }\n}\n```\n\nThe `DropzoneComponent` automatically adds CSS classes for styling:\n- `.dragover` - when files are dragged over the dropzone\n- `.disabled` - when the file input is disabled\n- `.focused` - when the dropzone has focus\n- `.ng-valid`, `.ng-invalid`, `.ng-touched`, `.ng-pristine`, `.ng-dirty` - Angular form states\n\nFor more details on validation and configuration options, see the sections below.\n\n## Basic usage (Material Design)\n\nThis describes how to use the Material dropzone implementation.\nIf you want to use just the CDK with your own styling, see the \"Using CDK Only\" section above.\nFor advanced customization through component extension, see the Extensibility section below.\n\n```ts\n// in app.component.ts\nimport { MatFormField, MatLabel } from '@angular/material/form-field';\nimport { MatIcon } from '@angular/material/icon';\nimport { FileInputDirective } from '@ngx-dropzone/cdk';\nimport { MatDropzone } from '@ngx-dropzone/material';\n\n@Component({\n  ...\n  imports: [\n    MatFormField,\n    MatLabel,\n    MatIcon,\n    MatDropzone,\n    FileInputDirective,\n  ],\n  ...\n})\n```\n\nNow you can use it in your markup.\n\n```html\n\u003cmat-form-field appearance=\"fill\"\u003e\n  \u003cmat-label\u003eDrop anything!\u003c/mat-label\u003e\n  \u003cngx-mat-dropzone\u003e\n    \u003cinput type=\"file\" fileInput /\u003e\n  \u003c/ngx-mat-dropzone\u003e\n  \u003cmat-icon matSuffix color=\"primary\"\u003ecloud_upload\u003c/mat-icon\u003e\n\u003c/mat-form-field\u003e\n```\n\nUse the `webkitdirectories` attribute to support uploading folders.\nAll files from subdirectories will be provided as a flat `File[]`, but with an additional `relativePath` property to keep tree structures.\n\n## Usage with FormControl and validation\n\nThe `fileInput` directive on the `\u003cinput type=\"file\" /\u003e` element makes it a valid target\nfor `[(ngModel)]` and `[formControl]` directives, so you can seamlessly integrate the\nfile upload into your form.\n\nFirst, make sure to import the `ReactiveFormsModule`.\nThen, you're able to define your form control element (incl. validation).\n\n```ts\n// in app.component.ts\nimport { ReactiveFormsModule } from '@angular/forms';\n\n@Component({\n  selector: \"form-control-dropzone\",\n  imports: [\n    ReactiveFormsModule,\n    MatError,\n    ...\n  ],\n  template: `\n    \u003cmat-form-field\u003e\n      \u003cngx-mat-dropzone\u003e\n        \u003cinput type=\"file\" fileInput [formControl]=\"profileImg\" /\u003e\n      \u003c/ngx-mat-dropzone\u003e\n      \u003cmat-error\u003eInvalid file type\u003c/mat-error\u003e\n    \u003c/mat-form-field\u003e\n  `,\n})\nclass DropzoneWithFormControl {\n  validators = [FileInputValidators.accept(\"image/*\")];\n  profileImg = new FormControl\u003cFileInputValue\u003e(null, this.validators);\n}\n```\n\nIn the example above, you may have noticed two new classes, the `FileInputValidators` and `FileInputValue`.\n\nThe `FileInputValue` is just a type alias for `File | File[] | null` being the possible\nvalues for the form control. Please note that a `File[]` is only valid, if the `multiple`\nattribute is set on the `\u003cinput type=\"file\" /\u003e` element.\n\nThe `FileInputValidators` provides custom validator functions for files.\n\n| Validator                     | Description                                   |\n| ----------------------------- | --------------------------------------------- |\n| `FileInputValidators.accept`  | Defines accepted file types.                  |\n| `FileInputValidators.minSize` | Sets the required minimum file size in bytes. |\n| `FileInputValidators.maxSize` | Sets the maximum allowed file size in bytes.  |\n\n## File Previews\n\nIn case you want to give a consistent user feedback about the selected\nfiles, we recommend to use the [Material Chips](https://material.angular.io/components/chips/overview).\n\n⚠️ Please note that no other file preview will be provided by this lib,\nbecause people are way too opinionated about their styling and behaviour.\n\n```html\n\u003cmat-form-field appearance=\"fill\"\u003e\n  \u003cmat-label\u003eDrop anything!\u003c/mat-label\u003e\n  \u003cngx-mat-dropzone\u003e\n    \u003cinput type=\"file\" fileInput [formControl]=\"fileCtrl\" /\u003e\n    @if (fileCtrl.value) {\n    \u003cmat-chip-row (removed)=\"clear()\"\u003e\n      {{ fileCtrl.value.name }}\n      \u003cbutton matChipRemove\u003e\n        \u003cmat-icon\u003ecancel\u003c/mat-icon\u003e\n      \u003c/button\u003e\n    \u003c/mat-chip-row\u003e\n    }\n  \u003c/ngx-mat-dropzone\u003e\n  \u003cmat-icon matSuffix color=\"primary\"\u003ecloud_upload\u003c/mat-icon\u003e\n\u003c/mat-form-field\u003e\n```\n\n```ts\nexport class AppComponent {\n  fileCtrl = new FormControl();\n\n  clear() {\n    this.fileCtrl.setValue(null);\n  }\n}\n```\n\n## Configuration\n\nNow that we have seen the minimal setup, here are some configuration options for the component markup.\n\n### FileInput directive\n\n| Property   | Description                                                                                      | Options                                                                                 |\n| ---------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |\n| `accept`   | Defines the accepted file types.                                                                 | See [here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) |\n| `mode`     | On select, either replace (default) or append the new files. Works only with multiple attribute. | `replace` or `append`                                                                   |\n| `multiple` | Allow multiple files to be selected.                                                             | `Boolean`                                                                               |\n| `disabled` | Disables any interaction.                                                                        | `Boolean`                                                                               |\n\n### Material dropzone\n\n| Property      | Description                                                      |\n| ------------- | ---------------------------------------------------------------- |\n| `required`    | Sets the native required property.                               |\n| `placeholder` | The placeholder text has no effect, use `\u003cmat-label /\u003e` instead. |\n\n## Development server\n\nRun `npm run start:[cdk|material]` to build and watch for changes on the\nlibrary packages.\n\nRun `npm run start:app` for an example app dev server to test changes locally. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.\n\nOther available commands are `npm run [build|test|lint]:[cdk|material]`.\n\n## Extensibility\n\nThis library provides a ready-to-use Material Design implementation for the dropzone.\nHowever, you might want to apply your own custom styling (or library).\n\n**Note:** For most use cases, you can use `DropzoneComponent` directly with your own CSS as shown in the \"Using CDK Only\" section above. Only extend `DropzoneComponent` if you need to add custom behavior or encapsulate complex styling in a reusable component.\n\nIf you want to create your own dropzone component, you can extend the `DropzoneComponent` from the CDK. See the [Material dropzone](/projects/material/src/lib/mat-dropzone/mat-dropzone.component.ts) as an example.\n\nThe basic setup requires you to create a standalone component that extends `DropzoneComponent` and import the required directives.\nUse the following skeleton as a starting point. You may always have a look at the\nMaterial reference implementation linked above.\n\n```ts\nimport { Component } from \"@angular/core\";\nimport { AcceptService, DropzoneComponent, DropzoneService, FileInputDirective } from \"@ngx-dropzone/cdk\";\n\n@Component({\n  selector: \"my-dropzone\",\n  imports: [FileInputDirective, DropzoneComponent],\n  providers: [DropzoneService, AcceptService],\n  template: `\n    \u003cdiv class=\"my-dropzone\"\u003e\n      \u003cng-content select=\"[fileInput]\"\u003e\u003c/ng-content\u003e\n    \u003c/div\u003e\n  `,\n  styles: [\n    `\n      .my-dropzone {\n        cursor: pointer;\n        text-align: center;\n        padding: 40px;\n        background: platinum;\n        border: 1px solid black;\n      }\n\n      .dragover \u003e .my-dropzone {\n        border-width: 2px;\n      }\n    `,\n  ],\n})\nexport class MyDropzone extends DropzoneComponent {}\n```\n\n## Contributing\n\n### Code of Conduct\n\nPlease read our `Code of Conduct` to keep our community open and respectable. 💖\n\n### Want to Help?\n\nWant to report a bug, contribute some code, or improve the documentation? Excellent! Read up on our guidelines for contributing and then check out one of our issues labeled as `help wanted` or `good first issue`.\n\n### Security\n\nIf you believe you have found a security vulnerability, we encourage you to responsibly disclose this and not open a public issue. Security issues in this open source project can be safely reported via `hackingharold@mailbox.org`.\n\n### License\n\nThis project is MIT-licensed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackingharold%2Fngx-dropzone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhackingharold%2Fngx-dropzone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackingharold%2Fngx-dropzone/lists"}