@unterberg/nivel 0.1.11 → 0.1.14
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 +5 -13
- package/dist/SearchModal-YJZFUB53.js +335 -0
- package/dist/SearchModal-YJZFUB53.js.map +1 -0
- package/dist/chunk-ESAHWFDZ.js +196 -0
- package/dist/chunk-ESAHWFDZ.js.map +1 -0
- package/dist/{chunk-GT62XN7K.js → chunk-NGX2C26M.js} +12 -22
- package/dist/chunk-NGX2C26M.js.map +1 -0
- package/dist/{chunk-HQHLPFGA.js → chunk-PKXDOKJY.js} +5 -3
- package/dist/{chunk-HQHLPFGA.js.map → chunk-PKXDOKJY.js.map} +1 -1
- package/dist/chunk-PYYPYIBD.js +49 -0
- package/dist/chunk-PYYPYIBD.js.map +1 -0
- package/dist/{chunk-NDJ5LYLK.js → chunk-QWIYQPCW.js} +6 -45
- package/dist/chunk-QWIYQPCW.js.map +1 -0
- package/dist/{chunk-6Q5XESPG.js → chunk-R6O4NLHC.js} +3 -3
- package/dist/{chunk-6TXPHBIC.js → chunk-SH5XWPXW.js} +353 -757
- package/dist/chunk-SH5XWPXW.js.map +1 -0
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +8 -5
- package/dist/config.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -2
- package/dist/mdx/code-blocks.d.ts +1 -1
- package/dist/mdx.js +3 -2
- package/dist/mdx.js.map +1 -1
- package/dist/runtime/client.d.ts +1 -1
- package/dist/runtime/client.js +8 -5
- package/dist/runtime/node.d.ts +1 -1
- package/dist/runtime/node.js +4 -3
- package/dist/{types-BGAec0JI.d.ts → types-IiJ1jLWc.d.ts} +1 -0
- package/dist/vike.d.ts +1 -1
- package/dist/vike.js +249 -4
- package/dist/vike.js.map +1 -1
- package/package.json +6 -7
- package/dist/chunk-6TXPHBIC.js.map +0 -1
- package/dist/chunk-GT62XN7K.js.map +0 -1
- package/dist/chunk-NDJ5LYLK.js.map +0 -1
- /package/dist/{chunk-6Q5XESPG.js.map → chunk-R6O4NLHC.js.map} +0 -0
package/README.md
CHANGED
|
@@ -22,6 +22,8 @@ pnpm add -D vite typescript @types/react @types/react-dom
|
|
|
22
22
|
|
|
23
23
|
`vike` and `vite` are peer dependencies. The package exposes a local `nivel` binary after install.
|
|
24
24
|
|
|
25
|
+
Set `siteUrl` in `pages/+docs.ts` to enable automatic `sitemap.xml` and `robots.txt` generation. V1 includes canonical docs routes from the docs graph plus normal filesystem-routed consumer pages. Consumer routes remapped only through custom `+route.ts` files are not included automatically.
|
|
26
|
+
|
|
25
27
|
## Quick Start
|
|
26
28
|
|
|
27
29
|
Scaffold a consumer:
|
|
@@ -108,6 +110,7 @@ const docsConfig = defineDocsConfig({
|
|
|
108
110
|
graph: docsGraph,
|
|
109
111
|
siteTitle: 'My Docs',
|
|
110
112
|
siteDescription: 'Documentation site powered by @unterberg/nivel.',
|
|
113
|
+
siteUrl: 'https://docs.example.com',
|
|
111
114
|
basePath: '/docs',
|
|
112
115
|
})
|
|
113
116
|
|
|
@@ -117,25 +120,14 @@ export default docsConfig
|
|
|
117
120
|
`pages/+config.ts`
|
|
118
121
|
|
|
119
122
|
```ts
|
|
120
|
-
import
|
|
123
|
+
import { createNivelVikeConfig } from '@unterberg/nivel/vike'
|
|
121
124
|
import type { Config } from 'vike/types'
|
|
122
|
-
import vikeReact from 'vike-react/config'
|
|
123
125
|
import docsConfig from './+docs'
|
|
124
126
|
|
|
125
127
|
export { config }
|
|
126
128
|
|
|
127
|
-
const themePreference = docsConfig.theme?.defaultPreference ?? 'light'
|
|
128
|
-
const dataTheme =
|
|
129
|
-
themePreference === 'dark'
|
|
130
|
-
? (docsConfig.theme?.dark ?? 'consumer-dark')
|
|
131
|
-
: (docsConfig.theme?.light ?? 'consumer-light')
|
|
132
|
-
|
|
133
129
|
const config: Config = {
|
|
134
|
-
...
|
|
135
|
-
extends: [vikeReact],
|
|
136
|
-
title: docsConfig.siteTitle,
|
|
137
|
-
description: docsConfig.siteDescription ?? `${docsConfig.siteTitle} documentation`,
|
|
138
|
-
htmlAttributes: { 'data-theme': dataTheme },
|
|
130
|
+
...createNivelVikeConfig(docsConfig),
|
|
139
131
|
prerender: true,
|
|
140
132
|
}
|
|
141
133
|
```
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LayoutComponent,
|
|
3
|
+
useDocsGlobalContext,
|
|
4
|
+
useDocsSearchActions,
|
|
5
|
+
useDocsSearchStore
|
|
6
|
+
} from "./chunk-ESAHWFDZ.js";
|
|
7
|
+
import {
|
|
8
|
+
withSiteBaseUrl
|
|
9
|
+
} from "./chunk-PYYPYIBD.js";
|
|
10
|
+
|
|
11
|
+
// src/runtime/client/components/SearchModal.tsx
|
|
12
|
+
import { ArrowRightFromLine, MessageCircleQuestion, TriangleAlert } from "lucide-react";
|
|
13
|
+
import { useEffect, useRef, useState } from "react";
|
|
14
|
+
import { createPortal } from "react-dom";
|
|
15
|
+
import { usePageContext } from "vike-react/usePageContext";
|
|
16
|
+
|
|
17
|
+
// src/runtime/client/search.ts
|
|
18
|
+
var hierarchyLevels = ["lvl0", "lvl1", "lvl2", "lvl3", "lvl4", "lvl5", "lvl6"];
|
|
19
|
+
var stripHtml = (value) => value.replace(/<[^>]+>/g, "");
|
|
20
|
+
var normalizeString = (value) => {
|
|
21
|
+
if (typeof value === "string") {
|
|
22
|
+
const normalized = stripHtml(value).replace(/\s+/g, " ").trim();
|
|
23
|
+
return normalized || void 0;
|
|
24
|
+
}
|
|
25
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
26
|
+
return String(value);
|
|
27
|
+
}
|
|
28
|
+
return void 0;
|
|
29
|
+
};
|
|
30
|
+
var getValueAtPath = (value, path) => {
|
|
31
|
+
if (!path) {
|
|
32
|
+
return void 0;
|
|
33
|
+
}
|
|
34
|
+
const segments = path.split(".").filter(Boolean);
|
|
35
|
+
let currentValue = value;
|
|
36
|
+
for (const segment of segments) {
|
|
37
|
+
if (!currentValue || typeof currentValue !== "object" || Array.isArray(currentValue)) {
|
|
38
|
+
return void 0;
|
|
39
|
+
}
|
|
40
|
+
currentValue = currentValue[segment];
|
|
41
|
+
}
|
|
42
|
+
return currentValue;
|
|
43
|
+
};
|
|
44
|
+
var getMappedString = (value, path) => {
|
|
45
|
+
return normalizeString(getValueAtPath(value, path));
|
|
46
|
+
};
|
|
47
|
+
var buildSearchUrl = (appId, indexName) => {
|
|
48
|
+
return `https://${appId}-dsn.algolia.net/1/indexes/${encodeURIComponent(indexName)}/query`;
|
|
49
|
+
};
|
|
50
|
+
var getDocSearchHierarchyValue = (hierarchy, level) => {
|
|
51
|
+
if (!hierarchy || typeof hierarchy !== "object") {
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
return normalizeString(hierarchy[level]);
|
|
55
|
+
};
|
|
56
|
+
var getDocSearchTitleLevel = (hit) => {
|
|
57
|
+
const levelFromType = typeof hit.type === "string" && /^lvl[0-6]$/.test(hit.type) ? hit.type : null;
|
|
58
|
+
if (levelFromType && getDocSearchHierarchyValue(hit.hierarchy, levelFromType)) {
|
|
59
|
+
return levelFromType;
|
|
60
|
+
}
|
|
61
|
+
return [...hierarchyLevels].reverse().find((level) => level !== "lvl0" && getDocSearchHierarchyValue(hit.hierarchy, level));
|
|
62
|
+
};
|
|
63
|
+
var getDocSearchFallbackResult = (hit) => {
|
|
64
|
+
const docSearchHit = hit;
|
|
65
|
+
const titleLevel = getDocSearchTitleLevel(docSearchHit);
|
|
66
|
+
const title = titleLevel ? getDocSearchHierarchyValue(docSearchHit.hierarchy, titleLevel) : void 0;
|
|
67
|
+
const titleLevelIndex = titleLevel ? hierarchyLevels.indexOf(titleLevel) : -1;
|
|
68
|
+
const sectionTitle = hierarchyLevels.slice(0, Math.max(titleLevelIndex, 0)).reverse().map((level) => getDocSearchHierarchyValue(docSearchHit.hierarchy, level)).find(Boolean) ?? normalizeString(docSearchHit.category);
|
|
69
|
+
return {
|
|
70
|
+
href: normalizeString(docSearchHit.url) ?? normalizeString(docSearchHit.url_without_anchor),
|
|
71
|
+
title: title ?? normalizeString(docSearchHit.category),
|
|
72
|
+
excerpt: normalizeString(docSearchHit._snippetResult?.content?.value) ?? normalizeString(docSearchHit.content) ?? normalizeString(docSearchHit._highlightResult?.content?.value),
|
|
73
|
+
sectionTitle
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
var mapHitToSearchResult = (hit, config) => {
|
|
77
|
+
const docSearchFallback = getDocSearchFallbackResult(hit);
|
|
78
|
+
const href = getMappedString(hit, config.fields.href) ?? docSearchFallback.href;
|
|
79
|
+
const title = getMappedString(hit, config.fields.title) ?? docSearchFallback.title;
|
|
80
|
+
if (!href || !title) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const excerpt = getMappedString(hit, config.fields.excerpt) ?? docSearchFallback.excerpt;
|
|
84
|
+
const sectionTitle = getMappedString(hit, config.fields.sectionTitle) ?? docSearchFallback.sectionTitle;
|
|
85
|
+
return {
|
|
86
|
+
href,
|
|
87
|
+
title,
|
|
88
|
+
excerpt,
|
|
89
|
+
sectionTitle
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
var searchAlgoliaIndex = async (options) => {
|
|
93
|
+
const { config, query, signal } = options;
|
|
94
|
+
if (!config) {
|
|
95
|
+
throw new Error("Algolia search is not configured.");
|
|
96
|
+
}
|
|
97
|
+
const response = await fetch(buildSearchUrl(config.appId, config.indexName), {
|
|
98
|
+
method: "POST",
|
|
99
|
+
signal,
|
|
100
|
+
headers: {
|
|
101
|
+
accept: "application/json",
|
|
102
|
+
"content-type": "application/json",
|
|
103
|
+
"x-algolia-api-key": config.apiKey,
|
|
104
|
+
"x-algolia-application-id": config.appId
|
|
105
|
+
},
|
|
106
|
+
body: JSON.stringify({
|
|
107
|
+
query,
|
|
108
|
+
...config.searchParams
|
|
109
|
+
})
|
|
110
|
+
});
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw new Error(`Algolia search request failed with status ${response.status}.`);
|
|
113
|
+
}
|
|
114
|
+
const data = await response.json();
|
|
115
|
+
return (data.hits ?? []).map((hit) => mapHitToSearchResult(hit, config)).filter((result) => result !== null);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// src/runtime/client/components/SearchModal.tsx
|
|
119
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
120
|
+
var MIN_QUERY_LENGTH = 2;
|
|
121
|
+
var QUERY_DEBOUNCE_MS = 150;
|
|
122
|
+
var useDebouncedValue = (value, delayMs) => {
|
|
123
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
const timeoutId = window.setTimeout(() => {
|
|
126
|
+
setDebouncedValue(value);
|
|
127
|
+
}, delayMs);
|
|
128
|
+
return () => {
|
|
129
|
+
window.clearTimeout(timeoutId);
|
|
130
|
+
};
|
|
131
|
+
}, [delayMs, value]);
|
|
132
|
+
return debouncedValue;
|
|
133
|
+
};
|
|
134
|
+
var useSearchResults = (options) => {
|
|
135
|
+
const docs = useDocsGlobalContext();
|
|
136
|
+
const { canSearch, isOpen, normalizedQuery } = options;
|
|
137
|
+
const [results, setResults] = useState([]);
|
|
138
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
139
|
+
const [isError, setIsError] = useState(false);
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
if (!isOpen || !canSearch) {
|
|
142
|
+
setResults([]);
|
|
143
|
+
setIsLoading(false);
|
|
144
|
+
setIsError(false);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const abortController = new AbortController();
|
|
148
|
+
setIsLoading(true);
|
|
149
|
+
setIsError(false);
|
|
150
|
+
searchAlgoliaIndex({
|
|
151
|
+
config: docs.algolia,
|
|
152
|
+
query: normalizedQuery,
|
|
153
|
+
signal: abortController.signal
|
|
154
|
+
}).then((nextResults) => {
|
|
155
|
+
if (abortController.signal.aborted) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
setResults(nextResults);
|
|
159
|
+
}).catch((error) => {
|
|
160
|
+
if (abortController.signal.aborted) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const isAbortError = error instanceof DOMException && error.name === "AbortError";
|
|
164
|
+
if (!isAbortError) {
|
|
165
|
+
setResults([]);
|
|
166
|
+
setIsError(true);
|
|
167
|
+
}
|
|
168
|
+
}).finally(() => {
|
|
169
|
+
if (!abortController.signal.aborted) {
|
|
170
|
+
setIsLoading(false);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return () => {
|
|
174
|
+
abortController.abort();
|
|
175
|
+
};
|
|
176
|
+
}, [canSearch, docs.algolia, isOpen, normalizedQuery]);
|
|
177
|
+
return {
|
|
178
|
+
results,
|
|
179
|
+
isLoading,
|
|
180
|
+
isError
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
var SearchModal = () => {
|
|
184
|
+
const docs = useDocsGlobalContext();
|
|
185
|
+
const { urlPathname } = usePageContext();
|
|
186
|
+
const { close, setQuery } = useDocsSearchActions();
|
|
187
|
+
const isOpen = useDocsSearchStore((state) => state.isOpen);
|
|
188
|
+
const query = useDocsSearchStore((state) => state.query);
|
|
189
|
+
const containerRef = useRef(null);
|
|
190
|
+
const suggestionBoxRef = useRef(null);
|
|
191
|
+
const previousPathnameRef = useRef(urlPathname);
|
|
192
|
+
const debouncedQuery = useDebouncedValue(query, QUERY_DEBOUNCE_MS);
|
|
193
|
+
const normalizedQuery = debouncedQuery.trim();
|
|
194
|
+
const canSearch = Boolean(docs.algolia) && normalizedQuery.length >= MIN_QUERY_LENGTH;
|
|
195
|
+
const { isError, isLoading, results } = useSearchResults({
|
|
196
|
+
canSearch,
|
|
197
|
+
isOpen,
|
|
198
|
+
normalizedQuery
|
|
199
|
+
});
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
if (previousPathnameRef.current !== urlPathname) {
|
|
202
|
+
close();
|
|
203
|
+
previousPathnameRef.current = urlPathname;
|
|
204
|
+
}
|
|
205
|
+
}, [close, urlPathname]);
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
if (!isOpen) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const handlePointerDown = (event) => {
|
|
211
|
+
const target = event.target;
|
|
212
|
+
if (!containerRef.current?.contains(target) && !suggestionBoxRef.current?.contains(target)) {
|
|
213
|
+
close();
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const handleKeyDown = (event) => {
|
|
217
|
+
if (event.key === "Escape") {
|
|
218
|
+
close();
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
222
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
223
|
+
return () => {
|
|
224
|
+
document.removeEventListener("pointerdown", handlePointerDown);
|
|
225
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
226
|
+
};
|
|
227
|
+
}, [close, isOpen]);
|
|
228
|
+
if (!docs.algolia) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
return /* @__PURE__ */ jsx("div", { ref: containerRef, className: "relative", children: /* @__PURE__ */ jsx(
|
|
232
|
+
SearchSuggestionBox,
|
|
233
|
+
{
|
|
234
|
+
contentRef: suggestionBoxRef,
|
|
235
|
+
isError,
|
|
236
|
+
isLoading,
|
|
237
|
+
isOpen,
|
|
238
|
+
onClose: close,
|
|
239
|
+
onQueryChange: setQuery,
|
|
240
|
+
query,
|
|
241
|
+
results
|
|
242
|
+
}
|
|
243
|
+
) });
|
|
244
|
+
};
|
|
245
|
+
var SearchSuggestionBox = ({
|
|
246
|
+
contentRef,
|
|
247
|
+
isError,
|
|
248
|
+
isLoading,
|
|
249
|
+
isOpen,
|
|
250
|
+
onClose,
|
|
251
|
+
onQueryChange,
|
|
252
|
+
query,
|
|
253
|
+
results
|
|
254
|
+
}) => {
|
|
255
|
+
const inputRef = useRef(null);
|
|
256
|
+
const normalizedQuery = query.trim();
|
|
257
|
+
const canSearch = normalizedQuery.length >= MIN_QUERY_LENGTH;
|
|
258
|
+
useEffect(() => {
|
|
259
|
+
if (!isOpen) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const frameId = window.requestAnimationFrame(() => {
|
|
263
|
+
inputRef.current?.focus();
|
|
264
|
+
inputRef.current?.setSelectionRange(query.length, query.length);
|
|
265
|
+
});
|
|
266
|
+
return () => {
|
|
267
|
+
window.cancelAnimationFrame(frameId);
|
|
268
|
+
};
|
|
269
|
+
}, [isOpen, query.length]);
|
|
270
|
+
if (!isOpen || typeof document === "undefined") {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
return createPortal(
|
|
274
|
+
/* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-30 h-full w-full bg-base-100/50 backdrop-blur-lg", children: [
|
|
275
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-1 bg-linear-to-b from-base-100 via-base-100 via-25% to-primary-muted-superlight dark:bg-linear-to-t" }),
|
|
276
|
+
/* @__PURE__ */ jsxs(
|
|
277
|
+
LayoutComponent,
|
|
278
|
+
{
|
|
279
|
+
ref: contentRef,
|
|
280
|
+
$size: "sm",
|
|
281
|
+
className: "mt-5 relative z-2 rounded-box bg-base-100/70 p-6 pt-6 shadow-lg shadow-primary-muted-light",
|
|
282
|
+
children: [
|
|
283
|
+
/* @__PURE__ */ jsx(
|
|
284
|
+
"input",
|
|
285
|
+
{
|
|
286
|
+
placeholder: "Search docs",
|
|
287
|
+
ref: inputRef,
|
|
288
|
+
type: "text",
|
|
289
|
+
className: "input input-primary input-xl w-full",
|
|
290
|
+
value: query,
|
|
291
|
+
onChange: (event) => onQueryChange(event.target.value)
|
|
292
|
+
}
|
|
293
|
+
),
|
|
294
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-7 items-center px-4 text-xs text-base-muted", children: isLoading ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
295
|
+
/* @__PURE__ */ jsx("span", { className: "loading loading-dots loading-xs" }),
|
|
296
|
+
"Searching..."
|
|
297
|
+
] }) : normalizedQuery ? null : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
298
|
+
/* @__PURE__ */ jsx(MessageCircleQuestion, { className: "h-3 w-3 shrink-0" }),
|
|
299
|
+
"Type at least ",
|
|
300
|
+
MIN_QUERY_LENGTH,
|
|
301
|
+
" characters."
|
|
302
|
+
] }) }),
|
|
303
|
+
normalizedQuery ? isError ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-box border border-warning/40 bg-base-100 p-4 text-sm text-base-muted shadow-md shadow-primary-muted-light", children: [
|
|
304
|
+
/* @__PURE__ */ jsx(TriangleAlert, { className: "h-4 w-4 shrink-0 text-warning" }),
|
|
305
|
+
"Search is temporarily unavailable."
|
|
306
|
+
] }) : !canSearch ? /* @__PURE__ */ jsx("div", { className: "text-sm text-base-muted", children: "Keep typing to search." }) : !isLoading && results.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-sm text-base-muted", children: "No results found." }) : /* @__PURE__ */ jsx("div", { className: "-mx-2 max-h-80 overflow-y-auto p-2", children: /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2", children: results.map((result) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
307
|
+
"a",
|
|
308
|
+
{
|
|
309
|
+
href: withSiteBaseUrl(result.href),
|
|
310
|
+
className: "block rounded-box border border-base-muted-medium bg-base-100 p-4 shadow-md hover:border-primary-muted hover:bg-base-200",
|
|
311
|
+
onClick: onClose,
|
|
312
|
+
children: [
|
|
313
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-start gap-2", children: [
|
|
314
|
+
/* @__PURE__ */ jsx("div", { className: "font-bold text-base-content", children: result.title }),
|
|
315
|
+
result.sectionTitle ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm text-base-muted-medium", children: [
|
|
316
|
+
/* @__PURE__ */ jsx(ArrowRightFromLine, { className: "h-3 w-3" }),
|
|
317
|
+
" ",
|
|
318
|
+
result.sectionTitle
|
|
319
|
+
] }) : null
|
|
320
|
+
] }),
|
|
321
|
+
result.excerpt ? /* @__PURE__ */ jsx("p", { className: "text-xs leading-5 text-base-muted", children: result.excerpt }) : null
|
|
322
|
+
]
|
|
323
|
+
}
|
|
324
|
+
) }, result.href)) }) }) : null
|
|
325
|
+
]
|
|
326
|
+
}
|
|
327
|
+
)
|
|
328
|
+
] }),
|
|
329
|
+
document.body
|
|
330
|
+
);
|
|
331
|
+
};
|
|
332
|
+
export {
|
|
333
|
+
SearchModal
|
|
334
|
+
};
|
|
335
|
+
//# sourceMappingURL=SearchModal-YJZFUB53.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/client/components/SearchModal.tsx","../src/runtime/client/search.ts"],"sourcesContent":["import { ArrowRightFromLine, MessageCircleQuestion, TriangleAlert } from 'lucide-react'\nimport type { RefObject } from 'react'\nimport { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { usePageContext } from 'vike-react/usePageContext'\nimport { withSiteBaseUrl } from '../../../shared/assets.js'\nimport { useDocsGlobalContext } from '../docsGlobalContext.js'\nimport { searchAlgoliaIndex } from '../search.js'\nimport { useDocsSearchActions, useDocsSearchStore } from '../store/runtime-store.js'\nimport { LayoutComponent } from './LayoutComponent.js'\n\nconst MIN_QUERY_LENGTH = 2\nconst QUERY_DEBOUNCE_MS = 150\n\nconst useDebouncedValue = (value: string, delayMs: number) => {\n const [debouncedValue, setDebouncedValue] = useState(value)\n\n useEffect(() => {\n const timeoutId = window.setTimeout(() => {\n setDebouncedValue(value)\n }, delayMs)\n\n return () => {\n window.clearTimeout(timeoutId)\n }\n }, [delayMs, value])\n\n return debouncedValue\n}\n\ntype SearchResults = Awaited<ReturnType<typeof searchAlgoliaIndex>>\n\nconst useSearchResults = (options: { canSearch: boolean; isOpen: boolean; normalizedQuery: string }) => {\n const docs = useDocsGlobalContext()\n const { canSearch, isOpen, normalizedQuery } = options\n const [results, setResults] = useState<SearchResults>([])\n const [isLoading, setIsLoading] = useState(false)\n const [isError, setIsError] = useState(false)\n\n useEffect(() => {\n if (!isOpen || !canSearch) {\n setResults([])\n setIsLoading(false)\n setIsError(false)\n return\n }\n\n const abortController = new AbortController()\n\n setIsLoading(true)\n setIsError(false)\n\n searchAlgoliaIndex({\n config: docs.algolia,\n query: normalizedQuery,\n signal: abortController.signal,\n })\n .then((nextResults) => {\n if (abortController.signal.aborted) {\n return\n }\n\n setResults(nextResults)\n })\n .catch((error: unknown) => {\n if (abortController.signal.aborted) {\n return\n }\n\n const isAbortError = error instanceof DOMException && error.name === 'AbortError'\n\n if (!isAbortError) {\n setResults([])\n setIsError(true)\n }\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false)\n }\n })\n\n return () => {\n abortController.abort()\n }\n }, [canSearch, docs.algolia, isOpen, normalizedQuery])\n\n return {\n results,\n isLoading,\n isError,\n }\n}\n\nexport const SearchModal = () => {\n const docs = useDocsGlobalContext()\n const { urlPathname } = usePageContext()\n const { close, setQuery } = useDocsSearchActions()\n const isOpen = useDocsSearchStore((state) => state.isOpen)\n const query = useDocsSearchStore((state) => state.query)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const suggestionBoxRef = useRef<HTMLDivElement | null>(null)\n const previousPathnameRef = useRef(urlPathname)\n const debouncedQuery = useDebouncedValue(query, QUERY_DEBOUNCE_MS)\n const normalizedQuery = debouncedQuery.trim()\n const canSearch = Boolean(docs.algolia) && normalizedQuery.length >= MIN_QUERY_LENGTH\n const { isError, isLoading, results } = useSearchResults({\n canSearch,\n isOpen,\n normalizedQuery,\n })\n\n useEffect(() => {\n if (previousPathnameRef.current !== urlPathname) {\n close()\n previousPathnameRef.current = urlPathname\n }\n }, [close, urlPathname])\n\n useEffect(() => {\n if (!isOpen) {\n return\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node\n\n if (!containerRef.current?.contains(target) && !suggestionBoxRef.current?.contains(target)) {\n close()\n }\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n close()\n }\n }\n\n document.addEventListener('pointerdown', handlePointerDown)\n document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown)\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [close, isOpen])\n\n if (!docs.algolia) {\n return null\n }\n\n return (\n <div ref={containerRef} className=\"relative\">\n <SearchSuggestionBox\n contentRef={suggestionBoxRef}\n isError={isError}\n isLoading={isLoading}\n isOpen={isOpen}\n onClose={close}\n onQueryChange={setQuery}\n query={query}\n results={results}\n />\n </div>\n )\n}\n\ntype SearchSuggestionBoxProps = {\n contentRef: RefObject<HTMLDivElement | null>\n isError: boolean\n isLoading: boolean\n isOpen: boolean\n onClose: () => void\n onQueryChange: (query: string) => void\n query: string\n results: SearchResults\n}\n\nconst SearchSuggestionBox = ({\n contentRef,\n isError,\n isLoading,\n isOpen,\n onClose,\n onQueryChange,\n query,\n results,\n}: SearchSuggestionBoxProps) => {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const normalizedQuery = query.trim()\n const canSearch = normalizedQuery.length >= MIN_QUERY_LENGTH\n\n useEffect(() => {\n if (!isOpen) {\n return\n }\n\n const frameId = window.requestAnimationFrame(() => {\n inputRef.current?.focus()\n inputRef.current?.setSelectionRange(query.length, query.length)\n })\n\n return () => {\n window.cancelAnimationFrame(frameId)\n }\n }, [isOpen, query.length])\n\n if (!isOpen || typeof document === 'undefined') {\n return null\n }\n\n return createPortal(\n <div className=\"fixed inset-0 z-30 h-full w-full bg-base-100/50 backdrop-blur-lg\">\n <div className=\"absolute inset-0 z-1 bg-linear-to-b from-base-100 via-base-100 via-25% to-primary-muted-superlight dark:bg-linear-to-t\" />\n <LayoutComponent\n ref={contentRef}\n $size=\"sm\"\n className=\"mt-5 relative z-2 rounded-box bg-base-100/70 p-6 pt-6 shadow-lg shadow-primary-muted-light\"\n >\n <input\n placeholder=\"Search docs\"\n ref={inputRef}\n type=\"text\"\n className=\"input input-primary input-xl w-full\"\n value={query}\n onChange={(event) => onQueryChange(event.target.value)}\n />\n <div className=\"flex h-7 items-center px-4 text-xs text-base-muted\">\n {isLoading ? (\n <span className=\"flex items-center gap-1\">\n <span className=\"loading loading-dots loading-xs\" />\n Searching...\n </span>\n ) : normalizedQuery ? null : (\n <span className=\"flex items-center gap-1\">\n <MessageCircleQuestion className=\"h-3 w-3 shrink-0\" />\n Type at least {MIN_QUERY_LENGTH} characters.\n </span>\n )}\n </div>\n {normalizedQuery ? (\n isError ? (\n <div className=\"flex items-center gap-2 rounded-box border border-warning/40 bg-base-100 p-4 text-sm text-base-muted shadow-md shadow-primary-muted-light\">\n <TriangleAlert className=\"h-4 w-4 shrink-0 text-warning\" />\n Search is temporarily unavailable.\n </div>\n ) : !canSearch ? (\n <div className=\"text-sm text-base-muted\">Keep typing to search.</div>\n ) : !isLoading && results.length === 0 ? (\n <div className=\"text-sm text-base-muted\">No results found.</div>\n ) : (\n <div className=\"-mx-2 max-h-80 overflow-y-auto p-2\">\n <ul className=\"flex flex-col gap-2\">\n {results.map((result) => (\n <li key={result.href}>\n <a\n href={withSiteBaseUrl(result.href)}\n className=\"block rounded-box border border-base-muted-medium bg-base-100 p-4 shadow-md hover:border-primary-muted hover:bg-base-200\"\n onClick={onClose}\n >\n <div className=\"mb-2 flex items-center justify-start gap-2\">\n <div className=\"font-bold text-base-content\">{result.title}</div>\n {result.sectionTitle ? (\n <div className=\"flex items-center gap-1 text-sm text-base-muted-medium\">\n <ArrowRightFromLine className=\"h-3 w-3\" /> {result.sectionTitle}\n </div>\n ) : null}\n </div>\n {result.excerpt ? <p className=\"text-xs leading-5 text-base-muted\">{result.excerpt}</p> : null}\n </a>\n </li>\n ))}\n </ul>\n </div>\n )\n ) : null}\n </LayoutComponent>\n </div>,\n document.body,\n )\n}\n","import type { ResolvedDocsAlgoliaConfig } from '../../docs/types.js'\n\ntype DocsSearchResult = {\n href: string\n title: string\n excerpt?: string\n sectionTitle?: string\n}\n\ntype SearchAlgoliaResponse = {\n hits?: unknown[]\n}\n\ntype AlgoliaDocSearchHit = {\n url?: unknown\n url_without_anchor?: unknown\n type?: unknown\n category?: unknown\n content?: unknown\n hierarchy?: Record<string, unknown> | null\n _highlightResult?: {\n content?: {\n value?: unknown\n }\n } | null\n _snippetResult?: {\n content?: {\n value?: unknown\n }\n } | null\n}\n\nconst hierarchyLevels = ['lvl0', 'lvl1', 'lvl2', 'lvl3', 'lvl4', 'lvl5', 'lvl6'] as const\n\nconst stripHtml = (value: string) => value.replace(/<[^>]+>/g, '')\n\nconst normalizeString = (value: unknown) => {\n if (typeof value === 'string') {\n const normalized = stripHtml(value).replace(/\\s+/g, ' ').trim()\n return normalized || undefined\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value)\n }\n\n return undefined\n}\n\nconst getValueAtPath = (value: unknown, path: string): unknown => {\n if (!path) {\n return undefined\n }\n\n const segments = path.split('.').filter(Boolean)\n let currentValue = value\n\n for (const segment of segments) {\n if (!currentValue || typeof currentValue !== 'object' || Array.isArray(currentValue)) {\n return undefined\n }\n\n currentValue = (currentValue as Record<string, unknown>)[segment]\n }\n\n return currentValue\n}\n\nconst getMappedString = (value: unknown, path: string): string | undefined => {\n return normalizeString(getValueAtPath(value, path))\n}\n\nconst buildSearchUrl = (appId: string, indexName: string) => {\n return `https://${appId}-dsn.algolia.net/1/indexes/${encodeURIComponent(indexName)}/query`\n}\n\nconst getDocSearchHierarchyValue = (\n hierarchy: AlgoliaDocSearchHit['hierarchy'],\n level: (typeof hierarchyLevels)[number],\n) => {\n if (!hierarchy || typeof hierarchy !== 'object') {\n return undefined\n }\n\n return normalizeString(hierarchy[level])\n}\n\nconst getDocSearchTitleLevel = (hit: AlgoliaDocSearchHit) => {\n const levelFromType =\n typeof hit.type === 'string' && /^lvl[0-6]$/.test(hit.type) ? (hit.type as (typeof hierarchyLevels)[number]) : null\n\n if (levelFromType && getDocSearchHierarchyValue(hit.hierarchy, levelFromType)) {\n return levelFromType\n }\n\n return [...hierarchyLevels]\n .reverse()\n .find((level) => level !== 'lvl0' && getDocSearchHierarchyValue(hit.hierarchy, level))\n}\n\nconst getDocSearchFallbackResult = (hit: unknown): Partial<DocsSearchResult> => {\n const docSearchHit = hit as AlgoliaDocSearchHit\n const titleLevel = getDocSearchTitleLevel(docSearchHit)\n const title = titleLevel ? getDocSearchHierarchyValue(docSearchHit.hierarchy, titleLevel) : undefined\n const titleLevelIndex = titleLevel ? hierarchyLevels.indexOf(titleLevel) : -1\n const sectionTitle =\n hierarchyLevels\n .slice(0, Math.max(titleLevelIndex, 0))\n .reverse()\n .map((level) => getDocSearchHierarchyValue(docSearchHit.hierarchy, level))\n .find(Boolean) ?? normalizeString(docSearchHit.category)\n\n return {\n href: normalizeString(docSearchHit.url) ?? normalizeString(docSearchHit.url_without_anchor),\n title: title ?? normalizeString(docSearchHit.category),\n excerpt:\n normalizeString(docSearchHit._snippetResult?.content?.value) ??\n normalizeString(docSearchHit.content) ??\n normalizeString(docSearchHit._highlightResult?.content?.value),\n sectionTitle,\n }\n}\n\nconst mapHitToSearchResult = (hit: unknown, config: ResolvedDocsAlgoliaConfig): DocsSearchResult | null => {\n const docSearchFallback = getDocSearchFallbackResult(hit)\n const href = getMappedString(hit, config.fields.href) ?? docSearchFallback.href\n const title = getMappedString(hit, config.fields.title) ?? docSearchFallback.title\n\n if (!href || !title) {\n return null\n }\n\n const excerpt = getMappedString(hit, config.fields.excerpt) ?? docSearchFallback.excerpt\n const sectionTitle = getMappedString(hit, config.fields.sectionTitle) ?? docSearchFallback.sectionTitle\n\n return {\n href,\n title,\n excerpt,\n sectionTitle,\n }\n}\n\nexport const searchAlgoliaIndex = async (options: {\n config?: ResolvedDocsAlgoliaConfig | null\n query: string\n signal?: AbortSignal\n}) => {\n const { config, query, signal } = options\n\n if (!config) {\n throw new Error('Algolia search is not configured.')\n }\n\n const response = await fetch(buildSearchUrl(config.appId, config.indexName), {\n method: 'POST',\n signal,\n headers: {\n accept: 'application/json',\n 'content-type': 'application/json',\n 'x-algolia-api-key': config.apiKey,\n 'x-algolia-application-id': config.appId,\n },\n body: JSON.stringify({\n query,\n ...config.searchParams,\n }),\n })\n\n if (!response.ok) {\n throw new Error(`Algolia search request failed with status ${response.status}.`)\n }\n\n const data = (await response.json()) as SearchAlgoliaResponse\n\n return (data.hits ?? [])\n .map((hit) => mapHitToSearchResult(hit, config))\n .filter((result): result is DocsSearchResult => result !== null)\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// src/runtime/client/docsGlobalContext.ts
|
|
2
|
+
import { createContext, createElement, useContext } from "react";
|
|
3
|
+
import { usePageContext } from "vike-react/usePageContext";
|
|
4
|
+
var DocsGlobalContext = createContext(null);
|
|
5
|
+
var getDocsFromGlobalContext = (pageContext) => {
|
|
6
|
+
const docs = pageContext.globalContext?.docs;
|
|
7
|
+
if (!docs) {
|
|
8
|
+
throw new Error("Missing docs global context data.");
|
|
9
|
+
}
|
|
10
|
+
return docs;
|
|
11
|
+
};
|
|
12
|
+
var DocsGlobalContextProvider = ({ children, docs }) => {
|
|
13
|
+
return createElement(DocsGlobalContext.Provider, { value: docs }, children);
|
|
14
|
+
};
|
|
15
|
+
var useDocsGlobalContext = () => {
|
|
16
|
+
const docs = useContext(DocsGlobalContext);
|
|
17
|
+
if (!docs) {
|
|
18
|
+
throw new Error("Missing docs global context provider.");
|
|
19
|
+
}
|
|
20
|
+
return docs;
|
|
21
|
+
};
|
|
22
|
+
var useDocsFromPageGlobalContext = () => {
|
|
23
|
+
return getDocsFromGlobalContext(usePageContext());
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// src/runtime/client/store/runtime-store.tsx
|
|
27
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
28
|
+
import { useStore } from "zustand";
|
|
29
|
+
import { createStore } from "zustand/vanilla";
|
|
30
|
+
import { jsx } from "react/jsx-runtime";
|
|
31
|
+
var defaultDocsSearchState = {
|
|
32
|
+
isOpen: false,
|
|
33
|
+
query: ""
|
|
34
|
+
};
|
|
35
|
+
var defaultDocsSidebarState = {
|
|
36
|
+
openNodes: {}
|
|
37
|
+
};
|
|
38
|
+
var createDocsRuntimeStore = () => {
|
|
39
|
+
return createStore()((set) => {
|
|
40
|
+
const searchActions = {
|
|
41
|
+
open: () => set((state) => {
|
|
42
|
+
if (state.searchState.isOpen) {
|
|
43
|
+
return state;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
searchState: {
|
|
47
|
+
...state.searchState,
|
|
48
|
+
isOpen: true
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}),
|
|
52
|
+
close: () => set((state) => {
|
|
53
|
+
if (!state.searchState.isOpen) {
|
|
54
|
+
return state;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
searchState: {
|
|
58
|
+
...state.searchState,
|
|
59
|
+
isOpen: false
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}),
|
|
63
|
+
toggle: () => set((state) => ({
|
|
64
|
+
searchState: {
|
|
65
|
+
...state.searchState,
|
|
66
|
+
isOpen: !state.searchState.isOpen
|
|
67
|
+
}
|
|
68
|
+
})),
|
|
69
|
+
setQuery: (query) => set((state) => {
|
|
70
|
+
if (state.searchState.query === query) {
|
|
71
|
+
return state;
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
searchState: {
|
|
75
|
+
...state.searchState,
|
|
76
|
+
query
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}),
|
|
80
|
+
clearQuery: () => set((state) => {
|
|
81
|
+
if (state.searchState.query === "") {
|
|
82
|
+
return state;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
searchState: {
|
|
86
|
+
...state.searchState,
|
|
87
|
+
query: ""
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
})
|
|
91
|
+
};
|
|
92
|
+
const sidebarActions = {
|
|
93
|
+
setNodeOpen: (nodeId, isOpen) => set((state) => {
|
|
94
|
+
if (state.sidebarState.openNodes[nodeId] === isOpen) {
|
|
95
|
+
return state;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
sidebarState: {
|
|
99
|
+
...state.sidebarState,
|
|
100
|
+
openNodes: {
|
|
101
|
+
...state.sidebarState.openNodes,
|
|
102
|
+
[nodeId]: isOpen
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
})
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
searchActions,
|
|
110
|
+
searchState: defaultDocsSearchState,
|
|
111
|
+
sidebarActions,
|
|
112
|
+
sidebarState: defaultDocsSidebarState
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
var DocsRuntimeStoreContext = createContext2(null);
|
|
117
|
+
var DocsRuntimeStoreProvider = ({ children, store }) => {
|
|
118
|
+
return /* @__PURE__ */ jsx(DocsRuntimeStoreContext.Provider, { value: store, children });
|
|
119
|
+
};
|
|
120
|
+
var useDocsRuntimeStoreApi = () => {
|
|
121
|
+
const store = useContext2(DocsRuntimeStoreContext);
|
|
122
|
+
if (store === null) {
|
|
123
|
+
throw new Error("Missing docs runtime store provider.");
|
|
124
|
+
}
|
|
125
|
+
return store;
|
|
126
|
+
};
|
|
127
|
+
var useDocsRuntimeStore = (selector) => {
|
|
128
|
+
return useStore(useDocsRuntimeStoreApi(), selector);
|
|
129
|
+
};
|
|
130
|
+
var useDocsSearchStore = (selector) => {
|
|
131
|
+
return useDocsRuntimeStore(
|
|
132
|
+
(state) => selector({
|
|
133
|
+
...state.searchState,
|
|
134
|
+
...state.searchActions
|
|
135
|
+
})
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
var useDocsSearchActions = () => {
|
|
139
|
+
return useDocsRuntimeStore((state) => state.searchActions);
|
|
140
|
+
};
|
|
141
|
+
var useDocsSidebarStore = (selector) => {
|
|
142
|
+
return useDocsRuntimeStore(
|
|
143
|
+
(state) => selector({
|
|
144
|
+
...state.sidebarState,
|
|
145
|
+
...state.sidebarActions
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
var useDocsSidebarActions = () => {
|
|
150
|
+
return useDocsRuntimeStore((state) => state.sidebarActions);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// src/runtime/client/components/LayoutComponent.tsx
|
|
154
|
+
import cm from "@classmatejs/react";
|
|
155
|
+
var LayoutSize = {
|
|
156
|
+
xxs: "xxs",
|
|
157
|
+
xs: "xs",
|
|
158
|
+
sm: "sm",
|
|
159
|
+
md: "md",
|
|
160
|
+
lg: "lg",
|
|
161
|
+
xl: "xl",
|
|
162
|
+
full: "full"
|
|
163
|
+
};
|
|
164
|
+
var layoutComponentSizeMapping = {
|
|
165
|
+
xxs: "max-w-[480px]",
|
|
166
|
+
xs: "max-w-[768px]",
|
|
167
|
+
sm: "max-w-5xl",
|
|
168
|
+
md: "max-w-6xl",
|
|
169
|
+
lg: "max-w-7xl",
|
|
170
|
+
xl: "max-w-[1440px]",
|
|
171
|
+
full: "max-w-full"
|
|
172
|
+
};
|
|
173
|
+
var LayoutComponent = cm.div.variants({
|
|
174
|
+
base: ({ $noGrow }) => `px-4 ${$noGrow ? "" : "mx-auto w-full"} relative`,
|
|
175
|
+
variants: {
|
|
176
|
+
$size: layoutComponentSizeMapping
|
|
177
|
+
},
|
|
178
|
+
defaultVariants: {
|
|
179
|
+
$size: LayoutSize.xl
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
export {
|
|
184
|
+
getDocsFromGlobalContext,
|
|
185
|
+
DocsGlobalContextProvider,
|
|
186
|
+
useDocsGlobalContext,
|
|
187
|
+
useDocsFromPageGlobalContext,
|
|
188
|
+
createDocsRuntimeStore,
|
|
189
|
+
DocsRuntimeStoreProvider,
|
|
190
|
+
useDocsSearchStore,
|
|
191
|
+
useDocsSearchActions,
|
|
192
|
+
useDocsSidebarStore,
|
|
193
|
+
useDocsSidebarActions,
|
|
194
|
+
LayoutComponent
|
|
195
|
+
};
|
|
196
|
+
//# sourceMappingURL=chunk-ESAHWFDZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/client/docsGlobalContext.ts","../src/runtime/client/store/runtime-store.tsx","../src/runtime/client/components/LayoutComponent.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { createContext, createElement, useContext } from 'react'\nimport { usePageContext } from 'vike-react/usePageContext'\nimport type { DocsGlobalContextData } from '../../docs/types.js'\n\nexport type DocsPageContext = {\n globalContext?: {\n docs?: DocsGlobalContextData\n }\n}\n\nconst DocsGlobalContext = createContext<DocsGlobalContextData | null>(null)\n\nexport const getDocsFromGlobalContext = (pageContext: DocsPageContext) => {\n const docs = pageContext.globalContext?.docs\n\n if (!docs) {\n throw new Error('Missing docs global context data.')\n }\n\n return docs\n}\n\nexport const DocsGlobalContextProvider = ({ children, docs }: { children: ReactNode; docs: DocsGlobalContextData }) => {\n return createElement(DocsGlobalContext.Provider, { value: docs }, children)\n}\n\nexport const useDocsGlobalContext = () => {\n const docs = useContext(DocsGlobalContext)\n\n if (!docs) {\n throw new Error('Missing docs global context provider.')\n }\n\n return docs\n}\n\nexport const useDocsFromPageGlobalContext = () => {\n return getDocsFromGlobalContext(usePageContext() as DocsPageContext)\n}\n","import type { ReactNode } from 'react'\nimport { createContext, useContext } from 'react'\nimport { useStore } from 'zustand'\nimport { createStore } from 'zustand/vanilla'\nimport type {\n DocsSearchActions,\n DocsSearchSlice,\n DocsSearchState,\n DocsSidebarActions,\n DocsSidebarSlice,\n DocsSidebarState,\n} from './types.js'\n\ntype DocsRuntimeStoreState = {\n searchActions: DocsSearchActions\n searchState: DocsSearchState\n sidebarActions: DocsSidebarActions\n sidebarState: DocsSidebarState\n}\n\ntype DocsRuntimeStoreApi = ReturnType<typeof createDocsRuntimeStore>\n\nconst defaultDocsSearchState: DocsSearchState = {\n isOpen: false,\n query: '',\n}\n\nconst defaultDocsSidebarState: DocsSidebarState = {\n openNodes: {},\n}\n\nexport const createDocsRuntimeStore = () => {\n return createStore<DocsRuntimeStoreState>()((set) => {\n const searchActions: DocsSearchActions = {\n open: () =>\n set((state) => {\n if (state.searchState.isOpen) {\n return state\n }\n\n return {\n searchState: {\n ...state.searchState,\n isOpen: true,\n },\n }\n }),\n close: () =>\n set((state) => {\n if (!state.searchState.isOpen) {\n return state\n }\n\n return {\n searchState: {\n ...state.searchState,\n isOpen: false,\n },\n }\n }),\n toggle: () =>\n set((state) => ({\n searchState: {\n ...state.searchState,\n isOpen: !state.searchState.isOpen,\n },\n })),\n setQuery: (query) =>\n set((state) => {\n if (state.searchState.query === query) {\n return state\n }\n\n return {\n searchState: {\n ...state.searchState,\n query,\n },\n }\n }),\n clearQuery: () =>\n set((state) => {\n if (state.searchState.query === '') {\n return state\n }\n\n return {\n searchState: {\n ...state.searchState,\n query: '',\n },\n }\n }),\n }\n\n const sidebarActions: DocsSidebarActions = {\n setNodeOpen: (nodeId, isOpen) =>\n set((state) => {\n if (state.sidebarState.openNodes[nodeId] === isOpen) {\n return state\n }\n\n return {\n sidebarState: {\n ...state.sidebarState,\n openNodes: {\n ...state.sidebarState.openNodes,\n [nodeId]: isOpen,\n },\n },\n }\n }),\n }\n\n return {\n searchActions,\n searchState: defaultDocsSearchState,\n sidebarActions,\n sidebarState: defaultDocsSidebarState,\n }\n })\n}\n\nconst DocsRuntimeStoreContext = createContext<DocsRuntimeStoreApi | null>(null)\n\nexport const DocsRuntimeStoreProvider = ({ children, store }: { children: ReactNode; store: DocsRuntimeStoreApi }) => {\n return <DocsRuntimeStoreContext.Provider value={store}>{children}</DocsRuntimeStoreContext.Provider>\n}\n\nconst useDocsRuntimeStoreApi = () => {\n const store = useContext(DocsRuntimeStoreContext)\n\n if (store === null) {\n throw new Error('Missing docs runtime store provider.')\n }\n\n return store\n}\n\nconst useDocsRuntimeStore = <Selected,>(selector: (state: DocsRuntimeStoreState) => Selected) => {\n return useStore(useDocsRuntimeStoreApi(), selector)\n}\n\nexport const useDocsSearchStore = <Selected,>(selector: (state: DocsSearchSlice) => Selected) => {\n return useDocsRuntimeStore((state) =>\n selector({\n ...state.searchState,\n ...state.searchActions,\n }),\n )\n}\n\nexport const useDocsSearchActions = () => {\n return useDocsRuntimeStore((state) => state.searchActions)\n}\n\nexport const useDocsSidebarStore = <Selected,>(selector: (state: DocsSidebarSlice) => Selected) => {\n return useDocsRuntimeStore((state) =>\n selector({\n ...state.sidebarState,\n ...state.sidebarActions,\n }),\n )\n}\n\nexport const useDocsSidebarActions = () => {\n return useDocsRuntimeStore((state) => state.sidebarActions)\n}\n","import cm from '@classmatejs/react'\n\nconst LayoutSize = {\n xxs: 'xxs',\n xs: 'xs',\n sm: 'sm',\n md: 'md',\n lg: 'lg',\n xl: 'xl',\n full: 'full',\n} as const\ntype LayoutSize = (typeof LayoutSize)[keyof typeof LayoutSize]\n\nconst layoutComponentSizeMapping: { [key in LayoutSize]: string } = {\n xxs: 'max-w-[480px]',\n xs: 'max-w-[768px]',\n sm: 'max-w-5xl',\n md: 'max-w-6xl',\n lg: 'max-w-7xl',\n xl: 'max-w-[1440px]',\n full: 'max-w-full',\n} as const\n\ninterface LayoutComponentProps {\n $size?: LayoutSize\n $noGrow?: boolean\n}\n\nexport const LayoutComponent = cm.div.variants<LayoutComponentProps>({\n base: ({ $noGrow }) => `px-4 ${$noGrow ? '' : 'mx-auto w-full'} relative`,\n variants: {\n $size: layoutComponentSizeMapping,\n },\n defaultVariants: {\n $size: LayoutSize.xl,\n },\n})\n"],"mappings":"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","names":["createContext","useContext"]}
|