/** * Custom type for file input element (``). */ type InputFile = HTMLInputElement & { capture?: boolean | string; }; /** * Type of options for file input element (``) virtually * created to select files. */ export type Options = { /** * Defines accepted file types. It's a comma-separated list of file * extensions, mime-types or unique file type specifiers. * * https://developer.mozilla.org/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers * * @example ```js * "image/*,video/*,.pdf,.doc,.docx,.xls" * ``` */ accept?: string; /** * Combined with `accept` property it specifies which camera to use for * capture of image or video. It was previously a Boolean value. */ capture?: string | boolean; /** * Allow multiple files selection. */ multiple?: boolean; }; /** * Creates a virtual file input element (``) with options. * @param options */ const createInputFile = ({ accept = '', capture = false, multiple = false, }: Options = {}): InputFile => { const input = document.createElement('input') as InputFile; input.type = 'file'; input.accept = accept; input.capture = capture; input.multiple = multiple; return input; }; /** * Virtually creates a file input element (``), triggers it * and returns selected files. * * @example * selectFiles({ accept: 'image/*', multiple: true }).then(files => { * // ... * }); * * @param options */ const selectFiles = (options?: Options) => new Promise((resolve) => { const input = createInputFile(options); input.addEventListener('change', () => resolve(input.files || null)); setTimeout(() => { const event = new MouseEvent('click'); input.dispatchEvent(event); }, 0); }); export default selectFiles;