@elliemae/ds-chat 2.0.0-next.0 → 2.0.0-next.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 (91) hide show
  1. package/cjs/parts/bubble/ChatBubble.js +15 -12
  2. package/cjs/parts/bubble/ChatBubbleArrow.js +64 -61
  3. package/cjs/parts/bubble/config/useValidateProps.js +5 -6
  4. package/cjs/parts/bubble/props.js +1 -1
  5. package/cjs/parts/bubble/styled.js +2 -31
  6. package/cjs/parts/chat-card/props.js +2 -2
  7. package/cjs/parts/chat-composer/ChatContainerComposer.js +16 -8
  8. package/cjs/parts/chat-composer/props.js +5 -11
  9. package/cjs/parts/chat-composer/styled.js +4 -4
  10. package/cjs/parts/chat-container/ChatContainer.js +50 -9
  11. package/cjs/parts/chat-container/props.js +2 -12
  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 +139 -34
  17. package/cjs/parts/chat-container-messages-list/props.js +5 -13
  18. package/cjs/parts/chat-container-messages-list/styled.js +2 -6
  19. package/cjs/parts/chat-empty-state/ChatEmptyState.js +2 -3
  20. package/cjs/parts/chat-sidebar/SideBarChat.js +57 -29
  21. package/cjs/parts/chat-sidebar/props.js +11 -1
  22. package/cjs/parts/chat-sidebar/styled.js +2 -2
  23. package/cjs/parts/floating-button/FloatingButton.js +12 -10
  24. package/cjs/parts/grid-influencer/styled.js +2 -6
  25. package/cjs/parts/message-delimiter/styled.js +1 -1
  26. package/cjs/parts/sidebar-button/SidebarButton.js +6 -1
  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 +31 -28
  30. package/cjs/parts/tile-button/props.js +12 -8
  31. package/cjs/parts/tile-button/styled.js +7 -3
  32. package/cjs/styled.js +1 -1
  33. package/esm/parts/bubble/ChatBubble.js +14 -11
  34. package/esm/parts/bubble/ChatBubbleArrow.js +64 -61
  35. package/esm/parts/bubble/config/useValidateProps.js +5 -6
  36. package/esm/parts/bubble/props.js +1 -1
  37. package/esm/parts/bubble/styled.js +2 -31
  38. package/esm/parts/chat-card/props.js +2 -2
  39. package/esm/parts/chat-composer/ChatContainerComposer.js +15 -6
  40. package/esm/parts/chat-composer/props.js +5 -11
  41. package/esm/parts/chat-composer/styled.js +2 -2
  42. package/esm/parts/chat-container/ChatContainer.js +50 -9
  43. package/esm/parts/chat-container/props.js +2 -12
  44. package/esm/parts/chat-container/styled.js +1 -1
  45. package/esm/parts/chat-container-header/ChatContainerHeader.js +3 -2
  46. package/esm/parts/chat-container-header/helpers.js +23 -0
  47. package/esm/parts/chat-container-header/styled.js +6 -6
  48. package/esm/parts/chat-container-messages-list/ChatContainerMessagesList.js +139 -34
  49. package/esm/parts/chat-container-messages-list/props.js +5 -13
  50. package/esm/parts/chat-container-messages-list/styled.js +2 -6
  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 +12 -9
  56. package/esm/parts/grid-influencer/styled.js +2 -6
  57. package/esm/parts/message-delimiter/styled.js +1 -1
  58. package/esm/parts/sidebar-button/SidebarButton.js +6 -1
  59. package/esm/parts/sidebar-button/props.js +1 -1
  60. package/esm/parts/system-message/style.js +1 -1
  61. package/esm/parts/tile-button/TileButton.js +32 -27
  62. package/esm/parts/tile-button/props.js +11 -3
  63. package/esm/parts/tile-button/styled.js +7 -4
  64. package/esm/styled.js +1 -1
  65. package/package.json +16 -6
  66. package/types/parts/bubble/styled.d.ts +3 -3
  67. package/types/parts/bubble/tests/ChatBubble.test.d.ts +1 -0
  68. package/types/parts/chat-card/styled.d.ts +1 -1
  69. package/types/parts/chat-composer/ChatContainerComposer.d.ts +2 -0
  70. package/types/parts/chat-composer/props.d.ts +10 -6
  71. package/types/parts/chat-composer/styled.d.ts +2 -2
  72. package/types/parts/chat-composer/tests/ChatContainerComposer.test.d.ts +1 -0
  73. package/types/parts/chat-container/props.d.ts +2 -0
  74. package/types/parts/chat-container/styled.d.ts +2 -2
  75. package/types/parts/chat-container-header/helpers.d.ts +6 -0
  76. package/types/parts/chat-container-header/styled.d.ts +3 -3
  77. package/types/parts/chat-container-messages-list/props.d.ts +6 -0
  78. package/types/parts/chat-empty-state/styled.d.ts +1 -1
  79. package/types/parts/chat-sidebar/SideBarChat.d.ts +3 -0
  80. package/types/parts/chat-sidebar/props.d.ts +8 -1
  81. package/types/parts/chat-sidebar/styled.d.ts +2 -2
  82. package/types/parts/floating-container/styled.d.ts +1 -1
  83. package/types/parts/grid-influencer/styled.d.ts +2 -2
  84. package/types/parts/message-delimiter/styled.d.ts +1 -1
  85. package/types/parts/sidebar-button/styled.d.ts +1 -1
  86. package/types/parts/system-message/style.d.ts +2 -2
  87. package/types/parts/tile-button/TileButton.d.ts +3 -0
  88. package/types/parts/tile-button/props.d.ts +6 -0
  89. package/types/parts/tile-button/styled.d.ts +5 -4
  90. package/cjs/package.json +0 -4
  91. package/esm/package.json +0 -4
