/** * codecs specific to uwc-input * * @internal * @module */ import type { SupportedIdlType } from "./uwc-input"; import * as Either from "@hesxenon/prelude/Either.js"; import { Codec, iso8601ContentAttribute__maybeDate, contentAttribute__number, contentAttribute__boolean, } from "@hesxenon/prelude/Codec.js"; /** * convert content attributes between expected types for min and max */ export const content__minMax: Codec< string, Date | number | undefined, UwcInputElement > = { encode(idl) { switch (true) { case idl instanceof Date: return iso8601ContentAttribute__maybeDate.encode(idl); case typeof idl === "number": { return contentAttribute__number.encode(idl); } default: return Either.right(idl ?? ""); } }, decode(content) { switch (true) { case this.type === "date": return iso8601ContentAttribute__maybeDate.decode(content); case this.multiple: case this.type === "file": case this.type === "number": case this.type === "range": return contentAttribute__number.decode(content); default: { return Either.left( new Error( "setting min/max attribute is only supported for [type=date], [type=number], [type=file] or [multiple]", ), ); } } }, }; /** * convert between idl and content representation of the value attribute */ export const valueCodec: Codec< string | undefined, SupportedIdlType, UwcInputElement > = { encode(value) { switch (true) { case this.type === "date": return !( value instanceof Date || typeof value === "number" || typeof value === "string" ) ? Either.left(new Error("cannot encode value as an ISO8601 string")) : iso8601ContentAttribute__maybeDate.encode( !(value instanceof Date) ? new Date(value) : value, ); case this.type === "file": return Either.right(""); default: return Either.right(value?.toString()); } }, decode(content) { switch (true) { case this.type === "date": return iso8601ContentAttribute__maybeDate.decode(content); case this.type === "number": case this.type === "range": return contentAttribute__number.decode(content); case this.type === "text" || this.type === "search" || this.type === "textarea": return Either.right(content as string | undefined); case this.type === "checkbox": case this.type === "radio": return Either.right(content as string | undefined); case this.type === "file": return Either.right(undefined); default: return Either.left( new Error( `cannot decode '${content}' according to type '${this.type}'`, ), ); } }, }; export const omitValueCodec: Codec< string | undefined, boolean | "form", UwcInputElement > = { encode(next) { return typeof next === "boolean" ? contentAttribute__boolean.encode(next) : Either.right(next); }, decode(content) { return content === "form" ? Either.right(content as "form") : contentAttribute__boolean.decode(content); }, };