@elliemae/ds-chat 2.0.0-next.8 → 2.0.0-rc.3

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 (88) hide show
  1. package/cjs/ChatDataTestids.js +27 -0
  2. package/cjs/parts/bubble/ChatBubble.js +9 -6
  3. package/cjs/parts/bubble/ChatBubbleArrow.js +64 -61
  4. package/cjs/parts/bubble/props.js +1 -1
  5. package/cjs/parts/bubble/styled.js +1 -1
  6. package/cjs/parts/chat-composer/ChatContainerComposer.js +14 -7
  7. package/cjs/parts/chat-composer/props.js +4 -0
  8. package/cjs/parts/chat-composer/styled.js +2 -2
  9. package/cjs/parts/chat-container/ChatContainer.js +53 -11
  10. package/cjs/parts/chat-container/props.js +7 -3
  11. package/cjs/parts/chat-container/styled.js +1 -1
  12. package/cjs/parts/chat-container-header/ChatContainerHeader.js +3 -3
  13. package/cjs/parts/chat-container-header/helpers.js +31 -0
  14. package/cjs/parts/chat-container-header/styled.js +6 -6
  15. package/cjs/parts/chat-container-messages-list/ChatContainerMessagesList.js +134 -29
  16. package/cjs/parts/chat-container-messages-list/props.js +4 -2
  17. package/cjs/parts/chat-container-messages-list/styled.js +2 -2
  18. package/cjs/parts/chat-empty-state/ChatEmptyState.js +2 -3
  19. package/cjs/parts/chat-sidebar/SideBarChat.js +57 -29
  20. package/cjs/parts/chat-sidebar/props.js +11 -1
  21. package/cjs/parts/chat-sidebar/styled.js +2 -2
  22. package/cjs/parts/floating-button/FloatingButton.js +18 -10
  23. package/cjs/parts/floating-button/props.js +6 -2
  24. package/cjs/parts/sidebar-button/SidebarButton.js +5 -0
  25. package/cjs/parts/sidebar-button/props.js +2 -3
  26. package/cjs/parts/system-message/style.js +1 -1
  27. package/cjs/parts/tile-button/TileButton.js +30 -27
  28. package/cjs/parts/tile-button/props.js +12 -8
  29. package/cjs/parts/tile-button/styled.js +6 -2
  30. package/esm/ChatDataTestids.js +23 -0
  31. package/esm/parts/bubble/ChatBubble.js +8 -5
  32. package/esm/parts/bubble/ChatBubbleArrow.js +64 -61
  33. package/esm/parts/bubble/props.js +1 -1
  34. package/esm/parts/bubble/styled.js +1 -1
  35. package/esm/parts/chat-composer/ChatContainerComposer.js +13 -5
  36. package/esm/parts/chat-composer/props.js +4 -0
  37. package/esm/parts/chat-container/ChatContainer.js +53 -11
  38. package/esm/parts/chat-container/props.js +7 -3
  39. package/esm/parts/chat-container/styled.js +1 -1
  40. package/esm/parts/chat-container-header/ChatContainerHeader.js +3 -2
  41. package/esm/parts/chat-container-header/helpers.js +23 -0
  42. package/esm/parts/chat-container-header/styled.js +6 -6
  43. package/esm/parts/chat-container-messages-list/ChatContainerMessagesList.js +134 -29
  44. package/esm/parts/chat-container-messages-list/props.js +4 -2
  45. package/esm/parts/chat-container-messages-list/styled.js +2 -2
  46. package/esm/parts/chat-empty-state/ChatEmptyState.js +1 -1
  47. package/esm/parts/chat-sidebar/SideBarChat.js +57 -28
  48. package/esm/parts/chat-sidebar/props.js +11 -1
  49. package/esm/parts/chat-sidebar/styled.js +2 -2
  50. package/esm/parts/floating-button/FloatingButton.js +18 -9
  51. package/esm/parts/floating-button/props.js +6 -2
  52. package/esm/parts/sidebar-button/SidebarButton.js +5 -0
  53. package/esm/parts/sidebar-button/props.js +1 -1
  54. package/esm/parts/system-message/style.js +1 -1
  55. package/esm/parts/tile-button/TileButton.js +31 -26
  56. package/esm/parts/tile-button/props.js +11 -3
  57. package/esm/parts/tile-button/styled.js +6 -3
  58. package/package.json +24 -6
  59. package/types/ChatDataTestids.d.ts +21 -0
  60. package/types/parts/bubble/styled.d.ts +3 -3
  61. package/types/parts/bubble/tests/ChatBubble.test.d.ts +1 -0
  62. package/types/parts/chat-card/styled.d.ts +1 -1
  63. package/types/parts/chat-composer/ChatContainerComposer.d.ts +2 -0
  64. package/types/parts/chat-composer/props.d.ts +10 -6
  65. package/types/parts/chat-composer/styled.d.ts +2 -2
  66. package/types/parts/chat-composer/tests/ChatContainerComposer.test.d.ts +1 -0
  67. package/types/parts/chat-container/ChatContainer.d.ts +1 -0
  68. package/types/parts/chat-container/props.d.ts +4 -0
  69. package/types/parts/chat-container/styled.d.ts +2 -2
  70. package/types/parts/chat-container/tests/ChatContainer.test.d.ts +1 -0
  71. package/types/parts/chat-container-header/helpers.d.ts +6 -0
  72. package/types/parts/chat-container-header/styled.d.ts +3 -3
  73. package/types/parts/chat-container-messages-list/props.d.ts +6 -0
  74. package/types/parts/chat-empty-state/styled.d.ts +1 -1
  75. package/types/parts/chat-sidebar/SideBarChat.d.ts +3 -0
  76. package/types/parts/chat-sidebar/props.d.ts +8 -1
  77. package/types/parts/chat-sidebar/styled.d.ts +2 -2
  78. package/types/parts/floating-button/FloatingButton.d.ts +3 -1
  79. package/types/parts/floating-button/props.d.ts +5 -0
  80. package/types/parts/floating-container/styled.d.ts +1 -2
  81. package/types/parts/grid-influencer/styled.d.ts +2 -2
  82. package/types/parts/message-delimiter/styled.d.ts +1 -1
  83. package/types/parts/sidebar-button/styled.d.ts +1 -1
  84. package/types/parts/system-message/style.d.ts +2 -2
  85. package/types/parts/tile-button/TileButton.d.ts +3 -0
  86. package/types/parts/tile-button/props.d.ts +6 -0
  87. package/types/parts/tile-button/styled.d.ts +5 -4
  88. package/types/tests/utils.d.ts +27 -0
