builder-vite
builder-vite copied to clipboard
[Bug] argTypes not working in mdx
What version of vite
are you using?
2.9.13
System info and storybook versions
System:
OS: Windows 10 10.0.19044
CPU: (12) x64 Intel(R) Core(TM) i7-10750
H CPU @ 2.60GHz
Binaries:
Node: 18.4.0 - ~\scoop\persist\nvm\nodej
s\nodejs\node.EXE
npm: 8.12.1 - ~\scoop\persist\nvm\nodejs
\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.19041.1266.0), Chromiu
6.5.9
@storybook/addon-links: ^6.5.9 => 6.5.9
@storybook/addon-notes: ^5.3.21 => 5.3.21
@storybook/addon-postcss: ^2.0.0 => 2.0.0
@storybook/builder-vite: ^0.1.36 => 0.1.38
@storybook/csf-tools: ^6.5.9 => 6.5.9
@storybook/testing-library: ^0.0.13 => 0.0.13
@storybook/theming: ^6.5.9 => 6.5.9
@storybook/vue3: ^6.5.9 => 6.5.9
Describe the Bug
When using argsTypes in MDX the changes are not being applied to the argsTable. The same component and config works as expected when using a normal CSF file.
Reproduction:
component.stories.mdx
import { Meta, Canvas, Story, ArgsTable, Description } from '@storybook/addon-docs'
const Component = {
description: 'test',
props: {
id: String(),
status: String(),
label: String()
},
__docgenInfo: {
displayName: 'component',
props: [
{name: 'id', required: true, type: {name: 'number'}},
{name: 'status', required: true, type: {name: 'string'}},
{name: 'label', required: true, type: {name: 'string'}}
]
}
}
<Meta title="component" component={Component} argTypes={{
status: {
name: 'Badge Status',
description: 'Available options available to the Badge',
options: [
'positive',
'negative',
'warning',
'error',
'neutral'
],
table: {
defaultValue: {
summary: 'positive'
},
type: {
summary: 'Shows options to the Badge',
detail: 'Listing of available options'
},
},
},
label: {
name: 'Badge Content',
description: 'Text shown by Badge',
control: {
type: 'text'
},
table: {
type: {
summary: 'The label contents',
detail: 'Text displayed by the Badge'
}
}
}
}} />
<ArgsTable for={Component} />
Link to Minimal Reproducible Example
No response
Participation
- [ ] I am willing to submit a pull request for this issue.
not sure if you're using typescript, but i had a similar issue in that none of my documentation changes were reflected, regardless of story file type. in my case, the issue was actually with @joshwooding/vite-plugin-react-docgen-typescript
.
when the plugin's transform
function is called, parseWithProgramProvider
(from react-docgen-typescript
) is used to generate a ComponentDoc
array. during plugin setup, however, the program provider is created using a "static" set of files.
my guess is that even though the plugin itself receives updated code, as well as the path to the updated code, the program provider files are actually stale. i'm not sure if it's possible to update provider files, but i ended up implementing a custom plugin that parses in "real" time by only parsing the file being transformed:
import MagicString from 'magic-string'
import micromatch from 'micromatch'
import path from 'node:path'
import {
withCustomConfig,
type ComponentDoc,
type FileParser
} from 'react-docgen-typescript'
import type { TransformResult } from 'rollup'
import dedent from 'ts-dedent'
import type { Plugin } from 'vite'
import { PLUGIN_NAME } from './constants'
import type Options from './options.interface'
/**
* Creates a `react-docgen-typescript` plugin.
*
* @see https://github.com/styleguidist/react-docgen-typescript
* @see https://vitejs.dev/guide/api-plugin.html
*
* @param {Options} [options] - Plugin options
* @return {Plugin} Vite `react-docgen-typescript` plugin
*/
const docgen = ({
apply,
componentNameResolver,
enforce = 'pre',
customComponentTypes = [],
exclude = ['**.stories.tsx'],
handler = doc => doc,
include = ['**.tsx'],
name = doc => doc.displayName,
propFilter = prop => !prop.parent?.fileName.includes('node_modules'),
savePropValueAsString = false,
shouldExtractLiteralValuesFromEnum = false,
shouldExtractValuesFromUnion = false,
shouldIncludeExpression = false,
shouldIncludePropTagMap = true,
shouldRemoveUndefinedFromOptional = true,
skipChildrenPropWithoutDoc = true,
tsconfigPath = path.resolve('tsconfig.json')
}: Options = {}): Plugin => {
/**
* Component docgen info parser.
*
* @see https://github.com/styleguidist/react-docgen-typescript#usage
*
* @const {FileParser} parser
*/
const parser: FileParser = withCustomConfig(tsconfigPath, {
componentNameResolver,
customComponentTypes,
propFilter,
savePropValueAsString,
shouldExtractLiteralValuesFromEnum,
shouldExtractValuesFromUnion,
shouldIncludeExpression,
shouldIncludePropTagMap,
shouldRemoveUndefinedFromOptional,
skipChildrenPropWithoutDoc
})
return {
apply,
enforce,
name: PLUGIN_NAME,
/**
* Parses component docgen info from `id`.
*
* The final transform result will include a new source map and updated
* version of `code` that includes a code block to attach a `__docgenInfo`
* property to the component exported from `id`.
*
* If `id` isn't explicity included via {@link include}, or is explicity
* excluded from transformation via {@link exclude}, `undefined` will be
* returned instead.
*
* @param {string} code - Source code
* @param {string} id - Module id
* @return {Exclude<TransformResult, string>} Transformation result
*/
transform(code: string, id: string): Exclude<TransformResult, string> {
// do nothing if file isn't explicity omitted
if (!micromatch.isMatch(id, include)) return
// do nothing if file is explicity omitted
if (micromatch.isMatch(id, exclude)) return
try {
/**
* Component docgen info.
*
* @see https://github.com/styleguidist/react-docgen-typescript/blob/v2.2.2/src/parser.ts#L16
*
* @var {ComponentDoc?} doc
*/
let doc: ComponentDoc | undefined = parser.parse(id).pop()
// bail if missing component docgen info
if (!doc) return null
/**
* {@link code} as `MagicString`.
*
* @see https://github.com/Rich-Harris/magic-string
*
* @const {MagicString} src
*/
const src: MagicString = new MagicString(code)
// apply additional transformations to component docgen info
doc = handler(doc, id, code)
/**
* Code block containing logic to attach a `__docgenInfo` property to
* the component found in {@link code}.
*
* @const {string} docgenblock
*/
const docgenblock: string = dedent`
try {
${name(doc, id, code)}.__docgenInfo=${JSON.stringify(doc)};
} catch (e) {
console.error('[${PLUGIN_NAME}]' + ' ' + e.message, e)
}
`
// add __docgenInfo code block to source code
src.append(docgenblock)
return {
code: src.toString(),
map: src.generateMap({ hires: true, source: id })
}
} catch (e: unknown) {
return void console.error(e instanceof Error ? e.message : e)
}
}
}
}
export default docgen
edit:
oops just realized you're using vue, sorry 😅! not sure what the vue equivalents are in storybook, but if they're somewhat similar, hopefully this is helpful! (leaving the snippet for react users who stumble across this issue)
@joshwooding this sleuthing might interest you ^.
Yeah what was discovered here is already a known issue. The ts program is created based on the current filesystem. The above approach works around that by creating a ts program every parse which is quite expensive.
@joshwooding do you have any links to issues or docs regarding this issue? i was searching for known issues surrounding this matter while i was debugging, but couldn't find any.
MDX ArgsTable is working for me on the 7.0.0 beta