doc-render-sdk 0.0.1

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/index.mjs ADDED
@@ -0,0 +1,3519 @@
1
+ import React, { useEffect, useMemo, useRef, useState } from "react";
2
+ import ReactDOM from "react-dom";
3
+ import EventTarget from "mini-event/EventTarget";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { cloneDeep, get as get$1, merge, set as set$1 } from "lodash-es";
6
+
7
+ //#region src/components/Navigation.tsx
8
+ const Navigation = ({ config, theme, currentRoute, componentRegistry, onNavigate, compact = false }) => {
9
+ const navigationItems = useMemo(() => {
10
+ const navigationConfig = config.navigation || {};
11
+ const { mode = "auto", groups = [], showHome = true } = navigationConfig;
12
+ const items = [];
13
+ if (showHome) items.push({
14
+ id: "home",
15
+ label: navigationConfig.homeTitle || "首页",
16
+ path: "/",
17
+ type: "home"
18
+ });
19
+ if (mode === "manual" && groups.length > 0) groups.forEach((group) => {
20
+ items.push({
21
+ id: group.id,
22
+ label: group.label,
23
+ type: "group",
24
+ children: group.items || []
25
+ });
26
+ });
27
+ else {
28
+ const components = componentRegistry.getComponentIds();
29
+ if (components.length > 0) {
30
+ const componentGroup = {
31
+ id: "components",
32
+ label: "组件",
33
+ type: "group",
34
+ children: components.map((componentId) => {
35
+ const componentConfig = componentRegistry.getComponent(componentId);
36
+ return {
37
+ id: componentId,
38
+ label: componentConfig?.label || componentId,
39
+ path: `/${componentId}`,
40
+ type: "component"
41
+ };
42
+ })
43
+ };
44
+ items.push(componentGroup);
45
+ }
46
+ }
47
+ return items;
48
+ }, [config, componentRegistry]);
49
+ const handleItemClick = (item) => {
50
+ if (item.path && onNavigate) onNavigate(item.path);
51
+ };
52
+ const isItemActive = (item) => {
53
+ if (!currentRoute) return false;
54
+ if (item.type === "home") return currentRoute.path === "/";
55
+ if (item.type === "component") return currentRoute.path === item.path;
56
+ return false;
57
+ };
58
+ const renderNavigationItem = (item, level = 0) => {
59
+ const isActive = isItemActive(item);
60
+ const hasChildren = item.children && item.children.length > 0;
61
+ if (item.type === "group") return /* @__PURE__ */ jsxs("div", {
62
+ className: "doc-navigation-group",
63
+ children: [!compact && /* @__PURE__ */ jsx("div", {
64
+ className: "doc-navigation-group-title",
65
+ children: item.label
66
+ }), hasChildren && /* @__PURE__ */ jsx("div", {
67
+ className: "doc-navigation-group-items",
68
+ children: item.children.map((child) => renderNavigationItem(child, level + 1))
69
+ })]
70
+ }, item.id);
71
+ return /* @__PURE__ */ jsxs("a", {
72
+ className: `doc-navigation-item ${isActive ? "active" : ""} ${compact ? "compact" : ""}`,
73
+ onClick: (e) => {
74
+ e.preventDefault();
75
+ handleItemClick(item);
76
+ },
77
+ href: item.path || "#",
78
+ style: { paddingLeft: `${16 + level * 16}px` },
79
+ children: [
80
+ item.icon && /* @__PURE__ */ jsx("span", {
81
+ className: "doc-navigation-item-icon",
82
+ children: item.icon
83
+ }),
84
+ /* @__PURE__ */ jsx("span", {
85
+ className: "doc-navigation-item-label",
86
+ children: item.label
87
+ }),
88
+ item.badge && /* @__PURE__ */ jsx("span", {
89
+ className: "doc-navigation-item-badge",
90
+ children: item.badge
91
+ })
92
+ ]
93
+ }, item.id);
94
+ };
95
+ return /* @__PURE__ */ jsxs("nav", {
96
+ className: `doc-navigation ${compact ? "compact" : ""}`,
97
+ children: [!compact && config.title && /* @__PURE__ */ jsx("div", {
98
+ className: "doc-navigation-title",
99
+ children: config.title
100
+ }), /* @__PURE__ */ jsx("div", {
101
+ className: "doc-navigation-items",
102
+ children: navigationItems.map((item) => renderNavigationItem(item))
103
+ })]
104
+ });
105
+ };
106
+ var Navigation_default = Navigation;
107
+
108
+ //#endregion
109
+ //#region src/components/Search.tsx
110
+ const Search = ({ config, componentRegistry, onClose, onNavigate }) => {
111
+ const [query, setQuery] = useState("");
112
+ const [results, setResults] = useState([]);
113
+ const [selectedIndex, setSelectedIndex] = useState(0);
114
+ const inputRef = useRef(null);
115
+ const overlayRef = useRef(null);
116
+ useEffect(() => {
117
+ if (inputRef.current) inputRef.current.focus();
118
+ const handleKeyDown = (e) => {
119
+ if (e.key === "Escape") onClose();
120
+ else if (e.key === "ArrowDown") {
121
+ e.preventDefault();
122
+ setSelectedIndex((prev) => Math.min(prev + 1, results.length - 1));
123
+ } else if (e.key === "ArrowUp") {
124
+ e.preventDefault();
125
+ setSelectedIndex((prev) => Math.max(prev - 1, 0));
126
+ } else if (e.key === "Enter") {
127
+ e.preventDefault();
128
+ if (results[selectedIndex]) handleResultClick(results[selectedIndex]);
129
+ }
130
+ };
131
+ document.addEventListener("keydown", handleKeyDown);
132
+ return () => document.removeEventListener("keydown", handleKeyDown);
133
+ }, [
134
+ results,
135
+ selectedIndex,
136
+ onClose
137
+ ]);
138
+ useEffect(() => {
139
+ if (!query.trim()) {
140
+ setResults([]);
141
+ setSelectedIndex(0);
142
+ return;
143
+ }
144
+ const searchResults = performSearch(query);
145
+ setResults(searchResults);
146
+ setSelectedIndex(0);
147
+ }, [query, componentRegistry]);
148
+ const performSearch = (searchQuery) => {
149
+ const results$1 = [];
150
+ const lowerQuery = searchQuery.toLowerCase();
151
+ const componentIds = componentRegistry.getComponentIds();
152
+ componentIds.forEach((componentId) => {
153
+ const componentConfig = componentRegistry.getComponent(componentId);
154
+ const label = componentConfig?.label || componentId;
155
+ const description = componentConfig?.description || "";
156
+ if (label.toLowerCase().includes(lowerQuery) || description.toLowerCase().includes(lowerQuery) || componentId.toLowerCase().includes(lowerQuery)) results$1.push({
157
+ type: "component",
158
+ id: componentId,
159
+ title: label,
160
+ description,
161
+ path: `/${componentId}`,
162
+ score: calculateScore(lowerQuery, label, description)
163
+ });
164
+ const demos = componentRegistry.getDemos(componentId);
165
+ demos.forEach((demo, demoSource) => {
166
+ const demoTitle = demo.title || demoSource;
167
+ const demoDesc = demo.desc || "";
168
+ if (demoTitle.toLowerCase().includes(lowerQuery) || demoDesc.toLowerCase().includes(lowerQuery)) results$1.push({
169
+ type: "demo",
170
+ id: `${componentId}-${demoSource}`,
171
+ title: `${label} - ${demoTitle}`,
172
+ description: demoDesc,
173
+ path: `/${componentId}`,
174
+ anchor: `demo-${demoSource}`,
175
+ score: calculateScore(lowerQuery, demoTitle, demoDesc)
176
+ });
177
+ });
178
+ const apis = componentRegistry.getApis(componentId);
179
+ apis.forEach((api, apiKey) => {
180
+ const apiTitle = api.title || apiKey;
181
+ if (apiTitle.toLowerCase().includes(lowerQuery)) results$1.push({
182
+ type: "api",
183
+ id: `${componentId}-${apiKey}`,
184
+ title: `${label} - ${apiTitle}`,
185
+ description: "API文档",
186
+ path: `/${componentId}`,
187
+ anchor: `api-${apiKey}`,
188
+ score: calculateScore(lowerQuery, apiTitle, "")
189
+ });
190
+ });
191
+ });
192
+ return results$1.sort((a, b) => b.score - a.score).slice(0, 10);
193
+ };
194
+ const calculateScore = (query$1, title, description) => {
195
+ let score = 0;
196
+ const lowerTitle = title.toLowerCase();
197
+ const lowerDesc = description.toLowerCase();
198
+ if (lowerTitle === query$1) score += 100;
199
+ else if (lowerTitle.startsWith(query$1)) score += 50;
200
+ else if (lowerTitle.includes(query$1)) score += 25;
201
+ if (lowerDesc.includes(query$1)) score += 10;
202
+ return score;
203
+ };
204
+ const handleResultClick = (result) => {
205
+ if (onNavigate) {
206
+ onNavigate(result.path);
207
+ if (result.anchor) setTimeout(() => {
208
+ const element = document.getElementById(result.anchor);
209
+ if (element) element.scrollIntoView({ behavior: "smooth" });
210
+ }, 100);
211
+ }
212
+ onClose();
213
+ };
214
+ const handleOverlayClick = (e) => {
215
+ if (e.target === overlayRef.current) onClose();
216
+ };
217
+ const getResultIcon = (type) => {
218
+ switch (type) {
219
+ case "component": return "📦";
220
+ case "demo": return "🎯";
221
+ case "api": return "📋";
222
+ default: return "📄";
223
+ }
224
+ };
225
+ const highlightText = (text, query$1) => {
226
+ if (!query$1) return text;
227
+ const regex = new RegExp(`(${query$1})`, "gi");
228
+ const parts = text.split(regex);
229
+ return parts.map((part, index) => regex.test(part) ? /* @__PURE__ */ jsx("mark", {
230
+ className: "doc-search-highlight",
231
+ children: part
232
+ }, index) : part);
233
+ };
234
+ return /* @__PURE__ */ jsx("div", {
235
+ className: "doc-search-overlay",
236
+ ref: overlayRef,
237
+ onClick: handleOverlayClick,
238
+ children: /* @__PURE__ */ jsxs("div", {
239
+ className: "doc-search-modal",
240
+ children: [
241
+ /* @__PURE__ */ jsxs("div", {
242
+ className: "doc-search-input-container",
243
+ children: [/* @__PURE__ */ jsx("input", {
244
+ ref: inputRef,
245
+ type: "text",
246
+ className: "doc-search-input",
247
+ placeholder: config.placeholder || "搜索文档...",
248
+ value: query,
249
+ onChange: (e) => setQuery(e.target.value)
250
+ }), /* @__PURE__ */ jsx("button", {
251
+ className: "doc-search-close",
252
+ onClick: onClose,
253
+ title: "关闭搜索",
254
+ children: "✕"
255
+ })]
256
+ }),
257
+ results.length > 0 && /* @__PURE__ */ jsx("div", {
258
+ className: "doc-search-results",
259
+ children: results.map((result, index) => /* @__PURE__ */ jsxs("div", {
260
+ className: `doc-search-result ${index === selectedIndex ? "selected" : ""}`,
261
+ onClick: () => handleResultClick(result),
262
+ children: [
263
+ /* @__PURE__ */ jsx("div", {
264
+ className: "doc-search-result-icon",
265
+ children: getResultIcon(result.type)
266
+ }),
267
+ /* @__PURE__ */ jsxs("div", {
268
+ className: "doc-search-result-content",
269
+ children: [/* @__PURE__ */ jsx("div", {
270
+ className: "doc-search-result-title",
271
+ children: highlightText(result.title, query)
272
+ }), result.description && /* @__PURE__ */ jsx("div", {
273
+ className: "doc-search-result-description",
274
+ children: highlightText(result.description, query)
275
+ })]
276
+ }),
277
+ /* @__PURE__ */ jsx("div", {
278
+ className: "doc-search-result-type",
279
+ children: result.type
280
+ })
281
+ ]
282
+ }, result.id))
283
+ }),
284
+ query && results.length === 0 && /* @__PURE__ */ jsx("div", {
285
+ className: "doc-search-no-results",
286
+ children: /* @__PURE__ */ jsx("p", { children: "未找到相关结果" })
287
+ }),
288
+ /* @__PURE__ */ jsx("div", {
289
+ className: "doc-search-footer",
290
+ children: /* @__PURE__ */ jsxs("div", {
291
+ className: "doc-search-shortcuts",
292
+ children: [
293
+ /* @__PURE__ */ jsxs("span", { children: [
294
+ /* @__PURE__ */ jsx("kbd", { children: "↑" }),
295
+ /* @__PURE__ */ jsx("kbd", { children: "↓" }),
296
+ " 导航"
297
+ ] }),
298
+ /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("kbd", { children: "Enter" }), " 选择"] }),
299
+ /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("kbd", { children: "Esc" }), " 关闭"] })
300
+ ]
301
+ })
302
+ })
303
+ ]
304
+ })
305
+ });
306
+ };
307
+ var Search_default = Search;
308
+
309
+ //#endregion
310
+ //#region src/components/Header.tsx
311
+ const Header = ({ config, theme, currentRoute, sidebarCollapsed, onSidebarToggle, showNavigation = false, componentRegistry, onNavigate }) => {
312
+ const [searchVisible, setSearchVisible] = useState(false);
313
+ const headerConfig = config.layout?.header || {};
314
+ const searchConfig = config.search || {};
315
+ const handleSearchToggle = () => {
316
+ setSearchVisible(!searchVisible);
317
+ };
318
+ const handleSearchClose = () => {
319
+ setSearchVisible(false);
320
+ };
321
+ const renderLogo = () => {
322
+ if (!headerConfig.showLogo) return null;
323
+ return /* @__PURE__ */ jsx("div", {
324
+ className: "doc-header-logo",
325
+ children: config.logo ? /* @__PURE__ */ jsx("img", {
326
+ src: config.logo,
327
+ alt: config.title
328
+ }) : /* @__PURE__ */ jsx("div", {
329
+ className: "doc-header-logo-placeholder",
330
+ children: "📚"
331
+ })
332
+ });
333
+ };
334
+ const renderTitle = () => {
335
+ if (!headerConfig.showTitle || !config.title) return null;
336
+ return /* @__PURE__ */ jsxs("div", {
337
+ className: "doc-header-title",
338
+ children: [config.title, config.version && /* @__PURE__ */ jsxs("span", {
339
+ className: "doc-header-version",
340
+ children: ["v", config.version]
341
+ })]
342
+ });
343
+ };
344
+ const renderNavigation = () => {
345
+ if (!showNavigation || !componentRegistry) return null;
346
+ const components = componentRegistry.getComponentIds();
347
+ return /* @__PURE__ */ jsxs("nav", {
348
+ className: "doc-header-navigation",
349
+ children: [/* @__PURE__ */ jsx("a", {
350
+ className: `doc-header-nav-item ${currentRoute?.path === "/" ? "active" : ""}`,
351
+ onClick: (e) => {
352
+ e.preventDefault();
353
+ onNavigate?.("/");
354
+ },
355
+ href: "/",
356
+ children: "首页"
357
+ }), components.map((componentId) => {
358
+ const componentConfig = componentRegistry.getComponent(componentId);
359
+ const path = `/${componentId}`;
360
+ const isActive = currentRoute?.path === path;
361
+ return /* @__PURE__ */ jsx("a", {
362
+ className: `doc-header-nav-item ${isActive ? "active" : ""}`,
363
+ onClick: (e) => {
364
+ e.preventDefault();
365
+ onNavigate?.(path);
366
+ },
367
+ href: path,
368
+ children: componentConfig?.label || componentId
369
+ }, componentId);
370
+ })]
371
+ });
372
+ };
373
+ const renderActions = () => {
374
+ return /* @__PURE__ */ jsxs("div", {
375
+ className: "doc-header-actions",
376
+ children: [
377
+ searchConfig.enabled && headerConfig.showSearch && /* @__PURE__ */ jsx("button", {
378
+ className: "doc-header-action doc-header-search-button",
379
+ onClick: handleSearchToggle,
380
+ title: `搜索 (${searchConfig.hotkey || "Ctrl+K"})`,
381
+ children: "🔍"
382
+ }),
383
+ onSidebarToggle && /* @__PURE__ */ jsx("button", {
384
+ className: "doc-header-action doc-header-sidebar-toggle",
385
+ onClick: onSidebarToggle,
386
+ title: sidebarCollapsed ? "展开侧边栏" : "收起侧边栏",
387
+ children: sidebarCollapsed ? "☰" : "✕"
388
+ }),
389
+ config.github && /* @__PURE__ */ jsx("a", {
390
+ className: "doc-header-action doc-header-github",
391
+ href: config.github,
392
+ target: "_blank",
393
+ rel: "noopener noreferrer",
394
+ title: "GitHub",
395
+ children: /* @__PURE__ */ jsx("svg", {
396
+ width: "20",
397
+ height: "20",
398
+ viewBox: "0 0 24 24",
399
+ fill: "currentColor",
400
+ children: /* @__PURE__ */ jsx("path", { d: "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" })
401
+ })
402
+ })
403
+ ]
404
+ });
405
+ };
406
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("header", {
407
+ className: "doc-header",
408
+ children: /* @__PURE__ */ jsxs("div", {
409
+ className: "doc-header-content",
410
+ children: [
411
+ /* @__PURE__ */ jsxs("div", {
412
+ className: "doc-header-left",
413
+ children: [renderLogo(), renderTitle()]
414
+ }),
415
+ renderNavigation(),
416
+ /* @__PURE__ */ jsx("div", {
417
+ className: "doc-header-right",
418
+ children: renderActions()
419
+ })
420
+ ]
421
+ })
422
+ }), searchVisible && searchConfig.enabled && /* @__PURE__ */ jsx(Search_default, {
423
+ config: searchConfig,
424
+ componentRegistry,
425
+ onClose: handleSearchClose,
426
+ onNavigate
427
+ })] });
428
+ };
429
+ var Header_default = Header;
430
+
431
+ //#endregion
432
+ //#region src/components/CodeBlock.tsx
433
+ const CodeBlock = ({ code, language = "javascript", theme, showLineNumbers = false, highlightLines = [], className = "" }) => {
434
+ const codeRef = useRef(null);
435
+ useEffect(() => {
436
+ if (window.hljs && codeRef.current) window.hljs.highlightElement(codeRef.current);
437
+ }, [code, language]);
438
+ const renderLineNumbers = () => {
439
+ if (!showLineNumbers) return null;
440
+ const lines = code.split("\n");
441
+ return /* @__PURE__ */ jsx("div", {
442
+ className: "doc-code-line-numbers",
443
+ children: lines.map((_, index) => /* @__PURE__ */ jsx("div", {
444
+ className: `doc-code-line-number ${highlightLines.includes(index + 1) ? "highlighted" : ""}`,
445
+ children: index + 1
446
+ }, index))
447
+ });
448
+ };
449
+ const renderCode = () => {
450
+ if (showLineNumbers) {
451
+ const lines = code.split("\n");
452
+ return /* @__PURE__ */ jsx("div", {
453
+ className: "doc-code-content",
454
+ children: lines.map((line, index) => /* @__PURE__ */ jsx("div", {
455
+ className: `doc-code-line ${highlightLines.includes(index + 1) ? "highlighted" : ""}`,
456
+ children: line || " "
457
+ }, index))
458
+ });
459
+ }
460
+ return /* @__PURE__ */ jsx("pre", {
461
+ className: "doc-code-content",
462
+ children: /* @__PURE__ */ jsx("code", {
463
+ ref: codeRef,
464
+ className: `language-${language}`,
465
+ children: code
466
+ })
467
+ });
468
+ };
469
+ return /* @__PURE__ */ jsxs("div", {
470
+ className: `doc-code-block ${className}`,
471
+ children: [/* @__PURE__ */ jsx("div", {
472
+ className: "doc-code-header",
473
+ children: /* @__PURE__ */ jsx("span", {
474
+ className: "doc-code-language",
475
+ children: language
476
+ })
477
+ }), /* @__PURE__ */ jsxs("div", {
478
+ className: "doc-code-body",
479
+ children: [renderLineNumbers(), renderCode()]
480
+ })]
481
+ });
482
+ };
483
+ var CodeBlock_default = CodeBlock;
484
+
485
+ //#endregion
486
+ //#region src/components/Demo.tsx
487
+ const Demo = ({ demo, componentId, config, theme, renderer }) => {
488
+ const [codeVisible, setCodeVisible] = useState(false);
489
+ const [copied, setCopied] = useState(false);
490
+ const demoRef = useRef(null);
491
+ const demoConfig = config.demo || {};
492
+ const { showCode = true, codeCollapsed = true, showCopyButton = true, showExpandButton = true } = demoConfig;
493
+ useEffect(() => {
494
+ setCodeVisible(!codeCollapsed);
495
+ }, [codeCollapsed]);
496
+ const handleCodeToggle = () => {
497
+ setCodeVisible(!codeVisible);
498
+ };
499
+ const handleCopyCode = async () => {
500
+ if (!demo.code) return;
501
+ try {
502
+ await navigator.clipboard.writeText(demo.code);
503
+ setCopied(true);
504
+ setTimeout(() => setCopied(false), 2e3);
505
+ } catch (error) {
506
+ console.error("Failed to copy code:", error);
507
+ }
508
+ };
509
+ const renderDemo = () => {
510
+ if (!demo.component) return /* @__PURE__ */ jsx("div", {
511
+ className: "doc-demo-error",
512
+ children: /* @__PURE__ */ jsx("p", { children: "Demo组件加载失败" })
513
+ });
514
+ try {
515
+ const DemoComponent = demo.component;
516
+ return /* @__PURE__ */ jsx(DemoComponent, {});
517
+ } catch (error) {
518
+ console.error("Demo render error:", error);
519
+ return /* @__PURE__ */ jsx("div", {
520
+ className: "doc-demo-error",
521
+ children: /* @__PURE__ */ jsxs("p", { children: ["Demo渲染出错: ", error.message] })
522
+ });
523
+ }
524
+ };
525
+ const renderDescription = () => {
526
+ if (!demo.desc) return null;
527
+ if (demo.descFlag === false) return /* @__PURE__ */ jsx("div", {
528
+ className: "doc-demo-description",
529
+ children: demo.desc
530
+ });
531
+ const styledDesc = demo.desc.replace(/{([^}]+)}/g, "<span class=\"doc-demo-highlight\">$1</span>");
532
+ return /* @__PURE__ */ jsx("div", {
533
+ className: "doc-demo-description",
534
+ dangerouslySetInnerHTML: { __html: styledDesc }
535
+ });
536
+ };
537
+ return /* @__PURE__ */ jsxs("div", {
538
+ className: "doc-demo",
539
+ "data-demo": demo.source,
540
+ children: [
541
+ /* @__PURE__ */ jsxs("div", {
542
+ className: "doc-demo-header",
543
+ children: [/* @__PURE__ */ jsx("h3", {
544
+ className: "doc-demo-title",
545
+ children: demo.title
546
+ }), renderDescription()]
547
+ }),
548
+ /* @__PURE__ */ jsx("div", {
549
+ className: "doc-demo-content",
550
+ ref: demoRef,
551
+ children: renderDemo()
552
+ }),
553
+ showCode && demo.code && /* @__PURE__ */ jsxs(Fragment, { children: [codeVisible && /* @__PURE__ */ jsx("div", {
554
+ className: "doc-demo-code",
555
+ children: /* @__PURE__ */ jsx(CodeBlock_default, {
556
+ code: demo.code,
557
+ language: "jsx",
558
+ theme,
559
+ showLineNumbers: true
560
+ })
561
+ }), /* @__PURE__ */ jsxs("div", {
562
+ className: "doc-demo-actions",
563
+ children: [
564
+ showCopyButton && /* @__PURE__ */ jsx("button", {
565
+ className: "doc-demo-action",
566
+ onClick: handleCopyCode,
567
+ title: "复制代码",
568
+ children: copied ? "已复制" : "复制代码"
569
+ }),
570
+ showExpandButton && /* @__PURE__ */ jsx("button", {
571
+ className: "doc-demo-action",
572
+ onClick: handleCodeToggle,
573
+ title: codeVisible ? "隐藏代码" : "显示代码",
574
+ children: codeVisible ? "隐藏代码" : "显示代码"
575
+ }),
576
+ /* @__PURE__ */ jsx("button", {
577
+ className: "doc-demo-action",
578
+ onClick: () => {
579
+ renderer?.emit("demo.openInNewWindow", {
580
+ componentId,
581
+ demo
582
+ });
583
+ },
584
+ title: "在新窗口打开",
585
+ children: "新窗口打开"
586
+ })
587
+ ]
588
+ })] })
589
+ ]
590
+ });
591
+ };
592
+ var Demo_default = Demo;
593
+
594
+ //#endregion
595
+ //#region src/components/ApiDoc.tsx
596
+ const ApiDoc = ({ api, componentId, config, theme }) => {
597
+ const apiConfig = config.api || {};
598
+ const { showRequired = true, showType = true, showDefault = true, showDescription = true } = apiConfig;
599
+ const renderApiTable = () => {
600
+ if (!api.data || !Array.isArray(api.data) || api.data.length === 0) return /* @__PURE__ */ jsx("div", {
601
+ className: "doc-api-empty",
602
+ children: /* @__PURE__ */ jsx("p", { children: "暂无API文档" })
603
+ });
604
+ return /* @__PURE__ */ jsxs("div", {
605
+ className: "doc-api-table",
606
+ children: [/* @__PURE__ */ jsxs("div", {
607
+ className: "doc-api-table-header",
608
+ children: [
609
+ /* @__PURE__ */ jsx("div", {
610
+ className: "doc-api-table-cell doc-api-table-param",
611
+ children: "参数"
612
+ }),
613
+ showType && /* @__PURE__ */ jsx("div", {
614
+ className: "doc-api-table-cell doc-api-table-type",
615
+ children: "类型"
616
+ }),
617
+ showDescription && /* @__PURE__ */ jsx("div", {
618
+ className: "doc-api-table-cell doc-api-table-description",
619
+ children: "说明"
620
+ }),
621
+ /* @__PURE__ */ jsx("div", {
622
+ className: "doc-api-table-cell doc-api-table-option",
623
+ children: "可选值"
624
+ }),
625
+ showDefault && /* @__PURE__ */ jsx("div", {
626
+ className: "doc-api-table-cell doc-api-table-default",
627
+ children: "默认值"
628
+ }),
629
+ showRequired && /* @__PURE__ */ jsx("div", {
630
+ className: "doc-api-table-cell doc-api-table-required",
631
+ children: "必需"
632
+ })
633
+ ]
634
+ }), /* @__PURE__ */ jsx("div", {
635
+ className: "doc-api-table-body",
636
+ children: api.data.map((item, index) => /* @__PURE__ */ jsxs("div", {
637
+ className: "doc-api-table-row",
638
+ children: [
639
+ /* @__PURE__ */ jsxs("div", {
640
+ className: "doc-api-table-cell doc-api-table-param",
641
+ children: [/* @__PURE__ */ jsx("code", {
642
+ className: "doc-api-param-name",
643
+ children: item.param
644
+ }), item.deprecated && /* @__PURE__ */ jsx("span", {
645
+ className: "doc-api-deprecated",
646
+ children: "已废弃"
647
+ })]
648
+ }),
649
+ showType && /* @__PURE__ */ jsx("div", {
650
+ className: "doc-api-table-cell doc-api-table-type",
651
+ children: /* @__PURE__ */ jsx("code", {
652
+ className: "doc-api-type",
653
+ children: item.type
654
+ })
655
+ }),
656
+ showDescription && /* @__PURE__ */ jsx("div", {
657
+ className: "doc-api-table-cell doc-api-table-description",
658
+ children: renderDescription(item.desc, item.descFlag)
659
+ }),
660
+ /* @__PURE__ */ jsx("div", {
661
+ className: "doc-api-table-cell doc-api-table-option",
662
+ children: item.option && /* @__PURE__ */ jsx("code", {
663
+ className: "doc-api-option",
664
+ children: item.option
665
+ })
666
+ }),
667
+ showDefault && /* @__PURE__ */ jsx("div", {
668
+ className: "doc-api-table-cell doc-api-table-default",
669
+ children: item.default !== void 0 && item.default !== "" && /* @__PURE__ */ jsx("code", {
670
+ className: "doc-api-default",
671
+ children: String(item.default)
672
+ })
673
+ }),
674
+ showRequired && /* @__PURE__ */ jsx("div", {
675
+ className: "doc-api-table-cell doc-api-table-required",
676
+ children: item.required ? /* @__PURE__ */ jsx("span", {
677
+ className: "doc-api-required-yes",
678
+ children: "是"
679
+ }) : /* @__PURE__ */ jsx("span", {
680
+ className: "doc-api-required-no",
681
+ children: "否"
682
+ })
683
+ })
684
+ ]
685
+ }, index))
686
+ })]
687
+ });
688
+ };
689
+ const renderDescription = (desc, descFlag = true) => {
690
+ if (!desc) return null;
691
+ if (typeof desc === "string") if (descFlag) {
692
+ const styledDesc = desc.replace(/{([^}]+)}/g, "<span class=\"doc-api-highlight\">$1</span>");
693
+ return /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: styledDesc } });
694
+ } else return /* @__PURE__ */ jsx("div", { children: desc });
695
+ return desc;
696
+ };
697
+ const renderCustomContent = () => {
698
+ if (!api.CustomContent) return null;
699
+ try {
700
+ const CustomContent = api.CustomContent;
701
+ return /* @__PURE__ */ jsx(CustomContent, {});
702
+ } catch (error) {
703
+ console.error("API custom content render error:", error);
704
+ return null;
705
+ }
706
+ };
707
+ return /* @__PURE__ */ jsxs("div", {
708
+ className: "doc-api",
709
+ id: `api-${api.apiKey}`,
710
+ children: [
711
+ /* @__PURE__ */ jsxs("div", {
712
+ className: "doc-api-header",
713
+ children: [/* @__PURE__ */ jsx("h3", {
714
+ className: "doc-api-title",
715
+ children: api.title
716
+ }), api.description && /* @__PURE__ */ jsx("p", {
717
+ className: "doc-api-description",
718
+ children: api.description
719
+ })]
720
+ }),
721
+ renderCustomContent(),
722
+ renderApiTable(),
723
+ api.example && /* @__PURE__ */ jsxs("div", {
724
+ className: "doc-api-example",
725
+ children: [/* @__PURE__ */ jsx("h4", {
726
+ className: "doc-api-example-title",
727
+ children: "示例"
728
+ }), /* @__PURE__ */ jsx("pre", {
729
+ className: "doc-api-example-code",
730
+ children: /* @__PURE__ */ jsx("code", { children: api.example })
731
+ })]
732
+ }),
733
+ api.notes && /* @__PURE__ */ jsxs("div", {
734
+ className: "doc-api-notes",
735
+ children: [/* @__PURE__ */ jsx("h4", {
736
+ className: "doc-api-notes-title",
737
+ children: "注意事项"
738
+ }), /* @__PURE__ */ jsx("div", {
739
+ className: "doc-api-notes-content",
740
+ children: Array.isArray(api.notes) ? /* @__PURE__ */ jsx("ul", { children: api.notes.map((note, index) => /* @__PURE__ */ jsx("li", { children: note }, index)) }) : /* @__PURE__ */ jsx("p", { children: api.notes })
741
+ })]
742
+ })
743
+ ]
744
+ });
745
+ };
746
+ var ApiDoc_default = ApiDoc;
747
+
748
+ //#endregion
749
+ //#region src/components/Home.tsx
750
+ const Home = ({ config, theme, componentRegistry }) => {
751
+ const components = componentRegistry.getComponentIds();
752
+ const renderWelcome = () => /* @__PURE__ */ jsxs("div", {
753
+ className: "doc-home-welcome",
754
+ children: [
755
+ /* @__PURE__ */ jsx("h1", {
756
+ className: "doc-home-title",
757
+ children: config.title || "Documentation"
758
+ }),
759
+ config.description && /* @__PURE__ */ jsx("p", {
760
+ className: "doc-home-description",
761
+ children: config.description
762
+ }),
763
+ config.version && /* @__PURE__ */ jsxs("div", {
764
+ className: "doc-home-version",
765
+ children: ["当前版本: ", /* @__PURE__ */ jsx("code", { children: config.version })]
766
+ })
767
+ ]
768
+ });
769
+ const renderQuickStart = () => {
770
+ if (config.quickStart === false) return null;
771
+ return /* @__PURE__ */ jsxs("div", {
772
+ className: "doc-home-section",
773
+ children: [
774
+ /* @__PURE__ */ jsx("h2", {
775
+ className: "doc-home-section-title",
776
+ children: "快速开始"
777
+ }),
778
+ config.installation && /* @__PURE__ */ jsxs("div", {
779
+ className: "doc-home-installation",
780
+ children: [/* @__PURE__ */ jsx("h3", { children: "安装" }), /* @__PURE__ */ jsx("pre", {
781
+ className: "doc-home-code",
782
+ children: /* @__PURE__ */ jsx("code", { children: config.installation })
783
+ })]
784
+ }),
785
+ config.usage && /* @__PURE__ */ jsxs("div", {
786
+ className: "doc-home-usage",
787
+ children: [/* @__PURE__ */ jsx("h3", { children: "使用" }), /* @__PURE__ */ jsx("pre", {
788
+ className: "doc-home-code",
789
+ children: /* @__PURE__ */ jsx("code", { children: config.usage })
790
+ })]
791
+ })
792
+ ]
793
+ });
794
+ };
795
+ const renderComponents = () => {
796
+ if (components.length === 0) return null;
797
+ return /* @__PURE__ */ jsxs("div", {
798
+ className: "doc-home-section",
799
+ children: [/* @__PURE__ */ jsx("h2", {
800
+ className: "doc-home-section-title",
801
+ children: "组件列表"
802
+ }), /* @__PURE__ */ jsx("div", {
803
+ className: "doc-home-components",
804
+ children: components.map((componentId) => {
805
+ const componentConfig = componentRegistry.getComponent(componentId);
806
+ const demos = componentRegistry.getDemos(componentId);
807
+ return /* @__PURE__ */ jsxs("div", {
808
+ className: "doc-home-component-card",
809
+ children: [
810
+ /* @__PURE__ */ jsx("h3", {
811
+ className: "doc-home-component-title",
812
+ children: /* @__PURE__ */ jsx("a", {
813
+ href: `#/${componentId}`,
814
+ children: componentConfig?.label || componentId
815
+ })
816
+ }),
817
+ componentConfig?.description && /* @__PURE__ */ jsx("p", {
818
+ className: "doc-home-component-description",
819
+ children: componentConfig.description
820
+ }),
821
+ /* @__PURE__ */ jsxs("div", {
822
+ className: "doc-home-component-meta",
823
+ children: [/* @__PURE__ */ jsxs("span", {
824
+ className: "doc-home-component-demos",
825
+ children: [demos.size, " 个示例"]
826
+ }), componentConfig?.version && /* @__PURE__ */ jsxs("span", {
827
+ className: "doc-home-component-version",
828
+ children: ["v", componentConfig.version]
829
+ })]
830
+ })
831
+ ]
832
+ }, componentId);
833
+ })
834
+ })]
835
+ });
836
+ };
837
+ const renderFeatures = () => {
838
+ if (!config.features || !Array.isArray(config.features)) return null;
839
+ return /* @__PURE__ */ jsxs("div", {
840
+ className: "doc-home-section",
841
+ children: [/* @__PURE__ */ jsx("h2", {
842
+ className: "doc-home-section-title",
843
+ children: "特性"
844
+ }), /* @__PURE__ */ jsx("div", {
845
+ className: "doc-home-features",
846
+ children: config.features.map((feature, index) => /* @__PURE__ */ jsxs("div", {
847
+ className: "doc-home-feature",
848
+ children: [
849
+ feature.icon && /* @__PURE__ */ jsx("div", {
850
+ className: "doc-home-feature-icon",
851
+ children: feature.icon
852
+ }),
853
+ /* @__PURE__ */ jsx("h3", {
854
+ className: "doc-home-feature-title",
855
+ children: feature.title
856
+ }),
857
+ feature.description && /* @__PURE__ */ jsx("p", {
858
+ className: "doc-home-feature-description",
859
+ children: feature.description
860
+ })
861
+ ]
862
+ }, index))
863
+ })]
864
+ });
865
+ };
866
+ const renderCustomContent = () => {
867
+ if (!config.homeContent) return null;
868
+ if (typeof config.homeContent === "function") {
869
+ const CustomContent = config.homeContent;
870
+ return /* @__PURE__ */ jsx(CustomContent, {
871
+ config,
872
+ theme,
873
+ componentRegistry
874
+ });
875
+ }
876
+ if (typeof config.homeContent === "string") return /* @__PURE__ */ jsx("div", {
877
+ className: "doc-home-custom-content",
878
+ dangerouslySetInnerHTML: { __html: config.homeContent }
879
+ });
880
+ return config.homeContent;
881
+ };
882
+ return /* @__PURE__ */ jsxs("div", {
883
+ className: "doc-home",
884
+ children: [
885
+ renderWelcome(),
886
+ renderQuickStart(),
887
+ renderFeatures(),
888
+ renderComponents(),
889
+ renderCustomContent()
890
+ ]
891
+ });
892
+ };
893
+ var Home_default = Home;
894
+
895
+ //#endregion
896
+ //#region src/components/Content.tsx
897
+ const Content = ({ config, theme, currentRoute, componentRegistry, renderer }) => {
898
+ const renderContent = useMemo(() => {
899
+ if (!currentRoute) return /* @__PURE__ */ jsx("div", {
900
+ className: "doc-content-loading",
901
+ children: "加载中..."
902
+ });
903
+ if (currentRoute.component === "home" || currentRoute.path === "/") return /* @__PURE__ */ jsx(Home_default, {
904
+ config,
905
+ theme,
906
+ componentRegistry
907
+ });
908
+ const componentId = currentRoute.component;
909
+ const componentConfig = componentRegistry.getComponent(componentId);
910
+ if (!componentConfig) return /* @__PURE__ */ jsxs("div", {
911
+ className: "doc-content-not-found",
912
+ children: [/* @__PURE__ */ jsx("h1", { children: "页面未找到" }), /* @__PURE__ */ jsxs("p", { children: [
913
+ "组件 \"",
914
+ componentId,
915
+ "\" 不存在"
916
+ ] })]
917
+ });
918
+ return /* @__PURE__ */ jsx(ComponentPage, {
919
+ componentId,
920
+ componentConfig,
921
+ componentRegistry,
922
+ config,
923
+ theme,
924
+ renderer
925
+ });
926
+ }, [
927
+ currentRoute,
928
+ componentRegistry,
929
+ config,
930
+ theme,
931
+ renderer
932
+ ]);
933
+ return /* @__PURE__ */ jsx("main", {
934
+ className: "doc-content",
935
+ children: /* @__PURE__ */ jsx("div", {
936
+ className: "doc-content-container",
937
+ children: renderContent
938
+ })
939
+ });
940
+ };
941
+ const ComponentPage = ({ componentId, componentConfig, componentRegistry, config, theme, renderer }) => {
942
+ const demos = componentRegistry.getDemos(componentId);
943
+ const apis = componentRegistry.getApis(componentId);
944
+ return /* @__PURE__ */ jsxs("div", {
945
+ className: "doc-component-page",
946
+ children: [
947
+ /* @__PURE__ */ jsxs("div", {
948
+ className: "doc-component-header",
949
+ children: [
950
+ /* @__PURE__ */ jsx("h1", {
951
+ className: "doc-component-title",
952
+ children: componentConfig.label || componentId
953
+ }),
954
+ componentConfig.description && /* @__PURE__ */ jsx("p", {
955
+ className: "doc-component-description",
956
+ children: componentConfig.description
957
+ }),
958
+ componentConfig.version && /* @__PURE__ */ jsxs("div", {
959
+ className: "doc-component-version",
960
+ children: ["版本: ", componentConfig.version]
961
+ })
962
+ ]
963
+ }),
964
+ demos.size > 0 && /* @__PURE__ */ jsxs("div", {
965
+ className: "doc-component-demos",
966
+ children: [/* @__PURE__ */ jsx("h2", {
967
+ className: "doc-component-section-title",
968
+ children: "示例"
969
+ }), Array.from(demos.values()).map((demo, index) => /* @__PURE__ */ jsx(Demo_default, {
970
+ demo,
971
+ componentId,
972
+ config,
973
+ theme,
974
+ renderer
975
+ }, demo.source || index))]
976
+ }),
977
+ apis.size > 0 && /* @__PURE__ */ jsxs("div", {
978
+ className: "doc-component-apis",
979
+ children: [/* @__PURE__ */ jsx("h2", {
980
+ className: "doc-component-section-title",
981
+ id: "api",
982
+ children: "API"
983
+ }), Array.from(apis.values()).map((api, index) => /* @__PURE__ */ jsx(ApiDoc_default, {
984
+ api,
985
+ componentId,
986
+ config,
987
+ theme
988
+ }, api.apiKey || index))]
989
+ }),
990
+ componentConfig.extra && /* @__PURE__ */ jsx("div", {
991
+ className: "doc-component-extra",
992
+ children: typeof componentConfig.extra === "function" ? componentConfig.extra({
993
+ componentId,
994
+ config,
995
+ theme
996
+ }) : componentConfig.extra
997
+ })
998
+ ]
999
+ });
1000
+ };
1001
+ var Content_default = Content;
1002
+
1003
+ //#endregion
1004
+ //#region src/components/Footer.tsx
1005
+ const Footer = ({ config, theme }) => {
1006
+ const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
1007
+ const renderCopyright = () => {
1008
+ if (config.copyright === false) return null;
1009
+ const copyright = config.copyright || `© ${currentYear} ${config.title || "Documentation"}`;
1010
+ return /* @__PURE__ */ jsx("div", {
1011
+ className: "doc-footer-copyright",
1012
+ children: copyright
1013
+ });
1014
+ };
1015
+ const renderLinks = () => {
1016
+ if (!config.footerLinks || !Array.isArray(config.footerLinks)) return null;
1017
+ return /* @__PURE__ */ jsx("div", {
1018
+ className: "doc-footer-links",
1019
+ children: config.footerLinks.map((link, index) => /* @__PURE__ */ jsx("a", {
1020
+ href: link.url,
1021
+ target: link.external ? "_blank" : "_self",
1022
+ rel: link.external ? "noopener noreferrer" : void 0,
1023
+ className: "doc-footer-link",
1024
+ children: link.text
1025
+ }, index))
1026
+ });
1027
+ };
1028
+ const renderPoweredBy = () => {
1029
+ if (config.hidePoweredBy) return null;
1030
+ return /* @__PURE__ */ jsxs("div", {
1031
+ className: "doc-footer-powered",
1032
+ children: ["Powered by ", /* @__PURE__ */ jsx("a", {
1033
+ href: "https://github.com/your-org/doc-sdk",
1034
+ target: "_blank",
1035
+ rel: "noopener noreferrer",
1036
+ children: "Doc SDK"
1037
+ })]
1038
+ });
1039
+ };
1040
+ const renderCustomContent = () => {
1041
+ if (!config.footerContent) return null;
1042
+ if (typeof config.footerContent === "function") {
1043
+ const CustomContent = config.footerContent;
1044
+ return /* @__PURE__ */ jsx(CustomContent, {
1045
+ config,
1046
+ theme
1047
+ });
1048
+ }
1049
+ if (typeof config.footerContent === "string") return /* @__PURE__ */ jsx("div", {
1050
+ className: "doc-footer-custom",
1051
+ dangerouslySetInnerHTML: { __html: config.footerContent }
1052
+ });
1053
+ return config.footerContent;
1054
+ };
1055
+ return /* @__PURE__ */ jsx("footer", {
1056
+ className: "doc-footer",
1057
+ children: /* @__PURE__ */ jsxs("div", {
1058
+ className: "doc-footer-content",
1059
+ children: [
1060
+ renderCopyright(),
1061
+ renderLinks(),
1062
+ renderCustomContent(),
1063
+ renderPoweredBy()
1064
+ ]
1065
+ })
1066
+ });
1067
+ };
1068
+ var Footer_default = Footer;
1069
+
1070
+ //#endregion
1071
+ //#region src/components/Layout.tsx
1072
+ const Layout = ({ config, theme, renderer, routerManager, componentRegistry, onRouteChange }) => {
1073
+ const [currentRoute, setCurrentRoute] = useState(null);
1074
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
1075
+ useEffect(() => {
1076
+ const unsubscribe = routerManager.onRouteChange((route) => {
1077
+ setCurrentRoute(route);
1078
+ if (onRouteChange) onRouteChange(route);
1079
+ });
1080
+ setCurrentRoute(routerManager.getCurrentRoute());
1081
+ return unsubscribe;
1082
+ }, [routerManager, onRouteChange]);
1083
+ const layoutConfig = config.layout || {};
1084
+ const { type = "sidebar" } = layoutConfig;
1085
+ const handleSidebarToggle = () => {
1086
+ setSidebarCollapsed(!sidebarCollapsed);
1087
+ };
1088
+ const handleNavigate = (path, params) => {
1089
+ routerManager.navigate(path, params);
1090
+ };
1091
+ const renderSidebarLayout = () => /* @__PURE__ */ jsxs("div", {
1092
+ className: "doc-layout doc-layout-sidebar-type",
1093
+ children: [
1094
+ /* @__PURE__ */ jsx(Header_default, {
1095
+ config,
1096
+ theme,
1097
+ currentRoute,
1098
+ sidebarCollapsed,
1099
+ onSidebarToggle: handleSidebarToggle
1100
+ }),
1101
+ /* @__PURE__ */ jsxs("div", {
1102
+ className: "doc-layout-content",
1103
+ children: [!sidebarCollapsed && /* @__PURE__ */ jsx("div", {
1104
+ className: "doc-layout-sidebar",
1105
+ children: /* @__PURE__ */ jsx(Navigation_default, {
1106
+ config,
1107
+ theme,
1108
+ currentRoute,
1109
+ componentRegistry,
1110
+ onNavigate: handleNavigate
1111
+ })
1112
+ }), /* @__PURE__ */ jsx("div", {
1113
+ className: "doc-layout-main",
1114
+ children: /* @__PURE__ */ jsx(Content_default, {
1115
+ config,
1116
+ theme,
1117
+ currentRoute,
1118
+ componentRegistry,
1119
+ renderer
1120
+ })
1121
+ })]
1122
+ }),
1123
+ layoutConfig.footer?.show !== false && /* @__PURE__ */ jsx(Footer_default, {
1124
+ config,
1125
+ theme
1126
+ })
1127
+ ]
1128
+ });
1129
+ const renderTopLayout = () => /* @__PURE__ */ jsxs("div", {
1130
+ className: "doc-layout doc-layout-top-type",
1131
+ children: [
1132
+ /* @__PURE__ */ jsx(Header_default, {
1133
+ config,
1134
+ theme,
1135
+ currentRoute,
1136
+ showNavigation: true,
1137
+ componentRegistry,
1138
+ onNavigate: handleNavigate
1139
+ }),
1140
+ /* @__PURE__ */ jsx("div", {
1141
+ className: "doc-layout-content",
1142
+ children: /* @__PURE__ */ jsx("div", {
1143
+ className: "doc-layout-main",
1144
+ children: /* @__PURE__ */ jsx(Content_default, {
1145
+ config,
1146
+ theme,
1147
+ currentRoute,
1148
+ componentRegistry,
1149
+ renderer
1150
+ })
1151
+ })
1152
+ }),
1153
+ layoutConfig.footer?.show !== false && /* @__PURE__ */ jsx(Footer_default, {
1154
+ config,
1155
+ theme
1156
+ })
1157
+ ]
1158
+ });
1159
+ const renderMixedLayout = () => /* @__PURE__ */ jsxs("div", {
1160
+ className: "doc-layout doc-layout-mixed-type",
1161
+ children: [
1162
+ /* @__PURE__ */ jsx(Header_default, {
1163
+ config,
1164
+ theme,
1165
+ currentRoute,
1166
+ showNavigation: true,
1167
+ componentRegistry,
1168
+ onNavigate: handleNavigate
1169
+ }),
1170
+ /* @__PURE__ */ jsxs("div", {
1171
+ className: "doc-layout-content",
1172
+ children: [/* @__PURE__ */ jsx("div", {
1173
+ className: "doc-layout-sidebar",
1174
+ children: /* @__PURE__ */ jsx(Navigation_default, {
1175
+ config,
1176
+ theme,
1177
+ currentRoute,
1178
+ componentRegistry,
1179
+ onNavigate: handleNavigate,
1180
+ compact: true
1181
+ })
1182
+ }), /* @__PURE__ */ jsx("div", {
1183
+ className: "doc-layout-main",
1184
+ children: /* @__PURE__ */ jsx(Content_default, {
1185
+ config,
1186
+ theme,
1187
+ currentRoute,
1188
+ componentRegistry,
1189
+ renderer
1190
+ })
1191
+ })]
1192
+ }),
1193
+ layoutConfig.footer?.show !== false && /* @__PURE__ */ jsx(Footer_default, {
1194
+ config,
1195
+ theme
1196
+ })
1197
+ ]
1198
+ });
1199
+ switch (type) {
1200
+ case "top": return renderTopLayout();
1201
+ case "mixed": return renderMixedLayout();
1202
+ case "sidebar":
1203
+ default: return renderSidebarLayout();
1204
+ }
1205
+ };
1206
+ var Layout_default = Layout;
1207
+
1208
+ //#endregion
1209
+ //#region src/core/RouterManager.ts
1210
+ /**
1211
+ * 路由管理器
1212
+ * 负责管理文档站点的路由系统
1213
+ */
1214
+ var RouterManager = class {
1215
+ constructor(renderer) {
1216
+ this.renderer = renderer;
1217
+ this.currentRoute = null;
1218
+ this.routes = /* @__PURE__ */ new Map();
1219
+ this.listeners = /* @__PURE__ */ new Set();
1220
+ this.isInitialized = false;
1221
+ }
1222
+ /**
1223
+ * 初始化路由系统
1224
+ */
1225
+ initialize() {
1226
+ if (this.isInitialized) return;
1227
+ this.registerRoutes();
1228
+ window.addEventListener("hashchange", this.handleHashChange.bind(this));
1229
+ window.addEventListener("popstate", this.handlePopState.bind(this));
1230
+ this.handleInitialRoute();
1231
+ this.isInitialized = true;
1232
+ }
1233
+ /**
1234
+ * 注册路由
1235
+ */
1236
+ registerRoutes() {
1237
+ const config = this.renderer.configManager.getConfig();
1238
+ const { components = {} } = config;
1239
+ this.routes.set("/", {
1240
+ path: "/",
1241
+ component: "home",
1242
+ title: config.title || "Documentation"
1243
+ });
1244
+ Object.entries(components).forEach(([componentId, componentConfig]) => {
1245
+ const path = `/${componentId}`;
1246
+ this.routes.set(path, {
1247
+ path,
1248
+ component: componentId,
1249
+ title: componentConfig.label || componentId,
1250
+ config: componentConfig
1251
+ });
1252
+ });
1253
+ }
1254
+ /**
1255
+ * 处理初始路由
1256
+ */
1257
+ handleInitialRoute() {
1258
+ const hash = window.location.hash;
1259
+ const path = this.parseHashToPath(hash);
1260
+ this.navigate(path, {}, false);
1261
+ }
1262
+ /**
1263
+ * 处理hash变化
1264
+ */
1265
+ handleHashChange() {
1266
+ const hash = window.location.hash;
1267
+ const path = this.parseHashToPath(hash);
1268
+ this.navigate(path, {}, false);
1269
+ }
1270
+ /**
1271
+ * 处理浏览器前进后退
1272
+ */
1273
+ handlePopState(event) {
1274
+ if (event.state && event.state.path) this.navigate(event.state.path, event.state.params || {}, false);
1275
+ }
1276
+ /**
1277
+ * 解析hash为路径
1278
+ * @param {string} hash - URL hash
1279
+ * @returns {string} 路径
1280
+ */
1281
+ parseHashToPath(hash) {
1282
+ if (!hash || hash === "#") return "/";
1283
+ const hashWithoutSymbol = hash.substring(1);
1284
+ const [path, queryString] = hashWithoutSymbol.split("?");
1285
+ return path || "/";
1286
+ }
1287
+ /**
1288
+ * 解析查询参数
1289
+ * @param {string} queryString - 查询字符串
1290
+ * @returns {Object} 参数对象
1291
+ */
1292
+ parseQuery(queryString) {
1293
+ const params = {};
1294
+ if (!queryString) return params;
1295
+ queryString.split("&").forEach((param) => {
1296
+ const [key, value] = param.split("=");
1297
+ if (key) params[decodeURIComponent(key)] = decodeURIComponent(value || "");
1298
+ });
1299
+ return params;
1300
+ }
1301
+ /**
1302
+ * 导航到指定路径
1303
+ * @param {string} path - 路径
1304
+ * @param {Object} params - 参数
1305
+ * @param {boolean} pushState - 是否推入历史记录
1306
+ */
1307
+ navigate(path, params = {}, pushState = true) {
1308
+ const route = this.routes.get(path);
1309
+ if (!route) {
1310
+ console.warn(`Route not found: ${path}`);
1311
+ return this.navigate("/", {}, pushState);
1312
+ }
1313
+ const newRoute = {
1314
+ ...route,
1315
+ params,
1316
+ query: this.parseQuery(window.location.hash.split("?")[1])
1317
+ };
1318
+ this.currentRoute = newRoute;
1319
+ if (pushState) {
1320
+ const hash = this.buildHash(path, params);
1321
+ window.location.hash = hash;
1322
+ window.history.pushState({
1323
+ path,
1324
+ params
1325
+ }, newRoute.title, window.location.pathname + window.location.search + hash);
1326
+ }
1327
+ this.notifyRouteChange(newRoute);
1328
+ return newRoute;
1329
+ }
1330
+ /**
1331
+ * 构建hash
1332
+ * @param {string} path - 路径
1333
+ * @param {Object} params - 参数
1334
+ * @returns {string} hash字符串
1335
+ */
1336
+ buildHash(path, params = {}) {
1337
+ let hash = path === "/" ? "" : path;
1338
+ const queryParams = Object.entries(params).filter(([key, value]) => value !== void 0 && value !== null).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
1339
+ if (queryParams) hash += `?${queryParams}`;
1340
+ return hash;
1341
+ }
1342
+ /**
1343
+ * 获取当前路由
1344
+ * @returns {Object|null} 当前路由信息
1345
+ */
1346
+ getCurrentRoute() {
1347
+ return this.currentRoute;
1348
+ }
1349
+ /**
1350
+ * 监听路由变化
1351
+ * @param {Function} listener - 监听函数
1352
+ * @returns {Function} 取消监听的函数
1353
+ */
1354
+ onRouteChange(listener) {
1355
+ this.listeners.add(listener);
1356
+ return () => {
1357
+ this.listeners.delete(listener);
1358
+ };
1359
+ }
1360
+ /**
1361
+ * 通知路由变化
1362
+ * @param {Object} route - 路由信息
1363
+ */
1364
+ notifyRouteChange(route) {
1365
+ this.listeners.forEach((listener) => {
1366
+ try {
1367
+ listener(route);
1368
+ } catch (error) {
1369
+ console.error("Route change listener error:", error);
1370
+ }
1371
+ });
1372
+ if (this.renderer && typeof this.renderer.handleRouteChange === "function") this.renderer.handleRouteChange(route);
1373
+ }
1374
+ /**
1375
+ * 销毁路由管理器
1376
+ */
1377
+ destroy() {
1378
+ if (this.isInitialized) {
1379
+ window.removeEventListener("hashchange", this.handleHashChange.bind(this));
1380
+ window.removeEventListener("popstate", this.handlePopState.bind(this));
1381
+ this.listeners.clear();
1382
+ this.routes.clear();
1383
+ this.currentRoute = null;
1384
+ this.isInitialized = false;
1385
+ }
1386
+ }
1387
+ };
1388
+
1389
+ //#endregion
1390
+ //#region src/core/ComponentRegistry.ts
1391
+ /**
1392
+ * 组件注册表
1393
+ * 负责管理和注册文档组件
1394
+ */
1395
+ var ComponentRegistry = class {
1396
+ apis;
1397
+ demos;
1398
+ components;
1399
+ renderer;
1400
+ constructor(renderer) {
1401
+ this.renderer = renderer;
1402
+ this.components = /* @__PURE__ */ new Map();
1403
+ this.demos = /* @__PURE__ */ new Map();
1404
+ this.apis = /* @__PURE__ */ new Map();
1405
+ }
1406
+ /**
1407
+ * 注册组件
1408
+ * @param {string} componentId - 组件ID
1409
+ * @param {Object} componentConfig - 组件配置
1410
+ */
1411
+ async register(componentId, componentConfig) {
1412
+ try {
1413
+ this.components.set(componentId, componentConfig);
1414
+ if (componentConfig.demos && Array.isArray(componentConfig.demos)) await this.registerDemos(componentId, componentConfig.demos);
1415
+ if (componentConfig.apis && Array.isArray(componentConfig.apis)) await this.registerApis(componentId, componentConfig.apis);
1416
+ return true;
1417
+ } catch (error) {
1418
+ console.error(`Failed to register component ${componentId}:`, error);
1419
+ return false;
1420
+ }
1421
+ }
1422
+ /**
1423
+ * 注册组件demos
1424
+ * @param {string} componentId - 组件ID
1425
+ * @param {Array} demos - demo配置数组
1426
+ */
1427
+ async registerDemos(componentId, demos) {
1428
+ const componentDemos = /* @__PURE__ */ new Map();
1429
+ for (const demo of demos) try {
1430
+ const demoComponent = await this.loadDemo(componentId, demo);
1431
+ const demoCode = await this.loadDemoCode(componentId, demo);
1432
+ componentDemos.set(demo.source, {
1433
+ ...demo,
1434
+ component: demoComponent,
1435
+ code: demoCode
1436
+ });
1437
+ } catch (error) {
1438
+ console.error(`Failed to load demo ${demo.source} for component ${componentId}:`, error);
1439
+ }
1440
+ this.demos.set(componentId, componentDemos);
1441
+ }
1442
+ /**
1443
+ * 加载demo组件
1444
+ * @param {string} componentId - 组件ID
1445
+ * @param {Object} demo - demo配置
1446
+ * @returns {React.Component} demo组件
1447
+ */
1448
+ async loadDemo(componentId, demo) {
1449
+ try {
1450
+ const demoPath = `../components/${componentId}/demo/${demo.source}`;
1451
+ console.log({ demoPath });
1452
+ const module = await import(demoPath);
1453
+ return module.default || module;
1454
+ } catch (error) {
1455
+ const globalDemo = window.__DOC_SDK_DEMOS__?.[componentId]?.[demo.source];
1456
+ if (globalDemo) return globalDemo;
1457
+ throw new Error(`Demo component not found: ${componentId}/${demo.source}`);
1458
+ }
1459
+ }
1460
+ /**
1461
+ * 加载demo源码
1462
+ * @param {string} componentId - 组件ID
1463
+ * @param {Object} demo - demo配置
1464
+ * @returns {string} demo源码
1465
+ */
1466
+ async loadDemoCode(componentId, demo) {
1467
+ try {
1468
+ const globalCode = window.__DOC_SDK_DEMO_CODES__?.[componentId]?.[demo.source];
1469
+ if (globalCode) return globalCode;
1470
+ return `// Demo code for ${componentId}/${demo.source}\n// Code not available`;
1471
+ } catch (error) {
1472
+ console.error(`Failed to load demo code: ${componentId}/${demo.source}`, error);
1473
+ return "// Code not available";
1474
+ }
1475
+ }
1476
+ /**
1477
+ * 注册组件APIs
1478
+ * @param {string} componentId - 组件ID
1479
+ * @param {Array} apis - API配置数组
1480
+ */
1481
+ async registerApis(componentId, apis) {
1482
+ const componentApis = /* @__PURE__ */ new Map();
1483
+ for (const api of apis) try {
1484
+ const apiData = await this.loadApiData(componentId, api);
1485
+ componentApis.set(api.apiKey, {
1486
+ ...api,
1487
+ data: apiData
1488
+ });
1489
+ } catch (error) {
1490
+ console.error(`Failed to load API ${api.apiKey} for component ${componentId}:`, error);
1491
+ }
1492
+ this.apis.set(componentId, componentApis);
1493
+ }
1494
+ /**
1495
+ * 加载API数据
1496
+ * @param {string} componentId - 组件ID
1497
+ * @param {Object} api - API配置
1498
+ * @returns {Array} API数据
1499
+ */
1500
+ async loadApiData(componentId, api) {
1501
+ try {
1502
+ const globalApiData = window.__DOC_SDK_APIS__?.[componentId]?.[api.apiKey];
1503
+ console.log(globalApiData, "globalApiData");
1504
+ if (globalApiData) return globalApiData;
1505
+ const apiPath = `../components/${componentId}/api`;
1506
+ console.log(apiPath, "apiPath");
1507
+ const module = await import(apiPath);
1508
+ const apiData = module.default || module;
1509
+ return apiData[api.apiKey] || [];
1510
+ } catch (error) {
1511
+ console.error(`Failed to load API data: ${componentId}/${api.apiKey}`, error);
1512
+ return [];
1513
+ }
1514
+ }
1515
+ /**
1516
+ * 获取组件配置
1517
+ * @param {string} componentId - 组件ID
1518
+ * @returns {Object|null} 组件配置
1519
+ */
1520
+ getComponent(componentId) {
1521
+ return this.components.get(componentId) || null;
1522
+ }
1523
+ /**
1524
+ * 获取组件demos
1525
+ * @param {string} componentId - 组件ID
1526
+ * @returns {Map} demos Map
1527
+ */
1528
+ getDemos(componentId) {
1529
+ return this.demos.get(componentId) || /* @__PURE__ */ new Map();
1530
+ }
1531
+ /**
1532
+ * 获取特定demo
1533
+ * @param {string} componentId - 组件ID
1534
+ * @param {string} demoSource - demo源
1535
+ * @returns {Object|null} demo对象
1536
+ */
1537
+ getDemo(componentId, demoSource) {
1538
+ const componentDemos = this.getDemos(componentId);
1539
+ return componentDemos.get(demoSource) || null;
1540
+ }
1541
+ /**
1542
+ * 获取组件APIs
1543
+ * @param {string} componentId - 组件ID
1544
+ * @returns {Map} APIs Map
1545
+ */
1546
+ getApis(componentId) {
1547
+ return this.apis.get(componentId) || /* @__PURE__ */ new Map();
1548
+ }
1549
+ /**
1550
+ * 获取特定API
1551
+ * @param {string} componentId - 组件ID
1552
+ * @param {string} apiKey - API键
1553
+ * @returns {Object|null} API对象
1554
+ */
1555
+ getApi(componentId, apiKey) {
1556
+ const componentApis = this.getApis(componentId);
1557
+ return componentApis.get(apiKey) || null;
1558
+ }
1559
+ /**
1560
+ * 获取所有注册的组件ID
1561
+ * @returns {Array} 组件ID数组
1562
+ */
1563
+ getComponentIds() {
1564
+ return Array.from(this.components.keys());
1565
+ }
1566
+ /**
1567
+ * 检查组件是否已注册
1568
+ * @param {string} componentId - 组件ID
1569
+ * @returns {boolean} 是否已注册
1570
+ */
1571
+ hasComponent(componentId) {
1572
+ return this.components.has(componentId);
1573
+ }
1574
+ /**
1575
+ * 清空注册表
1576
+ */
1577
+ clear() {
1578
+ this.components.clear();
1579
+ this.demos.clear();
1580
+ this.apis.clear();
1581
+ }
1582
+ };
1583
+
1584
+ //#endregion
1585
+ //#region src/core/DocRenderer.ts
1586
+ var DocRenderer = class extends EventTarget {
1587
+ configManager;
1588
+ themeManager;
1589
+ pluginManager;
1590
+ routerManager;
1591
+ componentRegistry;
1592
+ targetElement;
1593
+ isRendered;
1594
+ constructor({ configManager, themeManager, pluginManager }) {
1595
+ super();
1596
+ this.configManager = configManager;
1597
+ this.themeManager = themeManager;
1598
+ this.pluginManager = pluginManager;
1599
+ this.routerManager = new RouterManager(this);
1600
+ this.componentRegistry = new ComponentRegistry(this);
1601
+ this.targetElement = null;
1602
+ this.isRendered = false;
1603
+ this.pluginManager.initialize(this);
1604
+ }
1605
+ /**
1606
+ * 渲染文档到指定容器
1607
+ * @param {string|HTMLElement} target - 目标容器
1608
+ */
1609
+ async render(target) {
1610
+ try {
1611
+ this.targetElement = typeof target === "string" ? document.querySelector(target) : target;
1612
+ if (!this.targetElement) throw new Error("Target element not found");
1613
+ await this.registerComponents();
1614
+ this.routerManager.initialize();
1615
+ this.renderLayout();
1616
+ this.isRendered = true;
1617
+ return this;
1618
+ } catch (error) {
1619
+ throw error;
1620
+ }
1621
+ }
1622
+ /**
1623
+ * 渲染主布局
1624
+ */
1625
+ renderLayout() {
1626
+ const config = this.configManager.getConfig();
1627
+ const theme = this.themeManager.getCurrentTheme();
1628
+ const layoutProps = {
1629
+ config,
1630
+ theme,
1631
+ renderer: this,
1632
+ routerManager: this.routerManager,
1633
+ componentRegistry: this.componentRegistry,
1634
+ onRouteChange: this.handleRouteChange.bind(this)
1635
+ };
1636
+ ReactDOM.render(React.createElement(Layout_default, layoutProps), this.targetElement);
1637
+ }
1638
+ /**
1639
+ * 注册组件
1640
+ */
1641
+ async registerComponents() {
1642
+ const config = this.configManager.getConfig();
1643
+ const { components = {} } = config;
1644
+ for (const [componentId, componentConfig] of Object.entries(components)) await this.componentRegistry.register(componentId, componentConfig);
1645
+ }
1646
+ /**
1647
+ * 处理路由变化
1648
+ * @param {Object} route - 路由信息
1649
+ */
1650
+ handleRouteChange(route) {
1651
+ if (route.title) document.title = `${route.title} - ${this.configManager.get("title", "Documentation")}`;
1652
+ }
1653
+ /**
1654
+ * 更新渲染
1655
+ */
1656
+ update() {
1657
+ if (this.isRendered) this.renderLayout();
1658
+ return this;
1659
+ }
1660
+ /**
1661
+ * 销毁渲染器
1662
+ */
1663
+ destroy() {
1664
+ if (this.targetElement && this.isRendered) {
1665
+ ReactDOM.unmountComponentAtNode(this.targetElement);
1666
+ this.routerManager.destroy();
1667
+ this.componentRegistry.clear();
1668
+ this.isRendered = false;
1669
+ }
1670
+ return this;
1671
+ }
1672
+ /**
1673
+ * 获取组件注册表
1674
+ */
1675
+ getComponentRegistry() {
1676
+ return this.componentRegistry;
1677
+ }
1678
+ /**
1679
+ * 获取路由管理器
1680
+ */
1681
+ getRouterManager() {
1682
+ return this.routerManager;
1683
+ }
1684
+ /**
1685
+ * 获取当前路由
1686
+ */
1687
+ getCurrentRoute() {
1688
+ return this.routerManager.getCurrentRoute();
1689
+ }
1690
+ /**
1691
+ * 导航到指定路由
1692
+ * @param {string} path - 路由路径
1693
+ * @param {Object} params - 路由参数
1694
+ */
1695
+ navigate(path, params = {}) {
1696
+ return this.routerManager.navigate(path, params);
1697
+ }
1698
+ };
1699
+
1700
+ //#endregion
1701
+ //#region src/config/default.ts
1702
+ const defaultConfig = {
1703
+ title: "Documentation",
1704
+ description: "Component Documentation Site",
1705
+ version: "1.0.0",
1706
+ theme: {
1707
+ name: "default",
1708
+ colors: {},
1709
+ typography: {},
1710
+ spacing: {},
1711
+ layout: {}
1712
+ },
1713
+ layout: {
1714
+ type: "sidebar",
1715
+ sidebar: {
1716
+ width: 280,
1717
+ collapsible: true,
1718
+ defaultCollapsed: false
1719
+ },
1720
+ header: {
1721
+ height: 64,
1722
+ showLogo: true,
1723
+ showTitle: true,
1724
+ showSearch: true
1725
+ },
1726
+ content: {
1727
+ maxWidth: 1200,
1728
+ padding: 24
1729
+ },
1730
+ footer: {
1731
+ show: true,
1732
+ height: 60
1733
+ }
1734
+ },
1735
+ components: {},
1736
+ navigation: {
1737
+ mode: "auto",
1738
+ groups: [],
1739
+ showHome: true,
1740
+ homeTitle: "首页"
1741
+ },
1742
+ search: {
1743
+ enabled: true,
1744
+ placeholder: "搜索文档...",
1745
+ hotkey: "ctrl+k"
1746
+ },
1747
+ highlight: {
1748
+ theme: "github",
1749
+ languages: [
1750
+ "javascript",
1751
+ "jsx",
1752
+ "typescript",
1753
+ "tsx",
1754
+ "css",
1755
+ "less",
1756
+ "scss",
1757
+ "html",
1758
+ "json"
1759
+ ]
1760
+ },
1761
+ demo: {
1762
+ showCode: true,
1763
+ codeCollapsed: true,
1764
+ showCopyButton: true,
1765
+ showExpandButton: true
1766
+ },
1767
+ api: {
1768
+ showRequired: true,
1769
+ showType: true,
1770
+ showDefault: true,
1771
+ showDescription: true
1772
+ },
1773
+ plugins: [],
1774
+ dev: {
1775
+ hot: true,
1776
+ port: 8080,
1777
+ host: "localhost",
1778
+ open: true
1779
+ },
1780
+ build: {
1781
+ outDir: "dist",
1782
+ publicPath: "/",
1783
+ sourcemap: false,
1784
+ minify: true
1785
+ },
1786
+ router: {
1787
+ mode: "hash",
1788
+ base: "/"
1789
+ },
1790
+ i18n: {
1791
+ enabled: false,
1792
+ defaultLocale: "zh-CN",
1793
+ locales: ["zh-CN", "en-US"]
1794
+ },
1795
+ seo: {
1796
+ keywords: [],
1797
+ author: "",
1798
+ favicon: ""
1799
+ },
1800
+ analytics: {
1801
+ enabled: false,
1802
+ providers: []
1803
+ }
1804
+ };
1805
+ var default_default$1 = defaultConfig;
1806
+
1807
+ //#endregion
1808
+ //#region src/core/ConfigManager.ts
1809
+ var ConfigManager = class {
1810
+ config;
1811
+ listeners;
1812
+ constructor(userConfig = {}) {
1813
+ this.config = this.mergeConfig(default_default$1, userConfig);
1814
+ this.listeners = /* @__PURE__ */ new Set();
1815
+ }
1816
+ /**
1817
+ * 合并配置
1818
+ */
1819
+ mergeConfig(defaultConfig$1, userConfig) {
1820
+ return merge(cloneDeep(defaultConfig$1), userConfig);
1821
+ }
1822
+ /**
1823
+ * 获取完整配置
1824
+ */
1825
+ getConfig() {
1826
+ return cloneDeep(this.config);
1827
+ }
1828
+ /**
1829
+ * 获取配置项
1830
+ */
1831
+ get(path, defaultValue) {
1832
+ if (!path) return this.getConfig();
1833
+ return get$1(this.config, path, defaultValue);
1834
+ }
1835
+ /**
1836
+ * 设置配置项
1837
+ */
1838
+ set(path, value) {
1839
+ const oldValue = this.get(path);
1840
+ set$1(this.config, path, value);
1841
+ this.notifyChange(path, value, oldValue);
1842
+ }
1843
+ /**
1844
+ * 更新配置
1845
+ */
1846
+ update(newConfig) {
1847
+ const oldConfig = cloneDeep(this.config);
1848
+ this.config = this.mergeConfig(this.config, newConfig);
1849
+ this.notifyChange("*", this.config, oldConfig);
1850
+ }
1851
+ /**
1852
+ * 重置配置
1853
+ */
1854
+ reset(newConfig = {}) {
1855
+ const oldConfig = cloneDeep(this.config);
1856
+ this.config = this.mergeConfig(default_default$1, newConfig);
1857
+ this.notifyChange("*", this.config, oldConfig);
1858
+ }
1859
+ /**
1860
+ * 监听配置变化
1861
+ */
1862
+ onChange(listener) {
1863
+ this.listeners.add(listener);
1864
+ return () => {
1865
+ this.listeners.delete(listener);
1866
+ };
1867
+ }
1868
+ /**
1869
+ * 通知配置变化
1870
+ */
1871
+ notifyChange(path, newValue, oldValue) {
1872
+ this.listeners.forEach((listener) => {
1873
+ try {
1874
+ listener({
1875
+ path,
1876
+ newValue,
1877
+ oldValue,
1878
+ config: this.config
1879
+ });
1880
+ } catch (error) {
1881
+ console.error("Config change listener error:", error);
1882
+ }
1883
+ });
1884
+ }
1885
+ /**
1886
+ * 验证配置
1887
+ * @param {Object} config - 要验证的配置
1888
+ * @returns {Object} 验证结果
1889
+ */
1890
+ validate(config = this.config) {
1891
+ const errors = [];
1892
+ const warnings = [];
1893
+ if (!config.title) warnings.push("Missing title in config");
1894
+ if (!config.components || Object.keys(config.components).length === 0) warnings.push("No components defined in config");
1895
+ if (config.components) Object.entries(config.components).forEach(([id, component]) => {
1896
+ if (!component.label) warnings.push(`Component ${id} missing label`);
1897
+ if (!component.demos || !Array.isArray(component.demos)) warnings.push(`Component ${id} missing demos array`);
1898
+ });
1899
+ return {
1900
+ isValid: errors.length === 0,
1901
+ errors,
1902
+ warnings
1903
+ };
1904
+ }
1905
+ /**
1906
+ * 获取组件配置
1907
+ * @param {string} componentId - 组件ID
1908
+ * @returns {Object|null} 组件配置
1909
+ */
1910
+ getComponent(componentId) {
1911
+ return this.get(`components.${componentId}`, null);
1912
+ }
1913
+ /**
1914
+ * 获取所有组件配置
1915
+ * @returns {Object} 组件配置对象
1916
+ */
1917
+ getComponents() {
1918
+ return this.get("components", {});
1919
+ }
1920
+ /**
1921
+ * 获取主题配置
1922
+ * @returns {Object} 主题配置
1923
+ */
1924
+ getTheme() {
1925
+ return this.get("theme", {});
1926
+ }
1927
+ /**
1928
+ * 获取布局配置
1929
+ * @returns {Object} 布局配置
1930
+ */
1931
+ getLayout() {
1932
+ return this.get("layout", {});
1933
+ }
1934
+ /**
1935
+ * 获取插件配置
1936
+ * @returns {Array} 插件配置数组
1937
+ */
1938
+ getPlugins() {
1939
+ return this.get("plugins", []);
1940
+ }
1941
+ };
1942
+
1943
+ //#endregion
1944
+ //#region src/themes/default.ts
1945
+ /**
1946
+ * 默认主题
1947
+ */
1948
+ var default_default = {
1949
+ name: "default",
1950
+ colors: {
1951
+ primary: "#1890ff",
1952
+ primaryHover: "#40a9ff",
1953
+ primaryActive: "#096dd9",
1954
+ success: "#52c41a",
1955
+ successHover: "#73d13d",
1956
+ successActive: "#389e0d",
1957
+ warning: "#faad14",
1958
+ warningHover: "#ffc53d",
1959
+ warningActive: "#d48806",
1960
+ error: "#ff4d4f",
1961
+ errorHover: "#ff7875",
1962
+ errorActive: "#d9363e",
1963
+ text: "#262626",
1964
+ textSecondary: "#595959",
1965
+ textTertiary: "#8c8c8c",
1966
+ textQuaternary: "#bfbfbf",
1967
+ background: "#ffffff",
1968
+ backgroundSecondary: "#fafafa",
1969
+ backgroundTertiary: "#f5f5f5",
1970
+ border: "#d9d9d9",
1971
+ borderSecondary: "#f0f0f0",
1972
+ shadow: "rgba(0, 0, 0, 0.15)",
1973
+ shadowSecondary: "rgba(0, 0, 0, 0.06)",
1974
+ code: {
1975
+ background: "#f6f8fa",
1976
+ border: "#e1e4e8",
1977
+ text: "#24292e",
1978
+ keyword: "#d73a49",
1979
+ string: "#032f62",
1980
+ comment: "#6a737d",
1981
+ number: "#005cc5",
1982
+ function: "#6f42c1"
1983
+ }
1984
+ },
1985
+ typography: {
1986
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif",
1987
+ fontFamilyCode: "SFMono-Regular, Consolas, \"Liberation Mono\", Menlo, Courier, monospace",
1988
+ fontSize: {
1989
+ xs: "12px",
1990
+ sm: "14px",
1991
+ base: "16px",
1992
+ lg: "18px",
1993
+ xl: "20px",
1994
+ "2xl": "24px",
1995
+ "3xl": "30px",
1996
+ "4xl": "36px"
1997
+ },
1998
+ lineHeight: {
1999
+ tight: 1.25,
2000
+ normal: 1.5,
2001
+ relaxed: 1.75
2002
+ },
2003
+ fontWeight: {
2004
+ normal: 400,
2005
+ medium: 500,
2006
+ semibold: 600,
2007
+ bold: 700
2008
+ }
2009
+ },
2010
+ spacing: {
2011
+ xs: "4px",
2012
+ sm: "8px",
2013
+ md: "16px",
2014
+ lg: "24px",
2015
+ xl: "32px",
2016
+ "2xl": "48px",
2017
+ "3xl": "64px",
2018
+ "4xl": "96px"
2019
+ },
2020
+ layout: {
2021
+ sidebarWidth: "280px",
2022
+ headerHeight: "64px",
2023
+ footerHeight: "60px",
2024
+ contentMaxWidth: "1200px",
2025
+ borderRadius: "6px",
2026
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)"
2027
+ },
2028
+ components: {
2029
+ layout: `
2030
+ .doc-layout {
2031
+ min-height: 100vh;
2032
+ display: flex;
2033
+ flex-direction: column;
2034
+ }
2035
+
2036
+ .doc-layout-header {
2037
+ background: var(--doc-color-background);
2038
+ border-bottom: 1px solid var(--doc-color-border);
2039
+ box-shadow: var(--doc-layout-boxShadow);
2040
+ z-index: 100;
2041
+ }
2042
+
2043
+ .doc-layout-content {
2044
+ flex: 1;
2045
+ display: flex;
2046
+ }
2047
+
2048
+ .doc-layout-sidebar {
2049
+ width: var(--doc-layout-sidebarWidth);
2050
+ background: var(--doc-color-background);
2051
+ border-right: 1px solid var(--doc-color-border);
2052
+ overflow-y: auto;
2053
+ }
2054
+
2055
+ .doc-layout-main {
2056
+ flex: 1;
2057
+ background: var(--doc-color-backgroundSecondary);
2058
+ overflow-y: auto;
2059
+ }
2060
+
2061
+ .doc-layout-footer {
2062
+ background: var(--doc-color-background);
2063
+ border-top: 1px solid var(--doc-color-border);
2064
+ text-align: center;
2065
+ padding: var(--doc-spacing-md);
2066
+ color: var(--doc-color-textSecondary);
2067
+ }
2068
+ `,
2069
+ header: `
2070
+ .doc-header {
2071
+ height: var(--doc-layout-headerHeight);
2072
+ display: flex;
2073
+ align-items: center;
2074
+ padding: 0 var(--doc-spacing-lg);
2075
+ }
2076
+
2077
+ .doc-header-content {
2078
+ width: 100%;
2079
+ display: flex;
2080
+ align-items: center;
2081
+ justify-content: space-between;
2082
+ }
2083
+
2084
+ .doc-header-left {
2085
+ display: flex;
2086
+ align-items: center;
2087
+ gap: var(--doc-spacing-md);
2088
+ }
2089
+
2090
+ .doc-header-logo img {
2091
+ height: 32px;
2092
+ width: auto;
2093
+ }
2094
+
2095
+ .doc-header-logo-placeholder {
2096
+ font-size: 24px;
2097
+ }
2098
+
2099
+ .doc-header-title {
2100
+ font-size: var(--doc-typography-fontSize-lg);
2101
+ font-weight: var(--doc-typography-fontWeight-bold);
2102
+ color: var(--doc-color-text);
2103
+ }
2104
+
2105
+ .doc-header-version {
2106
+ margin-left: var(--doc-spacing-sm);
2107
+ font-size: var(--doc-typography-fontSize-sm);
2108
+ color: var(--doc-color-textSecondary);
2109
+ background: var(--doc-color-backgroundTertiary);
2110
+ padding: 2px 6px;
2111
+ border-radius: 3px;
2112
+ }
2113
+
2114
+ .doc-header-navigation {
2115
+ display: flex;
2116
+ gap: var(--doc-spacing-lg);
2117
+ }
2118
+
2119
+ .doc-header-nav-item {
2120
+ color: var(--doc-color-text);
2121
+ text-decoration: none;
2122
+ padding: var(--doc-spacing-sm) var(--doc-spacing-md);
2123
+ border-radius: var(--doc-layout-borderRadius);
2124
+ transition: all 0.2s ease;
2125
+ }
2126
+
2127
+ .doc-header-nav-item:hover {
2128
+ background: var(--doc-color-backgroundTertiary);
2129
+ color: var(--doc-color-primary);
2130
+ }
2131
+
2132
+ .doc-header-nav-item.active {
2133
+ background: var(--doc-color-primary);
2134
+ color: white;
2135
+ }
2136
+
2137
+ .doc-header-actions {
2138
+ display: flex;
2139
+ align-items: center;
2140
+ gap: var(--doc-spacing-sm);
2141
+ }
2142
+
2143
+ .doc-header-action {
2144
+ padding: var(--doc-spacing-sm);
2145
+ background: none;
2146
+ border: none;
2147
+ color: var(--doc-color-textSecondary);
2148
+ cursor: pointer;
2149
+ border-radius: var(--doc-layout-borderRadius);
2150
+ transition: all 0.2s ease;
2151
+ text-decoration: none;
2152
+ display: flex;
2153
+ align-items: center;
2154
+ justify-content: center;
2155
+ }
2156
+
2157
+ .doc-header-action:hover {
2158
+ background: var(--doc-color-backgroundTertiary);
2159
+ color: var(--doc-color-primary);
2160
+ }
2161
+ `,
2162
+ navigation: `
2163
+ .doc-navigation {
2164
+ padding: var(--doc-spacing-md);
2165
+ }
2166
+
2167
+ .doc-navigation-title {
2168
+ font-size: var(--doc-typography-fontSize-lg);
2169
+ font-weight: var(--doc-typography-fontWeight-bold);
2170
+ color: var(--doc-color-text);
2171
+ margin-bottom: var(--doc-spacing-lg);
2172
+ padding: 0 var(--doc-spacing-sm);
2173
+ }
2174
+
2175
+ .doc-navigation-group {
2176
+ margin-bottom: var(--doc-spacing-lg);
2177
+ }
2178
+
2179
+ .doc-navigation-group-title {
2180
+ font-size: var(--doc-typography-fontSize-sm);
2181
+ font-weight: var(--doc-typography-fontWeight-medium);
2182
+ color: var(--doc-color-textSecondary);
2183
+ text-transform: uppercase;
2184
+ letter-spacing: 0.5px;
2185
+ margin-bottom: var(--doc-spacing-sm);
2186
+ padding: 0 var(--doc-spacing-sm);
2187
+ }
2188
+
2189
+ .doc-navigation-item {
2190
+ display: block;
2191
+ padding: var(--doc-spacing-sm) var(--doc-spacing-md);
2192
+ color: var(--doc-color-text);
2193
+ text-decoration: none;
2194
+ border-radius: var(--doc-layout-borderRadius);
2195
+ transition: all 0.2s ease;
2196
+ margin-bottom: 2px;
2197
+ }
2198
+
2199
+ .doc-navigation-item:hover {
2200
+ background: var(--doc-color-backgroundTertiary);
2201
+ color: var(--doc-color-primary);
2202
+ }
2203
+
2204
+ .doc-navigation-item.active {
2205
+ background: var(--doc-color-primary);
2206
+ color: white;
2207
+ }
2208
+ `,
2209
+ content: `
2210
+ .doc-content {
2211
+ flex: 1;
2212
+ padding: var(--doc-spacing-lg);
2213
+ }
2214
+
2215
+ .doc-content-container {
2216
+ max-width: var(--doc-layout-contentMaxWidth);
2217
+ margin: 0 auto;
2218
+ }
2219
+
2220
+ .doc-content-loading {
2221
+ text-align: center;
2222
+ padding: var(--doc-spacing-4xl);
2223
+ color: var(--doc-color-textSecondary);
2224
+ }
2225
+
2226
+ .doc-content-not-found {
2227
+ text-align: center;
2228
+ padding: var(--doc-spacing-4xl);
2229
+ }
2230
+
2231
+ .doc-content-not-found h1 {
2232
+ font-size: var(--doc-typography-fontSize-3xl);
2233
+ color: var(--doc-color-text);
2234
+ margin-bottom: var(--doc-spacing-md);
2235
+ }
2236
+
2237
+ .doc-content-not-found p {
2238
+ color: var(--doc-color-textSecondary);
2239
+ }
2240
+
2241
+ .doc-component-page {
2242
+ padding: var(--doc-spacing-lg) 0;
2243
+ }
2244
+
2245
+ .doc-component-header {
2246
+ margin-bottom: var(--doc-spacing-2xl);
2247
+ padding-bottom: var(--doc-spacing-lg);
2248
+ border-bottom: 1px solid var(--doc-color-border);
2249
+ }
2250
+
2251
+ .doc-component-title {
2252
+ font-size: var(--doc-typography-fontSize-4xl);
2253
+ font-weight: var(--doc-typography-fontWeight-bold);
2254
+ color: var(--doc-color-text);
2255
+ margin-bottom: var(--doc-spacing-md);
2256
+ }
2257
+
2258
+ .doc-component-description {
2259
+ font-size: var(--doc-typography-fontSize-lg);
2260
+ color: var(--doc-color-textSecondary);
2261
+ line-height: var(--doc-typography-lineHeight-relaxed);
2262
+ margin-bottom: var(--doc-spacing-md);
2263
+ }
2264
+
2265
+ .doc-component-version {
2266
+ font-size: var(--doc-typography-fontSize-sm);
2267
+ color: var(--doc-color-textTertiary);
2268
+ }
2269
+
2270
+ .doc-component-section-title {
2271
+ font-size: var(--doc-typography-fontSize-2xl);
2272
+ font-weight: var(--doc-typography-fontWeight-semibold);
2273
+ color: var(--doc-color-text);
2274
+ margin: var(--doc-spacing-2xl) 0 var(--doc-spacing-lg) 0;
2275
+ padding-bottom: var(--doc-spacing-sm);
2276
+ border-bottom: 1px solid var(--doc-color-borderSecondary);
2277
+ }
2278
+ `,
2279
+ demo: `
2280
+ .doc-demo {
2281
+ margin-bottom: var(--doc-spacing-2xl);
2282
+ border: 1px solid var(--doc-color-border);
2283
+ border-radius: var(--doc-layout-borderRadius);
2284
+ overflow: hidden;
2285
+ background: var(--doc-color-background);
2286
+ }
2287
+
2288
+ .doc-demo-header {
2289
+ padding: var(--doc-spacing-lg);
2290
+ background: var(--doc-color-background);
2291
+ border-bottom: 1px solid var(--doc-color-borderSecondary);
2292
+ }
2293
+
2294
+ .doc-demo-title {
2295
+ font-size: var(--doc-typography-fontSize-lg);
2296
+ font-weight: var(--doc-typography-fontWeight-medium);
2297
+ color: var(--doc-color-text);
2298
+ margin-bottom: var(--doc-spacing-sm);
2299
+ }
2300
+
2301
+ .doc-demo-description {
2302
+ color: var(--doc-color-textSecondary);
2303
+ line-height: var(--doc-typography-lineHeight-relaxed);
2304
+ }
2305
+
2306
+ .doc-demo-highlight {
2307
+ background: var(--doc-color-warning);
2308
+ color: var(--doc-color-background);
2309
+ padding: 2px 4px;
2310
+ border-radius: 3px;
2311
+ font-size: 0.9em;
2312
+ }
2313
+
2314
+ .doc-demo-content {
2315
+ padding: var(--doc-spacing-xl);
2316
+ background: var(--doc-color-background);
2317
+ min-height: 100px;
2318
+ }
2319
+
2320
+ .doc-demo-error {
2321
+ padding: var(--doc-spacing-lg);
2322
+ background: var(--doc-color-error);
2323
+ color: white;
2324
+ text-align: center;
2325
+ border-radius: var(--doc-layout-borderRadius);
2326
+ }
2327
+
2328
+ .doc-demo-code {
2329
+ background: var(--doc-color-code-background);
2330
+ border-top: 1px solid var(--doc-color-border);
2331
+ }
2332
+
2333
+ .doc-demo-actions {
2334
+ display: flex;
2335
+ justify-content: flex-end;
2336
+ gap: var(--doc-spacing-sm);
2337
+ padding: var(--doc-spacing-sm) var(--doc-spacing-md);
2338
+ background: var(--doc-color-backgroundTertiary);
2339
+ border-top: 1px solid var(--doc-color-border);
2340
+ }
2341
+
2342
+ .doc-demo-action {
2343
+ padding: var(--doc-spacing-xs) var(--doc-spacing-sm);
2344
+ background: none;
2345
+ border: none;
2346
+ color: var(--doc-color-textSecondary);
2347
+ cursor: pointer;
2348
+ font-size: var(--doc-typography-fontSize-sm);
2349
+ transition: all 0.2s ease;
2350
+ border-radius: 3px;
2351
+ }
2352
+
2353
+ .doc-demo-action:hover {
2354
+ color: var(--doc-color-primary);
2355
+ background: var(--doc-color-backgroundSecondary);
2356
+ }
2357
+ `,
2358
+ api: `
2359
+ .doc-api {
2360
+ margin-bottom: var(--doc-spacing-2xl);
2361
+ }
2362
+
2363
+ .doc-api-header {
2364
+ margin-bottom: var(--doc-spacing-lg);
2365
+ }
2366
+
2367
+ .doc-api-title {
2368
+ font-size: var(--doc-typography-fontSize-xl);
2369
+ font-weight: var(--doc-typography-fontWeight-semibold);
2370
+ color: var(--doc-color-text);
2371
+ margin-bottom: var(--doc-spacing-sm);
2372
+ }
2373
+
2374
+ .doc-api-description {
2375
+ color: var(--doc-color-textSecondary);
2376
+ line-height: var(--doc-typography-lineHeight-relaxed);
2377
+ }
2378
+
2379
+ .doc-api-table {
2380
+ border: 1px solid var(--doc-color-border);
2381
+ border-radius: var(--doc-layout-borderRadius);
2382
+ overflow: hidden;
2383
+ background: var(--doc-color-background);
2384
+ }
2385
+
2386
+ .doc-api-table-header {
2387
+ display: grid;
2388
+ grid-template-columns: 1fr 1fr 2fr 1fr 1fr 80px;
2389
+ background: var(--doc-color-backgroundTertiary);
2390
+ border-bottom: 1px solid var(--doc-color-border);
2391
+ font-weight: var(--doc-typography-fontWeight-medium);
2392
+ }
2393
+
2394
+ .doc-api-table-cell {
2395
+ padding: var(--doc-spacing-md);
2396
+ border-right: 1px solid var(--doc-color-borderSecondary);
2397
+ font-size: var(--doc-typography-fontSize-sm);
2398
+ }
2399
+
2400
+ .doc-api-table-cell:last-child {
2401
+ border-right: none;
2402
+ }
2403
+
2404
+ .doc-api-table-row {
2405
+ display: grid;
2406
+ grid-template-columns: 1fr 1fr 2fr 1fr 1fr 80px;
2407
+ border-bottom: 1px solid var(--doc-color-borderSecondary);
2408
+ }
2409
+
2410
+ .doc-api-table-row:last-child {
2411
+ border-bottom: none;
2412
+ }
2413
+
2414
+ .doc-api-table-row:hover {
2415
+ background: var(--doc-color-backgroundSecondary);
2416
+ }
2417
+
2418
+ .doc-api-param-name {
2419
+ color: var(--doc-color-primary);
2420
+ font-family: var(--doc-typography-fontFamilyCode);
2421
+ font-size: 0.9em;
2422
+ }
2423
+
2424
+ .doc-api-type {
2425
+ color: var(--doc-color-success);
2426
+ font-family: var(--doc-typography-fontFamilyCode);
2427
+ font-size: 0.9em;
2428
+ }
2429
+
2430
+ .doc-api-option {
2431
+ color: var(--doc-color-warning);
2432
+ font-family: var(--doc-typography-fontFamilyCode);
2433
+ font-size: 0.9em;
2434
+ }
2435
+
2436
+ .doc-api-default {
2437
+ color: var(--doc-color-textTertiary);
2438
+ font-family: var(--doc-typography-fontFamilyCode);
2439
+ font-size: 0.9em;
2440
+ }
2441
+
2442
+ .doc-api-required-yes {
2443
+ color: var(--doc-color-error);
2444
+ font-weight: var(--doc-typography-fontWeight-medium);
2445
+ }
2446
+
2447
+ .doc-api-required-no {
2448
+ color: var(--doc-color-textTertiary);
2449
+ }
2450
+
2451
+ .doc-api-deprecated {
2452
+ background: var(--doc-color-error);
2453
+ color: white;
2454
+ font-size: 0.8em;
2455
+ padding: 2px 4px;
2456
+ border-radius: 3px;
2457
+ margin-left: var(--doc-spacing-xs);
2458
+ }
2459
+
2460
+ .doc-api-highlight {
2461
+ background: var(--doc-color-warning);
2462
+ color: var(--doc-color-background);
2463
+ padding: 2px 4px;
2464
+ border-radius: 3px;
2465
+ font-size: 0.9em;
2466
+ }
2467
+
2468
+ .doc-api-empty {
2469
+ padding: var(--doc-spacing-xl);
2470
+ text-align: center;
2471
+ color: var(--doc-color-textSecondary);
2472
+ background: var(--doc-color-backgroundSecondary);
2473
+ border-radius: var(--doc-layout-borderRadius);
2474
+ }
2475
+ `,
2476
+ search: `
2477
+ .doc-search-overlay {
2478
+ position: fixed;
2479
+ top: 0;
2480
+ left: 0;
2481
+ right: 0;
2482
+ bottom: 0;
2483
+ background: rgba(0, 0, 0, 0.5);
2484
+ z-index: 1000;
2485
+ display: flex;
2486
+ align-items: flex-start;
2487
+ justify-content: center;
2488
+ padding-top: 10vh;
2489
+ }
2490
+
2491
+ .doc-search-modal {
2492
+ background: var(--doc-color-background);
2493
+ border-radius: var(--doc-layout-borderRadius);
2494
+ box-shadow: var(--doc-layout-boxShadow);
2495
+ width: 90%;
2496
+ max-width: 600px;
2497
+ max-height: 70vh;
2498
+ overflow: hidden;
2499
+ display: flex;
2500
+ flex-direction: column;
2501
+ }
2502
+
2503
+ .doc-search-input-container {
2504
+ display: flex;
2505
+ align-items: center;
2506
+ padding: var(--doc-spacing-lg);
2507
+ border-bottom: 1px solid var(--doc-color-border);
2508
+ }
2509
+
2510
+ .doc-search-input {
2511
+ flex: 1;
2512
+ border: none;
2513
+ outline: none;
2514
+ font-size: var(--doc-typography-fontSize-lg);
2515
+ background: transparent;
2516
+ color: var(--doc-color-text);
2517
+ }
2518
+
2519
+ .doc-search-input::placeholder {
2520
+ color: var(--doc-color-textTertiary);
2521
+ }
2522
+
2523
+ .doc-search-close {
2524
+ background: none;
2525
+ border: none;
2526
+ color: var(--doc-color-textSecondary);
2527
+ cursor: pointer;
2528
+ padding: var(--doc-spacing-sm);
2529
+ border-radius: var(--doc-layout-borderRadius);
2530
+ transition: all 0.2s ease;
2531
+ }
2532
+
2533
+ .doc-search-close:hover {
2534
+ background: var(--doc-color-backgroundTertiary);
2535
+ color: var(--doc-color-text);
2536
+ }
2537
+
2538
+ .doc-search-results {
2539
+ flex: 1;
2540
+ overflow-y: auto;
2541
+ max-height: 400px;
2542
+ }
2543
+
2544
+ .doc-search-result {
2545
+ display: flex;
2546
+ align-items: center;
2547
+ padding: var(--doc-spacing-md) var(--doc-spacing-lg);
2548
+ cursor: pointer;
2549
+ border-bottom: 1px solid var(--doc-color-borderSecondary);
2550
+ transition: background 0.2s ease;
2551
+ }
2552
+
2553
+ .doc-search-result:hover,
2554
+ .doc-search-result.selected {
2555
+ background: var(--doc-color-backgroundSecondary);
2556
+ }
2557
+
2558
+ .doc-search-result-icon {
2559
+ margin-right: var(--doc-spacing-md);
2560
+ font-size: var(--doc-typography-fontSize-lg);
2561
+ }
2562
+
2563
+ .doc-search-result-content {
2564
+ flex: 1;
2565
+ }
2566
+
2567
+ .doc-search-result-title {
2568
+ font-weight: var(--doc-typography-fontWeight-medium);
2569
+ color: var(--doc-color-text);
2570
+ margin-bottom: 2px;
2571
+ }
2572
+
2573
+ .doc-search-result-description {
2574
+ font-size: var(--doc-typography-fontSize-sm);
2575
+ color: var(--doc-color-textSecondary);
2576
+ }
2577
+
2578
+ .doc-search-result-type {
2579
+ font-size: var(--doc-typography-fontSize-xs);
2580
+ color: var(--doc-color-textTertiary);
2581
+ text-transform: uppercase;
2582
+ letter-spacing: 0.5px;
2583
+ }
2584
+
2585
+ .doc-search-highlight {
2586
+ background: var(--doc-color-warning);
2587
+ color: var(--doc-color-background);
2588
+ padding: 1px 2px;
2589
+ border-radius: 2px;
2590
+ }
2591
+
2592
+ .doc-search-no-results {
2593
+ padding: var(--doc-spacing-xl);
2594
+ text-align: center;
2595
+ color: var(--doc-color-textSecondary);
2596
+ }
2597
+
2598
+ .doc-search-footer {
2599
+ padding: var(--doc-spacing-md) var(--doc-spacing-lg);
2600
+ border-top: 1px solid var(--doc-color-border);
2601
+ background: var(--doc-color-backgroundTertiary);
2602
+ }
2603
+
2604
+ .doc-search-shortcuts {
2605
+ display: flex;
2606
+ gap: var(--doc-spacing-md);
2607
+ font-size: var(--doc-typography-fontSize-xs);
2608
+ color: var(--doc-color-textTertiary);
2609
+ }
2610
+
2611
+ .doc-search-shortcuts kbd {
2612
+ background: var(--doc-color-backgroundSecondary);
2613
+ border: 1px solid var(--doc-color-border);
2614
+ border-radius: 3px;
2615
+ padding: 2px 4px;
2616
+ font-family: var(--doc-typography-fontFamilyCode);
2617
+ font-size: 0.9em;
2618
+ }
2619
+ `,
2620
+ home: `
2621
+ .doc-home {
2622
+ padding: var(--doc-spacing-2xl) 0;
2623
+ }
2624
+
2625
+ .doc-home-welcome {
2626
+ text-align: center;
2627
+ margin-bottom: var(--doc-spacing-4xl);
2628
+ }
2629
+
2630
+ .doc-home-title {
2631
+ font-size: var(--doc-typography-fontSize-4xl);
2632
+ font-weight: var(--doc-typography-fontWeight-bold);
2633
+ color: var(--doc-color-text);
2634
+ margin-bottom: var(--doc-spacing-lg);
2635
+ }
2636
+
2637
+ .doc-home-description {
2638
+ font-size: var(--doc-typography-fontSize-lg);
2639
+ color: var(--doc-color-textSecondary);
2640
+ line-height: var(--doc-typography-lineHeight-relaxed);
2641
+ max-width: 600px;
2642
+ margin: 0 auto var(--doc-spacing-lg);
2643
+ }
2644
+
2645
+ .doc-home-version {
2646
+ font-size: var(--doc-typography-fontSize-sm);
2647
+ color: var(--doc-color-textTertiary);
2648
+ }
2649
+
2650
+ .doc-home-version code {
2651
+ background: var(--doc-color-backgroundTertiary);
2652
+ padding: 2px 6px;
2653
+ border-radius: 3px;
2654
+ font-family: var(--doc-typography-fontFamilyCode);
2655
+ }
2656
+
2657
+ .doc-home-section {
2658
+ margin-bottom: var(--doc-spacing-4xl);
2659
+ }
2660
+
2661
+ .doc-home-section-title {
2662
+ font-size: var(--doc-typography-fontSize-2xl);
2663
+ font-weight: var(--doc-typography-fontWeight-semibold);
2664
+ color: var(--doc-color-text);
2665
+ margin-bottom: var(--doc-spacing-lg);
2666
+ text-align: center;
2667
+ }
2668
+
2669
+ .doc-home-code {
2670
+ background: var(--doc-color-code-background);
2671
+ border: 1px solid var(--doc-color-border);
2672
+ border-radius: var(--doc-layout-borderRadius);
2673
+ padding: var(--doc-spacing-lg);
2674
+ font-family: var(--doc-typography-fontFamilyCode);
2675
+ font-size: var(--doc-typography-fontSize-sm);
2676
+ overflow-x: auto;
2677
+ }
2678
+
2679
+ .doc-home-features {
2680
+ display: grid;
2681
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
2682
+ gap: var(--doc-spacing-xl);
2683
+ margin-top: var(--doc-spacing-lg);
2684
+ }
2685
+
2686
+ .doc-home-feature {
2687
+ text-align: center;
2688
+ padding: var(--doc-spacing-lg);
2689
+ }
2690
+
2691
+ .doc-home-feature-icon {
2692
+ font-size: var(--doc-typography-fontSize-3xl);
2693
+ margin-bottom: var(--doc-spacing-md);
2694
+ }
2695
+
2696
+ .doc-home-feature-title {
2697
+ font-size: var(--doc-typography-fontSize-lg);
2698
+ font-weight: var(--doc-typography-fontWeight-medium);
2699
+ color: var(--doc-color-text);
2700
+ margin-bottom: var(--doc-spacing-sm);
2701
+ }
2702
+
2703
+ .doc-home-feature-description {
2704
+ color: var(--doc-color-textSecondary);
2705
+ line-height: var(--doc-typography-lineHeight-relaxed);
2706
+ }
2707
+
2708
+ .doc-home-components {
2709
+ display: grid;
2710
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
2711
+ gap: var(--doc-spacing-lg);
2712
+ margin-top: var(--doc-spacing-lg);
2713
+ }
2714
+
2715
+ .doc-home-component-card {
2716
+ background: var(--doc-color-background);
2717
+ border: 1px solid var(--doc-color-border);
2718
+ border-radius: var(--doc-layout-borderRadius);
2719
+ padding: var(--doc-spacing-lg);
2720
+ transition: all 0.2s ease;
2721
+ }
2722
+
2723
+ .doc-home-component-card:hover {
2724
+ box-shadow: var(--doc-layout-boxShadow);
2725
+ border-color: var(--doc-color-primary);
2726
+ }
2727
+
2728
+ .doc-home-component-title a {
2729
+ color: var(--doc-color-text);
2730
+ text-decoration: none;
2731
+ font-weight: var(--doc-typography-fontWeight-medium);
2732
+ font-size: var(--doc-typography-fontSize-lg);
2733
+ }
2734
+
2735
+ .doc-home-component-title a:hover {
2736
+ color: var(--doc-color-primary);
2737
+ }
2738
+
2739
+ .doc-home-component-description {
2740
+ color: var(--doc-color-textSecondary);
2741
+ margin: var(--doc-spacing-sm) 0;
2742
+ line-height: var(--doc-typography-lineHeight-relaxed);
2743
+ }
2744
+
2745
+ .doc-home-component-meta {
2746
+ display: flex;
2747
+ justify-content: space-between;
2748
+ align-items: center;
2749
+ font-size: var(--doc-typography-fontSize-sm);
2750
+ color: var(--doc-color-textTertiary);
2751
+ margin-top: var(--doc-spacing-md);
2752
+ }
2753
+ `
2754
+ }
2755
+ };
2756
+
2757
+ //#endregion
2758
+ //#region src/core/ThemeManager.ts
2759
+ var ThemeManager = class {
2760
+ configManager;
2761
+ themes;
2762
+ currentTheme;
2763
+ styleElement;
2764
+ constructor(configManager) {
2765
+ this.configManager = configManager;
2766
+ this.themes = /* @__PURE__ */ new Map();
2767
+ this.currentTheme = null;
2768
+ this.styleElement = null;
2769
+ this.registerTheme("default", default_default);
2770
+ this.initialize();
2771
+ }
2772
+ /**
2773
+ * 初始化主题管理器
2774
+ */
2775
+ initialize() {
2776
+ const themeConfig = this.configManager.get("theme", {});
2777
+ const themeName = themeConfig.name || "default";
2778
+ this.setTheme(themeName, themeConfig);
2779
+ }
2780
+ /**
2781
+ * 注册主题
2782
+ * @param {string} name - 主题名称
2783
+ * @param {Object} theme - 主题对象
2784
+ */
2785
+ registerTheme(name, theme) {
2786
+ this.themes.set(name, theme);
2787
+ }
2788
+ /**
2789
+ * 设置当前主题
2790
+ * @param {string|Object} theme - 主题名称或主题对象
2791
+ * @param {Object} customConfig - 自定义配置
2792
+ */
2793
+ setTheme(theme, customConfig = {}) {
2794
+ let themeData;
2795
+ if (typeof theme === "string") {
2796
+ themeData = this.themes.get(theme);
2797
+ if (!themeData) {
2798
+ console.warn(`Theme "${theme}" not found, using default theme`);
2799
+ themeData = this.themes.get("default");
2800
+ }
2801
+ } else if (typeof theme === "object") themeData = theme;
2802
+ else {
2803
+ console.warn("Invalid theme type, using default theme");
2804
+ themeData = this.themes.get("default");
2805
+ }
2806
+ this.currentTheme = this.mergeTheme(themeData, customConfig);
2807
+ this.applyTheme();
2808
+ }
2809
+ /**
2810
+ * 合并主题配置
2811
+ * @param {Object} baseTheme - 基础主题
2812
+ * @param {Object} customConfig - 自定义配置
2813
+ * @returns {Object} 合并后的主题
2814
+ */
2815
+ mergeTheme(baseTheme, customConfig) {
2816
+ return {
2817
+ ...baseTheme,
2818
+ colors: {
2819
+ ...baseTheme.colors,
2820
+ ...customConfig.colors
2821
+ },
2822
+ typography: {
2823
+ ...baseTheme.typography,
2824
+ ...customConfig.typography
2825
+ },
2826
+ spacing: {
2827
+ ...baseTheme.spacing,
2828
+ ...customConfig.spacing
2829
+ },
2830
+ layout: {
2831
+ ...baseTheme.layout,
2832
+ ...customConfig.layout
2833
+ },
2834
+ components: {
2835
+ ...baseTheme.components,
2836
+ ...customConfig.components
2837
+ }
2838
+ };
2839
+ }
2840
+ /**
2841
+ * 应用主题样式
2842
+ */
2843
+ applyTheme() {
2844
+ if (!this.currentTheme) return;
2845
+ if (this.styleElement) this.styleElement.remove();
2846
+ const cssVariables = this.generateCSSVariables();
2847
+ const themeStyles = this.generateThemeStyles();
2848
+ this.styleElement = document.createElement("style");
2849
+ this.styleElement.setAttribute("data-doc-sdk-theme", "true");
2850
+ this.styleElement.textContent = `
2851
+ :root {
2852
+ ${cssVariables}
2853
+ }
2854
+
2855
+ ${themeStyles}
2856
+ `;
2857
+ document.head.appendChild(this.styleElement);
2858
+ }
2859
+ /**
2860
+ * 生成CSS变量
2861
+ * @returns {string} CSS变量字符串
2862
+ */
2863
+ generateCSSVariables() {
2864
+ const { colors, typography, spacing, layout } = this.currentTheme;
2865
+ const variables = [];
2866
+ if (colors) Object.entries(colors).forEach(([key, value]) => {
2867
+ if (typeof value === "object") Object.entries(value).forEach(([subKey, subValue]) => {
2868
+ variables.push(`--doc-color-${key}-${subKey}: ${subValue};`);
2869
+ });
2870
+ else variables.push(`--doc-color-${key}: ${value};`);
2871
+ });
2872
+ if (typography) Object.entries(typography).forEach(([key, value]) => {
2873
+ if (typeof value === "object") Object.entries(value).forEach(([subKey, subValue]) => {
2874
+ variables.push(`--doc-typography-${key}-${subKey}: ${subValue};`);
2875
+ });
2876
+ else variables.push(`--doc-typography-${key}: ${value};`);
2877
+ });
2878
+ if (spacing) Object.entries(spacing).forEach(([key, value]) => {
2879
+ variables.push(`--doc-spacing-${key}: ${value};`);
2880
+ });
2881
+ if (layout) Object.entries(layout).forEach(([key, value]) => {
2882
+ variables.push(`--doc-layout-${key}: ${value};`);
2883
+ });
2884
+ return variables.join("\n ");
2885
+ }
2886
+ /**
2887
+ * 生成主题样式
2888
+ * @returns {string} 主题样式字符串
2889
+ */
2890
+ generateThemeStyles() {
2891
+ const { components } = this.currentTheme;
2892
+ const styles = [];
2893
+ styles.push(`
2894
+ .doc-sdk-container {
2895
+ font-family: var(--doc-typography-fontFamily, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
2896
+ font-size: var(--doc-typography-fontSize, 14px);
2897
+ line-height: var(--doc-typography-lineHeight, 1.5);
2898
+ color: var(--doc-color-text, #333);
2899
+ background-color: var(--doc-color-background, #fff);
2900
+ }
2901
+ `);
2902
+ if (components) Object.entries(components).forEach(([componentName, componentStyles]) => {
2903
+ if (typeof componentStyles === "string") styles.push(componentStyles);
2904
+ else if (typeof componentStyles === "object") {
2905
+ const cssRules = this.objectToCSS(componentStyles, `.doc-${componentName}`);
2906
+ styles.push(cssRules);
2907
+ }
2908
+ });
2909
+ return styles.join("\n");
2910
+ }
2911
+ /**
2912
+ * 将对象转换为CSS规则
2913
+ * @param {Object} obj - 样式对象
2914
+ * @param {string} selector - CSS选择器
2915
+ * @returns {string} CSS规则字符串
2916
+ */
2917
+ objectToCSS(obj, selector) {
2918
+ const rules = [];
2919
+ Object.entries(obj).forEach(([key, value]) => {
2920
+ if (typeof value === "object") {
2921
+ const nestedSelector = key.startsWith("&") ? key.replace("&", selector) : `${selector} ${key}`;
2922
+ rules.push(this.objectToCSS(value, nestedSelector));
2923
+ } else {
2924
+ const cssProperty = key.replace(/([A-Z])/g, "-$1").toLowerCase();
2925
+ rules.push(`${cssProperty}: ${value};`);
2926
+ }
2927
+ });
2928
+ return `${selector} {\n ${rules.join("\n ")}\n}`;
2929
+ }
2930
+ /**
2931
+ * 获取当前主题
2932
+ * @returns {Object} 当前主题对象
2933
+ */
2934
+ getCurrentTheme() {
2935
+ return this.currentTheme;
2936
+ }
2937
+ /**
2938
+ * 获取主题变量值
2939
+ * @param {string} path - 变量路径
2940
+ * @param {*} defaultValue - 默认值
2941
+ * @returns {*} 变量值
2942
+ */
2943
+ getThemeValue(path, defaultValue) {
2944
+ const keys = path.split(".");
2945
+ let value = this.currentTheme;
2946
+ for (const key of keys) if (value && typeof value === "object" && key in value) value = value[key];
2947
+ else return defaultValue;
2948
+ return value;
2949
+ }
2950
+ /**
2951
+ * 获取所有注册的主题
2952
+ * @returns {Array} 主题名称数组
2953
+ */
2954
+ getAvailableThemes() {
2955
+ return Array.from(this.themes.keys());
2956
+ }
2957
+ /**
2958
+ * 销毁主题管理器
2959
+ */
2960
+ destroy() {
2961
+ if (this.styleElement) {
2962
+ this.styleElement.remove();
2963
+ this.styleElement = null;
2964
+ }
2965
+ this.themes.clear();
2966
+ this.currentTheme = null;
2967
+ }
2968
+ };
2969
+
2970
+ //#endregion
2971
+ //#region src/core/PluginManager.ts
2972
+ /**
2973
+ * 插件管理器
2974
+ * 负责管理文档站点的插件系统
2975
+ */
2976
+ var PluginManager = class {
2977
+ configManager;
2978
+ plugins;
2979
+ hooks;
2980
+ renderer;
2981
+ constructor(configManager) {
2982
+ this.configManager = configManager;
2983
+ this.plugins = /* @__PURE__ */ new Map();
2984
+ this.hooks = /* @__PURE__ */ new Map();
2985
+ this.renderer = null;
2986
+ }
2987
+ /**
2988
+ * 初始化插件管理器
2989
+ * @param {DocRenderer} renderer - 文档渲染器实例
2990
+ */
2991
+ initialize(renderer) {
2992
+ this.renderer = renderer;
2993
+ const pluginConfigs = this.configManager.get("plugins", []);
2994
+ pluginConfigs.forEach((pluginConfig) => {
2995
+ this.loadPlugin(pluginConfig);
2996
+ });
2997
+ }
2998
+ /**
2999
+ * 注册插件
3000
+ * @param {Object} plugin - 插件对象
3001
+ * @returns {boolean} 注册是否成功
3002
+ */
3003
+ register(plugin) {
3004
+ try {
3005
+ if (!this.validatePlugin(plugin)) return false;
3006
+ const { name, version = "1.0.0" } = plugin;
3007
+ if (this.plugins.has(name)) {
3008
+ console.warn(`Plugin "${name}" already registered`);
3009
+ return false;
3010
+ }
3011
+ this.plugins.set(name, {
3012
+ ...plugin,
3013
+ version,
3014
+ status: "registered"
3015
+ });
3016
+ if (this.renderer) this.activatePlugin(name);
3017
+ return true;
3018
+ } catch (error) {
3019
+ console.error(`Failed to register plugin:`, error);
3020
+ return false;
3021
+ }
3022
+ }
3023
+ /**
3024
+ * 加载插件
3025
+ * @param {Object|string} pluginConfig - 插件配置或插件名称
3026
+ */
3027
+ async loadPlugin(pluginConfig) {
3028
+ try {
3029
+ let plugin;
3030
+ if (typeof pluginConfig === "string") plugin = await this.loadPluginByName(pluginConfig);
3031
+ else if (typeof pluginConfig === "object") if (pluginConfig.name && !pluginConfig.install) {
3032
+ plugin = await this.loadPluginByName(pluginConfig.name);
3033
+ plugin.config = pluginConfig.config || {};
3034
+ } else plugin = pluginConfig;
3035
+ if (plugin) this.register(plugin);
3036
+ } catch (error) {
3037
+ console.error(`Failed to load plugin:`, error);
3038
+ }
3039
+ }
3040
+ /**
3041
+ * 通过名称加载插件
3042
+ * @param {string} name - 插件名称
3043
+ * @returns {Object} 插件对象
3044
+ */
3045
+ async loadPluginByName(name) {
3046
+ const globalPlugin = window.__DOC_SDK_PLUGINS__?.[name];
3047
+ if (globalPlugin) return globalPlugin;
3048
+ throw new Error(`Plugin "${name}" not found`);
3049
+ }
3050
+ /**
3051
+ * 激活插件
3052
+ * @param {string} name - 插件名称
3053
+ */
3054
+ activatePlugin(name) {
3055
+ const plugin = this.plugins.get(name);
3056
+ if (!plugin || plugin.status === "active") return;
3057
+ try {
3058
+ const context = this.createPluginContext(plugin);
3059
+ if (typeof plugin.install === "function") plugin.install(context);
3060
+ plugin.status = "active";
3061
+ console.log(`Plugin "${name}" activated`);
3062
+ } catch (error) {
3063
+ console.error(`Failed to activate plugin "${name}":`, error);
3064
+ plugin.status = "error";
3065
+ }
3066
+ }
3067
+ /**
3068
+ * 停用插件
3069
+ * @param {string} name - 插件名称
3070
+ */
3071
+ deactivatePlugin(name) {
3072
+ const plugin = this.plugins.get(name);
3073
+ if (!plugin || plugin.status !== "active") return;
3074
+ try {
3075
+ if (typeof plugin.uninstall === "function") plugin.uninstall();
3076
+ this.removePluginHooks(name);
3077
+ plugin.status = "inactive";
3078
+ console.log(`Plugin "${name}" deactivated`);
3079
+ } catch (error) {
3080
+ console.error(`Failed to deactivate plugin "${name}":`, error);
3081
+ }
3082
+ }
3083
+ /**
3084
+ * 创建插件上下文
3085
+ * @param {Object} plugin - 插件对象
3086
+ * @returns {Object} 插件上下文
3087
+ */
3088
+ createPluginContext(plugin) {
3089
+ return {
3090
+ plugin: {
3091
+ name: plugin.name,
3092
+ version: plugin.version,
3093
+ config: plugin.config || {}
3094
+ },
3095
+ renderer: this.renderer,
3096
+ config: this.configManager,
3097
+ theme: this.renderer?.themeManager,
3098
+ components: this.renderer.componentRegistry,
3099
+ router: this.renderer.routerManager,
3100
+ hooks: {
3101
+ add: this.addHook.bind(this),
3102
+ remove: this.removeHook.bind(this),
3103
+ call: this.callHook.bind(this)
3104
+ },
3105
+ events: {
3106
+ on: this.renderer.on.bind(this.renderer),
3107
+ off: this.renderer.off.bind(this.renderer),
3108
+ emit: this.renderer.emit.bind(this.renderer)
3109
+ }
3110
+ };
3111
+ }
3112
+ /**
3113
+ * 添加钩子
3114
+ * @param {string} hookName - 钩子名称
3115
+ * @param {Function} handler - 处理函数
3116
+ * @param {string} pluginName - 插件名称
3117
+ */
3118
+ addHook(hookName, handler, pluginName) {
3119
+ if (!this.hooks.has(hookName)) this.hooks.set(hookName, []);
3120
+ this.hooks.get(hookName).push({
3121
+ handler,
3122
+ plugin: pluginName
3123
+ });
3124
+ }
3125
+ /**
3126
+ * 移除钩子
3127
+ * @param {string} hookName - 钩子名称
3128
+ * @param {Function} handler - 处理函数
3129
+ */
3130
+ removeHook(hookName, handler) {
3131
+ const hooks = this.hooks.get(hookName);
3132
+ if (hooks) {
3133
+ const index = hooks.findIndex((hook) => hook.handler === handler);
3134
+ if (index !== -1) hooks.splice(index, 1);
3135
+ }
3136
+ }
3137
+ /**
3138
+ * 移除插件的所有钩子
3139
+ * @param {string} pluginName - 插件名称
3140
+ */
3141
+ removePluginHooks(pluginName) {
3142
+ this.hooks.forEach((hooks, hookName) => {
3143
+ const filteredHooks = hooks.filter((hook) => hook.plugin !== pluginName);
3144
+ this.hooks.set(hookName, filteredHooks);
3145
+ });
3146
+ }
3147
+ /**
3148
+ * 调用钩子
3149
+ * @param {string} hookName - 钩子名称
3150
+ * @param {...any} args - 参数
3151
+ * @returns {Array} 钩子返回值数组
3152
+ */
3153
+ callHook(hookName, ...args) {
3154
+ const hooks = this.hooks.get(hookName);
3155
+ if (!hooks || hooks.length === 0) return [];
3156
+ const results = [];
3157
+ hooks.forEach(({ handler, plugin }) => {
3158
+ try {
3159
+ const result = handler(...args);
3160
+ results.push(result);
3161
+ } catch (error) {
3162
+ console.error(`Hook "${hookName}" error in plugin "${plugin}":`, error);
3163
+ }
3164
+ });
3165
+ return results;
3166
+ }
3167
+ /**
3168
+ * 验证插件
3169
+ * @param {Object} plugin - 插件对象
3170
+ * @returns {boolean} 是否有效
3171
+ */
3172
+ validatePlugin(plugin) {
3173
+ if (!plugin || typeof plugin !== "object") {
3174
+ console.error("Plugin must be an object");
3175
+ return false;
3176
+ }
3177
+ if (!plugin.name || typeof plugin.name !== "string") {
3178
+ console.error("Plugin must have a name");
3179
+ return false;
3180
+ }
3181
+ if (!plugin.install || typeof plugin.install !== "function") {
3182
+ console.error("Plugin must have an install function");
3183
+ return false;
3184
+ }
3185
+ return true;
3186
+ }
3187
+ /**
3188
+ * 获取插件信息
3189
+ * @param {string} name - 插件名称
3190
+ * @returns {Object|null} 插件信息
3191
+ */
3192
+ getPlugin(name) {
3193
+ return this.plugins.get(name) || null;
3194
+ }
3195
+ /**
3196
+ * 获取所有插件
3197
+ * @returns {Array} 插件数组
3198
+ */
3199
+ getPlugins() {
3200
+ return Array.from(this.plugins.values());
3201
+ }
3202
+ /**
3203
+ * 获取活跃插件
3204
+ * @returns {Array} 活跃插件数组
3205
+ */
3206
+ getActivePlugins() {
3207
+ return this.getPlugins().filter((plugin) => plugin.status === "active");
3208
+ }
3209
+ /**
3210
+ * 销毁插件管理器
3211
+ */
3212
+ destroy() {
3213
+ this.plugins.forEach((plugin, name) => {
3214
+ if (plugin.status === "active") this.deactivatePlugin(name);
3215
+ });
3216
+ this.plugins.clear();
3217
+ this.hooks.clear();
3218
+ this.renderer = null;
3219
+ }
3220
+ };
3221
+
3222
+ //#endregion
3223
+ //#region src/utils/index.ts
3224
+ /**
3225
+ * 工具函数
3226
+ */
3227
+ /**
3228
+ * 转换样式化文本
3229
+ * @param {string} str - 原始字符串
3230
+ * @param {boolean} flag - 是否启用样式化
3231
+ * @returns {string} 处理后的字符串
3232
+ */
3233
+ const transToStyledText = (str, flag = true) => {
3234
+ if (!flag || typeof str !== "string") return str;
3235
+ return str.replace(/{/g, "<span class=\"doc-highlight\">").replace(/}/g, "</span>");
3236
+ };
3237
+ /**
3238
+ * 解析查询参数
3239
+ * @param {string} query - 查询字符串
3240
+ * @returns {Object} 参数对象
3241
+ */
3242
+ const parseQuery = (query) => {
3243
+ const params = {};
3244
+ if (!query) return params;
3245
+ const reg = /([^=&\s]+)[=\s]*([^=&\s]*)/g;
3246
+ let match;
3247
+ while ((match = reg.exec(query)) !== null) params[match[1]] = match[2];
3248
+ return params;
3249
+ };
3250
+ /**
3251
+ * 序列化查询参数
3252
+ * @param {Object} obj - 参数对象
3253
+ * @returns {string} 查询字符串
3254
+ */
3255
+ const stringifyQuery = (obj) => {
3256
+ if (!obj || typeof obj !== "object") return "";
3257
+ const params = [];
3258
+ Object.keys(obj).forEach((key) => {
3259
+ if (obj.hasOwnProperty(key) && obj[key] !== void 0 && obj[key] !== null) params.push(`${key}=${obj[key]}`);
3260
+ });
3261
+ return params.join("&");
3262
+ };
3263
+ /**
3264
+ * 防抖函数
3265
+ * @param {Function} func - 要防抖的函数
3266
+ * @param {number} wait - 等待时间
3267
+ * @param {boolean} immediate - 是否立即执行
3268
+ * @returns {Function} 防抖后的函数
3269
+ */
3270
+ const debounce = (func, wait, immediate = false) => {
3271
+ let timeout;
3272
+ return function executedFunction(...args) {
3273
+ const later = () => {
3274
+ timeout = null;
3275
+ if (!immediate) func.apply(this, args);
3276
+ };
3277
+ const callNow = immediate && !timeout;
3278
+ clearTimeout(timeout);
3279
+ timeout = setTimeout(later, wait);
3280
+ if (callNow) func.apply(this, args);
3281
+ };
3282
+ };
3283
+ /**
3284
+ * 节流函数
3285
+ * @param {Function} func - 要节流的函数
3286
+ * @param {number} limit - 时间限制
3287
+ * @returns {Function} 节流后的函数
3288
+ */
3289
+ const throttle = (func, limit) => {
3290
+ let inThrottle;
3291
+ return function(...args) {
3292
+ if (!inThrottle) {
3293
+ func.apply(this, args);
3294
+ inThrottle = true;
3295
+ setTimeout(() => inThrottle = false, limit);
3296
+ }
3297
+ };
3298
+ };
3299
+ /**
3300
+ * 深度合并对象
3301
+ * @param {Object} target - 目标对象
3302
+ * @param {...Object} sources - 源对象
3303
+ * @returns {Object} 合并后的对象
3304
+ */
3305
+ const deepMerge = (target, ...sources) => {
3306
+ if (!sources.length) return target;
3307
+ const source = sources.shift();
3308
+ if (isObject(target) && isObject(source)) for (const key in source) if (isObject(source[key])) {
3309
+ if (!target[key]) Object.assign(target, { [key]: {} });
3310
+ deepMerge(target[key], source[key]);
3311
+ } else Object.assign(target, { [key]: source[key] });
3312
+ return deepMerge(target, ...sources);
3313
+ };
3314
+ /**
3315
+ * 判断是否为对象
3316
+ * @param {*} item - 要判断的项
3317
+ * @returns {boolean} 是否为对象
3318
+ */
3319
+ const isObject = (item) => {
3320
+ return item && typeof item === "object" && !Array.isArray(item);
3321
+ };
3322
+ /**
3323
+ * 获取嵌套对象的值
3324
+ * @param {Object} obj - 对象
3325
+ * @param {string} path - 路径,用点分隔
3326
+ * @param {*} defaultValue - 默认值
3327
+ * @returns {*} 值
3328
+ */
3329
+ const get = (obj, path, defaultValue) => {
3330
+ if (!obj || !path) return defaultValue;
3331
+ const keys = path.split(".");
3332
+ let result = obj;
3333
+ for (const key of keys) {
3334
+ if (result == null || typeof result !== "object") return defaultValue;
3335
+ result = result[key];
3336
+ }
3337
+ return result !== void 0 ? result : defaultValue;
3338
+ };
3339
+ /**
3340
+ * 设置嵌套对象的值
3341
+ * @param {Object} obj - 对象
3342
+ * @param {string} path - 路径,用点分隔
3343
+ * @param {*} value - 值
3344
+ */
3345
+ const set = (obj, path, value) => {
3346
+ if (!obj || !path) return;
3347
+ const keys = path.split(".");
3348
+ const lastKey = keys.pop();
3349
+ let current = obj;
3350
+ for (const key of keys) {
3351
+ if (!(key in current) || typeof current[key] !== "object") current[key] = {};
3352
+ current = current[key];
3353
+ }
3354
+ current[lastKey] = value;
3355
+ };
3356
+ /**
3357
+ * 生成唯一ID
3358
+ * @param {string} prefix - 前缀
3359
+ * @returns {string} 唯一ID
3360
+ */
3361
+ const generateId = (prefix = "id") => {
3362
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
3363
+ };
3364
+ /**
3365
+ * 格式化文件大小
3366
+ * @param {number} bytes - 字节数
3367
+ * @param {number} decimals - 小数位数
3368
+ * @returns {string} 格式化后的大小
3369
+ */
3370
+ const formatFileSize = (bytes, decimals = 2) => {
3371
+ if (bytes === 0) return "0 Bytes";
3372
+ const k = 1024;
3373
+ const dm = decimals < 0 ? 0 : decimals;
3374
+ const sizes = [
3375
+ "Bytes",
3376
+ "KB",
3377
+ "MB",
3378
+ "GB",
3379
+ "TB",
3380
+ "PB",
3381
+ "EB",
3382
+ "ZB",
3383
+ "YB"
3384
+ ];
3385
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
3386
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
3387
+ };
3388
+ /**
3389
+ * 复制文本到剪贴板
3390
+ * @param {string} text - 要复制的文本
3391
+ * @returns {Promise<boolean>} 是否成功
3392
+ */
3393
+ const copyToClipboard = async (text) => {
3394
+ try {
3395
+ if (navigator.clipboard && window.isSecureContext) {
3396
+ await navigator.clipboard.writeText(text);
3397
+ return true;
3398
+ } else {
3399
+ const textArea = document.createElement("textarea");
3400
+ textArea.value = text;
3401
+ textArea.style.position = "fixed";
3402
+ textArea.style.left = "-999999px";
3403
+ textArea.style.top = "-999999px";
3404
+ document.body.appendChild(textArea);
3405
+ textArea.focus();
3406
+ textArea.select();
3407
+ const result = document.execCommand("copy");
3408
+ document.body.removeChild(textArea);
3409
+ return result;
3410
+ }
3411
+ } catch (error) {
3412
+ console.error("Failed to copy text:", error);
3413
+ return false;
3414
+ }
3415
+ };
3416
+ /**
3417
+ * 滚动到元素
3418
+ * @param {string|HTMLElement} element - 元素或选择器
3419
+ * @param {Object} options - 滚动选项
3420
+ */
3421
+ const scrollToElement = (element, options = {}) => {
3422
+ const target = typeof element === "string" ? document.querySelector(element) : element;
3423
+ if (!target) return;
3424
+ const defaultOptions = {
3425
+ behavior: "smooth",
3426
+ block: "start",
3427
+ inline: "nearest"
3428
+ };
3429
+ target.scrollIntoView({
3430
+ ...defaultOptions,
3431
+ ...options
3432
+ });
3433
+ };
3434
+ /**
3435
+ * 检查元素是否在视口中
3436
+ * @param {HTMLElement} element - 元素
3437
+ * @param {number} threshold - 阈值
3438
+ * @returns {boolean} 是否在视口中
3439
+ */
3440
+ const isElementInViewport = (element, threshold = 0) => {
3441
+ if (!element) return false;
3442
+ const rect = element.getBoundingClientRect();
3443
+ const windowHeight = window.innerHeight || document.documentElement.clientHeight;
3444
+ const windowWidth = window.innerWidth || document.documentElement.clientWidth;
3445
+ return rect.top >= -threshold && rect.left >= -threshold && rect.bottom <= windowHeight + threshold && rect.right <= windowWidth + threshold;
3446
+ };
3447
+
3448
+ //#endregion
3449
+ //#region src/index.ts
3450
+ var DocSDK = class {
3451
+ configManager;
3452
+ themeManager;
3453
+ pluginManager;
3454
+ renderer;
3455
+ constructor(config = {}) {
3456
+ this.configManager = new ConfigManager(config);
3457
+ this.themeManager = new ThemeManager(this.configManager);
3458
+ this.pluginManager = new PluginManager(this.configManager);
3459
+ this.renderer = new DocRenderer({
3460
+ configManager: this.configManager,
3461
+ themeManager: this.themeManager,
3462
+ pluginManager: this.pluginManager
3463
+ });
3464
+ }
3465
+ /**
3466
+ * 渲染文档到指定容器
3467
+ */
3468
+ async render(target) {
3469
+ await this.renderer.render(target);
3470
+ }
3471
+ /**
3472
+ * 销毁文档实例
3473
+ */
3474
+ destroy() {
3475
+ this.renderer.destroy();
3476
+ }
3477
+ /**
3478
+ * 更新配置
3479
+ */
3480
+ updateConfig(config) {
3481
+ this.configManager.update(config);
3482
+ this.renderer.update();
3483
+ }
3484
+ /**
3485
+ * 注册插件
3486
+ */
3487
+ use(plugin) {
3488
+ this.pluginManager.register(plugin);
3489
+ return this;
3490
+ }
3491
+ /**
3492
+ * 设置主题
3493
+ */
3494
+ setTheme(theme) {
3495
+ this.themeManager.setTheme(theme);
3496
+ this.renderer.update();
3497
+ }
3498
+ /**
3499
+ * 获取当前配置
3500
+ */
3501
+ getConfig() {
3502
+ return this.configManager.getConfig();
3503
+ }
3504
+ /**
3505
+ * 监听事件
3506
+ */
3507
+ on(event, handler) {}
3508
+ /**
3509
+ * 移除事件监听
3510
+ */
3511
+ off(event, handler) {}
3512
+ /**
3513
+ * 触发事件
3514
+ */
3515
+ emit(event, data) {}
3516
+ };
3517
+
3518
+ //#endregion
3519
+ export { ApiDoc_default as ApiDoc, CodeBlock_default as CodeBlock, ConfigManager, Demo_default as Demo, DocRenderer, Layout_default as Layout, Navigation_default as Navigation, PluginManager, ThemeManager, copyToClipboard, debounce, deepMerge, DocSDK as default, formatFileSize, generateId, get, isElementInViewport, isObject, parseQuery, scrollToElement, set, stringifyQuery, throttle, transToStyledText };