-
+
{title}
@@ -54,8 +55,8 @@ export default function HomepageFeatures() {
- {FeatureList.map((props, idx) => (
-
+ {FeatureList.map(({Icon, ...rest}, idx) => (
+
))}
diff --git a/src/components/SidebarThemeToggle/index.js b/src/components/SidebarThemeToggle/index.js
index d6379ac..837eed1 100644
--- a/src/components/SidebarThemeToggle/index.js
+++ b/src/components/SidebarThemeToggle/index.js
@@ -1,64 +1,6 @@
import React from 'react';
import {useColorMode} from '@docusaurus/theme-common';
-
-function IconSystem(props) {
- return (
-
- );
-}
-
-function IconSun(props) {
- return (
-
- );
-}
-
-function IconMoon(props) {
- return (
-
- );
-}
+import {Monitor, Sun, Moon} from 'lucide-react';
export default function SidebarThemeToggle() {
const {colorModeChoice, setColorMode} = useColorMode();
@@ -74,7 +16,7 @@ export default function SidebarThemeToggle() {
onClick={() => setColorMode(null)}
aria-pressed={colorModeChoice === null}
title="System">
-
+
);
diff --git a/src/css/custom.css b/src/css/custom.css
index 91d2574..792f8d7 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -687,6 +687,18 @@ main > .container.padding-top--md.padding-bottom--lg,
align-items: center;
}
+.sidebar-icon {
+ flex-shrink: 0;
+ width: 1rem;
+ height: 1rem;
+ stroke-width: 2;
+ color: var(--ifm-color-content-secondary);
+}
+
+.menu__link--active > .sidebar-icon {
+ color: var(--ifm-color-primary);
+}
+
.sidebar-link-label {
overflow: hidden;
text-overflow: ellipsis;
@@ -720,6 +732,10 @@ main > .container.padding-top--md.padding-bottom--lg,
color var(--ifm-transition-fast) var(--ifm-transition-timing-default);
}
+.menu__list-item-collapsible .clean-btn.menu__caret::before {
+ display: none;
+}
+
.menu__list-item-collapsible:has(.menu__link--active) .clean-btn.menu__caret {
color: var(--color-emerald-700);
}
@@ -733,22 +749,6 @@ main > .container.padding-top--md.padding-bottom--lg,
color: var(--color-emerald-400);
}
-.menu__list-item-collapsible .clean-btn.menu__caret::before {
- width: 0.875rem;
- height: 0.875rem;
- background: none;
- background-color: currentColor;
- mask-image: var(--ifm-menu-link-sublist-icon);
- mask-repeat: no-repeat;
- mask-position: center;
- mask-size: contain;
- -webkit-mask-image: var(--ifm-menu-link-sublist-icon);
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-position: center;
- -webkit-mask-size: contain;
- filter: none;
-}
-
/* ────────────────────────────────── Code blocks ─────────────────────── */
.theme-code-block {
border: 1px solid var(--color-neutral-200);
diff --git a/src/theme/DocCard/index.js b/src/theme/DocCard/index.js
index f782847..26f3ce0 100644
--- a/src/theme/DocCard/index.js
+++ b/src/theme/DocCard/index.js
@@ -9,6 +9,7 @@ import {usePluralForm} from '@docusaurus/theme-common';
import isInternalUrl from '@docusaurus/isInternalUrl';
import {translate} from '@docusaurus/Translate';
import Heading from '@theme/Heading';
+import {FolderOpen, FileText, ExternalLink} from 'lucide-react';
import styles from './styles.module.css';
function useCategoryItemsPlural() {
@@ -72,7 +73,7 @@ function CardCategory({item}) {
}
title={item.label}
description={item.description ?? categoryItemsPlural(item.items.length)}
/>
@@ -80,7 +81,7 @@ function CardCategory({item}) {
}
function CardLink({item}) {
- const icon = isInternalUrl(item.href) ? '📄️' : '🔗';
+ const icon = isInternalUrl(item.href) ?
:
;
const doc = useDocById(item.docId ?? undefined);
return (
+ >
+
+
);
}
@@ -106,7 +110,14 @@ function DocSidebarItemCategoryEmpty({ item, ...props }) {
if (!isCategoryWithHref(item)) {
return null;
}
- const { type, collapsed, collapsible, items, linkUnlisted, ...forwardableProps } = item;
+ const {
+ type,
+ collapsed,
+ collapsible,
+ items,
+ linkUnlisted,
+ ...forwardableProps
+ } = item;
const linkItem = { type: "link", ...forwardableProps };
return
;
}
@@ -175,6 +186,7 @@ function DocSidebarItemCategoryCollapsible({
};
const badge = customProps?.badge;
+ const IconComponent = getSidebarIcon(customProps?.icon);
return (
+ {IconComponent && (
+
+ )}
{label}
diff --git a/src/theme/DocSidebarItem/Link/index.js b/src/theme/DocSidebarItem/Link/index.js
index 46a6ac6..adec678 100644
--- a/src/theme/DocSidebarItem/Link/index.js
+++ b/src/theme/DocSidebarItem/Link/index.js
@@ -5,6 +5,7 @@ import { isActiveSidebarItem } from "@docusaurus/plugin-content-docs/client";
import Link from "@docusaurus/Link";
import isInternalUrl from "@docusaurus/isInternalUrl";
import IconExternalLink from "@theme/Icon/ExternalLink";
+import { getSidebarIcon } from "@site/src/utils/sidebarIcons";
export default function DocSidebarItemLink({
item,
@@ -18,6 +19,7 @@ export default function DocSidebarItemLink({
const isActive = isActiveSidebarItem(item, activePath);
const isInternalLink = isInternalUrl(href);
const badge = customProps?.badge;
+ const IconComponent = getSidebarIcon(customProps?.icon);
return (
+ {IconComponent && (
+
+ )}
{label}
- {badge && {badge}}
+ {badge && (
+ {badge}
+ )}
{!isInternalLink && }
diff --git a/src/theme/Icon/Close/index.js b/src/theme/Icon/Close/index.js
index bed0e15..cd5861a 100644
--- a/src/theme/Icon/Close/index.js
+++ b/src/theme/Icon/Close/index.js
@@ -1,4 +1,5 @@
import React from 'react';
+import {X} from 'lucide-react';
export default function IconClose({
width = 22,
@@ -8,22 +9,13 @@ export default function IconClose({
...restProps
}) {
return (
-
+ {...restProps}
+ />
);
}
diff --git a/src/theme/Icon/Menu/index.js b/src/theme/Icon/Menu/index.js
index eb443d6..ff1d28e 100644
--- a/src/theme/Icon/Menu/index.js
+++ b/src/theme/Icon/Menu/index.js
@@ -1,4 +1,5 @@
import React from 'react';
+import {Menu} from 'lucide-react';
export default function IconMenu({
width = 22,
@@ -7,21 +8,12 @@ export default function IconMenu({
...restProps
}) {
return (
-
+ {...restProps}
+ />
);
}
diff --git a/src/theme/SearchBar/index.js b/src/theme/SearchBar/index.js
index 2601f93..bc7ab4e 100644
--- a/src/theme/SearchBar/index.js
+++ b/src/theme/SearchBar/index.js
@@ -3,24 +3,7 @@ import {createPortal} from 'react-dom';
import {useLocation} from '@docusaurus/router';
import useIsBrowser from '@docusaurus/useIsBrowser';
import OriginalSearchBar from '@theme-original/SearchBar';
-
-function SearchIcon() {
- return (
-
- );
-}
+import {Search} from 'lucide-react';
function SearchModal({onClose, children}) {
const overlayRef = useRef(null);
@@ -111,7 +94,7 @@ export default function SearchBarWrapper(props) {
onClick={() => setIsOpen(true)}
type="button"
aria-label="Search">
-
+
Search
{isMac ? '⌘' : 'Ctrl'}
diff --git a/src/theme/TOCCollapsible/CollapseButton/index.js b/src/theme/TOCCollapsible/CollapseButton/index.js
index 9588855..51e4855 100644
--- a/src/theme/TOCCollapsible/CollapseButton/index.js
+++ b/src/theme/TOCCollapsible/CollapseButton/index.js
@@ -1,6 +1,7 @@
import React from 'react';
import clsx from 'clsx';
import Translate from '@docusaurus/Translate';
+import {ChevronDown} from 'lucide-react';
import styles from './styles.module.css';
export default function TOCCollapsibleCollapseButton({collapsed, ...props}) {
@@ -22,6 +23,11 @@ export default function TOCCollapsibleCollapseButton({collapsed, ...props}) {
On this page
+
);
}
diff --git a/src/theme/TOCCollapsible/CollapseButton/styles.module.css b/src/theme/TOCCollapsible/CollapseButton/styles.module.css
index 09e1501..1365aa9 100644
--- a/src/theme/TOCCollapsible/CollapseButton/styles.module.css
+++ b/src/theme/TOCCollapsible/CollapseButton/styles.module.css
@@ -12,7 +12,6 @@
align-items: center;
padding: 0.4rem 0.8rem;
width: 100%;
- /* Chevron uses `currentColor` in ::after — match sidebar caret */
color: var(--color-neutral-400);
}
@@ -20,28 +19,14 @@
color: var(--ifm-font-color-base);
}
-/* Match sidebar `.menu__caret::before`: same SVG mask, no bitmap background */
-.tocCollapsibleButton::after {
- content: "";
+.tocCollapsibleChevron {
flex-shrink: 0;
- width: 1.25rem;
- height: 1.25rem;
- background: none;
- background-color: currentColor;
- mask-image: var(--ifm-menu-link-sublist-icon);
- mask-repeat: no-repeat;
- mask-position: center;
- mask-size: contain;
- -webkit-mask-image: var(--ifm-menu-link-sublist-icon);
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-position: center;
- -webkit-mask-size: contain;
+ color: currentColor;
transform: rotate(180deg);
transition: transform var(--ifm-transition-fast)
var(--ifm-transition-timing-default);
- filter: none;
}
-.tocCollapsibleButtonExpanded::after {
+.tocCollapsibleButtonExpanded .tocCollapsibleChevron {
transform: none;
}
diff --git a/src/utils/sidebarIcons.js b/src/utils/sidebarIcons.js
new file mode 100644
index 0000000..e5ded46
--- /dev/null
+++ b/src/utils/sidebarIcons.js
@@ -0,0 +1,60 @@
+import {
+ BookOpen,
+ Network,
+ BrainCircuit,
+ Rocket,
+ Layers,
+ Sparkles,
+ LibraryBig,
+ Wrench,
+ Bot,
+ ShieldCheck,
+ Lock,
+ KeyRound,
+ Link,
+ Globe,
+ Plug,
+ Route,
+ Coins,
+ Target,
+ Gauge,
+ MessageSquareText,
+ FlaskConical,
+ Fingerprint,
+ Activity,
+ ClipboardList,
+ Handshake,
+ Hash,
+} from "lucide-react";
+
+const iconMap = {
+ BookOpen,
+ Network,
+ BrainCircuit,
+ Rocket,
+ Layers,
+ Sparkles,
+ LibraryBig,
+ Wrench,
+ Bot,
+ ShieldCheck,
+ Lock,
+ KeyRound,
+ Link,
+ Globe,
+ Plug,
+ Route,
+ Coins,
+ Target,
+ Gauge,
+ MessageSquareText,
+ FlaskConical,
+ Fingerprint,
+ Activity,
+ ClipboardList,
+ Handshake,
+};
+
+export function getSidebarIcon(name) {
+ return iconMap[name] ?? Hash;
+}