@unicef-polymer/etools-form-builder 4.0.1 → 4.0.3

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.
Files changed (40) hide show
  1. package/LICENSE +674 -674
  2. package/README.md +1 -1
  3. package/dist/form-attachments-popup/form-attachments-popup.js +135 -135
  4. package/dist/form-fields/abstract-field-base.class.js +100 -100
  5. package/dist/form-fields/field-renderer-component.d.ts +4 -3
  6. package/dist/form-fields/field-renderer-component.js +209 -195
  7. package/dist/form-fields/repeatable-fields/repeatable-attachment-field.js +111 -111
  8. package/dist/form-fields/repeatable-fields/repeatable-base-field.js +22 -22
  9. package/dist/form-fields/repeatable-fields/repeatable-choice-field.d.ts +1 -0
  10. package/dist/form-fields/repeatable-fields/repeatable-choice-field.js +66 -63
  11. package/dist/form-fields/repeatable-fields/repeatable-number-field.js +19 -19
  12. package/dist/form-fields/repeatable-fields/repeatable-scale-field.js +57 -57
  13. package/dist/form-fields/repeatable-fields/repeatable-text-field.js +19 -19
  14. package/dist/form-fields/single-fields/attachment-field.js +13 -13
  15. package/dist/form-fields/single-fields/boolean-field.js +16 -16
  16. package/dist/form-fields/single-fields/choice-field.d.ts +2 -0
  17. package/dist/form-fields/single-fields/choice-field.js +68 -65
  18. package/dist/form-fields/single-fields/number-field.js +20 -20
  19. package/dist/form-fields/single-fields/scale-field.d.ts +1 -0
  20. package/dist/form-fields/single-fields/scale-field.js +58 -58
  21. package/dist/form-fields/single-fields/text-field.js +30 -30
  22. package/dist/form-groups/form-abstract-group.js +129 -129
  23. package/dist/form-groups/form-card.js +30 -30
  24. package/dist/form-groups/form-collapsed-card.js +34 -34
  25. package/dist/lib/additional-components/confirmation-dialog.js +20 -20
  26. package/dist/lib/additional-components/etools-fb-card.js +144 -144
  27. package/dist/lib/styles/attachments.styles.js +61 -61
  28. package/dist/lib/styles/card-styles.js +147 -147
  29. package/dist/lib/styles/dialog.styles.js +83 -83
  30. package/dist/lib/styles/elevation-styles.js +46 -46
  31. package/dist/lib/styles/flex-layout-classes.js +316 -316
  32. package/dist/lib/styles/form-builder-card.styles.js +53 -53
  33. package/dist/lib/styles/page-layout-styles.js +198 -198
  34. package/dist/lib/styles/shared-styles.js +61 -61
  35. package/dist/lib/types/form-builder.types.d.ts +1 -0
  36. package/dist/rich-editor/rich-action.js +34 -34
  37. package/dist/rich-editor/rich-text.js +64 -64
  38. package/dist/rich-editor/rich-toolbar.js +125 -125
  39. package/dist/rich-editor/rich-viewer.js +21 -21
  40. package/package.json +53 -53
@@ -6,19 +6,19 @@ import { RepeatableBaseField } from './repeatable-base-field';
6
6
  import { AbstractFieldBaseClass } from '../abstract-field-base.class';
