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

Background addon not working #8575

Closed
abhilakshyadobhal opened this issue Oct 26, 2019 · 25 comments
Closed

Background addon not working #8575

abhilakshyadobhal opened this issue Oct 26, 2019 · 25 comments

Comments

@abhilakshyadobhal
Copy link

abhilakshyadobhal commented Oct 26, 2019

I have applied background addon to my storybook, it is showing those colors as option for selecting as background but on selecting it is not getting applied to my storybook.
My config.js looks like this

import { configure, addDecorator, addParameters } from '@storybook/react';
import BItheme from './theme';
import styles from "@sambego/storybook-styles";

addParameters({
  options: {
    theme: BItheme,
  },
  backgrounds: [
    { name: 'twitter', value: '#00aced'},
    { name: 'facebook', value: '#3b5998' },
  ],
});

addDecorator(styles({
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  height: 500,
}))

// automatically import all files ending in *.stories.js and tsx
configure(
  [
    require.context('../stories', true, /\.stories\.js$/),
    require.context('../src/components', true, /\.stories\.tsx$/)
  ],
  module
);
@from-nibly
Copy link

I am also seeing this issue. The problem seems to come from the fact that the body in the iframe has a background-color set to #fff If I remove that css value in developer tools the background addon starts working.

@abhilakshyadobhal
Copy link
Author

abhilakshyadobhal commented Oct 28, 2019

I also checked and found that it is because I was importing antd css in my components. But I couldn't find any solution. Is there any way that our component don't take body background property from that of antd.

@abhilakshyadobhal
Copy link
Author

Yes bro this is totally because of that iframe but I couldn't find from where that iframe is coming. If you will find please tell me also.

@from-nibly
Copy link

Oh sorry I think I miss-spoke. The iframe actually has the correct color. the body inside the iframe is overriding it for me. I believe, for me, it's because I am importing bootstrap and it is setting the background color and wont let the iframe's color change it.

@abhilakshyadobhal
Copy link
Author

For me it is because of antd as iframe also has a body tag so antd is setting background color of body of that ifram to #fff.

@stale
Copy link

stale bot commented Nov 20, 2019

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!

@stale stale bot added the inactive label Nov 20, 2019
@abhilakshyadobhal
Copy link
Author

Can anyone help?

@stale stale bot removed the inactive label Nov 22, 2019
@Marklb
Copy link
Member

Marklb commented Nov 24, 2019

I ran into this with the Grid tool, because I am using bootstrap with the background-color set on <body></body>, which was already mentioned. I use Angular, but I think its the same for the other iframe story previews. On the body there is a css class not used in my project .sb-show-main, so I just added body.sb-show-main { background-color: transparent; } to my css and it worked in storybook only.

To avoid putting a storybook specific rule in the app's css I then instead put the following in "preview-head.html".

<!-- .storybook/preview-head.html -->
<style>
  body.sb-show-main { background-color: transparent; }
</style>

I prefer the app's default background to be used, since some components don't have a background and aren't guaranteed to look right with what ever storybook theme background is set in the parent iframe when the background addon isn't being used. It is nice to have the option of turning the grid on for a sec or trying a few backgrounds sometimes though, so I took a quick look through the code to see if there was a way to hide the app's background only when either the Background or Grid tool is being used. So, if I turn off the grid, or unselect a background, I want it to go back to the app's background.

If you add code that has access to the api, then the addon does emit an event when the background selection is changed, but not when the grid is toggled. There is a state value for both, but I didn't see a simple way to observe the state value. To know initially before either tool is clicked I had to use a combination of the state and properties, since the state is only set after the tool is used.

The following small addon script isn't necessarily a good way to do this, but it seems to work without changing anything if needed until a good way to support this is decided. I don't have this in a published storybook, but it seems to work so far. This is the first time I have used the Storybook API and I rarely use React, so someone with more experience using them may know a better way to do the following, because I used a Panel component just to observe a state change and two events that sometime emit at the same time as the others causing the check to happen multiple times. Depending on the project the following may be trying to do to much and the current addon functionality is enough, instead of trying to sync the in-use state to a property on the body like I did.

