Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"react-dom": "^19.2.5",
"rimraf": "^3.0.2",
"sharp": "^0.34.5",
"strip-ansi": "^6.0.1",
"strip-ansi": "^7.2.0",
"stylelint": "^17.12.0",
"stylelint-config-standard": "^40.0.0",
"syncpack": "^14.3.1",
Expand Down
6 changes: 0 additions & 6 deletions packages/docusaurus-theme-classic/src/theme-classic.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1324,9 +1324,6 @@ declare module '@theme/NavbarItem/DefaultNavbarItem' {
readonly position?: 'left' | 'right';
};

// TODO Docusaurus v4, remove old type name
export type DesktopOrMobileNavBarItemProps = DefaultNavbarItemProps;

export interface Props extends DefaultNavbarItemProps {
readonly mobile?: boolean;
}
Expand Down Expand Up @@ -1380,9 +1377,6 @@ declare module '@theme/NavbarItem/DropdownNavbarItem' {
readonly className?: string;
};

// TODO Docusaurus v4, remove old type name
export type DesktopOrMobileNavBarItemProps = DropdownNavbarItemProps;

export interface Props extends DropdownNavbarItemProps {
readonly mobile?: boolean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,17 @@ import Line from '@theme/CodeBlock/Line';

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

// TODO Docusaurus v4: remove useless forwardRef
const Pre = React.forwardRef<HTMLPreElement, ComponentProps<'pre'>>(
function Pre(props, ref) {
return (
<pre
ref={ref}
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
tabIndex={0}
{...props}
className={clsx(props.className, styles.codeBlock, 'thin-scrollbar')}
/>
);
},
);
function Pre({className, ref, ...props}: ComponentProps<'pre'>) {
return (
<pre
ref={ref}
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
tabIndex={0}
{...props}
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}
/>
);
}

