@nyaruka/temba-components 0.108.7 → 0.109.1

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 (120) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/static/svg/index.svg +1 -1
  3. package/dist/temba-components.js +602 -455
  4. package/dist/temba-components.js.map +1 -1
  5. package/out-tsc/src/charcount/CharCount.js +4 -5
  6. package/out-tsc/src/charcount/CharCount.js.map +1 -1
  7. package/out-tsc/src/completion/Completion.js +27 -16
  8. package/out-tsc/src/completion/Completion.js.map +1 -1
  9. package/out-tsc/src/compose/Compose.js +259 -95
  10. package/out-tsc/src/compose/Compose.js.map +1 -1
  11. package/out-tsc/src/contacts/ContactChat.js +18 -16
  12. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  13. package/out-tsc/src/contacts/ContactTickets.js +1 -1
  14. package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
  15. package/out-tsc/src/interfaces.js.map +1 -1
  16. package/out-tsc/src/list/ShortcutList.js +125 -0
  17. package/out-tsc/src/list/ShortcutList.js.map +1 -0
  18. package/out-tsc/src/list/TembaList.js +8 -5
  19. package/out-tsc/src/list/TembaList.js.map +1 -1
  20. package/out-tsc/src/options/Options.js +46 -35
  21. package/out-tsc/src/options/Options.js.map +1 -1
  22. package/out-tsc/src/select/Select.js +1 -1
  23. package/out-tsc/src/select/Select.js.map +1 -1
  24. package/out-tsc/src/store/Store.js +18 -3
  25. package/out-tsc/src/store/Store.js.map +1 -1
  26. package/out-tsc/src/tabpane/Tab.js +2 -0
  27. package/out-tsc/src/tabpane/Tab.js.map +1 -1
  28. package/out-tsc/src/tabpane/TabPane.js +27 -5
  29. package/out-tsc/src/tabpane/TabPane.js.map +1 -1
  30. package/out-tsc/src/textinput/TextInput.js +7 -2
  31. package/out-tsc/src/textinput/TextInput.js.map +1 -1
  32. package/out-tsc/src/utils/index.js.map +1 -1
  33. package/out-tsc/src/vectoricon/index.js +3 -3
  34. package/out-tsc/src/vectoricon/index.js.map +1 -1
  35. package/out-tsc/temba-modules.js +2 -0
  36. package/out-tsc/temba-modules.js.map +1 -1
  37. package/out-tsc/test/temba-compose.test.js +26 -18
  38. package/out-tsc/test/temba-compose.test.js.map +1 -1
  39. package/out-tsc/test/temba-contact-chat.test.js +27 -18
  40. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  41. package/package.json +1 -1
  42. package/screenshots/truth/compose/attachments-and-send-button.png +0 -0
  43. package/screenshots/truth/compose/attachments-no-send-button.png +0 -0
  44. package/screenshots/truth/compose/attachments-with-all-files-and-click-send.png +0 -0
  45. package/screenshots/truth/compose/attachments-with-all-files.png +0 -0
  46. package/screenshots/truth/compose/attachments-with-failure-files.png +0 -0
  47. package/screenshots/truth/compose/attachments-with-success-files-and-click-send.png +0 -0
  48. package/screenshots/truth/compose/attachments-with-success-files.png +0 -0
  49. package/screenshots/truth/compose/chatbox-attachments-counter-and-send-button.png +0 -0
  50. package/screenshots/truth/compose/chatbox-attachments-counter-no-send-button.png +0 -0
  51. package/screenshots/truth/compose/chatbox-attachments-no-counter-and-send-button.png +0 -0
  52. package/screenshots/truth/compose/chatbox-attachments-no-counter-no-send-button.png +0 -0
  53. package/screenshots/truth/compose/chatbox-counter-and-send-button.png +0 -0
  54. package/screenshots/truth/compose/chatbox-counter-no-send-button.png +0 -0
  55. package/screenshots/truth/compose/chatbox-no-counter-and-send-button.png +0 -0
  56. package/screenshots/truth/compose/chatbox-no-counter-no-send-button.png +0 -0
  57. package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files-and-click-send.png +0 -0
  58. package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files.png +0 -0
  59. package/screenshots/truth/compose/chatbox-no-text-attachments-with-failure-files.png +0 -0
  60. package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files-and-click-send.png +0 -0
  61. package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files.png +0 -0
  62. package/screenshots/truth/compose/chatbox-with-text-and-click-send.png +0 -0
  63. package/screenshots/truth/compose/chatbox-with-text-and-hit-enter.png +0 -0
  64. package/screenshots/truth/compose/chatbox-with-text-and-spaces.png +0 -0
  65. package/screenshots/truth/compose/chatbox-with-text-and-url.png +0 -0
  66. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-click-send.png +0 -0
  67. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-hit-enter.png +0 -0
  68. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files.png +0 -0
  69. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-click-send.png +0 -0
  70. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-hit-enter.png +0 -0
  71. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files.png +0 -0
  72. package/screenshots/truth/compose/chatbox-with-text-attachments-with-failure-files.png +0 -0
  73. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-click-send.png +0 -0
  74. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-hit-enter.png +0 -0
  75. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files.png +0 -0
  76. package/screenshots/truth/compose/chatbox-with-text-no-spaces.png +0 -0
  77. package/screenshots/truth/compose/chatbox-with-text.png +0 -0
  78. package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
  79. package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
  80. package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
  81. package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
  82. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text-and-attachments.png +0 -0
  83. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
  84. package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
  85. package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
  86. package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
  87. package/screenshots/truth/contacts/contact-active-default.png +0 -0
  88. package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
  89. package/screenshots/truth/counter/summary.png +0 -0
  90. package/screenshots/truth/counter/text.png +0 -0
  91. package/screenshots/truth/counter/unicode-variables.png +0 -0
  92. package/screenshots/truth/counter/unicode.png +0 -0
  93. package/screenshots/truth/counter/variable.png +0 -0
  94. package/src/charcount/CharCount.ts +4 -5
  95. package/src/completion/Completion.ts +33 -19
  96. package/src/compose/Compose.ts +289 -96
  97. package/src/contacts/ContactChat.ts +18 -16
  98. package/src/contacts/ContactTickets.ts +1 -1
  99. package/src/interfaces.ts +7 -0
  100. package/src/list/ShortcutList.ts +137 -0
  101. package/src/list/TembaList.ts +9 -6
  102. package/src/options/Options.ts +53 -44
  103. package/src/select/Select.ts +1 -1
  104. package/src/store/Store.ts +23 -4
  105. package/src/tabpane/Tab.ts +2 -0
  106. package/src/tabpane/TabPane.ts +28 -5
  107. package/src/textinput/TextInput.ts +9 -3
  108. package/src/utils/index.ts +8 -2
  109. package/src/vectoricon/index.ts +3 -3
  110. package/static/svg/index.svg +1 -1
  111. package/static/svg/work/traced/folder-shield.svg +1 -0
  112. package/static/svg/work/traced/zap-fast.svg +1 -0
  113. package/static/svg/work/used/folder-shield.svg +3 -0
  114. package/static/svg/work/used/zap-fast.svg +3 -0
  115. package/temba-modules.ts +2 -0
  116. package/test/temba-compose.test.ts +28 -35
  117. package/test/temba-contact-chat.test.ts +28 -37
  118. package/test-assets/store/shortcuts.json +14 -0
  119. package/static/svg/work/traced/message-dots-circle.svg +0 -1
  120. package/static/svg/work/used/message-dots-circle.svg +0 -3
