dsh-plugin-core 0.21.0 → 0.22.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.
@@ -14,12 +14,12 @@ export interface AlertModalProps {
14
14
  confirmText?: string;
15
15
  /** 点遮罩是否关闭(默认 true)。 */
16
16
  closeOnMask?: boolean;
17
- /** 确认钮加载中(消费方在做异步处理):转圈 + 禁用,并锁死遮罩 / Esc 关闭。 */
17
+ /** 外部驱动确认钮 loading(如别处正在刷新)。与按钮自己的异步状态取或。 */
18
18
  confirmLoading?: boolean;
19
19
  /** 尺寸档(默认 sm 确认框宽度)。 */
20
20
  size?: ModalSize;
21
- /** 点击确认 / 遮罩 / Esc 的统一出口(单按钮弹窗,关闭即确认)。 */
22
- onConfirm?: () => void;
21
+ /** 点击确认 / 遮罩 / Esc 的统一出口(单按钮弹窗,关闭即确认);**返回 Promise 自动转圈 + 整框锁死**。 */
22
+ onConfirm?: () => unknown;
23
23
  translate?: Translate;
24
24
  }
25
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AlertModal.d.ts","sourceRoot":"","sources":["../../src/ui/AlertModal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAIpD,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AASpE,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,mBAAmB;IACnB,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wBAAwB;IACxB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,gDAAgD;IAChD,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAmBvE"}
1
+ {"version":3,"file":"AlertModal.d.ts","sourceRoot":"","sources":["../../src/ui/AlertModal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAIpD,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AASpE,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,mBAAmB;IACnB,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wBAAwB;IACxB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,OAAO,CAAA;IACzB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAsBvE"}
@@ -1,4 +1,4 @@
1
- import { createElement as h } from 'react';
1
+ import { createElement as h, useState } from 'react';
2
2
  import { Modal } from './Modal.js';
3
3
  import { Button } from './Button.js';
4
4
  import { t } from '../utils/i18n.js';
@@ -18,16 +18,19 @@ export function AlertModal(props) {
18
18
  ensureComponentStyles('feedback', FEEDBACK_CSS);
19
19
  const tt = props.translate ?? t;
20
20
  const severity = props.severity ?? 'info';
21
+ const [running, setRunning] = useState(false);
22
+ // 在跑(自己点的或外部传的)⇒ 遮罩 / Esc 一律不关。
23
+ const busy = running || props.confirmLoading === true;
21
24
  return h(Modal, {
22
25
  icon: h('span', { className: `dshpc-alert-sev dshpc-alert-sev--${severity}` }, SEVERITY_GLYPH[severity]),
23
26
  title: props.title,
24
27
  size: props.size ?? 'sm',
25
28
  hideHeader: props.title === undefined,
26
29
  closable: false,
27
- closeOnMask: props.confirmLoading === true ? false : props.closeOnMask,
28
- // 加载中锁死关闭路径(遮罩 / Esc 都走 onClose)。
29
- onClose: props.confirmLoading === true ? undefined : props.onConfirm,
30
- footer: h(Button, { variant: 'primary', loading: props.confirmLoading === true, onClick: () => props.onConfirm?.() }, props.confirmText ?? tt('dialogOk')),
30
+ closeOnMask: props.closeOnMask,
31
+ busy,
32
+ onClose: props.onConfirm,
33
+ footer: h(Button, { variant: 'primary', loading: props.confirmLoading === true, onBusyChange: setRunning, onClick: () => props.onConfirm?.() }, props.confirmText ?? tt('dialogOk')),
31
34
  }, props.message ?? null);
32
35
  }
33
36
  //# sourceMappingURL=AlertModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AlertModal.js","sourceRoot":"","sources":["../../src/ui/AlertModal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAkB,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAkB,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,CAAC,EAAkB,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAKhD,MAAM,cAAc,GAAkC;IACpD,IAAI,EAAE,GAAG;IACT,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;IACZ,KAAK,EAAE,GAAG;CACX,CAAA;AAsBD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,qBAAqB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAA;IACzC,OAAO,CAAC,CACN,KAAK,EACL;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,oCAAoC,QAAQ,EAAE,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QACxG,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;QACxB,UAAU,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS;QACrC,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW;QACtE,kCAAkC;QAClC,OAAO,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS;QACpE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC;KAC3J,EACD,KAAK,CAAC,OAAO,IAAI,IAAI,CACtB,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"AlertModal.js","sourceRoot":"","sources":["../../src/ui/AlertModal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAA;AACpE,OAAO,EAAE,KAAK,EAAkB,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,CAAC,EAAkB,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAKhD,MAAM,cAAc,GAAkC;IACpD,IAAI,EAAE,GAAG;IACT,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;IACZ,KAAK,EAAE,GAAG;CACX,CAAA;AAsBD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,qBAAqB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAA;IACzC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7C,gCAAgC;IAChC,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,CAAA;IACrD,OAAO,CAAC,CACN,KAAK,EACL;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,oCAAoC,QAAQ,EAAE,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QACxG,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;QACxB,UAAU,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS;QACrC,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,IAAI;QACJ,OAAO,EAAE,KAAK,CAAC,SAAS;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC;KACrL,EACD,KAAK,CAAC,OAAO,IAAI,IAAI,CACtB,CAAA;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import { createElement as h, type CSSProperties, type ReactNode } from 'react';
1
+ import { createElement as h, type CSSProperties, type MouseEvent, type ReactNode } from 'react';
2
2
  /** 按钮外观档。 */
3
3
  export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'success' | 'warning' | 'info' | 'danger-outline' | 'link' | 'purple' | 'pink' | 'cyan' | 'teal' | 'orange' | 'indigo' | 'rose' | 'slate';
4
4
  /** 按钮高度档(sm 24 / md 28 / lg 32)。 */
@@ -17,8 +17,18 @@ export interface ButtonProps {
17
17
  * 实心档作底色、描边与文字档作主色;hover / active 由基础层按该色混出。
18
18
  */
19
19
  color?: string;
20
- /** 加载中:文案前显示同色小圈,并自动禁用点击。 */
20
+ /** 加载中:文案前显示同色小圈,并自动禁用点击。与「点击自动 loading」是或关系,任一为真就转圈。 */
21
21
  loading?: boolean;
22
+ /**
23
+ * 点击回调。**返回 Promise 即自动进入 loading**(转圈 + 禁用 + 防连点),settle 后自己恢复;
24
+ * reject 会恢复并把错误打到控制台。同步返回值 = 老行为,不转圈。
25
+ */
26
+ onClick?: (event: MouseEvent<HTMLButtonElement>) => unknown;
27
+ /**
28
+ * 把「这个按钮正在跑」报出去(如锁死所在弹窗的遮罩 / Esc / ✕)。
29
+ * 不改变按钮自己的行为;与 `loading` 无关。
30
+ */
31
+ onBusyChange?: (busy: boolean) => void;
22
32
  /** 撑满父宽。 */
23
33
  block?: boolean;
24
34
  /**
@@ -53,6 +63,12 @@ export interface IconButtonProps {
53
63
  color?: string;
54
64
  /** 底色(任意 CSS 色值);不传 = 无底色。hover 按它压深。 */
55
65
  background?: string;
66
+ /** 加载中:图标位换成小圈并禁用(纯图标钮没有文字,圈就是它的全部内容)。与「点击自动 loading」取或。 */
67
+ loading?: boolean;
68
+ /** 点击回调;**返回 Promise 自动 loading**,settle 后恢复。 */
69
+ onClick?: (event: MouseEvent<HTMLButtonElement>) => unknown;
70
+ /** 把「这个按钮正在跑」报出去(如锁死所在弹窗)。 */
71
+ onBusyChange?: (busy: boolean) => void;
56
72
  /** 追加 class。 */
57
73
  className?: string;
58
74
  /** 追加样式。 */
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/ui/Button.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAI9E,aAAa;AACb,MAAM,MAAM,aAAa,GACrB,SAAS,GACT,WAAW,GACX,SAAS,GACT,OAAO,GACP,QAAQ,GACR,SAAS,GACT,SAAS,GACT,MAAM,GACN,gBAAgB,GAChB,MAAM,GACN,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;AAEhF,oCAAoC;AACpC,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAQ3C,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,kBAAkB;IAClB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,gCAAgC;IAChC,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY;IACZ,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC1B,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,eAAe;IACf,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,wEAAwE;IACxE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA;IACxC,kBAAkB;IAClB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,cAAc;IACd,IAAI,EAAE,SAAS,CAAA;IACf,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY;IACZ,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,0BAA0B;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AA+BD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAqC/D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAuBvE"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/ui/Button.ts"],"names":[],"mappings":"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"}
package/dist/ui/Button.js CHANGED
@@ -22,9 +22,10 @@
22
22
  */
23
23
  import { MarqueeText } from './MarqueeText.js';
24
24
  import { Loader } from './Loader.js';
25
- import { createElement as h } from 'react';
25
+ import { createElement as h, useState } from 'react';
26
26
  import { ensureComponentStyles } from './css.js';
27
27
  import { BUTTON_CSS } from './controls-css.js';
28
+ import { isThenable } from './thenable.js';
28
29
  /** 实心档(color 参数按「底色」处理;其余档按「字色 + 描边色」处理)。 */
