Merge branch 'master' into fix/instant-loading

This commit is contained in:
squidfunk 2023-09-23 16:48:31 +02:00
commit 15538b0a39
No known key found for this signature in database
GPG Key ID: 5ED40BC4F9C436DF
23 changed files with 540 additions and 285 deletions

View File

@ -36,7 +36,35 @@ permissions:
contents: read
jobs:
npm:
npm-build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js runtime
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
- name: Set up Node.js dependency cache
uses: actions/cache@v3
id: cache
with:
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
path: node_modules
- name: Set up Node.js dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: npm install
- name: Build project
run: |
npm run build
git diff --name-only
npm-check:
runs-on: ubuntu-latest
steps:
@ -62,12 +90,7 @@ jobs:
- name: Check project
run: npm run check
- name: Build project
run: |
npm run build
git diff --name-only
pypi:
python:
runs-on: ubuntu-latest
steps:
@ -78,6 +101,10 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: pip
cache-dependency-path: |
pyproject.toml
requirements.txt
- name: Set up Python dependencies
run: pip install --upgrade build twine

View File

@ -29,6 +29,8 @@ env:
permissions:
contents: write
id-token: write
pages: write
jobs:
documentation:
@ -40,20 +42,25 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
sparse-checkout: |
docs
includes
material/overrides
src/templates/partials/languages
- name: Set up Python runtime
uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Set the date environmental variable
run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
cache: pip
cache-dependency-path: |
pyproject.toml
requirements.txt
- name: Set up build cache
uses: actions/cache@v3
id: cache
uses: actions/cache/restore@v3
with:
key: mkdocs-material-${{ env.cache_id }}
key: mkdocs-material-${{ hashfiles('.cache/**') }}
path: .cache
restore-keys: |
mkdocs-material-
@ -63,15 +70,8 @@ jobs:
- name: Install Python dependencies
run: |
pip install \
"cairosvg>=2.5" \
"mkdocs-git-committers-plugin-2>=1.1.1" \
"mkdocs-git-revision-date-localized-plugin>=1.0" \
"mkdocs-minify-plugin>=0.3" \
"mkdocs-rss-plugin>=1.2" \
"mkdocs-redirects>=1.0" \
"lxml" \
"pillow<10"
pip install mkdocs-material
pip install mkdocs-material[recommended,git,imaging]
- name: Install Insiders build
if: github.event.repository.fork == false
@ -88,10 +88,30 @@ jobs:
rm -rf material
cp -r mkdocs-material-insiders/material material
- name: Deploy documentation
- name: Build documentation
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
GOOGLE_ANALYTICS_KEY: ${{ secrets.GOOGLE_ANALYTICS_KEY }}
run: |
mkdocs gh-deploy --force
mkdocs build --clean
mkdocs --version
- name: Adjust permissions
run: |
chmod -c -R +rX site/ | while read line; do
echo "::warning title=Invalid file permissions automatically fixed::$line"
done
- name: Upload to GitHub Pages
uses: actions/upload-pages-artifact@v2
with:
path: site
- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v2
- name: Save build cache
uses: actions/cache/save@v3
with:
key: mkdocs-material-${{ hashfiles('.cache/**') }}
path: .cache

View File

