@vendorflow/components 2.0.40 → 2.0.44

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.
@@ -77,27 +77,45 @@ var DefaultLoader = (0, react_2.forwardRef)(function (_a, ref) {
77
77
  (0, react_1.jsx)(material_1.CircularProgress, { size: "1.5rem", disableShrink: true })));
78
78
  });
79
79
  function useInfiniteScroll(_a) {
80
- var _b, _c;
80
+ var _b, _c, _d, _e;
81
81
  var scrollParent = _a.scrollParent, scrollBody = _a.scrollBody, isLoading = _a.isLoading, isFetching = _a.isFetching, isReverse = _a.isReverse, hasNextPage = _a.hasNextPage, fetchNextPage = _a.fetchNextPage;
82
82
  var prevPosition = (0, react_2.useRef)();
83
83
  var observer = (0, react_2.useRef)();
84
- var _d = __read((0, react_2.useState)(false), 2), isScrollInit = _d[0], setScrollInit = _d[1];
84
+ var _f = __read((0, react_2.useState)(false), 2), isScrollInit = _f[0], setScrollInit = _f[1];
85
+ var _g = __read((0, react_2.useState)(false), 2), isScrollLoad = _g[0], setScrollLoad = _g[1];
85
86
  var hasScrollbar = (0, react_2.useMemo)(function () {
86
87
  if (scrollParent.current && scrollBody.current) {
87
88
  return scrollBody.current.clientHeight > scrollParent.current.clientHeight;
88
89
  }
89
90
  return false;
90
91
  }, [(_b = scrollParent.current) === null || _b === void 0 ? void 0 : _b.clientHeight, (_c = scrollBody.current) === null || _c === void 0 ? void 0 : _c.clientHeight]);
92
+ // Ensures that when the chat initializes, it will scroll to the bottom
91
93
  (0, react_2.useEffect)(function () {
92
- var _a, _b;
93
94
  if (!isLoading && hasScrollbar) {
94
- console.log('scrolling to start!');
95
- console.log('scroll parent height: ', (_a = scrollParent.current) === null || _a === void 0 ? void 0 : _a.clientHeight);
96
- console.log('scroll body height: ', (_b = scrollBody.current) === null || _b === void 0 ? void 0 : _b.clientHeight);
97
95
  prevPosition.current = null;
96
+ setScrollLoad(false);
98
97
  scrollToStart();
99
98
  }
100
99
  }, [isLoading, hasScrollbar]);
100
+ // If a fetch happens that was not started by a scroll action (aka fetchNextPage),
101
+ // then this will track the prevPosition
102
+ (0, react_2.useEffect)(function () {
103
+ if (!isScrollLoad && scrollBody.current && isFetching) {
104
+ prevPosition.current = scrollBody.current.clientHeight;
105
+ }
106
+ }, [isFetching, isScrollLoad, (_d = scrollBody.current) === null || _d === void 0 ? void 0 : _d.clientHeight]);
107
+ // This will potentially scroll the page to the start when the page loads new data that did not
108
+ // originate from a fetchNextPage action
109
+ (0, react_2.useEffect)(function () {
110
+ if (!isScrollLoad &&
111
+ isReverse &&
112
+ scrollBody.current &&
113
+ prevPosition.current != null &&
114
+ scrollBody.current.clientHeight - prevPosition.current <= 200) {
115
+ prevPosition.current = null;
116
+ scrollToStart();
117
+ }
118
+ }, [isScrollLoad, (_e = scrollBody.current) === null || _e === void 0 ? void 0 : _e.clientHeight]);
101
119
  function scrollToStart() {
102
120
  var _a;
103
121
  var scrollHeight = (scrollBody.current || { scrollHeight: 0 }).scrollHeight;
@@ -118,24 +136,24 @@ function useInfiniteScroll(_a) {
118
136
  if (scrollBody.current && isReverse && isScrollInit) {
119
137
  // save the last element, so that we can scroll to it after the new data loads in
120
138
  prevPosition.current = scrollBody.current.clientHeight;
121
- console.log('saving prev position: ', prevPosition.current);
122
139
  }
123
140
  // load the next page
124
141
  fetchNextPage();
142
+ setScrollLoad(true);
125
143
  }
126
144
  }, {
127
145
  root: (scrollParent === null || scrollParent === void 0 ? void 0 : scrollParent.current) || null,
128
146
  threshold: 1.0,
129
147
  });
