@jc-times/business-ui 0.2.43

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 (154) hide show
  1. package/AGENTS.md +6 -0
  2. package/CHANGELOG.md +267 -0
  3. package/README.md +55 -0
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/bin/business-ui-gate.mjs +171 -0
  6. package/dist/Alert.js +47 -0
  7. package/dist/AsyncDirectoryPicker.js +134 -0
  8. package/dist/AsyncSearchPicker.js +155 -0
  9. package/dist/AutoComplete.js +34 -0
  10. package/dist/Badge.js +14 -0
  11. package/dist/Button.js +54 -0
  12. package/dist/Cascader.js +141 -0
  13. package/dist/Combobox.js +106 -0
  14. package/dist/ConfirmDialog.js +48 -0
  15. package/dist/DataTableHorizontalScrollbar.js +38 -0
  16. package/dist/DataTableIcons.js +37 -0
  17. package/dist/DataTableMergedRows.js +45 -0
  18. package/dist/DataTableTheme.js +135 -0
  19. package/dist/DateInput.js +223 -0
  20. package/dist/DropdownMenu.js +130 -0
  21. package/dist/EmptyState.js +27 -0
  22. package/dist/ExplainableButton.js +68 -0
  23. package/dist/FileDropzone.js +70 -0
  24. package/dist/FilePreparationDialog.js +33 -0
  25. package/dist/FloatingControls.js +120 -0
  26. package/dist/FormField.js +143 -0
  27. package/dist/MetricCard.js +38 -0
  28. package/dist/ModalShell.js +139 -0
  29. package/dist/MultiSelect.js +137 -0
  30. package/dist/NumericInput.js +97 -0
  31. package/dist/OverlayContainer.js +9 -0
  32. package/dist/PageHeader.js +36 -0
  33. package/dist/Pagination.js +115 -0
  34. package/dist/PreparedFileDropzone.js +30 -0
  35. package/dist/RecoverableAsyncState.js +35 -0
  36. package/dist/RovingTabs.js +54 -0
  37. package/dist/SectionCard.js +35 -0
  38. package/dist/SegmentedControl.js +46 -0
  39. package/dist/Select.js +73 -0
  40. package/dist/Skeleton.js +25 -0
  41. package/dist/SortableList.js +55 -0
  42. package/dist/StructuredAddressInput.js +157 -0
  43. package/dist/Toast.js +100 -0
  44. package/dist/ToggleSwitch.js +34 -0
  45. package/dist/TreeSelect.js +444 -0
  46. package/dist/amount-format.js +20 -0
  47. package/dist/business-ui.js +44 -0
  48. package/dist/chinese-address-regions.js +15 -0
  49. package/dist/classNames.js +6 -0
  50. package/dist/data-table.js +257 -0
  51. package/dist/document-render-budget.js +22 -0
  52. package/dist/document-viewer/ContinuousPdfViewer.js +145 -0
  53. package/dist/document-viewer/DocumentViewer.js +123 -0
  54. package/dist/document-viewer/DocumentViewerViewport.js +36 -0
  55. package/dist/document-viewer/ImagePage.js +39 -0
  56. package/dist/document-viewer/PdfCanvasPage.js +26 -0
  57. package/dist/document-viewer/PdfThumbnailRail.js +116 -0
  58. package/dist/document-viewer/PdfToolbar.js +61 -0
  59. package/dist/document-viewer/PdfWorkspace.js +42 -0
  60. package/dist/document-viewer/pdf-render-budget.js +7 -0
  61. package/dist/document-viewer/usePdfCanvas.js +69 -0
  62. package/dist/document-viewer/usePdfViewport.js +48 -0
  63. package/dist/document-viewer-v2/DocumentViewerV2.js +171 -0
  64. package/dist/document-viewer-v2/HeadlessPdfViewer.js +420 -0
  65. package/dist/document-viewer-v2/HeadlessSearch.js +66 -0
  66. package/dist/document-viewer-v2.js +13 -0
  67. package/dist/document-viewer.js +12 -0
  68. package/dist/pdfium-viewer.js +18 -0
  69. package/dist/styles.css +2 -0
  70. package/dist/types/Alert.d.ts +11 -0
  71. package/dist/types/AmountFormat.d.ts +15 -0
  72. package/dist/types/AsyncDirectoryPicker.d.ts +32 -0
  73. package/dist/types/AsyncSearchPicker.d.ts +26 -0
  74. package/dist/types/AutoComplete.d.ts +9 -0
  75. package/dist/types/Badge.d.ts +13 -0
  76. package/dist/types/Button.d.ts +36 -0
  77. package/dist/types/Cascader.d.ts +57 -0
  78. package/dist/types/ChineseAddressRegions.d.ts +4 -0
  79. package/dist/types/Combobox.d.ts +37 -0
  80. package/dist/types/ConfirmDialog.d.ts +20 -0
  81. package/dist/types/DataTable.d.ts +68 -0
  82. package/dist/types/DataTableHorizontalScrollbar.d.ts +8 -0
  83. package/dist/types/DataTableIcons.d.ts +19 -0
  84. package/dist/types/DataTableMergedRows.d.ts +11 -0
  85. package/dist/types/DataTableTheme.d.ts +4 -0
  86. package/dist/types/DateInput.d.ts +25 -0
  87. package/dist/types/DocumentRenderBudget.d.ts +9 -0
  88. package/dist/types/DocumentViewer.d.ts +11 -0
  89. package/dist/types/DocumentViewerV2.d.ts +10 -0
  90. package/dist/types/DropdownMenu.d.ts +73 -0
  91. package/dist/types/EmptyState.d.ts +9 -0
  92. package/dist/types/ExplainableButton.d.ts +7 -0
  93. package/dist/types/FileDropzone.d.ts +20 -0
  94. package/dist/types/FilePreparationDialog.d.ts +12 -0
  95. package/dist/types/FloatingControls.d.ts +39 -0
  96. package/dist/types/FormField.d.ts +35 -0
  97. package/dist/types/MetricCard.d.ts +17 -0
  98. package/dist/types/ModalShell.d.ts +33 -0
  99. package/dist/types/MultiSelect.d.ts +12 -0
  100. package/dist/types/NumericInput.d.ts +54 -0
  101. package/dist/types/OverlayContainer.d.ts +2 -0
  102. package/dist/types/PageHeader.d.ts +23 -0
  103. package/dist/types/Pagination.d.ts +14 -0
  104. package/dist/types/PdfiumViewer.d.ts +5 -0
  105. package/dist/types/PreparedFileDropzone.d.ts +7 -0
  106. package/dist/types/RecoverableAsyncState.d.ts +11 -0
  107. package/dist/types/RovingTabs.d.ts +21 -0
  108. package/dist/types/SectionCard.d.ts +18 -0
  109. package/dist/types/SegmentedControl.d.ts +26 -0
  110. package/dist/types/Select.d.ts +31 -0
  111. package/dist/types/Skeleton.d.ts +11 -0
  112. package/dist/types/SortableList.d.ts +17 -0
  113. package/dist/types/StructuredAddressInput.d.ts +57 -0
  114. package/dist/types/Toast.d.ts +22 -0
  115. package/dist/types/ToggleSwitch.d.ts +15 -0
  116. package/dist/types/TreeSelect.d.ts +58 -0
  117. package/dist/types/classNames.d.ts +1 -0
  118. package/dist/types/document-viewer/ContinuousPdfViewer.d.ts +16 -0
  119. package/dist/types/document-viewer/DocumentViewer.d.ts +31 -0
  120. package/dist/types/document-viewer/DocumentViewerViewport.d.ts +23 -0
  121. package/dist/types/document-viewer/ImagePage.d.ts +9 -0
  122. package/dist/types/document-viewer/PdfCanvasPage.d.ts +7 -0
  123. package/dist/types/document-viewer/PdfThumbnailRail.d.ts +12 -0
  124. package/dist/types/document-viewer/PdfToolbar.d.ts +13 -0
  125. package/dist/types/document-viewer/PdfWorkspace.d.ts +5 -0
  126. package/dist/types/document-viewer/pdf-render-budget.d.ts +2 -0
  127. package/dist/types/document-viewer/usePdfCanvas.d.ts +22 -0
  128. package/dist/types/document-viewer/usePdfViewport.d.ts +14 -0
  129. package/dist/types/document-viewer-v2/DocumentViewerV2.d.ts +50 -0
  130. package/dist/types/document-viewer-v2/HeadlessPdfViewer.d.ts +39 -0
  131. package/dist/types/document-viewer-v2/HeadlessSearch.d.ts +9 -0
  132. package/dist/types/index.d.ts +41 -0
  133. package/dist/types/useDebouncedValue.d.ts +2 -0
  134. package/dist/types/useFilePreparation.d.ts +28 -0
  135. package/dist/types/useModalFocusTrap.d.ts +3 -0
  136. package/dist/useDebouncedValue.js +16 -0
  137. package/dist/useFilePreparation.js +51 -0
  138. package/dist/useModalFocusTrap.js +71 -0
  139. package/docs/agent-guide.md +145 -0
  140. package/docs/api.md +220 -0
  141. package/docs/cascader.md +56 -0
  142. package/docs/component-strategy.md +94 -0
  143. package/docs/data-table.md +123 -0
  144. package/docs/dependencies.md +57 -0
  145. package/docs/document-viewer-v2.md +259 -0
  146. package/docs/document-viewer.md +28 -0
  147. package/docs/file-preparation.md +11 -0
  148. package/docs/maturity-migration.md +62 -0
  149. package/docs/modal-shell-migration.md +43 -0
  150. package/docs/mrt-poc.md +205 -0
  151. package/docs/release.md +32 -0
  152. package/docs/viewport-qa.md +99 -0
  153. package/licenses/rc-cascader-MIT.txt +21 -0
  154. package/package.json +163 -0
