@jc-times/business-ui 0.3.1 → 0.4.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.
Files changed (65) hide show
  1. package/AGENTS.md +15 -0
  2. package/CHANGELOG.md +23 -0
  3. package/README.md +2 -0
  4. package/THIRD_PARTY_NOTICES.md +8 -0
  5. package/assets/pdf-fonts/NotoSans-Bold.ttf +0 -0
  6. package/assets/pdf-fonts/NotoSans-BoldItalic.ttf +0 -0
  7. package/assets/pdf-fonts/NotoSans-Italic.ttf +0 -0
  8. package/assets/pdf-fonts/NotoSans-Regular.ttf +0 -0
  9. package/assets/pdf-fonts/NotoSansHans-Regular.otf +0 -0
  10. package/assets/pdf-fonts/OFL-CJK.txt +92 -0
  11. package/assets/pdf-fonts/OFL-Latin.txt +94 -0
  12. package/assets/pdf-fonts/README.md +11 -0
  13. package/bin/business-ui-gate.mjs +2 -2
  14. package/dist/AntDateWheelView.js +131 -0
  15. package/dist/AntOptionWheelView.js +76 -0
  16. package/dist/Cascader.js +56 -51
  17. package/dist/DateInput.js +84 -66
  18. package/dist/DateWheelPicker.js +58 -0
  19. package/dist/ModalShell.js +84 -72
  20. package/dist/MultiSelect.js +5 -1
  21. package/dist/OptionWheelDialog.js +99 -0
  22. package/dist/Select.js +116 -61
  23. package/dist/StructuredAddressInput.js +72 -70
  24. package/dist/TreeSelect.js +4 -1
  25. package/dist/WheelCascader.js +123 -0
  26. package/dist/WheelDateInput.js +97 -0
  27. package/dist/business-ui.js +42 -39
  28. package/dist/date-wheel-model.js +27 -0
  29. package/dist/document-viewer-v2/DocumentViewerV2.js +49 -48
  30. package/dist/document-viewer-v2/HeadlessPdfViewer.js +128 -124
  31. package/dist/document-viewer-v2/pdf-font-fallback.js +35 -0
  32. package/dist/option-wheel-model.js +49 -0
  33. package/dist/styles.css +1 -1
  34. package/dist/types/AntDateWheelView.d.ts +9 -0
  35. package/dist/types/AntOptionWheelView.d.ts +8 -0
  36. package/dist/types/Cascader.d.ts +2 -0
  37. package/dist/types/DateInput.d.ts +4 -0
  38. package/dist/types/DateWheelPicker.d.ts +13 -0
  39. package/dist/types/ModalShell.d.ts +3 -1
  40. package/dist/types/OptionWheelDialog.d.ts +18 -0
  41. package/dist/types/Select.d.ts +4 -1
  42. package/dist/types/StructuredAddressInput.d.ts +3 -1
  43. package/dist/types/WheelCascader.d.ts +6 -0
  44. package/dist/types/WheelDateInput.d.ts +11 -0
  45. package/dist/types/date-wheel-model.d.ts +8 -0
  46. package/dist/types/document-viewer-v2/pdf-font-fallback.d.ts +2 -0
  47. package/dist/types/index.d.ts +3 -0
  48. package/dist/types/option-wheel-model.d.ts +19 -0
  49. package/dist/types/usePhoneWheel.d.ts +2 -0
  50. package/dist/types/useSheetViewport.d.ts +3 -0
  51. package/dist/usePhoneWheel.js +16 -0
  52. package/dist/useSheetViewport.js +26 -0
  53. package/docs/agent-guide.md +15 -5
  54. package/docs/api.md +14 -0
  55. package/docs/cascader.md +2 -0
  56. package/docs/component-strategy.md +3 -0
  57. package/docs/date-wheel.md +25 -0
  58. package/docs/dependencies.md +2 -0
  59. package/docs/document-viewer-v2.md +2 -2
  60. package/docs/mobile-controls.md +54 -0
  61. package/docs/modal-shell-migration.md +25 -0
  62. package/docs/release.md +7 -0
  63. package/docs/viewport-qa.md +38 -0
  64. package/licenses/antd-mobile-MIT.txt +22 -0
  65. package/package.json +17 -4
