botframework-webchat 4.14.1 → 4.15.2-main.20220413.af6e8a3

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 (108) hide show
  1. package/.eslintrc.yml +5 -109
  2. package/.prettierrc.yml +1 -1
  3. package/README.md +1 -1
  4. package/lib/AddFullBundle.d.ts.map +1 -1
  5. package/lib/AddFullBundle.js +1 -2
  6. package/lib/FullComposer.d.ts.map +1 -1
  7. package/lib/FullComposer.js +3 -3
  8. package/lib/FullReactWebChat.js +2 -2
  9. package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.d.ts +1 -1
  10. package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.d.ts.map +1 -1
  11. package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.js +3 -1
  12. package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.d.ts +1 -1
  13. package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.d.ts.map +1 -1
  14. package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.js +10 -3
  15. package/lib/adaptiveCards/Attachment/AdaptiveCardContent.js +2 -2
  16. package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.d.ts +3 -2
  17. package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.d.ts.map +1 -1
  18. package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.js +138 -74
  19. package/lib/adaptiveCards/Attachment/AnimationCardContent.d.ts +1 -1
  20. package/lib/adaptiveCards/Attachment/AnimationCardContent.d.ts.map +1 -1
  21. package/lib/adaptiveCards/Attachment/AnimationCardContent.js +3 -1
  22. package/lib/adaptiveCards/Attachment/AudioCardContent.d.ts +1 -1
  23. package/lib/adaptiveCards/Attachment/AudioCardContent.d.ts.map +1 -1
  24. package/lib/adaptiveCards/Attachment/AudioCardContent.js +3 -1
  25. package/lib/adaptiveCards/Attachment/HeroCardContent.d.ts +1 -1
  26. package/lib/adaptiveCards/Attachment/HeroCardContent.d.ts.map +1 -1
  27. package/lib/adaptiveCards/Attachment/HeroCardContent.js +4 -2
  28. package/lib/adaptiveCards/Attachment/OAuthCardContent.d.ts +1 -1
  29. package/lib/adaptiveCards/Attachment/OAuthCardContent.d.ts.map +1 -1
  30. package/lib/adaptiveCards/Attachment/OAuthCardContent.js +3 -1
  31. package/lib/adaptiveCards/Attachment/ReceiptCardContent.d.ts +1 -1
  32. package/lib/adaptiveCards/Attachment/ReceiptCardContent.d.ts.map +1 -1
  33. package/lib/adaptiveCards/Attachment/ReceiptCardContent.js +3 -1
  34. package/lib/adaptiveCards/Attachment/SignInCardContent.d.ts +1 -1
  35. package/lib/adaptiveCards/Attachment/SignInCardContent.d.ts.map +1 -1
  36. package/lib/adaptiveCards/Attachment/SignInCardContent.js +1 -1
  37. package/lib/adaptiveCards/Attachment/ThumbnailCardContent.d.ts +1 -1
  38. package/lib/adaptiveCards/Attachment/ThumbnailCardContent.d.ts.map +1 -1
  39. package/lib/adaptiveCards/Attachment/ThumbnailCardContent.js +3 -1
  40. package/lib/adaptiveCards/Attachment/VideoCardContent.d.ts +1 -1
  41. package/lib/adaptiveCards/Attachment/VideoCardContent.d.ts.map +1 -1
  42. package/lib/adaptiveCards/Attachment/VideoCardContent.js +5 -3
  43. package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.d.ts +3 -0
  44. package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.d.ts.map +1 -1
  45. package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.js +8 -1
  46. package/lib/adaptiveCards/Styles/adaptiveCardHostConfig.js +2 -2
  47. package/lib/adaptiveCards/Styles/createAdaptiveCardsStyleSet.js +2 -2
  48. package/lib/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.d.ts.map +1 -1
  49. package/lib/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.js +26 -29
  50. package/lib/adaptiveCards/normalizeStyleOptions.js +2 -2
  51. package/lib/addVersion.js +2 -2
  52. package/lib/createDirectLineSpeechAdapters.d.ts +1 -1
  53. package/lib/createDirectLineSpeechAdapters.d.ts.map +1 -1
  54. package/lib/createDirectLineSpeechAdapters.js +1 -1
  55. package/lib/createFullStyleSet.d.ts +325 -56
  56. package/lib/createFullStyleSet.d.ts.map +1 -1
  57. package/lib/createFullStyleSet.js +2 -2
  58. package/lib/fullBundleDefaultStyleOptions.js +2 -2
  59. package/lib/index-es5.d.ts +1 -21
  60. package/lib/index-es5.d.ts.map +1 -1
  61. package/lib/index-es5.js +4 -44
  62. package/lib/index-minimal.js +22 -20
  63. package/lib/index.d.ts +30 -8
  64. package/lib/index.d.ts.map +1 -1
  65. package/lib/index.js +11 -8
  66. package/lib/polyfill.d.ts +23 -0
  67. package/lib/polyfill.d.ts.map +1 -0
  68. package/lib/polyfill.js +46 -0
  69. package/lib/renderMarkdown.d.ts.map +1 -1
  70. package/lib/renderMarkdown.js +34 -6
  71. package/lib/speech/CustomAudioInputStream.d.ts.map +1 -1
  72. package/lib/speech/CustomAudioInputStream.js +40 -15
  73. package/lib/speech/bytesPerSample.d.ts.map +1 -1
  74. package/lib/speech/bytesPerSample.js +3 -1
  75. package/lib/speech/createAudioConfig.d.ts.map +1 -1
  76. package/lib/speech/createAudioConfig.js +9 -3
  77. package/lib/speech/createMicrophoneAudioConfigAndAudioContext.d.ts.map +1 -1
  78. package/lib/speech/createMicrophoneAudioConfigAndAudioContext.js +3 -1
  79. package/lib/speech/getUserMedia.d.ts.map +1 -1
  80. package/lib/speech/getUserMedia.js +5 -2
  81. package/package.json +43 -43
  82. package/src/AddFullBundle.tsx +0 -1
  83. package/src/FullComposer.tsx +2 -0
  84. package/src/adaptiveCards/Attachment/AdaptiveCardAttachment.tsx +3 -1
  85. package/src/adaptiveCards/Attachment/AdaptiveCardBuilder.ts +8 -3
  86. package/src/adaptiveCards/Attachment/AdaptiveCardRenderer.tsx +183 -89
  87. package/src/adaptiveCards/Attachment/AnimationCardContent.tsx +3 -1
  88. package/src/adaptiveCards/Attachment/AudioCardContent.tsx +3 -1
  89. package/src/adaptiveCards/Attachment/HeroCardContent.tsx +4 -2
  90. package/src/adaptiveCards/Attachment/OAuthCardContent.tsx +3 -1
  91. package/src/adaptiveCards/Attachment/ReceiptCardContent.tsx +28 -48
  92. package/src/adaptiveCards/Attachment/SignInCardContent.tsx +1 -1
  93. package/src/adaptiveCards/Attachment/ThumbnailCardContent.tsx +3 -1
  94. package/src/adaptiveCards/Attachment/VideoCardContent.tsx +5 -3
  95. package/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.ts +8 -0
  96. package/src/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.tsx +0 -1
  97. package/src/createCognitiveServicesSpeechServicesPonyfillFactory.spec.js +2 -3
  98. package/src/createDirectLineSpeechAdapters.ts +1 -1
  99. package/src/index-es5.ts +3 -26
  100. package/src/polyfill.ts +29 -0
  101. package/src/renderMarkdown.ts +40 -4
  102. package/src/speech/CustomAudioInputStream.ts +38 -7
  103. package/src/speech/bytesPerSample.ts +2 -0
  104. package/src/speech/createAudioConfig.spec.js +1 -1
  105. package/src/speech/createAudioConfig.ts +7 -0
  106. package/src/speech/createMicrophoneAudioConfigAndAudioContext.ts +2 -0
  107. package/src/speech/getUserMedia.ts +4 -1
  108. package/.eslintignore +0 -1
