diff --git a/CHANGELOG.md b/CHANGELOG.md index 45f6084936..19d913f989 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Fixes +- Fix `Provider` is not executing staticStyles with the merged siteVariables @mnajdova ([#559](https://github.com/stardust-ui/react/pull/559)) + ### Features - `Ref` components uses `forwardRef` API by default @layershifter ([#491](https://github.com/stardust-ui/react/pull/491)) diff --git a/src/components/Provider/Provider.tsx b/src/components/Provider/Provider.tsx index 50ee52d236..8d92333e3b 100644 --- a/src/components/Provider/Provider.tsx +++ b/src/components/Provider/Provider.tsx @@ -23,7 +23,9 @@ export interface ProviderProps { /** * The Provider passes the CSS in JS renderer and theme to your components. */ -class Provider extends React.Component { +class Provider extends React.Component { + staticStylesRendered: boolean = false + static propTypes = { theme: PropTypes.shape({ siteVariables: PropTypes.object, @@ -54,13 +56,14 @@ class Provider extends React.Component { static Consumer = ProviderConsumer - renderStaticStyles = () => { + renderStaticStyles = (mergedTheme: ThemePrepared) => { // RTL WARNING // This function sets static styles which are global and renderer agnostic // With current implementation, static styles cannot differ between LTR and RTL // @see http://fela.js.org/docs/advanced/StaticStyle.html for details - const { siteVariables, staticStyles } = this.props.theme + const { siteVariables } = mergedTheme + const { staticStyles } = this.props.theme if (!staticStyles) return @@ -109,7 +112,6 @@ class Provider extends React.Component { } componentDidMount() { - this.renderStaticStyles() this.renderFontFaces() } @@ -122,7 +124,7 @@ class Provider extends React.Component { { const outgoingTheme: ThemePrepared = mergeThemes(incomingTheme, theme) - + this.renderStaticStylesOnce(outgoingTheme) return ( {children} @@ -132,6 +134,14 @@ class Provider extends React.Component { /> ) } + + renderStaticStylesOnce = (mergedTheme: ThemePrepared) => { + const { staticStyles } = this.props.theme + if (!this.staticStylesRendered && staticStyles) { + this.renderStaticStyles(mergedTheme) + this.staticStylesRendered = true + } + } } export default Provider diff --git a/test/specs/components/Provider/Provider-test.tsx b/test/specs/components/Provider/Provider-test.tsx index 4c3b185e0a..744972873f 100644 --- a/test/specs/components/Provider/Provider-test.tsx +++ b/test/specs/components/Provider/Provider-test.tsx @@ -1,5 +1,7 @@ +import * as React from 'react' import Provider from 'src/components/Provider/Provider' import ProviderConsumer from 'src/components/Provider/ProviderConsumer' +import { mount } from 'enzyme' describe('Provider', () => { test('is exported', () => { @@ -9,4 +11,46 @@ describe('Provider', () => { test('has a ProviderConsumer subcomponent', () => { expect(require('src/index.ts').Provider.Consumer).toEqual(ProviderConsumer) }) + + describe('staticStyles', () => { + test('are executed with the merged siteVariables', () => { + const staticStyle = jest.fn() + + mount( + + + + + , + ) + + expect(staticStyle).toHaveBeenCalledWith( + expect.objectContaining({ + background: 'red', + brand: 'yellow', + gray: '#868686', + }), + ) + }) + + test('are executed only once', () => { + const firstStaticStyle = jest.fn() + const secondStaticStyle = jest.fn() + + const providerInstance = mount( + + + , + ) + providerInstance.setProps({ theme: { staticStyles: [secondStaticStyle] } }) + + expect(firstStaticStyle).toHaveBeenCalledTimes(1) + expect(secondStaticStyle).not.toHaveBeenCalled() + }) + }) })