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

Control boolean with default value in component is not initialized correctly (vue js component) #14149

Closed
BudHimself opened this issue Mar 5, 2021 · 12 comments

Comments

@BudHimself
Copy link

BudHimself commented Mar 5, 2021

Describe the bug
props in vue js component with default value to true and a story which have the props set to false in the template not init correctly the component in storybook.

To Reproduce
Steps to reproduce the behavior:
I do a component using vue js. This component have a props isPrimary with default value set to true. In the template of the story is set this props to false.

Additional info
If you set to false as default in the component and set to true the template in the story, the storybook behavior is correct.
We see the control set to true and the component display true.

Expected behavior
I expected to see the control set to false. And my component receive a props with false

Screenshots
bug

After toggling true/false storybook behavior is as expected.

Code snippets
The vue component:

<template>
  <div>isPrimary: {{ isPrimary }}</div>
</template>

<script>
export default {
  name: "test-boolean",
  props: {
    isPrimary: {
      type: Boolean,
      default: true,
    },
  },
}
</script>

The story:

import { Meta, Story, Canvas } from "@storybook/addon-docs/blocks"
import { TestBoolean } from "../../../components"

<Meta
  title="Components/Action/TestBoolean"
  component={TestBoolean}
  argTypes={{
    isPrimary: {
      control: "boolean"
    },
  }}
/>

export const Template = (args, { argTypes }) => ({
  props: Object.keys(argTypes),
  template: '<test-boolean :is-primary="isPrimary"/>',
})

<Canvas>
  <Story name="bug" args={{ isPrimary: false }}>
    {Template.bind({})}
  </Story>
</Canvas>

System

Environment Info:

  System:
    OS: macOS 11.2.1
    CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
  Binaries:
    Node: 12.20.0 - ~/.asdf/installs/nodejs/12.20.0/bin/node
    npm: 6.14.8 - ~/.asdf/installs/nodejs/12.20.0/bin/npm
  Browsers:
    Chrome: 88.0.4324.192
    Safari: 14.0.3
  npmPackages:
    @storybook/addon-backgrounds: ^6.1.17 => 6.1.17 
    @storybook/addon-docs: ^6.1.16 => 6.1.17 
    @storybook/addon-essentials: ^6.1.16 => 6.1.17 
    @storybook/addon-links: ^6.1.16 => 6.1.17 
    @storybook/theming: ^6.1.16 => 6.1.17 
    @storybook/vue: ^6.1.16 => 6.1.17 
@kbrilla
Copy link

kbrilla commented Mar 8, 2021

Not sure but it is very similar to #14147

@shilman
Copy link
Member

shilman commented Mar 22, 2021

Try upgrading to the latest prerelease:

npx sb@next upgrade --prerelease

Does that fix it?

@BudHimself
Copy link
Author

BudHimself commented Mar 22, 2021

Nope.

Did i miss something in my code ?

@f4irline
Copy link

f4irline commented Aug 17, 2021

I have the same issue with an Angular library project. This is happening with the current latest version as well as the prerelease version, installed via npx sb upgrade --prerelease.

Here's my button:

export class Button{
    @Input() text: string;
    @Input() disabled?: boolean;
    @Input() type: ButtonTypesEnum= ButtonTypesEnum.PRIMARY;
    @Output() clickEvent: EventEmitter<Event>;

    constructor() {
        this.clickEvent = new EventEmitter<Event>();
        this.text = 'Button';
    }

    click(): void {
        if (!this.disabled) {
            this.clickEvent.next();
        }
    }
}

Here's my Storybook story for it:

export default {
    component: Button,
    decorators: [
        moduleMetadata({
            declarations: [Button],
        })
    ],
    title: 'Shared/Buttons/Button',
    args: {
        text: 'Accept',
        type: ButtonTypesEnum.PRIMARY,
        disabled: false,
    },
    argTypes: {
        text: {
            name: 'Text',
            description: 'Text inside the button',
        },
        type: {
            options: [ButtonTypesEnum.PRIMARY, ButtonTypesEnum.WARN],
            name: 'Type',
            description: 'Choice between button types',
            control: {
                type: 'radio',
                labels: {
                    [ButtonTypesEnum.PRIMARY]: 'primary',
                    [ButtonTypesEnum.WARN]: 'warning',
                },
            }
        },
        disabled: {
            name: 'Disabled',
            description: 'Switches between enabled and disabled button',
        },
    },
} as Meta;

