Skip to content

Commit eb7fa84

Browse files
committed
Prototype props table for design system documentation
1 parent 6e61b0c commit eb7fa84

File tree

13 files changed

+213
-22
lines changed

13 files changed

+213
-22
lines changed

.eslintrc.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ module.exports = {
6060
},
6161
},
6262
{
63-
files: [ 'bin/**/*', 'test/**/*' ],
63+
files: [ '**/bin/**/*', '**/test/**/*' ],
6464
...nodeConfig,
6565
},
6666
{
@@ -87,7 +87,7 @@ module.exports = {
8787
require( 'eslint-config-prettier' ),
8888
// Our own overrides
8989
{
90-
files: [ '**/*.ts', '**/*.tsx' ],
90+
files: [ '**/*.ts', '**/*.mts', '**/*.tsx' ],
9191
rules: {
9292
// Disable vanilla eslint rules that have a Typescript implementation
9393
// See https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/README.md#extension-rules
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import PropsTable from '#components/props-table';
2+
3+
# Breadcrumbs
4+
5+
<PropsTable component="Breadcrumbs" />
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import PropsTable from '#components/props-table';
2+
3+
# SummaryButton
4+
5+
<PropsTable component="SummaryButton" />

apps/design-system-docs/docusaurus.config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ const config: Config = {
2727
locales: [ 'en' ],
2828
},
2929

30+
plugins: [
31+
() => ( {
32+
name: 'dsdocs-resolver-plugin',
33+
configureWebpack( config ) {
34+
config.resolve ??= {};
35+
config.resolve.conditionNames ??= [ '...' ];
36+
config.resolve.conditionNames.unshift( 'dsdocs:src' );
37+
return config;
38+
},
39+
} ),
40+
],
41+
3042
presets: [
3143
[
3244
'classic',

apps/design-system-docs/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"url": "https://github.com/Automattic/wp-calypso.git",
1212
"directory": "apps/design-system-docs"
1313
},
14+
"imports": {
15+
"#components/*": "./src/components/*"
16+
},
1417
"scripts": {
1518
"docusaurus": "docusaurus",
1619
"start": "docusaurus start -p 42987",
@@ -28,7 +31,8 @@
2831
"@mdx-js/react": "^3.0.0",
2932
"prism-react-renderer": "^2.3.0",
3033
"react": "^18.3.1",
31-
"react-dom": "^18.3.1"
34+
"react-dom": "^18.3.1",
35+
"react-markdown": "^9.0.1"
3236
},
3337
"devDependencies": {
3438
"@docusaurus/module-type-aliases": "^3.7.0",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.required {
2+
color: var(--ifm-color-danger);
3+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import metadata from '@automattic/components/metadata';
2+
import { VisuallyHidden } from '@wordpress/components';
3+
import Markdown from 'react-markdown';
4+
import styles from './props-table.module.css';
5+
6+
interface PropsTableProps {
7+
component: string;
8+
}
9+
10+
function PropsTable( { component }: PropsTableProps ) {
11+
if ( ! metadata[ component ] ) {
12+
return null;
13+
}
14+
15+
const { props } = metadata[ component ];
16+
17+
return (
18+
<table>
19+
<thead>
20+
<tr>
21+
<th>Name</th>
22+
<th>Description</th>
23+
<th>Type</th>
24+
<th>Default</th>
25+
</tr>
26+
</thead>
27+
<tbody>
28+
{ Object.entries( props ).map( ( [ key, value ] ) => (
29+
<tr key={ key }>
30+
<td width="20%">
31+
{ key }
32+
{ value.required && (
33+
<>
34+
<VisuallyHidden>(Required)</VisuallyHidden>
35+
<span className={ styles.required } aria-hidden>
36+
*
37+
</span>
38+
</>
39+
) }
40+
</td>
41+
<td width="50%">
42+
<Markdown>{ value.description }</Markdown>
43+
</td>
44+
<td width="15%">{ value.type.name }</td>
45+
<td width="15%">{ value.defaultValue?.value }</td>
46+
</tr>
47+
) ) }
48+
</tbody>
49+
</table>
50+
);
51+
}
52+
53+
export default PropsTable;

apps/design-system-docs/tsconfig.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
// This file is not used in compilation. It is here just for a nice editor experience.
33
"extends": [ "@docusaurus/tsconfig", "@automattic/calypso-build/tsconfig.json" ],
44
"compilerOptions": {
5-
"baseUrl": "."
5+
"module": "ESNext",
6+
"moduleResolution": "bundler",
7+
"baseUrl": ".",
8+
"paths": {
9+
"#components/*": [ "./src/components/*" ]
10+
}
611
},
712
"exclude": [ ".docusaurus", "dist" ]
813
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
"lint": "run-s -s 'lint:*'",
102102
"lint:config-defaults": "node bin/validate-config-keys.js",
103103
"lint:css": "stylelint \"**/*.{css,scss}\"",
104-
"lint:js": "eslint --ext .js,.jsx,.ts,.tsx,.mjs,.json --cache .",
104+
"lint:js": "eslint --ext .js,.jsx,.ts,.tsx,.mjs,.mts,.json --cache .",
105105
"lint:mixedindent": "mixedindentlint --ignore-comments \"client/**/*.scss\" \"assets/**/*.scss\" \"!build/**\" \"!node_modules/**\" \"!public/**\"",
106106
"lint:unused-state-action-types": "bin/find-unused-state-action-types.sh",
107107
"postcss": "postcss -r --config packages/calypso-build/postcss.config.js",
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { mkdir, writeFile } from 'node:fs/promises';
2+
import { join } from 'node:path';
3+
import { parse } from 'react-docgen-typescript';
4+
5+
type ComponentMetadata = {
6+
props: Record<
7+
string,
8+
{
9+
description: string;
10+
defaultValue?: { value: any };
11+
required: boolean;
12+
type: { name: string };
13+
}
14+
>;
15+
};
16+
17+
const DOCUMENTED_COMPONENTS = [ 'breadcrumbs', 'summary-button' ];
18+
19+
const files = DOCUMENTED_COMPONENTS.map( ( component ) => `${ component }/index.tsx` );
20+
21+
const pick = < O extends Record< string, any >, K extends Array< keyof O > >(
22+
obj: O,
23+
keys: K
24+
): Pick< O, K[ number ] > =>
25+
Object.fromEntries( Object.entries( obj ).filter( ( [ key ] ) => keys.includes( key ) ) ) as Pick<
26+
O,
27+
K[ number ]
28+
>;
29+
30+
const omit = < O extends Record< string, any >, K extends Array< keyof O > >(
31+
obj: O,
32+
keys: K
33+
): Omit< O, K[ number ] > =>
34+
Object.fromEntries(
35+
Object.entries( obj ).filter( ( [ key ] ) => ! keys.includes( key ) )
36+
) as Omit< O, K[ number ] >;
37+
38+
const mapValues = < V, MV >(
39+
obj: Record< string, V >,
40+
fn: ( value: V ) => MV
41+
): Record< string, MV > =>
42+
Object.fromEntries( Object.entries( obj ).map( ( [ key, value ] ) => [ key, fn( value ) ] ) );
43+
44+
async function getMetadataEntry( file: string ): Promise< [ string, ComponentMetadata ] > {
45+
const parsed = await parse( join( process.cwd(), 'src', file ) );
46+
const [ { displayName, props } ] = parsed;
47+
return [
48+
displayName,
49+
{
50+
props: mapValues( omit( props, [ 'ref', 'key' ] ), ( value ) =>
51+
pick( value, [ 'description', 'defaultValue', 'required', 'type' ] )
52+
),
53+
},
54+
];
55+
}
56+
57+
const metadata = Object.fromEntries( await Promise.all( files.map( getMetadataEntry ) ) );
58+
59+
await mkdir( 'dist/types', { recursive: true } );
60+
61+
await Promise.all( [
62+
writeFile( 'dist/metadata.js', `export default ${ JSON.stringify( metadata, null, 2 ) };` ),
63+
writeFile(
64+
'dist/types/metadata.d.ts',
65+
`declare const metadata: Record< string, {
66+
props: Record< string, {
67+
description: string;
68+
defaultValue?: { value: any };
69+
required: boolean;
70+
type: { name: string; };
71+
} >;
72+
} >;
73+
74+
export default metadata;`
75+
),
76+
] );

packages/components/package.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616
"require": "./dist/cjs/index.js"
1717
},
1818
"./src/*": {
19-
"calypso:src": "./src/*"
19+
"calypso:src": "./src/*",
20+
"import": "./src/*"
2021
},
2122
"./styles/*": {
2223
"calypso:src": "./styles/*"
24+
},
25+
"./metadata": {
26+
"dsdocs:src": "./dist/metadata.js",
27+
"types": "./dist/types/metadata.d.ts"
2328
}
2429
},
2530
"sideEffects": [
@@ -92,15 +97,21 @@
9297
"@testing-library/user-event": "^14.6.1",
9398
"@types/canvas-confetti": "^1.6.0",
9499
"@types/node": "^22.7.5",
100+
"npm-run-all": "^4.1.5",
95101
"postcss": "^8.5.3",
102+
"react-docgen-typescript": "^2.2.2",
96103
"storybook": "^8.6.12",
97104
"typescript": "^5.8.3",
98105
"webpack": "^5.97.1"
99106
},
100107
"scripts": {
101108
"clean": "tsc --build ./tsconfig.json ./tsconfig-cjs.json --clean && rm -rf dist",
102-
"build": "tsc --build ./tsconfig.json ./tsconfig-cjs.json && copy-assets",
109+
"build": "run-p 'build:*'",
110+
"build:metadata": "node --experimental-strip-types bin/build-metadata.mts",
111+
"build:components": "tsc --build ./tsconfig.json",
112+
"build:assets": "copy-assets",
103113
"prepack": "yarn run clean && yarn run build",
114+
"prepare": "yarn run build",
104115
"storybook:start": "storybook dev -p 56833",
105116
"storybook:build": "storybook build"
106117
}

yarn.lock

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -873,8 +873,10 @@ __metadata:
873873
gridicons: "npm:^3.4.2"
874874
i18n-calypso: "workspace:^"
875875
lodash: "npm:^4.17.21"
876+
npm-run-all: "npm:^4.1.5"
876877
postcss: "npm:^8.5.3"
877878
prop-types: "npm:^15.8.1"
879+
react-docgen-typescript: "npm:^2.2.2"
878880
react-modal: "npm:^3.16.3"
879881
react-router-dom: "npm:^6.23.1"
880882
storybook: "npm:^8.6.12"
@@ -1097,6 +1099,7 @@ __metadata:
10971099
prism-react-renderer: "npm:^2.3.0"
10981100
react: "npm:^18.3.1"
10991101
react-dom: "npm:^18.3.1"
1102+
react-markdown: "npm:^9.0.1"
11001103
typescript: "npm:^5.8.3"
11011104
languageName: unknown
11021105
linkType: soft
@@ -9423,11 +9426,11 @@ __metadata:
94239426
linkType: hard
94249427

94259428
"@types/hast@npm:^2.0.0":
9426-
version: 2.3.4
9427-
resolution: "@types/hast@npm:2.3.4"
9429+
version: 2.3.10
9430+
resolution: "@types/hast@npm:2.3.10"
94289431
dependencies:
9429-
"@types/unist": "npm:*"
9430-
checksum: 635cfe9a8e91f6b3c15c9929455d0136ac4d75c5b7f596ce21b453cecdfda785e89b10eb2b2d9da9d43e548b1d65ba3e20c741bbaf83823575c9c45001ade4bb
9432+
"@types/unist": "npm:^2"
9433+
checksum: 16daac35d032e656defe1f103f9c09c341a6dc553c7ec17b388274076fa26e904a71ea5ea41fd368a6d5f1e9e53be275c80af7942b9c466d8511d261c9529c7e
94319434
languageName: node
94329435
linkType: hard
94339436

@@ -9599,11 +9602,11 @@ __metadata:
95999602
linkType: hard
96009603

96019604
"@types/mdast@npm:^3.0.0":
9602-
version: 3.0.11
9603-
resolution: "@types/mdast@npm:3.0.11"
9605+
version: 3.0.15
9606+
resolution: "@types/mdast@npm:3.0.15"
96049607
dependencies:
9605-
"@types/unist": "npm:*"
9606-
checksum: 569ec32ac16deb42f2c9e7cdbfb5be0f67d2407036b49ba9cfa07ad0258b044c259922acba170eaed165ebcf5eb168032fbb4b3e35023fe8c581fe46e9bcbad0
9608+
"@types/unist": "npm:^2"
9609+
checksum: fcbf716c03d1ed5465deca60862e9691414f9c43597c288c7d2aefbe274552e1bbd7aeee91b88a02597e88a28c139c57863d0126fcf8416a95fdc681d054ee3d
96079610
languageName: node
96089611
linkType: hard
96099612

@@ -9773,13 +9776,20 @@ __metadata:
97739776
languageName: node
97749777
linkType: hard
97759778

9776-
"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0":
9779+
"@types/prop-types@npm:*":
97779780
version: 15.7.5
97789781
resolution: "@types/prop-types@npm:15.7.5"
97799782
checksum: 648aae41423821c61c83823ae36116c8d0f68258f8b609bdbc257752dcd616438d6343d554262aa9a7edaee5a19aca2e028a74fa2d0f40fffaf2816bc7056857
97809783
languageName: node
97819784
linkType: hard
97829785

9786+
"@types/prop-types@npm:^15.0.0":
9787+
version: 15.7.14
9788+
resolution: "@types/prop-types@npm:15.7.14"
9789+
checksum: 1ec775160bfab90b67a782d735952158c7e702ca4502968aa82565bd8e452c2de8601c8dfe349733073c31179116cf7340710160d3836aa8a1ef76d1532893b1
9790+
languageName: node
9791+
linkType: hard
9792+
97839793
"@types/qs@npm:*, @types/qs@npm:^6.9.7":
97849794
version: 6.9.7
97859795
resolution: "@types/qs@npm:6.9.7"
@@ -10066,6 +10076,13 @@ __metadata:
1006610076
languageName: node
1006710077
linkType: hard
1006810078

10079+
"@types/unist@npm:^2":
10080+
version: 2.0.11
10081+
resolution: "@types/unist@npm:2.0.11"
10082+
checksum: 24dcdf25a168f453bb70298145eb043cfdbb82472db0bc0b56d6d51cd2e484b9ed8271d4ac93000a80da568f2402e9339723db262d0869e2bf13bc58e081768d
10083+
languageName: node
10084+
linkType: hard
10085+
1006910086
"@types/unist@npm:^2.0.0, @types/unist@npm:^2.0.2":
1007010087
version: 2.0.6
1007110088
resolution: "@types/unist@npm:2.0.6"
@@ -17357,9 +17374,9 @@ __metadata:
1735717374
linkType: hard
1735817375

1735917376
"diff@npm:^5.0.0":
17360-
version: 5.1.0
17361-
resolution: "diff@npm:5.1.0"
17362-
checksum: 77a0d9beb9ed54796154ac2511872288432124ac90a1cabb1878783c9b4d81f1847f3b746a0630b1e836181461d2c76e1e6b95559bef86ed16294d114862e364
17377+
version: 5.2.0
17378+
resolution: "diff@npm:5.2.0"
17379+
checksum: aed0941f206fe261ecb258dc8d0ceea8abbde3ace5827518ff8d302f0fc9cc81ce116c4d8f379151171336caf0516b79e01abdc1ed1201b6440d895a66689eb4
1736317380
languageName: node
1736417381
linkType: hard
1736517382

@@ -33844,11 +33861,11 @@ __metadata:
3384433861
linkType: hard
3384533862

3384633863
"style-to-object@npm:^0.4.0":
33847-
version: 0.4.1
33848-
resolution: "style-to-object@npm:0.4.1"
33864+
version: 0.4.4
33865+
resolution: "style-to-object@npm:0.4.4"
3384933866
dependencies:
3385033867
inline-style-parser: "npm:0.1.1"
33851-
checksum: bde789dab148ec01032d75ea3a7d9294aa8dac369e9ef44f9a8f504df565f806b5a2c7226e3355f09a7e5d127684c65a0b7a7ade08780e0f893299e945d1464e
33868+
checksum: 3a733080da66952881175b17d65f92985cf94c1ca358a92cf21b114b1260d49b94a404ed79476047fb95698d64c7e366ca7443f0225939e2fb34c38bbc9c7639
3385233869
languageName: node
3385333870
linkType: hard
3385433871

0 commit comments

Comments
 (0)