From 453331c629cfb22aed42876a88eb0d2ce16c8f44 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Sun, 1 Feb 2026 10:44:36 +0000 Subject: docs: replace emojis with icon in category names --- docs/src/theme/DocSidebarItem/Category/index.tsx | 270 +++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 docs/src/theme/DocSidebarItem/Category/index.tsx (limited to 'docs/src/theme') diff --git a/docs/src/theme/DocSidebarItem/Category/index.tsx b/docs/src/theme/DocSidebarItem/Category/index.tsx new file mode 100644 index 00000000..9426a026 --- /dev/null +++ b/docs/src/theme/DocSidebarItem/Category/index.tsx @@ -0,0 +1,270 @@ +import React, { + type ComponentProps, + type ReactNode, + useEffect, + useMemo, +} from 'react'; +import clsx from 'clsx'; +import { + ThemeClassNames, + useThemeConfig, + usePrevious, + Collapsible, + useCollapsible, +} from '@docusaurus/theme-common'; +import {isSamePath} from '@docusaurus/theme-common/internal'; +import { + isActiveSidebarItem, + findFirstSidebarItemLink, + useDocSidebarItemsExpandedState, +} from '@docusaurus/plugin-content-docs/client'; +import Link from '@docusaurus/Link'; +import {translate} from '@docusaurus/Translate'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import DocSidebarItems from '@theme/DocSidebarItems'; +import type {Props} from '@theme/DocSidebarItem/Category'; +import { + Rocket, + Package, + Settings, + BookOpen, + Plug, + Wrench, + Users, + Code, + type LucideIcon, +} from 'lucide-react'; + +// Map category labels to Lucide icons +const categoryIcons: Record = { + 'Getting Started': Rocket, + 'Installation': Package, + 'Configuration': Settings, + 'Using Karakeep': BookOpen, + 'Integrations': Plug, + 'Administration': Wrench, + 'Community': Users, + 'Development': Code, + 'API': Code, +}; + +// If we navigate to a category and it becomes active, it should automatically +// expand itself +function useAutoExpandActiveCategory({ + isActive, + collapsed, + updateCollapsed, +}: { + isActive: boolean; + collapsed: boolean; + updateCollapsed: (b: boolean) => void; +}) { + const wasActive = usePrevious(isActive); + useEffect(() => { + const justBecameActive = isActive && !wasActive; + if (justBecameActive && collapsed) { + updateCollapsed(false); + } + }, [isActive, wasActive, collapsed, updateCollapsed]); +} + +/** + * When a collapsible category has no link, we still link it to its first child + * during SSR as a temporary fallback. This allows to be able to navigate inside + * the category even when JS fails to load, is delayed or simply disabled + * React hydration becomes an optional progressive enhancement + * see https://github.com/facebookincubator/infima/issues/36#issuecomment-772543188 + * see https://github.com/facebook/docusaurus/issues/3030 + */ +function useCategoryHrefWithSSRFallback( + item: Props['item'], +): string | undefined { + const isBrowser = useIsBrowser(); + return useMemo(() => { + if (item.href && !item.linkUnlisted) { + return item.href; + } + // In these cases, it's not necessary to render a fallback + // We skip the "findFirstCategoryLink" computation + if (isBrowser || !item.collapsible) { + return undefined; + } + return findFirstSidebarItemLink(item); + }, [item, isBrowser]); +} + +function CollapseButton({ + collapsed, + categoryLabel, + onClick, +}: { + collapsed: boolean; + categoryLabel: string; + onClick: ComponentProps<'button'>['onClick']; +}) { + return ( +