# @doany-ai/catalog 中文文档

规范地址：https://npmcn.com/package/%40doany-ai/catalog/

版本：0\.1\.6
npm 元数据更新时间：2026-10-29T10:42:18.316Z
中文译文更新时间：2026-11-14T10:43:49.548Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40doany-ai/catalog
原文对照：https://npmcn.com/package/%40doany-ai/catalog/?lang=original

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

- 包体积（解压后）：90.9 kB，26 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：react ^18\.2\.0 \|\| ^19\.0\.0，react-dom ^18\.2\.0 \|\| ^19\.0\.0，@doany-ai/sdk ^0\.3\.0-alpha\.0 \|\| ^0\.4\.0 \|\| ^0\.5\.0，@doany-ai/app-core ^0\.1\.8 \|\| ^0\.2\.0，@tanstack/react-query ^5\.0\.0
- 首次发布：2026-09-24T06:45:28.217Z
- 最新版本发布：2026-10-28T16:24:16.360Z
- 近 30 天下载量：2069（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：11（近 12 个月 11 个）

## 中文简介

企业在多尼站点销售什么:目录钩和默认组件(物品卡,网格,变种取取器,物品细节)

## 安装

```sh
npm install @doany-ai/catalog
```

也可以使用：`pnpm add @doany-ai/catalog`、`yarn add @doany-ai/catalog`、`bun add @doany-ai/catalog`

## README

# @doany-ai/目录

一个企业在它的网站上卖什么: 通过目录读取的钩子 给定 SDK 客户端 `@doany-ai/app-core`是因为 `<DoanyProvider>`默认值 一个站点可以通过主题重新样式,通过道具调整,或者 在保持钩子的同时替换.

网站只读目录. 出版的,可购买的,以及 价格是平台决定的;组件显示API的答案. 访问者只看到已公布的物品;网站列出自己的物品和那些 企业的每个地点都卖. 物品的添加和出售 代理商的业务工具, 从来没有从网站的代码.

需求 `@doany-ai/app-core` (单位:千美元)`DoanyProvider`)和一个客户端 `@doany-ai/sdk` 0.3.0-alpha.0 或更晚时. 它没有CSS: 地点的Tailwind 构建扫描(参见 `@doany-ai/app-core`) (中文(简体) ).

```jsx
import { CatalogGrid, CatalogItemDetail } from "@doany-ai/catalog";
import { BuyButton } from "@doany-ai/commerce";

<CatalogGrid
  params={{ purchasable: true }}
  hrefFor={(item) => `/services/${item.id}`}
  renderLink={({ href, className, children }) => <Link to={href} className={className}>{children}</Link>}
/>

<CatalogItemDetail
  itemId={id}
  actions={(variant, item) => variant && item.purchasable && <BuyButton items={[{ catalog_item_variant_id: variant.id }]}>Order now</BuyButton>}
/>
```

## 记录

-   `CatalogItem`数字 : `id`, (中文(简体) ), `kind` (单位:千美元)`service` 编号 : `physical` 编号 : `digital` 编号 : `plan` 编号 : `bundle`, (中文(简体) ), `status` (单位:千美元)`draft` 编号 : `active` 编号 : `paused` 编号 : `archived`, (中文(简体) ), `name`, (中文(简体) ), `description`, (中文(简体) ), `category`, (中文(简体) ), `image_url`, (中文(简体) ), `service_mode` (单位:千美元)`booking` 编号 : `order` 编号 : `inquiry`,或 `null` 当他未分类的时候, 选项 `payment_requirement` (单位:千美元)`none` 编号 : `full_online` 编号 : `null`, (中文(简体) ), `direct_purchase_enabled`, (中文(简体) ), `purchasable` (API决定网站资格), `sort_order`, (中文(简体) ), `variants` (按显示顺序排列). 这是在目录上标注之前 建造的工地的产物 `legacy_id` (那个网站的id知道它)和 `attributes` (字段为 网站在名称和价格之外保留,例如 `slug` 或者说 `color`和它一样 留着吧 两者都只读,和 `{}` 编号 : `null` 关于在《京都议定书》 目录.
-   `CatalogVariant`数字 : `id`, (中文(简体) ), `name`, (中文(简体) ), `price_amount` (整数,最小货币) 单位; `null` =没有价格, `0` =免费,可选 `compare_at_amount` (仅以同一种货币表示的参考价格), `currency`, (中文(简体) ), `duration_minutes`, (中文(简体) ), `is_default` (预选), `status`, (中文(简体) ), `sku`, (中文(简体) ), `sort_order`。 。 。 .

预订使用日历;调查需要确认引用. 他们的直接购买是 固定关闭。 订购服务有固定的直接购买,但收费网站 目前需要 `full_online`· ; `none` 可供商业订单使用. 零是免费的 `null` 谓无价相. 跟着API `purchasable` 结果.

过滤清晰的顺序服务 `params={{ service_mode: "order", purchasable: true }}` 或者说 `useCatalogItems({ service_mode: "order" })`服务查询表本身 没有命令或预约.

## 构成部分

每个组件都 `locale` (金钱;默认:浏览器的), `labels` 联合国 部分内容 `CatalogLabels`,见下文)和 `className`。 。 。 .

