Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sidebar changes #386

Merged
merged 16 commits into from
Dec 15, 2023
11 changes: 11 additions & 0 deletions docs/dashboard.css
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a placeholder for #60 so we can more easily test the default dashboard styles.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@media (prefers-color-scheme: light) {
:root {
--theme-background: color-mix(in srgb, var(--theme-background-alt) 97%, black);
--theme-background-alt: rgb(255, 255, 255);
}
}

#observablehq-main,
#observablehq-footer {
max-width: initial;
}
3 changes: 3 additions & 0 deletions docs/dashboard.md
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page is unlisted, so it’s okay that it’s empty.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<link rel="stylesheet" type="text/css" href="dashboard.css">

# Dashboard theme test
134 changes: 70 additions & 64 deletions public/style.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
:root {
--observablehq-blue: #3b5fc0;
--theme-background: rgb(255, 255, 255);
--theme-background-alt: color-mix(in srgb, var(--theme-background) 95%, black);
--theme-background-alt: color-mix(in srgb, var(--theme-background) 97%, black);
--theme-foreground: rgb(27, 30, 35);
--theme-foreground-alt: color-mix(in srgb, var(--theme-foreground) 90%, var(--theme-background));
--theme-foreground-muted: color-mix(in srgb, var(--theme-foreground) 70%, var(--theme-background));
--theme-foreground-faint: color-mix(in srgb, var(--theme-foreground) 50%, var(--theme-background));
--theme-foreground-fainter: color-mix(in srgb, var(--theme-foreground) 30%, var(--theme-background));
--theme-foreground-faintest: color-mix(in srgb, var(--theme-foreground) 10%, var(--theme-background));
--theme-foreground-focus: #3182bd;
--theme-foreground-focus: var(--observablehq-blue);
--theme-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M5 7L8.125 9.5L11.25 7' stroke='rgb(27, 30, 35)' stroke-width='1.5' stroke-linecap='round' fill='none'/%3E%3C/svg%3E");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d rather have this inherit the currentColor, but that isn’t possible with data URL SVG. We could switch to an icon font to fix this, or generate inline SVG as I did for the sidebar toggle icon. It’s not a pressing issue, but it would make it easier for users to implement custom themes since then the caret icon would automatically inherit --theme-foreground.

--monospace: Menlo, Consolas, monospace;
--monospace-font: 14px/1.5 var(--monospace);
--serif: "Source Serif Pro", "Iowan Old Style", "Apple Garamond", "Palatino Linotype", "Times New Roman", "Droid Serif", Times, serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
Expand All @@ -20,7 +22,8 @@
--theme-foreground: rgb(223, 223, 214);
--theme-background: rgb(31, 31, 31);
--theme-background-alt: color-mix(in srgb, var(--theme-background) 70%, black);
--theme-foreground-focus: #20bbfc;
--theme-foreground-focus: oklch(from var(--observablehq-blue) calc(l + 20) calc(c + 0.1) h);
--theme-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M5 7L8.125 9.5L11.25 7' stroke='rgb(223, 223, 214)' stroke-width='1.5' stroke-linecap='round' fill='none'/%3E%3C/svg%3E");
}
}

Expand Down Expand Up @@ -109,7 +112,7 @@ body {
}

#observablehq-center {
margin: 1rem;
margin: 1rem 2rem;
}

#observablehq-sidebar {
Expand All @@ -118,12 +121,13 @@ body {
color: var(--theme-foreground-muted);
font: 14px var(--sans-serif);
font-weight: 500;
width: 240px;
width: 272px;
z-index: 2;
top: 0;
bottom: 0;
left: calc(-240px - 2rem);
padding: 1rem;
left: -272px;
box-sizing: border-box;
padding: 0 0.5rem 1rem 0.5rem;
overflow-y: auto;
}

Expand All @@ -137,28 +141,27 @@ body {
#observablehq-sidebar > ol,
#observablehq-sidebar > details {
position: relative;
padding: 0.5rem 0 0;
padding-bottom: 0.5rem;
margin: 0.5rem 0;
}

#observablehq-sidebar ol {
padding-bottom: 1rem;
}

#observablehq-sidebar > ol,
#observablehq-sidebar > details {
position: relative;
border-top: solid 1px var(--theme-foreground-faintest);
border-bottom: solid 1px var(--theme-foreground-faintest);
}

#observablehq-sidebar > ol:first-child {
border-top: none;
position: sticky;
top: 0;
z-index: 1;
background: var(--theme-background-alt);
font-size: 16px;
font-weight: 700;
padding: 0;
padding-top: 1rem;
margin: 0;
color: var(--theme-foreground);
}

#observablehq-sidebar > ol:last-child {
border-bottom: none;
}

#observablehq-sidebar summary {
font-weight: 700;
color: var(--theme-foreground);
Expand All @@ -171,12 +174,12 @@ body {

#observablehq-sidebar summary::after {
position: absolute;
right: 1rem;
margin-top: -0.25rem;
font-weight: 700;
font-size: 20px;
content: "⟩";
right: 0.5rem;
width: 1rem;
height: 1rem;
content: var(--theme-caret);
transition: transform 250ms ease;
transform: rotate(-90deg);
transform-origin: 50% 50%;
color: var(--theme-foreground-muted);
}
Expand All @@ -186,44 +189,55 @@ body {
}

