@@ -7,92 +7,119 @@ import '@vaadin/component-base/src/styles/style-props.js';
77import { css } from 'lit' ;
88
99export const masterDetailLayoutStyles = css `
10+ /* stylelint-disable no-duplicate-selectors */
1011 : host {
11- - - _master- size: 30rem;
12- - - _master- extra: 0px;
13- - - _detail- size: var(--_detail-cached-size );
14- - - _detail- extra: 0px;
15- - - _detail- cached- size: min- content;
16-
1712 - - _rtl- multiplier: 1;
1813 - - _transition- duration: 0s;
1914 - - _transition- easing: cubic- bezier(0.78, 0, 0.22, 1);
20- - - _transition- offset: calc(30px * var (- - _rtl- multiplier));
2115
2216 dis play: grid;
2317 box- sizing: bor der- box;
2418 height: 100%;
2519 position: relative;
2620 z- index: 0;
2721 overflow: clip;
28- grid- template-columns:
29- [master-start ] var (- - _master- size) var(- - _master- extra)
30- [detail-start ] var (- - _detail- size) var(- - _detail- extra)
31- [detail-end ];
32- grid- template-rows: 100%;
33- }
34-
35- : host ([hidden ]),
36- ::slotted ([hidden ]) {
37- display : none !important ;
3822 }
3923
4024 : host ([dir = 'rtl' ]) {
4125 --_rtl-multiplier : -1 ;
4226 }
4327
28+ : host ([orientation = 'horizontal' ]) {
29+ --_transition-offset : calc (30px * var (--_rtl-multiplier ));
30+ }
31+
4432 : host ([orientation = 'vertical' ]) {
4533 --_transition-offset : 0 30px ;
34+ }
4635
47- grid-template-columns : 100% ;
48- grid-template-rows :
49- [master-start] var (--_master-size ) var (--_master-extra )
50- [detail-start] var (--_detail-size ) var (--_detail-extra )
51- [detail-end];
36+ : host ([hidden ]),
37+ ::slotted ([hidden ]) {
38+ display : none !important ;
5239 }
5340
54- : is (# master , # detail , # detailPlaceholder , # detailOutgoing ) {
55- box-sizing : border-box;
41+ /* CSS grid template */
42+
43+ : host {
44+ - - _master- size: 30rem;
45+ - - _master- extra: 0px;
46+ - - _detail- size: var(--_detail-cached-size );
47+ - - _detail- extra: 0px;
48+ - - _detail- cached- size: min- content;
5649 }
5750
58- # detailPlaceholder {
59- z-index : 1 ;
60- opacity : 0 ;
61- pointer-events : none;
51+ : host ([orientation = 'horizontal' ]) {
52+ grid-template-columns :
53+ [master-start] var (--_master-size ) [master-extra-start] var (--_master-extra )
54+ [detail-start] var (--_detail-size ) [detail-extra-start] var (--_detail-extra ) [detail-end];
55+ grid-template-rows : 100% ;
6256 }
6357
64- : host ([has-detail-placeholder ]: not ([has-detail ], [overlay ])) # detailPlaceholder {
65- opacity : 1 ;
66- pointer-events : auto;
58+ : host ([orientation = 'vertical' ]) {
59+ grid-template-columns : 100% ;
60+ grid-template-rows :
61+ [master-start] var (--_master-size ) [master-extra-start] var (--_master-extra )
62+ [detail-start] var (--_detail-size ) [detail-extra-start] var (--_detail-extra ) [detail-end];
6763 }
6864
69- # master {
70- grid-column : master-start / detail-start;
71- grid-row : 1 ;
72- opacity : 0 ;
73- pointer-events : none;
65+ /* CSS grid placement */
66+
67+ : host {
68+ - - _master- area: master- start / detail- start;
69+
70+ /*
71+ When the detail size isn't explicitly defined and the detail is set to expand,
72+ the detail column template is 'min-content 1fr'. In this case, the detail area
73+ should not span both columns initially (and when recalculating the detail size)
74+ as spanning both would effectively collapse them into a single '1fr' column where
75+ min-content resolves to 0, making it impossible to measure the detail's intrinsic
76+ minimum width from JavaScript.
77+ */
78+ - - _detail- area: detail- start / detail- extra- start;
7479 }
7580
76- : host ([has-master ]) # master {
77- opacity : 1 ;
78- pointer-events : auto;
81+ : host (: is ([has-detail ], [has-detail-placeholder ]): not ([recalculating-detail-size ])) {
82+ --_detail-area : detail-start / detail-end;
7983 }
8084
81- : is ( # detail , # detailPlaceholder , # detailOutgoing ) {
82- grid-column : detail-start / detail-end ;
85+ : host ([ orientation = 'horizontal' ]) # master {
86+ grid-column : var ( --_master-area ) ;
8387 grid-row : 1 ;
8488 }
8589
8690 : host ([orientation = 'vertical' ]) # master {
8791 grid-column : 1 ;
88- grid-row : master-start / detail-start;
92+ grid-row : var (--_master-area );
93+ }
94+
95+ : host ([orientation = 'horizontal' ]) : is (# detail , # detailPlaceholder , # detailOutgoing ) {
96+ grid-column : var (--_detail-area );
97+ grid-row : 1 ;
8998 }
9099
91100 : host ([orientation = 'vertical' ]) : is (# detail , # detailPlaceholder , # detailOutgoing ) {
92101 grid-column : 1 ;
93- grid-row : detail-start / detail-end ;
102+ grid-row : var ( --_detail-area ) ;
94103 }
95104
105+ /* Expand */
106+
107+ : host (: is ([expand = 'both' ], [expand = 'master' ])) {
108+ --_master-extra : 1fr ;
109+ }
110+
111+ : host (: is ([expand = 'both' ], [expand = 'detail' ])) {
112+ --_detail-extra : 1fr ;
113+ }
114+
115+ : host ([keep-detail-column-offscreen ]),
116+ : host ([has-detail-placeholder ][overlay ]: not ([has-detail ])),
117+ : host (: not ([has-detail-placeholder ], [has-detail ])) {
118+ --_master-extra : calc (100% - var (--_master-size ));
119+ }
120+
121+ /* Backdrop base styles */
122+
96123 # backdrop {
97124 --_transition-easing : linear;
98125
@@ -105,36 +132,30 @@ export const masterDetailLayoutStyles = css`
105132 forced-color-adjust : none;
106133 }
107134
108- : host ([expand = 'both' ]),
109- : host ([expand = 'master' ]) {
110- --_master-extra : 1fr ;
111- }
135+ /* Master base styles */
112136
113- : host ([expand = 'both' ]: is ([has-detail ], [has-detail-placeholder ])),
114- : host ([expand = 'detail' ]: is ([has-detail ], [has-detail-placeholder ])) {
115- --_detail-extra : 1fr ;
137+ # master {
138+ opacity : 0 ;
139+ pointer-events : none;
140+ box-sizing : border-box;
116141 }
117142
118- : host ([recalculating-detail-size ]: is ([has-detail ], [has-detail-placeholder ])) {
119- --_detail-extra : 0px ;
143+ : host ([has-master ]) # master {
144+ opacity : 1 ;
145+ pointer-events : auto;
120146 }
121147
122- : host ([keep-detail-column-offscreen ]),
123- : host ([has-detail-placeholder ][overlay ]: not ([has-detail ])),
124- : host (: not ([has-detail-placeholder ], [has-detail ])) {
125- --_master-extra : calc (100% - var (--_master-size ));
126- }
148+ /* Detail base styles */
127149
128- : host ([ orientation = 'horizontal' ]) # detailPlaceholder ,
129- : host ([ orientation = 'horizontal' ] : not ([ overlay ])) # detail {
130- border-inline-start : var ( --vaadin-master-detail-layout-border-width , 1 px ) solid
131- var ( --vaadin-master-detail-layout-border-color , var ( --vaadin-border-color-secondary )) ;
150+ # detail {
151+ translate : var ( --_transition-offset );
152+ opacity : 0 ;
153+ z-index : 4 ;
132154 }
133155
134- : host ([orientation = 'vertical' ]) # detailPlaceholder ,
135- : host ([orientation = 'vertical' ]: not ([overlay ])) # detail {
136- border-top : var (--vaadin-master-detail-layout-border-width , 1px ) solid
137- var (--vaadin-master-detail-layout-border-color , var (--vaadin-border-color-secondary ));
156+ : host ([has-detail ]) # detail {
157+ translate : none;
158+ opacity : 1 ;
138159 }
139160
140161 # detailOutgoing {
@@ -147,26 +168,54 @@ export const masterDetailLayoutStyles = css`
147168 display : block;
148169 }
149170
150- /* Detail transition: off-screen by default, on-screen when has-detail */
151- # detail {
152- translate : var (--_transition-offset );
171+ # detailPlaceholder {
172+ z-index : 1 ;
153173 opacity : 0 ;
154- z-index : 4 ;
174+ pointer-events : none ;
155175 }
156176
157- : host ([has-detail ]) # detail {
158- translate : none;
177+ : host ([has-detail-placeholder ]: not ([has-detail ], [overlay ])) # detailPlaceholder {
159178 opacity : 1 ;
179+ pointer-events : auto;
160180 }
161181
162- : host ([overlay ]) {
182+ : is (# detail , # detailPlaceholder , # detailOutgoing ) {
183+ box-sizing : border-box;
184+ }
185+
186+ /* Detail borders */
187+
188+ # detail ,
189+ # detailPlaceholder {
190+ border-color : var (--vaadin-master-detail-layout-border-color , var (--vaadin-border-color-secondary ));
191+ border-width : var (--vaadin-master-detail-layout-border-width , 1px );
192+ }
193+
194+ : host ([orientation = 'horizontal' ]) # detailPlaceholder ,
195+ : host ([orientation = 'horizontal' ]: not ([overlay ])) # detail {
196+ border-inline-start-style : solid;
197+ }
198+
199+ : host ([orientation = 'vertical' ]) # detailPlaceholder ,
200+ : host ([orientation = 'vertical' ]: not ([overlay ])) # detail {
201+ border-block-start-style : solid;
202+ }
203+
204+ /* Overlay */
205+
206+ : host ([overlay ][orientation = 'horizontal' ]) {
163207 --_transition-offset : calc ((100% + 30px ) * var (--_rtl-multiplier ));
164208 }
165209
166210 : host ([overlay ][orientation = 'vertical' ]) {
167211 --_transition-offset : 0 calc (100% + 30px );
168212 }
169213
214+ : host ([has-detail ][overlay ]) # backdrop {
215+ opacity : 1 ;
216+ pointer-events : auto;
217+ }
218+
170219 : host ([has-detail ][overlay ]) : is (# detail , # detailOutgoing ) {
171220 position : absolute;
172221 background : var (--vaadin-master-detail-layout-detail-background , var (--vaadin-background-color ));
@@ -175,12 +224,7 @@ export const masterDetailLayoutStyles = css`
175224 grid-row : none;
176225 }
177226
178- : host ([has-detail ][overlay ]) # backdrop {
179- opacity : 1 ;
180- pointer-events : auto;
181- }
182-
183- : host ([has-detail ][overlay ]: not ([orientation = 'vertical' ])) : is (# detail , # detailOutgoing ) {
227+ : host ([has-detail ][overlay ][orientation = 'horizontal' ]) : is (# detail , # detailOutgoing ) {
184228 inset-block : 0 ;
185229 inset-inline-end : 0 ;
186230 width : var (--_overlay-size , var (--_detail-size ));
@@ -198,17 +242,8 @@ export const masterDetailLayoutStyles = css`
198242 position : fixed;
199243 }
200244
201- @media (forced-colors : active) {
202- : host ([has-detail ][overlay ]) : is (# detail , # detailOutgoing ) {
203- outline : 3px solid !important ;
204- }
205-
206- : is (# detail , # detailPlaceholder , # detailOutgoing ) {
207- background : Canvas !important ;
208- }
209- }
245+ /* Transitions */
210246
211- /* Enable transitions when motion is allowed */
212247 @media (prefers-reduced-motion : no-preference) {
213248 : host (: not ([no-animation ], [transition = 'replace' ])) {
214249 --_transition-duration : 200ms ;
@@ -218,4 +253,16 @@ export const masterDetailLayoutStyles = css`
218253 --_transition-duration : 300ms ;
219254 }
220255 }
256+
257+ /* Forced colors */
258+
259+ @media (forced-colors : active) {
260+ : host ([has-detail ][overlay ]) : is (# detail , # detailOutgoing ) {
261+ outline : 3px solid !important ;
262+ }
263+
264+ : is (# detail , # detailPlaceholder , # detailOutgoing ) {
265+ background : Canvas !important ;
266+ }
267+ }
221268` ;
0 commit comments