130
148
  if (node) {
131
- if (isReverse && scrollParent.current && prevPosition.current != null) {
132
- console.log('scrolling to prev position: ', prevPosition.current);
149
+ if (isReverse && scrollParent.current && prevPosition.current != null && isScrollLoad) {
133
150
  // If we had a prev position, then we want to scroll to it
134
151
  scrollParent.current.scrollTo(0, scrollBody.current.clientHeight - prevPosition.current);
135
152
  prevPosition.current = null;
153
+ setScrollLoad(false);
136
154
  }
137
155
  observer.current.observe(node);
138
156
  }
139
- }, [isLoading, isFetching, isReverse, hasNextPage, fetchNextPage, scrollParent, scrollBody, isScrollInit]);
157
+ }, [isLoading, isFetching, isReverse, hasNextPage, fetchNextPage, scrollParent, scrollBody, isScrollInit, isScrollLoad]);
140
158
  }
141
159
  var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
@@ -10,5 +10,4 @@ export { default as InputCheckboxGroup } from './material-ui/InputCheckboxGroup'
10
10
  export { default as InputRadioGroup } from './material-ui/InputRadioGroup';
11
11
  export { default as InputSearchDropdown } from './material-ui/InputSearchDropdown';
12
12
  export { default as InputTime } from './material-ui/InputTime';
13
- export { default as InfiniteScroll } from './InfiniteScroll';
14
13
  export { default as Modal } from './material-ui/Modal';
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Modal = exports.InfiniteScroll = exports.InputTime = exports.InputSearchDropdown = exports.InputRadioGroup = exports.InputCheckboxGroup = exports.InputGroup = exports.InputDateTime = exports.InputDate = exports.DataTable = exports.ColorPicker = exports.ChatInterface = exports.ButtonMenu = exports.Button = void 0;
6
+ exports.Modal = exports.InputTime = exports.InputSearchDropdown = exports.InputRadioGroup = exports.InputCheckboxGroup = exports.InputGroup = exports.InputDateTime = exports.InputDate = exports.DataTable = exports.ColorPicker = exports.ChatInterface = exports.ButtonMenu = exports.Button = void 0;
7
7
  var Button_1 = require("./material-ui/Button");
8
8
  Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return __importDefault(Button_1).default; } });
9
9
  var ButtonMenu_1 = require("./material-ui/ButtonMenu");
@@ -28,7 +28,5 @@ var InputSearchDropdown_1 = require("./material-ui/InputSearchDropdown");
28
28
  Object.defineProperty(exports, "InputSearchDropdown", { enumerable: true, get: function () { return __importDefault(InputSearchDropdown_1).default; } });
29
29
  var InputTime_1 = require("./material-ui/InputTime");
30
30
  Object.defineProperty(exports, "InputTime", { enumerable: true, get: function () { return __importDefault(InputTime_1).default; } });
31
- var InfiniteScroll_1 = require("./InfiniteScroll");
32
- Object.defineProperty(exports, "InfiniteScroll", { enumerable: true, get: function () { return __importDefault(InfiniteScroll_1).default; } });
33
31
  var Modal_1 = require("./material-ui/Modal");
34
32
  Object.defineProperty(exports, "Modal", { enumerable: true, get: function () { return __importDefault(Modal_1).default; } });
