@elliemae/ds-chat 2.0.0-next.9 → 2.0.0-rc.12

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 (111) hide show
  1. package/cjs/ChatDataTestids.js +27 -0
  2. package/cjs/parts/bubble/ChatBubble.js +9 -6
  3. package/cjs/parts/bubble/ChatBubbleArrow.js +64 -61
  4. package/cjs/parts/bubble/props.js +1 -1
  5. package/cjs/parts/bubble/styled.js +1 -1
  6. package/cjs/parts/chat-composer/ChatContainerComposer.js +14 -7
  7. package/cjs/parts/chat-composer/props.js +4 -0
  8. package/cjs/parts/chat-composer/styled.js +3 -3
  9. package/cjs/parts/chat-container/ChatContainer.js +67 -20
  10. package/cjs/parts/chat-container/config/useValidateProps.js +2 -2
  11. package/cjs/parts/chat-container/props.js +7 -3
  12. package/cjs/parts/chat-container/styled.js +1 -1
  13. package/cjs/parts/chat-container-header/ChatContainerHeader.js +3 -3
  14. package/cjs/parts/chat-container-header/helpers.js +31 -0
  15. package/cjs/parts/chat-container-header/styled.js +6 -6
  16. package/cjs/parts/chat-container-messages-list/ChatContainerMessagesList.js +151 -35
  17. package/cjs/parts/chat-container-messages-list/config/useValidateProps.js +2 -2
  18. package/cjs/parts/chat-container-messages-list/props.js +4 -2
  19. package/cjs/parts/chat-container-messages-list/styled.js +2 -2
  20. package/cjs/parts/chat-empty-state/ChatEmptyState.js +2 -3
  21. package/cjs/parts/chat-sidebar/SideBarChat.js +57 -29
  22. package/cjs/parts/chat-sidebar/props.js +11 -1
  23. package/cjs/parts/chat-sidebar/styled.js +2 -2
  24. package/cjs/parts/floating-button/FloatingButton.js +18 -10
  25. package/cjs/parts/floating-button/props.js +6 -2
  26. package/cjs/parts/sidebar-button/SidebarButton.js +5 -0
  27. package/cjs/parts/sidebar-button/props.js +2 -3
  28. package/cjs/parts/system-message/style.js +1 -1
  29. package/cjs/parts/tile-button/TileButton.js +30 -27
  30. package/cjs/parts/tile-button/props.js +12 -8
  31. package/cjs/parts/tile-button/styled.js +11 -4
  32. package/esm/ChatDataTestids.js +23 -0
  33. package/esm/parts/bubble/ChatBubble.js +8 -5
  34. package/esm/parts/bubble/ChatBubbleArrow.js +64 -61
  35. package/esm/parts/bubble/props.js +1 -1
  36. package/esm/parts/bubble/styled.js +1 -1
  37. package/esm/parts/chat-composer/ChatContainerComposer.js +13 -5
  38. package/esm/parts/chat-composer/props.js +4 -0
  39. package/esm/parts/chat-composer/styled.js +1 -1
  40. package/esm/parts/chat-container/ChatContainer.js +65 -18
  41. package/esm/parts/chat-container/config/useValidateProps.js +2 -2
  42. package/esm/parts/chat-container/props.js +7 -3
  43. package/esm/parts/chat-container/styled.js +1 -1
  44. package/esm/parts/chat-container-header/ChatContainerHeader.js +3 -2
  45. package/esm/parts/chat-container-header/helpers.js +23 -0
  46. package/esm/parts/chat-container-header/styled.js +6 -6
  47. package/esm/parts/chat-container-messages-list/ChatContainerMessagesList.js +149 -33
  48. package/esm/parts/chat-container-messages-list/config/useValidateProps.js +2 -2
  49. package/esm/parts/chat-container-messages-list/props.js +4 -2
  50. package/esm/parts/chat-container-messages-list/styled.js +2 -2
  51. package/esm/parts/chat-empty-state/ChatEmptyState.js +1 -1
  52. package/esm/parts/chat-sidebar/SideBarChat.js +57 -28
  53. package/esm/parts/chat-sidebar/props.js +11 -1
  54. package/esm/parts/chat-sidebar/styled.js +2 -2
  55. package/esm/parts/floating-button/FloatingButton.js +18 -9
  56. package/esm/parts/floating-button/props.js +6 -2
  57. package/esm/parts/sidebar-button/SidebarButton.js +5 -0
  58. package/esm/parts/sidebar-button/props.js +1 -1
  59. package/esm/parts/system-message/style.js +1 -1
  60. package/esm/parts/tile-button/TileButton.js +31 -26
  61. package/esm/parts/tile-button/props.js +11 -3
  62. package/esm/parts/tile-button/styled.js +11 -6
  63. package/package.json +28 -6
  64. package/types/ChatDataTestids.d.ts +21 -0
  65. package/types/parts/bubble/ChatBubble.d.ts +18 -5
  66. package/types/parts/bubble/props.d.ts +13 -4
  67. package/types/parts/bubble/styled.d.ts +9 -9
  68. package/types/parts/bubble/tests/ChatBubble.test.d.ts +1 -0
  69. package/types/parts/chat-card/ChatCard.d.ts +24 -4
  70. package/types/parts/chat-card/props.d.ts +19 -3
  71. package/types/parts/chat-card/styled.d.ts +6 -6
  72. package/types/parts/chat-composer/ChatContainerComposer.d.ts +48 -13
  73. package/types/parts/chat-composer/styled.d.ts +117 -24
  74. package/types/parts/chat-composer/tests/ChatContainerComposer.test.d.ts +1 -0
  75. package/types/parts/chat-container/ChatContainer.d.ts +54 -13
  76. package/types/parts/chat-container/config/useValidateProps.d.ts +1 -1
  77. package/types/parts/chat-container/styled.d.ts +4 -4
  78. package/types/parts/chat-container/tests/ChatContainer.test.d.ts +1 -0
  79. package/types/parts/chat-container-header/helpers.d.ts +6 -0
  80. package/types/parts/chat-container-header/styled.d.ts +3 -3
  81. package/types/parts/chat-container-messages-list/ChatContainerMessagesList.d.ts +39 -9
  82. package/types/parts/chat-container-messages-list/config/useValidateProps.d.ts +1 -1
  83. package/types/parts/chat-container-messages-list/styled.d.ts +7 -7
  84. package/types/parts/chat-empty-state/ChatEmptyState.d.ts +12 -3
  85. package/types/parts/chat-empty-state/props.d.ts +7 -2
  86. package/types/parts/chat-empty-state/styled.d.ts +2 -2
  87. package/types/parts/chat-sidebar/SideBarChat.d.ts +39 -9
  88. package/types/parts/chat-sidebar/props.d.ts +39 -9
  89. package/types/parts/chat-sidebar/styled.d.ts +2 -2
  90. package/types/parts/floating-button/FloatingButton.d.ts +11 -2
  91. package/types/parts/floating-button/props.d.ts +13 -1
  92. package/types/parts/floating-button/styled.d.ts +1 -1
  93. package/types/parts/floating-container/styled.d.ts +1 -2
  94. package/types/parts/grid-influencer/styled.d.ts +2 -2
  95. package/types/parts/message-delimiter/MessageDelimiter.d.ts +21 -4
  96. package/types/parts/message-delimiter/props.d.ts +16 -3
  97. package/types/parts/message-delimiter/styled.d.ts +3 -3
  98. package/types/parts/sidebar-button/SidebarButton.d.ts +16 -5
  99. package/types/parts/sidebar-button/props.d.ts +16 -5
  100. package/types/parts/sidebar-button/styled.d.ts +3 -3
  101. package/types/parts/system-message/SystemMessage.d.ts +12 -2
  102. package/types/parts/system-message/props.d.ts +7 -1
  103. package/types/parts/system-message/style.d.ts +5 -5
  104. package/types/parts/tile-button/TileButton.d.ts +66 -17
  105. package/types/parts/tile-button/props.d.ts +64 -16
  106. package/types/parts/tile-button/styled.d.ts +9 -8
  107. package/types/prop-types.d.ts +28 -9
  108. package/types/tests/utils.d.ts +27 -0
  109. package/types/parts/chat-composer/props.d.ts +0 -35
  110. package/types/parts/chat-container/props.d.ts +0 -39
  111. package/types/parts/chat-container-messages-list/props.d.ts +0 -23
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ require('core-js/modules/esnext.async-iterator.map.js');
6
+ require('core-js/modules/esnext.iterator.map.js');
7
+ require('core-js/modules/esnext.async-iterator.filter.js');
8
+ require('core-js/modules/esnext.iterator.constructor.js');
9
+ require('core-js/modules/esnext.iterator.filter.js');
10
+ require('core-js/modules/esnext.async-iterator.constructor.js');
11
+ require('core-js/modules/esnext.async-iterator.to-array.js');
12
+ require('core-js/modules/esnext.iterator.to-array.js');
13
+ var React = require('react');
14
+
15
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
16
+
17
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
18
+
19
+ const validHeaderChilds = children => React__default["default"].Children.toArray(children).filter(e => {
20
+ if (Array.isArray(e.props.children)) {
21
+ return false;
22
+ }
23
+
24
+ if (e.props.children === undefined && e.$$typeof.toString() === 'Symbol(react.element)') {
25
+ return true;
26
+ }
27
+
28
+ return !!e.props.children;
29
+ }).map(() => '32px');
30
+
31
+ exports.validHeaderChilds = validHeaderChilds;
@@ -9,15 +9,15 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
9
9
 
