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: The `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
+49-72
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,21 +286,31 @@ define({
286
286
});
287
287
```
288
288
289
-
## `render` & `content`
289
+
## Rendering
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 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 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()`.
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 creates and updates the content of the custom element:
298
+
299
+
```javascript
300
+
define({
301
+
tag:"my-element",
302
+
name:"",
303
+
render: ({ name }) =>html`<h1>Hello ${name}!</h1>`,
304
+
});
305
+
```
296
306
297
307
### Shadow DOM
298
308
299
-
Use the `render` key for the internal structure of the custom element, where you can add isolated styles, slot elements, etc.
309
+
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
310
301
-
```javascript
302
-
import { define, html } from"hybrids";
311
+
The template with styles:
303
312
313
+
```javascript
304
314
define({
305
315
tag:"my-element",
306
316
name:"",
@@ -313,88 +323,55 @@ define({
313
323
});
314
324
```
315
325
316
-
The `render` property provides unique `options` key for passing additional arguments to `host.attachShadow()` method:
317
-
318
-
```ts
319
-
render: {
320
-
value: (host) => { ... },
321
-
options: {
322
-
mode:"open"|"closed",
323
-
delegatesFocus: boolean,
324
-
},
325
-
...
326
-
}
327
-
```
326
+
The template with `<slot>` element:
328
327
329
328
```javascript
330
-
import { define, html } from"hybrids";
331
-
332
329
define({
333
330
tag:"my-element",
334
-
render: {
335
-
value:html`<div>...</div>`,
336
-
options: { delegatesFocus:true },
337
-
},
331
+
render: () =>html`
332
+
<slot></slot>
333
+
`,
338
334
});
339
335
```
340
336
341
-
### Element's Content
337
+
Templates are compiled "just in time", 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 explicitly.
342
338
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.
339
+
### Explicit Mode
344
340
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.
341
+
Use the `shadow` option of the `render` property to set rendering mode to Shadow DOM or element's content:
346
342
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:
343
+
```ts
344
+
// Disable Shadow DOM
345
+
render: {
346
+
value: (host) =>html`...`,
347
+
shadow:false,
348
+
...
349
+
}
360
350
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
-
}
351
+
// Force Shadow DOM
352
+
render: {
353
+
value: (host) =>html`...`,
354
+
shadow:true,
375
355
}
376
356
```
377
357
378
-
```javascript
379
-
importreactifyfrom"./reactify.js";
358
+
You can use this option for passing custom values to the `host.attachShadow()` method:
380
359
381
-
functionMyComponent({ name }) {
382
-
return<div>{name}</div>;
383
-
}
360
+
```javascript
361
+
import { define, html } from"hybrids";
384
362
385
363
define({
386
364
tag:"my-element",
387
-
render:reactify(({ name }) =><MyComponent name={name} />),
388
-
})
365
+
render: {
366
+
value:html`<div>...</div>`,
367
+
shadow: { mode:"close", delegatesFocus:true },
368
+
},
369
+
});
389
370
```
390
371
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
372
### Reference Internals
396
373
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.
374
+
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 the 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