From 7b7a31b20633d516898db6a4439277d46202081c Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:25:01 +0100 Subject: [PATCH 01/13] Sidebar: Add nested exampleSite for sidebar testing --- .../content/test-product/sidebar/_index.md | 10 +++ .../test-product/sidebar/nesting-1a/_index.md | 7 ++ .../test-product/sidebar/nesting-1b/_index.md | 4 + .../sidebar/nesting-1b/nesting-2/_index.md | 4 + .../nesting-1b/nesting-2/nesting-2-1.md | 6 ++ .../nesting-1b/nesting-2/nesting-2-2.md | 87 +++++++++++++++++++ .../nesting-1b/nesting-2/nesting-3/_index.md | 4 + .../test-product/sidebar/nesting-1c/_index.md | 4 + .../sidebar/nesting-1c/nesting-2/_index.md | 4 + .../nesting-1c/nesting-2/nesting-2-1.md | 6 ++ .../nesting-1c/nesting-2/nesting-2-2.md | 87 +++++++++++++++++++ .../nesting-1c/nesting-2/nesting-3/_index.md | 4 + 12 files changed, 227 insertions(+) create mode 100644 exampleSite/content/test-product/sidebar/_index.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1a/_index.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1b/_index.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/_index.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-2-1.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-2-2.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-3/_index.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1c/_index.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/_index.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-2-1.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-2-2.md create mode 100644 exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-3/_index.md diff --git a/exampleSite/content/test-product/sidebar/_index.md b/exampleSite/content/test-product/sidebar/_index.md new file mode 100644 index 0000000..878b6ab --- /dev/null +++ b/exampleSite/content/test-product/sidebar/_index.md @@ -0,0 +1,10 @@ +--- +description: Sidebar +title: Sidebar +--- + +This is the overview page for level 0. The root. This is an `_index.md` file. + +Because there is some content in this `_index.md` file, it should be displayed. + +If it were empty, we'd skip this and go straight to the first populated content in this tree. \ No newline at end of file diff --git a/exampleSite/content/test-product/sidebar/nesting-1a/_index.md b/exampleSite/content/test-product/sidebar/nesting-1a/_index.md new file mode 100644 index 0000000..79dce29 --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1a/_index.md @@ -0,0 +1,7 @@ +--- +description: Nesting-1a +title: Nesting-1a +--- + + +1a only has content at this level. This is an `_index.md` file. \ No newline at end of file diff --git a/exampleSite/content/test-product/sidebar/nesting-1b/_index.md b/exampleSite/content/test-product/sidebar/nesting-1b/_index.md new file mode 100644 index 0000000..23035ac --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1b/_index.md @@ -0,0 +1,4 @@ +--- +description: Nesting-1b +title: Nesting-1b +--- diff --git a/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/_index.md b/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/_index.md new file mode 100644 index 0000000..e25a6fe --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/_index.md @@ -0,0 +1,4 @@ +--- +description: Nesting-2 +title: Nesting-2 +--- diff --git a/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-2-1.md b/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-2-1.md new file mode 100644 index 0000000..d043889 --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-2-1.md @@ -0,0 +1,6 @@ +--- +description: Nesting-2-content-1 +title: Nesting-2-content-1 +--- + +This is some content in Nesting-2-content-1 \ No newline at end of file diff --git a/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-2-2.md b/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-2-2.md new file mode 100644 index 0000000..74e5b71 --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-2-2.md @@ -0,0 +1,87 @@ +--- +description: Nesting-2-content-2 +title: Nesting-2-content-2 +--- + +This is some content in Nesting-2-content-2. + +This is long enough to push headers outside of the normal viewport. + + +## Testing some headings for the toc 1 + +Some content + + +## Testing some headings for the toc 2 + +Once upon a time in the Technicolor Cloud Kingdom of Serverlandia, a joyful wind blew across the binary meadows, whispering tales of a mystical creature named nginx (pronounced "engine-x" by the locals and "wizard-swoosh" by the jellyfish). It wasn’t a dragon, a unicorn, or a sentient avocado—it was something far more magical: a hyper-fast, ever-smiling web server with the personality of a golden retriever and the efficiency of 10,000 caffeinated squirrels. + +Every morning, nginx would wake up with a cheerful beep-boop, stretch its configuration files, and greet the sun with a reverse proxy pirouette. Birds chirped in HTTP headers, and butterflies fluttered by on compressed gzip wings. Wherever nginx went, latency dropped to zero and 404 errors turned into motivational quotes. + +“Your content is just loading its potential!” they would say, bringing tears to the eyes of developers and hummingbirds alike. + +The townsfolk of Serverlandia adored nginx. They built shrines out of old USB cables and offered it snacks made of finely spun JSON. Even the databases—who were notoriously grumpy—would sing praises of nginx’s load balancing lullabies. Apache, the wise old monk of the hills, once tried to challenge nginx to a duel of requests-per-second, but halfway through the contest he just sighed, gave nginx a hug, and invited it to tea. + +At night, nginx would tuck in the children of the village by wrapping their bedtime stories in TLS encryption and caching their dreams for extra speed. Unicorns danced across CDN rainbows, singing songs about scalability and uptime. The moon itself would giggle as nginx gracefully handled a billion concurrent connections while baking cookies shaped like serverless functions. + +Even the grumpy firewall trolls came around, offering friendly port forwards and warm handshakes. Life was good. Load times were fast. The air smelled faintly of peppermint and perfectly formed XML. + +And thus, in a land where packets flowed like chocolate rivers and downtime was just a scary campfire story, nginx reigned supreme—not with power, but with kindness, balance, and beautifully efficient asynchronous processing. + +Everyone lived happily ever after, behind seven layers of security and a content delivery network that sparkled in the sky. + + +## Testing some headings for the toc 3 + +Once upon a time in the Technicolor Cloud Kingdom of Serverlandia, a joyful wind blew across the binary meadows, whispering tales of a mystical creature named nginx (pronounced "engine-x" by the locals and "wizard-swoosh" by the jellyfish). It wasn’t a dragon, a unicorn, or a sentient avocado—it was something far more magical: a hyper-fast, ever-smiling web server with the personality of a golden retriever and the efficiency of 10,000 caffeinated squirrels. + +Every morning, nginx would wake up with a cheerful beep-boop, stretch its configuration files, and greet the sun with a reverse proxy pirouette. Birds chirped in HTTP headers, and butterflies fluttered by on compressed gzip wings. Wherever nginx went, latency dropped to zero and 404 errors turned into motivational quotes. + +“Your content is just loading its potential!” they would say, bringing tears to the eyes of developers and hummingbirds alike. + +The townsfolk of Serverlandia adored nginx. They built shrines out of old USB cables and offered it snacks made of finely spun JSON. Even the databases—who were notoriously grumpy—would sing praises of nginx’s load balancing lullabies. Apache, the wise old monk of the hills, once tried to challenge nginx to a duel of requests-per-second, but halfway through the contest he just sighed, gave nginx a hug, and invited it to tea. + +At night, nginx would tuck in the children of the village by wrapping their bedtime stories in TLS encryption and caching their dreams for extra speed. Unicorns danced across CDN rainbows, singing songs about scalability and uptime. The moon itself would giggle as nginx gracefully handled a billion concurrent connections while baking cookies shaped like serverless functions. + +Even the grumpy firewall trolls came around, offering friendly port forwards and warm handshakes. Life was good. Load times were fast. The air smelled faintly of peppermint and perfectly formed XML. + +And thus, in a land where packets flowed like chocolate rivers and downtime was just a scary campfire story, nginx reigned supreme—not with power, but with kindness, balance, and beautifully efficient asynchronous processing. + +Everyone lived happily ever after, behind seven layers of security and a content delivery network that sparkled in the sky. + +## Testing some headings for the toc 4 + +Once upon a time in the Technicolor Cloud Kingdom of Serverlandia, a joyful wind blew across the binary meadows, whispering tales of a mystical creature named nginx (pronounced "engine-x" by the locals and "wizard-swoosh" by the jellyfish). It wasn’t a dragon, a unicorn, or a sentient avocado—it was something far more magical: a hyper-fast, ever-smiling web server with the personality of a golden retriever and the efficiency of 10,000 caffeinated squirrels. + +Every morning, nginx would wake up with a cheerful beep-boop, stretch its configuration files, and greet the sun with a reverse proxy pirouette. Birds chirped in HTTP headers, and butterflies fluttered by on compressed gzip wings. Wherever nginx went, latency dropped to zero and 404 errors turned into motivational quotes. + +“Your content is just loading its potential!” they would say, bringing tears to the eyes of developers and hummingbirds alike. + +The townsfolk of Serverlandia adored nginx. They built shrines out of old USB cables and offered it snacks made of finely spun JSON. Even the databases—who were notoriously grumpy—would sing praises of nginx’s load balancing lullabies. Apache, the wise old monk of the hills, once tried to challenge nginx to a duel of requests-per-second, but halfway through the contest he just sighed, gave nginx a hug, and invited it to tea. + +At night, nginx would tuck in the children of the village by wrapping their bedtime stories in TLS encryption and caching their dreams for extra speed. Unicorns danced across CDN rainbows, singing songs about scalability and uptime. The moon itself would giggle as nginx gracefully handled a billion concurrent connections while baking cookies shaped like serverless functions. + +Even the grumpy firewall trolls came around, offering friendly port forwards and warm handshakes. Life was good. Load times were fast. The air smelled faintly of peppermint and perfectly formed XML. + +And thus, in a land where packets flowed like chocolate rivers and downtime was just a scary campfire story, nginx reigned supreme—not with power, but with kindness, balance, and beautifully efficient asynchronous processing. + +Everyone lived happily ever after, behind seven layers of security and a content delivery network that sparkled in the sky. + +## Testing some headings for the toc 5 + +Once upon a time in the Technicolor Cloud Kingdom of Serverlandia, a joyful wind blew across the binary meadows, whispering tales of a mystical creature named nginx (pronounced "engine-x" by the locals and "wizard-swoosh" by the jellyfish). It wasn’t a dragon, a unicorn, or a sentient avocado—it was something far more magical: a hyper-fast, ever-smiling web server with the personality of a golden retriever and the efficiency of 10,000 caffeinated squirrels. + +Every morning, nginx would wake up with a cheerful beep-boop, stretch its configuration files, and greet the sun with a reverse proxy pirouette. Birds chirped in HTTP headers, and butterflies fluttered by on compressed gzip wings. Wherever nginx went, latency dropped to zero and 404 errors turned into motivational quotes. + +“Your content is just loading its potential!” they would say, bringing tears to the eyes of developers and hummingbirds alike. + +The townsfolk of Serverlandia adored nginx. They built shrines out of old USB cables and offered it snacks made of finely spun JSON. Even the databases—who were notoriously grumpy—would sing praises of nginx’s load balancing lullabies. Apache, the wise old monk of the hills, once tried to challenge nginx to a duel of requests-per-second, but halfway through the contest he just sighed, gave nginx a hug, and invited it to tea. + +At night, nginx would tuck in the children of the village by wrapping their bedtime stories in TLS encryption and caching their dreams for extra speed. Unicorns danced across CDN rainbows, singing songs about scalability and uptime. The moon itself would giggle as nginx gracefully handled a billion concurrent connections while baking cookies shaped like serverless functions. + +Even the grumpy firewall trolls came around, offering friendly port forwards and warm handshakes. Life was good. Load times were fast. The air smelled faintly of peppermint and perfectly formed XML. + +And thus, in a land where packets flowed like chocolate rivers and downtime was just a scary campfire story, nginx reigned supreme—not with power, but with kindness, balance, and beautifully efficient asynchronous processing. + +Everyone lived happily ever after, behind seven layers of security and a content delivery network that sparkled in the sky. \ No newline at end of file diff --git a/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-3/_index.md b/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-3/_index.md new file mode 100644 index 0000000..c7494ae --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1b/nesting-2/nesting-3/_index.md @@ -0,0 +1,4 @@ +--- +description: Nesting-3 +title: Nesting-3 +--- diff --git a/exampleSite/content/test-product/sidebar/nesting-1c/_index.md b/exampleSite/content/test-product/sidebar/nesting-1c/_index.md new file mode 100644 index 0000000..a6bd5a3 --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1c/_index.md @@ -0,0 +1,4 @@ +--- +description: Nesting-1c +title: Nesting-1c +--- diff --git a/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/_index.md b/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/_index.md new file mode 100644 index 0000000..e25a6fe --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/_index.md @@ -0,0 +1,4 @@ +--- +description: Nesting-2 +title: Nesting-2 +--- diff --git a/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-2-1.md b/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-2-1.md new file mode 100644 index 0000000..d043889 --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-2-1.md @@ -0,0 +1,6 @@ +--- +description: Nesting-2-content-1 +title: Nesting-2-content-1 +--- + +This is some content in Nesting-2-content-1 \ No newline at end of file diff --git a/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-2-2.md b/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-2-2.md new file mode 100644 index 0000000..74e5b71 --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-2-2.md @@ -0,0 +1,87 @@ +--- +description: Nesting-2-content-2 +title: Nesting-2-content-2 +--- + +This is some content in Nesting-2-content-2. + +This is long enough to push headers outside of the normal viewport. + + +## Testing some headings for the toc 1 + +Some content + + +## Testing some headings for the toc 2 + +Once upon a time in the Technicolor Cloud Kingdom of Serverlandia, a joyful wind blew across the binary meadows, whispering tales of a mystical creature named nginx (pronounced "engine-x" by the locals and "wizard-swoosh" by the jellyfish). It wasn’t a dragon, a unicorn, or a sentient avocado—it was something far more magical: a hyper-fast, ever-smiling web server with the personality of a golden retriever and the efficiency of 10,000 caffeinated squirrels. + +Every morning, nginx would wake up with a cheerful beep-boop, stretch its configuration files, and greet the sun with a reverse proxy pirouette. Birds chirped in HTTP headers, and butterflies fluttered by on compressed gzip wings. Wherever nginx went, latency dropped to zero and 404 errors turned into motivational quotes. + +“Your content is just loading its potential!” they would say, bringing tears to the eyes of developers and hummingbirds alike. + +The townsfolk of Serverlandia adored nginx. They built shrines out of old USB cables and offered it snacks made of finely spun JSON. Even the databases—who were notoriously grumpy—would sing praises of nginx’s load balancing lullabies. Apache, the wise old monk of the hills, once tried to challenge nginx to a duel of requests-per-second, but halfway through the contest he just sighed, gave nginx a hug, and invited it to tea. + +At night, nginx would tuck in the children of the village by wrapping their bedtime stories in TLS encryption and caching their dreams for extra speed. Unicorns danced across CDN rainbows, singing songs about scalability and uptime. The moon itself would giggle as nginx gracefully handled a billion concurrent connections while baking cookies shaped like serverless functions. + +Even the grumpy firewall trolls came around, offering friendly port forwards and warm handshakes. Life was good. Load times were fast. The air smelled faintly of peppermint and perfectly formed XML. + +And thus, in a land where packets flowed like chocolate rivers and downtime was just a scary campfire story, nginx reigned supreme—not with power, but with kindness, balance, and beautifully efficient asynchronous processing. + +Everyone lived happily ever after, behind seven layers of security and a content delivery network that sparkled in the sky. + + +## Testing some headings for the toc 3 + +Once upon a time in the Technicolor Cloud Kingdom of Serverlandia, a joyful wind blew across the binary meadows, whispering tales of a mystical creature named nginx (pronounced "engine-x" by the locals and "wizard-swoosh" by the jellyfish). It wasn’t a dragon, a unicorn, or a sentient avocado—it was something far more magical: a hyper-fast, ever-smiling web server with the personality of a golden retriever and the efficiency of 10,000 caffeinated squirrels. + +Every morning, nginx would wake up with a cheerful beep-boop, stretch its configuration files, and greet the sun with a reverse proxy pirouette. Birds chirped in HTTP headers, and butterflies fluttered by on compressed gzip wings. Wherever nginx went, latency dropped to zero and 404 errors turned into motivational quotes. + +“Your content is just loading its potential!” they would say, bringing tears to the eyes of developers and hummingbirds alike. + +The townsfolk of Serverlandia adored nginx. They built shrines out of old USB cables and offered it snacks made of finely spun JSON. Even the databases—who were notoriously grumpy—would sing praises of nginx’s load balancing lullabies. Apache, the wise old monk of the hills, once tried to challenge nginx to a duel of requests-per-second, but halfway through the contest he just sighed, gave nginx a hug, and invited it to tea. + +At night, nginx would tuck in the children of the village by wrapping their bedtime stories in TLS encryption and caching their dreams for extra speed. Unicorns danced across CDN rainbows, singing songs about scalability and uptime. The moon itself would giggle as nginx gracefully handled a billion concurrent connections while baking cookies shaped like serverless functions. + +Even the grumpy firewall trolls came around, offering friendly port forwards and warm handshakes. Life was good. Load times were fast. The air smelled faintly of peppermint and perfectly formed XML. + +And thus, in a land where packets flowed like chocolate rivers and downtime was just a scary campfire story, nginx reigned supreme—not with power, but with kindness, balance, and beautifully efficient asynchronous processing. + +Everyone lived happily ever after, behind seven layers of security and a content delivery network that sparkled in the sky. + +## Testing some headings for the toc 4 + +Once upon a time in the Technicolor Cloud Kingdom of Serverlandia, a joyful wind blew across the binary meadows, whispering tales of a mystical creature named nginx (pronounced "engine-x" by the locals and "wizard-swoosh" by the jellyfish). It wasn’t a dragon, a unicorn, or a sentient avocado—it was something far more magical: a hyper-fast, ever-smiling web server with the personality of a golden retriever and the efficiency of 10,000 caffeinated squirrels. + +Every morning, nginx would wake up with a cheerful beep-boop, stretch its configuration files, and greet the sun with a reverse proxy pirouette. Birds chirped in HTTP headers, and butterflies fluttered by on compressed gzip wings. Wherever nginx went, latency dropped to zero and 404 errors turned into motivational quotes. + +“Your content is just loading its potential!” they would say, bringing tears to the eyes of developers and hummingbirds alike. + +The townsfolk of Serverlandia adored nginx. They built shrines out of old USB cables and offered it snacks made of finely spun JSON. Even the databases—who were notoriously grumpy—would sing praises of nginx’s load balancing lullabies. Apache, the wise old monk of the hills, once tried to challenge nginx to a duel of requests-per-second, but halfway through the contest he just sighed, gave nginx a hug, and invited it to tea. + +At night, nginx would tuck in the children of the village by wrapping their bedtime stories in TLS encryption and caching their dreams for extra speed. Unicorns danced across CDN rainbows, singing songs about scalability and uptime. The moon itself would giggle as nginx gracefully handled a billion concurrent connections while baking cookies shaped like serverless functions. + +Even the grumpy firewall trolls came around, offering friendly port forwards and warm handshakes. Life was good. Load times were fast. The air smelled faintly of peppermint and perfectly formed XML. + +And thus, in a land where packets flowed like chocolate rivers and downtime was just a scary campfire story, nginx reigned supreme—not with power, but with kindness, balance, and beautifully efficient asynchronous processing. + +Everyone lived happily ever after, behind seven layers of security and a content delivery network that sparkled in the sky. + +## Testing some headings for the toc 5 + +Once upon a time in the Technicolor Cloud Kingdom of Serverlandia, a joyful wind blew across the binary meadows, whispering tales of a mystical creature named nginx (pronounced "engine-x" by the locals and "wizard-swoosh" by the jellyfish). It wasn’t a dragon, a unicorn, or a sentient avocado—it was something far more magical: a hyper-fast, ever-smiling web server with the personality of a golden retriever and the efficiency of 10,000 caffeinated squirrels. + +Every morning, nginx would wake up with a cheerful beep-boop, stretch its configuration files, and greet the sun with a reverse proxy pirouette. Birds chirped in HTTP headers, and butterflies fluttered by on compressed gzip wings. Wherever nginx went, latency dropped to zero and 404 errors turned into motivational quotes. + +“Your content is just loading its potential!” they would say, bringing tears to the eyes of developers and hummingbirds alike. + +The townsfolk of Serverlandia adored nginx. They built shrines out of old USB cables and offered it snacks made of finely spun JSON. Even the databases—who were notoriously grumpy—would sing praises of nginx’s load balancing lullabies. Apache, the wise old monk of the hills, once tried to challenge nginx to a duel of requests-per-second, but halfway through the contest he just sighed, gave nginx a hug, and invited it to tea. + +At night, nginx would tuck in the children of the village by wrapping their bedtime stories in TLS encryption and caching their dreams for extra speed. Unicorns danced across CDN rainbows, singing songs about scalability and uptime. The moon itself would giggle as nginx gracefully handled a billion concurrent connections while baking cookies shaped like serverless functions. + +Even the grumpy firewall trolls came around, offering friendly port forwards and warm handshakes. Life was good. Load times were fast. The air smelled faintly of peppermint and perfectly formed XML. + +And thus, in a land where packets flowed like chocolate rivers and downtime was just a scary campfire story, nginx reigned supreme—not with power, but with kindness, balance, and beautifully efficient asynchronous processing. + +Everyone lived happily ever after, behind seven layers of security and a content delivery network that sparkled in the sky. \ No newline at end of file diff --git a/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-3/_index.md b/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-3/_index.md new file mode 100644 index 0000000..c7494ae --- /dev/null +++ b/exampleSite/content/test-product/sidebar/nesting-1c/nesting-2/nesting-3/_index.md @@ -0,0 +1,4 @@ +--- +description: Nesting-3 +title: Nesting-3 +--- From 40d09c7c6e7d34925c05798dd11428dc83c6f5ad Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Thu, 1 May 2025 16:49:02 +0100 Subject: [PATCH 02/13] Sidebar: Basic implementation and styling --- assets/css/v2/style.css | 330 +++--------------- assets/js/sidebar-v2.js | 25 +- .../content/test-product/feather/_index.md | 2 + layouts/partials/sidebar-list.html | 61 ++++ layouts/partials/sidebar-v2.html | 74 +--- 5 files changed, 135 insertions(+), 357 deletions(-) create mode 100644 layouts/partials/sidebar-list.html diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index ef68fb6..0c46d09 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -85,11 +85,11 @@ --code-copy-icon-height: 1rem; --code-copy-icon-width: 1rem; --breadcrumb-max-height: 54px; - --sidebar-margin: 24px; + --sidebar-margin: 1.5rem; --sidebar-line-box-side-length: 8px; --sidebar-line-box-top: 6px; --sidebar-line-box-left: 12px; - --sidebar-width: 24rem; + --sidebar-width: 22rem; --sidebar-line-width: 11.5px; --side-gutter-width: 20rem; --table-top-bottom-spacing: 1rem; @@ -453,8 +453,10 @@ nav { .sidebar-layout { display: flex; flex-direction: column; - position: relative; z-index: 2; + border-right: 1px solid var(--color-divider); + min-height: 100vh; + overflow-y: auto; } #searchbox { @@ -710,36 +712,8 @@ body:not(:has(.main-layout)) header atomic-search-interface { } } -/* MARK: Sidebar +/* MARK: Product Selector */ -.sidebar { - display: flex; - flex-direction: column; - width: 24rem; - max-height: 100vh; - position: sticky; - top: 0; - margin-top: -1rem; - padding-top: 1rem; -} - -.sidebar .product-selector-button { - display: flex; - align-items: center; - justify-content: space-between; - background-color: oklch(var(--color-brand)); - color: var(--color-brand-100); - border: none; - font-size: 1.25rem; - width: 100%; - padding: 0.5rem 0.5rem 0.5rem 1rem; /* 1rem to vertically align with searchbar text */ - cursor: pointer; -} - -.sidebar .product-selector-button .selector-icon { - height: 24px; - width: 24px; -} .product-selector { display: none; @@ -782,275 +756,79 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { font-size: 1rem; } -/* Sidebar scroller */ -.sidebar .scrollbar-container { - width: 100%; - max-height: 100vh; - overflow: scroll; - scrollbar-gutter: stable; - scrollbar-width: none; -} - -.sidebar .scrollbar-container:hover { - overflow: auto; -} +/* MARK: Sidebar +*/ -.sidebar .sidebar-navigation { - margin-left: var(--sidebar-margin); +/* Reset/Renormalize lists to remove default browser styling */ +.sidebar__container, +.sidebar__container button, +.sidebar__container ul, +.sidebar__container li { + margin: 0; + padding: 0; + list-style: none; + font-weight: 400; + font-size: 1rem; } -/* removes the built in ul padding/margin */ -.sidebar .sidebar-navigation ul { - margin-left: 0; - padding-left: 0; - list-style-type: none; +.sidebar__container button { + padding: 0.25rem 0.75rem; } -.sidebar ul :not(.sidebar-navigation) ul { - padding-left: 16px; +.sidebar__content { + padding: 0.5rem 0 0.4rem 0; } -.sidebar .sidebar-navigation li { - margin-bottom: 16px; +.sidebar__ul { + padding-left: 0; } -.sidebar .sidebar-navigation a { - text-decoration: none; - color: black; +.sidebar__children { + padding-left: 1rem; } -.sidebar .sidebar-navigation .collapsible-header { +.sidebar__toggle { cursor: pointer; -} - -.sidebar .sidebar-navigation .collapsible-content { - display: none; - position: relative; -} - -.sidebar .sidebar-navigation .parent-box.opened, -.sidebar .sidebar-navigation .box.opened { - display: none; -} - -.toggle-checkbox:checked ~ .collapsible-header .parent-box.expand, -.toggle-checkbox:checked ~ .collapsible-header .box.expand { - display: none; -} - -.toggle-checkbox:checked ~ .collapsible-content { - display: block; -} - -.toggle-checkbox:checked ~ .collapsible-header .parent-box.opened { - display: inline-block; -} - -.toggle-checkbox:checked ~ .collapsible-header .box.opened { - display: block; -} - -/* Every other Sidebar Partial Vertical Line */ -.toggle-checkbox:checked ~ .collapsible-content::before { - content: ""; - position: absolute; - border-left: black 1px solid; - left: -8.5px; - top: -22.5px; - height: calc(100% + 13.5px); -} - -/* Every other Sidebar Partial Horizontal Lines */ -.toggle-checkbox:checked ~ .collapsible-content li { - position: relative; -} - -.collapsible-content .box::after { - content: ""; - position: absolute; - border-top: black 1px solid; - left: -11.5px; - width: var(--sidebar-line-width); - top: 50%; -} - -.collapsible-content .opened::after { - content: ""; - position: absolute; - border-top: black 1px solid; - left: -12.5px; - width: var(--sidebar-line-width); - top: 50%; -} - -.collapsible-content .box-link::after { - content: ""; - position: absolute; - border-top: black 1px solid; - left: -11.5px; - width: var(--sidebar-line-width); - top: 50%; -} - -.selected { - font-weight: 800; -} - -.sidebar .sidebar-navigation li:first-child { - margin-top: 16px; -} - -.sidebar .sidebar-navigation ul li .parent-box-link { - content: ""; - background-color: black; - position: absolute; - width: 1px; - height: var(--sidebar-line-box-side-length); - margin-top: var(--sidebar-line-box-top); - left: calc(0px - var(--sidebar-line-box-left)); -} - -.sidebar .sidebar-navigation ul li .box-link { - content: ""; - background-color: black; - position: absolute; - width: 1px; - height: var(--sidebar-line-box-side-length); - margin-top: var(--sidebar-line-box-top); - left: var(--sidebar-line-box-left); -} - -.sidebar .sidebar-navigation ul li .parent-box { - content: ""; - display: inline-block; - width: var(--sidebar-line-box-side-length); - height: var(--sidebar-line-box-side-length); - vertical-align: middle; - margin-left: -12px; - margin-top: -4px; -} - -.sidebar .sidebar-navigation ul li .box { - content: ""; - position: absolute; - width: var(--sidebar-line-box-side-length); - height: var(--sidebar-line-box-side-length); - margin-top: var(--sidebar-line-box-top); - left: var(--sidebar-line-box-left); -} - -.sidebar .sidebar-navigation ul li .expand { - background-color: black; -} - -.sidebar .sidebar-navigation ul li .opened { - border: black 1px solid; -} - -.sidebar .sidebar-navigation ul li .current { - background-color: oklch(var(--color-brand)); -} - -.sidebar .sidebar-navigation ul li .partial-box { - margin-left: -24px; -} - -.sidebar .sidebar-navigation ul li .partial { - margin-top: 0; - top: 5px; - left: -13px; -} - -/* First Sidebar Nav Vertical Line */ -.sidebar .sidebar-navigation .parent-collapsible-content { - position: relative; -} - -.sidebar .sidebar-navigation .parent-collapsible-content:first-child::before { - content: ""; - position: absolute; - border-left: black 1px solid; - left: -24px; - top: 10px; - height: calc(100% - 9px - 10px); -} - -.sidebar - .sidebar-navigation - .parent-collapsible-content - li:not(:only-child) - a - + :not(:has(#TableOfContents)) - li::before { + background: none; border: none; + width: 100%; + text-align: left; + padding: 0.25rem 0.75rem; + border-radius: 5px; } -/* First Sidebar Nav Horizontal Lines */ -.sidebar - .sidebar-navigation - .parent-collapsible-content - li:not(:only-child) - .parent-box::before { - content: ""; +.sidebar__link { display: block; - border-top: black 1px solid; - margin-left: -12px; - margin-top: 50%; - width: var(--sidebar-line-width); + padding: 0.25rem 0.75rem; + margin: 2px 0.5rem 2px 0; + border-radius: 5px; + color: oklch(0 0 0 / 0.75); + text-decoration: none; } -.parent-collapsible-content .parent-box-link::after { - content: ""; - position: absolute; - border-top: black 1px solid; - left: -11.5px; - width: var(--sidebar-line-width); - top: 50%; +.sidebar__link--current { + color: oklch(var(--color-brand) / 1); + background-color: oklch(var(--color-brand) / 0.1); + font-weight: 600; } -.row { - display: flex; - flex-wrap: nowrap; - align-items: flex-start; -} +.sidebar__toc { + #TableOfContents { + padding: 0.25rem 0.75rem; + margin: 2px 0.5rem 2px 0; + border-radius: 5px; + color: oklch(0 0 0 / 0.75); -/* Details/Summary */ -details summary { - color: oklch(var(--color-brand)); - transition: text-decoration-color 0.15s ease-in-out; - text-decoration: underline; - text-decoration-color: oklch(var(--color-brand) / 0.3); + &:empty { + display: none; + } - & ~ * { - margin-top: 1rem; + li { + padding: 0.25rem 0.75rem; + } } } -details summary:hover { - text-decoration-color: oklch(var(--color-brand) / 0.8); -} - -details:hover { - cursor: pointer; -} - -/* Table of Contents */ -#TableOfContents { - /* Close all TOC on sidebar */ - display: none; -} - -.current ~ nav, -.collapsible-content li ul li:has(.current) > nav { - /* Open TOC for current page */ - display: block !important; -} - -#TableOfContents li:not(:empty) { - position: relative; - list-style: square; -} - /* MARK: Content */ main { diff --git a/assets/js/sidebar-v2.js b/assets/js/sidebar-v2.js index ff7cf59..3ee136a 100644 --- a/assets/js/sidebar-v2.js +++ b/assets/js/sidebar-v2.js @@ -1,17 +1,14 @@ document.addEventListener('DOMContentLoaded', () => { - function expandToCurrentPage() { - const currentPage = document.getElementById('current-page'); - if (currentPage) { - let parentLabel = currentPage.closest('li'); - while (parentLabel) { - const checkbox = parentLabel.querySelector('.toggle-checkbox'); - if (checkbox) { - checkbox.checked = true; - } - parentLabel = parentLabel.closest('ul').closest('li'); - } - } - } + const toggles = document.querySelectorAll('.sidebar__toggle'); - expandToCurrentPage(); + toggles.forEach((toggle) => { + const parent = toggle.closest('li.sidebar__section'); + const children = parent.querySelector('.sidebar__children'); + + toggle.addEventListener('click', () => { + const isExpanded = toggle.getAttribute('aria-expanded') === 'true'; + toggle.setAttribute('aria-expanded', !isExpanded); + children.hidden = isExpanded; + }); + }); }); diff --git a/exampleSite/content/test-product/feather/_index.md b/exampleSite/content/test-product/feather/_index.md index ae1afcf..b0e0c9f 100644 --- a/exampleSite/content/test-product/feather/_index.md +++ b/exampleSite/content/test-product/feather/_index.md @@ -4,3 +4,5 @@ title: Feather weight: 300 toc: true --- + +Hello! diff --git a/layouts/partials/sidebar-list.html b/layouts/partials/sidebar-list.html new file mode 100644 index 0000000..8a0f3c6 --- /dev/null +++ b/layouts/partials/sidebar-list.html @@ -0,0 +1,61 @@ +{{ $currentUrl := .currentUrl }} +{{ $firstSection := .firstSection }} +{{ $currentPage := .currentPage }} + +{{ with $firstSection }} +
    + {{ range .Pages.ByWeight }} + {{- $onPage := eq $currentUrl .Permalink -}} + {{- $isAncestor := .IsAncestor $currentPage -}} + {{- $shouldExpand := or $onPage $isAncestor -}} + {{- $sectionID := printf "section-%s" (urlize .Permalink) -}} + + {{ if eq .Kind "section" }} +
  • + + +
    + {{ partial "sidebar-list.html" (dict + "firstSection" . "currentUrl" $currentUrl "currentPage" $currentPage) + }} +
    +
  • + + {{ else if eq .Kind "page" }} +
  • + + {{ .Title }} + + {{ if $onPage }} + {{ with .TableOfContents }} +
    {{ . }}
    + {{ end }} + {{ end }} +
  • + {{ end }} + {{ end }} +
