diff --git a/components/date-picker/WeekPicker.tsx b/components/date-picker/WeekPicker.tsx new file mode 100644 index 0000000000..08ef187f8d --- /dev/null +++ b/components/date-picker/WeekPicker.tsx @@ -0,0 +1,131 @@ +import React, { Component } from 'react'; +import moment from 'moment'; +import Calendar from 'rc-calendar'; +import RcDatePicker from 'rc-calendar/lib/Picker'; +import classNames from 'classnames'; +import Icon from '../icon'; +import { getLocaleCode } from '../_util/getLocale'; + +function formatValue(value: moment.Moment | undefined, format: string): string { + return (value && value.format(format)) || ''; +} + +export default class WeekPicker extends Component { + static defaultProps = { + format: 'YYYY-Wo', + allowClear: true, + }; + constructor(props) { + super(props); + const value = props.value || props.defaultValue; + if (value && !moment.isMoment(value)) { + throw new Error( + 'The value/defaultValue of DatePicker or MonthPicker must be ' + + 'a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value', + ); + } + this.state = { + value, + }; + } + componentWillReceiveProps(nextProps) { + if ('value' in nextProps) { + this.setState({ value: nextProps.value }); + } + } + weekDateRender = (current) => { + const selectedValue = this.state.value; + const { prefixCls } = this.props; + if (selectedValue && + current.year() === selectedValue.year() && + current.week() === selectedValue.week()) { + return ( +
+
+ {current.date()} +
+
+ ); + } + return ( +
+ {current.date()} +
+ ); + } + handleChange = (value) => { + if (!('value' in this.props)) { + this.setState({ value }); + } + this.props.onChange(value, formatValue(value, this.props.format)); + } + clearSelection = (e) => { + e.preventDefault(); + e.stopPropagation(); + this.handleChange(null); + } + render() { + const { + prefixCls, className, disabled, pickerClass, popupStyle, + pickerInputClass, format, allowClear, locale, disabledDate, + } = this.props; + + const pickerValue = this.state.value; + const localeCode = getLocaleCode(this.context); + if (pickerValue && localeCode) { + pickerValue.locale(localeCode); + } + + const placeholder = ('placeholder' in this.props) + ? this.props.placeholder : locale.lang.placeholder; + + const calendar = ( + + ); + const clearIcon = (!disabled && allowClear && this.state.value) ? ( + + ) : null; + const input = ({ value }) => { + return ( + + + {clearIcon} + + + ); + }; + return ( + + + {input} + + + ); + } +} diff --git a/components/date-picker/__tests__/__snapshots__/demo.test.js.snap b/components/date-picker/__tests__/__snapshots__/demo.test.js.snap index 7b593921b0..1a138cdf2b 100644 --- a/components/date-picker/__tests__/__snapshots__/demo.test.js.snap +++ b/components/date-picker/__tests__/__snapshots__/demo.test.js.snap @@ -62,6 +62,22 @@ exports[`renders ./components/date-picker/demo/basic.md correctly 1`] = ` /> +
+ + + + + + `; @@ -604,6 +620,22 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = ` /> +
+ + + + + + `; diff --git a/components/date-picker/__tests__/__snapshots__/other.test.js.snap b/components/date-picker/__tests__/__snapshots__/other.test.js.snap new file mode 100644 index 0000000000..11edea629d --- /dev/null +++ b/components/date-picker/__tests__/__snapshots__/other.test.js.snap @@ -0,0 +1,966 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`MonthPicker and WeekPicker render MonthPicker 1`] = ` +
+ +
+`; + +exports[`MonthPicker and WeekPicker render WeekPicker 1`] = ` +
+ +
+`; diff --git a/components/date-picker/__tests__/other.test.js b/components/date-picker/__tests__/other.test.js new file mode 100644 index 0000000000..7673961bab --- /dev/null +++ b/components/date-picker/__tests__/other.test.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { mount, render } from 'enzyme'; +import moment from 'moment'; +import { MonthPicker, WeekPicker } from '../'; + +describe('MonthPicker and WeekPicker', () => { + it('render MonthPicker', () => { + const birthday = moment('2000-01-01', 'YYYY-MM-DD').locale('zh-cn'); + const wrapper = mount( + + ); + wrapper.setProps({ value: birthday }); + expect(render(wrapper.find('Trigger').node.getComponent())).toMatchSnapshot(); + }); + + it('render WeekPicker', () => { + const birthday = moment('2000-01-01', 'YYYY-MM-DD').locale('zh-cn'); + const wrapper = mount( + + ); + wrapper.setProps({ value: birthday }); + expect(render(wrapper.find('Trigger').node.getComponent())).toMatchSnapshot(); + }); +}); diff --git a/components/date-picker/demo/basic.md b/components/date-picker/demo/basic.md index f568f7ff7e..6053cbb8ae 100644 --- a/components/date-picker/demo/basic.md +++ b/components/date-picker/demo/basic.md @@ -15,7 +15,7 @@ Basic use case. Users can select or input a date in panel. ````jsx import { DatePicker } from 'antd'; -const { MonthPicker, RangePicker } = DatePicker; +const { MonthPicker, RangePicker, WeekPicker } = DatePicker; function onChange(date, dateString) { console.log(date, dateString); @@ -28,6 +28,8 @@ ReactDOM.render(
+
+ , mountNode); ```` diff --git a/components/date-picker/demo/size.md b/components/date-picker/demo/size.md index cefbfb4070..0ade3d80d3 100644 --- a/components/date-picker/demo/size.md +++ b/components/date-picker/demo/size.md @@ -16,7 +16,7 @@ The input box comes in three sizes. `default` will be used if `size` is omitted. ````jsx import { DatePicker, Radio } from 'antd'; -const { MonthPicker, RangePicker } = DatePicker; +const { MonthPicker, RangePicker, WeekPicker } = DatePicker; class PickerSizesDemo extends React.Component { state = { @@ -42,6 +42,8 @@ class PickerSizesDemo extends React.Component {
+
+ ); } diff --git a/components/date-picker/index.en-US.md b/components/date-picker/index.en-US.md index 4155f593ea..a6ac716adf 100644 --- a/components/date-picker/index.en-US.md +++ b/components/date-picker/index.en-US.md @@ -12,13 +12,14 @@ By clicking the input box, you can select a date from a popup calendar. ## API -There are three kinds of picker: +There are four kinds of picker: * DatePicker * MonthPicker * RangePicker +* WeekPicker -**Note:** Part of locale of DatePicker, MonthPicker, RangePicker is read from value. So, please set the locale of moment correctly. +**Note:** Part of locale of DatePicker, MonthPicker, RangePicker, WeekPicker is read from value. So, please set the locale of moment correctly. ```jsx import moment from 'moment'; @@ -32,7 +33,7 @@ moment.locale('zh-cn'); ### Common API -The following APIs are shared by DatePicker, MonthPicker, RangePicker. +The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicker. | Property | Description | Type | Default | |--------------|----------------|----------|--------------| @@ -66,7 +67,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker. ### MonthPicker -| Property | Description | Type | Default | +| Property | Description | Type | Default | |--------------|----------------|----------|--------------| | value | to set date | [moment](http://momentjs.com/) | - | | defaultValue | to set default date | [moment](http://momentjs.com/) | - | @@ -74,6 +75,15 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker. | onChange | a callback function, can be executed when the selected time is changing | function(date: moment, dateString: string) | - | | monthCellContentRender | Custom month cell content render method | function(date, locale): ReactNode | - | +### WeekPicker + +| Property | Description | Type | Default | +|--------------|----------------|----------|--------------| +| value | to set date | [moment](http://momentjs.com/) | - | +| defaultValue | to set default date | [moment](http://momentjs.com/) | - | +| format | to set the date format, refer to [moment.js](http://momentjs.com/) | string | "YYYY-Wo" | +| onChange | a callback function, can be executed when the selected time is changing | function(date: moment, dateString: string) | - | + ### RangePicker | Property | Description | Type | Default | diff --git a/components/date-picker/index.tsx b/components/date-picker/index.tsx index 75312723e9..17640b9cc7 100755 --- a/components/date-picker/index.tsx +++ b/components/date-picker/index.tsx @@ -5,6 +5,7 @@ import MonthCalendar from 'rc-calendar/lib/MonthCalendar'; import createPicker from './createPicker'; import wrapPicker from './wrapPicker'; import RangePicker from './RangePicker'; +import WeekPicker from './WeekPicker'; import Calendar from './Calendar'; import { TimePickerProps } from '../time-picker'; @@ -75,15 +76,22 @@ export interface RangePickerProps extends PickerProps { }; } +export interface WeexPickerProps extends PickerProps, SinglePickerProps { + className?: string; + placeholder?: string; +} + Object.assign(DatePicker, { RangePicker: wrapPicker(RangePicker), Calendar, MonthPicker, + WeekPicker: wrapPicker(WeekPicker, 'YYYY-Wo'), }); export interface DatePickerDecorator extends React.ClassicComponentClass { RangePicker: React.ClassicComponentClass; MonthPicker: React.ClassicComponentClass; + WeekPicker: React.ClassicComponentClass; } export default DatePicker as DatePickerDecorator; diff --git a/components/date-picker/index.zh-CN.md b/components/date-picker/index.zh-CN.md index f3f31abc1f..777f0753ac 100644 --- a/components/date-picker/index.zh-CN.md +++ b/components/date-picker/index.zh-CN.md @@ -13,13 +13,14 @@ subtitle: 日期选择框 ## API -日期类组件包括以下三种形式。 +日期类组件包括以下四种形式。 * DatePicker * MonthPicker * RangePicker +* WeekPicker -**注意:**DatePicker、MonthPicker、RangePicker 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。 +**注意:**DatePicker、MonthPicker、RangePicker、WeekPicker 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。 ```jsx import moment from 'moment'; @@ -33,7 +34,7 @@ moment.locale('zh-cn'); ### 共同的 API -以下 API 为 DatePicker、MonthPicker、RangePicker 共享的 API。 +以下 API 为 DatePicker、MonthPicker、RangePicker, WeekPicker 共享的 API。 | 参数 | 说明 | 类型 | 默认值 | |--------------|----------------|----------|--------------| @@ -75,6 +76,15 @@ moment.locale('zh-cn'); | onChange | 时间发生变化的回调,发生在用户选择时间时 | function(date: moment, dateString: string) | - | | monthCellContentRender | 自定义的月份内容渲染方法 | function(date, locale): ReactNode | - | +### WeekPicker + +| 参数 | 说明 | 类型 | 默认值 | +|--------------|----------------|----------|--------------| +| value | 日期 | [moment](http://momentjs.com/) | - | +| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | +| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | "YYYY-Wo" | +| onChange | 时间发生变化的回调,发生在用户选择时间时 | function(date: moment, dateString: string) | - | + ### RangePicker | 参数 | 说明 | 类型 | 默认值 | diff --git a/components/date-picker/style/WeekPicker.less b/components/date-picker/style/WeekPicker.less new file mode 100644 index 0000000000..a6f533693c --- /dev/null +++ b/components/date-picker/style/WeekPicker.less @@ -0,0 +1,21 @@ +.@{calendar-prefix-cls}-week-number { + &-cell { + opacity: 0.5; + } + tr { + transition: all .3s; + cursor: pointer; + &:hover { + background: @primary-1; + } + &.@{calendar-prefix-cls}-active-week { + background: @primary-2; + font-weight: 500; + } + .@{calendar-prefix-cls}-selected-day .@{calendar-prefix-cls}-date, + .@{calendar-prefix-cls}-selected-day:hover .@{calendar-prefix-cls}-date { + background: transparent; + color: @text-color; + } + } +} diff --git a/components/date-picker/style/index.less b/components/date-picker/style/index.less index 37139915a3..466b7e889f 100644 --- a/components/date-picker/style/index.less +++ b/components/date-picker/style/index.less @@ -14,3 +14,4 @@ @import "YearPanel"; @import "DecadePanel"; @import "MonthPicker"; +@import "WeekPicker";