From 3deeb45a2dc1e5bffb93081e2aa5ea3b0eb7873d Mon Sep 17 00:00:00 2001 From: lethemanh Date: Thu, 9 Apr 2026 16:22:58 +0700 Subject: [PATCH] #760 fix date picker does not display on iphone --- .../Menubar/components/DatePickerMobile.tsx | 75 +++++++++++++++++-- .../Menubar/components/MonthSelector.tsx | 3 +- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/components/Menubar/components/DatePickerMobile.tsx b/src/components/Menubar/components/DatePickerMobile.tsx index 331f59b..74a9fb3 100644 --- a/src/components/Menubar/components/DatePickerMobile.tsx +++ b/src/components/Menubar/components/DatePickerMobile.tsx @@ -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 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 = ({ calendarRef, currentDate, @@ -25,6 +81,11 @@ export const DatePickerMobile: React.FC = ({ 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 = ({ 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 = ({ '.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 = ({ '.MuiDayCalendar-weekContainer': { width: '100%', justifyContent: 'space-around' + }, + '.MuiDateCalendar-root .MuiDayCalendar-slideTransition': { + minHeight: `${slideTransitionMinHeight}px` } } }, diff --git a/src/components/Menubar/components/MonthSelector.tsx b/src/components/Menubar/components/MonthSelector.tsx index 0e013e7..188219a 100644 --- a/src/components/Menubar/components/MonthSelector.tsx +++ b/src/components/Menubar/components/MonthSelector.tsx @@ -39,7 +39,8 @@ export const MonthSelector: React.FC = ({ py: 1, scrollbarWidth: 'none', '&::-webkit-scrollbar': { display: 'none' }, - backgroundColor: '#FFF' + backgroundColor: '#FFF', + minHeight: '48px' }} > {Array.from({ length: 12 }).map((_, i) => {