From f46279ce743daaf7faa348b8cb180dc85ae54bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Lu=C4=8Div=C5=88=C3=A1k?= Date: Mon, 26 Aug 2019 17:37:20 +0200 Subject: [PATCH] fix(Provider): should not use felaRenderer explicitly (#1842) * initial commit * update changelog * add tests * fix eslint * update changelog * simplify using jest.spyOn() * use createRenderer() instead of RendererMock * fix changelog * use dumb fontFaces definition --- CHANGELOG.md | 1 + packages/internal-tooling/eslint/index.js | 6 +++ .../src/components/Provider/Provider.tsx | 29 +++++------ .../components/Provider/Provider-test.tsx | 48 +++++++++++++++++++ 4 files changed, 70 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26e552c9a0..81f8552847 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixes - Fix `muted` prop in `Video` component @layershifter ([#1847](https://github.com/stardust-ui/react/pull/1847)) +- Fix `felaRenderer` is used in `Provider` explicitly @lucivpav ([#1842](https://github.com/stardust-ui/react/pull/1842)) ## [v0.37.0](https://github.com/stardust-ui/react/tree/v0.37.0) (2019-08-26) diff --git a/packages/internal-tooling/eslint/index.js b/packages/internal-tooling/eslint/index.js index 0e07259725..d821fca131 100644 --- a/packages/internal-tooling/eslint/index.js +++ b/packages/internal-tooling/eslint/index.js @@ -115,6 +115,12 @@ module.exports = { '@stardust-ui/no-visibility-modifiers': 'error', }, }, + { + files: '**/*.{ts,tsx}', + rules: { + 'no-dupe-class-members': 'off', + }, + }, ], settings: { 'import/resolver': { diff --git a/packages/react/src/components/Provider/Provider.tsx b/packages/react/src/components/Provider/Provider.tsx index 67175d2797..6f0f259ddf 100644 --- a/packages/react/src/components/Provider/Provider.tsx +++ b/packages/react/src/components/Provider/Provider.tsx @@ -5,7 +5,7 @@ import * as React from 'react' // @ts-ignore import { RendererProvider, ThemeProvider, ThemeContext } from '@stardust-ui/react-fela' -import { felaRenderer, ChildrenComponentProps, setUpWhatInput } from '../../lib' +import { ChildrenComponentProps, setUpWhatInput } from '../../lib' import { ThemePrepared, @@ -86,9 +86,10 @@ class Provider extends React.Component> { static Box = ProviderBox static contextType = ThemeContext + outgoingContext: ProviderContextPrepared staticStylesRendered: boolean = false - renderStaticStyles = (mergedTheme: ThemePrepared) => { + renderStaticStyles = (renderer: Renderer, mergedTheme: ThemePrepared) => { const { siteVariables } = mergedTheme const { staticStyles } = this.props.theme @@ -96,13 +97,13 @@ class Provider extends React.Component> { const renderObject = (object: StaticStyleObject) => { _.forEach(object, (style, selector) => { - felaRenderer.renderStatic(style as IStyle, selector) + renderer.renderStatic(style as IStyle, selector) }) } staticStyles.forEach((staticStyle: StaticStyle) => { if (typeof staticStyle === 'string') { - felaRenderer.renderStatic(staticStyle) + renderer.renderStatic(staticStyle) } else if (_.isPlainObject(staticStyle)) { renderObject(staticStyle as StaticStyleObject) } else if (_.isFunction(staticStyle)) { @@ -116,7 +117,7 @@ class Provider extends React.Component> { }) } - renderFontFaces = () => { + renderFontFaces = (renderer: Renderer) => { const { fontFaces } = this.props.theme if (!fontFaces) return @@ -126,7 +127,7 @@ class Provider extends React.Component> { throw new Error(`fontFaces must be objects, got: ${typeof font}`) } - felaRenderer.renderFont(font.name, font.paths, font.props) + renderer.renderFont(font.name, font.paths, font.props) } fontFaces.forEach((font: FontFace) => { @@ -135,7 +136,7 @@ class Provider extends React.Component> { } componentDidMount() { - this.renderFontFaces() + this.renderFontFaces(this.outgoingContext.renderer) if (this.props.target) { setUpWhatInput(this.props.target) } @@ -165,26 +166,26 @@ class Provider extends React.Component> { const incomingContext: ProviderContextPrepared = overwrite ? {} : this.context // rehydration disabled to avoid leaking styles between renderers // https://github.com/rofrischmann/fela/blob/master/docs/api/fela-dom/rehydrate.md - const outgoingContext: ProviderContextPrepared = mergeContexts(incomingContext, inputContext) + this.outgoingContext = mergeContexts(incomingContext, inputContext) - this.renderStaticStylesOnce(outgoingContext.theme) + this.renderStaticStylesOnce(this.outgoingContext.theme) const rtlProps: { dir?: 'rtl' | 'ltr' } = {} // only add dir attribute for top level provider or when direction changes from parent to child if ( !this.context || - (this.context.rtl !== outgoingContext.rtl && _.isBoolean(outgoingContext.rtl)) + (this.context.rtl !== this.outgoingContext.rtl && _.isBoolean(this.outgoingContext.rtl)) ) { - rtlProps.dir = outgoingContext.rtl ? 'rtl' : 'ltr' + rtlProps.dir = this.outgoingContext.rtl ? 'rtl' : 'ltr' } return ( - + {children} @@ -196,7 +197,7 @@ class Provider extends React.Component> { renderStaticStylesOnce = (mergedTheme: ThemePrepared) => { const { staticStyles } = this.props.theme if (!this.staticStylesRendered && staticStyles) { - this.renderStaticStyles(mergedTheme) + this.renderStaticStyles(this.outgoingContext.renderer, mergedTheme) this.staticStylesRendered = true } } diff --git a/packages/react/test/specs/components/Provider/Provider-test.tsx b/packages/react/test/specs/components/Provider/Provider-test.tsx index 936b3b5142..ce399cea11 100644 --- a/packages/react/test/specs/components/Provider/Provider-test.tsx +++ b/packages/react/test/specs/components/Provider/Provider-test.tsx @@ -3,6 +3,8 @@ import * as React from 'react' import Provider from 'src/components/Provider/Provider' import ProviderConsumer from 'src/components/Provider/ProviderConsumer' +import { ThemeInput } from 'src/themes/types' +import { createRenderer } from '@stardust-ui/fela' describe('Provider', () => { test('is exported', () => { @@ -184,4 +186,50 @@ describe('Provider', () => { }) }) }) + + describe('calls provided renderer', () => { + test('calls renderFont', () => { + const theme: ThemeInput = { + fontFaces: [ + { + name: 'Segoe UI', + paths: ['public/fonts/segoe-ui-regular.woff2'], + style: { fontWeight: 400 }, + }, + ], + } + const renderer = createRenderer() + const renderFont = jest.spyOn(renderer, 'renderFont') + + mount( + +
+ , + ) + + expect(renderFont).toHaveBeenCalled() + }) + }) + + test('calls renderStatic', () => { + const theme: ThemeInput = { + staticStyles: [ + { + a: { + textDecoration: 'none', + }, + }, + ], + } + const renderer = createRenderer() + const renderStatic = jest.spyOn(renderer, 'renderStatic') + + mount( + +
+ , + ) + + expect(renderStatic).toHaveBeenCalled() + }) })