@elliemae/ds-chat-container 3.80.0-next.30 → 3.80.0-next.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/cjs/DSChatContainerDefinitions.js +7 -1
  2. package/dist/cjs/DSChatContainerDefinitions.js.map +2 -2
  3. package/dist/cjs/parts/chat-container-messages-list/ChatContainerMessagesList.js +134 -71
  4. package/dist/cjs/parts/chat-container-messages-list/ChatContainerMessagesList.js.map +2 -2
  5. package/dist/cjs/parts/chat-container-messages-list/styled.js +33 -43
  6. package/dist/cjs/parts/chat-container-messages-list/styled.js.map +2 -2
  7. package/dist/cjs/parts/chat-container-messages-list/useActionRef.js +3 -9
  8. package/dist/cjs/parts/chat-container-messages-list/useActionRef.js.map +2 -2
  9. package/dist/cjs/parts/chat-container-messages-list/useChatContainerMessageList.js +30 -22
  10. package/dist/cjs/parts/chat-container-messages-list/useChatContainerMessageList.js.map +2 -2
  11. package/dist/cjs/parts/chat-container-messages-list/useFocusAndScrollHelpers.js +38 -38
  12. package/dist/cjs/parts/chat-container-messages-list/useFocusAndScrollHelpers.js.map +2 -2
  13. package/dist/cjs/parts/chat-container-messages-list/useGlobalEventListener.js.map +1 -1
  14. package/dist/cjs/parts/chat-container-messages-list/useKeyboard.js +8 -15
  15. package/dist/cjs/parts/chat-container-messages-list/useKeyboard.js.map +2 -2
  16. package/dist/cjs/parts/chat-container-messages-list/useMessageFocusTracker.js +132 -0
  17. package/dist/cjs/parts/chat-container-messages-list/useMessageFocusTracker.js.map +7 -0
  18. package/dist/cjs/react-desc-prop-types.js +39 -23
  19. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  20. package/dist/cjs/typescript-testing/typescript-chat-container-valid.js +31 -0
  21. package/dist/cjs/typescript-testing/typescript-chat-container-valid.js.map +2 -2
  22. package/dist/esm/DSChatContainerDefinitions.js +7 -1
  23. package/dist/esm/DSChatContainerDefinitions.js.map +2 -2
  24. package/dist/esm/parts/chat-container-messages-list/ChatContainerMessagesList.js +135 -74
  25. package/dist/esm/parts/chat-container-messages-list/ChatContainerMessagesList.js.map +2 -2
  26. package/dist/esm/parts/chat-container-messages-list/styled.js +33 -43
  27. package/dist/esm/parts/chat-container-messages-list/styled.js.map +2 -2
  28. package/dist/esm/parts/chat-container-messages-list/useActionRef.js +3 -9
  29. package/dist/esm/parts/chat-container-messages-list/useActionRef.js.map +2 -2
  30. package/dist/esm/parts/chat-container-messages-list/useChatContainerMessageList.js +30 -22
  31. package/dist/esm/parts/chat-container-messages-list/useChatContainerMessageList.js.map +2 -2
  32. package/dist/esm/parts/chat-container-messages-list/useFocusAndScrollHelpers.js +39 -39
  33. package/dist/esm/parts/chat-container-messages-list/useFocusAndScrollHelpers.js.map +2 -2
  34. package/dist/esm/parts/chat-container-messages-list/useGlobalEventListener.js.map +1 -1
  35. package/dist/esm/parts/chat-container-messages-list/useKeyboard.js +8 -15
  36. package/dist/esm/parts/chat-container-messages-list/useKeyboard.js.map +2 -2
  37. package/dist/esm/parts/chat-container-messages-list/useMessageFocusTracker.js +102 -0
  38. package/dist/esm/parts/chat-container-messages-list/useMessageFocusTracker.js.map +7 -0
  39. package/dist/esm/react-desc-prop-types.js +40 -24
  40. package/dist/esm/react-desc-prop-types.js.map +2 -2
  41. package/dist/esm/typescript-testing/typescript-chat-container-valid.js +31 -0
  42. package/dist/esm/typescript-testing/typescript-chat-container-valid.js.map +2 -2
  43. package/dist/types/DSChatContainerDefinitions.d.ts +8 -0
  44. package/dist/types/parts/chat-container-messages-list/styled.d.ts +18 -5
  45. package/dist/types/parts/chat-container-messages-list/useActionRef.d.ts +4 -6
  46. package/dist/types/parts/chat-container-messages-list/useChatContainerMessageList.d.ts +7 -2
  47. package/dist/types/parts/chat-container-messages-list/useFocusAndScrollHelpers.d.ts +9 -5
  48. package/dist/types/parts/chat-container-messages-list/useGlobalEventListener.d.ts +1 -1
  49. package/dist/types/parts/chat-container-messages-list/useKeyboard.d.ts +7 -3
  50. package/dist/types/parts/chat-container-messages-list/useMessageFocusTracker.d.ts +52 -0
  51. package/dist/types/react-desc-prop-types.d.ts +798 -793
  52. package/package.json +16 -16
@@ -39,6 +39,7 @@ module.exports = __toCommonJS(react_desc_prop_types_exports);
39
39
  var React = __toESM(require("react"));
40
40
  var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
41
41
  var import_ds_banner = require("@elliemae/ds-banner");
42
+ var import_DSChatContainerDefinitions = require("./DSChatContainerDefinitions.js");
42
43
  function noop(..._args) {
43
44
  }
