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

[T] Update Storybook to latest version "6.0.12" #512

Merged
merged 10 commits into from
Aug 25, 2020
Merged

[T] Update Storybook to latest version "6.0.12" #512

merged 10 commits into from
Aug 25, 2020

Conversation

kuroski
Copy link
Contributor

@kuroski kuroski commented Aug 19, 2020

This PR closes ticket FET-198

In this PR:

  • Update the project to the latest version of Storybook
  • All components that used the notes add-on are updated to use the Storybook docs
  • Convert some components with the newer syntax/add-ons for stories files
  • Here is the list of components that were changed:
    • HdAlert
    • HdBadge
    • HdButton
    • HdCalendar
    • HdEditSwitch
    • HdExpandText
    • HdGallery
    • HdIcon
    • HdLink
    • HdLoaderButton
    • HdResponsive
    • HdTimeslots
    • Welcome

New version

Changes and Deprecations

You can check deprecations and changes in this page

Here are some relevant points:

  • storiesOf method from @storybook/vue is still supported, but now Storybook recommends writing the files using Component Story Format (CSF)
    • Its nice to start converting our stories to CSF to avoid future deprecations and its easier to find documentation
  • Knobs are still supported, but we should avoid use them in prol of Controls
  • addon-notes is now in deprecation stage, we must use docs page
  • I've removed vue-cli-plugin-storybook to use the default configuration that comes originally with storybook
    • With that, you can also use MDX stories if you wish
    • You can change easily add-ons configuration e.g
    • We can remove this fork
    • We have the benefit of having a proper documentation if we need to configure something

Migrating to Component Story Format (CSF)

Let's use the HdBadge component as an example

Before

/* eslint-disable import/no-extraneous-dependencies */
import { storiesOf } from '@storybook/vue';
import { text, boolean, select } from '@storybook/addon-knobs';
import {
  HdBadge,
  HdBadgeTypes as TYPES,
} from 'homeday-blocks';

storiesOf('Components/HdBadge', module)
  .add('Playground without details', () => ({
    components: { HdBadge },
    props: {
      label: {
        type: String,
        default: text('Label', 'Badge'),
      },
      modifier: {
        type: String,
        default: select('Modifier', Object.values(TYPES), TYPES.default),
      },
      icon: {
        type: String,
        default: text('icon (url)'),
      },
      showIconBefore: {
        type: Boolean,
        default: boolean('show-icon-before', true),
      },
    },
    template: `
      <HdBadge
        :label=label
        :modifier=modifier
        :icon="icon"
        :show-icon-before="showIconBefore"
      />
    `,
  }))
  .add('Playground with details', () => ({
    components: { HdBadge },
    props: {
      label: {
        type: String,
        default: text('Label', 'Badge'),
      },
      details: {
        type: String,
        default: text('Details', 'test badge details!'),
      },
      modifier: {
        type: String,
        default: select('Modifier', Object.values(TYPES), TYPES.default),
      },
      icon: {
        type: String,
        default: text('icon (url)'),
      },
      showIconBefore: {
        type: Boolean,
        default: boolean('show-icon-before', true),
      },
    },
    template: `
      <HdBadge
        :label=label
        :modifier=modifier
        :icon="icon"
        :show-icon-before="showIconBefore"
      >
        <template>{{details}}</template>
      </HdBadge>
    `,
  }));

After

import {
  HdBadge,
  HdBadgeTypes as TYPES,
} from 'homeday-blocks';

export default {
  title: 'Components/HdBadge',
  component: HdBadge,
  decorators: [],
  argTypes: {
    modifier: {
      control: { type: 'select', options: Object.values(TYPES) },
      table: {
        defaultValue: { summary: TYPES.DEFAULT },
      },
    },
    details: {
      control: { type: 'text' },
      description: 'Details default slot of the badge',
    },
  },
  args: {
    label: 'Badge',
    modifier: TYPES.DEFAULT,
    icon: '',
    showIconBefore: true,
    details: null,
  },
  parameters: {
    docs: {
      source: {
        code: `
<HdBadge
  :label="label"
  :modifier="modifier"
  :icon="icon"
  :show-icon-before="showIconBefore"
>
  {{ details }}
</HdBadge>
        `,
      },
    },
  },
};

const Template = (args, { argTypes }) => ({
  props: Object.keys(argTypes),
  components: { HdBadge },
  template: `
    <HdBadge
      :label="label"
      :modifier="modifier"
      :icon="icon"
      :show-icon-before="showIconBefore"
    >
      <template v-if="details">{{ details }}</template>
    </HdBadge>
  `,
});

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

