UX-and-I / storybook-design-token

Display design token documentation generated from your stylesheets and icon files. Preview design token changes in the browser. Add your design tokens to your Storybook Docs pages using the custom Doc Blocks.
https://dev.to/psqrrl/managing-design-tokens-using-storybook-5975
MIT License
647 stars 123 forks source link

storybook fails with addon #37

Closed cherylcarpenter closed 2 years ago

cherylcarpenter commented 3 years ago

I'm running storybook 6.2.17 with a view project. Just adding this as an add-on in main.js, i get the following error on starting storybook. ERR! TypeError: Cannot read property 'options' of undefined

Sqrrl commented 3 years ago

Hi. Did you set the designToken parameter in your preview.js as described here? https://github.com/UX-and-I/storybook-design-token#configure-for-storybook-53-and-later

lmeijdam commented 3 years ago

I have also bumped into this same issue while using Cypress. Most of the tests fail now with the following error; CypressError: Timed out retrying after 4050ms: cy.click() failed because this element is detached from the DOM. This happens next to the ;ERR! TypeError: Cannot read property 'options' of undefined;. Might be linked to each other

cherylcarpenter commented 3 years ago

Hi. Did you set the designToken parameter in your preview.js as described here? https://github.com/UX-and-I/storybook-design-token#configure-for-storybook-53-and-later

Hi, I can copy-paste your suggestion into my preview but I don't really get what it wants as a config. That is a very large block of code when i just want to show tokens from my scss. A little more info would be appreciated. I assume the 'filename' is a variable but which file will make this work? my index.scss? my _variables.scss? my tokens.scss file?

cherylcarpenter commented 3 years ago

More info: I'm using storybook in a vue application. I'm thinking your plugin only works with React. I've tried adding @storybook/react but there are still many errors.

I've downloaded your code and tried running your Demos, and they also have unresolved paths. Overall this has cost me a lot of time and we are abandoning this leg of our workflow.

Sqrrl commented 3 years ago

Sorry, to hear that. The addon should work regardless of the framework you are using. Installing React should not be necessary at all. The demo gets deployed to Netlify after every change to the library, which seems to work fine. That lets me believe that there might be something in your project setup causing a problem. I would gladly assist but need a way to reproduce the issues you are having.

Regarding the documentation: I'll try to to add a few more words describing the necessary configuration and what it does when I find the time.

michelepatrassi commented 3 years ago

@Sqrrl I'm facing the same problem with Angular, but as you mentioned the issue is in the project itself. I created a new angular app, installed storybook and your addon and everything seems to work fine.

I'm doing some debugging in the project where is does not work. It looks like the story does not get the designToken parameter (storyData.parameters.designToken is undefined, but storyData.parameters contains other values) image.

I also noticed these two errors in the console

inferActionsFromArgTypesRegex was not supported :( !
addActionsFromArgTypes was not supported :( !

They started to appear after adding the addon. I'll keep debugging to understand what differs between the projects.

Anyway, thanks for the addon and your work!

Sqrrl commented 3 years ago

Hey @michelepatrassi,

Are you using an alpha release of Storybook 6.2? I get the "not supported" errors with version 6.2.0-alpha.29 without having the design token addon installed. So I'm assuming they are unrelated to the addon.

Anyway, thanks for your input. The designToken parameter should definitely not be undefined. Would be great if you'd find a minimal setup to reproduce the error. What is your preview.js looking like?

michelepatrassi commented 3 years ago

@Sqrrl Thanks for the input! Actually I was but I decided to go back to ^6.1.20. Your comment actually triggered me to remove and reinstall the node_modules and now I don't get the "Cannot read property 'options' of undefined" anymore, so I suspect that something was wrong in the node_modules at this point. @cherylcarpenter Can you give this solution a try with the latest stable version of storybook?

My preview.js and head.js are pretty basic, I created a folder called "foo" to test it out (contains default storybook stories and same CSS you have in the README inside my project)

main.js

module.exports = {
  "stories": [
    "../foo/**/*.stories.mdx",
    "../foo/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "storybook-design-token"
  ]
}

preview.js


import { setCompodocJson } from "@storybook/addon-docs/angular";
import docJson from "../documentation.json";
import { addParameters } from '@storybook/angular';

setCompodocJson(docJson);

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
}

const cssReq = require.context('!!raw-loader!../foo', true, /.\.css$/);
const cssTokenFiles = cssReq
  .keys()
  .map((filename) => ({ filename, content: cssReq(filename).default }));

const scssReq = require.context('!!raw-loader!../foo', true, /.\.scss$/);
const scssTokenFiles = scssReq
  .keys()
  .map((filename) => ({ filename, content: scssReq(filename).default }));

const lessReq = require.context('!!raw-loader!../foo', true, /.\.less$/);
const lessTokenFiles = lessReq
  .keys()
  .map((filename) => ({ filename, content: lessReq(filename).default }));

const svgIconsReq = require.context('!!raw-loader!../foo', true, /.\.svg$/);
const svgIconTokenFiles = svgIconsReq
  .keys()
  .map((filename) => ({ filename, content: svgIconsReq(filename).default }));

addParameters({
  designToken: {
    files: {
      css: cssTokenFiles,
      scss: scssTokenFiles,
      less: lessTokenFiles,
      svgIcons: svgIconTokenFiles
    },
    options: {
      hideMatchingHardCodedValues: false
    }
  }
});

So looks good so far! Only two things:

I'm able to reproduce the first on an empty project but not the second (just on my private repo), so I'll may create an issue if I can reproduce it

Sqrrl commented 3 years ago
  • I'm working with CSS variables, and I noticed that they are injected in the HTML only after they are edited. So if I set the border-radius of a button via var(--border-radius) it will be applied only after I edit it in the token panel. Is this by design?

That is intentional. The addon assumes that your variables default values are already applied globally. When you change a value it just calls style.setProperty() to overwrite the default value.

  • when I go to the design token panel I have an error in the console

I will check that out.

cherylcarpenter commented 3 years ago

Sorry, to hear that. The addon should work regardless of the framework you are using. Installing React should not be necessary at all. The demo gets deployed to Netlify after every change to the library, which seems to work fine. That lets me believe that there might be something in your project setup causing a problem. I would gladly assist but need a way to reproduce the issues you are having.

Regarding the documentation: I'll try to to add a few more words describing the necessary configuration and what it does when I find the time.

Hi, I tried again with a basic setup, exactly like this tutorial https://github.com/chromaui/learnstorybook-code/tree/vue

The code runs just fine. I add the plugin, but am still unclear on the paths, since storybook finds import '../src/index.css but with the plugin i get Module not found: Error: Can't resolve '../src/index.css' in '/Users/foo/Documents/GitHub/learnstorybook-code/.storybook'

so I'm still unclear what file the css raw loader needs to load. Does it want just a file of tokens? Can i link to my whole stack of css and it finds the tokens? Here is my preview file, from the base repo i mention above( `import '../src/index.css'

export const parameters = { actions: { argTypesRegex: "^on[A-Z].*" }, }

const cssReq = require.context('!!raw-loader!../src/index.css', true, /..css$/); const cssTokenFiles = cssReq .keys() .map((filename) => ({ filename, content: cssReq(filename).default }));

// const scssReq = require.context('!!raw-loader!../foo', true, /..scss$/); // const scssTokenFiles = scssReq // .keys() // .map((filename) => ({ filename, content: scssReq(filename).default }));

// const lessReq = require.context('!!raw-loader!../foo', true, /..less$/); // const lessTokenFiles = lessReq // .keys() // .map((filename) => ({ filename, content: lessReq(filename).default }));

// const svgIconsReq = require.context('!!raw-loader!../foo', true, /..svg$/); // const svgIconTokenFiles = svgIconsReq // .keys() // .map((filename) => ({ filename, content: svgIconsReq(filename).default }));

addParameters({ designToken: { files: { css: cssTokenFiles, // scss: scssTokenFiles, // less: lessTokenFiles, // svgIcons: svgIconTokenFiles }, options: { hideMatchingHardCodedValues: false } } });`

Sqrrl commented 3 years ago

const cssReq = require.context('!!raw-loader!../src/index.css', true, /..css$/);

The first parameter of require.context should specify the directory path of your token files, relative to the .storybook directory. In your case '!!raw-loader!../src' should be the correct path. The third parameter should be a regular expression matching your token files. To only match files with the .css extension, you should change your expression to /.\.css$/.

So I think your cssReq declaration should look like const cssReq = require.context('!!raw-loader!../src', true, /.\.css$/);.

I'll try to come up with a more detailed explanation for the docs.

cherylcarpenter commented 3 years ago

const cssReq = require.context('!!raw-loader!../src/index.css', true, /..css$/);

The first parameter of require.context should specify the directory path of your token files, relative to the .storybook directory. In your case '!!raw-loader!../src' should be the correct path. The third parameter should be a regular expression matching your token files. To only match files with the .css extension, you should change your expression to /.\.css$/.

So I think your cssReq declaration should look like const cssReq = require.context('!!raw-loader!../src', true, /.\.css$/);.

I'll try to come up with a more detailed explanation for the docs.

This seemed to help, and thank you for the explanation. Sorry, the intention was not clear to me :) Now I'm getting the following image

Sqrrl commented 3 years ago

That's tough to debug from the screenshot alone. What does your token files look like? Any chance your code is open source?

cherylcarpenter commented 3 years ago

That's tough to debug from the screenshot alone. What does your token files look like? Any chance your code is open source?

It is not open-source. That said, the ../src folder we looped in from the previous conversation is a folder of many scss files from a commercial bootstrap theme. So there is not one token file. My expectation was since we are pointing to a folder and not a file, that this plugin would just find them. So is there some way I need to mark them up for the plugin to do its thing? Pointing to a folder of many scss files does not seem efficient.

Sqrrl commented 3 years ago

The plugin will parse all files matched by your config. According to your example from above, you seem to be only loading .css files, not .scss files.

Further, for the addon to know which variables to display as tokens, the token files need to be annotated as described here: https://github.com/UX-and-I/storybook-design-token#usage

cherylcarpenter commented 3 years ago

Sorry I was dealing with two different examples in this overall discussion. I've tried scss and css files. The usage link is helpful for understanding that the plugin is looking for specific documentation, not sure how I missed that.

That said, now I'm back to storybook error: Module not found: Error: Can't resolve '@storybook/react' in '/.storybook' Overall I'm still debugging storybook versions and plugin versions in my stack. Sorry, I'm sure supporting rookies is the worst. I've also been playing with a .nuxt-storybook stack, which also does not work with this plugin. I will download your repo and try the examples again. I'd like to see one working version to even show my team if it is worth the time. We are also investing Invision/DSM tools for design tokens.

cherylcarpenter commented 3 years ago

Hi- for any that follow I try to be a good citizen. I have the plugin working in a basic Vue application with "@storybook/react": "^6.1.21", "@storybook/vue": "^6.1.21",

So.. some package in my current project is not playing nice. If I can narrow that down I will report in a new thread. Thank you! I'm a frontend dev and really want to get this working for our team!

frenchki commented 3 years ago

@cherylcarpenter @Sqrrl Any update on this issue? I am having the same issue with it not working correctly with the latest version of storybook (6.2.9) and storybook-design-token (1.0.2)

Sqrrl commented 2 years ago

Hey, this issue has been inactive for a while. Please re-open if you've still got issues with a recent version of the addon.