// .storybook/background-addon-detectable.js

import React from 'react'
import { addons, types } from '@storybook/addons'
import { AddonPanel } from '@storybook/components'
import { STORY_RENDER } from '@storybook/core-events'

import { ADDON_ID as ADDON_BACKGROUNDS_ID, PARAM_KEY as ADDON_BACKGROUNDS_PARAM_KEY } from '@storybook/addon-backgrounds/dist/constants'

const ADDON_ID = 'background-addon-detectable'
const PANEL_ID = `${ADDON_ID}/panel`

function getStoryBody() {
  const iframe = document && document.querySelector('#storybook-preview-iframe')
  if (iframe && iframe.contentDocument) {
    return iframe.contentDocument.querySelector('body')
  }
  return null
}

function isBackgroundSelected(api) {
  const currentValue = api.getAddonState(ADDON_BACKGROUNDS_PARAM_KEY)

  if (currentValue === 'transparent') {
    return false
  }

  const backgrounds = api.getCurrentParameter(ADDON_BACKGROUNDS_PARAM_KEY) || []

  if (!backgrounds.length) {
    return false
  }

  if (backgrounds.find(i => i.value === currentValue)) {
    return true
  }

  if (!currentValue && backgrounds.find(i => i.default)) {
    return true
  }

  return false
}

function isGridActive(api) {
  return api.getAddonState(`${ADDON_BACKGROUNDS_ID}/grid`) || false
}

function updateBgStateAttrForCss(api) {
  const isBgGridActive = isGridActive(api)
  const isBgSelected = isBackgroundSelected(api)

  const storyBody = getStoryBody()
  if (storyBody) {
    storyBody.setAttribute('data-addon-background', isBgSelected || isBgGridActive)
  }
}

addons.register(ADDON_ID, api => {
  // React to a background change.
  //
  // The README shows how to listen to the event emitted when a background is changed.
  // Source: https://github.com/storybookjs/storybook/blob/next/addons/backgrounds/README.md#events
  api.getChannel().on('storybook/background/update', (bg) => {
    // console.log('Background color', bg.selected)
    // console.log('Background name', bg.name)
    updateBgStateAttrForCss(api)
  })

  // There may be a better event, because it would probably only need this event
  // when the iframe is initially loaded.
  api.on(STORY_RENDER, evt => {
    updateBgStateAttrForCss(api)
  })

  //
  // The following is a way that could detect a grid state change.
  //
  // NOTE: I do not consider this a good thing to do, since I am adding a panel
  // just to listen for an event. I don't have much experience with React, I
  // mainly use Angular, so I just know enough to get by when I need to use it.
  // Someone else may know a better way to do what I am using this render
  // function for.
  //
  const render = ({ active, key }) => {
    // state will be undefined until the tool button is clicked
    // const isBgGridActive = api.getAddonState(`${ADDON_BACKGROUNDS_ID}/grid`) || false
    // console.log('isBgGridActive', isBgGridActive)
    updateBgStateAttrForCss(api)

    return React.createElement(AddonPanel, { active, key })
  }

  // Empty string should make the button visually hidden, but it is still there.
  const title = '';

  addons.add(PANEL_ID, {
    type: types.PANEL,
    title,
    render
  })
})

@winterlamon
Copy link
Contributor

I was also having this issue because we import styles (which includes Bootstrap). BS sets background-color on body to white by default. To get around it, I added a stylesheet to Storybook in the .storybook directory (not with our main styles) and imported it into .storybook/config.js.

// .storybook/storybook.scss

.sb-show-main {
  background-color: transparent;
}
// .storybook/config.js

import './storybook.scss'

@stale
Copy link

stale bot commented Dec 23, 2019

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!

