Merge branch 'main' of github.com:facebook/docusaurus into lex111/filter-sidebar

This commit is contained in:
Alexey Pyltsyn 2022-03-20 13:24:48 +03:00
commit aa997da632
47 changed files with 979 additions and 836 deletions

View file

@ -16,6 +16,6 @@ packages/stylelint-copyright/lib/
copyUntypedFiles.mjs
packages/create-docusaurus/lib/*
packages/create-docusaurus/templates/facebook/.eslintrc.js
packages/create-docusaurus/templates/facebook
website/_dogfooding/_swizzle_theme_tests

View file

@ -1,21 +0,0 @@
/**
* 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/env',
{
targets: {
node: 'current',
},
},
],
'@babel/react',
'@babel/preset-typescript',
],
};

View file

@ -30,7 +30,7 @@ export default {
testPathIgnorePatterns: ignorePatterns,
coveragePathIgnorePatterns: ignorePatterns,
transform: {
'^.+\\.[jt]sx?$': 'babel-jest',
'^.+\\.[jt]sx?$': '@swc/jest',
},
errorOnDeprecated: true,
moduleNameMapper: {

View file

@ -64,6 +64,8 @@
"@babel/core": "^7.17.7",
"@babel/preset-typescript": "^7.16.7",
"@crowdin/cli": "^3.7.8",
"@swc/core": "^1.2.158",
"@swc/jest": "^0.2.20",
"@testing-library/react-hooks": "^7.0.2",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.4.1",

View file

@ -92,8 +92,6 @@ declare module '@theme/Layout' {
export interface Props {
readonly children?: ReactNode;
readonly title?: string;
readonly description?: string;
}
export default function Layout(props: Props): JSX.Element;
}
@ -117,6 +115,10 @@ declare module '@theme/Root' {
export default function Root({children}: Props): JSX.Element;
}
declare module '@theme/SiteMetadata' {
export default function SiteMetadata(): JSX.Element;
}
declare module '@docusaurus/constants' {
export const DEFAULT_PLUGIN_ID: 'default';
}

View file

@ -368,31 +368,17 @@ declare module '@theme/Layout' {
export interface Props {
readonly children?: ReactNode;
readonly title?: string;
readonly noFooter?: boolean;
readonly description?: string;
readonly image?: string;
readonly keywords?: string | string[];
readonly permalink?: string;
readonly wrapperClassName?: string;
readonly pageClassName?: string;
readonly searchMetadata?: {
readonly version?: string;
readonly tag?: string;
};
// Not really layout-related, but kept for convenience/retro-compatibility
readonly title?: string;
readonly description?: string;
}
export default function Layout(props: Props): JSX.Element;
}
declare module '@theme/LayoutHead' {
import type {Props as LayoutProps} from '@theme/Layout';
export interface Props extends Omit<LayoutProps, 'children'> {}
export default function LayoutHead(props: Props): JSX.Element;
}
declare module '@theme/LayoutProviders' {
import type {ReactNode} from 'react';
@ -484,7 +470,7 @@ declare module '@theme/Navbar/Content' {
declare module '@theme/Navbar/Layout' {
export interface Props {
children: React.ReactNode;
readonly children: React.ReactNode;
}
export default function NavbarLayout(props: Props): JSX.Element;
@ -924,28 +910,6 @@ declare module '@theme/Tag' {
export default function Tag(props: Props): JSX.Element;
}
declare module '@theme/prism-include-languages' {
import type * as PrismNamespace from 'prismjs';
export default function prismIncludeLanguages(
PrismObject: typeof PrismNamespace,
): void;
}
declare module '@theme/Seo' {
import type {ReactNode} from 'react';
export interface Props {
readonly title?: string;
readonly description?: string;
readonly keywords?: readonly string[] | string;
readonly image?: string;
readonly children?: ReactNode;
}
export default function Seo(props: Props): JSX.Element;
}
declare module '@theme/TextHighlight' {
export interface Props {
readonly text?: string;
@ -954,3 +918,11 @@ declare module '@theme/TextHighlight' {
export default function TextHighlight(props: Props): JSX.Element;
}
declare module '@theme/prism-include-languages' {
import type * as PrismNamespace from 'prismjs';
export default function prismIncludeLanguages(
PrismObject: typeof PrismNamespace,
): void;
}

View file

@ -10,6 +10,7 @@ import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import type {ArchiveBlogPost, Props} from '@theme/BlogArchivePage';
import {translate} from '@docusaurus/Translate';
import {PageMetadata} from '@docusaurus/theme-common';
type YearProp = {
year: string;
@ -75,7 +76,9 @@ export default function BlogArchive({archive}: Props): JSX.Element {
});
const years = listPostsByYears(archive.blogPosts);
return (
<Layout title={title} description={description}>
<>
<PageMetadata title={title} description={description} />
<Layout>
<header className="hero hero--primary">
<div className="container">
<h1 className="hero__title">{title}</h1>
@ -84,5 +87,6 @@ export default function BlogArchive({archive}: Props): JSX.Element {
</header>
<main>{years.length > 0 && <YearsSection years={years} />}</main>
</Layout>
</>
);
}

View file

@ -12,28 +12,34 @@ import BlogLayout from '@theme/BlogLayout';
import BlogPostItem from '@theme/BlogPostItem';
import BlogListPaginator from '@theme/BlogListPaginator';
import type {Props} from '@theme/BlogListPage';
import {ThemeClassNames} from '@docusaurus/theme-common';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
} from '@docusaurus/theme-common';
import SearchMetadata from '@theme/SearchMetadata';
import clsx from 'clsx';
export default function BlogListPage(props: Props): JSX.Element {
const {metadata, items, sidebar} = props;
function BlogListPageMetadata(props: Props): JSX.Element {
const {metadata} = props;
const {
siteConfig: {title: siteTitle},
} = useDocusaurusContext();
const {blogDescription, blogTitle, permalink} = metadata;
const isBlogOnlyMode = permalink === '/';
const title = isBlogOnlyMode ? siteTitle : blogTitle;
return (
<BlogLayout
title={title}
description={blogDescription}
wrapperClassName={ThemeClassNames.wrapper.blogPages}
pageClassName={ThemeClassNames.page.blogListPage}
searchMetadata={{
// assign unique search tag to exclude this page from search results!
tag: 'blog_posts_list',
}}
sidebar={sidebar}>
<>
<PageMetadata title={title} description={blogDescription} />
<SearchMetadata tag="blog_posts_list" />
</>
);
}
function BlogListPageContent(props: Props): JSX.Element {
const {metadata, items, sidebar} = props;
return (
<BlogLayout sidebar={sidebar}>
{items.map(({content: BlogPostContent}) => (
<BlogPostItem
key={BlogPostContent.metadata.permalink}
@ -48,3 +54,16 @@ export default function BlogListPage(props: Props): JSX.Element {
</BlogLayout>
);
}
export default function BlogListPage(props: Props): JSX.Element {
return (
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.blogPages,
ThemeClassNames.page.blogListPage,
)}>
<BlogListPageMetadata {...props} />
<BlogListPageContent {...props} />
</HtmlClassNameProvider>
);
}

View file

@ -6,63 +6,32 @@
*/
import React from 'react';
import Seo from '@theme/Seo';
import BlogLayout from '@theme/BlogLayout';
import BlogPostItem from '@theme/BlogPostItem';
import BlogPostPaginator from '@theme/BlogPostPaginator';
import type {Props} from '@theme/BlogPostPage';
import {ThemeClassNames} from '@docusaurus/theme-common';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
} from '@docusaurus/theme-common';
import TOC from '@theme/TOC';
import clsx from 'clsx';
export default function BlogPostPage(props: Props): JSX.Element {
const {content: BlogPostContents, sidebar} = props;
function BlogPostPageMetadata(props: Props): JSX.Element {
const {content: BlogPostContents} = props;
const {assets, metadata} = BlogPostContents;
const {
title,
description,
nextItem,
prevItem,
date,
tags,
authors,
frontMatter,
} = metadata;
const {
hide_table_of_contents: hideTableOfContents,
keywords,
toc_min_heading_level: tocMinHeadingLevel,
toc_max_heading_level: tocMaxHeadingLevel,
} = frontMatter;
const {title, description, date, tags, authors, frontMatter} = metadata;
const {keywords} = frontMatter;
const image = assets.image ?? frontMatter.image;
return (
<BlogLayout
wrapperClassName={ThemeClassNames.wrapper.blogPages}
pageClassName={ThemeClassNames.page.blogPostPage}
sidebar={sidebar}
toc={
!hideTableOfContents &&
BlogPostContents.toc &&
BlogPostContents.toc.length > 0 ? (
<TOC
toc={BlogPostContents.toc}
minHeadingLevel={tocMinHeadingLevel}
maxHeadingLevel={tocMaxHeadingLevel}
/>
) : undefined
}>
<Seo
// TODO refactor needed: it's a bit annoying but Seo MUST be inside
// BlogLayout, otherwise default image (set by BlogLayout) would shadow
// the custom blog post image
<PageMetadata
title={title}
description={description}
keywords={keywords}
image={image}>
<meta property="og:type" content="article" />
<meta property="article:published_time" content={date} />
{/* TODO double check those article meta array syntaxes, see https://ogp.me/#array */}
{authors.some((author) => author.url) && (
<meta
@ -79,8 +48,33 @@ export default function BlogPostPage(props: Props): JSX.Element {
content={tags.map((tag) => tag.label).join(',')}
/>
)}
</Seo>
</PageMetadata>
);
}
function BlogPostPageContent(props: Props): JSX.Element {
const {content: BlogPostContents, sidebar} = props;
const {assets, metadata} = BlogPostContents;
const {nextItem, prevItem, frontMatter} = metadata;
const {
hide_table_of_contents: hideTableOfContents,
toc_min_heading_level: tocMinHeadingLevel,
toc_max_heading_level: tocMaxHeadingLevel,
} = frontMatter;
return (
<BlogLayout
sidebar={sidebar}
toc={
!hideTableOfContents &&
BlogPostContents.toc &&
BlogPostContents.toc.length > 0 ? (
<TOC
toc={BlogPostContents.toc}
minHeadingLevel={tocMinHeadingLevel}
maxHeadingLevel={tocMaxHeadingLevel}
/>
) : undefined
}>
<BlogPostItem
frontMatter={frontMatter}
assets={assets}
@ -95,3 +89,16 @@ export default function BlogPostPage(props: Props): JSX.Element {
</BlogLayout>
);
}
export default function BlogPostPage(props: Props): JSX.Element {
return (
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.blogPages,
ThemeClassNames.page.blogPostPage,
)}>
<BlogPostPageMetadata {...props} />
<BlogPostPageContent {...props} />
</HtmlClassNameProvider>
);
}

View file

@ -11,25 +11,29 @@ import BlogLayout from '@theme/BlogLayout';
import TagsListByLetter from '@theme/TagsListByLetter';
import type {Props} from '@theme/BlogTagsListPage';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
translateTagsPageTitle,
} from '@docusaurus/theme-common';
import SearchMetadata from '../SearchMetadata';
import clsx from 'clsx';
export default function BlogTagsListPage(props: Props): JSX.Element {
const {tags, sidebar} = props;
const title = translateTagsPageTitle();
return (
<BlogLayout
title={title}
wrapperClassName={ThemeClassNames.wrapper.blogPages}
pageClassName={ThemeClassNames.page.blogTagsListPage}
searchMetadata={{
// assign unique search tag to exclude this page from search results!
tag: 'blog_tags_list',
}}
sidebar={sidebar}>
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.blogPages,
ThemeClassNames.page.blogTagsListPage,
)}>
<PageMetadata title={title} />
<SearchMetadata tag="blog_tags_list" />
<BlogLayout sidebar={sidebar}>
<h1>{title}</h1>
<TagsListByLetter tags={Object.values(tags)} />
</BlogLayout>
</HtmlClassNameProvider>
);
}

