@charcuterie/logic

中文文档
2.12.0发布于 2026/11/02MITTypeScriptES Module构建来源已验证近 30 天下载 5835

Charcuterie的五种状态类型——能见度,能见度组,单接器,多接器,RovingFocus,和Status——作为带有React和Preact绑定的无框架核心.

中文使用文档
文档目录11 节
  1. @charcuterie/logic/query ——数据层
  2. 这五种
  3. useFlipList 也不是那种东西
  4. 形状
  5. 意向,注册,什么掉下来
  6. 存储注射
  7. 测试
  8. 什么是故意不在这里
  9. 优先布局
  10. 图表
  11. 压缩便携式图表预览

@charcuterie/logic

5个 Charcuterie 状态类型, 作为无框架核心与 React 19 和 Preact 装订。 没有组成部分——这些组成部分是: @charcuterie/ui (M3级).

@charcuterie/logic            React 19 binding (default entry)
@charcuterie/logic/core       framework-free factories, zero dependencies
@charcuterie/logic/preact     Preact binding (no preact/compat)
@charcuterie/logic/jotai      optional store adapter
@charcuterie/logic/signals    optional store adapter
@charcuterie/logic/query      request/response data layer (TanStack Query)
@charcuterie/logic/openapi    the typed HTTP seam, for a backend with an OpenAPI spec

@charcuterie/logic/query ——数据层

分舰队获取的方法之一: TanStack 查询缓存,默认为2 应用程序在它存在之前就已经调了.

import { QueryProvider } from "@charcuterie/logic/query"
import {
  createApiClient,
  createApiHooks,
} from "@charcuterie/logic/openapi"
import type { paths } from "./__generated__/api.gen.ts"

const fetchClient = createApiClient<paths>({ baseUrl: "/" })
export const api = createApiHooks(fetchClient)

const App = () => (
  <QueryProvider>
    <Jobs />
  </QueryProvider>
)

const Jobs = () => {
  // path, params, and response are all typed off the OpenAPI spec:
  const { data } = api.useQuery("get", "/jobs")
  return <JobList jobs={data ?? []} />
}

createQueryClient 保持反应-凯里自己的默认—— 继续尝试这样 层从一瞬间发光中恢复出来 深层会覆盖 A 类 希望申请失败的投票程序 没有 重试( 因为返回会 保留屏幕上的陈旧数据) 明确选择退出 : createQueryClient({ defaultOptions: { queries: { retry: false } } }) - 电话 夹克和棋盘游戏。 三个图书馆都是 选项 同行,以及 两个子路径选择不同的路径: ./query 仅需要 @tanstack/react-query,以及 ./openapi 添加 openapi-fetch + 键 openapi-react-query。不导入 OpenAPI 文件的应用程序 ./query 一个人 并安装两个 为什么他们分开 子路径。 。 。 .

这个 paths 类型来自后端的 OpenAPI 文档 openapi-typescript a. 与《公约》 .gen.ts 文档 Biome 和 ESLint 忽略——见 生成的系统 决定。 。 。 . 这是 请求/答复 层; RxJS 推动 层 (SSE/ WebSocket) 是单独的,未来的 @charcuterie/streams。 。 。 .

这五种

仁爱问它答案用于
createVisibility显示了吗?Modal、 Drawer、 Popover、 工具提示、 披露
createVisibilityGroup哪个 一个 显示吗 ?标签 协议 一个菜单的子菜单
createSinglePicker哪个 一个 被选中了吗?无线电、 选择、 分区控制
createMultiplePicker哪个 设定 被选中了吗?复选框组,多选择过滤器
createRovingFocus哪个是 选项卡? 吗?列表框、菜单、工具栏、标签列表
createStatus在哪个地方 生命周期? 吗?徽章、生活状况指示器、进步栏

后两个在v2中为新;参见 五种状态的决定。 。 。 . createLinkedIds 与众同坐 aria-controls 编号 : aria-labelledby 簿记——它没有出现用户状态,所以它不是第六种.

useFlipList 也不是那种东西

它完全没有状态。 它在承诺前读出布局 之后又读出 以变换方式回放差异——所以没有核心,没有商店,也没有预告 双胞胎保持步入正轨。 它住在反应入口 因为那里是它的两分之一 (渲染相测量,布局效果)必须坐.

const listRef = useFlipList({ signature: ids.join(",") })

<ul ref={listRef}>
  {ids.map((id) => <li data-flip-key={id} key={id}>…</li>)}