@@ -3,14 +3,14 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _jsx = require('@babel/runtime/helpers/jsx');
6
- var React = require('react');
6
+ require('react');
7
7
  var dsTruncatedTooltipText = require('@elliemae/ds-truncated-tooltip-text');
8
8
  var styled = require('./styled.js');
9
+ var helpers = require('./helpers.js');
9
10
 
10
11
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
12
 
12
13
  var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
13
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
14
14
 
15
15
  const ChatContainerHeader = props => {
16
16
  const {
@@ -30,7 +30,7 @@ const ChatContainerHeader = props => {
30
30
  }, void 0, /*#__PURE__*/_jsx__default["default"](dsTruncatedTooltipText.SimpleTruncatedTooltipText, {
31
31
  value: title
32
32
  })), /*#__PURE__*/_jsx__default["default"](styled.StyledChatContainerContentHeaderActions, {
33
- cols: React__default["default"].Children.toArray(children).filter(e => e).map(() => '32px'),
33
+ cols: helpers.validHeaderChilds(children),
34
34
  justifyContent: "flex-end",
35
35
  "data-testid": "chat-container-header-children"
36
36
  }, void 0, children));
@@ -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,19 @@ 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.for-each.js');
8
+ require('core-js/modules/esnext.iterator.constructor.js');
9
+ require('core-js/modules/esnext.iterator.for-each.js');
10
+ require('core-js/modules/esnext.async-iterator.map.js');
11
+ require('core-js/modules/esnext.iterator.map.js');
12
+ require('core-js/modules/esnext.async-iterator.find.js');
13
+ require('core-js/modules/esnext.iterator.find.js');
14
+ require('core-js/modules/esnext.async-iterator.filter.js');
15
+ require('core-js/modules/esnext.iterator.filter.js');
7
16
  var React = require('react');
8
17
  var reactDesc = require('react-desc');
9
18
  var reactVirtual = require('react-virtual');
10
- var DSButton = require('@elliemae/ds-basic/Button');
19
+ var DSButton = require('@elliemae/ds-button');
11
20
  var ChatBubble = require('../bubble/ChatBubble.js');
