Storybook: Addon-controls: configuring argTypes globally on preview.js

Created on 27 Jul 2020  路  8Comments  路  Source: storybookjs/storybook

Would be nice to have a way to configure some controls globally.

Example: imagine that all components contain one prop called ComponentId and we don't want this to be showing in the controls table.

How we do now:

On each component.stories.tsx you have to configure it manually within the default export:

export default {
  argTypes: { ComponentId: { table: { disabled: true } }
}

Proposal

Add this as configuration inside the preview.js

_preview.js_

export const argTypes: { ComponentId: { table: { disabled: true } }

And then it will be applied for all stories.

P2 controls feature request help wanted

Most helpful comment

i was missing step 4. Thanks! I will try to work on this in the coming weekend!

All 8 comments

To add another use-case:

I showcase different themes for my components (the third party themes addon doesn't work in my case, because of how the classes are applied vs how I need them, and I'd prefer users be able to tinker with components all in one place). The theming is done as a value passed in via a property, which I've set controls up to display the arg as an enum (because only certain values will work).

This arg is the same across all components and will contain the same selection options. The ideal way to set this up would be a global setting that provides that information without needing to add it to every single component.

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

I'm happy to help someone get a PR over the line adding this.

Hey! I'd love to try and tackle this.
If i understood the API correctly, we don't really need to change a lot, something like this should do:

--- a/addons/controls/src/components/ControlsPanel.tsx
+++ b/addons/controls/src/components/ControlsPanel.tsx
@@ -1,30 +1,45 @@
 import React, { FC } from 'react';
 import { ArgsTable, NoControlsWarning } from '@storybook/components';
-import { useArgs, useArgTypes, useParameter } from '@storybook/api';
+import { ArgTypes, useArgs, useArgTypes, useParameter } from '@storybook/api';

 import { PARAM_KEY } from '../constants';

 interface ControlsParameters {
   expanded?: boolean;
   hideNoControlsWarning?: boolean;
+  argTypes?: ArgTypes;
 }

 export const ControlsPanel: FC = () => {
   const [args, updateArgs, resetArgs] = useArgs();
   const rows = useArgTypes();
   const isArgsStory = useParameter<boolean>('__isArgsStory', false);
-  const { expanded, hideNoControlsWarning = false } = useParameter<ControlsParameters>(
+  const { expanded, hideNoControlsWarning = false, argTypes } = useParameter<ControlsParameters>(
     PARAM_KEY,
     {}
   );
   const hasControls = Object.values(rows).filter((argType) => !!argType?.control).length > 0;
+
+  const rowsWithDefaults = Object
+    .entries(rows)
+    .reduce((sum , [key, value]) => {
+      const defaultControls = argTypes[key] ?? {};
+      return {
+        ...sum,
+        [key]: {
+          ...defaultControls,
+          ...value
+        }
+      }
+    }, {} as ArgTypes);
+
   return (
     <>
       {(hasControls && isArgsStory) || hideNoControlsWarning ? null : <NoControlsWarning />}
       <ArgsTable
         {...{
           compact: !expanded && hasControls,
-          rows,
+          rows: rowsWithDefaults,
           args,
           updateArgs,
           resetArgs,

however, I'm a bit lost on how to test / experiment with this? Is there any guide i missed?

Hi @PupoSDC -- I'm not quite sure what that snippet does but that's not what I had in mind. I was thinking we'd add a concept of "global" args/argTypes, similar to global parameters and decorators. We would wire it up so it made its way from the .storybook/preview file into the StoryStore and then from there it should all just work automatically.

So basically we'd need to add:

  1. Support for a args and argTypes export key in preview (this is done via a virtual module entry here: https://github.com/storybookjs/storybook/blob/next/lib/core/src/server/preview/virtualModuleEntry.template.js)

  2. Add a addArgs and addArgTypes export to @storybook/client-api, via ClientApi.js, which ultimately calls into story_store.js. All of this would be very similar to how parameters, decorators etc are handled.

  3. ClientApi would ultimately just put args and argTypes into parameters (this is what we do at the story level too: https://github.com/storybookjs/storybook/blob/be5ed5094c7be39d36e40053437713ebb4fe4e95/lib/core/src/client/preview/loadCsf.ts#L141-L142 / https://github.com/storybookjs/storybook/blob/be5ed5094c7be39d36e40053437713ebb4fe4e95/lib/core/src/client/preview/loadCsf.ts#L190-L191)

    1. At this point it would all "just" work due to parameters inheritance. The one thing we'd need to think about would be how to do denormalized argtype enhancers (cc @shilman) but we haven't actually merged that PR yet: https://github.com/storybookjs/storybook/pull/11097

Thank you for the extra information!

This is my first time contributing here, so im not fully aware of the ecosystem.

My idea, would have the argTypes as part of the parameters export`. But your strategy seems more sound.

Im just a bit lost, on how to test / develop this. is there any "development environment" i can quickly set up?

Also, is it worth it for me to pick this up? Or is it already a WIP?

My idea, would have the argTypes as part of the parameters export`. But your strategy seems more sound.

This would be a simple way to prototype it for sure! We wouldn't want to leave them there long term as we'd reserve the right to use a different mechanism to store arg[Types] but it would be a simple way to try it out.

I think right now we have a warning/error if you try and put them in there so a start could just be to drop the warning and try it out in some stories in official storybook.

The instructions are here but my TLDR is:

  1. Checkout the next branch of the monorepo

  2. Run yarn and yarn bootstrap --core

  3. Run yarn build --watch core client-api api [you might need more packages than this but that'll get you started]

  4. In another terminal inside examples/official-storybook run yarn storybook.

Then I would add some more stories to the official storybook that use global args/arg types and see what happens.

Also, is it worth it for me to pick this up? Or is it already a WIP?

Nope (not a WIP)!

i was missing step 4. Thanks! I will try to work on this in the coming weekend!

Was this page helpful?
0 / 5 - 0 ratings