attaform 0.24.3 → 0.25.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.
Files changed (89) hide show
  1. package/dist/chunks/devtools.cjs +1 -1
  2. package/dist/chunks/devtools.mjs +1 -1
  3. package/dist/chunks/fingerprint2.cjs +1 -1
  4. package/dist/chunks/fingerprint2.mjs +1 -1
  5. package/dist/index.cjs +4 -4
  6. package/dist/index.d.cts +4 -4
  7. package/dist/index.d.mts +4 -4
  8. package/dist/index.d.ts +4 -4
  9. package/dist/index.mjs +4 -4
  10. package/dist/nuxt.d.cts +1 -1
  11. package/dist/nuxt.d.mts +1 -1
  12. package/dist/nuxt.d.ts +1 -1
  13. package/dist/runtime/plugins/attaform.cjs +2 -2
  14. package/dist/runtime/plugins/attaform.mjs +2 -2
  15. package/dist/shared/{attaform.DQcdvxKZ.cjs → attaform.3heDHayA.cjs} +146 -3
  16. package/dist/shared/attaform.3heDHayA.cjs.map +1 -0
  17. package/dist/shared/{attaform.yqcYwt0d.d.ts → attaform.8vmdOURQ.d.mts} +124 -56
  18. package/dist/shared/{attaform.BjiHiYAZ.d.ts → attaform.B3cgZE3c.d.ts} +1 -1
  19. package/dist/shared/{attaform.DHjRN5JP.d.cts → attaform.B5GFS3Su.d.cts} +124 -56
  20. package/dist/shared/{attaform.BVjueUPu.cjs → attaform.B5YcWrKi.cjs} +3 -3
  21. package/dist/shared/{attaform.BVjueUPu.cjs.map → attaform.B5YcWrKi.cjs.map} +1 -1
  22. package/dist/shared/{attaform.Bx6pgrIy.d.cts → attaform.BJt4ZCkM.d.mts} +1 -1
  23. package/dist/shared/{attaform.DK6_Ctv7.cjs → attaform.BRzKBj2g.cjs} +182 -7
  24. package/dist/shared/attaform.BRzKBj2g.cjs.map +1 -0
  25. package/dist/shared/{attaform.CB1kYKUB.cjs → attaform.BkUzunyB.cjs} +180 -38
  26. package/dist/shared/attaform.BkUzunyB.cjs.map +1 -0
  27. package/dist/shared/{attaform.Dbzwtn4g.mjs → attaform.CN4ZEGo6.mjs} +4 -4
  28. package/dist/shared/{attaform.Dbzwtn4g.mjs.map → attaform.CN4ZEGo6.mjs.map} +1 -1
  29. package/dist/shared/{attaform.C5qkSN6t.mjs → attaform.CqwcTExO.mjs} +146 -3
  30. package/dist/shared/attaform.CqwcTExO.mjs.map +1 -0
  31. package/dist/shared/{attaform.D4ebpNbS.mjs → attaform.CwXXbZIQ.mjs} +3 -3
  32. package/dist/shared/{attaform.D4ebpNbS.mjs.map → attaform.CwXXbZIQ.mjs.map} +1 -1
  33. package/dist/shared/{attaform.B_F61Rx1.mjs → attaform.DK3xUBkj.mjs} +181 -39
  34. package/dist/shared/attaform.DK3xUBkj.mjs.map +1 -0
  35. package/dist/shared/{attaform.ByIB7i15.mjs → attaform.DMNnfQq_.mjs} +4 -4
  36. package/dist/shared/{attaform.ByIB7i15.mjs.map → attaform.DMNnfQq_.mjs.map} +1 -1
  37. package/dist/shared/{attaform.0zueP54D.d.mts → attaform.DS_zBcdr.d.ts} +124 -56
  38. package/dist/shared/{attaform.DvqdxvNU.d.mts → attaform.DmKLa4tL.d.cts} +1 -1
  39. package/dist/shared/{attaform.DgbHNLf_.mjs → attaform.OLtKd9gM.mjs} +2 -2
  40. package/dist/shared/{attaform.DgbHNLf_.mjs.map → attaform.OLtKd9gM.mjs.map} +1 -1
  41. package/dist/shared/{attaform.WvcckZMD.mjs → attaform.Vp2-CWZB.mjs} +3 -2
  42. package/dist/shared/attaform.Vp2-CWZB.mjs.map +1 -0
  43. package/dist/shared/{attaform.CqlLImc1.cjs → attaform.Xe8dATED.cjs} +4 -4
  44. package/dist/shared/{attaform.CqlLImc1.cjs.map → attaform.Xe8dATED.cjs.map} +1 -1
  45. package/dist/shared/{attaform.CjdepGnw.cjs → attaform.ZXZ6dH72.cjs} +3 -1
  46. package/dist/shared/attaform.ZXZ6dH72.cjs.map +1 -0
  47. package/dist/shared/{attaform.DUc6cetN.d.cts → attaform.i_LA3X9o.d.cts} +54 -2
  48. package/dist/shared/{attaform.DUc6cetN.d.ts → attaform.i_LA3X9o.d.mts} +54 -2
  49. package/dist/shared/{attaform.DUc6cetN.d.mts → attaform.i_LA3X9o.d.ts} +54 -2
  50. package/dist/shared/{attaform.DwCtxauq.mjs → attaform.k9V0py0s.mjs} +182 -8
  51. package/dist/shared/attaform.k9V0py0s.mjs.map +1 -0
  52. package/dist/shared/{attaform.DfnwaGW2.cjs → attaform.sks1MFVO.cjs} +4 -4
  53. package/dist/shared/{attaform.DfnwaGW2.cjs.map → attaform.sks1MFVO.cjs.map} +1 -1
  54. package/dist/shared/{attaform.DRWrVSkH.cjs → attaform.xBDo0Ko0.cjs} +2 -2
  55. package/dist/shared/{attaform.DRWrVSkH.cjs.map → attaform.xBDo0Ko0.cjs.map} +1 -1
  56. package/dist/transforms.cjs +2 -1
  57. package/dist/transforms.cjs.map +1 -1
  58. package/dist/transforms.d.cts +13 -1
  59. package/dist/transforms.d.mts +13 -1
  60. package/dist/transforms.d.ts +13 -1
  61. package/dist/transforms.mjs +1 -1
  62. package/dist/vite.cjs +2 -1
  63. package/dist/vite.cjs.map +1 -1
  64. package/dist/vite.mjs +2 -1
  65. package/dist/vite.mjs.map +1 -1
  66. package/dist/zod-v3.cjs +2 -2
  67. package/dist/zod-v3.d.cts +3 -3
  68. package/dist/zod-v3.d.mts +3 -3
  69. package/dist/zod-v3.d.ts +3 -3
  70. package/dist/zod-v3.mjs +2 -2
  71. package/dist/zod-v4.cjs +2 -2
  72. package/dist/zod-v4.d.cts +5 -5
  73. package/dist/zod-v4.d.mts +5 -5
  74. package/dist/zod-v4.d.ts +5 -5
  75. package/dist/zod-v4.mjs +2 -2
  76. package/dist/zod.cjs +5 -5
  77. package/dist/zod.d.cts +5 -5
  78. package/dist/zod.d.mts +5 -5
  79. package/dist/zod.d.ts +5 -5
  80. package/dist/zod.mjs +5 -5
  81. package/package.json +6 -2
  82. package/dist/shared/attaform.B_F61Rx1.mjs.map +0 -1
  83. package/dist/shared/attaform.C5qkSN6t.mjs.map +0 -1
  84. package/dist/shared/attaform.CB1kYKUB.cjs.map +0 -1
  85. package/dist/shared/attaform.CjdepGnw.cjs.map +0 -1
  86. package/dist/shared/attaform.DK6_Ctv7.cjs.map +0 -1
  87. package/dist/shared/attaform.DQcdvxKZ.cjs.map +0 -1
  88. package/dist/shared/attaform.DwCtxauq.mjs.map +0 -1
  89. package/dist/shared/attaform.WvcckZMD.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
