@nyaruka/temba-components 0.29.0 → 0.30.0

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 (170) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.yarnrc +1 -1
  3. package/.yarnrc.yml +1 -0
  4. package/CHANGELOG.md +105 -57
  5. package/dist/{64e63814.js → dd72d92e.js} +305 -148
  6. package/dist/index.js +305 -148
  7. package/dist/static/icons/symbol-defs.svg +10 -20
  8. package/dist/sw.js +1 -1
  9. package/dist/sw.js.map +1 -1
  10. package/dist/templates/components-body.html +1 -1
  11. package/dist/templates/components-head.html +1 -1
  12. package/dist/workbox-80efdfd1.js.map +1 -1
  13. package/out-tsc/src/contacts/ContactBadges.js +2 -9
  14. package/out-tsc/src/contacts/ContactBadges.js.map +1 -1
  15. package/out-tsc/src/contacts/ContactChat.js +3 -0
  16. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  17. package/out-tsc/src/contacts/ContactName.js +19 -16
  18. package/out-tsc/src/contacts/ContactName.js.map +1 -1
  19. package/out-tsc/src/contacts/ContactNameFetch.js +36 -0
  20. package/out-tsc/src/contacts/ContactNameFetch.js.map +1 -0
  21. package/out-tsc/src/contacts/ContactStoreElement.js +9 -2
  22. package/out-tsc/src/contacts/ContactStoreElement.js.map +1 -1
  23. package/out-tsc/src/contacts/ContactUrn.js +12 -1
  24. package/out-tsc/src/contacts/ContactUrn.js.map +1 -1
  25. package/out-tsc/src/contacts/events.js +0 -3
  26. package/out-tsc/src/contacts/events.js.map +1 -1
  27. package/out-tsc/src/flow/FlowStoreElement.js +43 -0
  28. package/out-tsc/src/flow/FlowStoreElement.js.map +1 -0
  29. package/out-tsc/src/interfaces.js.map +1 -1
  30. package/out-tsc/src/label/Label.js +29 -42
  31. package/out-tsc/src/label/Label.js.map +1 -1
  32. package/out-tsc/src/list/RunList.js +317 -0
  33. package/out-tsc/src/list/RunList.js.map +1 -0
  34. package/out-tsc/src/list/TembaList.js +38 -14
  35. package/out-tsc/src/list/TembaList.js.map +1 -1
  36. package/out-tsc/src/options/Options.js +18 -2
  37. package/out-tsc/src/options/Options.js.map +1 -1
  38. package/out-tsc/src/slider/TembaSlider.js +9 -1
  39. package/out-tsc/src/slider/TembaSlider.js.map +1 -1
  40. package/out-tsc/src/sms/gsmvalidator.js +9 -138
  41. package/out-tsc/src/sms/gsmvalidator.js.map +1 -1
  42. package/out-tsc/src/store/Store.js +13 -3
  43. package/out-tsc/src/store/Store.js.map +1 -1
  44. package/out-tsc/src/tabpane/TabPane.js +3 -1
  45. package/out-tsc/src/tabpane/TabPane.js.map +1 -1
  46. package/out-tsc/src/utils/index.js +1 -0
  47. package/out-tsc/src/utils/index.js.map +1 -1
  48. package/out-tsc/src/vectoricon/VectorIcon.js +6 -11
  49. package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
  50. package/out-tsc/temba-components.js +1 -2
  51. package/out-tsc/temba-components.js.map +1 -1
  52. package/out-tsc/temba-modules.js +7 -1
  53. package/out-tsc/temba-modules.js.map +1 -1
  54. package/out-tsc/test/MouseHelper.js +47 -0
  55. package/out-tsc/test/MouseHelper.js.map +1 -0
  56. package/out-tsc/test/temba-contact-badges.test.js +23 -0
  57. package/out-tsc/test/temba-contact-badges.test.js.map +1 -0
  58. package/out-tsc/test/temba-contact-chat.test.js +111 -7
  59. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  60. package/out-tsc/test/temba-contact-history.test.js +6 -6
  61. package/out-tsc/test/temba-contact-history.test.js.map +1 -1
  62. package/out-tsc/test/temba-dialog.test.js +1 -1
  63. package/out-tsc/test/temba-dialog.test.js.map +1 -1
  64. package/out-tsc/test/temba-label.test.js +66 -0
  65. package/out-tsc/test/temba-label.test.js.map +1 -0
  66. package/out-tsc/test/temba-list.test.js +1 -1
  67. package/out-tsc/test/temba-list.test.js.map +1 -1
  68. package/out-tsc/test/temba-menu.test.js +1 -1
  69. package/out-tsc/test/temba-menu.test.js.map +1 -1
  70. package/out-tsc/test/temba-select.test.js +1 -6
  71. package/out-tsc/test/temba-select.test.js.map +1 -1
  72. package/out-tsc/test/temba-slider.test.js +151 -8
  73. package/out-tsc/test/temba-slider.test.js.map +1 -1
  74. package/out-tsc/test/temba-textinput.test.js +3 -4
  75. package/out-tsc/test/temba-textinput.test.js.map +1 -1
  76. package/out-tsc/test/temba-tip.test.js +1 -1
  77. package/out-tsc/test/temba-tip.test.js.map +1 -1
  78. package/out-tsc/test/utils.test.js +26 -14
  79. package/out-tsc/test/utils.test.js.map +1 -1
  80. package/package.json +5 -4
  81. package/screenshots/truth/contacts/badges.png +0 -0
  82. package/screenshots/truth/contacts/contact-active-default.png +0 -0
  83. package/screenshots/truth/contacts/contact-active-show-chat-history.png +0 -0
  84. package/screenshots/truth/contacts/contact-active-show-chat-msg.png +0 -0
  85. package/screenshots/truth/contacts/contact-archived-hide-chat-msg.png +0 -0
  86. package/screenshots/truth/contacts/contact-archived-show-chat-history.png +0 -0
  87. package/screenshots/truth/contacts/contact-blocked-hide-chat-msg.png +0 -0
  88. package/screenshots/truth/contacts/contact-blocked-show-chat-history.png +0 -0
  89. package/screenshots/truth/contacts/contact-stopped-hide-chat-msg.png +0 -0
  90. package/screenshots/truth/contacts/contact-stopped-show-chat-history.png +0 -0
  91. package/screenshots/truth/contacts/history-expanded.png +0 -0
  92. package/screenshots/truth/contacts/history.png +0 -0
  93. package/screenshots/truth/label/custom.png +0 -0
  94. package/screenshots/truth/label/danger.png +0 -0
  95. package/screenshots/truth/label/dark.png +0 -0
  96. package/screenshots/truth/label/default-icon.png +0 -0
  97. package/screenshots/truth/label/no-icon.png +0 -0
  98. package/screenshots/truth/label/primary.png +0 -0
  99. package/screenshots/truth/label/secondary.png +0 -0
  100. package/screenshots/truth/label/shadow.png +0 -0
  101. package/screenshots/truth/label/tertiary.png +0 -0
  102. package/screenshots/truth/slider/custom-min-custom-max-valid-value.png +0 -0
  103. package/screenshots/truth/slider/custom-min-default-max-no-value.png +0 -0
  104. package/screenshots/truth/slider/default-min-custom-max-no-value.png +0 -0
  105. package/screenshots/truth/slider/default-min-default-max-invalid-value.png +0 -0
  106. package/screenshots/truth/slider/default-min-default-max-valid-value.png +0 -0
  107. package/screenshots/truth/slider/default.png +0 -0
  108. package/screenshots/truth/slider/no-visible-range-invalid-value.png +0 -0
  109. package/screenshots/truth/slider/no-visible-range-no-value.png +0 -0
  110. package/screenshots/truth/slider/no-visible-range-valid-value.png +0 -0
  111. package/screenshots/truth/slider/update-slider-on-circle-dragged.png +0 -0
  112. package/screenshots/truth/slider/update-slider-on-track-clicked.png +0 -0
  113. package/screenshots/truth/slider/update-slider-on-value-change.png +0 -0
  114. package/src/contacts/ContactBadges.ts +2 -9
  115. package/src/contacts/ContactChat.ts +3 -0
  116. package/src/contacts/ContactName.ts +19 -17
  117. package/src/contacts/ContactNameFetch.ts +32 -0
  118. package/src/contacts/ContactStoreElement.ts +5 -2
  119. package/src/contacts/ContactUrn.ts +12 -1
  120. package/src/contacts/events.ts +0 -3
  121. package/src/flow/FlowStoreElement.ts +42 -0
  122. package/src/interfaces.ts +19 -0
  123. package/src/label/Label.ts +31 -43
  124. package/src/list/RunList.ts +353 -0
  125. package/src/list/TembaList.ts +50 -14
  126. package/src/options/Options.ts +17 -2
  127. package/src/slider/TembaSlider.ts +8 -1
  128. package/src/sms/gsmvalidator.ts +9 -138
  129. package/src/store/Store.ts +20 -3
  130. package/src/tabpane/TabPane.ts +3 -1
  131. package/src/untyped.d.ts +3 -0
  132. package/src/utils/index.ts +3 -0
  133. package/src/vectoricon/VectorIcon.ts +5 -10
  134. package/static/css/temba-components.css +4 -9
  135. package/static/icons/Read Me.txt +15 -15
  136. package/static/icons/SVG/credits.svg +5 -0
  137. package/static/icons/SVG/hourglass.svg +5 -0
  138. package/static/icons/demo-external-svg.html +142 -157
  139. package/static/icons/demo-files/demo.css +4 -4
  140. package/static/icons/demo.html +152 -177
  141. package/static/icons/selection.json +396 -339
  142. package/static/icons/style.css +0 -4
  143. package/static/icons/symbol-defs.svg +10 -20
  144. package/temba-components.ts +1 -2
  145. package/temba-modules.ts +7 -1
  146. package/test/MouseHelper.ts +47 -0
  147. package/test/temba-contact-badges.test.ts +33 -0
  148. package/test/temba-contact-chat.test.ts +202 -6
  149. package/test/temba-contact-history.test.ts +6 -6
  150. package/test/temba-dialog.test.ts +1 -1
  151. package/test/temba-label.test.ts +75 -0
  152. package/test/temba-list.test.ts +1 -1
  153. package/test/temba-menu.test.ts +1 -0
  154. package/test/temba-select.test.ts +6 -10
  155. package/test/temba-slider.test.ts +204 -8
  156. package/test/temba-textinput.test.ts +3 -4
  157. package/test/temba-tip.test.ts +1 -1
  158. package/test/utils.test.ts +34 -16
  159. package/test-assets/contacts/contact-barak-archived +40 -0
  160. package/test-assets/contacts/contact-dave-active +52 -0
  161. package/test-assets/contacts/contact-michelle-blocked +40 -0
  162. package/test-assets/contacts/contact-tim-stopped +52 -0
  163. package/test-assets/store/groups.json +29 -0
  164. package/test-assets/store/languages.json +290 -0
  165. package/test-assets/style.css +2 -0
  166. package/web-test-runner.config.mjs +16 -0
  167. package/.yarn/releases/yarn-1.22.10.cjs +0 -147392
  168. package/out-tsc/src/contacts/ContactGroups.js +0 -40
  169. package/out-tsc/src/contacts/ContactGroups.js.map +0 -1
  170. package/src/contacts/ContactGroups.ts +0 -42
