@elliemae/ds-chat 2.1.0-rc.1 → 2.1.0-rc.10

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.
@@ -21,7 +21,8 @@ const ChatDataTestIds = {
21
21
  SYSTEM_MSG_TIME: 'chat-system-message-time',
22
22
  BUBBLE: 'ds-chat-bubble',
23
23
  BUBBLE_TITLE: 'chat-bubble-title',
24
- BUBBLE_BODY: 'chat-bubble-body'
24
+ BUBBLE_BODY: 'chat-bubble-body',
25
+ BANNER: 'ds-banner-container'
25
26
  };
26
27
 
27
28
  exports.ChatDataTestIds = ChatDataTestIds;
@@ -48,10 +48,12 @@ const ChatComposer = props => {
48
48
  placeholder,
49
49
  inputMaxLength,
50
50
  maxLengthMessage,
51
+ ariaMaxLengthMessage,
51
52
  buttonDisabled,
52
53
  dataTestid,
53
54
  actionRef
54
55
  } = props;
56
+ const COMPOSER_MIN_HEIGHT = 32;
55
57
  const input = React__default["default"].useRef();
56
58
  const inputSize = React__default["default"].useRef();
57
59
  const inputSend = React__default["default"].useRef();
@@ -62,10 +64,10 @@ const ChatComposer = props => {
62
64
  var _inputSize$current, _inputSize$current2, _inputSize$current3, _inputSize$current4;
63
65
 
64
66
  const newHeight = ((_inputSize$current = inputSize.current) === null || _inputSize$current === void 0 ? void 0 : _inputSize$current.scrollHeight) > internalMaxHeight ? internalMaxHeight : (_inputSize$current2 = inputSize.current) === null || _inputSize$current2 === void 0 ? void 0 : _inputSize$current2.scrollHeight;
65
- onResize(newHeight);
67
+ if (newHeight !== height && newHeight > COMPOSER_MIN_HEIGHT) onResize(newHeight);
66
68
  setHeight(newHeight);
67
69
  setShowScroll(((_inputSize$current3 = inputSize.current) === null || _inputSize$current3 === void 0 ? void 0 : _inputSize$current3.scrollHeight) - ((_inputSize$current4 = inputSize.current) === null || _inputSize$current4 === void 0 ? void 0 : _inputSize$current4.clientHeight) > 5);
68
- }, [inputValue, internalMaxHeight, onResize]);
70
+ }, [inputValue, internalMaxHeight, height, onResize]);
69
71
  React__default["default"].useEffect(() => {
70
72
  if (actionRef && actionRef.current) {
71
73
  actionRef.current.focusToComposer = () => {
@@ -92,6 +94,9 @@ const ChatComposer = props => {
92
94
  "data-testid": dataTestid
93
95
  }, void 0, /*#__PURE__*/_jsx__default["default"](dsGrid.Grid, {
94
96
  cols: ['1fr', '24px'],
97
+ style: {
98
+ height: heightProps.height
99
+ },
95
100
  justifyContent: "center",
96
101
  alignItems: "flex-end",
97
102
  gutter: "xxs"
@@ -105,7 +110,9 @@ const ChatComposer = props => {
105
110
  onKeyDown: onKeyDown,
106
111
  placeholder: placeholder,
107
112
  "aria-label": "Message to send",
108
- "data-testid": "chat-composer-textarea"
113
+ "data-testid": "chat-composer-textarea",
114
+ name: "chat-composer-textarea",
115
+ id: "chat-composer-textarea"
109
116
  }), /*#__PURE__*/_jsx__default["default"](dsGrid.Grid, {
110
117
  height: "32px",
111
118
  alignItems: "center"
@@ -132,8 +139,7 @@ const ChatComposer = props => {
132
139
  width: (_input$current = input.current) === null || _input$current === void 0 ? void 0 : _input$current.clientWidth
133
140
  },
134
141
  onChange: handleChange,
135
- value: inputValue // maxLength={inputMaxLength}
136
-
142
+ value: inputValue
137
143
  }), /*#__PURE__*/_jsx__default["default"](dsGrid.Grid, {
138
144
  cols: ['1fr', '24px'],
139
145
  justifyContent: "flex-end",
@@ -146,7 +152,7 @@ const ChatComposer = props => {
146
152
  }, void 0, inputMaxLength && hasError ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
147
153
  children: [/*#__PURE__*/_jsx__default["default"](styled.StyledCounterErrorA11y, {
148
154
  role: "alert"
149
- }, void 0, maxLengthMessage || "You have entered ".concat(inputLength, " characters and have exceeded the limit by ").concat(inputLength - inputMaxLength, ". Please limit to less than ").concat(inputMaxLength, " characters. ")), maxLengthMessage || "Please limit to less than ".concat(inputMaxLength, " characters. ")]
155
+ }, void 0, ariaMaxLengthMessage || "You have entered ".concat(inputLength, " characters and have exceeded the limit by ").concat(inputLength - inputMaxLength, ". Please limit to less than ").concat(inputMaxLength, " characters. ")), maxLengthMessage || "Please limit to less than ".concat(inputMaxLength, " characters. ")]
150
156
  }) : '', inputMaxLength ? " ".concat(inputLength, " / ").concat(inputMaxLength) : ''), _Grid || (_Grid = /*#__PURE__*/_jsx__default["default"](dsGrid.Grid, {}))));
