Skip to content

Commit 30f9cdd

Browse files
Merge pull request #20198 from mozilla/FXA-13026
feat(settings): put Vijay's dark mode behind feature flag
2 parents adbcdac + d4184ec commit 30f9cdd

77 files changed

Lines changed: 817 additions & 168 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

libs/shared/assets/src/styles/flows.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* applied after content-server no longer needs it */
77

88
.card {
9-
@apply relative text-center w-full mobileLandscape:w-120 mobileLandscape:bg-white rounded-xl px-8 pb-10 pt-33 mobileLandscape:pt-20 mobileLandscape:shadow-card-grey-drop;
9+
@apply relative text-center w-full mobileLandscape:w-120 mobileLandscape:bg-white mobileLandscape:dark:bg-grey-700 rounded-xl px-8 pb-10 pt-33 mobileLandscape:pt-20 mobileLandscape:shadow-card-grey-drop;
1010

1111
/* HACK until content-server no longer needs .card, otherwise component classes take precedence */
1212
&.card-xl {

packages/fxa-content-server/app/scripts/head/startup-styles.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ StartupStyles.prototype = {
5454
this.addPasswordRevealerStyles();
5555
this.addFxiOSSyncStyles();
5656
this.addGetUserMediaStyles();
57+
this.addDarkModeStyles();
5758
},
5859

5960
addJSStyle: function () {
@@ -90,6 +91,32 @@ StartupStyles.prototype = {
9091
this._addClass('no-getusermedia');
9192
}
9293
},
94+
95+
addDarkModeStyles: function () {
96+
// fxa-settings handles the `theme_preference` localStorage key
97+
let themePreference = null;
98+
try {
99+
themePreference = JSON.parse(
100+
this.window.localStorage.getItem('__fxa_storage.theme_preference')
101+
);
102+
} catch (e) {
103+
// localStorage may be disabled; treat as light
104+
}
105+
106+
let prefersDark = false;
107+
if (themePreference === 'dark') {
108+
prefersDark = true;
109+
} else if (themePreference === 'system') {
110+
prefersDark = !!(
111+
this.window.matchMedia &&
112+
this.window.matchMedia('(prefers-color-scheme: dark)').matches
113+
);
114+
}
115+
116+
if (prefersDark) {
117+
this._addClass('dark');
118+
}
119+
},
93120
};
94121

95122
export default StartupStyles;

packages/fxa-content-server/app/scripts/templates/pair/index.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
<header class="relative">
44
{{#showSuccessMessage}}
55
<div id="fxa-connected-heading"
6-
class="w-full text-md font-bold p-3 mb-5 rounded bg-green-500 text-gray-900 flex items-center justify-center before:content-icon-circle-check-outline before:flex">
6+
class="w-full text-md font-bold p-3 mb-5 rounded bg-green-500 text-grey-900 dark:text-grey-900 flex items-center justify-center before:content-icon-circle-check-outline before:flex">
77
<span class="ps-3 align-middle">{{#t}}Signed in successfully!{{/t}}</span>
88
</div>
99
{{/showSuccessMessage}}
1010

1111
{{#needsMobileConfirmed}}
1212
<div class="relative flex items-center">
13-
<button id="back-btn" class="me-4 tablet:me-0 p-2 inline-block tablet:absolute tablet:-start-20 -top-1.5 rounded hover:bg-grey-50 active:bg-grey-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500" aria-label="{{#t}}Back{{/t}}" title="{{#t}}Back{{/t}}">
13+
<button id="back-btn" class="me-4 tablet:me-0 p-2 inline-block tablet:absolute tablet:-start-20 -top-1.5 rounded hover:bg-grey-50 dark:hover:bg-grey-600 active:bg-grey-100 dark:active:bg-grey-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500" aria-label="{{#t}}Back{{/t}}" title="{{#t}}Back{{/t}}">
1414
<svg height="20" viewBox="0 0 16 14" width="20" xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="text-grey-400 {{tabletBackArrowColor}} w-6 h-auto rtl:transform rtl:-scale-x-100"><path d="m15 5.99998h-11.58597l4.293-4.293c.37897-.39238.37355-1.016085-.01218-1.401818-.38573-.3857343-1.00944-.3911541-1.40182-.012182l-5.999999 6c-.3903823.3905-.3903823 1.0235 0 1.414l5.999999 6.00002c.39238.379 1.01609.3735 1.40182-.0122s.39115-1.0094.01218-1.4018l-4.293-4.29302h11.58597c.5523 0 1-.44772 1-1s-.4477-1-1-1z"/></svg>
1515
</button>
1616
<h1 class="text-grey-400 mb-0 tablet:mb-5 text-base inline-block align-top tablet:mt-0" id="cad-header">{{#t}}Connect another device{{/t}}</h1>

packages/fxa-content-server/app/scripts/templates/pair/unsupported.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
the same meaning. If the header text changes later, consider adding an aria-label/role=img. -->
1414
<div class="bg-no-ff-desktop bg-contain bg-center bg-no-repeat h-44"></div>
1515
<h2 id="pair-unsupported-header" class="card-header focus:outline-none mt-5" tabindex="-1">{{#t}}Oops! It looks like you’re not using Firefox.{{/t}}</h2>
16-
<div class="flex bg-orange-50 px-4 py-3 mt-6 rounded-lg mb-4">
16+
<div class="flex bg-orange-50 dark:bg-orange-900/30 px-4 py-3 mt-6 rounded-lg mb-4">
1717
<div class="bg-icon-warning bg-contain bg-center bg-no-repeat w-6" aria-label="{{#t}}Attention:{{/t}}" role="img"></div>
1818
<p class="ps-3">{{#t}}Switch to Firefox and open this page to connect another device.{{/t}}</p>
1919
</div>
@@ -30,7 +30,7 @@
3030
{{/isSystemCameraUrl}}
3131
{{^isSystemCameraUrl}}
3232
{{^isFirefox}}
33-
<div class="flex bg-orange-50 px-4 py-3 rounded-lg mb-8">
33+
<div class="flex bg-orange-50 dark:bg-orange-900/30 px-4 py-3 rounded-lg mb-8">
3434
<div class="bg-icon-warning bg-contain bg-center bg-no-repeat w-10" aria-label="{{#t}}Attention:{{/t}}" role="img"></div>
3535
<p class="ps-3 text-sm">{{#t}}Oops! It looks like you’re not using Firefox.{{/t}} <a href="{{{ escapedMobileDownloadLink }}}" target="_blank" class="link-blue" data-glean-id="cad_redirect_mobile_download">{{#t}}Download Firefox now{{/t}}</a></p>
3636
</div>

packages/fxa-content-server/app/styles/tailwind.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@
1818
@import './tailwind/tooltips';
1919

2020
body {
21-
@apply min-h-screen mobileLandscape:pt-12 text-black flex flex-col justify-center;
21+
@apply min-h-screen mobileLandscape:pt-12 text-black dark:text-grey-10 bg-grey-10 dark:bg-grey-900 flex flex-col justify-center;
2222
}

packages/fxa-content-server/app/styles/tailwind/state.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
.info {
6-
@apply flex gap-2 items-center mb-5 p-3 rounded bg-grey-50 text-black;
6+
@apply flex gap-2 items-center mb-5 p-3 rounded bg-grey-50 dark:bg-grey-700 text-black dark:text-grey-100;
77
}
88

99
.info-text {
@@ -16,7 +16,7 @@
1616
}
1717

1818
.success {
19-
@apply text-xs text-grey-900 bg-green-500 font-bold p-3 my-3 hidden rounded;
19+
@apply text-xs text-grey-900 dark:text-grey-900 bg-green-500 font-bold p-3 my-3 hidden rounded;
2020

2121
/* REACT NOTE: probably don't need this nesting, add class in JSX instead */
2222
a {

packages/fxa-content-server/app/tests/spec/head/startup-styles.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,53 @@ describe('head/startup-styles', function () {
125125
});
126126
});
127127

128+
describe('addDarkModeStyles', function () {
129+
const THEME_KEY = '__fxa_storage.theme_preference';
130+
131+
it('adds `dark` when theme_preference is "dark"', function () {
132+
windowMock.localStorage.setItem(THEME_KEY, JSON.stringify('dark'));
133+
startupStyles.addDarkModeStyles();
134+
assert.isTrue(/\bdark\b/.test(startupStyles.getClassName()));
135+
});
136+
137+
it('does not add `dark` when theme_preference is "light"', function () {
138+
windowMock.localStorage.setItem(THEME_KEY, JSON.stringify('light'));
139+
startupStyles.addDarkModeStyles();
140+
assert.isFalse(/\bdark\b/.test(startupStyles.getClassName()));
141+
});
142+
143+
it('adds `dark` when theme_preference is "system" and OS prefers dark', function () {
144+
windowMock.localStorage.setItem(THEME_KEY, JSON.stringify('system'));
145+
windowMock.matchMedia = function () {
146+
return { matches: true };
147+
};
148+
startupStyles.addDarkModeStyles();
149+
assert.isTrue(/\bdark\b/.test(startupStyles.getClassName()));
150+
});
151+
152+
it('does not add `dark` when theme_preference is "system" and OS prefers light', function () {
153+
windowMock.localStorage.setItem(THEME_KEY, JSON.stringify('system'));
154+
windowMock.matchMedia = function () {
155+
return { matches: false };
156+
};
157+
startupStyles.addDarkModeStyles();
158+
assert.isFalse(/\bdark\b/.test(startupStyles.getClassName()));
159+
});
160+
161+
it('defaults to light (no `dark` class) when theme_preference is not set', function () {
162+
startupStyles.addDarkModeStyles();
163+
assert.isFalse(/\bdark\b/.test(startupStyles.getClassName()));
164+
});
165+
166+
it('defaults to light when localStorage is unavailable', function () {
167+
sinon
168+
.stub(windowMock.localStorage, 'getItem')
169+
.throws(new Error('unavailable'));
170+
startupStyles.addDarkModeStyles();
171+
assert.isFalse(/\bdark\b/.test(startupStyles.getClassName()));
172+
});
173+
});
174+
128175
describe('initialize', function () {
129176
it('runs all the tests', function () {
130177
startupStyles.initialize();

packages/fxa-react/components/Footer/index.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,21 @@ import mozLogo from '@fxa/shared/assets/images/moz-logo-bw-rgb.svg';
99

1010
export const Footer = ({
1111
showLocaleToggle = false,
12-
localeToggleComponent
12+
localeToggleComponent,
13+
showDarkModeToggle = false,
14+
darkModeToggleComponent,
1315
}: {
1416
showLocaleToggle?: boolean;
15-
localeToggleComponent?: React.ComponentType<{ placement?: 'footer' | 'header' }>;
17+
localeToggleComponent?: React.ComponentType<{
18+
placement?: 'footer' | 'header';
19+
}>;
20+
showDarkModeToggle?: boolean;
21+
darkModeToggleComponent?: React.ComponentType;
1622
}) => {
1723
const { l10n } = useLocalization();
1824
return (
1925
<footer
20-
className="py-4 mt-16 mx-4 flex-wrap mobileLandscape:flex-nowrap mobileLandscape:mx-8 mobileLandscape:pb-6 flex border-t border-grey-100 text-grey-400"
26+
className="py-4 mt-16 mx-4 flex-wrap mobileLandscape:flex-nowrap mobileLandscape:mx-8 mobileLandscape:pb-6 flex border-t border-grey-100 dark:border-grey-600 text-grey-400 dark:text-grey-300"
2127
data-testid="footer"
2228
>
2329
<LinkExternal
@@ -62,6 +68,11 @@ export const Footer = ({
6268
{React.createElement(localeToggleComponent, { placement: 'footer' })}
6369
</div>
6470
)}
71+
{showDarkModeToggle && darkModeToggleComponent && (
72+
<div className="w-full mobileLandscape:w-auto flex items-center mt-3 mobileLandscape:mt-0 mobileLandscape:ml-10">
73+
{React.createElement(darkModeToggleComponent)}
74+
</div>
75+
)}
6576
</footer>
6677
);
6778
};

packages/fxa-react/components/Header/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const Header = (props: HeaderProps) => {
1919
// top-[env(safe-area-inset-top)] keeps the sticky header below the notch/status bar on scroll
2020
className={
2121
props.className ||
22-
'sticky top-[env(safe-area-inset-top)] bg-grey-10 z-10'
22+
'sticky top-[env(safe-area-inset-top)] bg-grey-10 dark:bg-grey-900 z-10'
2323
}
2424
style={props.styles}
2525
>

packages/fxa-react/components/LoadingSpinner/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export const LoadingSpinner = ({
6060
className={classNames(
6161
className,
6262
fullScreen &&
63-
'bg-grey-20 flex items-center flex-col justify-center h-screen select-none'
63+
'bg-grey-20 dark:bg-grey-900 flex items-center flex-col justify-center h-screen select-none'
6464
)}
6565
data-testid="loading-spinner"
6666
>

0 commit comments

Comments
 (0)