Skip to content

Commit

Permalink
feat: add ConfigProvider to replace LocaleProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
JeromeLin committed Dec 14, 2020
1 parent fed4b22 commit a50a418
Show file tree
Hide file tree
Showing 49 changed files with 417 additions and 399 deletions.
Expand Up @@ -23,7 +23,7 @@ exports[`ActionSheet renders correctly 1`] = `
onMaskClick={[MockFunction]}
visible={true}
>
<LocaleReceiver
<ConfigReceiver
actions={
Array [
Object {
Expand Down Expand Up @@ -248,6 +248,6 @@ exports[`ActionSheet renders correctly 1`] = `
</WarnIfDeprecatedComp>
</ForwardRef(ForwardedRefComp)>
</ActionSheet>
</LocaleReceiver>
</ConfigReceiver>
</ForwardRef(forwardRef)>
`;
4 changes: 2 additions & 2 deletions components/action-sheet/index.tsx
@@ -1,4 +1,4 @@
import ActionSheet from './ActionSheet';
import LocaleReceiver from '../locale-receiver';
import ConfigReceiver from '../config-receiver';

export default LocaleReceiver('ActionSheet')(ActionSheet);
export default ConfigReceiver('ActionSheet')(ActionSheet);
1 change: 0 additions & 1 deletion components/alert/Alert.tsx
Expand Up @@ -3,7 +3,6 @@ import classnames from 'classnames';
import PropsType from './PropsType';
import Modal from '../modal';
import alertLocale from './locale/zh_CN';
// import { getRunTimeLocale } from '../locale-provider/LocaleProvider';

export interface AlertProps extends PropsType {
prefixCls?: string;
Expand Down
4 changes: 2 additions & 2 deletions components/alert/index.tsx
@@ -1,4 +1,4 @@
import Alert from './Alert';
import LocaleReceiver from '../locale-receiver';
import ConfigReceiver from '../config-receiver';

export default LocaleReceiver('Alert')(Alert);
export default ConfigReceiver('Alert')(Alert);
37 changes: 37 additions & 0 deletions components/config-provider/ConfigProvider.tsx
@@ -0,0 +1,37 @@
import React, { PureComponent, createContext, Context } from 'react';
import { ConfigProviderProps, Locale } from './PropsType';
import setTheme from './setTheme';
import setPrimaryColor from './setPrimaryColor';

const defaultConfig: ConfigProviderProps = {
locale: {} as any as Locale,
theme: 'light',
primary: '#00bc70',
};

export const LocaleContext: Context<Locale> = createContext(defaultConfig.locale);
export const ConfigContext: Context<ConfigProviderProps> = createContext(defaultConfig);

let runTimeLocale: Locale;
const changeRunTimeLocale = (locale: Locale) => {
runTimeLocale = locale;
};

export const getRunTimeLocale = () => runTimeLocale;

export default class ConfigProvider extends PureComponent<ConfigProviderProps, {}> {
static defaultProps = defaultConfig;

render() {
const { children, locale, theme, primary } = this.props;
changeRunTimeLocale(locale);
setTheme(theme);
setPrimaryColor(primary);

return (
<ConfigContext.Provider value={{ locale, theme, primary }}>
{React.Children.only(children)}
</ConfigContext.Provider>
);
}
}
11 changes: 11 additions & 0 deletions components/config-provider/PropsType.tsx
@@ -0,0 +1,11 @@
import localeCN from './locale/zh_CN';

export type Locale = typeof localeCN;
export type Theme = 'dark' | 'light';
export type Primary = string;

export interface ConfigProviderProps {
locale: Locale;
theme: Theme;
primary: Primary;
}
119 changes: 119 additions & 0 deletions components/config-provider/demo.md
@@ -0,0 +1,119 @@
# ConfigProvider 全局配置



## 基本用法
```jsx
import { useState } from 'react';
import { Cell, ConfigProvider, Button, SearchBar, Modal, Keyboard, Radio } from 'zarm';
import enUS from 'zarm/config-provider/locale/en_US';
import zhCN from 'zarm/config-provider/locale/zh_CN';

