feat(core): add pure black mode for dark theme

This commit is contained in:
alistair3149 2024-04-25 15:45:24 -04:00
parent 405eef0b9a
commit 5768ccc25b
No known key found for this signature in database
10 changed files with 127 additions and 69 deletions

View file

@ -53,5 +53,10 @@
"citizen-theme-day-label": "Light",
"citizen-theme-night-label": "Dark",
"citizen-theme-os-label": "Auto",
"citizen-theme-exclusion-notice": "This page is always in light mode."
"citizen-theme-exclusion-notice": "This page is always in light mode.",
"citizen-feature-pure-black-name": "Pure black mode",
"citizen-feature-pure-black-description": "Pure black mode",
"citizen-feature-pure-black-0-label": "Off",
"citizen-feature-pure-black-1-label": "On"
}

View file

@ -55,5 +55,9 @@
"citizen-theme-day-label": "Label for light/day theme.",
"citizen-theme-night-label": "Label for dark/night theme.",
"citizen-theme-os-label": "Label for automatic theme (which respects any operating system setting).",
"citizen-theme-exclusion-notice": "Text that informs you that the page is always in light/day mode."
"citizen-theme-exclusion-notice": "Text that informs you that the page is always in light/day mode.",
"citizen-feature-pure-black-name": "Pure black mode",
"citizen-feature-pure-black-description": "Pure black mode",
"citizen-feature-pure-black-0-label": "Off",
"citizen-feature-pure-black-1-label": "On"
}

View file

