# @bundu/ui 中文文档

规范地址：https://npmcn.com/package/%40bundu/ui/

版本：0\.13\.0
npm 元数据更新时间：2026-11-05T14:13:06.875Z
中文译文更新时间：2026-11-08T19:50:59.177Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bundu/ui
原文对照：https://npmcn.com/package/%40bundu/ui/?lang=original
项目主页：https://github.com/mzizi-dev/packages-npm#readme
源码仓库：https://github.com/mzizi-dev/packages-npm

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.4 MB，250 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：5 个
- 首次发布：2026-07-03T06:17:07.713Z
- 最新版本发布：2026-11-05T14:13:06.504Z
- 近 30 天下载量：3735（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：14（近 12 个月 14 个）

## 中文简介

Bundu生态系统的营销UI工具包——Nyuchi实施Mzizi设计系统. 所有21个Mzizi彩色家族(7个矿物、7个遗产、7个实验性)在一个 -- -- 彩色\*命名空间、9步地表梯子、连接状态t

## 安装

```sh
npm install @bundu/ui
```

也可以使用：`pnpm add @bundu/ui`、`yarn add @bundu/ui`、`bun add @bundu/ui`

## README

# @bundu/ ui (英语)

> Bundu生态系统的营销UI工具箱——编辑Astro的构件外加Mzizi活字牌上的Shadcn风格回放原始(所有21个彩色家族).

