storybook Web组件的argTypesMap器可以为内部/私有成员创建控件,

4urapxun  于 3个月前  发布在  其他
关注(0)|答案(1)|浏览(30)

描述问题

至少在使用 @custom-elements-manifest/analyzer 解释 stencil 组件的情况下:
members 数组记录了所有类成员,无论它们是暴露的属性/属性、内部方法还是其他方式。这行代码用 members 覆盖了 attribute 的 argTypes(错误地归类为 properties),这为组件中的每个字段和方法创建了控件,而不管字段上应用了哪些装饰器(即使是 "private",也包括在清单中,但在这里被忽略)。
这是那一行代码:
storybook/code/renderers/web-components/src/docs/custom-elements.ts
第 149 行 in ea70649
| | ...mapData(metaData.members,'properties'), |
请查看我在发送给 open-wc 的问题中描述的问题和图片: open-wc/custom-elements-manifest#187

重现

这个问题的重现步骤不起作用,因为 sb 需要应用于现有的模板项目。
当通过类似于以下方式将模板项目连接到 Storybook 的自定义元素清单时:

import { defineCustomElements } from '../dist/esm/loader';
import { setCustomElementsManifest } from '@storybook/web-components';
import manifest from '../custom-elements.json';

defineCustomElements();
setCustomElementsManifest(manifest)

并且自定义元素清单是由 @custom-elements-manifest/analyzer 生成的,我们会得到所有字段和函数(无论是私有的还是内部的),除了其他数组之外,都添加到了 members 数组中。最引人注目的是 attributes,其中包含带有 @Prop() 装饰器的暴露模板属性/属性。
Storybook 然后从 argTypes 创建 attributes,然后用 members 覆盖它们,其中包括 所有。然后我们就有了实现细节的控件和文档,这些不应该成为文档的一部分。
Storybook 本可以只从 attributesproperties 创建控件,但至少它应该查找 private 字段以省略这些内容。

附加上下文

找到了一个相关的 issue: #15436

p5fdfcr1

p5fdfcr11#

我通过过滤私有字段来解决这个问题。然而,为了避免故意将字段标记为 private ,我添加了一个额外的选项,该选项会添加 members 拥有而 attributes 没有的字段,然后删除 members

import { setCustomElementsManifest } from '@storybook/web-components';

export const setCustomElementsManifestWithOptions = (
    customElements: any,
    options: { privateFields?: boolean; mapMembersToAttributes?: boolean },
): void => {
    let { privateFields = true, mapMembersToAttributes } = options;
    if (!privateFields) {
        ...
    }
    if (!mapMembersToAttributes) {
        actOnDeclarations(customElements, declaration => {
            const attrs = declaration.attributes;
            const members = declaration.members;
            attrs.forEach((attr: { name: any; description: any }) => {
                const member = members.find(
                    (member: { name: any; description: any }) =>
                        member.name === attr.name,
                );
                Object.keys(member).forEach(key => {
                    attr[key] = attr[key] ?? member[key];
                });
            });
            delete declaration.members;
        });
    }
    return setCustomElementsManifest(customElements);
};

const actOnDeclarations = (
    customElements: any,
    declarationsFunction: (declaration: any) => void,
) => {
    customElements?.modules?.forEach((module: { declarations: any[] }) => {
        module?.declarations?.forEach(declarationsFunction);
    });
};

相关问题