@blockquote-web-components/blockquote-mixin-slot-content
Version:
Webcomponent blockquote-mixin-slot-content following open-wc recommendations
252 lines (196 loc) • 5.95 kB
Markdown

`BlockquoteMixinSlotContent` is a mixin for managing the flattened set of nodes assigned to a slot when the node(s) contained in some slot change.
It implements the event handling pattern called [event delegation](https://javascript.info/event-delegation).
### Demo
[](https://stackblitz.com/github/oscarmarina/blockquote-web-components/tree/main/packages/mixins/blockquote-mixin-slot-content)
### Example:
```js
class SlotElement extends BlockquoteMixinSlotContent(LitElement) {
// ...
constructor() {
super();
this.addEventListener('slotchanges', this._onSlotChanges);
}
_onSlotChanges = (ev) => {
const { detail } = ev;
console.log(detail);
}
// ...
}
```
## Caveats with whitespace:
It's important to understand some of the nuances between text nodes that contain _`text`_ and text nodes that contain only [`whitespace`](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace#what_is_whitespace).
```html
<slot-element>
nodeText1
<p>Element 1</p>
<p>Element 2</p>
</slot-element>
```
#### assignedNodes returns 5 Nodes
```js
assignedNodes: Array(5)
0: text // textContent: "\n nodeText1\n "
1: p // textContent: "Element 1"
2: text // textContent: "\n "
3: p // textContent: "Element 2"
4: text // textContent: "\n "
length: 5
```
Also, another problem with whitespace is that when the content is just whitespace, assignedNodes are no longer able to return `flattened` nodes.
#### without `whitespace`
```html
<slot-element>
#shadow-root
<slot>
<img src="icon.svg" />
</slot>
</slot-element>
<slot-element>Hello</slot-element>
```
```js
document.querySelector('slot-element').textContent = '';
// assignedNodes [`img`]
```
<hr>
#### with `whitespace`
```html
<slot-element>
#shadow-root
<slot>
<img src="icon.svg" />
</slot>
</slot-element>
<slot-element>Hello</slot-element>
```
```js
document.querySelector('slot-element').textContent = ' ';
// assignedNodes [`#text`]
// * missing `flattened` node
```
<hr>
## The `detail property` - keeping that in mind.
The mixin will return only nodes [whose content is not whitespace](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace#whitespace_helper_functions)
and equally for flattened nodes.
```html
<slot-element>
#shadow-root
<slot>
<img src="icon.svg" />
</slot>
</slot-element>
<slot-element>
<p>sdfas</p>
<p>2jfie</p>
</slot-element>
```
#### `event.detail`
```json
{
"assignedSlotContent": {
"slotName": "",
"assignedSlot": slot
},
"assignedNodesContent": {
"assignedNodesByNode": [
{
"flatten": false,
"assignedNodes": p,
"assignedSlot": slot
},
{
"flatten": false,
"assignedNodes": p,
"assignedSlot": slot
}
],
"assignedNodes": [p, p]
},
"flattenedNodesContent": {
"assignedNodesByNode": [
{
"flatten": true,
"assignedNodes": img,
"assignedSlot": null
}
],
"assignedNodes": [img]
},
"originalEvent": {
"event": {
"isTrusted": true,
"type": "slotchange",
"target": null,
"currentTarget": null,
// ...
},
"assignedNodes": [text, p, text, p, text, text, text]
}
}
```
<hr>
```html
<slot-element>
#shadow-root
<slot></slot>
</slot-element>
<slot-element> </slot-element>
```
#### `event.detail`
```json
{
"assignedSlotContent": {
"slotName": "",
"assignedSlot": null
},
"assignedNodesContent": {
"assignedNodesByNode": [],
"assignedNodes": []
},
"flattenedNodesContent": {
"assignedNodesByNode": [],
"assignedNodes": []
},
"originalEvent": {
"event": {
"isTrusted": true,
"type": "slotchange",
"target": null,
"currentTarget": null,
// ...
},
"assignedNodes": [text]
}
}
```
### `src/BlockquoteMixinSlotContent.js`:
#### mixin: `BlockquoteMixinSlotContent`
##### Mixins
| Name | Module | Package |
| ------------- | ------ | --------------------- |
| `dedupeMixin` | | -wc/dedupe-mixin |
##### Parameters
| Name | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
| `Base` | | | |
<details><summary>Private API</summary>
##### Fields
| Name | Privacy | Type | Default | Description | Inherited From |
| --------------- | ------- | ---- | ------- | ----------- | -------------- |
| `#onSlotChange` | private | | | | |
##### Methods
| Name | Privacy | Description | Parameters | Return | Inherited From |
| ------------------------- | ------- | ----------- | --------------------------- | ------ | -------------- |
| `#processSlotContent` | private | | `slotNode: HTMLSlotElement` | | |
| `#createContentStructure` | private | | `content: *` | | |
</details>
<hr/>
#### Exports
| Kind | Name | Declaration | Module | Package |
| ---- | ---------------------------- | -------------------------- | --------------------------------- | ------- |
| `js` | `BlockquoteMixinSlotContent` | BlockquoteMixinSlotContent | src/BlockquoteMixinSlotContent.js | |
### `src/index.js`:
#### Exports
| Kind | Name | Declaration | Module | Package |
| ---- | ---------------------------- | -------------------------- | ------------------------------- | ------- |
| `js` | `BlockquoteMixinSlotContent` | BlockquoteMixinSlotContent | ./BlockquoteMixinSlotContent.js | |