mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] component: add static css support for sub components
part of issue #80
This commit is contained in:
+29
-8
@@ -4,7 +4,7 @@
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Example](#example)
|
||||
- [Templates](#templates)
|
||||
- [Composition](#composition)
|
||||
- [Reference](#reference)
|
||||
- [Properties](#properties)
|
||||
- [Methods](#methods)
|
||||
@@ -65,7 +65,7 @@ a state object is defined. It is not mandatory to use the state object, but it
|
||||
is certainly encouraged. The state object is [observed](observer.md), and any
|
||||
change to it will cause a rerendering.
|
||||
|
||||
## Templates
|
||||
## Composition
|
||||
|
||||
The example above shows a QWeb template with a `t-on-click` directive. Widget
|
||||
templates are standard [QWeb](qweb.md) templates, but with an extra directive:
|
||||
@@ -73,18 +73,39 @@ templates are standard [QWeb](qweb.md) templates, but with an extra directive:
|
||||
widgets:
|
||||
|
||||
```xml
|
||||
<div>
|
||||
<span>some text</span>
|
||||
<t t-widget="MyWidget" t-props="{info: 13}">
|
||||
</div>
|
||||
<div t-name="parent">
|
||||
<span>some text</span>
|
||||
<t t-widget="MyWidget" t-props="{info: 13}">
|
||||
</div>
|
||||
```
|
||||
|
||||
In this example, the template create a widget MyWidget just after the span. See
|
||||
the [QWeb](qweb.md) documentation for more information on the `t-widget` directive.
|
||||
```js
|
||||
class ParentWidget extends owl.Component {
|
||||
template = 'parent';
|
||||
widgets = { MyWidget: MyWidget};
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the `ParentWidget`'s template creates a widget `MyWidget` just
|
||||
after the span. See the [QWeb](qweb.md) documentation for more information on the
|
||||
`t-widget` directive.
|
||||
|
||||
Note that the rendering context for the template is the widget itself. This means
|
||||
that the template can access `state`, `props`, `env`, or any methods defined in the widget.
|
||||
|
||||
**CSS and style:** there is some specific support to allow the parent to declare
|
||||
additional css classes or style for the sub widget: css declared in `class`, `style`, `t-att-class` or `t-att-style` will be added to the
|
||||
root widget element.
|
||||
|
||||
```xml
|
||||
<div t-name="parent">
|
||||
<t t-widget="MyWidget" class="someClass" style="font-weight:bold;" t-props="{info: 13}">
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Reference
|
||||
|
||||
An Owl component is a small class which represent a widget or some UI element.
|
||||
|
||||
+14
-1
@@ -1212,8 +1212,21 @@ const widgetDirective: Directive = {
|
||||
finalizeWidgetCode += `;delete context.refs[${refKey}]`;
|
||||
}
|
||||
ctx.addIf(`isNew${widgetID}`);
|
||||
let createHook = "";
|
||||
let classAttr = node.getAttribute("class");
|
||||
let styleAttr = node.getAttribute("style");
|
||||
if (classAttr || styleAttr) {
|
||||
const classCode = classAttr
|
||||
? classAttr
|
||||
.split(" ")
|
||||
.map(c => `vn.elm.classList.add('${c}')`)
|
||||
.join(";") + ";"
|
||||
: "";
|
||||
const styleCode = styleAttr ? `vn.elm.style = '${styleAttr}'` : "";
|
||||
createHook = `vnode.data.hook = {create(_, vn){${classCode}${styleCode}}};`;
|
||||
}
|
||||
ctx.addLine(
|
||||
`def${defID} = def${defID}.then(vnode=>{let pvnode=h(vnode.sel, {key: ${templateID}});c${
|
||||
`def${defID} = def${defID}.then(vnode=>{${createHook}let pvnode=h(vnode.sel, {key: ${templateID}});c${
|
||||
ctx.parentNode
|
||||
}[_${dummyID}_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w${widgetID}._mount(vnode, vn.elm);pvnode.elm=nvn.elm;${refExpr}},remove(){${finalizeWidgetCode}},destroy(){${finalizeWidgetCode}}}; w${widgetID}.__owl__.pvnode = pvnode;});`
|
||||
);
|
||||
|
||||
@@ -1224,6 +1224,37 @@ describe("props evaluation (with t-props directive)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("class and style attributes with t-widget", () => {
|
||||
test("class is properly added on widget root el", async () => {
|
||||
class ParentWidget extends Widget {
|
||||
inlineTemplate = `
|
||||
<div>
|
||||
<t t-widget="child" class="a b"/>
|
||||
</div>`;
|
||||
widgets = { child: Child };
|
||||
}
|
||||
class Child extends Widget {
|
||||
inlineTemplate = `<div class="c"/>`
|
||||
}
|
||||
const widget = new ParentWidget(env);
|
||||
await widget.mount(fixture);
|
||||
expect(fixture.innerHTML).toBe(`<div><div class="c a b"></div></div>`);
|
||||
});
|
||||
|
||||
test("style is properly added on widget root el", async () => {
|
||||
class ParentWidget extends Widget {
|
||||
inlineTemplate = `
|
||||
<div>
|
||||
<t t-widget="child" style="font-weight: bold;"/>
|
||||
</div>`;
|
||||
widgets = { child: Widget };
|
||||
}
|
||||
const widget = new ParentWidget(env);
|
||||
await widget.mount(fixture);
|
||||
expect(fixture.innerHTML).toBe(`<div><div style="font-weight: bold;"></div></div>`);
|
||||
});
|
||||
});
|
||||
|
||||
describe("other directives with t-widget", () => {
|
||||
test("t-on works as expected", async () => {
|
||||
let n = 0;
|
||||
|
||||
Reference in New Issue
Block a user