@mitodl/smoot-design 3.5.0 → 3.7.0

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.
@@ -1,4 +1,5 @@
1
1
  import * as React from "react";
2
+ import { AiChatMessage } from "../../components/AiChat/types";
2
3
  import type { AiChatProps } from "../../components/AiChat/AiChat";
3
4
  type ChatInitMessage = {
4
5
  type: "smoot-design::chat-open";
@@ -8,6 +9,7 @@ type ChatInitMessage = {
8
9
  conversationStarters?: AiChatProps["conversationStarters"];
9
10
  initialMessages: AiChatProps["initialMessages"];
10
11
  apiUrl: AiChatProps["requestOpts"]["apiUrl"];
12
+ requestBody?: Record<string, unknown>;
11
13
  };
12
14
  };
13
15
  type AiChatDrawerProps = {
@@ -19,9 +21,20 @@ type AiChatDrawerProps = {
19
21
  messageOrigin: string;
20
22
  /**
21
23
  * Transform the body of the request before sending it to the server.
24
+ * Its result will be merged with the per-message requestBody opt, with
25
+ * transformBody taking precedence.
26
+ *
22
27
  * *This cannot be supplied via message events since the function is not serializable.*
28
+ *
23
29
  */
24
- transformBody?: AiChatProps["requestOpts"]["transformBody"];
30
+ transformBody?: (messages: AiChatMessage[]) => Iterable<unknown>;
31
+ /**
32
+ * Fetch options to be passed to the fetch call.
33
+ *
34
+ * NOTE: By default, the credentials are set to "include" to enable thread-
35
+ * identifying cookies.
36
+ */
37
+ fetchOpts?: AiChatProps["requestOpts"]["fetchOpts"];
25
38
  };
26
39
  declare const AiChatDrawer: React.FC<AiChatDrawerProps>;
27
40
  export { AiChatDrawer };
@@ -4,7 +4,11 @@ exports.AiChatDrawer = void 0;
4
4
  const React = require("react");
5
5
  const AiChat_1 = require("../../components/AiChat/AiChat");
6
6
  const Drawer_1 = require("@mui/material/Drawer");
7
- const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
7
+ const identity = (x) => x;
8
+ const DEFAULT_FETCH_OPTS = {
9
+ credentials: "include",
10
+ };
11
+ const AiChatDrawer = ({ messageOrigin, transformBody = identity, className, fetchOpts, }) => {
8
12
  const [open, setOpen] = React.useState(false);
9
13
  const [chatSettings, setChatSettings] = React.useState(null);
10
14
  React.useEffect(() => {
@@ -20,7 +24,6 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
20
24
  setChatSettings(event.data.payload);
21
25
  }
22
26
  };
23
- console.log("Attaching listener");
24
27
  window.addEventListener("message", cb);
25
28
  return () => {
26
29
  window.removeEventListener("message", cb);
@@ -28,7 +31,7 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
28
31
  }, [messageOrigin]);
29
32
  return (React.createElement(Drawer_1.default, { className: className, PaperProps: {
30
33
  sx: {
31
- width: "600px",
34
+ width: "900px",
32
35
  maxWidth: "100%",
33
36
  boxSizing: "border-box",
34
37
  padding: "24px 40px",
@@ -37,8 +40,11 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
37
40
  },
38
41
  },
39
42
  }, anchor: "right", open: open, onClose: () => setOpen(false) }, chatSettings ? (React.createElement(AiChat_1.AiChat, Object.assign({}, chatSettings, { requestOpts: {
40
- transformBody,
43
+ transformBody: (messages) => {
44
+ return Object.assign(Object.assign({}, chatSettings.requestBody), transformBody === null || transformBody === void 0 ? void 0 : transformBody(messages));
45
+ },
41
46
  apiUrl: chatSettings === null || chatSettings === void 0 ? void 0 : chatSettings.apiUrl,
47
+ fetchOpts: Object.assign(Object.assign({}, DEFAULT_FETCH_OPTS), fetchOpts),
42
48
  }, onClose: () => setOpen(false) }))) : null));
43
49
  };
44
50
  exports.AiChatDrawer = AiChatDrawer;
@@ -1,3 +1,7 @@
1
1
  import type { AiChatDrawerProps } from "./RemoteAiChatDrawer/RemoteAiChatDrawer";
2
+ /**
3
+ * Renders the AiChatDrawer in an shadow DOM in order to isolate the drawer
4
+ * styles from external stylesheets.
5
+ */
2
6
  declare const init: (opts: AiChatDrawerProps) => void;
3
7
  export { init };
