diff --git a/changelog.md b/changelog.md index 35793a608..58f67e7b1 100755 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ ## Next +### Improvements + +- [jss|jss-plugin-rule-value-function|jss-plugin-rule-value-observable] Split `getDynamicStyles` and move it out of `jss` ([#1000](https://github.com/cssinjs/jss/pull/1000)) + ### Bug fixes - [jss-starter-kit] Fix react-jss exports and add missing jss exports ([#1001](https://github.com/cssinjs/jss/pull/1001)) diff --git a/docs/jss-api.md b/docs/jss-api.md index 327663bdb..e6689c8f5 100644 --- a/docs/jss-api.md +++ b/docs/jss-api.md @@ -420,30 +420,6 @@ console.log(sheet.toString()) } ``` -## Extract dynamic styles - -`getDynamicStyles(styles)` - -Extracts a styles object with only props that contain function values. Useful when you want to share a static part between different elements and render only the dynamic styles separate for each element. - -```javascript -import {getDynamicStyles} from 'jss' - -const dynamicStyles = getDynamicStyles({ - button: { - fontSize: 12, - color: data => data.color - } -}) - -console.log(dynamicStyles) -// { -// button: { -// color: data => data.color -// } -// } -``` - ## Plugins See [plugins](plugins.md) documentation. diff --git a/packages/jss-plugin-rule-value-function/.size-snapshot.json b/packages/jss-plugin-rule-value-function/.size-snapshot.json index 0f600be75..7307b83f0 100644 --- a/packages/jss-plugin-rule-value-function/.size-snapshot.json +++ b/packages/jss-plugin-rule-value-function/.size-snapshot.json @@ -1,23 +1,23 @@ { "dist/jss-plugin-rule-value-function.js": { - "bundled": 2025, - "minified": 729, - "gzipped": 424 + "bundled": 2852, + "minified": 987, + "gzipped": 545 }, "dist/jss-plugin-rule-value-function.min.js": { - "bundled": 2025, - "minified": 729, - "gzipped": 424 + "bundled": 2852, + "minified": 987, + "gzipped": 545 }, "dist/jss-plugin-rule-value-function.cjs.js": { - "bundled": 1642, - "minified": 631, - "gzipped": 366 + "bundled": 2407, + "minified": 988, + "gzipped": 508 }, "dist/jss-plugin-rule-value-function.esm.js": { - "bundled": 1564, - "minified": 567, - "gzipped": 319, + "bundled": 2312, + "minified": 906, + "gzipped": 462, "treeshaked": { "rollup": { "code": 12, diff --git a/packages/jss-plugin-rule-value-function/src/index.js b/packages/jss-plugin-rule-value-function/src/index.js index b81d0837b..74ed98626 100644 --- a/packages/jss-plugin-rule-value-function/src/index.js +++ b/packages/jss-plugin-rule-value-function/src/index.js @@ -16,6 +16,45 @@ const fnRuleNs = `fnStyle${++now}` type StyleRuleWithRuleFunction = StyleRule & {[key: string]: Function} +const plainObjectConstrurctor = {}.constructor + +function getFunctionStyles(styles: Object): Object | null { + let to = null + + for (const key in styles) { + const value = styles[key] + + switch (typeof value) { + case 'function': { + if (!to) to = {} + to[key] = value + break + } + case 'object': { + if ( + value == null || + Array.isArray(value) || + value.constructor !== plainObjectConstrurctor + ) { + continue + } + const extracted = getFunctionStyles(value) + if (extracted) { + if (!to) to = {} + to[key] = extracted + } + break + } + default: + break + } + } + + return to +} + +export {getFunctionStyles} + export default function functionPlugin() { return { onCreateRule(name?: string, decl: JssStyle, options: RuleOptions): Rule | null { diff --git a/packages/jss-plugin-rule-value-observable/.size-snapshot.json b/packages/jss-plugin-rule-value-observable/.size-snapshot.json index c019555da..5f7bb675c 100644 --- a/packages/jss-plugin-rule-value-observable/.size-snapshot.json +++ b/packages/jss-plugin-rule-value-observable/.size-snapshot.json @@ -1,23 +1,23 @@ { "dist/jss-plugin-rule-value-observable.js": { - "bundled": 3531, - "minified": 1101, - "gzipped": 533 + "bundled": 4323, + "minified": 1323, + "gzipped": 627 }, "dist/jss-plugin-rule-value-observable.min.js": { - "bundled": 3531, - "minified": 1101, - "gzipped": 533 + "bundled": 4323, + "minified": 1323, + "gzipped": 627 }, "dist/jss-plugin-rule-value-observable.cjs.js": { - "bundled": 1709, - "minified": 754, - "gzipped": 399 + "bundled": 2261, + "minified": 1065, + "gzipped": 504 }, "dist/jss-plugin-rule-value-observable.esm.js": { - "bundled": 1495, - "minified": 591, - "gzipped": 318, + "bundled": 2005, + "minified": 861, + "gzipped": 427, "treeshaked": { "rollup": { "code": 38, diff --git a/packages/jss-plugin-rule-value-observable/src/index.js b/packages/jss-plugin-rule-value-observable/src/index.js index 65ac09365..842e31f89 100644 --- a/packages/jss-plugin-rule-value-observable/src/index.js +++ b/packages/jss-plugin-rule-value-observable/src/index.js @@ -10,10 +10,34 @@ import { } from 'jss' import type {Observable} from './types' -const isObservable = value => value && value[$$observable] && value === value[$$observable]() +const isObservable = (value: any) => value && value[$$observable] && value === value[$$observable]() export type Options = UpdateOptions +function getObservableStyles(styles: Object): Object | null { + let to = null + + for (const key in styles) { + const value = styles[key] + const type = typeof value + + if (isObservable(value)) { + if (!to) to = {} + to[key] = value + } else if (type === 'object' && value !== null && !Array.isArray(value)) { + const extracted = getObservableStyles(value) + if (extracted) { + if (!to) to = {} + to[key] = extracted + } + } + } + + return to +} + +export {isObservable, getObservableStyles} + export default function observablePlugin(updateOptions?: Options) { return { onCreateRule(name?: string, decl: JssStyle, options: RuleOptions): Rule | null { diff --git a/packages/jss/.size-snapshot.json b/packages/jss/.size-snapshot.json index 2df38f0fa..dca62f9e0 100644 --- a/packages/jss/.size-snapshot.json +++ b/packages/jss/.size-snapshot.json @@ -1,30 +1,30 @@ { "dist/jss.js": { - "bundled": 59740, - "minified": 22374, - "gzipped": 6667 + "bundled": 59110, + "minified": 22158, + "gzipped": 6581 }, "dist/jss.min.js": { - "bundled": 58601, - "minified": 21513, - "gzipped": 6230 + "bundled": 57971, + "minified": 21297, + "gzipped": 6147 }, "dist/jss.cjs.js": { - "bundled": 54651, - "minified": 24090, - "gzipped": 6647 + "bundled": 54065, + "minified": 23822, + "gzipped": 6562 }, "dist/jss.esm.js": { - "bundled": 54135, - "minified": 23671, - "gzipped": 6560, + "bundled": 53576, + "minified": 23428, + "gzipped": 6477, "treeshaked": { "rollup": { "code": 19192, "import_statements": 314 }, "webpack": { - "code": 20665 + "code": 20500 } } } diff --git a/packages/jss/src/index.d.ts b/packages/jss/src/index.d.ts index ca731b242..f72fd9225 100644 --- a/packages/jss/src/index.d.ts +++ b/packages/jss/src/index.d.ts @@ -213,7 +213,6 @@ export function create(options?: Partial): Jss export function createGenerateId(): GenerateId export function createRule(name: string, decl: JssStyle, options: RuleOptions): Rule export function toCssValue(value: JssValue, ignoreImportant: boolean): string -export function getDynamicStyles(styles: Styles): Styles | null declare const jss: Jss export default jss diff --git a/packages/jss/src/index.js b/packages/jss/src/index.js index 51150eb81..66d52fde8 100644 --- a/packages/jss/src/index.js +++ b/packages/jss/src/index.js @@ -55,11 +55,6 @@ export type { */ export const hasCSSTOMSupport = typeof CSS !== 'undefined' && CSS && 'number' in CSS -/** - * Extracts a styles object with only rules that contain function values. - */ -export {default as getDynamicStyles} from './utils/getDynamicStyles' - /** * Converts JSS array value to a CSS string. */ diff --git a/packages/jss/src/utils/getDynamicStyles.js b/packages/jss/src/utils/getDynamicStyles.js deleted file mode 100644 index fefbb4eaf..000000000 --- a/packages/jss/src/utils/getDynamicStyles.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Extracts a styles object with only props that contain function values. - */ -export default function getDynamicStyles(styles: Object): Object | null { - let to = null - - for (const key in styles) { - const value = styles[key] - const type = typeof value - - if (type === 'function') { - if (!to) to = {} - to[key] = value - } else if (type === 'object' && value !== null && !Array.isArray(value)) { - const extracted = getDynamicStyles(value) - if (extracted) { - if (!to) to = {} - to[key] = extracted - } - } - } - - return to -} diff --git a/packages/jss/tests/unit/getDynamicStyles.js b/packages/jss/tests/unit/getDynamicStyles.js deleted file mode 100644 index cf8b98bd4..000000000 --- a/packages/jss/tests/unit/getDynamicStyles.js +++ /dev/null @@ -1,74 +0,0 @@ -import expect from 'expect.js' -import getDynamicStyles from '../../src/utils/getDynamicStyles' -import {resetSheets} from '../../../../tests/utils' - -describe('Unit: jss - getDynamicStyles', () => { - beforeEach(resetSheets()) - - it('should extract dynamic styles', () => { - const color = data => data.color - const styles = { - button: { - float: 'left', - margin: [5, 10], - color, - '@media screen': { - width: null - }, - '@media print': { - width: undefined, - color - }, - '& a': { - color: 'red', - '& b': { - color - } - } - }, - '@media': { - button: { - width: 2, - color - } - }, - nested: { - '& a': { - color: 'red' - } - } - } - expect(getDynamicStyles(styles)).to.eql({ - button: { - color, - '@media print': { - color - }, - '& a': { - '& b': { - color - } - } - }, - '@media': { - button: { - color - } - } - }) - }) - - it('should return null if there are no function values', () => { - const styles = { - button: { - float: 'left' - }, - '@media': { - button: { - width: 2 - } - } - } - expect(getDynamicStyles(styles)).to.be(null) - }) -}) diff --git a/packages/react-jss/.size-snapshot.json b/packages/react-jss/.size-snapshot.json index ed48ab7eb..7af4f8136 100644 --- a/packages/react-jss/.size-snapshot.json +++ b/packages/react-jss/.size-snapshot.json @@ -1,30 +1,30 @@ { "dist/react-jss.js": { - "bundled": 131866, - "minified": 44695, - "gzipped": 13215 + "bundled": 132634, + "minified": 44917, + "gzipped": 13301 }, "dist/react-jss.min.js": { - "bundled": 100134, - "minified": 34854, - "gzipped": 10467 + "bundled": 100902, + "minified": 35076, + "gzipped": 10549 }, "dist/react-jss.cjs.js": { - "bundled": 14377, - "minified": 6602, - "gzipped": 2191 + "bundled": 14470, + "minified": 6688, + "gzipped": 2222 }, "dist/react-jss.esm.js": { - "bundled": 13737, - "minified": 6056, - "gzipped": 2082, + "bundled": 13788, + "minified": 6102, + "gzipped": 2102, "treeshaked": { "rollup": { - "code": 1925, - "import_statements": 436 + "code": 1964, + "import_statements": 475 }, "webpack": { - "code": 3285 + "code": 3358 } } } diff --git a/packages/react-jss/package.json b/packages/react-jss/package.json index d8740ff00..c004d926c 100644 --- a/packages/react-jss/package.json +++ b/packages/react-jss/package.json @@ -44,6 +44,7 @@ "@babel/runtime": "^7.0.0", "hoist-non-react-statics": "^3.2.0", "jss": "10.0.0-alpha.9", + "jss-plugin-rule-value-function": "10.0.0-alpha.9", "jss-preset-default": "10.0.0-alpha.9", "prop-types": "^15.6.0", "theming": "^3.0.3" diff --git a/packages/react-jss/src/withStyles.js b/packages/react-jss/src/withStyles.js index 064ea41f8..d81201297 100644 --- a/packages/react-jss/src/withStyles.js +++ b/packages/react-jss/src/withStyles.js @@ -1,7 +1,8 @@ // @flow import React, {Component, type ComponentType, type Node} from 'react' import hoistNonReactStatics from 'hoist-non-react-statics' -import {getDynamicStyles, SheetsManager, type StyleSheet} from 'jss' +import {SheetsManager, type StyleSheet} from 'jss' +import {getFunctionStyles} from 'jss-plugin-rule-value-function' import {ThemeContext} from 'theming' import type {HOCProps, Options, Styles, InnerProps} from './types' @@ -145,7 +146,7 @@ export default function withStyles>( }) this.manager.add(theme, staticSheet) // $FlowFixMe Cannot add random fields to instance of class StyleSheet - staticSheet[dynamicStylesNS] = getDynamicStyles(themedStyles) + staticSheet[dynamicStylesNS] = getFunctionStyles(themedStyles) return staticSheet }