diff --git a/.changeset/little-planets-bake.md b/.changeset/little-planets-bake.md
new file mode 100644
index 000000000..8ab5b6b64
--- /dev/null
+++ b/.changeset/little-planets-bake.md
@@ -0,0 +1,5 @@
+---
+"@effect-app/vue-components": minor
+---
+
+Restore OmegaForm input reactivity broken by the @tanstack/vue-form 1.32 bump — the Field slot's state prop became a stale snapshot, so bind inputs to the reactive field.state instead.
diff --git a/packages/vue-components/__tests__/OmegaForm/InputReactivity.test.ts b/packages/vue-components/__tests__/OmegaForm/InputReactivity.test.ts
new file mode 100644
index 000000000..37b2b4996
--- /dev/null
+++ b/packages/vue-components/__tests__/OmegaForm/InputReactivity.test.ts
@@ -0,0 +1,49 @@
+import { mount } from "@vue/test-utils"
+import * as S from "effect-app/Schema"
+import { describe, expect, it } from "vitest"
+import { useOmegaForm } from "../../src/components/OmegaForm"
+import OmegaIntlProvider from "../OmegaIntlProvider.vue"
+
+describe("OmegaForm input reactivity", () => {
+ it("reflects value changes from the slot `state` in the view", async () => {
+ const schema = S.Struct({
+ name: S.String
+ })
+
+ const wrapper = mount({
+ components: { OmegaIntlProvider },
+ template: `
+
+
+
+
+ field.handleChange(e.target.value)"
+ />
+ {{ state.value }}
+
+
+
+
+ `,
+ setup() {
+ const form = useOmegaForm(schema, {
+ defaultValues: { name: "" }
+ })
+ return { form }
+ }
+ })
+
+ await wrapper.vm.$nextTick()
+
+ const input = wrapper.find("[data-testid='input']")
+ await input.setValue("hello")
+ await wrapper.vm.$nextTick()
+
+ // The slot `state` must stay in sync with the form store
+ expect(wrapper.find("[data-testid='display']").text()).toBe("hello")
+ expect((input.element as HTMLInputElement).value).toBe("hello")
+ })
+})
diff --git a/packages/vue-components/src/components/OmegaForm/InputProps.ts b/packages/vue-components/src/components/OmegaForm/InputProps.ts
index 090c257ca..eaec0cf14 100644
--- a/packages/vue-components/src/components/OmegaForm/InputProps.ts
+++ b/packages/vue-components/src/components/OmegaForm/InputProps.ts
@@ -43,7 +43,7 @@ export type InputProps, TName extends Deep
inputClass: string | undefined | null
}
field: OmegaFieldInternalApi
- /** be sure to use this state and not `field.state` as it is not reactive */
+ /** reactive field state, sourced from `field.state` (the Field slot's own `state` prop is a stale snapshot since @tanstack/vue-form 1.32) */
state: OmegaFieldInternalApi["state"]
}
diff --git a/packages/vue-components/src/components/OmegaForm/OmegaArray.vue b/packages/vue-components/src/components/OmegaForm/OmegaArray.vue
index f6a630427..ec1ca29eb 100644
--- a/packages/vue-components/src/components/OmegaForm/OmegaArray.vue
+++ b/packages/vue-components/src/components/OmegaForm/OmegaArray.vue
@@ -3,10 +3,11 @@
:is="form.Field"
:name="name"
>
-
+
+
-
+
-
+
+