Skip to content

Commit

Permalink
fix: dark mode when javascript disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
SethFalco committed Nov 26, 2023
1 parent e4319aa commit 92c7c86
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
3 changes: 2 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ const config = {
"/.well-known/**"
]
}
]
],
"./src/plugins/prefers-color-scheme.js"
],
themes: [
'@docusaurus/theme-live-codeblock',
Expand Down
78 changes: 78 additions & 0 deletions src/plugins/prefers-color-scheme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
const postcss = require('postcss');

/**
* Docusaurus theming depends on JavaScript by default. This drops that in
* favor of `prefers-color-scheme`.
*
* Doesn't work for components styled with Prism like code blocks.
*
* @param {Object} context
* @returns {Object}
*/
function prefersColorScheme(context) {
const themeConfig = context.siteConfig.themeConfig;
const { colorMode } = themeConfig;

return {
name: 'prefers-color-scheme',
configurePostCss(postCssOptions) {
if (colorMode.disableSwitch && colorMode.respectPrefersColorScheme) {
/** @type {postcss.Plugin} */
const plugin = {
postcssPlugin: 'PrefersColorSchemePlugin',
Rule(rule) {
if (!rule.parent) {
return;
}

const pattern = /\[data-theme=(["']|)([^"']+)\1\]/;
const newSelectors = [];

for (const selector of rule.selectors) {
const match = pattern.exec(selector);

if (!match) {
newSelectors.push(selector);
continue;
}

const [fullMatch, , theme] = match;

// Replace attribute selector ([data-theme]) with an always
// matching selector of equal specificity (0, 1, 0)
const trimmed = selector.replace(fullMatch, '');
const newSelector =
trimmed.length > 0 ? `${trimmed}:not(._)` : ':root';

const newRule = rule.clone();
newRule.selector = newSelector;
newRule.selectors = [newSelector];

const media = new postcss.AtRule({
name: 'media',
params: `(prefers-color-scheme: ${theme})`,
nodes: [newRule],
});

rule.parent.insertBefore(rule, media);
}

if (newSelectors.length === 0) {
rule.remove();
return;
}

rule.selector = newSelectors.join(',');
rule.selectors = newSelectors;
},
};

postCssOptions.plugins.push(plugin);
}

return postCssOptions;
},
};
}

module.exports = prefersColorScheme;

0 comments on commit 92c7c86

Please sign in to comment.