Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web components argTypes mapper makes controls for internal/private members #19414

Open
nedredmond opened this issue Oct 10, 2022 · 1 comment

Comments

@nedredmond
Copy link

nedredmond commented Oct 10, 2022

Describe the bug
At least in the case of using @custom-elements-manifest/analyzer interpreting stencil components:

The members array documents all class members, whether they are exposed attributes/properties, internal methods, or otherwise. This line overwrites the attribute argTypes with members (categorized incorrectly(?) as properties), which creates controls for every field and method in the component, no matter what decorators are applied to the field (even "private", which is included in the manifest, is ignored here).

Here is the line:

...mapData(metaData.members, 'properties'),

See the problem description and images in the issue I sent to open-wc: open-wc/custom-elements-manifest#187

To Reproduce
The repro instructions don't work for this, because sb needs to be applied to an existing stencil project.
When connecting a stencil project to Storybook via a custom elements manifest like so:

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

defineCustomElements();
setCustomElementsManifest(manifest)

And the custom elements manifest is generated by @custom-elements-manifest/analyzer, we get all fields and functions, private/internal or not, added to the members array in addition to whatever other arrays apply-- most notably attributes, which is where exposed stencil attribute/properties (marked with @Prop() decorator) go.

Storybook then creates argTypes from attributes, then overwrites those with argTypes from members which includes everything. Then we have controls and docs for implementation details that are not exposed and should not be part of this documentation.

Storybook could just create controls from attributes and properties, but at the very least it should look for the private field to omit those from documentation.

Additional context
Found a related issue: #15436

@nedredmond
Copy link
Author

I kind of addressed this here by filtering out private fields.

However, to prevent having to deliberately mark fields as private, I added a second option that adds the fields that members have that attributes do not, then deletes 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);
    });
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant