@@ -72,36 +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' ,
80- disableTapHighlight : true
83+ disableTapHighlight : true ,
84+ '--cell-gap' : {
85+ type : 'paddingStart' ,
86+ value : 4
87+ } ,
88+ '--cell-max-width' : {
89+ type : 'width' ,
90+ 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'
106+ }
81107} , getAllowedOverrides ( ) ) ;
82108
83109const headerStyles = style ( {
84110 display : 'flex' ,
85111 alignItems : 'center' ,
86- justifyContent : 'space-between' ,
87- width : 'full'
112+ justifyContent : 'space-between'
88113} ) ;
89114
90115const headingStyles = style ( {
91116 display : 'flex' ,
92117 alignItems : 'center' ,
93118 justifyContent : 'space-between' ,
94119 margin : 0 ,
95- width : 'full'
120+ flexGrow : 1
96121} ) ;
97122
98123const titleStyles = style ( {
99124 font : 'title-lg' ,
100125 textAlign : 'center' ,
101126 flexGrow : 1 ,
102- flexShrink : 0 ,
103- flexBasis : '0%' ,
104- minWidth : 0
127+ flexShrink : 0
105128} ) ;
106129
107130const headerCellStyles = style ( {
@@ -121,10 +144,7 @@ const headerCellStyles = style({
121144
122145const cellStyles = style ( {
123146 outlineStyle : 'none' ,
124- '--cell-gap' : {
125- type : 'paddingStart' ,
126- value : 4
127- } ,
147+ boxSizing : 'content-box' ,
128148 paddingStart : {
129149 default : 4 ,
130150 isFirstChild : 0
@@ -142,15 +162,16 @@ const cellStyles = style({
142162 isLastWeek : 0
143163 } ,
144164 position : 'relative' ,
145- width : 32 ,
146- height : 32 ,
147165 display : {
148166 default : 'flex' ,
149167 isOutsideMonth : 'none'
150168 } ,
151169 alignItems : 'center' ,
152170 justifyContent : 'center' ,
153- disableTapHighlight : true
171+ disableTapHighlight : true ,
172+ width : '--cell-responsive-size' ,
173+ aspectRatio : 'square' ,
174+ height : 'auto'
154175} ) ;
155176
156177const cellInnerStyles = style < CalendarCellRenderProps & { selectionMode : 'single' | 'range' } > ( {
@@ -174,7 +195,7 @@ const cellInnerStyles = style<CalendarCellRenderProps & {selectionMode: 'single'
174195 font : 'body-sm' ,
175196 cursor : 'default' ,
176197 width : 'full' ,
177- height : 32 ,
198+ height : 'full' ,
178199 borderRadius : 'full' ,
179200 display : 'flex' ,
180201 alignItems : 'center' ,
@@ -291,7 +312,7 @@ const cellInnerStyles = style<CalendarCellRenderProps & {selectionMode: 'single'
291312
292313const todayStyles = style ( {
293314 position : 'absolute' ,
294- bottom : 4 ,
315+ bottom : '12.5%' ,
295316 left : '50%' ,
296317 transform : 'translateX(-50%)' ,
297318 width : 4 ,
@@ -420,13 +441,14 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
420441 ...otherProps
421442 } = props ;
422443 let stringFormatter = useLocalizedStringFormatter ( intlMessages , '@react-spectrum/s2' ) ;
444+ let isMultiMonth = visibleMonths > 1 ;
423445 return (
424446 < AriaCalendar
425447 { ...otherProps }
426448 ref = { ref }
427449 visibleDuration = { { months : visibleMonths } }
428450 style = { UNSAFE_style }
429- className = { ( UNSAFE_className || '' ) + calendarStyles ( null , styles ) } >
451+ className = { ( UNSAFE_className || '' ) + calendarStyles ( { isMultiMonth } , styles ) } >
430452 { ( { isInvalid, isDisabled} ) => {
431453 return (
432454 < >
@@ -435,11 +457,7 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
435457 [ HeaderContext , null ] ,
436458 [ HeadingContext , null ]
437459 ] } >
438- < Header styles = { headerStyles } >
439- < CalendarButton slot = "previous" > < ChevronLeftIcon /> </ CalendarButton >
440- < CalendarHeading />
441- < CalendarButton slot = "next" > < ChevronRightIcon /> </ CalendarButton >
442- </ Header >
460+ < CalendarHeader />
443461 </ Provider >
444462 < div
445463 className = { style ( {
@@ -450,7 +468,7 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
450468 alignItems : 'start'
451469 } ) } >
452470 { Array . from ( { length : visibleMonths } ) . map ( ( _ , i ) => (
453- < CalendarGrid months = { i } key = { i } />
471+ < CalendarGrid key = { i } months = { i } />
454472 ) ) }
455473 </ div >
456474 { isInvalid && (
@@ -465,6 +483,16 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
465483 ) ;
466484} ) ;
467485
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+
468496export const CalendarGrid = ( props : Omit < AriaCalendarGridProps , 'children' > & PropsWithChildren & { months : number } ) : ReactElement => {
469497 let rangeCalendarProps = useSlottedContext ( RangeCalendarContext ) ;
470498 let calendarProps = useSlottedContext ( AriaCalendarContext ) ;
@@ -497,7 +525,7 @@ export const CalendarGrid = (props: Omit<AriaCalendarGridProps, 'children'> & Pr
497525
498526// Ordinarily the heading is a formatted date range, ie January 2025 - February 2025.
499527// However, we want to show each month individually.
500- export const CalendarHeading = ( ) : ReactElement => {
528+ const CalendarHeading = ( ) : ReactElement => {
501529 let calendarStateContext = useContext ( CalendarStateContext ) ;
502530 let rangeCalendarStateContext = useContext ( RangeCalendarStateContext ) ;
503531 let { visibleRange, timeZone} = calendarStateContext ?? rangeCalendarStateContext ?? { } ;
@@ -648,11 +676,8 @@ const CalendarCellInner = (props: Omit<CalendarCellProps, 'children'> & {isRange
648676 < div
649677 className = { style ( {
650678 position : 'relative' ,
651- width : 32 ,
652- '--cell-width' : {
653- type : 'width' ,
654- value : '[self(width)]'
655- }
679+ width : 'full' ,
680+ height : 'full'
656681 } ) } >
657682 < div
658683 ref = { ref }
0 commit comments