export const WithDetails = Template.bind({});
WithDetails.args = {
  details: 'test badge details!',
};
WithDefailt.parameters = {.....}

And here is the result:

Screenshot 2020-08-20 at 11 55 29

API

You can read in details through Storybook documentation, but I will highlight the most important concepts bellow.

Component Story Format (CSF)

Default export

The default export defines metadata about your component, including the component itself, its title (where it will show up in the navigation UI story hierarchy), decorators, and parameters.

The component field is optional (but encouraged!), and is used by addons for automatic prop table generation and display of other component metadata. title should be unique, i.e. not re-used across files.

// MyComponent.story.js

import MyComponent from './MyComponent';

export default {
  title: 'Path/To/MyComponent',
  component: MyComponent, // with that information, the component prop table is automatically generated
  decorators: [ ... ],
  parameters: { ... }
}

Named story exports

With CSF, every named export in the file represents a story function by default.

// MyComponent.story.js

import MyComponent from './MyComponent';

export default {
  title: 'Path/To/MyComponent',
  component: MyComponent,
  decorators: [ ... ],
  parameters: { ... }
}

export const Basic = (args, { argTypes }) => ({
  props: Object.keys(argTypes),
  components: { MyComponent },
  template: `
    <MyComponent />
  `,
});

We should follow this pattern because its a limitation for the Vue side.
Since the component props are automatically injected, we must pass through them to the named export component, otherwise the application will crash.

The name of the export will be converted into the story title, e.g:

export const MyBasic_Component = () => ({...})

Will be converted to My Basic Component

Also, the exported component can override the default configurations

export const Basic = () => ({...})
Basic.storyName = 'So simple!';
Basic.decorators = [ ... ];
Basic.parameters = { ... };
Basic.args = { ... };

Args story inputs

Starting in SB 6.0, stories accept named inputs called Args. Args are dynamic data that are provided (and possibly updated by) Storybook and its addons.

ArgTypes

ArgTypes are a first-class feature in Storybook for specifying the behaviour of Args. By specifying the type of an arg you constrain the values that it can take and can also provide information about args that are not explicitly set (i.e. not required).

You can also use argTypes to “annotate” args with information that is used by addons that make use of those args, for instance to instruct the controls addons to render a color choose for a string-valued arg.

Arg types are automatically generated, but you can customize any property of the component, in the end, we will have a Args table in the documentation

argstable

// MyComponent.story.js

import MyComponent from './MyComponent';

export default {
  title: 'Path/To/MyComponent',
  component: MyComponent,
  argTypes: {
    label: { // overriding the `label` prop
      name: 'label',
      type: { name: 'string', required: false },
      defaultValue: 'Hello',
      description: 'demo description',
      table: {
        type: { summary: 'string' },
        defaultValue: { summary: 'Hello' },
      }
      control: {
        type: 'text'
      }
    }
  }
}

Storybook uses behind the scenes vue-docgen-api to infer the props and events from the component.

The controls that will appear in the Args table can be changed to any of the options that you can find here

Result

You guys can check a DEMO here:
https://blocks-storybook-6.netlify.app/

PS

The commit 42a5cef can be reverted once we convert the component to the CSF format, since we can do this

@kuroski kuroski self-assigned this Aug 19, 2020
@kuroski kuroski changed the title [WIP] [T] Update Storybook to latest version "6.0.12" [T] Update Storybook to latest version "6.0.12" Aug 20, 2020
@kuroski kuroski marked this pull request as ready for review August 20, 2020 12:01
@@ -75,8 +77,8 @@
"node-fetch": "^2.6.0",
"node-sass": "4.13.1",
"raw-loader": "3.1.0",
"react-is": "^16.13.1",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason to add this dependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency is used to write MDX files.
https://storybook.js.org/docs/vue/writing-docs/mdx

If we don't intent to write MDX we can remove it =D
What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok! That feature looks pretty cool!
Maybe we could evaluate in a couple of months if we're using it or not?
If we are not using it, then remove it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, it works for me =D

@@ -1,96 +1,198 @@
/* eslint-disable import/no-extraneous-dependencies */
Copy link
Contributor

@metal-gogo metal-gogo Aug 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment still needed on all files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing out, we can't remove for the files that are still importing dev dependencies.

Screenshot 2020-08-21 at 15 47 12

But for sure, I've forgot to update the Button story and to remove the comment in some files =D
Here are the changes:

