@nyaruka/temba-components 0.129.7 → 0.129.9

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 (269) hide show
  1. package/.devcontainer/Dockerfile +11 -4
  2. package/.devcontainer/devcontainer.json +3 -2
  3. package/.github/workflows/build.yml +4 -14
  4. package/CHANGELOG.md +29 -0
  5. package/demo/components/flow/example.html +1 -1
  6. package/demo/components/message-editor/example.html +125 -0
  7. package/demo/components/textinput/completion.html +1 -0
  8. package/demo/data/flows/food-order.json +12 -21
  9. package/demo/data/flows/sample-flow.json +210 -104
  10. package/dist/temba-components.js +715 -364
  11. package/dist/temba-components.js.map +1 -1
  12. package/out-tsc/src/display/Thumbnail.js +2 -1
  13. package/out-tsc/src/display/Thumbnail.js.map +1 -1
  14. package/out-tsc/src/events.js.map +1 -1
  15. package/out-tsc/src/excellent/helpers.js +2 -2
  16. package/out-tsc/src/excellent/helpers.js.map +1 -1
  17. package/out-tsc/src/flow/CanvasNode.js +25 -7
  18. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  19. package/out-tsc/src/flow/Editor.js +11 -1
  20. package/out-tsc/src/flow/Editor.js.map +1 -1
  21. package/out-tsc/src/flow/NodeEditor.js +342 -276
  22. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  23. package/out-tsc/src/flow/actions/add_input_labels.js +40 -0
  24. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  25. package/out-tsc/src/flow/actions/call_llm.js +56 -3
  26. package/out-tsc/src/flow/actions/call_llm.js.map +1 -1
  27. package/out-tsc/src/flow/actions/call_webhook.js +26 -17
  28. package/out-tsc/src/flow/actions/call_webhook.js.map +1 -1
  29. package/out-tsc/src/flow/actions/open_ticket.js +65 -3
  30. package/out-tsc/src/flow/actions/open_ticket.js.map +1 -1
  31. package/out-tsc/src/flow/actions/send_msg.js +147 -6
  32. package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
  33. package/out-tsc/src/flow/actions/set_run_result.js +75 -0
  34. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
  35. package/out-tsc/src/flow/config.js +4 -0
  36. package/out-tsc/src/flow/config.js.map +1 -1
  37. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +227 -0
  38. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -0
  39. package/out-tsc/src/flow/nodes/split_by_ticket.js +18 -0
  40. package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -0
  41. package/out-tsc/src/flow/nodes/wait_for_response.js +27 -1
  42. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  43. package/out-tsc/src/flow/types.js +0 -65
  44. package/out-tsc/src/flow/types.js.map +1 -1
  45. package/out-tsc/src/form/ArrayEditor.js +87 -57
  46. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  47. package/out-tsc/src/form/BaseListEditor.js +19 -4
  48. package/out-tsc/src/form/BaseListEditor.js.map +1 -1
  49. package/out-tsc/src/form/FieldRenderer.js +305 -0
  50. package/out-tsc/src/form/FieldRenderer.js.map +1 -0
  51. package/out-tsc/src/form/FormField.js +4 -4
  52. package/out-tsc/src/form/FormField.js.map +1 -1
  53. package/out-tsc/src/form/KeyValueEditor.js +1 -1
  54. package/out-tsc/src/form/KeyValueEditor.js.map +1 -1
  55. package/out-tsc/src/form/MediaPicker.js +13 -1
  56. package/out-tsc/src/form/MediaPicker.js.map +1 -1
  57. package/out-tsc/src/form/MessageEditor.js +422 -0
  58. package/out-tsc/src/form/MessageEditor.js.map +1 -0
  59. package/out-tsc/src/form/TextInput.js +13 -6
  60. package/out-tsc/src/form/TextInput.js.map +1 -1
  61. package/out-tsc/src/form/select/Select.js +52 -24
  62. package/out-tsc/src/form/select/Select.js.map +1 -1
  63. package/out-tsc/src/live/ContactChat.js +66 -15
  64. package/out-tsc/src/live/ContactChat.js.map +1 -1
  65. package/out-tsc/src/markdown.js +13 -11
  66. package/out-tsc/src/markdown.js.map +1 -1
  67. package/out-tsc/temba-modules.js +2 -0
  68. package/out-tsc/temba-modules.js.map +1 -1
  69. package/out-tsc/test/ActionHelper.js +2 -0
  70. package/out-tsc/test/ActionHelper.js.map +1 -1
  71. package/out-tsc/test/NodeHelper.js +148 -0
  72. package/out-tsc/test/NodeHelper.js.map +1 -0
  73. package/out-tsc/test/actions/call_llm.test.js +103 -0
  74. package/out-tsc/test/actions/call_llm.test.js.map +1 -0
  75. package/out-tsc/test/nodes/split_by_llm_categorize.test.js +532 -0
  76. package/out-tsc/test/nodes/split_by_llm_categorize.test.js.map +1 -0
  77. package/out-tsc/test/nodes/split_by_random.test.js +150 -0
  78. package/out-tsc/test/nodes/split_by_random.test.js.map +1 -0
  79. package/out-tsc/test/nodes/wait_for_digits.test.js +150 -0
  80. package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -0
  81. package/out-tsc/test/nodes/wait_for_response.test.js +171 -0
  82. package/out-tsc/test/nodes/wait_for_response.test.js.map +1 -0
  83. package/out-tsc/test/temba-add-input-labels.test.js +70 -0
  84. package/out-tsc/test/temba-add-input-labels.test.js.map +1 -0
  85. package/out-tsc/test/temba-field-config.test.js +4 -2
  86. package/out-tsc/test/temba-field-config.test.js.map +1 -1
  87. package/out-tsc/test/temba-field-renderer.test.js +296 -0
  88. package/out-tsc/test/temba-field-renderer.test.js.map +1 -0
  89. package/out-tsc/test/temba-markdown.test.js +1 -1
  90. package/out-tsc/test/temba-markdown.test.js.map +1 -1
  91. package/out-tsc/test/temba-message-editor.test.js +194 -0
  92. package/out-tsc/test/temba-message-editor.test.js.map +1 -0
  93. package/out-tsc/test/temba-node-editor.test.js +471 -0
  94. package/out-tsc/test/temba-node-editor.test.js.map +1 -1
  95. package/out-tsc/test/temba-select.test.js +7 -4
  96. package/out-tsc/test/temba-select.test.js.map +1 -1
  97. package/out-tsc/test/temba-textinput.test.js +16 -0
  98. package/out-tsc/test/temba-textinput.test.js.map +1 -1
  99. package/out-tsc/test/temba-webchat.test.js +5 -1
  100. package/out-tsc/test/temba-webchat.test.js.map +1 -1
  101. package/out-tsc/test/utils.test.js +2 -8
  102. package/out-tsc/test/utils.test.js.map +1 -1
  103. package/package.json +7 -4
  104. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  105. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  106. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  107. package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
  108. package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
  109. package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
  110. package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
  111. package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
  112. package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
  113. package/screenshots/truth/actions/call_llm/render/information-extraction.png +0 -0
  114. package/screenshots/truth/actions/call_llm/render/sentiment-analysis.png +0 -0
  115. package/screenshots/truth/actions/call_llm/render/summarization.png +0 -0
  116. package/screenshots/truth/actions/call_llm/render/translation-task.png +0 -0
  117. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  118. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  119. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  120. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  121. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  122. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  123. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  124. package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
  125. package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
  126. package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
  127. package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
  128. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  129. package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
  130. package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
  131. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  132. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  133. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  134. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  135. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  136. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  137. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  138. package/screenshots/truth/editor/router.png +0 -0
  139. package/screenshots/truth/editor/send_msg.png +0 -0
  140. package/screenshots/truth/editor/set_contact_language.png +0 -0
  141. package/screenshots/truth/editor/set_contact_name.png +0 -0
  142. package/screenshots/truth/editor/set_run_result.png +0 -0
  143. package/screenshots/truth/editor/wait.png +0 -0
  144. package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
  145. package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
  146. package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
  147. package/screenshots/truth/field-renderer/context-comparison.png +0 -0
  148. package/screenshots/truth/field-renderer/key-value-with-label.png +0 -0
  149. package/screenshots/truth/field-renderer/message-editor-with-label.png +0 -0
  150. package/screenshots/truth/field-renderer/select-multi.png +0 -0
  151. package/screenshots/truth/field-renderer/select-no-label.png +0 -0
  152. package/screenshots/truth/field-renderer/select-with-label.png +0 -0
  153. package/screenshots/truth/field-renderer/text-evaluated.png +0 -0
  154. package/screenshots/truth/field-renderer/text-no-label.png +0 -0
  155. package/screenshots/truth/field-renderer/text-with-errors.png +0 -0
  156. package/screenshots/truth/field-renderer/text-with-label.png +0 -0
  157. package/screenshots/truth/field-renderer/textarea-evaluated.png +0 -0
  158. package/screenshots/truth/field-renderer/textarea-with-label.png +0 -0
  159. package/screenshots/truth/formfield/markdown-errors.png +0 -0
  160. package/screenshots/truth/formfield/no-errors.png +0 -0
  161. package/screenshots/truth/formfield/plain-text-errors.png +0 -0
  162. package/screenshots/truth/message-editor/autogrow-initial-content.png +0 -0
  163. package/screenshots/truth/message-editor/default.png +0 -0
  164. package/screenshots/truth/message-editor/drag-highlight.png +0 -0
  165. package/screenshots/truth/message-editor/filtered-attachments.png +0 -0
  166. package/screenshots/truth/message-editor/with-completion.png +0 -0
  167. package/screenshots/truth/message-editor/with-properties.png +0 -0
  168. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  169. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  170. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  171. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  172. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  173. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  174. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  175. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  176. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  177. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  178. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  179. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  180. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  181. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  182. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  183. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  184. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  185. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  186. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  187. package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
  188. package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
  189. package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
  190. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  191. package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
  192. package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
  193. package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
  194. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  195. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  196. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  197. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  198. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  199. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  200. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  201. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  202. package/screenshots/truth/omnibox/selected.png +0 -0
  203. package/screenshots/truth/select/functions.png +0 -0
  204. package/screenshots/truth/select/multi-with-endpoint.png +0 -0
  205. package/screenshots/truth/select/search-enabled.png +0 -0
  206. package/screenshots/truth/textinput/autogrow-initial.png +0 -0
  207. package/screenshots/truth/textinput/input-form.png +0 -0
  208. package/src/display/Thumbnail.ts +2 -1
  209. package/src/events.ts +13 -1
  210. package/src/excellent/helpers.ts +2 -2
  211. package/src/flow/CanvasNode.ts +22 -1
  212. package/src/flow/Editor.ts +12 -1
  213. package/src/flow/NodeEditor.ts +412 -354
  214. package/src/flow/actions/add_input_labels.ts +45 -0
  215. package/src/flow/actions/call_llm.ts +57 -3
  216. package/src/flow/actions/call_webhook.ts +28 -18
  217. package/src/flow/actions/open_ticket.ts +74 -3
  218. package/src/flow/actions/send_msg.ts +170 -6
  219. package/src/flow/actions/set_run_result.ts +83 -0
  220. package/src/flow/config.ts +4 -0
  221. package/src/flow/nodes/split_by_llm_categorize.ts +277 -0
  222. package/src/flow/nodes/split_by_ticket.ts +19 -0
  223. package/src/flow/nodes/wait_for_response.ts +28 -1
  224. package/src/flow/types.ts +46 -128
  225. package/src/form/ArrayEditor.ts +96 -66
  226. package/src/form/BaseListEditor.ts +22 -6
  227. package/src/form/FieldRenderer.ts +465 -0
  228. package/src/form/FormField.ts +4 -4
  229. package/src/form/KeyValueEditor.ts +1 -1
  230. package/src/form/MediaPicker.ts +13 -1
  231. package/src/form/MessageEditor.ts +449 -0
  232. package/src/form/TextInput.ts +16 -8
  233. package/src/form/select/Select.ts +55 -24
  234. package/src/live/ContactChat.ts +69 -19
  235. package/src/markdown.ts +19 -11
  236. package/src/store/flow-definition.d.ts +5 -2
  237. package/static/api/labels.json +31 -0
  238. package/static/api/topics.json +24 -9
  239. package/static/api/users.json +35 -16
  240. package/static/css/temba-components.css +5 -3
  241. package/static/mr/docs/en-us/editor.json +2588 -0
  242. package/stress-test.js +143 -0
  243. package/temba-modules.ts +2 -0
  244. package/test/ActionHelper.ts +2 -0
  245. package/test/NodeHelper.ts +184 -0
  246. package/test/actions/call_llm.test.ts +137 -0
  247. package/test/nodes/README.md +78 -0
  248. package/test/nodes/split_by_llm_categorize.test.ts +698 -0
  249. package/test/nodes/split_by_random.test.ts +177 -0
  250. package/test/nodes/wait_for_digits.test.ts +176 -0
  251. package/test/nodes/wait_for_response.test.ts +206 -0
  252. package/test/temba-add-input-labels.test.ts +87 -0
  253. package/test/temba-field-config.test.ts +4 -2
  254. package/test/temba-field-renderer.test.ts +482 -0
  255. package/test/temba-markdown.test.ts +1 -1
  256. package/test/temba-message-editor.test.ts +300 -0
  257. package/test/temba-node-editor.test.ts +590 -0
  258. package/test/temba-select.test.ts +7 -7
  259. package/test/temba-textinput.test.ts +26 -0
  260. package/test/temba-webchat.test.ts +6 -1
  261. package/test/utils.test.ts +2 -13
  262. package/test-assets/contacts/history.json +19 -0
  263. package/test-assets/select/llms.json +18 -0
  264. package/test-assets/style.css +2 -0
  265. package/web-dev-mock.mjs +523 -0
  266. package/web-dev-server.config.mjs +74 -6
  267. package/web-test-runner.config.mjs +9 -4
  268. package/test/temba-flow-editor.test.ts.backup +0 -563
  269. package/test/temba-utils-index.test.ts.backup +0 -1737