View file

@ -12,8 +12,15 @@ import BlogLayout from '@theme/BlogLayout';
import BlogPostItem from '@theme/BlogPostItem';
import type {Props} from '@theme/BlogTagsPostsPage';
import Translate, {translate} from '@docusaurus/Translate';
import {ThemeClassNames, usePluralForm} from '@docusaurus/theme-common';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
usePluralForm,
} from '@docusaurus/theme-common';
import BlogListPaginator from '@theme/BlogListPaginator';
import SearchMetadata from '@theme/SearchMetadata';
import clsx from 'clsx';
// Very simple pluralization: probably good enough for now
function useBlogPostsPlural() {
@ -47,15 +54,14 @@ export default function BlogTagsPostsPage(props: Props): JSX.Element {
);
return (
<BlogLayout
title={title}
wrapperClassName={ThemeClassNames.wrapper.blogPages}
pageClassName={ThemeClassNames.page.blogTagPostListPage}
searchMetadata={{
// assign unique search tag to exclude this page from search results!
tag: 'blog_tags_posts',
}}
sidebar={sidebar}>
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.blogPages,
ThemeClassNames.page.blogTagPostListPage,
)}>
<PageMetadata title={title} />
<SearchMetadata tag="blog_tags_posts" />
<BlogLayout sidebar={sidebar}>
<header className="margin-bottom--xl">
<h1>{title}</h1>
@ -80,5 +86,6 @@ export default function BlogTagsPostsPage(props: Props): JSX.Element {
))}
<BlogListPaginator metadata={listMetadata} />
</BlogLayout>
</HtmlClassNameProvider>
);
}

View file

