mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 19:13:31 +01:00
feat: auto-link headings
This commit is contained in:
@@ -4,9 +4,42 @@ import mdx from '@astrojs/mdx';
|
|||||||
import react from '@astrojs/react';
|
import react from '@astrojs/react';
|
||||||
import { remarkCodeHike } from '@code-hike/mdx';
|
import { remarkCodeHike } from '@code-hike/mdx';
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
import { toString } from 'hast-util-to-string';
|
||||||
|
import { h } from 'hastscript';
|
||||||
|
import { escape } from 'html-escaper';
|
||||||
|
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
|
||||||
|
import rehypeSlug from 'rehype-slug';
|
||||||
import shikiThemeDarkPlus from 'shiki/themes/dark-plus.json' assert { type: 'json' };
|
import shikiThemeDarkPlus from 'shiki/themes/dark-plus.json' assert { type: 'json' };
|
||||||
import Unocss from 'unocss/astro';
|
import Unocss from 'unocss/astro';
|
||||||
|
|
||||||
|
const LinkIcon = h(
|
||||||
|
'svg',
|
||||||
|
{
|
||||||
|
width: '1rem',
|
||||||
|
height: '1rem',
|
||||||
|
viewBox: '0 0 24 24',
|
||||||
|
fill: 'none',
|
||||||
|
stroke: 'currentColor',
|
||||||
|
strokeWidth: '2',
|
||||||
|
strokeLinecap: 'round',
|
||||||
|
strokeLinejoin: 'round',
|
||||||
|
},
|
||||||
|
h('path', {
|
||||||
|
// eslint-disable-next-line id-length
|
||||||
|
d: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71',
|
||||||
|
}),
|
||||||
|
h('path', {
|
||||||
|
// eslint-disable-next-line id-length
|
||||||
|
d: 'M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const createSROnlyLabel = (text: string) => {
|
||||||
|
const node = h('span.sr-only', `Section titled ${escape(text)}`);
|
||||||
|
node.properties!['is:raw'] = true;
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
react(),
|
react(),
|
||||||
@@ -20,7 +53,34 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
markdown: {
|
markdown: {
|
||||||
remarkPlugins: [[remarkCodeHike, { autoImport: false, theme: shikiThemeDarkPlus, lineNumbers: true }]],
|
remarkPlugins: [[remarkCodeHike, { autoImport: false, theme: shikiThemeDarkPlus, lineNumbers: true }]],
|
||||||
rehypePlugins: [],
|
rehypePlugins: [
|
||||||
|
rehypeSlug,
|
||||||
|
[
|
||||||
|
rehypeAutolinkHeadings,
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
class:
|
||||||
|
'relative inline-flex w-6 h-6 place-items-center place-content-center outline-0 text-black dark:text-white ml-2',
|
||||||
|
},
|
||||||
|
behavior: 'after',
|
||||||
|
group: ({ tagName }) =>
|
||||||
|
h('div', {
|
||||||
|
class: `[&>*]:inline-block [&>h1]:m-0 [&>h2]:m-0 [&>h3]:m-0 [&>h4]:m-0 level-${tagName}`,
|
||||||
|
tabIndex: -1,
|
||||||
|
}),
|
||||||
|
content: (heading) => [
|
||||||
|
h(
|
||||||
|
`span.anchor-icon`,
|
||||||
|
{
|
||||||
|
ariaHidden: 'true',
|
||||||
|
},
|
||||||
|
LinkIcon,
|
||||||
|
),
|
||||||
|
createSROnlyLabel(toString(heading)),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
extendDefaultPlugins: true,
|
extendDefaultPlugins: true,
|
||||||
syntaxHighlight: false,
|
syntaxHighlight: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -72,9 +72,14 @@
|
|||||||
"eslint": "^8.24.0",
|
"eslint": "^8.24.0",
|
||||||
"eslint-config-neon": "^0.1.35",
|
"eslint-config-neon": "^0.1.35",
|
||||||
"happy-dom": "^7.4.0",
|
"happy-dom": "^7.4.0",
|
||||||
|
"hast-util-to-string": "^2.0.0",
|
||||||
|
"hastscript": "^7.0.2",
|
||||||
|
"html-escaper": "^3.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"prettier-plugin-astro": "^0.5.5",
|
"prettier-plugin-astro": "^0.5.5",
|
||||||
"prettier-plugin-tailwindcss": "^0.1.13",
|
"prettier-plugin-tailwindcss": "^0.1.13",
|
||||||
|
"rehype-autolink-headings": "^6.1.1",
|
||||||
|
"rehype-slug": "^5.0.1",
|
||||||
"typescript": "^4.8.4",
|
"typescript": "^4.8.4",
|
||||||
"unocss": "^0.45.26",
|
"unocss": "^0.45.26",
|
||||||
"vercel": "^28.4.8",
|
"vercel": "^28.4.8",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const { headings } = Astro.props;
|
|||||||
<script is:inline>
|
<script is:inline>
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
const headings = document.querySelectorAll(
|
const headings = document.querySelectorAll(
|
||||||
'div.prose > h1, div.prose > h2, div.prose > h3, div.prose > h4, div.prose > h5',
|
'div.level-h1 > h1, div.level-h2 > h2, div.level-h3 > h3, div.level-h4 > h4',
|
||||||
);
|
);
|
||||||
|
|
||||||
const headingsObserver = new IntersectionObserver(
|
const headingsObserver = new IntersectionObserver(
|
||||||
@@ -27,7 +27,7 @@ const { headings } = Astro.props;
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
root: null,
|
root: null,
|
||||||
rootMargin: '0px 0px -450px 0px',
|
rootMargin: '-100px 0% -66%',
|
||||||
threshold: 1.0,
|
threshold: 1.0,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -52,14 +52,30 @@ export default defineConfig({
|
|||||||
h1: {
|
h1: {
|
||||||
'scroll-margin-top': '6.5rem',
|
'scroll-margin-top': '6.5rem',
|
||||||
},
|
},
|
||||||
|
'.level-h1': {
|
||||||
|
margin: '1rem 0',
|
||||||
|
},
|
||||||
h2: {
|
h2: {
|
||||||
'margin-top': '1.25em',
|
'margin-top': '1.25em',
|
||||||
'scroll-margin-top': '6.5rem',
|
'scroll-margin-top': '6.5rem',
|
||||||
},
|
},
|
||||||
|
'.level-h2': {
|
||||||
|
margin: '1.25em 0',
|
||||||
|
},
|
||||||
h3: {
|
h3: {
|
||||||
'margin-top': '1.25em',
|
'margin-top': '1.25em',
|
||||||
'scroll-margin-top': '6.5rem',
|
'scroll-margin-top': '6.5rem',
|
||||||
},
|
},
|
||||||
|
'.level-h3': {
|
||||||
|
margin: '1.25em 0',
|
||||||
|
},
|
||||||
|
h4: {
|
||||||
|
'margin-top': '1.25em',
|
||||||
|
'scroll-margin-top': '6.5rem',
|
||||||
|
},
|
||||||
|
'.level-h4': {
|
||||||
|
margin: '1.25em 0',
|
||||||
|
},
|
||||||
// eslint-disable-next-line id-length
|
// eslint-disable-next-line id-length
|
||||||
p: {
|
p: {
|
||||||
margin: '.5em 0',
|
margin: '.5em 0',
|
||||||
|
|||||||
22
yarn.lock
22
yarn.lock
@@ -2130,6 +2130,9 @@ __metadata:
|
|||||||
eslint: ^8.24.0
|
eslint: ^8.24.0
|
||||||
eslint-config-neon: ^0.1.35
|
eslint-config-neon: ^0.1.35
|
||||||
happy-dom: ^7.4.0
|
happy-dom: ^7.4.0
|
||||||
|
hast-util-to-string: ^2.0.0
|
||||||
|
hastscript: ^7.0.2
|
||||||
|
html-escaper: ^3.0.3
|
||||||
meilisearch: ^0.28.0
|
meilisearch: ^0.28.0
|
||||||
prettier: ^2.7.1
|
prettier: ^2.7.1
|
||||||
prettier-plugin-astro: ^0.5.5
|
prettier-plugin-astro: ^0.5.5
|
||||||
@@ -2140,9 +2143,11 @@ __metadata:
|
|||||||
react-icons: ^4.4.0
|
react-icons: ^4.4.0
|
||||||
react-syntax-highlighter: ^15.5.0
|
react-syntax-highlighter: ^15.5.0
|
||||||
react-use: ^17.4.0
|
react-use: ^17.4.0
|
||||||
|
rehype-autolink-headings: ^6.1.1
|
||||||
rehype-ignore: ^1.0.1
|
rehype-ignore: ^1.0.1
|
||||||
rehype-pretty-code: ^0.3.2
|
rehype-pretty-code: ^0.3.2
|
||||||
rehype-raw: ^6.1.1
|
rehype-raw: ^6.1.1
|
||||||
|
rehype-slug: ^5.0.1
|
||||||
sharp: ^0.31.1
|
sharp: ^0.31.1
|
||||||
shiki: ^0.11.1
|
shiki: ^0.11.1
|
||||||
typescript: ^4.8.4
|
typescript: ^4.8.4
|
||||||
@@ -11173,7 +11178,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"hastscript@npm:^7.0.0":
|
"hastscript@npm:^7.0.0, hastscript@npm:^7.0.2":
|
||||||
version: 7.0.2
|
version: 7.0.2
|
||||||
resolution: "hastscript@npm:7.0.2"
|
resolution: "hastscript@npm:7.0.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -16706,6 +16711,21 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"rehype-autolink-headings@npm:^6.1.1":
|
||||||
|
version: 6.1.1
|
||||||
|
resolution: "rehype-autolink-headings@npm:6.1.1"
|
||||||
|
dependencies:
|
||||||
|
"@types/hast": ^2.0.0
|
||||||
|
extend: ^3.0.0
|
||||||
|
hast-util-has-property: ^2.0.0
|
||||||
|
hast-util-heading-rank: ^2.0.0
|
||||||
|
hast-util-is-element: ^2.0.0
|
||||||
|
unified: ^10.0.0
|
||||||
|
unist-util-visit: ^4.0.0
|
||||||
|
checksum: 60782fb2e505e70f75b59a3ac43cb5abfeb328485da07b604fcc73d6bc3626e9c3657d536a77c6c6c435b7b3086bae5c7f93d5ded510d74e553fd80fd91c8f97
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"rehype-ignore@npm:^1.0.1":
|
"rehype-ignore@npm:^1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "rehype-ignore@npm:1.0.1"
|
resolution: "rehype-ignore@npm:1.0.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user