注:
- 这 3 个组件是渐进式组件,可查看 渐进式组件 了解。
Import
import {
TaCalendar,
TaCalendarPopup,
TaCalendarView
} from 'tantalum-ui-mobile-react'
具体的引入方式可以参考引入组件。
Import Type
组件导出的类型定义:
import type {
CalendarValueFormatter,
CalendarValueParser,
CalendarOnSelect,
CalendarOnConfirm,
CalendarDayHandler,
CalendarMode,
CalendarDetail,
SelectorOnChange,
SelectorModelValue,
VisibleState,
PopupOnVisibleStateChange,
PopupOnCancel
} from 'tantalum-ui-mobile-react'
公共 Props
Calendar 日历选择器
注:
import {
showToast,
showCalendar,
SelectorModelValue,
TaGroup,
TaCell,
TaCalendar,
SelectorDetail
} from '@/index'
import { formatter, parser } from './utils'
import dayjs from 'dayjs'
const minDate = dayjs().startOf('day').subtract(1, 'month').toDate()
const maxDate = dayjs().startOf('day').add(1, 'month').toDate()
const formatValue = (
formatter(
[dayjs().startOf('day').add(1, 'month').toDate()],
'single'
) as SelectorDetail
).value
const disableValue = dayjs().startOf('day').add(1, 'month').toDate()
export default function ExpCalendar() {
function onCallApi() {
showCalendar({
mode: 'range',
showClose: true,
success: res => {
console.log('success', res)
if (res.cancel) {
showToast('取消了')
} else {
showToast(`选择了 ${res.detail.label}`)
}
}
})
}
function onChange(res: SelectorModelValue) {
console.log('change', res)
showToast('change: ' + (res as any)[0])
}
return (
<>
<TaGroup title="initialMode=simple">
<TaCell label="默认">
<TaCalendar />
</TaCell>
<TaCell label="showConfirm=true">
<TaCalendar showConfirm />
</TaCell>
<TaCell label="showClose=true">
<TaCalendar showClose />
</TaCell>
<TaCell label="firstDayOfWeek=1">
<TaCalendar firstDayOfWeek="1" />
</TaCell>
<TaCell label="minDate/maxDate +-1month">
<TaCalendar minDate={minDate} maxDate={maxDate} />
</TaCell>
<TaCell label="formatter/parser">
<TaCalendar
formatter={formatter}
parser={parser}
value={formatValue}
/>
</TaCell>
<TaCell label="禁用">
<TaCalendar disabled value={disableValue} />
</TaCell>
</TaGroup>
<TaGroup title="initialMode=range">
<TaCell label="默认">
<TaCalendar initialMode="range" />
</TaCell>
<TaCell label="allowSameDay">
<TaCalendar initialMode="range" allowSameDay />
</TaCell>
<TaCell label="maxRange=5">
<TaCalendar initialMode="range" maxRange="5" />
</TaCell>
</TaGroup>
<TaGroup title="事件监听">
<TaCell label="change">
<TaCalendar onChange={onChange} />
</TaCell>
</TaGroup>
<TaGroup title="API">
<TaCell label="showCalendar" isLink onClick={() => onCallApi()} />
</TaGroup>
</>
)
}
Calendar Props
属性 | 类型 | 默认值 | 必填 | 说明 |
---|
name | string | | 否 | 标识 |
placeholder | string | | 否 | 没有选中值的提示,也会用在弹窗标题上 |
disabled | boolean | false | 否 | 是否禁用 |
showConfirm | boolean | false | 否 | 弹窗是否展示确定按钮 |
showClose | boolean | false | 否 | 弹窗是否展示关闭按钮 |
Calendar Events
import {
showToast,
SelectorModelValue,
PopupOnVisibleStateChange,
PopupOnCancel,
TaCell,
TaGroup,
TaNoticeBar,
TaCalendar,
CalendarOnConfirm
} from '@/index'
import dayjs from 'dayjs'
import { formatter, parser, template } from '../Calendar/utils'
import { useRef, useState } from 'react'
interface showArgs {
showConfirm?: boolean
showClose?: boolean
visibleEvent?: boolean
changeEvent?: boolean
clickEvent?: boolean
}
const title = 'CalendarPopup'
const defaultValue = dayjs().format(template)
export default function ExpCalendarPopup() {
const [popupValue, setPopupValue] = useState(defaultValue)
const [popupRangeValue, setPopupRangeValue] = useState<SelectorModelValue>([])
const [visible, setVisible] = useState(false)
const [rangeVisible, setRangeVisible] = useState(false)
const [showConfirm, setShowConfirm] = useState(false)
const [showClose, setShowClose] = useState(false)
const clickEvent = useRef(false)
const changeEvent = useRef(false)
const visibleEvent = useRef(false)
function addOneDay() {
setPopupValue(
dayjs(popupValue, template, true).add(1, 'day').format(template)
)
}
function onShow(args: showArgs = {}) {
setShowConfirm(!!args.showConfirm)
setShowClose(!!args.showClose)
visibleEvent.current = !!args.visibleEvent
changeEvent.current = !!args.changeEvent
clickEvent.current = !!args.clickEvent
setVisible(true)
}
const onVisibleStateChange: PopupOnVisibleStateChange = res => {
if (visibleEvent.current) {
console.log('onVisibleStateChange', res)
showToast(`${res.state} 事件触发`)
}
}
const onConfirm: CalendarOnConfirm = res => {
if (clickEvent.current) {
console.log('onConfirm', res)
showToast(`点击确定按钮`)
}
}
const onCancel: PopupOnCancel = res => {
if (clickEvent.current) {
console.log('onCancel', res)
if (res.source === 'cancelClick') {
showToast('点击了取消按钮')
} else if (res.source === 'maskClick') {
showToast('点击了蒙层')
}
}
}
function onChange(res: SelectorModelValue) {
console.log('onChange', res)
if (changeEvent.current) {
showToast(`值改为 ${res}`)
}
setPopupValue(res as string)
}
function onRangeChange(res: SelectorModelValue) {
console.log('onChange', res)
setPopupRangeValue(res)
}
return (
<>
<TaNoticeBar
className="top-notice-bar"
title="基础展示参数可以参考 Calendar"
/>
<TaGroup title="基础用法">
<TaCell label="默认" onClick={() => onShow({})}>
{popupValue}
</TaCell>
<TaCell label="+1day" isLink onClick={() => addOneDay()}>
click
</TaCell>
<TaCell
label="showConfirm=true"
isLink
onClick={() => onShow({ showConfirm: true })}
/>
<TaCell
label="initialMode=range"
isLink
onClick={() => setRangeVisible(true)}
></TaCell>
</TaGroup>
<TaGroup title="事件监听">
<TaCell
label="onChange"
isLink
onClick={() => onShow({ changeEvent: true })}
/>
<TaCell
label="onConfirm/onCancel"
isLink
onClick={() => onShow({ clickEvent: true })}
/>
<TaCell
label="onVisibleStateChange"
isLink
onClick={() => onShow({ visibleEvent: true })}
/>
</TaGroup>
<TaCalendar.Popup
title={title}
showConfirm={showConfirm}
showClose={showClose}
formatter={formatter}
parser={parser}
visible={visible}
onUpdateVisible={v => setVisible(v)}
value={popupValue}
onChange={onChange}
onConfirm={onConfirm}
onCancel={onCancel}
onVisibleStateChange={onVisibleStateChange}
/>
<TaCalendar.Popup
title={title}
initialMode="range"
visible={rangeVisible}
onUpdateVisible={v => setRangeVisible(v)}
value={popupRangeValue}
onChange={onRangeChange}
/>
</>
)
}
属性 | 类型 | 默认值 | 必填 | 说明 |
---|
visible | boolean | false | 否 | 是否显示 |
title | string | | 否 | 弹窗标题 |
showConfirm | boolean | false | 否 | 选择时是否展示确定按钮 |
showClose | boolean | false | 否 | 是否展示关闭按钮 |
事件 | 描述 | 回调函数参数 | 函数 TypeScript |
---|
onConfirm | 选择完毕后触发 / showConfirm 点击确定按钮后触发 | payload: CalendarDetail | CalendarOnConfirm |
onCancel | 点击蒙层关闭后触发 | | PopupOnCancel |
onChange | 选择后值发生改变时触发 | payload: SelectorModelValue | SelectorOnChange |
onVisibleStateChange | 展示隐藏时触发 | payload: { state: VisibleState } | PopupOnVisibleStateChange |
onUpdateVisible | 展示隐藏时触发 | visible: boolean 是否显示 | |
VisibleState 值说明
值 | 说明 | 备注 |
---|
show | 展示时触发 | |
shown | 展示且动画结束后触发 | |
hide | 隐藏时触发 | 可能携带其他参数 cancel, maskClick, closeClick 等 |
hidden | 隐藏且动画结束后触发 | 可能携带其他参数 cancel, maskClick, closeClick 等 |
CalendarView 日历选择面板
import {
TaCalendar,
TaNoticeBar,
TaCell,
TaGroup,
CalendarOnSelect,
showToast
} from '@/index'
import { useState } from 'react'
import { formatter, parser } from '../Calendar/utils'
export default function ExpCalendarView() {
const [viewValue, setViewValue] = useState('')
const [viewRangeValue, setViewRangeValue] = useState('')
const onSelect: CalendarOnSelect = res => {
console.log('select', res)
showToast(`选择:${res.label}`)
}
return (
<>
<TaNoticeBar
className="top-notice-bar"
title="基础展示参数可以参考 Calendar"
/>
<TaGroup title="initialMode=single">
<TaCell label="value:"> {viewValue} </TaCell>
<TaCalendar.View
value={viewValue}
onChange={v => setViewValue(v as string)}
formatter={formatter}
parser={parser}
/>
</TaGroup>
<TaGroup title="initialMode=range">
<TaCell label="value:"> {viewRangeValue} </TaCell>
<TaCalendar.View
initialMode="range"
value={viewRangeValue}
onChange={v => setViewRangeValue(v as string)}
formatter={formatter}
parser={parser}
/>
</TaGroup>
<TaGroup title="select 事件">
<TaCalendar.View onSelect={onSelect} />
</TaGroup>
</>
)
}
CalendarView Events
showCalendar(object) 显示日历选择弹窗
object
属性 | 类型 | 默认值 | 必填 | 说明 |
---|
mode | CalendarMode | 'single' | 否 | 模式 |
title | string | | 否 | 弹窗标题 |
value | Date/Date[] | [] | 否 | 默认选择值,range 模式下需要提供两个 |
minDate | Date | 当前日期 | 否 | 可选最小值 |
maxDate | Date | 当前日期的六个月后 | 否 | 可选最大值 |
allowSameDay | boolean | false | 否 | range 模式生效,设置开始结束时间是否可以同一天 |
maxRange | number | Infinity | 否 | range 模式生效,选择区间的最长天数 |
dayHandler | CalendarDayHandler | | 否 | 日历每个日期处理函数 |
success | (payload: SuccessPayload) => void | | 否 | 接口调用成功(在用户做出选择后,如取消,选择选项)的回调函数 |
fail | (e: Error) => void | | 否 | 接口调用失败(如传入错误的参数)的回调函数(不传入 fail 遇错误直接抛出) |
complete | () => void | | 否 | 弹窗关闭或调用失败的回调函数 |
SuccessPayload
属性 | 类型 | 说明 |
---|
confirm? | boolean | 为 true 时,表示点击了确定,此时返回 detail |
cancel? | boolean | 为 true 时,表示取消 |
detail? | CalendarDetail | |
Usage
具体调用方式可以参考API 调用。
showCalendar({
type: 'range',
showClose: true,
success: ({ confirm, cancel, detail }) => {
...
}
})
类型释义
SelectorValue
type SelectorValue = string | number | Date
SelectorModelValue
type SelectorModelValue = SelectorValue | SelectorValue[]
注:在不自定义 formatter/parser
的情况下,value 只有 Date[]
这种情况。
CalendarDetail
interface CalendarDetail {
label: string
value: Date[]
valueArray: number[][]
rangeCount: number
}
字段 | 说明 |
---|
label | 选中值对应的描述文本,如果设置了 formatter ,则返回格式后文本 |
value | 选择的值,range 模式下有开始 Date 和结束 Date 两个实例,不受 formatter 影响 |
valueArray | 如:[[2021, 5, 1]] 或 [[2021, 5, 1], [2021, 5, 30]] |
rangeCount | 选择区间持续的天数(含首尾) |
CalendarMode
type CalendarMode = 'single' | 'range'
值 | 说明 |
---|
single | 选择一天 |
range | 选择一个日期区间 |
interface CalendarValueFormatter {
(valueArray: Date[], mode: CalendarMode):
| { value: SelectorModelValue; label: string }
| SelectorModelValue
}
将 value 的原始值转为需要的自定义值,值需要满足 SelectorModelValue
的类型约束,可以返回 { value, label } 对两个数据进行修改,或者单独返回 value。
CalendarValueParser
interface CalendarValueParser {
(value: unknown, mode: CalendarMode): Date[]
}
跟 CalendarValueFormatter
相反,将自定义 value 的值转为组件认识的原始数组。
CalendarDayHandler
type CalendarDayHandler = dayHandler(dayInfo: DayInfo) => DayInfo
interface DayInfo {
topHighlight?: boolean
topText?: string
state: string
bottomHighlight?: boolean
bottomText?: string
text: string
dateString: string
date?: Date
timestamp: number
}
日历中的每个日期都对应一个 DayInfo 对象,通过 day-handler
属性可以修改 DayInfo 对象的内容后返回。
值 | 类型 | 说明 |
---|
date | Date | 日期对应的 Date 对象,该字段修改无效 |
state | string | 日期当前的状态,有:selected 选中,startSelected 开始(initialMode="range"下),endSelected 结束(initialMode="range"下),disabled 禁用。在空字符串的情况下,可以设置为 disabled 强制设置该日期为禁用(一般在票卖完的情况下设置) |
text | string | 日期文本,不建议修改 |
topText | string | 日期上方展示文本,一般可修改为“节日名称”、“今天”、“明天”、“开始”、“结束”等 |
topHighlight | boolean | 日期上方展示文本是否高亮 |
bottomText | string | 日期下方展示文本,一般可修改为“机票价格”、“酒店价格”、“特价”、“热门”等 |
bottomHighlight | boolean | 日期下方展示文本是否高亮 |
dateString | string | 日期对应的格式化时间(YYYY-MM-DD ),如:2020-11-11,该字段不影响展示 |