function Code(props: ComponentProps<'code'>) {
const {metadata} = useCodeBlockContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,23 @@

import React, {type ReactNode} from 'react';
import clsx from 'clsx';
import Head from '@docusaurus/Head';
import {
ThemeClassNames,
UnlistedBannerTitle,
UnlistedBannerMessage,
UnlistedMetadata,
} from '@docusaurus/theme-common';
import Admonition from '@theme/Admonition';
import type {Props} from '@theme/ContentVisibility/Unlisted';

function UnlistedMetadata(): ReactNode {
return (
<Head>
<meta name="robots" content="noindex, nofollow" />
</Head>
);
}

function UnlistedBanner({className}: Props) {
return (
<Admonition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/

import React, {version, type ReactNode} from 'react';
import React, {type ReactNode} from 'react';
import clsx from 'clsx';
import {useNavbarSecondaryMenu} from '@docusaurus/theme-common/internal';
import {ThemeClassNames} from '@docusaurus/theme-common';
import type {Props} from '@theme/Navbar/MobileSidebar/Layout';

// TODO Docusaurus v4: remove temporary inert workaround
// See https://github.com/facebook/react/issues/17157
// See https://github.com/radix-ui/themes/pull/509
function inertProps(inert: boolean) {
const isBeforeReact19 = parseInt(version!.split('.')[0]!, 10) < 19;
if (isBeforeReact19) {
// TODO Docusaurus v4: remove temporary inert workaround
return {inert: inert ? '' : undefined} as unknown as {inert: boolean};
}
return {inert};
}

function NavbarMobileSidebarPanel({
children,
inert,
Expand All @@ -36,7 +24,7 @@ function NavbarMobileSidebarPanel({
ThemeClassNames.layout.navbar.mobileSidebar.panel,
'navbar-sidebar__item menu',
)}
{...inertProps(inert)}>
inert={inert}>
{children}
</div>
);
Expand Down
1 change: 0 additions & 1 deletion packages/docusaurus-theme-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
"lodash": "^4.17.21"
},
"peerDependencies": {
"@docusaurus/plugin-content-docs": "*",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
Expand Down
35 changes: 0 additions & 35 deletions packages/docusaurus-theme-common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/

import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import {DEFAULT_SEARCH_TAG} from './utils/searchUtils';

// TODO Docusaurus v4: remove these workarounds as a breaking change
// and remove docs plugin peerDeps in theme-common/package.json
// This is public API surface that we need to keep for v3
// See https://github.com/facebook/docusaurus/pull/10316
export function useCurrentSidebarCategory(...args: unknown[]): unknown {
// eslint-disable-next-line @typescript-eslint/no-require-imports
return require('@docusaurus/plugin-content-docs/client').useCurrentSidebarCategory(
...args,
);
}
export function filterDocCardListItems(...args: unknown[]): unknown {
// eslint-disable-next-line @typescript-eslint/no-require-imports
return require('@docusaurus/plugin-content-docs/client').filterDocCardListItems(
...args,
);
}
export function useDocsPreferredVersion(...args: unknown[]): unknown {
// eslint-disable-next-line @typescript-eslint/no-require-imports
return require('@docusaurus/plugin-content-docs/client').useDocsPreferredVersion(
...args,
);
}
export function useContextualSearchFilters() {
const {i18n} = useDocusaurusContext();
const docsTags =
// eslint-disable-next-line @typescript-eslint/no-require-imports
require('@docusaurus/plugin-content-docs/client').useDocsContextualSearchTags();
const tags = [DEFAULT_SEARCH_TAG, ...docsTags];
return {locale: i18n.currentLocale, tags};
}

/*
* APIs to document
*/
Expand Down Expand Up @@ -138,7 +104,6 @@ export {
export {
UnlistedBannerTitle,
UnlistedBannerMessage,
UnlistedMetadata,
DraftBannerTitle,
DraftBannerMessage,
} from './translations/contentVisibilityTranslations';
Expand Down
8 changes: 0 additions & 8 deletions packages/docusaurus-theme-common/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,6 @@ export {
getPrismCssVariables,
CodeBlockContextProvider,
useCodeBlockContext,

// TODO Docusaurus v4: remove, only kept for internal retro-compatibility
// See https://github.com/facebook/docusaurus/pull/11153
parseCodeBlockTitle,
parseClassNameLanguage as parseLanguage,
parseLines,
getLineNumbersStart,
containsLineNumbers,
} from './utils/codeBlockUtils';

export {DEFAULT_SEARCH_TAG} from './utils/searchUtils';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import React, {type ReactNode} from 'react';
import Translate from '@docusaurus/Translate';
import Head from '@docusaurus/Head';

export function UnlistedBannerTitle(): ReactNode {
return (
Expand All @@ -30,16 +29,6 @@ export function UnlistedBannerMessage(): ReactNode {
);
}

// TODO Docusaurus v4 breaking change (since it's v3 public theme-common API :/)
// Move this to theme/ContentVisibility/Unlisted
export function UnlistedMetadata(): ReactNode {
return (
<Head>
<meta name="robots" content="noindex, nofollow" />
</Head>
);
}

export function DraftBannerTitle(): ReactNode {
return (
<Translate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,65 @@ describe('extractLeadingEmoji', () => {
rest: 'Hello World 😀',
});
});

it('does not extract single digit', () => {
expect(extractLeadingEmoji('1 Hello World')).toEqual({
emoji: null,
rest: '1 Hello World',
});
});

it('does not extract multiple digits', () => {
expect(extractLeadingEmoji('11 Hello World')).toEqual({
emoji: null,
rest: '11 Hello World',
});
});

it('extracts real keycap emoji (digit + VS16 + combining keycap)', () => {
// 1️⃣ is digit "1" followed by U+FE0F (Variation Selector-16) and
// U+20E3 (Combining Enclosing Keycap) — a multi-codepoint grapheme
// that should still be detected as emoji
expect(extractLeadingEmoji('1\u{FE0F}\u{20E3} Something')).toEqual({
emoji: '1️⃣',
rest: ' Something',
});
});

it('extracts VS16 emoji - ⚠️ (text-default + variation selector)', () => {
// ⚠ (U+26A0) has Emoji=true, Emoji_Presentation=false. With VS16
// (U+FE0F) it becomes a multi-codepoint grapheme that IS an emoji
expect(extractLeadingEmoji('⚠\u{FE0F} Warning')).toEqual({
emoji: '⚠\u{FE0F}',
rest: ' Warning',
});
});

it('does not detect text-presentation symbols - ©', () => {
expect(extractLeadingEmoji('© 2026')).toEqual({
emoji: null,
rest: '© 2026',
});
});

it('does detect ©️', () => {
expect(extractLeadingEmoji('©️ 2026')).toEqual({
emoji: '©️',
rest: ' 2026',
});
});

it('does not detect text-presentation symbols - ™', () => {
expect(extractLeadingEmoji('™ Brand')).toEqual({
emoji: null,
rest: '™ Brand',
});
});

it('does not detect text-presentation symbols - ♠', () => {
expect(extractLeadingEmoji('♠ Cards')).toEqual({
emoji: null,
rest: '♠ Cards',
});
});
});
6 changes: 0 additions & 6 deletions packages/docusaurus-theme-common/src/utils/codeBlockUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,6 @@ export function getLineNumbersStart({
return getMetaLineNumbersStart(metastring);
}

// TODO Docusaurus v4: remove, only kept for internal retro-compatibility
// See https://github.com/facebook/docusaurus/pull/11153
export function containsLineNumbers(metastring?: string): boolean {
return Boolean(metastring?.includes('showLineNumbers'));
}

type ParseCodeLinesParam = {
/**
* The full metastring, as received from MDX. Line ranges declared here
Expand Down
9 changes: 4 additions & 5 deletions packages/docusaurus-theme-common/src/utils/emojiUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,10 @@ export function extractLeadingEmoji(input: string): {
return {emoji: null, rest: input};
}

// Leading grapheme contains an emoji (covers flags/ZWJ/skin tones)
if (
!/\p{Extended_Pictographic}/u.test(grapheme) &&
!/\p{Emoji}/u.test(grapheme)
) {
// Leading grapheme contains an emoji
// Covers flags/ZWJ/skin tones, excludes digits
// See https://github.com/facebook/docusaurus/pull/12072
if (!/^\p{RGI_Emoji}$/v.test(grapheme)) {
return {emoji: null, rest: input};
}

Expand Down
16 changes: 3 additions & 13 deletions packages/docusaurus-theme-mermaid/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import {useState, useEffect, useMemo} from 'react';
import {useState, useEffect, useMemo, useId} from 'react';
import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
import {loadMermaid} from './loadMermaid';

Expand All @@ -32,19 +32,9 @@ export function useMermaidConfig(): MermaidConfig {
);
}

// Random client-only id, we don't care much but mermaid want an id so...
function useMermaidId(): string {
/*
Random client-only id, we don't care much but mermaid want an id so...
Note: Mermaid doesn't like values provided by Rect.useId() and throws
*/

// TODO Docusaurus v4: check if useId() now works
// It could work thanks to https://github.com/facebook/react/pull/32001
// return useId(); // tried that, doesn't work ('#d:re:' is not a valid selector.)

return useState(
() => `mermaid-svg-${Math.round(Math.random() * 10000000)}`,
)[0];
return useId();
}

async function renderMermaid({
Expand Down
7 changes: 0 additions & 7 deletions packages/docusaurus-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,6 @@ export {
WEBPACK_URL_LOADER_LIMIT,
} from './constants';
export {generate, readOutputHTMLFile} from './emitUtils';
export {
// TODO Docusaurus v4: remove these legacy exports,
// they are only kept for retro-compatibility
getFileCommitDate,
FileNotTrackedError,
GitNotFoundError,
} from './vcs/gitUtils';
export {
mergeTranslations,
updateTranslationFileMessages,
Expand Down
Loading
Loading