@coffic/cosy-ui 0.3.10-beta.1 → 0.3.15
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/app.css +1 -1
- package/dist/components/base/Button.astro +61 -13
- package/dist/components/base/Image.astro +55 -16
- package/dist/components/base/Link.astro +14 -0
- package/dist/components/containers/Container.astro +35 -2
- package/dist/components/containers/Section.astro +23 -30
- package/dist/components/display/Modal.astro +14 -7
- package/dist/components/icons/MenuIcon.astro +5 -8
- package/dist/components/layouts/DocumentationLayout.astro +81 -25
- package/dist/components/layouts/Footer.astro +30 -76
- package/dist/components/layouts/Header.astro +17 -27
- package/dist/components/layouts/NavSection.astro +32 -0
- package/dist/components/layouts/Sidebar.astro +68 -68
- package/dist/components/layouts/SidebarNav.astro +122 -0
- package/dist/components/navigation/TableOfContents.astro +18 -50
- package/package.json +1 -1
- package/dist/components/containers/index.ts +0 -3
@@ -22,6 +22,10 @@
|
|
22
22
|
*/
|
23
23
|
|
24
24
|
import { isPathMatch } from '../../utils/path';
|
25
|
+
import Modal from '../display/Modal.astro';
|
26
|
+
import Button from '../base/Button.astro';
|
27
|
+
import SidebarNav from './SidebarNav.astro';
|
28
|
+
import MenuIcon from '../icons/MenuIcon.astro';
|
25
29
|
import "../../app.css"
|
26
30
|
|
27
31
|
export interface SidebarItem {
|
@@ -45,75 +49,71 @@ export interface Props {
|
|
45
49
|
* 当前路径
|
46
50
|
*/
|
47
51
|
currentPath: string;
|
52
|
+
|
53
|
+
/**
|
54
|
+
* 桌面端类名
|
55
|
+
*/
|
56
|
+
class?: string;
|
57
|
+
|
58
|
+
/**
|
59
|
+
* 是否开启调试模式,显示边框
|
60
|
+
* @default false
|
61
|
+
*/
|
62
|
+
debug?: boolean;
|
48
63
|
}
|
49
64
|
|
50
|
-
const {
|
65
|
+
const {
|
66
|
+
sidebarItems,
|
67
|
+
currentPath,
|
68
|
+
class: className,
|
69
|
+
debug = false
|
70
|
+
} = Astro.props;
|
71
|
+
|
72
|
+
const debugClass = debug ? "cosy:border cosy:border-red-500" : "";
|
73
|
+
|
74
|
+
// 获取当前活动的一级导航项
|
75
|
+
const currentSection = sidebarItems.find(section =>
|
76
|
+
section.items.some(item => isPathMatch(currentPath, item.href))
|
77
|
+
);
|
51
78
|
---
|
52
79
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
<a
|
94
|
-
href={subsubitem.href}
|
95
|
-
class:list={[
|
96
|
-
"cosy:hover:bg-base-300",
|
97
|
-
{ "cosy:active": isSubSubActive }
|
98
|
-
]}
|
99
|
-
>
|
100
|
-
{subsubitem.text}
|
101
|
-
</a>
|
102
|
-
</li>
|
103
|
-
);
|
104
|
-
})}
|
105
|
-
</ul>
|
106
|
-
)}
|
107
|
-
</li>
|
108
|
-
);
|
109
|
-
})}
|
110
|
-
</ul>
|
111
|
-
)}
|
112
|
-
</li>
|
113
|
-
);
|
114
|
-
})}
|
115
|
-
</ul>
|
116
|
-
</div>
|
117
|
-
))}
|
118
|
-
</nav>
|
119
|
-
</aside>
|
80
|
+
{/* 移动端导航栏 */}
|
81
|
+
<div class:list={[
|
82
|
+
"cosy:flex cosy:lg:hidden cosy:items-center cosy:justify-between cosy:px-4 cosy:py-2 cosy:border-b cosy:border-base-300 cosy:bg-base-100 cosy:relative cosy:z-10",
|
83
|
+
debugClass
|
84
|
+
]}>
|
85
|
+
<div class="cosy:flex cosy:items-center cosy:gap-2">
|
86
|
+
<button
|
87
|
+
type="button"
|
88
|
+
class="cosy:p-2 cosy:btn cosy:btn-ghost cosy:btn-sm"
|
89
|
+
data-modal-target="mobile-sidebar"
|
90
|
+
>
|
91
|
+
<MenuIcon class="cosy:w-5 cosy:h-5" />
|
92
|
+
</button>
|
93
|
+
<span class="cosy:font-medium cosy:text-sm">
|
94
|
+
{currentSection?.title || "导航"}
|
95
|
+
</span>
|
96
|
+
</div>
|
97
|
+
</div>
|
98
|
+
|
99
|
+
{/* 移动端侧边栏弹出层 */}
|
100
|
+
<Modal id="mobile-sidebar" class="cosy:mx-4 cosy:lg:w-80 cosy:w-[calc(100vw-2rem)] cosy:max-w-full">
|
101
|
+
<div class="cosy:h-[calc(100vh-8rem)] cosy:overflow-y-auto">
|
102
|
+
<SidebarNav
|
103
|
+
sidebarItems={sidebarItems}
|
104
|
+
currentPath={currentPath}
|
105
|
+
debug={debug}
|
106
|
+
/>
|
107
|
+
</div>
|
108
|
+
</Modal>
|
109
|
+
|
110
|
+
{/* 桌面端侧边栏 */}
|
111
|
+
<aside class:list={[className, debugClass, "cosy:hidden cosy:lg:block"]}>
|
112
|
+
<div class="cosy:top-16 cosy:sticky cosy:h-[calc(100vh-4rem)]">
|
113
|
+
<SidebarNav
|
114
|
+
sidebarItems={sidebarItems}
|
115
|
+
currentPath={currentPath}
|
116
|
+
debug={debug}
|
117
|
+
/>
|
118
|
+
</div>
|
119
|
+
</aside>
|
@@ -0,0 +1,122 @@
|
|
1
|
+
---
|
2
|
+
/**
|
3
|
+
* SidebarNav组件
|
4
|
+
*
|
5
|
+
* 用于渲染侧边栏的导航内容
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { isPathMatch } from '../../utils/path';
|
9
|
+
import "../../app.css"
|
10
|
+
|
11
|
+
export interface SidebarItem {
|
12
|
+
href: string;
|
13
|
+
text: string;
|
14
|
+
items?: SidebarItem[];
|
15
|
+
}
|
16
|
+
|
17
|
+
export interface SidebarSection {
|
18
|
+
title: string;
|
19
|
+
items: SidebarItem[];
|
20
|
+
}
|
21
|
+
|
22
|
+
interface Props {
|
23
|
+
/**
|
24
|
+
* 侧边栏项目
|
25
|
+
*/
|
26
|
+
sidebarItems: SidebarSection[];
|
27
|
+
|
28
|
+
/**
|
29
|
+
* 当前路径
|
30
|
+
*/
|
31
|
+
currentPath: string;
|
32
|
+
|
33
|
+
/**
|
34
|
+
* 是否开启调试模式,显示边框
|
35
|
+
* @default false
|
36
|
+
*/
|
37
|
+
debug?: boolean;
|
38
|
+
|
39
|
+
/**
|
40
|
+
* 自定义类名
|
41
|
+
*/
|
42
|
+
class?: string;
|
43
|
+
}
|
44
|
+
|
45
|
+
const {
|
46
|
+
sidebarItems,
|
47
|
+
currentPath,
|
48
|
+
debug = false,
|
49
|
+
class: className
|
50
|
+
} = Astro.props;
|
51
|
+
|
52
|
+
const debugClass = debug ? "cosy:border cosy:border-red-500" : "";
|
53
|
+
---
|
54
|
+
|
55
|
+
<nav class:list={["cosy:p-4", debugClass, className]}>
|
56
|
+
{sidebarItems.map((section: SidebarSection) => (
|
57
|
+
<div class:list={["cosy:mb-6", debugClass]}>
|
58
|
+
<h3 class:list={["cosy:font-bold cosy:mb-2 cosy:text-base-content/70", debugClass]}>{section.title}</h3>
|
59
|
+
<ul class:list={["cosy:menu cosy:bg-base-200 cosy:rounded-box cosy:w-56", debugClass]}>
|
60
|
+
{section.items.map((item: SidebarItem) => {
|
61
|
+
const isActive = isPathMatch(currentPath, item.href);
|
62
|
+
return (
|
63
|
+
<li class:list={[debugClass]}>
|
64
|
+
<a
|
65
|
+
href={item.href}
|
66
|
+
class:list={[
|
67
|
+
"cosy:hover:bg-base-300",
|
68
|
+
{ "cosy:menu-active": isActive },
|
69
|
+
debugClass
|
70
|
+
]}
|
71
|
+
>
|
72
|
+
{item.text}
|
73
|
+
</a>
|
74
|
+
{item.items && (
|
75
|
+
<ul class:list={[debugClass]}>
|
76
|
+
{item.items.map((subitem: SidebarItem) => {
|
77
|
+
const isSubActive = isPathMatch(currentPath, subitem.href);
|
78
|
+
return (
|
79
|
+
<li class:list={[debugClass]}>
|
80
|
+
<a
|
81
|
+
href={subitem.href}
|
82
|
+
class:list={[
|
83
|
+
"cosy:hover:bg-base-300",
|
84
|
+
{ "cosy:active": isSubActive },
|
85
|
+
debugClass
|
86
|
+
]}
|
87
|
+
>
|
88
|
+
{subitem.text}
|
89
|
+
</a>
|
90
|
+
{subitem.items && (
|
91
|
+
<ul class:list={[debugClass]}>
|
92
|
+
{subitem.items.map((subsubitem: SidebarItem) => {
|
93
|
+
const isSubSubActive = isPathMatch(currentPath, subsubitem.href);
|
94
|
+
return (
|
95
|
+
<li class:list={[debugClass]}>
|
96
|
+
<a
|
97
|
+
href={subsubitem.href}
|
98
|
+
class:list={[
|
99
|
+
"cosy:hover:bg-base-300",
|
100
|
+
{ "cosy:active": isSubSubActive },
|
101
|
+
debugClass
|
102
|
+
]}
|
103
|
+
>
|
104
|
+
{subsubitem.text}
|
105
|
+
</a>
|
106
|
+
</li>
|
107
|
+
);
|
108
|
+
})}
|
109
|
+
</ul>
|
110
|
+
)}
|
111
|
+
</li>
|
112
|
+
);
|
113
|
+
})}
|
114
|
+
</ul>
|
115
|
+
)}
|
116
|
+
</li>
|
117
|
+
);
|
118
|
+
})}
|
119
|
+
</ul>
|
120
|
+
</div>
|
121
|
+
))}
|
122
|
+
</nav>
|
@@ -54,7 +54,7 @@
|
|
54
54
|
|
55
55
|
// 导入样式
|
56
56
|
import '../../app.css';
|
57
|
-
import { getCurrentLanguage
|
57
|
+
import { getCurrentLanguage } from '../../utils/language';
|
58
58
|
import { createTextGetter } from '../../utils/i18n';
|
59
59
|
|
60
60
|
interface Props {
|
@@ -97,11 +97,6 @@ interface Props {
|
|
97
97
|
* @default 自动检测
|
98
98
|
*/
|
99
99
|
lang?: string;
|
100
|
-
/**
|
101
|
-
* 是否启用日志输出
|
102
|
-
* @default false
|
103
|
-
*/
|
104
|
-
enableLogging?: boolean;
|
105
100
|
}
|
106
101
|
|
107
102
|
const {
|
@@ -113,7 +108,6 @@ const {
|
|
113
108
|
minHeadings = 2,
|
114
109
|
lang: userLang,
|
115
110
|
title,
|
116
|
-
enableLogging = true,
|
117
111
|
} = Astro.props;
|
118
112
|
|
119
113
|
// 获取当前语言
|
@@ -125,54 +119,28 @@ const titleText = title || t('title');
|
|
125
119
|
|
126
120
|
// 生成唯一ID,确保多个TOC实例不会冲突
|
127
121
|
const tocId = `toc-${Math.random().toString(36).substring(2, 9)}`;
|
128
|
-
|
129
|
-
// 获取语言来源的描述
|
130
|
-
function getLanguageSourceDescription(source: LanguageSource): string {
|
131
|
-
switch (source) {
|
132
|
-
case LanguageSource.USER:
|
133
|
-
return '用户指定';
|
134
|
-
case LanguageSource.URL:
|
135
|
-
return 'URL参数';
|
136
|
-
case LanguageSource.BROWSER:
|
137
|
-
return '浏览器设置';
|
138
|
-
case LanguageSource.DEFAULT:
|
139
|
-
return '默认语言';
|
140
|
-
default:
|
141
|
-
return '未知来源';
|
142
|
-
}
|
143
|
-
}
|
144
122
|
---
|
145
123
|
|
146
|
-
<
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
124
|
+
<aside class:list={[
|
125
|
+
'cosy:hidden cosy:xl:block cosy:w-64 cosy:shrink-0',
|
126
|
+
className
|
127
|
+
]}>
|
128
|
+
<div class="cosy:top-16 cosy:sticky">
|
129
|
+
<div class={`toc-container ${fixed ? 'cosy:w-64' : 'cosy:w-full cosy:max-w-xs'}`} id={`${tocId}-container`} style="display: none;">
|
130
|
+
<div class="cosy:bg-base-100 cosy:shadow-xl cosy:card">
|
131
|
+
<div class="cosy:p-4 cosy:card-body">
|
132
|
+
<div class="cosy:mb-2 cosy:font-bold cosy:text-lg cosy:card-title">{titleText}</div>
|
133
|
+
<ul class="cosy:menu cosy:menu-sm" id={tocId}>
|
134
|
+
<!-- 目录项将通过 JavaScript 动态生成 -->
|
135
|
+
<li class="cosy:text-base-content/60">{t('loading')}</li>
|
136
|
+
</ul>
|
137
|
+
</div>
|
138
|
+
</div>
|
154
139
|
</div>
|
155
140
|
</div>
|
156
|
-
</
|
157
|
-
|
158
|
-
<script define:vars={{ selector, maxDepth, tocId, containerSelector, minHeadings, langInfo, enableLogging }}>
|
159
|
-
// 输出语言信息到控制台
|
160
|
-
if (enableLogging) {
|
161
|
-
console.log(`[TableOfContents] 语言信息:`, {
|
162
|
-
语言代码: langInfo.code,
|
163
|
-
语言来源: langInfo.source,
|
164
|
-
来源描述: (() => {
|
165
|
-
switch (langInfo.source) {
|
166
|
-
case 'user': return '用户指定';
|
167
|
-
case 'url': return 'URL参数';
|
168
|
-
case 'browser': return '浏览器设置';
|
169
|
-
case 'default': return '默认语言';
|
170
|
-
default: return '未知来源';
|
171
|
-
}
|
172
|
-
})()
|
173
|
-
});
|
174
|
-
}
|
141
|
+
</aside>
|
175
142
|
|
143
|
+
<script define:vars={{ selector, maxDepth, tocId, containerSelector, minHeadings, langInfo }}>
|
176
144
|
// 在页面加载完成后生成目录
|
177
145
|
function generateTOC() {
|
178
146
|
// 使用指定的容器选择器查找内容容器
|
package/package.json
CHANGED