Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v2): Support swizzling TypeScript components #2671

Merged
merged 9 commits into from
Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ packages/docusaurus-plugin-debug/lib/
packages/docusaurus-plugin-sitemap/lib/
packages/docusaurus-plugin-ideal-image/lib/
packages/docusaurus-plugin-ideal-image/copyUntypedFiles.js
packages/docusaurus-theme-classic/lib/

packages/docusaurus-1.x/.eslintrc.js
packages/docusaurus-init/templates/facebook/.eslintrc.js
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ packages/docusaurus-plugin-content-pages/lib/
packages/docusaurus-plugin-debug/lib/
packages/docusaurus-plugin-sitemap/lib/
packages/docusaurus-plugin-ideal-image/lib/
packages/docusaurus-theme-classic/lib/
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/cli": "^7.9.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
"@babel/preset-typescript": "^7.9.0",
Expand All @@ -52,6 +53,7 @@
"@types/lodash.pick": "^4.4.6",
"@types/lodash.pickby": "^4.6.6",
"@types/node": "^13.11.0",
"@types/prismjs": "^1.16.1",
"@types/react": "^16.9.38",
"@types/react-dev-utils": "^9.0.1",
"@types/react-helmet": "^6.0.0",
Expand Down
7 changes: 3 additions & 4 deletions packages/docusaurus-module-type-aliases/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ declare module '@generated/routesChunkNames' {
export default routesChunkNames;
}

declare module '@theme/*' {
const component: any;
export default component;
}
declare module '@theme/*';

declare module '@theme-original/*';

declare module '@docusaurus/*';

Expand Down
10 changes: 10 additions & 0 deletions packages/docusaurus-theme-classic/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* 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.
*/

