diff --git a/addons/docs/src/frameworks/vue/sourceDecorator.test.ts b/addons/docs/src/frameworks/vue/sourceDecorator.test.ts
index b02569d9aa62..c4aa381a3a4c 100644
--- a/addons/docs/src/frameworks/vue/sourceDecorator.test.ts
+++ b/addons/docs/src/frameworks/vue/sourceDecorator.test.ts
@@ -30,6 +30,66 @@ describe('vnodeToString', () => {
).toMatchInlineSnapshot(``);
});
+ it('static class', () => {
+ expect(
+ vnodeToString(
+ getVNode({
+ template: ``,
+ })
+ )
+ ).toMatchInlineSnapshot(``);
+ });
+
+ it('string dynamic class', () => {
+ expect(
+ vnodeToString(
+ getVNode({
+ template: ``,
+ })
+ )
+ ).toMatchInlineSnapshot(``);
+ });
+
+ it('non-string dynamic class', () => {
+ expect(
+ vnodeToString(
+ getVNode({
+ template: ``,
+ })
+ )
+ ).toMatchInlineSnapshot(``);
+ });
+
+ it('array dynamic class', () => {
+ expect(
+ vnodeToString(
+ getVNode({
+ template: ``,
+ })
+ )
+ ).toMatchInlineSnapshot(``);
+ });
+
+ it('merge dynamic and static classes', () => {
+ expect(
+ vnodeToString(
+ getVNode({
+ template: ``,
+ })
+ )
+ ).toMatchInlineSnapshot(``);
+ });
+
+ it('object dynamic class', () => {
+ expect(
+ vnodeToString(
+ getVNode({
+ template: ``,
+ })
+ )
+ ).toMatchInlineSnapshot(``);
+ });
+
it('attributes', () => {
const MyComponent: ComponentOptions = {
props: ['propA', 'propB', 'propC', 'propD', 'propE', 'propF', 'propG'],
diff --git a/addons/docs/src/frameworks/vue/sourceDecorator.ts b/addons/docs/src/frameworks/vue/sourceDecorator.ts
index 04975f10420c..6178b60dc66f 100644
--- a/addons/docs/src/frameworks/vue/sourceDecorator.ts
+++ b/addons/docs/src/frameworks/vue/sourceDecorator.ts
@@ -76,6 +76,7 @@ export const sourceDecorator = (storyFn: any, context: StoryContext) => {
export function vnodeToString(vnode: Vue.VNode): string {
const attrString = [
...(vnode.data?.slot ? ([['slot', vnode.data.slot]] as [string, any][]) : []),
+ ['class', normalizeClassAttribute(vnode)],
...(vnode.componentOptions?.propsData ? Object.entries(vnode.componentOptions.propsData) : []),
...(vnode.data?.attrs ? Object.entries(vnode.data.attrs) : []),
]
@@ -122,6 +123,29 @@ export function vnodeToString(vnode: Vue.VNode): string {
.join('')}${tag}>`;
}
+function normalizeClassAttribute(vnode: Vue.VNode): string | undefined {
+ if (!vnode.data || (!vnode.data.staticClass && !vnode.data.class)) {
+ return undefined;
+ }
+
+ let dynamicClass: readonly string[] = [];
+
+ if (typeof vnode.data.class === 'string') {
+ dynamicClass = [vnode.data.class];
+ } else if (vnode.data.class instanceof Array) {
+ dynamicClass = vnode.data.class;
+ } else if (typeof vnode.data.class === 'object') {
+ dynamicClass = Object.entries(vnode.data.class)
+ .filter(([, active]) => !!active)
+ .map(([className]) => className);
+ }
+
+ return (
+ [...(vnode.data.staticClass?.split(' ') ?? []), ...dynamicClass].filter(Boolean).join(' ') ||
+ undefined
+ );
+}
+
function stringifyAttr(attrName: string, value?: any): string | null {
if (typeof value === 'undefined' || typeof value === 'function') {
return null;