### `CatalogGrid`

网格中的卡片,并有加载,空出和出错的状态和"更多".

| Prop | 类型 |  |
| --- | --- | --- |
| `params` | `{ purchasable?, category?, kind?, type?, service_mode?, q?, sort?, limit? }` | 哪些项目. `sort`数字 : `sort_order` (违约), `name`, (中文(简体) ), `created_at`, (中文(简体) ), `updated_at`, (中文(简体) ), `-` 在前面为下降. `limit` 1 - 200, 默认50 |
| `hrefFor` | `(item) => string` | 每张卡片的链接 |
| `renderLink` | `({ href, className, children }) => ReactNode` | 链接如何显示; 平面 `<a>` 默认。 传路由器 `Link` 在网站上导航 |
| `onSelect` | `(item) => void` | 将每张牌变成按钮 |
| `renderItem` | `(item) => ReactNode` | 替换默认的牌 |
| `layout` | `"cards" | "list"` | 默认 `cards`:盖上,以自动柱为中心瓦片. `list`: 一栏全宽,包括加载占位符;无384px平板盖或小计数盖 |
| `footer` | `ReactNode | (item) => ReactNode` | 每张卡的价格 |
| `showDescription` | `boolean` |  |
| `appearance` | `"default" | "editorial" | "discovery" | "course"` | 默认:紧凑牌. 编辑:景观媒体和标题。 发现:大方形被子,无边形布局,完整标题/结果和突出的导航 CTA; 课程:16:9被子,以标题和描述为中心,紧凑以CTA为中心,默认没有价格或类别;软件包拥有所有布局 |
| `showPrice` | `boolean` | 默认 `true`; 在不更改 API 资格或选定变体的情况下隐藏显示的金额 |
| `media` | `ReactNode | (item) => ReactNode` | 用配置的网站媒体替换每张卡片的图像 |
| `mediaOverlay` | `ReactNode | (item) => ReactNode` | 对封面的独立预览控制, 在导航链接/按钮之外 |
| `formatLabel` | `ReactNode | (item) => ReactNode` | 提供Online 课程或 1:1 辅导等格式,与主题分开; 在已专门用于一种格式的列表中省略 |
| `accessLabel` | `ReactNode | (item) => ReactNode` | 提供访问/成员说明;保持可见 `showPrice={false}`仅列报,从未计算应享权利 |
| `eyebrow` | `ReactNode | (item) => ReactNode` | 替换类别行 |
| `actionLabel` | `string` | 每个链接/可选择的卡片内的导航提示; 发现时将其作为 CTA 文本( 默认为 `labels.viewItem`) (中文(简体) ). 这不是购买行动 |
| `empty` | `ReactNode` | 显示为无所售出。 默认: `empty` 标签 |

对于服务价格行或全宽特性,请选择 `layout="list"`。 。 。 . `renderItem` 单是刻意保持现有的卡片布局. 做一个 自定义行自己的列响应其可用的宽度,而不是屏幕 :

```jsx
<CatalogGrid layout="list" renderItem={(item) => (
  <article className="grid grid-cols-[repeat(auto-fit,minmax(min(100%,16rem),1fr))] gap-6 [&>*]:min-w-0">
    <div><h3>{item.name}</h3><p>{item.description}</p></div>
    <div><Price item={item} /><Button wrap asChild><Link to={`/services/${item.id}`}>Explore this service</Link></Button></div>
  </article>
)} />
```

`Price` 从 `@doany-ai/catalog`, (中文(简体) ), `Button` 从 `@doany-ai/app-core/ui/button`,以及 `Link` 从网站的路由器。 用同样的 价格表头和行的响应列定义; 在窄处 容器堆放单元格并显示其标签。 不要隐藏溢出到 隐藏被剪切的文本或动作.

### `CatalogItemCard`

