diff --git a/awesome_owl/__init__.py b/awesome_owl/__init__.py
index 457bae27e11..b0f26a9a602 100644
--- a/awesome_owl/__init__.py
+++ b/awesome_owl/__init__.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
-from . import controllers
\ No newline at end of file
+from . import controllers
diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js
new file mode 100644
index 00000000000..5e1c5291bf2
--- /dev/null
+++ b/awesome_owl/static/src/card/card.js
@@ -0,0 +1,24 @@
+import { Component, useState } from "@odoo/owl";
+import { Counter } from "../counter/counter";
+
+export class Card extends Component {
+ static template = "awesome_owl.Card";
+
+ static components = { Counter };
+
+ setup() {
+ this.state = useState({
+ open: true,
+ });
+
+ this.flip = this.flip.bind(this);
+ }
+
+ static props = {
+ title: String,
+ };
+
+ flip() {
+ this.state.open = !this.state.open;
+ }
+}
diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml
new file mode 100644
index 00000000000..b3b0f313402
--- /dev/null
+++ b/awesome_owl/static/src/card/card.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js
new file mode 100644
index 00000000000..88e9ae00982
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.js
@@ -0,0 +1,17 @@
+import { Component, useState } from "@odoo/owl";
+
+export class Counter extends Component {
+ static template = "awesome_owl.counter";
+
+ static props = {
+ validation_fct: { type: Function, optional: true },
+ };
+ setup() {
+ this.state = useState({ value: 0 });
+ }
+
+ increment() {
+ this.state.value++;
+ this.props.validation_fct?.call();
+ }
+}
diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml
new file mode 100644
index 00000000000..2fabde0843a
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js
index 657fb8b07bb..3953d603e9a 100644
--- a/awesome_owl/static/src/playground.js
+++ b/awesome_owl/static/src/playground.js
@@ -1,7 +1,21 @@
/** @odoo-module **/
-import { Component } from "@odoo/owl";
+import { Component, 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 template = "awesome_owl.playground";
+
+ static components = { Counter, Card, TodoList };
+
+ setup() {
+ this.state = useState({ sum: 0 });
+ this.incrSum = this.incrSum.bind(this);
+ }
+
+ incrSum() {
+ this.state.sum++;
+ }
}
diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml
index 4fb905d59f9..a64380e4b81 100644
--- a/awesome_owl/static/src/playground.xml
+++ b/awesome_owl/static/src/playground.xml
@@ -1,10 +1,14 @@
-
-
-
- hello world
-
-
-
+
+
+
Hello world
+
+
+
+
+
the sum is
+
+
+
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..c3545d8e282
--- /dev/null
+++ b/awesome_owl/static/src/todo_list/todo_item.js
@@ -0,0 +1,21 @@
+import { Component } from "@odoo/owl";
+
+export class TodoItem extends Component {
+ static template = "awesome_owl.TodoItem";
+
+ setup() {
+ this.toggleState = this.toggleState.bind(this);
+ }
+
+ static props = {
+ todo: {
+ type: Object,
+ shape: { id: Number, description: String, isCompleted: Boolean },
+ },
+ remove_fct: { type: Function },
+ };
+
+ toggleState() {
+ this.props.todo.isCompleted = !this.props.todo.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..2ae350057c1
--- /dev/null
+++ b/awesome_owl/static/src/todo_list/todo_item.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
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..2fad3c2ee5b
--- /dev/null
+++ b/awesome_owl/static/src/todo_list/todo_list.js
@@ -0,0 +1,44 @@
+import { Component, useState } from "@odoo/owl";
+import { TodoItem } from "./todo_item";
+import { useAutofocus } from "../utils/useAutoFocus";
+
+export class TodoList extends Component {
+ static template = "awesome_owl.TodoList";
+
+ static components = { TodoItem };
+
+ setup() {
+ this.state = useState({
+ todos: [],
+ curr_id: 0,
+ });
+
+ this.inputRef = useAutofocus("input");
+ this.delete_todo = this.delete_todo.bind(this);
+ }
+
+ add_todo(ev) {
+ if (ev.keyCode === 13) {
+ const value = ev.target.value.trim();
+ if (value !== "") {
+ this.state.todos.push({
+ id: this.state.curr_id,
+ description: value,
+ isCompleted: false,
+ });
+ }
+ ev.target.value = "";
+
+ this.state.curr_id++;
+ }
+ }
+
+ delete_todo(todo_to_remove_id) {
+ const index = this.state.todos.findIndex(
+ (elem) => elem.id === todo_to_remove_id
+ );
+ if (index >= 0) {
+ this.state.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..6fbcfabffaa
--- /dev/null
+++ b/awesome_owl/static/src/todo_list/todo_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/utils/useAutoFocus.js b/awesome_owl/static/src/utils/useAutoFocus.js
new file mode 100644
index 00000000000..6423dcc113f
--- /dev/null
+++ b/awesome_owl/static/src/utils/useAutoFocus.js
@@ -0,0 +1,13 @@
+import { onMounted, useRef } from "@odoo/owl";
+
+export function useAutofocus(refName) {
+ const elRef = useRef(refName);
+ onMounted(() => {
+ if (elRef.el && typeof elRef.el.focus === 'function') {
+ elRef.el.focus();
+ } else {
+ console.error("The component you try to focus does not have a focus method")
+ }
+ });
+ return elRef;
+}