修改发布日历
This commit is contained in:
117
src/components/CalendarCard/CalendarCard.tsx
Normal file
117
src/components/CalendarCard/CalendarCard.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { View, Text, Image } from '@tarojs/components'
|
||||
import styles from './index.module.scss'
|
||||
import images from '@/config/images'
|
||||
interface CalendarCardProps {
|
||||
value?: Date
|
||||
minDate?: Date
|
||||
maxDate?: Date
|
||||
onChange?: (date: Date) => void
|
||||
onNext?: (date: Date) => void
|
||||
onHeaderClick?: (date: Date) => void
|
||||
}
|
||||
|
||||
const startOfMonth = (date: Date) => new Date(date.getFullYear(), date.getMonth(), 1)
|
||||
const endOfMonth = (date: Date) => new Date(date.getFullYear(), date.getMonth() + 1, 0)
|
||||
const addMonths = (date: Date, delta: number) => new Date(date.getFullYear(), date.getMonth() + delta, 1)
|
||||
|
||||
const formatHeader = (date: Date) => `${date.getMonth() + 1}月 ${date.getFullYear()}`
|
||||
|
||||
const CalendarCard: React.FC<CalendarCardProps> = ({
|
||||
value,
|
||||
minDate,
|
||||
maxDate,
|
||||
onChange,
|
||||
onHeaderClick
|
||||
}) => {
|
||||
const today = new Date()
|
||||
const [current, setCurrent] = useState<Date>(value || startOfMonth(today))
|
||||
const [selected, setSelected] = useState<Date>(value || today)
|
||||
|
||||
|
||||
const firstDay = useMemo(() => startOfMonth(current), [current])
|
||||
const lastDay = useMemo(() => endOfMonth(current), [current])
|
||||
|
||||
const days = useMemo(() => {
|
||||
const startWeekday = firstDay.getDay() // 0 周日
|
||||
const prevPadding = startWeekday // 周日为第一列
|
||||
const total = prevPadding + lastDay.getDate()
|
||||
const rows = Math.ceil(total / 7)
|
||||
const grid: (Date | null)[] = []
|
||||
for (let i = 0; i < rows * 7; i++) {
|
||||
const day = i - prevPadding + 1
|
||||
if (day < 1 || day > lastDay.getDate()) {
|
||||
grid.push(null)
|
||||
} else {
|
||||
grid.push(new Date(current.getFullYear(), current.getMonth(), day))
|
||||
}
|
||||
}
|
||||
return grid
|
||||
}, [firstDay, lastDay, current])
|
||||
|
||||
const isDisabled = (d: Date) => {
|
||||
if (minDate && d < minDate) return true
|
||||
if (maxDate && d > maxDate) return true
|
||||
return false
|
||||
}
|
||||
|
||||
const gotoMonth = (delta: number) => setCurrent(prev => addMonths(prev, delta))
|
||||
|
||||
const handleHeaderClick = () => {
|
||||
onHeaderClick && onHeaderClick(current)
|
||||
}
|
||||
|
||||
const handleSelectDay = (d: Date | null) => {
|
||||
if (!d || isDisabled(d)) return
|
||||
setSelected(d)
|
||||
onChange && onChange(d)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<View className={styles['calendar-card']}>
|
||||
<View className={styles['header']}>
|
||||
<View className={styles['header-left']} onClick={handleHeaderClick}>
|
||||
<Text className={styles['header-text']}>{formatHeader(current)}</Text>
|
||||
<Image src={images.ICON_RIGHT_MAX} className={`${styles['month-arrow']}}`} onClick={() => gotoMonth(1)} />
|
||||
</View>
|
||||
<View className={styles['header-actions']}>
|
||||
<Image src={images.ICON_RIGHT_MAX} className={`${styles['arrow']} ${styles['left']}`} onClick={() => gotoMonth(-1)} />
|
||||
<Image src={images.ICON_RIGHT_MAX} className={`${styles['arrow']}}`} onClick={() => gotoMonth(1)} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className={styles['week-row']}>
|
||||
{['周日','周一','周二','周三','周四','周五','周六'].map((w) => (
|
||||
<Text key={w} className={styles['week-item']}>{w}</Text>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<View className={styles['grid']}>
|
||||
{days.map((d, idx) => {
|
||||
const isSelected = !!(d && selected && d.toDateString() === new Date(selected.getFullYear(), selected.getMonth(), selected.getDate()).toDateString())
|
||||
return (
|
||||
<View
|
||||
key={idx}
|
||||
className={`${styles['cell']} ${!d ? styles['empty'] : ''} ${d && isDisabled(d) ? styles['disabled'] : ''} `}
|
||||
onClick={() => handleSelectDay(d)}
|
||||
>
|
||||
{d ? <Text className={`${styles['cell-text']} ${isSelected ? styles['selected'] : ''}`}>{d.getDate()}</Text> : null}
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
|
||||
|
||||
|
||||
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export default CalendarCard
|
||||
Reference in New Issue
Block a user