10
10
  var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled);
11
11
 
12
- const StyledChatContainerContentHeader = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
12
+ const StyledChatContainerContentHeaderActions = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
13
13
  componentId: "sc-jmynvr-0"
14
- })(["width:100%;min-height:48px;border-bottom:1px solid ", ";background:", ";"], props => props.theme.colors.neutral['200'], props => props.theme.colors.neutral['050']);
15
- const StyledChatContainerContentHeaderLabel = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
14
+ })(["max-width:80px;"]);
15
+ const StyledChatContainerContentHeader = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
16
16
  componentId: "sc-jmynvr-1"
17
- })(["justify-content:center;align-items:center;font-weight:bold;font-size:18px;color:", ";"], props => props.theme.colors.neutral['700']);
18
- const StyledChatContainerContentHeaderActions = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
17
+ })(["width:100%;min-height:48px;border-bottom:1px solid ", ";background:", ";", "{& button{background:transparent;}}"], props => props.theme.colors.neutral['200'], props => props.theme.colors.neutral['050'], StyledChatContainerContentHeaderActions);
18
+ const StyledChatContainerContentHeaderLabel = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
19
19
  componentId: "sc-jmynvr-2"
20
- })(["max-width:80px;"]);
20
+ })(["justify-content:center;align-items:center;font-weight:bold;font-size:18px;color:", ";"], props => props.theme.colors.neutral['700']);
21
21
 
22
22
  exports.StyledChatContainerContentHeader = StyledChatContainerContentHeader;
23
23
  exports.StyledChatContainerContentHeaderActions = StyledChatContainerContentHeaderActions;
