@@ -13,7 +13,7 @@ import { Component, Element, h, Host, Prop, State } from '@stencil/core';
1313 * browser support or produce poor results.
1414 *
1515 * The number of columns is determined automatically based on the
16- * available width and the preferred column width.
16+ * available width and the minimum column width.
1717 *
1818 * :::note
1919 * This component has `shadow: false`, so consumers can treat it as
@@ -106,11 +106,13 @@ export class MasonryLayout {
106106 ) ;
107107 }
108108
109- private pxToRem ( px : number ) : number {
110- const rootFontSize = Number . parseFloat (
109+ private getRootFontSize ( ) : number {
110+ return Number . parseFloat (
111111 getComputedStyle ( document . documentElement ) . fontSize
112112 ) ;
113+ }
113114
115+ private pxToRem ( px : number , rootFontSize : number ) : number {
114116 return px / rootFontSize ;
115117 }
116118
@@ -121,8 +123,13 @@ export class MasonryLayout {
121123 *
122124 * @param property - The CSS custom property name to read.
123125 * @param fallback - The fallback CSS value if the property is not set.
126+ * @param rootFontSize - The root font size in pixels for rem conversion.
124127 */
125- private getCssPropertyInPx ( property : string , fallback : string ) : number {
128+ private getCssPropertyInPx (
129+ property : string ,
130+ fallback : string ,
131+ rootFontSize : number ,
132+ ) : number {
126133 const value =
127134 getComputedStyle ( this . host ) . getPropertyValue ( property ) . trim ( ) ||
128135 fallback ;
@@ -132,10 +139,6 @@ export class MasonryLayout {
132139 return number ;
133140 }
134141
135- const rootFontSize = Number . parseFloat (
136- getComputedStyle ( document . documentElement ) . fontSize
137- ) ;
138-
139142 // Assume rem for any other unit (rem is the project standard)
140143 return number * rootFontSize ;
141144 }
@@ -169,28 +172,53 @@ export class MasonryLayout {
169172 return ;
170173 }
171174
172- const gapPx = this . getCssPropertyInPx ( '--masonry-layout-gap' , '1rem' ) ;
173- const columnWidthPx = this . calculateColumnWidth ( hostWidth , gapPx ) ;
174- const columnHeights = this . positionItems ( items , columnWidthPx , gapPx ) ;
175+ const rootFontSize = this . getRootFontSize ( ) ;
176+ const gapPx = this . getCssPropertyInPx (
177+ '--masonry-layout-gap' ,
178+ '1rem' ,
179+ rootFontSize ,
180+ ) ;
181+ const { columnCount, columnWidth } = this . calculateColumns (
182+ hostWidth ,
183+ gapPx ,
184+ rootFontSize ,
185+ ) ;
186+ const columnHeights = this . positionItems (
187+ items ,
188+ columnCount ,
189+ columnWidth ,
190+ gapPx ,
191+ rootFontSize ,
192+ ) ;
175193
176- const newHeight = this . pxToRem ( Math . max ( ...columnHeights ) - gapPx ) ;
194+ const newHeight = this . pxToRem (
195+ Math . max ( ...columnHeights ) - gapPx ,
196+ rootFontSize ,
197+ ) ;
177198 if ( Math . abs ( newHeight - this . containerHeight ) > 0.1 ) {
178199 this . containerHeight = newHeight ;
179200 }
180201 }
181202
182- private calculateColumnWidth ( hostWidth : number , gapPx : number ) : number {
203+ private calculateColumns (
204+ hostWidth : number ,
205+ gapPx : number ,
206+ rootFontSize : number ,
207+ ) : { columnCount : number ; columnWidth : number } {
183208 const minColumnWidthPx = this . getCssPropertyInPx (
184209 '--masonry-layout-min-column-width' ,
185- '12rem'
210+ '12rem' ,
211+ rootFontSize ,
186212 ) ;
187213
188214 const columnCount = Math . max (
189215 1 ,
190- Math . floor ( ( hostWidth + gapPx ) / ( minColumnWidthPx + gapPx ) )
216+ Math . floor ( ( hostWidth + gapPx ) / ( minColumnWidthPx + gapPx ) ) ,
191217 ) ;
218+ const columnWidth =
219+ ( hostWidth - ( columnCount - 1 ) * gapPx ) / columnCount ;
192220
193- return ( hostWidth - ( columnCount - 1 ) * gapPx ) / columnCount ;
221+ return { columnCount, columnWidth } ;
194222 }
195223
196224 /**
@@ -202,12 +230,11 @@ export class MasonryLayout {
202230 */
203231 private positionItems (
204232 items : HTMLElement [ ] ,
233+ columnCount : number ,
205234 columnWidth : number ,
206- gapPx : number
235+ gapPx : number ,
236+ rootFontSize : number ,
207237 ) : number [ ] {
208- const columnCount = Math . round (
209- ( this . host . offsetWidth + gapPx ) / ( columnWidth + gapPx )
210- ) ;
211238 const columnHeights = Array . from ( { length : columnCount } , ( ) => 0 ) ;
212239
213240 let index = 0 ;
@@ -220,10 +247,13 @@ export class MasonryLayout {
220247 const y = columnHeights [ column ] ;
221248
222249 item . style . position = 'absolute' ;
223- item . style . left = `${ this . pxToRem ( x ) } rem` ;
224- item . style . top = `${ this . pxToRem ( y ) } rem` ;
225- item . style . width = `${ this . pxToRem ( columnWidth ) } rem` ;
226- item . style . animationDelay = `${ index * 15 } ms` ;
250+ item . style . left = `${ this . pxToRem ( x , rootFontSize ) } rem` ;
251+ item . style . top = `${ this . pxToRem ( y , rootFontSize ) } rem` ;
252+ item . style . width = `${ this . pxToRem ( columnWidth , rootFontSize ) } rem` ;
253+
254+ if ( ! this . hasRendered ) {
255+ item . style . animationDelay = `${ index * 15 } ms` ;
256+ }
227257
228258 columnHeights [ column ] += item . offsetHeight + gapPx ;
229259 index ++ ;
0 commit comments