const Template: Story<Button> = args => ({
    props: args,
});

export const Primary = Template.bind({});

export const Disabled = Template.bind({});
Disabled.args = {
    disabled: true,
};

But still, when I open the "Disabled" state button story, the control has the state toggled on, but it's not reflected in the UI with the button item:

image

If I use the control to toggle the disabled state off and then back on, then it renders correctly with the disabled style. Here's what it looks after the toggling the disabled state first off and then on:

image

Curiously the type state works as it should, but it's defined with an enum and not a boolean. Here's how the UI initially looks like for the "Warning" story:

image

@Hypenate
Copy link

Hypenate commented Aug 30, 2021

I have the same issue with Angular:
image

My story (simplified)

declare type StoryArgs = CrudLayoutComponent & { content: string };

/** Extra button Story */
export const extraButtonsStory: Story<StoryArgs> = template.bind({});
extraButtonsStory.parameters = {
  docs: {
    description: {
      story: 'Shows how you can add/remove extra buttons to the component.',
    },
  },
};

extraButtonsStory.argTypes = {
  storyBookShowLeftTop: {
    defaultValue: true,
    control: {
      type: 'boolean',
    },
  },
};

extraButtonsStory.args = {
  content: `
  <ng-container buttons-left-top *ngIf="storyBookShowLeftTop">
      <button sg-outlined-button class="buttons-left-top"> Left top </button>
  </ng-container>
  `,
};

Cypress E2E (simplified)

    it.only('Should show extra buttons in the left top', () => {
      cy.visit(
        '/iframe.html?id=formcrudlayout--extra-buttons-story&args=storyBookShowRightTop:false;storyBookShowLeftBottom:false;storyBookShowRightBottom:false'
      );
    });

@shilman
Copy link
Member

shilman commented Aug 31, 2021

Does anybody have a reproduction they can share? See how to create a repro. We prioritize issues with reproductions over those without. Thank you! 🙏

@BudHimself
Copy link
Author

With my colleague we worked on this issue few days ago. Because we were living since 5 march with this probleme.

In our case, we try to set some attribute to true by default on our web-component. This is not standard.
HTML standard has some components with an attribute as boolean but always with a false default value, like checked on checkbox or selected on option.
So we decided to reverse the logic of our component. To have false by default.

This work pretty well.

In our case (the top first exemple of this page), the props is isPrimary on a button. So now the button is by default primary. And if we have the attribute secondary the button has secondary style.

So i don't know if it is a storybook probleme or an implementation probleme.

If it could help, enjoy :)

@Hypenate
Copy link

We fixed this by using args and argTypes

@shilman shilman removed this from the 6.4 improvements milestone May 20, 2022
@phoniks
Copy link

phoniks commented Aug 10, 2022

@Hypenate - more details on your solution, please? I'm having what I think is a similar issue. I have a button which I'd like to be able to see both the enabled and disabled states in one story. If I set args it works, but using the toggle in the controls panel doesn't seem to have the desired effect. If I log the value of the variable (in my actual Button component) then I see undefined which leads me to believe I'm missing a step in configuring my story, but I've gone through the docs a few times to no avail.

Editing to clarify: I can set the property to either true or false with args but the switch doesn't work in the control panel. No matter what I toggle that to, the component always has the value that was set in args.

@shilman shilman removed the P0 label Oct 18, 2022
@shilman shilman removed the tiny label Apr 24, 2023
@github-actions
Copy link
Contributor

Hi there! Thank you for opening this issue, but it has been marked as stale because we need more information to move forward. Could you please provide us with the requested reproduction or additional information that could help us better understand the problem? We'd love to resolve this issue, but we can't do it without your help!

@github-actions github-actions bot added the Stale label Sep 28, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Oct 6, 2023

I'm afraid we need to close this issue for now, since we can't take any action without the requested reproduction or additional information. But please don't hesitate to open a new issue if the problem persists – we're always happy to help. Thanks so much for your understanding.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Oct 6, 2023
@pmoleri
Copy link

pmoleri commented Nov 10, 2023

For anyone else looking for this info:

const meta = {
  component: Example,
  argTypes: {
    value: {
      // ❌ Deprecated
      defaultValue: 0,
    },
  },
  // ✅ Do this instead
  args: {
    value: 0,
  },
} satisfies Meta<typeof Example>;

src: https://storybook.js.org/docs/7.0/react/api/arg-types#defaultvalue

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

7 participants