8000 Typed input value by malladinagarjuna2 · Pull Request #468 · armanbilge/calico · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions calico/src/main/scala/calico/html/Html.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,6 @@ sealed class Html[F[_]](using F: Async[F])

def valueAttr: HtmlAttr[F, String] =
HtmlAttr("value", encoders.identity)

extension (el: fs2.dom.HtmlInputElement[F])
def typedValue[T <: String](using r: InputReader[F, T]): F[r.Out] = r.read(el)
68 changes: 68 additions & 0 deletions calico/src/main/scala/calico/html/TypedInput.scala
8000
Original file line number Diff line numberDiff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2022 Arman Bilge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package calico
package html

import cats.effect.kernel.Async
import fs2.dom.HtmlInputElement
import org.scalajs.dom

type InputValue[T <: String] <: Any = T match
case "file" => dom.FileList
case "checkbox" => Boolean
case "radio" => Boolean
case "number" => Double
case "range" => Double
case String => String

trait InputReader[F[_], T <: String]:
type Out
def read(el: HtmlInputElement[F]): F[Out]

object InputReader:

type Aux[F[_], T <: String, O] = InputReader[F, T] { type Out = O }

given file[F[_]](using F: Async[F]): InputReader[F, "file"] with
type Out = dom.FileList
def read(el: HtmlInputElement[F]): F[dom.FileList] =
F.delay(el.asInstanceOf[dom.HTMLInputElement].files)

given checkbox[F[_]](using F: Async[F]): InputReader[F, "checkbox"] with
type Out = Boolean
def read(el: HtmlInputElement[F]): F[Boolean] =
F.delay(el.asInstanceOf[dom.HTMLInputElement].checked)

given radio[F[_]](using F: Async[F]): InputReader[F, "radio"] with
type Out = Boolean
def read(el: HtmlInputElement[F]): F[Boolean] =
F.delay(el.asInstanceOf[dom.HTMLInputElement].checked)

given number[F[_]](using F: Async[F]): InputReader[F, "number"] with
type Out = Double
def read(el: HtmlInputElement[F]): F[Double] =
F.delay(el.asInstanceOf[dom.HTMLInputElement].valueAsNum 8000 ber)

given range[F[_]](using F: Async[F]): InputReader[F, "range"] with
type Out = Double
def read(el: HtmlInputElement[F]): F[Double] =
F.delay(el.asInstanceOf[dom.HTMLInputElement].valueAsNumber)

given text[F[_], T <: String](using F: Async[F]): InputReader[F, T] with
type Out = String
def read(el: HtmlInputElement[F]): F[String] =
F.delay(el.asInstanceOf[dom.HTMLInputElement].value)
19 changes: 19 additions & 0 deletions calico/src/test/scala/calico/SyntaxSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import calico.syntax.*
import cats.effect.*
import cats.syntax.all.*
import fs2.concurrent.*
import org.scalajs.dom

class SyntaxSuite:

Expand All @@ -45,3 +46,21 @@ class SyntaxSuite:
onClick(_ => IO.unit),
onClick(IO.unit)
)

def typedInputReads(fileEl: fs2.dom.HtmlInputElement[IO]) =
val files: IO[dom.FileList] = fileEl.typedValue["file"]
val checked: IO[Boolean] = fileEl.typedValue["checkbox"]
val isRadio: IO[Boolean] = fileEl.typedValue["radio"]
val num: IO[Double] = fileEl.typedValue["number"]
val rng: IO[Double] = fileEl.typedValue["range"]
val str: IO[String] = fileEl.typedValue["text"]
val email: IO[String] = fileEl.typedValue["email"]
(files, checked, isRadio, num, rng, str, email)

def typedInputWithOnChange =
input.withSelf { self =>
(
typ := "file",
onChange --> { _.evalMap(_ => self.typedValue["file"]).foreach(_ => IO.unit) }
)
}
Loading
0