Skip to content

Commit

Permalink
Typed CSSOM values support (#887)
Browse files Browse the repository at this point in the history
* added fallbacks test to fn rules

* only call onChangeValue if plugins: true

* enable removing props from fn rules

* shorter syntax with coercion

* wip full syntax support

* restore browsers.json

* changelog

* move hook call to the core

* isProcessed flag explanation

* added tests to fn rules

* remove media rule as a function test case

* added a test for #796, as part of #682

* tests for compose plugin

* observables

- move documentation to the package
- update docs, since plugins don't apply by default
- introduce option process: true to the plugin to enable plugins if user wants that

* move fn values docs

* wording

* support typed cssom

* Update docs/json-api.md

* Update changelog.md
  • Loading branch information
kof authored Oct 14, 2018
1 parent 92a53e4 commit 87b9d58
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 1,312 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Next / 2018-09-16

- Fix multiple cases where linking CSS rules didn't work (#815, #710, #664)
- Added support for Typed CSSOM values

### Breaking changes

Expand Down
12 changes: 12 additions & 0 deletions docs/json-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,18 @@ Compiles to:
}
```

## Typed CSSOM (Houdini)

Typed CSSOM values are supported. You can learn more about them [here](https://developers.google.com/web/updates/2018/03/cssom) and track the standardization progress [here](https://ishoudinireadyyet.com/). Also make sure you use a [polyfill](https://github.com/csstools/css-typed-om) for browsers without support. It will make most sence when used together with function values and observables for frequent updates.

```javascript
const styles = {
button: {
margin: CSS.px(10)
}
}
```

## Plugins

JSS plugins give you even more features, [read about them](plugins.md).
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-flowtype": "^2.29.1",
"expect.js": "^0.3.1",
"flow-bin": "^0.73.0",
"flow-bin": "^0.83.0",
"json-loader": "^0.5.4",
"karma": "^1.3.0",
"karma-benchmark": "^0.6.0",
Expand Down
24 changes: 12 additions & 12 deletions packages/jss-plugin-cache/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{
"dist/jss-plugin-cache.js": {
"bundled": 1700,
"minified": 727,
"gzipped": 411
"bundled": 1058,
"minified": 515,
"gzipped": 330
},
"dist/jss-plugin-cache.min.js": {
"bundled": 1700,
"minified": 727,
"gzipped": 411
"bundled": 1058,
"minified": 515,
"gzipped": 330
},
"dist/jss-plugin-cache.cjs.js": {
"bundled": 1334,
"minified": 588,
"gzipped": 351
"bundled": 740,
"minified": 368,
"gzipped": 256
},
"dist/jss-plugin-cache.esm.js": {
"bundled": 1252,
"minified": 519,
"gzipped": 300,
"bundled": 658,
"minified": 299,
"gzipped": 213,
"treeshaked": {
"rollup": {
"code": 0,
Expand Down
24 changes: 12 additions & 12 deletions packages/jss-plugin-syntax-rule-value-function/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{
"dist/jss-plugin-syntax-rule-value-function.js": {
"bundled": 2024,
"minified": 775,
"gzipped": 453
"bundled": 2061,
"minified": 735,
"gzipped": 428
},
"dist/jss-plugin-syntax-rule-value-function.min.js": {
"bundled": 2024,
"minified": 775,
"gzipped": 453
"bundled": 2061,
"minified": 735,
"gzipped": 428
},
"dist/jss-plugin-syntax-rule-value-function.cjs.js": {
"bundled": 1633,
"minified": 664,
"gzipped": 392
"bundled": 1672,
"minified": 631,
"gzipped": 366
},
"dist/jss-plugin-syntax-rule-value-function.esm.js": {
"bundled": 1561,
"minified": 605,
"gzipped": 345,
"bundled": 1594,
"minified": 567,
"gzipped": 319,
"treeshaked": {
"rollup": {
"code": 12,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{
"dist/jss-plugin-syntax-rule-value-observable.js": {
"bundled": 3467,
"minified": 1102,
"gzipped": 530
"bundled": 3510,
"minified": 1107,
"gzipped": 538
},
"dist/jss-plugin-syntax-rule-value-observable.min.js": {
"bundled": 3467,
"minified": 1102,
"gzipped": 530
"bundled": 3510,
"minified": 1107,
"gzipped": 538
},
"dist/jss-plugin-syntax-rule-value-observable.cjs.js": {
"bundled": 1666,
"minified": 749,
"gzipped": 394
"bundled": 1709,
"minified": 754,
"gzipped": 399
},
"dist/jss-plugin-syntax-rule-value-observable.esm.js": {
"bundled": 1452,
"minified": 586,
"gzipped": 314,
"bundled": 1495,
"minified": 591,
"gzipped": 318,
"treeshaked": {
"rollup": {
"code": 38,
Expand Down
24 changes: 12 additions & 12 deletions packages/jss-preset-default/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{
"dist/jss-preset-default.js": {
"bundled": 67567,
"minified": 23676,
"gzipped": 7031
"bundled": 67177,
"minified": 23526,
"gzipped": 6976
},
"dist/jss-preset-default.min.js": {
"bundled": 66451,
"minified": 23156,
"gzipped": 6772
"bundled": 66061,
"minified": 23006,
"gzipped": 6720
},
"dist/jss-preset-default.cjs.js": {
"bundled": 1381,
"minified": 1174,
"gzipped": 393
"bundled": 1399,
"minified": 1186,
"gzipped": 396
},
"dist/jss-preset-default.esm.js": {
"bundled": 943,
"minified": 841,
"gzipped": 315,
"bundled": 961,
"minified": 853,
"gzipped": 319,
"treeshaked": {
"rollup": {
"code": 436,
Expand Down
28 changes: 14 additions & 14 deletions packages/jss/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
{
"dist/jss.js": {
"bundled": 53666,
"minified": 20003,
"gzipped": 6023
"bundled": 54280,
"minified": 20204,
"gzipped": 6074
},
"dist/jss.min.js": {
"bundled": 52790,
"minified": 19390,
"gzipped": 5704
"bundled": 53404,
"minified": 19591,
"gzipped": 5757
},
"dist/jss.cjs.js": {
"bundled": 47425,
"minified": 20447,
"gzipped": 5778
"bundled": 48003,
"minified": 20648,
"gzipped": 5818
},
"dist/jss.esm.js": {
"bundled": 46968,
"minified": 20075,
"gzipped": 5688,
"bundled": 47546,
"minified": 20276,
"gzipped": 5732,
"treeshaked": {
"rollup": {
"code": 17168,
"code": 17369,
"import_statements": 189
},
"webpack": {
"code": 18508
"code": 18709
}
}
}
Expand Down
21 changes: 19 additions & 2 deletions packages/jss/src/renderers/DomRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ const memoize = <Value>(fn: () => Value): (() => Value) => {
*/
function getPropertyValue(cssRule: HTMLElement | CSSStyleRule, prop: string): string {
try {
// Support CSSTOM.
if ('attributeStyleMap' in cssRule) {
// $FlowFixMe
return cssRule.attributeStyleMap.get(prop)
}
return cssRule.style.getPropertyValue(prop)
} catch (err) {
// IE may throw if property is unknown.
Expand All @@ -57,7 +62,13 @@ function setProperty(cssRule: HTMLElement | CSSStyleRule, prop: string, value: J
}
}

cssRule.style.setProperty(prop, cssValue)
// Support CSSTOM.
if ('attributeStyleMap' in cssRule) {
// $FlowFixMe
cssRule.attributeStyleMap.set(prop, cssValue)
} else {
cssRule.style.setProperty(prop, cssValue)
}
} catch (err) {
// IE may throw if property is unknown.
return false
Expand All @@ -70,7 +81,13 @@ function setProperty(cssRule: HTMLElement | CSSStyleRule, prop: string, value: J
*/
function removeProperty(cssRule: HTMLElement | CSSStyleRule, prop: string) {
try {
cssRule.style.removeProperty(prop)
// Support CSSTOM.
if ('attributeStyleMap' in cssRule) {
// $FlowFixMe
cssRule.attributeStyleMap.delete(prop)
} else {
cssRule.style.removeProperty(prop)
}
} catch (err) {
warning(
false,
Expand Down
7 changes: 7 additions & 0 deletions packages/jss/src/utils/cloneStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import $$observable from 'symbol-observable'
import type {JssStyle} from '../types'

const {isArray} = Array

// TODO: This should propably not be here, need to find a better place
const isObservable = value => value && value[$$observable] && value === value[$$observable]()

Expand All @@ -16,6 +17,12 @@ export default function cloneStyle(style: JssStyle): JssStyle {
return style
}

// It is a CSSTOM value.
// TODO will not work if instance comes from a different window.
if (style instanceof window.CSSStyleValue) {
return style
}

// Support array for FontFaceRule.
if (isArray(style)) return style.map(cloneStyle)

Expand Down
39 changes: 39 additions & 0 deletions packages/jss/tests/functional/houdini.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import expect from 'expect.js'
import {create} from '../../src'
import {createGenerateClassName, hasCSSTOMSupport, computeStyle} from '../utils'

describe('Functional: houdini', () => {
if (!hasCSSTOMSupport) return

let jss

beforeEach(() => {
jss = create({createGenerateClassName})
})

describe('use unit value', () => {
let sheet

beforeEach(() => {
sheet = jss
.createStyleSheet(
{
a: {
margin: CSS.px(42)
}
},
{link: true}
)
.attach()
})

it('should render correctly', () => {
expect(computeStyle(sheet.classes.a).margin).to.be('42px')
})

it('should delete property', () => {
sheet.getRule('a').prop('margin', null)
expect(computeStyle(sheet.classes.a).margin).to.be('0px')
})
})
})
3 changes: 2 additions & 1 deletion packages/jss/tests/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import './utils'

import './integration/rules'
import './integration/sheet'
import './integration/sheetsRegistry'
import './integration/plugins'
import './integration/houdini'
import './functional/rules'
import './functional/sheet'
import './functional/priority'
import './functional/houdini'
import './unit/getDynamicStyles'
import './unit/cloneStyle'
import './unit/SheetsManager'
Expand Down
46 changes: 46 additions & 0 deletions packages/jss/tests/integration/houdini.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import expect from 'expect.js'
import {stripIndent} from 'common-tags'
import {create} from '../../src'
import {createGenerateClassName, hasCSSTOMSupport} from '../utils'

describe('Integration: houdini', () => {
if (!hasCSSTOMSupport) return

let jss

beforeEach(() => {
jss = create({createGenerateClassName})
})

describe('use unit value', () => {
let sheet
const margin = CSS.px(42)

beforeEach(() => {
sheet = jss.createStyleSheet({
a: {
margin
}
})
})

it('should get value from .prop()', () => {
expect(sheet.getRule('a').prop('margin')).to.be(margin)
})

it('should set valid value with .prop()', () => {
const width = CSS.px(10)
const rule = sheet.getRule('a')
rule.prop('width', width)
expect(rule.prop('width')).to.be(width)
})

it('should return valid .toString()', () => {
expect(sheet.toString()).to.be(stripIndent`
.a-id {
margin: 42px;
}
`)
})
})
})
Loading

0 comments on commit 87b9d58

Please sign in to comment.