@@ -4,10 +4,21 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _jsx = require('@babel/runtime/helpers/jsx');
6
6
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
7
+ require('core-js/modules/esnext.async-iterator.some.js');
8
+ require('core-js/modules/esnext.iterator.constructor.js');
9
+ require('core-js/modules/esnext.iterator.some.js');
10
+ require('core-js/modules/esnext.async-iterator.for-each.js');
11
+ require('core-js/modules/esnext.iterator.for-each.js');
12
+ require('core-js/modules/esnext.async-iterator.map.js');
13
+ require('core-js/modules/esnext.iterator.map.js');
14
+ require('core-js/modules/esnext.async-iterator.find.js');
15
+ require('core-js/modules/esnext.iterator.find.js');
16
+ require('core-js/modules/esnext.async-iterator.filter.js');
17
+ require('core-js/modules/esnext.iterator.filter.js');
7
18
  var React = require('react');
8
19
  var reactDesc = require('react-desc');
9
20
  var reactVirtual = require('react-virtual');
10
- var DSButton = require('@elliemae/ds-basic/Button');
21
+ var DSButton = require('@elliemae/ds-button');
11
22
  var ChatBubble = require('../bubble/ChatBubble.js');
12
23
  var props$1 = require('../bubble/props.js');
13
24
  var MessageDelimiter = require('../message-delimiter/MessageDelimiter.js');
@@ -28,27 +39,35 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
28
39
 
29
40
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
30
41
 
31
- const getPadding = hasMoreItems => {
42
+ const getPadding = _ref => {
43
+ let {
44
+ hasMoreItems,
45
+ bannerPosition,
46
+ isLoading
47
+ } = _ref;
32
48
  const padding = {
33
49
  paddingStart: 0,
34
50
  paddingEnd: -5
35
51
  };
36
- if (hasMoreItems === 'top') padding.paddingStart = 42;else if (hasMoreItems === 'bottom') padding.paddingEnd = 42;
52
+ if ([hasMoreItems, bannerPosition, isLoading].some(item => item === 'top')) padding.paddingStart = 42;else if ([hasMoreItems, bannerPosition, isLoading].some(item => item === 'bottom')) padding.paddingEnd = 42;
37
53
  return padding;
38
54
  };
39
55
 
40
- const ChatContainerMessagesList = props => {
41
- useValidateProps.useValidateProps(props, ChatContainerMessagesListWithSchema.toTypescript());
56
+ const ChatContainerMessagesList = props$2 => {
57
+ useValidateProps.useValidateProps(props$2, props.listProps);
42
58
  const {
43
59
  sendingText,
60
+ bannerPosition,
44
61
  sendingMessages,
45
62
  messages,
46
63
  actionRef,
47
64
  onScrollEnds,
48
65
  getMoreMessages,
49
66
  hasMoreItems,
50
- isLoading
51
- } = props;
67
+ isLoading,
68
+ bannerRef
69
+ } = props$2;
70
+ const loadMoreRef = React__default["default"].useRef(null);
52
71
  const virtualListRef = React__default["default"].useRef(); // estimateSize should not be really required given what was stated on
53
72
  // https://github.com/tannerlinsley/react-virtual/issues/23
54
73
 
@@ -60,71 +79,88 @@ const ChatContainerMessagesList = props => {
60
79
  size: messages.length,
61
80
  parentRef: virtualListRef,
62
81
  overscan: 15
63
- }, getPadding(hasMoreItems)), {}, {
82
+ }, getPadding({
83
+ hasMoreItems,
84
+ bannerPosition,
85
+ isLoading
86
+ })), {}, {
64
87
  estimateSize: React__default["default"].useCallback(() => 80, [])
65
88
  }));
66
89
  const onScrollStop = React__default["default"].useCallback(() => {
90
+ var _virtualListRef$curre;
91
+
67
92
  const {
68
93
  bottom,
69
94
  top
70
- } = virtualListRef.current.getBoundingClientRect();
95
+ } = (_virtualListRef$curre = virtualListRef.current) === null || _virtualListRef$curre === void 0 ? void 0 : _virtualListRef$curre.getBoundingClientRect();
71
96
  const list = virtualListRef.current.querySelectorAll('[data-element="chat-element-list-item"]');
72
97
  const indexList = [];
73
98
  list.forEach(item => {
74
99
  const {
75
- top: itemTop
100
+ top: itemTop,
101
+ bottom: itemBottom
76
102
  } = item.getBoundingClientRect();
77
- if (itemTop < bottom && itemTop > top) indexList.push(item.dataset.index);
103
+ const itemPadding = 10;
104
+ if (itemTop + itemPadding < bottom && itemBottom - itemPadding > top) indexList.push(item.dataset.index);
78
105
  });
79
106
  if (onScrollEnds) onScrollEnds(indexList);
80
107
  return indexList;
81
108
  }, [onScrollEnds]);
