From 9eb6bf5ad54e4310180311880295d44e5fbb9657 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Sun, 13 Sep 2020 16:01:25 +0200 Subject: [PATCH] fix(backgrounds): apply styles in correct order - Make background also work with gradients and images --- .../src/decorators/withBackground.ts | 10 ++++-- addons/backgrounds/src/decorators/withGrid.ts | 9 ++--- addons/backgrounds/src/helpers/index.ts | 27 ++++++++++++--- addons/backgrounds/src/typings.d.ts | 1 + .../stories/addon-backgrounds.stories.js | 33 +++++++++++++++++++ 5 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 addons/backgrounds/src/typings.d.ts diff --git a/addons/backgrounds/src/decorators/withBackground.ts b/addons/backgrounds/src/decorators/withBackground.ts index 34c24cbb6ed1..defad6f99c71 100644 --- a/addons/backgrounds/src/decorators/withBackground.ts +++ b/addons/backgrounds/src/decorators/withBackground.ts @@ -1,7 +1,7 @@ import { StoryFn as StoryFunction, StoryContext, useMemo, useEffect } from '@storybook/addons'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; -import { clearStyles, addStyles, getBackgroundColorByName } from '../helpers'; +import { clearStyles, addBackgroundStyle, getBackgroundColorByName } from '../helpers'; export const withBackground = (StoryFn: StoryFunction, context: StoryContext) => { const { globals, parameters } = context; @@ -31,7 +31,7 @@ export const withBackground = (StoryFn: StoryFunction, context: StoryContext) => const backgroundStyles = useMemo(() => { return ` ${selector} { - background-color: ${selectedBackgroundColor} !important; + background: ${selectedBackgroundColor} !important; transition: background-color 0.3s; } `; @@ -48,7 +48,11 @@ export const withBackground = (StoryFn: StoryFunction, context: StoryContext) => return; } - addStyles(selectorId, backgroundStyles); + addBackgroundStyle( + selectorId, + backgroundStyles, + context.viewMode === 'docs' ? context.id : null + ); }, [isActive, backgroundStyles, context]); return StoryFn(); diff --git a/addons/backgrounds/src/decorators/withGrid.ts b/addons/backgrounds/src/decorators/withGrid.ts index d2cbb868f9c8..0252c57f6a49 100644 --- a/addons/backgrounds/src/decorators/withGrid.ts +++ b/addons/backgrounds/src/decorators/withGrid.ts @@ -2,7 +2,7 @@ import dedent from 'ts-dedent'; import deprecate from 'util-deprecate'; import { StoryFn as StoryFunction, StoryContext, useMemo, useEffect } from '@storybook/addons'; -import { clearStyles, addStyles } from '../helpers'; +import { clearStyles, addGridStyle } from '../helpers'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; const deprecatedCellSizeWarning = deprecate( @@ -20,6 +20,7 @@ export const withGrid = (StoryFn: StoryFunction, context: StoryContext) => { const gridParameters = parameters[BACKGROUNDS_PARAM_KEY].grid; const isActive = globals[BACKGROUNDS_PARAM_KEY]?.grid === true && gridParameters.disable !== true; const { cellAmount, cellSize, opacity } = gridParameters; + const isInDocs = context.viewMode === 'docs'; let gridSize: number; if (parameters.grid?.cellSize) { @@ -32,8 +33,8 @@ export const withGrid = (StoryFn: StoryFunction, context: StoryContext) => { const isLayoutPadded = parameters.layout === undefined || parameters.layout === 'padded'; // 16px offset in the grid to account for padded layout const defaultOffset = isLayoutPadded ? 16 : 0; - const offsetX = gridParameters.offsetX || defaultOffset; - const offsetY = gridParameters.offsetY || defaultOffset; + const offsetX = gridParameters.offsetX || isInDocs ? 20 : defaultOffset; + const offsetY = gridParameters.offsetY || isInDocs ? 20 : defaultOffset; const gridStyles = useMemo(() => { const selector = @@ -71,7 +72,7 @@ export const withGrid = (StoryFn: StoryFunction, context: StoryContext) => { return; } - addStyles(selectorId, gridStyles); + addGridStyle(selectorId, gridStyles); }, [isActive, gridStyles, context]); return StoryFn(); diff --git a/addons/backgrounds/src/helpers/index.ts b/addons/backgrounds/src/helpers/index.ts index 21a36f7590d1..6fead3837610 100644 --- a/addons/backgrounds/src/helpers/index.ts +++ b/addons/backgrounds/src/helpers/index.ts @@ -49,12 +49,21 @@ const clearStyle = (selector: string) => { } }; -export const addStyles = (selector: string | string[], css: string) => { - const selectors = Array.isArray(selector) ? selector : [selector]; - selectors.forEach((selec: string) => addStyle(selec, css)); +export const addGridStyle = (selector: string, css: string) => { + const existingStyle = document.getElementById(selector) as HTMLElement; + if (existingStyle) { + if (existingStyle.innerHTML !== css) { + existingStyle.innerHTML = css; + } + } else { + const style = document.createElement('style') as HTMLElement; + style.setAttribute('id', selector); + style.innerHTML = css; + document.head.appendChild(style); + } }; -export const addStyle = (selector: string, css: string) => { +export const addBackgroundStyle = (selector: string, css: string, storyId: string) => { const existingStyle = document.getElementById(selector) as HTMLElement; if (existingStyle) { if (existingStyle.innerHTML !== css) { @@ -64,6 +73,14 @@ export const addStyle = (selector: string, css: string) => { const style = document.createElement('style') as HTMLElement; style.setAttribute('id', selector); style.innerHTML = css; - document.head.appendChild(style); + + const gridStyleSelector = `addon-backgrounds-grid${storyId ? `-docs-${storyId}` : ''}`; + // If grids already exist, we want to add the style tag BEFORE it so the background doesn't override grid + const existingGridStyle = document.getElementById(gridStyleSelector) as HTMLElement; + if (existingGridStyle) { + existingGridStyle.parentElement.insertBefore(style, existingGridStyle); + } else { + document.head.appendChild(style); + } } }; diff --git a/addons/backgrounds/src/typings.d.ts b/addons/backgrounds/src/typings.d.ts new file mode 100644 index 000000000000..2f4eb9cf4fd9 --- /dev/null +++ b/addons/backgrounds/src/typings.d.ts @@ -0,0 +1 @@ +declare module 'global'; diff --git a/examples/official-storybook/stories/addon-backgrounds.stories.js b/examples/official-storybook/stories/addon-backgrounds.stories.js index 422e958feb39..3ad15dc5a00b 100644 --- a/examples/official-storybook/stories/addon-backgrounds.stories.js +++ b/examples/official-storybook/stories/addon-backgrounds.stories.js @@ -44,6 +44,39 @@ Overridden.parameters = { }, }; +export const WithGradient = Template.bind({}); +WithGradient.args = { + label: 'This one should have a nice gradient', +}; +WithGradient.parameters = { + backgrounds: { + default: 'gradient', + values: [ + { + name: 'gradient', + value: + 'linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)', + }, + ], + }, +}; + +export const WithImage = Template.bind({}); +WithImage.args = { + label: 'This one should have an image background', +}; +WithImage.parameters = { + backgrounds: { + default: 'space', + values: [ + { + name: 'space', + value: 'url(https://cdn.pixabay.com/photo/2017/08/30/01/05/milky-way-2695569_960_720.jpg)', + }, + ], + }, +}; + export const DisabledBackgrounds = Template.bind({}); DisabledBackgrounds.args = { label: 'This one should not use backgrounds',