Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
185 commits
Select commit Hold shift + click to select a range
debd035
[IMP] introduce signals and derived values
Goaman Sep 26, 2025
376bb18
[ref] update package-lock.json
ged-odoo Nov 20, 2025
4624471
[rel] update package.json
ged-odoo Nov 21, 2025
acdb90f
[ADD] add registry and plugin system
ged-odoo Nov 20, 2025
1943ca6
[notes] add release notes
ged-odoo Nov 24, 2025
4c301c8
[rel] update package.json to 3.0.0-alpha.2
ged-odoo Nov 24, 2025
a49dd9c
[imp] improve typing, fix registry validation code
ged-odoo Nov 24, 2025
7ed72ab
[rel] update version to alpha.4
ged-odoo Nov 24, 2025
7b9760c
[fix] registry: make it work, add addById method
ged-odoo Nov 24, 2025
5cbe0b5
v3.0.0-alpha.5
ged-odoo Nov 24, 2025
441ff96
[REM] utils: remove loadFile
ged-odoo Dec 2, 2025
df5a2be
[ref] signals: change their api
ged-odoo Dec 2, 2025
710ab00
[ref] plugins: change api
mcm-odoo Dec 2, 2025
026bfc9
[IMP] plugins: test with components
mcm-odoo Dec 2, 2025
7672770
[FIX] plugins: fix resource tests
mcm-odoo Dec 2, 2025
d562d8a
[ref] utils: rename useExternalListener to useListener
ged-odoo Dec 2, 2025
bca49c5
[ref] rename useState/reactive => proxy
ged-odoo Dec 2, 2025
583e075
[imp] update package.json dev dependencies
ged-odoo Dec 2, 2025
71d8418
[imp] streamline app API (Root/subroots => roots)
mcm-odoo Dec 2, 2025
16666f8
[fix] various fixes to make the previous commits work
ged-odoo Dec 2, 2025
9050347
[FIX] playground: fix playground
mcm-odoo Dec 4, 2025
e22ed18
[FIX] revamp error handling code, only throw error once in some cases
ged-odoo Dec 3, 2025
dca58d7
[IMP] reactivity: add Signal.update method
ged-odoo Dec 4, 2025
c8ab816
[REF] runtime: move code around to make it clearer
ged-odoo Dec 4, 2025
0e67c59
[REF] reactivity: split code into multiple files
ged-odoo Dec 4, 2025
c6405e6
[REF] rename withoutReactivity => untrack
ged-odoo Dec 4, 2025
4ef7d34
[REF] reactivity: move tests
ged-odoo Dec 4, 2025
1838e58
[REF] mini cleanup, remove commont/types file
ged-odoo Dec 4, 2025
66d7290
[IMP] app: remove warnIfNoStaticProps
mcm-odoo Dec 8, 2025
c3f6717
[FIX] app: fix mount return type
mcm-odoo Dec 8, 2025
7f91408
[IMP] props: introduce props function
mcm-odoo Dec 8, 2025
3ee3013
[IMP] prettify
mcm-odoo Dec 8, 2025
45d8497
[imp] add Resource, make registry chainable
ged-odoo Dec 8, 2025
188be79
[IMP] add Registry.remove, Resource.remove, rename Registry.get => Re…
ged-odoo Dec 8, 2025
8e1e6b8
update snapshots
ged-odoo Dec 8, 2025
decc5b4
[imp] error: simplify error handling
ged-odoo Dec 8, 2025
886a23c
[imp] simplify plugin and resources system
ged-odoo Dec 9, 2025
665069c
[add] add some tests for resource
ged-odoo Dec 9, 2025
605f403
[IMP] props: improve props types again
mcm-odoo Dec 9, 2025
08afebb
[IMP] hooks: remove env related hooks
mcm-odoo Dec 9, 2025
0086776
[IMP] hooks: remove env related hooks
mcm-odoo Dec 9, 2025
7f1bd61
[IMP] props: move default props to props function
mcm-odoo Dec 9, 2025
7e075df
[REF] slot: rename t-slot into t-call-slot
mcm-odoo Dec 9, 2025
c2b9f2f
[rem] remove onWillRender and onRendered
ged-odoo Dec 9, 2025
04e332b
[imp] slots: do not get props from component, but from component node
ged-odoo Dec 10, 2025
8215659
[IMP] ref: replace useRef by signal
mcm-odoo Dec 10, 2025
fcbf4ac
[REF] blockdom: simplify ref system
mcm-odoo Dec 11, 2025
e66f19e
[IMP] ref: use resource to get multiple refs at once
mcm-odoo Dec 11, 2025
34ae1be
[IMP] t-model: support signal instead of proxy
mcm-odoo Dec 11, 2025
43bfc5b
[IMP] status: status is now a hook
mcm-odoo Dec 11, 2025
d155b33
[IMP] plugin: plugin manager now has a status
mcm-odoo Dec 11, 2025
f1c1a24
[FIX] blockdom: cbRefs used the wrong idx
mcm-odoo Dec 11, 2025
394b42f
[FIX] playground: update playground
mcm-odoo Dec 11, 2025
5fdcd5a
[ref] rework error handling code
ged-odoo Dec 11, 2025
4a9b1c7
[wip] force use of this in rendering context
ged-odoo Dec 9, 2025
ddede1e
[IMP] force use of this in rendering context (mcm pass)
mcm-odoo Dec 12, 2025
32d300b
[REF] t-esc: replace t-esc by t-out
mcm-odoo Dec 12, 2025
924d7e6
[IMP] playground: replace t-esc by t-out
mcm-odoo Dec 12, 2025
b776a3c
remove t-esc
mcm-odoo Dec 12, 2025
446e022
remove t-esc tests
mcm-odoo Dec 12, 2025
08b49f7
[IMP] t-esc: remove t-esc final pass
mcm-odoo Dec 15, 2025
2c72795
[fix] playground: adapt code
ged-odoo Dec 13, 2025
0e323f3
[ref] rename derived => computed
ged-odoo Dec 15, 2025
05d5e52
[add] playground: add list of counters example
ged-odoo Dec 15, 2025
f01a358
update package.json => v3.0.0-alpha.7
ged-odoo Dec 15, 2025
f897a85
release: alpha.8
ged-odoo Dec 15, 2025
37b99bb
[ref] simplify useEffect, fix onWillDestroy
ged-odoo Dec 16, 2025
0338ea7
v3.0.0-alpha.9
ged-odoo Dec 17, 2025
1b317d8
add: .has method on registry/resource
ged-odoo Dec 19, 2025
c182a6e
add: allow starting an app with plugins list
ged-odoo Dec 22, 2025
e781ebe
make valpha 10
ged-odoo Dec 22, 2025
5854178
expose pluginmanager.current
ged-odoo Jan 5, 2026
4b280fb
fix: computed functions
ged-odoo Jan 6, 2026
4c4174e
v3.0.0-alpha.11
ged-odoo Jan 7, 2026
78a13c2
add default id for plugins
ged-odoo Jan 7, 2026
7eab4e3
allow instantiating a plugin manager without argument
ged-odoo Jan 7, 2026
f8e7d02
allow using $ in expressions symbols
ged-odoo Jan 7, 2026
58737d5
validation: add "extends" key
mcm-odoo Jan 7, 2026
ca84fb2
resource & registry constructor options param
mcm-odoo Jan 8, 2026
16744d9
plugin: some changes
mcm-odoo Jan 9, 2026
31a0c02
useListener: allow it to be used in plugins, change its meaning
ged-odoo Jan 9, 2026
b32bfda
add: useApp hook
ged-odoo Jan 12, 2026
a6d09c6
signals: change api
mcm-odoo Jan 12, 2026
8c43207
update to v3.0.0-alpha.12
ged-odoo Jan 12, 2026
78f60c6
plugins: introduce plugin.props function
ged-odoo Jan 13, 2026
f36b4ed
break cyclic dependencies
ged-odoo Jan 13, 2026
04d5a8a
new validation api
mcm-odoo Jan 13, 2026
93c54d0
rename proxy -> state
ged-odoo Jan 15, 2026
3f20b1c
remove useless computation
ged-odoo Jan 15, 2026
2198fe3
add test, prettify
ged-odoo Jan 16, 2026
07ae8ea
bump version to alpha 13
ged-odoo Jan 18, 2026
c973154
Revert "rename proxy -> state"
ged-odoo Jan 19, 2026
4a241d7
ref: rename registry.remove => registry.delete and resource.remove =>
ged-odoo Jan 19, 2026
53ba9e4
update package.json
mcm-odoo Jan 19, 2026
cd6e3dc
validation tests (props validation still skipped)
mcm-odoo Jan 19, 2026
ae1d440
make useListener work on refs
ged-odoo Jan 19, 2026
a4a3139
implement validation
mcm-odoo Jan 19, 2026
5323c4d
prettier
mcm-odoo Jan 19, 2026
45239df
props validation tests pass
mcm-odoo Jan 19, 2026
203b885
warn on t-slot
mcm-odoo Jan 19, 2026
f958539
bump to v3.0.0-alpha.14
ged-odoo Jan 19, 2026
a3528d9
fix tests
ged-odoo Jan 20, 2026
bea071e
fix t-slot + add test
mcm-odoo Jan 20, 2026
536db59
fix props type
mcm-odoo Jan 20, 2026
234cbbe
improve registry/resource api
ged-odoo Jan 20, 2026
e39a345
plugin manager: allow giving it directly the list of plugins
ged-odoo Jan 20, 2026
f777a2b
export useApp, make the useApp hook usable in plugins at start time
ged-odoo Jan 20, 2026
29f7213
remove this.render
ged-odoo Jan 20, 2026
0cf87b9
bump to version 3.0.0-alpha.15
ged-odoo Jan 20, 2026
a374c37
default props autocompletion
mcm-odoo Jan 22, 2026
d5a4b5e
destroy plugin manager with app
mcm-odoo Jan 22, 2026
17fe561
remove plugin children, destroy children with destroy callback
mcm-odoo Jan 22, 2026
a851c29
plugin input
mcm-odoo Jan 22, 2026
ebf5296
move plugin hooks in own file
mcm-odoo Jan 22, 2026
09f0a90
validate plugin inputs only in dev mode
mcm-odoo Jan 22, 2026
baa9421
plugin manager is not exposed
mcm-odoo Jan 23, 2026
990fbe4
prettier
mcm-odoo Jan 23, 2026
e84bab4
providePlugins now returns nothing
mcm-odoo Jan 23, 2026
2fd0760
give name in resource/registry type validation
mcm-odoo Jan 23, 2026
6572370
remove useComponent
mcm-odoo Jan 23, 2026
625d673
add option to give value type in signal
mcm-odoo Jan 23, 2026
ed3aadd
some renaming in reactivity
mcm-odoo Jan 23, 2026
70f8ddd
test app destroys plugin manager
mcm-odoo Jan 26, 2026
ec519b6
test resource can be used to start plugins
mcm-odoo Jan 26, 2026
b3ad871
start single plugin
mcm-odoo Jan 23, 2026
64631c0
remove App.__current
mcm-odoo Jan 26, 2026
3624793
remove parent property from plugin manager
mcm-odoo Jan 26, 2026
6aa7bcd
prettier
mcm-odoo Jan 26, 2026
c3a2d42
remove uses of runwithcomputation, => make shorter stack
ged-odoo Jan 26, 2026
16df35b
owl context
mcm-odoo Jan 27, 2026
1a18ebc
simplify computations
mcm-odoo Jan 28, 2026
b9f8714
writable computed
mcm-odoo Jan 29, 2026
5a180d2
small rework
mcm-odoo Jan 29, 2026
845cee5
prettier
mcm-odoo Jan 29, 2026
84108c1
fixes
mcm-odoo Jan 30, 2026
99f7b43
rename t.reactive to t.signal
ged-odoo Jan 30, 2026
ad39720
update to v3.0.0-alpha.16
ged-odoo Jan 30, 2026
8b722e3
fix validation tests
mcm-odoo Feb 2, 2026
bc5d208
global context
mcm-odoo Feb 2, 2026
622c99b
rename input to config
mcm-odoo Feb 2, 2026
405c166
give plugin config to app
mcm-odoo Feb 2, 2026
5d5dd90
fix component context
mcm-odoo Feb 2, 2026
49d430c
revert status change
mcm-odoo Feb 2, 2026
914cc77
type `computed.set`
LucasLefevre Feb 3, 2026
a57b3c8
prettier + fix test
ged-odoo Feb 3, 2026
6ad2c6b
update a bunch of dev dependencies
ged-odoo Feb 3, 2026
1e65785
prettier
ged-odoo Feb 3, 2026
e956822
update eslint rc file
ged-odoo Feb 3, 2026
14d628b
bump to 3.0.0-alpha.17
ged-odoo Feb 4, 2026
7787e8b
optional config
mcm-odoo Feb 9, 2026
6f83ccf
rename types.union to types.or
mcm-odoo Feb 11, 2026
53bf2d4
add validator types.and
mcm-odoo Feb 11, 2026
b8c010a
bump to v3.0.0-alpha.18
ged-odoo Feb 13, 2026
c0f5aa0
fix issue with effects not always properly resubscribed
ged-odoo Feb 13, 2026
e4577b5
plugins: prevent plugin manager effect from interfering with effects
ged-odoo Feb 15, 2026
bba628b
bump to v3.0.0-alpha.19
ged-odoo Feb 15, 2026
160b949
some optimizations
ged-odoo Feb 15, 2026
eeda0a6
plugin manager: fix
ged-odoo Feb 17, 2026
6bf3037
prettier
mcm-odoo Feb 17, 2026
23d9feb
fix t-call with empty t-out=0
ged-odoo Feb 18, 2026
1a477e1
[BREAKING] remove t-call on non-t nodes
jum-odoo Jan 21, 2026
6acf619
[BREAKING] parametric t-call
jum-odoo Jan 21, 2026
00d75d0
simplify scoping
ged-odoo Feb 18, 2026
177bacd
remove t-memo
ged-odoo Feb 19, 2026
1675f80
remove captureexpression
ged-odoo Feb 19, 2026
bd8e8e7
prettier
ged-odoo Feb 19, 2026
81a642d
simplify code generator
ged-odoo Feb 19, 2026
cfdf84d
compact foreach flags
ged-odoo Feb 19, 2026
ae49709
fix scoping issue
ged-odoo Feb 19, 2026
2b4e95b
more optimizations
ged-odoo Feb 19, 2026
7a8f199
optimise block compiler
ged-odoo Feb 19, 2026
a923355
move handlers function above function to reuse them
ged-odoo Feb 18, 2026
607258d
mini cleanups
ged-odoo Feb 19, 2026
27388c7
types again
mcm-odoo Feb 19, 2026
756676d
move createComponent from app to template helpers
mcm-odoo Feb 19, 2026
24bb663
move Portal into template helpers
mcm-odoo Feb 19, 2026
420694f
move callTemplate from TemplateSet to template helpers
mcm-odoo Feb 20, 2026
1bce9ad
mark TemplateSet._compileTemplate private
mcm-odoo Feb 20, 2026
6797297
prettier
mcm-odoo Feb 20, 2026
297a3e4
export types
ged-odoo Feb 20, 2026
b348815
bump to v3.0.0-alpha-20
ged-odoo Feb 20, 2026
a3c460b
optimisation: remove defensive props copy
ged-odoo Mar 3, 2026
f3a3b37
fix memory leak + optimization signals
ged-odoo Feb 20, 2026
607b940
add test
ged-odoo Mar 3, 2026
22f7a7a
implement mcm approach
ged-odoo Mar 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 0 additions & 47 deletions .eslintrc