44
45
  const defaultPropsComposer = {
@@ -61,7 +62,7 @@ const defaultPropsComposer = {
61
62
  const ChatComposerPropTypes = {
62
63
  placeholder: import_ds_props_helpers.PropTypes.string.description("Input Placeholder").defaultValue(defaultPropsComposer.placeholder),
63
64
  inputValue: import_ds_props_helpers.PropTypes.string.description("Input value").defaultValue(defaultPropsComposer.inputValue),
64
- ariaMaxLengthMessage: import_ds_props_helpers.PropTypes.string.description("Aria message for Max length message when exceeded").defaultValue(defaultPropsComposer.maxLengthMessage),
65
+ ariaMaxLengthMessage: import_ds_props_helpers.PropTypes.string.description("Aria message for Max length message when exceeded").defaultValue(defaultPropsComposer.ariaMaxLengthMessage),
65
66
  maxLengthMessage: import_ds_props_helpers.PropTypes.string.description("Max length message").defaultValue(defaultPropsComposer.maxLengthMessage),
66
67
  onChange: import_ds_props_helpers.PropTypes.func.description("Called when the user types").defaultValue(defaultPropsComposer.onChange),
67
68
  onResize: import_ds_props_helpers.PropTypes.func.description("Called the input changes his height").defaultValue(defaultPropsComposer.onResize),
@@ -69,19 +70,22 @@ const ChatComposerPropTypes = {
69
70
  onFocus: import_ds_props_helpers.PropTypes.func.description("Input focus").defaultValue(defaultPropsComposer.onFocus),
70
71
  onBlur: import_ds_props_helpers.PropTypes.func.description("Input blur").defaultValue(defaultPropsComposer.onBlur),
71
72
  onKeyDown: import_ds_props_helpers.PropTypes.func.description("Input on key down").defaultValue(defaultPropsComposer.onKeyDown),
72
- maxHeight: import_ds_props_helpers.PropTypes.number.description("Max height of the composer. Use 0 for no limit").defaultValue(defaultPropsComposer.onBlur),
73
+ maxHeight: import_ds_props_helpers.PropTypes.number.description("Max height of the composer. Use 0 for no limit").defaultValue(defaultPropsComposer.maxHeight),
73
74
  inputMaxLength: import_ds_props_helpers.PropTypes.number.description("Max length of the composer. `undefined` for no limit").defaultValue(defaultPropsComposer.inputMaxLength),
74
75
  buttonDisabled: import_ds_props_helpers.PropTypes.bool.description("Control the disabled for the send button").defaultValue(defaultPropsComposer.buttonDisabled),
75
- dataTestid: import_ds_props_helpers.PropTypes.string.description("Data testid").defaultValue(defaultPropsComposer.placeholder),
76
+ dataTestid: import_ds_props_helpers.PropTypes.string.description("Data testid").defaultValue(defaultPropsComposer.dataTestid),
76
77
  actionRef: import_ds_props_helpers.PropTypes.object.description(
77
78
  `Reference:
78
79
  {
79
- scrollToIndex?: (n: number, opts: { align: 'end' | 'center' | 'start' }) => void,
80
- getMessagesInView?: () => number[],
81
- focusToIndex?: (n: number) => void,
80
+ scrollToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,
81
+ focusToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,
82
+ getMessagesInView?: () => string[],
83
+ focusToIndexWithoutScroll?: (n: string) => void,
82
84
  focusToList?: () => void,
83
85
  focusToComposer?: () => void,
84
86
  focusToSend?: () => void,
87
+ focusOnBanner?: () => void,
88
+ focusOnBannerLink?: () => void,
85
89
  }
86
90
 
87
91
  `
@@ -100,18 +104,21 @@ const defaultPropsMessagesList = {
100
104
  bannerRef: void 0
101
105
  };
102
106
  const ChatContainerMessagesListPropTypes = {
107
+ ...(0, import_ds_props_helpers.getPropsPerSlotPropTypes)(import_DSChatContainerDefinitions.DSChatContainerSlotName, import_DSChatContainerDefinitions.DSChatContainerSlots),
103
108
  ...import_ds_props_helpers.globalAttributesPropTypes,
104
109
  messages: import_ds_props_helpers.PropTypes.arrayOf(import_ds_props_helpers.PropTypes.object).description("The array of out-of-the-box items you want to render inside the ChatMessageList").defaultValue(defaultPropsMessagesList.messages),
105
110
  actionRef: import_ds_props_helpers.PropTypes.object.description(
106
111
  `Reference:
107
112
  {
108
- scrollToIndex?: (n: number, opts: { align: 'end' | 'center' | 'start' }) => void,
109
- getMessagesInView: () => number[],
110
- focusToIndex: (n: number) => void,
111
- focusToIndexWithoutScroll: (n: number) => void,
112
- focusToList: () => void,
113
- focusToComposer: () => void,
114
- focusToSend: () => void,
113
+ scrollToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,
114
+ focusToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,
115
+ getMessagesInView?: () => string[],
116
+ focusToIndexWithoutScroll?: (n: string) => void,
117
+ focusToList?: () => void,
118
+ focusToComposer?: () => void,
119
+ focusToSend?: () => void,
120
+ focusOnBanner?: () => void,
121
+ focusOnBannerLink?: () => void,
115
122
  }
116
123
 
117
124
  `
@@ -123,7 +130,9 @@ const ChatContainerMessagesListPropTypes = {
123
130
  hasMoreItems: import_ds_props_helpers.PropTypes.oneOf(["top", "bottom", void 0]).description(
124
131
  "Show Load More button at the `top` or `bottom` of the container"
125
132
  ),
126
- getMoreMessages: import_ds_props_helpers.PropTypes.func.description("Called when the user clicks on load more").defaultValue(defaultPropsMessagesList.getMoreMessages),
133
+ getMoreMessages: import_ds_props_helpers.PropTypes.func.description(
134
+ "Called when the user clicks on load more. When older messages are added at the start of `messages`, the list keeps its scroll offset, so the messages in view shift; call `actionRef.current.scrollToIndex` after updating `messages` to bring the user back to where they were"
135
+ ).defaultValue(defaultPropsMessagesList.getMoreMessages),
127
136
  sendingMessages: import_ds_props_helpers.PropTypes.oneOfType([import_ds_props_helpers.PropTypes.arrayOf(import_ds_props_helpers.PropTypes.string), import_ds_props_helpers.PropTypes.arrayOf(import_ds_props_helpers.PropTypes.number)]).description("Array of ids of sending messages").defaultValue(defaultPropsMessagesList.sendingMessages),
128
137
  sendingText: import_ds_props_helpers.PropTypes.string.description("Label description for messages in sending status").defaultValue(defaultPropsMessagesList.sendingText)
129
138
  };
@@ -149,7 +158,9 @@ const defaultProps = {
149
158
  };
150
159
  const ChatContainerPropTypes = {
151
160
  ...import_ds_props_helpers.globalAttributesPropTypes,
152
- messagesListProps: import_ds_props_helpers.PropTypes.object.description('ChatMessageList props "messages" / "onScrollEnds"').defaultValue(defaultProps.messagesListProps),
161
+ messagesListProps: import_ds_props_helpers.PropTypes.object.description(
162
+ 'ChatMessageList props "messages" / "onScrollEnds", plus the "dsChatcontainerMessagesListScrollArea" slot prop (object or function) for the scroll area'
163
+ ).defaultValue(defaultProps.messagesListProps),
153
164
  composerProps: import_ds_props_helpers.PropTypes.object.description("Composer configuration").defaultValue(defaultProps.composerProps),
154
165
  autoScroll: import_ds_props_helpers.PropTypes.bool.description("Auto scroll to bottom on resize").defaultValue(defaultProps.autoScroll),
155
166
  device: import_ds_props_helpers.PropTypes.string.description("Option to render mobile or desktop style composer").defaultValue(defaultProps.device),
@@ -159,9 +170,11 @@ const ChatContainerPropTypes = {
159
170
  hasMoreItems: import_ds_props_helpers.PropTypes.oneOf(["top", "bottom", void 0]).description(
160
171
  "Show Load More button at the `top` or `bottom` of the container"
161
172
  ),
162
- getMoreMessages: import_ds_props_helpers.PropTypes.func.description("Called when the user clicks on load more").defaultValue(defaultProps.getMoreMessages),
173
+ getMoreMessages: import_ds_props_helpers.PropTypes.func.description(
174
+ "Called when the user clicks on load more. When older messages are added at the start of `messages`, the list keeps its scroll offset, so the messages in view shift; call `actionRef.current.scrollToIndex` after updating `messages` to bring the user back to where they were"
175
+ ).defaultValue(defaultProps.getMoreMessages),
163
176
  bannerPosition: import_ds_props_helpers.PropTypes.oneOf(["top", "bottom", void 0]).description(
164
- "Show Loading messages indicator at the `top` or `bottom` of the container"
177
+ "Show the unread messages banner (configured with `bannerProps`) at the `top` or `bottom` of the container"
165
178
  ),
166
179
  bannerProps: import_ds_props_helpers.PropTypes.object.description(
167
180
  `Banner configuration:
@@ -177,12 +190,15 @@ const ChatContainerPropTypes = {
177
190
  actionRef: import_ds_props_helpers.PropTypes.object.description(
178
191
  `Reference:
179
192
  {
180
- scrollToIndex: (n: number) => void,
181
- getMessagesInView: () => number[],
182
- focusToIndex: (n: number) => void,
183
- focusToList: () => void,
184
- focusToComposer: () => void,
185
- focusToSend: () => void,
193
+ scrollToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,
194
+ focusToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,
195
+ getMessagesInView?: () => string[],
196
+ focusToIndexWithoutScroll?: (n: string) => void,
197
+ focusToList?: () => void,
198
+ focusToComposer?: () => void,
199
+ focusToSend?: () => void,
200
+ focusOnBanner?: () => void,
201
+ focusOnBannerLink?: () => void,
186
202
  }
187
203
 
188
204
  `
@@ -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 type { Virtualizer } from '@tanstack/react-virtual';\nimport { PropTypes, globalAttributesPropTypes } from '@elliemae/ds-props-helpers';\nimport { BANNER_TYPES } from '@elliemae/ds-banner';\nimport { type DSChatBubbleT } from '@elliemae/ds-chat-bubble';\nimport { type DSButtonT } from '@elliemae/ds-button-v2';\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?: 'info' | 'success' | 'danger' | 'warning';\n onView: () => void;\n onClose: () => void;\n }\n /**\n * Single source of truth for the virtualizer's element generics \u2014 reused across every file that\n * types `useVirtualHelpers`, so they can't drift out of sync with each other (which previously\n * produced a real dts build failure: `Virtualizer<HTMLDivElement, Element>` vs `Virtualizer<Element, Element>`).\n */\n export type ChatVirtualizer = Virtualizer<HTMLDivElement, HTMLDivElement>;\n export type ScrollToIndexOptions = Parameters<ChatVirtualizer['scrollToIndex']>[1];\n export type ActionRef = React.MutableRefObject<{\n scrollToIndex?: (index: number, opts?: ScrollToIndexOptions) => void;\n focusToIndex?: (index: number, opts?: ScrollToIndexOptions) => void;\n getMessagesInView?: () => string[];\n focusToIndexWithoutScroll?: (index: string) => void;\n focusToList?: () => void;\n focusToComposer?: () => void;\n focusToSend?: () => void;\n focusOnBanner?: () => void;\n focusOnBannerLink?: () => void;\n }>;\n\n export interface ComposerProps extends Record<string, unknown> {\n placeholder?: string;\n inputValue?: string;\n ariaMaxLengthMessage?: string;\n maxLengthMessage?: string;\n onChange: (value: string) => void;\n onResize?: (value: number) => void;\n onSend: (e: Parameters<Required<DSButtonT.Props>['onClick']>[0]) => void;\n onFocus?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;\n onBlur?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n maxHeight?: number;\n inputMaxLength?: number;\n buttonDisabled: boolean;\n dataTestid?: string;\n actionRef?: ActionRef;\n }\n\n export interface MessagesListProps extends Record<string, unknown> {\n messages: DSChatBubbleT.Props[];\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 ContainerProps extends Record<string, unknown> {\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 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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",
4
+ "sourcesContent": ["/* eslint-disable max-lines */\nimport type { DSFastListT } from '@elliemae/ds-fast-list';\nimport { PropTypes, getPropsPerSlotPropTypes, globalAttributesPropTypes } from '@elliemae/ds-props-helpers';\nimport type { TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { BANNER_TYPES } from '@elliemae/ds-banner';\nimport { type DSChatBubbleT } from '@elliemae/ds-chat-bubble';\nimport { type DSButtonT } from '@elliemae/ds-button-v2';\nimport { DSChatContainerSlotName, DSChatContainerSlots } from './DSChatContainerDefinitions.js';\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?: 'info' | 'success' | 'danger' | 'warning';\n onView: () => void;\n onClose: () => void;\n }\n /**\n * Kept with its published shape \u2014 react-virtual v2's optional `scrollToIndex` options: `{ align }` with `align`\n * required, or `undefined` \u2014 so code written against it keeps compiling.\n */\n export type ScrollToIndexOptions = DSFastListT.ScrollToOptions | undefined;\n /** What `scrollToIndex` and `focusToIndex` accept: `align` is optional and `behavior` can request a smooth scroll. */\n export type ScrollActionOptions = DSFastListT.ScrollActionOptions;\n export type ActionRef = React.MutableRefObject<{\n /** Method syntax on purpose: an `actionRef` typed with the published `ScrollToIndexOptions` stays assignable. */\n scrollToIndex?(index: number, opts?: ScrollActionOptions): void;\n focusToIndex?(index: number, opts?: ScrollActionOptions): void;\n getMessagesInView?: () => string[];\n focusToIndexWithoutScroll?: (index: string) => void;\n focusToList?: () => void;\n focusToComposer?: () => void;\n focusToSend?: () => void;\n focusOnBanner?: () => void;\n focusOnBannerLink?: () => void;\n }>;\n\n export interface ComposerProps extends Record<string, unknown> {\n placeholder?: string;\n inputValue?: string;\n ariaMaxLengthMessage?: string;\n maxLengthMessage?: string;\n onChange: (value: string) => void;\n onResize?: (value: number) => void;\n onSend: (e: Parameters<Required<DSButtonT.Props>['onClick']>[0]) => void;\n onFocus?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;\n onBlur?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n maxHeight?: number;\n inputMaxLength?: number;\n buttonDisabled: boolean;\n dataTestid?: string;\n actionRef?: ActionRef;\n }\n\n export type MessagesListSlotProps = TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSChatContainerSlotName,\n typeof DSChatContainerSlots\n >;\n\n export interface MessagesListProps extends Record<string, unknown>, MessagesListSlotProps {\n messages: DSChatBubbleT.Props[];\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 ContainerProps extends Record<string, unknown> {\n messagesListProps: Pick<MessagesListProps, 'messages' | 'onScrollEnds'> & MessagesListSlotProps;\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 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.ariaMaxLengthMessage),\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.maxHeight),\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.dataTestid),\n actionRef: PropTypes.object\n .description(\n `Reference: \n { \n scrollToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,\n focusToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,\n getMessagesInView?: () => string[],\n focusToIndexWithoutScroll?: (n: string) => void,\n focusToList?: () => void,\n focusToComposer?: () => void,\n focusToSend?: () => void,\n focusOnBanner?: () => void,\n focusOnBannerLink?: () => 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 ...getPropsPerSlotPropTypes(DSChatContainerSlotName, DSChatContainerSlots),\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?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,\n focusToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,\n getMessagesInView?: () => string[],\n focusToIndexWithoutScroll?: (n: string) => void,\n focusToList?: () => void,\n focusToComposer?: () => void,\n focusToSend?: () => void,\n focusOnBanner?: () => void,\n focusOnBannerLink?: () => 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(\n 'Called when the user clicks on load more. When older messages are added at the start of `messages`, the list keeps its scroll offset, so the messages in view shift; call `actionRef.current.scrollToIndex` after updating `messages` to bring the user back to where they were',\n )\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(\n 'ChatMessageList props \"messages\" / \"onScrollEnds\", plus the \"dsChatcontainerMessagesListScrollArea\" slot prop (object or function) for the scroll area',\n )\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(\n 'Called when the user clicks on load more. When older messages are added at the start of `messages`, the list keeps its scroll offset, so the messages in view shift; call `actionRef.current.scrollToIndex` after updating `messages` to bring the user back to where they were',\n )\n .defaultValue(defaultProps.getMoreMessages),\n bannerPosition: PropTypes.oneOf(['top', 'bottom', undefined]).description(\n 'Show the unread messages banner (configured with `bannerProps`) 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, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,\n focusToIndex?: (n: number, opts?: { align?: 'start' | 'center' | 'end' | 'auto', behavior?: 'auto' | 'smooth' }) => void,\n getMessagesInView?: () => string[],\n focusToIndexWithoutScroll?: (n: string) => void,\n focusToList?: () => void,\n focusToComposer?: () => void,\n focusToSend?: () => void,\n focusOnBanner?: () => void,\n focusOnBannerLink?: () => 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
  }
@@ -76,6 +76,19 @@ const testDefinitionAsConst = {
76
76
  },
77
77
  sendingText: "Sending..."
78
78
  };
79
+ const actionRef = { current: {} };
80
+ const scrollOptionsAlign = { align: "end" };
81
+ const scrollOptionsBehavior = { behavior: "smooth" };
82
+ const scrollOptionsBoth = { align: "start", behavior: "auto" };
83
+ const publishedScrollOptions = { align: "center" };
84
+ const publishedAlign = publishedScrollOptions.align;
85
+ const publishedNoScrollOptions = void 0;
86
+ const handleScrollToIndexWithPublishedOptions = () => actionRef.current.scrollToIndex?.(1, publishedScrollOptions);
87
+ const handleScrollToIndex = () => actionRef.current.scrollToIndex?.(1);
88
+ const handleScrollToIndexWithAlign = () => actionRef.current.scrollToIndex?.(1, { align: "end" });
89
+ const handleScrollToIndexWithBehavior = () => actionRef.current.scrollToIndex?.(1, { behavior: "smooth" });
90
+ const handleFocusToIndexWithBoth = () => actionRef.current.focusToIndex?.(1, { align: "start", behavior: "auto" });
91
+ const handleGetMessagesInView = () => actionRef.current.getMessagesInView?.() ?? [];
79
92
  const ExampleUsageComponent = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
80
93
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.ChatContainer, { ...testExplicitDefinition }),
81
94
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.ChatContainer, { ...testInferedTypeCompatibility }),
@@ -99,6 +112,24 @@ const ExampleUsageComponent = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)
99
112
  },
100
113
  sendingText: "Sending..."
101
114
  }
115
+ ),
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.ChatContainer, { ...testExplicitDefinition, actionRef }),
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
118
+ import__.ChatContainer,
119
+ {
120
+ ...testExplicitDefinition,
121
+ messagesListProps: { messages, dsChatcontainerMessagesListScrollArea: { "aria-describedby": "description" } }
122
+ }
123
+ ),
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
125
+ import__.ChatContainer,
126
+ {
127
+ ...testExplicitDefinition,
128
+ messagesListProps: {
129
+ messages,
130
+ dsChatcontainerMessagesListScrollArea: () => ({ "aria-describedby": "description" })
131
+ }
132
+ }
102
133
  )
103
134
  ] });
104
135
  //# sourceMappingURL=typescript-chat-container-valid.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/typescript-testing/typescript-chat-container-valid.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\nimport type { DSChatBubbleT } from '@elliemae/ds-chat-bubble';\nimport { ChatContainer } from '../index.js';\nimport type { DSChatT } from '../index.js';\n\n// test we expose the namespace and the namespace follows our deliverable conventions\ntype ComponentPropsForApp = DSChatT.ContainerProps;\n\nconst messages: DSChatBubbleT.Props[] = [];\n\n// using the explicit type definition, if there is an error, it will be marked on the key that is wrong\nconst testExplicitDefinition: ComponentPropsForApp = {\n messagesListProps: {\n messages,\n },\n composerProps: {\n onChange: () => {},\n onSend: () => {},\n buttonDisabled: false,\n },\n autoScroll: false,\n device: 'desktop',\n getMoreMessages: () => {},\n sendingText: 'Sending...',\n};\n\n// using the \"as\" syntax, if there is an error, it will be marking the whole object as wrong because it is not compatible with the type\nconst testInferedTypeCompatibility = {\n messagesListProps: {\n messages,\n },\n composerProps: {\n onChange: () => {},\n onSend: () => {},\n buttonDisabled: false,\n },\n autoScroll: false,\n device: 'desktop',\n getMoreMessages: () => {},\n sendingText: 'Sending...',\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n messagesListProps: {\n messages,\n },\n composerProps: {\n onChange: () => {},\n onSend: () => {},\n buttonDisabled: false,\n },\n autoScroll: false,\n device: 'desktop',\n getMoreMessages: () => {},\n sendingText: 'Sending...',\n} as const;\n\nconst ExampleUsageComponent = () => (\n <>\n {/* works with explicitly casted props, all syntaxes */}\n <ChatContainer {...testExplicitDefinition} />\n <ChatContainer {...testInferedTypeCompatibility} />\n <ChatContainer {...testDefinitionAsConst} />\n {/* works with inline values */}\n <ChatContainer\n messagesListProps={{\n messages,\n }}\n composerProps={{\n onChange: () => {},\n onSend: () => {},\n buttonDisabled: false,\n }}\n autoScroll={false}\n device=\"desktop\"\n getMoreMessages={() => {}}\n sendingText=\"Sending...\"\n />\n </>\n);\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA,YAAuB;AC0DrB;AAxDF,eAA8B;AAM9B,MAAM,WAAkC,CAAC;AAGzC,MAAM,yBAA+C;AAAA,EACnD,mBAAmB;AAAA,IACjB;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,UAAU,MAAM;AAAA,IAAC;AAAA,IACjB,QAAQ,MAAM;AAAA,IAAC;AAAA,IACf,gBAAgB;AAAA,EAClB;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,iBAAiB,MAAM;AAAA,EAAC;AAAA,EACxB,aAAa;AACf;AAGA,MAAM,+BAA+B;AAAA,EACnC,mBAAmB;AAAA,IACjB;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,UAAU,MAAM;AAAA,IAAC;AAAA,IACjB,QAAQ,MAAM;AAAA,IAAC;AAAA,IACf,gBAAgB;AAAA,EAClB;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,iBAAiB,MAAM;AAAA,EAAC;AAAA,EACxB,aAAa;AACf;AAEA,MAAM,wBAAwB;AAAA,EAC5B,mBAAmB;AAAA,IACjB;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,UAAU,MAAM;AAAA,IAAC;AAAA,IACjB,QAAQ,MAAM;AAAA,IAAC;AAAA,IACf,gBAAgB;AAAA,EAClB;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,iBAAiB,MAAM;AAAA,EAAC;AAAA,EACxB,aAAa;AACf;AAEA,MAAM,wBAAwB,MAC5B,4EAEE;AAAA,8CAAC,0BAAe,GAAG,wBAAwB;AAAA,EAC3C,4CAAC,0BAAe,GAAG,8BAA8B;AAAA,EACjD,4CAAC,0BAAe,GAAG,uBAAuB;AAAA,EAE1C;AAAA,IAAC;AAAA;AAAA,MACC,mBAAmB;AAAA,QACjB;AAAA,MACF;AAAA,MACA,eAAe;AAAA,QACb,UAAU,MAAM;AAAA,QAAC;AAAA,QACjB,QAAQ,MAAM;AAAA,QAAC;AAAA,QACf,gBAAgB;AAAA,MAClB;AAAA,MACA,YAAY;AAAA,MACZ,QAAO;AAAA,MACP,iBAAiB,MAAM;AAAA,MAAC;AAAA,MACxB,aAAY;AAAA;AAAA,EACd;AAAA,GACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\nimport type { DSChatBubbleT } from '@elliemae/ds-chat-bubble';\nimport { ChatContainer } from '../index.js';\nimport type { DSChatT } from '../index.js';\n\n// test we expose the namespace and the namespace follows our deliverable conventions\ntype ComponentPropsForApp = DSChatT.ContainerProps;\n\nconst messages: DSChatBubbleT.Props[] = [];\n\n// using the explicit type definition, if there is an error, it will be marked on the key that is wrong\nconst testExplicitDefinition: ComponentPropsForApp = {\n messagesListProps: {\n messages,\n },\n composerProps: {\n onChange: () => {},\n onSend: () => {},\n buttonDisabled: false,\n },\n autoScroll: false,\n device: 'desktop',\n getMoreMessages: () => {},\n sendingText: 'Sending...',\n};\n\n// using the \"as\" syntax, if there is an error, it will be marking the whole object as wrong because it is not compatible with the type\nconst testInferedTypeCompatibility = {\n messagesListProps: {\n messages,\n },\n composerProps: {\n onChange: () => {},\n onSend: () => {},\n buttonDisabled: false,\n },\n autoScroll: false,\n device: 'desktop',\n getMoreMessages: () => {},\n sendingText: 'Sending...',\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n messagesListProps: {\n messages,\n },\n composerProps: {\n onChange: () => {},\n onSend: () => {},\n buttonDisabled: false,\n },\n autoScroll: false,\n device: 'desktop',\n getMoreMessages: () => {},\n sendingText: 'Sending...',\n} as const;\n\n// the public actionRef, including the scroll options (both `align` and `behavior` are optional)\nconst actionRef: DSChatT.ActionRef = { current: {} };\nconst scrollOptionsAlign: DSChatT.ScrollActionOptions = { align: 'end' };\nconst scrollOptionsBehavior: DSChatT.ScrollActionOptions = { behavior: 'smooth' };\nconst scrollOptionsBoth: DSChatT.ScrollActionOptions = { align: 'start', behavior: 'auto' };\n// ScrollToIndexOptions keeps its published shape: `{ align }` with `align` required, or `undefined`\nconst publishedScrollOptions: NonNullable<DSChatT.ScrollToIndexOptions> = { align: 'center' };\nconst publishedAlign: 'start' | 'center' | 'end' | 'auto' = publishedScrollOptions.align;\nconst publishedNoScrollOptions: DSChatT.ScrollToIndexOptions = undefined;\nconst handleScrollToIndexWithPublishedOptions = () => actionRef.current.scrollToIndex?.(1, publishedScrollOptions);\nconst handleScrollToIndex = () => actionRef.current.scrollToIndex?.(1);\nconst handleScrollToIndexWithAlign = () => actionRef.current.scrollToIndex?.(1, { align: 'end' });\nconst handleScrollToIndexWithBehavior = () => actionRef.current.scrollToIndex?.(1, { behavior: 'smooth' });\nconst handleFocusToIndexWithBoth = () => actionRef.current.focusToIndex?.(1, { align: 'start', behavior: 'auto' });\nconst handleGetMessagesInView: () => string[] = () => actionRef.current.getMessagesInView?.() ?? [];\n\nconst ExampleUsageComponent = () => (\n <>\n {/* works with explicitly casted props, all syntaxes */}\n <ChatContainer {...testExplicitDefinition} />\n <ChatContainer {...testInferedTypeCompatibility} />\n <ChatContainer {...testDefinitionAsConst} />\n {/* works with inline values */}\n <ChatContainer\n messagesListProps={{\n messages,\n }}\n composerProps={{\n onChange: () => {},\n onSend: () => {},\n buttonDisabled: false,\n }}\n autoScroll={false}\n device=\"desktop\"\n getMoreMessages={() => {}}\n sendingText=\"Sending...\"\n />\n <ChatContainer {...testExplicitDefinition} actionRef={actionRef} />\n {/* the message list scroll area slot, in object and function form, through messagesListProps */}\n <ChatContainer\n {...testExplicitDefinition}\n messagesListProps={{ messages, dsChatcontainerMessagesListScrollArea: { 'aria-describedby': 'description' } }}\n />\n <ChatContainer\n {...testExplicitDefinition}\n messagesListProps={{\n messages,\n dsChatcontainerMessagesListScrollArea: () => ({ 'aria-describedby': 'description' }),\n }}\n />\n </>\n);\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,9 +2,15 @@ import * as React from "react";
2
2
  const DSChatContainerName = "DSChatcontainername";
3
3
  const DSChatContainerComposerName = "DSChatcontainercomposer";
4
4
  const DSChatContainerMessagesList = "DSChatcontainermessageslist";
5
+ const DSChatContainerSlotName = "DSChatcontainer";
6
+ const DSChatContainerSlots = {
7
+ MESSAGES_LIST_SCROLL_AREA: "messages-list-scroll-area"
8
+ };
5
9
  export {
6
10
  DSChatContainerComposerName,
7
11
  DSChatContainerMessagesList,
8
- DSChatContainerName
12
+ DSChatContainerName,
13
+ DSChatContainerSlotName,
14
+ DSChatContainerSlots
9
15
  };
10
16
  //# sourceMappingURL=DSChatContainerDefinitions.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/DSChatContainerDefinitions.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "export const DSChatContainerName = 'DSChatcontainername';\nexport const DSChatContainerComposerName = 'DSChatcontainercomposer';\nexport const DSChatContainerMessagesList = 'DSChatcontainermessageslist';\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAhB,MAAM,sBAAsB;AAC5B,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "export const DSChatContainerName = 'DSChatcontainername';\nexport const DSChatContainerComposerName = 'DSChatcontainercomposer';\nexport const DSChatContainerMessagesList = 'DSChatcontainermessageslist';\n\n/**\n * Slot system: the main component and its parts share one slot owner name, each part with its own slot\n * names (the convention of the `ds-chat-container-compliance` change, which moves these into `src/constants/`).\n */\nexport const DSChatContainerSlotName = 'DSChatcontainer';\nexport const DSChatContainerSlots = {\n MESSAGES_LIST_SCROLL_AREA: 'messages-list-scroll-area',\n} as const;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAhB,MAAM,sBAAsB;AAC5B,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AAMpC,MAAM,0BAA0B;AAChC,MAAM,uBAAuB;AAAA,EAClC,2BAA2B;AAC7B;",