151
157
  };
152
158
 
@@ -8,6 +8,7 @@ var lodash = require('lodash');
8
8
  const defaultComposerPros = {
9
9
  placeholder: 'Type your message',
10
10
  inputValue: '',
11
+ ariaMaxLengthMessage: '',
11
12
  onChange: lodash.noop,
12
13
  onResize: lodash.noop,
13
14
  onSend: lodash.noop,
@@ -24,6 +25,7 @@ const defaultComposerPros = {
24
25
  const composerProps = {
25
26
  placeholder: reactDesc.PropTypes.string.description('Input Placeholder').defaultValue(defaultComposerPros.placeholder),
26
27
  inputValue: reactDesc.PropTypes.string.description('Input value').defaultValue(defaultComposerPros.inputValue),
28
+ ariaMaxLengthMessage: reactDesc.PropTypes.string.description('Aria message for Max length message when exceeded').defaultValue(defaultComposerPros.maxLengthMessage),
27
29
  maxLengthMessage: reactDesc.PropTypes.string.description('Max length message').defaultValue(defaultComposerPros.maxLengthMessage),
28
30
  onChange: reactDesc.PropTypes.func.description('Called when the user types').defaultValue(defaultComposerPros.onChange),
29
31
  onResize: reactDesc.PropTypes.func.description('Called the input changes his height').defaultValue(defaultComposerPros.onResize),
@@ -36,7 +36,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
36
36
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
37
37
 
38
38
  const ChatContainer = props$1 => {
39
- var _containerRef$current;
39
+ var _messagesListProps$me2, _containerRef$current;
40
40
 
41
41
  useValidateProps.useValidateProps(props$1, props.containerProps);
42
42
  const {
@@ -67,18 +67,16 @@ const ChatContainer = props$1 => {
67
67
  });
68
68
  const onResize = React__default["default"].useCallback(height => {
69
69
  if (onComposerResize) onComposerResize(height);
70
-
71
- if (height > 30) {
72
- /*
70
+ /*
73
71
  setTimeout is used to equal the animation duration from the
74
72
  composer text area when increase its size
75
73
  */
76
- setTimeout(() => {
77
- actionRef.current.scrollToIndex(messagesListProps.messages.length - 1, {
78
- align: 'start'
79
- });
80
- }, 50);
81
- }
74
+
75
+ setTimeout(() => {
76
+ actionRef.current.scrollToIndex(messagesListProps.messages.length - 1, {
77
+ align: 'start'
78
+ });
79
+ }, 50);
82
80
  }, [onComposerResize, messagesListProps.messages, actionRef]);
83
81
  const Container = device === 'desktop' ? styled.StyledChatContainerContent : styled.MobileStyledChatContainerContent;
84
82
  const handleTabs = React__default["default"].useCallback(e => {
@@ -86,7 +84,9 @@ const ChatContainer = props$1 => {
86
84
  const ref = actionRef || listRef;
87
85
 
88
86
  if (e.shiftKey && e.key === 'Tab') {
89
- if (messagesListProps.messages.length > 0) {
87
+ var _messagesListProps$me;
88
+
89
+ if (((_messagesListProps$me = messagesListProps.messages) === null || _messagesListProps$me === void 0 ? void 0 : _messagesListProps$me.length) > 0) {
90
90
  e.preventDefault();
91
91
 
92
92
  if (['top', 'bottom'].includes(bannerPosition)) {
@@ -100,7 +100,7 @@ const ChatContainer = props$1 => {
100
100
  }
101
101
  }
102
102
  }
103
- }, [actionRef, onComposerKeyDown, bannerPosition, messagesListProps.messages.length]); // Map actions
103
+ }, [actionRef, onComposerKeyDown, bannerPosition, (_messagesListProps$me2 = messagesListProps.messages) === null || _messagesListProps$me2 === void 0 ? void 0 : _messagesListProps$me2.length]); // Map actions
104
104
 
105
105
  React__default["default"].useEffect(() => {
106
106
  if (actionRef && actionRef.current) {
@@ -18,7 +18,7 @@ const StyledChatContainerContent = /*#__PURE__*/styled__default["default"](dsGri
18
18
  })(["height:100%;min-width:", "px;overflow:hidden;background:", ";position:relative;"], CONTAINER_WIDTH, props => props.theme.colors.neutral['050']);
19
19
  const StyledIndicatorContainer = /*#__PURE__*/styled__default["default"].div.withConfig({
20
20
  componentId: "sc-d732wo-1"
21
- })(["transition:0.4s ease-in-out;position:absolute;visibility:hidden;pointer-events:none;width:100%;padding:0 ", ";left:0;right:0;background:", ";", " ", " & div,a{font-size:13px;}"], props => !props.linear ? props.theme.space.xxs : 0, props => props.theme.colors.neutral['000'], props => props.isLoading === 'top' ? "\n top: -41px;\n transform: translate(0, 41px);\n visibility: visible;\n pointer-events: auto\n " : '', props => props.isLoading === 'bottom' ? "\n bottom: -41px;\n transform: translate(0, -41px);\n visibility: visible;\n pointer-events: auto;\n " : '');
21
+ })(["transition:0.4s ease-in-out;position:absolute;visibility:hidden;pointer-events:none;width:100%;padding:0 ", ";left:0;right:0;background:", ";", " ", " & div,a{font-size:13px;}"], props => !props.linear ? props.theme.space.xxs : 0, props => props.theme.colors.neutral['000'], props => props.isLoading === 'top' ? "\n top: -41px;\n transform: translate(0, 41px);\n visibility: visible;\n pointer-events: auto;\n " : '', props => props.isLoading === 'bottom' ? "\n bottom: -41px;\n transform: translate(0, -41px);\n visibility: visible;\n pointer-events: auto;\n " : '');
22
22
  const MobileStyledChatContainerContent = /*#__PURE__*/styled__default["default"](StyledChatContainerContent).withConfig({
23
23
  componentId: "sc-d732wo-2"
24
24
  })(["", ",", "{font-size:16px;}", "{font-size:13px;}", "{background-color:#fff;box-shadow:-0 1px 3px rgba(53,60,70,0.8);}", ",", "{font-size:16px;text-align:left;}", "{font-size:13px;}", "{font-size:16px;}", "{font-size:16px;}"], styled$1.StyledTitleLeftBubble, styled$1.StyleBodyWrapper, styled$1.StyledTitleRightBubble, style.Wrapper, style.Title, style.Message, style.Time, styled$2.StyledComposerInput, StyledIndicatorContainer);
@@ -26,7 +26,6 @@ var MessageDelimiter = require('../message-delimiter/MessageDelimiter.js');
26
26
  var SystemMessage = require('../system-message/SystemMessage.js');
27
27
  var styled = require('./styled.js');
28
28
  var props = require('./props.js');
29
- var useValidateProps = require('./config/useValidateProps.js');
30
29
  var jsxRuntime = require('react/jsx-runtime');
31
30
 
32
31
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -54,8 +53,7 @@ const getPadding = _ref => {
54
53
  return padding;
55
54
  };
56
55
 
57
- const ChatContainerMessagesList = props$2 => {
58
- useValidateProps.useValidateProps(props$2, props.listProps);
56
+ const ChatContainerMessagesList = props => {
59
57
  const {
60
58
  sendingText,
61
59
  bannerPosition,
@@ -67,7 +65,7 @@ const ChatContainerMessagesList = props$2 => {
67
65
  hasMoreItems,
68
66
  isLoading,
69
67
  bannerRef
70
- } = props$2;
68
+ } = props;
71
69
  const pendingOnScroll = React__default["default"].useRef(false);
72
70
  const loadMoreRef = React__default["default"].useRef(null);
73
71
  const virtualListRef = React__default["default"].useRef(); // estimateSize should not be really required given what was stated on
@@ -96,6 +94,7 @@ const ChatContainerMessagesList = props$2 => {
96
94
  return [];
97
95
  }
98
96
 
97
+ if (!virtualListRef.current) return [];
99
98
  pendingOnScroll.current = false;
100
99
  const {
101
100
  bottom,
@@ -138,6 +137,7 @@ const ChatContainerMessagesList = props$2 => {
138
137
  };
139
138
 
140
139
  actionRef.current.getMessagesInView = onScrollStop;
140
+ onScrollStop(); // init useMemo due to debounce use.
141
141
 
142
142
  actionRef.current.focusToIndex = function (a) {
143
143
  let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
@@ -203,12 +203,7 @@ const ChatContainerMessagesList = props$2 => {
203
203
 
204
204
  e.preventDefault();
205
205
  (_loadMoreRef$current2 = loadMoreRef.current) === null || _loadMoreRef$current2 === void 0 ? void 0 : _loadMoreRef$current2.focus();
206
- } else if (hasMoreItems === 'top' && e.shiftKey) {
207
- var _loadMoreRef$current3;
208
-
209
- e.preventDefault();
210
- (_loadMoreRef$current3 = loadMoreRef.current) === null || _loadMoreRef$current3 === void 0 ? void 0 : _loadMoreRef$current3.focus();
211
- } else if (!e.shiftKey) {
206
+ } else if (hasMoreItems === 'top' && e.shiftKey) ; else if (!e.shiftKey) {
212
207
  if (bannerPosition) {
213
208
  e.preventDefault();
214
209
  bannerRef.current.focusOnWrapper();
@@ -222,7 +217,7 @@ const ChatContainerMessagesList = props$2 => {
222
217
 
223
218
  break;
224
219
  }
225
- }, [actionRef, bannerRef, hasMoreItems, messages.length, bannerPosition, scrollAndFocus]);
220
+ }, [bannerRef, hasMoreItems, messages.length, bannerPosition, scrollAndFocus]);
226
221
  const handleListKey = React__default["default"].useCallback(e => {
227
222
  const {
228
223
  key
@@ -232,9 +227,7 @@ const ChatContainerMessagesList = props$2 => {
232
227
  case 'ArrowUp':
233
228
  e.preventDefault();
234
229
 
235
- if (document.activeElement === loadMoreRef.current) {
236
- scrollAndFocus(messages.length - 1);
237
- } else {
230
+ if (document.activeElement !== loadMoreRef.current) {
238
231
  onlyFocus(onScrollStop().shift());
239
232
  }
240
233
 
@@ -264,15 +257,15 @@ const ChatContainerMessagesList = props$2 => {
264
257
  case 'Tab':
265
258
  if (document.activeElement !== loadMoreRef.current) {
266
259
  if (hasMoreItems === 'bottom' && !e.shiftKey) {
267
- var _loadMoreRef$current4;
260
+ var _loadMoreRef$current3;
268
261
 
269
262
  e.preventDefault();
270
- (_loadMoreRef$current4 = loadMoreRef.current) === null || _loadMoreRef$current4 === void 0 ? void 0 : _loadMoreRef$current4.focus();
263
+ (_loadMoreRef$current3 = loadMoreRef.current) === null || _loadMoreRef$current3 === void 0 ? void 0 : _loadMoreRef$current3.focus();
271
264
  } else if (hasMoreItems === 'top' && e.shiftKey) {
272
- var _loadMoreRef$current5;
265
+ var _loadMoreRef$current4;
273
266
 
274
267
  e.preventDefault();
275
- (_loadMoreRef$current5 = loadMoreRef.current) === null || _loadMoreRef$current5 === void 0 ? void 0 : _loadMoreRef$current5.focus();
268
+ (_loadMoreRef$current4 = loadMoreRef.current) === null || _loadMoreRef$current4 === void 0 ? void 0 : _loadMoreRef$current4.focus();
276
269
  } else if (!e.shiftKey) {
277
270
  e.preventDefault();
278
271
  actionRef.current.focusToComposer();
@@ -17,7 +17,8 @@ const ChatDataTestIds = {
17
17
  SYSTEM_MSG_TIME: 'chat-system-message-time',
18
18
  BUBBLE: 'ds-chat-bubble',
19
19
  BUBBLE_TITLE: 'chat-bubble-title',
20
- BUBBLE_BODY: 'chat-bubble-body'
20
+ BUBBLE_BODY: 'chat-bubble-body',
21
+ BANNER: 'ds-banner-container'
21
22
  };
22
23
 
23
24
  export { ChatDataTestIds };
@@ -38,10 +38,12 @@ const ChatComposer = props => {
38
38
  placeholder,
39
39
  inputMaxLength,
40
40
  maxLengthMessage,
41
+ ariaMaxLengthMessage,
41
42
  buttonDisabled,
42
43
  dataTestid,
43
44
  actionRef
44
45
  } = props;
46
+ const COMPOSER_MIN_HEIGHT = 32;
45
47
  const input = React.useRef();
46
48
  const inputSize = React.useRef();
47
49
  const inputSend = React.useRef();
@@ -52,10 +54,10 @@ const ChatComposer = props => {
52
54
  var _inputSize$current, _inputSize$current2, _inputSize$current3, _inputSize$current4;
53
55
 
54
56
  const newHeight = ((_inputSize$current = inputSize.current) === null || _inputSize$current === void 0 ? void 0 : _inputSize$current.scrollHeight) > internalMaxHeight ? internalMaxHeight : (_inputSize$current2 = inputSize.current) === null || _inputSize$current2 === void 0 ? void 0 : _inputSize$current2.scrollHeight;
55
- onResize(newHeight);
57
+ if (newHeight !== height && newHeight > COMPOSER_MIN_HEIGHT) onResize(newHeight);
56
58
  setHeight(newHeight);
57
59
  setShowScroll(((_inputSize$current3 = inputSize.current) === null || _inputSize$current3 === void 0 ? void 0 : _inputSize$current3.scrollHeight) - ((_inputSize$current4 = inputSize.current) === null || _inputSize$current4 === void 0 ? void 0 : _inputSize$current4.clientHeight) > 5);
58
- }, [inputValue, internalMaxHeight, onResize]);
60
+ }, [inputValue, internalMaxHeight, height, onResize]);
59
61
  React.useEffect(() => {
60
62
  if (actionRef && actionRef.current) {
61
63
  actionRef.current.focusToComposer = () => {
@@ -82,6 +84,9 @@ const ChatComposer = props => {
82
84
  "data-testid": dataTestid
83
85
  }, void 0, /*#__PURE__*/_jsx(Grid, {
84
86
  cols: ['1fr', '24px'],
87
+ style: {
88
+ height: heightProps.height
89
+ },
85
90
  justifyContent: "center",
86
91
  alignItems: "flex-end",
87
92
  gutter: "xxs"
@@ -95,7 +100,9 @@ const ChatComposer = props => {
95
100
  onKeyDown: onKeyDown,
96
101
  placeholder: placeholder,
97
102
  "aria-label": "Message to send",
98
- "data-testid": "chat-composer-textarea"
103
+ "data-testid": "chat-composer-textarea",
104
+ name: "chat-composer-textarea",
105
+ id: "chat-composer-textarea"
99
106
  }), /*#__PURE__*/_jsx(Grid, {
100
107
  height: "32px",
101
108
  alignItems: "center"
@@ -122,8 +129,7 @@ const ChatComposer = props => {
122
129
  width: (_input$current = input.current) === null || _input$current === void 0 ? void 0 : _input$current.clientWidth
123
130
  },
124
131
  onChange: handleChange,
125
- value: inputValue // maxLength={inputMaxLength}
126
-
132
+ value: inputValue
127
133
  }), /*#__PURE__*/_jsx(Grid, {
128
134
  cols: ['1fr', '24px'],
129
135
  justifyContent: "flex-end",
@@ -136,7 +142,7 @@ const ChatComposer = props => {
136
142
  }, void 0, inputMaxLength && hasError ? /*#__PURE__*/jsxs(Fragment, {
137
143
  children: [/*#__PURE__*/_jsx(StyledCounterErrorA11y, {
138
144
  role: "alert"
139
- }, void 0, maxLengthMessage || "You have entered ".concat(inputLength, " characters and have exceeded the limit by ").concat(inputLength - inputMaxLength, ". Please limit to less than ").concat(inputMaxLength, " characters. ")), maxLengthMessage || "Please limit to less than ".concat(inputMaxLength, " characters. ")]
145
+ }, void 0, ariaMaxLengthMessage || "You have entered ".concat(inputLength, " characters and have exceeded the limit by ").concat(inputLength - inputMaxLength, ". Please limit to less than ").concat(inputMaxLength, " characters. ")), maxLengthMessage || "Please limit to less than ".concat(inputMaxLength, " characters. ")]
140
146
  }) : '', inputMaxLength ? " ".concat(inputLength, " / ").concat(inputMaxLength) : ''), _Grid || (_Grid = /*#__PURE__*/_jsx(Grid, {}))));
141
147
  };
142
148
 
@@ -4,6 +4,7 @@ import { noop } from 'lodash';
4
4
  const defaultComposerPros = {
5
5
  placeholder: 'Type your message',
6
6
  inputValue: '',
7
+ ariaMaxLengthMessage: '',
7
8
  onChange: noop,
8
9
  onResize: noop,
9
10
  onSend: noop,
@@ -20,6 +21,7 @@ const defaultComposerPros = {
20
21
  const composerProps = {
21
22
  placeholder: PropTypes.string.description('Input Placeholder').defaultValue(defaultComposerPros.placeholder),
22
23
  inputValue: PropTypes.string.description('Input value').defaultValue(defaultComposerPros.inputValue),
24
+ ariaMaxLengthMessage: PropTypes.string.description('Aria message for Max length message when exceeded').defaultValue(defaultComposerPros.maxLengthMessage),
23
25
  maxLengthMessage: PropTypes.string.description('Max length message').defaultValue(defaultComposerPros.maxLengthMessage),
24
26
  onChange: PropTypes.func.description('Called when the user types').defaultValue(defaultComposerPros.onChange),
25
27
  onResize: PropTypes.func.description('Called the input changes his height').defaultValue(defaultComposerPros.onResize),
@@ -24,7 +24,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
24
24
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
25
25
 
26
26
  const ChatContainer = props => {
27
- var _containerRef$current;
27
+ var _messagesListProps$me2, _containerRef$current;
28
28
 
29
29
  useValidateProps(props, containerProps);
30
30
  const {
@@ -55,18 +55,16 @@ const ChatContainer = props => {
55
55
  });
56
56
  const onResize = React.useCallback(height => {
57
57
  if (onComposerResize) onComposerResize(height);
58
-
59
- if (height > 30) {
60
- /*
58
+ /*
61
59
  setTimeout is used to equal the animation duration from the
62
60
  composer text area when increase its size
63
61
  */
64
- setTimeout(() => {
65
- actionRef.current.scrollToIndex(messagesListProps.messages.length - 1, {
66
- align: 'start'
67
- });
68
- }, 50);
69
- }
62
+
63
+ setTimeout(() => {
64
+ actionRef.current.scrollToIndex(messagesListProps.messages.length - 1, {
65
+ align: 'start'
66
+ });
67
+ }, 50);
70
68
  }, [onComposerResize, messagesListProps.messages, actionRef]);
71
69
  const Container = device === 'desktop' ? StyledChatContainerContent : MobileStyledChatContainerContent;
72
70
  const handleTabs = React.useCallback(e => {
@@ -74,7 +72,9 @@ const ChatContainer = props => {
74
72
  const ref = actionRef || listRef;
75
73
 
76
74
  if (e.shiftKey && e.key === 'Tab') {
77
- if (messagesListProps.messages.length > 0) {
75
+ var _messagesListProps$me;
76
+
77
+ if (((_messagesListProps$me = messagesListProps.messages) === null || _messagesListProps$me === void 0 ? void 0 : _messagesListProps$me.length) > 0) {
78
78
  e.preventDefault();
79
79
 
80
80
  if (['top', 'bottom'].includes(bannerPosition)) {
@@ -88,7 +88,7 @@ const ChatContainer = props => {
88
88
  }
89
89
  }
90
90
  }
91
- }, [actionRef, onComposerKeyDown, bannerPosition, messagesListProps.messages.length]); // Map actions
91
+ }, [actionRef, onComposerKeyDown, bannerPosition, (_messagesListProps$me2 = messagesListProps.messages) === null || _messagesListProps$me2 === void 0 ? void 0 : _messagesListProps$me2.length]); // Map actions
92
92
 
93
93
  React.useEffect(() => {
94
94
  if (actionRef && actionRef.current) {
@@ -10,7 +10,7 @@ const StyledChatContainerContent = /*#__PURE__*/styled(Grid).withConfig({
10
10
  })(["height:100%;min-width:", "px;overflow:hidden;background:", ";position:relative;"], CONTAINER_WIDTH, props => props.theme.colors.neutral['050']);
11
11
  const StyledIndicatorContainer = /*#__PURE__*/styled.div.withConfig({
12
12
  componentId: "sc-d732wo-1"
13
- })(["transition:0.4s ease-in-out;position:absolute;visibility:hidden;pointer-events:none;width:100%;padding:0 ", ";left:0;right:0;background:", ";", " ", " & div,a{font-size:13px;}"], props => !props.linear ? props.theme.space.xxs : 0, props => props.theme.colors.neutral['000'], props => props.isLoading === 'top' ? "\n top: -41px;\n transform: translate(0, 41px);\n visibility: visible;\n pointer-events: auto\n " : '', props => props.isLoading === 'bottom' ? "\n bottom: -41px;\n transform: translate(0, -41px);\n visibility: visible;\n pointer-events: auto;\n " : '');
13
+ })(["transition:0.4s ease-in-out;position:absolute;visibility:hidden;pointer-events:none;width:100%;padding:0 ", ";left:0;right:0;background:", ";", " ", " & div,a{font-size:13px;}"], props => !props.linear ? props.theme.space.xxs : 0, props => props.theme.colors.neutral['000'], props => props.isLoading === 'top' ? "\n top: -41px;\n transform: translate(0, 41px);\n visibility: visible;\n pointer-events: auto;\n " : '', props => props.isLoading === 'bottom' ? "\n bottom: -41px;\n transform: translate(0, -41px);\n visibility: visible;\n pointer-events: auto;\n " : '');
14
14
  const MobileStyledChatContainerContent = /*#__PURE__*/styled(StyledChatContainerContent).withConfig({
15
15
  componentId: "sc-d732wo-2"
16
16
  })(["", ",", "{font-size:16px;}", "{font-size:13px;}", "{background-color:#fff;box-shadow:-0 1px 3px rgba(53,60,70,0.8);}", ",", "{font-size:16px;text-align:left;}", "{font-size:13px;}", "{font-size:16px;}", "{font-size:16px;}"], StyledTitleLeftBubble, StyleBodyWrapper, StyledTitleRightBubble, Wrapper, Title, Message, Time, StyledComposerInput, StyledIndicatorContainer);
@@ -22,7 +22,6 @@ import { MessageDelimiter } from '../message-delimiter/MessageDelimiter.js';
22
22
  import { SystemMessage } from '../system-message/SystemMessage.js';
23
23
  import { ListItem, StyledWrapperListItem, StyledWrapper, StyledChatContainerContentList, StyledChatContainerContentListScroll, StyledLoadMoreContainer } from './styled.js';
24
24
  import { listProps, defaultProps } from './props.js';
25
- import { useValidateProps } from './config/useValidateProps.js';
26
25
  import { jsx } from 'react/jsx-runtime';
27
26
 
28
27
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
@@ -44,7 +43,6 @@ const getPadding = _ref => {
44
43
  };
45
44
 
46
45
  const ChatContainerMessagesList = props => {
47
- useValidateProps(props, listProps);
48
46
  const {
49
47
  sendingText,
50
48
  bannerPosition,
@@ -85,6 +83,7 @@ const ChatContainerMessagesList = props => {
85
83
  return [];
86
84
  }
87
85
 
86
+ if (!virtualListRef.current) return [];
88
87
  pendingOnScroll.current = false;
89
88
  const {
90
89
  bottom,
@@ -127,6 +126,7 @@ const ChatContainerMessagesList = props => {
127
126
  };
128
127
 
129
128
  actionRef.current.getMessagesInView = onScrollStop;
129
+ onScrollStop(); // init useMemo due to debounce use.
130
130
 
131
131
  actionRef.current.focusToIndex = function (a) {
132
132
  let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
@@ -192,12 +192,7 @@ const ChatContainerMessagesList = props => {
192
192
 
193
193
  e.preventDefault();
194
194
  (_loadMoreRef$current2 = loadMoreRef.current) === null || _loadMoreRef$current2 === void 0 ? void 0 : _loadMoreRef$current2.focus();
195
- } else if (hasMoreItems === 'top' && e.shiftKey) {
196
- var _loadMoreRef$current3;
197
-
198
- e.preventDefault();
199
- (_loadMoreRef$current3 = loadMoreRef.current) === null || _loadMoreRef$current3 === void 0 ? void 0 : _loadMoreRef$current3.focus();
200
- } else if (!e.shiftKey) {
195
+ } else if (hasMoreItems === 'top' && e.shiftKey) ; else if (!e.shiftKey) {
201
196
  if (bannerPosition) {
202
197
  e.preventDefault();
203
198
  bannerRef.current.focusOnWrapper();
@@ -211,7 +206,7 @@ const ChatContainerMessagesList = props => {
211
206
 
212
207
  break;
213
208
  }
214
- }, [actionRef, bannerRef, hasMoreItems, messages.length, bannerPosition, scrollAndFocus]);
209
+ }, [bannerRef, hasMoreItems, messages.length, bannerPosition, scrollAndFocus]);
215
210
  const handleListKey = React.useCallback(e => {
216
211
  const {
217
212
  key
@@ -221,9 +216,7 @@ const ChatContainerMessagesList = props => {
221
216
  case 'ArrowUp':
222
217
  e.preventDefault();
223
218
 
224
- if (document.activeElement === loadMoreRef.current) {
225
- scrollAndFocus(messages.length - 1);
226
- } else {
219
+ if (document.activeElement !== loadMoreRef.current) {
227
220
  onlyFocus(onScrollStop().shift());
228
221
  }
229
222
 
@@ -253,15 +246,15 @@ const ChatContainerMessagesList = props => {
253
246
  case 'Tab':
254
247
  if (document.activeElement !== loadMoreRef.current) {
255
248
  if (hasMoreItems === 'bottom' && !e.shiftKey) {
256
- var _loadMoreRef$current4;
249
+ var _loadMoreRef$current3;
257
250
 
258
251
  e.preventDefault();
259
- (_loadMoreRef$current4 = loadMoreRef.current) === null || _loadMoreRef$current4 === void 0 ? void 0 : _loadMoreRef$current4.focus();
252
+ (_loadMoreRef$current3 = loadMoreRef.current) === null || _loadMoreRef$current3 === void 0 ? void 0 : _loadMoreRef$current3.focus();
260
253
  } else if (hasMoreItems === 'top' && e.shiftKey) {
261
- var _loadMoreRef$current5;
254
+ var _loadMoreRef$current4;
262
255
 
263
256
  e.preventDefault();
264
- (_loadMoreRef$current5 = loadMoreRef.current) === null || _loadMoreRef$current5 === void 0 ? void 0 : _loadMoreRef$current5.focus();
257
+ (_loadMoreRef$current4 = loadMoreRef.current) === null || _loadMoreRef$current4 === void 0 ? void 0 : _loadMoreRef$current4.focus();
265
258
  } else if (!e.shiftKey) {
266
259
  e.preventDefault();
267
260
  actionRef.current.focusToComposer();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-chat",
3
- "version": "2.1.0-rc.1",
3
+ "version": "2.1.0-rc.10",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Chat",
6
6
  "module": "./esm/index.js",
@@ -305,15 +305,15 @@
305
305
  "generateSubmodules": true
306
306
  },
307
307
  "dependencies": {
308
- "@elliemae/ds-banner": "2.1.0-rc.1",
309
- "@elliemae/ds-button": "2.1.0-rc.1",
310
- "@elliemae/ds-grid": "2.1.0-rc.1",
311
- "@elliemae/ds-icons": "2.1.0-rc.1",
312
- "@elliemae/ds-indeterminate-progress-indicator": "2.1.0-rc.1",
313
- "@elliemae/ds-props-helpers": "2.1.0-rc.1",
314
- "@elliemae/ds-system": "2.1.0-rc.1",
315
- "@elliemae/ds-tooltip": "2.1.0-rc.1",
316
- "@elliemae/ds-truncated-tooltip-text": "2.1.0-rc.1",
308
+ "@elliemae/ds-banner": "2.1.0-rc.10",
309
+ "@elliemae/ds-button": "2.1.0-rc.10",
310
+ "@elliemae/ds-grid": "2.1.0-rc.10",
311
+ "@elliemae/ds-icons": "2.1.0-rc.10",
312
+ "@elliemae/ds-indeterminate-progress-indicator": "2.1.0-rc.10",
313
+ "@elliemae/ds-props-helpers": "2.1.0-rc.10",
314
+ "@elliemae/ds-system": "2.1.0-rc.10",
315
+ "@elliemae/ds-tooltip": "2.1.0-rc.10",
316
+ "@elliemae/ds-truncated-tooltip-text": "2.1.0-rc.10",
317
317
  "prop-types": "~15.7.2",
318
318
  "react-desc": "~4.1.2",
319
319
  "react-virtual": "~2.3.2"
@@ -18,4 +18,5 @@ export declare const ChatDataTestIds: {
18
18
  BUBBLE: string;
19
19
  BUBBLE_TITLE: string;
20
20
  BUBBLE_BODY: string;
21
+ BANNER: string;
21
22
  };
@@ -10,6 +10,9 @@ declare const ChatComposer: {
10
10
  inputValue: {
11
11
  deprecated: import("react-desc").PropTypesDescValidator;
12
12
  };
13
+ ariaMaxLengthMessage: {
14
+ deprecated: import("react-desc").PropTypesDescValidator;
15
+ };
13
16
  maxLengthMessage: {
14
17
  deprecated: import("react-desc").PropTypesDescValidator;
15
18
  };
@@ -1,27 +1 @@
1
- export declare const preLoadMessages2: ({
2
- dsId: string;
3
- body: string;
4
- type: string;
5
- title: string;
6
- time: string;
7
- extraProps?: undefined;
8
- helpMessage?: undefined;
9
- } | {
10
- dsId: string;
11
- type: string;
12
- title: string;
13
- extraProps: {
14
- 'data-testid': string;
15
- };
16
- body?: undefined;
17
- time?: undefined;
18
- helpMessage?: undefined;
19
- } | {
20
- dsId: string;
21
- body: string;
22
- type: string;
23
- title: string;
24
- time: string;
25
- helpMessage: string | null;
26
- extraProps?: undefined;
27
- })[];
1
+ export declare const loadMsgs: (q: number) => unknown;