@elliemae/ds-chat 3.3.0-next.8 → 3.3.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/dist/cjs/Code-review - 20 june 2022.md +119 -0
- package/dist/cjs/exported-related/bubble/props.js.map +1 -1
- package/dist/cjs/parts/chat-container-messages-list/ChatContainerMessagesList.js +11 -208
- package/dist/cjs/parts/chat-container-messages-list/ChatContainerMessagesList.js.map +2 -2
- package/dist/cjs/parts/chat-container-messages-list/styled.js.map +1 -1
- package/dist/cjs/parts/chat-container-messages-list/useActionRef.js +58 -0
- package/dist/cjs/parts/chat-container-messages-list/useActionRef.js.map +7 -0
- package/dist/cjs/parts/chat-container-messages-list/useChatContainerMessageList.js +100 -0
- package/dist/cjs/parts/chat-container-messages-list/useChatContainerMessageList.js.map +7 -0
- package/dist/cjs/parts/chat-container-messages-list/useFocusAndScrollHelpers.js +78 -0
- package/dist/cjs/parts/chat-container-messages-list/useFocusAndScrollHelpers.js.map +7 -0
- package/dist/cjs/parts/chat-container-messages-list/useGetNewMessages.js.map +2 -2
- package/dist/cjs/parts/chat-container-messages-list/useGlobalEventListener.js +56 -0
- package/dist/cjs/parts/chat-container-messages-list/useGlobalEventListener.js.map +7 -0
- package/dist/cjs/parts/chat-container-messages-list/useKeyboard.js +136 -0
- package/dist/cjs/parts/chat-container-messages-list/useKeyboard.js.map +7 -0
- package/dist/cjs/react-desc-prop-types.js +20 -20
- package/dist/cjs/react-desc-prop-types.js.map +2 -2
- package/dist/esm/Code-review - 20 june 2022.md +119 -0
- package/dist/esm/exported-related/bubble/props.js.map +1 -1
- package/dist/esm/parts/chat-container-messages-list/ChatContainerMessagesList.js +13 -215
- package/dist/esm/parts/chat-container-messages-list/ChatContainerMessagesList.js.map +2 -2
- package/dist/esm/parts/chat-container-messages-list/styled.js.map +1 -1
- package/dist/esm/parts/chat-container-messages-list/useActionRef.js +36 -0
- package/dist/esm/parts/chat-container-messages-list/useActionRef.js.map +7 -0
- package/dist/esm/parts/chat-container-messages-list/useChatContainerMessageList.js +82 -0
- package/dist/esm/parts/chat-container-messages-list/useChatContainerMessageList.js.map +7 -0
- package/dist/esm/parts/chat-container-messages-list/useFocusAndScrollHelpers.js +56 -0
- package/dist/esm/parts/chat-container-messages-list/useFocusAndScrollHelpers.js.map +7 -0
- package/dist/esm/parts/chat-container-messages-list/useGetNewMessages.js.map +2 -2
- package/dist/esm/parts/chat-container-messages-list/useGlobalEventListener.js +34 -0
- package/dist/esm/parts/chat-container-messages-list/useGlobalEventListener.js.map +7 -0
- package/dist/esm/parts/chat-container-messages-list/useKeyboard.js +114 -0
- package/dist/esm/parts/chat-container-messages-list/useKeyboard.js.map +7 -0
- package/dist/esm/react-desc-prop-types.js +10 -10
- package/dist/esm/react-desc-prop-types.js.map +2 -2
- package/package.json +10 -10
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/parts/chat-container-messages-list/useChatContainerMessageList.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable complexity */\n/* eslint-disable jsx-a11y/no-noninteractive-tabindex */\n/* eslint-disable max-lines */\nimport React from 'react';\nimport {\n useMemoMergePropsWithDefault,\n useGetGlobalAttributes,\n useValidateTypescriptPropTypes,\n} from '@elliemae/ds-utilities';\nimport { useVirtual } from 'react-virtual';\nimport { useActionRef } from './useActionRef';\nimport { useGlobalEventListener } from './useGlobalEventListener';\nimport { useKeyboard } from './useKeyboard';\nimport { useFocusAndScrollHelpers } from './useFocusAndScrollHelpers';\nimport { DSChatT, ChatContainerMessagesListPropTypes, defaultPropsMessagesList } from '../../react-desc-prop-types';\n\nconst getPadding = ({ hasMoreItems, bannerPosition, isLoading }: DSChatT.GetPaddingT) => {\n const padding = {\n paddingStart: 0,\n paddingEnd: -5,\n };\n if ([hasMoreItems, bannerPosition, isLoading].some((item) => item === 'top')) padding.paddingStart = 42;\n else if ([hasMoreItems, bannerPosition, isLoading].some((item) => item === 'bottom')) padding.paddingEnd = 42;\n return padding;\n};\n\ntype UseChatContainerMessageList = (props: DSChatT.MessagesListProps) => {\n propsWithDefault: DSChatT.MessagesListProps;\n globalAttributes: ReturnType<typeof useGetGlobalAttributes>;\n useVirtualHelpers: ReturnType<typeof useVirtual>;\n loadMoreRef: React.MutableRefObject<HTMLButtonElement | undefined>;\n virtualListRef: React.MutableRefObject<HTMLDivElement | undefined>;\n} & ReturnType<typeof useKeyboard>;\n\nexport const useChatContainerMessageList: UseChatContainerMessageList = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSChatT.MessagesListProps>(props, defaultPropsMessagesList);\n useValidateTypescriptPropTypes<DSChatT.MessagesListProps>(propsWithDefault, ChatContainerMessagesListPropTypes);\n const globalAttributes = useGetGlobalAttributes(propsWithDefault);\n const loadMoreRef = React.useRef<HTMLButtonElement>();\n const virtualListRef = React.useRef<HTMLDivElement>();\n\n const pendingOnScroll = React.useRef(false);\n const { bannerPosition, messages, actionRef, hasMoreItems, isLoading } = propsWithDefault;\n const useVirtualHelpers = useVirtual({\n size: messages?.length,\n parentRef: virtualListRef,\n overscan: 15,\n ...getPadding({ hasMoreItems, bannerPosition, isLoading }),\n // estimateSize should not be really required given what was stated on\n // https://github.com/tannerlinsley/react-virtual/issues/23\n estimateSize: React.useCallback(() => 80, []),\n });\n\n const { onScrollStop, onlyFocus, scrollAndFocus, checkPendingOnScroll } = useFocusAndScrollHelpers({\n propsWithDefault,\n useVirtualHelpers,\n pendingOnScroll,\n virtualListRef,\n });\n\n useActionRef({\n actionRef,\n useVirtualHelpers,\n virtualListRef,\n onScrollStop,\n onlyFocus,\n scrollAndFocus,\n });\n\n useGlobalEventListener({\n propsWithDefault,\n virtualListRef,\n onScrollStop,\n checkPendingOnScroll,\n });\n\n const keyboardMethods = useKeyboard({\n propsWithDefault,\n actionRef,\n virtualListRef,\n loadMoreRef,\n scrollAndFocus,\n onlyFocus,\n onScrollStop,\n });\n\n return React.useMemo(\n () => ({\n propsWithDefault,\n globalAttributes,\n useVirtualHelpers,\n loadMoreRef,\n virtualListRef,\n ...keyboardMethods,\n }),\n [globalAttributes, keyboardMethods, propsWithDefault, useVirtualHelpers, loadMoreRef, virtualListRef],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADGvB,mBAAkB;AAClB,0BAIO;AACP,2BAA2B;AAC3B,0BAA6B;AAC7B,oCAAuC;AACvC,yBAA4B;AAC5B,sCAAyC;AACzC,mCAAsF;AAEtF,MAAM,aAAa,CAAC,EAAE,cAAc,gBAAgB,gBAAqC;AACvF,QAAM,UAAU;AAAA,IACd,cAAc;AAAA,IACd,YAAY;AAAA,EACd;AACA,MAAI,CAAC,cAAc,gBAAgB,SAAS,EAAE,KAAK,CAAC,SAAS,SAAS,KAAK;AAAG,YAAQ,eAAe;AAAA,WAC5F,CAAC,cAAc,gBAAgB,SAAS,EAAE,KAAK,CAAC,SAAS,SAAS,QAAQ;AAAG,YAAQ,aAAa;AAC3G,SAAO;AACT;AAUO,MAAM,8BAA2D,CAAC,UAAU;AACjF,QAAM,mBAAmB,sDAAwD,OAAO,qDAAwB;AAChH,0DAA0D,kBAAkB,+DAAkC;AAC9G,QAAM,mBAAmB,gDAAuB,gBAAgB;AAChE,QAAM,cAAc,qBAAM,OAA0B;AACpD,QAAM,iBAAiB,qBAAM,OAAuB;AAEpD,QAAM,kBAAkB,qBAAM,OAAO,KAAK;AAC1C,QAAM,EAAE,gBAAgB,UAAU,WAAW,cAAc,cAAc;AACzE,QAAM,oBAAoB,qCAAW;AAAA,IACnC,MAAM,UAAU;AAAA,IAChB,WAAW;AAAA,IACX,UAAU;AAAA,IACV,GAAG,WAAW,EAAE,cAAc,gBAAgB,UAAU,CAAC;AAAA,IAGzD,cAAc,qBAAM,YAAY,MAAM,IAAI,CAAC,CAAC;AAAA,EAC9C,CAAC;AAED,QAAM,EAAE,cAAc,WAAW,gBAAgB,yBAAyB,8DAAyB;AAAA,IACjG;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,wCAAa;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,4DAAuB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB,oCAAY;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,qBAAM,QACX,MAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IACA,CAAC,kBAAkB,iBAAiB,kBAAkB,mBAAmB,aAAa,cAAc,CACtG;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
var useFocusAndScrollHelpers_exports = {};
|
|
23
|
+
__export(useFocusAndScrollHelpers_exports, {
|
|
24
|
+
useFocusAndScrollHelpers: () => useFocusAndScrollHelpers
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(useFocusAndScrollHelpers_exports);
|
|
27
|
+
var React = __toESM(require("react"));
|
|
28
|
+
var import_react = __toESM(require("react"));
|
|
29
|
+
var import_lodash = require("lodash");
|
|
30
|
+
const useFocusAndScrollHelpers = ({
|
|
31
|
+
propsWithDefault: { onScrollEnds },
|
|
32
|
+
useVirtualHelpers: { scrollToIndex: vScroll },
|
|
33
|
+
pendingOnScroll,
|
|
34
|
+
virtualListRef
|
|
35
|
+
}) => {
|
|
36
|
+
const onScrollStop = import_react.default.useMemo(() => (0, import_lodash.debounce)(() => {
|
|
37
|
+
if (document.visibilityState === "hidden") {
|
|
38
|
+
pendingOnScroll.current = true;
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
if (!virtualListRef.current)
|
|
42
|
+
return [];
|
|
43
|
+
pendingOnScroll.current = false;
|
|
44
|
+
const { bottom, top } = virtualListRef.current?.getBoundingClientRect() || {};
|
|
45
|
+
const list = virtualListRef.current.querySelectorAll('[data-element="chat-element-list-item"]');
|
|
46
|
+
const indexList = [];
|
|
47
|
+
list.forEach((item) => {
|
|
48
|
+
const { top: itemTop } = item.getBoundingClientRect();
|
|
49
|
+
const itemPadding = 10;
|
|
50
|
+
if (itemTop + itemPadding < bottom && itemTop + itemPadding > top)
|
|
51
|
+
indexList.push(item.dataset.index || "");
|
|
52
|
+
});
|
|
53
|
+
if (onScrollEnds)
|
|
54
|
+
onScrollEnds(indexList);
|
|
55
|
+
return indexList;
|
|
56
|
+
}, 500), [onScrollEnds, pendingOnScroll, virtualListRef]);
|
|
57
|
+
const onlyFocus = import_react.default.useCallback((index) => {
|
|
58
|
+
virtualListRef.current?.querySelector(`[data-index="${index || ""}"]`)?.focus();
|
|
59
|
+
}, [virtualListRef]);
|
|
60
|
+
const scrollAndFocus = import_react.default.useCallback((index, opts = { align: "center" }) => {
|
|
61
|
+
vScroll(index, opts);
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
onlyFocus(index);
|
|
64
|
+
}, 300);
|
|
65
|
+
onScrollStop();
|
|
66
|
+
}, [onScrollStop, onlyFocus, vScroll]);
|
|
67
|
+
const checkPendingOnScroll = import_react.default.useCallback(() => {
|
|
68
|
+
if (pendingOnScroll.current === true)
|
|
69
|
+
onScrollStop();
|
|
70
|
+
}, [onScrollStop, pendingOnScroll]);
|
|
71
|
+
return import_react.default.useMemo(() => ({
|
|
72
|
+
onScrollStop,
|
|
73
|
+
onlyFocus,
|
|
74
|
+
scrollAndFocus,
|
|
75
|
+
checkPendingOnScroll
|
|
76
|
+
}), [onScrollStop, onlyFocus, scrollAndFocus, checkPendingOnScroll]);
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=useFocusAndScrollHelpers.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/parts/chat-container-messages-list/useFocusAndScrollHelpers.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable complexity */\n/* eslint-disable jsx-a11y/no-noninteractive-tabindex */\n/* eslint-disable max-lines */\nimport React from 'react';\nimport { useVirtual } from 'react-virtual';\nimport { debounce } from 'lodash';\nimport { DSChatT } from '../../react-desc-prop-types';\n\ntype UseFocusAndScrollHelpersArgs = {\n propsWithDefault: DSChatT.MessagesListProps;\n useVirtualHelpers: ReturnType<typeof useVirtual>;\n pendingOnScroll: React.MutableRefObject<boolean>;\n virtualListRef: React.MutableRefObject<HTMLDivElement | undefined>;\n};\n\nexport const useFocusAndScrollHelpers = ({\n propsWithDefault: { onScrollEnds },\n useVirtualHelpers: { scrollToIndex: vScroll },\n pendingOnScroll,\n virtualListRef,\n}: UseFocusAndScrollHelpersArgs) => {\n const onScrollStop = React.useMemo(\n () =>\n debounce((): string[] => {\n if (document.visibilityState === 'hidden') {\n pendingOnScroll.current = true;\n return [];\n }\n if (!virtualListRef.current) return [];\n pendingOnScroll.current = false;\n const { bottom, top } = virtualListRef.current?.getBoundingClientRect() || {};\n\n const list = virtualListRef.current.querySelectorAll<HTMLElement>('[data-element=\"chat-element-list-item\"]');\n const indexList: Array<string> = [];\n list.forEach((item: HTMLElement) => {\n const { top: itemTop } = item.getBoundingClientRect();\n\n const itemPadding = 10;\n if (itemTop + itemPadding < bottom && itemTop + itemPadding > top) indexList.push(item.dataset.index || '');\n });\n if (onScrollEnds) onScrollEnds(indexList);\n return indexList;\n }, 500),\n [onScrollEnds, pendingOnScroll, virtualListRef],\n );\n\n const onlyFocus = React.useCallback(\n (index?: number | string) => {\n (virtualListRef.current?.querySelector(`[data-index=\"${index || ''}\"]`) as HTMLDivElement)?.focus();\n },\n [virtualListRef],\n );\n\n const scrollAndFocus = React.useCallback(\n (index: number, opts = { align: 'center' } as DSChatT.ScrollToIndexOptions) => {\n vScroll(index, opts);\n setTimeout(() => {\n onlyFocus(index);\n }, 300);\n onScrollStop();\n },\n [onScrollStop, onlyFocus, vScroll],\n );\n\n const checkPendingOnScroll = React.useCallback(() => {\n if (pendingOnScroll.current === true) onScrollStop();\n }, [onScrollStop, pendingOnScroll]);\n\n return React.useMemo(\n () => ({\n onScrollStop,\n onlyFocus,\n scrollAndFocus,\n checkPendingOnScroll,\n }),\n [onScrollStop, onlyFocus, scrollAndFocus, checkPendingOnScroll],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADGvB,mBAAkB;AAElB,oBAAyB;AAUlB,MAAM,2BAA2B,CAAC;AAAA,EACvC,kBAAkB,EAAE;AAAA,EACpB,mBAAmB,EAAE,eAAe;AAAA,EACpC;AAAA,EACA;AAAA,MACkC;AAClC,QAAM,eAAe,qBAAM,QACzB,MACE,4BAAS,MAAgB;AACvB,QAAI,SAAS,oBAAoB,UAAU;AACzC,sBAAgB,UAAU;AAC1B,aAAO,CAAC;AAAA,IACV;AACA,QAAI,CAAC,eAAe;AAAS,aAAO,CAAC;AACrC,oBAAgB,UAAU;AAC1B,UAAM,EAAE,QAAQ,QAAQ,eAAe,SAAS,sBAAsB,KAAK,CAAC;AAE5E,UAAM,OAAO,eAAe,QAAQ,iBAA8B,yCAAyC;AAC3G,UAAM,YAA2B,CAAC;AAClC,SAAK,QAAQ,CAAC,SAAsB;AAClC,YAAM,EAAE,KAAK,YAAY,KAAK,sBAAsB;AAEpD,YAAM,cAAc;AACpB,UAAI,UAAU,cAAc,UAAU,UAAU,cAAc;AAAK,kBAAU,KAAK,KAAK,QAAQ,SAAS,EAAE;AAAA,IAC5G,CAAC;AACD,QAAI;AAAc,mBAAa,SAAS;AACxC,WAAO;AAAA,EACT,GAAG,GAAG,GACR,CAAC,cAAc,iBAAiB,cAAc,CAChD;AAEA,QAAM,YAAY,qBAAM,YACtB,CAAC,UAA4B;AAC3B,IAAC,eAAe,SAAS,cAAc,gBAAgB,SAAS,MAAM,GAAsB,MAAM;AAAA,EACpG,GACA,CAAC,cAAc,CACjB;AAEA,QAAM,iBAAiB,qBAAM,YAC3B,CAAC,OAAe,OAAO,EAAE,OAAO,SAAS,MAAsC;AAC7E,YAAQ,OAAO,IAAI;AACnB,eAAW,MAAM;AACf,gBAAU,KAAK;AAAA,IACjB,GAAG,GAAG;AACN,iBAAa;AAAA,EACf,GACA,CAAC,cAAc,WAAW,OAAO,CACnC;AAEA,QAAM,uBAAuB,qBAAM,YAAY,MAAM;AACnD,QAAI,gBAAgB,YAAY;AAAM,mBAAa;AAAA,EACrD,GAAG,CAAC,cAAc,eAAe,CAAC;AAElC,SAAO,qBAAM,QACX,MAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IACA,CAAC,cAAc,WAAW,gBAAgB,oBAAoB,CAChE;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/parts/chat-container-messages-list/useGetNewMessages.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["import { useMemo, useState } from 'react';\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkC;AAG3B,MAAM,oBAAoB,CAAC,
|
|
4
|
+
"sourcesContent": ["import { useMemo, useState } from 'react';\nimport { BubblePropsT } from '../../exported-related/bubble/props';\n\nexport const useGetNewMessages = (messages: BubblePropsT[]) => {\n const [seenMessages, setSeenMessages] = useState<Record<BubblePropsT['dsId'], true>>({});\n const newMessages = useMemo(() => {\n const list: BubblePropsT[] = [];\n messages.forEach((message) => {\n if (!(message.dsId in seenMessages)) {\n list.push(message);\n }\n });\n setSeenMessages(Object.fromEntries(messages.map((m) => [m.dsId, true])));\n return list;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages]);\n\n return newMessages;\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkC;AAG3B,MAAM,oBAAoB,CAAC,aAA6B;AAC7D,QAAM,CAAC,cAAc,mBAAmB,2BAA6C,CAAC,CAAC;AACvF,QAAM,cAAc,0BAAQ,MAAM;AAChC,UAAM,OAAuB,CAAC;AAC9B,aAAS,QAAQ,CAAC,YAAY;AAC5B,UAAI,CAAE,SAAQ,QAAQ,eAAe;AACnC,aAAK,KAAK,OAAO;AAAA,MACnB;AAAA,IACF,CAAC;AACD,oBAAgB,OAAO,YAAY,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;AACvE,WAAO;AAAA,EAET,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
var useGlobalEventListener_exports = {};
|
|
23
|
+
__export(useGlobalEventListener_exports, {
|
|
24
|
+
useGlobalEventListener: () => useGlobalEventListener
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(useGlobalEventListener_exports);
|
|
27
|
+
var React = __toESM(require("react"));
|
|
28
|
+
var import_react = __toESM(require("react"));
|
|
29
|
+
const useGlobalEventListener = ({
|
|
30
|
+
propsWithDefault: { onScrollEnds },
|
|
31
|
+
virtualListRef,
|
|
32
|
+
onScrollStop,
|
|
33
|
+
checkPendingOnScroll
|
|
34
|
+
}) => {
|
|
35
|
+
import_react.default.useEffect(() => {
|
|
36
|
+
let handlerCallback;
|
|
37
|
+
const localVirtualRef = virtualListRef.current;
|
|
38
|
+
const onScroll = () => {
|
|
39
|
+
if (handlerCallback)
|
|
40
|
+
clearTimeout(handlerCallback);
|
|
41
|
+
handlerCallback = setTimeout(onScrollStop, 300);
|
|
42
|
+
};
|
|
43
|
+
if (onScrollEnds) {
|
|
44
|
+
virtualListRef.current?.addEventListener("scroll", onScroll);
|
|
45
|
+
}
|
|
46
|
+
document.addEventListener("visibilitychange", checkPendingOnScroll);
|
|
47
|
+
return () => {
|
|
48
|
+
if (handlerCallback)
|
|
49
|
+
clearTimeout(handlerCallback);
|
|
50
|
+
if (onScrollEnds)
|
|
51
|
+
localVirtualRef.removeEventListener("scroll", onScroll);
|
|
52
|
+
document.removeEventListener("visibilitychange", checkPendingOnScroll);
|
|
53
|
+
};
|
|
54
|
+
}, [onScrollStop, onScrollEnds, checkPendingOnScroll, virtualListRef]);
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=useGlobalEventListener.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/parts/chat-container-messages-list/useGlobalEventListener.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import React from 'react';\nimport { type DebouncedFunc } from 'lodash';\nimport { type DSChatT } from '../../react-desc-prop-types';\n\ntype UseGlobalEventListenerArgs = {\n propsWithDefault: DSChatT.MessagesListProps;\n virtualListRef: React.MutableRefObject<HTMLDivElement | undefined>;\n onScrollStop: DebouncedFunc<() => string[]>;\n checkPendingOnScroll: GenericFunc;\n};\n\nexport const useGlobalEventListener = ({\n propsWithDefault: { onScrollEnds },\n virtualListRef,\n onScrollStop,\n checkPendingOnScroll,\n}: UseGlobalEventListenerArgs) => {\n React.useEffect(() => {\n let handlerCallback: ReturnType<typeof setTimeout>;\n const localVirtualRef = virtualListRef.current;\n const onScroll = () => {\n if (handlerCallback) clearTimeout(handlerCallback);\n handlerCallback = setTimeout(onScrollStop, 300);\n };\n if (onScrollEnds) {\n virtualListRef.current?.addEventListener('scroll', onScroll);\n }\n document.addEventListener('visibilitychange', checkPendingOnScroll);\n return () => {\n if (handlerCallback) clearTimeout(handlerCallback);\n if (onScrollEnds) localVirtualRef.removeEventListener('scroll', onScroll);\n document.removeEventListener('visibilitychange', checkPendingOnScroll);\n };\n }, [onScrollStop, onScrollEnds, checkPendingOnScroll, virtualListRef]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkB;AAWX,MAAM,yBAAyB,CAAC;AAAA,EACrC,kBAAkB,EAAE;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,MACgC;AAChC,uBAAM,UAAU,MAAM;AACpB,QAAI;AACJ,UAAM,kBAAkB,eAAe;AACvC,UAAM,WAAW,MAAM;AACrB,UAAI;AAAiB,qBAAa,eAAe;AACjD,wBAAkB,WAAW,cAAc,GAAG;AAAA,IAChD;AACA,QAAI,cAAc;AAChB,qBAAe,SAAS,iBAAiB,UAAU,QAAQ;AAAA,IAC7D;AACA,aAAS,iBAAiB,oBAAoB,oBAAoB;AAClE,WAAO,MAAM;AACX,UAAI;AAAiB,qBAAa,eAAe;AACjD,UAAI;AAAc,wBAAgB,oBAAoB,UAAU,QAAQ;AACxE,eAAS,oBAAoB,oBAAoB,oBAAoB;AAAA,IACvE;AAAA,EACF,GAAG,CAAC,cAAc,cAAc,sBAAsB,cAAc,CAAC;AACvE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
var useKeyboard_exports = {};
|
|
23
|
+
__export(useKeyboard_exports, {
|
|
24
|
+
useKeyboard: () => useKeyboard
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(useKeyboard_exports);
|
|
27
|
+
var React = __toESM(require("react"));
|
|
28
|
+
var import_react = __toESM(require("react"));
|
|
29
|
+
const useKeyboard = ({
|
|
30
|
+
propsWithDefault: { hasMoreItems, messages, bannerPosition, bannerRef },
|
|
31
|
+
actionRef,
|
|
32
|
+
virtualListRef,
|
|
33
|
+
loadMoreRef,
|
|
34
|
+
scrollAndFocus,
|
|
35
|
+
onlyFocus,
|
|
36
|
+
onScrollStop
|
|
37
|
+
}) => {
|
|
38
|
+
const handleKey = import_react.default.useCallback((e) => {
|
|
39
|
+
const { key, currentTarget } = e;
|
|
40
|
+
const index = currentTarget.dataset?.index ? Number(currentTarget.dataset.index) : void 0;
|
|
41
|
+
e.stopPropagation();
|
|
42
|
+
switch (key) {
|
|
43
|
+
case "ArrowUp":
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
if (index && index > 0) {
|
|
46
|
+
(virtualListRef.current?.querySelector(`[data-index="${index - 1}"]`)).focus();
|
|
47
|
+
} else if (hasMoreItems === "top") {
|
|
48
|
+
loadMoreRef.current?.focus();
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
case "ArrowDown":
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
if (messages?.length && index && index < messages.length - 1) {
|
|
54
|
+
(virtualListRef.current?.querySelector(`[data-index="${index + 1}"]`)).focus();
|
|
55
|
+
}
|
|
56
|
+
break;
|
|
57
|
+
case "Home":
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
scrollAndFocus(0);
|
|
60
|
+
break;
|
|
61
|
+
case "End":
|
|
62
|
+
e.preventDefault();
|
|
63
|
+
if (messages?.length)
|
|
64
|
+
scrollAndFocus(messages.length - 1);
|
|
65
|
+
break;
|
|
66
|
+
case "Tab":
|
|
67
|
+
if (hasMoreItems === "bottom" && !e.shiftKey) {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
loadMoreRef.current?.focus();
|
|
70
|
+
} else if (hasMoreItems === "top" && e.shiftKey) {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
loadMoreRef.current?.focus();
|
|
73
|
+
} else if (!e.shiftKey) {
|
|
74
|
+
if (bannerPosition) {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
bannerRef?.current?.focusOnWrapper();
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
virtualListRef.current?.focus();
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}, [hasMoreItems, messages.length, scrollAndFocus, virtualListRef, loadMoreRef, bannerPosition, bannerRef]);
|
|
87
|
+
const handleListKey = import_react.default.useCallback((e) => {
|
|
88
|
+
const { key } = e;
|
|
89
|
+
switch (key) {
|
|
90
|
+
case "ArrowUp":
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
if (document.activeElement !== loadMoreRef.current) {
|
|
93
|
+
onlyFocus(onScrollStop()?.shift());
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
case "ArrowDown":
|
|
97
|
+
e.preventDefault();
|
|
98
|
+
if (document.activeElement === loadMoreRef.current) {
|
|
99
|
+
virtualListRef.current?.querySelector(`[data-index="0"]`)?.focus();
|
|
100
|
+
} else {
|
|
101
|
+
onlyFocus(onScrollStop()?.pop());
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
case "Home":
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
scrollAndFocus(0);
|
|
107
|
+
break;
|
|
108
|
+
case "End":
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
if (messages?.length)
|
|
111
|
+
scrollAndFocus(messages.length - 1);
|
|
112
|
+
break;
|
|
113
|
+
case "Tab":
|
|
114
|
+
if (document.activeElement !== loadMoreRef.current) {
|
|
115
|
+
if (hasMoreItems === "bottom" && !e.shiftKey) {
|
|
116
|
+
e.preventDefault();
|
|
117
|
+
loadMoreRef.current?.focus();
|
|
118
|
+
} else if (!e.shiftKey) {
|
|
119
|
+
e.preventDefault();
|
|
120
|
+
actionRef.current?.focusToComposer?.();
|
|
121
|
+
}
|
|
122
|
+
} else if (!e.shiftKey) {
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
actionRef.current?.focusToComposer?.();
|
|
125
|
+
} else {
|
|
126
|
+
e.preventDefault();
|
|
127
|
+
virtualListRef.current?.focus();
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
default:
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}, [actionRef, hasMoreItems, loadMoreRef, messages.length, onScrollStop, onlyFocus, scrollAndFocus, virtualListRef]);
|
|
134
|
+
return import_react.default.useMemo(() => ({ handleKey, handleListKey }), [handleKey, handleListKey]);
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=useKeyboard.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/parts/chat-container-messages-list/useKeyboard.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable complexity */\n/* eslint-disable jsx-a11y/no-noninteractive-tabindex */\n/* eslint-disable max-lines */\nimport React from 'react';\nimport { type DebouncedFunc } from 'lodash';\nimport { DSChatT } from '../../react-desc-prop-types';\n\ntype UseKeyboardArgs = {\n propsWithDefault: DSChatT.MessagesListProps;\n actionRef: DSChatT.ActionRef;\n virtualListRef: React.MutableRefObject<HTMLDivElement | undefined>;\n loadMoreRef: React.MutableRefObject<HTMLButtonElement | undefined>;\n scrollAndFocus: (index: number, opts?: DSChatT.ScrollToIndexOptions) => void;\n onlyFocus: (index?: number | string) => void;\n onScrollStop: DebouncedFunc<() => string[]>;\n // useVirtualHelpers: ReturnType<typeof useVirtual>;\n};\n\nexport const useKeyboard = ({\n propsWithDefault: { hasMoreItems, messages, bannerPosition, bannerRef },\n actionRef,\n virtualListRef,\n loadMoreRef,\n scrollAndFocus,\n onlyFocus,\n onScrollStop,\n}: UseKeyboardArgs) => {\n const handleKey = React.useCallback(\n (e: React.KeyboardEvent<HTMLElement>) => {\n const { key, currentTarget } = e;\n const index = currentTarget.dataset?.index ? Number(currentTarget.dataset.index) : undefined;\n e.stopPropagation();\n switch (key) {\n case 'ArrowUp':\n e.preventDefault();\n if (index && index > 0) {\n (virtualListRef.current?.querySelector(`[data-index=\"${index - 1}\"]`) as HTMLDivElement).focus();\n } else if (hasMoreItems === 'top') {\n loadMoreRef.current?.focus();\n }\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (messages?.length && index && index < messages.length - 1) {\n (virtualListRef.current?.querySelector(`[data-index=\"${index + 1}\"]`) as HTMLDivElement).focus();\n }\n break;\n case 'Home':\n e.preventDefault();\n scrollAndFocus(0);\n break;\n case 'End':\n e.preventDefault();\n if (messages?.length) scrollAndFocus(messages.length - 1);\n break;\n case 'Tab':\n if (hasMoreItems === 'bottom' && !e.shiftKey) {\n e.preventDefault();\n loadMoreRef.current?.focus();\n } else if (hasMoreItems === 'top' && e.shiftKey) {\n e.preventDefault();\n loadMoreRef.current?.focus();\n } else if (!e.shiftKey) {\n if (bannerPosition) {\n e.preventDefault();\n bannerRef?.current?.focusOnWrapper();\n }\n } else {\n e.preventDefault();\n virtualListRef.current?.focus();\n }\n break;\n default:\n break;\n }\n },\n [hasMoreItems, messages.length, scrollAndFocus, virtualListRef, loadMoreRef, bannerPosition, bannerRef],\n );\n const handleListKey = React.useCallback(\n (e: React.KeyboardEvent) => {\n const { key } = e;\n switch (key) {\n case 'ArrowUp':\n e.preventDefault();\n if (document.activeElement !== loadMoreRef.current) {\n onlyFocus(onScrollStop()?.shift());\n }\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (document.activeElement === loadMoreRef.current) {\n (virtualListRef.current?.querySelector(`[data-index=\"0\"]`) as HTMLDivElement)?.focus();\n } else {\n onlyFocus(onScrollStop()?.pop());\n }\n break;\n case 'Home':\n e.preventDefault();\n scrollAndFocus(0);\n break;\n case 'End':\n e.preventDefault();\n if (messages?.length) scrollAndFocus(messages.length - 1);\n break;\n case 'Tab':\n if (document.activeElement !== loadMoreRef.current) {\n if (hasMoreItems === 'bottom' && !e.shiftKey) {\n e.preventDefault();\n loadMoreRef.current?.focus();\n } else if (!e.shiftKey) {\n e.preventDefault();\n actionRef.current?.focusToComposer?.();\n }\n } else if (!e.shiftKey) {\n e.preventDefault();\n actionRef.current?.focusToComposer?.();\n } else {\n e.preventDefault();\n virtualListRef.current?.focus();\n }\n break;\n default:\n break;\n }\n },\n [actionRef, hasMoreItems, loadMoreRef, messages.length, onScrollStop, onlyFocus, scrollAndFocus, virtualListRef],\n );\n\n return React.useMemo(() => ({ handleKey, handleListKey }), [handleKey, handleListKey]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -30,19 +30,20 @@ __export(react_desc_prop_types_exports, {
|
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(react_desc_prop_types_exports);
|
|
32
32
|
var React = __toESM(require("react"));
|
|
33
|
-
var import_lodash = require("lodash");
|
|
34
33
|
var import_ds_utilities = require("@elliemae/ds-utilities");
|
|
35
34
|
var import_ds_banner = require("@elliemae/ds-banner");
|
|
35
|
+
function noop(..._args) {
|
|
36
|
+
}
|
|
36
37
|
const defaultPropsComposer = {
|
|
37
38
|
placeholder: "Type your message",
|
|
38
39
|
inputValue: "",
|
|
39
40
|
ariaMaxLengthMessage: "",
|
|
40
|
-
onChange:
|
|
41
|
-
onResize:
|
|
42
|
-
onSend:
|
|
43
|
-
onFocus:
|
|
44
|
-
onBlur:
|
|
45
|
-
onKeyDown:
|
|
41
|
+
onChange: noop,
|
|
42
|
+
onResize: noop,
|
|
43
|
+
onSend: noop,
|
|
44
|
+
onFocus: noop,
|
|
45
|
+
onBlur: noop,
|
|
46
|
+
onKeyDown: noop,
|
|
46
47
|
maxHeight: 0,
|
|
47
48
|
inputMaxLength: void 0,
|
|
48
49
|
maxLengthMessage: void 0,
|
|
@@ -67,21 +68,20 @@ const ChatComposerPropTypes = {
|
|
|
67
68
|
dataTestid: import_ds_utilities.PropTypes.string.description("Data testid").defaultValue(defaultPropsComposer.placeholder),
|
|
68
69
|
actionRef: import_ds_utilities.PropTypes.object.description(`Reference:
|
|
69
70
|
{
|
|
70
|
-
scrollToIndex
|
|
71
|
-
getMessagesInView
|
|
72
|
-
focusToIndex
|
|
73
|
-
focusToList
|
|
74
|
-
focusToComposer
|
|
75
|
-
focusToSend
|
|
71
|
+
scrollToIndex?: (n: number, opts: { align: 'end' | 'center' | 'start' }) => void,
|
|
72
|
+
getMessagesInView?: () => number[],
|
|
73
|
+
focusToIndex?: (n: number) => void,
|
|
74
|
+
focusToList?: () => void,
|
|
75
|
+
focusToComposer?: () => void,
|
|
76
|
+
focusToSend?: () => void,
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
`).defaultValue(defaultPropsComposer.actionRef)
|
|
79
80
|
};
|
|
80
81
|
const defaultPropsMessagesList = {
|
|
81
82
|
messages: [],
|
|
82
|
-
actionRef:
|
|
83
|
-
|
|
84
|
-
getMoreMessages: import_lodash.noop,
|
|
83
|
+
actionRef: { current: {} },
|
|
84
|
+
getMoreMessages: noop,
|
|
85
85
|
sendingMessages: void 0,
|
|
86
86
|
sendingText: "Sending",
|
|
87
87
|
bannerPosition: void 0,
|
|
@@ -92,7 +92,7 @@ const ChatContainerMessagesListPropTypes = {
|
|
|
92
92
|
messages: import_ds_utilities.PropTypes.arrayOf(import_ds_utilities.PropTypes.object).description("The array of out-of-the-box items you want to render inside the ChatMessageList").defaultValue(defaultPropsMessagesList.messages),
|
|
93
93
|
actionRef: import_ds_utilities.PropTypes.object.description(`Reference:
|
|
94
94
|
{
|
|
95
|
-
scrollToIndex
|
|
95
|
+
scrollToIndex?: (n: number, opts: { align: 'end' | 'center' | 'start' }) => void,
|
|
96
96
|
getMessagesInView: () => number[],
|
|
97
97
|
focusToIndex: (n: number) => void,
|
|
98
98
|
focusToIndexWithoutScroll: (n: number) => void,
|
|
@@ -117,14 +117,14 @@ const defaultProps = {
|
|
|
117
117
|
device: "desktop",
|
|
118
118
|
isLoading: void 0,
|
|
119
119
|
hasMoreItems: void 0,
|
|
120
|
-
getMoreMessages:
|
|
120
|
+
getMoreMessages: noop,
|
|
121
121
|
bannerPosition: void 0,
|
|
122
122
|
bannerProps: {
|
|
123
123
|
type: import_ds_banner.BANNER_TYPES.INFO,
|
|
124
124
|
label: "Unread Messages",
|
|
125
125
|
viewLabel: "View",
|
|
126
|
-
onView:
|
|
127
|
-
onClose:
|
|
126
|
+
onView: noop,
|
|
127
|
+
onClose: noop
|
|
128
128
|
},
|
|
129
129
|
sendingMessages: void 0,
|
|
130
130
|
sendingText: "Sending"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/react-desc-prop-types.tsx", "../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable max-lines */\nimport { noop } from 'lodash';\nimport { PropTypes, globalAttributesPropTypes } from '@elliemae/ds-utilities';\nimport { BANNER_TYPES } from '@elliemae/ds-banner';\nimport { BubblePropsT } from './exported-related/bubble/props';\n\nexport declare namespace DSChatT {\n export interface ContainerProps {\n messagesListProps: Pick<MessagesListProps, 'messages' | 'onScrollEnds'>;\n composerProps: ComposerProps;\n actionRef?: ActionRef;\n autoScroll: boolean;\n device: 'desktop' | 'mobile';\n isLoading?: 'top' | 'bottom';\n hasMoreItems?: 'top' | 'bottom';\n getMoreMessages: () => void;\n bannerPosition?: 'top' | 'bottom';\n bannerProps?: ChatBannerProps;\n sendingMessages?: string[] | number[];\n sendingText: string;\n }\n\n export interface ComposerProps {\n placeholder?: string;\n inputValue?: string;\n ariaMaxLengthMessage?: string;\n maxLengthMessage?: string;\n onChange: (value: string) => void;\n onResize?: (value: number) => void;\n onSend: (value: string) => void;\n onFocus?: (e: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;\n onBlur?: (e: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;\n onKeyDown?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n maxHeight?: number;\n inputMaxLength: number | undefined;\n buttonDisabled: boolean;\n dataTestid?: string;\n actionRef?: ActionRef;\n }\n\n export interface MessagesListProps {\n messages: BubblePropsT[];\n actionRef: () => void;\n onScrollEnds: (indexList: number[]) => number[];\n isLoading?: 'top' | 'bottom';\n hasMoreItems?: 'top' | 'bottom';\n getMoreMessages: () => void;\n sendingMessages?: Array<string | number>;\n sendingText: string;\n bannerPosition?: 'top' | 'bottom';\n bannerRef?: React.MutableRefObject<{\n focusOnWrapper: (...args: any[]) => void;\n focusOnLink: (...args: any[]) => void;\n }>;\n }\n\n interface ChatBannerProps {\n label: string;\n viewLabel: string;\n type?: string;\n onView: () => void;\n onClose: () => void;\n }\n\n interface ActionRef {\n scrollToIndex: (n: number, b: { align: 'end' | 'center' | 'start' }) => void;\n getMessagesInView: () => number[];\n }\n\n export interface GetPaddingT {\n hasMoreItems: string | undefined;\n bannerPosition: string | undefined;\n isLoading: string | undefined;\n }\n}\n\nexport interface TextAreaProps {\n height: string | number;\n style: React.CSSProperties;\n}\n\nexport const defaultPropsComposer: DSChatT.ComposerProps = {\n placeholder: 'Type your message',\n inputValue: '',\n ariaMaxLengthMessage: '',\n onChange: noop,\n onResize: noop,\n onSend: noop,\n onFocus: noop,\n onBlur: noop,\n onKeyDown: noop,\n maxHeight: 0,\n inputMaxLength: undefined,\n maxLengthMessage: undefined,\n buttonDisabled: false,\n dataTestid: 'ds-chat-composer',\n actionRef: undefined,\n};\n\nexport const ChatComposerPropTypes = {\n placeholder: PropTypes.string.description('Input Placeholder').defaultValue(defaultPropsComposer.placeholder),\n inputValue: PropTypes.string.description('Input value').defaultValue(defaultPropsComposer.inputValue),\n ariaMaxLengthMessage: PropTypes.string\n .description('Aria message for Max length message when exceeded')\n .defaultValue(defaultPropsComposer.maxLengthMessage),\n maxLengthMessage: PropTypes.string\n .description('Max length message')\n .defaultValue(defaultPropsComposer.maxLengthMessage),\n onChange: PropTypes.func.description('Called when the user types').defaultValue(defaultPropsComposer.onChange),\n onResize: PropTypes.func\n .description('Called the input changes his height')\n .defaultValue(defaultPropsComposer.onResize),\n onSend: PropTypes.func.description('Called when the click send').defaultValue(defaultPropsComposer.onSend),\n onFocus: PropTypes.func.description('Input focus').defaultValue(defaultPropsComposer.onFocus),\n onBlur: PropTypes.func.description('Input blur').defaultValue(defaultPropsComposer.onBlur),\n onKeyDown: PropTypes.func.description('Input on key down').defaultValue(defaultPropsComposer.onKeyDown),\n maxHeight: PropTypes.number\n .description('Max height of the composer. Use 0 for no limit')\n .defaultValue(defaultPropsComposer.onBlur),\n inputMaxLength: PropTypes.number\n .description('Max length of the composer. `undefined` for no limit')\n .defaultValue(defaultPropsComposer.inputMaxLength),\n buttonDisabled: PropTypes.bool\n .description('Control the disabled for the send button')\n .defaultValue(defaultPropsComposer.buttonDisabled),\n dataTestid: PropTypes.string.description('Data testid').defaultValue(defaultPropsComposer.placeholder),\n actionRef: PropTypes.object\n .description(\n `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 `,\n )\n .defaultValue(defaultPropsComposer.actionRef),\n};\n\nexport const defaultPropsMessagesList: DSChatT.MessagesListProps = {\n messages: [],\n actionRef: noop,\n onScrollEnds: () => [],\n getMoreMessages: noop,\n sendingMessages: undefined,\n sendingText: 'Sending',\n bannerPosition: undefined,\n bannerRef: undefined,\n};\n\nexport const ChatContainerMessagesListPropTypes = {\n ...globalAttributesPropTypes,\n\n messages: PropTypes.arrayOf(PropTypes.object)\n .description('The array of out-of-the-box items you want to render inside the ChatMessageList')\n .defaultValue(defaultPropsMessagesList.messages),\n actionRef: PropTypes.object\n .description(\n `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 `,\n )\n .defaultValue(defaultPropsMessagesList.actionRef),\n onScrollEnds: PropTypes.func.description(`Called when the scroll stops.`),\n isLoading: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Keeps the load more space while the loading is in progress',\n ),\n hasMoreItems: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show Load More button at the `top` or `bottom` of the container',\n ),\n getMoreMessages: PropTypes.func\n .description('Called when the user clicks on load more')\n .defaultValue(defaultPropsMessagesList.getMoreMessages),\n sendingMessages: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.arrayOf(PropTypes.number)])\n .description('Array of ids of sending messages')\n .defaultValue(defaultPropsMessagesList.sendingMessages),\n sendingText: PropTypes.string\n .description('Label description for messages in sending status')\n .defaultValue(defaultPropsMessagesList.sendingText),\n};\n\nexport const defaultProps: DSChatT.ContainerProps = {\n messagesListProps: defaultPropsMessagesList,\n composerProps: defaultPropsComposer,\n actionRef: undefined,\n autoScroll: false,\n device: 'desktop',\n isLoading: undefined,\n hasMoreItems: undefined,\n getMoreMessages: noop,\n bannerPosition: undefined,\n bannerProps: {\n type: BANNER_TYPES.INFO,\n label: 'Unread Messages',\n viewLabel: 'View',\n onView: noop,\n onClose: noop,\n },\n sendingMessages: undefined,\n sendingText: 'Sending',\n};\n\nexport const ChatContainerPropTypes = {\n ...globalAttributesPropTypes,\n messagesListProps: PropTypes.object\n .description('ChatMessageList props \"messages\" / \"onScrollEnds\"')\n .defaultValue(defaultProps.messagesListProps),\n composerProps: PropTypes.object.description('Composer configuration').defaultValue(defaultProps.composerProps),\n autoScroll: PropTypes.bool.description('Auto scroll to bottom on resize').defaultValue(defaultProps.autoScroll),\n device: PropTypes.string\n .description('Option to render mobile or desktop style composer')\n .defaultValue(defaultProps.device),\n isLoading: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show Loading messages indicator at the `top` or `bottom` of the container',\n ),\n hasMoreItems: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show Load More button at the `top` or `bottom` of the container',\n ),\n getMoreMessages: PropTypes.func\n .description('Called when the user clicks on load more')\n .defaultValue(defaultProps.getMoreMessages),\n bannerPosition: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show Loading messages indicator at the `top` or `bottom` of the container',\n ),\n bannerProps: PropTypes.object\n .description(\n `Banner configuration:\n label: string;\n viewLabel: string;\n type: BANNER_TYPES;\n onView: () => void;\n onClose: () => void;\n `,\n )\n .defaultValue(defaultProps.bannerProps),\n sendingMessages: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.arrayOf(PropTypes.number)])\n .description('Array of ids of sending messages')\n .defaultValue(defaultProps.sendingMessages),\n sendingText: PropTypes.string\n .description('Label description for messages in sending status')\n .defaultValue(defaultProps.sendingText),\n actionRef: PropTypes.object\n .description(\n `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 `,\n )\n .defaultValue(defaultProps.actionRef),\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable max-lines */\nimport { type DebouncedFunc } from 'lodash';\nimport { useVirtual } from 'react-virtual';\nimport { PropTypes, globalAttributesPropTypes } from '@elliemae/ds-utilities';\nimport { BANNER_TYPES } from '@elliemae/ds-banner';\nimport { BubblePropsT } from './exported-related/bubble/props';\n\n// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars\nfunction noop<T extends unknown[]>(..._args: T): void {}\nexport declare namespace DSChatT {\n interface ChatBannerProps {\n label: string;\n viewLabel: string;\n type?: string;\n onView: () => void;\n onClose: () => void;\n }\n export type ScrollToIndexOptions = Parameters<ReturnType<typeof useVirtual>['scrollToIndex']>[1];\n export type ActionRef = React.MutableRefObject<{\n scrollToIndex?: (index: number, opts: ScrollToIndexOptions) => void;\n focusToIndex?: (index: number, opts: ScrollToIndexOptions) => void;\n getMessagesInView?: DebouncedFunc<() => string[]>;\n focusToIndexWithoutScroll?: (index?: number) => void;\n focusToList?: () => void;\n focusToComposer?: () => void;\n focusToSend?: () => void;\n }>;\n\n export interface ContainerProps {\n messagesListProps: Pick<MessagesListProps, 'messages' | 'onScrollEnds'>;\n composerProps: ComposerProps;\n actionRef?: ActionRef;\n autoScroll: boolean;\n device: 'desktop' | 'mobile';\n isLoading?: 'top' | 'bottom';\n hasMoreItems?: 'top' | 'bottom';\n getMoreMessages: () => void;\n bannerPosition?: 'top' | 'bottom';\n bannerProps?: ChatBannerProps;\n sendingMessages?: string[] | number[];\n sendingText: string;\n }\n\n export interface ComposerProps {\n placeholder?: string;\n inputValue?: string;\n ariaMaxLengthMessage?: string;\n maxLengthMessage?: string;\n onChange: (value: string) => void;\n onResize?: (value: number) => void;\n onSend: (value: string) => void;\n onFocus?: (e: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;\n onBlur?: (e: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;\n onKeyDown?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n maxHeight?: number;\n inputMaxLength: number | undefined;\n buttonDisabled: boolean;\n dataTestid?: string;\n actionRef?: ActionRef;\n }\n\n export interface MessagesListProps {\n messages: BubblePropsT[];\n actionRef: ActionRef;\n onScrollEnds?: (indexList: string[]) => void;\n isLoading?: 'top' | 'bottom';\n hasMoreItems?: 'top' | 'bottom';\n getMoreMessages: () => void;\n sendingMessages?: Array<string | number>;\n sendingText: string;\n bannerPosition?: 'top' | 'bottom';\n bannerRef?: React.MutableRefObject<{\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n focusOnWrapper: (...args: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n focusOnLink: (...args: any[]) => void;\n }>;\n }\n\n export interface GetPaddingT {\n hasMoreItems: string | undefined;\n bannerPosition: string | undefined;\n isLoading: string | undefined;\n }\n}\n\nexport interface TextAreaProps {\n height: string | number;\n style: React.CSSProperties;\n}\n\nexport const defaultPropsComposer: DSChatT.ComposerProps = {\n placeholder: 'Type your message',\n inputValue: '',\n ariaMaxLengthMessage: '',\n onChange: noop,\n onResize: noop,\n onSend: noop,\n onFocus: noop,\n onBlur: noop,\n onKeyDown: noop,\n maxHeight: 0,\n inputMaxLength: undefined,\n maxLengthMessage: undefined,\n buttonDisabled: false,\n dataTestid: 'ds-chat-composer',\n actionRef: undefined,\n};\n\nexport const ChatComposerPropTypes = {\n placeholder: PropTypes.string.description('Input Placeholder').defaultValue(defaultPropsComposer.placeholder),\n inputValue: PropTypes.string.description('Input value').defaultValue(defaultPropsComposer.inputValue),\n ariaMaxLengthMessage: PropTypes.string\n .description('Aria message for Max length message when exceeded')\n .defaultValue(defaultPropsComposer.maxLengthMessage),\n maxLengthMessage: PropTypes.string\n .description('Max length message')\n .defaultValue(defaultPropsComposer.maxLengthMessage),\n onChange: PropTypes.func.description('Called when the user types').defaultValue(defaultPropsComposer.onChange),\n onResize: PropTypes.func\n .description('Called the input changes his height')\n .defaultValue(defaultPropsComposer.onResize),\n onSend: PropTypes.func.description('Called when the click send').defaultValue(defaultPropsComposer.onSend),\n onFocus: PropTypes.func.description('Input focus').defaultValue(defaultPropsComposer.onFocus),\n onBlur: PropTypes.func.description('Input blur').defaultValue(defaultPropsComposer.onBlur),\n onKeyDown: PropTypes.func.description('Input on key down').defaultValue(defaultPropsComposer.onKeyDown),\n maxHeight: PropTypes.number\n .description('Max height of the composer. Use 0 for no limit')\n .defaultValue(defaultPropsComposer.onBlur),\n inputMaxLength: PropTypes.number\n .description('Max length of the composer. `undefined` for no limit')\n .defaultValue(defaultPropsComposer.inputMaxLength),\n buttonDisabled: PropTypes.bool\n .description('Control the disabled for the send button')\n .defaultValue(defaultPropsComposer.buttonDisabled),\n dataTestid: PropTypes.string.description('Data testid').defaultValue(defaultPropsComposer.placeholder),\n actionRef: PropTypes.object\n .description(\n `Reference: \n { \n scrollToIndex?: (n: number, opts: { align: 'end' | 'center' | 'start' }) => void,\n getMessagesInView?: () => number[],\n focusToIndex?: (n: number) => void,\n focusToList?: () => void,\n focusToComposer?: () => void,\n focusToSend?: () => void,\n }\n \n `,\n )\n .defaultValue(defaultPropsComposer.actionRef),\n};\n\nexport const defaultPropsMessagesList: DSChatT.MessagesListProps = {\n messages: [],\n actionRef: { current: {} },\n // we don't want this to exist \"by default\" since this loads document.addEventListener\n // the code is already checking for this callback existence everytime it's invoked anyway\n // onScrollEnds: () => [],\n getMoreMessages: noop,\n sendingMessages: undefined,\n sendingText: 'Sending',\n bannerPosition: undefined,\n bannerRef: undefined,\n};\n\nexport const ChatContainerMessagesListPropTypes = {\n ...globalAttributesPropTypes,\n\n messages: PropTypes.arrayOf(PropTypes.object)\n .description('The array of out-of-the-box items you want to render inside the ChatMessageList')\n .defaultValue(defaultPropsMessagesList.messages),\n actionRef: PropTypes.object\n .description(\n `Reference: \n { \n scrollToIndex?: (n: number, opts: { align: 'end' | 'center' | 'start' }) => 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 `,\n )\n .defaultValue(defaultPropsMessagesList.actionRef),\n onScrollEnds: PropTypes.func.description(`Called when the scroll stops.`),\n isLoading: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Keeps the load more space while the loading is in progress',\n ),\n hasMoreItems: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show Load More button at the `top` or `bottom` of the container',\n ),\n getMoreMessages: PropTypes.func\n .description('Called when the user clicks on load more')\n .defaultValue(defaultPropsMessagesList.getMoreMessages),\n sendingMessages: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.arrayOf(PropTypes.number)])\n .description('Array of ids of sending messages')\n .defaultValue(defaultPropsMessagesList.sendingMessages),\n sendingText: PropTypes.string\n .description('Label description for messages in sending status')\n .defaultValue(defaultPropsMessagesList.sendingText),\n};\n\nexport const defaultProps: DSChatT.ContainerProps = {\n messagesListProps: defaultPropsMessagesList,\n composerProps: defaultPropsComposer,\n actionRef: undefined,\n autoScroll: false,\n device: 'desktop',\n isLoading: undefined,\n hasMoreItems: undefined,\n getMoreMessages: noop,\n bannerPosition: undefined,\n bannerProps: {\n type: BANNER_TYPES.INFO,\n label: 'Unread Messages',\n viewLabel: 'View',\n onView: noop,\n onClose: noop,\n },\n sendingMessages: undefined,\n sendingText: 'Sending',\n};\n\nexport const ChatContainerPropTypes = {\n ...globalAttributesPropTypes,\n messagesListProps: PropTypes.object\n .description('ChatMessageList props \"messages\" / \"onScrollEnds\"')\n .defaultValue(defaultProps.messagesListProps),\n composerProps: PropTypes.object.description('Composer configuration').defaultValue(defaultProps.composerProps),\n autoScroll: PropTypes.bool.description('Auto scroll to bottom on resize').defaultValue(defaultProps.autoScroll),\n device: PropTypes.string\n .description('Option to render mobile or desktop style composer')\n .defaultValue(defaultProps.device),\n isLoading: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show Loading messages indicator at the `top` or `bottom` of the container',\n ),\n hasMoreItems: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show Load More button at the `top` or `bottom` of the container',\n ),\n getMoreMessages: PropTypes.func\n .description('Called when the user clicks on load more')\n .defaultValue(defaultProps.getMoreMessages),\n bannerPosition: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show Loading messages indicator at the `top` or `bottom` of the container',\n ),\n bannerProps: PropTypes.object\n .description(\n `Banner configuration:\n label: string;\n viewLabel: string;\n type: BANNER_TYPES;\n onView: () => void;\n onClose: () => void;\n `,\n )\n .defaultValue(defaultProps.bannerProps),\n sendingMessages: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.arrayOf(PropTypes.number)])\n .description('Array of ids of sending messages')\n .defaultValue(defaultProps.sendingMessages),\n sendingText: PropTypes.string\n .description('Label description for messages in sending status')\n .defaultValue(defaultProps.sendingText),\n actionRef: PropTypes.object\n .description(\n `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 `,\n )\n .defaultValue(defaultProps.actionRef),\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Personal preferences/opinions:
|
|
2
|
+
|
|
3
|
+
## `packages/ds-chat/src/ChatDataTestids.tsx`
|
|
4
|
+
|
|
5
|
+
maybe this could have been a better way to handle the test-id hierarchy?
|
|
6
|
+
I personally prefeer this way, but it's just personal preference
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
export const ChatDataTestIds = {
|
|
10
|
+
COMPOSER: {
|
|
11
|
+
TEXTAREA: 'chat-composer-textarea',
|
|
12
|
+
SEND_BUTTON: 'chat-composer-send-button',
|
|
13
|
+
},
|
|
14
|
+
CARD: {
|
|
15
|
+
TITLE: 'chat-card-title',
|
|
16
|
+
WRAPPER: 'chat-card-wrapper',
|
|
17
|
+
TIME: 'chat-card-time',
|
|
18
|
+
RIGHT_ADDON: 'chat-right-addon',
|
|
19
|
+
CONTENT: 'chat-card-content',
|
|
20
|
+
},
|
|
21
|
+
LOADING_INDICATOR: 'ds-chat-loading-indicator',
|
|
22
|
+
HEADER: {
|
|
23
|
+
TITLE: 'chat-header-title',
|
|
24
|
+
CHILDREN: 'chat-header-children',
|
|
25
|
+
},
|
|
26
|
+
THREAD_CONTAINER: 'chat-thread-container',
|
|
27
|
+
LOAD_MORE_BUTTON: 'ds-chat-load-more-btn',
|
|
28
|
+
FLOATING_BUTTON: 'chat-floating-button',
|
|
29
|
+
SYSTEM_MSG: {
|
|
30
|
+
TITLE: 'chat-system-message-title',
|
|
31
|
+
BODY: 'chat-system-message-body',
|
|
32
|
+
TIME: 'chat-system-message-time',
|
|
33
|
+
},
|
|
34
|
+
BUBBLE: {
|
|
35
|
+
ROOT: 'ds-chat-bubble',
|
|
36
|
+
TITLE: 'chat-bubble-title',
|
|
37
|
+
BODY: 'chat-bubble-body',
|
|
38
|
+
},
|
|
39
|
+
BANNER: 'ds-banner-container',
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
# Scaffolding and Semantinc naming
|
|
44
|
+
|
|
45
|
+
## Generic
|
|
46
|
+
|
|
47
|
+
the way this component it's structured we don't have a clear "top-to-down" flow, it's hard to even identify the "entry point"
|
|
48
|
+
|
|
49
|
+
this is due to the fact that this was created with extreme composition in mind, but if we need to follow extreme composition
|
|
50
|
+
|
|
51
|
+
we should create different packages with each part having it's own "clear top-to-down flow and entry point" instread of squeezing everything here
|
|
52
|
+
|
|
53
|
+
we could re-arrange this `@elliemea/ds-chat` to become an "aggregator" package, re-exporting the differente pieces as per `@elliemae/ds-controlled-form`
|
|
54
|
+
|
|
55
|
+
and we could create separate atomic `@elliemae/ds-chat-${composer/container/bubble/card/sidebar...}` packages...
|
|
56
|
+
|
|
57
|
+
## `packages/ds-chat/src/styled.tsx`
|
|
58
|
+
|
|
59
|
+
this file contains only constants,
|
|
60
|
+
it doesn't even import styled-components...
|
|
61
|
+
we should move the content under `packages/ds-chat/src/config/style-constants.tsx` in my opinion
|
|
62
|
+
|
|
63
|
+
# Typescript related
|
|
64
|
+
|
|
65
|
+
## `packages/ds-chat/src/react-desc-prop-types.tsx`
|
|
66
|
+
|
|
67
|
+
the `DSChatT` namespace is exposing both composer props and container props,
|
|
68
|
+
|
|
69
|
+
this is unexpected we should instead have two different namespaces,
|
|
70
|
+
|
|
71
|
+
- `DSChatComposerT`
|
|
72
|
+
- `DSChatContainerT`
|
|
73
|
+
|
|
74
|
+
since they are pretty much different components
|
|
75
|
+
|
|
76
|
+
## `packages/ds-chat/src/exported-related/bubble/props.ts`
|
|
77
|
+
|
|
78
|
+
must be reviewed, optional props and required options are not clearly defined, if they variate based on the "Type" we should create expected props per type and define props as
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
export type BubblePropsT = SenderBubblePropsT | RecipientBubblePropsT | DelimiterBubblePropsT | SystemBubblePropsT;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
an example of how to handle polymorphism in typescript can be found at `packages/ds-form-date-time-picker/src/propTypes.tsx` line 50 ~ 137
|
|
85
|
+
|
|
86
|
+
# Features and dimsum standards
|
|
87
|
+
|
|
88
|
+
## `packages/ds-chat/src/**/*/styled.tsx`
|
|
89
|
+
|
|
90
|
+
Theme `slot` feature is not yet implemented
|
|
91
|
+
|
|
92
|
+
## `packages/ds-chat/src/parts/chat-container-messages-list/ChatContainerMessagesList.tsx`
|
|
93
|
+
|
|
94
|
+
**339 line** in one file is overdoing it, we should use the `useChatContainerMessageList` custom hook configuring the logic to make the component easier to mantain
|
|
95
|
+
|
|
96
|
+
I re-factored the code but we need testing that this didn't break anything before releasing it
|
|
97
|
+
|
|
98
|
+
# Eslint
|
|
99
|
+
|
|
100
|
+
basically every single file has some sort of eslint error, most of the errors comes from typescript typings.
|
|
101
|
+
|
|
102
|
+
we need to re-define typings correctly AND document them properly in storybook, right now storybook props are not in sync, some props are missing, some other parts are lying (documentation says receive an array of numbers, we send an array of strings and such...)
|
|
103
|
+
|
|
104
|
+
I will not list all of these errors because they are present basically everywhere and the fix should be kind of "global" too, as in, fixing typescript typing
|
|
105
|
+
|
|
106
|
+
I think it's a good idea to fix this Eslint errors only after splitting the chat exported-related into their own packages
|
|
107
|
+
|
|
108
|
+
# Conclusions
|
|
109
|
+
|
|
110
|
+
We need to overhaul the code...
|
|
111
|
+
|
|
112
|
+
The next steps in my opinion are:
|
|
113
|
+
|
|
114
|
+
- Divide this into sub-packages `@elliemae/ds-chat-${composer/container/bubble/card/sidebar...}`
|
|
115
|
+
- Make sure every single sub-packages comply with the "clear top-to-down flow and entry point" good practice + typescript namespace + proper Storybook Schema definitions
|
|
116
|
+
- Make every single sub-package eslint-error free
|
|
117
|
+
- deploy sub-packages with "typesafe:true" in their package.json configurations
|
|
118
|
+
|
|
119
|
+
After above steps are taken care of we could fine-detail check the code again
|