@jc-times/business-ui 0.2.55 → 0.3.0

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.
@@ -1,43 +1,43 @@
1
- # ModalShell 0.2.6 消费迁移
2
-
3
- ## 稳定 DOM 契约
4
-
5
- ModalShell 面板稳定保持以下直接子节点顺序:
6
-
7
- ```text
8
- .ui-modal
9
- ├─ .ui-modal-header
10
- ├─ .ui-modal-content (children;唯一正文滚动区)
11
- └─ .ui-modal-footer (仅在传入 footer 时存在;固定操作区)
12
- ```
13
-
14
- 消费方可以依赖这些具名插槽 class,但不应使用元素类型或无 class 的层级选择器猜测内部结构。没有 `footer` 时,面板只包含 header 与 content。
15
-
16
- ## 旧式调用迁移
17
-
18
- 旧式写法会把原生 footer 放进 `.ui-modal-content`,因此它会随正文滚动,且 `.panel > footer` 不再匹配:
19
-
20
- ```tsx
21
- <ModalShell {...dialogProps}>
22
- <Form />
23
- <footer className="actions">...</footer>
24
- </ModalShell>
25
- ```
26
-
27
- 改为显式插槽:
28
-
29
- ```tsx
30
- <ModalShell
31
- {...dialogProps}
32
- contentClassName="form-scroll"
33
- contentProps={{ ref: contentRef, "data-section": "dialog-body" }}
34
- footerClassName="actions"
35
- footer={<>...</>}
36
- >
37
- <Form />
38
- </ModalShell>
39
- ```
40
-
41
- 开发构建会对可识别的旧式直接 footer child 输出迁移警告,`business-ui-gate` 会阻止新增调用。公共包不会自动搬运 footer,因为这可能改变条件渲染、语义、事件边界或消费方业务布局。
42
-
43
- 如果消费仓库使用 `business-ui-gate --only ...`,升级后需把 `legacyModalFooter` 加入 `--only` 列表;默认全量门禁会自动启用该规则。
1
+ # ModalShell 0.2.6 消费迁移
2
+
3
+ ## 稳定 DOM 契约
4
+
5
+ ModalShell 面板稳定保持以下直接子节点顺序:
6
+
7
+ ```text
8
+ .ui-modal
9
+ ├─ .ui-modal-header
10
+ ├─ .ui-modal-content (children;唯一正文滚动区)
11
+ └─ .ui-modal-footer (仅在传入 footer 时存在;固定操作区)
12
+ ```
13
+
14
+ 消费方可以依赖这些具名插槽 class,但不应使用元素类型或无 class 的层级选择器猜测内部结构。没有 `footer` 时,面板只包含 header 与 content。
15
+
16
+ ## 旧式调用迁移
17
+
18
+ 旧式写法会把原生 footer 放进 `.ui-modal-content`,因此它会随正文滚动,且 `.panel > footer` 不再匹配:
19
+
20
+ ```tsx
21
+ <ModalShell {...dialogProps}>
22
+ <Form />
23
+ <footer className="actions">...</footer>
24
+ </ModalShell>
25
+ ```
26
+
27
+ 改为显式插槽:
28
+
29
+ ```tsx
30
+ <ModalShell
31
+ {...dialogProps}
32
+ contentClassName="form-scroll"
33
+ contentProps={{ ref: contentRef, "data-section": "dialog-body" }}
34
+ footerClassName="actions"
35
+ footer={<>...</>}
36
+ >
37
+ <Form />
38
+ </ModalShell>
39
+ ```
40
+
41
+ 开发构建会对可识别的旧式直接 footer child 输出迁移警告,`business-ui-gate` 会阻止新增调用。公共包不会自动搬运 footer,因为这可能改变条件渲染、语义、事件边界或消费方业务布局。
42
+
43
+ 如果消费仓库使用 `business-ui-gate --only ...`,升级后需把 `legacyModalFooter` 加入 `--only` 列表;默认全量门禁会自动启用该规则。
package/docs/mrt-poc.md CHANGED
@@ -168,7 +168,7 @@ node examples/mrt-poc/measure.mjs
168
168
  | `examples/mrt-poc/styles.css`、`icons.tsx`、`tokens.ts` | 局部视觉适配 |
169
169
  | `examples/mrt-poc/mrt.browser.ts` | 可重复的浏览器回归 |
170
170
 
171
- 已决定采用MRT;其他服务接入前,需确定通用列/明细插槽、模式选择、受控选择与查询状态、列偏好持久化、服务端契约和权限边界,再完成公共导出、版本发布及实际消费验证。当前样例未连接接口;仅搜索条件可本地记忆,列顺序/显隐/宽度等偏好尚未持久化,未验证React 19组合或真实手机/键盘拖列。不要跨仓库复制样例冒充已发布能力。
171
+ 已决定采用MRT;其他服务接入前,需确定通用列/明细插槽、模式选择、受控选择与查询状态、列偏好持久化、服务端契约和权限边界,再完成公共导出、版本发布及实际消费验证。当前样例未连接接口;仅搜索条件可本地记忆,列顺序/显隐/宽度等偏好尚未持久化,未验证React 19组合或真实手机/键盘拖列。不要跨仓库复制样例冒充已发布能力。
172
172
 
173
173
  ## 搜索条件记忆
174
174
 
@@ -1,43 +1,43 @@
1
- # 拖动排序与跨区块移动
2
-
1
+ # 拖动排序与跨区块移动
2
+
3
3
  空列表与移动上下文从 0.2.54 起提供;0.2.55 补齐空列表接收区和高亮样式。消费方仍应核对实际安装版本的类型声明。