+{{ end }} + + +{{/* {{ if gt (.WordCount) 0 }} +
    +
  • + {{ .Title }} - Overview +
  • +
+{{ end }} */}} \ No newline at end of file diff --git a/layouts/partials/sidebar-v2.html b/layouts/partials/sidebar-v2.html index a1de739..b349d1f 100644 --- a/layouts/partials/sidebar-v2.html +++ b/layouts/partials/sidebar-v2.html @@ -21,72 +21,12 @@ {{ $productIdentifier := index ((split $relPermalink "/")) 1 }} {{ $productName := index $productMap $productIdentifier }} - - - - - -
- {{ $groupedProducts := dict - "nginx-one" (where $nginxProducts "type" "nginx-one") - "nginx-app-protect" (where $nginxProducts "type" "nginx-app-protect") - "nginx-as-a-service" (where $nginxProducts "type" "nginx-as-a-service") - "nginx-other" (where $nginxProducts "type" "nginx-other") - }} - {{ $orderedKeys := slice "nginx-one" "nginx-app-protect" "nginx-as-a-service" "nginx-other" }} - {{ range $orderedKeys }} - {{ $type := . }} - {{ $products := index $groupedProducts $type }} -
-

{{ $type | humanize | title | upper }}

-
    - {{ range $products }} -
  • - {{ .title }} -
  • - {{ end }} -