图像、名称、类别、价格`From …` 当变量不同时)和持续时间.

| Prop | 类型 |  |
| --- | --- | --- |
| `item` | `CatalogItem` | 所需经费 |
| `href` | `string` | 让整张卡成为链接; 在发现时,只有明确的CTA是链接 |
| `onSelect` | `(item) => void` | 使整张卡成为按钮; 在发现时, 只有明确的 CTA 是按钮 |
| `renderLink`, (中文(简体) ), `footer`, (中文(简体) ), `showDescription` |  | 作为 `CatalogGrid` |
| `appearance`, (中文(简体) ), `showPrice`, (中文(简体) ), `media`, (中文(简体) ), `mediaOverlay`, (中文(简体) ), `formatLabel`, (中文(简体) ), `accessLabel`, (中文(简体) ), `eyebrow`, (中文(简体) ), `actionLabel` |  | 作为 `CatalogGrid` |

`media`, (中文(简体) ), `eyebrow`, (中文(简体) ), `formatLabel` 财务报告和审定财务报表 `accessLabel` 请坐 **内部** 全卡链接或 按钮。 保持它们不互动( 图像或哑音) 预览视频无控件). 单独的预览控件属于 `mediaOverlay`· ; 额外的播放/购买控制可以使用 `footer`。两个槽仍然处于导航之外. 默认和编辑上线与软件包的4:3和16:10媒体领域一致;自定义 媒体应保持这些比例。 发现使用一个平面覆盖和一个单独的CTA, 因此预览按钮永远无法激活课程链接. 其CTA包括项目名称 用于辅助技术。 一个交互式插槽需要自己的无障碍标签. 媒体配置和页面副本来自网站;可重复使用的卡片布局将保留 在这里。 这些档次不改变产品分类,准入或购买规则.

```jsx
<CatalogGrid
  appearance="editorial"
  showPrice={false}
  hrefFor={(item) => `/collections/${item.id}`}
  actionLabel="Explore collection"
  media={(item) => <img src={posters[item.id]} alt={item.name} />}
  footer={(item) => <button onClick={() => openPreview(item.id)}>Watch preview</button>}
/>
```

对于课程的发现,使用 `appearance="course"`:一个16:9的封面,以课程标题和描述为中心,以及一个紧凑的CTA. 显示一个 与细节页有明确的链接。 在此收藏中明确隐藏价格; 细节 报价保留其价格。 使用 `eyebrow=""` 以略去冗余的话题行,以及 `formatLabel` 只有在环境需要的时候 既不是这种外表,也不是隐藏 价格改变通用目录默认值,或决定某一物品是否可以购买.

```jsx
<CatalogGrid
  appearance="course"
  showPrice={false}
  eyebrow=""
  actionLabel="View course"
  hrefFor={(item) => `/courses/${item.id}`}
  media={(item) => <img src={posters[item.id]} alt="" />}
  mediaOverlay={(item) => <button onClick={() => openPreview(item.id)}>Preview<span className="sr-only"> {item.name}</span></button>}
  accessLabel={(item) => accessNotes[item.id]}
/>
```

出入说明书由场地从其核准的预测中提供 并不从产品类型、价格或浏览器本地状态推断成员.

### `CatalogItemDetail`

某物品的页面:图像,名称,描述,变种采取者和价格 选择的变体.

| Prop | 类型 |  |
| --- | --- | --- |
| `itemId` | `string` | 由id读取.. |
| `item` | `CatalogItem` | ...或显示为给定 |
| `actions` | `(variant | null, item) => ReactNode` | 备选案文:如何处理所选变式,例如a `BuyButton` |
| `variantId`, (中文(简体) ), `onVariantChange` | `string | null`, (中文(简体) ), `(variantId) => void` | 共享英雄/侧边栏/移动购买位置的可选控制选择;省略以保留本地选择。 缺少或不活跃的ID通过软件包的默认变量规则返回 |
| `notFound` | `ReactNode` | 项目不存在或未公布。 默认: `notAvailable` 标签 |
| `appearance` | `"default" | "editorial"` | 社论使用地貌媒体和显著标题,有相同的查询/选择/行动 |
| `media` | `ReactNode` | 替换项目图像; 由站点配置 |
| `showMedia` | `boolean` | 默认 `true`· ; `false` 删除整个媒体栏(包括自定义) `media` 和装入占位符),用于压缩摘要 |
| `headingLevel` | `1 | 2 | 3` | 默认 `1`; 当项目摘要位于现有页面标题下方时, 匹配页面的标题等级 |
| `eyebrow` | `ReactNode` | 替换类别行 |
| `showPrice` | `boolean` | 默认 `true`; 当错误时, 隐藏所选价格和取取出的数量; 选项和行动参数保持不变 |

