Skip to content

Commit 0941d4e

Browse files
committed
feat: add anchor link for all headings
1 parent 9c98bc6 commit 0941d4e

File tree

12 files changed

+347
-17
lines changed

12 files changed

+347
-17
lines changed

assets/styles/post.styl

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,20 @@ margin-y($top, $bottom = $top)
3434
.one-details
3535
margin-bottom 5px
3636

37-
[data-markdown]
37+
.icon-link
38+
position absolute
39+
transition-property transform, opacity
40+
transition-duration 0.2s
41+
transform translate(calc(-1px - 100%), -50%)
42+
opacity 0
43+
padding 0.1em
44+
45+
[data-target]
46+
.icon-link
47+
opacity 1
48+
transform translate(-100%, -50%)
49+
50+
[data-md]
3851
h1
3952
h1&
4053
margin-y(0, 1.25em)
@@ -49,11 +62,6 @@ margin-y($top, $bottom = $top)
4962
margin-y(1.3em, 1.2em)
5063
font-size 30px
5164

52-
&::before
53-
content "#"
54-
margin-right 5px
55-
color #ccc
56-
5765
& + h3
5866
margin-top 2em
5967

@@ -98,9 +106,17 @@ margin-y($top, $bottom = $top)
98106
h5&
99107
h6
100108
h6&
109+
position relative
110+
display flex
111+
align-items center
101112
color #333
102113
line-height 1
103114

115+
&:hover
116+
.icon-link
117+
opacity 1
118+
transform translate(-100%, -50%)
119+
104120
br
105121
br&
106122
clear both
@@ -368,7 +384,7 @@ margin-y($top, $bottom = $top)
368384
.post
369385
padding 30px
370386

371-
[data-markdown]
387+
[data-md]
372388
h1
373389
h1&
374390
font-size 24px

nuxt.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ module.exports = {
5353
],
5454

5555
plugins: [
56+
{ src: '~plugins/global.js' },
5657
{ src: '~plugins/hm.js', ssr: false },
5758
{ src: '~plugins/i18n.js' },
5859
{ src: '~plugins/l10n.js' },

one/build/page.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import frontmatter from 'remark-frontmatter'
66
import shortcodes from 'remark-shortcodes'
77
import remarkToRehype from 'remark-rehype'
88
import raw from 'rehype-raw'
9+
import rehypeAutolinkHeadings from '@justfork/rehype-autolink-headings'
910
import html from 'rehype-stringify'
1011
import highlight from 'rehype-highlight'
1112
import etpl from 'etpl'
@@ -45,6 +46,14 @@ const md = remark()
4546
.use(toc)
4647
.use(remarkToRehype, { allowDangerousHTML: true })
4748
.use(raw)
49+
.use(rehypeAutolinkHeadings, {
50+
content: {
51+
type: 'element',
52+
tagName: 'icon-link',
53+
properties: { class: 'icon-link' }
54+
},
55+
test: ['h2', 'h3', 'h4', 'h5', 'h6']
56+
})
4857
.use(rehypePreviewImg)
4958
.use(rehypeLink)
5059
.use(rehypeScoped)
@@ -87,16 +96,20 @@ export function renderDocToPage (file) {
8796
.replace(/\{/g, '{')
8897
.replace(/\}/g, '}')
8998
.replace(/v-pre="true"/g, 'v-pre')
90-
.replace(/data-markdown="true"/g, 'data-markdown'),
99+
.replace(/data-md="true"/g, 'data-md'),
91100
demos: demoList.map(name => {
92101
return {
93102
name,
94-
src: join('@/components/demos', relative(DOCS_DIR, demos[name].filePath))
103+
src: join(
104+
'@/components/demos',
105+
relative(DOCS_DIR, demos[name].filePath)
106+
)
95107
}
96108
}),
97109
components: componentList,
98110
alert: hasAlert,
99-
boilerplate: demoList.length || componentList.length || hasAlert || style === 'post',
111+
boilerplate:
112+
demoList.length || componentList.length || hasAlert || style === 'post',
100113
layout,
101114
style,
102115
path: file,

one/build/rehype-link.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@ export default function attacher () {
1010
let [, locale] = localPath.match(RE_LOCALE) || []
1111

1212
visit(tree, 'element', node => {
13-
let { tagName, properties: { href, ...props } } = node
14-
if (tagName !== 'a' || href.match(/^\w+:\/\//)) {
13+
let {
14+
tagName,
15+
properties: { href, ...props }
16+
} = node
17+
if (tagName !== 'a' || href.startsWith('#') || href.match(/^\w+:\/\//)) {
1518
return
1619
}
1720

18-
let routePath = locale && href.indexOf('/') === 0 ? `/${locale}${href}` : href
21+
let routePath =
22+
locale && href.indexOf('/') === 0 ? `/${locale}${href}` : href
1923

2024
node.tagName = 'nuxt-link'
2125
node.properties = { ...props, to: routePath }

one/build/rehype-scoped.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default function attacher () {
66
return tree => {
77
visit(tree, 'element', ({ tagName, properties }, _, { type }) => {
88
if (type === 'root' && !RE_DEMO.test(tagName)) {
9-
properties['data-markdown'] = true
9+
properties['data-md'] = true
1010
}
1111
})
1212
}

one/build/remark-anchor.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ export default function attacher () {
2929
const { type, depth, children, value, position } = node
3030
if (type === 'heading') {
3131
if (depth === 3) {
32-
const text = children[0]
32+
let text = children[0]
33+
if (text && text.type === 'element' && text.tagName === 'icon-link') {
34+
text = children[1]
35+
}
3336
if (text && text.type === 'text' && KNOWN_SCOPES[text.value]) {
3437
scope = KNOWN_SCOPES[text.value]
3538
return

one/docs/changelog.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
class="content post"
44
:class="{ 'filter-version': compareValid }"
55
>
6-
<h1 data-markdown>
6+
<h1 data-md>
77
升级日志
88
</h1>
99
<veui-form
@@ -78,7 +78,7 @@
7878
v-for="{ version, codeName, date, changeset } of pagedChangelog"
7979
:key="version"
8080
class="version-item"
81-
data-markdown
81+
data-md
8282
>
8383
<h2
8484
:id="getHash(version)"

one/docs/demo/style/number.vue

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<template>
2+
<article>
3+
<section>
4+
<strong :class="{ tabular }">
5+
{{ value }}
6+
</strong>
7+
<veui-checkbox v-model="tabular">
8+
Tabular numbers
9+
</veui-checkbox>
10+
</section>
11+
<veui-slider
12+
v-model="value"
13+
:step="1"
14+
:min="19000101"
15+
:max="21001231"
16+
/>
17+
</article>
18+
</template>
19+
20+
<script>
21+
import { Checkbox, Slider } from 'veui'
22+
23+
export default {
24+
components: {
25+
'veui-checkbox': Checkbox,
26+
'veui-slider': Slider
27+
},
28+
data () {
29+
return {
30+
tabular: true,
31+
value: 20170320
32+
}
33+
}
34+
}
35+
</script>
36+
37+
<style scoped>
38+
section {
39+
display: flex;
40+
align-items: center;
41+
gap: 24px;
42+
}
43+
44+
strong {
45+
font-family: "Baidu Number", sans-serif;
46+
font-size: 32px;
47+
}
48+
49+
.tabular {
50+
font-variant-numeric: tabular-nums;
51+
}
52+
53+
.veui-slider {
54+
width: 50%;
55+
margin-top: 24px;
56+
}
57+
</style>

0 commit comments

Comments
 (0)