attaform 0.18.1 → 0.19.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 (71) hide show
  1. package/README.md +3 -0
  2. package/dist/chunks/devtools.cjs +1 -1
  3. package/dist/chunks/devtools.mjs +1 -1
  4. package/dist/chunks/indexeddb.cjs +1 -1
  5. package/dist/chunks/indexeddb.mjs +1 -1
  6. package/dist/chunks/local-storage.cjs +1 -1
  7. package/dist/chunks/local-storage.mjs +1 -1
  8. package/dist/chunks/session-storage.cjs +1 -1
  9. package/dist/chunks/session-storage.mjs +1 -1
  10. package/dist/index.cjs +4 -4
  11. package/dist/index.d.cts +68 -75
  12. package/dist/index.d.mts +68 -75
  13. package/dist/index.d.ts +68 -75
  14. package/dist/index.mjs +5 -5
  15. package/dist/nuxt.d.cts +1 -1
  16. package/dist/nuxt.d.mts +1 -1
  17. package/dist/nuxt.d.ts +1 -1
  18. package/dist/runtime/plugins/attaform.cjs +2 -2
  19. package/dist/runtime/plugins/attaform.mjs +2 -2
  20. package/dist/shared/{attaform.DsC3rZHG.mjs → attaform.BTi-PsHr.mjs} +544 -134
  21. package/dist/shared/attaform.BTi-PsHr.mjs.map +1 -0
  22. package/dist/shared/{attaform.iTqxvl-P.d.mts → attaform.BTpuvGec.d.ts} +46 -13
  23. package/dist/shared/{attaform.BqK_L4gK.cjs → attaform.BqEfHpVB.cjs} +119 -1
  24. package/dist/shared/attaform.BqEfHpVB.cjs.map +1 -0
  25. package/dist/shared/{attaform.DK9aj0N8.d.ts → attaform.BtBmfLQN.d.mts} +46 -13
  26. package/dist/shared/{attaform.Dj9mwbaV.d.mts → attaform.C0uGZQ4M.d.cts} +365 -86
  27. package/dist/shared/{attaform.Dj9mwbaV.d.ts → attaform.C0uGZQ4M.d.mts} +365 -86
  28. package/dist/shared/{attaform.Dj9mwbaV.d.cts → attaform.C0uGZQ4M.d.ts} +365 -86
  29. package/dist/shared/{attaform.II89Pcf4.cjs → attaform.C1msmO2v.cjs} +544 -134
  30. package/dist/shared/attaform.C1msmO2v.cjs.map +1 -0
  31. package/dist/shared/{attaform.tts_OM7j.d.cts → attaform.CBjmobqk.d.cts} +1 -1
  32. package/dist/shared/{attaform.2b7M2mww.d.mts → attaform.CJ-e9gYI.d.ts} +1 -1
  33. package/dist/shared/{attaform.tsNFcEW7.d.ts → attaform.CRNA0vrd.d.mts} +1 -1
  34. package/dist/shared/{attaform.BDdFdjeX.mjs → attaform.Cghpuav8.mjs} +3 -3
  35. package/dist/shared/{attaform.BDdFdjeX.mjs.map → attaform.Cghpuav8.mjs.map} +1 -1
  36. package/dist/shared/{attaform.CtNUB9nf.mjs → attaform.CiMqJHDm.mjs} +3 -3
  37. package/dist/shared/{attaform.CtNUB9nf.mjs.map → attaform.CiMqJHDm.mjs.map} +1 -1
  38. package/dist/shared/{attaform.5UhpSVFI.cjs → attaform.CoxJ8Qm8.cjs} +2 -2
  39. package/dist/shared/{attaform.5UhpSVFI.cjs.map → attaform.CoxJ8Qm8.cjs.map} +1 -1
  40. package/dist/shared/{attaform.Xhg0AYNa.mjs → attaform.CrpjyXdO.mjs} +120 -2
  41. package/dist/shared/attaform.CrpjyXdO.mjs.map +1 -0
  42. package/dist/shared/{attaform.DF8wo-ry.d.ts → attaform.D4I63aBV.d.ts} +1 -1
  43. package/dist/shared/{attaform.DVLB6CAn.d.mts → attaform.DXYHL99q.d.mts} +1 -1
  44. package/dist/shared/{attaform.Dlk1jMuv.cjs → attaform.JBx8cfMA.cjs} +3 -3
  45. package/dist/shared/{attaform.Dlk1jMuv.cjs.map → attaform.JBx8cfMA.cjs.map} +1 -1
  46. package/dist/shared/{attaform.DUHru0OF.cjs → attaform.OznWyOPy.cjs} +3 -3
  47. package/dist/shared/{attaform.DUHru0OF.cjs.map → attaform.OznWyOPy.cjs.map} +1 -1
  48. package/dist/shared/{attaform.M33WKVV4.d.cts → attaform.QvygsFGh.d.cts} +1 -1
  49. package/dist/shared/{attaform.Xt0A3QUd.mjs → attaform.a3uBo-gw.mjs} +3 -3
  50. package/dist/shared/{attaform.Xt0A3QUd.mjs.map → attaform.a3uBo-gw.mjs.map} +1 -1
  51. package/dist/shared/{attaform.DoSuaKMd.d.cts → attaform.ePUcKxId.d.cts} +46 -13
  52. package/dist/zod-v3.cjs +3 -3
  53. package/dist/zod-v3.d.cts +4 -4
  54. package/dist/zod-v3.d.mts +4 -4
  55. package/dist/zod-v3.d.ts +4 -4
  56. package/dist/zod-v3.mjs +3 -3
  57. package/dist/zod-v4.cjs +3 -3
  58. package/dist/zod-v4.d.cts +4 -4
  59. package/dist/zod-v4.d.mts +4 -4
  60. package/dist/zod-v4.d.ts +4 -4
  61. package/dist/zod-v4.mjs +3 -3
  62. package/dist/zod.cjs +4 -4
  63. package/dist/zod.d.cts +6 -6
  64. package/dist/zod.d.mts +6 -6
  65. package/dist/zod.d.ts +6 -6
  66. package/dist/zod.mjs +5 -5
  67. package/package.json +5 -5
  68. package/dist/shared/attaform.BqK_L4gK.cjs.map +0 -1
  69. package/dist/shared/attaform.DsC3rZHG.mjs.map +0 -1
  70. package/dist/shared/attaform.II89Pcf4.cjs.map +0 -1
  71. package/dist/shared/attaform.Xhg0AYNa.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { F as FormKey, af as SlimPrimitiveKind, C as CoercionEntry, j as CoercionRegistry, G as GenericForm, Y as PathKey, X as Path, V as ValidationError, a as AbstractSchema, d as ShouldShowErrors, ao as WriteMeta, m as DeepPartial, ap as WriteShape, aj as ValidateOn, aw as PersistOptInRegistry, S as Segment, A as AttaformDefaults, b as UseFormReturnType, R as RegisterValue } from './attaform.Dj9mwbaV.mjs';
