Skip to content

Commit 8f1acd1

Browse files
authored
Merge pull request #42287 from nextcloud/fix/dark-theme-and-element-colors
fix(theming): Adjust status colors and make dark theme fully accessible
2 parents f225bf9 + ae12a73 commit 8f1acd1

5 files changed

Lines changed: 207 additions & 28 deletions

File tree

apps/theming/css/default.css

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@
2121
/** @deprecated use `--color-text-maxcontrast` instead */
2222
--color-text-lighter: var(--color-text-maxcontrast);
2323
--color-scrollbar: rgba(34,34,34, .15);
24-
--color-error: #d91812;
25-
--color-error-rgb: 217,24,18;
26-
--color-error-hover: #dd342f;
27-
--color-error-text: #c61610;
28-
--color-warning: #b88100;
29-
--color-warning-rgb: 184,129,0;
30-
--color-warning-hover: #c69a32;
31-
--color-warning-text: #855d00;
24+
--color-error: #C00505;
25+
--color-error-rgb: 192,5,5;
26+
--color-error-hover: #c72424;
27+
--color-error-text: #C00505;
28+
--color-warning: #A37200;
29+
--color-warning-rgb: 163,114,0;
30+
--color-warning-hover: #8a6000;
31+
--color-warning-text: #7f5900;
3232
--color-success: #2d7b41;
3333
--color-success-rgb: 45,123,65;
34-
--color-success-hover: #448955;
34+
--color-success-hover: #428854;
3535
--color-success-text: #286c39;
3636
--color-info: #0071ad;
3737
--color-info-rgb: 0,113,173;

apps/theming/lib/Themes/DarkTheme.php

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ public function getCSSVariables(): array {
6060
$colorBoxShadow = $this->util->darken($colorMainBackground, 70);
6161
$colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow));
6262

63-
$colorError = '#ee312b';
64-
$colorWarning = '#c28900';
65-
$colorSuccess = '#36914e';
66-
$colorInfo = '#007bbd';
63+
$colorError = '#FF5252';
64+
$colorWarning = '#FFCC00';
65+
$colorSuccess = '#50BB50';
66+
$colorInfo = '#00AEFF';
6767

