@@ -72,44 +72,59 @@ export interface CalendarProps<T extends DateValue>
7272
7373export const CalendarContext = createContext < ContextValue < Partial < CalendarProps < any > > , HTMLDivElement > > ( null ) ;
7474
75- const calendarStyles = style ( {
75+ const calendarStyles = style < { isMultiMonth ?: boolean } > ( {
7676 display : 'flex' ,
77+ containerType : {
78+ default : 'inline-size' ,
79+ isMultiMonth : 'unset'
80+ } ,
7781 flexDirection : 'column' ,
7882 gap : 24 ,
79- width : 'fit' ,
8083 disableTapHighlight : true ,
8184 '--cell-gap' : {
8285 type : 'paddingStart' ,
8386 value : 4
8487 } ,
85- '--cell-min -width' : {
88+ '--cell-max -width' : {
8689 type : 'width' ,
8790 value : 32
91+ } ,
92+ '--cell-responsive-size' : {
93+ type : 'width' ,
94+ value : {
95+ default : '[min(var(--cell-max-width), (100cqw - (var(--cell-gap) * 12)) / 7)]' ,
96+ isMultiMonth : '--cell-max-width'
97+ }
98+ } ,
99+ width : {
100+ default : 'calc(7 * var(--cell-max-width) + var(--cell-gap) * 12)' ,
101+ isMultiMonth : 'fit'
102+ } ,
103+ maxWidth : {
104+ default : 'full' ,
105+ isMultiMonth : 'unset'
88106 }
89107} , getAllowedOverrides ( ) ) ;
90108
91109const headerStyles = style ( {
92110 display : 'flex' ,
93111 alignItems : 'center' ,
94- justifyContent : 'space-between' ,
95- width : 'full'
112+ justifyContent : 'space-between'
96113} ) ;
97114
98115const headingStyles = style ( {
99116 display : 'flex' ,
100117 alignItems : 'center' ,
101118 justifyContent : 'space-between' ,
102119 margin : 0 ,
103- width : 'full'
120+ flexGrow : 1
104121} ) ;
105122
106123const titleStyles = style ( {
107124 font : 'title-lg' ,
108125 textAlign : 'center' ,
109126 flexGrow : 1 ,
110- flexShrink : 0 ,
111- flexBasis : '0%' ,
112- minWidth : 0
127+ flexShrink : 0
113128} ) ;
114129
115130const headerCellStyles = style ( {
@@ -154,11 +169,7 @@ const cellStyles = style({
154169 alignItems : 'center' ,
155170 justifyContent : 'center' ,
156171 disableTapHighlight : true ,
157- '--cell-min-width' : {
158- type : 'width' ,
159- value : 32
160- } ,
161- width : '[min(var(--cell-min-width), calc((100cqw / 7) - var(--cell-gap)))]' ,
172+ width : '--cell-responsive-size' ,
162173 aspectRatio : 'square' ,
163174 height : 'auto'
164175} ) ;
@@ -301,7 +312,7 @@ const cellInnerStyles = style<CalendarCellRenderProps & {selectionMode: 'single'
301312
302313const todayStyles = style ( {
303314 position : 'absolute' ,
304- bottom : 4 ,
315+ bottom : '12.5%' ,
305316 left : '50%' ,
306317 transform : 'translateX(-50%)' ,
307318 width : 4 ,
@@ -430,13 +441,14 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
430441 ...otherProps
431442 } = props ;
432443 let stringFormatter = useLocalizedStringFormatter ( intlMessages , '@react-spectrum/s2' ) ;
444+ let isMultiMonth = visibleMonths > 1 ;
433445 return (
434446 < AriaCalendar
435447 { ...otherProps }
436448 ref = { ref }
437449 visibleDuration = { { months : visibleMonths } }
438450 style = { UNSAFE_style }
439- className = { ( UNSAFE_className || '' ) + calendarStyles ( null , styles ) } >
451+ className = { ( UNSAFE_className || '' ) + calendarStyles ( { isMultiMonth } , styles ) } >
440452 { ( { isInvalid, isDisabled} ) => {
441453 return (
442454 < >
@@ -445,11 +457,7 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
445457 [ HeaderContext , null ] ,
446458 [ HeadingContext , null ]
447459 ] } >
448- < Header styles = { headerStyles } >
449- < CalendarButton slot = "previous" > < ChevronLeftIcon /> </ CalendarButton >
450- < CalendarHeading />
451- < CalendarButton slot = "next" > < ChevronRightIcon /> </ CalendarButton >
452- </ Header >
460+ < CalendarHeader />
453461 </ Provider >
454462 < div
455463 className = { style ( {
@@ -460,23 +468,7 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
460468 alignItems : 'start'
461469 } ) } >
462470 { Array . from ( { length : visibleMonths } ) . map ( ( _ , i ) => (
463- < div
464- key = { i }
465- style = { { '--visible-months' : visibleMonths } as React . CSSProperties }
466- className = { style ( {
467- containerType : 'inline-size' ,
468- flexGrow : 1 ,
469- flexShrink : 0 ,
470- flexBasis : '0%' ,
471- minWidth : 0 ,
472- width : 'calc(7 * var(--cell-min-width) + var(--cell-gap) * 12)' ,
473- maxWidth : {
474- default : 'calc(100vw / var(--visible-months))' ,
475- '@media (max-width: 375px)' : '100%'
476- }
477- } ) } >
478- < CalendarGrid months = { i } />
479- </ div >
471+ < CalendarGrid key = { i } months = { i } />
480472 ) ) }
481473 </ div >
482474 { isInvalid && (
@@ -491,6 +483,16 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
491483 ) ;
492484} ) ;
493485
486+ export const CalendarHeader = ( ) : ReactElement => {
487+ return (
488+ < Header styles = { headerStyles } >
489+ < CalendarButton slot = "previous" > < ChevronLeftIcon /> </ CalendarButton >
490+ < CalendarHeading />
491+ < CalendarButton slot = "next" > < ChevronRightIcon /> </ CalendarButton >
492+ </ Header >
493+ ) ;
494+ } ;
495+
494496export const CalendarGrid = ( props : Omit < AriaCalendarGridProps , 'children' > & PropsWithChildren & { months : number } ) : ReactElement => {
495497 let rangeCalendarProps = useSlottedContext ( RangeCalendarContext ) ;
496498 let calendarProps = useSlottedContext ( AriaCalendarContext ) ;
@@ -502,8 +504,7 @@ export const CalendarGrid = (props: Omit<AriaCalendarGridProps, 'children'> & Pr
502504 className = { style ( {
503505 borderCollapse : 'collapse' ,
504506 borderSpacing : 0 ,
505- isolation : 'isolate' ,
506- width : 'full'
507+ isolation : 'isolate'
507508 } ) }
508509 offset = { { months : props . months } } >
509510 < CalendarGridHeader className = "" >
@@ -524,7 +525,7 @@ export const CalendarGrid = (props: Omit<AriaCalendarGridProps, 'children'> & Pr
524525
525526// Ordinarily the heading is a formatted date range, ie January 2025 - February 2025.
526527// However, we want to show each month individually.
527- export const CalendarHeading = ( ) : ReactElement => {
528+ const CalendarHeading = ( ) : ReactElement => {
528529 let calendarStateContext = useContext ( CalendarStateContext ) ;
529530 let rangeCalendarStateContext = useContext ( RangeCalendarStateContext ) ;
530531 let { visibleRange, timeZone} = calendarStateContext ?? rangeCalendarStateContext ?? { } ;
0 commit comments