mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-01-12 22:51:09 +08:00
Initial implementation
This commit is contained in:
327
README.md
Normal file
327
README.md
Normal file
@@ -0,0 +1,327 @@
|
||||
# react-web-sdk
|
||||
|
||||
**Experimental / API proof of concept**
|
||||
|
||||
Components for building web applications and SDKs. Based on `react-native`'s
|
||||
components.
|
||||
|
||||
1. Styles are plain JavaScript objects.
|
||||
2. Styles are passed to a component's `style` prop.
|
||||
3. Non-dynamic styles rely on static CSS classes.
|
||||
4. Dynamic styles are written as inline styles on the DOM node.
|
||||
|
||||
Each Component defines `StylePropTypes` and filters out any style properties
|
||||
that are not part of its style API. For example, `View` does not support any
|
||||
typographic properties. You must use `Text` to wrap and style any text strings.
|
||||
|
||||
### Implementation notes
|
||||
|
||||
The current implementation uses a prebuilt CSS library – 200+ single-purpose,
|
||||
obfuscated selectors. It provides a large number of common, knowable styles
|
||||
needed to build apps. This makes the foundational CSS fixed (~5KB gzipped) and
|
||||
highly cachable. Inline styles are used for anything the CSS library doesn't
|
||||
provide, but their use is significantly reduced.
|
||||
|
||||
A better implementation would generate the CSS library from the declarations
|
||||
defined in the source code, replace static variables (use webpack's
|
||||
`DefinePlugin`?), and only use inline-styles for dynamic, instance-specific
|
||||
styles.
|
||||
|
||||
What about media queries? Perhaps rely on `mediaMatch` and re-render when the
|
||||
`style` prop needs to change; works better with DOM-related changes that need
|
||||
to happen at breakpoints. And that would avoid the need for any additional
|
||||
CSS. Alternatively, rely on something similar to `react-style`'s approach and
|
||||
duplicate the single-purpose classes within static CSS media queries.
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import {Image, Text, View} from 'react-web-sdk';
|
||||
|
||||
class Example extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<View element="main" style={{ ...style.common, ...style.root }}>
|
||||
<Image alt="accessibility text" src="/image.png" style={style.image} />
|
||||
<Text style={{ ...style.common, ...(Math.random() > 0.5 && style.text) }}>
|
||||
Example component
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const style = {
|
||||
common: {
|
||||
backgroundColor: 'white',
|
||||
borderRadius: '1em'
|
||||
},
|
||||
root: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
image: {
|
||||
opacity: 0.5
|
||||
},
|
||||
text: {
|
||||
fontWeight: '300'
|
||||
}
|
||||
};
|
||||
|
||||
export default Example;
|
||||
```
|
||||
|
||||
## Component: `SDKComponent`
|
||||
|
||||
A component that manages styles across the `className` and `style` properties.
|
||||
The building block upon which all other components in `react-web-sdk` are
|
||||
build.
|
||||
|
||||
### PropTypes
|
||||
|
||||
All other props are transferred directly to the `element`.
|
||||
|
||||
+ `className`: `string`
|
||||
+ `element`: `func` or `string`
|
||||
+ `style`: `object`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
const ViewStylePropTypes = {
|
||||
opacity: PropTypes.number
|
||||
};
|
||||
|
||||
const ViewStyleDefaultProps = {
|
||||
opacity: 1
|
||||
};
|
||||
|
||||
class ViewExample extends React.Component {
|
||||
render() {
|
||||
// filter other props
|
||||
const other = ReactWebSDK.getOtherProps(this);
|
||||
// exclude other styles
|
||||
const supportedStyle = ReactWebSDK.objectWithProps(this.props.style, ViewStylePropTypes);
|
||||
// merge defaults with instance styles
|
||||
const style = { ...ViewStyleDefaultProps, ...supportedStyle }
|
||||
|
||||
return (
|
||||
<SDKComponent
|
||||
{...other}
|
||||
children={this.props.children}
|
||||
className={`ViewExample ${this.props.className}`}
|
||||
element={this.props.element}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Component: `Image`
|
||||
|
||||
TODO
|
||||
|
||||
### PropTypes
|
||||
|
||||
All other props are transferred directly to the `element`.
|
||||
|
||||
+ `alt`: `string`
|
||||
+ `async`: `bool` (TODO)
|
||||
+ `className`: `string`
|
||||
+ `src`: `string`
|
||||
+ `style`: `ImageStylePropTypes`
|
||||
|
||||
### ImageStylePropTypes
|
||||
|
||||
+ `BackgroundPropTypes`
|
||||
+ `BorderThemePropTypes`
|
||||
+ `LayoutPropTypes`
|
||||
+ `opacity`: `string`
|
||||
|
||||
|
||||
## Component: `Text`
|
||||
|
||||
Text layout and styles.
|
||||
|
||||
### PropTypes
|
||||
|
||||
All other props are transferred directly to the `element`.
|
||||
|
||||
+ `className`: `string`
|
||||
+ `element`: `func` or `string` (default `"div"`)
|
||||
+ `style`: `TextStylePropTypes`
|
||||
|
||||
### TextStylePropTypes
|
||||
|
||||
+ ViewStylePropTypes
|
||||
+ TypographicPropTypes
|
||||
|
||||
|
||||
## Component: `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
|
||||
any type.
|
||||
|
||||
### PropTypes
|
||||
|
||||
All other props are transferred directly to the `element`.
|
||||
|
||||
+ `className`: `string`
|
||||
+ `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).
|
||||
|
||||
```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
|
||||
};
|
||||
```
|
||||
|
||||
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`.
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
// TODO
|
||||
```
|
||||
|
||||
## StylePropTypes
|
||||
|
||||
### Background
|
||||
|
||||
+ `backgroundColor`: `string`
|
||||
+ `backgroundImage`: `string`
|
||||
+ `backgroundPosition`: `string`
|
||||
+ `backgroundRepeat`: `string`
|
||||
+ `backgroundSize`: `string`
|
||||
|
||||
### BorderTheme
|
||||
|
||||
+ `borderColor`: `string`
|
||||
+ `borderTopColor`: `string`
|
||||
+ `borderRightColor`: `string`
|
||||
+ `borderBottomColor`: `string`
|
||||
+ `borderLeftColor`: `string`
|
||||
+ `borderStyle`: `string`
|
||||
+ `borderRadius`: `number` or `string`
|
||||
+ `borderTopLeftRadius`: `number` or `string`
|
||||
+ `borderTopRightRadius`: `number` or `string`
|
||||
+ `borderBottomLeftRadius`: `number` or `string`
|
||||
+ `borderBottomRightRadius`: `number` or `string`
|
||||
|
||||
### BoxModel
|
||||
|
||||
+ `borderWidth`: `number` or `string`
|
||||
+ `borderTopWidth`: `number` or `string`
|
||||
+ `borderRightWidth`: `number` or `string`
|
||||
+ `borderBottomWidth`: `number` or `string`
|
||||
+ `borderLeftWidth`: `number` or `string`
|
||||
+ `boxSizing`: `oneOf('border-box', 'content-box')`
|
||||
+ `display`: `oneOf('block', 'flex', 'inline', 'inline-block', 'inline-flex')`
|
||||
+ `height`: `number` or `string`
|
||||
+ `margin`: `number` or `string`
|
||||
+ `marginTop`: `number` or `string`
|
||||
+ `marginRight`: `number` or `string`
|
||||
+ `marginBottom`: `number` or `string`
|
||||
+ `marginLeft`: `number` or `string`
|
||||
+ `padding`: `number` or `string`
|
||||
+ `paddingTop`: `number` or `string`
|
||||
+ `paddingRight`: `number` or `string`
|
||||
+ `paddingBottom`: `number` or `string`
|
||||
+ `paddingLeft`: `number` or `string`
|
||||
+ `width`: `number` or `string`
|
||||
|
||||
### Flexbox
|
||||
|
||||
* `alignContent`: `oneOf('center', 'flex-end', 'flex-start', 'stretch', 'space-around', 'space-between')`
|
||||
* `alignItems`: `oneOf('baseline', 'center', 'flex-end', 'flex-start', 'stretch')`
|
||||
* `alignSelf`: `oneOf('auto', 'baseline', 'center', 'flex-end', 'flex-start', 'stretch')`
|
||||
* `flexBasis`: `string`
|
||||
* `flexDirection`: `oneOf('column', 'column-reverse', 'row', 'row-reverse')`
|
||||
* `flexGrow`: `number`
|
||||
* `flexShrink`: `number`
|
||||
* `flexWrap`: `oneOf('nowrap', 'wrap', 'wrap-reverse')`
|
||||
* `justifyContent`: `oneOf('center', 'flex-end', 'flex-start', 'space-around', 'space-between')`
|
||||
* `order`: `number`
|
||||
|
||||
See this [guide to flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/).
|
||||
|
||||
### Layout
|
||||
|
||||
* BoxModel
|
||||
* Flexbox
|
||||
* Position
|
||||
|
||||
### Position
|
||||
|
||||
* `position`: `oneOf('absolute', 'fixed', 'relative')`
|
||||
* `bottom`: `number` or `string`
|
||||
* `left`: `number` or `string`
|
||||
* `right`: `number` or `string`
|
||||
* `top`: `number` or `string`
|
||||
* `zIndex`: `number`
|
||||
|
||||
### Typographic
|
||||
|
||||
* `direction`: `oneOf('auto', 'ltr', 'rtl')`
|
||||
* `fontFamily`: `string`
|
||||
* `fontSize`: `string`
|
||||
* `fontWeight`: `oneOf('100', '200', '300', '400', '500', '600', '700', '800', '900', 'bold', 'normal')`
|
||||
* `fontStyle`: `oneOf('normal', 'italic')`
|
||||
* `letterSpacing`: `string`
|
||||
* `lineHeight`: `number` or `string`
|
||||
* `textAlign`: `oneOf('auto', 'left', 'right', 'center')`
|
||||
* `textDecoration`: `oneOf('none', 'underline')`
|
||||
* `textTransform`: `oneOf('capitalize', 'lowercase', 'none', 'uppercase')`
|
||||
* `wordWrap`: `oneOf('break-word', 'normal')`
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
npm run build
|
||||
npm run build:watch
|
||||
open index.html
|
||||
```
|
||||
39
example.js
Normal file
39
example.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
import { Image, Text, View } from '.';
|
||||
|
||||
class Example extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={style.root}>
|
||||
{[1,2,3,4,5,6].map((item) => {
|
||||
return (
|
||||
<View style={{ ...style.box, ...(item === 6 && style.boxFull) }}>
|
||||
<Text style={{fontSize: '2rem'}}>{item}</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const style = {
|
||||
root: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
height: '100px'
|
||||
},
|
||||
box: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'lightblue',
|
||||
flexGrow: 1,
|
||||
justifyContent: 'center',
|
||||
borderColor: 'blue',
|
||||
borderWidth: '5px'
|
||||
},
|
||||
boxFull: {
|
||||
width: '100%'
|
||||
}
|
||||
}
|
||||
|
||||
React.render(<Example />, document.getElementById('react-root'));
|
||||
4
index.html
Normal file
4
index.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<div id="react-root"></div>
|
||||
<script src="dist/example.js"></script>
|
||||
14
index.js
Normal file
14
index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import getOtherProps, {objectWithProps} from './lib/getOtherProps';
|
||||
import Image from './lib/components/Image';
|
||||
import SDKComponent from './lib/components/SDKComponent';
|
||||
import Text from './lib/components/Text';
|
||||
import View from './lib/components/View';
|
||||
|
||||
export default {
|
||||
getOtherProps,
|
||||
Image,
|
||||
objectWithProps,
|
||||
SDKComponent,
|
||||
Text,
|
||||
View
|
||||
};
|
||||
0
lib/.gitkeep
Normal file
0
lib/.gitkeep
Normal file
9
lib/StylePropTypes/Background.js
Normal file
9
lib/StylePropTypes/Background.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import {PropTypes} from 'react';
|
||||
|
||||
export default {
|
||||
backgroundColor: PropTypes.string,
|
||||
backgroundImage: PropTypes.string,
|
||||
backgroundPosition: PropTypes.string,
|
||||
backgroundRepeat: PropTypes.string,
|
||||
backgroundSize: PropTypes.string
|
||||
};
|
||||
28
lib/StylePropTypes/BorderTheme.js
Normal file
28
lib/StylePropTypes/BorderTheme.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import {PropTypes} from 'react';
|
||||
|
||||
export default {
|
||||
// border-color
|
||||
borderColor: PropTypes.string,
|
||||
borderTopColor: PropTypes.string,
|
||||
borderRightColor: PropTypes.string,
|
||||
borderBottomColor: PropTypes.string,
|
||||
borderLeftColor: PropTypes.string,
|
||||
// border-style
|
||||
borderStyle: PropTypes.string,
|
||||
// border-radius
|
||||
borderRadius: PropTypes.oneOfType([
|
||||
PropTypes.number, PropTypes.string
|
||||
]),
|
||||
borderTopLeftRadius: PropTypes.oneOfType([
|
||||
PropTypes.number, PropTypes.string
|
||||
]),
|
||||
borderTopRightRadius: PropTypes.oneOfType([
|
||||
PropTypes.number, PropTypes.string
|
||||
]),
|
||||
borderBottomLeftRadius: PropTypes.oneOfType([
|
||||
PropTypes.number, PropTypes.string
|
||||
]),
|
||||
borderBottomRightRadius: PropTypes.oneOfType([
|
||||
PropTypes.number, PropTypes.string
|
||||
])
|
||||
};
|
||||
71
lib/StylePropTypes/BoxModel.js
Normal file
71
lib/StylePropTypes/BoxModel.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import {PropTypes} from 'react';
|
||||
|
||||
export default {
|
||||
boxSizing: PropTypes.oneOf([
|
||||
'border-box',
|
||||
'content-box'
|
||||
]),
|
||||
// display
|
||||
display: PropTypes.oneOf([
|
||||
'block',
|
||||
'flex',
|
||||
'inline',
|
||||
'inline-block',
|
||||
'inline-flex'
|
||||
]),
|
||||
// dimensions
|
||||
height: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
width: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
// border width
|
||||
borderWidth: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
borderTopWidth: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
borderRightWidth: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
borderBottomWidth: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
borderLeftWidth: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
// margin
|
||||
margin: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
marginTop: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
marginBottom: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
marginLeft: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
marginRight: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
// padding
|
||||
padding: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
paddingTop: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
paddingBottom: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
paddingLeft: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
]),
|
||||
paddingRight: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.number
|
||||
])
|
||||
};
|
||||
49
lib/StylePropTypes/Flexbox.js
Normal file
49
lib/StylePropTypes/Flexbox.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import {PropTypes} from 'react';
|
||||
|
||||
export default {
|
||||
alignContent: PropTypes.oneOf([
|
||||
'center',
|
||||
'flex-end',
|
||||
'flex-start',
|
||||
'stretch',
|
||||
'space-around',
|
||||
'space-between'
|
||||
]),
|
||||
alignItems: PropTypes.oneOf([
|
||||
'baseline',
|
||||
'center',
|
||||
'flex-end',
|
||||
'flex-start',
|
||||
'stretch'
|
||||
]),
|
||||
alignSelf: PropTypes.oneOf([
|
||||
'auto',
|
||||
'baseline',
|
||||
'center',
|
||||
'flex-end',
|
||||
'flex-start',
|
||||
'stretch'
|
||||
]),
|
||||
flexBasis: PropTypes.string,
|
||||
flexDirection: PropTypes.oneOf([
|
||||
'column',
|
||||
'column-reverse',
|
||||
'row',
|
||||
'row-reverse'
|
||||
]),
|
||||
flexGrow: PropTypes.number,
|
||||
flexShrink: PropTypes.number,
|
||||
flexWrap: PropTypes.oneOf([
|
||||
'nowrap',
|
||||
'wrap',
|
||||
'wrap-reverse'
|
||||
]),
|
||||
justifyContent: PropTypes.oneOf([
|
||||
'center',
|
||||
'flex-end',
|
||||
'flex-start',
|
||||
'space-around',
|
||||
'space-between'
|
||||
]),
|
||||
order: PropTypes.number
|
||||
};
|
||||
9
lib/StylePropTypes/Layout.js
Normal file
9
lib/StylePropTypes/Layout.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import BoxModel from './BoxModel';
|
||||
import Flexbox from './Flexbox';
|
||||
import Position from './Position';
|
||||
|
||||
export default {
|
||||
...BoxModel,
|
||||
...Flexbox,
|
||||
...Position
|
||||
};
|
||||
14
lib/StylePropTypes/Position.js
Normal file
14
lib/StylePropTypes/Position.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import {PropTypes} from 'react';
|
||||
|
||||
export default {
|
||||
position: PropTypes.oneOf([
|
||||
'absolute',
|
||||
'fixed',
|
||||
'relative'
|
||||
]),
|
||||
bottom: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
||||
left: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
||||
right: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
||||
top: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
||||
zIndex: PropTypes.number
|
||||
};
|
||||
30
lib/StylePropTypes/Typographic.js
Normal file
30
lib/StylePropTypes/Typographic.js
Normal file
@@ -0,0 +1,30 @@
|
||||
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'
|
||||
])
|
||||
};
|
||||
13
lib/StylePropTypes/index.js
Normal file
13
lib/StylePropTypes/index.js
Normal 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
|
||||
};
|
||||
47
lib/autoprefix.js
Normal file
47
lib/autoprefix.js
Normal file
@@ -0,0 +1,47 @@
|
||||
export default function prefixStyles(style) {
|
||||
if (style.hasOwnProperty('flexBasis')) {
|
||||
style = {
|
||||
WebkitFlexBasis: style.flexBasis,
|
||||
msFlexBasis: style.flexBasis,
|
||||
...style
|
||||
};
|
||||
}
|
||||
|
||||
if (style.hasOwnProperty('flexGrow')) {
|
||||
style = {
|
||||
WebkitBoxFlex: style.flexGrow,
|
||||
WebkitFlexGrow: style.flexGrow,
|
||||
msFlexPositive: style.flexGrow,
|
||||
...style
|
||||
};
|
||||
}
|
||||
|
||||
if (style.hasOwnProperty('flexShrink')) {
|
||||
style = {
|
||||
WebkitFlexShrink: style.flexShrink,
|
||||
msFlexNegative: style.flexShrink,
|
||||
...style
|
||||
};
|
||||
}
|
||||
|
||||
// NOTE: adding `;` to the string value prevents React from automatically
|
||||
// adding a `px` suffix to the unitless value
|
||||
if (style.hasOwnProperty('order')) {
|
||||
style = {
|
||||
WebkitBoxOrdinalGroup: `${parseInt(style.order, 10) + 1};`,
|
||||
WebkitOrder: `${style.order}`,
|
||||
msFlexOrder: `${style.order};`,
|
||||
...style
|
||||
};
|
||||
}
|
||||
|
||||
if (style.hasOwnProperty('transform')) {
|
||||
style = {
|
||||
WebkitTransform: style.transform,
|
||||
msTransform: style.transform,
|
||||
...style
|
||||
};
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
61
lib/components/Image.js
Normal file
61
lib/components/Image.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import {objectWithProps} from '../getOtherProps';
|
||||
import React, {PropTypes} from 'react';
|
||||
import StylePropTypes from '../StylePropTypes';
|
||||
import SDKComponent from './SDKComponent';
|
||||
|
||||
const ImageStyleDefaultProps = {
|
||||
backgroundColor: 'lightGray',
|
||||
borderWidth: 0,
|
||||
maxWidth: '100%'
|
||||
};
|
||||
|
||||
const ImageStylePropTypes = {
|
||||
...StylePropTypes.BorderThemePropTypes,
|
||||
...StylePropTypes.LayoutPropTypes,
|
||||
backgroundColor: PropTypes.string,
|
||||
opacity: PropTypes.string
|
||||
};
|
||||
|
||||
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 _getDefaultProps() {
|
||||
return {
|
||||
async: true,
|
||||
className: '',
|
||||
src: 'data:image/gif;base64,' +
|
||||
'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
|
||||
style: {}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { alt, className, src, style, ...other } = this.props;
|
||||
const filteredStyle = objectWithProps(style, Object.keys(ImageStylePropTypes));
|
||||
const mergedStyle = { ...ImageStyleDefaultProps, ...filteredStyle };
|
||||
|
||||
return (
|
||||
<SDKComponent
|
||||
{...other}
|
||||
alt={alt}
|
||||
className={`Image ${className}`}
|
||||
element="img"
|
||||
src={src}
|
||||
style={mergedStyle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Image.propTypes = Image._getPropTypes();
|
||||
Image.defaultProps = Image._getDefaultProps();
|
||||
|
||||
export default Image;
|
||||
74
lib/components/SDKComponent.js
Normal file
74
lib/components/SDKComponent.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import autoprefix from '../autoprefix';
|
||||
import getOtherProps from '../getOtherProps';
|
||||
import React, {PropTypes} from 'react';
|
||||
|
||||
// styles
|
||||
import styleMap from '../styleMap';
|
||||
|
||||
class SDKComponent 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 other = getOtherProps(this);
|
||||
const { classNames, inlineStyles } = this._separateClassNamesAndStyles();
|
||||
|
||||
return (
|
||||
<this.props.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 classNameProp = this.props.className;
|
||||
const styleProp = this.props.style;
|
||||
|
||||
let classNames = [ classNameProp ];
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
||||
SDKComponent.propTypes = SDKComponent._getPropTypes();
|
||||
SDKComponent.defaultProps = SDKComponent._getDefaultProps();
|
||||
|
||||
export default SDKComponent;
|
||||
65
lib/components/Text.js
Normal file
65
lib/components/Text.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import {objectWithProps} from '../getOtherProps';
|
||||
import React, {PropTypes} from 'react';
|
||||
import StylePropTypes from '../StylePropTypes';
|
||||
import SDKComponent from './SDKComponent';
|
||||
import {ViewStylePropTypes} from './View';
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
class Text extends React.Component {
|
||||
static _getPropTypes() {
|
||||
return {
|
||||
className: PropTypes.string,
|
||||
element: PropTypes.oneOfType([
|
||||
PropTypes.string, PropTypes.func
|
||||
]),
|
||||
style: PropTypes.shape(TextStylePropTypes)
|
||||
};
|
||||
}
|
||||
|
||||
static _getDefaultProps() {
|
||||
return {
|
||||
className: '',
|
||||
element: 'div',
|
||||
style: {}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, element, style, ...other } = this.props;
|
||||
const filteredStyle = objectWithProps(style, Object.keys(TextStylePropTypes));
|
||||
const mergedStyle = { ...TextStyleDefaultProps, ...filteredStyle };
|
||||
|
||||
return (
|
||||
<SDKComponent
|
||||
{...other}
|
||||
className={`Text ${className}`}
|
||||
element={element}
|
||||
style={mergedStyle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Text.propTypes = Text._getPropTypes();
|
||||
Text.defaultProps = Text._getDefaultProps();
|
||||
|
||||
export default Text;
|
||||
81
lib/components/View.js
Normal file
81
lib/components/View.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import {objectWithProps} from '../getOtherProps';
|
||||
import React, {PropTypes} from 'react';
|
||||
import StylePropTypes from '../StylePropTypes';
|
||||
import SDKComponent from './SDKComponent';
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
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 _getDefaultProps() {
|
||||
return {
|
||||
className: '',
|
||||
element: 'div',
|
||||
style: {}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, element, pointerEvents, style, ...other } = this.props;
|
||||
const filteredStyle = objectWithProps(style, Object.keys(ViewStylePropTypes));
|
||||
const pointerEventsStyle = pointerEvents && { pointerEvents };
|
||||
const mergedStyle = {
|
||||
...ViewStyleDefaultProps,
|
||||
...filteredStyle,
|
||||
...pointerEventsStyle
|
||||
};
|
||||
|
||||
return (
|
||||
<SDKComponent
|
||||
{...other}
|
||||
className={`View ${className}`}
|
||||
element={element}
|
||||
style={mergedStyle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
View.propTypes = View._getPropTypes();
|
||||
View.defaultProps = View._getDefaultProps();
|
||||
|
||||
export default View;
|
||||
export {ViewStylePropTypes};
|
||||
0
lib/css/.gitkeep
Normal file
0
lib/css/.gitkeep
Normal file
13
lib/css/background.css
Normal file
13
lib/css/background.css
Normal file
@@ -0,0 +1,13 @@
|
||||
:local .backgroundColor-#fff { background-color: #fff; }
|
||||
:local .backgroundColor-transparent { background-color: currentcolor; }
|
||||
|
||||
:local .backgroundImage { background-image: none; }
|
||||
|
||||
:local .backgroundPosition-center { background-position: center; }
|
||||
:local .backgroundSize-contain { background-size: contain; }
|
||||
:local .backgroundSize-cover { background-size: cover; }
|
||||
|
||||
:local .backgroundRepeat-no-repeat { background-repeat: no-repeat; }
|
||||
:local .backgroundRepeat-repeat { background-repeat: repeat; }
|
||||
:local .backgroundRepeat-repeat-x { background-repeat: repeat-x; }
|
||||
:local .backgroundRepeat-repeat-y { background-repeat: repeat-y; }
|
||||
42
lib/css/border.css
Normal file
42
lib/css/border.css
Normal file
@@ -0,0 +1,42 @@
|
||||
:local .borderColor-currentcolor { border-color: currentcolor; }
|
||||
:local .borderColor-transparent { border-color: transparent; }
|
||||
|
||||
:local .borderStyle-dotted { border-style: dotted; }
|
||||
:local .borderStyle-dashed { border-style: dashed; }
|
||||
:local .borderStyle-solid { border-style: solid; }
|
||||
|
||||
:local .borderWidth-0 { border-width: 0; }
|
||||
:local .borderTopWidth-0 { border-top-width: 0; }
|
||||
:local .borderRightWidth-0 { border-right-width: 0; }
|
||||
:local .borderBottomWidth-0 { border-bottom-width: 0; }
|
||||
:local .borderLeftWidth-0 { border-left-width: 0; }
|
||||
|
||||
:local .borderWidth-1px { border-width: 1px; }
|
||||
:local .borderTopWidth-1px { border-top-width: 1px; }
|
||||
:local .borderRightWidth-1px { border-right-width: 1px; }
|
||||
:local .borderBottomWidth-1px { border-bottom-width: 1px; }
|
||||
:local .borderLeftWidth-1px { border-left-width: 1px; }
|
||||
|
||||
:local .borderWidth-2px { border-width: 2px; }
|
||||
:local .borderTopWidth-2px { border-top-width: 2px; }
|
||||
:local .borderRightWidth-2px { border-right-width: 2px; }
|
||||
:local .borderBottomWidth-2px { border-bottom-width: 2px; }
|
||||
:local .borderLeftWidth-2px { border-left-width: 2px; }
|
||||
|
||||
:local .borderWidth-3px { border-width: 3px; }
|
||||
:local .borderTopWidth-3px { border-top-width: 3px; }
|
||||
:local .borderRightWidth-3px { border-right-width: 3px; }
|
||||
:local .borderBottomWidth-3px { border-bottom-width: 3px; }
|
||||
:local .borderLeftWidth-3px { border-left-width: 3px; }
|
||||
|
||||
:local .borderWidth-4px { border-width: 4px; }
|
||||
:local .borderTopWidth-4px { border-top-width: 4px; }
|
||||
:local .borderRightWidth-4px { border-right-width: 4px; }
|
||||
:local .borderBottomWidth-4px { border-bottom-width: 4px; }
|
||||
:local .borderLeftWidth-4px { border-left-width: 4px; }
|
||||
|
||||
:local .borderWidth-5px { border-width: 5px; }
|
||||
:local .borderTopWidth-5px { border-top-width: 5px; }
|
||||
:local .borderRightWidth-5px { border-right-width: 5px; }
|
||||
:local .borderBottomWidth-5px { border-bottom-width: 5px; }
|
||||
:local .borderLeftWidth-5px { border-left-width: 5px; }
|
||||
2
lib/css/boxSizing.css
Normal file
2
lib/css/boxSizing.css
Normal file
@@ -0,0 +1,2 @@
|
||||
:local .boxSizing-border-box { box-sizing: border-box; }
|
||||
:local .boxSizing-content-box { box-sizing: content-box; }
|
||||
4
lib/css/clear.css
Normal file
4
lib/css/clear.css
Normal file
@@ -0,0 +1,4 @@
|
||||
:local .clear-both { clear: both; }
|
||||
:local .clear-left { clear: left; }
|
||||
:local .clear-none { clear: none; }
|
||||
:local .clear-right { clear: right; }
|
||||
4
lib/css/color.css
Normal file
4
lib/css/color.css
Normal file
@@ -0,0 +1,4 @@
|
||||
:local .color-\#fff { color: #fff; }
|
||||
:local .color-\#000 { color: #000; }
|
||||
:local .color-transparent { color: transparent; }
|
||||
:local .color-inherit { color: inherit; }
|
||||
3
lib/css/direction.css
Normal file
3
lib/css/direction.css
Normal file
@@ -0,0 +1,3 @@
|
||||
:local .direction-auto { direction: auto; }
|
||||
:local .direction-ltr { direction: ltr; }
|
||||
:local .direction-rtl { direction: rtl; }
|
||||
12
lib/css/display.css
Normal file
12
lib/css/display.css
Normal file
@@ -0,0 +1,12 @@
|
||||
:local .display-block { display: block; }
|
||||
:local .display-flex { display: flex; }
|
||||
:local .display-inline { display: inline; }
|
||||
:local .display-inline-block { display: inline-block; }
|
||||
:local .display-inline-flex { display: inline-flex; }
|
||||
:local .display-inline-table { display: inline-table; }
|
||||
:local .display-none { display: none; }
|
||||
:local .display-table { display: table; }
|
||||
:local .display-table-row { display: table-row; }
|
||||
:local .display-table-cell { display: table-cell; }
|
||||
:local .display-table-column { display: table-column; }
|
||||
:local .display-table-column-group { display: table-column-group; }
|
||||
70
lib/css/flexbox.css
Normal file
70
lib/css/flexbox.css
Normal file
@@ -0,0 +1,70 @@
|
||||
:local .alignContent-center { align-content: center; }
|
||||
:local .alignContent-flex-end { align-content: flex-end; }
|
||||
:local .alignContent-flex-start { align-content: flex-start; }
|
||||
:local .alignContent-stretch { align-content: stretch; }
|
||||
:local .alignContent-space-around { align-content: space-around; }
|
||||
:local .alignContent-space-between { align-content: space-between; }
|
||||
|
||||
:local .alignItems-center { align-items: center; }
|
||||
:local .alignItems-flex-end { align-items: flex-end; }
|
||||
:local .alignItems-flex-start { align-items: flex-start; }
|
||||
:local .alignItems-stretch { align-items: stretch; }
|
||||
:local .alignItems-space-around { align-items: space-around; }
|
||||
:local .alignItems-space-between { align-items: space-between; }
|
||||
|
||||
:local .alignSelf-auto { align-self: auto; }
|
||||
:local .alignSelf-baseline { align-self: baseline; }
|
||||
:local .alignSelf-center { align-self: center; }
|
||||
:local .alignSelf-flex-end { align-self: flex-end; }
|
||||
:local .alignSelf-flex-start { align-self: flex-start; }
|
||||
:local .alignSelf-stretch { align-self: stretch; }
|
||||
|
||||
:local .flexBasis-0 { flex-basis: 0%; }
|
||||
:local .flexBasis-auto { flex-basis: auto; }
|
||||
|
||||
:local .flexDirection-column { flex-direction: column; }
|
||||
:local .flexDirection-column-reverse { flex-direction: column-reverse; }
|
||||
:local .flexDirection-row { flex-direction: row; }
|
||||
:local .flexDirection-row-reverse { flex-direction: row-reverse; }
|
||||
|
||||
:local .flexGrow-0 { flex-grow: 0; }
|
||||
:local .flexGrow-1 { flex-grow: 1; }
|
||||
:local .flexGrow-2 { flex-grow: 2; }
|
||||
:local .flexGrow-3 { flex-grow: 3; }
|
||||
:local .flexGrow-4 { flex-grow: 4; }
|
||||
:local .flexGrow-5 { flex-grow: 5; }
|
||||
:local .flexGrow-6 { flex-grow: 6; }
|
||||
:local .flexGrow-7 { flex-grow: 7; }
|
||||
:local .flexGrow-8 { flex-grow: 8; }
|
||||
:local .flexGrow-9 { flex-grow: 9; }
|
||||
|
||||
:local .flexShrink-0 { flex-shrink: 0; }
|
||||
:local .flexShrink-1 { flex-shrink: 1; }
|
||||
:local .flexShrink-2 { flex-shrink: 2; }
|
||||
:local .flexShrink-3 { flex-shrink: 3; }
|
||||
:local .flexShrink-4 { flex-shrink: 4; }
|
||||
:local .flexShrink-5 { flex-shrink: 5; }
|
||||
:local .flexShrink-6 { flex-shrink: 6; }
|
||||
:local .flexShrink-7 { flex-shrink: 7; }
|
||||
:local .flexShrink-8 { flex-shrink: 8; }
|
||||
:local .flexShrink-9 { flex-shrink: 9; }
|
||||
|
||||
:local .flexWrap-nowrap { flex-wrap: nowrap; }
|
||||
:local .flexWrap-wrap { flex-wrap: wrap; }
|
||||
:local .flexWrap-wrap-reverse { flex-wrap: wrap-reverse; }
|
||||
|
||||
:local .justifyContent-center { justify-content: center; }
|
||||
:local .justifyContent-flex-end { justify-content: flex-end; }
|
||||
:local .justifyContent-flex-start { justify-content: flex-start; }
|
||||
:local .justifyContent-space-around { justify-content: space-around; }
|
||||
:local .justifyContent-space-between { justify-content: space-between; }
|
||||
|
||||
:local .order-1 { order: 1; }
|
||||
:local .order-2 { order: 2; }
|
||||
:local .order-3 { order: 3; }
|
||||
:local .order-4 { order: 4; }
|
||||
:local .order-5 { order: 5; }
|
||||
:local .order-6 { order: 6; }
|
||||
:local .order-7 { order: 7; }
|
||||
:local .order-8 { order: 8; }
|
||||
:local .order-9 { order: 9; }
|
||||
3
lib/css/float.css
Normal file
3
lib/css/float.css
Normal file
@@ -0,0 +1,3 @@
|
||||
:local .float-left { float: left; }
|
||||
:local .float-none { float: none; }
|
||||
:local .float-right { float: right; }
|
||||
16
lib/css/font.css
Normal file
16
lib/css/font.css
Normal file
@@ -0,0 +1,16 @@
|
||||
:local .font-inherit { font: inherit; }
|
||||
|
||||
:local .fontStyle-italic { font-style: italic; }
|
||||
:local .fontStyle-normal { font-style: normal; }
|
||||
|
||||
:local .fontWeight-100 { font-weight: 100; }
|
||||
:local .fontWeight-200 { font-weight: 200; }
|
||||
:local .fontWeight-300 { font-weight: 300; }
|
||||
:local .fontWeight-400 { font-weight: 400; }
|
||||
:local .fontWeight-500 { font-weight: 500; }
|
||||
:local .fontWeight-600 { font-weight: 600; }
|
||||
:local .fontWeight-700 { font-weight: 700; }
|
||||
:local .fontWeight-800 { font-weight: 800; }
|
||||
:local .fontWeight-900 { font-weight: 900; }
|
||||
:local .fontWeight-bold { font-weight: bold; }
|
||||
:local .fontWeight-normal { font-weight: normal; }
|
||||
3
lib/css/height.css
Normal file
3
lib/css/height.css
Normal file
@@ -0,0 +1,3 @@
|
||||
:local .maxHeight-100\% { max-height: 100%; }
|
||||
:local .minHeight-100\% { min-height: 100%; }
|
||||
:local .height-100\% { height: 100%; }
|
||||
13
lib/css/margin.css
Normal file
13
lib/css/margin.css
Normal file
@@ -0,0 +1,13 @@
|
||||
:local .margin-0 { margin: 0; }
|
||||
:local .margin-auto { margin: auto; }
|
||||
:local .marginTop-0 { margin-top: 0; }
|
||||
:local .marginTop-auto { margin-top: auto; }
|
||||
|
||||
:local .marginRight-0 { margin-right: 0; }
|
||||
:local .marginRight-auto { margin-right: auto; }
|
||||
|
||||
:local .marginBottom-0 { margin-bottom: 0; }
|
||||
:local .marginBottom-auto { margin-bottom: auto; }
|
||||
|
||||
:local .marginLeft-0 { margin-left: 0; }
|
||||
:local .marginLeft-auto { margin-left: auto; }
|
||||
14
lib/css/overflow.css
Normal file
14
lib/css/overflow.css
Normal file
@@ -0,0 +1,14 @@
|
||||
:local .overflow-auto { overflow: auto; }
|
||||
:local .overflow-hidden { overflow: hidden; }
|
||||
:local .overflow-scroll { overflow: scroll; }
|
||||
:local .overflow-visible { overflow: visible; }
|
||||
|
||||
:local .overflowX-auto { overflow-x: auto; }
|
||||
:local .overflowX-hidden { overflow-x: hidden; }
|
||||
:local .overflowX-scroll { overflow-x: scroll; }
|
||||
:local .overflowX-visible { overflow-x: visible; }
|
||||
|
||||
:local .overflowY-auto { overflow-y: auto; }
|
||||
:local .overflowY-hidden { overflow-y: hidden; }
|
||||
:local .overflowY-scroll { overflow-y: scroll; }
|
||||
:local .overflowY-visible { overflow-y: visible; }
|
||||
17
lib/css/padding.css
Normal file
17
lib/css/padding.css
Normal file
@@ -0,0 +1,17 @@
|
||||
:local .padding-0 { padding: 0; }
|
||||
:local .paddingTop-0 { padding-top: 0; }
|
||||
:local .paddingRight-0 { padding-right: 0; }
|
||||
:local .paddingBottom-0 { padding-bottom: 0; }
|
||||
:local .paddingLeft-0 { padding-left: 0; }
|
||||
|
||||
:local .padding-1em { padding: 1em; }
|
||||
:local .paddingTop-1em { padding-top: 1em; }
|
||||
:local .paddingRight-1em { padding-right: 1em; }
|
||||
:local .paddingBottom-1em { padding-bottom: 1em; }
|
||||
:local .paddingLeft-1em { padding-left: 1em; }
|
||||
|
||||
:local .padding-1rem { padding: 1rem; }
|
||||
:local .paddingTop-1rem { padding-top: 1rem; }
|
||||
:local .paddingRight-1rem { padding-right: 1rem; }
|
||||
:local .paddingBottom-1rem { padding-bottom: 1rem; }
|
||||
:local .paddingLeft-1rem { padding-left: 1rem; }
|
||||
6
lib/css/pointerEvents.css
Normal file
6
lib/css/pointerEvents.css
Normal file
@@ -0,0 +1,6 @@
|
||||
:local .pointerEvents-auto { pointer-events: auto; }
|
||||
:local .pointerEvents-none { pointer-events: none; }
|
||||
:local .pointerEvents-box-none { pointer-events: none; }
|
||||
:local .pointerEvents-box-none * { pointer-events: auto;}
|
||||
:local .pointerEvents-box-only { pointer-events: auto; }
|
||||
:local .pointerEvents-box-only * { pointer-events: none; }
|
||||
13
lib/css/position.css
Normal file
13
lib/css/position.css
Normal file
@@ -0,0 +1,13 @@
|
||||
:local .position-absolute { position: absolute; }
|
||||
:local .position-fixed { position: fixed; }
|
||||
:local .position-relative { position: relative; }
|
||||
|
||||
:local .top-0 { top: 0; }
|
||||
:local .right-0 { right: 0; }
|
||||
:local .left-0 { left: 0; }
|
||||
:local .bottom-0 { bottom: 0; }
|
||||
|
||||
:local .top-100\% { top: 100%; }
|
||||
:local .right-100\% { right: 100%; }
|
||||
:local .left-100\% { left: 100%; }
|
||||
:local .bottom-100\% { bottom: 100%; }
|
||||
14
lib/css/text.css
Normal file
14
lib/css/text.css
Normal file
@@ -0,0 +1,14 @@
|
||||
:local .textAlign-center { text-align: center; }
|
||||
:local .textAlign-left { text-align: left; }
|
||||
:local .textAlign-right { text-align: right; }
|
||||
:local .textAlign-justify { text-align: justify; }
|
||||
|
||||
:local .textDecoration-none { text-decoration: none; }
|
||||
:local .textDecoration-underline { text-decoration: underline; }
|
||||
|
||||
:local .textOverflow-ellipsis { text-overflow: ellipsis }
|
||||
|
||||
:local .textTransform-capitalize { text-transform: capitalize; }
|
||||
:local .textTransform-lowercase { text-transform: lowercase; }
|
||||
:local .textTransform-none { text-transform: none; }
|
||||
:local .textTransform-uppercase { text-transform: uppercase; }
|
||||
3
lib/css/userSelect.css
Normal file
3
lib/css/userSelect.css
Normal file
@@ -0,0 +1,3 @@
|
||||
:local .userSelect-all { user-select: all; }
|
||||
:local .userSelect-inherit { user-select: inherit; }
|
||||
:local .userSelect-none { user-select: none; }
|
||||
2
lib/css/visibility.css
Normal file
2
lib/css/visibility.css
Normal file
@@ -0,0 +1,2 @@
|
||||
:local .visibility-hidden { visibility: hidden; }
|
||||
:local .visibility-visible { visibility: visible; }
|
||||
3
lib/css/whiteSpace.css
Normal file
3
lib/css/whiteSpace.css
Normal file
@@ -0,0 +1,3 @@
|
||||
:local .whiteSpace-normal { white-space: normal; }
|
||||
:local .whiteSpace-nowrap { white-space: nowrap; }
|
||||
:local .whiteSpace-pre { white-space: pre; }
|
||||
3
lib/css/width.css
Normal file
3
lib/css/width.css
Normal file
@@ -0,0 +1,3 @@
|
||||
:local .maxWidth-100\% { max-width: 100%; }
|
||||
:local .minWidth-100\% { min-width: 100%; }
|
||||
:local .width-100\% { width: 100%; }
|
||||
2
lib/css/word.css
Normal file
2
lib/css/word.css
Normal file
@@ -0,0 +1,2 @@
|
||||
:local .wordWrap-break-word { word-wrap: break-word; }
|
||||
:local .wordWrap-normal { word-wrap: normal; }
|
||||
12
lib/css/zIndex.css
Normal file
12
lib/css/zIndex.css
Normal file
@@ -0,0 +1,12 @@
|
||||
:local .zIndex--1 { z-index: -1; }
|
||||
:local .zIndex-0 { z-index: 0; }
|
||||
:local .zIndex-1 { z-index: 1; }
|
||||
:local .zIndex-2 { z-index: 2; }
|
||||
:local .zIndex-3 { z-index: 3; }
|
||||
:local .zIndex-4 { z-index: 4; }
|
||||
:local .zIndex-5 { z-index: 5; }
|
||||
:local .zIndex-6 { z-index: 6; }
|
||||
:local .zIndex-7 { z-index: 7; }
|
||||
:local .zIndex-8 { z-index: 8; }
|
||||
:local .zIndex-9 { z-index: 9; }
|
||||
:local .zIndex-10 { z-index: 10; }
|
||||
37
lib/getOtherProps.js
Normal file
37
lib/getOtherProps.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Extract all props that are not part of the React Component's 'propTypes'
|
||||
*/
|
||||
export default (componentInstance) => {
|
||||
const excludedProps = Object.keys(componentInstance.constructor.propTypes);
|
||||
return objectWithoutProps(componentInstance.props, excludedProps);
|
||||
};
|
||||
|
||||
function objectFilterProps(obj, props, excluded=false) {
|
||||
if (!Array.isArray(props)) {
|
||||
throw new TypeError('props is not an Array');
|
||||
}
|
||||
|
||||
let filtered = {};
|
||||
for (let prop in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
||||
let isMatch = props.indexOf(prop) > -1;
|
||||
if (excluded && isMatch) {
|
||||
continue;
|
||||
} else if (!excluded && !isMatch) {
|
||||
continue;
|
||||
}
|
||||
|
||||
filtered[prop] = obj[prop];
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
export function objectWithProps(obj, props) {
|
||||
return objectFilterProps(obj, props);
|
||||
}
|
||||
|
||||
export function objectWithoutProps(obj, props) {
|
||||
return objectFilterProps(obj, props, true);
|
||||
}
|
||||
47
lib/styleMap.js
Normal file
47
lib/styleMap.js
Normal file
@@ -0,0 +1,47 @@
|
||||
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 margin from './css/margin.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 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';
|
||||
|
||||
const map = Object.assign({},
|
||||
border,
|
||||
boxSizing,
|
||||
clear,
|
||||
color,
|
||||
cssFloat,
|
||||
direction,
|
||||
display,
|
||||
flexbox,
|
||||
font,
|
||||
height,
|
||||
margin,
|
||||
overflow,
|
||||
padding,
|
||||
pointerEvents,
|
||||
position,
|
||||
text,
|
||||
userSelect,
|
||||
visibility,
|
||||
whiteSpace,
|
||||
width,
|
||||
word
|
||||
);
|
||||
|
||||
export default map;
|
||||
24
package.json
24
package.json
@@ -3,6 +3,28 @@
|
||||
"version": "0.0.1",
|
||||
"description": "UI SDK based on react-native",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "npm run build:package & npm run build:example",
|
||||
"build:example": "webpack index.js dist/main.js --config webpack.config.js",
|
||||
"build:example:watch": "npm run build:example -- --watch",
|
||||
"build:package": "webpack example.js dist/example.js --config webpack.config.js",
|
||||
"build:package:watch": "npm run build:package -- --watch",
|
||||
"build:watch": "npm run build:package:watch & npm run build:example:watch"
|
||||
},
|
||||
"author": "Nicolas Gallagher",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"autoprefixer-core": "^5.2.0",
|
||||
"babel-core": "^5.5.6",
|
||||
"babel-loader": "^5.1.4",
|
||||
"babel-runtime": "^5.5.6",
|
||||
"css-loader": "^0.14.4",
|
||||
"node-libs-browser": "^0.5.2",
|
||||
"postcss-loader": "^0.4.4",
|
||||
"style-loader": "^0.12.3",
|
||||
"webpack": "^1.9.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^0.13.3"
|
||||
}
|
||||
}
|
||||
|
||||
19
webpack.config.js
Normal file
19
webpack.config.js
Normal file
@@ -0,0 +1,19 @@
|
||||
var autoprefixer = require('autoprefixer-core');
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: 'style-loader!css-loader?localIdentName=[hash:base64:5]!postcss-loader'
|
||||
},
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
query: { cacheDirectory: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
postcss: [ autoprefixer ]
|
||||
};
|
||||
Reference in New Issue
Block a user