#observablehq-sidebar details[open] summary:after {
transform: rotate(90deg);
transform: rotate(0deg);
}

#observablehq-sidebar-toggle {
position: fixed;
appearance: none;
}

#observablehq-sidebar-open {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 1rem;
appearance: none;
bottom: 0;
width: 2rem;
display: flex;
align-items: center;
justify-content: center;
cursor: e-resize;
margin: 0;
padding: 2px;
cursor: pointer;
z-index: 3;
background: none;
color: var(--theme-foreground-muted);
font-weight: 700;
font-size: 20px;
z-index: 1;
}

#observablehq-sidebar-toggle::before {
content: "⟩";
#observablehq-sidebar-close {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
color: var(--theme-foreground-muted);
top: 1rem;
right: 0;
width: 2rem;
height: 2.2rem; /* 1rem padding + line-height: normal */
cursor: w-resize;
}

#observablehq-sidebar-toggle:checked::before {
content: "⟨";
#observablehq-sidebar-close:hover {
color: inherit;
}

#observablehq-sidebar summary,
.observablehq-link a {
display: block;
padding: 0.5rem 1rem;
padding: 0.5rem 1rem 0.5rem 1.5rem;
margin-left: -0.5rem;
}

#observablehq-sidebar summary:hover,
.observablehq-link-active a,
.observablehq-link a:hover {
background: var(--theme-background);
}
Expand All @@ -245,9 +259,10 @@ body {
}

#observablehq-toc nav {
width: 160px;
width: 192px;
Copy link
Contributor

@cinxmo cinxmo Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this arbitrary or based on some calculation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s the same as before, 160px + 2rem = 160px + 32px = 192px. The 160px is semi-arbitrary (10rem). The 2rem comes from 1rem of margin on either side.

margin: 2rem 0;
padding: 0 1rem;
box-sizing: border-box;
border-left: solid 1px var(--theme-foreground-faintest);
}

Expand Down Expand Up @@ -283,7 +298,7 @@ body {
.observablehq-link-active::before {
top: 0;
bottom: 0;
left: -1rem;
left: -0.5rem;
}

.observablehq-secondary-link-highlight {
Expand Down Expand Up @@ -328,51 +343,43 @@ a[href],
}
}

@media (min-width: calc(640px + 4rem + 240px + 2rem)) {
@media (min-width: calc(640px + 6rem + 272px)) {
#observablehq-sidebar {
transition: none;
}
#observablehq-sidebar-toggle:indeterminate::before {
content: "⟨";
}
#observablehq-sidebar-toggle:checked ~ #observablehq-sidebar-backdrop {
display: none;
}
#observablehq-sidebar-toggle:checked ~ #observablehq-sidebar,
#observablehq-sidebar-toggle:indeterminate ~ #observablehq-sidebar {
left: 0;
box-shadow: none;
border-right: solid 1px var(--theme-foreground-faintest);
}
#observablehq-sidebar-toggle:checked ~ #observablehq-center,
#observablehq-sidebar-toggle:indeterminate ~ #observablehq-center {
padding-left: calc(240px + 3rem);
padding-left: calc(272px + 1rem);
padding-right: 1rem;
}
pre {
border-radius: 4px;
}
}

@media (min-width: calc(640px + 4rem + 160px + 2rem)) {
@media (min-width: calc(640px + 6rem + 192px)) {
#observablehq-toc ~ #observablehq-center {
padding-right: calc(160px + 3rem);
}
#observablehq-toc ~ #observablehq-center pre {
border-radius: 4px;
padding-right: calc(192px + 1rem);
}
#observablehq-toc {
display: block;
}
}

@media (min-width: calc(640px + 4rem + 240px + 2rem)) {
@media (min-width: calc(640px + 6rem + 272px)) {
#observablehq-sidebar-toggle:checked ~ #observablehq-toc,
#observablehq-sidebar-toggle:indeterminate ~ #observablehq-toc {
display: none;
}
}

@media (min-width: calc(640px + 4rem + 240px + 2rem + 160px + 2rem)) {
@media (min-width: calc(640px + 6rem + 272px + 192px)) {
#observablehq-sidebar-toggle:checked ~ #observablehq-toc,
#observablehq-sidebar-toggle:indeterminate ~ #observablehq-toc,
#observablehq-toc {
Expand All @@ -381,18 +388,16 @@ a[href],
#observablehq-sidebar-toggle:checked ~ #observablehq-toc ~ #observablehq-center,
#observablehq-sidebar-toggle:indeterminate ~ #observablehq-toc ~ #observablehq-center,
#observablehq-toc ~ #observablehq-center {
padding-right: calc(160px + 3rem);
padding-right: calc(192px + 1rem);
}
}

