@wisdomgarden/torque-knowledge 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,101 @@
1
+ WisdomGarden License
2
+ Version 1.0, September 2026
3
+
4
+ Copyright (c) 2026 WisdomGarden. All rights reserved.
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean WisdomGarden, the copyright owner of the Work.
14
+
15
+ "Work" shall mean the software made available under this License,
16
+ including its source code, object code, documentation, design assets,
17
+ and any accompanying files.
18
+
19
+ "You" shall mean an individual or Legal Entity exercising permissions
20
+ granted by this License.
21
+
22
+ "Authorized User" shall mean (a) WisdomGarden and its affiliates, and
23
+ (b) any Legal Entity that has entered into a valid commercial agreement
24
+ with WisdomGarden covering a WisdomGarden product, for the duration of
25
+ that agreement and solely in connection with that product.
26
+
27
+ 2. Grant of Copyright License.
28
+
29
+ Subject to the terms of this License, Licensor grants to each Authorized
30
+ User a non-exclusive, non-transferable, non-sublicensable, revocable,
31
+ royalty-free license to use, reproduce, and modify the Work, and to
32
+ incorporate the Work into products operated by or on behalf of that
33
+ Authorized User, solely for that purpose.
34
+
35
+ 3. Grant of Patent License.
36
+
37
+ Subject to the terms of this License, Licensor grants to each Authorized
38
+ User a non-exclusive, non-transferable, revocable, royalty-free patent
39
+ license to make and use the Work, limited to those patent claims
40
+ licensable by Licensor that are necessarily infringed by the Work alone.
41
+ If You institute patent litigation against any entity alleging that the
42
+ Work constitutes patent infringement, any license granted to You under
43
+ this License terminates as of the date such litigation is filed.
44
+
45
+ 4. Restrictions.
46
+
47
+ Except as expressly permitted by Section 2, You may not:
48
+
49
+ (a) use the Work if You are not an Authorized User;
50
+
51
+ (b) distribute, sublicense, sell, rent, or lease the Work, or any
52
+ derivative of it, to any third party;
53
+
54
+ (c) use the Work to build, operate, or offer a product that competes
55
+ with any WisdomGarden product; or
56
+
57
+ (d) remove or obscure any copyright, trademark, or other proprietary
58
+ notice contained in the Work.
59
+
60
+ The Work may be publicly downloadable from a package registry. Public
61
+ availability does not grant any license beyond what this document
62
+ states.
63
+
64
+ 5. Redistribution.
65
+
66
+ Redistribution of the Work as a standalone library is not permitted. An
67
+ Authorized User may deploy the Work as part of a product it operates,
68
+ provided the Work is not offered to third parties on its own.
69
+
70
+ 6. Trademarks.
71
+
72
+ This License does not grant permission to use the trade names,
73
+ trademarks, service marks, or product names of Licensor, including
74
+ "WisdomGarden" and "Torque Design", except as required for reasonable
75
+ and customary use in describing the origin of the Work.
76
+
77
+ 7. Disclaimer of Warranty.
78
+
79
+ THE WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
80
+ CONDITIONS OF ANY KIND, either express or implied, including, without
81
+ limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
82
+ MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely
83
+ responsible for determining the appropriateness of using the Work and
84
+ assume any risks associated with Your exercise of permissions under
85
+ this License.
86
+
87
+ 8. Limitation of Liability.
88
+
89
+ IN NO EVENT AND UNDER NO LEGAL THEORY SHALL LICENSOR BE LIABLE TO YOU
90
+ FOR DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
91
+ CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING AS A RESULT OF THIS
92
+ LICENSE OR OUT OF THE USE OR INABILITY TO USE THE WORK, even if
93
+ Licensor has been advised of the possibility of such damages.
94
+
95
+ 9. Termination.
96
+
97
+ This License terminates automatically if You breach any of its terms,
98
+ or when You cease to be an Authorized User. Upon termination You must
99
+ cease all use of the Work and destroy all copies in Your possession.
100
+
101
+ END OF TERMS AND CONDITIONS
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # @wisdomgarden/torque-knowledge
2
+
3
+ **这个包是给机器读的,不是给人读的。** 人读的组件文档在
4
+ [`@wisdomgarden/torque-doc`](../torque-doc)(文档站),组件本身在
5
+ [`@wisdomgarden/torque`](../torque)。
6
+
7
+ 它把组件库的知识打包成一个可发布、可版本寻址的 artifact,供两个消费端取用。
8
+ 包里不含任何运行时代码,**不要 `import` 它** —— 没有 `main` / `exports`,
9
+ 消费端是 `npm pack` 之后解包取文件。
10
+
11
+ ## 产物
12
+
13
+ | 文件 | 给谁 | 是什么 |
14
+ | --- | --- | --- |
15
+ | `dist/torque-components.md` | **diting**(`lms-web` 的 CI code review) | 选型决策树 + 可用组件全表 + 硬约束 + 禁止事项。带 diting 认的 frontmatter(单行 `keywords` / `globs`),解包进它的 `rule_dirs` 就能被召回 |
16
+ | `dist/components.db` | **`lms-web` 的本地 MCP** | SQLite 组件目录,`search_component()` 的数据源。44 个组件的导出名、英文描述、keywords 和完整 props |
17
+ | `dist/.meta.json` | CI / 下游漂移检测 | `{ knowledge, torque, generatedAt }` —— 这份知识是哪个版本、描述的又是哪个 torque 版本 |
18
+
19
+ ## 版本与 `@wisdomgarden/torque` 相互独立
20
+
21
+ 四个包各自独立版本号,这个包的 version **没有**和 `torque` 相等的义务 ——
22
+ `knowledge@0.2.0` 描述 `torque@0.1.5` 是完全正常的状态。
23
+
24
+ 下游取的是 `latest`(`npm pack @wisdomgarden/torque-knowledge@latest`),
25
+ 不经过 lockfile —— 因为把它装成 `devDependency` 会让 `lms-web` 的 base image
26
+ (1642 个包)在每次知识更新时重建,而这个包有时只改了几句描述。
27
+
28
+ 代价是版本对齐从「精确」降成「有窗口」,靠漂移检测兜住:`dist/.meta.json` 的
29
+ `torque` 字段记着这份知识描述的是哪个版本,下游拿它和自己装的 `torque` 比对。
30
+ **所以那个字段是必须的,不是锦上添花** —— 上游不落地 `.meta.json`,
31
+ 下游的漂移检测就是恒静默的,不报错也不会有人发现。
32
+
33
+ ## 构建
34
+
35
+ ```bash
36
+ pnpm --filter @wisdomgarden/torque-knowledge build
37
+ ```
38
+
39
+ `dist/` 是构建产物,不入库。仓库根的 `pnpm build` 会自动带上这个包。
40
+
41
+ ## 源与数据流
42
+
43
+ ```
44
+ packages/torque/src/index.ts ← 组件清单的唯一来源(不是 readdir)
45
+ packages/torque/src/components/*/readme.md ← 39 篇,props 和中文描述
46
+ packages/torque/src/provider/readme.md ← 第 40 篇
47
+ src/fallback.json ← 全部 44 个组件的英文描述(手工维护)
48
+ src/handwritten/*.md ← 人工提炼的正文片段
49
+
50
+ └──> scripts/gen.mjs ──> dist/
51
+ ```
52
+
53
+ 机械的部分(扫源码、解析 props、产 db 和组件全表)在 `gen.mjs` 里,每次 `pnpm build`
54
+ 都跑。需要判断力的部分(读懂 readme 提炼选型/约束、复核英文描述)在
55
+ `.claude/skills/torque-knowledge/` 这个 skill 里。
56
+
57
+ `scripts/check-changes.mjs` 是两者之间的闸门:
58
+
59
+ ```bash
60
+ node scripts/check-changes.mjs --check-only # 只问「有活吗」,不写缓存、不生成
61
+ node scripts/check-changes.mjs # 有变化就顺便重新生成
62
+ ```
63
+
64
+ 退出码是契约:`0` 有变化 / `1` 无变化 / `2` 有变化但生成失败。
65
+ `--check-only` 的意义是让调用方先判断要不要花一次 AI 调用 —— lms-web 实测 22 个生产日里
66
+ 有 21 天没活干。缓存在 `.cache/changes.json`(gitignore)。
67
+
68
+ `gen.mjs` 和 `check-changes.mjs` 共用 `scripts/lib/parse-barrel.mjs` 解析组件清单。
69
+ **别在任一个里重写一遍正则** —— 两份必然漂移,一个认得 `StickyBox` 另一个不认得,
70
+ 变更检测就会报出永远修不掉的假变化。
71
+
72
+ 几件容易踩的事,改 `gen.mjs` 前先看一眼:
73
+
74
+ - **组件清单从 barrel 推,不要 `readdir`。** `components/sticky-box.tsx` 是裸文件、
75
+ 没有目录也没有 readme,但公开导出 `StickyBox`;`_inner/` 则不该暴露。barrel 两个问题都没有。
76
+ - **`components.db` 的 schema 是硬契约。** `lms-web` 的 reader 按字段名取值,
77
+ 改了名那边静默返回 `undefined`,不会报错。
78
+ - **db 保持默认的 `DELETE` journal 模式,不要设 WAL。** WAL 标记会持久化进 db header,
79
+ 产物在只读目录下会直接打不开。
80
+ - **`torque-components.md` 的 frontmatter 是 diting 的硬契约**:`keywords` / `globs`
81
+ 必须单行逗号分隔(它用 `^keywords:\s*(.*?)$` 解析,多行 YAML 数组会静默变成空),
82
+ 且**不能**设 `alwaysApply: true`(那等于每次 review 都全量注入)。
83
+ - **`gen.mjs` 不写回 `src/fallback.json`。** 缺 entry 就报错退出,由人补。
84
+ 写回会让 `pnpm build` 变成改动被追踪源文件的操作。
85
+ - **不要给这个包加 npm 依赖。** 它会被解包进 CI 环境,只用 Node 内置模块。
86
+
87
+ ## 新增组件之后
88
+
89
+ 1. 在 `packages/torque/src/index.ts` 里导出它(`gen.mjs` 从这里认组件)
90
+ 2. 往 `src/fallback.json` 加一条**英文**的 `whenToUse` + `keywords` ——
91
+ 不加的话 `pnpm build` 会直接报错退出,并把建议的起手式打出来
92
+ 3. 组件有 readme 的话,props 会自动解析出来(表格或 `- \`name?: Type\`: 说明` 列表都认)
93
+ 4. 如果它带来了新的硬约束或禁止事项,补进 `src/handwritten/`
@@ -0,0 +1,5 @@
1
+ {
2
+ "knowledge": "0.1.2",
3
+ "torque": "0.1.2",
4
+ "generatedAt": "2026-09-16T14:28:56.156Z"
5
+ }
Binary file
@@ -0,0 +1,208 @@
1
+ ---
2
+ description: Torque UI component library — selection priority, available components, and hard constraints.
3
+ globs: src/**/*.{tsx,ts}
4
+ keywords: torque, component, ui, mantine, layout, button, icon-button, link-button, link-icon-button, tooltip, popover, drawer, bottom-drawer, modal, menu, message, notifications, alert, sticky-box, tag, tab, table, table-pagination, tree, tree-select, virtualized-tree-select, date-picker, filter, data-filter, base-input, form-wrapper, text-input, text-area, number-input, password-input, checkbox, radio, switch, select, multi-select, combobox, box, text, flex, group, stack, paper, unstyled-button, provider, iconbutton, linkbutton, linkiconbutton, bottomdrawer, messages, stickybox, tabs, tablepagination, treeselect, virtualizedtreeselect, datepicker, datafilter, baseinput, formitemwrapper, textinput, textarea, numberinput, passwordinput, multiselect, unstyledbutton, uiprovider
5
+ ---
6
+
7
+ # Torque UI 组件库
8
+
9
+ > 由 `@wisdomgarden/torque-knowledge@0.1.2` 生成,对应 `@wisdomgarden/torque@0.1.2`。
10
+ > 不要手改 —— 它是 npm 包解包出来的,下次装依赖就被覆盖。
11
+
12
+ ## 导入方式
13
+
14
+ 一切都从**包根**导出,没有子路径导入:
15
+
16
+ ```tsx
17
+ import { Button, Select, Stack, Text, messages, drawers } from '@wisdomgarden/torque';
18
+ ```
19
+
20
+ `@wisdomgarden/torque-icons` 的图标已在包根**再导出**,不要单独去装、去导。
21
+ `lms-web` 侧的 barrel `@/ui/base` 就是对本包的一层转发,两种写法等价。
22
+
23
+ 配置入口只有 `UiProvider` 一个,必须在 `'use client'` 边界内 —— 它接收组件引用,
24
+ Server Component 序列化不了。
25
+
26
+ ## 选型决策树
27
+
28
+ **优先级:`@wisdomgarden/torque` > `className` + Tailwind 自行扩展 > Mantine 兜底。**
29
+
30
+ **布局与文本**
31
+
32
+ | 需求 | 用 |
33
+ | --- | --- |
34
+ | 视觉表面(卡片 / 面板 / 弹窗内容区) | `Paper` |
35
+ | 水平排列 + 垂直居中(按钮组、标签行、工具栏) | `Group` |
36
+ | 垂直排列(表单字段、列表项、页面区块) | `Stack` |
37
+ | 要响应式换方向,或对齐方式不是前两者的默认值 | `Flex` |
38
+ | 不需要布局,只是替代裸 `<div>`(含响应式显隐) | `Box` |
39
+ | 文本:字号 / 字重 / 截断 / 语义标签 | `Text` |
40
+ | 自定义点击区(整卡可点、图片热区) | `UnstyledButton` |
41
+ | 有明确按钮样式变体 | `Button`;纯图标 `IconButton`;跳转 `LinkButton` / `LinkIconButton` |
42
+
43
+ `Box` 替代 `<div>`;`Text` 替代 `<span>` / `<p>`,用 `component` 选语义标签
44
+ (`h1`–`h6` / `p` / `span`);`UnstyledButton` 替代 `<button>`。
45
+ `Paper` 不参与布局 —— 内部要排版就在里面嵌 `Flex` / `Group` / `Stack`。
46
+
47
+ `Group` / `Stack` 是 `Flex` 的预设,只是默认值不同:`Group` = `align: center` +
48
+ `wrap` + `gap: md`;`Stack` = `align: stretch` + `nowrap` + `gap: md`;
49
+ `Flex` = `align: stretch` + `nowrap` + 无 gap。**默认值合适就别用 `Flex`。**
50
+
51
+ **下拉与选择** —— 标准表单字段用 `Select`(单选)/ `MultiSelect`(多选,值是
52
+ `string[]`);要自定义触发器外观或富选项内容(头像、标签)才用 `Combobox`;
53
+ 树形数据用 `TreeSelect`,大到需要虚拟滚动用 `VirtualizedTreeSelect`;
54
+ 纯筛选触发器(不是表单字段)用 `Filter` / `MultiFilter` / `IconFilter`;
55
+ **业务数据筛选区一律用 `DataFilter`**,哪怕当前只有一个筛选项。
56
+
57
+ **反馈与浮层** —— 一句话轻提示无交互用 `messages.showXxx()`;有标题 + 详情、带操作
58
+ 按钮或文本较长用 `notifications.showXxx()`;页面内常驻状态条用 `Alert`;
59
+ 侧边抽屉优先指令式 `drawers.open()`,需要复杂局部状态联动才用声明式 `<Drawer>`;
60
+ 移动端底部抽屉用 `BottomDrawer`(**只在移动端**);悬停提示 `Tooltip`;
61
+ 需要交互内容的浮层 `Popover`;操作菜单 `Menu`。
62
+
63
+ **多态(`component` prop)** —— 自建布局组件**只接受 HTML 标签字符串**,Server 和
64
+ Client Component 都安全。Mantine 的 `component={ReactComponent}` 只能在 Client
65
+ Component 里用(函数跨 Server/Client 边界无法序列化)。
66
+
67
+ ## 可用组件全表
68
+
69
+ 全部从 `@wisdomgarden/torque`(lms-web 侧是 `@/ui/base`)导出。
70
+ 完整 props 和完整描述查 `components.db`(MCP 的 `search_component()`),这里只给选型用的一句话。
71
+
72
+ | 组件 | 导出名 | 何时使用 |
73
+ | --- | --- | --- |
74
+ | button | `Button` | General-purpose button with multiple variants (primary,… |
75
+ | icon-button | `IconButton` | Icon-only button built on Button |
76
+ | link-button | `LinkButton` | Button-looking navigation component with native <a> sem… |
77
+ | link-icon-button | `LinkIconButton` | Icon-only navigation component with IconButton appearan… |
78
+ | tooltip | `Tooltip` | Hover tooltip for short contextual help text or to reve… |
79
+ | popover | `Popover`, `PopoverTarget`, `PopoverDropdown` | Floating popover component that displays content near a… |
80
+ | drawer | `Drawer`, `DrawerManager`, `drawers` | Side panel sliding in from the right by default, with a… |
81
+ | bottom-drawer | `BottomDrawer` | Bottom sheet that slides up from the bottom edge |
82
+ | modal | `Modal` | PC-side modal dialog with a custom header (title + clos… |
83
+ | menu | `Menu` | Responsive action menu |
84
+ | message | `messages` | Imperative lightweight toast shown top-center, auto-clo… |
85
+ | notifications | `notifications`, `Notification` | Imperative global notification popup shown top-right, a… |
86
+ | alert | `Alert`, `AlertSkeleton` | Inline status banner with built-in icon, semantic color… |
87
+ | sticky-box | `StickyBox` | Pin a block to the top or bottom of its nearest scroll… |
88
+ | tag | `Tag` | Compact label/badge for categorization, status, or meta… |
89
+ | tab | `Tabs`, `TabsTab`, `TabsList`, `TabsPanel` | Primary tab navigation with Tabs, TabsList, TabsPanel,… |
90
+ | table | `Table`, `TableSkeleton` | Data table with sortable columns, row selection, and a… |
91
+ | table-pagination | `TablePagination`, `Pagination`, `getPaginationRange` | Standard pagination bar for tables: page numbers, a per… |
92
+ | tree | `Tree` | Hierarchical tree component for displaying nested data… |
93
+ | tree-select | `TreeSelect` | Hierarchical tree selector with dropdown support, check… |
94
+ | virtualized-tree-select | `VirtualizedTreeSelect` | Virtualized hierarchical tree dropdown for selecting fr… |
95
+ | date-picker | `DatePicker`, `TimePicker`, `DateTimePicker`, `DateRangePicker` | Date and time selection components including DatePicker… |
96
+ | filter | `Filter`, `IconFilter`, `MultiFilter` | Filter triggers built on Select/MultiSelect that open a… |
97
+ | data-filter | `DataFilter` | The shared, business-agnostic container for data-filter… |
98
+ | base-input | `BaseInput`, `BaseInputTarget`, `BaseInputWrapper` | Foundation input component providing the base structure… |
99
+ | form-wrapper | `FormItemWrapper`, `FormItemWrapperDefaultsProvider`, `useFormItemWrapperDefaults` | Wrap a form field with a consistent label, helper text,… |
100
+ | text-input | `TextInput` | Standard single-line text input field |
101
+ | text-area | `TextArea` | Multi-line text input for longer free-form content such… |
102
+ | number-input | `NumberInput` | Numeric text field with increment/decrement stepper but… |
103
+ | password-input | `PasswordInput` | Password field with a show/hide visibility toggle |
104
+ | checkbox | `Checkbox` | Checkbox for a single boolean choice and CheckboxGroup… |
105
+ | radio | `Radio` | Radio button and RadioGroup for mutually exclusive sing… |
106
+ | switch | `Switch`, `SwitchGroup` | Toggle switch for a single boolean on/off setting |
107
+ | select | `Select` | Single-value dropdown selector |
108
+ | multi-select | `MultiSelect` | Multi-value selector rendered as an input field with se… |
109
+ | combobox | `Combobox`, `useCombobox`, `useComboboxContext` | Compound dropdown selection component with desktop Popo… |
110
+ | box | `Box` | The most basic layout primitive, a drop-in replacement… |
111
+ | text | `Text` | Text rendering primitive built on Box, adding font size… |
112
+ | flex | `Flex` | Generic flexbox container with full CSS flex control |
113
+ | group | `Group` | Horizontal row layout with default center alignment, wr… |
114
+ | stack | `Stack` | Vertical column layout with default stretch alignment a… |
115
+ | paper | `Paper` | Visual surface container (card/panel) with raised backg… |
116
+ | unstyled-button | `UnstyledButton` | Button without any default styling — a blank slate for… |
117
+ | provider | `UiProvider`, `UiContext`, `DefaultUiLink`, `useLocale` | UiProvider is the single configuration entry point for… |
118
+
119
+ ## 硬约束
120
+
121
+ 每一条都会**直接导致 bug 或规范违规**,不是风格偏好。来源是各组件 readme 的
122
+ 「AI 编码最佳实践 & 注意事项」。
123
+
124
+ ### 表单
125
+
126
+ - **传了 `form` + `fieldName` 就不要再传 `value` / `onChange` / `error`**,组件会从
127
+ `form.getInputProps` 自己取,两边都传会互相覆盖。(`TextInput` / `TextArea` /
128
+ `NumberInput` / `DatePicker` 系列 / `TreeSelect`)
129
+ - **表单控件已内置 `FormItemWrapper`**,外面不要再包 `Field` / `Form.Item`,
130
+ `DataFilter` 里的 `Select` 也一样 —— 会出现重复 label。
131
+ - **`TextInput` / `TextArea` 的字数统计要求受控或绑表单。** 非受控且没传 `form` 时
132
+ 组件读不到当前长度,`maxLength` 计数不更新。
133
+ - **`CheckboxGroup` 内的 `Checkbox` 不要手动绑 `checked` / `onChange`**,会被 Context
134
+ 覆盖,只传 `value`。
135
+ - **`Switch` 的 `onChange` 参数是原生 `ChangeEvent`**,取值要 `e.currentTarget.checked`。
136
+ - **`NumberInput` 的 `onChange` 可能给到 `string`**(清空时是 `''`),不只是 `number`。
137
+ - **`MultiSelect` 的 `value` 是 `string[]`**,初始值写 `[]`,不是 `''` / `null`。
138
+
139
+ ### 加载与禁用
140
+
141
+ - **`loading={true}` 已经等于禁用**(不只是样式,`onClick` 也会被阻断)。提交表单只写
142
+ `loading={isSubmitting}`,不要再加 `disabled`。(`Button` / `IconButton`)
143
+ - **不要用原生 `disabled` 控制 `Button` / `IconButton`**,用组件的 `disabled` prop ——
144
+ 内部会处理 `aria-disabled` / `tabIndex` / `data-disabled`。
145
+ (`UnstyledButton` 相反,它就用原生 `disabled`。)
146
+
147
+ ### 浮层与移动端
148
+
149
+ - **`DataFilter` 里的下拉控件(`Select` / `MultiSelect` / `TreeSelect` / `DatePicker`)
150
+ 保持 `withinPortal` 默认的 `true`,不要设 `false`** —— 设了下拉层会被 DataFilter 的
151
+ 滚动容器裁剪。嵌套浮层的外部点击、焦点范围、层级和逐层 Escape 由基础 `Popover` 统一处理。
152
+ - **移动端标题靠 `placeholder` / `title`**(`Select` / `MultiSelect` 用前者,
153
+ `Menu` / `Combobox.Dropdown` / `Filter` 用后者)。桌面端可能不显示,但在移动端
154
+ 它是底部弹层的标题,不传就是没标题。
155
+ - **`BottomDrawer` 只用于移动端**,PC 端用 `Drawer`。
156
+ - **`messages.showXxx` / `notifications.showXxx` 是副作用**,只能在事件处理函数或
157
+ `useEffect` 里调,**严禁**在渲染主体里调。
158
+ - **`Combobox.Target` / `Popover.Target` 只接受单个 React 元素**(内部走 `cloneElement`),
159
+ 多个元素或 Fragment 会报错。
160
+ - **不要在 `Combobox.Option` 里嵌 `<button>`** —— `role="option"` 的点击由组件接管,
161
+ 再放交互元素会触发 a11y 的 `nested-interactive` 违规。
162
+ - **不要给 `Filter` / `IconFilter` 的 `buttonProps` / `iconButtonProps` 传 `onClick`**,
163
+ 会覆盖内置的弹层开关,导致弹不出来。
164
+
165
+ ### 文本与截断
166
+
167
+ - **`Text` 的 `truncate` 必须有明确宽度限制**(父容器或自身),否则截断不生效。
168
+ - **文本溢出才显示 Tooltip 用 `showOnlyWhenTruncated`**,不要自己写测量逻辑;
169
+ 多行用 `truncateMaxLines`。
170
+ - **`Text` 没有颜色 prop**,颜色走 `className`(如 `text-fg-secondary`)。
171
+
172
+ ### 其他
173
+
174
+ - **`Table` 用 `tableColumns` 传列配置,不是原生的 `columns`**,传错会类型报错或自定义
175
+ 渲染失效。加载态用 `TableSkeleton`。空单元格占位、文本截断和 Tooltip 都已内置,
176
+ 不要重复实现。
177
+ - **`Menu` 的破坏性操作用 `dangerous: true` 标记**,不要用 `className` 改颜色。触发器要
178
+ 跟随展开状态时用 `renderTarget={({ opened }) => ...}`,**不要**自己维护 `isOpen`。
179
+ - **`Alert` 自己管关闭状态**,父组件不需要维护 `visible` / `onClose`。
180
+ - **`Tabs` 切换默认卸载其他 Panel**,Panel 里有表单或音视频时必须设
181
+ `keepMounted={true}`。吸顶时 `sticky` 加在 `Tabs.List` 的**外层** `div` 上
182
+ (`overflow="scroll"` 时内部有独立滚动容器)。
183
+ - **`Select` 的搜索是自动的** —— 选项数超阈值会自动开启,不要手写 `searchable`,
184
+ 只有要违背默认行为时才显式传值。
185
+ - **`Tree` 的 `defaultExpandedIds` 只放真正需要默认可见的节点**,不要递归收集全部。
186
+ 懒加载场景必须显式传 `isItemFolder`,否则 `children` 为 `undefined` 的节点会被误判成叶子。
187
+ - **`UnstyledButton` 在表单里必须显式 `type="button"`**,否则会意外触发提交。
188
+ - **`IconButton` 必须给 `aria-label` 或 `title`** —— 它没有可见文字。
189
+ - **日期选择器除 `DatePicker` 外都是草稿模式** —— 弹层里的操作只改临时状态,点「确定」
190
+ 才触发 `onChange`。没立刻触发不是 bug。
191
+
192
+ ## 禁止事项
193
+
194
+ - ❌ **从 `@mantine/core` 导入 `Box` / `Text` / `Flex` / `Group` / `Stack` / `Paper` /
195
+ `UnstyledButton`。** 这些在 `@wisdomgarden/torque` 里都有同名替代品,行为和默认值
196
+ 是本设计系统的,不是 Mantine 的。其他 Mantine 交互组件同理 —— 库里有的一律用库里的。
197
+ - ❌ **Mantine style props**:`p` / `m` / `bg` / `c` / `fz` / `fw` / `sx` / `styles`。
198
+ 一律用 `className` + Tailwind。(`Flex` / `Group` / `Stack` 的 `gap` / `align` /
199
+ `justify` 是本库自己的 props,接受设计 token,不在此列。)
200
+ - ❌ **`--mantine-*` CSS 变量。** 用 `--t-*` 或 Tailwind 类。
201
+ - ❌ **任意值**(`p-[16px]` 这种)。只用设计 token。
202
+ - ❌ **手写 dark mode 分支。** `--t-*` 颜色自动适配,不要按主题条件切换颜色。
203
+ - ❌ **在 Server Component 里用 `component={ReactComponent}`**(Next 16 限制)。
204
+ 标签字符串形式的 `component="form"` 两边都安全。
205
+ - ❌ **裸 `<div>`**,尤其是需要 `hiddenFrom` / `visibleFrom` 的地方 —— 用 `Box`。
206
+ - ❌ **重新实现业务筛选容器、折叠行为或触发器** —— 用 `DataFilter`。
207
+ - ❌ **直接调用 `@mantine/notifications` 的 `showNotification`** —— 用 `messages` / `notifications`。
208
+ - ❌ **组件不支持 dark mode / 响应式 / i18n(5 语言)/ a11y / ltr-rtl。**
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@wisdomgarden/torque-knowledge",
3
+ "version": "0.1.2",
4
+ "description": "Machine-readable knowledge artifact for @wisdomgarden/torque — component catalog (SQLite) and AI coding rules (Markdown). Consumed by CI code review and local AI tooling, not by application runtime.",
5
+ "type": "module",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "engines": {
8
+ "node": ">=22.13"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public",
15
+ "registry": "https://registry.npmjs.org/"
16
+ },
17
+ "scripts": {
18
+ "build": "node scripts/gen.mjs"
19
+ }
20
+ }