@ -0,0 +1,100 @@
---
date: 2023-09-22
authors: [squidfunk]
categories:
- Build
- Performance
links:
- publishing-your-site.md#with-github-actions
- creating-your-site.md#building-your-site
---
# Using `git sparse-checkout` for faster documentation builds
__Leveraging `git sparse-checkout` in GitHub Actions enabled us to speed up
documentation builds in our repository, cutting checkout times from 20 to 30
seconds to just 2 seconds.__
Developing an efficient approach to build documentation in CI workflows is
essential, especially when working in large repositories with thousands of
commits, like ours. Of course, we want to build documentation quickly and
efficiently, ensuring fast and productive workflows. When using both the
wonderful [`git-committers`][git-committers] and [`git-revision-date-localized`]
[git-revision-date-localized] plugins to display [document contributors] and
[dates] at the bottom of each page, we are required to set `fetch-depth: 0`,
which resulted in checkout times of 20 to 30 seconds on our repository. By
leveraging [`git sparse-checkout`][git sparse-checkout] within [GitHub Actions],
check out time was brought down to 2 seconds.
[git sparse-checkout]: https://git-scm.com/docs/git-sparse-checkout
[GitHub Actions]: ../../publishing-your-site.md#with-github-actions
[git-revision-date-localized]: https://github.com/timvink/mkdocs-git-revision-date-localized-plugin
[git-committers]: https://github.com/ojacques/mkdocs-git-committers-plugin-2
[document contributors]: ../../setup/adding-a-git-repository.md#document-contributors
[dates]: ../../setup/adding-a-git-repository.md#document-dates
<!-- more -->
## A Primer
[`git sparse-checkout`][git sparse-checkout] allows you to check out only a
subset of the files in a repository, making it incredibly useful for large
repositories where a full checkout takes long and includes many files that are
not relevant when building documentation.
## GitHub Actions
To enable [`git sparse-checkout`][git sparse-checkout] within [GitHub Actions]
and ensure that you are only building the documentation that you need, add the
following lines to your workflow file:
``` yaml
- uses: actions/checkout@v4
with:
fetch-depth: 0
sparse-checkout: |
docs
includes
```
[`git sparse-checkout`][git sparse-checkout] always checks out all files
residing in the repositorys root. This means that regardless of the specified
paths or directories for sparse checkout, the files located in the root of the
repository will always be included in the checkout process.
Thus, you only need to specify the directories that are necessary for building
documentation. In our case, we only need the `docs` and `includes` folders,
but if you need additional directories, you can just add them to the end of the
list. A complete example workflow for [GitHub Actions]:
``` yaml hl_lines="13-18"
name: documentation
on:
push:
branches:
- master
- main
permissions:
contents: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
sparse-checkout: |
docs
includes
- uses: actions/setup-python@v4
with:
python-version: 3.x
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force
```
## Conclusion
That's all there is! We're super happy with the results and hope that this will
help you to speed up your documentation builds in [GitHub Actions] as well. As
always, feel free to share your thoughts and experiences in the comments below.

View File