@@ -2,6 +2,7 @@ import { css, html, TemplateResult } from 'lit';
2
2
  import { property } from 'lit/decorators';
3
3
  import { CustomEventType } from '../interfaces';
4
4
  import { RapidElement } from '../RapidElement';
5
+ import { Store } from '../store/Store';
5
6
  import { fetchResultsPage, ResultsPage } from '../utils';
6
7
 
7
8
  const DEFAULT_REFRESH = 10000;
@@ -37,6 +38,9 @@ export class TembaList extends RapidElement {
37
38
  @property({ type: Boolean })
38
39
  collapsed: boolean;
39
40
 
41
+ @property({ type: Boolean })
42
+ hideShadow: boolean;
43
+
40
44
  @property({ attribute: false })
41
45
  getNextRefresh: (firstOption: any) => any;
42
46
 
@@ -56,6 +60,8 @@ export class TembaList extends RapidElement {
56
60
  @property({ type: String })
57
61
  refreshKey = '0';
58
62
 
63
+ reverseRefresh = true;
64
+
59
65
  // our next page from our endpoint
60
66
  nextPage: string = null;
61
67
 
@@ -63,6 +69,8 @@ export class TembaList extends RapidElement {
63
69
  clearRefreshTimeout: any;
64
70
  pending: AbortController[] = [];
65
71
 
72
+ store: Store;
73
+
66
74
  // used for testing only
67
75
  preserve: boolean;
68
76
 
@@ -72,9 +80,6 @@ export class TembaList extends RapidElement {
72
80
  static get styles() {
73
81
  return css`
74
82
  :host {
75
- display: block;
76
- height: 100%;
77
- width: 100%;
78
83
  }
79
84
 
80
85
  temba-options {
@@ -82,18 +87,12 @@ export class TembaList extends RapidElement {
82
87
  width: 100%;
83
88
  flex-grow: 1;
84
89
  }
85
-
86
- .wrapper {
87
- display: flex;
88
- flex-direction: column;
89
- height: 100%;
90
- align-items: center;
91
- }
92
90
  `;
93
91
  }
94
92
 
95
93
  constructor() {
96
94
  super();
95
+ this.store = document.querySelector('temba-store') as Store;
97
96
  this.handleSelection.bind(this);
98
97
  }
99
98
 
@@ -139,7 +138,9 @@ export class TembaList extends RapidElement {
139
138
  }
140
139
 
141
140
  if (changedProperties.has('mostRecentItem')) {
142
- this.fireCustomEvent(CustomEventType.Refreshed);
141
+ if (this.mostRecentItem) {
142
+ this.fireCustomEvent(CustomEventType.Refreshed);
143
+ }
143
144
  }
144
145
 
145
146
  if (changedProperties.has('cursorIndex')) {
@@ -221,6 +222,11 @@ export class TembaList extends RapidElement {
221
222
  * Refreshes the first page, updating any found items in our list
222
223
  */
223
224
  private async refreshTop(): Promise<void> {
225
+ const refreshEndpoint = this.getRefreshEndpoint();
226
+ if (!refreshEndpoint) {
227
+ return;
228
+ }
229
+
224
230
  // cancel any outstanding requests
225
231
  while (this.pending.length > 0) {
226
232
  const pending = this.pending.pop();
@@ -256,7 +262,19 @@ export class TembaList extends RapidElement {
256
262
  });
257
263
 
258
264
  // insert our new items at the front
259
- const newItems = [...page.results.reverse(), ...items];
265
+ let results = page.results;
266
+ if (this.reverseRefresh) {
267
+ results = page.results.reverse();
268
+ }
269
+ const newItems = [...results, ...items];
270
+
271
+ const topItem = newItems[0];
272
+ if (
273
+ !this.mostRecentItem ||
274
+ JSON.stringify(this.mostRecentItem) !== JSON.stringify(topItem)
275
+ ) {
276
+ this.mostRecentItem = topItem;
277
+ }
260
278
 
261
279
  if (prevItem) {
262
280
  const newItem = newItems[this.cursorIndex];
@@ -324,6 +342,8 @@ export class TembaList extends RapidElement {
324
342
  } catch (error) {
325
343
  // aborted
326
344
  this.reset();
345
+
346
+ console.log('error, resetting');
327
347
  return;
328
348
  }
329
349
 
@@ -410,6 +430,18 @@ export class TembaList extends RapidElement {
410
430
  }
411
431
  }
412
432
 
433
+ public renderHeader(): TemplateResult {
434
+ return null;
435
+ }
436
+
437
+ public renderFooter(): TemplateResult {
438
+ return null;
439
+ }
440
+
441
+ public getListStyle() {
442
+ return '';
443
+ }
444
+
413
445
  private handleSelection(event: CustomEvent) {
414
446
  const { selected, index } = event.detail;
415
447
 
@@ -421,10 +453,13 @@ export class TembaList extends RapidElement {
421
453
  }
422
454
 
423
455
  public render(): TemplateResult {
424
- return html`<div class="wrapper">
456
+ return html`
457
+ ${this.renderHeader()}
425
458
  <temba-options
459
+ style="${this.getListStyle()}"
426
460
  ?visible=${true}
427
461
  ?block=${true}
462
+ ?hideShadow=${this.hideShadow}
428
463
  ?collapsed=${this.collapsed}
429
464
  ?loading=${this.loading}
430
465
  .renderOption=${this.renderOption}
@@ -436,6 +471,7 @@ export class TembaList extends RapidElement {
436
471
  >
437
472
  <slot></slot>
438
473
  </temba-options>
439
- </div>`;
474
+ ${this.renderFooter()}
475
+ `;
440
476
  }
441
477
  }
@@ -16,7 +16,6 @@ export class Options extends RapidElement {
16
16
  .options-container {
17
17
  background: var(--color-widget-bg-focused);
18
18
  user-select: none;
19
- box-shadow: var(--options-shadow);
20
19
  border-radius: var(--curvature-widget);
21
20
  overflow: hidden;
22
21
  margin-top: var(--options-margin-top);
@@ -32,6 +31,10 @@ export class Options extends RapidElement {
32
31
  border: 1px transparent;
33
32
  }
34
33
 
34
+ .shadow {
35
+ box-shadow: var(--options-shadow);
36
+ }
37
+
35
38
  .anchored {
36
39
  position: fixed;
37
40
  }
@@ -52,12 +55,19 @@ export class Options extends RapidElement {
52
55
  }
53
56
 
54
57
  :host([block]) {
55
- box-shadow: var(--options-block-shadow);
56
58
  border-radius: var(--curvature);
57
59
  display: block;
58
60
  height: 100%;
59
61
  }
60
62
 
63
+ :host([block]) .shadow {
64
+ box-shadow: var(--options-block-shadow);
65
+ }
66
+
67
+ .bordered {
68
+ border: 1px solid var(--color-widget-border) !important;
69
+ }
70
+
61
71
  :host([block]) .options {
62
72
  margin-bottom: 1.5em;
63
73
  }
@@ -218,6 +228,9 @@ export class Options extends RapidElement {
218
228
  @property({ type: Boolean })
219
229
  collapsed: boolean;
220
230
 
231
+ @property({ type: Boolean })
232
+ hideShadow = false;
233
+
221
234
  @property({ attribute: false })
222
235
  getName: { (option: any): string } = function (option: any) {
223
236
  return option[this.nameKey || 'name'];
@@ -589,6 +602,8 @@ export class Options extends RapidElement {
589
602
  top: this.poppedTop,
590
603
  anchored: !this.block,
591
604
  loading: this.loading,
605
+ shadow: !this.hideShadow,
606
+ bordered: this.hideShadow,
592
607
  });
593
608
 
594
609
  const classesInner = getClasses({
@@ -128,7 +128,14 @@ export class TembaSlider extends FormElement {
128
128
  const track = this.shadowRoot.querySelector('.track') as HTMLDivElement;
129
129
  const pre = this.shadowRoot.querySelector('.pre') as HTMLDivElement;
130
130
  const range = this.max - this.min;
131
- const pct = (parseInt(this.value) - this.min) / range;
131
+ let cValue = parseInt(this.value);
132
+ if (!cValue || cValue < this.min) {
133
+ cValue = this.min;
134
+ } else if (cValue > this.max) {
135
+ cValue = this.max;
136
+ }
137
+ this.value = '' + cValue;
138
+ const pct = (cValue - this.min) / range;
132
139
  const pctAsPixels = track.offsetWidth * pct;
133
140
 
134
141
  this.circleX = pctAsPixels + (pre ? pre.offsetWidth : 0);
@@ -1,143 +1,14 @@
1
- /* eslint-disable @typescript-eslint/camelcase */
2
1
  // '@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ\x20!"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà\f^{}\\[~]|€'
3
2
  const GSM_charCodes = [
4
- 10,
5
- 12,
6
- 13,
7
- 32,
8
- 33,
9
- 34,
10
- 35,
11
- 36,
12
- 37,
13
- 38,
14
- 39,
15
- 40,
16
- 41,
17
- 42,
18
- 43,
19
- 44,
20
- 45,
21
- 46,
22
- 47,
23
- 48,
24
- 49,
25
- 50,
26
- 51,
27
- 52,
28
- 53,
29
- 54,
30
- 55,
31
- 56,
32
- 57,
33
- 58,
34
- 59,
35
- 60,
36
- 61,
37
- 62,
38
- 63,
39
- 64,
40
- 65,
41
- 66,
42
- 67,
43
- 68,
44
- 69,
45
- 70,
46
- 71,
47
- 72,
48
- 73,
49
- 74,
50
- 75,
51
- 76,
52
- 77,
53
- 78,
54
- 79,
55
- 80,
56
- 81,
57
- 82,
58
- 83,
59
- 84,
60
- 85,
61
- 86,
62
- 87,
63
- 88,
64
- 89,
65
- 90,
66
- 91,
67
- 92,
68
- 93,
69
- 94,
70
- 95,
71
- 97,
72
- 98,
73
- 99,
74
- 100,
75
- 101,
76
- 102,
77
- 103,
78
- 104,
79
- 105,
80
- 106,
81
- 107,
82
- 108,
83
- 109,
84
- 110,
85
- 111,
86
- 112,
87
- 113,
88
- 114,
89
- 115,
90
- 116,
91
- 117,
92
- 118,
93
- 119,
94
- 120,
95
- 121,
96
- 122,
97
- 123,
98
- 124,
99
- 125,
100
- 126,
101
- 161,
102
- 163,
103
- 164,
104
- 165,
105
- 167,
106
- 191,
107
- 196,
108
- 197,
109
- 198,
110
- 199,
111
- 201,
112
- 209,
113
- 214,
114
- 216,
115
- 220,
116
- 223,
117
- 224,
118
- 228,
119
- 229,
120
- 230,
121
- 232,
122
- 233,
123
- 236,
124
- 241,
125
- 242,
126
- 246,
127
- 248,
128
- 249,
129
- 252,
130
- 915,
131
- 916,
132
- 920,
133
- 923,
134
- 926,
135
- 928,
136
- 931,
137
- 934,
138
- 936,
139
- 937,
140
- 8364,
3
+ 10, 12, 13, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
4
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
5
+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
6
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 97, 98, 99, 100, 101, 102, 103, 104,
7
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
8
+ 120, 121, 122, 123, 124, 125, 126, 161, 163, 164, 165, 167, 191, 196, 197,
9
+ 198, 199, 201, 209, 214, 216, 220, 223, 224, 228, 229, 230, 232, 233, 236,
10
+ 241, 242, 246, 248, 249, 252, 915, 916, 920, 923, 926, 928, 931, 934, 936,
11
+ 937, 8364,
141
12
  ];
142
13
 
143
14
  // '\f|^€{}[~]\\'
@@ -179,11 +179,28 @@ export class Store extends RapidElement {
179
179
  return 'en';
180
180
  }
181
181
 
182
- public getShortDuration(isoDate: string) {
183
- const scheduled = DateTime.fromISO(isoDate);
184
- const now = DateTime.now();
182
+ public getShortDuration(
183
+ isoDateA: string,
184
+ isoDateB: string = null,
185
+ showSeconds = false
186
+ ) {
187
+ const scheduled = DateTime.fromISO(isoDateA);
188
+ const now = isoDateB ? DateTime.fromISO(isoDateB) : DateTime.now();
185
189
 
186
190
  const duration = scheduled.diff(now).valueOf();
191
+
192
+ if (showSeconds) {
193
+ return this.humanizer.humanize(duration, {
194
+ language: this.getLanguageCode(),
195
+ largest: 1,
196
+ round: true,
197
+ });
198
+ }
199
+
200
+ if (Math.abs(duration) < 60000) {
201
+ return 'just now';
202
+ }
203
+
187
204
  return this.humanizer.humanize(duration, {
188
205
  language: this.getLanguageCode(),
189
206
  largest: 1,
@@ -177,7 +177,9 @@ export class TabPane extends RapidElement {
177
177
  ? html`
178
178
  <div class="badge">
179
179
  ${tab.count > 0
180
- ? html`<div class="count">${tab.count}</div>`
180
+ ? html`<div class="count">
181
+ ${tab.count.toLocaleString()}
182
+ </div>`
181
183
  : null}
182
184
  </div>
183
185
  `
package/src/untyped.d.ts CHANGED
@@ -7,6 +7,9 @@ declare function type(text: string);
7
7
  declare function click(selector: string);
8
8
  declare function pressKey(key, times: number);
9
9
  declare function waitFor(millis: number);
10
+ declare function moveMouse(x: number, y: number);
11
+ declare function mouseDown();
12
+ declare function mouseUp();
10
13
  declare function setViewport({}: any);
11
14
 
12
15
  declare function readStaticFile(filename: string);
@@ -599,3 +599,6 @@ export enum COOKIE_KEYS {
599
599
  MENU_COLLAPSED = 'menu-collapsed',
600
600
  TICKET_SHOW_DETAILS = 'tickets.show-details',
601
601
  }
602
+
603
+ export const capitalize = ([first, ...rest], locale = navigator.language) =>
604
+ first === undefined ? '' : first.toLocaleUpperCase(locale) + rest.join('');
@@ -4,7 +4,7 @@ import { property } from 'lit/decorators';
4
4
  import { getClasses } from '../utils';
5
5
 
6
6
  // for cache busting, increase whenever the icon set changes
7
- const ICON_VERSION = 12;
7
+ const ICON_VERSION = 13;
8
8
 
9
9
  export class VectorIcon extends LitElement {
10
10
  @property({ type: String })
@@ -36,7 +36,7 @@ export class VectorIcon extends LitElement {
36
36
  animationDuration = 200;
37
37
 
38
38
  @property({ type: String })
39
- href = '';
39
+ src = '';
40
40
 
41
41
  @property({ type: Number, attribute: false })
42
42
  steps = 2;
@@ -54,11 +54,6 @@ export class VectorIcon extends LitElement {
54
54
  --color1: var(--icon-color);
55
55
  }
56
56
 
57
- :host([id='flow']),
58
- :host([name='flow']) {
59
- padding-bottom: 0.2em;
60
- }
61
-
62
57
  .sheet {
63
58
  fill: var(--icon-color);
64
59
  transform: scale(1);
@@ -205,7 +200,7 @@ export class VectorIcon extends LitElement {
205
200
  this.steps}ms
206
201
  ${this.easing}"
207
202
  class="${getClasses({
208
- sheet: this.href === '',
203
+ sheet: this.src === '',
209
204
  [this.animateChange]: !!this.animateChange,
210
205
  [this.animateChange + '-' + this.animationStep]:
211
206
  this.animationStep > 0,
@@ -215,8 +210,8 @@ export class VectorIcon extends LitElement {
215
210
  })}"
216
211
  >
217
212
  <use
218
- href="${this.href
219
- ? this.href
213
+ href="${this.src
214
+ ? this.src
220
215
  : `${
221
216
  this.prefix || (window as any).static_url || '/static/'
222
217
  }icons/symbol-defs.svg?v=${ICON_VERSION}#icon-${
@@ -59,6 +59,9 @@
59
59
  --color-text-dark-secondary: rgba(0, 0, 0, 0.25);
60
60
  --color-text-help: rgba(0, 0, 0, 0.35);
61
61
 
62
+
63
+ --color-tertiary: rgb(var(--tertiary-rgb));
64
+
62
65
  --help-text-size: 0.85em;
63
66
  --help-text-margin-left: 0.3em;
64
67
  --color-text-help: rgb(120,120,120);
@@ -86,14 +89,6 @@
86
89
 
87
90
  --color-button-attention: #2ecc71;
88
91
 
89
- --color-label-primary: var(--color-primary-dark);
90
- --color-label-primary-text: var(--color-text-light);
91
- --color-label-secondary: rgba(0, 0, 0, 0.2);
92
- --color-label-secondary-text: rgba(255, 255, 255, 0.9);
93
- --color-label-tertiary: var(--color-tertiary);
94
- --color-label-tertiary-text: var(--color-text-light);
95
-
96
-
97
92
  --color-nav-unselected: #fff;
98
93
  --color-nav-selected-bg: #fff;
99
94
  --color-nav-selected-text: var(--color-primary-dark);
@@ -109,7 +104,7 @@
109
104
 
110
105
  --icon-color: var(--text-color);
111
106
  --icon-color-hover: var(--icon-color);
112
- --icon-color-circle-hover: rgb(245, 245, 245);
107
+ --icon-color-circle-hover: rgba(245, 245, 245, .8);
113
108
 
114
109
  --transition-speed: 250ms;
115
110
  --event-padding: 0.5em 1em;
@@ -1,15 +1,15 @@
1
- The *SVG* folder contains the icons you selected as separate SVG files.
2
-
3
- If you prefer using PNGs, PDFs, or CSS sprites, refer to the Preferences panel of the IcoMoon app before downloading your zip pack.
4
-
5
- *demo.html* lists the icons that you selected. To insert your icons as inline SVGs (with the <use> element), copy the <svg> element (that contains symbol definitions) from the source of the demo.html file, below your own HTML's <body> tag. After copying this SVG, you can reference your glyphs like the following:
6
-
7
- <svg class="icon icon-language"><use xlink:href="#icon-language"></use></svg>
8
-
9
- You can get this code from the SVG tab of the IcoMoon app, or by referring to the source of the demo.html file. To see how you can change the color/size of your icons using CSS, refer to the example provided in the *style.css* file.
10
-
11
- If you prefer to reference an external SVG (containing <defs>) instead of embedding it in HTML, you will need to use *svgxuse.js* in order to support IE 9+. In browsers that don't support referencing external SVGs (such as IE 9), this polyfill sends one HTTP request to fetch and cache all symbol definitions. See *demo-external-svg.html* for this approach. This demo references the *symbol-defs.svg* file and uses the aforementioned polyfill. Note that it must be hosted on a web server to work
12
- properly. Learn more about this polyfill here: https://github.com/Keyamoon/svgxuse
13
-
14
- You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection.
15
-
1
+ The *SVG* folder contains the icons you selected as separate SVG files.
2
+
3
+ If you prefer using PNGs, PDFs, or CSS sprites, refer to the Preferences panel of the IcoMoon app before downloading your zip pack.
4
+
5
+ *demo.html* lists the icons that you selected. To insert your icons as inline SVGs (with the <use> element), copy the <svg> element (that contains symbol definitions) from the source of the demo.html file, below your own HTML's <body> tag. After copying this SVG, you can reference your glyphs like the following:
6
+
7
+ <svg class="icon icon-hourglass"><use xlink:href="#icon-hourglass"></use></svg>
8
+
9
+ You can get this code from the SVG tab of the IcoMoon app, or by referring to the source of the demo.html file. To see how you can change the color/size of your icons using CSS, refer to the example provided in the *style.css* file.
10
+
11
+ If you prefer to reference an external SVG (containing <defs>) instead of embedding it in HTML, you will need to use *svgxuse.js* in order to support IE 9+. In browsers that don't support referencing external SVGs (such as IE 9), this polyfill sends one HTTP request to fetch and cache all symbol definitions. See *demo-external-svg.html* for this approach. This demo references the *symbol-defs.svg* file and uses the aforementioned polyfill. Note that it must be hosted on a web server to work
12
+ properly. Learn more about this polyfill here: https://github.com/Keyamoon/svgxuse
13
+
14
+ You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection.
15
+
@@ -0,0 +1,5 @@
1
+ <!-- Generated by IcoMoon.io -->
2
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
3
+ <title>credits</title>
4
+ <path d="M10.479 4.958c-0.364 0-0.72 0.036-1.064 0.103-0.027-0.021-0.055-0.041-0.084-0.061 0.425-0.294 0.669-0.636 0.669-1v-1c0-1.105-2.239-2-5-2s-5 0.895-5 2v1c0 0.364 0.244 0.706 0.669 1-0.425 0.294-0.669 0.636-0.669 1v1c0 0.364 0.244 0.706 0.669 1-0.425 0.294-0.669 0.636-0.669 1v1c0 0.364 0.244 0.706 0.669 1-0.425 0.294-0.669 0.636-0.669 1v1c0 1.105 2.239 2 5 2 0.738 0 1.438-0.064 2.069-0.179 0.939 0.739 2.123 1.179 3.41 1.179 3.049 0 5.521-2.472 5.521-5.521s-2.472-5.521-5.521-5.521zM0.5 3c0-0.298 0.451-0.671 1.15-0.95 0.887-0.355 2.076-0.55 3.35-0.55s2.463 0.195 3.35 0.55c0.699 0.279 1.15 0.652 1.15 0.95s-0.451 0.671-1.15 0.95c-0.288 0.115-0.609 0.214-0.954 0.294-0.716 0.167-1.536 0.256-2.396 0.256s-1.68-0.089-2.396-0.256c-0.345-0.080-0.666-0.179-0.954-0.294-0.699-0.279-1.15-0.652-1.15-0.95zM0.5 9c0-0.221 0.249-0.483 0.663-0.718 0.917 0.439 2.296 0.718 3.837 0.718 0.053 0 0.106-0.001 0.159-0.001-0.131 0.471-0.201 0.968-0.201 1.481 0 0.007 0 0.014 0 0.021-0.844-0.003-1.65-0.091-2.354-0.256-0.345-0.080-0.666-0.179-0.954-0.294-0.699-0.279-1.15-0.652-1.15-0.95zM5 13.5c-1.273 0-2.463-0.195-3.35-0.55-0.699-0.279-1.15-0.652-1.15-0.95 0-0.221 0.249-0.483 0.663-0.718 0.917 0.439 2.296 0.718 3.837 0.718 0.057 0 0.114-0.001 0.17-0.002 0.151 0.527 0.378 1.022 0.668 1.472-0.274 0.019-0.554 0.029-0.839 0.029zM5 7.5c-0.859 0-1.68-0.089-2.396-0.256-0.345-0.080-0.666-0.179-0.954-0.294-0.699-0.279-1.15-0.652-1.15-0.95 0-0.221 0.249-0.483 0.663-0.718 0.917 0.439 2.296 0.718 3.837 0.718 1.030 0 1.987-0.125 2.782-0.339-0.781 0.438-1.444 1.060-1.932 1.808-0.278 0.020-0.562 0.030-0.85 0.030zM10.479 14.996c-2.495 0-4.517-2.022-4.517-4.517s2.022-4.517 4.517-4.517c2.495 0 4.517 2.022 4.517 4.517s-2.022 4.517-4.517 4.517zM11 7h-1v1h-2v3h2v1h-2v1h2v1h1v-1h2v-3h-2v-1h2v-1h-2v-1zM10 10h-1v-1h1v1zM12 11v1h-1v-1h1z"></path>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <!-- Generated by IcoMoon.io -->
2
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
3
+ <title>hourglass</title>
4
+ <path d="M12 11.484l3.984-3.984v-3.516h-7.969v3.516zM15.984 16.5l-3.984-3.984-3.984 3.984v3.516h7.969v-3.516zM6 2.016h12v6l-3.984 3.984 3.984 3.984v6h-12v-6l3.984-3.984-3.984-3.984v-6z"></path>
5
+ </svg>