module.exports = {
presets: [['@babel/preset-typescript', {isTSX: true, allExtensions: true}]],
};
8 changes: 8 additions & 0 deletions packages/docusaurus-theme-classic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
"access": "public"
},
"license": "MIT",
"scripts": {
"tsc": "tsc --noEmit && yarn babel && yarn prettier",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably rename the tsc scripts to just build or something (can be in another PR)

Also, I added recently a global yarn watch command, all TS subprojects should rather implement it as well

"babel": "babel src -d lib --extensions \".tsx,.ts\" --copy-files",
"prettier": "prettier --config ../../.prettierrc --write \"**/*.{js,ts}\""
},
"dependencies": {
"@mdx-js/mdx": "^1.5.8",
"@mdx-js/react": "^1.5.8",
Expand All @@ -20,6 +25,9 @@
"react-router-dom": "^5.1.2",
"react-toggle": "^4.1.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.0.0-alpha.58"
},
"peerDependencies": {
"@docusaurus/core": "^2.0.0",
"react": "^16.8.4",
Expand Down
4 changes: 4 additions & 0 deletions packages/docusaurus-theme-classic/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ module.exports = function (context, options) {
name: 'docusaurus-theme-classic',

getThemePath() {
return path.join(__dirname, '..', 'lib', 'theme');
},

getTypeScriptThemePath() {
return path.resolve(__dirname, './theme');
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import useUserPreferencesContext from '@theme/hooks/useUserPreferencesContext';

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

function AnnouncementBar() {
function AnnouncementBar(): JSX.Element | null {
const {
siteConfig: {themeConfig: {announcementBar = {}}} = {},
siteConfig: {themeConfig: {announcementBar = {}} = {}} = {},
} = useDocusaurusContext();
const {content, backgroundColor, textColor} = announcementBar;
const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import Layout from '@theme/Layout';
import BlogPostItem from '@theme/BlogPostItem';
import BlogListPaginator from '@theme/BlogListPaginator';

function BlogListPage(props) {
type Props = {
metadata: {permalink: string; title: string};
items: {content}[];
};

function BlogListPage(props: Props): JSX.Element {
const {metadata, items} = props;
const {
siteConfig: {title: siteTitle},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import React from 'react';
import Link from '@docusaurus/Link';

function BlogListPaginator(props) {
function BlogListPaginator(props): JSX.Element {
const {metadata} = props;
const {previousPage, nextPage} = metadata;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const MONTHS = [
'December',
];

function BlogPostItem(props) {
function BlogPostItem(props): JSX.Element {
const {
children,
frontMatter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Layout from '@theme/Layout';
import BlogPostItem from '@theme/BlogPostItem';
import BlogPostPaginator from '@theme/BlogPostPaginator';

function BlogPostPage(props) {
function BlogPostPage(props): JSX.Element {
const {content: BlogPostContents} = props;
const {frontMatter, metadata} = BlogPostContents;
const {title, description, nextItem, prevItem, editUrl} = metadata;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import React from 'react';
import Link from '@docusaurus/Link';

function BlogPostPaginator(props) {
function BlogPostPaginator(props): JSX.Element {
const {nextItem, prevItem} = props;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ import React from 'react';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';

function getCategoryOfTag(tag) {
function getCategoryOfTag(tag: string) {
// tag's category should be customizable
return tag[0].toUpperCase();
}

function BlogTagsListPage(props) {
type Tag = {permalink: string; name: string; count: number};

function BlogTagsListPage(props: {tags: Record<string, Tag>}): JSX.Element {
const {tags} = props;

const tagCategories = {};
const tagCategories: {[category: string]: string[]} = {};
Object.keys(tags).forEach((tag) => {
const category = getCategoryOfTag(tag);
tagCategories[category] = tagCategories[category] || [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import Layout from '@theme/Layout';
import BlogPostItem from '@theme/BlogPostItem';
import Link from '@docusaurus/Link';

function pluralize(count, word) {
function pluralize(count: number, word: string) {
return count > 1 ? `${word}s` : word;
}

function BlogTagsPostPage(props) {
function BlogTagsPostPage(props): JSX.Element {
const {metadata, items} = props;
const {allTagsPath, name: tagName, count} = metadata;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,15 @@ const highlightDirectiveRegex = (lang) => {
};
const codeBlockTitleRegex = /title=".*"/;

export default ({children, className: languageClassName, metastring}) => {
export default ({
children,
className: languageClassName,
metastring,
}: {
children: string;
className: string;
metastring: string;
}): JSX.Element => {
const {
siteConfig: {
themeConfig: {prism = {}},
Expand All @@ -108,21 +116,25 @@ export default ({children, className: languageClassName, metastring}) => {
}, []);

const button = useRef(null);
let highlightLines = [];
let highlightLines: number[] = [];
let codeBlockTitle = '';

const prismTheme = usePrismTheme();

if (metastring && highlightLinesRangeRegex.test(metastring)) {
const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1];
// Tested above
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const highlightLinesRange = metastring.match(highlightLinesRangeRegex)![1];
highlightLines = rangeParser
.parse(highlightLinesRange)
.filter((n) => n > 0);
}

if (metastring && codeBlockTitleRegex.test(metastring)) {
// Tested above
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
codeBlockTitle = metastring
.match(codeBlockTitleRegex)[0]
.match(codeBlockTitleRegex)![0]
.split('title=')[1]
.replace(/"+/g, '');
}
Expand Down Expand Up @@ -151,7 +163,10 @@ export default ({children, className: languageClassName, metastring}) => {
if (match !== null) {
const directive = match
.slice(1)
.reduce((final, item) => final || item, undefined);
.reduce(
(final: string | undefined, item) => final || item,
undefined,
);
switch (directive) {
case 'highlight-next-line':
range += `${lineNumber},`;
Expand Down Expand Up @@ -188,9 +203,10 @@ export default ({children, className: languageClassName, metastring}) => {
return (
<Highlight
{...defaultProps}
key={mounted}
key={String(mounted)}
theme={prismTheme}
code={code}
// @ts-expect-error: prism-react-renderer doesn't export Language type
language={language}>
{({className, style, tokens, getLineProps, getTokenProps}) => (
<>
Expand All @@ -211,7 +227,7 @@ export default ({children, className: languageClassName, metastring}) => {
{showCopied ? 'Copied' : 'Copy'}
</button>
<div
tabIndex="0"
tabIndex={0}
className={clsx(className, styles.codeBlock, {
[styles.codeBlockWithTitle]: codeBlockTitle,
})}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function DocTOC({headings}) {
}

/* eslint-disable jsx-a11y/control-has-associated-label */
function Headings({headings, isChild}) {
function Headings({headings, isChild}: {headings; isChild?: boolean}) {
if (!headings.length) {
return null;
}
Expand All @@ -58,7 +58,7 @@ function Headings({headings, isChild}) {
);
}

function DocItem(props) {
function DocItem(props): JSX.Element {
const {siteConfig = {}} = useDocusaurusContext();
const {url: siteUrl, title: siteTitle} = siteConfig;
const {content: DocContent} = props;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {matchPath} from '@docusaurus/router';

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

function DocPage(props) {
function DocPage(props): JSX.Element {
const {route: baseRoute, docsMetadata, location} = props;
// case-sensitive route such as it is defined in the sidebar
const currentRoute =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
import React from 'react';
import Link from '@docusaurus/Link';

function DocPaginator(props) {
type PageInfo = {permalink: string; title: string};

type Props = {
metadata: {previous: PageInfo; next: PageInfo};
};

function DocPaginator(props: Props): JSX.Element {
const {metadata} = props;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,11 @@ function DocSidebarItem(props) {
}
}

function DocSidebar(props) {
function DocSidebar(props): JSX.Element | null {
const [showResponsiveSidebar, setShowResponsiveSidebar] = useState(false);
const {
siteConfig: {
themeConfig: {navbar: {title, hideOnScroll = false} = {}},
themeConfig: {navbar: {title = '', hideOnScroll = false} = {}} = {},
} = {},
isClient,
} = useDocusaurusContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const FooterLogo = ({url, alt}) => (
<img className="footer__logo" alt={alt} src={url} />
);

function Footer() {
function Footer(): JSX.Element | null {
const context = useDocusaurusContext();
const {siteConfig = {}} = context;
const {themeConfig = {}} = siteConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

/* eslint-disable jsx-a11y/anchor-has-content, jsx-a11y/anchor-is-valid */

import React from 'react';
import React, {ComponentType} from 'react';
import clsx from 'clsx';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';

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

const Heading = (Tag) =>
const Heading = (Tag: ComponentType): ((props) => JSX.Element) =>
function TargetComponent({id, ...props}) {
const {
siteConfig: {
Expand All @@ -30,7 +30,7 @@ const Heading = (Tag) =>
<Tag {...props}>
<a
aria-hidden="true"
tabIndex="-1"
tabIndex={-1}
className={clsx('anchor', {
[styles.enhancedAnchor]: !hideOnScroll,
})}
Expand All @@ -39,7 +39,7 @@ const Heading = (Tag) =>
{props.children}
<a
aria-hidden="true"
tabIndex="-1"
tabIndex={-1}
className="hash-link"
href={`#${id}`}
title="Direct link to heading">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import React, {ReactNode} from 'react';
import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl';
Expand All @@ -18,7 +18,18 @@ import Footer from '@theme/Footer';

import './styles.css';

function Layout(props) {
type Props = {
children: ReactNode;
title?: string;
noFooter?: boolean;
description?: string;
image?: string;
keywords?: string[];
permalink?: string;
version?: string;
};

function Layout(props: Props): JSX.Element {
const {siteConfig = {}} = useDocusaurusContext();
const {
favicon,
Expand Down
Loading