在现场的英雄之下买东西 `<h1>`,使用时 `<CatalogItemDetail itemId={id} headingLevel={2} showMedia={false} actions={...} />`。 。 。 . 项目查询、价格变化选择和行动投入保持不变; 没有空图像列。 这个 `detail` 下面的道具示例运行此程序 由二级标题组成.

### `VariantPicker`

以收音机组为单位定价的活性变体;一件物品没有单向销售.

| Prop | 类型 |  |
| --- | --- | --- |
| `variants` | `CatalogVariant[]` | 所需经费 |
| `value` | `string | null` | 所选变体的 id |
| `onChange` | `(variantId) => void` | 所需经费 |
| `includeUnpriced` | `boolean` | 也提供无价变体(不能订购)。 默认 `false` |
| `label` | `string` | 屏幕阅读器; 胜过 `options` |
| `showPrice` | `boolean` | 默认 `true`; 仅演示文稿, 不允许非价格选择 |

### `Price`

`variant` (一价)或 `item` (一种价格,或 `From …` 当它的变体 差异); `fallback` 当无价(默认:无)时.

## 钩子

| 钩子 | 回返 |
| --- | --- |
| `useCatalogItems(params)` | 网站的项目,一个网页一次, `sort_order` 第一条: `items` (所有页阅读至今), `isLoading`, (中文(简体) ), `isError`, (中文(简体) ), `hasNextPage`, (中文(简体) ), `fetchNextPage()`。 。 。 . `params` 作为 `CatalogGrid` |
| `useCatalogItem(itemId)` | 查询; `data` 是其活动变量的项目 |
| `useVariantSelection(item, { value?, onChange? })` | `{ variant, select(variantId) }`:从项目的默认变体开始,跟随新项目;非项目的代号倒回默认. 可选可控输入在多个选项中共享一个选项 |