7
7
  let RepeatableTextField = class RepeatableTextField extends RepeatableBaseField {
8
8
  controlTemplate(value, index) {
9
- return html `
10
- <etools-textarea
11
- id="textarea"
12
- class="no-padding-left"
13
- no-label-float
14
- placeholder="${this.isReadonly ? '—' : this.placeholder}"
15
- .value="${value}"
16
- @value-changed="${({ detail }) => this.valueChanged(detail.value, index)}"
17
- ?readonly="${this.isReadonly}"
18
- ?invalid="${this.errorMessage[index]}"
19
- error-message="${this.errorMessage[index]}"
20
- >
21
- </etools-textarea>
9
+ return html `
10
+ <etools-textarea
11
+ id="textarea"
12
+ class="no-padding-left"
13
+ no-label-float
14
+ placeholder="${this.isReadonly ? '—' : this.placeholder}"
15
+ .value="${value}"
16
+ @value-changed="${({ detail }) => this.valueChanged(detail.value, index)}"
17
+ ?readonly="${this.isReadonly}"
18
+ ?invalid="${this.errorMessage[index]}"
19
+ error-message="${this.errorMessage[index]}"
20
+ >
21
+ </etools-textarea>
22
22
  `;
23
23
  }
24
24
  customValidation() {
@@ -28,12 +28,12 @@ let RepeatableTextField = class RepeatableTextField extends RepeatableBaseField
28
28
  // language=CSS
29
29
  return [
30
30
  ...AbstractFieldBaseClass.styles,
31
- css `
32
- @media (max-width: 380px) {
33
- .no-padding-left {
34
- padding-left: 0;
35
- }
36
- }
31
+ css `
32
+ @media (max-width: 380px) {
33
+ .no-padding-left {
34
+ padding-left: 0;
35
+ }
36
+ }
37
37
  `
38
38
  ];
39
39
  }
@@ -20,19 +20,19 @@ let AttachmentField = class AttachmentField extends BaseField {
20
20
  return AttachmentsHelper.jwtLocalStorageKey;
21
21
  }
22
22
  controlTemplate() {
23
- return html `
24
- <!-- Upload button -->
25
- <etools-upload
26
- class="with-padding"
27
- activate-offline
28
- .uploadedFileInfo="${this.value}"
29
- ?readonly="${this.isReadonly}"
30
- @upload-finished="${({ detail }) => this.attachmentsUploaded(detail)}"
31
- @delete-file="${() => this.valueChanged(null)}"
32
- .endpointInfo="${{ endpoint: this.uploadUrl, extraInfo: { composedPath: this.computedPath } }}"
33
- .jwtLocalStorageKey="${this.jwtLocalStorageKey}"
34
- >
35
- </etools-upload>
23
+ return html `
24
+ <!-- Upload button -->
25
+ <etools-upload
26
+ class="with-padding"
27
+ activate-offline
28
+ .uploadedFileInfo="${this.value}"
29
+ ?readonly="${this.isReadonly}"
30
+ @upload-finished="${({ detail }) => this.attachmentsUploaded(detail)}"
31
+ @delete-file="${() => this.valueChanged(null)}"
32
+ .endpointInfo="${{ endpoint: this.uploadUrl, extraInfo: { composedPath: this.computedPath } }}"
33
+ .jwtLocalStorageKey="${this.jwtLocalStorageKey}"
34
+ >
35
+ </etools-upload>
36
36
  `;
37
37
  }
38
38
  customValidation() {
@@ -5,16 +5,16 @@ import { BaseField } from './base-field';
5
5
  import '@shoelace-style/shoelace/dist/components/switch/switch.js';
6
6
  let BooleanField = class BooleanField extends BaseField {
7
7
  controlTemplate() {
8
- return html `
9
- <sl-switch
10
- class="no-padding-left"
11
- ?checked="${this.value}"
12
- @sl-change="${(e) => this.valueChanged(e.target.checked)}"
13
- ?disabled="${this.isReadonly}"
14
- >
15
- </sl-switch>
16
-
17
- <div ?hidden="${!this.errorMessage}" class="error-text">${this.errorMessage}</div>
8
+ return html `
9
+ <sl-switch
10
+ class="no-padding-left"
11
+ ?checked="${this.value}"
12
+ @sl-change="${(e) => this.valueChanged(e.target.checked)}"
13
+ ?disabled="${this.isReadonly}"
14
+ >
15
+ </sl-switch>
16
+
17
+ <div ?hidden="${!this.errorMessage}" class="error-text">${this.errorMessage}</div>
18
18
  `;
19
19
  }