82
- const scrollAndFocus = React__default["default"].useCallback(index => {
83
- vScroll(index, {
84
- align: 'center'
85
- });
109
+ const onlyFocus = React__default["default"].useCallback(index => {
86
110
  setTimeout(() => {
87
111
  virtualListRef.current.querySelector("[data-index=\"".concat(index, "\"]")).focus();
88
112
  }, 300);
89
- }, [vScroll]);
113
+ }, []);
114
+ const scrollAndFocus = React__default["default"].useCallback(function (index) {
115
+ let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
116
+ align: 'center'
117
+ };
118
+ vScroll(index, b);
119
+ onlyFocus(index);
120
+ }, [onlyFocus, vScroll]);
90
121
  React__default["default"].useEffect(() => {
91
122
  if (actionRef && actionRef.current) {
92
- actionRef.current.scrollToIndex = (a, b = {
93
- align: 'center'
94
- }) => {
123
+ actionRef.current.scrollToIndex = function (a) {
124
+ let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
125
+ align: 'center'
126
+ };
95
127
  vScroll(a, b);
96
128
  };
97
129
 
98
130
  actionRef.current.getMessagesInView = onScrollStop;
99
131
 
100
- actionRef.current.focusToIndex = (a, b = {
101
- align: 'center'
102
- }) => {
103
- scrollAndFocus(a);
132
+ actionRef.current.focusToIndex = function (a) {
133
+ let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
134
+ align: 'center'
135
+ };
136
+ scrollAndFocus(a, b);
104
137
  };
105
138
 
106
- actionRef.current.focusToList = (a, b = {
107
- align: 'center'
108
- }) => {
109
- var _virtualListRef$curre;
139
+ actionRef.current.focusToIndexWithoutScroll = onlyFocus;
140
+
141
+ actionRef.current.focusToList = a => {
142
+ var _virtualListRef$curre2;
110
143
 
111
- (_virtualListRef$curre = virtualListRef.current) === null || _virtualListRef$curre === void 0 ? void 0 : _virtualListRef$curre.focus();
144
+ (_virtualListRef$curre2 = virtualListRef.current) === null || _virtualListRef$curre2 === void 0 ? void 0 : _virtualListRef$curre2.focus();
112
145
  };
113
146
  }
114
- }, [actionRef, onScrollStop, scrollAndFocus, vScroll]);
147
+ }, [actionRef, onScrollStop, onlyFocus, scrollAndFocus, vScroll]);
115
148
  const handleKey = React__default["default"].useCallback(e => {
116
- e.preventDefault();
117
149
  const {
118
150
  key
119
151
  } = e;
120
152
  const index = Number(e.currentTarget.dataset.index);
153
+ e.stopPropagation();
121
154
 
122
155
  switch (key) {
123
156
  case 'ArrowUp':
157
+ e.preventDefault();
124
158
  if (index > 0) virtualListRef.current.querySelector("[data-index=\"".concat(index - 1, "\"]")).focus();
125
159
  break;
126
160
 
127
161
  case 'ArrowDown':
162
+ e.preventDefault();
163
+
128
164
  if (index < messages.length - 1) {
129
165
  virtualListRef.current.querySelector("[data-index=\"".concat(index + 1, "\"]")).focus();
130
166
  }
@@ -132,18 +168,96 @@ const ChatContainerMessagesList = props => {
132
168
  break;
133
169
 
134
170
  case 'Home':
171
+ e.preventDefault();
135
172
  scrollAndFocus(0);
136
173
  break;
137
174
 
138
175
  case 'End':
176
+ e.preventDefault();
139
177
  scrollAndFocus(messages.length - 1);
140
178
  break;
141
179
 
142
180
  case 'Tab':
143
- actionRef.current.focusToComposer();
181
+ e.preventDefault();
182
+
183
+ if (hasMoreItems === 'bottom' && !e.shiftKey) {
184
+ var _loadMoreRef$current;
185
+
186
+ (_loadMoreRef$current = loadMoreRef.current) === null || _loadMoreRef$current === void 0 ? void 0 : _loadMoreRef$current.focus();
187
+ } else if (hasMoreItems === 'top' && e.shiftKey) {
188
+ var _loadMoreRef$current2;
189
+
190
+ (_loadMoreRef$current2 = loadMoreRef.current) === null || _loadMoreRef$current2 === void 0 ? void 0 : _loadMoreRef$current2.focus();
191
+ } else if (!e.shiftKey) {
192
+ if (bannerPosition) {
193
+ bannerRef.current.focusOnWrapper();
194
+ } else {
195
+ actionRef.current.focusToComposer();
196
+ }
197
+ } else {
198
+ var _virtualListRef$curre3;
199
+
200
+ (_virtualListRef$curre3 = virtualListRef.current) === null || _virtualListRef$curre3 === void 0 ? void 0 : _virtualListRef$curre3.focus();
201
+ }
202
+
203
+ break;
204
+ }
205
+ }, [actionRef, hasMoreItems, messages.length, bannerPosition, scrollAndFocus]);
206
+ const handleListKey = React__default["default"].useCallback(e => {
207
+ const {
208
+ key
209
+ } = e;
210
+
211
+ switch (key) {
212
+ case 'ArrowUp':
213
+ e.preventDefault();
214
+ onlyFocus(onScrollStop().shift());
215
+ break;
216
+
217
+ case 'ArrowDown':
218
+ e.preventDefault();
219
+ onlyFocus(onScrollStop().pop());
220
+ break;
221
+
222
+ case 'Home':
223
+ e.preventDefault();
224
+ scrollAndFocus(0);
225
+ break;
226
+
227
+ case 'End':
228
+ e.preventDefault();
229
+ scrollAndFocus(messages.length - 1);
230
+ break;
231
+
232
+ case 'Tab':
233
+ if (document.activeElement !== loadMoreRef.current) {
234
+ if (hasMoreItems === 'bottom' && !e.shiftKey) {
235
+ var _loadMoreRef$current3;
236
+
237
+ e.preventDefault();
238
+ (_loadMoreRef$current3 = loadMoreRef.current) === null || _loadMoreRef$current3 === void 0 ? void 0 : _loadMoreRef$current3.focus();
239
+ } else if (hasMoreItems === 'top' && e.shiftKey) {
240
+ var _loadMoreRef$current4;
241
+
242
+ e.preventDefault();
243
+ (_loadMoreRef$current4 = loadMoreRef.current) === null || _loadMoreRef$current4 === void 0 ? void 0 : _loadMoreRef$current4.focus();
244
+ } else if (!e.shiftKey) {
245
+ e.preventDefault();
246
+ actionRef.current.focusToComposer();
247
+ }
248
+ } else if (!e.shiftKey) {
249
+ e.preventDefault();
250
+ actionRef.current.focusToComposer();
251
+ } else {
252
+ var _virtualListRef$curre4;
253
+
254
+ e.preventDefault();
255
+ (_virtualListRef$curre4 = virtualListRef.current) === null || _virtualListRef$curre4 === void 0 ? void 0 : _virtualListRef$curre4.focus();
256
+ }
257
+
144
258
  break;
145
259
  }
146
- }, [actionRef, messages.length, scrollAndFocus]);
260
+ }, [actionRef, hasMoreItems, messages.length, onScrollStop, onlyFocus, scrollAndFocus]);
147
261
  React__default["default"].useEffect(() => {
148
262
  let handlerCallback = null;
149
263
  const localVirtualRef = virtualListRef.current;
@@ -193,7 +307,7 @@ const ChatContainerMessagesList = props => {
193
307
  jsxRuntime.jsx(ChatBubble.ChatBubble, _objectSpread(_objectSpread({}, row), {}, {
194
308
  helpMessage: isSending ? sendingText : row.helpMessage
195
309
  })) : null, row.type === props$1.BUBBLE_TYPES.DELIMITER ? /*#__PURE__*/jsxRuntime.jsx(MessageDelimiter.MessageDelimiter, _objectSpread({}, row)) : null, row.type === props$1.BUBBLE_TYPES.SYSTEM ? /*#__PURE__*/jsxRuntime.jsx(SystemMessage.SystemMessage, _objectSpread({}, row)) : null)
196
- }, "ds-chat-bubble-".concat(index));
310
+ }, "ds-chat-bubble-".concat(index, "-").concat(row.dsId, "-").concat(row.type));
197
311
  }), [virtualItems, messages, sendingMessages, handleKey, sendingText]);
