boltdocs 2.7.10 → 2.8.0
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.
- package/README.md +2 -2
- package/dist/banner-3N4Jd_L9.d.ts +100 -0
- package/dist/banner-MynZD_Ox.d.cts +100 -0
- package/dist/cache-BMUyNiiA.mjs +6 -0
- package/dist/cache-CKm45d2w.cjs +6 -0
- package/dist/client/index.cjs +2268 -1
- package/dist/client/index.d.cts +86 -110
- package/dist/client/index.d.ts +87 -111
- package/dist/client/index.js +2214 -1
- package/dist/client/mdx.cjs +12 -1
- package/dist/client/mdx.d.cts +39 -93
- package/dist/client/mdx.d.ts +38 -93
- package/dist/client/mdx.js +7 -1
- package/dist/client/primitives.cjs +60 -1
- package/dist/client/primitives.d.cts +411 -347
- package/dist/client/primitives.d.ts +411 -347
- package/dist/client/primitives.js +20 -1
- package/dist/docs-layout-CwCq42Zt.cjs +1348 -0
- package/dist/docs-layout-Dn6S5g59.js +1167 -0
- package/dist/doctor-BArviV8X.cjs +28 -0
- package/dist/doctor-CgLA7_Uv.mjs +28 -0
- package/dist/{doctor-CrytFkqW.cjs → doctor-DyNUVe96.cjs} +1 -1
- package/dist/{routes-DP1vmWRj.cjs → doctor-aN_leTbh.mjs} +1 -1
- package/dist/{generator-ClVanhvi.mjs → generator-BHCrLU6h.mjs} +2 -2
- package/dist/{generator-CHqxiQhF.cjs → generator-CC2yHzhZ.cjs} +2 -2
- package/dist/icons-dev-DvJ-hh9x.cjs +1209 -0
- package/dist/icons-dev-Oju24Wjp.js +845 -0
- package/dist/image-Ch4-GxdO.cjs +268 -0
- package/dist/image-Do8V9PCW.js +214 -0
- package/dist/mdx-D3A2_l7P.js +520 -0
- package/dist/mdx-PLhhPJRS.cjs +531 -0
- package/dist/node/cli-entry.cjs +3 -1
- package/dist/node/cli-entry.mjs +3 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +258 -152
- package/dist/node/index.d.mts +258 -150
- package/dist/node/index.mjs +1 -1
- package/dist/node/routes/worker.cjs +1 -1
- package/dist/node/routes/worker.mjs +1 -1
- package/dist/node-BmlP0eBP.cjs +159 -0
- package/dist/node-Y8_4ayje.mjs +159 -0
- package/dist/package-2nFy_NsW.cjs +6 -0
- package/dist/{package--0Yf0t1N.mjs → package-DAbtltXX.mjs} +1 -1
- package/dist/parser-B7-6PyQz.cjs +6 -0
- package/dist/{parser-Aq8LoH-0.cjs → parser-BzB-zCkF.cjs} +1 -1
- package/dist/parser-WGZdWs0X.mjs +6 -0
- package/dist/routes-BDDSxAl0.mjs +6 -0
- package/dist/routes-DJNJ-rTt.cjs +6 -0
- package/dist/routes-DiYC4nD2.cjs +6 -0
- package/dist/routes-_Bb2f4eI.mjs +6 -0
- package/dist/search-dialog-BXVoecTx.cjs +483 -0
- package/dist/search-dialog-BYhOov4S.cjs +331 -0
- package/dist/search-dialog-C09riYmx.js +313 -0
- package/dist/search-dialog-CUeAfy-8.cjs +8 -0
- package/dist/search-dialog-D8gLkhUV.js +453 -0
- package/dist/search-dialog-DHc_8FFX.js +8 -0
- package/dist/{sidebar-CcBkrm06.d.cts → sidebar-DNq4_ZAa.d.ts} +118 -52
- package/dist/{sidebar-CyZS9YOm.d.ts → sidebar-Dlkgbxs6.d.cts} +118 -52
- package/dist/utils-BYITg7T5.mjs +7 -0
- package/dist/utils-Cjmx1hhk.cjs +7 -0
- package/dist/worker-pool-CtqklOXq.cjs +6 -0
- package/dist/worker-pool-k0DY6k8T.mjs +6 -0
- package/package.json +5 -6
- package/src/shared/config-utils.ts +4 -0
- package/src/shared/types.ts +52 -6
- package/dist/cache-Ba-DZQNH.cjs +0 -6
- package/dist/cache-BuMZ58L5.mjs +0 -6
- package/dist/cards-BakZPTz9.d.ts +0 -30
- package/dist/cards-CQn9mXZS.d.cts +0 -30
- package/dist/docs-layout-KoWNZc8_.js +0 -6
- package/dist/docs-layout-x2yKt2cL.cjs +0 -6
- package/dist/doctor-Be7Ly1oM.mjs +0 -21
- package/dist/doctor-jMxWZyLJ.cjs +0 -21
- package/dist/icons-dev-B_RZIyxu.js +0 -6
- package/dist/icons-dev-BlV3wWFT.cjs +0 -6
- package/dist/image-BHhTvQzr.cjs +0 -6
- package/dist/image-CqKzYD8f.js +0 -6
- package/dist/mdx-DudBEac0.js +0 -7
- package/dist/mdx-r4cDQxWu.cjs +0 -7
- package/dist/node-DtEDyN1u.cjs +0 -111
- package/dist/node-_1jhMGYx.mjs +0 -111
- package/dist/package-DrwtlXfk.cjs +0 -6
- package/dist/parser-CdNbqN5y.cjs +0 -6
- package/dist/parser-nE792MLO.mjs +0 -6
- package/dist/rolldown-runtime-fkIsjY3S.mjs +0 -6
- package/dist/routes-2k3tbUmC.cjs +0 -6
- package/dist/routes-CpxZIsMM.mjs +0 -6
- package/dist/search-dialog-B584t9ZF.js +0 -6
- package/dist/search-dialog-BvBopRsZ.cjs +0 -6
- package/dist/search-dialog-ByvGScjt.js +0 -6
- package/dist/search-dialog-Cyko6TJm.cjs +0 -6
- package/dist/search-dialog-D6BNohIJ.js +0 -6
- package/dist/search-dialog-DuYTIefy.cjs +0 -6
- package/dist/utils-CG65J0Sc.mjs +0 -7
- package/dist/utils-CKunkU96.cjs +0 -7
- package/dist/worker-pool-CGn7DrLb.mjs +0 -6
- package/dist/worker-pool-Crbqgw5R.cjs +0 -6
- package/src/client/app/config-context.tsx +0 -51
- package/src/client/app/doc-page.tsx +0 -38
- package/src/client/app/docs-layout.tsx +0 -28
- package/src/client/app/head.tsx +0 -122
- package/src/client/app/helmet-compat.tsx +0 -36
- package/src/client/app/mdx-component.tsx +0 -8
- package/src/client/app/mdx-components-context.tsx +0 -72
- package/src/client/app/routes-context.tsx +0 -34
- package/src/client/app/scroll-handler.tsx +0 -74
- package/src/client/app/theme-context.tsx +0 -103
- package/src/client/app/ui-context.tsx +0 -42
- package/src/client/components/docs-layout-default.tsx +0 -85
- package/src/client/components/icons-dev.tsx +0 -282
- package/src/client/components/mdx/callout.tsx +0 -97
- package/src/client/components/mdx/card.tsx +0 -99
- package/src/client/components/mdx/cards.tsx +0 -27
- package/src/client/components/mdx/code-block.tsx +0 -184
- package/src/client/components/mdx/field.tsx +0 -33
- package/src/client/components/mdx/image.tsx +0 -44
- package/src/client/components/mdx/index.ts +0 -19
- package/src/client/components/mdx/table.tsx +0 -54
- package/src/client/components/mdx/typographics.tsx +0 -120
- package/src/client/components/mdx/use-code-block.ts +0 -34
- package/src/client/components/primitives/breadcrumbs.tsx +0 -54
- package/src/client/components/primitives/button-group.tsx +0 -54
- package/src/client/components/primitives/button.tsx +0 -6
- package/src/client/components/primitives/code-block.tsx +0 -120
- package/src/client/components/primitives/docs-layout.tsx +0 -125
- package/src/client/components/primitives/error-boundary.tsx +0 -107
- package/src/client/components/primitives/heading.tsx +0 -128
- package/src/client/components/primitives/helpers/observer.ts +0 -141
- package/src/client/components/primitives/image.tsx +0 -26
- package/src/client/components/primitives/link.tsx +0 -102
- package/src/client/components/primitives/menu.tsx +0 -137
- package/src/client/components/primitives/navbar.tsx +0 -466
- package/src/client/components/primitives/on-this-page.tsx +0 -430
- package/src/client/components/primitives/page-nav.tsx +0 -51
- package/src/client/components/primitives/popover.tsx +0 -28
- package/src/client/components/primitives/search-dialog.tsx +0 -193
- package/src/client/components/primitives/sidebar.tsx +0 -423
- package/src/client/components/primitives/skeleton.tsx +0 -26
- package/src/client/components/primitives/tabs.tsx +0 -70
- package/src/client/components/primitives/tooltip.tsx +0 -81
- package/src/client/components/primitives/types.ts +0 -11
- package/src/client/components/ui-base/banner.tsx +0 -66
- package/src/client/components/ui-base/breadcrumbs.tsx +0 -44
- package/src/client/components/ui-base/copy-markdown.tsx +0 -107
- package/src/client/components/ui-base/error-boundary.tsx +0 -15
- package/src/client/components/ui-base/github-stars.tsx +0 -29
- package/src/client/components/ui-base/icons.tsx +0 -240
- package/src/client/components/ui-base/index.ts +0 -16
- package/src/client/components/ui-base/last-updated.tsx +0 -27
- package/src/client/components/ui-base/navbar.tsx +0 -266
- package/src/client/components/ui-base/not-found.tsx +0 -26
- package/src/client/components/ui-base/on-this-page.tsx +0 -57
- package/src/client/components/ui-base/page-nav.tsx +0 -50
- package/src/client/components/ui-base/search-dialog.tsx +0 -163
- package/src/client/components/ui-base/search-highlight.tsx +0 -10
- package/src/client/components/ui-base/sidebar.tsx +0 -92
- package/src/client/components/ui-base/tabs.tsx +0 -83
- package/src/client/components/ui-base/theme-toggle.tsx +0 -130
- package/src/client/components/ui-base/version-i18n.tsx +0 -80
- package/src/client/hooks/index.ts +0 -13
- package/src/client/hooks/use-analytics.ts +0 -272
- package/src/client/hooks/use-breadcrumbs.ts +0 -22
- package/src/client/hooks/use-i18n.ts +0 -182
- package/src/client/hooks/use-localized-to.ts +0 -113
- package/src/client/hooks/use-location.ts +0 -5
- package/src/client/hooks/use-navbar.ts +0 -130
- package/src/client/hooks/use-page-nav.ts +0 -46
- package/src/client/hooks/use-routes.ts +0 -108
- package/src/client/hooks/use-search-highlight.ts +0 -185
- package/src/client/hooks/use-search.ts +0 -118
- package/src/client/hooks/use-sidebar.ts +0 -205
- package/src/client/hooks/use-tabs.ts +0 -46
- package/src/client/hooks/use-version.ts +0 -111
- package/src/client/index.ts +0 -31
- package/src/client/mdx.ts +0 -2
- package/src/client/primitives.ts +0 -19
- package/src/client/ssg/boltdocs-shell.tsx +0 -148
- package/src/client/ssg/create-routes.tsx +0 -473
- package/src/client/ssg/index.ts +0 -4
- package/src/client/ssg/mdx-page.tsx +0 -38
- package/src/client/store/boltdocs-context.tsx +0 -137
- package/src/client/theme/neutral.css +0 -141
- package/src/client/theme/reset.css +0 -189
- package/src/client/types.ts +0 -116
- package/src/client/utils/cn.ts +0 -6
- package/src/client/utils/copy-clipboard.ts +0 -22
- package/src/client/utils/get-base-file-path.ts +0 -21
- package/src/client/utils/github.ts +0 -121
- package/src/client/utils/i18n.ts +0 -23
- package/src/client/utils/path.ts +0 -9
- package/src/client/utils/react-to-text.ts +0 -34
- package/src/client/virtual.d.ts +0 -24
- /package/dist/{meta-loader-CWg2gnbY.mjs → meta-loader-DzwDFtdT.mjs} +0 -0
|
@@ -0,0 +1,1348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boltdocs - https://boltdocs.vercel.app
|
|
3
|
+
* Copyright (c) 2026 Jesus Alcala
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
const require_icons_dev = require('./icons-dev-DvJ-hh9x.cjs');
|
|
7
|
+
let react = require("react");
|
|
8
|
+
let react_router_dom = require("react-router-dom");
|
|
9
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
+
let react_aria_components = require("react-aria-components");
|
|
11
|
+
react_aria_components = require_icons_dev.__toESM(react_aria_components);
|
|
12
|
+
let virtual_boltdocs_icons = require("virtual:boltdocs-icons");
|
|
13
|
+
virtual_boltdocs_icons = require_icons_dev.__toESM(virtual_boltdocs_icons);
|
|
14
|
+
let scroll_into_view_if_needed = require("scroll-into-view-if-needed");
|
|
15
|
+
scroll_into_view_if_needed = require_icons_dev.__toESM(scroll_into_view_if_needed);
|
|
16
|
+
|
|
17
|
+
//#region src/client/app/ui-context.tsx
|
|
18
|
+
const UIContext = (0, react.createContext)(void 0);
|
|
19
|
+
function UIProvider({ children }) {
|
|
20
|
+
const [isSidebarOpen, setIsSidebarOpen] = (0, react.useState)(false);
|
|
21
|
+
const location = (0, react_router_dom.useLocation)();
|
|
22
|
+
const toggleSidebar = () => setIsSidebarOpen((prev) => !prev);
|
|
23
|
+
const closeSidebar = () => setIsSidebarOpen(false);
|
|
24
|
+
(0, react.useEffect)(() => {
|
|
25
|
+
setIsSidebarOpen(false);
|
|
26
|
+
}, [location.pathname]);
|
|
27
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UIContext.Provider, {
|
|
28
|
+
value: {
|
|
29
|
+
isSidebarOpen,
|
|
30
|
+
toggleSidebar,
|
|
31
|
+
closeSidebar
|
|
32
|
+
},
|
|
33
|
+
children
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function useUI() {
|
|
37
|
+
const context = (0, react.useContext)(UIContext);
|
|
38
|
+
if (context === void 0) return {
|
|
39
|
+
isSidebarOpen: false,
|
|
40
|
+
toggleSidebar: () => {},
|
|
41
|
+
closeSidebar: () => {}
|
|
42
|
+
};
|
|
43
|
+
return context;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/client/components/primitives/breadcrumbs.tsx
|
|
48
|
+
function Breadcrumbs({ children, className, ...props }) {
|
|
49
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Breadcrumbs, {
|
|
50
|
+
className: require_icons_dev.cn("flex flex-wrap items-center", className),
|
|
51
|
+
...props,
|
|
52
|
+
children
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function BreadcrumbsItem({ children, className, ...props }) {
|
|
56
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Breadcrumb, {
|
|
57
|
+
className: require_icons_dev.cn("flex items-center", className),
|
|
58
|
+
...props,
|
|
59
|
+
children
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function BreadcrumbsLink({ children, href, className, ...props }) {
|
|
63
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.Link, {
|
|
64
|
+
href,
|
|
65
|
+
className: require_icons_dev.cn("cursor-pointer", className),
|
|
66
|
+
...props,
|
|
67
|
+
children
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function BreadcrumbsSeparator({ className }) {
|
|
71
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.ChevronRight, {
|
|
72
|
+
size: 14,
|
|
73
|
+
className: require_icons_dev.cn("shrink-0", className)
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
Breadcrumbs.Root = Breadcrumbs;
|
|
77
|
+
Breadcrumbs.Item = BreadcrumbsItem;
|
|
78
|
+
Breadcrumbs.Link = BreadcrumbsLink;
|
|
79
|
+
Breadcrumbs.Separator = BreadcrumbsSeparator;
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/client/components/primitives/button-group.tsx
|
|
83
|
+
function ButtonGroup({ children, className, vertical = false }) {
|
|
84
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
85
|
+
className: require_icons_dev.cn("inline-flex", vertical ? "flex-col" : "flex-row", !vertical && [
|
|
86
|
+
"[&>*:not(:first-child)]:-ml-px",
|
|
87
|
+
"[&>*:first-child]:rounded-r-none",
|
|
88
|
+
"[&>*:last-child]:rounded-l-none",
|
|
89
|
+
"[&>*:not(:first-child):not(:last-child)]:rounded-none",
|
|
90
|
+
className?.includes("rounded-full") && ["[&>*:first-child]:rounded-l-full", "[&>*:last-child]:rounded-r-full"],
|
|
91
|
+
className?.includes("rounded-xl") && ["[&>*:first-child]:rounded-l-xl", "[&>*:last-child]:rounded-r-xl"],
|
|
92
|
+
className?.includes("rounded-lg") && ["[&>*:first-child]:rounded-l-lg", "[&>*:last-child]:rounded-r-lg"]
|
|
93
|
+
], vertical && [
|
|
94
|
+
"[&>*:not(:first-child)]:-mt-px",
|
|
95
|
+
"[&>*:first-child]:rounded-b-none",
|
|
96
|
+
"[&>*:last-child]:rounded-t-none",
|
|
97
|
+
"[&>*:not(:first-child):not(:last-child)]:rounded-none",
|
|
98
|
+
className?.includes("rounded-full") && ["[&>*:first-child]:rounded-t-full", "[&>*:last-child]:rounded-b-full"]
|
|
99
|
+
], className),
|
|
100
|
+
children
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/client/components/primitives/popover.tsx
|
|
106
|
+
/**
|
|
107
|
+
* A reusable Popover primitive with premium glassmorphism styling and smooth animations.
|
|
108
|
+
*/
|
|
109
|
+
function Popover({ children, className, ...props }) {
|
|
110
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Popover, {
|
|
111
|
+
offset: 8,
|
|
112
|
+
className: require_icons_dev.cn("z-50 overflow-auto outline-none transition-none", className),
|
|
113
|
+
...props,
|
|
114
|
+
children
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/client/components/primitives/menu.tsx
|
|
120
|
+
function MenuTrigger({ placement, className, ...props }) {
|
|
121
|
+
const [trigger, menu] = react.Children.toArray(props.children).slice(0, 2);
|
|
122
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_aria_components.MenuTrigger, {
|
|
123
|
+
...props,
|
|
124
|
+
children: [trigger, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Popover, {
|
|
125
|
+
placement,
|
|
126
|
+
className,
|
|
127
|
+
children: menu
|
|
128
|
+
})]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function SubmenuTrigger({ className, ...props }) {
|
|
132
|
+
const [trigger, menu] = react.Children.toArray(props.children).slice(0, 2);
|
|
133
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_aria_components.SubmenuTrigger, {
|
|
134
|
+
...props,
|
|
135
|
+
children: [trigger, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Popover, {
|
|
136
|
+
offset: -4,
|
|
137
|
+
crossOffset: -4,
|
|
138
|
+
className,
|
|
139
|
+
children: menu
|
|
140
|
+
})]
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The Menu container.
|
|
145
|
+
*/
|
|
146
|
+
function Menu(props) {
|
|
147
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Menu, {
|
|
148
|
+
...props,
|
|
149
|
+
className: react_aria_components.composeRenderProps(props.className, (className) => require_icons_dev.cn("outline-none overflow-auto", className))
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* MenuItem with support for selection states and submenus.
|
|
154
|
+
*/
|
|
155
|
+
function MenuItem(props) {
|
|
156
|
+
const textValue = props.textValue || (typeof props.children === "string" ? props.children : void 0);
|
|
157
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.MenuItem, {
|
|
158
|
+
...props,
|
|
159
|
+
textValue,
|
|
160
|
+
className: react_aria_components.composeRenderProps(props.className, (className) => require_icons_dev.cn("group relative flex flex-row items-center cursor-default outline-none", className)),
|
|
161
|
+
children: react_aria_components.composeRenderProps(props.children, (children, { selectionMode, isSelected, hasSubmenu }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
162
|
+
selectionMode === "multiple" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
163
|
+
className: "flex items-center shrink-0 justify-center",
|
|
164
|
+
children: isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.Check, { className: "size-3.5" })
|
|
165
|
+
}),
|
|
166
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
167
|
+
className: "flex flex-row w-full items-center",
|
|
168
|
+
children
|
|
169
|
+
}),
|
|
170
|
+
hasSubmenu && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.ChevronRight, { className: "size-4 ml-auto" })
|
|
171
|
+
] }))
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function MenuSection({ title, ...props }) {
|
|
175
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_aria_components.MenuSection, {
|
|
176
|
+
...props,
|
|
177
|
+
className: require_icons_dev.cn("flex flex-col", props.className),
|
|
178
|
+
children: [title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Header, {
|
|
179
|
+
className: "select-none",
|
|
180
|
+
children: title
|
|
181
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Collection, {
|
|
182
|
+
items: props.items,
|
|
183
|
+
children: props.children
|
|
184
|
+
})]
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* MenuSeparator for visual division.
|
|
189
|
+
*/
|
|
190
|
+
function MenuSeparator(props) {
|
|
191
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Separator, {
|
|
192
|
+
...props,
|
|
193
|
+
className: require_icons_dev.cn("border-t", props.className)
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
Menu.Root = Menu;
|
|
197
|
+
Menu.Item = MenuItem;
|
|
198
|
+
Menu.Trigger = MenuTrigger;
|
|
199
|
+
Menu.SubTrigger = SubmenuTrigger;
|
|
200
|
+
Menu.Section = MenuSection;
|
|
201
|
+
Menu.Separator = MenuSeparator;
|
|
202
|
+
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region src/client/components/primitives/tabs.tsx
|
|
205
|
+
function Tabs({ children, className = "", ...props }) {
|
|
206
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
207
|
+
className: require_icons_dev.cn("w-full", className),
|
|
208
|
+
...props,
|
|
209
|
+
children
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function TabsList({ children, className = "" }) {
|
|
213
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
214
|
+
role: "tablist",
|
|
215
|
+
className: require_icons_dev.cn("relative flex flex-row items-center overflow-x-auto", className),
|
|
216
|
+
children
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
function TabsItem({ children, id, selected, className = "", ...props }) {
|
|
220
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
221
|
+
role: "tab",
|
|
222
|
+
"aria-selected": selected,
|
|
223
|
+
"data-selected": selected,
|
|
224
|
+
className: require_icons_dev.cn("outline-none cursor-pointer bg-transparent border-none", className),
|
|
225
|
+
...props,
|
|
226
|
+
children
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function TabsContent({ children, className = "" }) {
|
|
230
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
231
|
+
className: require_icons_dev.cn("outline-none", className),
|
|
232
|
+
children
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function TabsIndicator({ className = "", style }) {
|
|
236
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
237
|
+
className: require_icons_dev.cn("absolute bottom-0", className),
|
|
238
|
+
style
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
Tabs.Root = Tabs;
|
|
242
|
+
Tabs.List = TabsList;
|
|
243
|
+
Tabs.Item = TabsItem;
|
|
244
|
+
Tabs.Content = TabsContent;
|
|
245
|
+
Tabs.Indicator = TabsIndicator;
|
|
246
|
+
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/client/components/primitives/helpers/observer.ts
|
|
249
|
+
function getItemId(url) {
|
|
250
|
+
if (url.startsWith("#")) return url.slice(1);
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
var Observer = class {
|
|
254
|
+
items = [];
|
|
255
|
+
single = false;
|
|
256
|
+
observer = null;
|
|
257
|
+
timers = [];
|
|
258
|
+
onChange;
|
|
259
|
+
callback(_entries) {
|
|
260
|
+
for (const item of this.items) {
|
|
261
|
+
const element = document.getElementById(item.id);
|
|
262
|
+
if (!element) {
|
|
263
|
+
item.active = false;
|
|
264
|
+
item.fallback = false;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
const rect = element.getBoundingClientRect();
|
|
268
|
+
const viewportHeight = typeof window !== "undefined" ? window.innerHeight : 1e3;
|
|
269
|
+
const isInViewport = rect.bottom > 0 && rect.top < viewportHeight;
|
|
270
|
+
item.active = isInViewport;
|
|
271
|
+
item.fallback = !isInViewport && rect.top > 0 && rect.top < viewportHeight * 2;
|
|
272
|
+
}
|
|
273
|
+
if (this.single) {
|
|
274
|
+
let highlightIdx = -1;
|
|
275
|
+
const visibleItems = this.items.map((item, idx) => ({
|
|
276
|
+
item,
|
|
277
|
+
idx
|
|
278
|
+
})).filter(({ item }) => item.active);
|
|
279
|
+
if (visibleItems.length > 0) highlightIdx = visibleItems[0].idx;
|
|
280
|
+
else {
|
|
281
|
+
const fallbackItems = this.items.map((item, idx) => ({
|
|
282
|
+
item,
|
|
283
|
+
idx
|
|
284
|
+
})).filter(({ item }) => item.fallback);
|
|
285
|
+
if (fallbackItems.length > 0) highlightIdx = fallbackItems[0].idx;
|
|
286
|
+
else if (this.items.length > 0) highlightIdx = 0;
|
|
287
|
+
}
|
|
288
|
+
this.items = this.items.map((item, idx) => ({
|
|
289
|
+
...item,
|
|
290
|
+
active: idx === highlightIdx,
|
|
291
|
+
t: idx === highlightIdx ? Date.now() : item.t
|
|
292
|
+
}));
|
|
293
|
+
} else this.items = this.items.map((item, idx) => ({
|
|
294
|
+
...item,
|
|
295
|
+
active: item.active,
|
|
296
|
+
t: item.active ? Date.now() : item.t
|
|
297
|
+
}));
|
|
298
|
+
this.onChange?.();
|
|
299
|
+
}
|
|
300
|
+
setItems(newItems) {
|
|
301
|
+
const observer = this.observer;
|
|
302
|
+
if (observer) for (const item of this.items) {
|
|
303
|
+
const element = document.getElementById(item.id);
|
|
304
|
+
if (!element) continue;
|
|
305
|
+
observer.unobserve(element);
|
|
306
|
+
}
|
|
307
|
+
this.items = [];
|
|
308
|
+
for (const item of newItems) {
|
|
309
|
+
const id = getItemId(item.url);
|
|
310
|
+
if (!id) continue;
|
|
311
|
+
this.items.push({
|
|
312
|
+
id,
|
|
313
|
+
active: false,
|
|
314
|
+
fallback: false,
|
|
315
|
+
t: 0,
|
|
316
|
+
original: item
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
this.watchItems();
|
|
320
|
+
if (typeof window !== "undefined") {
|
|
321
|
+
this.timers.push(setTimeout(() => this.watchItems(), 100));
|
|
322
|
+
this.timers.push(setTimeout(() => this.watchItems(), 500));
|
|
323
|
+
this.timers.push(setTimeout(() => this.watchItems(), 1e3));
|
|
324
|
+
}
|
|
325
|
+
this.onChange?.();
|
|
326
|
+
}
|
|
327
|
+
watch(options) {
|
|
328
|
+
if (this.observer) return;
|
|
329
|
+
this.observer = new IntersectionObserver(this.callback.bind(this), options);
|
|
330
|
+
this.watchItems();
|
|
331
|
+
}
|
|
332
|
+
watchItems() {
|
|
333
|
+
if (!this.observer) return;
|
|
334
|
+
for (const item of this.items) {
|
|
335
|
+
const element = document.getElementById(item.id);
|
|
336
|
+
if (!element) continue;
|
|
337
|
+
this.observer.observe(element);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
unwatch() {
|
|
341
|
+
for (const timer of this.timers) clearTimeout(timer);
|
|
342
|
+
this.timers = [];
|
|
343
|
+
this.observer?.disconnect();
|
|
344
|
+
this.observer = null;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
//#endregion
|
|
349
|
+
//#region src/client/components/primitives/on-this-page.tsx
|
|
350
|
+
const ItemsContext = (0, react.createContext)(null);
|
|
351
|
+
const ScrollContext = (0, react.createContext)(null);
|
|
352
|
+
function useItems() {
|
|
353
|
+
const ctx = (0, react.use)(ItemsContext);
|
|
354
|
+
if (!ctx) throw new Error(`Component must be used under the <AnchorProvider /> component.`);
|
|
355
|
+
return ctx;
|
|
356
|
+
}
|
|
357
|
+
function useActiveAnchor() {
|
|
358
|
+
const items = useItems();
|
|
359
|
+
return (0, react.useMemo)(() => {
|
|
360
|
+
let out;
|
|
361
|
+
for (const item of items) {
|
|
362
|
+
if (!item.active) continue;
|
|
363
|
+
if (!out || item.t > out.t) out = item;
|
|
364
|
+
}
|
|
365
|
+
return out?.id;
|
|
366
|
+
}, [items]);
|
|
367
|
+
}
|
|
368
|
+
function useActiveAnchors() {
|
|
369
|
+
const items = useItems();
|
|
370
|
+
return (0, react.useMemo)(() => {
|
|
371
|
+
const out = [];
|
|
372
|
+
for (const item of items) if (item.active) out.push(item.id);
|
|
373
|
+
return out;
|
|
374
|
+
}, [items]);
|
|
375
|
+
}
|
|
376
|
+
/** Optional: add auto-scroll to TOC items. */
|
|
377
|
+
function ScrollProvider({ containerRef, children }) {
|
|
378
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollContext.Provider, {
|
|
379
|
+
value: containerRef,
|
|
380
|
+
children
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
function AnchorProvider({ toc, single = false, observerOptions, children }) {
|
|
384
|
+
const observer = (0, react.useMemo)(() => new Observer(), []);
|
|
385
|
+
const [items, setItems] = (0, react.useState)(observer.items);
|
|
386
|
+
observer.single = single;
|
|
387
|
+
(0, react.useEffect)(() => {
|
|
388
|
+
observer.setItems(toc);
|
|
389
|
+
}, [observer, toc]);
|
|
390
|
+
(0, react.useEffect)(() => {
|
|
391
|
+
const defaultOptions = {
|
|
392
|
+
rootMargin: "-80px 0% -60% 0%",
|
|
393
|
+
threshold: 0
|
|
394
|
+
};
|
|
395
|
+
const options = observerOptions ? {
|
|
396
|
+
...defaultOptions,
|
|
397
|
+
...observerOptions
|
|
398
|
+
} : defaultOptions;
|
|
399
|
+
observer.watch(options);
|
|
400
|
+
observer.onChange = () => setItems([...observer.items]);
|
|
401
|
+
return () => {
|
|
402
|
+
observer.unwatch();
|
|
403
|
+
};
|
|
404
|
+
}, [observer]);
|
|
405
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItemsContext.Provider, {
|
|
406
|
+
value: items,
|
|
407
|
+
children
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
function OnThisPage({ children, className }) {
|
|
411
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
|
|
412
|
+
className: require_icons_dev.cn("sticky top-navbar hidden xl:flex flex-col shrink-0", "w-toc", "py-4 pl-6 pr-4", className),
|
|
413
|
+
children
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
function OnThisPageHeader({ children, className, ...props }) {
|
|
417
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
418
|
+
className: require_icons_dev.cn("mb-4 text-xs font-bold text-body", className),
|
|
419
|
+
...props,
|
|
420
|
+
children
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
function OnThisPageContent({ children, className, ref, ...props }) {
|
|
424
|
+
const internalRef = (0, react.useRef)(null);
|
|
425
|
+
(0, react.useImperativeHandle)(ref, () => internalRef.current);
|
|
426
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
427
|
+
ref: internalRef,
|
|
428
|
+
className: require_icons_dev.cn("relative overflow-y-auto boltdocs-otp-content pb-12", "max-h-[70%]", className),
|
|
429
|
+
style: {
|
|
430
|
+
maskImage: "linear-gradient(to bottom, black 90%, transparent 100%)",
|
|
431
|
+
WebkitMaskImage: "linear-gradient(to bottom, black 90%, transparent 100%)"
|
|
432
|
+
},
|
|
433
|
+
...props,
|
|
434
|
+
children
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
OnThisPageContent.displayName = "OnThisPageContent";
|
|
438
|
+
function OnThisPageList({ children, className }) {
|
|
439
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
440
|
+
className: require_icons_dev.cn("relative space-y-0.5 text-sm border-l border-subtle", className),
|
|
441
|
+
children
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
function OnThisPageItem({ level, children, className }) {
|
|
445
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
446
|
+
className: require_icons_dev.cn(level === 3 && "pl-3", className),
|
|
447
|
+
children
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
function OnThisPageLink({ children, href, active, onClick, className }) {
|
|
451
|
+
const items = (0, react.use)(ItemsContext);
|
|
452
|
+
const containerRef = (0, react.use)(ScrollContext);
|
|
453
|
+
const id = href ? getItemId(href) : null;
|
|
454
|
+
const anchorRef = (0, react.useRef)(null);
|
|
455
|
+
const computedActive = active !== void 0 ? active : id && items ? !!items.find((i) => i.id === id)?.active : false;
|
|
456
|
+
(0, react.useEffect)(() => {
|
|
457
|
+
if (computedActive && anchorRef.current && containerRef?.current) (0, scroll_into_view_if_needed.default)(anchorRef.current, {
|
|
458
|
+
behavior: "smooth",
|
|
459
|
+
block: "center",
|
|
460
|
+
inline: "center",
|
|
461
|
+
scrollMode: "if-needed",
|
|
462
|
+
boundary: containerRef.current
|
|
463
|
+
});
|
|
464
|
+
}, [computedActive, containerRef]);
|
|
465
|
+
const handleClick = (e) => {
|
|
466
|
+
if (onClick) onClick(e);
|
|
467
|
+
else if (href && href.startsWith("#")) {
|
|
468
|
+
e.preventDefault();
|
|
469
|
+
const elementId = href.slice(1);
|
|
470
|
+
const el = document.getElementById(elementId);
|
|
471
|
+
if (el) {
|
|
472
|
+
el.scrollIntoView({ behavior: "smooth" });
|
|
473
|
+
window.history.pushState(null, "", href);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
478
|
+
ref: anchorRef,
|
|
479
|
+
href,
|
|
480
|
+
onClick: handleClick,
|
|
481
|
+
"data-active": computedActive,
|
|
482
|
+
className: require_icons_dev.cn("block py-0.5 pl-4 text-[13px] outline-none transition-colors", computedActive ? "text-primary-500" : "text-muted hover:text-body", className),
|
|
483
|
+
children
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
function OnThisPageIndicator({ style, className }) {
|
|
487
|
+
const containerRef = (0, react.useRef)(null);
|
|
488
|
+
const [internalStyle, setInternalStyle] = (0, react.useState)({
|
|
489
|
+
opacity: 0,
|
|
490
|
+
...style
|
|
491
|
+
});
|
|
492
|
+
(0, react.useEffect)(() => {
|
|
493
|
+
const parent = containerRef.current?.parentElement;
|
|
494
|
+
if (!parent) return;
|
|
495
|
+
const activeLinks = parent.querySelectorAll("a[data-active=\"true\"]");
|
|
496
|
+
if (activeLinks.length > 0) {
|
|
497
|
+
const firstActiveLink = activeLinks[0];
|
|
498
|
+
const lastActiveLink = activeLinks[activeLinks.length - 1];
|
|
499
|
+
const firstRect = firstActiveLink.getBoundingClientRect();
|
|
500
|
+
const lastRect = lastActiveLink.getBoundingClientRect();
|
|
501
|
+
const parentRect = parent.getBoundingClientRect();
|
|
502
|
+
const offsetTop = firstRect.top - parentRect.top;
|
|
503
|
+
const height = lastRect.bottom - firstRect.top;
|
|
504
|
+
setInternalStyle({
|
|
505
|
+
transform: `translateY(${offsetTop}px)`,
|
|
506
|
+
height: `${height}px`,
|
|
507
|
+
opacity: 1,
|
|
508
|
+
...style
|
|
509
|
+
});
|
|
510
|
+
} else setInternalStyle({
|
|
511
|
+
opacity: 0,
|
|
512
|
+
...style
|
|
513
|
+
});
|
|
514
|
+
}, [useItems(), style]);
|
|
515
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
516
|
+
ref: containerRef,
|
|
517
|
+
className: require_icons_dev.cn("absolute -left-px w-0.5 rounded-full bg-primary-500", className),
|
|
518
|
+
style: {
|
|
519
|
+
transition: "transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1), height 180ms cubic-bezier(0.2, 0.8, 0.2, 1), opacity 150ms",
|
|
520
|
+
...internalStyle
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* High-level automated list of toc items
|
|
526
|
+
*/
|
|
527
|
+
function OnThisPageItems({ headings = [], className }) {
|
|
528
|
+
const activeIds = useActiveAnchors();
|
|
529
|
+
if (headings.length === 0) return null;
|
|
530
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(OnThisPageList, {
|
|
531
|
+
className,
|
|
532
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(OnThisPageIndicator, {}), headings.map((h) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OnThisPageItem, {
|
|
533
|
+
level: h.level,
|
|
534
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OnThisPageLink, {
|
|
535
|
+
href: `#${h.id}`,
|
|
536
|
+
active: activeIds.includes(h.id),
|
|
537
|
+
children: h.text
|
|
538
|
+
})
|
|
539
|
+
}, h.id))]
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* High-level automated Table of Contents tree
|
|
544
|
+
*/
|
|
545
|
+
function OnThisPageTree({ headings = [], className }) {
|
|
546
|
+
const toc = (0, react.useMemo)(() => headings.map((h) => ({
|
|
547
|
+
title: h.text,
|
|
548
|
+
url: `#${h.id}`,
|
|
549
|
+
depth: h.level
|
|
550
|
+
})), [headings]);
|
|
551
|
+
const scrollContainerRef = (0, react.useRef)(null);
|
|
552
|
+
if (headings.length === 0) return null;
|
|
553
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnchorProvider, {
|
|
554
|
+
toc,
|
|
555
|
+
single: false,
|
|
556
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollProvider, {
|
|
557
|
+
containerRef: scrollContainerRef,
|
|
558
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OnThisPageContent, {
|
|
559
|
+
ref: scrollContainerRef,
|
|
560
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OnThisPageItems, {
|
|
561
|
+
headings,
|
|
562
|
+
className
|
|
563
|
+
})
|
|
564
|
+
})
|
|
565
|
+
})
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
OnThisPage.Root = OnThisPage;
|
|
569
|
+
OnThisPage.Header = OnThisPageHeader;
|
|
570
|
+
OnThisPage.Content = OnThisPageContent;
|
|
571
|
+
OnThisPage.List = OnThisPageList;
|
|
572
|
+
OnThisPage.Item = OnThisPageItem;
|
|
573
|
+
OnThisPage.Link = OnThisPageLink;
|
|
574
|
+
OnThisPage.Indicator = OnThisPageIndicator;
|
|
575
|
+
OnThisPage.Items = OnThisPageItems;
|
|
576
|
+
OnThisPage.Tree = OnThisPageTree;
|
|
577
|
+
|
|
578
|
+
//#endregion
|
|
579
|
+
//#region src/client/components/primitives/page-nav.tsx
|
|
580
|
+
function PageNav({ children, className }) {
|
|
581
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
|
|
582
|
+
className: require_icons_dev.cn("grid sm:grid-cols-2 gap-4", className),
|
|
583
|
+
children
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
function PageNavLink({ children, to, direction, className }) {
|
|
587
|
+
const isNext = direction === "next";
|
|
588
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_icons_dev.Link, {
|
|
589
|
+
href: to,
|
|
590
|
+
className: require_icons_dev.cn("flex items-center outline-none no-underline", isNext ? "justify-end" : "justify-start", className),
|
|
591
|
+
children: [
|
|
592
|
+
!isNext && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.ChevronLeft, { className: "shrink-0" }),
|
|
593
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
594
|
+
className: "flex flex-col flex-1",
|
|
595
|
+
children
|
|
596
|
+
}),
|
|
597
|
+
isNext && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.ChevronRight, { className: "shrink-0" })
|
|
598
|
+
]
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
function PageNavTitle({ children, className }) {
|
|
602
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
603
|
+
className: require_icons_dev.cn(className),
|
|
604
|
+
children
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
function PageNavDescription({ children, className }) {
|
|
608
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
609
|
+
className: require_icons_dev.cn("truncate", className),
|
|
610
|
+
children
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
function PageNavIcon({ children }) {
|
|
614
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
|
|
615
|
+
}
|
|
616
|
+
PageNav.Root = PageNav;
|
|
617
|
+
PageNav.Link = PageNavLink;
|
|
618
|
+
PageNav.Title = PageNavTitle;
|
|
619
|
+
PageNav.Description = PageNavDescription;
|
|
620
|
+
PageNav.Icon = PageNavIcon;
|
|
621
|
+
|
|
622
|
+
//#endregion
|
|
623
|
+
//#region src/client/hooks/use-sidebar.ts
|
|
624
|
+
function useSidebar(routes) {
|
|
625
|
+
const config = require_icons_dev.useConfig();
|
|
626
|
+
const currentPath = require_icons_dev.normalizePath((0, react_router_dom.useLocation)().pathname);
|
|
627
|
+
return (0, react.useMemo)(() => {
|
|
628
|
+
const activeRoute = routes.find((r) => require_icons_dev.normalizePath(r.path) === currentPath);
|
|
629
|
+
const activeTabId = activeRoute?.tab?.toLowerCase();
|
|
630
|
+
const noCollection = routes.filter((r) => !r.collection);
|
|
631
|
+
const filteredRoutes = activeTabId ? noCollection.filter((r) => !r.tab || r.tab.toLowerCase() === activeTabId) : noCollection;
|
|
632
|
+
const directoryMeta = {};
|
|
633
|
+
if (config.directoryMeta) for (const [key, value] of Object.entries(config.directoryMeta)) {
|
|
634
|
+
const cleanKey = key.split("/").filter((part) => !part.startsWith("(") || !part.endsWith(")")).map((part) => part.replace(/^\d+-/, "")).join("/");
|
|
635
|
+
directoryMeta[cleanKey === "" ? "." : cleanKey] = value;
|
|
636
|
+
}
|
|
637
|
+
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1).replace(/-/g, " ");
|
|
638
|
+
const rootNodesMap = /* @__PURE__ */ new Map();
|
|
639
|
+
const ungrouped = [];
|
|
640
|
+
const getOrCreateNode = (parts, rootStore) => {
|
|
641
|
+
let currentMap = rootStore;
|
|
642
|
+
let parentPath = "";
|
|
643
|
+
let lastNode = null;
|
|
644
|
+
for (let i = 0; i < parts.length; i++) {
|
|
645
|
+
const segment = parts[i];
|
|
646
|
+
const currentRelPath = parentPath ? `${parentPath}/${segment}` : segment;
|
|
647
|
+
if (!currentMap.has(segment)) {
|
|
648
|
+
const meta = directoryMeta[currentRelPath] || {};
|
|
649
|
+
const newNode = {
|
|
650
|
+
path: "#",
|
|
651
|
+
title: meta.title || capitalize(segment),
|
|
652
|
+
componentPath: "",
|
|
653
|
+
filePath: "",
|
|
654
|
+
icon: meta.icon,
|
|
655
|
+
groupPosition: typeof meta.order === "number" ? meta.order : 999,
|
|
656
|
+
subRoutes: []
|
|
657
|
+
};
|
|
658
|
+
currentMap.set(segment, newNode);
|
|
659
|
+
}
|
|
660
|
+
lastNode = currentMap.get(segment);
|
|
661
|
+
if (!lastNode._subMap) lastNode._subMap = /* @__PURE__ */ new Map();
|
|
662
|
+
currentMap = lastNode._subMap;
|
|
663
|
+
parentPath = currentRelPath;
|
|
664
|
+
}
|
|
665
|
+
return lastNode;
|
|
666
|
+
};
|
|
667
|
+
const sortedRoutes = [...filteredRoutes].sort((a, b) => {
|
|
668
|
+
return (a.sidebarPosition ?? a.order ?? 999) - (b.sidebarPosition ?? b.order ?? 999);
|
|
669
|
+
});
|
|
670
|
+
for (const route of sortedRoutes) {
|
|
671
|
+
if (route.sidebarHidden) continue;
|
|
672
|
+
const parts = route.slugParts || [];
|
|
673
|
+
const fileName = route.filePath.split("/").pop() || "";
|
|
674
|
+
const isIndex = /^index\.mdx?$/.test(fileName);
|
|
675
|
+
if (parts.length === 0) {
|
|
676
|
+
if (route.filePath) ungrouped.push(route);
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
if (isIndex) {
|
|
680
|
+
const containerNode = getOrCreateNode(parts, rootNodesMap);
|
|
681
|
+
if (containerNode) {
|
|
682
|
+
containerNode.path = route.path;
|
|
683
|
+
containerNode.title = route.title || containerNode.title;
|
|
684
|
+
containerNode.icon = route.icon || containerNode.icon;
|
|
685
|
+
containerNode.badge = route.badge;
|
|
686
|
+
containerNode.sidebarPosition = route.sidebarPosition;
|
|
687
|
+
containerNode.frontmatter = route.frontmatter;
|
|
688
|
+
}
|
|
689
|
+
} else {
|
|
690
|
+
const parentNode = getOrCreateNode(parts, rootNodesMap);
|
|
691
|
+
if (parentNode) parentNode.subRoutes.push(route);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
const finalizeTree = (nodes, currentPathPrefix = "") => {
|
|
695
|
+
nodes.forEach((node) => {
|
|
696
|
+
if (node._subMap) {
|
|
697
|
+
const childDirs = Array.from(node._subMap.values());
|
|
698
|
+
node.subRoutes = [...node.subRoutes || [], ...childDirs];
|
|
699
|
+
delete node._subMap;
|
|
700
|
+
}
|
|
701
|
+
if (node.subRoutes && node.subRoutes.length > 0) node.subRoutes = finalizeTree(node.subRoutes);
|
|
702
|
+
});
|
|
703
|
+
return nodes.sort((a, b) => {
|
|
704
|
+
const posA = a.sidebarPosition ?? a.groupPosition ?? 999;
|
|
705
|
+
const posB = b.sidebarPosition ?? b.groupPosition ?? 999;
|
|
706
|
+
if (posA !== posB) return posA - posB;
|
|
707
|
+
return a.title.localeCompare(b.title);
|
|
708
|
+
});
|
|
709
|
+
};
|
|
710
|
+
const finalizedTopNodes = finalizeTree(Array.from(rootNodesMap.values()));
|
|
711
|
+
finalizedTopNodes.map((node) => {
|
|
712
|
+
return {
|
|
713
|
+
slug: node.title.toLowerCase().replace(/\s+/g, "-"),
|
|
714
|
+
title: node.title,
|
|
715
|
+
icon: node.icon,
|
|
716
|
+
routes: [node]
|
|
717
|
+
};
|
|
718
|
+
});
|
|
719
|
+
return {
|
|
720
|
+
groups: finalizedTopNodes.map((node) => {
|
|
721
|
+
if (node.subRoutes && node.subRoutes.length > 0) return {
|
|
722
|
+
slug: node.title.toLowerCase().replace(/\s+/g, "-"),
|
|
723
|
+
title: node.title,
|
|
724
|
+
icon: node.icon,
|
|
725
|
+
routes: node.subRoutes
|
|
726
|
+
};
|
|
727
|
+
ungrouped.push(node);
|
|
728
|
+
return null;
|
|
729
|
+
}).filter(Boolean),
|
|
730
|
+
ungrouped: finalizeTree(ungrouped),
|
|
731
|
+
activeRoute,
|
|
732
|
+
activePath: currentPath,
|
|
733
|
+
config
|
|
734
|
+
};
|
|
735
|
+
}, [
|
|
736
|
+
routes,
|
|
737
|
+
config,
|
|
738
|
+
currentPath
|
|
739
|
+
]);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
//#endregion
|
|
743
|
+
//#region src/client/components/primitives/sidebar.tsx
|
|
744
|
+
let sidebarScrollPos = 0;
|
|
745
|
+
function getIcon(iconName) {
|
|
746
|
+
if (!iconName) return void 0;
|
|
747
|
+
const icons = {
|
|
748
|
+
...require_icons_dev.icons_exports,
|
|
749
|
+
...virtual_boltdocs_icons.default
|
|
750
|
+
};
|
|
751
|
+
return icons[iconName] || icons[iconName + "Icon"] || void 0;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Internal Badge component for links
|
|
755
|
+
*/
|
|
756
|
+
function Badge({ badge }) {
|
|
757
|
+
const colors = {
|
|
758
|
+
new: "bg-primary-500/10 text-primary-500 border border-primary-500/20",
|
|
759
|
+
updated: "bg-emerald-500/10 text-emerald-500 border border-emerald-500/20",
|
|
760
|
+
deprecated: "bg-danger-500/10 text-danger-500 border border-danger-500/20"
|
|
761
|
+
};
|
|
762
|
+
const text = typeof badge === "string" ? badge : badge?.text;
|
|
763
|
+
if (!text) return null;
|
|
764
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
765
|
+
className: require_icons_dev.cn("ml-auto flex h-5 items-center rounded-md text-[10px] font-bold px-1.5 py-0.5 uppercase tracking-wider", colors[text] || colors.new),
|
|
766
|
+
children: text
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Desktop Sidebar Container
|
|
771
|
+
*/
|
|
772
|
+
function SidebarRoot({ children, className }) {
|
|
773
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
|
|
774
|
+
className: require_icons_dev.cn("hidden lg:flex flex-col w-sidebar sticky top-navbar h-[calc(100vh-var(--spacing-navbar))] border-r border-subtle bg-main", className),
|
|
775
|
+
children
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Mobile Sidebar Modal
|
|
780
|
+
*/
|
|
781
|
+
function SidebarMobile({ children, className }) {
|
|
782
|
+
const { isSidebarOpen, closeSidebar } = useUI();
|
|
783
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.ModalOverlay, {
|
|
784
|
+
isOpen: isSidebarOpen,
|
|
785
|
+
onOpenChange: (open) => !open && closeSidebar(),
|
|
786
|
+
isDismissable: true,
|
|
787
|
+
className: require_icons_dev.cn("fixed inset-0 z-50 bg-black/20 backdrop-blur-sm lg:hidden", "entering:animate-in entering:fade-in exiting:animate-out exiting:fade-out duration-300"),
|
|
788
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Modal, {
|
|
789
|
+
className: require_icons_dev.cn("fixed top-0 left-0 bottom-0 w-80 bg-main border-r border-subtle shadow-2xl outline-none", "entering:animate-in entering:slide-in-from-left exiting:animate-out exiting:slide-out-to-left duration-300", className),
|
|
790
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria_components.Dialog, {
|
|
791
|
+
className: "h-full focus:outline-none outline-none flex flex-col",
|
|
792
|
+
children
|
|
793
|
+
})
|
|
794
|
+
})
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Shared Header for Sidebar
|
|
799
|
+
*/
|
|
800
|
+
function SidebarHeader({ children, className }) {
|
|
801
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
802
|
+
className: require_icons_dev.cn("flex items-center justify-between p-4 border-b border-subtle", className),
|
|
803
|
+
children
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Scrollable Content Wrapper
|
|
808
|
+
*/
|
|
809
|
+
function SidebarContent({ children, className }) {
|
|
810
|
+
const scrollRef = (0, react.useRef)(null);
|
|
811
|
+
(0, react.useLayoutEffect)(() => {
|
|
812
|
+
if (scrollRef.current) scrollRef.current.scrollTop = sidebarScrollPos;
|
|
813
|
+
}, []);
|
|
814
|
+
(0, react.useEffect)(() => {
|
|
815
|
+
const el = scrollRef.current;
|
|
816
|
+
if (!el) return;
|
|
817
|
+
const handleScroll = () => {
|
|
818
|
+
sidebarScrollPos = el.scrollTop;
|
|
819
|
+
};
|
|
820
|
+
el.addEventListener("scroll", handleScroll, { passive: true });
|
|
821
|
+
return () => el.removeEventListener("scroll", handleScroll);
|
|
822
|
+
}, []);
|
|
823
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
824
|
+
ref: scrollRef,
|
|
825
|
+
className: require_icons_dev.cn("flex-1 overflow-y-auto p-4 pb-16 custom-scrollbar", className),
|
|
826
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
|
|
827
|
+
className: "flex flex-col gap-6",
|
|
828
|
+
children
|
|
829
|
+
})
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Navigation Group
|
|
834
|
+
*/
|
|
835
|
+
function SidebarGroup({ title, icon: Icon, children, className }) {
|
|
836
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
837
|
+
className,
|
|
838
|
+
children: [title && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h4", {
|
|
839
|
+
className: "px-2 mb-2 flex items-center gap-2 text-[11px] font-bold uppercase tracking-widest text-muted/50",
|
|
840
|
+
children: [Icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { size: 12 }), title]
|
|
841
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
842
|
+
className: "flex flex-col gap-0.5",
|
|
843
|
+
children
|
|
844
|
+
})]
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
function SidebarLink({ label, href, active, icon: Icon, badge, className }) {
|
|
848
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_icons_dev.Link, {
|
|
849
|
+
href,
|
|
850
|
+
className: require_icons_dev.cn("group flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-sm transition-all outline-none", active ? "bg-primary-500/10 text-primary-500 font-medium shadow-sm" : "text-muted hover:bg-surface hover:text-body", className),
|
|
851
|
+
children: [
|
|
852
|
+
Icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
853
|
+
size: 16,
|
|
854
|
+
className: require_icons_dev.cn(active ? "text-primary-500" : "text-muted group-hover:text-body")
|
|
855
|
+
}),
|
|
856
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
857
|
+
className: "truncate",
|
|
858
|
+
children: label
|
|
859
|
+
}),
|
|
860
|
+
badge && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, { badge })
|
|
861
|
+
]
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Nested SubGroup
|
|
866
|
+
*/
|
|
867
|
+
function SidebarSubGroup({ label, href, active, icon: Icon, badge, isOpen, onToggle, children, className }) {
|
|
868
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
869
|
+
className: "flex flex-col gap-0.5",
|
|
870
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
871
|
+
className: "group relative flex items-center",
|
|
872
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarLink, {
|
|
873
|
+
label,
|
|
874
|
+
href,
|
|
875
|
+
active,
|
|
876
|
+
icon: Icon,
|
|
877
|
+
badge,
|
|
878
|
+
className: require_icons_dev.cn("flex-1 pr-8", className)
|
|
879
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
880
|
+
onClick: (e) => {
|
|
881
|
+
e.preventDefault();
|
|
882
|
+
e.stopPropagation();
|
|
883
|
+
onToggle();
|
|
884
|
+
},
|
|
885
|
+
className: "absolute right-1 p-1.5 text-muted hover:text-body transition-colors outline-none cursor-pointer",
|
|
886
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.ChevronRight, {
|
|
887
|
+
size: 14,
|
|
888
|
+
className: require_icons_dev.cn("transition-transform duration-200", isOpen && "rotate-90")
|
|
889
|
+
})
|
|
890
|
+
})]
|
|
891
|
+
}), isOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
892
|
+
className: "ml-4 pl-3 border-l border-subtle/50 mt-0.5 flex flex-col gap-0.5",
|
|
893
|
+
children
|
|
894
|
+
})]
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
function SidebarItem({ route, activePath, activeRoute, className }) {
|
|
898
|
+
const localizedHref = require_icons_dev.useLocalizedTo(route.path);
|
|
899
|
+
const isCurrent = activePath === (localizedHref.endsWith("/") ? localizedHref.slice(0, -1) : localizedHref) || !!activeRoute?.filePath && !!route.filePath && activeRoute.filePath === route.filePath;
|
|
900
|
+
const hasChildren = !!route.routes?.length || !!route.subRoutes?.length;
|
|
901
|
+
const children = route.routes || route.subRoutes;
|
|
902
|
+
const [isOpen, setIsOpen] = (0, react.useState)(() => activePath.startsWith(localizedHref) || !!activeRoute?.filePath && !!route.filePath && activeRoute.filePath === route.filePath);
|
|
903
|
+
const [prevActivePath, setPrevActivePath] = (0, react.useState)(activePath);
|
|
904
|
+
if (activePath !== prevActivePath) {
|
|
905
|
+
setPrevActivePath(activePath);
|
|
906
|
+
if (activePath.startsWith(localizedHref) || !!activeRoute?.filePath && !!route.filePath && activeRoute.filePath === route.filePath) setIsOpen(true);
|
|
907
|
+
}
|
|
908
|
+
if (hasChildren) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarSubGroup, {
|
|
909
|
+
label: route.title,
|
|
910
|
+
href: route.path,
|
|
911
|
+
active: isCurrent,
|
|
912
|
+
icon: getIcon(route.icon),
|
|
913
|
+
badge: route.badge,
|
|
914
|
+
isOpen,
|
|
915
|
+
onToggle: () => setIsOpen(!isOpen),
|
|
916
|
+
className,
|
|
917
|
+
children: children?.map((subRoute) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarItem, {
|
|
918
|
+
route: subRoute,
|
|
919
|
+
activePath,
|
|
920
|
+
activeRoute
|
|
921
|
+
}, subRoute.path))
|
|
922
|
+
});
|
|
923
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarLink, {
|
|
924
|
+
label: route.title,
|
|
925
|
+
href: route.path,
|
|
926
|
+
active: isCurrent,
|
|
927
|
+
icon: getIcon(route.icon),
|
|
928
|
+
badge: route.badge,
|
|
929
|
+
className
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
function SidebarItems({ routes, className }) {
|
|
933
|
+
const { groups, ungrouped, activePath, activeRoute } = useSidebar(routes);
|
|
934
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
935
|
+
className: require_icons_dev.cn("flex flex-col gap-6", className),
|
|
936
|
+
children: [ungrouped.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarGroup, { children: ungrouped.map((route) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarItem, {
|
|
937
|
+
route,
|
|
938
|
+
activePath,
|
|
939
|
+
activeRoute
|
|
940
|
+
}, route.path)) }), groups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarGroup, {
|
|
941
|
+
title: group.title,
|
|
942
|
+
icon: getIcon(group.icon),
|
|
943
|
+
children: group.routes.map((route) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarItem, {
|
|
944
|
+
route,
|
|
945
|
+
activePath,
|
|
946
|
+
activeRoute
|
|
947
|
+
}, route.path))
|
|
948
|
+
}, group.title))]
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Main Sidebar Export
|
|
953
|
+
*/
|
|
954
|
+
const Sidebar = Object.assign(SidebarRoot, {
|
|
955
|
+
Root: SidebarRoot,
|
|
956
|
+
Mobile: SidebarMobile,
|
|
957
|
+
Header: SidebarHeader,
|
|
958
|
+
Content: SidebarContent,
|
|
959
|
+
Group: SidebarGroup,
|
|
960
|
+
Link: SidebarLink,
|
|
961
|
+
SubGroup: SidebarSubGroup,
|
|
962
|
+
Item: SidebarItem,
|
|
963
|
+
Items: SidebarItems
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
//#endregion
|
|
967
|
+
//#region src/client/hooks/use-location.ts
|
|
968
|
+
const useLocation = () => {
|
|
969
|
+
return (0, react_router_dom.useLocation)();
|
|
970
|
+
};
|
|
971
|
+
|
|
972
|
+
//#endregion
|
|
973
|
+
//#region src/client/hooks/use-search-highlight.ts
|
|
974
|
+
/**
|
|
975
|
+
* Hook to highlight search terms based on the 'hl' query parameter.
|
|
976
|
+
*/
|
|
977
|
+
function useSearchHighlight(containerSelector = ".boltdocs-page") {
|
|
978
|
+
const { search } = useLocation();
|
|
979
|
+
const query = new URLSearchParams(search).get("hl");
|
|
980
|
+
(0, react.useEffect)(() => {
|
|
981
|
+
if (!query) {
|
|
982
|
+
clearHighlights(containerSelector);
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
const container = document.querySelector(containerSelector);
|
|
986
|
+
if (!container) return;
|
|
987
|
+
let rafId;
|
|
988
|
+
const observer = new MutationObserver((mutations) => {
|
|
989
|
+
if (mutations.some((m) => {
|
|
990
|
+
const addedNodes = Array.from(m.addedNodes);
|
|
991
|
+
const removedNodes = Array.from(m.removedNodes);
|
|
992
|
+
return addedNodes.some((n) => !(n instanceof HTMLElement && n.hasAttribute("data-search-highlight"))) || removedNodes.some((n) => !(n instanceof HTMLElement && n.hasAttribute("data-search-highlight")));
|
|
993
|
+
})) run();
|
|
994
|
+
});
|
|
995
|
+
function run() {
|
|
996
|
+
cancelAnimationFrame(rafId);
|
|
997
|
+
rafId = requestAnimationFrame(() => {
|
|
998
|
+
observer.disconnect();
|
|
999
|
+
clearHighlights(containerSelector);
|
|
1000
|
+
const terms = query.split(/\s+/).map((t) => t.trim()).filter((t) => t.length >= 2);
|
|
1001
|
+
if (terms.length > 0) highlightTerms(container, terms);
|
|
1002
|
+
observer.observe(container, {
|
|
1003
|
+
childList: true,
|
|
1004
|
+
subtree: true
|
|
1005
|
+
});
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
run();
|
|
1009
|
+
return () => {
|
|
1010
|
+
cancelAnimationFrame(rafId);
|
|
1011
|
+
observer.disconnect();
|
|
1012
|
+
clearHighlights(containerSelector);
|
|
1013
|
+
};
|
|
1014
|
+
}, [
|
|
1015
|
+
query,
|
|
1016
|
+
search,
|
|
1017
|
+
containerSelector
|
|
1018
|
+
]);
|
|
1019
|
+
}
|
|
1020
|
+
function clearHighlights(selector) {
|
|
1021
|
+
document.querySelectorAll(`${selector} mark[data-search-highlight]`).forEach((mark) => {
|
|
1022
|
+
try {
|
|
1023
|
+
const parent = mark.parentNode;
|
|
1024
|
+
if (parent && parent.contains(mark)) {
|
|
1025
|
+
const text = mark.textContent || "";
|
|
1026
|
+
parent.replaceChild(document.createTextNode(text), mark);
|
|
1027
|
+
}
|
|
1028
|
+
} catch (e) {}
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
function highlightTerms(container, terms) {
|
|
1032
|
+
const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, { acceptNode: (node) => {
|
|
1033
|
+
const parent = node.parentElement;
|
|
1034
|
+
if (parent && (parent.tagName === "SCRIPT" || parent.tagName === "STYLE" || parent.tagName === "MARK" || parent.closest("pre") || parent.closest("code"))) return NodeFilter.FILTER_REJECT;
|
|
1035
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
1036
|
+
} });
|
|
1037
|
+
const nodes = [];
|
|
1038
|
+
let node;
|
|
1039
|
+
while (node = walker.nextNode()) nodes.push(node);
|
|
1040
|
+
const accentMap = {
|
|
1041
|
+
a: "[aáàäâã]",
|
|
1042
|
+
e: "[eéèëê]",
|
|
1043
|
+
i: "[iíìïî]",
|
|
1044
|
+
o: "[oóòöôõ]",
|
|
1045
|
+
u: "[uúùüû]",
|
|
1046
|
+
n: "[nñ]",
|
|
1047
|
+
c: "[cç]"
|
|
1048
|
+
};
|
|
1049
|
+
const prepareRegex = (term) => {
|
|
1050
|
+
let pattern = term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1051
|
+
pattern = pattern.split("").map((char) => {
|
|
1052
|
+
return accentMap[char.toLowerCase()] || char;
|
|
1053
|
+
}).join("");
|
|
1054
|
+
return pattern;
|
|
1055
|
+
};
|
|
1056
|
+
const combinedPattern = terms.map(prepareRegex).join("|");
|
|
1057
|
+
const regex = new RegExp(`(${combinedPattern})`, "gi");
|
|
1058
|
+
const matchRegexes = terms.map((term) => {
|
|
1059
|
+
const p = prepareRegex(term);
|
|
1060
|
+
return new RegExp(`^${p}$`, "i");
|
|
1061
|
+
});
|
|
1062
|
+
nodes.forEach((textNode) => {
|
|
1063
|
+
const text = textNode.textContent;
|
|
1064
|
+
if (text && regex.test(text)) {
|
|
1065
|
+
const fragment = document.createDocumentFragment();
|
|
1066
|
+
text.split(regex).forEach((part) => {
|
|
1067
|
+
if (matchRegexes.some((rx) => rx.test(part))) {
|
|
1068
|
+
const mark = document.createElement("mark");
|
|
1069
|
+
mark.textContent = part;
|
|
1070
|
+
mark.setAttribute("data-search-highlight", "true");
|
|
1071
|
+
fragment.appendChild(mark);
|
|
1072
|
+
} else if (part) fragment.appendChild(document.createTextNode(part));
|
|
1073
|
+
});
|
|
1074
|
+
if (textNode.parentNode) textNode.parentNode.replaceChild(fragment, textNode);
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
//#endregion
|
|
1080
|
+
//#region src/client/components/ui-base/search-highlight.tsx
|
|
1081
|
+
/**
|
|
1082
|
+
* Component that enables search term highlighting on the page.
|
|
1083
|
+
* It doesn't render anything visible.
|
|
1084
|
+
*/
|
|
1085
|
+
function SearchHighlight() {
|
|
1086
|
+
useSearchHighlight(".boltdocs-page");
|
|
1087
|
+
return null;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
//#endregion
|
|
1091
|
+
//#region src/client/components/primitives/docs-layout.tsx
|
|
1092
|
+
/**
|
|
1093
|
+
* Root layout shell. Renders a full-height flex column.
|
|
1094
|
+
*
|
|
1095
|
+
* Usage:
|
|
1096
|
+
* ```tsx
|
|
1097
|
+
* <DocsLayout>
|
|
1098
|
+
* <Navbar />
|
|
1099
|
+
* <DocsLayout.Body>...</DocsLayout.Body>
|
|
1100
|
+
* </DocsLayout>
|
|
1101
|
+
* ```
|
|
1102
|
+
*/
|
|
1103
|
+
function DocsLayoutRoot({ children, className, style }) {
|
|
1104
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1105
|
+
className: require_icons_dev.cn("h-screen flex flex-col overflow-hidden bg-main text-body", className),
|
|
1106
|
+
style,
|
|
1107
|
+
children
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* Horizontal flex container for sidebar + content + toc.
|
|
1112
|
+
*/
|
|
1113
|
+
function Body({ children, className, style }) {
|
|
1114
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1115
|
+
className: require_icons_dev.cn("mx-auto flex flex-1 w-full max-w-(--breakpoint-3xl) bg-main overflow-hidden", className),
|
|
1116
|
+
style,
|
|
1117
|
+
children
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Main scrollable content area.
|
|
1122
|
+
*/
|
|
1123
|
+
function Content({ children, className, style }) {
|
|
1124
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("main", {
|
|
1125
|
+
className: require_icons_dev.cn("boltdocs-content flex-1 min-w-0 overflow-y-auto", "contain-layout", className),
|
|
1126
|
+
style,
|
|
1127
|
+
children
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* MDX Content wrapper with standard page padding and max-width logic.
|
|
1132
|
+
*/
|
|
1133
|
+
function ContentMdx({ children, className, style }) {
|
|
1134
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1135
|
+
className: require_icons_dev.cn("boltdocs-page mx-auto pt-4 pb-20 px-4 sm:px-8", className),
|
|
1136
|
+
style,
|
|
1137
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchHighlight, {}), children]
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Content header area (breadcrumbs, title, description, etc).
|
|
1142
|
+
*/
|
|
1143
|
+
function Header({ children, className, style }) {
|
|
1144
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("header", {
|
|
1145
|
+
className: require_icons_dev.cn("mb-10", className),
|
|
1146
|
+
style,
|
|
1147
|
+
children
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Footer area inside the content section (page nav).
|
|
1152
|
+
*/
|
|
1153
|
+
function Footer({ children, className, style }) {
|
|
1154
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1155
|
+
className: require_icons_dev.cn("mt-20", className),
|
|
1156
|
+
style,
|
|
1157
|
+
children
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
const DocsLayout = Object.assign(DocsLayoutRoot, {
|
|
1161
|
+
Body,
|
|
1162
|
+
Content,
|
|
1163
|
+
ContentMdx,
|
|
1164
|
+
Header,
|
|
1165
|
+
Footer
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
//#endregion
|
|
1169
|
+
Object.defineProperty(exports, 'AnchorProvider', {
|
|
1170
|
+
enumerable: true,
|
|
1171
|
+
get: function () {
|
|
1172
|
+
return AnchorProvider;
|
|
1173
|
+
}
|
|
1174
|
+
});
|
|
1175
|
+
Object.defineProperty(exports, 'Breadcrumbs', {
|
|
1176
|
+
enumerable: true,
|
|
1177
|
+
get: function () {
|
|
1178
|
+
return Breadcrumbs;
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1181
|
+
Object.defineProperty(exports, 'ButtonGroup', {
|
|
1182
|
+
enumerable: true,
|
|
1183
|
+
get: function () {
|
|
1184
|
+
return ButtonGroup;
|
|
1185
|
+
}
|
|
1186
|
+
});
|
|
1187
|
+
Object.defineProperty(exports, 'DocsLayout', {
|
|
1188
|
+
enumerable: true,
|
|
1189
|
+
get: function () {
|
|
1190
|
+
return DocsLayout;
|
|
1191
|
+
}
|
|
1192
|
+
});
|
|
1193
|
+
Object.defineProperty(exports, 'Menu', {
|
|
1194
|
+
enumerable: true,
|
|
1195
|
+
get: function () {
|
|
1196
|
+
return Menu;
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
Object.defineProperty(exports, 'OnThisPage', {
|
|
1200
|
+
enumerable: true,
|
|
1201
|
+
get: function () {
|
|
1202
|
+
return OnThisPage;
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
Object.defineProperty(exports, 'OnThisPageItems', {
|
|
1206
|
+
enumerable: true,
|
|
1207
|
+
get: function () {
|
|
1208
|
+
return OnThisPageItems;
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
Object.defineProperty(exports, 'OnThisPageTree', {
|
|
1212
|
+
enumerable: true,
|
|
1213
|
+
get: function () {
|
|
1214
|
+
return OnThisPageTree;
|
|
1215
|
+
}
|
|
1216
|
+
});
|
|
1217
|
+
Object.defineProperty(exports, 'PageNav', {
|
|
1218
|
+
enumerable: true,
|
|
1219
|
+
get: function () {
|
|
1220
|
+
return PageNav;
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
Object.defineProperty(exports, 'Popover', {
|
|
1224
|
+
enumerable: true,
|
|
1225
|
+
get: function () {
|
|
1226
|
+
return Popover;
|
|
1227
|
+
}
|
|
1228
|
+
});
|
|
1229
|
+
Object.defineProperty(exports, 'ScrollProvider', {
|
|
1230
|
+
enumerable: true,
|
|
1231
|
+
get: function () {
|
|
1232
|
+
return ScrollProvider;
|
|
1233
|
+
}
|
|
1234
|
+
});
|
|
1235
|
+
Object.defineProperty(exports, 'Sidebar', {
|
|
1236
|
+
enumerable: true,
|
|
1237
|
+
get: function () {
|
|
1238
|
+
return Sidebar;
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
Object.defineProperty(exports, 'SidebarContent', {
|
|
1242
|
+
enumerable: true,
|
|
1243
|
+
get: function () {
|
|
1244
|
+
return SidebarContent;
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
Object.defineProperty(exports, 'SidebarGroup', {
|
|
1248
|
+
enumerable: true,
|
|
1249
|
+
get: function () {
|
|
1250
|
+
return SidebarGroup;
|
|
1251
|
+
}
|
|
1252
|
+
});
|
|
1253
|
+
Object.defineProperty(exports, 'SidebarHeader', {
|
|
1254
|
+
enumerable: true,
|
|
1255
|
+
get: function () {
|
|
1256
|
+
return SidebarHeader;
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
Object.defineProperty(exports, 'SidebarItem', {
|
|
1260
|
+
enumerable: true,
|
|
1261
|
+
get: function () {
|
|
1262
|
+
return SidebarItem;
|
|
1263
|
+
}
|
|
1264
|
+
});
|
|
1265
|
+
Object.defineProperty(exports, 'SidebarItems', {
|
|
1266
|
+
enumerable: true,
|
|
1267
|
+
get: function () {
|
|
1268
|
+
return SidebarItems;
|
|
1269
|
+
}
|
|
1270
|
+
});
|
|
1271
|
+
Object.defineProperty(exports, 'SidebarLink', {
|
|
1272
|
+
enumerable: true,
|
|
1273
|
+
get: function () {
|
|
1274
|
+
return SidebarLink;
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
Object.defineProperty(exports, 'SidebarMobile', {
|
|
1278
|
+
enumerable: true,
|
|
1279
|
+
get: function () {
|
|
1280
|
+
return SidebarMobile;
|
|
1281
|
+
}
|
|
1282
|
+
});
|
|
1283
|
+
Object.defineProperty(exports, 'SidebarRoot', {
|
|
1284
|
+
enumerable: true,
|
|
1285
|
+
get: function () {
|
|
1286
|
+
return SidebarRoot;
|
|
1287
|
+
}
|
|
1288
|
+
});
|
|
1289
|
+
Object.defineProperty(exports, 'SidebarSubGroup', {
|
|
1290
|
+
enumerable: true,
|
|
1291
|
+
get: function () {
|
|
1292
|
+
return SidebarSubGroup;
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
Object.defineProperty(exports, 'Tabs', {
|
|
1296
|
+
enumerable: true,
|
|
1297
|
+
get: function () {
|
|
1298
|
+
return Tabs;
|
|
1299
|
+
}
|
|
1300
|
+
});
|
|
1301
|
+
Object.defineProperty(exports, 'UIProvider', {
|
|
1302
|
+
enumerable: true,
|
|
1303
|
+
get: function () {
|
|
1304
|
+
return UIProvider;
|
|
1305
|
+
}
|
|
1306
|
+
});
|
|
1307
|
+
Object.defineProperty(exports, 'useActiveAnchor', {
|
|
1308
|
+
enumerable: true,
|
|
1309
|
+
get: function () {
|
|
1310
|
+
return useActiveAnchor;
|
|
1311
|
+
}
|
|
1312
|
+
});
|
|
1313
|
+
Object.defineProperty(exports, 'useActiveAnchors', {
|
|
1314
|
+
enumerable: true,
|
|
1315
|
+
get: function () {
|
|
1316
|
+
return useActiveAnchors;
|
|
1317
|
+
}
|
|
1318
|
+
});
|
|
1319
|
+
Object.defineProperty(exports, 'useItems', {
|
|
1320
|
+
enumerable: true,
|
|
1321
|
+
get: function () {
|
|
1322
|
+
return useItems;
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
Object.defineProperty(exports, 'useLocation', {
|
|
1326
|
+
enumerable: true,
|
|
1327
|
+
get: function () {
|
|
1328
|
+
return useLocation;
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
1331
|
+
Object.defineProperty(exports, 'useSearchHighlight', {
|
|
1332
|
+
enumerable: true,
|
|
1333
|
+
get: function () {
|
|
1334
|
+
return useSearchHighlight;
|
|
1335
|
+
}
|
|
1336
|
+
});
|
|
1337
|
+
Object.defineProperty(exports, 'useSidebar', {
|
|
1338
|
+
enumerable: true,
|
|
1339
|
+
get: function () {
|
|
1340
|
+
return useSidebar;
|
|
1341
|
+
}
|
|
1342
|
+
});
|
|
1343
|
+
Object.defineProperty(exports, 'useUI', {
|
|
1344
|
+
enumerable: true,
|
|
1345
|
+
get: function () {
|
|
1346
|
+
return useUI;
|
|
1347
|
+
}
|
|
1348
|
+
});
|