diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js
new file mode 100644
index 00000000000..97954973c5d
--- /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 template = "awesome_owl.card";
+
+ static props = {
+ title: {
+ type: String,
+ },
+ slots: {
+ type: Object,
+ shape:{
+ default: Object,
+ }
+ }
+ }
+
+ setup() {
+ this.state = useState({visible: true});
+ }
+
+ showContent() {
+ this.state.visible = !this.state.visible;
+ }
+}
diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml
new file mode 100644
index 00000000000..765b1bb3cad
--- /dev/null
+++ b/awesome_owl/static/src/card/card.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js
new file mode 100644
index 00000000000..4a017a1cb68
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.js
@@ -0,0 +1,23 @@
+import {Component, useState} from "@odoo/owl";
+
+export class Counter extends Component {
+ static template = "awesome_owl.counter";
+
+ static props = {
+ onChange: {
+ type: Function,
+ optional: true
+ }
+ }
+
+ setup() {
+ this.state = useState({value: 0});
+ }
+
+ increment() {
+ this.state.value++;
+ 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..5e0ec2135c0
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Counter:
+
+
+
+
diff --git a/awesome_owl/static/src/main.js b/awesome_owl/static/src/main.js
index 1aaea902b55..d822c898ee1 100644
--- a/awesome_owl/static/src/main.js
+++ b/awesome_owl/static/src/main.js
@@ -1,12 +1,11 @@
-import { whenReady } from "@odoo/owl";
-import { mountComponent } from "@web/env";
-import { Playground } from "./playground";
+import {whenReady} from "@odoo/owl";
+import {mountComponent} from "@web/env";
+import {Playground} from "./playground";
const config = {
dev: true,
- name: "Owl Tutorial"
+ name: "Owl Tutorial"
};
// Mount the Playground component when the document.body is ready
whenReady(() => mountComponent(Playground, document.body, config));
-
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js
index 4ac769b0aa5..a919d50ac38 100644
--- a/awesome_owl/static/src/playground.js
+++ b/awesome_owl/static/src/playground.js
@@ -1,5 +1,18 @@
-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 components = {Counter, Card, TodoList};
+
+ setup() {
+ this.state = useState({value: 0});
+ }
+
+ incrementSum() {
+ this.state.value++;
+ }
}
diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml
index 4fb905d59f9..441eb9b0392 100644
--- a/awesome_owl/static/src/playground.xml
+++ b/awesome_owl/static/src/playground.xml
@@ -2,9 +2,16 @@
-
- hello world
-
+ My Counter
+
+
+
+
+
+
+
+ Sum:
+
diff --git a/awesome_owl/static/src/todo/item/todo_item.js b/awesome_owl/static/src/todo/item/todo_item.js
new file mode 100644
index 00000000000..c8a34cc8cc1
--- /dev/null
+++ b/awesome_owl/static/src/todo/item/todo_item.js
@@ -0,0 +1,33 @@
+import {Component} from "@odoo/owl";
+import {Card} from "../../card/card";
+
+export class TodoItem extends Component {
+ static template = "awesome_owl.todo_item";
+
+ static Components = [Card]
+
+ static props = {
+ todo: {
+ type: Object,
+ shape: {
+ id: Number,
+ description: String,
+ isCompleted: Boolean,
+ }
+ },
+ toggleState: {
+ type: Function
+ },
+ removeTodo: {
+ type: Function
+ }
+ }
+
+ changeCheckbox(ev) {
+ this.props.toggleState(this.props.todo.id, ev.target.checked);
+ }
+
+ removeTodo() {
+ this.props.removeTodo(this.props.todo.id)
+ }
+}
diff --git a/awesome_owl/static/src/todo/item/todo_item.xml b/awesome_owl/static/src/todo/item/todo_item.xml
new file mode 100644
index 00000000000..c8a347482eb
--- /dev/null
+++ b/awesome_owl/static/src/todo/item/todo_item.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
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..e601818aae6
--- /dev/null
+++ b/awesome_owl/static/src/todo/list/todo_list.js
@@ -0,0 +1,60 @@
+import {Component, useState, useRef, onMounted} from "@odoo/owl";
+import {TodoItem} from "../item/todo_item";
+import {useAutoFocus} from "../../utils/utils";
+
+export class TodoList extends Component {
+ static template = "awesome_owl.todo_list";
+
+ static components = {TodoItem};
+
+ static props = {
+ items: {
+ type: Array,
+ optional: true,
+ }
+ }
+
+ setup() {
+ this.props.items = useState([])
+ this.descriptionRef = useRef('descriptionInput');
+ this.nextId = 1;
+ onMounted(() => {
+ useAutoFocus(this.descriptionRef.el)
+ });
+ }
+
+ #checkDescription() {
+ return this.descriptionRef?.el?.value?.trim();
+ }
+
+ addTodoItem() {
+ if (this.#checkDescription()) {
+ this.props.items.push({
+ id: this.nextId++,
+ description: this.descriptionRef.el.value,
+ isCompleted: false
+ })
+ this.descriptionRef.el.value = '';
+ }
+ }
+
+ checkAndAddTask(ev) {
+ if (ev.keyCode === 13 && this.#checkDescription()) {
+ this.addTodoItem();
+ }
+ }
+
+ toggleTodoState = (id, isChecked) => {
+ const element = this.props.items.find(item => item.id === id);
+ if (element) {
+ element.isCompleted = isChecked;
+ }
+ }
+
+ removeTodoItem = (id) => {
+ const index = this.props.items.findIndex(item => item.id === id);
+ if(index >= 0) {
+ this.props.items.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..17cc4897782
--- /dev/null
+++ b/awesome_owl/static/src/todo/list/todo_list.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/utils/utils.js b/awesome_owl/static/src/utils/utils.js
new file mode 100644
index 00000000000..ad892d4e94e
--- /dev/null
+++ b/awesome_owl/static/src/utils/utils.js
@@ -0,0 +1,3 @@
+export const useAutoFocus = (el) => {
+ el?.focus();
+}