@elliemae/ds-chat 2.0.0-next.6 → 2.0.0-rc.1
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.
- package/cjs/parts/bubble/ChatBubble.js +9 -6
- package/cjs/parts/bubble/ChatBubbleArrow.js +64 -61
- package/cjs/parts/bubble/props.js +1 -1
- package/cjs/parts/bubble/styled.js +1 -1
- package/cjs/parts/chat-composer/ChatContainerComposer.js +14 -7
- package/cjs/parts/chat-composer/props.js +4 -0
- package/cjs/parts/chat-composer/styled.js +2 -2
- package/cjs/parts/chat-container/ChatContainer.js +50 -9
- package/cjs/parts/chat-container/props.js +1 -1
- package/cjs/parts/chat-container/styled.js +1 -1
- package/cjs/parts/chat-container-header/ChatContainerHeader.js +3 -3
- package/cjs/parts/chat-container-header/helpers.js +31 -0
- package/cjs/parts/chat-container-header/styled.js +6 -6
- package/cjs/parts/chat-container-messages-list/ChatContainerMessagesList.js +134 -29
- package/cjs/parts/chat-container-messages-list/props.js +4 -2
- package/cjs/parts/chat-container-messages-list/styled.js +2 -2
- package/cjs/parts/chat-empty-state/ChatEmptyState.js +2 -3
- package/cjs/parts/chat-sidebar/SideBarChat.js +57 -29
- package/cjs/parts/chat-sidebar/props.js +11 -1
- package/cjs/parts/chat-sidebar/styled.js +2 -2
- package/cjs/parts/floating-button/FloatingButton.js +12 -10
- package/cjs/parts/sidebar-button/SidebarButton.js +5 -0
- package/cjs/parts/sidebar-button/props.js +2 -3
- package/cjs/parts/system-message/style.js +1 -1
- package/cjs/parts/tile-button/TileButton.js +30 -27
- package/cjs/parts/tile-button/props.js +12 -8
- package/cjs/parts/tile-button/styled.js +6 -2
- package/esm/parts/bubble/ChatBubble.js +8 -5
- package/esm/parts/bubble/ChatBubbleArrow.js +64 -61
- package/esm/parts/bubble/props.js +1 -1
- package/esm/parts/bubble/styled.js +1 -1
- package/esm/parts/chat-composer/ChatContainerComposer.js +13 -5
- package/esm/parts/chat-composer/props.js +4 -0
- package/esm/parts/chat-container/ChatContainer.js +50 -9
- package/esm/parts/chat-container/props.js +1 -1
- package/esm/parts/chat-container/styled.js +1 -1
- package/esm/parts/chat-container-header/ChatContainerHeader.js +3 -2
- package/esm/parts/chat-container-header/helpers.js +23 -0
- package/esm/parts/chat-container-header/styled.js +6 -6
- package/esm/parts/chat-container-messages-list/ChatContainerMessagesList.js +134 -29
- package/esm/parts/chat-container-messages-list/props.js +4 -2
- package/esm/parts/chat-container-messages-list/styled.js +2 -2
- package/esm/parts/chat-empty-state/ChatEmptyState.js +1 -1
- package/esm/parts/chat-sidebar/SideBarChat.js +57 -28
- package/esm/parts/chat-sidebar/props.js +11 -1
- package/esm/parts/chat-sidebar/styled.js +2 -2
- package/esm/parts/floating-button/FloatingButton.js +12 -9
- package/esm/parts/sidebar-button/SidebarButton.js +5 -0
- package/esm/parts/sidebar-button/props.js +1 -1
- package/esm/parts/system-message/style.js +1 -1
- package/esm/parts/tile-button/TileButton.js +31 -26
- package/esm/parts/tile-button/props.js +11 -3
- package/esm/parts/tile-button/styled.js +6 -3
- package/package.json +16 -6
- package/types/parts/bubble/styled.d.ts +3 -3
- package/types/parts/bubble/tests/ChatBubble.test.d.ts +1 -0
- package/types/parts/chat-card/styled.d.ts +1 -1
- package/types/parts/chat-composer/ChatContainerComposer.d.ts +2 -0
- package/types/parts/chat-composer/props.d.ts +10 -6
- package/types/parts/chat-composer/styled.d.ts +2 -2
- package/types/parts/chat-composer/tests/ChatContainerComposer.test.d.ts +1 -0
- package/types/parts/chat-container/props.d.ts +2 -0
- package/types/parts/chat-container/styled.d.ts +2 -2
- package/types/parts/chat-container-header/helpers.d.ts +6 -0
- package/types/parts/chat-container-header/styled.d.ts +3 -3
- package/types/parts/chat-container-messages-list/props.d.ts +6 -0
- package/types/parts/chat-empty-state/styled.d.ts +1 -1
- package/types/parts/chat-sidebar/SideBarChat.d.ts +3 -0
- package/types/parts/chat-sidebar/props.d.ts +8 -1
- package/types/parts/chat-sidebar/styled.d.ts +2 -2
- package/types/parts/floating-container/styled.d.ts +1 -1
- package/types/parts/grid-influencer/styled.d.ts +2 -2
- package/types/parts/message-delimiter/styled.d.ts +1 -1
- package/types/parts/sidebar-button/styled.d.ts +1 -1
- package/types/parts/system-message/style.d.ts +2 -2
- package/types/parts/tile-button/TileButton.d.ts +3 -0
- package/types/parts/tile-button/props.d.ts +6 -0
- package/types/parts/tile-button/styled.d.ts +5 -4
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
2
|
-
import
|
|
2
|
+
import 'react';
|
|
3
3
|
import { SimpleTruncatedTooltipText } from '@elliemae/ds-truncated-tooltip-text';
|
|
4
4
|
import { StyledChatContainerContentHeader, StyledChatContainerContentHeaderLabel, StyledChatContainerContentHeaderActions } from './styled.js';
|
|
5
|
+
import { validHeaderChilds } from './helpers.js';
|
|
5
6
|
|
|
6
7
|
const ChatContainerHeader = props => {
|
|
7
8
|
const {
|
|
@@ -21,7 +22,7 @@ const ChatContainerHeader = props => {
|
|
|
21
22
|
}, void 0, /*#__PURE__*/_jsx(SimpleTruncatedTooltipText, {
|
|
22
23
|
value: title
|
|
23
24
|
})), /*#__PURE__*/_jsx(StyledChatContainerContentHeaderActions, {
|
|
24
|
-
cols:
|
|
25
|
+
cols: validHeaderChilds(children),
|
|
25
26
|
justifyContent: "flex-end",
|
|
26
27
|
"data-testid": "chat-container-header-children"
|
|
27
28
|
}, void 0, children));
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import 'core-js/modules/esnext.async-iterator.map.js';
|
|
2
|
+
import 'core-js/modules/esnext.iterator.map.js';
|
|
3
|
+
import 'core-js/modules/esnext.async-iterator.filter.js';
|
|
4
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
5
|
+
import 'core-js/modules/esnext.iterator.filter.js';
|
|
6
|
+
import 'core-js/modules/esnext.async-iterator.constructor.js';
|
|
7
|
+
import 'core-js/modules/esnext.async-iterator.to-array.js';
|
|
8
|
+
import 'core-js/modules/esnext.iterator.to-array.js';
|
|
9
|
+
import React from 'react';
|
|
10
|
+
|
|
11
|
+
const validHeaderChilds = children => React.Children.toArray(children).filter(e => {
|
|
12
|
+
if (Array.isArray(e.props.children)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (e.props.children === undefined && e.$$typeof.toString() === 'Symbol(react.element)') {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return !!e.props.children;
|
|
21
|
+
}).map(() => '32px');
|
|
22
|
+
|
|
23
|
+
export { validHeaderChilds };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
2
|
import { Grid } from '@elliemae/ds-grid';
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const StyledChatContainerContentHeaderActions = /*#__PURE__*/styled(Grid).withConfig({
|
|
5
5
|
componentId: "sc-jmynvr-0"
|
|
6
|
-
})(["width:
|
|
7
|
-
const
|
|
6
|
+
})(["max-width:80px;"]);
|
|
7
|
+
const StyledChatContainerContentHeader = /*#__PURE__*/styled(Grid).withConfig({
|
|
8
8
|
componentId: "sc-jmynvr-1"
|
|
9
|
-
})(["
|
|
10
|
-
const
|
|
9
|
+
})(["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);
|
|
10
|
+
const StyledChatContainerContentHeaderLabel = /*#__PURE__*/styled(Grid).withConfig({
|
|
11
11
|
componentId: "sc-jmynvr-2"
|
|
12
|
-
})(["
|
|
12
|
+
})(["justify-content:center;align-items:center;font-weight:bold;font-size:18px;color:", ";"], props => props.theme.colors.neutral['700']);
|
|
13
13
|
|
|
14
14
|
export { StyledChatContainerContentHeader, StyledChatContainerContentHeaderActions, StyledChatContainerContentHeaderLabel };
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
import 'core-js/modules/esnext.async-iterator.filter.js';
|
|
2
|
+
import 'core-js/modules/esnext.iterator.filter.js';
|
|
1
3
|
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
2
4
|
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
|
5
|
+
import 'core-js/modules/esnext.async-iterator.for-each.js';
|
|
6
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
7
|
+
import 'core-js/modules/esnext.iterator.for-each.js';
|
|
8
|
+
import 'core-js/modules/esnext.async-iterator.map.js';
|
|
9
|
+
import 'core-js/modules/esnext.iterator.map.js';
|
|
10
|
+
import 'core-js/modules/esnext.async-iterator.find.js';
|
|
11
|
+
import 'core-js/modules/esnext.iterator.find.js';
|
|
3
12
|
import React from 'react';
|
|
4
13
|
import { describe } from 'react-desc';
|
|
5
14
|
import { useVirtual } from 'react-virtual';
|
|
6
|
-
import DSButton from '@elliemae/ds-
|
|
15
|
+
import DSButton from '@elliemae/ds-button';
|
|
7
16
|
import { ChatBubble } from '../bubble/ChatBubble.js';
|
|
8
17
|
import { BUBBLE_TYPES } from '../bubble/props.js';
|
|
9
18
|
import { MessageDelimiter } from '../message-delimiter/MessageDelimiter.js';
|
|
@@ -30,14 +39,17 @@ const ChatContainerMessagesList = props => {
|
|
|
30
39
|
useValidateProps(props, ChatContainerMessagesListWithSchema.toTypescript());
|
|
31
40
|
const {
|
|
32
41
|
sendingText,
|
|
42
|
+
bannerPosition,
|
|
33
43
|
sendingMessages,
|
|
34
44
|
messages,
|
|
35
45
|
actionRef,
|
|
36
46
|
onScrollEnds,
|
|
37
47
|
getMoreMessages,
|
|
38
48
|
hasMoreItems,
|
|
39
|
-
isLoading
|
|
49
|
+
isLoading,
|
|
50
|
+
bannerRef
|
|
40
51
|
} = props;
|
|
52
|
+
const loadMoreRef = React.useRef(null);
|
|
41
53
|
const virtualListRef = React.useRef(); // estimateSize should not be really required given what was stated on
|
|
42
54
|
// https://github.com/tannerlinsley/react-virtual/issues/23
|
|
43
55
|
|
|
@@ -53,67 +65,80 @@ const ChatContainerMessagesList = props => {
|
|
|
53
65
|
estimateSize: React.useCallback(() => 80, [])
|
|
54
66
|
}));
|
|
55
67
|
const onScrollStop = React.useCallback(() => {
|
|
68
|
+
var _virtualListRef$curre;
|
|
69
|
+
|
|
56
70
|
const {
|
|
57
71
|
bottom,
|
|
58
72
|
top
|
|
59
|
-
} = virtualListRef.current.getBoundingClientRect();
|
|
73
|
+
} = (_virtualListRef$curre = virtualListRef.current) === null || _virtualListRef$curre === void 0 ? void 0 : _virtualListRef$curre.getBoundingClientRect();
|
|
60
74
|
const list = virtualListRef.current.querySelectorAll('[data-element="chat-element-list-item"]');
|
|
61
75
|
const indexList = [];
|
|
62
76
|
list.forEach(item => {
|
|
63
77
|
const {
|
|
64
|
-
top: itemTop
|
|
78
|
+
top: itemTop,
|
|
79
|
+
bottom: itemBottom
|
|
65
80
|
} = item.getBoundingClientRect();
|
|
66
|
-
|
|
81
|
+
const itemPadding = 10;
|
|
82
|
+
if (itemTop + itemPadding < bottom && itemBottom - itemPadding > top) indexList.push(item.dataset.index);
|
|
67
83
|
});
|
|
68
84
|
if (onScrollEnds) onScrollEnds(indexList);
|
|
69
85
|
return indexList;
|
|
70
86
|
}, [onScrollEnds]);
|
|
71
|
-
const
|
|
72
|
-
vScroll(index, {
|
|
73
|
-
align: 'center'
|
|
74
|
-
});
|
|
87
|
+
const onlyFocus = React.useCallback(index => {
|
|
75
88
|
setTimeout(() => {
|
|
76
89
|
virtualListRef.current.querySelector("[data-index=\"".concat(index, "\"]")).focus();
|
|
77
90
|
}, 300);
|
|
78
|
-
}, [
|
|
91
|
+
}, []);
|
|
92
|
+
const scrollAndFocus = React.useCallback(function (index) {
|
|
93
|
+
let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
94
|
+
align: 'center'
|
|
95
|
+
};
|
|
96
|
+
vScroll(index, b);
|
|
97
|
+
onlyFocus(index);
|
|
98
|
+
}, [onlyFocus, vScroll]);
|
|
79
99
|
React.useEffect(() => {
|
|
80
100
|
if (actionRef && actionRef.current) {
|
|
81
|
-
actionRef.current.scrollToIndex = (a
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
actionRef.current.scrollToIndex = function (a) {
|
|
102
|
+
let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
103
|
+
align: 'center'
|
|
104
|
+
};
|
|
84
105
|
vScroll(a, b);
|
|
85
106
|
};
|
|
86
107
|
|
|
87
108
|
actionRef.current.getMessagesInView = onScrollStop;
|
|
88
109
|
|
|
89
|
-
actionRef.current.focusToIndex = (a
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
110
|
+
actionRef.current.focusToIndex = function (a) {
|
|
111
|
+
let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
112
|
+
align: 'center'
|
|
113
|
+
};
|
|
114
|
+
scrollAndFocus(a, b);
|
|
93
115
|
};
|
|
94
116
|
|
|
95
|
-
actionRef.current.
|
|
96
|
-
align: 'center'
|
|
97
|
-
}) => {
|
|
98
|
-
var _virtualListRef$curre;
|
|
117
|
+
actionRef.current.focusToIndexWithoutScroll = onlyFocus;
|
|
99
118
|
|
|
100
|
-
|
|
119
|
+
actionRef.current.focusToList = a => {
|
|
120
|
+
var _virtualListRef$curre2;
|
|
121
|
+
|
|
122
|
+
(_virtualListRef$curre2 = virtualListRef.current) === null || _virtualListRef$curre2 === void 0 ? void 0 : _virtualListRef$curre2.focus();
|
|
101
123
|
};
|
|
102
124
|
}
|
|
103
|
-
}, [actionRef, onScrollStop, scrollAndFocus, vScroll]);
|
|
125
|
+
}, [actionRef, onScrollStop, onlyFocus, scrollAndFocus, vScroll]);
|
|
104
126
|
const handleKey = React.useCallback(e => {
|
|
105
|
-
e.preventDefault();
|
|
106
127
|
const {
|
|
107
128
|
key
|
|
108
129
|
} = e;
|
|
109
130
|
const index = Number(e.currentTarget.dataset.index);
|
|
131
|
+
e.stopPropagation();
|
|
110
132
|
|
|
111
133
|
switch (key) {
|
|
112
134
|
case 'ArrowUp':
|
|
135
|
+
e.preventDefault();
|
|
113
136
|
if (index > 0) virtualListRef.current.querySelector("[data-index=\"".concat(index - 1, "\"]")).focus();
|
|
114
137
|
break;
|
|
115
138
|
|
|
116
139
|
case 'ArrowDown':
|
|
140
|
+
e.preventDefault();
|
|
141
|
+
|
|
117
142
|
if (index < messages.length - 1) {
|
|
118
143
|
virtualListRef.current.querySelector("[data-index=\"".concat(index + 1, "\"]")).focus();
|
|
119
144
|
}
|
|
@@ -121,18 +146,96 @@ const ChatContainerMessagesList = props => {
|
|
|
121
146
|
break;
|
|
122
147
|
|
|
123
148
|
case 'Home':
|
|
149
|
+
e.preventDefault();
|
|
150
|
+
scrollAndFocus(0);
|
|
151
|
+
break;
|
|
152
|
+
|
|
153
|
+
case 'End':
|
|
154
|
+
e.preventDefault();
|
|
155
|
+
scrollAndFocus(messages.length - 1);
|
|
156
|
+
break;
|
|
157
|
+
|
|
158
|
+
case 'Tab':
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
|
|
161
|
+
if (hasMoreItems === 'bottom' && !e.shiftKey) {
|
|
162
|
+
var _loadMoreRef$current;
|
|
163
|
+
|
|
164
|
+
(_loadMoreRef$current = loadMoreRef.current) === null || _loadMoreRef$current === void 0 ? void 0 : _loadMoreRef$current.focus();
|
|
165
|
+
} else if (hasMoreItems === 'top' && e.shiftKey) {
|
|
166
|
+
var _loadMoreRef$current2;
|
|
167
|
+
|
|
168
|
+
(_loadMoreRef$current2 = loadMoreRef.current) === null || _loadMoreRef$current2 === void 0 ? void 0 : _loadMoreRef$current2.focus();
|
|
169
|
+
} else if (!e.shiftKey) {
|
|
170
|
+
if (bannerPosition) {
|
|
171
|
+
bannerRef.current.focusOnWrapper();
|
|
172
|
+
} else {
|
|
173
|
+
actionRef.current.focusToComposer();
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
var _virtualListRef$curre3;
|
|
177
|
+
|
|
178
|
+
(_virtualListRef$curre3 = virtualListRef.current) === null || _virtualListRef$curre3 === void 0 ? void 0 : _virtualListRef$curre3.focus();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}, [actionRef, hasMoreItems, messages.length, bannerPosition, scrollAndFocus]);
|
|
184
|
+
const handleListKey = React.useCallback(e => {
|
|
185
|
+
const {
|
|
186
|
+
key
|
|
187
|
+
} = e;
|
|
188
|
+
|
|
189
|
+
switch (key) {
|
|
190
|
+
case 'ArrowUp':
|
|
191
|
+
e.preventDefault();
|
|
192
|
+
onlyFocus(onScrollStop().shift());
|
|
193
|
+
break;
|
|
194
|
+
|
|
195
|
+
case 'ArrowDown':
|
|
196
|
+
e.preventDefault();
|
|
197
|
+
onlyFocus(onScrollStop().pop());
|
|
198
|
+
break;
|
|
199
|
+
|
|
200
|
+
case 'Home':
|
|
201
|
+
e.preventDefault();
|
|
124
202
|
scrollAndFocus(0);
|
|
125
203
|
break;
|
|
126
204
|
|
|
127
205
|
case 'End':
|
|
206
|
+
e.preventDefault();
|
|
128
207
|
scrollAndFocus(messages.length - 1);
|
|
129
208
|
break;
|
|
130
209
|
|
|
131
210
|
case 'Tab':
|
|
132
|
-
|
|
211
|
+
if (document.activeElement !== loadMoreRef.current) {
|
|
212
|
+
if (hasMoreItems === 'bottom' && !e.shiftKey) {
|
|
213
|
+
var _loadMoreRef$current3;
|
|
214
|
+
|
|
215
|
+
e.preventDefault();
|
|
216
|
+
(_loadMoreRef$current3 = loadMoreRef.current) === null || _loadMoreRef$current3 === void 0 ? void 0 : _loadMoreRef$current3.focus();
|
|
217
|
+
} else if (hasMoreItems === 'top' && e.shiftKey) {
|
|
218
|
+
var _loadMoreRef$current4;
|
|
219
|
+
|
|
220
|
+
e.preventDefault();
|
|
221
|
+
(_loadMoreRef$current4 = loadMoreRef.current) === null || _loadMoreRef$current4 === void 0 ? void 0 : _loadMoreRef$current4.focus();
|
|
222
|
+
} else if (!e.shiftKey) {
|
|
223
|
+
e.preventDefault();
|
|
224
|
+
actionRef.current.focusToComposer();
|
|
225
|
+
}
|
|
226
|
+
} else if (!e.shiftKey) {
|
|
227
|
+
e.preventDefault();
|
|
228
|
+
actionRef.current.focusToComposer();
|
|
229
|
+
} else {
|
|
230
|
+
var _virtualListRef$curre4;
|
|
231
|
+
|
|
232
|
+
e.preventDefault();
|
|
233
|
+
(_virtualListRef$curre4 = virtualListRef.current) === null || _virtualListRef$curre4 === void 0 ? void 0 : _virtualListRef$curre4.focus();
|
|
234
|
+
}
|
|
235
|
+
|
|
133
236
|
break;
|
|
134
237
|
}
|
|
135
|
-
}, [actionRef, messages.length, scrollAndFocus]);
|
|
238
|
+
}, [actionRef, hasMoreItems, messages.length, onScrollStop, onlyFocus, scrollAndFocus]);
|
|
136
239
|
React.useEffect(() => {
|
|
137
240
|
let handlerCallback = null;
|
|
138
241
|
const localVirtualRef = virtualListRef.current;
|
|
@@ -182,7 +285,7 @@ const ChatContainerMessagesList = props => {
|
|
|
182
285
|
jsx(ChatBubble, _objectSpread(_objectSpread({}, row), {}, {
|
|
183
286
|
helpMessage: isSending ? sendingText : row.helpMessage
|
|
184
287
|
})) : null, row.type === BUBBLE_TYPES.DELIMITER ? /*#__PURE__*/jsx(MessageDelimiter, _objectSpread({}, row)) : null, row.type === BUBBLE_TYPES.SYSTEM ? /*#__PURE__*/jsx(SystemMessage, _objectSpread({}, row)) : null)
|
|
185
|
-
}, "ds-chat-bubble-".concat(index));
|
|
288
|
+
}, "ds-chat-bubble-".concat(index, "-").concat(row.dsId, "-").concat(row.type));
|
|
186
289
|
}), [virtualItems, messages, sendingMessages, handleKey, sendingText]);
|
|
187
290
|
return /*#__PURE__*/_jsx(StyledWrapper, {}, void 0, /*#__PURE__*/jsx(StyledChatContainerContentList, {
|
|
188
291
|
"data-testid": "chat-thread-container",
|
|
@@ -190,7 +293,7 @@ const ChatContainerMessagesList = props => {
|
|
|
190
293
|
"aria-live": "polite",
|
|
191
294
|
ref: virtualListRef,
|
|
192
295
|
role: "list",
|
|
193
|
-
onKeyDown:
|
|
296
|
+
onKeyDown: handleListKey,
|
|
194
297
|
children: /*#__PURE__*/_jsx(StyledChatContainerContentListScroll, {
|
|
195
298
|
height: "".concat(totalSize, "px")
|
|
196
299
|
}, void 0, render, !isLoading && hasMoreItems ? /*#__PURE__*/_jsx(StyledLoadMoreContainer, {
|
|
@@ -198,7 +301,9 @@ const ChatContainerMessagesList = props => {
|
|
|
198
301
|
}, void 0, /*#__PURE__*/_jsx(DSButton, {
|
|
199
302
|
labelText: "Load More",
|
|
200
303
|
buttonType: "secondary",
|
|
201
|
-
onClick: getMoreMessages
|
|
304
|
+
onClick: getMoreMessages,
|
|
305
|
+
"data-testid": "ds-chat-load-more-btn",
|
|
306
|
+
innerRef: loadMoreRef
|
|
202
307
|
})) : null)
|
|
203
308
|
}));
|
|
204
309
|
};
|
|
@@ -7,11 +7,13 @@ const defaultProps = {
|
|
|
7
7
|
onScrollEnds: () => [],
|
|
8
8
|
getMoreMessages: noop,
|
|
9
9
|
sendingMessages: undefined,
|
|
10
|
-
sendingText: 'Sending'
|
|
10
|
+
sendingText: 'Sending',
|
|
11
|
+
bannerPosition: undefined,
|
|
12
|
+
bannerRef: undefined
|
|
11
13
|
};
|
|
12
14
|
const listProps = {
|
|
13
15
|
messages: PropTypes.arrayOf(PropTypes.object).description('The array of out-of-the-box items you want to render inside the ChatMessageList').defaultValue(defaultProps.messages),
|
|
14
|
-
actionRef: 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),
|
|
16
|
+
actionRef: 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),
|
|
15
17
|
onScrollEnds: PropTypes.func.description("Called when the scroll stops."),
|
|
16
18
|
isLoading: PropTypes.oneOf(['top', 'bottom', undefined]).description('Keeps the load more space while the loading is in progress'),
|
|
17
19
|
hasMoreItems: PropTypes.oneOf(['top', 'bottom', undefined]).description('Show Load More button at the `top` or `bottom` of the container'),
|
|
@@ -8,7 +8,7 @@ const StyledWrapper = /*#__PURE__*/styled.div.withConfig({
|
|
|
8
8
|
|
|
9
9
|
const StyledWrapperListItem = /*#__PURE__*/styled.div.withConfig({
|
|
10
10
|
componentId: "sc-1jhprzr-1"
|
|
11
|
-
})(["min-width:100%;", ";", ";", ";"], props => props.type === BUBBLE_TYPES.SENDER && "padding: ".concat(props.theme.space.xxs, " ").concat(props.theme.space.xxs, "
|
|
11
|
+
})(["min-width:100%;", ";", ";", ";"], props => props.type === BUBBLE_TYPES.SENDER && "padding: ".concat(props.theme.space.xxs, " ").concat(props.theme.space.xxs, " ").concat(props.theme.space.xxs, " 13%\n "), props => props.type === BUBBLE_TYPES.RECIPIENT && "padding: ".concat(props.theme.space.xxs, " 13% ").concat(props.theme.space.xxs, "\n ").concat(props.theme.space.xxs, "\n "), props => props.type === BUBBLE_TYPES.SYSTEM && "padding: ".concat(props.theme.space.xxs, " 0px\n "));
|
|
12
12
|
const StyledChatContainerContentList = /*#__PURE__*/styled.div.withConfig({
|
|
13
13
|
componentId: "sc-1jhprzr-2"
|
|
14
14
|
})(["width:100%;height:100%;padding:", ";padding-bottom:0;overflow-y:auto;overflow-x:hidden;"], props => props.theme.space.xs);
|
|
@@ -20,6 +20,6 @@ const StyledLoadMoreContainer = /*#__PURE__*/styled.div.withConfig({
|
|
|
20
20
|
})(["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;' : '');
|
|
21
21
|
const ListItem = /*#__PURE__*/styled.div.withConfig({
|
|
22
22
|
componentId: "sc-1jhprzr-5"
|
|
23
|
-
})(["&:focus,&:focus-visible{outline:none;&:after{content:'';display:block;position:absolute;pointer-events:none;
|
|
23
|
+
})(["&: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);
|
|
24
24
|
|
|
25
25
|
export { ListItem, StyledChatContainerContentList, StyledChatContainerContentListScroll, StyledLoadMoreContainer, StyledWrapper, StyledWrapperListItem };
|
|
@@ -3,7 +3,7 @@ import 'core-js/modules/web.url.to-json.js';
|
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import { describe } from 'react-desc';
|
|
5
5
|
import { Grid } from '@elliemae/ds-grid';
|
|
6
|
-
import Communications from '@elliemae/ds-icons
|
|
6
|
+
import { Communications } from '@elliemae/ds-icons';
|
|
7
7
|
import { emptyStateProps, defaultProps } from './props.js';
|
|
8
8
|
import { MessageWrapper, ChatEmptyStateWrapper } from './styled.js';
|
|
9
9
|
import { useValidateProps } from './config/useValidateProps.js';
|
|
@@ -1,34 +1,43 @@
|
|
|
1
1
|
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
|
2
2
|
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
3
3
|
import 'core-js/modules/web.url.to-json.js';
|
|
4
|
-
import '
|
|
4
|
+
import 'core-js/modules/esnext.async-iterator.map.js';
|
|
5
|
+
import 'core-js/modules/esnext.iterator.map.js';
|
|
6
|
+
import 'core-js/modules/esnext.async-iterator.filter.js';
|
|
7
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
8
|
+
import 'core-js/modules/esnext.iterator.filter.js';
|
|
9
|
+
import 'core-js/modules/esnext.async-iterator.for-each.js';
|
|
10
|
+
import 'core-js/modules/esnext.iterator.for-each.js';
|
|
11
|
+
import React from 'react';
|
|
5
12
|
import { describe } from 'react-desc';
|
|
6
|
-
import MenuExpand from '@elliemae/ds-icons
|
|
7
|
-
import MenuCollapse from '@elliemae/ds-icons/MenuCollapse';
|
|
13
|
+
import { MenuCollapse, MenuExpand } from '@elliemae/ds-icons';
|
|
8
14
|
import { StyledSideBarContainer, StyledSideBarButtonsContainer } from './styled.js';
|
|
9
15
|
import { TileButton } from '../tile-button/TileButton.js';
|
|
10
16
|
import { SidebarButton } from '../sidebar-button/SidebarButton.js';
|
|
11
17
|
import { chatSidebarProps, defaultProps } from './props.js';
|
|
12
18
|
import { useValidateProps } from './config/useValidateProps.js';
|
|
13
|
-
import { jsx } from 'react/jsx-runtime';
|
|
19
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
14
20
|
|
|
15
21
|
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; }
|
|
16
22
|
|
|
17
23
|
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(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; }
|
|
18
24
|
|
|
19
|
-
const FooterChat =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
const FooterChat = _ref => {
|
|
26
|
+
let {
|
|
27
|
+
expanded,
|
|
28
|
+
onFooterClose,
|
|
29
|
+
onFooterExpand,
|
|
30
|
+
footerButtonExtraProps
|
|
31
|
+
} = _ref;
|
|
32
|
+
return /*#__PURE__*/_jsx(SidebarButton, {
|
|
33
|
+
dsId: "sidebar_footer",
|
|
34
|
+
label: null,
|
|
35
|
+
Icon: !expanded ? MenuCollapse : MenuExpand,
|
|
36
|
+
onClick: expanded ? onFooterClose : onFooterExpand,
|
|
37
|
+
"aria-pressed": expanded,
|
|
38
|
+
"aria-label": footerButtonExtraProps['aria-label']
|
|
39
|
+
});
|
|
40
|
+
};
|
|
32
41
|
|
|
33
42
|
const SideBarChat = props => {
|
|
34
43
|
useValidateProps(props, SideBarChatWithSchema.toJSON());
|
|
@@ -38,18 +47,38 @@ const SideBarChat = props => {
|
|
|
38
47
|
onFooterClose,
|
|
39
48
|
onFooterExpand,
|
|
40
49
|
selectedItem,
|
|
41
|
-
footerButtonExtraProps
|
|
50
|
+
footerButtonExtraProps,
|
|
51
|
+
tooltipPlacement,
|
|
52
|
+
enableTooltipWhenIsClosed,
|
|
53
|
+
actionRef
|
|
42
54
|
} = props;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
const {
|
|
56
|
+
current: listRef
|
|
57
|
+
} = React.useRef({});
|
|
58
|
+
const registerReference = React.useCallback(ref => {
|
|
59
|
+
if (ref) listRef[ref.dataset.key] = ref;
|
|
60
|
+
}, [listRef]);
|
|
61
|
+
React.useEffect(() => {
|
|
62
|
+
if (actionRef.current.listRef) {
|
|
63
|
+
actionRef.current.listRef = listRef;
|
|
64
|
+
}
|
|
65
|
+
}, [sidebarItems, expanded, actionRef, listRef]);
|
|
66
|
+
return /*#__PURE__*/jsxs(StyledSideBarContainer, {
|
|
67
|
+
rows: [1, 'auto'],
|
|
68
|
+
ref: listRef,
|
|
69
|
+
children: [/*#__PURE__*/_jsx(StyledSideBarButtonsContainer, {}, void 0, sidebarItems.map(p => /*#__PURE__*/jsx(TileButton, _objectSpread(_objectSpread({
|
|
70
|
+
innerRef: registerReference
|
|
71
|
+
}, p), {}, {
|
|
72
|
+
selected: selectedItem === p.dsId,
|
|
73
|
+
tooltipPlacement: tooltipPlacement,
|
|
74
|
+
disableTooltip: enableTooltipWhenIsClosed ? false : !expanded
|
|
75
|
+
}), p.dsId))), /*#__PURE__*/_jsx(FooterChat, {
|
|
76
|
+
expanded: expanded,
|
|
77
|
+
onFooterClose: onFooterClose,
|
|
78
|
+
onFooterExpand: onFooterExpand,
|
|
79
|
+
footerButtonExtraProps: footerButtonExtraProps
|
|
80
|
+
})]
|
|
81
|
+
});
|
|
53
82
|
};
|
|
54
83
|
|
|
55
84
|
SideBarChat.defaultProps = defaultProps;
|
|
@@ -11,17 +11,27 @@ const defaultProps = {
|
|
|
11
11
|
onHeaderClose: noop,
|
|
12
12
|
footerButtonExtraProps: {
|
|
13
13
|
'aria-label': 'expand or collapse button'
|
|
14
|
+
},
|
|
15
|
+
tooltipPlacement: 'right',
|
|
16
|
+
enableTooltipWhenIsClosed: false,
|
|
17
|
+
actionRef: {
|
|
18
|
+
current: {
|
|
19
|
+
listRef: []
|
|
20
|
+
}
|
|
14
21
|
}
|
|
15
22
|
};
|
|
16
23
|
const chatSidebarProps = {
|
|
17
24
|
sidebarItems: PropTypes.arrayOf(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),
|
|
18
25
|
expanded: PropTypes.bool.description('Whether to show the chat expanded or collapsed').defaultValue(defaultProps.expanded),
|
|
19
26
|
selectedItem: PropTypes.string.description('The id of the chat item you want to be opened').defaultValue(defaultProps.selectedItem),
|
|
27
|
+
tooltipPlacement: 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'"),
|
|
28
|
+
enableTooltipWhenIsClosed: PropTypes.bool.description('Enable tooltip when is closed').defaultValue(defaultProps.onFooterExpand),
|
|
20
29
|
onFooterExpand: PropTypes.func.description('The function to call when the chat is opened via the footer').defaultValue(defaultProps.onFooterExpand),
|
|
21
30
|
onFooterClose: PropTypes.func.description('The function to call when the chat is closed via the footer').defaultValue(defaultProps.onFooterClose),
|
|
22
31
|
onHeaderExpand: PropTypes.func.description('The function to call when the chat is opened via the header').defaultValue(defaultProps.onHeaderExpand),
|
|
23
32
|
onHeaderClose: PropTypes.func.description('The function to call when the chat is closed via the header').defaultValue(defaultProps.onHeaderClose),
|
|
24
|
-
footerButtonExtraProps: PropTypes.object.description('Expand/collapse footer button extra props').defaultValue(defaultProps.footerButtonExtraProps)
|
|
33
|
+
footerButtonExtraProps: PropTypes.object.description('Expand/collapse footer button extra props').defaultValue(defaultProps.footerButtonExtraProps),
|
|
34
|
+
actionRef: PropTypes.object.description("Action ref for sidebar\n {\n listRef: references to Tiles\n }\n ").defaultValue(defaultProps.actionRef)
|
|
25
35
|
};
|
|
26
36
|
|
|
27
37
|
export { chatSidebarProps, defaultProps };
|
|
@@ -4,9 +4,9 @@ import { MIN_WIDTH_SIDEBAR, BUTTON_SIDEBAR_HEIGHT } from '../../styled.js';
|
|
|
4
4
|
|
|
5
5
|
const StyledSideBarContainer = /*#__PURE__*/styled(Grid).withConfig({
|
|
6
6
|
componentId: "sc-16uijso-0"
|
|
7
|
-
})(["height:100%;width:", "px;background:", ";border-right:1px solid ", ";"], MIN_WIDTH_SIDEBAR, props => props.theme.colors.neutral['050'], props => props.theme.colors.neutral['100']);
|
|
7
|
+
})(["height:100%;width:", "px;background:", ";border-right:1px solid ", ";overflow:hidden;"], MIN_WIDTH_SIDEBAR, props => props.theme.colors.neutral['050'], props => props.theme.colors.neutral['100']);
|
|
8
8
|
const StyledSideBarButtonsContainer = /*#__PURE__*/styled(Grid).withConfig({
|
|
9
9
|
componentId: "sc-16uijso-1"
|
|
10
|
-
})(["overflow-y:auto;align-items:flex-start;justify-content:flex-start;grid-template-rows:repeat(auto-fill,", "px);"], BUTTON_SIDEBAR_HEIGHT);
|
|
10
|
+
})(["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;}"], BUTTON_SIDEBAR_HEIGHT);
|
|
11
11
|
|
|
12
12
|
export { StyledSideBarButtonsContainer, StyledSideBarContainer };
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
2
2
|
import 'react';
|
|
3
|
-
import Comments from '@elliemae/ds-icons
|
|
3
|
+
import { Comments } from '@elliemae/ds-icons';
|
|
4
4
|
import { StyledFloatingButton } from './styled.js';
|
|
5
5
|
import { defaultFloatingButton } from './props.js';
|
|
6
6
|
|
|
7
7
|
var _Comments;
|
|
8
|
-
const FloatingButton =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
8
|
+
const FloatingButton = _ref => {
|
|
9
|
+
let {
|
|
10
|
+
onClick
|
|
11
|
+
} = _ref;
|
|
12
|
+
return /*#__PURE__*/_jsx(StyledFloatingButton, {
|
|
13
|
+
"data-testid": "chat-floating-button",
|
|
14
|
+
onClick: onClick
|
|
15
|
+
}, void 0, _Comments || (_Comments = /*#__PURE__*/_jsx(Comments, {
|
|
16
|
+
size: "l"
|
|
17
|
+
})));
|
|
18
|
+
};
|
|
16
19
|
FloatingButton.defaultProps = defaultFloatingButton;
|
|
17
20
|
|
|
18
21
|
export { FloatingButton };
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import 'core-js/modules/esnext.async-iterator.filter.js';
|
|
2
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
3
|
+
import 'core-js/modules/esnext.iterator.filter.js';
|
|
4
|
+
import 'core-js/modules/esnext.async-iterator.for-each.js';
|
|
5
|
+
import 'core-js/modules/esnext.iterator.for-each.js';
|
|
1
6
|
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
|
2
7
|
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
3
8
|
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import propsTypes from 'prop-types';
|
|
2
2
|
import { PropTypes } from 'react-desc';
|
|
3
3
|
import { noop } from 'lodash';
|
|
4
|
-
import Comments from '@elliemae/ds-icons
|
|
4
|
+
import { Comments } from '@elliemae/ds-icons';
|
|
5
5
|
|
|
6
6
|
const defaultSidebarButton = {
|
|
7
7
|
Icon: Comments,
|
|
@@ -3,7 +3,7 @@ import { Grid } from '@elliemae/ds-grid';
|
|
|
3
3
|
|
|
4
4
|
const Wrapper = /*#__PURE__*/styled(Grid).withConfig({
|
|
5
5
|
componentId: "sc-80w41d-0"
|
|
6
|
-
})(["align-items:center;justify-content:center;
|
|
6
|
+
})(["align-items:center;justify-content:center;max-width:100%;padding:0 8px 8px;border:1px solid ", ";border-radius:10px;background-color:", ";box-shadow:none;"], props => props.theme.colors.neutral['100'], props => props.theme.colors.neutral['080']);
|
|
7
7
|
const Header = /*#__PURE__*/styled(Grid).withConfig({
|
|
8
8
|
componentId: "sc-80w41d-1"
|
|
9
9
|
})(["align-items:center;height:36px;"]);
|