@@ -6,24 +6,23 @@ var _jsx = require('@babel/runtime/helpers/jsx');
6
6
  require('core-js/modules/web.url.to-json.js');
7
7
  var React = require('react');
8
8
  var reactDesc = require('react-desc');
9
- var DSTooltip = require('@elliemae/ds-tooltip');
9
+ var dsTooltip = require('@elliemae/ds-tooltip');
10
10
  var dsGrid = require('@elliemae/ds-grid');
11
- var CloseXsmall = require('@elliemae/ds-icons/CloseXsmall');
11
+ var dsIcons = require('@elliemae/ds-icons');
12
12
  var styled = require('./styled.js');
13
13
  var props = require('./props.js');
14
14
  var useValidateProps = require('./config/useValidateProps.js');
15
+ var jsxRuntime = require('react/jsx-runtime');
15
16
 
16
17
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
17
18
 
18
19
  var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
19
20
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
20
- var DSTooltip__default = /*#__PURE__*/_interopDefaultLegacy(DSTooltip);
21
- var CloseXsmall__default = /*#__PURE__*/_interopDefaultLegacy(CloseXsmall);
22
21
 
23
22
  var _StyledWrapperLeftBor, _CloseXsmall;
24
23
 
25
24
  const TileButton = props => {
26
- var _Icon, _StyledStatusBadge, _StyledTileButtonLabe;
25
+ var _Icon, _StyledTileButtonLabe, _span;
27
26
 
28
27
  useValidateProps.useValidateProps(props, TileButtonWithSchema.toJSON());
29
28
  const {
@@ -42,7 +41,10 @@ const TileButton = props => {
42
41
  disabled,
43
42
  selected,
44
43
  isHeader,
45
- ariaLabel
44
+ ariaLabel,
45
+ tooltipPlacement,
46
+ disableTooltip,
47
+ innerRef
46
48
  } = props;
47
49
  const handleClick = React__default["default"].useCallback(() => {
48
50
  onClick(dsId, title);
@@ -58,17 +60,19 @@ const TileButton = props => {
58
60
  justifyContent: "center"
59
61
  }, void 0, _Icon || (_Icon = /*#__PURE__*/_jsx__default["default"](Icon, {
60
62
  size: "m"
61
- })), badge ? _StyledStatusBadge || (_StyledStatusBadge = /*#__PURE__*/_jsx__default["default"](styled.StyledStatusBadge, {
63
+ })), badge ? /*#__PURE__*/_jsx__default["default"](styled.StyledStatusBadge, {
62
64
  badgeColor: badgeColor,
63
- badgePosition: badgePosition
64
- })) : null)), !isHeader ? /*#__PURE__*/_jsx__default["default"](dsGrid.Grid, {
65
+ badgePosition: badgePosition,
66
+ "data-testid": "tile-badge-".concat(dsId)
67
+ }) : null)), !isHeader ? /*#__PURE__*/_jsx__default["default"](dsGrid.Grid, {
65
68
  width: "100%",
66
69
  justifyContent: "center"
67
70
  }, void 0, label ? _StyledTileButtonLabe || (_StyledTileButtonLabe = /*#__PURE__*/_jsx__default["default"](styled.StyledTileButtonLabel, {}, void 0, label)) : null) : null), [isHeader, Icon, badge, badgeColor, badgePosition, label]);
68
- return /*#__PURE__*/_jsx__default["default"](styled.StyledTileButton, {
71
+ const Btn = React__default["default"].useMemo(() => /*#__PURE__*/jsxRuntime.jsx(styled.StyledTileButton, {
69
72
  isHeader: isHeader,
70
73
  value: dsId,
71
74
  "data-testid": "tile-button-".concat(dsId),
75
+ "data-key": dsId,
72
76
  onClick: handleClick,
73
77
  onFocus: onFocus,
74
78
  onBlur: onBlur,
@@ -77,23 +81,22 @@ const TileButton = props => {
77
81
  badgeColor: badgeColor,
78
82
  badgePosition: badgePosition,
79
83
  "aria-pressed": selected,
80
- "aria-label": ariaLabel
81
- }, dsId, /*#__PURE__*/_jsx__default["default"](styled.StyledWrapper, {
82
- alignItems: "center",
83
- justifyContent: "center"
84
- }, void 0, title ? /*#__PURE__*/_jsx__default["default"](DSTooltip__default["default"], {
85
- containerProps: {
86
- id: "ds-chat-tile-tooltip-button-".concat(dsId),
87
- 'data-testid': "ds-chat-tile-tooltip-button-".concat(dsId)
88
- },
89
- interactionType: "hover",
90
- title: title,
91
- triggerComponent: /*#__PURE__*/_jsx__default["default"]("span", {}, void 0, MainContent),
92
- placement: "bottom"
93
- }) : MainContent, _StyledWrapperLeftBor || (_StyledWrapperLeftBor = /*#__PURE__*/_jsx__default["default"](styled.StyledWrapperLeftBorder, {})), showClose && !disabled ? /*#__PURE__*/_jsx__default["default"](styled.CloseButton, {
94
- onClick: onClose,
95
- value: dsId
96
- }, void 0, _CloseXsmall || (_CloseXsmall = /*#__PURE__*/_jsx__default["default"](CloseXsmall__default["default"], {}))) : null));
84
+ "aria-label": ariaLabel,
85
+ ref: innerRef,
86
+ children: /*#__PURE__*/_jsx__default["default"](styled.StyledWrapper, {
87
+ alignItems: "center",
88
+ justifyContent: "center"
89
+ }, void 0, _span || (_span = /*#__PURE__*/_jsx__default["default"]("span", {}, void 0, MainContent)), _StyledWrapperLeftBor || (_StyledWrapperLeftBor = /*#__PURE__*/_jsx__default["default"](styled.StyledWrapperLeftBorder, {})), showClose && !disabled ? /*#__PURE__*/_jsx__default["default"](styled.CloseButton, {
90
+ onClick: onClose,
91
+ value: dsId,
92
+ "data-testid": "tile-close-btn-".concat(dsId)
93
+ }, void 0, _CloseXsmall || (_CloseXsmall = /*#__PURE__*/_jsx__default["default"](dsIcons.CloseXsmall, {}))) : null)
94
+ }, dsId), [MainContent, ariaLabel, badgeColor, badgePosition, disabled, dsId, handleClick, isHeader, onBlur, onClose, onFocus, selected, showClose, innerRef]);
95
+ return title && !disableTooltip ? /*#__PURE__*/_jsx__default["default"](styled.StyledTooltipV3ButtonWrapper, {}, void 0, /*#__PURE__*/_jsx__default["default"](dsTooltip.DSTooltipV3, {
96
+ id: "ds-chat-tile-tooltip-button-".concat(dsId),
97
+ text: title,
98
+ startPlacementPreference: tooltipPlacement
99
+ }, void 0, Btn)) : Btn;
97
100
  };