</ul>

两个应用程序独立地发展了它——队列飞行员的海报网格和Docket的相位 列表——这是它属于这里而不是属于其中任何一个的门槛. 时间和放松来自 --duration-normal 编号 : --easing-standard,所以重排顺序 移动的速度与周围的一切一样 prefers-reduced-motion 已经 已处理: @charcuterie/tokens 崩溃每个持续时间 0ms 里面的查询,和 钩子在零时提前返回.

形状

每个核心 { getState, subscribe, ...commands } 加纯选择器 :

import {
  createVisibilityGroup,
  selectIsKeyVisible,
} from "@charcuterie/logic/core"

const tabs = createVisibilityGroup()

const release = tabs.register("overview")

tabs.show("overview")

selectIsKeyVisible(tabs.getState(), "overview") // true

getState() 返回 a 只有在状态改变时其身份才会改变的被冻结对象。 。 。 . 这是负载的,而不是家务 useSyncExternalStore 重新放弃身份,所以 一个在每一个读数上重建其派生数组的核心将重新发送一个完整的列表框 - 在预告装订中,循环.

React and Preact 钩子将它固定在一个物体上:

const { register, show, visibleKey } = useVisibilityGroup()

他们是 无控制数字 : visibleKey 是一个初始值,并且 onChange 这是 观察出逃舱门 见 不受控制的决定。 。 。 .

意向,注册,什么掉下来

四家会员店 消费者要求的 并引导公众 回答 + 谁是当前挂载的 。 三个属性自由:

  • 成员挂起前设定的值不丢失 . 它停在 pendingKey编号 :pendingValue(s) 在登记时得到促进——这就是: 表单的初始值在选项中幸存.
  • 复挂圆通. 严格模式的双挂载, 路由更改, 虚拟化列表 卷出一行又一行——意向从未被抛弃,故复出 选中 .
  • 众生无常者从代表入正. "最能见者"为一地. " (中文(简体) )selectedValue 总是注册的选项或 null"是引出,不是规则六 命令必须记住.

登记为a 多集组合而不是一组。 两样东西都登记在同一个密钥上 而不是你猜想的,以一个平地,第一座升起的升起 生还者.

createRovingFocus 故意打破对称性: 重点 成员移动焦点在邻居身上,而不是停车,因为键盘 用户的行已消失 .

存储注射

import { createStoreFromJotai } from "@charcuterie/logic/jotai"

useVisibility({ createStore: createStoreFromJotai(jotaiStore) })

接缝有三名成员—— get, (中文(简体) ), set, (中文(简体) ), subscribe 默认是 20行的可观察参考文献,没有依赖性。 Jotai不是从属关系 存储注入决定。 。 。 .

测试

pnpm vitest run --project logic       # cores, node
pnpm vitest run --project logic-dom   # React + Preact bindings, chromium

src/conformance/ 持有 一个 基于模型的套件,与五个适配器相对应: 核心,核心过一个乔泰商店,核心过一个 @preact/signals-core 存储, 反应 装有19个 装有Preact的 快检查生成随机命令序列, 应用 每一个都给一个天真的参考模型 和一个真实的东西, 并声称之后 每个 步骤.

DOM 适配器挂载一个主机组件,使 null 重建项目 getState() 从 页:1 最后一次承诺 - 所以一个没有重新交代的绑定 读 stale and the 模型在下一个断言上抓住它.

因为一个不能失败的绿色套房

故意回归结果
多集 −平原 Set 内 registrations.ts15个核心属性失效
预录 useStoreValue 停止签名10 事前属性失败, 不受影响

沙盒纸条. 这个 logic-dom 项目需要铬建造。 代理集装箱 船舶浏览器 拥有 全球设置的 Playwright 属于根主 /opt/pw-browsers 和点 PLAYWRIGHT_BROWSERS_PATH 在这里。 截止2026-08-24年 目录持有铬 第1234条 这回波的剧作家想要 第1234条,所以运行 双方同意 巧合而来而不是设计。 双方 以自己的时间表行动, 舰队中的两个重机已经不同意.

当运行结束, 命名一个未在其中的建筑编号 /opt/pw-browsers,安装此选项 repo的建筑在可写的地方,而不是改变repo:

PLAYWRIGHT_BROWSERS_PATH=/tmp/pw-browsers pnpm playwright install chromium-headless-shell
PLAYWRIGHT_BROWSERS_PATH=/tmp/pw-browsers pnpm vitest run --project logic-dom

