[
  {
    "path": ".gitignore",
    "content": "node_modules\r\ndist\r\nstorybook-static\r\npackage-lock.json\r\n.DS_Store\r\n.svelte-kit\r\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n\t\"useTabs\": false,\n\t\"singleQuote\": false,\n\t\"trailingComma\": \"none\",\n\t\"printWidth\": 100,\n\t\"plugins\": [\"prettier-plugin-svelte\"],\n\t\"overrides\": [{ \"files\": \"*.svelte\", \"options\": { \"parser\": \"svelte\" } }],\n\t\"arrowParens\": \"avoid\"\n}\n\n"
  },
  {
    "path": ".storybook/main.js",
    "content": "export default {\n  stories: [\"../stories/**/*.stories.js\"],\n  addons: [\"@storybook/addon-links\", \"@storybook/addon-essentials\", \"@storybook/addon-interactions\"],\n  framework: {\n    name: \"@storybook/sveltekit\",\n    options: {},\n  },\n  docs: {\n    autodocs: true,\n  },\n};\n"
  },
  {
    "path": ".storybook/preview-head.html",
    "content": "<script>\n  window.global = window;\n</script>\n"
  },
  {
    "path": "README.md",
    "content": "# svelte-file-dropzone\r\n\r\n[![NPM](https://img.shields.io/npm/v/svelte-file-dropzone.svg)](https://www.npmjs.com/package/svelte-file-dropzone)\r\n[![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/svelte-file-dropzone.svg)](https://www.npmjs.com/package/svelte-file-dropzone)\r\n\r\nSvelteJS component for file upload and dropzone.The component is Svelte implementation of [react-dropzone](https://github.com/react-dropzone/react-dropzone).\r\n\r\n## Demo\r\n\r\n[Click here for Storybook link](https://svelte-file-dropzone.netlify.app/?path=/info/examples--basic-dropzone)\r\n\r\n## Installation\r\n\r\n```\r\nnpm install svelte-file-dropzone\r\n\r\nor\r\n\r\nyarn add svelte-file-dropzone\r\n```\r\n\r\n## Usage\r\n\r\n```svelte\r\n<script>\r\n  import Dropzone from \"svelte-file-dropzone\";\r\n\r\n  let files = {\r\n    accepted: [],\r\n    rejected: []\r\n  };\r\n\r\n  function handleFilesSelect(e) {\r\n    const { acceptedFiles, fileRejections } = e.detail;\r\n    files.accepted = [...files.accepted, ...acceptedFiles];\r\n    files.rejected = [...files.rejected, ...fileRejections];\r\n  }\r\n</script>\r\n\r\n<Dropzone on:drop={handleFilesSelect} />\r\n<ol>\r\n  {#each files.accepted as item}\r\n    <li>{item.name}</li>\r\n  {/each}\r\n</ol>\r\n```\r\n\r\n## API\r\n\r\n### Props\r\n\r\n| Prop Name             | Description                                                                              | Default Value |\r\n| --------------------- | ---------------------------------------------------------------------------------------- | ------------- |\r\n| accept                | Set accepted file types. See https://github.com/okonet/attr-accept for more information. | undefined     |\r\n| disabled              |                                                                                          | false         |\r\n| maxSize               |                                                                                          | Infinity      |\r\n| minSize               |                                                                                          | 0             |\r\n| multiple              | if true, multiple files can be selected at once                                          | true          |\r\n| preventDropOnDocument | 1231                                                                                     | true          |\r\n| noClick               | disable click events                                                                     | false         |\r\n| noKeyboard            | disable keyboard events                                                                  | false         |\r\n| noDrag                | disable drag events                                                                      | false         |\r\n| containerClasses      | custom container classes                                                                 | \"\"            |\r\n| containerStyles       | custom inline container styles                                                           | \"\"            |\r\n| disableDefaultStyles  | don't apply default styles to container                                                  | false         |\r\n| inputElement          | reference to inputElement                                                                | undefined     |\r\n| required              | html5 required attribute added to input                                                  | false         |\r\n\r\n### Events\r\n\r\n| Event Name       | Description | `event.detail` info                    |\r\n| ---------------- | ----------- | -------------------------------------- |\r\n| dragenter        |             | `{dragEvent: event}`                   |\r\n| dragover         |             | `{dragEvent: event}`                   |\r\n| dragleave        |             | `{dragEvent: event}`                   |\r\n| drop             |             | `{acceptedFiles,fileRejections,event}` |\r\n| filedropped      |             | `{event}`                              |\r\n| droprejected     |             | `{fileRejections,event}`               |\r\n| dropaccepted     |             | `{acceptedFiles,event}`                |\r\n| filedialogcancel |             |                                        |\r\n\r\n### Examples\r\n\r\n[Click here](https://github.com/thecodejack/svelte-file-dropzone/tree/master/stories/views) to view stories implementation\r\n\r\n## Credits\r\n\r\nComponent is reimplementation [react-dropzone](https://github.com/react-dropzone/react-dropzone). Complete credit goes to author and contributors of [react-dropzone](https://github.com/react-dropzone/react-dropzone).\r\n\r\n## License\r\n\r\nMIT\r\n"
  },
  {
    "path": "TODO",
    "content": "\nTodo:\n  ✔ Git repo @done(20-06-17 21:58)\n  ✔ npm initial publish @done(20-06-18 22:34)\n  ✔ setup netlify @done(20-06-17 22:55)\n  ✔ Fix README.md @done(20-06-17 22:28)\n  ✔ Add README.md to Notes of storybook @done(20-06-18 22:34)\n  ✔ Build setup @done(20-06-17 22:33)\n  ☐ Advanced Examples\n    ☐ Custom Dropzone with delete file etc\n    ✔ CustomDropzone with different drop behaviour @done(20-06-18 22:34)\n    \n"
  },
  {
    "path": "demo/.gitignore",
    "content": ".DS_Store\nnode_modules\n/build\n/.svelte-kit\n/package\n.env\n.env.*\n!.env.example\nvite.config.js.timestamp-*\nvite.config.ts.timestamp-*\n"
  },
  {
    "path": "demo/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "demo/.prettierignore",
    "content": "# Ignore files for PNPM, NPM and YARN\npnpm-lock.yaml\npackage-lock.json\nyarn.lock\n"
  },
  {
    "path": "demo/.prettierrc",
    "content": "{\n\t\"useTabs\": true,\n\t\"singleQuote\": true,\n\t\"trailingComma\": \"none\",\n\t\"printWidth\": 100,\n\t\"plugins\": [\"prettier-plugin-svelte\"],\n\t\"overrides\": [{ \"files\": \"*.svelte\", \"options\": { \"parser\": \"svelte\" } }]\n}\n"
  },
  {
    "path": "demo/README.md",
    "content": "# create-svelte\n\nEverything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).\n\n## Creating a project\n\nIf you're seeing this, you've probably already done this step. Congrats!\n\n```bash\n# create a new project in the current directory\nnpm create svelte@latest\n\n# create a new project in my-app\nnpm create svelte@latest my-app\n```\n\n## Developing\n\nOnce you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:\n\n```bash\nnpm run dev\n\n# or start the server and open the app in a new browser tab\nnpm run dev -- --open\n```\n\n## Building\n\nTo create a production version of your app:\n\n```bash\nnpm run build\n```\n\nYou can preview the production build with `npm run preview`.\n\n> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.\n"
  },
  {
    "path": "demo/package.json",
    "content": "{\n\t\"name\": \"demo\",\n\t\"version\": \"0.0.1\",\n\t\"private\": true,\n\t\"scripts\": {\n\t\t\"dev\": \"vite dev\",\n\t\t\"build\": \"vite build\",\n\t\t\"preview\": \"vite preview\",\n\t\t\"check\": \"svelte-kit sync && svelte-check --tsconfig ./tsconfig.json\",\n\t\t\"check:watch\": \"svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch\",\n\t\t\"test\": \"vitest\",\n\t\t\"lint\": \"prettier --check .\",\n\t\t\"format\": \"prettier --write .\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@sveltejs/adapter-auto\": \"^3.0.0\",\n\t\t\"@sveltejs/kit\": \"^2.5.5\",\n\t\t\"@sveltejs/vite-plugin-svelte\": \"^3.0.0\",\n\t\t\"prettier\": \"^3.1.1\",\n\t\t\"prettier-plugin-svelte\": \"^3.1.2\",\n\t\t\"svelte\": \"^4.2.12\",\n\t\t\"svelte-check\": \"^3.6.0\",\n\t\t\"tslib\": \"^2.4.1\",\n\t\t\"typescript\": \"^5.0.0\",\n\t\t\"vite\": \"^5.0.3\",\n\t\t\"vitest\": \"^1.0.0\"\n\t},\n\t\"type\": \"module\"\n}\n"
  },
  {
    "path": "demo/src/app.d.ts",
    "content": "// See https://kit.svelte.dev/docs/types#app\n// for information about these interfaces\ndeclare global {\n\tnamespace App {\n\t\t// interface Error {}\n\t\t// interface Locals {}\n\t\t// interface PageData {}\n\t\t// interface PageState {}\n\t\t// interface Platform {}\n\t}\n}\n\nexport {};\n"
  },
  {
    "path": "demo/src/app.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" href=\"%sveltekit.assets%/favicon.png\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t\t%sveltekit.head%\n\t</head>\n\t<body data-sveltekit-preload-data=\"hover\">\n\t\t<div style=\"display: contents\">%sveltekit.body%</div>\n\t</body>\n</html>\n"
  },
  {
    "path": "demo/src/index.test.ts",
    "content": "import { describe, it, expect } from 'vitest';\n\ndescribe('sum test', () => {\n\tit('adds 1 + 2 to equal 3', () => {\n\t\texpect(1 + 2).toBe(3);\n\t});\n});\n"
  },
  {
    "path": "demo/src/lib/index.ts",
    "content": "// place files you want to import through the `$lib` alias in this folder.\n"
  },
  {
    "path": "demo/src/routes/basic/+page.svelte",
    "content": "<script lang=\"ts\">\n\timport Dropzone from '../../../../src/lib/components/Dropzone.svelte';\n\n\tlet files = {\n\t\taccepted: [] as any[],\n\t\trejected: [] as any[]\n\t};\n\n\tfunction handleFilesSelect(e: any) {\n\t\tconst { acceptedFiles, fileRejections } = e.detail;\n\t\tfiles.accepted = [...files.accepted, ...acceptedFiles];\n\t\tfiles.rejected = [...files.rejected, ...fileRejections];\n\t}\n</script>\n\n<section>\n\t<Dropzone on:drop={handleFilesSelect} />\n\n\t<ol>\n\t\t{#each files.accepted as item}\n\t\t\t<li>{item.name}</li>\n\t\t{/each}\n\t</ol>\n</section>\n\n<style>\n\tsection {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tflex: 1;\n\t}\n</style>\n"
  },
  {
    "path": "demo/src/routes/custom-props/+page.svelte",
    "content": "<script lang=\"ts\">\n\timport Dropzone from '../../../../src/lib/components/Dropzone.svelte';\n\n\tlet files = {\n\t\taccepted: [] as any[],\n\t\trejected: [] as any[]\n\t};\n\n\tfunction handleFilesSelect(e: any) {\n\t\tconst { acceptedFiles, fileRejections } = e.detail;\n\t\tfiles.accepted = [...files.accepted, ...acceptedFiles];\n\t\tfiles.rejected = [...files.rejected, ...fileRejections];\n\t}\n\n\tfunction clickToUpload() {\n\t\tdocument.getElementById('xyz')!.click();\n\t}\n</script>\n\n<section>\n\t<button on:click={clickToUpload}>Click to upload</button>\n\t<Dropzone on:drop={handleFilesSelect} id=\"xyz\" />\n\n\t<ol>\n\t\t{#each files.accepted as item}\n\t\t\t<li>{item.name}</li>\n\t\t{/each}\n\t</ol>\n</section>\n\n<style>\n\tsection {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tflex: 1;\n\t}\n</style>\n"
  },
  {
    "path": "demo/src/routes/form/+page.server.ts",
    "content": "export const actions = {\n\tasync postFiles({ request }) {\n\t\tconst formData: FormData = await request.formData();\n\t\tconst files = formData.getAll('files');\n\n\t\treturn { files: files.map((f) => (f as any).name) };\n\t}\n};\n"
  },
  {
    "path": "demo/src/routes/form/+page.svelte",
    "content": "<script lang=\"ts\">\n\timport { enhance } from '$app/forms';\n\timport { page } from '$app/stores';\n\timport Dropzone from '../../../../src/lib/components/Dropzone.svelte';\n\n\tlet files: { name: string }[] = [];\n\n\tfunction handleFilesSelect(e: any) {\n\t\tconst { acceptedFiles } = e.detail;\n\t\tfiles = [...acceptedFiles];\n\t}\n</script>\n\n<form method=\"POST\" action=\"?/postFiles\" use:enhance enctype=\"multipart/form-data\">\n\t<Dropzone on:drop={handleFilesSelect} name=\"files\" />\n\n\t<button>Go</button>\n</form>\n\nFiles about to upload:\n<ul>\n\t{#each files as file}\n\t\t<li>{file.name}</li>\n\t{/each}\n</ul>\n\n<hr />\n\nFiles posted to form action:\n<ul>\n\t{#each $page.form?.files ?? [] as file}\n\t\t<li>{file}</li>\n\t{/each}\n</ul>\n"
  },
  {
    "path": "demo/src/routes/reactive-disabled/+page.svelte",
    "content": "<script lang=\"ts\">\n\timport Dropzone from '../../../../src/lib/components/Dropzone.svelte';\n\n\tlet files = {\n\t\taccepted: [] as any[],\n\t\trejected: [] as any[]\n\t};\n\n\tfunction handleFilesSelect(e: any) {\n\t\tconst { acceptedFiles, fileRejections } = e.detail;\n\t\tfiles.accepted = [...files.accepted, ...acceptedFiles];\n\t\tfiles.rejected = [...files.rejected, ...fileRejections];\n\t}\n\n\tlet disabled = false;\n\t$: dropAddedStyles = disabled\n\t\t? 'border-color: lightgray; cursor: not-allowed;'\n\t\t: 'border-color: blue';\n</script>\n\n<section>\n\t<label>Disable dropzone <input type=\"checkbox\" bind:checked={disabled} /></label>\n\t<Dropzone {disabled} on:drop={handleFilesSelect} containerStyles={dropAddedStyles} />\n\n\t<ol>\n\t\t{#each files.accepted as item}\n\t\t\t<li>{item.name}</li>\n\t\t{/each}\n\t</ol>\n</section>\n\n<style>\n\tsection {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tflex: 1;\n\t}\n</style>\n"
  },
  {
    "path": "demo/src/routes/toggle-multiple/+page.svelte",
    "content": "<script lang=\"ts\">\n\timport Dropzone from '../../../../src/lib/components/Dropzone.svelte';\n\n\tlet files = {\n\t\taccepted: [] as any[],\n\t\trejected: [] as any[]\n\t};\n\n\tfunction handleFilesSelect(e: any) {\n\t\tconst { acceptedFiles, fileRejections } = e.detail;\n\t\tfiles.accepted = [...files.accepted, ...acceptedFiles];\n\t\tfiles.rejected = [...files.rejected, ...fileRejections];\n\t}\n\n\tlet multiple = false;\n</script>\n\n<section>\n\t<label>Multiple <input type=\"checkbox\" bind:checked={multiple} /></label>\n\t<Dropzone on:drop={handleFilesSelect} {multiple} />\n\n\t<ol>\n\t\t{#each files.accepted as item}\n\t\t\t<li>{item.name}</li>\n\t\t{/each}\n\t</ol>\n</section>\n\n<style>\n\tsection {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tflex: 1;\n\t}\n</style>\n"
  },
  {
    "path": "demo/svelte.config.js",
    "content": "import adapter from '@sveltejs/adapter-auto';\nimport { vitePreprocess } from '@sveltejs/vite-plugin-svelte';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\t// Consult https://kit.svelte.dev/docs/integrations#preprocessors\n\t// for more information about preprocessors\n\tpreprocess: vitePreprocess(),\n\n\tkit: {\n\t\t// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.\n\t\t// If your environment is not supported or you settled on a specific environment, switch out the adapter.\n\t\t// See https://kit.svelte.dev/docs/adapters for more information about adapters.\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;\n"
  },
  {
    "path": "demo/tsconfig.json",
    "content": "{\n\t\"extends\": \"./.svelte-kit/tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"allowJs\": true,\n\t\t\"checkJs\": true,\n\t\t\"esModuleInterop\": true,\n\t\t\"forceConsistentCasingInFileNames\": true,\n\t\t\"resolveJsonModule\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"sourceMap\": true,\n\t\t\"strict\": true,\n\t\t\"moduleResolution\": \"bundler\"\n\t}\n\t// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias\n\t//\n\t// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes\n\t// from the referenced tsconfig.json - TypeScript does not merge them in\n}\n"
  },
  {
    "path": "demo/vite.config.ts",
    "content": "import { sveltekit } from '@sveltejs/kit/vite';\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n\tplugins: [sveltekit()],\n\ttest: {\n\t\tinclude: ['src/**/*.{test,spec}.{js,ts}']\n\t}\n});\n"
  },
  {
    "path": "jsconfig.json",
    "content": "{}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"svelte-file-dropzone\",\n  \"version\": \"2.0.9\",\n  \"description\": \"Svelte component for fileupload and file dropzone\",\n  \"scripts\": {\n    \"package\": \"svelte-kit sync && svelte-package && publint\",\n    \"prepublishOnly\": \"npm run package\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"storybook\": \"storybook dev -p 6006\",\n    \"build-storybook\": \"storybook build\"\n  },\n  \"exports\": {\n    \".\": {\n      \"types\": \"./dist/index.d.ts\",\n      \"svelte\": \"./dist/index.js\"\n    }\n  },\n  \"typesVersions\": {\n    \">4.0\": {\n      \"Dropzone.svelte\": [\n        \"./dist/components/Dropzone.svelte.d.ts\"\n      ]\n    }\n  },\n  \"repository\": {\n    \"url\": \"https://github.com/thecodejack/svelte-file-dropzone\"\n  },\n  \"author\": \"thecodejack\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"file-selector\": \"^0.6.0\"\n  },\n  \"peerDependencies\": {\n    \"svelte\": \"^3.54.0 || ^4.0.0 || ^5\"\n  },\n  \"devDependencies\": {\n    \"@storybook/addon-essentials\": \"^7.6.6\",\n    \"@storybook/addon-interactions\": \"^7.6.6\",\n    \"@storybook/addon-links\": \"^7.6.6\",\n    \"@storybook/addons\": \"7.6.6\",\n    \"@storybook/svelte\": \"7.6.6\",\n    \"@storybook/sveltekit\": \"^7.6.6\",\n    \"@sveltejs/kit\": \"^1.30.4\",\n    \"@sveltejs/package\": \"^2.2.5\",\n    \"babel-loader\": \"9.1.3\",\n    \"publint\": \"^0.2.7\",\n    \"storybook\": \"^7.6.6\",\n    \"svelte\": \"^4.2.12\",\n    \"vite\": \"^4.5.1\"\n  },\n  \"keywords\": [\n    \"svelte\",\n    \"svelte3\",\n    \"svelte-components\",\n    \"upload\",\n    \"dropzone\",\n    \"svelte-file-dropzone\",\n    \"svelte-dropzone\",\n    \"sveltejs\"\n  ],\n  \"files\": [\n    \"src\",\n    \"dist\",\n    \"!dist/**/*.test.*\",\n    \"!dist/**/*.spec.*\"\n  ],\n  \"svelte\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"type\": \"module\"\n}\n"
  },
  {
    "path": "renovate.json",
    "content": "{\n  \"extends\": [\n    \"config:base\"\n  ]\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import svelte from \"rollup-plugin-svelte\";\nimport resolve from \"@rollup/plugin-node-resolve\";\nimport commonjs from \"@rollup/plugin-commonjs\";\nimport pkg from \"./package.json\";\n\nconst name = pkg.name\n  .replace(/^(@\\S+\\/)?(svelte-)?(\\S+)/, \"$3\")\n  .replace(/^\\w/, (m) => m.toUpperCase())\n  .replace(/-\\w/g, (m) => m[1].toUpperCase());\n\nexport default {\n  input: \"src/index.svelte\",\n  output: [\n    { file: pkg.module, format: \"es\" },\n    { file: pkg.main, format: \"umd\", name },\n  ],\n  plugins: [svelte(), resolve(), commonjs()],\n};\n"
  },
  {
    "path": "src/lib/components/Dropzone.svelte",
    "content": "<script>\r\n  import { fromEvent } from \"file-selector\";\r\n  import {\r\n    fileAccepted,\r\n    fileMatchSize,\r\n    isEvtWithFiles,\r\n    isIeOrEdge,\r\n    isPropagationStopped,\r\n    TOO_MANY_FILES_REJECTION\r\n  } from \"../utils/index\";\r\n  import { onMount, onDestroy, createEventDispatcher } from \"svelte\";\r\n\r\n  //props\r\n  /**\r\n   * Set accepted file types.\r\n   * See https://github.com/okonet/attr-accept for more information.\r\n   */\r\n  /**\r\n   * @type {string | Array<string>}\r\n   */\r\n  export let accept = undefined;\r\n  export let disabled = false;\r\n  export let getFilesFromEvent = fromEvent;\r\n  export let maxSize = Infinity;\r\n  export let minSize = 0;\r\n  export let multiple = true;\r\n  export let preventDropOnDocument = true;\r\n  export let noClick = false;\r\n  export let noKeyboard = false;\r\n  export let noDrag = false;\r\n  export let noDragEventsBubbling = false;\r\n  export let containerClasses = \"\";\r\n  export let containerStyles = \"\";\r\n  export let disableDefaultStyles = false;\r\n  export let name = \"\";\r\n  export let inputElement = undefined;\r\n  export let required = false;\r\n  const dispatch = createEventDispatcher();\r\n\r\n  //state\r\n\r\n  let state = {\r\n    isFocused: false,\r\n    isFileDialogActive: false,\r\n    isDragActive: false,\r\n    isDragAccept: false,\r\n    isDragReject: false,\r\n    draggedFiles: [],\r\n    acceptedFiles: [],\r\n    fileRejections: []\r\n  };\r\n\r\n  let rootRef;\r\n\r\n  function resetState() {\r\n    state.isFileDialogActive = false;\r\n    state.isDragActive = false;\r\n    state.draggedFiles = [];\r\n    state.acceptedFiles = [];\r\n    state.fileRejections = [];\r\n  }\r\n\r\n  // Fn for opening the file dialog programmatically\r\n  function openFileDialog() {\r\n    if (inputElement) {\r\n      inputElement.value = null; // TODO check if null needs to be set\r\n      state.isFileDialogActive = true;\r\n      inputElement.click();\r\n    }\r\n  }\r\n\r\n  // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\r\n  function onKeyDownCb(event) {\r\n    // Ignore keyboard events bubbling up the DOM tree\r\n    if (!rootRef || !rootRef.isEqualNode(event.target)) {\r\n      return;\r\n    }\r\n\r\n    if (event.keyCode === 32 || event.keyCode === 13) {\r\n      event.preventDefault();\r\n      openFileDialog();\r\n    }\r\n  }\r\n\r\n  // Update focus state for the dropzone\r\n  function onFocusCb() {\r\n    state.isFocused = true;\r\n  }\r\n  function onBlurCb() {\r\n    state.isFocused = false;\r\n  }\r\n\r\n  // Cb to open the file dialog when click occurs on the dropzone\r\n  function onClickCb() {\r\n    if (noClick) {\r\n      return;\r\n    }\r\n\r\n    // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\r\n    // to ensure React can handle state changes\r\n    // See: https://github.com/react-dropzone/react-dropzone/issues/450\r\n    if (isIeOrEdge()) {\r\n      setTimeout(openFileDialog, 0);\r\n    } else {\r\n      openFileDialog();\r\n    }\r\n  }\r\n\r\n  function onDragEnterCb(event) {\r\n    event.preventDefault();\r\n    stopPropagation(event);\r\n\r\n    dragTargetsRef = [...dragTargetsRef, event.target];\r\n\r\n    if (isEvtWithFiles(event)) {\r\n      Promise.resolve(getFilesFromEvent(event)).then(draggedFiles => {\r\n        if (isPropagationStopped(event) && !noDragEventsBubbling) {\r\n          return;\r\n        }\r\n\r\n        state.draggedFiles = draggedFiles;\r\n        state.isDragActive = true;\r\n\r\n        dispatch(\"dragenter\", {\r\n          dragEvent: event\r\n        });\r\n      });\r\n    }\r\n  }\r\n\r\n  function onDragOverCb(event) {\r\n    event.preventDefault();\r\n    stopPropagation(event);\r\n\r\n    if (event.dataTransfer) {\r\n      try {\r\n        event.dataTransfer.dropEffect = \"copy\";\r\n      } catch {} /* eslint-disable-line no-empty */\r\n    }\r\n\r\n    if (isEvtWithFiles(event)) {\r\n      dispatch(\"dragover\", {\r\n        dragEvent: event\r\n      });\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  function onDragLeaveCb(event) {\r\n    event.preventDefault();\r\n    stopPropagation(event);\r\n\r\n    // Only deactivate once the dropzone and all children have been left\r\n    const targets = dragTargetsRef.filter(target => rootRef && rootRef.contains(target));\r\n    // Make sure to remove a target present multiple times only once\r\n    // (Firefox may fire dragenter/dragleave multiple times on the same element)\r\n    const targetIdx = targets.indexOf(event.target);\r\n    if (targetIdx !== -1) {\r\n      targets.splice(targetIdx, 1);\r\n    }\r\n    dragTargetsRef = targets;\r\n    if (targets.length > 0) {\r\n      return;\r\n    }\r\n\r\n    state.isDragActive = false;\r\n    state.draggedFiles = [];\r\n\r\n    if (isEvtWithFiles(event)) {\r\n      dispatch(\"dragleave\", {\r\n        dragEvent: event\r\n      });\r\n    }\r\n  }\r\n\r\n  function onDropCb(event) {\r\n    event.preventDefault();\r\n    stopPropagation(event);\r\n\r\n    dragTargetsRef = [];\r\n\r\n    if (isEvtWithFiles(event)) {\r\n      dispatch(\"filedropped\", {\r\n        event\r\n      });\r\n      Promise.resolve(getFilesFromEvent(event)).then(files => {\r\n        if (isPropagationStopped(event) && !noDragEventsBubbling) {\r\n          return;\r\n        }\r\n\r\n        const acceptedFiles = [];\r\n        const fileRejections = [];\r\n\r\n        files.forEach(file => {\r\n          const [accepted, acceptError] = fileAccepted(file, accept);\r\n          const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);\r\n          if (accepted && sizeMatch) {\r\n            acceptedFiles.push(file);\r\n          } else {\r\n            const errors = [acceptError, sizeError].filter(e => e);\r\n            fileRejections.push({ file, errors });\r\n          }\r\n        });\r\n\r\n        if (!multiple && acceptedFiles.length > 1) {\r\n          // Reject everything and empty accepted files\r\n          acceptedFiles.forEach(file => {\r\n            fileRejections.push({ file, errors: [TOO_MANY_FILES_REJECTION] });\r\n          });\r\n          acceptedFiles.splice(0);\r\n        }\r\n\r\n        // Files dropped keep input in sync\r\n        if (event.dataTransfer) {\r\n          inputElement.files = event.dataTransfer.files;\r\n        }\r\n\r\n        state.acceptedFiles = acceptedFiles;\r\n        state.fileRejections = fileRejections;\r\n\r\n        dispatch(\"drop\", {\r\n          acceptedFiles,\r\n          fileRejections,\r\n          event\r\n        });\r\n\r\n        if (fileRejections.length > 0) {\r\n          dispatch(\"droprejected\", {\r\n            fileRejections,\r\n            event\r\n          });\r\n        }\r\n\r\n        if (acceptedFiles.length > 0) {\r\n          dispatch(\"dropaccepted\", {\r\n            acceptedFiles,\r\n            event\r\n          });\r\n        }\r\n      });\r\n    }\r\n    resetState();\r\n  }\r\n\r\n  $: composeHandler = fn => (disabled ? null : fn);\r\n\r\n  $: composeKeyboardHandler = fn => (noKeyboard ? null : composeHandler(fn));\r\n\r\n  $: composeDragHandler = fn => (noDrag ? null : composeHandler(fn));\r\n\r\n  $: defaultPlaceholderString = multiple\r\n    ? \"Drag 'n' drop some files here, or click to select files\"\r\n    : \"Drag 'n' drop a file here, or click to select a file\";\r\n\r\n  function stopPropagation(event) {\r\n    if (noDragEventsBubbling) {\r\n      event.stopPropagation();\r\n    }\r\n  }\r\n\r\n  // allow the entire document to be a drag target\r\n  function onDocumentDragOver(event) {\r\n    if (preventDropOnDocument) {\r\n      event.preventDefault();\r\n    }\r\n  }\r\n\r\n  let dragTargetsRef = [];\r\n  function onDocumentDrop(event) {\r\n    if (!preventDropOnDocument) {\r\n      return;\r\n    }\r\n    if (rootRef && rootRef.contains(event.target)) {\r\n      // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\r\n      return;\r\n    }\r\n    event.preventDefault();\r\n    dragTargetsRef = [];\r\n  }\r\n\r\n  // Update file dialog active state when the window is focused on\r\n  function onWindowFocus() {\r\n    // Execute the timeout only if the file dialog is opened in the browser\r\n    if (state.isFileDialogActive) {\r\n      setTimeout(() => {\r\n        if (inputElement) {\r\n          const { files } = inputElement;\r\n\r\n          if (!files.length) {\r\n            state.isFileDialogActive = false;\r\n            dispatch(\"filedialogcancel\");\r\n          }\r\n        }\r\n      }, 300);\r\n    }\r\n  }\r\n\r\n  onDestroy(() => {\r\n    // This is critical for canceling the timeout behaviour on `onWindowFocus()`\r\n    inputElement = null;\r\n  });\r\n\r\n  function onInputElementClick(event) {\r\n    event.stopPropagation();\r\n  }\r\n</script>\r\n\r\n<svelte:window on:focus={onWindowFocus} on:dragover={onDocumentDragOver} on:drop={onDocumentDrop} />\r\n\r\n<div\r\n  bind:this={rootRef}\r\n  tabindex=\"0\"\r\n  role=\"button\"\r\n  class=\"{disableDefaultStyles ? '' : 'dropzone'}\r\n  {containerClasses}\"\r\n  style={containerStyles}\r\n  on:keydown={composeKeyboardHandler(onKeyDownCb)}\r\n  on:focus={composeKeyboardHandler(onFocusCb)}\r\n  on:blur={composeKeyboardHandler(onBlurCb)}\r\n  on:click={composeHandler(onClickCb)}\r\n  on:dragenter={composeDragHandler(onDragEnterCb)}\r\n  on:dragover={composeDragHandler(onDragOverCb)}\r\n  on:dragleave={composeDragHandler(onDragLeaveCb)}\r\n  on:drop={composeDragHandler(onDropCb)}\r\n  {...$$restProps}\r\n>\r\n  <input\r\n    accept={accept?.toString()}\r\n    {multiple}\r\n    {required}\r\n    type=\"file\"\r\n    {name}\r\n    autocomplete=\"off\"\r\n    tabindex=\"-1\"\r\n    on:change={onDropCb}\r\n    on:click={onInputElementClick}\r\n    bind:this={inputElement}\r\n    style=\"display: none;\"\r\n  />\r\n  <slot>\r\n    <p>{defaultPlaceholderString}</p>\r\n  </slot>\r\n</div>\r\n\r\n<style>\r\n  .dropzone {\r\n    flex: 1;\r\n    display: flex;\r\n    flex-direction: column;\r\n    align-items: center;\r\n    padding: 20px;\r\n    border-width: 2px;\r\n    border-radius: 2px;\r\n    border-color: #eeeeee;\r\n    border-style: dashed;\r\n    background-color: #fafafa;\r\n    color: #bdbdbd;\r\n    outline: none;\r\n    transition: border 0.24s ease-in-out;\r\n  }\r\n  .dropzone:focus {\r\n    border-color: #2196f3;\r\n  }\r\n</style>\r\n"
  },
  {
    "path": "src/lib/index.ts",
    "content": "import Dropzone from \"./components/Dropzone.svelte\";\n\nexport default Dropzone"
  },
  {
    "path": "src/lib/utils/attr-accept.js",
    "content": "/**\r\n * Check if the provided file type should be accepted by the input with accept attribute.\r\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#attr-accept\r\n *\r\n * Inspired by https://github.com/enyo/dropzone\r\n *\r\n * @param file {File} https://developer.mozilla.org/en-US/docs/Web/API/File\r\n * @param acceptedFiles {string}\r\n * @returns {boolean}\r\n */\r\n\r\nexport default function(file, acceptedFiles) {\r\n  if (file && acceptedFiles) {\r\n    const acceptedFilesArray = Array.isArray(acceptedFiles)\r\n      ? acceptedFiles\r\n      : acceptedFiles.split(\",\");\r\n    const fileName = file.name || \"\";\r\n    const mimeType = (file.type || \"\").toLowerCase();\r\n    const baseMimeType = mimeType.replace(/\\/.*$/, \"\");\r\n\r\n    return acceptedFilesArray.some((type) => {\r\n      const validType = type.trim().toLowerCase();\r\n      if (validType.charAt(0) === \".\") {\r\n        return fileName.toLowerCase().endsWith(validType);\r\n      } else if (validType.endsWith(\"/*\")) {\r\n        // This is something like a image/* mime type\r\n        return baseMimeType === validType.replace(/\\/.*$/, \"\");\r\n      }\r\n      return mimeType === validType;\r\n    });\r\n  }\r\n  return true;\r\n}\r\n"
  },
  {
    "path": "src/lib/utils/index.js",
    "content": "import accepts from \"./attr-accept\";\r\n\r\n// Error codes\r\nexport const FILE_INVALID_TYPE = \"file-invalid-type\";\r\nexport const FILE_TOO_LARGE = \"file-too-large\";\r\nexport const FILE_TOO_SMALL = \"file-too-small\";\r\nexport const TOO_MANY_FILES = \"too-many-files\";\r\n\r\n// File Errors\r\nexport const getInvalidTypeRejectionErr = (accept) => {\r\n  accept = Array.isArray(accept) && accept.length === 1 ? accept[0] : accept;\r\n  const messageSuffix = Array.isArray(accept)\r\n    ? `one of ${accept.join(\", \")}`\r\n    : accept;\r\n  return {\r\n    code: FILE_INVALID_TYPE,\r\n    message: `File type must be ${messageSuffix}`,\r\n  };\r\n};\r\n\r\nexport const getTooLargeRejectionErr = (maxSize) => {\r\n  return {\r\n    code: FILE_TOO_LARGE,\r\n    message: `File is larger than ${maxSize} bytes`,\r\n  };\r\n};\r\n\r\nexport const getTooSmallRejectionErr = (minSize) => {\r\n  return {\r\n    code: FILE_TOO_SMALL,\r\n    message: `File is smaller than ${minSize} bytes`,\r\n  };\r\n};\r\n\r\nexport const TOO_MANY_FILES_REJECTION = {\r\n  code: TOO_MANY_FILES,\r\n  message: \"Too many files\",\r\n};\r\n\r\n// Firefox versions prior to 53 return a bogus MIME type for every file drag, so dragovers with\r\n// that MIME type will always be accepted\r\nexport function fileAccepted(file, accept) {\r\n  const isAcceptable =\r\n    file.type === \"application/x-moz-file\" || accepts(file, accept);\r\n  return [\r\n    isAcceptable,\r\n    isAcceptable ? null : getInvalidTypeRejectionErr(accept),\r\n  ];\r\n}\r\n\r\nexport function fileMatchSize(file, minSize, maxSize) {\r\n  if (isDefined(file.size)) {\r\n    if (isDefined(minSize) && isDefined(maxSize)) {\r\n      if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];\r\n      if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];\r\n    } else if (isDefined(minSize) && file.size < minSize)\r\n      return [false, getTooSmallRejectionErr(minSize)];\r\n    else if (isDefined(maxSize) && file.size > maxSize)\r\n      return [false, getTooLargeRejectionErr(maxSize)];\r\n  }\r\n  return [true, null];\r\n}\r\n\r\nfunction isDefined(value) {\r\n  return value !== undefined && value !== null;\r\n}\r\n\r\nexport function allFilesAccepted({\r\n  files,\r\n  accept,\r\n  minSize,\r\n  maxSize,\r\n  multiple,\r\n}) {\r\n  if (!multiple && files.length > 1) {\r\n    return false;\r\n  }\r\n\r\n  return files.every((file) => {\r\n    const [accepted] = fileAccepted(file, accept);\r\n    const [sizeMatch] = fileMatchSize(file, minSize, maxSize);\r\n    return accepted && sizeMatch;\r\n  });\r\n}\r\n\r\n// React's synthetic events has event.isPropagationStopped,\r\n// but to remain compatibility with other libs (Preact) fall back\r\n// to check event.cancelBubble\r\nexport function isPropagationStopped(event) {\r\n  if (typeof event.isPropagationStopped === \"function\") {\r\n    return event.isPropagationStopped();\r\n  } else if (typeof event.cancelBubble !== \"undefined\") {\r\n    return event.cancelBubble;\r\n  }\r\n  return false;\r\n}\r\n\r\nexport function isEvtWithFiles(event) {\r\n  if (!event.dataTransfer) {\r\n    return !!event.target && !!event.target.files;\r\n  }\r\n  // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types\r\n  // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file\r\n  return Array.prototype.some.call(\r\n    event.dataTransfer.types,\r\n    (type) => type === \"Files\" || type === \"application/x-moz-file\"\r\n  );\r\n}\r\n\r\nexport function isKindFile(item) {\r\n  return typeof item === \"object\" && item !== null && item.kind === \"file\";\r\n}\r\n\r\nfunction isIe(userAgent) {\r\n  return (\r\n    userAgent.indexOf(\"MSIE\") !== -1 || userAgent.indexOf(\"Trident/\") !== -1\r\n  );\r\n}\r\n\r\nfunction isEdge(userAgent) {\r\n  return userAgent.indexOf(\"Edge/\") !== -1;\r\n}\r\n\r\nexport function isIeOrEdge(userAgent = window.navigator.userAgent) {\r\n  return isIe(userAgent) || isEdge(userAgent);\r\n}\r\n\r\n/**\r\n * This is intended to be used to compose event handlers\r\n * They are executed in order until one of them calls `event.isPropagationStopped()`.\r\n * Note that the check is done on the first invoke too,\r\n * meaning that if propagation was stopped before invoking the fns,\r\n * no handlers will be executed.\r\n *\r\n * @param {Function} fns the event hanlder functions\r\n * @return {Function} the event handler to add to an element\r\n */\r\nexport function composeEventHandlers(...fns) {\r\n  return (event, ...args) =>\r\n    fns.some((fn) => {\r\n      if (!isPropagationStopped(event) && fn) {\r\n        fn(event, ...args);\r\n      }\r\n      return isPropagationStopped(event);\r\n    });\r\n}\r\n"
  },
  {
    "path": "stories/1-dropzone.stories.js",
    "content": "//import { action } from \"@storybook/addon-actions\";\r\n\r\nimport BasicDropZoneView from \"./views/BasicDropzoneView.svelte\";\r\nimport BasicDropZoneViewSource from \"./views/BasicDropzoneView.svelte?raw\";\r\nimport DisabledDropzoneView from \"./views/DisabledDropzoneView.svelte\";\r\nimport DisabledDropzoneViewSource from \"./views/DisabledDropzoneView.svelte?raw\";\r\nimport CustomSlotDropzoneView from \"./views/CustomSlotDropzoneView.svelte\";\r\nimport CustomSlotDropzoneViewSource from \"./views/CustomSlotDropzoneView.svelte?raw\";\r\nimport NoClickDropZoneView from \"./views/NoClickDropzoneView.svelte\";\r\nimport NoClickDropZoneViewSource from \"./views/NoClickDropzoneView.svelte?raw\";\r\nimport NoDragDropzoneView from \"./views/NoDragDropzoneView.svelte\";\r\nimport NoDragDropzoneViewSource from \"./views/NoDragDropzoneView.svelte?raw\";\r\n\r\nimport { sourceParameters } from \"./helpers\";\r\n\r\nexport default {\r\n  title: \"Examples\",\r\n  component: null,\r\n};\r\n\r\nexport const BasicDropzone = {\r\n  ...sourceParameters(BasicDropZoneViewSource),\r\n  render: () => ({\r\n    Component: BasicDropZoneView,\r\n  }),\r\n};\r\n\r\nexport const DisabledDropzone = {\r\n  ...sourceParameters(DisabledDropzoneViewSource),\r\n  render: () => ({\r\n    Component: DisabledDropzoneView,\r\n  }),\r\n};\r\n\r\nexport const CustomSlotDropzone = {\r\n  ...sourceParameters(CustomSlotDropzoneViewSource),\r\n  render: () => ({\r\n    Component: CustomSlotDropzoneView,\r\n  }),\r\n};\r\n\r\nexport const DropZoneWithClickDisabled = {\r\n  ...sourceParameters(NoClickDropZoneViewSource),\r\n  render: () => ({\r\n    Component: NoClickDropZoneView,\r\n  }),\r\n};\r\n\r\nexport const DropZoneWithDragDisabled = {\r\n  ...sourceParameters(NoDragDropzoneViewSource),\r\n  render: () => ({\r\n    Component: NoDragDropzoneView,\r\n  }),\r\n};\r\n"
  },
  {
    "path": "stories/2-advanced-dropzone.stories.js",
    "content": "import { action } from \"@storybook/addon-actions\";\r\n\r\nimport WorkingCSVFileUploadView from \"./views/WorkingCSVFileUploadView.svelte\";\r\nimport WorkingCSVFileUploadViewSource from \"./views/WorkingCSVFileUploadView.svelte?raw\";\r\nimport FullyFeaturedDropzoneView from \"./views/FullyFeaturedDropzoneView.svelte\";\r\nimport FullyFeaturedDropzoneViewSource from \"./views/FullyFeaturedDropzoneView.svelte?raw\";\r\n\r\nimport { sourceParameters } from \"./helpers\";\r\n\r\nexport default {\r\n  title: \"Advanced Examples\",\r\n  component: null,\r\n};\r\n\r\nexport const WorkingCSVFileUploadDropzone = {\r\n  ...sourceParameters(WorkingCSVFileUploadViewSource),\r\n  render: () => ({\r\n    Component: WorkingCSVFileUploadView,\r\n  }),\r\n};\r\n\r\nexport const FullyFeaturedImagesDropzone = {\r\n  ...sourceParameters(FullyFeaturedDropzoneViewSource),\r\n  render: () => ({\r\n    Component: FullyFeaturedDropzoneView,\r\n  }),\r\n};\r\n"
  },
  {
    "path": "stories/helpers.js",
    "content": "export const sourceParameters = (source) => ({\n  parameters: {\n    docs: {\n      source: {\n        code: source,\n      },\n    },\n  },\n});\n"
  },
  {
    "path": "stories/views/BasicDropzoneAcceptImagesView.svelte",
    "content": "<script>\r\n  import Dropzone from \"../../src/lib/components/Dropzone.svelte\";\r\n\r\n  let files = {\r\n    accepted: [],\r\n    rejected: [],\r\n  };\r\n\r\n  function handleFilesSelect(e) {\r\n    const { acceptedFiles, fileRejections } = e.detail;\r\n    files.accepted = [...files.accepted, ...acceptedFiles];\r\n    files.rejected = [...files.rejected, ...fileRejections];\r\n  }\r\n</script>\r\n\r\n<Dropzone on:drop={handleFilesSelect} accept=\"image/*\" />\r\n<ol>\r\n  {#each files.accepted as item}\r\n    <li>{item.name}</li>\r\n  {/each}\r\n</ol>\r\n"
  },
  {
    "path": "stories/views/BasicDropzoneView.svelte",
    "content": "<script>\r\n  import Dropzone from \"../../src/lib/components/Dropzone.svelte\";\r\n\r\n  let files = {\r\n    accepted: [],\r\n    rejected: [],\r\n  };\r\n\r\n  function handleFilesSelect(e) {\r\n    const { acceptedFiles, fileRejections } = e.detail;\r\n    files.accepted = [...files.accepted, ...acceptedFiles];\r\n    files.rejected = [...files.rejected, ...fileRejections];\r\n  }\r\n</script>\r\n\r\n<Dropzone on:drop={handleFilesSelect} />\r\n<ol>\r\n  {#each files.accepted as item}\r\n    <li>{item.name}</li>\r\n  {/each}\r\n</ol>\r\n"
  },
  {
    "path": "stories/views/CustomSlotDropzoneView.svelte",
    "content": "<script>\r\n  import Dropzone from \"../../src/lib/components/Dropzone.svelte\";\r\n\r\n  let files = {\r\n    accepted: [],\r\n    rejected: [],\r\n  };\r\n\r\n  function handleFilesSelect(e) {\r\n    const { acceptedFiles, fileRejections } = e.detail;\r\n    files.accepted = [...files.accepted, ...acceptedFiles];\r\n    files.rejected = [...files.rejected, ...fileRejections];\r\n  }\r\n</script>\r\n\r\n<Dropzone on:drop={handleFilesSelect}>\r\n  <p>Custom Slot Dropzone</p>\r\n</Dropzone>\r\n<ol>\r\n  {#each files.accepted as item}\r\n    <li>{item.name}</li>\r\n  {/each}\r\n</ol>\r\n"
  },
  {
    "path": "stories/views/DisabledDropzoneView.svelte",
    "content": "<script>\r\n  import Dropzone from \"../../src/lib/components/Dropzone.svelte\";\r\n\r\n  let files = {\r\n    accepted: [],\r\n    rejected: [],\r\n  };\r\n\r\n  function handleFilesSelect(e) {\r\n    const { acceptedFiles, fileRejections } = e.detail;\r\n    files.accepted = [...files.accepted, ...acceptedFiles];\r\n    files.rejected = [...files.rejected, ...fileRejections];\r\n  }\r\n</script>\r\n\r\n<Dropzone on:drop={handleFilesSelect} disabled />\r\n<ol>\r\n  {#each files.accepted as item}\r\n    <li>{item.name}</li>\r\n  {/each}\r\n</ol>\r\n"
  },
  {
    "path": "stories/views/FullyFeaturedDropzoneView.svelte",
    "content": "<script>\r\n  import Dropzone from \"../../src/lib/components/Dropzone.svelte\";\r\n\r\n  let files = {\r\n    accepted: [],\r\n    rejected: [],\r\n  };\r\n\r\n  function handleFilesSelect(e) {\r\n    const { acceptedFiles, fileRejections } = e.detail;\r\n    files.accepted = [...files.accepted, ...acceptedFiles];\r\n    files.rejected = [...files.rejected, ...fileRejections];\r\n  }\r\n\r\n  function handleRemoveFile(e, index) {\r\n    files.accepted.splice(index, 1);\r\n    files.accepted = [...files.accepted];\r\n  }\r\n  function handleRemoveAll() {\r\n    files.accepted = [];\r\n  }\r\n</script>\r\n\r\n<Dropzone on:drop={handleFilesSelect} accept={[\"image/*\"]} containerClasses=\"custom-dropzone\">\r\n  <button>Choose images to upload</button>\r\n\r\n  <p>or</p>\r\n  <p>Drag and drop them here</p>\r\n</Dropzone>\r\n<div style=\"margin: 5px;\">\r\n  {#if files.accepted.length > 0}\r\n    <button on:click={handleRemoveAll}>RemoveAll</button>\r\n  {/if}\r\n  {#each files.accepted as item, index}\r\n    <div>\r\n      <span>{item.name}</span>\r\n      <button on:click={(e) => handleRemoveFile(e, index)}>Remove</button>\r\n    </div>\r\n  {/each}\r\n</div>\r\n\r\n<style>\r\n  :global(.custom-dropzone) {\r\n  }\r\n</style>\r\n"
  },
  {
    "path": "stories/views/NoClickDropzoneView.svelte",
    "content": "<script>\r\n  import Dropzone from \"../../src/lib/components/Dropzone.svelte\";\r\n\r\n  let files = {\r\n    accepted: [],\r\n    rejected: [],\r\n  };\r\n\r\n  function handleFilesSelect(e) {\r\n    const { acceptedFiles, fileRejections } = e.detail;\r\n    files.accepted = [...files.accepted, ...acceptedFiles];\r\n    files.rejected = [...files.rejected, ...fileRejections];\r\n  }\r\n</script>\r\n\r\n<Dropzone on:drop={handleFilesSelect} noClick />\r\n<ol>\r\n  {#each files.accepted as item}\r\n    <li>{item.name}</li>\r\n  {/each}\r\n</ol>\r\n"
  },
  {
    "path": "stories/views/NoDragDropzoneView.svelte",
    "content": "<script>\r\n  import Dropzone from \"../../src/lib/components/Dropzone.svelte\";\r\n\r\n  let files = {\r\n    accepted: [],\r\n    rejected: [],\r\n  };\r\n\r\n  function handleFilesSelect(e) {\r\n    const { acceptedFiles, fileRejections } = e.detail;\r\n    files.accepted = [...files.accepted, ...acceptedFiles];\r\n    files.rejected = [...files.rejected, ...fileRejections];\r\n  }\r\n</script>\r\n\r\n<Dropzone on:drop={handleFilesSelect} noDrag />\r\n<ol>\r\n  {#each files.accepted as item}\r\n    <li>{item.name}</li>\r\n  {/each}\r\n</ol>\r\n"
  },
  {
    "path": "stories/views/WorkingCSVFileUploadView.svelte",
    "content": "<script>\r\n  import Dropzone from \"../../src/lib/components/Dropzone.svelte\";\r\n\r\n  let files = [];\r\n  let fileData = [];\r\n\r\n  function processRawCSV(data) {\r\n    const output = [];\r\n    const rows = data.split(\"\\n\");\r\n    for (let i = 0; i < rows.length; i++) {\r\n      const cells = rows[i].split(\",\");\r\n      output.push(cells);\r\n    }\r\n    return output;\r\n  }\r\n\r\n  function handleFilesSelect(e) {\r\n    files = e.detail.acceptedFiles;\r\n\r\n    for (let i = 0; i < files.length; i++) {\r\n      const reader = new FileReader();\r\n      reader.onload = () => {\r\n        const binaryStr = reader.result;\r\n        fileData = processRawCSV(binaryStr);\r\n      };\r\n      console.log(reader.readAsText(files[i]));\r\n    }\r\n  }\r\n</script>\r\n\r\n<h1>Upload CSV file and preview same</h1>\r\n<Dropzone on:drop={handleFilesSelect} multiple={false} accept=\".csv\" />\r\n\r\n{#each files as item}\r\n  <h2>{item.name}</h2>\r\n{/each}\r\n\r\n<table border=\"1\">\r\n  {#each fileData as row}\r\n    <tr>\r\n      {#each row as item}\r\n        <td>{item}</td>\r\n      {/each}\r\n    </tr>\r\n  {/each}\r\n</table>\r\n"
  }
]