@ -6,11 +6,13 @@
*/
import React from 'react';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
import {
PageMetadata,
useCurrentSidebarCategory,
} from '@docusaurus/theme-common';
import type {Props} from '@theme/DocCategoryGeneratedIndexPage';
import DocCardList from '@theme/DocCardList';
import DocPaginator from '@theme/DocPaginator';
import Seo from '@theme/Seo';
import DocVersionBanner from '@theme/DocVersionBanner';
import DocVersionBadge from '@theme/DocVersionBadge';
import DocBreadcrumbs from '@theme/DocBreadcrumbs';
@ -19,13 +21,27 @@ import useBaseUrl from '@docusaurus/useBaseUrl';
import styles from './styles.module.css';
export default function DocCategoryGeneratedIndexPage({
function DocCategoryGeneratedIndexPageMetadata({
categoryGeneratedIndex,
}: Props): JSX.Element {
return (
<PageMetadata
title={categoryGeneratedIndex.title}
description={categoryGeneratedIndex.description}
keywords={categoryGeneratedIndex.keywords}
// TODO `require` this?
image={useBaseUrl(categoryGeneratedIndex.image)}
/>
);
}
function DocCategoryGeneratedIndexPageContent({
categoryGeneratedIndex,
}: Props): JSX.Element {
const category = useCurrentSidebarCategory();
return (
<>
<Seo
<PageMetadata
title={categoryGeneratedIndex.title}
description={categoryGeneratedIndex.description}
keywords={categoryGeneratedIndex.keywords}
@ -57,3 +73,14 @@ export default function DocCategoryGeneratedIndexPage({
</>
);
}
export default function DocCategoryGeneratedIndexPage(
props: Props,
): JSX.Element {
return (
<>
<DocCategoryGeneratedIndexPageMetadata {...props} />
<DocCategoryGeneratedIndexPageContent {...props} />
</>
);
}

View file

@ -10,7 +10,6 @@ import clsx from 'clsx';
import DocPaginator from '@theme/DocPaginator';
import DocVersionBanner from '@theme/DocVersionBanner';
import DocVersionBadge from '@theme/DocVersionBadge';
import Seo from '@theme/Seo';
import type {Props} from '@theme/DocItem';
import DocItemFooter from '@theme/DocItemFooter';
import TOC from '@theme/TOC';
@ -18,6 +17,7 @@ import TOCCollapsible from '@theme/TOCCollapsible';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
useWindowSize,
@ -25,18 +25,26 @@ import {
import DocBreadcrumbs from '@theme/DocBreadcrumbs';
import MDXContent from '@theme/MDXContent';
export default function DocItem(props: Props): JSX.Element {
function DocItemMetadata(props: Props): JSX.Element {
const {content: DocContent} = props;
const {metadata, frontMatter, assets} = DocContent;
const {keywords} = frontMatter;
const {description, title} = metadata;
const image = assets.image ?? frontMatter.image;
return <PageMetadata {...{title, description, keywords, image}} />;
}
function DocItemContent(props: Props): JSX.Element {
const {content: DocContent} = props;
const {metadata, frontMatter} = DocContent;
const {
keywords,
hide_title: hideTitle,
hide_table_of_contents: hideTableOfContents,
toc_min_heading_level: tocMinHeadingLevel,
toc_max_heading_level: tocMaxHeadingLevel,
} = frontMatter;
const {description, title} = metadata;
const image = assets.image ?? frontMatter.image;
const {title} = metadata;
// We only add a title if:
// - user asks to hide it with front matter
@ -53,9 +61,6 @@ export default function DocItem(props: Props): JSX.Element {
canRenderTOC && (windowSize === 'desktop' || windowSize === 'ssr');
return (
<HtmlClassNameProvider className={`docs-doc-id-${metadata.unversionedId}`}>
<Seo {...{title, description, keywords, image}} />
<div className="row">
<div className={clsx('col', !hideTableOfContents && styles.docItemCol)}>
<DocVersionBanner />
@ -76,8 +81,7 @@ export default function DocItem(props: Props): JSX.Element {
/>
)}
<div
className={clsx(ThemeClassNames.docs.docMarkdown, 'markdown')}>
<div className={clsx(ThemeClassNames.docs.docMarkdown, 'markdown')}>
{/*
Title can be declared inside md content or declared through
front matter and added manually. To make both cases consistent,
@ -111,6 +115,15 @@ export default function DocItem(props: Props): JSX.Element {
</div>
)}
</div>
);
}
export default function DocItem(props: Props): JSX.Element {
const docHtmlClassName = `docs-doc-id-${props.content.metadata.unversionedId}`;
return (
<HtmlClassNameProvider className={docHtmlClassName}>
<DocItemMetadata {...props} />
<DocItemContent {...props} />
</HtmlClassNameProvider>
);
}

View file

@ -8,15 +8,6 @@
import React, {type ReactNode, useState, useCallback} from 'react';
import renderRoutes from '@docusaurus/renderRoutes';
import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs';
import {
DocsFilterProvider,
HtmlClassNameProvider,
ThemeClassNames,
docVersionSearchTag,
DocsSidebarProvider,
useDocsSidebar,
DocsVersionProvider,
} from '@docusaurus/theme-common';
import Layout from '@theme/Layout';
import DocSidebar from '@theme/DocSidebar';
import NotFound from '@theme/NotFound';
@ -30,6 +21,17 @@ import {translate} from '@docusaurus/Translate';
import clsx from 'clsx';
import styles from './styles.module.css';
import {
DocsFilterProvider,
HtmlClassNameProvider,
ThemeClassNames,
docVersionSearchTag,
DocsSidebarProvider,
useDocsSidebar,
DocsVersionProvider,
} from '@docusaurus/theme-common';
import SearchMetadata from '@theme/SearchMetadata';
type DocPageContentProps = {
readonly currentDocRoute: DocumentRoute;
readonly versionMetadata: PropVersionMetadata;
@ -56,13 +58,12 @@ function DocPageContent({
}, [hiddenSidebar]);
return (
<Layout
wrapperClassName={ThemeClassNames.wrapper.docsPages}
pageClassName={ThemeClassNames.page.docsDocPage}
searchMetadata={{
version,
tag: docVersionSearchTag(pluginId, version),
}}>
<>
<SearchMetadata
version={version}
tag={docVersionSearchTag(pluginId, version)}
/>
<Layout>
<div className={styles.docPage}>
<BackToTopButton />
@ -75,7 +76,9 @@ function DocPageContent({
)}
onTransitionEnd={(e) => {
if (
!e.currentTarget.classList.contains(styles.docSidebarContainer!)
!e.currentTarget.classList.contains(
styles.docSidebarContainer!,
)
) {
return;
}
@ -137,6 +140,7 @@ function DocPageContent({
</main>
</div>
</Layout>
</>
);
}
@ -161,7 +165,12 @@ export default function DocPage(props: Props): JSX.Element {
: null;
return (
<HtmlClassNameProvider className={versionMetadata.className}>
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.docsPages,
ThemeClassNames.page.docsDocPage,
versionMetadata.className,
)}>
<DocsVersionProvider version={versionMetadata}>
<DocsSidebarProvider sidebar={sidebar ?? null}>
<DocsFilterProvider>

View file

@ -10,10 +10,6 @@
--doc-sidebar-hidden-width: 30px;
}
:global(.docs-wrapper) {
display: flex;
}
.docPage,
.docMainContainer {
display: flex;

View file

@ -9,10 +9,17 @@ import React from 'react';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import {ThemeClassNames, usePluralForm} from '@docusaurus/theme-common';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
usePluralForm,
} from '@docusaurus/theme-common';
import type {PropTagDocListDoc} from '@docusaurus/plugin-content-docs';
import Translate, {translate} from '@docusaurus/Translate';
import type {Props} from '@theme/DocTagDocListPage';
import SearchMetadata from '@theme/SearchMetadata';
import clsx from 'clsx';
// Very simple pluralization: probably good enough for now
function useNDocsTaggedPlural() {
@ -55,14 +62,14 @@ export default function DocTagDocListPage({tag}: Props): JSX.Element {
);
return (
<Layout
title={title}
wrapperClassName={ThemeClassNames.wrapper.docsPages}
pageClassName={ThemeClassNames.page.docsTagDocListPage}
searchMetadata={{
// assign unique search tag to exclude this page from search results!
tag: 'doc_tag_doc_list',
}}>
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.docsPages,
ThemeClassNames.page.docsTagDocListPage,
)}>
<PageMetadata title={title} />
<SearchMetadata tag="doc_tag_doc_list" />
<Layout>
<div className="container margin-vert--lg">
<div className="row">
<main className="col col--8 col--offset-2">
@ -85,5 +92,6 @@ export default function DocTagDocListPage({tag}: Props): JSX.Element {
</div>
</div>
</Layout>
</HtmlClassNameProvider>
);
}

View file

@ -9,23 +9,27 @@ import React from 'react';
import Layout from '@theme/Layout';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
translateTagsPageTitle,
} from '@docusaurus/theme-common';
import TagsListByLetter from '@theme/TagsListByLetter';
import type {Props} from '@theme/DocTagsListPage';
import SearchMetadata from '@theme/SearchMetadata';
import clsx from 'clsx';
export default function DocTagsListPage({tags}: Props): JSX.Element {
const title = translateTagsPageTitle();
return (
<Layout
title={title}
wrapperClassName={ThemeClassNames.wrapper.docsPages}
pageClassName={ThemeClassNames.page.docsTagsListPage}
searchMetadata={{
// assign unique search tag to exclude this page from search results!
tag: 'doc_tags_list',
}}>
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.docsPages,
ThemeClassNames.page.docsTagsListPage,
)}>
<PageMetadata title={title} />
<SearchMetadata tag="doc_tags_list" />
<Layout>
<div className="container margin-vert--lg">
<div className="row">
<main className="col col--8 col--offset-2">
@ -35,5 +39,6 @@ export default function DocTagsListPage({tags}: Props): JSX.Element {
</div>
</div>
</Layout>
</HtmlClassNameProvider>
);
}

View file

@ -13,20 +13,30 @@ import AnnouncementBar from '@theme/AnnouncementBar';
import Navbar from '@theme/Navbar';
import Footer from '@theme/Footer';
import LayoutProviders from '@theme/LayoutProviders';
import LayoutHead from '@theme/LayoutHead';
import type {Props} from '@theme/Layout';
import {ThemeClassNames, useKeyboardNavigation} from '@docusaurus/theme-common';
import {
PageMetadata,
ThemeClassNames,
useKeyboardNavigation,
} from '@docusaurus/theme-common';
import ErrorPageContent from '@theme/ErrorPageContent';
import './styles.css';
export default function Layout(props: Props): JSX.Element {
const {children, noFooter, wrapperClassName, pageClassName} = props;
const {
children,
noFooter,
wrapperClassName,
// not really layout-related, but kept for convenience/retro-compatibility
title,
description,
} = props;
useKeyboardNavigation();
return (
<LayoutProviders>
<LayoutHead {...props} />
<PageMetadata title={title} description={description} />
<SkipToContent />
@ -34,12 +44,7 @@ export default function Layout(props: Props): JSX.Element {
<Navbar />
<div
className={clsx(
ThemeClassNames.wrapper.main,
wrapperClassName,
pageClassName,
)}>
<div className={clsx(ThemeClassNames.wrapper.main, wrapperClassName)}>
<ErrorBoundary fallback={ErrorPageContent}>{children}</ErrorBoundary>
</div>

View file

@ -11,25 +11,30 @@ import Layout from '@theme/Layout';
import MDXContent from '@theme/MDXContent';
import type {Props} from '@theme/MDXPage';
import TOC from '@theme/TOC';
import {ThemeClassNames} from '@docusaurus/theme-common';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
} from '@docusaurus/theme-common';
import styles from './styles.module.css';
export default function MDXPage(props: Props): JSX.Element {
const {content: MDXPageContent} = props;
const {
metadata: {title, description, permalink, frontMatter},
metadata: {title, description, frontMatter},
} = MDXPageContent;
const {wrapperClassName, hide_table_of_contents: hideTableOfContents} =
frontMatter;
return (
<Layout
title={title}
description={description}
permalink={permalink}
wrapperClassName={wrapperClassName ?? ThemeClassNames.wrapper.mdxPages}
pageClassName={ThemeClassNames.page.mdxPage}>
<HtmlClassNameProvider
className={clsx(
wrapperClassName ?? ThemeClassNames.wrapper.mdxPages,
ThemeClassNames.page.mdxPage,
)}>
<PageMetadata title={title} description={description} />
<Layout>
<main className="container container--fluid margin-vert--lg">
<div className={clsx('row', styles.mdxPageWrapper)}>
<div className={clsx('col', !hideTableOfContents && 'col--8')}>
@ -49,5 +54,6 @@ export default function MDXPage(props: Props): JSX.Element {
</div>
</main>
</Layout>
</HtmlClassNameProvider>
);
}

View file

@ -8,14 +8,18 @@
import React from 'react';
import Layout from '@theme/Layout';
import Translate, {translate} from '@docusaurus/Translate';
import {PageMetadata} from '@docusaurus/theme-common';
export default function NotFound(): JSX.Element {
return (
<Layout
<>
<PageMetadata
title={translate({
id: 'theme.NotFound.title',
message: 'Page Not Found',
})}>
})}
/>
<Layout>
<main className="container margin-vert--xl">
<div className="row">
<div className="col col--6 col--offset-3">
@ -45,5 +49,6 @@ export default function NotFound(): JSX.Element {
</div>
</main>
</Layout>
</>
);
}

View file

@ -1,49 +0,0 @@
/**
* 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 Head from '@docusaurus/Head';
import {useTitleFormatter} from '@docusaurus/theme-common';
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
import type {Props} from '@theme/Seo';
export default function Seo({
title,
description,
keywords,
image,
children,
}: Props): JSX.Element {
const pageTitle = useTitleFormatter(title);
const {withBaseUrl} = useBaseUrlUtils();
const pageImage = image ? withBaseUrl(image, {absolute: true}) : undefined;
return (
<Head>
{title && <title>{pageTitle}</title>}
{title && <meta property="og:title" content={pageTitle} />}
{description && <meta name="description" content={description} />}
{description && <meta property="og:description" content={description} />}
{keywords && (
<meta
name="keywords"
content={
(Array.isArray(keywords) ? keywords.join(',') : keywords) as string
}
/>
)}
{pageImage && <meta property="og:image" content={pageImage} />}
{pageImage && <meta name="twitter:image" content={pageImage} />}
{children}
</Head>
);
}

View file

@ -9,19 +9,18 @@ import React from 'react';
import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl';
import type {Props} from '@theme/Layout';
import SearchMetadata from '@theme/SearchMetadata';
import Seo from '@theme/Seo';
import {
PageMetadata,
DEFAULT_SEARCH_TAG,
useTitleFormatter,
useAlternatePageUtils,
useThemeConfig,
keyboardFocusedClassName,
} from '@docusaurus/theme-common';
import {useLocation} from '@docusaurus/router';
// Useful for SEO
// TODO move to SiteMetadataDefaults or theme-common ?
// Useful for i18n/SEO
// See https://developers.google.com/search/docs/advanced/crawling/localized-versions
// See https://github.com/facebook/docusaurus/issues/3317
function AlternateLangHeaders(): JSX.Element {
@ -66,6 +65,7 @@ function useDefaultCanonicalUrl() {
return siteUrl + useBaseUrl(pathname);
}
// TODO move to SiteMetadataDefaults or theme-common ?
function CanonicalUrlHeaders({permalink}: {permalink?: string}) {
const {
siteConfig: {url: siteUrl},
@ -83,45 +83,31 @@ function CanonicalUrlHeaders({permalink}: {permalink?: string}) {
);
}
export default function LayoutHead(props: Props): JSX.Element {
export default function SiteMetadata(): JSX.Element {
const {
siteConfig: {favicon},
i18n: {currentLocale, localeConfigs},
i18n: {currentLocale},
} = useDocusaurusContext();
// TODO maybe move these 2 themeConfig to siteConfig?
// These seems useful for other themes as well
const {metadata, image: defaultImage} = useThemeConfig();
const {title, description, image, keywords, searchMetadata} = props;
const faviconUrl = useBaseUrl(favicon);
const pageTitle = useTitleFormatter(title);
const {htmlLang, direction: htmlDir} = localeConfigs[currentLocale]!;
return (
<>
<Head>
<html lang={htmlLang} dir={htmlDir} />
{favicon && <link rel="icon" href={faviconUrl} />}
<title>{pageTitle}</title>
<meta property="og:title" content={pageTitle} />
<meta name="twitter:card" content="summary_large_image" />
{/* The keyboard focus class name need to be applied when SSR so links
are outlined when JS is disabled */}
<body className={keyboardFocusedClassName} />
</Head>
{/* image can override the default image */}
{defaultImage && <Seo image={defaultImage} />}
{image && <Seo image={image} />}
<Seo description={description} keywords={keywords} />
{defaultImage && <PageMetadata image={defaultImage} />}
<CanonicalUrlHeaders />
<AlternateLangHeaders />
<SearchMetadata
tag={DEFAULT_SEARCH_TAG}
locale={currentLocale}
{...searchMetadata}
/>
<SearchMetadata tag={DEFAULT_SEARCH_TAG} locale={currentLocale} />
<Head
// it's important to have an additional <Head> element here,

View file

@ -15,10 +15,10 @@ function TextHighlight({text, highlight}: Props): JSX.Element {
return <>{text}</>;
}
const highlightedText = text.replace(
const highlightedText = text?.replace(
new RegExp(highlight, 'gi'),
(match) => `<mark>${match}</mark>`,
);
) as string;
return (
<span

View file

@ -129,9 +129,10 @@ export {isRegexpStringMatch} from './utils/regexpUtils';
export {useHomePageRoute} from './utils/routesUtils';
export {
PageMetadata,
HtmlClassNameProvider,
PluginHtmlClassNameProvider,
} from './utils/metadataUtilsTemp';
} from './utils/metadataUtils';
export {
useColorMode,

View file

@ -9,6 +9,53 @@ import React, {type ReactNode} from 'react';
import Head from '@docusaurus/Head';
import clsx from 'clsx';
import useRouteContext from '@docusaurus/useRouteContext';
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
import {useTitleFormatter} from './generalUtils';
interface PageMetadataProps {
readonly title?: string;
readonly description?: string;
readonly keywords?: readonly string[] | string;
readonly image?: string;
readonly children?: ReactNode;
}
// Helper component to manipulate page metadata and override site defaults
export function PageMetadata({
title,
description,
keywords,
image,
children,
}: PageMetadataProps): JSX.Element {
const pageTitle = useTitleFormatter(title);
const {withBaseUrl} = useBaseUrlUtils();
const pageImage = image ? withBaseUrl(image, {absolute: true}) : undefined;
return (
<Head>
{title && <title>{pageTitle}</title>}
{title && <meta property="og:title" content={pageTitle} />}
{description && <meta name="description" content={description} />}
{description && <meta property="og:description" content={description} />}
{keywords && (
<meta
name="keywords"
content={
(Array.isArray(keywords) ? keywords.join(',') : keywords) as string
}
/>
)}
{pageImage && <meta property="og:image" content={pageImage} />}
{pageImage && <meta name="twitter:image" content={pageImage} />}
{children}
</Head>
);
}
const HtmlClassNameContext = React.createContext<string | undefined>(undefined);

View file

@ -47,7 +47,8 @@ export class ReactContextError extends Error {
super();
this.name = 'ReactContextError';
this.message = `Hook ${
this.stack?.split('\n')[1]?.match(/at (?<name>\w+)/)?.groups!.name
this.stack?.split('\n')[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups!
.name
} is called outside the <${providerName}>. ${additionalInfo || ''}`;
}
}

View file

@ -17,6 +17,7 @@ import Head from '@docusaurus/Head';
import Link from '@docusaurus/Link';
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
import {
HtmlClassNameProvider,
useTitleFormatter,
usePluralForm,
isRegexpStringMatch,
@ -149,7 +150,7 @@ type ResultDispatcher =
| {type: 'update'; value: ResultDispatcherState}
| {type: 'advance'; value?: undefined};
export default function SearchPage(): JSX.Element {
function SearchPageContent(): JSX.Element {
const {
siteConfig: {themeConfig},
i18n: {currentLocale},
@ -356,7 +357,7 @@ export default function SearchPage(): JSX.Element {
}, [makeSearch, searchResultState.lastPage]);
return (
<Layout wrapperClassName="search-page-wrapper">
<Layout>
<Head>
<title>{useTitleFormatter(getTitle())}</title>
{/*
@ -516,3 +517,11 @@ export default function SearchPage(): JSX.Element {
</Layout>
);
}
export default function SearchPage(): JSX.Element {
return (
<HtmlClassNameProvider className="search-page-wrapper">
<SearchPageContent />
</HtmlClassNameProvider>
);
}

View file

@ -13,7 +13,9 @@ import {BrowserContextProvider} from './exports/browserContext';
import {DocusaurusContextProvider} from './exports/docusaurusContext';
import PendingNavigation from './PendingNavigation';
import BaseUrlIssueBanner from './baseUrlIssueBanner/BaseUrlIssueBanner';
import SiteMetadataDefaults from './SiteMetadataDefaults';
import Root from '@theme/Root';
import SiteMetadata from '@theme/SiteMetadata';
import './client-lifecycles-dispatcher';
@ -27,6 +29,8 @@ export default function App(): JSX.Element {
<DocusaurusContextProvider>
<BrowserContextProvider>
<Root>
<SiteMetadataDefaults />
<SiteMetadata />
<BaseUrlIssueBanner />
<PendingNavigation routes={routes} delay={1000}>
{renderRoutes(routes)}

View file

@ -0,0 +1,27 @@
/**
* 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 Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl';
export default function SiteMetadataDefaults(): JSX.Element {
const {
siteConfig: {favicon, tagline, title},
i18n: {currentLocale, localeConfigs},
} = useDocusaurusContext();
const faviconUrl = useBaseUrl(favicon);
const {htmlLang, direction: htmlDir} = localeConfigs[currentLocale]!;
return (
<Head defaultTitle={`${title}${tagline ? ` · ${tagline}` : ''}`}>
<html lang={htmlLang} dir={htmlDir} />
{favicon && <link rel="icon" href={faviconUrl} />}
</Head>
);
}

View file

@ -62,7 +62,8 @@ export default function ComponentCreator(
if (chunkRegistry) {
// eslint-disable-next-line prefer-destructuring
optsLoader[key] = chunkRegistry[0];
optsModules.push(chunkRegistry[1], chunkRegistry[2]);
optsModules.push(chunkRegistry[1]);
optsWebpack.push(chunkRegistry[2]);
}
});
@ -75,21 +76,25 @@ export default function ComponentCreator(
// Clone the original object since we don't want to alter the original.
const loadedModules = JSON.parse(JSON.stringify(chunkNames));
Object.keys(loaded).forEach((key) => {
const newComp = loaded[key].default;
if (!newComp) {
throw new Error(
`The page component at ${path} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`,
);
}
if (typeof newComp === 'object' || typeof newComp === 'function') {
Object.keys(loaded[key])
.filter((k) => k !== 'default')
.forEach((nonDefaultKey) => {
newComp[nonDefaultKey] = loaded[key][nonDefaultKey];
});
}
let val = loadedModules;
const keyPath = key.split('.');
keyPath.slice(0, -1).forEach((k) => {
val = val[k];
});
val[keyPath[keyPath.length - 1]!] = loaded[key].default;
const nonDefaultKeys = Object.keys(loaded[key]).filter(
(k) => k !== 'default',
);
if (nonDefaultKeys?.length) {
nonDefaultKeys.forEach((nonDefaultKey) => {
val[keyPath[keyPath.length - 1]!][nonDefaultKey] =
loaded[key][nonDefaultKey];
});
}
val[keyPath[keyPath.length - 1]!] = newComp;
});
const Component = loadedModules.component;
@ -103,7 +108,7 @@ export default function ComponentCreator(
// Is there any way to put this RouteContextProvider upper in the tree?
return (
<RouteContextProvider value={routeContextModule}>
<Component {...loadedModules} {...props} />;
<Component {...loadedModules} {...props} />
</RouteContextProvider>
);
},

View file

@ -9,6 +9,7 @@ import React from 'react';
import Layout from '@theme/Layout';
import ErrorBoundary from '@docusaurus/ErrorBoundary';
import type {Props} from '@theme/Error';
import Head from '@docusaurus/Head';
function ErrorDisplay({error, tryAgain}: Props): JSX.Element {
return (
@ -40,7 +41,10 @@ export default function Error({error, tryAgain}: Props): JSX.Element {
// Note: we display the original error here, not the error that we
// captured in this extra error boundary
fallback={() => <ErrorDisplay error={error} tryAgain={tryAgain} />}>
<Layout title="Page Error">
<Head>
<title>Page Error</title>
</Head>
<Layout>
<ErrorDisplay error={error} tryAgain={tryAgain} />
</Layout>
</ErrorBoundary>

View file

@ -6,31 +6,8 @@
*/
import React from 'react';
import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl';
import type {Props} from '@theme/Layout';
export default function Layout({
children,
title,
description,
}: Props): JSX.Element {
const context = useDocusaurusContext();
const {siteConfig} = context;
const {favicon, tagline, title: defaultTitle} = siteConfig;
const faviconUrl = useBaseUrl(favicon);
return (
<>
<Head defaultTitle={`${defaultTitle}${tagline ? ` · ${tagline}` : ''}`}>
{title && <title>{`${title} · ${tagline}`}</title>}
{favicon && <link rel="icon" href={faviconUrl} />}
{description && <meta name="description" content={description} />}
{description && (
<meta property="og:description" content={description} />
)}
</Head>
{children}
</>
);
export default function Layout({children}: Props): JSX.Element {
return <>{children}</>;
}

View file

@ -7,10 +7,15 @@
import React from 'react';
import Layout from '@theme/Layout';
import Head from '@docusaurus/Head';
export default function NotFound(): JSX.Element {
return (
<Layout title="Page Not Found">
<>
<Head>
<title>Page Not Found</title>
</Head>
<Layout>
<div
style={{
display: 'flex',
@ -22,5 +27,6 @@ export default function NotFound(): JSX.Element {
<h1>Oops, page not found </h1>
</div>
</Layout>
</>
);
}

View file

@ -5,7 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
import React, {type ReactNode} from 'react';
import React from 'react';
import type {Props} from '@theme/Root';
// Wrapper at the very top of the app, that is applied constantly
// and does not depend on current route (unlike the layout)
@ -14,6 +15,6 @@ import React, {type ReactNode} from 'react';
// and these providers won't reset state when we navigate
//
// See https://github.com/facebook/docusaurus/issues/3919
export default function Root({children}: {children: ReactNode}): JSX.Element {
export default function Root({children}: Props): JSX.Element {
return <>{children}</>;
}

View file

@ -0,0 +1,11 @@
/**
* 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.
*/
// To be implemented by the theme with <Head>
export default function SiteMetadata(): JSX.Element | null {
return null;
}

View file

@ -33,6 +33,7 @@ exports[`base webpack config creates webpack aliases 1`] = `
"@theme-original/PluginThemeComponentEnhanced": "secondPluginThemeFolder/PluginThemeComponentEnhanced.js",
"@theme-original/PluginThemeComponentOverriddenByUser": "pluginThemeFolder/PluginThemeComponentOverriddenByUser.js",
"@theme-original/Root": "../../../../client/theme-fallback/Root/index.tsx",
"@theme-original/SiteMetadata": "../../../../client/theme-fallback/SiteMetadata/index.tsx",
"@theme-original/subfolder/PluginThemeComponent2": "pluginThemeFolder/subfolder/PluginThemeComponent2.js",
"@theme/Error": "../../../../client/theme-fallback/Error/index.tsx",
"@theme/Layout": "../../../../client/theme-fallback/Layout/index.tsx",
@ -42,6 +43,7 @@ exports[`base webpack config creates webpack aliases 1`] = `
"@theme/PluginThemeComponentEnhanced": "src/theme/PluginThemeComponentEnhanced.js",
"@theme/PluginThemeComponentOverriddenByUser": "src/theme/PluginThemeComponentOverriddenByUser.js",
"@theme/Root": "../../../../client/theme-fallback/Root/index.tsx",
"@theme/SiteMetadata": "../../../../client/theme-fallback/SiteMetadata/index.tsx",
"@theme/UserThemeComponent1": "src/theme/UserThemeComponent1.js",
"@theme/subfolder/PluginThemeComponent2": "pluginThemeFolder/subfolder/PluginThemeComponent2.js",
"@theme/subfolder/UserThemeComponent2": "src/theme/subfolder/UserThemeComponent2.js",

View file

@ -0,0 +1,22 @@
/**
* 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.
*/
html.plugin-docs.plugin-id-docs-tests .red > a {
color: red;
}
html.plugin-docs.plugin-id-docs-tests .navbar {
border-bottom: solid thin cyan;
}
html.plugin-blog.plugin-id-blog-tests .navbar {
border-bottom: solid thin lime;
}
html.plugin-pages.plugin-id-pages-tests .navbar {
border-bottom: solid thin yellow;
}

View file

@ -35,9 +35,9 @@ Create a file `/src/pages/helloReact.js`:
import React from 'react';
import Layout from '@theme/Layout';
function Hello() {
export default function Hello() {
return (
<Layout title="Hello">
<Layout title="Hello" description="Hello React Page">
<div
style={{
display: 'flex',
@ -53,8 +53,6 @@ function Hello() {
</Layout>
);
}
export default Hello;
```
Once you save the file, the development server will automatically reload the changes. Now open `http://localhost:3000/helloReact` and you will see the new page you just created.

View file

@ -42,22 +42,6 @@ Similar to [global metadata](#global-metadata), Docusaurus also allows for the a
Some content...
```
```jsx title="my-react-page.jsx"
import React from 'react';
import Head from '@docusaurus/Head';
export default function page() {
return (
<Layout title="Page" description="A React page demo">
<Head>
<meta property="og:image" content="image.png" />
</Head>
{/* ... */}
</Layout>
);
}
```
Docusaurus automatically adds `description`, `title`, canonical URL links, and other useful metadata to each Markdown page. They are configurable through front matter:
```md
@ -77,6 +61,31 @@ Prefer to use front matter for fields like `description` and `keywords`: Docusau
:::
For JSX pages, you can use the Docusaurus [`<Head>`](docusaurus-core.md#head) component.
```jsx title="my-react-page.jsx"
import React from 'react';
import Layout from '@theme/Layout';
import Head from '@docusaurus/Head';
export default function page() {
return (
<Layout title="Page" description="A React page demo">
<Head>
<meta property="og:image" content="image.png" />
</Head>
{/* ... */}
</Layout>
);
}
```
:::tip
For convenience, the default theme `<Layout>` component accept `title` and `description` as props.
:::
## Static HTML generation {#static-html-generation}
Docusaurus is a static site generator—HTML files are statically generated for every URL route, which helps search engines discover your content more easily.

View file

@ -94,10 +94,18 @@ const config = {
},
webpack: {
jsLoader: (isServer) => ({
loader: require.resolve('esbuild-loader'),
loader: require.resolve('swc-loader'),
options: {
loader: 'tsx',
target: isServer ? 'node12' : 'es2017',
jsc: {
"parser": {
"syntax": "typescript",
"tsx": true
},
target: 'es2017',
},
module: {
type: isServer ? 'commonjs' : 'es6',
}
},
}),
},
@ -320,7 +328,10 @@ const config = {
remarkPlugins: [npm2yarn],
},
theme: {
customCss: [require.resolve('./src/css/custom.css')],
customCss: [
require.resolve('./src/css/custom.css'),
require.resolve('./_dogfooding/dogfooding.css'),
],
},
gtag: !isDeployPreview
? {

View file

@ -49,9 +49,9 @@
"@docusaurus/utils": "2.0.0-beta.17",
"@docusaurus/utils-common": "2.0.0-beta.17",
"@popperjs/core": "^2.11.4",
"@swc/core": "^1.2.158",
"clsx": "^1.1.1",
"color": "^4.2.1",
"esbuild-loader": "2.18.0",
"fs-extra": "^10.0.1",
"netlify-plugin-cache": "^1.0.3",
"raw-loader": "^4.0.2",
@ -61,6 +61,7 @@
"react-popper": "^2.2.5",
"rehype-katex": "^6.0.2",
"remark-math": "^3.0.1",
"swc-loader": "^0.1.15",
"unist-util-visit": "^2.0.2",
"workbox-routing": "^6.5.1",
"workbox-strategies": "^6.5.1"

View file

@ -166,10 +166,6 @@ div[class^='announcementBar_'] {
font-weight: bold;
}
.red > a {
color: red;
}
.screen-reader-only {
border: 0;
clip: rect(0 0 0 0);

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -778,6 +778,15 @@ const Users: User[] = [
source: null,
tags: ['product'],
},
{
title: 'SeaORM - 🐚 An async & dynamic ORM for Rust',
description:
'SeaORM is a relational ORM to help you build web services in Rust with the familiarity of dynamic languages.',
preview: require('./showcase/SeaORM.png'),
website: 'https://www.sea-ql.org/SeaORM/',
source: 'https://github.com/SeaQL/seaql.github.io',
tags: ['opensource', 'versioning'],
},
{
title: 'Ionic',
description:

View file

@ -9,27 +9,35 @@ import React from 'react';
import BlogLayout from '@theme/BlogLayout';
import BlogListPaginator from '@theme/BlogListPaginator';
import type {Props} from '@theme/BlogListPage';
import {ThemeClassNames} from '@docusaurus/theme-common';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
} from '@docusaurus/theme-common';
import Link from '@docusaurus/Link';
import ChangelogItem from '@theme/ChangelogItem';
import styles from './styles.module.css';
import SearchMetadata from '@theme/SearchMetadata';
import clsx from 'clsx';
export default function ChangelogList(props: Props): JSX.Element {
function ChangelogListMetadata(props: Props): JSX.Element {
const {metadata} = props;
const {blogTitle, blogDescription} = metadata;
return (
<>
<PageMetadata title={blogTitle} description={blogDescription} />
<SearchMetadata tag="blog_posts_list" />
</>
);
}
function ChangelogListContent(props: Props): JSX.Element {
const {metadata, items, sidebar} = props;
const {blogDescription, blogTitle} = metadata;
const {blogTitle} = metadata;
return (
<BlogLayout
title={blogTitle}
description={blogDescription}
wrapperClassName={ThemeClassNames.wrapper.blogPages}
pageClassName={ThemeClassNames.page.blogListPage}
searchMetadata={{
// assign unique search tag to exclude this page from search results!
tag: 'blog_posts_list',
}}
sidebar={sidebar}>
<BlogLayout sidebar={sidebar}>
<header className="margin-bottom--lg">
<h1 style={{fontSize: '3rem'}}>{blogTitle}</h1>
<p>
@ -88,3 +96,16 @@ export default function ChangelogList(props: Props): JSX.Element {
</BlogLayout>
);
}
export default function ChangelogList(props: Props): JSX.Element {
return (
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.blogPages,
ThemeClassNames.page.blogListPage,
)}>
<ChangelogListMetadata {...props} />
<ChangelogListContent {...props} />
</HtmlClassNameProvider>
);
}

View file

@ -6,59 +6,28 @@
*/
import React from 'react';
import Seo from '@theme/Seo';
import BlogLayout from '@theme/BlogLayout';
import ChangelogItem from '@theme/ChangelogItem';
import BlogPostPaginator from '@theme/BlogPostPaginator';
import type {Props} from '@theme/BlogPostPage';
import {ThemeClassNames} from '@docusaurus/theme-common';
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
} from '@docusaurus/theme-common';
import TOC from '@theme/TOC';
import Link from '@docusaurus/Link';
import clsx from 'clsx';
// This page doesn't change anything. It's just swapping BlogPostItem with our
// own ChangelogItem. We don't want to apply the swizzled item to the actual
// blog.
export default function BlogPostPage(props: Props): JSX.Element {
const {content: BlogPostContents, sidebar} = props;
function ChangelogPageMetadata(props: Props): JSX.Element {
const {content: BlogPostContents} = props;
const {assets, metadata} = BlogPostContents;
const {
title,
description,
nextItem,
prevItem,
date,
tags,
authors,
frontMatter,
// @ts-expect-error: we injected this
listPageLink,
} = metadata;
const {
hide_table_of_contents: hideTableOfContents,
keywords,
toc_min_heading_level: tocMinHeadingLevel,
toc_max_heading_level: tocMaxHeadingLevel,
} = frontMatter;
const {title, description, date, tags, authors, frontMatter} = metadata;
const {keywords} = frontMatter;
const image = assets.image ?? frontMatter.image;
return (
<BlogLayout
wrapperClassName={ThemeClassNames.wrapper.blogPages}
pageClassName={ThemeClassNames.page.blogPostPage}
sidebar={sidebar}
toc={
!hideTableOfContents &&
BlogPostContents.toc &&
BlogPostContents.toc.length > 0 ? (
<TOC
toc={BlogPostContents.toc}
minHeadingLevel={tocMinHeadingLevel}
maxHeadingLevel={tocMaxHeadingLevel}
/>
) : undefined
}>
<Seo
<PageMetadata
title={title}
description={description}
keywords={keywords}
@ -81,8 +50,42 @@ export default function BlogPostPage(props: Props): JSX.Element {
content={tags.map((tag) => tag.label).join(',')}
/>
)}
</Seo>
</PageMetadata>
);
}
function ChangelogPageContent(props: Props): JSX.Element {
const {content: BlogPostContents, sidebar} = props;
const {assets, metadata} = BlogPostContents;
const {
nextItem,
prevItem,
frontMatter,
// @ts-expect-error: we injected this
listPageLink,
} = metadata;
const {
hide_table_of_contents: hideTableOfContents,
toc_min_heading_level: tocMinHeadingLevel,
toc_max_heading_level: tocMaxHeadingLevel,
} = frontMatter;
return (
<>
<PageMetadata />
<BlogLayout
sidebar={sidebar}
toc={
!hideTableOfContents &&
BlogPostContents.toc &&
BlogPostContents.toc.length > 0 ? (
<TOC
toc={BlogPostContents.toc}
minHeadingLevel={tocMinHeadingLevel}
maxHeadingLevel={tocMaxHeadingLevel}
/>
) : undefined
}>
<Link to={listPageLink}> Back to index page</Link>
<ChangelogItem
@ -97,5 +100,22 @@ export default function BlogPostPage(props: Props): JSX.Element {
<BlogPostPaginator nextItem={nextItem} prevItem={prevItem} />
)}
</BlogLayout>
</>
);
}
// This page doesn't change anything. It's just swapping BlogPostItem with our
// own ChangelogItem. We don't want to apply the swizzled item to the actual
// blog.
export default function ChangelogPage(props: Props): JSX.Element {
return (
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.blogPages,
ThemeClassNames.page.blogPostPage,
)}>
<ChangelogPageMetadata {...props} />
<ChangelogPageContent {...props} />
</HtmlClassNameProvider>
);
}

258
yarn.lock
View file

@ -1751,6 +1751,13 @@
slash "^3.0.0"
strip-ansi "^6.0.0"
"@jest/create-cache-key-function@^27.4.2":
version "27.5.1"
resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz#7448fae15602ea95c828f5eceed35c202a820b31"
integrity sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==
dependencies:
"@jest/types" "^27.5.1"
"@jest/environment@^27.5.1":
version "27.5.1"
resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74"
@ -3579,6 +3586,97 @@
"@svgr/plugin-jsx" "^6.2.1"
"@svgr/plugin-svgo" "^6.2.0"
"@swc/core-android-arm-eabi@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.158.tgz#c850b614854da8e58e27cf51390bee656f093cc7"
integrity sha512-8RHlMo9+N8V5EE/2VOCF9H9DU3s3rj6SIRpTnQbIaJlZNwqCHp+q8xQGfKEFTrY2GShhFa/vN+w279gl2NXA+g==
"@swc/core-android-arm64@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-android-arm64/-/core-android-arm64-1.2.158.tgz#62764c3f509df24c6f504827d2cb7adad8a2f634"
integrity sha512-lfSUGzIjIvyj9sMtvnL6VPuC0XryfVCs3Fsvzbk4H0bi3nSDYFmVbpBvXZFhd60lcw1bcOFepBfi70LFmnhHTQ==
"@swc/core-darwin-arm64@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.158.tgz#64ef42f32b06c64c61d2648a5bbca8766338197c"
integrity sha512-vrdITsJjbx7lVN43Aq//gT+NRSdxS1+KxC6EiOct3qLcQA+P7w1nehZnlR+4qRLCgbBmQZQeeNnInaKpm9G7+g==
"@swc/core-darwin-x64@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.2.158.tgz#0ca64b3d244771e4d99a1555c4e9052dbe63d00f"
integrity sha512-+SIZgX01YEbTTClVdbc4aNR4dDsIVP+JiXxH1Zq5JYSsGxXzunRBMYcmTxnxRK2RHY1wOsLMD8AT5lZqQK6jsg==
"@swc/core-freebsd-x64@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.158.tgz#f0609f2f4c9d5bde24f6ab4b061ee42fbaec85f5"
integrity sha512-a+dF5T+Wi95E5IrMlHdGVETUgFkeL2roFT7cfjfWokR8UudD40kYkr8dxOBFizeIvgoeQdQ0hnJJl1dASL/ydA==
"@swc/core-linux-arm-gnueabihf@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.158.tgz#c166c42e6c07b1f1c273b4034d40ce486a23ef00"
integrity sha512-+B/WYr8RRe6YcCUAfD8r/p2rGrxEEDud2MXxbAS3OMYuSYrFzfOxqKzCd6rQ7/OTXpTpapg0yctvhzOyArtAZw==
"@swc/core-linux-arm64-gnu@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.158.tgz#597577dda702400f5f5d4cf49b32bb3fa6017835"
integrity sha512-QNTs6g9VYMF4UxRnSCMe7TRAPgCdsaUbHeWhaRtRE2nfKN4fd0YYPOzODEi7P3mvLW5p75FlHtRWokaME/J1HA==
"@swc/core-linux-arm64-musl@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.158.tgz#fb8e9aadace980eaa408596edb78090b20f4d982"
integrity sha512-dylgrtZQJIZ6JfRDL87sPdXlOew/hl5VQaIjjhN6hu+tuRmAHzyN50DJIioErMxqFFaxnqJCxMZUFX0AlPwEKg==
"@swc/core-linux-x64-gnu@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.158.tgz#190113e5afa441e20db60d67ea1926ed1f9e1ae6"
integrity sha512-f+l13OggHhdlk3va4tol7KxHm3kt1QPusLZJpVh00OENqXV6Wuv3Xh1BMgv5XMy6oXfOUdrXcPi3GWWi8079XA==
"@swc/core-linux-x64-musl@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.158.tgz#72894115ea3af335be0ec530c00aea88ce4fa298"
integrity sha512-+TuNuzCBkDfoZKaaeqUrDdEANc3iVS8TYQgutHokSu6FCcNd9OGCm81SXknmYuDMtqYGs1LwVNMwCV7YOWEsiA==
"@swc/core-win32-arm64-msvc@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.158.tgz#5569523a0b2758d62e65319433e2228ace4cc64e"
integrity sha512-GXfOgEgqWdrol6dpseLXQL9RkRy6TSBMULtwpxwH5uf1jwAAZaMBsd+JemvhW0OjbIX0P9M19hdvQYtxuYxvrg==
"@swc/core-win32-ia32-msvc@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.158.tgz#18f0b6cb1b6343a127b9da24904b3d1b1283db82"
integrity sha512-Z/KIIgJrI2lXm+S/vRmYLcanOTvvxWq929ggjgY93m3zWrHjsWGVFoelbn2xLRUOtI/u0qna6DovLHhC4KcuBw==
"@swc/core-win32-x64-msvc@1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.158.tgz#1f52b172617f62892afab6bfa8d624e99fa26964"
integrity sha512-h0jGYJmcNFhOinLT9vNE95DZfGtxROv9eDD+b5vMz03rvli5EUEUSkQ2MPDMuezHmL/P+cpKfVc/WGWWWXpfuQ==
"@swc/core@^1.2.158":
version "1.2.158"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.2.158.tgz#aba1421d16fc9cdda8e09872776957dcdae70917"
integrity sha512-EBTuqLC2CRd4HN2CSbe+z0QoYdMCGZV2GqUvco0s2pqcNSssrWAZj6xozcJOQ5VeUsYRVdKro2muMAWdNe7qug==
optionalDependencies:
"@swc/core-android-arm-eabi" "1.2.158"
"@swc/core-android-arm64" "1.2.158"
"@swc/core-darwin-arm64" "1.2.158"
"@swc/core-darwin-x64" "1.2.158"
"@swc/core-freebsd-x64" "1.2.158"
"@swc/core-linux-arm-gnueabihf" "1.2.158"
"@swc/core-linux-arm64-gnu" "1.2.158"
"@swc/core-linux-arm64-musl" "1.2.158"
"@swc/core-linux-x64-gnu" "1.2.158"
"@swc/core-linux-x64-musl" "1.2.158"
"@swc/core-win32-arm64-msvc" "1.2.158"
"@swc/core-win32-ia32-msvc" "1.2.158"
"@swc/core-win32-x64-msvc" "1.2.158"
"@swc/jest@^0.2.20":
version "0.2.20"
resolved "https://registry.yarnpkg.com/@swc/jest/-/jest-0.2.20.tgz#2bddb4348fb730296b86cdcd96748be131b11395"
integrity sha512-5qSUBYY1wyIMn7p0Vl9qqV4hMI69oJwZCIPUpBsTFWN2wlwn6RDugzdgCn+bLXVYh+Cxi8bJcZ1uumDgsoL+FA==
dependencies:
"@jest/create-cache-key-function" "^27.4.2"
"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
@ -8160,144 +8258,6 @@ es6-promisify@^6.0.0:
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-6.1.1.tgz#46837651b7b06bf6fff893d03f29393668d01621"
integrity sha512-HBL8I3mIki5C1Cc9QjKUenHtnG0A5/xA8Q/AllRcfiwl2CZFXGK7ddBiCoRwAix4i2KxcQfjtIVcrVbB3vbmwg==
esbuild-android-64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.27.tgz#b868bbd9955a92309c69df628d8dd1945478b45c"
integrity sha512-LuEd4uPuj/16Y8j6kqy3Z2E9vNY9logfq8Tq+oTE2PZVuNs3M1kj5Qd4O95ee66yDGb3isaOCV7sOLDwtMfGaQ==
esbuild-android-arm64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.27.tgz#e7d6430555e8e9c505fd87266bbc709f25f1825c"
integrity sha512-E8Ktwwa6vX8q7QeJmg8yepBYXaee50OdQS3BFtEHKrzbV45H4foMOeEE7uqdjGQZFBap5VAqo7pvjlyA92wznQ==
esbuild-darwin-64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.27.tgz#4dc7484127564e89b4445c0a560a3cb50b3d68e1"
integrity sha512-czw/kXl/1ZdenPWfw9jDc5iuIYxqUxgQ/Q+hRd4/3udyGGVI31r29LCViN2bAJgGvQkqyLGVcG03PJPEXQ5i2g==
esbuild-darwin-arm64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.27.tgz#469e59c665f84a8ed323166624c5e7b9b2d22ac1"
integrity sha512-BEsv2U2U4o672oV8+xpXNxN9bgqRCtddQC6WBh4YhXKDcSZcdNh7+6nS+DM2vu7qWIWNA4JbRG24LUUYXysimQ==
esbuild-freebsd-64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.27.tgz#895df03bf5f87094a56c9a5815bf92e591903d70"
integrity sha512-7FeiFPGBo+ga+kOkDxtPmdPZdayrSzsV9pmfHxcyLKxu+3oTcajeZlOO1y9HW+t5aFZPiv7czOHM4KNd0tNwCA==
esbuild-freebsd-arm64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.27.tgz#0b72a41a6b8655e9a8c5608f2ec1afdcf6958441"
integrity sha512-8CK3++foRZJluOWXpllG5zwAVlxtv36NpHfsbWS7TYlD8S+QruXltKlXToc/5ZNzBK++l6rvRKELu/puCLc7jA==
esbuild-linux-32@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.27.tgz#43b8ba3803b0bbe7f051869c6a8bf6de1e95de28"
integrity sha512-qhNYIcT+EsYSBClZ5QhLzFzV5iVsP1YsITqblSaztr3+ZJUI+GoK8aXHyzKd7/CKKuK93cxEMJPpfi1dfsOfdw==
esbuild-linux-64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.27.tgz#dc8072097327ecfadba1735562824ce8c05dd0bd"
integrity sha512-ESjck9+EsHoTaKWlFKJpPZRN26uiav5gkI16RuI8WBxUdLrrAlYuYSndxxKgEn1csd968BX/8yQZATYf/9+/qg==
esbuild-linux-arm64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.27.tgz#c52b58cbe948426b1559910f521b0a3f396f10b8"
integrity sha512-no6Mi17eV2tHlJnqBHRLekpZ2/VYx+NfGxKcBE/2xOMYwctsanCaXxw4zapvNrGE9X38vefVXLz6YCF8b1EHiQ==
esbuild-linux-arm@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.27.tgz#df869dbd67d4ee3a04b3c7273b6bd2b233e78a18"
integrity sha512-JnnmgUBdqLQO9hoNZQqNHFWlNpSX82vzB3rYuCJMhtkuaWQEmQz6Lec1UIxJdC38ifEghNTBsF9bbe8dFilnCw==
esbuild-linux-mips64le@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.27.tgz#a2b646d9df368b01aa970a7b8968be6dd6b01d19"
integrity sha512-NolWP2uOvIJpbwpsDbwfeExZOY1bZNlWE/kVfkzLMsSgqeVcl5YMen/cedRe9mKnpfLli+i0uSp7N+fkKNU27A==
esbuild-linux-ppc64le@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.27.tgz#9a21af766a0292578a3009c7408b8509cac7cefd"
integrity sha512-/7dTjDvXMdRKmsSxKXeWyonuGgblnYDn0MI1xDC7J1VQXny8k1qgNp6VmrlsawwnsymSUUiThhkJsI+rx0taNA==
esbuild-linux-riscv64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.27.tgz#344a27f91568056a5903ad5841b447e00e78d740"
integrity sha512-D+aFiUzOJG13RhrSmZgrcFaF4UUHpqj7XSKrIiCXIj1dkIkFqdrmqMSOtSs78dOtObWiOrFCDDzB24UyeEiNGg==
esbuild-linux-s390x@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.27.tgz#73a7309bd648a07ef58f069658f989a5096130db"
integrity sha512-CD/D4tj0U4UQjELkdNlZhQ8nDHU5rBn6NGp47Hiz0Y7/akAY5i0oGadhEIg0WCY/HYVXFb3CsSPPwaKcTOW3bg==
esbuild-loader@2.18.0:
version "2.18.0"
resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-2.18.0.tgz#7b9548578ab954574fd94655693d22aa5ec74120"
integrity sha512-AKqxM3bI+gvGPV8o6NAhR+cBxVO8+dh+O0OXBHIXXwuSGumckbPWHzZ17subjBGI2YEGyJ1STH7Haj8aCrwL/w==
dependencies:
esbuild "^0.14.6"
joycon "^3.0.1"
json5 "^2.2.0"
loader-utils "^2.0.0"
tapable "^2.2.0"
webpack-sources "^2.2.0"
esbuild-netbsd-64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.27.tgz#482a587cdbd18a6c264a05136596927deb46c30a"
integrity sha512-h3mAld69SrO1VoaMpYl3a5FNdGRE/Nqc+E8VtHOag4tyBwhCQXxtvDDOAKOUQexBGca0IuR6UayQ4ntSX5ij1Q==
esbuild-openbsd-64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.27.tgz#e99f8cdc63f1628747b63edd124d53cf7796468d"
integrity sha512-xwSje6qIZaDHXWoPpIgvL+7fC6WeubHHv18tusLYMwL+Z6bEa4Pbfs5IWDtQdHkArtfxEkIZz77944z8MgDxGw==
esbuild-sunos-64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.27.tgz#8611d825bcb8239c78d57452e83253a71942f45c"
integrity sha512-/nBVpWIDjYiyMhuqIqbXXsxBc58cBVH9uztAOIfWShStxq9BNBik92oPQPJ57nzWXRNKQUEFWr4Q98utDWz7jg==
esbuild-windows-32@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.27.tgz#c06374206d4d92dd31d4fda299b09f51a35e82f6"
integrity sha512-Q9/zEjhZJ4trtWhFWIZvS/7RUzzi8rvkoaS9oiizkHTTKd8UxFwn/Mm2OywsAfYymgUYm8+y2b+BKTNEFxUekw==
esbuild-windows-64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.27.tgz#756631c1d301dfc0d1a887deed2459ce4079582f"
integrity sha512-b3y3vTSl5aEhWHK66ngtiS/c6byLf6y/ZBvODH1YkBM+MGtVL6jN38FdHUsZasCz9gFwYs/lJMVY9u7GL6wfYg==
esbuild-windows-arm64@0.14.27:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.27.tgz#ad7e187193dcd18768b16065a950f4441d7173f4"
integrity sha512-I/reTxr6TFMcR5qbIkwRGvldMIaiBu2+MP0LlD7sOlNXrfqIl9uNjsuxFPGEG4IRomjfQ5q8WT+xlF/ySVkqKg==
esbuild@^0.14.6:
version "0.14.27"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.27.tgz#41fe0f1b6b68b9f77cac025009bc54bb96e616f1"
integrity sha512-MZQt5SywZS3hA9fXnMhR22dv0oPGh6QtjJRIYbgL1AeqAoQZE+Qn5ppGYQAoHv/vq827flj4tIJ79Mrdiwk46Q==
optionalDependencies:
esbuild-android-64 "0.14.27"
esbuild-android-arm64 "0.14.27"
esbuild-darwin-64 "0.14.27"
esbuild-darwin-arm64 "0.14.27"
esbuild-freebsd-64 "0.14.27"
esbuild-freebsd-arm64 "0.14.27"
esbuild-linux-32 "0.14.27"
esbuild-linux-64 "0.14.27"
esbuild-linux-arm "0.14.27"
esbuild-linux-arm64 "0.14.27"
esbuild-linux-mips64le "0.14.27"
esbuild-linux-ppc64le "0.14.27"
esbuild-linux-riscv64 "0.14.27"
esbuild-linux-s390x "0.14.27"
esbuild-netbsd-64 "0.14.27"
esbuild-openbsd-64 "0.14.27"
esbuild-sunos-64 "0.14.27"
esbuild-windows-32 "0.14.27"
esbuild-windows-64 "0.14.27"
esbuild-windows-arm64 "0.14.27"
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@ -11825,11 +11785,6 @@ joi@^17.6.0:
"@sideway/formula" "^3.0.0"
"@sideway/pinpoint" "^2.0.0"
joycon@^3.0.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03"
integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==
jpeg-js@0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.2.tgz#8b345b1ae4abde64c2da2fe67ea216a114ac279d"
@ -17352,7 +17307,7 @@ sort-keys@^4.0.0:
dependencies:
is-plain-obj "^2.0.0"
source-list-map@^2.0.0, source-list-map@^2.0.1:
source-list-map@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
@ -18040,6 +17995,13 @@ svgo@^2.5.0, svgo@^2.7.0:
picocolors "^1.0.0"
stable "^0.1.8"
swc-loader@^0.1.15:
version "0.1.15"
resolved "https://registry.yarnpkg.com/swc-loader/-/swc-loader-0.1.15.tgz#cb9c630ccfbb46dabc5aebc5560cced658e32992"
integrity sha512-cn1WPIeQJvXM4bbo3OwdEIapsQ4uUGOfyFj0h2+2+brT0k76DCGnZXDE2KmcqTd2JSQ+b61z2NPMib7eEwMYYw==
dependencies:
loader-utils "^2.0.0"
symbol-observable@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
@ -19490,14 +19452,6 @@ webpack-sources@^1.4.3:
source-list-map "^2.0.0"
source-map "~0.6.1"
webpack-sources@^2.2.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd"
integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==
dependencies:
source-list-map "^2.0.1"
source-map "^0.6.1"
webpack-sources@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"