198
312
  return /*#__PURE__*/_jsx__default["default"](styled.StyledWrapper, {}, void 0, /*#__PURE__*/jsxRuntime.jsx(styled.StyledChatContainerContentList, {
199
313
  "data-testid": "chat-thread-container",
@@ -201,7 +315,7 @@ const ChatContainerMessagesList = props => {
201
315
  "aria-live": "polite",
202
316
  ref: virtualListRef,
203
317
  role: "list",
204
- onKeyDown: handleKey,
318
+ onKeyDown: handleListKey,
205
319
  children: /*#__PURE__*/_jsx__default["default"](styled.StyledChatContainerContentListScroll, {
206
320
  height: "".concat(totalSize, "px")
207
321
  }, void 0, render, !isLoading && hasMoreItems ? /*#__PURE__*/_jsx__default["default"](styled.StyledLoadMoreContainer, {
@@ -209,7 +323,9 @@ const ChatContainerMessagesList = props => {
209
323
  }, void 0, /*#__PURE__*/_jsx__default["default"](DSButton__default["default"], {
210
324
  labelText: "Load More",
211
325
  buttonType: "secondary",
212
- onClick: getMoreMessages
326
+ onClick: getMoreMessages,
327
+ "data-testid": "ds-chat-load-more-btn",
328
+ innerRef: loadMoreRef
213
329
  })) : null)
214
330
  }));
215
331
  };
@@ -4,8 +4,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var dsPropsHelpers = require('@elliemae/ds-props-helpers');
6
6
 
7
- const useValidateProps = (props, schema) => {
8
- dsPropsHelpers.useValidateTypescriptPropTypes(props, schema);
7
+ const useValidateProps = (props, propTypes) => {
8
+ dsPropsHelpers.useValidateTypescriptPropTypes(props, propTypes);
9
9
  };
10
10
 
11
11
  exports.useValidateProps = useValidateProps;
@@ -11,11 +11,13 @@ const defaultProps = {
11
11
  onScrollEnds: () => [],
12
12
  getMoreMessages: lodash.noop,
13
13
  sendingMessages: undefined,
14
- sendingText: 'Sending'
14
+ sendingText: 'Sending',
15
+ bannerPosition: undefined,
16
+ bannerRef: undefined
15
17
  };
16
18
  const listProps = {
17
19
  messages: reactDesc.PropTypes.arrayOf(reactDesc.PropTypes.object).description('The array of out-of-the-box items you want to render inside the ChatMessageList').defaultValue(defaultProps.messages),
18
- actionRef: reactDesc.PropTypes.object.description("Reference: \n { \n scrollToIndex: (n: number) => void,\n getMessagesInView: () => number[],\n focusToIndex: (n: number) => void,\n focusToList: () => void,\n focusToComposer: () => void,\n focusToSend: () => void,\n }\n \n ").defaultValue(defaultProps.actionRef),
20
+ actionRef: reactDesc.PropTypes.object.description("Reference: \n { \n scrollToIndex: (n: number) => void,\n getMessagesInView: () => number[],\n focusToIndex: (n: number) => void,\n focusToIndexWithoutScroll: (n: number) => void,\n focusToList: () => void,\n focusToComposer: () => void,\n focusToSend: () => void,\n }\n \n ").defaultValue(defaultProps.actionRef),
19
21
  onScrollEnds: reactDesc.PropTypes.func.description("Called when the scroll stops."),
20
22
  isLoading: reactDesc.PropTypes.oneOf(['top', 'bottom', undefined]).description('Keeps the load more space while the loading is in progress'),
21
23
  hasMoreItems: reactDesc.PropTypes.oneOf(['top', 'bottom', undefined]).description('Show Load More button at the `top` or `bottom` of the container'),
@@ -16,7 +16,7 @@ const StyledWrapper = /*#__PURE__*/styled__default["default"].div.withConfig({
16
16
 
17
17
  const StyledWrapperListItem = /*#__PURE__*/styled__default["default"].div.withConfig({
18
18
  componentId: "sc-1jhprzr-1"
19
- })(["min-width:100%;", ";", ";", ";"], props$1 => props$1.type === props.BUBBLE_TYPES.SENDER && "padding: ".concat(props$1.theme.space.xxs, " ").concat(props$1.theme.space.xxs, " 0px 13%\n "), props$1 => props$1.type === props.BUBBLE_TYPES.RECIPIENT && "padding: ".concat(props$1.theme.space.xxs, " 13% ").concat(props$1.theme.space.xxs, "\n ").concat(props$1.theme.space.xxs, "\n "), props$1 => props$1.type === props.BUBBLE_TYPES.SYSTEM && "padding: ".concat(props$1.theme.space.xxs, " 0px\n "));
19
+ })(["min-width:100%;", ";", ";", ";"], props$1 => props$1.type === props.BUBBLE_TYPES.SENDER && "padding: ".concat(props$1.theme.space.xxs, " ").concat(props$1.theme.space.xxs, " ").concat(props$1.theme.space.xxs, " 13%\n "), props$1 => props$1.type === props.BUBBLE_TYPES.RECIPIENT && "padding: ".concat(props$1.theme.space.xxs, " 13% ").concat(props$1.theme.space.xxs, "\n ").concat(props$1.theme.space.xxs, "\n "), props$1 => props$1.type === props.BUBBLE_TYPES.SYSTEM && "padding: ".concat(props$1.theme.space.xxs, " 0px\n "));
20
20
  const StyledChatContainerContentList = /*#__PURE__*/styled__default["default"].div.withConfig({
21
21
  componentId: "sc-1jhprzr-2"
22
22
  })(["width:100%;height:100%;padding:", ";padding-bottom:0;overflow-y:auto;overflow-x:hidden;"], props => props.theme.space.xs);
@@ -28,7 +28,7 @@ const StyledLoadMoreContainer = /*#__PURE__*/styled__default["default"].div.with
28
28
  })(["position:absolute;width:calc(100% + ", ");padding:", ";left:-", ";right:-", ";display:grid;justify-content:center;align-items:center;", " ", ""], props => props.theme.space.xxs, props => props.theme.space.xxs, props => props.theme.space.xxs, props => props.theme.space.xxs, props => props.hasMoreItems === 'top' ? 'top: 0;' : '', props => props.hasMoreItems === 'bottom' ? 'bottom: 0;' : '');
29
29
  const ListItem = /*#__PURE__*/styled__default["default"].div.withConfig({
30
30
  componentId: "sc-1jhprzr-5"
31
- })(["&:focus,&:focus-visible{outline:none;&:after{content:'';display:block;position:absolute;pointer-events:none;background:rgba(255,255,255,0.5);width:calc(100% + ", ");height:100%;}}"], props => props.theme.space.xxs);
31
+ })(["&:focus,&:focus-visible{outline:none;&:after{content:'';display:block;position:absolute;top:0;left:-", ";pointer-events:none;border-radius:2px;background-color:#ebedf0;width:calc(100% + 24px);border:2px solid #1e79c2;height:100%;z-index:-1;}}"], props => props.theme.space.xxs);
32
32
 
