mirror of
https://github.com/ant-design/ant-design.git
synced 2025-08-06 16:06:28 +08:00
commit
cb2460c412
@ -422,14 +422,6 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
|
||||
Click me!
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Won't show loading
|
||||
</span>
|
||||
</button>
|
||||
<br />
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-loading"
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import { render, mount } from 'enzyme';
|
||||
import { renderToJson } from 'enzyme-to-json';
|
||||
import Button from '..';
|
||||
@ -25,4 +25,43 @@ describe('Button', () => {
|
||||
// eslint-disable-next-line
|
||||
expect(wrapper.type().__ANT_BUTTON).toBe(true);
|
||||
});
|
||||
|
||||
it('should change loading state instantly by default', () => {
|
||||
class DefaultButton extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
};
|
||||
enterLoading = () => {
|
||||
this.setState({ loading: true });
|
||||
}
|
||||
render() {
|
||||
return <Button loading={this.state.loading} onClick={this.enterLoading}>Button</Button>;
|
||||
}
|
||||
}
|
||||
const wrapper = mount(
|
||||
<DefaultButton />
|
||||
);
|
||||
wrapper.simulate('click');
|
||||
expect(wrapper.hasClass('ant-btn-loading')).toBe(true);
|
||||
});
|
||||
|
||||
it('should change loading state with delay', () => {
|
||||
// eslint-disable-next-line
|
||||
class DefaultButton extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
};
|
||||
enterLoading = () => {
|
||||
this.setState({ loading: { delay: 1000 } });
|
||||
}
|
||||
render() {
|
||||
return <Button loading={this.state.loading} onClick={this.enterLoading}>Button</Button>;
|
||||
}
|
||||
}
|
||||
const wrapper = mount(
|
||||
<DefaultButton />
|
||||
);
|
||||
wrapper.simulate('click');
|
||||
expect(wrapper.hasClass('ant-btn-loading')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -41,7 +41,7 @@ export interface ButtonProps {
|
||||
size?: ButtonSize;
|
||||
onClick?: React.FormEventHandler<any>;
|
||||
onMouseUp?: React.FormEventHandler<any>;
|
||||
loading?: boolean;
|
||||
loading?: boolean | { delay?: number };
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
@ -66,7 +66,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
size: React.PropTypes.oneOf(['large', 'default', 'small']),
|
||||
htmlType: React.PropTypes.oneOf(['submit', 'button', 'reset']),
|
||||
onClick: React.PropTypes.func,
|
||||
loading: React.PropTypes.bool,
|
||||
loading: React.PropTypes.oneOfType([React.PropTypes.bool, React.PropTypes.object]),
|
||||
className: React.PropTypes.string,
|
||||
icon: React.PropTypes.string,
|
||||
};
|
||||
@ -89,8 +89,8 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
clearTimeout(this.delayTimeout);
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
this.delayTimeout = setTimeout(() => this.setState({ loading }), 200);
|
||||
if (loading && loading.delay) {
|
||||
this.delayTimeout = setTimeout(() => this.setState({ loading }), loading.delay);
|
||||
} else {
|
||||
this.setState({ loading });
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ class App extends React.Component {
|
||||
state = {
|
||||
loading: false,
|
||||
iconLoading: false,
|
||||
delayLoading: false,
|
||||
}
|
||||
|
||||
enterLoading = () => {
|
||||
@ -30,15 +29,6 @@ class App extends React.Component {
|
||||
enterIconLoading = () => {
|
||||
this.setState({ iconLoading: true });
|
||||
}
|
||||
delayLoading = () => {
|
||||
this.setState({
|
||||
delayLoading: true,
|
||||
});
|
||||
|
||||
setTimeout(() => this.setState({
|
||||
delayLoading: false,
|
||||
}), 150);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
@ -56,9 +46,6 @@ class App extends React.Component {
|
||||
<Button type="primary" icon="poweroff" loading={this.state.iconLoading} onClick={this.enterIconLoading}>
|
||||
Click me!
|
||||
</Button>
|
||||
<Button type="primary" loading={this.state.delayLoading} onClick={this.delayLoading}>
|
||||
Won't show loading
|
||||
</Button>
|
||||
<br />
|
||||
<Button shape="circle" loading />
|
||||
<Button type="primary" shape="circle" loading />
|
||||
|
@ -21,7 +21,7 @@ htmlType | to set the original `type` of `button`, see: [MDN](https://developer.
|
||||
icon | set the icon of button, see: Icon component | string | -
|
||||
shape | can be set to `circle` or omitted | string | -
|
||||
size | can be set to `small` `large` or omitted | string | `default`
|
||||
loading | to set the loading status of button | boolean | `false`
|
||||
loading | to set the loading status of button | boolean \| { delay: number } | `false`
|
||||
onClick | set the handler to handle `click` event | function | -
|
||||
ghost | make background transparent and invert text and border color, added in 2.7 | boolean | false
|
||||
|
||||
|
@ -24,7 +24,7 @@ htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标
|
||||
icon | 设置按钮的图标类型 | string | -
|
||||
shape | 设置按钮形状,可选值为 `circle` 或者不设 | string | -
|
||||
size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default`
|
||||
loading | 设置按钮载入状态 | boolean | `false`
|
||||
loading | 设置按钮载入状态 | boolean \| { delay: number } | `false`
|
||||
onClick | `click` 事件的 handler | function | -
|
||||
ghost | 幽灵属性,使按钮背景透明,版本 2.7 中增加 | boolean | false
|
||||
|
||||
|
2
components/calendar/locale/et_EE.tsx
Normal file
2
components/calendar/locale/et_EE.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
import et_EE from '../../date-picker/locale/et_EE';
|
||||
export default et_EE;
|
2
components/calendar/locale/ja_JP.tsx
Normal file
2
components/calendar/locale/ja_JP.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
import ja_JP from '../../date-picker/locale/ja_JP';
|
||||
export default ja_JP;
|
2
components/calendar/locale/sk_SK.tsx
Normal file
2
components/calendar/locale/sk_SK.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
import sk_SK from '../../date-picker/locale/sk_SK';
|
||||
export default sk_SK;
|
2
components/calendar/locale/tr_TR.tsx
Normal file
2
components/calendar/locale/tr_TR.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
import tr_TR from '../../date-picker/locale/tr_TR';
|
||||
export default tr_TR;
|
@ -20,8 +20,9 @@
|
||||
}
|
||||
|
||||
&-head {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
height: @card-head-height;
|
||||
line-height: @card-head-height;
|
||||
background: @card-head-background;
|
||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||
padding: 0 24px;
|
||||
|
||||
@ -32,7 +33,7 @@
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
color: @heading-color;
|
||||
color: @card-head-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ export interface CascaderProps {
|
||||
onPopupVisibleChange?: (popupVisible: boolean) => void;
|
||||
prefixCls?: string;
|
||||
inputPrefixCls?: string;
|
||||
getPopupContainer?: (triggerNode: Element) => HTMLElement;
|
||||
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
|
||||
}
|
||||
|
||||
function highlightKeyword(str: string, keyword: string, prefixCls: string) {
|
||||
|
17
components/date-picker/locale/et_EE.tsx
Normal file
17
components/date-picker/locale/et_EE.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/et_EE';
|
||||
import TimePickerLocale from '../../time-picker/locale/et_EE';
|
||||
import assign from 'object-assign';
|
||||
|
||||
// 统一合并为完整的 Locale
|
||||
const locale = {
|
||||
lang: assign({
|
||||
placeholder: 'Vali kuupäev',
|
||||
rangePlaceholder: ['Algus kuupäev', 'Lõpu kuupäev'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
16
components/date-picker/locale/ja_JP.tsx
Normal file
16
components/date-picker/locale/ja_JP.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/ja_JP';
|
||||
import TimePickerLocale from '../../time-picker/locale/ja_JP';
|
||||
import assign from 'object-assign';
|
||||
|
||||
const locale = {
|
||||
lang: assign({
|
||||
placeholder: '日付を選択',
|
||||
rangePlaceholder: ['開始日付', '終了日付'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
17
components/date-picker/locale/sk_SK.tsx
Normal file
17
components/date-picker/locale/sk_SK.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/sk_SK';
|
||||
import TimePickerLocale from '../../time-picker/locale/sk_SK';
|
||||
import assign from 'object-assign';
|
||||
|
||||
// 统一合并为完整的 Locale
|
||||
const locale = {
|
||||
lang: assign({
|
||||
placeholder: 'Vybrať dátum',
|
||||
rangePlaceholder: ['Od', 'Do'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
17
components/date-picker/locale/tr_TR.tsx
Normal file
17
components/date-picker/locale/tr_TR.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/en_US';
|
||||
import TimePickerLocale from '../../time-picker/locale/tr_TR';
|
||||
import assign from 'object-assign';
|
||||
|
||||
// Merge into a locale object
|
||||
const locale = {
|
||||
lang: assign({
|
||||
placeholder: 'Tarih Seç',
|
||||
rangePlaceholder: ['Başlangıç Tarihi', 'Bitiş Tarihi'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
@ -23,3 +23,4 @@ When a numeric value needs to be provided.
|
||||
| disabled | disable the input | boolean | false |
|
||||
| size | width of input box | string | - |
|
||||
| formatter | Specifies the format of the value presented | function(value: number \| string): string | - |
|
||||
| parser | Specifies the value extracted from formatter | function( string): number | - |
|
||||
|
@ -26,3 +26,4 @@ title: InputNumber
|
||||
| disabled | 禁用 | boolean | false |
|
||||
| size | 输入框大小 | string | 无 |
|
||||
| formatter | 指定输入框展示值的格式 | function(value: number \| string): string | - |
|
||||
| parser | 指定从 formatter 里转换回数字的方式,和 formatter 搭配使用 | function( string): number | - |
|
||||
|
@ -14,6 +14,10 @@ import nlNL from '../nl_NL';
|
||||
import caES from '../ca_ES';
|
||||
import csCZ from '../cs_CZ';
|
||||
import koKR from '../ko_KR';
|
||||
import etEE from '../et_EE';
|
||||
import skSK from '../sk_SK';
|
||||
import jaJP from '../ja_JP';
|
||||
import trTR from '../tr_TR';
|
||||
|
||||
const Option = Select.Option;
|
||||
const RangePicker = DatePicker.RangePicker;
|
||||
@ -59,7 +63,7 @@ const App = () => (
|
||||
|
||||
describe('Locale Provider', () => {
|
||||
it('should display the text as locale changed', () => {
|
||||
[enUS, ptBR, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR].forEach((locale) => {
|
||||
[enUS, ptBR, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR, etEE, skSK, jaJP, trTR].forEach((locale) => {
|
||||
const wrapper = mount(
|
||||
<LocaleProvider locale={locale}>
|
||||
<App />
|
||||
@ -81,7 +85,7 @@ describe('Locale Provider', () => {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
[enUS, ptBR, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR].forEach((locale) => {
|
||||
[enUS, ptBR, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR, trTR].forEach((locale) => {
|
||||
mount(
|
||||
<LocaleProvider locale={locale}>
|
||||
<ModalDemo />
|
||||
|
45
components/locale-provider/et_EE.tsx
Normal file
45
components/locale-provider/et_EE.tsx
Normal file
@ -0,0 +1,45 @@
|
||||
import moment from 'moment';
|
||||
moment.locale('et');
|
||||
|
||||
import DatePicker from '../date-picker/locale/et_EE';
|
||||
import TimePicker from '../time-picker/locale/et_EE';
|
||||
import Calendar from '../calendar/locale/et_EE';
|
||||
|
||||
export default {
|
||||
locale: 'et',
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
Table: {
|
||||
filterTitle: 'Filtri menüü',
|
||||
filterConfirm: 'OK',
|
||||
filterReset: 'Nulli',
|
||||
emptyText: 'Andmed puuduvad',
|
||||
selectAll: 'Vali kõik',
|
||||
selectInvert: 'Inverteeri valik',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Tühista',
|
||||
justOkText: 'OK',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Tühista',
|
||||
},
|
||||
Transfer: {
|
||||
notFoundContent: 'Ei leitud',
|
||||
searchPlaceholder: 'Otsi siit',
|
||||
itemUnit: 'kogus',
|
||||
itemsUnit: 'kogus',
|
||||
},
|
||||
Select: {
|
||||
notFoundContent: 'Ei leitud',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'Üleslaadimine...',
|
||||
removeFile: 'Eemalda fail',
|
||||
uploadError: 'Üleslaadimise tõrge',
|
||||
previewFile: 'Faili eelvaade',
|
||||
},
|
||||
};
|
47
components/locale-provider/ja_JP.tsx
Normal file
47
components/locale-provider/ja_JP.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import moment from 'moment';
|
||||
moment.locale('ja');
|
||||
|
||||
import Pagination from 'rc-pagination/lib/locale/ja_JP';
|
||||
import DatePicker from '../date-picker/locale/ja_JP';
|
||||
import TimePicker from '../time-picker/locale/ja_JP';
|
||||
import Calendar from '../calendar/locale/ja_JP';
|
||||
|
||||
export default {
|
||||
locale: 'ja',
|
||||
Pagination,
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
Table: {
|
||||
filterTitle: 'メニューをフィルター',
|
||||
filterConfirm: 'OK',
|
||||
filterReset: 'リセット',
|
||||
emptyText: 'データがありません',
|
||||
selectAll: 'すべてを選択',
|
||||
selectInvert: '選択を反転',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'OK',
|
||||
cancelText: 'キャンセル',
|
||||
justOkText: 'OK',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'OK',
|
||||
cancelText: 'キャンセル',
|
||||
},
|
||||
Transfer: {
|
||||
notFoundContent: '結果はありません',
|
||||
searchPlaceholder: 'ここを検索',
|
||||
itemUnit: 'アイテム',
|
||||
itemsUnit: 'アイテム',
|
||||
},
|
||||
Select: {
|
||||
notFoundContent: '結果はありません',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'アップロード中...',
|
||||
removeFile: 'ファイルを削除',
|
||||
uploadError: 'アップロードエラー',
|
||||
previewFile: 'ファイルをプレビュー',
|
||||
},
|
||||
};
|
47
components/locale-provider/sk_SK.tsx
Normal file
47
components/locale-provider/sk_SK.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import moment from 'moment';
|
||||
moment.locale('sk');
|
||||
|
||||
import Pagination from 'rc-pagination/lib/locale/sk_SK';
|
||||
import DatePicker from '../date-picker/locale/sk_SK';
|
||||
import TimePicker from '../time-picker/locale/sk_SK';
|
||||
import Calendar from '../calendar/locale/sk_SK';
|
||||
|
||||
export default {
|
||||
locale: 'sk',
|
||||
Pagination,
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
Table: {
|
||||
filterTitle: 'Filter',
|
||||
filterConfirm: 'OK',
|
||||
filterReset: 'Obnoviť',
|
||||
emptyText: 'Žiadne dáta',
|
||||
selectAll: 'Vybrať všetko',
|
||||
selectInvert: 'Vybrať opačné',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Zrušiť',
|
||||
justOkText: 'OK',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Zrušiť',
|
||||
},
|
||||
Transfer: {
|
||||
notFoundContent: 'Nenájdené',
|
||||
searchPlaceholder: 'Vyhľadávanie',
|
||||
itemUnit: 'položka',
|
||||
itemsUnit: 'položiek',
|
||||
},
|
||||
Select: {
|
||||
notFoundContent: 'Nenájdené',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'Nahrávanie...',
|
||||
removeFile: 'Odstrániť súbor',
|
||||
uploadError: 'Chyba pri nahrávaní',
|
||||
previewFile: 'Zobraziť súbor',
|
||||
},
|
||||
};
|
47
components/locale-provider/tr_TR.tsx
Normal file
47
components/locale-provider/tr_TR.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import moment from 'moment';
|
||||
moment.locale('tr');
|
||||
|
||||
import Pagination from 'rc-pagination/lib/locale/en_US';
|
||||
import DatePicker from '../date-picker/locale/tr_TR';
|
||||
import TimePicker from '../time-picker/locale/tr_TR';
|
||||
import Calendar from '../calendar/locale/en_US';
|
||||
|
||||
export default {
|
||||
locale: 'tr',
|
||||
Pagination,
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
Table: {
|
||||
filterTitle: 'Menü Filtrele',
|
||||
filterConfirm: 'Tamam',
|
||||
filterReset: 'Sıfırla',
|
||||
emptyText: 'Veri Yok',
|
||||
selectAll: 'Hepsini Seç',
|
||||
selectInvert: 'Select Invert',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'Tamam',
|
||||
cancelText: 'İptal',
|
||||
justOkText: 'Tamam',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'Tamam',
|
||||
cancelText: 'İptal',
|
||||
},
|
||||
Transfer: {
|
||||
notFoundContent: 'Bulunamadı',
|
||||
searchPlaceholder: 'Arama',
|
||||
itemUnit: 'Öğe',
|
||||
itemsUnit: 'Öğeler',
|
||||
},
|
||||
Select: {
|
||||
notFoundContent: 'Bulunamadı',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'Yükleniyor...',
|
||||
removeFile: `Dosya'ı kaldır`,
|
||||
uploadError: 'Yükleme Hatası',
|
||||
previewFile: `Dosya'ı Önizle`,
|
||||
},
|
||||
};
|
@ -21,6 +21,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -31,7 +32,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:73.82742735936014px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:221.48228207808043px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@ -60,6 +61,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -70,7 +72,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
stroke="#ff5500"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:88.59291283123217px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:206.7167966062084px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@ -101,6 +103,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -111,7 +114,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
stroke="#87d068"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:0px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@ -147,6 +150,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -157,7 +161,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = `
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:295.3097094374406px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:0px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@ -211,6 +215,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -221,7 +226,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:206.7167966062084px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:88.59291283123217px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@ -250,6 +255,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -260,7 +266,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
stroke="#ff5500"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:88.59291283123217px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:206.7167966062084px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@ -291,6 +297,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -301,7 +308,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
stroke="#87d068"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:0px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@ -316,6 +323,51 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/progress/demo/dashboard.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info"
|
||||
>
|
||||
<div
|
||||
class="ant-progress-inner"
|
||||
style="width:132px;height:132px;font-size:27.12px;"
|
||||
>
|
||||
<svg
|
||||
class="ant-progress-circle "
|
||||
viewbox="0 0 100 100"
|
||||
>
|
||||
<path
|
||||
class="ant-progress-circle-trail"
|
||||
d="M 50,50 m 0,47
|
||||
a 47,47 0 1 1 0,-94
|
||||
a 47,47 0 1 1 0,94"
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:220.30970943744057px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
d="M 50,50 m 0,47
|
||||
a 47,47 0 1 1 0,-94
|
||||
a 47,47 0 1 1 0,94"
|
||||
fill-opacity="0"
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:165.23228207808043px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="ant-progress-text"
|
||||
>
|
||||
75%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/progress/demo/dynamic.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
@ -385,6 +437,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -395,7 +448,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:73.82742735936014px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:221.48228207808043px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@ -424,6 +477,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@ -434,7 +488,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
|
||||
stroke="#87d068"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:0px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
|
24
components/progress/demo/dashboard.md
Normal file
24
components/progress/demo/dashboard.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
order: 8
|
||||
title:
|
||||
zh-CN: 仪表盘
|
||||
en-US: Dashboard
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
仪表盘。
|
||||
|
||||
## en-US
|
||||
|
||||
A dashboard.
|
||||
|
||||
````jsx
|
||||
import { Progress } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Progress type="dashboard" percent={75} />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
@ -17,7 +17,7 @@ If it will take a long time to complete the operation, you can use `Progress` to
|
||||
|
||||
Property | Description | Type | Default
|
||||
-----|-----|-----|------
|
||||
type | to set the type, options: `line` `circle` | string | line
|
||||
type | to set the type, options: `line` `circle` `dashboard`| string | line
|
||||
percent | to set the completion percentage | number | 0
|
||||
format | template function of the content | function(percent) | `percent => percent + '%'`
|
||||
status | to set the status of the progress, options: `success` `exception` `active` | string | -
|
||||
|
@ -19,7 +19,7 @@ title: Progress
|
||||
|
||||
| 属性 | 说明 | 类型 | 默认值 |
|
||||
|----------|---------------|----------|---------------|
|
||||
| type | 类型,可选 `line` `circle` | string | line |
|
||||
| type | 类型,可选 `line` `circle` `dashboard` | string | line |
|
||||
| percent | 百分比 | number | 0 |
|
||||
| format | 内容的模板函数 | function(percent) | `percent => percent + '%'` |
|
||||
| status | 状态,可选:`success` `exception` `active` | string | - |
|
||||
|
@ -12,7 +12,7 @@ const statusColorMap = {
|
||||
export interface ProgressProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
type?: 'line' | 'circle';
|
||||
type?: 'line' | 'circle' | 'dashboard';
|
||||
percent?: number;
|
||||
format?: (percent: number) => string;
|
||||
status?: 'success' | 'active' | 'exception';
|
||||
@ -21,6 +21,8 @@ export interface ProgressProps {
|
||||
trailColor?: string;
|
||||
width?: number;
|
||||
style?: React.CSSProperties;
|
||||
gapDegree?: number;
|
||||
gapPosition?: 'top' | 'bottom' | 'left' | 'right';
|
||||
}
|
||||
|
||||
export default class Progress extends React.Component<ProgressProps, any> {
|
||||
@ -37,20 +39,21 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
|
||||
static propTypes = {
|
||||
status: PropTypes.oneOf(['normal', 'exception', 'active', 'success']),
|
||||
type: PropTypes.oneOf(['line', 'circle']),
|
||||
type: PropTypes.oneOf(['line', 'circle', 'dashboard']),
|
||||
showInfo: PropTypes.bool,
|
||||
percent: PropTypes.number,
|
||||
width: PropTypes.number,
|
||||
strokeWidth: PropTypes.number,
|
||||
trailColor: PropTypes.string,
|
||||
format: PropTypes.func,
|
||||
gapDegree: PropTypes.number,
|
||||
};
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const {
|
||||
prefixCls, className, percent = 0, status, format, trailColor,
|
||||
type, strokeWidth, width, showInfo, ...restProps,
|
||||
type, strokeWidth, width, showInfo, gapDegree = 0, gapPosition, ...restProps,
|
||||
} = props;
|
||||
const progressStatus = parseInt(percent.toString(), 10) >= 100 && !('status' in props) ?
|
||||
'success' : (status || 'normal');
|
||||
@ -60,7 +63,7 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
|
||||
if (showInfo) {
|
||||
let text;
|
||||
const iconType = type === 'circle' ? '' : '-circle';
|
||||
const iconType = (type === 'circle' || type === 'dashboard') ? '' : '-circle';
|
||||
if (progressStatus === 'exception') {
|
||||
text = format ? textFormatter(percent) : <Icon type={`cross${iconType}`} />;
|
||||
} else if (progressStatus === 'success') {
|
||||
@ -86,7 +89,7 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
{progressInfo}
|
||||
</div>
|
||||
);
|
||||
} else if (type === 'circle') {
|
||||
} else if (type === 'circle' || type === 'dashboard') {
|
||||
const circleSize = width || 132;
|
||||
const circleStyle = {
|
||||
width: circleSize,
|
||||
@ -94,6 +97,8 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
fontSize: circleSize * 0.16 + 6,
|
||||
};
|
||||
const circleWidth = strokeWidth || 6;
|
||||
const gapPos = gapPosition || type === 'dashboard' && 'bottom' || 'top';
|
||||
const gapDeg = gapDegree || type === 'dashboard' && 75;
|
||||
progress = (
|
||||
<div className={`${prefixCls}-inner`} style={circleStyle}>
|
||||
<Circle
|
||||
@ -103,6 +108,8 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
strokeColor={statusColorMap[progressStatus]}
|
||||
trailColor={trailColor}
|
||||
prefixCls={prefixCls}
|
||||
gapDegree={gapDeg}
|
||||
gapPosition={gapPos}
|
||||
/>
|
||||
{progressInfo}
|
||||
</div>
|
||||
@ -110,7 +117,7 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
}
|
||||
|
||||
const classString = classNames(prefixCls, {
|
||||
[`${prefixCls}-${type}`]: true,
|
||||
[`${prefixCls}-${type === 'dashboard' && 'circle' || type}`]: true,
|
||||
[`${prefixCls}-status-${progressStatus}`]: true,
|
||||
[`${prefixCls}-show-info`]: showInfo,
|
||||
}, className);
|
||||
|
@ -493,6 +493,188 @@ exports[`renders ./components/radio/demo/radiogroup-more.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/radio/demo/radiogroup-optional.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-radio-group"
|
||||
>
|
||||
<label
|
||||
class="ant-radio-wrapper ant-radio-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio ant-radio-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Apple
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Pear
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Orange
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="ant-radio-group"
|
||||
>
|
||||
<label
|
||||
class="ant-radio-wrapper ant-radio-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio ant-radio-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Apple
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Pear
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Orange
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="ant-radio-group"
|
||||
>
|
||||
<label
|
||||
class="ant-radio-wrapper ant-radio-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio ant-radio-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Apple
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Pear
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Orange
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/radio/demo/size.md correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
|
@ -16,6 +16,21 @@ describe('Radio', () => {
|
||||
);
|
||||
}
|
||||
|
||||
function createRadioGroupByOption(props) {
|
||||
const options = [
|
||||
{ label: 'A', value: 'A' },
|
||||
{ label: 'B', value: 'B' },
|
||||
{ label: 'C', value: 'C' },
|
||||
];
|
||||
|
||||
return (
|
||||
<RadioGroup
|
||||
{...props}
|
||||
options={options}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
it('responses hover events', () => {
|
||||
const onMouseEnter = jest.fn();
|
||||
const onMouseLeave = jest.fn();
|
||||
@ -77,4 +92,13 @@ describe('Radio', () => {
|
||||
radios.at(0).simulate('change');
|
||||
expect(onChange.mock.calls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('optional should correct render', () => {
|
||||
const wrapper = mount(
|
||||
createRadioGroupByOption()
|
||||
);
|
||||
const radios = wrapper.find('input');
|
||||
|
||||
expect(radios.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
68
components/radio/demo/radiogroup-optional.md
Normal file
68
components/radio/demo/radiogroup-optional.md
Normal file
@ -0,0 +1,68 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: RadioGroup 组合 - 配置方式
|
||||
en-US: RadioGroup group - optional
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
通过配置参数来控制渲染单选框。
|
||||
|
||||
## en-US
|
||||
|
||||
Render radios by configuring parameters.
|
||||
|
||||
```jsx
|
||||
import { Radio } from 'antd';
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
const plainOptions = ['Apple', 'Pear', 'Orange'];
|
||||
const options = [
|
||||
{ label: 'Apple', value: 'Apple' },
|
||||
{ label: 'Pear', value: 'Pear' },
|
||||
{ label: 'Orange', value: 'Orange' },
|
||||
];
|
||||
const optionsWithDisabled = [
|
||||
{ label: 'Apple', value: 'Apple' },
|
||||
{ label: 'Pear', value: 'Pear' },
|
||||
{ label: 'Orange', value: 'Orange', disabled: false },
|
||||
];
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
value1: 'Apple',
|
||||
value2: 'Apple',
|
||||
value3: 'Apple',
|
||||
}
|
||||
onChange1 = (e) => {
|
||||
console.log('radio1 checked', e.target.value);
|
||||
this.setState({
|
||||
value1: e.target.value,
|
||||
});
|
||||
}
|
||||
onChange2 = (e) => {
|
||||
console.log('radio2 checked', e.target.value);
|
||||
this.setState({
|
||||
value2: e.target.value,
|
||||
});
|
||||
}
|
||||
onChange3 = (e) => {
|
||||
console.log('radio3 checked', e.target.value);
|
||||
this.setState({
|
||||
value3: e.target.value,
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<RadioGroup options={plainOptions} onChange={this.onChange1} value={this.state.value1} />
|
||||
<RadioGroup options={options} onChange={this.onChange2} value={this.state.value2} />
|
||||
<RadioGroup options={optionsWithDisabled} onChange={this.onChange3} value={this.state.value3} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
```
|
@ -1,6 +1,7 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import shallowEqual from 'shallowequal';
|
||||
import Radio from './radio';
|
||||
|
||||
function getCheckedValue(children) {
|
||||
let value = null;
|
||||
@ -29,6 +30,12 @@ export interface RadioGroupProps {
|
||||
disabled?: boolean;
|
||||
onMouseEnter?: React.FormEventHandler<any>;
|
||||
onMouseLeave?: React.FormEventHandler<any>;
|
||||
/** 以配置的方式设置 Radio 子元素,设置了此参数,会忽略 children */
|
||||
options?: Array<string | {
|
||||
label: string;
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
}>;
|
||||
}
|
||||
|
||||
export default class RadioGroup extends React.Component<RadioGroupProps, any> {
|
||||
@ -83,8 +90,8 @@ export default class RadioGroup extends React.Component<RadioGroupProps, any> {
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState, nextContext) {
|
||||
return !shallowEqual(this.props, nextProps) ||
|
||||
!shallowEqual(this.state, nextState) ||
|
||||
!shallowEqual(this.context.group, nextContext.group);
|
||||
!shallowEqual(this.state, nextState) ||
|
||||
!shallowEqual(this.context.group, nextContext.group);
|
||||
}
|
||||
|
||||
onRadioChange = (ev) => {
|
||||
@ -103,10 +110,44 @@ export default class RadioGroup extends React.Component<RadioGroupProps, any> {
|
||||
}
|
||||
render() {
|
||||
const props = this.props;
|
||||
const { prefixCls = 'ant-radio-group', className = '', children } = props;
|
||||
const { prefixCls = 'ant-radio-group', className = '' } = props;
|
||||
const classString = classNames(prefixCls, {
|
||||
[`${prefixCls}-${props.size}`]: props.size,
|
||||
}, className);
|
||||
|
||||
let children: React.ReactChildren[] | React.ReactElement<any>[] | React.ReactNode = props.children;
|
||||
|
||||
// 如果存在 options, 优先使用
|
||||
if (props.options && props.options.length > 0) {
|
||||
children = props.options.map((option, index) => {
|
||||
if (typeof option === 'string') { // 此处类型自动推导为 string
|
||||
return (
|
||||
<Radio
|
||||
key={index}
|
||||
disabled={this.props.disabled}
|
||||
value={option}
|
||||
onChange={this.onRadioChange}
|
||||
checked={this.state.value === option}
|
||||
>
|
||||
{option}
|
||||
</Radio>
|
||||
);
|
||||
} else { // 此处类型自动推导为 { label: string value: string }
|
||||
return (
|
||||
<Radio
|
||||
key={index}
|
||||
disabled={option.disabled || this.props.disabled}
|
||||
value={option.value}
|
||||
onChange={this.onRadioChange}
|
||||
checked={this.state.value === option.value}
|
||||
>
|
||||
{option.label}
|
||||
</Radio>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classString}
|
||||
|
@ -31,3 +31,4 @@ radio group,wrap a group of `Radio`。
|
||||
| value | Used for setting the currently selected value. | any | none | none |
|
||||
| defaultValue | Default selected value | any | none | none |
|
||||
| size | Size, only on radio style | string | `large` `default` `small` | `default` |
|
||||
| options | set children optional | string[] \| Array<{ label: string value: string disabled?: boolean }> | 无 | 无 |
|
||||
|
@ -32,3 +32,4 @@ title: Radio
|
||||
| value | 用于设置当前选中的值 | any | 无 | 无 |
|
||||
| defaultValue | 默认选中的值 | any | 无 | 无 |
|
||||
| size | 大小,只对按钮样式生效 | string | `large` `default` `small` | `default` |
|
||||
| options | 以配置形式设置子元素 | string[] \| Array<{ label: string value: string disabled?: boolean }> | 无 | 无 |
|
||||
|
@ -18,3 +18,4 @@ size | size of spin, available in `small`, `default` and `large` | string | 'def
|
||||
spinning | whether Spin is spinning | boolean | true
|
||||
tip | customize description content when spin has children | string | -
|
||||
delay | specifies a delay millisecond for loading state (prevent flush) | number (millisecond) | -
|
||||
wrapperClassName | className of wrapper when Spin has children | string | -
|
||||
|
@ -13,6 +13,7 @@ export interface SpinProps {
|
||||
size?: 'small' | 'default' | 'large';
|
||||
tip?: string;
|
||||
delay?: number;
|
||||
wrapperClassName?: string;
|
||||
}
|
||||
|
||||
export default class Spin extends React.Component<SpinProps, any> {
|
||||
@ -20,6 +21,7 @@ export default class Spin extends React.Component<SpinProps, any> {
|
||||
prefixCls: 'ant-spin',
|
||||
spinning: true,
|
||||
size: 'default',
|
||||
wrapperClassName: '',
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
@ -27,6 +29,7 @@ export default class Spin extends React.Component<SpinProps, any> {
|
||||
className: PropTypes.string,
|
||||
spinning: PropTypes.bool,
|
||||
size: PropTypes.oneOf(['small', 'default', 'large']),
|
||||
wrapperClassName: PropTypes.string,
|
||||
};
|
||||
|
||||
debounceTimeout: number;
|
||||
@ -82,7 +85,7 @@ export default class Spin extends React.Component<SpinProps, any> {
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const { className, size, prefixCls, tip, ...restProps } = this.props;
|
||||
const { className, size, prefixCls, tip, wrapperClassName, ...restProps } = this.props;
|
||||
const { spinning } = this.state;
|
||||
|
||||
const spinClassName = classNames(prefixCls, {
|
||||
@ -110,6 +113,10 @@ export default class Spin extends React.Component<SpinProps, any> {
|
||||
</div>
|
||||
);
|
||||
if (this.isNestedPattern()) {
|
||||
let animateClassName = prefixCls + '-nested-loading';
|
||||
if (wrapperClassName) {
|
||||
animateClassName += ' ' + wrapperClassName;
|
||||
}
|
||||
const containerClassName = classNames({
|
||||
[`${prefixCls}-container`]: true,
|
||||
[`${prefixCls}-blur`]: spinning,
|
||||
@ -118,7 +125,7 @@ export default class Spin extends React.Component<SpinProps, any> {
|
||||
<Animate
|
||||
{...divProps}
|
||||
component="div"
|
||||
className={`${prefixCls}-nested-loading`}
|
||||
className={animateClassName}
|
||||
style={null}
|
||||
transitionName="fade"
|
||||
>
|
||||
|
@ -19,3 +19,4 @@ size | 组件大小,可选值为 `small` `default` `large` | string | 'default
|
||||
spinning | 是否旋转 | boolean | true
|
||||
tip | 当作为包裹元素时,可以自定义描述文案 | string | -
|
||||
delay | 延迟显示加载效果的时间(防止闪烁) | number (毫秒) | -
|
||||
wrapperClassName | 包装器的类属性 | string | -
|
||||
|
@ -265,3 +265,9 @@
|
||||
// ---
|
||||
@rate-star-color: #f5a623;
|
||||
@rate-star-bg: #e9e9e9;
|
||||
|
||||
// Card
|
||||
// ---
|
||||
@card-head-height: 48px;
|
||||
@card-head-color: @heading-color;
|
||||
@card-head-background: @component-background;
|
||||
|
@ -15,6 +15,7 @@ export interface ColumnProps<T> {
|
||||
width?: string | number;
|
||||
className?: string;
|
||||
fixed?: boolean | ('left' | 'right');
|
||||
filterIcon?: React.ReactNode;
|
||||
filteredValue?: any[];
|
||||
sortOrder?: boolean | ('ascend' | 'descend');
|
||||
children?: ColumnProps<T>[];
|
||||
|
@ -175,7 +175,7 @@ export default class SelectionCheckboxAll extends React.Component<SelectionCheck
|
||||
customSelections = (
|
||||
<Dropdown
|
||||
overlay={menu}
|
||||
getPopupContainer={trigger => trigger.parentNode as HTMLElement}
|
||||
getPopupContainer={(trigger: HTMLElement) => trigger.parentNode as HTMLElement}
|
||||
>
|
||||
<div className={`${selectionPrefixCls}-down`}>
|
||||
<Icon type="down" />
|
||||
|
@ -862,7 +862,8 @@ exports[`renders ./components/table/demo/custom-filter-panel.md correctly 1`] =
|
||||
<span>
|
||||
Name
|
||||
<i
|
||||
class="anticon anticon-filter ant-dropdown-trigger"
|
||||
class="anticon anticon-smile-o ant-table-filter-icon ant-dropdown-trigger"
|
||||
style="color:#aaa;"
|
||||
title="筛选"
|
||||
/>
|
||||
</span>
|
||||
|
@ -14,7 +14,7 @@ title:
|
||||
Implement a customized column search example via `filterDropdown`, `filterDropdownVisible` and `filterDropdownVisibleChange`.
|
||||
|
||||
````jsx
|
||||
import { Table, Input, Button } from 'antd';
|
||||
import { Table, Input, Button, Icon } from 'antd';
|
||||
|
||||
const data = [{
|
||||
key: '1',
|
||||
@ -43,6 +43,7 @@ class App extends React.Component {
|
||||
filterDropdownVisible: false,
|
||||
data,
|
||||
searchText: '',
|
||||
filtered: false,
|
||||
};
|
||||
onInputChange = (e) => {
|
||||
this.setState({ searchText: e.target.value });
|
||||
@ -52,6 +53,7 @@ class App extends React.Component {
|
||||
const reg = new RegExp(searchText, 'gi');
|
||||
this.setState({
|
||||
filterDropdownVisible: false,
|
||||
filtered: !!searchText,
|
||||
data: data.map((record) => {
|
||||
const match = record.name.match(reg);
|
||||
if (!match) {
|
||||
@ -78,6 +80,7 @@ class App extends React.Component {
|
||||
filterDropdown: (
|
||||
<div className="custom-filter-dropdown">
|
||||
<Input
|
||||
ref={ele => this.searchInput = ele}
|
||||
placeholder="Search name"
|
||||
value={this.state.searchText}
|
||||
onChange={this.onInputChange}
|
||||
@ -86,8 +89,9 @@ class App extends React.Component {
|
||||
<Button type="primary" onClick={this.onSearch}>Search</Button>
|
||||
</div>
|
||||
),
|
||||
filterIcon: <Icon type="smile-o" style={{ color: this.state.filtered ? '#108ee9' : '#aaa' }} />,
|
||||
filterDropdownVisible: this.state.filterDropdownVisible,
|
||||
onFilterDropdownVisibleChange: visible => this.setState({ filterDropdownVisible: visible }),
|
||||
onFilterDropdownVisibleChange: visible => this.setState({ filterDropdownVisible: visible }, () => this.searchInput.focus()),
|
||||
}, {
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
|
@ -19,6 +19,7 @@ export interface FilterMenuProps {
|
||||
filterDropdownVisible?: boolean,
|
||||
onFilterDropdownVisibleChange?: (visible: boolean) => any,
|
||||
fixed?: boolean | string,
|
||||
filterIcon?: React.ReactNode;
|
||||
};
|
||||
confirmFilter: (column: Object, selectedKeys: string[]) => any;
|
||||
prefixCls: string;
|
||||
@ -168,6 +169,18 @@ export default class FilterMenu extends React.Component<FilterMenuProps, any> {
|
||||
this.setState({ keyPathOfSelectedItem });
|
||||
}
|
||||
|
||||
renderFilterIcon = () => {
|
||||
const { column, locale, prefixCls } = this.props;
|
||||
const filterIcon = column.filterIcon as any;
|
||||
const dropdownSelectedClass = this.props.selectedKeys.length > 0 ? `${prefixCls}-selected` : '';
|
||||
|
||||
return filterIcon ? React.cloneElement(filterIcon as any, {
|
||||
title: locale.filterTitle,
|
||||
className: classNames(filterIcon.className, {
|
||||
[`${prefixCls}-icon`]: true,
|
||||
}),
|
||||
}) : <Icon title={locale.filterTitle} type="filter" className={dropdownSelectedClass} />;
|
||||
}
|
||||
render() {
|
||||
const { column, locale, prefixCls, dropdownPrefixCls } = this.props;
|
||||
// default multiple selection in filter dropdown
|
||||
@ -209,9 +222,6 @@ export default class FilterMenu extends React.Component<FilterMenuProps, any> {
|
||||
</FilterDropdownMenuWrapper>
|
||||
);
|
||||
|
||||
const dropdownSelectedClass = (this.props.selectedKeys.length > 0)
|
||||
? `${prefixCls}-selected` : '';
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
@ -219,7 +229,7 @@ export default class FilterMenu extends React.Component<FilterMenuProps, any> {
|
||||
visible={this.neverShown ? false : this.state.visible}
|
||||
onVisibleChange={this.onVisibleChange}
|
||||
>
|
||||
<Icon title={locale.filterTitle} type="filter" className={dropdownSelectedClass} />
|
||||
{this.renderFilterIcon()}
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
@ -92,7 +92,9 @@ One of Property `columns` for descriping column, Column has the same API.
|
||||
| filterDropdown | customized filter overlay | ReactNode | - |
|
||||
| filterDropdownVisible | whether filterDropdown is visible | boolean | - |
|
||||
| onFilterDropdownVisibleChange | called when filterDropdownVisible is changed | function(visible) {} | - |
|
||||
| filteredValue | controlled filtered value | string[] | - |
|
||||
| filteredValue | controlled filtered value, filter icon will highlight. | string[] | - |
|
||||
| filtered | whether the dataSource is filterd | boolean | false |
|
||||
| filterIcon | customized filter icon | ReactNode | false |
|
||||
| sorter | sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set it `true` | Function\|boolean | - |
|
||||
| colSpan | span of this column's title | number | |
|
||||
| width | width of this column | string\|number | - |
|
||||
|
@ -94,6 +94,8 @@ const columns = [{
|
||||
| filterDropdownVisible | 用于控制自定义筛选菜单是否可见 | boolean | - |
|
||||
| onFilterDropdownVisibleChange | 自定义筛选菜单可见变化时调用 | function(visible) {} | - |
|
||||
| filteredValue | 筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组 | string[] | - |
|
||||
| filtered | 标识数据是否经过过滤,筛选图标会高亮 | boolean | false |
|
||||
| filterIcon | 自定义 fiter 图标。| ReactNode | false |
|
||||
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - |
|
||||
| colSpan | 表头列合并,设置为 0 时,不渲染 | number | |
|
||||
| width | 列宽度 | string\|number | - |
|
||||
|
@ -39,7 +39,7 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.@{iconfont-css-prefix}-filter {
|
||||
.@{iconfont-css-prefix}-filter, .@{table-prefix-cls}-filter-icon {
|
||||
margin-left: 4px;
|
||||
font-size: @font-size-base;
|
||||
cursor: pointer;
|
||||
|
@ -24,6 +24,8 @@ Ant Design has 3 types Tabs for different situation.
|
||||
| defaultActiveKey | Default actived tabPanel's key, if activeKey is not setted. | - |
|
||||
| onChange | Callback when tab is switched | Function | - |
|
||||
| onTabClick | Callback when tab is clicked | Function | - |
|
||||
| onPrevClick | Callback when prev button is clicked | Function | 无 |
|
||||
| onNextClick | Callback when next button is clicked | Function | 无 |
|
||||
| tabBarExtraContent | Extra element in tab bar | React.ReactNode | - |
|
||||
| tabBarStyle | tar bar style object | object | - |
|
||||
| type | Basic style of tabs. Options: line, card & editable-card | string | line |
|
||||
@ -31,7 +33,7 @@ Ant Design has 3 types Tabs for different situation.
|
||||
| tabPosition | Position of tabs. Options: top, right, bottom & left | string | top |
|
||||
| onEdit | Callback when tab is added or removed, which is executing when set type as editable-card | (targetKey, action): void | - |
|
||||
| hideAdd | Hide plus icon or not, which is effective when set type as editable-card | boolean | false |
|
||||
| animated | Whether to change tabs with animation, this property only works with `tabPosition=top|bottom` | boolean | true |
|
||||
| animated | Whether to change tabs with animation, this property only works with `tabPosition=top|bottom` | boolean \| {inkBar:boolean, tabPane:boolean} | true |
|
||||
|
||||
### Tabs.TabPane
|
||||
| Property | Description | Type | Default |
|
||||
|
@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import { cloneElement } from 'react';
|
||||
import React, { cloneElement } from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import RcTabs, { TabPane } from 'rc-tabs';
|
||||
import ScrollableInkTabBar from 'rc-tabs/lib/ScrollableInkTabBar';
|
||||
@ -18,6 +17,8 @@ export interface TabsProps {
|
||||
hideAdd?: boolean;
|
||||
onChange?: (activeKey: string) => void;
|
||||
onTabClick?: Function;
|
||||
onPrevClick?: (e) => void;
|
||||
onNextClick?: (e) => void;
|
||||
tabBarExtraContent?: React.ReactNode | null;
|
||||
tabBarStyle?: React.CSSProperties;
|
||||
type?: TabsType;
|
||||
@ -27,7 +28,7 @@ export interface TabsProps {
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
animated?: boolean;
|
||||
animated?: boolean | { inkBar: boolean; tabPane: boolean; };
|
||||
}
|
||||
|
||||
// Tabs
|
||||
@ -95,8 +96,17 @@ export default class Tabs extends React.Component<TabsProps, any> {
|
||||
tabBarStyle,
|
||||
hideAdd,
|
||||
onTabClick,
|
||||
onPrevClick,
|
||||
onNextClick,
|
||||
animated,
|
||||
} = this.props;
|
||||
|
||||
let { inkBarAnimated, tabPaneAnimated } = typeof animated === 'object' ? {
|
||||
inkBarAnimated: animated.inkBar, tabPaneAnimated: animated.tabPane,
|
||||
} : {
|
||||
inkBarAnimated: animated, tabPaneAnimated: animated,
|
||||
};
|
||||
|
||||
warning(
|
||||
!(type.indexOf('card') >= 0 && size === 'small'),
|
||||
'Tabs[type=card|editable-card] doesn\'t have small size, it\'s by designed.',
|
||||
@ -150,8 +160,11 @@ export default class Tabs extends React.Component<TabsProps, any> {
|
||||
|
||||
const renderTabBar = () => (
|
||||
<ScrollableInkTabBar
|
||||
inkBarAnimated={inkBarAnimated}
|
||||
extraContent={tabBarExtraContent}
|
||||
onTabClick={onTabClick}
|
||||
onPrevClick={onPrevClick}
|
||||
onNextClick={onNextClick}
|
||||
style={tabBarStyle}
|
||||
/>
|
||||
);
|
||||
@ -162,7 +175,7 @@ export default class Tabs extends React.Component<TabsProps, any> {
|
||||
className={cls}
|
||||
tabBarPosition={tabPosition}
|
||||
renderTabBar={renderTabBar}
|
||||
renderTabContent={() => <TabContent animated={animated} animatedWithMargin />}
|
||||
renderTabContent={() => <TabContent animated={tabPaneAnimated} animatedWithMargin />}
|
||||
onChange={this.handleChange}
|
||||
>
|
||||
{childrenWithClose || children}
|
||||
|
@ -27,6 +27,8 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
|
||||
| defaultActiveKey | 初始化选中面板的 key,如果没有设置 activeKey | string | 第一个面板 |
|
||||
| onChange | 切换面板的回调 | Function | 无 |
|
||||
| onTabClick | tab 被点击的回调 | Function | 无 |
|
||||
| onPrevClick | prev 按钮被点击的回调 | Function | 无 |
|
||||
| onNextClick | next 按钮被点击的回调 | Function | 无 |
|
||||
| tabBarExtraContent | tab bar 上额外的元素 | React.ReactNode | 无 |
|
||||
| tabBarStyle | tar bar 的样式对象 | object | - |
|
||||
| type | 页签的基本样式,可选 `line`、`card` `editable-card` 类型 | string | 'line' |
|
||||
@ -34,7 +36,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
|
||||
| tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | 'top' |
|
||||
| onEdit | 新增和删除页签的回调,在 `type="editable-card"` 时有效 | (targetKey, action): void | 无 |
|
||||
| hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false |
|
||||
| animated | 是否使用动画切换 Tabs,在 `tabPosition=top|bottom` 时有效 | boolean | true |
|
||||
| animated | 是否使用动画切换 Tabs,在 `tabPosition=top|bottom` 时有效 | boolean \| {inkBar:boolean, tabPane:boolean} | true |
|
||||
|
||||
### Tabs.TabPane
|
||||
|
||||
|
@ -18,8 +18,10 @@
|
||||
box-sizing: border-box;
|
||||
height: 2px;
|
||||
background-color: @primary-color;
|
||||
transition: transform 0.3s @ease-in-out;
|
||||
transform-origin: 0 0;
|
||||
&-animated {
|
||||
transition: transform 0.3s @ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
&-bar {
|
||||
|
@ -1,5 +1,52 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/time-picker/demo/12hours.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
class="ant-time-picker "
|
||||
>
|
||||
<input
|
||||
class="ant-time-picker-input"
|
||||
placeholder="请选择时间"
|
||||
readonly=""
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-time-picker-icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-time-picker "
|
||||
>
|
||||
<input
|
||||
class="ant-time-picker-input"
|
||||
placeholder="请选择时间"
|
||||
readonly=""
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-time-picker-icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-time-picker "
|
||||
>
|
||||
<input
|
||||
class="ant-time-picker-input"
|
||||
placeholder="请选择时间"
|
||||
readonly=""
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-time-picker-icon"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/time-picker/demo/addon.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-time-picker "
|
||||
|
30
components/time-picker/demo/12hours.md
Normal file
30
components/time-picker/demo/12hours.md
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
order: 7
|
||||
title:
|
||||
zh-CN: 12 小时制
|
||||
en-US: 12 hours
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
12 小时制的时间选择器,默认的 format 为 `h:mm:ss a`。
|
||||
|
||||
## en-US
|
||||
|
||||
TimePicker of 12 hours format, with default format `h:mm:ss a`.
|
||||
|
||||
````jsx
|
||||
import { TimePicker } from 'antd';
|
||||
|
||||
function onChange(time, timeString) {
|
||||
console.log(time, timeString);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<TimePicker use12Hours onChange={onChange} />
|
||||
<TimePicker use12Hours format="h:mm:ss A" onChange={onChange} />
|
||||
<TimePicker use12Hours format="h:mm a" onChange={onChange} />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
@ -27,13 +27,14 @@ import moment from 'moment';
|
||||
| value | to set time | [moment](http://momentjs.com/) | - |
|
||||
| placeholder | display when there's no value | string | "Select a time" |
|
||||
| onChange | a callback function, can be executed when the selected time is changing | function(time: moment, timeString: string): void | - |
|
||||
| format | to set the time format | string | "HH:mm:ss"、"HH:mm"、"mm:ss" |
|
||||
| format | to set the time format | string | "HH:mm:ss" |
|
||||
| disabled | determine whether the TimePicker is disabled | boolean | false |
|
||||
| disabledHours | to specify the hours that cannot be selected | function() | - |
|
||||
| disabledMinutes | to specify the minutes that cannot be selected | function(selectedHour) | - |
|
||||
| disabledSeconds | to specify the seconds that cannot be selected | function(selectedHour, selectedMinute) | - |
|
||||
| hideDisabledOptions | hide the options that can not be selected | boolean | false |
|
||||
| getPopupContainer | to set the container of the floating layer, while the default is to create a div element in body | function(trigger) | - |
|
||||
| addon | called from timepicker panel to render some addon to its bottom | function | 无 |
|
||||
| addon | called from timepicker panel to render some addon to its bottom | function | - |
|
||||
| use12Hours | display as 12 hours format, with default format `h:mm:ss a` | boolean | false |
|
||||
|
||||
<style>.code-box-demo .ant-time-picker { margin: 0 8px 12px 0; }</style>
|
||||
|
@ -22,6 +22,7 @@ export interface TimePickerProps {
|
||||
style?: React.CSSProperties;
|
||||
getPopupContainer?: (triggerNode: Element) => HTMLElement;
|
||||
addon?: Function;
|
||||
use12Hours?: boolean;
|
||||
}
|
||||
|
||||
abstract class TimePicker extends React.Component<TimePickerProps, any> {
|
||||
@ -81,10 +82,21 @@ abstract class TimePicker extends React.Component<TimePickerProps, any> {
|
||||
this.timePickerRef.focus();
|
||||
}
|
||||
|
||||
getDefaultFormat() {
|
||||
const { format, use12Hours } = this.props;
|
||||
if (format) {
|
||||
return format;
|
||||
} else if (use12Hours) {
|
||||
return 'h:mm:ss a';
|
||||
}
|
||||
return 'HH:mm:ss';
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = assign({ format: 'HH:mm:ss' }, this.props);
|
||||
const props = assign({}, this.props);
|
||||
delete props.defaultValue;
|
||||
|
||||
const format = this.getDefaultFormat();
|
||||
const className = classNames(props.className, {
|
||||
[`${props.prefixCls}-${props.size}`]: !!props.size,
|
||||
});
|
||||
@ -101,12 +113,13 @@ abstract class TimePicker extends React.Component<TimePickerProps, any> {
|
||||
<RcTimePicker
|
||||
{...props}
|
||||
ref={this.saveTimePicker}
|
||||
format={format}
|
||||
className={className}
|
||||
value={this.state.value}
|
||||
placeholder={props.placeholder === undefined ? this.getLocale().placeholder : props.placeholder}
|
||||
showHour={props.format.indexOf('HH') > -1}
|
||||
showMinute={props.format.indexOf('mm') > -1}
|
||||
showSecond={props.format.indexOf('ss') > -1}
|
||||
showHour={format.indexOf('HH') > -1 || format.indexOf('h') > -1}
|
||||
showMinute={format.indexOf('mm') > -1}
|
||||
showSecond={format.indexOf('ss') > -1}
|
||||
onChange={this.handleChange}
|
||||
addon={addon}
|
||||
/>
|
||||
|
@ -28,7 +28,7 @@ import moment from 'moment';
|
||||
| value | 当前时间 | [moment](http://momentjs.com/) | 无 |
|
||||
| placeholder | 没有值的时候显示的内容 | string | "请选择时间" |
|
||||
| onChange | 时间发生变化的回调 | function(time: moment, timeString: string): void | 无 |
|
||||
| format | 展示的时间格式 | string | "HH:mm:ss"、"HH:mm"、"mm:ss" |
|
||||
| format | 展示的时间格式 | string | "HH:mm:ss" |
|
||||
| disabled | 禁用全部操作 | boolean | false |
|
||||
| disabledHours | 禁止选择部分小时选项 | function() | 无 |
|
||||
| disabledMinutes | 禁止选择部分分钟选项 | function(selectedHour) | 无 |
|
||||
@ -36,5 +36,6 @@ import moment from 'moment';
|
||||
| hideDisabledOptions | 隐藏禁止选择的选项 | boolean | false |
|
||||
| getPopupContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | 无 |
|
||||
| addon | 选择框底部显示自定义的内容 | function | 无 |
|
||||
| use12Hours | 使用 12 小时制,为 true 时 `format` 默认为 `h:mm:ss a` | boolean | false |
|
||||
|
||||
<style>.code-box-demo .ant-time-picker { margin: 0 8px 12px 0; }</style>
|
||||
|
5
components/time-picker/locale/et_EE.tsx
Normal file
5
components/time-picker/locale/et_EE.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
const locale = {
|
||||
placeholder: 'Vali aeg',
|
||||
};
|
||||
|
||||
export default locale;
|
5
components/time-picker/locale/ja_JP.tsx
Normal file
5
components/time-picker/locale/ja_JP.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
const locale = {
|
||||
placeholder: '時刻を選択',
|
||||
};
|
||||
|
||||
export default locale;
|
5
components/time-picker/locale/sk_SK.tsx
Normal file
5
components/time-picker/locale/sk_SK.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
const locale = {
|
||||
placeholder: 'Vybrať čas',
|
||||
};
|
||||
|
||||
export default locale;
|
5
components/time-picker/locale/tr_TR.tsx
Normal file
5
components/time-picker/locale/tr_TR.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
const locale = {
|
||||
placeholder: 'Zaman Seç',
|
||||
};
|
||||
|
||||
export default locale;
|
@ -5,7 +5,6 @@
|
||||
@timepicker-prefix-cls: ~"@{ant-prefix}-time-picker";
|
||||
|
||||
.@{timepicker-prefix-cls}-panel {
|
||||
max-width: @time-picker-panel-width;
|
||||
z-index: @zindex-picker;
|
||||
position: absolute;
|
||||
|
||||
|
@ -84,10 +84,6 @@
|
||||
&.@{select-tree-prefix-cls}-bottom_close,
|
||||
&.@{select-tree-prefix-cls}-noline_close {
|
||||
.antTreeSwitcherIcon();
|
||||
.ie-rotate(3);
|
||||
&:after {
|
||||
transform: rotate(270deg) scale(0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -484,6 +484,170 @@ exports[`renders ./components/tree/demo/basic-controlled.md correctly 1`] = `
|
||||
</ul>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree/demo/customized-icon.md correctly 1`] = `
|
||||
<ul
|
||||
class="ant-tree-show-line ant-tree"
|
||||
role="tree-node"
|
||||
unselectable="true"
|
||||
>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-roots_open"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
|
||||
title="parent 1"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-iconEle ant-tree-icon__open"
|
||||
/>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
parent 1
|
||||
</span>
|
||||
</a>
|
||||
<ul
|
||||
class="ant-tree-child-tree ant-tree-child-tree-open"
|
||||
data-expanded="true"
|
||||
>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-center_open"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open ant-tree-node-selected"
|
||||
title="parent 1-0"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-iconEle ant-tree-icon__open"
|
||||
/>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
parent 1-0
|
||||
</span>
|
||||
</a>
|
||||
<ul
|
||||
class="ant-tree-child-tree ant-tree-child-tree-open ant-tree-line"
|
||||
data-expanded="true"
|
||||
>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-switcher-noop ant-tree-center_docu"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
title="leaf"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-iconEle ant-tree-icon__docu"
|
||||
/>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
leaf
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-switcher-noop ant-tree-bottom_docu"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
title="leaf"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-iconEle ant-tree-icon__docu"
|
||||
/>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
leaf
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-center_open"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
|
||||
title="parent 1-1"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-iconEle ant-tree-icon__open"
|
||||
/>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
parent 1-1
|
||||
</span>
|
||||
</a>
|
||||
<ul
|
||||
class="ant-tree-child-tree ant-tree-child-tree-open ant-tree-line"
|
||||
data-expanded="true"
|
||||
>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-switcher-noop ant-tree-bottom_docu"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
title="leaf"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-iconEle ant-tree-icon__docu"
|
||||
/>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
leaf
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-switcher-noop ant-tree-bottom_docu"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
title="leaf"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-iconEle ant-tree-icon__docu"
|
||||
/>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
leaf
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree/demo/draggable.md correctly 1`] = `
|
||||
<ul
|
||||
class="draggable-tree ant-tree"
|
||||
@ -682,6 +846,144 @@ exports[`renders ./components/tree/demo/dynamic.md correctly 1`] = `
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree/demo/line.md correctly 1`] = `
|
||||
<ul
|
||||
class="ant-tree-show-line ant-tree"
|
||||
role="tree-node"
|
||||
unselectable="true"
|
||||
>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-roots_open"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
|
||||
title="parent 1"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
parent 1
|
||||
</span>
|
||||
</a>
|
||||
<ul
|
||||
class="ant-tree-child-tree ant-tree-child-tree-open"
|
||||
data-expanded="true"
|
||||
>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-center_open"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
|
||||
title="parent 1-0"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
parent 1-0
|
||||
</span>
|
||||
</a>
|
||||
<ul
|
||||
class="ant-tree-child-tree ant-tree-child-tree-open ant-tree-line"
|
||||
data-expanded="true"
|
||||
>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-switcher-noop ant-tree-center_docu"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
title="leaf"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
leaf
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-switcher-noop ant-tree-center_docu"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
title="leaf"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
leaf
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-switcher-noop ant-tree-bottom_docu"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
title="leaf"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
leaf
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-center_close"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"
|
||||
title="parent 1-1"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
parent 1-1
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-tree-switcher ant-tree-bottom_close"
|
||||
/>
|
||||
<a
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"
|
||||
title="parent 1-2"
|
||||
>
|
||||
<span
|
||||
class="ant-tree-title"
|
||||
>
|
||||
parent 1-2
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree/demo/search.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
|
85
components/tree/demo/customized-icon.md
Normal file
85
components/tree/demo/customized-icon.md
Normal file
@ -0,0 +1,85 @@
|
||||
---
|
||||
order: 6
|
||||
title:
|
||||
zh-CN: 自定义图标
|
||||
en-US: Customize Icon
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以针对不同节点采用样式覆盖的方式定制图标。
|
||||
|
||||
## en-US
|
||||
|
||||
You can customize icons for different nodes by styles override.
|
||||
|
||||
````jsx
|
||||
import { Tree } from 'antd';
|
||||
const TreeNode = Tree.TreeNode;
|
||||
|
||||
class Demo extends React.Component {
|
||||
onSelect = (selectedKeys, info) => {
|
||||
console.log('selected', selectedKeys, info);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Tree
|
||||
showIcon
|
||||
showLine
|
||||
defaultExpandedKeys={['0-0-0', '0-0-1']}
|
||||
defaultSelectedKeys={['0-0-0', '0-0-1']}
|
||||
onSelect={this.onSelect}
|
||||
>
|
||||
<TreeNode title="parent 1" key="0-0">
|
||||
<TreeNode title="parent 1-0" key="0-0-0">
|
||||
<TreeNode title="leaf" key="0-0-0-0" />
|
||||
<TreeNode title="leaf" key="0-0-0-1" />
|
||||
</TreeNode>
|
||||
<TreeNode title="parent 1-1" key="0-0-1">
|
||||
<TreeNode title="leaf" key="0-0-1-0" />
|
||||
</TreeNode>
|
||||
<TreeNode title="leaf" key="0-0-2" />
|
||||
</TreeNode>
|
||||
</Tree>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
||||
|
||||
```css
|
||||
#components-tree-demo-customized-icon .ant-tree-iconEle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
background: #fff;
|
||||
}
|
||||
#components-tree-demo-customized-icon .ant-tree-iconEle::after {
|
||||
font-size: 12px;
|
||||
zoom: 1;
|
||||
display: inline-block;
|
||||
font-family: 'anticon';
|
||||
text-rendering: optimizeLegibility;
|
||||
color: #999;
|
||||
transition: transform .3s ease;
|
||||
margin-top: 2px;
|
||||
background: #fff;
|
||||
}
|
||||
#components-tree-demo-customized-icon .ant-tree-iconEle.ant-tree-icon__docu::after {
|
||||
content: "\E664";
|
||||
}
|
||||
#components-tree-demo-customized-icon .ant-tree-iconEle.ant-tree-icon__open::after {
|
||||
content: "\E699";
|
||||
}
|
||||
#components-tree-demo-customized-icon .ant-tree-iconEle.ant-tree-icon__close::after {
|
||||
content: "\E662";
|
||||
}
|
||||
#components-tree-demo-customized-icon .ant-tree-switcher {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
background: transparent;
|
||||
}
|
||||
#components-tree-demo-customized-icon .ant-tree-switcher::after {
|
||||
opacity: 0;
|
||||
}
|
||||
```
|
51
components/tree/demo/line.md
Normal file
51
components/tree/demo/line.md
Normal file
@ -0,0 +1,51 @@
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 连接线
|
||||
en-US: Tree With Line
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
带连接线的树。
|
||||
|
||||
## en-US
|
||||
|
||||
Tree With Line
|
||||
|
||||
````jsx
|
||||
import { Tree } from 'antd';
|
||||
const TreeNode = Tree.TreeNode;
|
||||
|
||||
class Demo extends React.Component {
|
||||
onSelect = (selectedKeys, info) => {
|
||||
console.log('selected', selectedKeys, info);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Tree
|
||||
showLine
|
||||
defaultExpandedKeys={['0-0-0']}
|
||||
onSelect={this.onSelect}
|
||||
>
|
||||
<TreeNode title="parent 1" key="0-0">
|
||||
<TreeNode title="parent 1-0" key="0-0-0">
|
||||
<TreeNode title="leaf" key="0-0-0-0" />
|
||||
<TreeNode title="leaf" key="0-0-0-1" />
|
||||
<TreeNode title="leaf" key="0-0-0-2" />
|
||||
</TreeNode>
|
||||
<TreeNode title="parent 1-1" key="0-0-1">
|
||||
<TreeNode title="leaf" key="0-0-1-0" />
|
||||
</TreeNode>
|
||||
<TreeNode title="parent 1-2" key="0-0-2">
|
||||
<TreeNode title="leaf" key="0-0-2-0" />
|
||||
<TreeNode title="leaf" key="0-0-2-1" />
|
||||
</TreeNode>
|
||||
</TreeNode>
|
||||
</Tree>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
@ -38,6 +38,8 @@ Directory, organization, biological classification, country, and etc. Almost thi
|
||||
|onDragLeave | Defines a function will be called when the onDragLeave event occurs | function({event, node}) | - |
|
||||
|onDragEnd | Defines a function will be called when the onDragEnd event occurs | function({event, node}) | - |
|
||||
|onDrop | Defines a function will be called when the onDrop event occurs | function({event, node, dragNode, dragNodesKeys}) | - |
|
||||
|showLine | Whether show connecting line | boolean | false |
|
||||
|showIcon | Whether show the icon before TreeNode title, which has no default style, you must set custom style for it if set to true | boolean | false |
|
||||
|
||||
### TreeNode props
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import RcTree, { TreeNode } from 'rc-tree';
|
||||
import animation from '../_util/openAnimation';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface AntTreeNodeProps {
|
||||
disabled?: boolean;
|
||||
@ -96,11 +97,16 @@ export default class Tree extends React.Component<TreeProps, any> {
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const { prefixCls, className, showLine } = props;
|
||||
let checkable = props.checkable;
|
||||
const classString = classNames({
|
||||
[`${prefixCls}-show-line`]: !!showLine,
|
||||
}, className);
|
||||
return (
|
||||
<RcTree
|
||||
{...props}
|
||||
checkable={checkable ? (<span className={`${props.prefixCls}-checkbox-inner`} />) : checkable}
|
||||
className={classString}
|
||||
checkable={checkable ? <span className={`${prefixCls}-checkbox-inner`} /> : checkable}
|
||||
>
|
||||
{this.props.children}
|
||||
</RcTree>
|
||||
|
@ -39,6 +39,8 @@ subtitle: 树形控件
|
||||
|onDragLeave | dragleave 触发时调用 | function({event, node}) | - |
|
||||
|onDragEnd | dragend 触发时调用 | function({event, node}) | - |
|
||||
|onDrop | drop 触发时调用 | function({event, node, dragNode, dragNodesKeys}) | - |
|
||||
|showLine | 是否展示连接线 | boolean | false |
|
||||
|showIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true,需要自行定义图标相关样式 | boolean | false |
|
||||
|
||||
### TreeNode props
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
user-select: none;
|
||||
border-top: 2px transparent solid;
|
||||
border-bottom: 2px transparent solid;
|
||||
|
||||
margin-top: -2px;
|
||||
/* Required to make elements draggable in old WebKit */
|
||||
-khtml-user-drag: element;
|
||||
-webkit-user-drag: element;
|
||||
@ -72,7 +72,8 @@
|
||||
}
|
||||
span {
|
||||
&.@{tree-prefix-cls}-checkbox {
|
||||
margin: 0 4px 0 0;
|
||||
margin: 0 4px 0 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
&.@{tree-prefix-cls}-switcher,
|
||||
&.@{tree-prefix-cls}-iconEle {
|
||||
@ -96,7 +97,7 @@
|
||||
}
|
||||
&.@{tree-prefix-cls}-switcher {
|
||||
&.@{tree-prefix-cls}-switcher-noop {
|
||||
cursor: auto;
|
||||
cursor: default;
|
||||
}
|
||||
&.@{tree-prefix-cls}-roots_open,
|
||||
&.@{tree-prefix-cls}-center_open,
|
||||
@ -111,11 +112,19 @@
|
||||
.antTreeSwitcherIcon();
|
||||
.ie-rotate(3);
|
||||
&:after {
|
||||
transform: rotate(270deg) scale(0.6);
|
||||
transform: rotate(270deg) scale(0.59);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&:last-child > span {
|
||||
&.@{tree-prefix-cls}-switcher,
|
||||
&.@{tree-prefix-cls}-iconEle {
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> li {
|
||||
&:first-child {
|
||||
@ -132,9 +141,9 @@
|
||||
}
|
||||
}
|
||||
&-treenode-disabled {
|
||||
>span,
|
||||
>a,
|
||||
>a span {
|
||||
> span,
|
||||
> a,
|
||||
> a span {
|
||||
color: @disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
@ -147,4 +156,39 @@
|
||||
margin-right: 2px;
|
||||
vertical-align: top;
|
||||
}
|
||||
// Tree with line
|
||||
&&-show-line {
|
||||
li {
|
||||
position: relative;
|
||||
span {
|
||||
&.@{tree-prefix-cls}-switcher {
|
||||
background: @component-background;
|
||||
&.@{tree-prefix-cls}-switcher-noop {
|
||||
.antTreeShowLineIcon("tree-doc-icon");
|
||||
}
|
||||
&.@{tree-prefix-cls}-roots_open,
|
||||
&.@{tree-prefix-cls}-center_open,
|
||||
&.@{tree-prefix-cls}-bottom_open,
|
||||
&.@{tree-prefix-cls}-noline_open {
|
||||
.antTreeShowLineIcon("tree-showline-open-icon");
|
||||
}
|
||||
&.@{tree-prefix-cls}-roots_close,
|
||||
&.@{tree-prefix-cls}-center_close,
|
||||
&.@{tree-prefix-cls}-bottom_close,
|
||||
&.@{tree-prefix-cls}-noline_close {
|
||||
.antTreeShowLineIcon("tree-showline-close-icon");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
li:not(:last-child):before {
|
||||
content: ' ';
|
||||
width: 1px;
|
||||
border-left: 1px solid @border-color-base;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
margin: 18px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,30 @@
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
.antTreeSwitcherIcon() {
|
||||
position: relative;
|
||||
@tree-default-open-icon: "\e606";
|
||||
@tree-showline-open-icon: "\e621";
|
||||
@tree-showline-close-icon: "\e645";
|
||||
@tree-doc-icon: "\e664";
|
||||
@tree-showline-icon-color: @text-color-secondary;
|
||||
|
||||
.antTreeSwitcherIcon(@type: "tree-default-open-icon") {
|
||||
&:after {
|
||||
.iconfont-size-under-12px(7px);
|
||||
display: inline-block;
|
||||
.iconfont-font("\e606");
|
||||
.iconfont-font(@@type);
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 4px;
|
||||
color: @text-color;
|
||||
transition: transform .3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.antTreeShowLineIcon(@type) {
|
||||
&:after {
|
||||
.iconfont-size-under-12px(12px);
|
||||
display: inline-block;
|
||||
.iconfont-font(@@type);
|
||||
vertical-align: baseline;
|
||||
font-weight: normal;
|
||||
color: @tree-showline-icon-color;
|
||||
transition: transform .3s ease;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ Supported languages:
|
||||
- Swedish - sv_SE
|
||||
- Dutch - nl_NL
|
||||
- Catalan - ca_ES
|
||||
- Japanese - ja_JP
|
||||
|
||||
See usage and contributing way of a new locale package at [LocaleProvider](/components/locale-provider).
|
||||
|
||||
|
@ -32,6 +32,7 @@ return (
|
||||
- 瑞典语 - sv_SE
|
||||
- 荷兰语 - nl_NL
|
||||
- 加泰罗尼亚 - ca_ES
|
||||
- 日本语 - ja_JP
|
||||
|
||||
具体的使用方法和新语言包贡献方式请参考 [LocaleProvider 文档](/components/locale-provider)。
|
||||
|
||||
|
@ -67,7 +67,7 @@ Add `script` and `link` tags in your browser and use the global variable `antd`.
|
||||
|
||||
We provide `antd.js` `antd.css` and `antd.min.js` `antd.min.css` under `antd/dist` in antd's npm package. You can also download these files directly from [](https://cdnjs.com/libraries/antd) or [unpkg](https://unpkg.com/).
|
||||
|
||||
> **We strongly discourage loading these entire files** this will add bloat to your application and make it more difficult to receive bugfixes and updates. Ant is intended to be used in conjunction with a built a tool, such as [webpack](https://webpack.github.io/), which will make it easy to import only the parts of antd that you are using.
|
||||
> **We strongly discourage loading these entire files** this will add bloat to your application and make it more difficult to receive bugfixes and updates. Ant is intended to be used in conjunction with a built a tool, such as [webpack](https://webpack.github.io/), which will make it easy to import only the parts of antd that you are using.
|
||||
|
||||
## Usage
|
||||
|
||||
@ -95,7 +95,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
}
|
||||
```
|
||||
|
||||
This allows you to import components from antd without having to manually import the corresponding stylesheet. The antd babel plugin will automatically import stylesheets.
|
||||
This allows you to import components from antd without having to manually import the corresponding stylesheet. The antd babel plugin will automatically import stylesheets.
|
||||
|
||||
```jsx
|
||||
// import js and css modularly, parsed by babel-plugin-import
|
||||
@ -164,7 +164,6 @@ If you'd like to help us improve antd, just create a [Pull Request](https://gith
|
||||
|
||||
## Need Help?
|
||||
|
||||
For questions on how to use antd, please post questions to [stackoverflow](http://stackoverflow.com/questions/tagged/antd) using the `antd` tag. If you're not finding what you need on stackoverflow, you can find us on [gitter](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) as well.
|
||||
For questions on how to use antd, please post questions to [stackoverflow](http://stackoverflow.com/questions/tagged/antd) using the `antd` tag. If you're not finding what you need on stackoverflow, you can find us on [gitter](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) as well.
|
||||
|
||||
As always, we encourage experienced users to help those who are not familiar with `antd`!
|
||||
|
||||
|
12
package.json
12
package.json
@ -43,7 +43,7 @@
|
||||
"object-assign": "~4.1.0",
|
||||
"omit.js": "^0.1.0",
|
||||
"rc-animate": "~2.3.0",
|
||||
"rc-calendar": "~7.6.2",
|
||||
"rc-calendar": "~7.7.1",
|
||||
"rc-cascader": "~0.11.0",
|
||||
"rc-checkbox": "~1.5.0",
|
||||
"rc-collapse": "~1.6.4",
|
||||
@ -51,11 +51,11 @@
|
||||
"rc-dropdown": "~1.4.8",
|
||||
"rc-editor-mention": "~0.5.2",
|
||||
"rc-form": "~1.3.0",
|
||||
"rc-input-number": "~3.3.0",
|
||||
"rc-input-number": "~3.4.4",
|
||||
"rc-menu": "~5.0.9",
|
||||
"rc-notification": "~1.4.0",
|
||||
"rc-pagination": "~1.7.0",
|
||||
"rc-progress": "~2.0.1",
|
||||
"rc-pagination": "~1.8.0",
|
||||
"rc-progress": "~2.1.0",
|
||||
"rc-radio": "~2.0.0",
|
||||
"rc-rate": "~2.1.0",
|
||||
"rc-select": "~6.8.0",
|
||||
@ -63,8 +63,8 @@
|
||||
"rc-steps": "~2.4.0",
|
||||
"rc-switch": "~1.4.2",
|
||||
"rc-table": "~5.2.13",
|
||||
"rc-tabs": "~7.2.0",
|
||||
"rc-time-picker": "~2.2.1",
|
||||
"rc-tabs": "~7.3.0",
|
||||
"rc-time-picker": "~2.3.3",
|
||||
"rc-tooltip": "~3.4.2",
|
||||
"rc-tree": "~1.4.0",
|
||||
"rc-tree-select": "~1.9.0",
|
||||
|
Loading…
Reference in New Issue
Block a user