@mitodl/smoot-design 0.0.0-1967631

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 (261) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +35 -0
  3. package/dist/bundles/remoteTutorDrawer.es.js +38609 -0
  4. package/dist/bundles/remoteTutorDrawer.es.js.map +1 -0
  5. package/dist/bundles/remoteTutorDrawer.umd.js +241 -0
  6. package/dist/bundles/remoteTutorDrawer.umd.js.map +1 -0
  7. package/dist/cjs/VERSION.d.ts +6 -0
  8. package/dist/cjs/VERSION.js +9 -0
  9. package/dist/cjs/ai.d.ts +3 -0
  10. package/dist/cjs/ai.js +9 -0
  11. package/dist/cjs/bundles/RemoteTutorDrawer/FlashcardsScreen.d.ts +9 -0
  12. package/dist/cjs/bundles/RemoteTutorDrawer/FlashcardsScreen.js +87 -0
  13. package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.d.ts +56 -0
  14. package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.js +283 -0
  15. package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.stories.d.ts +17 -0
  16. package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.stories.js +302 -0
  17. package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.test.d.ts +1 -0
  18. package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.test.js +247 -0
  19. package/dist/cjs/bundles/remoteTutorDrawer.d.ts +7 -0
  20. package/dist/cjs/bundles/remoteTutorDrawer.js +43 -0
  21. package/dist/cjs/components/AiChat/AiChat.d.ts +5 -0
  22. package/dist/cjs/components/AiChat/AiChat.js +233 -0
  23. package/dist/cjs/components/AiChat/AiChat.stories.d.ts +21 -0
  24. package/dist/cjs/components/AiChat/AiChat.stories.js +257 -0
  25. package/dist/cjs/components/AiChat/AiChat.test.d.ts +1 -0
  26. package/dist/cjs/components/AiChat/AiChat.test.js +211 -0
  27. package/dist/cjs/components/AiChat/AiChatContext.d.ts +26 -0
  28. package/dist/cjs/components/AiChat/AiChatContext.js +105 -0
  29. package/dist/cjs/components/AiChat/AiChatContext.stories.d.ts +14 -0
  30. package/dist/cjs/components/AiChat/AiChatContext.stories.js +75 -0
  31. package/dist/cjs/components/AiChat/ChatTitle.d.ts +8 -0
  32. package/dist/cjs/components/AiChat/ChatTitle.js +43 -0
  33. package/dist/cjs/components/AiChat/EntryScreen.d.ts +11 -0
  34. package/dist/cjs/components/AiChat/EntryScreen.js +123 -0
  35. package/dist/cjs/components/AiChat/Markdown.d.ts +7 -0
  36. package/dist/cjs/components/AiChat/Markdown.js +14 -0
  37. package/dist/cjs/components/AiChat/TimLogo.d.ts +5 -0
  38. package/dist/cjs/components/AiChat/TimLogo.js +15 -0
  39. package/dist/cjs/components/AiChat/test-utils/api.d.ts +2 -0
  40. package/dist/cjs/components/AiChat/test-utils/api.js +164 -0
  41. package/dist/cjs/components/AiChat/types.d.ts +91 -0
  42. package/dist/cjs/components/AiChat/types.js +3 -0
  43. package/dist/cjs/components/AiChat/utils.d.ts +9 -0
  44. package/dist/cjs/components/AiChat/utils.js +41 -0
  45. package/dist/cjs/components/Alert/Alert.d.ts +15 -0
  46. package/dist/cjs/components/Alert/Alert.js +62 -0
  47. package/dist/cjs/components/Alert/Alert.stories.d.ts +8 -0
  48. package/dist/cjs/components/Alert/Alert.stories.js +53 -0
  49. package/dist/cjs/components/Button/ActionButton.d.ts +30 -0
  50. package/dist/cjs/components/Button/ActionButton.js +73 -0
  51. package/dist/cjs/components/Button/ActionButton.stories.d.ts +15 -0
  52. package/dist/cjs/components/Button/ActionButton.stories.js +113 -0
  53. package/dist/cjs/components/Button/Button.d.ts +54 -0
  54. package/dist/cjs/components/Button/Button.js +240 -0
  55. package/dist/cjs/components/Button/Button.stories.d.ts +17 -0
  56. package/dist/cjs/components/Button/Button.stories.js +135 -0
  57. package/dist/cjs/components/Button/Button.test.d.ts +1 -0
  58. package/dist/cjs/components/Button/Button.test.js +46 -0
  59. package/dist/cjs/components/ImageAdapter/ImageAdapter.d.ts +23 -0
  60. package/dist/cjs/components/ImageAdapter/ImageAdapter.js +30 -0
  61. package/dist/cjs/components/Input/Input.d.ts +116 -0
  62. package/dist/cjs/components/Input/Input.js +237 -0
  63. package/dist/cjs/components/Input/Input.stories.d.ts +19 -0
  64. package/dist/cjs/components/Input/Input.stories.js +135 -0
  65. package/dist/cjs/components/Input/Input.test.d.ts +1 -0
  66. package/dist/cjs/components/Input/Input.test.js +32 -0
  67. package/dist/cjs/components/LinkAdapter/LinkAdapter.d.ts +23 -0
  68. package/dist/cjs/components/LinkAdapter/LinkAdapter.js +34 -0
  69. package/dist/cjs/components/ScrollSnap/ScrollSnap.d.ts +19 -0
  70. package/dist/cjs/components/ScrollSnap/ScrollSnap.js +59 -0
  71. package/dist/cjs/components/ScrollSnap/ScrollSnap.stories.d.ts +6 -0
  72. package/dist/cjs/components/ScrollSnap/ScrollSnap.stories.js +43 -0
  73. package/dist/cjs/components/ScrollSnap/useScrollSnap.d.ts +6 -0
  74. package/dist/cjs/components/ScrollSnap/useScrollSnap.js +36 -0
  75. package/dist/cjs/components/SrAnnouncer/SrAnnouncer.d.ts +25 -0
  76. package/dist/cjs/components/SrAnnouncer/SrAnnouncer.js +43 -0
  77. package/dist/cjs/components/SrAnnouncer/SrAnnouncer.stories.d.ts +6 -0
  78. package/dist/cjs/components/SrAnnouncer/SrAnnouncer.stories.js +44 -0
  79. package/dist/cjs/components/SrAnnouncer/SrAnnouncer.test.d.ts +1 -0
  80. package/dist/cjs/components/SrAnnouncer/SrAnnouncer.test.js +62 -0
  81. package/dist/cjs/components/TabButtons/TabButtonList.d.ts +25 -0
  82. package/dist/cjs/components/TabButtons/TabButtonList.js +97 -0
  83. package/dist/cjs/components/TabButtons/TabButtonList.stories.d.ts +24 -0
  84. package/dist/cjs/components/TabButtons/TabButtonList.stories.js +139 -0
  85. package/dist/cjs/components/TextField/TextField.d.ts +29 -0
  86. package/dist/cjs/components/TextField/TextField.js +33 -0
  87. package/dist/cjs/components/TextField/TextField.stories.d.ts +10 -0
  88. package/dist/cjs/components/TextField/TextField.stories.js +136 -0
  89. package/dist/cjs/components/TextField/TextField.test.d.ts +1 -0
  90. package/dist/cjs/components/TextField/TextField.test.js +77 -0
  91. package/dist/cjs/components/ThemeProvider/ThemeProvider.d.ts +21 -0
  92. package/dist/cjs/components/ThemeProvider/ThemeProvider.js +86 -0
  93. package/dist/cjs/components/ThemeProvider/ThemeProvider.stories.d.ts +63 -0
  94. package/dist/cjs/components/ThemeProvider/ThemeProvider.stories.js +102 -0
  95. package/dist/cjs/components/ThemeProvider/Typography.stories.d.ts +39 -0
  96. package/dist/cjs/components/ThemeProvider/Typography.stories.js +65 -0
  97. package/dist/cjs/components/ThemeProvider/breakpoints.d.ts +4 -0
  98. package/dist/cjs/components/ThemeProvider/breakpoints.js +19 -0
  99. package/dist/cjs/components/ThemeProvider/buttons.d.ts +7 -0
  100. package/dist/cjs/components/ThemeProvider/buttons.js +20 -0
  101. package/dist/cjs/components/ThemeProvider/chips.d.ts +3 -0
  102. package/dist/cjs/components/ThemeProvider/chips.js +154 -0
  103. package/dist/cjs/components/ThemeProvider/colors.d.ts +32 -0
  104. package/dist/cjs/components/ThemeProvider/colors.js +35 -0
  105. package/dist/cjs/components/ThemeProvider/typography.d.ts +18 -0
  106. package/dist/cjs/components/ThemeProvider/typography.js +173 -0
  107. package/dist/cjs/components/VisuallyHidden/VisuallyHidden.d.ts +24 -0
  108. package/dist/cjs/components/VisuallyHidden/VisuallyHidden.js +33 -0
  109. package/dist/cjs/components/VisuallyHidden/VisuallyHidden.stories.d.ts +6 -0
  110. package/dist/cjs/components/VisuallyHidden/VisuallyHidden.stories.js +13 -0
  111. package/dist/cjs/components/internal/FormHelpers/FormHelpers.d.ts +39 -0
  112. package/dist/cjs/components/internal/FormHelpers/FormHelpers.js +78 -0
  113. package/dist/cjs/components/internal/FormHelpers/FormHelpers.test.d.ts +1 -0
  114. package/dist/cjs/components/internal/FormHelpers/FormHelpers.test.js +93 -0
  115. package/dist/cjs/index.d.ts +16 -0
  116. package/dist/cjs/index.js +30 -0
  117. package/dist/cjs/jest-setup.d.ts +1 -0
  118. package/dist/cjs/jest-setup.js +18 -0
  119. package/dist/cjs/jsdom-extended.d.ts +6 -0
  120. package/dist/cjs/jsdom-extended.js +14 -0
  121. package/dist/cjs/story-utils/index.d.ts +6 -0
  122. package/dist/cjs/story-utils/index.js +17 -0
  123. package/dist/cjs/utils/composeRefs.d.ts +7 -0
  124. package/dist/cjs/utils/composeRefs.js +20 -0
  125. package/dist/cjs/utils/composeRefs.test.d.ts +1 -0
  126. package/dist/cjs/utils/composeRefs.test.js +19 -0
  127. package/dist/cjs/utils/useDevCheckStable.d.ts +8 -0
  128. package/dist/cjs/utils/useDevCheckStable.js +29 -0
  129. package/dist/cjs/utils/useInterval.d.ts +7 -0
  130. package/dist/cjs/utils/useInterval.js +25 -0
  131. package/dist/esm/VERSION.d.ts +6 -0
  132. package/dist/esm/VERSION.js +6 -0
  133. package/dist/esm/ai.d.ts +3 -0
  134. package/dist/esm/ai.js +2 -0
  135. package/dist/esm/bundles/RemoteTutorDrawer/FlashcardsScreen.d.ts +9 -0
  136. package/dist/esm/bundles/RemoteTutorDrawer/FlashcardsScreen.js +83 -0
  137. package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.d.ts +56 -0
  138. package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.js +280 -0
  139. package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.stories.d.ts +17 -0
  140. package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.stories.js +299 -0
  141. package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.test.d.ts +1 -0
  142. package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.test.js +245 -0
  143. package/dist/esm/bundles/remoteTutorDrawer.d.ts +7 -0
  144. package/dist/esm/bundles/remoteTutorDrawer.js +40 -0
  145. package/dist/esm/components/AiChat/AiChat.d.ts +5 -0
  146. package/dist/esm/components/AiChat/AiChat.js +229 -0
  147. package/dist/esm/components/AiChat/AiChat.stories.d.ts +21 -0
  148. package/dist/esm/components/AiChat/AiChat.stories.js +254 -0
  149. package/dist/esm/components/AiChat/AiChat.test.d.ts +1 -0
  150. package/dist/esm/components/AiChat/AiChat.test.js +209 -0
  151. package/dist/esm/components/AiChat/AiChatContext.d.ts +26 -0
  152. package/dist/esm/components/AiChat/AiChatContext.js +101 -0
  153. package/dist/esm/components/AiChat/AiChatContext.stories.d.ts +14 -0
  154. package/dist/esm/components/AiChat/AiChatContext.stories.js +72 -0
  155. package/dist/esm/components/AiChat/ChatTitle.d.ts +8 -0
  156. package/dist/esm/components/AiChat/ChatTitle.js +40 -0
  157. package/dist/esm/components/AiChat/EntryScreen.d.ts +11 -0
  158. package/dist/esm/components/AiChat/EntryScreen.js +120 -0
  159. package/dist/esm/components/AiChat/Markdown.d.ts +7 -0
  160. package/dist/esm/components/AiChat/Markdown.js +12 -0
  161. package/dist/esm/components/AiChat/TimLogo.d.ts +5 -0
  162. package/dist/esm/components/AiChat/TimLogo.js +13 -0
  163. package/dist/esm/components/AiChat/test-utils/api.d.ts +2 -0
  164. package/dist/esm/components/AiChat/test-utils/api.js +161 -0
  165. package/dist/esm/components/AiChat/types.d.ts +91 -0
  166. package/dist/esm/components/AiChat/types.js +2 -0
  167. package/dist/esm/components/AiChat/utils.d.ts +9 -0
  168. package/dist/esm/components/AiChat/utils.js +38 -0
  169. package/dist/esm/components/Alert/Alert.d.ts +15 -0
  170. package/dist/esm/components/Alert/Alert.js +59 -0
  171. package/dist/esm/components/Alert/Alert.stories.d.ts +8 -0
  172. package/dist/esm/components/Alert/Alert.stories.js +50 -0
  173. package/dist/esm/components/Button/ActionButton.d.ts +30 -0
  174. package/dist/esm/components/Button/ActionButton.js +68 -0
  175. package/dist/esm/components/Button/ActionButton.stories.d.ts +15 -0
  176. package/dist/esm/components/Button/ActionButton.stories.js +110 -0
  177. package/dist/esm/components/Button/Button.d.ts +54 -0
  178. package/dist/esm/components/Button/Button.js +232 -0
  179. package/dist/esm/components/Button/Button.stories.d.ts +17 -0
  180. package/dist/esm/components/Button/Button.stories.js +132 -0
  181. package/dist/esm/components/Button/Button.test.d.ts +1 -0
  182. package/dist/esm/components/Button/Button.test.js +44 -0
  183. package/dist/esm/components/ImageAdapter/ImageAdapter.d.ts +23 -0
  184. package/dist/esm/components/ImageAdapter/ImageAdapter.js +27 -0
  185. package/dist/esm/components/Input/Input.d.ts +116 -0
  186. package/dist/esm/components/Input/Input.js +232 -0
  187. package/dist/esm/components/Input/Input.stories.d.ts +19 -0
  188. package/dist/esm/components/Input/Input.stories.js +132 -0
  189. package/dist/esm/components/Input/Input.test.d.ts +1 -0
  190. package/dist/esm/components/Input/Input.test.js +30 -0
  191. package/dist/esm/components/LinkAdapter/LinkAdapter.d.ts +23 -0
  192. package/dist/esm/components/LinkAdapter/LinkAdapter.js +31 -0
  193. package/dist/esm/components/ScrollSnap/ScrollSnap.d.ts +19 -0
  194. package/dist/esm/components/ScrollSnap/ScrollSnap.js +56 -0
  195. package/dist/esm/components/ScrollSnap/ScrollSnap.stories.d.ts +6 -0
  196. package/dist/esm/components/ScrollSnap/ScrollSnap.stories.js +40 -0
  197. package/dist/esm/components/ScrollSnap/useScrollSnap.d.ts +6 -0
  198. package/dist/esm/components/ScrollSnap/useScrollSnap.js +33 -0
  199. package/dist/esm/components/SrAnnouncer/SrAnnouncer.d.ts +25 -0
  200. package/dist/esm/components/SrAnnouncer/SrAnnouncer.js +40 -0
  201. package/dist/esm/components/SrAnnouncer/SrAnnouncer.stories.d.ts +6 -0
  202. package/dist/esm/components/SrAnnouncer/SrAnnouncer.stories.js +41 -0
  203. package/dist/esm/components/SrAnnouncer/SrAnnouncer.test.d.ts +1 -0
  204. package/dist/esm/components/SrAnnouncer/SrAnnouncer.test.js +60 -0
  205. package/dist/esm/components/TabButtons/TabButtonList.d.ts +25 -0
  206. package/dist/esm/components/TabButtons/TabButtonList.js +92 -0
  207. package/dist/esm/components/TabButtons/TabButtonList.stories.d.ts +24 -0
  208. package/dist/esm/components/TabButtons/TabButtonList.stories.js +136 -0
  209. package/dist/esm/components/TextField/TextField.d.ts +29 -0
  210. package/dist/esm/components/TextField/TextField.js +30 -0
  211. package/dist/esm/components/TextField/TextField.stories.d.ts +10 -0
  212. package/dist/esm/components/TextField/TextField.stories.js +133 -0
  213. package/dist/esm/components/TextField/TextField.test.d.ts +1 -0
  214. package/dist/esm/components/TextField/TextField.test.js +75 -0
  215. package/dist/esm/components/ThemeProvider/ThemeProvider.d.ts +21 -0
  216. package/dist/esm/components/ThemeProvider/ThemeProvider.js +82 -0
  217. package/dist/esm/components/ThemeProvider/ThemeProvider.stories.d.ts +63 -0
  218. package/dist/esm/components/ThemeProvider/ThemeProvider.stories.js +99 -0
  219. package/dist/esm/components/ThemeProvider/Typography.stories.d.ts +39 -0
  220. package/dist/esm/components/ThemeProvider/Typography.stories.js +62 -0
  221. package/dist/esm/components/ThemeProvider/breakpoints.d.ts +4 -0
  222. package/dist/esm/components/ThemeProvider/breakpoints.js +15 -0
  223. package/dist/esm/components/ThemeProvider/buttons.d.ts +7 -0
  224. package/dist/esm/components/ThemeProvider/buttons.js +17 -0
  225. package/dist/esm/components/ThemeProvider/chips.d.ts +3 -0
  226. package/dist/esm/components/ThemeProvider/chips.js +151 -0
  227. package/dist/esm/components/ThemeProvider/colors.d.ts +32 -0
  228. package/dist/esm/components/ThemeProvider/colors.js +32 -0
  229. package/dist/esm/components/ThemeProvider/typography.d.ts +18 -0
  230. package/dist/esm/components/ThemeProvider/typography.js +167 -0
  231. package/dist/esm/components/VisuallyHidden/VisuallyHidden.d.ts +24 -0
  232. package/dist/esm/components/VisuallyHidden/VisuallyHidden.js +30 -0
  233. package/dist/esm/components/VisuallyHidden/VisuallyHidden.stories.d.ts +6 -0
  234. package/dist/esm/components/VisuallyHidden/VisuallyHidden.stories.js +10 -0
  235. package/dist/esm/components/internal/FormHelpers/FormHelpers.d.ts +39 -0
  236. package/dist/esm/components/internal/FormHelpers/FormHelpers.js +73 -0
  237. package/dist/esm/components/internal/FormHelpers/FormHelpers.test.d.ts +1 -0
  238. package/dist/esm/components/internal/FormHelpers/FormHelpers.test.js +91 -0
  239. package/dist/esm/index.d.ts +16 -0
  240. package/dist/esm/index.js +11 -0
  241. package/dist/esm/jest-setup.d.ts +1 -0
  242. package/dist/esm/jest-setup.js +16 -0
  243. package/dist/esm/jsdom-extended.d.ts +6 -0
  244. package/dist/esm/jsdom-extended.js +12 -0
  245. package/dist/esm/story-utils/index.d.ts +6 -0
  246. package/dist/esm/story-utils/index.js +13 -0
  247. package/dist/esm/utils/composeRefs.d.ts +7 -0
  248. package/dist/esm/utils/composeRefs.js +17 -0
  249. package/dist/esm/utils/composeRefs.test.d.ts +1 -0
  250. package/dist/esm/utils/composeRefs.test.js +17 -0
  251. package/dist/esm/utils/useDevCheckStable.d.ts +8 -0
  252. package/dist/esm/utils/useDevCheckStable.js +26 -0
  253. package/dist/esm/utils/useInterval.d.ts +7 -0
  254. package/dist/esm/utils/useInterval.js +22 -0
  255. package/dist/tsconfig.tsbuildinfo +1 -0
  256. package/dist/type-augmentation/TypescriptDocs.mdx +17 -0
  257. package/dist/type-augmentation/imports.d.ts +3 -0
  258. package/dist/type-augmentation/index.d.ts +3 -0
  259. package/dist/type-augmentation/theme.d.ts +105 -0
  260. package/dist/type-augmentation/typography.d.ts +54 -0
  261. package/package.json +158 -0