@@ -5,11 +5,36 @@ const React = require("react");
5
5
  const client_1 = require("react-dom/client");
6
6
  const RemoteAiChatDrawer_1 = require("./RemoteAiChatDrawer/RemoteAiChatDrawer");
7
7
  const ThemeProvider_1 = require("../components/ThemeProvider/ThemeProvider");
8
+ const react_1 = require("@emotion/react");
9
+ const cache_1 = require("@emotion/cache");
10
+ /**
11
+ * Renders the AiChatDrawer in an shadow DOM in order to isolate the drawer
12
+ * styles from external stylesheets.
13
+ */
8
14
  const init = (opts) => {
9
- const root = document.createElement("div");
10
- root.id = "smoot-chat-drawer-root";
11
- document.body.append(root);
12
- (0, client_1.createRoot)(root).render(React.createElement(ThemeProvider_1.ThemeProvider, null,
13
- React.createElement(RemoteAiChatDrawer_1.AiChatDrawer, Object.assign({}, opts))));
15
+ const container = document.createElement("div");
16
+ document.body.appendChild(container);
17
+ const shadowContainer = container.attachShadow({ mode: "open" });
18
+ const shadowRootEl = document.createElement("div");
19
+ shadowRootEl.id = "smoot-chat-drawer-root";
20
+ shadowContainer.append(shadowRootEl);
21
+ // See https://mui.com/material-ui/customization/shadow-dom/
22
+ // Ensure style tags are rendered in shadow root
23
+ const cache = (0, cache_1.default)({
24
+ key: "css",
25
+ prepend: true,
26
+ container: shadowContainer,
27
+ });
28
+ const theme = (0, ThemeProvider_1.createTheme)({
29
+ components: {
30
+ // Ensure modals, etc, are rendered in shadow root
31
+ MuiPopover: { defaultProps: { container: shadowRootEl } },
32
+ MuiPopper: { defaultProps: { container: shadowRootEl } },
33
+ MuiModal: { defaultProps: { container: shadowRootEl } },
34
+ },
35
+ });
36
+ (0, client_1.createRoot)(shadowRootEl).render(React.createElement(react_1.CacheProvider, { value: cache },
37
+ React.createElement(ThemeProvider_1.ThemeProvider, { theme: theme },
38
+ React.createElement(RemoteAiChatDrawer_1.AiChatDrawer, Object.assign({}, opts)))));
14
39
  };
15
40
  exports.init = init;
@@ -1,4 +1,5 @@
1
1
  import * as React from "react";
2
+ import { AiChatMessage } from "../../components/AiChat/types";
2
3
  import type { AiChatProps } from "../../components/AiChat/AiChat";
3
4
  type ChatInitMessage = {
4
5
  type: "smoot-design::chat-open";
@@ -8,6 +9,7 @@ type ChatInitMessage = {
8
9
  conversationStarters?: AiChatProps["conversationStarters"];
9
10
  initialMessages: AiChatProps["initialMessages"];
10
11
  apiUrl: AiChatProps["requestOpts"]["apiUrl"];
12
+ requestBody?: Record<string, unknown>;
11
13
  };
12
14
  };
