@mitodl/smoot-design 3.4.1 → 3.6.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,13 @@ 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>;
25
31
  };
26
32
  declare const AiChatDrawer: React.FC<AiChatDrawerProps>;
27
33
  export { AiChatDrawer };
@@ -4,7 +4,8 @@ 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 AiChatDrawer = ({ messageOrigin, transformBody = identity, className, }) => {
8
9
  const [open, setOpen] = React.useState(false);
9
10
  const [chatSettings, setChatSettings] = React.useState(null);
10
11
  React.useEffect(() => {
@@ -20,7 +21,6 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
20
21
  setChatSettings(event.data.payload);
21
22
  }
22
23
  };
23
- console.log("Attaching listener");
24
24
  window.addEventListener("message", cb);
25
25
  return () => {
26
26
  window.removeEventListener("message", cb);
@@ -37,7 +37,9 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
37
37
  },
38
38
  },
39
39
  }, anchor: "right", open: open, onClose: () => setOpen(false) }, chatSettings ? (React.createElement(AiChat_1.AiChat, Object.assign({}, chatSettings, { requestOpts: {
40
- transformBody,
40
+ transformBody: (messages) => {
41
+ return Object.assign(Object.assign({}, chatSettings.requestBody), transformBody === null || transformBody === void 0 ? void 0 : transformBody(messages));
42
+ },
41
43
  apiUrl: chatSettings === null || chatSettings === void 0 ? void 0 : chatSettings.apiUrl,
42
44
  }, onClose: () => setOpen(false) }))) : null));
43
45
  };
@@ -35,6 +35,7 @@ const classes = {
35
35
  messageRowAssistant: "MitAiChat--messageRowAssistant",
36
36
  message: "MitAiChat--message",
37
37
  input: "MitAiChat--input",
38
+ bottomSection: "MitAiChat--bottomSection",
38
39
  };