package/AGENTS.md CHANGED
@@ -1,6 +1,21 @@
1
1
  # 公共组件维护入口
2
2
 
3
+ 本仓同时维护根目录UI包与packages/business-sdk统一业务SDK。SDK开发先读[SDK维护入口](packages/business-sdk/AGENTS.md);UI本身不承担业务接口,SDK允许封装受信服务协议,两者独立构建/版本。不得递归公开发布工作区。
4
+
3
5
  - 开始组件使用、选型或修改前,先读 [Agent 使用指南](docs/agent-guide.md),再按需读取 API 和专题文档。
4
6
  - 公共参数以当前源码和导出为准;消费项目以其安装版本的类型声明为准,不把本地新增能力当成已发布能力。
5
7
  - 新增或改变公共能力时,同步指南的场景选型、对应 API/专题和 package.json 发布文件清单。README 保持入口与导航,详细用法集中维护。
6
8
  - 通用交互、无障碍与响应式在本库实现;业务权限、接口、领域状态与文案由消费方组合。验证和发布遵循 docs/viewport-qa.md 与 docs/release.md。
9
+
10
+ ## 统一版本号治理
11
+
12
+ - 产品、服务和公共包统一采用语义化版本 `MAJOR.MINOR.PATCH`。不再默认“每个完成批次都提升 PATCH”;一个发布批次按其中影响最大的变更决定版本级别,并在 PR、提交说明或发布记录中标明 `major`、`minor`、`patch` 或 `none`。
13
+ - `MAJOR`:任何不向后兼容的外部契约变化,包括删除或改变 API 字段/语义、认证或权限契约、配置格式、必须由调用方同步改造的行为,或不可逆/不兼容的数据迁移。
14
+ - `MINOR`:向后兼容的新业务能力、新接口、可选字段、可选配置或增量数据结构;已有调用方无需修改即可继续工作。版本级别按兼容性和能力变化判断,不按代码行数或实现工作量判断,因此代码很少但新增独立能力时仍属于 `MINOR`。
15
+ - `PATCH`:向后兼容的缺陷、安全、兼容性、性能和依赖修复,且不新增独立业务能力。小范围样式、交互或内部实现调整只要没有新增能力,通常属于 `PATCH`。仅文档、测试、注释、开发工具或不进入运行制品的变化使用 `none`,不提升产品版本;`none` 仍需要正常提交。
16
+ - 每个逻辑完整、经过相应基本验证的修改批次都必须及时提交 Git;不得把多个无关事项长期堆积为未提交改动,也不得等到正式发布才一次性提交。一个提交聚焦一个可说明、可审查、可回退的事项。只提交当前任务拥有的文件或精确变更,不得夹带用户或其他任务的既有改动。普通开发提交不强制修改产品版本或版本清单,commit 数量与版本号递增次数不绑定。
17
+ - 只有生成可部署、可安装或需要交付测试的开发制品时,才生成目标正式版本对应的 `X.Y.Z-dev.N`;进入验收使用 `X.Y.Z-rc.N`,正式版本不得带预发布后缀。每个开发/候选制品必须绑定准确 Git SHA,`N` 应由 CI 或仓库发布脚本按已存在制品自动分配,避免多人手工抢号;普通 commit 不为增加 `dev.N` 而修改清单。现有 `0.x` 历史不重排,不机械跳到 `1.0.0`;是否建立 `1.0.0` 稳定基线须单独明确决定。
18
+ - 产品版本、Git 提交、构建身份、镜像身份、API 路径版本、数据库迁移号和业务数据修订号是不同事实,不得混用。构建身份建议包含“服务名 + 产品版本 + 时间 + 短提交”;镜像必须可按不可变标签和 digest 追溯;API 只有不兼容契约才从 `/v1` 升 `/v2`;数据库迁移继续使用独立顺序;合同等业务 `V2/V3` 不属于软件版本。
19
+ - 每个正式发布必须使用唯一版本和 `v<版本>` 标签,并指向干净、已验证的提交;已发布或已打标签的版本不可覆盖、移动或复用。失败候选不占用新的正式版本。版本须通过仓库既有版本命令或唯一清单统一更新,禁止只手改部分清单;同时提交相应锁文件和生成元数据。
20
+ - 配置变化若改变可观察行为或契约,按上述规则提升版本;仅密钥轮换、同源码重建或无行为变化的重新部署不提升产品版本,只增加部署/构建记录。回滚是重新激活旧的不可变制品,不降低、重发或伪造版本;修复后前进发布使用新的 PATCH 或更高版本。
21
+ - CI/发布门禁应校验所有版本清单一致、目标版本大于现有正式版本、标签与提交一致、版本未被制品库占用,并保留“产品版本 + Git SHA + 构建 ID + 镜像 digest/运行时指纹”的核验链。本节优先于仓库中过去“每批固定加 PATCH”的笼统约定;更严格且不冲突的仓库发布门禁继续有效。
package/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## 0.4.0 — 2026-09-28(minor)
2
+
3
+ - 修复滚轮控件外部 ref 转发在 React 18 类型定义下无法编译的问题,兼容 React 18/19。
4
+
5
+ - 修复 MultiSelect 同时控制选中项与搜索词时,Escape/失焦关闭后因重放选中状态而重新打开候选层;自由搜索文本不成为业务 ID。桌面、手机弹窗内回归通过。
6
+
7
+ - 修复长单选值、勾选/开关标签及Alert编号在窄网格中的溢出;触屏展开、清空、关闭按钮及多选标签布局统一优化。
8
+ - 公开usePhoneWheel供消费方按需组合手机控件,电脑/平板保持既有交互。
9
+
10
+ - ModalShell/Dialog新增手机bottom-sheet模式,小表单内容高度贴底、上滑进入、固定底栏、安全区和VisualViewport键盘适配;默认全屏及桌面居中行为保留。
11
+
12
+ - Select、静态叶子单选Cascader与StructuredAddressInput新增可选手机滚轮;复用antd-mobile PickerView,确认式提交、父子联动、动态候选失效及键盘读屏支持,桌面/平板保持原模式。
13
+
14
+ - 新增独立年月日滚轮DateWheelPicker/WheelDateInput,DateInput可选手机滚轮适配;有界渲染、日期限制、取消/确认、键盘与触屏操作。
15
+ - ModalShell补齐嵌套重绘后Escape仅关闭最上层的回退,保留Radix焦点与浮层管理。
16
+ - 增加绑定SHA的私有UI开发包生成入口,不公开发布SDK或业务内容。
17
+
1
18
  # 0.3.1