@media (hover: hover) {
#observablehq-sidebar-toggle:not(:checked):not(:hover)::before {
content: "";
#observablehq-sidebar-open {
transition: color 150ms ease;
}
@media (min-width: calc(640px + 4rem + 240px + 2rem)) {
#observablehq-sidebar-toggle:indeterminate:not(:checked):not(:hover)::before {
content: "⟨";
}
#observablehq-sidebar-open:not(:hover) {
color: transparent;
}
}

Expand Down Expand Up @@ -528,6 +533,7 @@ hr {
pre {
position: relative;
background-color: var(--theme-background-alt);
border-radius: 4px;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have 2rem of margin on the center, the pre elements with -1rem horizontal margin never touch the side of the window, and so we can always have a border-radius.

margin: 1rem -1rem;
max-width: 960px;
min-height: 1.5em;
Expand Down
14 changes: 14 additions & 0 deletions src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,27 @@ ${renderFooter(path, options)}

async function renderSidebar(title = "Home", pages: (Page | Section)[], path: string): Promise<Html> {
return html`<input id="observablehq-sidebar-toggle" type="checkbox">
<label id="observablehq-sidebar-open" for="observablehq-sidebar-toggle" title="Open sidebar">
<svg width="16" height="16" viewBox="0 0 16 16">
<path d="m10.5,11 2.5-3-2.5-3 M6,8h7" fill="none" stroke="currentColor" stroke-width="2"/>
<rect x="2" y="2" fill="currentColor" height="12" rx="0.5" width="2"/>
</svg>
</label>
<label id="observablehq-sidebar-backdrop" for="observablehq-sidebar-toggle"></label>
<nav id="observablehq-sidebar">
<ol>
<li class="observablehq-link${path === "/index" ? " observablehq-link-active" : ""}"><a href="${relativeUrl(
path,
"/"
)}">${title}</a></li>
<label id="observablehq-sidebar-close" for="observablehq-sidebar-toggle" title="Close sidebar">
<svg width="16" height="16" viewBox="0 0 16 16">
<g transform="rotate(180 8,8)">
<path d="m10.5,11 2.5-3-2.5-3 M6,8h7" fill="none" stroke="currentColor" stroke-width="2"/>
<rect x="2" y="2" fill="currentColor" height="12" rx="0.5" width="2"/>
</g>
</svg>
</label>
</ol>
<ol>${pages.map((p, i) =>
"pages" in p
Expand Down
14 changes: 14 additions & 0 deletions test/output/build/archives/tar.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,24 @@

</script>
<input id="observablehq-sidebar-toggle" type="checkbox">
<label id="observablehq-sidebar-open" for="observablehq-sidebar-toggle" title="Open sidebar">
<svg width="16" height="16" viewBox="0 0 16 16">
<path d="m10.5,11 2.5-3-2.5-3 M6,8h7" fill="none" stroke="currentColor" stroke-width="2"/>
<rect x="2" y="2" fill="currentColor" height="12" rx="0.5" width="2"/>
</svg>
</label>
<label id="observablehq-sidebar-backdrop" for="observablehq-sidebar-toggle"></label>
<nav id="observablehq-sidebar">
<ol>
<li class="observablehq-link"><a href="./">Home</a></li>
<label id="observablehq-sidebar-close" for="observablehq-sidebar-toggle" title="Close sidebar">
<svg width="16" height="16" viewBox="0 0 16 16">
<g transform="rotate(180 8,8)">
<path d="m10.5,11 2.5-3-2.5-3 M6,8h7" fill="none" stroke="currentColor" stroke-width="2"/>
<rect x="2" y="2" fill="currentColor" height="12" rx="0.5" width="2"/>
</g>
</svg>
</label>
</ol>
<ol>
<li class="observablehq-link observablehq-link-active"><a href="./tar">Tar</a></li>
Expand Down
14 changes: 14 additions & 0 deletions test/output/build/archives/zip.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,24 @@

</script>
<input id="observablehq-sidebar-toggle" type="checkbox">
<label id="observablehq-sidebar-open" for="observablehq-sidebar-toggle" title="Open sidebar">
<svg width="16" height="16" viewBox="0 0 16 16">
<path d="m10.5,11 2.5-3-2.5-3 M6,8h7" fill="none" stroke="currentColor" stroke-width="2"/>
<rect x="2" y="2" fill="currentColor" height="12" rx="0.5" width="2"/>
</svg>
</label>
<label id="observablehq-sidebar-backdrop" for="observablehq-sidebar-toggle"></label>
<nav id="observablehq-sidebar">
<ol>
<li class="observablehq-link"><a href="./">Home</a></li>
<label id="observablehq-sidebar-close" for="observablehq-sidebar-toggle" title="Close sidebar">
<svg width="16" height="16" viewBox="0 0 16 16">
<g transform="rotate(180 8,8)">
<path d="m10.5,11 2.5-3-2.5-3 M6,8h7" fill="none" stroke="currentColor" stroke-width="2"/>
<rect x="2" y="2" fill="currentColor" height="12" rx="0.5" width="2"/>
</g>
</svg>
</label>
</ol>
<ol>
<li class="observablehq-link"><a href="./tar">Tar</a></li>
Expand Down
Loading