@nyaruka/temba-components 0.25.2 → 0.26.2

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 (186) hide show
  1. package/.github/workflows/build.yml +1 -1
  2. package/CHANGELOG.md +33 -0
  3. package/demo/index.html +60 -1
  4. package/dist/4f80c187.js +4277 -0
  5. package/dist/index.js +3957 -36
  6. package/dist/static/icons/symbol-defs.svg +29 -20
  7. package/dist/sw.js +1 -1
  8. package/dist/sw.js.map +1 -1
  9. package/dist/templates/components-body.html +1 -1
  10. package/dist/templates/components-head.html +1 -1
  11. package/out-tsc/src/FormElement.js +1 -1
  12. package/out-tsc/src/FormElement.js.map +1 -1
  13. package/out-tsc/src/RapidElement.js +1 -1
  14. package/out-tsc/src/RapidElement.js.map +1 -1
  15. package/out-tsc/src/alert/Alert.js +3 -3
  16. package/out-tsc/src/alert/Alert.js.map +1 -1
  17. package/out-tsc/src/aliaseditor/AliasEditor.js +3 -3
  18. package/out-tsc/src/aliaseditor/AliasEditor.js.map +1 -1
  19. package/out-tsc/src/anchor/Anchor.js +2 -1
  20. package/out-tsc/src/anchor/Anchor.js.map +1 -1
  21. package/out-tsc/src/button/Button.js +2 -1
  22. package/out-tsc/src/button/Button.js.map +1 -1
  23. package/out-tsc/src/charcount/CharCount.js +2 -1
  24. package/out-tsc/src/charcount/CharCount.js.map +1 -1
  25. package/out-tsc/src/checkbox/Checkbox.js +3 -1
  26. package/out-tsc/src/checkbox/Checkbox.js.map +1 -1
  27. package/out-tsc/src/completion/Completion.js +2 -1
  28. package/out-tsc/src/completion/Completion.js.map +1 -1
  29. package/out-tsc/src/completion/helpers.js +27 -4
  30. package/out-tsc/src/completion/helpers.js.map +1 -1
  31. package/out-tsc/src/contacts/ContactChat.js +101 -86
  32. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  33. package/out-tsc/src/contacts/ContactDetails.js +2 -1
  34. package/out-tsc/src/contacts/ContactDetails.js.map +1 -1
  35. package/out-tsc/src/contacts/ContactHistory.js +32 -37
  36. package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
  37. package/out-tsc/src/contacts/events.js +62 -76
  38. package/out-tsc/src/contacts/events.js.map +1 -1
  39. package/out-tsc/src/contactsearch/ContactSearch.js +2 -1
  40. package/out-tsc/src/contactsearch/ContactSearch.js.map +1 -1
  41. package/out-tsc/src/datepicker/DatePicker.js +2 -1
  42. package/out-tsc/src/datepicker/DatePicker.js.map +1 -1
  43. package/out-tsc/src/dialog/Dialog.js +2 -2
  44. package/out-tsc/src/dialog/Dialog.js.map +1 -1
  45. package/out-tsc/src/dialog/Modax.js +3 -6
  46. package/out-tsc/src/dialog/Modax.js.map +1 -1
  47. package/out-tsc/src/dropdown/Dropdown.js +133 -0
  48. package/out-tsc/src/dropdown/Dropdown.js.map +1 -0
  49. package/out-tsc/src/formfield/FormField.js +2 -1
  50. package/out-tsc/src/formfield/FormField.js.map +1 -1
  51. package/out-tsc/src/label/Label.js +2 -1
  52. package/out-tsc/src/label/Label.js.map +1 -1
  53. package/out-tsc/src/leafletmap/LeafletMap.js +2 -1
  54. package/out-tsc/src/leafletmap/LeafletMap.js.map +1 -1
  55. package/out-tsc/src/list/TembaList.js +7 -5
  56. package/out-tsc/src/list/TembaList.js.map +1 -1
  57. package/out-tsc/src/list/TembaMenu.js +112 -97
  58. package/out-tsc/src/list/TembaMenu.js.map +1 -1
  59. package/out-tsc/src/list/TicketList.js +2 -1
  60. package/out-tsc/src/list/TicketList.js.map +1 -1
  61. package/out-tsc/src/loading/Loading.js +2 -1
  62. package/out-tsc/src/loading/Loading.js.map +1 -1
  63. package/out-tsc/src/omnibox/Omnibox.js +2 -1
  64. package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
  65. package/out-tsc/src/options/Options.js +3 -2
  66. package/out-tsc/src/options/Options.js.map +1 -1
  67. package/out-tsc/src/remote/Remote.js +2 -1
  68. package/out-tsc/src/remote/Remote.js.map +1 -1
  69. package/out-tsc/src/select/Select.js +8 -10
  70. package/out-tsc/src/select/Select.js.map +1 -1
  71. package/out-tsc/src/shadowless/Shadowless.js +2 -2
  72. package/out-tsc/src/shadowless/Shadowless.js.map +1 -1
  73. package/out-tsc/src/store/Store.js +2 -1
  74. package/out-tsc/src/store/Store.js.map +1 -1
  75. package/out-tsc/src/tabpane/Tab.js +46 -0
  76. package/out-tsc/src/tabpane/Tab.js.map +1 -0
  77. package/out-tsc/src/tabpane/TabPane.js +109 -0
  78. package/out-tsc/src/tabpane/TabPane.js.map +1 -0
  79. package/out-tsc/src/textinput/TextInput.js +3 -2
  80. package/out-tsc/src/textinput/TextInput.js.map +1 -1
  81. package/out-tsc/src/tip/Tip.js +2 -2
  82. package/out-tsc/src/tip/Tip.js.map +1 -1
  83. package/out-tsc/src/vectoricon/VectorIcon.js +18 -6
  84. package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
  85. package/out-tsc/temba-modules.js +6 -0
  86. package/out-tsc/temba-modules.js.map +1 -1
  87. package/out-tsc/test/temba-contact-history.test.js +9 -6
  88. package/out-tsc/test/temba-contact-history.test.js.map +1 -1
  89. package/out-tsc/test/temba-dialog.test.js +3 -3
  90. package/out-tsc/test/temba-dialog.test.js.map +1 -1
  91. package/package.json +10 -9
  92. package/screenshots/truth/alert/error.png +0 -0
  93. package/screenshots/truth/alert/info.png +0 -0
  94. package/screenshots/truth/alert/warning.png +0 -0
  95. package/screenshots/truth/contacts/history-expanded.png +0 -0
  96. package/screenshots/truth/contacts/history.png +0 -0
  97. package/screenshots/truth/counter/summary.png +0 -0
  98. package/screenshots/truth/counter/unicode-variables.png +0 -0
  99. package/screenshots/truth/counter/unicode.png +0 -0
  100. package/screenshots/truth/dialog/focused.png +0 -0
  101. package/screenshots/truth/list/items-selected.png +0 -0
  102. package/screenshots/truth/list/items-updated.png +0 -0
  103. package/screenshots/truth/list/items.png +0 -0
  104. package/screenshots/truth/list/menu-root.png +0 -0
  105. package/screenshots/truth/list/menu-submenu.png +0 -0
  106. package/screenshots/truth/modax/form.png +0 -0
  107. package/screenshots/truth/modax/simple.png +0 -0
  108. package/screenshots/truth/options/block.png +0 -0
  109. package/screenshots/truth/select/embedded.png +0 -0
  110. package/screenshots/truth/select/expression-selected.png +0 -0
  111. package/screenshots/truth/select/expressions.png +0 -0
  112. package/screenshots/truth/select/functions.png +0 -0
  113. package/screenshots/truth/select/local-options.png +0 -0
  114. package/screenshots/truth/select/remote-options.png +0 -0
  115. package/screenshots/truth/select/search-enabled.png +0 -0
  116. package/screenshots/truth/select/search-selected-focus.png +0 -0
  117. package/screenshots/truth/select/search-selected.png +0 -0
  118. package/screenshots/truth/select/search-with-selected.png +0 -0
  119. package/screenshots/truth/select/searching.png +0 -0
  120. package/screenshots/truth/select/selected-multi.png +0 -0
  121. package/screenshots/truth/select/selected-single.png +0 -0
  122. package/screenshots/truth/select/selection-clearable.png +0 -0
  123. package/screenshots/truth/select/with-placeholder.png +0 -0
  124. package/screenshots/truth/select/without-placeholder.png +0 -0
  125. package/screenshots/truth/textinput/date-initialized.png +0 -0
  126. package/screenshots/truth/textinput/input-focused.png +0 -0
  127. package/screenshots/truth/textinput/textarea-focused.png +0 -0
  128. package/screenshots/truth/tip/bottom.png +0 -0
  129. package/screenshots/truth/tip/left.png +0 -0
  130. package/screenshots/truth/tip/right.png +0 -0
  131. package/screenshots/truth/tip/top.png +0 -0
  132. package/src/FormElement.ts +1 -1
  133. package/src/RapidElement.ts +1 -1
  134. package/src/alert/Alert.ts +3 -3
  135. package/src/aliaseditor/AliasEditor.ts +4 -3
  136. package/src/anchor/Anchor.ts +2 -1
  137. package/src/button/Button.ts +3 -1
  138. package/src/charcount/CharCount.ts +2 -1
  139. package/src/checkbox/Checkbox.ts +3 -1
  140. package/src/completion/Completion.ts +2 -1
  141. package/src/completion/helpers.ts +30 -4
  142. package/src/contacts/ContactChat.ts +115 -95
  143. package/src/contacts/ContactDetails.ts +2 -1
  144. package/src/contacts/ContactHistory.ts +64 -67
  145. package/src/contacts/events.ts +62 -77
  146. package/src/contactsearch/ContactSearch.ts +2 -1
  147. package/src/datepicker/DatePicker.ts +2 -7
  148. package/src/dialog/Dialog.ts +2 -2
  149. package/src/dialog/Modax.ts +4 -6
  150. package/src/dropdown/Dropdown.ts +136 -0
  151. package/src/formfield/FormField.ts +2 -1
  152. package/src/label/Label.ts +2 -8
  153. package/src/leafletmap/LeafletMap.ts +2 -2
  154. package/src/list/TembaList.ts +8 -5
  155. package/src/list/TembaMenu.ts +125 -103
  156. package/src/list/TicketList.ts +2 -1
  157. package/src/loading/Loading.ts +2 -1
  158. package/src/omnibox/Omnibox.ts +2 -1
  159. package/src/options/Options.ts +3 -2
  160. package/src/remote/Remote.ts +2 -7
  161. package/src/select/Select.ts +11 -10
  162. package/src/shadowless/Shadowless.ts +2 -2
  163. package/src/store/Store.ts +2 -1
  164. package/src/tabpane/Tab.ts +42 -0
  165. package/src/tabpane/TabPane.ts +113 -0
  166. package/src/textinput/TextInput.ts +3 -2
  167. package/src/tip/Tip.ts +2 -2
  168. package/src/vectoricon/VectorIcon.ts +18 -6
  169. package/static/css/temba-components.css +11 -0
  170. package/static/icons/Read Me.txt +1 -1
  171. package/static/icons/SVG/pause.svg +5 -0
  172. package/static/icons/SVG/play.svg +5 -0
  173. package/static/icons/SVG/{upload-cloud.svg → publish.svg} +1 -1
  174. package/static/icons/SVG/user-x.svg +5 -0
  175. package/static/icons/demo-external-svg.html +157 -142
  176. package/static/icons/demo-files/demo.css +3 -3
  177. package/static/icons/demo.html +186 -162
  178. package/static/icons/selection.json +390 -318
  179. package/static/icons/symbol-defs.svg +29 -20
  180. package/temba-modules.ts +6 -0
  181. package/test/temba-contact-history.test.ts +10 -6
  182. package/test/temba-dialog.test.ts +5 -6
  183. package/test-assets/modax/form.html +1 -1
  184. package/test-assets/style.css +7 -0
  185. package/web-test-runner.config.mjs +130 -117
  186. package/dist/56e0e480.js +0 -356