33
33
  exports.ListItem = ListItem;
34
34
  exports.StyledChatContainerContentList = StyledChatContainerContentList;
@@ -7,7 +7,7 @@ require('core-js/modules/web.url.to-json.js');
7
7
  var React = require('react');
8
8
  var reactDesc = require('react-desc');
9
9
  var dsGrid = require('@elliemae/ds-grid');
10
- var Communications = require('@elliemae/ds-icons/Communications');
10
+ var dsIcons = require('@elliemae/ds-icons');
11
11
  var props = require('./props.js');
12
12
  var styled = require('./styled.js');
13
13
  var useValidateProps = require('./config/useValidateProps.js');
@@ -15,7 +15,6 @@ var useValidateProps = require('./config/useValidateProps.js');
15
15
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
16
16
 
17
17
  var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
18
- var Communications__default = /*#__PURE__*/_interopDefaultLegacy(Communications);
19
18
 
20
19
  const ChatEmptyState = props => {
21
20
  var _Grid, _Grid2;
@@ -31,7 +30,7 @@ const ChatEmptyState = props => {
31
30
  }, void 0, /*#__PURE__*/_jsx__default["default"](dsGrid.Grid, {
32
31
  alignItems: "center",
33
32
  justifyContent: "center"
34
- }, void 0, /*#__PURE__*/_jsx__default["default"](Communications__default["default"], {
33
+ }, void 0, /*#__PURE__*/_jsx__default["default"](dsIcons.Communications, {
35
34
  size: "xxl",
36
35
  color: ['neutral', 400]
37
36
  })), _Grid || (_Grid = /*#__PURE__*/_jsx__default["default"](dsGrid.Grid, {
@@ -5,10 +5,16 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
6
6
  var _jsx = require('@babel/runtime/helpers/jsx');
7
7
  require('core-js/modules/web.url.to-json.js');
8
- require('react');
8
+ require('core-js/modules/esnext.async-iterator.map.js');
9
+ require('core-js/modules/esnext.iterator.map.js');
10
+ require('core-js/modules/esnext.async-iterator.filter.js');
11
+ require('core-js/modules/esnext.iterator.constructor.js');
12
+ require('core-js/modules/esnext.iterator.filter.js');
13
+ require('core-js/modules/esnext.async-iterator.for-each.js');
14
+ require('core-js/modules/esnext.iterator.for-each.js');
15
+ var React = require('react');
9
16
  var reactDesc = require('react-desc');
10
- var MenuExpand = require('@elliemae/ds-icons/MenuExpand');
11
- var MenuCollapse = require('@elliemae/ds-icons/MenuCollapse');
17
+ var dsIcons = require('@elliemae/ds-icons');
12
18
  var styled = require('./styled.js');
13
19
  var TileButton = require('../tile-button/TileButton.js');
14
20
  var SidebarButton = require('../sidebar-button/SidebarButton.js');
@@ -20,26 +26,28 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
20
26
 
21
27
  var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
22
28
  var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
23
- var MenuExpand__default = /*#__PURE__*/_interopDefaultLegacy(MenuExpand);
24
- var MenuCollapse__default = /*#__PURE__*/_interopDefaultLegacy(MenuCollapse);
29
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
25
30
 
26
31
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
27
32
 
28
33
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
29
34
 
30
- const FooterChat = ({
31
- expanded,
32
- onFooterClose,
33
- onFooterExpand,
34
- footerButtonExtraProps
35
- }) => /*#__PURE__*/_jsx__default["default"](SidebarButton.SidebarButton, {
36
- dsId: "sidebar_footer",
37
- label: null,
38
- Icon: !expanded ? MenuCollapse__default["default"] : MenuExpand__default["default"],
39
- onClick: expanded ? onFooterClose : onFooterExpand,
40
- "aria-pressed": expanded,
41
- "aria-label": footerButtonExtraProps['aria-label']
42
- });
35
+ const FooterChat = _ref => {
36
+ let {
37
+ expanded,
38
+ onFooterClose,
39
+ onFooterExpand,
40
+ footerButtonExtraProps
41
+ } = _ref;
42
+ return /*#__PURE__*/_jsx__default["default"](SidebarButton.SidebarButton, {
43
+ dsId: "sidebar_footer",
44
+ label: null,
45
+ Icon: !expanded ? dsIcons.MenuCollapse : dsIcons.MenuExpand,
46
+ onClick: expanded ? onFooterClose : onFooterExpand,
47
+ "aria-pressed": expanded,
48
+ "aria-label": footerButtonExtraProps['aria-label']
49
+ });
50
+ };
43
51
 
44
52
  const SideBarChat = props => {
45
53
  useValidateProps.useValidateProps(props, SideBarChatWithSchema.toJSON());
@@ -49,18 +57,38 @@ const SideBarChat = props => {
49
57
  onFooterClose,
50
58
  onFooterExpand,
51
59
  selectedItem,
52
- footerButtonExtraProps
60
+ footerButtonExtraProps,
61
+ tooltipPlacement,
62
+ enableTooltipWhenIsClosed,
63
+ actionRef
53
64
  } = props;
54
- return /*#__PURE__*/_jsx__default["default"](styled.StyledSideBarContainer, {
55
- rows: [1, 'auto']
56
- }, void 0, /*#__PURE__*/_jsx__default["default"](styled.StyledSideBarButtonsContainer, {}, void 0, sidebarItems.map(p => /*#__PURE__*/jsxRuntime.jsx(TileButton.TileButton, _objectSpread(_objectSpread({}, p), {}, {
57
- selected: selectedItem === p.dsId
58
- })))), /*#__PURE__*/_jsx__default["default"](FooterChat, {
59
- expanded: expanded,
60
- onFooterClose: onFooterClose,
61
- onFooterExpand: onFooterExpand,
62
- footerButtonExtraProps: footerButtonExtraProps
63
- }));
65
+ const {
66
+ current: listRef
67
+ } = React__default["default"].useRef({});
68
+ const registerReference = React__default["default"].useCallback(ref => {
69
+ if (ref) listRef[ref.dataset.key] = ref;
70
+ }, [listRef]);
71
+ React__default["default"].useEffect(() => {
72
+ if (actionRef.current.listRef) {
73
+ actionRef.current.listRef = listRef;
74
+ }
75
+ }, [sidebarItems, expanded, actionRef, listRef]);
76
+ return /*#__PURE__*/jsxRuntime.jsxs(styled.StyledSideBarContainer, {
77
+ rows: [1, 'auto'],
78
+ ref: listRef,
79
+ children: [/*#__PURE__*/_jsx__default["default"](styled.StyledSideBarButtonsContainer, {}, void 0, sidebarItems.map(p => /*#__PURE__*/jsxRuntime.jsx(TileButton.TileButton, _objectSpread(_objectSpread({
80
+ innerRef: registerReference
81
+ }, p), {}, {
82
+ selected: selectedItem === p.dsId,
83
+ tooltipPlacement: tooltipPlacement,
84
+ disableTooltip: enableTooltipWhenIsClosed ? false : !expanded
85
+ }), p.dsId))), /*#__PURE__*/_jsx__default["default"](FooterChat, {
86
+ expanded: expanded,
87
+ onFooterClose: onFooterClose,
88
+ onFooterExpand: onFooterExpand,
89
+ footerButtonExtraProps: footerButtonExtraProps
90
+ })]
91
+ });
64
92
  };
65
93
 
66
94
  SideBarChat.defaultProps = props.defaultProps;
@@ -15,17 +15,27 @@ const defaultProps = {
15
15
  onHeaderClose: lodash.noop,
16
16
  footerButtonExtraProps: {
17
17
  'aria-label': 'expand or collapse button'
18
+ },
19
+ tooltipPlacement: 'right',
20
+ enableTooltipWhenIsClosed: false,
21
+ actionRef: {
22
+ current: {
23
+ listRef: []
24
+ }
18
25
  }
19
26
  };
20
27
  const chatSidebarProps = {
21
28
  sidebarItems: reactDesc.PropTypes.arrayOf(reactDesc.PropTypes.object).description('The array of out-of-the-box items you want to render inside the sidebar nav of the chat').defaultValue(defaultProps.sidebarItems),
22
29
  expanded: reactDesc.PropTypes.bool.description('Whether to show the chat expanded or collapsed').defaultValue(defaultProps.expanded),
23
30
  selectedItem: reactDesc.PropTypes.string.description('The id of the chat item you want to be opened').defaultValue(defaultProps.selectedItem),
31
+ tooltipPlacement: reactDesc.PropTypes.oneOf(['top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']).description('start placement preferences, as per popperjs placement option').defaultValue("'right'"),
32
+ enableTooltipWhenIsClosed: reactDesc.PropTypes.bool.description('Enable tooltip when is closed').defaultValue(defaultProps.onFooterExpand),
24
33
  onFooterExpand: reactDesc.PropTypes.func.description('The function to call when the chat is opened via the footer').defaultValue(defaultProps.onFooterExpand),
25
34
  onFooterClose: reactDesc.PropTypes.func.description('The function to call when the chat is closed via the footer').defaultValue(defaultProps.onFooterClose),
26
35
  onHeaderExpand: reactDesc.PropTypes.func.description('The function to call when the chat is opened via the header').defaultValue(defaultProps.onHeaderExpand),
27
36
  onHeaderClose: reactDesc.PropTypes.func.description('The function to call when the chat is closed via the header').defaultValue(defaultProps.onHeaderClose),
28
- footerButtonExtraProps: reactDesc.PropTypes.object.description('Expand/collapse footer button extra props').defaultValue(defaultProps.footerButtonExtraProps)
37
+ footerButtonExtraProps: reactDesc.PropTypes.object.description('Expand/collapse footer button extra props').defaultValue(defaultProps.footerButtonExtraProps),
38
+ actionRef: reactDesc.PropTypes.object.description("Action ref for sidebar\n {\n listRef: references to Tiles\n }\n ").defaultValue(defaultProps.actionRef)
29
39
  };
30
40
 
31
41
  exports.chatSidebarProps = chatSidebarProps;
@@ -12,10 +12,10 @@ var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled);
12
12
 
13
13
  const StyledSideBarContainer = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
14
14
  componentId: "sc-16uijso-0"
15
- })(["height:100%;width:", "px;background:", ";border-right:1px solid ", ";"], styled$1.MIN_WIDTH_SIDEBAR, props => props.theme.colors.neutral['050'], props => props.theme.colors.neutral['100']);
15
+ })(["height:100%;width:", "px;background:", ";border-right:1px solid ", ";overflow:hidden;"], styled$1.MIN_WIDTH_SIDEBAR, props => props.theme.colors.neutral['050'], props => props.theme.colors.neutral['100']);
16
16
  const StyledSideBarButtonsContainer = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