20
20
  customValidation() {
@@ -24,12 +24,12 @@ let BooleanField = class BooleanField extends BaseField {
24
24
  // language=CSS
25
25
  return [
26
26
  ...BaseField.styles,
27
- css `
28
- @media (max-width: 380px) {
29
- .no-padding-left {
30
- padding-left: 0;
31
- }
32
- }
27
+ css `
28
+ @media (max-width: 380px) {
29
+ .no-padding-left {
30
+ padding-left: 0;
31
+ }
32
+ }
33
33
  `
34
34
  ];
35
35
  }
@@ -5,12 +5,14 @@ import '@unicef-polymer/etools-unicef/src/etools-checkbox/etools-checkbox';
5
5
  export type ChoiceFieldOption = {
6
6
  value: any;
7
7
  label: string;
8
+ disabled?: boolean;
8
9
  };
9
10
  export declare class ChoiceField extends BaseField<(string | number)[] | null> {
10
11
  options: (ChoiceFieldOption | string | number)[];
11
12
  protected controlTemplate(): TemplateResult;
12
13
  protected getLabel(option: ChoiceFieldOption | string | number): unknown;
13
14
  protected getValue(option: ChoiceFieldOption | string | number): unknown;
15
+ protected getDisabled(option: ChoiceFieldOption | string | number): unknown;
14
16
  protected onToggle(itemValue: string | number, checked: boolean): void;
15
17
  protected customValidation(): string | null;
16
18
  static get styles(): CSSResultArray;
@@ -12,38 +12,38 @@ let ChoiceField = class ChoiceField extends BaseField {
12
12
  this.options = [];
13
13
  }
14
14
  controlTemplate() {
15
- return html `
16
- <div class="container">
17
- <div class="checkbox-group">
15
+ return html `
16
+ <div class="container">
17
+ <div class="checkbox-group">
18
18
  ${repeat(this.options, (option) => {
19
19
  const val = this.getValue(option);
20
20
  const checked = Array.isArray(this.value) && this.value.includes(val);
21
- return html `
22
- <etools-checkbox
23
- class="checkbox"
24
- value="${val}"
25
- ?checked="${checked}"
26
- ?disabled="${this.isReadonly}"
27
- @sl-change="${(e) => this.onToggle(val, e.target.checked)}"
28
- >
29
- ${this.getLabel(option)}
30
- </etools-checkbox>
21
+ return html `
22
+ <etools-checkbox
23
+ class="checkbox"
24
+ value="${val}"
25
+ ?checked="${checked}"
26
+ ?disabled="${this.isReadonly || this.getDisabled(option)}"
27
+ @sl-change="${(e) => this.onToggle(val, e.target.checked)}"
28
+ >
29
+ ${this.getLabel(option)}
30
+ </etools-checkbox>
31
31
  `;
32
- })}
33
- </div>
34
-
35
- <etools-button
36
- class="neutral clear-button"
37
- variant="text"
38
- ?hidden="${this.isReadonly}"
39
- @click="${() => this.valueChanged([])}"
40
- >
41
- <etools-icon name="clear" slot="prefix"></etools-icon>
42
- ${getTranslation(this.language, 'CLEAR')}
43
- </etools-button>
44
- </div>
45
-
46
- <div ?hidden="${!this.errorMessage}" class="error-text">${this.errorMessage}</div>
32
+ })}
33
+ </div>
34
+
35
+ <etools-button
36
+ class="neutral clear-button"
37
+ variant="text"
38
+ ?hidden="${this.isReadonly}"
39
+ @click="${() => this.valueChanged([])}"
40
+ >
41
+ <etools-icon name="clear" slot="prefix"></etools-icon>
42
+ ${getTranslation(this.language, 'CLEAR')}
43
+ </etools-button>
44
+ </div>
45
+
46
+ <div ?hidden="${!this.errorMessage}" class="error-text">${this.errorMessage}</div>
47
47
  `;
48
48
  }
49
49
  getLabel(option) {
@@ -52,6 +52,9 @@ let ChoiceField = class ChoiceField extends BaseField {
52
52
  getValue(option) {
53
53
  return typeof option === 'object' ? option.value : option;
54
54
  }
55
+ getDisabled(option) {
56
+ return typeof option === 'object' ? option.disabled : false;
57
+ }
55
58
  onToggle(itemValue, checked) {
56
59
  this.touched = true;
57
60
  let newValue = Array.isArray(this.value) ? [...this.value] : [];
@@ -71,43 +74,43 @@ let ChoiceField = class ChoiceField extends BaseField {
71
74
  static get styles() {
72
75
  return [
73
76
  ...BaseField.styles,
74
- css `
75
- .container {
76
- position: relative;
77
- min-height: 48px;
78
- display: flex;
79
- align-items: center;
80
- flex-direction: row;
81
- }
82
-
83
- .checkbox-group {
84
- display: flex;
85
- flex-direction: row;
86
- flex-wrap: wrap;
87
- gap: 0.5rem;
88
- }
89
-
90
- :host([is-readonly]) .checkbox-group {
91
- pointer-events: none;
92
- opacity: 0.55;
93
- }
94
-
95
- @media (max-width: 1080px) {
96
- .container {
97
- flex-direction: column;
98
- align-items: flex-start;
99
- }
100
- .checkbox-group {
101
- flex-direction: column;
102
- }
103
- .checkbox {
104
- padding-left: 3px;
105
- }
106
- .clear-button {
107
- margin: 0;
108
- padding-left: 0;
109
- }
110
- }
77
+ css `
78
+ .container {
79
+ position: relative;
80
+ min-height: 48px;
81
+ display: flex;
82
+ align-items: center;
83
+ flex-direction: row;
84
+ }
85
+
86
+ .checkbox-group {
87
+ display: flex;
88
+ flex-direction: row;
89
+ flex-wrap: wrap;
90
+ gap: 0.5rem;
91
+ }
92
+
93
+ :host([is-readonly]) .checkbox-group {
94
+ pointer-events: none;
95
+ opacity: 0.55;
96
+ }
97
+
98
+ @media (max-width: 1080px) {
99
+ .container {
100
+ flex-direction: column;
101
+ align-items: flex-start;
102
+ }
103
+ .checkbox-group {
104
+ flex-direction: column;
105
+ }
106
+ .checkbox {
107
+ padding-left: 3px;
108
+ }
109
+ .clear-button {
110
+ margin: 0;
111
+ padding-left: 0;
112
+ }
113
+ }
111
114
  `
