diff --git a/src/components/CustomMessage.tsx b/src/components/CustomMessage.tsx index 269f4fbb5..b7ad8a239 100644 --- a/src/components/CustomMessage.tsx +++ b/src/components/CustomMessage.tsx @@ -124,6 +124,7 @@ export default function CustomMessage(props: Props) { // for user message if (message.isUserMessage()) { const sources = getSourceFromMetadata(message); + // console.log('## message.message: ', message.message); const tokens: Token[] = parseTextMessage(message.message, replacementTextList); const textMessageBody = ; diff --git a/src/components/TokensBody.tsx b/src/components/TokensBody.tsx index fbd07ae9f..2ebc867af 100644 --- a/src/components/TokensBody.tsx +++ b/src/components/TokensBody.tsx @@ -1,4 +1,4 @@ -import Markdown from 'markdown-to-jsx'; +import Markdown, {RuleType} from 'markdown-to-jsx'; import styled from 'styled-components'; import BotMessageBottom from './BotMessageBottom'; @@ -7,6 +7,13 @@ import { CodeBlock } from './ui/CodeBlock'; import { useConstantState } from '../context/ConstantContext'; import { Token, TokenType } from '../utils'; import './markdown.css'; +import {Key} from "react"; +// @ts-ignore +import ParserResult = MarkdownToJSX.ParserResult; +// @ts-ignore +import RuleOutput = MarkdownToJSX.RuleOutput; +// @ts-ignore +import State = MarkdownToJSX.State; type TokensBodyProps = { tokens: Token[]; @@ -32,16 +39,28 @@ export const TextContainer = styled.div` white-space: pre-wrap; `; +function getSpaces(count: unknown): string { + const num = Number(count) - 1; + if (isNaN(num) || num < 0) { + return ''; + } + const res = ' '.repeat(num * 2); + return res; +} + export default function TokensBody({ tokens, sources }: TokensBodyProps) { const { enableSourceMessage } = useConstantState(); - + return ( {tokens.map((token: Token, i) => { // Normal text part of the message. if (token.type === TokenType.string) { - return
- {token.value} + console.log('## token: ', token.value); + return
+ + {token.value} +
} // Code part of the message. diff --git a/src/components/markdown.css b/src/components/markdown.css index c7aa31e7f..7b00fe52c 100644 --- a/src/components/markdown.css +++ b/src/components/markdown.css @@ -1,36 +1,57 @@ -.markdown p { - font-size: 14px; - line-height: 1.43; - margin: 0; +.markdown { + font-size: 14px; /* em is based on parent. So need to set default size here (parent class). */ + padding: 0 12px; /* apply side padding of the bubble */ +} + +.markdown hr { + border-top-width: 1px; + margin-bottom: 1.5em; /* 3em in ChatGPT */ + margin-top: 1.5em; /* 3em in ChatGPT */ } .markdown h1 { - margin: 0; + margin-top: 0; + margin-bottom: .8888889em; padding: 0; - font-size: 28px; + font-size: 1.6em; /* original size is 2.25em in ChatGPT but because we are rendering in bubble, we reduced size to make it more appealing visually. */ + line-height: 1.1111111; + font-weight: 700; + letter-spacing: -.04rem; } .markdown h2 { - margin: 0; - padding: 0; - font-size: 22px; + font-weight: 600; + margin-bottom: 0.75rem; /* 1em in ChatGPT */ + margin-top: 1.5rem; /* 2em in ChatGPT */ + font-size: 1.3em; /* 1.5em in ChatGPT */ + line-height: 1.3333333; } .markdown h3 { - margin: 0; - padding: 0; - font-size: 18px; + font-weight: 600; + margin-bottom: .5rem; + margin-top: 1rem; + font-size: 1.1em; /* 1.25em in ChatGPT */ + line-height: 1.6; } -.markdown { - margin: 0; - padding: 0; +.markdown p:not(:first-child) { + margin-top: .5rem; } -.markdown code { - margin: 0; - padding: 0; +.markdown p { font-size: 1em; + line-height: 1.43; /* 1.75 in ChatGPT */ + margin-bottom: .5rem; + margin-top: 0; +} + +.markdown code { + border-radius: .25rem; + font-size: .875em; + font-weight: 500; + padding: .15rem .3rem; + background-color: #e7c8ff; /* I picked this color randomly. Need to be checked by the design team. Also need to be made customizable. */ } .markdown table { @@ -43,3 +64,60 @@ .markdown tr, th, td { border: 1px solid; } + +.markdown menu, ol, ul { + list-style: none; +} + +/* +Below stuffs are from ChatGPT. I asked Widget to send me a random message with +bunch of markdown syntaxes. Then I asked ChatGPT to send me the exact same message. +I then benchmarked the style ChatGPT used. Below classes are the exact same classes. +*/ + +.markdown :where(ol):not(:where([class~=not-markdown] *)) { + padding-inline-start: 1.2em; /* 1.625em in ChatGPT */ + list-style-type: decimal; + margin-top: 1.25em; + margin-bottom: 1.25em; +} + +.markdown :where(ul):not(:where([class~=not-markdown] *)) { + padding-inline-start: 1.2em; /* 1.625em in ChatGPT */ + list-style-type: disc; + margin-top: 1.25em; + margin-bottom: 1.25em; +} + +/* +Any element inside .markdown will have a margin-top: 0 applied if it directly follows an h3. +Any element inside .not-markdown will not be affected. +markdown.markdown is to increase specificity. Refer to: https://www.w3.org/TR/CSS21/cascade.html#specificity +*/ +.markdown.markdown :where(h3+*):not(:where([class~=not-markdown] *)) { + margin-top: 0; +} + +.markdown :where(ol,ul)>li>:first-child { + margin-bottom: 0; + margin-top: 0; +} + +.markdown :where(ol,ul)>li>:last-child { + margin-bottom: 0; +} + +.markdown p+:where(ol,ul) { + margin-top: 0; +} + +.markdown :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~=not-markdown] *)) { + margin-bottom: 0.75em; + margin-top: 0.75em; +} + +.markdown :where(li):not(:where([class~=not-markdown] *)) { + padding-inline-start: 0; /* .375 in ChatGPT */ + margin-bottom: .4em; /* .5em in ChatGPT */ + margin-top: .4em; /* .5em in ChatGPT */ +}