diff --git a/packages/effect-fc/src/Form.ts b/packages/effect-fc/src/Form.ts index 1febeaa..1cd7773 100644 --- a/packages/effect-fc/src/Form.ts +++ b/packages/effect-fc/src/Form.ts @@ -3,7 +3,7 @@ import { Array, Duration, Effect, Equal, Equivalence, identity, Option, ParseRes import type { NoSuchElementException } from "effect/Cause" import * as React from "react" import { Hooks } from "./hooks/index.js" -import { PropertyPath, Subscribable as SubscribableInternal } from "./types/index.js" +import { PropertyPath, Subscribable as SubscribableInternal, SubscriptionSubRef } from "./types/index.js" export const FormTypeId: unique symbol = Symbol.for("effect-fc/Form") @@ -184,12 +184,41 @@ export const field: { ) { return new FormFieldImpl( pipe( - (value: Option.Option) => Option.map(value, v => PropertyPath.get(v, path)), + (v: Option.Option) => Option.match(v, { + onSome: PropertyPath.get(path), + onNone: () => Option.none(), + }), filter => SubscribableInternal.make({ get: Effect.flatMap(self.valueRef, filter), get changes() { return Stream.flatMap(self.valueRef.changes, filter) }, }), - ) + ), + + SubscriptionSubRef.makeFromPath(self.encodedValueRef, path), + + pipe( + Option.match({ + onSome: (v: ParseResult.ParseError) => Effect.andThen( + ParseResult.ArrayFormatter.formatError(v), + Array.filter(issue => PropertyPath.equivalence(issue.path, path)), + ), + onNone: () => Effect.succeed([]), + }), + filter => SubscribableInternal.make({ + get: Effect.flatMap(self.errorRef.get, filter), + get changes() { return Stream.flatMap(self.errorRef.changes, filter) }, + }), + ), + + self.isValidatingRef, + + pipe( + AsyncData.isLoading, + filter => SubscribableInternal.make({ + get: Effect.map(self.submitStateRef, filter), + get changes() { return Stream.map(self.submitStateRef.changes, filter) }, + }), + ), ) })