112
115
  ];
113
116
  }
@@ -10,20 +10,20 @@ let NumberField = class NumberField extends BaseField {
10
10
  this.isInteger = false;
11
11
  }
12
12
  controlTemplate() {
13
- return html `
14
- <etools-input
15
- class="no-padding-left"
16
- no-label-float
17
- placeholder="${this.isReadonly ? '—' : this.placeholder}"
18
- .value="${this.value}"
19
- @value-changed="${({ detail }) => this.valueChanged(detail.value)}"
20
- @focus="${() => (this.touched = true)}"
21
- placeholder="&#8212;"
22
- ?invalid="${this.errorMessage}"
23
- error-message="${this.errorMessage}"
24
- ?readonly="${this.isReadonly}"
25
- >
26
- </etools-input>
13
+ return html `
14
+ <etools-input
15
+ class="no-padding-left"
16
+ no-label-float
17
+ placeholder="${this.isReadonly ? '—' : this.placeholder}"
18
+ .value="${this.value}"
19
+ @value-changed="${({ detail }) => this.valueChanged(detail.value)}"
20
+ @focus="${() => (this.touched = true)}"
21
+ placeholder="&#8212;"
22
+ ?invalid="${this.errorMessage}"
23
+ error-message="${this.errorMessage}"
24
+ ?readonly="${this.isReadonly}"
25
+ >
26
+ </etools-input>
27
27
  `;
28
28
  }
29
29
  valueChanged(newValue) {
@@ -45,12 +45,12 @@ let NumberField = class NumberField extends BaseField {
45
45
  // language=CSS
46
46
  return [
47
47
  ...BaseField.styles,
48
- css `
49
- @media (max-width: 380px) {
50
- .no-padding-left {
51
- padding-left: 0;
52
- }
53
- }
48
+ css `
49
+ @media (max-width: 380px) {
50
+ .no-padding-left {
51
+ padding-left: 0;
52
+ }
53
+ }
54
54
  `
55
55
  ];
