diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js
new file mode 100644
index 00000000000..324e57fffab
--- /dev/null
+++ b/awesome_owl/static/src/card/card.js
@@ -0,0 +1,25 @@
+import { Component, useState } from "@odoo/owl";
+
+export class Card extends Component {
+ static props = {
+ label: {type: String},
+ slots: {
+ type: Object,
+ shape: {
+ default: Object,
+ },
+ optional: true,
+ },
+ };
+ static template = "awesome_owl.card";
+
+ setup() {
+ this.state = useState({
+ showContent: true,
+ })
+ }
+
+ toggleShowContent() {
+ this.state.showContent = !this.state.showContent;
+ }
+}
diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml
new file mode 100644
index 00000000000..d7afa0a36b5
--- /dev/null
+++ b/awesome_owl/static/src/card/card.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js
new file mode 100644
index 00000000000..82a42947b15
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.js
@@ -0,0 +1,19 @@
+import { Component, useState } from "@odoo/owl";
+
+export class Counter extends Component {
+ static props = {
+ onChange: {optional: true}
+ };
+ static template = "awesome_owl.counter";
+
+ setup() {
+ this.state = useState({ counter: 0 });
+ }
+
+ increment() {
+ this.state.counter++;
+ if (this.props.onChange) {
+ this.props.onChange();
+ }
+ }
+}
diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml
new file mode 100644
index 00000000000..cefcfa219c9
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js
index 4ac769b0aa5..8907558530c 100644
--- a/awesome_owl/static/src/playground.js
+++ b/awesome_owl/static/src/playground.js
@@ -1,5 +1,28 @@
-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/todo_list";
export class Playground extends Component {
+ static props = [];
static template = "awesome_owl.playground";
+ static components = {
+ Counter,
+ Card,
+ TodoList,
+ };
+
+ content1 = markup("This is the content for card 1");
+
+ setup() {
+ super.setup();
+ this.state = useState({
+ total: 0,
+ });
+ }
+
+ onCounterIncremeneted = () => {
+ console.log(this.state)
+ this.state.total ++;
+ }
}
diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml
index 4fb905d59f9..a32f3ac153c 100644
--- a/awesome_owl/static/src/playground.xml
+++ b/awesome_owl/static/src/playground.xml
@@ -2,9 +2,14 @@
-
- hello world
-
+
+
+ VS
+
+
+
+
+
diff --git a/awesome_owl/static/src/todo/todo_item.js b/awesome_owl/static/src/todo/todo_item.js
new file mode 100644
index 00000000000..b6991073542
--- /dev/null
+++ b/awesome_owl/static/src/todo/todo_item.js
@@ -0,0 +1,31 @@
+import { Component, markup, useState } from "@odoo/owl";
+import { Card } from "../card/card"
+
+export class TodoItem extends Component {
+ static props = {
+ todo: {
+ type: Object,
+ shape: {
+ id: {type: Number},
+ description: {type: String},
+ isCompleted: {type: Boolean},
+ }
+ },
+ toggleState: {type: Function},
+ handleDeleteTodo: {type: Function},
+ };
+
+ static components = {
+ Card,
+ };
+
+ static template = "awesome_owl.todo_item";
+
+ onToggleChange = () => {
+ this.props.toggleState(this.props.todo.id);
+ }
+
+ onDelete = () => {
+ this.props.handleDeleteTodo(this.props.todo.id);
+ }
+}
diff --git a/awesome_owl/static/src/todo/todo_item.xml b/awesome_owl/static/src/todo/todo_item.xml
new file mode 100644
index 00000000000..671e4e228f3
--- /dev/null
+++ b/awesome_owl/static/src/todo/todo_item.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ .
+
+
+
+
+
diff --git a/awesome_owl/static/src/todo/todo_list.js b/awesome_owl/static/src/todo/todo_list.js
new file mode 100644
index 00000000000..bb8e5c28f99
--- /dev/null
+++ b/awesome_owl/static/src/todo/todo_list.js
@@ -0,0 +1,47 @@
+import { Component, markup, useState, onMounted, useRef } from "@odoo/owl";
+import { TodoItem } from "./todo_item";
+import { useAutofocus } from "../utils"
+
+export class TodoList extends Component {
+ static components = {
+ TodoItem,
+ };
+
+ static template = "awesome_owl.todo_list";
+
+ setup() {
+ this.todos = useState([]);
+ useAutofocus('todo_input');
+ this.nextId = 0;
+ }
+
+ createTodo = (ev) => {
+ if (ev.keyCode != 13)
+ return;
+
+ const text = ev.target.value.trim();
+
+ if (!text)
+ return;
+
+ this.todos.push({
+ id: ++this.nextId,
+ description: text,
+ isCompleted: false,
+ });
+
+ ev.target.value = "";
+ }
+
+ handleTodoStateChanged = (todoId) => {
+ const toChange = this.todos.find(t => t.id == todoId);
+ toChange.isCompleted = !toChange.isCompleted;
+ }
+
+ handleDeleteTodo = (todoId) => {
+ const index = this.todos.findIndex(t => t.id === todoId);
+ if (index !== -1) {
+ this.todos.splice(index, 1);
+ }
+ }
+}
diff --git a/awesome_owl/static/src/todo/todo_list.xml b/awesome_owl/static/src/todo/todo_list.xml
new file mode 100644
index 00000000000..dde80abdc0e
--- /dev/null
+++ b/awesome_owl/static/src/todo/todo_list.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/utils.js b/awesome_owl/static/src/utils.js
new file mode 100644
index 00000000000..c1b5bccd7be
--- /dev/null
+++ b/awesome_owl/static/src/utils.js
@@ -0,0 +1,10 @@
+import { useRef, onMounted } from "@odoo/owl"
+
+export function useAutofocus(refName) {
+ const ref = useRef(refName);
+
+ onMounted(() => {
+ if (ref.el)
+ ref.el.focus();
+ })
+}
\ No newline at end of file