const Demo = () => {
const [lang, setLang] = useState(GlobalContext.lang);
const [theme, setTheme] = useState(GlobalContext.theme);
const [primary, setPrimary] = useState(GlobalContext.primary);

const locale = lang === 'enUS' ? enUS : zhCN;

const show = (key) => {
if (key === 'alert') {
Modal.alert({
title: '警告',
content: '这里是警告信息',
shape: 'radius'
});
} else {
Modal.confirm({
title: '确认信息',
content: '你确定要这样做吗?',
shape: 'radius'
})
}
};

return (
<ConfigProvider locale={locale} primary={primary} theme={theme}>
<>
<Cell
title="切换语言"
description={
<Radio.Group
compact
type="button"
value={lang}
onChange={setLang}
>
<Radio value="zhCN">中文</Radio>
<Radio value="enUS">EN</Radio>
</Radio.Group>
}
/>

<Cell
title="切换品牌色"
description={
<ul className="colors">
{
['#00bc70', '#1890ff', '#f5222d', '#fa541b', '#13c2c2', '#2f54ec', '#712fd1'].map((color, index) => {
return (
<li
key={+index}
style={{ backgroundColor: color }}
onClick={() => setPrimary(color)}
/>
);
})
}
</ul>
}
/>

<Cell
title="切换主题"
description={
<Radio.Group
compact
type="button"
value={theme}
onChange={(value) => setTheme(value)}
>
<Radio value="light">默认主题</Radio>
<Radio value="dark">暗黑主题</Radio>
</Radio.Group>
}
/>

<SearchBar />
<Keyboard />

<Cell
description={
<Button size="xs" onClick={() => show('alert')}>开启</Button>
}
>
警告框
</Cell>

<Cell
description={
<Button size="xs" onClick={() => show('confirm')}>开启</Button>
}
>
确认框
</Cell>
</>
</ConfigProvider>
);
}

ReactDOM.render(<Demo />, mountNode);
```



## API

| 属性 | 类型 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- |
| locale | Object | - | 语言包配置,默认为中文,语言包可到 zarm/lib/locale-provider/locale 目录下寻找 |
3 changes: 3 additions & 0 deletions components/config-provider/index.tsx
@@ -0,0 +1,3 @@
import ConfigProvider from './ConfigProvider';

export default ConfigProvider;
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions components/config-provider/setPrimaryColor.ts
@@ -0,0 +1,9 @@
import Color from 'color';

const setPrimaryColor = (color) => {
document.documentElement.style.setProperty('--theme-primary', color);
document.documentElement.style.setProperty('--theme-primary-dark', Color(color).darken(0.05));
document.documentElement.style.setProperty('--button-primary-shadow-color', Color(color).alpha(0.5).lighten(0.0));
};

export default setPrimaryColor;
@@ -1,3 +1,5 @@
import { Theme } from './PropsType';

const themes = {
'--theme-primary-lighter': '#303030',
'--color-text': 'rgba(255, 255, 255, 0.85)',
Expand All @@ -24,7 +26,6 @@ const themes = {
'--cell-arrow-color': '#666',
'--cell-arrow-disabled-color': '#333',
'--checkbox-background': '#000',
'--checkbox-border-color': 'transparent',
'--checkbox-disabled-background': '#555',
'--checkbox-disabled-color': 'rgba(255, 255, 255, 0.3)',
'--collapse-arrow-color': '#666',
Expand All @@ -34,7 +35,6 @@ const themes = {
'--keyboard-background': '#000',
'--loading-background': '#2b2c2d',
'--modal-background': '#2b2c2d',
'--modal-title-color': 'var(--color-text)',
'--modal-close-color': 'rgba(255, 255, 255, 0.3)',
'--modal-close-active-color': 'rgba(255, 255, 255, 0.65)',
'--nav-bar-color': '#1b1c1e',
Expand All @@ -46,7 +46,6 @@ const themes = {
'--picker-line': '#303030',
'--progress-background': 'var(--border-color)',
'--radio-background': '#000',
'--radio-border-color': 'transparent',
'--radio-disabled-background': '#555',
'--radio-disabled-color': 'rgba(255, 255, 255, 0.3)',
'--search-bar-background': '#1b1c1e',
Expand All @@ -61,7 +60,7 @@ const themes = {
'--tooltip-background': '#5b5c60',
};

const setDarkTheme = (value) => {
const setTheme = (value: Theme) => {
document.body.setAttribute('data-theme', value);
Object.keys(themes).forEach((key) => {
value === 'dark'
Expand All @@ -70,4 +69,4 @@ const setDarkTheme = (value) => {
});
};

export default setDarkTheme;
export default setTheme;
File renamed without changes.
@@ -1,21 +1,25 @@
import React, { Context } from 'react';
import hoistNonReactStatic from 'hoist-non-react-statics';
import { LocaleContext } from '../locale-provider/LocaleProvider';
import defaultLocaleData from '../locale-provider/locale/zh_CN';
import { ConfigContext, LocaleContext } from '../config-provider/ConfigProvider';
import defaultLocaleData from '../config-provider/locale/zh_CN';

const defaultConfigData = {
locale: defaultLocaleData,
};

type GetContextInnerType<T extends Context<any>> = T extends Context<infer R> ? R : never;
type nameType = keyof Omit<GetContextInnerType<typeof LocaleContext>, 'locale'>;

type ComponentType = new (...args: any[]) => any;

const LocaleReceiverWrapper = (name?: nameType, defaultLocale?: typeof defaultLocaleData) => {
const ConfigReceiverWrapper = (name?: nameType, defaultConfig?: typeof defaultConfigData) => {
return function InnerWrapper<T extends ComponentType>(WrappedComponent: T) {
const LocaleReceiver = (props: any) => {
const ConfigReceiver = (props: any) => {
return (
<LocaleContext.Consumer>
<ConfigContext.Consumer>
{
(locale) => {
const globalLocale = (locale.locale) ? locale : (defaultLocale || defaultLocaleData);
({ locale }) => {
const globalLocale = (locale.locale) ? locale : (defaultConfig?.locale || defaultConfigData?.locale);
const componentLocale = globalLocale[name || WrappedComponent.name as nameType];
const localeCode = globalLocale.locale;
const { forwardedRef, ...rest } = props;
Expand All @@ -30,16 +34,16 @@ const LocaleReceiverWrapper = (name?: nameType, defaultLocale?: typeof defaultLo
);
}
}
</LocaleContext.Consumer>
</ConfigContext.Consumer>
);
};
const forwardRef = (props: InstanceType<T>['props'], ref: React.Ref<InstanceType<T>>) => {
return <LocaleReceiver {...props} forwardedRef={ref} />;
return <ConfigReceiver {...props} forwardedRef={ref} />;
};
const LocaleReceiverWithRef = React.forwardRef<InstanceType<T>, InstanceType<T>['props']>(forwardRef);
hoistNonReactStatic(LocaleReceiverWithRef, WrappedComponent);
return LocaleReceiverWithRef as (T & typeof LocaleReceiverWithRef);
const ConfigReceiverWithRef = React.forwardRef<InstanceType<T>, InstanceType<T>['props']>(forwardRef);
hoistNonReactStatic(ConfigReceiverWithRef, WrappedComponent);
return ConfigReceiverWithRef as (T & typeof ConfigReceiverWithRef);
};
};

export default LocaleReceiverWrapper;
export default ConfigReceiverWrapper;
3 changes: 3 additions & 0 deletions components/config-receiver/index.tsx
@@ -0,0 +1,3 @@
import ConfigReceiver from './ConfigReceiver';

export default ConfigReceiver;
File renamed without changes.
4 changes: 2 additions & 2 deletions components/confirm/index.tsx
@@ -1,4 +1,4 @@
import Confirm from './Confirm';
import LocaleReceiver from '../locale-receiver';
import ConfigReceiver from '../config-receiver';

export default LocaleReceiver('Confirm')(Confirm);
export default ConfigReceiver('Confirm')(Confirm);
Expand Up @@ -7,7 +7,7 @@ exports[`DatePickerView DatePickerView time 1`] = `
placeholder="请选择时间"
title="选择时间"
>
<LocaleReceiver
<ConfigReceiver
defaultValue="2017-9-6 12:00"
forwardedRef={null}
mode="datetime"
Expand Down Expand Up @@ -2411,7 +2411,7 @@ exports[`DatePickerView DatePickerView time 1`] = `
</div>
</PickerView>
</DatePickerView>
</LocaleReceiver>
</ConfigReceiver>
</ForwardRef(forwardRef)>
`;

