--- url: /guide/components-json.md --- # components.json 配置 `components.json` 文件用于配置你的项目,使 Codebase Kit 能够理解你的项目设置并生成定制化组件。 :::tip 注意 `components.json` 文件是可选的,**仅在使用 CLI 添加组件时才需要**。如果你使用复制粘贴的方式,则不需要此文件。 ::: ## 初始化 你可以使用以下命令在项目中创建 `components.json` 文件: ```sh [npx] npx shadcn@latest init ``` ```sh [yarn] yarn dlx shadcn@latest init ``` ```sh [pnpm] pnpm dlx shadcn@latest init ``` ```sh [bunx] bunx shadcn@latest init ``` ```sh [deno] deno run npm:shadcn@latest npm:init ``` ## $schema `$schema` 属性用于指定 `components.json` 文件的 JSON Schema。 ```json title="components.json" { "$schema": "https://ui.shadcn.com/schema.json" } ``` ## style 组件的样式风格。**初始化后无法更改此配置。** ```json title="components.json" { "style": "default" } ``` Codebase Kit 基于 [UnoCSS](https://unocss.dev/) 和 [Ant Design](https://ant.design/) 构建,提供了简洁的默认样式和主题系统。 ## framework 指定使用的框架类型。 ```json title="components.json" { "framework": "react" } ``` 目前 Codebase Kit 支持 React 框架。 ## aliases CLI 使用这些值和 `tsconfig.json` 或 `jsconfig.json` 文件中的 `paths` 配置来确定生成组件的正确位置。 路径别名必须在 `tsconfig.json` 或 `jsconfig.json` 文件中设置。 :::tip 重要 如果你使用 `src` 目录,请确保将其包含在 `tsconfig.json` 或 `jsconfig.json` 文件的 `paths` 下。 ::: ### aliases.utils 工具函数的导入别名。 ```json title="components.json" { "aliases": { "utils": "@/lib/utils" } } ``` ### aliases.components 组件的导入别名。 ```json title="components.json" { "aliases": { "components": "@/components" } } ``` ### aliases.ui `ui` 组件的导入别名。 CLI 将使用 `aliases.ui` 值来确定放置 `ui` 组件的位置。如果你想自定义 `ui` 组件的安装目录,请使用此配置。 ```json title="components.json" { "aliases": { "ui": "@/components" } } ``` ### aliases.lib `lib` 函数的导入别名,例如 `format-date` 或 `generate-id`。 ```json title="components.json" { "aliases": { "lib": "@/lib" } } ``` ### aliases.hooks `hooks` 的导入别名,例如 `use-media-query` 或 `use-toast`。 ```json title="components.json" { "aliases": { "hooks": "@/hooks" } } ``` ## registries 为你的项目配置多个资源注册表。这允许你从各种源(包括私有注册表)安装组件、库、工具和其他资源。 ### 基础配置 使用 URL 模板配置注册表: ```json title="components.json" { "registries": { "@v0": "https://v0.dev/chat/b/{name}", "@acme": "https://registry.acme.com/{name}.json", "@internal": "https://internal.company.com/{name}.json" } } ``` `{name}` 占位符将在安装时被资源名称替换。 ### 高级配置 - 带身份验证 对于需要身份验证的私有注册表: ```json title="components.json" { "registries": { "@private": { "url": "https://api.company.com/registry/{name}.json", "headers": { "Authorization": "Bearer ${REGISTRY_TOKEN}", "X-API-Key": "${API_KEY}" }, "params": { "version": "latest" } } } } ``` 格式为 `${VAR_NAME}` 的环境变量将从你的环境中自动展开。 ### 使用命名空间注册表 配置完成后,使用命名空间语法安装资源: ```bash # 从配置的注册表安装 npx shadcn@latest add @v0/dashboard # 从私有注册表安装 npx shadcn@latest add @private/button # 安装多个资源 npx shadcn@latest add @acme/header @internal/auth-utils ``` ### 示例:多注册表设置 ```json title="components.json" { "registries": { "@shadcn": "https://ui.shadcn.com/r/{name}.json", "@company-ui": { "url": "https://registry.company.com/ui/{name}.json", "headers": { "Authorization": "Bearer ${COMPANY_TOKEN}" } }, "@team": { "url": "https://team.company.com/{name}.json", "params": { "team": "frontend", "version": "${REGISTRY_VERSION}" } } } } ``` 此配置允许你: - 从 shadcn/ui 安装公共组件 - 使用身份验证访问私有公司 UI 组件 - 使用带版本控制的团队特定资源 ## 完整示例 以下是一个完整的 `components.json` 配置示例: ```json title="components.json" showLineNumbers { "$schema": "https://ui.shadcn.com/schema.json", "style": "default", "framework": "react", "aliases": { "utils": "@/lib/utils", "components": "@/components", "ui": "@/components", "lib": "@/lib", "hooks": "@/hooks" }, "registries": { "@codebase-kit": "https://codebase.anyask.dev/r/{name}.json" } } ``` ## tsconfig.json 配置 为了使路径别名正常工作,你还需要在 `tsconfig.json` 中配置路径映射: ```json title="tsconfig.json" showLineNumbers { "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./src/*"], "@/components/*": ["./src/components/*"], "@/lib/*": ["./src/lib/*"], "@/hooks/*": ["./src/hooks/*"] } } } ``` --- url: /guide/get-started.md --- # 快速开始 **这不是一个传统组件库。它是你构建自己组件库的方式。** 你知道大多数传统组件库是如何工作的:从 NPM 安装一个包,导入组件,然后在应用中使用它们。 这种方式在你需要定制组件以适应你的设计系统,或者需要库中没有包含的组件时,就会遇到问题。**你最终不得不包装库组件、编写覆盖样式的工作代码,或者混合使用来自不同库的 API 不兼容的组件。** 这就是 Codebase Kit 要解决的问题。它基于以下原则构建: - **开放代码:** 组件的顶层代码开放,可修改。 - **可组合性:** 每个组件使用通用、可组合的接口,使它们可预测。 - **易于分发:** 扁平文件模式和命令行工具使组件分发变得简单。 - **精致默认:** 精心选择的默认样式,开箱即用即可获得出色设计。 - **面向 AI:** 开放代码供 LLMs 读取、理解和改进。 ## 安装 ### 1. 初始化配置 运行以下命令在你的项目中创建 `components.json` 配置文件: ```sh [npm] npm shadcn@latest init ``` ```sh [yarn] yarn shadcn@latest init ``` ```sh [pnpm] pnpm shadcn@latest init ``` ```sh [bun] bun shadcn@latest init ``` ```sh [deno] deno shadcn@latest npm:init ``` 这将引导你完成配置过程,包括: - 选择样式风格 - 配置路径别名 - 设置 TypeScript 选项 :::tip 提示 详细了解 `components.json` 的所有配置选项,请参阅 [components.json 配置](/guide/components-json.md) 文档。 ::: ### 2. 安装组件 配置完成后,你可以使用 CLI 安装组件: ```bash # 安装单个组件 npx shadcn@latest add https://codebase.anyask.dev/r/button.json # 安装多个组件 npx shadcn@latest add @xuanyuan/search-form @xuanyuan/descriptions ``` ## 开放代码 Codebase Kit 为你提供实际的组件代码。你拥有完全的控制权来定制和扩展组件以满足你的需求。这意味着: - **完全透明:** 你可以精确地看到每个组件是如何构建的。 - **轻松定制:** 修改组件的任何部分以适应你的设计和功能要求。 - **AI 集成:** 访问代码使 LLMs 能够直接读取、理解甚至改进你的组件。 _在典型的库中,如果你需要更改按钮的行为,你必须覆盖样式或包装组件。使用 Codebase Kit,你只需直接编辑按钮代码。_ ## 可组合性 Codebase Kit 中的每个组件都共享一个通用的、可组合的接口。**如果某个组件不存在,我们会引入它,使其可组合,并调整其样式以匹配并与设计系统的其余部分一起工作。** _共享的可组合接口意味着它对你的团队和 LLMs 都是可预测的。你不会为每个新组件学习不同的 API。即使是第三方组件也是如此。_ ## 易于分发 Codebase Kit 也是一个代码分发系统。它定义了组件的模式和用于分发它们的 CLI。 - **模式:** 定义组件、其依赖项和属性的扁平文件结构。 - **CLI:** 用于跨项目分发和安装组件的命令行工具,支持跨框架。 _你可以使用该模式将组件分发到其他项目,或者让 AI 基于现有模式生成全新的组件。_ ## 精致默认 Codebase Kit 提供了大量具有精心选择的默认样式的组件。它们的设计本身就很好看,并且作为一个一致的系统协同工作: - **开箱即用:** 无需额外工作,你的 UI 就拥有简洁的外观。 - **统一设计:** 组件自然地相互配合。每个组件都是为了与其他组件匹配而构建的,保持 UI 的一致性。 - **易于定制:** 如果你想改变什么,覆盖和扩展默认值很简单。 ## 面向 AI Codebase Kit 的设计使 AI 工具能够轻松地与你的代码协作。其开放代码和一致的 API 允许 AI 模型读取、理解甚至生成新组件。 _AI 模型可以学习你的组件如何工作,并提出改进建议,甚至创建与你现有设计集成的新组件。_ --- url: /guide/index.md --- # Markdown & MDX Rspress supports not only Markdown but also [MDX](https://mdxjs.com/), a powerful way to develop content. ## Markdown MDX is a superset of Markdown, which means you can write Markdown files as usual. For example: ```md # Hello world ``` ## Use component When you want to use React components in Markdown files, you should name your files with `.mdx` extension. For example: ```mdx // docs/index.mdx import { CustomComponent } from './custom'; # Hello world ``` ## Front matter You can add Front Matter at the beginning of your Markdown file, which is a YAML-formatted object that defines some metadata. For example: ```yaml --- title: Hello world --- ``` > Note: By default, Rspress uses h1 headings as html headings. You can also access properties defined in Front Matter in the body, for example: ```markdown --- title: Hello world --- # {frontmatter.title} ``` The previously defined properties will be passed to the component as `frontmatter` properties. So the final output will be: ```html

