Skip to content

Commit 2dd2256

Browse files
authored
Merge pull request #2371 from tf/filter-fade
Preserve backdrop blur during fade transitions
2 parents 0c198c5 + 101c057 commit 2dd2256

19 files changed

Lines changed: 465 additions & 251 deletions

File tree

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import {renderHook} from '@testing-library/react-hooks';
2+
3+
import {useAppearanceOverlayStyle} from 'frontend/appearance';
4+
5+
describe('useAppearanceOverlayStyle', () => {
6+
it('returns empty object for shadow appearance', () => {
7+
const {result} = renderHook(() =>
8+
useAppearanceOverlayStyle({appearance: 'shadow'})
9+
);
10+
11+
expect(result.current).toEqual({});
12+
});
13+
14+
it('returns empty object for transparent appearance', () => {
15+
const {result} = renderHook(() =>
16+
useAppearanceOverlayStyle({appearance: 'transparent'})
17+
);
18+
19+
expect(result.current).toEqual({});
20+
});
21+
22+
describe('cards appearance', () => {
23+
it('returns backdropFilter for translucent cardSurfaceColor', () => {
24+
const {result} = renderHook(() =>
25+
useAppearanceOverlayStyle({
26+
appearance: 'cards',
27+
cardSurfaceColor: '#ff000080'
28+
})
29+
);
30+
31+
expect(result.current).toEqual({
32+
backgroundColor: '#ff000080',
33+
backdropFilter: 'blur(10px)'
34+
});
35+
});
36+
37+
it('does not return backdropFilter for opaque cardSurfaceColor', () => {
38+
const {result} = renderHook(() =>
39+
useAppearanceOverlayStyle({
40+
appearance: 'cards',
41+
cardSurfaceColor: '#ff0000'
42+
})
43+
);
44+
45+
expect(result.current).toEqual({
46+
backgroundColor: '#ff0000'
47+
});
48+
});
49+
50+
it('does not return backdropFilter when no cardSurfaceColor is set', () => {
51+
const {result} = renderHook(() =>
52+
useAppearanceOverlayStyle({appearance: 'cards'})
53+
);
54+
55+
expect(result.current).toEqual({});
56+
});
57+
58+
it('scales overlayBackdropBlur to max 10px', () => {
59+
const {result} = renderHook(() =>
60+
useAppearanceOverlayStyle({
61+
appearance: 'cards',
62+
cardSurfaceColor: '#ff000080',
63+
overlayBackdropBlur: 50
64+
})
65+
);
66+
67+
expect(result.current).toEqual({
68+
backgroundColor: '#ff000080',
69+
backdropFilter: 'blur(5px)'
70+
});
71+
});
72+
73+
it('does not return backdropFilter when overlayBackdropBlur is 0', () => {
74+
const {result} = renderHook(() =>
75+
useAppearanceOverlayStyle({
76+
appearance: 'cards',
77+
cardSurfaceColor: '#ff000080',
78+
overlayBackdropBlur: 0
79+
})
80+
);
81+
82+
expect(result.current).toEqual({
83+
backgroundColor: '#ff000080'
84+
});
85+
});
86+
});
87+
88+
describe('split appearance', () => {
89+
it('returns backdropFilter for translucent splitOverlayColor', () => {
90+
const {result} = renderHook(() =>
91+
useAppearanceOverlayStyle({
92+
appearance: 'split',
93+
splitOverlayColor: '#ff000080',
94+
overlayBackdropBlur: 50
95+
})
96+
);
97+
98+
expect(result.current).toEqual({
99+
backgroundColor: '#ff000080',
100+
backdropFilter: 'blur(5px)'
101+
});
102+
});
103+
104+
it('returns default backdropFilter when no splitOverlayColor is set', () => {
105+
const {result} = renderHook(() =>
106+
useAppearanceOverlayStyle({appearance: 'split'})
107+
);
108+
109+
expect(result.current).toEqual({backdropFilter: 'blur(10px)'});
110+
});
111+
112+
it('does not return backdropFilter for opaque splitOverlayColor', () => {
113+
const {result} = renderHook(() =>
114+
useAppearanceOverlayStyle({
115+
appearance: 'split',
116+
splitOverlayColor: '#ff0000'
117+
})
118+
);
119+
120+
expect(result.current).toEqual({
121+
backgroundColor: '#ff0000'
122+
});
123+
});
124+
125+
it('returns default backdropFilter for translucent splitOverlayColor', () => {
126+
const {result} = renderHook(() =>
127+
useAppearanceOverlayStyle({
128+
appearance: 'split',
129+
splitOverlayColor: '#ff000080'
130+
})
131+
);
132+
133+
expect(result.current).toEqual({
134+
backgroundColor: '#ff000080',
135+
backdropFilter: 'blur(10px)'
136+
});
137+
});
138+
});
139+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {renderEntry, usePageObjects} from 'support/pageObjects';
2+
3+
describe('fade transitions with backdrop blur', () => {
4+
usePageObjects();
5+
6+
it('uses per-element fade to preserve backdrop blur', () => {
7+
const {getSectionByPermaId} = renderEntry({
8+
seed: {
9+
sections: [
10+
{id: 1, permaId: 9, configuration: {fullHeight: true, transition: 'scroll'}},
11+
{id: 2, permaId: 10,
12+
configuration: {appearance: 'cards', cardSurfaceColor: '#ff000080',
13+
fullHeight: true, transition: 'fade'}}
14+
],
15+
contentElements: [{sectionId: 2}]
16+
}
17+
});
18+
19+
expect(getSectionByPermaId(10).usesPerElementFadeTransition()).toBe(true);
20+
});
21+
22+
it('uses regular fade when there is no backdrop blur', () => {
23+
const {getSectionByPermaId} = renderEntry({
24+
seed: {
25+
sections: [
26+
{id: 1, permaId: 9, configuration: {fullHeight: true, transition: 'scroll'}},
27+
{id: 2, permaId: 10,
28+
configuration: {appearance: 'cards', cardSurfaceColor: '#ff0000',
29+
fullHeight: true, transition: 'fade'}}
30+
],
31+
contentElements: [{sectionId: 2}]
32+
}
33+
});
34+
35+
expect(getSectionByPermaId(10).usesPerElementFadeTransition()).toBe(false);
36+
});
37+
});

entry_types/scrolled/package/spec/frontend/foregroundBoxes/CardBoxWrapper-spec.js

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ import CardBoxWrapper from 'frontend/foregroundBoxes/CardBoxWrapper';
77
import cardBoxStyles from 'frontend/foregroundBoxes/CardBoxWrapper.module.css';
88
import boundaryMarginStyles from 'frontend/foregroundBoxes/BoxBoundaryMargin.module.css';
99

10+
const transitionStyles = {foregroundOpacity: 'foregroundOpacity'};
11+
1012
describe('CardBoxWrapper', () => {
1113
describe('at section boundaries', () => {
1214
it('does not have noTopMargin class when not at section start', () => {
1315
const {container} = render(
14-
<CardBoxWrapper openStart={false} openEnd={true} atSectionStart={false}>
16+
<CardBoxWrapper transitionStyles={transitionStyles}
17+
openStart={false} openEnd={true} atSectionStart={false}>
1518
Content
1619
</CardBoxWrapper>
1720
);
@@ -21,7 +24,8 @@ describe('CardBoxWrapper', () => {
2124

2225
it('has noTopMargin class when at section start', () => {
2326
const {container} = render(
24-
<CardBoxWrapper openStart={false} openEnd={true} atSectionStart={true}>
27+
<CardBoxWrapper transitionStyles={transitionStyles}
28+
openStart={false} openEnd={true} atSectionStart={true}>
2529
Content
2630
</CardBoxWrapper>
2731
);
@@ -31,7 +35,8 @@ describe('CardBoxWrapper', () => {
3135

3236
it('does not have noBottomMargin class when not at section end', () => {
3337
const {container} = render(
34-
<CardBoxWrapper openStart={true} openEnd={false} atSectionEnd={false}>
38+
<CardBoxWrapper transitionStyles={transitionStyles}
39+
openStart={true} openEnd={false} atSectionEnd={false}>
3540
Content
3641
</CardBoxWrapper>
3742
);
@@ -41,7 +46,8 @@ describe('CardBoxWrapper', () => {
4146

4247
it('has noBottomMargin class when at section end', () => {
4348
const {container} = render(
44-
<CardBoxWrapper openStart={true} openEnd={false} atSectionEnd={true}>
49+
<CardBoxWrapper transitionStyles={transitionStyles}
50+
openStart={true} openEnd={false} atSectionEnd={true}>
4551
Content
4652
</CardBoxWrapper>
4753
);
@@ -50,88 +56,82 @@ describe('CardBoxWrapper', () => {
5056
});
5157
});
5258

53-
describe('backdrop blur', () => {
54-
it('applies blur class when overlayBackdropBlur is set and color is translucent', () => {
55-
const {container} = render(
56-
<CardBoxWrapper cardSurfaceColor="#ff000080"
57-
overlayBackdropBlur={50}>
58-
Content
59-
</CardBoxWrapper>
60-
);
61-
62-
expect(container.firstChild).toHaveClass(cardBoxStyles.blur);
63-
});
64-
65-
it('does not apply blur class when color is opaque', () => {
66-
const {container} = render(
67-
<CardBoxWrapper cardSurfaceColor="#ff0000"
68-
overlayBackdropBlur={50}>
69-
Content
70-
</CardBoxWrapper>
71-
);
72-
73-
expect(container.firstChild).not.toHaveClass(cardBoxStyles.blur);
74-
});
75-
76-
it('does not apply blur when everything is default', () => {
59+
describe('background element', () => {
60+
it('applies foregroundOpacity class to background element', () => {
7761
const {container} = render(
78-
<CardBoxWrapper>
62+
<CardBoxWrapper transitionStyles={transitionStyles}
63+
openStart={false} openEnd={false}>
7964
Content
8065
</CardBoxWrapper>
8166
);
8267

83-
expect(container.firstChild).not.toHaveClass(cardBoxStyles.blur);
68+
expect(container.querySelector(`.${cardBoxStyles.cardBg}`))
69+
.toHaveClass('foregroundOpacity');
8470
});
71+
});
8572

86-
it('applies blur class by default for translucent color', () => {
73+
describe('content wrapper', () => {
74+
it('applies foregroundOpacity class to content wrapper', () => {
8775
const {container} = render(
88-
<CardBoxWrapper cardSurfaceColor="#ff000080">
89-
Content
76+
<CardBoxWrapper transitionStyles={transitionStyles}
77+
openStart={false} openEnd={false}>
78+
<span>Content</span>
9079
</CardBoxWrapper>
9180
);
9281

93-
expect(container.firstChild).toHaveClass(cardBoxStyles.blur);
82+
const contentWrapper = container.querySelector(`.foregroundOpacity:not(.${cardBoxStyles.cardBg})`);
83+
expect(contentWrapper).not.toBeNull();
84+
expect(contentWrapper).toHaveTextContent('Content');
9485
});
86+
});
9587

96-
it('sets backdrop blur CSS variable by default for translucent color', () => {
88+
describe('outside box', () => {
89+
it('wraps outsideBox children in foregroundOpacity', () => {
9790
const {container} = render(
98-
<CardBoxWrapper cardSurfaceColor="#ff000080">
99-
Content
91+
<CardBoxWrapper transitionStyles={transitionStyles}
92+
position="sticky">
93+
<span>Content</span>
10094
</CardBoxWrapper>
10195
);
10296

103-
expect(container.firstChild.style.getPropertyValue('--card-backdrop-blur'))
104-
.toBe('blur(10px)');
97+
expect(container.querySelector('.foregroundOpacity'))
98+
.toHaveTextContent('Content');
10599
});
100+
});
106101

107-
it('does not apply blur class when overlayBackdropBlur is 0', () => {
102+
describe('overlay style', () => {
103+
it('applies overlay style to background element', () => {
108104
const {container} = render(
109-
<CardBoxWrapper cardSurfaceColor="#ff000080"
110-
overlayBackdropBlur={0}>
105+
<CardBoxWrapper transitionStyles={transitionStyles}
106+
overlayStyle={{backgroundColor: '#ff000080', backdropFilter: 'blur(5px)'}}>
111107
Content
112108
</CardBoxWrapper>
113109
);
114110

115-
expect(container.firstChild).not.toHaveClass(cardBoxStyles.blur);
111+
const bg = container.querySelector(`.${cardBoxStyles.cardBg}`);
112+
expect(bg).toHaveStyle({backgroundColor: '#ff000080'});
113+
expect(bg.style.backdropFilter).toBe('blur(5px)');
116114
});
117115

118-
it('sets backdrop blur CSS variable when color is translucent', () => {
116+
it('does not set inline styles when overlayStyle is empty', () => {
119117
const {container} = render(
120-
<CardBoxWrapper cardSurfaceColor="#ff000080"
121-
overlayBackdropBlur={50}>
118+
<CardBoxWrapper transitionStyles={transitionStyles}
119+
overlayStyle={{}}>
122120
Content
123121
</CardBoxWrapper>
124122
);
125123

126-
expect(container.firstChild.style.getPropertyValue('--card-backdrop-blur'))
127-
.toBe('blur(5px)');
124+
const bg = container.querySelector(`.${cardBoxStyles.cardBg}`);
125+
expect(bg.style.backdropFilter).toBeFalsy();
126+
expect(bg.style.backgroundColor).toBeFalsy();
128127
});
129128
});
130129

131130
describe('cardEnd padding', () => {
132131
it('does not have cardEndPadding class when lastMarginBottom is set', () => {
133132
const {container} = render(
134-
<CardBoxWrapper openStart={true} openEnd={false} lastMarginBottom="lg">
133+
<CardBoxWrapper transitionStyles={transitionStyles}
134+
openStart={true} openEnd={false} lastMarginBottom="lg">
135135
Content
136136
</CardBoxWrapper>
137137
);
@@ -142,7 +142,8 @@ describe('CardBoxWrapper', () => {
142142

143143
it('has cardEndPadding class when lastMarginBottom is not set', () => {
144144
const {container} = render(
145-
<CardBoxWrapper openStart={true} openEnd={false}>
145+
<CardBoxWrapper transitionStyles={transitionStyles}
146+
openStart={true} openEnd={false}>
146147
Content
147148
</CardBoxWrapper>
148149
);

0 commit comments

Comments
 (0)