@ -21,7 +21,7 @@
import os
import re
from glob import glob
from glob import iglob
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.pages import Page
from urllib.parse import urlencode, urlparse
@ -40,7 +40,7 @@ def on_page_markdown(markdown: str, *, page: Page, config: MkDocsConfig, files):
# Collect all existing languages
names: dict[str, str] = {}
known: dict[str, dict[str, str]] = {}
for path in glob("src/templates/partials/languages/*.html"):
for path in iglob("src/templates/partials/languages/*.html"):
with open(path, "r", encoding = "utf-8") as f:
data = f.read()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -44,7 +44,7 @@
{% endif %}
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.72749a73.min.css' | url }}">
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.d451bc0e.min.css' | url }}">
{% if config.theme.palette %}
{% set palette = config.theme.palette %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/palette.a5377069.min.css' | url }}">
@ -250,7 +250,7 @@
</script>
{% endblock %}
{% block scripts %}
<script src="{{ 'assets/javascripts/bundle.73f771f6.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.5827baa9.min.js' | url }}"></script>
{% for script in config.extra_javascript %}
{{ script | script_tag }}
{% endfor %}

View File

@ -8,7 +8,7 @@
<div class="md-sidebar md-sidebar--post" data-md-component="sidebar" data-md-type="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner md-post">
<nav class="md-nav">
<nav class="md-nav md-nav--primary">
<div class="md-post__back">
<div class="md-nav__title md-nav__container">
<a href="{{ page.parent.url | url }}" class="md-nav__link">
@ -35,62 +35,66 @@
</div>
{% endif %}
<ul class="md-post__meta md-nav__list">
<li class="md-nav__item md-nav__title">
<div class="md-nav__link">
<li class="md-nav__item md-nav__item--section">
<div class="md-post__title">
<span class="md-ellipsis">
{{ lang.t("blog.meta") }}
</span>
</div>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/calendar.svg" %}
<time datetime="{{ page.config.date.created }}" class="md-ellipsis">
{{- page.config.date.created | date -}}
</time>
</div>
</li>
{% if page.config.date.updated %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/calendar-clock.svg" %}
<time datetime="{{ page.config.date.updated }}" class="md-ellipsis">
{{- page.config.date.updated | date -}}
</time>
</div>
</li>
{% endif %}
{% if page.categories %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/bookshelf.svg" %}
<span class="md-ellipsis">
{{ lang.t("blog.categories.in") }}
{% for category in page.categories %}
<a href="{{ category.url | url }}">
{{- category.title -}}
</a>
{%- if loop.revindex > 1 %}, {% endif -%}
{% endfor -%}
</span>
</div>
</li>
{% endif %}
{% if page.config.readtime %}
{% set time = page.config.readtime %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/clock-outline.svg" %}
<span class="md-ellipsis">
{% if time == 1 %}
{{ lang.t("readtime.one") }}
{% else %}
{{ lang.t("readtime.other") | replace("#", time) }}
{% endif %}
</span>
</div>
</li>
{% endif %}
</ul>
</nav>
</li>
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/calendar.svg" %}
<time datetime="{{ page.config.date.created }}" class="md-ellipsis">
{{- page.config.date.created | date -}}
</time>
</div>
</li>
{% if page.config.date.updated %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/calendar-clock.svg" %}
<time datetime="{{ page.config.date.updated }}" class="md-ellipsis">
{{- page.config.date.updated | date -}}
</time>
</div>
</li>
{% endif %}
{% if page.categories %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/bookshelf.svg" %}
<span class="md-ellipsis">
{{ lang.t("blog.categories.in") }}
{% for category in page.categories %}
<a href="{{ category.url | url }}">
{{- category.title -}}
</a>
{%- if loop.revindex > 1 %}, {% endif -%}
{% endfor -%}
</span>
</div>
</li>
{% endif %}
{% if page.config.readtime %}
{% set time = page.config.readtime %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/clock-outline.svg" %}
<span class="md-ellipsis">
{% if time == 1 %}
{{ lang.t("readtime.one") }}
{% else %}
{{ lang.t("readtime.other") | replace("#", time) }}
{% endif %}
</span>
</div>
</li>
{% endif %}
</ul>
</nav>
{% if "toc.integrate" in features %}

View File

@ -47,6 +47,7 @@
"select.language": "Izberi jezik",
"select.version": "Izberi različico",
"source": "Pojdi na repozitorij",
"source.file.contributors": "Soavtorji",
"source.file.date.created": "Ustvarjeno",
"source.file.date.updated": "Zadnja posodobitev",
"tabs": "Zavihki",

View File

@ -48,25 +48,26 @@
{% endif %}
{% endfor %}
{% endif %}
{% if "navigation.sections" in features and level == 1 + (
"navigation.tabs" in features
) %}
{% set tabs = "navigation.tabs" in features %}
{% set sections = "navigation.sections" in features %}
{% if tabs and level == 1 or sections and tabs >= level - 1 %}
{% set class = class ~ " md-nav__item--section" %}
{% set is_section = true %}
{% elif not nav_item.active and "navigation.prune" in features %}
{% set class = class ~ " md-nav__item--pruned" %}
{% set prune = true %}
{% set is_pruned = true %}
{% endif %}
<li class="{{ class }} md-nav__item--nested">
{% if not prune %}
{% set expanded = "navigation.expand" in features %}
{% set active = nav_item.active or expanded %}
{% if not is_pruned %}
{% set checked = "checked" if nav_item.active %}
{% if expanded and not checked %}
{% set is_expanded = "navigation.expand" in features %}
{% if is_expanded and not checked %}
{% set indeterminate = "md-toggle--indeterminate" %}
{% endif %}
<input class="md-nav__toggle md-toggle {{ indeterminate }}" type="checkbox" id="{{ path }}" {{ checked }}>
{% if not indexes %}
<label class="md-nav__link" for="{{ path }}" id="{{ path }}_label" tabindex="0">
{% set tabindex = "0" if not is_section %}
<label class="md-nav__link" for="{{ path }}" id="{{ path }}_label" tabindex="{{ tabindex }}">
{{ render_content(nav_item) }}
<span class="md-nav__icon md-icon"></span>
</label>
@ -78,7 +79,8 @@
{{ render_content(index, nav_item) }}
</a>
{% if nav_item.children | length > 1 %}
<label class="md-nav__link {{ class }}" for="{{ path }}">
{% set tabindex = "0" if not is_section %}
<label class="md-nav__link {{ class }}" for="{{ path }}" id="{{ path }}_label" tabindex="{{ tabindex }}">
<span class="md-nav__icon md-icon"></span>
</label>
{% endif %}

View File

@ -21,7 +21,7 @@
import os
import re
from glob import glob
from glob import iglob
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.pages import Page
from urllib.parse import urlencode, urlparse
@ -40,7 +40,7 @@ def on_page_markdown(markdown: str, *, page: Page, config: MkDocsConfig, files):
# Collect all existing languages
names: dict[str, str] = {}
known: dict[str, dict[str, str]] = {}
for path in glob("src/templates/partials/languages/*.html"):
for path in iglob("src/templates/partials/languages/*.html"):
with open(path, "r", encoding = "utf-8") as f:
data = f.read()

View File

@ -24,6 +24,7 @@ import {
Observable,
Subject,
animationFrameScheduler,
asyncScheduler,
auditTime,
combineLatest,
defer,
@ -36,6 +37,7 @@ import {
ignoreElements,
map,
mergeMap,
observeOn,
takeUntil,
tap,
withLatestFrom
@ -202,6 +204,7 @@ export function mountSidebar(
.pipe(
mergeMap(label => fromEvent(label, "click")
.pipe(
observeOn(asyncScheduler),
map(() => label),
takeUntil(done$)
)

View File

@ -30,10 +30,12 @@ import {
debounceTime,
distinctUntilKeyChanged,
endWith,
filter,
fromEvent,
ignoreElements,
map,
of,
sample,
share,
skip,
startWith,
@ -291,19 +293,17 @@ export function setupInstantLoading(
popstate$.pipe(map(getLocation))
.subscribe(location$)
// Intercept clicks on anchor links, and scroll document into position. As
// we disabled scroll restoration, we need to do this manually here.
// Intercept clicks on anchor links, and scroll document into position - as
// we disabled scroll restoration, we need to do this manually here
location$
.pipe(
startWith(getLocation()),
bufferCount(2, 1),
switchMap(([prev, next]) => (
filter(([prev, next]) => (
prev.pathname === next.pathname &&
prev.hash !== next.hash
)
? of(next)
: EMPTY
)
)),
map(([, next]) => next)
)
.subscribe(url => {
if (history.state !== null || !url.hash) {
@ -315,6 +315,29 @@ export function setupInstantLoading(
}
})
// Intercept clicks on the same anchor link - we must use a distinct pipeline
// for this, or we'd end up in a loop, setting the hash again and again
location$
.pipe(
sample(instant$),
startWith(getLocation()),
bufferCount(2, 1),
filter(([prev, next]) => (
prev.pathname === next.pathname &&
prev.hash === next.hash
)),
map(([, next]) => next)
)
.subscribe(url => {
history.scrollRestoration = "auto"
setLocationHash(url.hash)
history.scrollRestoration = "manual"
// Hack: we need to make sure that we don't end up with multiple history
// entries for the same anchor link, so we just remove the last entry
history.back()
})
// After parsing the document, check if the current history entry has a state.
// This may happen when users press the back or forward button to visit a page
// that was already seen. If there's no state, it means a new page was visited
@ -332,9 +355,8 @@ export function setupInstantLoading(
// the current history state whenever the scroll position changes. This must
// be debounced and cannot be done in popstate, as popstate has already
// removed the entry from the history.
document$
viewport$
.pipe(
switchMap(() => viewport$),
distinctUntilKeyChanged("offset"),
debounceTime(100)
)

View File

@ -80,19 +80,10 @@
list-style: none;
}
// Navigation item
&__item {
padding: 0 px2rem(12px);
// Navigation item on level 2
& & {
padding-inline-end: 0;
}
}
// Navigation link
&__link {
display: flex;
gap: px2rem(8px);
align-items: flex-start;
margin-top: 0.625em;
transition: color 125ms;
@ -121,9 +112,9 @@
position: relative;
}
// Always align navigation icons to the right
// Always align navigation icons to the end
.md-icon:last-child {
margin-left: auto;
margin-inline-start: auto;
}
// Navigation link icon
@ -131,15 +122,10 @@
flex-shrink: 0;
height: 1.3em;
fill: currentcolor;
// Adjust spacing of next child
+ * {
margin-inline-start: px2rem(8px);
}
}
// Navigation link on focus/hover
&:not(.md-nav__container):is(:focus, :hover) {
&:is([href], [for]):is(:focus, :hover) {
color: var(--md-accent-fg-color);
cursor: pointer;
}
@ -177,6 +163,9 @@
// Stretch first child
&:first-child {
flex-grow: 1;
// Hack: if a very long word is used, it can push the arrow out of sight.
// Setting this property contains the text - see https://t.ly/E02vp
min-width: 0;
}
}
@ -290,7 +279,6 @@
// Navigation item
.md-nav__item {
padding: 0;
border-top: px2rem(1px) solid var(--md-default-fg-color--lightest);
// Navigation link in active navigation
@ -386,7 +374,7 @@
background-color: transparent;
}
// Toggle for nested navigation
// Hide nested navigation
&__toggle ~ & {
display: flex;
opacity: 0;
@ -475,62 +463,118 @@
// [tablet landscape +]: Tree-like table of contents
@include break-from-device(tablet landscape) {
margin-bottom: px2rem(-8px);
// Navigation title
&--secondary &__title {
position: sticky;
top: 0;
// Hack: because of the hack that we need to make .md-ellipsis work in
// Safari, we need to set `z-index` here as - see https://bit.ly/3s5M2jm
z-index: 1;
background: var(--md-default-bg-color);
box-shadow: 0 0 px2rem(8px) px2rem(8px) var(--md-default-bg-color);
// Table of contents
&--secondary {
// Adjust snapping behavior
&[for="__toc"] {
scroll-snap-align: start;
// Navigation title
.md-nav__title {
position: sticky;
top: 0;
// Hack: because of the hack that we need to make .md-ellipsis work in
// Safari, we need to set `z-index` here as - see https://bit.ly/3s5M2jm
z-index: 1;
background: var(--md-default-bg-color);
box-shadow: 0 0 px2rem(8px) px2rem(8px) var(--md-default-bg-color);
// Adjust snapping behavior
&[for="__toc"] {
scroll-snap-align: start;
}
// Hide navigation icon
.md-nav__icon {
display: none;
}
}
// Hide navigation icon
.md-nav__icon {
display: none;
// Adjust spacing for navigation list - same reason as below
.md-nav__list {
padding-inline-start: px2rem(12px);
padding-bottom: px2rem(8px);
}
// Adjust spacing for navigation link - before this change, we set spacing
// on the left and right of a navigation item, but this led to the problem
// of cropped focus outlines, because we must set `overflow: hidden` on
// the navigation list for smooth expand and collapse transitions.
.md-nav__item > .md-nav__link {
margin-inline-end: px2rem(8px);
}
}
}
// [screen +]: Tree-like navigation
@include break-from-device(screen) {
margin-bottom: px2rem(-8px);
transition: max-height 250ms cubic-bezier(0.86, 0, 0.07, 1);
// Navigation title
&--primary &__title {
position: sticky;
top: 0;
// Hack: because of the hack that we need to make .md-ellipsis work in
// Safari, we need to set `z-index` here as - see https://bit.ly/3s5M2jm
z-index: 1;
background: var(--md-default-bg-color);
box-shadow: 0 0 px2rem(8px) px2rem(8px) var(--md-default-bg-color);
// Primary navigation
&--primary {
// Adjust snapping behavior
&[for="__drawer"] {
scroll-snap-align: start;
// Navigation title
.md-nav__title {
position: sticky;
top: 0;
// Hack: because of the hack that we need to make .md-ellipsis work in
// Safari, we need to set `z-index` here as - see https://bit.ly/3s5M2jm
z-index: 1;
background: var(--md-default-bg-color);
box-shadow: 0 0 px2rem(8px) px2rem(8px) var(--md-default-bg-color);
// Adjust snapping behavior
&[for="__drawer"] {
scroll-snap-align: start;
}
// Hide navigation icon
.md-nav__icon {
display: none;
}
}
// Hide navigation icon
.md-nav__icon {
display: none;
// Adjust spacing for navigation list - same reason as below
.md-nav__list {
padding-inline-start: px2rem(12px);
padding-bottom: px2rem(8px);
}
// Adjust spacing for navigation link - before this change, we set spacing
// on the left and right of a navigation item, but this led to the problem
// of cropped focus outlines, because we must set `overflow: hidden` on
// the navigation list for smooth expand and collapse transitions.
.md-nav__item > .md-nav__link {
margin-inline-end: px2rem(8px);
}
}
// Hide toggle for nested navigation
// Hide nested navigation
&__toggle ~ & {
display: none;
display: grid;
grid-template-rows: 0fr;
visibility: collapse;
opacity: 0;
transition:
grid-template-rows 250ms cubic-bezier(0.86, 0, 0.07, 1),
opacity 250ms,
visibility 0ms 250ms;
// Navigation list
> .md-nav__list {
overflow: hidden;
}
}
// Show nested navigation when toggle is active or indeterminate
&__toggle:is(:checked, :indeterminate) ~ & {
display: block;
grid-template-rows: 1fr;
visibility: visible;
opacity: 1;
transition:
grid-template-rows 250ms cubic-bezier(0.86, 0, 0.07, 1),
opacity 150ms 100ms,
visibility 0ms;
}
// Hide navigation title in nested navigation
@ -562,8 +606,9 @@
pointer-events: none;
}
// Hide naviation icon
.md-nav__icon {
// Hide navigation icon
> [for],
.md-icon {
display: none;
}
}
@ -571,6 +616,9 @@
// Navigation
> .md-nav {
display: block;
margin-inline-start: px2rem(-12px);
visibility: visible;
opacity: 1;
// Adjust spacing on next level item
> .md-nav__list > .md-nav__item {
@ -622,8 +670,7 @@
// Modifier for when navigation tabs are rendered
&--lifted {
// Hide nested level 0 navigation items and site title
> .md-nav__list > .md-nav__item--nested,
// Hide site title
> .md-nav__title {
display: none;
}
@ -635,16 +682,13 @@
// Active parent navigation item
&--active {
display: block;
padding: 0;
// Show navigation link as title
> .md-nav__link {
position: sticky;
top: 0;
z-index: 1;
padding: 0 px2rem(12px);
margin-top: 0;
font-weight: 700;
background: var(--md-default-bg-color);
box-shadow: 0 0 px2rem(8px) px2rem(8px) var(--md-default-bg-color);
@ -652,12 +696,17 @@
&:not(.md-nav__container) {
pointer-events: none;
}
// Hide naviation icon
.md-nav__icon {
display: none;
}
}
// Adjust spacing for navigation section
&.md-nav__item--section {
margin: 0;
}
}
// Adjust spacing for nested navigation
> .md-nav {
margin-inline-start: px2rem(-12px);
}
// Make labels discernable from links
@ -667,14 +716,11 @@
}
// Hack: Always show active navigation tab on breakpoint screen, despite
// of checkbox being checked or not. Fixes #1655.
// of checkbox being checked or not - see https://t.ly/Qc311
.md-nav[data-md-level="1"] {
display: block;
// Adjust spacing for level 1 navigation items
> .md-nav__list > .md-nav__item {
padding-inline-end: px2rem(12px);
}
grid-template-rows: 1fr;
visibility: visible;
opacity: 1;
}
}
@ -695,7 +741,15 @@
.md-nav--secondary {
display: block;
margin-bottom: 1.25em;
visibility: visible;
border-inline-start: px2rem(1px) solid var(--md-primary-fg-color);
opacity: 1;
// Navigation list
> .md-nav__list {
padding-bottom: 0;
overflow: visible;
}
// Hide table of contents title
> .md-nav__title {

View File

@ -53,7 +53,7 @@
display: flex;
flex-direction: column;
gap: px2rem(12px);
margin: 0 px2rem(12px);
margin: 0 px2rem(12px) px2rem(24px);
}
// Post metadata
@ -70,6 +70,12 @@
}
}
// Post navigation title @todo - generalize
&__title {
font-weight: 700;
color: var(--md-default-fg-color--light);
}
// Post excerpt
&--excerpt {
margin-bottom: px2rem(64px);
@ -105,8 +111,7 @@
}
}
// Adjust spacing for navigation
> .md-nav:first-child > .md-nav__list,
// Add margin to table of contents
> .md-nav--secondary {
margin: 1em 0;
}

View File

@ -36,7 +36,6 @@
// Status
.md-status {
margin-left: px2rem(4px);
// Status icon
&::after {

View File

@ -36,7 +36,7 @@
>
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner md-post">
<nav class="md-nav">
<nav class="md-nav md-nav--primary">
<!-- Back to overview link -->
<div class="md-post__back">
@ -50,7 +50,7 @@
</div>
</div>
<!-- Page authors -->
<!-- Post authors -->
{% if page.authors %}
<div class="md-post__authors md-typeset">
{% for author in page.authors %}
@ -67,72 +67,82 @@
</div>
{% endif %}
<!-- Page metadata -->
<!-- Post metadata -->
<ul class="md-post__meta md-nav__list">
<li class="md-nav__item md-nav__title">
<div class="md-nav__link">
<li class="md-nav__item md-nav__item--section">
<div class="md-post__title">
<span class="md-ellipsis">
{{ lang.t("blog.meta") }}
</span>
</div>
<nav class="md-nav">
<ul class="md-nav__list">
<!-- Post date -->
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/calendar.svg" %}
<time
datetime="{{ page.config.date.created }}"
class="md-ellipsis"
>
{{- page.config.date.created | date -}}
</time>
</div>
</li>
<!-- Post date updated -->
{% if page.config.date.updated %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/calendar-clock.svg" %}
<time
datetime="{{ page.config.date.updated }}"
class="md-ellipsis"
>
{{- page.config.date.updated | date -}}
</time>
</div>
</li>
{% endif %}
<!-- Post categories -->
{% if page.categories %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/bookshelf.svg" %}
<span class="md-ellipsis">
{{ lang.t("blog.categories.in") }}
{% for category in page.categories %}
<a href="{{ category.url | url }}">
{{- category.title -}}
</a>
{%- if loop.revindex > 1 %}, {% endif -%}
{% endfor -%}
</span>
</div>
</li>
{% endif %}
<!-- Post readtime -->
{% if page.config.readtime %}
{% set time = page.config.readtime %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/clock-outline.svg" %}
<span class="md-ellipsis">
{% if time == 1 %}
{{ lang.t("readtime.one") }}
{% else %}
{{ lang.t("readtime.other") | replace("#", time) }}
{% endif %}
</span>
</div>
</li>
{% endif %}
</ul>
</nav>
</li>
<!-- Page date -->
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/calendar.svg" %}
<time datetime="{{ page.config.date.created }}" class="md-ellipsis">
{{- page.config.date.created | date -}}
</time>
</div>
</li>
<!-- Page date updated -->
{% if page.config.date.updated %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/calendar-clock.svg" %}
<time datetime="{{ page.config.date.updated }}" class="md-ellipsis">
{{- page.config.date.updated | date -}}
</time>
</div>
</li>
{% endif %}
<!-- Page categories -->
{% if page.categories %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/bookshelf.svg" %}
<span class="md-ellipsis">
{{ lang.t("blog.categories.in") }}
{% for category in page.categories %}
<a href="{{ category.url | url }}">
{{- category.title -}}
</a>
{%- if loop.revindex > 1 %}, {% endif -%}
{% endfor -%}
</span>
</div>
</li>
{% endif %}
<!-- Page readtime -->
{% if page.config.readtime %}
{% set time = page.config.readtime %}
<li class="md-nav__item">
<div class="md-nav__link">
{% include ".icons/material/clock-outline.svg" %}
<span class="md-ellipsis">
{% if time == 1 %}
{{ lang.t("readtime.one") }}
{% else %}
{{ lang.t("readtime.other") | replace("#", time) }}
{% endif %}
</span>
</div>
</li>
{% endif %}
</ul>
</nav>

View File

@ -67,6 +67,7 @@
"select.language": "Izberi jezik",
"select.version": "Izberi različico",
"source": "Pojdi na repozitorij",
"source.file.contributors": "Soavtorji",
"source.file.date.created": "Ustvarjeno",
"source.file.date.updated": "Zadnja posodobitev",
"tabs": "Zavihki",

View File

@ -101,26 +101,26 @@
{% endif %}
<!-- Determine whether to render item as a section -->
{% if "navigation.sections" in features and level == 1 + (
"navigation.tabs" in features
) %}
{% set tabs = "navigation.tabs" in features %}
{% set sections = "navigation.sections" in features %}
{% if tabs and level == 1 or sections and tabs >= level - 1 %}
{% set class = class ~ " md-nav__item--section" %}
{% set is_section = true %}
<!-- Determine whether to prune inactive item -->
{% elif not nav_item.active and "navigation.prune" in features %}
{% set class = class ~ " md-nav__item--pruned" %}
{% set prune = true %}
{% set is_pruned = true %}
{% endif %}
<!-- Nested navigation item -->
<li class="{{ class }} md-nav__item--nested">
{% if not prune %}
{% set expanded = "navigation.expand" in features %}
{% set active = nav_item.active or expanded %}
{% if not is_pruned %}
{% set checked = "checked" if nav_item.active %}
<!-- Determine checked and indeterminate state -->
{% set checked = "checked" if nav_item.active %}
{% if expanded and not checked %}
{% set is_expanded = "navigation.expand" in features %}
{% if is_expanded and not checked %}
{% set indeterminate = "md-toggle--indeterminate" %}
{% endif %}
@ -134,11 +134,12 @@
<!-- Toggle to expand nested items -->
{% if not indexes %}
{% set tabindex = "0" if not is_section %}
<label
class="md-nav__link"
for="{{ path }}"
id="{{ path }}_label"
tabindex="0"
tabindex="{{ tabindex }}"
>
{{ render_content(nav_item) }}
<span class="md-nav__icon md-icon"></span>
@ -158,7 +159,13 @@
<!-- Only render toggle if there's at least one more page -->
{% if nav_item.children | length > 1 %}
<label class="md-nav__link {{ class }}" for="{{ path }}">
{% set tabindex = "0" if not is_section %}
<label
class="md-nav__link {{ class }}"
for="{{ path }}"
id="{{ path }}_label"
tabindex="{{ tabindex }}"
>
<span class="md-nav__icon md-icon"></span>
</label>
{% endif %}