diff --git a/code/addons/docs/docs/props-tables.md b/code/addons/docs/docs/props-tables.md index 5aeba6cbcd9b..b367c47c25ba 100644 --- a/code/addons/docs/docs/props-tables.md +++ b/code/addons/docs/docs/props-tables.md @@ -18,7 +18,7 @@ Storybook Docs automatically generates props tables for components in supported ## Usage -For framework-specific setup instructions, see the framework's README: [React](../react/README.md), [Vue3 ](../vue3/README.md), [Angular](../angular/README.md), [Web Components](../web-components/README.md), [Ember](../ember/README.md). +For framework-specific setup instructions, see the framework's README: [React](../react/README.md), [Vue3](../vue3/README.md), [Angular](../angular/README.md), [Web Components](../web-components/README.md), [Ember](../ember/README.md). ### DocsPage diff --git a/code/renderers/vue3/src/docs/sourceDecorator.test.ts b/code/renderers/vue3/src/docs/sourceDecorator.test.ts index 1cd1ee9a2e0f..f0a926b0a1ec 100644 --- a/code/renderers/vue3/src/docs/sourceDecorator.test.ts +++ b/code/renderers/vue3/src/docs/sourceDecorator.test.ts @@ -152,16 +152,20 @@ test('should generate source code for slots with bindings', () => { type TestBindings = { foo: string; bar?: number; + boo: { + mimeType: string; + }; }; const slots = { - a: ({ foo, bar }: TestBindings) => `Slot with bindings ${foo} and ${bar}`, - b: ({ foo }: TestBindings) => h('a', { href: foo, target: foo }, `Test link: ${foo}`), + a: ({ foo, bar, boo }: TestBindings) => `Slot with bindings ${foo}, ${bar} and ${boo.mimeType}`, + b: ({ foo, boo }: TestBindings) => + h('a', { href: foo, target: foo, type: boo.mimeType, ...boo }, `Test link: ${foo}`), }; - const expectedCode = ` + const expectedCode = ` -`; +`; const actualCode = generateSlotSourceCode(slots, Object.keys(slots), { imports: {}, diff --git a/code/renderers/vue3/src/docs/sourceDecorator.ts b/code/renderers/vue3/src/docs/sourceDecorator.ts index cc2f922f63f1..c3265394ea9c 100644 --- a/code/renderers/vue3/src/docs/sourceDecorator.ts +++ b/code/renderers/vue3/src/docs/sourceDecorator.ts @@ -26,6 +26,20 @@ export type SourceCodeGeneratorContext = { imports: Record>; }; +/** + * Used to get the tracking data from the proxy. A symbol is unique, so when using it as a key it + * can't be accidentally accessed. + */ +const TRACKING_SYMBOL = Symbol('DEEP_ACCESS_SYMBOL'); + +type TrackingProxy = { + [TRACKING_SYMBOL]: true; + toString: () => string; +}; + +const isProxy = (obj: unknown): obj is TrackingProxy => + !!(obj && typeof obj === 'object' && TRACKING_SYMBOL in obj); + /** Decorator to generate Vue source code for stories. */ export const sourceDecorator: Decorator = (storyFn, ctx) => { const story = storyFn(); @@ -226,6 +240,10 @@ export const generatePropsSourceCode = ( return; } // do not render undefined/null values // do not render undefined/null values + if (isProxy(value)) { + value = value.toString(); + } + switch (typeof value) { case 'string': if (value === '') { @@ -269,7 +287,7 @@ export const generatePropsSourceCode = ( case 'object': { properties.push({ name: propName, - value: formatObject(value), + value: formatObject(value ?? {}), // to follow Vue best practices, complex values like object and arrays are // usually placed inside the