显示所使用的组件的帮助 : `itemPriceLabel(item, locale?, words?)`, (中文(简体) ), `variantPriceLabel(variant, locale?, words?)` (文本,或 `null` 当没有 价格, `formatDuration(minutes)` (单位:千美元)`1 h 30 min`, (中文(简体) ), `pricedVariants(item)`, (中文(简体) ), `defaultVariant(item)`。 。 。 . `catalogKeys` 是反应查询键,用于 无效 .

## 标签

组件显示的每个字 `CatalogLabels`组成部分参与 以物配主,以物配主,并传达给里面的人 它(一个网格取出它的牌,一个项页取出它的取出者). `defaultCatalogLabels` 持有默认值; `catalogLabels(partial)` 合并.

| 密钥 | 默认 |
| --- | --- |
| `free` | 免费 |
| `fromPrice` | `(price) => "From " + price` |
| `duration` | `(minutes) => "45 min"`, (中文(简体) ), `"1 h 30 min"` |
| `options` | 选项( 屏幕读取器) |
| `empty` | 这里还没有. |
| `loadError` | 无法装入目录 。 (除非设定,否则平台本身的信息会显示) |
| `tryAgain` | 再试一次 |
| `loadMore` | 装入更多 |
| `loadingMore` | 正在装入.. |
| `notAvailable` | 本项目不详. |
| `viewItem` | 查看细节( 发现 CTA; 明确 `actionLabel` 赢) |

## 自定义

停止第一级,即满足需要:

1.  **支助科**: 主题变量 `:root` (见 `@doany-ai/app-core`) (中文(简体) ).
    
2.  **道具**:上面的插槽和道具,以及 `labels` 每个字:
    
    ```jsx
    <CatalogGrid labels={{ loadMore: "Show more", free: "Complimentary", duration: (m) => `${m} minutes` }} />
    ```
    
3.  **钩子**: 将列表或项目页面建入 `useCatalogItems`, (中文(简体) ), `useCatalogItem` 财务报告和审定财务报表 `useVariantSelection`,与 `itemPriceLabel` 编号 : `variantPriceLabel` 价格问题.
    

从不编辑此软件包 `node_modules` 或将其来源复制到网站.

## 4个可循环用途

官方实例 `@doany-ai/catalog/examples`每个更改 构成部分有四种用法: `grid`, (中文(简体) ), `card`, (中文(简体) ), `detail`,以及 `picker`。 。 。 .

```jsx
import { CatalogExamples } from "@doany-ai/catalog/examples";

<CatalogExamples component="grid" mode="default" />
<CatalogExamples component="grid" mode="css" />
<CatalogExamples component="grid" mode="props" />
<CatalogExamples component="grid" mode="hook" />
```

-   `default`: 实际软件包组件及其查询/选择行为.
-   `css`: 相同的组件道具,并有一套被范围化的主题变量. 这些 示例中没有门户;一个真实的网站的全球主题属于 `:root`。 。 。 .
-   `props`:包自有的编辑外观,标签/相机和价格能见度.
-   `hook`: 使用明确的自定义标记 `useCatalogItems`, (中文(简体) ), `useCatalogItem` 财务报告和审定财务报表 `useVariantSelection`;格式化仍然使用软件包的价格帮助.

同样的4个卡/网格用法可以显示发现的演示:

```jsx
<CatalogExamples component="card" appearance="course" mode="default" />
<CatalogExamples component="card" appearance="course" mode="css" />
<CatalogExamples component="card" appearance="course" mode="props" />
<CatalogExamples component="card" appearance="course" mode="hook" />
```

默认和CSS只拥有相同的组件道具和记录. 支持添加一个 明确格式/访问注释和自定义 CTA; 仅用钩子构建接口 真正的目录查询。 每个发现实例都有单独的预览和视图 进程动作: 预览报告选定的本地样本, 不进行导航或 声称要演拖车 打电话者提供实际的媒体和玩家行为.

`onSelect(item)` 可以观察选择。 每个例子都有自己的地方 `DoanyProvider` 并查询缓存。 导出 `catalogExampleItems` 财务报告和审定财务报表 `createCatalogExampleClient(items?, pageSize = 2)` 并让预览作曲 一个提供者中的软件包组件。 客户端回复本地目录列表/ get, 支持显示的过滤器、名称排序和页码,并拒绝 账户/上载/移动能力 `EXAMPLE_ONLY`它从不叫 腾讯网. 这些说明性的数字记录没有建立Course API, 授权、订阅、下载交付或离职合同。 生产 页面使用网站真正的SDK客户端,而不是这个示例适配器.

## 开发

`npm run typecheck` 包含 `tests/sdk-contract.types.ts`真实的 `@doany-ai/sdk` 客户端( 来自 `../doany-sdk`)必须满足客户类型 软件包的呼叫,所以一个变更的SDK合同在这里失败,而不是在一个站点.

`CatalogItemDetail appearance="summary"` 使用紧凑的标题并默认隐藏长描述用于购买侧边栏和关闭动作. `showDescription` 可推翻演示文稿;选项选择、实际价格,以及 `actions(variant, item)` 保持同样的行为。 官方道具的例子表明了这种外观.

### 可选原价

`Price` 财务报告和审定财务报表 `CatalogItemDetail` 显示击穿 `compare_at_amount` 提供 按当前旁的目录 `price_amount`. 缺失/参考价格 只有当前价格。 项目价格范围没有参考价格,除非每个 定价的变种既分享金额又分享货币。 选择另一个变体更新 这两笔金额. `showCompareAt={false}` 隐藏引用; `labels.currentPrice` 财务报告和审定财务报表 `labels.originalPrice` 自定义屏幕阅读器措辞 。 命令和退房总是 使用情况 `price_amount`;参考金额从来不是收费或客户折扣.

所有四种用途都可用 `<CatalogExamples component="price" mode={mode} />`数字 : `default`,仅限主题 `css`,措辞 `props`,以及 `hook` 使用 `useCatalogItem`, (中文(简体) ), `useVariantSelection`, (中文(简体) ), `variantPriceLabel` 财务报告和审定财务报表 `compareAtPriceLabel` 与定制标记.

## 常见问题

### @doany-ai/catalog 是什么？

企业在多尼站点销售什么:目录钩和默认组件\(物品卡,网格,变种取取器,物品细节\)

### 如何安装 @doany-ai/catalog？

在项目目录运行 npm install @doany-ai/catalog，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（^18\.2\.0 \|\| ^19\.0\.0）、react-dom（^18\.2\.0 \|\| ^19\.0\.0）、@doany-ai/app-core（^0\.1\.8 \|\| ^0\.2\.0）、@tanstack/react-query（^5\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @doany-ai/catalog 支持 TypeScript 吗？

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

### @doany-ai/catalog 支持 ESM 还是 CommonJS？

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

### @doany-ai/catalog 可以商用吗？

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

### @doany-ai/catalog 的下载量有多少？

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

### @doany-ai/catalog 还在维护吗？

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

