@dazhicheng/ui 1.6.19 → 1.6.21

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 (49) hide show
  1. package/dist/components/tt-form/index.d.ts +2 -2
  2. package/dist/components/tt-form/src/formApi.d.ts +11 -2
  3. package/dist/components/tt-form/src/group-form/LazyFormField.vue.js +162 -114
  4. package/dist/components/tt-form/src/group-form/groupFormApi.js +0 -6
  5. package/dist/components/tt-form/src/group-form/lazyContext.d.ts +18 -0
  6. package/dist/components/tt-form/src/group-form/lazyContext.js +64 -36
  7. package/dist/components/tt-form/src/group-form/types.d.ts +39 -6
  8. package/dist/components/tt-form/src/group-form/useGroupForm.d.ts +7 -5
  9. package/dist/components/tt-form/src/types.d.ts +58 -26
  10. package/dist/components/tt-form/src/useForm.d.ts +1 -1
  11. package/dist/components/tt-form/src/useForm.js +5 -5
  12. package/dist/components/tt-modal/index.d.ts +1 -0
  13. package/dist/components/tt-modal/index.js +8 -3
  14. package/dist/components/tt-modal/src/RenderModal.vue.js +224 -210
  15. package/dist/components/tt-modal/src/hooks/useModalRender.js +66 -67
  16. package/dist/components/tt-modal/src/index.js +9 -7
  17. package/dist/components/tt-modal/src/utils/modal-api.d.ts +9 -3
  18. package/dist/components/tt-modal/src/utils/modal-api.js +42 -36
  19. package/dist/components/tt-modal/src/utils/modal-close-transition.d.ts +13 -0
  20. package/dist/components/tt-modal/src/utils/modal-close-transition.js +13 -0
  21. package/dist/components/tt-modal/src/utils/modal-host-app.d.ts +5 -0
  22. package/dist/components/tt-modal/src/utils/modal-host-app.js +12 -0
  23. package/dist/components/tt-modal/src/utils/modal-scope.d.ts +21 -0
  24. package/dist/components/tt-modal/src/utils/modal-scope.js +20 -0
  25. package/dist/components/tt-modal/src/utils/modal-service.d.ts +23 -0
  26. package/dist/components/tt-modal/src/utils/modal-service.js +51 -0
  27. package/dist/components/tt-modal/src/utils/modal-stack.d.ts +14 -13
  28. package/dist/components/tt-modal/src/utils/modal-stack.js +20 -9
  29. package/dist/components/tt-modal/src/utils/modal-z-index.d.ts +15 -0
  30. package/dist/components/tt-modal/src/utils/modal-z-index.js +24 -0
  31. package/dist/components/tt-modal/src/utils/resolve-modal-target.d.ts +14 -0
  32. package/dist/components/tt-modal/src/utils/resolve-modal-target.js +83 -47
  33. package/dist/components/tt-modal-form/props.d.ts +9 -4
  34. package/dist/components/tt-modal-form/useModalForm.d.ts +1 -1
  35. package/dist/components/tt-table/index.d.ts +15 -0
  36. package/dist/components/tt-table/src/Table.vue.d.ts +9 -0
  37. package/dist/components/tt-table/src/Table.vue.js +240 -242
  38. package/dist/components/tt-table/src/TableForm.vue.d.ts +7 -5
  39. package/dist/components/tt-table/src/TableForm.vue.js +199 -180
  40. package/dist/components/tt-table/src/hooks/usePagination.d.ts +1 -1
  41. package/dist/components/tt-table/src/hooks/usePagination.js +38 -24
  42. package/dist/components/tt-table/src/hooks/useTableRender.d.ts +4 -4
  43. package/dist/components/tt-table/src/props.d.ts +6 -0
  44. package/dist/components/tt-table/src/props.js +5 -0
  45. package/dist/components/tt-table/src/types/table.d.ts +8 -0
  46. package/dist/components/tt-table/src/types/tableForm.d.ts +29 -14
  47. package/dist/components/tt-table/src/utils/table-form-api.d.ts +11 -11
  48. package/dist/index.js +132 -127
  49. package/package.json +1 -1
@@ -9,8 +9,8 @@ export { COMPONENT_MAP, useForm };
9
9
  export type { FormApi } from './src/formApi';
10
10
  type TtFormSchema<TValues extends Record<string, any> = Record<string, any>> = FormSchema<TValues>;
11
11
  type TtFormRenderProps<TValues extends Record<string, any> = Record<string, any>> = FormRenderProps<TValues>;
12
- type TtExtendedFormApi = ExtendedFormApi;
13
- export type { ArraySchemaContext, BaseFormComponentMap, BaseFormComponentType, ComponentProps, FormArrayActions, FormItemDependenciesCondition, FormItemDependenciesConditionWithProps, FormItemDependenciesConditionWithRules, FormSlotSchema, InferredComponentPropsType, NestedArrayHandle, RenderComponentContentType, } from './src/types';
12
+ type TtExtendedFormApi<TValues extends Record<string, any> = Record<string, any>> = ExtendedFormApi<TValues>;
13
+ export type { ArraySchemaContext, BaseFormComponentMap, BaseFormComponentType, ComponentProps, FormArrayActions, FormItemDependencies, FormItemDependenciesCondition, FormItemDependenciesConditionWithProps, FormItemDependenciesConditionWithRules, FormSlotSchema, FormValuesInput, InferredComponentPropsType, NestedArrayHandle, RenderComponentContentType, } from './src/types';
14
14
  export type { FieldArrayContext, FieldEntry, ReadonlyFieldEntry, ResolvedFieldArrayContext } from './src/types/forms';