@@ -12,7 +12,6 @@ export interface ChatInterfaceProps {
12
12
  handleSend: (message: string) => Promise<boolean>;
13
13
  className?: string;
14
14
  style?: any;
15
- submitting: boolean;
16
15
  placeholder?: string;
17
16
  hasNextPage?: boolean;
18
17
  fetchNextPage?: () => Promise<any> | any;
@@ -20,6 +19,8 @@ export interface ChatInterfaceProps {
20
19
  isLoading: boolean;
21
20
  /** Determines if a data fetch is happening */
22
21
  isFetching: boolean;
22
+ /** Determines if a message submission is happening */
23
+ isSubmitting: boolean;
23
24
  colors?: {
24
25
  user: string;
25
26
  others: string;
@@ -27,4 +28,4 @@ export interface ChatInterfaceProps {
27
28
  /** Needs to take a ref that is used to determine the height of the input component */
28
29
  renderInputComponent?: (ref: Ref<HTMLDivElement>) => ReactNode;
29
30
  }
30
- export default function ChatInterface({ userId, messages, fetchNextPage, handleSend, hasNextPage, className, style, submitting, placeholder, isLoading, isFetching, colors, renderInputComponent, }: ChatInterfaceProps): JSX.Element;
31
+ export default function ChatInterface({ userId, messages, fetchNextPage, handleSend, hasNextPage, className, style, isSubmitting, placeholder, isLoading, isFetching, colors, renderInputComponent, }: ChatInterfaceProps): JSX.Element;
@@ -67,7 +67,7 @@ var react_measure_1 = __importDefault(require("react-measure"));
67
67
  var MessageInput_1 = __importDefault(require("./MessageInput"));
68
68
  var MessageThread_1 = __importDefault(require("./MessageThread"));
69
69
  function ChatInterface(_a) {
70
- var userId = _a.userId, messages = _a.messages, fetchNextPage = _a.fetchNextPage, handleSend = _a.handleSend, hasNextPage = _a.hasNextPage, className = _a.className, style = _a.style, submitting = _a.submitting, placeholder = _a.placeholder, isLoading = _a.isLoading, isFetching = _a.isFetching, colors = _a.colors, renderInputComponent = _a.renderInputComponent;
70
+ var userId = _a.userId, messages = _a.messages, fetchNextPage = _a.fetchNextPage, handleSend = _a.handleSend, hasNextPage = _a.hasNextPage, className = _a.className, style = _a.style, isSubmitting = _a.isSubmitting, placeholder = _a.placeholder, isLoading = _a.isLoading, isFetching = _a.isFetching, colors = _a.colors, renderInputComponent = _a.renderInputComponent;
71
71
  var _b = __read((0, react_2.useState)(''), 2), message = _b[0], setMessage = _b[1];
72
72
  var _c = __read((0, react_2.useState)(-1), 2), inputHeight = _c[0], setInputHeight = _c[1];
73
73
  function handleClickSend() {
@@ -101,8 +101,8 @@ function ChatInterface(_a) {
101
101
  } }, function (_a) {
102
102
  var measureRef = _a.measureRef;
103
103
  return ((0, react_1.jsx)(react_2.Fragment, null,
104
- (0, react_1.jsx)(MessageThread_1.default, { userId: userId, messages: messages, inputHeight: inputHeight, hasNextPage: hasNextPage, fetchNextPage: fetchNextPage, isLoading: isLoading, isFetching: isFetching, colors: colors }),
105
- renderInputComponent ? (renderInputComponent(measureRef)) : ((0, react_1.jsx)(MessageInput_1.default, { ref: measureRef, handleClickSend: handleClickSend, message: message, setMessage: setMessage, submitting: submitting, placeholder: placeholder }))));
104
+ (0, react_1.jsx)(MessageThread_1.default, { userId: userId, messages: messages, inputHeight: inputHeight, hasNextPage: hasNextPage, fetchNextPage: fetchNextPage, isLoading: isLoading, isFetching: isFetching, isSubmitting: isSubmitting, colors: colors }),
105
+ renderInputComponent ? (renderInputComponent(measureRef)) : ((0, react_1.jsx)(MessageInput_1.default, { ref: measureRef, handleClickSend: handleClickSend, message: message, setMessage: setMessage, isSubmitting: isSubmitting, placeholder: placeholder }))));
106
106
  })));
107
107
  }
108
108
  exports.default = ChatInterface;
