Compare commits

...

25 Commits

Author SHA1 Message Date
88b0f1b2ab fix: broken "edit this page" link in windows (#143) 2023-10-18 22:33:36 +01:00
a31b46f5e3 chore(i18n): add translations of Korean (#144)
* chore(i18n): add translations of Korean

* Update ko.yaml

---------

Co-authored-by: Xin <xin@imfing.com>
2023-10-18 22:32:28 +01:00
Sid
6641d36b98 docs: add using Hextra as Git submodule (#137)
* docs: update docs relating to getting started and Hugo modules

* docs: add docs to use Hextra as Git submodule, closes #107

* chore: use paragraph instead of callout, refactor docs

* Update getting-started.md

* Update getting-started.md

---------

Co-authored-by: Xin <xin@imfing.com>
2023-10-16 14:28:28 +01:00
e42d01898a fix: add missing translations (#142)
* fix: add missing translation in blog list

* fix: add translatable variables

* Update en.yaml

---------

Co-authored-by: Xin <xin@imfing.com>
2023-10-16 13:30:31 +01:00
Xin
6cd4c55613 fix: callout styling issue with markdown content (#141) 2023-10-13 00:09:57 +01:00
Xin
cb09b7ce1e fix: skip scroll event if no backToTop element (#138) 2023-10-12 23:25:34 +01:00
96c6ff073f chore(i18n): update zh-cn.yaml (#136) 2023-10-11 23:22:07 +01:00
Xin
28a20e1e7e chore: add code copy button icons in js (#133) 2023-10-07 20:01:19 +01:00
Xin
5f4c7423d0 chore: add feature request issue template
[skip ci]
2023-10-04 20:54:29 +01:00
Xin
2bc4ed19e3 chore: add issue bug report template
[skip ci]
2023-10-04 20:51:22 +01:00
Xin
8aa6439132 feat: support custom primary saturation (#131)
* feat: support custom primary saturation

* chore: run npm run build:css

* docs: update instruction for customizing primary color
2023-10-04 20:41:59 +01:00
b7558aca44 feat: support empty prev/next pagination (#130)
[skip ci]
2023-10-04 20:13:49 +01:00
Xin
55ff819dae fix: not-prose p tag inconsistent style (#126)
* fix: not-prose p tag should reset styles

* chore: compile CSS
2023-10-03 09:12:30 +01:00
Xin
924d8508d0 fix: footer enable flag logic issue (#125) 2023-10-03 08:51:41 +01:00
1b932f260a chore: add Vietnamese translation (#123)
[skip ci]
2023-10-03 08:36:35 +01:00
5768ed4695 chore: add Portuguese translation (#119) 2023-10-02 23:53:53 +01:00
f4cea168b1 chore: spanish translations es.yaml (#114)
[skip ci]
2023-10-02 11:57:12 +01:00
e2d00fdcd0 chore: add Swahili translation (#113)
[skip ci]
2023-10-01 23:13:18 +01:00
Xin
103faa24f3 chore: re-compile CSS 2023-10-01 09:25:02 +00:00
d1bed05843 feat: Back To Top (#105)
* Scroll to top

* Update scripts.html

---------

Co-authored-by: Xin <xin@imfing.com>
2023-10-01 10:06:28 +01:00
Xin
2df3c563bf fix: use div for copyright container in footer (#104) 2023-09-27 20:40:35 +01:00
Xin
ec02eb34fe fix: search shortcut based on user platform (#101)
* fix: search shortcut based on user platform

* chore: make it work with iPad and iPhone as well
2023-09-27 19:47:20 +01:00
Xin
46dea718e6 docs: add giscus comments system (#96)
* chore: rename comment to comments

* docs: add giscus comments

* docs: update
2023-09-26 23:33:27 +01:00
Xin
adf5a113fc fix: giscus theme and language display issues (#95)
* chore: minor update giscus template

* fix: theme toggle should select all

* chore: example configs for giscus

* fix: language code in giscus
2023-09-26 22:12:38 +01:00
6a19ac31c0 feat: add giscus support (#92)
* feat: add giscus support #89

* Update comment.html

* Update giscus.html

* Update giscus.html

---------

Co-authored-by: Xin <xin@imfing.com>
2023-09-26 20:47:22 +01:00
38 changed files with 577 additions and 102 deletions

40
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,40 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Description**
<!-- Provide a clear and concise description of the bug -->
**Steps To Reproduce**
1.
2.
3.
**Expected Behavior**
<!-- What should have happened? -->
**Actual Behavior**
<!-- What happened instead? -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem -->
**Environment**
- Hugo Version: [e.g., 0.85.0]
- Browser/OS: [e.g., Chrome, MacOS]
- Theme Version: [e.g., v2.0]
**Additional Context**
<!-- Add any other context about the problem here -->

View File

@ -0,0 +1,24 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Feature Description**
<!-- Provide a clear and concise description of the feature -->
**Problem/Solution**
<!-- What problem will this feature solve? Or what new capability will it add? -->
**Alternatives Considered**
<!-- Have you considered any alternative solutions or workarounds? -->
**Additional Context**
<!-- Add any other context or screenshots about the feature request here -->

View File

@ -697,6 +697,12 @@ video {
.h-2 {
height: 0.5rem;
}
.h-3 {
height: 0.75rem;
}
.h-3\.5 {
height: 0.875rem;
}
.h-4 {
height: 1rem;
}
@ -941,6 +947,10 @@ video {
--tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity));
}
.border-gray-500 {
--tw-border-opacity: 1;
border-color: rgb(107 114 128 / var(--tw-border-opacity));
}
.border-orange-100 {
--tw-border-opacity: 1;
border-color: rgb(255 237 213 / var(--tw-border-opacity));
@ -977,18 +987,18 @@ video {
}
.bg-primary-100 {
--tw-bg-opacity: 1;
background-color: hsl(var(--primary-hue) 100% 94% / var(--tw-bg-opacity));
background-color: hsl(var(--primary-hue) var(--primary-saturation) 94% / var(--tw-bg-opacity));
}
.bg-primary-400 {
--tw-bg-opacity: 1;
background-color: hsl(var(--primary-hue) 100% 66% / var(--tw-bg-opacity));
background-color: hsl(var(--primary-hue) var(--primary-saturation) 66% / var(--tw-bg-opacity));
}
.bg-primary-600 {
--tw-bg-opacity: 1;
background-color: hsl(var(--primary-hue) 100% 45% / var(--tw-bg-opacity));
background-color: hsl(var(--primary-hue) var(--primary-saturation) 45% / var(--tw-bg-opacity));
}
.bg-primary-700\/5 {
background-color: hsl(var(--primary-hue) 100% 39% / 0.05);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 39% / 0.05);
}
.bg-red-100 {
--tw-bg-opacity: 1;
@ -1251,7 +1261,7 @@ video {
}
.text-primary-800 {
--tw-text-opacity: 1;
color: hsl(var(--primary-hue) 100% 32% / var(--tw-text-opacity));
color: hsl(var(--primary-hue) var(--primary-saturation) 32% / var(--tw-text-opacity));
}
.text-red-900 {
--tw-text-opacity: 1;
@ -1370,6 +1380,9 @@ video {
.duration-200 {
transition-duration: 200ms;
}
.duration-75 {
transition-duration: 75ms;
}
.ease-in {
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
@ -1426,7 +1439,7 @@ video {
}
}
:is(html[class~="dark"] .content h2) {
border-color: hsl(var(--primary-hue) 100% 94% / 0.1);
border-color: hsl(var(--primary-hue) var(--primary-saturation) 94% / 0.1);
--tw-text-opacity: 1;
color: rgb(241 245 249 / var(--tw-text-opacity));
}
@ -1492,9 +1505,13 @@ video {
.content p:first-child {
margin-top: 0px;
}
.content .not-prose p {
margin-top: 0px;
line-height: 1.5;
}
.content a {
--tw-text-opacity: 1;
color: hsl(var(--primary-hue) 100% 45% / var(--tw-text-opacity));
color: hsl(var(--primary-hue) var(--primary-saturation) 45% / var(--tw-text-opacity));
text-decoration-line: underline;
text-decoration-thickness: from-font;
text-underline-position: from-font;
@ -1532,7 +1549,7 @@ video {
margin-bottom: 1rem;
overflow-x: auto;
border-radius: 0.75rem;
background-color: hsl(var(--primary-hue) 100% 39% / 0.05);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 39% / 0.05);
padding-top: 1rem;
padding-bottom: 1rem;
font-size: .9em;
@ -1544,18 +1561,18 @@ video {
.content pre:not(.code-block pre) {
border-width: 1px;
border-color: hsl(var(--primary-hue) 100% 24% / 0.2);
border-color: hsl(var(--primary-hue) var(--primary-saturation) 24% / 0.2);
--tw-contrast: contrast(1.5);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
}
:is(html[class~="dark"] .content pre:not(.code-block pre)) {
background-color: hsl(var(--primary-hue) 100% 77% / 0.1);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 77% / 0.1);
}
@media (prefers-contrast: more) {
:is(html[class~="dark"] .content pre:not(.code-block pre)) {
border-color: hsl(var(--primary-hue) 100% 94% / 0.4);
border-color: hsl(var(--primary-hue) var(--primary-saturation) 94% / 0.4);
}
}
.content code:not(.code-block code) {
@ -2151,7 +2168,7 @@ article details > summary::before {
}
.code-block pre {
overflow-x: auto;
background-color: hsl(var(--primary-hue) 100% 39% / 0.05);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 39% / 0.05);
font-size: .9em;
font-weight: 500;
-webkit-font-smoothing: auto;
@ -2161,18 +2178,18 @@ article details > summary::before {
.code-block pre {
border-width: 1px;
border-color: hsl(var(--primary-hue) 100% 24% / 0.2);
border-color: hsl(var(--primary-hue) var(--primary-saturation) 24% / 0.2);
--tw-contrast: contrast(1.5);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
}
:is(html[class~="dark"] .code-block pre) {
background-color: hsl(var(--primary-hue) 100% 77% / 0.1);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 77% / 0.1);
}
@media (prefers-contrast: more) {
:is(html[class~="dark"] .code-block pre) {
border-color: hsl(var(--primary-hue) 100% 94% / 0.4);
border-color: hsl(var(--primary-hue) var(--primary-saturation) 94% / 0.4);
}
}
.code-block .filename {
@ -2185,7 +2202,7 @@ article details > summary::before {
white-space: nowrap;
border-top-left-radius: 0.75rem;
border-top-right-radius: 0.75rem;
background-color: hsl(var(--primary-hue) 100% 39% / 0.05);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 39% / 0.05);
padding-top: 0.5rem;
padding-bottom: 0.5rem;
padding-left: 1rem;
@ -2195,7 +2212,7 @@ article details > summary::before {
color: rgb(55 65 81 / var(--tw-text-opacity));
}
:is(html[class~="dark"] .code-block .filename) {
background-color: hsl(var(--primary-hue) 100% 77% / 0.1);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 77% / 0.1);
--tw-text-opacity: 1;
color: rgb(229 231 235 / var(--tw-text-opacity));
}
@ -2248,7 +2265,7 @@ article details > summary::before {
.chroma .hl {
display: block;
width: 100%;
background-color: hsl(var(--primary-hue) 100% 32% / 0.1);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 32% / 0.1);
}
.hextra-cards {
grid-template-columns: repeat(auto-fill, minmax(max(250px, calc((100% - 1rem * 2) / var(--rows))), 1fr));
@ -2340,13 +2357,13 @@ article details > summary::before {
}
.search-wrapper li .active {
border-radius: 0.375rem;
background-color: hsl(var(--primary-hue) 100% 50% / 0.1);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 50% / 0.1);
}
@media (prefers-contrast: more) {
.search-wrapper li .active {
--tw-border-opacity: 1;
border-color: hsl(var(--primary-hue) 100% 50% / var(--tw-border-opacity));
border-color: hsl(var(--primary-hue) var(--primary-saturation) 50% / var(--tw-border-opacity));
}
}
.search-wrapper .no-result {
@ -2433,7 +2450,7 @@ article details > summary::before {
}
.search-wrapper .match {
--tw-text-opacity: 1;
color: hsl(var(--primary-hue) 100% 45% / var(--tw-text-opacity));
color: hsl(var(--primary-hue) var(--primary-saturation) 45% / var(--tw-text-opacity));
}
@media (max-width: 767px) {
.sidebar-container {
@ -2572,11 +2589,13 @@ body {
}
:root {
--primary-hue: 212deg;
--primary-saturation: 100%;
--navbar-height: 4rem;
--menu-height: 3.75rem;
}
.dark {
--primary-hue: 204deg;
--primary-saturation: 100%;
}
.placeholder\:text-gray-500::-moz-placeholder {
--tw-text-opacity: 1;
@ -2660,6 +2679,10 @@ body {
--tw-border-opacity: 1;
border-color: rgb(156 163 175 / var(--tw-border-opacity));
}
.hover\:border-gray-900:hover {
--tw-border-opacity: 1;
border-color: rgb(17 24 39 / var(--tw-border-opacity));
}
.hover\:bg-gray-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
@ -2669,11 +2692,11 @@ body {
}
.hover\:bg-primary-50:hover {
--tw-bg-opacity: 1;
background-color: hsl(var(--primary-hue) 100% 97% / var(--tw-bg-opacity));
background-color: hsl(var(--primary-hue) var(--primary-saturation) 97% / var(--tw-bg-opacity));
}
.hover\:bg-primary-700:hover {
--tw-bg-opacity: 1;
background-color: hsl(var(--primary-hue) 100% 39% / var(--tw-bg-opacity));
background-color: hsl(var(--primary-hue) var(--primary-saturation) 39% / var(--tw-bg-opacity));
}
.hover\:bg-slate-50:hover {
--tw-bg-opacity: 1;
@ -2693,7 +2716,7 @@ body {
}
.hover\:text-primary-600:hover {
--tw-text-opacity: 1;
color: hsl(var(--primary-hue) 100% 45% / var(--tw-text-opacity));
color: hsl(var(--primary-hue) var(--primary-saturation) 45% / var(--tw-text-opacity));
}
.hover\:opacity-60:hover {
opacity: 0.6;
@ -2730,7 +2753,7 @@ body {
}
.focus\:ring-primary-300:focus {
--tw-ring-opacity: 1;
--tw-ring-color: hsl(var(--primary-hue) 100% 77% / var(--tw-ring-opacity));
--tw-ring-color: hsl(var(--primary-hue) var(--primary-saturation) 77% / var(--tw-ring-opacity));
}
.active\:bg-gray-400\/20:active {
background-color: rgb(156 163 175 / 0.2);
@ -2772,11 +2795,11 @@ body {
}
.data-\[state\=selected\]\:border-primary-500[data-state=selected] {
--tw-border-opacity: 1;
border-color: hsl(var(--primary-hue) 100% 50% / var(--tw-border-opacity));
border-color: hsl(var(--primary-hue) var(--primary-saturation) 50% / var(--tw-border-opacity));
}
.data-\[state\=selected\]\:text-primary-600[data-state=selected] {
--tw-text-opacity: 1;
color: hsl(var(--primary-hue) 100% 45% / var(--tw-text-opacity));
color: hsl(var(--primary-hue) var(--primary-saturation) 45% / var(--tw-text-opacity));
}
.group[data-theme=dark] .group-data-\[theme\=dark\]\:hidden {
display: none;
@ -2918,6 +2941,11 @@ body {
border-color: currentColor;
}
.contrast-more\:border-gray-800 {
--tw-border-opacity: 1;
border-color: rgb(31 41 55 / var(--tw-border-opacity));
}
.contrast-more\:border-gray-900 {
--tw-border-opacity: 1;
border-color: rgb(17 24 39 / var(--tw-border-opacity));
@ -2930,7 +2958,7 @@ body {
.contrast-more\:border-primary-500 {
--tw-border-opacity: 1;
border-color: hsl(var(--primary-hue) 100% 50% / var(--tw-border-opacity));
border-color: hsl(var(--primary-hue) var(--primary-saturation) 50% / var(--tw-border-opacity));
}
.contrast-more\:border-transparent {
@ -2993,6 +3021,10 @@ body {
:is(html[class~="dark"] .dark\:border-gray-100\/20) {
border-color: rgb(243 244 246 / 0.2);
}
:is(html[class~="dark"] .dark\:border-gray-400) {
--tw-border-opacity: 1;
border-color: rgb(156 163 175 / var(--tw-border-opacity));
}
:is(html[class~="dark"] .dark\:border-neutral-700) {
--tw-border-opacity: 1;
border-color: rgb(64 64 64 / var(--tw-border-opacity));
@ -3038,14 +3070,14 @@ body {
background-color: rgb(251 146 60 / 0.2);
}
:is(html[class~="dark"] .dark\:bg-primary-300\/10) {
background-color: hsl(var(--primary-hue) 100% 77% / 0.1);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 77% / 0.1);
}
:is(html[class~="dark"] .dark\:bg-primary-400\/10) {
background-color: hsl(var(--primary-hue) 100% 66% / 0.1);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 66% / 0.1);
}
:is(html[class~="dark"] .dark\:bg-primary-600) {
--tw-bg-opacity: 1;
background-color: hsl(var(--primary-hue) 100% 45% / var(--tw-bg-opacity));
background-color: hsl(var(--primary-hue) var(--primary-saturation) 45% / var(--tw-bg-opacity));
}
:is(html[class~="dark"] .dark\:bg-red-900\/30) {
background-color: rgb(127 29 29 / 0.3);
@ -3099,7 +3131,7 @@ body {
}
:is(html[class~="dark"] .dark\:text-primary-600) {
--tw-text-opacity: 1;
color: hsl(var(--primary-hue) 100% 45% / var(--tw-text-opacity));
color: hsl(var(--primary-hue) var(--primary-saturation) 45% / var(--tw-text-opacity));
}
:is(html[class~="dark"] .dark\:text-red-200) {
--tw-text-opacity: 1;
@ -3152,6 +3184,10 @@ body {
--tw-invert: invert(100%);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
:is(html[class~="dark"] .dark\:hover\:border-gray-100:hover) {
--tw-border-opacity: 1;
border-color: rgb(243 244 246 / var(--tw-border-opacity));
}
:is(html[class~="dark"] .dark\:hover\:border-gray-600:hover) {
--tw-border-opacity: 1;
border-color: rgb(75 85 99 / var(--tw-border-opacity));
@ -3184,14 +3220,14 @@ body {
background-color: rgb(23 23 23 / var(--tw-bg-opacity));
}
:is(html[class~="dark"] .dark\:hover\:bg-primary-100\/5:hover) {
background-color: hsl(var(--primary-hue) 100% 94% / 0.05);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 94% / 0.05);
}
:is(html[class~="dark"] .dark\:hover\:bg-primary-700:hover) {
--tw-bg-opacity: 1;
background-color: hsl(var(--primary-hue) 100% 39% / var(--tw-bg-opacity));
background-color: hsl(var(--primary-hue) var(--primary-saturation) 39% / var(--tw-bg-opacity));
}
:is(html[class~="dark"] .hover\:dark\:bg-primary-500\/10):hover {
background-color: hsl(var(--primary-hue) 100% 50% / 0.1);
background-color: hsl(var(--primary-hue) var(--primary-saturation) 50% / 0.1);
}
:is(html[class~="dark"] .dark\:hover\:text-gray-100:hover) {
--tw-text-opacity: 1;
@ -3219,7 +3255,7 @@ body {
}
:is(html[class~="dark"] .hover\:dark\:text-primary-600):hover {
--tw-text-opacity: 1;
color: hsl(var(--primary-hue) 100% 45% / var(--tw-text-opacity));
color: hsl(var(--primary-hue) var(--primary-saturation) 45% / var(--tw-text-opacity));
}
:is(html[class~="dark"] .dark\:hover\:shadow-none:hover) {
--tw-shadow: 0 0 #0000;
@ -3232,7 +3268,7 @@ body {
}
:is(html[class~="dark"] .dark\:focus\:ring-primary-800:focus) {
--tw-ring-opacity: 1;
--tw-ring-color: hsl(var(--primary-hue) 100% 32% / var(--tw-ring-opacity));
--tw-ring-color: hsl(var(--primary-hue) var(--primary-saturation) 32% / var(--tw-ring-opacity));
}
@media (prefers-contrast: more) {
@ -3252,7 +3288,7 @@ body {
:is(html[class~="dark"] .contrast-more\:dark\:border-primary-500) {
--tw-border-opacity: 1;
border-color: hsl(var(--primary-hue) 100% 50% / var(--tw-border-opacity));
border-color: hsl(var(--primary-hue) var(--primary-saturation) 50% / var(--tw-border-opacity));
}
:is(html[class~="dark"] .dark\:contrast-more\:border-neutral-400) {

View File

@ -21,10 +21,12 @@ body {
:root {
--primary-hue: 212deg;
--primary-saturation: 100%;
--navbar-height: 4rem;
--menu-height: 3.75rem;
}
.dark {
--primary-hue: 204deg;
--primary-saturation: 100%;
}

View File

@ -20,6 +20,9 @@
p {
@apply mt-6 leading-7 first:mt-0;
}
.not-prose p {
@apply mt-0 leading-normal;
}
a {
@apply text-primary-600 underline decoration-from-font [text-underline-position:from-font];
}

22
assets/js/back-to-top.js Normal file
View File

@ -0,0 +1,22 @@
// Back to top button
document.addEventListener("DOMContentLoaded", function () {
const backToTop = document.querySelector("#backToTop");
if (backToTop) {
document.addEventListener("scroll", (e) => {
if (window.scrollY > 300) {
backToTop.classList.remove("opacity-0");
} else {
backToTop.classList.add("opacity-0");
}
});
}
});
function scrollUp() {
window.scroll({
top: 0,
left: 0,
behavior: "smooth",
});
}

View File

@ -1,30 +1,63 @@
document.querySelectorAll('.code-copy-btn').forEach(function (button) {
button.addEventListener('click', function (e) {
e.preventDefault();
const targetId = button.getAttribute('data-clipboard-target');
const target = document.querySelector(targetId);
let codeElement;
if (target.tagName === 'CODE') {
codeElement = target;
} else {
// Select the last code element in case line numbers are present
const codeElements = target.querySelectorAll('code');
codeElement = codeElements[codeElements.length - 1];
}
if (codeElement) {
// Replace double newlines with single newlines in the innerText
// as each line inside <span> has trailing newline '\n'
const code = codeElement.innerText.replace(/\n\n/g, '\n');
navigator.clipboard.writeText(code).then(function () {
button.classList.add('copied');
setTimeout(function () {
button.classList.remove('copied');
}, 500);
}).catch(function (err) {
console.error('Failed to copy text: ', err);
});
} else {
console.error('Target element not found');
}
// Copy button for code blocks
document.addEventListener('DOMContentLoaded', function () {
const getCopyIcon = () => {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.innerHTML = `
<path stroke-linecap="round" stroke-linejoin="round" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
`;
svg.setAttribute('fill', 'none');
svg.setAttribute('viewBox', '0 0 24 24');
svg.setAttribute('stroke', 'currentColor');
svg.setAttribute('stroke-width', '2');
return svg;
}
const getSuccessIcon = () => {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.innerHTML = `
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
`;
svg.setAttribute('fill', 'none');
svg.setAttribute('viewBox', '0 0 24 24');
svg.setAttribute('stroke', 'currentColor');
svg.setAttribute('stroke-width', '2');
return svg;
}
document.querySelectorAll('.code-copy-btn').forEach(function (button) {
// Add copy and success icons
button.querySelector('.copy-icon')?.appendChild(getCopyIcon());
button.querySelector('.success-icon')?.appendChild(getSuccessIcon());
// Add click event listener for copy button
button.addEventListener('click', function (e) {
e.preventDefault();
const targetId = button.getAttribute('data-clipboard-target');
const target = document.querySelector(targetId);
let codeElement;
if (target.tagName === 'CODE') {
codeElement = target;
} else {
// Select the last code element in case line numbers are present
const codeElements = target.querySelectorAll('code');
codeElement = codeElements[codeElements.length - 1];
}
if (codeElement) {
// Replace double newlines with single newlines in the innerText
// as each line inside <span> has trailing newline '\n'
const code = codeElement.innerText.replace(/\n\n/g, '\n');
navigator.clipboard.writeText(code).then(function () {
button.classList.add('copied');
setTimeout(function () {
button.classList.remove('copied');
}, 500);
}).catch(function (err) {
console.error('Failed to copy text: ', err);
});
} else {
console.error('Target element not found');
}
});
});
});

View File

@ -1,5 +1,16 @@
// Search functionality using FlexSearch.
// Change shortcut key to cmd+k on Mac, iPad or iPhone.
document.addEventListener("DOMContentLoaded", function () {
if (/iPad|iPhone|Macintosh/.test(navigator.userAgent)) {
// select the kbd element under the .search-wrapper class
const keys = document.querySelectorAll(".search-wrapper kbd");
keys.forEach(key => {
key.innerHTML = '<span class="text-xs">⌘</span>K';
});
}
});
// Render the search data as JSON.
// {{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }}
// {{ $searchData := resources.Get "json/search-data.json" | resources.ExecuteAsTemplate $searchDataFile . }}

View File

@ -12,4 +12,5 @@ This section covers some advanced topics of the theme.
{{< cards >}}
{{< card link="multi-language" title="Multi-language" icon="translate" >}}
{{< card link="customization" title="Customization" icon="pencil" >}}
{{< card link="comments" title="Comments System" icon="chat-alt" >}}
{{< /cards >}}

View File

@ -0,0 +1,39 @@
---
title: Comments System
linkTitle: Comments
---
Hextra supports adding comments system to your site.
Currently [giscus](https://giscus.app/) is supported.
<!--more-->
## giscus
[giscus](https://giscus.app/) is a comments system powered by [GitHub Discussions](https://docs.github.com/en/discussions). It is free and open source.
To enable giscus, you need to add the following to the site configuration file:
```yaml {filename="hugo.yaml"}
params:
comments:
enable: false
type: giscus
giscus:
repo: <repository>
repoId: <repository ID>
category: <category>
categoryId: <category ID>
```
The giscus configurations can be constructed from the [giscus.app](https://giscus.app/) website. More details can also be found there.
Comments can be enabled or disabled for a specific page in the page front matter:
```yaml {filename="content/docs/about.md"}
---
title: About
comments: true
---
```

View File

@ -34,11 +34,12 @@ The color of text mixed with `other text` can customized with:
### Primary Color
The primary color of the theme can be customized by setting the `--primary-hue` variable:
The primary color of the theme can be customized by setting the `--primary-hue` and `--primary-saturation` variables:
```css {filename="assets/css/custom.css"}
:root {
--primary-hue: 100deg;
--primary-saturation: 90%;
}
```

View File

@ -19,18 +19,29 @@ We have provided a [GitHub Actions workflow](https://docs.github.com/en/pages/ge
## Start as New Project
### Prerequisites
There are two main ways to add the Hextra theme to your Hugo project.
Before we start, make sure we have [Hugo](https://gohugo.io/) installed.
Please refer to Hugo's [official installation guide](https://gohugo.io/installation/) for more details.
1. **Hugo Modules (Recommended)**: The simplest and recommended method. [Hugo modules](https://gohugo.io/hugo-modules/) let you pull in the theme directly from its online source. Theme is downloaded automatically and managed by Hugo.
[Hugo modules](https://gohugo.io/hugo-modules/) are the recommended way to manage Hugo themes. To use Hugo modules, we need to install [Git](https://git-scm.com/) and [Go](https://go.dev/).
2. **Git Submodule**: Alternatively, add Hextra as a [Git Submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules). The theme will be downloaded by Git and stored in your project's `themes` folder.
### Setup Hextra as Hugo module
#### Prerequisites
Before starting, you need to have the following softwares installed:
- [Hugo (extended version)](https://gohugo.io/installation/)
- [Git](https://git-scm.com/)
- [Go](https://go.dev/)
#### Steps
{{% steps %}}
### Initialize a new Hugo site
```bash
```shell
$ hugo new site my-site --format=yaml
```
@ -45,7 +56,7 @@ $ hugo mod init github.com/username/my-site
$ hugo mod get github.com/imfing/hextra
```
Edit `hugo.yaml` to enable Hextra theme:
Configure `hugo.yaml` to use Hextra theme by adding the following:
```yaml
module:
@ -55,7 +66,7 @@ module:
### Create your first content pages
Let's create a new content page for the home page and the documentation page:
Let's create new content page for the home page and the documentation page:
```shell
$ hugo new content/_index.md
@ -73,20 +84,101 @@ Voila! You can see your new site at `http://localhost:1313/`.
{{% /steps %}}
## Update Theme
{{% details title="How to update theme?" %}}
To update the theme to the [latest released version](https://github.com/imfing/hextra/releases), run the following command:
To update all Hugo modules in your project to their latest versions, run the following command:
```shell
$ hugo mod get -u
```
To update only Hextra to the [latest released version](https://github.com/imfing/hextra/releases), run the following command:
```shell
hugo mod get -u github.com/imfing/hextra
```
See [Hugo Modules](https://gohugo.io/hugo-modules/use-modules/#update-all-modules) for more details.
{{% /details %}}
### Setup Hextra as Git submodule
#### Prerequisites
Before starting, you need to have the following softwares installed:
- [Hugo (extended version)](https://gohugo.io/installation/)
- [Git](https://git-scm.com/)
#### Steps
{{% steps %}}
### Initialize a new Hugo site
```shell
$ hugo new site my-site --format=yaml
```
### Add Hextra theme as a Git submodule
```shell
git submodule add https://github.com/imfing/hextra.git themes/hextra
```
Configure `hugo.yaml` to use Hextra theme by adding the following:
```yaml
theme: hextra
```
### Create your first content pages
Let's create new content page for the home page and the documentation page:
```shell
$ hugo new content/_index.md
$ hugo new content/docs/_index.md
```
### Preview the site locally
```shell
$ hugo server --buildDrafts --disableFastRender
```
Voila! You can see your new site at `http://localhost:1313/`.
{{% /steps %}}
When using [CI/CD](https://en.wikipedia.org/wiki/CI/CD) for Hugo website deployment, it's essential to ensure that the following command is executed before running the `hugo` command.
```shell
git submodule update --init
```
Failure to run this command will result in the theme folder not being populated with Hextra theme files, leading to a build failure.
{{% details title="How to update theme?" %}}
To update all submodules in your repository to their latest commits, run the following command:
```shell
$ git submodule update --remote
```
To update only Hextra to the latest commit, run the following command:
```shell
git submodule update --remote themes/hextra
```
See [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) for more details.
{{% /details %}}
## Next

View File

@ -26,6 +26,7 @@ languages:
title: "Hextra テーマ"
zh-cn:
languageName: 简体中文
languageCode: zh-CN
weight: 3
title: Hextra
@ -122,3 +123,20 @@ params:
editURL:
enable: true
base: "https://github.com/imfing/hextra/edit/main/exampleSite/content"
comments:
enable: false
type: giscus
# https://giscus.app/
giscus:
repo: imfing/hextra
repoId: R_kgDOJ9fJag
category: General
categoryId: DIC_kwDOJ9fJas4CY7gW
# mapping: pathname
# strict: 0
# reactionsEnabled: 1
# emitMetadata: 0
# inputPosition: top
# lang: en

View File

@ -112,6 +112,7 @@
"border-black/5",
"border-blue-200",
"border-gray-200",
"border-gray-500",
"border-l",
"border-orange-100",
"border-red-200",
@ -127,6 +128,7 @@
"content",
"contrast-more:border",
"contrast-more:border-current",
"contrast-more:border-gray-800",
"contrast-more:border-gray-900",
"contrast-more:border-neutral-400",
"contrast-more:border-primary-500",
@ -152,6 +154,7 @@
"contrast-more:text-gray-800",
"contrast-more:text-gray-900",
"contrast-more:underline",
"copy-icon",
"cursor-default",
"cursor-pointer",
"dark:before:bg-neutral-800",
@ -171,6 +174,7 @@
"dark:block",
"dark:border-blue-200/30",
"dark:border-gray-100/20",
"dark:border-gray-400",
"dark:border-neutral-700",
"dark:border-neutral-800",
"dark:border-orange-400/30",
@ -188,6 +192,7 @@
"dark:hover:bg-neutral-900",
"dark:hover:bg-primary-100/5",
"dark:hover:bg-primary-700",
"dark:hover:border-gray-100",
"dark:hover:border-gray-600",
"dark:hover:border-neutral-500",
"dark:hover:border-neutral-700",
@ -226,6 +231,7 @@
"data-[state=selected]:text-primary-600",
"decoration-from-font",
"duration-200",
"duration-75",
"ease-in",
"ease-in-out",
"filename",
@ -264,6 +270,7 @@
"h-0",
"h-16",
"h-2",
"h-3.5",
"h-4",
"h-5",
"h-7",
@ -289,6 +296,7 @@
"hover:border-gray-200",
"hover:border-gray-300",
"hover:border-gray-400",
"hover:border-gray-900",
"hover:dark:bg-primary-500/10",
"hover:dark:text-primary-600",
"hover:opacity-60",

View File

@ -1,5 +1,9 @@
onThisPage: "On this page"
backToTop: "Scroll to top"
changeLanguage: "Change language"
changeTheme: "Change theme"
copyright: "© 2023 Hextra Project."
editThisPage: "Edit this page on GitHub →"
lastUpdated: "Last updated on"
copyright: "© 2023 Hextra Project."
onThisPage: "On this page"
readMore: "Read more →"
searchPlaceholder: "Search..."

7
i18n/es.yaml Normal file
View File

@ -0,0 +1,7 @@
onThisPage: "En esta página"
editThisPage: "Edita esta página en GitHub →"
lastUpdated: "Última actualización"
backToTop: "Subir al inicio"
copyright: "© 2023 Hextra Project."

9
i18n/ko.yaml Normal file
View File

@ -0,0 +1,9 @@
backToTop: "맨위로 스크롤"
changeLanguage: "언어변경"
changeTheme: "테마변경"
copyright: "© 2023 Hextra Project."
editThisPage: "Github에서 편집하기 →"
lastUpdated: "마지막 수정일자"
onThisPage: "페이지 목차"
readMore: "더보기 →"
searchPlaceholder: "검색..."

7
i18n/pt.yaml Normal file
View File

@ -0,0 +1,7 @@
onThisPage: "Nesta página"
editThisPage: "Edita esta página no GitHub →"
lastUpdated: "Última actualização"
backToTop: "Voltar ao topo"
copyright: "© 2023 Projecto Hextra."

5
i18n/sw.yaml Normal file
View File

@ -0,0 +1,5 @@
onThisPage: "Kwenye ukurasa huu"
editThisPage: "Hariri ukurasa huu kwenye GitHub →"
lastUpdated: "Ilisasishwa mwisho"
backToTop: "Tembeza hadi juu"
copyright: "© 2023 Hextra Project."

7
i18n/vi.yaml Normal file
View File

@ -0,0 +1,7 @@
onThisPage: "Ở trang này"
editThisPage: "Sửa trang này trên GitHub →"
lastUpdated: "Lần cuối cập nhật lúc"
backToTop: "Lướt lên đầu trang"
copyright: "© 2023 Hextra Project."

View File

@ -12,4 +12,6 @@ onThisPage: "此页上"
editThisPage: "在 GitHub 上编辑此页 →"
lastUpdated: "最后更新于"
backToTop: "返回顶部"
copyright: "© 2023 Hextra Project."

View File

@ -15,9 +15,13 @@
<pre><code id="code-block-{{ .Ordinal }}">{{ .Inner }}</code></pre>
{{- end -}}
<div class="opacity-0 transition group-hover/code:opacity-100 flex gap-1 absolute m-[11px] right-0 {{ if $filename }}top-8{{ else }}top-0{{ end }}">
<button class="code-copy-btn group/copybtn transition-all active:opacity-50 bg-primary-700/5 border border-black/5 text-gray-600 hover:text-gray-900 rounded-md p-1.5 dark:bg-primary-300/10 dark:border-white/10 dark:text-gray-400 dark:hover:text-gray-50" title="Copy code" data-clipboard-target="#code-block-{{ .Ordinal }}">
{{ partial "utils/icon.html" (dict "name" "copy" "attributes" "class=\"group-[.copied]/copybtn:hidden pointer-events-none h-4 w-4\"") }}
{{ partial "utils/icon.html" (dict "name" "check" "attributes" "class=\"hidden group-[.copied]/copybtn:block success-icon pointer-events-none h-4 w-4\"") }}
<button
class="code-copy-btn group/copybtn transition-all active:opacity-50 bg-primary-700/5 border border-black/5 text-gray-600 hover:text-gray-900 rounded-md p-1.5 dark:bg-primary-300/10 dark:border-white/10 dark:text-gray-400 dark:hover:text-gray-50"
title="Copy code"
data-clipboard-target="#code-block-{{ .Ordinal }}"
>
<div class="group-[.copied]/copybtn:hidden copy-icon pointer-events-none h-4 w-4"></div>
<div class="hidden group-[.copied]/copybtn:block success-icon pointer-events-none h-4 w-4"></div>
</button>
</div>
</div>

View File

@ -4,7 +4,9 @@
<body dir="ltr">
{{- partial "navbar.html" . -}}
{{- block "main" . }}{{ end -}}
{{- if (.Site.Params.footer.enable | default true) }}{{ partial "footer.html" . }}{{ end }}
{{- if or (eq .Site.Params.footer.enable nil) (.Site.Params.footer.enable) }}
{{ partial "footer.html" . }}
{{ end }}
</body>
{{ partial "scripts.html" . }}
</html>

View File

@ -10,6 +10,7 @@
</div>
<div class="mt-16"></div>
{{ partial "components/last-updated.html" . }}
{{ partial "components/comments.html" . }}
</main>
</article>
</div>

View File

@ -10,6 +10,8 @@
<div class="content">
{{ .Content }}
</div>
<div class="mt-16"></div>
{{ partial "components/comments.html" . }}
</main>
</article>
</div>

View File

@ -1,4 +1,5 @@
{{ define "main" }}
{{- $readMore := (T "readMore") | default "Read more →" -}}
<div class='mx-auto flex {{ partial "utils/page-width" . }}'>
{{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }}
<article class="w-full break-words flex min-h-[calc(100vh-var(--navbar-height))] min-w-0 justify-center pb-8 pr-[calc(env(safe-area-inset-right)-1.5rem)]">
@ -11,7 +12,7 @@
<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>
<span class="inline-block"> <a class="text-[color:hsl(var(--primary-hue),100%,50%)] underline underline-offset-2 decoration-from-font" href="{{ .RelPermalink }}">{{ $readMore }}</a> </span>
</p>
<p class="opacity-50 text-sm mt-6 leading-7">{{ partial "utils/format-date" .Date }}</p>
</div>

View File

@ -28,6 +28,7 @@
{{ partial "components/last-updated.html" . }}
{{ .Scratch.Set "reversePagination" true }}
{{ partial "components/pager.html" . }}
{{ partial "components/comments.html" . }}
</main>
</article>
</div>

View File

@ -9,9 +9,9 @@
<h1>{{ .Title }}</h1>
{{ .Content }}
</div>
<div class="mt-16"></div>
{{ partial "components/last-updated.html" . }}
{{ partial "components/pager.html" . }}
{{ partial "components/comments.html" . }}
</main>
</article>
</div>

View File

@ -11,6 +11,7 @@
</div>
{{ partial "components/last-updated.html" . }}
{{ partial "components/pager.html" . }}
{{ partial "components/comments.html" . }}
</main>
</article>
</div>

View File

@ -0,0 +1,11 @@
{{- $enableComments := site.Params.comments.enable | default false -}}
{{ if not (eq .Params.comments nil) }}
{{ $enableComments = .Params.comments }}
{{ end }}
{{- if $enableComments -}}
{{- if eq site.Params.comments.type "giscus" -}}
{{ partial "components/giscus.html" . }}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,62 @@
{{- $lang := site.Language.LanguageCode | default `en` -}}
{{- with site.Params.comments.giscus -}}
<script>
/*
* "preferred color scheme" theme in giscus works using "prefers-color-scheme" in media query.
* but, hugo's theme switch function works by using "color-theme" in local storage.
* This solution was created with reference to:
* https://github.com/giscus/giscus/issues/336#issuecomment-1214366281
*/
function getGiscusTheme() {
return localStorage.getItem("color-theme");
}
function setGiscusTheme() {
function sendMessage(message) {
const iframe = document.querySelector('iframe.giscus-frame');
if (!iframe) return;
iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
}
sendMessage({
setConfig: {
theme: getGiscusTheme(),
},
});
}
document.addEventListener('DOMContentLoaded', function () {
const giscusAttributes = {
"src": "https://giscus.app/client.js",
"data-repo": "{{ .repo }}",
"data-repo-id": "{{ .repoId }}",
"data-category": "{{ .category }}",
"data-category-id": "{{ .categoryId }}",
"data-mapping": "{{ .mapping | default `pathname` }}",
"data-strict": "{{ (string .strict) | default 0 }}",
"data-reactions-enabled": "{{ (string .reactionsEnabled) | default 1 }}",
"data-emit-metadata": "{{ (string .emitMetadata) | default 0 }}",
"data-input-position": "{{ .inputPosition | default `top` }}",
"data-theme": getGiscusTheme(),
"data-lang": "{{ .lang | default $lang }}",
"crossorigin": "anonymous",
"async": "",
};
// Dynamically create script tag
const giscusScript = document.createElement("script");
Object.entries(giscusAttributes).forEach(([key, value]) => giscusScript.setAttribute(key, value));
document.getElementById('giscus').appendChild(giscusScript);
// Update giscus theme when theme switcher is clicked
const toggles = document.querySelectorAll(".theme-toggle");
if (toggles) {
toggles.forEach(toggle => toggle.addEventListener('click', setGiscusTheme));
}
});
</script>
<div id="giscus"></div>
{{- else -}}
{{ warnf "giscus is not configured" }}
{{- end -}}

View File

@ -5,15 +5,23 @@
{{- $prev := cond $reversePagination .PrevInSection .NextInSection -}}
{{- $next := cond $reversePagination .NextInSection .PrevInSection -}}
{{- with .Params.prev -}}
{{- with $.Site.GetPage . -}}
{{- if $reversePagination }}{{ $next = . }}{{ else }}{{ $prev = . }}{{ end -}}
{{- if eq .Params.prev false }}
{{- if $reversePagination }}{{ $next = false }}{{ else }}{{ $prev = false }}{{ end -}}
{{ else }}
{{- with .Params.prev -}}
{{- with $.Site.GetPage . -}}
{{- if $reversePagination }}{{ $next = . }}{{ else }}{{ $prev = . }}{{ end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- with .Params.next -}}
{{- with $.Site.GetPage . -}}
{{- if $reversePagination }}{{ $prev = . }}{{ else }}{{ $next = . }}{{ end -}}
{{- if eq .Params.next false }}
{{- if $reversePagination }}{{ $prev = false }}{{ else }}{{ $next = false }}{{ end -}}
{{ else }}
{{- with .Params.next -}}
{{- with $.Site.GetPage . -}}
{{- if $reversePagination }}{{ $prev = . }}{{ else }}{{ $next = . }}{{ end -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -24,7 +24,7 @@
>
<div class="flex w-full flex-col items-center sm:items-start">
{{- if (.Site.Params.footer.displayPoweredBy | default true) }}<div class="font-semibold">{{ template "theme-credit" . }}</div>{{ end }}
{{- if .Site.Params.footer.displayCopyright }}<p class="mt-6 text-xs">{{ $copyright | markdownify }}</p>{{ end }}
{{- if .Site.Params.footer.displayCopyright }}<div class="mt-6 text-xs">{{ $copyright | markdownify }}</div>{{ end }}
</div>
</div>
</footer>

View File

@ -5,8 +5,9 @@
{{- $jsCodeCopy := resources.Get "js/code-copy.js" -}}
{{- $jsFileTree := resources.Get "js/filetree.js" -}}
{{- $jsSidebar := resources.Get "js/sidebar.js" -}}
{{- $jsBackToTop := resources.Get "js/back-to-top.js" -}}
{{- $scripts := slice $jsTheme $jsMenu $jsCodeCopy $jsTabs $jsLang $jsFileTree $jsSidebar | resources.Concat "js/main.js" -}}
{{- $scripts := slice $jsTheme $jsMenu $jsCodeCopy $jsTabs $jsLang $jsFileTree $jsSidebar $jsBackToTop | resources.Concat "js/main.js" -}}
{{- if hugo.IsProduction -}}
{{- $scripts = $scripts | minify | fingerprint -}}
{{- end -}}

View File

@ -13,7 +13,7 @@
<kbd
class="absolute my-1.5 select-none ltr:right-1.5 rtl:left-1.5 h-5 rounded bg-white px-1.5 font-mono text-[10px] font-medium text-gray-500 border dark:border-gray-100/20 dark:bg-dark/50 contrast-more:border-current contrast-more:text-current contrast-more:dark:border-current items-center gap-1 transition-opacity pointer-events-none hidden sm:flex"
>
<span class="text-xs"></span>K
CTRL K
</kbd>
</div>

View File

@ -3,6 +3,7 @@
{{- $toc := .Params.toc | default true -}}
{{- $onThisPage := (T "onThisPage") | default "On this page"}}
{{- $editThisPage := (T "editThisPage") | default "Edit this page"}}
{{- $backToTop := (T "backToTop") | default "Scroll to top" -}}
<nav class="hextra-toc order-last hidden w-64 shrink-0 xl:block print:hidden px-4" aria-label="table of contents">
{{- if $toc }}
@ -25,10 +26,19 @@
<div class="{{ $borderClass }} sticky bottom-0 flex flex-col items-start gap-2 pb-8 dark:border-neutral-800 contrast-more:border-t contrast-more:border-neutral-400 contrast-more:shadow-none contrast-more:dark:border-neutral-400">
{{- if site.Params.editURL.enable -}}
{{- $editURL := site.Params.editURL.base | default "" -}}
{{- with .File -}}{{ $editURL = urls.JoinPath $editURL .Path }}{{- end -}}
{{- with .File -}}{{ $editURL = urls.JoinPath $editURL (replace .Path "\\" "/") }}{{- end -}}
{{- with .Params.editURL -}}{{ $editURL = .Params.editURL }}{{- end -}}
<a class="text-xs font-medium text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100 contrast-more:text-gray-800 contrast-more:dark:text-gray-50" href="{{ $editURL }}" target="_blank" rel="noreferer">{{ $editThisPage }}</a>
{{- end -}}
{{/* Scroll To Top */}}
<button aria-hidden="true" id="backToTop" onClick="scrollUp();" class="transition-all transition duration-75 opacity-0 text-xs font-medium text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100 contrast-more:text-gray-800 contrast-more:dark:text-gray-50">
<span>
{{- $backToTop -}}
</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="inline ml-1 h-3.5 w-3.5 border rounded-full border-gray-500 hover:border-gray-900 dark:border-gray-400 dark:hover:border-gray-100 contrast-more:border-gray-800 contrast-more:dark:border-gray-50">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
</svg>
</button>
</div>
</div>
{{ end -}}

View File

@ -17,8 +17,8 @@
<div class="overflow-x-auto mt-6 flex rounded-lg border py-2 ltr:pr-4 rtl:pl-4 contrast-more:border-current contrast-more:dark:border-current {{ $class }}">
<div class="select-none text-xl ltr:pl-3 ltr:pr-2 rtl:pr-3 rtl:pl-2" style='font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";'>{{ $emoji }}</div>
<div class="w-full min-w-0 leading-7">
<p class="mt-6 leading-7 first:mt-0">
<div class="mt-6 leading-7 first:mt-0">
{{ .Inner | markdownify }}
</p>
</div>
</div>
</div>

View File

@ -3,10 +3,10 @@ const colors = require('tailwindcss/colors')
const makePrimaryColor =
l =>
({ opacityValue }) => {
if (opacityValue === undefined) {
return `hsl(var(--primary-hue) 100% ${l}%)`
}
return `hsl(var(--primary-hue) 100% ${l}% / ${opacityValue})`
return (
`hsl(var(--primary-hue) var(--primary-saturation) ${l}%` +
(opacityValue ? ` / ${opacityValue})` : ')')
)
}
/** @type {import('tailwindcss').Config} */