@@ -1 +1 @@
1
- {"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../../src/form/TextInput.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit-html/directives/if-defined.js';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { FormElement } from './FormElement';\nimport { Modax } from '../layout/Modax';\nimport { sanitizeUnintendedUnicode } from '../utils';\nimport { CharCount } from '../display/CharCount';\n\nexport enum InputType {\n Text = 'text',\n Password = 'password',\n Number = 'number'\n}\n\nexport class TextInput extends FormElement {\n static get styles() {\n return css`\n .input-container {\n border-radius: var(--curvature-widget);\n cursor: var(--input-cursor);\n background: var(--color-widget-bg);\n border: 1px solid var(--color-widget-border);\n transition: all ease-in-out var(--transition-speed);\n display: flex;\n flex-direction: row;\n align-items: stretch;\n box-shadow: var(--widget-box-shadow);\n caret-color: var(--input-caret);\n }\n\n .clear-icon {\n --icon-color: var(--color-text-dark-secondary);\n cursor: pointer;\n margin: auto;\n padding-right: 10px;\n line-height: 1;\n }\n\n .clear-icon:hover {\n --icon-color: var(--color-text-dark);\n }\n\n .hidden {\n visibility: hidden;\n position: absolute;\n }\n\n .input-container:focus-within {\n border-color: var(--color-focus);\n background: var(--color-widget-bg-focused);\n box-shadow: var(--widget-box-shadow-focused);\n position: relative;\n }\n\n .input-container:hover {\n }\n\n textarea {\n height: var(--textarea-height);\n min-height: var(--textarea-min-height, var(--textarea-height));\n transition: height var(--transition-speed) ease-in-out;\n unicode-bidi: var(--unicode-bidi, normal);\n }\n\n .textinput:focus {\n }\n\n .textinput {\n padding: var(--temba-textinput-padding);\n border: none;\n flex: 1;\n margin: 0;\n background: transparent;\n color: var(--color-widget-text);\n font-family: var(--font-family);\n font-size: var(--temba-textinput-font-size);\n line-height: normal;\n cursor: var(--input-cursor);\n resize: none;\n width: 100%;\n }\n\n .textinput:focus {\n outline: none;\n box-shadow: none;\n cursor: text;\n color: var(--color-widget-text-focused, var(--color-widget-text));\n }\n\n .textinput::placeholder {\n color: var(--color-placeholder);\n }\n\n .grow-wrap {\n display: flex;\n align-items: stretch;\n width: 100%;\n margin-bottom: 1em;\n }\n\n .grow-wrap > div {\n border: 0px solid green;\n white-space: pre-wrap;\n width: 100%;\n padding: var(--temba-textinput-padding);\n flex: 1;\n margin: 0;\n background: none;\n color: var(--color-widget-text);\n font-family: var(--font-family);\n font-size: var(--temba-textinput-font-size);\n line-height: normal;\n cursor: text;\n resize: none;\n width: 100%;\n word-break: break-word;\n opacity: 0;\n z-index: -1;\n max-height: var(--temba-textinput-max-height, 30em);\n }\n\n .grow-wrap textarea {\n margin-left: -100%;\n height: 100%;\n flex-grow: 1;\n }\n\n input[type='number'] {\n appearance: none;\n }\n\n input[type='number']::-webkit-inner-spin-button {\n display: none;\n }\n\n .type-icon {\n color: #e3e3e3;\n }\n `;\n }\n\n @property({ type: Boolean })\n textarea: boolean;\n\n @property({ type: String })\n placeholder = '';\n\n @property({ type: Boolean })\n password: boolean;\n\n @property({ type: Number })\n maxlength: number;\n\n @property({ type: Object })\n inputElement: HTMLInputElement;\n\n @property({ type: Boolean })\n clearable: boolean;\n\n @property({ type: Boolean })\n gsm: boolean;\n\n @property({ type: String })\n counter: string;\n\n // if we are still loading\n @property({ type: Boolean })\n loading = true;\n\n @property({ type: Boolean })\n submitOnEnter = true;\n\n @property()\n onBlur: any;\n\n @property({ type: Boolean })\n autogrow = false;\n\n @property({ type: String })\n type = InputType.Text;\n\n counterElement: CharCount = null;\n cursorStart = -1;\n cursorEnd = -1;\n\n public constructor() {\n super();\n }\n\n public firstUpdated(changes: Map<string, any>) {\n super.firstUpdated(changes);\n\n this.inputElement = this.shadowRoot.querySelector('.textinput');\n\n if (changes.has('counter')) {\n let root = this.getParentModax() as any;\n if (root) {\n root = root.shadowRoot;\n }\n if (!root) {\n root = document;\n }\n this.counterElement = root.querySelector(this.counter);\n this.counterElement.text = this.value;\n }\n }\n\n public updated(changes: Map<string, any>) {\n super.updated(changes);\n\n if (changes.has('value')) {\n if (changes.get('value') !== undefined) {\n this.fireEvent('change');\n }\n\n if (this.textarea && this.autogrow) {\n const autogrow = this.shadowRoot.querySelector(\n '.grow-wrap > div'\n ) as HTMLDivElement;\n autogrow.innerText = this.value + String.fromCharCode(10);\n }\n\n if (this.cursorStart > -1 && this.cursorEnd > -1) {\n this.inputElement.setSelectionRange(this.cursorStart, this.cursorEnd);\n this.cursorStart = -1;\n this.cursorEnd = -1;\n }\n }\n }\n\n public getDisplayValue() {\n return this.inputElement.value;\n }\n\n private handleClear(event: any): void {\n event.stopPropagation();\n event.preventDefault();\n this.value = null;\n }\n\n public getTextInput(): TextInput {\n return this;\n }\n\n public updateValue(value: string): void {\n const cursorStart = this.inputElement.selectionStart;\n const cursorEnd = this.inputElement.selectionEnd;\n const sanitized = this.sanitizeGSM(value);\n\n if (sanitized !== value) {\n this.cursorStart = cursorStart;\n this.cursorEnd = cursorEnd;\n }\n\n this.value = sanitized;\n\n if (this.textarea) {\n this.inputElement.value = this.value;\n }\n\n if (this.counterElement) {\n this.counterElement.text = value;\n }\n }\n\n private sanitizeGSM(text: string): string {\n return this.gsm ? sanitizeUnintendedUnicode(text) : text;\n }\n\n private handleChange(update: any): void {\n if (this.disabled) {\n return;\n }\n this.updateValue(update.target.value);\n this.fireEvent('change');\n }\n\n private handleContainerClick(): void {\n if (this.disabled) {\n return;\n }\n if (this.inputElement) {\n this.inputElement.click();\n }\n }\n\n private handleContainerFocus(): void {\n if (this.disabled) {\n return;\n }\n if (this.inputElement) {\n this.inputElement.focus();\n }\n }\n\n private handleInput(update: any): void {\n if (this.disabled) {\n return;\n }\n\n this.updateValue(update.target.value);\n this.fireEvent('input');\n }\n\n /** we just return the value since it should be a string */\n public serializeValue(value: any): string {\n return value;\n }\n\n public getParentModax(): Modax {\n let parent = this as HTMLElement;\n\n while (parent) {\n if (parent.parentElement) {\n parent = parent.parentElement;\n } else {\n parent = (parent as any).getRootNode().host;\n }\n\n if (!parent) {\n return null;\n }\n\n if (parent.tagName == 'TEMBA-MODAX') {\n return parent as Modax;\n }\n }\n }\n\n public getParentForm(): HTMLFormElement {\n let parent = this as HTMLElement;\n\n while (parent) {\n if (parent.parentElement) {\n parent = parent.parentElement;\n } else {\n parent = (parent as any).getRootNode().host;\n }\n\n if (!parent) {\n return null;\n }\n\n if (parent.tagName === 'FORM') {\n return parent as HTMLFormElement;\n }\n }\n }\n\n public click(): void {\n super.click();\n this.handleContainerClick();\n }\n\n public focus(): void {\n super.focus();\n this.handleContainerFocus();\n }\n\n // TODO make this a formelement and have contactsearch set the root\n public render(): TemplateResult {\n const containerStyle = {\n height: `${this.textarea ? '100%' : 'auto'}`\n };\n\n const clear =\n this.clearable && this.inputElement && this.inputElement.value\n ? html`<temba-icon\n name=\"x\"\n class=\"clear-icon\"\n @click=${this.handleClear}\n />`\n : null;\n\n let input = html`\n <input\n autofocus\n class=\"textinput\"\n autocomplete=\"off\"\n name=${this.name}\n type=\"${this.password || this.type === InputType.Password\n ? 'password'\n : this.type}\"\n maxlength=\"${ifDefined(this.maxlength)}\"\n @change=${this.handleChange}\n @input=${this.handleInput}\n @blur=${this.blur}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const input = this;\n\n if (this.submitOnEnter) {\n const parentModax = input.getParentModax();\n const parentForm = !parentModax ? input.getParentForm() : null;\n\n // if we don't have something to submit then bail\n if (!parentModax && !parentForm) {\n return false;\n }\n\n // don't submit disabled forms on enter\n if (parentModax && parentModax.disabled) {\n return false;\n }\n\n input.blur();\n\n // look for a form to submit\n window.setTimeout(function () {\n // first, look for a modax that contains us\n const modax = input.getParentModax();\n if (modax) {\n input.blur();\n\n modax.submit();\n } else {\n // otherwise, just look for a vanilla submit button\n const form = input.getParentForm();\n\n if (form) {\n const submitButton = form.querySelector(\n \"input[type='submit']\"\n ) as HTMLInputElement;\n if (submitButton) {\n submitButton.click();\n } else {\n form.submit();\n }\n }\n }\n }, 10);\n // this is needed for firefox, would be nice to\n // find a way to do this with a callback instead\n }\n }\n }}\n placeholder=${this.placeholder}\n .value=${this.value}\n .disabled=${this.disabled}\n />\n `;\n\n if (this.textarea) {\n input = html`\n <textarea\n class=\"textinput\"\n name=${this.name}\n maxlength=\"${ifDefined(this.maxlength)}\"\n placeholder=${this.placeholder}\n @change=${this.handleChange}\n @input=${this.handleInput}\n @blur=${this.blur}\n .value=${this.value}\n .disabled=${this.disabled}\n ></textarea>\n `;\n\n if (this.autogrow) {\n input = html` <div class=\"grow-wrap\">\n <div></div>\n ${input}\n </div>`;\n }\n }\n\n return html`\n <temba-field\n name=${this.name}\n .label=\"${this.label}\"\n .helpText=\"${this.helpText}\"\n .errors=${this.errors}\n .widgetOnly=${this.widgetOnly}\n .hideLabel=${this.hideLabel}\n .disabled=${this.disabled}\n >\n <div\n class=\"input-container\"\n style=${styleMap(containerStyle)}\n @click=${this.handleContainerClick}\n >\n <slot name=\"prefix\"></slot>\n\n ${input} ${clear}\n <slot name=\"type\" class=\"type-icon\"\n >${this.type === InputType.Number\n ? html`<temba-icon name=\"number\"></temba-icon>`\n : null}</slot\n >\n <slot></slot>\n </div>\n </temba-field>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../../src/form/TextInput.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit-html/directives/if-defined.js';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { FormElement } from './FormElement';\nimport { Modax } from '../layout/Modax';\nimport { sanitizeUnintendedUnicode } from '../utils';\nimport { CharCount } from '../display/CharCount';\n\nexport enum InputType {\n Text = 'text',\n Password = 'password',\n Number = 'number'\n}\n\nexport class TextInput extends FormElement {\n static get styles() {\n return css`\n .input-container {\n border-radius: var(--curvature-widget);\n cursor: var(--input-cursor);\n background: var(--color-widget-bg);\n border: 1px solid var(--color-widget-border);\n transition: all ease-in-out var(--transition-speed);\n display: flex;\n flex-direction: row;\n align-items: stretch;\n box-shadow: var(--widget-box-shadow);\n caret-color: var(--input-caret);\n }\n\n .clear-icon {\n --icon-color: var(--color-text-dark-secondary);\n cursor: pointer;\n margin: auto;\n padding-right: 10px;\n line-height: 1;\n }\n\n .clear-icon:hover {\n --icon-color: var(--color-text-dark);\n }\n\n .hidden {\n visibility: hidden;\n position: absolute;\n }\n\n .input-container:focus-within {\n border-color: var(--color-focus);\n background: var(--color-widget-bg-focused);\n box-shadow: var(--widget-box-shadow-focused);\n position: relative;\n }\n\n .input-container:hover {\n }\n\n textarea {\n height: var(--textarea-height);\n min-height: var(--textarea-min-height, var(--textarea-height));\n transition: height var(--transition-speed) ease-in-out;\n unicode-bidi: var(--unicode-bidi, normal);\n }\n\n .textinput:focus {\n }\n\n .textinput {\n padding: var(--temba-textinput-padding);\n border: none;\n flex: 1;\n margin: 0;\n background: transparent;\n color: var(--color-widget-text);\n font-family: var(--font-family);\n font-size: var(--temba-textinput-font-size);\n line-height: normal;\n cursor: var(--input-cursor);\n resize: none;\n width: 100%;\n }\n\n .textinput:focus {\n outline: none;\n box-shadow: none;\n cursor: text;\n color: var(--color-widget-text-focused, var(--color-widget-text));\n }\n\n .textinput::placeholder {\n color: var(--color-placeholder);\n }\n\n .grow-wrap {\n display: flex;\n align-items: stretch;\n width: 100%;\n margin-bottom: 1em;\n }\n\n .grow-wrap > div {\n border: 0px solid green;\n white-space: pre-wrap;\n width: 100%;\n padding: var(--temba-textinput-padding);\n flex: 1;\n margin: 0;\n background: none;\n color: var(--color-widget-text);\n font-family: var(--font-family);\n font-size: var(--temba-textinput-font-size);\n line-height: normal;\n cursor: text;\n resize: none;\n width: 100%;\n word-break: break-word;\n opacity: 0;\n z-index: -1;\n max-height: var(--temba-textinput-max-height, 30em);\n }\n\n .grow-wrap textarea {\n margin-left: -100%;\n height: 100%;\n flex-grow: 1;\n }\n\n input[type='number'] {\n appearance: none;\n }\n\n input[type='number']::-webkit-inner-spin-button {\n display: none;\n }\n\n .type-icon {\n color: #e3e3e3;\n }\n `;\n }\n\n @property({ type: Boolean })\n textarea: boolean;\n\n @property({ type: String })\n placeholder = '';\n\n @property({ type: Boolean })\n password: boolean;\n\n @property({ type: Number })\n maxlength: number;\n\n @property({ type: Object })\n inputElement: HTMLInputElement;\n\n @property({ type: Boolean })\n clearable: boolean;\n\n @property({ type: Boolean })\n gsm: boolean;\n\n @property({ type: String })\n counter: string;\n\n // if we are still loading\n @property({ type: Boolean })\n loading = true;\n\n @property({ type: Boolean })\n submitOnEnter = true;\n\n @property()\n onBlur: any;\n\n @property({ type: Boolean })\n autogrow = false;\n\n @property({ type: String })\n type = InputType.Text;\n\n counterElement: CharCount = null;\n cursorStart = -1;\n cursorEnd = -1;\n\n public constructor() {\n super();\n }\n\n public firstUpdated(changes: Map<string, any>) {\n super.firstUpdated(changes);\n\n this.inputElement = this.shadowRoot.querySelector('.textinput');\n\n if (changes.has('counter') && this.counter && this.counter.trim()) {\n let root = this.getParentModax() as any;\n if (root) {\n root = root.shadowRoot;\n }\n if (!root) {\n root = document;\n }\n this.counterElement = root.querySelector(this.counter);\n if (this.counterElement) {\n this.counterElement.text = this.value;\n }\n }\n }\n\n private updateAutogrowSize(): void {\n if (this.textarea && this.autogrow) {\n const autogrow = this.shadowRoot.querySelector(\n '.grow-wrap > div'\n ) as HTMLDivElement;\n if (autogrow) {\n autogrow.innerText = this.value + String.fromCharCode(10);\n }\n }\n }\n\n public updated(changes: Map<string, any>) {\n super.updated(changes);\n\n if (changes.has('value')) {\n if (changes.get('value') !== undefined) {\n this.fireEvent('change');\n }\n\n this.updateAutogrowSize();\n\n if (this.cursorStart > -1 && this.cursorEnd > -1) {\n this.inputElement.setSelectionRange(this.cursorStart, this.cursorEnd);\n this.cursorStart = -1;\n this.cursorEnd = -1;\n }\n }\n }\n\n public getDisplayValue() {\n return this.inputElement.value;\n }\n\n private handleClear(event: any): void {\n event.stopPropagation();\n event.preventDefault();\n this.value = null;\n }\n\n public getTextInput(): TextInput {\n return this;\n }\n\n public updateValue(value: string): void {\n const cursorStart = this.inputElement.selectionStart;\n const cursorEnd = this.inputElement.selectionEnd;\n const sanitized = this.sanitizeGSM(value);\n\n if (sanitized !== value) {\n this.cursorStart = cursorStart;\n this.cursorEnd = cursorEnd;\n }\n\n this.value = sanitized;\n\n if (this.textarea) {\n this.inputElement.value = this.value;\n }\n\n if (this.counterElement) {\n this.counterElement.text = value;\n }\n }\n\n private sanitizeGSM(text: string): string {\n return this.gsm ? sanitizeUnintendedUnicode(text) : text;\n }\n\n private handleChange(update: any): void {\n if (this.disabled) {\n return;\n }\n this.updateValue(update.target.value);\n this.fireEvent('change');\n }\n\n private handleContainerClick(): void {\n if (this.disabled) {\n return;\n }\n if (this.inputElement) {\n this.inputElement.click();\n }\n }\n\n private handleContainerFocus(): void {\n if (this.disabled) {\n return;\n }\n if (this.inputElement) {\n this.inputElement.focus();\n }\n }\n\n private handleInput(update: any): void {\n if (this.disabled) {\n return;\n }\n\n this.updateValue(update.target.value);\n this.fireEvent('input');\n }\n\n /** we just return the value since it should be a string */\n public serializeValue(value: any): string {\n return value;\n }\n\n public getParentModax(): Modax {\n let parent = this as HTMLElement;\n\n while (parent) {\n if (parent.parentElement) {\n parent = parent.parentElement;\n } else {\n parent = (parent as any).getRootNode().host;\n }\n\n if (!parent) {\n return null;\n }\n\n if (parent.tagName == 'TEMBA-MODAX') {\n return parent as Modax;\n }\n }\n }\n\n public getParentForm(): HTMLFormElement {\n let parent = this as HTMLElement;\n\n while (parent) {\n if (parent.parentElement) {\n parent = parent.parentElement;\n } else {\n parent = (parent as any).getRootNode().host;\n }\n\n if (!parent) {\n return null;\n }\n\n if (parent.tagName === 'FORM') {\n return parent as HTMLFormElement;\n }\n }\n }\n\n public click(): void {\n super.click();\n this.handleContainerClick();\n }\n\n public focus(): void {\n super.focus();\n this.handleContainerFocus();\n }\n\n // TODO make this a formelement and have contactsearch set the root\n public render(): TemplateResult {\n const containerStyle = {\n height: `${this.textarea ? '100%' : 'auto'}`\n };\n\n const clear =\n this.clearable && this.inputElement && this.inputElement.value\n ? html`<temba-icon\n name=\"x\"\n class=\"clear-icon\"\n @click=${this.handleClear}\n />`\n : null;\n\n let input = html`\n <input\n autofocus\n class=\"textinput\"\n autocomplete=\"off\"\n name=${this.name}\n type=\"${this.password || this.type === InputType.Password\n ? 'password'\n : this.type}\"\n maxlength=\"${ifDefined(this.maxlength)}\"\n @change=${this.handleChange}\n @input=${this.handleInput}\n @blur=${this.blur}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const input = this;\n\n if (this.submitOnEnter) {\n const parentModax = input.getParentModax();\n const parentForm = !parentModax ? input.getParentForm() : null;\n\n // if we don't have something to submit then bail\n if (!parentModax && !parentForm) {\n return false;\n }\n\n // don't submit disabled forms on enter\n if (parentModax && parentModax.disabled) {\n return false;\n }\n\n input.blur();\n\n // look for a form to submit\n window.setTimeout(function () {\n // first, look for a modax that contains us\n const modax = input.getParentModax();\n if (modax) {\n input.blur();\n\n modax.submit();\n } else {\n // otherwise, just look for a vanilla submit button\n const form = input.getParentForm();\n\n if (form) {\n const submitButton = form.querySelector(\n \"input[type='submit']\"\n ) as HTMLInputElement;\n if (submitButton) {\n submitButton.click();\n } else {\n form.submit();\n }\n }\n }\n }, 10);\n // this is needed for firefox, would be nice to\n // find a way to do this with a callback instead\n }\n }\n }}\n placeholder=${this.placeholder}\n .value=${this.value}\n .disabled=${this.disabled}\n />\n `;\n\n if (this.textarea) {\n input = html`\n <textarea\n class=\"textinput\"\n name=${this.name}\n maxlength=\"${ifDefined(this.maxlength)}\"\n placeholder=${this.placeholder}\n @change=${this.handleChange}\n @input=${this.handleInput}\n @blur=${this.blur}\n .value=${this.value}\n .disabled=${this.disabled}\n ></textarea>\n `;\n\n if (this.autogrow) {\n input = html` <div class=\"grow-wrap\">\n <div></div>\n ${input}\n </div>`;\n }\n }\n\n return html`\n <temba-field\n name=${this.name}\n .label=\"${this.label}\"\n .helpText=\"${this.helpText}\"\n .errors=${this.errors}\n .widgetOnly=${this.widgetOnly}\n .hideLabel=${this.hideLabel}\n .disabled=${this.disabled}\n >\n <div\n class=\"input-container\"\n style=${styleMap(containerStyle)}\n @click=${this.handleContainerClick}\n >\n <slot name=\"prefix\"></slot>\n\n ${input} ${clear}\n <slot name=\"type\" class=\"type-icon\"\n >${this.type === InputType.Number\n ? html`<temba-icon name=\"number\"></temba-icon>`\n : null}</slot\n >\n <slot></slot>\n </div>\n </temba-field>\n `;\n }\n}\n"]}
@@ -57,7 +57,7 @@ export class Select extends FormElement {
57
57
  background: rgba(100, 100, 100, 0.05);
58
58
  }
