diff --git a/CHANGELOG.md b/CHANGELOG.md index 762127b7f3..cbde22b2ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixes - Fix build on Windows @jurokapsiar ([#383](https://github.com/stardust-ui/react/pull/383)) +### Features +- Export `mergeThemes` @levithomason ([#285](https://github.com/stardust-ui/react/pull/285)) + +### Documentation +- Add `Provider` examples @levithomason ([#285](https://github.com/stardust-ui/react/pull/285)) + ## [v0.10.0](https://github.com/stardust-ui/react/tree/v0.10.0) (2018-10-19) [Compare changes](https://github.com/stardust-ui/react/compare/v0.9.1...v0.10.0) diff --git a/docs/src/examples/components/Provider/Types/ProviderExample.shorthand.tsx b/docs/src/examples/components/Provider/Types/ProviderExample.shorthand.tsx new file mode 100644 index 0000000000..a09d4ab1ae --- /dev/null +++ b/docs/src/examples/components/Provider/Types/ProviderExample.shorthand.tsx @@ -0,0 +1,20 @@ +import React from 'react' +import { Provider } from '@stardust-ui/react' + +const theme = { siteVariables: { brand: 'cornflowerblue' } } + +const ProviderExampleShorthand = () => ( + +
+

+ Use the Provider.Consumer to access the theme: +

+ + theme.siteVariables.brand = {theme.siteVariables.brand}} + /> +
+
+) + +export default ProviderExampleShorthand diff --git a/docs/src/examples/components/Provider/Types/index.tsx b/docs/src/examples/components/Provider/Types/index.tsx new file mode 100644 index 0000000000..57b5e357df --- /dev/null +++ b/docs/src/examples/components/Provider/Types/index.tsx @@ -0,0 +1,15 @@ +import * as React from 'react' +import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample' +import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection' + +const Types = () => ( + + + +) + +export default Types diff --git a/docs/src/examples/components/Provider/index.tsx b/docs/src/examples/components/Provider/index.tsx new file mode 100644 index 0000000000..bb4e2aaa06 --- /dev/null +++ b/docs/src/examples/components/Provider/index.tsx @@ -0,0 +1,10 @@ +import * as React from 'react' +import Types from './Types' + +const ProviderExamples = () => ( +
+ +
+) + +export default ProviderExamples diff --git a/src/components/Provider/Provider.tsx b/src/components/Provider/Provider.tsx index f06d57203d..2c775c4e6f 100644 --- a/src/components/Provider/Provider.tsx +++ b/src/components/Provider/Provider.tsx @@ -21,7 +21,7 @@ export interface ProviderProps { } /** - * The Provider passes the CSS in JS renderer and theme down context. + * The Provider passes the CSS in JS renderer and theme to your components. */ class Provider extends React.Component { static propTypes = { diff --git a/src/index.ts b/src/index.ts index d22c6a8aa5..dbed4569fc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -118,3 +118,8 @@ export { export { default as chatMessageEnterEscBehavior, } from './lib/accessibility/Behaviors/Chat/chatMessageEnterEscBehavior' + +// +// Utilities +// +export { default as mergeThemes } from './lib/mergeThemes' diff --git a/test/specs/components/Provider/Provider-test.tsx b/test/specs/components/Provider/Provider-test.tsx new file mode 100644 index 0000000000..4c3b185e0a --- /dev/null +++ b/test/specs/components/Provider/Provider-test.tsx @@ -0,0 +1,12 @@ +import Provider from 'src/components/Provider/Provider' +import ProviderConsumer from 'src/components/Provider/ProviderConsumer' + +describe('Provider', () => { + test('is exported', () => { + expect(require('src/index.ts').Provider).toEqual(Provider) + }) + + test('has a ProviderConsumer subcomponent', () => { + expect(require('src/index.ts').Provider.Consumer).toEqual(ProviderConsumer) + }) +}) diff --git a/test/specs/components/Provider/ProviderConsumer-test.tsx b/test/specs/components/Provider/ProviderConsumer-test.tsx new file mode 100644 index 0000000000..391630117e --- /dev/null +++ b/test/specs/components/Provider/ProviderConsumer-test.tsx @@ -0,0 +1,74 @@ +import * as React from 'react' +import { mount } from 'enzyme' + +import Provider from 'src/components/Provider/Provider' +import ProviderConsumer from 'src/components/Provider/ProviderConsumer' +import { IThemeInput } from 'types/theme' + +describe('ProviderConsumer', () => { + test('is exported', () => { + expect(require('src/index.ts').ProviderConsumer).toEqual(ProviderConsumer) + }) + + test('is a subcomponent of the Provider', () => { + expect(Provider.Consumer).toEqual(ProviderConsumer) + }) + + describe('render', () => { + test('is a callback that receives the prepared theme', () => { + expect.assertions(13) + + const inputTheme: IThemeInput = { + siteVariables: { a: 'b' }, + componentVariables: { Button: { color: 'red' } }, + componentStyles: { Button: { root: { color: 'red' } } }, + fontFaces: [{ name: 'name', paths: ['path.woff2'], style: { fontWeight: 400 } }], + staticStyles: ['body{margin:0;}', { body: { margin: 0 } }], + icons: { + user: { icon: { content: '\\f1', fontFamily: 'i' } }, + userFunc: { icon: () => ({ content: '\\f1', fontFamily: 'i' }) }, + userSvg: { isSvg: true, icon: }, + userSvgFunc: { isSvg: true, icon: () => }, + }, + } + + mount( + + { + // siteVariables + expect(preparedTheme).toHaveProperty('siteVariables.a', 'b') + + // componentVariables + expect(preparedTheme).toHaveProperty('componentVariables.Button') + expect(preparedTheme.componentVariables.Button).toBeInstanceOf(Function) + expect(preparedTheme.componentVariables.Button()).toMatchObject( + inputTheme.componentVariables.Button, + ) + + // componentStyles + expect(preparedTheme).toHaveProperty('componentStyles.Button.root') + expect(preparedTheme.componentStyles.Button.root).toBeInstanceOf(Function) + expect(preparedTheme.componentStyles.Button.root()).toMatchObject( + inputTheme.componentStyles.Button.root, + ) + + // fontFaces + expect(preparedTheme).toHaveProperty('fontFaces') + expect(preparedTheme.fontFaces).toMatchObject(inputTheme.fontFaces) + + // staticStyles + expect(preparedTheme).toHaveProperty('staticStyles') + expect(preparedTheme.staticStyles).toMatchObject(inputTheme.staticStyles) + + // icons + expect(preparedTheme).toHaveProperty('icons') + expect(preparedTheme.icons).toMatchObject(inputTheme.icons) + return null + }} + /> + , + ) + }) + }) +})