Skip to content

Commit

Permalink
Merge branch 'main' of github.com:facebook/docusaurus into lex111/hig…
Browse files Browse the repository at this point in the history
…hlight-code-line-built
  • Loading branch information
lex111 committed Apr 15, 2022
2 parents 916f922 + 84d04ed commit f7613a2
Show file tree
Hide file tree
Showing 20 changed files with 539 additions and 277 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,22 @@ describe('themeConfig', () => {
},
],
},
// HTML-only
{
type: 'html',
position: 'right',
value: '<button>Give feedback</button>',
},
// Dropdown with label as HTML
{
type: 'dropdown',
label: 'Tools <sup>new</sup>',
position: 'left',
items: [
{
type: 'html',
value: '<b>Supported package managers</b>',
},
{
type: 'doc',
docId: 'npm',
Expand All @@ -181,6 +191,10 @@ describe('themeConfig', () => {
},
],
dropdownItemsAfter: [
{
type: 'html',
value: '<hr/>',
},
{
to: '/versions',
label: 'All versions',
Expand Down
68 changes: 65 additions & 3 deletions packages/docusaurus-theme-classic/src/theme-classic.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ declare module '@theme/BlogLayout' {
}

declare module '@theme/CodeBlock' {
import type {ReactElement} from 'react';
import type {ReactNode} from 'react';

export interface Props {
readonly children: string | ReactElement;
readonly children: ReactNode;
readonly className?: string;
readonly metastring?: string;
readonly title?: string;
Expand All @@ -170,6 +170,56 @@ declare module '@theme/CodeBlock/CopyButton' {
export default function CopyButton(props: Props): JSX.Element;
}

declare module '@theme/CodeBlock/Container' {
import type {ComponentProps} from 'react';

export default function CodeBlockContainer<T extends 'div' | 'pre'>({
as: As,
...props
}: {as: T} & ComponentProps<T>): JSX.Element;
}

declare module '@theme/CodeBlock/Content/Element' {
import type {Props} from '@theme/CodeBlock';

export type {Props};

export default function CodeBlockElementContent(props: Props): JSX.Element;
}

declare module '@theme/CodeBlock/Content/String' {
import type {Props as CodeBlockProps} from '@theme/CodeBlock';

export interface Props extends Omit<CodeBlockProps, 'children'> {
readonly children: string;
}

export default function CodeBlockStringContent(props: Props): JSX.Element;
}

declare module '@theme/CodeBlock/Line' {
import type {ComponentProps} from 'react';
import type Highlight from 'prism-react-renderer';

// Lib does not make this easy
type RenderProps = Parameters<
ComponentProps<typeof Highlight>['children']
>[0];
type GetLineProps = RenderProps['getLineProps'];
type GetTokenProps = RenderProps['getTokenProps'];
type Token = RenderProps['tokens'][number][number];

export interface Props {
readonly line: Token[];
readonly highlight: boolean;
readonly showLineNumbers: boolean;
readonly getLineProps: GetLineProps;
readonly getTokenProps: GetTokenProps;
}

export default function CodeBlockLine(props: Props): JSX.Element;
}

declare module '@theme/DocCard' {
import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';

Expand Down Expand Up @@ -822,6 +872,16 @@ declare module '@theme/NavbarItem/DocSidebarNavbarItem' {
export default function DocSidebarNavbarItem(props: Props): JSX.Element;
}

declare module '@theme/NavbarItem/HtmlNavbarItem' {
import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem';

export interface Props extends DefaultNavbarItemProps {
readonly value: string;
}

export default function HtmlNavbarItem(props: Props): JSX.Element;
}

declare module '@theme/NavbarItem' {
import type {ComponentProps} from 'react';
import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem';
Expand All @@ -832,12 +892,14 @@ declare module '@theme/NavbarItem' {
import type {Props as DocsVersionDropdownNavbarItemProps} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
import type {Props as LocaleDropdownNavbarItemProps} from '@theme/NavbarItem/LocaleDropdownNavbarItem';
import type {Props as SearchNavbarItemProps} from '@theme/NavbarItem/SearchNavbarItem';
import type {Props as HtmlNavbarItemProps} from '@theme/NavbarItem/HtmlNavbarItem';

export type LinkLikeNavbarItemProps =
| ({readonly type?: 'default'} & DefaultNavbarItemProps)
| ({readonly type: 'doc'} & DocNavbarItemProps)
| ({readonly type: 'docsVersion'} & DocsVersionNavbarItemProps)
| ({readonly type: 'docSidebar'} & DocSidebarNavbarItemProps);
| ({readonly type: 'docSidebar'} & DocSidebarNavbarItemProps)
| ({readonly type: 'html'} & HtmlNavbarItemProps);

export type Props = ComponentProps<'a'> & {
readonly position?: 'left' | 'right';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React, {type ComponentProps} from 'react';
import clsx from 'clsx';
import {
usePrismTheme,
getPrismCssVariables,
ThemeClassNames,
} from '@docusaurus/theme-common';
import styles from './styles.module.css';

export default function CodeBlockContainer<T extends 'div' | 'pre'>({
as: As,
...props
}: {as: T} & ComponentProps<T>): JSX.Element {
const prismTheme = usePrismTheme();
const prismCssVariables = getPrismCssVariables(prismTheme);
return (
<As
// Polymorphic components are hard to type, without `oneOf` generics
{...(props as never)}
style={prismCssVariables}
className={clsx(
props.className,
styles.codeBlockContainer,
ThemeClassNames.common.codeBlock,
)}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

.codeBlockContainer {
background: var(--prism-background-color);
color: var(--prism-color);
margin-bottom: var(--ifm-leading);
box-shadow: var(--ifm-global-shadow-lw);
border-radius: var(--ifm-code-border-radius);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import Container from '@theme/CodeBlock/Container';
import clsx from 'clsx';
import type {Props} from '@theme/CodeBlock/Content/Element';

import styles from './styles.module.css';

// <pre> tags in markdown map to CodeBlocks. They may contain JSX children. When
// the children is not a simple string, we just return a styled block without
// actually highlighting.
export default function CodeBlockJSX({
children,
className,
}: Props): JSX.Element {
return (
<Container
as="pre"
tabIndex={0}
className={clsx(styles.codeBlockStandalone, 'thin-scrollbar', className)}>
<code className={styles.codeBlockLines}>{children}</code>
</Container>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import {
useThemeConfig,
parseCodeBlockTitle,
parseLanguage,
parseLines,
containsLineNumbers,
usePrismTheme,
} from '@docusaurus/theme-common';
import clsx from 'clsx';
import Highlight, {defaultProps, type Language} from 'prism-react-renderer';
import Line from '@theme/CodeBlock/Line';
import CopyButton from '@theme/CodeBlock/CopyButton';
import Container from '@theme/CodeBlock/Container';
import type {Props} from '@theme/CodeBlock/Content/String';

import styles from './styles.module.css';

export default function CodeBlockString({
children,
className: blockClassName = '',
metastring,
title: titleProp,
showLineNumbers: showLineNumbersProp,
language: languageProp,
}: Props): JSX.Element {
const {
prism: {defaultLanguage},
} = useThemeConfig();
const language =
languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage;
const prismTheme = usePrismTheme();

// We still parse the metastring in case we want to support more syntax in the
// future. Note that MDX doesn't strip quotes when parsing metastring:
// "title=\"xyz\"" => title: "\"xyz\""
const title = parseCodeBlockTitle(metastring) || titleProp;

const {highlightLines, code} = parseLines(children, metastring, language);
const showLineNumbers =
showLineNumbersProp || containsLineNumbers(metastring);

return (
<Container
as="div"
className={clsx(
blockClassName,
language &&
!blockClassName.includes(`language-${language}`) &&
`language-${language}`,
)}>
{title && <div className={styles.codeBlockTitle}>{title}</div>}
<div className={styles.codeBlockContent}>
<Highlight
{...defaultProps}
theme={prismTheme}
code={code}
language={(language ?? 'text') as Language}>
{({className, tokens, getLineProps, getTokenProps}) => (
<pre
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
tabIndex={0}
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
<code
className={clsx(
styles.codeBlockLines,
showLineNumbers && styles.codeBlockLinesWithNumbering,
)}>
{tokens.map((line, i) => (
<Line
key={i}
line={line}
getLineProps={getLineProps}
getTokenProps={getTokenProps}
highlight={highlightLines.includes(i)}
showLineNumbers={showLineNumbers}
/>
))}
</code>
</pre>
)}
</Highlight>
<CopyButton code={code} />
</div>
</Container>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

.codeBlockContent {
position: relative;
/* rtl:ignore */
direction: ltr;
border-radius: inherit;
}

.codeBlockTitle {
border-bottom: 1px solid var(--ifm-color-emphasis-300);
font-size: var(--ifm-code-font-size);
font-weight: 500;
padding: 0.75rem var(--ifm-pre-padding);
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}

.codeBlock {
--ifm-pre-background: var(--prism-background-color);
margin: 0;
padding: 0;
}

.codeBlockTitle + .codeBlockContent .codeBlock {
border-top-left-radius: 0;
border-top-right-radius: 0;
}

.codeBlockStandalone {
padding: 0;
}

.codeBlockLines {
font: inherit;
/* rtl:ignore */
float: left;
min-width: 100%;
padding: var(--ifm-pre-padding);
}

.codeBlockLinesWithNumbering {
display: table;
padding: var(--ifm-pre-padding) 0;
}

@media print {
.codeBlockLines {
white-space: pre-wrap;
}
}
Loading

0 comments on commit f7613a2

Please sign in to comment.