可定制标记样式的 taro
日历组件。本组件的初期设计完全参考taro-ui
中的calendar
组件。在其之上进行了功能扩充和优化。
- 可定制样式
- 支持农历显示
- 支持周视图
- 可完全自定义控制器
- 可指定一周的起点
yarn add taro-calendar-customizable
npm install taro-calendar-customizable
import Taro, { FunctionComponent } from '@tarojs/taro';
import Calendar from 'taro-calendar-customizable';
const Index: FunctionComponent = () => {
return (
<Calendar
marks={[
{ value: '2019-08-11', color: 'red', markSize: '9px' },
{ value: '2019-08-12', color: 'pink', markSize: '9px' },
{ value: '2019-08-13', color: 'gray', markSize: '9px' },
{ value: '2019-08-14', color: 'yellow', markSize: '9px' },
{ value: '2019-08-15', color: 'darkblue', markSize: '9px' },
{ value: '2019-08-16', color: 'pink', markSize: '9px' },
{ value: '2019-08-17', color: 'green', markSize: '9px' }
]}
extraInfo={[
{ value: '2019-08-21', text: '生日', color: 'red' },
{ value: '2019-08-22', text: '休假', color: 'darkblue' },
{ value: '2019-08-23', text: '会议', color: 'gray' }
]}
mode="lunar"
selectedDateColor="#346fc2"
onDayClick={item => console.log(item)}
onDayLongPress={item => console.log(item)}
/>
);
};
export default Index;
这里展示了最简单的样式设置方式,点击查看效果,具体到日期单元格样式的定制可以使用customStyleGenerator
import Taro, { FunctionComponent } from '@tarojs/taro';
import Calendar from 'taro-calendar-customizable';
const Index: FunctionComponent = () => {
return (
<Calendar
marks={[
{ value: '2019-08-11', color: 'red', markSize: '9px' },
{ value: '2019-08-12', color: 'pink', markSize: '9px' },
{ value: '2019-08-13', color: 'gray', markSize: '9px' },
{ value: '2019-08-14', color: 'yellow', markSize: '9px' },
{ value: '2019-08-15', color: 'darkblue', markSize: '9px' },
{ value: '2019-08-16', color: 'pink', markSize: '9px' },
{ value: '2019-08-17', color: 'green', markSize: '9px' }
]}
mode="normal"
isMultiSelect
selectedDateColor="#346fc2"
onDayClick={item => console.log(item)}
onDayLongPress={item => console.log(item)}
headStyle={{
backgroundColor: 'RGBA(12,36,157,0.5)',
borderTopLeftRadius: '10px',
borderTopRightRadius: '10px',
boxShadow: '0 0 5px RGBA(0,0,0,0.3)',
width: '90vw',
marginLeft: '5vw',
zIndex: 2
}}
bodyStyle={{
backgroundColor: 'lightblue',
borderBottomLeftRadius: '10px',
borderBottomRightRadius: '10px',
boxShadow: '0 0 5px RGBA(0,0,0,0.3)',
borderTop: 'none',
width: '90vw',
marginLeft: '5vw'
}}
/>
);
};
export default Index;
这里通过bindRef
方法获取到了Calendar
的实例,通过调用内部方法goNext()
以及goPrev()
实现了翻页控制。查看效果
import Taro, { FunctionComponent, useState } from '@tarojs/taro';
import Calendar from 'taro-calendar-customizable';
import { View, Button, Text, Switch } from '@tarojs/components';
const Index: FunctionComponent = () => {
const [calendarObj, setCalendarObj] = useState<Calendar>();
const [currentView, setCurrentView] = useState('2019-08-18');
const [selected, setSelected] = useState('2019-08-18');
const [isWeekView, setIsWeekView] = useState(false);
const [hideController, setHideController] = useState(false);
return (
<View>
<Calendar
view={isWeekView ? 'week' : 'month'}
bindRef={ref => {
setCalendarObj(ref);
}}
hideController={hideController}
currentView={currentView}
onCurrentViewChange={setCurrentView}
selectedDate={selected}
onDayClick={item => setSelected(item.value)}
/>
<Text style={{ display: 'block', width: '100vw', textAlign: 'center' }}>
{currentView.slice(0, 7)}
</Text>
<Button
onClick={() => {
calendarObj ? calendarObj.goPre() : '';
}}
style={{ width: '50%', display: 'inline-block' }}
>
上一页
</Button>
<Button
onClick={() => {
calendarObj ? calendarObj.goNext() : '';
}}
style={{ width: '50%', display: 'inline-block' }}
>
下一页
</Button>
<Button onClick={() => setCurrentView('2019-08')}>
设置view为2019-08
</Button>
<Button onClick={() => setSelected('2019-08-08')}>选中2019-08-08</Button>
<Switch
checked={isWeekView}
onChange={e => {
// @ts-ignore
setIsWeekView(e.target.value);
}}
>
周视图
</Switch>
<Switch
checked={hideController}
onChange={e => {
// @ts-ignore
setHideController(e.target.value);
}}
>
隐藏控制器
</Switch>
</View>
);
};
export default Index;
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
mode | 显示模式,普通或农历 | "normal" |"lunar" |
"normal" |
view | 视图模式 | "week" |"month" |
"month" |
selectedDate | 当前选中的时间,格式:YYYY-MM-DD |
string |
Date.now() |
currentView | 月视图时为当前视图显示的月份YYYY-MM ,周视图下为当前显示的周内的某一天YYYY-MM-DD |
string |
当前系统时间年月 |
minDate | 最小的可选时间,格式:YYYY-MM-DD |
string |
1970-01-01 |
maxDate | 最大的可选时间,格式:YYYY-MM-DD |
string |
null |
isSwiper | 是否可以滑动 | boolean |
true |
isVertical | 是否垂直滑动 | boolean |
false |
isMultiSelect | 是否范围选择 | boolean |
false |
marks | 需要标记的时间 | Array<{value:string,color:string,markSize:string}> |
[] |
extraInfo | 额外信息 | Array<{value:string,text:string,color:string,fontSize:string}> |
[] |
hideArrow | 是否隐藏箭头 | boolean |
false |
hideController | 是否显示控制器 | false |
boolean |
showDivider | 是否显示分割线 | boolean |
false |
bindRef | 父组件通过 ref 可以调用内部方法,主要用于实现自定义控制器 | (ref:Calendar)=>any |
- |
参数 | 说明 | 类型 |
---|---|---|
onClickPre | 点击左箭头 | () => any |
onClickNext | 点击右箭头 | () => any |
onDayClick | 点击日期时候触发 | (item:{value:string}) => any |
onDayLongPress | 长按日期时触发(长按事件与点击事件互斥) | (item:{value:string}) => any |
onCurrentViewChange | 月份/周 改变时触发 | (value: string) => any |
onSelectDate | 选中日期时候触发 | (value: SelectDate) => any |
参数 | 说明 | 类型 |
---|---|---|
selectedDateColor | 选中日期的颜色 | string |
customStyleGenerator | 单元格样式生成器 | (dateInfo:StyleGeneratorParams ) => CustomStyles |
pickerTextGenerator | 日期选择器文本的生成器,参数为:当前视图中的任意一天 | (currentView:Date)=>string |
headStyle | head 整体样式 | CSSProperties |
headCellStyle | head 单元格样式 | CSSProperties |
bodyStyle | body 整体样式 | CSSProperties |
leftArrowStyle | 左箭头样式 | CSSProperties |
rightArrowStyle | 右箭头样式 | CSSProperties |
datePickerStyle | 日期选择器样式 | CSSProperties |
pickerRowStyle | 日期选择器&左右箭头 所在容器样式 | CSSProperties |
进行样式定制时可以参考组件内部结构图:
给customStyleGenerator
赋值的时候不要使用临时对象,否则性能会很差
错误用法:
<Calendar
...
customStyleGenerator={
params => {
return {
containerStyle: {
}
};
}
}
/>
正确用法:
在引用Calendar的组件的外部创建const对象,然后赋值:
const customStyleGenerator = params => {
return {
containerStyle: {
}
};
};
export default class XXXX extends Component {
render () {
return (
...
<Calendar
...
customStyleGenerator={customStyleGenerator}
/>
);
}
}
每个单元格包含的所有信息
参数 | 说明 | 类型 |
---|---|---|
date | 当前月的第几天 1 ~ 31 | number |
currentMonth | 是否是属于当前显示的月份(比如 7 月 31 日不属于 8 月,但是会显示在 8 月这一页) | boolean |
fullDateStr | 时间 YYYY-MM-DD | string |
selected | 是否被选中 | boolean |
marked | 是否标记 | boolean |
hasExtraInfo | 是否含有额外信息 | boolean |
multiSelect | 多选模式参数 | MultiSelectParam |
lunar | 农历信息(仅在农历模式下生效) | LunarInfo 或 null |
startDay | 指定周几为一行的起点,0 为周日,1 为周一 | number |
样式生成器返回结果
参数 | 说明 | 类型 |
---|---|---|
lunarStyle | 农历样式 | CSSProperties |
dateStyle | 日期样式 | CSSProperties |
markStyle | 标记样式 | CSSProperties |
containerStyle | 容器单元格样式 | CSSProperties |
extraInfoStyle | 额外信息样式 | CSSProperties |
多选模式参数
参数 | 说明 | 类型 |
---|---|---|
multiSelected | 是否在选择范围内 | boolean |
multiSelectedStar | 是否是选择起点 | boolean |
multiSelectedEnd | 是否是选择终点 | boolean |
农历信息
参数 | 说明 | 类型 |
---|---|---|
Animal | 生肖 | string |
IDayCn | 中文 农历 日 (例:'初二') | string |
IMonthCn | 中文 农历 月 (例:'八月') | string |
Term | 二十四节气 | string 或null |
astro | 星座 | string |
cDay | 公历 日 | number |
cMonth | 公历 月 | number |
cYear | 公历 年 | number |
gzDay | 天干地支纪年 日 | string |
gzMonth | 天干地支纪年 月 | string |
gzYear | 天干地支纪年 年 | string |
isLeap | 是否是闰月 | boolean |
isTerm | 是否是节气 | boolean |
isToDay | 是否是今天 | boolean |
lDay | 农历 日 | number |
lMonth | 农历 月 | number |
lYear | 农历 年 | number |
nWeek | 一周的第几天 1~7 | number |
ncWeek | 星期 (例:'星期五) | string |
农历信息的生成使用的是calendar.js,可直接调用农历信息生成工具
农历生成工具调用
import { CalendarTools } from 'taro-calendar-customizable';
const LunarInfo = CalendarTools.solar2lunar('2019-08-17');