@@ -70,8 +70,7 @@ export const make: {
|
|||||||
|
|
||||||
|
|
||||||
export namespace useInput {
|
export namespace useInput {
|
||||||
export interface Options<I, P extends PropertyPath.Paths<I>> {
|
export interface Options {
|
||||||
readonly path: P
|
|
||||||
readonly debounce?: Duration.DurationInput
|
readonly debounce?: Duration.DurationInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,21 +82,23 @@ export namespace useInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const useInput: {
|
export const useInput: {
|
||||||
<A, I, R, P extends PropertyPath.Paths<I>>(
|
<A, I, R, const P extends PropertyPath.Paths<I>>(
|
||||||
self: Form<A, I, R>,
|
self: Form<A, I, R>,
|
||||||
options: useInput.Options<NoInfer<I>, P>,
|
path: P,
|
||||||
|
options?: useInput.Options,
|
||||||
): Effect.Effect<useInput.Result<PropertyPath.ValueFromPath<I, P>>, NoSuchElementException, R>
|
): Effect.Effect<useInput.Result<PropertyPath.ValueFromPath<I, P>>, NoSuchElementException, R>
|
||||||
} = Effect.fnUntraced(function* <A, I, R, P extends PropertyPath.Paths<I>>(
|
} = Effect.fnUntraced(function* <A, I, R, const P extends PropertyPath.Paths<I>>(
|
||||||
self: Form<A, I, R>,
|
self: Form<A, I, R>,
|
||||||
options: useInput.Options<NoInfer<I>, P>,
|
path: P,
|
||||||
|
options?: useInput.Options,
|
||||||
) {
|
) {
|
||||||
const [internalValueRef, issuesSubscribable] = yield* Hooks.useMemo(() => Effect.all([
|
const [internalValueRef, issuesSubscribable] = yield* Hooks.useMemo(() => Effect.all([
|
||||||
self.encodedValueRef.pipe(
|
self.encodedValueRef.pipe(
|
||||||
Effect.andThen(PropertyPath.get(options.path)),
|
Effect.andThen(PropertyPath.get(path)),
|
||||||
Effect.andThen(SubscriptionRef.make<PropertyPath.ValueFromPath<I, P>>),
|
Effect.andThen(SubscriptionRef.make<PropertyPath.ValueFromPath<I, P>>),
|
||||||
),
|
),
|
||||||
Effect.succeed(self.makeFieldIssuesSubscribable(options.path)),
|
Effect.succeed(self.makeFieldIssuesSubscribable(path)),
|
||||||
]), [self, ...options.path])
|
]), [self, ...path])
|
||||||
|
|
||||||
const [value, setValue] = yield* Hooks.useRefState(internalValueRef)
|
const [value, setValue] = yield* Hooks.useRefState(internalValueRef)
|
||||||
const [issues] = yield* Hooks.useSubscribe(issuesSubscribable)
|
const [issues] = yield* Hooks.useSubscribe(issuesSubscribable)
|
||||||
@@ -105,12 +106,12 @@ export const useInput: {
|
|||||||
yield* Hooks.useFork(() => Stream.runForEach(
|
yield* Hooks.useFork(() => Stream.runForEach(
|
||||||
internalValueRef.changes.pipe(
|
internalValueRef.changes.pipe(
|
||||||
Stream.changesWith(Equivalence.strict()),
|
Stream.changesWith(Equivalence.strict()),
|
||||||
options.debounce ? Stream.debounce(options.debounce) : identity,
|
options?.debounce ? Stream.debounce(options.debounce) : identity,
|
||||||
Stream.drop(1),
|
Stream.drop(1),
|
||||||
),
|
),
|
||||||
|
|
||||||
internalValue => self.encodedValueRef.pipe(
|
internalValue => self.encodedValueRef.pipe(
|
||||||
Effect.andThen(encodedValue => PropertyPath.immutableSet(encodedValue, options.path, internalValue)),
|
Effect.andThen(encodedValue => PropertyPath.immutableSet(encodedValue, path, internalValue)),
|
||||||
Effect.tap(encodedValue => SubscriptionRef.set(self.encodedValueRef, encodedValue)),
|
Effect.tap(encodedValue => SubscriptionRef.set(self.encodedValueRef, encodedValue)),
|
||||||
Effect.andThen(flow(
|
Effect.andThen(flow(
|
||||||
Schema.decode(self.schema),
|
Schema.decode(self.schema),
|
||||||
@@ -119,7 +120,7 @@ export const useInput: {
|
|||||||
Effect.catchTag("ParseError", e => SubscriptionRef.set(self.errorRef, Option.some(e)))
|
Effect.catchTag("ParseError", e => SubscriptionRef.set(self.errorRef, Option.some(e)))
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
), [internalValueRef, self, ...options.path])
|
), [internalValueRef, self, ...path])
|
||||||
|
|
||||||
return { value, setValue, issues }
|
return { value, setValue, issues }
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ class RegisterForm extends Effect.Service<RegisterForm>()("RegisterForm", {
|
|||||||
|
|
||||||
class RegisterPage extends Component.makeUntraced(function* RegisterPage() {
|
class RegisterPage extends Component.makeUntraced(function* RegisterPage() {
|
||||||
const form = yield* RegisterForm
|
const form = yield* RegisterForm
|
||||||
const emailInput = yield* Form.useInput(form, { path: ["email"] })
|
const emailInput = yield* Form.useInput(form, ["email"])
|
||||||
const passwordInput = yield* Form.useInput(form, { path: ["password"] })
|
const passwordInput = yield* Form.useInput(form, ["password"])
|
||||||
|
|
||||||
yield* useFork(() => Stream.runForEach(form.valueRef.changes, Console.log), [])
|
yield* useFork(() => Stream.runForEach(form.valueRef.changes, Console.log), [])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user