@@ -51,15 +51,14 @@ export class CharCount extends RapidElement {
51
51
  overflow: hidden;
52
52
  opacity: 0.3;
53
53
  transform: scale(0.7);
54
- box-shadow: var(--shadow);
54
+ box-shadow: var(--dropdown-shadow);
55
55
  transition: transform cubic-bezier(0.71, 0.18, 0.61, 1.33)
56
56
  var(--transition-speed);
57
57
  visibility: hidden;
58
- margin-top: var(--temba-charcount-summary-margin-top);
59
- right: var(--temba-charcount-summary-right);
60
- bottom: var(--temba-charcount-summary-bottom);
61
58
  text-align: left;
62
- position: var(--temba-charcount-summary-position);
59
+ position: fixed;
60
+ margin-left: -190px;
61
+ margin-top: 20px;
63
62
  z-index: 1000;
64
63
  }
65
64
 
@@ -1 +1 @@
1
- {"version":3,"file":"CharCount.js","sourceRoot":"","sources":["../../../src/charcount/CharCount.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { RapidElement } from '../RapidElement';\nimport { splitSMS } from '../sms';\nimport { getExtendedCharacters } from './helpers';\nimport { property } from 'lit/decorators.js';\n\nexport class CharCount extends RapidElement {\n static get styles() {\n return css`\n :host {\n overflow: auto;\n }\n\n :host::after {\n content: '';\n clear: both;\n display: table;\n }\n\n .counter {\n float: right;\n text-align: right;\n position: relative;\n }\n\n .extended {\n font-size: 14px;\n display: flex;\n margin-top: 4px;\n }\n\n .extended-char {\n border: 1px solid #e6e6e6;\n border-radius: var(--curvature-widget);\n padding: 4px;\n text-align: center;\n line-height: 20px;\n margin-right: 4px;\n }\n\n .summary {\n width: 180px;\n padding: 8px 12px;\n font-size: 12px;\n background: white;\n border-radius: var(--curvature-widget);\n overflow: hidden;\n opacity: 0.3;\n transform: scale(0.7);\n box-shadow: var(--shadow);\n transition: transform cubic-bezier(0.71, 0.18, 0.61, 1.33)\n var(--transition-speed);\n visibility: hidden;\n margin-top: var(--temba-charcount-summary-margin-top);\n right: var(--temba-charcount-summary-right);\n bottom: var(--temba-charcount-summary-bottom);\n text-align: left;\n position: var(--temba-charcount-summary-position);\n z-index: 1000;\n }\n\n .fine-print {\n margin-top: 8px;\n margin-left: -12px;\n margin-right: -12px;\n margin-bottom: -8px;\n padding: 8px 12px;\n color: #999;\n background: #f5f5f5;\n font-size: 10px;\n }\n\n .extended-warning {\n margin-top: 8px;\n }\n\n .note {\n font-weight: 600;\n display: inline-block;\n margin-right: 2px;\n }\n\n .counts {\n cursor: pointer;\n transition: all cubic-bezier(0.71, 0.18, 0.61, 1.33) 200ms;\n transform: scale(0.9);\n display: inline-block;\n padding: 2px 6px;\n border-radius: var(--curvature);\n margin-top: var(--temba-charcount-counts-margin-top);\n }\n\n .segments {\n font-size: 85%;\n display: inline-block;\n }\n\n .attention .counts {\n transform: scale(0.95);\n background: var(--color-overlay-light);\n color: var(--color-overlay-light-text);\n }\n\n .attention .segments {\n font-weight: 600;\n }\n\n .counter:hover .summary {\n opacity: 1;\n transform: scale(1);\n visibility: visible;\n }\n `;\n }\n\n @property({ type: String })\n text: string;\n\n @property({ type: Number })\n count: number;\n\n @property({ type: Number, attribute: false })\n segments: number;\n\n @property({ type: Object, attribute: false })\n extended: string[] = [];\n\n public updated(changes: Map<string, any>) {\n super.updated(changes);\n if (changes.has('text')) {\n this.updateSegments();\n }\n }\n\n private updateSegments() {\n const sms = splitSMS(this.text);\n this.count = sms.length;\n this.segments = sms.parts.length;\n this.extended = getExtendedCharacters(this.text);\n this.count = this.text.length;\n }\n\n public render(): TemplateResult {\n const hasExpressions = this.text && this.text.indexOf('@') > -1;\n\n let segments = html`.`;\n if (this.segments > 1) {\n segments = html`and will use ${hasExpressions ? html`at least` : null}\n <b>${this.segments} messages</b> to send over SMS.`;\n } else {\n segments = html`and will use ${hasExpressions ? html`at least` : null} one\n message to send over SMS.`;\n }\n\n let extended = null;\n if (this.extended.length > 0 && (this.segments > 1 || hasExpressions)) {\n extended = this.extended.map(\n (ch: string) => html`<div class=\"extended-char\">${ch}</div>`\n );\n extended = html`\n <div class=\"extended-warning\">\n Some characters require more space over SMS. To save on fees, consider\n replacing them.\n <div class=\"extended\">${extended}</div>\n </div>\n `;\n }\n\n const summary =\n this.count > 1\n ? html` <div class=\"summary\">\n This message is <b>${this.count} characters</b>\n ${segments} ${extended}\n ${hasExpressions\n ? html`\n <div class=\"fine-print\">\n <div class=\"note\">NOTE</div>\n Using variables may result in more messages when sending\n over SMS than this estimate.\n </div>\n `\n : null}\n </div>`\n : null;\n\n return html`<div class=\"counter${\n extended ? ' attention' : ''\n }\"><div class=\"counts\">${this.count}${\n this.segments > 1 || hasExpressions\n ? html`<div class=\"segments\">\n &nbsp;/&nbsp;${this.segments}${hasExpressions ? html`+` : null}\n <div></div>\n </div>`\n : null\n }</div> ${summary}</div></div>`;\n }\n}\n"]}
1
+ {"version":3,"file":"CharCount.js","sourceRoot":"","sources":["../../../src/charcount/CharCount.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { RapidElement } from '../RapidElement';\nimport { splitSMS } from '../sms';\nimport { getExtendedCharacters } from './helpers';\nimport { property } from 'lit/decorators.js';\n\nexport class CharCount extends RapidElement {\n static get styles() {\n return css`\n :host {\n overflow: auto;\n }\n\n :host::after {\n content: '';\n clear: both;\n display: table;\n }\n\n .counter {\n float: right;\n text-align: right;\n position: relative;\n }\n\n .extended {\n font-size: 14px;\n display: flex;\n margin-top: 4px;\n }\n\n .extended-char {\n border: 1px solid #e6e6e6;\n border-radius: var(--curvature-widget);\n padding: 4px;\n text-align: center;\n line-height: 20px;\n margin-right: 4px;\n }\n\n .summary {\n width: 180px;\n padding: 8px 12px;\n font-size: 12px;\n background: white;\n border-radius: var(--curvature-widget);\n overflow: hidden;\n opacity: 0.3;\n transform: scale(0.7);\n box-shadow: var(--dropdown-shadow);\n transition: transform cubic-bezier(0.71, 0.18, 0.61, 1.33)\n var(--transition-speed);\n visibility: hidden;\n text-align: left;\n position: fixed;\n margin-left: -190px;\n margin-top: 20px;\n z-index: 1000;\n }\n\n .fine-print {\n margin-top: 8px;\n margin-left: -12px;\n margin-right: -12px;\n margin-bottom: -8px;\n padding: 8px 12px;\n color: #999;\n background: #f5f5f5;\n font-size: 10px;\n }\n\n .extended-warning {\n margin-top: 8px;\n }\n\n .note {\n font-weight: 600;\n display: inline-block;\n margin-right: 2px;\n }\n\n .counts {\n cursor: pointer;\n transition: all cubic-bezier(0.71, 0.18, 0.61, 1.33) 200ms;\n transform: scale(0.9);\n display: inline-block;\n padding: 2px 6px;\n border-radius: var(--curvature);\n margin-top: var(--temba-charcount-counts-margin-top);\n }\n\n .segments {\n font-size: 85%;\n display: inline-block;\n }\n\n .attention .counts {\n transform: scale(0.95);\n background: var(--color-overlay-light);\n color: var(--color-overlay-light-text);\n }\n\n .attention .segments {\n font-weight: 600;\n }\n\n .counter:hover .summary {\n opacity: 1;\n transform: scale(1);\n visibility: visible;\n }\n `;\n }\n\n @property({ type: String })\n text: string;\n\n @property({ type: Number })\n count: number;\n\n @property({ type: Number, attribute: false })\n segments: number;\n\n @property({ type: Object, attribute: false })\n extended: string[] = [];\n\n public updated(changes: Map<string, any>) {\n super.updated(changes);\n if (changes.has('text')) {\n this.updateSegments();\n }\n }\n\n private updateSegments() {\n const sms = splitSMS(this.text);\n this.count = sms.length;\n this.segments = sms.parts.length;\n this.extended = getExtendedCharacters(this.text);\n this.count = this.text.length;\n }\n\n public render(): TemplateResult {\n const hasExpressions = this.text && this.text.indexOf('@') > -1;\n\n let segments = html`.`;\n if (this.segments > 1) {\n segments = html`and will use ${hasExpressions ? html`at least` : null}\n <b>${this.segments} messages</b> to send over SMS.`;\n } else {\n segments = html`and will use ${hasExpressions ? html`at least` : null} one\n message to send over SMS.`;\n }\n\n let extended = null;\n if (this.extended.length > 0 && (this.segments > 1 || hasExpressions)) {\n extended = this.extended.map(\n (ch: string) => html`<div class=\"extended-char\">${ch}</div>`\n );\n extended = html`\n <div class=\"extended-warning\">\n Some characters require more space over SMS. To save on fees, consider\n replacing them.\n <div class=\"extended\">${extended}</div>\n </div>\n `;\n }\n\n const summary =\n this.count > 1\n ? html` <div class=\"summary\">\n This message is <b>${this.count} characters</b>\n ${segments} ${extended}\n ${hasExpressions\n ? html`\n <div class=\"fine-print\">\n <div class=\"note\">NOTE</div>\n Using variables may result in more messages when sending\n over SMS than this estimate.\n </div>\n `\n : null}\n </div>`\n : null;\n\n return html`<div class=\"counter${\n extended ? ' attention' : ''\n }\"><div class=\"counts\">${this.count}${\n this.segments > 1 || hasExpressions\n ? html`<div class=\"segments\">\n &nbsp;/&nbsp;${this.segments}${hasExpressions ? html`+` : null}\n <div></div>\n </div>`\n : null\n }</div> ${summary}</div></div>`;\n }\n}\n"]}
@@ -89,31 +89,36 @@ export class Completion extends FormElement {
89
89
  this.appendChild(this.hiddenElement);
90
90
  }
