-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
41 changed files
with
6,643 additions
and
391 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Calendar <Experimental></Experimental> | ||
|
||
Used to select a date or date range. | ||
|
||
## When to Use | ||
|
||
When the user needs to enter a date, he can select it in the pop-up date panel. | ||
|
||
## Demos | ||
|
||
<code src="./demos/demo1.tsx"></code> | ||
|
||
<code src="./demos/demo2.tsx"></code> | ||
|
||
<code src="./demos/demo3.tsx"></code> | ||
|
||
<code src="./demos/demo4.tsx"></code> | ||
|
||
## Calendar | ||
|
||
### Props | ||
|
||
| Name | Description | Type | Default | Version | | ||
| --- | --- | --- | --- | --- | | ||
| visible | To show or hide the Cclendar | `boolean` | `true` | | ||
| confirmText | The text of confirm button | `string` | `Confirm` | | ||
| popupClassName | The custom class name of the popup | `string` | - | | ||
| popupStyle | The custom style of the popup | `React.CSSProperties` | - | | ||
| popupBodyStyle | The custom style of the popup body | `React.CSSProperties` | - | | ||
| forceRender | Render content forcely,When ref is passed,always be true | `boolean` | `false` | | ||
| closeOnMaskClick | Whether to close after clicking the mask layer | `boolean` | `true` | | ||
| onClose | Triggered when closed | `() => void` | - | | ||
| onMaskClick | Triggered when the mask is clicked | `() => void` | - | | ||
| allowClear | Whether to allow clearing after another click. | `boolean` | `true` | | ||
| defaultValue | The default selected date or date range. | Same as `value` prop. | - | | ||
| max | Maximum value of a selectable range. | `Date` | - | | ||
| min | Minimum value of a selectable range. | `Date` | - | - | | ||
| onChange | Trigger when selected date changes. | `(val: Date \| null) => void` when selection mode is "single". `(val: [Date, Date] \| null) => void` when selection mode is "range". | - | | ||
| onConfirm | Trigger when confirm button is clicked. | `(val: Date \| null) => void` when selection mode is "single",`(val: [Date, Date] \| null) => void` when selection mode is "range" | - | | ||
| renderTop | The top information of date render function. | `(date: Date) => ReactNode \| null \| undefined` | - | | ||
| renderBottom | The bottom information of date render function. | `(date: Date) => ReactNode \| null \| undefined` | - | | ||
| selectionMode | The selection mode. Disable selection when this prop is not set. | `'single' \| 'range'` | - | | ||
| shouldDisableDate | Set whether the date is disable selection. The min and max Settings are ignored | `(date: Date) => boolean` | - | | ||
| title | The title of calendar | `React.ReactNode` | `Date selection` | | ||
| value | The selected date or date range. | `Date \| null` when selection mode is "single". `[Date, Date] \| null` when selection mode is "range" | - | | ||
| weekStartsOn | Week starts on which day. | `'Monday' \| 'Sunday'` | `'Sunday'` | | ||
| renderDate | Custom date rendering. | `(date: Date) => ReactNode` | - | 5.28.0 | | ||
|
||
### CSS Variables | ||
|
||
Not supported yet. | ||
|
||
### Ref | ||
|
||
| Name | Description | Type | | ||
| --- | --- | --- | | ||
| jumpTo | Jump to specified page | `(page: Page \| ((page: Page) => Page)) => void` | | ||
| jumpToToday | Jump to today's page | `() => void` | | ||
| getDateRange | get date | `[Date, Date]` | | ||
|
||
```ts | ||
type Page = { month: number; year: number } | ||
``` | ||
You can manually control the page turning of the calendar through Ref, for example: | ||
```ts | ||
// Jump to today's page | ||
ref.current.jumpToToday() | ||
|
||
// Jump to the specified year and month | ||
ref.current.jumpTo({ year: 2021, month: 1 }) | ||
|
||
// Jump to three years later | ||
ref.current.jumpTo(page => ({ | ||
year: page.year + 3, | ||
month: page.month, | ||
})) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import React, { forwardRef, useRef } from 'react' | ||
import { withNativeProps } from '../../utils/native-props' | ||
import classNames from 'classnames' | ||
import Button from '../button' | ||
import Divider from '../divider' | ||
import Popup from '../popup' | ||
import { mergeProps } from '../../utils/with-default-props' | ||
import { useConfig } from '../config-provider' | ||
import CalendarView, { | ||
CalendarViewProps, | ||
CalendarViewRef, | ||
} from '../calendar-picker-view' | ||
|
||
const classPrefix = 'adm-calendar' | ||
|
||
export type CalendarRef = CalendarViewRef | ||
|
||
export type CalendarProps = CalendarViewProps & { | ||
visible?: boolean | ||
confirmText?: string | ||
popupClassName?: string | ||
popupStyle?: React.CSSProperties | ||
popupBodyStyle?: React.CSSProperties | ||
forceRender?: true | ||
closeOnMaskClick?: boolean | ||
onClose?: () => void | ||
onMaskClick?: () => void | ||
} & ( | ||
| { | ||
selectionMode?: undefined | ||
onConfirm?: undefined | ||
} | ||
| { | ||
selectionMode: 'single' | ||
onConfirm?: (val: Date | null) => void | ||
} | ||
| { | ||
selectionMode: 'range' | ||
onConfirm?: (val: [Date, Date] | null) => void | ||
} | ||
) | ||
|
||
const defaultProps = { | ||
weekStartsOn: 'Sunday', | ||
defaultValue: null, | ||
allowClear: true, | ||
usePopup: true, | ||
selectionMode: 'single', | ||
} | ||
|
||
export const Calendar = forwardRef<CalendarRef, CalendarProps>((p, ref) => { | ||
const props = mergeProps(defaultProps, p) | ||
const { locale } = useConfig() | ||
const calendarRef = (ref ?? | ||
useRef<CalendarRef>(null)) as React.RefObject<CalendarRef> | ||
|
||
const { | ||
visible, | ||
confirmText, | ||
popupClassName, | ||
popupStyle, | ||
popupBodyStyle, | ||
forceRender, | ||
closeOnMaskClick, | ||
onClose, | ||
onConfirm, | ||
onMaskClick, | ||
...calendarViewProps | ||
} = props | ||
|
||
const footer = ( | ||
<div className={`${classPrefix}-footer`}> | ||
<Divider /> | ||
<div className={`${classPrefix}-footer-bottom`}> | ||
<Button | ||
color='primary' | ||
onClick={() => { | ||
const dateRange = calendarRef.current?.getDateRange() ?? null | ||
|
||
if (props.selectionMode === 'single') { | ||
props.onConfirm?.(dateRange ? dateRange[0] : null) | ||
} else if (props.selectionMode === 'range') { | ||
props.onConfirm?.(dateRange) | ||
} | ||
onClose?.() | ||
}} | ||
> | ||
{confirmText ?? locale.Calendar.confirm} | ||
</Button> | ||
</div> | ||
</div> | ||
) | ||
|
||
return withNativeProps( | ||
props, | ||
<div className={classPrefix}> | ||
<Popup | ||
visible={visible} | ||
className={classNames(`${classPrefix}-popup`, popupClassName)} | ||
showCloseButton | ||
forceRender={ref ? true : forceRender} | ||
style={popupStyle} | ||
bodyStyle={{ | ||
borderTopLeftRadius: '8px', | ||
borderTopRightRadius: '8px', | ||
minHeight: '80vh', | ||
overflow: 'auto', | ||
...popupBodyStyle, | ||
}} | ||
onClose={onClose} | ||
onMaskClick={() => { | ||
onMaskClick?.() | ||
if (closeOnMaskClick) { | ||
onClose?.() | ||
} | ||
}} | ||
> | ||
<CalendarView ref={calendarRef} {...calendarViewProps} /> | ||
{footer} | ||
</Popup> | ||
</div> | ||
) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Calendar 日历 <Experimental></Experimental> | ||
|
||
用于选择日期或日期区间。 | ||
|
||
## 何时使用 | ||
|
||
当用户需要输入一个日期,可以在弹出的日期面板进行选择。 | ||
|
||
## 示例 | ||
|
||
<code src="./demos/demo1.tsx"></code> | ||
|
||
<code src="./demos/demo2.tsx"></code> | ||
|
||
<code src="./demos/demo3.tsx"></code> | ||
|
||
<code src="./demos/demo4.tsx"></code> | ||
|
||
## Calendar | ||
|
||
### 属性 | ||
|
||
| 属性 | 说明 | 类型 | 默认值 | 版本 | | ||
| --- | --- | --- | --- | --- | | ||
| visible | 显示隐藏 | `boolean` | `true` | | ||
| confirmText | 确认按钮文案 | `string` | `确认` | | ||
| popupClassName | 弹出层类名 | `string` | - | | ||
| popupStyle | 弹层容器的自定义样式 | `React.CSSProperties` | - | | ||
| popupBodyStyle | 容器内部自定义样式 | `React.CSSProperties` | - | | ||
| forceRender | 强制渲染内容,当传递 ref 时,会强制设为 true | `boolean` | `false` | | ||
| closeOnMaskClick | 点击背景蒙层后是否关闭 | `boolean` | `true` | | ||
| onClose | 关闭时触发 | `() => void` | - | | ||
| onMaskClick | 点击背景蒙层时触发 | `() => void` | - | | ||
| allowClear | 是否允许再次点击后清除 | `boolean` | `true` | | ||
| defaultValue | 默认选择的日期 | 同 `value` 属性 | - | | ||
| max | 可选择范围的最大值 | `Date` | - | | ||
| min | 可选择范围的最小值 | `Date` | - | | ||
| onChange | 选择日期变化时触发 | 单选模式下为 `(val: Date \| null) => void`,多选模式下为 `(val: [Date, Date] \| null) => void` | - | | ||
| onConfirm | 点击确认按钮时触发 | 单选模式下为 `(val: Date \| null) => void`,多选模式下为 `(val: [Date, Date] \| null) => void` | - | | ||
| renderTop | 日期顶部信息的渲染函数 | `(date: Date) => ReactNode \| null \| undefined` | - | | ||
| renderBottom | 日期底部信息的渲染函数 | `(date: Date) => ReactNode \| null \| undefined` | - | | ||
| selectionMode | 选择模式,不设置的话表示不支持选择 | `'single' \| 'range'` | - | | ||
| shouldDisableDate | 判断日期是否可选,使用后会忽略 min 和 max 设置 | `(date: Date) => boolean` | - | | ||
| title | 日期选择器的标题 | `React.ReactNode` | `日期选择` | | ||
| value | 选择的日期 | 单选模式下为 `Date \| null`,多选模式下为 `[Date, Date] \| null` | - | | ||
| weekStartsOn | 每周以周几作为第一天 | `'Monday' \| 'Sunday'` | `'Sunday'` | | ||
| renderDate | 自定义日期渲染 | `(date: Date) => ReactNode` | - | 5.28.0 | | ||
|
||
### CSS 变量 | ||
|
||
暂无 | ||
|
||
### Ref | ||
|
||
| 属性 | 说明 | 类型 | | ||
| --- | --- | --- | | ||
| jumpTo | 跳转至指定日期的区间 | `(page: Page \| ((page: Page) => Page)) => void` | | ||
| jumpToToday | 跳转至今日 | `() => void` | | ||
| getDateRange | 获取日期 | `[Date, Date]` | | ||
|
||
```ts | ||
type Page = { month: number; year: number } | ||
``` | ||
你可以通过 Ref 手动控制日历的翻页,例如: | ||
```ts | ||
// 跳回当月 | ||
ref.current.jumpToToday() | ||
|
||
// 跳转至指定年月 | ||
ref.current.jumpTo({ year: 2021, month: 1 }) | ||
|
||
// 跳转到三年之后 | ||
ref.current.jumpTo(page => ({ | ||
year: page.year + 3, | ||
month: page.month, | ||
})) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import dayjs from 'dayjs' | ||
import React, { useState } from 'react' | ||
import { Calendar, List } from 'antd-mobile' | ||
|
||
const defaultRange: [Date, Date] = [ | ||
dayjs().toDate(), | ||
dayjs().add(2, 'day').toDate(), | ||
] | ||
|
||
export default () => { | ||
const [val, setVal] = useState<[Date, Date] | null>(() => [ | ||
dayjs().subtract(2, 'day').toDate(), | ||
dayjs().add(2, 'day').toDate(), | ||
]) | ||
const [visible1, setVisible1] = useState(false) | ||
const [visible2, setVisible2] = useState(false) | ||
const [visible3, setVisible3] = useState(false) | ||
|
||
const singleDate: Date = new Date('2023-06-03') | ||
|
||
return ( | ||
<List header='日期选择'> | ||
<List.Item | ||
onClick={() => { | ||
setVisible1(true) | ||
}} | ||
> | ||
选择单个日期 | ||
<Calendar | ||
visible={visible1} | ||
selectionMode='single' | ||
defaultValue={singleDate} | ||
onClose={() => setVisible1(false)} | ||
onMaskClick={() => setVisible1(false)} | ||
/> | ||
</List.Item> | ||
<List.Item | ||
onClick={() => { | ||
setVisible2(true) | ||
}} | ||
> | ||
选择日期范围 | ||
<Calendar | ||
visible={visible2} | ||
defaultValue={defaultRange} | ||
selectionMode='range' | ||
onClose={() => setVisible2(false)} | ||
onMaskClick={() => setVisible2(false)} | ||
onChange={val => { | ||
console.log(val) | ||
}} | ||
/> | ||
</List.Item> | ||
<List.Item | ||
onClick={() => { | ||
setVisible3(true) | ||
}} | ||
> | ||
受控日期选择 | ||
<Calendar | ||
visible={visible3} | ||
selectionMode='range' | ||
value={val} | ||
onClose={() => setVisible3(false)} | ||
onMaskClick={() => setVisible3(false)} | ||
onChange={val => { | ||
setVal(val) | ||
}} | ||
/> | ||
</List.Item> | ||
</List> | ||
) | ||
} |
Oops, something went wrong.