{"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      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;CACT;AAED,SAAS,oBAAoB,OAA8D;AACzF,KAAI,CAAC,MACH,QAAO;AAGT,KAAI,iBAAiB,SACnB,QAAO;CAGT,MAAM,SAAS,IAAI,cAAc;AACjC,MAAK,MAAM,QAAQ,MACjB,QAAO,MAAM,IAAI,KAAK;AAGxB,QAAO,OAAO;;AAGhB,SAAS,YAAY,SAA+B;AAClD,KAAI,OAAO,aAAa,YACtB,QAAO;CAGT,MAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,OAAM,OAAO;AAEb,KAAI,QAAQ,OACV,OAAM,SAAS,QAAQ;AAGzB,KAAI,QAAQ,SACV,OAAM,WAAW,QAAQ;AAG3B,KAAI,QAAQ,QACV,OAAM,UAAU,QAAQ;AAG1B,KAAI,QAAQ,UACV,OAAM,kBAAkB,QAAQ;AAGlC,OAAM,MAAM,UAAU;AACtB,QAAO;;AAST,SAAgB,cAAc,QAA8B,EAAE,EAA4B;CACxF,MAAM,UAAgC;EAAE,GAAG;EAAgB,GAAG;EAAO;CACrE,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAsC,oBAAoB,QAAQ,aAAa,CAAC;CAC9F,MAAM,YAAA,GAAA,MAAA,QAA2C,KAAK;CAEtD,MAAM,gBAAA,GAAA,MAAA,cACH,UAAiB;EAChB,MAAM,SAAS,MAAM;AACrB,MAAI,QAAQ,OAAO;AACjB,YAAS,OAAO,MAAM;AACtB,WAAQ,WAAW,OAAO,MAAM;;IAGpC,CAAC,QAAQ,SAAS,CACnB;CAED,MAAM,uBAAA,GAAA,MAAA,mBAAwC;AAC5C,WAAS,SAAS,QAAQ;AAC1B,WAAS,UAAU,YAAY,QAAQ;AAEvC,MAAI,SAAS,SAAS;AACpB,YAAS,QAAQ,iBAAiB,UAAU,cAAc,EAAE,MAAM,MAAM,CAAC;AACzE,YAAS,KAAK,YAAY,SAAS,QAAQ;;IAE5C,CAAC,SAAS,aAAa,CAAC;AAE3B,+BAAA,0BAA0B;AACxB,uBAAqB;AACrB,eAAa,SAAS,SAAS,QAAQ;IACtC,EAAE,CAAC;CAEN,MAAM,SAAA,GAAA,MAAA,mBAA0B;AAC9B,WAAS,KAAK;AACd,UAAQ,WAAW,KAAK;IACvB,CAAC,QAAQ,SAAS,CAAC;AAWtB,QAAO;EAAE;EAAO,OAAA,GAAA,MAAA,mBATe;AAC7B,OAAI,QAAQ,YACV,QAAO;AAGT,wBAAqB;AACrB,YAAS,SAAS,OAAO;KACxB;GAAC,QAAQ;GAAa;GAAO;GAAoB,CAAC;EAE/B;EAAO"}