import { Button, FileUpload } from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
const Demo = () => {
return (
<FileUpload.Root>
<FileUpload.HiddenInput />
<FileUpload.Trigger asChild>
<Button variant="outline" size="sm">
<HiUpload /> Upload file
</Button>
</FileUpload.Trigger>
<FileUpload.List />
</FileUpload.Root>
)
}
用法
¥Usage
import { FileUpload } from "@chakra-ui/react"
<FileUpload.Root>
<FileUpload.HiddenInput />
<FileUpload.Label />
<FileUpload.Dropzone>
<FileUpload.DropzoneContent />
</FileUpload.Dropzone>
<FileUpload.Trigger />
<FileUpload.ItemGroup>
<FileUpload.Item>
<FileUpload.ItemPreview />
<FileUpload.ItemFileName />
<FileUpload.ItemSizeText />
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
</FileUpload.ItemGroup>
</FileUpload.Root>
快捷键
¥Shortcuts
FileUpload
组件还提供了一组用于常见用例的快捷方式。
¥The FileUpload
component also provides a set of shortcuts for common use
cases.
FileUploadItems
默认情况下,FileUploadItems
快捷方式会渲染已上传文件的列表。
¥By default, the FileUploadItems
shortcut renders the list of uploaded files.
有效:
¥This works:
<FileUpload.ItemGroup>
<FileUpload.Context>
{({ acceptedFiles }) =>
acceptedFiles.map((file) => (
<FileUpload.Item key={file.name} file={file}>
<FileUpload.ItemPreview />
<FileUpload.ItemName />
<FileUpload.ItemSizeText />
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
))
}
</FileUpload.Context>
</FileUpload.ItemGroup>
如果你不需要自定义文件上传项目,这可能会更简洁:
¥This might be more concise, if you don't need to customize the file upload items:
<FileUpload.ItemGroup>
<FileUpload.Items />
</FileUpload.ItemGroup>
FileUploadList
FileUploadList
快捷方式渲染已上传文件的列表。它组成了 FileUpload.ItemGroup
和 FileUpload.Items
组件。
¥The FileUploadList
shortcut renders the list of uploaded files. It composes
the FileUpload.ItemGroup
and FileUpload.Items
components.
<FileUpload.List />
等同于:
¥is the same as:
<FileUpload.ItemGroup>
<FileUpload.Items />
</FileUpload.ItemGroup>
示例
¥Examples
可接受的文件
¥Accepted Files
使用 accept
属性定义可接受的上传文件。
¥Define the accepted files for upload using the accept
prop.
import { Button, FileUpload } from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
const Demo = () => {
return (
<FileUpload.Root accept={["image/png"]}>
<FileUpload.HiddenInput />
<FileUpload.Trigger asChild>
<Button variant="outline" size="sm">
<HiUpload /> Upload file
</Button>
</FileUpload.Trigger>
<FileUpload.List />
</FileUpload.Root>
)
}
多个文件
¥Multiple Files
使用 maxFiles
prop 一次上传多个文件。
¥Upload multiple files at once by using the maxFiles
prop.
import { Button, FileUpload } from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
const Demo = () => {
return (
<FileUpload.Root maxFiles={5}>
<FileUpload.HiddenInput />
<FileUpload.Trigger asChild>
<Button variant="outline" size="sm">
<HiUpload /> Upload file
</Button>
</FileUpload.Trigger>
<FileUpload.List showSize clearable />
</FileUpload.Root>
)
}
自定义预览
¥Custom Preview
以下是如何显示文件的自定义图片预览的示例。
¥Here's an example of how to show a custom image preview for files.
"use client"
import {
Button,
FileUpload,
Float,
useFileUploadContext,
} from "@chakra-ui/react"
import { LuFileImage, LuX } from "react-icons/lu"
const FileUploadList = () => {
const fileUpload = useFileUploadContext()
const files = fileUpload.acceptedFiles
if (files.length === 0) return null
return (
<FileUpload.ItemGroup>
{files.map((file) => (
<FileUpload.Item
w="auto"
boxSize="20"
p="2"
file={file}
key={file.name}
>
<FileUpload.ItemPreviewImage />
<Float placement="top-end">
<FileUpload.ItemDeleteTrigger boxSize="4" layerStyle="fill.solid">
<LuX />
</FileUpload.ItemDeleteTrigger>
</Float>
</FileUpload.Item>
))}
</FileUpload.ItemGroup>
)
}
const Demo = () => {
return (
<FileUpload.Root accept="image/*">
<FileUpload.HiddenInput />
<FileUpload.Trigger asChild>
<Button variant="outline" size="sm">
<LuFileImage /> Upload Images
</Button>
</FileUpload.Trigger>
<FileUploadList />
</FileUpload.Root>
)
}
目录
¥Directory
使用 directory
属性可允许选择目录而不是文件。
¥Use the directory
prop to allow selecting a directory instead of a file.
import { Button, FileUpload } from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
const Demo = () => {
return (
<FileUpload.Root directory>
<FileUpload.HiddenInput />
<FileUpload.Trigger asChild>
<Button variant="outline" size="sm">
<HiUpload /> Upload file
</Button>
</FileUpload.Trigger>
<FileUpload.List />
</FileUpload.Root>
)
}
媒体捕获
¥Media Capture
使用 capture
属性从不同的环境和媒体类型中选择和上传文件。
¥Use the capture
prop to select and upload files from different environments
and media types.
注意:这在所有浏览器中都是 不完全支持。
import { Button, FileUpload } from "@chakra-ui/react"
import { HiCamera } from "react-icons/hi"
const Demo = () => {
return (
<FileUpload.Root capture="environment">
<FileUpload.HiddenInput />
<FileUpload.Trigger asChild>
<Button variant="outline" size="sm">
<HiCamera /> Open Camera
</Button>
</FileUpload.Trigger>
<FileUpload.List />
</FileUpload.Root>
)
}
拖放区
¥Dropzone
将多个文件拖放到拖放区内,并使用 maxFiles
属性设置可一次上传的文件数量。
¥Drop multiple files inside the dropzone and use the maxFiles
prop to set the
number of files that can be uploaded at once.
import { Box, FileUpload, Icon } from "@chakra-ui/react"
import { LuUpload } from "react-icons/lu"
const Demo = () => {
return (
<FileUpload.Root maxW="xl" alignItems="stretch" maxFiles={10}>
<FileUpload.HiddenInput />
<FileUpload.Dropzone>
<Icon size="md" color="fg.muted">
<LuUpload />
</Icon>
<FileUpload.DropzoneContent>
<Box>Drag and drop files here</Box>
<Box color="fg.muted">.png, .jpg up to 5MB</Box>
</FileUpload.DropzoneContent>
</FileUpload.Dropzone>
<FileUpload.List />
</FileUpload.Root>
)
}
输入框
¥Input
使用 FileInput
组件创建看起来像文本输入框的触发器。
¥Use the FileInput
component to create a trigger that looks like a text input.
import { FileUpload, Input } from "@chakra-ui/react"
const Demo = () => {
return (
<FileUpload.Root gap="1" maxWidth="300px">
<FileUpload.HiddenInput />
<FileUpload.Label>Upload file</FileUpload.Label>
<Input asChild>
<FileUpload.Trigger>
<FileUpload.FileText />
</FileUpload.Trigger>
</Input>
</FileUpload.Root>
)
}
可清除
¥Clearable
以下是可清除文件上传输入的示例。
¥Here's an example of a clearable file upload input.
import { CloseButton, FileUpload, Input, InputGroup } from "@chakra-ui/react"
import { LuFileUp } from "react-icons/lu"
const Demo = () => {
return (
<FileUpload.Root gap="1" maxWidth="300px">
<FileUpload.HiddenInput />
<FileUpload.Label>Upload file</FileUpload.Label>
<InputGroup
startElement={<LuFileUp />}
endElement={
<FileUpload.ClearTrigger asChild>
<CloseButton
me="-1"
size="xs"
variant="plain"
focusVisibleRing="inside"
focusRingWidth="2px"
pointerEvents="auto"
/>
</FileUpload.ClearTrigger>
}
>
<Input asChild>
<FileUpload.Trigger>
<FileUpload.FileText lineClamp={1} />
</FileUpload.Trigger>
</Input>
</InputGroup>
</FileUpload.Root>
)
}
粘贴文件
¥Pasting Files
以下是处理从剪贴板粘贴的文件的示例。
¥Here's an example of handling files pasted from the clipboard.
"use client"
import {
FileUpload,
Float,
HStack,
Input,
type InputProps,
useFileUploadContext,
} from "@chakra-ui/react"
import { HiX } from "react-icons/hi"
const FilePasteInput = (props: InputProps) => {
const fileUpload = useFileUploadContext()
return (
<Input
{...props}
onPaste={(e) => {
fileUpload.setClipboardFiles(e.clipboardData)
}}
/>
)
}
const FileImageList = () => {
const fileUpload = useFileUploadContext()
return (
<HStack wrap="wrap" gap="3">
{fileUpload.acceptedFiles.map((file) => (
<FileUpload.Item
p="2"
width="auto"
key={file.name}
file={file}
pos="relative"
>
<Float placement="top-start">
<FileUpload.ItemDeleteTrigger
p="0.5"
rounded="l1"
bg="bg"
borderWidth="1px"
>
<HiX />
</FileUpload.ItemDeleteTrigger>
</Float>
<FileUpload.ItemPreviewImage
boxSize="12"
rounded="l1"
objectFit="cover"
/>
</FileUpload.Item>
))}
</HStack>
)
}
const Demo = () => {
return (
<FileUpload.Root maxFiles={3} accept="image/*">
<FileUpload.HiddenInput />
<FileImageList />
<FilePasteInput placeholder="Paste image here..." />
</FileUpload.Root>
)
}
商店
¥Store
控制文件上传的另一种方法是使用 RootProvider
组件和 useFileUpload
存储钩子。
¥An alternative way to control the file upload is to use the RootProvider
component and the useFileUpload
store hook.
这样,你就可以从文件上传状态外部访问文件上传状态和方法。
¥This way you can access the file upload state and methods from outside the file upload.
accepted:
rejected:
"use client"
import {
Button,
Code,
FileUpload,
Stack,
useFileUpload,
} from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
const Demo = () => {
const fileUpload = useFileUpload({
maxFiles: 1,
maxFileSize: 3000,
})
const accepted = fileUpload.acceptedFiles.map((file) => file.name)
const rejected = fileUpload.rejectedFiles.map((e) => e.file.name)
return (
<Stack align="flex-start">
<Code colorPalette="green">accepted: {accepted.join(", ")}</Code>
<Code colorPalette="red">rejected: {rejected.join(", ")}</Code>
<FileUpload.RootProvider value={fileUpload}>
<FileUpload.HiddenInput />
<FileUpload.Trigger asChild>
<Button variant="outline" size="sm">
<HiUpload /> Upload file
</Button>
</FileUpload.Trigger>
<FileUpload.List />
</FileUpload.RootProvider>
</Stack>
)
}
属性
¥Props
根元素
¥Root
Prop | Default | Type |
---|---|---|
allowDrop | true | boolean Whether to allow drag and drop in the dropzone element |
locale | '\'en-US\'' | string The current locale. Based on the BCP 47 definition. |
maxFiles | '1' | number The maximum number of files |
maxFileSize | 'Infinity' | number The maximum file size in bytes |
minFileSize | '0' | number The minimum file size in bytes |
preventDocumentDrop | true | boolean Whether to prevent the drop event on the document |
as | React.ElementType The underlying element to render. | |
asChild | boolean Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
unstyled | boolean Whether to remove the component's style. | |
accept | Record<string, string[]> | FileMimeType | FileMimeType[] The accept file types | |
acceptedFiles | File[] The controlled accepted files | |
capture | 'user' | 'environment' The default camera to use when capturing media | |
defaultAcceptedFiles | File[] The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | |
directory | boolean Whether to accept directories, only works in webkit browsers | |
disabled | boolean Whether the file input is disabled | |
ids | Partial<{
root: string
dropzone: string
hiddenInput: string
trigger: string
label: string
item: (id: string) => string
itemName: (id: string) => string
itemSizeText: (id: string) => string
itemPreview: (id: string) => string
}> The ids of the elements. Useful for composition. | |
invalid | boolean Whether the file input is invalid | |
name | string The name of the underlying file input | |
onFileAccept | (details: FileAcceptDetails) => void Function called when the file is accepted | |
onFileChange | (details: FileChangeDetails) => void Function called when the value changes, whether accepted or rejected | |
onFileReject | (details: FileRejectDetails) => void Function called when the file is rejected | |
required | boolean Whether the file input is required | |
transformFiles | (files: File[]) => Promise<File[]> Function to transform the accepted files to apply transformations | |
translations | IntlTranslations The localized messages to use. | |
validate | (file: File, details: FileValidateDetails) => FileError[] | null Function to validate a file |