39
40
  const ChatContainer = styled_1.default.div({
40
41
  width: "100%",
@@ -67,10 +68,9 @@ const MessagesContainer = (0, styled_1.default)(ScrollSnap_1.ScrollSnap)({
67
68
  display: "flex",
68
69
  flexDirection: "column",
69
70
  flex: 1,
70
- paddingTop: "14px",
71
- paddingBottom: "24px",
71
+ padding: "14px 0",
72
72
  overflow: "auto",
73
- gap: "24px",
73
+ gap: "16px",
74
74
  });
75
75
  const MessageRow = styled_1.default.div({
76
76
  display: "flex",
@@ -88,16 +88,18 @@ const Message = styled_1.default.div(({ theme }) => (Object.assign(Object.assign
88
88
  marginTop: 0,
89
89
  }, "p:last-of-type": {
90
90
  marginBottom: 0,
91
+ }, "ol, ul": {
92
+ paddingInlineStart: "32px",
93
+ li: {
94
+ margin: "16px 0",
95
+ },
96
+ }, ul: {
97
+ marginInlineStart: "-16px",
91
98
  }, a: {
92
99
  color: theme.custom.colors.red,
93
100
  fontWeight: "normal",
94
101
  }, borderRadius: "12px", [`.${classes.messageRowAssistant} &`]: {
95
- border: `1px solid ${theme.custom.colors.lightGray2}`,
96
- borderRadius: "0px 8px 8px 8px",
97
- svg: {
98
- fill: theme.custom.colors.silverGrayDark,
99
- display: "block",
100
- },
102
+ padding: "12px 16px 12px 0",
101
103
  }, [`.${classes.messageRowUser} &`]: {
102
104
  borderRadius: "8px 0px 8px 8px",
103
105
  backgroundColor: theme.custom.colors.lightGray1,
@@ -118,20 +120,18 @@ const RobotIcon = (0, styled_1.default)(react_1.RiRobot2Line)({
118
120
  width: "40px",
119
121
  height: "40px",
120
122
  });
121
- const StyledInput = (0, styled_1.default)(Input_1.Input)(({ theme }) => ({
122
- backgroundColor: theme.custom.colors.lightGray1,
123
- borderRadius: "8px",
124
- border: `1px solid ${theme.custom.colors.lightGray2}`,
125
- }));
126
123
  const StyledSendButton = (0, styled_1.default)(react_1.RiSendPlaneFill)(({ theme }) => ({
127
124
  fill: theme.custom.colors.red,
128
125
  }));
129
126
  const StyledStopButton = (0, styled_1.default)(react_1.RiStopFill)(({ theme }) => ({
130
127
  fill: theme.custom.colors.red,
131
128
  }));
129
+ const BottomSection = styled_1.default.div({
130
+ paddingTop: "12px",
131
+ });
132
132
  const Disclaimer = (0, styled_1.default)(Typography_1.default)(({ theme }) => ({
133
133
  color: theme.custom.colors.silverGrayDark,
134
- marginTop: "16px",
134
+ marginTop: "14px",
135
135
  textAlign: "center",
136
136
  }));
137
137
  const ChatTitle = (0, styled_1.default)(({ title, askTimTitle, onClose, className }) => {
@@ -210,23 +210,24 @@ const AiChatInternal = function AiChat(_a) {
210
210
  React.createElement(Message, null,
211
211
  React.createElement(react_1.RiMoreFill, null)))) : null,
212
212
  error ? (React.createElement(Alert_1.Alert, { severity: "error", closable: true }, "An unexpected error has occurred.")) : null),
213
- React.createElement("form", { onSubmit: (e) => {
214
- e.preventDefault();
215
- if (isLoading && stoppable) {
216
- stop();
217
- }
218
- else {
219
- scrollToBottom();
220
- handleSubmit(e);
221
- }
222
- } },
223
- React.createElement(StyledInput, { fullWidth: true, size: "chat", className: classes.input, placeholder: placeholder, name: "message", sx: { flex: 1 }, value: input, onChange: handleInputChange, endAdornment: isLoading ? (React.createElement(Input_1.AdornmentButton, { "aria-label": "Stop", onClick: stop, disabled: !stoppable },
224
- React.createElement(StyledStopButton, null))) : (React.createElement(Input_1.AdornmentButton, { "aria-label": "Send", type: "submit", disabled: !input, onClick: (e) => {
213
+ React.createElement(BottomSection, { className: classes.bottomSection },
214
+ React.createElement("form", { onSubmit: (e) => {
215
+ e.preventDefault();
216
+ if (isLoading && stoppable) {
217
+ stop();
218
+ }
219
+ else {
225
220
  scrollToBottom();
226
221
  handleSubmit(e);
227
- } },
228
- React.createElement(StyledSendButton, null))) })),
229
- React.createElement(Disclaimer, { variant: "body3" }, "AI-generated content may be incorrect."),
222
+ }
223
+ } },
224
+ React.createElement(Input_1.Input, { fullWidth: true, size: "chat", className: classes.input, placeholder: placeholder, name: "message", sx: { flex: 1 }, value: input, onChange: handleInputChange, endAdornment: isLoading ? (React.createElement(Input_1.AdornmentButton, { "aria-label": "Stop", onClick: stop, disabled: !stoppable },
225
+ React.createElement(StyledStopButton, null))) : (React.createElement(Input_1.AdornmentButton, { "aria-label": "Send", type: "submit", onClick: (e) => {
226
+ scrollToBottom();
227
+ handleSubmit(e);
228
+ } },
229
+ React.createElement(StyledSendButton, null))) })),
230
+ React.createElement(Disclaimer, { variant: "body3" }, "AI-generated content may be incorrect.")),
230
231
  React.createElement(SrAnnouncer_1.SrAnnouncer, { isLoading: isLoading, loadingMessages: srLoadingMessages, message: lastMsg.role === "assistant" ? lastMsg.content : "" })));
231
232
  };
232
233
  const AiChat = (props) => (
@@ -9,3 +9,7 @@ export declare const StreamingResponses: Story;
9
9
  * to text via `parseContent`.
10
10
  */
11
11
  export declare const JsonResponses: Story;
12
+ /**
13
+ * This story shows the component's builtin markdown styling.
14
+ */
15
+ export declare const MarkdownStyling: Story;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JsonResponses = exports.StreamingResponses = void 0;
3
+ exports.MarkdownStyling = exports.JsonResponses = exports.StreamingResponses = void 0;
4
4
  const React = require("react");
5
5
  const AiChat_1 = require("./AiChat");
6
6
  const styled_1 = require("@emotion/styled");
@@ -77,3 +77,38 @@ exports.JsonResponses = {
77
77
  },
78
78
  },
79
79
  };
80
+ const DEMO_MARKDOWN = `This shows default markdown styling. Here's a list:
81
+ - Item 1 lorem ipsum dolor sit amet, consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
82
+ - Item 2
83
+ - Item 3
84
+ - Item 3.1
85
+ - Item 3.2
86
+ - Item 4
87
+ 1. Item 4.1
88
+ 2. Item 4.2
89
+ 3. Item 4.3
90
+
91
+ Here is a longer paragraph and **bold text** and *italic text*. Lorem ipsum dolor sit amet, consectetur adipiscing elit
92
+ sed do eiusmod tempor [incididunt](https://mit.edu) ut labore et dolore magna aliqua. Ut enim ad minim veniam.
93
+
94
+ And some inline code, \`\`<inline></inline>\`\` and code block:
95
+ \`\`\`
96
+ def f(x):
97
+ print(x)
98
+ \`\`\`
99
+ `;
100
+ /**
101
+ * This story shows the component's builtin markdown styling.
102
+ */
103
+ exports.MarkdownStyling = {
104
+ args: {
105
+ title: "Markdown Styles",
106
+ requestOpts: { apiUrl: TEST_API_STREAMING },
107
+ initialMessages: [
108
+ {
109
+ role: "assistant",
110
+ content: DEMO_MARKDOWN,
111
+ },
112
+ ],
113
+ },
114
+ };
@@ -41,6 +41,19 @@ Here are some courses on linear algebra that you can explore:
41
41
  These courses provide a comprehensive introduction to linear algebra and its applications across various fields.
42
42
  <!-- Comment! -->
43
43
  `,
44
+ `Here are some courses on quantum computing that offer certificates:
45
+
46
+ 1. [Introduction to Quantum Computing](https://xpro.mit.edu/courses/course-v1:xPRO+QCFx1/)
47
+ - **Description**: This is the first course in the Quantum Computing Fundamentals professional certificate program. You can earn a Professional Certificate and CEUs by completing both courses in the program. Alternatively, you can take this course individually for a certificate of completion and CEUs.
48
+ - **Offered by**: MIT xPRO
49
+ - **Instructors**: Isaac Chuang, William Oliver, Peter Shor, Aram Harrow
50
+
51
+ 2. [Practical Realities of Quantum Computation and Quantum Communication](https://xpro.mit.edu/courses/course-v1:xPRO+QCRx1/)
52
+ - **Description**: This course is part of the Quantum Computing Realities professional certificate program. Completing both courses in the program will earn you a Professional Certificate and CEUs. You can also take this course individually for a certificate of completion and CEUs.
53
+ - **Offered by**: MIT xPRO
54
+ - **Instructors**: Isaac Chuang, William Oliver, Peter Shor, Aram Harrow
55
+
56
+ These courses are part of professional certificate programs, and you can choose to complete the entire program or take individual courses for certification.`,
44
57
  ];
45
58
  const rand = (min, max) => {
46
59
  // min and max included
@@ -25,7 +25,7 @@ const responsiveSize = {
25
25
  small: "small",
26
26
  medium: "small",
27
27
  large: "medium",
28
- chat: "medium",
28
+ chat: "chat",
29
29
  hero: "large",
30
30
  };
31
31
  const sizeStyles = ({ size, theme, multiline }) => (0, react_1.css)([
@@ -87,12 +87,14 @@ const sizeStyles = ({ size, theme, multiline }) => (0, react_1.css)([
87
87
  size === "chat" && {
88
88
  padding: "0 16px",
89
89
  borderRadius: "8px",
90
- "&:hover:not(.Mui-disabled):not(.Mui-focused)": {
91
- borderColor: theme.custom.colors.silverGrayLight,
92
- },
93
- "&.Mui-focused": {
94
- borderColor: theme.custom.colors.silverGrayLight,
90
+ borderColor: theme.custom.colors.silverGrayLight,
91
+ "&:hover:not(.Mui-disabled), &.Mui-focused, :hover:not(.Mui-disabled):not(.Mui-focused)": {
92
+ boxShadow: "0px 8px 20px 0px rgba(120, 147, 172, 0.10)",
93
+ borderColor: theme.custom.colors.silverGray,
95
94
  outline: "none",
95
+ svg: {
96
+ fill: theme.custom.colors.lightRed,
97
+ },
96
98
  },
97
99
  ".Mit-AdornmentButton": {
98
100
  padding: "0 16px",
@@ -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,13 @@ 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>;
25
31
  };
26
32
  declare const AiChatDrawer: React.FC<AiChatDrawerProps>;
27
33
  export { AiChatDrawer };
@@ -1,7 +1,8 @@
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 AiChatDrawer = ({ messageOrigin, transformBody = identity, className, }) => {
5
6
  const [open, setOpen] = React.useState(false);
6
7
  const [chatSettings, setChatSettings] = React.useState(null);
7
8
  React.useEffect(() => {
@@ -17,7 +18,6 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
17
18
  setChatSettings(event.data.payload);
18
19
  }
19
20
  };
20
- console.log("Attaching listener");
21
21
  window.addEventListener("message", cb);
22
22
  return () => {
23
23
  window.removeEventListener("message", cb);
@@ -34,7 +34,9 @@ const AiChatDrawer = ({ messageOrigin, transformBody, className, }) => {
34
34
  },
35
35
  },
36
36
  }, anchor: "right", open: open, onClose: () => setOpen(false) }, chatSettings ? (React.createElement(AiChat, Object.assign({}, chatSettings, { requestOpts: {
37
- transformBody,
37
+ transformBody: (messages) => {
38
+ return Object.assign(Object.assign({}, chatSettings.requestBody), transformBody === null || transformBody === void 0 ? void 0 : transformBody(messages));
39
+ },
38
40
  apiUrl: chatSettings === null || chatSettings === void 0 ? void 0 : chatSettings.apiUrl,
39
41
  }, onClose: () => setOpen(false) }))) : null));
40
42
  };
@@ -32,6 +32,7 @@ const classes = {
32
32
  messageRowAssistant: "MitAiChat--messageRowAssistant",
33
33
  message: "MitAiChat--message",
34
34
  input: "MitAiChat--input",
35
+ bottomSection: "MitAiChat--bottomSection",
35
36
  };
36
37
  const ChatContainer = styled.div({
37
38
  width: "100%",
@@ -64,10 +65,9 @@ const MessagesContainer = styled(ScrollSnap)({
64
65
  display: "flex",
65
66
  flexDirection: "column",
66
67
  flex: 1,
67
- paddingTop: "14px",
68
- paddingBottom: "24px",
68
+ padding: "14px 0",
69
69
  overflow: "auto",
70
- gap: "24px",
70
+ gap: "16px",
71
71
  });
72
72
  const MessageRow = styled.div({
73
73
  display: "flex",
@@ -85,16 +85,18 @@ const Message = styled.div(({ theme }) => (Object.assign(Object.assign({ color:
85
85
  marginTop: 0,
86
86
  }, "p:last-of-type": {
87
87
  marginBottom: 0,
88
+ }, "ol, ul": {
89
+ paddingInlineStart: "32px",
90
+ li: {
91
+ margin: "16px 0",
92
+ },
93
+ }, ul: {
94
+ marginInlineStart: "-16px",
88
95
  }, a: {
89
96
  color: theme.custom.colors.red,
90
97
  fontWeight: "normal",
91
98
  }, borderRadius: "12px", [`.${classes.messageRowAssistant} &`]: {
92
- border: `1px solid ${theme.custom.colors.lightGray2}`,
93
- borderRadius: "0px 8px 8px 8px",
94
- svg: {
95
- fill: theme.custom.colors.silverGrayDark,
96
- display: "block",
97
- },
99
+ padding: "12px 16px 12px 0",
98
100
  }, [`.${classes.messageRowUser} &`]: {
99
101
  borderRadius: "8px 0px 8px 8px",
100
102
  backgroundColor: theme.custom.colors.lightGray1,
@@ -115,20 +117,18 @@ const RobotIcon = styled(RiRobot2Line)({
115
117
  width: "40px",
116
118
  height: "40px",
117
119
  });
118
- const StyledInput = styled(Input)(({ theme }) => ({
119
- backgroundColor: theme.custom.colors.lightGray1,
120
- borderRadius: "8px",
121
- border: `1px solid ${theme.custom.colors.lightGray2}`,
122
- }));
123
120
  const StyledSendButton = styled(RiSendPlaneFill)(({ theme }) => ({
124
121
  fill: theme.custom.colors.red,
125
122
  }));
126
123
  const StyledStopButton = styled(RiStopFill)(({ theme }) => ({
127
124
  fill: theme.custom.colors.red,
128
125
  }));
126
+ const BottomSection = styled.div({
127
+ paddingTop: "12px",
128
+ });
129
129
  const Disclaimer = styled(Typography)(({ theme }) => ({
130
130
  color: theme.custom.colors.silverGrayDark,
131
- marginTop: "16px",
131
+ marginTop: "14px",
132
132
  textAlign: "center",
133
133
  }));
134
134
  const ChatTitle = styled(({ title, askTimTitle, onClose, className }) => {
@@ -207,23 +207,24 @@ const AiChatInternal = function AiChat(_a) {
207
207
  React.createElement(Message, null,
208
208
  React.createElement(RiMoreFill, null)))) : null,
209
209
  error ? (React.createElement(Alert, { severity: "error", closable: true }, "An unexpected error has occurred.")) : null),
210
- React.createElement("form", { onSubmit: (e) => {
211
- e.preventDefault();
212
- if (isLoading && stoppable) {
213
- stop();
214
- }
215
- else {
216
- scrollToBottom();
217
- handleSubmit(e);
218
- }
219
- } },
220
- React.createElement(StyledInput, { fullWidth: true, size: "chat", className: classes.input, placeholder: placeholder, name: "message", sx: { flex: 1 }, value: input, onChange: handleInputChange, endAdornment: isLoading ? (React.createElement(AdornmentButton, { "aria-label": "Stop", onClick: stop, disabled: !stoppable },
221
- React.createElement(StyledStopButton, null))) : (React.createElement(AdornmentButton, { "aria-label": "Send", type: "submit", disabled: !input, onClick: (e) => {
210
+ React.createElement(BottomSection, { className: classes.bottomSection },
211
+ React.createElement("form", { onSubmit: (e) => {
212
+ e.preventDefault();
213
+ if (isLoading && stoppable) {
214
+ stop();
215
+ }
216
+ else {
222
217
  scrollToBottom();
223
218
  handleSubmit(e);
224
- } },
225
- React.createElement(StyledSendButton, null))) })),
226
- React.createElement(Disclaimer, { variant: "body3" }, "AI-generated content may be incorrect."),
219
+ }
220
+ } },
221
+ React.createElement(Input, { fullWidth: true, size: "chat", className: classes.input, placeholder: placeholder, name: "message", sx: { flex: 1 }, value: input, onChange: handleInputChange, endAdornment: isLoading ? (React.createElement(AdornmentButton, { "aria-label": "Stop", onClick: stop, disabled: !stoppable },
222
+ React.createElement(StyledStopButton, null))) : (React.createElement(AdornmentButton, { "aria-label": "Send", type: "submit", onClick: (e) => {
223
+ scrollToBottom();
224
+ handleSubmit(e);
225
+ } },
226
+ React.createElement(StyledSendButton, null))) })),
227
+ React.createElement(Disclaimer, { variant: "body3" }, "AI-generated content may be incorrect.")),
227
228
  React.createElement(SrAnnouncer, { isLoading: isLoading, loadingMessages: srLoadingMessages, message: lastMsg.role === "assistant" ? lastMsg.content : "" })));
228
229
  };
229
230
  const AiChat = (props) => (
@@ -9,3 +9,7 @@ export declare const StreamingResponses: Story;
9
9
  * to text via `parseContent`.
10
10
  */
11
11
  export declare const JsonResponses: Story;
12
+ /**
13
+ * This story shows the component's builtin markdown styling.
14
+ */
15
+ export declare const MarkdownStyling: Story;
@@ -74,3 +74,38 @@ export const JsonResponses = {
74
74
  },
75
75
  },
76
76
  };
77
+ const DEMO_MARKDOWN = `This shows default markdown styling. Here's a list:
78
+ - Item 1 lorem ipsum dolor sit amet, consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
79
+ - Item 2
80
+ - Item 3
81
+ - Item 3.1
82
+ - Item 3.2
83
+ - Item 4
84
+ 1. Item 4.1
85
+ 2. Item 4.2
86
+ 3. Item 4.3
87
+
88
+ Here is a longer paragraph and **bold text** and *italic text*. Lorem ipsum dolor sit amet, consectetur adipiscing elit
89
+ sed do eiusmod tempor [incididunt](https://mit.edu) ut labore et dolore magna aliqua. Ut enim ad minim veniam.
90
+
91
+ And some inline code, \`\`<inline></inline>\`\` and code block:
92
+ \`\`\`
93
+ def f(x):
94
+ print(x)
95
+ \`\`\`
96
+ `;
97
+ /**
98
+ * This story shows the component's builtin markdown styling.
99
+ */
100
+ export const MarkdownStyling = {
101
+ args: {
102
+ title: "Markdown Styles",
103
+ requestOpts: { apiUrl: TEST_API_STREAMING },
104
+ initialMessages: [
105
+ {
106
+ role: "assistant",
107
+ content: DEMO_MARKDOWN,
108
+ },
109
+ ],
110
+ },
111
+ };
@@ -38,6 +38,19 @@ Here are some courses on linear algebra that you can explore:
38
38
  These courses provide a comprehensive introduction to linear algebra and its applications across various fields.
39
39
  <!-- Comment! -->
40
40
  `,
41
+ `Here are some courses on quantum computing that offer certificates:
42
+
43
+ 1. [Introduction to Quantum Computing](https://xpro.mit.edu/courses/course-v1:xPRO+QCFx1/)
44
+ - **Description**: This is the first course in the Quantum Computing Fundamentals professional certificate program. You can earn a Professional Certificate and CEUs by completing both courses in the program. Alternatively, you can take this course individually for a certificate of completion and CEUs.
45
+ - **Offered by**: MIT xPRO
46
+ - **Instructors**: Isaac Chuang, William Oliver, Peter Shor, Aram Harrow
47
+
48
+ 2. [Practical Realities of Quantum Computation and Quantum Communication](https://xpro.mit.edu/courses/course-v1:xPRO+QCRx1/)
49
+ - **Description**: This course is part of the Quantum Computing Realities professional certificate program. Completing both courses in the program will earn you a Professional Certificate and CEUs. You can also take this course individually for a certificate of completion and CEUs.
50
+ - **Offered by**: MIT xPRO
51
+ - **Instructors**: Isaac Chuang, William Oliver, Peter Shor, Aram Harrow
52
+
53
+ These courses are part of professional certificate programs, and you can choose to complete the entire program or take individual courses for certification.`,
41
54
  ];
42
55
  const rand = (min, max) => {
43
56
  // min and max included
@@ -22,7 +22,7 @@ const responsiveSize = {
22
22
  small: "small",
23
23
  medium: "small",
24
24
  large: "medium",
25
- chat: "medium",
25
+ chat: "chat",
26
26
  hero: "large",
27
27
  };
28
28
  const sizeStyles = ({ size, theme, multiline }) => css([
@@ -84,12 +84,14 @@ const sizeStyles = ({ size, theme, multiline }) => css([
84
84
  size === "chat" && {
85
85
  padding: "0 16px",
86
86
  borderRadius: "8px",
87
- "&:hover:not(.Mui-disabled):not(.Mui-focused)": {
88
- borderColor: theme.custom.colors.silverGrayLight,
89
- },
90
- "&.Mui-focused": {
91
- borderColor: theme.custom.colors.silverGrayLight,
87
+ borderColor: theme.custom.colors.silverGrayLight,
88
+ "&:hover:not(.Mui-disabled), &.Mui-focused, :hover:not(.Mui-disabled):not(.Mui-focused)": {
89
+ boxShadow: "0px 8px 20px 0px rgba(120, 147, 172, 0.10)",
90
+ borderColor: theme.custom.colors.silverGray,
92
91
  outline: "none",
92
+ svg: {
93
+ fill: theme.custom.colors.lightRed,
94
+ },
93
95
  },
94
96
  ".Mit-AdornmentButton": {
95
97
  padding: "0 16px",