2
19
 
3
20
  - 修复 `form-controls` 中图标从 `lucide-react` 根入口导入导致消费者打入完整图标集的问题。
@@ -321,3 +338,9 @@
321
338
 
322
339
  ## 0.2.52
323
340
  - AutoComplete and Combobox accept grouped options with non-selectable, muted headings and preserve filtering and keyboard selection.
341
+ # 0.3.2 — 2026-09-22 (patch)
342
+
343
+ - Render existing signature Widget appearances in Headless pages and thumbnails (`withForms: true`); rendering does not enable form editing or alter signed bytes. Add failed-before/passed-after Widget regression coverage.
344
+
345
+ - Fix missing Chinese and substituted Latin text in PDFs with unembedded fonts. Both PDFium viewers use stable same-origin Noto fallback configuration; assets and OFL licenses ship with the package, with no external CDN requests.
346
+ - Add desktop/mobile real PDF rendering coverage. Restoring `fontFallback: null` makes the same Chinese test fail with zero text pixels; explicit caller overrides remain supported.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ > 本仓也维护统一业务SDK(含反馈子入口),见 [SDK文档](packages/business-sdk/README.md)。UI包名、版本和公开发布流程保持独立。
2
+
1
3
  # @jc-times/business-ui
2
4
 
3
5
  精诚时代业务应用共用的 React 基础组件与交互标准。公共包负责通用 UI、无障碍与响应式;权限、接口、业务文案和合同、客户、订单、ERP 等领域状态由消费应用提供。
@@ -29,3 +29,11 @@
29
29
  MIT, Copyright (c) 2019-present react-component. Source: https://github.com/react-component/cascader. Used as the external Cascader interaction dependency; license reproduced in licenses/rc-cascader-MIT.txt. Transitive dependencies retain their own notices in their installed packages.
