@vendorflow/components 2.0.32 → 2.0.36

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.
@@ -6,10 +6,11 @@ interface Props {
6
6
  children: ReactElement[];
7
7
  scrollParent: MutableRefObject<HTMLDivElement | null>;
8
8
  isLoading?: boolean;
9
+ isFetching?: boolean;
9
10
  isReverse?: boolean;
10
- hasMore?: boolean;
11
- loadMore?: () => Promise<void> | void;
11
+ hasNextPage?: boolean;
12
+ fetchNextPage?: () => Promise<any> | any;
12
13
  Loader?: ReactElement;
13
14
  }
14
- export default function InfiniteScroll({ children, scrollParent, isLoading, isReverse, hasMore, loadMore, Loader, }: Props): jsx.JSX.Element;
15
+ export default function InfiniteScroll({ children, scrollParent, isLoading, isFetching, isReverse, hasNextPage, fetchNextPage, Loader, }: Props): jsx.JSX.Element;
15
16
  export {};
@@ -3,6 +3,22 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook
3
3
  if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
4
  return cooked;
5
5
  };
6
+ var __read = (this && this.__read) || function (o, n) {
7
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
8
+ if (!m) return o;
9
+ var i = m.call(o), r, ar = [], e;
10
+ try {
11
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
12
+ }
13
+ catch (error) { e = { error: error }; }
14
+ finally {
15
+ try {
16
+ if (r && !r.done && (m = i["return"])) m.call(i);
17
+ }
18
+ finally { if (e) throw e.error; }
19
+ }
20
+ return ar;
21
+ };
6
22
  Object.defineProperty(exports, "__esModule", { value: true });
7
23
  /** @jsxRuntime classic */
8
24
  /** @jsx jsx */
@@ -10,18 +26,31 @@ var react_1 = require("@emotion/react");
10
26
  var react_2 = require("react");
11
27
  var material_1 = require("@mui/material");
