mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 18:27:56 +02:00
refactor: import jest as global; unify import style of some modules (#6898)
* refactor: import jest as global * fix react
This commit is contained in:
parent
e97dc0d37e
commit
c9ee6e467c
59 changed files with 177 additions and 139 deletions
13
.eslintrc.js
13
.eslintrc.js
|
@ -166,7 +166,12 @@ module.exports = {
|
||||||
// selector:
|
// selector:
|
||||||
// @ 'ExportDefaultDeclaration > Identifier, ExportNamedDeclaration[source=null] > ExportSpecifier',
|
// @ 'ExportDefaultDeclaration > Identifier, ExportNamedDeclaration[source=null] > ExportSpecifier',
|
||||||
// message: 'Export in one statement'
|
// message: 'Export in one statement'
|
||||||
// }
|
// },
|
||||||
|
...['path', 'fs-extra', 'webpack', 'lodash'].map((m) => ({
|
||||||
|
selector: `ImportDeclaration[importKind=value]:has(Literal[value=${m}]) > ImportSpecifier[importKind=value]`,
|
||||||
|
message:
|
||||||
|
'Default-import this, both for readability and interoperability with ESM',
|
||||||
|
})),
|
||||||
],
|
],
|
||||||
'no-template-curly-in-string': WARNING,
|
'no-template-curly-in-string': WARNING,
|
||||||
'no-unused-expressions': [WARNING, {allowTaggedTemplates: true}],
|
'no-unused-expressions': [WARNING, {allowTaggedTemplates: true}],
|
||||||
|
@ -312,5 +317,11 @@ module.exports = {
|
||||||
'@typescript-eslint/explicit-module-boundary-types': OFF,
|
'@typescript-eslint/explicit-module-boundary-types': OFF,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
files: ['*.test.ts', '*.test.tsx'],
|
||||||
|
rules: {
|
||||||
|
'import/no-extraneous-dependencies': OFF,
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* This source code is licensed under the MIT license found in the
|
* This source code is licensed under the MIT license found in the
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
|
||||||
|
|
||||||
import {Globby} from '@docusaurus/utils';
|
import {Globby} from '@docusaurus/utils';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import logger from '../index';
|
import logger from '../index';
|
||||||
|
|
||||||
describe('formatters', () => {
|
describe('formatters', () => {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import remark from 'remark';
|
import remark from 'remark';
|
||||||
import mdx from 'remark-mdx';
|
import mdx from 'remark-mdx';
|
||||||
|
|
|
@ -5,22 +5,20 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {join} from 'path';
|
import path from 'path';
|
||||||
import remark from 'remark';
|
import remark from 'remark';
|
||||||
import mdx from 'remark-mdx';
|
import mdx from 'remark-mdx';
|
||||||
import vfile from 'to-vfile';
|
import vfile from 'to-vfile';
|
||||||
import plugin from '..';
|
import plugin from '..';
|
||||||
|
|
||||||
const processFixture = async (name) => {
|
const processFixture = async (name: string) => {
|
||||||
const path = join(__dirname, '__fixtures__', name);
|
const file = await vfile.read(path.join(__dirname, '__fixtures__', name));
|
||||||
const file = await vfile.read(path);
|
|
||||||
const result = await remark().use(mdx).use(plugin).process(file);
|
const result = await remark().use(mdx).use(plugin).process(file);
|
||||||
return result.toString();
|
return result.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
const processFixtureAST = async (name) => {
|
const processFixtureAST = async (name: string) => {
|
||||||
const path = join(__dirname, '__fixtures__', name);
|
const file = await vfile.read(path.join(__dirname, '__fixtures__', name));
|
||||||
const file = await vfile.read(path);
|
|
||||||
return remark().use(mdx).use(plugin).parse(file);
|
return remark().use(mdx).use(plugin).parse(file);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {migrateDocusaurusProject} from '../index';
|
import {migrateDocusaurusProject} from '../index';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {createBlogFeedFiles} from '../feed';
|
import {createBlogFeedFiles} from '../feed';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import pluginContentBlog from '../index';
|
import pluginContentBlog from '../index';
|
||||||
import type {DocusaurusConfig, LoadContext, I18n} from '@docusaurus/types';
|
import type {DocusaurusConfig, LoadContext, I18n} from '@docusaurus/types';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {linkify, type LinkifyParams, getSourceToPermalink} from '../blogUtils';
|
import {linkify, type LinkifyParams, getSourceToPermalink} from '../blogUtils';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {cliDocsVersionCommand} from '../cli';
|
import {cliDocsVersionCommand} from '../cli';
|
||||||
import type {
|
import type {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {loadContext} from '@docusaurus/core/src/server/index';
|
import {loadContext} from '@docusaurus/core/src/server/index';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {isMatch} from 'picomatch';
|
import {isMatch} from 'picomatch';
|
||||||
import commander from 'commander';
|
import commander from 'commander';
|
||||||
|
@ -29,7 +30,7 @@ import type {
|
||||||
} from '../sidebars/types';
|
} from '../sidebars/types';
|
||||||
import {toSidebarsProp} from '../props';
|
import {toSidebarsProp} from '../props';
|
||||||
|
|
||||||
import {validate} from 'webpack';
|
import webpack from 'webpack';
|
||||||
import {DefaultSidebarItemsGenerator} from '../sidebars/generator';
|
import {DefaultSidebarItemsGenerator} from '../sidebars/generator';
|
||||||
import {DisabledSidebars} from '../sidebars';
|
import {DisabledSidebars} from '../sidebars';
|
||||||
|
|
||||||
|
@ -311,7 +312,7 @@ describe('simple website', () => {
|
||||||
undefined,
|
undefined,
|
||||||
content,
|
content,
|
||||||
);
|
);
|
||||||
const errors = validate(config);
|
const errors = webpack.validate(config);
|
||||||
expect(errors).toBeUndefined();
|
expect(errors).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import shell from 'shelljs';
|
import shell from 'shelljs';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {
|
import {
|
||||||
getVersionsFilePath,
|
getVersionsFilePath,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {linkify} from '../linkify';
|
import {linkify} from '../linkify';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {DefaultSidebarItemsGenerator} from '../generator';
|
import {DefaultSidebarItemsGenerator} from '../generator';
|
||||||
import type {SidebarItemsGenerator} from '../types';
|
import type {SidebarItemsGenerator} from '../types';
|
||||||
import {DefaultNumberPrefixParser} from '../../numberPrefix';
|
import {DefaultNumberPrefixParser} from '../../numberPrefix';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {processSidebars} from '../processor';
|
import {processSidebars} from '../processor';
|
||||||
import type {
|
import type {
|
||||||
SidebarItem,
|
SidebarItem,
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
type ComponentProps,
|
|
||||||
isValidElement,
|
isValidElement,
|
||||||
|
type ComponentProps,
|
||||||
type ReactElement,
|
type ReactElement,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import Head from '@docusaurus/Head';
|
import Head from '@docusaurus/Head';
|
||||||
|
@ -52,7 +52,7 @@ const MDXComponents: MDXComponentsObject = {
|
||||||
const shouldBeInline = React.Children.toArray(props.children).every(
|
const shouldBeInline = React.Children.toArray(props.children).every(
|
||||||
(el) =>
|
(el) =>
|
||||||
(typeof el === 'string' && !el.includes('\n')) ||
|
(typeof el === 'string' && !el.includes('\n')) ||
|
||||||
(React.isValidElement(el) && inlineElements.includes(el.props.mdxType)),
|
(isValidElement(el) && inlineElements.includes(el.props.mdxType)),
|
||||||
);
|
);
|
||||||
|
|
||||||
return shouldBeInline ? <code {...props} /> : <CodeBlock {...props} />;
|
return shouldBeInline ? <code {...props} /> : <CodeBlock {...props} />;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import React, {
|
import React, {
|
||||||
useState,
|
useState,
|
||||||
cloneElement,
|
cloneElement,
|
||||||
Children,
|
|
||||||
isValidElement,
|
isValidElement,
|
||||||
type ReactElement,
|
type ReactElement,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
@ -40,7 +39,7 @@ function TabsComponent(props: Props): JSX.Element {
|
||||||
groupId,
|
groupId,
|
||||||
className,
|
className,
|
||||||
} = props;
|
} = props;
|
||||||
const children = Children.map(props.children, (child) => {
|
const children = React.Children.map(props.children, (child) => {
|
||||||
if (isValidElement(child) && isTabItem(child)) {
|
if (isValidElement(child) && isTabItem(child)) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,11 @@ import React, {
|
||||||
useEffect,
|
useEffect,
|
||||||
useRef,
|
useRef,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
useLayoutEffect,
|
||||||
type RefObject,
|
type RefObject,
|
||||||
type Dispatch,
|
type Dispatch,
|
||||||
type SetStateAction,
|
type SetStateAction,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
useLayoutEffect,
|
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
const DefaultAnimationEasing = 'ease-in-out';
|
const DefaultAnimationEasing = 'ease-in-out';
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
type ComponentProps,
|
|
||||||
type ReactElement,
|
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
|
type ComponentProps,
|
||||||
|
type ReactElement,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
|
@ -10,9 +10,8 @@ import React, {
|
||||||
useEffect,
|
useEffect,
|
||||||
useCallback,
|
useCallback,
|
||||||
useMemo,
|
useMemo,
|
||||||
type ReactNode,
|
|
||||||
useContext,
|
useContext,
|
||||||
createContext,
|
type ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||||
import {createStorageSlot} from './storageUtils';
|
import {createStorageSlot} from './storageUtils';
|
||||||
|
@ -96,7 +95,9 @@ const useAnnouncementBarContextValue = (): AnnouncementBarAPI => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const AnnouncementBarContext = createContext<AnnouncementBarAPI | null>(null);
|
const AnnouncementBarContext = React.createContext<AnnouncementBarAPI | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
export function AnnouncementBarProvider({
|
export function AnnouncementBarProvider({
|
||||||
children,
|
children,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import React, {
|
||||||
useEffect,
|
useEffect,
|
||||||
useContext,
|
useContext,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
useRef,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {ReactContextError} from './reactUtils';
|
import {ReactContextError} from './reactUtils';
|
||||||
|
@ -96,7 +97,7 @@ function useColorModeContextValue(): ColorModeContextValue {
|
||||||
// be reset to dark when exiting print mode, disregarding user settings. When
|
// be reset to dark when exiting print mode, disregarding user settings. When
|
||||||
// the listener fires only because of a print/screen switch, we don't change
|
// the listener fires only because of a print/screen switch, we don't change
|
||||||
// color mode. See https://github.com/facebook/docusaurus/pull/6490
|
// color mode. See https://github.com/facebook/docusaurus/pull/6490
|
||||||
const previousMediaIsPrint = React.useRef(false);
|
const previousMediaIsPrint = useRef(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (disableSwitch && !respectPrefersColorScheme) {
|
if (disableSwitch && !respectPrefersColorScheme) {
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
createContext,
|
|
||||||
type ReactNode,
|
|
||||||
useContext,
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
|
type ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {useThemeConfig, type DocsVersionPersistence} from '../useThemeConfig';
|
import {useThemeConfig, type DocsVersionPersistence} from '../useThemeConfig';
|
||||||
import {isDocsPluginEnabled} from '../docsUtils';
|
import {isDocsPluginEnabled} from '../docsUtils';
|
||||||
|
@ -131,7 +130,9 @@ function useContextValue() {
|
||||||
|
|
||||||
type DocsPreferredVersionContextValue = ReturnType<typeof useContextValue>;
|
type DocsPreferredVersionContextValue = ReturnType<typeof useContextValue>;
|
||||||
|
|
||||||
const Context = createContext<DocsPreferredVersionContextValue | null>(null);
|
const Context = React.createContext<DocsPreferredVersionContextValue | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
export function DocsPreferredVersionContextProvider({
|
export function DocsPreferredVersionContextProvider({
|
||||||
children,
|
children,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {createContext, type ReactNode, useContext} from 'react';
|
import React, {type ReactNode, useContext} from 'react';
|
||||||
import {
|
import {
|
||||||
useActivePlugin,
|
useActivePlugin,
|
||||||
useAllDocsData,
|
useAllDocsData,
|
||||||
|
@ -29,7 +29,7 @@ export const isDocsPluginEnabled: boolean = !!useAllDocsData;
|
||||||
// Inspired by https://github.com/jamiebuilds/unstated-next/blob/master/src/unstated-next.tsx
|
// Inspired by https://github.com/jamiebuilds/unstated-next/blob/master/src/unstated-next.tsx
|
||||||
const EmptyContextValue: unique symbol = Symbol('EmptyContext');
|
const EmptyContextValue: unique symbol = Symbol('EmptyContext');
|
||||||
|
|
||||||
const DocsVersionContext = createContext<
|
const DocsVersionContext = React.createContext<
|
||||||
PropVersionMetadata | typeof EmptyContextValue
|
PropVersionMetadata | typeof EmptyContextValue
|
||||||
>(EmptyContextValue);
|
>(EmptyContextValue);
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ export function useDocById(id: string | undefined): PropVersionDoc | undefined {
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DocsSidebarContext = createContext<
|
const DocsSidebarContext = React.createContext<
|
||||||
PropSidebar | null | typeof EmptyContextValue
|
PropSidebar | null | typeof EmptyContextValue
|
||||||
>(EmptyContextValue);
|
>(EmptyContextValue);
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,11 @@
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
useState,
|
useState,
|
||||||
type ReactNode,
|
|
||||||
useContext,
|
useContext,
|
||||||
createContext,
|
|
||||||
useEffect,
|
useEffect,
|
||||||
type ComponentType,
|
|
||||||
useMemo,
|
useMemo,
|
||||||
|
type ReactNode,
|
||||||
|
type ComponentType,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {ReactContextError} from './reactUtils';
|
import {ReactContextError} from './reactUtils';
|
||||||
|
|
||||||
|
@ -46,7 +45,7 @@ function useContextValue() {
|
||||||
|
|
||||||
type ContextValue = ReturnType<typeof useContextValue>;
|
type ContextValue = ReturnType<typeof useContextValue>;
|
||||||
|
|
||||||
const Context = createContext<ContextValue | null>(null);
|
const Context = React.createContext<ContextValue | null>(null);
|
||||||
|
|
||||||
export function MobileSecondaryMenuProvider({
|
export function MobileSecondaryMenuProvider({
|
||||||
children,
|
children,
|
||||||
|
|
|
@ -6,14 +6,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
createContext,
|
|
||||||
type ReactNode,
|
|
||||||
useCallback,
|
useCallback,
|
||||||
useContext,
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
|
type ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {useDynamicCallback, ReactContextError} from './reactUtils';
|
import {useDynamicCallback, ReactContextError} from './reactUtils';
|
||||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||||
|
@ -57,7 +56,7 @@ function useScrollControllerContextValue(): ScrollController {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ScrollMonitorContext = createContext<ScrollController | undefined>(
|
const ScrollMonitorContext = React.createContext<ScrollController | undefined>(
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import React, {
|
||||||
useState,
|
useState,
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
createContext,
|
|
||||||
useMemo,
|
useMemo,
|
||||||
useContext,
|
useContext,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
|
@ -24,7 +23,7 @@ type TabGroupChoiceContextValue = {
|
||||||
readonly setTabGroupChoices: (groupId: string, newChoice: string) => void;
|
readonly setTabGroupChoices: (groupId: string, newChoice: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const TabGroupChoiceContext = createContext<
|
const TabGroupChoiceContext = React.createContext<
|
||||||
TabGroupChoiceContextValue | undefined
|
TabGroupChoiceContextValue | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {extractThemeCodeMessages} from '../update';
|
import {extractThemeCodeMessages} from '../update';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import Joi from '../Joi';
|
import Joi from '../Joi';
|
||||||
import {JoiFrontMatter} from '../JoiFrontMatter';
|
import {JoiFrontMatter} from '../JoiFrontMatter';
|
||||||
import {validateFrontMatter} from '../validationUtils';
|
import {validateFrontMatter} from '../validationUtils';
|
||||||
|
@ -21,7 +22,9 @@ describe('validateFrontMatter', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should reject bad values', () => {
|
test('should reject bad values', () => {
|
||||||
const consoleError = jest.spyOn(console, 'error').mockImplementation();
|
const consoleError = jest
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(() => {});
|
||||||
const schema = Joi.object<{test: string}>({
|
const schema = Joi.object<{test: string}>({
|
||||||
test: Joi.string(),
|
test: Joi.string(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {genChunkName, readOutputHTMLFile, generate} from '../emitUtils';
|
import {genChunkName, readOutputHTMLFile, generate} from '../emitUtils';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {
|
import {
|
||||||
removeSuffix,
|
removeSuffix,
|
||||||
removePrefix,
|
removePrefix,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {type ReactNode, useContext, createContext} from 'react';
|
import React, {type ReactNode, useContext} from 'react';
|
||||||
|
|
||||||
type LinksCollector = {
|
type LinksCollector = {
|
||||||
collectLink: (link: string) => void;
|
collectLink: (link: string) => void;
|
||||||
|
@ -26,7 +26,7 @@ export const createStatefulLinksCollector = (): StatefulLinksCollector => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const Context = createContext<LinksCollector>({
|
const Context = React.createContext<LinksCollector>({
|
||||||
collectLink: () => {
|
collectLink: () => {
|
||||||
// noop by default for client
|
// noop by default for client
|
||||||
// we only use the broken links checker server-side
|
// we only use the broken links checker server-side
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import normalizeLocation from '../normalizeLocation';
|
import normalizeLocation from '../normalizeLocation';
|
||||||
|
|
||||||
describe('normalizeLocation', () => {
|
describe('normalizeLocation', () => {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {hydrate, render} from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import {BrowserRouter} from 'react-router-dom';
|
import {BrowserRouter} from 'react-router-dom';
|
||||||
import {HelmetProvider} from 'react-helmet-async';
|
import {HelmetProvider} from 'react-helmet-async';
|
||||||
|
|
||||||
|
@ -30,7 +30,8 @@ if (ExecutionEnvironment.canUseDOM) {
|
||||||
// first-load experience.
|
// first-load experience.
|
||||||
// For development, there is no existing markup so we had to render it.
|
// For development, there is no existing markup so we had to render it.
|
||||||
// We also preload async component to avoid first-load loading screen.
|
// We also preload async component to avoid first-load loading screen.
|
||||||
const renderMethod = process.env.NODE_ENV === 'production' ? hydrate : render;
|
const renderMethod =
|
||||||
|
process.env.NODE_ENV === 'production' ? ReactDOM.hydrate : ReactDOM.render;
|
||||||
preload(routes, window.location.pathname).then(() => {
|
preload(routes, window.location.pathname).then(() => {
|
||||||
renderMethod(
|
renderMethod(
|
||||||
<HelmetProvider>
|
<HelmetProvider>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {type ReactNode} from 'react';
|
import React, {isValidElement, type ReactNode} from 'react';
|
||||||
import type {
|
import type {
|
||||||
InterpolateProps,
|
InterpolateProps,
|
||||||
InterpolateValues,
|
InterpolateValues,
|
||||||
|
@ -49,7 +49,7 @@ export function interpolate<Str extends string, Value extends ReactNode>(
|
||||||
const value = values?.[key];
|
const value = values?.[key];
|
||||||
|
|
||||||
if (typeof value !== 'undefined') {
|
if (typeof value !== 'undefined') {
|
||||||
const element = React.isValidElement(value)
|
const element = isValidElement(value)
|
||||||
? value
|
? value
|
||||||
: // For non-React elements: basic primitive->string conversion
|
: // For non-React elements: basic primitive->string conversion
|
||||||
String(value);
|
String(value);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
import BrowserOnly from '../BrowserOnly';
|
import BrowserOnly from '../BrowserOnly';
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import useBaseUrl, {useBaseUrlUtils} from '../useBaseUrl';
|
import useBaseUrl, {useBaseUrlUtils} from '../useBaseUrl';
|
||||||
import useDocusaurusContext from '../useDocusaurusContext';
|
import useDocusaurusContext from '../useDocusaurusContext';
|
||||||
|
|
||||||
jest.mock('../useDocusaurusContext', () => jest.fn(), {virtual: true});
|
jest.mock('../useDocusaurusContext');
|
||||||
|
|
||||||
const mockedContext = <jest.Mock>useDocusaurusContext;
|
const mockedContext = useDocusaurusContext as jest.Mock;
|
||||||
|
|
||||||
const forcePrepend = {forcePrependBaseUrl: true};
|
const forcePrepend = {forcePrependBaseUrl: true};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {ThemePath, createTempSiteDir, Components} from './testUtils';
|
import {ThemePath, createTempSiteDir, Components} from './testUtils';
|
||||||
|
|
2
packages/docusaurus/src/deps.d.ts
vendored
2
packages/docusaurus/src/deps.d.ts
vendored
|
@ -62,7 +62,7 @@ declare module '@slorber/static-site-generator-webpack-plugin' {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'webpack/lib/HotModuleReplacementPlugin' {
|
declare module 'webpack/lib/HotModuleReplacementPlugin' {
|
||||||
import {HotModuleReplacementPlugin} from 'webpack';
|
import type {HotModuleReplacementPlugin} from 'webpack';
|
||||||
|
|
||||||
export default HotModuleReplacementPlugin;
|
export default HotModuleReplacementPlugin;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import {handleBrokenLinks} from '../brokenLinks';
|
import {handleBrokenLinks} from '../brokenLinks';
|
||||||
|
@ -157,7 +158,7 @@ describe('handleBrokenLinks', () => {
|
||||||
test('no-op for ignore', async () => {
|
test('no-op for ignore', async () => {
|
||||||
// In any case, _.mapValues will always be called, unless handleBrokenLinks
|
// In any case, _.mapValues will always be called, unless handleBrokenLinks
|
||||||
// has already bailed
|
// has already bailed
|
||||||
const lodashMock = jest.spyOn(_, 'mapValues').mockImplementation();
|
const lodashMock = jest.spyOn(_, 'mapValues');
|
||||||
await handleBrokenLinks({
|
await handleBrokenLinks({
|
||||||
allCollectedLinks,
|
allCollectedLinks,
|
||||||
onBrokenLinks: 'ignore',
|
onBrokenLinks: 'ignore',
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {handleDuplicateRoutes} from '../duplicateRoutes';
|
import {handleDuplicateRoutes} from '../duplicateRoutes';
|
||||||
import type {RouteConfig} from '@docusaurus/types';
|
import type {RouteConfig} from '@docusaurus/types';
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {loadI18n, localizePath, getDefaultLocaleConfig} from '../i18n';
|
import {loadI18n, localizePath, getDefaultLocaleConfig} from '../i18n';
|
||||||
import {DEFAULT_I18N_CONFIG} from '../configValidation';
|
import {DEFAULT_I18N_CONFIG} from '../configValidation';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
@ -79,7 +80,7 @@ describe('defaultLocaleConfig', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('loadI18n', () => {
|
describe('loadI18n', () => {
|
||||||
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
consoleSpy.mockClear();
|
consoleSpy.mockClear();
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,6 +20,7 @@ export function sortAliases(aliases: ThemeAliases): ThemeAliases {
|
||||||
const entries = _.sortBy(Object.entries(aliases), ([alias]) => alias);
|
const entries = _.sortBy(Object.entries(aliases), ([alias]) => alias);
|
||||||
// @theme/NavbarItem should be after @theme/NavbarItem/LocaleDropdown
|
// @theme/NavbarItem should be after @theme/NavbarItem/LocaleDropdown
|
||||||
entries.sort(([alias1], [alias2]) =>
|
entries.sort(([alias1], [alias2]) =>
|
||||||
|
// eslint-disable-next-line no-nested-ternary
|
||||||
alias1.includes(`${alias2}/`) ? -1 : alias2.includes(`${alias1}/`) ? 1 : 0,
|
alias1.includes(`${alias2}/`) ? -1 : alias2.includes(`${alias1}/`) ? 1 : 0,
|
||||||
);
|
);
|
||||||
return Object.fromEntries(entries);
|
return Object.fromEntries(entries);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import {
|
import {
|
||||||
ensureTranslationFileContent,
|
ensureTranslationFileContent,
|
||||||
writeTranslationFileContent,
|
writeTranslationFileContent,
|
||||||
|
@ -560,7 +561,7 @@ describe('getPluginsDefaultCodeTranslationMessages', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('applyDefaultCodeTranslations', () => {
|
describe('applyDefaultCodeTranslations', () => {
|
||||||
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
consoleSpy.mockClear();
|
consoleSpy.mockClear();
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import tmp from 'tmp-promise';
|
import tmp from 'tmp-promise';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {validate} from 'webpack';
|
import {jest} from '@jest/globals';
|
||||||
|
import webpack from 'webpack';
|
||||||
|
|
||||||
import createClientConfig from '../client';
|
import createClientConfig from '../client';
|
||||||
import loadSetup from '../../server/__tests__/testUtils';
|
import loadSetup from '../../server/__tests__/testUtils';
|
||||||
|
@ -15,7 +16,7 @@ describe('webpack dev config', () => {
|
||||||
console.log = jest.fn();
|
console.log = jest.fn();
|
||||||
const props = await loadSetup('simple');
|
const props = await loadSetup('simple');
|
||||||
const config = await createClientConfig(props);
|
const config = await createClientConfig(props);
|
||||||
const errors = validate(config);
|
const errors = webpack.validate(config);
|
||||||
expect(errors).toBeUndefined();
|
expect(errors).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ describe('webpack dev config', () => {
|
||||||
console.log = jest.fn();
|
console.log = jest.fn();
|
||||||
const props = await loadSetup('custom');
|
const props = await loadSetup('custom');
|
||||||
const config = await createClientConfig(props);
|
const config = await createClientConfig(props);
|
||||||
const errors = validate(config);
|
const errors = webpack.validate(config);
|
||||||
expect(errors).toBeUndefined();
|
expect(errors).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {validate} from 'webpack';
|
import {jest} from '@jest/globals';
|
||||||
|
import webpack from 'webpack';
|
||||||
|
|
||||||
import createServerConfig from '../server';
|
import createServerConfig from '../server';
|
||||||
import loadSetup from '../../server/__tests__/testUtils';
|
import loadSetup from '../../server/__tests__/testUtils';
|
||||||
|
@ -15,7 +16,7 @@ describe('webpack production config', () => {
|
||||||
console.log = jest.fn();
|
console.log = jest.fn();
|
||||||
const props = await loadSetup('simple');
|
const props = await loadSetup('simple');
|
||||||
const config = await createServerConfig({props});
|
const config = await createServerConfig({props});
|
||||||
const errors = validate(config);
|
const errors = webpack.validate(config);
|
||||||
expect(errors).toBeUndefined();
|
expect(errors).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ describe('webpack production config', () => {
|
||||||
console.log = jest.fn();
|
console.log = jest.fn();
|
||||||
const props = await loadSetup('custom');
|
const props = await loadSetup('custom');
|
||||||
const config = await createServerConfig({props});
|
const config = await createServerConfig({props});
|
||||||
const errors = validate(config);
|
const errors = webpack.validate(config);
|
||||||
expect(errors).toBeUndefined();
|
expect(errors).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {validate, type Configuration, type RuleSetRule} from 'webpack';
|
import webpack, {type Configuration, type RuleSetRule} from 'webpack';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -86,7 +86,7 @@ describe('extending generated webpack config', () => {
|
||||||
filename: 'new.bundle.js',
|
filename: 'new.bundle.js',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const errors = validate(config);
|
const errors = webpack.validate(config);
|
||||||
expect(errors).toBeUndefined();
|
expect(errors).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ describe('extending generated webpack config', () => {
|
||||||
filename: 'new.bundle.js',
|
filename: 'new.bundle.js',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const errors = validate(config);
|
const errors = webpack.validate(config);
|
||||||
expect(errors).toBeUndefined();
|
expect(errors).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Template, type Compiler} from 'webpack';
|
import webpack, {type Compiler} from 'webpack';
|
||||||
|
|
||||||
const pluginName = 'chunk-asset-plugin';
|
const pluginName = 'chunk-asset-plugin';
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ export default class ChunkAssetPlugin {
|
||||||
chunkNameToId,
|
chunkNameToId,
|
||||||
)}[chunkId]||chunkId; return __webpack_require__.p + __webpack_require__.u(chunkId); };`,
|
)}[chunkId]||chunkId; return __webpack_require__.p + __webpack_require__.u(chunkId); };`,
|
||||||
);
|
);
|
||||||
return Template.asString(buf);
|
return webpack.Template.asString(buf);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,9 @@ describe('lqip library', () => {
|
||||||
const invalidPath = path.join(__dirname, '__fixtures__', 'docusaurus.svg');
|
const invalidPath = path.join(__dirname, '__fixtures__', 'docusaurus.svg');
|
||||||
|
|
||||||
it('should reject unknown or unsupported file format', async () => {
|
it('should reject unknown or unsupported file format', async () => {
|
||||||
await expect(lqip.base64(invalidPath)).rejects.toBeTruthy();
|
await expect(lqip.base64(invalidPath)).rejects.toThrow(
|
||||||
|
/Error: Input file is missing or uses unsupported image format, lqip v.*/,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a valid base64', async () => {
|
it('should generate a valid base64', async () => {
|
||||||
|
|
|
@ -11,36 +11,35 @@ import type {Palette} from 'node-vibrant/lib/color';
|
||||||
|
|
||||||
import {toPalette, toBase64} from '../utils';
|
import {toPalette, toBase64} from '../utils';
|
||||||
|
|
||||||
describe('lqip-loader', () => {
|
describe('toBase64', () => {
|
||||||
describe('toBase64', () => {
|
test('should return a properly formatted Base64 image string', () => {
|
||||||
test('should return a properly formatted Base64 image string', () => {
|
const mockedMimeType = 'image/jpeg';
|
||||||
const expected = 'data:image/jpeg;base64,aGVsbG8gd29ybGQ=';
|
const mockedBase64Data = Buffer.from('hello world');
|
||||||
const mockedMimeType = 'image/jpeg';
|
expect(toBase64(mockedMimeType, mockedBase64Data)).toEqual(
|
||||||
const mockedBase64Data = Buffer.from('hello world');
|
'data:image/jpeg;base64,aGVsbG8gd29ybGQ=',
|
||||||
expect(toBase64(mockedMimeType, mockedBase64Data)).toEqual(expected);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('toPalette', () => {
|
describe('toPalette', () => {
|
||||||
let correctTestSwatch: Palette = {};
|
let correctTestSwatch: Palette = {};
|
||||||
let testSwatchWithNull: Palette & {Vibrant?: null} = {};
|
let testSwatchWithNull: Palette & {Vibrant?: null} = {};
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
const imgPath = path.join(__dirname, '__fixtures__', 'endi.jpg');
|
const imgPath = path.join(__dirname, '__fixtures__/endi.jpg');
|
||||||
const vibrant = new Vibrant(imgPath, {});
|
const vibrant = new Vibrant(imgPath, {});
|
||||||
|
|
||||||
return vibrant.getPalette().then((palette) => {
|
return vibrant.getPalette().then((palette) => {
|
||||||
correctTestSwatch = {...palette};
|
correctTestSwatch = {...palette};
|
||||||
testSwatchWithNull = {...palette, Vibrant: null};
|
testSwatchWithNull = {...palette, Vibrant: null};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 6 hex colours sorted by popularity', () => {
|
it('should return 6 hex colours sorted by popularity', () => {
|
||||||
expect(toPalette(correctTestSwatch)).toHaveLength(6);
|
expect(toPalette(correctTestSwatch)).toHaveLength(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 5 hex colours with no errors if a palette was incomplete', () => {
|
it('should return 5 hex colours with no errors if a palette was incomplete', () => {
|
||||||
expect(toPalette(testSwatchWithNull)).toHaveLength(5);
|
expect(toPalette(testSwatchWithNull)).toHaveLength(5);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, {useRef} from 'react';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
export default function LinkTest(): JSX.Element {
|
export default function LinkTest(): JSX.Element {
|
||||||
const anchorRef = React.useRef<HTMLAnchorElement>(null);
|
const anchorRef = useRef<HTMLAnchorElement>(null);
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<main className="container margin-vert--xl">
|
<main className="container margin-vert--xl">
|
||||||
|
|
|
@ -102,7 +102,7 @@ import MyComponentSource from '!!raw-loader!@site/src/pages/examples/\_myCompone
|
||||||
|
|
||||||
```jsx live
|
```jsx live
|
||||||
function Demo() {
|
function Demo() {
|
||||||
React.useEffect(() => console.log('mount'), []);
|
useEffect(() => console.log('mount'), []);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
Children,
|
|
||||||
type ComponentProps,
|
type ComponentProps,
|
||||||
type ReactElement,
|
type ReactElement,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
isValidElement,
|
isValidElement,
|
||||||
useRef,
|
useRef,
|
||||||
useEffect,
|
useEffect,
|
||||||
forwardRef,
|
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {useHistory} from '@docusaurus/router';
|
import {useHistory} from '@docusaurus/router';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
@ -27,41 +25,41 @@ interface Props {
|
||||||
function getText(node: ReactElement): string {
|
function getText(node: ReactElement): string {
|
||||||
let curNode: ReactNode = node;
|
let curNode: ReactNode = node;
|
||||||
while (isValidElement(curNode)) {
|
while (isValidElement(curNode)) {
|
||||||
[curNode] = Children.toArray(curNode.props.children);
|
[curNode] = React.Children.toArray(curNode.props.children);
|
||||||
}
|
}
|
||||||
return curNode as string;
|
return curNode as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const APITableRow = forwardRef(
|
function APITableRow(
|
||||||
(
|
{
|
||||||
{
|
name,
|
||||||
name,
|
children,
|
||||||
children,
|
}: {name: string | undefined; children: ReactElement<ComponentProps<'tr'>>},
|
||||||
}: {name: string | undefined; children: ReactElement<ComponentProps<'tr'>>},
|
ref: React.ForwardedRef<HTMLTableRowElement>,
|
||||||
ref: React.ForwardedRef<HTMLTableRowElement>,
|
) {
|
||||||
) => {
|
const entryName = getText(children);
|
||||||
const entryName = getText(children);
|
const id = name ? `${name}-${entryName}` : entryName;
|
||||||
const id = name ? `${name}-${entryName}` : entryName;
|
const anchor = `#${id}`;
|
||||||
const anchor = `#${id}`;
|
const history = useHistory();
|
||||||
const history = useHistory();
|
return (
|
||||||
return (
|
<tr
|
||||||
<tr
|
id={id}
|
||||||
id={id}
|
tabIndex={0}
|
||||||
tabIndex={0}
|
ref={history.location.hash === anchor ? ref : undefined}
|
||||||
ref={history.location.hash === anchor ? ref : undefined}
|
onClick={() => {
|
||||||
onClick={() => {
|
history.push(anchor);
|
||||||
|
}}
|
||||||
|
onKeyDown={(e: React.KeyboardEvent) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
history.push(anchor);
|
history.push(anchor);
|
||||||
}}
|
}
|
||||||
onKeyDown={(e: React.KeyboardEvent) => {
|
}}>
|
||||||
if (e.key === 'Enter') {
|
{children.props.children}
|
||||||
history.push(anchor);
|
</tr>
|
||||||
}
|
);
|
||||||
}}>
|
}
|
||||||
{children.props.children}
|
|
||||||
</tr>
|
const APITableRowComp = React.forwardRef(APITableRow);
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: this is not a quite robust component since it makes a lot of
|
* Note: this is not a quite robust component since it makes a lot of
|
||||||
|
@ -69,19 +67,19 @@ const APITableRow = forwardRef(
|
||||||
* should be generally correct in the MDX context.
|
* should be generally correct in the MDX context.
|
||||||
*/
|
*/
|
||||||
export default function APITable({children, name}: Props): JSX.Element {
|
export default function APITable({children, name}: Props): JSX.Element {
|
||||||
const [thead, tbody] = Children.toArray(
|
const [thead, tbody] = React.Children.toArray(
|
||||||
children.props.children,
|
children.props.children,
|
||||||
) as ReactElement[];
|
) as ReactElement[];
|
||||||
const highlightedRow = useRef<HTMLTableRowElement>(null);
|
const highlightedRow = useRef<HTMLTableRowElement>(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
highlightedRow.current?.focus();
|
highlightedRow.current?.focus();
|
||||||
}, [highlightedRow]);
|
}, [highlightedRow]);
|
||||||
const rows = Children.map(
|
const rows = React.Children.map(
|
||||||
tbody.props.children,
|
tbody.props.children,
|
||||||
(row: ReactElement<ComponentProps<'tr'>>) => (
|
(row: ReactElement<ComponentProps<'tr'>>) => (
|
||||||
<APITableRow name={name} ref={highlightedRow}>
|
<APITableRowComp name={name} ref={highlightedRow}>
|
||||||
{row}
|
{row}
|
||||||
</APITableRow>
|
</APITableRowComp>
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {TagList, sortedUsers, type User} from '../users';
|
import {TagList, sortedUsers, type User} from '../users';
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
||||||
import {Joi} from '@docusaurus/utils-validation';
|
import {Joi} from '@docusaurus/utils-validation';
|
||||||
|
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
||||||
import imageSize from 'image-size';
|
import imageSize from 'image-size';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {memo} from 'react';
|
import React from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import Image from '@theme/IdealImage';
|
import Image from '@theme/IdealImage';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
|
@ -95,4 +95,4 @@ function ShowcaseCard({user}: {user: User}) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default memo(ShowcaseCard);
|
export default React.memo(ShowcaseCard);
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
type ComponentProps,
|
|
||||||
type ReactNode,
|
|
||||||
type ReactElement,
|
|
||||||
useCallback,
|
useCallback,
|
||||||
useState,
|
useState,
|
||||||
useEffect,
|
useEffect,
|
||||||
|
type ComponentProps,
|
||||||
|
type ReactNode,
|
||||||
|
type ReactElement,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {useHistory, useLocation} from '@docusaurus/router';
|
import {useHistory, useLocation} from '@docusaurus/router';
|
||||||
import {toggleListItem} from '@site/src/utils/jsUtils';
|
import {toggleListItem} from '@site/src/utils/jsUtils';
|
||||||
|
|
Loading…
Add table
Reference in a new issue