17
17
  componentId: "sc-16uijso-1"
18
- })(["overflow-y:auto;align-items:flex-start;justify-content:flex-start;grid-template-rows:repeat(auto-fill,", "px);"], styled$1.BUTTON_SIDEBAR_HEIGHT);
18
+ })(["overflow-y:auto;align-items:flex-start;justify-content:flex-start;grid-template-rows:repeat(auto-fill,", "px);overflow-x:hidden;scrollbar-width:thin;&::-webkit-scrollbar{width:6px;}"], styled$1.BUTTON_SIDEBAR_HEIGHT);
19
19
 
20
20
  exports.StyledSideBarButtonsContainer = StyledSideBarButtonsContainer;
21
21
  exports.StyledSideBarContainer = StyledSideBarContainer;
@@ -4,24 +4,32 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _jsx = require('@babel/runtime/helpers/jsx');
6
6
  require('react');
7
- var Comments = require('@elliemae/ds-icons/Comments');
7
+ var dsIcons = require('@elliemae/ds-icons');
8
8
  var styled = require('./styled.js');
9
9
  var props = require('./props.js');
10
+ var jsxRuntime = require('react/jsx-runtime');
10
11
 
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
13
 
13
14
  var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
14
- var Comments__default = /*#__PURE__*/_interopDefaultLegacy(Comments);
15
15
 
16
16
  var _Comments;
17
- const FloatingButton = ({
18
- onClick
19
- }) => /*#__PURE__*/_jsx__default["default"](styled.StyledFloatingButton, {
20
- "data-testid": "chat-floating-button",
21
- onClick: onClick
22
- }, void 0, _Comments || (_Comments = /*#__PURE__*/_jsx__default["default"](Comments__default["default"], {
23
- size: "l"
24
- })));
17
+ const FloatingButton = _ref => {
18
+ let {
19
+ onClick,
20
+ onFocus,
21
+ innerRef
22
+ } = _ref;
23
+ return /*#__PURE__*/jsxRuntime.jsx(styled.StyledFloatingButton, {
24
+ onFocus: onFocus,
25
+ ref: innerRef,
26
+ "data-testid": "chat-floating-button",
27
+ onClick: onClick,
28
+ children: _Comments || (_Comments = /*#__PURE__*/_jsx__default["default"](dsIcons.Comments, {
29
+ size: "l"
30
+ }))
31
+ });
32
+ };
25
33
  FloatingButton.defaultProps = props.defaultFloatingButton;
26
34
 
27
35
  exports.FloatingButton = FloatingButton;