Hello world

``` ## Custom container You can use the `:::` syntax to create custom containers and support custom titles. For example: **Input:** ```markdown :::tip This is a `block` of type `tip` ::: :::info This is a `block` of type `info` ::: :::warning This is a `block` of type `warning` ::: :::danger This is a `block` of type `danger` ::: ::: details This is a `block` of type `details` ::: :::tip Custom Title This is a `block` of `Custom Title` ::: :::tip{title="Custom Title"} This is a `block` of `Custom Title` ::: ``` **Output:** :::tip This is a `block` of type `tip` ::: :::info This is a `block` of type `info` ::: :::warning This is a `block` of type `warning` ::: :::danger This is a `block` of type `danger` ::: ::: details This is a `block` of type `details` ::: :::tip Custom Title This is a `block` of `Custom Title` ::: :::tip\{title="Custom Title"} This is a `block` of `Custom Title` ::: ## Code block ### Basic usage You can use the \`\`\` syntax to create code blocks and support custom titles. For example: **Input:** ````md ```js console.log('Hello World'); ``` ```js title="hello.js" console.log('Hello World'); ``` ```` **Output:** ```js console.log('Hello World'); ``` ```js title="hello.js" console.log('Hello World'); ``` ### Show line numbers If you want to display line numbers, you can enable the `showLineNumbers` option in the config file: ```ts title="rspress.config.ts" export default { // ... markdown: { showLineNumbers: true, }, }; ``` ### Wrap code If you want to wrap long code line by default, you can enable the `defaultWrapCode` option in the config file: ```ts title="rspress.config.ts" export default { // ... markdown: { defaultWrapCode: true, }, }; ``` ### Line highlighting You can also apply line highlighting and code block title at the same time, for example: **Input:** ````md ```js title="hello.js" console.log('Hello World'); // [\!code highlight] // [\!code highlight:3] const a = 1; console.log(a); const b = 2; console.log(b); ``` ```` :::warning The backslash (`\`) in `[\!code highlight]` is for Markdown escaping to display the raw syntax. Do not include it when using this notation in your actual code. ::: **Output:** ```js title="hello.js" console.log('Hello World'); // [!code highlight] // [!code highlight:3] const a = 1; console.log(a); const b = 2; console.log(b); ``` ## Rustify MDX compiler You can enable Rustify MDX compiler by following config: --- url: /guide/llms.md --- # LLMs.txt 本指南介绍如何让 Cursor、Windsurf 和 Claude 等 AI 工具更好地理解 Codebase Kit。 ## 什么是 LLMs.txt? 我们支持通过 [LLMs.txt](https://llmstxt.org/) 文件向大语言模型(LLMs)提供 Codebase Kit 文档。此功能可帮助 AI 工具更好地理解我们的组件库、API 及使用模式。 ## 可用资源 我们提供多个 LLMs.txt 路由来帮助 AI 工具访问文档: - [llms.txt](https://codebase.anyask.dev/llms.txt) - 包含所有组件及其文档链接的结构化概览 - [llms-full.txt](https://codebase.anyask.dev/llms-full.txt) - 提供包含实现细节和示例的完整文档 ## 在 AI 工具中的使用 ### Cursor 在 Cursor 中使用 `@Docs` 功能将 LLMs.txt 文件包含到您的项目中。这有助于 Cursor 为 Codebase Kit 组件提供更准确的代码建议和文档。 [详细了解 Cursor 中的 @Docs 功能](https://docs.cursor.com/zh/context/@-symbols/@-docs) ### Windsurf 通过 `@` 引用或在 `.windsurf/rules` 文件中配置 LLMs.txt 文件,以增强 Windsurf 对 Codebase Kit 组件的理解。 [详细了解 Windsurf Memories 功能](https://docs.windsurf.com/windsurf/cascade/memories) ### Claude Code 在 Claude Code 中,将 `LLMs.txt` 添加到工作区的知识库(Docs / Context Files)配置中,即可在代码补全与解释时引用其中的内容,从而提升对 Codebase Kit 组件的理解。 [详细了解 Claude Code 文档上下文配置](https://code.claude.com/docs) ### Gemini CLI 在 Gemini CLI 中,可以通过 `--context` 参数或在 `.gemini/config.json` 中指定 `LLMs.txt` 文件路径,让 Gemini 在回答和生成代码时参考该文档。 [详细了解 Gemini CLI 上下文配置](https://ai.google.dev/gemini-api/docs?hl=zh-cn) ### Trae 在 Trae 中,将 `LLMs.txt` 文件放入项目的 knowledge sources 并在设置里开启引用,即可让 Trae 在生成或分析代码时更好地支持 Codebase Kit 组件。 [详细了解 Trae 的知识源功能](https://trae.ai/docs) ### Qoder 在 Qoder 中,可以在 `.qoder/config.yml` 中添加 `LLMs.txt` 作为外部知识文件,或在对话中通过 `@docs LLMs.txt` 进行临时引用,增强对 Codebase Kit 组件的支持。 [详细了解 Qoder 配置方法](https://docs.qoder.com/) ### 其他 AI 工具 任何支持 LLMs.txt 的 AI 工具均可使用以上路径来更好地理解 Codebase Kit。 --- url: /components/AIFormFill.md --- # AIFormFill AI 智能表单填写 AI 智能表单填写组件,可以自动分析表单字段并智能填写合适的测试数据。 ## 安装 ```sh [npx] npx shadcn@latest add https://codebase.anyask.dev/r/ai-form-fill.json ``` ```sh [yarn] yarn dlx shadcn@latest add https://codebase.anyask.dev/r/ai-form-fill.json ``` ```sh [pnpm] pnpm dlx shadcn@latest add https://codebase.anyask.dev/r/ai-form-fill.json ``` ```sh [bunx] bunx shadcn@latest add https://codebase.anyask.dev/r/ai-form-fill.json ``` ```sh [deno] deno run npm:shadcn@latest npm:add https://codebase.anyask.dev/r/ai-form-fill.json ``` ## 基础用法 最简单的用法,将 `Form.Item` 包裹在 `AIFormFill` 组件中即可。 ```tsx file="/demos/components/AIFormFill/basic.demo.tsx" preview import React from 'react'; import { DatePicker, Form, Input, message } from 'antd'; import AIFormFill from '@/components/AIFormFill'; const Demo: React.FC = () => { const [form] = Form.useForm(); const handleFillComplete = (values: Record) => { console.log('AI Fill Complete:', values); message.success('AI 已完成表单填写'); }; const handleFillError = (error: Error) => { console.error('AI Fill Error:', error); message.error(`AI 填写失败: ${error.message}`); }; return (

💡 AI 自动填写功能演示

点击下方的「AI 智能填写」按钮,AI 会自动分析表单字段并智能填写合适的测试数据。

); }; export default Demo; ``` ## 与 SearchForm 组合使用 `AIFormFill` 可以与 `SearchForm` 组件完美配合使用。只需将 `AIFormFill` 包裹在 `SearchForm` 外层即可。 ```tsx file="/demos/components/AIFormFill/with-search-form.demo.tsx" preview import React from 'react'; import { DatePicker, Form, Input, message } from 'antd'; import AIFormFill from '@/components/AIFormFill'; import SearchForm from '@/components/SearchForm'; const Demo: React.FC = () => { const [form] = Form.useForm(); const handleSearch = (values: Record) => { console.log('Search:', values); message.success(`查询成功: ${JSON.stringify(values)}`); }; const handleReset = () => { console.log('Reset'); message.info('表单已重置'); }; const handleFillComplete = (values: Record) => { console.log('AI Fill Complete:', values); message.success('AI 已完成表单填写'); }; const handleFillError = (error: Error) => { console.error('AI Fill Error:', error); message.error(`AI 填写失败: ${error.message}`); }; return (

🔗 与 SearchForm 组合使用

AIFormFill 可以与 SearchForm 组件完美配合使用。只需将 AIFormFill 包裹在 SearchForm 外层即可。

); }; export default Demo; ``` ## 自定义按钮 你可以通过 `renderButton` 属性完全自定义按钮的渲染方式,或者通过 `buttonIcon`、`buttonType` 等属性调整样式。 ```tsx file="/demos/components/AIFormFill/custom-button.demo.tsx" preview import React from 'react'; import { Button, DatePicker, Form, Input, message, Space } from 'antd'; import { RobotOutlined } from '@ant-design/icons'; import AIFormFill from '@/components/AIFormFill'; const Demo: React.FC = () => { const [form] = Form.useForm(); const handleFillComplete = (values: Record) => { console.log('AI Fill Complete:', values); message.success('AI 已完成表单填写'); }; const handleFillError = (error: Error) => { console.error('AI Fill Error:', error); message.error(`AI 填写失败: ${error.message}`); }; return (

🎨 自定义按钮样式

你可以通过 renderButton 属性完全自定义按钮的渲染方式,或者通过 buttonIcon、buttonType 等属性调整样式。

{/* 示例 1: 自定义图标和类型 */} } buttonType="primary" placement="top-right" > {/* 示例 2: 完全自定义按钮 */} (
{progressInfo && 🤖 {progressInfo}}
)} >
); }; export default Demo; ``` ## 智能识别字段类型 组件会自动识别以下类型的字段并生成相应的测试数据: | 字段类型/名称 | 示例数据 | | ---------------------------------------- | ---------------------- | | ID 字段 (包含 `id` 或 `ID`) | `"12345"` | | 姓名字段 (包含 `name`、`姓名`、`名称`) | `"张三"`、`"李四"` | | 邮箱字段 (包含 `email`、`邮箱`) | `"test123@gmail.com"` | | 日期字段 (DatePicker 或包含 `date`、`日期`、`time`) | `moment('2024-01-15')` | | 数字字段 (InputNumber 或包含 `number`、`数量`) | `123` | | 其他文本字段 | `"{标签} - 测试数据 42"` | ## API --- url: /components/AsyncDescriptions.md --- # AsyncDescriptions 异步描述列表 支持异步数据加载的描述列表组件,集成了 BoundaryBlock 的加载、错误、空状态处理。 ## 安装 ```sh [npx] npx shadcn@latest add https://codebase.anyask.dev/r/async-descriptions.json ``` ```sh [yarn] yarn dlx shadcn@latest add https://codebase.anyask.dev/r/async-descriptions.json ``` ```sh [pnpm] pnpm dlx shadcn@latest add https://codebase.anyask.dev/r/async-descriptions.json ``` ```sh [bunx] bunx shadcn@latest add https://codebase.anyask.dev/r/async-descriptions.json ``` ```sh [deno] deno run npm:shadcn@latest npm:add https://codebase.anyask.dev/r/async-descriptions.json ``` ## 基础用法 ```tsx file="/demos/components/AsyncDescriptions/basic.demo.tsx" preview import React from 'react'; import AsyncDescriptions from '@/components/AsyncDescriptions'; const Demo: React.FC = () => { const fetchUserInfo = async () => { // 模拟异步请求 await new Promise((resolve) => setTimeout(resolve, 1000)); return { name: '张三', age: 28, email: 'zhangsan@example.com', status: 'active', createTime: '2024-01-15', }; }; return ( ); }; export default Demo; ``` ## 自定义头部渲染 通过 `renderHeader` 自定义头部区域,可以显示更丰富的信息。 ```tsx file="/demos/components/AsyncDescriptions/custom-render.demo.tsx" preview import React from 'react'; import { Button } from 'antd'; import { ReloadOutlined } from '@ant-design/icons'; import AsyncDescriptions from '@/components/AsyncDescriptions'; const Demo: React.FC = () => { const fetchUserInfo = async () => { await new Promise((resolve) => setTimeout(resolve, 1000)); return { name: '李四', salary: 15000, phone: '13800138000', status: 'active', }; }; return ( (
{data.name}
)} items={[ { dataIndex: 'name', label: '姓名' }, { dataIndex: 'salary', label: '薪资', unit: '元', precision: 0 }, { dataIndex: 'phone', label: '手机号' }, { dataIndex: 'status', label: '状态', enum: { active: 启用, inactive: 禁用 }, }, ]} /> ); }; export default Demo; ``` ## Features - **自动请求**: 组件挂载时自动调用 `request` 函数获取数据 - **状态处理**: 集成 BoundaryBlock,自动处理加载中、错误、空状态 - **自定义头部**: 支持 `title` 或 `renderHeader` 自定义头部 - **Descriptions支持**: 完全支持 Descriptions 的所有配置项 ## API ### [#](#asyncdescriptions)AsyncDescriptions | 属性 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | request*** | 请求函数 | `() => Promise` | `-` | | descriptionsClassName | Descriptions className | `string` | `-` | | title | 标题 | `ReactNode` | `-` | | renderHeader | 自定义渲染 header | `(data: T, result: Result) => ReactNode` | `-` | 继承 [BoundaryBlock](/components/BoundaryBlock.md#boundaryblock) 的属性(除 `header`)。 --- url: /components/AsyncSelect.md --- # AsyncSelect 异步选择器 支持异步数据加载和远程搜索的选择器组件。 ## 安装 ```sh [npx] npx shadcn@latest add https://codebase.anyask.dev/r/async-select.json ``` ```sh [yarn] yarn dlx shadcn@latest add https://codebase.anyask.dev/r/async-select.json ``` ```sh [pnpm] pnpm dlx shadcn@latest add https://codebase.anyask.dev/r/async-select.json ``` ```sh [bunx] bunx shadcn@latest add https://codebase.anyask.dev/r/async-select.json ``` ```sh [deno] deno run npm:shadcn@latest npm:add https://codebase.anyask.dev/r/async-select.json ``` ## 基础用法 传入 `service` 函数异步加载选项数据。 ```tsx file="/demos/components/AsyncSelect/basic.demo.tsx" preview import React from 'react'; import AsyncSelect from '@/components/AsyncSelect'; // 模拟接口返回数据 const fetchOptions = async () => { await new Promise((resolve) => setTimeout(resolve, 500)); return { data: [ { label: '选项一', value: '1' }, { label: '选项二', value: '2' }, { label: '选项三', value: '3' }, ], }; }; const Demo: React.FC = () => { return ; }; export default Demo; ``` ## 远程搜索 启用 `enableRemoteSearch` 后,用户输入时会调用 `service` 函数进行远程搜索。支持防抖配置 `searchDebounceWait`。 ```tsx file="/demos/components/AsyncSelect/remote-search.demo.tsx" preview import React from 'react'; import AsyncSelect from '@/components/AsyncSelect'; // 模拟搜索接口 const searchOptions = async (searchText: string) => { await new Promise((resolve) => setTimeout(resolve, 500)); const allOptions = [ { label: '苹果', value: 'apple' }, { label: '香蕉', value: 'banana' }, { label: '橙子', value: 'orange' }, { label: '葡萄', value: 'grape' }, { label: '西瓜', value: 'watermelon' }, ]; const filtered = allOptions.filter((item) => item.label.includes(searchText) || item.value.includes(searchText)); // 如果没有匹配结果,返回用户输入作为提示 if (filtered.length === 0 && searchText) { return { data: [ { label: `搜索 "${searchText}" 无结果`, value: searchText, disabled: true, }, ], }; } return { data: filtered }; }; const Demo: React.FC = () => { return ( ); }; export default Demo; ``` ## 允许空搜索 通过 `allowEmptySearch` 控制搜索值为空时是否允许搜索。配合 `initialLoad` 可实现聚焦时加载全部数据。 ```tsx file="/demos/components/AsyncSelect/allow-empty-search.demo.tsx" preview import React from 'react'; import AsyncSelect from '@/components/AsyncSelect'; // 模拟搜索 API(允许空搜索时返回所有数据) const mockSearchProducts = async (searchText?: string) => { return new Promise<{ data: any[] }>((resolve) => { setTimeout(() => { const allProducts = [ { id: '1', name: 'iPhone 15', code: 'IP15' }, { id: '2', name: 'MacBook Pro', code: 'MBP' }, { id: '3', name: 'AirPods Pro', code: 'APP' }, { id: '4', name: 'iPad Air', code: 'IPA' }, { id: '5', name: 'Apple Watch', code: 'AW' }, ]; // 允许空搜索时,searchText 为空也会返回所有数据 const filtered = searchText ? allProducts.filter( (product) => product.name.toLowerCase().includes(searchText.toLowerCase()) || product.code.toLowerCase().includes(searchText.toLowerCase()), ) : allProducts; resolve({ data: filtered }); }, 300); }); }; const Demo: React.FC = () => { return (

