Skip to content

Commit

Permalink
chore: mv
Browse files Browse the repository at this point in the history
  • Loading branch information
zombieJ committed Oct 19, 2023
1 parent 969837b commit 99c997f
Show file tree
Hide file tree
Showing 41 changed files with 6,643 additions and 391 deletions.
3 changes: 2 additions & 1 deletion config/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export const components = {
experimental: [
'/guide/what-is-experimental',
'/components/calendar',
'/components/calendar-view',
'/components/calendar-picker',
'/components/calendar-picker-view',
'/components/dropdown',
'/components/floating-bubble',
'/components/image-uploader',
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
79 changes: 79 additions & 0 deletions src/components/calendar-picker/calendar.en.md
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,
}))
```
123 changes: 123 additions & 0 deletions src/components/calendar-picker/calendar.tsx
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>
)
})
79 changes: 79 additions & 0 deletions src/components/calendar-picker/calendar.zh.md
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,
}))
```
73 changes: 73 additions & 0 deletions src/components/calendar-picker/demos/demo1.tsx
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>
)
}
Loading

0 comments on commit 99c997f

Please sign in to comment.