mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-23 04:00:04 +08:00
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.
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
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 TextInput from './modules/TextInput';
|
||||
@@ -10,8 +8,6 @@ export default {
|
||||
getOtherProps,
|
||||
omitProps,
|
||||
pickProps,
|
||||
StylePropTypes,
|
||||
WebStyleComponent,
|
||||
Image,
|
||||
Text,
|
||||
TextInput,
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import {
|
||||
BorderThemePropTypes,
|
||||
LayoutPropTypes
|
||||
} from '../StylePropTypes';
|
||||
import { StylePropTypes } from '../react-web-style';
|
||||
import { PropTypes } from 'react';
|
||||
|
||||
export default {
|
||||
...BorderThemePropTypes,
|
||||
...LayoutPropTypes,
|
||||
...StylePropTypes.BorderThemePropTypes,
|
||||
...StylePropTypes.LayoutPropTypes,
|
||||
backgroundColor: PropTypes.string,
|
||||
boxShadow: PropTypes.string,
|
||||
opacity: PropTypes.number,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { pickProps } from '../filterObjectProps';
|
||||
import { WebStyleComponent } from '../react-web-style';
|
||||
import ImageStylePropTypes, { ImageDefaultStyles } from './ImageStylePropTypes';
|
||||
import React, { PropTypes } from 'react';
|
||||
import WebStyleComponent from '../WebStyleComponent';
|
||||
|
||||
class Image extends React.Component {
|
||||
static propTypes = {
|
||||
@@ -29,7 +29,7 @@ class Image extends React.Component {
|
||||
{...other}
|
||||
alt={alt}
|
||||
className={`sdk-Image ${className}`}
|
||||
element='img'
|
||||
component='img'
|
||||
style={mergedStyle}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { TypographicPropTypes } from '../StylePropTypes';
|
||||
import { StylePropTypes } from '../react-web-style';
|
||||
import { ViewStylePropTypes } from '../View/ViewStylePropTypes';
|
||||
|
||||
export default {
|
||||
...ViewStylePropTypes,
|
||||
...TypographicPropTypes
|
||||
...StylePropTypes.TypographicPropTypes
|
||||
};
|
||||
|
||||
export const TextDefaultStyles = {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { pickProps } from '../filterObjectProps';
|
||||
import { WebStyleComponent } from '../react-web-style';
|
||||
import React, { PropTypes } from 'react';
|
||||
import TextStylePropTypes, { TextDefaultStyle } from './TextStylePropTypes';
|
||||
import WebStyleComponent from '../WebStyleComponent';
|
||||
|
||||
class Text extends React.Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
element: PropTypes.oneOfType([
|
||||
component: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.string
|
||||
]),
|
||||
@@ -16,7 +16,7 @@ class Text extends React.Component {
|
||||
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
element: 'div'
|
||||
component: 'div'
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { PropTypes } from 'react';
|
||||
import { TypographicPropTypes } from '../StylePropTypes';
|
||||
import { StylePropTypes } from '../react-web-style';
|
||||
import ViewStylePropTypes from '../View/ViewStylePropTypes';
|
||||
|
||||
export default {
|
||||
...ViewStylePropTypes,
|
||||
...TypographicPropTypes
|
||||
...StylePropTypes.TypographicPropTypes
|
||||
};
|
||||
|
||||
export const TextInputDefaultStyles = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { pickProps } from '../filterObjectProps';
|
||||
import { WebStyleComponent } from '../react-web-style';
|
||||
import React, { PropTypes } from 'react';
|
||||
import TextInputStylePropTypes, { TextInputDefaultStyles } from './TextInputStylePropTypes';
|
||||
import WebStyleComponent from '../WebStyleComponent';
|
||||
|
||||
class TextInput extends React.Component {
|
||||
static propTypes = {
|
||||
@@ -26,8 +26,8 @@ class TextInput extends React.Component {
|
||||
<WebStyleComponent
|
||||
{...other}
|
||||
className={`sdk-TextInput ${className}`}
|
||||
component={multiline ? 'textarea' : 'input'}
|
||||
disabled={!editable}
|
||||
element={multiline ? 'textarea' : 'input'}
|
||||
placeholder={placeholder}
|
||||
style={mergedStyle}
|
||||
/>
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import {
|
||||
BackgroundPropTypes,
|
||||
BorderThemePropTypes,
|
||||
LayoutPropTypes
|
||||
} from '../StylePropTypes';
|
||||
|
||||
import { PropTypes } from 'react';
|
||||
import { StylePropTypes } from '../react-web-style';
|
||||
|
||||
export default {
|
||||
...BackgroundPropTypes,
|
||||
...BorderThemePropTypes,
|
||||
...LayoutPropTypes,
|
||||
...StylePropTypes.BackgroundPropTypes,
|
||||
...StylePropTypes.BorderThemePropTypes,
|
||||
...StylePropTypes.LayoutPropTypes,
|
||||
boxShadow: PropTypes.string,
|
||||
opacity: PropTypes.number,
|
||||
transform: PropTypes.string
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { pickProps } from '../filterObjectProps';
|
||||
import { WebStyleComponent } from '../react-web-style';
|
||||
import React, { PropTypes } from 'react';
|
||||
import ViewStylePropTypes, { ViewDefaultStyle } from './ViewStylePropTypes';
|
||||
import WebStyleComponent from '../WebStyleComponent';
|
||||
|
||||
class View extends React.Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
element: PropTypes.oneOfType([
|
||||
component: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.string
|
||||
]),
|
||||
@@ -22,11 +22,11 @@ class View extends React.Component {
|
||||
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
element: 'div'
|
||||
component: 'div'
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, element, pointerEvents, style, ...other } = this.props;
|
||||
const { className, pointerEvents, style, ...other } = this.props;
|
||||
const filteredStyle = pickProps(style, Object.keys(ViewStylePropTypes));
|
||||
const pointerEventsStyle = pointerEvents && { pointerEvents };
|
||||
const mergedStyle = {
|
||||
@@ -39,7 +39,6 @@ class View extends React.Component {
|
||||
<WebStyleComponent
|
||||
{...other}
|
||||
className={`sdk-View ${className}`}
|
||||
element={element}
|
||||
style={mergedStyle}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
33
src/modules/react-web-style/index.js
vendored
Normal file
33
src/modules/react-web-style/index.js
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import StylePropTypes from './StylePropTypes';
|
||||
import stylingStrategy from './strategy';
|
||||
|
||||
class WebStyleComponent extends React.Component {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
component: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.string
|
||||
]),
|
||||
style: PropTypes.object
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
element: 'div'
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { component: Component, ...other } = this.props;
|
||||
|
||||
return (
|
||||
<Component
|
||||
{...other}
|
||||
{...stylingStrategy(this.props)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { StylePropTypes, WebStyleComponent };
|
||||
38
src/modules/react-web-style/strategy.js
vendored
Normal file
38
src/modules/react-web-style/strategy.js
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import autoprefix from './autoprefix';
|
||||
import styleMap from './styleMap';
|
||||
|
||||
/**
|
||||
* Find declarations that correspond to single purpose classes
|
||||
*/
|
||||
function getSinglePurposeClassName(prop, style) {
|
||||
const uniqueClassName = `${prop}-${style[prop]}`;
|
||||
if (
|
||||
style.hasOwnProperty(prop) &&
|
||||
styleMap[uniqueClassName]
|
||||
) {
|
||||
return styleMap[uniqueClassName];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace inline styles with single purpose classes where possible
|
||||
*/
|
||||
export default function stylingStrategy(props) {
|
||||
const { className: origClassName, style: origStyle } = props;
|
||||
const classNames = [ origClassName ];
|
||||
const style = {};
|
||||
|
||||
for (const prop in origStyle) {
|
||||
const singlePurposeClassName = getSinglePurposeClassName(prop, origStyle);
|
||||
if (singlePurposeClassName) {
|
||||
classNames.push(singlePurposeClassName);
|
||||
} else {
|
||||
style[prop] = origStyle[prop];
|
||||
}
|
||||
}
|
||||
|
||||
const className = classNames.join(' ');
|
||||
const prefixedStyle = autoprefix(style);
|
||||
|
||||
return { className, style: prefixedStyle };
|
||||
}
|
||||
Reference in New Issue
Block a user