{"version":3,"file":"use-file-dialog.cjs","names":[],"sources":["../../src/use-file-dialog/use-file-dialog.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nexport interface UseFileDialogOptions {\n  /** Determines whether multiple files are allowed, `true` by default */\n  multiple?: boolean;\n\n  /** `accept` attribute of the file input, '*' by default */\n  accept?: string;\n\n  /** `capture` attribute of the file input */\n  capture?: string;\n\n  /** Determines whether the user can pick a directory instead of file, `false` by default */\n  directory?: boolean;\n\n  /** Determines whether the file input state should be reset when the file dialog is opened, `false` by default */\n  resetOnOpen?: boolean;\n\n  /** Initial selected files */\n  initialFiles?: FileList | File[];\n\n  /** Called when files are selected */\n  onChange?: (files: FileList | null) => void;\n\n  /** Called when file dialog is canceled */\n  onCancel?: () => void;\n}\n\nconst defaultOptions: UseFileDialogOptions = {\n  multiple: true,\n  accept: '*',\n};\n\nfunction getInitialFilesList(files: UseFileDialogOptions['initialFiles']): FileList | null {\n  if (!files) {\n    return null;\n  }\n\n  if (files instanceof FileList) {\n    return files;\n  }\n\n  const result = new DataTransfer();\n  for (const file of files) {\n    result.items.add(file);\n  }\n\n  return result.files;\n}\n\nfunction createInput(options: UseFileDialogOptions) {\n  if (typeof document === 'undefined') {\n    return null;\n  }\n\n  const input = document.createElement('input');\n  input.type = 'file';\n\n  if (options.accept) {\n    input.accept = options.accept;\n  }\n\n  if (options.multiple) {\n    input.multiple = options.multiple;\n  }\n\n  if (options.capture) {\n    input.capture = options.capture;\n  }\n\n  if (options.directory) {\n    input.webkitdirectory = options.directory;\n  }\n\n  input.style.display = 'none';\n  return input;\n}\n\nexport interface UseFileDialogReturnValue {\n  files: FileList | null;\n  open: () => void;\n  reset: () => void;\n}\n\nexport function useFileDialog(input: UseFileDialogOptions = {}): UseFileDialogReturnValue {\n  const options: UseFileDialogOptions = { ...defaultOptions, ...input };\n  const [files, setFiles] = useState<FileList | null>(getInitialFilesList(options.initialFiles));\n  const inputRef = useRef<HTMLInputElement | null>(null);\n\n  const handleChange = useCallback(\n    (event: Event) => {\n      const target = event.target as HTMLInputElement;\n      if (target?.files) {\n        setFiles(target.files);\n        options.onChange?.(target.files);\n      }\n    },\n    [options.onChange]\n  );\n\n  const createAndSetupInput = useCallback(() => {\n    inputRef.current?.remove();\n    inputRef.current = createInput(options);\n\n    if (inputRef.current) {\n      inputRef.current.addEventListener('change', handleChange, { once: true });\n      if (options.onCancel) {\n        inputRef.current.addEventListener('cancel', options.onCancel, { once: true });\n      }\n      document.body.appendChild(inputRef.current);\n    }\n  }, [options, handleChange]);\n\n  useIsomorphicEffect(() => {\n    createAndSetupInput();\n    return () => inputRef.current?.remove();\n  }, []);\n\n  const reset = useCallback(() => {\n    setFiles(null);\n    options.onChange?.(null);\n  }, [options.onChange]);\n\n  const open = useCallback(() => {\n    if (options.resetOnOpen) {\n      reset();\n    }\n\n    createAndSetupInput();\n    inputRef.current?.click();\n  }, [options.resetOnOpen, reset, createAndSetupInput]);\n\n  return { files, open, reset };\n}\n\nexport namespace useFileDialog {\n  export type Options = UseFileDialogOptions;\n  export type ReturnValue = UseFileDialogReturnValue;\n}\n"],"mappings":";;;;AA6BA,MAAM,iBAAuC;CAC3C,UAAU;CACV,QAAQ;AACV;AAEA,SAAS,oBAAoB,OAA8D;CACzF,IAAI,CAAC,OACH,OAAO;CAGT,IAAI,iBAAiB,UACnB,OAAO;CAGT,MAAM,SAAS,IAAI,aAAa;CAChC,KAAK,MAAM,QAAQ,OACjB,OAAO,MAAM,IAAI,IAAI;CAGvB,OAAO,OAAO;AAChB;AAEA,SAAS,YAAY,SAA+B;CAClD,IAAI,OAAO,aAAa,aACtB,OAAO;CAGT,MAAM,QAAQ,SAAS,cAAc,OAAO;CAC5C,MAAM,OAAO;CAEb,IAAI,QAAQ,QACV,MAAM,SAAS,QAAQ;CAGzB,IAAI,QAAQ,UACV,MAAM,WAAW,QAAQ;CAG3B,IAAI,QAAQ,SACV,MAAM,UAAU,QAAQ;CAG1B,IAAI,QAAQ,WACV,MAAM,kBAAkB,QAAQ;CAGlC,MAAM,MAAM,UAAU;CACtB,OAAO;AACT;AAQA,SAAgB,cAAc,QAA8B,CAAC,GAA6B;CACxF,MAAM,UAAgC;EAAE,GAAG;EAAgB,GAAG;CAAM;CACpE,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAsC,oBAAoB,QAAQ,YAAY,CAAC;CAC7F,MAAM,YAAA,GAAA,MAAA,QAA2C,IAAI;CAErD,MAAM,gBAAA,GAAA,MAAA,cACH,UAAiB;EAChB,MAAM,SAAS,MAAM;EACrB,IAAI,QAAQ,OAAO;GACjB,SAAS,OAAO,KAAK;GACrB,QAAQ,WAAW,OAAO,KAAK;EACjC;CACF,GACA,CAAC,QAAQ,QAAQ,CACnB;CAEA,MAAM,uBAAA,GAAA,MAAA,mBAAwC;EAC5C,SAAS,SAAS,OAAO;EACzB,SAAS,UAAU,YAAY,OAAO;EAEtC,IAAI,SAAS,SAAS;GACpB,SAAS,QAAQ,iBAAiB,UAAU,cAAc,EAAE,MAAM,KAAK,CAAC;GACxE,IAAI,QAAQ,UACV,SAAS,QAAQ,iBAAiB,UAAU,QAAQ,UAAU,EAAE,MAAM,KAAK,CAAC;GAE9E,SAAS,KAAK,YAAY,SAAS,OAAO;EAC5C;CACF,GAAG,CAAC,SAAS,YAAY,CAAC;CAE1B,8BAAA,0BAA0B;EACxB,oBAAoB;EACpB,aAAa,SAAS,SAAS,OAAO;CACxC,GAAG,CAAC,CAAC;CAEL,MAAM,SAAA,GAAA,MAAA,mBAA0B;EAC9B,SAAS,IAAI;EACb,QAAQ,WAAW,IAAI;CACzB,GAAG,CAAC,QAAQ,QAAQ,CAAC;CAWrB,OAAO;EAAE;EAAO,OAAA,GAAA,MAAA,mBATe;GAC7B,IAAI,QAAQ,aACV,MAAM;GAGR,oBAAoB;GACpB,SAAS,SAAS,MAAM;EAC1B,GAAG;GAAC,QAAQ;GAAa;GAAO;EAAmB,CAEhC;EAAG;CAAM;AAC9B"}