@@ -0,0 +1,134 @@
1
+ import { AsyncSearchPicker as e } from "./AsyncSearchPicker.js";
2
+ import { useEffect as t, useRef as n, useState as r } from "react";
3
+ import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
4
+ //#region src/AsyncDirectoryPicker.tsx
5
+ function s({ selectedItem: s, loadItems: ee, getKey: c, getText: l, getSelectionText: u = l, renderItem: d, onSelect: te, onQueryChange: f, ownerKey: p = "", label: m, placeholder: h = "输入关键词搜索", searchLabel: g, loadingTitle: _, emptyText: v, minimumCharacters: y = 0, minimumCharactersText: ne, debounceMs: b = 200, cacheSize: x = 50, cacheTtlMs: S = 3e5, refreshKey: C, loadOnFocus: re = !0, disabled: w = !1, busy: T = !1, className: E, inputProps: D }) {
6
+ let O = s ? u(s) : "", [k, A] = r(O), [j, M] = r(O), [N, P] = r([]), [F, I] = r("idle"), [L, R] = r(!1), [z, B] = r(!1), [V, H] = r(!1), U = n(0), W = n(O);
7
+ W.current = O;
8
+ let [G, K] = r(""), q = n(null), J = n(0), Y = n(/* @__PURE__ */ new Map()), X = Number.isFinite(x) ? Math.max(0, Math.floor(x)) : 50, Z = n(X);
9
+ Z.current = X, t(() => {
10
+ for (; Y.current.size > X;) Y.current.delete(Y.current.keys().next().value);
11
+ }, [X]), t(() => () => {
12
+ J.current++, U.current++, q.current?.abort();
13
+ }, []), t(() => {
14
+ J.current++, q.current?.abort(), q.current = null, Y.current.clear(), U.current++, H(!1);
15
+ let e = s ? u(s) : "";
16
+ A(e), M(e), P([]), I("idle"), K("");
17
+ }, [p]), t(() => {
18
+ J.current++, q.current?.abort(), Y.current.clear(), P([]), I("idle");
19
+ }, [C, S]), t(() => {
20
+ J.current++, q.current?.abort(), U.current++, H(!1);
21
+ let e = s ? u(s) : "";
22
+ A(e), M(e), P([]), I("idle"), K("");
23
+ }, [s && c(s), s && u(s)]), t(() => {
24
+ if (w || T || V || L || z || k === j || k.trim().length < y) return;
25
+ let e = window.setTimeout(() => void Q(k), Math.max(0, b));
26
+ return () => window.clearTimeout(e);
27
+ }, [
28
+ k,
29
+ j,
30
+ w,
31
+ T,
32
+ V,
33
+ L,
34
+ z,
35
+ y,
36
+ b,
37
+ C,
38
+ S
39
+ ]);
40
+ async function Q(e = k) {
41
+ let t = e.trim();
42
+ if (w || T || V || z || t.length < y) return;
43
+ let n = ++J.current;
44
+ q.current?.abort(), q.current = null;
45
+ let r = t, i = X > 0 ? Y.current.get(r) : void 0;
46
+ if (i && i.expires > Date.now()) {
47
+ Y.current.delete(r), Y.current.set(r, i), P(i.items), I("success"), K("");
48
+ return;
49
+ }
50
+ let a = new AbortController();
51
+ q.current = a, I("loading"), K("");
52
+ try {
53
+ let e = await ee(t, a.signal);
54
+ if (n !== J.current || a.signal.aborted) return;
55
+ if (Z.current > 0) for (Y.current.delete(r), Y.current.set(r, {
56
+ items: e,
57
+ expires: Date.now() + Math.max(0, S)
58
+ }); Y.current.size > Z.current;) Y.current.delete(Y.current.keys().next().value);
59
+ P(e), I("success");
60
+ } catch (e) {
61
+ if (n !== J.current || a.signal.aborted) return;
62
+ K(e instanceof Error ? e.message : "目录查询失败"), I("error");
63
+ } finally {
64
+ n === J.current && (q.current = null);
65
+ }
66
+ }
67
+ function $(e) {
68
+ J.current++, q.current?.abort(), q.current = null, A(e), M(""), P([]), I("idle"), K(""), f?.(e);
69
+ }
70
+ async function ie(e) {
71
+ J.current++, q.current?.abort(), q.current = null;
72
+ let t = ++U.current, n = u(e);
73
+ A(n), M(n), P([]), I("idle"), H(!0), K("");
74
+ try {
75
+ await te(e);
76
+ } catch (e) {
77
+ if (t !== U.current) return;
78
+ A(W.current), M(W.current), K(e instanceof Error ? e.message : "选择保存失败");
79
+ } finally {
80
+ t === U.current && H(!1);
81
+ }
82
+ }
83
+ function ae(e) {
84
+ D?.onFocus?.(e), !e.defaultPrevented && re && !s && F === "idle" && !N.length && k.trim().length >= y && Q(k);
85
+ }
86
+ function oe(e) {
87
+ D?.onKeyDown?.(e), (e.key === "Backspace" || e.key === "Delete") && R(!0);
88
+ }
89
+ function se(e) {
90
+ D?.onKeyUp?.(e), (e.key === "Backspace" || e.key === "Delete") && R(!1);
91
+ }
92
+ return /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a(e, {
93
+ query: k,
94
+ onQueryChange: $,
95
+ onSearch: () => void Q(),
96
+ items: N,
97
+ getKey: c,
98
+ getText: l,
99
+ renderItem: d,
100
+ onSelect: ie,
101
+ status: F,
102
+ error: G,
103
+ label: m,
104
+ searchLabel: g,
105
+ loadingTitle: _,
106
+ emptyText: v,
107
+ minimumCharacters: y,
108
+ minimumCharactersText: ne,
109
+ busy: T || V,
110
+ disabled: w,
111
+ className: E,
112
+ inputProps: {
113
+ ...D,
114
+ placeholder: h,
115
+ onFocus: ae,
116
+ onKeyDown: oe,
117
+ onKeyUp: se,
118
+ onCompositionStart: (e) => {
119
+ B(!0), D?.onCompositionStart?.(e);
120
+ },
121
+ onCompositionEnd: (e) => {
122
+ B(!1), D?.onCompositionEnd?.(e);
123
+ },
124
+ onBlur: (e) => {
125
+ D?.onBlur?.(e), R(!1);
126
+ }
127
+ }
128
+ }), G && F === "idle" && /* @__PURE__ */ a("div", {
129
+ role: "alert",
130
+ children: G
131
+ })] });
132
+ }
133
+ //#endregion
134
+ export { s as AsyncDirectoryPicker };
@@ -0,0 +1,155 @@
1
+ import { Button as e } from "./Button.js";
2
+ import { TextInput as t } from "./FormField.js";
3
+ import { RecoverableAsyncState as n } from "./RecoverableAsyncState.js";
4
+ import { memo as r, useCallback as i, useEffect as a, useId as o, useRef as s, useState as c } from "react";
5
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
6
+ //#region src/AsyncSearchPicker.tsx
7
+ function d({ query: r, onQueryChange: d, onSearch: p, items: h, getKey: g, getText: _, renderItem: v, onSelect: y, status: b = "idle", error: x, label: S, searchLabel: C = "查询", loadingTitle: w = "正在查询", emptyText: T = "没有匹配项", minimumCharacters: E = 0, minimumCharactersText: D = (e) => `请至少输入 ${e} 个字符`, busy: O = !1, disabled: k = !1, className: A = "", inputRef: j, inputProps: M }) {
8
+ let N = `ui-async-picker-${o().replaceAll(":", "")}`, [P, F] = c(-1), [I, L] = c(!1), R = s(/* @__PURE__ */ new Map()), z = s(null), [B, V] = c(320), H = k || O || b === "loading", U = r.trim().length < E, W = !I && b === "success" && !U, G = P >= 0 && P < h.length ? h[P] : void 0;
9
+ a(() => {
10
+ F(-1);
11
+ }, [r, h]), a(() => {
12
+ let e = (e) => {
13
+ z.current?.contains(e.target) || (L(!0), F(-1));
14
+ };
15
+ return document.addEventListener("pointerdown", e, !0), () => document.removeEventListener("pointerdown", e, !0);
16
+ }, []), a(() => {
17
+ if (!W || h.length === 0) return;
18
+ let e = window.visualViewport, t = 0, n = () => {
19
+ t && window.cancelAnimationFrame(t), t = window.requestAnimationFrame(() => {
20
+ t = 0;
21
+ let n = z.current?.querySelector(".ui-async-search-control");
22
+ if (!n) return;
23
+ let r = (e?.offsetTop ?? 0) + (e?.height ?? window.innerHeight), i = Math.floor(r - n.getBoundingClientRect().bottom - 12);
24
+ V(Math.max(96, Math.min(320, i)));
25
+ });
26
+ };
27
+ return n(), e?.addEventListener("resize", n), e?.addEventListener("scroll", n), window.addEventListener("resize", n), () => {
28
+ t && window.cancelAnimationFrame(t), e?.removeEventListener("resize", n), e?.removeEventListener("scroll", n), window.removeEventListener("resize", n);
29
+ };
30
+ }, [h.length, W]);
31
+ function K() {
32
+ !H && !U && (L(!1), p(r));
33
+ }
34
+ let q = i((e) => {
35
+ H || (y(e), L(!0), F(-1));
36
+ }, [H, y]);
37
+ function J(e) {
38
+ if (!h.length) return;
39
+ let t = (e + h.length) % h.length;
40
+ F(t);
41
+ let n = R.current.get(g(h[t]));
42
+ typeof n?.scrollIntoView == "function" && n.scrollIntoView({ block: "nearest" });
43
+ }
44
+ function Y(e) {
45
+ M?.onKeyDown?.(e), !(e.defaultPrevented || e.nativeEvent.isComposing) && (e.key === "ArrowDown" && W && h.length ? (e.preventDefault(), J(P + 1)) : e.key === "ArrowUp" && W && h.length ? (e.preventDefault(), J(P <= 0 ? h.length - 1 : P - 1)) : e.key === "Enter" ? (e.preventDefault(), G && W ? q(G) : K()) : (e.key === "Escape" || e.key === "Tab") && (L(!0), F(-1)));
46
+ }
47
+ return /* @__PURE__ */ u("div", {
48
+ ref: z,
49
+ className: `ui-async-search-picker ${A}`.trim(),
50
+ onBlur: (e) => {
51
+ e.currentTarget.contains(e.relatedTarget) || (L(!0), F(-1));
52
+ },
53
+ children: [
54
+ /* @__PURE__ */ u("div", {
55
+ className: "ui-async-search-control",
56
+ children: [/* @__PURE__ */ l(t, {
57
+ ...M,
58
+ ref: j,
59
+ label: S,
60
+ value: r,
61
+ disabled: k || O,
62
+ onFocus: (e) => {
63
+ L(!1), M?.onFocus?.(e);
64
+ },
65
+ onChange: (e) => {
66
+ L(!1), d(e.target.value);
67
+ },
68
+ onKeyDown: Y,
69
+ role: "combobox",
70
+ "aria-autocomplete": "list",
71
+ "aria-expanded": W && h.length > 0,
72
+ "aria-controls": W && h.length > 0 ? `${N}-list` : void 0,
73
+ "aria-activedescendant": W && G ? `${N}-${f(g(G))}` : void 0
74
+ }), /* @__PURE__ */ l(e, {
75
+ variant: "primary",
76
+ busy: O || b === "loading",
77
+ disabled: k || U,
78
+ onClick: K,
79
+ children: C
80
+ })]
81
+ }),
82
+ /* @__PURE__ */ u("div", {
83
+ className: "ui-async-search-status",
84
+ "aria-live": "polite",
85
+ children: [
86
+ U ? D(E) : null,
87
+ !I && !U && b === "loading" ? /* @__PURE__ */ l(n, {
88
+ compact: !0,
89
+ phase: "loading",
90
+ loadingTitle: w,
91
+ errorTitle: ""
92
+ }) : null,
93
+ !I && !U && b === "error" ? /* @__PURE__ */ l(n, {
94
+ compact: !0,
95
+ phase: "error",
96
+ loadingTitle: "",
97
+ errorTitle: "查询失败",
98
+ detail: x,
99
+ onRetry: H ? void 0 : K,
100
+ retryLabel: "重试"
101
+ }) : null,
102
+ W && h.length === 0 ? /* @__PURE__ */ l("div", {
103
+ className: "ui-async-search-empty",
104
+ children: T
105
+ }) : null
106
+ ]
107
+ }),
108
+ W && h.length > 0 ? /* @__PURE__ */ l("div", {
109
+ id: `${N}-list`,
110
+ role: "listbox",
111
+ className: "ui-async-search-list",
112
+ style: { maxHeight: B },
113
+ children: h.map((e, t) => {
114
+ let n = g(e);
115
+ return /* @__PURE__ */ l(m, {
116
+ item: e,
117
+ index: t,
118
+ optionKey: n,
119
+ id: `${N}-${f(n)}`,
120
+ selected: P === t,
121
+ refs: R.current,
122
+ activate: F,
123
+ select: q,
124
+ getText: _,
125
+ renderItem: v
126
+ }, n);
127
+ })
128
+ }) : null
129
+ ]
130
+ });
131
+ }
132
+ function f(e) {
133
+ return e.replace(/[^a-zA-Z0-9_-]/g, "-");
134
+ }
135
+ function p({ item: e, index: t, optionKey: n, id: r, selected: a, refs: o, activate: s, select: c, getText: u, renderItem: d }) {
136
+ let f = i((e) => {
137
+ e ? o.set(n, e) : o.delete(n);
138
+ }, [o, n]);
139
+ return /* @__PURE__ */ l("button", {
140
+ ref: f,
141
+ id: r,
142
+ type: "button",
143
+ role: "option",
144
+ "aria-selected": a,
145
+ className: "ui-async-search-option",
146
+ tabIndex: -1,
147
+ onMouseEnter: () => s(t),
148
+ onClick: () => c(e),
149
+ "aria-label": u(e),
150
+ children: d(e)
151
+ });
152
+ }
153
+ var m = r(p);
154
+ //#endregion
155
+ export { d as AsyncSearchPicker };
@@ -0,0 +1,34 @@
1
+ import { Combobox as e } from "./Combobox.js";
2
+ import { useMemo as t, useState as n } from "react";
3
+ import { jsx as r } from "react/jsx-runtime";
4
+ //#region src/AutoComplete.tsx
5
+ function i({ value: i, defaultValue: a = "", onChange: o, onSelect: s, items: c, ...l }) {
6
+ let [u, d] = n(a), f = i ?? u, p = t(() => {
7
+ let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
8
+ for (let n of c) e.set(n.id, n), t.has(n.label) || t.set(n.label, n.id);
9
+ return {
10
+ byId: e,
11
+ byLabel: t
12
+ };
13
+ }, [c]), m = p.byLabel.get(f) ?? null;
14
+ function h(e) {
15
+ i === void 0 && d(e), o?.(e);
16
+ }
17
+ function g(e) {
18
+ if (e === null) return;
19
+ let t = p.byId.get(e);
20
+ t && (h(t.label), s?.(t));
21
+ }
22
+ return /* @__PURE__ */ r(e, {
23
+ ...l,
24
+ items: c,
25
+ inputValue: f,
26
+ onInputChange: h,
27
+ selectedKey: m,
28
+ onSelectionChange: g,
29
+ allowsCustomValue: !0
30
+ });
31
+ }
32
+ var a = i;
33
+ //#endregion
34
+ export { i as AutoComplete, a as Autocomplete };
package/dist/Badge.js ADDED
@@ -0,0 +1,14 @@
1
+ import { joinClassNames as e } from "./classNames.js";
2
+ import { forwardRef as t } from "react";
3
+ import { jsx as n } from "react/jsx-runtime";
4
+ //#region src/Badge.tsx
5
+ var r = t(function({ tone: t = "neutral", size: r = "medium", className: i, children: a, ...o }, s) {
6
+ return /* @__PURE__ */ n("span", {
7
+ ...o,
8
+ ref: s,
9
+ className: e("ui-badge", `ui-badge-${t}`, `ui-badge-${r}`, i),
10
+ children: a
11
+ });
12
+ });
13
+ //#endregion
14
+ export { r as Badge };
package/dist/Button.js ADDED
@@ -0,0 +1,54 @@
1
+ import { LoaderCircle as e } from "lucide-react";
2
+ import { forwardRef as t } from "react";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/Button.tsx
5
+ var i = t(function({ variant: t = "secondary", size: i = "default", iconOnly: a = !1, busy: s = !1, busyLabel: c, className: l = "", disabled: u, children: d, type: f = "button", ...p }, m) {
6
+ return /* @__PURE__ */ r("button", {
7
+ ...p,
8
+ ref: m,
9
+ type: f,
10
+ className: o({
11
+ variant: t,
12
+ size: i,
13
+ iconOnly: a,
14
+ className: l
15
+ }),
16
+ disabled: u || s,
17
+ "aria-busy": s || void 0,
18
+ children: [s && /* @__PURE__ */ n(e, {
19
+ className: "ui-button-spinner",
20
+ size: 16,
21
+ "aria-hidden": "true"
22
+ }), s && c !== void 0 ? c : d]
23
+ });
24
+ }), a = t(function({ variant: e = "secondary", size: t = "default", iconOnly: r = !1, className: i = "", disabled: a = !1, href: s, role: c, tabIndex: l, onClick: u, ...d }, f) {
25
+ let p = (e) => {
26
+ a ? (e.preventDefault(), e.stopPropagation()) : u?.(e);
27
+ };
28
+ return /* @__PURE__ */ n("a", {
29
+ ...d,
30
+ ref: f,
31
+ href: a ? void 0 : s,
32
+ className: o({
33
+ variant: e,
34
+ size: t,
35
+ iconOnly: r,
36
+ className: i
37
+ }),
38
+ role: a ? c ?? "link" : c,
39
+ "aria-disabled": a || void 0,
40
+ tabIndex: a ? -1 : l,
41
+ onClick: p
42
+ });
43
+ });
44
+ function o({ variant: e = "secondary", size: t = "default", iconOnly: n = !1, className: r = "" } = {}) {
45
+ return [
46
+ "ui-button",
47
+ `ui-button-${e}`,
48
+ `ui-button-${t}`,
49
+ n ? "ui-button-icon" : "",
50
+ r
51
+ ].filter(Boolean).join(" ");
52
+ }
53
+ //#endregion
54
+ export { i as Button, a as LinkButton, o as buttonClassName };
@@ -0,0 +1,141 @@
1
+ import { useOverlayContainer as e } from "./OverlayContainer.js";
2
+ import { FormField as t } from "./FormField.js";
3
+ import { ChevronDown as n, ChevronRight as r, LoaderCircle as i, X as a } from "lucide-react";
4
+ import { useCallback as o, useEffect as s, useId as c, useRef as l, useState as u } from "react";
5
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
6
+ import p from "@rc-component/cascader";
7
+ //#region src/Cascader.tsx
8
+ function m(m) {
9
+ let g = c(), [_, v] = u(!1);
10
+ s(() => {
11
+ m.disabled && v(!1);
12
+ }, [m.disabled]);
13
+ let y = !m.disabled && (m.open ?? _), b = m.id ?? m.inputProps?.id ?? g, x = e(), { inputProps: S, inputRef: C, label: w, helpText: T, error: E } = m, D = l(null), O = o((e) => {
14
+ D.current = e, typeof C == "function" ? C(e) : C && (C.current = e);
15
+ }, [C]);
16
+ s(() => {
17
+ D.current?.setCustomValidity(m.required && !m.value.length ? "请选择一个选项" : "");
18
+ }, [m.required, m.value.length]);
19
+ let k = [
20
+ S?.["aria-describedby"],
21
+ T !== void 0 && `${b}-help`,
22
+ E && `${b}-error`
23
+ ].filter(Boolean).join(" ") || void 0, A = {
24
+ id: b,
25
+ options: m.options,
26
+ prefixCls: "ui-cascader",
27
+ className: m.className,
28
+ disabled: m.disabled,
29
+ open: y,
30
+ onPopupVisibleChange: (e) => {
31
+ v(e), m.onOpenChange?.(e);
32
+ },
33
+ onInputKeyDown: (e) => {
34
+ e.key === "Escape" && y && !e.nativeEvent.isComposing && (e.preventDefault(), e.stopPropagation(), v(!1), m.onOpenChange?.(!1));
35
+ },
36
+ showAction: [],
37
+ placeholder: m.placeholder ?? "请选择或搜索",
38
+ notFoundContent: m.emptyText ?? "没有匹配的选项",
39
+ allowClear: m.allowClear !== !1 && {
40
+ clearIcon: /* @__PURE__ */ d(a, { size: 14 }),
41
+ label: m.clearLabel ?? "清除选择"
42
+ },
43
+ suffix: /* @__PURE__ */ d(n, { size: 16 }),
44
+ expandIcon: /* @__PURE__ */ d(r, { size: 14 }),
45
+ loadingIcon: /* @__PURE__ */ d(i, { size: 14 }),
46
+ changeOnSelect: m.changeOnSelect,
47
+ loadData: m.loadData,
48
+ showSearch: m.searchable ?? !m.loadData ? {
49
+ filter: (e, t) => h(t.map((e) => e.label).join("/")).includes(h(e)),
50
+ render: (e, t) => t.map((e) => e.label).join(" / "),
51
+ limit: 50
52
+ } : !1,
53
+ displayRender: (e) => e.join(" / "),
54
+ getPopupContainer: (e) => x instanceof HTMLElement ? x : e.ownerDocument.body,
55
+ popupMatchSelectWidth: !1,
56
+ components: { input: /* @__PURE__ */ d("input", {
57
+ ...S,
58
+ ref: O,
59
+ id: b,
60
+ placeholder: "",
61
+ required: m.required && !m.value.length,
62
+ "aria-required": m.required || void 0,
63
+ "aria-invalid": E ? !0 : S?.["aria-invalid"],
64
+ "aria-describedby": k
65
+ }) },
66
+ tagRender: ({ label: e, closable: t, onClose: n }) => /* @__PURE__ */ f("span", {
67
+ className: "ui-cascader-tag",
68
+ children: [/* @__PURE__ */ d("span", { children: e }), t && /* @__PURE__ */ d("button", {
69
+ type: "button",
70
+ "aria-label": `移除 ${String(e)}`,
71
+ onMouseDown: (e) => {
72
+ e.preventDefault(), e.stopPropagation();
73
+ },
74
+ onClick: (e) => {
75
+ e.stopPropagation(), n();
76
+ },
77
+ children: /* @__PURE__ */ d(a, { size: 12 })
78
+ })]
79
+ })
80
+ };
81
+ return /* @__PURE__ */ f(t, {
82
+ controlId: b,
83
+ label: w,
84
+ helpText: T,
85
+ error: E,
86
+ required: m.required,
87
+ children: [y && /* @__PURE__ */ d("span", {
88
+ hidden: !0,
89
+ "data-ui-aria-overlay": ""
90
+ }), m.multiple ? /* @__PURE__ */ d(p, {
91
+ ...A,
92
+ checkable: !0,
93
+ checkStrictly: m.checkStrictly ?? !0,
94
+ maxTagCount: m.maxTagCount ?? 3,
95
+ value: m.value,
96
+ onChange: (e, t) => m.onValueChange(e ?? [], t ?? [])
97
+ }) : /* @__PURE__ */ d(p, {
98
+ ...A,
99
+ value: m.value,
100
+ onChange: (e, t) => m.onValueChange(e ?? [], t ?? [])
101
+ })]
102
+ });
103
+ }
104
+ function h(e) {
105
+ return e.replace(/[\s/]+/gu, "").toLocaleLowerCase();
106
+ }
107
+ function g(e) {
108
+ let t = /* @__PURE__ */ new Map(), n = new Map(e.map((e) => [e.id, e.parentId]));
109
+ for (let n of e) {
110
+ if (!n.id || t.has(n.id)) throw Error("Cascader IDs must be nonempty and unique");
111
+ t.set(n.id, {
112
+ value: n.id,
113
+ label: n.label,
114
+ disabled: n.disabled
115
+ });
116
+ }
117
+ let r = [];
118
+ for (let i of e) {
119
+ let e = /* @__PURE__ */ new Set([i.id]), a = i.parentId;
120
+ for (; a && t.has(a);) {
121
+ if (e.has(a)) throw Error("Cascader hierarchy contains a cycle");
122
+ e.add(a), a = n.get(a);
123
+ }
124
+ let o = t.get(i.id), s = i.parentId ? t.get(i.parentId) : void 0;
125
+ s ? (s.children ??= []).push(o) : r.push(o);
126
+ }
127
+ return r;
128
+ }
129
+ function _(e) {
130
+ let t = /* @__PURE__ */ new Map();
131
+ function n(e, r) {
132
+ for (let i of e) {
133
+ if (t.has(i.value)) throw Error("ID path indexing requires globally unique values");
134
+ let e = [...r, i.value];
135
+ t.set(i.value, e), i.children && n(i.children, e);
136
+ }
137
+ }
138
+ return n(e, []), t;
139
+ }
140
+ //#endregion
141
+ export { m as Cascader, g as buildCascaderOptions, _ as indexCascaderPaths };
@@ -0,0 +1,106 @@
1
+ import { useOverlayContainer as e } from "./OverlayContainer.js";
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";
7
+ //#region src/Combobox.tsx
8
+ var y = {
9
+ rowSize: 48,
10
+ gap: 2,
11
+ padding: 4
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, {
15
+ 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, {
23
+ 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
+ })] })
31
+ })
32
+ });
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,
44
+ menuTrigger: "focus",
45
+ "aria-label": x === void 0 ? z?.["aria-label"] : void 0,
46
+ "aria-labelledby": x === void 0 ? z?.["aria-labelledby"] : void 0,
47
+ children: [
48
+ x === void 0 ? null : /* @__PURE__ */ c(f, {
49
+ className: "ui-form-label",
50
+ children: [x, j && /* @__PURE__ */ s("span", {
51
+ className: "ui-form-required",
52
+ "aria-hidden": "true",
53
+ children: "*"
54
+ })]
55
+ }),
56
+ /* @__PURE__ */ c("div", {
57
+ className: "ui-combobox-control",
58
+ children: [/* @__PURE__ */ s(d, {
59
+ ...z,
60
+ ref: R,
61
+ id: H,
62
+ className: "ui-input",
63
+ placeholder: S,
64
+ "aria-invalid": F ? !0 : z?.["aria-invalid"]
65
+ }), /* @__PURE__ */ s(l, {
66
+ className: "ui-combobox-trigger",
67
+ "aria-label": "展开选项",
68
+ children: k ? /* @__PURE__ */ s(r, {
69
+ className: "spin",
70
+ size: 16
71
+ }) : /* @__PURE__ */ s(n, { size: 16 })
72
+ })]
73
+ }),
74
+ P === void 0 ? null : /* @__PURE__ */ s(g, {
75
+ slot: "description",
76
+ className: "ui-form-help",
77
+ children: P
78
+ }),
79
+ F === void 0 || F === "" ? null : /* @__PURE__ */ s(g, {
80
+ slot: "errorMessage",
81
+ className: "ui-form-error",
82
+ children: F
83
+ }),
84
+ /* @__PURE__ */ c(h, {
85
+ className: "ui-combobox-popover",
86
+ "data-ui-aria-overlay": "",
87
+ maxHeight: 320,
88
+ placement: B,
89
+ UNSTABLE_portalContainer: U,
90
+ children: [k && /* @__PURE__ */ c("div", {
91
+ className: "ui-combobox-loading",
92
+ children: [/* @__PURE__ */ s(r, {
93
+ className: "spin",
94
+ size: 15
95
+ }), "正在加载"]
96
+ }), I ? /* @__PURE__ */ s(v, {
97
+ layout: _,
98
+ layoutOptions: y,
99
+ children: G
100
+ }) : G]
101
+ })
102
+ ]
103
+ });
104
+ }
105
+ //#endregion
106
+ export { b as Combobox };
@@ -0,0 +1,48 @@
1
+ import { Button as e } from "./Button.js";
2
+ import { ModalShell as t } from "./ModalShell.js";
3
+ import { useId as n, useRef as r } from "react";
4
+ import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
5
+ //#region src/ConfirmDialog.tsx
6
+ function s({ open: s, title: c, description: l, confirmLabel: u = "确认", cancelLabel: d = "取消", confirmVariant: f = "primary", busy: p = !1, busyLabel: m = "处理中", closeOnEscape: h = !0, initialFocus: g = "cancel", returnFocus: _, onConfirm: v, onCancel: y, children: b }) {
7
+ let x = `ui-confirm-${n().replaceAll(":", "")}`, S = r(null), C = r(null);
8
+ if (!s) return null;
9
+ let w = g === "cancel" ? S : g === "confirm" ? C : g;
10
+ return /* @__PURE__ */ a(t, {
11
+ titleId: `${x}-title`,
12
+ describedBy: l === void 0 ? void 0 : `${x}-description`,
13
+ title: c,
14
+ description: l === void 0 ? void 0 : /* @__PURE__ */ a("span", {
15
+ id: `${x}-description`,
16
+ children: l
17
+ }),
18
+ closeLabel: "关闭确认对话框",
19
+ onClose: y,
20
+ closeDisabled: p,
21
+ closeOnEscape: h,
22
+ initialFocus: w,
23
+ returnFocus: _,
24
+ role: "alertdialog",
25
+ showCloseButton: !1,
26
+ footerClassName: "ui-confirm-dialog-actions",
27
+ footer: /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a(e, {
28
+ ref: S,
29
+ variant: "outline",
30
+ disabled: p,
31
+ onClick: y,
32
+ children: d
33
+ }), /* @__PURE__ */ a(e, {
34
+ ref: C,
35
+ variant: f,
36
+ busy: p,
37
+ busyLabel: m,
38
+ onClick: v,
39
+ children: u
40
+ })] }),
41
+ children: b === void 0 ? null : /* @__PURE__ */ a("div", {
42
+ className: "ui-confirm-dialog-body",
43
+ children: b
44
+ })
45
+ });
46
+ }
47
+ //#endregion
48
+ export { s as ConfirmDialog };