@jc-times/business-ui 0.2.43 → 0.2.53

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 (44) hide show
  1. package/AGENTS.md +6 -6
  2. package/CHANGELOG.md +51 -14
  3. package/README.md +7 -7
  4. package/THIRD_PARTY_NOTICES.md +12 -10
  5. package/dist/Cascader.js +8 -0
  6. package/dist/Combobox.js +104 -61
  7. package/dist/DataTableHorizontalScrollbar.js +14 -11
  8. package/dist/FloatingControls.js +14 -13
  9. package/dist/MultilineAutoComplete.js +80 -0
  10. package/dist/SortableList.js +105 -32
  11. package/dist/UserProfilePopover.js +69 -0
  12. package/dist/_virtual/_rolldown/runtime.js +17 -0
  13. package/dist/business-ui.js +41 -38
  14. package/dist/document-viewer/PdfWorkspace.js +14 -12
  15. package/dist/document-viewer-v2/HeadlessPdfViewer.js +147 -142
  16. package/dist/sortable-transfer-scope.js +33 -0
  17. package/dist/styles.css +1 -1
  18. package/dist/types/Combobox.d.ts +1 -0
  19. package/dist/types/FloatingControls.d.ts +2 -1
  20. package/dist/types/MultilineAutoComplete.d.ts +20 -0
  21. package/dist/types/SortableList.d.ts +10 -2
  22. package/dist/types/UserProfilePopover.d.ts +20 -0
  23. package/dist/types/document-viewer/PdfWorkspace.d.ts +2 -1
  24. package/dist/types/document-viewer-v2/HeadlessPdfViewer.d.ts +1 -0
  25. package/dist/types/index.d.ts +2 -0
  26. package/dist/types/sortable-transfer-scope.d.ts +27 -0
  27. package/dist/vendor/embedpdf-zoom-react.js +187 -0
  28. package/docs/agent-guide.md +26 -3
  29. package/docs/api.md +39 -14
  30. package/docs/cascader.md +2 -0
  31. package/docs/component-strategy.md +1 -1
  32. package/docs/data-table.md +124 -120
  33. package/docs/dependencies.md +57 -57
  34. package/docs/document-viewer-v2.md +8 -0
  35. package/docs/document-viewer.md +28 -28
  36. package/docs/file-preparation.md +11 -11
  37. package/docs/maturity-migration.md +62 -62
  38. package/docs/mrt-poc.md +204 -204
  39. package/docs/release.md +32 -32
  40. package/docs/user-profile.md +17 -0
  41. package/docs/viewport-qa.md +37 -7
  42. package/licenses/embedpdf-MIT.txt +21 -0
  43. package/package.json +164 -161
  44. package/patches/@embedpdf__plugin-zoom@2.15.0.patch +77 -0