29
30
  const SOLID_VARIANTS = [
30
31
  'primary', 'secondary', 'danger', 'success', 'warning', 'info',
@@ -58,6 +59,32 @@ function buttonClass(variant, size, block, hasIcon, extra) {
58
59
  + `${hasIcon ? ' dshpc-btn--icon-start' : ''}`
59
60
  + `${extra !== undefined && extra !== '' ? ` ${extra}` : ''}`;
60
61
  }
62
+ /**
63
+ * 异步点击:`onClick` 返回 thenable 就自己转圈(并禁用),settle 后恢复。
64
+ * 不用 `onBusyChange` 也能单独工作 —— 它只是把状态报给外面(弹窗锁关闭用)。
65
+ */
66
+ function useAsyncClick(onClick, onBusyChange) {
67
+ const [busy, setBusy] = useState(false);
68
+ const click = (event) => {
69
+ if (onClick === undefined)
70
+ return;
71
+ const out = onClick(event);
72
+ if (!isThenable(out))
73
+ return;
74
+ setBusy(true);
75
+ onBusyChange?.(true);
76
+ const done = () => {
77
+ setBusy(false);
78
+ onBusyChange?.(false);
79
+ };
80
+ void out.then(done, (err) => {
81
+ // 状态先恢复,再让失败可见(不吞:消费方该看到自己抛了什么)
82
+ done();
83
+ console.error('[dsh-plugin-core] Button 异步点击失败,已恢复可点:', err);
84
+ });
85
+ };
86
+ return { busy, click };
87
+ }
61
88
  /**
62
89
  * 渲染一个「图标 + 文案」按钮。
63
90
  *
@@ -66,7 +93,10 @@ function buttonClass(variant, size, block, hasIcon, extra) {
66
93
  */
67
94
  export function Button(props) {
68
95
  ensureComponentStyles('button', BUTTON_CSS);
69
- const { variant = 'outline', size = 'lg', icon, iconRight, color, loading = false, block = false, width, minWidth, maxWidth, className, style, children, ...rest } = props;
96
+ const { variant = 'outline', size = 'lg', icon, iconRight, color, loading: loadingProp = false, block = false, width, minWidth, maxWidth, className, style, children, onClick, onBusyChange, ...rest } = props;
97
+ const asyncClick = useAsyncClick(onClick, onBusyChange);
98
+ // 两个来源取或:外部传的 loading(别处刷新也能点亮它)+ 自己异步在跑
99
+ const loading = loadingProp || asyncClick.busy;
70
100
  // 三轴互斥:固定宽优先,min / max 失效;否则 min / max 各自生效。
71
101
  const widthStyle = {};
72
102
  if (width !== undefined) {
@@ -84,6 +114,7 @@ export function Button(props) {
84
114
  ...rest,
85
115
  type: rest.type ?? 'button',
86
116
  disabled: rest.disabled === true || loading,
117
+ onClick: asyncClick.click,
87
118
  className: buttonClass(variant, size, block, icon !== undefined && icon !== null && !loading, className),
88
119
  style: { ...colorVars(variant, color), ...widthStyle, ...style },
89
120
  };
@@ -95,7 +126,9 @@ export function Button(props) {
95
126
  ? h('span', { className: 'dshpc-btn__icon' }, icon)
96
127
  : null, marqueeLabel
97
128
  ? h(MarqueeText, { text: children, className: 'dshpc-btn__label' })
98
- : children, iconRight !== undefined && iconRight !== null
129
+ : children,
130
+ // 转圈期间所有图标位都让位:前置位被 Loader 顶替,后置位(展开 / 外链)留在禁用态里只会挤版面
131
+ iconRight !== undefined && iconRight !== null && !loading
99
132
  ? h('span', { className: 'dshpc-btn__icon-end' }, iconRight)
100
133
  : null);
101
134
  }
@@ -107,7 +140,9 @@ export function Button(props) {
107
140
  */
108
141
  export function IconButton(props) {
109
142
  ensureComponentStyles('button', BUTTON_CSS);
110
- const { variant = 'plain', size = 'lg', icon, label, color, background, className, style, ...rest } = props;
143
+ const { variant = 'plain', size = 'lg', icon, label, color, background, loading: loadingProp = false, className, style, onClick, onBusyChange, ...rest } = props;
144
+ const asyncClick = useAsyncClick(onClick, onBusyChange);
145
+ const loading = loadingProp || asyncClick.busy;
111
146
  // 只覆盖 4 个局部变量:图标色 / 底色及其 hover 派生(不新增皮肤,皮肤仍在 controls-css.ts)。
112
147
  const accent = {};
113
148
  if (color !== undefined && color !== '') {
@@ -124,9 +159,13 @@ export function IconButton(props) {
124
159
  type: rest.type ?? 'button',
125
160
  title: rest.title ?? label,
126
161
  'aria-label': rest['aria-label'] ?? label,
162
+ // 无障碍名不变(仍是 label),只声明「正在忙」,读屏不会把圈读成内容
163
+ 'aria-busy': loading || undefined,
164
+ disabled: rest.disabled === true || loading,
165
+ onClick: asyncClick.click,
127
166
  className: `dshpc-iconbtn dshpc-iconbtn--${variant} dshpc-iconbtn--${size}${className !== undefined && className !== '' ? ` ${className}` : ''}`,
128
167
  style: { ...accent, ...style },
129
168
  };
130
- return h('button', attrs, icon);
169
+ return h('button', attrs, loading ? h(Loader, { size: 'xs' }) : icon);
131
170
  }
132
171
  //# sourceMappingURL=Button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../src/ui/Button.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../src/ui/Button.ts"],"names":[],"mappings":"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"}
@@ -15,20 +15,23 @@ export interface ConfirmModalProps {
15
15
  cancelText?: string;
16
16
  /** 点遮罩是否关闭(默认 true;点了 = 取消)。 */
17
17
  closeOnMask?: boolean;
18
- /** 确认钮加载中(消费方在做异步处理):转圈 + 禁用。任一钮加载中,整框都不许关。 */
18
+ /** 外部驱动确认钮 loading(如别处正在刷新)。与按钮自己的异步状态取或。 */
19
19
  confirmLoading?: boolean;
20
- /** 取消钮加载中:同上。 */
20
+ /** 外部驱动取消钮 loading:同上。 */
21
21
  cancelLoading?: boolean;
22
22
  size?: ModalSize;
23
- /** 确认回调。 */
24
- onConfirm?: () => void;
25
- /** 取消 / 遮罩 / Esc 回调。 */
26
- onCancel?: () => void;
23
+ /** 确认回调;**返回 Promise 自动转圈 + 整框锁死**,settle 后恢复(关闭与否由你决定)。 */
24
+ onConfirm?: () => unknown;
25
+ /** 取消 / 遮罩 / Esc 回调;异步语义同 `onConfirm`。 */
26
+ onCancel?: () => unknown;
27
27
  translate?: Translate;
28
28
  }
29
29
  /**
30
30
  * 确认框(语义层,基于 Modal):双按钮(取消 outline + 确认语义档)、无 ✕;无标题时整条头部消失。
31
31
  * 样式封闭:按钮只暴露语义档(tone → variant),不透传任意 className/style。
32
+ *
33
+ * 异步不在这里实现:`onConfirm` / `onCancel` 返回 Promise 时由 `Button` 自动转圈,
34
+ * 它再把「在跑」报上来,这里只负责把它转成 `Modal` 的 `busy`(锁死遮罩 / Esc)。
32
35
  */
33
36
  export declare function ConfirmModal(props: ConfirmModalProps): ReturnType<typeof h>;
34
37
  //# sourceMappingURL=ConfirmModal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmModal.d.ts","sourceRoot":"","sources":["../../src/ui/ConfirmModal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEpD,uBAAuB;AACvB,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE1D,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,mBAAmB;IACnB,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,iBAAiB;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,YAAY;IACZ,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAwB3E"}
1
+ {"version":3,"file":"ConfirmModal.d.ts","sourceRoot":"","sources":["../../src/ui/ConfirmModal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEpD,uBAAuB;AACvB,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE1D,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,mBAAmB;IACnB,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,OAAO,CAAA;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAA;IACxB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CA2B3E"}
@@ -1,25 +1,31 @@
1
- import { createElement as h } from 'react';
1
+ import { createElement as h, useState } from 'react';
2
2
  import { Modal } from './Modal.js';
3
3
  import { Button } from './Button.js';
4
4
  import { t } from '../utils/i18n.js';
5
5
  /**
6
6
  * 确认框(语义层,基于 Modal):双按钮(取消 outline + 确认语义档)、无 ✕;无标题时整条头部消失。
7
7
  * 样式封闭:按钮只暴露语义档(tone → variant),不透传任意 className/style。
8
+ *
9
+ * 异步不在这里实现:`onConfirm` / `onCancel` 返回 Promise 时由 `Button` 自动转圈,
10
+ * 它再把「在跑」报上来,这里只负责把它转成 `Modal` 的 `busy`(锁死遮罩 / Esc)。
8
11
  */
9
12
  export function ConfirmModal(props) {
10
13
  const tt = props.translate ?? t;
11
14
  const tone = props.tone ?? 'primary';
12
15
  const confirmVariant = tone === 'danger' ? 'danger' : tone === 'warning' ? 'warning' : 'primary';
13
- // 加载中整框锁死:遮罩 / Esc 都走 onClose,置空即封死(✕ 本来就没有)。
14
- const busy = props.confirmLoading === true || props.cancelLoading === true;
16
+ const [confirmBusy, setConfirmBusy] = useState(false);
17
+ const [cancelBusy, setCancelBusy] = useState(false);
18
+ // 任一钮在跑(自己点的或外部传的)⇒ 整框不可关。
19
+ const busy = confirmBusy || cancelBusy || props.confirmLoading === true || props.cancelLoading === true;
15
20
  return h(Modal, {
16
21
  title: props.title,
17
22
  size: props.size ?? 'sm',
18
23
  hideHeader: props.title === undefined,
19
24
  closable: false,
20
- closeOnMask: busy ? false : props.closeOnMask,
21
- onClose: busy ? undefined : props.onCancel,
22
- footer: h('div', { style: { display: 'flex', gap: '8px', justifyContent: 'flex-end' } }, h(Button, { variant: 'outline', loading: props.cancelLoading === true, onClick: () => props.onCancel?.() }, props.cancelText ?? tt('cancel')), h(Button, { variant: confirmVariant, loading: props.confirmLoading === true, onClick: () => props.onConfirm?.() }, props.confirmText ?? tt('confirm'))),
25
+ closeOnMask: props.closeOnMask,
26
+ busy,
27
+ onClose: props.onCancel,
28
+ footer: h('div', { style: { display: 'flex', gap: '8px', justifyContent: 'flex-end' } }, h(Button, { variant: 'outline', loading: props.cancelLoading === true, onBusyChange: setCancelBusy, onClick: () => props.onCancel?.() }, props.cancelText ?? tt('cancel')), h(Button, { variant: confirmVariant, loading: props.confirmLoading === true, onBusyChange: setConfirmBusy, onClick: () => props.onConfirm?.() }, props.confirmText ?? tt('confirm'))),
23
29
  }, props.message ?? null);
24
30
  }
25
31
  //# sourceMappingURL=ConfirmModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmModal.js","sourceRoot":"","sources":["../../src/ui/ConfirmModal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAkB,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAkB,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,CAAC,EAAkB,MAAM,kBAAkB,CAAA;AA6BpD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,SAAS,CAAA;IACpC,MAAM,cAAc,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAChG,8CAA8C;IAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,cAAc,KAAK,IAAI,IAAI,KAAK,CAAC,aAAa,KAAK,IAAI,CAAA;IAC1E,OAAO,CAAC,CACN,KAAK,EACL;QACE,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;QACxB,UAAU,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS;QACrC,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW;QAC7C,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ;QAC1C,MAAM,EAAE,CAAC,CACP,KAAK,EACL,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,EACtE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,EAC7I,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,CACvJ;KACF,EACD,KAAK,CAAC,OAAO,IAAI,IAAI,CACtB,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"ConfirmModal.js","sourceRoot":"","sources":["../../src/ui/ConfirmModal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAA;AACpE,OAAO,EAAE,KAAK,EAAkB,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,CAAC,EAAkB,MAAM,kBAAkB,CAAA;AA6BpD;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,SAAS,CAAA;IACpC,MAAM,cAAc,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAChG,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACrD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,2BAA2B;IAC3B,MAAM,IAAI,GAAG,WAAW,IAAI,UAAU,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,IAAI,KAAK,CAAC,aAAa,KAAK,IAAI,CAAA;IACvG,OAAO,CAAC,CACN,KAAK,EACL;QACE,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;QACxB,UAAU,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS;QACrC,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,IAAI;QACJ,OAAO,EAAE,KAAK,CAAC,QAAQ;QACvB,MAAM,EAAE,CAAC,CACP,KAAK,EACL,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,EACtE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,EAC1K,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,CACrL;KACF,EACD,KAAK,CAAC,OAAO,IAAI,IAAI,CACtB,CAAA;AACH,CAAC"}
@@ -23,6 +23,11 @@ export interface ModalProps {
23
23
  closeOnMask?: boolean;
24
24
  /** 按 Esc 是否关闭(默认 true)。 */
25
25
  escClose?: boolean;
26
+ /**
27
+ * 有异步在跑(如 footer 里的 `Button` 正在 loading):为真时遮罩 / Esc / ✕ **三条关闭路径全失效**,
28
+ * 内容照常渲染。与 `closeOnMask` / `escClose` / `closable` 是"与"关系 —— 它是否决项,不替代它们。
29
+ */
30
+ busy?: boolean;
26
31
  /** 尺寸档:sm=小确认框家族 / md·lg=大弹窗家族;也可用 width/height 精确覆盖。 */
27
32
  size?: ModalSize;
28
33
  /** 面板宽度(默认随 size:sm 360px / md 720px / lg 1120px,均带视口兜底)。 */
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/ui/Modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAMpD,qCAAqC;AACrC,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE1C,MAAM,WAAW,UAAU;IACzB,oBAAoB;IACpB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,qCAAqC;IACrC,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wCAAwC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,yDAAyD;IACzD,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,wDAAwD;IACxD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAmE7D"}
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/ui/Modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAMpD,qCAAqC;AACrC,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE1C,MAAM,WAAW,UAAU;IACzB,oBAAoB;IACpB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,qCAAqC;IACrC,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wCAAwC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,yDAAyD;IACzD,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,wDAAwD;IACxD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAqE7D"}
package/dist/ui/Modal.js CHANGED
@@ -12,8 +12,10 @@ import { PanelSurface } from './panel.js';
12
12
  export function Modal(props) {
13
13
  ensureComponentStyles('feedback', FEEDBACK_CSS);
14
14
  const tt = props.translate ?? t;
15
- const closeOnMask = props.closeOnMask !== false;
16
- useEscapeClose(props.escClose !== false, props.onClose);
15
+ // busy 是否决项:三条关闭路径一起封死(✕ 见下面 showClose)。
16
+ const busy = props.busy === true;
17
+ const closeOnMask = !busy && props.closeOnMask !== false;
18
+ useEscapeClose(!busy && props.escClose !== false, busy ? undefined : props.onClose);
17
19
  // 默认宽高(兄弟项目真值:小框 360px(task-list.tsx:457)/ 大弹窗 min(1120px,100vw-32px) × calc(100%-80px)(archive-session-css.ts:42))。
18
20
  // 宽度用 `100%`(相对遮罩盒)而不是 `100vw`:遮罩已按右侧分栏让位(见 feedback.css),
19
21
  // 用 `100vw` 算出来的宽在分栏在场时会溢出到分栏上,等于白让(用户 2026-10-22)。
@@ -23,7 +25,7 @@ export function Modal(props) {
23
25
  lg: { width: 'min(1120px, calc(100% - 32px))', height: 'calc(100% - 80px)' },
24
26
  };
25
27
  const s = sizeStyle[props.size ?? 'md'];
26
- const showClose = props.closable !== false && props.onClose !== undefined;
28
+ const showClose = props.closable !== false && props.onClose !== undefined && !busy;
27
29
  const showHeader = props.hideHeader !== true &&
28
30
  (props.icon !== undefined ||
29
31
  props.title !== undefined ||
@@ -31,7 +33,7 @@ export function Modal(props) {
31
33
  props.headerExtra !== undefined ||
32
34
  props.headerActions !== undefined ||
33
35
  showClose);
34
- return h(OverlayMask, { kind: 'center', closeOnMask, onClose: props.onClose },
36
+ return h(OverlayMask, { kind: 'center', closeOnMask, onClose: busy ? undefined : props.onClose },
35
37
  // 表面(底色/描边/圆角/阴影)来自 panel.css 的 modal 档;`.dshpc-modal` 只剩家族布局,
36
38
  // 且继续作为既有类名别名存在(消费方写在它上面的覆盖不受影响)。
37
39
  h(PanelSurface, {
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/ui/Modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAkB,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAE,CAAC,EAAkB,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA8CzC;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,KAAiB;IACrC,qBAAqB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAC/B,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,KAAK,KAAK,CAAA;IAC/C,cAAc,CAAC,KAAK,CAAC,QAAQ,KAAK,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAEvD,qHAAqH;IACrH,2DAA2D;IAC3D,oDAAoD;IACpD,MAAM,SAAS,GAAiG;QAC9G,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE;QACrD,EAAE,EAAE,EAAE,KAAK,EAAE,+BAA+B,EAAE,SAAS,EAAE,MAAM,EAAE;QACjE,EAAE,EAAE,EAAE,KAAK,EAAE,gCAAgC,EAAE,MAAM,EAAE,mBAAmB,EAAE;KAC7E,CAAA;IACD,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAA;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,CAAA;IACzE,MAAM,UAAU,GACd,KAAK,CAAC,UAAU,KAAK,IAAI;QACzB,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YACvB,KAAK,CAAC,KAAK,KAAK,SAAS;YACzB,KAAK,CAAC,QAAQ,KAAK,SAAS;YAC5B,KAAK,CAAC,WAAW,KAAK,SAAS;YAC/B,KAAK,CAAC,aAAa,KAAK,SAAS;YACjC,SAAS,CAAC,CAAA;IAEd,OAAO,CAAC,CACN,WAAW,EACX,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;IACvD,+DAA+D;IAC/D,kCAAkC;IAClC,CAAC,CACC,YAAY,EACZ;QACE,IAAI,EAAE,OAAO;QACb,SAAS,EAAE,cAAc,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QACjK,KAAK,EAAE;YACL,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK;YAC7B,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ;YACtC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS;YACzC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM;SACjC;QACD,eAAe,EAAE,IAAI;KACtB;IACD,6CAA6C;IAC7C,UAAU;QACR,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YACb,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,KAAK,CAAC,WAAW;YACxB,OAAO,EAAE,KAAK,CAAC,aAAa;YAC5B,UAAU,EAAE,EAAE,CAAC,YAAY,CAAC;YAC5B,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC/C,CAAC;QACJ,CAAC,CAAC,IAAI;IACR,wCAAwC;IACxC,gDAAgD;IAChD,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,EACpE,KAAK,CAAC,MAAM,KAAK,SAAS;QACxB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CACC,KAAK,EACL,EAAE,SAAS,EAAE,oBAAoB,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EACpG,KAAK,CAAC,MAAM,CACb,CACN,CACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/ui/Modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAkB,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAE,CAAC,EAAkB,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAmDzC;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,KAAiB;IACrC,qBAAqB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAC/B,yCAAyC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,IAAI,CAAA;IAChC,MAAM,WAAW,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAA;IACxD,cAAc,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEnF,qHAAqH;IACrH,2DAA2D;IAC3D,oDAAoD;IACpD,MAAM,SAAS,GAAiG;QAC9G,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE;QACrD,EAAE,EAAE,EAAE,KAAK,EAAE,+BAA+B,EAAE,SAAS,EAAE,MAAM,EAAE;QACjE,EAAE,EAAE,EAAE,KAAK,EAAE,gCAAgC,EAAE,MAAM,EAAE,mBAAmB,EAAE;KAC7E,CAAA;IACD,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAA;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,IAAI,CAAA;IAClF,MAAM,UAAU,GACd,KAAK,CAAC,UAAU,KAAK,IAAI;QACzB,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YACvB,KAAK,CAAC,KAAK,KAAK,SAAS;YACzB,KAAK,CAAC,QAAQ,KAAK,SAAS;YAC5B,KAAK,CAAC,WAAW,KAAK,SAAS;YAC/B,KAAK,CAAC,aAAa,KAAK,SAAS;YACjC,SAAS,CAAC,CAAA;IAEd,OAAO,CAAC,CACN,WAAW,EACX,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE;IAC1E,+DAA+D;IAC/D,kCAAkC;IAClC,CAAC,CACC,YAAY,EACZ;QACE,IAAI,EAAE,OAAO;QACb,SAAS,EAAE,cAAc,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QACjK,KAAK,EAAE;YACL,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK;YAC7B,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ;YACtC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS;YACzC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM;SACjC;QACD,eAAe,EAAE,IAAI;KACtB;IACD,6CAA6C;IAC7C,UAAU;QACR,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YACb,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,KAAK,CAAC,WAAW;YACxB,OAAO,EAAE,KAAK,CAAC,aAAa;YAC5B,UAAU,EAAE,EAAE,CAAC,YAAY,CAAC;YAC5B,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC/C,CAAC;QACJ,CAAC,CAAC,IAAI;IACR,wCAAwC;IACxC,gDAAgD;IAChD,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,EACpE,KAAK,CAAC,MAAM,KAAK,SAAS;QACxB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CACC,KAAK,EACL,EAAE,SAAS,EAAE,oBAAoB,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EACpG,KAAK,CAAC,MAAM,CACb,CACN,CACF,CAAA;AACH,CAAC"}
@@ -45,6 +45,11 @@ export interface SideSheetProps {
45
45
  closeOnMask?: boolean;
46
46
  /** 按 Esc 是否关闭(默认 true)。 */
47
47
  escClose?: boolean;
48
+ /**
49
+ * 有异步在跑(如 footer 里的 `Button` 正在 loading):为真时遮罩 / Esc / ✕ **三条关闭路径全失效**,
50
+ * 内容照常渲染。与 `closeOnMask` / `escClose` / `closable` 是"与"关系 —— 它是否决项,不替代它们。
51
+ */
52
+ busy?: boolean;
48
53
  /** **初始**宽度(px,默认 460,与 PanelDock 同档);拖过之后以拖出来的为准。 */
49
54
  width?: number;
50
55
  /** 可拖宽的下限(默认 320)。 */
@@ -1 +1 @@
1
- {"version":3,"file":"SideSheet.d.ts","sourceRoot":"","sources":["../../src/ui/SideSheet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACvF,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAOpD,wBAAwB;AACxB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAA;AAE5C,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,cAAc;IACd,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,eAAe;IACf,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,iCAAiC;IACjC,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IACzB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,qBAAqB;IACrB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,wBAAwB;IACxB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qBAAqB;IACrB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CAqH1D"}
1
+ {"version":3,"file":"SideSheet.d.ts","sourceRoot":"","sources":["../../src/ui/SideSheet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACvF,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAOpD,wBAAwB;AACxB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAA;AAE5C,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,cAAc;IACd,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,eAAe;IACf,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,iCAAiC;IACjC,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IACzB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,qBAAqB;IACrB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,wBAAwB;IACxB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qBAAqB;IACrB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CAuH1D"}
@@ -22,8 +22,10 @@ export function SideSheet(props) {
22
22
  ensureComponentStyles('side-sheet', SIDE_SHEET_CSS);
23
23
  const tt = props.translate ?? t;
24
24
  const side = props.side ?? 'left';
25
- const closeOnMask = props.closeOnMask !== false;
26
- useEscapeClose(props.escClose !== false, props.onClose);
25
+ // busy 是否决项:三条关闭路径一起封死(✕ 见下面 showClose)。
26
+ const busy = props.busy === true;
27
+ const closeOnMask = !busy && props.closeOnMask !== false;
28
+ useEscapeClose(!busy && props.escClose !== false, busy ? undefined : props.onClose);
27
29
  const [width, setWidth] = useState(props.width ?? 460);
28
30
  const panelRef = useRef(null);
29
31
  // 收起动效(用户 2026-11-02):open=false 时先播完 dshpc-side-out 再真正卸载;
@@ -37,7 +39,7 @@ export function SideSheet(props) {
37
39
  }, [leaving]);
38
40
  if (unmounted)
39
41
  return null;
40
- const showClose = props.closable !== false && props.onClose !== undefined;
42
+ const showClose = props.closable !== false && props.onClose !== undefined && !busy;
41
43
  const hasHeader = props.header !== null;
42
44
  const beginResize = (event) => {
43
45
  const element = panelRef.current;
@@ -84,7 +86,7 @@ export function SideSheet(props) {
84
86
  }
85
87
  return h('div', { className: 'dshpc-dock__head' }, props.icon === undefined ? null : h('div', { className: 'dshpc-dock__lead' }, props.icon), h('div', { className: 'dshpc-dock__title' }, props.title), props.extra === undefined ? null : h('div', { className: 'dshpc-dock__extra' }, props.extra));
86
88
  };
87
- return h(OverlayMask, { kind: 'side', closeOnMask, onClose: props.onClose }, h('section', {
89
+ return h(OverlayMask, { kind: 'side', closeOnMask, onClose: busy ? undefined : props.onClose }, h('section', {
88
90
  ref: (element) => {
89
91
  panelRef.current = element;
90
92
  },
@@ -1 +1 @@
1
- {"version":3,"file":"SideSheet.js","sourceRoot":"","sources":["../../src/ui/SideSheet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAA;AACvF,OAAO,EAAE,CAAC,EAAkB,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAiDrD,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,qBAAqB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IACnD,qBAAqB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IACnD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAA;IACjC,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,KAAK,KAAK,CAAA;IAC/C,cAAc,CAAC,KAAK,CAAC,QAAQ,KAAK,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAEvD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC,CAAA;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAA;IAEjD,4DAA4D;IAC5D,kBAAkB;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAA;IACpC,iCAAiC;IACjC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;IACnD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO;YAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IACb,IAAI,SAAS;QAAE,OAAO,IAAI,CAAA;IAE1B,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,CAAA;IACzE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,KAAK,IAAI,CAAA;IAEvC,MAAM,WAAW,GAAG,CAAC,KAAuD,EAAQ,EAAE;QACpF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAA;QAChC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAM;QAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAA;QAC5B,MAAM,UAAU,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAA;QACxD,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,IAAI,GAAG,CAAA;QACjC,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,iBAAiB,CAAA;QAC9D,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QACrD,sBAAsB,CAAC;YACrB,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE;gBACnB,+BAA+B;gBAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,EAAE,qBAAqB,EAAE,CAAC,KAAK,IAAI,MAAM,CAAC,UAAU,CAAA;gBACrF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAA;gBACrD,qBAAqB;gBACrB,MAAM,GAAG,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,CAAA;gBAC/F,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;YACtD,CAAC;YACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACf,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,IAAI,IAAI,CAAA;YACnC,CAAC;YACD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;gBACjB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,8BAA8B,CAAC,CAAA;gBACxD,QAAQ,CAAC,IAAI,CAAC,CAAA;YAChB,CAAC;SACF,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,QAAiB,EAAa,EAAE,CACnD,CAAC,SAAS;QACR,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CACC,QAAQ,EACR;YACE,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,qBAAqB,QAAQ,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,wBAAwB,EAAE;YACrG,YAAY,EAAE,EAAE,CAAC,WAAW,CAAC;YAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE;SACjC,EACD,KAAK,CAAC,SAAS,IAAI,GAAG,CACvB,CAAA;IAEP,MAAM,YAAY,GAAG,GAAc,EAAE;QACnC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QACtC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,2CAA2C,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QAC3F,CAAC;QACD,OAAO,CAAC,CACN,KAAK,EACL,EAAE,SAAS,EAAE,kBAAkB,EAAE,EACjC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,EACzF,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,KAAkB,CAAC,EACtE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAC7F,CAAA;IACH,CAAC,CAAA;IAED,OAAO,CAAC,CACN,WAAW,EACX,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EACrD,CAAC,CACC,SAAS,EACT;QACE,GAAG,EAAE,CAAC,OAA2B,EAAQ,EAAE;YACzC,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAA;QAC5B,CAAC;QACD,SAAS,EAAE,+CAA+C,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,EAAE;QACzG,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,EAAE;QAC9B,yCAAyC;QACzC,cAAc,EAAE,GAAS,EAAE;YACzB,IAAI,OAAO;gBAAE,YAAY,CAAC,IAAI,CAAC,CAAA;QACjC,CAAC;QACD,YAAY,EAAE,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACvE,8BAA8B;QAC9B,OAAO,EAAE,CAAC,CAAkC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE;KACrE,EACD,KAAK,CAAC,SAAS,KAAK,KAAK;QACvB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;YACP,SAAS,EAAE,qBAAqB;YAChC,IAAI,EAAE,WAAW;YACjB,kBAAkB,EAAE,UAAU;YAC9B,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC;YAC9B,aAAa,EAAE,CAAC,KAAuD,EAAE,EAAE;gBACzE,WAAW,CAAC,KAAK,CAAC,CAAA;YACpB,CAAC;SACF,CAAC,EACN,YAAY,EAAE,EACd,WAAW,CAAC,CAAC,SAAS,CAAC,EACvB,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,oCAAoC,EAAE,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,EACrF,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAC/F,CACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"SideSheet.js","sourceRoot":"","sources":["../../src/ui/SideSheet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAA;AACvF,OAAO,EAAE,CAAC,EAAkB,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAsDrD,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,qBAAqB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IACnD,qBAAqB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IACnD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAA;IACjC,yCAAyC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,IAAI,CAAA;IAChC,MAAM,WAAW,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAA;IACxD,cAAc,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEnF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC,CAAA;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAA;IAEjD,4DAA4D;IAC5D,kBAAkB;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAA;IACpC,iCAAiC;IACjC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;IACnD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO;YAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IACb,IAAI,SAAS;QAAE,OAAO,IAAI,CAAA;IAE1B,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,IAAI,CAAA;IAClF,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,KAAK,IAAI,CAAA;IAEvC,MAAM,WAAW,GAAG,CAAC,KAAuD,EAAQ,EAAE;QACpF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAA;QAChC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAM;QAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAA;QAC5B,MAAM,UAAU,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAA;QACxD,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,IAAI,GAAG,CAAA;QACjC,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,iBAAiB,CAAA;QAC9D,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QACrD,sBAAsB,CAAC;YACrB,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE;gBACnB,+BAA+B;gBAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,EAAE,qBAAqB,EAAE,CAAC,KAAK,IAAI,MAAM,CAAC,UAAU,CAAA;gBACrF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAA;gBACrD,qBAAqB;gBACrB,MAAM,GAAG,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,CAAA;gBAC/F,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;YACtD,CAAC;YACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACf,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,IAAI,IAAI,CAAA;YACnC,CAAC;YACD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;gBACjB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,8BAA8B,CAAC,CAAA;gBACxD,QAAQ,CAAC,IAAI,CAAC,CAAA;YAChB,CAAC;SACF,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,QAAiB,EAAa,EAAE,CACnD,CAAC,SAAS;QACR,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CACC,QAAQ,EACR;YACE,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,qBAAqB,QAAQ,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,wBAAwB,EAAE;YACrG,YAAY,EAAE,EAAE,CAAC,WAAW,CAAC;YAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE;SACjC,EACD,KAAK,CAAC,SAAS,IAAI,GAAG,CACvB,CAAA;IAEP,MAAM,YAAY,GAAG,GAAc,EAAE;QACnC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QACtC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,2CAA2C,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QAC3F,CAAC;QACD,OAAO,CAAC,CACN,KAAK,EACL,EAAE,SAAS,EAAE,kBAAkB,EAAE,EACjC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,EACzF,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,KAAkB,CAAC,EACtE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAC7F,CAAA;IACH,CAAC,CAAA;IAED,OAAO,CAAC,CACN,WAAW,EACX,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,EACxE,CAAC,CACC,SAAS,EACT;QACE,GAAG,EAAE,CAAC,OAA2B,EAAQ,EAAE;YACzC,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAA;QAC5B,CAAC;QACD,SAAS,EAAE,+CAA+C,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,EAAE;QACzG,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,EAAE;QAC9B,yCAAyC;QACzC,cAAc,EAAE,GAAS,EAAE;YACzB,IAAI,OAAO;gBAAE,YAAY,CAAC,IAAI,CAAC,CAAA;QACjC,CAAC;QACD,YAAY,EAAE,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACvE,8BAA8B;QAC9B,OAAO,EAAE,CAAC,CAAkC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE;KACrE,EACD,KAAK,CAAC,SAAS,KAAK,KAAK;QACvB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;YACP,SAAS,EAAE,qBAAqB;YAChC,IAAI,EAAE,WAAW;YACjB,kBAAkB,EAAE,UAAU;YAC9B,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC;YAC9B,aAAa,EAAE,CAAC,KAAuD,EAAE,EAAE;gBACzE,WAAW,CAAC,KAAK,CAAC,CAAA;YACpB,CAAC;SACF,CAAC,EACN,YAAY,EAAE,EACd,WAAW,CAAC,CAAC,SAAS,CAAC,EACvB,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,oCAAoC,EAAE,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,EACrF,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAC/F,CACF,CAAA;AACH,CAAC"}
@@ -17,7 +17,7 @@ export interface HostDialogHandlers {
17
17
  alert: (opts: HostAlertArgs) => Promise<void>;
18
18
  }
19
19
  export declare function registerHostDialog(handlers: HostDialogHandlers): void;
20
- /** 点按钮的回调:返回 thenable 即视为「消费方要做异步处理」,弹窗转 loading 并锁死关闭,settle 后再收尾。 */
20
+ /** 点按钮的回调:返回 thenable 即视为「消费方要做异步处理」。 */
21
21
  type DialogHandler = () => unknown;
22
22
  export type ConfirmOptions = Omit<ConfirmModalProps, 'onConfirm' | 'onCancel' | 'confirmLoading' | 'cancelLoading'> & {
23
23
  skin?: 'core' | 'host';
@@ -1 +1 @@
1
- {"version":3,"file":"modal-host.d.ts","sourceRoot":"","sources":["../../src/ui/modal-host.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAmDxE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AACD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AACD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACpD,KAAK,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9C;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAErE;AAED,uEAAuE;AACvE,KAAK,aAAa,GAAG,MAAM,OAAO,CAAA;AAElC,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,WAAW,GAAG,UAAU,GAAG,gBAAgB,GAAG,eAAe,CAAC,GAAG;IACpH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,aAAa,CAAA;CACzB,CAAA;AACD,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,gBAAgB,CAAC,GAAG;IACjF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,oDAAoD;IACpD,SAAS,CAAC,EAAE,aAAa,CAAA;CAC1B,CAAA;AAOD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CA2DnE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgD5D"}
1
+ {"version":3,"file":"modal-host.d.ts","sourceRoot":"","sources":["../../src/ui/modal-host.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAoDxE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AACD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AACD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACpD,KAAK,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9C;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAErE;AAED,yCAAyC;AACzC,KAAK,aAAa,GAAG,MAAM,OAAO,CAAA;AAElC,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,WAAW,GAAG,UAAU,GAAG,gBAAgB,GAAG,eAAe,CAAC,GAAG;IACpH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,aAAa,CAAA;CACzB,CAAA;AACD,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,gBAAgB,CAAC,GAAG;IACjF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,oDAAoD;IACpD,SAAS,CAAC,EAAE,aAAa,CAAA;CAC1B,CAAA;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CA0CnE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC5D"}
@@ -3,6 +3,7 @@ import { createRoot } from 'react-dom/client';
3
3
  import { ensureControls, getStyleKit } from './css.js';
4
4
  import { AlertModal } from './AlertModal.js';
5
5
  import { ConfirmModal } from './ConfirmModal.js';
6
+ import { isThenable } from './thenable.js';
6
7
  // ⚠️ core 的 StyleKit / i18n 都是**模块级单例**(见 css.ts 注释),不依赖 React Context,
7
8
  // 所以命令式弹窗所在的独立 root 天然能读到它们——无需手动注入插件上下文。
8
9
  // 唯一读不到的是「插件自己定义的 React Context」,那是用户的私有环境,命令式本就不继承。
@@ -45,11 +46,6 @@ let hostHandlers = null;
45
46
  export function registerHostDialog(handlers) {
46
47
  hostHandlers = handlers;
47
48
  }
48
- function isThenable(value) {
49
- if (value === null || value === undefined)
50
- return false;
51
- return typeof value.then === 'function';
52
- }
53
49
  /**
54
50
  * 命令式确认框:Promise 形式,`true`=确定 / `false`=取消(或点遮罩 / Esc)。`skin:"host"` 走宿主原生 Modal。
55
51
  * 回调返回 Promise 时进入 loading(按钮转圈 + 遮罩 / Esc 锁死),settle 后才真正关闭。
@@ -71,49 +67,32 @@ export function confirmModal(opts) {
71
67
  void _skin;
72
68
  return new Promise((resolve) => {
73
69
  const id = ++idSeq;
74
- const entry = { id, node: null };
75
- let busy = null;
76
70
  let closed = false;
77
- const draw = () => {
78
- entry.node = h(ConfirmModal, {
79
- ...core,
80
- confirmLoading: busy === 'confirm',
81
- cancelLoading: busy === 'cancel',
82
- onConfirm: () => void run('confirm'),
83
- onCancel: () => void run('cancel'),
84
- });
85
- flush();
86
- };
87
71
  const close = (result) => {
72
+ if (closed)
73
+ return;
88
74
  closed = true;
89
75
  dismiss(id);
90
76
  resolve(result);
91
77
  };
92
- const run = async (which) => {
93
- if (closed || busy !== null)
94
- return;
78
+ // 「跑完关不关」归这里;转圈与锁框归 Button / ConfirmModal。把原 promise 返回给 Button 去转。
79
+ const run = (which) => {
80
+ if (closed)
81
+ return undefined;
95
82
  const out = (which === 'confirm' ? onConfirm : onCancel)?.();
96
83
  if (!isThenable(out)) {
97
84
  close(which === 'confirm');
98
- return;
99
- }
100
- busy = which;
101
- draw();
102
- try {
103
- await out;
104
- }
105
- catch (err) {
106
- // 失败:撤回 loading,框留着让人重试 / 取消;错误照常暴露出来,不吞。
107
- busy = null;
108
- draw();
109
- console.error('[dsh-plugin-core] confirmModal 回调失败,弹窗已恢复可操作:', err);
110
- return;
85
+ return undefined;
111
86
  }
112
- busy = null;
113
- close(which === 'confirm');
87
+ // reject 不关:按钮已自己恢复可点,错误由 Button 打到控制台
88
+ void out.then(() => close(which === 'confirm'), () => { });
89
+ return out;
114
90
  };
115
- entries.push(entry);
116
- draw();
91
+ entries.push({
92
+ id,
93
+ node: h(ConfirmModal, { ...core, onConfirm: () => run('confirm'), onCancel: () => run('cancel') }),
94
+ });
95
+ flush();
117
96
  });
118
97
  }
119
98
  /**
@@ -135,40 +114,28 @@ export function alertModal(opts) {
135
114
  void _skin;
136
115
  return new Promise((resolve) => {
137
116
  const id = ++idSeq;
138
- const entry = { id, node: null };
139
- let busy = false;
140
- const draw = () => {
141
- entry.node = h(AlertModal, { ...core, confirmLoading: busy, onConfirm: () => void run() });
142
- flush();
143
- };
117
+ let closed = false;
144
118
  const close = () => {
119
+ if (closed)
120
+ return;
121
+ closed = true;
145
122
  dismiss(id);
146
123
  resolve();
147
124
  };
148
- const run = async () => {
149
- if (busy)
150
- return;
125
+ // 同 confirmModal:只决定「跑完关不关」,转圈与锁框交给 Button / AlertModal。
126
+ const run = () => {
127
+ if (closed)
128
+ return undefined;
151
129
  const out = onConfirm?.();
152
130
  if (!isThenable(out)) {
153
131
  close();
154
- return;
155
- }
156
- busy = true;
157
- draw();
158
- try {
159
- await out;
160
- }
161
- catch (err) {
162
- busy = false;
163
- draw();
164
- console.error('[dsh-plugin-core] alertModal 回调失败,弹窗已恢复可操作:', err);
165
- return;
132
+ return undefined;
166
133
  }
167
- busy = false;
168
- close();
134
+ void out.then(close, () => { });
135
+ return out;
169
136
  };
170
- entries.push(entry);
171
- draw();
137
+ entries.push({ id, node: h(AlertModal, { ...core, onConfirm: () => run() }) });
138
+ flush();
172
139
  });
173
140
  }
174
141
  //# sourceMappingURL=modal-host.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"modal-host.js","sourceRoot":"","sources":["../../src/ui/modal-host.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"modal-host.js","sourceRoot":"","sources":["../../src/ui/modal-host.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** 返回值是不是 thenable。Button 的自动 loading 与命令式弹窗的收尾共用这一份判定。 */
2
+ export declare function isThenable(value: unknown): value is PromiseLike<unknown>;
3
+ //# sourceMappingURL=thenable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thenable.d.ts","sourceRoot":"","sources":["../../src/ui/thenable.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,CAGxE"}
@@ -0,0 +1,7 @@
1
+ /** 返回值是不是 thenable。Button 的自动 loading 与命令式弹窗的收尾共用这一份判定。 */
2
+ export function isThenable(value) {
3
+ if (value === null || value === undefined)
4
+ return false;
5
+ return typeof value.then === 'function';
6
+ }
7
+ //# sourceMappingURL=thenable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thenable.js","sourceRoot":"","sources":["../../src/ui/thenable.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IACvD,OAAO,OAAQ,KAA4B,CAAC,IAAI,KAAK,UAAU,CAAA;AACjE,CAAC"}
@@ -306,6 +306,10 @@ const doc: DocTopic = {
306
306
  zh: 'IconButton:variant: plain|outline|danger(默认 plain,**无底色**)、size(默认 lg)、icon(必填)、label(必填,无障碍名兼 title)、color(图标色)、background(底色,不传即无底色)。',
307
307
  en: 'IconButton: variant plain|outline|danger (default plain, **no background**), size (default lg), icon (required), label (required, doubles as a11y name and title), color (icon colour), background (fill; omitted = no fill).',
308
308
  },
309
+ {
310
+ zh: '两者的 loading 语义一致:`onClick` 返回 Promise 就转圈(纯图标钮把图标位换成小圈,`aria-label` 不变、补 `aria-busy`),`onBusyChange` 把「在跑」报出去;受控 `loading` 与它取或 —— 别处刷新也能点亮同一颗按钮。转圈期间按钮自己的图标位(`icon` / `iconRight`)全部让位,只留转圈 + 文字。',
311
+ en: 'Both share one loading semantics: a Promise-returning `onClick` spins (an icon button swaps its icon for the spinner, keeps `aria-label` and adds `aria-busy`), `onBusyChange` reports "running", and the controlled `loading` prop is OR-ed in — an external refresh lights the same button too. While spinning, the button’s own icon slots (`icon` / `iconRight`) all step aside: spinner plus label only.',
312
+ },
309
313
  {
310
314
  zh: 'Segmented:`items`(必填)支持单选 / 多选,`size`(默认 lg;三档总高 24 / 28 / 32)、`bordered`(1px 外框,总高不变)、`multiple`(多选)。外观只有一套:灰底轨道 + 白色选中片,选中片的描边环与阴影由宿主 elevation token 提供(离线兜底值没有那圈环)。选中片配色只经 `tone`:传内置色名(与 Chip 同名的 business / success / warning / danger / purple / pink / cyan / teal / orange / indigo / rose / slate)时底与字由核心定、深浅两主题各自成立;传 `{ bg, fg }` 时两个主题都用调用方这一对颜色(对比度由调用方负责)。段内 `icon` 是前置图标槽(官方图标组件 / 数组 / 自绘节点均可),`label` 也可传节点;顺序固定为 icon → label → count。只有图标(无文字 / 计数 / 角标)时该段自动变正方形(宽 = 段高),读屏名用 `ariaLabel`,缺省退回 `tooltip`。段内 `count`(弱化灰字,选中段内自动跟着选中片字色提亮)/ `badge`(红角标)接受 `number | string`:数字 ≤0 不显示,字符串原样显示(如 `1K` / `99+`)。',
311
315
  en: 'Segmented: `items` (required) supports single or multiple selection; `size` (default lg; totals 24 / 28 / 32), `bordered` (1px outer frame, same total height), `multiple` (multi-select). One look only: grey track + white selected pill; its stroke ring and shadow come from the host elevation token (the offline fallback has no ring). The selected pill’s colors go through `tone` only: a built-in color name (business / success / warning / danger / purple / pink / cyan / teal / orange / indigo / rose / slate, same names as Chip) lets the core pick background and text per theme; `{ bg, fg }` uses that pair verbatim in both themes (contrast is the caller’s call). An item’s leading `icon` takes any node (official icon component, array, or custom); `label` also accepts a node; order is always icon → label → count. With only an icon (no label / count / badge) the segment squares itself (width = segment height), and the accessible name comes from `ariaLabel`, falling back to `tooltip`. An item’s `count` (muted text; auto-lightened to follow the selected pill’s text color while selected) and `badge` (red pill) take `number | string`: numbers ≤0 render nothing, strings render as given (e.g. `\'1K\'` / `\'99+\'`).',
@@ -320,13 +324,15 @@ const doc: DocTopic = {
320
324
  { name: 'icon', type: 'ReactNode', def: '—', desc: { zh: '前置图标(官方图标组件 / 字符串均可)', en: 'Leading icon (official icon component or string)' } },
321
325
  { name: 'iconRight', type: 'ReactNode', def: '—', desc: { zh: '后置图标(展开箭头、外链)', en: 'Trailing icon (expand arrow, external link)' } },
322
326
  { name: 'color', type: 'string', def: '—', desc: { zh: '自定义主色:实心档作底色,线框 / 无底档作主色', en: 'Custom main color: background for solid tiers, main color for outline/bare' } },
323
- { name: 'loading', type: 'boolean', def: "'false'", desc: { zh: '文案前显示同色小圈,并自动 disabled', en: 'Shows a same-color spinner before the label and auto-disables' } },
327
+ { name: 'loading', type: 'boolean', def: "'false'", desc: { zh: '受控 loading:文案前显示同色小圈并自动 disabled(别处刷新也能点亮它);与「点击自动 loading」取或', en: 'Controlled loading: same-color spinner before the label plus auto-disable (an external refresh can light it up too); OR-ed with automatic click loading' } },
328
+ { name: 'onClick', type: '(...) => unknown', def: '—', desc: { zh: '**返回 Promise 即自动 loading**:转圈 + 禁用 + 防连点,settle 后自己恢复;reject 也恢复并把错误打到控制台。同步返回值 = 老行为', en: '**Returning a Promise enables loading automatically**: spinner, disabled, no double-clicks, restored on settle; a rejection also restores and logs the error. Sync return values behave as before' } },
329
+ { name: 'onBusyChange', type: '(busy: boolean) => void', def: '—', desc: { zh: '把「这个按钮正在跑」报出去(配合 `Modal` / `SideSheet` 的 `busy` 锁死关闭),不改变按钮自身行为', en: 'Reports "this button is running" outward (pair with `busy` on `Modal` / `SideSheet` to lock closing); does not change the button itself' } },
324
330
  { name: 'block', type: 'boolean', def: "'false'", desc: { zh: '撑满父宽', en: 'Fill parent width' } },
325
331
  { name: 'width', type: 'number | string', def: '—', desc: { zh: '固定宽(px 或任意 CSS 宽度);与 minWidth / maxWidth 互斥,一旦设定后两者自动失效', en: 'Fixed width (px or any CSS width); mutually exclusive with minWidth/maxWidth — once set, the other two are ignored' } },
326
332
  { name: 'minWidth', type: 'number | string', def: '—', desc: { zh: '最小宽:width 未设时生效,内容不足此宽时以它为准', en: 'Minimum width: applies only when width is unset; content shorter than this still takes this width' } },
327
333
  { name: 'maxWidth', type: 'number | string', def: '—', desc: { zh: '最大宽:width 未设时生效,文字超出折叠成省略号,hover 以跑马灯展开全名', en: 'Maximum width: applies only when width is unset; overflowing text collapses to an ellipsis and marquees on hover' } },
328
334
  { name: 'children', type: 'ReactNode', def: '—', desc: { zh: '文案(由调用方按语言给:中文出中文、英文出英文,中英混排也支持)', en: 'Label (caller supplies per locale: zh shows zh, en shows en, mixed is supported)' } },
329
- { name: '…rest', type: '原生 button 属性', def: '—', desc: { zh: 'type / disabled / title / aria-* / onClick 原样透传', en: 'type / disabled / title / aria-* / onClick passed through' } },
335
+ { name: '…rest', type: '原生 button 属性', def: '—', desc: { zh: 'type / disabled / title / aria-* 等原样透传(onClick 见上面那行)', en: 'type / disabled / title / aria-* and friends pass through (onClick is documented above)' } },
330
336
  ],
331
337
  },
332
338
  ],
@@ -785,6 +791,7 @@ const doc: DocTopic = {
785
791
  { name: 'onClose', type: '() => void', def: '—', desc: { zh: '不传则不显示关闭钮', en: 'No close button if omitted' } },
786
792
  { name: 'closeOnMask', type: 'boolean', def: "'true'", desc: { zh: '点遮罩关闭;误触代价大的场景设 false', en: 'Close on mask click; set false where mis-clicks are costly' } },
787
793
  { name: 'escClose', type: 'boolean', def: "'true'", desc: { zh: 'Esc 关闭', en: 'Close on Esc' } },
794
+ { name: 'busy', type: 'boolean', def: 'false', desc: { zh: '有异步在跑(footer 里的 `Button` 正在 loading):遮罩 / Esc / ✕ 三条关闭路径一起失效,内容照常。否决项,不替代 closeOnMask / escClose', en: 'Async work in flight (a footer `Button` is loading): mask / Esc / ✕ all stop closing while content keeps rendering. A veto, not a replacement for closeOnMask / escClose' } },
788
795
  { name: 'maxWidth', type: 'string', def: '按 size', desc: { zh: '任意 CSS 值,覆盖 size 的宽度上限;不要用 vw(遮罩已按右侧分栏让位)', en: 'Any CSS value, overriding the size’s max width; avoid vw (the mask already yielded to the right column)' } },
789
796
  { name: 'hideHeader', type: 'boolean', def: "'false'", desc: { zh: '不渲染头部(沉浸式)', en: 'Skip header (immersive)' } },
790
797
  { name: 'footer', type: 'ReactNode', def: '—', desc: { zh: '底栏(按钮区;上下内距相等、内容垂直居中)', en: 'Footer (button area; symmetric padding, vertically centred)' } },
@@ -826,6 +833,7 @@ const doc: DocTopic = {
826
833
  { name: 'onClose / closable / closeIcon', type: '() => void / boolean / ReactNode', def: '— / 跟随 onClose / ✕', desc: { zh: '关闭回调;不传则不出关闭钮', en: 'Close handler; no close button if omitted' } },
827
834
  { name: 'open', type: 'boolean', def: 'true', desc: { zh: '受控开关:传 false 时先播收起动画再卸载(想有收起效果就常驻渲染它、只切这个布尔)', en: 'Controlled flag: false plays the collapse animation before unmounting (keep it mounted and toggle this to get the exit motion)' } },
828
835
  { name: 'closeOnMask / escClose', type: 'boolean', def: "'true' / 'true'", desc: { zh: '点遮罩关闭 / Esc 关闭', en: 'Close on mask click / on Esc' } },
836
+ { name: 'busy', type: 'boolean', def: 'false', desc: { zh: '有异步在跑(footer 里的 `Button` 正在 loading):遮罩 / Esc / ✕ 三条关闭路径一起失效,内容照常。否决项,不替代 closeOnMask / escClose', en: 'Async work in flight (a footer `Button` is loading): mask / Esc / ✕ all stop closing while content keeps rendering. A veto, not a replacement for closeOnMask / escClose' } },
829
837
  { name: 'width / minWidth / maxWidth', type: 'number / number / number', def: '460 / 320 / —', desc: { zh: '初始宽度 / 拖拽下限 / 拖拽上限(px;上限缺省 = 遮罩盒宽)', en: 'Initial width / resize floor / resize ceiling (px; ceiling defaults to the mask box)' } },
830
838
  { name: 'resizable', type: 'boolean', def: 'true', desc: { zh: '能否拖宽(关掉就没有拖拽条)', en: 'Whether it resizes by dragging (off = no handle)' } },
831
839
  { name: 'footer / children', type: 'ReactNode / ReactNode', def: '— / —', desc: { zh: '底栏 / 主体(主体是唯一滚动容器)', en: 'Footer / body (the body is the only scroll container)' } },
package/docs/help/ui.md CHANGED
@@ -43,6 +43,10 @@ IconButton:variant: plain|outline|danger(默认 plain,**无底色**)、s
43
43
 
44
44
  > EN: IconButton: variant plain|outline|danger (default plain, **no background**), size (default lg), icon (required), label (required, doubles as a11y name and title), color (icon colour), background (fill; omitted = no fill).
45
45
 
46
+ 两者的 loading 语义一致:`onClick` 返回 Promise 就转圈(纯图标钮把图标位换成小圈,`aria-label` 不变、补 `aria-busy`),`onBusyChange` 把「在跑」报出去;受控 `loading` 与它取或 —— 别处刷新也能点亮同一颗按钮。转圈期间按钮自己的图标位(`icon` / `iconRight`)全部让位,只留转圈 + 文字。
47
+
48
+ > EN: Both share one loading semantics: a Promise-returning `onClick` spins (an icon button swaps its icon for the spinner, keeps `aria-label` and adds `aria-busy`), `onBusyChange` reports "running", and the controlled `loading` prop is OR-ed in — an external refresh lights the same button too. While spinning, the button’s own icon slots (`icon` / `iconRight`) all step aside: spinner plus label only.
49
+
46
50
  Segmented:`items`(必填)支持单选 / 多选,`size`(默认 lg;三档总高 24 / 28 / 32)、`bordered`(1px 外框,总高不变)、`multiple`(多选)。外观只有一套:灰底轨道 + 白色选中片,选中片的描边环与阴影由宿主 elevation token 提供(离线兜底值没有那圈环)。选中片配色只经 `tone`:传内置色名(与 Chip 同名的 business / success / warning / danger / purple / pink / cyan / teal / orange / indigo / rose / slate)时底与字由核心定、深浅两主题各自成立;传 `{ bg, fg }` 时两个主题都用调用方这一对颜色(对比度由调用方负责)。段内 `icon` 是前置图标槽(官方图标组件 / 数组 / 自绘节点均可),`label` 也可传节点;顺序固定为 icon → label → count。只有图标(无文字 / 计数 / 角标)时该段自动变正方形(宽 = 段高),读屏名用 `ariaLabel`,缺省退回 `tooltip`。段内 `count`(弱化灰字,选中段内自动跟着选中片字色提亮)/ `badge`(红角标)接受 `number | string`:数字 ≤0 不显示,字符串原样显示(如 `1K` / `99+`)。
47
51
 
48
52
  > EN: Segmented: `items` (required) supports single or multiple selection; `size` (default lg; totals 24 / 28 / 32), `bordered` (1px outer frame, same total height), `multiple` (multi-select). One look only: grey track + white selected pill; its stroke ring and shadow come from the host elevation token (the offline fallback has no ring). The selected pill’s colors go through `tone` only: a built-in color name (business / success / warning / danger / purple / pink / cyan / teal / orange / indigo / rose / slate, same names as Chip) lets the core pick background and text per theme; `{ bg, fg }` uses that pair verbatim in both themes (contrast is the caller’s call). An item’s leading `icon` takes any node (official icon component, array, or custom); `label` also accepts a node; order is always icon → label → count. With only an icon (no label / count / badge) the segment squares itself (width = segment height), and the accessible name comes from `ariaLabel`, falling back to `tooltip`. An item’s `count` (muted text; auto-lightened to follow the selected pill’s text color while selected) and `badge` (red pill) take `number | string`: numbers ≤0 render nothing, strings render as given (e.g. `'1K'` / `'99+'`).
@@ -54,13 +58,15 @@ Segmented:`items`(必填)支持单选 / 多选,`size`(默认 lg;三
54
58
  | `icon` | `ReactNode` | — | 前置图标(官方图标组件 / 字符串均可) | Leading icon (official icon component or string) |
55
59
  | `iconRight` | `ReactNode` | — | 后置图标(展开箭头、外链) | Trailing icon (expand arrow, external link) |
56
60
  | `color` | `string` | — | 自定义主色:实心档作底色,线框 / 无底档作主色 | Custom main color: background for solid tiers, main color for outline/bare |
57
- | `loading` | `boolean` | 'false' | 文案前显示同色小圈,并自动 disabled | Shows a same-color spinner before the label and auto-disables |
61
+ | `loading` | `boolean` | 'false' | 受控 loading:文案前显示同色小圈并自动 disabled(别处刷新也能点亮它);与「点击自动 loading」取或 | Controlled loading: same-color spinner before the label plus auto-disable (an external refresh can light it up too); OR-ed with automatic click loading |
62
+ | `onClick` | `(...) => unknown` | — | **返回 Promise 即自动 loading**:转圈 + 禁用 + 防连点,settle 后自己恢复;reject 也恢复并把错误打到控制台。同步返回值 = 老行为 | **Returning a Promise enables loading automatically**: spinner, disabled, no double-clicks, restored on settle; a rejection also restores and logs the error. Sync return values behave as before |
63
+ | `onBusyChange` | `(busy: boolean) => void` | — | 把「这个按钮正在跑」报出去(配合 `Modal` / `SideSheet` 的 `busy` 锁死关闭),不改变按钮自身行为 | Reports "this button is running" outward (pair with `busy` on `Modal` / `SideSheet` to lock closing); does not change the button itself |
58
64
  | `block` | `boolean` | 'false' | 撑满父宽 | Fill parent width |
59
65
  | `width` | `number \| string` | — | 固定宽(px 或任意 CSS 宽度);与 minWidth / maxWidth 互斥,一旦设定后两者自动失效 | Fixed width (px or any CSS width); mutually exclusive with minWidth/maxWidth — once set, the other two are ignored |
60
66
  | `minWidth` | `number \| string` | — | 最小宽:width 未设时生效,内容不足此宽时以它为准 | Minimum width: applies only when width is unset; content shorter than this still takes this width |
61
67
  | `maxWidth` | `number \| string` | — | 最大宽:width 未设时生效,文字超出折叠成省略号,hover 以跑马灯展开全名 | Maximum width: applies only when width is unset; overflowing text collapses to an ellipsis and marquees on hover |
62
68
  | `children` | `ReactNode` | — | 文案(由调用方按语言给:中文出中文、英文出英文,中英混排也支持) | Label (caller supplies per locale: zh shows zh, en shows en, mixed is supported) |
63
- | `…rest` | `原生 button 属性` | — | type / disabled / title / aria-* / onClick 原样透传 | type / disabled / title / aria-* / onClick passed through |
69
+ | `…rest` | `原生 button 属性` | — | type / disabled / title / aria-* 等原样透传(onClick 见上面那行) | type / disabled / title / aria-* and friends pass through (onClick is documented above) |
64
70
 
65
71
  ## Input 家族(Field.ts)
66
72
 
@@ -657,6 +663,7 @@ Modal 是自绘 overlay,不走 react-dom portal。
657
663
  | `onClose` | `() => void` | — | 不传则不显示关闭钮 | No close button if omitted |
658
664
  | `closeOnMask` | `boolean` | 'true' | 点遮罩关闭;误触代价大的场景设 false | Close on mask click; set false where mis-clicks are costly |
659
665
  | `escClose` | `boolean` | 'true' | Esc 关闭 | Close on Esc |
666
+ | `busy` | `boolean` | false | 有异步在跑(footer 里的 `Button` 正在 loading):遮罩 / Esc / ✕ 三条关闭路径一起失效,内容照常。否决项,不替代 closeOnMask / escClose | Async work in flight (a footer `Button` is loading): mask / Esc / ✕ all stop closing while content keeps rendering. A veto, not a replacement for closeOnMask / escClose |
660
667
  | `maxWidth` | `string` | 按 size | 任意 CSS 值,覆盖 size 的宽度上限;不要用 vw(遮罩已按右侧分栏让位) | Any CSS value, overriding the size’s max width; avoid vw (the mask already yielded to the right column) |
661
668
  | `hideHeader` | `boolean` | 'false' | 不渲染头部(沉浸式) | Skip header (immersive) |
662
669
  | `footer` | `ReactNode` | — | 底栏(按钮区;上下内距相等、内容垂直居中) | Footer (button area; symmetric padding, vertically centred) |
@@ -692,6 +699,7 @@ Modal 是自绘 overlay,不走 react-dom portal。
692
699
  | `onClose / closable / closeIcon` | `() => void / boolean / ReactNode` | — / 跟随 onClose / ✕ | 关闭回调;不传则不出关闭钮 | Close handler; no close button if omitted |
693
700
  | `open` | `boolean` | true | 受控开关:传 false 时先播收起动画再卸载(想有收起效果就常驻渲染它、只切这个布尔) | Controlled flag: false plays the collapse animation before unmounting (keep it mounted and toggle this to get the exit motion) |
694
701
  | `closeOnMask / escClose` | `boolean` | 'true' / 'true' | 点遮罩关闭 / Esc 关闭 | Close on mask click / on Esc |
702
+ | `busy` | `boolean` | false | 有异步在跑(footer 里的 `Button` 正在 loading):遮罩 / Esc / ✕ 三条关闭路径一起失效,内容照常。否决项,不替代 closeOnMask / escClose | Async work in flight (a footer `Button` is loading): mask / Esc / ✕ all stop closing while content keeps rendering. A veto, not a replacement for closeOnMask / escClose |
695
703
  | `width / minWidth / maxWidth` | `number / number / number` | 460 / 320 / — | 初始宽度 / 拖拽下限 / 拖拽上限(px;上限缺省 = 遮罩盒宽) | Initial width / resize floor / resize ceiling (px; ceiling defaults to the mask box) |
696
704
  | `resizable` | `boolean` | true | 能否拖宽(关掉就没有拖拽条) | Whether it resizes by dragging (off = no handle) |
697
705
  | `footer / children` | `ReactNode / ReactNode` | — / — | 底栏 / 主体(主体是唯一滚动容器) | Footer / body (the body is the only scroll container) |
@@ -109,6 +109,12 @@ dsh-plugin-core/
109
109
  几何画在 24×24 viewBox 内等比缩放;颜色走 `currentColor`;默认 `aria-hidden`,传 `label` 才播报。
110
110
  新形态加在库里(枚举 + 一段 CSS),不在插件里另造转圈。Button 的 loading 与 `LoadingToast` /
111
111
  `LoadingBlock` 的转圈改为复用它(环的画法与 keyframes 只剩 `controls/loader.css` 一份)。
112
+ - 按钮与弹窗的 loading **只有一套**(2026-11-03 用户拍板,推翻「alert/confirm 单独一套」):
113
+ `Button` / `IconButton` 的 `onClick` 返回 Promise 即自动转圈禁用、settle 后恢复(reject 也恢复并打错),
114
+ 受控 `loading` 与之取或(**别处刷新也能点亮同一颗按钮**);`onBusyChange` 把「在跑」报出去。
115
+ `Modal` / `SideSheet` 只认 `busy`(遮罩 / Esc / ✕ 一并失效,footer 皮肤各弹窗自管),
116
+ `ConfirmModal` / `AlertModal` 退化成薄壳,命令式 `confirmModal` / `alertModal` 只负责「跑完关不关」。
117
+ 转圈期间按钮自己的 `icon` / `iconRight` 一律让位,只留转圈(+ 文字)。内测期不设兼容层。
112
118
  - `Loading` 是旧的「自带定位 + 自带 pill 背景」复合件,**保留不删**但标 `@deprecated`,新代码用 `Loader`。
113
119
  - 布局基础:`PanelDock` / `DockPanel` / `createPanelDock`(**可停靠分栏容器**:多面板并存、按组名寻址、拖拽拉栏、宽度记忆;2026-10-20 拍板用此名,替代早先的 `SidebarLayout` / `SplitPane`)。只做右侧;组名与窗口一对一;默认上限 3,超限拒绝新开;不做 tab 切换 / 自动淘汰 / 多份同名;**面板本身始终是布局成员,不做面板浮层**(2026-10-28 补:**收起** = 面板退出布局、另出右侧一只独立的 `position: fixed` 耳朵,点耳朵展开并还原宽度;关闭不留耳朵——耳朵是独立浮层,不是把面板变浮层)。**结构照成熟库口径写 children,`open/close` 只传 id,不把页面树塞进调用参数**
114
120
  - 浮动快捷工具栏:`QuickToolbar`(2026-10-31 用户拍板):右侧一列独立圆钮,纵向**恒贴屏幕底边**(默认 16px);横向默认贴屏幕右缘,传 `anchorId` / `anchor()` 时贴到指定控件右缘外侧,右侧放不下则退回屏幕右缘(控件找不到按跟随窗口处理)。内置回顶部默认 `when:'scroll'`、阈值 320,`backToTop:false` 可关掉,对象可调 `order` / `label` / `threshold`;自定义项 `items` 支持 `icon` / `label` / `onClick` / `visible` / `when` / `order` / `threshold` / `color` / `fgColor`,统一 `onAction`。旧的 `BackToTop` **全部删除**,只保留这一份,不做迁移。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-core",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "packageManager": "pnpm@12.3.4",
5
5
  "description": "Shared base for DSH plugins: design tokens, UI controls, utils, workspace explorer, session preview",
6
6
  "keywords": [