This file was deleted.

10 changes: 5 additions & 5 deletions doc/learning/tutorial_todoapp.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ data and a template to the `App` component:

```js
class Root extends Component {
static template = xml/* xml */ `
static template = xml /* xml */ `
<div class="task-list">
<t t-foreach="tasks" t-as="task" t-key="task.id">
<div class="task">
Expand Down Expand Up @@ -565,7 +565,7 @@ function createTaskStore() {
// Task Component
// -------------------------------------------------------------------------
class Task extends Component {
static template = xml/* xml */ `
static template = xml /* xml */ `
<div class="task" t-att-class="props.task.isCompleted ? 'done' : ''">
<input type="checkbox" t-att-checked="props.task.isCompleted" t-on-click="() => store.toggleTask(props.task)"/>
<span><t t-esc="props.task.text"/></span>
Expand All @@ -583,7 +583,7 @@ class Task extends Component {
// Root Component
// -------------------------------------------------------------------------
class Root extends Component {
static template = xml/* xml */ `
static template = xml /* xml */ `
<div class="todo-app">
<input placeholder="Enter a new task" t-on-keyup="addTask" t-ref="add-input"/>
<div class="task-list">
Expand Down Expand Up @@ -838,7 +838,7 @@ For reference, here is the final code:
// Task Component
// -------------------------------------------------------------------------
class Task extends Component {
static template = xml/* xml */ `
static template = xml /* xml */ `
<div class="task" t-att-class="props.task.isCompleted ? 'done' : ''">
<input type="checkbox"
t-att-id="props.task.id"
Expand All @@ -859,7 +859,7 @@ For reference, here is the final code:
// Root Component
// -------------------------------------------------------------------------
class Root extends Component {
static template = xml/* xml */ `
static template = xml /* xml */ `
<div class="todo-app">
<input placeholder="Enter a new task" t-on-keyup="addTask" t-ref="add-input"/>
<div class="task-list">
Expand Down
3 changes: 1 addition & 2 deletions doc/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ Other hooks:
- [`useComponent`](reference/hooks.md#usecomponent): return a reference to the current component (useful to create derived hooks)
- [`useEffect`](reference/hooks.md#useeffect): define an effect with its dependencies
- [`useEnv`](reference/hooks.md#useenv): return a reference to the current env
- [`useExternalListener`](reference/hooks.md#useexternallistener): add a listener outside of a component DOM
- [`useListener`](reference/hooks.md#uselistener): add a listener outside of a component DOM
- [`useRef`](reference/hooks.md#useref): get an object representing a reference (`t-ref`)
- [`useChildSubEnv`](reference/hooks.md#usesubenv-and-usechildsubenv): extend the current env with additional information (for child components)
- [`useSubEnv`](reference/hooks.md#usesubenv-and-usechildsubenv): extend the current env with additional information (for current component and child components)

Utility/helpers:

- [`EventBus`](reference/utils.md#eventbus): a simple event bus
- [`loadFile`](reference/utils.md#loadfile): an helper to load a file from the server
- [`markup`](reference/templates.md#outputting-data): utility function to define strings that represent html (should not be escaped)
- [`status`](reference/component.md#status-helper): utility function to get the status of a component (new, mounted or destroyed)
- [`validate`](reference/utils.md#validate): validates if an object satisfies a specified schema
Expand Down
3 changes: 1 addition & 2 deletions doc/reference/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ instance somewhere in the DOM.
is complete.

The `option` object is an object with the following keys:

- **`position (string)`**: either `first-child` or `last-child`. This option determines
the position of the application in the target: either first or last child.

Expand Down Expand Up @@ -130,7 +129,7 @@ what it could look like in practice:

```js
// in the main js file:
const { loadFile, mount } = owl;
const { mount } = owl;

