Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions _data/site.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
{
"title": "ReallySimpleDocs",
"subtitle": "v0.1.3",
"description": "A really simple documentation template built with 11ty and Tailwind.",
"url": "https://reallysimpledocs.com",
"logo": {
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-book-open-icon lucide-book-open\"><path d=\"M12 7v14\"/><path d=\"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z\"/></svg>"
},
"links": [
{
"label": "GitHub",
"icon": "<svg role=\"img\" fill=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><title>GitHub</title><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"/></svg>",
"url": "https://github.com/hunvreus/reallysimpledocs",
"attrs": {
"rel": "noopener",
"target": "_blank",
"class": "btn-sm h-7"
}
}
]
"title": "ReallySimpleDocs",
"subtitle": "v0.2.0-beta.1",
"description": "A really simple documentation template built with 11ty and Tailwind.",
"url": "https://reallysimpledocs.com",
"logo": {
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-book-open-icon lucide-book-open\"><path d=\"M12 7v14\"/><path d=\"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z\"/></svg>"
},
"links": [
{
"label": "GitHub",
"icon": "<svg role=\"img\" fill=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><title>GitHub</title><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"/></svg>",
"url": "https://github.com/hunvreus/reallysimpledocs",
"attrs": {
"rel": "noopener",
"target": "_blank",
"class": "btn-sm h-7"
}
}
]
}
3 changes: 2 additions & 1 deletion _includes/layouts/base.njk
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<meta name="description" content="{{ meta_description }}"/>
<meta name="title" content="{{ meta_title }}">
{% if site.keywords %}<meta name="keywords" content="{{ site.keywords | join(',') }}" />{% endif %}

{# Favicon #}
<link rel="icon" type="image/svg+xml" href="{{ siteUrl }}/assets/favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="{{ siteUrl }}/assets/apple-touch-icon.png">
Expand Down Expand Up @@ -72,6 +72,7 @@
<script src="/assets/basecoat.min.js" defer></script>
<script src="/assets/copy-code.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script src="/assets/pagefind-search.js" defer></script>
<script>
const highlight = () => {
if (!window.hljs) return;
Expand Down
8 changes: 4 additions & 4 deletions _includes/layouts/doc.njk
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ layout: base
{% include "partials/docs/sidebar.njk" %}
{% set navigation = menu | getNavigation(collections) %}

<main id="content">
<header class="bg-background sticky inset-x-0 top-0 isolate flex shrink-0 items-center gap-2 border-b z-10">
<main id="content" data-pagefind-body>
<header class="bg-background sticky inset-x-0 top-0 isolate flex shrink-0 items-center gap-2 border-b z-10" data-pagefind-ignore>
{% include "partials/docs/header.njk" %}
</header>

Expand All @@ -16,7 +16,7 @@ layout: base
<div class="mx-auto w-full max-w-2xl flex-1 space-y-10">
<header class="space-y-2">
<div class="flex items-start gap-x-2">
<h1 class="text-3xl font-semibold tracking-tight sm:text-4xl mr-auto">{{ title }}</h1>
<h1 class="text-3xl font-semibold tracking-tight sm:text-4xl mr-auto" data-pagefind-meta="title">{{ title }}</h1>
<div class="flex items-center gap-x-2 mt-1.5">
<div role="group" class="button-group">
<button
Expand Down Expand Up @@ -117,7 +117,7 @@ layout: base
</footer>
</div>
</article>
<aside class="hidden xl:block w-56">
<aside class="hidden xl:block w-56" data-pagefind-ignore>
<div class="sticky top-20 text-sm [&_a]:text-muted-foreground [&_a]:hover:text-primary space-y-2 [&_ol]:space-y-2 [&_ol_ol]:pl-3 [&_ol_ol]:mt-2">
<h2 class="font-medium flex items-center gap-1">
{% lucide "table-of-contents", { class: "size-4" } %}
Expand Down
7 changes: 5 additions & 2 deletions _includes/partials/docs/header.njk
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{% from "macros/command.njk" import command_dialog %}

{% set commandMenu = menu | commandMenu(collections) %}
{{ command_dialog(id="command-search", items=commandMenu, placeholder="Search the docs...") }}
{{ command_dialog(
id="command-search",
placeholder="Search the docs...",
dialog_attrs={ "data-pagefind-search": "true" }
) }}
<script>
document.addEventListener('keydown', (e) => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
Expand Down
97 changes: 97 additions & 0 deletions assets/pagefind-search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Pagefind search integration for command dialog
// Lazy-loads Pagefind on first use, renders results as menuitem elements

let pagefind = null;

async function loadPagefind() {
if (!pagefind) {
pagefind = await import('/pagefind/pagefind.js');
await pagefind.init();
}
return pagefind;
}

function debounce(fn, ms) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), ms);
};
}

