Skip to content

Commit d02357c

Browse files
authored
feat: DatePicker add date range picker (#323)
Authored-by: jianyi-gronk <jianyi_gronk@163.com>
1 parent 6f8b551 commit d02357c

22 files changed

Lines changed: 749 additions & 45 deletions

File tree

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ sites/pc/static/js/
1515
sites/pc/pages/
1616
sites/pages/
1717
packages/arcodesign/tools/*.js
18+
**/*.js

packages/arcodesign/components/date-picker/README.en-US.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,21 @@ Date picker, based on the `Picker` component, supports the specified range, the
1010
1111
|Property|Description|Type|DefaultValue|
1212
|----------|-------------|------|------|
13-
|onOk|Callback when clicking OK|(timestamp: number, obj: IDateObj) =\> void|-|
14-
|currentTs|The currently selected time, timestamp|number|Date.now()|
15-
|onChange|Callback when value is changed|(timestamp: number, obj: IDateObj) =\> void|-|
13+
|onOk|Callback when clicking OK|(timestamp: number \| \[number, number\], obj: IDateObj \| \[IDateObj, IDateObj\]) =\> void|-|
14+
|currentTs|The currently selected time, timestamp|number \| \[number, number\]|Date.now()|
15+
|onChange|Callback when value is changed|(timestamp: number \| \[number, number\], obj: IDateObj \| \[IDateObj, IDateObj\]) =\> void|-|
1616
|onValueChange|The callback function after each column data selection changes|(timestamp: number, obj: IDateObj, index: number) =\> void|-|
1717
|mode|Optional column type, date means year, month and day, time means hour, minute and second, datetime means year, month, day, hour, minute and second|"date" \| "time" \| "datetime"|"datetime"|
1818
|typeArr|optional column list|ItemType\[\]|[]|
19-
|minTs|Minimum selectable date, timestamp|number|10 years ago from the current time|
20-
|maxTs|Maximum selectable date, timestamp|number|Next decade from current time|
19+
|minTs|Minimum selectable date, timestamp|number \| \{ startTs: number; endTs: number; \}|10 years ago from the current time|
20+
|maxTs|Maximum selectable date, timestamp|number \| \{ startTs: number; endTs: number; \}|Next decade from current time|
2121
|useUTC|Whether to use UTC|boolean|false|
22+
|rangeItemFormat|Time range picker display format|string|-|
2223
|formatter|The formatting method of each optional item, the parameter type is ItemTypes, the parameter value is the value of the current row, and the displayed text is returned\.|(value: number, type: ItemType) =\> string|(value: number) => (value < 10 ? \`0${value}\` : String(value))|
2324
|valueFilter|Row filtering method, the parameter type is ItemType, the parameter value is the value of the current row, and returns true to indicate that the row can be selected|(type: ItemType, value: number) =\> boolean|() => true|
2425
|columnsProcessor|Selector list item intervention to insert custom options\.|(columns: PickerData\[\]\[\], currentDateObj: IDateObj) =\> PickerData\[\]\[\]|-|
25-
|renderLinkedContainer|Associate the hidden state of the picker and the display of the selected value with a container\. After passing it in, the container and the picker component will be rendered at the same time\. At this time, the visible and onHide attributes of the picker component are optional values\. Clicking the container will evoke the picker|(currentTs: number, itemTypes: ItemType\[\]) =\> ReactNode|-|
26+
|renderSeparator|Defined separator area|() =\> ReactNode|-|
27+
|renderLinkedContainer|Associate the hidden state of the picker and the display of the selected value with a container\. After passing it in, the container and the picker component will be rendered at the same time\. At this time, the visible and onHide attributes of the picker component are optional values\. Clicking the container will evoke the picker|(currentTs: number \| \[number, number\], itemTypes: ItemType\[\]) =\> ReactNode|-|
2628
|visible|whether to show the picker|boolean|false|
2729
|maskClosable|Whether to click the mask to close the menu|boolean|false|
2830
|needBottomOffset|Whether the content of the menu that slides out from the bottom fits the bottom of ipx|boolean|false|
@@ -59,6 +61,7 @@ Date picker, based on the `Picker` component, supports the specified range, the
5961
|hideEmptyCols|Whether to hide empty columns without data, often used for cascading selection|boolean|false|
6062
|title|Picker title|string|""|
6163
|touchToStop|Whether to stop sliding by long\-pressing, inputing in the number x means that the touch exceeds x milliseconds to count as long\-pressing, inputing true means that x=100, the long\-press event and the click event are mutually exclusive|number \| boolean|false|
64+
|renderExtraHeader|Define the area of extra header|() =\> ReactNode|-|
6265

6366
> Refs
6467

packages/arcodesign/components/date-picker/README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,21 @@
1010
1111
|参数|描述|类型|默认值|
1212
|----------|-------------|------|------|
13-
|onOk|点击选中时执行的回调|(timestamp: number, obj: IDateObj) =\> void|-|
14-
|currentTs|当前选中的时间,timestamp|number|Date.now()|
15-
|onChange|选中后的回调|(timestamp: number, obj: IDateObj) =\> void|-|
13+
|onOk|点击选中时执行的回调|(timestamp: number \| \[number, number\], obj: IDateObj \| \[IDateObj, IDateObj\]) =\> void|-|
14+
|currentTs|当前选中的时间,timestamp|number \| \[number, number\]|Date.now()|
15+
|onChange|选中后的回调|(timestamp: number \| \[number, number\], obj: IDateObj \| \[IDateObj, IDateObj\]) =\> void|-|
1616
|onValueChange|每列数据选择变化后的回调函数|(timestamp: number, obj: IDateObj, index: number) =\> void|-|
1717
|mode|可选列类型,date \- 年月日,time \- 时分秒,datetime \- 年月日时分秒|"date" \| "time" \| "datetime"|"datetime"|
1818
|typeArr|可选列数组|ItemType\[\]|[]|
19-
|minTs|最小可选日期,timestamp|number|当前时间的前十年|
20-
|maxTs|最大可选日期,timestamp|number|当前时间的后十年|
19+
|minTs|最小可选日期,timestamp|number \| \{ startTs: number; endTs: number; \}|当前时间的前十年|
20+
|maxTs|最大可选日期,timestamp|number \| \{ startTs: number; endTs: number; \}|当前时间的后十年|
2121
|useUTC|是否使用 UTC 时间|boolean|false|
22+
|rangeItemFormat|日期时间范围选择展示格式|string|-|
2223
|formatter|各可选项展示的格式化方法,参数type为ItemTypes,参数value为当前行的值,返回展示的文字|(value: number, type: ItemType) =\> string|(value: number) => (value < 10 ? \`0${value}\` : String(value))|
2324
|valueFilter|可选择行过滤方法,参数type为ItemType,参数value为当前行的值,返回true表示该行可选择|(type: ItemType, value: number) =\> boolean|() => true|
2425
|columnsProcessor|选择器列表项干预,可插入自定义选项|(columns: PickerData\[\]\[\], currentDateObj: IDateObj) =\> PickerData\[\]\[\]|-|
25-
|renderLinkedContainer|将选择器的展现隐藏状态及选中值的展示与某个容器关联,传入后将同时渲染该容器和选择器组件,此时选择器组件的 visible 和 onHide 属性可不传,点击该容器会唤起选择器|(currentTs: number, itemTypes: ItemType\[\]) =\> ReactNode|-|
26+
|renderSeparator|自定义分隔符|() =\> ReactNode|-|
27+
|renderLinkedContainer|将选择器的展现隐藏状态及选中值的展示与某个容器关联,传入后将同时渲染该容器和选择器组件,此时选择器组件的 visible 和 onHide 属性可不传,点击该容器会唤起选择器|(currentTs: number \| \[number, number\], itemTypes: ItemType\[\]) =\> ReactNode|-|
2628
|visible|是否展示选择器|boolean|false|
2729
|maskClosable|点击蒙层是否关闭菜单|boolean|false|
2830
|needBottomOffset|从底部滑出的菜单内容是否适配ipx底部|boolean|false|
@@ -59,6 +61,7 @@
5961
|hideEmptyCols|是否隐藏无数据的空列,常用于级联选择|boolean|false|
6062
|title|选择器标题|string|""|
6163
|touchToStop|是否通过长按停止滑动,传入数字 x 表示触摸超过 x 毫秒算长按,传 true 表示 x=100,长按事件与 click 事件互斥|number \| boolean|false|
64+
|renderExtraHeader|自定义头部扩展区域|() =\> ReactNode|-|
6265

6366
> 引用/Refs
6467

packages/arcodesign/components/date-picker/__ast__/index.ast.json

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
},
2626
"required": false,
2727
"type": {
28-
"name": "(timestamp: number, obj: IDateObj) => void"
28+
"name": "(timestamp: number | [number, number], obj: IDateObj | [IDateObj, IDateObj]) => void"
2929
}
3030
},
3131
"currentTs": {
@@ -45,7 +45,7 @@
4545
},
4646
"required": false,
4747
"type": {
48-
"name": "number"
48+
"name": "number | [number, number]"
4949
}
5050
},
5151
"onChange": {
@@ -62,7 +62,7 @@
6262
},
6363
"required": false,
6464
"type": {
65-
"name": "(timestamp: number, obj: IDateObj) => void"
65+
"name": "(timestamp: number | [number, number], obj: IDateObj | [IDateObj, IDateObj]) => void"
6666
}
6767
},
6868
"onValueChange": {
@@ -152,7 +152,7 @@
152152
},
153153
"required": false,
154154
"type": {
155-
"name": "number"
155+
"name": "number | { startTs: number; endTs: number; }"
156156
}
157157
},
158158
"maxTs": {
@@ -173,7 +173,7 @@
173173
},
174174
"required": false,
175175
"type": {
176-
"name": "number"
176+
"name": "number | { startTs: number; endTs: number; }"
177177
}
178178
},
179179
"useUTC": {
@@ -196,6 +196,23 @@
196196
"name": "boolean"
197197
}
198198
},
199+
"rangeItemFormat": {
200+
"defaultValue": null,
201+
"description": "日期时间范围选择展示格式\n@en Time range picker display format",
202+
"name": "rangeItemFormat",
203+
"tags": {
204+
"en": "Time range picker display format"
205+
},
206+
"descWithTags": "日期时间范围选择展示格式",
207+
"parent": {
208+
"fileName": "arcom-github/packages/arcodesign/components/date-picker/type.ts",
209+
"name": "DatePickerProps"
210+
},
211+
"required": false,
212+
"type": {
213+
"name": "string"
214+
}
215+
},
199216
"formatter": {
200217
"defaultValue": {
201218
"value": "(value: number) => (value < 10 ? \\`0${value}\\` : String(value))"
@@ -253,6 +270,23 @@
253270
"name": "(columns: PickerData[][], currentDateObj: IDateObj) => PickerData[][]"
254271
}
255272
},
273+
"renderSeparator": {
274+
"defaultValue": null,
275+
"description": "自定义分隔符\n@en Defined separator area",
276+
"name": "renderSeparator",
277+
"tags": {
278+
"en": "Defined separator area"
279+
},
280+
"descWithTags": "自定义分隔符",
281+
"parent": {
282+
"fileName": "arcom-github/packages/arcodesign/components/date-picker/type.ts",
283+
"name": "DatePickerProps"
284+
},
285+
"required": false,
286+
"type": {
287+
"name": "() => ReactNode"
288+
}
289+
},
256290
"renderLinkedContainer": {
257291
"defaultValue": null,
258292
"description": "将选择器的展现隐藏状态及选中值的展示与某个容器关联,传入后将同时渲染该容器和选择器组件,此时选择器组件的 visible 和 onHide 属性可不传,点击该容器会唤起选择器\n@en Associate the hidden state of the picker and the display of the selected value with a container. After passing it in, the container and the picker component will be rendered at the same time. At this time, the visible and onHide attributes of the picker component are optional values. Clicking the container will evoke the picker",
@@ -267,7 +301,7 @@
267301
},
268302
"required": false,
269303
"type": {
270-
"name": "(currentTs: number, itemTypes: ItemType[]) => ReactNode"
304+
"name": "(currentTs: number | [number, number], itemTypes: ItemType[]) => ReactNode"
271305
}
272306
},
273307
"visible": {
@@ -952,6 +986,23 @@
952986
"name": "number | boolean"
953987
}
954988
},
989+
"renderExtraHeader": {
990+
"defaultValue": null,
991+
"description": "自定义头部扩展区域\n@en Define the area of extra header",
992+
"name": "renderExtraHeader",
993+
"tags": {
994+
"en": "Define the area of extra header"
995+
},
996+
"descWithTags": "自定义头部扩展区域",
997+
"parent": {
998+
"fileName": "arcom-github/packages/arcodesign/components/picker/type.ts",
999+
"name": "PickerProps"
1000+
},
1001+
"required": false,
1002+
"type": {
1003+
"name": "() => ReactNode"
1004+
}
1005+
},
9551006
"ref": {
9561007
"defaultValue": null,
9571008
"description": "",

packages/arcodesign/components/date-picker/__test__/__snapshots__/index.spec.js.snap

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,89 @@ exports[`date-picker demo test date-picker demo: index.md renders correctly 1`]
166166
</DocumentFragment>
167167
`;
168168

169+
exports[`date-picker demo test date-picker demo: range.md renders correctly 1`] = `
170+
<DocumentFragment>
171+
<div
172+
class="arco-cell-group all-border-box"
173+
>
174+
<div
175+
class="cell-group-body"
176+
>
177+
<div
178+
class="arco-cell all-border-box bordered"
179+
>
180+
<div
181+
class="arco-cell-inner"
182+
>
183+
<div
184+
class="cell-label"
185+
>
186+
<div
187+
class="cell-title"
188+
>
189+
Select time range
190+
</div>
191+
</div>
192+
<div
193+
class="cell-content has-label"
194+
/>
195+
<div
196+
class="cell-arrow-icon"
197+
>
198+
<svg
199+
class="arrow-icon-svg"
200+
fill="none"
201+
viewBox="0 0 8 14"
202+
>
203+
<path
204+
clip-rule="evenodd"
205+
d="M0.594858 1.24219C0.399596 1.43745 0.399596 1.75403 0.594859 1.94929L5.59905 6.95348L0.636039 11.9165C0.440776 12.1118 0.440776 12.4283 0.636038 12.6236L0.989592 12.9771C1.18485 13.1724 1.50144 13.1724 1.6967 12.9771L7.35355 7.3203C7.5296 7.14425 7.54692 6.86959 7.40553 6.67413C7.38216 6.62774 7.35111 6.58423 7.31237 6.54549L1.65552 0.888634C1.46026 0.693372 1.14367 0.693372 0.948411 0.888634L0.594858 1.24219Z"
206+
fill-rule="evenodd"
207+
/>
208+
</svg>
209+
</div>
210+
</div>
211+
</div>
212+
<div
213+
class="arco-cell all-border-box bordered"
214+
>
215+
<div
216+
class="arco-cell-inner"
217+
>
218+
<div
219+
class="cell-label"
220+
>
221+
<div
222+
class="cell-title"
223+
>
224+
Select date range
225+
</div>
226+
</div>
227+
<div
228+
class="cell-content has-label"
229+
/>
230+
<div
231+
class="cell-arrow-icon"
232+
>
233+
<svg
234+
class="arrow-icon-svg"
235+
fill="none"
236+
viewBox="0 0 8 14"
237+
>
238+
<path
239+
clip-rule="evenodd"
240+
d="M0.594858 1.24219C0.399596 1.43745 0.399596 1.75403 0.594859 1.94929L5.59905 6.95348L0.636039 11.9165C0.440776 12.1118 0.440776 12.4283 0.636038 12.6236L0.989592 12.9771C1.18485 13.1724 1.50144 13.1724 1.6967 12.9771L7.35355 7.3203C7.5296 7.14425 7.54692 6.86959 7.40553 6.67413C7.38216 6.62774 7.35111 6.58423 7.31237 6.54549L1.65552 0.888634C1.46026 0.693372 1.14367 0.693372 0.948411 0.888634L0.594858 1.24219Z"
241+
fill-rule="evenodd"
242+
/>
243+
</svg>
244+
</div>
245+
</div>
246+
</div>
247+
</div>
248+
</div>
249+
</DocumentFragment>
250+
`;
251+
169252
exports[`date-picker demo test date-picker demo: time.md renders correctly 1`] = `
170253
<DocumentFragment>
171254
<div

packages/arcodesign/components/date-picker/__test__/index.spec.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { defaultContext } from '../../context-provider';
88
import '@testing-library/jest-dom';
99

1010
const prefix = `${defaultContext.prefixCls}-picker`;
11+
const datePrefix = `${defaultContext.prefixCls}-date-picker`;
1112

1213
demoTest('date-picker');
1314

@@ -26,7 +27,7 @@ describe('DatePicker', () => {
2627
const mockFn = jest.fn();
2728
const { rerender } = render(
2829
<DatePicker
29-
visible={true}
30+
visible
3031
maskClosable
3132
disabled={false}
3233
currentTs={new Date('2020-02-29 00:00:00'.replace(/-/g, '/')).getTime()}
@@ -36,7 +37,7 @@ describe('DatePicker', () => {
3637
);
3738
rerender(
3839
<DatePicker
39-
visible={true}
40+
visible
4041
maskClosable
4142
disabled={false}
4243
currentTs={new Date('2020-03-29 00:00:00'.replace(/-/g, '/')).getTime()}
@@ -55,7 +56,7 @@ describe('DatePicker', () => {
5556
it('Time constraints render correctly', () => {
5657
const { rerender } = render(
5758
<DatePicker
58-
visible={true}
59+
visible
5960
maskClosable
6061
disabled={false}
6162
minTs={new Date('2022-02-29 00:00:00'.replace(/-/g, '/')).getTime()}
@@ -66,7 +67,7 @@ describe('DatePicker', () => {
6667

6768
rerender(
6869
<DatePicker
69-
visible={true}
70+
visible
7071
maskClosable
7172
disabled={false}
7273
maxTs={new Date('2022-02-29 00:00:00'.replace(/-/g, '/')).getTime()}
@@ -78,7 +79,7 @@ describe('DatePicker', () => {
7879
it('Option filtering renders correctly', () => {
7980
render(
8081
<DatePicker
81-
visible={true}
82+
visible
8283
maskClosable
8384
disabled={false}
8485
typeArr={['hour', 'minute', 'second']}
@@ -95,4 +96,18 @@ describe('DatePicker', () => {
9596
'000102030405060708091011121314151617181920212223000102030405060708091011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859000510152025303540455055',
9697
);
9798
});
99+
it('Date range render correctly', () => {
100+
render(
101+
<DatePicker
102+
visible
103+
maskClosable
104+
disabled={false}
105+
currentTs={[
106+
new Date('2020-02-29 00:00:00'.replace(/-/g, '/')).getTime(),
107+
new Date('2020-02-29 00:00:00'.replace(/-/g, '/')).getTime(),
108+
]}
109+
/>,
110+
);
111+
expect(document.querySelectorAll(`.${datePrefix}-show`).length).toBe(1);
112+
});
98113
});

0 commit comments

Comments
 (0)