diff --git a/README.md b/README.md
index 0c28568b..3013485b 100644
--- a/README.md
+++ b/README.md
@@ -110,7 +110,8 @@ const Html = () => (
)
```
-Rendering on the client automatically includes your app styles:
+Rendering on the client automatically includes your app styles and supports
+progressive app loading (i.e. code-splitting / lazy bundle loading):
```js
// client.js
diff --git a/docs/apis/StyleSheet.md b/docs/apis/StyleSheet.md
index 22d7a063..b0b96c8e 100644
--- a/docs/apis/StyleSheet.md
+++ b/docs/apis/StyleSheet.md
@@ -37,24 +37,10 @@ Use styles:
```
-Render styles on the server or in the browser:
-
-```js
-StyleSheet.renderToString()
-```
-
## Methods
**create**(obj: {[key: string]: any})
-**destroy**()
-
-Clears all style information.
-
-**renderToString**()
-
-Renders a CSS Style Sheet.
-
## About
### Strategy
@@ -71,9 +57,9 @@ CSS](https://speakerdeck.com/vjeux/react-css-in-js):
6. Non-deterministic resolution
7. Breaking isolation
-The strategy also minimizes the amount of generated CSS, making it more viable
-to inline the style sheet when pre-rendering pages on the server. There is one
-unique selector per unique style _declaration_.
+The strategy minimizes the amount of generated CSS, making it viable to inline
+the style sheet when pre-rendering pages on the server. There is one unique
+selector per unique style _declaration_.
```js
// definition
@@ -88,7 +74,7 @@ unique selector per unique style _declaration_.
}
}
-// css
+// css output
//
// .a { color: gray; }
// .b { font-size: 2rem; }
@@ -130,16 +116,17 @@ In production the class names are obfuscated.
(CSS libraries like [Atomic CSS](http://acss.io/),
[Basscss](http://www.basscss.com/), [SUIT CSS](https://suitcss.github.io/), and
[tachyons](http://tachyons.io/) are attempts to limit style scope and limit
-style sheet growth in a similar way. But they're CSS utility libraries, each with a
-particular set of classes and features to learn. All of them require developers
-to manually connect CSS classes for given styles.)
+style sheet growth in a similar way. But they're CSS utility libraries, each
+with a particular set of classes and features to learn. And all of them require
+developers to manually connect CSS classes for given styles.)
### Reset
React Native for Web includes a very small CSS reset taken from
-[normalize.css](https://necolas.github.io/normalize.css/). It removes unwanted
-User Agent styles from (pseudo-)elements beyond the reach of React (e.g.,
-`html`, `body`) or inline styles (e.g., `::-moz-focus-inner`).
+[normalize.css](https://necolas.github.io/normalize.css/) – **you do not need
+to include normalize.css**. It removes unwanted User Agent styles from
+(pseudo-)elements beyond the reach of React (e.g., `html`, `body`) or inline
+styles (e.g., `::-moz-focus-inner`).
```css
html {
@@ -162,4 +149,10 @@ input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
+
+ol,
+ul,
+li {
+ list-style:none
+}
```
diff --git a/package.json b/package.json
index ff38ac60..bbfae4eb 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"dist"
],
"scripts": {
- "build": "rm -rf ./dist && mkdir dist && babel src -d dist --ignore src/**/__tests__,src/modules/specHelpers",
+ "build": "rm -rf ./dist && mkdir dist && babel src -d dist --ignore **/__tests__,src/modules/specHelpers",
"build:umd": "webpack --config config/webpack.config.js --sort-assets-by --progress",
"examples": "webpack-dev-server --config config/webpack.config.example.js --inline --hot --colors --quiet",
"lint": "eslint config examples src",
diff --git a/src/__tests__/index-test.js b/src/__tests__/index-test.js
index a047a866..a287efd7 100644
--- a/src/__tests__/index-test.js
+++ b/src/__tests__/index-test.js
@@ -1,6 +1,5 @@
/* eslint-env mocha */
-import * as utils from '../modules/specHelpers'
import assert from 'assert'
import React from '..'
diff --git a/src/index.js b/src/index.js
index 95e8ad70..3f6aa607 100644
--- a/src/index.js
+++ b/src/index.js
@@ -15,7 +15,7 @@ import Touchable from './components/Touchable'
import View from './components/View'
const renderStyle = () => {
- return ``
+ return ``
}
const render = (element, container, callback) => {
diff --git a/src/modules/StyleSheet/__tests__/index-test.js b/src/modules/StyleSheet/__tests__/index-test.js
index dcf16c4f..93939085 100644
--- a/src/modules/StyleSheet/__tests__/index-test.js
+++ b/src/modules/StyleSheet/__tests__/index-test.js
@@ -8,24 +8,40 @@ const styles = { root: { borderWidth: 1 } }
suite('modules/StyleSheet', () => {
setup(() => {
- StyleSheet.destroy()
+ StyleSheet._destroy()
})
- test('create', () => {
- assert.equal(StyleSheet.create(styles), styles)
- })
+ suite('create', () => {
+ const div = document.createElement('div')
- test('renderToString', () => {
- StyleSheet.create(styles)
- assert.equal(
- StyleSheet.renderToString(),
- `${resetCSS}\n${predefinedCSS}\n` +
- `/* 4 unique declarations */\n` +
- `.borderBottomWidth\\:1px{border-bottom-width:1px;}\n` +
- `.borderLeftWidth\\:1px{border-left-width:1px;}\n` +
- `.borderRightWidth\\:1px{border-right-width:1px;}\n` +
- `.borderTopWidth\\:1px{border-top-width:1px;}`
- )
+ setup(() => {
+ document.body.appendChild(div)
+ StyleSheet.create(styles)
+ div.innerHTML = ``
+ })
+
+ teardown(() => {
+ document.body.removeChild(div)
+ })
+
+ test('returns styles object', () => {
+ assert.equal(StyleSheet.create(styles), styles)
+ })
+
+ test('updates already-rendered style sheet', () => {
+ StyleSheet.create({ root: { color: 'red' } })
+
+ assert.equal(
+ document.getElementById('react-stylesheet').textContent,
+ `${resetCSS}\n${predefinedCSS}\n` +
+ `/* 5 unique declarations */\n` +
+ `.borderBottomWidth\\:1px{border-bottom-width:1px;}\n` +
+ `.borderLeftWidth\\:1px{border-left-width:1px;}\n` +
+ `.borderRightWidth\\:1px{border-right-width:1px;}\n` +
+ `.borderTopWidth\\:1px{border-top-width:1px;}\n` +
+ `.color\\:red{color:red;}`
+ )
+ })
})
test('resolve', () => {
@@ -34,4 +50,17 @@ suite('modules/StyleSheet', () => {
StyleSheet.create(styles)
assert.deepEqual(StyleSheet.resolve(props), expected)
})
+
+ test('_renderToString', () => {
+ StyleSheet.create(styles)
+ assert.equal(
+ StyleSheet._renderToString(),
+ `${resetCSS}\n${predefinedCSS}\n` +
+ `/* 4 unique declarations */\n` +
+ `.borderBottomWidth\\:1px{border-bottom-width:1px;}\n` +
+ `.borderLeftWidth\\:1px{border-left-width:1px;}\n` +
+ `.borderRightWidth\\:1px{border-right-width:1px;}\n` +
+ `.borderTopWidth\\:1px{border-top-width:1px;}`
+ )
+ })
})
diff --git a/src/modules/StyleSheet/index.js b/src/modules/StyleSheet/index.js
index 9e41a1e8..0f1222ca 100644
--- a/src/modules/StyleSheet/index.js
+++ b/src/modules/StyleSheet/index.js
@@ -13,6 +13,24 @@ const initialState = { classNames: predefinedClassNames }
const options = { obfuscateClassNames: process.env.NODE_ENV === 'production' }
const createStore = () => new Store(initialState, options)
let store = createStore()
+let isRendered = false
+
+/**
+ * Destroy existing styles
+ */
+const _destroy = () => {
+ store = createStore()
+ isRendered = false
+}
+
+/**
+ * Render the styles as a CSS style sheet
+ */
+const _renderToString = () => {
+ const css = store.toString()
+ isRendered = true
+ return `${resetCSS}\n${predefinedCSS}\n${css}`
+}
/**
* Process all unique declarations
@@ -33,24 +51,20 @@ const create = (styles: Object): Object => {
}
})
})
+
+ // update the style sheet in place
+ if (isRendered) {
+ const stylesheet = document.getElementById('react-stylesheet')
+ if (stylesheet) {
+ stylesheet.textContent = _renderToString()
+ } else if (process.env.NODE_ENV !== 'production') {
+ console.error('ReactNativeWeb: cannot find "react-stylesheet" element')
+ }
+ }
+
return styles
}
-/**
- * Destroy existing styles
- */
-const destroy = () => {
- store = createStore()
-}
-
-/**
- * Render the styles as a CSS style sheet
- */
-const renderToString = () => {
- const css = store.toString()
- return `${resetCSS}\n${predefinedCSS}\n${css}`
-}
-
/**
* Accepts React props and converts inline styles to single purpose classes
* where possible.
@@ -81,8 +95,8 @@ const resolve = ({ className = '', style = {} }) => {
}
export default {
+ _destroy,
+ _renderToString,
create,
- destroy,
- renderToString,
resolve
}