Skip to content

Commit 2803caa

Browse files
default to alternate logo or brand
if dark mode is enabled and we don't have data using the opposite data is the best we can do having some trouble with this approach for sidebar seems ugly to resolve this in render-contexts and to have inconsistency between format.render.brand and project.resolveBrand() but this is where we know if theme is enabling dark mode provisional commit to test in CI
1 parent 6ce6420 commit 2803caa

File tree

11 files changed

+179
-29
lines changed

11 files changed

+179
-29
lines changed

src/command/render/render-contexts.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ import {
8686
import { ExtensionContext } from "../../extension/types.ts";
8787
import { NotebookContext } from "../../render/notebook/notebook-types.ts";
8888
import { safeCloneDeep } from "../../core/safe-clone-deep.ts";
89+
import { darkModeDefaultMetadata } from "../../format/html/format-html-info.ts";
8990

9091
export async function resolveFormatsFromMetadata(
9192
metadata: Metadata,
@@ -570,6 +571,19 @@ async function resolveFormats(
570571
// resolve brand in project and forward it to format
571572
const brand = await project.resolveBrand(target.source);
572573
mergedFormats[format].render.brand = brand;
574+
if (
575+
mergedFormats[format].render.brand &&
576+
!mergedFormats[format].render.brand.dark &&
577+
darkModeDefaultMetadata(mergedFormats[format].metadata) !== undefined
578+
) {
579+
// there is no dark brand specified but the theme enables dark mode
580+
// so we need to copy the light brand to the dark brand
581+
// https://github.com/quarto-dev/quarto-cli/issues/12981
582+
583+
mergedFormats[format].render.brand.dark = ld.cloneDeep(
584+
mergedFormats[format].render.brand.light,
585+
);
586+
}
573587

574588
// apply defaults from brand yaml under the metadata of the current format
575589
const brandFormatDefaults: Metadata =

src/core/brand/brand.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ export function resolveLogo(
327327
};
328328
if (!spec) {
329329
return {
330-
light: findLogo("light", order),
331-
dark: findLogo("dark", order),
330+
light: findLogo("light", order) || findLogo("dark", order),
331+
dark: findLogo("dark", order) || findLogo("light", order),
332332
};
333333
}
334334
if (typeof spec === "string") {
@@ -358,6 +358,15 @@ export function resolveLogo(
358358
} else {
359359
dark = resolveLogoOptions("dark", spec.dark);
360360
}
361+
// light logo default to dark logo if no light logo specified
362+
if (!light && dark) {
363+
light = { ...dark };
364+
}
365+
// dark logo default to light logo if no dark logo specified
366+
// and dark mode is enabled
367+
if (!dark && light && brand && brand.dark) {
368+
dark = { ...light };
369+
}
361370
return {
362371
light,
363372
dark,

src/format/dashboard/format-dashboard.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export function dashboardFormat() {
122122
}
123123
}
124124

125-
const brand = await project.resolveBrand(input);
125+
const brand = format.render.brand;
126126
let logoSpec = format.metadata[kLogo] as LogoLightDarkSpecifier;
127127
if (typeof logoSpec === "string" && format.metadata[kLogoAlt]) {
128128
logoSpec = {
@@ -135,7 +135,6 @@ export function dashboardFormat() {
135135
"medium",
136136
"large",
137137
]);
138-
console.log("dash logo", format.metadata[kLogo]);
139138

140139
const extras: FormatExtras = await baseHtmlFormat.formatExtras(
141140
input,

src/format/html/format-html-info.ts

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,48 @@ export function formatDarkMode(format: Format): boolean | undefined {
3838
return undefined;
3939
}
4040

41-
export function darkModeDefault(format: Format): boolean | undefined {
42-
const metadata = format.metadata;
43-
const brand = format.render.brand;
44-
if (metadata !== undefined) {
45-
if (metadata[kTheme] && typeof metadata[kTheme] === "object") {
46-
const keys = Object.keys(metadata[kTheme]);
47-
if (keys.includes("dark")) {
48-
if (keys[0] === "dark") {
49-
return true;
50-
} else {
51-
return false;
52-
}
41+
// there are two stages of knowing whether dark mode is enabled:
42+
// 1. from the start we can look at theme and brand metadata to see if there is
43+
// a dark theme or brand
44+
// 2. later, after brand is loaded, we'll know whether unified brand enabled dark mode
45+
// in practice, we only know
46+
export function darkModeDefaultMetadata(
47+
metadata: Metadata,
48+
): boolean | undefined {
49+
if (metadata[kTheme] && typeof metadata[kTheme] === "object") {
50+
const keys = Object.keys(metadata[kTheme]);
51+
if (keys.includes("dark")) {
52+
if (keys[0] === "dark") {
53+
return true;
54+
} else {
55+
return false;
5356
}
5457
}
55-
if (metadata[kBrand] || brand) {
56-
if (metadata[kBrand] && typeof metadata[kBrand] === "object") {
57-
const keys = Object.keys(metadata[kBrand]);
58-
if (keys.includes("dark")) {
59-
if (keys[0] === "dark") {
60-
return true;
61-
} else {
62-
return false;
63-
}
64-
}
65-
}
66-
if (brand && brand.dark) {
67-
// unified brand has no author preference but it can have dark mode
58+
}
59+
if (metadata[kBrand] && typeof metadata[kBrand] === "object") {
60+
const keys = Object.keys(metadata[kBrand]);
61+
if (keys.includes("dark")) {
62+
if (keys[0] === "dark") {
63+
return true;
64+
} else {
6865
return false;
6966
}
7067
}
7168
}
7269
return undefined;
7370
}
71+
export function darkModeDefault(format: Format): boolean | undefined {
72+
const metadata = format.metadata;
73+
if (metadata !== undefined) {
74+
const dmdm = darkModeDefaultMetadata(metadata);
75+
if (dmdm !== undefined) {
76+
return dmdm;
77+
}
78+
}
79+
const brand = format.render.brand;
80+
if (brand && brand.dark) {
81+
// unified brand has no author preference but it can have dark mode
82+
return false;
83+
}
84+
return undefined;
85+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
logo:
2+
images:
3+
light-logo:
4+
path: light-logo.png
5+
alt: light logo
6+
dark-logo:
7+
path: dark-logo.png
8+
alt: dark logo
9+
small:
10+
light: light-logo
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
title: Yes dark logo if theme enables dark mode
3+
format:
4+
dashboard:
5+
theme:
6+
light: default
7+
dark: darkly # Explicitly enable dark mode
8+
brand: logo-light-only.yml
9+
logo:
10+
light: quarto.png
11+
_quarto:
12+
tests:
13+
dashboard:
14+
ensureHtmlElements:
15+
-
16+
- 'img[src="quarto.png"][alt=""][class="navbar-logo light-content d-inline-block"]'
17+
- 'img[src="light-logo.png"][alt="light logo"][class="navbar-logo dark-content d-inline-block"]'
18+
- []
19+
---
20+
21+
22+
There is ambiguity whether this should use `quarto.png` for the dark logo, since
23+
the brand provides no dark logos, but if that's the intention then use
24+
25+
```yaml
26+
logo: quarto.png
27+
```
28+
29+
30+
{{< lipsum 4 >}}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
title: Yes dark logo if theme enables dark mode
3+
format:
4+
dashboard:
5+
theme:
6+
light: default
7+
dark: darkly
8+
brand:
9+
logo:
10+
images:
11+
light-logo:
12+
path: light-logo.png
13+
alt: light logo
14+
small:
15+
light: light-logo
16+
logo:
17+
light: quarto.png
18+
_quarto:
19+
tests:
20+
dashboard:
21+
ensureHtmlElements:
22+
-
23+
- 'img[src="quarto.png"][alt=""][class="navbar-logo light-content d-inline-block"]'
24+
- 'img[src="light-logo.png"][alt="light logo"][class="navbar-logo dark-content d-inline-block"]'
25+
- []
26+
---
27+
28+
There is ambiguity whether this should use `quarto.png` for the dark logo, since
29+
the brand provides no dark logos, but if that's the intention then use
30+
31+
```yaml
32+
logo: quarto.png
33+
```
34+
35+
36+
{{< lipsum 4 >}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/.quarto/
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
project:
2+
type: default
3+
format:
4+
dashboard:
5+
theme:
6+
light: default
7+
dark: darkly # Explicitly enable dark mode
8+
brand: logo-light-only.yml
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
logo:
2+
images:
3+
light-logo:
4+
path: light-logo.png
5+
alt: light logo
6+
small:
7+
light: light-logo
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: Yes dark logo if theme enables dark mode
3+
logo:
4+
light: quarto.png
5+
_quarto:
6+
tests:
7+
dashboard:
8+
ensureHtmlElements:
9+
-
10+
- 'img[src="quarto.png"][alt=""][class="navbar-logo light-content d-inline-block"]'
11+
- 'img[src="light-logo.png"][alt="light logo"][class="navbar-logo dark-content d-inline-block"]'
12+
- []
13+
---
14+
15+
16+
There is ambiguity whether this should use `quarto.png` for the dark logo, since
17+
the brand provides no dark logos, but if that's the intention then use
18+
19+
```yaml
20+
logo: quarto.png
21+
```
22+
23+
24+
{{< lipsum 4 >}}

0 commit comments

Comments
 (0)