12
21
  var props$1 = require('../bubble/props.js');
13
22
  var MessageDelimiter = require('../message-delimiter/MessageDelimiter.js');
@@ -41,14 +50,17 @@ const ChatContainerMessagesList = props => {
41
50
  useValidateProps.useValidateProps(props, ChatContainerMessagesListWithSchema.toTypescript());
42
51
  const {
43
52
  sendingText,
53
+ bannerPosition,
44
54
  sendingMessages,
45
55
  messages,
46
56
  actionRef,
47
57
  onScrollEnds,
48
58
  getMoreMessages,
49
59
  hasMoreItems,
50
- isLoading
60
+ isLoading,
61
+ bannerRef
51
62
  } = props;
63
+ const loadMoreRef = React__default["default"].useRef(null);
52
64
  const virtualListRef = React__default["default"].useRef(); // estimateSize should not be really required given what was stated on
53
65
  // https://github.com/tannerlinsley/react-virtual/issues/23
54
66
 
@@ -64,86 +76,177 @@ const ChatContainerMessagesList = props => {
64
76
  estimateSize: React__default["default"].useCallback(() => 80, [])
65
77
  }));
66
78
  const onScrollStop = React__default["default"].useCallback(() => {
79
+ var _virtualListRef$curre;
80
+
67
81
  const {
68
82
  bottom,
69
83
  top
70
- } = virtualListRef.current.getBoundingClientRect();
84
+ } = (_virtualListRef$curre = virtualListRef.current) === null || _virtualListRef$curre === void 0 ? void 0 : _virtualListRef$curre.getBoundingClientRect();
71
85
  const list = virtualListRef.current.querySelectorAll('[data-element="chat-element-list-item"]');
72
86
  const indexList = [];
73
87
  list.forEach(item => {
74
88
  const {
75
- top: itemTop
89
+ top: itemTop,
90
+ bottom: itemBottom
76
91
  } = item.getBoundingClientRect();
77
- if (itemTop < bottom && itemTop > top) indexList.push(item.dataset.index);
92
+ const itemPadding = 10;
93
+ if (itemTop + itemPadding < bottom && itemBottom - itemPadding > top) indexList.push(item.dataset.index);
78
94
  });
79
95
  if (onScrollEnds) onScrollEnds(indexList);
80
96
  return indexList;
81
97
  }, [onScrollEnds]);
