Skip to content

SidebarSublist

Ion’s SidebarSublist override allows you to use Icons in the sidebar.

SidebarSublist.astro
---
import { Icon } from 'astro-icon/components';
import { type SidebarEntry } from 'starlight-ion-theme/utils/navigation.js';
import Badge from './Badge.astro';
import { icons } from 'ion:globals';
interface Props {
sublist: SidebarEntry[];
nested?: boolean;
nestedCount: number;
}
const { sublist, nested, nestedCount } = Astro.props;
---
<ul class:list={{ 'top-level': !nested }}>
{
sublist.map((entry) => {
return (
<li class:list={[{ nested: nested && nestedCount > 1, active: entry.type === 'link' && entry.isCurrent }, entry.label.includes("[") && "has-icon"]}>
{entry.type === 'link' ? (
<a
href={entry.href}
aria-current={entry.isCurrent && 'page'}
class:list={[{ individual: !nested }, entry.attrs.class, "flex-link"]}
{...entry.attrs}
>
{icons && entry.label.includes("[") && (
<Icon name={entry.label.split("[").pop()?.split("]")[0] || ""} />
)}
<span>{entry.label.split("]").pop()?.trim()}</span>
{entry.badge && (
<>
{' '}
<Badge
text={entry.badge.text}
variant={entry.isCurrent ? 'outline' : entry.badge.variant}
/>
</>
)}
</a>
) : (
<details
open
>
<summary style="pointer-events: none;" class={nested ? "hidden" : ""}>
<div class="group-label">
{icons && entry.label.includes("[") && (
<Icon name={entry.label.split("[").pop()?.split("]")[0] || ""} />
)}
<span class="large">{entry.label.split("]").pop()?.trim()}</span>
{entry.badge && (
<>
{' '}
<Badge text={entry.badge.text} variant={entry.badge.variant} />
</>
)}
</div>
</summary>
<Astro.self sublist={entry.entries} nested nestedCount={nestedCount + 1} />
</details>
)}
</li>
)
})
}
</ul>
<style>
ul {
list-style: none;
padding: 0;
color: var(--sl-color-gray-2);
}
li {
overflow-wrap: anywhere;
margin-bottom: 0.25rem;
}
ul ul li {
margin-inline-start: var(--sl-sidebar-item-padding-inline);
/* border-inline-start: 1px solid var(--sl-color-hairline-light); */
padding-inline-start: var(--sl-sidebar-item-padding-inline);
}
.large {
font-size: var(--sl-text-lg);
font-weight: 600;
/* color: var(--sl-color-white); */
transition: all 0.1s ease;
}
.individual {
font-size: var(--sl-text-md);
font-weight: 400;
transition: all 0.1s ease;
}
ul:not(.top-level) > li > details {
margin-inline-start: 0.5rem;
padding-inline-start: 0.5rem;
> summary {
border-top: none;
padding-top: 0;
}
}
.top-level > li + li {
margin-top: 0.75rem;
}
summary {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.2em var(--sl-sidebar-item-padding-inline);
line-height: 1.4;
cursor: pointer;
user-select: none;
margin-bottom: 0.75rem;
margin-top: 1rem;
border-top: 1px solid var(--sl-color-hairline-light);
padding-top: 1rem;
}
summary span {
font-family: "Space Mono", monospace;
font-weight: 400 !important;
}
.top-level li:first-of-type > details > summary {
margin-top: 0;
border-top: none;
padding-top: 0;
}
summary::marker,
summary::-webkit-details-marker {
display: none !important;
background-image: none !important;
-webkit-appearance: none !important;
}
.caret {
transition: transform 0.2s ease-in-out;
flex-shrink: 0;
}
:global([dir='rtl']) .caret {
transform: rotateZ(180deg);
}
[open] > summary .caret {
transform: rotateZ(90deg);
}
a {
display: block;
border-radius: 0.25rem;
text-decoration: none;
color: var(--sl-color-gray-2);
padding: 0.3em var(--sl-sidebar-item-padding-inline);
line-height: 1.4;
}
a:hover,
a:focus {
color: var(--sl-color-white);
transition: all 0.1s ease;
}
[aria-current='page'],
[aria-current='page']:hover,
[aria-current='page']:focus {
font-weight: 600;
color: var(--sl-color-accent) !important;
svg {
filter: drop-shadow(0 0 8px var(--sl-color-accent));
}
span {
color: var(--sl-color-white) !important;
}
/* background-color: var(--sl-color-text-accent); */
}
.group-label, .flex-link {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
}
a > *:not(:last-child),
.group-label > *:not(:last-child) {
margin-inline-end: 0.25em;
}
@media (min-width: 50rem) {
.top-level > li + li {
margin-top: 0.5rem;
}
.large {
font-size: var(--sl-text-base);
}
a {
font-size: var(--sl-text-sm);
}
}
</style>