6868
return array_merge(
6969
$defaultVariables,
@@ -72,6 +72,7 @@ public function getCSSVariables(): array {
7272
'--color-main-text' => $colorMainText,
7373
'--color-main-background' => $colorMainBackground,
7474
'--color-main-background-rgb' => $colorMainBackgroundRGB,
75+
'--color-main-background-blur' => 'rgba(var(--color-main-background-rgb), .85)',
7576

7677
'--color-scrollbar' => $this->util->lighten($colorMainBackground, 15),
7778

@@ -84,26 +85,26 @@ public function getCSSVariables(): array {
8485

8586
'--color-text-maxcontrast' => $colorTextMaxcontrast,
8687
'--color-text-maxcontrast-default' => $colorTextMaxcontrast,
87-
'--color-text-maxcontrast-background-blur' => $this->util->lighten($colorTextMaxcontrast, 2),
88+
'--color-text-maxcontrast-background-blur' => $this->util->lighten($colorTextMaxcontrast, 6),
8889
'--color-text-light' => 'var(--color-main-text)', // deprecated
8990
'--color-text-lighter' => 'var(--color-text-maxcontrast)', // deprecated
9091

9192
'--color-error' => $colorError,
9293
'--color-error-rgb' => join(',', $this->util->hexToRGB($colorError)),
93-
'--color-error-hover' => $this->util->mix($colorError, $colorMainBackground, 85),
94-
'--color-error-text' => $this->util->lighten($colorError, 12),
94+
'--color-error-hover' => $this->util->lighten($colorError, 10),
95+
'--color-error-text' => $this->util->lighten($colorError, 10),
9596
'--color-warning' => $colorWarning,
9697
'--color-warning-rgb' => join(',', $this->util->hexToRGB($colorWarning)),
97-
'--color-warning-hover' => $this->util->mix($colorWarning, $colorMainBackground, 60),
98+
'--color-warning-hover' => $this->util->lighten($colorWarning, 10),
9899
'--color-warning-text' => $colorWarning,
99100
'--color-success' => $colorSuccess,
100101
'--color-success-rgb' => join(',', $this->util->hexToRGB($colorSuccess)),
101-
'--color-success-hover' => $this->util->mix($colorSuccess, $colorMainBackground, 85),
102-
'--color-success-text' => $this->util->lighten($colorSuccess, 6),
102+
'--color-success-hover' => $this->util->lighten($colorSuccess, 10),
103+
'--color-success-text' => $colorSuccess,
103104
'--color-info' => $colorInfo,
104105
'--color-info-rgb' => join(',', $this->util->hexToRGB($colorInfo)),
105-
'--color-info-hover' => $this->util->mix($colorInfo, $colorMainBackground, 85),
106-
'--color-info-text' => $this->util->lighten($colorInfo, 9),
106+
'--color-info-hover' => $this->util->lighten($colorInfo, 10),
107+
'--color-info-text' => $colorInfo,
107108

108109
// used for the icon loading animation
109110
'--color-loading-light' => '#777',

apps/theming/lib/Themes/DefaultTheme.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ public function getCSSVariables(): array {
111111
$colorBoxShadow = $this->util->darken($colorMainBackground, 70);
112112
$colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow));
113113

114-
$colorError = '#d91812';
115-
$colorWarning = '#b88100';
114+
$colorError = '#C00505';
115+
$colorWarning = '#A37200';
116116
$colorSuccess = '#2d7b41';
117117
$colorInfo = '#0071ad';
118118

@@ -148,14 +148,14 @@ public function getCSSVariables(): array {
148148
'--color-error' => $colorError,
149149
'--color-error-rgb' => join(',', $this->util->hexToRGB($colorError)),
150150
'--color-error-hover' => $this->util->mix($colorError, $colorMainBackground, 75),
151-
'--color-error-text' => $this->util->darken($colorError, 4),
151+
'--color-error-text' => $colorError,
152152
'--color-warning' => $colorWarning,
153153
'--color-warning-rgb' => join(',', $this->util->hexToRGB($colorWarning)),
154-
'--color-warning-hover' => $this->util->mix($colorWarning, $colorMainBackground, 60),
155-
'--color-warning-text' => $this->util->darken($colorWarning, 10),
154+
'--color-warning-hover' => $this->util->darken($colorWarning, 5),
155+
'--color-warning-text' => $this->util->darken($colorWarning, 7),
156156
'--color-success' => $colorSuccess,
157157
'--color-success-rgb' => join(',', $this->util->hexToRGB($colorSuccess)),
158-
'--color-success-hover' => $this->util->mix($colorSuccess, $colorMainBackground, 78),
158+
'--color-success-hover' => $this->util->mix($colorSuccess, $colorMainBackground, 80),
159159
'--color-success-text' => $this->util->darken($colorSuccess, 4),
160160
'--color-info' => $colorInfo,
161161
'--color-info-rgb' => join(',', $this->util->hexToRGB($colorInfo)),

apps/theming/tests/Themes/AccessibleThemeTestCase.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ public function dataAccessibilityPairs() {
4646
],
4747
3.0,
4848
],
49+
'status color elements on background' => [
50+
[
51+
'--color-error',
52+
'--color-error-hover',
53+
'--color-warning',
54+
'--color-warning-hover',
55+
'--color-info',
56+
'--color-info-hover',
57+
'--color-success',
58+
'--color-success-hover',
59+
],
60+
[
61+
'--color-main-background',
62+
'--color-background-hover',
63+
'--color-background-dark',
64+
'--color-background-darker',
65+
'--color-main-background-blur',
66+
],
67+
3.0,
68+
],
4969
'primary-element-text' => [
5070
[
5171
'--color-primary-element-text',
@@ -92,6 +112,21 @@ public function dataAccessibilityPairs() {
92112
],
93113
4.5,
94114
],
115+
'status-text' => [
116+
[
117+
'--color-error-text',
118+
'--color-warning-text',
119+
'--color-success-text',
120+
'--color-info-text',
121+
],
122+
[
123+
'--color-main-background',
124+
'--color-background-hover',
125+
'--color-background-dark',
126+
'--color-main-background-blur',
127+
],
128+
4.5,
129+
],
95130
];
96131
}
97132

@@ -108,7 +143,7 @@ public function testAccessibilityOfVariables($mainColors, $backgroundColors, $mi
108143
$variables = $this->theme->getCSSVariables();
109144

110145
// Blur effect does not work so we mockup the color - worst supported case is the default "clouds" background image (on dark themes the clouds with white color are bad on bright themes the primary color as sky is bad)
111-
$variables['--color-main-background-blur'] = $this->util->mix($variables['--color-main-background'], $this->util->isBrightColor($variables['--color-main-background']) ? $variables['--color-primary'] : '#ffffff', 75);
146+
$variables['--color-main-background-blur'] = $this->util->mix($variables['--color-main-background'], $this->util->isBrightColor($variables['--color-main-background']) ? '#000000' : '#ffffff', 75);
112147

113148
foreach ($backgroundColors as $background) {
114149
$this->assertStringStartsWith('#', $variables[$background], 'Is not a plain color variable - consider to remove or fix this test');
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
/**
3+
* @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com>
4+
*
5+
* @author John Molakvoæ <skjnldsv@protonmail.com>
6+
*
7+
* @license GNU AGPL version 3 or any later version
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
namespace OCA\Theming\Tests\Themes;
24+
25+
use OCA\Theming\AppInfo\Application;
26+
use OCA\Theming\ImageManager;
27+
use OCA\Theming\ITheme;
28+
use OCA\Theming\Service\BackgroundService;
29+
use OCA\Theming\Themes\DarkTheme;
30+
use OCA\Theming\ThemingDefaults;
31+
use OCA\Theming\Util;
32+
use OCP\App\IAppManager;
33+
use OCP\Files\IAppData;
34+
use OCP\IConfig;
35+
use OCP\IL10N;
36+
use OCP\IURLGenerator;
37+
use OCP\IUserSession;
38+
use PHPUnit\Framework\MockObject\MockObject;
39+
40+
class DarkThemeTest extends AccessibleThemeTestCase {
41+
/** @var ThemingDefaults|MockObject */
42+
private $themingDefaults;
43+
/** @var IUserSession|MockObject */
44+
private $userSession;
45+
/** @var IURLGenerator|MockObject */
46+
private $urlGenerator;
47+
/** @var ImageManager|MockObject */
48+
private $imageManager;
49+
/** @var IConfig|MockObject */
50+
private $config;
51+
/** @var IL10N|MockObject */
52+
private $l10n;
53+
/** @var IAppManager|MockObject */
54+
private $appManager;
55+
56+
protected function setUp(): void {
57+
$this->themingDefaults = $this->createMock(ThemingDefaults::class);
58+
$this->userSession = $this->createMock(IUserSession::class);
59+
$this->urlGenerator = $this->createMock(IURLGenerator::class);
60+
$this->imageManager = $this->createMock(ImageManager::class);
61+
$this->config = $this->createMock(IConfig::class);
62+
$this->l10n = $this->createMock(IL10N::class);
63+
$this->appManager = $this->createMock(IAppManager::class);
64+
65+
$this->util = new Util(
66+
$this->config,
67+
$this->appManager,
68+
$this->createMock(IAppData::class),
69+
$this->imageManager
70+
);
71+
72+
$this->themingDefaults
73+
->expects($this->any())
74+
->method('getColorPrimary')
75+
->willReturn('#0082c9');
76+
77+
$this->themingDefaults
78+
->expects($this->any())
79+
->method('getDefaultColorPrimary')
80+
->willReturn('#0082c9');
81+
82+
$this->themingDefaults
83+
->expects($this->any())
84+
->method('getBackground')
85+
->willReturn('/apps/' . Application::APP_ID . '/img/background/' . BackgroundService::DEFAULT_BACKGROUND_IMAGE);
86+
87+
$this->l10n
88+
->expects($this->any())
89+
->method('t')
90+
->willReturnCallback(function ($text, $parameters = []) {
91+
return vsprintf($text, $parameters);
92+
});
93+
94+
$this->urlGenerator
95+
->expects($this->any())
96+
->method('imagePath')
97+
->willReturnCallback(function ($app = 'core', $filename = '') {
98+
return "/$app/img/$filename";
99+
});
100+
101+
$this->theme = new DarkTheme(
102+
$this->util,
103+
$this->themingDefaults,
104+
$this->userSession,
105+
$this->urlGenerator,
106+
$this->imageManager,
107+
$this->config,
108+
$this->l10n,
109+
$this->appManager,
110+
);
111+
112+
parent::setUp();
113+
}
114+
115+
116+
public function testGetId() {
117+
$this->assertEquals('dark', $this->theme->getId());
118+
}
119+
120+
public function testGetType() {
121+
$this->assertEquals(ITheme::TYPE_THEME, $this->theme->getType());
122+
}
123+
124+
public function testGetTitle() {
125+
$this->assertEquals('Dark theme', $this->theme->getTitle());
126+
}
127+
128+
public function testGetEnableLabel() {
129+
$this->assertEquals('Enable dark theme', $this->theme->getEnableLabel());
130+
}
131+
132+
public function testGetDescription() {
133+
$this->assertEquals('A dark theme to ease your eyes by reducing the overall luminosity and brightness.', $this->theme->getDescription());
134+
}
135+
136+
public function testGetMediaQuery() {
137+
$this->assertEquals('(prefers-color-scheme: dark)', $this->theme->getMediaQuery());
138+
}
139+
140+
public function testGetCustomCss() {
141+
$this->assertEquals('', $this->theme->getCustomCss());
142+
}
143+
}

0 commit comments

Comments
 (0)