Expand All @@ -2424,7 +2424,7 @@ exports[`DatePickerView DatePickerView time 2`] = `
title="选择日期"
value="2017-9-6 12:00"
>
<LocaleReceiver
<ConfigReceiver
forwardedRef={null}
max="2019-11-23 21:00"
min="2007-01-03 11:00"
Expand Down Expand Up @@ -4582,6 +4582,6 @@ exports[`DatePickerView DatePickerView time 2`] = `
</div>
</PickerView>
</DatePickerView>
</LocaleReceiver>
</ConfigReceiver>
</ForwardRef(forwardRef)>
`;
4 changes: 2 additions & 2 deletions components/date-picker-view/index.tsx
@@ -1,4 +1,4 @@
import DatePickerView from './DatePickerView';
import LocaleReceiver from '../locale-receiver';
import ConfigReceiver from '../config-receiver';

export default LocaleReceiver('DatePickerView')(DatePickerView);
export default ConfigReceiver('DatePickerView')(DatePickerView);
4 changes: 2 additions & 2 deletions components/date-picker/index.tsx
@@ -1,4 +1,4 @@
import DatePicker from './DatePicker';
import LocaleReceiver from '../locale-receiver';
import ConfigReceiver from '../config-receiver';

export default LocaleReceiver('DatePicker')(DatePicker);
export default ConfigReceiver('DatePicker')(DatePicker);

0 comments on commit a50a418

Please sign in to comment.