Created
February 22, 2025 15:24
-
-
Save nguyenyou/156f29598d51a3b550335e3124a67e0d to your computer and use it in GitHub Desktop.
Laminar + SAPUI5 TodoApp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//> using scala 3.6.3 | |
//> using platform scala-js | |
//> using dep "org.scala-js::scalajs-dom::2.8.0" | |
//> using dep "com.raquo::laminar::17.2.0" | |
//> using dep "be.doeraene::web-components-ui5::2.1.0" | |
//> using jsModuleKind es | |
//> using jsModuleSplitStyleStr fewestmodules | |
package myapp | |
import org.scalajs.dom | |
import com.raquo.laminar.api.L.* | |
import be.doeraene.webcomponents.ui5.* | |
import be.doeraene.webcomponents.ui5.configkeys.* | |
case class Todo(id: Int, text: String, completed: Boolean) | |
@main | |
def main(): Unit = { | |
val container = dom.document.getElementById("app") | |
// State management | |
val todosVar = Var(Vector.empty[Todo]) | |
val inputVar = Var("") | |
def addTodo(text: String): Unit = | |
if text.trim.nonEmpty then | |
val newTodo = Todo( | |
id = System.currentTimeMillis().toInt, | |
text = text.trim, | |
completed = false | |
) | |
todosVar.update(_ :+ newTodo) | |
inputVar.set("") | |
def toggleTodo(id: Int): Unit = | |
todosVar.update(_.map { todo => | |
if todo.id == id then todo.copy(completed = !todo.completed) | |
else todo | |
}) | |
def deleteTodo(id: Int): Unit = | |
todosVar.update(_.filterNot(_.id == id)) | |
render( | |
container, | |
div( | |
className := "max-w-md mx-auto mt-8 p-4", | |
// Input form | |
form( | |
className := "flex items-center gap-2 mb-4", | |
onSubmit.preventDefault --> { _ => addTodo(inputVar.now()) }, | |
Input( | |
_.placeholder := "Add a new todo...", | |
_.value <-- inputVar, | |
_.events.onInput.mapToValue --> inputVar.writer | |
), | |
Button( | |
_.design := ButtonDesign.Emphasized, | |
_.tpe := ButtonType.Submit, | |
"Add" | |
) | |
), | |
// Todo list | |
div( | |
className := "space-y-2", | |
children <-- todosVar.signal.map { todos => | |
todos.map { todo => | |
div( | |
className := "flex items-center gap-2 p-2 border rounded", | |
input( | |
typ := "checkbox", | |
checked := todo.completed, | |
className := "h-5 w-5", | |
onClick --> { _ => toggleTodo(todo.id) } | |
), | |
span( | |
className := (if todo.completed then "line-through text-gray-500" else ""), | |
todo.text | |
), | |
button( | |
className := "ml-auto px-2 py-1 text-red-500 hover:bg-red-100 rounded", | |
onClick --> { _ => deleteTodo(todo.id) }, | |
"×" | |
) | |
) | |
} | |
} | |
) | |
) | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment