@jc-times/business-ui 0.3.2 → 0.4.1

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 (59) hide show
  1. package/AGENTS.md +15 -0
  2. package/CHANGELOG.md +22 -0
  3. package/README.md +2 -0
  4. package/THIRD_PARTY_NOTICES.md +3 -0
  5. package/bin/business-ui-gate.mjs +2 -2
  6. package/dist/AntDateWheelView.js +131 -0
  7. package/dist/AntOptionWheelView.js +76 -0
  8. package/dist/AsyncDirectoryPicker.js +89 -88
  9. package/dist/AsyncSearchPicker.js +136 -82
  10. package/dist/Cascader.js +56 -51
  11. package/dist/DateInput.js +84 -66
  12. package/dist/DateWheelPicker.js +58 -0
  13. package/dist/MobilePickerPanel.js +34 -0
  14. package/dist/ModalShell.js +84 -72
  15. package/dist/MultiSelect.js +5 -1
  16. package/dist/OptionWheelDialog.js +99 -0
  17. package/dist/Select.js +116 -61
  18. package/dist/StructuredAddressInput.js +72 -70
  19. package/dist/TreeSelect.js +265 -217
  20. package/dist/WheelCascader.js +123 -0
  21. package/dist/WheelDateInput.js +97 -0
  22. package/dist/business-ui.js +42 -39
  23. package/dist/date-wheel-model.js +27 -0
  24. package/dist/option-wheel-model.js +49 -0
  25. package/dist/styles.css +1 -1
  26. package/dist/types/AntDateWheelView.d.ts +9 -0
  27. package/dist/types/AntOptionWheelView.d.ts +8 -0
  28. package/dist/types/AsyncDirectoryPicker.d.ts +2 -1
  29. package/dist/types/AsyncSearchPicker.d.ts +3 -1
  30. package/dist/types/Cascader.d.ts +2 -0
  31. package/dist/types/DateInput.d.ts +4 -0
  32. package/dist/types/DateWheelPicker.d.ts +13 -0
  33. package/dist/types/MobilePickerPanel.d.ts +11 -0
  34. package/dist/types/ModalShell.d.ts +3 -1
  35. package/dist/types/OptionWheelDialog.d.ts +18 -0
  36. package/dist/types/Select.d.ts +4 -1
  37. package/dist/types/StructuredAddressInput.d.ts +3 -1
  38. package/dist/types/TreeSelect.d.ts +2 -1
  39. package/dist/types/WheelCascader.d.ts +6 -0
  40. package/dist/types/WheelDateInput.d.ts +11 -0
  41. package/dist/types/date-wheel-model.d.ts +8 -0
  42. package/dist/types/index.d.ts +3 -0
  43. package/dist/types/option-wheel-model.d.ts +19 -0
  44. package/dist/types/usePhoneWheel.d.ts +2 -0
  45. package/dist/types/useSheetViewport.d.ts +3 -0
  46. package/dist/usePhoneWheel.js +16 -0
  47. package/dist/useSheetViewport.js +26 -0
  48. package/docs/agent-guide.md +15 -5
  49. package/docs/api.md +16 -0
  50. package/docs/cascader.md +2 -0
  51. package/docs/component-strategy.md +18 -0
  52. package/docs/date-wheel.md +25 -0
  53. package/docs/dependencies.md +2 -0
  54. package/docs/mobile-controls.md +74 -0
  55. package/docs/modal-shell-migration.md +25 -0
  56. package/docs/release.md +8 -1
  57. package/docs/viewport-qa.md +52 -0
  58. package/licenses/antd-mobile-MIT.txt +22 -0
  59. package/package.json +11 -2
package/dist/DateInput.js CHANGED
@@ -1,38 +1,56 @@
1
1
  import { useOverlayContainer as e } from "./OverlayContainer.js";
2
- import { forwardRef as t, useCallback as n, useEffect as r, useId as ee, useRef as i, useState as a } from "react";
3
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
- import { CalendarDays as te, ChevronLeft as ne, ChevronRight as re, X as c } from "lucide-react";
5
- import * as l from "@radix-ui/react-popover";
6
- import { Button as u, Calendar as ie, CalendarCell as ae, CalendarGrid as oe, CalendarGridBody as se, CalendarGridHeader as ce, CalendarHeaderCell as le, Heading as ue, I18nProvider as de } from "react-aria-components";
7
- import { CalendarDate as fe, getLocalTimeZone as d, parseDate as f, today as p } from "@internationalized/date";
2
+ import { WheelDateInput as t } from "./WheelDateInput.js";
3
+ import { forwardRef as n, useCallback as r, useEffect as i, useId as a, useRef as o, useState as s } from "react";
4
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
5
+ import { CalendarDays as ee, ChevronLeft as te, ChevronRight as ne, X as re } from "lucide-react";
6
+ import * as u from "@radix-ui/react-popover";
7
+ import { Button as d, Calendar as ie, CalendarCell as ae, CalendarGrid as oe, CalendarGridBody as se, CalendarGridHeader as ce, CalendarHeaderCell as le, Heading as ue, I18nProvider as de } from "react-aria-components";
8
+ import { CalendarDate as fe, getLocalTimeZone as f, parseDate as p, today as m } from "@internationalized/date";
8
9
  //#region src/DateInput.tsx
