saasufy-components 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/conditional-group.js +10 -1
- package/if-group.js +58 -0
- package/package.json +1 -1
- package/utils.js +7 -1
package/README.md
CHANGED
|
@@ -223,10 +223,15 @@ A general purpose modal component.
|
|
|
223
223
|
|
|
224
224
|
A component which can be used to guarantee that certain children components are always rendered at the same time (once they are loaded) to provide a smooth user experience.
|
|
225
225
|
|
|
226
|
+
### if-group
|
|
227
|
+
|
|
228
|
+
A modal component which exposes a `show-content` property which can be set to true or false to show or hide its content.
|
|
229
|
+
It's intended to be placed inside a `model-viewer`, `collection-browser` or `collection-reducer` component such that the true/false value of the `show-content` attribute can be computed using a template `{{expression}}` placeholder. Unlike `conditional-group`, this component requires a template and a viewport to be slotted in. The content of the template will not be processed unless the `show-content` condition is met.
|
|
230
|
+
|
|
226
231
|
### conditional-group
|
|
227
232
|
|
|
228
233
|
A modal component which exposes a `show-content` property which can be set to true or false to show or hide its content.
|
|
229
|
-
It's intended to be placed inside a `model-viewer`, `collection-browser` or `collection-reducer` component such that the true/false value of the `show-content` attribute can be computed using a template `{{expression}}` placeholder.
|
|
234
|
+
It's intended to be placed inside a `model-viewer`, `collection-browser` or `collection-reducer` component such that the true/false value of the `show-content` attribute can be computed using a template `{{expression}}` placeholder. Unlike `if-group`, this component does not require a template, however, the trade-off is that the slotted content will be pre-processed by the browser even when the expression is false. This may not be suitable if you want to (for example) render child images conditionally because the browser will preload images based on their `src` attributes, even if they are not shown.
|
|
230
235
|
|
|
231
236
|
### collection-adder-group
|
|
232
237
|
|
package/conditional-group.js
CHANGED
|
@@ -23,7 +23,16 @@ class ConditionalGroup extends HTMLElement {
|
|
|
23
23
|
|
|
24
24
|
render() {
|
|
25
25
|
let showContent = this.getAttribute('show-content');
|
|
26
|
-
|
|
26
|
+
if (
|
|
27
|
+
!showContent ||
|
|
28
|
+
showContent === 'false' ||
|
|
29
|
+
showContent === 'null' ||
|
|
30
|
+
showContent === 'undefined'
|
|
31
|
+
) {
|
|
32
|
+
this.shadowRoot.innerHTML = '';
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.shadowRoot.innerHTML = '<slot></slot>';
|
|
27
36
|
}
|
|
28
37
|
}
|
|
29
38
|
|
package/if-group.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { debouncer } from './utils.js';
|
|
2
|
+
|
|
3
|
+
const DEBOUNCE_DELAY = 0;
|
|
4
|
+
|
|
5
|
+
class IfGroup extends HTMLElement {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this.isReady = false;
|
|
9
|
+
this.attachShadow({ mode: 'open' });
|
|
10
|
+
this.shadowRoot.innerHTML = '<slot name="content"></slot><slot name="viewport"></slot>';
|
|
11
|
+
|
|
12
|
+
let debounce = debouncer();
|
|
13
|
+
|
|
14
|
+
this.processTemplates = () => {
|
|
15
|
+
let viewportSlot = this.shadowRoot.querySelector('slot[name="viewport"]');
|
|
16
|
+
let viewportNode = viewportSlot.assignedNodes()[0];
|
|
17
|
+
if (!viewportNode) return;
|
|
18
|
+
|
|
19
|
+
let showContent = this.getAttribute('show-content');
|
|
20
|
+
if (
|
|
21
|
+
!showContent ||
|
|
22
|
+
showContent === 'false' ||
|
|
23
|
+
showContent === 'null' ||
|
|
24
|
+
showContent === 'undefined'
|
|
25
|
+
) return;
|
|
26
|
+
|
|
27
|
+
let contentSlot = this.shadowRoot.querySelector('slot[name="content"]');
|
|
28
|
+
let contentNodes = contentSlot.assignedNodes();
|
|
29
|
+
if (!contentNodes.length) return;
|
|
30
|
+
|
|
31
|
+
let contentList = [];
|
|
32
|
+
for (let node of contentNodes) {
|
|
33
|
+
contentList.push(node.innerHTML);
|
|
34
|
+
}
|
|
35
|
+
viewportNode.innerHTML = contentList.join('');
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
this.debouncedProcessTemplates = debounce(this.processTemplates, DEBOUNCE_DELAY);
|
|
39
|
+
this.shadowRoot.addEventListener('slotchange', this.debouncedProcessTemplates);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static get observedAttributes() {
|
|
43
|
+
return [
|
|
44
|
+
'show-content'
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
attributeChangedCallback() {
|
|
49
|
+
if (!this.isReady) return;
|
|
50
|
+
this.processTemplates();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
connectedCallback() {
|
|
54
|
+
this.isReady = true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
window.customElements.define('if-group', IfGroup);
|
package/package.json
CHANGED
package/utils.js
CHANGED
|
@@ -18,6 +18,12 @@ export function toSafeHTML(text) {
|
|
|
18
18
|
return text;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export function toExpression(html) {
|
|
22
|
+
return html.replace(/&/g, '&')
|
|
23
|
+
.replace(/</g, '<')
|
|
24
|
+
.replace(/>/g, '>');
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
export function debouncer() {
|
|
22
28
|
let debounceTimeout = null;
|
|
23
29
|
return function (callback, duration) {
|
|
@@ -213,7 +219,7 @@ export function renderTemplate(templateString, data, socket) {
|
|
|
213
219
|
try {
|
|
214
220
|
return toSafeHTML(
|
|
215
221
|
execExpression(
|
|
216
|
-
expString,
|
|
222
|
+
toExpression(expString),
|
|
217
223
|
options
|
|
218
224
|
)
|
|
219
225
|
);
|