@stale stale bot added the inactive label Dec 23, 2019
@stale
Copy link

stale bot commented Jan 22, 2020

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

@stale stale bot closed this as completed Jan 22, 2020
@slashwhatever
Copy link

Note that while this may have been closed, this is still a bug and a breaking change from older versions of storybook.

Here's the content of my preview.js file:

import React from "react";
import { addDecorator, addParameters } from "@storybook/react";
import { withKnobs } from "@storybook/addon-knobs";
  
addParameters({
  backgrounds: [
    { name: "light", value: "#FFFFFF" },
    { name: "gray", value: "#eeeeee" },
    { name: "dark", value: "#505959", default: true }
  ]
});
   
addDecorator(story => {
  const content = story();
  return <div style={{ margin: "50px", height: "1000px" }}>{content}</div>;
});

What this should do is allow users to select the background color as a global setting across all of storybook.

What I'm seeing is that the background color is applied to the wrapper element outside the storybook preview iframe which means any styling you have in your theme could override that setting. Note that this is a change from previous versions of storybook backgrounds which would add the style to the element inside the preview iframe.

Example screenshots:

This is where the background styling is added: http://snpy.in/s4ASQJ
This is where your own styling can end up overriding that setting: http://snpy.in/S10n3d
This is where old versions of storybook would apply the background styling: http://snpy.in/VffzYh

@tugglecore
Copy link

Will a fix for this be coming soon? This is a problem that still exists today

@shilman
Copy link
Member

shilman commented May 1, 2020

@tugglecore would you like to contribute the fix?

@slashwhatever
Copy link

slashwhatever commented May 1, 2020

Will a fix for this be coming soon? This is a problem that still exists today

Quick fix (might work for you - definitely worked for me while I try to decipher a real fix):

Add a storybook.css file in your .storybook folder and give it this CSS rule:

.sb-show-main {
  background-color: transparent;
}

Obvs, you'll need to make sure that CSS file gets used so import it in your preview.js file:

import "./storybook.css";

@shilman
Copy link
Member

shilman commented May 2, 2020

Related? #10612

@shilman
Copy link
Member

shilman commented Sep 25, 2020

Ta-da!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.1.0-alpha.16 containing PR #12368 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

@hugotox
Copy link

hugotox commented Jun 30, 2021

This is still broken in version 6.3.1. And the workaround doesn't work anymore because now the .sh-show-main has an !important rule:
image

@hugotox
Copy link

hugotox commented Jun 30, 2021

Probably this line

background: ${selectedBackgroundColor} !important;

@hugotox
Copy link

hugotox commented Jun 30, 2021

Found the root cause for this @react-theming/storybook-addon breaks the background addon

@joelain
Copy link

joelain commented Jul 2, 2021

Existing background color on iframe body is not an issue for us. We are also not using @react-theming/storybook-addon. Still can't figure out why backgrounds are not working.

Notes on issue:

  • Background colors show in top icon bar (Added via preview.js or in the story directly works fine)
  • When a background color is selected the url changes to the selected color but nothing happens: http://localhost:4400/?path=/story/navitem--client&globals=backgrounds.value:!hex(cccccc)
  • Background is not applied.

@shilman
Copy link
Member

shilman commented Jul 2, 2021

@joelain do you have a repro?

@joelain
Copy link

joelain commented Jul 2, 2021

@shilman Not sure what you mean by repro. We have a repo for our project but its not something I can provide access to.

@shilman
Copy link
Member

shilman commented Jul 2, 2021

Can you please create a reproduction by running npx sb@next repro, following the instructions, and linking it in your issue description? We prioritize issues with reproductions over those without. Thank you! 🙏

@T04435
Copy link

T04435 commented Jul 29, 2021

Based on: #8575 (comment)

Only on change on the above the css priority by the issue would still take precedence so new here is the css to fix it.

body.sb-show-main {
  background: transparent !important;
}

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

10 participants