UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

148 lines (147 loc) • 4.34 kB
"use client"; import Icon from "../../Icon/Icon.mjs"; import { filterFilesByAccept } from "./helpers.mjs"; import { styles } from "./style.mjs"; import { memo, useCallback, useRef, useState } from "react"; import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime"; import { cx } from "antd-style"; import { Upload } from "lucide-react"; //#region src/base-ui/Upload/Upload.tsx const resolveAcceptedFiles = async (files, beforeUpload) => { if (!beforeUpload) return files; const accepted = []; for (const file of files) { let result; try { result = await beforeUpload(file, files); } catch { result = false; } if (result !== false) accepted.push(file); } return accepted; }; const Upload$1 = memo(({ accept, beforeUpload, children, className, description, directory, disabled, dragger, maxCount, multiple, onChange, onFiles, openFileDialogOnClick = true, ref, style, title, ...rest }) => { const inputRef = useRef(null); const [isDragOver, setIsDragOver] = useState(false); const handleFiles = useCallback(async (rawFiles) => { const filtered = filterFilesByAccept(rawFiles, accept); const accepted = await resolveAcceptedFiles(filtered, beforeUpload); const sliced = maxCount ? accepted.slice(0, maxCount) : accepted; if (sliced.length === 0) return; onFiles?.(sliced); for (const file of sliced) onChange?.({ file, fileList: sliced }); }, [ accept, beforeUpload, maxCount, onFiles, onChange ]); const openDialog = useCallback(() => { if (disabled) return; inputRef.current?.click(); }, [disabled]); const handleInputChange = useCallback((event) => { const files = event.target.files ? [...event.target.files] : []; event.target.value = ""; if (files.length > 0) handleFiles(files); }, [handleFiles]); const handleClick = useCallback((event) => { if (event.target === inputRef.current) return; if (disabled || !openFileDialogOnClick) return; openDialog(); }, [ disabled, openFileDialogOnClick, openDialog ]); const handleKeyDown = useCallback((event) => { if (disabled || !openFileDialogOnClick) return; if (event.key === "Enter" || event.key === " ") { event.preventDefault(); openDialog(); } }, [ disabled, openFileDialogOnClick, openDialog ]); const handleDragOver = useCallback((event) => { event.preventDefault(); }, []); const handleDragEnter = useCallback((event) => { event.preventDefault(); if (!disabled) setIsDragOver(true); }, [disabled]); const handleDragLeave = useCallback((event) => { event.preventDefault(); setIsDragOver(false); }, []); const handleDrop = useCallback((event) => { event.preventDefault(); setIsDragOver(false); if (disabled) return; const files = event.dataTransfer.files ? [...event.dataTransfer.files] : []; if (files.length > 0) handleFiles(files); }, [disabled, handleFiles]); const inputEl = /* @__PURE__ */ jsx("input", { accept, disabled, multiple, ref: inputRef, style: { display: "none" }, type: "file", onChange: handleInputChange, ...directory ? { webkitdirectory: "" } : {} }); if (dragger) return /* @__PURE__ */ jsxs("div", { "aria-disabled": disabled, className: cx(styles.dragger, isDragOver && styles.draggerOver, className), ref, role: "button", style, tabIndex: disabled ? -1 : 0, onClick: handleClick, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, onKeyDown: handleKeyDown, ...rest, children: [inputEl, children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [ /* @__PURE__ */ jsx(Icon, { className: styles.draggerIcon, icon: Upload, size: 24 }), /* @__PURE__ */ jsx("b", { className: styles.draggerTitle, children: title ?? "Click or drag file to this area to upload" }), description && /* @__PURE__ */ jsx("span", { className: styles.draggerDescription, children: description }) ] })] }); return /* @__PURE__ */ jsxs("span", { "aria-disabled": disabled, className: cx(styles.trigger, className), ref, role: "button", style, tabIndex: disabled ? -1 : 0, onClick: handleClick, onKeyDown: handleKeyDown, ...rest, children: [inputEl, children] }); }); Upload$1.displayName = "Upload"; //#endregion export { Upload$1 as default }; //# sourceMappingURL=Upload.mjs.map