diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js
new file mode 100644
index 00000000000..a85367bb527
--- /dev/null
+++ b/awesome_owl/static/src/card/card.js
@@ -0,0 +1,38 @@
+import { Component, xml, useState } from "@odoo/owl";
+
+export class Card extends Component {
+ static template = xml`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `;
+
+ static props = {
+ title: { type: String },
+ slots: { type: Object, optional: true }
+ };
+
+ setup() {
+ this.state = useState({
+ isOpen: true
+ });
+ }
+
+ toggle() {
+ this.state.isOpen = !this.state.isOpen;
+ }
+}
diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js
new file mode 100644
index 00000000000..f3cac2e0f4b
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.js
@@ -0,0 +1,21 @@
+import { Component, useState } from "@odoo/owl";
+
+export class Counter extends Component {
+ static template = "awesome_owl.counter";
+
+ setup() {
+ this.state = useState({ value: 0 });
+ }
+
+ increment() {
+ this.state.value++
+
+ if (this.props.onChange) {
+ this.props.onChange();
+ }
+ }
+
+ static props = {
+ onChange: { type: Function, optional: true }
+ }
+}
diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml
new file mode 100644
index 00000000000..f20e162d294
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js
index 4ac769b0aa5..0e7579cb203 100644
--- a/awesome_owl/static/src/playground.js
+++ b/awesome_owl/static/src/playground.js
@@ -1,5 +1,23 @@
-import { Component } from "@odoo/owl";
+import { Component, markup, useState } from "@odoo/owl";
+import { Counter } from "./counter/counter";
+import { Card } from "./card/card";
+import { TodoList } from "./todo_list/todo_list";
export class Playground extends Component {
static template = "awesome_owl.playground";
+ static components = { Counter, Card, TodoList };
+
+ setup() {
+ const productDescriptionFromDB = "This is a great product!
";
+ this.description = markup(productDescriptionFromDB);
+ this.sum = useState({ value: 0 });
+
+ this.someExpression = () => {
+ return true;
+ }
+ }
+
+ incrementSum() {
+ this.sum.value++;
+ }
}
diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml
index 4fb905d59f9..31daad927b1 100644
--- a/awesome_owl/static/src/playground.xml
+++ b/awesome_owl/static/src/playground.xml
@@ -5,6 +5,20 @@
hello world
+
+
+
+ Total Sum:
+
+
+ test
+ description
+
+
+ Content of card 2
+
+
+
diff --git a/awesome_owl/static/src/todo_list/todo_item.js b/awesome_owl/static/src/todo_list/todo_item.js
new file mode 100644
index 00000000000..3d8ce1cfdff
--- /dev/null
+++ b/awesome_owl/static/src/todo_list/todo_item.js
@@ -0,0 +1,21 @@
+import { Component, useState } from "@odoo/owl";
+
+export class TodoItem extends Component {
+ static template = "awesome_owl.todo_item";
+ static props = {
+ id: { type: Number },
+ description: { type: String },
+ isCompleted: { type: Boolean }
+ };
+
+ onChange() {
+ this.state.isCompleted = !this.state.isCompleted;
+ }
+
+ setup() {
+ this.state = useState({
+ isCompleted: this.props.isCompleted
+ })
+ }
+
+};
diff --git a/awesome_owl/static/src/todo_list/todo_item.xml b/awesome_owl/static/src/todo_list/todo_item.xml
new file mode 100644
index 00000000000..125cd4addd0
--- /dev/null
+++ b/awesome_owl/static/src/todo_list/todo_item.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
ID:
+
Description:
+
Completed:
+
+
+
+
diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js
new file mode 100644
index 00000000000..f1ae60b87bd
--- /dev/null
+++ b/awesome_owl/static/src/todo_list/todo_list.js
@@ -0,0 +1,38 @@
+import { Component, useState, onMounted, useRef } from "@odoo/owl";
+import { TodoItem } from "./todo_item";
+
+export class TodoList extends Component {
+ static template = "awesome_owl.todo_list";
+ static components = { TodoItem };
+
+ setup() {
+ this.nextId = 0;
+ this.todos = useState([]);
+
+ this.inputRef = useRef("input");
+ onMounted(() => {
+ this.inputRef.el.focus();
+ });
+ }
+
+ addTodo(ev) {
+ if (ev.keyCode === 13 && ev.target.value != "") {
+ this.todos.push(
+ {
+ "id": this.nextId++,
+ "description": ev.target.value,
+ "isCompleted": false
+ }
+ )
+ ev.target.value = "";
+ }
+ }
+
+ delete(todoId) {
+ const index = this.todos.findIndex((todo) => todo.id === todoId);
+ if (index !== -1) {
+ this.todos.splice(index, 1);
+ }
+ }
+
+}
diff --git a/awesome_owl/static/src/todo_list/todo_list.xml b/awesome_owl/static/src/todo_list/todo_list.xml
new file mode 100644
index 00000000000..d007b83f232
--- /dev/null
+++ b/awesome_owl/static/src/todo_list/todo_list.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+