@ -148,7 +148,8 @@ class SkinCitizen extends SkinMustache {
* @param array &$options
*/
private function buildSkinFeatures( array &$options ) {
$title = $this->getOutput()->getTitle();
$out = $this->getOutput();
$title = $out->getTitle();
$metadata = new Metadata( $this );
$skinTheme = new Theme( $this );
@ -162,6 +163,9 @@ class SkinCitizen extends SkinMustache {
// Disable default ToC since it is handled by Citizen
$options['toc'] = false;
// Clientprefs feature handling
$out->addHtmlClasses( 'citizen-feature-pure-black-clientpref-0' );
// Collapsible sections
// Load in content pages
if ( $title !== null && $title->isContentPage() ) {

View file

@ -2,5 +2,9 @@
"skin-theme": {
"options": [ "os", "day", "night" ],
"preferenceKey": "citizen-theme"
},
"citizen-feature-pure-black": {
"options": [ "0", "1" ],
"preferenceKey": "citizen-pure-black"
}
}

View file

@ -98,6 +98,18 @@
// New clientPrefs styles
.citizen-client-prefs {
display: flex;
flex-direction: column;
gap: var( --space-xs );
form {
display: grid;
// This is not the best because it does not adapt to the text length but will revisit later
grid-template-columns: 1fr 1fr;
gap: var( --space-xxs );
text-align: center;
}
&-radio {
&__input {
// Hide radio button because we use label as button
@ -138,15 +150,7 @@
}
#skin-client-prefs-skin-theme {
form {
display: grid;
// This is not the best because it does not adapt to the text length but will revisit later
grid-template-columns: 1fr 1fr;
gap: var( --space-xxs );
text-align: center;
}
label {
.citizen-client-prefs-radio__label {
background: var( --color-surface-0 );
&[ for='skin-client-pref-skin-theme-value-day' ] {
@ -165,6 +169,25 @@
}
}
#skin-client-prefs-citizen-feature-pure-black {
display: none;
// Display on dark theme
.skin-theme-clientpref-night & {
display: block;
}
@media ( prefers-color-scheme: dark ) {
.skin-theme-clientpref-os & {
display: block;
}
}
.citizen-client-prefs-radio__label[ for='skin-client-pref-citizen-feature-pure-black-value-1' ] {
background-color: #000;
}
}
@media ( hover: hover ) {
.citizen-pref:hover .citizen-pref__button .citizen-ui-icon::before {
transform: rotate3d( 0, 0, 1, 90deg );

View file

@ -11,7 +11,7 @@
<aside id="citizen-pref-panel" class="citizen-pref-panel">
<header id="citizen-pref-header">{{msg-preferences}}</header>
<div id="citizen-client-prefs"></div>
<div class="citizen-client-prefs" id="citizen-client-prefs"></div>
<form id="citizen-pref-form">
{{! Font size }}
<fieldset class="citizen-pref-item" id="citizen-pref-fontsize">

View file

@ -0,0 +1,11 @@
.citizen-feature-pure-black-clientpref-1 {
:root.skin-theme-clientpref-night& {
--color-surface-0: #000;
}
@media ( prefers-color-scheme: dark ) {
:root.skin-theme-clientpref-os& {
--color-surface-0: #000;
}
}
}

View file

@ -1,3 +1,49 @@
/**
* Dark theme mixin
* Dark theme needs a mixin because it is being used by the auto theme as well
*/
.theme-dark() {
--color-primary__l: 60%;
--color-surface-0: ~'hsl( var( --color-primary__h ), 20%, 10% )';
--color-surface-1: ~'hsl( var( --color-primary__h ), 25%, 12% )';
--color-surface-2: ~'hsl( var( --color-primary__h ), 25%, 15% )';
--color-surface-3: ~'hsl( var( --color-primary__h ), 15%, 20% )';
--color-surface-4: ~'hsl( var( --color-primary__h ), 15%, 25% )';
--color-base--emphasized: ~'hsl( var( --color-primary__h ), 80%, 95% )';
--color-base: ~'hsl( var( --color-primary__h ), 25%, 80% )';
--color-base--subtle: ~'hsl( var( --color-primary__h ), 25%, 65% )';
--background-color-primary--hover: ~'hsl( var( --color-primary__h ), var( --color-primary__s ), 15% )';
--background-color-primary--active: ~'hsl( var( --color-primary__h ), var( --color-primary__s ), 20% )';
--background-color-overlay: ~'hsla( var( --color-primary__h ), 20%, 10%, 0.95 )';
--background-color-overlay--lighter: ~'hsla( var( --color-primary__h ), 20%, 10%, 0.6 )';
--color-surface-2--hover: ~'hsl( var( --color-primary__h ), 30%, 19% )';
--color-surface-2--active: ~'hsl( var( --color-primary__h ), 30%, 11% )';
--border-color-base: rgba( 255, 255, 255, 0.05 );
--border-color-subtle: rgba( 255, 255, 255, 0.02 );
--border-color-interactive: rgba( 255, 255, 255, 0.08 );
--surface-shadow: var( --color-primary__h ), 50%, 3%;
--shadow-strength: 0.8;
--filter-invert: invert( 1 ) hue-rotate( 180deg );
--font-grade: -25;
// FIXME: Browsers seem to treat GRAD differently, disabling for now
// Dark theme usually have an illusion of thicker fonts
// So we have to tune it back
// font-variation-settings: 'GRAD' -90;
color-scheme: dark;
}
/**
* Base/light theme
*/
@ -47,6 +93,18 @@
--shadow-strength: 0.02;
--font-grade: 0;
// Dark theme
&.skin-theme-clientpref-night {
.theme-dark();
}
// Auto theme
@media ( prefers-color-scheme: dark ) {
&.skin-theme-clientpref-os {
.theme-dark();
}
}
}
a {
@ -54,58 +112,3 @@ a {
--color-link--hover: ~'var( --color-primary--hover )';
--color-link--active: ~'var( --color-primary--active )';
}
/**
* Dark theme
* Dark theme needs a mixin because it is being used by the auto theme as well
*/
.theme-dark() {
--color-primary__l: 60%;
--color-surface-0: ~'hsl( var( --color-primary__h ), 20%, 10% )';
--color-surface-1: ~'hsl( var( --color-primary__h ), 25%, 12% )';
--color-surface-2: ~'hsl( var( --color-primary__h ), 25%, 15% )';
--color-surface-3: ~'hsl( var( --color-primary__h ), 15%, 20% )';
--color-surface-4: ~'hsl( var( --color-primary__h ), 15%, 25% )';
--color-base--emphasized: ~'hsl( var( --color-primary__h ), 80%, 95% )';
--color-base: ~'hsl( var( --color-primary__h ), 25%, 80% )';
--color-base--subtle: ~'hsl( var( --color-primary__h ), 25%, 65% )';
--background-color-primary--hover: ~'hsl( var( --color-primary__h ), var( --color-primary__s ), 15% )';
--background-color-primary--active: ~'hsl( var( --color-primary__h ), var( --color-primary__s ), 20% )';
--background-color-overlay: ~'hsla( var( --color-primary__h ), 20%, 10%, 0.95 )';
--background-color-overlay--lighter: ~'hsla( var( --color-primary__h ), 20%, 10%, 0.6 )';
--color-surface-2--hover: ~'hsl( var( --color-primary__h ), 30%, 19% )';
--color-surface-2--active: ~'hsl( var( --color-primary__h ), 30%, 11% )';
--border-color-base: rgba( 255, 255, 255, 0.05 );
--border-color-subtle: rgba( 255, 255, 255, 0.02 );
--border-color-interactive: rgba( 255, 255, 255, 0.08 );
--surface-shadow: var( --color-primary__h ), 50%, 3%;
--shadow-strength: 0.8;
--filter-invert: invert( 1 ) hue-rotate( 180deg );
--font-grade: -25;
// FIXME: Browsers seem to treat GRAD differently, disabling for now
// Dark theme usually have an illusion of thicker fonts
// So we have to tune it back
// font-variation-settings: 'GRAD' -90;
color-scheme: dark;
}
:root.skin-theme-clientpref-night {
.theme-dark();
}
@media ( prefers-color-scheme: dark ) {
:root.skin-theme-clientpref-os {
.theme-dark();
}
}

View file

@ -18,6 +18,7 @@
@media screen {
@import 'layout.less';
@import 'common/theme.less';
@import 'common/features.less';
@import 'common/common.less';
@import 'common/content.less';
@import 'common/scrollbar.less';

View file

@ -246,7 +246,10 @@
"citizen-theme-day-label",
"citizen-theme-night-label",
"citizen-theme-os-label",
"citizen-theme-exclusion-notice"
"citizen-theme-exclusion-notice",
"citizen-feature-pure-black-name",
"citizen-feature-pure-black-0-label",
"citizen-feature-pure-black-1-label"
],
"dependencies": [
"mediawiki.storage",