@@ -44,7 +44,7 @@ var ChatInterface_1 = __importDefault(require("./ChatInterface"));
44
44
  function ChatInterface() {
45
45
  var _a = __read((0, react_2.useState)(true), 2), isLoading = _a[0], setLoading = _a[1];
46
46
  var _b = __read((0, react_2.useState)(true), 2), isFetching = _b[0], setFetching = _b[1];
47
- var _c = __read((0, react_2.useState)(false), 2), submitting = _c[0], setSubmitting = _c[1];
47
+ var _c = __read((0, react_2.useState)(false), 2), isSubmitting = _c[0], setSubmitting = _c[1];
48
48
  var _d = __read((0, react_2.useState)([]), 2), messages = _d[0], setMessages = _d[1];
49
49
  var _e = __read((0, react_2.useState)(true), 2), hasMore = _e[0], setHasMore = _e[1];
50
50
  (0, react_2.useEffect)(function () {
@@ -80,15 +80,16 @@ function ChatInterface() {
80
80
  function generateMessagePage() {
81
81
  return new Array(10).fill(null).map(generateMessage);
82
82
  }
83
- function loadMore() {
83
+ var fetchNextPage = (0, react_2.useCallback)(function () {
84
84
  setFetching(true);
85
85
  setTimeout(function () {
86
86
  setMessages(__spreadArray(__spreadArray([], __read(messages), false), __read(generateMessagePage()), false));
87
87
  setFetching(false);
88
88
  }, 100);
89
- }
89
+ }, [messages, generateMessagePage, setMessages]);
90
90
  function handleSend(message) {
91
91
  setSubmitting(true);
92
+ setFetching(true);
92
93
  return new Promise(function (resolve) {
93
94
  setTimeout(function () {
94
95
  setMessages(__spreadArray([
@@ -101,12 +102,13 @@ function ChatInterface() {
101
102
  }
102
103
  ], __read(messages), false));
103
104
  setSubmitting(false);
105
+ setFetching(false);
104
106
  resolve(true);
105
107
  }, 500);
106
108
  });
107
109
  }
108
- return ((0, react_1.jsx)("div", { css: (0, react_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n border: 1px solid #ededed;\n height: 50rem;\n "], ["\n border: 1px solid #ededed;\n height: 50rem;\n "]))) },
109
- (0, react_1.jsx)(ChatInterface_1.default, { userId: "user1", messages: messages, handleSend: handleSend, submitting: submitting, fetchNextPage: loadMore, hasNextPage: hasMore, isLoading: isLoading, isFetching: isFetching })));
110
+ return ((0, react_1.jsx)("div", { css: (0, react_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n border: 1px solid #ededed;\n height: 30rem;\n "], ["\n border: 1px solid #ededed;\n height: 30rem;\n "]))) },
111
+ (0, react_1.jsx)(ChatInterface_1.default, { userId: "user1", messages: messages, handleSend: handleSend, fetchNextPage: fetchNextPage, hasNextPage: hasMore, isLoading: isLoading, isFetching: isFetching, isSubmitting: isSubmitting })));
110
112
  }
111
113
  exports.ChatInterface = ChatInterface;
112
114
  var templateObject_1;
@@ -1,10 +1,9 @@
1
1
  import { Dispatch, SetStateAction } from 'react';
2
- interface Props {
2
+ import { ChatInterfaceProps } from './ChatInterface';
3
+ interface Props extends Pick<ChatInterfaceProps, 'isSubmitting' | 'placeholder'> {
3
4
  handleClickSend: () => Promise<void>;
4
5
  message: string;
5
- placeholder?: string;
6
6
  setMessage: Dispatch<SetStateAction<string>>;
7
- submitting: boolean;
8
7
  }
9
8
  declare const MessageInput: import("react").ForwardRefExoticComponent<Props & import("react").RefAttributes<HTMLDivElement>>;
10
9
  export default MessageInput;
@@ -15,7 +15,7 @@ var react_textarea_autosize_1 = __importDefault(require("react-textarea-autosize
15
15
  var material_1 = require("@mui/material");
16
16
  var icons_material_1 = require("@mui/icons-material");
17
17
  var MessageInput = (0, react_2.forwardRef)(function (_a, ref) {
18
- var handleClickSend = _a.handleClickSend, message = _a.message, placeholder = _a.placeholder, setMessage = _a.setMessage, submitting = _a.submitting;
18
+ var handleClickSend = _a.handleClickSend, message = _a.message, placeholder = _a.placeholder, setMessage = _a.setMessage, isSubmitting = _a.isSubmitting;
19
19
  function handleOnChange(_a) {
20
20
  var value = _a.target.value;
21
21
  setMessage(value);
@@ -42,7 +42,7 @@ var MessageInput = (0, react_2.forwardRef)(function (_a, ref) {
42
42
  var _a, _b;
43
43
  return (0, react_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell',\n 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n resize: none;\n width: calc(100% - 3.5rem);\n outline: 0 none transparent;\n font-size: 16px;\n margin: 0.5rem;\n padding: 0.5rem;\n box-sizing: border-box;\n border-radius: 5px;\n border-color: ", ";\n "], ["\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell',\n 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n resize: none;\n width: calc(100% - 3.5rem);\n outline: 0 none transparent;\n font-size: 16px;\n margin: 0.5rem;\n padding: 0.5rem;\n box-sizing: border-box;\n border-radius: 5px;\n border-color: ", ";\n "])), ((_b = (_a = theme === null || theme === void 0 ? void 0 : theme.palette) === null || _a === void 0 ? void 0 : _a.primary) === null || _b === void 0 ? void 0 : _b.main) || 'hsl(0, 0%, 89%)');
44
44
  }, placeholder: placeholder || 'Type your message here...', value: message, onChange: handleOnChange, onKeyDown: handleOnKeyDown, minRows: 3, maxRows: 8 }),
45
- (0, react_1.jsx)("div", { css: (0, react_1.css)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n height: 2rem;\n width: 2rem;\n padding-right: ", ";\n "], ["\n height: 2rem;\n width: 2rem;\n padding-right: ", ";\n "])), submitting ? '0.5rem' : '0.25rem') }, submitting ? ((0, react_1.jsx)(material_1.CircularProgress, { size: "2rem" })) : ((0, react_1.jsx)(material_1.IconButton, { css: (0, react_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n height: 100%;\n width: 100%;\n "], ["\n height: 100%;\n width: 100%;\n "]))), onClick: handleOnClickSend, disabled: submitting },
45
+ (0, react_1.jsx)("div", { css: (0, react_1.css)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n height: 2rem;\n width: 2rem;\n padding-right: ", ";\n "], ["\n height: 2rem;\n width: 2rem;\n padding-right: ", ";\n "])), isSubmitting ? '0.5rem' : '0.25rem') }, isSubmitting ? ((0, react_1.jsx)(material_1.CircularProgress, { size: "2rem" })) : ((0, react_1.jsx)(material_1.IconButton, { css: (0, react_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n height: 100%;\n width: 100%;\n "], ["\n height: 100%;\n width: 100%;\n "]))), onClick: handleOnClickSend, disabled: isSubmitting },
46
46
  (0, react_1.jsx)(icons_material_1.Send, null))))));
47
47
  });
