Skip to content

Commit 44e7f84

Browse files
respect-user-color-scheme: take prefers-color-schema instead of author default
fixes #1470 respect-user-color-schema defaults to false use static tests for user default color scheme since we do not support dynamic change of prefers-color-scheme yet
1 parent f09661a commit 44e7f84

21 files changed

+307
-30
lines changed

news/changelog-1.7.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ All changes included in 1.7:
6161
- ([#12277](https://github.com/quarto-dev/quarto-cli/pull/12277)): Provide light and dark plot and table renderings with `renderings: [light,dark]`
6262
- ([#11860](https://github.com/quarto-dev/quarto-cli/issues/11860)): ES6 modules that import other local JS modules in documents with `embed-resources: true` are now correctly embedded.
6363
- ([#1325](https://github.com/quarto-dev/quarto-cli/issues/1325)): Dark Mode pages should not flash light on reload. (Nor should Light Mode pages flash dark.)
64+
- ([#1470](https://github.com/quarto-dev/quarto-cli/issues/1470)): `respect-user-color-scheme` enables checking the media query `prefers-color-scheme` for user preference. This is only on page load, not dynamically. Author preference still influences stylesheet order and therefore NoJS experience. Defaults to `false`, leaving to author preference.
6465
- ([#12307](https://github.com/quarto-dev/quarto-cli/issues/12307)): Tabsets using `tabby.js` in non-boostrap html (`theme: pandoc`, `theme: none` or `minimal: true`) now correctly render reactive content when `server: shiny` is used.
6566
- ([#12356](https://github.com/quarto-dev/quarto-cli/issues/12356)): Remove duplicate id in HTML document when using `#lst-` prefix label for using Quarto crossref.
6667

src/config/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export const kHtmlTableProcessing = "html-table-processing";
142142
export const kHtmlPreTagProcessing = "html-pre-tag-processing";
143143
export const kCssPropertyProcessing = "css-property-processing";
144144
export const kBrandMode = "brand-mode";
145+
export const kRespectUserColorScheme = "respect-user-color-scheme";
145146
export const kUseRsvgConvert = "use-rsvg-convert";
146147
export const kValidateYaml = "validate-yaml";
147148

src/format/html/format-html.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ import {
2424
kFigResponsive,
2525
kFilterParams,
2626
kHeaderIncludes,
27-
kIncludeBeforeBody,
2827
kIncludeAfterBody,
28+
kIncludeBeforeBody,
2929
kIncludeInHeader,
3030
kLinkExternalFilter,
3131
kLinkExternalIcon,
3232
kLinkExternalNewwindow,
3333
kNotebookLinks,
3434
kNotebookViewStyle,
35+
kRespectUserColorScheme,
3536
kTheme,
3637
} from "../../config/constants.ts";
3738

@@ -343,6 +344,8 @@ export async function htmlFormatExtras(
343344
options.codeTools = formatHasCodeTools(format);
344345
options.darkMode = formatDarkMode(format);
345346
options.darkModeDefault = darkModeDefault(format.metadata);
347+
options.respectUserColorScheme = format.metadata[kRespectUserColorScheme] ||
348+
false;
346349
options.linkExternalIcon = format.render[kLinkExternalIcon];
347350
options.linkExternalNewwindow = format.render[kLinkExternalNewwindow];
348351
options.linkExternalFilter = format.render[kLinkExternalFilter];
@@ -502,7 +505,7 @@ export async function htmlFormatExtras(
502505
renderEjs(
503506
formatResourcePath("html", join("hypothesis", "hypothesis.ejs")),
504507
{ hypothesis: options.hypothesis },
505-
)
508+
),
506509
);
507510
includeInHeader.push(hypothesisHeader);
508511
}
@@ -516,10 +519,12 @@ export async function htmlFormatExtras(
516519
!!options[option]
517520
);
518521
if (quartoHtmlRequired) {
519-
for(const {dest, ejsfile} of [
520-
{dest: includeBeforeBody, ejsfile: "quarto-html-before-body.ejs"},
521-
{dest: includeAfterBody, ejsfile: "quarto-html-after-body.ejs"}
522-
]) {
522+
for (
523+
const { dest, ejsfile } of [
524+
{ dest: includeBeforeBody, ejsfile: "quarto-html-before-body.ejs" },
525+
{ dest: includeAfterBody, ejsfile: "quarto-html-after-body.ejs" },
526+
]
527+
) {
523528
const quartoHtmlScript = temp.createFile();
524529
const renderedHtml = renderEjs(
525530
formatResourcePath("html", join("templates", ejsfile)),

src/resources/formats/html/templates/quarto-html-before-body.ejs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,12 @@
128128
return localAlternateSentinel;
129129
}
130130
}
131-
const darkModeDefault = <%= darkModeDefault %>;
131+
<% if (respectUserColorScheme) { %>
132+
const darkModeDefault = window.matchMedia('(prefers-color-scheme: dark)').matches;
133+
<% } else { %>
134+
const darkModeDefault = <%= darkModeDefault %>;
135+
<% } %>
136+
132137
let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
133138
134139
// Dark / light mode switch

src/resources/schema/document-options.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@
8484
formats: [$html-doc]
8585
description: Enables smooth scrolling within the page.
8686

87+
- name: respect-user-color-scheme
88+
schema: boolean
89+
default: false
90+
tags:
91+
formats: [$html-doc]
92+
description:
93+
short: "Whether the `prefers-color-scheme` media query controls dark mode."
94+
long: |
95+
Whether to use the `prefers-color-scheme` media query to determine whether to show
96+
the user a dark or light page. Otherwise the author preference (order of `light`
97+
and `dark` in `theme` or `brand`) determines what is shown to the user at first visit.
98+
8799
- name: html-math-method
88100
tags:
89101
formats: [$html-doc, $epub-all, gfm]

0 commit comments

Comments
 (0)