attaform 0.21.0 → 0.21.2
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.
- package/dist/chunks/dev-key-collision-warnings.cjs +1 -1
- package/dist/chunks/dev-key-collision-warnings.mjs +1 -1
- package/dist/chunks/devtools.cjs +1 -1
- package/dist/chunks/devtools.mjs +1 -1
- package/dist/chunks/fingerprint2.cjs +1 -1
- package/dist/chunks/fingerprint2.mjs +1 -1
- package/dist/chunks/indexeddb.cjs +1 -1
- package/dist/chunks/indexeddb.mjs +1 -1
- package/dist/chunks/local-storage.cjs +1 -1
- package/dist/chunks/local-storage.mjs +1 -1
- package/dist/chunks/multi-tab-sync.cjs +2 -2
- package/dist/chunks/multi-tab-sync.mjs +2 -2
- package/dist/chunks/session-storage.cjs +1 -1
- package/dist/chunks/session-storage.mjs +1 -1
- package/dist/chunks/wire-persistence.cjs +2 -2
- package/dist/chunks/wire-persistence.mjs +2 -2
- package/dist/index.cjs +37 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -28
- package/dist/index.d.mts +31 -28
- package/dist/index.d.ts +31 -28
- package/dist/index.mjs +38 -25
- package/dist/index.mjs.map +1 -1
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +396 -216
- package/dist/runtime/components/DevtoolsValueTree.vue +176 -114
- package/dist/runtime/plugins/attaform.cjs +2 -2
- package/dist/runtime/plugins/attaform.mjs +2 -2
- package/dist/shared/{attaform.BA3vRDos.cjs → attaform.B5LNzqQh.cjs} +349 -277
- package/dist/shared/attaform.B5LNzqQh.cjs.map +1 -0
- package/dist/shared/{attaform.PnqML3xW.cjs → attaform.BBDIKtKY.cjs} +13 -16
- package/dist/shared/attaform.BBDIKtKY.cjs.map +1 -0
- package/dist/shared/{attaform.CRsXyy-Y.d.ts → attaform.BCcrLApm.d.mts} +131 -64
- package/dist/shared/{attaform.BupwXkj_.mjs → attaform.BFWb6hDk.mjs} +29 -23
- package/dist/shared/attaform.BFWb6hDk.mjs.map +1 -0
- package/dist/shared/{attaform.7lzO9pdM.d.mts → attaform.BGf_J22U.d.ts} +131 -64
- package/dist/shared/{attaform.BnK_bfcb.mjs → attaform.BVeLgfEh.mjs} +14 -17
- package/dist/shared/attaform.BVeLgfEh.mjs.map +1 -0
- package/dist/shared/{attaform.BK1RE2ha.d.ts → attaform.BYgioWLF.d.ts} +2 -2
- package/dist/shared/{attaform.F8LMHHWV.d.cts → attaform.BkjJfMvJ.d.cts} +131 -64
- package/dist/shared/{attaform.BDIEq9qP.d.cts → attaform.BoY6RZUl.d.cts} +2 -2
- package/dist/shared/{attaform.CEf6wYfD.cjs → attaform.BwLp9KM7.cjs} +2 -2
- package/dist/shared/{attaform.CEf6wYfD.cjs.map → attaform.BwLp9KM7.cjs.map} +1 -1
- package/dist/shared/{attaform._rsCZy2j.cjs → attaform.BwrowMp2.cjs} +25 -45
- package/dist/shared/attaform.BwrowMp2.cjs.map +1 -0
- package/dist/shared/{attaform.ezb5Nh2t.mjs → attaform.C41gjp-a.mjs} +2 -2
- package/dist/shared/{attaform.ezb5Nh2t.mjs.map → attaform.C41gjp-a.mjs.map} +1 -1
- package/dist/shared/{attaform.BM6YD9kZ.cjs → attaform.CR6wGvNu.cjs} +29 -23
- package/dist/shared/attaform.CR6wGvNu.cjs.map +1 -0
- package/dist/shared/{attaform.DSqO6Db7.mjs → attaform.CTheKoTc.mjs} +705 -282
- package/dist/shared/attaform.CTheKoTc.mjs.map +1 -0
- package/dist/shared/{attaform.BzvOdiSI.cjs → attaform.CcnF1AKJ.cjs} +4 -4
- package/dist/shared/attaform.CcnF1AKJ.cjs.map +1 -0
- package/dist/shared/{attaform.BQ6drorq.d.mts → attaform.CnEl--PF.d.mts} +2 -2
- package/dist/shared/{attaform.CkjTapyq.mjs → attaform.CrD73S4m.mjs} +4 -4
- package/dist/shared/attaform.CrD73S4m.mjs.map +1 -0
- package/dist/shared/{attaform.BUszFoKq.cjs → attaform.D2ZuIOCf.cjs} +711 -287
- package/dist/shared/attaform.D2ZuIOCf.cjs.map +1 -0
- package/dist/shared/{attaform.r3PePkDR.mjs → attaform.D6GYGshL.mjs} +25 -45
- package/dist/shared/attaform.D6GYGshL.mjs.map +1 -0
- package/dist/shared/{attaform.Y_Mgg0Yp.mjs → attaform.DP-u7_tk.mjs} +348 -277
- package/dist/shared/attaform.DP-u7_tk.mjs.map +1 -0
- package/dist/shared/{attaform.B1nyO4ec.d.cts → attaform.ory-3WhV.d.cts} +395 -176
- package/dist/shared/{attaform.B1nyO4ec.d.mts → attaform.ory-3WhV.d.mts} +395 -176
- package/dist/shared/{attaform.B1nyO4ec.d.ts → attaform.ory-3WhV.d.ts} +395 -176
- package/dist/transforms.cjs +1 -1
- package/dist/transforms.mjs +1 -1
- package/dist/vite.cjs +1 -1
- package/dist/vite.mjs +1 -1
- package/dist/zod-v3.cjs +3 -4
- package/dist/zod-v3.cjs.map +1 -1
- package/dist/zod-v3.d.cts +4 -4
- package/dist/zod-v3.d.mts +4 -4
- package/dist/zod-v3.d.ts +4 -4
- package/dist/zod-v3.mjs +2 -3
- package/dist/zod-v3.mjs.map +1 -1
- package/dist/zod-v4.cjs +3 -4
- package/dist/zod-v4.cjs.map +1 -1
- package/dist/zod-v4.d.cts +4 -4
- package/dist/zod-v4.d.mts +4 -4
- package/dist/zod-v4.d.ts +4 -4
- package/dist/zod-v4.mjs +2 -3
- package/dist/zod-v4.mjs.map +1 -1
- package/dist/zod.cjs +6 -6
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +77 -26
- package/dist/zod.d.mts +77 -26
- package/dist/zod.d.ts +77 -26
- package/dist/zod.mjs +5 -6
- package/dist/zod.mjs.map +1 -1
- package/package.json +3 -11
- package/dist/shared/attaform.BA3vRDos.cjs.map +0 -1
- package/dist/shared/attaform.BM6YD9kZ.cjs.map +0 -1
- package/dist/shared/attaform.BUszFoKq.cjs.map +0 -1
- package/dist/shared/attaform.BnK_bfcb.mjs.map +0 -1
- package/dist/shared/attaform.BupwXkj_.mjs.map +0 -1
- package/dist/shared/attaform.BzvOdiSI.cjs.map +0 -1
- package/dist/shared/attaform.CkjTapyq.mjs.map +0 -1
- package/dist/shared/attaform.DSqO6Db7.mjs.map +0 -1
- package/dist/shared/attaform.PnqML3xW.cjs.map +0 -1
- package/dist/shared/attaform.Y_Mgg0Yp.mjs.map +0 -1
- package/dist/shared/attaform._rsCZy2j.cjs.map +0 -1
- package/dist/shared/attaform.r3PePkDR.mjs.map +0 -1
- package/dist/shared/{attaform.DSD85fHb.d.cts → attaform.nf83TIR5.d.cts} +10 -10
- package/dist/shared/{attaform.DSD85fHb.d.mts → attaform.nf83TIR5.d.mts} +10 -10
- package/dist/shared/{attaform.DSD85fHb.d.ts → attaform.nf83TIR5.d.ts} +10 -10
|
@@ -24,6 +24,11 @@ class InvalidUseFormConfigError extends AttaformError {
|
|
|
24
24
|
}
|
|
25
25
|
class SubmitErrorHandlerError extends AttaformError {
|
|
26
26
|
}
|
|
27
|
+
function toError(value) {
|
|
28
|
+
if (value instanceof Error) return value;
|
|
29
|
+
const message = typeof value === "string" && value.length > 0 ? value : `Submit callback threw a non-Error value (${typeof value})`;
|
|
30
|
+
return new Error(message, { cause: value });
|
|
31
|
+
}
|
|
27
32
|
class RegistryNotInstalledError extends AttaformError {
|
|
28
33
|
constructor() {
|
|
29
34
|
super(
|
|
@@ -277,125 +282,20 @@ function invokeArrayFns(fns, ...args) {
|
|
|
277
282
|
}
|
|
278
283
|
}
|
|
279
284
|
|
|
280
|
-
|
|
281
|
-
const raw = new Error().stack;
|
|
282
|
-
if (typeof raw !== "string") return void 0;
|
|
283
|
-
const lines = raw.split("\n");
|
|
284
|
-
for (let i = 1; i < lines.length; i++) {
|
|
285
|
-
const frame = lines[i];
|
|
286
|
-
if (frame === void 0) continue;
|
|
287
|
-
if (/attaform[/-]forms?/i.test(frame)) continue;
|
|
288
|
-
if (/\bforms\.[A-Za-z0-9_-]+\.m?js\b/.test(frame)) continue;
|
|
289
|
-
const trimmed = frame.trim();
|
|
290
|
-
if (trimmed.length === 0) continue;
|
|
291
|
-
return shortenSourceFrame(trimmed);
|
|
292
|
-
}
|
|
293
|
-
return void 0;
|
|
294
|
-
}
|
|
295
|
-
function shortenSourceFrame(frame) {
|
|
296
|
-
const match = /(?:^|\s|\()([^\s()]+):(\d+):\d+\)?$/.exec(frame);
|
|
297
|
-
if (match === null) return frame;
|
|
298
|
-
const [, urlOrPath, line] = match;
|
|
299
|
-
if (urlOrPath === void 0 || line === void 0) return frame;
|
|
300
|
-
let path = urlOrPath;
|
|
301
|
-
path = path.replace(/^[a-z]+:\/\/[^/]+\//i, "");
|
|
302
|
-
path = path.replace(/^_nuxt\//, "");
|
|
303
|
-
path = path.replace(/^\//, "");
|
|
304
|
-
return `(${path}:${line})`;
|
|
305
|
-
}
|
|
306
|
-
|
|
285
|
+
const V_REGISTER_MARKER = Symbol.for("attaform:v-register-directive");
|
|
307
286
|
const REGISTER_OWNER_MARKER = Symbol.for("attaform:register-owner-marker");
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
return Reflect.get(v, prop);
|
|
318
|
-
},
|
|
319
|
-
has(_target, prop) {
|
|
320
|
-
if (prop === "__v_isRef" || prop === "value") return true;
|
|
321
|
-
const v = capturedRegisterValue.value;
|
|
322
|
-
if (v === void 0) return false;
|
|
323
|
-
return Reflect.has(v, prop);
|
|
324
|
-
},
|
|
325
|
-
ownKeys(_target) {
|
|
326
|
-
const v = capturedRegisterValue.value;
|
|
327
|
-
if (v === void 0) return [];
|
|
328
|
-
return Reflect.ownKeys(v);
|
|
329
|
-
},
|
|
330
|
-
getOwnPropertyDescriptor(_target, prop) {
|
|
331
|
-
const v = capturedRegisterValue.value;
|
|
332
|
-
if (v === void 0) return void 0;
|
|
333
|
-
const desc = Reflect.getOwnPropertyDescriptor(v, prop);
|
|
334
|
-
if (desc !== void 0) {
|
|
335
|
-
desc.configurable = true;
|
|
336
|
-
}
|
|
337
|
-
return desc;
|
|
338
|
-
}
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
function useRegister() {
|
|
342
|
-
const instance = vue.getCurrentInstance();
|
|
343
|
-
if (instance === null) {
|
|
344
|
-
warnOutsideSetup();
|
|
345
|
-
return makeRegisterValueProxy(vue.shallowRef(void 0));
|
|
346
|
-
}
|
|
347
|
-
ensureAttaformInstalled(instance.appContext.app);
|
|
348
|
-
const capturedRegisterValue = vue.shallowRef(void 0);
|
|
349
|
-
const refreshAndStripBridgeAttrs = () => {
|
|
350
|
-
const rawAttrs = instance.attrs;
|
|
351
|
-
if ("registerValue" in rawAttrs) {
|
|
352
|
-
capturedRegisterValue.value = rawAttrs["registerValue"];
|
|
353
|
-
delete rawAttrs["registerValue"];
|
|
354
|
-
} else {
|
|
355
|
-
const dirs = instance.vnode.dirs;
|
|
356
|
-
if (dirs !== null && dirs !== void 0) {
|
|
357
|
-
for (const dir of dirs) {
|
|
358
|
-
const marked = dir.dir?.[V_REGISTER_MARKER];
|
|
359
|
-
if (marked === true) {
|
|
360
|
-
capturedRegisterValue.value = dir.value;
|
|
361
|
-
break;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
if ("value" in rawAttrs) delete rawAttrs["value"];
|
|
367
|
-
};
|
|
368
|
-
refreshAndStripBridgeAttrs();
|
|
369
|
-
vue.onBeforeMount(refreshAndStripBridgeAttrs);
|
|
370
|
-
vue.onBeforeUpdate(refreshAndStripBridgeAttrs);
|
|
371
|
-
vue.onMounted(() => {
|
|
372
|
-
const el = instance.vnode.el;
|
|
373
|
-
if (el !== null && el !== void 0 && typeof el === "object") {
|
|
374
|
-
el[REGISTER_OWNER_MARKER] = true;
|
|
375
|
-
}
|
|
376
|
-
if (capturedRegisterValue.value === void 0) {
|
|
377
|
-
warnNoParentRV(instance);
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
return makeRegisterValueProxy(capturedRegisterValue);
|
|
381
|
-
}
|
|
382
|
-
function warnOutsideSetup() {
|
|
383
|
-
if (!__DEV__) return;
|
|
384
|
-
if (warnedOutsideSetup) return;
|
|
385
|
-
warnedOutsideSetup = true;
|
|
386
|
-
const frame = captureUserCallSite();
|
|
387
|
-
console.warn(
|
|
388
|
-
`[attaform] useRegister() called outside a component setup; returning an unbound RegisterValue proxy. Fix: call it inside <script setup> or a setup() function \u2014 not from an event handler or async callback.` + (frame !== void 0 ? ` ${frame}` : "")
|
|
389
|
-
);
|
|
287
|
+
function isRegisterValue(val) {
|
|
288
|
+
if (typeof val !== "object" || val === null) return false;
|
|
289
|
+
if (!("innerRef" in val)) return false;
|
|
290
|
+
if (!vue.isRef(val.innerRef)) return false;
|
|
291
|
+
if (!("registerElement" in val)) return false;
|
|
292
|
+
if (typeof val.registerElement !== "function") return false;
|
|
293
|
+
if (!("setValueWithInternalPath" in val)) return false;
|
|
294
|
+
if (typeof val.setValueWithInternalPath !== "function") return false;
|
|
295
|
+
return true;
|
|
390
296
|
}
|
|
391
|
-
function
|
|
392
|
-
|
|
393
|
-
if (warnedNoParentRV.has(instance)) return;
|
|
394
|
-
warnedNoParentRV.add(instance);
|
|
395
|
-
const frame = captureUserCallSite();
|
|
396
|
-
console.warn(
|
|
397
|
-
`[attaform] useRegister: no parent registerValue prop; RegisterValue fields will read as undefined. Pass v-register on the parent: \`<YourComponent v-register="form.register('field')" />\`.` + (frame !== void 0 ? ` ${frame}` : "")
|
|
398
|
-
);
|
|
297
|
+
function isTransforming(value) {
|
|
298
|
+
return isRegisterValue(value) && value.transforming;
|
|
399
299
|
}
|
|
400
300
|
|
|
401
301
|
const MANAGED_ARIA_ATTRS = [
|
|
@@ -506,6 +406,199 @@ function isRegisterValueLike(val) {
|
|
|
506
406
|
return typeof val === "object" && val !== null && "markInteracted" in val && typeof val.markInteracted === "function";
|
|
507
407
|
}
|
|
508
408
|
|
|
409
|
+
const assignKey = Symbol.for("attaform:assign-key");
|
|
410
|
+
const DEFAULT_ASSIGNER_TAG = Symbol.for("attaform:default-assigner-tag");
|
|
411
|
+
function isDefaultAssigner(fn) {
|
|
412
|
+
return typeof fn === "function" && fn[DEFAULT_ASSIGNER_TAG] === true;
|
|
413
|
+
}
|
|
414
|
+
const CONSUMER_WRAPPED_TAG = Symbol.for("attaform:consumer-wrapped-assigner");
|
|
415
|
+
function isConsumerWrapped(fn) {
|
|
416
|
+
return typeof fn === "function" && fn[CONSUMER_WRAPPED_TAG] === true;
|
|
417
|
+
}
|
|
418
|
+
function fireAssigner(el, registerValue, value) {
|
|
419
|
+
const fn = el[assignKey];
|
|
420
|
+
if (fn === void 0) return void 0;
|
|
421
|
+
if (isDefaultAssigner(fn) || isConsumerWrapped(fn)) {
|
|
422
|
+
return fn(value);
|
|
423
|
+
}
|
|
424
|
+
if (!isRegisterValue(registerValue)) {
|
|
425
|
+
return fn(value, void 0);
|
|
426
|
+
}
|
|
427
|
+
return wrapWithTransforms(
|
|
428
|
+
value,
|
|
429
|
+
registerValue,
|
|
430
|
+
(coerced) => fn(coerced, registerValue),
|
|
431
|
+
void 0
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
function isThenable(x) {
|
|
435
|
+
return x !== null && (typeof x === "object" || typeof x === "function") && typeof x.then === "function";
|
|
436
|
+
}
|
|
437
|
+
function makeTransformContext() {
|
|
438
|
+
const holder = { controller: null, aborted: false };
|
|
439
|
+
const ctx = {
|
|
440
|
+
get signal() {
|
|
441
|
+
if (holder.controller === null) {
|
|
442
|
+
holder.controller = new AbortController();
|
|
443
|
+
if (holder.aborted) holder.controller.abort();
|
|
444
|
+
}
|
|
445
|
+
return holder.controller.signal;
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
return { ctx, holder };
|
|
449
|
+
}
|
|
450
|
+
function runTransforms(initial, registerValue) {
|
|
451
|
+
const transforms = registerValue.transforms;
|
|
452
|
+
if (transforms === void 0 || transforms.length === 0) {
|
|
453
|
+
return { kind: "sync", ok: true, value: initial };
|
|
454
|
+
}
|
|
455
|
+
const { ctx, holder } = makeTransformContext();
|
|
456
|
+
let v = initial;
|
|
457
|
+
for (let i = 0; i < transforms.length; i++) {
|
|
458
|
+
const fn = transforms[i];
|
|
459
|
+
let out;
|
|
460
|
+
try {
|
|
461
|
+
out = fn(v, ctx);
|
|
462
|
+
} catch (err) {
|
|
463
|
+
logTransformFailure(registerValue.path, i, fn, err);
|
|
464
|
+
return { kind: "sync", ok: false };
|
|
465
|
+
}
|
|
466
|
+
if (isThenable(out)) {
|
|
467
|
+
const rest = transforms.slice(i + 1);
|
|
468
|
+
const seed = out;
|
|
469
|
+
const run = () => rest.reduce(
|
|
470
|
+
(acc, next) => acc.then((value) => next(value, ctx)),
|
|
471
|
+
Promise.resolve(seed)
|
|
472
|
+
);
|
|
473
|
+
return { kind: "async", run, holder };
|
|
474
|
+
}
|
|
475
|
+
v = out;
|
|
476
|
+
}
|
|
477
|
+
return { kind: "sync", ok: true, value: v };
|
|
478
|
+
}
|
|
479
|
+
function kickoffAsyncTransform(rv, holder, run, commit, syncDom) {
|
|
480
|
+
const token = rv.beginTransform(holder);
|
|
481
|
+
void run().then(
|
|
482
|
+
(value) => {
|
|
483
|
+
const live = rv.isCurrentTransform(token);
|
|
484
|
+
rv.endTransform(token);
|
|
485
|
+
if (!live) return;
|
|
486
|
+
const coerced = applyCoerce(value, rv);
|
|
487
|
+
const wrote = commit(coerced);
|
|
488
|
+
if (wrote === false) rv.setTransformError(transformGateRejectedError(rv.path));
|
|
489
|
+
else syncDom?.();
|
|
490
|
+
},
|
|
491
|
+
(err) => {
|
|
492
|
+
if (rv.isCurrentTransform(token)) rv.setTransformError(toTransformError(err));
|
|
493
|
+
rv.endTransform(token);
|
|
494
|
+
}
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
function logTransformFailure(path, index, fn, err) {
|
|
498
|
+
if (__DEV__) {
|
|
499
|
+
const namePart = fn.name !== "" ? `, '${fn.name}'` : "";
|
|
500
|
+
console.error(
|
|
501
|
+
`[attaform] transform threw for path '${path}' (index ${index}${namePart}) \u2014 write aborted. Transforms must not throw; wrap your own try/catch if the throw is recoverable. Original error:`,
|
|
502
|
+
err
|
|
503
|
+
);
|
|
504
|
+
} else {
|
|
505
|
+
console.error(
|
|
506
|
+
`[attaform] transform error \u2014 write aborted (set NODE_ENV=development for details).`
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function applyCoerce(value, registerValue) {
|
|
511
|
+
return registerValue.coerce !== void 0 ? registerValue.coerce(value) : value;
|
|
512
|
+
}
|
|
513
|
+
function wrapWithTransforms(value, registerValue, commit, syncDom) {
|
|
514
|
+
const r = runTransforms(value, registerValue);
|
|
515
|
+
if (r.kind === "async") {
|
|
516
|
+
kickoffAsyncTransform(registerValue, r.holder, r.run, commit, syncDom);
|
|
517
|
+
return true;
|
|
518
|
+
}
|
|
519
|
+
if (!r.ok) return false;
|
|
520
|
+
const coerced = applyCoerce(r.value, registerValue);
|
|
521
|
+
return commit(coerced);
|
|
522
|
+
}
|
|
523
|
+
function toTransformError(value) {
|
|
524
|
+
if (value instanceof Error) return value;
|
|
525
|
+
const message = typeof value === "string" && value.length > 0 ? value : `Transform rejected with a non-Error value (${typeof value})`;
|
|
526
|
+
return new Error(message, { cause: value });
|
|
527
|
+
}
|
|
528
|
+
function transformGateRejectedError(path) {
|
|
529
|
+
return new Error(
|
|
530
|
+
`[attaform] transform result for path '${path}' was rejected by the field's type gate (the resolved value did not fit the schema slot).`
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
const getModelAssigner = (el, vnode, registerValue) => {
|
|
534
|
+
const fn = vnode.props?.["onUpdate:registerValue"] ?? vnode.props?.["on:update:registerValue"];
|
|
535
|
+
if (isArray(fn)) {
|
|
536
|
+
const fnArr = fn.filter((x) => isFunction(x));
|
|
537
|
+
const wrapped = (value) => {
|
|
538
|
+
return wrapWithTransforms(
|
|
539
|
+
value,
|
|
540
|
+
registerValue,
|
|
541
|
+
(coerced) => {
|
|
542
|
+
invokeArrayFns(fnArr, coerced, registerValue);
|
|
543
|
+
return void 0;
|
|
544
|
+
},
|
|
545
|
+
void 0
|
|
546
|
+
);
|
|
547
|
+
};
|
|
548
|
+
wrapped[CONSUMER_WRAPPED_TAG] = true;
|
|
549
|
+
return wrapped;
|
|
550
|
+
}
|
|
551
|
+
if (isFunction(fn)) {
|
|
552
|
+
const handler = fn;
|
|
553
|
+
const wrapped = (value) => {
|
|
554
|
+
return wrapWithTransforms(
|
|
555
|
+
value,
|
|
556
|
+
registerValue,
|
|
557
|
+
(coerced) => handler(coerced, registerValue),
|
|
558
|
+
void 0
|
|
559
|
+
);
|
|
560
|
+
};
|
|
561
|
+
wrapped[CONSUMER_WRAPPED_TAG] = true;
|
|
562
|
+
return wrapped;
|
|
563
|
+
}
|
|
564
|
+
const defaultAssigner = (value) => {
|
|
565
|
+
if (value === void 0 && registerValue.acceptsUndefined) {
|
|
566
|
+
return registerValue.setValueWithInternalPath(void 0);
|
|
567
|
+
}
|
|
568
|
+
return wrapWithTransforms(
|
|
569
|
+
value,
|
|
570
|
+
registerValue,
|
|
571
|
+
(coerced) => registerValue.setValueWithInternalPath(coerced),
|
|
572
|
+
el._syncFromStorage
|
|
573
|
+
);
|
|
574
|
+
};
|
|
575
|
+
defaultAssigner[DEFAULT_ASSIGNER_TAG] = true;
|
|
576
|
+
return defaultAssigner;
|
|
577
|
+
};
|
|
578
|
+
function makeNoopAssigner() {
|
|
579
|
+
const noop = (_) => void 0;
|
|
580
|
+
noop[DEFAULT_ASSIGNER_TAG] = true;
|
|
581
|
+
return noop;
|
|
582
|
+
}
|
|
583
|
+
function setAssignFunction(el, vnode, value) {
|
|
584
|
+
const current = el[assignKey];
|
|
585
|
+
if (current !== void 0 && !isDefaultAssigner(current) && !isConsumerWrapped(current)) {
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
if (value === void 0) {
|
|
589
|
+
el[assignKey] = makeNoopAssigner();
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
if (!isRegisterValue(value)) {
|
|
593
|
+
vue.warn(
|
|
594
|
+
`v-register expected a RegisterValue, got '${typeof value}'. Bind to form.register('field') \u2014 not the field's ref, value, or path string.`
|
|
595
|
+
);
|
|
596
|
+
el[assignKey] = makeNoopAssigner();
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
el[assignKey] = getModelAssigner(el, vnode, value);
|
|
600
|
+
}
|
|
601
|
+
|
|
509
602
|
function isBlankFileValue(value) {
|
|
510
603
|
if (value === null || value === void 0) return true;
|
|
511
604
|
if (Array.isArray(value) && value.length === 0) return true;
|
|
@@ -513,6 +606,11 @@ function isBlankFileValue(value) {
|
|
|
513
606
|
return true;
|
|
514
607
|
return false;
|
|
515
608
|
}
|
|
609
|
+
function isMultipleInput(el, vnode) {
|
|
610
|
+
if (el.multiple) return true;
|
|
611
|
+
const authored = vnode.props?.["multiple"];
|
|
612
|
+
return authored === true || authored === "";
|
|
613
|
+
}
|
|
516
614
|
function readFilesFromInput(el) {
|
|
517
615
|
const files = el.files;
|
|
518
616
|
if (el.multiple) {
|
|
@@ -538,21 +636,25 @@ function maybeWarnPersistedFile(value) {
|
|
|
538
636
|
}
|
|
539
637
|
const fileScopeKey = Symbol.for("attaform:file-scope");
|
|
540
638
|
const vRegisterFile = {
|
|
541
|
-
created(el, { value }) {
|
|
639
|
+
created(el, { value }, vnode) {
|
|
542
640
|
if (!isRegisterValue(value)) return;
|
|
543
641
|
const input = el;
|
|
544
642
|
value.registerElement(input);
|
|
643
|
+
setAssignFunction(input, vnode, value);
|
|
545
644
|
maybeWarnPersistedFile(value);
|
|
546
645
|
const currentRaw = value.innerRef.value;
|
|
547
646
|
if (isBlankFileValue(currentRaw)) {
|
|
548
|
-
const blankShape = input
|
|
647
|
+
const blankShape = isMultipleInput(input, vnode) ? [] : null;
|
|
549
648
|
value.setValueWithInternalPath(blankShape, { blank: true });
|
|
550
649
|
}
|
|
551
650
|
addTrackedListener(input, "change", () => {
|
|
552
651
|
noteInteraction(value);
|
|
553
652
|
const next = readFilesFromInput(input);
|
|
554
|
-
|
|
555
|
-
|
|
653
|
+
if (isBlankFileValue(next)) {
|
|
654
|
+
value.setValueWithInternalPath(next, { blank: true });
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
fireAssigner(input, value, next);
|
|
556
658
|
});
|
|
557
659
|
const scope = vue.effectScope(true);
|
|
558
660
|
scope.run(() => {
|
|
@@ -572,7 +674,7 @@ const vRegisterFile = {
|
|
|
572
674
|
if (!isRegisterValue(value)) return;
|
|
573
675
|
const input = el;
|
|
574
676
|
const currentRaw = value.innerRef.value;
|
|
575
|
-
if (isBlankFileValue(currentRaw)) {
|
|
677
|
+
if (isBlankFileValue(currentRaw) && !isTransforming(value)) {
|
|
576
678
|
value.setValueWithInternalPath(currentRaw, { blank: true });
|
|
577
679
|
if (input.value !== "") input.value = "";
|
|
578
680
|
}
|
|
@@ -841,136 +943,48 @@ function syncElementRegistration(el, value, oldValue) {
|
|
|
841
943
|
}
|
|
842
944
|
}
|
|
843
945
|
|
|
946
|
+
const valueSyncScopeKey = Symbol.for("attaform:value-sync-scope");
|
|
947
|
+
function isElementFocused(el) {
|
|
948
|
+
const rootNode = el.getRootNode();
|
|
949
|
+
const activeElement = rootNode instanceof Document || rootNode instanceof ShadowRoot ? rootNode.activeElement : null;
|
|
950
|
+
return activeElement === el;
|
|
951
|
+
}
|
|
952
|
+
function setupValueSync(el, source, apply, options = {}) {
|
|
953
|
+
const skipWhileFocused = options.skipWhileFocused === true;
|
|
954
|
+
const scope = vue.effectScope(true);
|
|
955
|
+
scope.run(() => {
|
|
956
|
+
vue.watch(
|
|
957
|
+
source,
|
|
958
|
+
() => {
|
|
959
|
+
if (el.composing === true) return;
|
|
960
|
+
if (skipWhileFocused && isElementFocused(el)) return;
|
|
961
|
+
apply();
|
|
962
|
+
},
|
|
963
|
+
{ flush: "post" }
|
|
964
|
+
);
|
|
965
|
+
});
|
|
966
|
+
el[valueSyncScopeKey] = () => scope.stop();
|
|
967
|
+
}
|
|
968
|
+
function teardownValueSync(el) {
|
|
969
|
+
const carrier = el;
|
|
970
|
+
const stop = carrier[valueSyncScopeKey];
|
|
971
|
+
if (stop === void 0) return;
|
|
972
|
+
stop();
|
|
973
|
+
delete carrier[valueSyncScopeKey];
|
|
974
|
+
}
|
|
975
|
+
|
|
844
976
|
const INTERACTIVE_TAG_NAMES = /* @__PURE__ */ new Set(["INPUT", "SELECT", "TEXTAREA"]);
|
|
845
977
|
|
|
846
|
-
const assignKey = Symbol.for("attaform:assign-key");
|
|
847
|
-
function isRegisterValue(val) {
|
|
848
|
-
if (typeof val !== "object" || val === null) return false;
|
|
849
|
-
if (!("innerRef" in val)) return false;
|
|
850
|
-
if (!vue.isRef(val.innerRef)) return false;
|
|
851
|
-
if (!("registerElement" in val)) return false;
|
|
852
|
-
if (typeof val.registerElement !== "function") return false;
|
|
853
|
-
if (!("setValueWithInternalPath" in val)) return false;
|
|
854
|
-
if (typeof val.setValueWithInternalPath !== "function") return false;
|
|
855
|
-
return true;
|
|
856
|
-
}
|
|
857
978
|
function writeLastTypedForm(rv, next) {
|
|
858
979
|
rv.lastTypedForm.value = next;
|
|
859
980
|
}
|
|
860
|
-
const DEFAULT_ASSIGNER_TAG = Symbol.for("attaform:default-assigner-tag");
|
|
861
|
-
function isDefaultAssigner(fn) {
|
|
862
|
-
return typeof fn === "function" && fn[DEFAULT_ASSIGNER_TAG] === true;
|
|
863
|
-
}
|
|
864
|
-
const CONSUMER_WRAPPED_TAG = Symbol.for("attaform:consumer-wrapped-assigner");
|
|
865
|
-
function isConsumerWrapped(fn) {
|
|
866
|
-
return typeof fn === "function" && fn[CONSUMER_WRAPPED_TAG] === true;
|
|
867
|
-
}
|
|
868
|
-
function fireAssigner(el, registerValue, value) {
|
|
869
|
-
const fn = el[assignKey];
|
|
870
|
-
if (fn === void 0) return void 0;
|
|
871
|
-
if (isDefaultAssigner(fn) || isConsumerWrapped(fn)) {
|
|
872
|
-
return fn(value);
|
|
873
|
-
}
|
|
874
|
-
if (!isRegisterValue(registerValue)) {
|
|
875
|
-
return fn(value, void 0);
|
|
876
|
-
}
|
|
877
|
-
const r = runTransforms(value, registerValue);
|
|
878
|
-
if (!r.ok) return false;
|
|
879
|
-
const coerced = applyCoerce(r.value, registerValue);
|
|
880
|
-
return fn(coerced, registerValue);
|
|
881
|
-
}
|
|
882
981
|
function shouldBailListener(el) {
|
|
883
982
|
if (INTERACTIVE_TAG_NAMES.has(el.tagName)) return false;
|
|
884
983
|
return isDefaultAssigner(el[assignKey]);
|
|
885
984
|
}
|
|
886
|
-
function runTransforms(initial, registerValue) {
|
|
887
|
-
const transforms = registerValue.transforms;
|
|
888
|
-
if (transforms === void 0 || transforms.length === 0) {
|
|
889
|
-
return { ok: true, value: initial };
|
|
890
|
-
}
|
|
891
|
-
let v = initial;
|
|
892
|
-
for (let i = 0; i < transforms.length; i++) {
|
|
893
|
-
const fn = transforms[i];
|
|
894
|
-
try {
|
|
895
|
-
v = fn(v);
|
|
896
|
-
} catch (err) {
|
|
897
|
-
logTransformFailure(registerValue.path, i, fn, err);
|
|
898
|
-
return { ok: false };
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
if (v instanceof Promise) {
|
|
902
|
-
logTransformAsync(registerValue.path);
|
|
903
|
-
return { ok: false };
|
|
904
|
-
}
|
|
905
|
-
return { ok: true, value: v };
|
|
906
|
-
}
|
|
907
|
-
function logTransformFailure(path, index, fn, err) {
|
|
908
|
-
if (__DEV__) {
|
|
909
|
-
const namePart = fn.name !== "" ? `, '${fn.name}'` : "";
|
|
910
|
-
console.error(
|
|
911
|
-
`[attaform] transform threw for path '${path}' (index ${index}${namePart}) \u2014 write aborted. Transforms must not throw; wrap your own try/catch if the throw is recoverable. Original error:`,
|
|
912
|
-
err
|
|
913
|
-
);
|
|
914
|
-
} else {
|
|
915
|
-
console.error(
|
|
916
|
-
`[attaform] transform error \u2014 write aborted (set NODE_ENV=development for details).`
|
|
917
|
-
);
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
function applyCoerce(value, registerValue) {
|
|
921
|
-
return registerValue.coerce !== void 0 ? registerValue.coerce(value) : value;
|
|
922
|
-
}
|
|
923
985
|
function applyElementCoerce(value, registerValue) {
|
|
924
986
|
return registerValue.coerceElement !== void 0 ? registerValue.coerceElement(value) : value;
|
|
925
987
|
}
|
|
926
|
-
function logTransformAsync(path) {
|
|
927
|
-
if (__DEV__) {
|
|
928
|
-
console.error(
|
|
929
|
-
`[attaform] transform pipeline for path '${path}' returned a Promise \u2014 transforms must be sync. Use async field validation for canonicalize-before-write patterns. Write aborted.`
|
|
930
|
-
);
|
|
931
|
-
} else {
|
|
932
|
-
console.error(
|
|
933
|
-
`[attaform] transform error \u2014 write aborted (set NODE_ENV=development for details).`
|
|
934
|
-
);
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
const getModelAssigner = (vnode, registerValue) => {
|
|
938
|
-
const fn = vnode.props?.["onUpdate:registerValue"] ?? vnode.props?.["on:update:registerValue"];
|
|
939
|
-
if (isArray(fn)) {
|
|
940
|
-
const fnArr = fn.filter((x) => isFunction(x));
|
|
941
|
-
const wrapped = (value) => {
|
|
942
|
-
const r = runTransforms(value, registerValue);
|
|
943
|
-
if (!r.ok) return false;
|
|
944
|
-
const coerced = applyCoerce(r.value, registerValue);
|
|
945
|
-
invokeArrayFns(fnArr, coerced, registerValue);
|
|
946
|
-
return void 0;
|
|
947
|
-
};
|
|
948
|
-
wrapped[CONSUMER_WRAPPED_TAG] = true;
|
|
949
|
-
return wrapped;
|
|
950
|
-
}
|
|
951
|
-
if (isFunction(fn)) {
|
|
952
|
-
const handler = fn;
|
|
953
|
-
const wrapped = (value) => {
|
|
954
|
-
const r = runTransforms(value, registerValue);
|
|
955
|
-
if (!r.ok) return false;
|
|
956
|
-
const coerced = applyCoerce(r.value, registerValue);
|
|
957
|
-
return handler(coerced, registerValue);
|
|
958
|
-
};
|
|
959
|
-
wrapped[CONSUMER_WRAPPED_TAG] = true;
|
|
960
|
-
return wrapped;
|
|
961
|
-
}
|
|
962
|
-
const defaultAssigner = (value) => {
|
|
963
|
-
if (value === void 0 && registerValue.acceptsUndefined) {
|
|
964
|
-
return registerValue.setValueWithInternalPath(void 0);
|
|
965
|
-
}
|
|
966
|
-
const r = runTransforms(value, registerValue);
|
|
967
|
-
if (!r.ok) return false;
|
|
968
|
-
const coerced = applyCoerce(r.value, registerValue);
|
|
969
|
-
return registerValue.setValueWithInternalPath(coerced);
|
|
970
|
-
};
|
|
971
|
-
defaultAssigner[DEFAULT_ASSIGNER_TAG] = true;
|
|
972
|
-
return defaultAssigner;
|
|
973
|
-
};
|
|
974
988
|
function onCompositionStart(e) {
|
|
975
989
|
const target = e.target;
|
|
976
990
|
if (!target) return;
|
|
@@ -983,29 +997,6 @@ function onCompositionEnd(e) {
|
|
|
983
997
|
target.dispatchEvent(new Event("input"));
|
|
984
998
|
}
|
|
985
999
|
}
|
|
986
|
-
function makeNoopAssigner() {
|
|
987
|
-
const noop = (_) => void 0;
|
|
988
|
-
noop[DEFAULT_ASSIGNER_TAG] = true;
|
|
989
|
-
return noop;
|
|
990
|
-
}
|
|
991
|
-
function setAssignFunction(el, vnode, value) {
|
|
992
|
-
const current = el[assignKey];
|
|
993
|
-
if (current !== void 0 && !isDefaultAssigner(current) && !isConsumerWrapped(current)) {
|
|
994
|
-
return;
|
|
995
|
-
}
|
|
996
|
-
if (value === void 0) {
|
|
997
|
-
el[assignKey] = makeNoopAssigner();
|
|
998
|
-
return;
|
|
999
|
-
}
|
|
1000
|
-
if (!isRegisterValue(value)) {
|
|
1001
|
-
vue.warn(
|
|
1002
|
-
`v-register expected a RegisterValue, got '${typeof value}'. Bind to form.register('field') \u2014 not the field's ref, value, or path string.`
|
|
1003
|
-
);
|
|
1004
|
-
el[assignKey] = makeNoopAssigner();
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
|
-
el[assignKey] = getModelAssigner(vnode, value);
|
|
1008
|
-
}
|
|
1009
1000
|
const vRegisterText = {
|
|
1010
1001
|
created(el, { value, modifiers: { lazy, trim, number } }, vnode) {
|
|
1011
1002
|
const castToNumberAtCreated = number === true || vnode.props?.["type"] === "number";
|
|
@@ -1014,6 +1005,13 @@ const vRegisterText = {
|
|
|
1014
1005
|
value.registerElement(el);
|
|
1015
1006
|
setAssignFunction(el, vnode, value);
|
|
1016
1007
|
}
|
|
1008
|
+
el._syncFromStorage = () => {
|
|
1009
|
+
if (!isRegisterValue(value)) return;
|
|
1010
|
+
const storage = value.innerRef.value;
|
|
1011
|
+
const display = storage == null ? "" : String(storage);
|
|
1012
|
+
if (el.value !== display) el.value = display;
|
|
1013
|
+
if (liveCastToNumber()) writeLastTypedForm(value, null);
|
|
1014
|
+
};
|
|
1017
1015
|
addTrackedListener(el, lazy === true ? "change" : "input", (e) => {
|
|
1018
1016
|
if (shouldBailListener(el)) return;
|
|
1019
1017
|
const target = e.target;
|
|
@@ -1061,7 +1059,7 @@ const vRegisterText = {
|
|
|
1061
1059
|
}
|
|
1062
1060
|
const commit = domValue === "" && isRegisterValue(value) && value.acceptsUndefined ? void 0 : domValue;
|
|
1063
1061
|
fireAssigner(el, value, commit);
|
|
1064
|
-
if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {
|
|
1062
|
+
if (isRegisterValue(value) && isDefaultAssigner(el[assignKey]) && !isTransforming(value)) {
|
|
1065
1063
|
const storage = value.innerRef.value;
|
|
1066
1064
|
if (storage !== domValue) {
|
|
1067
1065
|
const display = storage == null ? "" : String(storage);
|
|
@@ -1121,6 +1119,15 @@ const vRegisterText = {
|
|
|
1121
1119
|
mounted(el, { value }) {
|
|
1122
1120
|
if (!isRegisterValue(value)) return;
|
|
1123
1121
|
el.value = value.displayValue.value;
|
|
1122
|
+
setupValueSync(
|
|
1123
|
+
el,
|
|
1124
|
+
value.displayValue,
|
|
1125
|
+
() => {
|
|
1126
|
+
const next = value.displayValue.value;
|
|
1127
|
+
if (el.value !== next) el.value = next;
|
|
1128
|
+
},
|
|
1129
|
+
{ skipWhileFocused: true }
|
|
1130
|
+
);
|
|
1124
1131
|
},
|
|
1125
1132
|
beforeUpdate(el, { value, oldValue, modifiers: { lazy, trim } }, vnode) {
|
|
1126
1133
|
setAssignFunction(el, vnode, value);
|
|
@@ -1150,6 +1157,11 @@ const vRegisterCheckbox = {
|
|
|
1150
1157
|
if (!isRegisterValue(value)) return;
|
|
1151
1158
|
value.registerElement(el);
|
|
1152
1159
|
setAssignFunction(el, vnode, value);
|
|
1160
|
+
el._syncFromStorage = () => {
|
|
1161
|
+
if (!isRegisterValue(value)) return;
|
|
1162
|
+
setChecked(el, value);
|
|
1163
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
1164
|
+
};
|
|
1153
1165
|
addTrackedListener(el, "change", () => {
|
|
1154
1166
|
if (shouldBailListener(el)) return;
|
|
1155
1167
|
noteInteraction(value);
|
|
@@ -1192,7 +1204,7 @@ const vRegisterCheckbox = {
|
|
|
1192
1204
|
} else {
|
|
1193
1205
|
fireAssigner(el, value, getCheckboxValue(el, checked));
|
|
1194
1206
|
}
|
|
1195
|
-
if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {
|
|
1207
|
+
if (isRegisterValue(value) && isDefaultAssigner(el[assignKey]) && !isTransforming(value)) {
|
|
1196
1208
|
setChecked(el, value);
|
|
1197
1209
|
el._lastAppliedModel = value.innerRef.value;
|
|
1198
1210
|
}
|
|
@@ -1201,7 +1213,12 @@ const vRegisterCheckbox = {
|
|
|
1201
1213
|
// set initial checked on mount to wait for true-value/false-value
|
|
1202
1214
|
mounted(el, { value }) {
|
|
1203
1215
|
setChecked(el, value);
|
|
1204
|
-
if (isRegisterValue(value))
|
|
1216
|
+
if (!isRegisterValue(value)) return;
|
|
1217
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
1218
|
+
setupValueSync(el, value.innerRef, () => {
|
|
1219
|
+
setChecked(el, value);
|
|
1220
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
1221
|
+
});
|
|
1205
1222
|
},
|
|
1206
1223
|
// Skip the DOM sync when the model is identity-unchanged from the
|
|
1207
1224
|
// last application. Pre-fix the scalar branch in `setChecked`
|
|
@@ -1247,11 +1264,18 @@ const vRegisterRadio = {
|
|
|
1247
1264
|
if (!isRegisterValue(value)) return;
|
|
1248
1265
|
value.registerElement(el);
|
|
1249
1266
|
setAssignFunction(el, vnode, value);
|
|
1267
|
+
el._syncFromStorage = () => {
|
|
1268
|
+
if (!isRegisterValue(value)) return;
|
|
1269
|
+
const currentModel = value.innerRef.value;
|
|
1270
|
+
const target = looseEqual(currentModel, applyCoerce(getValue(el), value));
|
|
1271
|
+
if (el.checked !== target) el.checked = target;
|
|
1272
|
+
el._lastAppliedModel = currentModel;
|
|
1273
|
+
};
|
|
1250
1274
|
addTrackedListener(el, "change", () => {
|
|
1251
1275
|
if (shouldBailListener(el)) return;
|
|
1252
1276
|
noteInteraction(value);
|
|
1253
1277
|
fireAssigner(el, value, getValue(el));
|
|
1254
|
-
if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {
|
|
1278
|
+
if (isRegisterValue(value) && isDefaultAssigner(el[assignKey]) && !isTransforming(value)) {
|
|
1255
1279
|
const currentModel = value.innerRef.value;
|
|
1256
1280
|
const target = looseEqual(currentModel, applyCoerce(getValue(el), value));
|
|
1257
1281
|
if (el.checked !== target) el.checked = target;
|
|
@@ -1270,6 +1294,10 @@ const vRegisterRadio = {
|
|
|
1270
1294
|
if (!isRegisterValue(value)) return;
|
|
1271
1295
|
el.checked = looseEqual(value.innerRef.value, applyCoerce(getValue(el), value));
|
|
1272
1296
|
el._lastAppliedModel = value.innerRef.value;
|
|
1297
|
+
setupValueSync(el, value.innerRef, () => {
|
|
1298
|
+
el.checked = looseEqual(value.innerRef.value, applyCoerce(getValue(el), value));
|
|
1299
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
1300
|
+
});
|
|
1273
1301
|
},
|
|
1274
1302
|
// Skip the DOM sync when the model is identity-unchanged from the
|
|
1275
1303
|
// last application. Pre-fix the guard read `value.innerRef.value
|
|
@@ -1295,6 +1323,11 @@ const vRegisterSelect = {
|
|
|
1295
1323
|
created(el, { value, modifiers: { number } }, vnode) {
|
|
1296
1324
|
if (!isRegisterValue(value)) return;
|
|
1297
1325
|
value.registerElement(el);
|
|
1326
|
+
el._syncFromStorage = () => {
|
|
1327
|
+
if (!isRegisterValue(value)) return;
|
|
1328
|
+
setSelected(el, value);
|
|
1329
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
1330
|
+
};
|
|
1298
1331
|
addTrackedListener(el, "change", () => {
|
|
1299
1332
|
if (shouldBailListener(el)) return;
|
|
1300
1333
|
noteInteraction(value);
|
|
@@ -1311,7 +1344,7 @@ const vRegisterSelect = {
|
|
|
1311
1344
|
el._assigning = false;
|
|
1312
1345
|
});
|
|
1313
1346
|
}
|
|
1314
|
-
if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {
|
|
1347
|
+
if (isRegisterValue(value) && isDefaultAssigner(el[assignKey]) && !isTransforming(value)) {
|
|
1315
1348
|
setSelected(el, value);
|
|
1316
1349
|
el._lastAppliedModel = value.innerRef.value;
|
|
1317
1350
|
}
|
|
@@ -1322,7 +1355,13 @@ const vRegisterSelect = {
|
|
|
1322
1355
|
// <option>s.
|
|
1323
1356
|
mounted(el, { value }) {
|
|
1324
1357
|
setSelected(el, value);
|
|
1325
|
-
if (isRegisterValue(value))
|
|
1358
|
+
if (!isRegisterValue(value)) return;
|
|
1359
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
1360
|
+
setupValueSync(el, value.innerRef, () => {
|
|
1361
|
+
if (el._assigning === true) return;
|
|
1362
|
+
setSelected(el, value);
|
|
1363
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
1364
|
+
});
|
|
1326
1365
|
},
|
|
1327
1366
|
beforeUpdate(el, binding, vnode) {
|
|
1328
1367
|
setAssignFunction(el, vnode, binding.value);
|
|
@@ -1420,6 +1459,9 @@ const vRegisterDynamic = {
|
|
|
1420
1459
|
syncMultiTabOptOut(binding.value, void 0);
|
|
1421
1460
|
callModelHook(el, binding, vnode, null, "created");
|
|
1422
1461
|
if (isRegisterValue(binding.value)) setupAria(el, binding.value, vnode);
|
|
1462
|
+
},
|
|
1463
|
+
mounted(el, binding, vnode) {
|
|
1464
|
+
callModelHook(el, binding, vnode, null, "mounted");
|
|
1423
1465
|
if (__DEV__ && warnedUnsupportedElements !== null && !INTERACTIVE_TAG_NAMES.has(el.tagName) && !warnedUnsupportedElements.has(el)) {
|
|
1424
1466
|
void vue.nextTick(() => {
|
|
1425
1467
|
if (warnedUnsupportedElements.has(el)) return;
|
|
@@ -1435,9 +1477,6 @@ const vRegisterDynamic = {
|
|
|
1435
1477
|
});
|
|
1436
1478
|
}
|
|
1437
1479
|
},
|
|
1438
|
-
mounted(el, binding, vnode) {
|
|
1439
|
-
callModelHook(el, binding, vnode, null, "mounted");
|
|
1440
|
-
},
|
|
1441
1480
|
beforeUpdate(el, binding, vnode, prevVNode) {
|
|
1442
1481
|
syncPersistOptIn(el, binding.value, binding.oldValue, vnode.props?.["type"]);
|
|
1443
1482
|
syncMultiTabOptOut(binding.value, binding.oldValue);
|
|
@@ -1465,6 +1504,7 @@ const vRegisterDynamic = {
|
|
|
1465
1504
|
beforeUnmount(el, { value }) {
|
|
1466
1505
|
removeTrackedListeners(el);
|
|
1467
1506
|
teardownAria(el);
|
|
1507
|
+
teardownValueSync(el);
|
|
1468
1508
|
if (isRegisterValue(value)) {
|
|
1469
1509
|
value.persistOptIns.removeAllFor(getOrAssignElementId(el));
|
|
1470
1510
|
value.unmarkNoSync?.();
|
|
@@ -1473,6 +1513,7 @@ const vRegisterDynamic = {
|
|
|
1473
1513
|
value.deregisterElement(el);
|
|
1474
1514
|
delete el.composing;
|
|
1475
1515
|
delete el._assigning;
|
|
1516
|
+
delete el._syncFromStorage;
|
|
1476
1517
|
delete el[assignKey];
|
|
1477
1518
|
},
|
|
1478
1519
|
// The lifecycle hooks above don't run on the server (Vue skips
|
|
@@ -1485,7 +1526,11 @@ const vRegisterDynamic = {
|
|
|
1485
1526
|
getSSRProps(binding, vnode) {
|
|
1486
1527
|
const rv = binding.value;
|
|
1487
1528
|
if (!isRegisterValue(rv)) return void 0;
|
|
1488
|
-
|
|
1529
|
+
const realVnode = vnode ?? null;
|
|
1530
|
+
const ariaProps = getSSRAriaProps(rv, realVnode);
|
|
1531
|
+
const formStateProps = realVnode !== null ? getSSRFormStateProps(rv, realVnode) : void 0;
|
|
1532
|
+
if (ariaProps === void 0 && formStateProps === void 0) return void 0;
|
|
1533
|
+
return { ...ariaProps, ...formStateProps };
|
|
1489
1534
|
}
|
|
1490
1535
|
};
|
|
1491
1536
|
function resolveDynamicModel(tagName, type) {
|
|
@@ -1497,12 +1542,38 @@ function resolveDynamicModel(tagName, type) {
|
|
|
1497
1542
|
if (type === "radio") return vRegisterRadio;
|
|
1498
1543
|
return vRegisterText;
|
|
1499
1544
|
}
|
|
1545
|
+
function ssrCheckboxProps(rv, props) {
|
|
1546
|
+
const model = rv.innerRef.value;
|
|
1547
|
+
const optionValue = props?.["value"];
|
|
1548
|
+
let checked;
|
|
1549
|
+
if (isArray(model)) {
|
|
1550
|
+
checked = looseIndexOf(model, applyElementCoerce(optionValue, rv)) > -1;
|
|
1551
|
+
} else if (isSet(model)) {
|
|
1552
|
+
checked = model.has(applyElementCoerce(optionValue, rv));
|
|
1553
|
+
} else {
|
|
1554
|
+
const trueValue = props !== null && "true-value" in props ? props["true-value"] : true;
|
|
1555
|
+
checked = looseEqual(model, applyCoerce(trueValue, rv));
|
|
1556
|
+
}
|
|
1557
|
+
return checked ? { checked: "" } : void 0;
|
|
1558
|
+
}
|
|
1559
|
+
function getSSRFormStateProps(rv, vnode) {
|
|
1560
|
+
if (typeof vnode.type !== "string") return void 0;
|
|
1561
|
+
const props = vnode.props ?? null;
|
|
1562
|
+
const variant = resolveDynamicModel(vnode.type.toUpperCase(), props?.["type"]);
|
|
1563
|
+
if (variant === vRegisterFile || variant === vRegisterSelect) return void 0;
|
|
1564
|
+
if (variant === vRegisterCheckbox) return ssrCheckboxProps(rv, props);
|
|
1565
|
+
if (variant === vRegisterRadio) {
|
|
1566
|
+
const matches = looseEqual(rv.innerRef.value, applyCoerce(props?.["value"], rv));
|
|
1567
|
+
return matches ? { checked: "" } : void 0;
|
|
1568
|
+
}
|
|
1569
|
+
const value = rv.displayValue.value;
|
|
1570
|
+
return value === "" ? void 0 : { value };
|
|
1571
|
+
}
|
|
1500
1572
|
function callModelHook(el, binding, vnode, prevVNode, hook) {
|
|
1501
1573
|
const modelToUse = resolveDynamicModel(el.tagName, vnode.props?.["type"]);
|
|
1502
1574
|
const fn = modelToUse[hook];
|
|
1503
1575
|
fn?.(el, binding, vnode, prevVNode);
|
|
1504
1576
|
}
|
|
1505
|
-
const V_REGISTER_MARKER = Symbol.for("attaform:v-register-directive");
|
|
1506
1577
|
const vRegister = vRegisterDynamic;
|
|
1507
1578
|
vRegisterDynamic[V_REGISTER_MARKER] = true;
|
|
1508
1579
|
|
|
@@ -1658,16 +1729,17 @@ exports.INTERACTIVE_TAG_NAMES = INTERACTIVE_TAG_NAMES;
|
|
|
1658
1729
|
exports.InvalidPathError = InvalidPathError;
|
|
1659
1730
|
exports.InvalidUseFormConfigError = InvalidUseFormConfigError;
|
|
1660
1731
|
exports.OutsideSetupError = OutsideSetupError;
|
|
1732
|
+
exports.REGISTER_OWNER_MARKER = REGISTER_OWNER_MARKER;
|
|
1661
1733
|
exports.ROOT_PATH = ROOT_PATH;
|
|
1662
1734
|
exports.ROOT_PATH_KEY = ROOT_PATH_KEY;
|
|
1663
1735
|
exports.RegistryNotInstalledError = RegistryNotInstalledError;
|
|
1664
1736
|
exports.ReservedFormKeyError = ReservedFormKeyError;
|
|
1665
1737
|
exports.SubmitErrorHandlerError = SubmitErrorHandlerError;
|
|
1738
|
+
exports.V_REGISTER_MARKER = V_REGISTER_MARKER;
|
|
1666
1739
|
exports.__DEV__ = __DEV__;
|
|
1667
1740
|
exports.allowSensitivePersist = allowSensitivePersist;
|
|
1668
1741
|
exports.assignKey = assignKey;
|
|
1669
1742
|
exports.canonicalizePath = canonicalizePath;
|
|
1670
|
-
exports.captureUserCallSite = captureUserCallSite;
|
|
1671
1743
|
exports.coerceToPathKey = coerceToPathKey;
|
|
1672
1744
|
exports.createAttaform = createAttaform;
|
|
1673
1745
|
exports.createIsSensitivePath = createIsSensitivePath;
|
|
@@ -1687,7 +1759,7 @@ exports.kFormInstanceId = kFormInstanceId;
|
|
|
1687
1759
|
exports.parseDottedPath = parseDottedPath;
|
|
1688
1760
|
exports.pathKeyToDotted = pathKeyToDotted;
|
|
1689
1761
|
exports.segmentsForPathKey = segmentsForPathKey;
|
|
1690
|
-
exports.
|
|
1762
|
+
exports.toError = toError;
|
|
1691
1763
|
exports.useRegistry = useRegistry;
|
|
1692
1764
|
exports.vRegister = vRegister;
|
|
1693
|
-
//# sourceMappingURL=attaform.
|
|
1765
|
+
//# sourceMappingURL=attaform.B5LNzqQh.cjs.map
|