13
15
  type AiChatDrawerProps = {
@@ -19,9 +21,20 @@ type AiChatDrawerProps = {
19
21
  messageOrigin: string;
20
22
  /**
21
23
  * Transform the body of the request before sending it to the server.
24
+ * Its result will be merged with the per-message requestBody opt, with
25
+ * transformBody taking precedence.
26
+ *
22
27
  * *This cannot be supplied via message events since the function is not serializable.*
28
+ *
23
29
  */
24
- transformBody?: AiChatProps["requestOpts"]["transformBody"];
30
+ transformBody?: (messages: AiChatMessage[]) => Iterable<unknown>;
31
+ /**
32
+ * Fetch options to be passed to the fetch call.
33
+ *
34
+ * NOTE: By default, the credentials are set to "include" to enable thread-
35
+ * identifying cookies.
36
+ */
37
+ fetchOpts?: AiChatProps["requestOpts"]["fetchOpts"];
25
38
  };
26
39
  declare const AiChatDrawer: React.FC<AiChatDrawerProps>;
27
40
  export { AiChatDrawer };
@@ -1,7 +1,11 @@
1
1
  import * as React from "react";
2
2
  import { AiChat } from "../../components/AiChat/AiChat";
3
3
  import Drawer from "@mui/material/Drawer";
4
- const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
4
+ const identity = (x) => x;
5
+ const DEFAULT_FETCH_OPTS = {
6
+ credentials: "include",
7
+ };
8
+ const AiChatDrawer = ({ messageOrigin, transformBody = identity, className, fetchOpts, }) => {
5
9
  const [open, setOpen] = React.useState(false);
6
10
  const [chatSettings, setChatSettings] = React.useState(null);
7
11
  React.useEffect(() => {
@@ -17,7 +21,6 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
17
21
  setChatSettings(event.data.payload);
18
22
  }
19
23
  };
20
- console.log("Attaching listener");
21
24
  window.addEventListener("message", cb);
22
25
  return () => {
23
26
  window.removeEventListener("message", cb);
@@ -25,7 +28,7 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
25
28
  }, [messageOrigin]);
26
29
  return (React.createElement(Drawer, { className: className, PaperProps: {
27
30
  sx: {
28
- width: "600px",
31
+ width: "900px",
29
32
  maxWidth: "100%",
30
33
  boxSizing: "border-box",
31
34
  padding: "24px 40px",
@@ -34,8 +37,11 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
34
37
  },
35
38
  },
36
39
  }, anchor: "right", open: open, onClose: () => setOpen(false) }, chatSettings ? (React.createElement(AiChat, Object.assign({}, chatSettings, { requestOpts: {
37
- transformBody,
40
+ transformBody: (messages) => {
41
+ return Object.assign(Object.assign({}, chatSettings.requestBody), transformBody === null || transformBody === void 0 ? void 0 : transformBody(messages));
42
+ },
38
43
  apiUrl: chatSettings === null || chatSettings === void 0 ? void 0 : chatSettings.apiUrl,
44
+ fetchOpts: Object.assign(Object.assign({}, DEFAULT_FETCH_OPTS), fetchOpts),
39
45
  }, onClose: () => setOpen(false) }))) : null));
40
46
  };
41
47
  export { AiChatDrawer };
@@ -1,3 +1,7 @@
1
1
  import type { AiChatDrawerProps } from "./RemoteAiChatDrawer/RemoteAiChatDrawer";
2
+ /**
3
+ * Renders the AiChatDrawer in an shadow DOM in order to isolate the drawer
4
+ * styles from external stylesheets.
5
+ */
2
6
  declare const init: (opts: AiChatDrawerProps) => void;
3
7
  export { init };
@@ -1,12 +1,37 @@
1
1
  import * as React from "react";
2
2
  import { createRoot } from "react-dom/client";
3
3
  import { AiChatDrawer } from "./RemoteAiChatDrawer/RemoteAiChatDrawer";
4
- import { ThemeProvider } from "../components/ThemeProvider/ThemeProvider";
4
+ import { ThemeProvider, createTheme, } from "../components/ThemeProvider/ThemeProvider";
5
+ import { CacheProvider } from "@emotion/react";
6
+ import createCache from "@emotion/cache";
7
+ /**
8
+ * Renders the AiChatDrawer in an shadow DOM in order to isolate the drawer
9
+ * styles from external stylesheets.
10
+ */
5
11
  const init = (opts) => {
6
- const root = document.createElement("div");
7
- root.id = "smoot-chat-drawer-root";
8
- document.body.append(root);
9
- createRoot(root).render(React.createElement(ThemeProvider, null,
10
- React.createElement(AiChatDrawer, Object.assign({}, opts))));
12
+ const container = document.createElement("div");
13
+ document.body.appendChild(container);
14
+ const shadowContainer = container.attachShadow({ mode: "open" });
15
+ const shadowRootEl = document.createElement("div");
16
+ shadowRootEl.id = "smoot-chat-drawer-root";
17
+ shadowContainer.append(shadowRootEl);
18
+ // See https://mui.com/material-ui/customization/shadow-dom/
19
+ // Ensure style tags are rendered in shadow root
20
+ const cache = createCache({
21
+ key: "css",
22
+ prepend: true,
23
+ container: shadowContainer,
24
+ });
25
+ const theme = createTheme({
26
+ components: {
27
+ // Ensure modals, etc, are rendered in shadow root
28
+ MuiPopover: { defaultProps: { container: shadowRootEl } },
29
+ MuiPopper: { defaultProps: { container: shadowRootEl } },
30
+ MuiModal: { defaultProps: { container: shadowRootEl } },
31
+ },
32
+ });
33
+ createRoot(shadowRootEl).render(React.createElement(CacheProvider, { value: cache },
34
+ React.createElement(ThemeProvider, { theme: theme },
35
+ React.createElement(AiChatDrawer, Object.assign({}, opts)))));
11
36
  };
12
37
  export { init };