30
30
 
31
31
  0.2.46 additionally bundles the React gesture entry of @embedpdf/plugin-zoom@2.15.0 with a pinned bounds/precision patch. Original MIT license: licenses/embedpdf-MIT.txt; patch: patches/@embedpdf__plugin-zoom@2.15.0.patch. Engine and core plugin implementations remain external.
32
+ # PDF fallback fonts
33
+
34
+ `assets/pdf-fonts` contains unmodified Noto Sans Hans and Noto Sans fonts from
35
+ `@embedpdf/fonts-sc@1.0.0` and `@embedpdf/fonts-latin@1.0.0`, under SIL OFL 1.1.
36
+ See the accompanying `OFL-CJK.txt`, `OFL-Latin.txt`, and source README.
37
+
38
+ ## antd-mobile 5.43.0
39
+ MIT,来源https://github.com/ant-design/ant-design-mobile。仅按需使用DatePickerView与PickerView子模块,外置依赖;许可证见licenses/antd-mobile-MIT.txt,不复制源码或全量导入主题。
@@ -0,0 +1,92 @@
1
+ This Font Software is licensed under the SIL Open Font License,
2
+ Version 1.1.
3
+
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+ -----------------------------------------------------------
8
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
9
+ -----------------------------------------------------------
10
+
11
+ PREAMBLE
12
+ The goals of the Open Font License (OFL) are to stimulate worldwide
13
+ development of collaborative font projects, to support the font
14
+ creation efforts of academic and linguistic communities, and to
15
+ provide a free and open framework in which fonts may be shared and
16
+ improved in partnership with others.
17
+
18
+ The OFL allows the licensed fonts to be used, studied, modified and
19
+ redistributed freely as long as they are not sold by themselves. The
20
+ fonts, including any derivative works, can be bundled, embedded,
21
+ redistributed and/or sold with any software provided that any reserved
22
+ names are not used by derivative works. The fonts and derivatives,
23
+ however, cannot be released under any other type of license. The
24
+ requirement for fonts to remain under this license does not apply to
25
+ any document created using the fonts or their derivatives.
26
+
27
+ DEFINITIONS
28
+ "Font Software" refers to the set of files released by the Copyright
29
+ Holder(s) under this license and clearly marked as such. This may
30
+ include source files, build scripts and documentation.
31
+
32
+ "Reserved Font Name" refers to any names specified as such after the
33
+ copyright statement(s).
34
+
35
+ "Original Version" refers to the collection of Font Software
36
+ components as distributed by the Copyright Holder(s).
37
+
38
+ "Modified Version" refers to any derivative made by adding to,
39
+ deleting, or substituting -- in part or in whole -- any of the
40
+ components of the Original Version, by changing formats or by porting
41
+ the Font Software to a new environment.
42
+
43
+ "Author" refers to any designer, engineer, programmer, technical
44
+ writer or other person who contributed to the Font Software.
45
+
46
+ PERMISSION & CONDITIONS
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of the Font Software, to use, study, copy, merge, embed,
49
+ modify, redistribute, and sell modified and unmodified copies of the
50
+ Font Software, subject to the following conditions:
51
+
52
+ 1) Neither the Font Software nor any of its individual components, in
53
+ Original or Modified Versions, may be sold by itself.
54
+
55
+ 2) Original or Modified Versions of the Font Software may be bundled,
56
+ redistributed and/or sold with any software, provided that each copy
57
+ contains the above copyright notice and this license. These can be
58
+ included either as stand-alone text files, human-readable headers or
59
+ in the appropriate machine-readable metadata fields within text or
60
+ binary files as long as those fields can be easily viewed by the user.
61
+
62
+ 3) No Modified Version of the Font Software may use the Reserved Font
63
+ Name(s) unless explicit written permission is granted by the
64
+ corresponding Copyright Holder. This restriction only applies to the
65
+ primary font name as presented to the users.
66
+
67
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
68
+ Software shall not be used to promote, endorse or advertise any
69
+ Modified Version, except to acknowledge the contribution(s) of the
70
+ Copyright Holder(s) and the Author(s) or with their explicit written
71
+ permission.
72
+
73
+ 5) The Font Software, modified or unmodified, in part or in whole,
74
+ must be distributed entirely under this license, and must not be
75
+ distributed under any other license. The requirement for fonts to
76
+ remain under this license does not apply to any document created using
77
+ the Font Software.
78
+
79
+ TERMINATION
80
+ This license becomes null and void if any of the above conditions are
81
+ not met.
82
+
83
+ DISCLAIMER
84
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
86
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
87
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
88
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
89
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
90
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
91
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
92
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,94 @@
1
+ Copyright 2018 The Noto Project Authors (github.com/googlei18n/noto-fonts)
2
+
3
+ This Font Software is licensed under the SIL Open Font License,
4
+ Version 1.1.
5
+
6
+ This license is copied below, and is also available with a FAQ at:
7
+ http://scripts.sil.org/OFL
8
+
9
+ -----------------------------------------------------------
10
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
11
+ -----------------------------------------------------------
12
+
13
+ PREAMBLE
14
+ The goals of the Open Font License (OFL) are to stimulate worldwide
15
+ development of collaborative font projects, to support the font
16
+ creation efforts of academic and linguistic communities, and to
17
+ provide a free and open framework in which fonts may be shared and
18
+ improved in partnership with others.
19
+
20
+ The OFL allows the licensed fonts to be used, studied, modified and
21
+ redistributed freely as long as they are not sold by themselves. The
22
+ fonts, including any derivative works, can be bundled, embedded,
23
+ redistributed and/or sold with any software provided that any reserved
24
+ names are not used by derivative works. The fonts and derivatives,
25
+ however, cannot be released under any other type of license. The
26
+ requirement for fonts to remain under this license does not apply to
27
+ any document created using the fonts or their derivatives.
28
+
29
+ DEFINITIONS
30
+ "Font Software" refers to the set of files released by the Copyright
31
+ Holder(s) under this license and clearly marked as such. This may
32
+ include source files, build scripts and documentation.
33
+
34
+ "Reserved Font Name" refers to any names specified as such after the
35
+ copyright statement(s).
36
+
37
+ "Original Version" refers to the collection of Font Software
38
+ components as distributed by the Copyright Holder(s).
39
+
40
+ "Modified Version" refers to any derivative made by adding to,
41
+ deleting, or substituting -- in part or in whole -- any of the
42
+ components of the Original Version, by changing formats or by porting
43
+ the Font Software to a new environment.
44
+
45
+ "Author" refers to any designer, engineer, programmer, technical
46
+ writer or other person who contributed to the Font Software.
47
+
48
+ PERMISSION & CONDITIONS
49
+ Permission is hereby granted, free of charge, to any person obtaining
50
+ a copy of the Font Software, to use, study, copy, merge, embed,
51
+ modify, redistribute, and sell modified and unmodified copies of the
52
+ Font Software, subject to the following conditions:
53
+
54
+ 1) Neither the Font Software nor any of its individual components, in
55
+ Original or Modified Versions, may be sold by itself.
56
+
57
+ 2) Original or Modified Versions of the Font Software may be bundled,
58
+ redistributed and/or sold with any software, provided that each copy
59
+ contains the above copyright notice and this license. These can be
60
+ included either as stand-alone text files, human-readable headers or
61
+ in the appropriate machine-readable metadata fields within text or
62
+ binary files as long as those fields can be easily viewed by the user.
63
+
64
+ 3) No Modified Version of the Font Software may use the Reserved Font
65
+ Name(s) unless explicit written permission is granted by the
66
+ corresponding Copyright Holder. This restriction only applies to the
67
+ primary font name as presented to the users.
68
+
69
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
70
+ Software shall not be used to promote, endorse or advertise any
71
+ Modified Version, except to acknowledge the contribution(s) of the
72
+ Copyright Holder(s) and the Author(s) or with their explicit written
73
+ permission.
74
+
75
+ 5) The Font Software, modified or unmodified, in part or in whole,
76
+ must be distributed entirely under this license, and must not be
77
+ distributed under any other license. The requirement for fonts to
78
+ remain under this license does not apply to any document created using
79
+ the Font Software.
80
+
81
+ TERMINATION
82
+ This license becomes null and void if any of the above conditions are
83
+ not met.
84
+
85
+ DISCLAIMER
86
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
87
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
88
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
89
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
90
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
91
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
92
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
93
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
94
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,11 @@
1
+ # PDFium fallback fonts
2
+
3
+ Unmodified assets copied from exact npm packages `@embedpdf/fonts-sc@1.0.0`
4
+ and `@embedpdf/fonts-latin@1.0.0` (their `fonts/` directories). Noto Sans Hans
5
+ Regular provides Chinese glyphs; Noto Sans Regular/Bold/Italic/BoldItalic
6
+ provides Latin variants. Licenses accompany the font files.
7
+
8
+ The public viewer imports these through `@jc-times/business-ui/pdf-fonts/*?url`.
9
+ Consumer bundlers emit static same-origin assets. The renderer requests the
10
+ required font only when a PDF lacks its own font. These files must not be
11
+ inlined into the main JavaScript entry or loaded from a public CDN.
@@ -82,8 +82,8 @@ function scan(directory) {
82
82
  }
