chore(site): markdown supports custom anchors (#53316)

* chore(site): markdown supports custom anchors

wait: https://github.com/umijs/dumi/pull/2268

* chore: update deps

* chore: update

* chore: comment

* chore(deps): bump dumi to `2.4.20`

* chore: temp scripts

* Revert "chore: temp scripts"

This reverts commit 49a2ab86c4.
This commit is contained in:
𝑾𝒖𝒙𝒉 2025-04-02 11:03:02 +08:00 committed by GitHub
parent 08cdaf21c7
commit 48b8efbfde
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 99 additions and 11 deletions

86
.dumi/remarkAnchor.ts Normal file
View File

@ -0,0 +1,86 @@
import { unistUtilVisit } from 'dumi';
import type { UnifiedTransformer } from 'dumi';
let toSlug: typeof import('github-slugger').slug;
// workaround to import pure esm module
(async () => {
({ slug: toSlug } = await import('github-slugger'));
})();
const isNil = (value: any) => value == null;
const toArr = <T>(value: T | T[]) => {
if (isNil(value)) return [];
return Array.isArray(value) ? value : [value];
};
const patch = (context: Record<string, any>, key: string, value: any) => {
if (!context[key]) {
context[key] = value;
}
return context[key];
};
interface Options {
level?: number;
}
const remarkAnchor = (opt: Options = {}): UnifiedTransformer<any> => {
// https://regex101.com/r/WDjkK0/1
const RE = /\s*\{#([^}]+)\}$/;
const realOpt = {
level: [1, 2, 3, 4, 5, 6],
...opt,
};
return function transformer(tree) {
const ids = new Set();
unistUtilVisit.visit(tree, 'heading', (node) => {
if (toArr(realOpt.level).indexOf(node.depth) === -1) {
return unistUtilVisit.CONTINUE;
}
const lastChild = node.children.at(-1);
if (lastChild?.type === 'text') {
const text = lastChild.value;
const match = text.match(RE);
if (match) {
const id = match[1];
if (id !== toSlug(id)) {
throw new Error(
`Expected header ID to be a valid slug. You specified: {#${id}}. Replace it with: {#${toSlug(id)}}`,
);
}
node.data ??= {};
node.data.hProperties = { ...node.data.hProperties, id };
lastChild.value = text.replace(RE, '');
if (lastChild.value === '') {
node.children.pop();
}
if (ids.has(id)) {
throw new Error(`Cannot have a duplicate header with id "${id}" on the page.
Rename the section or give it an explicit unique ID. For example: #### Arguments {#setstate-arguments}`);
}
ids.add(id);
const data = patch(node, 'data', {});
patch(data, 'id', id);
patch(data, 'htmlAttributes', {});
patch(data, 'hProperties', {});
patch(data.htmlAttributes, 'id', id);
patch(data.hProperties, 'id', id);
}
}
});
};
};
export default remarkAnchor;

View File

@ -5,6 +5,7 @@ import os from 'node:os';
import rehypeAntd from './.dumi/rehypeAntd';
import remarkAntd from './.dumi/remarkAntd';
import remarkAnchor from './.dumi/remarkAnchor';
import { version } from './package.json';
export default defineConfig({
@ -52,7 +53,7 @@ export default defineConfig({
'@ant-design/icons$': '@ant-design/icons/lib',
},
extraRehypePlugins: [rehypeAntd],
extraRemarkPlugins: [remarkAntd],
extraRemarkPlugins: [remarkAntd, remarkAnchor],
metas: [
{ name: 'theme-color', content: '#1677ff' },
{ name: 'build-time', content: Date.now().toString() },

View File

@ -96,7 +96,7 @@ It accepts all props which native buttons support.
## FAQ
### How to choose type and color & variant?
### How to choose type and color & variant? {#faq-type-color-variant}
Type is essentially syntactic sugar for colors and variants. It internally provides a set of mapping relationships between colors and variants for the type. If both exist at the same time, the colors and variants will be used first.
@ -112,7 +112,7 @@ Equivalent
</Button>
```
### How to close the click wave effect?
### How to close the click wave effect? {#faq-close-wave-effect}
If you don't need this feature, you can set `disabled` of `wave` in [ConfigProvider](/components/config-provider#api) as `true`.

View File

@ -12,7 +12,7 @@ group:
order: 1
---
## 何时使用
## 何时使用 {#when-to-use}
标记了一个(或封装一组)操作命令,响应用户点击行为,触发相应的业务逻辑。
@ -33,7 +33,7 @@ group:
[完整设计指南](https://ant.design/docs/spec/buttons-cn)
## 代码演示
## 代码演示 {#examples}
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">语法糖</code>
@ -92,17 +92,17 @@ group:
> type PresetColors = 'blue' | 'purple' | 'cyan' | 'green' | 'magenta' | 'pink' | 'red' | 'orange' | 'yellow' | 'volcano' | 'geekblue' | 'lime' | 'gold';
## Semantic DOM
## Semantic DOM {#semantic-dom}
<code src="./demo/_semantic.tsx" simplify="true"></code>
## 主题变量Design Token
## 主题变量Design Token{#design-token}
<ComponentTokenTable component="Button"></ComponentTokenTable>
## FAQ
### 类型和颜色与变体如何选择?
### 类型和颜色与变体如何选择? {#faq-type-color-variant}
类型本质上是颜色与变体的语法糖,内部为其提供了一组颜色与变体的映射关系。如果两者同时存在,优先使用颜色与变体。
@ -118,7 +118,7 @@ group:
</Button>
```
### 如何关闭点击波纹效果?
### 如何关闭点击波纹效果? {#faq-close-wave-effect}
如果你不需要这个特性,可以设置 [ConfigProvider](/components/config-provider-cn#api) 的 `wave``disabled``true`
@ -135,6 +135,6 @@ group:
}
</style>
## 设计指引
## 设计指引 {#design-guide}
- [我的按钮究竟该放哪儿!?| Ant Design 4.0 系列分享](https://zhuanlan.zhihu.com/p/109644406)

View File

@ -239,7 +239,7 @@
"cypress-image-diff-html-report": "2.2.0",
"dekko": "^0.2.1",
"dotenv": "^16.4.5",
"dumi": "~2.4.17",
"dumi": "~2.4.20",
"dumi-plugin-color-chunk": "^2.1.0",
"env-paths": "^3.0.0",
"eslint": "^9.23.0",
@ -251,6 +251,7 @@
"fast-glob": "^3.3.2",
"fs-extra": "^11.2.0",
"gh-pages": "^6.2.0",
"github-slugger": "^2.0.0",
"glob": "^11.0.0",
"html2sketch": "^1.0.2",
"http-server": "^14.1.1",