- import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, readonly, toRaw, reactive, watch, markRaw, triggerRef, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope, nextTick } from 'vue';
2
- import { n as pathsEqual, j as isPathPrefix, _ as __DEV__, f as canonicalizePath, s as segmentsForPathKey, o as keyForSegments, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, q as INTERACTIVE_TAG_NAMES, R as ROOT_PATH, r as coerceToPathKey, a as InvalidUseFormConfigError, w as ensureAttaformInstalled, u as useRegistry, x as kFormContext, y as kFormInstanceId, d as ReservedFormKeyError, l as kAttaformWizardActiveStepResolver, z as kAttaformAncestorWizard } from './attaform.C5qkSN6t.mjs';
3
- import { R as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER } from './attaform.WvcckZMD.mjs';
1
+ import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, nextTick, warn, readonly, toRaw, reactive, watch, markRaw, triggerRef, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope } from 'vue';
2
+ import { n as pathsEqual, j as isPathPrefix, _ as __DEV__, f as canonicalizePath, s as segmentsForPathKey, o as keyForSegments, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, q as INTERACTIVE_TAG_NAMES, R as ROOT_PATH, r as coerceToPathKey, a as InvalidUseFormConfigError, w as ensureAttaformInstalled, u as useRegistry, x as kFormContext, y as kFormInstanceId, d as ReservedFormKeyError, l as kAttaformWizardActiveStepResolver, z as kAttaformAncestorWizard } from './attaform.CqwcTExO.mjs';
3
+ import { R as REGISTER_OWNER_MARKER, b as V_REGISTER_MARKER } from './attaform.Vp2-CWZB.mjs';
4
4
 
