aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/docs/01-getting-started/_category_.json2
-rw-r--r--docs/docs/02-installation/_category_.json2
-rw-r--r--docs/docs/03-configuration/_category_.json2
-rw-r--r--docs/docs/04-using-karakeep/_category_.json2
-rw-r--r--docs/docs/05-integrations/_category_.json2
-rw-r--r--docs/docs/06-administration/_category_.json2
-rw-r--r--docs/docs/07-community/_category_.json2
-rw-r--r--docs/docs/08-development/_category_.json2
-rw-r--r--docs/docs/api/_category_.json2
-rw-r--r--docs/docusaurus.config.ts2
-rw-r--r--docs/package.json1
-rw-r--r--docs/sidebars.ts4
-rw-r--r--docs/src/css/custom.css1
-rw-r--r--docs/src/theme/DocSidebarItem/Category/index.tsx270
-rw-r--r--docs/versioned_docs/version-v0.30.0/01-getting-started/_category_.json2
-rw-r--r--docs/versioned_docs/version-v0.30.0/02-installation/_category_.json2
-rw-r--r--docs/versioned_docs/version-v0.30.0/03-configuration/_category_.json2
-rw-r--r--docs/versioned_docs/version-v0.30.0/04-using-karakeep/_category_.json2
-rw-r--r--docs/versioned_docs/version-v0.30.0/05-integrations/_category_.json2
-rw-r--r--docs/versioned_docs/version-v0.30.0/06-administration/_category_.json2
-rw-r--r--docs/versioned_docs/version-v0.30.0/07-community/_category_.json2
-rw-r--r--docs/versioned_docs/version-v0.30.0/08-development/_category_.json2
-rw-r--r--docs/versioned_docs/version-v0.30.0/api/_category_.json2
-rw-r--r--docs/versioned_sidebars/version-v0.30.0-sidebars.json2
-rw-r--r--pnpm-lock.yaml3
25 files changed, 298 insertions, 21 deletions
diff --git a/docs/docs/01-getting-started/_category_.json b/docs/docs/01-getting-started/_category_.json
index 4bfa738a..3562d433 100644
--- a/docs/docs/01-getting-started/_category_.json
+++ b/docs/docs/01-getting-started/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "🚀 Getting Started",
+ "label": "Getting Started",
"position": 1
}
diff --git a/docs/docs/02-installation/_category_.json b/docs/docs/02-installation/_category_.json
index d39d5f24..874082cc 100644
--- a/docs/docs/02-installation/_category_.json
+++ b/docs/docs/02-installation/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "📦 Installation",
+ "label": "Installation",
"position": 3
}
diff --git a/docs/docs/03-configuration/_category_.json b/docs/docs/03-configuration/_category_.json
index ae9f593e..0aea1748 100644
--- a/docs/docs/03-configuration/_category_.json
+++ b/docs/docs/03-configuration/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "⚙️ Configuration",
+ "label": "Configuration",
"position": 4
}
diff --git a/docs/docs/04-using-karakeep/_category_.json b/docs/docs/04-using-karakeep/_category_.json
index 95ef28ea..b0784ea6 100644
--- a/docs/docs/04-using-karakeep/_category_.json
+++ b/docs/docs/04-using-karakeep/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "📖 Using Karakeep",
+ "label": "Using Karakeep",
"position": 2
}
diff --git a/docs/docs/05-integrations/_category_.json b/docs/docs/05-integrations/_category_.json
index e526841b..c2495ffd 100644
--- a/docs/docs/05-integrations/_category_.json
+++ b/docs/docs/05-integrations/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "🔌 Integrations",
+ "label": "Integrations",
"position": 5
}
diff --git a/docs/docs/06-administration/_category_.json b/docs/docs/06-administration/_category_.json
index 9847810a..8998ac56 100644
--- a/docs/docs/06-administration/_category_.json
+++ b/docs/docs/06-administration/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "🛠️ Administration",
+ "label": "Administration",
"position": 6
}
diff --git a/docs/docs/07-community/_category_.json b/docs/docs/07-community/_category_.json
index 265fd50d..6fe06d4a 100644
--- a/docs/docs/07-community/_category_.json
+++ b/docs/docs/07-community/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "👥 Community",
+ "label": "Community",
"position": 7
}
diff --git a/docs/docs/08-development/_category_.json b/docs/docs/08-development/_category_.json
index 5cfb6b1d..3f59497c 100644
--- a/docs/docs/08-development/_category_.json
+++ b/docs/docs/08-development/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "💻 Development",
+ "label": "Development",
"position": 8
}
diff --git a/docs/docs/api/_category_.json b/docs/docs/api/_category_.json
index b493787e..695d9dbe 100644
--- a/docs/docs/api/_category_.json
+++ b/docs/docs/api/_category_.json
@@ -1 +1 @@
-{ "label": "🔗 API", "position": 9 }
+{ "label": "API", "position": 9 }
diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts
index 4bbc208d..db857986 100644
--- a/docs/docusaurus.config.ts
+++ b/docs/docusaurus.config.ts
@@ -42,7 +42,7 @@ const config: Config = {
}) => {
const sidebarItems = await defaultSidebarItemsGenerator(args);
return sidebarItems.filter(
- (item) => !(item.type == "category" && item.label === "🔗 API"),
+ (item) => !(item.type == "category" && item.label === "API"),
);
},
editUrl: "https://github.com/karakeep-app/karakeep/tree/main/docs/",
diff --git a/docs/package.json b/docs/package.json
index d02b5271..713e31fa 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -23,6 +23,7 @@
"clsx": "^2.1.0",
"docusaurus-plugin-openapi-docs": "^4.3.7",
"docusaurus-theme-openapi-docs": "^4.4.0",
+ "lucide-react": "^0.501.0",
"prism-react-renderer": "^2.4.1",
"react": "^19.2.1",
"react-dom": "^19.2.1",
diff --git a/docs/sidebars.ts b/docs/sidebars.ts
index 67337c10..9943e513 100644
--- a/docs/sidebars.ts
+++ b/docs/sidebars.ts
@@ -6,7 +6,9 @@ const sidebars: SidebarsConfig = {
sidebar: [
{ type: "autogenerated", dirName: "." },
{
- "🔗 API": openapiSidebar,
+ type: "category",
+ label: "API",
+ items: openapiSidebar,
},
],
};
diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css
index 9cfc2a44..573d7e39 100644
--- a/docs/src/css/custom.css
+++ b/docs/src/css/custom.css
@@ -593,6 +593,7 @@ li::marker {
/* ============================================
API Docs Specific Styles
============================================ */
+
.api-method > .menu__link {
align-items: center;
justify-content: start;
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<string, LucideIcon> = {
+ '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 (
+ <button
+ aria-label={
+ collapsed
+ ? translate(
+ {
+ id: 'theme.DocSidebarItem.expandCategoryAriaLabel',
+ message: "Expand sidebar category '{label}'",
+ description: 'The ARIA label to expand the sidebar category',
+ },
+ {label: categoryLabel},
+ )
+ : translate(
+ {
+ id: 'theme.DocSidebarItem.collapseCategoryAriaLabel',
+ message: "Collapse sidebar category '{label}'",
+ description: 'The ARIA label to collapse the sidebar category',
+ },
+ {label: categoryLabel},
+ )
+ }
+ aria-expanded={!collapsed}
+ type="button"
+ className="clean-btn menu__caret"
+ onClick={onClick}
+ />
+ );
+}
+
+export default function DocSidebarItemCategory({
+ item,
+ onItemClick,
+ activePath,
+ level,
+ index,
+ ...props
+}: Props): ReactNode {
+ const {items, label, collapsible, className, href} = item;
+ const {
+ docs: {
+ sidebar: {autoCollapseCategories},
+ },
+ } = useThemeConfig();
+ const hrefWithSSRFallback = useCategoryHrefWithSSRFallback(item);
+
+ const isActive = isActiveSidebarItem(item, activePath);
+ const isCurrentPage = isSamePath(href, activePath);
+
+ const {collapsed, setCollapsed} = useCollapsible({
+ // Active categories are always initialized as expanded. The default
+ // (`item.collapsed`) is only used for non-active categories.
+ initialState: () => {
+ if (!collapsible) {
+ return false;
+ }
+ return isActive ? false : item.collapsed;
+ },
+ });
+
+ const {expandedItem, setExpandedItem} = useDocSidebarItemsExpandedState();
+ // Use this instead of `setCollapsed`, because it is also reactive
+ const updateCollapsed = (toCollapsed: boolean = !collapsed) => {
+ setExpandedItem(toCollapsed ? null : index);
+ setCollapsed(toCollapsed);
+ };
+ useAutoExpandActiveCategory({isActive, collapsed, updateCollapsed});
+ useEffect(() => {
+ if (
+ collapsible &&
+ expandedItem != null &&
+ expandedItem !== index &&
+ autoCollapseCategories
+ ) {
+ setCollapsed(true);
+ }
+ }, [collapsible, expandedItem, index, setCollapsed, autoCollapseCategories]);
+
+ return (
+ <li
+ className={clsx(
+ ThemeClassNames.docs.docSidebarItemCategory,
+ ThemeClassNames.docs.docSidebarItemCategoryLevel(level),
+ 'menu__list-item',
+ {
+ 'menu__list-item--collapsed': collapsed,
+ },
+ className,
+ )}>
+ <div
+ className={clsx('menu__list-item-collapsible', {
+ 'menu__list-item-collapsible--active': isCurrentPage,
+ })}>
+ <Link
+ className={clsx('menu__link', {
+ 'menu__link--sublist': collapsible,
+ 'menu__link--sublist-caret': !href && collapsible,
+ 'menu__link--active': isActive,
+ })}
+ onClick={
+ collapsible
+ ? (e) => {
+ onItemClick?.(item);
+ if (href) {
+ // When already on the category's page, we collapse it
+ // We don't use "isActive" because it would collapse the
+ // category even when we browse a children element
+ // See https://github.com/facebook/docusaurus/issues/11213
+ if (isCurrentPage) {
+ e.preventDefault();
+ updateCollapsed();
+ } else {
+ // When navigating to a new category, we always expand
+ // see https://github.com/facebook/docusaurus/issues/10854#issuecomment-2609616182
+ updateCollapsed(false);
+ }
+ } else {
+ e.preventDefault();
+ updateCollapsed();
+ }
+ }
+ : () => {
+ onItemClick?.(item);
+ }
+ }
+ aria-current={isCurrentPage ? 'page' : undefined}
+ role={collapsible && !href ? 'button' : undefined}
+ aria-expanded={collapsible && !href ? !collapsed : undefined}
+ href={collapsible ? hrefWithSSRFallback ?? '#' : hrefWithSSRFallback}
+ {...props}>
+ {(() => {
+ const Icon = categoryIcons[label];
+ if (Icon) {
+ return (
+ <span style={{display: 'flex', alignItems: 'center', gap: '0.625rem'}}>
+ <Icon size={16} strokeWidth={1.5} style={{opacity: 0.6}} />
+ {label}
+ </span>
+ );
+ }
+ return label;
+ })()}
+ </Link>
+ {href && collapsible && (
+ <CollapseButton
+ collapsed={collapsed}
+ categoryLabel={label}
+ onClick={(e) => {
+ e.preventDefault();
+ updateCollapsed();
+ }}
+ />
+ )}
+ </div>
+
+ <Collapsible lazy as="ul" className="menu__list" collapsed={collapsed}>
+ <DocSidebarItems
+ items={items}
+ tabIndex={collapsed ? -1 : 0}
+ onItemClick={onItemClick}
+ activePath={activePath}
+ level={level + 1}
+ />
+ </Collapsible>
+ </li>
+ );
+}
diff --git a/docs/versioned_docs/version-v0.30.0/01-getting-started/_category_.json b/docs/versioned_docs/version-v0.30.0/01-getting-started/_category_.json
index 4bfa738a..3562d433 100644
--- a/docs/versioned_docs/version-v0.30.0/01-getting-started/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/01-getting-started/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "🚀 Getting Started",
+ "label": "Getting Started",
"position": 1
}
diff --git a/docs/versioned_docs/version-v0.30.0/02-installation/_category_.json b/docs/versioned_docs/version-v0.30.0/02-installation/_category_.json
index d39d5f24..874082cc 100644
--- a/docs/versioned_docs/version-v0.30.0/02-installation/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/02-installation/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "📦 Installation",
+ "label": "Installation",
"position": 3
}
diff --git a/docs/versioned_docs/version-v0.30.0/03-configuration/_category_.json b/docs/versioned_docs/version-v0.30.0/03-configuration/_category_.json
index ae9f593e..0aea1748 100644
--- a/docs/versioned_docs/version-v0.30.0/03-configuration/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/03-configuration/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "⚙️ Configuration",
+ "label": "Configuration",
"position": 4
}
diff --git a/docs/versioned_docs/version-v0.30.0/04-using-karakeep/_category_.json b/docs/versioned_docs/version-v0.30.0/04-using-karakeep/_category_.json
index 95ef28ea..b0784ea6 100644
--- a/docs/versioned_docs/version-v0.30.0/04-using-karakeep/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/04-using-karakeep/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "📖 Using Karakeep",
+ "label": "Using Karakeep",
"position": 2
}
diff --git a/docs/versioned_docs/version-v0.30.0/05-integrations/_category_.json b/docs/versioned_docs/version-v0.30.0/05-integrations/_category_.json
index e526841b..c2495ffd 100644
--- a/docs/versioned_docs/version-v0.30.0/05-integrations/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/05-integrations/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "🔌 Integrations",
+ "label": "Integrations",
"position": 5
}
diff --git a/docs/versioned_docs/version-v0.30.0/06-administration/_category_.json b/docs/versioned_docs/version-v0.30.0/06-administration/_category_.json
index 9847810a..8998ac56 100644
--- a/docs/versioned_docs/version-v0.30.0/06-administration/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/06-administration/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "🛠️ Administration",
+ "label": "Administration",
"position": 6
}
diff --git a/docs/versioned_docs/version-v0.30.0/07-community/_category_.json b/docs/versioned_docs/version-v0.30.0/07-community/_category_.json
index 265fd50d..6fe06d4a 100644
--- a/docs/versioned_docs/version-v0.30.0/07-community/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/07-community/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "👥 Community",
+ "label": "Community",
"position": 7
}
diff --git a/docs/versioned_docs/version-v0.30.0/08-development/_category_.json b/docs/versioned_docs/version-v0.30.0/08-development/_category_.json
index 5cfb6b1d..3f59497c 100644
--- a/docs/versioned_docs/version-v0.30.0/08-development/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/08-development/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "💻 Development",
+ "label": "Development",
"position": 8
}
diff --git a/docs/versioned_docs/version-v0.30.0/api/_category_.json b/docs/versioned_docs/version-v0.30.0/api/_category_.json
index b493787e..695d9dbe 100644
--- a/docs/versioned_docs/version-v0.30.0/api/_category_.json
+++ b/docs/versioned_docs/version-v0.30.0/api/_category_.json
@@ -1 +1 @@
-{ "label": "🔗 API", "position": 9 }
+{ "label": "API", "position": 9 }
diff --git a/docs/versioned_sidebars/version-v0.30.0-sidebars.json b/docs/versioned_sidebars/version-v0.30.0-sidebars.json
index a5808711..f887c909 100644
--- a/docs/versioned_sidebars/version-v0.30.0-sidebars.json
+++ b/docs/versioned_sidebars/version-v0.30.0-sidebars.json
@@ -5,7 +5,7 @@
"dirName": "."
},
{
- "🔗 API": [
+ "API": [
{
"type": "doc",
"id": "api/karakeep-api"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 62e8a485..56e9081e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1007,6 +1007,9 @@ importers:
docusaurus-theme-openapi-docs:
specifier: ^4.4.0
version: 4.4.0(@docusaurus/theme-common@3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.2.5)(react@19.2.3))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@types/react@19.2.5)(docusaurus-plugin-openapi-docs@4.4.0(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.2.5)(react@19.2.3))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(@docusaurus/utils-validation@3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@docusaurus/utils@3.9.2(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(encoding@0.1.13)(react@19.2.3))(docusaurus-plugin-sass@0.2.6(@docusaurus/core@3.8.1(@mdx-js/react@3.1.0(@types/react@19.2.5)(react@19.2.3))(acorn@8.15.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(sass@1.89.1)(webpack@5.99.9))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.99.9)
+ lucide-react:
+ specifier: ^0.501.0
+ version: 0.501.0(react@19.2.3)
prism-react-renderer:
specifier: ^2.4.1
version: 2.4.1(react@19.2.3)