package/AGENTS.md CHANGED
@@ -1,6 +1,6 @@
1
- # 公共组件维护入口
2
-
3
- - 开始组件使用、选型或修改前,先读 [Agent 使用指南](docs/agent-guide.md),再按需读取 API 和专题文档。
4
- - 公共参数以当前源码和导出为准;消费项目以其安装版本的类型声明为准,不把本地新增能力当成已发布能力。
5
- - 新增或改变公共能力时,同步指南的场景选型、对应 API/专题和 package.json 发布文件清单。README 保持入口与导航,详细用法集中维护。
6
- - 通用交互、无障碍与响应式在本库实现;业务权限、接口、领域状态与文案由消费方组合。验证和发布遵循 docs/viewport-qa.md 与 docs/release.md。
1
+ # 公共组件维护入口
2
+
3
+ - 开始组件使用、选型或修改前,先读 [Agent 使用指南](docs/agent-guide.md),再按需读取 API 和专题文档。
4
+ - 公共参数以当前源码和导出为准;消费项目以其安装版本的类型声明为准,不把本地新增能力当成已发布能力。
5
+ - 新增或改变公共能力时,同步指南的场景选型、对应 API/专题和 package.json 发布文件清单。README 保持入口与导航,详细用法集中维护。
6
+ - 通用交互、无障碍与响应式在本库实现;业务权限、接口、领域状态与文案由消费方组合。验证和发布遵循 docs/viewport-qa.md 与 docs/release.md。
package/CHANGELOG.md CHANGED
@@ -1,17 +1,40 @@
1
- # 0.2.43
2
-
3
- - 新增语义化 `LinkButton`,以真实链接承载导航和文件下载,并复用 Button 的变体、尺寸、图标无障碍和禁用样式。
4
- - 收紧 `LinkButton` 的必填 `href` 契约;禁用链接保留可访问语义并隔离父级点击,补充下载属性、可访问名称和真实浏览器下载回归。
5
-
6
- # 0.2.42
7
-
8
- - DataTable 新增可选底部吸附横向滚动条,在内容溢出时显示并与 MRT 原生滚动区双向同步;支持业务化无障碍名称,默认不改变既有表格布局。
9
-
10
- # 0.2.41
11
-
12
- - 修复高分屏上 PDFium 左侧缩略图按设备像素尺寸显示而被裁切的问题;缩略图按插件逻辑尺寸完整缩放并保持高清渲染。
13
-
14
- # 0.2.40
1
+ # 0.2.53
2
+
3
+ - 新增 `UserProfilePopover`:紧凑的人员标签和只读资料卡,支持姓名、编号、部门、身份标签、头像与受控打开状态;资料卡随视口在 300–560px 间缩放,并保留键盘关闭与焦点归还。
4
+
5
+ ## 0.2.51
6
+ - Add MultilineAutoComplete: a single textarea with React Aria suggestions, explicit selection, free text and newlines. Preserves focus when choosing suggestions with mouse or touch.
7
+
8
+ ## 0.2.50
9
+ - SortableList supports scoped transfers between nested lists, source placeholders and insertion highlights; consumers retain membership and order updates.
10
+ - Fences stale/missing transfer items and resolves nested drop indicators to the unique current owner. Disabling drag remounts the React Aria grid to keep its hook topology stable.
11
+
12
+ # 0.2.49
13
+
14
+ - SortableList supports optional internal drop onto eligible items, with controlled domain callbacks and React Aria mouse, touch and keyboard behavior.
15
+
16
+ # 0.2.47
17
+
18
+ - 修复表格横向滚动同步条异步事件回写旧位置,避免中断触控板连续滚动;每帧最多同步一次,卸载时取消待执行同步。
19
+
20
+ # 0.2.45
21
+
22
+ - PDFium/Headless 正文和缩略图默认渲染 PDF 内已有批注(包括 Stamp 和 FreeText),修复审核文件签章提示缺失;不启用批注编辑,不改写源文件。
23
+
24
+ # 0.2.43
25
+
26
+ - 新增语义化 `LinkButton`,以真实链接承载导航和文件下载,并复用 Button 的变体、尺寸、图标无障碍和禁用样式。
27
+ - 收紧 `LinkButton` 的必填 `href` 契约;禁用链接保留可访问语义并隔离父级点击,补充下载属性、可访问名称和真实浏览器下载回归。
28
+
29
+ # 0.2.42
30
+
31
+ - DataTable 新增可选底部吸附横向滚动条,在内容溢出时显示并与 MRT 原生滚动区双向同步;支持业务化无障碍名称,默认不改变既有表格布局。
32
+
33
+ # 0.2.41
34
+
35
+ - 修复高分屏上 PDFium 左侧缩略图按设备像素尺寸显示而被裁切的问题;缩略图按插件逻辑尺寸完整缩放并保持高清渲染。
36
+
37
+ # 0.2.40
15
38
 
16
39
  - 公共 PDF 全屏在 Escape 时退出浏览器原生全屏,由 fullscreenchange 同步状态,避免退出按钮提前消失。
17
40
 
@@ -25,6 +48,11 @@
25
48
 
26
49
  # Changelog
27
50
 
51
+ ## 0.2.48
52
+
53
+ - Cascader:按可见视口处理多列展开的边缘碰撞,修复右侧表单区县列超出屏幕的问题。
54
+ - 回归:1280px 右侧340px表单旧逻辑浮层右边缘为1395px;修正后保持在1280px内。
55
+
28
56
  ## 0.2.37
29
57
 
30
58
  - Headless 新增可选 initialZoom="fit-width",通过官方缩放插件适配窄屏;既有默认比例与受控 zoom 保持兼容。
@@ -265,3 +293,12 @@
265
293
  - Cascader 取消聚焦自动展开:标签点击和 Tab 只聚焦;保留点击、输入搜索与方向键展开。
266
294
 
267
295
  - StructuredAddressInput 默认取消地址类型,海外使用顶级地区;旧模式显式启用时复用公共 Select,不再手写原生 select。
296
+
297
+ ## 0.2.44 — 2026-09-14
298
+ - PDFium 双指缩放使用统一引擎比例,修复松手边界回跳;增加 defaultRailCollapsed 侧栏初始配置。
299
+
300
+ ## 0.2.45 — 2026-09-14
301
+ - 恢复官方低开销触控缩放;修复可见页码回传造成的跳页,触屏/滚轮预览和提交使用同一缩放边界。
302
+
303
+ ## 0.2.52
304
+ - AutoComplete and Combobox accept grouped options with non-selectable, muted headings and preserve filtering and keyboard selection.
package/README.md CHANGED
@@ -21,18 +21,18 @@ React 等 peer dependencies 按所安装版本的 package.json 配置。应用
21
21
 