91
91
  handleKeyUp(evt) {
92
- // if we have options, ignore keys that are meant for them
93
- if (this.options && this.options.length > 0) {
94
- if (evt.key === 'ArrowUp' || evt.key === 'ArrowDown') {
95
- return;
96
- }
97
- if (evt.ctrlKey) {
98
- if (evt.key === 'n' || evt.key === 'p') {
92
+ if (this.disableCompletion) {
93
+ // if we have options, ignore keys that are meant for them
94
+ if (this.options && this.options.length > 0) {
95
+ if (evt.key === 'ArrowUp' || evt.key === 'ArrowDown') {
99
96
  return;
100
97
  }
98
+ if (evt.ctrlKey) {
99
+ if (evt.key === 'n' || evt.key === 'p') {
100
+ return;
101
+ }
102
+ }
103
+ if (evt.key === 'Enter' ||
104
+ evt.key === 'Escape' ||
105
+ evt.key === 'Tab' ||
106
+ evt.key.startsWith('Control')) {
107
+ evt.stopPropagation();
108
+ evt.preventDefault();
109
+ return;
110
+ }
111
+ this.executeQuery(evt.currentTarget);
101
112
  }
102
- if (evt.key === 'Enter' ||
103
- evt.key === 'Escape' ||
104
- evt.key === 'Tab' ||
105
- evt.key.startsWith('Control')) {
106
- evt.stopPropagation();
107
- evt.preventDefault();
108
- return;
109
- }
110
- this.executeQuery(evt.currentTarget);
111
113
  }
112
114
  }
113
115
  hasVisibleOptions() {
114
116
  return this.options.length > 0;
115
117
  }
116
118
  executeQuery(ele) {
119
+ if (this.disableCompletion) {
120
+ return;
121
+ }
117
122
  const store = document.querySelector('temba-store');
118
123
  if (!ele.inputElement) {
119
124
  return;
@@ -156,6 +161,9 @@ export class Completion extends FormElement {
156
161
  this.executeQuery(this.textInputElement);
157
162
  }
158
163
  }
164
+ getTextInput() {
165
+ return this.textInputElement;
166
+ }
159
167
  click() {
160
168
  super.click();
161
169
  const input = this.shadowRoot.querySelector('temba-textinput');
@@ -267,6 +275,9 @@ __decorate([
267
275
  __decorate([
268
276
  property({ type: Boolean })
269
277
  ], Completion.prototype, "gsm", void 0);
278
+ __decorate([
279
+ property({ type: Boolean })
280
+ ], Completion.prototype, "disableCompletion", void 0);
270
281
  __decorate([
271
282
  property({ type: String })
272
283
  ], Completion.prototype, "counter", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"Completion.js","sourceRoot":"","sources":["../../../src/completion/Completion.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, css, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit-html/directives/if-defined.js';\nimport { TextInput } from '../textinput/TextInput';\nimport {\n renderCompletionOption,\n updateInputElementWithCompletion,\n executeCompletionQuery\n} from './helpers';\n\nimport { FormElement } from '../FormElement';\nimport { CompletionOption, Position } from '../interfaces';\nimport { Store } from '../store/Store';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { msg } from '@lit/localize';\n\n/**\n * Completion is a text input that handles excellent completion options in a popup\n */\nexport class Completion extends FormElement {\n static get styles() {\n return css`\n :host {\n display: block;\n }\n\n temba-options {\n --widget-box-shadow-focused: 0 0 4px rgba(0, 0, 0, 0.15);\n --color-focus: #e6e6e6;\n }\n\n .comp-container {\n position: relative;\n height: 100%;\n }\n\n #anchor {\n /* background: rgba(132, 40, 158, .1); */\n position: absolute;\n visibility: hidden;\n width: 250px;\n height: 20px;\n }\n\n .fn-marker {\n font-weight: bold;\n font-size: 42px;\n }\n\n .option-slot {\n background: #fff;\n }\n\n .current-fn {\n padding: 10px;\n margin: 5px;\n background: var(--color-primary-light);\n color: rgba(0, 0, 0, 0.5);\n border-radius: var(--curvature-widget);\n font-size: 90%;\n }\n\n .footer {\n padding: 5px 10px;\n background: var(--color-primary-light);\n color: rgba(0, 0, 0, 0.5);\n font-size: 80%;\n border-bottom-left-radius: var(--curvature-widget);\n border-bottom-right-radius: var(--curvature-widget);\n }\n\n code {\n background: rgba(0, 0, 0, 0.1);\n padding: 1px 5px;\n border-radius: var(--curvature);\n }\n `;\n }\n\n @property({ type: Number })\n maxLength: number;\n\n @property({ type: Boolean })\n session: boolean;\n\n @property({ type: Boolean })\n submitOnEnter = false;\n\n @property({ type: Object })\n anchorPosition: Position = { left: 0, top: 0 };\n\n @property({ attribute: false })\n currentFunction: CompletionOption;\n\n @property({ type: String })\n placeholder = '';\n\n @property({ attribute: false })\n textInputElement: TextInput;\n\n @property({ attribute: false })\n anchorElement: HTMLDivElement;\n\n @property({ type: Array })\n options: any[] = [];\n\n @property({ type: String })\n name = '';\n\n @property({ type: String })\n value = '';\n\n @property({ type: Boolean })\n textarea: boolean;\n\n @property({ type: Boolean })\n gsm: boolean;\n\n @property({ type: String })\n counter: string;\n\n @property({ type: Boolean })\n autogrow = false;\n\n private hiddenElement: HTMLInputElement;\n private query: string;\n\n public firstUpdated() {\n this.textInputElement = this.shadowRoot.querySelector(\n 'temba-textinput'\n ) as TextInput;\n this.anchorElement = this.shadowRoot.querySelector('#anchor');\n\n // create our hidden container so it gets included in our host element's form\n this.hiddenElement = document.createElement('input');\n this.hiddenElement.setAttribute('type', 'hidden');\n this.hiddenElement.setAttribute('name', this.getAttribute('name'));\n this.hiddenElement.setAttribute('value', this.getAttribute('value') || '');\n this.appendChild(this.hiddenElement);\n }\n\n private handleKeyUp(evt: KeyboardEvent) {\n // if we have options, ignore keys that are meant for them\n if (this.options && this.options.length > 0) {\n if (evt.key === 'ArrowUp' || evt.key === 'ArrowDown') {\n return;\n }\n\n if (evt.ctrlKey) {\n if (evt.key === 'n' || evt.key === 'p') {\n return;\n }\n }\n\n if (\n evt.key === 'Enter' ||\n evt.key === 'Escape' ||\n evt.key === 'Tab' ||\n evt.key.startsWith('Control')\n ) {\n evt.stopPropagation();\n evt.preventDefault();\n return;\n }\n\n this.executeQuery(evt.currentTarget as TextInput);\n }\n }\n\n public hasVisibleOptions() {\n return this.options.length > 0;\n }\n\n private executeQuery(ele: TextInput) {\n const store: Store = document.querySelector('temba-store');\n if (!ele.inputElement) {\n return;\n }\n const result = executeCompletionQuery(\n ele.inputElement,\n store,\n this.session\n );\n\n this.query = result.query;\n this.options = result.options;\n this.anchorPosition = result.anchorPosition;\n }\n\n private handleClick(evt: MouseEvent) {\n this.executeQuery(evt.currentTarget as TextInput);\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n\n // if our cursor changed, lets make sure our scrollbox is showing it\n if (changedProperties.has('value')) {\n this.hiddenElement.setAttribute('value', this.value);\n }\n }\n\n private handleInput(evt: KeyboardEvent) {\n const ele = evt.currentTarget as TextInput;\n this.executeQuery(ele);\n this.value = ele.inputElement.value;\n this.fireEvent('change');\n }\n\n private handleOptionCanceled() {\n // delay in case we are actively selecting\n window.setTimeout(() => {\n this.options = [];\n this.query = '';\n }, 100);\n }\n\n private handleOptionSelection(evt: CustomEvent) {\n const option = evt.detail.selected as CompletionOption;\n const tabbed = evt.detail.tabbed;\n\n updateInputElementWithCompletion(\n this.query,\n this.textInputElement.inputElement,\n option\n );\n this.query = '';\n this.options = [];\n\n if (tabbed) {\n this.executeQuery(this.textInputElement);\n }\n }\n\n public click() {\n super.click();\n const input = this.shadowRoot.querySelector('temba-textinput') as TextInput;\n if (input) {\n input.click();\n }\n }\n\n public focus() {\n super.focus();\n const input = this.shadowRoot.querySelector('temba-textinput') as TextInput;\n if (input) {\n input.focus();\n }\n }\n\n public render(): TemplateResult {\n const anchorStyles = this.anchorPosition\n ? {\n top: `${this.anchorPosition.top}px`,\n left: `${this.anchorPosition.left}px`\n }\n : {};\n\n const visible = this.options && this.options.length > 0;\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 >\n <div class=\"comp-container\">\n <div id=\"anchor\" style=${styleMap(anchorStyles)}></div>\n <temba-textinput\n name=${this.name}\n placeholder=${this.placeholder}\n gsm=${this.gsm}\n counter=${ifDefined(this.counter)}\n @keyup=${this.handleKeyUp}\n @click=${this.handleClick}\n @input=${this.handleInput}\n @blur=${this.handleOptionCanceled}\n maxlength=\"${ifDefined(this.maxLength)}\"\n .value=${this.value}\n ?autogrow=${this.autogrow}\n ?textarea=${this.textarea}\n ?submitOnEnter=${this.submitOnEnter}\n >\n </temba-textinput>\n <temba-options\n @temba-selection=${this.handleOptionSelection}\n @temba-canceled=${this.handleOptionCanceled}\n .renderOption=${renderCompletionOption}\n .anchorTo=${this.anchorElement}\n .options=${this.options}\n ?visible=${visible}\n >\n ${this.currentFunction\n ? html`\n <div class=\"current-fn\">\n ${renderCompletionOption(this.currentFunction, true)}\n </div>\n `\n : null}\n <div class=\"footer\" style=\"${!visible ? 'display:none' : null}\">\n ${msg('Tab to complete, enter to select')}\n </div>\n </temba-options>\n </div>\n </temba-field>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"Completion.js","sourceRoot":"","sources":["../../../src/completion/Completion.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, css, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit-html/directives/if-defined.js';\nimport { TextInput } from '../textinput/TextInput';\nimport {\n renderCompletionOption,\n updateInputElementWithCompletion,\n executeCompletionQuery\n} from './helpers';\n\nimport { FormElement } from '../FormElement';\nimport { CompletionOption, Position } from '../interfaces';\nimport { Store } from '../store/Store';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { msg } from '@lit/localize';\n\n/**\n * Completion is a text input that handles excellent completion options in a popup\n */\nexport class Completion extends FormElement {\n static get styles() {\n return css`\n :host {\n display: block;\n }\n\n temba-options {\n --widget-box-shadow-focused: 0 0 4px rgba(0, 0, 0, 0.15);\n --color-focus: #e6e6e6;\n }\n\n .comp-container {\n position: relative;\n height: 100%;\n }\n\n #anchor {\n /* background: rgba(132, 40, 158, .1); */\n position: absolute;\n visibility: hidden;\n width: 250px;\n height: 20px;\n }\n\n .fn-marker {\n font-weight: bold;\n font-size: 42px;\n }\n\n .option-slot {\n background: #fff;\n }\n\n .current-fn {\n padding: 10px;\n margin: 5px;\n background: var(--color-primary-light);\n color: rgba(0, 0, 0, 0.5);\n border-radius: var(--curvature-widget);\n font-size: 90%;\n }\n\n .footer {\n padding: 5px 10px;\n background: var(--color-primary-light);\n color: rgba(0, 0, 0, 0.5);\n font-size: 80%;\n border-bottom-left-radius: var(--curvature-widget);\n border-bottom-right-radius: var(--curvature-widget);\n }\n\n code {\n background: rgba(0, 0, 0, 0.1);\n padding: 1px 5px;\n border-radius: var(--curvature);\n }\n `;\n }\n\n @property({ type: Number })\n maxLength: number;\n\n @property({ type: Boolean })\n session: boolean;\n\n @property({ type: Boolean })\n submitOnEnter = false;\n\n @property({ type: Object })\n anchorPosition: Position = { left: 0, top: 0 };\n\n @property({ attribute: false })\n currentFunction: CompletionOption;\n\n @property({ type: String })\n placeholder = '';\n\n @property({ attribute: false })\n textInputElement: TextInput;\n\n @property({ attribute: false })\n anchorElement: HTMLDivElement;\n\n @property({ type: Array })\n options: any[] = [];\n\n @property({ type: String })\n name = '';\n\n @property({ type: String })\n value = '';\n\n @property({ type: Boolean })\n textarea: boolean;\n\n @property({ type: Boolean })\n gsm: boolean;\n\n @property({ type: Boolean })\n disableCompletion: boolean;\n\n @property({ type: String })\n counter: string;\n\n @property({ type: Boolean })\n autogrow = false;\n\n private hiddenElement: HTMLInputElement;\n private query: string;\n\n public firstUpdated() {\n this.textInputElement = this.shadowRoot.querySelector(\n 'temba-textinput'\n ) as TextInput;\n this.anchorElement = this.shadowRoot.querySelector('#anchor');\n\n // create our hidden container so it gets included in our host element's form\n this.hiddenElement = document.createElement('input');\n this.hiddenElement.setAttribute('type', 'hidden');\n this.hiddenElement.setAttribute('name', this.getAttribute('name'));\n this.hiddenElement.setAttribute('value', this.getAttribute('value') || '');\n this.appendChild(this.hiddenElement);\n }\n\n private handleKeyUp(evt: KeyboardEvent) {\n if (this.disableCompletion) {\n // if we have options, ignore keys that are meant for them\n if (this.options && this.options.length > 0) {\n if (evt.key === 'ArrowUp' || evt.key === 'ArrowDown') {\n return;\n }\n\n if (evt.ctrlKey) {\n if (evt.key === 'n' || evt.key === 'p') {\n return;\n }\n }\n\n if (\n evt.key === 'Enter' ||\n evt.key === 'Escape' ||\n evt.key === 'Tab' ||\n evt.key.startsWith('Control')\n ) {\n evt.stopPropagation();\n evt.preventDefault();\n return;\n }\n\n this.executeQuery(evt.currentTarget as TextInput);\n }\n }\n }\n\n public hasVisibleOptions() {\n return this.options.length > 0;\n }\n\n private executeQuery(ele: TextInput) {\n if (this.disableCompletion) {\n return;\n }\n\n const store: Store = document.querySelector('temba-store');\n if (!ele.inputElement) {\n return;\n }\n\n const result = executeCompletionQuery(\n ele.inputElement,\n store,\n this.session\n );\n\n this.query = result.query;\n this.options = result.options;\n this.anchorPosition = result.anchorPosition;\n }\n\n private handleClick(evt: MouseEvent) {\n this.executeQuery(evt.currentTarget as TextInput);\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n\n // if our cursor changed, lets make sure our scrollbox is showing it\n if (changedProperties.has('value')) {\n this.hiddenElement.setAttribute('value', this.value);\n }\n }\n\n private handleInput(evt: KeyboardEvent) {\n const ele = evt.currentTarget as TextInput;\n this.executeQuery(ele);\n this.value = ele.inputElement.value;\n this.fireEvent('change');\n }\n\n private handleOptionCanceled() {\n // delay in case we are actively selecting\n window.setTimeout(() => {\n this.options = [];\n this.query = '';\n }, 100);\n }\n\n private handleOptionSelection(evt: CustomEvent) {\n const option = evt.detail.selected as CompletionOption;\n const tabbed = evt.detail.tabbed;\n\n updateInputElementWithCompletion(\n this.query,\n this.textInputElement.inputElement,\n option\n );\n this.query = '';\n this.options = [];\n\n if (tabbed) {\n this.executeQuery(this.textInputElement);\n }\n }\n\n public getTextInput(): TextInput {\n return this.textInputElement;\n }\n\n public click() {\n super.click();\n const input = this.shadowRoot.querySelector('temba-textinput') as TextInput;\n if (input) {\n input.click();\n }\n }\n\n public focus() {\n super.focus();\n const input = this.shadowRoot.querySelector('temba-textinput') as TextInput;\n if (input) {\n input.focus();\n }\n }\n\n public render(): TemplateResult {\n const anchorStyles = this.anchorPosition\n ? {\n top: `${this.anchorPosition.top}px`,\n left: `${this.anchorPosition.left}px`\n }\n : {};\n\n const visible = this.options && this.options.length > 0;\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 >\n <div class=\"comp-container\">\n <div id=\"anchor\" style=${styleMap(anchorStyles)}></div>\n <temba-textinput\n name=${this.name}\n placeholder=${this.placeholder}\n gsm=${this.gsm}\n counter=${ifDefined(this.counter)}\n @keyup=${this.handleKeyUp}\n @click=${this.handleClick}\n @input=${this.handleInput}\n @blur=${this.handleOptionCanceled}\n maxlength=\"${ifDefined(this.maxLength)}\"\n .value=${this.value}\n ?autogrow=${this.autogrow}\n ?textarea=${this.textarea}\n ?submitOnEnter=${this.submitOnEnter}\n >\n </temba-textinput>\n <temba-options\n @temba-selection=${this.handleOptionSelection}\n @temba-canceled=${this.handleOptionCanceled}\n .renderOption=${renderCompletionOption}\n .anchorTo=${this.anchorElement}\n .options=${this.options}\n ?visible=${visible}\n >\n ${this.currentFunction\n ? html`\n <div class=\"current-fn\">\n ${renderCompletionOption(this.currentFunction, true)}\n </div>\n `\n : null}\n <div class=\"footer\" style=\"${!visible ? 'display:none' : null}\">\n ${msg('Tab to complete, enter to select')}\n </div>\n </temba-options>\n </div>\n </temba-field>\n `;\n }\n}\n"]}