98
101
 
99
102
  TileButton.defaultProps = props.defaultTileButton;
@@ -4,14 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var reactDesc = require('react-desc');
6
6
  var lodash = require('lodash');
7
- var Comments = require('@elliemae/ds-icons/Comments');
8
-
9
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
-
11
- var Comments__default = /*#__PURE__*/_interopDefaultLegacy(Comments);
7
+ var dsIcons = require('@elliemae/ds-icons');
12
8
 
13
9
  const defaultTileButton = {
14
- Icon: Comments__default["default"],
10
+ Icon: dsIcons.Comments,
15
11
  dsId: undefined,
16
12
  label: '',
17
13
  onClick: lodash.noop,
@@ -26,7 +22,10 @@ const defaultTileButton = {
26
22
  disabled: false,
27
23
  selected: false,
28
24
  isHeader: false,
29
- ariaLabel: 'Tile button'
25
+ ariaLabel: 'Tile button',
26
+ tooltipPlacement: 'right',
27
+ disableTooltip: false,
28
+ innerRef: lodash.noop
30
29
  };
31
30
  const propsTileButton = {
32
31
  Icon: reactDesc.PropTypes.func.description('Icon component').defaultValue(defaultTileButton.Icon),
@@ -44,7 +43,12 @@ const propsTileButton = {
44
43
  disabled: reactDesc.PropTypes.bool.description('It will disabled the button').defaultValue(defaultTileButton.disabled),
45
44
  selected: reactDesc.PropTypes.bool.description('Indicate that the button is selected').defaultValue(defaultTileButton.disabled),
46
45
  isHeader: reactDesc.PropTypes.bool.description("It won't render the label").defaultValue(defaultTileButton.disabled),
47
- ariaLabel: reactDesc.PropTypes.string.description('aria-label attribute').defaultValue(defaultTileButton.ariaLabel)
46
+ ariaLabel: reactDesc.PropTypes.string.description('aria-label attribute').defaultValue(defaultTileButton.ariaLabel),
47
+ 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'"),
48
+ disableTooltip: reactDesc.PropTypes.bool.description('Disable tooltip option').defaultValue(defaultTileButton.disableTooltip),
49
+ innerRef: reactDesc.PropTypes.oneOfType([reactDesc.PropTypes.func, reactDesc.PropTypes.shape({
50
+ current: reactDesc.PropTypes.any
51
+ })]).description('reference to the component')
48
52
  };
49
53
 
50
54
  exports.defaultTileButton = defaultTileButton;
@@ -54,8 +54,11 @@ const CloseButton = /*#__PURE__*/styled__default["default"].button.withConfig({
54
54
  componentId: "sc-1ebp1zs-5"
55
55
  })(["outline:none;background:none;height:9px;width:9px;position:absolute;top:1px;right:1px;overflow:hidden;padding:0;border:none;span{position:absolute;left:-3px;top:-4px;}&:focus,&:hover{svg{fill:", ";}&:after{display:block;content:'';position:absolute;top:0;left:0;width:100%;height:100%;border:solid 1px ", ";border-radius:2px;}}cursor:pointer;"], props => props.theme.colors.brand[600], props => props.theme.colors.brand[600]); // MAIN WRAPPER
56
56
 
57
- const StyledTileButton = /*#__PURE__*/styled__default["default"].button.withConfig({
57
+ const StyledTooltipV3ButtonWrapper = /*#__PURE__*/styled__default["default"].div.withConfig({
58
58
  componentId: "sc-1ebp1zs-6"
59
+ })(["height:", "px;width:", "px;"], BUTTON_SIDEBAR_HEIGHT, MIN_WIDTH_SIDEBAR);
60
+ const StyledTileButton = /*#__PURE__*/styled__default["default"].button.withConfig({
61
+ componentId: "sc-1ebp1zs-7"
59
62
  })(["outline:none;background:transparent;height:", "px;width:", "px;position:relative;padding:0;border:none;cursor:pointer;border-bottom:", ";&:focus,&:hover,&:active,&:disabled{background:", ";& ", "{border:2px solid ", ";margin-top:-2px;", ";}}&:focus,&:hover{& ", "{background:", ";}& ", "{color:", ";}& svg{fill:", ";}}&:active:not(:disabled){background:", ";& ", "{background:", ";}& ", "{color:", ";font-weight:600;}& svg{fill:", ";}& ", "{border:2px solid ", ";}}&:disabled{background:", ";", "{background:", ";}& ", "{background:", ";border:2px solid ", ";}", "{svg{fill:", ";}}", "{color:", ";}}", ""], BUTTON_SIDEBAR_HEIGHT, MIN_WIDTH_SIDEBAR, props => props.isHeader ? "1px solid ".concat(props.theme.colors.neutral['200']) : 'none', props => props.theme.colors.neutral['080'], StyledStatusBadge, props => props.theme.colors.neutral['080'], props => {
60
63
  switch (props.badgePosition) {
61
64
  case 'left':
@@ -75,7 +78,7 @@ const StyledTileButton = /*#__PURE__*/styled__default["default"].button.withConf
75
78
  return '';
76
79
  });
77
80
  const StyledWrapper = /*#__PURE__*/styled__default["default"](dsGrid.Grid).withConfig({
78
- componentId: "sc-1ebp1zs-7"
81
+ componentId: "sc-1ebp1zs-8"
79
82
  })(["height:100%;width:100%;position:relative;"]);
80
83
 
81
84
  exports.CloseButton = CloseButton;
@@ -83,6 +86,7 @@ exports.StyledStatusBadge = StyledStatusBadge;
83
86
  exports.StyledTileButton = StyledTileButton;
84
87
  exports.StyledTileButtonIcon = StyledTileButtonIcon;
85
88
  exports.StyledTileButtonLabel = StyledTileButtonLabel;
89
+ exports.StyledTooltipV3ButtonWrapper = StyledTooltipV3ButtonWrapper;
86
90
  exports.StyledWrapper = StyledWrapper;
87
91
  exports.StyledWrapperCentralContent = StyledWrapperCentralContent;
88
92
  exports.StyledWrapperLeftBorder = StyledWrapperLeftBorder;
@@ -0,0 +1,23 @@
1
+ const ChatDataTestIds = {
2
+ COMPOSER_TEXTAREA: 'chat-composer-textarea',
3
+ COMPOSER_SEND_BUTTON: 'chat-composer-send-button',
4
+ CARD_TITLE: 'chat-card-title',
5
+ CARD_WRAPPER: 'chat-card-wrapper',
6
+ CARD_TIME: 'chat-card-time',
7
+ CARD_RIGHT_ADDON: 'chat-right-addon',
8
+ CARD_CONTENT: 'chat-card-content',
9
+ LOADING_INDICATOR: 'ds-chat-loading-indicator',
10
+ HEADER_TITLE: 'chat-header-title',
11
+ HEADER_CHILDREN: 'chat-header-children',
12
+ THREAD_CONTAINER: 'chat-thread-container',
13
+ LOAD_MORE_BUTTON: 'ds-chat-load-more-btn',
14
+ FLOATING_BUTTON: 'chat-floating-button',
15
+ SYSTEM_MSG_TITLE: 'chat-system-message-title',
16
+ SYSTEM_MSG_BODY: 'chat-system-message-body',
17
+ SYSTEM_MSG_TIME: 'chat-system-message-time',
18
+ BUBBLE: 'ds-chat-bubble',
19
+ BUBBLE_TITLE: 'chat-bubble-title',
20
+ BUBBLE_BODY: 'chat-bubble-body'
21
+ };
22
+
23
+ export { ChatDataTestIds };
@@ -1,14 +1,16 @@
1
1
  import _jsx from '@babel/runtime/helpers/esm/jsx';
2
2
  import 'core-js/modules/web.url.to-json.js';
3
- import 'react';
3
+ import 'core-js/modules/esnext.async-iterator.map.js';
4
+ import 'core-js/modules/esnext.iterator.map.js';
5
+ import React from 'react';
4
6
  import { describe } from 'react-desc';
5
- import Warning from '@elliemae/ds-icons/WarningCircleFill';
7
+ import { WarningCircleFill } from '@elliemae/ds-icons';
6
8
  import { StyledWrapper, StyledColoredBubble, StyledTitleBubble, StyledTitleLeftBubble, StyledTitleRightBubble, StyleBodyWrapper, StyleErrorMessage, StyleHelpMessage } from './styled.js';
7
9
  import { propsBubbles } from './props.js';
8
10
  import { useValidateProps } from './config/useValidateProps.js';
9
11
  import { ChatBubbleArrow } from './ChatBubbleArrow.js';
10
12
 
11
- var _Warning;
13
+ var _br, _WarningCircleFill;
12
14
 
13
15
  const ChatBubble = props => {
14
16
  useValidateProps(props, ChatBubbleWithSchema.toJSON());
@@ -21,6 +23,7 @@ const ChatBubble = props => {
21
23
  errorMessage,
22
24
  helpMessage
23
25
  } = props;
26
+ const bodyParts = React.useMemo(() => typeof body === 'string' ? body.split('\n') : [body], [body]);
24
27
  return /*#__PURE__*/_jsx(StyledWrapper, {
25
28
  "data-testid": "ds-chat-bubble-".concat(dsId),
26
29
  type: type
@@ -40,14 +43,14 @@ const ChatBubble = props => {
40
43
  "data-testid": "chat-bubble-time-".concat(dsId)
41
44
  }, void 0, time)), /*#__PURE__*/_jsx(StyleBodyWrapper, {
42
45
  "data-testid": "chat-bubble-body-".concat(dsId)
43
- }, void 0, body), /*#__PURE__*/_jsx(ChatBubbleArrow, {
46
+ }, void 0, bodyParts.map((item, index) => /*#__PURE__*/_jsx(React.Fragment, {}, "".concat(item, "-").concat(index), item, index < bodyParts.length - 1 ? _br || (_br = /*#__PURE__*/_jsx("br", {})) : null))), /*#__PURE__*/_jsx(ChatBubbleArrow, {
44
47
  type: type
45
48
  })), errorMessage ? /*#__PURE__*/_jsx(StyleErrorMessage, {
46
49
  "data-testid": "chat-bubble-error-message-".concat(dsId),
47
50
  p: "xxs",
48
51
  gutter: "xxs",
49
52
  cols: [1, 'auto']
50
- }, void 0, /*#__PURE__*/_jsx("span", {}, void 0, errorMessage), _Warning || (_Warning = /*#__PURE__*/_jsx(Warning, {}))) : null, helpMessage ? /*#__PURE__*/_jsx(StyleHelpMessage, {
53
+ }, void 0, /*#__PURE__*/_jsx("span", {}, void 0, errorMessage), _WarningCircleFill || (_WarningCircleFill = /*#__PURE__*/_jsx(WarningCircleFill, {}))) : null, helpMessage ? /*#__PURE__*/_jsx(StyleHelpMessage, {
51
54
  "data-testid": "chat-bubble-help-message-".concat(dsId),
52
55
  p: "xxs",
53
56
  gutter: "xxs",
@@ -4,66 +4,69 @@ import { StyledBubbleArrow } from './styled.js';
4
4
  import { BUBBLE_TYPES } from './props.js';
5
5
 
6
6
  var _svg, _svg2;
7
- const ChatBubbleArrow = ({
8
- type
9
- }) => /*#__PURE__*/_jsx(StyledBubbleArrow, {}, void 0, type === BUBBLE_TYPES.RECIPIENT ? _svg || (_svg = /*#__PURE__*/_jsx("svg", {
10
- width: "15px",
11
- height: "14px",
12
- viewBox: "0 0 15 14"
13
- }, void 0, /*#__PURE__*/_jsx("defs", {}, void 0, /*#__PURE__*/_jsx("path", {
14
- d: "M12,8.5 C12,7.9373169 11.6782751,7.4856453 11.2282104,7.196228 C11.2286673,7.1967363 3,2 3,2 L3,10 L10.5627441,10 L10.5658569,9.9933472 C11.3630371,9.9580688 12,9.3058472 12,8.5 Z",
15
- id: "path-1"
16
- }), /*#__PURE__*/_jsx("filter", {
17
- x: "-55.6%",
18
- y: "-50.0%",
19
- width: "211.1%",
20
- height: "225.0%",
21
- filterUnits: "objectBoundingBox",
22
- id: "filter-2"
23
- }, void 0, /*#__PURE__*/_jsx("feOffset", {
24
- dx: "2.3",
25
- dy: "1.2",
26
- in: "SourceAlpha",
27
- result: "shadowOffsetOuter1"
28
- }), /*#__PURE__*/_jsx("feGaussianBlur", {
29
- stdDeviation: "1.5",
30
- in: "shadowOffsetOuter1",
31
- result: "shadowBlurOuter1"
32
- }), /*#__PURE__*/_jsx("feColorMatrix", {
33
- values: "0 0 0 0 0.207843137 0 0 0 0 0.235294118 0 0 0 0 0.274509804 0 0 0 0.8 0",
34
- type: "matrix",
35
- in: "shadowBlurOuter1"
36
- }))), /*#__PURE__*/_jsx("g", {
37
- id: "[DSK]-Visual-Design",
38
- stroke: "none",
39
- strokeWidth: "1",
40
- fill: "none",
41
- fillRule: "evenodd"
42
- }, void 0, /*#__PURE__*/_jsx("g", {
43
- id: "Path-Copy",
44
- transform: "translate(7.500000, 6.000000) scale(-1, 1) translate(-7.500000, -6.000000) "
45
- }, void 0, /*#__PURE__*/_jsx("use", {
46
- fill: "black",
47
- fillOpacity: "1",
48
- filter: "url(#filter-2)",
49
- xlinkHref: "#path-1"
50
- }), /*#__PURE__*/_jsx("use", {
51
- fill: "#FFFFFF",
52
- fillRule: "evenodd",
53
- xlinkHref: "#path-1"
54
- }))))) : _svg2 || (_svg2 = /*#__PURE__*/_jsx("svg", {
55
- width: "9px",
56
- height: "8px",
57
- viewBox: "0 0 9 8"
58
- }, void 0, /*#__PURE__*/_jsx("g", {
59
- stroke: "none",
60
- strokeWidth: "1",
61
- fill: "none",
62
- fillRule: "evenodd"
63
- }, void 0, /*#__PURE__*/_jsx("path", {
64
- d: "M9,6.5 C9,5.9373169 8.6782751,5.4856453 8.2282104,5.196228 C8.2286673,5.1967363 0,0 0,0 L0,8 L7.5627441,8 L7.5658569,7.9933472 C8.3630371,7.9580688 9,7.3058472 9,6.5 Z",
65
- id: "Path",
66
- fill: "#1E79C2"
67
- })))));
7
+ const ChatBubbleArrow = _ref => {
8
+ let {
9
+ type
10
+ } = _ref;
11
+ return /*#__PURE__*/_jsx(StyledBubbleArrow, {}, void 0, type === BUBBLE_TYPES.RECIPIENT ? _svg || (_svg = /*#__PURE__*/_jsx("svg", {
12
+ width: "15px",
13
+ height: "14px",
14
+ viewBox: "0 0 15 14"
15
+ }, void 0, /*#__PURE__*/_jsx("defs", {}, void 0, /*#__PURE__*/_jsx("path", {
16
+ d: "M12,8.5 C12,7.9373169 11.6782751,7.4856453 11.2282104,7.196228 C11.2286673,7.1967363 3,2 3,2 L3,10 L10.5627441,10 L10.5658569,9.9933472 C11.3630371,9.9580688 12,9.3058472 12,8.5 Z",
17
+ id: "path-1"
18
+ }), /*#__PURE__*/_jsx("filter", {
19
+ x: "-55.6%",
20
+ y: "-50.0%",
21
+ width: "211.1%",
22
+ height: "225.0%",
23
+ filterUnits: "objectBoundingBox",
24
+ id: "filter-2"
25
+ }, void 0, /*#__PURE__*/_jsx("feOffset", {
26
+ dx: "2.3",
27
+ dy: "1.2",
28
+ in: "SourceAlpha",
29
+ result: "shadowOffsetOuter1"
30
+ }), /*#__PURE__*/_jsx("feGaussianBlur", {
31
+ stdDeviation: "1.5",
32
+ in: "shadowOffsetOuter1",
33
+ result: "shadowBlurOuter1"
34
+ }), /*#__PURE__*/_jsx("feColorMatrix", {
35
+ values: "0 0 0 0 0.207843137 0 0 0 0 0.235294118 0 0 0 0 0.274509804 0 0 0 0.8 0",
36
+ type: "matrix",
37
+ in: "shadowBlurOuter1"
38
+ }))), /*#__PURE__*/_jsx("g", {
39
+ id: "[DSK]-Visual-Design",
40
+ stroke: "none",
41
+ strokeWidth: "1",
42
+ fill: "none",
43
+ fillRule: "evenodd"
44
+ }, void 0, /*#__PURE__*/_jsx("g", {
45
+ id: "Path-Copy",
46
+ transform: "translate(7.500000, 6.000000) scale(-1, 1) translate(-7.500000, -6.000000) "
47
+ }, void 0, /*#__PURE__*/_jsx("use", {
48
+ fill: "black",
49
+ fillOpacity: "1",
50
+ filter: "url(#filter-2)",
51
+ xlinkHref: "#path-1"
52
+ }), /*#__PURE__*/_jsx("use", {
53
+ fill: "#FFFFFF",
54
+ fillRule: "evenodd",
55
+ xlinkHref: "#path-1"
56
+ }))))) : _svg2 || (_svg2 = /*#__PURE__*/_jsx("svg", {
57
+ width: "9px",
58
+ height: "8px",
59
+ viewBox: "0 0 9 8"
60
+ }, void 0, /*#__PURE__*/_jsx("g", {
61
+ stroke: "none",
62
+ strokeWidth: "1",
63
+ fill: "none",
64
+ fillRule: "evenodd"
65
+ }, void 0, /*#__PURE__*/_jsx("path", {
66
+ d: "M9,6.5 C9,5.9373169 8.6782751,5.4856453 8.2282104,5.196228 C8.2286673,5.1967363 0,0 0,0 L0,8 L7.5627441,8 L7.5658569,7.9933472 C8.3630371,7.9580688 9,7.3058472 9,6.5 Z",
67
+ id: "Path",
68
+ fill: "#1E79C2"
69
+ })))));
70
+ };
68
71
 
69
72
  export { ChatBubbleArrow };
@@ -28,7 +28,7 @@ const propsBubbles = {
28
28
  type: PropTypes.oneOf([BUBBLE_TYPES.RECIPIENT, BUBBLE_TYPES.SENDER]).isRequired.description('Define bubble type ').defaultValue(defaultBubbleProps.type),
29
29
  title: PropTypes.string.isRequired.description('Title of the bubble').defaultValue(defaultBubbleProps.title),
30
30
  time: PropTypes.string.isRequired.description('Time of the bubble').defaultValue(defaultBubbleProps.title),
31
- body: PropTypes.oneOf(['string', 'element']).isRequired.description('Bubble content').defaultValue(defaultBubbleProps.body),
31
+ body: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired.description('Bubble content').defaultValue(defaultBubbleProps.body),
32
32
  onClick: PropTypes.string.description('Callback when the bubble is tapped').defaultValue(defaultBubbleProps.onClick),
33
33
  errorMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).description('Error message to display at bottom of the bubble').defaultValue(defaultBubbleProps.onClick),
34
34
  helpMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).description('Help message to display at bottom of the bubble').defaultValue(defaultBubbleProps.onClick)
@@ -22,7 +22,7 @@ const StyleBodyWrapper = /*#__PURE__*/styled.div.withConfig({
22
22
  })(["font-size:13px;font-weight:400;line-height:15px;min-height:18px;padding:0px 10px 8px 10px;"]);
23
23
  const StyleErrorMessage = /*#__PURE__*/styled.div.withConfig({
24
24
  componentId: "sc-fe8e9o-5"
25
- })(["font-size:12px;font-weight:400;padding-top:", ";padding-bottom:", ";color:", ";align-items:flex-end;justify-content:center;text-align:right;line-height:15px;svg{fill:", ";}a{font-size:12px;color:", ";}.em-ds-icon{margin-left:8px;}"], props => props.theme.space.xxxs, props => props.theme.space.xxxs, props => props.theme.colors.danger[900], props => props.theme.colors.danger[900], props => props.theme.colors.danger[900]);
25
+ })(["font-size:12px;font-weight:400;padding-top:", ";color:", ";align-items:flex-end;justify-content:center;text-align:right;line-height:15px;svg{fill:", ";}a{font-size:12px;color:", ";}.em-ds-icon{margin-left:8px;}"], props => props.theme.space.xxxs, props => props.theme.colors.danger[900], props => props.theme.colors.danger[900], props => props.theme.colors.danger[900]);
26
26
  const StyleHelpMessage = /*#__PURE__*/styled(StyleErrorMessage).withConfig({
27
27
  componentId: "sc-fe8e9o-6"
28
28
  })(["font-size:12px;line-height:15px;color:", ";svg{fill:", ";}a{font-size:12px;color:", ";}"], props => props.theme.colors.neutral[500], props => props.theme.colors.danger[500], props => props.theme.colors.danger[500]); // bubble sender/ recipient
@@ -2,10 +2,15 @@ import _jsx from '@babel/runtime/helpers/esm/jsx';
2
2
  import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
3
3
  import 'core-js/modules/web.url.to-json.js';
4
4
  import 'core-js/modules/web.dom-collections.iterator.js';
5
+ import 'core-js/modules/esnext.async-iterator.filter.js';
6
+ import 'core-js/modules/esnext.iterator.constructor.js';
7
+ import 'core-js/modules/esnext.iterator.filter.js';
8
+ import 'core-js/modules/esnext.async-iterator.for-each.js';
9
+ import 'core-js/modules/esnext.iterator.for-each.js';
5
10
  import React from 'react';
6
11
  import { Grid } from '@elliemae/ds-grid';
7
12
  import { describe } from 'react-desc';
8
- import PaperAirplane from '@elliemae/ds-icons/PaperAirplane';
13
+ import { PaperAirplane } from '@elliemae/ds-icons';
9
14
  import { StyledChatContainerContentComposer, StyledComposerInput, StyledComposerButton, StyledCounterArea, StyledCounterErrorA11y } from './styled.js';
10
15
  import { useValidateProps } from './config/useValidateProps.js';
11
16
  import { composerProps, defaultComposerPros } from './props.js';
@@ -28,9 +33,11 @@ const ChatComposer = props => {
28
33
  onSend,
29
34
  onFocus,
30
35
  onBlur,
36
+ onKeyDown,
31
37
  maxHeight = 300,
32
38
  placeholder,
33
39
  inputMaxLength,
40
+ maxLengthMessage,
34
41
  buttonDisabled,
35
42
  dataTestid,
36
43
  actionRef
@@ -48,7 +55,7 @@ const ChatComposer = props => {
48
55
  onResize(newHeight);
49
56
  setHeight(newHeight);
50
57
  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);
51
- }, [inputValue, internalMaxHeight]);
58
+ }, [inputValue, internalMaxHeight, onResize]);
52
59
  React.useEffect(() => {
53
60
  if (actionRef && actionRef.current) {
54
61
  actionRef.current.focusToComposer = () => {
@@ -59,7 +66,7 @@ const ChatComposer = props => {
59
66
  inputSend.current.focus();
60
67
  };
61
68
  }
62
- }, [actionRef.current]);
69
+ }, [actionRef]);
63
70
  const handleChange = React.useCallback(e => {
64
71
  onChange(e.target.value);
65
72
  }, [onChange]);
