Skip to content

Commit

Permalink
feat(ConfigProvider): config-provider support rtl
Browse files Browse the repository at this point in the history
  • Loading branch information
youluna committed Nov 12, 2018
1 parent c7d6ea6 commit e91591a
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 40 deletions.
11 changes: 6 additions & 5 deletions docs/config-provider/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,12 @@ export default config(Component);

### ConfigProvider

| 参数 | 说明 | 类型 | 默认值 |
| -------- | ----------------------------------- | ------------ | ---- |
| pure | 是否开启 Pure Render 模式,会提高性能,但是也会带来副作用 | Boolean | - |
| warning | 是否在开发模式下显示组件属性被废弃的 warning 提示 | Boolean | true |
| children | 组件树 | ReactElement | - |
| 参数 | 说明 | 类型 | 默认值 |
| -------- | ----------------------------------- | ------------ | ----- |
| pure | 是否开启 Pure Render 模式,会提高性能,但是也会带来副作用 | Boolean | - |
| warning | 是否在开发模式下显示组件属性被废弃的 warning 提示 | Boolean | true |
| rtl | 是否开启 rtl 模式 | Boolean | false |
| children | 组件树 | ReactElement | - |

<!-- api-extra-start -->

Expand Down
65 changes: 48 additions & 17 deletions src/config-provider/config.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,15 @@ export function getLanguage() {

export function config(Component, options = {}) {
if (Component.prototype.shouldComponentUpdate === undefined) {
Component.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
Component.prototype.shouldComponentUpdate = function shouldComponentUpdate(
nextProps,
nextState
) {
if (this.props.pure) {
return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
return (
!shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState)
);
}

return true;
Expand All @@ -57,13 +63,15 @@ export function config(Component, options = {}) {
...(Component.propTypes || {}),
prefix: PropTypes.string,
locale: PropTypes.object,
pure: PropTypes.bool
pure: PropTypes.bool,
rtl: PropTypes.bool
};
static contextTypes = {
...(Component.contextTypes || {}),
nextPrefix: PropTypes.string,
nextLocale: PropTypes.object,
nextPure: PropTypes.bool,
nextRtl: PropTypes.bool,
nextWarning: PropTypes.bool
};

Expand Down Expand Up @@ -100,25 +108,48 @@ export function config(Component, options = {}) {
}

render() {
const { prefix, locale, pure, ...others } = this.props;
const { nextPrefix, nextLocale = {}, nextPure } = this.context;

const displayName = options.componentName || getDisplayName(Component);
const { prefix, locale, pure, rtl, ...others } = this.props;
const {
nextPrefix,
nextLocale = {},
nextPure,
nextRtl
} = this.context;

const displayName =
options.componentName || getDisplayName(Component);
const contextProps = getContextProps(
{ prefix, locale, pure },
{ nextPrefix, nextLocale: { ...currentGlobalLocale, ...nextLocale }, nextPure }, displayName
{ prefix, locale, pure, rtl },
{
nextPrefix,
nextLocale: { ...currentGlobalLocale, ...nextLocale },
nextPure,
nextRtl
},
displayName
);

const newContextProps = ['prefix', 'locale', 'pure'].reduce((ret, name) => {
if (typeof contextProps[name] !== 'undefined') {
ret[name] = contextProps[name];
}
return ret;
}, {});
const newContextProps = ['prefix', 'locale', 'pure', 'rtl'].reduce(
(ret, name) => {
if (typeof contextProps[name] !== 'undefined') {
ret[name] = contextProps[name];
}
return ret;
},
{}
);

const newOthers = options.transform ? options.transform(others, this._deprecated) : others;
const newOthers = options.transform ?
options.transform(others, this._deprecated) :
others;

return <Component {...newOthers} {...newContextProps} ref={this._getInstance} />;
return (
<Component
{...newOthers}
{...newContextProps}
ref={this._getInstance}
/>
);
}
}

Expand Down
18 changes: 8 additions & 10 deletions src/config-provider/consumer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,22 @@ const mapKeys = (obj, fn) => {
* @param {String} key
* @return {String}
*/
const replaceKey = key => key.replace(
/^(next)([A-Z])/,
(match, p1, p2) => p2.toLowerCase()
);
const replaceKey = key =>
key.replace(/^(next)([A-Z])/, (match, p1, p2) => p2.toLowerCase());

/**
* @param {Object} source
* @return {Object}
*/
const transformContext = (source) => mapKeys(source, replaceKey);
const transformContext = source => mapKeys(source, replaceKey);

/**
* Consumer
* @param {Object} prop
* @param {Object} context
*/
const Consumer = ({ children }, context) => (
typeof children === 'function' ? children(transformContext(context)) : null
);
const Consumer = ({ children }, context) =>
typeof children === 'function' ? children(transformContext(context)) : null;

/**
* PropTypes
Expand All @@ -55,7 +52,7 @@ const Consumer = ({ children }, context) => (
Consumer.propTypes = {
// Render context as function
// Function(context: object): ReactElement
children: PropTypes.func,
children: PropTypes.func
};

/**
Expand All @@ -67,7 +64,8 @@ Consumer.contextTypes = {
nextPrefix: PropTypes.string,
nextLocale: PropTypes.object,
nextPure: PropTypes.bool,
nextWarning: PropTypes.bool,
newRtl: PropTypes.bool,
nextWarning: PropTypes.bool
};

export default Consumer;
6 changes: 4 additions & 2 deletions src/config-provider/get-context-props.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default function getContextProps(props, context, displayName) {
const { prefix, locale, pure } = props;
const { nextPrefix, nextLocale, nextPure, nextWarning } = context;
const { prefix, locale, pure, rtl } = props;
const { nextPrefix, nextLocale, nextPure, nextWarning, nextRtl } = context;

const newPrefix = prefix || nextPrefix;

Expand All @@ -19,11 +19,13 @@ export default function getContextProps(props, context, displayName) {
}

const newPure = typeof pure === 'boolean' ? pure : nextPure;
const newRtl = typeof rtl === 'boolean' ? rtl : nextRtl;

return {
prefix: newPrefix,
locale: newLocale,
pure: newPure,
rtl: newRtl,
warning: nextWarning
};
}
37 changes: 31 additions & 6 deletions src/config-provider/index.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { Component, Children } from 'react';
import PropTypes from 'prop-types';
import getContextProps from './get-context-props';
import { config, initLocales, setLanguage, setLocale, getLocale, getLanguage } from './config';
import {
config,
initLocales,
setLanguage,
setLocale,
getLocale,
getLanguage
} from './config';
import Consumer from './consumer';

let childContextCache = {};
Expand All @@ -28,20 +35,26 @@ class ConfigProvider extends Component {
* 是否在开发模式下显示组件属性被废弃的 warning 提示
*/
warning: PropTypes.bool,
/**
* 是否开启 rtl 模式
*/
rtl: PropTypes.bool,
/**
* 组件树
*/
children: PropTypes.element
};

static defaultProps = {
warning: true
warning: true,
rtl: false
};

static childContextTypes = {
nextPrefix: PropTypes.string,
nextLocale: PropTypes.object,
nextPure: PropTypes.bool,
nextRtl: PropTypes.bool,
nextWarning: PropTypes.bool
};

Expand Down Expand Up @@ -73,23 +86,31 @@ class ConfigProvider extends Component {
static Consumer = Consumer;

static getContext = () => {
const { nextPrefix, nextLocale, nextPure, nextWarning } = childContextCache;
const {
nextPrefix,
nextLocale,
nextPure,
nextRtl,
nextWarning
} = childContextCache;

return {
prefix: nextPrefix,
locale: nextLocale,
pure: nextPure,
rtl: nextRtl,
warning: nextWarning
};
}
};

getChildContext() {
const { prefix, locale, pure, warning } = this.props;
const { prefix, locale, pure, warning, rtl } = this.props;

return {
nextPrefix: prefix,
nextLocale: locale,
nextPure: pure,
nextRtl: rtl,
nextWarning: warning
};
}
Expand All @@ -99,7 +120,11 @@ class ConfigProvider extends Component {
}

componentDidMount() {
childContextCache = Object.assign({}, this.getChildContext(), childContextCache);
childContextCache = Object.assign(
{},
this.getChildContext(),
childContextCache
);
}

componentWillReceiveProps(nextProps) {
Expand Down

0 comments on commit e91591a

Please sign in to comment.