12
28
  function InfiniteScroll(_a) {
13
- var children = _a.children, scrollParent = _a.scrollParent, isLoading = _a.isLoading, isReverse = _a.isReverse, hasMore = _a.hasMore, loadMore = _a.loadMore, Loader = _a.Loader;
29
+ var children = _a.children, scrollParent = _a.scrollParent, isLoading = _a.isLoading, isFetching = _a.isFetching, isReverse = _a.isReverse, hasNextPage = _a.hasNextPage, fetchNextPage = _a.fetchNextPage, Loader = _a.Loader;
30
+ var _b = __read((0, react_2.useState)(false), 2), isLoadMoreFetch = _b[0], setLoadMoreFetch = _b[1];
14
31
  var scrollBody = (0, react_2.useRef)(null);
15
32
  var loadMoreRef = useInfiniteScroll({
16
33
  scrollParent: scrollParent,
17
34
  scrollBody: scrollBody,
18
35
  isReverse: isReverse,
19
36
  isLoading: isLoading,
20
- hasMore: hasMore,
21
- loadMore: loadMore,
37
+ isFetching: isFetching,
38
+ hasNextPage: hasNextPage,
39
+ fetchNextPage: fetchNextPageAndSetFlag,
22
40
  });
41
+ (0, react_2.useEffect)(function () {
42
+ if (!isFetching) {
43
+ setLoadMoreFetch(false);
44
+ }
45
+ }, [isFetching]);
46
+ function fetchNextPageAndSetFlag() {
47
+ if (fetchNextPage) {
48
+ fetchNextPage();
49
+ setLoadMoreFetch(true);
50
+ }
51
+ }
23
52
  function renderLoader() {
24
- if (!hasMore) {
53
+ if (!hasNextPage) {
25
54
  return null;
26
55
  }
27
56
  if (Loader) {
@@ -29,12 +58,12 @@ function InfiniteScroll(_a) {
29
58
  var css = _a.css;
30
59
  return (0, react_2.cloneElement)(Loader, {
31
60
  ref: loadMoreRef,
32
- className: css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n && {\n visibility: ", ";\n }\n "], ["\n && {\n visibility: ", ";\n }\n "])), isLoading ? 'visible' : 'hidden'),
61
+ className: css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n && {\n visibility: ", ";\n }\n "], ["\n && {\n visibility: ", ";\n }\n "])), isFetching && isLoadMoreFetch ? 'visible' : 'hidden'),
33
62
  });
34
63
  }));
35
64
  }
36
65
  else {
37
- return ((0, react_1.jsx)(DefaultLoader, { css: (0, react_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n && {\n visibility: ", ";\n }\n "], ["\n && {\n visibility: ", ";\n }\n "])), isLoading ? 'visible' : 'hidden'), ref: loadMoreRef }));
66
+ return ((0, react_1.jsx)(DefaultLoader, { css: (0, react_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n && {\n visibility: ", ";\n }\n "], ["\n && {\n visibility: ", ";\n }\n "])), isFetching && isLoadMoreFetch ? 'visible' : 'hidden'), ref: loadMoreRef }));
38
67
  }
39
68
  }
40
69
  return ((0, react_1.jsx)("div", { css: (0, react_1.css)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n display: flex;\n flex-direction: ", ";\n justify-content: flex-start;\n align-items: flex-start;\n "], ["\n display: flex;\n flex-direction: ", ";\n justify-content: flex-start;\n align-items: flex-start;\n "])), isReverse ? 'column-reverse' : 'column'), ref: scrollBody },
@@ -48,50 +77,55 @@ var DefaultLoader = (0, react_2.forwardRef)(function (_a, ref) {
48
77
  (0, react_1.jsx)(material_1.CircularProgress, { size: "1.5rem", disableShrink: true })));
49
78
  });
50
79
  function useInfiniteScroll(_a) {
51
- var scrollParent = _a.scrollParent, scrollBody = _a.scrollBody, isLoading = _a.isLoading, isReverse = _a.isReverse, hasMore = _a.hasMore, loadMore = _a.loadMore;
52
- var prevTarget = (0, react_2.useRef)();
80
+ var scrollParent = _a.scrollParent, scrollBody = _a.scrollBody, isLoading = _a.isLoading, isFetching = _a.isFetching, isReverse = _a.isReverse, hasNextPage = _a.hasNextPage, fetchNextPage = _a.fetchNextPage;
81
+ var prevPosition = (0, react_2.useRef)();
53
82
  var observer = (0, react_2.useRef)();
54
- return (0, react_2.useCallback)(function (node) {
55
- var _a;
56
- function scrollToStart() {
57
- var _a;
58
- var scrollHeight = (scrollBody.current || { scrollHeight: 0 }).scrollHeight;
59
- var scrollToValue = isReverse ? scrollHeight : 0;
60
- (_a = scrollParent.current) === null || _a === void 0 ? void 0 : _a.scrollTo(0, scrollToValue);
83
+ var hasScrollbar = (0, react_2.useMemo)(function () {
84
+ if (scrollParent.current && scrollBody.current) {
85
+ return scrollBody.current.clientHeight > scrollParent.current.clientHeight;
86
+ }
87
+ return false;
88
+ }, [scrollParent, scrollBody]);
89
+ (0, react_2.useEffect)(function () {
90
+ if (!isLoading && hasScrollbar) {
91
+ scrollToStart();
61
92
  }
62
- if (isLoading) {
93
+ }, [isLoading, hasScrollbar]);
94
+ function scrollToStart() {
95
+ var _a;
96
+ var scrollHeight = (scrollBody.current || { scrollHeight: 0 }).scrollHeight;
97
+ var scrollToValue = isReverse ? scrollHeight : 0;
98
+ (_a = scrollParent.current) === null || _a === void 0 ? void 0 : _a.scrollTo(0, scrollToValue);
99
+ }
100
+ // this callback is used and fired based on the state of the element it is attached to
101
+ return (0, react_2.useCallback)(function (node) {
102
+ if (isLoading || isFetching) {
63
103
  return;
64
104
  }
65
105
  if (observer.current) {
66
106
  observer.current.disconnect();
67
107
  }
68
108
  observer.current = new IntersectionObserver(function (entries) {
69
- if (entries[0].isIntersecting && hasMore && loadMore) {
70
- if (scrollParent.current) {
109
+ if (entries[0].isIntersecting && hasNextPage && fetchNextPage) {
110
+ if (scrollBody.current && isReverse) {
71
111
  // save the last element, so that we can scroll to it after the new data loads in
72
- prevTarget.current = entries[0].target;
112
+ prevPosition.current = scrollBody.current.clientHeight;
73
113
  }
74
114
  // load the next page
75
- loadMore();
115
+ fetchNextPage();
76
116
  }
77
117
  }, {
78
118
  root: (scrollParent === null || scrollParent === void 0 ? void 0 : scrollParent.current) || null,
79
119
  threshold: 1.0,
80
120
  });
81
121
  if (node) {
82
- if (scrollParent.current) {
83
- // If we had a prev target, then we want to scroll to its position
84
- if (prevTarget.current) {
85
- (_a = prevTarget.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: 'auto', block: 'center' });
86
- prevTarget.current = undefined;
87
- }
88
- else {
89
- // else we will just scroll to the start of the list
90
- scrollToStart();
91
- }
122
+ if (isReverse && scrollParent.current && prevPosition.current != null) {
123
+ // If we had a prev position, then we want to scroll to it
124
+ scrollParent.current.scrollTo(0, scrollBody.current.clientHeight - prevPosition.current);
125
+ prevPosition.current = null;
92
126
  }
93
127
  observer.current.observe(node);
94
128
  }
95
- }, [isLoading, isReverse, hasMore, loadMore, scrollParent, scrollBody]);
129
+ }, [isLoading, isFetching, isReverse, hasNextPage, fetchNextPage, scrollParent, scrollBody]);
96
130
  }
97
131
  var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
@@ -14,9 +14,12 @@ export interface ChatInterfaceProps {
14
14
  style?: any;
15
15
  submitting: boolean;
16
16
  placeholder?: string;
17
- hasMore?: boolean;
18
- loadMore?: () => Promise<void> | void;
17
+ hasNextPage?: boolean;
18
+ fetchNextPage?: () => Promise<any> | any;
19
+ /** Determines if the initial load is happening */
19
20
  isLoading: boolean;
21
+ /** Determines if a data fetch is happening */
22
+ isFetching: boolean;
20
23
  colors?: {
21
24
  user: string;
22
25
  others: string;
@@ -24,4 +27,4 @@ export interface ChatInterfaceProps {
24
27
  /** Needs to take a ref that is used to determine the height of the input component */
25
28
  renderInputComponent?: (ref: Ref<HTMLDivElement>) => ReactNode;
26
29
  }
27
- export default function ChatInterface({ userId, messages, loadMore, handleSend, hasMore, className, style, submitting, placeholder, isLoading, colors, renderInputComponent, }: ChatInterfaceProps): JSX.Element;
30
+ export default function ChatInterface({ userId, messages, fetchNextPage, handleSend, hasNextPage, className, style, submitting, 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, loadMore = _a.loadMore, handleSend = _a.handleSend, hasMore = _a.hasMore, className = _a.className, style = _a.style, submitting = _a.submitting, placeholder = _a.placeholder, isLoading = _a.isLoading, 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, submitting = _a.submitting, 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,7 +101,7 @@ 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, hasMore: hasMore, loadMore: loadMore, isLoading: isLoading, colors: colors }),
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
105
  renderInputComponent ? (renderInputComponent(measureRef)) : ((0, react_1.jsx)(MessageInput_1.default, { ref: measureRef, handleClickSend: handleClickSend, message: message, setMessage: setMessage, submitting: submitting, placeholder: placeholder }))));
106
106
  })));
107
107
  }
@@ -37,14 +37,16 @@ exports.ChatInterface = void 0;
37
37
  /** @jsx jsx */
38
38
  var react_1 = require("@emotion/react");
39
39
  var react_2 = require("react");
40
+ var faker_1 = __importDefault(require("faker"));
40
41
  var short_uuid_1 = __importDefault(require("short-uuid"));
41
42
  var ChatInterface_1 = __importDefault(require("./ChatInterface"));
42
43
  // tslint:disable-next-line:no-console
43
44
  function ChatInterface() {
44
45
  var _a = __read((0, react_2.useState)(true), 2), isLoading = _a[0], setLoading = _a[1];
45
- var _b = __read((0, react_2.useState)(false), 2), submitting = _b[0], setSubmitting = _b[1];
46
- var _c = __read((0, react_2.useState)([]), 2), messages = _c[0], setMessages = _c[1];
47
- var _d = __read((0, react_2.useState)(true), 2), hasMore = _d[0], setHasMore = _d[1];
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];
48
+ var _d = __read((0, react_2.useState)([]), 2), messages = _d[0], setMessages = _d[1];
49
+ var _e = __read((0, react_2.useState)(true), 2), hasMore = _e[0], setHasMore = _e[1];
48
50
  (0, react_2.useEffect)(function () {
49
51
  setMessages([
50
52
  {
@@ -98,6 +100,7 @@ function ChatInterface() {
98
100
  },
99
101
  ]);
100
102
  setLoading(false);
103
+ setFetching(false);
101
104
  }, []);
102
105
  function generateTimestamp() {
103
106
  return new Date().toISOString();
@@ -105,34 +108,32 @@ function ChatInterface() {
105
108
  function generateId() {
106
109
  return short_uuid_1.default.generate();
107
110
  }
108
- function loadMore() {
109
- setLoading(true);
110
- setTimeout(function () {
111
- setMessages(__spreadArray(__spreadArray([], __read(messages), false), [
111
+ function generateMessagePage() {
112
+ return new Array(10).fill(null).map(function () {
113
+ var user = faker_1.default.random.arrayElement([
112
114
  {
113
- id: generateId(),
114
- userId: 'user1',
115
- username: 'Socorro Aguilar',
116
- timestamp: generateTimestamp(),
117
- content: 'Great!',
115
+ id: 'user1',
116
+ name: 'Socorro Aguilar',
118
117
  },
119
118
  {
120
- id: generateId(),
121
- userId: 'user2',
122
- username: 'Greg Bujak',
123
- timestamp: generateTimestamp(),
124
- content: 'how are you?',
119
+ id: 'user2',
120
+ name: 'Greg Bujak',
125
121
  },
126
- {
127
- id: generateId(),
128
- userId: 'user1',
129
- username: 'Socorro Aguilar',
130
- timestamp: generateTimestamp(),
131
- content: 'hello',
132
- },
133
- ], false));
134
- setHasMore(false);
135
- setLoading(false);
122
+ ]);
123
+ return {
124
+ id: generateId(),
125
+ userId: user.id,
126
+ username: user.name,
127
+ timestamp: generateTimestamp(),
128
+ content: faker_1.default.lorem.sentence(5, 2),
129
+ };
130
+ });
131
+ }
132
+ function loadMore() {
133
+ setFetching(true);
134
+ setTimeout(function () {
135
+ setMessages(__spreadArray(__spreadArray([], __read(messages), false), __read(generateMessagePage()), false));
136
+ setFetching(false);
136
137
  }, 1000);
137
138
  }
138
139
  function handleSend(message) {
@@ -153,8 +154,8 @@ function ChatInterface() {
153
154
  }, 500);
154
155
  });
155
156
  }
156
- return ((0, react_1.jsx)("div", { css: (0, react_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n border: 1px solid #ededed;\n height: 20rem;\n "], ["\n border: 1px solid #ededed;\n height: 20rem;\n "]))) },
157
- (0, react_1.jsx)(ChatInterface_1.default, { userId: "user1", messages: messages, handleSend: handleSend, submitting: submitting, loadMore: loadMore, hasMore: hasMore, isLoading: isLoading })));
157
+ return ((0, react_1.jsx)("div", { css: (0, react_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n border: 1px solid #ededed;\n height: 40rem;\n "], ["\n border: 1px solid #ededed;\n height: 40rem;\n "]))) },
158
+ (0, react_1.jsx)(ChatInterface_1.default, { userId: "user1", messages: messages, handleSend: handleSend, submitting: submitting, fetchNextPage: loadMore, hasNextPage: hasMore, isLoading: isLoading, isFetching: isFetching })));
158
159
  }
159
160
  exports.ChatInterface = ChatInterface;
160
161
  var templateObject_1;
@@ -1,6 +1,6 @@
1
1
  import { ChatInterfaceProps } from './ChatInterface';
2
- interface Props extends Pick<ChatInterfaceProps, 'userId' | 'messages' | 'hasMore' | 'loadMore' | 'isLoading' | 'colors'> {
2
+ interface Props extends Pick<ChatInterfaceProps, 'userId' | 'messages' | 'hasNextPage' | 'fetchNextPage' | 'isLoading' | 'isFetching' | 'colors'> {
3
3
  inputHeight: number;
4
4
  }
5
- export default function MessageThread({ userId, messages, inputHeight, hasMore, loadMore, isLoading, colors, }: Props): JSX.Element;
5
+ export default function MessageThread({ userId, messages, inputHeight, hasNextPage, fetchNextPage, isLoading, isFetching, colors, }: Props): JSX.Element;
6
6
  export {};
@@ -14,10 +14,10 @@ var react_2 = require("react");
14
14
  var MessageItem_1 = __importDefault(require("./MessageItem"));
15
15
  var InfiniteScroll_1 = __importDefault(require("../../InfiniteScroll/InfiniteScroll"));
16
16
  function MessageThread(_a) {
17
- var userId = _a.userId, messages = _a.messages, inputHeight = _a.inputHeight, hasMore = _a.hasMore, loadMore = _a.loadMore, isLoading = _a.isLoading, colors = _a.colors;
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
18
  var scrollParent = (0, react_2.useRef)(null);
19
19
  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, hasMore: hasMore, loadMore: loadMore }, messages.map(function (message) { return ((0, react_1.jsx)(MessageItem_1.default, { key: "" + message.id, message: message, userId: userId, colors: colors })); }))));
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 })); }))));
21
21
  }
22
22
  exports.default = MessageThread;
23
23
  var templateObject_1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vendorflow/components",
3
- "version": "2.0.32",
3
+ "version": "2.0.36",
4
4
  "description": "React components for vendorflow",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",