5
5
  function safeAssign(target, key, value) {
6
6
  if (key === "__proto__") {
@@ -939,6 +939,15 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
939
939
  if (since !== void 0 && (transformingSince === null || since < transformingSince))
940
940
  transformingSince = since;
941
941
  }
942
+ const ownRecord = state.fields.get(key);
943
+ if (ownRecord !== void 0) {
944
+ if (ownRecord.focused === true) focused = true;
945
+ if (ownRecord.blurred === true) blurred = true;
946
+ if (ownRecord.touched === true) touched = true;
947
+ if (ownRecord.interacted === true) interacted = true;
948
+ if (ownRecord.blurredAfterInteraction === true) blurredAfterInteraction = true;
949
+ if (ownRecord.connected === true) connected = true;
950
+ }
942
951
  const ownTransformError = state.transformErrors.get(key) ?? null;
943
952
  const gated = asyncPending && !state.firstValidationDone.value;
944
953
  const valid = !gated && errors.length === 0 && !validating;
@@ -2009,11 +2018,11 @@ function applyInvalidSubmitPolicy(state, formInstanceId, policy) {
2009
2018
  return;
2010
2019
  }
2011
2020
  if (policy === "focus-first-error") {
2012
- target.element.focus();
2021
+ target.element.focus({ focusVisible: true });
2013
2022
  return;
2014
2023
  }
2015
2024
  target.element.scrollIntoView();
2016
- target.element.focus({ preventScroll: true });
2025
+ target.element.focus({ preventScroll: true, focusVisible: true });
2017
2026
  }
2018
2027
 
2019
2028
  const warnedRejections = __DEV__ ? /* @__PURE__ */ new WeakMap() : null;
@@ -2284,6 +2293,7 @@ function coerceValue(value, accepted, elementAccepted, index) {
2284
2293
  return coerceScalar(value, accepted, index);
2285
2294
  }
2286
2295
 
2296
+ const warnedMultiRootHosts = /* @__PURE__ */ new Set();
2287
2297
  const EMPTY_TRANSFORMS = Object.freeze([]);
2288
2298
  const attaformListenersSymbol = Symbol.for("attaform:focus-listeners");