6
6
  "names": []
7
7
  }
@@ -8,101 +8,162 @@ import { MessageDelimiter } from "@elliemae/ds-chat-message-delimeter";
8
8
  import { SystemMessage } from "@elliemae/ds-chat-system-message";
9
9
  import {
10
10
  StyledWrapperListItem,
11
- StyledChatContainerContentList,
12
- StyledChatContainerContentListScroll,
11
+ StyledFastList,
13
12
  StyledWrapper,
14
13
  StyledLoadMoreContainer,
15
- ListItem,
16
14
  StyledNewMessagesHiddenContainer
17
15
  } from "./styled.js";
18
16
  import { ChatContainerMessagesListPropTypes } from "../../react-desc-prop-types.js";
19
17
  import { useGetNewMessages } from "./useGetNewMessages.js";
20
18
  import { useChatContainerMessageList } from "./useChatContainerMessageList.js";
19
+ import { getMessageFocusId, getMessagePositionId } from "./useMessageFocusTracker.js";
21
20
  import { ChatContainerDataTestIds } from "../../ChatContainerDataTestids.js";
21
+ const ESTIMATED_MESSAGE_HEIGHT = 80;
22
+ const estimateSize = () => ESTIMATED_MESSAGE_HEIGHT;
23
+ const WRAPPER_LIST_PROPS = { role: "none" };
24
+ const ItemRenderer = ({ index, extraItemProps }) => {
25
+ const { messages, sendingMessages, sendingText, focusRequest, focusCallbacks } = extraItemProps ?? {};
26
+ const row = messages?.[index];
27
+ const isFocusTarget = Boolean(
28
+ row && focusRequest && (focusRequest.messageId === getMessageFocusId(row, index) || focusRequest.messageId === getMessagePositionId(index))
29
+ );
30
+ const requestId = isFocusTarget && focusRequest ? focusRequest.requestId : 0;
31
+ const preventScroll = isFocusTarget && focusRequest ? focusRequest.preventScroll : false;
32
+ const focusRef = React2.useCallback(
33
+ (node) => {
34
+ if (!node || !isFocusTarget || !focusCallbacks) return;
35
+ const item = node.closest("[data-index]");
36
+ const takeFocus = focusCallbacks.mayTakeFocus(requestId, item);
37
+ if (!takeFocus) return;
38
+ item?.focus({ preventScroll: takeFocus === "restore" || preventScroll });
39
+ focusCallbacks.markFulfilled(requestId);
40
+ },
41
+ [isFocusTarget, requestId, preventScroll, focusCallbacks]
42
+ );
43
+ if (!row) return null;
44
+ const isSending = sendingMessages && sendingMessages.find((m) => m === row.dsId);
45
+ return /* @__PURE__ */ jsxs(StyledWrapperListItem, { type: row.type, innerRef: focusRef, children: [
46
+ row.type === BUBBLE_TYPES.SENDER || row.type === BUBBLE_TYPES.RECIPIENT ? /* @__PURE__ */ jsx(ChatBubble, { ...row, helpMessage: isSending ? sendingText : row.helpMessage }) : null,
47
+ row.type === BUBBLE_TYPES.DELIMITER ? /* @__PURE__ */ jsx(MessageDelimiter, { ...row }) : null,
48
+ row.type === BUBBLE_TYPES.SYSTEM ? /* @__PURE__ */ jsx(SystemMessage, { ...row }) : null
49
+ ] });
50
+ };
22
51
  const ChatContainerMessagesList = (props) => {
23
52
  const {
24
53
  propsWithDefault,
25
54
  globalAttributes,
26
- useVirtualHelpers,
55
+ fastListActionRef,
56
+ paddingStart,
57
+ paddingEnd,
27
58
  handleKey,
28
59
  handleListKey,
29
60
  loadMoreRef,
30
- virtualListRef
61
+ virtualListRef,
62
+ focusTracker
31
63
  } = useChatContainerMessageList(props);
32
64
  const { sendingText, sendingMessages, messages, getMoreMessages, hasMoreItems, isLoading } = propsWithDefault;
33
- const totalSize = useVirtualHelpers.getTotalSize();
34
- const virtualItems = useVirtualHelpers.getVirtualItems();
35
- const { measureElement } = useVirtualHelpers;
36
65
  const newMessages = useGetNewMessages(messages);
37
- const render = React2.useMemo(
38
- () => virtualItems.map((virtualItem) => {
39
- const { index, start } = virtualItem;
40
- const row = messages[index];
41
- const isSending = sendingMessages && sendingMessages.find((m) => m === row.dsId);
42
- const style = {
43
- position: "absolute",
44
- top: 0,
45
- left: 0,
46
- transform: `translateY(${start}px)`,
47
- width: "100%"
48
- };
49
- return /* @__PURE__ */ jsx(
50
- ListItem,
51
- {
52
- "data-element": "chat-element-list-item",
53
- "data-index": index,
54
- style,
55
- innerRef: measureElement,
56
- tabIndex: -1,
57
- onKeyDown: handleKey,
58
- role: "listitem",
59
- children: /* @__PURE__ */ jsxs(StyledWrapperListItem, { type: row.type, children: [
60
- row.type === BUBBLE_TYPES.SENDER || row.type === BUBBLE_TYPES.RECIPIENT ? /* @__PURE__ */ jsx(ChatBubble, { ...row, helpMessage: isSending ? sendingText : row.helpMessage }) : null,
61
- row.type === BUBBLE_TYPES.DELIMITER ? /* @__PURE__ */ jsx(MessageDelimiter, { ...row }) : null,
62
- row.type === BUBBLE_TYPES.SYSTEM ? /* @__PURE__ */ jsx(SystemMessage, { ...row }) : null
63
- ] })
64
- },
65
- `ds-chat-bubble-${index}-${row.dsId}-${row.type}`
66
- );
67
- }),
68
- [virtualItems, messages, sendingMessages, handleKey, sendingText, measureElement]
66
+ const getOwnerProps = React2.useCallback(() => propsWithDefault, [propsWithDefault]);
67
+ const getId = React2.useCallback(
68
+ (index) => `${index}-${messages[index].dsId}-${messages[index].type}`,
69
+ [messages]
70
+ );
71
+ const {
72
+ focusRequest,
73
+ mayTakeFocus,
74
+ markFulfilled,
75
+ trackFocusedMessage,
76
+ trackFocusResetter,
77
+ handleFocusOut,
78
+ listRootRef
79
+ } = focusTracker;
80
+ const focusCallbacks = React2.useMemo(() => ({ mayTakeFocus, markFulfilled }), [mayTakeFocus, markFulfilled]);
81
+ const extraItemProps = React2.useMemo(
82
+ () => ({ messages, sendingMessages, sendingText, focusRequest, focusCallbacks }),
83
+ [messages, sendingMessages, sendingText, focusRequest, focusCallbacks]
69
84
  );
70
- return /* @__PURE__ */ jsxs(StyledWrapper, { ...globalAttributes, children: [
71
- /* @__PURE__ */ jsx(
72
- StyledChatContainerContentList,
85
+ const { onFocus: onFocusFromConsumer, onBlur: onBlurFromConsumer } = globalAttributes;
86
+ const handleFocusIn = React2.useCallback(
87
+ (e) => {
88
+ const item = e.target.closest('[data-element="chat-element-list-item"]');
89
+ const index = item?.dataset.index;
90
+ const position = Number(index);
91
+ const row = index !== void 0 ? messages[position] : void 0;
92
+ if (row) trackFocusedMessage(getMessageFocusId(row, position));
93
+ else trackFocusResetter();
94
+ onFocusFromConsumer?.(e);
95
+ },
96
+ [messages, trackFocusedMessage, trackFocusResetter, onFocusFromConsumer]
97
+ );
98
+ const handleFocusOutWithConsumer = React2.useCallback(
99
+ (e) => {
100
+ handleFocusOut(e);
101
+ onBlurFromConsumer?.(e);
102
+ },
103
+ [handleFocusOut, onBlurFromConsumer]
104
+ );
105
+ const itemProps = React2.useMemo(
106
+ () => ({ "data-element": "chat-element-list-item", tabIndex: -1, onKeyDown: handleKey }),
107
+ [handleKey]
108
+ );
109
+ const extraContent = React2.useMemo(
110
+ () => !isLoading && hasMoreItems ? /* @__PURE__ */ jsx(StyledLoadMoreContainer, { hasMoreItems, role: "listitem", children: /* @__PURE__ */ jsx(
111
+ DSButtonV2,
73
112
  {
74
- "data-testid": ChatContainerDataTestIds.THREAD_CONTAINER,
75
- tabIndex: 0,
76
- innerRef: virtualListRef,
77
- role: "list",
78
- onKeyDown: handleListKey,
79
- children: /* @__PURE__ */ jsxs(StyledChatContainerContentListScroll, { height: `${totalSize}px`, children: [
80
- !isLoading && hasMoreItems ? /* @__PURE__ */ jsx(StyledLoadMoreContainer, { hasMoreItems, role: "listitem", children: /* @__PURE__ */ jsx(
81
- DSButtonV2,
82
- {
83
- buttonType: "outline",
84
- onClick: getMoreMessages,
85
- "data-testid": ChatContainerDataTestIds.LOAD_MORE_BUTTON,
86
- innerRef: loadMoreRef,
87
- children: "Load More"
88
- }
89
- ) }) : null,
90
- render
91
- ] })
113
+ buttonType: "outline",
114
+ onClick: getMoreMessages,
115
+ "data-testid": ChatContainerDataTestIds.LOAD_MORE_BUTTON,
116
+ innerRef: loadMoreRef,
117
+ children: "Load More"
92
118
  }
93
- ),
94
- /* @__PURE__ */ jsx(StyledNewMessagesHiddenContainer, { "aria-live": "polite", "aria-hidden": "false", children: newMessages.map((newMessage) => /* @__PURE__ */ jsxs("p", { children: [
95
- newMessage.title,
96
- " ",
97
- newMessage.time,
98
- " ",
99
- newMessage.body,
100
- " ",
101
- newMessage.errorMessage,
102
- " ",
103
- newMessage.helpMessage
104
- ] }, newMessage.dsId)) })
105
- ] });
119
+ ) }) : null,
120
+ [isLoading, hasMoreItems, getMoreMessages, loadMoreRef]
121
+ );
122
+ return /* @__PURE__ */ jsxs(
123
+ StyledWrapper,
124
+ {
125
+ ...globalAttributes,
126
+ innerRef: listRootRef,
127
+ onFocus: handleFocusIn,
128
+ onBlur: handleFocusOutWithConsumer,
129
+ children: [
130
+ /* @__PURE__ */ jsx(
131
+ StyledFastList,
132
+ {
133
+ getOwnerProps,
134
+ "data-testid": ChatContainerDataTestIds.THREAD_CONTAINER,
135
+ role: "list",
136
+ tabIndex: 0,
137
+ onKeyDown: handleListKey,
138
+ innerRef: virtualListRef,
139
+ actionRef: fastListActionRef,
140
+ remountOnCountChange: false,
141
+ count: messages.length,
142
+ getId,
143
+ estimateSize,
144
+ paddingStart,
145
+ paddingEnd,
146
+ ItemRenderer,
147
+ extraItemProps,
148
+ extraContent,
149
+ dsFastlistWrapperList: WRAPPER_LIST_PROPS,
150
+ dsFastlistItem: itemProps
151
+ }
152
+ ),
153
+ /* @__PURE__ */ jsx(StyledNewMessagesHiddenContainer, { "aria-live": "polite", "aria-hidden": "false", children: newMessages.map((newMessage) => /* @__PURE__ */ jsxs("p", { children: [
154
+ newMessage.title,
155
+ " ",
156
+ newMessage.time,
157
+ " ",
158
+ newMessage.body,
159
+ " ",
160
+ newMessage.errorMessage,
161
+ " ",
162
+ newMessage.helpMessage
163
+ ] }, newMessage.dsId)) })
164
+ ]
165
+ }
166
+ );
106
167
  };
107
168
  ChatContainerMessagesList.displayName = "ChatContainerMessagesList";
108
169
  const ChatContainerMessagesListWithSchema = describe(ChatContainerMessagesList);