56
56
  }
@@ -6,6 +6,7 @@ import '@unicef-polymer/etools-unicef/src/etools-button/etools-button';
6
6
  export type FieldOption = {
7
7
  value: any;
8
8
  label: string;
9
+ disabled?: boolean;
9
10
  };
10
11
  export declare class ScaleField extends BaseField<string | number | null> {
11
12
  options: (FieldOption | string | number)[];
@@ -13,28 +13,28 @@ let ScaleField = class ScaleField extends BaseField {
13
13
  this.options = [];
14
14
  }
15
15
  controlTemplate() {
16
- return html `
17
- <div class="container">
18
- <etools-radio-group
19
- class="radio-group"
20
- .value="${this.value}"
21
- @sl-change="${(e) => this.onSelect(e.target.value)}"
22
- >
23
- ${repeat(this.options, (option) => html `
24
- <sl-radio class="radio-button" value="${this.getValue(option)}">${this.getLabel(option)}</sl-radio>
25
- `)}
26
- </etools-radio-group>
27
- <etools-button
28
- class="neutral clear-button"
29
- variant="text"
30
- ?hidden="${this.isReadonly}"
31
- @click="${() => this.valueChanged(null)}"
32
- >
33
- <etools-icon name="clear" slot="prefix"></etools-icon>
34
- ${getTranslation(this.language, 'CLEAR')}
35
- </etools-button>
36
- </div>
37
- <div ?hidden="${!this.errorMessage}" class="error-text">${this.errorMessage}</div>
16
+ return html `
17
+ <div class="container">
18
+ <etools-radio-group
19
+ class="radio-group"
20
+ .value="${this.value}"
21
+ @sl-change="${(e) => this.onSelect(e.target.value)}"
22
+ >
23
+ ${repeat(this.options, (option) => html `
24
+ <sl-radio class="radio-button" value="${this.getValue(option)}">${this.getLabel(option)}</sl-radio>
25
+ `)}
26
+ </etools-radio-group>
27
+ <etools-button
28
+ class="neutral clear-button"
29
+ variant="text"
30
+ ?hidden="${this.isReadonly}"
31
+ @click="${() => this.valueChanged(null)}"
32
+ >
33
+ <etools-icon name="clear" slot="prefix"></etools-icon>
34
+ ${getTranslation(this.language, 'CLEAR')}
35
+ </etools-button>
36
+ </div>
37
+ <div ?hidden="${!this.errorMessage}" class="error-text">${this.errorMessage}</div>
38
38
  `;
39
39
  }
40
40
  getLabel(option) {
@@ -56,42 +56,42 @@ let ScaleField = class ScaleField extends BaseField {
56
56
  // language=CSS
57
57
  return [
58
58
  ...BaseField.styles,
59
- css `
60
- .container {
61
- position: relative;
62
- min-height: 48px;
63
- display: flex;
64
- align-items: center;
65
- flex-direction: row;
66
- }
67
-
68
- .radio-group {
69
- display: flex;
70
- flex-direction: row;
71
- flex-wrap: wrap;
72
- }
73
-
74
- :host([is-readonly]) etools-radio-group {
75
- pointer-events: none;
76
- opacity: 0.55;
77
- }
78
-
79
- @media (max-width: 1080px) {
80
- .container {
81
- flex-direction: column;
82
- align-items: flex-start;
83
- }
84
- .radio-group {
85
- flex-direction: column;
86
- }
87
- .radio-button {
88
- padding-left: 3px;
89
- }
90
- .clear-button {
91
- margin: 0;
92
- padding-left: 0;
93
- }
94
- }
59
+ css `
60
+ .container {
61
+ position: relative;
62
+ min-height: 48px;
63
+ display: flex;
64
+ align-items: center;
65
+ flex-direction: row;
66
+ }
67
+
68
+ .radio-group {
69
+ display: flex;
70
+ flex-direction: row;
71
+ flex-wrap: wrap;
72
+ }
73
+
74
+ :host([is-readonly]) etools-radio-group {
75
+ pointer-events: none;
76
+ opacity: 0.55;
77
+ }
78
+
79
+ @media (max-width: 1080px) {
80
+ .container {
81
+ flex-direction: column;
82
+ align-items: flex-start;
83
+ }
84
+ .radio-group {
85
+ flex-direction: column;
86
+ }
87
+ .radio-button {
88
+ padding-left: 3px;
89
+ }
90
+ .clear-button {
91
+ margin: 0;
92
+ padding-left: 0;
93
+ }
94
+ }
95
95
  `
96
96
  ];
97
97
  }
