Merge pull request #19195 from dvdksn/improve-sidebar-initial-state

site: make it faster
This commit is contained in:
David Karlsson 2024-01-25 13:07:58 +01:00 committed by GitHub
commit b41cdf9c02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 131 additions and 109 deletions

View File

@ -19,8 +19,8 @@
}
.external-link {
.icon:after {
@apply text-base ml-1;
.icon-svg svg {
@apply text-base ml-1 align-top;
}
}

View File

@ -1,19 +1,11 @@
@layer utilities {
.icon {
font-family: "Material Symbols Rounded";
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
}
.icon:after {
content: attr(data-icon);
.icon-svg {
svg {
font-size: 24px;
width: 1em;
height: 1em;
display: inline-block;
fill: currentColor;
}
}
}

View File

@ -1,20 +1,14 @@
// Scroll the given menu item into view. We actually pick the item *above*
// the current item to give some headroom above
function scrollMenuItem() {
let item = sectiontree.querySelector('[aria-current="page"]');
if (!item) return;
item = item.parentElement.closest("li");
if (item) {
const itemY = item.getBoundingClientRect().y;
// scroll to the item y-coord (with a 150px padding for some head room)
if (itemY > window.innerHeight - 150) {
sidebar.scrollTop = itemY - 150;
}
}
function toggleMenuItem(event) {
const section = event.currentTarget.parentElement;
const icons = event.currentTarget.querySelectorAll(".icon-svg");
const subsection = section.querySelector("ul");
subsection.classList.toggle("hidden");
icons.forEach(i => i.classList.toggle('hidden'))
}
const sectiontree = document.querySelector("#sectiontree");
const sidebar = document.querySelector("#sidebar");
if (sectiontree && sidebar) {
scrollMenuItem();
if (sectiontree) {
for (const button of sectiontree.querySelectorAll("button")) {
button.addEventListener("click", toggleMenuItem);
}
}

View File

@ -21,7 +21,7 @@ grid:
link: /admin/organization/registry-access/
- title: General settings
description: Configure general information or create a company.
icon: settings_suggest
icon: settings
link: /admin/organization/general-settings/
- title: SSO & SCIM
description: 'Set up [Single Sign-On](/security/for-admins/single-sign-on/)
@ -45,4 +45,4 @@ To create an organization, see [Create your organization](../organization/orgs.m
Learn how to administer an organization in the following sections.
{{< grid >}}
{{< grid >}}

View File

@ -26,7 +26,7 @@ grid:
link: /compose/compose-file/07-volumes/
- title: Configs top-level element
description: Find out about configs in Compose.
icon: settings_suggest
icon: settings
link: /compose/compose-file/08-configs/
- title: Secrets top-level element
description: Learn about secrets in Compose.
@ -57,4 +57,4 @@ The Compose Specification on Docker Docs is the Docker Compose implementation. I
Use the following links to navigate key sections of the Compose Specification.
{{< grid >}}
{{< grid >}}

View File

@ -51,8 +51,8 @@ grid:
icon: "publish"
description: Icon name = publish
- title: "Interacting"
icon: "multiple_stops"
description: Icon name = multiple_stops
icon: "multiple_stop"
description: Icon name = multiple_stop
- title: "Storage"
icon: "database"
description: Icon name = database
@ -141,8 +141,8 @@ grid:
description: Icon name = supervised_user_circle
icon: supervised_user_circle
- title: "General settings"
icon: "settings_suggest"
description: Icon name = settings_suggest
icon: "settings"
description: Icon name = settings
---
Below is an inventory of the icons we use to represent different topics or features across docs. To be used with the [cards component](cards.md).

View File

@ -41,7 +41,7 @@ grid_apis:
link: /docker-hub/api/latest/
- title: DVP Data API
description: API for Docker Verified Publishers to fetch analytics data.
icon: auto_graph
icon: area_chart
link: /docker-hub/api/dvp/
grid_specs:
- title: Image specification

View File

@ -7,7 +7,7 @@ grid:
icon: web_asset
link: /desktop/release-notes/
- title: Docker Engine
icon: settings_suggest
icon: developer_board
link: /engine/release-notes/
- title: Docker Compose
icon: storage

View File

@ -231,6 +231,9 @@ module:
target: assets
- source: hugo_stats.json
target: assets/watching/hugo_stats.json
- source: node_modules/@material-symbols/svg-400/rounded
target: assets/icons
imports:
- path: github.com/moby/moby

View File

@ -1,13 +1,14 @@
<div class="group relative">
<button
x-data="{ code: '{{encoding.Base64Encode .Inner}}' }"
class="material-symbols-rounded hidden group-hover:block absolute top-3 right-3 text-gray-light-300 dark:text-gray-dark-600"
x-data="{ code: '{{encoding.Base64Encode .Inner}}', copying: false }"
class="absolute top-3 right-3 text-gray-light-300 dark:text-gray-dark-600"
title="Copy"
@click="window.navigator.clipboard.writeText(atob(code).replaceAll(/^\$\s*/gm, ''));
$el.textContent='check_circle';
setTimeout(() => $el.textContent='content_copy', 2000);"
copying = true;
setTimeout(() => copying = false, 2000);"
>
content_copy
<span :class="{ 'group-hover:block' : !copying }" class="hidden icon-svg">{{ partial "icon" "content_copy" }}</span>
<span :class="{ 'group-hover:block' : copying }" class="hidden icon-svg">{{ partial "icon" "check_circle" }}</span>
</button>
{{ $result := transform.HighlightCodeBlock . }}
<div class="syntax-light dark:syntax-dark">

View File

@ -34,9 +34,9 @@
class="fixed z-20 inset-0 flex items-center justify-center bg-black/70 p-6"
>
<button
class="material-symbols-rounded fixed z-30 top-6 right-8 text-white text-5xl"
class="text-white fixed z-30 top-6 right-8 icon-svg"
>
close
{{ partial "icon" "close" }}
</button>
<img
class="rounded max-w-full max-h-full"

View File

@ -5,9 +5,11 @@
class="link external-link"
href="{{ $url | safeURL }}"
target="_blank"
rel="noopener"
>{{ .Text | safeHTML }}<span
class="icon" data-icon="open_in_new"></span></a>
rel="noopener">
{{- .Text | safeHTML -}}
<span class="icon-svg">
{{- partial "icon" "open_in_new" -}}
</span></a>
{{- else if (strings.HasPrefix $url "/") -}}
{{/* absolute link, use url as-is */}}
<a class="link" href="{{ $url }}">{{ .Text | safeHTML }}</a>

View File

@ -5,27 +5,24 @@
{{ partial "head.html" . }}
</head>
<body
class="bg-background-light dark:bg-background-dark text-base divide-y divide-divider-light dark:divide-divider-dark flex flex-col h-max dark:text-white">
<body class="min-w-fit bg-background-light text-base dark:bg-background-dark dark:text-white">
{{ partial "header.html" . }}
<main class="min-h-screen flex items-stretch">
<main class="grid grid-cols-main md:flex xl:grid-cols-main-xl">
<div id="sidebar"
class="z-10 flex flex-col items-end sticky top-16 h-[calc(100vh-theme(space.16))] overflow-y-scroll flex-shrink-0 flex-grow md:fixed md:w-screen md:hidden bg-background-light dark:bg-gray-dark-100">
class="sticky top-16 h-[calc(100lvh-theme(space.16))] overflow-y-scroll flex flex-row-reverse dark:bg-gray-dark-100 md:fixed md:z-10 md:hidden md:h-screen md:w-screen">
{{ block "left" . }}
{{ end }}
</div>
<div class="w-[840px] flex flex-col lg:w-full lg:flex-grow px-8 pb-16 sm:px-4 overflow-hidden">
<div class="p-6 pt-0">
{{ block "main" . }}
{{ end }}
</div>
<div class="sticky w-[300px] top-16 p-5 h-[calc(100vh-theme(space.16))] flex-grow overflow-y-auto lg:hidden">
<div class="sticky top-16 h-[calc(100lvh-theme(space.16))] overflow-y-scroll lg:hidden">
{{ block "right" . }}
{{ end }}
</div>
</main>
<footer>
{{ partialCached "footer.html" . }}
</footer>
<footer>{{ partialCached "footer.html" . }}</footer>
</body>
</html>

View File

@ -1,6 +1,4 @@
<aside class="space-y-4 lg:hidden w-[300px]">
<div class="space-y-2">
{{ partial "github-links.html" . }}
</div>
<aside class="py-4 space-y-4">
{{ partial "github-links.html" . }}
{{ partial "toc-default.html" . }}
</aside>

View File

@ -1,10 +1,8 @@
<div x-data="{ open: false }" class="border border-gray-light-200 dark:border-gray-dark-200 bg-white dark:bg-gray-dark-100">
<button class="not-prose w-full py-2 px-4 flex justify-between" x-on:click="open = ! open">
<span>{{ .title }}</span>
<span
class="material-symbols-rounded text-gray-light dark:text-gray-dark"
x-text="open ? 'expand_less' : 'expand_more'"
></span>
<span :class="{ 'hidden' : !open }" class="icon-svg">{{ partial "icon" "expand_less" }}</span>
<span :class="{ 'hidden' : open }" class="icon-svg">{{ partial "icon" "expand_more" }}</span>
</button>
<div x-show="open" x-collapse class="px-4">

View File

@ -33,7 +33,7 @@
<img class="w-[32px] invertible" src="{{ . }}" alt="">
{{ else }}
{{/* icon ligature */}}
<span class="material-symbols-rounded text-[32px]">{{ . }}</span>
<span class="icon-svg">{{ partial "icon" . }}</span>
{{ end }}
{{ end }}
<div>

View File

@ -2,19 +2,22 @@
{{ with .File }}
{{ if not (in .Filename "/_vendor/") }}
<p class="flex items-center gap-2">
<span class="material-symbols-rounded">edit</span>
<span class="icon-svg">{{ partial "icon" "edit" }}</span>
<a class="link external-link" target="_blank" rel="noopener"
href="{{ site.Params.repo }}/edit/main/content/{{ .Path }}">{{ T "editPage" }}
<span class="icon" data-icon="open_in_new"></span>
</a>
<span class="icon-svg">
{{- partial "icon" "open_in_new" -}}
</span></a>
</p>
{{ end }}
{{ end }}
<p class="flex items-center gap-2">
<span class="material-symbols-rounded">done</span>
<span class="icon-svg">{{ partial "icon" "done" }}</span>
<a class="link external-link" target="_blank" rel="noopener"
href="{{ site.Params.repo }}/issues/new?template=doc_issue.yml&location={{ .Permalink }}&labels=status%2Ftriage">{{ T "requestChanges" }}
<span class="icon" data-icon="open_in_new"></span>
<span class="icon-svg">
{{- partial "icon" "open_in_new" -}}
</span></a>
</a>
</p>
{{ end }}

View File

@ -37,9 +37,8 @@
</script>
{{ end }}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap" />
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:FILL@1" rel="stylesheet" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,500&display=optional" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono&display=optional" />
{{ partial "utils/css.html" . }}
{{ $theme := resources.Get "js/theme.js" | js.Build (dict "minify" true) }}
<script>{{ $theme.Content | safeJS }}</script>

View File

@ -9,9 +9,8 @@
} else {
sidebar.classList.replace('md:block', 'md:hidden');
}
}" class="btn-icon-round menu-btn material-symbols-rounded hidden h-full px-4 md:block" aria-label="Menu"
id="menu-btn">
menu
}" class="icon-svg hidden px-4 md:block" aria-label="Menu">
{{ partial "icon" "menu" }}
</button>
<div>
{{/* main logo */}}
@ -25,11 +24,14 @@
</div>
<div class="flex items-center gap-6">
<div id="docsearch"></div>
<button id="theme-switch" tabindex="1" class="material-symbols-rounded"
<button id="theme-switch" tabindex="1" class="svg-icon"
x-data="{ theme: localStorage.getItem('theme-preference') }" x-init="$watch('theme', value => {
localStorage.setItem('theme-preference', value);
document.firstElementChild.className = value;
})" @click="theme = (theme === 'dark' ? 'light' : 'dark')" x-text="`${theme}_mode`"></button>
})" @click="theme = (theme === 'dark' ? 'light' : 'dark')">
<span class="icon-svg dark:hidden">{{ partial "icon" "light_mode"}}</span>
<span class="icon-svg hidden dark:block">{{ partial "icon" "dark_mode"}}</span>
</button>
</div>
</div>

