diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 563805c7..7f6af111 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -59,6 +59,7 @@
"@reporters/github": "^1.12.0",
"@types/mdast": "^4.0.4",
"@types/node": "^24.10.1",
+ "@types/semver": "^7.7.1",
"c8": "^10.1.3",
"eslint": "^9.39.2",
"eslint-import-resolver-node": "^0.3.9",
@@ -959,7 +960,6 @@
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
"license": "MIT",
- "peer": true,
"engines": {
"node": "^14.21.3 || >=16"
},
@@ -1059,7 +1059,6 @@
"resolved": "https://registry.npmjs.org/@orama/cuid2/-/cuid2-2.2.3.tgz",
"integrity": "sha512-Lcak3chblMejdlSHgYU2lS2cdOhDpU6vkfIJH4m+YKvqQyLqs1bB8+w6NT1MG5bO12NUK2GFc34Mn2xshMIQ1g==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@noble/hashes": "^1.1.5"
}
@@ -1077,8 +1076,7 @@
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/@orama/oramacore-events-parser/-/oramacore-events-parser-0.0.5.tgz",
"integrity": "sha512-yAuSwog+HQBAXgZ60TNKEwu04y81/09mpbYBCmz1RCxnr4ObNY2JnPZI7HmALbjAhLJ8t5p+wc2JHRK93ubO4w==",
- "license": "AGPL-3.0",
- "peer": true
+ "license": "AGPL-3.0"
},
"node_modules/@orama/stopwords": {
"version": "3.1.16",
@@ -3347,6 +3345,13 @@
"csstype": "^3.0.2"
}
},
+ "node_modules/@types/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@@ -3509,6 +3514,7 @@
"integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.54.0",
@@ -3898,6 +3904,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -4439,8 +4446,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/debug": {
"version": "4.4.3",
@@ -4643,6 +4649,7 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -7560,6 +7567,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -7609,6 +7617,7 @@
"resolved": "https://registry.npmjs.org/preact/-/preact-11.0.0-beta.0.tgz",
"integrity": "sha512-IcODoASASYwJ9kxz7+MJeiJhvLriwSb4y4mHIyxdgaRZp6kPUud7xytrk/6GZw8U3y6EFJaRb5wi9SrEK+8+lg==",
"license": "MIT",
+ "peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
@@ -8111,8 +8120,7 @@
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/semver": {
"version": "7.7.3",
@@ -8700,6 +8708,7 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -9054,6 +9063,7 @@
"integrity": "sha512-VUyWiTNQD7itdiMuJy+EuLEErLj3uwX/EpHQF8EOf33Dq3Ju6VW1GXm+swk6+1h7a49uv9fKZ+dft9jU7esdLA==",
"dev": true,
"hasInstallScript": true,
+ "peer": true,
"dependencies": {
"napi-postinstall": "^0.2.4"
},
@@ -9484,7 +9494,6 @@
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz",
"integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==",
"license": "ISC",
- "peer": true,
"peerDependencies": {
"zod": "^3.24.1"
}
diff --git a/package.json b/package.json
index 8e4f854a..4e410d39 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
"@reporters/github": "^1.12.0",
"@types/mdast": "^4.0.4",
"@types/node": "^24.10.1",
+ "@types/semver": "^7.7.1",
"c8": "^10.1.3",
"eslint": "^9.39.2",
"eslint-import-resolver-node": "^0.3.9",
diff --git a/src/generators/jsx-ast/utils/buildBarProps.mjs b/src/generators/jsx-ast/utils/buildBarProps.mjs
index 047bf2b3..15031e90 100644
--- a/src/generators/jsx-ast/utils/buildBarProps.mjs
+++ b/src/generators/jsx-ast/utils/buildBarProps.mjs
@@ -68,7 +68,7 @@ const extractHeading = entry => {
value: heading,
stability: parseInt(entry.stability?.children[0]?.data.index ?? 2),
slug: data.slug,
- data: { id: data.slug },
+ data: { id: data.slug, type: data.type },
};
};
diff --git a/src/generators/jsx-ast/utils/buildContent.mjs b/src/generators/jsx-ast/utils/buildContent.mjs
index 030bfd6b..09f5663d 100644
--- a/src/generators/jsx-ast/utils/buildContent.mjs
+++ b/src/generators/jsx-ast/utils/buildContent.mjs
@@ -123,9 +123,15 @@ export const createHeadingElement = (content, changeElement) => {
// Build heading with anchor link
const headingWrapper = createElement('div', [
- createElement(`h${depth}`, [
- createElement(`a#${slug}`, { href: `#${slug}` }, headingContent),
- ]),
+ createElement(
+ `h${depth}`,
+ { id: slug },
+ createElement(
+ 'a',
+ { href: `#${slug}`, className: ['anchor'] },
+ headingContent
+ )
+ ),
]);
// Prepend type icon if not 'misc' and type exists
diff --git a/src/generators/types.d.ts b/src/generators/types.d.ts
index 2638e6c8..efdbd5f5 100644
--- a/src/generators/types.d.ts
+++ b/src/generators/types.d.ts
@@ -1,5 +1,4 @@
import type { SemVer } from 'semver';
-import type { ApiDocReleaseEntry } from '../types';
import type { publicGenerators, allGenerators } from './index.mjs';
declare global {
diff --git a/src/generators/web/ui/components/MetaBar/index.jsx b/src/generators/web/ui/components/MetaBar/index.jsx
index b5d8d5e4..23f48638 100644
--- a/src/generators/web/ui/components/MetaBar/index.jsx
+++ b/src/generators/web/ui/components/MetaBar/index.jsx
@@ -21,6 +21,38 @@ const iconMap = {
const STABILITY_KINDS = ['error', 'warning', null, 'info'];
const STABILITY_LABELS = ['D', 'E', null, 'L'];
+const STABILITY_TOOLTIPS = ['Deprecated', 'Experimental', null, 'Legacy'];
+
+/**
+ * Renders a heading value with an optional stability badge
+ * @param {{ value: string, stability: number }} props
+ */
+const HeadingValue = ({ value, stability }) => {
+ if (stability === 2) {
+ return value;
+ }
+
+ const ariaLabel = STABILITY_TOOLTIPS[stability]
+ ? `Stability: ${STABILITY_TOOLTIPS[stability]}`
+ : undefined;
+
+ return (
+ <>
+ {value}
+
+