Skip to content

Commit 518e64f

Browse files
authored
feat!: use stackOverlay property instead of stackThreshold (#9052)
1 parent b51204b commit 518e64f

File tree

6 files changed

+73
-88
lines changed

6 files changed

+73
-88
lines changed

dev/master-detail-layout.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<vaadin-checkbox id="maxWidth" label="Use max-width on the host"></vaadin-checkbox>
4040
<vaadin-checkbox id="maxHeight" label="Use max-height on the host"></vaadin-checkbox>
4141
<vaadin-checkbox id="forceOverlay" label="Force overlay"></vaadin-checkbox>
42-
<vaadin-checkbox id="stack" label="Set stack threshold"></vaadin-checkbox>
42+
<vaadin-checkbox id="stack" label="Use stack mode"></vaadin-checkbox>
4343
<button id="set-small-detail">Set small detail</button>
4444
<button id="set-large-detail">Set large detail</button>
4545
<button id="clear-detail">Clear detail</button>
@@ -117,7 +117,7 @@
117117
});
118118

119119
document.querySelector('#stack').addEventListener('change', (e) => {
120-
layout.stackThreshold = e.target.checked ? '600px' : null;
120+
layout.stackOverlay = e.target.checked;
121121
});
122122

123123
document.querySelector('#set-small-detail').addEventListener('click', () => {

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ declare class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ThemableMix
9696
* there is enough space for master and detail to be shown next to
9797
* each other using the default (split) mode.
9898
*
99+
* In order to enforce the stack mode, use this property together with
100+
* `stackOverlay` property and set both to `true`.
101+
*
99102
* @attr {boolean} force-overlay
100103
*/
101104
forceOverlay: boolean;
@@ -109,12 +112,15 @@ declare class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ThemableMix
109112
containment: 'layout' | 'viewport';
110113

111114
/**
112-
* The threshold (in CSS length units) at which the layout switches to
113-
* the "stack" mode, making detail area fully cover the master area.
115+
* When true, the layout in the overlay mode is rendered as a "stack",
116+
* making detail area fully cover the master area.
117+
*
118+
* In order to enforce the stack mode, use this property together with
119+
* `forceOverlay` property and set both to `true`.
114120
*
115121
* @attr {string} stack-threshold
116122
*/
117-
stackThreshold: string | null | undefined;
123+
stackOverlay: boolean;
118124

119125
/**
120126
* When true, the layout does not use animated transitions for the detail area.

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

Lines changed: 27 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,6 @@ class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ElementMixin(Themab
207207
:host([stack]) [part='detail'] {
208208
inset: 0;
209209
}
210-
211-
[part='master']::before {
212-
background-position-y: var(--_stack-threshold);
213-
}
214210
`;
215211
}
216212

@@ -291,6 +287,9 @@ class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ElementMixin(Themab
291287
* there is enough space for master and detail to be shown next to
292288
* each other using the default (split) mode.
293289
*
290+
* In order to enforce the stack mode, use this property together with
291+
* `stackOverlay` property and set both to `true`.
292+
*
294293
* @attr {boolean} force-overlay
295294
*/
296295
forceOverlay: {
@@ -314,14 +313,18 @@ class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ElementMixin(Themab
314313
},
315314

316315
/**
317-
* The threshold (in CSS length units) at which the layout switches to
318-
* the "stack" mode, making detail area fully cover the master area.
316+
* When true, the layout in the overlay mode is rendered as a "stack",
317+
* making detail area fully cover the master area.
318+
*
319+
* In order to enforce the stack mode, use this property together with
320+
* `forceOverlay` property and set both to `true`.
319321
*
320322
* @attr {string} stack-threshold
321323
*/
322-
stackThreshold: {
323-
type: String,
324-
observer: '__stackThresholdChanged',
324+
stackOverlay: {
325+
type: Boolean,
326+
value: false,
327+
observer: '__stackOverlayChanged',
325328
sync: true,
326329
},
327330

@@ -337,7 +340,6 @@ class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ElementMixin(Themab
337340

338341
/**
339342
* When true, the component uses the overlay mode. This property is read-only.
340-
* In order to enforce the overlay mode, use `forceOverlay` property.
341343
* @protected
342344
*/
343345
_overlay: {
@@ -349,7 +351,6 @@ class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ElementMixin(Themab
349351

350352
/**
351353
* When true, the component uses the stack mode. This property is read-only.
352-
* In order to enforce the stack mode, use `stackThreshold` property.
353354
* @protected
354355
*/
355356
_stack: {
@@ -463,14 +464,8 @@ class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ElementMixin(Themab
463464
}
464465

465466
/** @private */
466-
__stackThresholdChanged(threshold, oldThreshold) {
467-
if (threshold || oldThreshold) {
468-
if (threshold) {
469-
this.$.master.style.setProperty('--_stack-threshold', threshold);
470-
} else {
471-
this.$.master.style.removeProperty('--_stack-threshold');
472-
}
473-
467+
__stackOverlayChanged(stackOverlay, oldStackOverlay) {
468+
if (stackOverlay || oldStackOverlay) {
474469
this.__detectLayoutMode();
475470
}
476471
}
@@ -486,30 +481,25 @@ class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ElementMixin(Themab
486481
this.toggleAttribute(`has-${prop}`, !!size);
487482
}
488483

484+
/** @private */
485+
__setOverlayMode(value) {
486+
if (this.stackOverlay) {
487+
this._stack = value;
488+
} else {
489+
this._overlay = value;
490+
}
491+
}
492+
489493
/** @private */
490494
__detectLayoutMode() {
491495
this._overlay = false;
492496
this._stack = false;
493497

494498
if (this.forceOverlay) {
495-
this._overlay = true;
499+
this.__setOverlayMode(true);
496500
return;
497501
}
498502

499-
if (this.stackThreshold != null) {
500-
// Set stack to true to disable masterMinSize and detailMinSize
501-
// that would affect size measurements below when in split mode
502-
this._stack = true;
503-
504-
const threshold = this.__getStackThresholdInPixels();
505-
const size = this.orientation === 'vertical' ? this.offsetHeight : this.offsetWidth;
506-
if (size > threshold) {
507-
this._stack = false;
508-
} else {
509-
return;
510-
}
511-
}
512-
513503
if (!this._hasDetail) {
514504
return;
515505
}
@@ -535,38 +525,28 @@ class MasterDetailLayout extends SlotStylesMixin(ResizeMixin(ElementMixin(Themab
535525

536526
// If the combined minimum size of both the master and the detail content
537527
// exceeds the size of the layout, the layout changes to the overlay mode.
538-
this._overlay = this.offsetWidth < masterWidth + detailWidth;
528+
this.__setOverlayMode(this.offsetWidth < masterWidth + detailWidth);
539529

540530
// Toggling the overlay resizes master content, which can cause document
541531
// scroll bar to appear or disappear, and trigger another resize of the
542532
// layout which can affect previous measurements and end up in horizontal
543533
// scroll. Check if that is the case and if so, preserve the overlay mode.
544534
if (this.offsetWidth < this.scrollWidth) {
545-
this._overlay = true;
535+
this.__setOverlayMode(true);
546536
}
547537
}
548538

549539
/** @private */
550540
__detectVerticalMode() {
551-
// Remove overlay attribute temporarily to detect if there is enough space
552-
// for both areas so that layout could switch back to the split mode.
553-
this._overlay = false;
554-
555541
const masterHeight = this.$.master.clientHeight;
556542

557543
// If the combined minimum size of both the master and the detail content
558544
// exceeds the available height, the layout changes to the overlay mode.
559545
if (this.offsetHeight < masterHeight + this.$.detail.clientHeight) {
560-
this._overlay = true;
546+
this.__setOverlayMode(true);
561547
}
562548
}
563549

564-
/** @private */
565-
__getStackThresholdInPixels() {
566-
const { backgroundPositionY } = getComputedStyle(this.$.master, '::before');
567-
return parseFloat(backgroundPositionY);
568-
}
569-
570550
/**
571551
* Sets the detail element to be displayed in the detail area and starts a
572552
* view transition that animates adding, replacing or removing the detail

packages/master-detail-layout/test/aria.test.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect } from '@vaadin/chai-plugins';
2-
import { fixtureSync, nextRender, nextResize } from '@vaadin/testing-helpers';
2+
import { fixtureSync, nextRender } from '@vaadin/testing-helpers';
33
import '../src/vaadin-master-detail-layout.js';
44
import './helpers/master-content.js';
55
import './helpers/detail-content.js';
@@ -31,15 +31,12 @@ describe('ARIA', () => {
3131
expect(detail.hasAttribute('role')).to.be.false;
3232
});
3333

34-
it('should set role to dialog on the detail part in the stack mode', async () => {
35-
layout.stackThreshold = '500px';
36-
layout.style.width = '500px';
37-
await nextResize(layout);
38-
34+
it('should set role to dialog on the detail part in the stack mode', () => {
35+
layout.forceOverlay = true;
36+
layout.stackOverlay = true;
3937
expect(detail.getAttribute('role')).to.equal('dialog');
4038

41-
layout.style.width = '600px';
42-
await nextResize(layout);
39+
layout.forceOverlay = false;
4340

4441
expect(detail.hasAttribute('role')).to.be.false;
4542
});

0 commit comments

Comments
 (0)