@nyaruka/temba-components 0.129.9 → 0.129.10

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 (118) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/demo/test-colorpicker.html +30 -0
  3. package/dist/temba-components.js +867 -915
  4. package/dist/temba-components.js.map +1 -1
  5. package/out-tsc/src/events.js.map +1 -1
  6. package/out-tsc/src/form/ArrayEditor.js +45 -56
  7. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  8. package/out-tsc/src/form/BaseListEditor.js +4 -3
  9. package/out-tsc/src/form/BaseListEditor.js.map +1 -1
  10. package/out-tsc/src/form/Checkbox.js +77 -24
  11. package/out-tsc/src/form/Checkbox.js.map +1 -1
  12. package/out-tsc/src/form/ColorPicker.js +28 -40
  13. package/out-tsc/src/form/ColorPicker.js.map +1 -1
  14. package/out-tsc/src/form/Completion.js +44 -53
  15. package/out-tsc/src/form/Completion.js.map +1 -1
  16. package/out-tsc/src/form/Compose.js +7 -8
  17. package/out-tsc/src/form/Compose.js.map +1 -1
  18. package/out-tsc/src/form/ContactSearch.js +3 -4
  19. package/out-tsc/src/form/ContactSearch.js.map +1 -1
  20. package/out-tsc/src/form/DatePicker.js +29 -36
  21. package/out-tsc/src/form/DatePicker.js.map +1 -1
  22. package/out-tsc/src/form/{FormField.js → FieldElement.js} +78 -50
  23. package/out-tsc/src/form/FieldElement.js.map +1 -0
  24. package/out-tsc/src/form/FieldRenderer.js +2 -1
  25. package/out-tsc/src/form/FieldRenderer.js.map +1 -1
  26. package/out-tsc/src/form/ImagePicker.js +122 -126
  27. package/out-tsc/src/form/ImagePicker.js.map +1 -1
  28. package/out-tsc/src/form/KeyValueEditor.js +41 -37
  29. package/out-tsc/src/form/KeyValueEditor.js.map +1 -1
  30. package/out-tsc/src/form/MessageEditor.js +55 -63
  31. package/out-tsc/src/form/MessageEditor.js.map +1 -1
  32. package/out-tsc/src/form/TembaSlider.js +3 -3
  33. package/out-tsc/src/form/TembaSlider.js.map +1 -1
  34. package/out-tsc/src/form/TemplateEditor.js +3 -3
  35. package/out-tsc/src/form/TemplateEditor.js.map +1 -1
  36. package/out-tsc/src/form/TextInput.js +22 -26
  37. package/out-tsc/src/form/TextInput.js.map +1 -1
  38. package/out-tsc/src/form/select/Select.js +9 -15
  39. package/out-tsc/src/form/select/Select.js.map +1 -1
  40. package/out-tsc/src/form/select/UserSelect.js +8 -9
  41. package/out-tsc/src/form/select/UserSelect.js.map +1 -1
  42. package/out-tsc/src/form/select/WorkspaceSelect.js +7 -8
  43. package/out-tsc/src/form/select/WorkspaceSelect.js.map +1 -1
  44. package/out-tsc/src/live/ContactChat.js +32 -40
  45. package/out-tsc/src/live/ContactChat.js.map +1 -1
  46. package/out-tsc/src/live/ContactFieldEditor.js.map +1 -1
  47. package/out-tsc/temba-modules.js +3 -2
  48. package/out-tsc/temba-modules.js.map +1 -1
  49. package/out-tsc/test/temba-checkbox.test.js +16 -0
  50. package/out-tsc/test/temba-checkbox.test.js.map +1 -1
  51. package/out-tsc/test/temba-integration-markdown.test.js +2 -4
  52. package/out-tsc/test/temba-integration-markdown.test.js.map +1 -1
  53. package/out-tsc/test/temba-slider.test.js +0 -1
  54. package/out-tsc/test/temba-slider.test.js.map +1 -1
  55. package/package.json +1 -1
  56. package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
  57. package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
  58. package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
  59. package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
  60. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  61. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  62. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  63. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  64. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  65. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  66. package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
  67. package/screenshots/truth/checkbox/checkbox-no-label-no-background-hover.png +0 -0
  68. package/screenshots/truth/checkbox/checkbox-with-help-text.png +0 -0
  69. package/screenshots/truth/checkbox/checked.png +0 -0
  70. package/screenshots/truth/checkbox/default.png +0 -0
  71. package/screenshots/truth/colorpicker/default.png +0 -0
  72. package/screenshots/truth/colorpicker/focused.png +0 -0
  73. package/screenshots/truth/colorpicker/initialized.png +0 -0
  74. package/screenshots/truth/colorpicker/selected.png +0 -0
  75. package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
  76. package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
  77. package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
  78. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  79. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  80. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  81. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  82. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  83. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  84. package/screenshots/truth/run-list/basic.png +0 -0
  85. package/src/events.ts +5 -6
  86. package/src/form/ArrayEditor.ts +45 -57
  87. package/src/form/BaseListEditor.ts +4 -4
  88. package/src/form/Checkbox.ts +81 -24
  89. package/src/form/ColorPicker.ts +31 -43
  90. package/src/form/Completion.ts +49 -56
  91. package/src/form/Compose.ts +8 -8
  92. package/src/form/ContactSearch.ts +3 -4
  93. package/src/form/DatePicker.ts +32 -38
  94. package/src/form/{FormField.ts → FieldElement.ts} +105 -52
  95. package/src/form/FieldRenderer.ts +2 -1
  96. package/src/form/ImagePicker.ts +107 -110
  97. package/src/form/KeyValueEditor.ts +43 -39
  98. package/src/form/MessageEditor.ts +61 -67
  99. package/src/form/TembaSlider.ts +3 -3
  100. package/src/form/TemplateEditor.ts +3 -3
  101. package/src/form/TextInput.ts +25 -28
  102. package/src/form/select/Select.ts +12 -17
  103. package/src/form/select/UserSelect.ts +10 -11
  104. package/src/form/select/WorkspaceSelect.ts +9 -10
  105. package/src/live/ContactChat.ts +32 -41
  106. package/src/live/ContactFieldEditor.ts +2 -2
  107. package/temba-modules.ts +3 -2
  108. package/test/temba-checkbox.test.ts +26 -0
  109. package/test/temba-integration-markdown.test.ts +2 -4
  110. package/test/temba-slider.test.ts +0 -1
  111. package/test-assets/contacts/history.json +7 -20
  112. package/out-tsc/src/form/FormElement.js +0 -67
  113. package/out-tsc/src/form/FormElement.js.map +0 -1
  114. package/out-tsc/src/form/FormField.js.map +0 -1
  115. package/out-tsc/test/temba-formfield.test.js +0 -94
  116. package/out-tsc/test/temba-formfield.test.js.map +0 -1
  117. package/src/form/FormElement.ts +0 -69
  118. package/test/temba-formfield.test.ts +0 -121
