Skip to content

Commit 120b2ff

Browse files
authored
home config option (#1689)
* home config option * remove unused logo option * make logo style custom * tiny polish * docs * tests, normalize home
1 parent 4ca8e9e commit 120b2ff

File tree

6 files changed

+52
-12
lines changed

6 files changed

+52
-12
lines changed

docs/config.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,16 @@ In this case, the path to the stylesheet is resolved relative to the page’s Ma
104104

105105
## title
106106

107-
The app’s title. If specified, this text is used for the link to the home page in the sidebar, and to complement the titles of the webpages. For instance, a page titled “Sales” in an app titled “ACME, Inc.” will display “Sales | ACME, Inc.” in the browser’s title bar. If not specified, the home page link will appear as “Home” in the sidebar, and page titles will be shown as-is.
107+
The app’s title. If specified, this text is appended to page titles with a separating pipe symbol (“|”). For instance, a page titled “Sales” in an app titled “ACME, Inc.” will display “Sales | ACME, Inc.” in the browser’s title bar. See also the [**home** option](#home).
108108

109109
## sidebar
110110

111111
Whether to show the sidebar. Defaults to true if **pages** is not empty.
112112

113+
## home <a href="https://github.com/observablehq/framework/pull/1689" class="observablehq-version-badge" data-version="prerelease" title="Added in #1689"></a>
114+
115+
An HTML fragment to render the link to the home page in the top of the sidebar. Defaults to the [app’s title](#title), if any, and otherwise the word “Home”. If specified as a function, receives an object with the page’s `title`, (front-matter) `data`, and `path`, and must return a string.
116+
113117
## pages
114118

115119
An array containing pages and sections. If not specified, it defaults to all Markdown files found in the source root in directory listing order.

docs/style.css

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ code:not(pre code, h1 code, h2 code, h3 code, h4 code, h5 code, h6 code) {
4646
text-decoration: none;
4747
}
4848

49-
#observablehq-header a[target="_blank"]:hover span,
50-
.observablehq-link a[target="_blank"]:hover span {
49+
#observablehq-header a[target="_blank"]:is(:hover, :focus) span,
50+
.observablehq-link a[target="_blank"]:is(:hover, :focus) span {
5151
text-decoration: underline;
5252
}
5353

@@ -96,10 +96,25 @@ h1 {
9696

9797
@container not (min-width: 640px) {
9898
.hide-if-small {
99-
display: none;
99+
display: none !important;
100100
}
101101
}
102102

103+
@media (min-width: calc(640px + 6rem + 272px)) {
104+
#observablehq-sidebar-toggle:is(:checked, :indeterminate) ~ #observablehq-center .hide-if-sidebar {
105+
display: none !important;
106+
}
107+
}
108+
109+
#observablehq-sidebar > ol:first-child > li::before {
110+
display: none;
111+
}
112+
113+
#observablehq-sidebar > ol:first-child > li > a {
114+
background: none;
115+
color: inherit;
116+
}
117+
103118
a.observablehq-version-badge {
104119
font: 500 12px var(--sans-serif);
105120
display: inline-block;

observablehq.config.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,24 @@ export default {
114114
: ""
115115
}
116116
<script type="module">/Win/.test(navigator.platform) || Array.from(document.querySelectorAll(".win"), (e) => e.remove())</script>`,
117-
header: `<a href="https://observablehq.com/" target="_self" rel="" style="display: flex; align-items: center;">
117+
home: `<span style="display: flex; align-items: center; font-weight: 500; gap: 0.25rem; margin-left: -0.5rem; color: var(--theme-foreground);">
118118
<svg width="22" height="22" viewBox="0 0 21.92930030822754 22.68549919128418" fill="currentColor">
119119
<path d="M10.9646 18.9046C9.95224 18.9046 9.07507 18.6853 8.33313 18.2467C7.59386 17.8098 7.0028 17.1909 6.62722 16.4604C6.22789 15.7003 5.93558 14.8965 5.75735 14.0684C5.56825 13.1704 5.47613 12.2574 5.48232 11.3427C5.48232 10.6185 5.52984 9.92616 5.62578 9.26408C5.7208 8.60284 5.89715 7.93067 6.15391 7.24843C6.41066 6.56618 6.74143 5.97468 7.14438 5.47308C7.56389 4.9592 8.1063 4.54092 8.72969 4.25059C9.38391 3.93719 10.1277 3.78091 10.9646 3.78091C11.977 3.78091 12.8542 4.00021 13.5962 4.43879C14.3354 4.87564 14.9265 5.49454 15.3021 6.22506C15.6986 6.97704 15.9883 7.7744 16.1719 8.61712C16.3547 9.459 16.447 10.3681 16.447 11.3427C16.447 12.067 16.3995 12.7593 16.3035 13.4214C16.2013 14.1088 16.0206 14.7844 15.7644 15.437C15.4994 16.1193 15.1705 16.7108 14.7739 17.2124C14.3774 17.714 13.8529 18.1215 13.1996 18.4349C12.5463 18.7483 11.8016 18.9046 10.9646 18.9046ZM12.8999 13.3447C13.4242 12.8211 13.7159 12.0966 13.7058 11.3427C13.7058 10.5639 13.4436 9.89654 12.92 9.34074C12.3955 8.78495 11.7441 8.50705 10.9646 8.50705C10.1852 8.50705 9.53376 8.78495 9.00928 9.34074C8.49569 9.87018 8.21207 10.5928 8.22348 11.3427C8.22348 12.1216 8.48572 12.7889 9.00928 13.3447C9.53376 13.9005 10.1852 14.1784 10.9646 14.1784C11.7441 14.1784 12.3891 13.9005 12.8999 13.3447ZM10.9646 22.6855C17.0199 22.6855 21.9293 17.6068 21.9293 11.3427C21.9293 5.07871 17.0199 0 10.9646 0C4.90942 0 0 5.07871 0 11.3427C0 17.6068 4.90942 22.6855 10.9646 22.6855Z"></path>
120120
</svg>
121-
</a>
122-
<div style="display: flex; flex-grow: 1; justify-content: space-between; align-items: baseline;">
123-
<a href="/">
124-
<span class="hide-if-small">Observable</span> Framework
125-
</a>
121+
Observable Framework
122+
</span>`,
123+
header: `<div style="display: flex; flex-grow: 1; justify-content: space-between; align-items: center;">
124+
<div>
125+
<a href="/" class="hide-if-sidebar" style="display: flex; align-items: center; gap: 0.25rem;">
126+
<svg width="22" height="22" viewBox="0 0 21.92930030822754 22.68549919128418" fill="currentColor">
127+
<path d="M10.9646 18.9046C9.95224 18.9046 9.07507 18.6853 8.33313 18.2467C7.59386 17.8098 7.0028 17.1909 6.62722 16.4604C6.22789 15.7003 5.93558 14.8965 5.75735 14.0684C5.56825 13.1704 5.47613 12.2574 5.48232 11.3427C5.48232 10.6185 5.52984 9.92616 5.62578 9.26408C5.7208 8.60284 5.89715 7.93067 6.15391 7.24843C6.41066 6.56618 6.74143 5.97468 7.14438 5.47308C7.56389 4.9592 8.1063 4.54092 8.72969 4.25059C9.38391 3.93719 10.1277 3.78091 10.9646 3.78091C11.977 3.78091 12.8542 4.00021 13.5962 4.43879C14.3354 4.87564 14.9265 5.49454 15.3021 6.22506C15.6986 6.97704 15.9883 7.7744 16.1719 8.61712C16.3547 9.459 16.447 10.3681 16.447 11.3427C16.447 12.067 16.3995 12.7593 16.3035 13.4214C16.2013 14.1088 16.0206 14.7844 15.7644 15.437C15.4994 16.1193 15.1705 16.7108 14.7739 17.2124C14.3774 17.714 13.8529 18.1215 13.1996 18.4349C12.5463 18.7483 11.8016 18.9046 10.9646 18.9046ZM12.8999 13.3447C13.4242 12.8211 13.7159 12.0966 13.7058 11.3427C13.7058 10.5639 13.4436 9.89654 12.92 9.34074C12.3955 8.78495 11.7441 8.50705 10.9646 8.50705C10.1852 8.50705 9.53376 8.78495 9.00928 9.34074C8.49569 9.87018 8.21207 10.5928 8.22348 11.3427C8.22348 12.1216 8.48572 12.7889 9.00928 13.3447C9.53376 13.9005 10.1852 14.1784 10.9646 14.1784C11.7441 14.1784 12.3891 13.9005 12.8999 13.3447ZM10.9646 22.6855C17.0199 22.6855 21.9293 17.6068 21.9293 11.3427C21.9293 5.07871 17.0199 0 10.9646 0C4.90942 0 0 5.07871 0 11.3427C0 17.6068 4.90942 22.6855 10.9646 22.6855Z"></path>
128+
</svg>
129+
<span>
130+
<span class="hide-if-small">Observable</span>
131+
Framework
132+
</span>
133+
</a>
134+
</div>
126135
<span style="display: flex; align-items: baseline; gap: 1rem; font-size: 14px;">
127136
<a target="_blank" title="${
128137
process.env.npm_package_version

src/config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import op from "node:path";
55
import {basename, dirname, extname, join} from "node:path/posix";
66
import {cwd} from "node:process";
77
import {pathToFileURL} from "node:url";
8+
import he from "he";
89
import type MarkdownIt from "markdown-it";
910
import wrapAnsi from "wrap-ansi";
1011
import {visitFiles} from "./files.js";
@@ -79,6 +80,7 @@ export interface Config {
7980
root: string; // defaults to src
8081
output: string; // defaults to dist
8182
base: string; // defaults to "/"
83+
home: string; // defaults to the (escaped) title, or "Home"
8284
title?: string;
8385
sidebar: boolean; // defaults to true if pages isn’t empty
8486
pages: (Page | Section<Page>)[];
@@ -112,6 +114,7 @@ export interface ConfigSpec {
112114
header?: unknown;
113115
footer?: unknown;
114116
interpreters?: unknown;
117+
home?: unknown;
115118
title?: unknown;
116119
pages?: unknown;
117120
pager?: unknown;
@@ -244,6 +247,7 @@ export function normalizeConfig(spec: ConfigSpec = {}, defaultRoot?: string, wat
244247
markdownIt: spec.markdownIt as any
245248
});
246249
const title = spec.title === undefined ? undefined : String(spec.title);
250+
const home = spec.home === undefined ? he.escape(title ?? "Home") : String(spec.home); // eslint-disable-line import/no-named-as-default-member
247251
const pages = spec.pages === undefined ? undefined : normalizePages(spec.pages);
248252
const pager = spec.pager === undefined ? true : Boolean(spec.pager);
249253
const dynamicPaths = normalizeDynamicPaths(spec.dynamicPaths);
@@ -272,6 +276,7 @@ export function normalizeConfig(spec: ConfigSpec = {}, defaultRoot?: string, wat
272276
root,
273277
output,
274278
base,
279+
home,
275280
title,
276281
sidebar: sidebar!, // see below
277282
pages: pages!, // see below

src/render.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,15 @@ function registerFile(
132132
}
133133

134134
async function renderSidebar(options: RenderOptions, {resolveImport, resolveLink}: Resolvers): Promise<Html> {
135-
const {title = "Home", pages, root, path, search} = options;
135+
const {home, pages, root, path, search} = options;
136136
return html`<input id="observablehq-sidebar-toggle" type="checkbox" title="Toggle sidebar">
137137
<label id="observablehq-sidebar-backdrop" for="observablehq-sidebar-toggle"></label>
138138
<nav id="observablehq-sidebar">
139139
<ol>
140140
<label id="observablehq-sidebar-close" for="observablehq-sidebar-toggle"></label>
141141
<li class="observablehq-link${
142142
normalizePath(path) === "/index" ? " observablehq-link-active" : ""
143-
}"><a href="${encodeURI(resolveLink("/"))}">${title}</a></li>
143+
}"><a href="${encodeURI(resolveLink("/"))}">${html.unsafe(home)}</a></li>
144144
</ol>${
145145
search
146146
? html`\n <div id="observablehq-search"><input type="search" placeholder="Search"></div>

test/config-test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ describe("readConfig(undefined, root)", () => {
3434
}
3535
],
3636
title: undefined,
37+
home: "Home",
3738
toc: {label: "On this page", show: true},
3839
pager: true,
3940
scripts: [],
@@ -61,6 +62,7 @@ describe("readConfig(undefined, root)", () => {
6162
sidebar: true,
6263
pages: [{name: "Build test case", path: "/simple", pager: "main"}],
6364
title: undefined,
65+
home: "Home",
6466
toc: {label: "Contents", show: true},
6567
pager: true,
6668
scripts: [],
@@ -84,6 +86,11 @@ describe("normalizeConfig(spec, root)", () => {
8486
assert.strictEqual(config({pages: []}, root).title, undefined);
8587
assert.strictEqual(config({title: undefined, pages: []}, root).title, undefined);
8688
});
89+
it("defaults the home to the escaped title", () => {
90+
assert.strictEqual(config({title: "dollar&pound", pages: []}, root).home, "dollar&amp;pound");
91+
assert.strictEqual(config({title: 42, pages: []}, root).home, "42");
92+
assert.strictEqual(config({title: null, pages: []}, root).home, "null");
93+
});
8794
it("populates default pages", () => {
8895
assert.deepStrictEqual(config({}, root).pages, [
8996
{name: "One", path: "/one", pager: "main"},

0 commit comments

Comments
 (0)