View File

@ -0,0 +1,8 @@
{{- $svg := resources.Get (fmt.Printf "icons/%s-fill.svg" .) }}
{{- if not $svg }}
{{- errorf "Failed to get icon: %s" . }}
{{ end }}
{{- if not $svg.Content }}
{{- errorf "Failed to get icon: %s" . }}
{{- end }}
{{- safe.HTML $svg.Content -}}

View File

@ -18,14 +18,18 @@
{{ end }}
</nav>
{{ if $firstSection }}
{{ $allSections := slice }}
{{ range $i, $e := ($scratch.GetSortedMapValues "sections") }}
{{ $allSections = $allSections | append (index $e "title") }}
{{ end }}
<hr>
<nav id="sectiontree" class="text-sm w-[300px] md:w-full flex flex-col gap-2 px-3">
<div class="hidden md:block pt-4 text-gray-light dark:text-gray-dark">This section</div>
<nav id="sectiontree" class="text-sm w-[300px] md:w-full flex flex-col">
<div class="hidden md:block p-4 text-gray-light dark:text-gray-dark">This section</div>
{{/* The current page is in the table of contents */}}
<ul>
{{/* Walk the toc.yaml nodes under the current main section */}}
{{ range (index site.Data.toc $firstSection) }}
{{ template "tocRender" (dict "ctx" $ctx "entry" .) }}
{{ template "tocRender" (dict "ctx" $ctx "entry" . "sections" $allSections) }}
{{ end }}
</ul>
</nav>
@ -34,17 +38,26 @@
{{/* Recursive template for sidebar items */}}
{{ define "tocRender" }}
{{ $ctx := .ctx }}
{{ $sections := .sections }}
{{ if .entry.sectiontitle }}
{{ $expanded := in $sections .entry.sectiontitle }}
{{/* .entry is a section */}}
<li x-data="{ expanded: false }" x-init="expanded = !!$el.querySelector('a[aria-current]')" :data-expanded="expanded">
<button @click="expanded = ! expanded" class="rounded px-4 sidebar-hover w-full flex items-center justify-between">
<span class="py-2 truncate flex items-center gap-2">{{ markdownify .entry.sectiontitle }}</span>
<span class="material-symbols-rounded -my-1 md:text-[28px]" x-text="expanded ? 'expand_less' : 'expand_more'">
<li>
{{/* See event handler in assets/js/src/sidebar.js */}}
<button class="rounded px-4 sidebar-hover w-full flex items-center justify-between">
<span class="py-2 truncate flex items-center gap-2">
{{ markdownify .entry.sectiontitle }}
</span>
<span class="icon-svg {{ if $expanded }}hidden{{ end }}">
{{ partial "icon" "expand_more" }}
</span>
<span class="icon-svg {{ if not $expanded }}hidden{{ end }}">
{{ partial "icon" "expand_less" }}
</span>
</button>
<ul x-show="expanded" x-collapse class="ml-3 md:ml-[21px]">
<ul class="{{if not $expanded}}hidden {{end}}ml-3 md:ml-[21px]">
{{ range .entry.section }}
{{ template "tocRender" (dict "entry" . "ctx" $ctx) }}
{{ template "tocRender" (dict "entry" . "ctx" $ctx "sections" $sections ) }}
{{ end }}
</ul>
</li>