@@ -0,0 +1,245 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { act, render, screen } from "@testing-library/react";
11
+ import user from "@testing-library/user-event";
12
+ import { RemoteTutorDrawer } from "./RemoteTutorDrawer";
13
+ import { ThemeProvider } from "../../components/ThemeProvider/ThemeProvider";
14
+ import * as React from "react";
15
+ import { http, HttpResponse } from "msw";
16
+ import { setupServer } from "msw/node";
17
+ jest.mock("../../components/AiChat/Markdown", () => {
18
+ return {
19
+ __esModule: true,
20
+ default: ({ children }) => React.createElement("div", null, children),
21
+ };
22
+ });
23
+ const TEST_API_STREAMING = "http://localhost:4567/test";
24
+ const CONTENT_FILE_URL = "http://localhost:4567/api/v1/contentfiles/1";
25
+ const CONTENT_RESPONSE = {
26
+ count: 1,
27
+ next: null,
28
+ previous: null,
29
+ results: [
30
+ {
31
+ id: 1,
32
+ summary: "This is a test summary",
33
+ flashcards: [
34
+ {
35
+ question: "Test question 1?",
36
+ answer: "Test answer 1",
37
+ },
38
+ {
39
+ question: "Test question 2?",
40
+ answer: "Test answer 2",
41
+ },
42
+ {
43
+ question: "Test question 3?",
44
+ answer: "Test answer 3",
45
+ },
46
+ ],
47
+ },
48
+ ],
49
+ };
50
+ class MockResizeObserver {
51
+ constructor() {
52
+ this.observe = jest.fn();
53
+ this.unobserve = jest.fn();
54
+ this.disconnect = jest.fn();
55
+ }
56
+ }
57
+ global.ResizeObserver = MockResizeObserver;
58
+ describe("RemoteTutorDrawer", () => {
59
+ const server = setupServer(http.post(TEST_API_STREAMING, () => __awaiter(void 0, void 0, void 0, function* () {
60
+ return HttpResponse.text("AI Response");
61
+ })), http.get(CONTENT_FILE_URL, () => {
62
+ return HttpResponse.json(CONTENT_RESPONSE);
63
+ }));
64
+ beforeEach(() => {
65
+ jest.resetAllMocks();
66
+ });
67
+ afterEach(() => {
68
+ server.resetHandlers();
69
+ });
70
+ afterAll(() => server.close());
71
+ const setup = (message) => __awaiter(void 0, void 0, void 0, function* () {
72
+ server.listen();
73
+ render(React.createElement(RemoteTutorDrawer, { "data-testid": "remote-tutor-drawer", messageOrigin: "http://localhost:6006", target: "ai-chat" }), { wrapper: ThemeProvider });
74
+ yield screen.findByTestId("remote-tutor-drawer-waiting");
75
+ const event = new MessageEvent("message", {
76
+ data: message,
77
+ origin: "http://localhost:6006",
78
+ });
79
+ yield act(() => __awaiter(void 0, void 0, void 0, function* () {
80
+ window.dispatchEvent(event);
81
+ yield new Promise((resolve) => setTimeout(resolve, 100));
82
+ }));
83
+ });
84
+ test("Problem drawer opens showing title", () => __awaiter(void 0, void 0, void 0, function* () {
85
+ yield setup({
86
+ type: "smoot-design::tutor-drawer-open",
87
+ payload: {
88
+ blockType: "problem",
89
+ target: "ai-chat",
90
+ title: "Drawer Title",
91
+ chat: {
92
+ apiUrl: TEST_API_STREAMING,
93
+ },
94
+ },
95
+ });
96
+ screen.getByRole("heading", { name: "Drawer Title" });
97
+ }));
98
+ test("Video drawer opens showing chat entry screen and tabs", () => __awaiter(void 0, void 0, void 0, function* () {
99
+ yield setup({
100
+ type: "smoot-design::tutor-drawer-open",
101
+ payload: {
102
+ blockType: "video",
103
+ target: "ai-chat",
104
+ chat: {
105
+ entryScreenTitle: "Entry screen title",
106
+ apiUrl: TEST_API_STREAMING,
107
+ conversationStarters: [
108
+ { content: "Prompt 1" },
109
+ { content: "Prompt 2" },
110
+ { content: "Prompt 3" },
111
+ ],
112
+ },
113
+ summary: {
114
+ apiUrl: CONTENT_FILE_URL,
115
+ },
116
+ },
117
+ });
118
+ screen.getByText("Entry screen title");
119
+ screen.getByRole("tab", { name: "Chat" });
120
+ screen.getByRole("tab", { name: "Flashcards" });
121
+ screen.getByRole("tab", { name: "Summary" });
122
+ screen.getByRole("button", { name: "Prompt 1" });
123
+ screen.getByRole("button", { name: "Prompt 2" });
124
+ screen.getByRole("button", { name: "Prompt 3" });
125
+ }));
126
+ test("Video drawer chat entry screen selects starters from flashcards", () => __awaiter(void 0, void 0, void 0, function* () {
127
+ yield setup({
128
+ type: "smoot-design::tutor-drawer-open",
129
+ payload: {
130
+ blockType: "video",
131
+ target: "ai-chat",
132
+ chat: {
133
+ entryScreenTitle: "Entry screen title",
134
+ apiUrl: TEST_API_STREAMING,
135
+ },
136
+ summary: {
137
+ apiUrl: CONTENT_FILE_URL,
138
+ },
139
+ },
140
+ });
141
+ screen.getByRole("button", { name: "Test question 1?" });
142
+ screen.getByRole("button", { name: "Test question 2?" });
143
+ screen.getByRole("button", { name: "Test question 3?" });
144
+ }));
145
+ test("Video drawer chat entry screen shows default starters where no flashcards are available", server.boundary(() => __awaiter(void 0, void 0, void 0, function* () {
146
+ const contentResponse = JSON.parse(JSON.stringify(CONTENT_RESPONSE));
147
+ contentResponse.results[0].flashcards = null;
148
+ server.use(http.get(CONTENT_FILE_URL, () => {
149
+ return HttpResponse.json(contentResponse);
150
+ }));
151
+ yield setup({
152
+ type: "smoot-design::tutor-drawer-open",
153
+ payload: {
154
+ blockType: "video",
155
+ target: "ai-chat",
156
+ chat: {
157
+ entryScreenTitle: "Entry screen title",
158
+ apiUrl: TEST_API_STREAMING,
159
+ },
160
+ summary: {
161
+ apiUrl: CONTENT_FILE_URL,
162
+ },
163
+ },
164
+ });
165
+ screen.getByRole("button", {
166
+ name: "What are the most important concepts introduced in the video?",
167
+ });
168
+ screen.getByRole("button", {
169
+ name: "What examples are used to illustrate concepts covered in the video?",
170
+ });
171
+ screen.getByRole("button", {
172
+ name: "What are the key terms introduced in this video?",
173
+ });
174
+ })));
175
+ test("Video drawer chat entry screen displays default title", () => __awaiter(void 0, void 0, void 0, function* () {
176
+ yield setup({
177
+ type: "smoot-design::tutor-drawer-open",
178
+ payload: {
179
+ blockType: "video",
180
+ target: "ai-chat",
181
+ chat: {
182
+ apiUrl: TEST_API_STREAMING,
183
+ },
184
+ summary: {
185
+ apiUrl: CONTENT_FILE_URL,
186
+ },
187
+ },
188
+ });
189
+ screen.getByText("What do you want to know about this video?");
190
+ }));
191
+ test("Flashcard shows content and can be click navigated", server.boundary(() => __awaiter(void 0, void 0, void 0, function* () {
192
+ yield setup({
193
+ type: "smoot-design::tutor-drawer-open",
194
+ payload: {
195
+ blockType: "video",
196
+ target: "ai-chat",
197
+ chat: {
198
+ apiUrl: TEST_API_STREAMING,
199
+ },
200
+ summary: {
201
+ apiUrl: CONTENT_FILE_URL,
202
+ },
203
+ },
204
+ });
205
+ yield user.click(screen.getByRole("tab", { name: "Flashcards" }));
206
+ yield user.click(screen.getByText("Q: Test question 1?"));
207
+ screen.getByText("Answer: Test answer 1");
208
+ yield user.click(screen.getByRole("button", { name: "Next card" }));
209
+ yield user.click(screen.getByText("Q: Test question 2?"));
210
+ screen.getByText("Answer: Test answer 2");
211
+ yield user.click(screen.getByRole("button", { name: "Previous card" }));
212
+ screen.getByText("Q: Test question 1?");
213
+ })));
214
+ test("Flashcard shows content and can be keyboard navigated and cycles", server.boundary(() => __awaiter(void 0, void 0, void 0, function* () {
215
+ yield setup({
216
+ type: "smoot-design::tutor-drawer-open",
217
+ payload: {
218
+ blockType: "video",
219
+ target: "ai-chat",
220
+ chat: {
221
+ apiUrl: TEST_API_STREAMING,
222
+ },
223
+ summary: {
224
+ apiUrl: CONTENT_FILE_URL,
225
+ },
226
+ },
227
+ });
228
+ yield user.click(screen.getByRole("tab", { name: "Flashcards" }));
229
+ screen.getByText("Q: Test question 1?");
230
+ yield user.keyboard("{enter}");
231
+ screen.getByText("Answer: Test answer 1");
232
+ yield user.keyboard("{arrowright}");
233
+ screen.getByText("Q: Test question 2?");
234
+ yield user.keyboard("{enter}");
235
+ screen.getByText("Answer: Test answer 2");
236
+ yield user.keyboard("{arrowleft}");
237
+ screen.getByText("Q: Test question 1?");
238
+ yield user.keyboard("{arrowleft}");
239
+ screen.getByText("Q: Test question 3?");
240
+ yield user.keyboard("{arrowright}");
241
+ yield user.keyboard("{arrowright}");
242
+ yield user.keyboard("{arrowright}");
243
+ screen.getByText("Q: Test question 3?");
244
+ })));
245
+ });
@@ -0,0 +1,7 @@
1
+ import type { RemoteTutorDrawerProps } from "./RemoteTutorDrawer/RemoteTutorDrawer";
2
+ /**
3
+ * Renders the RemoteTutorDrawer in an shadow DOM in order to isolate the drawer
4
+ * styles from external stylesheets.
5
+ */
6
+ declare const init: (opts: RemoteTutorDrawerProps) => void;
7
+ export { init };
@@ -0,0 +1,40 @@
1
+ import * as React from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import { RemoteTutorDrawer } from "./RemoteTutorDrawer/RemoteTutorDrawer";
4
+ import { ThemeProvider, createTheme, } from "../components/ThemeProvider/ThemeProvider";
5
+ import { CacheProvider } from "@emotion/react";
6
+ import createCache from "@emotion/cache";
7
+ import { MathJaxContext } from "better-react-mathjax";
8
+ /**
9
+ * Renders the RemoteTutorDrawer in an shadow DOM in order to isolate the drawer
10
+ * styles from external stylesheets.
11
+ */
12
+ const init = (opts) => {
13
+ const container = document.createElement("div");
14
+ document.body.appendChild(container);
15
+ const shadowContainer = container.attachShadow({ mode: "open" });
16
+ const shadowRootEl = document.createElement("div");
17
+ shadowRootEl.id = "smoot-chat-drawer-root";
18
+ shadowContainer.append(shadowRootEl);
19
+ // See https://mui.com/material-ui/customization/shadow-dom/
20
+ // Ensure style tags are rendered in shadow root
21
+ const cache = createCache({
22
+ key: "css",
23
+ prepend: true,
24
+ container: shadowContainer,
25
+ });
26
+ const theme = createTheme({
27
+ components: {
28
+ // Ensure modals, etc, are rendered in shadow root
29
+ MuiPopover: { defaultProps: { container: shadowRootEl } },
30
+ MuiPopper: { defaultProps: { container: shadowRootEl } },
31
+ MuiModal: { defaultProps: { container: shadowRootEl } },
32
+ },
33
+ });
34
+ createRoot(shadowRootEl).render(React.createElement(CacheProvider, { value: cache },
35
+ React.createElement(ThemeProvider, { theme: theme },
36
+ React.createElement(MathJaxContext, null,
37
+ React.createElement(RemoteTutorDrawer, Object.assign({}, opts))),
38
+ ",")));
39
+ };
40
+ export { init };
@@ -0,0 +1,5 @@
1
+ import type { FC } from "react";
2
+ import type { AiChatDisplayProps, AiChatProps } from "./types";
3
+ declare const AiChatDisplay: FC<AiChatDisplayProps>;
4
+ declare const AiChat: FC<AiChatProps>;
5
+ export { AiChatDisplay, AiChat };
@@ -0,0 +1,229 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import * as React from "react";
13
+ import { useEffect, useRef, useState } from "react";
14
+ import styled from "@emotion/styled";
15
+ import Typography from "@mui/material/Typography";
16
+ import classNames from "classnames";
17
+ import { RiSendPlaneFill, RiStopFill, RiMoreFill } from "@remixicon/react";
18
+ import { Input, AdornmentButton } from "../Input/Input";
19
+ import { EntryScreen } from "./EntryScreen";
20
+ import { ScrollSnap } from "../ScrollSnap/ScrollSnap";
21
+ import { SrAnnouncer } from "../SrAnnouncer/SrAnnouncer";
22
+ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden";
23
+ import { Alert } from "../Alert/Alert";
24
+ import { ChatTitle } from "./ChatTitle";
25
+ import { AiChatProvider, useAiChat } from "./AiChatContext";
26
+ import { useScrollSnap } from "../ScrollSnap/useScrollSnap";
27
+ import Markdown from "./Markdown";
28
+ const classes = {
29
+ root: "MitAiChat--root",
30
+ title: "MitAiChat--title",
31
+ entryScreenContainer: "MitAiChat--entryScreenContainer",
32
+ conversationStarter: "MitAiChat--conversationStarter",
33
+ chatScreenContainer: "MitAiChat--chatScreenContainer",
34
+ messagesContainer: "MitAiChat--messagesContainer",
35
+ messageRow: "MitAiChat--messageRow",
36
+ messageRowUser: "MitAiChat--messageRowUser",
37
+ messageRowAssistant: "MitAiChat--messageRowAssistant",
38
+ message: "MitAiChat--message",
39
+ input: "MitAiChat--input",
40
+ bottomSection: "MitAiChat--bottomSection",
41
+ };
42
+ const Container = styled.div();
43
+ const ChatScreen = styled.div(({ externalScroll, theme }) => (Object.assign({ padding: "16px 32px 0", [theme.breakpoints.down("md")]: {
44
+ padding: "16px 16px 0",
45
+ }, boxSizing: "border-box", background: "white", position: "absolute", bottom: 0, top: 0, left: 0, right: 0, zIndex: 1 }, (externalScroll && {
46
+ padding: "0 32px",
47
+ [theme.breakpoints.down("md")]: {
48
+ padding: "0 16px",
49
+ },
50
+ }))));
51
+ const ChatContainer = styled.div(({ externalScroll }) => ({
52
+ width: "100%",
53
+ height: externalScroll ? "auto" : "100%",
54
+ minHeight: externalScroll ? "100%" : "auto",
55
+ display: "flex",
56
+ flexDirection: "column",
57
+ }));
58
+ const MessagesContainer = styled(ScrollSnap)(({ externalScroll }) => ({
59
+ display: "flex",
60
+ flexDirection: "column",
61
+ flex: 1,
62
+ padding: "14px 0",
63
+ overflow: externalScroll ? "visible" : "auto",
64
+ gap: "16px",
65
+ [`> .${classes.messageRowAssistant}:first-child`]: {
66
+ marginTop: "16px",
67
+ },
68
+ }));
69
+ const MessageRow = styled.div({
70
+ display: "flex",
71
+ width: "100%",
72
+ gap: "10px",
73
+ [`&.${classes.messageRowUser}`]: {
74
+ flexDirection: "row-reverse",
75
+ },
76
+ "> *": {
77
+ minWidth: 0,
78
+ },
79
+ position: "relative",
80
+ });
81
+ const Message = styled.div(({ theme }) => (Object.assign(Object.assign({ color: theme.custom.colors.darkGray2, backgroundColor: theme.custom.colors.white }, theme.typography.body2), { "p:first-of-type": {
82
+ marginTop: 0,
83
+ }, "p:last-of-type": {
84
+ marginBottom: 0,
85
+ }, "ol, ul": {
86
+ paddingInlineStart: "16px",
87
+ marginLeft: "6px",
88
+ "ol, ul": {
89
+ marginLeft: 0,
90
+ },
91
+ li: {
92
+ margin: "16px 0",
93
+ },
94
+ }, a: {
95
+ color: theme.custom.colors.red,
96
+ fontWeight: "normal",
97
+ }, borderRadius: "12px", [`.${classes.messageRowUser} &`]: {
98
+ padding: "12px 16px",
99
+ borderRadius: "8px 0px 8px 8px",
100
+ backgroundColor: theme.custom.colors.lightGray1,
101
+ } })));
102
+ const StarterContainer = styled.div({
103
+ alignSelf: "flex-end",
104
+ alignItems: "end",
105
+ display: "flex",
106
+ flexDirection: "column",
107
+ gap: "12px",
108
+ });
109
+ const Starter = styled.button(({ theme }) => (Object.assign(Object.assign({ border: `1px solid ${theme.custom.colors.lightGray2}`, backgroundColor: theme.custom.colors.white, padding: "8px 16px" }, theme.typography.body3), { cursor: "pointer", boxSizing: "border-box", "&:hover": {
110
+ color: theme.custom.colors.white,
111
+ backgroundColor: theme.custom.colors.silverGrayDark,
112
+ borderColor: "transparent",
113
+ }, borderRadius: "8px" })));
114
+ const StyledSendButton = styled(RiSendPlaneFill)(({ theme }) => ({
115
+ fill: theme.custom.colors.red,
116
+ }));
117
+ const StyledStopButton = styled(RiStopFill)(({ theme }) => ({
118
+ fill: theme.custom.colors.red,
119
+ }));
120
+ const BottomSection = styled.div(({ externalScroll, theme }) => (Object.assign(Object.assign({ padding: "12px 0 16px" }, (externalScroll && {
121
+ position: "sticky",
122
+ bottom: 0,
123
+ background: theme.custom.colors.white,
124
+ })), { "button:focus-visible": {
125
+ outlineOffset: "-1px",
126
+ borderRadius: "7px",
127
+ } })));
128
+ const Disclaimer = styled(Typography)(({ theme }) => ({
129
+ color: theme.custom.colors.silverGrayDark,
130
+ marginTop: "16px",
131
+ textAlign: "center",
132
+ }));
133
+ const AiChatDisplay = (_a) => {
134
+ var _b, _c;
135
+ var { conversationStarters, askTimTitle, entryScreenEnabled = true, entryScreenTitle, srLoadingMessages, placeholder = "", className, scrollElement, ref, useMathJax = false } = _a, others = __rest(_a, ["conversationStarters", "askTimTitle", "entryScreenEnabled", "entryScreenTitle", "srLoadingMessages", "placeholder", "className", "scrollElement", "ref", "useMathJax"]) // Could contain data attributes
136
+ ;
137
+ const containerRef = useRef(null);
138
+ const messagesContainerRef = useRef(null);
139
+ const chatScreenRef = useRef(null);
140
+ const promptInputRef = useRef(null);
141
+ const { messages, input, handleInputChange, handleSubmit, append, isLoading, stop, error, initialMessages, } = useAiChat();
142
+ useScrollSnap({
143
+ scrollElement: scrollElement || messagesContainerRef.current,
144
+ contentElement: scrollElement ? messagesContainerRef.current : null,
145
+ threshold: 200,
146
+ });
147
+ const [showEntryScreen, setShowEntryScreen] = useState(entryScreenEnabled);
148
+ useEffect(() => {
149
+ var _a, _b;
150
+ if (!showEntryScreen) {
151
+ (_b = (_a = promptInputRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("input")) === null || _b === void 0 ? void 0 : _b.focus();
152
+ }
153
+ }, [showEntryScreen]);
154
+ const showStarters = messages.length === ((initialMessages === null || initialMessages === void 0 ? void 0 : initialMessages.length) || 0);
155
+ const waiting = !showStarters && !error && ((_b = messages[messages.length - 1]) === null || _b === void 0 ? void 0 : _b.role) === "user";
156
+ const stoppable = isLoading && ((_c = messages[messages.length - 1]) === null || _c === void 0 ? void 0 : _c.role) !== "user";
157
+ const scrollToBottom = () => {
158
+ const element = scrollElement || messagesContainerRef.current;
159
+ element === null || element === void 0 ? void 0 : element.scrollBy({
160
+ behavior: "instant",
161
+ top: element === null || element === void 0 ? void 0 : element.scrollHeight,
162
+ });
163
+ };
164
+ const lastMsg = messages[messages.length - 1];
165
+ const externalScroll = !!scrollElement;
166
+ return (React.createElement(Container, { className: className, ref: containerRef }, showEntryScreen ? (React.createElement(EntryScreen, { className: classes.entryScreenContainer, title: entryScreenTitle, conversationStarters: conversationStarters, onPromptSubmit: (prompt) => {
167
+ if (prompt.trim() === "") {
168
+ return;
169
+ }
170
+ setShowEntryScreen(false);
171
+ append({ role: "user", content: prompt });
172
+ } })) : (React.createElement(ChatScreen, { className: classes.chatScreenContainer, "data-testid": "ai-chat-screen", externalScroll: externalScroll, ref: chatScreenRef },
173
+ React.createElement(ChatContainer, Object.assign({ className: classNames(className, classes.root), externalScroll: externalScroll }, others),
174
+ React.createElement(ChatTitle, { askTimTitle: askTimTitle, externalScroll: externalScroll, className: classNames(className, classes.title) }),
175
+ React.createElement(MessagesContainer, { className: classes.messagesContainer, externalScroll: externalScroll, ref: messagesContainerRef },
176
+ messages.map((m, i) => {
177
+ // Our Markdown+Mathjax has issues when rendering streaming display math
178
+ // Force a re-render of the last (streaming) message when it's done loading.
179
+ const key = i === messages.length - 1 && isLoading
180
+ ? `isLoading-${m.id}`
181
+ : m.id;
182
+ return (React.createElement(MessageRow, { key: key, "data-chat-role": m.role, className: classNames(classes.messageRow, {
183
+ [classes.messageRowUser]: m.role === "user",
184
+ [classes.messageRowAssistant]: m.role === "assistant",
185
+ }) },
186
+ React.createElement(Message, { className: classes.message },
187
+ React.createElement(VisuallyHidden, { as: m.role === "user" ? "h5" : "h6" }, m.role === "user" ? "You said: " : "Assistant said: "),
188
+ React.createElement(Markdown, { enableMathjax: useMathJax }, m.content))));
189
+ }),
190
+ showStarters ? (React.createElement(StarterContainer, null, conversationStarters === null || conversationStarters === void 0 ? void 0 : conversationStarters.map((m) => (React.createElement(Starter, { className: classes.conversationStarter, key: m.content, onClick: () => {
191
+ scrollToBottom();
192
+ append({ role: "user", content: m.content });
193
+ } }, m.content))))) : null,
194
+ waiting ? (React.createElement(MessageRow, { className: classNames(classes.messageRow, classes.messageRowAssistant), key: "loading" },
195
+ React.createElement(Message, null,
196
+ React.createElement(RiMoreFill, null)))) : null,
197
+ error ? (React.createElement(Alert, { severity: "error", closable: true }, "An unexpected error has occurred.")) : null),
198
+ React.createElement(BottomSection, { externalScroll: externalScroll, className: classes.bottomSection },
199
+ React.createElement("form", { onSubmit: (e) => {
200
+ e.preventDefault();
201
+ if (isLoading && stoppable) {
202
+ stop();
203
+ }
204
+ else {
205
+ scrollToBottom();
206
+ handleSubmit(e);
207
+ }
208
+ } },
209
+ React.createElement(Input, { ref: promptInputRef, fullWidth: true, size: "chat", className: classes.input, placeholder: placeholder, name: "message", sx: { flex: 1 }, value: input, onChange: handleInputChange, inputProps: {
210
+ "aria-label": "Ask a question",
211
+ }, endAdornment: isLoading ? (React.createElement(AdornmentButton, { "aria-label": "Stop", onClick: stop, disabled: !stoppable },
212
+ React.createElement(StyledStopButton, null))) : (React.createElement(AdornmentButton, { "aria-label": "Send", type: "submit", onClick: (e) => {
213
+ if (input.trim() === "") {
214
+ e.preventDefault();
215
+ return;
216
+ }
217
+ scrollToBottom();
218
+ handleSubmit(e);
219
+ } },
220
+ React.createElement(StyledSendButton, null))) })),
221
+ React.createElement(Disclaimer, { variant: "body3" }, "AI-generated content may be incorrect.")),
222
+ React.createElement(SrAnnouncer, { isLoading: isLoading, loadingMessages: srLoadingMessages, message: (lastMsg === null || lastMsg === void 0 ? void 0 : lastMsg.role) === "assistant" ? lastMsg === null || lastMsg === void 0 ? void 0 : lastMsg.content : "" }))))));
223
+ };
224
+ const AiChat = (_a) => {
225
+ var { requestOpts, initialMessages, chatId, parseContent } = _a, displayProps = __rest(_a, ["requestOpts", "initialMessages", "chatId", "parseContent"]);
226
+ return (React.createElement(AiChatProvider, { requestOpts: requestOpts, chatId: chatId, initialMessages: initialMessages, parseContent: parseContent },
227
+ React.createElement(AiChatDisplay, Object.assign({}, displayProps))));
228
+ };
229
+ export { AiChatDisplay, AiChat };
@@ -0,0 +1,21 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { AiChat } from "./AiChat";
3
+ declare const meta: Meta<typeof AiChat>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof AiChat>;
6
+ export declare const StreamingResponses: Story;
7
+ /**
8
+ * Here `AiChat` is used with a non-streaming JSON API. The JSON is converted
9
+ * to text via `parseContent`.
10
+ */
11
+ export declare const JsonResponses: Story;
12
+ /**
13
+ * This story shows the component's builtin markdown styling.
14
+ */
15
+ export declare const MarkdownStyling: Story;
16
+ /**
17
+ * Where a scrollable container exists in the including component, it can be passed in
18
+ * for the AiChat component to use in place of its own height constrained message container
19
+ * overflow scroll. This is useful for cases such as use inside a modal or drawer.
20
+ */
21
+ export declare const ScrollContainer: Story;