Compare commits

...

27 Commits
0.0.2 ... 0.0.4

Author SHA1 Message Date
Nicolas Gallagher
17d993261b 0.0.4 2015-09-03 19:43:32 -07:00
Nicolas Gallagher
ef4064d966 Add CONTRIBUTING.md 2015-09-03 19:39:03 -07:00
Nicolas Gallagher
b9e2007b59 Add travis.yml 2015-09-03 19:38:52 -07:00
Nicolas Gallagher
247f489fdd Add LICENSE 2015-09-03 19:38:45 -07:00
Nicolas Gallagher
d5b3b60c04 Update package.json and scripts 2015-09-03 19:38:36 -07:00
Nicolas Gallagher
6b55032e49 Reorganize docs; rewrite README 2015-09-03 19:38:21 -07:00
Nicolas Gallagher
77f73a8929 Reorganize modules 2015-09-03 19:37:20 -07:00
Nicolas Gallagher
f951de43a2 Move config files 2015-09-03 19:36:43 -07:00
Nicolas Gallagher
fb7a997256 Add 'Image' tests 2015-09-02 17:28:07 -07:00
Nicolas Gallagher
1417dd2e6a Install eslint and fix code style 2015-09-02 17:15:05 -07:00
Nicolas Gallagher
ff5c8f64cc Text tests 2015-09-01 16:45:11 -07:00
Nicolas Gallagher
653cfd71ce View tests 2015-09-01 16:45:00 -07:00
Nicolas Gallagher
95d6b98e9d Add tests for 'filterObjectProps' 2015-09-01 14:44:59 -07:00
Nicolas Gallagher
92dbadacb5 Initial test framework setup 2015-09-01 14:44:42 -07:00
Nicolas Gallagher
d3dce675df Reduce size of API; remove helpers 2015-09-01 14:43:05 -07:00
Nicolas Gallagher
000bbf9f93 Simplify organization of react-native-web-style 2015-09-01 14:07:38 -07:00
Nicolas Gallagher
9d424fa529 Update docs 2015-08-19 14:28:26 -07:00
Nicolas Gallagher
344239bd8a Export the styling strategy 2015-08-19 14:28:17 -07:00
Nicolas Gallagher
8ec27cefab Add more opacity values 2015-08-19 14:27:46 -07:00
Nicolas Gallagher
ecc23f46d4 Move all style related work into 'react-web-style'
Move the styling strategy into a separate module within react-web-style;
consider supporting strategy injection.
2015-08-19 14:07:57 -07:00
Nicolas Gallagher
39088affbc Add TextInput to example 2015-08-17 13:46:28 -07:00
Nicolas Gallagher
5494a8e191 add(TextInput): initial implementation 2015-08-17 13:46:11 -07:00
Nicolas Gallagher
95b1af9f1f Update default styles 2015-08-17 13:45:36 -07:00
Nicolas Gallagher
1f3ac7a7b8 fix(StylePropTypes): add missing values and props 2015-08-17 13:15:09 -07:00
Nicolas Gallagher
d86c2f4840 change(babelrc): add es7.classProperties 2015-08-17 13:13:43 -07:00
Nicolas Gallagher
89202e51f6 0.0.3 2015-07-05 15:23:41 -07:00
Nicolas Gallagher
36b6bd05af Remove unused import 2015-07-05 15:23:00 -07:00
86 changed files with 1798 additions and 1085 deletions

View File

