feat: DatePicker support presets (#38249)

* chore: basic style

* chore: all of token spread

* chore: default presets style

* docs: update presets

* chore: fix style

* chore: fix ts

* test: Update snapshot

* test: Update snapshot

* test: Update snapshot

* test: update snapshot

* chore: bump bundle size

* test: update snapshot

* chore: update picker style

* chore: rm useless content
This commit is contained in:
二货爱吃白萝卜 2022-10-28 16:44:19 +08:00 committed by GitHub
parent 87b1a32aca
commit 752d671acb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 313310 additions and 310975 deletions

View File

@ -1,7 +1,7 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import { resetComponent } from '../../style';
import { resetComponent, textEllipsis } from '../../style';
export interface ComponentToken {}
@ -75,13 +75,11 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
paddingInline: `${token.anchorPaddingInline}px 0`,
'&-title': {
...textEllipsis,
position: 'relative',
display: 'block',
marginBlockEnd: token.anchorTitleBlock,
overflow: 'hidden',
color: token.colorText,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
transition: `all ${token.motionDurationSlow}`,
'&:only-child': {

View File

@ -2,7 +2,7 @@ import type { CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import { clearFix, resetComponent } from '../../style';
import { clearFix, resetComponent, textEllipsis } from '../../style';
export interface ComponentToken {}
@ -55,9 +55,7 @@ const genCardHeadStyle: GenerateStyle<CardToken> = (token): CSSObject => {
display: 'inline-block',
flex: 1,
padding: `${cardHeadPadding}px 0`,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
...textEllipsis,
[`
> ${componentCls}-typography,
@ -183,12 +181,10 @@ const genCardMetaStyle: GenerateStyle<CardToken> = (token): CSSObject => ({
},
'&-title': {
overflow: 'hidden',
color: token.colorTextHeading,
fontWeight: token.fontWeightStrong,
fontSize: token.fontSizeLG,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
...textEllipsis,
},
'&-description': {

View File

@ -1,6 +1,7 @@
import { getStyle as getCheckboxStyle } from '../../checkbox/style';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook } from '../../theme';
import { textEllipsis } from '../../style';
import { genCompactItemStyle } from '../../style/compact-item';
export interface ComponentToken {
@ -91,14 +92,12 @@ const genBaseStyle: GenerateStyle<CascaderToken> = token => {
},
'&-item': {
...textEllipsis,
display: 'flex',
flexWrap: 'nowrap',
alignItems: 'center',
padding: `${itemPaddingVertical}px ${token.paddingSM}px`,
overflow: 'hidden',
lineHeight: token.lineHeight,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
cursor: 'pointer',
transition: `all ${token.motionDurationFast}`,
borderRadius: token.radiusSM,

View File

@ -1,7 +0,0 @@
import * as React from 'react';
import type { TagProps } from '../tag';
import Tag from '../tag';
export default function PickerTag(props: TagProps) {
return <Tag color="blue" {...props} />;
}

View File

@ -2563,6 +2563,50 @@ exports[`renders ./components/date-picker/demo/presetted-ranges.md correctly 1`]
<div
class="ant-space ant-space-vertical"
>
<div
class="ant-space-item"
style="margin-bottom:12px"
>
<div
class="ant-picker"
>
<div
class="ant-picker-input"
>
<input
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
class="ant-picker-suffix"
>
<span
aria-label="calendar"
class="anticon anticon-calendar"
role="img"
>
<svg
aria-hidden="true"
data-icon="calendar"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
/>
</svg>
</span>
</span>
</div>
</div>
</div>
<div
class="ant-space-item"
style="margin-bottom:12px"

View File

@ -14,14 +14,21 @@ title:
We can set preset ranges to RangePicker to improve user experience.
```tsx
import { DatePicker, Space } from 'antd';
import type { RangePickerProps } from 'antd/es/date-picker';
import dayjs from 'dayjs';
import React from 'react';
import { DatePicker, Space } from 'antd';
import dayjs from 'dayjs';
import type { Dayjs } from 'dayjs';
const { RangePicker } = DatePicker;
const onChange: RangePickerProps['onChange'] = (dates, dateStrings) => {
const onChange = (date: Dayjs) => {
if (date) {
console.log('Date: ', date);
} else {
console.log('Clear');
}
};
const onRangeChange = (dates: null | (Dayjs | null)[], dateStrings: string[]) => {
if (dates) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
@ -30,23 +37,32 @@ const onChange: RangePickerProps['onChange'] = (dates, dateStrings) => {
}
};
const rangePresets: {
label: string;
value: [Dayjs, Dayjs];
}[] = [
{ label: 'Last 7 Days', value: [dayjs().add(-7, 'd'), dayjs()] },
{ label: 'Last 14 Days', value: [dayjs().add(-14, 'd'), dayjs()] },
{ label: 'Last 30 Days', value: [dayjs().add(-30, 'd'), dayjs()] },
{ label: 'Last 90 Days', value: [dayjs().add(-90, 'd'), dayjs()] },
];
const App: React.FC = () => (
<Space direction="vertical" size={12}>
<RangePicker
ranges={{
Today: [dayjs(), dayjs()],
'This Month': [dayjs().startOf('month'), dayjs().endOf('month')],
}}
<DatePicker
presets={[
{ label: 'Yesterday', value: dayjs().add(-1, 'd') },
{ label: 'Last Week', value: dayjs().add(-7, 'd') },
{ label: 'Last Month', value: dayjs().add(-1, 'month') },
]}
onChange={onChange}
/>
<RangePicker presets={rangePresets} onChange={onRangeChange} />
<RangePicker
ranges={{
Today: [dayjs(), dayjs()],
'This Month': [dayjs().startOf('month'), dayjs().endOf('month')],
}}
presets={rangePresets}
showTime
format="YYYY/MM/DD HH:mm:ss"
onChange={onChange}
onChange={onRangeChange}
/>
</Space>
);

View File

@ -16,11 +16,10 @@ import type { TimePickerLocale } from '../../time-picker';
import type { InputStatus } from '../../_util/statusUtils';
import { tuple } from '../../_util/type';
import PickerButton from '../PickerButton';
import PickerTag from '../PickerTag';
import generateRangePicker from './generateRangePicker';
import generateSinglePicker from './generateSinglePicker';
export const Components = { button: PickerButton, rangeItem: PickerTag };
export const Components = { button: PickerButton };
function toArray<T>(list: T | T[]): T[] {
if (!list) {

View File

@ -71,6 +71,7 @@ The following APIs are shared by DatePicker, RangePicker.
| placeholder | The placeholder of date input | string \| \[string,string] | - | |
| placement | The position where the selection box pops up | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | |
| popupStyle | To customize the style of the popup calendar | CSSProperties | {} | |
| presets | The preset ranges for quick selection | { label: React.ReactNode, value: [dayjs](https://day.js.org/) }[] | - | |
| prevIcon | The custom prev icon | ReactNode | - | 4.17.0 |
| size | To determine the size of the input box, the height of `large` and `small`, are 40px and 24px respectively, while default size is 32px | `large` \| `middle` \| `small` | - | |
| status | Set validation status | 'error' \| 'warning' | - | 4.19.0 |
@ -164,7 +165,7 @@ Added in `4.1.0`.
| disabled | If disable start or end | \[boolean, boolean] | - | |
| disabledTime | To specify the time that cannot be selected | function(date: dayjs, partial: `start` \| `end`) | - | |
| format | To set the date format, refer to [dayjs](https://day.js.org/). When an array is provided, all values are used for parsing and first value is used for formatting | string \| string\[] | `YYYY-MM-DD HH:mm:ss` | |
| ranges | The preseted ranges for quick selection | { \[range: string]: [dayjs](https://day.js.org/)\[] } \| { \[range: string]: () => [dayjs](https://day.js.org/)\[] } | - | |
| presets | The preset ranges for quick selection | { label: React.ReactNode, value: [dayjs](https://day.js.org/)\[] }[] | - | |
| renderExtraFooter | Render extra footer in panel | () => React.ReactNode | - | |
| separator | Set separator between inputs | React.ReactNode | `<SwapRightOutlined />` | |
| showTime | To provide an additional time selection | object \| boolean | [TimePicker Options](/components/time-picker/#API) | |

View File

@ -73,6 +73,7 @@ import locale from 'antd/locale/zh_CN';
| placement | 选择框弹出的位置 | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | |
| popupStyle | 额外的弹出日历样式 | CSSProperties | {} | |
| prevIcon | 自定义上一个图标 | ReactNode | - | 4.17.0 |
| presets | 预设时间范围快捷选择 | { label: React.ReactNode, value: [dayjs](https://day.js.org/) }[] | - | |
| size | 输入框大小,`large` 高度为 40px`small` 为 24px默认是 32px | `large` \| `middle` \| `small` | - | |
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
| style | 自定义输入框样式 | CSSProperties | {} | |
@ -165,7 +166,7 @@ import locale from 'antd/locale/zh_CN';
| disabled | 禁用起始项 | \[boolean, boolean] | - | |
| disabledTime | 不可选择的时间 | function(date: dayjs, partial: `start` \| `end`) | - | |
| format | 展示的日期格式 | string | `YYYY-MM-DD HH:mm:ss` | |
| ranges | 预设时间范围快捷选择 | { \[range: string]: [dayjs](https://day.js.org/)\[] } \| { \[range: string]: () => [dayjs](https://day.js.org/)\[] } | - | |
| presets | 预设时间范围快捷选择 | { label: React.ReactNode, value: [dayjs](https://day.js.org/)\[] }[] | - | |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | |
| separator | 设置分隔符 | React.ReactNode | `<SwapRightOutlined />` | |
| showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker/#API) | |

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import { resetComponent } from '../../style';
import { resetComponent, textEllipsis } from '../../style';
interface DescriptionsToken extends FullToken<'Descriptions'> {
descriptionsTitleMarginBottom: number;
@ -87,14 +87,12 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: Descripti
marginBottom: descriptionsTitleMarginBottom,
},
[`${componentCls}-title`]: {
...textEllipsis,
flex: 'auto',
overflow: 'hidden',
color: token.colorText,
fontWeight: token.fontWeightStrong,
fontSize: token.fontSizeLG,
lineHeight: token.lineHeightLG,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
},
[`${componentCls}-extra`]: {
marginInlineStart: 'auto',

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ import { genModalMaskStyle } from '../../modal/style';
import { initZoomMotion } from '../../style/motion';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import { resetComponent } from '../../style';
import { resetComponent, textEllipsis } from '../../style';
export interface ComponentToken {
zIndexPopup: number;
@ -41,10 +41,8 @@ export const genImageMaskStyle = (token: ImageToken): CSSObject => {
transition: `opacity ${motionDurationSlow}`,
[`.${prefixCls}-mask-info`]: {
...textEllipsis,
padding: `0 ${paddingXXS}px`,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
[iconCls]: {
marginInlineEnd: marginXXS,
},

View File

@ -9,7 +9,7 @@ import {
} from '../../input/style';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook } from '../../theme';
import { resetComponent } from '../../style';
import { resetComponent, textEllipsis } from '../../style';
export interface ComponentToken {
zIndexPopup: number;
@ -161,16 +161,14 @@ const genMentionsStyle: GenerateStyle<MentionsToken> = token => {
outline: 'none',
'&-item': {
...textEllipsis,
position: 'relative',
display: 'block',
minWidth: token.controlItemWidth,
padding: `${itemPaddingVertical}px ${controlPaddingHorizontal}px`,
overflow: 'hidden',
color: colorText,
fontWeight: 'normal',
lineHeight,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
cursor: 'pointer',
transition: `background ${motionDurationSlow} ease`,

View File

@ -1,4 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import { textEllipsis } from '../../style';
import type { MenuToken } from '.';
import type { GenerateStyle } from '../../theme';
@ -217,10 +218,8 @@ const getVerticalStyle: GenerateStyle<MenuToken> = token => {
},
[`${componentCls}-item-group-title`]: {
...textEllipsis,
paddingInline: paddingXS,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
},
},
},

View File

@ -1,7 +1,7 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import { resetComponent } from '../../style';
import { resetComponent, textEllipsis } from '../../style';
export interface ComponentToken {}
@ -36,9 +36,7 @@ function getSegmentedItemSelectedStyle(token: SegmentedToken): CSSObject {
const segmentedTextEllipsisCss: CSSObject = {
overflow: 'hidden',
// handle text ellipsis
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
wordBreak: 'keep-all',
...textEllipsis,
};
// ============================== Styles ==============================

View File

@ -9,7 +9,7 @@ import {
slideUpOut,
} from '../../style/motion';
import type { GenerateStyle } from '../../theme';
import { resetComponent } from '../../style';
import { resetComponent, textEllipsis } from '../../style';
const genItemStyle: GenerateStyle<SelectToken, CSSObject> = token => {
const { controlPaddingHorizontal } = token;
@ -111,9 +111,7 @@ const genSingleStyle: GenerateStyle<SelectToken> = token => {
'&-content': {
flex: 'auto',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
...textEllipsis,
},
'&-state': {

View File

@ -4,7 +4,7 @@ import { genComponentStyleHook, mergeToken } from '../../theme';
import genDropdownStyle from './dropdown';
import genMultipleStyle from './multiple';
import genSingleStyle from './single';
import { resetComponent, resetIcon } from '../../style';
import { resetComponent, resetIcon, textEllipsis } from '../../style';
import { genCompactItemStyle } from '../../style/compact-item';
export interface ComponentToken {
@ -144,19 +144,15 @@ const genBaseStyle: GenerateStyle<SelectToken> = token => {
// ======================== Selection ========================
[`${componentCls}-selection-item`]: {
flex: 1,
overflow: 'hidden',
fontWeight: 'normal',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
...textEllipsis,
},
// ======================= Placeholder =======================
[`${componentCls}-selection-placeholder`]: {
...textEllipsis,
flex: 1,
overflow: 'hidden',
color: token.colorTextPlaceholder,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
pointerEvents: 'none',
},

View File

@ -1,4 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import { textEllipsis } from '../../style';
import type { StepsToken } from '.';
import type { GenerateStyle } from '../../theme';
@ -42,9 +43,7 @@ const genStepsNavStyle: GenerateStyle<StepsToken, CSSObject> = token => {
[`${componentCls}-item-title`]: {
maxWidth: '100%',
paddingInlineEnd: 0,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
...textEllipsis,
'&::after': {
display: 'none',

View File

@ -5,6 +5,12 @@ import type { DerivativeToken } from '../theme';
export { operationUnit } from './operationUnit';
export { roundedArrow } from './roundedArrow';
export const textEllipsis: CSSObject = {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
};
export const resetComponent = (token: DerivativeToken): CSSObject => ({
boxSizing: 'border-box',
margin: 0,

View File

@ -1,4 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import { textEllipsis } from '../../style';
import type { GenerateStyle } from '../../theme';
import type { TableToken } from './index';
@ -7,9 +8,7 @@ const genEllipsisStyle: GenerateStyle<TableToken, CSSObject> = token => {
return {
[`${componentCls}-wrapper`]: {
[`${componentCls}-cell-ellipsis`]: {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
...textEllipsis,
wordBreak: 'keep-all',
// Fixed first or last should special process

View File

@ -1,7 +1,7 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import { genFocusStyle, resetComponent } from '../../style';
import { genFocusStyle, resetComponent, textEllipsis } from '../../style';
import genMotionStyle from './motion';
export interface ComponentToken {
@ -173,18 +173,16 @@ const genDropdownStyle: GenerateStyle<TabsToken> = (token: TabsToken): CSSObject
boxShadow: token.boxShadow,
'&-item': {
...textEllipsis,
display: 'flex',
alignItems: 'center',
minWidth: token.tabsDropdownWidth,
margin: 0,
padding: `${token.paddingXXS}px ${token.paddingSM}px`,
overflow: 'hidden',
color: token.colorText,
fontWeight: 'normal',
fontSize: token.fontSize,
lineHeight: token.lineHeight,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
cursor: 'pointer',
transition: `all ${token.motionDurationSlow}`,

View File

@ -2,7 +2,7 @@ import type { CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import { resetComponent, resetIcon } from '../../style';
import { resetComponent, resetIcon, textEllipsis } from '../../style';
export interface ComponentToken {
listWidth: number;
@ -149,11 +149,9 @@ const genTransferListStyle: GenerateStyle<TransferToken> = (token: TransferToken
},
'&-title': {
...textEllipsis,
flex: 'auto',
overflow: 'hidden',
whiteSpace: 'nowrap',
textAlign: 'end',
textOverflow: 'ellipsis',
},
'&-dropdown': {
@ -206,10 +204,8 @@ const genTransferListStyle: GenerateStyle<TransferToken> = (token: TransferToken
},
'&-text': {
...textEllipsis,
flex: 'auto',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
},
'&-remove': {

View File

@ -1,6 +1,6 @@
import type { UploadToken } from '.';
import type { GenerateStyle } from '../../theme';
import { clearFix } from '../../style';
import { clearFix, textEllipsis } from '../../style';
const genListStyle: GenerateStyle<UploadToken> = token => {
const { componentCls, antCls, iconCls, fontSizeBase, lineHeight } = token;
@ -29,11 +29,9 @@ const genListStyle: GenerateStyle<UploadToken> = token => {
},
[`${itemCls}-name`]: {
...textEllipsis,
padding: `0 ${token.paddingXS}px`,
overflow: 'hidden',
lineHeight,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
flex: 'auto',
transition: `all ${token.motionDurationSlow}`,
},

View File

@ -1,7 +1,7 @@
import { TinyColor } from '@ctrl/tinycolor';
import type { UploadToken } from '.';
import type { GenerateStyle } from '../../theme';
import { clearFix } from '../../style';
import { clearFix, textEllipsis } from '../../style';
const genPictureStyle: GenerateStyle<UploadToken> = token => {
const { componentCls, iconCls, uploadThumbnailSize, uploadProgressOffset } = token;
@ -24,14 +24,12 @@ const genPictureStyle: GenerateStyle<UploadToken> = token => {
},
[`${itemCls}-thumbnail`]: {
...textEllipsis,
width: uploadThumbnailSize,
height: uploadThumbnailSize,
lineHeight: `${uploadThumbnailSize + token.paddingSM}px`,
textAlign: 'center',
flex: 'none',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
[iconCls]: {
fontSize: token.fontSizeHeading2,

View File

@ -134,7 +134,7 @@
"rc-motion": "^2.6.1",
"rc-notification": "~5.0.0-alpha.9",
"rc-pagination": "~3.1.17",
"rc-picker": "~2.6.11",
"rc-picker": "~3.0.0-4",
"rc-progress": "~3.3.2",
"rc-rate": "~2.9.0",
"rc-resize-observer": "^1.2.0",
@ -308,13 +308,13 @@
"size-limit": [
{
"path": "./dist/antd.min.js",
"limit": "373.5 kB"
"limit": "375 kB"
}
],
"bundlesize": [
{
"path": "./dist/antd.min.js",
"maxSize": "374.5 kB"
"maxSize": "375 kB"
}
],
"tnpm": {