Skip to content

Commit 1366305

Browse files
vursenclaude
andauthored
refactor: restore forceOverlay property (#11489)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ee5bb91 commit 1366305

11 files changed

Lines changed: 258 additions & 77 deletions

packages/master-detail-layout/src/styles/vaadin-master-detail-layout-base-styles.js

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,30 @@ export const masterDetailLayoutStyles = css`
4949
--_detail-size: var(--_detail-cached-size);
5050
--_detail-extra: 0px;
5151
--_detail-cached-size: min-content;
52+
53+
/* prettier-ignore */
54+
--_grid-template:
55+
[master-start] var(--_master-size) [master-extra] var(--_master-extra)
56+
[detail-start] var(--_detail-size) [detail-extra] var(--_detail-extra)
57+
[detail-end];
58+
}
59+
60+
:host([force-overlay]) {
61+
/* prettier-ignore */
62+
--_grid-template:
63+
[master-start] var(--_master-size) [master-extra] var(--_master-extra)
64+
[detail-start] 0px [detail-extra] 0px
65+
[detail-end];
5266
}
5367
5468
:host([orientation='horizontal']) {
55-
grid-template-columns:
56-
[master-start] var(--_master-size) [master-extra-start] var(--_master-extra)
57-
[detail-start] var(--_detail-size) [detail-extra-start] var(--_detail-extra) [detail-end];
69+
grid-template-columns: var(--_grid-template);
5870
grid-template-rows: 100%;
5971
}
6072
6173
:host([orientation='vertical']) {
6274
grid-template-columns: 100%;
63-
grid-template-rows:
64-
[master-start] var(--_master-size) [master-extra-start] var(--_master-extra)
65-
[detail-start] var(--_detail-size) [detail-extra-start] var(--_detail-extra) [detail-end];
75+
grid-template-rows: var(--_grid-template);
6676
}
6777
6878
/* CSS grid placement */
@@ -78,7 +88,7 @@ export const masterDetailLayoutStyles = css`
7888
min-content resolves to 0, making it impossible to measure the detail's intrinsic
7989
minimum width from JavaScript.
8090
*/
81-
--_detail-area: detail-start / detail-extra-start;
91+
--_detail-area: detail-start / detail-extra;
8292
}
8393
8494
:host(:is([has-detail], [has-detail-placeholder]):not([recalculating-detail-size])) {

packages/master-detail-layout/src/vaadin-master-detail-layout.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,15 @@ declare class MasterDetailLayout extends ThemableMixin(ElementMixin(HTMLElement)
161161
*/
162162
noAnimation: boolean;
163163

164+
/**
165+
* When true, the layout forces the detail area to be shown as an overlay,
166+
* even if there is enough space for master and detail to be shown next to
167+
* each other using the default (split) mode.
168+
*
169+
* @attr {boolean} force-overlay
170+
*/
171+
forceOverlay: boolean;
172+
164173
/**
165174
* When `detailSize` is not explicitly set, re-measures the cached intrinsic size of
166175
* the detail content by placing it in a min-content CSS grid column, then repeats

packages/master-detail-layout/src/vaadin-master-detail-layout.js

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
121121
detailSize: {
122122
type: String,
123123
sync: true,
124-
observer: '__detailSizeChanged',
125124
},
126125

127126
/**
@@ -135,7 +134,6 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
135134
masterSize: {
136135
type: String,
137136
sync: true,
138-
observer: '__masterSizeChanged',
139137
},
140138

141139
/**
@@ -162,7 +160,6 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
162160
value: 'horizontal',
163161
reflectToAttribute: true,
164162
sync: true,
165-
observer: '__orientationChanged',
166163
},
167164

168165
/**
@@ -219,6 +216,20 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
219216
reflectToAttribute: true,
220217
},
221218

219+
/**
220+
* When true, the layout forces the detail area to be shown as an overlay,
221+
* even if there is enough space for master and detail to be shown next to
222+
* each other using the default (split) mode.
223+
*
224+
* @attr {boolean} force-overlay
225+
*/
226+
forceOverlay: {
227+
type: Boolean,
228+
value: false,
229+
reflectToAttribute: true,
230+
sync: true,
231+
},
232+
222233
/** @private */
223234
__detailCachedSize: {
224235
type: String,
@@ -287,27 +298,24 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
287298
cancelAnimations(this);
288299
}
289300

290-
/** @private */
291-
__masterSizeChanged(size, oldSize) {
292-
this.style.setProperty('--_master-size', size);
301+
/** @protected */
302+
updated(props) {
303+
super.updated(props);
293304

294-
if (oldSize != null) {
295-
this.recalculateLayout();
305+
if (props.has('masterSize')) {
306+
this.style.setProperty('--_master-size', this.masterSize);
296307
}
297-
}
298308

299-
/** @private */
300-
__detailSizeChanged(size, oldSize) {
301-
this.style.setProperty('--_detail-size', size);
302-
303-
if (oldSize != null) {
304-
this.recalculateLayout();
309+
if (props.has('detailSize')) {
310+
this.style.setProperty('--_detail-size', this.detailSize);
305311
}
306-
}
307312

308-
/** @private */
309-
__orientationChanged(_orientation, oldOrientation) {
310-
if (oldOrientation != null) {
313+
if (
314+
(props.has('masterSize') && props.get('masterSize') != null) ||
315+
(props.has('detailSize') && props.get('detailSize') != null) ||
316+
(props.has('orientation') && props.get('orientation') != null) ||
317+
(props.has('forceOverlay') && props.get('forceOverlay') != null)
318+
) {
311319
this.recalculateLayout();
312320
}
313321
}
@@ -375,7 +383,8 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
375383
const trackSizesProp = isVertical ? 'gridTemplateRows' : 'gridTemplateColumns';
376384
const trackSizes = parseTrackSizes(computedStyle[trackSizesProp]);
377385

378-
const hasOverflow = (hasDetail || hasDetailPlaceholder) && detectOverflow(hostSize, trackSizes);
386+
const hasOverflow =
387+
(hasDetail || hasDetailPlaceholder) && (this.forceOverlay || detectOverflow(hostSize, trackSizes));
379388
const focusTarget = !hadDetail && hasDetail && hasOverflow ? getFocusableElements(slottedDetail)[0] : null;
380389

381390
return {

packages/master-detail-layout/test/detail-auto-size.test.js

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,47 +16,6 @@ describe('detail auto size', () => {
1616
return layout.style.getPropertyValue('--_detail-cached-size');
1717
}
1818

19-
describe('basic', () => {
20-
let spy;
21-
22-
beforeEach(async () => {
23-
layout = fixtureSync(`
24-
<vaadin-master-detail-layout master-size="200px" detail-size="200px" orientation="horizontal">
25-
<div>Master</div>
26-
<div slot="detail">Detail</div>
27-
</vaadin-master-detail-layout>
28-
`);
29-
spy = sinon.spy(layout, 'recalculateLayout');
30-
await onceResized(layout);
31-
});
32-
33-
it('should not be called when masterSize, detailSize and orientation are provided initially', () => {
34-
expect(spy).to.not.be.called;
35-
});
36-
37-
it('should be called when masterSize is changed after initial render', () => {
38-
layout.masterSize = '200px';
39-
layout.masterSize = '300px';
40-
expect(spy).to.be.calledOnce;
41-
});
42-
43-
it('should be called when detailSize is changed after initial render', () => {
44-
layout.detailSize = '200px';
45-
layout.detailSize = '300px';
46-
expect(spy).to.be.calledOnce;
47-
});
48-
49-
it('should be called when orientation is changed after initial render', () => {
50-
layout.orientation = 'vertical';
51-
expect(spy).to.be.calledOnce;
52-
});
53-
54-
it('should not throw when called on a disconnected element', () => {
55-
layout.parentElement.removeChild(layout);
56-
expect(() => layout.recalculateLayout()).to.not.throw();
57-
});
58-
});
59-
6019
describe('Lit element detail', () => {
6120
const detailElementTag = defineCE(
6221
class extends LitElement {

packages/master-detail-layout/test/dom/__snapshots__/master-detail-layout.test.snap.js

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ snapshots["vaadin-master-detail-layout host masterSize and detailSize"] =
5656
`;
5757
/* end snapshot vaadin-master-detail-layout host masterSize and detailSize */
5858

59-
snapshots["vaadin-master-detail-layout host expandMaster"] =
59+
snapshots["vaadin-master-detail-layout host expandMaster"] =
6060
`<vaadin-master-detail-layout
6161
expand-master=""
6262
has-master=""
@@ -70,7 +70,7 @@ snapshots["vaadin-master-detail-layout host expandMaster"] =
7070
`;
7171
/* end snapshot vaadin-master-detail-layout host expandMaster */
7272

73-
snapshots["vaadin-master-detail-layout host expandDetail"] =
73+
snapshots["vaadin-master-detail-layout host expandDetail"] =
7474
`<vaadin-master-detail-layout
7575
expand-detail=""
7676
has-master=""
@@ -84,7 +84,7 @@ snapshots["vaadin-master-detail-layout host expandDetail"] =
8484
`;
8585
/* end snapshot vaadin-master-detail-layout host expandDetail */
8686

87-
snapshots["vaadin-master-detail-layout shadow default"] =
87+
snapshots["vaadin-master-detail-layout shadow default"] =
8888
`<div
8989
id="backdrop"
9090
part="backdrop"
@@ -195,6 +195,27 @@ snapshots["vaadin-master-detail-layout detail removed"] =
195195
`;
196196
/* end snapshot vaadin-master-detail-layout detail removed */
197197

198+
snapshots["vaadin-master-detail-layout detail forceOverlay"] =
199+
`<vaadin-master-detail-layout
200+
force-overlay=""
201+
has-detail=""
202+
has-master=""
203+
master-size="300px"
204+
orientation="horizontal"
205+
overlay=""
206+
overlay-containment="layout"
207+
style="--_master-size: 300px;"
208+
>
209+
<div>
210+
Master content
211+
</div>
212+
<div slot="detail">
213+
Detail content
214+
</div>
215+
</vaadin-master-detail-layout>
216+
`;
217+
/* end snapshot vaadin-master-detail-layout detail forceOverlay */
218+
198219
snapshots["vaadin-master-detail-layout detail placeholder default"] =
199220
`<vaadin-master-detail-layout
200221
has-detail-placeholder=""
@@ -256,7 +277,7 @@ snapshots["vaadin-master-detail-layout nested layouts default"] =
256277
orientation="horizontal"
257278
overlay-containment="layout"
258279
overlay-size="100px"
259-
style="--_master-size: 100px; --_overlay-size: 100px; --_detail-cached-size: 501px;"
280+
style="--_overlay-size: 100px; --_master-size: 100px; --_detail-cached-size: 501px;"
260281
>
261282
<div>
262283
Master 0
@@ -270,7 +291,7 @@ snapshots["vaadin-master-detail-layout nested layouts default"] =
270291
overlay-containment="layout"
271292
overlay-size="100px"
272293
slot="detail"
273-
style="--_master-size: 100px; --_detail-size: 400px; --_overlay-size: 100px;"
294+
style="--_overlay-size: 100px; --_master-size: 100px; --_detail-size: 400px;"
274295
>
275296
<div>
276297
Master 1
@@ -283,7 +304,7 @@ snapshots["vaadin-master-detail-layout nested layouts default"] =
283304
overlay-containment="layout"
284305
overlay-size="100px"
285306
slot="detail"
286-
style="--_master-size: 100px; --_overlay-size: 100px; --_detail-cached-size: 201px;"
307+
style="--_overlay-size: 100px; --_master-size: 100px; --_detail-cached-size: 201px;"
287308
>
288309
<div>
289310
Master 2
@@ -321,7 +342,7 @@ snapshots["vaadin-master-detail-layout nested layouts overflow"] =
321342
overlay=""
322343
overlay-containment="layout"
323344
overlay-size="100px"
324-
style="--_master-size: 100px; --_overlay-size: 100px; width: 200px; --_detail-cached-size: 501px;"
345+
style="--_overlay-size: 100px; --_master-size: 100px; width: 200px; --_detail-cached-size: 501px;"
325346
>
326347
<div>
327348
Master 0
@@ -337,7 +358,7 @@ snapshots["vaadin-master-detail-layout nested layouts overflow"] =
337358
overlay-containment="layout"
338359
overlay-size="100px"
339360
slot="detail"
340-
style="--_master-size: 100px; --_detail-size: 400px; --_overlay-size: 100px;"
361+
style="--_overlay-size: 100px; --_master-size: 100px; --_detail-size: 400px;"
341362
>
342363
<div>
343364
Master 1
@@ -352,7 +373,7 @@ snapshots["vaadin-master-detail-layout nested layouts overflow"] =
352373
overlay-containment="layout"
353374
overlay-size="100px"
354375
slot="detail"
355-
style="--_master-size: 100px; --_overlay-size: 100px; --_detail-cached-size: 201px;"
376+
style="--_overlay-size: 100px; --_master-size: 100px; --_detail-cached-size: 201px;"
356377
>
357378
<div>
358379
Master 2
@@ -382,3 +403,73 @@ snapshots["vaadin-master-detail-layout nested layouts overflow"] =
382403
`;
383404
/* end snapshot vaadin-master-detail-layout nested layouts overflow */
384405

406+
snapshots["vaadin-master-detail-layout nested layouts forceOverlay on child"] =
407+
`<vaadin-master-detail-layout
408+
has-detail=""
409+
has-master=""
410+
master-size="100px"
411+
orientation="horizontal"
412+
overlay-containment="layout"
413+
overlay-size="100px"
414+
style="--_overlay-size: 100px; --_master-size: 100px; --_detail-cached-size: 101px;"
415+
>
416+
<div>
417+
Master 0
418+
</div>
419+
<vaadin-master-detail-layout
420+
detail-size="400px"
421+
force-overlay=""
422+
has-detail=""
423+
has-master=""
424+
keep-detail-column-offscreen=""
425+
master-size="100px"
426+
orientation="horizontal"
427+
overlay=""
428+
overlay-containment="layout"
429+
overlay-size="100px"
430+
slot="detail"
431+
style="--_overlay-size: 100px; --_master-size: 100px; --_detail-size: 400px;"
432+
>
433+
<div>
434+
Master 1
435+
</div>
436+
<vaadin-master-detail-layout
437+
has-detail=""
438+
has-master=""
439+
keep-detail-column-offscreen=""
440+
master-size="100px"
441+
orientation="horizontal"
442+
overlay=""
443+
overlay-containment="layout"
444+
overlay-size="100px"
445+
slot="detail"
446+
style="--_overlay-size: 100px; --_master-size: 100px; --_detail-cached-size: 201px;"
447+
>
448+
<div>
449+
Master 2
450+
</div>
451+
<vaadin-master-detail-layout
452+
detail-size="100px"
453+
has-detail=""
454+
has-master=""
455+
keep-detail-column-offscreen=""
456+
master-size="100px"
457+
orientation="horizontal"
458+
overlay=""
459+
overlay-containment="layout"
460+
slot="detail"
461+
style="--_master-size: 100px; --_detail-size: 100px;"
462+
>
463+
<div>
464+
Master 3
465+
</div>
466+
<div slot="detail">
467+
Detail
468+
</div>
469+
</vaadin-master-detail-layout>
470+
</vaadin-master-detail-layout>
471+
</vaadin-master-detail-layout>
472+
</vaadin-master-detail-layout>
473+
`;
474+
/* end snapshot vaadin-master-detail-layout nested layouts forceOverlay on child */
475+

0 commit comments

Comments
 (0)