59
59
 
60
- . selected-item.multi .remove-item {
60
+ .selected-item.multi .remove-item {
61
61
  display: none;
62
62
  }
63
63
 
@@ -198,6 +198,7 @@ export class Select extends FormElement {
198
198
 
199
199
  .multi temba-sortable-list {
200
200
  margin: 0 !important;
201
+ flex-grow: 1;
201
202
  }
202
203
 
203
204
  input {
@@ -231,6 +232,12 @@ export class Select extends FormElement {
231
232
 
232
233
  .multi .input-wrapper {
233
234
  margin-left: 2px !important;
235
+ margin-right: 2px !important;
236
+ margin-top: 2px;
237
+ margin-bottom: 2px;
238
+ flex-shrink: 0;
239
+ min-width: 100px;
240
+ align-self: center;
234
241
  }
235
242
 
236
243
  .input-wrapper:focus-within .placeholder {
@@ -266,11 +273,6 @@ export class Select extends FormElement {
266
273
  box-shadow: none !important;
267
274
  }
268
275
 
269
- .multi .input-wrapper {
270
- flex-shrink: 0;
271
- min-width: 100px;
272
- }
273
-
274
276
  .input-wrapper .searchbox {
275
277
  }
276
278
 
@@ -286,6 +288,17 @@ export class Select extends FormElement {
286
288
  margin-left: 6px;
287
289
  }
288
290
 
291
+ .empty .placeholder {
292
+ display: block;
293
+ }
294
+
295
+ .multi .placeholder {
296
+ display: block;
297
+ margin: 2px 2px;
298
+ padding: 2px 8px;
299
+ align-self: center;
300
+ }
301
+
289
302
  .footer {
290
303
  padding: 5px 10px;
291
304
  background: var(--color-primary-light);
@@ -296,10 +309,10 @@ export class Select extends FormElement {
296
309
  }
297
310
 
298
311
  .small {
299
- --temba-select-selected-padding: 7px;
300
- --temba-select-selected-line-height: 13px;
301
- --temba-select-selected-font-size: 12px;
302
- --search-input-height: 7px !important;
312
+ --temba-select-selected-padding: 6px;
313
+ --temba-select-selected-line-height: 12px;
314
+ --temba-select-selected-font-size: 14px;
315
+ --temba-select-min-height: 2.28em;
303
316
  }
304
317
 
305
318
  .info-text {
@@ -331,6 +344,14 @@ export class Select extends FormElement {
331
344
  }
332
345
  `;
333
346
  }
347
+ // Override the setter to ensure values is always an array
348
+ set values(newValues) {
349
+ this._values = Array.isArray(newValues) ? newValues : [];
350
+ this.requestUpdate('values');
351
+ }
352
+ get values() {
353
+ return this._values || [];
354
+ }
334
355
  constructor() {
335
356
  super();
336
357
  this.hiddenInputs = [];
@@ -361,8 +382,10 @@ export class Select extends FormElement {
361
382
  this.emails = false;
362
383
  this.flavor = 'default';
363
384
  this.infoText = '';
364
- this.values = [];
365
- this.getName = (option) => option[this.nameKey || 'name'];
385
+ this._values = [];
386
+ this.getName = (option) => {
387
+ return option[this.nameKey || 'name'];
388
+ };
366
389
  this.isMatch = this.isMatchDefault;
367
390
  this.getValue = (option) => option[this.valueKey || 'value'] || option.id;
368
391
  this.sortFunction = null;
@@ -377,14 +400,16 @@ export class Select extends FormElement {
377
400
  this.alphaSort = (a, b) => {
378
401
  // by default, all endpoint values are sorted by name
379
402
  if (this.endpoint) {
380
- return this.getName(a).localeCompare(this.getName(b));
403
+ return this.getNameInternal(a).localeCompare(this.getNameInternal(b));
381
404
  }
382
405
  return 0;
383
406
  };
384
407
  this.next = null;
385
408
  this.lruCache = lru(20, 60000);
386
409
  this.getNameInternal = (option) => {
387
- return this.getName(option);
410
+ return this.getName
411
+ ? this.getName(option)
412
+ : option[this.nameKey || 'name'] || '';
388
413
  };
389
414
  this.renderOptionDefault = this.renderOptionDefault.bind(this);
390
415
  this.renderSelectedItemDefault = this.renderSelectedItemDefault.bind(this);
@@ -396,7 +421,7 @@ export class Select extends FormElement {
396
421
  return options;
397
422
  }
398
423
  isMatchDefault(option, q) {
399
- const name = this.getName(option) || '';
424
+ const name = this.getNameInternal(option) || '';
400
425
  return name.toLowerCase().indexOf(q) > -1;
401
426
  }
402
427
  handleSlotChange() {
@@ -1164,7 +1189,7 @@ export class Select extends FormElement {
1164
1189
  name="${icon}"
1165
1190
  style="margin-right:0.5em;"
1166
1191
  ></temba-icon>`
1167
- : null}<span>${this.getName(option)}</span>
1192
+ : null}<span>${this.getNameInternal(option)}</span>
1168
1193
  </div>
1169
1194
  `;
1170
1195
  }
@@ -1284,9 +1309,11 @@ export class Select extends FormElement {
1284
1309
  }
1285
1310
  render() {
1286
1311
  const placeholder = this.values.length === 0 ? this.placeholder : '';
1287
- const placeholderDiv = html `
1288
- <div class="placeholder">${placeholder}</div>
1289
- `;
1312
+ // Single unified placeholder - shows when empty and (not focused OR not searchable)
1313
+ const shouldShowPlaceholder = this.values.length === 0 && (!this.focused || !this.searchable);
1314
+ const placeholderElement = shouldShowPlaceholder
1315
+ ? html `<div class="placeholder">${placeholder}</div>`
1316
+ : null;
1290
1317
  const clear = this.clearable && this.values.length > 0 && !this.isMultiMode
1291
1318
  ? html `<temba-icon
1292
1319
  name="${Icon.select_clear}"
@@ -1326,10 +1353,9 @@ export class Select extends FormElement {
1326
1353
  .value=${this.input}
1327
1354
  />
1328
1355
  <div id="anchor" style=${styleMap(anchorStyles)}></div>
1329
- ${placeholderDiv}
1330
1356
  </div>
1331
1357
  `
1332
- : placeholderDiv;
1358
+ : null;
1333
1359
  const items = html `${!this.isMultiMode && !this.resolving ? input : null}
1334
1360
  ${this.isMultiMode && this.values.length > 1
1335
1361
  ? html `
@@ -1400,9 +1426,10 @@ export class Select extends FormElement {
1400
1426
  ${this.renderSelectedItem(selected)}
1401
1427
  </div>
1402
1428
  `)}
1429
+ ${this.searchable && this.focused ? input : null}
1403
1430
  </temba-sortable-list>
1404
1431
  `
1405
- : this.values.map((selected, index) => html `
1432
+ : html `${this.values.map((selected, index) => html `
1406
1433
  <div
1407
1434
  class="selected-item ${index === this.selectedIndex
1408
1435
  ? 'focused'
@@ -1449,7 +1476,8 @@ export class Select extends FormElement {
1449
1476
  : null}
1450
1477
  </div>
1451
1478
  `)}
1452
- ${this.isMultiMode ? input : null}`;
1479
+ ${this.isMultiMode && this.searchable && this.focused ? input : null}
1480
+ ${placeholderElement}`}`;
1453
1481
  return html `
1454
1482
 
1455
1483
  <temba-field
@@ -1670,7 +1698,7 @@ __decorate([
1670
1698
  ], Select.prototype, "infoText", void 0);
1671
1699
  __decorate([
1672
1700
  property({ type: Array })
1673
- ], Select.prototype, "values", void 0);
1701
+ ], Select.prototype, "values", null);
1674
1702
  __decorate([
1675
1703
  property({ type: Object })
1676
1704
  ], Select.prototype, "selection", void 0);