@@ -1,37 +1,65 @@
1
1
  /* eslint no-magic-numbers: ["error", { "ignore": [-1, 0, 2] }] */
2
2
 
3
- import { Action, OpenUrlAction, SubmitAction } from 'adaptivecards';
3
+ import {
4
+ Action as AdaptiveCardAction,
5
+ AdaptiveCard,
6
+ IMarkdownProcessingResult,
7
+ OpenUrlAction,
8
+ SubmitAction
9
+ } from 'adaptivecards';
4
10
  import { Components, getTabIndex, hooks } from 'botframework-webchat-component';
5
- import { DirectLineCardAction } from 'botframework-webchat-core';
6
11
  import classNames from 'classnames';
7
12
  import PropTypes from 'prop-types';
8
- import React, { useCallback, useEffect, useLayoutEffect, useRef, useState, VFC } from 'react';
13
+ import React, {
14
+ KeyboardEventHandler,
15
+ MouseEventHandler,
16
+ useCallback,
17
+ useEffect,
18
+ useLayoutEffect,
19
+ useRef,
20
+ useState,
21
+ VFC
22
+ } from 'react';
23
+ import type { DirectLineCardAction } from 'botframework-webchat-core';
9
24
 
25
+ import { BotFrameworkCardAction } from './AdaptiveCardBuilder';
10
26
  import useAdaptiveCardsHostConfig from '../hooks/useAdaptiveCardsHostConfig';