82
- const scrollAndFocus = React__default["default"].useCallback(index => {
83
- vScroll(index, {
84
- align: 'center'
85
- });
98
+ const onlyFocus = React__default["default"].useCallback(index => {
86
99
  setTimeout(() => {
87
- virtualListRef.current.querySelector(`[data-index="${index}"]`).focus();
100
+ virtualListRef.current.querySelector("[data-index=\"".concat(index, "\"]")).focus();
88
101
  }, 300);
89
- }, [vScroll]);
102
+ }, []);
103
+ const scrollAndFocus = React__default["default"].useCallback(function (index) {
104
+ let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
105
+ align: 'center'
106
+ };
107
+ vScroll(index, b);
108
+ onlyFocus(index);
109
+ }, [onlyFocus, vScroll]);
90
110
  React__default["default"].useEffect(() => {
91
111
  if (actionRef && actionRef.current) {
92
- actionRef.current.scrollToIndex = (a, b = {
93
- align: 'center'
94
- }) => {
112
+ actionRef.current.scrollToIndex = function (a) {
113
+ let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
114
+ align: 'center'
115
+ };
95
116
  vScroll(a, b);
96
117
  };
97
118
 
98
119
  actionRef.current.getMessagesInView = onScrollStop;
99
120
 
100
- actionRef.current.focusToIndex = (a, b = {
101
- align: 'center'
102
- }) => {
103
- scrollAndFocus(a);
121
+ actionRef.current.focusToIndex = function (a) {
122
+ let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
123
+ align: 'center'
124
+ };
125
+ scrollAndFocus(a, b);
104
126
  };
105
127
 
106
- actionRef.current.focusToList = (a, b = {
107
- align: 'center'
108
- }) => {
109
- var _virtualListRef$curre;
128
+ actionRef.current.focusToIndexWithoutScroll = onlyFocus;
110
129
 
111
- (_virtualListRef$curre = virtualListRef.current) === null || _virtualListRef$curre === void 0 ? void 0 : _virtualListRef$curre.focus();
130
+ actionRef.current.focusToList = a => {
131
+ var _virtualListRef$curre2;
132
+
133
+ (_virtualListRef$curre2 = virtualListRef.current) === null || _virtualListRef$curre2 === void 0 ? void 0 : _virtualListRef$curre2.focus();
112
134
  };
113
135
  }
114
- }, [actionRef, onScrollStop, scrollAndFocus, vScroll]);
136
+ }, [actionRef, onScrollStop, onlyFocus, scrollAndFocus, vScroll]);
115
137
  const handleKey = React__default["default"].useCallback(e => {
116
- e.preventDefault();
117
138
  const {
118
139
  key
119
140
  } = e;
120
141
  const index = Number(e.currentTarget.dataset.index);
142
+ e.stopPropagation();
121
143
 
122
144
  switch (key) {
123
145
  case 'ArrowUp':
124
- if (index > 0) virtualListRef.current.querySelector(`[data-index="${index - 1}"]`).focus();
146
+ e.preventDefault();
147
+ if (index > 0) virtualListRef.current.querySelector("[data-index=\"".concat(index - 1, "\"]")).focus();
125
148
  break;
126
149
 
127
150
  case 'ArrowDown':
151
+ e.preventDefault();
152
+
128
153
  if (index < messages.length - 1) {
129
- virtualListRef.current.querySelector(`[data-index="${index + 1}"]`).focus();
154
+ virtualListRef.current.querySelector("[data-index=\"".concat(index + 1, "\"]")).focus();
155
+ }
156
+
157
+ break;
158
+
159
+ case 'Home':
160
+ e.preventDefault();
161
+ scrollAndFocus(0);
162
+ break;
163
+
164
+ case 'End':
165
+ e.preventDefault();
166
+ scrollAndFocus(messages.length - 1);
167
+ break;
168
+
169
+ case 'Tab':
170
+ e.preventDefault();
171
+
172
+ if (hasMoreItems === 'bottom' && !e.shiftKey) {
173
+ var _loadMoreRef$current;
174
+
175
+ (_loadMoreRef$current = loadMoreRef.current) === null || _loadMoreRef$current === void 0 ? void 0 : _loadMoreRef$current.focus();
176
+ } else if (hasMoreItems === 'top' && e.shiftKey) {
177
+ var _loadMoreRef$current2;
178
+
179
+ (_loadMoreRef$current2 = loadMoreRef.current) === null || _loadMoreRef$current2 === void 0 ? void 0 : _loadMoreRef$current2.focus();
180
+ } else if (!e.shiftKey) {
181
+ if (bannerPosition) {
182
+ bannerRef.current.focusOnWrapper();
183
+ } else {
184
+ actionRef.current.focusToComposer();
185
+ }
186
+ } else {
187
+ var _virtualListRef$curre3;
188
+
189
+ (_virtualListRef$curre3 = virtualListRef.current) === null || _virtualListRef$curre3 === void 0 ? void 0 : _virtualListRef$curre3.focus();
130
190
  }
131
191
 
132
192
  break;
193
+ }
194
+ }, [actionRef, hasMoreItems, messages.length, bannerPosition, scrollAndFocus]);
195
+ const handleListKey = React__default["default"].useCallback(e => {
196
+ const {
197
+ key
198
+ } = e;
199
+
200
+ switch (key) {
201
+ case 'ArrowUp':
202
+ e.preventDefault();
203
+ onlyFocus(onScrollStop().shift());
204
+ break;
205
+
206
+ case 'ArrowDown':
207
+ e.preventDefault();
208
+ onlyFocus(onScrollStop().pop());
209
+ break;
133
210
 
134
211
  case 'Home':
212
+ e.preventDefault();
135
213
  scrollAndFocus(0);
136
214
  break;
137
215
 
138
216
  case 'End':
217
+ e.preventDefault();
139
218
  scrollAndFocus(messages.length - 1);
140
219
  break;
141
220
 
142
221
  case 'Tab':
143
- actionRef.current.focusToComposer();
222
+ if (document.activeElement !== loadMoreRef.current) {
223
+ if (hasMoreItems === 'bottom' && !e.shiftKey) {
224
+ var _loadMoreRef$current3;
225
+
226
+ e.preventDefault();
227
+ (_loadMoreRef$current3 = loadMoreRef.current) === null || _loadMoreRef$current3 === void 0 ? void 0 : _loadMoreRef$current3.focus();
228
+ } else if (hasMoreItems === 'top' && e.shiftKey) {
229
+ var _loadMoreRef$current4;
230
+
231
+ e.preventDefault();
232
+ (_loadMoreRef$current4 = loadMoreRef.current) === null || _loadMoreRef$current4 === void 0 ? void 0 : _loadMoreRef$current4.focus();
233
+ } else if (!e.shiftKey) {
234
+ e.preventDefault();
235
+ actionRef.current.focusToComposer();
236
+ }
237
+ } else if (!e.shiftKey) {
238
+ e.preventDefault();
239
+ actionRef.current.focusToComposer();
240
+ } else {
241
+ var _virtualListRef$curre4;
242
+
243
+ e.preventDefault();
244
+ (_virtualListRef$curre4 = virtualListRef.current) === null || _virtualListRef$curre4 === void 0 ? void 0 : _virtualListRef$curre4.focus();
245
+ }
246
+
144
247
  break;
145
248
  }
146
- }, [actionRef, messages.length, scrollAndFocus]);
249
+ }, [actionRef, hasMoreItems, messages.length, onScrollStop, onlyFocus, scrollAndFocus]);
147
250
  React__default["default"].useEffect(() => {
148
251
  let handlerCallback = null;
149
252
  const localVirtualRef = virtualListRef.current;
@@ -174,7 +277,7 @@ const ChatContainerMessagesList = props => {
174
277
  position: 'absolute',
175
278
  top: 0,
176
279
  left: 0,
177
- transform: `translateY(${start}px)`,
280
+ transform: "translateY(".concat(start, "px)"),
178
281
  width: '100%'
179
282
  };
180
283
  return /*#__PURE__*/jsxRuntime.jsx(styled.ListItem, {
@@ -193,7 +296,7 @@ const ChatContainerMessagesList = props => {
193
296
  jsxRuntime.jsx(ChatBubble.ChatBubble, _objectSpread(_objectSpread({}, row), {}, {
194
297
  helpMessage: isSending ? sendingText : row.helpMessage
195
298
  })) : 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-${index}`);
299
+ }, "ds-chat-bubble-".concat(index, "-").concat(row.dsId, "-").concat(row.type));
197
300
  }), [virtualItems, messages, sendingMessages, handleKey, sendingText]);
198
301
  return /*#__PURE__*/_jsx__default["default"](styled.StyledWrapper, {}, void 0, /*#__PURE__*/jsxRuntime.jsx(styled.StyledChatContainerContentList, {
199
302
  "data-testid": "chat-thread-container",
@@ -201,15 +304,17 @@ const ChatContainerMessagesList = props => {
201
304
  "aria-live": "polite",
202
305
  ref: virtualListRef,
203
306
  role: "list",
204
- onKeyDown: handleKey,
307
+ onKeyDown: handleListKey,
205
308
  children: /*#__PURE__*/_jsx__default["default"](styled.StyledChatContainerContentListScroll, {
206
- height: `${totalSize}px`
309
+ height: "".concat(totalSize, "px")
207
310
  }, void 0, render, !isLoading && hasMoreItems ? /*#__PURE__*/_jsx__default["default"](styled.StyledLoadMoreContainer, {
208
311
  hasMoreItems: hasMoreItems
209
312
  }, void 0, /*#__PURE__*/_jsx__default["default"](DSButton__default["default"], {
210
313
  labelText: "Load More",
211
314
  buttonType: "secondary",
212
- onClick: getMoreMessages
315
+ onClick: getMoreMessages,
316
+ "data-testid": "ds-chat-load-more-btn",
317
+ innerRef: loadMoreRef
213
318
  })) : null)
214
319
  }));
215
320
  };
@@ -11,22 +11,14 @@ 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:
19
- {
20
- scrollToIndex: (n: number) => void,
21
- getMessagesInView: () => number[],
22
- focusToIndex: (n: number) => void,
23
- focusToList: () => void,
24
- focusToComposer: () => void,
25
- focusToSend: () => void,
26
- }
27
-
28
- `).defaultValue(defaultProps.actionRef),
29
- onScrollEnds: reactDesc.PropTypes.func.description(`Called when the scroll stops.`),
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),
21
+ onScrollEnds: reactDesc.PropTypes.func.description("Called when the scroll stops."),
30
22
  isLoading: reactDesc.PropTypes.oneOf(['top', 'bottom', undefined]).description('Keeps the load more space while the loading is in progress'),
31
23
  hasMoreItems: reactDesc.PropTypes.oneOf(['top', 'bottom', undefined]).description('Show Load More button at the `top` or `bottom` of the container'),
32
24
  getMoreMessages: reactDesc.PropTypes.func.description('Called when the user clicks on load more').defaultValue(defaultProps.getMoreMessages),
@@ -16,11 +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: ${props$1.theme.space.xxs} ${props$1.theme.space.xxs} 0px 13%
20
- `, props$1 => props$1.type === props.BUBBLE_TYPES.RECIPIENT && `padding: ${props$1.theme.space.xxs} 13% ${props$1.theme.space.xxs}
21
- ${props$1.theme.space.xxs}
22
- `, props$1 => props$1.type === props.BUBBLE_TYPES.SYSTEM && `padding: ${props$1.theme.space.xxs} 0px
23
- `);
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 "));
24
20
  const StyledChatContainerContentList = /*#__PURE__*/styled__default["default"].div.withConfig({
25
21
  componentId: "sc-1jhprzr-2"
26
22
  })(["width:100%;height:100%;padding:", ";padding-bottom:0;overflow-y:auto;overflow-x:hidden;"], props => props.theme.space.xs);
@@ -32,7 +28,7 @@ const StyledLoadMoreContainer = /*#__PURE__*/styled__default["default"].div.with
32
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;' : '');
33
29
  const ListItem = /*#__PURE__*/styled__default["default"].div.withConfig({
34
30
  componentId: "sc-1jhprzr-5"
35
- })(["&: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);
36
32
 
37
33
  exports.ListItem = ListItem;
38
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,26 @@ 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
10
 
11
11
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
12
 
13
13
  var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
14
- var Comments__default = /*#__PURE__*/_interopDefaultLegacy(Comments);
15
14
 
16
15
  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
- })));
16
+ const FloatingButton = _ref => {
17
+ let {
18
+ onClick
19
+ } = _ref;
20
+ return /*#__PURE__*/_jsx__default["default"](styled.StyledFloatingButton, {
21
+ "data-testid": "chat-floating-button",
22
+ onClick: onClick
23
+ }, void 0, _Comments || (_Comments = /*#__PURE__*/_jsx__default["default"](dsIcons.Comments, {
24
+ size: "l"
25
+ })));
26
+ };
25
27
  FloatingButton.defaultProps = props.defaultFloatingButton;
26
28
 
27
29
  exports.FloatingButton = FloatingButton;