1
+ import { t as FormKey, ae as SlimPrimitiveKind, C as CoercionEntry, g as CoercionRegistry, G as GenericForm, T as PathKey, S as Path, am as ValidationError, A as AbstractSchema, x as GetDisplayState, aq as WriteMeta, D as DeepPartial, ar as WriteShape, ak as ValidateOn, Y as PersistOptInRegistry, aa as Segment, f as AttaformDefaults, aj as UseFormReturnType, a8 as RegisterValue } from './attaform.C0uGZQ4M.js';
2
2
  import { Ref, ComputedRef, App, InjectionKey } from 'vue';
3
3
 
4
4
  /**
@@ -517,19 +517,29 @@ declare const defaultCoercionRules: CoercionRegistry;
517
517
  */
518
518
  /**
519
519
  * Per-path field status. Replaced wholesale (not mutated in place) on
520
- * every change. Three semantic groups:
520
+ * every change. Five semantic groups:
521
521
  *
522
522
  * - `connected` — is a DOM element registered for this path?
523
523
  * - `focused` / `blurred` — DOM-state flags. `null` while no element
524
524
  * is connected (no DOM means the concepts don't apply); plain
525
525
  * booleans once connected, with the invariant `blurred === !focused`
526
526
  * enforced by `markFocused`.
527
- * - `touched` — interaction history, not DOM state. Always a plain
527
+ * - `touched` — focus/blur history, not DOM state. Always a plain
528
528
  * boolean: `false` at registration, sticky `true` after first blur,
529
529
  * cleared only by `form.reset()` / `form.resetField(path)`. Persists
530
530
  * across disconnects so v-if'd-away fields don't lose their touched
531
531
  * state on rehide (wizard "show review of touched fields" patterns
532
532
  * rely on this).
533
+ * - `interacted` — value-mutation history, not DOM state. Plain
534
+ * boolean: `false` at registration, sticky `true` once the user
535
+ * issues a value edit through the directive's input listeners
536
+ * (never on hydration, default seeding, or programmatic setValue);
537
+ * cleared with `touched` by `form.reset()` / `form.resetField(path)`.
538
+ * - `blurredAfterInteraction` — the first blur that follows a value
539
+ * edit (the field has been edited and then left). Plain boolean,
540
+ * sticky `true`. A tab-through blur with no prior edit does NOT set
541
+ * it (`interacted` is still false at that blur). Composes
542
+ * `interacted` with the departure; drives the default display gate.
533
543
  */
