diff --git a/playground/app.vue b/playground/app.vue index a8bd3fc..4c8ae9f 100644 --- a/playground/app.vue +++ b/playground/app.vue @@ -5,13 +5,25 @@ import { z } from "zod" const schema = z.object({ planet: z.string() }) // Create your form with a unique key -const { getFieldState, register, key } = useForm({ +const { getFieldState, register, key, setValue } = useForm({ schema, key: "planet-form-key", }) // Get the state of the 'planet' field const planetState = getFieldState("planet") +const hideInput = ref(false) + +// random operation to demonstrate updating the planet field programmatically +function updateVal(testUpdate: boolean) { + setValue("planet", (v) => { + const [base, count] = v.split(".") + const recoveredNum = Number(count ?? 0) + const safeNum = Number.isNaN(recoveredNum) ? 0 : recoveredNum + const BASE_DEFAULT = "Jupiter" + return testUpdate ? `${base || BASE_DEFAULT}.${safeNum + 1}` : v + }) +} diff --git a/src/runtime/lib/core/composables/use-meta-tracker-store.ts b/src/runtime/lib/core/composables/use-meta-tracker-store.ts index a3e0b89..db23d38 100644 --- a/src/runtime/lib/core/composables/use-meta-tracker-store.ts +++ b/src/runtime/lib/core/composables/use-meta-tracker-store.ts @@ -1,6 +1,4 @@ -// import { useState } from "#app" -// import { useState } from "nuxt/app" -import { merge } from "lodash-es" +import { isEqual, merge } from "lodash-es" import { useState } from "nuxt/app" import { computed } from "vue" import type { @@ -41,8 +39,11 @@ export function updateMetaTracker(config: UpdateMetaTrackerConfig) { = typeof basePath === "string" ? metaTracker[basePath]?.updatedAt ?? null : null + + const hasRawValueChanged = basePath === null ? true : !isEqual(metaTracker[basePath]?.rawValue, rawValue) + const newTime = hasRawValueChanged ? new Date().toISOString() : lastKnownTime const updatedAt - = updateTime ?? true ? new Date().toISOString() : lastKnownTime + = (updateTime ?? true) ? newTime : lastKnownTime const flattenedObject = flattenObjectWithBaseKey( rawValue, diff --git a/src/runtime/lib/core/utils/register.ts b/src/runtime/lib/core/utils/register.ts index 9d84764..53923ca 100644 --- a/src/runtime/lib/core/utils/register.ts +++ b/src/runtime/lib/core/utils/register.ts @@ -56,7 +56,6 @@ export function registerFactory
( basePath: path, metaTracker: metaTracker.value, rawValue: metaTracker.value?.[path]?.rawValue ?? get(form, path), - updateTime: false, isConnected: true, }) } @@ -72,7 +71,6 @@ export function registerFactory( basePath: path, metaTracker: metaTracker.value, rawValue: metaTracker.value?.[path]?.rawValue ?? get(form, path), - updateTime: false, // for consistency, only recompute `updatedAt` when form value changes isConnected: !!remainingElementCount, // only mark as disconnected if all elements are unmounted }) }, diff --git a/src/runtime/types/types-api.ts b/src/runtime/types/types-api.ts index b2753c9..f9b1069 100644 --- a/src/runtime/types/types-api.ts +++ b/src/runtime/types/types-api.ts @@ -134,16 +134,36 @@ export type CustomRegisterDirective = Obje [S: symbol]: CustomDirectiveRegisterAssignerFn }, RegisterValue, Modifiers, string> +// bring in this RegisterModelDynamicCustomDirective type once PR #12605 in vuejs/core enters production (currently in main but not released) +// https://github.com/vuejs/core/pull/12605 +// export type RegisterTextCustomDirective = CustomRegisterDirective< +// HTMLInputElement | HTMLTextAreaElement, +// "trim" | "number" | "lazy" +// > + export type RegisterTextCustomDirective = CustomRegisterDirective< -HTMLInputElement | HTMLTextAreaElement, -"trim" | "number" | "lazy" + HTMLInputElement | HTMLTextAreaElement, string > export type RegisterCheckboxCustomDirective = CustomRegisterDirective export type RegisterRadioCustomDirective = CustomRegisterDirective -export type RegisterSelectCustomDirective = CustomRegisterDirective + +// bring in this RegisterModelDynamicCustomDirective type once PR #12605 in vuejs/core enters production (currently in main but not released) +// https://github.com/vuejs/core/pull/12605 +// export type RegisterTextCustomDirective = CustomRegisterDirective< +// HTMLInputElement | HTMLTextAreaElement, +// "trim" | "number" | "lazy" +// > +// export type RegisterSelectCustomDirective = CustomRegisterDirective +export type RegisterSelectCustomDirective = CustomRegisterDirective + +// bring in this RegisterModelDynamicCustomDirective type once PR #12605 in vuejs/core enters production (currently in main but not released) +// https://github.com/vuejs/core/pull/12605 +// export type RegisterModelDynamicCustomDirective = ObjectDirective< +// HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, RegisterValue, "trim" | "number" | "lazy" +// > export type RegisterModelDynamicCustomDirective = ObjectDirective< -HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, RegisterValue, "trim" | "number" | "lazy" +HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, RegisterValue, string > export type RegisterDirective = | RegisterTextCustomDirective