function reinitCommand(container) {
// Remove initialization flag so basecoat re-inits
const commandEl = container.querySelector('.command');
if (commandEl) {
commandEl.removeAttribute('data-command-initialized');
window.basecoat?.init('command');
}
}

function renderResults(items, menuEl, dialog) {
if (items.length === 0) {
menuEl.innerHTML = `<div role="menuitem" aria-disabled="true" class="empty">${menuEl.dataset.empty || 'No results found.'}</div>`;
reinitCommand(dialog);
return;
}

menuEl.innerHTML = items.map((item, i) => `
<a id="search-result-${i}" href="${item.url}" role="menuitem">
<span class="search-title">${item.meta?.title || 'Untitled'}</span>
${item.excerpt ? `<span class="search-excerpt">${item.excerpt}</span>` : ''}
</a>
`).join('');

reinitCommand(dialog);
}

async function search(query, menuEl, dialog) {
const trimmed = query.trim();

if (!trimmed) {
menuEl.innerHTML = '<div role="menuitem" aria-disabled="true" class="empty">Type to search documentation...</div>';
reinitCommand(dialog);
return;
}

menuEl.innerHTML = '<div role="menuitem" aria-disabled="true" class="loading">Searching...</div>';

try {
const pf = await loadPagefind();
const results = await pf.search(trimmed);

const items = await Promise.all(
results.results.slice(0, 8).map(r => r.data())
);

renderResults(items, menuEl, dialog);
} catch (err) {
console.error('Search error:', err);
menuEl.innerHTML = '<div role="menuitem" aria-disabled="true" class="error">Search failed. Try again.</div>';
reinitCommand(dialog);
}
}

function initPagefindSearch() {
document.querySelectorAll('dialog.command-dialog[data-pagefind-search]').forEach(dialog => {
const input = dialog.querySelector('header input');
const menu = dialog.querySelector('[role="menu"]');
if (!input || !menu) return;

menu.innerHTML = '<div role="menuitem" aria-disabled="true" class="empty">Type to search documentation...</div>';

const debouncedSearch = debounce(() => search(input.value, menu, dialog), 150);
input.addEventListener('input', debouncedSearch);

dialog.addEventListener('close', () => {
input.value = '';
menu.innerHTML = '<div role="menuitem" aria-disabled="true" class="empty">Type to search documentation...</div>';
});
});
}