534
544
  type FieldRecord = {
535
545
  readonly path: Path;
@@ -538,6 +548,8 @@ type FieldRecord = {
538
548
  readonly focused: boolean | null;
539
549
  readonly blurred: boolean | null;
540
550
  readonly touched: boolean;
551
+ readonly interacted: boolean;
552
+ readonly blurredAfterInteraction: boolean;
541
553
  };
542
554
  /** Per-path DOM element tracking. Client-only. */
543
555
  type ElementRecord = {
@@ -649,15 +661,14 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
649
661
  */
650
662
  readonly ssr: boolean;
651
663
  /**
652
- * Resolved `shouldShowErrors` predicate driving `field.showErrors`
653
- * and `form.meta.showErrors`. Resolved once at construction via
654
- * `resolveShouldShowErrors(options.shouldShowErrors)` so the
655
- * field-state computeds don't repeat the boolean-vs-function
656
- * branch on every read. Boolean shorthand has already been lifted
657
- * to a constant predicate by the time it lands here; `undefined`
658
- * config falls through to `defaultShouldShowErrors`.
664
+ * Resolved `getDisplayState` predicate driving `field.displayState`,
665
+ * the `show*` booleans, and their `form.meta` rollups. Resolved once
666
+ * at construction via `resolveGetDisplayState(options.getDisplayState)`;
667
+ * `undefined` config falls through to `defaultDisplayState`. The
668
+ * field-state computeds read the resolved function directly on every
669
+ * read.
659
670
  */
660
- readonly shouldShowErrors: ShouldShowErrors;
671
+ readonly getDisplayState: GetDisplayState;
661
672
  readonly submitting: Ref<boolean>;
662
673
  readonly activeSubmissions: Ref<number>;
663
674
  readonly submissionAttempts: Ref<number>;
@@ -831,6 +842,14 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
831
842
  */
832
843
  setValueAtPath(path: Path, value: unknown, meta?: WriteMeta): boolean;
833
844
  getValueAtPath(path: Path): unknown;
845
+ /**
846
+ * Stable identity for the array element at `path`. An array element
847
+ * (numeric last segment) carries its allocated identity token,
848
+ * maintained by `array-identity.ts` across structural mutations.
849
+ * Empty for any non-array-element path: a record entry, a
850
+ * fixed-object field, a container, or the root. Backs `FieldState.key`.
851
+ */
852
+ arrayElementKey(path: Path): string;
834
853
  reset(nextDefaultValues?: DeepPartial<WriteShape<F>>): void;
835
854
  resetField(path: Path): void;
836
855
  /**
@@ -894,6 +913,12 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
894
913
  readonly instance?: WriteMeta['instance'];
895
914
  }): void;
896
915
  markTouched(path: Path): void;
916
+ /**
917
+ * Flip `interacted: true` on a leaf — the sticky value-mutation flag.
918
+ * Driven by the directive's input listeners (via the RegisterValue's
919
+ * `markInteracted`); idempotent, never set by programmatic writes.
920
+ */
921
+ markInteracted(path: Path): void;
897
922
  /**
898
923
  * Walk every active-variant leaf under `segments` and flip
899
924
  * `touched: true`. Powers `form.touch(path?)`. Idempotent;
@@ -920,6 +945,14 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
920
945
  * isn't exposed to consumers.
921
946
  */
922
947
  isPristineAtPath(path: Path): boolean;
948
+ /**
949
+ * Whether any tracked array under `path` has changed shape — a reorder,
950
+ * insert, or removal — relative to its construction/reset baseline. The
951
+ * structural half of `dirty`: per-element baselines travel with their
952
+ * element across a mutation, so a positional value comparison alone can
953
+ * no longer see the shape change.
954
+ */
955
+ hasStructuralChangeUnder(path: Path): boolean;
923
956
  getFieldRecord(path: Path): FieldRecord | undefined;
924
957
  getOriginalAtPath(path: Path): unknown;
925
958
  /**
@@ -1647,5 +1680,5 @@ declare const AttaformErrorCode: {
1647
1680
  };
1648
1681
  type AttaformErrorCode = (typeof AttaformErrorCode)[keyof typeof AttaformErrorCode];
1649
1682
 
1650
- export { AttaformErrorCode as d, createRegistry as p, defaultCoercionRules as q, defineCoercion as r, getRegistryFromApp as s, injectForm as t, injectWizard as u, kAttaformRegistry as v, lazy as w, useRegister as x, useRegistry as y, useWizard as z };
1651
- export type { AttaformRegistry as A, CompiledStep as C, FormStatus as F, InjectWizardInput as I, LazyMarker as L, SSRDetectOptions as S, UseRegisterReturn as U, WizardCtx as W, SerializedFormData as a, AggregateError as b, AnyForm as c, StepSlot as e, UseWizardReturnType as f, WizardCtxForm as g, WizardOnError as h, WizardOnSubmit as i, WizardOptions as j, WizardPersistFn as k, WizardRestoreFn as l, WizardRestoreState as m, WizardStatusesProxy as n, WizardSubmitContext as o };
1683
+ export { AttaformErrorCode as b, createRegistry as p, defaultCoercionRules as q, defineCoercion as r, getRegistryFromApp as s, injectForm as t, injectWizard as u, kAttaformRegistry as v, lazy as w, useRegister as x, useRegistry as y, useWizard as z };
1684
+ export type { AggregateError as A, CompiledStep as C, FormStatus as F, InjectWizardInput as I, LazyMarker as L, SSRDetectOptions as S, UseRegisterReturn as U, WizardCtx as W, AnyForm as a, AttaformRegistry as c, SerializedFormData as d, StepSlot as e, UseWizardReturnType as f, WizardCtxForm as g, WizardOnError as h, WizardOnSubmit as i, WizardOptions as j, WizardPersistFn as k, WizardRestoreFn as l, WizardRestoreState as m, WizardStatusesProxy as n, WizardSubmitContext as o };
@@ -818,6 +818,9 @@ function setAssignFunction(el, vnode, value) {
818
818
  }
819
819
  el[assignKey] = getModelAssigner(el, vnode, value);
820
820
  }
821
+ function noteInteraction(value) {
822
+ if (isRegisterValue(value)) value.markInteracted();
823
+ }
821
824
  const vRegisterText = {
822
825
  created(el, { value, modifiers: { lazy, trim, number } }, vnode) {
823
826
  const castToNumber = number === true || vnode.props?.["type"] === "number";
@@ -829,6 +832,7 @@ const vRegisterText = {
829
832
  if (shouldBailListener(el)) return;
830
833
  const target = e.target;
831
834
  if (target === null || target.composing) return;
835
+ noteInteraction(value);
832
836
  let domValue = el.value;
833
837
  if (trim === true && lazy === true) {
834
838
  domValue = domValue.trim();
@@ -960,6 +964,7 @@ const vRegisterCheckbox = {
960
964
  setAssignFunction(el, vnode, value);
961
965
  addEventListener(el, "change", () => {
962
966
  if (shouldBailListener(el)) return;
967
+ noteInteraction(value);
963
968
  const modelValue = value.innerRef.value ?? [];
964
969
  const explicitValueRequired = true;
965
970
  const rawElementValue = getValue(el, explicitValueRequired);
@@ -1057,6 +1062,7 @@ const vRegisterRadio = {
1057
1062
  setAssignFunction(el, vnode, value);
1058
1063
  addEventListener(el, "change", () => {
1059
1064
  if (shouldBailListener(el)) return;
1065
+ noteInteraction(value);
1060
1066
  el[assignKey]?.(getValue(el));
1061
1067
  if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {
1062
1068
  const currentModel = value.innerRef.value;
@@ -1105,6 +1111,7 @@ const vRegisterSelect = {
1105
1111
  const isSetModel = isSet(value.innerRef.value);
1106
1112
  addEventListener(el, "change", () => {
1107
1113
  if (shouldBailListener(el)) return;
1114
+ noteInteraction(value);
1108
1115
  const selectedVal = Array.prototype.filter.call(el.options, (o) => o.selected).map((o) => number === true ? looseToNumber(getValue(o)) : getValue(o));
1109
1116
  const wrote = el[assignKey]?.(
1110
1117
  el.multiple ? isSetModel ? new Set(selectedVal) : selectedVal : selectedVal[0]
@@ -1219,11 +1226,83 @@ function getCheckboxValue(el, checked) {
1219
1226
  }
1220
1227
  const SUPPORTED_TAGS = /* @__PURE__ */ new Set(["INPUT", "TEXTAREA", "SELECT"]);
1221
1228
  const warnedUnsupportedElements = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
1229
+ const MANAGED_ARIA_ATTRS = [
1230
+ "aria-invalid",
1231
+ "aria-busy",
1232
+ "aria-required",
1233
+ "aria-describedby"
1234
+ ];
1235
+ const ariaLockKey = Symbol.for("attaform:aria-locks");
1236
+ const ariaScopeKey = Symbol.for("attaform:aria-scope");
1237
+ const EMPTY_ARIA_LOCKS = /* @__PURE__ */ new Set();
1238
+ function mergeAriaLocks(el, vnode) {
1239
+ let locks = el[ariaLockKey];
1240
+ if (locks === void 0) {
1241
+ locks = /* @__PURE__ */ new Set();
1242
+ el[ariaLockKey] = locks;
1243
+ }
1244
+ const props = vnode.props;
1245
+ if (props !== null) {
1246
+ for (const attr of MANAGED_ARIA_ATTRS) {
1247
+ if (attr in props) locks.add(attr);
1248
+ }
1249
+ }
1250
+ return locks;
1251
+ }
1252
+ function setAriaAttr(el, attr, value) {
1253
+ if (value === null) el.removeAttribute(attr);
1254
+ else el.setAttribute(attr, value);
1255
+ }
1256
+ function resolveAriaValue(attr, rv, ds) {
1257
+ switch (attr) {
1258
+ case "aria-invalid":
1259
+ return ds === "error" ? "true" : null;
1260
+ case "aria-busy":
1261
+ return ds === "pending" ? "true" : null;
1262
+ case "aria-required":
1263
+ return rv.isRequired === true ? "true" : null;
1264
+ case "aria-describedby":
1265
+ return ds === "error" && rv.aria?.errorId !== void 0 ? rv.aria.errorId : null;
1266
+ default:
1267
+ return null;
1268
+ }
1269
+ }
1270
+ function applyAria(el, rv) {
1271
+ if (rv.ariaEnabled !== true || rv.ariaDisplayState === void 0) return;
1272
+ const locks = el[ariaLockKey] ?? EMPTY_ARIA_LOCKS;
1273
+ const ds = rv.ariaDisplayState.value;
1274
+ for (const attr of MANAGED_ARIA_ATTRS) {
1275
+ if (!locks.has(attr)) setAriaAttr(el, attr, resolveAriaValue(attr, rv, ds));
1276
+ }
1277
+ }
1278
+ function setupAria(el, rv, vnode) {
1279
+ if (rv.ariaEnabled !== true || rv.ariaDisplayState === void 0) return;
1280
+ mergeAriaLocks(el, vnode);
1281
+ applyAria(el, rv);
1282
+ const displayState = rv.ariaDisplayState;
1283
+ const scope = vue.effectScope(true);
1284
+ scope.run(() => {
1285
+ vue.watch(displayState, () => applyAria(el, rv), { flush: "post" });
1286
+ });
1287
+ el[ariaScopeKey] = () => scope.stop();
1288
+ }
1289
+ function teardownAria(el) {
1290
+ const stop = el[ariaScopeKey];
1291
+ if (stop === void 0) return;
1292
+ stop();
1293
+ delete el[ariaScopeKey];
1294
+ const locks = el[ariaLockKey] ?? EMPTY_ARIA_LOCKS;
1295
+ for (const attr of MANAGED_ARIA_ATTRS) {
1296
+ if (!locks.has(attr)) el.removeAttribute(attr);
1297
+ }
1298
+ delete el[ariaLockKey];
1299
+ }
1222
1300
  const vRegisterDynamic = {
1223
1301
  created(el, binding, vnode) {
1224
1302
  syncPersistOptIn(el, binding.value, void 0, vnode.props?.["type"]);
1225
1303
  syncMultiTabOptOut(binding.value, void 0);
1226
1304
  callModelHook(el, binding, vnode, null, "created");
1305
+ if (isRegisterValue(binding.value)) setupAria(el, binding.value, vnode);
1227
1306
  if (__DEV__ && warnedUnsupportedElements !== null && !SUPPORTED_TAGS.has(el.tagName) && !warnedUnsupportedElements.has(el)) {
1228
1307
  void vue.nextTick(() => {
1229
1308
  if (warnedUnsupportedElements.has(el)) return;
@@ -1247,12 +1326,28 @@ const vRegisterDynamic = {
1247
1326
  syncMultiTabOptOut(binding.value, binding.oldValue);
1248
1327
  syncElementRegistration(el, binding.value, binding.oldValue);
1249
1328
  callModelHook(el, binding, vnode, prevVNode, "beforeUpdate");
1329
+ const ariaEl = el;
1330
+ const value = binding.value;
1331
+ if (!isRegisterValue(value) || value.ariaEnabled !== true || value.ariaDisplayState === void 0) {
1332
+ teardownAria(ariaEl);
1333
+ } else {
1334
+ const old = binding.oldValue;
1335
+ const pathChanged = !isRegisterValue(old) || old.path !== value.path;
1336
+ if (pathChanged) {
1337
+ teardownAria(ariaEl);
1338
+ setupAria(ariaEl, value, vnode);
1339
+ } else {
1340
+ mergeAriaLocks(ariaEl, vnode);
1341
+ applyAria(ariaEl, value);
1342
+ }
1343
+ }
1250
1344
  },
1251
1345
  updated(el, binding, vnode, prevVNode) {
1252
1346
  callModelHook(el, binding, vnode, prevVNode, "updated");
1253
1347
  },
1254
1348
  beforeUnmount(el, { value }) {
1255
1349
  removeTrackedListeners(el);
1350
+ teardownAria(el);
1256
1351
  if (isRegisterValue(value)) {
1257
1352
  value.persistOptIns.removeAllFor(getOrAssignElementId(el));
1258
1353
  value.unmarkNoSync?.();
@@ -1262,6 +1357,28 @@ const vRegisterDynamic = {
1262
1357
  delete el.composing;
1263
1358
  delete el._assigning;
1264
1359
  delete el[assignKey];
1360
+ },
1361
+ // The lifecycle hooks above don't run on the server (Vue skips
1362
+ // directive lifecycle during SSR), so emit the same aria attributes
1363
+ // here from the SSR-time gated display state. Honors authored attrs
1364
+ // (vnode-level lockout) and the ariaEnabled gate, touches no DOM, and
1365
+ // shares `resolveAriaValue` with the client path. Ids are SSR-stable
1366
+ // (formInstanceId derives from Vue's useId), so a server-rendered
1367
+ // describedby matches the client after hydration.
1368
+ getSSRProps(binding, vnode) {
1369
+ const rv = binding.value;
1370
+ if (!isRegisterValue(rv) || rv.ariaEnabled !== true || rv.ariaDisplayState === void 0) {
1371
+ return void 0;
1372
+ }
1373
+ const props = vnode?.props ?? null;
1374
+ const ds = rv.ariaDisplayState.value;
1375
+ const out = {};
1376
+ for (const attr of MANAGED_ARIA_ATTRS) {
1377
+ if (props !== null && attr in props) continue;
1378
+ const value = resolveAriaValue(attr, rv, ds);
1379
+ if (value !== null) out[attr] = value;
1380
+ }
1381
+ return out;
1265
1382
  }
1266
1383
  };
1267
1384
  function isBlankFileValue(value) {
@@ -1307,6 +1424,7 @@ const vRegisterFile = {
1307
1424
  value.setValueWithInternalPath(blankShape, { blank: true });
1308
1425
  }
1309
1426
  addEventListener(input, "change", () => {
1427
+ noteInteraction(value);
1310
1428
  const next = readFilesFromInput(input);
1311
1429
  const blank = isBlankFileValue(next);
1312
1430
  value.setValueWithInternalPath(next, blank ? { blank: true } : void 0);
@@ -1548,4 +1666,4 @@ exports.segmentsForPathKey = segmentsForPathKey;
1548
1666
  exports.useRegister = useRegister;
1549
1667
  exports.useRegistry = useRegistry;
1550
1668
  exports.vRegister = vRegister;
1551
- //# sourceMappingURL=attaform.BqK_L4gK.cjs.map
1669
+ //# sourceMappingURL=attaform.BqEfHpVB.cjs.map