@@ -85,6 +92,7 @@ const ChatComposer = props => {
85
92
  value: inputValue,
86
93
  onFocus: onFocus,
87
94
  onBlur: onBlur,
95
+ onKeyDown: onKeyDown,
88
96
  placeholder: placeholder,
89
97
  "aria-label": "Message to send",
90
98
  "data-testid": "chat-composer-textarea"
@@ -128,8 +136,8 @@ const ChatComposer = props => {
128
136
  }, void 0, inputMaxLength && hasError ? /*#__PURE__*/jsxs(Fragment, {
129
137
  children: [/*#__PURE__*/_jsx(StyledCounterErrorA11y, {
130
138
  role: "alert"
131
- }, void 0, "You have exceeded the character limit by ", inputLength - inputMaxLength), "Please limit to less than ", inputMaxLength, " characters.", ' ']
132
- }) : '', inputMaxLength ? "".concat(inputLength, " / ").concat(inputMaxLength) : ''), _Grid || (_Grid = /*#__PURE__*/_jsx(Grid, {}))));
139
+ }, void 0, maxLengthMessage || "You have exceeded the character limit by ".concat(inputLength - inputMaxLength)), maxLengthMessage || "Please limit to less than ".concat(inputMaxLength, " characters. ")]
140
+ }) : '', inputMaxLength ? " ".concat(inputLength, " / ").concat(inputMaxLength) : ''), _Grid || (_Grid = /*#__PURE__*/_jsx(Grid, {}))));
133
141
  };
