{"id":13808434,"url":"https://github.com/hackingharold/ngx-dropzone","last_synced_at":"2025-05-14T02:31:53.667Z","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":"2025-05-14T02:31:53.651Z","avatar_url":"https://github.com/hackingharold.png","language":"TypeScript","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) 19 will be compatible with `@ngx-dropzone/cdk@19.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## Basic usage\n\nThis describes how to use the Material dropzone.\nIf you want to extend the CDK with your own styling, see 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\nIn this case, you're able to build upon the dropzone 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 extend the `DropzoneComponent` in your app to apply your own styling and functionality.\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","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Drag and Drop"],"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"}