@@ -1,5 +1,6 @@
{
"optional": [
"es7.classProperties",
"runtime"
],
"stage": 1

3
.eslintignore Normal file
View File

@@ -0,0 +1,3 @@
dist
docs
example

17
.eslintrc Normal file
View File

@@ -0,0 +1,17 @@
{
// babel parser to support ES features
"parser": "babel-eslint",
// based on https://github.com/feross/standard
"extends": [ "standard", "standard-react" ],
"env": {
"mocha": true
},
"rules": {
// overrides of the standard style
"space-before-function-paren": [ 2, { "anonymous": "always", "named": "never" } ],
"wrap-iife": [ 2, "outside" ],
// overrides of the standard-react style
"react/jsx-sort-props": 2,
"react/jsx-sort-prop-types": 2
}
}

3
.travis.yml Normal file
View File

@@ -0,0 +1,3 @@
language: node_js
node_js:
- "0.12"

125
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,125 @@
# Contributing to this project
The issue tracker is the preferred channel for [bug reports](#bugs),
[features requests](#features) and [submitting pull
requests](#pull-requests).
<a name="bugs"></a>
## Bug reports
A bug is a _demonstrable problem_ that is caused by the code in the repository.
Good bug reports are extremely helpful - thank you!
Guidelines for bug reports:
1. **Use the GitHub issue search** &mdash; check if the issue has already been
reported.
2. **Check if the issue has been fixed** &mdash; try to reproduce it using the
latest `master` or development branch in the repository.
3. **Isolate the problem** &mdash; create a [reduced test
case](http://css-tricks.com/reduced-test-cases/) and a live example.
A good bug report contains as much detail as possible. What is your
environment? What steps will reproduce the issue? What browser(s) and OS
experience the problem? What would you expect to be the outcome? All these
details really help!
Example:
> Short and descriptive example bug report title
>
> A summary of the issue and the browser/OS environment in which it occurs. If
> suitable, include the steps required to reproduce the bug.
>
> 1. This is the first step
> 2. This is the second step
> 3. Further steps, etc.
>
> `<url>` - a link to the reduced test case
>
> Any other information you want to share that is relevant to the issue being
> reported. This might include the lines of code that you have identified as
> causing the bug, and potential solutions (and your opinions on their
> merits).
<a name="features"></a>
## Feature requests
Feature requests are welcome. But take a moment to find out whether your idea
fits with the scope and aims of the project. It's up to *you* to make a strong
case to convince the project's developers of the merits of this feature. Please
provide as much detail and context as possible.
<a name="pull-requests"></a>
## Pull requests
Good pull requests - patches, improvements, new features - are a fantastic
help. Please keep them focused in scope and avoid containing unrelated commits.
**Please ask first** before embarking on any significant pull request (e.g.
implementing new features or components, refactoring code), otherwise you risk
spending a lot of time working on something that the project's developers might
not want to merge into the project.
Development commands:
* `npm start` start the dev server and develop against live examples
* `npm run lint` run the linter
* `npm run specs` run the unit tests
* `npm run build` generate a build
Please follow this process for submitting a patch:
1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork,
and configure the remotes:
```bash
# Clone your fork of the repo into the current directory
git clone https://github.com/<your-username>/react-native-web
# Navigate to the newly cloned directory
cd react-native-web
# Assign the original repo to a remote called "upstream"
git remote add upstream https://github.com/necolas/react-native-web
```
2. If you cloned a while ago, get the latest changes from upstream:
```bash
git checkout master
git pull upstream master
```
3. Create a new topic branch (off the main project development branch) to
contain your feature, change, or fix:
```bash
git checkout -b <topic-branch-name>
```
4. Commit your changes in logical chunks. Please adhere to these [git commit
message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
or your code is unlikely be merged into the main project. Use Git's
[interactive rebase](https://help.github.com/articles/interactive-rebase)
feature to tidy up your commits before making them public.
5. Locally merge (or rebase) the upstream development branch into your topic branch:
```bash
git pull [--rebase] upstream master
```
6. Push your topic branch up to your fork:
```bash
git push origin <topic-branch-name>
```
7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
with a clear title and description.
**IMPORTANT**: By submitting a patch, you agree to allow the project owner to
license your work under the same license as that used by the project.

21
LICENCE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Nicolas Gallagher
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

213
README.md
View File

@@ -1,102 +1,123 @@
# react-web-sdk
# React Native for Web
**Experimental / Proof of concept**
[![Build Status][travis-image]][travis-url]
[![npm version][npm-image]][npm-url] (14 KB gzipped)
A React SDK (~9KB gzipped) for creating web applications and toolkits. Inspired by `react-native`.
The core [React Native][react-native-url] components built for the web, backed
by a precomputed CSS library.
It includes the following components:
## Table of contents
* `View`: a flexbox primitive
* `Text`: a text primitive
* `Image`: an image primitive
* (`Component`: base / implementation)
* [Install](#install)
* [Use](#use)
* [Components](#components)
* [Styling](#styling)
* [Contributing](#contributing)
* [Thanks](#thanks)
* [License](#license)
And uses a [styling strategy](docs/styling-strategy.md) that maps inline styles
to single-purpose CSS rules.
## Install
This proof of concept uses a CSS bundle (~4.5KB gzipped) of 300+ precomputed
declarations. A more sophisticated implementation is likely to produce a
slightly larger CSS file and fewer inline styles.
```
npm install --save react react-native-web
```
## Use
React Native for Web exports its components and a reference to the `React`
installation. Styles are authored in JavaScript as plain objects.
```js
import React, { View } from 'react-native-web'
class MyComponent extends React.Component {
render() {
return (
<View style={styles.root} />
)
}
}
const styles = {
root: {
borderColor: 'currentcolor'
borderWidth: '5px',
flexDirection: 'row'
height: '5em'
}
}
```
## Components
All components define explicit `style` PropTypes according to the [`StyleProp`
spec](docs/StyleProp.spec.md).
Partial implementations of…
### Component
TODO
[`Component`](docs/Component.md)
### View
TODO
A flexbox container; foundational layout building block.
[`View` spec](docs/View.spec.md)
See this [guide to flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/).
### Text
TODO
[`Text` spec](docs/View.spec.md)
### Image
TODO
[`Image` spec](docs/View.spec.md)
* [`Image`](docs/components/Image.md)
* [`Text`](docs/components/Text.md)
* [`TextInput`](docs/components/TextInput.md)
* [`View`](docs/components/View.md)
## Styling
React Native Web provides a mechanism to declare all your styles and layout
inline with the components that use them. The `View` component makes it easy
to build common layouts with flexbox, such as stacked and nested boxes with
margin and padding.
Styling is identical to using inline styles in React, but most inline styles
are converted to unique CSS classes. **This is only true for the SDK
components**.
are converted to single-purpose classes. The current implementation includes
300+ precomputed CSS declarations (~4.5KB gzipped) that cover a large
proportion of common styles. A more sophisticated build-time implementation may
produce a slightly larger CSS file for large apps, and fall back to fewer
inline styles. Read more about the [styling
strategy](docs/react-native-web-style/styling.md).
The companion stylesheet can be referenced as an external resource, inlined, or
injected by JS.
See the [styling strategy docs](docs/styling-strategy.md) for more details.
### Use plain JavaScript objects
Use JavaScript to write style definitions in React components:
See this [guide to flexbox][flexbox-guide-url].
```js
const style = {
common: {
backgroundColor: 'white',
borderRadius: '1em'
},
root: {
flexDirection: 'row',
justifyContent: 'space-between'
},
image: {
opacity: 0.5
},
text: {
fontWeight: '300'
}
};
```
import React, { Image, Text, View } from 'react-native-web'
### Use the `style` attribute
The `style` attribute is a simple API for creating element-scoped styles.
```js
import {View} from 'react-web-sdk';
class Example extends React.Component {
class App extends React.Component {
render() {
return (
<View style={style.root}>...</View>
);
<View style={styles.row}>
<Image
source={{ uri: 'http://facebook.github.io/react/img/logo_og.png' }}
style={styles.image}
/>
<View style={styles.text}>
<Text style={styles.title}>
React Native Web
</Text>
<Text style={styles.subtitle}>
Build high quality web apps using React
</Text>
</View>
</View>
)
},
})
const styles = {
row: {
flexDirection: 'row',
margin: 40
},
image: {
height: 40,
marginRight: 10,
width: 40,
},
text: {
flex: 1,
justifyContent: 'center'
},
title: {
fontSize: '1.25rem',
fontWeight: 'bold'
},
subtitle: {
fontSize: '1rem'
}
}
```
@@ -104,7 +125,7 @@ class Example extends React.Component {
Combine and override style objects:
```js
import baseStyle from './baseStyle';
import baseStyle from './baseStyle'
const buttonStyle = {
...baseStyle,
@@ -113,25 +134,25 @@ const buttonStyle = {
}
```
## Utilities
## Contributing
#### `getOtherProps(reactComponentInstance)`
Please read the [contribution guidelines][contributing-url]. Contributions are
welcome!
Returns an object containing all the props from `this.props` that are not
defined in `propTypes`.
## Thanks
#### `omitProps(obj, arrayOfExcludedProps)`
Thanks to current and past members of the React and React Native teams (in
particular Vjeux and Pete Hunt), and Tobias Koppers for Webpack and CSS loader.
Returns an object with the specified props excluded.
## License
#### `pickProps(obj, arrayOfIncludedProps)`
Copyright (c) 2015 Nicolas Gallagher. Released under the [MIT
license](http://www.opensource.org/licenses/mit-license.php).
Returns an object with the specified props included.
## Development
```
npm install
npm run build:example:watch
open example/index.html
```
[contributing-url]: https://github.com/necolas/react-native-web/blob/master/CONTRIBUTING.md
[flexbox-guide]: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
[npm-image]: https://img.shields.io/npm/v/react-native-web.svg
[npm-url]: https://npmjs.org/package/react-native-web
[react-native-url]: https://facebook.github.io/react-native/
[travis-image]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
[travis-url]: https://travis-ci.org/necolas/react-native-web

45
config/karma.config.js Normal file
View File

@@ -0,0 +1,45 @@
var assign = require('object-assign')
var path = require('path')
var webpackConfig = require('./webpack-base.config.js')
module.exports = function (config) {
config.set({
basePath: path.resolve(__dirname, '..'),
browsers: [ 'Chrome' ],
browserNoActivityTimeout: 60000,
client: {
captureConsole: true,
mocha: {
ui: 'tdd'
},
useIframe: true
},
files: [
'src/specs.bundle.js'
],
frameworks: [
'mocha'
],
plugins: [
'karma-chrome-launcher',
'karma-mocha',
'karma-sourcemap-loader',
'karma-webpack'
],
preprocessors: {
'src/specs.bundle.js': [ 'webpack', 'sourcemap' ]
},
reporters: [ 'dots' ],
singleRun: true,
webpack: assign({}, webpackConfig, { devtool: 'inline' }),
webpackMiddleware: {
stats: {
assetsSort: 'name',
colors: true,
children: false,
chunks: false,
modules: false
}
}
})
}

View File

@@ -0,0 +1,23 @@
var autoprefixer = require('autoprefixer-core')
module.exports = {
module: {
loaders: [
{
test: /\.css$/,
loader: [
'style-loader',
'css-loader?module&localIdentName=[hash:base64:5]',
'!postcss-loader'
].join('!')
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: { cacheDirectory: true }
}
]
},
postcss: [ autoprefixer ]
}

29
config/webpack.config.js Normal file
View File

@@ -0,0 +1,29 @@
var assign = require('object-assign')
var base = require('./webpack-base.config.js')
var webpack = require('webpack')
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin
module.exports = assign({}, base, {
entry: {
main: './src/index'
},
externals: [{
react: true
}],
output: {
filename: 'react-native-web.js',
library: 'ReactNativeWeb',
libraryTarget: 'commonjs2',
path: './dist'
},
plugins: [
new UglifyJsPlugin({
compress: {
dead_code: true,
drop_console: true,
screw_ie8: true,
warnings: true
}
})
]
})

View File

@@ -1,44 +0,0 @@
# `Component`
This component is part of the implementation for managing styles across the
`className` and `style` properties. It is the building block upon which all
other components in `react-web-sdk` are built.
## PropTypes
All other props are transferred directly to the `element`.
+ `element`: `func` or `string`
+ `style`: `object`
#### Examples
```js
import {Component, pickProps} from 'react-web-sdk';
import React, {PropTypes} from 'react';
const ExampleStylePropTypes = { opacity: PropTypes.number };
const ExampleStyleDefaultProps = { opacity: 1 };
class Example extends React.Component {
static propTypes = {
style: PropTypes.shape(ExampleStylePropTypes)
}
render() {
const { style, ...other } = this.props;
// only apply supported styles
const supportedStyle = pickProps(style, ExampleStylePropTypes);
// merge with default styles
const mergedStyle = { ...ExampleStyleDefaultProps, ...supportedStyle }
return (
<Component
...other
element="main"
style={mergedStyle}
/>
);
}
}
```

View File

@@ -1,4 +1,4 @@
# View spec
# View
`View` is a flexbox container and the fundamental building block for UI. It is
designed to be nested inside other `View`'s and to have 0-to-many children of
@@ -8,7 +8,7 @@ any type.
All other props are transferred directly to the `element`.
+ `element`: `func` or `string` (default `"div"`)
+ `component`: `func` or `string` (default `"div"`)
+ `pointerEvents`: `oneOf('all', 'box-only', 'box-none', 'none')`
+ `style`: `ViewStylePropTypes`
@@ -43,7 +43,7 @@ Implements the default styles from
`right`, `bottom` do something when not specifying `position:absolute`.
```js
const ViewStyleDefaultProps = {
const ViewDefaultStyle = {
alignItems: 'stretch', // 1
borderWidth: 0,
borderStyle: 'solid',

View File

@@ -0,0 +1,15 @@
# TextInput spec
Text input layout and styles.
#### PropTypes
All other props are transferred directly to the `element`.
+ `component`: `func` or `string` (default `"div"`)
+ `style`: `TextStylePropTypes`
#### TextStylePropTypes
+ ViewStylePropTypes
+ TypographicPropTypes

66
docs/components/View.md Normal file
View File

@@ -0,0 +1,66 @@
# View spec
`View` is a flexbox container and the fundamental building block for UI. It is
designed to be nested inside other `View`'s and to have 0-to-many children of
any type.
## PropTypes
All other props are transferred directly to the `element`.
+ `element`: `func` or `string` (default `"div"`)
+ `pointerEvents`: `oneOf('all', 'box-only', 'box-none', 'none')`
+ `style`: `ViewStylePropTypes`
## ViewStylePropTypes
+ BackgroundPropTypes
+ BorderThemePropTypes
+ LayoutPropTypes
+ `boxShadow`: `string`
+ `color`: `string`
+ `opacity`: `number`
## ViewStyleDefaultProps
Implements the default styles from
[facebook/css-layout](https://github.com/facebook/css-layout).
1. All the flex elements are oriented from top-to-bottom, left-to-right and do
not shrink. This is how things are laid out using the default CSS settings
and what you'd expect.
2. The most convenient way to express the relation between width and other
box-model properties.
3. Everything is `display:flex` by default. All the behaviors of `block` and
`inline-block` can be expressed in term of flex but not the opposite.
4. Everything is `position:relative`. This makes `position:absolute` target the
direct parent and not some parent which is either relative or absolute. If
you want to position an element relative to something else, you should move
it in the DOM instead of relying of CSS. It also makes `top`, `left`,
`right`, `bottom` do something when not specifying `position:absolute`.
```js
const ViewStyleDefaultProps = {
alignItems: 'stretch', // 1
borderWidth: 0,
borderStyle: 'solid',
boxSizing: 'border-box', // 2
display: 'flex', // 3
flexBasis: 'auto', // 1
flexDirection: 'column', // 1
flexShrink: 0, // 1
listStyle: 'none',
margin: 0,
padding: 0,
position: 'relative' // 4
};
```
## Examples
```js
// TODO
```

View File

@@ -49,7 +49,7 @@ const styles = Stylesheet.create({
One strategy for converting styles from JS to CSS is to map style objects to
CSS rules. Another strategy is to map declarations to declarataions.
![](sdk-styling-strategy.png)
![](../static/styling-strategy.png)
Mapping entire `style` objects to CSS rules can lead to increasingly large CSS
files. Each new component adds new rules to the stylesheet.

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { Image, Text, View } from '../dist/main';
import React, { Image, Text, TextInput, View } from '../dist/react-native-web';
class Example extends React.Component {
render() {
@@ -24,6 +23,9 @@ class Example extends React.Component {
}}>
<Text>This should be centered</Text>
</View>
<TextInput type="text" autoFocus />
<TextInput multiline defaultValue="default value" />
</View>
);
}

View File

@@ -1,6 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../dist/react-web-sdk.css">
<div id="react-root"></div>
<script src="../dist/example.js"></script>

View File

@@ -1,37 +1,53 @@
{
"name": "react-web-sdk",
"version": "0.0.2",
"description": "UI SDK based on react-native",
"main": "dist/main.js",
"name": "react-native-web",
"version": "0.0.4",
"description": "React Native for Web",
"main": "dist/react-native-web.js",
"files": [
"dist"
],
"scripts": {
"prebuild": "rm -rf ./dist && npm install",
"build": "webpack --config webpack.config.js",
"build:watch": "npm run build -- --watch",
"build:example": "npm run build && cd example && webpack --config ./webpack.config.js",
"build:example:watch": "npm run build:example -- --watch"
"prepublish": "NODE_ENV=production npm run build",
"build": "rm -rf ./dist && webpack --config config/webpack.config.js --sort-assets-by --progress",
"lint": "eslint .",
"specs": "NODE_ENV=test karma start config/karma.config.js",
"specs:watch": "npm run specs -- --no-single-run",
"start": "webpack-dev-server --config config/webpack.config.js --inline --hot --colors --quiet",
"test": "npm run specs && npm run lint"
},
"dependencies": {
"react": "^0.13.3"
},
"devDependencies": {
"autoprefixer-core": "^5.2.0",
"babel-core": "^5.5.6",
"babel-loader": "^5.1.4",
"babel-runtime": "^5.5.6",
"css-loader": "^0.15.1",
"extract-text-webpack-plugin": "^0.8.1",
"autoprefixer-core": "^5.2.1",
"babel-core": "^5.8.23",
"babel-eslint": "^4.1.1",
"babel-loader": "^5.3.2",
"babel-runtime": "^5.8.20",
"css-loader": "^0.17.0",
"eslint": "^1.3.1",
"eslint-config-standard": "^4.3.1",
"eslint-config-standard-react": "^1.0.4",
"eslint-plugin-react": "^3.3.1",
"eslint-plugin-standard": "^1.3.0",
"extract-text-webpack-plugin": "^0.8.2",
"karma": "^0.13.9",
"karma-chrome-launcher": "^0.2.0",
"karma-mocha": "^0.2.0",
"karma-sourcemap-loader": "^0.3.5",
"karma-webpack": "^1.7.0",
"mocha": "^2.3.0",
"node-libs-browser": "^0.5.2",
"object-assign": "^4.0.1",
"postcss-loader": "^0.4.4",
"style-loader": "^0.12.3",
"webpack": "^1.9.10"
"webpack": "^1.12.1",
"webpack-dev-server": "^1.10.1"
},
"author": "Nicolas Gallagher",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/necolas/react-web-sdk.git"
"url": "git://github.com/necolas/react-native-web.git"
}
}

View File

@@ -1,17 +1,16 @@
import { getOtherProps, omitProps, pickProps } from './modules/filterObjectProps';
import WebStyleComponent from './modules/WebStyleComponent';
import StylePropTypes from './modules/StylePropTypes';
import Image from './modules/Image';
import Text from './modules/Text';
import View from './modules/View';
import React from 'react'
export default {
getOtherProps,
omitProps,
pickProps,
StylePropTypes,
WebStyleComponent,
// components
import Image from './modules/Image'
import Text from './modules/Text'
import TextInput from './modules/TextInput'
import View from './modules/View'
export default React
export {
Image,
Text,
TextInput,
View
};
}

View File

@@ -0,0 +1,17 @@
import { StylePropTypes } from '../react-native-web-style'
import { PropTypes } from 'react'
export default {
...StylePropTypes.BorderThemePropTypes,
...StylePropTypes.LayoutPropTypes,
backgroundColor: PropTypes.string,
boxShadow: PropTypes.string,
opacity: PropTypes.number,
transform: PropTypes.string
}
export const ImageDefaultStyle = {
backgroundColor: 'lightGray',
borderWidth: 0,
maxWidth: '100%'
}

View File

@@ -1,61 +1,38 @@
import { pickProps } from '../filterObjectProps';
import StylePropTypes from '../StylePropTypes';
import React, { PropTypes } from 'react';
import WebStyleComponent from '../WebStyleComponent';
const ImageStyleDefaultProps = {
backgroundColor: 'lightGray',
borderWidth: 0,
maxWidth: '100%'
};
const ImageStylePropTypes = {
...StylePropTypes.BorderThemePropTypes,
...StylePropTypes.LayoutPropTypes,
backgroundColor: PropTypes.string,
opacity: PropTypes.string
};
import { pickProps } from '../filterObjectProps'
import { WebStyleComponent } from '../react-native-web-style'
import ImageStylePropTypes, { ImageDefaultStyle } from './ImageStylePropTypes'
import React, { PropTypes } from 'react'
class Image extends React.Component {
static _getPropTypes() {
return {
alt: PropTypes.string,
async: PropTypes.bool,
className: PropTypes.string,
src: PropTypes.string,
style: PropTypes.shape(ImageStylePropTypes)
};
static propTypes = {
accessibilityLabel: PropTypes.string,
className: PropTypes.string,
source: PropTypes.object,
style: PropTypes.shape(ImageStylePropTypes)
}
static _getDefaultProps() {
return {
async: true,
className: '',
src: 'data:image/gif;base64,' +
'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
style: {}
};
static defaultProps = {
className: '',
source: 'data:image/gif;base64,' +
'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
}
render() {
const { alt, className, src, style, ...other } = this.props;
const filteredStyle = pickProps(style, Object.keys(ImageStylePropTypes));
const mergedStyle = { ...ImageStyleDefaultProps, ...filteredStyle };
const { accessibilityLabel, className, source, style, ...other } = this.props
const filteredStyle = pickProps(style, Object.keys(ImageStylePropTypes))
const mergedStyle = { ...ImageDefaultStyle, ...filteredStyle }
return (
<WebStyleComponent
{...other}
alt={alt}
alt={accessibilityLabel}
className={`Image ${className}`}
element="img"
src={src}
component='img'
src={source.uri}
style={mergedStyle}
/>
);
)
}
}
Image.propTypes = Image._getPropTypes();
Image.defaultProps = Image._getDefaultProps();
export default Image;
export default Image

View File

@@ -0,0 +1,64 @@
import assert from 'assert'
import React from 'react/addons'
import { ImageDefaultStyle } from './ImageStylePropTypes'
import Image from '.'
const ReactTestUtils = React.addons.TestUtils
function shallowRender(component, context = {}) {
const shallowRenderer = React.addons.TestUtils.createRenderer()
shallowRenderer.render(component, context)
return shallowRenderer.getRenderOutput()
}
suite('Image', () => {
test('defaults', () => {
const result = ReactTestUtils.renderIntoDocument(<Image />)
const root = React.findDOMNode(result)
assert.equal((root.tagName).toLowerCase(), 'img')
})
test('prop "accessibilityLabel"', () => {
const label = 'accessibilityLabel'
const result = ReactTestUtils.renderIntoDocument(<Image accessibilityLabel={label} />)
const root = React.findDOMNode(result)
assert.equal(root.getAttribute('alt'), label)
})
test('prop "className"', () => {
const className = 'className'
const result = shallowRender(<Image className={className} />)
assert.ok(
(result.props.className).indexOf(className) > -1,
'"className" was not transferred'
)
})
test('prop "source"', () => {
const source = { uri: 'path-to-image' }
const result = ReactTestUtils.renderIntoDocument(<Image source={source} />)
const root = React.findDOMNode(result)
assert.equal(root.getAttribute('src'), source.uri)
})
test('prop "style"', () => {
const initial = shallowRender(<Image />)
assert.deepEqual(
initial.props.style,
ImageDefaultStyle,
'default "style" is incorrect'
)
const unsupported = shallowRender(<Image style={{ unsupported: 'true' }} />)
assert.deepEqual(
unsupported.props.style.unsupported,
null,
'unsupported "style" properties must not be transferred'
)
})
})

View File

@@ -1,9 +0,0 @@
import BoxModel from './BoxModel';
import Flexbox from './Flexbox';
import Position from './Position';
export default {
...BoxModel,
...Flexbox,
...Position
};

View File

@@ -1,30 +0,0 @@
import {PropTypes} from 'react';
export default {
direction: PropTypes.oneOf([
'auto', 'ltr', 'rtl'
]),
fontFamily: PropTypes.string,
fontSize: PropTypes.string,
fontWeight: PropTypes.oneOf([
'100', '200', '300', '400', '500', '600', '700', '800', '900',
'bold', 'normal'
]),
fontStyle: PropTypes.oneOf([
'normal', 'italic'
]),
letterSpacing: PropTypes.string,
lineHeight: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
textAlign: PropTypes.oneOf([
'auto', 'left', 'right', 'center'
]),
textDecoration: PropTypes.oneOf([
'none', 'underline'
]),
textTransform: PropTypes.oneOf([
'capitalize', 'lowercase', 'none', 'uppercase'
]),
wordWrap: PropTypes.oneOf([
'break-word', 'normal'
])
};

View File

@@ -1,13 +0,0 @@
import BackgroundPropTypes from './Background';
import BorderThemePropTypes from './BorderTheme';
import FlexboxPropTypes from './Flexbox';
import LayoutPropTypes from './Layout';
import TypographicPropTypes from './Typographic';
export default {
BackgroundPropTypes,
BorderThemePropTypes,
FlexboxPropTypes,
LayoutPropTypes,
TypographicPropTypes
};

View File

@@ -0,0 +1,11 @@
import { StylePropTypes } from '../react-native-web-style'
import { ViewStylePropTypes } from '../View/ViewStylePropTypes'
export default {
...ViewStylePropTypes,
...StylePropTypes.TypographicPropTypes
}
export const TextDefaultStyle = {
display: 'inline'
}

View File

@@ -1,52 +1,28 @@
import { pickProps } from '../filterObjectProps';
import { ViewStylePropTypes } from '../View';
import StylePropTypes from '../StylePropTypes';
import React, { PropTypes } from 'react';
import WebStyleComponent from '../WebStyleComponent';
const TextStyleDefaultProps = {
alignItems: 'stretch', /* 1 */
borderWidth: '0',
borderStyle: 'solid',
boxSizing: 'border-box', /* 2 */
display: 'flex', /* 3 */
flexBasis: 'auto', /* 1 */
flexDirection: 'column', /* 1 */
flexShrink: 0, /* 1 */
listStyle: 'none',
margin: '0',
padding: '0',
position: 'relative' /* 4 */
};
const TextStylePropTypes = {
...ViewStylePropTypes,
...StylePropTypes.TypographicPropTypes
};
import { pickProps } from '../filterObjectProps'
import { WebStyleComponent } from '../react-native-web-style'
import React, { PropTypes } from 'react'
import TextStylePropTypes, { TextDefaultStyle } from './TextStylePropTypes'
class Text extends React.Component {
static _getPropTypes() {
return {
className: PropTypes.string,
element: PropTypes.oneOfType([
PropTypes.string, PropTypes.func
]),
style: PropTypes.shape(TextStylePropTypes)
};
static propTypes = {
children: PropTypes.any,
className: PropTypes.string,
component: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string
]),
style: PropTypes.shape(TextStylePropTypes)
}
static _getDefaultProps() {
return {
className: '',
element: 'div',
style: {}
};
static defaultProps = {
className: '',
component: 'span'
}
render() {
const { className, style, ...other } = this.props;
const filteredStyle = pickProps(style, Object.keys(TextStylePropTypes));
const mergedStyle = { ...TextStyleDefaultProps, ...filteredStyle };
const { className, style, ...other } = this.props
const filteredStyle = pickProps(style, Object.keys(TextStylePropTypes))
const mergedStyle = { ...TextDefaultStyle, ...filteredStyle }
return (
<WebStyleComponent
@@ -54,12 +30,8 @@ class Text extends React.Component {
className={`Text ${className}`}
style={mergedStyle}
/>
);
)
}
}
Text.propTypes = Text._getPropTypes();
Text.defaultProps = Text._getDefaultProps();
export default Text;
export { TextStylePropTypes };
export default Text

View File

@@ -0,0 +1,67 @@
import assert from 'assert'
import React from 'react/addons'
import { TextDefaultStyle } from './TextStylePropTypes'
import Text from '.'
const ReactTestUtils = React.addons.TestUtils
function shallowRender(component, context = {}) {
const shallowRenderer = React.addons.TestUtils.createRenderer()
shallowRenderer.render(component, context)
return shallowRenderer.getRenderOutput()
}
suite('Text', () => {
test('defaults', () => {
const result = ReactTestUtils.renderIntoDocument(<Text />)
const root = React.findDOMNode(result)
assert.equal((root.tagName).toLowerCase(), 'span')
})
test('prop "children"', () => {
const children = 'children'
const result = shallowRender(<Text>{children}</Text>)
assert.equal(result.props.children, children)
})
test('prop "className"', () => {
const className = 'className'
const result = shallowRender(<Text className={className} />)
assert.ok(
(result.props.className).indexOf(className) > -1,
'"className" was not transferred'
)
})
test('prop "component"', () => {
const type = 'a'
const result = ReactTestUtils.renderIntoDocument(<Text component={type} />)
const root = React.findDOMNode(result)
assert.equal(
(root.tagName).toLowerCase(),
type,
'"component" did not produce the correct DOM node type'
)
})
test('prop "style"', () => {
const initial = shallowRender(<Text />)
assert.deepEqual(
initial.props.style,
TextDefaultStyle,
'default "style" is incorrect'
)
const unsupported = shallowRender(<Text style={{ unsupported: 'true' }} />)
assert.deepEqual(
unsupported.props.style.unsupported,
null,
'unsupported "style" properties must not be transferred'
)
})
})

View File

@@ -0,0 +1,13 @@
import { StylePropTypes } from '../react-native-web-style'
import ViewStylePropTypes from '../View/ViewStylePropTypes'
export default {
...ViewStylePropTypes,
...StylePropTypes.TypographicPropTypes
}
export const TextInputDefaultStyles = {
background: 'transparent',
color: 'inherit',
font: 'inherit'
}

View File

@@ -0,0 +1,38 @@
import { pickProps } from '../filterObjectProps'
import { WebStyleComponent } from '../react-native-web-style'
import React, { PropTypes } from 'react'
import TextInputStylePropTypes, { TextInputDefaultStyles } from './TextInputStylePropTypes'
class TextInput extends React.Component {
static propTypes = {
className: PropTypes.string,
editable: PropTypes.bool,
multiline: PropTypes.bool,
placeholder: PropTypes.string,
style: PropTypes.shape(TextInputStylePropTypes)
}
static defaultProps = {
editable: true,
multiline: false
}
render() {
const { className, editable, multiline, placeholder, style, ...other } = this.props
const filteredStyle = pickProps(style, Object.keys(TextInputStylePropTypes))
const mergedStyle = { ...TextInputDefaultStyles, ...filteredStyle }
return (
<WebStyleComponent
{...other}
className={`TextInput ${className}`}
component={multiline ? 'textarea' : 'input'}
disabled={!editable}
placeholder={placeholder}
style={mergedStyle}
/>
)
}
}
export default TextInput

View File

@@ -0,0 +1,27 @@
import { PropTypes } from 'react'
import { StylePropTypes } from '../react-native-web-style'
export default {
...StylePropTypes.BackgroundPropTypes,
...StylePropTypes.BorderThemePropTypes,
...StylePropTypes.LayoutPropTypes,
boxShadow: PropTypes.string,
opacity: PropTypes.number,
transform: PropTypes.string
}
// https://github.com/facebook/css-layout#default-values
export const ViewDefaultStyle = {
alignItems: 'stretch',
borderWidth: 0,
borderStyle: 'solid',
boxSizing: 'border-box',
display: 'flex',
flexBasis: 'auto',
flexDirection: 'column',
flexShrink: 0,
listStyle: 'none',
margin: 0,
padding: 0,
position: 'relative'
}

View File

@@ -1,81 +1,48 @@
import { pickProps } from '../filterObjectProps';
import StylePropTypes from '../StylePropTypes';
import React, { PropTypes } from 'react';
import WebStyleComponent from '../WebStyleComponent';
// https://github.com/facebook/css-layout#default-values
const ViewStyleDefaultProps = {
alignItems: 'stretch',
borderWidth: 0,
borderStyle: 'solid',
boxSizing: 'border-box',
display: 'flex',
flexBasis: 'auto',
flexDirection: 'column',
flexShrink: 0,
listStyle: 'none',
margin: 0,
padding: 0,
position: 'relative'
};
const ViewStylePropTypes = {
...StylePropTypes.BackgroundPropTypes,
...StylePropTypes.BorderThemePropTypes,
...StylePropTypes.LayoutPropTypes,
boxShadow: PropTypes.string,
opacity: PropTypes.number,
transform: PropTypes.string
};
import { pickProps } from '../filterObjectProps'
import { WebStyleComponent } from '../react-native-web-style'
import React, { PropTypes } from 'react'
import ViewStylePropTypes, { ViewDefaultStyle } from './ViewStylePropTypes'
class View extends React.Component {
static _getPropTypes() {
return {
className: PropTypes.string,
element: PropTypes.oneOfType([
PropTypes.string, PropTypes.func
]),
pointerEvents: PropTypes.oneOf([
'auto',
'box-none',
'box-only',
'none'
]),
style: PropTypes.shape(ViewStylePropTypes)
};
static propTypes = {
children: PropTypes.any,
className: PropTypes.string,
component: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string
]),
pointerEvents: PropTypes.oneOf([
'auto',
'box-none',
'box-only',
'none'
]),
style: PropTypes.shape(ViewStylePropTypes)
}
static _getDefaultProps() {
return {
className: '',
element: 'div',
style: {}
};
static defaultProps = {
className: '',
component: 'div'
}
render() {
const { className, element, pointerEvents, style, ...other } = this.props;
const filteredStyle = pickProps(style, Object.keys(ViewStylePropTypes));
const pointerEventsStyle = pointerEvents && { pointerEvents };
const { className, pointerEvents, style, ...other } = this.props
const filteredStyle = pickProps(style, Object.keys(ViewStylePropTypes))
const pointerEventsStyle = pointerEvents && { pointerEvents }
const mergedStyle = {
...ViewStyleDefaultProps,
...ViewDefaultStyle,
...filteredStyle,
...pointerEventsStyle
};
}
return (
<WebStyleComponent
{...other}
className={`View ${className}`}
element={element}
style={mergedStyle}
/>
);
)
}
}
View.propTypes = View._getPropTypes();
View.defaultProps = View._getDefaultProps();
export default View;
export { ViewStylePropTypes };
export default View

View File

@@ -0,0 +1,76 @@
import assert from 'assert'
import React from 'react/addons'
import { ViewDefaultStyle } from './ViewStylePropTypes'
import View from '.'
const ReactTestUtils = React.addons.TestUtils
function shallowRender(component, context = {}) {
const shallowRenderer = React.addons.TestUtils.createRenderer()
shallowRenderer.render(component, context)
return shallowRenderer.getRenderOutput()
}
suite('View', () => {
test('defaults', () => {
const result = ReactTestUtils.renderIntoDocument(<View />)
const root = React.findDOMNode(result)
assert.equal((root.tagName).toLowerCase(), 'div')
})
test('prop "children"', () => {
const children = 'children'
const result = shallowRender(<View>{children}</View>)
assert.equal(result.props.children, children)
})
test('prop "className"', () => {
const className = 'className'
const result = shallowRender(<View className={className} />)
assert.ok(
(result.props.className).indexOf(className) > -1,
'"className" was not transferred'
)
})
test('prop "component"', () => {
const type = 'a'
const result = ReactTestUtils.renderIntoDocument(<View component={type} />)
const root = React.findDOMNode(result)
assert.equal(
(root.tagName).toLowerCase(),
type,
'"component" did not produce the correct DOM node type'
)
})
test('prop "pointerEvents"', () => {
const result = shallowRender(<View pointerEvents='box-only' />)
assert.equal(
result.props.style.pointerEvents,
'box-only'
)
})
test('prop "style"', () => {
const initial = shallowRender(<View />)
assert.deepEqual(
initial.props.style,
ViewDefaultStyle,
'default "style" is incorrect'
)
const unsupported = shallowRender(<View style={{ unsupported: 'true' }} />)
assert.deepEqual(
unsupported.props.style.unsupported,
null,
'unsupported "style" properties must not be transferred'
)
})
})

View File

@@ -1,70 +0,0 @@
import autoprefix from './lib/autoprefix';
import React, {PropTypes} from 'react';
import styleMap from './lib/styleMap';
class WebStyleComponent extends React.Component {
static _getPropTypes() {
return {
className: PropTypes.string,
element: PropTypes.oneOfType([
PropTypes.string, PropTypes.func
]),
style: PropTypes.object
};
}
static _getDefaultProps() {
return {
className: '',
element: 'div',
style: {}
};
}
render() {
const { element: Element, ...other } = this.props;
const { classNames, inlineStyles } = this._separateClassNamesAndStyles();
return (
<Element
{...other}
className={classNames.join(' ')}
style={autoprefix(inlineStyles)}
/>
);
}
_getSinglePurposeClassName(prop, style) {
const uniqueClassName = `${prop}-${style[prop]}`;
if (
style.hasOwnProperty(prop) &&
styleMap[uniqueClassName]
) {
return styleMap[uniqueClassName];
}
}
_separateClassNamesAndStyles() {
const styleProp = this.props.style;
let classNames = [ this.props.className ];
let inlineStyles = {};
for (let prop in styleProp) {
let singlePurposeClassName =
this._getSinglePurposeClassName(prop, styleProp);
if (singlePurposeClassName) {
classNames.push(singlePurposeClassName);
} else {
inlineStyles[prop] = styleProp[prop];
}
}
return { classNames, inlineStyles };
}
}
WebStyleComponent.propTypes = WebStyleComponent._getPropTypes();
WebStyleComponent.defaultProps = WebStyleComponent._getDefaultProps();
export default WebStyleComponent;

View File

@@ -1 +0,0 @@
.appearance-none { appearance: none; }

View File

@@ -1,44 +0,0 @@
.backgroundAttachment-fixed { background-attachment: fixed; }
.backgroundAttachment-inherit { background-attachment: inherit; }
.backgroundAttachment-local { background-attachment: local; }
.backgroundAttachment-scroll { background-attachment: scroll; }
.backgroundClip-border-box { background-clip: border-box; }
.backgroundClip-content-box { background-clip: content-box; }
.backgroundClip-inherit { background-clip: inherit; }
.backgroundClip-padding-box { background-clip: padding-box; }
.backgroundColor-\#000,
.backgroundColor-black { background-color: black; }
.backgroundColor-\#fff,
.backgroundColor-white { background-color: white; }
.backgroundColor-currentcolor,
.backgroundColor-currentColor { background-color: currentcolor; }
.backgroundColor-inherit { background-color: inherit; }
.backgroundColor-transparent { background-color: transparent; }
.backgroundImage { background-image: none; }
.backgroundOrigin-border-box { background-clip: border-box; }
.backgroundOrigin-content-box { background-clip: content-box; }
.backgroundOrigin-inherit { background-clip: inherit; }
.backgroundOrigin-padding-box { background-clip: padding-box; }
.backgroundPosition-bottom { background-position: bottom; }
.backgroundPosition-center { background-position: center; }
.backgroundPosition-left { background-position: left; }
.backgroundPosition-right { background-position: right; }
.backgroundPosition-top { background-position: top; }
.backgroundRepeat-inherit { background-repeat: inherit; }
.backgroundRepeat-no-repeat { background-repeat: no-repeat; }
.backgroundRepeat-repeat { background-repeat: repeat; }
.backgroundRepeat-repeat-x { background-repeat: repeat-x; }
.backgroundRepeat-repeat-y { background-repeat: repeat-y; }
.backgroundRepeat-round { background-repeat: round; }
.backgroundRepeat-space { background-repeat: space; }
.backgroundSize-auto { background-size: auto; }
.backgroundSize-contain { background-size: contain; }
.backgroundSize-cover { background-size: cover; }
.backgroundSize-inherit { background-size: inherit; }

View File

@@ -1,100 +0,0 @@
/* border-color */
.borderColor-\#fff,
.borderColor-white { border-color: white; }
.borderColor-currentcolor { border-color: currentcolor; }
.borderColor-inherit { border-color: inherit; }
.borderColor-transparent { border-color: transparent; }
.borderBottomColor-\#fff,
.borderBottomColor-white { border-bottom-color: white; }
.borderBottomColor-currentcolor { border-bottom-color: currentcolor; }
.borderBottomColor-inherit { border-bottom-color: inherit; }
.borderBottomColor-transparent { border-bottom-color: transparent; }
.borderLeftColor-\#fff,
.borderLeftColor-white { border-left-color: white; }
.borderLeftColor-currentcolor { border-left-color: currentcolor; }
.borderLeftColor-inherit { border-left-color: inherit; }
.borderLeftColor-transparent { border-left-color: transparent; }
.borderRightColor-\#fff,
.borderRightColor-white { border-right-color: white; }
.borderRightColor-currentcolor { border-right-color: currentcolor; }
.borderRightColor-inherit { border-right-color: inherit; }
.borderRightColor-transparent { border-right-color: transparent; }
.borderTopColor-\#fff,
.borderTopColor-white { border-top-color: white; }
.borderTopColor-currentcolor { border-top-color: currentcolor; }
.borderTopColor-inherit { border-top-color: inherit; }
.borderTopColor-transparent { border-top-color: transparent; }
/* border-style */
.borderStyle-dashed { border-style: dashed; }
.borderStyle-dotted { border-style: dotted; }
.borderStyle-inherit { border-style: inherit; }
.borderStyle-none { border-style: none; }
.borderStyle-solid { border-style: solid; }
.borderBottomStyle-dashed { border-bottom-style: dashed; }
.borderBottomStyle-dotted { border-bottom-style: dotted; }
.borderBottomStyle-inherit { border-bottom-style: inherit; }
.borderBottomStyle-none { border-bottom-style: none; }
.borderBottomStyle-solid { border-bottom-style: solid; }
.borderLeftStyle-dashed { border-left-style: dashed; }
.borderLeftStyle-dotted { border-left-style: dotted; }
.borderLeftStyle-inherit { border-left-style: inherit; }
.borderLeftStyle-none { border-left-style: none; }
.borderLeftStyle-solid { border-left-style: solid; }
.borderRightStyle-dashed { border-right-style: dashed; }
.borderRightStyle-dotted { border-right-style: dotted; }
.borderRightStyle-inherit { border-right-style: inherit; }
.borderRightStyle-none { border-right-style: none; }
.borderRightStyle-solid { border-right-style: solid; }
.borderTopStyle-dashed { border-top-style: dashed; }
.borderTopStyle-dotted { border-top-style: dotted; }
.borderTopStyle-inherit { border-top-style: inherit; }
.borderTopStyle-none { border-top-style: none; }
.borderTopStyle-solid { border-top-style: solid; }
/* border-width */
.borderWidth-0 { border-width: 0; }
.borderWidth-1px { border-width: 1px; }
.borderWidth-2px { border-width: 2px; }
.borderWidth-3px { border-width: 3px; }
.borderWidth-4px { border-width: 4px; }
.borderWidth-5px { border-width: 5px; }
.borderBottomWidth-0 { border-bottom-width: 0; }
.borderBottomWidth-1px { border-bottom-width: 1px; }
.borderBottomWidth-2px { border-bottom-width: 2px; }
.borderBottomWidth-3px { border-bottom-width: 3px; }
.borderBottomWidth-4px { border-bottom-width: 4px; }
.borderBottomWidth-5px { border-bottom-width: 5px; }
.borderLeftWidth-0 { border-left-width: 0; }
.borderLeftWidth-1px { border-left-width: 1px; }
.borderLeftWidth-2px { border-left-width: 2px; }
.borderLeftWidth-3px { border-left-width: 3px; }
.borderLeftWidth-4px { border-left-width: 4px; }
.borderLeftWidth-5px { border-left-width: 5px; }
.borderRightWidth-0 { border-right-width: 0; }
.borderRightWidth-1px { border-right-width: 1px; }
.borderRightWidth-2px { border-right-width: 2px; }
.borderRightWidth-3px { border-right-width: 3px; }
.borderRightWidth-4px { border-right-width: 4px; }
.borderRightWidth-5px { border-right-width: 5px; }
.borderTopWidth-0 { border-top-width: 0; }
.borderTopWidth-1px { border-top-width: 1px; }
.borderTopWidth-2px { border-top-width: 2px; }
.borderTopWidth-3px { border-top-width: 3px; }
.borderTopWidth-4px { border-top-width: 4px; }
.borderTopWidth-5px { border-top-width: 5px; }

View File

@@ -1,4 +0,0 @@
.boxSizing-border-box { box-sizing: border-box; }
.boxSizing-content-box { box-sizing: content-box; }
.boxSizing-inherit { box-sizing: inherit; }
.boxSizing-padding-box { box-sizing: padding-box; }

View File

@@ -1,5 +0,0 @@
.clear-both { clear: both; }
.clear-inherit { clear: inherit; }
.clear-left { clear: left; }
.clear-none { clear: none; }
.clear-right { clear: right; }

View File

@@ -1,6 +0,0 @@
.color-#000,
.color-black { color: black; }
.color-\#fff,
.color-white { color: white; }
.color-inherit { color: inherit; }
.color-transparent { color: transparent; }

View File

@@ -1,3 +0,0 @@
.direction-inherit { direction: inherit; }
.direction-ltr { direction: ltr; }
.direction-rtl { direction: rtl; }

View File

@@ -1,22 +0,0 @@
.display-block { display: block; }
.display-contents { display: contents; }
.display-flex { display: flex; }
.display-grid { display: grid; }
.display-inherit { display: inherit; }
.display-initial { display: initial; }
.display-inline { display: inline; }
.display-inline-block { display: inline-block; }
.display-inline-flex { display: inline-flex; }
.display-inline-grid { display: inline-grid; }
.display-inline-table { display: inline-table; }
.display-list-item { display: list-item; }
.display-none { display: none; }
.display-table { display: table; }
.display-table-cell { display: table-cell; }
.display-table-column { display: table-column; }
.display-table-column-group { display: table-column-group; }
.display-table-footer-group { display: table-footer-group; }
.display-table-header-group { display: table-header-group; }
.display-table-row { display: table-row; }
.display-table-row-group { display: table-row-group; }
.display-unset { display: unset; }

View File

@@ -1,74 +0,0 @@
.alignContent-center { align-content: center; }
.alignContent-flex-end { align-content: flex-end; }
.alignContent-flex-start { align-content: flex-start; }
.alignContent-stretch { align-content: stretch; }
.alignContent-space-around { align-content: space-around; }
.alignContent-space-between { align-content: space-between; }
.alignItems-center { align-items: center; }
.alignItems-flex-end { align-items: flex-end; }
.alignItems-flex-start { align-items: flex-start; }
.alignItems-stretch { align-items: stretch; }
.alignItems-space-around { align-items: space-around; }
.alignItems-space-between { align-items: space-between; }
.alignSelf-auto { align-self: auto; }
.alignSelf-baseline { align-self: baseline; }
.alignSelf-center { align-self: center; }
.alignSelf-flex-end { align-self: flex-end; }
.alignSelf-flex-start { align-self: flex-start; }
.alignSelf-stretch { align-self: stretch; }
.flexBasis-0 { flex-basis: 0%; }
.flexBasis-auto { flex-basis: auto; }
.flexDirection-column { flex-direction: column; }
.flexDirection-column-reverse { flex-direction: column-reverse; }
.flexDirection-row { flex-direction: row; }
.flexDirection-row-reverse { flex-direction: row-reverse; }
.flexGrow-0 { flex-grow: 0; }
.flexGrow-1 { flex-grow: 1; }
.flexGrow-2 { flex-grow: 2; }
.flexGrow-3 { flex-grow: 3; }
.flexGrow-4 { flex-grow: 4; }
.flexGrow-5 { flex-grow: 5; }
.flexGrow-6 { flex-grow: 6; }
.flexGrow-7 { flex-grow: 7; }
.flexGrow-8 { flex-grow: 8; }
.flexGrow-9 { flex-grow: 9; }
.flexGrow-10 { flex-grow: 10; }
.flexGrow-11 { flex-grow: 11; }
.flexShrink-0 { flex-shrink: 0; }
.flexShrink-1 { flex-shrink: 1; }
.flexShrink-2 { flex-shrink: 2; }
.flexShrink-3 { flex-shrink: 3; }
.flexShrink-4 { flex-shrink: 4; }
.flexShrink-5 { flex-shrink: 5; }
.flexShrink-6 { flex-shrink: 6; }
.flexShrink-7 { flex-shrink: 7; }
.flexShrink-8 { flex-shrink: 8; }
.flexShrink-9 { flex-shrink: 9; }
.flexShrink-10 { flex-shrink: 10; }
.flexShrink-11 { flex-shrink: 11; }
.flexWrap-nowrap { flex-wrap: nowrap; }
.flexWrap-wrap { flex-wrap: wrap; }
.flexWrap-wrap-reverse { flex-wrap: wrap-reverse; }
.justifyContent-center { justify-content: center; }
.justifyContent-flex-end { justify-content: flex-end; }
.justifyContent-flex-start { justify-content: flex-start; }
.justifyContent-space-around { justify-content: space-around; }
.justifyContent-space-between { justify-content: space-between; }
.order-1 { order: 1; }
.order-2 { order: 2; }
.order-3 { order: 3; }
.order-4 { order: 4; }
.order-5 { order: 5; }
.order-6 { order: 6; }
.order-7 { order: 7; }
.order-8 { order: 8; }
.order-9 { order: 9; }

View File

@@ -1,3 +0,0 @@
.float-left { float: left; }
.float-none { float: none; }
.float-right { float: right; }

View File

@@ -1,37 +0,0 @@
.font-inherit { font: inherit; }
/* font-family */
.fontFamily-inherit { font-family: inherit; }
.fontFamily-monospace { font-family: monospace; }
.fontFamily-sans-serif { font-family: sans-serif; }
.fontFamily-serif { font-family: serif; }
/* font-size */
.fontSize-100\% { font-size: 100%; }
.fontSize-inherit { font-size: inherit; }
/* font-style */
.fontStyle-inherit { font-style: inherit; }
.fontStyle-italic { font-style: italic; }
.fontStyle-normal { font-style: normal; }
.fontStyle-oblique { font-style: oblique; }
/* font-weight */
.fontWeight-100 { font-weight: 100; }
.fontWeight-200 { font-weight: 200; }
.fontWeight-300 { font-weight: 300; }
.fontWeight-400 { font-weight: 400; }
.fontWeight-500 { font-weight: 500; }
.fontWeight-600 { font-weight: 600; }
.fontWeight-700 { font-weight: 700; }
.fontWeight-800 { font-weight: 800; }
.fontWeight-900 { font-weight: 900; }
.fontWeight-bold { font-weight: bold; }
.fontWeight-bolder { font-weight: bolder; }
.fontWeight-inherit { font-weight: inherit; }
.fontWeight-lighter { font-weight: lighter; }
.fontWeight-normal { font-weight: normal; }

View File

@@ -1,20 +0,0 @@
.height-0 { height: 0; }
.height-10\% { height: 10%; }
.height-12\.5\% { height: 12.5%; }
.height-20\% { height: 20%; }
.height-25\% { height: 25%; }
.height-30\% { height: 30%; }
.height-37\.5\% { height: 37.5%; }
.height-40\% { height: 40%; }
.height-50\% { height: 50%; }
.height-60\% { height: 60%; }
.height-62\.5\% { height: 62.5%; }
.height-70\% { height: 70%; }
.height-75\% { height: 75%; }
.height-80\% { height: 80%; }
.height-87\.5\% { height: 87.5%; }
.height-90\% { height: 90%; }
.height-100\% { height: 100%; }
.maxHeight-100\% { max-height: 100%; }
.minHeight-100\% { min-height: 100%; }

View File

@@ -1,2 +0,0 @@
.lineHeight-inherit { line-height: inherit; }
.lineHeight-normal { line-height: normal; }

View File

@@ -1 +0,0 @@
.listStyle-none { list-style: none; }

View File

@@ -1,22 +0,0 @@
.margin-0 { margin: 0; }
.margin-auto { margin: auto; }
.marginBottom-auto { margin-bottom: auto; }
.marginLeft-auto { margin-left: auto; }
.marginRight-auto { margin-right: auto; }
.marginTop-auto { margin-top: auto; }
.marginBottom-0 { margin-bottom: 0; }
.marginLeft-0 { margin-left: 0; }
.marginRight-0 { margin-right: 0; }
.marginTop-0 { margin-top: 0; }
.marginBottom-1em { margin-bottom: 1em; }
.marginLeft-1em { margin-left: 1em; }
.marginRight-1em { margin-right: 1em; }
.marginTop-1em { margin-top: 1em; }
.marginBottom-1rem { margin-bottom: 1rem; }
.marginLeft-1rem { margin-left: 1rem; }
.marginRight-1rem { margin-right: 1rem; }
.marginTop-1rem { margin-top: 1rem; }

View File

@@ -1,2 +0,0 @@
.opacity-0 { opacity: 0; }
.opacity-1 { opacity: 1; }

View File

@@ -1,17 +0,0 @@
.overflow-auto { overflow: auto; }
.overflow-hidden { overflow: hidden; }
.overflow-inherit { overflow: inherit; }
.overflow-scroll { overflow: scroll; }
.overflow-visible { overflow: visible; }
.overflowX-auto { overflow-x: auto; }
.overflowX-hidden { overflow-x: hidden; }
.overflowX-inherit { overflow-x: inherit; }
.overflowX-scroll { overflow-x: scroll; }
.overflowX-visible { overflow-x: visible; }
.overflowY-auto { overflow-y: auto; }
.overflowY-hidden { overflow-y: hidden; }
.overflowY-inherit { overflow-y: inherit; }
.overflowY-scroll { overflow-y: scroll; }
.overflowY-visible { overflow-y: visible; }

View File

@@ -1,17 +0,0 @@
.padding-0 { padding: 0; }
.paddingTop-0 { padding-top: 0; }
.paddingRight-0 { padding-right: 0; }
.paddingBottom-0 { padding-bottom: 0; }
.paddingLeft-0 { padding-left: 0; }
.padding-1em { padding: 1em; }
.paddingTop-1em { padding-top: 1em; }
.paddingRight-1em { padding-right: 1em; }
.paddingBottom-1em { padding-bottom: 1em; }
.paddingLeft-1em { padding-left: 1em; }
.padding-1rem { padding: 1rem; }
.paddingTop-1rem { padding-top: 1rem; }
.paddingRight-1rem { padding-right: 1rem; }
.paddingBottom-1rem { padding-bottom: 1rem; }
.paddingLeft-1rem { padding-left: 1rem; }

View File

@@ -1,6 +0,0 @@
.pointerEvents-auto { pointer-events: auto; }
.pointerEvents-none { pointer-events: none; }
.pointerEvents-box-none { pointer-events: none; }
.pointerEvents-box-none * { pointer-events: auto;}
.pointerEvents-box-only { pointer-events: auto; }
.pointerEvents-box-only * { pointer-events: none; }

View File

@@ -1,18 +0,0 @@
.position-absolute { position: absolute; }
.position-fixed { position: fixed; }
.position-relative { position: relative; }
.bottom-0 { bottom: 0; }
.left-0 { left: 0; }
.right-0 { right: 0; }
.top-0 { top: 0; }
.bottom-50% { bottom: 50%; }
.left-50% { left: 50%; }
.right-50% { right: 50%; }
.top-50% { top: 50%; }
.bottom-100% { bottom: 100%; }
.left-100% { left: 100%; }
.right-100% { right: 100%; }
.top-100% { top: 100%; }

View File

@@ -1,25 +0,0 @@
.textAlign-center { text-align: center; }
.textAlign-end { text-align: end; }
.textAlign-inherit { text-align: inherit; }
.textAlign-left { text-align: left; }
.textAlign-right { text-align: right; }
.textAlign-justify { text-align: justify; }
.textAlign-start { text-align: start; }
.textDecoration-inherit { text-decoration: inherit; }
.textDecoration-none { text-decoration: none; }
.textDecoration-underline { text-decoration: underline; }
.textOverflow-clip { text-overflow: clip; }
.textOverflow-ellipsis { text-overflow: ellipsis; }
.textRendering-auto { text-rendering: auto; }
.textRendering-geometricPrecision { text-rendering: geometricPrecision; }
.textRendering-inherit { text-rendering: inherit; }
.textRendering-optimizeLegibility { text-rendering: optimizeLegibility; }
.textRendering-optimizeSpeed { text-rendering: optimizeSpeed; }
.textTransform-capitalize { text-transform: capitalize; }
.textTransform-lowercase { text-transform: lowercase; }
.textTransform-none { text-transform: none; }
.textTransform-uppercase { text-transform: uppercase; }

View File

@@ -1,7 +0,0 @@
.unicodeBidi-bidi-override { unicode-bidi: bidi-override; }
.unicodeBidi-embed { unicode-bidi: embed; }
.unicodeBidi-inherit { unicode-bidi: inherit; }
.unicodeBidi-isolate { unicode-bidi: isolate; }
.unicodeBidi-isolate-override { unicode-bidi: isolate-override; }
.unicodeBidi-normal { unicode-bidi: normal; }
.unicodeBidi-plaintext { unicode-bidi: plaintext; }

View File

@@ -1,4 +0,0 @@
.userSelect-all { user-select: all; }
.userSelect-inherit { user-select: inherit; }
.userSelect-none { user-select: none; }
.userSelect-text { user-select: text; }

View File

@@ -1,4 +0,0 @@
.visibility-collapse { visibility: collapse; }
.visibility-hidden { visibility: hidden; }
.visibility-inherit { visibility: inherit; }
.visibility-visible { visibility: visible; }

View File

@@ -1,5 +0,0 @@
.whiteSpace-normal { white-space: normal; }
.whiteSpace-nowrap { white-space: nowrap; }
.whiteSpace-pre { white-space: pre; }
.whiteSpace-pre-line { white-space: pre-line; }
.whiteSpace-pre-wrap { white-space: pre-wrap; }

View File

@@ -1,20 +0,0 @@
.maxWidth-100\% { max-width: 100%; }
.minWidth-100\% { min-width: 100%; }
.width-0 { width: 0; }
.width-10\% { width: 10%; }
.width-12\.5\% { width: 12.5%; }
.width-20\% { width: 20%; }
.width-25\% { width: 25%; }
.width-30\% { width: 30%; }
.width-37\.5\% { width: 37.5%; }
.width-40\% { width: 40%; }
.width-50\% { width: 50%; }
.width-60\% { width: 60%; }
.width-62\.5\% { width: 62.5%; }
.width-70\% { width: 70%; }
.width-75\% { width: 75%; }
.width-80\% { width: 80%; }
.width-87\.5\% { width: 87.5%; }
.width-90\% { width: 90%; }
.width-100\% { width: 100%; }

View File

@@ -1,2 +0,0 @@
.wordWrap-break-word { word-wrap: break-word; }
.wordWrap-normal { word-wrap: normal; }

View File

@@ -1,12 +0,0 @@
.zIndex--1 { z-index: -1; }
.zIndex-0 { z-index: 0; }
.zIndex-1 { z-index: 1; }
.zIndex-2 { z-index: 2; }
.zIndex-3 { z-index: 3; }
.zIndex-4 { z-index: 4; }
.zIndex-5 { z-index: 5; }
.zIndex-6 { z-index: 6; }
.zIndex-7 { z-index: 7; }
.zIndex-8 { z-index: 8; }
.zIndex-9 { z-index: 9; }
.zIndex-10 { z-index: 10; }

View File

@@ -1,60 +0,0 @@
import appearance from './css/appearance.css';
import background from './css/background.css';
import border from './css/border.css';
import boxSizing from './css/boxSizing.css';
import clear from './css/clear.css';
import color from './css/color.css';
import cssFloat from './css/float.css';
import direction from './css/direction.css';
import display from './css/display.css';
import flexbox from './css/flexbox.css';
import font from './css/font.css';
import height from './css/height.css';
import lineHeight from './css/lineHeight.css';
import list from './css/list.css';
import margin from './css/margin.css';
import opacity from './css/opacity.css';
import overflow from './css/overflow.css';
import padding from './css/padding.css';
import pointerEvents from './css/pointerEvents.css';
import position from './css/position.css';
import text from './css/text.css';
import unicodeBidi from './css/unicodeBidi.css';
import userSelect from './css/userSelect.css';
import visibility from './css/visibility.css';
import whiteSpace from './css/whiteSpace.css';
import width from './css/width.css';
import word from './css/word.css';
import zIndex from './css/zIndex.css';
const map = Object.assign({},
appearance,
background,
border,
boxSizing,
clear,
color,
cssFloat,
direction,
display,
flexbox,
font,
height,
list,
margin,
opacity,
overflow,
padding,
pointerEvents,
position,
text,
unicodeBidi,
userSelect,
visibility,
whiteSpace,
width,
word,
zIndex
);
export default map;

View File

@@ -1,35 +1,29 @@
function filterProps(obj, props, excluded=false) {
function filterProps(obj, props, excluded = false) {
if (!Array.isArray(props)) {
throw new TypeError('props is not an Array');
throw new TypeError('props is not an Array')
}
let filtered = {};
for (let prop in obj) {
const filtered = {}
for (const prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
let isMatch = props.indexOf(prop) > -1;
const isMatch = props.indexOf(prop) > -1
if (excluded && isMatch) {
continue;
continue
} else if (!excluded && !isMatch) {
continue;
continue
}
filtered[prop] = obj[prop];
filtered[prop] = obj[prop]
}
}
return filtered;
}
// Extract all props that are not part of the React Component's 'propTypes'
export function getOtherProps(componentInstance) {
const excludedProps = Object.keys(componentInstance.constructor.propTypes);
return omitProps(componentInstance.props, excludedProps);
return filtered
}
export function pickProps(obj, props) {
return filterProps(obj, props);
return filterProps(obj, props)
}
export function omitProps(obj, props) {
return filterProps(obj, props, true);
return filterProps(obj, props, true)
}

View File

@@ -0,0 +1,40 @@
import { omitProps, pickProps } from '.'
import assert from 'assert'
suite('pickProps', () => {
test('interface', () => {
assert.throws(
() => { pickProps({}, true) },
TypeError,
'pickProps should throw if the second argument is not an array'
)
})
test('return value', () => {
const obj = { a: 1, b: 2, c: { cc: { ccc: 3 } } }
const props = [ 'a', 'b' ]
const expected = { a: 1, b: 2 }
const actual = pickProps(obj, props)
assert.deepEqual(actual, expected)
})
})
suite('omitProps', () => {
test('interface', () => {
assert.throws(
() => { omitProps({}, true) },
TypeError,
'omitProps should throw if the second argument is not an array'
)
})
test('return value', () => {
const obj = { a: 1, b: 2, c: { cc: { ccc: 3 } } }
const props = [ 'a', 'b' ]
const expected = { c: { cc: { ccc: 3 } } }
const actual = omitProps(obj, props)
assert.deepEqual(actual, expected)
})
})

View File

@@ -0,0 +1,32 @@
import React, { PropTypes } from 'react'
import restyle from './modules/restyle'
import StylePropTypes from './modules/StylePropTypes'
class WebStyleComponent extends React.Component {
static propTypes = {
className: PropTypes.string,
component: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string
]),
style: PropTypes.object
}
static defaultProps = {
className: '',
component: 'div'
}
render() {
const { component: Component, ...other } = this.props
return (
<Component
{...other}
{...restyle(this.props)}
/>
)
}
}
export { StylePropTypes, restyle, WebStyleComponent }

View File

@@ -1,4 +1,4 @@
import {PropTypes} from 'react';
import { PropTypes } from 'react'
export default {
backgroundColor: PropTypes.string,
@@ -6,4 +6,4 @@ export default {
backgroundPosition: PropTypes.string,
backgroundRepeat: PropTypes.string,
backgroundSize: PropTypes.string
};
}

View File

@@ -1,9 +1,9 @@
import {PropTypes} from 'react';
import { PropTypes } from 'react'
const numberOrString = PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]);
PropTypes.string
])
export default {
// border-color
@@ -20,4 +20,4 @@ export default {
borderTopRightRadius: numberOrString,
borderBottomLeftRadius: numberOrString,
borderBottomRightRadius: numberOrString
};
}

View File

@@ -1,9 +1,9 @@
import {PropTypes} from 'react';
import {PropTypes} from 'react'
const numberOrString = PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]);
PropTypes.string
])
export default {
boxSizing: PropTypes.oneOf([
@@ -39,4 +39,4 @@ export default {
paddingBottom: numberOrString,
paddingLeft: numberOrString,
paddingRight: numberOrString
};
}

View File

@@ -1,4 +1,4 @@
import {PropTypes} from 'react';
import { PropTypes } from 'react'
export default {
alignContent: PropTypes.oneOf([
@@ -46,4 +46,4 @@ export default {
'space-between'
]),
order: PropTypes.number
};
}

View File

@@ -0,0 +1,9 @@
import BoxModel from './BoxModel'
import Flexbox from './Flexbox'
import Position from './Position'
export default {
...BoxModel,
...Flexbox,
...Position
}

View File

@@ -1,19 +1,19 @@
import {PropTypes} from 'react';
import { PropTypes } from 'react'
const numberOrString = PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]);
PropTypes.string
])
export default {
position: PropTypes.oneOf([
'absolute',
'fixed',
'relative'
'relative' /* default */
]),
bottom: numberOrString,
left: numberOrString,
right: numberOrString,
top: numberOrString,
zIndex: PropTypes.number
};
}

View File

@@ -0,0 +1,35 @@
import { PropTypes } from 'react'
export default {
color: PropTypes.string,
direction: PropTypes.oneOf([
'auto', 'ltr', 'rtl'
]),
font: PropTypes.string,
fontFamily: PropTypes.string,
fontSize: PropTypes.string,
fontStyle: PropTypes.oneOf([
'inherit', 'normal', 'italic'
]),
fontWeight: PropTypes.oneOf([
'inherit', 'bold', 'normal',
'100', '200', '300', '400', '500', '600', '700', '800', '900'
]),
letterSpacing: PropTypes.string,
lineHeight: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string
]),
textAlign: PropTypes.oneOf([
'auto', 'center', 'justify', 'left', 'right'
]),
textDecoration: PropTypes.oneOf([
'none', 'line-through', 'underline', 'underline line-through'
]),
textTransform: PropTypes.oneOf([
'none', 'capitalize', 'lowercase', 'uppercase'
]),
wordWrap: PropTypes.oneOf([
'break-word', 'normal'
])
}

View File

@@ -0,0 +1,13 @@
import BackgroundPropTypes from './Background'
import BorderThemePropTypes from './BorderTheme'
import FlexboxPropTypes from './Flexbox'
import LayoutPropTypes from './Layout'
import TypographicPropTypes from './Typographic'
export default {
BackgroundPropTypes,
BorderThemePropTypes,
FlexboxPropTypes,
LayoutPropTypes,
TypographicPropTypes
}

View File

@@ -4,7 +4,7 @@ export default function prefixStyles(style) {
WebkitFlexBasis: style.flexBasis,
msFlexBasis: style.flexBasis,
...style
};
}
}
if (style.hasOwnProperty('flexGrow')) {
@@ -13,7 +13,7 @@ export default function prefixStyles(style) {
WebkitFlexGrow: style.flexGrow,
msFlexPositive: style.flexGrow,
...style
};
}
}
if (style.hasOwnProperty('flexShrink')) {
@@ -21,7 +21,7 @@ export default function prefixStyles(style) {
WebkitFlexShrink: style.flexShrink,
msFlexNegative: style.flexShrink,
...style
};
}
}
// NOTE: adding `;` to the string value prevents React from automatically
@@ -30,9 +30,9 @@ export default function prefixStyles(style) {
style = {
WebkitBoxOrdinalGroup: `${parseInt(style.order, 10) + 1};`,
WebkitOrder: `${style.order}`,
msFlexOrder: `${style.order};`,
msFlexOrder: `${style.order}`,
...style
};
}
}
if (style.hasOwnProperty('transform')) {
@@ -40,8 +40,8 @@ export default function prefixStyles(style) {
WebkitTransform: style.transform,
msTransform: style.transform,
...style
};
}
}
return style;
return style
}

View File

@@ -0,0 +1,40 @@
import autoprefix from './autoprefix'
import styles from '../../styles'
/**
* Get the HTML class that corresponds to a style declaration
* @param prop {string} prop name
* @param style {Object} style
* @return {string} class name
*/
function getSinglePurposeClassName(prop, style) {
const className = `${prop}-${style[prop]}`
if (style.hasOwnProperty(prop) && styles[className]) {
return styles[className]
}
}
/**
* Replace inline styles with single purpose classes where possible
* @param props {Object} React Element properties
* @return {Object}
*/
export default function stylingStrategy(props) {
let className
let style = {}
const classList = [ props.className ]
for (const prop in props.style) {
const styleClass = getSinglePurposeClassName(prop, props.style)
if (styleClass) {
classList.push(styleClass)
} else {
style[prop] = props.style[prop]
}
}
className = classList.join(' ')
style = autoprefix(style)
return { className: className, style }
}

View File

@@ -0,0 +1,2 @@
import styles from './styles.css'
export default styles

View File

@@ -0,0 +1,683 @@
/* align-content */
.alignContent-center { align-content: center; }
.alignContent-flex-end { align-content: flex-end; }
.alignContent-flex-start { align-content: flex-start; }
.alignContent-stretch { align-content: stretch; }
.alignContent-space-around { align-content: space-around; }
.alignContent-space-between { align-content: space-between; }
/* align-items */
.alignItems-center { align-items: center; }
.alignItems-flex-end { align-items: flex-end; }
.alignItems-flex-start { align-items: flex-start; }
.alignItems-stretch { align-items: stretch; }
.alignItems-space-around { align-items: space-around; }
.alignItems-space-between { align-items: space-between; }
/* align-self */
.alignSelf-auto { align-self: auto; }
.alignSelf-baseline { align-self: baseline; }
.alignSelf-center { align-self: center; }
.alignSelf-flex-end { align-self: flex-end; }
.alignSelf-flex-start { align-self: flex-start; }
.alignSelf-stretch { align-self: stretch; }
/* appearance */
.appearance-none { appearance: none; }
/* background-attachment */
.backgroundAttachment-fixed { background-attachment: fixed; }
.backgroundAttachment-inherit { background-attachment: inherit; }
.backgroundAttachment-local { background-attachment: local; }
.backgroundAttachment-scroll { background-attachment: scroll; }
/* background-clip */
.backgroundClip-border-box { background-clip: border-box; }
.backgroundClip-content-box { background-clip: content-box; }
.backgroundClip-inherit { background-clip: inherit; }
.backgroundClip-padding-box { background-clip: padding-box; }
/* background-color */
.backgroundColor-\#000,
.backgroundColor-black { background-color: black; }
.backgroundColor-\#fff,
.backgroundColor-white { background-color: white; }
.backgroundColor-currentcolor,
.backgroundColor-currentColor { background-color: currentcolor; }
.backgroundColor-inherit { background-color: inherit; }
.backgroundColor-transparent { background-color: transparent; }
/* background-image */
.backgroundImage { background-image: none; }
/* background-origin */
.backgroundOrigin-border-box { background-clip: border-box; }
.backgroundOrigin-content-box { background-clip: content-box; }
.backgroundOrigin-inherit { background-clip: inherit; }
.backgroundOrigin-padding-box { background-clip: padding-box; }
/* background-position */
.backgroundPosition-bottom { background-position: bottom; }
.backgroundPosition-center { background-position: center; }
.backgroundPosition-left { background-position: left; }
.backgroundPosition-right { background-position: right; }
.backgroundPosition-top { background-position: top; }
/* background-repeat */
.backgroundRepeat-inherit { background-repeat: inherit; }
.backgroundRepeat-no-repeat { background-repeat: no-repeat; }
.backgroundRepeat-repeat { background-repeat: repeat; }
.backgroundRepeat-repeat-x { background-repeat: repeat-x; }
.backgroundRepeat-repeat-y { background-repeat: repeat-y; }
.backgroundRepeat-round { background-repeat: round; }
.backgroundRepeat-space { background-repeat: space; }
/* background-size */
.backgroundSize-auto { background-size: auto; }
.backgroundSize-contain { background-size: contain; }
.backgroundSize-cover { background-size: cover; }
.backgroundSize-inherit { background-size: inherit; }
/* border-color */
.borderColor-\#fff,
.borderColor-white { border-color: white; }
.borderColor-currentcolor { border-color: currentcolor; }
.borderColor-inherit { border-color: inherit; }
.borderColor-transparent { border-color: transparent; }
/* border-bottom-color */
.borderBottomColor-\#fff,
.borderBottomColor-white { border-bottom-color: white; }
.borderBottomColor-currentcolor { border-bottom-color: currentcolor; }
.borderBottomColor-inherit { border-bottom-color: inherit; }
.borderBottomColor-transparent { border-bottom-color: transparent; }
/* border-left-color */
.borderLeftColor-\#fff,
.borderLeftColor-white { border-left-color: white; }
.borderLeftColor-currentcolor { border-left-color: currentcolor; }
.borderLeftColor-inherit { border-left-color: inherit; }
.borderLeftColor-transparent { border-left-color: transparent; }
/* border-right-color */
.borderRightColor-\#fff,
.borderRightColor-white { border-right-color: white; }
.borderRightColor-currentcolor { border-right-color: currentcolor; }
.borderRightColor-inherit { border-right-color: inherit; }
.borderRightColor-transparent { border-right-color: transparent; }
/* border-top-color */
.borderTopColor-\#fff,
.borderTopColor-white { border-top-color: white; }
.borderTopColor-currentcolor { border-top-color: currentcolor; }
.borderTopColor-inherit { border-top-color: inherit; }
.borderTopColor-transparent { border-top-color: transparent; }
/* border-style */
.borderStyle-dashed { border-style: dashed; }
.borderStyle-dotted { border-style: dotted; }
.borderStyle-inherit { border-style: inherit; }
.borderStyle-none { border-style: none; }
.borderStyle-solid { border-style: solid; }
/* border-bottom-style */
.borderBottomStyle-dashed { border-bottom-style: dashed; }
.borderBottomStyle-dotted { border-bottom-style: dotted; }
.borderBottomStyle-inherit { border-bottom-style: inherit; }
.borderBottomStyle-none { border-bottom-style: none; }
.borderBottomStyle-solid { border-bottom-style: solid; }
/* border-left-style */
.borderLeftStyle-dashed { border-left-style: dashed; }
.borderLeftStyle-dotted { border-left-style: dotted; }
.borderLeftStyle-inherit { border-left-style: inherit; }
.borderLeftStyle-none { border-left-style: none; }
.borderLeftStyle-solid { border-left-style: solid; }
/* border-right-style */
.borderRightStyle-dashed { border-right-style: dashed; }
.borderRightStyle-dotted { border-right-style: dotted; }
.borderRightStyle-inherit { border-right-style: inherit; }
.borderRightStyle-none { border-right-style: none; }
.borderRightStyle-solid { border-right-style: solid; }
/* border-top-style */
.borderTopStyle-dashed { border-top-style: dashed; }
.borderTopStyle-dotted { border-top-style: dotted; }
.borderTopStyle-inherit { border-top-style: inherit; }
.borderTopStyle-none { border-top-style: none; }
.borderTopStyle-solid { border-top-style: solid; }
/* border-width */
.borderWidth-0 { border-width: 0; }
.borderWidth-1px { border-width: 1px; }
.borderWidth-2px { border-width: 2px; }
.borderWidth-3px { border-width: 3px; }
.borderWidth-4px { border-width: 4px; }
.borderWidth-5px { border-width: 5px; }
/* border-bottom-width */
.borderBottomWidth-0 { border-bottom-width: 0; }
.borderBottomWidth-1px { border-bottom-width: 1px; }
.borderBottomWidth-2px { border-bottom-width: 2px; }
.borderBottomWidth-3px { border-bottom-width: 3px; }
.borderBottomWidth-4px { border-bottom-width: 4px; }
.borderBottomWidth-5px { border-bottom-width: 5px; }
/* border-left-width */
.borderLeftWidth-0 { border-left-width: 0; }
.borderLeftWidth-1px { border-left-width: 1px; }
.borderLeftWidth-2px { border-left-width: 2px; }
.borderLeftWidth-3px { border-left-width: 3px; }
.borderLeftWidth-4px { border-left-width: 4px; }
.borderLeftWidth-5px { border-left-width: 5px; }
/* border-right-width */
.borderRightWidth-0 { border-right-width: 0; }
.borderRightWidth-1px { border-right-width: 1px; }
.borderRightWidth-2px { border-right-width: 2px; }
.borderRightWidth-3px { border-right-width: 3px; }
.borderRightWidth-4px { border-right-width: 4px; }
.borderRightWidth-5px { border-right-width: 5px; }
/* border-top-width */
.borderTopWidth-0 { border-top-width: 0; }
.borderTopWidth-1px { border-top-width: 1px; }
.borderTopWidth-2px { border-top-width: 2px; }
.borderTopWidth-3px { border-top-width: 3px; }
.borderTopWidth-4px { border-top-width: 4px; }
.borderTopWidth-5px { border-top-width: 5px; }
/* bottom */
.bottom-0 { bottom: 0; }
.bottom-50% { bottom: 50%; }
.bottom-100% { bottom: 100%; }
/* box-sizing */
.boxSizing-border-box { box-sizing: border-box; }
.boxSizing-content-box { box-sizing: content-box; }
.boxSizing-inherit { box-sizing: inherit; }
.boxSizing-padding-box { box-sizing: padding-box; }
/* clear */
.clear-both { clear: both; }
.clear-inherit { clear: inherit; }
.clear-left { clear: left; }
.clear-none { clear: none; }
.clear-right { clear: right; }
/* color */
.color-#000,
.color-black { color: black; }
.color-\#fff,
.color-white { color: white; }
.color-inherit { color: inherit; }
.color-transparent { color: transparent; }
/* direction */
.direction-inherit { direction: inherit; }
.direction-ltr { direction: ltr; }
.direction-rtl { direction: rtl; }
/* display */
.display-block { display: block; }
.display-contents { display: contents; }
.display-flex { display: flex; }
.display-grid { display: grid; }
.display-inherit { display: inherit; }
.display-initial { display: initial; }
.display-inline { display: inline; }
.display-inline-block { display: inline-block; }
.display-inline-flex { display: inline-flex; }
.display-inline-grid { display: inline-grid; }
.display-inline-table { display: inline-table; }
.display-list-item { display: list-item; }
.display-none { display: none; }
.display-table { display: table; }
.display-table-cell { display: table-cell; }
.display-table-column { display: table-column; }
.display-table-column-group { display: table-column-group; }
.display-table-footer-group { display: table-footer-group; }
.display-table-header-group { display: table-header-group; }
.display-table-row { display: table-row; }
.display-table-row-group { display: table-row-group; }
.display-unset { display: unset; }
/* flex-basis */
.flexBasis-0 { flex-basis: 0%; }
.flexBasis-auto { flex-basis: auto; }
/* flex-direction */
.flexDirection-column { flex-direction: column; }
.flexDirection-column-reverse { flex-direction: column-reverse; }
.flexDirection-row { flex-direction: row; }
.flexDirection-row-reverse { flex-direction: row-reverse; }
/* flex-grow */
.flexGrow-0 { flex-grow: 0; }
.flexGrow-1 { flex-grow: 1; }
.flexGrow-2 { flex-grow: 2; }
.flexGrow-3 { flex-grow: 3; }
.flexGrow-4 { flex-grow: 4; }
.flexGrow-5 { flex-grow: 5; }
.flexGrow-6 { flex-grow: 6; }
.flexGrow-7 { flex-grow: 7; }
.flexGrow-8 { flex-grow: 8; }
.flexGrow-9 { flex-grow: 9; }
.flexGrow-10 { flex-grow: 10; }
.flexGrow-11 { flex-grow: 11; }
/* flex-shrink */
.flexShrink-0 { flex-shrink: 0; }
.flexShrink-1 { flex-shrink: 1; }
.flexShrink-2 { flex-shrink: 2; }
.flexShrink-3 { flex-shrink: 3; }
.flexShrink-4 { flex-shrink: 4; }
.flexShrink-5 { flex-shrink: 5; }
.flexShrink-6 { flex-shrink: 6; }
.flexShrink-7 { flex-shrink: 7; }
.flexShrink-8 { flex-shrink: 8; }
.flexShrink-9 { flex-shrink: 9; }
.flexShrink-10 { flex-shrink: 10; }
.flexShrink-11 { flex-shrink: 11; }
/* flex-wrap */
.flexWrap-nowrap { flex-wrap: nowrap; }
.flexWrap-wrap { flex-wrap: wrap; }
.flexWrap-wrap-reverse { flex-wrap: wrap-reverse; }
/* float */
.float-left { float: left; }
.float-none { float: none; }
.float-right { float: right; }
/* font */
.font-inherit { font: inherit; }
/* font-family */
.fontFamily-inherit { font-family: inherit; }
.fontFamily-monospace { font-family: monospace; }
.fontFamily-sans-serif { font-family: sans-serif; }
.fontFamily-serif { font-family: serif; }
/* font-size */
.fontSize-100\% { font-size: 100%; }
.fontSize-inherit { font-size: inherit; }
/* font-style */
.fontStyle-inherit { font-style: inherit; }
.fontStyle-italic { font-style: italic; }
.fontStyle-normal { font-style: normal; }
.fontStyle-oblique { font-style: oblique; }
/* font-weight */
.fontWeight-100 { font-weight: 100; }
.fontWeight-200 { font-weight: 200; }
.fontWeight-300 { font-weight: 300; }
.fontWeight-400 { font-weight: 400; }
.fontWeight-500 { font-weight: 500; }
.fontWeight-600 { font-weight: 600; }
.fontWeight-700 { font-weight: 700; }
.fontWeight-800 { font-weight: 800; }
.fontWeight-900 { font-weight: 900; }
.fontWeight-bold { font-weight: bold; }
.fontWeight-bolder { font-weight: bolder; }
.fontWeight-inherit { font-weight: inherit; }
.fontWeight-lighter { font-weight: lighter; }
.fontWeight-normal { font-weight: normal; }
/* height */
.height-0 { height: 0; }
.height-10\% { height: 10%; }
.height-12\.5\% { height: 12.5%; }
.height-20\% { height: 20%; }
.height-25\% { height: 25%; }
.height-30\% { height: 30%; }
.height-37\.5\% { height: 37.5%; }
.height-40\% { height: 40%; }
.height-50\% { height: 50%; }
.height-60\% { height: 60%; }
.height-62\.5\% { height: 62.5%; }
.height-70\% { height: 70%; }
.height-75\% { height: 75%; }
.height-80\% { height: 80%; }
.height-87\.5\% { height: 87.5%; }
.height-90\% { height: 90%; }
.height-100\% { height: 100%; }
/* justify-content */
.justifyContent-center { justify-content: center; }
.justifyContent-flex-end { justify-content: flex-end; }
.justifyContent-flex-start { justify-content: flex-start; }
.justifyContent-space-around { justify-content: space-around; }
.justifyContent-space-between { justify-content: space-between; }
/* left */
.left-0 { left: 0; }
.left-50% { left: 50%; }
.left-100% { left: 100%; }
/* line-height */
.lineHeight-inherit { line-height: inherit; }
.lineHeight-normal { line-height: normal; }
/* list-style */
.listStyle-none { list-style: none; }
/* margin */
.margin-0 { margin: 0; }
.margin-auto { margin: auto; }
/* margin-bottom */
.marginBottom-auto { margin-bottom: auto; }
.marginBottom-0 { margin-bottom: 0; }
.marginBottom-1em { margin-bottom: 1em; }
.marginBottom-1rem { margin-bottom: 1rem; }
/* margin-left */
.marginLeft-auto { margin-left: auto; }
.marginLeft-0 { margin-left: 0; }
.marginLeft-1em { margin-left: 1em; }
.marginLeft-1rem { margin-left: 1rem; }
/* margin-right */
.marginRight-auto { margin-right: auto; }
.marginRight-0 { margin-right: 0; }
.marginRight-1em { margin-right: 1em; }
.marginRight-1rem { margin-right: 1rem; }
/* margin-top */
.marginTop-auto { margin-top: auto; }
.marginTop-0 { margin-top: 0; }
.marginTop-1em { margin-top: 1em; }
.marginTop-1rem { margin-top: 1rem; }
/* max-height */
.maxHeight-100\% { max-height: 100%; }
/* max-width */
.maxWidth-100\% { max-width: 100%; }
/* min-height */
.minHeight-100\% { min-height: 100%; }
/* min-width */
.minWidth-100\% { min-width: 100%; }
/* opacity */
.opacity-0 { opacity: 0; }
.opacity-0\.1 { opacity: 0.1; }
.opacity-0\.2 { opacity: 0.2; }
.opacity-0\.25 { opacity: 0.25; }
.opacity-0\.3 { opacity: 0.3; }
.opacity-0\.4 { opacity: 0.4; }
.opacity-0\.5 { opacity: 0.5; }
.opacity-0\.6 { opacity: 0.6; }
.opacity-0\.7 { opacity: 0.7; }
.opacity-0\.75 { opacity: 0.75; }
.opacity-0\.8 { opacity: 0.8; }
.opacity-0\.9 { opacity: 0.9; }
.opacity-1 { opacity: 1; }
/* order */
.order--1 { order: -1; }
.order-1 { order: 1; }
.order-2 { order: 2; }
.order-3 { order: 3; }
.order-4 { order: 4; }
.order-5 { order: 5; }
.order-6 { order: 6; }
.order-7 { order: 7; }
.order-8 { order: 8; }
.order-9 { order: 9; }
.order-10 { order: 10; }
.order-11 { order: 11; }
/* overflow */
.overflow-auto { overflow: auto; }
.overflow-hidden { overflow: hidden; }
.overflow-inherit { overflow: inherit; }
.overflow-scroll { overflow: scroll; }
.overflow-visible { overflow: visible; }
/* overflow-x */
.overflowX-auto { overflow-x: auto; }
.overflowX-hidden { overflow-x: hidden; }
.overflowX-inherit { overflow-x: inherit; }
.overflowX-scroll { overflow-x: scroll; }
.overflowX-visible { overflow-x: visible; }
/* overflow-y */
.overflowY-auto { overflow-y: auto; }
.overflowY-hidden { overflow-y: hidden; }
.overflowY-inherit { overflow-y: inherit; }
.overflowY-scroll { overflow-y: scroll; }
.overflowY-visible { overflow-y: visible; }
/* padding */
.padding-0 { padding: 0; }
.padding-1em { padding: 1em; }
.padding-1rem { padding: 1rem; }
/* padding-bottom */
.paddingBottom-0 { padding-bottom: 0; }
.paddingBottom-1em { padding-bottom: 1em; }
.paddingBottom-1rem { padding-bottom: 1rem; }
/* padding-left */
.paddingLeft-0 { padding-left: 0; }
.paddingLeft-1em { padding-left: 1em; }
.paddingLeft-1rem { padding-left: 1rem; }
/* padding-right */
.paddingRight-0 { padding-right: 0; }
.paddingRight-1em { padding-right: 1em; }
.paddingRight-1rem { padding-right: 1rem; }
/* padding-top */
.paddingTop-0 { padding-top: 0; }
.paddingTop-1em { padding-top: 1em; }
.paddingTop-1rem { padding-top: 1rem; }
/* pointer-events */
.pointerEvents-auto { pointer-events: auto; }
.pointerEvents-none { pointer-events: none; }
.pointerEvents-box-none { pointer-events: none; }
.pointerEvents-box-none * { pointer-events: auto;}
.pointerEvents-box-only { pointer-events: auto; }
.pointerEvents-box-only * { pointer-events: none; }
/* position */
.position-absolute { position: absolute; }
.position-fixed { position: fixed; }
.position-relative { position: relative; }
/* right */
.right-0 { right: 0; }
.right-50% { right: 50%; }
.right-100% { right: 100%; }
/* text-align */
.textAlign-center { text-align: center; }
.textAlign-end { text-align: end; }
.textAlign-inherit { text-align: inherit; }
.textAlign-left { text-align: left; }
.textAlign-right { text-align: right; }
.textAlign-justify { text-align: justify; }
.textAlign-start { text-align: start; }
/* text-decoration */
.textDecoration-inherit { text-decoration: inherit; }
.textDecoration-none { text-decoration: none; }
.textDecoration-underline { text-decoration: underline; }
/* text-overflow */
.textOverflow-clip { text-overflow: clip; }
.textOverflow-ellipsis { text-overflow: ellipsis; }
/* text-rendering */
.textRendering-auto { text-rendering: auto; }
.textRendering-geometricPrecision { text-rendering: geometricPrecision; }
.textRendering-inherit { text-rendering: inherit; }
.textRendering-optimizeLegibility { text-rendering: optimizeLegibility; }
.textRendering-optimizeSpeed { text-rendering: optimizeSpeed; }
/* text-transform */
.textTransform-capitalize { text-transform: capitalize; }
.textTransform-lowercase { text-transform: lowercase; }
.textTransform-none { text-transform: none; }
.textTransform-uppercase { text-transform: uppercase; }
/* top */
.top-0 { top: 0; }
.top-50% { top: 50%; }
.top-100% { top: 100%; }
/* unicode-bidi */
.unicodeBidi-bidi-override { unicode-bidi: bidi-override; }
.unicodeBidi-embed { unicode-bidi: embed; }
.unicodeBidi-inherit { unicode-bidi: inherit; }
.unicodeBidi-isolate { unicode-bidi: isolate; }
.unicodeBidi-isolate-override { unicode-bidi: isolate-override; }
.unicodeBidi-normal { unicode-bidi: normal; }
.unicodeBidi-plaintext { unicode-bidi: plaintext; }
/* user-select */
.userSelect-all { user-select: all; }
.userSelect-inherit { user-select: inherit; }
.userSelect-none { user-select: none; }
.userSelect-text { user-select: text; }
/* visibility */
.visibility-collapse { visibility: collapse; }
.visibility-hidden { visibility: hidden; }
.visibility-inherit { visibility: inherit; }
.visibility-visible { visibility: visible; }
/* white-space */
.whiteSpace-normal { white-space: normal; }
.whiteSpace-nowrap { white-space: nowrap; }
.whiteSpace-pre { white-space: pre; }
.whiteSpace-pre-line { white-space: pre-line; }
.whiteSpace-pre-wrap { white-space: pre-wrap; }
/* width */
.width-0 { width: 0; }
.width-10\% { width: 10%; }
.width-12\.5\% { width: 12.5%; }
.width-20\% { width: 20%; }
.width-25\% { width: 25%; }
.width-30\% { width: 30%; }
.width-37\.5\% { width: 37.5%; }
.width-40\% { width: 40%; }
.width-50\% { width: 50%; }
.width-60\% { width: 60%; }
.width-62\.5\% { width: 62.5%; }
.width-70\% { width: 70%; }
.width-75\% { width: 75%; }
.width-80\% { width: 80%; }
.width-87\.5\% { width: 87.5%; }
.width-90\% { width: 90%; }
.width-100\% { width: 100%; }
/* word-wrap */
.wordWrap-break-word { word-wrap: break-word; }
.wordWrap-normal { word-wrap: normal; }
/* z-index */
.zIndex--1 { z-index: -1; }
.zIndex-0 { z-index: 0; }
.zIndex-1 { z-index: 1; }
.zIndex-2 { z-index: 2; }
.zIndex-3 { z-index: 3; }
.zIndex-4 { z-index: 4; }
.zIndex-5 { z-index: 5; }
.zIndex-6 { z-index: 6; }
.zIndex-7 { z-index: 7; }
.zIndex-8 { z-index: 8; }
.zIndex-9 { z-index: 9; }
.zIndex-10 { z-index: 10; }

9
src/specs.bundle.js Normal file
View File

@@ -0,0 +1,9 @@
/**
* This module creates a context of all the spec files (following a naming
* convention). It's used as the webpack entry file for unit tests.
*
* See: https://github.com/webpack/docs/wiki/context
*/
const specContext = require.context('.', true, /.+\.spec\.jsx?$/)
specContext.keys().forEach(specContext)
module.exports = specContext

View File

@@ -1,49 +0,0 @@
var autoprefixer = require('autoprefixer-core');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var localcss = require('postcss-modules-local-by-default');
var webpack = require('webpack');
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
module.exports = {
entry: {
main: './src/index'
},
externals: [{
react: true
}],
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract(
'style-loader',
'css-loader?module&localIdentName=[hash:base64:5]!postcss-loader'
)
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: { cacheDirectory: true }
}
]
},
output: {
filename: 'main.js',
library: 'ReactWebSDK',
libraryTarget: 'commonjs2',
path: './dist'
},
plugins: [
new ExtractTextPlugin('react-web-sdk.css'),
new UglifyJsPlugin({
compress: {
dead_code: true,
drop_console: true,
screw_ie8: true,
warnings: true
}
})
],
postcss: [ autoprefixer ]
};