755364d

/* eslint-disable import/no-extraneous-dependencies */
import { storiesOf } from '@storybook/vue';
/* import { storiesOf } from '@storybook/vue';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a work in progress, right?
Make sure to remove these comments when you're finished hehe...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've forgot to remove them >_<

Here is the change:
755364d

Default.parameters = {
docs: {
description: {
component: HdResponsiveNote,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool!

Copy link
Contributor

@metal-gogo metal-gogo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks great! I added a comment to remove some commented lines.
Would you create a new ticket to rewrite the remaining stories to the new format?

Copy link
Contributor

@viniciuskneves viniciuskneves left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it and it seems fine. Reaaaaally appreciate the huge effort! I've dropped a comment regarding the HdButton stories.

I think you will need to update the Hygen scaffolding template for stories, right?
Another thing, have you tested Percy? Does it still work? Because we had the skip parameter for HdAlert, for example, and it is not there anymore. --> We can disable (skip) it for all stories for now and get back to it after, otherwise it might become a hell of a PR to review.

:disabled=disabled
@click="onClick"
>{{ text }}</HdButton>
<div v-if="isInDarkBackground" :style="styleDarkBackground" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we lost this guy in here which used to trick the dark background. @metal-gogo I think you can input here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right.
Actually, I thought that we could use the 'background' to simulate that, but its not that intuitive:

gif

I will update the component, 1 min

Copy link
Contributor Author

@kuroski kuroski Aug 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it is =D

6d0d076

You can also check in the demo URL

And sorry @metal-gogo I didn't noticed that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OMG, I didn't know about this background option. Can we make it enable it as soon as we select the "isInDarkBackground"? 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried it out, unfortunately we don't have access to addon methods during a Story render.

Maybe I'm wrong, but I didn't find out on how to do it 😅

@kuroski
Copy link
Contributor Author

kuroski commented Aug 21, 2020

@metal-gogo

It looks great! I added a comment to remove some commented lines.
Would you create a new ticket to rewrite the remaining stories to the new format?

Yes, this was a suggestions from @ilyasmez
I just changed the components that were using notes (because its deprecated) and I've also tried to change some other components as an example.

We can calmly migrate the format, we have time until the version 7.0 😆

@kuroski
Copy link
Contributor Author

kuroski commented Aug 21, 2020

@viniciuskneves

I tested it and it seems fine. Reaaaaally appreciate the huge effort! I've dropped a comment regarding the HdButton stories.

I think you will need to update the Hygen scaffolding template for stories, right?
Another thing, have you tested Percy? Does it still work? Because we had the skip parameter for HdAlert, for example, and it is not there anymore. --> We can disable (skip) it for all stories for now and get back to it after, otherwise it might become a hell of a PR to review.

Thanks man =D, and answering your questions:

  • Yeah, you are totally right, I forgot to include the changes in Hygen
  • Percy is supposed to work normally, because I didn't change the testing command, and there were no breaking changes during the version bump
  • We can disable Percy for now and check on it later, we can just change the PERCY_TOKEN or just remove the npm script in CI right?
  • I tried to maintain the same properties for all components, but this skip was in the Playground story, I remove it because you can now play with the component in the documentation tab
    • But I've double check it and I forgot to add the skip to one component: 7c95487

Screenshot 2020-08-21 at 16 06 42

If you think it's nice to maintain the Playground, I can definitely put it back.

  • Also, after merging the PR I know that we MUST update the https://homeday.zeroheight.com/ links (I know you didn't commented on that, but I know that we must do that)

Copy link
Contributor

@volcanioo volcanioo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What an achievement! 🎉 🎉 Generally, I like all features but especially ArgTypes feature is poetical. Stories are looking better now.
Also, thanks for your detailed explanation, I suggest writing a Medium Blog about it!

@kuroski kuroski added the enhancement New feature or request label Aug 24, 2020
@viniciuskneves
Copy link
Contributor

@kuroski the Percy thing was just a ping, I didn't test it myself.

I don't think we need the playground anymore. This new version of Storybook tackles things differently which is nice =]

Nevertheless, removing from CI/Token should be enough. If it is not causing any issues, just keep it the way it is.

Copy link
Contributor

@viniciuskneves viniciuskneves left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@kuroski kuroski merged commit 36ce924 into homeday-de:develop Aug 25, 2020
@kuroski kuroski deleted the task/migrate-storybook-to-v6 branch August 25, 2020 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants