mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor: Improve template README section (#4794)
* refactor: Improve template README section * Fix version * Add darcula * Fix typos
This commit is contained in:
@@ -7,6 +7,7 @@ MacOS = "macOS"
|
||||
[default.extend-words]
|
||||
# do as sudo replacement
|
||||
doas = "doas"
|
||||
darcula = "darcula"
|
||||
|
||||
[files]
|
||||
extend-exclude = [
|
||||
|
||||
@@ -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 (
|
||||
<ReactMarkdown
|
||||
className={styles.markdown}
|
||||
remarkPlugins={[gfm]}
|
||||
components={{
|
||||
a: ({ href, target, children }) => (
|
||||
@@ -30,22 +31,27 @@ export const Markdown: FC<{ children: string }> = ({ children }) => {
|
||||
</Link>
|
||||
),
|
||||
|
||||
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 <pre>{children}</pre>
|
||||
},
|
||||
|
||||
code: ({ node, inline, className, children, ...props }) => {
|
||||
const match = /language-(\w+)/.exec(className || "")
|
||||
|
||||
return !inline && match ? (
|
||||
<SyntaxHighlighter
|
||||
// Custom style to match our main colors
|
||||
style={{
|
||||
...dark,
|
||||
hljs: {
|
||||
...dark.hljs,
|
||||
background: theme.palette.background.default,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
}}
|
||||
style={darcula}
|
||||
language={match[1]}
|
||||
PreTag="div"
|
||||
useInlineStyles={false}
|
||||
// Use inline styles does not work correctly
|
||||
// https://github.com/react-syntax-highlighter/react-syntax-highlighter/issues/329
|
||||
codeTagProps={{ style: {} }}
|
||||
{...props}
|
||||
>
|
||||
{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,
|
||||
},
|
||||
}))
|
||||
|
||||
@@ -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<
|
||||
<TemplateResourcesTable
|
||||
resources={getStartedResources(templateResources)}
|
||||
/>
|
||||
<WorkspaceSection
|
||||
title={Language.readmeTitle}
|
||||
contentsProps={{ className: styles.readmeContents }}
|
||||
>
|
||||
|
||||
<div className={styles.markdownSection}>
|
||||
<div className={styles.readmeLabel}>README.md</div>
|
||||
<div className={styles.markdownWrapper}>
|
||||
<Markdown>{readme.body}</Markdown>
|
||||
<MemoizedMarkdown>{readme.body}</MemoizedMarkdown>
|
||||
</div>
|
||||
</WorkspaceSection>
|
||||
</div>
|
||||
|
||||
<VersionsTable versions={templateVersions} />
|
||||
</Stack>
|
||||
)
|
||||
@@ -79,12 +73,23 @@ export const TemplateSummaryPageView: FC<
|
||||
|
||||
export const useStyles = makeStyles((theme) => {
|
||||
return {
|
||||
readmeContents: {
|
||||
margin: 0,
|
||||
},
|
||||
markdownWrapper: {
|
||||
markdownSection: {
|
||||
background: theme.palette.background.paper,
|
||||
padding: theme.spacing(3, 4),
|
||||
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: {
|
||||
padding: theme.spacing(0, 3, 5),
|
||||
maxWidth: 800,
|
||||
margin: "auto",
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user