48
48
  exports.default = MessageInput;
@@ -1,6 +1,6 @@
1
1
  import { ChatInterfaceProps } from './ChatInterface';
2
- interface Props extends Pick<ChatInterfaceProps, 'userId' | 'messages' | 'hasNextPage' | 'fetchNextPage' | 'isLoading' | 'isFetching' | 'colors'> {
2
+ interface Props extends Pick<ChatInterfaceProps, 'userId' | 'messages' | 'hasNextPage' | 'fetchNextPage' | 'isLoading' | 'isFetching' | 'isSubmitting' | 'colors'> {
3
3
  inputHeight: number;
4
4
  }
5
- export default function MessageThread({ userId, messages, inputHeight, hasNextPage, fetchNextPage, isLoading, isFetching, colors, }: Props): JSX.Element;
5
+ export default function MessageThread({ userId, messages, inputHeight, hasNextPage, fetchNextPage, isLoading, isFetching, isSubmitting, colors, }: Props): JSX.Element;
6
6
  export {};
@@ -12,12 +12,108 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  var react_1 = require("@emotion/react");
13
13
  var react_2 = require("react");
14
14
  var MessageItem_1 = __importDefault(require("./MessageItem"));
15
- var InfiniteScroll_1 = __importDefault(require("../../InfiniteScroll/InfiniteScroll"));
15
+ var lodash_1 = require("lodash");
16
+ var material_1 = require("@mui/material");
16
17
  function MessageThread(_a) {
17
- var userId = _a.userId, messages = _a.messages, inputHeight = _a.inputHeight, hasNextPage = _a.hasNextPage, fetchNextPage = _a.fetchNextPage, isLoading = _a.isLoading, isFetching = _a.isFetching, colors = _a.colors;
18
+ var _b;
19
+ var userId = _a.userId, messages = _a.messages, inputHeight = _a.inputHeight, hasNextPage = _a.hasNextPage, fetchNextPage = _a.fetchNextPage, isLoading = _a.isLoading, isFetching = _a.isFetching, isSubmitting = _a.isSubmitting, colors = _a.colors;
20
+ var isInitialized = (0, react_2.useRef)(false);
21
+ var isScrollLoad = (0, react_2.useRef)(false);
22
+ var hasSubmitted = (0, react_2.useRef)(false);
23
+ var prevScrollTop = (0, react_2.useRef)(null);
24
+ var prevScrollHeight = (0, react_2.useRef)(null);
25
+ var shouldScrollToPrevPosition = (0, react_2.useRef)(false);
18
26
  var scrollParent = (0, react_2.useRef)(null);
27
+ var handleScrollEvent = (0, react_2.useCallback)((0, lodash_1.debounce)(function (evt) {
28
+ var parent = evt.target;
29
+ if (parent.scrollTop === 0 && hasNextPage && fetchNextPage && !isLoading && !isFetching) {
30
+ isScrollLoad.current = true;
31
+ prevScrollHeight.current = parent.scrollHeight;
32
+ fetchNextPage();
33
+ }
34
+ }, 300), [hasNextPage, fetchNextPage, isLoading, isFetching]);
35
+ (0, react_2.useEffect)(function () {
36
+ if (isSubmitting) {
37
+ hasSubmitted.current = true;
38
+ }
39
+ }, [isSubmitting]);
40
+ // This will handle the initial loading of messages, then scroll to bottom
41
+ (0, react_2.useEffect)(function () {
42
+ if (!isInitialized.current && !isFetching && scrollParent.current) {
43
+ var _a = scrollParent.current, clientHeight = _a.clientHeight, scrollHeight = _a.scrollHeight;
44
+ if (clientHeight >= scrollHeight && hasNextPage && fetchNextPage) {
45
+ fetchNextPage();
46
+ return;
47
+ }
48
+ isInitialized.current = true;
49
+ scrollParent.current.scrollTo(0, scrollHeight - clientHeight);
50
+ }
51
+ }, [isFetching, isInitialized.current, hasNextPage, fetchNextPage]);
52
+ // Sets up the scroll event listener
53
+ (0, react_2.useEffect)(function () {
54
+ if (scrollParent.current) {
55
+ scrollParent.current.addEventListener('scroll', handleScrollEvent);
56
+ }
57
+ return function () {
58
+ if (scrollParent.current) {
59
+ scrollParent.current.removeEventListener('scroll', handleScrollEvent);
60
+ }
61
+ };
62
+ }, [scrollParent.current, hasNextPage, fetchNextPage, isLoading, isFetching]);
63
+ // Handles the scroll position adjustment after fetching the next page
64
+ (0, react_2.useEffect)(function () {
65
+ if (!isFetching &&
66
+ isInitialized.current &&
67
+ scrollParent.current &&
68
+ isScrollLoad.current &&
69
+ prevScrollHeight.current &&
70
+ scrollParent.current.scrollHeight !== prevScrollHeight.current) {
71
+ var delta = scrollParent.current.scrollHeight - prevScrollHeight.current;
72
+ scrollParent.current.scrollTo(0, delta);
73
+ isScrollLoad.current = false;
74
+ prevScrollHeight.current = 0;
75
+ }
76
+ }, [isFetching, prevScrollHeight.current]);
77
+ // Manages scroll position for data changes that are triggered from anything other than the scroll event
78
+ (0, react_2.useEffect)(function () {
79
+ var _a;
80
+ if (scrollParent.current && !isScrollLoad.current && isInitialized.current) {
81
+ var _b = scrollParent.current, scrollHeight = _b.scrollHeight, scrollTop = _b.scrollTop, clientHeight = _b.clientHeight;
82
+ if (isFetching) {
83
+ // track the current position
84
+ prevScrollHeight.current = scrollHeight;
85
+ prevScrollTop.current = scrollTop;
86
+ var distanceFromBottom = scrollHeight - scrollTop - clientHeight;
87
+ if (!isSubmitting && distanceFromBottom > 200) {
88
+ shouldScrollToPrevPosition.current = true;
89
+ }
90
+ }
91
+ else {
92
+ // init to scroll to bottom delta
93
+ var delta = scrollHeight - clientHeight;
94
+ if (hasSubmitted.current) {
95
+ // scroll to bottom if this was triggered by the current user's sent message
96
+ (_a = scrollParent.current) === null || _a === void 0 ? void 0 : _a.scrollTo(0, delta);
97
+ }
98
+ else if (!isFetching && prevScrollHeight.current !== null && prevScrollTop.current !== null) {
99
+ if (shouldScrollToPrevPosition.current) {
100
+ delta = prevScrollTop.current;
101
+ }
102
+ scrollParent.current.scrollTo(0, delta);
103
+ }
104
+ // clean up
105
+ prevScrollHeight.current = null;
106
+ prevScrollTop.current = null;
107
+ hasSubmitted.current = false;
108
+ shouldScrollToPrevPosition.current = false;
109
+ }
110
+ }
111
+ }, [isFetching, (_b = scrollParent.current) === null || _b === void 0 ? void 0 : _b.scrollHeight]);
19
112
  return ((0, react_1.jsx)("div", { ref: scrollParent, css: (0, react_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n box-sizing: border-box;\n height: calc(100% - ", "px);\n width: 100%;\n padding: 0.5rem 1rem;\n overflow-y: auto;\n "], ["\n box-sizing: border-box;\n height: calc(100% - ", "px);\n width: 100%;\n padding: 0.5rem 1rem;\n overflow-y: auto;\n "])), inputHeight) },
20
- (0, react_1.jsx)(InfiniteScroll_1.default, { scrollParent: scrollParent, isReverse: true, isLoading: isLoading, isFetching: isFetching, hasNextPage: hasNextPage, fetchNextPage: fetchNextPage }, messages.map(function (message) { return ((0, react_1.jsx)(MessageItem_1.default, { key: "" + message.id, message: message, userId: userId, colors: colors })); }))));
113
+ (0, react_1.jsx)("div", { css: (0, react_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n flex-direction: column-reverse;\n justify-content: flex-start;\n align-items: flex-start;\n "], ["\n display: flex;\n flex-direction: column-reverse;\n justify-content: flex-start;\n align-items: flex-start;\n "]))) },
114
+ messages.map(function (message) { return ((0, react_1.jsx)(MessageItem_1.default, { key: "" + message.id, message: message, userId: userId, colors: colors })); }),
115
+ hasNextPage && ((0, react_1.jsx)("div", { key: "loader", css: (0, react_1.css)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n width: 100%;\n margin: 0.5rem 0;\n height: auto;\n display: flex;\n justify-content: center;\n align-items: center;\n\n && {\n visibility: ", ";\n }\n "], ["\n width: 100%;\n margin: 0.5rem 0;\n height: auto;\n display: flex;\n justify-content: center;\n align-items: center;\n\n && {\n visibility: ", ";\n }\n "])), isFetching && isScrollLoad ? 'visible' : 'hidden') },
116
+ (0, react_1.jsx)(material_1.CircularProgress, { size: "1.5rem", disableShrink: true }))))));
21
117
  }
22
118
  exports.default = MessageThread;
23
- var templateObject_1;
119
+ var templateObject_1, templateObject_2, templateObject_3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vendorflow/components",
3
- "version": "2.0.40",
3
+ "version": "2.0.44",
4
4
  "description": "React components for vendorflow",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",