/tmp没有 $HOME/.cache/ms-playwright ——M2推荐这条路径,甚至是错误的 那麽. --dry-run 在安装打印上不下载精确的修订版.

⚠️ 永远不要碰这个包的 Playwright 来匹配容器,从不编辑 vitest.browser.config.ts 对于它。 被绑定的版本是 CI 安装什么 和什么 符合性套间对照衡量 从不报告浏览器套件无法运行 - 它运行的很好 在覆盖下; 说你使用了它。 长版本 : docs/runbooks/agent-sandbox-runtime.md 输入 agentic 工作空间.

什么是故意不在这里

浮起定位、抛出层、焦点陷阱、打字头、虚拟化和日期 逻辑 他们抵达M4 @floating-ui/react,这是 施工控制 —— 说 你通过状态, 它从来没有存储它,所以 VisibilityGroup 保持独主。 拉迪克丝, Base UI 和 Ark UI 都拥有 open 本身,这就是冲突 包存在到 避开.

优先布局

selectPriorityLayout 从 @charcuterie/logic/core 比较测量布局 候选人。 每节宣布一个数字 priority,分配数 width 财务报告和审定财务报表 height,可选最小维度,以及可选介质 aspectRatio。 。 。 . 所需内容首先适合;然后在降级时尽量扩大有用区域 优先秩序. idealArea 一旦区域有足够的空间,它就会盖上。 候选人 命令断开联系。 该功能是框架独立的; apps 拥有它们 测量、内容和渲染.

可选章节声明单独的数值 visibilityPriority 和候选人 可能标记它们 isHidden可见内容必须首先符合其最小维度. 在合适的候选人中,较高可见度的优先事项比较低者优先; 焦点 priority 然后用剩下的空间。 隐藏可选段落被消耗 没有最小的维度,也没有有用的领域。 奥米 visibilityPriority 用于控制等必要部分。 Apps列举了测量可见度状态; 选择者从不更改候选人或默片内容.

图表

@charcuterie/logic/charts 曝光共享的 TanStack 图表定义和独立的 SVG 渲染器 . /charts/react 财务报告和审定财务报表 /charts/preact 曝光 ChartPlot 用于本地框架表面,具有共性 ChartOptions,徘徊/touch/键盘交互,以及可选的减动-意识过渡. TanStack在α时被钉入0.1.8. 导入核心或已存在的绑定不会加载此引擎.

现有 renderChartSvg 内 /core 仍然是受限制客户的可移动倒数。 两个引擎都接受分组条,签名堆栈(barLayout: "stacked"、线条和无效样本。 诺尔是没有的,从零。 Apps 供应序列和标签; 没有引擎执行请求或计算报告数据.

压缩便携式图表预览

renderChartSvg 接受 isSparkline: true 中长期可见的小趋势 限制显示 。 通过预览 width 财务报告和审定财务报表 height; SVG 伸展 输入其容器时没有轴标签或密集点标记。 缺失值 仍然断线, 孤立的观测仍然可见, 负值仍然存在 在域中,标题和描述仍可访问。 完整图表保存 它们的默认演示文稿。 互动图外观继续渲染 详细情况; isSparkline 适用于便携式渲染器.

版本与发布记录

@charcuterie/logic 共发布 22 个版本,首次发布于 2026/07/31;过去 12 个月发布了 22 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.12.0latest2026/11/027 天前
2.11.02026/10/1623 天前
2.10.02026/10/051 个月前
2.9.02026/10/021 个月前
2.8.02026/10/021 个月前
2.7.02026/10/021 个月前

关于 @charcuterie/logic 的常见问题

@charcuterie/logic 是什么?

Charcuterie的五种状态类型——能见度,能见度组,单接器,多接器,RovingFocus,和Status——作为带有React和Preact绑定的无框架核心.

如何安装 @charcuterie/logic?

在项目目录运行 npm install @charcuterie/logic,或使用 pnpm add / yarn add / bun add。

@charcuterie/logic 支持 TypeScript 吗?

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

@charcuterie/logic 支持 ESM 还是 CommonJS?

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

@charcuterie/logic 可以商用吗?

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

@charcuterie/logic 的下载量有多少?

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

@charcuterie/logic 还在维护吗?

最新版本 2.12.0 发布于 2026/11/02(7 天前);至今共发布 22 个版本,其中过去 12 个月发布了 22 个;首次发布于 2026/07/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。