@@ -1,4 +1,5 @@
1
- import { css, property } from 'lit-element';
1
+ import { css } from 'lit';
2
+ import { property } from 'lit/decorators';
2
3
  import { html, TemplateResult } from 'lit-html';
3
4
  import { Contact, CustomEventType, Ticket } from '../interfaces';
4
5
  import { RapidElement } from '../RapidElement';
@@ -109,22 +110,24 @@ export class ContactHistory extends RapidElement {
109
110
  return css`
110
111
  ${getEventStyles()}
111
112
 
112
- :host {
113
- flex-grow: 1;
114
- flex-direction: column;
113
+ .wrapper {
114
+ border: 0px solid green;
115
115
  display: flex;
116
116
  flex-direction: column;
117
117
  align-items: items-stretch;
118
+ flex-grow: 1;
119
+ min-height: 0;
118
120
  }
119
121
 
120
122
  .events {
121
- height: 200px;
122
123
  overflow-y: scroll;
123
124
  overflow-x: hidden;
124
- flex-grow: 1;
125
- border-top-left-radius: var(--curvature);
126
- padding-top: 1em;
127
125
  background: #fff;
126
+ display: flex;
127
+ flex-direction: column;
128
+ flex-grow: 1;
129
+ min-height: 0;
130
+ padding-top: 3em;
128
131
  }
129
132
 
130
133
  temba-loading {
@@ -179,12 +182,9 @@ export class ContactHistory extends RapidElement {
179
182
  }
180
183
 
181
184
  .sticky-bin {
182
- display: flex;
183
- flex-direction: column;
184
- z-index: 2;
185
185
  border-top-left-radius: var(--curvature);
186
- overflow: hidden;
187
- box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.15);
186
+ z-index: 2;
187
+ box-shadow: rgb(0 0 0 / 15%) 0px 3px 3px 0px;
188
188
  background: rgb(240, 240, 240);
189
189
  }
190
190
 
@@ -381,7 +381,6 @@ export class ContactHistory extends RapidElement {
381
381
  if (forceOpen) {
382
382
  grouped[grouped.length - 1].open = forceOpen;
383
383
  }
384
-
385
384
  this.eventGroups = [...previousGroups, ...grouped];
386
385
  }
387
386
  this.refreshing = false;
@@ -451,6 +450,7 @@ export class ContactHistory extends RapidElement {
451
450
  if (changedProperties.has('refreshing') && !this.refreshing) {
452
451
  if (this.lastRefreshAdded > 0) {
453
452
  const events = this.getEventsPane();
453
+
454
454
  // if we are near the bottom, push us to the bottom to show new stuff
455
455
  if (this.lastHeight > 0) {
456
456
  const addedHeight = events.scrollHeight - this.lastHeight;
@@ -572,7 +572,6 @@ export class ContactHistory extends RapidElement {
572
572
  }
573
573
  eventGroup = {
574
574
  open: false,
575
- closing: false,
576
575
  events: [event],
577
576
  type: currentEventGroupType,
578
577
  };
@@ -641,30 +640,24 @@ export class ContactHistory extends RapidElement {
641
640
  private handleEventGroupShow(event: MouseEvent) {
642
641
  const grouping = event.currentTarget as HTMLDivElement;
643
642
  const groupIndex = parseInt(grouping.getAttribute('data-group-index'));
644
- const eventGroup = this.eventGroups[
645
- this.eventGroups.length - groupIndex - 1
646
- ];
643
+ const eventGroup =
644
+ this.eventGroups[this.eventGroups.length - groupIndex - 1];
647
645
  eventGroup.open = true;
648
646
  this.requestUpdate('eventGroups');
649
647
  }
650
648
 
651
649
  private handleEventGroupHide(event: MouseEvent) {
650
+ event.preventDefault();
651
+ event.stopPropagation();
652
+
652
653
  const grouping = event.currentTarget as HTMLDivElement;
653
654
  const groupIndex = parseInt(grouping.getAttribute('data-group-index'));
654
- const eventGroup = this.eventGroups[
655
- this.eventGroups.length - groupIndex - 1
656
- ];
655
+ const eventGroup =
656
+ this.eventGroups[this.eventGroups.length - groupIndex - 1];
657
657
 
658
- // mark us as closing
659
- eventGroup.closing = true;
660
- this.requestUpdate('eventGroups');
658
+ eventGroup.open = false;
661
659
 
662
- // after our animation, close it up for real
663
- setTimeout(() => {
664
- eventGroup.closing = false;
665
- eventGroup.open = false;
666
- this.requestUpdate('eventGroups');
667
- }, 300);
660
+ this.requestUpdate('eventGroups');
668
661
  }
669
662
 
670
663
  private handleScroll() {
@@ -720,7 +713,7 @@ export class ContactHistory extends RapidElement {
720
713
  return 0;
721
714
  }
722
715
 
723
- public renderEvent(event: ContactEvent): TemplateResult {
716
+ public renderEvent(event: ContactEvent): any {
724
717
  switch (event.type) {
725
718
  case Events.IVR_CREATED:
726
719
  case Events.MESSAGE_CREATED:
@@ -914,12 +907,16 @@ export class ContactHistory extends RapidElement {
914
907
  : null;
915
908
 
916
909
  return html`
917
- ${this.ticket
918
- ? html`<div class="sticky-bin">${unfetchedTickets}</div>`
919
- : null}
920
- ${this.fetching
921
- ? html`<temba-loading units="5" size="10"></temba-loading>`
922
- : html`<div style="height:0em"></div>`}
910
+ ${
911
+ this.ticket
912
+ ? html`<div class="sticky-bin">${unfetchedTickets}</div>`
913
+ : null
914
+ }
915
+ ${
916
+ this.fetching
917
+ ? html`<temba-loading units="5" size="10"></temba-loading>`
918
+ : html`<div style="height:0em"></div>`
919
+ }
923
920
  <div class="events" @scroll=${this.handleScroll}>
924
921
  ${this.eventGroups.map((eventGroup: EventGroup, index: number) => {
925
922
  const grouping = getEventGroupType(eventGroup.events[0], this.ticket);
@@ -929,9 +926,7 @@ export class ContactHistory extends RapidElement {
929
926
  grouping: true,
930
927
  [grouping]: true,
931
928
  expanded: eventGroup.open,
932
- closing: eventGroup.closing,
933
929
  });
934
-
935
930
  return html`<div class="${classes}">
936
931
  ${grouping === 'verbose'
937
932
  ? html`<div
@@ -939,36 +934,37 @@ export class ContactHistory extends RapidElement {
939
934
  @click=${this.handleEventGroupShow}
940
935
  data-group-index="${groupIndex}"
941
936
  >
942
- ${eventGroup.events.length}
943
- ${eventGroup.events.length === 1 ? html`event` : html`events`}
937
+ ${eventGroup.open
938
+ ? html`<temba-icon
939
+ @click=${this.handleEventGroupHide}
940
+ data-group-index="${groupIndex}"
941
+ name="x"
942
+ clickable
943
+ ></temba-icon>`
944
+ : html`${eventGroup.events.length}
945
+ ${eventGroup.events.length === 1
946
+ ? html`event`
947
+ : html`events`} `}
944
948
  </div>`
945
949
  : null}
946
- ${grouping === 'verbose'
947
- ? html`
948
- <temba-icon
949
- @click=${this.handleEventGroupHide}
950
- data-group-index="${groupIndex}"
951
- class="grouping-close-button"
952
- name="x"
953
- clickable
954
- ></temba-icon>
955
- `
956
- : null}
957
- ${eventGroup.events.map((event: ContactEvent) => {
958
- if (
959
- event.type === Events.TICKET_ASSIGNED &&
960
- (event as TicketEvent).note
961
- ) {
962
- const noteEvent = { ...event };
963
- noteEvent.type = Events.TICKET_NOTE_ADDED;
964
-
965
- return html`${this.renderEventContainer(
966
- noteEvent
967
- )}${this.renderEventContainer(event)}`;
968
- } else {
969
- return this.renderEventContainer(event);
970
- }
971
- })}
950
+
951
+ <div class="items">
952
+ ${eventGroup.events.map((event: ContactEvent) => {
953
+ if (
954
+ event.type === Events.TICKET_ASSIGNED &&
955
+ (event as TicketEvent).note
956
+ ) {
957
+ const noteEvent = { ...event };
958
+ noteEvent.type = Events.TICKET_NOTE_ADDED;
959
+
960
+ return html`${this.renderEventContainer(
961
+ noteEvent
962
+ )}${this.renderEventContainer(event)}`;
963
+ } else {
964
+ return this.renderEventContainer(event);
965
+ }
966
+ })}
967
+ </div>
972
968
  </div>`;
973
969
  })}
974
970
  </div>
@@ -985,6 +981,7 @@ export class ContactHistory extends RapidElement {
985
981
  New Messages
986
982
  </div>
987
983
  </div>
984
+ </div>
988
985
  `;
989
986
  }
990
987
  }
@@ -1,5 +1,4 @@
1
- import { css } from 'lit-element';
2
- import { html, TemplateResult } from 'lit-html';
1
+ import { css, html, TemplateResult } from 'lit';
3
2
  import { Msg, ObjectReference, User } from '../interfaces';
4
3
  import { getClasses, oxford, oxfordFn, oxfordNamed, timeSince } from '../utils';
5
4
  import { getDisplayName } from './helpers';
@@ -7,21 +6,54 @@ import { getDisplayName } from './helpers';
7
6
  export const getEventStyles = () => {
8
7
  return css`
9
8
  .grouping {
10
- padding: 0 2em;
11
- margin: 0 -1em;
9
+ margin-top: 1em;
12
10
  }
13
11
 
14
12
  .grouping.verbose {
15
13
  background: #f9f9f9;
16
- max-height: 1px;
17
- border-top: 1px solid #f9f9f9;
18
- padding-top: 0;
19
- padding-bottom: 0;
20
- margin-top: 0;
21
- margin-bottom: 1.5em;
22
- color: #efefef;
14
+ color: var(--color-dark);
23
15
  --color-link-primary: rgba(38, 166, 230, 1);
24
16
  pointer-events: none;
17
+ background: #fefefe;
18
+ box-shadow: -8px 0px 8px 1px rgba(0, 0, 0, 0.05) inset;
19
+ margin-right: -16px;
20
+ padding-right: 16px;
21
+ margin-bottom: 1.3em;
22
+ }
23
+
24
+ .grouping .items {
25
+ display: block;
26
+ user-select: none;
27
+ }
28
+
29
+ .grouping.verbose .items {
30
+ opacity: 0;
31
+ max-height: 0;
32
+ display: flex;
33
+ flex-direction: column;
34
+ }
35
+
36
+ .grouping.flows .items {
37
+ padding: 0;
38
+ }
39
+
40
+ .grouping.messages .items {
41
+ display: flex;
42
+ flex-direction: column;
43
+ margin: 0em 0.75em;
44
+ }
45
+
46
+ .grouping.verbose.expanded .items {
47
+ transition: max-height var(--transition-speed) ease-in-out,
48
+ opacity var(--transition-speed) ease-in-out;
49
+ opacity: 1;
50
+ max-height: 1000px;
51
+ padding: 1em 1em;
52
+ }
53
+
54
+ .grouping.verbose.expanded {
55
+ border-top: 1px solid #f3f3f3;
56
+ border-bottom: 1px solid #f3f3f3;
25
57
  }
26
58
 
27
59
  .grouping.verbose.expanded,
@@ -44,50 +76,37 @@ export const getEventStyles = () => {
44
76
  }
45
77
 
46
78
  .grouping.verbose .attn {
47
- color: #fff;
79
+ color: #666;
48
80
  }
49
81
 
50
82
  .event-count {
51
83
  position: relative;
52
- top: -1.2em;
53
84
  font-size: 0.8em;
54
85
  text-align: center;
55
- border: 2px solid #f9f9f9;
56
- background: #fff;
57
86
  margin: 0 auto;
58
87
  display: table;
59
88
  padding: 3px 10px;
60
89
  font-weight: 400;
61
- color: #777;
62
- border-radius: var(--curvature);
90
+ color: #999;
63
91
  cursor: pointer;
64
- min-width: 0%;
92
+ width: 100%;
65
93
  opacity: 1;
66
- transition: all var(--transition-speed) ease-in, opacity 0.1ms,
67
- margin-top 0ms;
68
- }
69
-
70
- .closing .grouping-close-button {
71
- opacity: 0 !important;
72
- transition: none !important;
94
+ z-index: 1;
73
95
  }
74
96
 
75
- .event-count {
76
- z-index: 1;
77
- margin-bottom: 1em;
97
+ .event-count temba-icon {
98
+ display: inline-block;
99
+ position: absolute;
100
+ right: 5px;
101
+ top: 5px;
78
102
  }
79
103
 
80
104
  .event-count:hover {
81
- padding: 3px 10px;
82
- min-width: 50%;
83
- background: #f9f9f9;
84
- color: #333;
105
+ color: var(--color-link-primary-hover);
85
106
  }
86
107
 
87
108
  .expanded .event-count {
88
- opacity: 0;
89
- margin-top: -42px;
90
- z-index: 0;
109
+ padding: 0;
91
110
  pointer-events: none;
92
111
  }
93
112
 
@@ -115,54 +134,18 @@ export const getEventStyles = () => {
115
134
  word-wrap: break-word;
116
135
  }
117
136
 
118
- .grouping.verbose.closing {
119
- opacity: 0 !important;
120
- padding: 0 !important;
121
- background: #f9f9f9 !important;
122
- max-height: 1px !important;
123
- border-top: 1px solid #f9f9f9 !important;
124
- padding-top: 0 !important;
125
- padding-bottom: 0 !important;
126
- margin-top: 0 !important;
127
- margin-bottom: 0 !important;
128
- }
129
-
130
- .grouping.verbose.closing .event,
131
- .grouping.verbose.closing pre {
132
- max-height: 0px;
133
- }
134
-
135
- .grouping.verbose.expanded {
136
- transition: all var(--transition-speed)
137
- cubic-bezier(0.68, -0.55, 0.265, 1.05),
138
- color 0.1ms;
139
- background: #444;
140
- color: #efefef;
141
- max-height: 1000px;
142
- border-top: 1px solid #f1f1f1;
143
- padding: 2em;
144
- margin-left: 1em;
145
- margin-right: 1em;
146
- border-radius: var(--curvature);
147
- padding-bottom: 1em;
148
- box-shadow: inset 0px 11px 4px -15px #000, inset 0px -11px 4px -15px #000;
149
- }
150
-
151
137
  .grouping.verbose.expanded .event,
152
138
  .grouping.verbose.expanded pre {
153
139
  max-height: 500px;
154
- margin-bottom: 0.5em;
155
140
  opacity: 1;
156
- transition: all var(--transition-speed) ease-in-out;
157
141
  }
158
142
 
159
143
  .grouping-close-button {
144
+ position: relative;
145
+ display: inline-block;
160
146
  opacity: 0;
161
147
  float: right;
162
- margin-top: -1em !important;
163
- margin-right: -1em !important;
164
- fill: #f2f2f2;
165
- transition: opacity var(--transition-speed) ease-in;
148
+ --icon-color: #666;
166
149
  }
167
150
 
168
151
  .grouping.verbose.expanded:hover .grouping-close-button {
@@ -176,7 +159,7 @@ export const getEventStyles = () => {
176
159
  }
177
160
 
178
161
  .event {
179
- margin-bottom: 1em;
162
+ margin: 0.25em 0.5em;
180
163
  border-radius: var(--curvature);
181
164
  flex-grow: 1;
182
165
  }
@@ -333,6 +316,7 @@ export const getEventStyles = () => {
333
316
  font-size: 80%;
334
317
  color: rgba(0, 0, 0, 0.6);
335
318
  padding: 6px 3px;
319
+ margin-bottom: 0.5em;
336
320
  }
337
321
 
338
322
  .msg-summary temba-icon[name='log'] {
@@ -461,7 +445,6 @@ export interface EventGroup {
461
445
  type: string;
462
446
  events: ContactEvent[];
463
447
  open: boolean;
464
- closing: boolean;
465
448
  }
466
449
 
467
450
  export enum Events {
@@ -1082,7 +1065,9 @@ export const renderContactLanguageChangedEvent = (
1082
1065
  event: ContactLanguageChangedEvent
1083
1066
  ): TemplateResult => {
1084
1067
  return html`<temba-icon name="contact"></temba-icon>
1085
- <div class="description">Language updated to ${event.language}</div>`;
1068
+ <div class="description">
1069
+ Language updated to <span class="attn">${event.language}</span>
1070
+ </div>`;
1086
1071
  };
1087
1072
 
1088
1073
  export const renderChannelEvent = (event: ChannelEvent): TemplateResult => {
@@ -1,4 +1,5 @@
1
- import { TemplateResult, html, property, css } from 'lit-element';
1
+ import { TemplateResult, html, css } from 'lit';
2
+ import { property } from 'lit/decorators';
2
3
  import { getUrl, WebResponse } from '../utils';
3
4
  import { TextInput } from '../textinput/TextInput';
4
5
  import '../alert/Alert';
@@ -1,10 +1,5 @@
1
- import {
2
- customElement,
3
- TemplateResult,
4
- html,
5
- css,
6
- property,
7
- } from 'lit-element';
1
+ import { TemplateResult, html, css } from 'lit';
2
+ import { property, customElement } from 'lit/decorators';
8
3
 
9
4
  import { FormElement } from '../FormElement';
10
5
  import 'lit-flatpickr';
@@ -1,5 +1,5 @@
1
- import { property } from 'lit-element/lib/decorators';
2
- import { TemplateResult, html, css } from 'lit-element';
1
+ import { property } from 'lit/decorators';
2
+ import { TemplateResult, html, css } from 'lit';
3
3
  import { Button } from '../button/Button';
4
4
  import { RapidElement } from '../RapidElement';
5
5
  import { CustomEventType } from '../interfaces';
@@ -1,8 +1,9 @@
1
- import { property } from 'lit-element/lib/decorators';
2
- import { TemplateResult, html, css } from 'lit-element';
1
+ import { TemplateResult, html, css } from 'lit';
2
+ import { property } from 'lit/decorators';
3
+ import { unsafeHTML } from 'lit-html/directives/unsafe-html';
4
+
3
5
  import { RapidElement } from '../RapidElement';
4
6
  import { getUrl, serialize, postUrl, WebResponse } from '../utils';
5
- import { unsafeHTML } from 'lit-html/directives/unsafe-html';
6
7
  import { CustomEventType } from '../interfaces';
7
8
  import { Dialog } from './Dialog';
8
9
 
@@ -100,9 +101,6 @@ export class Modax extends RapidElement {
100
101
  @property({ type: String })
101
102
  onLoaded: string;
102
103
 
103
- @property({ type: String })
104
- onSubmitted: string;
105
-
106
104
  @property({ type: Boolean })
107
105
  noSubmit: boolean;
108
106
 
@@ -0,0 +1,136 @@
1
+ import { css, html, TemplateResult } from 'lit';
2
+ import { property } from 'lit/decorators';
3
+ import { RapidElement } from '../RapidElement';
4
+
5
+ export class Dropdown extends RapidElement {
6
+ static get styles() {
7
+ return css`
8
+ .toggle {
9
+ cursor: pointer;
10
+ }
11
+
12
+ .dropdown {
13
+ position: absolute;
14
+ opacity: 0;
15
+ z-index: 10;
16
+ pointer-events: none;
17
+ padding: 0;
18
+ border-radius: var(--curvature);
19
+ background: #fff;
20
+ transform: translateY(2em);
21
+ transition: all calc(0.6 * var(--transition-speed)) linear;
22
+ user-select: none;
23
+ margin-top: 0px;
24
+ margin-left: 0px;
25
+ box-shadow: var(--dropdown-shadow);
26
+ }
27
+
28
+ .dropdown:focus {
29
+ outline: none;
30
+ }
31
+
32
+ .arrow {
33
+ content: '';
34
+ width: 0px;
35
+ height: 0;
36
+ top: -6px;
37
+ z-index: 10;
38
+ position: absolute;
39
+ border-left: 6px solid transparent;
40
+ border-right: 6px solid transparent;
41
+ border-bottom: 6px solid white;
42
+ }
43
+
44
+ .open .dropdown {
45
+ opacity: 1;
46
+ pointer-events: auto;
47
+ transform: translateY(0);
48
+ }
49
+ `;
50
+ }
51
+
52
+ @property({ type: Boolean })
53
+ open = false;
54
+
55
+ @property({ type: Number })
56
+ arrowSize = 6;
57
+
58
+ @property({ type: Number })
59
+ arrowOffset = this.arrowSize * 2;
60
+
61
+ @property({ type: Number })
62
+ offsetX = -10;
63
+
64
+ @property({ type: Number })
65
+ offsetY = 0;
66
+
67
+ public firstUpdated(props: any) {
68
+ super.firstUpdated(props);
69
+
70
+ const dropdown = this.shadowRoot.querySelector(
71
+ '.dropdown'
72
+ ) as HTMLDivElement;
73
+ const arrow = this.shadowRoot.querySelector('.arrow') as HTMLDivElement;
74
+
75
+ arrow.style.borderWidth = this.arrowSize + 'px';
76
+ arrow.style.top = '-' + this.arrowSize + 'px';
77
+
78
+ if (this.arrowOffset < 0) {
79
+ arrow.style.right = Math.abs(this.arrowOffset) + 'px';
80
+ } else {
81
+ arrow.style.left = this.arrowOffset + 'px';
82
+ }
83
+
84
+ dropdown.style.marginTop = this.offsetY + 'px';
85
+
86
+ if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {
87
+ dropdown.style.marginLeft =
88
+ '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';
89
+ } else {
90
+ dropdown.style.marginLeft = this.offsetX + 'px';
91
+ }
92
+
93
+ dropdown.addEventListener('blur', () => {
94
+ // we nest this to deal with clicking the toggle to close
95
+ // as we don't want it to toggle an immediate open, probably
96
+ // a better way to deal with this
97
+ window.setTimeout(() => {
98
+ this.open = false;
99
+ }, 200);
100
+ });
101
+ }
102
+
103
+ public updated(changedProperties: Map<string, any>) {
104
+ super.updated(changedProperties);
105
+ if (changedProperties.has('open')) {
106
+ if (this.open) {
107
+ this.classList.add('open');
108
+ } else {
109
+ this.classList.remove('open');
110
+ }
111
+ }
112
+ }
113
+
114
+ public handleOpen(): void {
115
+ if (!this.open) {
116
+ this.open = true;
117
+
118
+ const dropdown = this.shadowRoot.querySelector(
119
+ '.dropdown'
120
+ ) as HTMLDivElement;
121
+ dropdown.focus();
122
+ }
123
+ }
124
+
125
+ public render(): TemplateResult {
126
+ return html`
127
+ <div class=${this.open ? 'open' : ''}>
128
+ <slot name="toggle" class="toggle" @click="${this.handleOpen}"></slot>
129
+ <div class="dropdown" tabindex="0">
130
+ <div class="arrow"></div>
131
+ <slot name="dropdown"></slot>
132
+ </div>
133
+ </div>
134
+ `;
135
+ }
136
+ }
@@ -1,4 +1,5 @@
1
- import { TemplateResult, html, css, property, LitElement } from 'lit-element';
1
+ import { TemplateResult, html, css, LitElement } from 'lit';
2
+ import { property } from 'lit/decorators';
2
3
 
3
4
  /**
4
5
  * A small wrapper to display labels and help text in a smartmin style.
@@ -1,11 +1,5 @@
1
- import {
2
- LitElement,
3
- TemplateResult,
4
- html,
5
- css,
6
- customElement,
7
- property,
8
- } from 'lit-element';
1
+ import { LitElement, TemplateResult, html, css } from 'lit';
2
+ import { property, customElement } from 'lit/decorators';
9
3
  import { getClasses } from '../utils';
10
4
  import { styleMap } from 'lit-html/directives/style-map';
11
5
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/camelcase */
2
1
  import { Feature, Geometry } from 'geojson';
3
2
  import {
4
3
  GeoJSON,
@@ -9,7 +8,8 @@ import {
9
8
  map as createMap,
10
9
  Path,
11
10
  } from 'leaflet';
12
- import { css, html, LitElement, property } from 'lit-element';
11
+ import { css, html, LitElement } from 'lit';
12
+ import { property } from 'lit/decorators';
13
13
 
14
14
  import { FeatureProperties } from '../interfaces';
15
15
  import { getUrl, WebResponse } from '../utils';