83
83
  if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
84
84
  const tag = node.tagName.getText(sourceFile);
85
- const hasClass = hasAttribute(node, "className");
86
- if (tag === "button" && !hasClass) counts.bareButton += 1;
85
+ // Styling does not provide the shared Button behavior or accessibility contract.
86
+ if (tag === "button") counts.bareButton += 1;
87
87
  if (tag === "input" && !exemptInput(node)) counts.bareInput += 1;
88
88
  if (tag === "select") counts.bareSelect += 1;
89
89
  if (tag === "textarea") counts.bareTextarea += 1;
@@ -0,0 +1,131 @@
1
+ import { clampWheelDate as e } from "./date-wheel-model.js";
2
+ import { useEffect as t, useLayoutEffect as n, useMemo as r, useRef as i } from "react";
3
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
4
+ import { CalendarDate as s } from "@internationalized/date";
5
+ import c from "antd-mobile/es/components/date-picker-view";
6
+ //#region src/AntDateWheelView.tsx
7
+ function l(e) {
8
+ let t = /* @__PURE__ */ new Date(0);
9
+ return t.setFullYear(e.year, e.month - 1, e.day), t.setHours(12, 0, 0, 0), t;
10
+ }
11
+ function u(e) {
12
+ return new s(e.getFullYear(), e.getMonth() + 1, e.getDate());
13
+ }
14
+ var d = [
15
+ "年",
16
+ "月",
17
+ "日"
18
+ ];
19
+ function f({ date: f, bounds: p, onValueChange: m, isDateUnavailable: h, disabled: g, readOnly: _, onPendingChange: v, "aria-label": y = "选择日期" }) {
20
+ let b = i(null), x = i(0), S = i(!1), C = i(v);
21
+ C.current = v;
22
+ let w = !!(g || _), T = r(() => l(e(new s(Math.max(1, f.year - 50), 1, 1), p)), [f.year, p.min.toString()]), E = r(() => l(e(new s(Math.min(9999, f.year + 50), 12, 31), p)), [f.year, p.max.toString()]), D = r(() => l(f), [f.toString()]), O = r(() => ({ day: (e, { date: t }) => !h?.(u(t).toString()) }), [h]);
23
+ function k(t) {
24
+ let n = e(t, p);
25
+ if (!w) {
26
+ if (h?.(n.toString())) {
27
+ let e;
28
+ for (let t = 1; t <= 30 && !e; t++) for (let r of [n.add({ days: t }), n.subtract({ days: t })]) if (r.year === n.year && r.month === n.month && r.compare(p.min) >= 0 && r.compare(p.max) <= 0 && !h(r.toString())) {
29
+ e = r;
30
+ break;
31
+ }
32
+ if (!e) return;
33
+ n = e;
34
+ }
35
+ m(n.toString());
36
+ }
37
+ }
38
+ n(() => {
39
+ let e = [
40
+ f.year,
41
+ f.month,
42
+ f.day
43
+ ], t = [
44
+ p.min.year,
45
+ f.year === p.min.year ? p.min.month : 1,
46
+ f.year === p.min.year && f.month === p.min.month ? p.min.day : 1
47
+ ], n = [
48
+ p.max.year,
49
+ f.year === p.max.year ? p.max.month : 12,
50
+ f.year === p.max.year && f.month === p.max.month ? p.max.day : f.calendar.getDaysInMonth(f)
51
+ ];
52
+ b.current?.querySelectorAll(".adm-picker-view-column").forEach((r, i) => {
53
+ r.tabIndex = w ? -1 : 0, r.setAttribute("role", "spinbutton"), r.setAttribute("aria-label", d[i]), r.setAttribute("aria-valuenow", String(e[i])), r.setAttribute("aria-valuetext", `${e[i]}${d[i]}`), r.setAttribute("aria-valuemin", String(t[i])), r.setAttribute("aria-valuemax", String(n[i])), r.setAttribute("aria-disabled", String(w)), r.querySelector(".adm-picker-view-column-accessible")?.setAttribute("aria-hidden", "true");
54
+ });
55
+ }), t(() => (C.current?.(!1), () => {
56
+ cancelAnimationFrame(x.current), C.current?.(!1);
57
+ }), []);
58
+ function A() {
59
+ w || (S.current = !0, cancelAnimationFrame(x.current), C.current?.(!0));
60
+ }
61
+ function j() {
62
+ S.current = !1, cancelAnimationFrame(x.current);
63
+ let e = "", t = performance.now();
64
+ function n(r) {
65
+ if (!b.current || S.current) return;
66
+ let i = [...b.current.querySelectorAll(".adm-picker-view-column-wheel")].map((e) => getComputedStyle(e).transform).join(";");
67
+ if (i !== e && (e = i, t = r), r - t >= 120) {
68
+ C.current?.(!1);
69
+ return;
70
+ }
71
+ x.current = requestAnimationFrame(n);
72
+ }
73
+ x.current = requestAnimationFrame(n);
74
+ }
75
+ function M(e) {
76
+ if (w) return;
77
+ let t = [...b.current?.querySelectorAll(".adm-picker-view-column") ?? []], n = t.indexOf(e.target);
78
+ if (n < 0) return;
79
+ if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
80
+ e.preventDefault(), t[(n + (e.key === "ArrowLeft" ? 2 : 1)) % 3]?.focus();
81
+ return;
82
+ }
83
+ if (![
84
+ "ArrowUp",
85
+ "ArrowDown",
86
+ "PageUp",
87
+ "PageDown",
88
+ "Home",
89
+ "End"
90
+ ].includes(e.key)) return;
91
+ e.preventDefault();
92
+ let r = [
93
+ "year",
94
+ "month",
95
+ "day"
96
+ ][n], i = e.key.includes("Up") ? -1 : 1;
97
+ if (e.key === "Home" || e.key === "End") {
98
+ let t = e.key === "Home";
99
+ k(f.set({ [r]: n === 0 ? t ? p.min.year : p.max.year : t ? 1 : n === 1 ? 12 : f.calendar.getDaysInMonth(f) }));
100
+ } else k(f.set({ [r]: f[r] + i * (e.key.startsWith("Page") ? 5 : 1) }));
101
+ }
102
+ return /* @__PURE__ */ o("div", {
103
+ ref: b,
104
+ className: "ui-date-wheel",
105
+ role: "group",
106
+ "aria-label": y,
107
+ "aria-disabled": w || void 0,
108
+ onKeyDown: M,
109
+ onTouchStartCapture: A,
110
+ onTouchEndCapture: j,
111
+ onTouchCancelCapture: j,
112
+ onMouseDownCapture: A,
113
+ onMouseUpCapture: j,
114
+ children: [/* @__PURE__ */ a("div", {
115
+ className: "ui-date-wheel-labels",
116
+ "aria-hidden": "true",
117
+ children: d.map((e) => /* @__PURE__ */ a("span", { children: e }, e))
118
+ }), /* @__PURE__ */ a(c, {
119
+ value: D,
120
+ min: T,
121
+ max: E,
122
+ precision: "day",
123
+ filter: O,
124
+ mouseWheel: !1,
125
+ renderLabel: (e, t) => `${t}${e === "year" ? "年" : e === "month" ? "月" : "日"}`,
126
+ onChange: (e) => k(u(e))
127
+ })]
128
+ });
129
+ }
130
+ //#endregion
131
+ export { f as default };
@@ -0,0 +1,76 @@
1
+ import { wheelText as e } from "./option-wheel-model.js";
2
+ import { useEffect as t, useLayoutEffect as n, useRef as r } from "react";
3
+ import { jsx as i } from "react/jsx-runtime";
4
+ import a from "antd-mobile/es/components/picker-view";
5
+ //#region src/AntOptionWheelView.tsx
6
+ function o({ columns: o, value: s, onChange: c, onPendingChange: l }) {
7
+ let u = r(null), d = r(0), f = r(!1), p = r(l);
8
+ p.current = l, n(() => {
9
+ u.current?.querySelectorAll(".adm-picker-view-column").forEach((t, n) => {
10
+ let r = o[n], i = r.findIndex((e) => e.value === s[n]);
11
+ t.tabIndex = 0, t.setAttribute("role", "spinbutton"), t.setAttribute("aria-label", o.length === 1 ? "选项" : `第${n + 1}级`), t.setAttribute("aria-valuenow", String(i + 1)), t.setAttribute("aria-valuemin", "1"), t.setAttribute("aria-valuemax", String(r.length)), t.setAttribute("aria-valuetext", i >= 0 ? e(r[i]) : "无可选项"), t.querySelector(".adm-picker-view-column-accessible")?.setAttribute("aria-hidden", "true");
12
+ });
13
+ }), t(() => (p.current(!1), () => {
14
+ cancelAnimationFrame(d.current);
15
+ }), []);
16
+ function m() {
17
+ f.current = !0, cancelAnimationFrame(d.current), p.current(!0);
18
+ }
19
+ function h() {
20
+ f.current = !1, cancelAnimationFrame(d.current);
21
+ let e = "", t = performance.now();
22
+ function n(r) {
23
+ if (!u.current || f.current) return;
24
+ let i = [...u.current.querySelectorAll(".adm-picker-view-column-wheel")].map((e) => getComputedStyle(e).transform).join(";");
25
+ if (i !== e && (e = i, t = r), r - t >= 120) {
26
+ p.current(!1);
27
+ return;
28
+ }
29
+ d.current = requestAnimationFrame(n);
30
+ }
31
+ d.current = requestAnimationFrame(n);
32
+ }
33
+ function g(e) {
34
+ let t = [...u.current?.querySelectorAll(".adm-picker-view-column") ?? []], n = t.indexOf(e.target);
35
+ if (n < 0 || f.current) return;
36
+ if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
37
+ e.preventDefault(), t[(n + (e.key === "ArrowLeft" ? t.length - 1 : 1)) % t.length]?.focus();
38
+ return;
39
+ }
40
+ if (![
41
+ "ArrowUp",
42
+ "ArrowDown",
43
+ "PageUp",
44
+ "PageDown",
45
+ "Home",
46
+ "End"
47
+ ].includes(e.key)) return;
48
+ e.preventDefault();
49
+ let r = o[n], i = r.findIndex((e) => e.value === s[n]), a = e.key.includes("Up") ? -1 : 1, l = e.key === "Home" ? 0 : e.key === "End" ? r.length - 1 : Math.max(0, Math.min(r.length - 1, i + a * (e.key.startsWith("Page") ? 5 : 1)));
50
+ c([...s.slice(0, n), r[l].value]);
51
+ }
52
+ return /* @__PURE__ */ i("div", {
53
+ ref: u,
54
+ className: "ui-date-wheel ui-option-wheel",
55
+ onKeyDown: g,
56
+ onTouchStartCapture: m,
57
+ onTouchEndCapture: h,
58
+ onTouchCancelCapture: h,
59
+ onMouseDownCapture: m,
60
+ onMouseUpCapture: h,
61
+ children: /* @__PURE__ */ i(a, {
62
+ columns: o.map((t) => t.map((t) => ({
63
+ value: t.value,
64
+ label: e(t)
65
+ }))),
66
+ value: s,
67
+ mouseWheel: !1,
68
+ onChange: (e) => {
69
+ let t = e.findIndex((e, t) => e !== s[t]);
70
+ t >= 0 && c(e.slice(0, t + 1).filter((e) => typeof e == "string"));
71
+ }
72
+ })
73
+ });
74
+ }
75
+ //#endregion
76
+ export { o as default };