4
-
5
- ## 场景与接口
6
-
7
- - 同列表排序沿用 `onReorder(items)`。
8
- - 同一编辑范围共享 `useSortableTransferScope<T>(ownerKey)`;不同范围不接收彼此的拖动。ownerKey 使用稳定的业务身份。
9
- - 各列表可传稳定的 `listId: string | number`。它用于回调上下文,不代替 scope 隔离;省略时对应上下文字段为 undefined。
10
- - `onDropOnItem(moving, target, context)`:放到目标项上。
11
- - `onDropBetweenItems(moving, target, position, context)`:跨列表插入,position 为 before/after。
12
- - `onDropOnList(moving, context)`:放到集合本身,包括空列表;配合 `canDropOnList(moving)` 限制接收。
13
- - `context: SortableMoveContext` 包含 `sourceListId`、`targetListId`。原有少参数回调无需修改。
14
- - `renderEmptyState()` 自定义空状态;默认根据是否可接收显示提示。插入位置、来源占位和目标高亮沿用公共主题。
15
-
16
- 根区域落点不承诺插入位置,由消费方选择追加或其他规则。需要精确位置时用 before/after。未配置回调的落点不接收拖动。
17
-
18
- ```tsx
19
- const scope = useSortableTransferScope<Row>(documentId);
20
- // 来源列表也传同一 scope,以及自己的 listId。
21
- <SortableList
22
- aria-label="待办区" listId="todo" transferScope={scope}
23
- items={rows} getKey={row => row.id} getTextValue={row => row.title}
24
- renderItem={row => <Card row={row} />} onReorder={setRows}
25
- onDropOnList={(moving, { sourceListId, targetListId }) => {
26
- // 通过一次状态更新同时移除来源并添加到目标,持久化由应用处理。
27
- moveRows(moving, sourceListId, targetListId);
28
- }}
29
- />
30
- ```
31
-
32
- ## 状态与约束
33
-
34
- - `disabled` 仅禁用拖放,不卸载列表和卡片,也不禁用卡片中的业务表单。手柄隐藏,但保持拖放 hooks 结构稳定,避免 hook 数量变化和草稿丢失。
35
- - 同一 scope 内 key 必须唯一,items 更新必须提供新数组;移动项沿来源顺序返回。
36
- - 拖动过程中保留来源数据;来源删除、禁用、卸载或 ownerKey 改变后不提交旧拖动。目标卸载、目标禁用、键歧义和取消均不提交;一次跨列表拖动只消费一次。
37
- - 卡片在跨列表移动时的局部状态保留不在本组件承诺内;需跨容器保留的草稿由消费方受控保存。
38
- - 建立每列表 key 索引供拖动判定使用,避免每次 hover 遍历全部行;scope 歧义检查仍随列表数量增长,不等于已支持虚拟化。
39
-
40
- ## 验证
41
-
42
- `src/SortableList.transfer.test.tsx` 覆盖失效来源/目标、重复键、scope 更换、取消、上下文与 2000 行/500 次 hover 的 key 访问计数。
43
- `e2e/sortable-drop.spec.ts` 覆盖真实浏览器键盘/鼠标投放、空列表、禁用切换时输入节点/草稿/焦点保留及五档视口;手机项目为模拟视口,不替代实机触屏。
4
+
5
+ ## 场景与接口
6
+
7
+ - 同列表排序沿用 `onReorder(items)`。
8
+ - 同一编辑范围共享 `useSortableTransferScope<T>(ownerKey)`;不同范围不接收彼此的拖动。ownerKey 使用稳定的业务身份。
9
+ - 各列表可传稳定的 `listId: string | number`。它用于回调上下文,不代替 scope 隔离;省略时对应上下文字段为 undefined。
10
+ - `onDropOnItem(moving, target, context)`:放到目标项上。
11
+ - `onDropBetweenItems(moving, target, position, context)`:跨列表插入,position 为 before/after。
12
+ - `onDropOnList(moving, context)`:放到集合本身,包括空列表;配合 `canDropOnList(moving)` 限制接收。
13
+ - `context: SortableMoveContext` 包含 `sourceListId`、`targetListId`。原有少参数回调无需修改。
14
+ - `renderEmptyState()` 自定义空状态;默认根据是否可接收显示提示。插入位置、来源占位和目标高亮沿用公共主题。
15
+
16
+ 根区域落点不承诺插入位置,由消费方选择追加或其他规则。需要精确位置时用 before/after。未配置回调的落点不接收拖动。
17
+
18
+ ```tsx
19
+ const scope = useSortableTransferScope<Row>(documentId);
20
+ // 来源列表也传同一 scope,以及自己的 listId。
21
+ <SortableList
22
+ aria-label="待办区" listId="todo" transferScope={scope}
23
+ items={rows} getKey={row => row.id} getTextValue={row => row.title}
24
+ renderItem={row => <Card row={row} />} onReorder={setRows}
25
+ onDropOnList={(moving, { sourceListId, targetListId }) => {
26
+ // 通过一次状态更新同时移除来源并添加到目标,持久化由应用处理。
27
+ moveRows(moving, sourceListId, targetListId);
28
+ }}
29
+ />
30
+ ```
31
+
32
+ ## 状态与约束
33
+
34
+ - `disabled` 仅禁用拖放,不卸载列表和卡片,也不禁用卡片中的业务表单。手柄隐藏,但保持拖放 hooks 结构稳定,避免 hook 数量变化和草稿丢失。
35
+ - 同一 scope 内 key 必须唯一,items 更新必须提供新数组;移动项沿来源顺序返回。
36
+ - 拖动过程中保留来源数据;来源删除、禁用、卸载或 ownerKey 改变后不提交旧拖动。目标卸载、目标禁用、键歧义和取消均不提交;一次跨列表拖动只消费一次。
37
+ - 卡片在跨列表移动时的局部状态保留不在本组件承诺内;需跨容器保留的草稿由消费方受控保存。
38
+ - 建立每列表 key 索引供拖动判定使用,避免每次 hover 遍历全部行;scope 歧义检查仍随列表数量增长,不等于已支持虚拟化。
39
+
40
+ ## 验证
41
+
42
+ `src/SortableList.transfer.test.tsx` 覆盖失效来源/目标、重复键、scope 更换、取消、上下文与 2000 行/500 次 hover 的 key 访问计数。
43
+ `e2e/sortable-drop.spec.ts` 覆盖真实浏览器键盘/鼠标投放、空列表、禁用切换时输入节点/草稿/焦点保留及五档视口;手机项目为模拟视口,不替代实机触屏。
@@ -1,17 +1,17 @@
1
- # 人员资料卡
2
-
3
- `UserProfilePopover` 将紧凑人员标签和只读资料卡组合在一起。默认点击标签打开,键盘可用 Enter 或空格打开、Escape 关闭,关闭后焦点返回标签。弹层会避开视口边缘,并在窄屏中换行显示较长的部门路径。
4
-
5
- ```tsx
6
- import { UserProfilePopover } from "@jc-times/business-ui";
7
- import "@jc-times/business-ui/styles.css";
8
-
9
- <UserProfilePopover name="章晨露" code="ZhangChenLu"
10
- department="示例集团 / 项目管理部 / 项目运营组" tag="内部成员" avatarColor="#e94b50"/>;
11
- ```
12
-
13
- `name` 必填,其余资料字段可省略。没有头像图片时取姓名首字符;`avatarUrl` 可提供图片地址。`code`、`department` 和 `tag` 只负责展示,业务层决定具体含义及是否有权显示。`codeLabel`、`departmentLabel` 可以修改字段标题。`avatarColor` 或 CSS 变量 `--ui-user-avatar-bg` 控制头像背景;不传时使用主题主色。
14
-
15
- 资料卡默认宽度随视口变化:`clamp(300px, 15vw, 560px)`,并受浮层实际可用宽度限制。普通桌面网页约 300px,宽屏业务页面可逐步放大;手机上会收缩到可用视口,长部门名称自动换行。页面需要固定宽度时,可在主题根节点设置 `--ui-user-profile-width`,或通过 `className` 给弹层设置该变量。
16
-
17
- 默认触发器是一个人员标签按钮。需要放进其他布局时,使用 `trigger={<button>...</button>}` 提供可转发 ref 的交互元素。`side`、`align`、`open`、`defaultOpen` 和 `onOpenChange` 与公共 `Popover` 一致;`className` 作用于弹层。组件不获取人员资料或处理业务权限。
1
+ # 人员资料卡
2
+
3
+ `UserProfilePopover` 将紧凑人员标签和只读资料卡组合在一起。默认点击标签打开,键盘可用 Enter 或空格打开、Escape 关闭,关闭后焦点返回标签。弹层会避开视口边缘,并在窄屏中换行显示较长的部门路径。
4
+
5
+ ```tsx
6
+ import { UserProfilePopover } from "@jc-times/business-ui";
7
+ import "@jc-times/business-ui/styles.css";
8
+
9
+ <UserProfilePopover name="章晨露" code="ZhangChenLu"
10
+ department="示例集团 / 项目管理部 / 项目运营组" tag="内部成员" avatarColor="#e94b50"/>;
11
+ ```
12
+
13
+ `name` 必填,其余资料字段可省略。没有头像图片时取姓名首字符;`avatarUrl` 可提供图片地址。`code`、`department` 和 `tag` 只负责展示,业务层决定具体含义及是否有权显示。`codeLabel`、`departmentLabel` 可以修改字段标题。`avatarColor` 或 CSS 变量 `--ui-user-avatar-bg` 控制头像背景;不传时使用主题主色。
14
+
15
+ 资料卡默认宽度随视口变化:`clamp(300px, 15vw, 560px)`,并受浮层实际可用宽度限制。普通桌面网页约 300px,宽屏业务页面可逐步放大;手机上会收缩到可用视口,长部门名称自动换行。页面需要固定宽度时,可在主题根节点设置 `--ui-user-profile-width`,或通过 `className` 给弹层设置该变量。
16
+
17
+ 默认触发器是一个人员标签按钮。需要放进其他布局时,使用 `trigger={<button>...</button>}` 提供可转发 ref 的交互元素。`side`、`align`、`open`、`defaultOpen` 和 `onOpenChange` 与公共 `Popover` 一致;`className` 作用于弹层。组件不获取人员资料或处理业务权限。
@@ -7,129 +7,129 @@
7
7
  - 移动端结果为浏览器模拟;真实触屏惯性滚动和双指缩放仍需真机验收。
