for example, we can use @since annotation to get a version this could be in turn used to be displayed in storybook.
i did some hacking around with storyblocks and i got something based on this plugin
annotation example based on shoelace example
/**
* A button is used to trigger an action. For more information about a button, click [here](https://unify.nedap.healthcare/42a5b6c3c/p/17c689-button/b/05c6fc)
*
* @status stable
* @since 2.0.0
*
* @dependency uc-icon
* @dependency uc-badge
*
**/
the cem plugin
import {parse} from 'comment-parser';
function noDash(string) {
return string.replace(/^\s?-/, '').trim();
}
export function customTags() {
return {
name: 'custom-tags',
analyzePhase({ts, node, moduleDoc}) {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration: {
const className = node.name.getText();
const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className);
const customTags = ['aria-rules', 'deprecated-attribute','dependency', 'status', 'since'];
let customComments = '/**';
node.jsDoc?.forEach(jsDoc => {
jsDoc?.tags?.forEach(tag => {
const tagName = tag.tagName.getText();
if (customTags.includes(tagName)) {
customComments += `\n * @${tagName} ${tag.comment}`;
}
});
});
// This is what allows us to map JSDOC comments to ReactWrappers.
classDoc['jsDoc'] = node.jsDoc?.map(jsDoc => jsDoc.getFullText()).join('\n');
const parsed = parse(`${customComments}\n */`);
parsed[0].tags?.forEach(t => {
switch (t.tag) {
// custom rule for aria
case 'aria-rules':
if (!Array.isArray(classDoc['aria-rules'])) {
classDoc['aria-rules'] = [];
}
classDoc['aria-rules'].push({
name: t.name,
description: noDash(t.description),
});
break;
// custom deprecated attribute rule
case 'deprecated-attribute':
if (!Array.isArray(classDoc['deprecated-attribute'])) {
classDoc['deprecated-attribute'] = [];
}
classDoc['deprecated-attribute'].push({
name: t.name,
description: noDash(t.description),
});
break;
// custom deprecated element rule
case 'deprecated':
if (!Array.isArray(classDoc['deprecated'])) {
classDoc['deprecated'] = [];
}
classDoc['deprecated'].push({
description: noDash(t.description),
});
break;
// Dependencies
case 'dependency':
if (!Array.isArray(classDoc['dependencies'])) {
classDoc['dependencies'] = [];
}
classDoc['dependencies'].push(t.name);
break;
// Value-only metadata tags
case 'since':
case 'status':
classDoc[t.tag] = t.name;
break;
// All other tags
default:
if (!Array.isArray(classDoc[t.tag])) {
classDoc[t.tag] = [];
}
classDoc[t.tag].push({
name: t.name,
description: t.description,
type: t.type || undefined
});
}
});
}
}
}
}
}
preview.ts
import { setCustomElementsManifest } from "@storybook/web-components";
import { setWcStorybookHelpersConfig } from "wc-storybook-helpers";
import customElements from "custom-elements.json";
import DocumentationTemplate from "./DocumentationTemplate.mdx";
setWcStorybookHelpersConfig({ typeRef: "expandedType", hideArgRef: true });
setCustomElementsManifest(customElements);
const preview: Preview = {
// ... more settings and things
docs: {
page: DocumentationTemplate,
},
}
export default preview;
DocumentationTemplate.mdx
import { Meta, Title, Subtitle, Primary, Controls, Stories, Description } from '@storybook/blocks';
import MyCustomBlock from './MyCustomBlock';
{/*
* 👇 The isTemplate property is required to tell Storybook that this is a template
* See https://storybook.js.org/docs/api/doc-block-meta
* to learn how to use
*/}
<Meta isTemplate />
<Title />
<Subtitle/>
<Description />
<MyCustomBlock />
# Default implementation
<Primary />
## Inputs
The component accepts the following inputs (props):
<Controls />
---
## Additional variations
Listed below are additional variations of the component.
<Stories />
like discussed on discord :)
the idea is to be able to use custom jsdoc annotations to document things in storybook based on this work https://github.com/shoelace-style/shoelace/blob/dafb35c6e210193a9ca31efddc3429ba2bb66be3/custom-elements-manifest.config.js
for example, we can use
@since
annotation to get a version this could be in turn used to be displayed in storybook. i did some hacking around with storyblocks and i got something based on this pluginannotation example based on shoelace example
the cem plugin
preview.ts
DocumentationTemplate.mdx
MyCustomBlock.jsx