You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BREAKING CHANGE: `content` property is no longer supported. The `render` property must be used. In some cases usage of the `shadow` option might be required.
Copy file name to clipboardExpand all lines: docs/component-model/structure.md
+38-70
Original file line number
Diff line number
Diff line change
@@ -12,10 +12,10 @@ The cache mechanism uses equality check to compare values (`nextValue` !== `last
12
12
13
13
## Reserved Keys
14
14
15
-
There are three reserved property names in the definition:
15
+
There are two reserved property names in the definition:
16
16
17
17
*`tag` - a string which sets the custom element tag name
18
-
*`render`and `content`, which expect the value as a function, and have additional options available
18
+
*`render`- expects its value as a function for rendering the internal structure of the custom element
19
19
20
20
## Translation
21
21
@@ -53,7 +53,7 @@ define({
53
53
});
54
54
```
55
55
56
-
Usually, the shorthand definition is more readable and less verbose, but the second one gives more control over the property behavior, as it provides additional options.
56
+
Usually, the shorthand syntax is more readable and less verbose, but the second one gives more control over the property behavior, as it provides additional options.
57
57
58
58
## Attributes
59
59
@@ -286,17 +286,29 @@ define({
286
286
});
287
287
```
288
288
289
-
## `render` & `content`
289
+
## `render`
290
290
291
-
The `render`and `content` properties are reserved for the rendering structure of the custom element. The `value` option must be a function, which returns a result of the call to the built-in template engine or a custom update function.
291
+
The `render`property is reserved for the creating a structure of the custom element. The `value` option must be a function, which returns a result of the call to the built-in template engine.
292
292
293
-
The library uses internally the `observe` pattern to called function automatically when dependencies change. As the property returns an update function, it can also be called manually, by `el.render()` or `el.content()`.
293
+
The library uses internally the `observe` pattern to call the function automatically when dependencies change. As the property resolves to the update function, it can also be called manually, by `el.render()` or `el.content()`.
294
294
295
-
> You can use built-in [template engine](/component/templates.md) with those properties without additional code
295
+
### Element's Content
296
+
297
+
By default `render` property updates the content of the custom element:
298
+
299
+
```javascript
300
+
import { define, html } from"hybrids";
301
+
302
+
define({
303
+
tag:"my-element",
304
+
name:"",
305
+
render: ({ name }) =>html`<h1>Hello ${name}!</h1>`,
306
+
});
307
+
```
296
308
297
309
### Shadow DOM
298
310
299
-
Use the `render` key for the internal structure of the custom element, where you can add isolated styles, slot elements, etc.
311
+
If the root template of the element includes styles (`css` and `style` helpers, or `<style>` elements) or `<slot>` element, the library will render the content to the shadow DOM:
300
312
301
313
```javascript
302
314
import { define, html } from"hybrids";
@@ -313,88 +325,44 @@ define({
313
325
});
314
326
```
315
327
316
-
The `render` property provides unique `options` key for passing additional arguments to `host.attachShadow()` method:
328
+
!> Templates are compiled lazy, so only the root template can be used to determine the rendering mode. If your nested template includes styles or slots, you must use the `shadow` option to force rendering in the Shadow DOM
329
+
330
+
### Explicit Mode
331
+
332
+
Use unique `shadow` option of the `render` property to force rendering in Shadow DOM or element's content:
317
333
318
334
```ts
335
+
// Disable Shadow DOM
319
336
render: {
320
-
value: (host) => { ... },
321
-
options: {
322
-
mode:"open"|"closed",
323
-
delegatesFocus: boolean,
324
-
},
337
+
value: (host) =>html`...`,
338
+
shadow:false,
325
339
...
326
340
}
341
+
342
+
// Enable Shadow DOM
343
+
render: {
344
+
value: (host) =>html`...`,
345
+
shadow:true,
346
+
}
327
347
```
328
348
349
+
You can use `shadow` option for passing custom argument to the `host.attachShadow()` method:
350
+
329
351
```javascript
330
352
import { define, html } from"hybrids";
331
353
332
354
define({
333
355
tag:"my-element",
334
356
render: {
335
357
value:html`<div>...</div>`,
336
-
options: { delegatesFocus:true },
358
+
options: { mode:"close", delegatesFocus:true },
337
359
},
338
360
});
339
361
```
340
362
341
-
### Element's Content
342
-
343
-
Use the `content` property for rendering templates in the content of the custom element. By the design, it does not support isolated styles, slot elements, etc.
344
-
345
-
However, it is the way to build an app-like views structure, which can be rendered as a document content in light DOM. It is easily accessible in developer tools and search engines. For example, form elements (like `<input>`) have to be in the same subtree with the `<form>` element.
346
-
347
-
```javascript
348
-
import { define, html } from"hybrids";
349
-
350
-
define({
351
-
tag:"my-element",
352
-
name:"",
353
-
content: ({ name }) =>html`<h1>Hello ${name}!</h1>`
354
-
});
355
-
```
356
-
357
-
### Custom Function
358
-
359
-
The preferred way is to use a built-in [template engine](/component/templates.md), but you can use any function to update the DOM of the custom element, which accepts the following structure:
360
-
361
-
```javascript
362
-
importReactfrom"react";
363
-
importReactDOMfrom"react-dom";
364
-
365
-
exportdefaultfunctionreactify(fn) {
366
-
return (host) => {
367
-
// get the component using the fn and host element
368
-
constComponent=fn(host);
369
-
370
-
// return the update function
371
-
return (host, target) => {
372
-
ReactDOM.render(Component, target);
373
-
}
374
-
}
375
-
}
376
-
```
377
-
378
-
```javascript
379
-
importreactifyfrom"./reactify.js";
380
-
381
-
functionMyComponent({ name }) {
382
-
return<div>{name}</div>;
383
-
}
384
-
385
-
define({
386
-
tag:"my-element",
387
-
render:reactify(({ name }) =><MyComponent name={name} />),
388
-
})
389
-
```
390
-
391
-
The above example uses the [`factory` pattern](#factories), to produce a function, which accepts the host element and returns the update function, which has `host` and `target` arguments. The `target` argument in the update function can be a `host` or `host.shadowRoot` depending on the property name.
392
-
393
-
!> The other properties from the `host` must be called in the main function body (not in the update function), as only then they will be correctly observed
394
-
395
363
### Reference Internals
396
364
397
-
Both`render`and `content` properties can be used to reference internals of the custom element. The DOM update process is asynchronous, so to avoid rendering timing issues, always use a property as a reference to the target element. If the property depending on `render` or `content` is called before the first update, the update will be triggered manually by calling the function.
365
+
The`render`property can be used to reference internals of the custom element. The DOM update process is asynchronous, so to avoid rendering timing issues, always use a property as a reference to the target element. If the property depending on `render` is called before the first update, the update will be triggered manually by calling the function.
Copy file name to clipboardExpand all lines: docs/migration.md
+38-6
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
## v9.0.0
4
4
5
-
The `v9.0` release brings simplification into the full object property descriptor and moves out some rarely used default behaviors into optional features.
5
+
The `v9.0` release brings simplification into the full object property descriptor, removes the `content` property, and moves out some rarely used default behaviors into optional features.
6
6
7
7
### Descriptors
8
8
@@ -49,11 +49,11 @@ Writable properties are no longer automatically synchronized back to the attribu
49
49
50
50
Read more about the attribute synchronization in the [Structure](/component-model/structure.md#reflect) section.
51
51
52
-
### Render and Content
52
+
### Render Property
53
53
54
-
#### Keys
54
+
#### Key
55
55
56
-
The `render`and `content` properties are now reserved and expect an update function as a value (they cannot be used for other purpose). If you defined them as a full descriptor with custom behavior, you must rename them:
56
+
The `render`property is now reserved and expects an update function as a value (it cannot be used for other purpose). If you defined it as a full descriptor with custom behavior, you must rename the property:
57
57
58
58
```javascript
59
59
// before
@@ -74,7 +74,39 @@ The `render` and `content` properties are now reserved and expect an update func
74
74
}
75
75
```
76
76
77
-
#### Shadow DOM
77
+
#### Content
78
+
79
+
From now, the `content` property has no special behavior, so it does not render. As the content should not include styles or `<slot>` elements, it is sufficient to just rename the property to `render`:
80
+
81
+
```javascript
82
+
// before
83
+
{
84
+
content: () =>html`...`,
85
+
...
86
+
}
87
+
```
88
+
89
+
```javascript
90
+
// after
91
+
{
92
+
render: () =>html`...`,
93
+
...
94
+
}
95
+
```
96
+
97
+
If you need to pass styles to the element's content, you can disable Shadow DOM explicitly:
0 commit comments