Skip to content

Commit 38715b9

Browse files
web-padawanclaude
andauthored
refactor: rename MDL overflow attribute to overlay (#11407)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 391552e commit 38715b9

File tree

9 files changed

+62
-62
lines changed

9 files changed

+62
-62
lines changed

packages/aura/src/components/master-detail-layout.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ vaadin-master-detail-layout::part(detail) {
33
background: var(--aura-surface-color) padding-box;
44
}
55

6-
vaadin-master-detail-layout[overflow]::part(detail) {
6+
vaadin-master-detail-layout[overlay]::part(detail) {
77
--aura-surface-opacity: var(--aura-overlay-surface-opacity);
88
background: var(--aura-surface-color) padding-box;
99
-webkit-backdrop-filter: var(--aura-overlay-backdrop-filter);
@@ -14,19 +14,19 @@ vaadin-master-detail-layout[overflow]::part(detail) {
1414
var(--aura-shadow-m);
1515
}
1616

17-
vaadin-master-detail-layout[overflow][overlay-containment='viewport']::part(detail) {
17+
vaadin-master-detail-layout[overlay][overlay-containment='viewport']::part(detail) {
1818
box-shadow: var(--aura-overlay-shadow);
1919
}
2020

2121
/* TODO could be a built-in variant */
22-
vaadin-master-detail-layout[theme~='inset-drawer'][overflow]::part(detail),
23-
vaadin-master-detail-layout[overflow][overlay-containment='viewport']::part(detail) {
22+
vaadin-master-detail-layout[theme~='inset-drawer'][overlay]::part(detail),
23+
vaadin-master-detail-layout[overlay][overlay-containment='viewport']::part(detail) {
2424
margin: calc(var(--aura-app-layout-inset) / 2);
2525
border-radius: var(--_app-layout-radius);
2626
}
2727

2828
vaadin-master-detail-layout > vaadin-master-detail-layout,
29-
vaadin-master-detail-layout:not([overflow])::part(detail) {
29+
vaadin-master-detail-layout:not([overlay])::part(detail) {
3030
border-start-end-radius: var(--_app-layout-radius);
3131
border-end-end-radius: var(--_app-layout-radius);
3232
}

packages/master-detail-layout/ARCHITECTURE.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ The `>=` (not `>`) is intentional: when `keep-detail-column-offscreen` or `:not(
5454
Layout detection is split into two methods to avoid forced reflows:
5555

5656
- **`__computeLayoutState()`** — pure reads: `checkVisibility()`, `getComputedStyle()`, `getFocusableElements()`. Called in the ResizeObserver callback where layout is already computed — no forced reflow.
57-
- **`__applyLayoutState(state)`** — pure writes: toggles `has-detail`, `overflow`, `keep-detail-column-offscreen`; calls `requestUpdate()` for ARIA; focuses detail. No DOM/style reads.
57+
- **`__applyLayoutState(state)`** — pure writes: toggles `has-detail`, `overlay`, `keep-detail-column-offscreen`; calls `requestUpdate()` for ARIA; focuses detail. No DOM/style reads.
5858

5959
### ResizeObserver
6060

@@ -64,7 +64,7 @@ Layout detection is split into two methods to avoid forced reflows:
6464

6565
## Overlay Modes
6666

67-
When `overflow` AND `has-detail` are both set, the detail becomes an overlay:
67+
When `overlay` AND `has-detail` are both set, the detail becomes an overlay:
6868

6969
- `position: absolute; grid-column: none` removes detail from grid flow
7070
- Backdrop becomes visible
@@ -85,7 +85,7 @@ Setting `overlaySize` to `100%` makes the detail cover the full layout (replaces
8585

8686
Prevents the master from jumping when the detail overlay first appears.
8787

88-
When no detail is present, master's extra track is set to `calc(100% - masterSize)`, pushing the detail column offscreen. This ensures that when a detail element appears, it starts offscreen and is then either moved into an overlay (if overflow, so no blink occurs and master area size is preserved) or revealed by removing the `calc()` override (if no overflow). The `keep-detail-column-offscreen` attribute keeps the same override active when detail first appears with overflow, until the overlay takes effect.
88+
When no detail is present, master's extra track is set to `calc(100% - masterSize)`, pushing the detail column offscreen. This ensures that when a detail element appears, it starts offscreen and is then either moved into an overlay (if `overlay` is set, so no blink occurs and master area size is preserved) or revealed by removing the `calc()` override (if no overlay). The `keep-detail-column-offscreen` attribute keeps the same override active when detail first appears with overlay, until the overlay takes effect.
8989

9090
```css
9191
:host(:not([has-detail])),
@@ -94,7 +94,7 @@ When no detail is present, master's extra track is set to `calc(100% - masterSiz
9494
}
9595
```
9696

97-
Set when detail first appears with overflow, cleared when detail is removed or overflow resolves.
97+
Set when detail first appears with overlay, cleared when detail is removed or overlay resolves.
9898

9999
## Detail Animations
100100

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ export const masterDetailLayoutStyles = css`
8888
--_detail-column: var(--_detail-size) 1fr;
8989
}
9090
91-
:host([orientation='horizontal'][has-detail]:not([overflow])) #detail {
91+
:host([orientation='horizontal'][has-detail]:not([overlay])) #detail {
9292
border-inline-start: var(--vaadin-master-detail-layout-border-width, 1px) solid
9393
var(--vaadin-master-detail-layout-border-color, var(--vaadin-border-color-secondary));
9494
}
9595
96-
:host([orientation='vertical'][has-detail]:not([overflow])) #detail {
96+
:host([orientation='vertical'][has-detail]:not([overlay])) #detail {
9797
border-top: var(--vaadin-master-detail-layout-border-width, 1px) solid
9898
var(--vaadin-master-detail-layout-border-color, var(--vaadin-border-color-secondary));
9999
}
@@ -119,47 +119,47 @@ export const masterDetailLayoutStyles = css`
119119
z-index: 1;
120120
}
121121
122-
:host([overflow]) {
122+
:host([overlay]) {
123123
--_detail-offscreen: calc((100% + 30px) * var(--_rtl-multiplier));
124124
}
125125
126-
:host([overflow][orientation='vertical']) {
126+
:host([overlay][orientation='vertical']) {
127127
--_detail-offscreen: 0 calc(100% + 30px);
128128
}
129129
130-
:host([overflow]) :is(#detail, #outgoing) {
130+
:host([overlay]) :is(#detail, #outgoing) {
131131
position: absolute;
132132
z-index: 2;
133133
background: var(--vaadin-master-detail-layout-detail-background, var(--vaadin-background-color));
134134
box-shadow: var(--vaadin-master-detail-layout-detail-shadow, 0 0 20px 0 rgba(0, 0, 0, 0.3));
135135
grid-column: none;
136136
}
137137
138-
:host([overflow]) [part~='backdrop'] {
138+
:host([overlay]) [part~='backdrop'] {
139139
display: block;
140140
}
141141
142-
:host([overflow]:not([orientation='vertical'])) :is(#detail, #outgoing) {
142+
:host([overlay]:not([orientation='vertical'])) :is(#detail, #outgoing) {
143143
inset-block: 0;
144144
width: var(--_overlay-size, var(--_detail-size, min-content));
145145
inset-inline-end: 0;
146146
}
147147
148-
:host([overflow][orientation='vertical']) :is(#detail, #outgoing) {
148+
:host([overlay][orientation='vertical']) :is(#detail, #outgoing) {
149149
grid-column: auto;
150150
grid-row: none;
151151
inset-inline: 0;
152152
height: var(--_overlay-size, var(--_detail-size, min-content));
153153
inset-block-end: 0;
154154
}
155155
156-
:host([overflow][overlay-containment='viewport']) :is(#detail, #outgoing),
157-
:host([overflow][overlay-containment='viewport']) [part~='backdrop'] {
156+
:host([overlay][overlay-containment='viewport']) :is(#detail, #outgoing),
157+
:host([overlay][overlay-containment='viewport']) [part~='backdrop'] {
158158
position: fixed;
159159
}
160160
161161
@media (forced-colors: active) {
162-
:host([overflow]) :is(#detail, #outgoing) {
162+
:host([overlay]) :is(#detail, #outgoing) {
163163
outline: 3px solid !important;
164164
}
165165
@@ -174,7 +174,7 @@ export const masterDetailLayoutStyles = css`
174174
--_transition-duration: 200ms;
175175
}
176176
177-
:host([overflow]:not([no-animation])) {
177+
:host([overlay]:not([no-animation])) {
178178
--_transition-duration: 300ms;
179179
}
180180
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export interface MasterDetailLayoutEventMap extends HTMLElementEventMap, MasterD
3636
* `expand` | Set to `master`, `detail`, or `both`.
3737
* `orientation` | Set to `horizontal` or `vertical` depending on the orientation.
3838
* `has-detail` | Set when the detail content is provided and visible.
39-
* `overflow` | Set when columns don't fit and the detail is shown as an overlay.
39+
* `overlay` | Set when columns don't fit and the detail is shown as an overlay.
4040
* `overlay-containment` | Set to `layout` or `viewport`.
4141
*
4242
* The following custom CSS properties are available for styling:

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function parseTrackSizes(gridTemplate) {
4242
* `expand` | Set to `master`, `detail`, or `both`.
4343
* `orientation` | Set to `horizontal` or `vertical` depending on the orientation.
4444
* `has-detail` | Set when the detail content is provided and visible.
45-
* `overflow` | Set when columns don't fit and the detail is shown as an overlay.
45+
* `overlay` | Set when columns don't fit and the detail is shown as an overlay.
4646
* `overlay-containment` | Set to `layout` or `viewport`.
4747
*
4848
* The following custom CSS properties are available for styling:
@@ -182,7 +182,7 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
182182

183183
/** @protected */
184184
render() {
185-
const isOverlay = this.hasAttribute('has-detail') && this.hasAttribute('overflow');
185+
const isOverlay = this.hasAttribute('has-detail') && this.hasAttribute('overlay');
186186
const isViewport = isOverlay && this.overlayContainment === 'viewport';
187187
const isLayoutContained = isOverlay && !isViewport;
188188

@@ -290,7 +290,7 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
290290
* @private
291291
*/
292292
__applyLayoutState({ hadDetail, hasDetail, hasOverflow, focusTarget }) {
293-
// Set keep-detail-column-offscreen when detail first appears with overflow
293+
// Set keep-detail-column-offscreen when detail first appears with overlay
294294
// to prevent master width from jumping.
295295
if (!hadDetail && hasDetail && hasOverflow) {
296296
this.setAttribute('keep-detail-column-offscreen', '');
@@ -299,10 +299,10 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
299299
}
300300

301301
this.toggleAttribute('has-detail', hasDetail);
302-
this.toggleAttribute('overflow', hasOverflow);
302+
this.toggleAttribute('overlay', hasOverflow);
303303

304304
// Re-render to update ARIA attributes (role, aria-modal, inert)
305-
// which depend on has-detail and overflow state.
305+
// which depend on has-detail and overlay state.
306306
this.requestUpdate();
307307

308308
if (focusTarget) {
@@ -434,7 +434,7 @@ class MasterDetailLayout extends ElementMixin(ThemableMixin(PolylitMixin(LitElem
434434

435435
const opts = this.__getAnimationParams();
436436
opts.interrupted = interrupted;
437-
opts.overlay = this.hasAttribute('overflow');
437+
opts.overlay = this.hasAttribute('overlay');
438438

439439
return this.__animateTransition(transitionType, opts, updateCallback);
440440
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('ARIA', () => {
2525
});
2626

2727
it('should set role="dialog" on detail in overlay mode', () => {
28-
expect(layout.hasAttribute('overflow')).to.be.true;
28+
expect(layout.hasAttribute('overlay')).to.be.true;
2929
expect(detail.getAttribute('role')).to.equal('dialog');
3030
});
3131

packages/master-detail-layout/test/overflow.test.js renamed to packages/master-detail-layout/test/overlay-detection.test.js

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ window.Vaadin ||= {};
77
window.Vaadin.featureFlags ||= {};
88
window.Vaadin.featureFlags.masterDetailLayoutComponent = true;
99

10-
describe('overflow detection', () => {
10+
describe('overlay detection', () => {
1111
describe('horizontal', () => {
1212
let layout;
1313

@@ -22,65 +22,65 @@ describe('overflow detection', () => {
2222
});
2323

2424
describe('layout resize', () => {
25-
it('should not set overflow when columns fit within the layout', () => {
26-
expect(layout.hasAttribute('overflow')).to.be.false;
25+
it('should not set overlay when columns fit within the layout', () => {
26+
expect(layout.hasAttribute('overlay')).to.be.false;
2727
});
2828

29-
it('should set overflow when layout size is decreased below column minimums', async () => {
29+
it('should set overlay when layout size is decreased below column minimums', async () => {
3030
layout.style.width = '400px';
3131
await onceResized(layout);
32-
expect(layout.hasAttribute('overflow')).to.be.true;
32+
expect(layout.hasAttribute('overlay')).to.be.true;
3333
});
3434

35-
it('should remove overflow when layout size is increased to fit columns', async () => {
35+
it('should remove overlay when layout size is increased to fit columns', async () => {
3636
layout.style.width = '400px';
3737
await onceResized(layout);
38-
expect(layout.hasAttribute('overflow')).to.be.true;
38+
expect(layout.hasAttribute('overlay')).to.be.true;
3939

4040
layout.style.width = '800px';
4141
await onceResized(layout);
42-
expect(layout.hasAttribute('overflow')).to.be.false;
42+
expect(layout.hasAttribute('overlay')).to.be.false;
4343
});
4444
});
4545

4646
describe('property changes', () => {
47-
it('should set overflow when masterSize increases beyond available space', async () => {
47+
it('should set overlay when masterSize increases beyond available space', async () => {
4848
layout.masterSize = '600px';
4949
await onceResized(layout);
50-
expect(layout.hasAttribute('overflow')).to.be.true;
50+
expect(layout.hasAttribute('overlay')).to.be.true;
5151
});
5252

53-
it('should remove overflow when masterSize decreases to fit', async () => {
53+
it('should remove overlay when masterSize decreases to fit', async () => {
5454
layout.style.width = '400px';
5555
await onceResized(layout);
5656

5757
layout.masterSize = '100px';
5858
await onceResized(layout);
59-
expect(layout.hasAttribute('overflow')).to.be.false;
59+
expect(layout.hasAttribute('overlay')).to.be.false;
6060
});
6161

62-
it('should remove overflow when masterSize decreases to fit while keep-detail-column-offscreen is set', async () => {
62+
it('should remove overlay when masterSize decreases to fit while keep-detail-column-offscreen is set', async () => {
6363
layout.style.width = '400px';
6464
await onceResized(layout);
6565

6666
layout.masterSize = '50px';
6767
await onceResized(layout);
68-
expect(layout.hasAttribute('overflow')).to.be.false;
68+
expect(layout.hasAttribute('overlay')).to.be.false;
6969
});
7070

71-
it('should set overflow when masterSize is set to 100%', async () => {
71+
it('should set overlay when masterSize is set to 100%', async () => {
7272
layout.masterSize = '100%';
7373
await onceResized(layout);
74-
expect(layout.hasAttribute('overflow')).to.be.true;
74+
expect(layout.hasAttribute('overlay')).to.be.true;
7575
});
7676

77-
it('should not set overflow when detail is removed', async () => {
77+
it('should not set overlay when detail is removed', async () => {
7878
layout.style.width = '400px';
7979
await onceResized(layout);
8080

8181
layout.querySelector('[slot="detail"]').remove();
8282
await onceResized(layout);
83-
expect(layout.hasAttribute('overflow')).to.be.false;
83+
expect(layout.hasAttribute('overlay')).to.be.false;
8484
});
8585
});
8686
});
@@ -103,23 +103,23 @@ describe('overflow detection', () => {
103103
await onceResized(layout);
104104
});
105105

106-
it('should not set overflow when rows fit within the layout', () => {
107-
expect(layout.hasAttribute('overflow')).to.be.false;
106+
it('should not set overlay when rows fit within the layout', () => {
107+
expect(layout.hasAttribute('overlay')).to.be.false;
108108
});
109109

110-
it('should set overflow when layout height is decreased below row minimums', async () => {
110+
it('should set overlay when layout height is decreased below row minimums', async () => {
111111
layout.style.height = '400px';
112112
await onceResized(layout);
113-
expect(layout.hasAttribute('overflow')).to.be.true;
113+
expect(layout.hasAttribute('overlay')).to.be.true;
114114
});
115115

116-
it('should remove overflow when layout height is increased to fit rows', async () => {
116+
it('should remove overlay when layout height is increased to fit rows', async () => {
117117
layout.style.height = '400px';
118118
await onceResized(layout);
119119

120120
layout.style.height = '800px';
121121
await onceResized(layout);
122-
expect(layout.hasAttribute('overflow')).to.be.false;
122+
expect(layout.hasAttribute('overlay')).to.be.false;
123123
});
124124
});
125125

@@ -150,14 +150,14 @@ describe('overflow detection', () => {
150150
// round to integers, which can mask overflow when the fractional host size is
151151
// slightly less than the track sum (e.g. 599.6px rounds up to 600px, matching
152152
// the 300+300 track sum).
153-
it(`should not report false overflow due to sub-pixel rounding`, async () => {
153+
it(`should not report false overlay due to sub-pixel rounding`, async () => {
154154
layout.style[sizeProp] = '600.4px';
155155
await onceResized(layout);
156-
expect(layout.hasAttribute('overflow')).to.be.false;
156+
expect(layout.hasAttribute('overlay')).to.be.false;
157157

158158
layout.style[sizeProp] = '599.6px';
159159
await onceResized(layout);
160-
expect(layout.hasAttribute('overflow')).to.be.true;
160+
expect(layout.hasAttribute('overlay')).to.be.true;
161161
});
162162
});
163163
});

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ describe('overlay', () => {
4444
const detailContent = layout.querySelector('[slot="detail"]');
4545
detailContent.remove();
4646
await onceResized(layout);
47-
expect(layout.hasAttribute('overflow')).to.be.false;
47+
expect(layout.hasAttribute('overlay')).to.be.false;
4848

4949
layout.appendChild(detailContent);
5050
await onceResized(layout);
51-
expect(layout.hasAttribute('overflow')).to.be.true;
51+
expect(layout.hasAttribute('overlay')).to.be.true;
5252
expect(getComputedStyle(detail).position).to.equal('absolute');
5353
});
5454
});
@@ -117,7 +117,7 @@ describe('overlay', () => {
117117
it('should switch back to split mode when layout grows', async () => {
118118
layout.style.width = '800px';
119119
await onceResized(layout);
120-
expect(layout.hasAttribute('overflow')).to.be.false;
120+
expect(layout.hasAttribute('overlay')).to.be.false;
121121
});
122122

123123
it('should switch to overlay when detail is added to a narrow layout', async () => {
@@ -127,7 +127,7 @@ describe('overlay', () => {
127127

128128
layout.appendChild(detailContent);
129129
await onceResized(layout);
130-
expect(layout.hasAttribute('overflow')).to.be.true;
130+
expect(layout.hasAttribute('overlay')).to.be.true;
131131
expect(detail.offsetWidth).to.equal(layout.offsetWidth);
132132
});
133133
});

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ describe('Transitions', () => {
288288
const midValue = parseFloat(midTranslate);
289289
expect(midValue).to.be.greaterThan(0);
290290

291-
// Set overflow so replace uses slide (not cross-fade)
292-
layout.setAttribute('overflow', '');
291+
// Set overlay so replace uses slide (not cross-fade)
292+
layout.setAttribute('overlay', '');
293293

294294
// Interrupt with replace — outgoing should start from captured position
295295
const replaceCallback = sinon.spy();

0 commit comments

Comments
 (0)