saasufy-components 2.7.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 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
 
@@ -40,7 +40,10 @@ class CollectionAdder extends SocketConsumer {
40
40
  'model-values',
41
41
  'submit-button-label',
42
42
  'hide-submit-button',
43
- 'success-message'
43
+ 'success-message',
44
+ 'autocapitalize',
45
+ 'autocorrect',
46
+ 'trim-spaces'
44
47
  ];
45
48
  }
46
49
 
@@ -106,6 +109,8 @@ class CollectionAdder extends SocketConsumer {
106
109
  }
107
110
  }
108
111
 
112
+ let trimSpaces = this.hasAttribute('trim-spaces');
113
+
109
114
  let newModelData = {
110
115
  ...this.modelFieldValues,
111
116
  ...radioData,
@@ -121,7 +126,11 @@ class CollectionAdder extends SocketConsumer {
121
126
  } else {
122
127
  value = input.value;
123
128
  }
124
- return [ input.name, Type(value) ];
129
+ let sanitizedValue = Type(value);
130
+ if (trimSpaces && typeof sanitizedValue === 'string') {
131
+ sanitizedValue = sanitizedValue.trim();
132
+ }
133
+ return [ input.name, sanitizedValue ];
125
134
  })
126
135
  )
127
136
  };
@@ -188,6 +197,15 @@ class CollectionAdder extends SocketConsumer {
188
197
  fieldValues: optionLabels
189
198
  } = this.getFieldDetails(this.getAttribute('option-labels'));
190
199
 
200
+ let autocapitalize = this.getAttribute('autocapitalize');
201
+ let autocorrect = this.getAttribute('autocorrect');
202
+
203
+ let extraAttributesString = `${
204
+ autocapitalize ? ` autocapitalize="${autocapitalize}"` : ''
205
+ }${
206
+ autocorrect ? ` autocorrect="${autocorrect}"` : ''
207
+ }`;
208
+
191
209
  this.modelFieldValues = modelFieldValues;
192
210
 
193
211
  if (this.collection) this.collection.destroy();
@@ -242,7 +260,7 @@ class CollectionAdder extends SocketConsumer {
242
260
  field
243
261
  }" placeholder="${
244
262
  inputLabel
245
- }" />
263
+ }"${extraAttributesString} />
246
264
  <select class="collection-adder-select">
247
265
  <option value="" selected disabled hidden>${optionLabel}</option>
248
266
  ${inputTypeParams.map(param => `<option value="${param}">${param}</option>`).join('')}
@@ -278,7 +296,7 @@ class CollectionAdder extends SocketConsumer {
278
296
  field
279
297
  }" placeholder="${
280
298
  inputLabel
281
- }"></textarea>`
299
+ }"${extraAttributesString}></textarea>`
282
300
  );
283
301
  } else {
284
302
  items.push(
@@ -288,7 +306,7 @@ class CollectionAdder extends SocketConsumer {
288
306
  field
289
307
  }" placeholder="${
290
308
  inputLabel
291
- }" />`
309
+ }"${extraAttributesString} />`
292
310
  );
293
311
  }
294
312
  }
@@ -23,7 +23,16 @@ class ConditionalGroup extends HTMLElement {
23
23
 
24
24
  render() {
25
25
  let showContent = this.getAttribute('show-content');
26
- this.shadowRoot.innerHTML = showContent != null && showContent !== 'false' ? '<slot></slot>' : '';
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/input-provider.js CHANGED
@@ -28,7 +28,9 @@ class InputProvider extends HTMLElement {
28
28
  'debounce-delay',
29
29
  'options',
30
30
  'value',
31
- 'height'
31
+ 'height',
32
+ 'autocapitalize',
33
+ 'autocorrect'
32
34
  ];
33
35
  }
34
36
 
@@ -59,6 +61,8 @@ class InputProvider extends HTMLElement {
59
61
  render() {
60
62
  this.innerHTML = '';
61
63
  let inputId = this.getAttribute('input-id');
64
+ let autocapitalize = this.getAttribute('autocapitalize');
65
+ let autocorrect = this.getAttribute('autocorrect');
62
66
  let inputList = this.getAttribute('list');
63
67
  let type = this.getAttribute('type') || 'text';
64
68
  let placeholder = this.getAttribute('placeholder');
@@ -97,6 +101,12 @@ class InputProvider extends HTMLElement {
97
101
  if (inputId) {
98
102
  this.inputElement.setAttribute('id', inputId);
99
103
  }
104
+ if (autocapitalize) {
105
+ this.inputElement.setAttribute('autocapitalize', autocapitalize);
106
+ }
107
+ if (autocorrect) {
108
+ this.inputElement.setAttribute('autocorrect', autocorrect);
109
+ }
100
110
  if (placeholder) {
101
111
  this.inputElement.setAttribute('placeholder', placeholder);
102
112
  }
package/model-input.js CHANGED
@@ -36,7 +36,9 @@ class ModelInput extends SocketConsumer {
36
36
  'enable-rebound',
37
37
  'options',
38
38
  'height',
39
- 'hide-error-logs'
39
+ 'hide-error-logs',
40
+ 'autocapitalize',
41
+ 'autocorrect'
40
42
  ];
41
43
  }
42
44
 
@@ -71,6 +73,8 @@ class ModelInput extends SocketConsumer {
71
73
  let modelInstanceProperty = this.getAttribute('model-instance-property');
72
74
  let showErrorMessage = this.hasAttribute('show-error-message');
73
75
  let inputId = this.getAttribute('input-id');
76
+ let autocapitalize = this.getAttribute('autocapitalize');
77
+ let autocorrect = this.getAttribute('autocorrect');
74
78
  let inputList = this.getAttribute('list');
75
79
  let type = this.getAttribute('type') || 'text';
76
80
  let placeholder = this.getAttribute('placeholder');
@@ -188,6 +192,12 @@ class ModelInput extends SocketConsumer {
188
192
  if (inputId) {
189
193
  this.inputElement.setAttribute('id', inputId);
190
194
  }
195
+ if (autocapitalize) {
196
+ this.inputElement.setAttribute('autocapitalize', autocapitalize);
197
+ }
198
+ if (autocorrect) {
199
+ this.inputElement.setAttribute('autocorrect', autocorrect);
200
+ }
191
201
  if (placeholder) {
192
202
  this.inputElement.setAttribute('placeholder', placeholder);
193
203
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasufy-components",
3
- "version": "2.7.0",
3
+ "version": "2.9.0",
4
4
  "description": "Components for Saasufy.",
5
5
  "main": "index.js",
6
6
  "scripts": {
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(/&amp;/g, '&')
23
+ .replace(/&lt;/g, '<')
24
+ .replace(/&gt;/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
  );