9
- var m = "jc-business-ui-date-input-open", h = t(function({ value: t, onValueChange: f, inputRef: h, inputClassName: y, className: x = "", disabled: S, readOnly: C, required: w, inputMode: pe = "numeric", autoComplete: me = "off", onFocus: T, onBlur: he, onKeyDown: ge, min: E, max: D, minDate: _e, maxDate: ve, isDateUnavailable: O, onValidationError: ye, ...k }, A) {
10
- let j = `ui-date-calendar-${ee().replaceAll(":", "")}`, be = e(), M = i(null), N = i(!1), P = i(!1), F = i(!1), [I, L] = a(!1), [R, z] = a(() => g(t)), [B, V] = a(""), H = _(t), U = _(_e ?? (E === void 0 ? "" : String(E))), W = _(ve ?? (D === void 0 ? "" : String(D))), [G, K] = a(() => H ?? p(d())), q = !!(S || C), xe = n((e) => {
11
- M.current = e, b(h, e), b(A, e);
12
- }, [h, A]);
13
- r(() => {
14
- z(g(t)), V(""), M.current?.setCustomValidity("");
15
- }, [t]), r(() => {
10
+ var h = "jc-business-ui-date-input-open", g = "(hover: none) and (pointer: coarse)";
11
+ function _() {
12
+ return typeof navigator > "u" ? !1 : /iPhone|iPod|Android.+Mobile/i.test(navigator.userAgent);
13
+ }
14
+ var v = n(function({ mobileMode: e = "calendar", ...n }, r) {
15
+ let [a, o] = s(() => typeof window < "u" && !!window.matchMedia?.(g).matches);
16
+ return i(() => {
17
+ if (e !== "wheel" || !window.matchMedia) return;
18
+ let t = window.matchMedia(g), n = () => o(t.matches);
19
+ return n(), t.addEventListener("change", n), () => t.removeEventListener("change", n);
20
+ }, [e]), e === "wheel" && a && _() ? /* @__PURE__ */ c(t, {
21
+ ...n,
22
+ ref: r
23
+ }) : /* @__PURE__ */ c(y, {
24
+ ...n,
25
+ ref: r
26
+ });
27
+ }), y = n(function({ value: t, onValueChange: n, inputRef: p, inputClassName: g, className: _ = "", disabled: v, readOnly: y, required: C, inputMode: pe = "numeric", autoComplete: me = "off", onFocus: he, onBlur: ge, onKeyDown: _e, min: T, max: E, minDate: D, maxDate: ve, isDateUnavailable: O, onValidationError: ye, ...k }, A) {
28
+ let j = `ui-date-calendar-${a().replaceAll(":", "")}`, be = e(), M = o(null), N = o(!1), P = o(!1), F = o(!1), [I, L] = s(!1), [R, z] = s(() => b(t)), [B, V] = s(""), H = x(t), U = x(D ?? (T === void 0 ? "" : String(T))), W = x(ve ?? (E === void 0 ? "" : String(E))), [G, K] = s(() => H ?? m(f())), q = !!(v || y), xe = r((e) => {
29
+ M.current = e, w(p, e), w(A, e);
30
+ }, [p, A]);
31
+ i(() => {
32
+ z(b(t)), V(""), M.current?.setCustomValidity("");
33
+ }, [t]), i(() => {
16
34
  q && L(!1);
17
- }, [q]), r(() => {
35
+ }, [q]), i(() => {
18
36
  let e = (e) => {
19
37
  e.detail !== j && L(!1);
20
38
  };
21
- return document.addEventListener(m, e), () => document.removeEventListener(m, e);
39
+ return document.addEventListener(h, e), () => document.removeEventListener(h, e);
22
40
  }, [j]);
23
41
  function J(e) {
24
42
  if (!(e && q)) {
25
43
  if (e && !I) {
26
- document.dispatchEvent(new CustomEvent(m, { detail: j }));
27
- let e = H ?? p(d());
44
+ document.dispatchEvent(new CustomEvent(h, { detail: j }));
45
+ let e = H ?? m(f());
28
46
  U && e.compare(U) < 0 && (e = U), W && e.compare(W) > 0 && (e = W), K(e);
29
47
  }
30
48
  L(e);
31
49
  }
32
50
  }
33
51
  function Y(e) {
34
- if (!e) return w ? "请选择日期" : "";
35
- let t = _(e);
52
+ if (!e) return C ? "请选择日期" : "";
53
+ let t = x(e);
36
54
  return t ? U && t.compare(U) < 0 ? `日期不能早于 ${U}` : W && t.compare(W) > 0 ? `日期不能晚于 ${W}` : O?.(t.toString()) ? "该日期不可选择" : "" : "请输入有效日期(YYYY/MM/DD)";
37
55
  }
38
56
  function X(e) {
@@ -40,33 +58,33 @@ var m = "jc-business-ui-date-input-open", h = t(function({ value: t, onValueChan
40
58
  }
41
59
  function Z() {
42
60
  if (q) return;
43
- let e = R.trim() ? v(R) : "", n = e === null ? "请输入有效日期(YYYY/MM/DD)" : Y(e);
44
- X(n), !n && e !== null && (z(g(e)), e !== t && f(e));
61
+ let e = R.trim() ? S(R) : "", r = e === null ? "请输入有效日期(YYYY/MM/DD)" : Y(e);
62
+ X(r), !r && e !== null && (z(b(e)), e !== t && n(e));
45
63
  }
46
64
  function Q(e) {
47
65
  if (q) return;
48
66
  let t = Y(e);
49
- X(t), !t && (F.current = !0, f(e), z(g(e)), L(!1));
67
+ X(t), !t && (F.current = !0, n(e), z(b(e)), L(!1));
50
68
  }
51
- let $ = p(d()).toString();
52
- return /* @__PURE__ */ s(l.Root, {
69
+ let $ = m(f()).toString();
70
+ return /* @__PURE__ */ l(u.Root, {
53
71
  open: I && !q,
54
72
  onOpenChange: J,
55
73
  children: [
56
- /* @__PURE__ */ o(l.Anchor, {
74
+ /* @__PURE__ */ c(u.Anchor, {
57
75
  asChild: !0,
58
- children: /* @__PURE__ */ s("span", {
59
- className: `ui-date-input${I ? " open" : ""}${x ? ` ${x}` : ""}`,
60
- children: [/* @__PURE__ */ o("input", {
76
+ children: /* @__PURE__ */ l("span", {
77
+ className: `ui-date-input${I ? " open" : ""}${_ ? ` ${_}` : ""}`,
78
+ children: [/* @__PURE__ */ c("input", {
61
79
  ...k,
62
80
  ref: xe,
63
- className: y,
81
+ className: g,
64
82
  type: "text",
65
83
  inputMode: pe,
66
84
  autoComplete: me,
67
- disabled: S,
68
- readOnly: C,
69
- required: w,
85
+ disabled: v,
86
+ readOnly: y,
87
+ required: C,
70
88
  value: R,
71
89
  placeholder: k.placeholder ?? "YYYY/MM/DD",
72
90
  "aria-haspopup": "dialog",
@@ -75,18 +93,18 @@ var m = "jc-business-ui-date-input-open", h = t(function({ value: t, onValueChan
75
93
  "aria-invalid": B ? !0 : k["aria-invalid"],
76
94
  "aria-describedby": [k["aria-describedby"], B ? `${j}-error` : ""].filter(Boolean).join(" ") || void 0,
77
95
  onFocus: (e) => {
78
- T?.(e), !e.defaultPrevented && !N.current && J(!0);
96
+ he?.(e), !e.defaultPrevented && !N.current && J(!0);
79
97
  },
80
98
  onChange: (e) => {
81
99
  z(e.target.value), B && X("");
82
100
  },
83
101
  onBlur: (e) => {
84
- Z(), he?.(e);
102
+ Z(), ge?.(e);
85
103
  },
86
104
  onKeyDown: (e) => {
87
- ge?.(e), !(e.defaultPrevented || e.nativeEvent.isComposing || e.keyCode === 229 || q) && (e.key === "ArrowDown" && (e.preventDefault(), P.current = !0, J(!0), I && document.getElementById(j)?.querySelector("[role=\"gridcell\"] [tabindex=\"0\"]")?.focus()), e.key === "Enter" && (e.preventDefault(), Z()));
105
+ _e?.(e), !(e.defaultPrevented || e.nativeEvent.isComposing || e.keyCode === 229 || q) && (e.key === "ArrowDown" && (e.preventDefault(), P.current = !0, J(!0), I && document.getElementById(j)?.querySelector("[role=\"gridcell\"] [tabindex=\"0\"]")?.focus()), e.key === "Enter" && (e.preventDefault(), Z()));
88
106
  }
89
- }), /* @__PURE__ */ o("button", {
107
+ }), /* @__PURE__ */ c("button", {
90
108
  type: "button",
91
109
  className: "ui-date-trigger",
92
110
  disabled: q,
@@ -96,22 +114,22 @@ var m = "jc-business-ui-date-input-open", h = t(function({ value: t, onValueChan
96
114
  onClick: () => {
97
115
  P.current = !0, J(!I);
98
116
  },
99
- children: /* @__PURE__ */ o(te, {
117
+ children: /* @__PURE__ */ c(ee, {
100
118
  size: 17,
101
119
  "aria-hidden": "true"
102
120
  })
103
121
  })]
104
122
  })
105
123
  }),
106
- B && /* @__PURE__ */ o("span", {
124
+ B && /* @__PURE__ */ c("span", {
107
125
  id: `${j}-error`,
108
126
  className: "ui-form-error",
109
127
  role: "alert",
110
128
  children: B
111
129
  }),
112
- /* @__PURE__ */ o(l.Portal, {
130
+ /* @__PURE__ */ c(u.Portal, {
113
131
  container: be,
114
- children: /* @__PURE__ */ s(l.Content, {
132
+ children: /* @__PURE__ */ l(u.Content, {
115
133
  id: j,
116
134
  className: "ui-date-calendar",
117
135
  "aria-label": "选择日期",
@@ -129,9 +147,9 @@ var m = "jc-business-ui-date-input-open", h = t(function({ value: t, onValueChan
129
147
  onInteractOutside: (e) => {
130
148
  M.current?.parentElement?.contains(e.target) && e.preventDefault();
131
149
  },
132
- children: [/* @__PURE__ */ o(de, {
150
+ children: [/* @__PURE__ */ c(de, {
133
151
  locale: "zh-CN",
134
- children: /* @__PURE__ */ s(ie, {
152
+ children: /* @__PURE__ */ l(ie, {
135
153
  "aria-label": "选择日期",
136
154
  value: H,
137
155
  onChange: (e) => Q(e.toString()),
@@ -141,49 +159,49 @@ var m = "jc-business-ui-date-input-open", h = t(function({ value: t, onValueChan
141
159
  focusedValue: G,
142
160
  onFocusChange: (e) => K(new fe(e.year, e.month, e.day)),
143
161
  children: [
144
- /* @__PURE__ */ s("header", { children: [
145
- /* @__PURE__ */ o(u, {
162
+ /* @__PURE__ */ l("header", { children: [
163
+ /* @__PURE__ */ c(d, {
146
164
  slot: "previous",
147
165
  "aria-label": "上个月",
148
- children: /* @__PURE__ */ o(ne, { size: 18 })
166
+ children: /* @__PURE__ */ c(te, { size: 18 })
149
167
  }),
150
- /* @__PURE__ */ o(ue, {}),
151
- /* @__PURE__ */ o(u, {
168
+ /* @__PURE__ */ c(ue, {}),
169
+ /* @__PURE__ */ c(d, {
152
170
  slot: "next",
153
171
  "aria-label": "下个月",
154
- children: /* @__PURE__ */ o(re, { size: 18 })
172
+ children: /* @__PURE__ */ c(ne, { size: 18 })
155
173
  })
156
174
  ] }),
157
- /* @__PURE__ */ s("label", {
175
+ /* @__PURE__ */ l("label", {
158
176
  className: "ui-date-month-jump",
159
- children: ["跳转年月", /* @__PURE__ */ o("input", {
177
+ children: ["跳转年月", /* @__PURE__ */ c("input", {
160
178
  type: "month",
161
179
  "aria-label": "跳转年月",
162
180
  value: `${G.year.toString().padStart(4, "0")}-${String(G.month).padStart(2, "0")}`,
163
181
  min: U?.toString().slice(0, 7),
164
182
  max: W?.toString().slice(0, 7),
165
183
  onChange: (e) => {
166
- let t = _(`${e.target.value}-01`);
184
+ let t = x(`${e.target.value}-01`);
167
185
  t && K(U && t.compare(U) < 0 ? U : W && t.compare(W) > 0 ? W : t);
168
186
  }
169
187
  })]
170
188
  }),
171
- /* @__PURE__ */ s(oe, {
189
+ /* @__PURE__ */ l(oe, {
172
190
  className: "ui-aria-calendar-grid",
173
- children: [/* @__PURE__ */ o(ce, { children: (e) => /* @__PURE__ */ o(le, { children: e }) }), /* @__PURE__ */ o(se, { children: (e) => /* @__PURE__ */ o(ae, {
191
+ children: [/* @__PURE__ */ c(ce, { children: (e) => /* @__PURE__ */ c(le, { children: e }) }), /* @__PURE__ */ c(se, { children: (e) => /* @__PURE__ */ c(ae, {
174
192
  date: e,
175
193
  "data-date": e.toString()
176
194
  }) })]
177
195
  })
178
196
  ]
179
197
  })
180
- }), /* @__PURE__ */ s("footer", { children: [/* @__PURE__ */ s("button", {
198
+ }), /* @__PURE__ */ l("footer", { children: [/* @__PURE__ */ l("button", {
181
199
  type: "button",
182
200
  className: "ui-date-clear",
183
- disabled: !t || w,
201
+ disabled: !t || C,
184
202
  onClick: () => Q(""),
185
- children: [/* @__PURE__ */ o(c, { size: 14 }), "清除"]
186
- }), /* @__PURE__ */ o("button", {
203
+ children: [/* @__PURE__ */ c(re, { size: 14 }), "清除"]
204
+ }), /* @__PURE__ */ c("button", {
187
205
  type: "button",
188
206
  className: "ui-date-today",
189
207
  disabled: !!Y($),
@@ -195,29 +213,29 @@ var m = "jc-business-ui-date-input-open", h = t(function({ value: t, onValueChan
195
213
  ]
196
214
  });
197
215
  });
198
- function g(e) {
216
+ function b(e) {
199
217
  return /^\d{4}-\d{2}-\d{2}$/.test(e) ? e.replaceAll("-", "/") : e;
200
218
  }
201
- function _(e) {
202
- let t = v(e);
203
- return t ? f(t) : null;
219
+ function x(e) {
220
+ let t = S(e);
221
+ return t ? p(t) : null;
204
222
  }
205
- function v(e) {
223
+ function S(e) {
206
224
  let t = e.trim().match(/^(\d{4})[/.\-](\d{1,2})[/.\-](\d{1,2})$/);
207
225
  if (!t || Number(t[1]) < 1) return null;
208
226
  let n = `${t[1]}-${t[2].padStart(2, "0")}-${t[3].padStart(2, "0")}`;
209
227
  try {
210
- return f(n).toString();
228
+ return p(n).toString();
211
229
  } catch {
212
230
  return null;
213
231
  }
214
232
  }
215
- function y(e, t) {
233
+ function C(e, t) {
216
234
  let n = new Date(e, t, 1), r = new Date(e, t, 1 - n.getDay());
217
235
  return Array.from({ length: 42 }, (e, t) => ({ date: new Date(r.getFullYear(), r.getMonth(), r.getDate() + t) }));
218
236
  }
219
- function b(e, t) {
237
+ function w(e, t) {
220
238
  typeof e == "function" ? e(t) : e && (e.current = t);
221
239
  }
222
240
  //#endregion
223
- export { h as DateInput, y as calendarDays, v as parseDate };
241
+ export { v as DateInput, C as calendarDays, S as parseDate };
@@ -0,0 +1,58 @@
1
+ import { RecoverableAsyncState as e } from "./RecoverableAsyncState.js";
2
+ import { initialWheelDate as t, wheelBounds as n } from "./date-wheel-model.js";
3
+ import { Component as r, Suspense as i, lazy as a, useEffect as o, useState as s } from "react";
4
+ import { jsx as c } from "react/jsx-runtime";
5
+ //#region src/DateWheelPicker.tsx
6
+ var l = () => a(() => import("./AntDateWheelView.js"));
7
+ function u(e) {
8
+ let [{ View: r, attempt: a }, o] = s(() => ({
9
+ View: l(),
10
+ attempt: 0
11
+ })), u = n(e.minDate, e.maxDate);
12
+ return u ? /* @__PURE__ */ c(d, {
13
+ onError: () => e.onPendingChange?.(!0),
14
+ onRetry: () => o({
15
+ View: l(),
16
+ attempt: a + 1
17
+ }),
18
+ children: /* @__PURE__ */ c(i, {
19
+ fallback: /* @__PURE__ */ c(f, { onPendingChange: e.onPendingChange }),
20
+ children: /* @__PURE__ */ c(r, {
21
+ ...e,
22
+ date: t(e.value, e.minDate, e.maxDate),
23
+ bounds: u
24
+ })
25
+ })
26
+ }, a) : /* @__PURE__ */ c("p", {
27
+ role: "alert",
28
+ className: "ui-form-error",
29
+ children: "日期范围无效"
30
+ });
31
+ }
32
+ var d = class extends r {
33
+ state = { failed: !1 };
34
+ static getDerivedStateFromError() {
35
+ return { failed: !0 };
36
+ }
37
+ componentDidCatch() {
38
+ this.props.onError();
39
+ }
40
+ render() {
41
+ return this.state.failed ? /* @__PURE__ */ c(e, {
42
+ phase: "error",
43
+ loadingTitle: "加载日期选择器",
44
+ errorTitle: "日期选择器加载失败",
45
+ onRetry: this.props.onRetry
46
+ }) : this.props.children;
47
+ }
48
+ };
49
+ function f({ onPendingChange: e }) {
50
+ return o(() => {
51
+ e?.(!0);
52
+ }, [e]), /* @__PURE__ */ c("p", {
53
+ role: "status",
54
+ children: "正在加载日期选择器…"
55
+ });
56
+ }
57
+ //#endregion
58
+ export { u as DateWheelPicker };
@@ -0,0 +1,34 @@
1
+ import { Button as e } from "./Button.js";
2
+ import { useOverlayContainer as t } from "./OverlayContainer.js";
3
+ import { ModalShell as n } from "./ModalShell.js";
4
+ import { useId as r } from "react";
5
+ import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
6
+ import { createPortal as s } from "react-dom";
7
+ //#region src/MobilePickerPanel.tsx
8
+ function c({ title: c, children: l, onClose: u, returnFocus: d, initialFocus: f, summary: p }) {
9
+ let m = r(), h = t();
10
+ return s(/* @__PURE__ */ a(n, {
11
+ titleId: `${m}-title`,
12
+ title: c,
13
+ closeLabel: "关闭选择面板",
14
+ mobileMode: "bottom-sheet",
15
+ onClose: u,
16
+ returnFocus: d,
17
+ initialFocus: f,
18
+ backdropClassName: "ui-picker-sheet-backdrop",
19
+ panelClassName: "ui-picker-sheet",
20
+ contentClassName: "ui-picker-sheet-content",
21
+ footerClassName: "ui-picker-sheet-footer",
22
+ footer: /* @__PURE__ */ o(i, { children: [p && /* @__PURE__ */ a("span", {
23
+ className: "ui-picker-sheet-summary",
24
+ role: "status",
25
+ children: p
26
+ }), /* @__PURE__ */ a(e, {
27
+ onClick: u,
28
+ children: "完成"
29
+ })] }),
30
+ children: l
31
+ }), h ?? document.body);
32
+ }
33
+ //#endregion
34
+ export { c as MobilePickerPanel };
@@ -1,105 +1,117 @@
1
1
  import { Button as e } from "./Button.js";
2
2
  import { OverlayContainerContext as t } from "./OverlayContainer.js";
3
- import { Children as n, Fragment as r, isValidElement as i, useCallback as a, useEffect as o, useRef as s, useState as c } from "react";
4
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
- import { X as d } from "lucide-react";
6
- import * as f from "@radix-ui/react-dialog";
3
+ import { useSheetViewport as n } from "./useSheetViewport.js";
4
+ import { Children as r, Fragment as i, isValidElement as a, useCallback as o, useEffect as s, useRef as c, useState as l } from "react";
5
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
6
+ import { X as f } from "lucide-react";
7
+ import * as p from "@radix-ui/react-dialog";
7
8
  //#region src/ModalShell.tsx
8
- function p({ backdropClassName: e = "", panelClassName: n = "", titleId: r, eyebrow: i, title: d, description: p, closeLabel: _, onClose: b, closeDisabled: x = !1, showCloseButton: S = !0, closeIconSize: C = 20, closeOnBackdrop: w = !1, rootRef: T, closeOnEscape: E = !0, initialFocus: D, returnFocus: O, role: k = "dialog", describedBy: A, children: j, footer: M, contentClassName: N = "", contentProps: P, footerClassName: F = "" }) {
9
- let I = s(null), [L, R] = c(null), z = s(typeof document > "u" ? null : document.activeElement), B = a((e) => {
10
- I.current = e, v(T, e);
11
- }, [T]), V = s(!1), { ref: H, ...U } = P ?? {};
12
- function W() {
13
- return [...document.querySelectorAll("[role='dialog'][aria-modal='true'],[role='alertdialog'][aria-modal='true']")].at(-1) === I.current;
9
+ var m = Symbol("ui-modal-nested-escape");
10
+ function h({ backdropClassName: e = "", panelClassName: r = "", titleId: i, eyebrow: a, title: f, description: h, closeLabel: y, onClose: S, closeDisabled: C = !1, showCloseButton: w = !0, closeIconSize: T = 20, closeOnBackdrop: E = !1, rootRef: D, closeOnEscape: O = !0, initialFocus: k, returnFocus: A, role: j = "dialog", describedBy: M, children: N, footer: P, contentClassName: F = "", contentProps: I, footerClassName: L = "", mobileMode: R = "fullscreen" }) {
11
+ let z = n(R === "bottom-sheet"), B = c(null), [V, H] = l(null), U = c(typeof document > "u" ? null : document.activeElement), W = o((e) => {
12
+ B.current = e, b(D, e);
13
+ }, [D]), G = c(!1), { ref: K, ...q } = I ?? {};
14
+ function J() {
15
+ return [...document.querySelectorAll("[role='dialog'][aria-modal='true'],[role='alertdialog'][aria-modal='true']")].at(-1) === B.current;
14
16
  }
15
- function G() {
16
- !x && W() && b();
17
+ function Y() {
18
+ !C && J() && S();
17
19
  }
18
- o(() => {
19
- h() && M === void 0 && !V.current && m(j) && (V.current = !0, console.warn("[business-ui] ModalShell 的直接 <footer> child 会位于可滚动正文区。固定底栏请改用 footer 属性,并用 footerClassName 定制样式;组件不会自动搬运 children。"));
20
- }, [j, M]);
21
- function K(e) {
22
- w && e.target === e.currentTarget && G(), e.target.closest("button,a[href],input,select,textarea,[tabindex]") || e.preventDefault();
20
+ s(() => {
21
+ _() && P === void 0 && !G.current && g(N) && (G.current = !0, console.warn("[business-ui] ModalShell 的直接 <footer> child 会位于可滚动正文区。固定底栏请改用 footer 属性,并用 footerClassName 定制样式;组件不会自动搬运 children。"));
22
+ }, [N, P]);
23
+ function X(e) {
24
+ E && e.target === e.currentTarget && Y(), e.target.closest("button,a[href],input,select,textarea,[tabindex]") || e.preventDefault();
23
25
  }
24
- return /* @__PURE__ */ l(f.Root, {
26
+ return /* @__PURE__ */ u(p.Root, {
25
27
  open: !0,
26
28
  onOpenChange: (e) => {
27
- e || G();
29
+ e || Y();
28
30
  },
29
- children: /* @__PURE__ */ l(f.Overlay, {
31
+ children: /* @__PURE__ */ u(p.Overlay, {
30
32
  asChild: !0,
31
- children: /* @__PURE__ */ l(f.Content, {
33
+ children: /* @__PURE__ */ u(p.Content, {
32
34
  asChild: !0,
33
35
  onEscapeKeyDown: (e) => {
34
- (x || !E || I.current?.querySelector("[data-ui-aria-overlay]")) && e.preventDefault();
36
+ if (!J()) {
37
+ e[m] = !0, e.preventDefault();
38
+ return;
39
+ }
40
+ (C || !O || B.current?.querySelector("[data-ui-aria-overlay]")) && e.preventDefault();
35
41
  },
36
42
  onInteractOutside: (e) => e.preventDefault(),
37
43
  onOpenAutoFocus: (e) => {
38
- let t = y(D);
44
+ let t = x(k);
39
45
  t && !t.hasAttribute("disabled") && (e.preventDefault(), t.focus());
40
46
  },
41
47
  onCloseAutoFocus: (e) => {
42
- if (e.preventDefault(), O !== !1) {
43
- let e = y(O) ?? z.current;
48
+ if (e.preventDefault(), A !== !1) {
49
+ let e = x(A) ?? U.current;
44
50
  e?.isConnected && e.focus();
45
51
  }
46
52
  },
47
- children: /* @__PURE__ */ l("div", {
48
- ref: B,
53
+ children: /* @__PURE__ */ u("div", {
54
+ ref: W,
49
55
  "data-ui-focus-managed": "radix",
56
+ "data-mobile-mode": R,
57
+ style: z,
50
58
  className: `ui-modal-backdrop ${e}`.trim(),
51
- role: k,
59
+ role: j,
52
60
  "aria-modal": "true",
53
- "aria-labelledby": r,
54
- "aria-describedby": A ?? (p === void 0 ? void 0 : `${r}-description`),
55
- onMouseDown: K,
61
+ "aria-labelledby": i,
62
+ "aria-describedby": M ?? (h === void 0 ? void 0 : `${i}-description`),
63
+ onMouseDown: X,
56
64
  tabIndex: -1,
57
- children: /* @__PURE__ */ u(t.Provider, {
58
- value: L,
59
- children: [/* @__PURE__ */ u("section", {
60
- className: `ui-modal ${n}`.trim(),
65
+ onKeyDown: (e) => {
66
+ let t = e.nativeEvent[m];
67
+ e.key === "Escape" && (!e.defaultPrevented || t) && J() && O && !C && !B.current?.querySelector("[data-ui-aria-overlay]") && (e.preventDefault(), e.stopPropagation(), Y());
68
+ },
69
+ children: /* @__PURE__ */ d(t.Provider, {
70
+ value: V,
71
+ children: [/* @__PURE__ */ d("section", {
72
+ className: `ui-modal ${r}`.trim(),
61
73
  children: [
62
- /* @__PURE__ */ u("header", {
74
+ /* @__PURE__ */ d("header", {
63
75
  className: "ui-modal-header",
64
- children: [/* @__PURE__ */ u("div", { children: [
65
- i === void 0 ? null : /* @__PURE__ */ l("span", {
76
+ children: [/* @__PURE__ */ d("div", { children: [
77
+ a === void 0 ? null : /* @__PURE__ */ u("span", {
66
78
  className: "ui-modal-eyebrow",
67
- children: i
79
+ children: a
68
80
  }),
69
- /* @__PURE__ */ l(f.Title, {
81
+ /* @__PURE__ */ u(p.Title, {
70
82
  asChild: !0,
71
- children: /* @__PURE__ */ l("h2", {
72
- id: r,
73
- children: d
83
+ children: /* @__PURE__ */ u("h2", {
84
+ id: i,
85
+ children: f
74
86
  })
75
87
  }),
76
- p === void 0 ? null : /* @__PURE__ */ l(f.Description, {
88
+ h === void 0 ? null : /* @__PURE__ */ u(p.Description, {
77
89
  asChild: !0,
78
- children: /* @__PURE__ */ l("p", {
79
- id: `${r}-description`,
80
- children: p
90
+ children: /* @__PURE__ */ u("p", {
91
+ id: `${i}-description`,
92
+ children: h
81
93
  })
82
94
  })
83
- ] }), S && /* @__PURE__ */ l(g, {
84
- label: _,
85
- disabled: x,
86
- size: C,
87
- onClose: G
95
+ ] }), w && /* @__PURE__ */ u(v, {
96
+ label: y,
97
+ disabled: C,
98
+ size: T,
99
+ onClose: Y
88
100
  })]
89
101
  }),
90
- /* @__PURE__ */ l("div", {
91
- ...U,
92
- ref: H,
93
- className: `ui-modal-content ${N}`.trim(),
94
- children: j
102
+ /* @__PURE__ */ u("div", {
103
+ ...q,
104
+ ref: K,
105
+ className: `ui-modal-content ${F}`.trim(),
106
+ children: N
95
107
  }),
96
- M === void 0 ? null : /* @__PURE__ */ l("footer", {
97
- className: `ui-modal-footer ${F}`.trim(),
98
- children: M
108
+ P === void 0 ? null : /* @__PURE__ */ u("footer", {
109
+ className: `ui-modal-footer ${L}`.trim(),
110
+ children: P
99
111
  })
100
112
  ]
101
- }), /* @__PURE__ */ l("div", {
102
- ref: R,
113
+ }), /* @__PURE__ */ u("div", {
114
+ ref: H,
103
115
  className: "ui-overlay-container"
104
116
  })]
105
117
  })
@@ -108,32 +120,32 @@ function p({ backdropClassName: e = "", panelClassName: n = "", titleId: r, eyeb
108
120
  })
109
121
  });
110
122
  }
111
- function m(e) {
112
- return n.toArray(e).some((e) => i(e) ? e.type === "footer" || e.type === r && m(e.props.children) : !1);
123
+ function g(e) {
124
+ return r.toArray(e).some((e) => a(e) ? e.type === "footer" || e.type === i && g(e.props.children) : !1);
113
125
  }
114
- function h() {
126
+ function _() {
115
127
  return typeof process < "u" && process.env.NODE_ENV !== "production";
116
128
  }
117
- function g({ label: t, disabled: n, size: r, onClose: i }) {
118
- return /* @__PURE__ */ l(e, {
129
+ function v({ label: t, disabled: n, size: r, onClose: i }) {
130
+ return /* @__PURE__ */ u(e, {
119
131
  className: "ui-modal-close",
120
132
  variant: "ghost",
121
133
  iconOnly: !0,
122
134
  "aria-label": t,
123
135
  onClick: i,
124
136
  disabled: n,
125
- children: /* @__PURE__ */ l(d, {
137
+ children: /* @__PURE__ */ u(f, {
126
138
  size: r,
127
139
  "aria-hidden": "true"
128
140
  })
129
141
  });
130
142
  }
131
- var _ = p;
132
- function v(e, t) {
143
+ var y = h;
144
+ function b(e, t) {
133
145
  typeof e == "function" ? e(t) : e && (e.current = t);
134
146
  }
135
- function y(e) {
147
+ function x(e) {
136
148
  return e && "current" in e ? e.current : e || null;
137
149
  }
138
150
  //#endregion
139
- export { _ as Dialog, p as ModalShell };
151
+ export { y as Dialog, h as ModalShell };
@@ -43,6 +43,7 @@ function x({ values: x, defaultValues: S = y, onValuesChange: C, name: w, select
43
43
  selectionMode: "multiple",
44
44
  value: Z,
45
45
  onChange: (e) => Q(e.map(String)),
46
+ allowsCustomValue: !0,
46
47
  inputValue: j,
47
48
  defaultInputValue: M,
48
49
  onInputChange: N,
@@ -87,7 +88,10 @@ function x({ values: x, defaultValues: S = y, onValuesChange: C, name: w, select
87
88
  id: e.id,
88
89
  textValue: e.label,
89
90
  className: "ui-selection-tag",
90
- children: [e.label, /* @__PURE__ */ r(c, {
91
+ children: [/* @__PURE__ */ r("span", {
92
+ className: "ui-selection-tag-label",
93
+ children: e.label
94
+ }), /* @__PURE__ */ r(c, {
91
95
  slot: "remove",
92
96
  "aria-label": `移除 ${e.label}`,
93
97
  children: "×"