diff --git a/package.json b/package.json index c752b0ca..f2d87825 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "@markdoc/markdoc": "0.3.0", "@markdoc/next.js": "0.2.2", "@open-draft/until": "2.1.0", - "@pluralsh/design-system": "2.1.1", + "@pluralsh/design-system": "2.1.2", "@react-types/shared": "3.18.1", "@tanstack/react-table": "8.9.3", "@tanstack/react-virtual": "3.0.0-beta.48", @@ -100,7 +100,7 @@ "autoprefixer": "10.4.14", "concurrently": "8.2.0", "cross-env": "7.0.3", - "eslint": "8.45.0", + "eslint": "8.46.0", "eslint-config-next": "13.4.10", "eslint-config-prettier": "8.8.0", "eslint-import-resolver-typescript": "3.5.5", diff --git a/src/components/RepoReadme/RepoReadmeMd.tsx b/src/components/RepoReadme/RepoReadmeMd.tsx index 80edd906..b883ae93 100644 --- a/src/components/RepoReadme/RepoReadmeMd.tsx +++ b/src/components/RepoReadme/RepoReadmeMd.tsx @@ -1,55 +1,37 @@ -import { Children, memo } from 'react' +import { Children, useMemo } from 'react' import { - Blockquote, - Code, - Div, - H1, - H2, - H3, - H4, - H5, - H6, - Li, - Ol, - P, - Ul, -} from 'honorable' + InlineCode, + Code as MultilineCode, + isExternalUrl, + removeTrailingSlashes, +} from '@pluralsh/design-system' +import { Div } from 'honorable' import ReactMarkdown from 'react-markdown' import rehypeRaw from 'rehype-raw' import styled from 'styled-components' -import MultilineCode from './Code' - -const MdA = styled.a(({ theme }) => ({ - '&, &:any-link': { - ...theme.partials.marketingText.inlineLink, - }, -})) +type MarkdownProps = { + text: string + gitUrl?: string + mainBranch?: string +} -const MdImg = styled(({ src, gitUrl, mainBranch, ...props }) => { - // Convert local image paths to full path on github - // Only works if primary git branch is named "master" - if (gitUrl && src && !src.match(/^https*/)) { - src = `${gitUrl}/raw/${mainBranch}/${src}` +const render = ({ component: Component, props: extraProps }: any) => + function renderComponent({ node: _, ...props }: any) { + return ( + + ) } - return ( - - ) -})((_) => ({ - '&&': { - display: 'inline', - maxWidth: '100%', - }, -})) - -function getLastStringChild(children, depth = 0) { - let lastChild: string | null = null +function getLastStringChild(children: any, depth = 0): any { + let lastChild: any = null Children.forEach(children, (child) => { if (typeof child === 'string') { @@ -62,11 +44,13 @@ function getLastStringChild(children, depth = 0) { return lastChild } -function MdPre({ children, ...props }) { +function MarkdownPreformatted({ children, ...props }: any) { let lang - if (children.props?.className?.startsWith('lang-')) { - lang = children.props.className.slice(5) + const className = children?.[0]?.props?.className + + if (className && typeof className === 'string') { + lang = /language-(\w+)/.exec(className)?.[1] || '' } const stringChild = getLastStringChild(children) || '' @@ -81,161 +65,214 @@ function MdPre({ children, ...props }) { ) } +const commonCfg = { shouldForwardProp: () => true } -const toReactMarkdownComponent = ({ - component: Component, - props, +const MdBlockquote = styled.blockquote.withConfig(commonCfg)(({ theme }) => ({ + position: 'relative', + ...theme.partials.text.body1, + color: theme.colors['text-light'], + margin: 0, + marginLeft: theme.spacing.xlarge - 1, + borderLeft: `2px solid ${theme.colors.border}`, + padding: '0', + paddingLeft: theme.spacing.xlarge - 1, + boxShadow: 'none', + '& p': { + ...theme.partials.text.body1, + color: theme.colors['text-light'], + }, +})) +const MdUl = styled.ul.withConfig(commonCfg)(({ theme }) => ({ + listStyle: 'initial', + paddingLeft: theme.spacing.xlarge, + marginBottom: theme.spacing.small, +})) +const MdOl = styled.ol.withConfig(commonCfg)(({ theme }) => ({ + listStyle: 'initial', + paddingLeft: theme.spacing.xlarge, + marginBottom: theme.spacing.small, +})) +const MdLi = styled.li.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.body2LooseLineHeight, + marginTop: theme.spacing.xxsmall, +})) +const MdH1 = styled.h1.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.title2, + color: theme.colors.text, + marginTop: theme.spacing.large, + marginBottom: theme.spacing.small, + ':first-of-type': { marginTop: 0 }, +})) +const MdH2 = styled.h2.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.subtitle1, + color: theme.colors.text, + marginTop: theme.spacing.large, + marginBottom: theme.spacing.small, + ':first-of-type': { marginTop: 0 }, +})) +const MdH3 = styled.h3.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.subtitle2, + color: theme.colors.text, + marginTop: theme.spacing.large, + marginBottom: theme.spacing.small, + ':first-of-type': { marginTop: 0 }, +})) +const MdH4 = styled.h4.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.body1Bold, + color: theme.colors.text, + marginTop: theme.spacing.large, + marginBottom: theme.spacing.small, + ':first-of-type': { marginTop: 0 }, +})) +const MdH5 = styled.h5.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.body1Bold, + color: theme.colors.text, + marginTop: theme.spacing.large, + marginBottom: theme.spacing.small, + ':first-of-type': { marginTop: 0 }, +})) +const MdH6 = styled.h6.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.body1Bold, + color: theme.colors.text, + marginTop: theme.spacing.large, + marginBottom: theme.spacing.small, + ':first-of-type': { marginTop: 0 }, +})) +const MdImg = styled.img(() => ({ display: 'inline', maxWidth: '100%' })) +const MdP = styled.p.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.body2LooseLineHeight, + marginBottom: theme.spacing.medium, +})) +const MdDiv = styled.div.withConfig(commonCfg)(({ theme }) => ({ + ...theme.partials.text.body2LooseLineHeight, + marginBottom: theme.spacing.medium, +})) +const MdA = styled.a.withConfig(commonCfg)(({ theme }) => ({ + display: 'inline', + ...theme.partials.marketingText.inlineLink, +})) +const MdSpan = styled.span.withConfig(commonCfg)((_p) => ({ + verticalAlign: 'bottom', +})) +const MdHr = styled.hr.withConfig(commonCfg)(({ theme }) => ({ + '&::before': { + content: '""', + display: 'table', + }, + '&::after': { + content: '""', + clear: 'both', + display: 'table', + }, + height: '1px', + backgroundColor: theme.colors.border, + border: 0, + padding: 0, + margin: `${theme.spacing.xlarge}px ${theme.spacing.large}px`, +})) +const MdDetails = styled.details(({ theme }) => ({ + ...theme.partials.text.body2LooseLineHeight, + summary: { + ...theme.partials.text.overline, + marginBottom: theme.spacing.medium, + '&::marker': { + color: theme.colors['text-xlight'], + }, + }, +})) + +function MarkdownImage({ + src, + gitUrl, + style, + mainBranch = 'master', + ...props +}: any) { + // Convert local image paths to full path on github + if (gitUrl && src && !isExternalUrl(src)) { + src = src.replace(/^\//, '') + src = `${removeTrailingSlashes(gitUrl)}/raw/${mainBranch}/${src}` + } + + return ( + + ) +} + +function MarkdownLink({ + href, + gitUrl, + mainBranch, + ...props }: { - component?: any - props?: any -}) => - function renderComponent(p) { - return ( - - ) + href: string + gitUrl: string + mainBranch: string +}) { + // Convert local readme hrefs to full path on github + if (gitUrl && href && !isExternalUrl(href)) { + // Remove potential starting slash + href = href.replace(/^\//, '') + href = `${removeTrailingSlashes(gitUrl)}/blob/${mainBranch}/${href}` } -export default memo( - ({ - text, - gitUrl, - mainBranch, - }: { - text: string - gitUrl: string - mainBranch: string - }) => ( -
+ return ( + + ) +} + +function Markdown({ text, gitUrl, mainBranch }: MarkdownProps) { + return useMemo( + () => ( ( - - ), - p: toReactMarkdownComponent({ - component: P, - props: { body2: true, marginBottom: 'medium' }, - }), - div: toReactMarkdownComponent({ - component: Div, - props: { body2: true, marginBottom: 'medium' }, - }), - a: toReactMarkdownComponent({ - component: MdA, - props: { - // inline: true, - // display: 'inline', - target: '_blank', - }, - }), - span: toReactMarkdownComponent({ - props: { style: { verticalAlign: 'bottom' } }, - }), - code: toReactMarkdownComponent({ component: Code }), - pre: toReactMarkdownComponent({ component: MdPre }), + hr: render({ component: MdHr }), + details: render({ component: MdDetails }), }} > {text} -
+ ), + [text, gitUrl, mainBranch] ) -) +} + +export default Markdown diff --git a/src/generated/graphqlPlural.ts b/src/generated/graphqlPlural.ts index 865a84dd..2e948f6c 100644 --- a/src/generated/graphqlPlural.ts +++ b/src/generated/graphqlPlural.ts @@ -2726,6 +2726,7 @@ export type RootMutationType = { installStack?: Maybe>>; installStackShell?: Maybe>>; installTerraform?: Maybe; + installVersion?: Maybe; linkPublisher?: Maybe; login?: Maybe; loginToken?: Maybe; @@ -3225,6 +3226,14 @@ export type RootMutationTypeInstallTerraformArgs = { }; +export type RootMutationTypeInstallVersionArgs = { + package: Scalars['String']['input']; + repository: Scalars['String']['input']; + type: DependencyType; + vsn: Scalars['String']['input']; +}; + + export type RootMutationTypeLinkPublisherArgs = { token: Scalars['String']['input']; }; diff --git a/yarn.lock b/yarn.lock index fac9337b..ecbb7b4d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1980,16 +1980,16 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.4.0": - version: 4.5.0 - resolution: "@eslint-community/regexpp@npm:4.5.0" - checksum: 99c01335947dbd7f2129e954413067e217ccaa4e219fe0917b7d2bd96135789384b8fedbfb8eb09584d5130b27a7b876a7150ab7376f51b3a0c377d5ce026a10 +"@eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.6.1": + version: 4.6.2 + resolution: "@eslint-community/regexpp@npm:4.6.2" + checksum: a3c341377b46b54fa228f455771b901d1a2717f95d47dcdf40199df30abc000ba020f747f114f08560d119e979d882a94cf46cfc51744544d54b00319c0f2724 languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.0": - version: 2.1.0 - resolution: "@eslint/eslintrc@npm:2.1.0" +"@eslint/eslintrc@npm:^2.1.0, @eslint/eslintrc@npm:^2.1.1": + version: 2.1.1 + resolution: "@eslint/eslintrc@npm:2.1.1" dependencies: ajv: ^6.12.4 debug: ^4.3.2 @@ -2000,7 +2000,7 @@ __metadata: js-yaml: ^4.1.0 minimatch: ^3.1.2 strip-json-comments: ^3.1.1 - checksum: d5ed0adbe23f6571d8c9bb0ca6edf7618dc6aed4046aa56df7139f65ae7b578874e0d9c796df784c25bda648ceb754b6320277d828c8b004876d7443b8dc018c + checksum: bf909ea183d27238c257a82d4ffdec38ca94b906b4b8dfae02ecbe7ecc9e5a8182ef5e469c808bb8cb4fea4750f43ac4ca7c4b4a167b6cd7e3aaacd386b2bd25 languageName: node linkType: hard @@ -2011,6 +2011,13 @@ __metadata: languageName: node linkType: hard +"@eslint/js@npm:^8.46.0": + version: 8.46.0 + resolution: "@eslint/js@npm:8.46.0" + checksum: 7aed479832302882faf5bec37e9d068f270f84c19b3fb529646a7c1b031e73a312f730569c78806492bc09cfce3d7651dfab4ce09a56cbb06bc6469449e56377 + languageName: node + linkType: hard + "@floating-ui/core@npm:^1.2.6": version: 1.2.6 resolution: "@floating-ui/core@npm:1.2.6" @@ -3504,9 +3511,9 @@ __metadata: languageName: node linkType: hard -"@pluralsh/design-system@npm:2.1.1": - version: 2.1.1 - resolution: "@pluralsh/design-system@npm:2.1.1" +"@pluralsh/design-system@npm:2.1.2": + version: 2.1.2 + resolution: "@pluralsh/design-system@npm:2.1.2" dependencies: "@floating-ui/react-dom-interactions": 0.13.3 "@loomhq/loom-embed": 1.5.0 @@ -3554,7 +3561,7 @@ __metadata: react-dom: ">=18.2.0" react-transition-group: ">=4.4.5" styled-components: ">=5.3.11" - checksum: b143aac3a39e5c71c3ec981c73b1c72ece3d7ea554f0cf741391a3e6fdab89106c865056ca9b703702f1c0c250fecd694f86b23da6b67d4b4932bf4bb1b996db + checksum: 7fcbf31a9044c217fd42bfb0dd3bf664927d3b817fe126696d640c8dedc25c43597bf726bbb59527d0b7b5c5cddad79d870cfff19535442e3f2cff43df9a0a8b languageName: node linkType: hard @@ -7921,13 +7928,13 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.0": - version: 7.2.0 - resolution: "eslint-scope@npm:7.2.0" +"eslint-scope@npm:^7.2.0, eslint-scope@npm:^7.2.2": + version: 7.2.2 + resolution: "eslint-scope@npm:7.2.2" dependencies: esrecurse: ^4.3.0 estraverse: ^5.2.0 - checksum: 64591a2d8b244ade9c690b59ef238a11d5c721a98bcee9e9f445454f442d03d3e04eda88e95a4daec558220a99fa384309d9faae3d459bd40e7a81b4063980ae + checksum: ec97dbf5fb04b94e8f4c5a91a7f0a6dd3c55e46bfc7bbcd0e3138c3a76977570e02ed89a1810c778dcd72072ff0e9621ba1379b4babe53921d71e2e4486fda3e languageName: node linkType: hard @@ -7938,10 +7945,10 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1": - version: 3.4.1 - resolution: "eslint-visitor-keys@npm:3.4.1" - checksum: f05121d868202736b97de7d750847a328fcfa8593b031c95ea89425333db59676ac087fa905eba438d0a3c5769632f828187e0c1a0d271832a2153c1d3661c2c +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.2": + version: 3.4.2 + resolution: "eslint-visitor-keys@npm:3.4.2" + checksum: 9e0e7e4aaea705c097ae37c97410e5f167d4d2193be2edcb1f0760762ede3df01545e4820ae314f42dcec687745f2c6dcaf6d83575c4a2a241eb0c8517d724f2 languageName: node linkType: hard @@ -7994,26 +8001,26 @@ __metadata: languageName: node linkType: hard -"eslint@npm:8.45.0": - version: 8.45.0 - resolution: "eslint@npm:8.45.0" +"eslint@npm:8.46.0": + version: 8.46.0 + resolution: "eslint@npm:8.46.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 - "@eslint-community/regexpp": ^4.4.0 - "@eslint/eslintrc": ^2.1.0 - "@eslint/js": 8.44.0 + "@eslint-community/regexpp": ^4.6.1 + "@eslint/eslintrc": ^2.1.1 + "@eslint/js": ^8.46.0 "@humanwhocodes/config-array": ^0.11.10 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 - ajv: ^6.10.0 + ajv: ^6.12.4 chalk: ^4.0.0 cross-spawn: ^7.0.2 debug: ^4.3.2 doctrine: ^3.0.0 escape-string-regexp: ^4.0.0 - eslint-scope: ^7.2.0 - eslint-visitor-keys: ^3.4.1 - espree: ^9.6.0 + eslint-scope: ^7.2.2 + eslint-visitor-keys: ^3.4.2 + espree: ^9.6.1 esquery: ^1.4.2 esutils: ^2.0.2 fast-deep-equal: ^3.1.3 @@ -8037,11 +8044,11 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 3e6dcce5cc43c5e301662db88ee26d1d188b22c177b9f104d7eefd1191236980bd953b3670fe2fac287114b26d7c5420ab48407d7ea1c3a446d6313c000009da + checksum: 7a7d36b1a3bbc12e08fbb5bc36fd482a7a5a1797e62e762499dd45601b9e45aaa53a129f31ce0b4444551a9639b8b681ad535f379893dd1e3ae37b31dccd82aa languageName: node linkType: hard -"espree@npm:^9.6.0": +"espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -11136,7 +11143,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.0": +"node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1": version: 2.6.12 resolution: "node-fetch@npm:2.6.12" dependencies: @@ -11150,20 +11157,6 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.1": - version: 2.6.9 - resolution: "node-fetch@npm:2.6.9" - dependencies: - whatwg-url: ^5.0.0 - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - checksum: acb04f9ce7224965b2b59e71b33c639794d8991efd73855b0b250921382b38331ffc9d61bce502571f6cc6e11a8905ca9b1b6d4aeb586ab093e2756a1fd190d0 - languageName: node - linkType: hard - "node-gyp-build@npm:^4.3.0": version: 4.6.0 resolution: "node-gyp-build@npm:4.6.0" @@ -11819,7 +11812,7 @@ __metadata: "@markdoc/next.js": 0.2.2 "@next/bundle-analyzer": 13.4.12 "@open-draft/until": 2.1.0 - "@pluralsh/design-system": 2.1.1 + "@pluralsh/design-system": 2.1.2 "@pluralsh/eslint-config-typescript": 2.5.56 "@pluralsh/stylelint-config": 2.0.5 "@react-types/shared": 3.18.1 @@ -11836,7 +11829,7 @@ __metadata: concurrently: 8.2.0 cross-env: 7.0.3 deep-freeze: 0.0.1 - eslint: 8.45.0 + eslint: 8.46.0 eslint-config-next: 13.4.10 eslint-config-prettier: 8.8.0 eslint-import-resolver-typescript: 3.5.5 @@ -12003,7 +11996,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.27": +"postcss@npm:8.4.27, postcss@npm:^8.2.4, postcss@npm:^8.4.16, postcss@npm:^8.4.21, postcss@npm:^8.4.23, postcss@npm:^8.4.24": version: 8.4.27 resolution: "postcss@npm:8.4.27" dependencies: @@ -12014,17 +12007,6 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.2.4, postcss@npm:^8.4.16, postcss@npm:^8.4.21, postcss@npm:^8.4.23, postcss@npm:^8.4.24": - version: 8.4.26 - resolution: "postcss@npm:8.4.26" - dependencies: - nanoid: ^3.3.6 - picocolors: ^1.0.0 - source-map-js: ^1.0.2 - checksum: 1cf08ee10d58cbe98f94bf12ac49a5e5ed1588507d333d2642aacc24369ca987274e1f60ff4cbf0081f70d2ab18a5cd3a4a273f188d835b8e7f3ba381b184e57 - languageName: node - linkType: hard - "posthog-js@npm:1.75.2": version: 1.75.2 resolution: "posthog-js@npm:1.75.2"