8
8
 
9
9
  ## 2026-09-18 — 人员资料卡
10
-
11
- - Chromium Desktop Chrome 与 Pixel 7 模拟共 4 项:人员标签打开只读资料卡,长部门路径可见,弹层位于视口内、页面无横向溢出;Escape 关闭后焦点返回标签。包含 320px 窄屏检查;默认宽度随视口按 300–560px 缩放。
12
-
13
- ## 2026-09-14 — PDFium 0.2.45 批注显示
14
- - Desktop Chrome / Pixel 7 模拟视口4项通过:仅存在于Stamp/FreeText批注层的测试图形在正文和缩略图均可见;本地真实审核PDF第一页原生印章与签章提示可见。真实文件不提交、不上传;自动测试支持本地环境变量注入。
15
- - 141项单测、类型/库/矩阵/按需构建通过。仅改变原生批注显示,不启用批注编辑或改写文件;浏览器模拟不替代真机验收。
16
-
17
- 运行 `pnpm dev:matrix -- --host 127.0.0.1`,在受控浏览器中检查以下矩阵:
18
-
19
- | 档位 | 视口 | 核心检查 |
20
- | --- | --- | --- |
21
- | 手机 | 390 × 844 | 无水平溢出;按钮与表单可触达;分页正确换行;弹窗占满可用宽度 |
22
- | 小屏手机 | 320 × 480 | 弹窗固定头尾;正文可独立滚动;底栏操作不被正文吞入 |
23
- | 平板 | 768 × 1024 | 表单栅格不拥挤;日期浮层不越界;Tabs 可横向滚动 |
24
- | 桌面 | 1440 × 900 | 内容宽度、按钮组和分页布局合理;弹窗居中且内容可滚动 |
25
- | 短横屏 | 844 × 390 | 弹窗留有视口边距;头部紧凑;正文滚动且固定底栏始终可见 |
26
-
27
- 每档需检查默认页及弹窗页,并确认:
28
-
29
- - Tab 焦点顺序可预测,焦点环清晰。
30
- - `Escape` 关闭弹窗并恢复触发按钮焦点。
31
- - 日期选择器保持在视口内,可选择、清除并用 `Escape` 关闭。
32
- - 禁用原因可通过键盘聚焦查看。
33
- - Alert 的操作与关闭按钮在手机端正确换行;EmptyState 和 Skeleton 不挤压容器。
34
- - PageHeader 与 SectionCard 的说明和 actions 在窄屏正确换行;长标题不造成水平溢出。
35
- - Badge 五档 tone 和两档 size 可辨识;MetricCard 在四列、两列和单列布局中保持阅读顺序与等高节奏。
36
- - Tooltip 可由悬停和键盘焦点打开;Popover、Popconfirm 与 Select 在两端均不越界并可用 Escape 关闭。
37
- - Combobox 与 AutoComplete 可输入、筛选和键盘选择;大列表只渲染可见项。
38
- - TextInput 的搜索图标、清除按钮及 NumericInput 的单位/百分号与同行控件等高;点击非交互装饰可聚焦,清除按钮可独立操作,错误和禁用外框状态完整。
39
- - Toast 在手机端贴近底部且左右保留 12px 安全边距;DataTable 只在自身容器内横向滚动。
40
- - 浏览器控制台无错误。
41
-
42
- 分段控制器专项:在「表单控件 → 视图切换」及 `e2e/segmented.html` 检查实色/浅底、收缩/等宽、胶囊、纵向、图标和长文字;验证方向键跳过禁用项、组之间互不干扰、焦点环可见,以及粗指针每项至少 44px。自动回归运行 `pnpm exec playwright test e2e/segmented.spec.ts`。
43
-
44
- 验收结论只记录日期、浏览器、视口和结果,不记录账号、Cookie 或其他会话数据。
45
-
46
- ## 验收记录
47
-
48
- ### 2026-09-12 — V2 原生 Headless 页面层候选
49
-
50
- - Chromium 桌面/手机查看器 14 项回归通过;原生模式覆盖五档视口,底栏可见、正文可滚动、页面无横向溢出,手机缩放旋转叠层截图目检通过。
51
- - 验证受控跳页与手动滚动、原生叠层点击、缩放旋转、单页互切、全屏、切换文档与失败恢复;138 项单测、类型和库/矩阵构建通过。未发布;真实多指手势与消费业务印章端到端仍需消费方验收。
52
-
53
- ### 2026-09-06 — 0.2.13 输入装饰
54
-
55
- - 浏览器:Codex 内置 Chromium;桌面验收页实际测得三个装饰组合外框均为 40px、内层 input 为 38px,宽度无溢出。
56
- - 搜索图标、清除按钮、百分号、货币符号和单位布局与同行 TextInput/SelectInput 对齐;清除按钮点击后输入值清空并按条件移除按钮。
57
- - 粗指针 44px 外框与内层 input 归零规则由 CSS 契约测试覆盖;类型检查、91 项测试、库构建和视觉矩阵构建通过,控制台无 warning/error。
58
-
59
- ### 2026-09-05 — 0.2.6 TreeSelect、StructuredAddressInput 与控件高度
60
-
61
- - 浏览器:Codex 内置 Chromium。
62
- - 视口:1440 × 900、390 × 844、320 × 480;桌面双列表单和两档手机单列表单均保持可读。
63
- - TreeSelect:320px 下使用固定底部候选面板,树层级、当前项、展开状态与 44px 触控高度清晰;修正面板横向滚动后无水平溢出。
64
- - StructuredAddressInput:桌面三级列并排,390px 下底部面板适配安全区;地区摘要、级联选中、详细地址和数据版本信息均可辨识。
65
- - 同行控件:TextInput、SelectInput 与 Button 使用显式 40px border-box 默认高度,未再依赖原生 select 的平台内在高度。
66
-
67
- ### 2026-09-05 — 0.2.6 ModalShell 兼容治理
68
-
69
- - 浏览器:Codex 内置 Chromium。
70
- - 视口:1440 × 900、390 × 844、844 × 390、320 × 480;四档页面均无水平溢出。
71
- - DOM:`.ui-modal-header`、`.ui-modal-content`、`.ui-modal-footer` 保持面板直接子节点顺序;正文区 `overflow-y:auto` 且存在真实溢出,底栏不在正文中并始终位于视口内。
72
- - 响应式:桌面弹窗 560px 居中;两档手机全屏;短横屏保留 12px 视口边距、使用 366px 最大高度并压缩头部留白。
73
- - 透传:验收页的 content ref/role/ARIA/data 契约对应节点正确;控制台无 warning 或 error。
74
-
75
- ### 2026-09-04 — 0.2.4 候选
76
-
77
- - 浏览器:Codex 内置 Chromium 浏览器与 Microsoft Edge headless 截图。
78
- - 视口:390 × 844、768 × 1024、1440 × 900;三档页面 `scrollWidth` 均等于内容视口宽度,无页面级水平溢出。
79
- - 新增组件:PageHeader 操作区在手机端改为整行;SectionCard 标题、说明与 actions 正确换行;MetricCard 分别为 1、2、4 列,桌面四卡等高;Badge 五档 tone 与两档 size 可辨识。
80
- - 语义:页面标题与区域标题保持 `h1` → `h2` 层级,SectionCard 由可见标题命名。
81
- - 控制台:未发现 warning 或 error。
82
-
83
- ### 2026-09-04 — 0.2.0 候选
84
-
85
- - 浏览器:Codex 内置 Chromium 浏览器。
86
- - 视口:390 × 844、768 × 1024、1440 × 900。
87
- - 结果:三档均无水平溢出;表单、按钮组、Tabs 与分页布局正常。
88
- - 弹窗:手机全屏、桌面 560px 居中;首焦点、Tab 回环、Escape 关闭及触发按钮焦点恢复正常。
89
- - 日期选择器:手机和平板均保持在视口内,Escape 可关闭。
90
- - 控制台:未发现 warning 或 error。
91
-
92
- 数字输入专项:在「表单控件」页检查数量千分位、聚焦取消分组、尾随小数点、Enter/失焦提交;缩放输入聚焦/点击全选;错误提示与禁用态。默认和触屏尺寸应与同行 TextInput 一致,窄屏无横向溢出。消费方既有 bareInput 门禁已覆盖原生数字输入,不新增重复扫描规则;替换本地包装后须缩减基线。
93
-
94
- 输入装饰专项:在「表单控件」页检查搜索图标、清除按钮、货币符号、金额单位和百分号;桌面组合外框为 40px,粗指针触屏最小 44px。装饰存在与否不应改变标签、帮助、错误或输入值的可访问名称;键盘仍直接进入输入框和清除按钮。
95
-
96
- ### 2026-09-06 数字输入 0.2.8
97
-
98
- - 1440×900、390×844、320×480、768×1024、844×390 的表单页 DOM 边界检查通过,无文档水平溢出;桌面/390px 目检数字、错误和禁用样式一致,输入继承 40px 默认高度。
99
- - 浏览器确认缩放输入聚焦全选 `1234.56`,输入 `1.005` 回车后显示 `1.01`;数量保留 `1234.` 草稿,失焦后显示 `1,234`。控制台无 warning/error。
100
- - 本轮新增控件没有修改 CSS;触屏 44px 继续由既有 coarse-pointer 样式契约测试覆盖,未模拟手机软键盘。
101
-
102
-
103
- ### 2026-09-11 — SegmentedControl 本地增强
104
-
105
- - Chromium 桌面/Pixel 7 模拟:320×480、390×844、768×1024、1440×900、844×390 无页面水平溢出;粗指针全部选项点击高度至少 44px。
106
- - 原生方向键跳过禁用项、横向/纵向循环选择与独立分组通过;390px 浅底、胶囊、纵向、纯图标、长文字和禁用态截图目检通过。新增 4 项浏览器检查通过,非真实手机验收。
107
-
108
- ## 2026-09-11 — Cascader 本地接入
109
-
110
- - Chromium 桌面与 Pixel 7 模拟,320×480、390×844、768×1024、1440×900、844×390 五档:三级展开无页面横向溢出;窄屏底部面板、44px 触控行、390px/1440px 截图目检通过。
111
- - 部门父子独立多选、地址路径搜索与叶子选中后详细地址聚焦、弹窗内 portal、键盘选择及 Escape 分层关闭通过。输入占位不与摘要重叠,清空归一与必填搜索未选中由单测覆盖。
112
- - 新增级联 6 项浏览器测试通过;全量 36 项浏览器、25 文件 133 项单测、类型、库与视觉矩阵构建通过;打包演练包含声明、专题和 MIT 许可。
113
- - 本地待发布;尚未升级消费项目。触屏测试是浏览器模拟,非真实手机软键盘验收。复测:`pnpm exec playwright test e2e/cascader.spec.ts`。
114
-
115
- ### 2026-09-14 PDFium 0.2.44
116
- - Playwright Desktop Chrome / Pixel 7 六项定向验收通过:默认侧栏收起与往返开关、双指连续缩放、最小/最大比例、松手前后页面几何一致、业务叠层不误触。属于模拟触控,真实手机待消费方验收。
117
-
118
- ### 2026-09-14 PDFium 0.2.46
119
- - Desktop Chrome / Pixel 7 的8项手势专项通过:连续Ctrl/Meta滚轮、触屏缩放上下限、侧栏。77%起始跨越适宽边界,回传页码不再触发额外跳页,手势期间0次引擎缩放提交,每次结束仅1次。位置误差小于5 CSS像素、宽度误差小于0.5 CSS像素。原生路径复现额外跳页约304px,修复接入层后通过。
120
- - pnpm精确补丁仅为官方2.15.0 React手势预览增加引擎一致的上下限和精度,保留官方CSS预览、虚拟滚动、延迟清晰重绘;未新增逐帧PDFium渲染。真机仍待用户复验。
121
-
122
- ## 2026-09-14 — 0.2.47 横向滚动
123
-
124
- Desktop Chrome / Pixel 7模拟视口共4项通过:50行8列表格,连续横向wheel位置不回退,同步条双向操作与固定高度原生滚动;原生模式无额外吸附条,纵向滚动表头仍可见。3项同步生命周期单测覆盖异步回传、每帧合并和卸载取消;修复前异步回传测试从140回退100,修复后保持140。模拟wheel不能替代真实触控板验收。
125
-
126
- ## 2026-09-15 — SortableList目标项接收
127
-
128
- Chromium桌面与Pixel 7视口,鼠标拖入目标、键盘选择目标/取消、禁止投放普通项、禁用手柄与宽度回归共6项通过;触屏视口为模拟,未宣称实机多指验证。2项排序单测及TypeScript通过。目标高亮复用主题令牌;领域移动由消费方处理。
129
-
130
- ## 2026-09-15 / 0.2.50 嵌套拖动
131
- - sortable-drop.spec.ts 与 sortable-width.spec.ts:桌面/Pixel7 模拟共14项通过,覆盖鼠标来源占位尺寸不变、进入组高亮、成员插入线、键盘移出/移回/组内排序与禁用宽度;TypeScript通过。键盘测试先等待嵌套列表的漫游焦点真正落到所选手柄,再按Enter,避免测试自身在焦点转移时启动拖动。不是实际触屏验收。
132
- - 新增禁用切换页面错误捕获,避免误将组件崩溃当成隐藏手柄成功。React Aria hooks有无改变时通过显式GridList key切换。
133
- - 嵌套指示器可能把目标key交给祖先回调,scope仅路由至唯一当前所属列表;一次拖动只消费一次。
134
-
135
- - 首轮矩阵CI34971182111发现隐藏占位span使content不再是only-child,禁用行缩宽;占位仅在可拖动状态渲染,sortable-width回归验证。
10
+
11
+ - Chromium Desktop Chrome 与 Pixel 7 模拟共 4 项:人员标签打开只读资料卡,长部门路径可见,弹层位于视口内、页面无横向溢出;Escape 关闭后焦点返回标签。包含 320px 窄屏检查;默认宽度随视口按 300–560px 缩放。
12
+
13
+ ## 2026-09-14 — PDFium 0.2.45 批注显示
14
+ - Desktop Chrome / Pixel 7 模拟视口4项通过:仅存在于Stamp/FreeText批注层的测试图形在正文和缩略图均可见;本地真实审核PDF第一页原生印章与签章提示可见。真实文件不提交、不上传;自动测试支持本地环境变量注入。
15
+ - 141项单测、类型/库/矩阵/按需构建通过。仅改变原生批注显示,不启用批注编辑或改写文件;浏览器模拟不替代真机验收。
16
+
17
+ 运行 `pnpm dev:matrix -- --host 127.0.0.1`,在受控浏览器中检查以下矩阵:
18
+
19
+ | 档位 | 视口 | 核心检查 |
20
+ | --- | --- | --- |
21
+ | 手机 | 390 × 844 | 无水平溢出;按钮与表单可触达;分页正确换行;弹窗占满可用宽度 |
22
+ | 小屏手机 | 320 × 480 | 弹窗固定头尾;正文可独立滚动;底栏操作不被正文吞入 |
23
+ | 平板 | 768 × 1024 | 表单栅格不拥挤;日期浮层不越界;Tabs 可横向滚动 |
24
+ | 桌面 | 1440 × 900 | 内容宽度、按钮组和分页布局合理;弹窗居中且内容可滚动 |
25
+ | 短横屏 | 844 × 390 | 弹窗留有视口边距;头部紧凑;正文滚动且固定底栏始终可见 |
26
+
27
+ 每档需检查默认页及弹窗页,并确认:
28
+
29
+ - Tab 焦点顺序可预测,焦点环清晰。
30
+ - `Escape` 关闭弹窗并恢复触发按钮焦点。
31
+ - 日期选择器保持在视口内,可选择、清除并用 `Escape` 关闭。
32
+ - 禁用原因可通过键盘聚焦查看。
33
+ - Alert 的操作与关闭按钮在手机端正确换行;EmptyState 和 Skeleton 不挤压容器。
34
+ - PageHeader 与 SectionCard 的说明和 actions 在窄屏正确换行;长标题不造成水平溢出。
35
+ - Badge 五档 tone 和两档 size 可辨识;MetricCard 在四列、两列和单列布局中保持阅读顺序与等高节奏。
36
+ - Tooltip 可由悬停和键盘焦点打开;Popover、Popconfirm 与 Select 在两端均不越界并可用 Escape 关闭。
37
+ - Combobox 与 AutoComplete 可输入、筛选和键盘选择;大列表只渲染可见项。
38
+ - TextInput 的搜索图标、清除按钮及 NumericInput 的单位/百分号与同行控件等高;点击非交互装饰可聚焦,清除按钮可独立操作,错误和禁用外框状态完整。
39
+ - Toast 在手机端贴近底部且左右保留 12px 安全边距;DataTable 只在自身容器内横向滚动。
40
+ - 浏览器控制台无错误。
41
+
42
+ 分段控制器专项:在「表单控件 → 视图切换」及 `e2e/segmented.html` 检查实色/浅底、收缩/等宽、胶囊、纵向、图标和长文字;验证方向键跳过禁用项、组之间互不干扰、焦点环可见,以及粗指针每项至少 44px。自动回归运行 `pnpm exec playwright test e2e/segmented.spec.ts`。
43
+
44
+ 验收结论只记录日期、浏览器、视口和结果,不记录账号、Cookie 或其他会话数据。
45
+
46
+ ## 验收记录
47
+
48
+ ### 2026-09-12 — V2 原生 Headless 页面层候选
49
+
50
+ - Chromium 桌面/手机查看器 14 项回归通过;原生模式覆盖五档视口,底栏可见、正文可滚动、页面无横向溢出,手机缩放旋转叠层截图目检通过。
51
+ - 验证受控跳页与手动滚动、原生叠层点击、缩放旋转、单页互切、全屏、切换文档与失败恢复;138 项单测、类型和库/矩阵构建通过。未发布;真实多指手势与消费业务印章端到端仍需消费方验收。
52
+
53
+ ### 2026-09-06 — 0.2.13 输入装饰
54
+
55
+ - 浏览器:Codex 内置 Chromium;桌面验收页实际测得三个装饰组合外框均为 40px、内层 input 为 38px,宽度无溢出。
56
+ - 搜索图标、清除按钮、百分号、货币符号和单位布局与同行 TextInput/SelectInput 对齐;清除按钮点击后输入值清空并按条件移除按钮。
57
+ - 粗指针 44px 外框与内层 input 归零规则由 CSS 契约测试覆盖;类型检查、91 项测试、库构建和视觉矩阵构建通过,控制台无 warning/error。
58
+
59
+ ### 2026-09-05 — 0.2.6 TreeSelect、StructuredAddressInput 与控件高度
60
+
61
+ - 浏览器:Codex 内置 Chromium。
62
+ - 视口:1440 × 900、390 × 844、320 × 480;桌面双列表单和两档手机单列表单均保持可读。
63
+ - TreeSelect:320px 下使用固定底部候选面板,树层级、当前项、展开状态与 44px 触控高度清晰;修正面板横向滚动后无水平溢出。
64
+ - StructuredAddressInput:桌面三级列并排,390px 下底部面板适配安全区;地区摘要、级联选中、详细地址和数据版本信息均可辨识。
65
+ - 同行控件:TextInput、SelectInput 与 Button 使用显式 40px border-box 默认高度,未再依赖原生 select 的平台内在高度。
66
+
67
+ ### 2026-09-05 — 0.2.6 ModalShell 兼容治理
68
+
69
+ - 浏览器:Codex 内置 Chromium。
70
+ - 视口:1440 × 900、390 × 844、844 × 390、320 × 480;四档页面均无水平溢出。
71
+ - DOM:`.ui-modal-header`、`.ui-modal-content`、`.ui-modal-footer` 保持面板直接子节点顺序;正文区 `overflow-y:auto` 且存在真实溢出,底栏不在正文中并始终位于视口内。
72
+ - 响应式:桌面弹窗 560px 居中;两档手机全屏;短横屏保留 12px 视口边距、使用 366px 最大高度并压缩头部留白。
73
+ - 透传:验收页的 content ref/role/ARIA/data 契约对应节点正确;控制台无 warning 或 error。
74
+
75
+ ### 2026-09-04 — 0.2.4 候选
76
+
77
+ - 浏览器:Codex 内置 Chromium 浏览器与 Microsoft Edge headless 截图。
78
+ - 视口:390 × 844、768 × 1024、1440 × 900;三档页面 `scrollWidth` 均等于内容视口宽度,无页面级水平溢出。
79
+ - 新增组件:PageHeader 操作区在手机端改为整行;SectionCard 标题、说明与 actions 正确换行;MetricCard 分别为 1、2、4 列,桌面四卡等高;Badge 五档 tone 与两档 size 可辨识。
80
+ - 语义:页面标题与区域标题保持 `h1` → `h2` 层级,SectionCard 由可见标题命名。
81
+ - 控制台:未发现 warning 或 error。
82
+
83
+ ### 2026-09-04 — 0.2.0 候选
84
+
85
+ - 浏览器:Codex 内置 Chromium 浏览器。
86
+ - 视口:390 × 844、768 × 1024、1440 × 900。
87
+ - 结果:三档均无水平溢出;表单、按钮组、Tabs 与分页布局正常。
88
+ - 弹窗:手机全屏、桌面 560px 居中;首焦点、Tab 回环、Escape 关闭及触发按钮焦点恢复正常。
89
+ - 日期选择器:手机和平板均保持在视口内,Escape 可关闭。
90
+ - 控制台:未发现 warning 或 error。
91
+
92
+ 数字输入专项:在「表单控件」页检查数量千分位、聚焦取消分组、尾随小数点、Enter/失焦提交;缩放输入聚焦/点击全选;错误提示与禁用态。默认和触屏尺寸应与同行 TextInput 一致,窄屏无横向溢出。消费方既有 bareInput 门禁已覆盖原生数字输入,不新增重复扫描规则;替换本地包装后须缩减基线。
93
+
94
+ 输入装饰专项:在「表单控件」页检查搜索图标、清除按钮、货币符号、金额单位和百分号;桌面组合外框为 40px,粗指针触屏最小 44px。装饰存在与否不应改变标签、帮助、错误或输入值的可访问名称;键盘仍直接进入输入框和清除按钮。
95
+
96
+ ### 2026-09-06 数字输入 0.2.8
97
+
98
+ - 1440×900、390×844、320×480、768×1024、844×390 的表单页 DOM 边界检查通过,无文档水平溢出;桌面/390px 目检数字、错误和禁用样式一致,输入继承 40px 默认高度。
99
+ - 浏览器确认缩放输入聚焦全选 `1234.56`,输入 `1.005` 回车后显示 `1.01`;数量保留 `1234.` 草稿,失焦后显示 `1,234`。控制台无 warning/error。
100
+ - 本轮新增控件没有修改 CSS;触屏 44px 继续由既有 coarse-pointer 样式契约测试覆盖,未模拟手机软键盘。
101
+
102
+
103
+ ### 2026-09-11 — SegmentedControl 本地增强
104
+
105
+ - Chromium 桌面/Pixel 7 模拟:320×480、390×844、768×1024、1440×900、844×390 无页面水平溢出;粗指针全部选项点击高度至少 44px。
106
+ - 原生方向键跳过禁用项、横向/纵向循环选择与独立分组通过;390px 浅底、胶囊、纵向、纯图标、长文字和禁用态截图目检通过。新增 4 项浏览器检查通过,非真实手机验收。
107
+
108
+ ## 2026-09-11 — Cascader 本地接入
109
+
110
+ - Chromium 桌面与 Pixel 7 模拟,320×480、390×844、768×1024、1440×900、844×390 五档:三级展开无页面横向溢出;窄屏底部面板、44px 触控行、390px/1440px 截图目检通过。
111
+ - 部门父子独立多选、地址路径搜索与叶子选中后详细地址聚焦、弹窗内 portal、键盘选择及 Escape 分层关闭通过。输入占位不与摘要重叠,清空归一与必填搜索未选中由单测覆盖。
112
+ - 新增级联 6 项浏览器测试通过;全量 36 项浏览器、25 文件 133 项单测、类型、库与视觉矩阵构建通过;打包演练包含声明、专题和 MIT 许可。
113
+ - 本地待发布;尚未升级消费项目。触屏测试是浏览器模拟,非真实手机软键盘验收。复测:`pnpm exec playwright test e2e/cascader.spec.ts`。
114
+
115
+ ### 2026-09-14 PDFium 0.2.44
116
+ - Playwright Desktop Chrome / Pixel 7 六项定向验收通过:默认侧栏收起与往返开关、双指连续缩放、最小/最大比例、松手前后页面几何一致、业务叠层不误触。属于模拟触控,真实手机待消费方验收。
117
+
118
+ ### 2026-09-14 PDFium 0.2.46
119
+ - Desktop Chrome / Pixel 7 的8项手势专项通过:连续Ctrl/Meta滚轮、触屏缩放上下限、侧栏。77%起始跨越适宽边界,回传页码不再触发额外跳页,手势期间0次引擎缩放提交,每次结束仅1次。位置误差小于5 CSS像素、宽度误差小于0.5 CSS像素。原生路径复现额外跳页约304px,修复接入层后通过。
120
+ - pnpm精确补丁仅为官方2.15.0 React手势预览增加引擎一致的上下限和精度,保留官方CSS预览、虚拟滚动、延迟清晰重绘;未新增逐帧PDFium渲染。真机仍待用户复验。
121
+
122
+ ## 2026-09-14 — 0.2.47 横向滚动
123
+
124
+ Desktop Chrome / Pixel 7模拟视口共4项通过:50行8列表格,连续横向wheel位置不回退,同步条双向操作与固定高度原生滚动;原生模式无额外吸附条,纵向滚动表头仍可见。3项同步生命周期单测覆盖异步回传、每帧合并和卸载取消;修复前异步回传测试从140回退100,修复后保持140。模拟wheel不能替代真实触控板验收。
125
+
126
+ ## 2026-09-15 — SortableList目标项接收
127
+
128
+ Chromium桌面与Pixel 7视口,鼠标拖入目标、键盘选择目标/取消、禁止投放普通项、禁用手柄与宽度回归共6项通过;触屏视口为模拟,未宣称实机多指验证。2项排序单测及TypeScript通过。目标高亮复用主题令牌;领域移动由消费方处理。
129
+
130
+ ## 2026-09-15 / 0.2.50 嵌套拖动
131
+ - sortable-drop.spec.ts 与 sortable-width.spec.ts:桌面/Pixel7 模拟共14项通过,覆盖鼠标来源占位尺寸不变、进入组高亮、成员插入线、键盘移出/移回/组内排序与禁用宽度;TypeScript通过。键盘测试先等待嵌套列表的漫游焦点真正落到所选手柄,再按Enter,避免测试自身在焦点转移时启动拖动。不是实际触屏验收。
132
+ - 新增禁用切换页面错误捕获,避免误将组件崩溃当成隐藏手柄成功。React Aria hooks有无改变时通过显式GridList key切换。
133
+ - 嵌套指示器可能把目标key交给祖先回调,scope仅路由至唯一当前所属列表;一次拖动只消费一次。
134
+
135
+ - 首轮矩阵CI34971182111发现隐藏占位span使content不再是only-child,禁用行缩宽;占位仅在可拖动状态渲染,sortable-width回归验证。
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2019-present react-component
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2019-present react-component
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jc-times/business-ui",
3
- "version": "0.2.55",
3
+ "version": "0.3.0",
4
4
  "description": "Shared accessible business UI components for JC Times applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -55,6 +55,10 @@
55
55
  "import": "./dist/chinese-address-regions.js"
56
56
  },
57
57
  "./styles.css": "./dist/styles.css",
58
+ "./form-controls": {
59
+ "types": "./dist/types/form-controls.d.ts",
60
+ "import": "./dist/form-controls.js"
61
+ },
58
62
  "./document-viewer": {
59
63
  "types": "./dist/types/DocumentViewer.d.ts",
60
64
  "import": "./dist/document-viewer.js"