Merge pull request #761 from lethemanh/760-fix-date-picker-on-iphone
#760 fix date picker does not display on iphone
This commit is contained in:
@@ -3,12 +3,15 @@ import { useTheme } from '@linagora/twake-mui'
|
|||||||
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'
|
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'
|
||||||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'
|
||||||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'
|
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'
|
||||||
import React from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { useI18n } from 'twake-i18n'
|
import { useI18n } from 'twake-i18n'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
import localeData from 'dayjs/plugin/localeData'
|
||||||
import { PickerValue } from '@mui/x-date-pickers/internals'
|
import { PickerValue } from '@mui/x-date-pickers/internals'
|
||||||
import { MonthSelector } from './MonthSelector'
|
import { MonthSelector } from './MonthSelector'
|
||||||
|
|
||||||
|
dayjs.extend(localeData)
|
||||||
|
|
||||||
export type DatePickerMobileProps = {
|
export type DatePickerMobileProps = {
|
||||||
calendarRef: React.RefObject<CalendarApi | null>
|
calendarRef: React.RefObject<CalendarApi | null>
|
||||||
currentDate: Date
|
currentDate: Date
|
||||||
@@ -16,6 +19,59 @@ export type DatePickerMobileProps = {
|
|||||||
onCloseDatePicker: () => void
|
onCloseDatePicker: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate dynamic height based on month's week count
|
||||||
|
const calculateCalendarHeightByMonth = (
|
||||||
|
currentDate: Date,
|
||||||
|
lang: string
|
||||||
|
): {
|
||||||
|
rootMinHeight: number
|
||||||
|
calendarHeight: number
|
||||||
|
slideTransitionMinHeight: number
|
||||||
|
} => {
|
||||||
|
const date = dayjs(currentDate).locale(lang)
|
||||||
|
const firstDay = date.startOf('month')
|
||||||
|
|
||||||
|
const localeWeekStart = date.localeData().firstDayOfWeek()
|
||||||
|
const firstDayOfWeek = firstDay.day()
|
||||||
|
|
||||||
|
// Calculate days from start of month to first Sunday
|
||||||
|
// This determines how many days from previous month are shown
|
||||||
|
const daysFromPrevMonth = (firstDayOfWeek - localeWeekStart + 7) % 7
|
||||||
|
|
||||||
|
const daysInCurrentMonth = firstDay.daysInMonth()
|
||||||
|
|
||||||
|
// Total days displayed in calendar grid
|
||||||
|
const totalDaysDisplayed = daysFromPrevMonth + daysInCurrentMonth
|
||||||
|
|
||||||
|
// Calculate number of weeks needed (always round up to fill complete weeks)
|
||||||
|
const weekCount = Math.ceil(totalDaysDisplayed / 7)
|
||||||
|
|
||||||
|
// For showDaysOutsideCurrentMonth, most months will show 5-6 weeks
|
||||||
|
const adjustedWeekCount = Math.max(4, weekCount) // Minimum 4 weeks for consistency
|
||||||
|
|
||||||
|
// Base height per week + some padding
|
||||||
|
const baseHeightPerWeek = 50
|
||||||
|
const padding = 80
|
||||||
|
const minHeight = 200 // Minimum height for 4 weeks
|
||||||
|
const maxHeight = 400 // Maximum height for 6 weeks
|
||||||
|
const rootMinHeightOffset = 120
|
||||||
|
const slideTransitionOffset = 100
|
||||||
|
|
||||||
|
const calculatedHeight = Math.max(
|
||||||
|
minHeight,
|
||||||
|
Math.min(maxHeight, adjustedWeekCount * baseHeightPerWeek + padding)
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
rootMinHeight: Math.max(minHeight, calculatedHeight - rootMinHeightOffset),
|
||||||
|
calendarHeight: calculatedHeight,
|
||||||
|
slideTransitionMinHeight: Math.max(
|
||||||
|
minHeight,
|
||||||
|
calculatedHeight - slideTransitionOffset
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
|
export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
|
||||||
calendarRef,
|
calendarRef,
|
||||||
currentDate,
|
currentDate,
|
||||||
@@ -25,6 +81,11 @@ export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
|
|||||||
const { t, lang } = useI18n()
|
const { t, lang } = useI18n()
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
|
|
||||||
|
const { rootMinHeight, calendarHeight, slideTransitionMinHeight } = useMemo(
|
||||||
|
() => calculateCalendarHeightByMonth(currentDate, lang ?? 'en'),
|
||||||
|
[currentDate, lang]
|
||||||
|
)
|
||||||
|
|
||||||
const onChangeDate = (newDate: PickerValue): void => {
|
const onChangeDate = (newDate: PickerValue): void => {
|
||||||
if (newDate && calendarRef.current) {
|
if (newDate && calendarRef.current) {
|
||||||
const d = newDate.toDate()
|
const d = newDate.toDate()
|
||||||
@@ -66,7 +127,8 @@ export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
|
|||||||
slots={{ calendarHeader: () => null, actionBar: () => null }}
|
slots={{ calendarHeader: () => null, actionBar: () => null }}
|
||||||
sx={{
|
sx={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
marginTop: '10px'
|
marginTop: '10px',
|
||||||
|
minHeight: `${rootMinHeight}px`
|
||||||
}}
|
}}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
toolbar: { hidden: true },
|
toolbar: { hidden: true },
|
||||||
@@ -75,9 +137,9 @@ export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
|
|||||||
'.MuiDateCalendar-root': {
|
'.MuiDateCalendar-root': {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
margin: 0,
|
margin: 0,
|
||||||
maxWidth: 'unset',
|
maxWidth: 'none',
|
||||||
maxHeight: 'unset',
|
maxHeight: 'none',
|
||||||
height: '400px'
|
height: `${calendarHeight}px`
|
||||||
},
|
},
|
||||||
'.MuiDayCalendar-header': {
|
'.MuiDayCalendar-header': {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@@ -86,6 +148,9 @@ export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
|
|||||||
'.MuiDayCalendar-weekContainer': {
|
'.MuiDayCalendar-weekContainer': {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
justifyContent: 'space-around'
|
justifyContent: 'space-around'
|
||||||
|
},
|
||||||
|
'.MuiDateCalendar-root .MuiDayCalendar-slideTransition': {
|
||||||
|
minHeight: `${slideTransitionMinHeight}px`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ export const MonthSelector: React.FC<MonthSelectorProps> = ({
|
|||||||
py: 1,
|
py: 1,
|
||||||
scrollbarWidth: 'none',
|
scrollbarWidth: 'none',
|
||||||
'&::-webkit-scrollbar': { display: 'none' },
|
'&::-webkit-scrollbar': { display: 'none' },
|
||||||
backgroundColor: '#FFF'
|
backgroundColor: '#FFF',
|
||||||
|
minHeight: '48px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Array.from({ length: 12 }).map((_, i) => {
|
{Array.from({ length: 12 }).map((_, i) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user