[![npm](https://img.shields.io/npm/v/%40bundu%2Fui?style=flat-square&logo=npm)](https://www.npmjs.com/package/@bundu/ui) [![Lint](https://img.shields.io/github/actions/workflow/status/mzizi-dev/packages-npm/lint.yml?branch=main&label=lint&style=flat-square)](https://github.com/mzizi-dev/packages-npm/actions/workflows/lint.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)

**重现 :** [mzizi-dev/packages-npm (英语:](https://github.com/mzizi-dev/packages-npm) | **结构 :** [mzizi.dev (英语)](https://mzizi.dev/)

* * *

## 这是什么

销售站点背后的共享组件层(bundu, nyuchi, mukoko). 这是Nyuchi执行 [姆齐兹](https://mzizi.dev/) 设计 - Bundu基金会的一个开放建筑项目,运营和 由Nyuchi开发。 这个包裹不是Mzizi本身.

-   **Astro营销组件** —— 说 `Hero`, (中文(简体) ), `Section`, (中文(简体) ), `SectionHeader`, (中文(简体) ), `Container`, (中文(简体) ), `MineralStrip`, (中文(简体) ), `Icon`, (中文(简体) ), `SocialIcon`,以及 `Breadcrumb` (emits 有效计划.org) `BreadcrumbList` JSON-LD for Google rich results. (原始内容存档于2018-09-27).
    
-   **Astro形式和媒体组件** —— 说 `SegmentedControl` (本地无线电), `NativeSelect`, (中文(简体) ), `Toaster` (单位:千美元)`window.toast()` )和 `SafeAreaFrame` (几何学: `safeAreaBands` 从软件包根中导入,以 `@bundu/ui/<Name>.astro`,除登记原始人 `Alert`, (中文(简体) ), `Button`, (中文(简体) ), `Card`, (中文(简体) ), `Input`, (中文(简体) ), `Label`, (中文(简体) ), `Skeleton` 财务报告和审定财务报表 `StatusBadge`各自保持其登记册 合同(`contracts/ui/`); 应用模式处于下 `@bundu/ui/app/*` (下关.
    
-   **Markdown,通过建筑安全** —— 说 `MarkdownRenderer` (单位:千美元)`@bundu/ui/MarkdownRenderer.astro`, (中文(简体) ), 合同 `ui/markdown-renderer`) (中文(简体) ). 它解释 `content` 绘制成 元素,从不通过 HTML 字符串。 源代码中的 Raw HTML 显示为文本, 链接通过 方案允许列表( :`links="safe"`、默认值、保存 https、 https、 mailto、 电话和相对 地址; `links="https"` 仅保留 https; 拒绝的链接保留其单词. `from="html"` 或者说 `"auto"` 阅读编辑的丰富文本 `headingBase` 设置关卡 a `#` 标题 {\\fn黑体\\fs22\\bord1\\shad0\\3aHBE\\4aH00\\fscx67\\fscy66\\2cHFFFFFF\\3cH808080}你还好吧? 它从中吸取的解析器是 `@bundu/ui/markdown-parse`数字 : `markdownBlocks()`, (中文(简体) ), `safeHref()` 和块和内线类型, 对于代码需要树,而不是标记.
    
    ```astro
    ---
    import MarkdownRenderer from "@bundu/ui/MarkdownRenderer.astro";
    ---
    <MarkdownRenderer content={post.body} headingBase={2} />
    ```
    
-   **阴影 CVA + `cn()` 反应原始人** —— 说 `Button`, (中文(简体) ), `Card`, (中文(简体) ), `Badge`, (中文(简体) ), `Input`, (中文(简体) ), `Textarea`, (中文(简体) ), `Select`, (中文(简体) ), `Label`, (中文(简体) ), `Alert`, (中文(简体) ), `Avatar`, (中文(简体) ), `Separator`, (中文(简体) ), `Skeleton`, (中文(简体) ), `Switch`, (中文(简体) ), `Checkbox`, (中文(简体) ), `Tabs`, (中文(简体) ), `Tooltip`。 。 。 .
    
-   **整个Mzizi调色板** —— 说 `styles/tokens.css` 全部携带 **21个有色家庭** 在一个下 `--color-*` 命名空间:7个矿物,7个遗产色调,7个实验色调. 加九步地表梯(`--pitch`, (中文(简体) ), `--void`, (中文(简体) ), `--base`, (中文(简体) ), `--surface`, (中文(简体) ), `--container`, (中文(简体) ), `--overlay`, (中文(简体) ), `--raised`, (中文(简体) ), `--scrim`, (中文(简体) ), `--wash`)和连通性 状态三进制( r)`--syncing`, (中文(简体) ), `--offline`, (中文(简体) ), `--neutral`) (中文(简体) ).
    
-   **尾风 v3 和 v4** —— 说 `styles/theme.css` 是一个本地 v4 `@theme` 入场点; `tailwind-preset.mjs` 是 v3- 形状的预设, 仍在发运并仍在工作( v4 载重) 它穿过 `@config`) (中文(简体) ).
    
-   **品牌覆盖** —— 说 `brand-bundu`, (中文(简体) ), `brand-nyuchi`, (中文(简体) ), `brand-mukoko`, (中文(简体) ), `brand-shamwari`, (中文(简体) ), `brand-mzizi`和子应用程序 `brand-events` (木科克事件), `brand-lingo`, (中文(简体) ), `brand-bushtrade`, (中文(简体) ), `brand-campfire`, (中文(简体) ), `brand-news`, (中文(简体) ), `brand-weather`, (中文(简体) ), `brand-kweli`, (中文(简体) ), `brand-learning` 财务报告和审定财务报表 `brand-circles` (木科克圆. `brand-nhimbe` 是再出口的已贬值的别名 `brand-events` (nhimbe品牌已退役;事件平台为Mukoko事件). 每个重点 `--primary` 财务报告和审定财务报表 `--ring` 矿物质来自 克能生态系统表. `brand-circles` 另设 `--brand-accent` (特拉科塔语), 哪个牌子的手杖排着一个口音.
    
-   **`tokens.json`** ——机器可读值相同,包括每个自定义属性 对于完全无法消耗 CSS 的表面, 解为每个模式的字面六进制 : 博览会( E)`mukoko-weather-mobile`)和以佐藤里为主的OG-图像/电子邮件/PDF生成器.
    

## 生成, 不转录

`styles/tokens.css`, (中文(简体) ), `styles/theme.css`, (中文(简体) ), `tokens.json`, (中文(简体) ), `tailwind-palette.mjs` 和每个 `styles/brand-*.css` 为: **生成** 以 `scripts/generate-tokens.mjs` 从 `tokens/canon.snapshot.json`,它本身是机器写 `scripts/fetch-canon.mjs` 从划道上 :

| 来源 | 用品 |
| --- | --- |
| `https://api.mzizi.dev/api/v1/brand` | 21个家庭,语义符号,背景阶梯,光线,品牌-矿表 |
| `mzizi-dev/mzizi-registry` → `lib/tokens/palette.source.ts` | 矿物 `onContainer` 成对, 哪个 `/v1/brand` 不预测 |

两人在每逢交接的时候,都要互相考核。如果他们对一击有分歧, 获取失败 而不是默默地偏爱它。 这种分歧就是遗产 最后是四个不同的地铁.

十六进制值 **没有** 生活在数据库中。 Mzizi没有品牌或原始的象征数据 在Supabase或其他任何地方——0.1.1's `tokens.css` 信头说错了.

三道城门,都不得空出:

| 命令 | 网络 | 运行 | 失败的时间 |
| --- | --- | --- | --- |
| `pnpm tokens:check` | 没有 | 每一个CI工作, `prepack` | 生成的文件与生成器不一致 |
| `pnpm canon:parity` | 对 | **仅CI** | 承诺的快照已经从活的峡谷飘来飘去 |
| `pnpm canon:fetch` | 对 | 需求 | aPI和 `palette.source.ts` 异议 |

`canon:parity` 拒绝在CI以外运行 `--force`因此它不能爬入建筑物 或运行时路径。 手机回家制作一个页面的标志性软件包是一页 aPI的下午是空白的,情况不妙.

每个值都通过 CSS 自定义属性来流动 / Tailwind sords —— **从来没有生六分之一英寸 来源**。 。 。 .

## 安装

```sh
pnpm add @bundu/ui
# peer deps (for the React primitives)
pnpm add react react-dom
```

## 快速使用

**1a. 尾风v4(建议)** - 一个样式表,没有 `tailwind.config.mjs` 完全没有:

```css
@import "tailwindcss";
@import "@bundu/ui/styles/theme.css"; /* @imports tokens.css, adds @theme */
@import "@bundu/ui/styles/globals.css"; /* the @layer rules the Astro components use, and density.css */
@import "@bundu/ui/styles/color-scheme.css"; /* optional: follow the OS dark setting */
@import "@bundu/ui/styles/brand-nyuchi.css";
@source "../../node_modules/@bundu/ui/src"; /* v4 does not scan node_modules itself */
```

`color-scheme.css` 选择进入. `tokens.css` 只变暗 `.dark` 或者说 `[data-theme="dark"]`,此文件在 `prefers-color-scheme: dark`,用于没有主题脚本的网站。 明确 `data-theme="light"` 仍然赢了。 在品牌覆盖前导入.

`theme.css` 搭载调色板、类型比例(`text-display` . `text-caption`页:1 读取宽度( r)`max-w-narrow`和命名的间隔,所以 `globals.css`是因为 `@apply` 规则 而组件的类解而无预设。 尾风进口 `tokens.css` 一次 尽管两个文件都提到它。 Astro组件使反应原生 (例如 `Hero`按钮,所以一个Astro网站也需要 `@astrojs/react`没有 `client:*` 他们向静态 HTML 提供指令, 并且没有JavaScript .

**平地和密度.** `globals.css` 进口 `styles/density.css`从 登记:正文文本 17px, 标题 14px, 每个控件上的49px击出区域( 控件可能 在桌面密度下绘制 28-40px,以及 a `hit-area` 覆盖保持49px命中区域, 以及作为公用事业的部件的作用大小(`h-control`, (中文(简体) ), `h-control-sm`, (中文(简体) ), `h-control-lg`, (中文(简体) ), `size-control-icon`, (中文(简体) ), `h-field`, (中文(简体) ), `min-h-touch-min`) (中文(简体) ). 这些公用设施解决了 没有它,什么都没有。 将棋子分别导入的应用程序( Q)`theme.css` 财务报告和审定财务报表 `tokens.css`,没有 `globals.css`必须在其后面加上:

```css
@import "@bundu/ui/styles/theme.css";
@import "@bundu/ui/styles/density.css";
```

`<html data-mzizi-sizes="legacy">` 恢复地板前的尺寸( 16px 身体, 12px) 标题, 48/ 56px 控件), 直到一个应用程序迁移 。 移民表:mzizi-注册 `docs/sizes-and-density.md`。 。 。 .

**1b. 有尾风v3或v4通过 `@config`** - 与0.1.x不变,仍然支持:

```css
@import "tailwindcss";
@import "@bundu/ui/styles/tokens.css"; /* or globals.css for the @layer rules */
@import "@bundu/ui/styles/brand-nyuchi.css";
@config "../../tailwind.config.mjs";
```

```js
// tailwind.config.mjs
import preset from "@bundu/ui/tailwind-preset";

export default {
  presets: [preset],
  content: ["./src/**/*.{astro,html,js,jsx,md,mdx,ts,tsx,vue}"],
};
```

**2\. 浏览器外部** - 博览会、佐藤里会、PDF:

```js
import tokens from "@bundu/ui/tokens.json" with { type: "json" };

tokens.resolved.dark["--color-sodalite"]; // "#3d5afe"
tokens.color.heritage.savanna.dark; // "#e5c158"
tokens.surface.base.light; // "#f3f3f1"
```

**3\. 组件:**

```astro
---
import Hero from "@bundu/ui/Hero.astro";
import Container from "@bundu/ui/Container.astro";
import MineralStrip from "@bundu/ui/MineralStrip.astro";
import Breadcrumb from "@bundu/ui/Breadcrumb.astro";
import { deriveBreadcrumbs } from "@bundu/ui";

const crumbs = deriveBreadcrumbs(Astro.url.pathname, { about: "About" }, "Nyuchi");
---

<MineralStrip />
<Hero title="Build in the open" subtitle="Bundu Ecosystem" />
<Container>
  <Breadcrumb items={crumbs} origin={Astro.site?.toString()} />
</Container>
```

```tsx
import { Button } from "@bundu/ui/ui/button";
import { Alert, AlertTitle } from "@bundu/ui/ui/alert";

export function CTA() {
  return (
    <>
      <Alert variant="success">
        <AlertTitle>Saved</AlertTitle>
      </Alert>
      <Button variant="primary" href="/start" arrow>
        Get started
      </Button>
    </>
  );
}
```

## 英雄们

```astro
---
import Hero from "@bundu/ui/Hero.astro";
---

<!-- 0.1.x usage, unchanged: a single text column -->
<Hero
  title="Build in the open"
  subtitle="Bundu Ecosystem"
  description="One line that says what this is."
  primaryCTA={{ text: "Get started", href: "/start" }}
  secondaryCTA={{ text: "Read the docs", href: "https://docs.example.org", external: true }}
/>

<!-- Split: text beside a live demo at lg, stacked (text first) below it -->
<Hero
  layout="split"
  variant="showcase"
  badge="Beta"
  title="A short, bold headline"
  description="One line of subtext."
  primaryCTA={{ text: "Try it", href: "#demo" }}
  mediaLabel="Live demo"
>
  <div slot="media"><!-- your demo, screenshot or widget --></div>
</Hero>
```

| Prop | 类型 | 默认 | 页:1 |
| --- | --- | --- | --- |
| `title` | `string` | —— 说 | 这个 `h1`。 。 。 . |
| `subtitle` | `string` | —— 说 | 眉从头而上. |
| `description` | `string` | —— 说 | 分文一段. |
| `primaryCTA` | `{ text, href, external? }` | —— 说 | 药扣. |
| `secondaryCTA` | `{ text, href, external? }` | —— 说 | 以一箭为鬼扣. |
| `variant` | `"default" | "gradient" | "light" | "showcase"` | `"default"` | `showcase` 洗了这个牌子 `--primary` 和钴过 `--background`; 只有符号. |
| `align` | `"start" | "center"` | `"start"` |  |
| `layout` | `"stack" | "split"` | `"stack"` | `split` 设置文本和 `media` 位置并肩从 `lg`。 。 。 . |
| `badge` | `string` | —— 说 | 头条上面的状态药丸 它被理解为权利主张,所以要准确. |
| `mediaLabel` | `string` | —— 说 | 媒体区域无障碍名称(`role="group"`) (中文(简体) ). |
| `media` (分数) | 标记 | —— 说 | 文本列旁或下方的(分块). |

没有 `media` 插槽,没有 `badge`, (中文(简体) ), `layout` 左侧 `stack` 和一个0.1.x `variant`, (中文(简体) ), `Hero` 调制 **字节相同** 标记为0.1.1。 每一个建筑都检查过了 与公布的0.1.1 焦油球相配合.

见 [建 议.md](https://github.com/mzizi-dev/packages-npm/blob/main/packages/bundu-ui/BUILDING.md) 用于完整的工具链——mzizi MCP、shadcn CLI、 21个有色人种,和"无生克"规则.

## App图案 (0. 3. 0)

服务器为已登录的应用程序和控制台提供组件 `@bundu/ui/app/*`他们是 **纯天体**: 无反应( 或任何框架) 他们和没有客户JavaScript, 正如Mzizi学说有它为Astro。 过滤器 是获取表单, 调用是链接, 菜单是 `<details>`祝酒词被取消 带有隐藏复选框标签。 每个颜色都是一种标志, 所以光和暗 跟着 `tokens.css` 编号 : `color-scheme.css`。分类食谱与 反应原始人通过 `@bundu/ui/ui/variants`,所以两个建筑看起来都是一样的.

| 构成部分 | 它会做什么 |
| --- | --- |
| `AppShell.astro` | 粘性顶条( R)`brand`, (中文(简体) ), `account` 边栏导航 `lg` 和下面的披露, `main#main` |
| `SideNav.astro` | 附有标签和摘要的部分清单; `aria-current="page"` 关于当前项目; 48px目标 |
| `AccountMenu.astro` | 签名者、 账户动作的插槽( 外观窗体、 链接) 和签出 POST 格式 |
| `PageHeader.astro` | 这页是一页 `<h1>`描述,面包屑, `actions` 插槽 |
| `DataTable.astro` | 真实的 `<table>` 带有标题和范围标题; 窄屏幕上每行一张牌; 单元格是数据而不是标记 |
| `FilterBar.astro` | 搜索并选择过滤器为 a `role="search"` 获取窗体; 设置时“ 清除 ” |
| `Pagination.astro` | "显示112的26-50"和上个,编号和下个链接;当一个页面足够时隐藏 |
| `DetailPanel.astro` | 一个记录作为描述列表,一个可选的"全面记录"JSON披露,一个 `actions` 插槽 |
| `FormLayout.astro` | 有标题的表单卡;卡宽时分出两个栏(容器查询);表单级别提醒; `enctype` 用于文件 |
| `FormField.astro` | 可见标签和一个输入(文本、数字、日期、文件.)、文本区域或选择,并带有提示和有线错误 `aria-describedby` 财务报告和审定财务报表 `aria-invalid`· ; `wide` 横跨两列 |
| `StateMessage.astro` | 空、 出错、 不配置、 不可用和装入( skeleton) 有固定措辞的状态 |
| `Toast.astro` | 最后一项行动的结果是:一个有礼貌的居住区;在被解雇之前继续居住(WCAG 2.2.3) |
| `StatTile.astro` | A 中的一个标题图 `<dl>`: 标签, 值 ("不可用", 从不可用 0) 以文字写成的趋势 |
| `BarChart.astro` | 列或行为 SVG, 标题 `<figure>`,从不拥挤的轴线标签,以及披露下真实表格中的确切数字 |
| `Button.astro` | `<a>` 与 `href`,则 `<button>`· ; `appButtonVariants`,包含. `destructive` 财务报告和审定财务报表 `destructive-outline` |
| `Badge.astro` | Mzizi登记册 `badge` 合同: `default`, (中文(简体) ), `secondary`, (中文(简体) ), `destructive`, (中文(简体) ), `outline`, (中文(简体) ), `ghost`, (中文(简体) ), `link` |
| `Card.astro`, (中文(简体) ), `Alert.astro`, (中文(简体) ), `Input.astro`, (中文(简体) ), `Label.astro`, (中文(简体) ), `Skeleton.astro` | 这些原始的图案都是由纯洁的Astro建造的 |

`@bundu/ui/lib/table` 以纯洁的助手为后盾 `DataTable`, (中文(简体) ), `FilterBar` 财务报告和审定财务报表 `Pagination`数字 : `parseTableQuery` (URL ) 查询,被夹住), `filterRows` (每个字, 大小写和重音不敏感,加上精确匹配的过滤器), `paginate` 财务报告和审定财务报表 `withParams`。 。 。 .

```astro
---
import AppShell from "@bundu/ui/app/AppShell.astro";
import SideNav from "@bundu/ui/app/SideNav.astro";
import AccountMenu from "@bundu/ui/app/AccountMenu.astro";
import PageHeader from "@bundu/ui/app/PageHeader.astro";
import FilterBar from "@bundu/ui/app/FilterBar.astro";
import DataTable from "@bundu/ui/app/DataTable.astro";
import Pagination from "@bundu/ui/app/Pagination.astro";
import { filterRows, paginate, parseTableQuery, withParams } from "@bundu/ui/lib/table";

const query = parseTableQuery(Astro.url.searchParams, ["role"]);
const rows = filterRows(people, query, (p) => [p.name], (p, f) => (f === "role" ? p.role : null));
const page = paginate(rows, query.page, query.perPage);
---

<AppShell>
  <a slot="brand" href="/">Your app</a>
  <AccountMenu slot="account" name="Tendai Moyo" email="tendai@example.com" signOutAction="/auth/logout" />
  <SideNav slot="nav" items={[{ href: "/people", label: "People", summary: "Everyone in your family" }]} />

  <PageHeader title="People" description="Everyone in your family." />
  <FilterBar searchLabel="Search people" q={query.q} values={query.filters} clearHref={withParams(Astro.url, { q: null, role: null, page: null })} />
  <DataTable
    caption={`People, ${page.total} in all`}
    columns={[{ key: "name", label: "Name" }, { key: "role", label: "Role" }]}
    rows={page.rows.map((p) => ({ name: { text: p.name, href: `/people/${p.id}` }, role: { text: p.role, badge: "outline" } }))}
  />
  <Pagination url={Astro.url} {...page} noun="people" />
</AppShell>
```

他们只需要Astro和Tailwind v4 上面的设置,包括 `@source` 线条可以生成软件包中的类. `BarChart` 大小其条 作为 SVG 几何, 绝不内置 `style`因此,内容-安全政策不需要 `style-src-attr 'unsafe-inline'`。 。 。 .

`DataTable` 徽章( 符号)`{ text, badge }`)取注册徽章变体. 在此之前 0.3.0 控制台的拷贝使用了反应器的矿物变体 `Badge`· ; `primary` 还有 `default` 在这里。 记录下,一个牢房 `tone` (单位:千美元)`{ text, tone }`数字 : `neutral`, (中文(简体) ), `success`, (中文(简体) ), `warning`, (中文(简体) ), `info`, (中文(简体) ), `accent`, (中文(简体) ), `premium`(中文(简体) ) 是一种状态药丸,使用固定状态颜色( p)`statusToneClasses` 内 `@bundu/ui/ui/variants`(三); `tone` 胜过 `badge`。 。 。 .

### 产品- Dash板外壳

应用图案制造出一个全宽的产品仪表板, 稠密的像一个 控制台,而不是像营销版那样的客房.

| 构成部分 | 它会做什么 |
| --- | --- |
| `AppShell.astro` | 整个取景口:一个固定的16.25雷姆侧边栏(`workspace`, (中文(简体) ), `search`, (中文(简体) ), `nav` 插槽,从下方切入一个倒塌的切换)和填充其余部分的主柱(一个薄的上边栏 `brand`, (中文(简体) ), `actions`, (中文(简体) ), `account`; 页面; `footerLinks` 编号 : `footer`) (中文(简体) ). 没有以页为中心的容器 。 折叠到3.5rem图标栏上(真正的复选框); `collapsed` 财务报告和审定财务报表 `persist` 保持整个页面。 64rem下方的侧边栏为一出出坎瓦斯抽屉:与波波弗API弹出式相同元素,因此"逃出"并点击外侧关闭. `overlay` a 时段 `CommandPalette` |
| `SideNav.astro` | `groups` (或0.3平方英尺) `items`),每个项目的一个图标, `badge` ("新"),被嵌入项在切夫龙披露下(当孩子是当前时打开),当下项被填入一金指标. **仅标签**: 一个物品 `description` 是一个关于悬浮和键盘焦点及其 `aria-describedby`;在倒塌的栏杆上,工具提示也显示标签 |
| `WorkspaceSwitcher.astro` | 产品标记( :`mark` a) 用于当前工作空间 `<details>` 工作空间和链接的列表,或当没有可切换到的纯链接主机 |
| `QuickSearch.astro` + 键 `CommandPalette.astro` | 侧边栏的搜索按钮带有QQ提示打开调色板(`popovertarget`: 每一个导航项,分组,作为链接,并与 `action` a 服务器的搜索表单 |
| `TopBarAction.astro` | 上行的图标和标签链接或按钮 (“ Ask AI ” 、“ 支持 ” ); 图标仅下方 `sm` 以标签为名称 |
| `Toolbar.astro` + 键 `ToolbarMenu.astro` | 一个全宽的 GET 搜索框加入按钮组; `ToolbarMenu` 是一个 `<details>` 链接列表( 日期范围) |
| `StatTiles.astro` | 相邻一行等同 `StatTile`有发线分接器; `StatTile` 收益 `info` |
| `InfoTip.astro` | 可聚焦信息图标,其工具提示是其可访问描述 |
| `EmptyState.astro` | 相接卡:一个标题、帮助文本和动作; `StateMessage kind="empty"` 用这个 |
| `BrandMark.astro` | 克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克`brand="mukoko"`, 蜂窝: Mzizi 注册处的光/暗图标对对, 缩放, 永不重画, 小写 sarif wordmark 和 当被问及时的哑音后缀; CSS 每个主题的右变体 |

`@bundu/ui/app/nav` 纯洁的助手们 `groupNav` 转弯 平面单行登记`group`, (中文(简体) ), `parent`(一) 成群结队; `currentHref` 选择最长的匹配格里夫; `searchNav` 编号 : `matchesQuery` 匹配每一个字,大小写和重音不敏感.

**密度.** `Button`, (中文(简体) ), `Input`, (中文(简体) ), `FilterBar`, (中文(简体) ), `DataTable`, (中文(简体) ), `Pagination`, (中文(简体) ), `DetailPanel`, (中文(简体) ), `FormLayout`, (中文(简体) ), `PageHeader` 财务报告和审定财务报表 `StatTile` 使用应用程序密度 (单位:千美元)`appButtonVariants`, (中文(简体) ), `appInputClasses` 内 `@bundu/ui/ui/variants`: 36px (英语) 控件, 14px文本和~40px表格行带有精细指针; 44–48px目标 和 16px 触摸输入 (`pointer-coarse:`) (中文(简体) ). 内向 `AppShell` 使用该 身体圣贤。 营销原始人不变.

**文选.** 两个组件各带一个小模块,两个组件均不工作 内容: `AppShell` (它写着崩溃的选择) `persist` 饼干和酒 逃脱隐藏工具提示)和 `CommandPalette` (QQK / Ctrl+K 快捷键, 实时) 使用已宣布的计数、 Enter 和箭头键过滤 。 键盘 cSS 无法进行快捷键和活过滤。 Astro把它们装作文件, 这样 `script-src 'self'` 如果应用程序不内入小脚本, CSP 将有效 (一组) `vite.build.assetsInlineLimit: 0`) (中文(简体) ).

```astro
---
import AppShell from "@bundu/ui/app/AppShell.astro";
import BrandMark from "@bundu/ui/app/BrandMark.astro";
import CommandPalette from "@bundu/ui/app/CommandPalette.astro";
import QuickSearch from "@bundu/ui/app/QuickSearch.astro";
import SideNav from "@bundu/ui/app/SideNav.astro";
import TopBarAction from "@bundu/ui/app/TopBarAction.astro";
import WorkspaceSwitcher from "@bundu/ui/app/WorkspaceSwitcher.astro";
import { groupNav } from "@bundu/ui/app/nav";

const groups = groupNav(
  [
    { href: "/", label: "Home", icon: "home" },
    { href: "/people", label: "People", icon: "users", group: "Identity & people", description: "Everyone in your organisation" },
    { href: "/keys", label: "API keys", group: "Developer", parent: "/dev" },
    { href: "/dev", label: "Developer", icon: "terminal", group: "Developer" },
  ],
  ["Identity & people", "Developer"],
);
---

<AppShell collapsed={Astro.cookies.get("sidebar")?.value === "collapsed"} persist="sidebar" footerLinks={[{ label: "Status", href: "https://status.example" }]}>
  <WorkspaceSwitcher slot="workspace" name="Nyuchi Africa" href="/"><BrandMark slot="mark" wordmark suffix="console" /></WorkspaceSwitcher>
  <QuickSearch slot="search" target="palette" />
  <SideNav slot="nav" groups={groups} />
  <TopBarAction slot="actions" label="Support" icon="help" href="/support" />
  <slot />
  <CommandPalette slot="overlay" id="palette" groups={groups} action="/search" />
</AppShell>
```

## 发现模式(Mzizi 发现标准)

Mukoko家族的每个公开发现和浏览页面都有一个设计: 网络上的超级应用 纯Astro,没有 客户端JavaScript,没有内置样式. 11个构成部分 `@bundu/ui/discover/*`数字 :

| 构成部分 | 这是什么 |
| --- | --- |
| `DiscoverShell` | 跳过链接,矿物条,头条(品牌,主导航,一个动作), `<main id="main">`页脚 |
| `DiscoverMeta` | `<head>` 标记:标题、机器人、犬科、开放图形、X卡、JSON-LD |
| `DiscoverHero` | 面包屑,眉毛,那个 `<h1>`,引导,然后 `search` 财务报告和审定财务报表 `actions` 插槽 |
| `DiscoverSearch` | 获取搜索表单, 每个指针48px |
| `CategoryChips` | 命名导航 `CategoryChip` 连接 |
| `CategoryChip` | 与计数的一类联系; `current` 标记它 |
| `DiscoverSection` | 被命名的乐队:眉毛,取向,描述,"看见所有",内容 |
| `ResultGrid` | 状态行,牌,空状态和"再加载";布局 `grid`, (中文(简体) ), `list`, (中文(简体) ), `rail` |
| `DiscoverCard` | 一张牌,变型 `article`, (中文(简体) ), `event`, (中文(简体) ), `circle`, (中文(简体) ), `place`,分享一个解剖学 |
| `LoadMore` | 光标标记: 1 `rel="next"` 链接到 `?cursor=…` |
| `OpenInApp` | “在Mukoko打开”动作: https链接和一条线 |

```astro
---
import DiscoverShell from "@bundu/ui/discover/DiscoverShell.astro";
import DiscoverHero from "@bundu/ui/discover/DiscoverHero.astro";
import DiscoverSearch from "@bundu/ui/discover/DiscoverSearch.astro";
import DiscoverSection from "@bundu/ui/discover/DiscoverSection.astro";
import ResultGrid from "@bundu/ui/discover/ResultGrid.astro";
import DiscoverCard from "@bundu/ui/discover/DiscoverCard.astro";
import LoadMore from "@bundu/ui/discover/LoadMore.astro";
---
<DiscoverShell homeLabel="mukoko circles, home" nav={[{ label: "All circles", href: "/circles" }]}>
  <span slot="brand">mukoko circles</span>
  <DiscoverHero size="home" eyebrow="Mukoko Circles" title="Find your people.">
    <DiscoverSearch slot="search" label="Search circles" />
  </DiscoverHero>
  <DiscoverSection id="featured" title="Circles worth joining" seeAllHref="/circles">
    <ResultGrid label="Featured circles" summary={`${circles.length} circles`}>
      {circles.map((c) => <DiscoverCard variant="circle" href={c.href} title={c.name} initial={c.name[0]} meta={[c.members]} />)}
      <LoadMore slot="more" href={next} label="More circles" />
    </ResultGrid>
  </DiscoverSection>
</DiscoverShell>
```

尾风必须看到组件的类: 加 `@source "../../node_modules/@bundu/ui/src";` (您 CSS 文件的路径) 之后 `@bundu/ui` 进口.

**服务器装满了贝壳 .** 每个发现组件在页面出现时也会工作 使用 `{{placeholders}}` 并有一个服务器填充(作为圆.mukoko.). 连锁店 Rust Worker确实如此:文本道具是纯字符串,空文本隐藏自己 状态开关( t)`ResultGrid state`, (中文(简体) ), `LoadMore state`, (中文(简体) ), `DiscoverCard badgeTone`, (中文(简体) ), `CategoryChip current`)是按类排序的属性,所以模板需要 没有逻辑.

## 构成部分合同

每个应用程序和发现器组件都带有合同,就像Mzizi建造的所有设备一样。 这个 合同由Mzizi登记处撰写 (单位:千美元)[`mzizi-dev/mzizi-registry`, (中文(简体) ), `contracts/`](https://github.com/mzizi-dev/mzizi-registry/tree/main/contracts)(中文(简体) ) 并在此发送, 每个组件一个 JSON 文件 :

```js
import contract from "@bundu/ui/contracts/app/side-nav.contract.json" with { type: "json" };
```

每个都说明部件的道具和插槽的类型、行为和命名 状态、可获取性(作用、键盘、焦点、ARIA),精度和密度 粗指针, 主题( 仅覆盖品牌符号; 布局从未因 (b) 无JavaScript的倒置和反应规则,加上 `contract … end` block 在Mzizi语言的条款语法中。 计划是 `@bundu/ui/contracts/schema/component-contract.schema.json`。 。 。 .

`src/app/contracts.test.ts` 使每个指定状态的每个组件 评估其合同:条款、选择器检查、密度表和 品牌覆盖规则。 跑者不能评估的条款失败,同样失败 任意内行 `style` 属性( 一页的 CSP 从来不需要) `style-src-attr 'unsafe-inline'`) (中文(简体) ). `contracts/app/` 这是 **姆齐齐板 标准** 财务报告和审定财务报表 `contracts/discover/` 页:1 **Mzizi 发现标准** (docs.mzizi.dev) (英语).

**上游为先.** 应用程序需要的组件不在这里,或更改为 换句话说,你马上过来(和合同) 一个 应用程序仅在 PR 打开、标记时保存本地副本 `TODO(mzizi): <PR URL>`。 。 。 .

不编辑 `contracts/` 在这里。 那就换个登记册吧 `pnpm contracts:fetch` (或 `pnpm contracts:check [ref]` 比较).

## 许可证

[麻省理工学院](https://github.com/mzizi-dev/packages-npm/blob/main/LICENSE) Nyuchi非洲(Pvt)有限公司.

## 常见问题

### @bundu/ui 是什么？

Bundu生态系统的营销UI工具包——Nyuchi实施Mzizi设计系统\. 所有21个Mzizi彩色家族\(7个矿物、7个遗产、7个实验性\)在一个 -- -- 彩色\*命名空间、9步地表梯子、连接状态t

### 如何安装 @bundu/ui？

在项目目录运行 npm install @bundu/ui，或使用 pnpm add / yarn add / bun add。

### @bundu/ui 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @bundu/ui 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @bundu/ui 可以商用吗？

@bundu/ui 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @bundu/ui 的下载量有多少？

根据 npm 官方下载统计，@bundu/ui 在 2026/10/09 – 2026/11/07 这 30 天内被下载 3,735 次，日均约 125 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bundu/ui 还在维护吗？

最新版本 0\.13\.0 发布于 2026/11/05（3 天前）；至今共发布 14 个版本，其中过去 12 个月发布了 14 个；首次发布于 2026/07/03。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

