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>
)
}
用法
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>
快捷方式
FileUpload
组件还提供了一组常用快捷方式。
FileUploadItems
默认情况下,FileUploadItems
快捷方式渲染已上传文件的列表。
这样可行
<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>
如果您不需要自定义文件上传项,这可能会更简洁。
<FileUpload.ItemGroup>
<FileUpload.Items />
</FileUpload.ItemGroup>
FileUploadList
FileUploadList
快捷方式渲染已上传文件的列表。它由 FileUpload.ItemGroup
和 FileUpload.Items
组件组成。
<FileUpload.List />
等同于
<FileUpload.ItemGroup>
<FileUpload.Items />
</FileUpload.ItemGroup>
示例
接受的文件
使用 accept
属性定义接受上传的文件类型。
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>
)
}
多个文件
使用 maxFiles
属性一次上传多个文件。
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>
)
}
自定义预览
以下是为文件显示自定义图像预览的示例。
"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
属性允许选择目录而不是文件。
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>
)
}
媒体捕获
使用 capture
属性从不同环境和媒体类型中选择和上传文件。
注意: 并非所有浏览器都完全支持此功能。
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>
)
}
拖放区
将多个文件拖放到拖放区内,并使用 maxFiles
属性设置一次可上传的文件数量。
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>
)
}
输入框
使用 FileInput
组件创建一个看起来像文本输入框的触发器。
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>
)
}
可清空
以下是可清空文件上传输入框的示例。
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>
)
}
粘贴文件
以下是处理从剪贴板粘贴的文件的示例。
"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
store hook。
这样,您就可以在文件上传组件外部访问文件上传的状态和方法。
已接受
已拒绝
"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>
)
}
属性
根
属性 | 默认值 | 类型 |
---|---|---|
allowDrop | true | 布尔值 是否允许在拖放区元素中进行拖放 |
locale | '\'en-US\'' | 字符串 当前语言环境。基于 BCP 47 定义。 |
maxFiles | '1' | 数字 最大文件数量 |
maxFileSize | 'Infinity' | 数字 最大文件大小(字节) |
minFileSize | '0' | 数字 最小文件大小(字节) |
preventDocumentDrop | true | 布尔值 是否阻止在文档上发生拖放事件 |
accept | Record<string, string[]> | FileMimeType | FileMimeType[] 接受的文件类型 | |
asChild | ||
capture | 'user' | 'environment' 捕获媒体时使用的默认摄像头 | |
directory | 布尔值 是否接受目录,仅在 webkit 浏览器中有效 | |
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 }> 元素的 ID。用于组合很有用。 | |
invalid | 布尔值 文件输入是否无效 | |
name | 字符串 底层文件输入框的名称 | |
onFileAccept | (details: FileAcceptDetails) => void 文件被接受时调用的函数 | |
onFileChange | (details: FileChangeDetails) => void 值更改时(无论接受或拒绝)调用的函数 | |
onFileReject | (details: FileRejectDetails) => void 文件被拒绝时调用的函数 | |
required | 布尔值 文件输入是否必需 | |
translations | IntlTranslations 要使用的本地化消息。 | |
validate | (file: File, details: FileValidateDetails) => FileError[] | null 验证文件的函数 | |
as | React.ElementType 要渲染的底层元素。 | |
unstyled | 布尔值 是否移除组件的样式。 |