diff --git a/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/__fixtures__/attributes.md b/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/__fixtures__/attributes.md
new file mode 100644
index 000000000000..eb91dea38bbf
--- /dev/null
+++ b/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/__fixtures__/attributes.md
@@ -0,0 +1,21 @@
+Admonitions with attributes
+
+:::info[Info Title]{.bold}
+An info admonition with a className attribute.
+:::
+
+:::info{.bold .italic}
+An info admonition with multiple className attributes.
+:::
+
+:::info{#custom-id}
+An info admonition with a custom id attribute.
+:::
+
+:::info{#custom-id .bold}
+An info admonition with both id and className attributes.
+:::
+
+:::info{.c1 #id1 .c2 #id2 hello=world}
+Arbitrary attributes are ignored.
+:::
\ No newline at end of file
diff --git a/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/__snapshots__/index.test.ts.snap
index c19b192babb0..23b93a2b663f 100644
--- a/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/__snapshots__/index.test.ts.snap
+++ b/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/__snapshots__/index.test.ts.snap
@@ -11,6 +11,15 @@ exports[`admonitions remark plugin add custom keyword 1`] = `
++++
"
`;
+exports[`admonitions remark plugin attributes 1`] = `
+"Admonitions with attributes
+An info admonition with a className attribute.
+An info admonition with multiple className attributes.
+An info admonition with a custom id attribute.
+An info admonition with both id and className attributes.
+Arbitrary attributes are ignored.
"
+`;
+
exports[`admonitions remark plugin base 1`] = `
"The blog feature enables you to deploy in no time a full-featured blog.
Check the Blog Plugin API Reference documentation for an exhaustive list of options.
diff --git a/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/index.test.ts
index 7784850e44e1..7629d8679401 100644
--- a/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/index.test.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/admonitions/__tests__/index.test.ts
@@ -97,4 +97,9 @@ describe('admonitions remark plugin', () => {
const result = await processFixture('nesting');
expect(result).toMatchSnapshot();
});
+
+ it('attributes', async () => {
+ const result = await processFixture('attributes');
+ await expect(result).toMatchSnapshot();
+ });
});
diff --git a/packages/docusaurus-mdx-loader/src/remark/admonitions/index.ts b/packages/docusaurus-mdx-loader/src/remark/admonitions/index.ts
index d87df3bb54a5..15bfb37e5326 100644
--- a/packages/docusaurus-mdx-loader/src/remark/admonitions/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/admonitions/index.ts
@@ -107,6 +107,8 @@ const plugin: Plugin[], Root> = function plugin(
hName: 'admonition',
hProperties: {
...(textOnlyTitle && {title: textOnlyTitle}),
+ ...(node.attributes?.class && {className: node.attributes.class}),
+ ...(node.attributes?.id && {id: node.attributes.id}),
type: node.name,
},
};
diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts
index c38431f8b7f4..961d68fcc044 100644
--- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts
+++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts
@@ -48,6 +48,7 @@ declare module '@theme/Admonition' {
readonly icon?: ReactNode;
readonly title?: ReactNode;
readonly className?: string;
+ readonly id?: string;
}
export default function Admonition(props: Props): ReactNode;
@@ -123,6 +124,7 @@ declare module '@theme/Admonition/Layout' {
readonly icon?: ReactNode;
readonly title?: ReactNode;
readonly className?: string;
+ readonly id?: string;
}
export default function AdmonitionLayout(props: Props): ReactNode;
}
diff --git a/packages/docusaurus-theme-classic/src/theme/Admonition/Layout/index.tsx b/packages/docusaurus-theme-classic/src/theme/Admonition/Layout/index.tsx
index b90b6cb1dbbc..521712de772c 100644
--- a/packages/docusaurus-theme-classic/src/theme/Admonition/Layout/index.tsx
+++ b/packages/docusaurus-theme-classic/src/theme/Admonition/Layout/index.tsx
@@ -17,7 +17,8 @@ function AdmonitionContainer({
type,
className,
children,
-}: Pick & {children: ReactNode}) {
+ id,
+}: Pick & {children: ReactNode}) {
return (
+ )}
+ id={id}>
{children}
);
@@ -47,9 +49,9 @@ function AdmonitionContent({children}: Pick) {
}
export default function AdmonitionLayout(props: Props): ReactNode {
- const {type, icon, title, children, className} = props;
+ const {type, icon, title, children, className, id} = props;
return (
-
+
{title || icon ? : null}
{children}
diff --git a/website/_dogfooding/_docs tests/tests/admonitions.mdx b/website/_dogfooding/_docs tests/tests/admonitions.mdx
index e9f7d858aae2..4a80c46b2734 100644
--- a/website/_dogfooding/_docs tests/tests/admonitions.mdx
+++ b/website/_dogfooding/_docs tests/tests/admonitions.mdx
@@ -54,6 +54,73 @@ import InfoIcon from "@theme/Admonition/Icon/Info"
```
+## Admonitions with attributes
+
+
+Relevant CSS for this section
+
+```css title="dogfooding.css"
+/* ... */
+.shadow {
+ --shadow-color: red;
+ box-shadow: 10px 10px 10px var(--shadow-color);
+
+ &.blue {
+ --shadow-color: blue;
+ }
+}
+
+#info-1 {
+ border: solid 2px blue;
+}
+
+#info-2 {
+ border: solid 2px green;
+}
+
+#info-3 {
+ border: solid 2px red;
+}
+```
+
+
+
+### Classes
+
+:::info{.shadow}
+
+The class `shadow` was added by writing `:::info{.shadow}`.
+
+:::
+
+:::info{.shadow .blue}
+
+The class `shadow` and `blue` were added by writing `:::info{.shadow .blue}`.
+
+:::
+
+### Ids
+
+:::info{#info-1}
+
+The id `info-1` was added by writing `:::{#info-1}`
+
+:::
+
+:::info{#info-3 #info-1 #info-2}
+
+The last provided id `info-2` wins when writing `:::{#info-3 #info-1 #info-2}`
+
+:::
+
+### Combination
+
+:::info{.shadow #info-4 .blue #info-3}
+
+Multiple classes and ids: `{.shadow #info-4 .blue #info-3}`.
+
+:::
+
## Indented admonitions
See admonition title v2 compat syntax bug: https://github.com/facebook/docusaurus/issues/9507
diff --git a/website/_dogfooding/dogfooding.css b/website/_dogfooding/dogfooding.css
index 54376d3d546c..3ae643d6f197 100644
--- a/website/_dogfooding/dogfooding.css
+++ b/website/_dogfooding/dogfooding.css
@@ -25,6 +25,27 @@ html {
border-bottom: solid thin cyan;
}
+ .shadow {
+ --shadow-color: red;
+ box-shadow: 10px 10px 10px var(--shadow-color);
+
+ &.blue {
+ --shadow-color: blue;
+ }
+ }
+
+ #info-1 {
+ border: solid 2px blue;
+ }
+
+ #info-2 {
+ border: solid 2px green;
+ }
+
+ #info-3 {
+ border: solid 2px red;
+ }
+
.dogfood_sidebar_class_name_test {
&.theme-doc-sidebar-item-link > a {
color: cyan;
diff --git a/website/docs/guides/markdown-features/markdown-features-admonitions.mdx b/website/docs/guides/markdown-features/markdown-features-admonitions.mdx
index 39353f587396..60f8605ad347 100644
--- a/website/docs/guides/markdown-features/markdown-features-admonitions.mdx
+++ b/website/docs/guides/markdown-features/markdown-features-admonitions.mdx
@@ -129,6 +129,54 @@ Some **content** with some _Markdown_ `syntax`.
```
+## Specifying attributes {#specifying-attributes}
+
+You may also provide classes or IDs to admonitions.
+
+```md
+:::note[With css classes]{.padding--lg .text--italic}
+
+Note the padding and the italicized text.
+
+:::
+
+:::note{#admonition-id}
+
+The admonition container has now the id `admonition-id`.
+
+:::
+
+:::note{.padding--lg #admonition-id-2}
+
+Use id and classes together.
+
+:::
+```
+
+```mdx-code-block
+
+
+:::note[With css classes]{.padding--lg .text--italic}
+
+Note the padding and the italicized text.
+
+:::
+
+:::note{#admonition-id}
+
+The admonition container has now the id `admonition-id`.
+
+:::
+
+:::note{.padding--lg #admonition-id-2}
+
+Use id and classes together.
+
+:::
+
+
+```
+
## Nested admonitions {#nested-admonitions}
Admonitions can be nested. Use more colons `:` for each parent admonition level.