Skip to content
Open

owl 3.x #1780

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
184 commits
Select commit Hold shift + click to select a range
7303f37
[IMP] introduce signals and derived values
Goaman Sep 26, 2025
a8620b5
[ref] update package-lock.json
ged-odoo Nov 20, 2025
89669d7
[rel] update package.json
ged-odoo Nov 21, 2025
b0fb304
[ADD] add registry and plugin system
ged-odoo Nov 20, 2025
adaf3aa
[notes] add release notes
ged-odoo Nov 24, 2025
d558e44
[rel] update package.json to 3.0.0-alpha.2
ged-odoo Nov 24, 2025
06078b7
[imp] improve typing, fix registry validation code
ged-odoo Nov 24, 2025
ac8d8af
[rel] update version to alpha.4
ged-odoo Nov 24, 2025
91c26e8
[fix] registry: make it work, add addById method
ged-odoo Nov 24, 2025
cd8691e
v3.0.0-alpha.5
ged-odoo Nov 24, 2025
84da898
[REM] utils: remove loadFile
ged-odoo Dec 2, 2025
4f06e2a
[ref] signals: change their api
ged-odoo Dec 2, 2025
4231b4e
[ref] plugins: change api
mcm-odoo Dec 2, 2025
623ad1d
[IMP] plugins: test with components
mcm-odoo Dec 2, 2025
a607693
[FIX] plugins: fix resource tests
mcm-odoo Dec 2, 2025
f3bb447
[ref] utils: rename useExternalListener to useListener
ged-odoo Dec 2, 2025
ad2ff8a
[ref] rename useState/reactive => proxy
ged-odoo Dec 2, 2025
65cf357
[imp] update package.json dev dependencies
ged-odoo Dec 2, 2025
508cd86
[imp] streamline app API (Root/subroots => roots)
mcm-odoo Dec 2, 2025
2128505
[fix] various fixes to make the previous commits work
ged-odoo Dec 2, 2025
4561e24
[FIX] playground: fix playground
mcm-odoo Dec 4, 2025
3cf7f1f
[FIX] revamp error handling code, only throw error once in some cases
ged-odoo Dec 3, 2025
554d3b5
[IMP] reactivity: add Signal.update method
ged-odoo Dec 4, 2025
881c9d2
[REF] runtime: move code around to make it clearer
ged-odoo Dec 4, 2025
4c1e807
[REF] reactivity: split code into multiple files
ged-odoo Dec 4, 2025
d7b31ad
[REF] rename withoutReactivity => untrack
ged-odoo Dec 4, 2025
f1734ba
[REF] reactivity: move tests
ged-odoo Dec 4, 2025
a04552d
[REF] mini cleanup, remove commont/types file
ged-odoo Dec 4, 2025
54cdf58
[IMP] app: remove warnIfNoStaticProps
mcm-odoo Dec 8, 2025
4749c37
[FIX] app: fix mount return type
mcm-odoo Dec 8, 2025
7faadf1
[IMP] props: introduce props function
mcm-odoo Dec 8, 2025
1cdd072
[IMP] prettify
mcm-odoo Dec 8, 2025
114cd5e
[imp] add Resource, make registry chainable
ged-odoo Dec 8, 2025
9cab2b3
[IMP] add Registry.remove, Resource.remove, rename Registry.get => Re…
ged-odoo Dec 8, 2025
a14b12d
update snapshots
ged-odoo Dec 8, 2025
eeba18a
[imp] error: simplify error handling
ged-odoo Dec 8, 2025
2196a24
[imp] simplify plugin and resources system
ged-odoo Dec 9, 2025
86316c0
[add] add some tests for resource
ged-odoo Dec 9, 2025
d9ef644
[IMP] props: improve props types again
mcm-odoo Dec 9, 2025
dce7d8a
[IMP] hooks: remove env related hooks
mcm-odoo Dec 9, 2025
df82e05
[IMP] hooks: remove env related hooks
mcm-odoo Dec 9, 2025
c4477a3
[IMP] props: move default props to props function
mcm-odoo Dec 9, 2025
c7fe10c
[REF] slot: rename t-slot into t-call-slot
mcm-odoo Dec 9, 2025
51fca90
[rem] remove onWillRender and onRendered
ged-odoo Dec 9, 2025
023aeec
[imp] slots: do not get props from component, but from component node
ged-odoo Dec 10, 2025
d0c9ece
[IMP] ref: replace useRef by signal
mcm-odoo Dec 10, 2025
38dff57
[REF] blockdom: simplify ref system
mcm-odoo Dec 11, 2025
4f4ced9
[IMP] ref: use resource to get multiple refs at once
mcm-odoo Dec 11, 2025
d923821
[IMP] t-model: support signal instead of proxy
mcm-odoo Dec 11, 2025
a757abc
[IMP] status: status is now a hook
mcm-odoo Dec 11, 2025
053ff74
[IMP] plugin: plugin manager now has a status
mcm-odoo Dec 11, 2025
fa08656
[FIX] blockdom: cbRefs used the wrong idx
mcm-odoo Dec 11, 2025
3e396e8
[FIX] playground: update playground
mcm-odoo Dec 11, 2025
780abd9
[ref] rework error handling code
ged-odoo Dec 11, 2025
2a3738f
[wip] force use of this in rendering context
ged-odoo Dec 9, 2025
ed81ff8
[IMP] force use of this in rendering context (mcm pass)
mcm-odoo Dec 12, 2025
4ea0590
[REF] t-esc: replace t-esc by t-out
mcm-odoo Dec 12, 2025
7e87cea
[IMP] playground: replace t-esc by t-out
mcm-odoo Dec 12, 2025
715cfeb
remove t-esc
mcm-odoo Dec 12, 2025
391a47c
remove t-esc tests
mcm-odoo Dec 12, 2025
d7ac27f
[IMP] t-esc: remove t-esc final pass
mcm-odoo Dec 15, 2025
cb747b8
[fix] playground: adapt code
ged-odoo Dec 13, 2025
ea89cbb
[ref] rename derived => computed
ged-odoo Dec 15, 2025
713c156
[add] playground: add list of counters example
ged-odoo Dec 15, 2025
a658013
update package.json => v3.0.0-alpha.7
ged-odoo Dec 15, 2025
432cad8
release: alpha.8
ged-odoo Dec 15, 2025
fef27e8
[ref] simplify useEffect, fix onWillDestroy
ged-odoo Dec 16, 2025
1171f99
v3.0.0-alpha.9
ged-odoo Dec 17, 2025
1740a07
add: .has method on registry/resource
ged-odoo Dec 19, 2025
38c1de7
add: allow starting an app with plugins list
ged-odoo Dec 22, 2025
4481fef
make valpha 10
ged-odoo Dec 22, 2025
d454847
expose pluginmanager.current
ged-odoo Jan 5, 2026
5d8519b
fix: computed functions
ged-odoo Jan 6, 2026
792f9c1
v3.0.0-alpha.11
ged-odoo Jan 7, 2026
887062a
add default id for plugins
ged-odoo Jan 7, 2026
d680f4c
allow instantiating a plugin manager without argument
ged-odoo Jan 7, 2026
5bb2bb5
allow using $ in expressions symbols
ged-odoo Jan 7, 2026
680aca4
validation: add "extends" key
mcm-odoo Jan 7, 2026
85ba7ae
resource & registry constructor options param
mcm-odoo Jan 8, 2026
eac731f
plugin: some changes
mcm-odoo Jan 9, 2026
1e94f23
useListener: allow it to be used in plugins, change its meaning
ged-odoo Jan 9, 2026
c7e2b27
add: useApp hook
ged-odoo Jan 12, 2026
cdd2ede
signals: change api
mcm-odoo Jan 12, 2026
8c3cb7c
update to v3.0.0-alpha.12
ged-odoo Jan 12, 2026
07fb034
plugins: introduce plugin.props function
ged-odoo Jan 13, 2026
9270474
break cyclic dependencies
ged-odoo Jan 13, 2026
e9551ba
new validation api
mcm-odoo Jan 13, 2026
46ae0c2
rename proxy -> state
ged-odoo Jan 15, 2026
7b56918
remove useless computation
ged-odoo Jan 15, 2026
b0def47
add test, prettify
ged-odoo Jan 16, 2026
975e229
bump version to alpha 13
ged-odoo Jan 18, 2026
0bce7db
Revert "rename proxy -> state"
ged-odoo Jan 19, 2026
a73eb21
ref: rename registry.remove => registry.delete and resource.remove =>
ged-odoo Jan 19, 2026
b0f6273
update package.json
mcm-odoo Jan 19, 2026
3276cad
validation tests (props validation still skipped)
mcm-odoo Jan 19, 2026
7c098ba
make useListener work on refs
ged-odoo Jan 19, 2026
18d6c53
implement validation
mcm-odoo Jan 19, 2026
cf0891b
prettier
mcm-odoo Jan 19, 2026
4a033b1
props validation tests pass
mcm-odoo Jan 19, 2026
b8550b5
warn on t-slot
mcm-odoo Jan 19, 2026
a6d5bcf
bump to v3.0.0-alpha.14
ged-odoo Jan 19, 2026
ec05b34
fix tests
ged-odoo Jan 20, 2026
505a62d
fix t-slot + add test
mcm-odoo Jan 20, 2026
614e0fc
fix props type
mcm-odoo Jan 20, 2026
7d4fad5
improve registry/resource api
ged-odoo Jan 20, 2026
1d3b5e6
plugin manager: allow giving it directly the list of plugins
ged-odoo Jan 20, 2026
62030b9
export useApp, make the useApp hook usable in plugins at start time
ged-odoo Jan 20, 2026
15b71f7
remove this.render
ged-odoo Jan 20, 2026
f9b9ef3
bump to version 3.0.0-alpha.15
ged-odoo Jan 20, 2026
d51cbfb
default props autocompletion
mcm-odoo Jan 22, 2026
a39a835
destroy plugin manager with app
mcm-odoo Jan 22, 2026
aa3eb16
remove plugin children, destroy children with destroy callback
mcm-odoo Jan 22, 2026
db0e65c
plugin input
mcm-odoo Jan 22, 2026
fb90d76
move plugin hooks in own file
mcm-odoo Jan 22, 2026
4c77f19
validate plugin inputs only in dev mode
mcm-odoo Jan 22, 2026
d9c5958
plugin manager is not exposed
mcm-odoo Jan 23, 2026
dc8e727
prettier
mcm-odoo Jan 23, 2026
6f9fcc1
providePlugins now returns nothing
mcm-odoo Jan 23, 2026
752a743
give name in resource/registry type validation
mcm-odoo Jan 23, 2026
a95ec3b
remove useComponent
mcm-odoo Jan 23, 2026
58842e7
add option to give value type in signal
mcm-odoo Jan 23, 2026
8541311
some renaming in reactivity
mcm-odoo Jan 23, 2026
2c80526
test app destroys plugin manager
mcm-odoo Jan 26, 2026
2d4f103
test resource can be used to start plugins
mcm-odoo Jan 26, 2026
ba11264
start single plugin
mcm-odoo Jan 23, 2026
296a1a7
remove App.__current
mcm-odoo Jan 26, 2026
67b506a
remove parent property from plugin manager
mcm-odoo Jan 26, 2026
6848aa5
prettier
mcm-odoo Jan 26, 2026
1ebfc99
remove uses of runwithcomputation, => make shorter stack
ged-odoo Jan 26, 2026
7848618
owl context
mcm-odoo Jan 27, 2026
c66ad75
simplify computations
mcm-odoo Jan 28, 2026
24be71c
writable computed
mcm-odoo Jan 29, 2026
fd83e30
small rework
mcm-odoo Jan 29, 2026
6e90bf7
prettier
mcm-odoo Jan 29, 2026
bdce598
fixes
mcm-odoo Jan 30, 2026
5c07829
rename t.reactive to t.signal
ged-odoo Jan 30, 2026
cfef9f0
update to v3.0.0-alpha.16
ged-odoo Jan 30, 2026
f02f600
fix validation tests
mcm-odoo Feb 2, 2026
837913a
global context
mcm-odoo Feb 2, 2026
8dc1703
rename input to config
mcm-odoo Feb 2, 2026
24b8f16
give plugin config to app
mcm-odoo Feb 2, 2026
f1d017c
fix component context
mcm-odoo Feb 2, 2026
d096de8
revert status change
mcm-odoo Feb 2, 2026
f728821
type `computed.set`
LucasLefevre Feb 3, 2026
1e874cb
prettier + fix test
ged-odoo Feb 3, 2026
a848998
update a bunch of dev dependencies
ged-odoo Feb 3, 2026
957265d
prettier
ged-odoo Feb 3, 2026
bef4c5d
update eslint rc file
ged-odoo Feb 3, 2026
e99cbe3
bump to 3.0.0-alpha.17
ged-odoo Feb 4, 2026
1eea236
optional config
mcm-odoo Feb 9, 2026
7989be7
rename types.union to types.or
mcm-odoo Feb 11, 2026
ec59e47
add validator types.and
mcm-odoo Feb 11, 2026
5824aa4
bump to v3.0.0-alpha.18
ged-odoo Feb 13, 2026
22156cc
fix issue with effects not always properly resubscribed
ged-odoo Feb 13, 2026
59ef055
plugins: prevent plugin manager effect from interfering with effects
ged-odoo Feb 15, 2026
64a6485
bump to v3.0.0-alpha.19
ged-odoo Feb 15, 2026
00c29e8
some optimizations
ged-odoo Feb 15, 2026
5a31cc8
plugin manager: fix
ged-odoo Feb 17, 2026
4cc9f40
prettier
mcm-odoo Feb 17, 2026
fbc4202
fix t-call with empty t-out=0
ged-odoo Feb 18, 2026
0d0e756
[BREAKING] remove t-call on non-t nodes
jum-odoo Jan 21, 2026
5c6992c
[BREAKING] parametric t-call
jum-odoo Jan 21, 2026
5e67d47
simplify scoping
ged-odoo Feb 18, 2026
4973840
remove t-memo
ged-odoo Feb 19, 2026
91bb8be
remove captureexpression
ged-odoo Feb 19, 2026
d51b601
prettier
ged-odoo Feb 19, 2026
6cb480d
simplify code generator
ged-odoo Feb 19, 2026
e780383
compact foreach flags
ged-odoo Feb 19, 2026
e707387
fix scoping issue
ged-odoo Feb 19, 2026
47250b7
more optimizations
ged-odoo Feb 19, 2026
ec3a1f3
optimise block compiler
ged-odoo Feb 19, 2026
072d356
move handlers function above function to reuse them
ged-odoo Feb 18, 2026
d3b6a80
mini cleanups
ged-odoo Feb 19, 2026
136554a
types again
mcm-odoo Feb 19, 2026
001f613
move createComponent from app to template helpers
mcm-odoo Feb 19, 2026
289942d
move Portal into template helpers
mcm-odoo Feb 19, 2026
febe0fd
move callTemplate from TemplateSet to template helpers
mcm-odoo Feb 20, 2026
6a7be5c
mark TemplateSet._compileTemplate private
mcm-odoo Feb 20, 2026
7952b60
prettier
mcm-odoo Feb 20, 2026
85237ba
export types
ged-odoo Feb 20, 2026
dba8f58
bump to v3.0.0-alpha-20
ged-odoo Feb 20, 2026
7d4b8d6
optimisation: remove defensive props copy
ged-odoo Mar 3, 2026
88bceb7
fix memory leak + optimization signals
ged-odoo Feb 20, 2026
af46657
auto -alike arrow functions if possible
ged-odoo Mar 4, 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