refactor(core): removed legacy docgen implementation

This commit is contained in:
Ken committed 2026-07-10 13:10:22 +02:00
1 parent bdaeac40e7
commit 9506e93017
7 files changed
+2 -138

No files matched your search

@@ -89,7 +89,7 @@ Move stories to component root dir. If stories import from internal paths, updat
### 5. Update `index.ts`
The repo uses a mix of default and named exports because `react-docgen-typescript` (used by `scripts/docgen.ts`) has inconsistent pickup depending on export style. Follow the existing pattern in the component's original `index.ts` — do NOT change export style during restructure.
The repo uses a mix of default and named export. Follow the existing pattern in the component's original `index.ts` — do NOT change export style during restructure.
Typical pattern (main component as default re-export, sub-components as named):
-3
View File
@@ -27,9 +27,6 @@ jobs:
with:
npm_auth_token: ${{ secrets.READER_TOKEN }}
- name: Run ts-docgen
run: yarn docgen
- name: Run metadata generation
run: yarn docgen:meta
-3
View File
@@ -107,11 +107,8 @@ utilities/**/css
*/**/NAV-ikonpakke-png.zip
*/**/NAV-ikonpakke-svg.zip
react-docgen.json
react-docgen-docs.json
cjs
esm
@navikt/community/navno/css
.vercel
_docs.json
_metadata.json
-1
View File
@@ -722,7 +722,6 @@
}
},
"scripts": {
"docgen": "tsx ../../../scripts/docgen.ts && yarn docgen:meta",
"docgen:meta": "yarn metadata:generate-names && tsx ./scripts/extract-metadata.ts",
"metadata:generate-names": "tsx ./scripts/extract-component-names.ts",
"i18n-jsdoc": "tsx ./scripts/addJsdocToLocales.ts",
@@ -11,7 +11,6 @@ import { validateMetas } from "./metadata/validate-meta";
* Orchestrates the metadata utils: parse -> validate -> run
* `react-docgen-typescript` on the referenced components/utils -> emit a
* grouped record per family to `_metadata.json`.
* Runs alongside `scripts/docgen.ts` during the migration.
*/
const metas = parseMetaFiles();
+1 -2
View File
@@ -21,12 +21,11 @@
"build:storybook": "storybook build",
"chromatic": "npx chromatic --only-changed --build-script-name build:storybook-chromatic",
"build:storybook-chromatic": "cross-env CHROMATIC=true WITH_WEBSITE=true storybook build",
"docgen": "yarn workspaces foreach -vv -pA run docgen",
"changelog": "deno run --allow-read --allow-write --no-config scripts/deno/changelog/createMainChangelog.ts",
"updateArticleViews": "deno run --allow-net --allow-env --allow-read --no-config scripts/deno/article-views/update-article-views/main.ts",
"changeset": "changeset",
"create-version": "changeset version && yarn changelog && yarn",
"release": "yarn boot && yarn docgen && changeset publish && yarn script:git-release",
"release": "yarn boot && yarn docgen:meta && changeset publish && yarn script:git-release",
"postinstall": "husky install"
},
"workspaces": [
-127
View File
@@ -1,127 +0,0 @@
import fg from "fast-glob";
import { writeFileSync } from "node:fs";
import * as docgen from "react-docgen-typescript";
export interface ComponentDoc extends docgen.ComponentDoc {
props: {
[key: string]: docgen.PropItem & {
// Extra fields added during enrichment
example?: string;
params?: string[];
return?: string;
deprecated?: string;
};
};
}
const options: docgen.ParserOptions = {
savePropValueAsString: true,
shouldRemoveUndefinedFromOptional: true,
shouldExtractLiteralValuesFromEnum: true,
propFilter: (prop) => {
if (prop.name === "as" && prop.type.name === "undefined") {
return false;
}
if (prop.name === "className" || prop.parent?.name === "RefAttributes") {
return true;
}
if (prop.parent?.fileName.includes("/node_modules/@types/react/")) {
return false;
}
/**
* Filter out all HTML attributes inherited from React.HTMLAttributes
* className is handled separately above
*/
if (prop.parent?.name === "HTMLAttributes") {
return false;
}
return true;
},
};
const tsConfigParser = docgen.withCustomConfig(`./tsconfig.esm.json`, options);
const enrich_extra_prop_fields = (docs: ComponentDoc[]) => {
for (const doc of docs) {
for (const prop of Object.values(doc.props)) {
if (!prop.description) {
continue;
}
const example_regex = /@example((.|\n)*?(?=@[a-z]+\s))|@example((.|\n)*)/;
const example = prop.description.match(example_regex);
prop.description = prop.description.replace(example_regex, "");
// We replace twice as a hack b.c. 'asChild' ends up with two @example-blocks,
// probably b.c. it's defined two times (discriminated union, see AsChildProps.ts)
prop.description = prop.description.replace(example_regex, "").trim();
if (example?.[1] || example?.[3]) {
prop.example = (example[1] || example[3]).trim();
}
const params_regex = /(@param|@argument|@arg)(.*)/g;
const params = prop.description.match(params_regex);
prop.description = prop.description.replace(params_regex, "").trim();
if (params) {
prop.params = params.map((param) =>
param.replace(/@param|@argument|@arg/, "").trim(),
);
}
const return_regex = /(@returns?)(.*)/;
const _return = prop.description.match(return_regex);
prop.description = prop.description.replace(return_regex, "").trim();
if (_return) {
const return_val = _return[2].replace(/@returns?/, "").trim();
prop.return = return_val ? return_val : "void";
}
const link_regex = /@see {@link (http[^ ]+) ([^}]+)}/;
prop.description = prop.description.replace(link_regex, "[$2]($1)");
const deprecation_regex = /(@deprecated?)(.*)/;
const deprecation = prop.description.match(deprecation_regex);
prop.description = prop.description.replace(deprecation_regex, "").trim();
if (deprecation) {
const return_val = deprecation[2].replace(/@deprecated?/, "").trim();
prop.deprecated = return_val;
}
}
}
};
const genDocs = () => {
const files = fg
.sync([`./src/**/*.tsx`, "!**/*.stories.*", "!**/*.test.*", "!**/stories"])
.filter(
(x) =>
!x.toLowerCase().includes("illustration") &&
!x.toLowerCase().includes("pictogram"),
);
const res: ComponentDoc[][] = [];
const fails: string[] = [];
files.forEach((file) => {
const doc = tsConfigParser.parse(file);
enrich_extra_prop_fields(doc);
if (doc.length > 0) {
res.push(doc);
} else {
fails.push(file);
}
});
console.info({ Documented: res.length, fails });
const cleaned = res.flat().map((file) => ({
filePath: file.filePath,
displayName: file.displayName,
props: file.props,
}));
writeFileSync(`_docs.json`, JSON.stringify(cleaned, null, 2));
};
genDocs();