134
142
 
135
143
  ChatComposer.defaultProps = defaultComposerPros;
@@ -9,8 +9,10 @@ const defaultComposerPros = {
9
9
  onSend: noop,
10
10
  onFocus: noop,
11
11
  onBlur: noop,
12
+ onKeyDown: noop,
12
13
  maxHeight: 0,
13
14
  inputMaxLength: undefined,
15
+ maxLengthMessage: undefined,
14
16
  buttonDisabled: false,
15
17
  dataTestid: 'ds-chat-composer',
16
18
  actionRef: noop
@@ -18,11 +20,13 @@ const defaultComposerPros = {
18
20
  const composerProps = {
19
21
  placeholder: PropTypes.string.description('Input Placeholder').defaultValue(defaultComposerPros.placeholder),
20
22
  inputValue: PropTypes.string.description('Input value').defaultValue(defaultComposerPros.inputValue),
23
+ maxLengthMessage: PropTypes.string.description('Max length message').defaultValue(defaultComposerPros.maxLengthMessage),
21
24
  onChange: PropTypes.func.description('Called when the user types').defaultValue(defaultComposerPros.onChange),
22
25
  onResize: PropTypes.func.description('Called the input changes his height').defaultValue(defaultComposerPros.onResize),
23
26
  onSend: PropTypes.func.description('Called when the click send').defaultValue(defaultComposerPros.onSend),
24
27
  onFocus: PropTypes.func.description('Input focus').defaultValue(defaultComposerPros.onFocus),
25
28
  onBlur: PropTypes.func.description('Input blur').defaultValue(defaultComposerPros.onBlur),
29
+ onKeyDown: PropTypes.func.description('Input on key down').defaultValue(defaultComposerPros.onKeyDown),
26
30
  maxHeight: PropTypes.number.description('Max height of the composer. Use 0 for no limit').defaultValue(defaultComposerPros.onBlur),
27
31
  inputMaxLength: PropTypes.number.description('Max length of the composer. `undefined` for no limit').defaultValue(defaultComposerPros.inputMaxLength),
28
32
  buttonDisabled: PropTypes.bool.description('Control the disabled for the send button').defaultValue(defaultComposerPros.buttonDisabled),
@@ -1,9 +1,14 @@
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 _jsx from '@babel/runtime/helpers/esm/jsx';
2
7
  import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
3
8
  import React from 'react';
4
9
  import { noop } from 'lodash';
5
10
  import { describe } from 'react-desc';
6
- import DSIndeterminateProgressIndicator from '@elliemae/ds-basic/IndeterminateProgressIndicator';
11
+ import DSIndeterminateProgressIndicator from '@elliemae/ds-indeterminate-progress-indicator';
7
12
  import DSBanner, { BANNER_TYPES } from '@elliemae/ds-banner';
8
13
  import { ChatComposer } from '../chat-composer/ChatContainerComposer.js';
9
14
  import { ChatContainerMessagesList } from '../chat-container-messages-list/ChatContainerMessagesList.js';
@@ -30,15 +35,21 @@ const ChatContainer = props => {
30
35
  messagesListProps,
31
36
  composerProps,
32
37
  composerProps: {
33
- onResize: onComposerResize
38
+ onResize: onComposerResize,
39
+ onKeyDown: onComposerKeyDown
34
40
  },
35
41
  actionRef,
36
42
  autoScroll,
37
43
  device,
38
44
  isLoading,
39
45
  hasMoreItems,
40
- getMoreMessages
46
+ getMoreMessages,
47
+ ariaLabel
41
48
  } = props;
49
+ const bannerRef = React.useRef({
50
+ focusOnWrapper: noop,
51
+ focusOnLink: noop
52
+ });
42
53
  const containerRef = React.useRef();
43
54
  const listRef = React.useRef({
44
55
  scrollToIndex: noop
@@ -53,14 +64,38 @@ const ChatContainer = props => {
53
64
  }
54
65
  }, [onComposerResize, messagesListProps.messages, autoScroll]);
55
66
  const Container = device === 'desktop' ? StyledChatContainerContent : MobileStyledChatContainerContent;
67
+ const handleTabs = React.useCallback(e => {
68
+ if (onComposerKeyDown) onComposerKeyDown(e);else {
69
+ const ref = actionRef || listRef;
70
+
71
+ if (e.shiftKey && e.key === 'Tab') {
72
+ e.preventDefault();
73
+
74
+ if (['top', 'bottom'].includes(bannerPosition)) {
75
+ bannerRef.current.focusOnWrapper();
76
+ } else {
77
+ const last = ref.current.getMessagesInView().pop();
78
+ ref.current.focusToIndexWithoutScroll(last);
79
+ }
80
+ }
81
+ }
82
+ }, [actionRef, onComposerKeyDown, bannerPosition]); // Map actions
83
+
84
+ React.useEffect(() => {
85
+ if (actionRef && actionRef.current) {
86
+ actionRef.current.focusOnBanner = bannerRef.current.focusOnWrapper;
87
+ actionRef.current.focusOnBannerLink = bannerRef.current.focusOnLink;
88
+ }
89
+ }, [actionRef]);
56
90
  return /*#__PURE__*/jsxs(Container, {
57
91
  rows: ['minmax(0, 1fr)', 'auto'],
58
92
  ref: containerRef,
59
93
  role: "region",
60
- "aria-label": "chat window",
94
+ "aria-label": ariaLabel,
61
95
  children: [/*#__PURE__*/_jsx("div", {
62
96
  style: {
63
- position: 'relative'
97
+ position: 'relative',
98
+ overflow: 'hidden'
64
99
  }
65
100
  }, void 0, /*#__PURE__*/jsx(ChatContainerMessagesList, _objectSpread(_objectSpread({}, messagesListProps), {}, {
66
101
  actionRef: actionRef || listRef,
@@ -68,13 +103,17 @@ const ChatContainer = props => {
68
103
  hasMoreItems: hasMoreItems,
69
104
  getMoreMessages: getMoreMessages,
70
105
  sendingMessages: sendingMessages,
71
- sendingText: sendingText
106
+ sendingText: sendingText,
107
+ bannerPosition: bannerPosition,
108
+ bannerRef: bannerRef
72
109
  })), ['top', 'bottom'].includes(isLoading) ? /*#__PURE__*/_jsx(StyledIndicatorContainer, {
73
- isLoading: isLoading
110
+ isLoading: isLoading,
111
+ "data-testid": "ds-chat-loading-indicator"
74
112
  }, void 0, _DSIndeterminateProgr || (_DSIndeterminateProgr = /*#__PURE__*/_jsx(DSIndeterminateProgressIndicator, {
75
113
  processing: true,
76
114
  title: "Loading"
77
- }))) : null, ['top', 'bottom'].includes(bannerPosition) ? /*#__PURE__*/_jsx(StyledIndicatorContainer, {
115
+ }))) : null, /*#__PURE__*/_jsx(StyledIndicatorContainer, {
116
+ linear: true,
78
117
  isLoading: bannerPosition
79
118
  }, void 0, /*#__PURE__*/_jsx(DSBanner, {
80
119
  showCloseButton: true,
@@ -88,15 +127,18 @@ const ChatContainer = props => {
88
127
  },
89
128
  onClose: bannerProps.onClose,
90
129
  isOpen: true,
91
- type: BANNER_TYPES.INFO
92
- })) : null, sendingMessages && sendingMessages.length > 0 ? _StyledIndicatorConta || (_StyledIndicatorConta = /*#__PURE__*/_jsx(StyledIndicatorContainer, {
130
+ type: bannerProps.type || BANNER_TYPES.INFO,
131
+ actionRef: bannerRef
132
+ })), sendingMessages && sendingMessages.length > 0 ? _StyledIndicatorConta || (_StyledIndicatorConta = /*#__PURE__*/_jsx(StyledIndicatorContainer, {
93
133
  isLoading: "bottom",
94
- linear: true
134
+ linear: true,
135
+ "data-testid": "ds-chat-loading-indicator"
95
136
  }, void 0, /*#__PURE__*/_jsx(DSIndeterminateProgressIndicator, {
96
137
  processing: true,
97
138
  title: "Loading",
98
139
  lineOnly: true
99
140
  }))) : null), /*#__PURE__*/jsx(ChatComposer, _objectSpread(_objectSpread({}, composerProps), {}, {
141
+ onKeyDown: handleTabs,
100
142
  onResize: onResize,
101
143
  maxHeight: (((_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.clientHeight) || 0) / 2,
102
144
  actionRef: actionRef || listRef