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