diff --git a/packages/example/src/lib/TextFieldInput.tsx b/packages/example/src/lib/TextFieldInput.tsx index c3170bd..b3c475e 100644 --- a/packages/example/src/lib/TextFieldInput.tsx +++ b/packages/example/src/lib/TextFieldInput.tsx @@ -5,8 +5,14 @@ import { useInput, useOptionalInput } from "effect-fc/hooks" import * as React from "react" -export type TextFieldInputProps = Omit, "schema" | "equivalence"> & Omit -export type TextFieldOptionalInputProps = Omit, "schema" | "equivalence"> & Omit +export type TextFieldInputProps = ( + & Omit, "schema" | "equivalence"> + & Omit +) +export type TextFieldOptionalInputProps = ( + & Omit, "schema" | "equivalence"> + & Omit +) export const TextFieldInput = (options: { readonly optional?: O @@ -50,7 +56,7 @@ export const TextFieldInput = (options: { value={input.value} onChange={e => input.setValue(e.target.value)} disabled={input.optional ? !input.enabled : undefined} - {...Struct.omit(props as TextFieldOptionalInputProps | TextFieldInputProps, "ref")} + {...Struct.omit(props as TextFieldOptionalInputProps | TextFieldInputProps, "ref", "defaultValue")} /> diff --git a/packages/example/src/lib/schema/datetime.ts b/packages/example/src/lib/schema/datetime.ts index 54875d4..ce85d3a 100644 --- a/packages/example/src/lib/schema/datetime.ts +++ b/packages/example/src/lib/schema/datetime.ts @@ -1,32 +1,38 @@ -import { DateTime, identity, ParseResult, Schema } from "effect" +import { DateTime, Effect, Option, ParseResult, Schema } from "effect" -export const DateTimeUtcFromZoned = Schema.transformOrFail( +export class DateTimeUtcFromZoned extends Schema.transformOrFail( Schema.DateTimeZonedFromSelf, Schema.DateTimeUtcFromSelf, { strict: true, encode: DateTime.setZoneCurrent, - decode: zoned => ParseResult.succeed(DateTime.toUtc(zoned)), + decode: i => ParseResult.succeed(DateTime.toUtc(i)), }, -) +) {} -export const DateTimeZonedFromUtc = Schema.transformOrFail( +export class DateTimeZonedFromUtc extends Schema.transformOrFail( Schema.DateTimeUtcFromSelf, Schema.DateTimeZonedFromSelf, { strict: true, - encode: zoned => ParseResult.succeed(DateTime.toUtc(zoned)), + encode: a => ParseResult.succeed(DateTime.toUtc(a)), decode: DateTime.setZoneCurrent, }, -) +) {} -export const DateTimeUtcFromZonedInput = Schema.transform( +export class DateTimeUtcFromZonedInput extends Schema.transformOrFail( Schema.String, - Schema.compose(Schema.DateTimeZoned, DateTimeUtcFromZoned), + DateTimeUtcFromZoned, { strict: true, - encode: v => v.slice(0, 16), - decode: identity, + encode: a => ParseResult.succeed(DateTime.formatIsoZoned(a).slice(0, 16)), + decode: (i, _, ast) => Effect.flatMap( + DateTime.CurrentTimeZone, + timeZone => Option.match(DateTime.makeZoned(i, { timeZone, adjustForTimeZone: true }), { + onSome: ParseResult.succeed, + onNone: () => ParseResult.fail(new ParseResult.Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a DateTime.Zoned`)), + }), + ), }, -) +) {} diff --git a/packages/example/src/todo/Todo.tsx b/packages/example/src/todo/Todo.tsx index e2de3bd..8cdc5d4 100644 --- a/packages/example/src/todo/Todo.tsx +++ b/packages/example/src/todo/Todo.tsx @@ -4,9 +4,9 @@ import { TextAreaInput } from "@/lib/TextAreaInput" import { TextFieldInput } from "@/lib/TextFieldInput" import { Box, Button, Flex, IconButton } from "@radix-ui/themes" import { GetRandomValues, makeUuid4 } from "@typed/id" -import { Chunk, Effect, Match, Option, Ref, Runtime, Schema, SubscriptionRef } from "effect" +import { Chunk, DateTime, Effect, Match, Option, Ref, Runtime, Schema, SubscriptionRef } from "effect" import { Component, Memo } from "effect-fc" -import { Hooks } from "effect-fc/hooks" +import { Hooks, useOnce } from "effect-fc/hooks" import { SubscriptionSubRef } from "effect-fc/types" import { FaArrowDown, FaArrowUp } from "react-icons/fa" import { FaDeleteLeft } from "react-icons/fa6" @@ -60,8 +60,9 @@ export class Todo extends Component.makeUntraced(function* Todo(props: TodoProps DateTime.now)} /> {props._tag === "new" &&