@doany-ai/catalog

中文文档
0.1.6发布于 2026/10/29MITTypeScriptES Module近 30 天下载 2069

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

中文使用文档
文档目录13 节
  1. 记录
  2. 构成部分
  3. CatalogGrid
  4. CatalogItemCard
  5. CatalogItemDetail
  6. VariantPicker
  7. Price
  8. 钩子
  9. 标签
  10. 自定义
  11. 4个可循环用途
  12. 开发
  13. 可选原价

@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) (中文(简体) ).

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平板盖或小计数盖
footerReactNode | (item) => ReactNode每张卡的价格
showDescriptionboolean
appearance"default" | "editorial" | "discovery" | "course"默认:紧凑牌. 编辑:景观媒体和标题。 发现:大方形被子,无边形布局,完整标题/结果和突出的导航 CTA; 课程:16:9被子,以标题和描述为中心,紧凑以CTA为中心,默认没有价格或类别;软件包拥有所有布局
showPriceboolean默认 true; 在不更改 API 资格或选定变体的情况下隐藏显示的金额
mediaReactNode | (item) => ReactNode用配置的网站媒体替换每张卡片的图像
mediaOverlayReactNode | (item) => ReactNode对封面的独立预览控制, 在导航链接/按钮之外
formatLabelReactNode | (item) => ReactNode提供Online 课程或 1:1 辅导等格式,与主题分开; 在已专门用于一种格式的列表中省略
accessLabelReactNode | (item) => ReactNode提供访问/成员说明;保持可见 showPrice={false}仅列报,从未计算应享权利
eyebrowReactNode | (item) => ReactNode替换类别行
actionLabelstring每个链接/可选择的卡片内的导航提示; 发现时将其作为 CTA 文本( 默认为 labels.viewItem) (中文(简体) ). 这不是购买行动
emptyReactNode显示为无所售出。 默认: empty 标签

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

<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类型
itemCatalogItem所需经费
hrefstring让整张卡成为链接; 在发现时,只有明确的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包括项目名称 用于辅助技术。 一个交互式插槽需要自己的无障碍标签. 媒体配置和页面副本来自网站;可重复使用的卡片布局将保留 在这里。 这些档次不改变产品分类,准入或购买规则.

<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 只有在环境需要的时候 既不是这种外表,也不是隐藏 价格改变通用目录默认值,或决定某一物品是否可以购买.

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

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

VariantPicker

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

Prop类型
variantsCatalogVariant[]所需经费
valuestring | null所选变体的 id
onChange(variantId) => void所需经费
includeUnpricedboolean也提供无价变体(不能订购)。 默认 false
labelstring屏幕阅读器; 胜过 options
showPriceboolean默认 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 每个字:

    <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。 。 。 .

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个卡/网格用法可以显示发现的演示:

<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 共发布 11 个版本,首次发布于 2026/09/24;过去 12 个月发布了 11 个版本。

版本发布日期距今
0.1.6latest2026/10/2916 天前
0.1.52026/10/2322 天前
0.1.42026/10/2124 天前
0.1.32026/10/2124 天前
0.1.22026/10/2025 天前
0.1.12026/10/1926 天前

其他发布通道:alpha → 0.1.0-alpha.3。

关于 @doany-ai/catalog 的常见问题

@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 和提交记录判断。