@@ -1,11 +1,14 @@
1
1
  import { TemplateResult, html, css } from 'lit';
2
- import { FormElement } from './FormElement';
2
+ import { FieldElement } from './FieldElement';
3
3
  import { property } from 'lit/decorators.js';
4
4
  import { Icon } from '../Icons';
5
+ import { renderMarkdownInline } from '../markdown';
5
6
 
6
- export class Checkbox extends FormElement {
7
+ export class Checkbox extends FieldElement {
7
8
  static get styles() {
8
9
  return css`
10
+ ${super.styles}
11
+
9
12
  :host {
10
13
  color: var(--color-text);
11
14
  display: inline-block;
@@ -24,25 +27,45 @@ export class Checkbox extends FormElement {
24
27
  background: var(--checkbox-hover-bg, #f9f9f9);
25
28
  }
26
29
 
27
- temba-field {
28
- --help-text-margin-left: 24px;
29
- cursor: pointer;
30
- }
31
-
32
30
  .checkbox-container {
33
31
  cursor: pointer;
34
32
  display: flex;
33
+ align-items: flex-start;
35
34
  user-select: none;
36
35
  -webkit-user-select: none;
37
36
  }
38
37
 
38
+ .checkbox-container temba-icon {
39
+ align-self: flex-start;
40
+ vertical-align: top;
41
+ line-height: 1;
42
+ }
43
+
44
+ .label-and-help {
45
+ flex-grow: 1;
46
+ margin-left: 8px;
47
+ }
48
+
39
49
  .checkbox-label {
40
50
  font-family: var(--font-family);
41
51
  padding: 0px;
42
- margin-left: 8px;
52
+ margin: 0px;
43
53
  font-size: 14px;
44
54
  line-height: 19px;
45
- flex-grow: 1;
55
+ }
56
+
57
+ .checkbox-help-text {
58
+ font-family: var(--font-family);
59
+ font-size: var(--help-text-size, 0.85em);
60
+ line-height: normal;
61
+ color: var(--color-text-help);
62
+ margin-top: 4px;
63
+ opacity: 1;
64
+ }
65
+
66
+ /* Checkbox help text should align with the checkbox icon, not indented */
67
+ .help-text {
68
+ margin-left: 0;
46
69
  }
47
70
 
48
71
  .far {
@@ -123,7 +146,7 @@ export class Checkbox extends FormElement {
123
146
  super.click();
124
147
  }
125
148
 
126
- public render(): TemplateResult {
149
+ protected renderWidget(): TemplateResult {
127
150
  const icon = html`<temba-icon
128
151
  name="${this.checked
129
152
  ? Icon.checkbox_checked
@@ -132,27 +155,61 @@ export class Checkbox extends FormElement {
132
155
  : Icon.checkbox}"
133
156
  size="${this.size}"
134
157
  animatechange="${this.animateChange}"
135
- />`;
158
+ ></temba-icon>`;
136
159
 
137
160
  return html`
138
- <div class="wrapper ${this.label ? 'label' : ''}">
139
- <temba-field
140
- name=${this.name}
141
- .helpText=${this.helpText}
142
- .errors=${this.errors}
143
- .widgetOnly=${this.widgetOnly}
144
- .helpAlways=${true}
145
- ?disabled=${this.disabled}
146
- @click=${this.handleClick}
147
- >
148
- <div class="checkbox-container ${this.disabled ? 'disabled' : ''}">
149
- ${icon}
161
+ <div
162
+ class="wrapper ${this.label ? 'label' : ''}"
163
+ @click=${this.handleClick}
164
+ >
165
+ <div class="checkbox-container ${this.disabled ? 'disabled' : ''}">
166
+ ${icon}
167
+ <div class="label-and-help">
150
168
  ${this.label && String(this.label).trim()
151
169
  ? html`<div class="checkbox-label">${this.label}</div>`
152
170
  : null}
171
+ ${this.helpText && this.helpText !== 'None'
172
+ ? html` <div class="checkbox-help-text">${this.helpText}</div> `
173
+ : null}
153
174
  </div>
154
- </temba-field>
175
+ </div>
176
+ </div>
177
+ `;
178
+ }
179
+
180
+ protected renderField(): TemplateResult {
181
+ // Use standard FieldElement behavior but skip the field label since checkbox renders its own inline
182
+ const hasErrors = !this.hideErrors && this.errors && this.errors.length > 0;
183
+ const errors = hasErrors
184
+ ? this.errors.map((error: string) => {
185
+ return html`
186
+ <div class="alert-error">${renderMarkdownInline(error)}</div>
187
+ `;
188
+ })
189
+ : [];
190
+
191
+ if (this.widgetOnly) {
192
+ return html`
193
+ <div class="${this.disabled ? 'disabled' : ''}">
194
+ ${this.renderWidget()}
195
+ </div>
196
+ ${errors}
197
+ `;
198
+ }
199
+
200
+ // This matches FieldElement.renderField() but without the field label
201
+ return html`
202
+ <div
203
+ class="field ${this.disabled ? 'disabled' : ''} ${hasErrors
204
+ ? 'has-error'
205
+ : ''}"
206
+ >
207
+ <div class="widget">${this.renderWidget()} ${errors}</div>
155
208
  </div>
156
209
  `;
157
210
  }
211
+
212
+ public render(): TemplateResult {
213
+ return this.renderField();
214
+ }
158
215
  }
@@ -1,10 +1,10 @@
1
1
  import { html, css, PropertyValueMap } from 'lit';
2
- import { FormElement } from './FormElement';
2
+ import { FieldElement } from './FieldElement';
3
3
  import { property } from 'lit/decorators.js';
4
4
  import { getClasses, hslToHex } from '../utils';
5
5
  import { TextInput } from './TextInput';
6
6
 
7
- export class ColorPicker extends FormElement {
7
+ export class ColorPicker extends FieldElement {
8
8
  @property({ type: Boolean })
9
9
  expanded = false;
10
10
 
@@ -24,6 +24,8 @@ export class ColorPicker extends FormElement {
24
24
 
25
25
  static get styles() {
26
26
  return css`
27
+ ${super.styles}
28
+
27
29
  :host {
28
30
  color: var(--color-text);
29
31
  display: inline-block;
@@ -38,11 +40,6 @@ export class ColorPicker extends FormElement {
38
40
  width: 5em;
39
41
  }
40
42
 
41
- temba-field {
42
- display: block;
43
- width: 100%;
44
- }
45
-
46
43
  .wrapper {
47
44
  border: 1px solid var(--color-widget-border);
48
45
  padding: calc(var(--curvature) / 2);
@@ -221,46 +218,37 @@ export class ColorPicker extends FormElement {
221
218
  return value;
222
219
  }
223
220
 
224
- public render() {
221
+ protected renderWidget() {
225
222
  return html`
226
- <temba-field
227
- name=${this.name}
228
- .helpText=${this.helpText}
229
- .errors=${this.errors}
230
- .widgetOnly=${this.widgetOnly}
231
- .hideLabel=${this.hideLabel}
232
- .disabled=${this.disabled}
233
- >
234
- <div style="display:flex" tabindex="0">
235
- <div class=${getClasses({ wrapper: true, expanded: this.expanded })}>
236
- <div class=${getClasses({ 'picker-wrapper': true })}>
237
- <div
238
- class=${getClasses({
239
- preview: true,
240
- selecting: this.selecting
241
- })}
242
- style="color:${this.labelColor};background:${this.previewColor}"
243
- @click=${this.handlePreviewClick}
244
- >
245
- ${this.label}
246
- </div>
247
- <div
248
- class="color-picker"
249
- tabindex="0"
250
- @blur=${this.handleBlur}
251
- @mousemove=${this.handleMouseMove}
252
- @mouseout=${this.handleMouseOut}
253
- @click=${this.handleColorClick}
254
- ></div>
223
+ <div style="display:flex" tabindex="0">
224
+ <div class=${getClasses({ wrapper: true, expanded: this.expanded })}>
225
+ <div class=${getClasses({ 'picker-wrapper': true })}>
226
+ <div
227
+ class=${getClasses({
228
+ preview: true,
229
+ selecting: this.selecting
230
+ })}
231
+ style="color:${this.labelColor};background:${this.previewColor}"
232
+ @click=${this.handlePreviewClick}
233
+ >
234
+ ${this.label}
255
235
  </div>
256
- <temba-textinput
257
- value=${this.hex}
258
- @input=${this.handleHexInput}
259
- placeholder="#000000"
260
- ></temba-textinput>
236
+ <div
237
+ class="color-picker"
238
+ tabindex="0"
239
+ @blur=${this.handleBlur}
240
+ @mousemove=${this.handleMouseMove}
241
+ @mouseout=${this.handleMouseOut}
242
+ @click=${this.handleColorClick}
243
+ ></div>
261
244
  </div>
245
+ <temba-textinput
246
+ value=${this.hex}
247
+ @input=${this.handleHexInput}
248
+ placeholder="#000000"
249
+ ></temba-textinput>
262
250
  </div>
263
- </temba-field>
251
+ </div>
264
252
  `;
265
253
  }
266
254
  }
@@ -8,7 +8,7 @@ import {
8
8
  executeCompletionQuery
9
9
  } from '../excellent/helpers';
10
10
 
11
- import { FormElement } from './FormElement';
11
+ import { FieldElement } from './FieldElement';
12
12
  import { CompletionOption, Position } from '../interfaces';
13
13
  import { styleMap } from 'lit-html/directives/style-map.js';
14
14
  import { msg } from '@lit/localize';
@@ -16,9 +16,10 @@ import { msg } from '@lit/localize';
16
16
  /**
17
17
  * Completion is a text input that handles excellent completion options in a popup
18
18
  */
19
- export class Completion extends FormElement {
19
+ export class Completion extends FieldElement {
20
20
  static get styles() {
21
21
  return css`
22
+ ${super.styles}
22
23
  :host {
23
24
  display: block;
24
25
  }
@@ -69,7 +70,6 @@ export class Completion extends FormElement {
69
70
  }
70
71
 
71
72
  code {
72
- background: rgba(0, 0, 0, 0.1);
73
73
  padding: 1px 5px;
74
74
  border-radius: var(--curvature);
75
75
  }
@@ -106,9 +106,6 @@ export class Completion extends FormElement {
106
106
  @property({ type: String })
107
107
  name = '';
108
108
 
109
- @property({ type: String })
110
- value = '';
111
-
112
109
  @property({ type: Boolean })
113
110
  textarea: boolean;
114
111
 
@@ -259,7 +256,7 @@ export class Completion extends FormElement {
259
256
  }
260
257
  }
261
258
 
262
- public render(): TemplateResult {
259
+ protected renderWidget(): TemplateResult {
263
260
  const anchorStyles = this.anchorPosition
264
261
  ? {
265
262
  top: `${this.anchorPosition.top}px`,
@@ -270,55 +267,51 @@ export class Completion extends FormElement {
270
267
  const visible = this.options && this.options.length > 0;
271
268
 
272
269
  return html`
273
- <temba-field
274
- name=${this.name}
275
- .label=${this.label}
276
- .helpText=${this.helpText}
277
- .errors=${this.errors}
278
- .widgetOnly=${this.widgetOnly}
279
- >
280
- <div class="comp-container">
281
- <div id="anchor" style=${styleMap(anchorStyles)}></div>
282
- <temba-textinput
283
- name=${this.name}
284
- placeholder=${this.placeholder}
285
- gsm=${this.gsm}
286
- counter=${ifDefined(this.counter)}
287
- @keyup=${this.handleKeyUp}
288
- @click=${this.handleClick}
289
- @input=${this.handleInput}
290
- @blur=${this.handleOptionCanceled}
291
- maxlength="${ifDefined(this.maxLength)}"
292
- .value=${this.value}
293
- ?autogrow=${this.autogrow}
294
- ?textarea=${this.textarea}
295
- ?submitOnEnter=${this.submitOnEnter}
296
- style=${this.minHeight
297
- ? `--textarea-min-height: ${this.minHeight}px`
298
- : ''}
299
- >
300
- </temba-textinput>
301
- <temba-options
302
- @temba-selection=${this.handleOptionSelection}
303
- @temba-canceled=${this.handleOptionCanceled}
304
- .renderOption=${renderCompletionOption}
305
- .anchorTo=${this.anchorElement}
306
- .options=${this.options}
307
- ?visible=${visible}
308
- >
309
- ${this.currentFunction
310
- ? html`
311
- <div class="current-fn">
312
- ${renderCompletionOption(this.currentFunction, true)}
313
- </div>
314
- `
315
- : null}
316
- <div class="footer" style="${!visible ? 'display:none' : null}">
317
- ${msg('Tab to complete, enter to select')}
318
- </div>
319
- </temba-options>
320
- </div>
321
- </temba-field>
270
+ <div class="comp-container">
271
+ <div id="anchor" style=${styleMap(anchorStyles)}></div>
272
+ <temba-textinput
273
+ name=${this.name}
274
+ placeholder=${this.placeholder}
275
+ gsm=${this.gsm}
276
+ counter=${ifDefined(this.counter)}
277
+ @keyup=${this.handleKeyUp}
278
+ @click=${this.handleClick}
279
+ @input=${this.handleInput}
280
+ @blur=${this.handleOptionCanceled}
281
+ maxlength="${ifDefined(this.maxLength)}"
282
+ .value=${this.value}
283
+ ?autogrow=${this.autogrow}
284
+ ?textarea=${this.textarea}
285
+ ?submitOnEnter=${this.submitOnEnter}
286
+ style=${this.minHeight
287
+ ? `--textarea-min-height: ${this.minHeight}px`
288
+ : ''}
289
+ >
290
+ </temba-textinput>
291
+ <temba-options
292
+ @temba-selection=${this.handleOptionSelection}
293
+ @temba-canceled=${this.handleOptionCanceled}
294
+ .renderOption=${renderCompletionOption}
295
+ .anchorTo=${this.anchorElement}
296
+ .options=${this.options}
297
+ ?visible=${visible}
298
+ >
299
+ ${this.currentFunction
300
+ ? html`
301
+ <div class="current-fn">
302
+ ${renderCompletionOption(this.currentFunction, true)}
303
+ </div>
304
+ `
305
+ : null}
306
+ <div class="footer" style="${!visible ? 'display:none' : null}">
307
+ ${msg('Tab to complete, enter to select')}
308
+ </div>
309
+ </temba-options>
310
+ </div>
322
311
  `;
323
312
  }
313
+
314
+ public render(): TemplateResult {
315
+ return this.renderField();
316
+ }
324
317
  }
@@ -1,5 +1,5 @@
1
1
  import { TemplateResult, html, css } from 'lit';
2
- import { FormElement } from './FormElement';
2
+ import { FieldElement } from './FieldElement';
3
3
  import { property } from 'lit/decorators.js';
4
4
  import { Attachment, CustomEventType, Language, Shortcut } from '../interfaces';
5
5
  import { DEFAULT_MEDIA_ENDPOINT, getClasses } from '../utils';
@@ -20,7 +20,7 @@ export interface ComposeValue {
20
20
  variables: string[];
21
21
  }
22
22
 
23
- export class Compose extends FormElement {
23
+ export class Compose extends FieldElement {
24
24
  static get styles() {
25
25
  return css`
26
26
  :host {
@@ -544,12 +544,12 @@ export class Compose extends FormElement {
544
544
  }
545
545
 
546
546
  public render(): TemplateResult {
547
+ return this.renderField();
548
+ }
549
+
550
+ protected renderWidget(): TemplateResult {
547
551
  return html`
548
- <temba-field
549
- name=${this.name}
550
- .errors=${this.errors}
551
- .widgetOnly=${this.widgetOnly}
552
- .value=${this.value}
552
+ <div
553
553
  class=${getClasses({
554
554
  'active-template':
555
555
  !!this.currentTemplate &&
@@ -570,7 +570,7 @@ export class Compose extends FormElement {
570
570
  <div class="container">
571
571
  <div class="items actions">${this.getActions()}</div>
572
572
  </div>
573
- </temba-field>
573
+ </div>
574
574
  `;
575
575
  }
576
576
 
@@ -5,7 +5,7 @@ import { getClasses, postJSON, stopEvent, WebResponse } from '../utils';
5
5
  import { TextInput } from './TextInput';
6
6
  import '../display/Alert';
7
7
  import { Contact, CustomEventType } from '../interfaces';
8
- import { FormElement } from './FormElement';
8
+ import { FieldElement } from './FieldElement';
9
9
  import { Checkbox } from './Checkbox';
10
10
  import { msg } from '@lit/localize';
11
11
  import { OmniOption } from './select/Omnibox';
@@ -23,7 +23,7 @@ interface SummaryResponse {
23
23
  blockers: string[];
24
24
  }
25
25
 
26
- export class ContactSearch extends FormElement {
26
+ export class ContactSearch extends FieldElement {
27
27
  static get styles() {
28
28
  return css`
29
29
  :host {
@@ -475,7 +475,7 @@ export class ContactSearch extends FormElement {
475
475
  }
476
476
  }
477
477
 
478
- public render(): TemplateResult {
478
+ public renderWidget(): TemplateResult {
479
479
  let summary: TemplateResult;
480
480
  if (this.summary) {
481
481
  if (!this.summary.error) {
@@ -539,7 +539,6 @@ export class ContactSearch extends FormElement {
539
539
  this.advanced
540
540
  ? html`<div class="query">
541
541
  <temba-textinput
542
- .label=${this.label}
543
542
  .helpText=${this.helpText}
544
543
  .widgetOnly=${this.widgetOnly}
545
544
  .errors=${this.errors}
@@ -1,12 +1,13 @@
1
1
  import { TemplateResult, html, css, PropertyValueMap } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
- import { FormElement } from './FormElement';
3
+ import { FieldElement } from './FieldElement';
4
4
  import { getClasses } from '../utils';
5
5
  import { DateTime } from 'luxon';
6
6
 
7
- export class DatePicker extends FormElement {
7
+ export class DatePicker extends FieldElement {
8
8
  static get styles() {
9
9
  return css`
10
+ ${super.styles}
10
11
  :host {
11
12
  display: block;
12
13
  }
@@ -205,7 +206,7 @@ export class DatePicker extends FormElement {
205
206
  this.shadowRoot.querySelector('input').focus();
206
207
  }
207
208
 
208
- public render(): TemplateResult {
209
+ protected renderWidget(): TemplateResult {
209
210
  const classes = getClasses({ unset: !this.value });
210
211
 
211
212
  let dateWidgetValue = null;
@@ -216,42 +217,35 @@ export class DatePicker extends FormElement {
216
217
  }
217
218
 
218
219
  return html`
219
- <temba-field
220
- class=${getClasses({ disabled: this.disabled })}
221
- name=${this.name}
222
- .label="${this.label}"
223
- .helpText="${this.helpText}"
224
- .errors=${this.errors}
225
- .widgetOnly=${this.widgetOnly}
226
- .hideLabel=${this.hideLabel}
227
- .disabled=${this.disabled}
228
- >
229
- <div class="container" @click=${this.handleClicked}>
230
- <slot name="prefix"></slot>
231
- <div class="input-wrapper">
232
- <input
233
- class=${classes}
234
- name=${this.label}
235
- value=${dateWidgetValue}
236
- type="${this.time ? 'datetime-local' : 'date'}"
237
- @change=${this.handleChange}
238
- min=${this.min || undefined}
239
- max=${this.max || undefined}
240
- />
241
- </div>
242
- ${this.time
243
- ? html`
244
- <div class="tz-wrapper">
245
- <div class="tz">
246
- <div class="label">Time Zone</div>
247
- <div class="zone">${this.timezoneFriendly}</div>
248
- </div>
249
- </div>
250
- `
251
- : null}
252
- <slot name="postfix"></slot>
220
+ <div class="container" @click=${this.handleClicked}>
221
+ <slot name="prefix"></slot>
222
+ <div class="input-wrapper">
223
+ <input
224
+ class=${classes}
225
+ name=${this.label}
226
+ value=${dateWidgetValue}
227
+ type="${this.time ? 'datetime-local' : 'date'}"
228
+ @change=${this.handleChange}
229
+ min=${this.min || undefined}
230
+ max=${this.max || undefined}
231
+ />
253
232
  </div>
254
- </temba-field>
233
+ ${this.time
234
+ ? html`
235
+ <div class="tz-wrapper">
236
+ <div class="tz">
237
+ <div class="label">Time Zone</div>
238
+ <div class="zone">${this.timezoneFriendly}</div>
239
+ </div>
240
+ </div>
241
+ `
242
+ : null}
243
+ <slot name="postfix"></slot>
244
+ </div>
255
245
  `;
256
246
  }
247
+
248
+ public render(): TemplateResult {
249
+ return this.renderField();
250
+ }
257
251
  }