Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/add-ts-typings' into add-ts-typings
Browse files Browse the repository at this point in the history
* origin/add-ts-typings:
  Scoped keyframes (#888)
  Update readme.md (#897)
  Use CSSTOM in default unit plugin (#893)
  Added .nvmrc (#896)
  [WIP] DONT MERGE Fix ci (#895)
  Update ci (#894)
  Support plugins processing for observables by default (#892)
  Typed CSSOM values support (#887)
  Dynamic values full syntax (#878)
  [jss-plugin-cache] Use WeakMap for cache plugin (#890)
  • Loading branch information
Henri Beck committed Oct 22, 2018
2 parents d9d39fa + c6cae18 commit db8d088
Show file tree
Hide file tree
Showing 101 changed files with 10,732 additions and 990 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ branches:
after_success:
- bash <(curl -s https://codecov.io/bash)
script:
- yarn check-snapshots
- yarn build
- yarn lint:ci
- yarn test
env:
Expand Down
10 changes: 10 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
## Next / 2018-09-16

- Fix multiple cases where linking CSS rules didn't work (#815, #710, #664)
- Added support for Typed CSSOM values (#882)
- Added scoped keyframes support (#346)
- Function values and function rules support now fallbacks, media queries, nesting, global styles (#682)

### Breaking changes

- Observables, function values and rules are now standalone packages, not part of the core. They are still part of the default preset though.
- Function values, rules and observables apply plugins by default now, which means they can support all plugin defined syntaxes, but they are also slower by default. To speed them up use `sheet.update(data, {process: false})` for fn values/rules and `jss.use(pluginObservable({process: false}))` when setting up observables plugin. (#682)
- Rule @keyframes has now scoped name by default, which means that you can access it using `$ref` from the same sheet and generate global one as before using `@global` rule ((#346).
- Options `createGenerateClassName` and `generateClassName` are renamed to `createGenerateId` and `generateId` since th same function is now used to scope @keyframes rules. This affects both JSS and React-JSS.

## 9.8.7 / 2018-06-24

Expand Down
12 changes: 6 additions & 6 deletions docs/js-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default jss

Options:

- `createGenerateClassName` - a function which returns a function which generates unique class names.
- `createGenerateId` - a function which returns a function which generates unique class names.
- `plugins` - an array of functions, will be passed to `jss.use`.
- `virtual` - if true, JSS will use VirtualRenderer.
- `insertionPoint` - string value of a DOM comment node which marks the start of sheets or a rendered DOM node. Sheets rendered by this Jss instance are inserted after this point sequentially.
Expand Down Expand Up @@ -74,7 +74,7 @@ Options:
- `link` - link jss `Rule` instances with DOM `CSSRule` instances so that styles, can be modified dynamically, false by default because it has some performance cost.
- `element` - style element, will create one by default.
- `index` - 0 by default - determines DOM rendering order, higher number = higher specificity (inserted after).
- `generateClassName` - a function that generates a unique class name.
- `generateId` - a function that generates a unique class name.
- `classNamePrefix` - a string, which will be added at the beginning of the class name.

```javascript
Expand Down Expand Up @@ -358,22 +358,22 @@ console.log(sheet.toString())

## Generate your own class names

`createGenerateClassName`
`createGenerateId`

Option `createGenerateClassName` allows you to specify a function which returns a class name generator function `generateClassName(rule, sheet)`. This pattern is used to allow JSS reset the counter upon factory invocation, when needed. For example, it is used in [React-JSS](https://github.com/cssinjs/react-jss) to reset the counter on each request for server-side rendering.
Option `createGenerateId` allows you to specify a function which returns a class name generator function `generateId(rule, sheet)`. This pattern is used to allow JSS reset the counter upon factory invocation, when needed. For example, it is used in [React-JSS](https://github.com/cssinjs/react-jss) to reset the counter on each request for server-side rendering.

By default class names generator uses a simple counter to ensure uniqueness of the class names. It consists of `classNamePrefix` Style Sheet option + rule name + counter. **Note**: in production (`NODE_ENV=production`) it uses just the `c` + rules counter.

```javascript
import jss from 'jss'

const createGenerateClassName = () => {
const createGenerateId = () => {
let counter = 0

return (rule, sheet) => `pizza--${rule.key}-${counter++}`
}

jss.setup({createGenerateClassName})
jss.setup({createGenerateId})

const sheet = jss.createStyleSheet({
button: {
Expand Down
103 changes: 23 additions & 80 deletions docs/json-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,72 +22,6 @@ Compiles to:
}
```

## Function values

If you want dynamic behavior for your Style Sheet, you can use functions as a value which return the actual value. If function values returns `null|undefined|false` - property will be removed. Use [sheet.update(data)](./js-api.md#update-function-values) in order to pass the data object. [Sheet option](./js-api.md#create-style-sheet) `link: true` is required for this to function.

```javascript
const styles = {
button: {
color: data => data.color
}
}
```

### Support of "!important"

To use the `!important` modifier with function values, you must use [array syntax](#alternative-syntax-for-space-and-comma-separated-values):

```javascript
const styles = {
button: {
color: data => [[data.color], '!important']
}
}
```

## Function rules

Similar to function values, you can use a function to return a dynamic style object. Use [sheet.update(data)](./js-api.md#update-function-values) in order to pass the data object. Sheet option `link: true` is required for this to function.

```javascript
const styles = {
button: data => ({
display: 'flex',
color: data.color
})
}
```

## Observable values

In order to create highly dynamic animations, you may want to use streams. Take a look at the [tc39 observable proposal](https://github.com/tc39/proposal-observable). Sheet option `link: true` is required for this to function.

```javascript
const styles = {
button: {
color: new Observable(observer => {
observer.next('red')
})
}
}
```

## Observable rules

Similar to observable values, you can declare observable rules. Stream should contain in this case the style object. Sheet option `link: true` is required for this to function.

```javascript
const styles = {
button: new Observable(observer => {
observer.next({
color: 'red',
opacity: 1
})
})
}
```

## Media Queries

```javascript
Expand Down Expand Up @@ -135,41 +69,38 @@ Compiles to:

## Keyframes Animation

Note: keyframe id is still global and may conflict.
Keyframes name will use the same id generator function as the class names. Animation name will be scoped by default. In order to access it within the same style sheet, you can use `$ref` syntax as a value of `animationName` or `animation` property.

```javascript
const styles = {
'@keyframes my-animation': {
from: {opacity: 0},
to: {opacity: 1}
}
}
```
Additionally generated name can be accessed through `sheet.keyframes.{name}` map.

### ES6 with generated keyframe id
In order to generate a global animation name, you can use `@global` rule.

```javascript
const animationId = Math.random()

const styles = {
[`@keyframes ${animationId}`]: {
'@keyframes slideRight': {
from: {opacity: 0},
to: {opacity: 1}
},
container: {
animationName: '$slideRight'
}
}
```

Compiles to:

```css
@keyframes my-animation {
@keyframes keyframes-slideRight-0-1-2 {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.container-0-1-3 {
animation-name: keyframes-slideRight-0-1-2;
}
```

## Fallbacks
Expand Down Expand Up @@ -421,6 +352,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).
8 changes: 8 additions & 0 deletions flow-typed/css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
interface CSSOM {
px(val: number | string): {};
percent(val: number | string): {};
ms(val: number | string): {};
number(val: number | string): {};
}

declare var CSS: ?CSSOM
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = config => {
'node_modules/raf/polyfill.js',
'./packages/jss/tests/index.js',
'./packages/jss-plugin-syntax-rule-value-function/src/index.test.js',
'./packages/jss-plugin-syntax-rule-value-observable/src/observable.test.js',
'./packages/jss-plugin-syntax-rule-value-observable/src/index.test.js',
'./packages/jss-plugin-syntax-expand/src/index.test.js',
'./packages/jss-plugin-syntax-default-unit/src/index.test.js',
'./packages/jss-plugin-syntax-camel-case/src/index.test.js',
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"packages/*"
],
"scripts": {
"prepare": "lerna run prepare",
"publish": "yarn lint && yarn test && lerna publish",
"build": "lerna run prepare",
"publish": "yarn lint && yarn test && yarn build && lerna publish",
"typecheck": "flow check --max-warnings=0",
"ts-check": "tsc",
"lint": "eslint scripts/ packages/ && yarn typecheck && yarn format",
Expand All @@ -15,7 +15,8 @@
"format": "prettier \"*.{js,md,json,ts}\" \"{docs,packages,scripts}/**/*.{js,md,json,ts}\" --write",
"test": "cross-env NODE_ENV=test VERSION=\"1\" karma start --single-run",
"test:watch": "cross-env NODE_ENV=test VERSION=\"1\" karma start",
"posttest": "lerna exec -- cross-env SNAPSHOT=match rollup --config ../../rollup.config.js && [ -z \"$TRAVIS\" ] || codecov",
"check-snapshots": "lerna exec -- cross-env SNAPSHOT=match rollup --config ../../rollup.config.js",
"posttest": "yarn check-snapshots && [ -z \"$TRAVIS\" ] || codecov",
"codecov": "codecov",
"bench": "cross-env BENCHMARK=true karma start --single-run"
},
Expand Down Expand Up @@ -70,7 +71,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": 1066,
"minified": 518,
"gzipped": 331
},
"dist/jss-plugin-cache.min.js": {
"bundled": 1700,
"minified": 727,
"gzipped": 411
"bundled": 1066,
"minified": 518,
"gzipped": 331
},
"dist/jss-plugin-cache.cjs.js": {
"bundled": 1334,
"minified": 588,
"gzipped": 351
"bundled": 748,
"minified": 371,
"gzipped": 258
},
"dist/jss-plugin-cache.esm.js": {
"bundled": 1252,
"minified": 519,
"gzipped": 300,
"bundled": 666,
"minified": 302,
"gzipped": 215,
"treeshaked": {
"rollup": {
"code": 0,
Expand Down
4 changes: 4 additions & 0 deletions packages/jss-plugin-cache/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ in general.

[![Gitter](https://badges.gitter.im/JoinChat.svg)](https://gitter.im/cssinjs/lobby)

## Polyfills

1. This plugin is using a `WeakMap`. If you support browsers which do not support WeakMap, you will have to include a polyfill.

## Caveats

1. Don't use it if you mutate your `styles`.
Expand Down
26 changes: 2 additions & 24 deletions packages/jss-plugin-cache/src/index.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,11 @@
// @flow
import type {Plugin} from 'jss'

/**
* Tiny WeakMap like cache using arrays.
* Required because we have frozen style objects in dev, which are not extensible,
* so we can't put some key into that object.
* Relies on [].indexOf(Object).
*/
class Cache {
keys = []

data = []

get(key) {
const index = this.keys.indexOf(key)
return index === -1 ? null : this.data[index]
}

set(key, value) {
this.keys.push(key)
this.data.push(value)
}
}

export default function cachePlugin(): Plugin {
const cache = new Cache()
const cache = new WeakMap()

function onCreateRule(name, decl, {parent}) {
return parent ? cache.get(parent.rules.raw[name]) : null
return parent && name ? cache.get(parent.rules.raw[name]) || null : null
}

function onProcessRule(rule) {
Expand Down
2 changes: 1 addition & 1 deletion packages/jss-plugin-props-sort/src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {create} from 'jss'
import propsSort from './index'

const settings = {
createGenerateClassName: () => rule => `${rule.key}-id`
createGenerateId: () => rule => `${rule.key}-id`
}

describe('jss-plugin-props-sort', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/jss-plugin-syntax-camel-case/src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import functionPlugin from 'jss-plugin-syntax-rule-value-function'
import camelCase from './index'

const settings = {
createGenerateClassName: () => rule => `${rule.key}-id`
createGenerateId: () => rule => `${rule.key}-id`
}

describe('jss-plugin-syntax-camel-case', () => {
Expand Down
Loading

0 comments on commit db8d088

Please sign in to comment.