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:
lethemanh
2026-04-10 14:36:11 +07:00
committed by GitHub
2 changed files with 72 additions and 6 deletions
@@ -3,12 +3,15 @@ import { useTheme } from '@linagora/twake-mui'
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'
import React from 'react'
import React, { useMemo } from 'react'
import { useI18n } from 'twake-i18n'
import dayjs from 'dayjs'
import localeData from 'dayjs/plugin/localeData'
import { PickerValue } from '@mui/x-date-pickers/internals'
import { MonthSelector } from './MonthSelector'
dayjs.extend(localeData)
export type DatePickerMobileProps = {
calendarRef: React.RefObject<CalendarApi | null>
currentDate: Date
@@ -16,6 +19,59 @@ export type DatePickerMobileProps = {
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> = ({
calendarRef,
currentDate,
@@ -25,6 +81,11 @@ export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
const { t, lang } = useI18n()
const theme = useTheme()
const { rootMinHeight, calendarHeight, slideTransitionMinHeight } = useMemo(
() => calculateCalendarHeightByMonth(currentDate, lang ?? 'en'),
[currentDate, lang]
)
const onChangeDate = (newDate: PickerValue): void => {
if (newDate && calendarRef.current) {
const d = newDate.toDate()
@@ -66,7 +127,8 @@ export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
slots={{ calendarHeader: () => null, actionBar: () => null }}
sx={{
width: '100%',
marginTop: '10px'
marginTop: '10px',
minHeight: `${rootMinHeight}px`
}}
slotProps={{
toolbar: { hidden: true },
@@ -75,9 +137,9 @@ export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
'.MuiDateCalendar-root': {
width: '100%',
margin: 0,
maxWidth: 'unset',
maxHeight: 'unset',
height: '400px'
maxWidth: 'none',
maxHeight: 'none',
height: `${calendarHeight}px`
},
'.MuiDayCalendar-header': {
width: '100%',
@@ -86,6 +148,9 @@ export const DatePickerMobile: React.FC<DatePickerMobileProps> = ({
'.MuiDayCalendar-weekContainer': {
width: '100%',
justifyContent: 'space-around'
},
'.MuiDateCalendar-root .MuiDayCalendar-slideTransition': {
minHeight: `${slideTransitionMinHeight}px`
}
}
},
@@ -39,7 +39,8 @@ export const MonthSelector: React.FC<MonthSelectorProps> = ({
py: 1,
scrollbarWidth: 'none',
'&::-webkit-scrollbar': { display: 'none' },
backgroundColor: '#FFF'
backgroundColor: '#FFF',
minHeight: '48px'
}}
>
{Array.from({ length: 12 }).map((_, i) => {