15
15
  export type { TtExtendedFormApi, TtFormProps, TtFormRenderProps, TtFormSchema };
16
16
  export * as z from 'zod';
@@ -1,7 +1,7 @@
1
1
  import { FormState, GenericObject, ResetFormOpts, ValidationOptions } from 'vee-validate';
2
- import { ComponentPublicInstance } from 'vue';
2
+ import { ComponentPublicInstance, Ref } from 'vue';
3
3
  import { Recordable, StateHandler } from '../../../../../utils/src';
4
- import { FormActions, FormArrayActions, FormSchema, NestedArrayHandle, TtFormProps } from './types';
4
+ import { FormActions, FormArrayActions, FormSchema, NestedArrayHandle, NoInfer, TtFormProps } from './types';
5
5
  import { FieldArrayContext, ResolvedFieldArrayContext } from './types/forms';
6
6
  import { Store } from './shared/store';
7
7
  export type { ArrayPathSegment } from './utils/array-path';
@@ -9,6 +9,15 @@ export { buildArrayFieldPath, collectArrayFieldPathAliases, normalizeArrayFieldP
9
9
  export declare class FormApi {
10
10
  form: FormActions;
11
11
  isMounted: boolean;
12
+ /**
13
+ * 订阅 store 状态,由 `useForm` / `useGroupForm` 在创建 api 时挂载。
14
+ *
15
+ * 声明在类上是为了让实例本身满足对外的 `ExtendedFormApi`:schema 回调收到的就是这个实例,
16
+ * 回调签名里写的是对外类型,缺了这一项两边就对不上,只能靠 as 强转补。
17
+ * 用 `declare` 而不是 `useStore!`:后者在 `useDefineForClassFields` 下会真的产出一个
18
+ * 值为 undefined 的实例字段,这里只需要类型声明,不能改运行时的对象形状。
19
+ */
20
+ useStore: <T = NoInfer<TtFormProps>>(selector?: (state: NoInfer<TtFormProps>) => T) => Readonly<Ref<T>>;
12
21
  state: null | TtFormProps;
13
22
  stateHandler: StateHandler;
14
23
  store: Store<TtFormProps>;
@@ -1,12 +1,12 @@
1
- import { defineComponent as K, unref as i, inject as O, computed as G, ref as E, watch as S, useTemplateRef as J, shallowRef as Q, onMounted as W, onBeforeUnmount as X, createElementBlock as q, openBlock as h, normalizeClass as p, createBlock as T, createCommentVNode as Z, mergeProps as ee, withCtx as V, renderSlot as te, normalizeProps as oe, guardReactiveProps as ne, normalizeStyle as x, createElementVNode as re, createVNode as N, nextTick as le } from "vue";
2
- import { ElSkeleton as ie, ElSkeletonItem as z } from "element-plus";
1
+ import { defineComponent as ie, unref as l, inject as le, computed as se, ref as A, watch as H, useTemplateRef as ue, shallowRef as ae, onMounted as fe, onBeforeUnmount as ce, createElementBlock as I, openBlock as w, normalizeClass as y, createBlock as D, createCommentVNode as me, mergeProps as de, withCtx as Y, renderSlot as pe, normalizeProps as ve, guardReactiveProps as ge, normalizeStyle as q, createElementVNode as he, createVNode as j, nextTick as ye } from "vue";
2
+ import { ElSkeleton as Re, ElSkeletonItem as K } from "element-plus";
3
3
  import "../../../../node_modules/.pnpm/vue-types@5.1.3_vue@3.5.21_typescript@5.9.3_/node_modules/vue-types/shim/index.modern.js";
4
- import { useDesign as se } from "../../../../packages/hooks/src/useDesign.js";
4
+ import { useDesign as ke } from "../../../../packages/hooks/src/useDesign.js";
5
5
  import "axios";
6
- import { isFunction as ae, isBoolean as ue } from "../../../../packages/utils/src/is.js";
6
+ import { isFunction as we, isBoolean as _e } from "../../../../packages/utils/src/is.js";
7
7
  import "dayjs";
8
8
  import "numeral";
9
- import { clnm as fe } from "../../../../packages/utils/src/tool.js";
9
+ import { clnm as Ce } from "../../../../packages/utils/src/tool.js";
10
10
  import "../../../../node_modules/.pnpm/decimal.js@10.6.0/node_modules/decimal.js/decimal.js";
11
11
  import "../../../../node_modules/.pnpm/crypto-js@4.2.0/node_modules/crypto-js/aes.js";
12
12
  import "../../../../node_modules/.pnpm/crypto-js@4.2.0/node_modules/crypto-js/enc-utf8.js";
@@ -14,12 +14,12 @@ import "../../../../node_modules/.pnpm/crypto-js@4.2.0/node_modules/crypto-js/mo
14
14
  import "../../../../node_modules/.pnpm/crypto-js@4.2.0/node_modules/crypto-js/pad-pkcs7.js";
15
15
  import "lodash-es";
16
16
  import "vue-router";
17
- import { useFormValues as ce } from "vee-validate";
18
- import me from "../form-render/FormField.vue2.js";
19
- import { injectFormProps as de } from "../useFormContext.js";
20
- import { RENDER_SCHEDULER_KEY as pe } from "./lazyContext.js";
21
- import { resolveValueByFieldName as ve } from "../form-render/dependencies.js";
22
- const ge = ["data-field-anchor"], ze = /* @__PURE__ */ K({
17
+ import { useFormValues as Ee } from "vee-validate";
18
+ import Me from "../form-render/FormField.vue2.js";
19
+ import { injectFormProps as Fe } from "../useFormContext.js";
20
+ import { RENDER_SCHEDULER_KEY as Be, nextFrame as g } from "./lazyContext.js";
21
+ import { resolveValueByFieldName as Pe } from "../form-render/dependencies.js";
22
+ const He = ["data-field-anchor"], We = /* @__PURE__ */ ie({
23
23
  name: "LazyFormField",
24
24
  inheritAttrs: !1,
25
25
  __name: "LazyFormField",
@@ -34,162 +34,210 @@ const ge = ["data-field-anchor"], ze = /* @__PURE__ */ K({
34
34
  skeleton: { type: Boolean, default: !0 },
35
35
  skeletonAnimated: { type: Boolean, default: !0 }
36
36
  },
37
- setup(L) {
38
- const { prefixCls: u } = se("lazy-form-field"), a = L, [I] = de(), b = i(I).formApi, D = a.fieldProps.fieldName, n = O(pe, void 0), R = ce(), C = G(() => a.fieldProps.dependencies), l = E(!0);
39
- let v = 0;
40
- S(
37
+ setup(O) {
38
+ const { prefixCls: c } = ke("lazy-form-field"), f = O, [U] = Fe(), G = l(U).formApi, J = f.fieldProps.fieldName, n = le(Be, void 0), b = Ee(), L = se(() => f.fieldProps.dependencies), o = A(!0);
39
+ let R = 0;
40
+ H(
41
41
  () => {
42
- var o;
43
- const e = C.value;
44
- if ((o = e == null ? void 0 : e.triggerFields) != null && o.length)
45
- return e.triggerFields.map((t) => ve(R.value, t));
42
+ var t;
43
+ const e = L.value;
44
+ if ((t = e == null ? void 0 : e.triggerFields) != null && t.length)
45
+ return e.triggerFields.map((r) => Pe(b.value, r));
46
46
  },
47
47
  async () => {
48
- const e = ++v, o = C.value;
49
- if (!o || o.if === void 0) {
50
- if (e !== v) return;
51
- l.value = !0;
48
+ const e = ++R, t = L.value;
49
+ if (!t || t.if === void 0) {
50
+ if (e !== R) return;
51
+ o.value = !0;
52
52
  return;
53
53
  }
54
- if (ae(o.if)) {
55
- const t = !!await o.if(R.value, b);
56
- if (e !== v) return;
57
- l.value = t;
58
- } else if (ue(o.if)) {
59
- if (e !== v) return;
60
- l.value = o.if;
54
+ if (we(t.if)) {
55
+ const r = !!await t.if(b.value, G);
56
+ if (e !== R) return;
57
+ o.value = r;
58
+ } else if (_e(t.if)) {
59
+ if (e !== R) return;
60
+ o.value = t.if;
61
61
  }
62
62
  },
63
63
  { deep: !0, immediate: !0 }
64
64
  );
65
- const s = J("containerRef"), f = E(!1);
65
+ const s = ue("containerRef"), u = A(!1);
66
66
  let m = !1;
67
- const H = `${u}--offscreen`, M = Q(a.estimateHeight);
68
- let c = null, r = null, y = null;
69
- function w(e) {
70
- let o = e.parentElement;
71
- for (; o; ) {
72
- const t = getComputedStyle(o).overflowY;
73
- if (t === "auto" || t === "scroll") return o;
74
- o = o.parentElement;
67
+ const T = `${c}--offscreen`, V = ae(f.estimateHeight);
68
+ let p = null, i = null, h = null, a = null, _ = [], d = null;
69
+ function $(e) {
70
+ let t = e.parentElement;
71
+ for (; t; ) {
72
+ const r = getComputedStyle(t).overflowY;
73
+ if (r === "auto" || r === "scroll") return t;
74
+ t = t.parentElement;
75
75
  }
76
76
  return null;
77
77
  }
78
- function k() {
78
+ function C() {
79
79
  const e = s.value;
80
- if (!e || f.value) return;
81
- const o = e.offsetHeight;
82
- e.style.height = `${o}px`, e.style.overflow = "hidden", f.value = !0, le(() => {
83
- requestAnimationFrame(() => {
84
- const t = s.value;
85
- if (!t) return;
86
- const B = t.scrollHeight - o;
87
- t.style.height = "", t.style.overflow = "", !(Math.abs(B) <= 2) && requestAnimationFrame(() => {
88
- const _ = s.value;
89
- if (!_) return;
90
- const P = y ?? w(_);
80
+ if (!e || u.value) return;
81
+ const t = e.offsetHeight;
82
+ e.style.height = `${t}px`, e.style.overflow = "hidden", u.value = !0, ye(() => {
83
+ g(() => {
84
+ const r = s.value;
85
+ if (!r) return;
86
+ const N = r.scrollHeight - t;
87
+ r.style.height = "", r.style.overflow = "", !(Math.abs(N) <= 2) && g(() => {
88
+ const B = s.value;
89
+ if (!B) return;
90
+ const P = h ?? $(B);
91
91
  if (!P) return;
92
- const U = _.getBoundingClientRect().top, Y = P.getBoundingClientRect().top;
93
- U < Y && (P.scrollTop += B);
92
+ const ne = B.getBoundingClientRect().top, oe = P.getBoundingClientRect().top;
93
+ ne < oe && (P.scrollTop += N);
94
94
  });
95
95
  });
96
96
  });
97
97
  }
98
- let F = !1, g = !1;
99
- function A() {
100
- r = null, l.value && (F = !0, n == null || n.trackMount(), k());
98
+ let E = !1, k = !1;
99
+ function S() {
100
+ i = null, o.value && (E = !0, n == null || n.trackMount(), C());
101
101
  }
102
- function $() {
103
- f.value || r || !l.value || (r = n ? n.request(A) : (() => {
104
- const e = requestAnimationFrame(A);
105
- return () => cancelAnimationFrame(e);
106
- })());
102
+ function x() {
103
+ u.value || i || !o.value || (i = n ? n.request(S) : g(S));
107
104
  }
108
- function j() {
109
- !a.progressive || g || !F || (g = !0, n == null || n.settleMount());
105
+ function Q() {
106
+ !f.progressive || k || !E || (k = !0, n == null || n.settleMount());
110
107
  }
111
- return S(l, (e) => {
112
- a.progressive && e && $();
113
- }), W(() => {
108
+ function M() {
109
+ u.value || i || !m || !o.value || (i = n ? n.request(() => {
110
+ i = null, !(!m || !o.value) && C();
111
+ }) : g(() => {
112
+ i = null, !(!m || !o.value) && C();
113
+ }));
114
+ }
115
+ function W() {
116
+ const e = String(f.rootMargin).trim().split(/\s+/)[0] ?? "", t = Number.parseFloat(e);
117
+ return Number.isFinite(t) ? t : 0;
118
+ }
119
+ function X() {
120
+ const e = s.value;
121
+ if (!(e != null && e.isConnected)) return !1;
122
+ const t = e.getBoundingClientRect();
123
+ if (t.width === 0 || t.height === 0) return !1;
124
+ const r = W();
125
+ if (h) {
126
+ const v = h.getBoundingClientRect();
127
+ return t.bottom > v.top - r && t.top < v.bottom + r;
128
+ }
129
+ return t.bottom > -r && t.top < window.innerHeight + r;
130
+ }
131
+ function F() {
132
+ u.value || !o.value || !X() || (m = !0, M());
133
+ }
134
+ function Z() {
135
+ if (a) return;
136
+ if (n) {
137
+ a = n.registerVisibilityCheck(F);
138
+ return;
139
+ }
140
+ const e = () => {
141
+ d || (d = g(() => {
142
+ d = null, F();
143
+ }));
144
+ };
145
+ document.addEventListener("scroll", e, { capture: !0, passive: !0 }), window.addEventListener("resize", e, { passive: !0 }), a = () => {
146
+ document.removeEventListener("scroll", e, { capture: !0 }), window.removeEventListener("resize", e), d == null || d(), d = null, a = null;
147
+ };
148
+ }
149
+ const ee = [300, 800, 1600, 3200];
150
+ function te() {
151
+ for (const e of ee)
152
+ _.push(
153
+ setTimeout(() => {
154
+ u.value || F();
155
+ }, e)
156
+ );
157
+ }
158
+ function z() {
159
+ _.forEach(clearTimeout), _ = [];
160
+ }
161
+ function re() {
162
+ u.value || (Z(), te());
163
+ }
164
+ return H(u, (e) => {
165
+ e && (a == null || a(), z());
166
+ }), H(o, (e) => {
167
+ e && (f.progressive ? x() : M());
168
+ }), fe(() => {
114
169
  if (s.value) {
115
- if (y = w(s.value), a.progressive) {
116
- $();
170
+ if (h = $(s.value), f.progressive) {
171
+ x();
117
172
  return;
118
173
  }
119
- c = new IntersectionObserver(
174
+ p = new IntersectionObserver(
120
175
  (e) => {
121
- const o = e[0];
122
- if (o)
123
- if (o.isIntersecting) {
176
+ const t = e[0];
177
+ if (t)
178
+ if (t.isIntersecting) {
124
179
  m = !0;
125
- const t = s.value;
126
- t && (t.style.minHeight = "", t.classList.remove(H)), !f.value && !r && l.value && (r = n ? n.request(() => {
127
- r = null, !(!m || !l.value) && k();
128
- }) : (() => {
129
- const d = requestAnimationFrame(() => {
130
- r = null, !(!m || !l.value) && k();
131
- });
132
- return () => cancelAnimationFrame(d);
133
- })());
180
+ const r = s.value;
181
+ r && (r.style.minHeight = "", r.classList.remove(T)), M();
134
182
  } else
135
- m = !1, f.value && s.value && requestAnimationFrame(() => {
183
+ m = !1, u.value && s.value && g(() => {
136
184
  if (m) return;
137
- const t = s.value;
138
- if (!(t != null && t.isConnected)) return;
139
- const d = t.offsetHeight;
140
- d !== 0 && (t.style.minHeight = `${d}px`, t.classList.add(H));
141
- }), r && (r(), r = null);
185
+ const r = s.value;
186
+ if (!(r != null && r.isConnected)) return;
187
+ const v = r.offsetHeight;
188
+ v !== 0 && (r.style.minHeight = `${v}px`, r.classList.add(T));
189
+ }), i && (i(), i = null);
142
190
  },
143
191
  {
144
- root: y,
145
- rootMargin: a.rootMargin
192
+ root: h,
193
+ rootMargin: f.rootMargin
146
194
  }
147
- ), c.observe(s.value);
195
+ ), p.observe(s.value), re();
148
196
  }
149
- }), X(() => {
150
- r && (r(), r = null), a.progressive && F && !g && (g = !0, n == null || n.settleMount()), c == null || c.disconnect(), c = null;
151
- }), (e, o) => (h(), q("div", {
197
+ }), ce(() => {
198
+ a == null || a(), z(), i && (i(), i = null), f.progressive && E && !k && (k = !0, n == null || n.settleMount()), p == null || p.disconnect(), p = null;
199
+ }), (e, t) => (w(), I("div", {
152
200
  ref_key: "containerRef",
153
201
  ref: s,
154
- "data-field-anchor": i(D),
155
- class: p(i(fe)(i(u), e.fieldClass, { [`${i(u)}--hidden`]: !l.value }))
202
+ "data-field-anchor": l(J),
203
+ class: y(l(Ce)(l(c), e.fieldClass, { [`${l(c)}--hidden`]: !o.value }))
156
204
  }, [
157
- f.value ? (h(), T(me, ee({ key: 0 }, e.fieldProps, {
205
+ u.value ? (w(), D(Me, de({ key: 0 }, e.fieldProps, {
158
206
  rules: e.rules,
159
- onVnodeMounted: j
207
+ onVnodeMounted: Q
160
208
  }), {
161
- default: V((t) => [
162
- te(e.$slots, "default", oe(ne(t)))
209
+ default: Y((r) => [
210
+ pe(e.$slots, "default", ve(ge(r)))
163
211
  ]),
164
212
  _: 3
165
- }, 16, ["rules"])) : e.skeleton && l.value ? (h(), T(i(ie), {
213
+ }, 16, ["rules"])) : e.skeleton && o.value ? (w(), D(l(Re), {
166
214
  key: 1,
167
215
  animated: e.skeletonAnimated,
168
- class: p(`${i(u)}__skeleton`),
169
- style: x({ minHeight: `${M.value}px` })
216
+ class: y(`${l(c)}__skeleton`),
217
+ style: q({ minHeight: `${V.value}px` })
170
218
  }, {
171
- template: V(() => [
172
- re("div", {
173
- class: p(`${i(u)}__row`)
219
+ template: Y(() => [
220
+ he("div", {
221
+ class: y(`${l(c)}__row`)
174
222
  }, [
175
- N(i(z), {
223
+ j(l(K), {
176
224
  variant: "text",
177
- class: p(`${i(u)}__label`)
225
+ class: y(`${l(c)}__label`)
178
226
  }, null, 8, ["class"]),
179
- N(i(z), {
227
+ j(l(K), {
180
228
  variant: "rect",
181
- class: p(`${i(u)}__control`)
229
+ class: y(`${l(c)}__control`)
182
230
  }, null, 8, ["class"])
183
231
  ], 2)
184
232
  ]),
185
233
  _: 1
186
- }, 8, ["animated", "class", "style"])) : l.value ? (h(), q("div", {
234
+ }, 8, ["animated", "class", "style"])) : o.value ? (w(), I("div", {
187
235
  key: 2,
188
- style: x({ height: `${M.value}px` })
189
- }, null, 4)) : Z("", !0)
190
- ], 10, ge));
236
+ style: q({ height: `${V.value}px` })
237
+ }, null, 4)) : me("", !0)
238
+ ], 10, He));
191
239
  }
192
240
  });
193
241
  export {
194
- ze as default
242
+ We as default
195
243
  };
@@ -96,12 +96,6 @@ class ye extends j {
96
96
  l(this, "_navSyncLoopWarned", !1);
97
97
  /** VirtualGroupForm 组件实例引用,由 useGroupForm 的 h() 渲染时赋值 */
98
98
  l(this, "groupFormRef", T(null));
99
- /**
100
- * @description 响应式读取 store 状态,由 useGroupForm 在运行时注入实现
101
- * @param {Function} [selector] - 可选的状态选择器
102
- * @returns {Readonly<Ref<T>>} 响应式状态引用
103
- */
104
- l(this, "useStore");
105
99
  const {
106
100
  groupSchema: s,
107
101
  virtual: r = !0,
@@ -29,7 +29,25 @@ export interface RenderScheduler {
29
29
  * @returns {Promise<void>}
30
30
  */
31
31
  whenAllSettled: () => Promise<void>;
32
+ /**
33
+ * @description 注册「兜底可见性检查」回调,由调度器用共享的 scroll / resize 监听统一驱动。
34
+ * 微前端 iframe 沙箱下 IntersectionObserver 只在初始观测一次,之后滚动不再上报,需要主动测量补齐;
35
+ * 若每个字段各自绑定监听,长表单会产生大量重复监听与重复几何读取,故在此集中为一份监听 + 一次节流帧。
36
+ * @param {() => void} check - 字段的可见性检查回调(内部自行判断是否已挂载)
37
+ * @returns {() => void} 注销函数
38
+ */
39
+ registerVisibilityCheck: (check: () => void) => () => void;
32
40
  }
41
+ /**
42
+ * @description 调度一次「下一帧」回调,rAF 与 setTimeout 竞速,只执行一次。
43
+ * 微前端 iframe 沙箱(如 micro-app)下子应用运行在 display:none 的 iframe 中,该文档不参与渲染,
44
+ * requestAnimationFrame 无法被持续驱动(首帧后即停止回调)。若仅依赖 rAF,分批渲染队列会在
45
+ * scheduled 标记为 true 后永久卡住(后续 schedule 与 resume 全部空转),导致剩余字段永久停留骨架屏。
46
+ * 故用 setTimeout 兜底,保证队列一定能被推进。
47
+ * @param {() => void} callback - 下一帧要执行的回调
48
+ * @returns {() => void} 取消函数
49
+ */
50
+ export declare function nextFrame(callback: () => void): () => void;
33
51
  /**
34
52
  * @description 创建分批渲染调度器
35
53
  * @param {number} [batchSize=4] - 每帧最多渲染的字段数
@@ -1,54 +1,82 @@
1
- function R(f = 4) {
2
- const n = [];
3
- let l = !1, u = !1, r = 0, c = [];
4
- function i() {
5
- return n.length === 0 && !l && r === 0;
6
- }
7
- function o() {
8
- if (i() && c.length > 0) {
9
- const e = c;
10
- c = [], e.forEach((t) => t());
1
+ function E(a) {
2
+ let t = !1;
3
+ const n = () => {
4
+ t || (t = !0, a());
5
+ }, u = requestAnimationFrame(n), l = setTimeout(n, 32);
6
+ return () => {
7
+ t = !0, cancelAnimationFrame(u), clearTimeout(l);
8
+ };
9
+ }
10
+ function w(a = 4) {
11
+ const t = [];
12
+ let n = !1, u = !1, l = 0, o = [];
13
+ function h() {
14
+ return t.length === 0 && !n && l === 0;
15
+ }
16
+ function m() {
17
+ if (h() && o.length > 0) {
18
+ const e = o;
19
+ o = [], e.forEach((i) => i());
11
20
  }
12
21
  }
13
- function a() {
14
- if (l = !1, u) return;
22
+ function _() {
23
+ if (n = !1, u) return;
15
24
  let e = 0;
16
- for (; n.length > 0 && e < f; ) {
17
- const t = n.shift();
18
- t.cancelled || (t.cb(), e++);
25
+ for (; t.length > 0 && e < a; ) {
26
+ const i = t.shift();
27
+ i.cancelled || (i.cb(), e++);
19
28
  }
20
- n.length > 0 ? s() : o();
29
+ t.length > 0 ? d() : m();
21
30
  }
22
- function s() {
23
- l || u || (l = !0, requestAnimationFrame(a));
31
+ function d() {
32
+ n || u || (n = !0, E(_));
24
33
  }
25
- function d(e) {
26
- const t = { cb: e, cancelled: !1 };
27
- return n.push(t), s(), () => {
28
- t.cancelled = !0;
34
+ function S(e) {
35
+ const i = { cb: e, cancelled: !1 };
36
+ return t.push(i), d(), () => {
37
+ i.cancelled = !0;
29
38
  };
30
39
  }
31
- function h() {
40
+ function p() {
32
41
  u = !0;
33
42
  }
34
- function S() {
35
- u = !1, n.length > 0 && s();
43
+ function v() {
44
+ u = !1, t.length > 0 && d();
36
45
  }
37
- function m() {
38
- r++;
46
+ function L() {
47
+ l++;
39
48
  }
40
- function E() {
41
- r > 0 && r--, o();
49
+ function A() {
50
+ l > 0 && l--, m();
42
51
  }
43
- function p() {
44
- return i() ? Promise.resolve() : new Promise((e) => c.push(e));
52
+ function b() {
53
+ return h() ? Promise.resolve() : new Promise((e) => o.push(e));
54
+ }
55
+ const c = /* @__PURE__ */ new Set();
56
+ let s = null, r = null;
57
+ function f() {
58
+ r || (r = E(() => {
59
+ r = null;
60
+ for (const e of [...c]) e();
61
+ }));
62
+ }
63
+ function R() {
64
+ s || (document.addEventListener("scroll", f, { capture: !0, passive: !0 }), window.addEventListener("resize", f, { passive: !0 }), s = () => {
65
+ document.removeEventListener("scroll", f, { capture: !0 }), window.removeEventListener("resize", f), r == null || r(), r = null, s = null;
66
+ });
67
+ }
68
+ function C(e) {
69
+ return c.add(e), R(), () => {
70
+ c.delete(e), c.size === 0 && (s == null || s());
71
+ };
45
72
  }
46
- return { request: d, pause: h, resume: S, trackMount: m, settleMount: E, whenAllSettled: p };
73
+ return { request: S, pause: p, resume: v, trackMount: L, settleMount: A, whenAllSettled: b, registerVisibilityCheck: C };
47
74
  }
48
- const _ = Symbol("VirtualRenderScheduler"), b = Symbol("GroupVisibilityCallback"), g = Symbol("HiddenGroupKeys");
75
+ const y = Symbol("VirtualRenderScheduler"), K = Symbol("GroupVisibilityCallback"), g = Symbol("HiddenGroupKeys");
49
76
  export {
50
- b as GROUP_VISIBILITY_CALLBACK_KEY,
77
+ K as GROUP_VISIBILITY_CALLBACK_KEY,
51
78
  g as HIDDEN_GROUP_KEYS_KEY,
52
- _ as RENDER_SCHEDULER_KEY,
53
- R as createRenderScheduler
79
+ y as RENDER_SCHEDULER_KEY,
80
+ w as createRenderScheduler,
81
+ E as nextFrame
54
82
  };
@@ -1,7 +1,9 @@
1
- import { FormCommonConfig, FormSchema, FormSlotSchema, CustomRenderType, TtFormProps, WrapperClassType } from '../types';
1
+ import { Ref } from 'vue';
2
+ import { FormCommonConfig, FormSchema, FormSlotSchema, CustomRenderType, FormValuesInput, NoInfer, TtFormProps, WrapperClassType } from '../types';
2
3
  import { FormApi } from '../formApi';
3
4
  import { TtNavAnchorProps } from '../../../tt-nav-anchor';
4
5
  import { GroupFormApi } from './groupFormApi';
6
+ import { InsertPosition } from './utils';
5
7
  export type CollapsibleType<TValues extends Record<string, any> = Record<string, any>> = boolean | ((values: TValues, formApi: FormApi) => boolean | PromiseLike<boolean>);
6
8
  /** 控制 group / row / slot 是否显示,支持布尔值或函数(接收表单值与 formApi,可返回 Promise) */
7
9
  export type IfShowConditionType<TValues extends Record<string, any> = Record<string, any>> = boolean | ((values: TValues, formApi: FormApi) => boolean | PromiseLike<boolean>);
@@ -105,12 +107,12 @@ export interface UseGroupFormOptionsWithLegacySchema<TValues extends Record<stri
105
107
  }
106
108
  /** groupSchema 与 schema 二选一(至少传一个) */
107
109
  export type UseGroupFormOptions<TValues extends Record<string, any> = Record<string, any>> = UseGroupFormOptionsWithGroupSchema<TValues> | UseGroupFormOptionsWithLegacySchema<TValues>;
108
- export type GroupFormExtraState = Partial<Pick<UseGroupFormOptions, "virtual" | "progressive" | "navAnchorProps" | "containerHeight" | "rootMargin" | "estimateFieldHeight" | "scrollOffset">> & {
110
+ export type GroupFormExtraState<TValues extends Record<string, any> = Record<string, any>> = Partial<Pick<UseGroupFormOptions, "virtual" | "progressive" | "navAnchorProps" | "containerHeight" | "rootMargin" | "estimateFieldHeight" | "scrollOffset">> & {
109
111
  /** 分组 schema 树形结构(store 状态,由 GroupFormApi.setState 维护) */
110
- groupSchema?: GroupFormSchema[];
112
+ groupSchema?: GroupFormSchema<TValues>[];
111
113
  };
112
114
  /** 分组表单完整 store 状态类型 */
113
- export type GroupFormState<TValues extends Record<string, any> = Record<string, any>> = TtFormProps<TValues> & GroupFormExtraState;
115
+ export type GroupFormState<TValues extends Record<string, any> = Record<string, any>> = TtFormProps<TValues> & GroupFormExtraState<TValues>;
114
116
  /** LazyFormField 组件 props */
115
117
  export interface LazyFormFieldProps {
116
118
  /** 传给 FormField 的完整 props(通过 v-bind 透传) */
@@ -174,7 +176,38 @@ export interface GroupSectionProps {
174
176
  * @description GroupFormApi 构造函数的分组配置选项,复用 UseGroupFormOptions 中同名字段的类型定义,
175
177
  * 额外增加 `groupSchema`(由 useGroupForm 传入)。
176
178
  */
177
- export type GroupFormApiOptions = Pick<UseGroupFormOptions, "virtual" | "progressive" | "navAnchorProps" | "scrollToFirstError" | "containerHeight" | "rootMargin" | "estimateFieldHeight" | "scrollOffset"> & {
179
+ export type GroupFormApiOptions<TValues extends Record<string, any> = Record<string, any>> = Pick<UseGroupFormOptions, "virtual" | "progressive" | "navAnchorProps" | "scrollToFirstError" | "containerHeight" | "rootMargin" | "estimateFieldHeight" | "scrollOffset"> & {
178
180
  /** 分组 schema 树形结构(由 useGroupForm 传入) */
179
- groupSchema: GroupFormSchema[];
181
+ groupSchema: GroupFormSchema<TValues>[];
180
182
  };
183
+ /**
184
+ * 分组表单 api 对外类型。
185
+ *
186
+ * 与 {@link ExtendedFormApi} 同一个思路:`GroupFormApi` 类内部按 `Record<string, any>` 处理,
187
+ * 泛型在这一层收窄。分组独有的 `groupSchema` / `appendFields` 也跟着 `TValues` 走,
188
+ * `useGroupForm<Data>()` 之后再 `setState({ groupSchema })`,回调里依旧能推断出 `Data`。
189
+ *
190
+ * 写成「收窄签名 & 类」而不是 `Omit<类, ...> & 收窄签名`:类带私有成员,是名义类型,
191
+ * `Omit` 会把私有成员抹掉,业务把 api 标注成 `GroupFormApi` 就会报缺属性。
192
+ * 交叉后属性变成重载对,收窄签名在前所以优先匹配,匹配不上再退回类的宽松签名。
193
+ */
194
+ export type ExtendedGroupFormApi<TValues extends Record<string, any> = Record<string, any>> = {
195
+ /** 设置表单状态,支持 `groupSchema` 等分组扩展字段 */
196
+ setState: (stateOrFn: ((prev: GroupFormState<TValues>) => Partial<GroupFormState<TValues>>) | Partial<GroupFormState<TValues>>) => void;
197
+ /** 读取当前表单状态 */
198
+ getState: () => null | GroupFormState<TValues>;
199
+ /**
200
+ * 获取表单值
201
+ * @param isGroup - 为 true 时返回按分组 key 嵌套的对象,默认 false 返回扁平值
202
+ */
203
+ getValues: <T = TValues>(isGroup?: boolean) => Promise<T>;
204
+ /** 写入表单值,已声明字段按 `TValues` 校验类型 */
205
+ setValues: (fields: FormValuesInput<TValues>, filterFields?: boolean, shouldValidate?: boolean) => Promise<void>;
206
+ /** 按 fieldName 局部更新已展平的 schema */
207
+ updateSchema: (schema: Partial<FormSchema<TValues>>[]) => void;
208
+ /** 在分组树中增量插入字段或子结构 */
209
+ appendFields: (fields: GroupFormSchema<TValues>[], position?: InsertPosition) => void;
210
+ /** 校验表单,第二个参数控制是否滚动到第一个错误分组 */
211
+ validate: (opts?: any, scrollToError?: boolean) => ReturnType<GroupFormApi["validate"]>;
212
+ useStore: <T = NoInfer<GroupFormState<TValues>>>(selector?: (state: NoInfer<GroupFormState<TValues>>) => T) => Readonly<Ref<T>>;
213
+ } & GroupFormApi;
@@ -1,10 +1,12 @@
1
1
  import { DefineComponent } from 'vue';
2
- import { GroupFormApi } from './groupFormApi';
3
- import { UseGroupFormOptions, UseGroupFormOptionsCommon } from './types';
4
- type GroupFormOverrideProps = Partial<UseGroupFormOptionsCommon>;
5
- type UseGroupFormReturn = readonly [DefineComponent<GroupFormOverrideProps>, GroupFormApi];
2
+ import { ExtendedGroupFormApi, UseGroupFormOptions, UseGroupFormOptionsCommon } from './types';
3
+ type GroupFormOverrideProps<TValues extends Record<string, any> = Record<string, any>> = Partial<UseGroupFormOptionsCommon<TValues>>;
4
+ type UseGroupFormReturn<TValues extends Record<string, any> = Record<string, any>> = readonly [
5
+ DefineComponent<GroupFormOverrideProps<TValues>>,
6
+ ExtendedGroupFormApi<TValues>
7
+ ];
6
8
  /**
7
9
  * @description 返回可渲染的包装组件、扩展后的表单 API,以及分组折叠状态对象。
8
10
  */
9
- export declare function useGroupForm<TValues extends Record<string, any> = Record<string, any>>(options: UseGroupFormOptions<TValues>): UseGroupFormReturn;
11
+ export declare function useGroupForm<TValues extends Record<string, any> = Record<string, any>>(options: UseGroupFormOptions<TValues>): UseGroupFormReturn<TValues>;
10
12
  export {};