Gradio 月活用户突破 100 万!
阅读更多Gradio 月活用户突破 100 万!
阅读更多本指南将涵盖您实现自定义组件前端所需了解的一切。
提示: Gradio 组件使用 Svelte。编写 Svelte 很有趣!如果您不熟悉它,我们建议您查看他们的交互式[指南](https://learn.svelte.dev/tutorial/welcome-to-svelte)。
前端代码应至少包含三个文件
Index.svelte
:这是主要导出,也是组件的布局和逻辑所在。Example.svelte
:这是定义组件示例视图的位置。随意添加其他文件和子目录。如果您想导出任何其他模块,请记住修改 package.json
文件
"exports": {
".": "./Index.svelte",
"./example": "./Example.svelte",
"./package.json": "./package.json"
},
您的组件应公开以下属性,这些属性将从父 Gradio 应用程序向下传递。
import type { LoadingStatus } from "@gradio/statustracker";
import type { Gradio } from "@gradio/utils";
export let gradio: Gradio<{
event_1: never;
event_2: never;
}>;
export let elem_id = "";
export let elem_classes: string[] = [];
export let scale: number | null = null;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus | undefined = undefined;
export let mode: "static" | "interactive";
elem_id
和 elem_classes
允许 Gradio 应用开发者使用来自 Python Blocks
类的自定义 CSS 和 JavaScript 定位您的组件。
scale
和 min_width
允许 Gradio 应用开发者控制您的组件在 UI 中占据多少空间。
loading_status
用于在组件作为事件的输出时显示加载状态。
mode
是父 Gradio 应用告知您的组件应显示 interactive
版本还是 static
版本的方式。
gradio
:gradio
对象由父 Gradio 应用创建。它存储一些应用程序级别的配置,这些配置在您的组件中很有用,例如国际化。您必须使用它从您的组件调度事件。
一个最小的 Index.svelte
文件可能如下所示
<script lang="ts">
import type { LoadingStatus } from "@gradio/statustracker";
import { Block } from "@gradio/atoms";
import { StatusTracker } from "@gradio/statustracker";
import type { Gradio } from "@gradio/utils";
export let gradio: Gradio<{
event_1: never;
event_2: never;
}>;
export let value = "";
export let elem_id = "";
export let elem_classes: string[] = [];
export let scale: number | null = null;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus | undefined = undefined;
export let mode: "static" | "interactive";
</script>
<Block
visible={true}
{elem_id}
{elem_classes}
{scale}
{min_width}
allow_overflow={false}
padding={true}
>
{#if loading_status}
<StatusTracker
autoscroll={gradio.autoscroll}
i18n={gradio.i18n}
{...loading_status}
/>
{/if}
<p>{value}</p>
</Block>
Example.svelte
文件应公开以下属性
export let value: string;
export let type: "gallery" | "table";
export let selected = false;
export let index: number;
value
:应显示的示例值。
type
:这是一个变量,可以是 "gallery"
或 "table"
,具体取决于示例的显示方式。当示例对应于单个输入组件时,使用 "gallery"
形式,而当用户有多个输入组件,并且示例需要填充所有组件时,使用 "table"
形式。
selected
:如果用户通过使用 selected 变量“选择”了特定示例,您还可以调整示例的显示方式。
index
:所选值的当前索引。
您的“非示例”组件所需的任何其他属性!
这是 Radio
代码组件的 Example.svelte
文件
<script lang="ts">
export let value: string;
export let type: "gallery" | "table";
export let selected = false;
</script>
<div
class:table={type === "table"}
class:gallery={type === "gallery"}
class:selected
>
{value}
</div>
<style>
.gallery {
padding: var(--size-1) var(--size-2);
}
</style>
如果您的组件处理文件,则这些文件应该上传到后端服务器。@gradio/client
npm 包提供了 upload
和 prepare_files
实用程序函数来帮助您完成此操作。
prepare_files
函数会将浏览器的 File
数据类型转换为 gradio 的内部 FileData
类型。您应该在组件中使用 FileData
数据来跟踪上传的文件。
upload
函数会将 FileData
值的数组上传到服务器。
这是一个从 <input>
元素加载文件的示例,当其值更改时。
<script lang="ts">
import { upload, prepare_files, type FileData } from "@gradio/client";
export let root;
export let value;
let uploaded_files;
async function handle_upload(file_data: FileData[]): Promise<void> {
await tick();
uploaded_files = await upload(file_data, root);
}
async function loadFiles(files: FileList): Promise<void> {
let _files: File[] = Array.from(files);
if (!files.length) {
return;
}
if (file_count === "single") {
_files = [files[0]];
}
let file_data = await prepare_files(_files);
await handle_upload(file_data);
}
async function loadFilesFromUpload(e: Event): Promise<void> {
const target = e.target;
if (!target.files) return;
await loadFiles(target.files);
}
</script>
<input
type="file"
on:change={loadFilesFromUpload}
multiple={true}
/>
该组件公开了一个名为 root
的属性。这是由父 gradio 应用向下传递的,它表示文件将上传到和从中获取的基本 URL。
对于 WASM 支持,您应该从 Context
获取 upload 函数,并将其作为 upload
函数的第三个参数传递。
<script lang="ts">
import { getContext } from "svelte";
const upload_fn = getContext<typeof upload_files>("upload_files");
async function handle_upload(file_data: FileData[]): Promise<void> {
await tick();
await upload(file_data, root, upload_fn);
}
</script>
Gradio 的大多数前端组件都发布在 npm,即 javascript 包存储库上。这意味着您可以使用它们来节省时间,同时在组件中融入常见模式,例如上传文件。例如,@gradio/upload
包具有 Upload
和 ModifyUpload
组件,用于正确地将文件上传到 Gradio 服务器。以下是如何使用它们来创建用户界面以上传和显示 PDF 文件。
<script>
import { type FileData, Upload, ModifyUpload } from "@gradio/upload";
import { Empty, UploadText, BlockLabel } from "@gradio/atoms";
</script>
<BlockLabel Icon={File} label={label || "PDF"} />
{#if value === null && interactive}
<Upload
filetype="application/pdf"
on:load={handle_load}
{root}
>
<UploadText type="file" i18n={gradio.i18n} />
</Upload>
{:else if value !== null}
{#if interactive}
<ModifyUpload i18n={gradio.i18n} on:clear={handle_clear}/>
{/if}
<iframe title={value.orig_name || "PDF"} src={value.data} height="{height}px" width="100%"></iframe>
{:else}
<Empty size="large"> <File/> </Empty>
{/if}
您还可以组合现有的 Gradio 组件来创建完全独特的体验。例如,渲染聊天机器人对话的画廊。可能性是无限的,请阅读我们 javascript 包的文档此处。我们将在未来几周内添加更多包和文档!
您可以通过 Storybook 探索我们的组件库。您将能够与我们的组件进行交互,并查看它们的不同状态。
对于那些对设计定制感兴趣的人,我们提供了 CSS 变量,其中包括我们的调色板、半径、间距以及我们使用的图标 - 因此您可以轻松地将您的自定义组件与我们核心组件的样式相匹配。此 Storybook 将定期更新任何新增内容或更改。
如果您想利用庞大的 vite 生态系统,可以使用 gradio.config.js
文件来配置组件的构建过程。这允许您使用 tailwindcss、mdsvex 等工具。
目前,可以配置以下内容
Vite 选项
plugins
:要使用的 vite 插件列表。Svelte 选项
preprocess
:要使用的 svelte 预处理器列表。extensions
:要编译为 .svelte
文件的文件扩展名列表。build.target
:要构建的目标,这可能是支持较新的 javascript 功能所必需的。有关更多信息,请参阅 esbuild 文档。gradio.config.js
文件应放置在组件 frontend
目录的根目录下。当您创建一个新组件时,将为您创建一个默认的配置文件。但是,如果不存在配置文件,您也可以创建自己的配置文件,并使用它来自定义组件的构建过程。
自定义组件可以使用 Vite 插件来自定义构建过程。请查看 Vite 文档 以获取更多信息。
这里我们配置了 TailwindCSS,一个实用至上的 CSS 框架。使用版本 4 预发布版可以最轻松地进行设置。
npm install tailwindcss@next @tailwindcss/vite@next
在 gradio.config.js
中
import tailwindcss from "@tailwindcss/vite";
export default {
plugins: [tailwindcss()]
};
然后创建一个包含以下内容的 style.css
文件
@import "tailwindcss";
将此文件导入到 Index.svelte
中。请注意,您需要导入包含 @import
的 css 文件,而不能仅仅使用 <style>
标签并在其中使用 @import
。
<script lang="ts">
[...]
import "./style.css";
[...]
</script>
在 gradio.config.js
中,您还可以指定一些 Svelte 选项,以应用于 Svelte 编译。在此示例中,我们将添加对 mdsvex
的支持,这是一个用于 Svelte 的 Markdown 预处理器。
为了做到这一点,我们需要在 gradio.config.js
中的 svelte
对象中添加一个 Svelte 预处理器,并配置 extensions
字段。目前不支持其他选项。
首先,安装 mdsvex
插件
npm install mdsvex
然后将以下内容添加到 gradio.config.js
import { mdsvex } from "mdsvex";
export default {
svelte: {
preprocess: [
mdsvex()
],
extensions: [".svelte", ".svx"]
}
};
现在我们可以在组件的 frontend
目录中创建 mdsvex
文档,它们将被编译为 .svelte
文件。
<!-- HelloWorld.svx -->
<script lang="ts">
import { Block } from "@gradio/atoms";
export let title = "Hello World";
</script>
<Block label="Hello World">
# {title}
This is a markdown file.
</Block>
然后我们可以在组件中使用 HelloWorld.svx
文件
<script lang="ts">
import HelloWorld from "./HelloWorld.svx";
</script>
<HelloWorld />
您现在知道如何为您的组件创建令人愉快的前端了!