11
27
  import useAdaptiveCardsPackage from '../hooks/useAdaptiveCardsPackage';
12
- import { BotFrameworkCardAction } from './AdaptiveCardBuilder';
13
28
 
14
29
  const { ErrorBox } = Components;
15
30
  const { useDisabled, useLocalizer, usePerformCardAction, useRenderMarkdownAsHTML, useScrollToEnd, useStyleSet } = hooks;
16
31
 
17
- // eslint-disable-next-line no-undef
18
32
  const node_env = process.env.node_env || process.env.NODE_ENV;
19
33
 
20
- function addClass(element, className) {
21
- const classNames = new Set(element.className.split(' '));
34
+ type UndoFunction = (() => void) | undefined;
22
35
 
23
- if (!classNames.has(className)) {
24
- classNames.add(className);
36
+ function bunchUndos(...fns: UndoFunction[]): UndoFunction {
37
+ return () => fns.forEach(fn => fn?.());
38
+ }
25
39
 
26
- element.className = Array.from(classNames).join(' ');
40
+ /**
41
+ * Adds a class to the `HTMLElement`. Returns `true` if the class is added, otherwise, `undefined`.
42
+ */
43
+ function addClass(element: HTMLElement, className: string): true | undefined {
44
+ const { classList } = element;
45
+
46
+ if (!classList.contains(className)) {
47
+ classList.add(className);
27
48
 
28
49
  return true;
29
50
  }
30
-
31
- return false;
32
51
  }
33
52
 
34
- function addPersistentClassWithUndo(element, className) {
53
+ /**
54
+ * Adds a class to the `HTMLElement` and re-add on mutations.
55
+ *
56
+ * @returns {function} A function, when called, will restore to previous state.
57
+ */
58
+ function addPersistentClassWithUndo(element: HTMLElement | undefined, className: string): UndoFunction {
59
+ if (!element) {
60
+ return;
61
+ }
62
+
35
63
  if (addClass(element, className)) {
36
64
  // After we add the class, keep observing the element to make sure the class is not removed.
37
65
  const observer = new MutationObserver(() => addClass(element, className));
@@ -49,11 +77,27 @@ function addPersistentClassWithUndo(element, className) {
49
77
  }
50
78
  }
51
79
 
80
+ /**
81
+ * Returns `true`, if the object is a plain object and not a class, otherwise, `false`.
82
+ */
52
83
  function isPlainObject(obj) {
53
84
  return Object.getPrototypeOf(obj) === Object.prototype;
54
85
  }
55
86
 
56
- function setAttributeWithUndo(element, qualifiedName, nextValue) {
87
+ /**
88
+ * Sets an attribute.
89
+ *
90
+ * @returns {function} A function, when called, will restore to previous state.
91
+ */
92
+ function setAttributeWithUndo(
93
+ element: HTMLElement | undefined,
94
+ qualifiedName: string,
95
+ nextValue: string
96
+ ): UndoFunction {
97
+ if (!element) {
98
+ return;
99
+ }
100
+
57
101
  const value = element.getAttribute(qualifiedName);
58
102
 
59
103
  if (value !== nextValue) {
@@ -63,15 +107,29 @@ function setAttributeWithUndo(element, qualifiedName, nextValue) {
63
107
  }
64
108
  }
65
109
 
66
- const disabledHandler = event => {
110
+ /**
111
+ * An event handler for disabling event bubbling and propagation.
112
+ */
113
+ const disabledHandler = (event: Event) => {
67
114
  event.preventDefault();
68
115
  event.stopImmediatePropagation();
69
116
  event.stopPropagation();
70
117
  };
71
118
 
72
- function addEventListenerOnceWithUndo(element, name, handler) {
119
+ /**
120
+ * Listens to event once. Returns a function, when called, will stop listening.
121
+ */
122
+ function addEventListenerOnceWithUndo(
123
+ element: HTMLElement | undefined,
124
+ name: string,
125
+ handler: EventListener
126
+ ): UndoFunction {
127
+ if (!element) {
128
+ return;
129
+ }
130
+
73
131
  /* eslint-disable-next-line prefer-const */
74
- let detach;
132
+ let detach: () => void;
75
133
  const detachingHandler = event => {
76
134
  try {
77
135
  handler(event);
@@ -88,14 +146,34 @@ function addEventListenerOnceWithUndo(element, name, handler) {
88
146
  return detach;
89
147
  }
90
148
 
91
- function addEventListenerWithUndo(element, name, handler) {
149
+ /**
150
+ * Listens to event. Returns a function, when called, will stop listening.
151
+ */
152
+ function addEventListenerWithUndo(
153
+ element: HTMLElement | undefined,
154
+ name: string,
155
+ handler: EventListener
156
+ ): UndoFunction {
157
+ if (!element) {
158
+ return;
159
+ }
160
+
92
161
  element.addEventListener(name, handler);
93
162
 
94
163
  return () => element.removeEventListener(name, handler);
95
164
  }
96
165
 
97
- function disableElementWithUndo(element) {
98
- const undoStack = [];
166
+ /**
167
+ * Disables an element with undo function.
168
+ *
169
+ * @returns {function} A function, when called, will restore to previous state.
170
+ */
171
+ function disableElementWithUndo(element: HTMLElement | undefined): UndoFunction {
172
+ if (!element) {
173
+ return;
174
+ }
175
+
176
+ const undoStack: UndoFunction[] = [];
99
177
  const isActive = element === document.activeElement;
100
178
  const tag = element.nodeName.toLowerCase();
101
179
 
@@ -131,11 +209,23 @@ function disableElementWithUndo(element) {
131
209
  break;
132
210
  }
133
211
 
134
- return () => undoStack.forEach(undo => undo && undo());
212
+ return bunchUndos(...undoStack);
135
213
  }
136
214
 
137
- function disableInputElementsWithUndo(element: HTMLElement, observeSubtree = true) {
138
- const undoStack = [].map.call(element.querySelectorAll('button, input, select, textarea'), element =>
215
+ /**
216
+ * Disables all inputtable descendants.
217
+ *
218
+ * @param {HTMLElement | undefined} element Container element to start looking for inputtable descendants.
219
+ * @param {boolean} observeSubtree `true` to applies to all future inputtable descendants, otherwise, `false`.
220
+ *
221
+ * @returns {function} A function, when called, will restore to previous state.
222
+ */
223
+ function disableInputElementsWithUndo(element: HTMLElement | undefined, observeSubtree = true): UndoFunction {
224
+ if (!element) {
225
+ return;
226
+ }
227
+
228
+ const undoStack: (() => void)[] = [].map.call(element.querySelectorAll('button, input, select, textarea'), element =>
139
229
  disableElementWithUndo(element)
140
230
  );
141
231
 
@@ -157,18 +247,7 @@ function disableInputElementsWithUndo(element: HTMLElement, observeSubtree = tru
157
247
  undoStack.push(() => observer.disconnect());
158
248
  }
159
249
 
160
- return () => undoStack.forEach(undo => undo && undo());
161
- }
162
-
163
- /**
164
- * Checks if an element contains a class.
165
- *
166
- * @param {HTMLElement} element - The element to check for the class.
167
- * @param {string} className - The name of the class to check for.
168
- * @returns {boolean} `true` if the element contains the class, otherwise, `false`.
169
- */
170
- function containsClassName(element: HTMLElement, className: string): boolean {
171
- return (element.className || '').split(' ').includes(className);
250
+ return bunchUndos(...undoStack);
172
251
  }
173
252
 
174
253
  /**
@@ -177,7 +256,7 @@ function containsClassName(element: HTMLElement, className: string): boolean {
177
256
  * @returns {false | string} The value of the attribute. `false` if the attribute was not set.
178
257
  */
179
258
  function getAttribute(element: HTMLElement, qualifiedName: string): false | string {
180
- return element.hasAttribute(qualifiedName) && element.getAttribute(qualifiedName);
259
+ return !!element && element.hasAttribute(qualifiedName) && (element.getAttribute(qualifiedName) || '');
181
260
  }
182
261
 
183
262
  /**
@@ -187,11 +266,11 @@ function getAttribute(element: HTMLElement, qualifiedName: string): false | stri
187
266
  * @param {string} qualifiedName - The name of the attribute.
188
267
  * @param {false | string} value - The value of the attribute. When passing `false`, remove the attribute.
189
268
  */
190
- function setOrRemoveAttribute(element: HTMLElement, qualifiedName: string, value: false | string): void {
269
+ function setOrRemoveAttribute(element: HTMLElement | undefined, qualifiedName: string, value: false | string): void {
191
270
  if (value === false) {
192
- element.removeAttribute(qualifiedName);
271
+ element?.removeAttribute(qualifiedName);
193
272
  } else {
194
- element.setAttribute(qualifiedName, value);
273
+ element?.setAttribute(qualifiedName, value);
195
274
  }
196
275
  }
197
276
 
@@ -204,7 +283,15 @@ function setOrRemoveAttribute(element: HTMLElement, qualifiedName: string, value
204
283
  *
205
284
  * @returns {() => void} The undo function, when called, will undo all manipulations by restoring values recorded at the time of the function call.
206
285
  */
207
- function setOrRemoveAttributeWithUndo(element: HTMLElement, qualifiedName: string, value: false | string): () => void {
286
+ function setOrRemoveAttributeWithUndo(
287
+ element: HTMLElement | undefined,
288
+ qualifiedName: string,
289
+ value: false | string
290
+ ): UndoFunction {
291
+ if (!element) {
292
+ return;
293
+ }
294
+
208
295
  const prevValue = getAttribute(element, qualifiedName);
209
296
 
210
297
  setOrRemoveAttribute(element, qualifiedName, value);
@@ -221,14 +308,12 @@ function setOrRemoveAttributeWithUndo(element: HTMLElement, qualifiedName: strin
221
308
  * @returns {HTMLElement | undefined} The first ancestor that fulfill the predicate, otherwise, `undefined`.
222
309
  */
223
310
  function findAncestor(element: HTMLElement, predicate: (ancestor: HTMLElement) => boolean): HTMLElement | undefined {
224
- let current = element.parentElement;
311
+ let current = element;
225
312
 
226
- while (current) {
313
+ while ((current = current.parentElement)) {
227
314
  if (predicate.call(element, current)) {
228
315
  return current;
229
316
  }
230
-
231
- current = current.parentElement;
232
317
  }
233
318
  }
234
319
 
@@ -244,15 +329,15 @@ function findAncestor(element: HTMLElement, predicate: (ancestor: HTMLElement) =
244
329
  * @returns {() => void} The undo function, when called, will undo all manipulations by restoring values recorded at the time of the function call.
245
330
  */
246
331
  function indicateActionSelectionWithUndo(
247
- selectedActionElements: HTMLElement[],
332
+ selectedActionElements: HTMLElement[] | undefined,
248
333
  actionPerformedClassName?: string
249
- ): (() => void) | undefined {
250
- if (!selectedActionElements.length) {
334
+ ): UndoFunction {
335
+ if (!selectedActionElements?.length) {
251
336
  return;
252
337
  }
253
338
 
254
339
  // Verify all input elements are "ac-pushButton", could belongs to ActionSet or "card actions".
255
- if (selectedActionElements.some(actionElement => !containsClassName(actionElement, 'ac-pushButton'))) {
340
+ if (selectedActionElements.some(actionElement => !actionElement.classList.contains('ac-pushButton'))) {
256
341
  console.warn(
257
342
  'botframework-webchat: Cannot mark selected action in the card, some elements are not an "ac-pushButton".'
258
343
  );
@@ -299,7 +384,7 @@ function indicateActionSelectionWithUndo(
299
384
  );
300
385
  });
301
386
 
302
- return () => undoStack.forEach(undo => undo());
387
+ return bunchUndos(...undoStack);
303
388
  }
304
389
 
305
390
  /**
@@ -307,21 +392,21 @@ function indicateActionSelectionWithUndo(
307
392
  *
308
393
  * @returns {() => void} The undo function, when called, will undo all manipulations by restoring values recorded at the time of the function call.
309
394
  */
310
- function fixAccessibilityIssuesWithUndo(element: HTMLElement): () => void {
311
- // These hacks should be done in Adaptive Cards library instead.
312
- const undoStack: (() => void)[] = [];
395
+ function fixAccessibilityIssuesWithUndo(element: HTMLElement): UndoFunction {
396
+ if (!element) {
397
+ return;
398
+ }
313
399
 
400
+ // These hacks should be done in Adaptive Cards library instead.
314
401
  // Related to #3949: All action buttons inside role="menubar" should be role="menuitem".
315
- undoStack.push(
316
- ...Array.from(element.querySelectorAll('.ac-actionSet[role="menubar"] [role="button"]')).map(actionButton =>
317
- setAttributeWithUndo(actionButton, 'role', 'menuitem')
318
- )
319
- );
402
+ const undoStack: UndoFunction[] = Array.from(
403
+ element.querySelectorAll('.ac-actionSet[role="menubar"] [role="button"]') as NodeListOf<HTMLElement>
404
+ ).map(actionButton => setAttributeWithUndo(actionButton, 'role', 'menuitem'));
320
405
 
321
- return () => undoStack.forEach(undo => undo());
406
+ return () => undoStack.forEach(undo => undo?.());
322
407
  }
323
408
 
324
- function getFocusableElements(element) {
409
+ function getFocusableElements(element: HTMLElement) {
325
410
  return [].filter.call(
326
411
  element.querySelectorAll(
327
412
  [
@@ -338,7 +423,7 @@ function getFocusableElements(element) {
338
423
  'textarea',
339
424
  '[tabindex]'
340
425
  ].join(', ')
341
- ),
426
+ ) as NodeListOf<HTMLElement>,
342
427
  element => {
343
428
  const tabIndex = getTabIndex(element);
344
429
 
@@ -347,49 +432,55 @@ function getFocusableElements(element) {
347
432
  );
348
433
  }
349
434
 
350
- function restoreActiveElementIndex(element, activeElementIndex) {
351
- const focusable = getFocusableElements(element)[activeElementIndex];
352
-
353
- focusable && focusable.focus();
435
+ function restoreActiveElementIndex(element: HTMLElement, activeElementIndex: number) {
436
+ getFocusableElements(element)[+activeElementIndex]?.focus();
354
437
  }
355
438
 
356
- function saveActiveElementIndex(element) {
439
+ function saveActiveElementIndex(element: HTMLElement) {
357
440
  return getFocusableElements(element).indexOf(document.activeElement);
358
441
  }
359
442
 
360
- function restoreInputValues(element, inputValues) {
361
- const inputs = element.querySelectorAll('input, select, textarea');
443
+ function restoreInputValues(element: HTMLElement, inputValues: (boolean | string)[]) {
444
+ const inputs = element.querySelectorAll('input, select, textarea') as NodeListOf<
445
+ HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
446
+ >;
362
447
 
363
- [].forEach.call(inputs, (input, index) => {
364
- const value = inputValues[index];
448
+ [].forEach.call(inputs, (input: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, index: number) => {
449
+ const value = inputValues[+index];
365
450
 
366
451
  if (typeof value !== 'undefined') {
367
452
  const { tagName, type } = input;
368
453
 
369
454
  if (tagName === 'INPUT' && (type === 'checkbox' || type === 'radio')) {
370
- input.checked = value;
371
- } else {
455
+ if (typeof value === 'boolean') {
456
+ (input as HTMLInputElement).checked = value;
457
+ }
458
+ } else if (typeof value === 'string') {
372
459
  input.value = value;
373
460
  }
374
461
  }
375
462
  });
376
463
  }
377
464
 
378
- function saveInputValues(element) {
379
- const inputs = element.querySelectorAll('input, select, textarea');
465
+ function saveInputValues(element: HTMLElement): (boolean | string)[] {
466
+ const inputs = element.querySelectorAll('input, select, textarea') as NodeListOf<
467
+ HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
468
+ >;
469
+
470
+ return [].map.call(inputs, (input: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement) => {
471
+ const { type } = input;
380
472
 
381
- return [].map.call(inputs, ({ checked, tagName, type, value }) => {
382
- if (tagName === 'INPUT' && (type === 'checkbox' || type === 'radio')) {
383
- return checked;
473
+ if (input.tagName === 'INPUT' && (type === 'checkbox' || type === 'radio')) {
474
+ return (input as HTMLInputElement).checked;
384
475
  }
385
476
 
386
- return value;
477
+ return input.value;
387
478
  });
388
479
  }
389
480
 
390
481
  type AdaptiveCardRendererProps = {
391
482
  actionPerformedClassName?: string;
392
- adaptiveCard: any;
483
+ adaptiveCard: AdaptiveCard;
393
484
  disabled?: boolean;
394
485
  tapAction?: DirectLineCardAction;
395
486
  };
@@ -402,7 +493,7 @@ const AdaptiveCardRenderer: VFC<AdaptiveCardRendererProps> = ({
402
493
  }) => {
403
494
  const [{ adaptiveCardRenderer: adaptiveCardRendererStyleSet }] = useStyleSet();
404
495
  const [{ GlobalSettings, HostConfig }] = useAdaptiveCardsPackage();
405
- const [actionsPerformed, setActionsPerformed] = useState([]);
496
+ const [actionsPerformed, setActionsPerformed] = useState<AdaptiveCardAction[]>([]);
406
497
  const [adaptiveCardsHostConfig] = useAdaptiveCardsHostConfig();
407
498
  const [disabledFromComposer] = useDisabled();
408
499
  const [errors, setErrors] = useState([]);
@@ -410,7 +501,7 @@ const AdaptiveCardRenderer: VFC<AdaptiveCardRendererProps> = ({
410
501
  const activeElementIndexRef = useRef(-1);
411
502
  const adaptiveCardElementRef = useRef<HTMLElement>();
412
503
  const contentRef = useRef<HTMLDivElement>();
413
- const inputValuesRef = useRef([]);
504
+ const inputValuesRef = useRef<(boolean | string)[]>([]);
414
505
  const localize = useLocalizer();
415
506
  const performCardAction = usePerformCardAction();
416
507
  const renderMarkdownAsHTML = useRenderMarkdownAsHTML();
@@ -421,8 +512,9 @@ const AdaptiveCardRenderer: VFC<AdaptiveCardRendererProps> = ({
421
512
  // TODO: [P2] #3199 We should consider using `adaptiveCard.selectAction` instead.
422
513
  // The null check for "tapAction" is in "handleClickAndKeyPressForTapAction".
423
514
  const handleClickAndKeyPress = useCallback(
424
- event => {
425
- const { key, target, type } = event;
515
+ (event: KeyboardEvent | MouseEvent): void => {
516
+ const { key, type } = event as KeyboardEvent;
517
+ const target = event.target as HTMLDivElement;
426
518
 
427
519
  // Some items, e.g. tappable text, cannot be disabled thru DOM attributes
428
520
  const { current } = contentRef;
@@ -466,12 +558,13 @@ const AdaptiveCardRenderer: VFC<AdaptiveCardRendererProps> = ({
466
558
  const handleClickAndKeyPressForTapAction = !disabled && tapAction ? handleClickAndKeyPress : undefined;
467
559
 
468
560
  const addActionsPerformed = useCallback(
469
- action => !~actionsPerformed.indexOf(action) && setActionsPerformed([...actionsPerformed, action]),
561
+ (action: AdaptiveCardAction): void =>
562
+ !~actionsPerformed.indexOf(action) && setActionsPerformed([...actionsPerformed, action]),
470
563
  [actionsPerformed, setActionsPerformed]
471
564
  );
472
565
 
473
566
  const handleExecuteAction = useCallback(
474
- (action: Action) => {
567
+ (action: AdaptiveCardAction): void => {
475
568
  // Some items, e.g. tappable image, cannot be disabled thru DOM attributes
476
569
  if (disabled) {
477
570
  return;
@@ -541,7 +634,9 @@ const AdaptiveCardRenderer: VFC<AdaptiveCardRendererProps> = ({
541
634
  // This could be limitations from Adaptive Cards package (not supported as of 1.2.5)
542
635
  // Because there could be timing difference between .parse and .render, we could be using wrong Markdown engine
543
636
 
544
- adaptiveCard.constructor.onProcessMarkdown = (text, result) => {
637
+ // "onProcessMarkdown" is a static function but we are trying to scope it to the current object instead.
638
+ // eslint-disable-next-line dot-notation
639
+ adaptiveCard.constructor['onProcessMarkdown'] = (text: string, result: IMarkdownProcessingResult) => {
545
640
  if (renderMarkdownAsHTML) {
546
641
  result.outputHtml = renderMarkdownAsHTML(text);
547
642
  result.didProcess = true;
@@ -563,7 +658,7 @@ const AdaptiveCardRenderer: VFC<AdaptiveCardRendererProps> = ({
563
658
  return setErrors(validationEvents.reduce((items, { message }) => [...items, new Error(message)], []));
564
659
  }
565
660
 
566
- let element;
661
+ let element: HTMLElement;
567
662
 
568
663
  try {
569
664
  element = adaptiveCard.render();
@@ -642,8 +737,8 @@ const AdaptiveCardRenderer: VFC<AdaptiveCardRendererProps> = ({
642
737
  ) : (
643
738
  <div
644
739
  className={classNames(adaptiveCardRendererStyleSet + '', 'webchat__adaptive-card-renderer')}
645
- onClick={handleClickAndKeyPressForTapAction}
646
- onKeyPress={handleClickAndKeyPressForTapAction}
740
+ onClick={handleClickAndKeyPressForTapAction as unknown as MouseEventHandler<HTMLDivElement>}
741
+ onKeyPress={handleClickAndKeyPressForTapAction as unknown as KeyboardEventHandler<HTMLDivElement>}
647
742
  ref={contentRef}
648
743
  />
649
744
  );
@@ -661,7 +756,6 @@ AdaptiveCardRenderer.propTypes = {
661
756
  disabled: PropTypes.bool,
662
757
 
663
758
  // TypeScript class is not mappable to PropTypes.func
664
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
665
759
  // @ts-ignore
666
760
  tapAction: PropTypes.shape({
667
761
  image: PropTypes.string,
@@ -1,9 +1,9 @@
1
1
  /* eslint react/no-array-index-key: "off" */
2
2
 
3
- import { DirectLineAnimationCard } from 'botframework-webchat-core';
4
3
  import { Components, hooks } from 'botframework-webchat-component';
5
4
  import PropTypes from 'prop-types';
6
5
  import React, { FC } from 'react';
6
+ import type { DirectLineAnimationCard } from 'botframework-webchat-core';
7
7
 
8
8
  import CommonCard from './CommonCard';
9
9
 
@@ -41,6 +41,8 @@ AnimationCardContent.defaultProps = {
41
41
 
42
42
  AnimationCardContent.propTypes = {
43
43
  actionPerformedClassName: PropTypes.string,
44
+ // PropTypes cannot fully capture TypeScript types.
45
+ // @ts-ignore
44
46
  content: PropTypes.shape({
45
47
  media: PropTypes.arrayOf(
46
48
  PropTypes.shape({
@@ -1,9 +1,9 @@
1
1
  /* eslint react/no-array-index-key: "off" */
2
2
 
3
- import { DirectLineAudioCard } from 'botframework-webchat-core';
4
3
  import { Components, hooks } from 'botframework-webchat-component';
5
4
  import PropTypes from 'prop-types';
6
5
  import React, { FC } from 'react';
6
+ import type { DirectLineAudioCard } from 'botframework-webchat-core';
7
7
 
8
8
  import CommonCard from './CommonCard';
9
9
 
@@ -41,6 +41,8 @@ AudioCardContent.defaultProps = {
41
41
 
42
42
  AudioCardContent.propTypes = {
43
43
  actionPerformedClassName: PropTypes.string,
44
+ // PropTypes cannot fully capture TypeScript types.
45
+ // @ts-ignore
44
46
  content: PropTypes.shape({
45
47
  autostart: PropTypes.bool,
46
48
  autoloop: PropTypes.bool,
@@ -1,7 +1,7 @@
1
- import { DirectLineHeroCard } from 'botframework-webchat-core';
2
1
  import { hooks } from 'botframework-webchat-component';
3
2
  import PropTypes from 'prop-types';
4
3
  import React, { FC, useMemo } from 'react';
4
+ import type { DirectLineHeroCard } from 'botframework-webchat-core';
5
5
 
6
6
  import AdaptiveCardBuilder from './AdaptiveCardBuilder';
7
7
  import AdaptiveCardRenderer from './AdaptiveCardRenderer';
@@ -50,10 +50,12 @@ HeroCardContent.defaultProps = {
50
50
 
51
51
  HeroCardContent.propTypes = {
52
52
  actionPerformedClassName: PropTypes.string,
53
+ // PropTypes cannot fully capture TypeScript types.
54
+ // @ts-ignore
53
55
  content: PropTypes.shape({
54
56
  images: PropTypes.arrayOf(
55
57
  PropTypes.shape({
56
- alt: PropTypes.string,
58
+ alt: PropTypes.string.isRequired,
57
59
  tap: PropTypes.any,
58
60
  url: PropTypes.string.isRequired
59
61
  })
@@ -1,7 +1,7 @@
1
- import { DirectLineOAuthCard } from 'botframework-webchat-core';
2
1
  import { hooks } from 'botframework-webchat-component';
3
2
  import PropTypes from 'prop-types';
4
3
  import React, { FC, useMemo } from 'react';
4
+ import type { DirectLineOAuthCard } from 'botframework-webchat-core';
5
5
 
6
6
  import AdaptiveCardBuilder from './AdaptiveCardBuilder';
7
7
  import AdaptiveCardRenderer from './AdaptiveCardRenderer';
@@ -48,6 +48,8 @@ OAuthCardContent.defaultProps = {
48
48
 
49
49
  OAuthCardContent.propTypes = {
50
50
  actionPerformedClassName: PropTypes.string,
51
+ // PropTypes cannot fully capture TypeScript types.
52
+ // @ts-ignore
51
53
  content: PropTypes.shape({
52
54
  buttons: PropTypes.array
53
55
  }).isRequired,