if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initPagefindSearch);
} else {
initPagefindSearch();
}
134 changes: 134 additions & 0 deletions assets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace;
--color-yellow-200: oklch(94.5% 0.129 101.54);
--color-yellow-500: oklch(79.5% 0.184 86.047);
--color-black: #000;
--color-white: #fff;
--spacing: 0.25rem;
--container-xs: 20rem;
--container-lg: 32rem;
--container-xl: 36rem;
--container-2xl: 42rem;
--text-xs: 0.75rem;
--text-xs--line-height: calc(1 / 0.75);
Expand Down Expand Up @@ -554,6 +557,9 @@
.opacity-0 {
opacity: 0%;
}
.filter {
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,);
}
.transition-all {
transition-property: all;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
Expand Down Expand Up @@ -4205,6 +4211,68 @@
}
}
}
.command-dialog[data-pagefind-search] > .command {
@media (width >= 40rem) {
max-width: var(--container-xl);
}
}
.command-dialog[data-pagefind-search] [role="menu"] {
max-height: 500px;
padding: calc(var(--spacing) * 2);
}
.command-dialog[data-pagefind-search] [role="menuitem"]:not(.empty):not(.loading):not(.error) {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: calc(var(--spacing) * 0.5);
overflow: visible;
padding-block: calc(var(--spacing) * 2);
text-wrap: wrap;
white-space: normal;
}
.command-dialog[data-pagefind-search] [role="menuitem"] .search-title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
--tw-font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-medium);
color: var(--color-foreground);
}
.command-dialog[data-pagefind-search] [role="menuitem"] .search-excerpt {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
color: var(--color-muted-foreground);
}
.command-dialog[data-pagefind-search] [role="menuitem"] mark {
border-radius: var(--radius-sm);
background-color: color-mix(in srgb, oklch(94.5% 0.129 101.54) 60%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-yellow-200) 60%, transparent);
}
padding-inline: calc(var(--spacing) * 0.5);
color: inherit;
&:is(.dark *) {
background-color: color-mix(in srgb, oklch(79.5% 0.184 86.047) 30%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-yellow-500) 30%, transparent);
}
}
}
.command-dialog[data-pagefind-search] [role="menuitem"].empty, .command-dialog[data-pagefind-search] [role="menuitem"].loading, .command-dialog[data-pagefind-search] [role="menuitem"].error {
cursor: default;
justify-content: center;
padding-block: calc(var(--spacing) * 4);
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
color: var(--color-muted-foreground);
}
.command-dialog[data-pagefind-search] [role="menuitem"].error {
color: var(--color-destructive);
}
:root {
--hljs-bg: #fff;
--hljs-color: #24292e;
Expand Down Expand Up @@ -4348,6 +4416,59 @@ code.hljs {
syntax: "*";
inherits: false;
}
@property --tw-blur {
syntax: "*";
inherits: false;
}
@property --tw-brightness {
syntax: "*";
inherits: false;
}
@property --tw-contrast {
syntax: "*";
inherits: false;
}
@property --tw-grayscale {
syntax: "*";
inherits: false;
}
@property --tw-hue-rotate {
syntax: "*";
inherits: false;
}
@property --tw-invert {
syntax: "*";
inherits: false;
}
@property --tw-opacity {
syntax: "*";
inherits: false;
}
@property --tw-saturate {
syntax: "*";
inherits: false;
}
@property --tw-sepia {
syntax: "*";
inherits: false;
}
@property --tw-drop-shadow {
syntax: "*";
inherits: false;
}
@property --tw-drop-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-drop-shadow-alpha {
syntax: "<percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-drop-shadow-size {
syntax: "*";
inherits: false;
}
@property --tw-shadow {
syntax: "*";
inherits: false;
Expand Down Expand Up @@ -4445,6 +4566,19 @@ code.hljs {
--tw-leading: initial;
--tw-font-weight: initial;
--tw-tracking: initial;
--tw-blur: initial;
--tw-brightness: initial;
--tw-contrast: initial;
--tw-grayscale: initial;
--tw-hue-rotate: initial;
--tw-invert: initial;
--tw-opacity: initial;
--tw-saturate: initial;
--tw-sepia: initial;
--tw-drop-shadow: initial;
--tw-drop-shadow-color: initial;
--tw-drop-shadow-alpha: 100%;
--tw-drop-shadow-size: initial;
--tw-shadow: 0 0 #0000;
--tw-shadow-color: initial;
--tw-shadow-alpha: 100%;
Expand Down
Loading