diff --git a/.github/workflows/typos.toml b/.github/workflows/typos.toml index f3d22513ac40a..455392eb13754 100644 --- a/.github/workflows/typos.toml +++ b/.github/workflows/typos.toml @@ -7,6 +7,7 @@ MacOS = "macOS" [default.extend-words] # do as sudo replacement doas = "doas" +darcula = "darcula" [files] extend-exclude = [ diff --git a/site/src/components/Markdown/Markdown.tsx b/site/src/components/Markdown/Markdown.tsx index f068b72194048..1e06f5be6e23f 100644 --- a/site/src/components/Markdown/Markdown.tsx +++ b/site/src/components/Markdown/Markdown.tsx @@ -1,27 +1,28 @@ import Link from "@material-ui/core/Link" -import { makeStyles, Theme, useTheme } from "@material-ui/core/styles" +import { makeStyles } from "@material-ui/core/styles" import Table from "@material-ui/core/Table" import TableBody from "@material-ui/core/TableBody" import TableCell from "@material-ui/core/TableCell" import TableContainer from "@material-ui/core/TableContainer" import TableHead from "@material-ui/core/TableHead" import TableRow from "@material-ui/core/TableRow" -import { FC } from "react" +import React, { FC } from "react" import ReactMarkdown from "react-markdown" -import SyntaxHighlighter from "react-syntax-highlighter" -import { dracula as dark } from "react-syntax-highlighter/dist/cjs/styles/hljs" +import { Prism as SyntaxHighlighter } from "react-syntax-highlighter" import gfm from "remark-gfm" +import { colors } from "theme/colors" +import darcula from "react-syntax-highlighter/dist/cjs/styles/prism/darcula" export interface MarkdownProps { children: string } export const Markdown: FC<{ children: string }> = ({ children }) => { - const theme: Theme = useTheme() const styles = useStyles() return ( ( @@ -30,22 +31,27 @@ export const Markdown: FC<{ children: string }> = ({ children }) => { ), + pre: ({ node, children }) => { + const firstChild = node.children[0] + // When pre is wrapping a code, the SyntaxHighlighter is already going + // to wrap it with a pre so we don't need it + if (firstChild.type === "element" && firstChild.tagName === "code") { + return <>{children} + } + return
{children}
+ }, + code: ({ node, inline, className, children, ...props }) => { const match = /language-(\w+)/.exec(className || "") + return !inline && match ? ( {String(children).replace(/\n$/, "")} @@ -91,12 +97,50 @@ export const Markdown: FC<{ children: string }> = ({ children }) => { ) } +export const MemoizedMarkdown = React.memo(Markdown) + const useStyles = makeStyles((theme) => ({ + markdown: { + fontSize: 16, + lineHeight: "24px", + + "& h1, & h2, & h3, & h4, & h5, & h6": { + marginTop: theme.spacing(4), + marginBottom: theme.spacing(2), + lineHeight: "1.25", + }, + + "& p": { + marginTop: 0, + marginBottom: theme.spacing(2), + }, + + "& ul, & ol": { + display: "flex", + flexDirection: "column", + gap: theme.spacing(1), + }, + + "& .prismjs": { + background: theme.palette.background.paperLight, + borderRadius: theme.shape.borderRadius, + padding: theme.spacing(2, 3), + + "& code": { + color: theme.palette.text.secondary, + }, + + "& .key, & .property": { + color: colors.turquoise[7], + }, + }, + }, + codeWithoutLanguage: { - overflowX: "auto", - padding: "0.5em", - background: theme.palette.background.default, - borderRadius: theme.shape.borderRadius, + padding: theme.spacing(0.5, 1), + background: theme.palette.divider, + borderRadius: 4, color: theme.palette.text.primary, + fontSize: 14, }, })) diff --git a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx index 2ceb20463e75e..6fa7aab3da861 100644 --- a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx +++ b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx @@ -6,21 +6,15 @@ import { WorkspaceResource, } from "api/typesGenerated" import { AlertBanner } from "components/AlertBanner/AlertBanner" -import { Markdown } from "components/Markdown/Markdown" +import { MemoizedMarkdown } from "components/Markdown/Markdown" import { Stack } from "components/Stack/Stack" import { TemplateResourcesTable } from "components/TemplateResourcesTable/TemplateResourcesTable" import { TemplateStats } from "components/TemplateStats/TemplateStats" import { VersionsTable } from "components/VersionsTable/VersionsTable" -import { WorkspaceSection } from "components/WorkspaceSection/WorkspaceSection" import frontMatter from "front-matter" import { FC } from "react" import { DAUChart } from "./DAUChart" -const Language = { - readmeTitle: "README", - resourcesTitle: "Resources", -} - export interface TemplateSummaryPageViewProps { template: Template activeTemplateVersion: TemplateVersion @@ -64,14 +58,14 @@ export const TemplateSummaryPageView: FC< - + +
+
README.md
- {readme.body} + {readme.body}
- +
+ ) @@ -79,12 +73,23 @@ export const TemplateSummaryPageView: FC< export const useStyles = makeStyles((theme) => { return { - readmeContents: { - margin: 0, + markdownSection: { + background: theme.palette.background.paper, + border: `1px solid ${theme.palette.divider}`, + borderRadius: theme.shape.borderRadius, }, + + readmeLabel: { + color: theme.palette.text.secondary, + fontWeight: 600, + padding: theme.spacing(2, 3), + borderBottom: `1px solid ${theme.palette.divider}`, + }, + markdownWrapper: { - background: theme.palette.background.paper, - padding: theme.spacing(3, 4), + padding: theme.spacing(0, 3, 5), + maxWidth: 800, + margin: "auto", }, } })