37
package-lock.json generated
View File

@ -11,6 +11,7 @@
"devDependencies": {
"@alpinejs/collapse": "^3.11.1",
"@docsearch/js": "^3.5.2",
"@material-symbols/svg-400": "^0.14.6",
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tailwindcss/typography": "^0.5.8",
"alpinejs": "^3.12.3",
@ -319,6 +320,12 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@material-symbols/svg-400": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/@material-symbols/svg-400/-/svg-400-0.14.6.tgz",
"integrity": "sha512-4uxXEyKljpfwlEQQE5xpN0ZOLduXC3ClCkwNtsM6xy8CLkVP1x32s8BPYHrpfGdhNNnKLkl+p8vh7VBqZi8D4A==",
"dev": true
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -608,9 +615,9 @@
}
},
"node_modules/browserslist": {
"version": "4.22.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
"integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
"version": "4.22.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
"integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
"dev": true,
"funding": [
{
@ -627,9 +634,9 @@
}
],
"dependencies": {
"caniuse-lite": "^1.0.30001541",
"electron-to-chromium": "^1.4.535",
"node-releases": "^2.0.13",
"caniuse-lite": "^1.0.30001565",
"electron-to-chromium": "^1.4.601",
"node-releases": "^2.0.14",
"update-browserslist-db": "^1.0.13"
},
"bin": {
@ -649,9 +656,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001543",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001543.tgz",
"integrity": "sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA==",
"version": "1.0.30001580",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001580.tgz",
"integrity": "sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==",
"dev": true,
"funding": [
{
@ -1379,9 +1386,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
"version": "1.4.540",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.540.tgz",
"integrity": "sha512-aoCqgU6r9+o9/S7wkcSbmPRFi7OWZWiXS9rtjEd+Ouyu/Xyw5RSq2XN8s5Qp8IaFOLiRrhQCphCIjAxgG3eCAg==",
"version": "1.4.645",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.645.tgz",
"integrity": "sha512-EeS1oQDCmnYsRDRy2zTeC336a/4LZ6WKqvSaM1jLocEk5ZuyszkQtCpsqvuvaIXGOUjwtvF6LTcS8WueibXvSw==",
"dev": true
},
"node_modules/elkjs": {
@ -2431,9 +2438,9 @@
}
},
"node_modules/node-releases": {
"version": "2.0.13",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
"dev": true
},
"node_modules/non-layered-tidy-tree-layout": {

View File

@ -16,6 +16,7 @@
"devDependencies": {
"@alpinejs/collapse": "^3.11.1",
"@docsearch/js": "^3.5.2",
"@material-symbols/svg-400": "^0.14.6",
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tailwindcss/typography": "^0.5.8",
"alpinejs": "^3.12.3",

View File

@ -4,6 +4,10 @@ module.exports = {
darkMode: "class",
theme: {
extend: {
gridTemplateColumns: {
"main": 'minmax(300px, 1fr) 840px minmax(300px, 1fr)',
"main-xl": '300px 840px minmax(0, 1fr)',
},
typography: (theme) => ({
DEFAULT: {
css: {