feat: update config-provider
parent
2875d57a25
commit
50018321a2
|
@ -1,5 +1,5 @@
|
|||
module.exports = {
|
||||
dev: {
|
||||
componentName: 'checkbox', // dev components
|
||||
componentName: 'config-provider', // dev components
|
||||
},
|
||||
};
|
||||
|
|
|
@ -162,7 +162,7 @@ export default {
|
|||
|
||||
render() {
|
||||
if (this.configProvider.csp) {
|
||||
this.csp = csp;
|
||||
this.csp = this.configProvider.csp;
|
||||
}
|
||||
return this.$slots.default && this.$slots.default[0];
|
||||
},
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import { mount } from '@vue/test-utils';
|
||||
import ConfigProvider from '..';
|
||||
import Button from '../../button';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
|
||||
describe('ConfigProvider', () => {
|
||||
mountTest({
|
||||
render() {
|
||||
return (
|
||||
<ConfigProvider>
|
||||
<div />
|
||||
</ConfigProvider>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
it('Content Security Policy', () => {
|
||||
const csp = { nonce: 'test-antd' };
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return (
|
||||
<ConfigProvider csp={csp}>
|
||||
<Button />
|
||||
</ConfigProvider>
|
||||
);
|
||||
},
|
||||
});
|
||||
expect(wrapper.find({ name: 'Wave' }).vm.csp).toBe(csp);
|
||||
});
|
||||
|
||||
it('autoInsertSpaceInButton', () => {
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return (
|
||||
<ConfigProvider autoInsertSpaceInButton={false}>
|
||||
<Button>确定</Button>
|
||||
</ConfigProvider>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.find({ name: 'AButton' }).text()).toBe('确定');
|
||||
});
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
<script>
|
||||
import Locale from './locale.md';
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
|
||||
|
@ -16,9 +17,14 @@ export default {
|
|||
type: '其他',
|
||||
title: 'ConfigProvider',
|
||||
render() {
|
||||
const csp = { nonce: 'test-antd' };
|
||||
return (
|
||||
<div>
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<Locale />
|
||||
<a-config-provider csp={csp}>
|
||||
<a-button>确定</a-button>
|
||||
</a-config-provider>
|
||||
<api>
|
||||
<template slot="cn">
|
||||
<CN />
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
<cn>
|
||||
#### 国际化
|
||||
此处列出 Ant Design Vue 中需要国际化支持的组件,你可以在演示里切换语言。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Locale
|
||||
Components which need localization support are listed here, you can toggle the language in the demo.
|
||||
</us>
|
||||
|
||||
```tpl
|
||||
<template>
|
||||
<div>
|
||||
<div class="change-locale">
|
||||
<span style="margin-right: 16px">Change locale of components: </span>
|
||||
<a-radio-group :value="locale" @change="changeLocale">
|
||||
<a-radio-button key="en" :value="enUS">
|
||||
English
|
||||
</a-radio-button>
|
||||
<a-radio-button key="cn" :value="zhCN">
|
||||
中文
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<a-config-provider :locale="locale">
|
||||
<div :key="locale ? locale.locale : 'en'" class="locale-components">
|
||||
<div class="example">
|
||||
<a-pagination :default-current="1" :total="50" show-size-changer />
|
||||
</div>
|
||||
<div class="example">
|
||||
<a-select show-search style="width: 200px">
|
||||
<a-select-option value="jack">
|
||||
jack
|
||||
</a-select-option>
|
||||
<a-select-option value="lucy">
|
||||
lucy
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-date-picker />
|
||||
<a-time-picker />
|
||||
<a-range-picker style="width: 200px" />
|
||||
</div>
|
||||
<div class="example">
|
||||
<a-button type="primary" @click="visible = true">
|
||||
Show Modal
|
||||
</a-button>
|
||||
<a-button @click="info">
|
||||
Show info
|
||||
</a-button>
|
||||
<a-button @click="confirm">
|
||||
Show confirm
|
||||
</a-button>
|
||||
<a-popconfirm title="Question?">
|
||||
<a href="#">Click to confirm</a>
|
||||
</a-popconfirm>
|
||||
</div>
|
||||
<div class="example">
|
||||
<a-transfer :data-source="[]" show-search :target-keys="[]" :render="item => item.title" />
|
||||
</div>
|
||||
<div style="width: 319px; border: 1px solid #d9d9d9; border-radius: 4px">
|
||||
<a-calendar :fullscreen="false" :value="moment()" />
|
||||
</div>
|
||||
<div class="example">
|
||||
<a-table :data-source="[]" :columns="columns" />
|
||||
</div>
|
||||
<a-modal v-model="visible" title="Locale Modal">
|
||||
<p>Locale Modal</p>
|
||||
</a-modal>
|
||||
</div>
|
||||
</a-config-provider>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import enUS from 'ant-design-vue/locale-provider/en_US';
|
||||
import zhCN from 'ant-design-vue/locale-provider/zh_CN';
|
||||
import moment from 'moment';
|
||||
import 'moment/locale/zh-cn';
|
||||
|
||||
moment.locale('en');
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
filters: [
|
||||
{
|
||||
text: 'filter1',
|
||||
value: 'filter1',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
},
|
||||
];
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
columns,
|
||||
visible: false,
|
||||
locale: enUS,
|
||||
moment,
|
||||
enUS,
|
||||
zhCN,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changeLocale(e) {
|
||||
const localeValue = e.target.value;
|
||||
this.locale = localeValue;
|
||||
if (!localeValue) {
|
||||
moment.locale('en');
|
||||
} else {
|
||||
moment.locale('zh-cn');
|
||||
}
|
||||
},
|
||||
info() {
|
||||
this.$info({
|
||||
title: 'some info',
|
||||
content: 'some info',
|
||||
});
|
||||
},
|
||||
confirm(){
|
||||
this.$confirm({
|
||||
title: 'some info',
|
||||
content: 'some info',
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.locale-components {
|
||||
border-top: 1px solid #d9d9d9;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.example {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.example > * {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.change-locale {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -1,9 +0,0 @@
|
|||
<svg width="64" height="41" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0 1)" fill="none" fill-rule="evenodd">
|
||||
<ellipse fill="#F5F5F5" cx="32" cy="33" rx="32" ry="7"/>
|
||||
<g fill-rule="nonzero" stroke="#D9D9D9">
|
||||
<path d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"/>
|
||||
<path d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z" fill="#FAFAFA"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 657 B |
|
@ -25,7 +25,7 @@ This component provides a configuration to all Vue components underneath itself
|
|||
|
||||
### Content Security Policy
|
||||
|
||||
Some component use dynamic style to support wave effect. You can config `csp` prop if Content Security Policy (CSP) is enabled:
|
||||
Some components use dynamic style to support wave effect. You can config `csp` prop if Content Security Policy (CSP) is enabled:
|
||||
|
||||
```html
|
||||
<a-config-provider :csp="{ nonce: 'YourNonceCode' }">
|
||||
|
@ -35,10 +35,36 @@ Some component use dynamic style to support wave effect. You can config `csp` pr
|
|||
|
||||
## API
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| autoInsertSpaceInButton | Set `false` to remove space between 2 chinese characters on Button | boolean | true |
|
||||
| csp | Set [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) config | { nonce: string } | - |
|
||||
| renderEmpty | set empty content of components. Ref [Empty](/components/empty/) | slot-scope \| Function(componentName: string): ReactNode | - |
|
||||
| getPopupContainer | to set the container of the popup element. The default is to create a `div` element in `body`. | Function(triggerNode, dialogContext) | `() => document.body` |
|
||||
| prefixCls | set prefix class | string | ant |
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| autoInsertSpaceInButton | Set `false` to remove space between 2 chinese characters on Button | boolean | true | |
|
||||
| csp | Set [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) config | { nonce: string } | - | |
|
||||
| renderEmpty | set empty content of components. Ref [Empty](/components/empty/) | slot-scope \| Function(componentName: string): ReactNode | - | |
|
||||
| getPopupContainer | to set the container of the popup element. The default is to create a `div` element in `body`. | Function(triggerNode, dialogContext) | `() => document.body` | |
|
||||
| locale | language package setting, you can find the packages in [antd/es/locale](http://unpkg.com/ant-design-vue/es/locale/) | object | - | 1.5.0 |
|
||||
| prefixCls | set prefix class | string | ant | |
|
||||
| pageHeader | Unify the ghost of pageHeader ,Ref [pageHeader](<(/components/page-header)> | { ghost:boolean } | 'true' | 1.5.0 |
|
||||
|
||||
## FAQ
|
||||
|
||||
#### Does the locale problem still exist in DatePicker even if ConfigProvider `locale` is used?
|
||||
|
||||
Please make sure you set moment locale by `moment.locale('zh-cn')` or that you don't have two different versions of moment.
|
||||
|
||||
#### Modal throw error when setting `getPopupContainer`?
|
||||
|
||||
When you config `getPopupContainer` to parentNode globally, Modal will throw error of `triggerNode is undefined` because it did not have a triggerNode.
|
||||
|
||||
```diff
|
||||
<ConfigProvider
|
||||
- getPopupContainer={triggerNode => triggerNode.parentNode}
|
||||
+ getPopupContainer={node => {
|
||||
+ if (node) {
|
||||
+ return node.parentNode;
|
||||
+ }
|
||||
+ return document.body;
|
||||
+ }}
|
||||
>
|
||||
<App />
|
||||
</ConfigProvider>
|
||||
```
|
||||
|
|
|
@ -3,11 +3,13 @@ import PropTypes from '../_util/vue-types';
|
|||
import { filterEmpty, getComponentFromProp } from '../_util/props-util';
|
||||
import defaultRenderEmpty from './renderEmpty';
|
||||
import Base from '../base';
|
||||
import LocaleProvider, { ANT_MARK } from '../locale-provider';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
|
||||
function getWatch(keys = []) {
|
||||
const watch = {};
|
||||
keys.forEach(k => {
|
||||
watch[k] = function() {
|
||||
watch[k] = function(value) {
|
||||
this._proxyVm._data[k] = value;
|
||||
};
|
||||
});
|
||||
|
@ -22,6 +24,8 @@ const ConfigProvider = {
|
|||
renderEmpty: PropTypes.func,
|
||||
csp: PropTypes.object,
|
||||
autoInsertSpaceInButton: PropTypes.bool,
|
||||
locale: PropTypes.object,
|
||||
pageHeader: PropTypes.object,
|
||||
},
|
||||
provide() {
|
||||
const _self = this;
|
||||
|
@ -39,7 +43,7 @@ const ConfigProvider = {
|
|||
};
|
||||
},
|
||||
watch: {
|
||||
...getWatch(['prefixCls', 'csp', 'autoInsertSpaceInButton']),
|
||||
...getWatch(['prefixCls', 'csp', 'autoInsertSpaceInButton', 'locale', 'pageHeader']),
|
||||
},
|
||||
methods: {
|
||||
renderEmptyComponent(h, name) {
|
||||
|
@ -52,9 +56,21 @@ const ConfigProvider = {
|
|||
if (customizePrefixCls) return customizePrefixCls;
|
||||
return suffixCls ? `${prefixCls}-${suffixCls}` : prefixCls;
|
||||
},
|
||||
renderProvider(legacyLocale) {
|
||||
return (
|
||||
<LocaleProvider locale={this.locale || legacyLocale} _ANT_MARK__={ANT_MARK}>
|
||||
{this.$slots.default ? filterEmpty(this.$slots.default)[0] : null}
|
||||
</LocaleProvider>
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
return this.$slots.default ? filterEmpty(this.$slots.default)[0] : null;
|
||||
return (
|
||||
<LocaleReceiver
|
||||
scopedSlots={{ default: (_, __, legacyLocale) => this.renderProvider(legacyLocale) }}
|
||||
/>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -35,10 +35,35 @@ ConfigProvider 使用 Vue 的 [provide / inject](https://vuejs.org/v2/api/#provi
|
|||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| autoInsertSpaceInButton | 设置为 `false` 时,移除按钮中 2 个汉字之间的空格 | boolean | true |
|
||||
| csp | 设置 [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 配置 | { nonce: string } | - |
|
||||
| renderEmpty | 自定义组件空状态。参考 [空状态](/components/empty/) | slot-scope \| Function(componentName: string): VNode | - |
|
||||
| getPopupContainer | 弹出框(Select, Tooltip, Menu 等等)渲染父节点,默认渲染到 body 上。 | Function(triggerNode, dialogContext) | () => document.body |
|
||||
| prefixCls | 设置统一样式前缀 | string | ant |
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| autoInsertSpaceInButton | 设置为 `false` 时,移除按钮中 2 个汉字之间的空格 | boolean | true | |
|
||||
| csp | 设置 [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 配置 | { nonce: string } | - | |
|
||||
| renderEmpty | 自定义组件空状态。参考 [空状态](/components/empty/) | slot-scope \| Function(componentName: string): VNode | - | |
|
||||
| getPopupContainer | 弹出框(Select, Tooltip, Menu 等等)渲染父节点,默认渲染到 body 上。 | Function(triggerNode, dialogContext) | () => document.body | |
|
||||
| locale | 语言包配置,语言包可到 [antd/es/locale](http://unpkg.com/antd/es/locale/) 目录下寻找 | object | - | 1.5.0 |
|
||||
| pageHeader | 统一设置 pageHeader 的 ghost,参考 [pageHeader](<(/components/page-header)>) | { ghost: boolean } | 'true' | 1.5.0 |
|
||||
|
||||
## FAQ
|
||||
|
||||
#### 为什么我使用了 ConfigProvider `locale`,时间类组件的国际化还有问题?
|
||||
|
||||
请检查是否设置了 `moment.locale('zh-cn')`,或者是否有两个版本的 moment 共存。
|
||||
|
||||
#### 配置 `getPopupContainer` 导致 Modal 报错?
|
||||
|
||||
当如下全局设置 `getPopupContainer` 为触发节点的 parentNode 时,由于 Modal 的用法不存在 `triggerNode`,这样会导致 `triggerNode is undefined` 的报错,需要增加一个判断条件。
|
||||
|
||||
```diff
|
||||
<ConfigProvider
|
||||
- getPopupContainer={triggerNode => triggerNode.parentNode}
|
||||
+ getPopupContainer={node => {
|
||||
+ if (node) {
|
||||
+ return node.parentNode;
|
||||
+ }
|
||||
+ return document.body;
|
||||
+ }}
|
||||
>
|
||||
<App />
|
||||
</ConfigProvider>
|
||||
```
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import PropTypes from '../_util/vue-types';
|
||||
import Empty from '../empty';
|
||||
import emptyImg from './empty.svg';
|
||||
import { ConfigConsumerProps } from './';
|
||||
|
||||
const RenderEmpty = {
|
||||
|
@ -19,13 +18,14 @@ const RenderEmpty = {
|
|||
switch (componentName) {
|
||||
case 'Table':
|
||||
case 'List':
|
||||
return <Empty image={emptyImg} class={`${prefix}-normal`} />;
|
||||
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />;
|
||||
|
||||
case 'Select':
|
||||
case 'TreeSelect':
|
||||
case 'Cascader':
|
||||
case 'Transfer':
|
||||
return <Empty image={emptyImg} class={`${prefix}-small`} />;
|
||||
case 'Mentions':
|
||||
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} class={`${prefix}-small`} />;
|
||||
|
||||
default:
|
||||
return <Empty />;
|
||||
|
|
|
@ -37,6 +37,7 @@ export default {
|
|||
render() {
|
||||
const { $scopedSlots } = this;
|
||||
const children = this.children || $scopedSlots.default;
|
||||
return children(this.getLocale(), this.getLocaleCode());
|
||||
const { antLocale } = this.localeData;
|
||||
return children(this.getLocale(), this.getLocaleCode(), antLocale);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@ import * as moment from 'moment';
|
|||
import interopDefault from '../_util/interopDefault';
|
||||
import { changeConfirmLocale } from '../modal/locale';
|
||||
import Base from '../base';
|
||||
import warning from '../_util/warning';
|
||||
// export interface Locale {
|
||||
// locale: string;
|
||||
// Pagination?: Object;
|
||||
|
@ -16,7 +17,7 @@ import Base from '../base';
|
|||
// Select?: Object;
|
||||
// Upload?: Object;
|
||||
// }
|
||||
|
||||
export const ANT_MARK = 'internalMark';
|
||||
function setMomentLocale(locale) {
|
||||
if (locale && locale.locale) {
|
||||
interopDefault(moment).locale(locale.locale);
|
||||
|
@ -29,8 +30,14 @@ const LocaleProvider = {
|
|||
name: 'ALocaleProvider',
|
||||
props: {
|
||||
locale: PropTypes.object.def({}),
|
||||
_ANT_MARK__: PropTypes.string,
|
||||
},
|
||||
data() {
|
||||
warning(
|
||||
this._ANT_MARK__ === ANT_MARK,
|
||||
'LocaleProvider',
|
||||
'`LocaleProvider` is deprecated. Please use `locale` with `ConfigProvider` instead',
|
||||
);
|
||||
return {
|
||||
antLocale: {
|
||||
...this.locale,
|
||||
|
@ -50,6 +57,7 @@ const LocaleProvider = {
|
|||
exist: true,
|
||||
};
|
||||
setMomentLocale(val);
|
||||
changeConfirmLocale(val && val.Modal);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
@ -57,10 +65,6 @@ const LocaleProvider = {
|
|||
setMomentLocale(locale);
|
||||
changeConfirmLocale(locale && locale.Modal);
|
||||
},
|
||||
updated() {
|
||||
const { locale } = this;
|
||||
changeConfirmLocale(locale && locale.Modal);
|
||||
},
|
||||
beforeDestroy() {
|
||||
changeConfirmLocale();
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue