forked from drowl87/hextra_mirror
feat: add blog list layout
chore: add toc to mobile dropdown menu single items chore: refactor sidebar chore: add single layout for blog chore: add vscode settings chore: add blog section chore: add devcontainer.json chore: exclude icon from mobile nav chore: support multiple theme switches - simplify theme switch implementation using data attributes - hide theme switch when sidebar is disabled chore: add theme switch to footer - enable when sidebar is disabled chore: add format-date partial
This commit is contained in:
parent
2f34627da3
commit
a7aa9fa1cb
23
.devcontainer/devcontainer.json
Normal file
23
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/go:1",
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/hugo:1": {
|
||||||
|
"extended": true,
|
||||||
|
"version": "0.116.1"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/node:1": {}
|
||||||
|
},
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"mhutchie.git-graph",
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
"bradlc.vscode-tailwindcss",
|
||||||
|
"tamasfe.even-better-toml",
|
||||||
|
"budparr.language-hugo-vscode"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postCreateCommand": "npm install",
|
||||||
|
"forwardPorts": [1313]
|
||||||
|
}
|
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"css.customData": [".vscode/tailwind.json"]
|
||||||
|
}
|
55
.vscode/tailwind.json
vendored
Normal file
55
.vscode/tailwind.json
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"version": 1.1,
|
||||||
|
"atDirectives": [
|
||||||
|
{
|
||||||
|
"name": "@tailwind",
|
||||||
|
"description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#tailwind"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "@apply",
|
||||||
|
"description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#apply"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "@responsive",
|
||||||
|
"description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#responsive"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "@screen",
|
||||||
|
"description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#screen"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "@variants",
|
||||||
|
"description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#variants"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,44 +1,36 @@
|
|||||||
// Dark theme toggle
|
// Dark theme toggle
|
||||||
// https://flowbite.com/docs/customize/dark-mode/
|
|
||||||
|
|
||||||
const themeToggleBtn = document.getElementById("theme-toggle");
|
const themeToggleButtons = document.querySelectorAll(".theme-toggle");
|
||||||
|
|
||||||
const themeToggleDarkIcon = document.getElementById("theme-toggle-dark-icon");
|
|
||||||
const themeToggleLightIcon = document.getElementById("theme-toggle-light-icon");
|
|
||||||
|
|
||||||
// Change the icons inside the button based on previous settings
|
// Change the icons inside the button based on previous settings
|
||||||
if (
|
if (
|
||||||
localStorage.getItem("color-theme") === "dark" ||
|
localStorage.getItem("color-theme") === "dark" ||
|
||||||
(!("color-theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)
|
(!("color-theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)
|
||||||
) {
|
) {
|
||||||
themeToggleLightIcon.classList.remove("hidden");
|
themeToggleButtons.forEach((el) => el.dataset.theme = "dark");
|
||||||
} else {
|
} else {
|
||||||
themeToggleDarkIcon.classList.remove("hidden");
|
themeToggleButtons.forEach((el) => el.dataset.theme = "light");
|
||||||
}
|
}
|
||||||
|
|
||||||
themeToggleBtn.addEventListener("click", function () {
|
themeToggleButtons.forEach((el) => {
|
||||||
// toggle icons inside button
|
el.addEventListener("click", function () {
|
||||||
themeToggleDarkIcon.classList.toggle("hidden");
|
if (localStorage.getItem("color-theme")) {
|
||||||
themeToggleLightIcon.classList.toggle("hidden");
|
if (localStorage.getItem("color-theme") === "light") {
|
||||||
|
document.documentElement.classList.add("dark");
|
||||||
// if set via local storage previously
|
localStorage.setItem("color-theme", "dark");
|
||||||
if (localStorage.getItem("color-theme")) {
|
} else {
|
||||||
if (localStorage.getItem("color-theme") === "light") {
|
document.documentElement.classList.remove("dark");
|
||||||
document.documentElement.classList.add("dark");
|
localStorage.setItem("color-theme", "light");
|
||||||
localStorage.setItem("color-theme", "dark");
|
}
|
||||||
} else {
|
} else {
|
||||||
document.documentElement.classList.remove("dark");
|
if (document.documentElement.classList.contains("dark")) {
|
||||||
localStorage.setItem("color-theme", "light");
|
document.documentElement.classList.remove("dark");
|
||||||
|
localStorage.setItem("color-theme", "light");
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.add("dark");
|
||||||
|
localStorage.setItem("color-theme", "dark");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
el.dataset.theme = document.documentElement.classList.contains("dark") ? "dark" : "light";
|
||||||
// if NOT set via local storage previously
|
});
|
||||||
} else {
|
|
||||||
if (document.documentElement.classList.contains("dark")) {
|
|
||||||
document.documentElement.classList.remove("dark");
|
|
||||||
localStorage.setItem("color-theme", "light");
|
|
||||||
} else {
|
|
||||||
document.documentElement.classList.add("dark");
|
|
||||||
localStorage.setItem("color-theme", "dark");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
3
content/blog/_index.md
Normal file
3
content/blog/_index.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
title: "Hextra Blog"
|
||||||
|
---
|
175
content/blog/markdown.md
Normal file
175
content/blog/markdown.md
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
---
|
||||||
|
title: Markdown
|
||||||
|
math: true
|
||||||
|
date: 2020-01-01
|
||||||
|
authors:
|
||||||
|
- name: John Doe
|
||||||
|
link: https://example.com/johndoe
|
||||||
|
image: https://example.com/johndoe.png
|
||||||
|
---
|
||||||
|
|
||||||
|
This article offers a sample of basic Markdown syntax that can be used in Hugo content files, also it shows whether basic HTML elements are decorated with CSS in a Hugo theme.
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
## Headings
|
||||||
|
|
||||||
|
The following HTML `<h1>`—`<h6>` elements represent six levels of section headings. `<h1>` is the highest section level while `<h6>` is the lowest.
|
||||||
|
|
||||||
|
# H1
|
||||||
|
## H2
|
||||||
|
### H3
|
||||||
|
#### H4
|
||||||
|
##### H5
|
||||||
|
###### H6
|
||||||
|
|
||||||
|
## Paragraph
|
||||||
|
|
||||||
|
Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.
|
||||||
|
|
||||||
|
Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.
|
||||||
|
|
||||||
|
## Blockquotes
|
||||||
|
|
||||||
|
The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations.
|
||||||
|
|
||||||
|
#### Blockquote without attribution
|
||||||
|
|
||||||
|
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
|
||||||
|
> **Note** that you can use *Markdown syntax* within a blockquote.
|
||||||
|
|
||||||
|
#### Blockquote with attribution
|
||||||
|
|
||||||
|
> Don't communicate by sharing memory, share memory by communicating.<br>
|
||||||
|
> — <cite>Rob Pike[^1]</cite>
|
||||||
|
|
||||||
|
[^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
|
||||||
|
|
||||||
|
## Tables
|
||||||
|
|
||||||
|
Tables aren't part of the core Markdown spec, but Hugo supports them out-of-the-box.
|
||||||
|
|
||||||
|
Name | Age
|
||||||
|
--------|------
|
||||||
|
Bob | 27
|
||||||
|
Alice | 23
|
||||||
|
|
||||||
|
#### Inline Markdown within tables
|
||||||
|
|
||||||
|
| Italics | Bold | Code |
|
||||||
|
| -------- | -------- | ------ |
|
||||||
|
| *italics* | **bold** | `code` |
|
||||||
|
|
||||||
|
## Code Blocks
|
||||||
|
|
||||||
|
### Code block with triple backticks
|
||||||
|
|
||||||
|
```
|
||||||
|
def say_hello():
|
||||||
|
print("Hello!")
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```python
|
||||||
|
def say_hello():
|
||||||
|
print("Hello!")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code block with filename
|
||||||
|
|
||||||
|
```python {filename="hello.py"}
|
||||||
|
def say_hello():
|
||||||
|
print("Hello!")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code block highlight with line numbers
|
||||||
|
|
||||||
|
```python {linenos=table,hl_lines=[1, 2],linenostart=1}
|
||||||
|
def say_hello():
|
||||||
|
print("Hello!")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
say_hello()
|
||||||
|
```
|
||||||
|
|
||||||
|
```python {linenos=table,hl_lines=[1, 2],linenostart=1,filename="hello.py"}
|
||||||
|
def say_hello():
|
||||||
|
print("Hello!")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
say_hello()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Diagrams
|
||||||
|
|
||||||
|
[Mermaid](https://github.com/mermaid-js/mermaid#readme) is a JavaScript based diagramming and charting tool that takes Markdown-inspired text definitions and creates diagrams dynamically in the browser.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant Alice
|
||||||
|
participant Bob
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
loop Healthcheck
|
||||||
|
John->>John: Fight against hypochondria
|
||||||
|
end
|
||||||
|
Note right of John: Rational thoughts <br/>prevail!
|
||||||
|
John-->>Alice: Great!
|
||||||
|
John->>Bob: How about you?
|
||||||
|
Bob-->>John: Jolly good!
|
||||||
|
```
|
||||||
|
|
||||||
|
## List Types
|
||||||
|
|
||||||
|
#### Ordered List
|
||||||
|
|
||||||
|
1. First item
|
||||||
|
2. Second item
|
||||||
|
3. Third item
|
||||||
|
|
||||||
|
#### Unordered List
|
||||||
|
|
||||||
|
* List item
|
||||||
|
* Another item
|
||||||
|
* And another item
|
||||||
|
|
||||||
|
#### Nested list
|
||||||
|
|
||||||
|
* Fruit
|
||||||
|
* Apple
|
||||||
|
* Orange
|
||||||
|
* Banana
|
||||||
|
* Dairy
|
||||||
|
* Milk
|
||||||
|
* Cheese
|
||||||
|
|
||||||
|
## Math
|
||||||
|
|
||||||
|
[KaTeX](https://github.com/KaTeX/KaTeX) is a fast math typesetting library for the web. It uses javascript for client-side rendering.
|
||||||
|
|
||||||
|
### Inline
|
||||||
|
|
||||||
|
```
|
||||||
|
This $\int\limits_1^\infty \frac{1}{k}\,dk$ is inline.
|
||||||
|
```
|
||||||
|
|
||||||
|
This $\int\limits_1^\infty \frac{1}{k}\,dk$ is inline.
|
||||||
|
|
||||||
|
### Separate Paragraph
|
||||||
|
|
||||||
|
```
|
||||||
|
$$f(x) = \int_{-\infty}^\infty \hat f(\xi)\,e^{2 \pi i \xi x} \,d\xi$$
|
||||||
|
```
|
||||||
|
|
||||||
|
$$f(x) = \int_{-\infty}^\infty \hat f(\xi)\,e^{2 \pi i \xi x} \,d\xi$$
|
||||||
|
|
||||||
|
|
||||||
|
## Other Elements — abbr, sub, sup, kbd, mark
|
||||||
|
|
||||||
|
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
|
||||||
|
|
||||||
|
H<sub>2</sub>O
|
||||||
|
|
||||||
|
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
|
||||||
|
|
||||||
|
Press <kbd>CTRL</kbd>+<kbd>ALT</kbd>+<kbd>Delete</kbd> to end the session.
|
||||||
|
|
||||||
|
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
|
@ -56,8 +56,8 @@ defaultContentLanguage = 'en'
|
|||||||
pageRef = '/docs'
|
pageRef = '/docs'
|
||||||
weight = 10
|
weight = 10
|
||||||
[[menu.main]]
|
[[menu.main]]
|
||||||
name = 'Showcase'
|
name = 'Blog'
|
||||||
pageRef = '/showcase'
|
pageRef = '/blog'
|
||||||
weight = 20
|
weight = 20
|
||||||
[[menu.main]]
|
[[menu.main]]
|
||||||
name = 'About'
|
name = 'About'
|
||||||
@ -81,3 +81,8 @@ defaultContentLanguage = 'en'
|
|||||||
name = 'Hugo Docs ↗'
|
name = 'Hugo Docs ↗'
|
||||||
url = 'https://gohugo.io/documentation/'
|
url = 'https://gohugo.io/documentation/'
|
||||||
weight = 20
|
weight = 20
|
||||||
|
|
||||||
|
[params]
|
||||||
|
dateFormat = 'January 2, 2006'
|
||||||
|
|
||||||
|
displayUpdatedDate = true
|
||||||
|
21
layouts/blog/list.html
Normal file
21
layouts/blog/list.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
<div class="mx-auto flex max-w-[90rem]">
|
||||||
|
{{ partial "sidebar.html" (dict "context" . "disableSidebar" true) }}
|
||||||
|
<article class="w-full break-words flex min-h-[calc(100vh-4rem)] min-w-0 justify-center pb-8 pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||||
|
<main class="w-full min-w-0 max-w-6xl px-6 pt-4 md:px-12">
|
||||||
|
<h1 class="text-4xl tracking-tighter text-center font-extrabold md:text-5xl mt-8 pb-6">{{ .Title }}</h1>
|
||||||
|
{{ range .Pages.ByDate }}
|
||||||
|
<div class="mb-10">
|
||||||
|
<h3><a style="color: inherit; text-decoration: none;" class="block font-semibold mt-8 text-2xl " href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
|
||||||
|
<p class="opacity-80 mt-6 leading-7">
|
||||||
|
{{- partial "utils/page-description" . }}
|
||||||
|
<span class="inline-block"> <a class="text-[color:hsl(var(--primary-hue),100%,50%)] underline underline-offset-2 decoration-from-font" href="{{ .RelPermalink }}">Read more →</a> </span>
|
||||||
|
</p>
|
||||||
|
<p class="opacity-50 text-sm mt-6 leading-7">{{ partial "utils/format-date" .Date }}</p>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</main>
|
||||||
|
</article>
|
||||||
|
<div class="max-xl:hidden h-0 w-64 shrink-0"></div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
33
layouts/blog/single.html
Normal file
33
layouts/blog/single.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
<div class="mx-auto flex max-w-[90rem]">
|
||||||
|
{{ partial "sidebar.html" (dict "context" . "disableSidebar" true) }}
|
||||||
|
{{ partial "toc.html" . }}
|
||||||
|
<article class="w-full break-words flex min-h-[calc(100vh-4rem)] min-w-0 justify-center pb-8 pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||||
|
<main class="w-full min-w-0 max-w-6xl px-6 pt-4 md:px-12">
|
||||||
|
{{ partial "breadcrumb.html" . }}
|
||||||
|
<h1 class="mt-2 text-4xl font-bold tracking-tight text-slate-900 dark:text-slate-100">{{ .Title }}</h1>
|
||||||
|
{{ with $date := .Date }}
|
||||||
|
<div class="mt-4 mb-16 text-gray-500 text-sm">
|
||||||
|
{{ partial "utils/format-date" $date }}
|
||||||
|
{{- if $.Params.authors }} by {{ end -}}
|
||||||
|
{{- with $.Params.authors }}
|
||||||
|
{{- range $i, $author := . -}}
|
||||||
|
{{- if $i }},{{ end -}}
|
||||||
|
{{- if $author.link }}
|
||||||
|
<a href="{{ $author.link }}" target="_blank" class="mx-1 text-current underline [text-underline-position:from-font] decoration-from-font">{{ $author.name }}</a>
|
||||||
|
{{ else }}
|
||||||
|
<span>{{ $author.name }}</span>
|
||||||
|
{{ end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
<div class="content">
|
||||||
|
{{ .Content }}
|
||||||
|
</div>
|
||||||
|
<div class="mt-16"></div>
|
||||||
|
{{ partial "pager.html" . }}
|
||||||
|
</main>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
@ -1,6 +1,6 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<div class="mx-auto flex max-w-[90rem]">
|
<div class="mx-auto flex max-w-[90rem]">
|
||||||
{{ partial "sidebar.html" . }}
|
{{ partial "sidebar.html" (dict "context" .) }}
|
||||||
{{ partial "toc.html" . }}
|
{{ partial "toc.html" . }}
|
||||||
<article class="w-full break-words flex min-h-[calc(100vh-4rem)] min-w-0 justify-center pb-8 pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
<article class="w-full break-words flex min-h-[calc(100vh-4rem)] min-w-0 justify-center pb-8 pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||||
<main class="w-full min-w-0 max-w-6xl px-6 pt-4 md:px-12">
|
<main class="w-full min-w-0 max-w-6xl px-6 pt-4 md:px-12">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<div class="mx-auto flex max-w-[90rem]">
|
<div class="mx-auto flex max-w-[90rem]">
|
||||||
{{ partial "sidebar.html" . }}
|
{{ partial "sidebar.html" (dict "context" .) }}
|
||||||
{{ partial "toc.html" . }}
|
{{ partial "toc.html" . }}
|
||||||
<article class="w-full break-words flex min-h-[calc(100vh-4rem)] min-w-0 justify-center pb-8 pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
<article class="w-full break-words flex min-h-[calc(100vh-4rem)] min-w-0 justify-center pb-8 pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||||
<main class="w-full min-w-0 max-w-6xl px-6 pt-4 md:px-12">
|
<main class="w-full min-w-0 max-w-6xl px-6 pt-4 md:px-12">
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
{{- $enableFooterSwitches := .Scratch.Get "enableFooterSwitches" | default false -}}
|
||||||
|
|
||||||
|
|
||||||
<footer class="bg-gray-100 pb-[env(safe-area-inset-bottom)] dark:bg-neutral-900 print:bg-transparent">
|
<footer class="bg-gray-100 pb-[env(safe-area-inset-bottom)] dark:bg-neutral-900 print:bg-transparent">
|
||||||
|
{{- if $enableFooterSwitches }}{{ template "footer-switches" }}{{ end -}}
|
||||||
<hr class="dark:border-neutral-800" />
|
<hr class="dark:border-neutral-800" />
|
||||||
<div class="mx-auto flex max-w-[90rem] justify-center py-12 pl-[max(env(safe-area-inset-left),1.5rem)] pr-[max(env(safe-area-inset-right),1.5rem)] text-gray-600 dark:text-gray-400 md:justify-start">
|
<div class="mx-auto flex max-w-[90rem] justify-center py-12 pl-[max(env(safe-area-inset-left),1.5rem)] pr-[max(env(safe-area-inset-right),1.5rem)] text-gray-600 dark:text-gray-400 md:justify-start">
|
||||||
<div class="flex w-full flex-col items-center sm:items-start">
|
<div class="flex w-full flex-col items-center sm:items-start">
|
||||||
@ -12,3 +16,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
{{- define "footer-switches" -}}
|
||||||
|
<div class="mx-auto flex max-w-[90rem] gap-2 py-2 px-4">
|
||||||
|
{{ partial "theme-toggle.html" }}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
{{ $context := .context }}
|
||||||
|
{{ $disableSidebar := .disableSidebar | default false }}
|
||||||
|
|
||||||
|
{{ $navRoot := cond (eq site.Home.Type "docs") site.Home $context.FirstSection }}
|
||||||
|
{{ $navPages := union $navRoot.RegularPages $navRoot.Sections }}
|
||||||
|
{{ $pageURL := $context.RelPermalink }}
|
||||||
|
|
||||||
|
|
||||||
<aside class="sidebar-container flex flex-col print:hidden md:top-16 md:shrink-0 md:w-64 md:sticky md:self-start max-md:[transform:translate3d(0,-100%,0)]">
|
<aside class="sidebar-container flex flex-col print:hidden md:top-16 md:shrink-0 md:w-64 md:sticky md:self-start max-md:[transform:translate3d(0,-100%,0)]">
|
||||||
<!-- Search bar on small screen -->
|
<!-- Search bar on small screen -->
|
||||||
<div class="px-4 pt-4 md:hidden">
|
<div class="px-4 pt-4 md:hidden">
|
||||||
@ -5,47 +13,51 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="overflow-y-auto overflow-x-hidden p-4 grow md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]">
|
<div class="overflow-y-auto overflow-x-hidden p-4 grow md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]">
|
||||||
<ul class="flex flex-col gap-1 md:hidden">
|
<ul class="flex flex-col gap-1 md:hidden">
|
||||||
<!-- Navbar -->
|
<!-- Nav -->
|
||||||
{{- range .Site.Menus.main -}}
|
{{- range site.Menus.main -}}
|
||||||
{{- if and .URL (ne .Params.type "search") -}}
|
{{- if and .URL (and (ne .Params.type "search") (not .Params.icon)) -}}
|
||||||
<li>{{ template "sidebar-item-link" dict "active" false "title" .Name "link" .URL }}</li>
|
<li>{{ template "sidebar-item-link" dict "active" false "title" .Name "link" .URL }}</li>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
<div class="mt-4 border-t py-4 dark:border-neutral-800 contrast-more:border-neutral-400 dark:contrast-more:border-neutral-400" />
|
{{ template "sidebar-separator" }}
|
||||||
|
{{ template "sidebar-main" (dict "pages" $navPages "pageURL" $pageURL "toc" true) }}
|
||||||
{{- $s := .FirstSection -}}
|
|
||||||
{{- $topLevelItems := union $s.RegularPages $s.Sections -}}
|
|
||||||
{{- $pageURL := .RelPermalink -}}
|
|
||||||
|
|
||||||
{{- range $topLevelItems.ByWeight -}}
|
|
||||||
{{ template "sidebar-item" (dict "item" . "pageURL" $pageURL) }}
|
|
||||||
{{ template "sidebar-tree" (dict "context" . "level" 1 "pageURL" $pageURL "toc" true) }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Sidebar footer -->
|
<!-- Sidebar footer -->
|
||||||
<div class="mt-4 border-t py-4 dark:border-neutral-800 contrast-more:border-neutral-400 dark:contrast-more:border-neutral-400" />
|
{{ with site.Params.sidebar.footer -}}
|
||||||
{{ template "sidebar-footer" }}
|
{{ template "sidebar-separator" }}
|
||||||
|
{{ template "sidebar-footer" }}
|
||||||
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- Sidebar on large screen -->
|
<!-- Sidebar on large screen -->
|
||||||
<ul class="flex flex-col gap-1 max-md:hidden">
|
{{ if $disableSidebar -}}
|
||||||
{{- $s := .FirstSection -}}
|
<div class="max-xl:hidden h-0 w-64 shrink-0"></div>
|
||||||
{{- $topLevelItems := union $s.RegularPages $s.Sections -}}
|
{{ .context.Scratch.Set "enableFooterSwitches" true }}
|
||||||
{{- $pageURL := .RelPermalink -}}
|
{{ else }}
|
||||||
|
<ul class="flex flex-col gap-1 max-md:hidden">
|
||||||
{{- range $topLevelItems.ByWeight -}}
|
{{ template "sidebar-main" (dict "pages" $navPages "pageURL" $pageURL) }}
|
||||||
<!-- First level items and nested tree under -->
|
{{ template "sidebar-footer" }}
|
||||||
{{ template "sidebar-item" (dict "item" . "pageURL" $pageURL) }}
|
</ul>
|
||||||
{{ template "sidebar-tree" (dict "context" . "level" 1 "pageURL" $pageURL) }}
|
{{ end }}
|
||||||
{{ end }}
|
|
||||||
<!-- Sidebar footer -->
|
|
||||||
{{ template "sidebar-footer" }}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
{{ template "theme-switch" }}
|
{{/* Hide theme switch when sidebar is disabled */}}
|
||||||
|
{{ template "theme-switch" (dict "class" (cond $disableSidebar "md:hidden" "")) }}
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
{{- define "sidebar-main" -}}
|
||||||
|
{{ $pages := .pages }}
|
||||||
|
{{ $toc := .toc | default false }}
|
||||||
|
{{ $pageURL := .pageURL }}
|
||||||
|
|
||||||
|
{{- with $pages -}}
|
||||||
|
{{- range .ByWeight -}}
|
||||||
|
{{ template "sidebar-item" (dict "item" . "pageURL" $pageURL "toc" $toc) }}
|
||||||
|
{{ template "sidebar-tree" (dict "context" . "level" 1 "pageURL" $pageURL "toc" $toc) }}
|
||||||
|
{{- end -}}
|
||||||
|
{{ end }}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
{{- define "sidebar-footer" -}}
|
{{- define "sidebar-footer" -}}
|
||||||
{{- range site.Menus.sidebar -}}
|
{{- range site.Menus.sidebar -}}
|
||||||
{{ if eq .Params.type "separator" }}
|
{{ if eq .Params.type "separator" }}
|
||||||
@ -113,10 +125,14 @@
|
|||||||
{{- $active := eq .pageURL .item.RelPermalink -}}
|
{{- $active := eq .pageURL .item.RelPermalink -}}
|
||||||
{{- $title := .item.LinkTitle | default .item.File.BaseFileName -}}
|
{{- $title := .item.LinkTitle | default .item.File.BaseFileName -}}
|
||||||
{{- $link := .item.RelPermalink -}}
|
{{- $link := .item.RelPermalink -}}
|
||||||
|
{{- $toc := .toc | default false -}}
|
||||||
|
|
||||||
|
|
||||||
<li class="open">
|
<li class="open">
|
||||||
{{ template "sidebar-item-link" dict "active" $active "title" $title "link" $link }}
|
{{ template "sidebar-item-link" dict "active" $active "title" $title "link" $link }}
|
||||||
|
{{ if and $toc $active }}
|
||||||
|
{{ template "sidebar-toc" dict "page" .item }}
|
||||||
|
{{ end }}
|
||||||
</li>
|
</li>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
@ -136,20 +152,15 @@
|
|||||||
</a>
|
</a>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "sidebar-separator" -}}
|
||||||
|
<div class="mt-4 border-t py-4 dark:border-neutral-800 contrast-more:border-neutral-400 dark:contrast-more:border-neutral-400" />
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
{{- define "theme-switch" -}}
|
{{- define "theme-switch" -}}
|
||||||
<!-- theme switch button -->
|
{{- $class := .class -}}
|
||||||
<div class="sticky bottom-0 bg-white dark:bg-dark mx-4 py-4 shadow-[0_-12px_16px_#fff] flex items-center gap-2 dark:border-neutral-800 dark:shadow-[0_-12px_16px_#111] contrast-more:border-neutral-400 contrast-more:shadow-none contrast-more:dark:shadow-none border-t" data-toggle-animation="show">
|
<div class="{{ $class }} sticky bottom-0 bg-white dark:bg-dark mx-4 py-4 shadow-[0_-12px_16px_#fff] flex items-center gap-2 dark:border-neutral-800 dark:shadow-[0_-12px_16px_#111] contrast-more:border-neutral-400 contrast-more:shadow-none contrast-more:dark:shadow-none border-t" data-toggle-animation="show">
|
||||||
<div class="grow flex flex-col">
|
<div class="grow flex flex-col">
|
||||||
<button title="Change theme" class="h-7 rounded-md px-2 text-left text-xs font-medium text-gray-600 transition-colors dark:text-gray-400 hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-primary-100/5 dark:hover:text-gray-50" id="theme-toggle" type="button" aria-label="Toggle Dark Mode">
|
{{ partial "theme-toggle" }}
|
||||||
<div id="theme-toggle-light-icon" class="hidden flex items-center gap-2 capitalize">
|
|
||||||
{{- partial "utils/icon.html" (dict "name" "sun" "attributes" "height=12") -}}
|
|
||||||
<span>Light</span>
|
|
||||||
</div>
|
|
||||||
<div id="theme-toggle-dark-icon" class="hidden flex items-center gap-2 capitalize">
|
|
||||||
{{- partial "utils/icon.html" (dict "name" "moon" "attributes" "height=12") -}}
|
|
||||||
<span>Dark</span>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
8
layouts/partials/theme-toggle.html
Normal file
8
layouts/partials/theme-toggle.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<button title="Change theme" data-theme="light" class="theme-toggle group h-7 rounded-md px-2 text-left text-xs font-medium text-gray-600 transition-colors dark:text-gray-400 hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-primary-100/5 dark:hover:text-gray-50" type="button" aria-label="Toggle Dark Mode">
|
||||||
|
<div class="flex items-center gap-2 capitalize">
|
||||||
|
{{- partial "utils/icon.html" (dict "name" "sun" "attributes" "height=12 class=\"group-data-[theme=light]:hidden\"") -}}
|
||||||
|
<span class="group-data-[theme=light]:hidden">Light</span>
|
||||||
|
{{- partial "utils/icon.html" (dict "name" "moon" "attributes" "height=12 class=\"group-data-[theme=dark]:hidden\"") -}}
|
||||||
|
<span class="group-data-[theme=dark]:hidden">Dark</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
3
layouts/partials/utils/format-date.html
Normal file
3
layouts/partials/utils/format-date.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{{- with . -}}
|
||||||
|
{{- . | time.Format (site.Params.dateFormat | default ":date_long") -}}
|
||||||
|
{{- end -}}
|
11
layouts/partials/utils/page-description.html
Normal file
11
layouts/partials/utils/page-description.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{{ with .Description | plainify -}}
|
||||||
|
{{ . -}}
|
||||||
|
{{ else -}}
|
||||||
|
{{ if .IsPage -}}
|
||||||
|
{{ .Summary | plainify | chomp -}}
|
||||||
|
{{ else -}}
|
||||||
|
{{ with .Site.Params.description | plainify -}}
|
||||||
|
{{ . -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
Loading…
x
Reference in New Issue
Block a user