22
22
  | 文档 | 用途 |
23
23
  | --- | --- |
24
- | [Agent 使用指南](docs/agent-guide.md) | 场景选型、组件组合、边界和接入检查 |
25
- | [依赖维护](docs/dependencies.md) | 稳定版本核查、兼容例外、消费迁移要求 |
26
- | [公共 API](docs/api.md) | 公共行为、参数说明、数字输入与装饰示例;完整签名见安装包类型声明 |
27
- | [DataTable 与 MRT 迁移](docs/data-table.md) | 公共表格替代、旧参数兼容、完整配置、独立入口与合并明细;0.2.31起提供 |
28
- | [表格能力与 MRT 样例](docs/mrt-poc.md) | DataTable边界、筛选/列管理、产品行合并/展开、配置及性能;包含业务样例与公共API边界 |
24
+ | [Agent 使用指南](docs/agent-guide.md) | 场景选型、组件组合、边界和接入检查 |
25
+ | [依赖维护](docs/dependencies.md) | 稳定版本核查、兼容例外、消费迁移要求 |
26
+ | [公共 API](docs/api.md) | 公共行为、参数说明、数字输入与装饰示例;完整签名见安装包类型声明 |
27
+ | [DataTable 与 MRT 迁移](docs/data-table.md) | 公共表格替代、旧参数兼容、完整配置、独立入口与合并明细;0.2.31起提供 |
28
+ | [表格能力与 MRT 样例](docs/mrt-poc.md) | DataTable边界、筛选/列管理、产品行合并/展开、配置及性能;包含业务样例与公共API边界 |
29
29
  | [分段控制器](docs/api.md#分段控制器-segmentedcontrol) | 少量互斥选项、浅底/图标/纵向示例、兼容边界 |
30
30
  | [组件设计策略](docs/component-strategy.md) | 设计依据、公共能力范围和交互内核策略 |
31
31
  | [弹窗迁移](docs/modal-shell-migration.md) | header/content/footer 稳定插槽与历史写法迁移 |
32
32
  | [成熟度迁移](docs/maturity-migration.md) | 日期、多选、目录缓存、表格、文件限制及 Toast 行为 |
33
33
  | [上传前处理](docs/file-preparation.md) | 文件异步前处理、整批提交与取消 |
34
34
  | [文档查看器](docs/document-viewer.md) | PDF.js 与图片查看入口 |
35
- | [文档与图片查看器 V2](docs/document-viewer-v2.md) | PDFium/WASM、原生页面叠层、图片及 V1 兼容入口与迁移边界 |
35
+ | [文档与图片查看器 V2](docs/document-viewer-v2.md) | PDFium/WASM、原生页面叠层、图片及 V1 兼容入口与迁移边界 |
36
36
  | [多视口验收](docs/viewport-qa.md) | 桌面、移动与交互验证 |
37
37
  | [发布流程](docs/release.md) | registry、版本、制品与发布检查 |
38
38
  | [变更记录](CHANGELOG.md) | 按版本查看变化 |
@@ -52,4 +52,4 @@ React 等 peer dependencies 按所安装版本的 package.json 配置。应用
52
52
 
53
53
  仓库通过 `v<package.version>` 标签触发受控发布。公共包本地验证、正式发布、消费应用升级和生产部署是不同状态,应分别验证和记录。
54
54
 
55
- - [通用级联选择与部门/地址适配](docs/cascader.md)
55
+ - [通用级联选择与部门/地址适配](docs/cascader.md)
@@ -2,16 +2,16 @@
2
2
 
3
3
  `@jc-times/business-ui` 使用以下固定版本开源依赖。依赖源码未复制到本仓库;最终安装包由包管理器连同各自许可证一并解析。
4
4
 
5
- | Package | Version | License | Project |
6
- | --- | --- | --- | --- |
7
- | `lucide-react` | 1.45.0(开发验证版本) | ISC | https://github.com/lucide-icons/lucide |
8
- | `pdfjs-dist` | 6.3.289 | Apache-2.0 | https://github.com/mozilla/pdf.js |
9
- | `material-react-table` | 3.2.1 | MIT | https://github.com/KevinVandy/material-react-table |
10
- | `@mui/material`, `@mui/icons-material` | 7.3.11 | MIT | https://github.com/mui/material-ui |
11
- | `@mui/x-date-pickers` | 9.13.0 | MIT | https://github.com/mui/mui-x |
12
- | `@emotion/react`, `@emotion/styled` | 11.14.0 / 11.14.1 | MIT | https://github.com/emotion-js/emotion |
13
- | `@embedpdf/react-pdf-viewer` | 2.15.0 | MIT | https://github.com/embedpdf/embed-pdf-viewer |
14
- | `@embedpdf/core`, `@embedpdf/engines`, `@embedpdf/plugin-document-manager`, `@embedpdf/plugin-viewport`, `@embedpdf/plugin-scroll`, `@embedpdf/plugin-render`, `@embedpdf/plugin-zoom`, `@embedpdf/plugin-rotate`, `@embedpdf/plugin-thumbnail` | 2.15.0 | MIT | https://github.com/embedpdf/embed-pdf-viewer |
5
+ | Package | Version | License | Project |
6
+ | --- | --- | --- | --- |
7
+ | `lucide-react` | 1.45.0(开发验证版本) | ISC | https://github.com/lucide-icons/lucide |
8
+ | `pdfjs-dist` | 6.3.289 | Apache-2.0 | https://github.com/mozilla/pdf.js |
9
+ | `material-react-table` | 3.2.1 | MIT | https://github.com/KevinVandy/material-react-table |
10
+ | `@mui/material`, `@mui/icons-material` | 7.3.11 | MIT | https://github.com/mui/material-ui |
11
+ | `@mui/x-date-pickers` | 9.13.0 | MIT | https://github.com/mui/mui-x |
12
+ | `@emotion/react`, `@emotion/styled` | 11.14.0 / 11.14.1 | MIT | https://github.com/emotion-js/emotion |
13
+ | `@embedpdf/react-pdf-viewer` | 2.15.0 | MIT | https://github.com/embedpdf/embed-pdf-viewer |
14
+ | `@embedpdf/core`, `@embedpdf/engines`, `@embedpdf/plugin-document-manager`, `@embedpdf/plugin-viewport`, `@embedpdf/plugin-scroll`, `@embedpdf/plugin-render`, `@embedpdf/plugin-zoom`, `@embedpdf/plugin-rotate`, `@embedpdf/plugin-thumbnail` | 2.15.0 | MIT | https://github.com/embedpdf/embed-pdf-viewer |
15
15
  | PDFium(由 `@embedpdf/pdfium` 随查看器分发) | 2.15.0 | BSD-3-Clause / Apache-2.0 等,详见依赖内 `LICENSE.pdfium` | https://pdfium.googlesource.com/pdfium/ |
16
16
  | `@radix-ui/react-popover` | 1.1.23 | MIT | https://github.com/radix-ui/primitives |
17
17
  | `@radix-ui/react-dialog` | 1.1.23 | MIT | https://github.com/radix-ui/primitives |
@@ -27,3 +27,5 @@
27
27
  ## @rc-component/cascader 1.25.0
28
28
 
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
+
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.
package/dist/Cascader.js CHANGED
@@ -53,6 +53,14 @@ function m(m) {
53
53
  displayRender: (e) => e.join(" / "),
54
54
  getPopupContainer: (e) => x instanceof HTMLElement ? x : e.ownerDocument.body,
55
55
  popupMatchSelectWidth: !1,
56
+ popupAlign: {
57
+ htmlRegion: "visible",
58
+ overflow: {
59
+ adjustX: 1,
60
+ adjustY: 1,
61
+ shiftX: !0
62
+ }
63
+ },
56
64
  components: { input: /* @__PURE__ */ d("input", {
57
65
  ...S,
58
66
  ref: O,
package/dist/Combobox.js CHANGED
@@ -1,106 +1,149 @@
1
1
  import { useOverlayContainer as e } from "./OverlayContainer.js";
2
2
  import { Check as t, ChevronDown as n, LoaderCircle as r } from "lucide-react";
3
- import { useId as i, useMemo as a } from "react";
4
- import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
5
- import { Button as l, ComboBox as u, Input as d, Label as f, ListBox as p, ListBoxItem as m, Popover as h, Text as g } from "react-aria-components";
6
- import { ListLayout as _, Virtualizer as v } from "react-aria-components/Virtualizer";
3
+ import { useContext as i, useEffect as a, useId as o, useMemo as s, useRef as c } from "react";
4
+ import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
5
+ import { Button as f, Collection as p, ComboBox as m, ComboBoxStateContext as h, Header as g, Input as _, Label as v, ListBox as y, ListBoxItem as b, ListBoxSection as x, Popover as S, Text as C } from "react-aria-components";
6
+ import { ListLayout as w, Virtualizer as T } from "react-aria-components/Virtualizer";
7
7
  //#region src/Combobox.tsx
8
- var y = {
8
+ var E = {
9
9
  rowSize: 48,
10
10
  gap: 2,
11
11
  padding: 4
12
12
  };
13
- function b({ items: b, label: x, placeholder: S = "搜索或选择", inputValue: C, defaultInputValue: w, selectedKey: T, defaultSelectedKey: E, onInputChange: D, onSelectionChange: O, loading: k = !1, disabled: A = !1, required: j = !1, allowsCustomValue: M = !1, emptyText: N = "没有匹配项", helpText: P, error: F, virtualized: I = b.length > 100, className: L = "", inputRef: R, inputProps: z, placement: B = "bottom start", portalContainer: V }) {
14
- let H = `ui-combobox-${i().replaceAll(":", "")}`, U = e(V), W = a(() => Array.from(b), [b]), G = /* @__PURE__ */ s(p, {
13
+ function D({ items: i, label: a, placeholder: c = "搜索或选择", inputValue: h, defaultInputValue: D, selectedKey: k, defaultSelectedKey: A, onInputChange: j, onSelectionChange: M, loading: N = !1, disabled: P = !1, required: F = !1, allowsCustomValue: I = !1, emptyText: L = "没有匹配项", helpText: R, error: z, virtualized: B = i.length > 100, className: V = "", inputRef: H, inputProps: U, placement: W = "bottom start", portalContainer: G }) {
14
+ let K = `ui-combobox-${o().replaceAll(":", "")}`, q = e(G), J = s(() => Array.from(i), [i]), Y = s(() => {
15
+ let e = /* @__PURE__ */ new Map();
16
+ for (let t of J) {
17
+ let n = t.group ?? "";
18
+ e.has(n) || e.set(n, {
19
+ id: `group:${n}`,
20
+ label: n,
21
+ items: []
22
+ }), e.get(n).items.push(t);
23
+ }
24
+ return Array.from(e.values());
25
+ }, [J]), X = J.some((e) => e.group !== void 0), Z = (e) => /* @__PURE__ */ u(b, {
26
+ id: e.id,
27
+ textValue: e.label,
28
+ isDisabled: e.disabled,
29
+ className: "ui-combobox-item",
30
+ children: ({ isSelected: n }) => /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ d("span", { children: [/* @__PURE__ */ u("strong", { children: e.label }), e.description && /* @__PURE__ */ u("small", { children: e.description })] }), n && /* @__PURE__ */ u(t, {
31
+ size: 15,
32
+ "aria-hidden": "true"
33
+ })] })
34
+ }), Q = () => /* @__PURE__ */ u("div", {
35
+ className: "ui-combobox-empty",
36
+ children: N ? "正在加载…" : L
37
+ }), $ = X ? /* @__PURE__ */ u(y, {
15
38
  className: "ui-combobox-list",
16
- items: W,
17
- layout: I ? "grid" : "stack",
18
- renderEmptyState: () => /* @__PURE__ */ s("div", {
19
- className: "ui-combobox-empty",
20
- children: k ? "正在加载…" : N
21
- }),
22
- children: (e) => /* @__PURE__ */ s(m, {
39
+ items: Y,
40
+ layout: "stack",
41
+ renderEmptyState: Q,
42
+ children: (e) => /* @__PURE__ */ d(x, {
23
43
  id: e.id,
24
- textValue: e.label,
25
- isDisabled: e.disabled,
26
- className: "ui-combobox-item",
27
- children: ({ isSelected: n }) => /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ c("span", { children: [/* @__PURE__ */ s("strong", { children: e.label }), e.description && /* @__PURE__ */ s("small", { children: e.description })] }), n && /* @__PURE__ */ s(t, {
28
- size: 15,
29
- "aria-hidden": "true"
30
- })] })
44
+ "aria-label": e.label || "选项",
45
+ children: [e.label && /* @__PURE__ */ u(g, {
46
+ className: "ui-combobox-group-heading",
47
+ children: e.label
48
+ }), /* @__PURE__ */ u(p, {
49
+ items: e.items,
50
+ children: Z
51
+ })]
31
52
  })
53
+ }) : /* @__PURE__ */ u(y, {
54
+ className: "ui-combobox-list",
55
+ items: J,
56
+ layout: B ? "grid" : "stack",
57
+ renderEmptyState: Q,
58
+ children: Z
32
59
  });
33
- return /* @__PURE__ */ c(u, {
34
- className: `ui-combobox ${L}`.trim(),
35
- inputValue: C,
36
- defaultInputValue: w,
37
- selectedKey: T,
38
- defaultSelectedKey: E,
39
- onInputChange: D,
40
- onSelectionChange: (e) => O?.(e === null ? null : String(e)),
41
- isDisabled: A,
42
- isRequired: j,
43
- allowsCustomValue: M,
60
+ return /* @__PURE__ */ d(m, {
61
+ items: J,
62
+ className: `ui-combobox ${V}`.trim(),
63
+ inputValue: h,
64
+ defaultInputValue: D,
65
+ selectedKey: k,
66
+ defaultSelectedKey: A,
67
+ onInputChange: j,
68
+ onSelectionChange: (e) => M?.(e === null ? null : String(e)),
69
+ isDisabled: P,
70
+ isRequired: F,
71
+ allowsCustomValue: I,
44
72
  menuTrigger: "focus",
45
- "aria-label": x === void 0 ? z?.["aria-label"] : void 0,
46
- "aria-labelledby": x === void 0 ? z?.["aria-labelledby"] : void 0,
73
+ "aria-label": a === void 0 ? U?.["aria-label"] : void 0,
74
+ "aria-labelledby": a === void 0 ? U?.["aria-labelledby"] : void 0,
47
75
  children: [
48
- x === void 0 ? null : /* @__PURE__ */ c(f, {
76
+ a === void 0 ? null : /* @__PURE__ */ d(v, {
49
77
  className: "ui-form-label",
50
- children: [x, j && /* @__PURE__ */ s("span", {
78
+ children: [a, F && /* @__PURE__ */ u("span", {
51
79
  className: "ui-form-required",
52
80
  "aria-hidden": "true",
53
81
  children: "*"
54
82
  })]
55
83
  }),
56
- /* @__PURE__ */ c("div", {
84
+ I && /* @__PURE__ */ u(O, {
85
+ count: J.length,
86
+ loading: N
87
+ }),
88
+ /* @__PURE__ */ d("div", {
57
89
  className: "ui-combobox-control",
58
- children: [/* @__PURE__ */ s(d, {
59
- ...z,
60
- ref: R,
61
- id: H,
90
+ children: [/* @__PURE__ */ u(_, {
91
+ ...U,
92
+ ref: H,
93
+ id: K,
62
94
  className: "ui-input",
63
- placeholder: S,
64
- "aria-invalid": F ? !0 : z?.["aria-invalid"]
65
- }), /* @__PURE__ */ s(l, {
95
+ placeholder: c,
96
+ "aria-invalid": z ? !0 : U?.["aria-invalid"]
97
+ }), /* @__PURE__ */ u(f, {
66
98
  className: "ui-combobox-trigger",
67
99
  "aria-label": "展开选项",
68
- children: k ? /* @__PURE__ */ s(r, {
100
+ children: N ? /* @__PURE__ */ u(r, {
69
101
  className: "spin",
70
102
  size: 16
71
- }) : /* @__PURE__ */ s(n, { size: 16 })
103
+ }) : /* @__PURE__ */ u(n, { size: 16 })
72
104
  })]
73
105
  }),
74
- P === void 0 ? null : /* @__PURE__ */ s(g, {
106
+ R === void 0 ? null : /* @__PURE__ */ u(C, {
75
107
  slot: "description",
76
108
  className: "ui-form-help",
77
- children: P
109
+ children: R
78
110
  }),
79
- F === void 0 || F === "" ? null : /* @__PURE__ */ s(g, {
111
+ z === void 0 || z === "" ? null : /* @__PURE__ */ u(C, {
80
112
  slot: "errorMessage",
81
113
  className: "ui-form-error",
82
- children: F
114
+ children: z
83
115
  }),
84
- /* @__PURE__ */ c(h, {
116
+ /* @__PURE__ */ d(S, {
85
117
  className: "ui-combobox-popover",
86
118
  "data-ui-aria-overlay": "",
87
119
  maxHeight: 320,
88
- placement: B,
89
- UNSTABLE_portalContainer: U,
90
- children: [k && /* @__PURE__ */ c("div", {
120
+ placement: W,
121
+ UNSTABLE_portalContainer: q,
122
+ children: [N && /* @__PURE__ */ d("div", {
91
123
  className: "ui-combobox-loading",
92
- children: [/* @__PURE__ */ s(r, {
124
+ children: [/* @__PURE__ */ u(r, {
93
125
  className: "spin",
94
126
  size: 15
95
127
  }), "正在加载"]
96
- }), I ? /* @__PURE__ */ s(v, {
97
- layout: _,
98
- layoutOptions: y,
99
- children: G
100
- }) : G]
128
+ }), B ? /* @__PURE__ */ u(T, {
129
+ layout: w,
130
+ layoutOptions: E,
131
+ children: $
132
+ }) : $]
101
133
  })
102
134
  ]
103
135
  });
104
136
  }
137
+ function O({ count: e, loading: t }) {
138
+ let n = i(h), r = c(n);
139
+ return r.current = n, a(() => {
140
+ let n = r.current;
141
+ e && !t && n?.isFocused && !n.isOpen && n.open(null, "manual");
142
+ }, [
143
+ e,
144
+ t,
145
+ n?.collection.size
146
+ ]), null;
147
+ }
105
148
  //#endregion
106
- export { b as Combobox };
149
+ export { D as Combobox };
@@ -7,18 +7,21 @@ function a({ children: a, enabled: o = !1, label: s = "表格横向滚动" }) {
7
7
  if (!o) return;
8
8
  let e = c.current, t = l.current, n = e?.querySelector(".MuiTableContainer-root"), r = n?.querySelector("table");
9
9
  if (!e || !t || !n || !r) return;
10
- let i = !1, a = () => {
10
+ let i = /* @__PURE__ */ new WeakMap(), a, s, u = (e, t) => {
11
+ t.scrollLeft !== e.scrollLeft && (t.scrollLeft = e.scrollLeft, i.set(t, t.scrollLeft));
12
+ }, f = (e) => {
13
+ let r = e === n ? t : n;
14
+ i.get(e) !== e.scrollLeft && r.scrollLeft !== e.scrollLeft && (i.delete(e), s = e, a === void 0 && (a = requestAnimationFrame(() => {
15
+ a = void 0, s && u(s, s === n ? t : n);
16
+ })));
17
+ }, p = () => {
11
18
  let e = n.scrollWidth > n.clientWidth + 1;
12
- d(e ? n.scrollWidth : 0), e && (t.scrollLeft = n.scrollLeft);
13
- }, s = () => {
14
- i ||= (i = !0, n.scrollLeft = t.scrollLeft, !1);
15
- }, u = () => {
16
- i ||= (i = !0, t.scrollLeft = n.scrollLeft, !1);
17
- };
18
- a();
19
- let f = typeof ResizeObserver > "u" ? null : new ResizeObserver(a);
20
- return f?.observe(n), f?.observe(r), t.addEventListener("scroll", s, { passive: !0 }), n.addEventListener("scroll", u, { passive: !0 }), () => {
21
- f?.disconnect(), t.removeEventListener("scroll", s), n.removeEventListener("scroll", u);
19
+ d(e ? n.scrollWidth : 0), e && u(n, t);
20
+ }, m = () => f(t), h = () => f(n);
21
+ p();
22
+ let g = typeof ResizeObserver > "u" ? null : new ResizeObserver(p);
23
+ return g?.observe(n), g?.observe(r), t.addEventListener("scroll", m, { passive: !0 }), n.addEventListener("scroll", h, { passive: !0 }), () => {
24
+ g?.disconnect(), a !== void 0 && cancelAnimationFrame(a), t.removeEventListener("scroll", m), n.removeEventListener("scroll", h);
22
25
  };
23
26
  }, [o]), o ? /* @__PURE__ */ i("div", {
24
27
  ref: c,
@@ -30,34 +30,35 @@ function l({ children: e, content: n, side: r = "top", delayDuration: i = 450, d
30
30
  })] })
31
31
  });
32
32
  }
33
- function u({ trigger: e, children: i, title: c, closeLabel: l = "关闭", side: u = "bottom", align: d = "start", open: f, defaultOpen: p, modal: m = !1, onOpenChange: h, contentClassName: g = "" }) {
34
- let _ = t(), v = `ui-popover-title-${r().replaceAll(":", "")}`;
33
+ function u({ trigger: e, children: i, title: c, contentLabel: l, closeLabel: u = "关闭", side: d = "bottom", align: f = "start", open: p, defaultOpen: m, modal: h = !1, onOpenChange: g, contentClassName: _ = "" }) {
34
+ let v = t(), y = `ui-popover-title-${r().replaceAll(":", "")}`;
35
35
  return /* @__PURE__ */ o(s.Root, {
36
- open: f,
37
- defaultOpen: p,
38
- modal: m,
39
- onOpenChange: h,
36
+ open: p,
37
+ defaultOpen: m,
38
+ modal: h,
39
+ onOpenChange: g,
40
40
  children: [/* @__PURE__ */ a(s.Trigger, {
41
41
  asChild: !0,
42
42
  children: e
43
43
  }), /* @__PURE__ */ a(s.Portal, {
44
- container: _,
44
+ container: v,
45
45
  children: /* @__PURE__ */ o(s.Content, {
46
- className: `ui-popover ${g}`.trim(),
47
- side: u,
48
- align: d,
46
+ className: `ui-popover ${_}`.trim(),
47
+ side: d,
48
+ align: f,
49
49
  sideOffset: 8,
50
50
  collisionPadding: 12,
51
- "aria-labelledby": c === void 0 ? void 0 : v,
51
+ "aria-label": l,
52
+ "aria-labelledby": c === void 0 ? void 0 : y,
52
53
  children: [
53
54
  c === void 0 ? null : /* @__PURE__ */ o("div", {
54
55
  className: "ui-popover-heading",
55
56
  children: [/* @__PURE__ */ a("strong", {
56
- id: v,
57
+ id: y,
57
58
  children: c
58
59
  }), /* @__PURE__ */ a(s.Close, {
59
60
  className: "ui-floating-close",
60
- "aria-label": l,
61
+ "aria-label": u,
61
62
  children: /* @__PURE__ */ a(n, { size: 16 })
62
63
  })]
63
64
  }),
@@ -0,0 +1,80 @@
1
+ import { useOverlayContainer as e } from "./OverlayContainer.js";
2
+ import { useRef as t, useState as n } from "react";
3
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
4
+ import { Autocomplete as a, Label as o, ListBox as s, ListBoxItem as c, Popover as l, TextArea as u, TextField as d } from "react-aria-components";
5
+ //#region src/MultilineAutoComplete.tsx
6
+ function f(f) {
7
+ let p = t(null), m = t(null), [h, g] = n(!1), [_, v] = n(!1), y = e(f.portalContainer), b = f.items.filter((e) => e.label.toLocaleLowerCase().includes(f.value.toLocaleLowerCase()));
8
+ return /* @__PURE__ */ i("div", {
9
+ className: `ui-multiline-autocomplete ${f.className ?? ""}`,
10
+ children: [
11
+ /* @__PURE__ */ i(a, {
12
+ disableAutoFocusFirst: !0,
13
+ inputValue: f.value,
14
+ onInputChange: (e) => {
15
+ v(!1), f.onChange(e);
16
+ },
17
+ children: [/* @__PURE__ */ i(d, {
18
+ "aria-label": f["aria-label"],
19
+ isDisabled: f.disabled,
20
+ onFocus: () => {
21
+ g(!0), v(!1), f.onFocus?.();
22
+ },
23
+ onBlur: (e) => {
24
+ m.current?.contains(e.relatedTarget) || (g(!1), f.onBlur?.());
25
+ },
26
+ children: [f.label !== void 0 && /* @__PURE__ */ r(o, {
27
+ className: "ui-form-label",
28
+ children: f.label
29
+ }), /* @__PURE__ */ r(u, {
30
+ ref: p,
31
+ className: "ui-input ui-multiline-input",
32
+ placeholder: f.placeholder,
33
+ rows: Math.min(6, f.value.split("\n").length)
34
+ })]
35
+ }), /* @__PURE__ */ r(l, {
36
+ ref: m,
37
+ triggerRef: p,
38
+ isNonModal: !0,
39
+ isOpen: h && !_ && !f.disabled && b.length > 0,
40
+ onOpenChange: (e) => {
41
+ e || v(!0);
42
+ },
43
+ UNSTABLE_portalContainer: y,
44
+ placement: "bottom start",
45
+ className: "ui-combobox-popover",
46
+ "data-ui-aria-overlay": "",
47
+ maxHeight: 260,
48
+ children: /* @__PURE__ */ r(s, {
49
+ "aria-label": "输入建议",
50
+ className: "ui-combobox-list",
51
+ items: b,
52
+ selectionMode: "none",
53
+ onAction: (e) => {
54
+ let t = b.find((t) => t.id === String(e));
55
+ t && !t.disabled && (f.onChange(t.label), f.onSelect?.(t), v(!0), p.current?.focus());
56
+ },
57
+ children: (e) => /* @__PURE__ */ r(c, {
58
+ id: e.id,
59
+ textValue: e.label,
60
+ isDisabled: e.disabled,
61
+ className: "ui-combobox-item",
62
+ children: /* @__PURE__ */ i("span", { children: [/* @__PURE__ */ r("strong", { children: e.label }), e.description && /* @__PURE__ */ r("small", { children: e.description })] })
63
+ })
64
+ })
65
+ })]
66
+ }),
67
+ f.loading && /* @__PURE__ */ r("span", {
68
+ role: "status",
69
+ className: "ui-form-help",
70
+ children: "正在查找…"
71
+ }),
72
+ f.helpText && /* @__PURE__ */ r("span", {
73
+ className: "ui-form-help",
74
+ children: f.helpText
75
+ })
76
+ ]
77
+ });
78
+ }
79
+ //#endregion
80
+ export { f as MultilineAutoComplete };