Add remaining samples, tooling, and local project assets
This commit is contained in:
1 parent
05d43a7999
commit
1ff6c6cbb2
862 files changed
+18979
-21
No files matched your search
@@ -0,0 +1,204 @@
|
||||
---
|
||||
import TableOfContentsList from "./TableOfContentsList.astro";
|
||||
|
||||
const parseFlag = (value) => {
|
||||
if (typeof value === "boolean") return value;
|
||||
if (typeof value === "string") {
|
||||
const normalized = value.trim().toLowerCase();
|
||||
if (["true", "1", "yes", "y", "on"].includes(normalized)) return true;
|
||||
if (["false", "0", "no", "n", "off"].includes(normalized)) return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const route = Astro.locals.starlightRoute ?? {};
|
||||
const { toc } = route;
|
||||
const entryData = route.entry?.data ?? {};
|
||||
const frontmatter = entryData.frontmatter ?? entryData;
|
||||
const enableNumbering = parseFlag(frontmatter.numberedHeadings);
|
||||
const filteredItems = (toc?.items ?? []).filter((item) => item.slug !== "_top");
|
||||
const title = Astro.locals.t("tableOfContents.onThisPage");
|
||||
---
|
||||
|
||||
{
|
||||
filteredItems.length > 0 && (
|
||||
<mobile-starlight-toc data-min-h={toc?.minHeadingLevel} data-max-h={toc?.maxHeadingLevel}>
|
||||
<nav aria-labelledby="starlight__on-this-page--mobile">
|
||||
<details id="starlight__mobile-toc">
|
||||
<summary id="starlight__on-this-page--mobile" class="sl-flex">
|
||||
<div class="toggle sl-flex">
|
||||
<a href="#_top">{title}</a>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="caret"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
style="--sl-icon-size: 1rem;"
|
||||
>
|
||||
<path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span class="display-current" />
|
||||
</summary>
|
||||
<div class="dropdown">
|
||||
<TableOfContentsList toc={filteredItems} isMobile enableNumbering={enableNumbering} />
|
||||
</div>
|
||||
</details>
|
||||
</nav>
|
||||
</mobile-starlight-toc>
|
||||
)
|
||||
}
|
||||
|
||||
<style>
|
||||
@layer starlight.core {
|
||||
:global(mobile-starlight-toc) {
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
nav {
|
||||
position: fixed;
|
||||
z-index: var(--sl-z-index-toc);
|
||||
top: calc(var(--sl-nav-height) - 1px);
|
||||
inset-inline: 0;
|
||||
border-top: 1px solid var(--sl-color-gray-5);
|
||||
background-color: var(--sl-color-bg-nav);
|
||||
display: block !important;
|
||||
}
|
||||
@media (min-width: 50rem) {
|
||||
nav {
|
||||
inset-inline-start: var(--sl-content-inline-start, 0);
|
||||
}
|
||||
}
|
||||
:global(.sidebar-collapsed) nav {
|
||||
inset-inline-start: 11px !important;
|
||||
inset-inline-end: 2px !important;
|
||||
}
|
||||
@media (min-width: 72rem) {
|
||||
nav {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@media (max-width: 87.499rem) {
|
||||
:global([data-has-toc] mobile-starlight-toc nav) {
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
summary {
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
height: var(--sl-mobile-toc-height);
|
||||
border-bottom: 1px solid var(--sl-color-hairline-shade);
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: var(--sl-text-xs);
|
||||
outline-offset: var(--sl-outline-offset-inside);
|
||||
}
|
||||
summary::marker,
|
||||
summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
flex-shrink: 0;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border: 1px solid var(--sl-color-gray-5);
|
||||
border-radius: 0.5rem;
|
||||
padding-block: 0.5rem;
|
||||
padding-inline-start: 0.75rem;
|
||||
padding-inline-end: 0.5rem;
|
||||
line-height: 1;
|
||||
background-color: var(--sl-color-black);
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.toggle a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toggle a:hover,
|
||||
.toggle a:focus-visible {
|
||||
text-decoration: underline;
|
||||
}
|
||||
details[open] .toggle {
|
||||
color: var(--sl-color-white);
|
||||
border-color: var(--sl-color-accent);
|
||||
}
|
||||
details .toggle:hover {
|
||||
color: var(--sl-color-white);
|
||||
border-color: var(--sl-color-gray-2);
|
||||
}
|
||||
|
||||
:global([dir="rtl"]) .caret {
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
details[open] .caret {
|
||||
transform: rotateZ(90deg);
|
||||
}
|
||||
|
||||
.display-current {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: var(--sl-color-white);
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
--border-top: 1px;
|
||||
margin-top: calc(-1 * var(--border-top));
|
||||
border: var(--border-top) solid var(--sl-color-gray-6);
|
||||
border-top-color: var(--sl-color-hairline-shade);
|
||||
max-height: calc(85vh - var(--sl-nav-height) - var(--sl-mobile-toc-height));
|
||||
overflow-y: auto;
|
||||
background-color: var(--sl-color-black);
|
||||
box-shadow: var(--sl-shadow-md);
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { StarlightTOC } from "./starlight-toc";
|
||||
|
||||
class MobileStarlightTOC extends StarlightTOC {
|
||||
override set current(link) {
|
||||
super.current = link;
|
||||
const display = this.querySelector(".display-current");
|
||||
if (display) display.textContent = link.textContent;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const details = this.querySelector("details");
|
||||
if (!details) return;
|
||||
const closeToC = () => {
|
||||
details.open = false;
|
||||
};
|
||||
details.querySelectorAll("a").forEach((a) => {
|
||||
a.addEventListener("click", closeToC);
|
||||
});
|
||||
window.addEventListener("click", (e) => {
|
||||
if (!details.contains(e.target)) closeToC();
|
||||
});
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape" && details.open) {
|
||||
const hasFocus = details.contains(document.activeElement);
|
||||
closeToC();
|
||||
if (hasFocus) {
|
||||
const summary = details.querySelector("summary");
|
||||
if (summary) summary.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("mobile-starlight-toc", MobileStarlightTOC);
|
||||
</script>
|
||||
Reference in new issue
Block a user