Compare commits

..

13 Commits

Author SHA1 Message Date
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
20 changed files with 300 additions and 82 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];
}

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

@ -0,0 +1,18 @@
const backToTop = document.querySelector("#backToTop");
document.addEventListener("scroll", (event) => {
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

@ -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

@ -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

@ -2,4 +2,6 @@ onThisPage: "On this page"
editThisPage: "Edit this page on GitHub →"
lastUpdated: "Last updated on"
backToTop: "Scroll to top"
copyright: "© 2023 Hextra Project."

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."

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

@ -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

@ -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

@ -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

@ -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 }}
@ -29,6 +30,15 @@
{{- 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

@ -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} */