@@ -11,32 +11,32 @@ let TextField = class TextField extends BaseField {
11
11
  }
12
12
  controlTemplate() {
13
13
  return this.showRichEditor
14
- ? html `<div class="finding-container no-padding-left">
15
- <rich-text
16
- .value="${this.originalValue}"
17
- ?readonly="${this.isReadonly}"
14
+ ? html `<div class="finding-container no-padding-left">
15
+ <rich-text
16
+ .value="${this.originalValue}"
17
+ ?readonly="${this.isReadonly}"
18
18
  @editor-changed="${({ detail }) => {
19
19
  if (detail.value !== this.value) {
20
20
  this.valueChanged(detail.value);
21
21
  }
22
- }}"
23
- ></rich-text>
22
+ }}"
23
+ ></rich-text>
24
24
  </div>`
25
- : html `
26
- <etools-textarea
27
- id="otherInfo"
28
- class="no-padding-left"
29
- no-label-float
30
- placeholder="${this.isReadonly ? '—' : this.placeholder}"
31
- .value="${this.value}"
32
- @value-changed="${({ detail }) => this.valueChanged(detail.value)}"
33
- @focus="${() => (this.touched = true)}"
34
- ?readonly="${this.isReadonly}"
35
- ?invalid="${this.errorMessage}"
36
- name="${this.name}"
37
- error-message="${this.errorMessage}"
38
- >
39
- </etools-textarea>
25
+ : html `
26
+ <etools-textarea
27
+ id="otherInfo"
28
+ class="no-padding-left"
29
+ no-label-float
30
+ placeholder="${this.isReadonly ? '—' : this.placeholder}"
31
+ .value="${this.value}"
32
+ @value-changed="${({ detail }) => this.valueChanged(detail.value)}"
33
+ @focus="${() => (this.touched = true)}"
34
+ ?readonly="${this.isReadonly}"
35
+ ?invalid="${this.errorMessage}"
36
+ name="${this.name}"
37
+ error-message="${this.errorMessage}"
38
+ >
39
+ </etools-textarea>
40
40
  `;
41
41
  }
42
42
  connectedCallback() {
@@ -68,15 +68,15 @@ let TextField = class TextField extends BaseField {
68
68
  // language=CSS
69
69
  return [
70
70
  ...BaseField.styles,
71
- css `
72
- :host(.wide) etools-textarea {
73
- padding-left: 0;
74
- }
75
- @media (max-width: 380px) {
76
- .no-padding-left {
77
- padding-left: 0;
78
- }
79
- }
71
+ css `
72
+ :host(.wide) etools-textarea {
73
+ padding-left: 0;
74
+ }
75
+ @media (max-width: 380px) {
76
+ .no-padding-left {
77
+ padding-left: 0;
78
+ }
79
+ }
80
80
  `
81
81
  ];
82
82
  }