saasufy-components 2.10.0 → 2.11.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 CHANGED
@@ -225,12 +225,17 @@ A component which can be used to guarantee that certain children components are
225
225
 
226
226
  ### if-group
227
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.
228
+ A component which exposes a `show-content` property which can be set to true or false to show or hide its content.
229
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
230
 
231
+ ### switch-group
232
+
233
+ A component which exposes a `show-cases` property which can be set to key-value pairs in the format `key1=true,key2=false`. It can be used to conditionally display multiple slotted elements based on multiple conditions. It helps to keep HTML clean when the conditions are complex.
234
+ This element is intended to be placed inside a `model-viewer`, `collection-browser` or `collection-reducer` component such that the true/false values of the `show-cases` attribute can be computed using template `{{expression}}` placeholders. This component requires one or more templates and a viewport to be slotted in. The content of the templates will not be processed unless the `show-cases` condition is met. All templates must have a `slot="content"` attribute and a name attribute in the format `name="key1"` where the value `key1` corresponds to the key specified inside the `show-cases` attribute of the `switch-group`.
235
+
231
236
  ### conditional-group
232
237
 
233
- A modal component which exposes a `show-content` property which can be set to true or false to show or hide its content.
238
+ A component which exposes a `show-content` property which can be set to true or false to show or hide its content.
234
239
  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.
235
240
 
236
241
  ### collection-adder-group
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasufy-components",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "description": "Components for Saasufy.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,71 @@
1
+ import { debouncer } from './utils.js';
2
+
3
+ const DEBOUNCE_DELAY = 0;
4
+
5
+ class SwitchGroup 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 showCases = this.getAttribute('show-cases');
20
+ if (!showCases) return;
21
+
22
+ let caseEntries = showCases.split(',').map((caseString) => {
23
+ let sanitizedCase = caseString.trim();
24
+ return sanitizedCase.split('=').map(part => part.trim());
25
+ });
26
+
27
+ let contentList = [];
28
+
29
+ for (let [ caseName, showContent ] of caseEntries) {
30
+ if (
31
+ !showContent ||
32
+ showContent === 'false' ||
33
+ showContent === 'null' ||
34
+ showContent === 'undefined'
35
+ ) continue;
36
+
37
+ let contentSlot = this.shadowRoot.querySelector('slot[name="content"]');
38
+
39
+ let contentElements = contentSlot.assignedElements().filter((element) => {
40
+ return element.getAttribute('name') === caseName;
41
+ });
42
+
43
+ for (let element of contentElements) {
44
+ contentList.push(element.innerHTML);
45
+ }
46
+ }
47
+
48
+ viewportNode.innerHTML = contentList.join('');
49
+ };
50
+
51
+ this.debouncedProcessTemplates = debounce(this.processTemplates, DEBOUNCE_DELAY);
52
+ this.shadowRoot.addEventListener('slotchange', this.debouncedProcessTemplates);
53
+ }
54
+
55
+ static get observedAttributes() {
56
+ return [
57
+ 'show-cases'
58
+ ];
59
+ }
60
+
61
+ attributeChangedCallback() {
62
+ if (!this.isReady) return;
63
+ this.processTemplates();
64
+ }
65
+
66
+ connectedCallback() {
67
+ this.isReady = true;
68
+ }
69
+ }
70
+
71
+ window.customElements.define('switch-group', SwitchGroup);