@@ -12,21 +12,25 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
1212import { masterDetailLayoutStyles } from './styles/vaadin-master-detail-layout-base-styles.js' ;
1313
1414function parseTrackSizes ( gridTemplate ) {
15- return gridTemplate
15+ const sizes = gridTemplate
1616 . replace ( / \[ [ ^ \] ] + \] / gu, '' )
1717 . replace ( / \s + / gu, ' ' )
1818 . trim ( )
1919 . split ( ' ' )
2020 . map ( parseFloat ) ;
21+ return {
22+ masterSize : sizes [ 0 ] ,
23+ masterExtra : sizes [ 1 ] ,
24+ detailSize : sizes [ 2 ] ,
25+ detailExtra : sizes [ 3 ] ,
26+ } ;
2127}
2228
23- function detectOverflow ( hostSize , trackSizes ) {
24- const [ masterSize , masterExtra , detailSize ] = trackSizes ;
25-
26- if ( Math . floor ( masterSize + masterExtra + detailSize ) <= Math . floor ( hostSize ) ) {
29+ function detectOverflow ( { hostSize, masterSize, masterExtra, detailSize, detailExtra } ) {
30+ if ( Math . floor ( masterSize + masterExtra + detailSize + detailExtra ) <= Math . floor ( hostSize ) ) {
2731 return false ;
2832 }
29- if ( Math . floor ( masterExtra ) >= Math . floor ( detailSize ) ) {
33+ if ( Math . floor ( masterExtra ) >= Math . floor ( detailSize + detailExtra ) ) {
3034 return false ;
3135 }
3236 return true ;
@@ -314,7 +318,7 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
314318 this . __resizeObserver = this . __resizeObserver || new ResizeObserver ( ( ) => this . __onResize ( ) ) ;
315319 this . __resizeObserver . disconnect ( ) ;
316320
317- const children = this . querySelectorAll ( ':scope > [slot="detail"], :scope >:not([slot])' ) ;
321+ const children = this . querySelectorAll ( ':scope > [slot="detail"], :scope > :not([slot])' ) ;
318322 [ this , this . $ . master , this . $ . detail , ...children ] . forEach ( ( node ) => {
319323 this . __resizeObserver . observe ( node ) ;
320324 } ) ;
@@ -340,7 +344,7 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
340344 __readLayoutState ( ) {
341345 const isVertical = this . orientation === 'vertical' ;
342346
343- const detailContent = this . querySelector ( '[slot="detail"]' ) ;
347+ const detailContent = this . querySelector ( ':scope > [slot="detail"]' ) ;
344348 const detailPlaceholder = this . querySelector ( ':scope > [slot="detail-placeholder"]' ) ;
345349
346350 const hadDetail = this . hasAttribute ( 'has-detail' ) ;
@@ -354,53 +358,53 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
354358 const trackSizesProp = isVertical ? 'gridTemplateRows' : 'gridTemplateColumns' ;
355359 const trackSizes = parseTrackSizes ( computedStyle [ trackSizesProp ] ) ;
356360
357- const hadOverflow = this . hasAttribute ( 'overlay' ) ;
358- const hasOverflow = ( hasDetail || hasDetailPlaceholder ) && detectOverflow ( hostSize , trackSizes ) ;
361+ let nestedLayoutSize = 0 ;
362+ if ( hasDetail && detailContent . matches ( this . constructor . is ) ) {
363+ const nestedLayout = detailContent . __readLayoutState ( ) ;
364+
365+ nestedLayoutSize += nestedLayout . trackSizes . masterSize ;
366+
367+ if ( nestedLayout . nestedLayoutSize > 0 ) {
368+ nestedLayoutSize += nestedLayout . nestedLayoutSize ;
369+ } else if ( nestedLayout . hasDetail ) {
370+ nestedLayoutSize += nestedLayout . trackSizes . detailSize ;
371+ }
372+ }
373+
374+ const hasOverflow =
375+ ( hasDetail || hasDetailPlaceholder ) &&
376+ detectOverflow ( {
377+ hostSize,
378+ masterSize : trackSizes . masterSize ,
379+ masterExtra : trackSizes . masterExtra ,
380+ detailSize : nestedLayoutSize > 0 ? nestedLayoutSize : trackSizes . detailSize ,
381+ detailExtra : trackSizes . detailExtra ,
382+ } ) ;
359383 const focusTarget = ! hadDetail && hasDetail && hasOverflow ? getFocusableElements ( detailContent ) [ 0 ] : null ;
360384
361385 return {
362386 hadDetail,
363387 hasDetail,
364388 hasDetailPlaceholder,
365- hadOverflow,
366389 hasOverflow,
367390 focusTarget,
368391 hostSize,
369392 trackSizes,
393+ nestedLayoutSize,
370394 } ;
371395 }
372396
373397 /**
374398 * Applies layout state to DOM attributes. Pure writes, no reads.
375399 * @private
376400 */
377- __writeLayoutState ( {
378- hadDetail,
379- hasDetail,
380- hasDetailPlaceholder,
381- hasOverflow,
382- hadOverflow,
383- focusTarget,
384- trackSizes,
385- } ) {
386- const [ _masterSize , _masterExtra , detailSize ] = trackSizes ;
387-
388- // If no detailSize is explicitily set, cache the intrinsic size (min-content) of
389- // the slotted detail content to use as a fallback for the detail column size
390- // while the detail content is rendered in an overlay.
391- if ( ! hadOverflow && hasOverflow && ! this . detailSize && ! this . __detailCachedSize ) {
392- this . __detailCachedSize = `${ Math . ceil ( detailSize ) } px` ;
401+ __writeLayoutState ( { hadDetail, hasDetail, hasDetailPlaceholder, hasOverflow, focusTarget, nestedLayoutSize } ) {
402+ if ( nestedLayoutSize > 0 ) {
403+ this . style . setProperty ( '--_nested-layout-size' , `${ nestedLayoutSize } px` ) ;
404+ } else {
405+ this . style . removeProperty ( '--_nested-layout-size' ) ;
393406 }
394407
395- if ( ( hadOverflow && ! hasOverflow ) || ( ! hasDetail && ! hasDetailPlaceholder ) ) {
396- this . __detailCachedSize = null ;
397- }
398- // if (!this.detailSize && !this.__detailCachedSize && hasDetail && detailSize > 0) {
399- // this.__detailCachedSize = `${Math.ceil(detailSize)}px`;
400- // } else if (hadDetail && !hasDetail) {
401- // this.__detailCachedSize = null;
402- // }
403-
404408 // Force the detail column offscreen when it first appears and overflow
405409 // is already detected. This prevents unnecessary master column shrinking,
406410 // as the detail content is rendered in an overlay anyway.
@@ -423,17 +427,6 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
423427 }
424428 }
425429
426- recalculateDetailSize ( ) {
427- this . __detailCachedSize = null ;
428- this . removeAttribute ( 'overlay' ) ;
429- this . toggleAttribute ( 'recalculating-detail-size' , true ) ;
430-
431- const { focusTarget, ...state } = this . __readLayoutState ( ) ;
432- this . __writeLayoutState ( state ) ;
433-
434- this . toggleAttribute ( 'recalculating-detail-size' , false ) ;
435- }
436-
437430 /** @private */
438431 __onBackdropClick ( ) {
439432 this . dispatchEvent ( new CustomEvent ( 'backdrop-click' ) ) ;
0 commit comments