-
- {{ end }} -
-
-
-
    - {{ range .FirstSection.Pages.ByWeight }} -
  • - {{ if eq .Kind "section" }} - - - {{ partial "sidebar-list-pages.html" (dict "context" . "currentUrl" $.Permalink) }} - {{ else if eq .Kind "page" }} - {{ if eq $.Permalink .Permalink }} - - {{ else }} - - {{ end }} - {{ .Title }} - {{ if eq $.Permalink .Permalink }} - {{- with .TableOfContents -}} - {{- . -}} - {{- end -}} - {{ end }} - {{ end }} -
  • - {{ end }} -
+
+
+ {{ partial "sidebar-list.html" (dict + "firstSection" .FirstSection + "currentUrl" .Permalink + "currentPage" . + ) }}
\ No newline at end of file From 969d12fa48f8fc597c3590b3bc85c9d1c2528779 Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Fri, 2 May 2025 11:17:23 +0100 Subject: [PATCH 03/13] Sidebar: Add chevron --- assets/css/v2/style.css | 26 ++++++++++++++++-- assets/js/sidebar-v2.js | 29 +++++++++++++-------- layouts/partials/sidebar-list.html | 42 +++++++++++++++--------------- 3 files changed, 63 insertions(+), 34 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 0c46d09..57165df 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -768,7 +768,7 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { padding: 0; list-style: none; font-weight: 400; - font-size: 1rem; + font-size: 0.875rem; } .sidebar__container button { @@ -788,15 +788,36 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { } .sidebar__toggle { + display: flex; + align-items: center; + gap: 0.25rem; cursor: pointer; background: none; border: none; width: 100%; text-align: left; - padding: 0.25rem 0.75rem; + padding: 0.25rem 0.5rem; border-radius: 5px; } +.sidebar__chevron { + display: flex; + align-items: center; +} + +.sidebar__chevron svg { + margin-right: -0.325rem; + stroke-width: 1.5; +} + +.sidebar__chevron--open { + transform: rotate(90deg); +} + +.sidebar__toggle:has(.sidebar__chevron) { + padding-left: .4rem; +} + .sidebar__link { display: block; padding: 0.25rem 0.75rem; @@ -810,6 +831,7 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { color: oklch(var(--color-brand) / 1); background-color: oklch(var(--color-brand) / 0.1); font-weight: 600; + width: fit-content; } .sidebar__toc { diff --git a/assets/js/sidebar-v2.js b/assets/js/sidebar-v2.js index 3ee136a..4277329 100644 --- a/assets/js/sidebar-v2.js +++ b/assets/js/sidebar-v2.js @@ -1,14 +1,21 @@ -document.addEventListener('DOMContentLoaded', () => { - const toggles = document.querySelectorAll('.sidebar__toggle'); +document.addEventListener('click', (e) => { + const toggle = e.target.closest('.sidebar__toggle'); + if (toggle) { + const chevron = toggle.querySelector('.sidebar__chevron'); + const expanded = toggle.getAttribute('aria-expanded') === 'true'; + const panel = document.getElementById(toggle.getAttribute('aria-controls')); - toggles.forEach((toggle) => { - const parent = toggle.closest('li.sidebar__section'); - const children = parent.querySelector('.sidebar__children'); + // Toggle the expanded state + toggle.setAttribute('aria-expanded', String(!expanded)); - toggle.addEventListener('click', () => { - const isExpanded = toggle.getAttribute('aria-expanded') === 'true'; - toggle.setAttribute('aria-expanded', !isExpanded); - children.hidden = isExpanded; - }); - }); + // Toggle visibility of the content + if (panel) { + panel.hidden = expanded; + } + + // Toggle chevron direction class + if (chevron) { + chevron.classList.toggle('sidebar__chevron--open', !expanded); + } + } }); diff --git a/layouts/partials/sidebar-list.html b/layouts/partials/sidebar-list.html index 8a0f3c6..6d24ba0 100644 --- a/layouts/partials/sidebar-list.html +++ b/layouts/partials/sidebar-list.html @@ -9,28 +9,27 @@ {{- $isAncestor := .IsAncestor $currentPage -}} {{- $shouldExpand := or $onPage $isAncestor -}} {{- $sectionID := printf "section-%s" (urlize .Permalink) -}} - {{ if eq .Kind "section" }} -
  • - - -
    - {{ partial "sidebar-list.html" (dict - "firstSection" . "currentUrl" $currentUrl "currentPage" $currentPage) - }} -
    -
  • - +
  • + +
    + {{ partial "sidebar-list.html" (dict + "firstSection" . "currentUrl" $currentUrl "currentPage" $currentPage) }} +
    +
  • {{ else if eq .Kind "page" }}
  • + {{ end }} {{ end }} From e1c39d4a9a8d2576c77254bfcb2b5b7aafad6d04 Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Fri, 2 May 2025 11:49:11 +0100 Subject: [PATCH 04/13] Sidebar: Make sticky, Add scrollbar --- assets/css/v2/style.css | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 57165df..377f38d 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -456,7 +456,6 @@ nav { z-index: 2; border-right: 1px solid var(--color-divider); min-height: 100vh; - overflow-y: auto; } #searchbox { @@ -759,6 +758,19 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { /* MARK: Sidebar */ +.sidebar { + display: flex; + flex-direction: column; + width: 22rem; + max-height: 100vh; + position: sticky; + top: 0; + margin-top: 0rem; + padding-top: 1rem; + align-items: start; + overflow-y: auto; +} + /* Reset/Renormalize lists to remove default browser styling */ .sidebar__container, .sidebar__container button, From 571df42b6ac8628740da475f3ec84f7e8939c804 Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Fri, 2 May 2025 15:37:07 +0100 Subject: [PATCH 05/13] Sidebar: Toc styling border --- assets/css/v2/style.css | 48 +++++++++++++++++++++++++++--- layouts/partials/sidebar-list.html | 45 +++++++++++++++------------- 2 files changed, 68 insertions(+), 25 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 377f38d..7379aed 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -453,11 +453,22 @@ nav { .sidebar-layout { display: flex; flex-direction: column; + position: relative; /* required for absolute-positioned pseudo element */ z-index: 2; - border-right: 1px solid var(--color-divider); min-height: 100vh; } +/* this is the complete, corrected CSS you can directly copy/paste clearly: */ +.sidebar-layout::before { + content: ""; + position: absolute; + top: 0; + bottom: 0; + right: 0; + width: 1px; + background-color: var(--color-divider); +} + #searchbox { width: 24rem; display: none; @@ -810,6 +821,16 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { text-align: left; padding: 0.25rem 0.5rem; border-radius: 5px; + font-weight: 500; + + &:hover { + background-color: oklch(var(--color-brand) / 0.06); + color: oklch(var(--color-brand) / 1); + } +} + +.sidebar__container button.sidebar__toggle--ancestor { + font-weight: 600; } .sidebar__chevron { @@ -837,6 +858,12 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { border-radius: 5px; color: oklch(0 0 0 / 0.75); text-decoration: none; + transition: background-color 0.2s ease, color 0.2s ease; + + &:hover { + background-color: oklch(var(--color-brand) / 0.08); + color: oklch(var(--color-brand)); + } } .sidebar__link--current { @@ -848,11 +875,16 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { .sidebar__toc { #TableOfContents { - padding: 0.25rem 0.75rem; - margin: 2px 0.5rem 2px 0; - border-radius: 5px; + padding: 0 0.75rem 0 0; + margin: 0.5rem 0.25rem 0.5rem 0.8rem; + border-left: 1px solid var(--color-divider); color: oklch(0 0 0 / 0.75); + a { + color: oklch(0 0 0 / 0.75); + text-decoration: none; + } + &:empty { display: none; } @@ -860,6 +892,14 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { li { padding: 0.25rem 0.75rem; } + + li:first-child { + padding-top: 0; + } + + li:last-child { + padding-bottom: 0; + } } } diff --git a/layouts/partials/sidebar-list.html b/layouts/partials/sidebar-list.html index 6d24ba0..6d1a983 100644 --- a/layouts/partials/sidebar-list.html +++ b/layouts/partials/sidebar-list.html @@ -9,27 +9,30 @@ {{- $isAncestor := .IsAncestor $currentPage -}} {{- $shouldExpand := or $onPage $isAncestor -}} {{- $sectionID := printf "section-%s" (urlize .Permalink) -}} + {{ if eq .Kind "section" }} -
  • - -
    - {{ partial "sidebar-list.html" (dict - "firstSection" . "currentUrl" $currentUrl "currentPage" $currentPage) }} -
    -
  • +
  • + +
    + {{ partial "sidebar-list.html" (dict + "firstSection" . "currentUrl" $currentUrl "currentPage" $currentPage) + }} +
    +
  • + {{ else if eq .Kind "page" }}
  • {{ .Title }} + {{ if $onPage }} {{ with .TableOfContents }}
    {{ . }}
    {{ end }} {{ end }}
  • - {{ end }} {{ end }} From 55813dd455fbfd85ed6957e3b623e96d480869b4 Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Fri, 2 May 2025 17:51:36 +0100 Subject: [PATCH 06/13] Sidebar: Stretch slection background colour --- assets/css/v2/style.css | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 7379aed..4b10b63 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -794,6 +794,10 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { font-size: 0.875rem; } +.sidebar__container { + width: var(--sidebar-width); +} + .sidebar__container button { padding: 0.25rem 0.75rem; } @@ -820,7 +824,7 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { width: 100%; text-align: left; padding: 0.25rem 0.5rem; - border-radius: 5px; + border-radius: 5px 0 5px 0; font-weight: 500; &:hover { @@ -849,13 +853,14 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { .sidebar__toggle:has(.sidebar__chevron) { padding-left: .4rem; + margin-left: -1rem; } .sidebar__link { display: block; padding: 0.25rem 0.75rem; - margin: 2px 0.5rem 2px 0; - border-radius: 5px; + margin: 2px 0 2px 0; + border-radius: 5px 0 5px 0; color: oklch(0 0 0 / 0.75); text-decoration: none; transition: background-color 0.2s ease, color 0.2s ease; @@ -870,7 +875,9 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { color: oklch(var(--color-brand) / 1); background-color: oklch(var(--color-brand) / 0.1); font-weight: 600; - width: fit-content; + display: block; /* Make it stretch horizontally clearly */ + width: auto; /* reset width clearly */ + box-sizing: border-box; } .sidebar__toc { From 2590dc334cd293745d007fcc3ee75e24bb58895b Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Tue, 6 May 2025 11:44:28 +0100 Subject: [PATCH 07/13] Sidebar: Chevron styling Fix chevron sizing Move chevron to right of links Fix nested li top padding Steal 1rem from left main --- assets/css/v2/style.css | 232 +++++++++++++++-------------- layouts/partials/lucide.html | 3 +- layouts/partials/sidebar-list.html | 2 +- 3 files changed, 126 insertions(+), 111 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 4b10b63..a15f1aa 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -281,6 +281,12 @@ header { } } +main { + flex: 1; + min-width: 20rem; + margin: 0 2rem 2rem 1rem; +} + /* MARK: Footer */ footer { @@ -523,6 +529,10 @@ nav { .sidebar-layout { display: none; } + + main { + margin: 0 2rem 2rem 2rem; + } } @media (min-width: 88em) { @@ -770,6 +780,8 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { */ .sidebar { + --color-foreground: oklch(0 0 0 / 0.75); + display: flex; flex-direction: column; width: 22rem; @@ -780,143 +792,145 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { padding-top: 1rem; align-items: start; overflow-y: auto; -} + color: var(--color-foreground); -/* Reset/Renormalize lists to remove default browser styling */ -.sidebar__container, -.sidebar__container button, -.sidebar__container ul, -.sidebar__container li { - margin: 0; - padding: 0; - list-style: none; - font-weight: 400; - font-size: 0.875rem; -} + /* Reset/Renormalize lists to remove default browser styling */ + .sidebar__container, + .sidebar__container button, + .sidebar__container ul, + .sidebar__container li { + margin: 0; + padding: 0; + list-style: none; + font-weight: 400; + font-size: 0.875rem; + } -.sidebar__container { - width: var(--sidebar-width); -} + .sidebar__container { + width: var(--sidebar-width); + } -.sidebar__container button { - padding: 0.25rem 0.75rem; -} + .sidebar__container button { + padding: 0.25rem 0.75rem; + justify-content: space-between; + } -.sidebar__content { - padding: 0.5rem 0 0.4rem 0; -} + .sidebar__content { + padding: 0.5rem 0 0.4rem 0; + } -.sidebar__ul { - padding-left: 0; -} + .sidebar__ul { + padding-left: 0; + } -.sidebar__children { - padding-left: 1rem; -} + .sidebar__children { + padding-left: 1rem; + } -.sidebar__toggle { - display: flex; - align-items: center; - gap: 0.25rem; - cursor: pointer; - background: none; - border: none; - width: 100%; - text-align: left; - padding: 0.25rem 0.5rem; - border-radius: 5px 0 5px 0; - font-weight: 500; + .sidebar__toggle { + display: flex; + align-items: center; + gap: 0.25rem; + cursor: pointer; + background: none; + border: none; + width: 100%; + text-align: left; + padding: 0.25rem 0.5rem; + border-radius: 5px 0 5px 0; + font-weight: 500; + color: var(--color-foreground); - &:hover { - background-color: oklch(var(--color-brand) / 0.06); - color: oklch(var(--color-brand) / 1); + &:hover { + background-color: oklch(var(--color-brand) / 0.06); + color: oklch(var(--color-brand) / 1); + } } -} -.sidebar__container button.sidebar__toggle--ancestor { - font-weight: 600; -} + .sidebar__container button.sidebar__toggle--ancestor { + font-weight: 600; + } -.sidebar__chevron { - display: flex; - align-items: center; -} + .sidebar__chevron { + display: flex; + align-items: flex-end; + } -.sidebar__chevron svg { - margin-right: -0.325rem; - stroke-width: 1.5; -} + .sidebar__chevron svg { + stroke-width: 1.5; + width: 1rem; + height: 1rem; + } -.sidebar__chevron--open { - transform: rotate(90deg); -} + .sidebar__chevron--open { + transform: rotate(90deg); + } -.sidebar__toggle:has(.sidebar__chevron) { - padding-left: .4rem; - margin-left: -1rem; -} + .sidebar__toggle:not(:has(.sidebar__chevron)) { + padding-left: 2rem; + } -.sidebar__link { - display: block; - padding: 0.25rem 0.75rem; - margin: 2px 0 2px 0; - border-radius: 5px 0 5px 0; - color: oklch(0 0 0 / 0.75); - text-decoration: none; - transition: background-color 0.2s ease, color 0.2s ease; + .sidebar__link { + display: block; + padding: 0.25rem 0.75rem; + margin: 2px 0 2px 0; + border-radius: 5px 0 5px 0; + color: oklch(0 0 0 / 0.75); + text-decoration: none; + transition: background-color 0.2s ease, color 0.2s ease; - &:hover { - background-color: oklch(var(--color-brand) / 0.08); - color: oklch(var(--color-brand)); + &:hover { + background-color: oklch(var(--color-brand) / 0.08); + color: oklch(var(--color-brand)); + } } -} -.sidebar__link--current { - color: oklch(var(--color-brand) / 1); - background-color: oklch(var(--color-brand) / 0.1); - font-weight: 600; - display: block; /* Make it stretch horizontally clearly */ - width: auto; /* reset width clearly */ - box-sizing: border-box; -} - -.sidebar__toc { - #TableOfContents { - padding: 0 0.75rem 0 0; - margin: 0.5rem 0.25rem 0.5rem 0.8rem; - border-left: 1px solid var(--color-divider); - color: oklch(0 0 0 / 0.75); + .sidebar__link--current { + color: oklch(var(--color-brand) / 1); + background-color: oklch(var(--color-brand) / 0.1); + font-weight: 600; + display: block; /* Make it stretch horizontally clearly */ + width: auto; /* reset width clearly */ + box-sizing: border-box; + } - a { + .sidebar__toc { + #TableOfContents { + padding: 0 0.75rem 0 0; + margin: 0.5rem 0.25rem 0.5rem 0.8rem; + border-left: 1px solid var(--color-divider); color: oklch(0 0 0 / 0.75); - text-decoration: none; - } - &:empty { - display: none; - } + a { + color: oklch(0 0 0 / 0.75); + text-decoration: none; + } - li { - padding: 0.25rem 0.75rem; - } + &:empty { + display: none; + } - li:first-child { - padding-top: 0; - } + li { + padding: 0.25rem 0.75rem; + } + + li:first-child { + padding-top: 0; + } + + ul ul li:first-child { + padding-top: 0.75rem; + } - li:last-child { - padding-bottom: 0; + li:last-child { + padding-bottom: 0; + } } } } /* MARK: Content */ -main { - flex: 1; - min-width: 20rem; - margin: 0 2rem 2rem 2rem; -} p { margin: 0; @@ -1575,8 +1589,8 @@ hr { } .lucide { - width: 1.5rem; - height: 1.5rem; + width: 3rem; + height: 3rem; stroke: currentColor; fill: none; stroke-width: 2; diff --git a/layouts/partials/lucide.html b/layouts/partials/lucide.html index d1e0fb2..8fe0176 100644 --- a/layouts/partials/lucide.html +++ b/layouts/partials/lucide.html @@ -1,5 +1,6 @@ {{- /* Usage: */ -}} {{- /* (dict "context" . "icon" "circle") */ -}} - + \ No newline at end of file diff --git a/layouts/partials/sidebar-list.html b/layouts/partials/sidebar-list.html index 6d1a983..e6fac04 100644 --- a/layouts/partials/sidebar-list.html +++ b/layouts/partials/sidebar-list.html @@ -17,10 +17,10 @@ aria-expanded="{{ $shouldExpand }}" aria-controls="{{ $sectionID }}" > + {{ .Title }} {{ partial "lucide" (dict "context" . "icon" "chevron-right") }} - {{ .Title }}
    Date: Tue, 6 May 2025 14:14:06 +0100 Subject: [PATCH 08/13] Sidebar: Show and hide toc --- assets/css/v2/style.css | 12 +++++++--- assets/js/sidebar-v2.js | 3 --- layouts/partials/sidebar-list.html | 38 ++++++++++++++++++++---------- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index a15f1aa..32b512a 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -885,12 +885,14 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { } } - .sidebar__link--current { + .sidebar__link--current, + .sidebar__toggle.sidebar__link--current { color: oklch(var(--color-brand) / 1); background-color: oklch(var(--color-brand) / 0.1); font-weight: 600; - display: block; /* Make it stretch horizontally clearly */ - width: auto; /* reset width clearly */ + display: flex; + justify-self: stretch; + width: auto; box-sizing: border-box; } @@ -901,6 +903,10 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { border-left: 1px solid var(--color-divider); color: oklch(0 0 0 / 0.75); + &[hidden] { + display: none; + } + a { color: oklch(0 0 0 / 0.75); text-decoration: none; diff --git a/assets/js/sidebar-v2.js b/assets/js/sidebar-v2.js index 4277329..a55e256 100644 --- a/assets/js/sidebar-v2.js +++ b/assets/js/sidebar-v2.js @@ -5,15 +5,12 @@ document.addEventListener('click', (e) => { const expanded = toggle.getAttribute('aria-expanded') === 'true'; const panel = document.getElementById(toggle.getAttribute('aria-controls')); - // Toggle the expanded state toggle.setAttribute('aria-expanded', String(!expanded)); - // Toggle visibility of the content if (panel) { panel.hidden = expanded; } - // Toggle chevron direction class if (chevron) { chevron.classList.toggle('sidebar__chevron--open', !expanded); } diff --git a/layouts/partials/sidebar-list.html b/layouts/partials/sidebar-list.html index e6fac04..37f03fc 100644 --- a/layouts/partials/sidebar-list.html +++ b/layouts/partials/sidebar-list.html @@ -33,20 +33,32 @@
    - {{ else if eq .Kind "page" }} + {{ else if eq .Kind "page" }}
  • - - {{ .Title }} - - - {{ if $onPage }} - {{ with .TableOfContents }} -
    {{ . }}
    - {{ end }} + {{- $pageHasTOC := (and $onPage .TableOfContents) -}} + {{- $tocID := printf "toc-%s" (urlize .Permalink) -}} + {{- if $pageHasTOC }} + +
    + {{ .TableOfContents }} +
    + {{ else }} + + {{ .Title }} + {{ end }}
  • {{ end }} From ec81207eed3764cffcd9624b5e0f6f6d1c43d8e1 Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Wed, 7 May 2025 11:20:03 +0100 Subject: [PATCH 09/13] Sidebar: Add a11y to skip entire sidebar or toc --- assets/css/v2/style.css | 31 +++++++++++++++-- layouts/_default/docs.html | 2 +- layouts/_default/list.html | 2 +- layouts/partials/sidebar-list.html | 56 ++++++++++++++++++++---------- layouts/partials/sidebar-v2.html | 2 ++ 5 files changed, 70 insertions(+), 23 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 32b512a..13282be 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -817,6 +817,7 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { .sidebar__content { padding: 0.5rem 0 0.4rem 0; + margin-right: 0.25rem; } .sidebar__ul { @@ -837,7 +838,7 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { width: 100%; text-align: left; padding: 0.25rem 0.5rem; - border-radius: 5px 0 5px 0; + border-radius: 5px 0 0 5px; font-weight: 500; color: var(--color-foreground); @@ -874,7 +875,7 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { display: block; padding: 0.25rem 0.75rem; margin: 2px 0 2px 0; - border-radius: 5px 0 5px 0; + border-radius: 5px 0 0 5px; color: oklch(0 0 0 / 0.75); text-decoration: none; transition: background-color 0.2s ease, color 0.2s ease; @@ -908,7 +909,6 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { } a { - color: oklch(0 0 0 / 0.75); text-decoration: none; } @@ -1606,6 +1606,31 @@ hr { margin: 0; } +/* MARK: Accessibility +*/ + +.skip-link { + position: fixed; + top: 0; + left: 0; + background-color: var(--color-background); + color: var(--color-foreground); + padding: 1rem 1rem; + font-size: 1rem; + border: 2px solid var(--color-foreground); + z-index: 1000; + text-decoration: none; + border-radius: 0; + box-shadow: 3px 3px 0px var(--color-shadow); + opacity: 0; + pointer-events: none; +} + +.skip-link:focus { + opacity: 1; + pointer-events: auto; +} + /* FILTHY HACKS BEGIN */ /* Override logo with black text version */ diff --git a/layouts/_default/docs.html b/layouts/_default/docs.html index 373e7b0..43b4d6e 100644 --- a/layouts/_default/docs.html +++ b/layouts/_default/docs.html @@ -74,7 +74,7 @@
    -
    +
    {{ if not .IsHome }} diff --git a/layouts/_default/list.html b/layouts/_default/list.html index d68dde4..8d9fd72 100644 --- a/layouts/_default/list.html +++ b/layouts/_default/list.html @@ -18,7 +18,7 @@
    -
    +
    {{ if not .IsHome }} diff --git a/layouts/partials/sidebar-list.html b/layouts/partials/sidebar-list.html index 37f03fc..5707779 100644 --- a/layouts/partials/sidebar-list.html +++ b/layouts/partials/sidebar-list.html @@ -1,23 +1,31 @@ {{ $currentUrl := .currentUrl }} -{{ $firstSection := .firstSection }} {{ $currentPage := .currentPage }} +{{ $firstSection := .firstSection }} +{{ $idPrefix := .idPrefix }} {{ with $firstSection }}
      - {{ range .Pages.ByWeight }} - {{- $onPage := eq $currentUrl .Permalink -}} - {{- $isAncestor := .IsAncestor $currentPage -}} + {{ $pages := .Pages.ByWeight }} + {{ range $index, $p := $pages }} + {{- $onPage := eq $currentUrl $p.Permalink -}} + {{- $isAncestor := $p.IsAncestor $currentPage -}} {{- $shouldExpand := or $onPage $isAncestor -}} - {{- $sectionID := printf "section-%s" (urlize .Permalink) -}} + {{/* These variables are used to create a unique id to be attached to every link + that accessibility users can correctly "Skip Table Of Contents" */}} + {{- $sectionID := printf "%ssection-%s" $idPrefix (urlize $p.Permalink) -}} + {{- $linkID := printf "%slink-%s" $idPrefix (urlize $p.Permalink) -}} + {{- $nextIndex := add $index 1 -}} + {{- $nextLink := index $pages $nextIndex -}} - {{ if eq .Kind "section" }} + {{ if eq $p.Kind "section" }}
    - {{ else if eq .Kind "page" }} + {{ else if eq $p.Kind "page" }} + {{- $tocHasItems := (in $p.TableOfContents "
  • ") -}} + {{- $pageHasTOC := (and $onPage $tocHasItems $p.Params.toc) -}} + {{- $tocID := printf "%stoc-%s" $idPrefix (urlize $p.Permalink) -}}
  • - {{- $pageHasTOC := (and $onPage .TableOfContents) -}} - {{- $tocID := printf "toc-%s" (urlize .Permalink) -}} - {{- if $pageHasTOC }} + {{ if $pageHasTOC }}
    - {{ .TableOfContents }} + {{ if $nextLink }} + {{- $nextLinkID := printf "%slink-%s" $idPrefix (urlize $nextLink.Permalink) -}} + Skip Table of Contents + {{ else }} + Skip Table of Contents + {{ end }} + {{ $p.TableOfContents }}
    {{ else }} - {{ .Title }} + {{ $p.Title }} {{ end }}
  • {{ end }} + {{ end }} {{ end }} - {{/* {{ if gt (.WordCount) 0 }}
    • diff --git a/layouts/partials/sidebar-v2.html b/layouts/partials/sidebar-v2.html index b349d1f..cf628c6 100644 --- a/layouts/partials/sidebar-v2.html +++ b/layouts/partials/sidebar-v2.html @@ -23,10 +23,12 @@
      + Skip Navigation {{ partial "sidebar-list.html" (dict "firstSection" .FirstSection "currentUrl" .Permalink "currentPage" . + "idPrefix" "" ) }}
      \ No newline at end of file From 4b4cca2e5efd15a5e35f37e9128eac77f84d9963 Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Wed, 7 May 2025 16:04:03 +0100 Subject: [PATCH 10/13] Sidebar: Show search in top nav --- assets/css/v2/style.css | 12 ++++++------ assets/js/coveo.js | 16 ---------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 13282be..458d504 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -576,6 +576,11 @@ nav { .content-layout .side-gutter { grid-column-start: 2; } + + .navbar atomic-search-interface { + margin: 0; + display: block; + } } .list-page { @@ -708,11 +713,6 @@ atomic-search-layout atomic-layout-section[section="search"] { z-index: 9999; } -header atomic-search-interface { - /* Hide by default */ - display: none; -} - body:not(:has(.main-layout)) header atomic-search-interface { /* Show on landing pages */ display: block; @@ -789,7 +789,7 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon { position: sticky; top: 0; margin-top: 0rem; - padding-top: 1rem; + padding-top: 1.5rem; align-items: start; overflow-y: auto; color: var(--color-foreground); diff --git a/assets/js/coveo.js b/assets/js/coveo.js index 780e36c..8dc9bf7 100644 --- a/assets/js/coveo.js +++ b/assets/js/coveo.js @@ -53,22 +53,6 @@ async function atomicCoveo() { }, }); await searchPageInterface.executeFirstSearch(); - } else { - if (sidebar) { - await searchBarSidebar.initialize({ - accessToken: token, - organizationId: org_id, - analytics: { analyticsMode: 'legacy' }, - preprocessRequest: (request, clientOrigin, metadata) => { - const body = JSON.parse(request.body); - body.q = `<@- ${body.q} -@>`; - request.body = JSON.stringify(body); - - return request; - }, - }); - await searchBarSidebar.executeFirstSearch(); - } } /* Initialize the header searchbar*/ From d543860f268f979f51ed2388e66dc2331465cf30 Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Thu, 8 May 2025 08:38:30 +0100 Subject: [PATCH 11/13] Sidebar: Revert lucide default sizes --- assets/css/v2/style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 458d504..4731633 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -1595,8 +1595,8 @@ hr { } .lucide { - width: 3rem; - height: 3rem; + width: 1.5rem; + height: 1.5rem; stroke: currentColor; fill: none; stroke-width: 2; From 8c6d3d3880a59798b60b55856b8dd4f6ccb22e11 Mon Sep 17 00:00:00 2001 From: Jack Hickey <133868041+nginx-jack@users.noreply.github.com> Date: Thu, 8 May 2025 17:29:41 +0100 Subject: [PATCH 12/13] Sidebar: Remove extra search from search page --- assets/css/v2/style.css | 7 ------- assets/js/sidebar-v2.js | 16 ++++++++++++++++ layouts/search/single.html | 1 - 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index 4731633..ff2184f 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -725,13 +725,6 @@ body:not(:has(.main-layout)) header atomic-search-interface { } } -@media (max-width: 1023px) { - /* Show on search page with facet if it is hidden */ - body:has(atomic-search-layout) header atomic-search-interface { - display: block; - } -} - /* MARK: Product Selector */ diff --git a/assets/js/sidebar-v2.js b/assets/js/sidebar-v2.js index a55e256..3efb8c5 100644 --- a/assets/js/sidebar-v2.js +++ b/assets/js/sidebar-v2.js @@ -16,3 +16,19 @@ document.addEventListener('click', (e) => { } } }); + +document.addEventListener('DOMContentLoaded', () => { + const sidebar = document.querySelector('.sidebar__ul'); + + if (!sidebar) return; + + const activeLink = sidebar.querySelector('.sidebar__link--current'); + + if (activeLink) { + activeLink.scrollIntoView({ + behavior: 'auto', + block: 'center', + inline: 'nearest', + }); + } +}); diff --git a/layouts/search/single.html b/layouts/search/single.html index 086312d..bbbfc2d 100644 --- a/layouts/search/single.html +++ b/layouts/search/single.html @@ -121,7 +121,6 @@ - From c9c912cd19ec6bbec3f9bd05272f4de791a88cea Mon Sep 17 00:00:00 2001 From: Lam Nguyen Date: Wed, 7 May 2025 13:08:36 -0700 Subject: [PATCH 13/13] Sidebar: Mobile support --- assets/css/v2/style.css | 87 ++++++++++++++++++++++++++++++-- assets/js/sidebar-v2.js | 18 +++++++ layouts/_default/docs.html | 5 +- layouts/_default/list.html | 3 +- layouts/partials/breadcrumb.html | 1 + 5 files changed, 108 insertions(+), 6 deletions(-) diff --git a/assets/css/v2/style.css b/assets/css/v2/style.css index ff2184f..76374c0 100644 --- a/assets/css/v2/style.css +++ b/assets/css/v2/style.css @@ -91,6 +91,7 @@ --sidebar-line-box-left: 12px; --sidebar-width: 22rem; --sidebar-line-width: 11.5px; + --sidebar-mobile-top-displacement: 3rem; --side-gutter-width: 20rem; --table-top-bottom-spacing: 1rem; --table-row-space-between: 1.5rem; @@ -266,6 +267,10 @@ header { padding: 20px 10px; } + .nav-item-explore { + margin: 0; + } + .navbar-button { padding: 0.5rem 0.5rem; border: none; @@ -526,8 +531,74 @@ nav { column-gap: var(--grid-column-gutter); } - .sidebar-layout { - display: none; + body:has(#sidebar-v2[style*="block"]) { + /* Disable scrolling in main content + hide footer if the sidebar is visible */ + overflow-y: hidden; + + .sidebar-layout { + position: absolute; + height: 100%; + } + + footer { + display: none; + } + + .sidebar-layout .sidebar-mobile-toggle { + display: flex !important; + align-items: center; + position: sticky; + top: 1rem; + margin-top: 2rem; + padding: 0.5rem; + color: white; + background-color: oklch(var(--color-brand)); + } + } + + .breadcrumb .sidebar-mobile-toggle { + display: inline !important; + padding: 0; + } + + .sidebar-mobile-toggle { + background-color: transparent; + border: none; + + .lucide { + margin-right: 1rem; + } + } + + .main-layout { + /* Mobile support for sidebar */ + display: flex; + flex-direction: column; + position: relative; + + .sidebar-layout { + min-height: fit-content; + background: white; + z-index: 3; + width: calc(100% + 4rem); + margin-left: -2rem; + + &::before { + display: none; + } + + nav { + width: 100%; + display: none; + padding: 0; + top: var(--sidebar-mobile-top-displacement); + max-height: calc(100vh - var(--sidebar-mobile-top-displacement)); + + .sidebar__container { + width: 100%; + } + } + } } main { @@ -936,6 +1007,16 @@ p { line-height: 1.5rem; } +.breadcrumb-layout { + position: sticky; + top: 0; + z-index: 3; + background-color: white; + width: calc(100% + 4rem); + margin-left: -2rem; + padding: 1rem 2rem; +} + .breadcrumb { color: var(--color-foreground); text-decoration: none; @@ -1163,7 +1244,7 @@ blockquote p:last-child { } /* Maintain the split column for as long as possible */ -@media (min-width: 67rem) { +@media (min-width: 88rem) { blockquote.side-callout { grid-column: 2 !important; align-self: start; diff --git a/assets/js/sidebar-v2.js b/assets/js/sidebar-v2.js index 3efb8c5..16af84a 100644 --- a/assets/js/sidebar-v2.js +++ b/assets/js/sidebar-v2.js @@ -1,5 +1,6 @@ document.addEventListener('click', (e) => { const toggle = e.target.closest('.sidebar__toggle'); + const sidebarMobileToggle = e.target.closest('.sidebar-mobile-toggle'); if (toggle) { const chevron = toggle.querySelector('.sidebar__chevron'); const expanded = toggle.getAttribute('aria-expanded') === 'true'; @@ -14,6 +15,23 @@ document.addEventListener('click', (e) => { if (chevron) { chevron.classList.toggle('sidebar__chevron--open', !expanded); } + } else if (sidebarMobileToggle) { + // Show the sidebar + const sidebar = document.getElementById('sidebar-v2'); + const expanded = + sidebarMobileToggle.getAttribute('aria-expanded') === 'true'; + sidebar.setAttribute( + 'style', + !expanded ? 'display: block;' : 'display: none;' + ); + + // Set the aria for all the toggle buttons so they are in lockstep + const toggleButtons = document.getElementsByClassName( + 'sidebar-mobile-toggle' + ); + for (const button of [...toggleButtons]) { + button.setAttribute('aria-expanded', String(!expanded)); + } } }); diff --git a/layouts/_default/docs.html b/layouts/_default/docs.html index 43b4d6e..da684fd 100644 --- a/layouts/_default/docs.html +++ b/layouts/_default/docs.html @@ -69,14 +69,15 @@
      -
      + +
      {{ partial "sidebar-v2.html" . }}
      -
      +
      {{ if not .IsHome }} {{ if not (in .Params.display_breadcrumb "false" ) }} {{ partial "breadcrumb" .}} diff --git a/layouts/_default/list.html b/layouts/_default/list.html index 8d9fd72..4948ee8 100644 --- a/layouts/_default/list.html +++ b/layouts/_default/list.html @@ -13,6 +13,7 @@
      +
      {{ partial "sidebar-v2.html" . }}
      @@ -20,7 +21,7 @@
      -
      +
      {{ if not .IsHome }} {{ if not (in .Params.display_breadcrumb "false" ) }} {{ partial "breadcrumb" .}} diff --git a/layouts/partials/breadcrumb.html b/layouts/partials/breadcrumb.html index eeba1ad..5b16553 100644 --- a/layouts/partials/breadcrumb.html +++ b/layouts/partials/breadcrumb.html @@ -1,6 +1,7 @@
        +
      1. Home
      2. {{- define "breadcrumb" -}} {{- with .Parent -}}