2289
2299
  function attachFocusListeners(state, segments, element, instanceMeta) {
@@ -2388,6 +2398,24 @@ function buildRegister(state, formInstanceId, instanceConfig) {
2388
2398
  setValueWithInternalPath: (value, meta) => {
2389
2399
  return state.setValueAtPath(segments, value, withInstanceMeta(meta));
2390
2400
  },
2401
+ setValueFromHost: (value) => {
2402
+ state.markInteracted(segments);
2403
+ const accepted = state.setValueAtPath(segments, value, withInstanceMeta(void 0));
2404
+ if (__DEV__) {
2405
+ const dedupeKey = `${formInstanceId}:${pathKey}`;
2406
+ const isWired = () => (state.elements.get(pathKey)?.elements.size ?? 0) > 0 || state.getFieldRecord(segments)?.connected === true;
2407
+ if (!warnedMultiRootHosts.has(dedupeKey) && !isWired()) {
2408
+ warnedMultiRootHosts.add(dedupeKey);
2409
+ void nextTick(() => {
2410
+ if (isWired()) return;
2411
+ warn(
2412
+ `[attaform] v-register received a value update from a component it never attached to. Vue drops a runtime directive on a component with more than one root node (a fragment / multi-root template), so v-register's value binding works but its field state (connected, focus, aria, scroll-to-error) does not. Give the component a single element root, or wrap it so v-register lands on one element.`
2413
+ );
2414
+ });
2415
+ }
2416
+ }
2417
+ return accepted;
2418
+ },
2391
2419
  // Called by the `vRegisterHint` compile-time transform's wrapping
2392
2420
  // IIFE on every server-side render of `<element v-register="…">`.
2393
2421
  // Without it, every SSR'd FieldState serialises `connected: false`
@@ -2399,6 +2427,24 @@ function buildRegister(state, formInstanceId, instanceConfig) {
2399
2427
  markConnectedOptimistically: () => {
2400
2428
  state.markConnectedOptimistically(segments);
2401
2429
  },
2430
+ markHostConnected: (connected) => {
2431
+ state.markHostConnected(segments, connected);
2432
+ },
2433
+ markFocused: (focused) => {
2434
+ state.markFocused(
2435
+ segments,
2436
+ focused,
2437
+ instanceMeta !== void 0 ? { instance: instanceMeta } : void 0
2438
+ );
2439
+ },
2440
+ hasRegisteredDescendant: (hostElement) => {
2441
+ const record = state.elements.get(pathKey);
2442
+ if (record === void 0) return false;
2443
+ for (const element of record.elements) {
2444
+ if (hostElement.contains(element)) return true;
2445
+ }
2446
+ return false;
2447
+ },
2402
2448
  // --- Async transform lifecycle (internal; the directive's
2403
2449
  // deferred orchestrator is the only legitimate consumer). Thin
2404
2450
  // path-bound delegates to the store's per-path token / counter
@@ -3181,7 +3227,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
3181
3227
  const focusFirstError = (options2) => {
3182
3228
  const target = state.getFirstErrorElement(formInstanceId);
3183
3229
  if (target === null) return false;
3184
- target.element.focus(options2);
3230
+ target.element.focus({ focusVisible: true, ...options2 });
3185
3231
  return true;
3186
3232
  };
3187
3233
  const scrollToFirstError = (options2) => {
@@ -4972,6 +5018,21 @@ function createFormStore(options) {
4972
5018
  blurred: current?.blurred ?? true
4973
5019
  });
4974
5020
  }
5021
+ function markHostConnected(path, connected) {
5022
+ const { key } = canonicalizePath(path);
5023
+ const current = fields.get(key);
5024
+ if (connected) {
5025
+ if (current?.connected === true) return;
5026
+ touchFieldRecord(key, path, {
5027
+ connected: true,
5028
+ focused: current?.focused ?? false,
5029
+ blurred: current?.blurred ?? true
5030
+ });
5031
+ } else {
5032
+ if (current?.connected !== true) return;
5033
+ touchFieldRecord(key, path, { connected: false, focused: null, blurred: null });
5034
+ }
5035
+ }
4975
5036
  function markFocused(path, focused, meta) {
4976
5037
  const { key } = canonicalizePath(path);
4977
5038
  const current = fields.get(key);
@@ -5303,10 +5364,7 @@ function createFormStore(options) {
5303
5364
  if (elementToFormInstance.get(entry.element) !== formInstanceId) continue;
5304
5365
  if (!entry.element.isConnected) continue;
5305
5366
  if (entry.element.offsetParent === null) continue;
5306
- const { key } = canonicalizePath(entry.path);
5307
- const hasSchemaErr = (schemaErrors.get(key)?.length ?? 0) > 0;
5308
- const hasUserErr = (userErrors.get(key)?.length ?? 0) > 0;
5309
- if (!hasSchemaErr && !hasUserErr) continue;
5367
+ if (getErrorsForPath(entry.path).length === 0) continue;
5310
5368
  return { path: entry.path, element: entry.element };
5311
5369
  }
5312
5370
  return null;
@@ -5381,6 +5439,7 @@ function createFormStore(options) {
5381
5439
  markInteracted,
5382
5440
  touchAtPath,
5383
5441
  markConnectedOptimistically,
5442
+ markHostConnected,
5384
5443
  isPristineAtPath,
5385
5444
  isPristineAtPathByKey,
5386
5445
  hasStructuralChangeUnder,
@@ -5885,7 +5944,7 @@ function resolveState(key, registry) {
5885
5944
  if (key !== void 0) {
5886
5945
  const stored = registry.forms.get(key);
5887
5946
  if (stored === void 0) {
5888
- warnMiss$1(`no form registered for key '${key}'`, registry.ssr);
5947
+ warnMiss$1(`no form registered for key '${key}'`, registry.ssr, registry.forms);
5889
5948
  return null;
5890
5949
  }
5891
5950
  return stored;
@@ -5895,12 +5954,22 @@ function resolveState(key, registry) {
5895
5954
  warnIfAmbientProviderHadDuplicates();
5896
5955
  return ambient;
5897
5956
  }
5898
- function warnMiss$1(detail, ssr) {
5957
+ function availableKeysHint$1(forms) {
5958
+ const addressable = [...forms.keys()].filter((key) => !key.startsWith(RESERVED_KEY_PREFIX));
5959
+ if (addressable.length === 0) return void 0;
5960
+ return `Registered keys: ${addressable.map((key) => `'${key}'`).join(", ")}.`;
5961
+ }
5962
+ function warnMiss$1(detail, ssr, forms) {
5899
5963
  if (!__DEV__ || ssr) return;
5900
5964
  const frame = captureUserCallSite();
5901
- console.warn(
5902
- `[attaform] injectForm: ${detail}. Returning null.` + (frame !== void 0 ? ` ${frame}` : "")
5965
+ const parts = [`[attaform] injectForm: ${detail}. Returning null.`];
5966
+ const keys = availableKeysHint$1(forms);
5967
+ if (keys !== void 0) parts.push(keys);
5968
+ parts.push(
5969
+ `A form created by a child or sibling component is not registered until that component's own setup runs, which happens after this point. Lift its useForm({ key }) call to a common ancestor, or read the form after mount.`
5903
5970
  );
5971
+ if (frame !== void 0) parts.push(frame);
5972
+ console.warn(parts.join(" "));
5904
5973
  }
5905
5974
  function warnIfAmbientProviderHadDuplicates() {
5906
5975
  if (!__DEV__ || ambientProvideHistory === null) return;
@@ -5979,6 +6048,8 @@ function useRegister() {
5979
6048
  }
5980
6049
  }
5981
6050
  if ("value" in rawAttrs) delete rawAttrs["value"];
6051
+ if ("modelValue" in rawAttrs) delete rawAttrs["modelValue"];
6052
+ if ("onUpdate:modelValue" in rawAttrs) delete rawAttrs["onUpdate:modelValue"];
5982
6053
  };
5983
6054
  refreshAndStripBridgeAttrs();
5984
6055
  onBeforeMount(refreshAndStripBridgeAttrs);
@@ -6158,6 +6229,9 @@ function asStatusSource(form) {
6158
6229
  function asSubmissionSource(form) {
6159
6230
  return form;
6160
6231
  }
6232
+ function asHandleSubmitSource(form) {
6233
+ return form;
6234
+ }
6161
6235
  function useWizard(options) {
6162
6236
  const rawSteps = Array.isArray(options.steps) ? options.steps : [];
6163
6237
  if (rawSteps.length === 0 && __DEV__) {
@@ -6252,6 +6326,7 @@ function useWizard(options) {
6252
6326
  }
6253
6327
  };
6254
6328
  function resolveSlot(slot, index, ctx) {
6329
+ if (slot === void 0 || slot === null) return void 0;
6255
6330
  if (typeof slot === "string") {
6256
6331
  return getOrBuildNoop(slot);
6257
6332
  }
@@ -6267,7 +6342,7 @@ function useWizard(options) {
6267
6342
  return void 0;
6268
6343
  }
6269
6344
  function resolveSlotResult(result) {
6270
- if (result === void 0) return void 0;
6345
+ if (result === void 0 || result === null) return void 0;
6271
6346
  if (typeof result === "string") {
6272
6347
  return getOrBuildNoop(result);
6273
6348
  }
@@ -6335,6 +6410,50 @@ function useWizard(options) {
6335
6410
  const first = list[0];
6336
6411
  return first === void 0 ? void 0 : first.form;
6337
6412
  });
6413
+ watch(compiledSteps, (list, prevList) => {
6414
+ const key = activeKey.value;
6415
+ if (key === "") return;
6416
+ if (list.some((step) => step.key === key)) return;
6417
+ if (list.length === 0) {
6418
+ activeKey.value = "";
6419
+ return;
6420
+ }
6421
+ const oldIndex = prevList.findIndex((step) => step.key === key);
6422
+ const slid = list[oldIndex < 0 ? 0 : Math.min(oldIndex, list.length - 1)];
6423
+ if (slid !== void 0) activeKey.value = slid.key;
6424
+ });
6425
+ const activeFormFacade = new Proxy({}, {
6426
+ get(_target, prop) {
6427
+ const form = activeForm.value;
6428
+ if (form === void 0) return void 0;
6429
+ if (prop === "handleSubmit") {
6430
+ const lateBound = (onValid, onInvalid) => {
6431
+ return (event) => {
6432
+ const current = activeForm.value;
6433
+ if (current === void 0) return Promise.resolve();
6434
+ return asHandleSubmitSource(current).handleSubmit(onValid, onInvalid)(event);
6435
+ };
6436
+ };
6437
+ return lateBound;
6438
+ }
6439
+ return Reflect.get(form, prop, form);
6440
+ },
6441
+ has(_target, prop) {
6442
+ const form = activeForm.value;
6443
+ return form === void 0 ? false : Reflect.has(form, prop);
6444
+ },
6445
+ ownKeys(_target) {
6446
+ const form = activeForm.value;
6447
+ return form === void 0 ? [] : Reflect.ownKeys(form);
6448
+ },
6449
+ getOwnPropertyDescriptor(_target, prop) {
6450
+ const form = activeForm.value;
6451
+ if (form === void 0) return void 0;
6452
+ const descriptor = Reflect.getOwnPropertyDescriptor(form, prop);
6453
+ if (descriptor === void 0) return void 0;
6454
+ return { ...descriptor, configurable: true };
6455
+ }
6456
+ });
6338
6457
  const isFinalStep = computed(() => {
6339
6458
  const list = compiledSteps.value;
6340
6459
  const idx = activeIndex.value;
@@ -6699,6 +6818,39 @@ function useWizard(options) {
6699
6818
  const target = list[idx + 1];
6700
6819
  moveTo(target.key);
6701
6820
  }
6821
+ async function tryNext() {
6822
+ if (submitting.value) {
6823
+ if (__DEV__) {
6824
+ console.warn(`[attaform] wizard.tryNext(): blocked while a submit is in flight.`);
6825
+ }
6826
+ return false;
6827
+ }
6828
+ const list = compiledSteps.value;
6829
+ if (list.length === 0) {
6830
+ if (__DEV__) {
6831
+ console.warn(`[attaform] wizard.tryNext(): wizard has no compiled steps; no-op.`);
6832
+ }
6833
+ return false;
6834
+ }
6835
+ const idx = activeIndex.value;
6836
+ if (idx < 0 || idx >= list.length - 1) {
6837
+ if (__DEV__) {
6838
+ console.warn(
6839
+ `[attaform] wizard.tryNext(): already on the final step ("${activeKey.value}"). Use wizard.handleSubmit() to submit.`
6840
+ );
6841
+ }
6842
+ return false;
6843
+ }
6844
+ const form = activeForm.value;
6845
+ if (form === void 0) return false;
6846
+ let advanced = false;
6847
+ await asHandleSubmitSource(form).handleSubmit(() => {
6848
+ const before = activeKey.value;
6849
+ next();
6850
+ advanced = activeKey.value !== before;
6851
+ })();
6852
+ return advanced;
6853
+ }
6702
6854
  function back() {
6703
6855
  if (submitting.value) {
6704
6856
  if (__DEV__) {
@@ -6835,20 +6987,13 @@ function useWizard(options) {
6835
6987
  const final = isFinalStep.value;
6836
6988
  const list = compiledSteps.value;
6837
6989
  const results = /* @__PURE__ */ new Map();
6838
- if (final) {
6839
- await Promise.all(
6840
- list.map(async (step) => {
6841
- registry.forms.get(step.key)?.clearUserErrors();
6842
- const result = await processOne(step.form);
6843
- results.set(step.key, result);
6844
- })
6845
- );
6846
- } else {
6847
- const active = activeForm.value;
6848
- registry.forms.get(active.key)?.clearUserErrors();
6849
- const result = await processOne(active);
6850
- results.set(active.key, result);
6851
- }
6990
+ await Promise.all(
6991
+ list.map(async (step) => {
6992
+ registry.forms.get(step.key)?.clearUserErrors();
6993
+ const result = await processOne(step.form);
6994
+ results.set(step.key, result);
6995
+ })
6996
+ );
6852
6997
  for (const key of results.keys()) {
6853
6998
  const store = registry.forms.get(key);
6854
6999
  if (store !== void 0) {
@@ -6883,14 +7028,7 @@ function useWizard(options) {
6883
7028
  }
6884
7029
  return;
6885
7030
  }
6886
- if (final) {
6887
- done.value = true;
6888
- } else {
6889
- recordDeparture(currentKey);
6890
- const idx = activeIndex.value;
6891
- const target = list[idx + 1];
6892
- if (target !== void 0) moveTo(target.key);
6893
- }
7031
+ done.value = true;
6894
7032
  } else {
6895
7033
  await focusFirstWizardError(errors);
6896
7034
  if (onError !== void 0) {
@@ -6940,13 +7078,14 @@ function useWizard(options) {
6940
7078
  next,
6941
7079
  back,
6942
7080
  goTo,
7081
+ tryNext,
6943
7082
  handleSubmit,
6944
7083
  reset,
6945
7084
  get currentStep() {
6946
7085
  return currentStep.value;
6947
7086
  },
6948
7087
  get activeForm() {
6949
- return activeForm.value;
7088
+ return activeForm.value === void 0 ? void 0 : activeFormFacade;
6950
7089
  },
6951
7090
  get activeIndex() {
6952
7091
  return activeIndex.value;
@@ -7078,6 +7217,9 @@ function warnMiss(detail, ssr, hint) {
7078
7217
  const frame = captureUserCallSite();
7079
7218
  const parts = [`[attaform] injectWizard: ${detail}. Returning null.`];
7080
7219
  if (hint !== void 0) parts.push(hint);
7220
+ parts.push(
7221
+ `A wizard created by a child or sibling component is not registered until that component's own setup runs, which happens after this point. Lift its useWizard({ key }) call to a common ancestor, or read the wizard after mount.`
7222
+ );
7081
7223
  if (frame !== void 0) parts.push(frame);
7082
7224
  console.warn(parts.join(" "));
7083
7225
  }
@@ -7100,4 +7242,4 @@ function warnIfAmbientWizardProviderHadDuplicates() {
7100
7242
  }
7101
7243
 
7102
7244
  export { AttaformErrorCode as A, DEFAULT_TIMINGS as D, injectWizard as a, isUnset as b, useRegister as c, useWizard as d, defaultCoercionRules as e, defaultDisplayState as f, defineCoercion as g, useAbstractForm as h, injectForm as i, isPlainRecord as j, safeAssign as k, lazy as l, makeDefaultDisplayState as m, slimKindOf as n, humanize as o, getAtPath as p, setAtPath as q, safeOwnRead as s, unset as u };
7103
- //# sourceMappingURL=attaform.B_F61Rx1.mjs.map
7245
+ //# sourceMappingURL=attaform.DK3xUBkj.mjs.map