允许空搜索 - 输入框为空或聚焦时会加载数据

不允许空搜索 - 必须输入内容才搜索

); }; export default Demo; ``` ## 数据依赖 通过 `deps` 监听依赖变化,当依赖项变化时会自动重新请求数据。 ```tsx file="/demos/components/AsyncSelect/deps.demo.tsx" preview import React, { useState } from 'react'; import { Select } from 'antd'; import AsyncSelect from '@/components/AsyncSelect'; // 模拟根据分类获取选项 const fetchOptionsByCategory = async (category: string) => { await new Promise((resolve) => setTimeout(resolve, 500)); const optionsMap: Record = { fruit: [ { label: '苹果', value: 'apple' }, { label: '香蕉', value: 'banana' }, ], vegetable: [ { label: '胡萝卜', value: 'carrot' }, { label: '西红柿', value: 'tomato' }, ], drink: [ { label: '可乐', value: 'cola' }, { label: '橙汁', value: 'orange-juice' }, ], }; return { data: optionsMap[category] || [] }; }; const Demo: React.FC = () => { const [category, setCategory] = useState('fruit'); return (
setHighlight(e.target.value)} style={{ width: 300 }} />
); }; export default Demo; ``` ## API ### [#](#highlighttext)HighlightText | 属性 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | text*** | 要显示的文本 | `string` | `-` | | highlight*** | 要高亮的关键词 | `string` | `-` | | highlightClass | 高亮文本的自定义样式类名 | `string` | `text-primary` | --- url: /components/Iframe.md --- # Iframe 内嵌框架 带有加载状态和错误处理的 iframe 组件。 ## 安装 ```sh [npx] npx shadcn@latest add https://codebase.anyask.dev/r/iframe.json ``` ```sh [yarn] yarn dlx shadcn@latest add https://codebase.anyask.dev/r/iframe.json ``` ```sh [pnpm] pnpm dlx shadcn@latest add https://codebase.anyask.dev/r/iframe.json ``` ```sh [bunx] bunx shadcn@latest add https://codebase.anyask.dev/r/iframe.json ``` ```sh [deno] deno run npm:shadcn@latest npm:add https://codebase.anyask.dev/r/iframe.json ``` ## 基础用法 ```tsx file="/demos/components/Iframe/basic.demo.tsx" preview import React from 'react'; import Iframe from '@/components/Iframe'; const Demo: React.FC = () => { return