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

refactor(theme-classic): completely migrate package to TypeScript #5459

Merged
merged 8 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from 7 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
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ Object {
\\"pluginId\\": \\"default\\",
\\"version\\": \\"current\\",
\\"label\\": \\"Next\\",
\\"banner\\": \\"none\\",
\\"banner\\": null,
\\"badge\\": false,
\\"className\\": \\"docs-version-current\\",
\\"isLast\\": true,
Expand Down Expand Up @@ -1025,7 +1025,7 @@ Object {
\\"pluginId\\": \\"community\\",
\\"version\\": \\"1.0.0\\",
\\"label\\": \\"1.0.0\\",
\\"banner\\": \\"none\\",
\\"banner\\": null,
\\"badge\\": true,
\\"className\\": \\"docs-version-1.0.0\\",
\\"isLast\\": true,
Expand Down Expand Up @@ -1722,7 +1722,7 @@ Object {
\\"pluginId\\": \\"default\\",
\\"version\\": \\"1.0.1\\",
\\"label\\": \\"1.0.1\\",
\\"banner\\": \\"none\\",
\\"banner\\": null,
\\"badge\\": true,
\\"className\\": \\"docs-version-1.0.1\\",
\\"isLast\\": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('simple site', () => {
versionLabel: 'Next',
versionName: 'current',
versionPath: '/docs',
versionBanner: 'none',
versionBanner: null,
versionBadge: false,
versionClassName: 'docs-version-current',
};
Expand Down Expand Up @@ -262,7 +262,7 @@ describe('versioned site, pluginId=default', () => {
versionLabel: '1.0.1',
versionName: '1.0.1',
versionPath: '/docs',
versionBanner: 'none',
versionBanner: null,
versionBadge: true,
versionClassName: 'docs-version-1.0.1',
};
Expand Down Expand Up @@ -554,7 +554,7 @@ describe('versioned site, pluginId=default', () => {
routePriority: -1,
tagsPath: '/docs/tags',
versionPath: '/docs',
versionBanner: 'none',
versionBanner: null,
versionBadge: false,
},
]);
Expand Down Expand Up @@ -702,7 +702,7 @@ describe('versioned site, pluginId=community', () => {
versionLabel: '1.0.0',
versionName: '1.0.0',
versionPath: '/communityBasePath',
versionBanner: 'none',
versionBanner: null,
versionBadge: true,
versionClassName: 'docs-version-1.0.0',
};
Expand Down Expand Up @@ -750,7 +750,7 @@ describe('versioned site, pluginId=community', () => {
routePriority: -1,
tagsPath: '/communityBasePath/tags',
versionPath: '/communityBasePath',
versionBanner: 'none',
versionBanner: null,
versionBadge: false,
},
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ declare module '@docusaurus/plugin-content-docs' {

// TODO public api surface types should rather be exposed as "@docusaurus/plugin-content-docs"
declare module '@docusaurus/plugin-content-docs-types' {
type VersionBanner = import('./types').VersionBanner;
export type VersionBanner = import('./types').VersionBanner;
type GlobalDataVersion = import('./types').GlobalVersion;
type GlobalDataDoc = import('./types').GlobalDoc;
type VersionTag = import('./types').VersionTag;
Expand All @@ -22,7 +22,7 @@ declare module '@docusaurus/plugin-content-docs-types' {
pluginId: string;
version: string;
label: string;
banner: VersionBanner;
banner: VersionBanner | null;
badge: boolean;
className: string;
isLast: boolean;
Expand Down
6 changes: 3 additions & 3 deletions packages/docusaurus-plugin-content-docs/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export type VersionMetadata = ContentPaths & {
tagsPath: string;
versionEditUrl?: string | undefined;
versionEditUrlLocalized?: string | undefined;
versionBanner: VersionBanner;
versionBanner: VersionBanner | null;
versionBadge: boolean;
versionClassName: string;
isLast: boolean;
Expand Down Expand Up @@ -65,12 +65,12 @@ export type PathOptions = {
};

// TODO support custom version banner? {type: "error", content: "html content"}
export type VersionBanner = 'none' | 'unreleased' | 'unmaintained';
export type VersionBanner = 'unreleased' | 'unmaintained';

export type VersionOptions = {
path?: string;
label?: string;
banner?: VersionBanner;
banner?: 'none' | VersionBanner;
badge?: boolean;
className?: string;
};
Expand Down
25 changes: 12 additions & 13 deletions packages/docusaurus-plugin-content-docs/src/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,10 @@ function getDefaultVersionBanner({
versionName: string;
versionNames: string[];
lastVersionName: string;
}): VersionBanner {
}): VersionBanner | null {
// Current version: good, no banner
if (versionName === lastVersionName) {
return 'none';
return null;
}
// Upcoming versions: unreleased banner
else if (
Expand All @@ -291,17 +291,16 @@ function getVersionBanner({
versionNames: string[];
lastVersionName: string;
options: Pick<PluginOptions, 'versions'>;
}): VersionBanner {
const versionOptionBanner = options.versions[versionName]?.banner;

return (
versionOptionBanner ??
getDefaultVersionBanner({
versionName,
versionNames,
lastVersionName,
})
);
}): VersionBanner | null {
const versionBannerOption = options.versions[versionName]?.banner;
if (versionBannerOption) {
return versionBannerOption === 'none' ? null : versionBannerOption;
}
return getDefaultVersionBanner({
versionName,
versionNames,
lastVersionName,
});
}

function getVersionBadge({
Expand Down
2 changes: 2 additions & 0 deletions packages/docusaurus-theme-classic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.0.0-beta.5",
"@types/mdx-js__react": "^1.5.4",
"@types/parse-numeric-range": "^0.0.1",
"@types/rtlcss": "^3.1.1",
"utility-types": "^3.10.0"
},
"peerDependencies": {
Expand Down
13 changes: 8 additions & 5 deletions packages/docusaurus-theme-classic/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {ThemeConfig} from '@docusaurus/theme-common';
import {getTranslationFiles, translateThemeConfig} from './translations';
import path from 'path';
import Module from 'module';
import type {AcceptedPlugin, Result, Plugin as PostCssPlugin} from 'postcss';
import type {AcceptedPlugin, Plugin as PostCssPlugin} from 'postcss';
import rtlcss from 'rtlcss';
import {readDefaultCodeTranslationMessages} from '@docusaurus/utils';

Expand All @@ -25,7 +25,10 @@ const ContextReplacementPlugin = requireFromDocusaurusCore(
// Need to be inlined to prevent dark mode FOUC
// Make sure that the 'storageKey' is the same as the one in `/theme/hooks/useTheme.js`
const ThemeStorageKey = 'theme';
const noFlashColorMode = ({defaultMode, respectPrefersColorScheme}) => {
const noFlashColorMode = ({
defaultMode,
respectPrefersColorScheme,
}: ThemeConfig['colorMode']) => {
return `(function() {
var defaultMode = '${defaultMode}';
var respectPrefersColorScheme = ${respectPrefersColorScheme};
Expand Down Expand Up @@ -83,7 +86,7 @@ const AnnouncementBarInlineJavaScript = `
document.documentElement.setAttribute('${AnnouncementBarDismissDataAttribute}', isDismissed());
})();`;

function getInfimaCSSFile(direction) {
function getInfimaCSSFile(direction: string) {
return `infima/dist/css/default/default${
direction === 'rtl' ? '-rtl' : ''
}.css`;
Expand Down Expand Up @@ -183,13 +186,13 @@ export default function docusaurusThemeClassic(
const resolvedInfimaFile = require.resolve(getInfimaCSSFile(direction));
const plugin: PostCssPlugin = {
postcssPlugin: 'RtlCssPlugin',
prepare: (result: Result) => {
prepare: (result) => {
const file = result.root?.source?.input?.file;
// Skip Infima as we are using the its RTL version.
if (file === resolvedInfimaFile) {
return {};
}
return rtlcss(result.root);
return rtlcss((result.root as unknown) as rtlcss.ConfigOptions);
},
};
postCssOptions.plugins.push(plugin);
Expand Down
90 changes: 51 additions & 39 deletions packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,51 +18,63 @@ import styles from './styles.module.css';

import {useThemeConfig, parseCodeBlockTitle} from '@docusaurus/theme-common';

const highlightLinesRangeRegex = /{([\d,-]+)}/;
const HighlightLinesRangeRegex = /{([\d,-]+)}/;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As I understand PascalCased variables should be objects right? (Also noticed this in docusaurus-init where TypeScriptTemplateSuffix is PascalCased)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't have a strong opinion about JS constant namings as long as it's clear enough those are constants. We already have this convention in other places so just made it consistent, but we can also redefine those conventions if needed


const HighlightLanguages = ['js', 'jsBlock', 'jsx', 'python', 'html'] as const;
type HighlightLanguage = typeof HighlightLanguages[number];

type HighlightLanguageConfig = {
start: string;
end: string;
};

// Supported types of highlight comments
const HighlightComments: Record<HighlightLanguage, HighlightLanguageConfig> = {
js: {
start: '\\/\\/',
end: '',
},
jsBlock: {
start: '\\/\\*',
end: '\\*\\/',
},
jsx: {
start: '\\{\\s*\\/\\*',
end: '\\*\\/\\s*\\}',
},
python: {
start: '#',
end: '',
},
html: {
start: '<!--',
end: '-->',
},
};

// Supported highlight directives
const HighlightDirectives = [
'highlight-next-line',
'highlight-start',
'highlight-end',
];

const getHighlightDirectiveRegex = (
languages = ['js', 'jsBlock', 'jsx', 'python', 'html'],
) => {
// supported types of comments
const comments = {
js: {
start: '\\/\\/',
end: '',
},
jsBlock: {
start: '\\/\\*',
end: '\\*\\/',
},
jsx: {
start: '\\{\\s*\\/\\*',
end: '\\*\\/\\s*\\}',
},
python: {
start: '#',
end: '',
},
html: {
start: '<!--',
end: '-->',
},
};
// supported directives
const directives = [
'highlight-next-line',
'highlight-start',
'highlight-end',
].join('|');
languages: readonly HighlightLanguage[] = HighlightLanguages,
): RegExp => {
// to be more reliable, the opening and closing comment must match
const commentPattern = languages
.map(
(lang) =>
`(?:${comments[lang].start}\\s*(${directives})\\s*${comments[lang].end})`,
)
.map((lang) => {
const {start, end} = HighlightComments[lang];
return `(?:${start}\\s*(${HighlightDirectives.join('|')})\\s*${end})`;
})
.join('|');
// white space is allowed, but otherwise it should be on it's own line
return new RegExp(`^\\s*(?:${commentPattern})\\s*$`);
};

// select comment styles based on language
const highlightDirectiveRegex = (lang: string) => {
const highlightDirectiveRegex = (lang: string): RegExp => {
switch (lang) {
case 'js':
case 'javascript':
Expand Down Expand Up @@ -123,9 +135,9 @@ export default function CodeBlock({
? children.join('')
: (children as string);

if (metastring && highlightLinesRangeRegex.test(metastring)) {
if (metastring && HighlightLinesRangeRegex.test(metastring)) {
// Tested above
const highlightLinesRange = metastring.match(highlightLinesRangeRegex)![1];
const highlightLinesRange = metastring.match(HighlightLinesRangeRegex)![1];
highlightLines = rangeParser(highlightLinesRange).filter((n) => n > 0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function useShowAnnouncementBar() {
return showAnnouncementBar;
}

function HideableSidebarButton({onClick}) {
function HideableSidebarButton({onClick}: {onClick: React.MouseEventHandler}) {
return (
<button
type="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import type {

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

const isActiveSidebarItem = (item: Props['item'], activePath: string) => {
const isActiveSidebarItem = (
item: Props['item'],
activePath: string,
): boolean => {
if (item.type === 'link') {
return isSamePath(item.href, activePath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {

import type {Props} from '@theme/DocVersionBanner';
import clsx from 'clsx';
import type {VersionBanner} from '@docusaurus/plugin-content-docs-types';

type BannerLabelComponentProps = {
siteTitle: string;
Expand Down Expand Up @@ -66,7 +67,7 @@ function UnmaintainedVersionLabel({
}

const BannerLabelComponents: Record<
Exclude<Props['versionMetadata']['banner'], 'none'>,
VersionBanner,
ComponentType<BannerLabelComponentProps>
> = {
unreleased: UnreleasedVersionLabel,
Expand All @@ -75,7 +76,7 @@ const BannerLabelComponents: Record<

function BannerLabel(props: BannerLabelComponentProps) {
const BannerLabelComponent =
BannerLabelComponents[props.versionMetadata.banner];
BannerLabelComponents[props.versionMetadata.banner!];
return <BannerLabelComponent {...props} />;
}

Expand Down Expand Up @@ -156,11 +157,10 @@ function DocVersionBannerEnabled({versionMetadata}: Props): JSX.Element {
}

function DocVersionBanner({versionMetadata}: Props): JSX.Element {
if (versionMetadata.banner === 'none') {
return <></>;
} else {
if (versionMetadata.banner) {
return <DocVersionBannerEnabled versionMetadata={versionMetadata} />;
}
return <></>;
}

export default DocVersionBanner;
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ import {
import type {Props} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
import {useDocsPreferredVersion} from '@docusaurus/theme-common';
import {translate} from '@docusaurus/Translate';
import type {GlobalDataVersion} from '@docusaurus/plugin-content-docs-types';

const getVersionMainDoc = (version) =>
version.docs.find((doc) => doc.id === version.mainDocId);
const getVersionMainDoc = (version: GlobalDataVersion) =>
version.docs.find((doc) => doc.id === version.mainDocId)!;

export default function DocsVersionDropdownNavbarItem({
mobile,
Expand Down
Loading