@docubook/flame 1.5.2 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,13 +36,39 @@ export default function Menu({ onNavigate, className = "", pathname, routes = []
36
36
  if (!currentPath.startsWith("/docs")) return null;
37
37
 
38
38
  const mode = docuConfig.sidebar?.context || "dropdown";
39
+ const navProps = {
40
+ "aria-label": "Documentation navigation" as const,
41
+ className: cn("transition-all duration-200", className),
42
+ };
39
43
 
40
- // Helper: check if a sublink under a given route matches the current path
41
- const isItemActive = (itemHref: string, parentRouteHref: string) => {
42
- const fullHref = `/docs${parentRouteHref}${itemHref}`;
43
- return currentPath === fullHref || currentPath === `${fullHref}.html`;
44
+ // Shared nav item with border-left overlap wrapper
45
+ const renderBorderItem = (item: DocuRoute, parentRouteHref: string, key: string) => {
46
+ const fullHref = `/docs${parentRouteHref}${item.href}`;
47
+ const isActive = currentPath === fullHref || currentPath === `${fullHref}.html`;
48
+ return (
49
+ <li key={key}>
50
+ <div
51
+ className={cn(
52
+ "-ml-[14px] border-l-2",
53
+ isActive ? "border-primary" : "border-transparent"
54
+ )}
55
+ >
56
+ <div className="pl-3">
57
+ <Sublink
58
+ {...item}
59
+ href={item.href}
60
+ level={0}
61
+ onNavigate={onNavigate}
62
+ parentHref={`/docs${parentRouteHref}`}
63
+ />
64
+ </div>
65
+ </div>
66
+ </li>
67
+ );
44
68
  };
45
69
 
70
+ const sharedUlClasses = "border-base-300 flex flex-col gap-0.5 border-l-2 pb-0.5 pl-3 pt-0.5";
71
+
46
72
  // Separator mode: render all context sections as group headers + nav items
47
73
  if (mode === "separator") {
48
74
  const contextRoutes = menuRoutes.filter((r) => r.context);
@@ -50,62 +76,24 @@ export default function Menu({ onNavigate, className = "", pathname, routes = []
50
76
  // No context routes defined — fall back to flat list of all routes
51
77
  if (contextRoutes.length === 0) {
52
78
  return (
53
- <nav
54
- aria-label="Documentation navigation"
55
- className={cn("transition-all duration-200", className)}
56
- >
57
- <ul className="flex flex-col gap-0.5 py-4">
58
- {menuRoutes.map((route) => (
59
- <li key={route.href}>
60
- <Sublink
61
- {...route}
62
- href={route.href}
63
- level={0}
64
- onNavigate={onNavigate}
65
- parentHref="/docs"
66
- />
67
- </li>
68
- ))}
79
+ <nav {...navProps}>
80
+ <ul className={sharedUlClasses}>
81
+ {menuRoutes.map((route) => renderBorderItem(route, "", route.href))}
69
82
  </ul>
70
83
  </nav>
71
84
  );
72
85
  }
73
86
 
74
87
  return (
75
- <nav
76
- aria-label="Documentation navigation"
77
- className={cn("transition-all duration-200", className)}
78
- >
88
+ <nav {...navProps}>
79
89
  {contextRoutes.map((route, i) => (
80
90
  <div key={route.href} className={i > 0 ? "mt-6 lg:mt-8" : ""}>
81
91
  <SidebarGroupHeader
82
92
  icon={route.context?.icon}
83
93
  title={route.context?.title || route.title}
84
94
  />
85
- <ul className="border-base-300 flex flex-col gap-0.5 border-l-2 pb-0.5 pl-3 pt-0.5">
86
- {route.items?.map((item) => {
87
- const isActive = isItemActive(item.href, route.href);
88
- return (
89
- <li key={item.href}>
90
- <div
91
- className={cn(
92
- "-ml-[14px] border-l-2",
93
- isActive ? "border-primary" : "border-transparent"
94
- )}
95
- >
96
- <div className="pl-3">
97
- <Sublink
98
- {...item}
99
- href={item.href}
100
- level={0}
101
- onNavigate={onNavigate}
102
- parentHref={`/docs${route.href}`}
103
- />
104
- </div>
105
- </div>
106
- </li>
107
- );
108
- })}
95
+ <ul className={sharedUlClasses}>
96
+ {route.items?.map((item) => renderBorderItem(item, route.href, item.href))}
109
97
  </ul>
110
98
  </div>
111
99
  ))}
@@ -131,10 +119,7 @@ export default function Menu({ onNavigate, className = "", pathname, routes = []
131
119
  if (!contextRoute) return null;
132
120
 
133
121
  return (
134
- <nav
135
- aria-label="Documentation navigation"
136
- className={cn("transition-all duration-200", className)}
137
- >
122
+ <nav {...navProps}>
138
123
  <ul className="flex flex-col gap-0.5 py-4">
139
124
  <li key={contextRoute.title}>
140
125
  <Sublink
@@ -2,6 +2,7 @@ import type { ReactNode } from "react";
2
2
  import { useState } from "react";
3
3
  import Anchor from "./Anchor";
4
4
  import { cn } from "../node/utils";
5
+ import { config as docuConfig } from "../node/client-routes";
5
6
  import {
6
7
  Navbar as BaseNavbar,
7
8
  Logo as BaseLogo,
@@ -172,7 +173,7 @@ export function NavbarBrand({
172
173
  }
173
174
 
174
175
  export function GitHubLink({ repoUrl }: { repoUrl?: string }) {
175
- if (!repoUrl) return null;
176
+ if (!docuConfig.repo?.edit || !repoUrl) return null;
176
177
 
177
178
  return (
178
179
  <a
@@ -5,6 +5,7 @@ import { ChevronDown } from "lucide-react";
5
5
  import Anchor from "./Anchor";
6
6
  import type { DocuRoute } from "../node/types";
7
7
  import { cn, docsHtmlHref } from "../node/utils";
8
+ import { config as docuConfig } from "../node/client-routes";
8
9
 
9
10
  interface SublinkProps extends DocuRoute {
10
11
  level: number;
@@ -34,7 +35,7 @@ export default function Sublink({
34
35
  });
35
36
 
36
37
  // Shared padding based on nesting level
37
- const levelPadding = cn(level === 1 && "pl-2", level === 2 && "pl-4", level >= 3 && "pl-6");
38
+ const levelPadding = cn(level === 1 && "pl-4", level === 2 && "pl-8", level >= 3 && "pl-12");
38
39
  const isActive = currentPathname === fullHref || currentPathname === `${fullHref}.html`;
39
40
  const activeRef = useRef<HTMLDivElement>(null);
40
41
 
@@ -58,16 +59,49 @@ export default function Sublink({
58
59
  </Anchor>
59
60
  );
60
61
 
62
+ // Level 0: border handled by Menu.tsx wrapper
63
+ // Level 1+: border at natural indented position, follows levelPadding
64
+ if (level >= 1) {
65
+ // Separator mode: active border overlaps at ul's edge
66
+ // Each parent section adds its levelPadding to the offset
67
+ if (docuConfig.sidebar?.context === "separator") {
68
+ // Calculate accumulated offset from ul's edge to this item's natural position
69
+ // Base: ul border(2px) + pl-3(12px) = 14px
70
+ // Each parent section adds: level 1→16px, level 2→32px, level 3+→48px
71
+ const sectionOffsets: Record<number, number> = { 1: 16, 2: 32 };
72
+ let overlap = 14;
73
+ for (let l = 1; l < level; l++) {
74
+ overlap += sectionOffsets[l] ?? 48;
75
+ }
76
+
77
+ return (
78
+ <div
79
+ ref={activeRef}
80
+ className={cn("border-l-2", isActive ? "border-primary" : "border-transparent")}
81
+ style={{ marginLeft: `-${overlap}px` }}
82
+ >
83
+ <div className={cn("py-1 pl-3", levelPadding)}>{link}</div>
84
+ </div>
85
+ );
86
+ }
87
+
88
+ return (
89
+ <div
90
+ ref={activeRef}
91
+ className={cn(
92
+ "py-1",
93
+ levelPadding,
94
+ "border-l-2",
95
+ isActive ? "border-primary" : "border-base-300"
96
+ )}
97
+ >
98
+ {link}
99
+ </div>
100
+ );
101
+ }
102
+
61
103
  return (
62
- <div
63
- ref={activeRef}
64
- className={cn(
65
- "py-1",
66
- levelPadding,
67
- level >= 2 && "border-l-2",
68
- level >= 2 && (isActive ? "border-primary" : "border-base-300")
69
- )}
70
- >
104
+ <div ref={activeRef} className={cn("py-1", levelPadding)}>
71
105
  {link}
72
106
  </div>
73
107
  );
@@ -2,7 +2,7 @@ import { PropsWithChildren } from "react";
2
2
 
3
3
  export function Typography({ children }: PropsWithChildren) {
4
4
  return (
5
- <div className="prose prose-zinc dark:prose-invert prose-code:font-code dark:prose-code:bg-stone-900/25 prose-code:bg-stone-50 prose-pre:bg-background max-lg:prose-headings:scroll-mt-54 prose-headings:scroll-mt-4 prose-code:text-sm prose-code:leading-6 dark:prose-code:text-white prose-code:text-stone-800 prose-code:p-1 prose-code:rounded-md prose-code:border prose-img:rounded-md prose-img:border prose-code:before:content-none prose-code:after:content-none prose-code:px-1.5 prose-code:overflow-x-auto prose-img:my-3 prose-h2:my-4 prose-h2:mt-8 w-[85vw] max-w-[500px]! min-w-full! pt-2 sm:mx-auto sm:w-full">
5
+ <div className="prose prose-zinc dark:prose-invert prose-code:font-code dark:prose-code:bg-stone-900/25 prose-code:bg-stone-50 prose-pre:bg-background max-lg:prose-headings:scroll-mt-54 prose-headings:scroll-mt-4 prose-code:text-sm prose-code:leading-6 dark:prose-code:text-white prose-code:text-stone-800 prose-code:p-1 prose-code:rounded-md prose-code:border prose-img:rounded-md prose-img:border prose-code:before:content-none prose-code:after:content-none prose-code:px-1.5 prose-code:overflow-x-auto prose-img:my-3 prose-h2:my-4 prose-h2:mt-8 max-w-full! w-full pt-2">
6
6
  {children}
7
7
  </div>
8
8
  );
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runBuildCli
3
- } from "./chunk-7J3N2MCP.js";
4
- import "./chunk-QGEFJH47.js";
3
+ } from "./chunk-NYCIAZTI.js";
4
+ import "./chunk-C67LPMQA.js";
5
5
  import "./chunk-EOK6KATZ.js";
6
- import "./chunk-GLOJMRT4.js";
6
+ import "./chunk-GXQB4ETN.js";
7
7
  import "./chunk-J5NMYSBJ.js";
8
8
 
9
9
  // .docu/node/build.deno.ts
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  runBuild,
3
3
  runBuildCli
4
- } from "./chunk-7J3N2MCP.js";
5
- import "./chunk-QGEFJH47.js";
4
+ } from "./chunk-NYCIAZTI.js";
5
+ import "./chunk-C67LPMQA.js";
6
6
  import "./chunk-EOK6KATZ.js";
7
- import "./chunk-GLOJMRT4.js";
7
+ import "./chunk-GXQB4ETN.js";
8
8
  import "./chunk-J5NMYSBJ.js";
9
9
  export {
10
10
  runBuild,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runBuildCli
3
- } from "./chunk-7J3N2MCP.js";
4
- import "./chunk-QGEFJH47.js";
3
+ } from "./chunk-NYCIAZTI.js";
4
+ import "./chunk-C67LPMQA.js";
5
5
  import "./chunk-EOK6KATZ.js";
6
- import "./chunk-GLOJMRT4.js";
6
+ import "./chunk-GXQB4ETN.js";
7
7
  import "./chunk-J5NMYSBJ.js";
8
8
 
9
9
  // .docu/node/build.node.ts
@@ -14,7 +14,7 @@ import {
14
14
  htmlShell,
15
15
  initSentry,
16
16
  loadPlugins
17
- } from "./chunk-QGEFJH47.js";
17
+ } from "./chunk-C67LPMQA.js";
18
18
  import {
19
19
  SECURITY_HEADERS,
20
20
  generateNonce,
@@ -27,7 +27,7 @@ import {
27
27
  } from "./chunk-EOK6KATZ.js";
28
28
  import {
29
29
  logger
30
- } from "./chunk-GLOJMRT4.js";
30
+ } from "./chunk-GXQB4ETN.js";
31
31
  import {
32
32
  DIST_DIR,
33
33
  DOCS_DIR,