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
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
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
147 changes: 77 additions & 70 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='black' stroke-width='1.5' stroke-linecap='round' fill='none'/%3E%3C/svg%3E");
--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,7 @@
--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(0.712564 0.257662 265.758); /* oklch(from var(--observablehq-blue) calc(l + 20) calc(c + 0.1) h) */
}
}

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

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

#observablehq-sidebar {
Expand All @@ -118,12 +120,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 +140,29 @@ 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;
padding-left: 0.5rem;
margin: 0;
margin-left: -0.5rem;
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,59 +175,72 @@ 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;
background: var(--theme-foreground-muted);
content: "";
-webkit-mask: var(--theme-caret);
mask: var(--theme-caret);
transition: transform 250ms ease;
transform: rotate(-90deg);
transform-origin: 50% 50%;
color: var(--theme-foreground-muted);
}

#observablehq-sidebar summary:hover::after {
color: var(--theme-foreground);
}

#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 +262,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 All @@ -262,8 +280,8 @@ body {
padding: 0.25rem 0;
}

.observablehq-link a[href],
.observablehq-secondary-link a[href] {
.observablehq-link:not(.observablehq-link-active) a[href]:not(:hover),
.observablehq-secondary-link:not(.observablehq-secondary-link-active) a[href]:not(:hover) {
color: inherit;
}

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

.observablehq-secondary-link-highlight {
Expand All @@ -293,9 +311,7 @@ body {
transition: top 150ms ease, height 150ms ease;
}

a[href],
.observablehq-link-active a[href],
.observablehq-secondary-link-active a[href] {
a[href] {
color: var(--theme-foreground-focus);
}

Expand Down Expand Up @@ -328,51 +344,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 +389,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 +534,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
Loading