Compare commits

..

5 Commits

Author SHA1 Message Date
Xin
d0cdd29ee5 fix(navbar): search wrapper class not prefixed (#756)
* fix(navbar): search wrapper class not prefixed

* fix(css): update Tailwind CSS properties layer for improved compatibility
2025-08-15 14:33:09 +08:00
Xin
91cc6b53d8 fix(toc): enhance hash navigation handling and adjust observer sensitivity (#754) 2025-08-15 10:33:49 +08:00
Ludovic Fernandez
2033d50005 docs: add documentation on all shortcodes (#753) 2025-08-15 09:09:58 +08:00
Ludovic Fernandez
80ada64da0 fix: search colors (#752) 2025-08-15 08:57:18 +08:00
Xin
776c758825 chore(build): update MAIN_VERSION to v0.10.0 in build script 2025-08-15 00:07:57 +08:00
27 changed files with 260 additions and 20 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
nav {
.search-wrapper {
.hextra-search-wrapper {
@apply hx:hidden hx:md:inline-block;
}
}

View File

@@ -392,7 +392,7 @@ document.addEventListener("DOMContentLoaded", function () {
function highlightMatches(text, query) {
const escapedQuery = query.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
const regex = new RegExp(escapedQuery, 'gi');
return text.replace(regex, (match) => `<span class="match">${match}</span>`);
return text.replace(regex, (match) => `<span class="hextra-search-match">${match}</span>`);
}
// Create a DOM element from the HTML string.
@@ -405,11 +405,11 @@ document.addEventListener("DOMContentLoaded", function () {
function handleMouseMove(e) {
const target = e.target.closest('a');
if (target) {
const active = resultsElement.querySelector('a.active');
const active = resultsElement.querySelector('a.hextra-search-active');
if (active) {
active.classList.remove('active');
active.classList.remove('hextra-search-active');
}
target.classList.add('active');
target.classList.add('hextra-search-active');
}
}

View File

@@ -20,10 +20,14 @@ document.addEventListener("DOMContentLoaded", function () {
if (headings.length === 0) return;
let currentActiveLink = null;
let isHashNavigation = false;
// Create intersection observer
const observer = new IntersectionObserver(
(entries) => {
// Skip observer updates during hash navigation
if (isHashNavigation) return;
const visibleHeadings = entries.filter((entry) => entry.isIntersecting).map((entry) => entry.target);
if (visibleHeadings.length === 0) return;
@@ -50,7 +54,7 @@ document.addEventListener("DOMContentLoaded", function () {
}
},
{
rootMargin: "-20px 0px -80% 0px", // Adjust sensitivity
rootMargin: "-20px 0px -60% 0px", // Adjust sensitivity
threshold: [0, 0.1, 0.5, 1],
}
);
@@ -58,11 +62,31 @@ document.addEventListener("DOMContentLoaded", function () {
// Observe all headings
headings.forEach((heading) => observer.observe(heading));
// Handle edge case: if no headings are visible on initial load
setTimeout(() => {
if (!currentActiveLink && tocLinks.length > 0) {
tocLinks[0].classList.add("hextra-toc-active");
currentActiveLink = tocLinks[0];
// Handle direct navigation to page with hash
function handleHashNavigation() {
const hash = window.location.hash;
if (hash) {
const targetLink = toc.querySelector(`a[href="${hash}"]`);
if (targetLink) {
// Disable observer temporarily during hash navigation
isHashNavigation = true;
if (currentActiveLink) {
currentActiveLink.classList.remove("hextra-toc-active");
}
targetLink.classList.add("hextra-toc-active");
currentActiveLink = targetLink;
// Re-enable observer after scroll settles
setTimeout(() => { isHashNavigation = false; }, 500);
return;
}
}
}, 100);
}
// Handle hash changes navigation
window.addEventListener("hashchange", handleHashNavigation);
// Handle initial load
setTimeout(handleHashNavigation, 100);
});

View File

@@ -8,7 +8,7 @@ echo "Using base URL: $BASE_URL"
# Version configuration - modify these arrays to specify versions to build
# Format: "ref:display_name" (ref can be tag, branch, or commit hash, display name is what will appear in URL)
MAIN_VERSION="v0.9.6:latest"
MAIN_VERSION="v0.10.0:latest"
VERSIONS=(
"main:latest" # latest version always builds from main
"v0.9.6:v0.9"

View File

@@ -1,3 +1,19 @@
{{- /*
A shortcode to create a badge.
@param {string} content The content of the badge.
@param {string} type The type of the badge.
@param {string} class The class of the badge.
@param {string} link The link of the badge.
@param {string} icon The icon of the badge.
or
@param {string} 0 The content of the badge.
@example {{< badge content="info" type="info" >}}
*/ -}}
{{- if .IsNamedParams -}}
{{- $content := .Get "content" -}}
{{- $type := .Get "type" | default "" -}}

View File

@@ -1,3 +1,14 @@
{{- /*
A shortcode to create a callout.
@param {string} type The type of the callout (default, info, warning, error).
@param {string} content The content of the callout.
@param {string} emoji The emoji of the callout (related to type or can be a custom emoji).
@param {string} icon The icon of the callout.
@example {{< callout type="info" >}}Content{{< /callout >}}
*/ -}}
{{- $calloutEmojiDict := dict "info" "" "warning" "⚠️" "error" "🚫" -}}
{{- $type := .Get "type" | default "default" -}}
{{/* If emoji is not set, use the emoji from dict */}}

View File

@@ -1,3 +1,20 @@
{{- /*
A shortcode to create a card.
@param {string} link The link to the card.
@param {string} title The title of the card.
@param {string} icon The icon of the card.
@param {string} subtitle The subtitle of the card.
@param {string} tag The tag of the card.
@param {string} tagType The type of the tag.
@param {string} image The image of the card.
@param {string} method The method to process the image.
@param {string} options The options to process the image.
@param {string} imageStyle The style of the image.
@example {{< card link="/" title="Image Card" }}
*/ -}}
{{- $context := . -}}
{{- $link := .Get "link" -}}
{{- $title := .Get "title" -}}

View File

@@ -1,3 +1,11 @@
{{- /*
A shortcode for creating cards.
@param {string} cols The number of columns.
@example {{< cards cols="3" >}}{{< /cards >}}
*/ -}}
{{- $cols := .Get "cols" | default 3 -}}
{{- partial "shortcodes/cards" (dict "cols" $cols "content" .Inner) -}}

View File

@@ -1,3 +1,12 @@
{{- /*
A built-in component to display a collapsible content.
@param {string} title The title of the details.
@param {string} closed Whether the details are closed or not (default: false).
@example {{% details title="Details" %}}Content{{% /details %}}
*/ -}}
{{- $title := .Get "title" | default "" -}}
{{- $closed := eq (.Get "closed") "true" | default false -}}

View File

@@ -1,3 +1,9 @@
{{- /*
A file tree container.
@example {{< filetree/container >}}{{< /filetree/container >}}
*/ -}}
<div class="hextra-filetree hx:mt-6 hx:select-none hx:text-sm hx:text-gray-800 hx:dark:text-gray-300 not-prose">
<div class="hx:inline-block hx:rounded-lg hx:px-4 hx:py-2 hx:border hx:border-gray-200 hx:dark:border-neutral-800">
{{- .InnerDeindent -}}

View File

@@ -1,5 +1,12 @@
{{- $name := .Get "name" -}}
{{- /*
A file in a file tree.
@param {string} name The name of the file.
@example {{< filetree/file name="_index.md" >}}
*/ -}}
{{- $name := .Get "name" -}}
<li class="hx:flex hx:list-none">
<span class="hx:inline-flex hx:cursor-default hx:items-center hx:py-1">

View File

@@ -1,3 +1,12 @@
{{- /*
A folder in a file tree.
@param {string} name The name of the folder.
@param {string} state The state of the folder.
@example {{< filetree/folder name="docs" state="closed" >}}
*/ -}}
{{- $name := .Get "name" -}}
{{- $state := .Get "state" | default "open" }}

View File

@@ -1,3 +1,18 @@
{{- /*
A shortcode for displaying a feature card.
@param {string} title The title of the card.
@param {string} subtitle The subtitle of the card.
@param {string} class The class of the card.
@param {string} image The image of the card.
@param {string} imageClass The class of the image.
@param {string} style The style of the card.
@param {string} icon The icon of the card.
@param {string} link The link of the card.
@example {{< hextra/feature-card title="Feature Card" subtitle="This is a feature card." >}}
*/ -}}
{{- $title := .Get "title" -}}
{{- $subtitle := .Get "subtitle" -}}
{{- $class := .Get "class" -}}

View File

@@ -1,3 +1,12 @@
{{- /*
A shortcode for displaying a feature grid.
@param {string} cols The number of columns.
@param {string} style The style of the grid.
@example {{< hextra/feature-grid cols="3" >}}{{< /hextra/feature-grid >}}
*/ -}}
{{- $cols := .Get "cols" | default 3 -}}
{{- $style := .Get "style" | default "" -}}

View File

@@ -1,10 +1,19 @@
{{- /*
A shortcode for rendering a badge with a link.
@param {string} link The link of the badge.
@param {string} class The class of the badge.
@param {string} style The style of the badge.
@example {{< hextra/hero-badge >}}{{< /hextra/hero-badge >}}
*/ -}}
{{- $link := .Get "link" -}}
{{- $external := hasPrefix $link "http" -}}
{{- $href := cond (hasPrefix $link "/") ($link | relURL) $link -}}
{{- $class := .Get "class" }}
{{- $style := .Get "style" -}}
<a
{{ if $link }}href="{{ $href }}"{{ end }}
class="{{ $class }} not-prose hx:inline-flex hx:items-center hx:rounded-full hx:gap-2 hx:px-3 hx:py-1 hx:text-xs hx:text-gray-600 hx:dark:text-gray-400 hx:bg-gray-100 hx:dark:bg-neutral-800 hx:border-gray-200 hx:dark:border-neutral-800 hx:border hx:hover:border-gray-400 hx:dark:hover:text-gray-50 hx:dark:hover:border-gray-600 hx:transition-all hx:ease-in hx:duration-200"

View File

@@ -1,3 +1,13 @@
{{- /*
A shortcode for rendering a button with a link.
@param {string} link The link of the button.
@param {string} text The text of the button.
@param {string} style The style of the button.
@example {{< hextra/hero-button text="Get Started" link="docs" >}}
*/ -}}
{{- $link := .Get "link" -}}
{{- $text := .Get "text" -}}
{{- $style := .Get "style" -}}

View File

@@ -1,3 +1,21 @@
{{- /*
A simple hero container with an image on the left side.
@param {string} class The class of the container.
@param {string} cols The number of columns (default: 2).
@param {string} image The image of the container.
@param {bool} imageCard Whether to display the image as a card (default: false).
@param {string} imageClass The class of the image.
@param {string} imageLink The link of the image.
@param {string} imageStyle The style of the image.
@param {string} imageTitle The title of the image.
@param {int} imageWidth The width of the image (default: 350).
@param {int} imageHeight The height of the image (default: 350).
@param {string} style The style of the container.
@example {{< hextra/hero-container image="image.png" imageLink="https://example.com" imageTitle="Example Image" >}}
*/ -}}
{{- $class := .Get "class" -}}
{{- $cols := .Get "cols" | default 2 -}}
{{- $image := .Get "image" -}}

View File

@@ -1,5 +1,12 @@
{{- $style := .Get "style" -}}
{{- /*
A shortcode for displaying a hero headline.
@param {string} style The style of the headline.
@example {{< hextra/hero-headline >}}{{< /hextra/hero-headline >}}
*/ -}}
{{- $style := .Get "style" -}}
<h1
class="not-prose hx:text-4xl hx:font-bold hx:leading-none hx:tracking-tighter hx:md:text-5xl hx:py-2 hx:bg-clip-text hx:text-transparent hx:bg-gradient-to-r hx:from-gray-900 hx:to-gray-600 hx:dark:from-gray-100 hx:dark:to-gray-400"

View File

@@ -1,3 +1,13 @@
{{- /*
A simple hero section with a heading and optional style.
@param {string} heading The heading level (default: h2).
@param {string} style The style of the heading.
@param {string} content The content of the heading.
@example {{< hextra/hero-section heading="h3" >}}{{< /hextra/hero-section >}}>
*/ -}}
{{- $style := .Get "style" -}}
{{- $heading := int (strings.TrimPrefix "h" (.Get "heading" | default "h2")) -}}
{{- $size := cond (ge $heading 4) "xl" (cond (eq $heading 3) "2xl" "4xl") -}}

View File

@@ -1,5 +1,12 @@
{{- $style := .Get "style" -}}
{{- /*
A shortcode for displaying a hero subtitle.
@param {string} style The style of the subtitle.
@example {{< hextra/hero-subtitle >}}{{< /hextra/hero-subtitle >}}
*/ -}}
{{- $style := .Get "style" -}}
<p
class="not-prose hx:text-xl hx:text-gray-600 hx:dark:text-gray-400 hx:sm:text-xl"

View File

@@ -1,3 +1,17 @@
{{- /*
Create an icon.
@param {string} name The name of the icon.
@param {string} attributes The attributes of the icon.
or
@param {string} 0 The name of the icon.
@example {{< icon name="github" >}}
@example {{< icon "github" >}}
*/ -}}
{{- $name := .Get "name" | default (.Get 0) -}}
{{- $icon := index site.Data.icons $name -}}
{{- $attributes := .Get "attributes" | default "height=1em"}}

View File

@@ -1,4 +1,11 @@
{{/* Render Jupyter Notebook */}}
{{- /*
Render Jupyter Notebook
@param {string} 0 The path of the Jupyter Notebook.
@example {{% jupyter "notebook.ipynb" %}}
*/ -}}
{{- $path := .Get 0 -}}
{{- $data := "" -}}
{{- $page := .Page -}}

View File

@@ -1,4 +1,10 @@
{{/* Shortcode to include a PDF file in a page. */}}
{{- /*
Shortcode to include a PDF file in a page.
@param {string} 0 The path to the PDF file.
@example {{< pdf "path/to/file.pdf" >}}
*/ -}}
{{- $path := .Get 0 -}}
{{- $url := partial "utils/file-path" (dict "page" .Page "path" $path) -}}

View File

@@ -1,3 +1,9 @@
{{- /*
A shortcode for creating a step list.
@example {{% steps %}}{{% /steps %}}
*/ -}}
<div class="hextra-steps hx:ml-4 hx:mb-12 hx:ltr:border-l hx:rtl:border-r hx:border-gray-200 hx:ltr:pl-6 hx:rtl:pr-6 hx:dark:border-neutral-800 [counter-reset:step]">
{{- .Inner -}}
</div>

View File

@@ -1,3 +1,9 @@
{{- /*
Create a tab.
@example {{< tab >}}content{{< /tab >}}
*/ -}}
{{- $defaultIndex := int ((.Parent.Get "defaultIndex") | default "0") -}}
<div

View File

@@ -1,3 +1,12 @@
{{- /*
Create a tabbed interface with the given items.
@param {string} items The items to display in the tabs.
@param {string} defaultIndex The index of the default tab.
@example {{< tabs items="JSON,YAML,TOML" >}}{{< /tabs >}}
*/ -}}
{{- $items := split (.Get "items") "," -}}
{{- $defaultIndex := int ((.Get "defaultIndex") | default "0") -}}