// async, so we can use async/await
(async function setup() {
Expand Down
3 changes: 0 additions & 3 deletions doc/reference/concurrency_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ component (with some code like `app.mount(document.body)`).
1. `willStart` is called on `A`

2. when it is done, template `A` is rendered.

- component `B` is created
1. `willStart` is called on `B`
2. template `B` is rendered
Expand Down Expand Up @@ -116,7 +115,6 @@ Here is what Owl will do:

1. because of a state change, the method `render` is called on `C`
2. template `C` is rendered again

- component `D` is updated:
1. hook `willUpdateProps` is called on `D` (async)
2. template `D` is rerendered
Expand All @@ -130,7 +128,6 @@ Here is what Owl will do:
4. components `F`, `D` are patched in that order

5. component `C` is patched, which will cause recursively:

1. `willUnmount` hook on `E`
2. destruction of `E`,

Expand Down
8 changes: 4 additions & 4 deletions doc/reference/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- [`useState`](#usestate)
- [`useRef`](#useref)
- [`useSubEnv` and `useChildSubEnv`](#usesubenv-and-usechildsubenv)
- [`useExternalListener`](#useexternallistener)
- [`useListener`](#uselistener)
- [`useComponent`](#usecomponent)
- [`useEnv`](#useenv)
- [`useEffect`](#useeffect)
Expand Down Expand Up @@ -187,16 +187,16 @@ frozen, to prevent unwanted modifications.
Note that both these hooks can be called an arbitrary number of times. The `env`
will then be updated accordingly.

### `useExternalListener`
### `useListener`

The `useExternalListener` hook helps solve a very common problem: adding and removing
The `useListener` hook helps solve a very common problem: adding and removing
a listener on some target whenever a component is mounted/unmounted. It takes a target
as its first argument, forwards the other arguments to `addEventListener`. For example,
a dropdown menu (or its parent) may need to listen to a `click` event on `window`
to be closed:

```js
useExternalListener(window, "click", this.closeMenu, { capture: true });
useListener(window, "click", this.closeMenu, { capture: true });
```

### `useComponent`
Expand Down
16 changes: 0 additions & 16 deletions doc/reference/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ functions are all available in the `owl.utils` namespace.
## Content

- [`whenReady`](#whenready): executing code when DOM is ready
- [`loadFile`](#loadfile): loading a file (useful for templates)
- [`EventBus`](#eventbus): a simple EventBus
- [`validate`](#validate): a validation function
- [`batched`](#batched): batch function calls
Expand All @@ -32,21 +31,6 @@ whenReady(function () {
});
```

## `loadFile`

`loadFile` is a helper function to fetch a file. It simply
performs a `GET` request and returns the resulting string in a promise. The
initial usecase for this function is to load a template file. For example:

```js
const { loadFile } = owl;

async function makeEnv() {
const templates = await loadFile("templates.xml");
// do something
}
```

## `EventBus`

It is a simple `EventBus`, with the same API as usual DOM elements, and an
Expand Down
59 changes: 36 additions & 23 deletions docs/playground/playground.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { debounce, loadJS } from "./utils.js";
import {
App,
__info__,
Component,
useState,
useRef,
mount,
onMounted,
onWillUnmount,
onPatched,
onWillStart,
onWillUnmount,
onWillUpdateProps,
loadFile as _loadFile,
whenReady,
__info__,
OwlError,
props,
proxy,
signal,
useEffect,
onWillStart,
whenReady,
} from "../owl.js";
import { debounce, loadJS } from "./utils.js";

//------------------------------------------------------------------------------
// Constants, helpers, utils
Expand All @@ -32,7 +33,12 @@ const DEFAULT_XML = `<templates>
const fileCache = {};
const loadFile = (path) => {
if (!(path in fileCache)) {
fileCache[path] = _loadFile(path);
fileCache[path] = fetch(path).then((result) => {
if (!result.ok) {
throw new OwlError("Error while fetching xml templates");
}
return result.text();
});
}
return fileCache[path];
}
Expand Down Expand Up @@ -75,7 +81,12 @@ const SAMPLES = [
code: ["js", "xml", "css"],
},
{
description: "Form Input Bindings",
description: "List of Counters",
folder: "counters",
code: ["js", "xml", "css"],
},
{
description: "t-model",
folder: "form",
code: ["js", "xml"],
},
Expand Down Expand Up @@ -145,23 +156,25 @@ function loadSamples() {
// Tabbed editor
//------------------------------------------------------------------------------
class TabbedEditor extends Component {
props = props();

setup() {
const props = this.props;
this.state = useState({
this.state = proxy({
currentTab: props.js !== false ? "js" : props.xml ? "xml" : "css"
});
this.setTab = debounce(this.setTab.bind(this), 250, true);

this.sessions = {};
this._setupSessions(props);
this.editorNode = useRef("editor");
this.editorNode = signal(null);
this._updateCode = this._updateCode.bind(this);

onMounted(() => {
this.editor = this.editor || ace.edit(this.editorNode.el);
this.editor = this.editor || ace.edit(this.editorNode());

this.editor.setValue(this.props[this.state.currentTab], -1);
this.editor.setFontSize("12px");
this.editor.setFontSize("14px");
this.editor.setTheme("ace/theme/monokai");
this.editor.setSession(this.sessions[this.state.currentTab]);
const tabSize = this.state.currentTab === "xml" ? 2 : 4;
Expand Down Expand Up @@ -252,7 +265,7 @@ class Playground extends Component {
this.version = __info__.version;

this.isDirty = false;
this.state = useState({
this.state = proxy({
js: "",
css: "",
xml: DEFAULT_XML,
Expand Down Expand Up @@ -290,17 +303,17 @@ class Playground extends Component {
this.toggleLayout = debounce(this.toggleLayout, 250, true);
this.runCode = debounce(this.runCode, 250, true);
this.exportStandaloneApp = debounce(this.exportStandaloneApp, 250, true);
this.content = useRef("content");
this.content = signal(null);
this.updateCode = this.updateCode.bind(this);
}

runCode() {
this.content.el.innerHTML = "";
this.content().innerHTML = "";
this.state.displayWelcome = false;

const { js, css, xml } = this.state;
const subiframe = makeCodeIframe(js, css, xml);
this.content.el.appendChild(subiframe);
this.content().appendChild(subiframe);
}

shareCode() {
Expand Down Expand Up @@ -394,10 +407,10 @@ async function start() {
loadFile("templates.xml"),
whenReady()
]);
const rootApp = new App(Playground, { name: "Owl Playground" });
rootApp.addTemplates(templates);

await rootApp.mount(document.body);
await mount(Playground, document.body, {
name: "Owl Playground",
templates,
});
}

start();
4 changes: 2 additions & 2 deletions docs/playground/samples/components/components.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.greeter {
.counter {
font-size: 20px;
width: 300px;
height: 100px;
Expand All @@ -7,4 +7,4 @@
line-height: 100px;
background-color: #eeeeee;
user-select: none;
}
}
23 changes: 8 additions & 15 deletions docs/playground/samples/components/components.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
// In this example, we show how components can be defined and created.
import { Component, useState, mount } from "@odoo/owl";
import { Component, signal, mount } from "@odoo/owl";

class Greeter extends Component {
static template = "Greeter";
class Counter extends Component {
static template = "Counter";

setup() {
this.state = useState({ word: 'Hello' });
}

toggle() {
this.state.word = this.state.word === 'Hi' ? 'Hello' : 'Hi';
count = signal(0);

increment() {
this.count.update(val => val + 1);
}
}

// Main root component
class Root extends Component {
static components = { Greeter };
static components = { Counter };
static template = "Root"

setup() {
this.state = useState({ name: 'World'});
}
}

mount(Root, document.body, { templates: TEMPLATES, dev: true });
Loading