0.1.4 #5
@@ -1,5 +1,5 @@
|
||||
import * as AsyncData from "@typed/async-data"
|
||||
import { Array, Duration, Effect, Equal, Equivalence, Exit, flow, identity, Option, ParseResult, pipe, Pipeable, Ref, Schema, Scope, Stream, Subscribable, SubscriptionRef } from "effect"
|
||||
import { Array, Duration, Effect, Equal, Exit, flow, identity, Option, ParseResult, pipe, Pipeable, Ref, Schema, Scope, Stream, Subscribable, SubscriptionRef } from "effect"
|
||||
import type { NoSuchElementException } from "effect/Cause"
|
||||
import * as React from "react"
|
||||
import { Hooks } from "./hooks/index.js"
|
||||
@@ -289,40 +289,45 @@ export const useInput: {
|
||||
Stream.runForEach(
|
||||
internalValueRef.changes.pipe(
|
||||
Stream.drop(1),
|
||||
Stream.changesWith(Equivalence.strict()),
|
||||
Stream.changesWith(Equal.equivalence()),
|
||||
options?.debounce ? Stream.debounce(options.debounce) : identity,
|
||||
),
|
||||
internalValue => Ref.set(field.encodedValueRef, internalValue),
|
||||
),
|
||||
], { concurrency: "unbounded" }), [field, internalValueRef])
|
||||
], { concurrency: "unbounded" }), [field, internalValueRef, options?.debounce])
|
||||
|
||||
return { value, setValue, issues }
|
||||
})
|
||||
|
||||
export namespace useOptionalInput {
|
||||
export interface Options<I extends Option.Option<any>> extends useInput.Options {
|
||||
readonly defaultValue: Option.Option.Value<I>
|
||||
export interface Options<I> extends useInput.Options {
|
||||
readonly defaultValue: I
|
||||
}
|
||||
|
||||
export interface Result<T> extends useInput.Result<T> {}
|
||||
export interface Result<T> extends useInput.Result<T> {
|
||||
readonly enabled: boolean
|
||||
readonly setEnabled: React.Dispatch<React.SetStateAction<boolean>>
|
||||
}
|
||||
}
|
||||
|
||||
export const useOptionalInput: {
|
||||
<A, I extends Option.Option<any>>(
|
||||
field: FormField<A, I>,
|
||||
<A, I>(
|
||||
field: FormField<A, Option.Option<I>>,
|
||||
options: useOptionalInput.Options<I>,
|
||||
): Effect.Effect<useOptionalInput.Result<Option.Option.Value<I>>, NoSuchElementException>
|
||||
} = Effect.fnUntraced(function* <A, I extends Option.Option<any>>(
|
||||
field: FormField<A, I>,
|
||||
): Effect.Effect<useOptionalInput.Result<I>, NoSuchElementException>
|
||||
} = Effect.fnUntraced(function* <A, I>(
|
||||
field: FormField<A, Option.Option<I>>,
|
||||
options: useOptionalInput.Options<I>,
|
||||
) {
|
||||
const internalValueRef = yield* Hooks.useMemo(() => field.encodedValueRef.pipe(
|
||||
Effect.map(Option.match({
|
||||
onSome: identity,
|
||||
onNone: () => options.defaultValue,
|
||||
})),
|
||||
Effect.andThen(SubscriptionRef.make),
|
||||
const [enabledRef, internalValueRef] = yield* Hooks.useMemo(() => Effect.andThen(
|
||||
field.encodedValueRef,
|
||||
Option.match({
|
||||
onSome: v => Effect.all([SubscriptionRef.make(true), SubscriptionRef.make(v)]),
|
||||
onNone: () => Effect.all([SubscriptionRef.make(false), SubscriptionRef.make(options.defaultValue)]),
|
||||
}),
|
||||
), [field])
|
||||
|
||||
const [enabled, setEnabled] = yield* Hooks.useRefState(enabledRef)
|
||||
const [value, setValue] = yield* Hooks.useRefState(internalValueRef)
|
||||
const [issues] = yield* Hooks.useSubscribables(field.issuesSubscribable)
|
||||
|
||||
@@ -336,14 +341,15 @@ export const useOptionalInput: {
|
||||
),
|
||||
|
||||
Stream.runForEach(
|
||||
internalValueRef.changes.pipe(
|
||||
enabledRef.changes.pipe(
|
||||
Stream.zipLatest(internalValueRef.changes),
|
||||
Stream.drop(1),
|
||||
Stream.changesWith(Equivalence.strict()),
|
||||
Stream.changesWith(Equal.equivalence()),
|
||||
options?.debounce ? Stream.debounce(options.debounce) : identity,
|
||||
),
|
||||
internalValue => Ref.set(field.encodedValueRef, internalValue),
|
||||
([enabled, internalValue]) => Ref.set(field.encodedValueRef, enabled ? Option.some(internalValue) : Option.none()),
|
||||
),
|
||||
], { concurrency: "unbounded" }), [field, internalValueRef])
|
||||
], { concurrency: "unbounded" }), [field, enabledRef, internalValueRef, options.debounce])
|
||||
|
||||
return { value, setValue, issues }
|
||||
return { enabled, setEnabled, value, setValue, issues }
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user