@coffic/cosy-ui 0.3.69 → 0.4.5
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/Alert.astro +3 -3
- package/dist/components/containers/Container.astro +80 -4
- package/dist/components/containers/Main.astro +41 -54
- package/dist/components/data-display/Blog.astro +1 -0
- package/dist/components/data-display/ProductCard.astro +0 -2
- package/dist/components/data-display/Products.astro +0 -2
- package/dist/components/data-display/TeamMember.astro +0 -2
- package/dist/components/data-display/TeamMembers.astro +0 -2
- package/dist/components/display/Banner.astro +0 -1
- package/dist/components/display/Card.astro +0 -1
- package/dist/components/display/CodeBlock.astro +0 -1
- package/dist/components/display/CodeExample.astro +0 -1
- package/dist/components/display/Modal.astro +65 -67
- package/dist/components/layouts/AppLayout.astro +258 -0
- package/dist/components/layouts/BaseLayout.astro +46 -92
- package/dist/components/layouts/DashboardLayout.astro +615 -604
- package/dist/components/layouts/Footer.astro +141 -113
- package/dist/components/layouts/Header.astro +11 -292
- package/dist/components/layouts/Sidebar.astro +54 -31
- package/dist/components/layouts/SidebarNav.astro +1 -11
- package/dist/components/typography/Article.astro +8 -30
- package/dist/index.ts +7 -4
- package/dist/types/article.ts +22 -0
- package/dist/types/footer.ts +119 -22
- package/dist/types/header.ts +70 -0
- package/dist/types/layout.ts +71 -10
- package/dist/types/main.ts +69 -0
- package/dist/types/meta.ts +50 -0
- package/dist/types/sidebar.ts +38 -0
- package/package.json +2 -2
- package/dist/components/layouts/DefaultLayout.astro +0 -170
- package/dist/components/layouts/DocumentationLayout.astro +0 -624
- package/dist/components/layouts/LandingLayout.astro +0 -388
@@ -1,388 +0,0 @@
|
|
1
|
-
---
|
2
|
-
/**
|
3
|
-
* LandingLayout组件
|
4
|
-
*
|
5
|
-
* 适用于落地页的布局,包含页眉、页脚和多个区块
|
6
|
-
*
|
7
|
-
* @example
|
8
|
-
* ```astro
|
9
|
-
* ---
|
10
|
-
* import LandingLayout from '../layouts/LandingLayout.astro';
|
11
|
-
* ---
|
12
|
-
*
|
13
|
-
* <LandingLayout
|
14
|
-
* title="产品名称 - 简短的产品描述"
|
15
|
-
* description="详细的产品描述,包含关键词"
|
16
|
-
* >
|
17
|
-
* <div slot="hero">
|
18
|
-
* <h1>产品标题</h1>
|
19
|
-
* <p>产品简介</p>
|
20
|
-
* <button>立即开始</button>
|
21
|
-
* </div>
|
22
|
-
*
|
23
|
-
* <section>
|
24
|
-
* <h2>产品特点</h2>
|
25
|
-
* <p>详细介绍产品特点...</p>
|
26
|
-
* </section>
|
27
|
-
* </LandingLayout>
|
28
|
-
* ```
|
29
|
-
*/
|
30
|
-
|
31
|
-
import BaseLayout from './BaseLayout.astro';
|
32
|
-
|
33
|
-
// 导入样式
|
34
|
-
import '../../app.css';
|
35
|
-
|
36
|
-
export interface NavItem {
|
37
|
-
href: string;
|
38
|
-
label: string;
|
39
|
-
isButton?: boolean;
|
40
|
-
}
|
41
|
-
|
42
|
-
export interface FooterLink {
|
43
|
-
href: string;
|
44
|
-
label: string;
|
45
|
-
}
|
46
|
-
|
47
|
-
export interface FooterSection {
|
48
|
-
title: string;
|
49
|
-
links: FooterLink[];
|
50
|
-
}
|
51
|
-
|
52
|
-
export interface SocialLink {
|
53
|
-
href: string;
|
54
|
-
icon: string;
|
55
|
-
label: string;
|
56
|
-
}
|
57
|
-
|
58
|
-
export interface Props {
|
59
|
-
/**
|
60
|
-
* 页面标题
|
61
|
-
*/
|
62
|
-
title: string;
|
63
|
-
|
64
|
-
/**
|
65
|
-
* 页面描述
|
66
|
-
*/
|
67
|
-
description?: string;
|
68
|
-
|
69
|
-
/**
|
70
|
-
* 页面关键词
|
71
|
-
*/
|
72
|
-
keywords?: string;
|
73
|
-
|
74
|
-
/**
|
75
|
-
* 品牌名称
|
76
|
-
* @default "品牌名称"
|
77
|
-
*/
|
78
|
-
brandName?: string;
|
79
|
-
|
80
|
-
/**
|
81
|
-
* 品牌Logo URL
|
82
|
-
*/
|
83
|
-
logoUrl?: string;
|
84
|
-
|
85
|
-
/**
|
86
|
-
* 导航链接
|
87
|
-
*/
|
88
|
-
navItems?: NavItem[];
|
89
|
-
|
90
|
-
/**
|
91
|
-
* 页脚链接分组
|
92
|
-
*/
|
93
|
-
footerSections?: FooterSection[];
|
94
|
-
|
95
|
-
/**
|
96
|
-
* 社交媒体链接
|
97
|
-
*/
|
98
|
-
socialLinks?: SocialLink[];
|
99
|
-
|
100
|
-
/**
|
101
|
-
* 版权信息
|
102
|
-
*/
|
103
|
-
copyright?: string;
|
104
|
-
|
105
|
-
/**
|
106
|
-
* 自定义头部内容
|
107
|
-
*/
|
108
|
-
head?: astroHTML.JSX.Element;
|
109
|
-
|
110
|
-
/**
|
111
|
-
* 页面类名
|
112
|
-
*/
|
113
|
-
class?: string;
|
114
|
-
|
115
|
-
/**
|
116
|
-
* 类名列表
|
117
|
-
*/
|
118
|
-
'class:list'?: any;
|
119
|
-
}
|
120
|
-
|
121
|
-
const {
|
122
|
-
title,
|
123
|
-
description,
|
124
|
-
keywords,
|
125
|
-
brandName = "品牌名称",
|
126
|
-
logoUrl,
|
127
|
-
navItems = [
|
128
|
-
{ href: "/", label: "首页" },
|
129
|
-
{ href: "/features", label: "特性" },
|
130
|
-
{ href: "/pricing", label: "价格" },
|
131
|
-
{ href: "/about", label: "关于我们" },
|
132
|
-
{ href: "/contact", label: "联系我们" },
|
133
|
-
{ href: "/signup", label: "注册", isButton: true }
|
134
|
-
],
|
135
|
-
footerSections = [
|
136
|
-
{
|
137
|
-
title: "产品",
|
138
|
-
links: [
|
139
|
-
{ href: "/features", label: "特性" },
|
140
|
-
{ href: "/pricing", label: "价格" },
|
141
|
-
{ href: "/docs", label: "文档" },
|
142
|
-
{ href: "/releases", label: "更新日志" }
|
143
|
-
]
|
144
|
-
},
|
145
|
-
{
|
146
|
-
title: "公司",
|
147
|
-
links: [
|
148
|
-
{ href: "/about", label: "关于我们" },
|
149
|
-
{ href: "/team", label: "团队" },
|
150
|
-
{ href: "/careers", label: "招聘" },
|
151
|
-
{ href: "/contact", label: "联系我们" }
|
152
|
-
]
|
153
|
-
},
|
154
|
-
{
|
155
|
-
title: "资源",
|
156
|
-
links: [
|
157
|
-
{ href: "/blog", label: "博客" },
|
158
|
-
{ href: "/community", label: "社区" },
|
159
|
-
{ href: "/support", label: "支持" }
|
160
|
-
]
|
161
|
-
},
|
162
|
-
{
|
163
|
-
title: "法律",
|
164
|
-
links: [
|
165
|
-
{ href: "/privacy", label: "隐私政策" },
|
166
|
-
{ href: "/terms", label: "服务条款" }
|
167
|
-
]
|
168
|
-
}
|
169
|
-
],
|
170
|
-
socialLinks = [
|
171
|
-
{ href: "https://twitter.com", icon: "twitter", label: "Twitter" },
|
172
|
-
{ href: "https://github.com", icon: "github", label: "GitHub" },
|
173
|
-
{ href: "https://linkedin.com", icon: "linkedin", label: "LinkedIn" }
|
174
|
-
],
|
175
|
-
copyright = `© ${new Date().getFullYear()} ${brandName}. 保留所有权利。`,
|
176
|
-
head,
|
177
|
-
class: className,
|
178
|
-
'class:list': classList,
|
179
|
-
...rest
|
180
|
-
} = Astro.props;
|
181
|
-
|
182
|
-
// 社交媒体图标映射
|
183
|
-
const socialIconMap: Record<string, string> = {
|
184
|
-
twitter: "🐦",
|
185
|
-
github: "🐙",
|
186
|
-
linkedin: "🔗",
|
187
|
-
facebook: "👤",
|
188
|
-
instagram: "📷",
|
189
|
-
youtube: "📺",
|
190
|
-
discord: "💬",
|
191
|
-
slack: "🔶",
|
192
|
-
wechat: "💬",
|
193
|
-
weibo: "微"
|
194
|
-
};
|
195
|
-
---
|
196
|
-
|
197
|
-
<BaseLayout
|
198
|
-
title={title}
|
199
|
-
description={description}
|
200
|
-
keywords={keywords}
|
201
|
-
head={head}
|
202
|
-
class="landing-layout"
|
203
|
-
{...rest}
|
204
|
-
>
|
205
|
-
<!-- 页眉 -->
|
206
|
-
<header class="site-header">
|
207
|
-
<div class="container">
|
208
|
-
<div class="header-content">
|
209
|
-
<div class="brand">
|
210
|
-
<a href="/" class="brand-link">
|
211
|
-
{logoUrl ? (
|
212
|
-
<img src={logoUrl} alt={brandName} class="brand-logo" />
|
213
|
-
) : (
|
214
|
-
<span class="brand-name">{brandName}</span>
|
215
|
-
)}
|
216
|
-
</a>
|
217
|
-
</div>
|
218
|
-
|
219
|
-
<nav class="main-nav">
|
220
|
-
<ul class="nav-list">
|
221
|
-
{navItems.map((item: NavItem) => (
|
222
|
-
<li class="nav-item">
|
223
|
-
{item.isButton ? (
|
224
|
-
<a href={item.href} class="btn btn-primary btn-sm">{item.label}</a>
|
225
|
-
) : (
|
226
|
-
<a href={item.href} class="nav-link">{item.label}</a>
|
227
|
-
)}
|
228
|
-
</li>
|
229
|
-
))}
|
230
|
-
</ul>
|
231
|
-
</nav>
|
232
|
-
|
233
|
-
<button class="mobile-menu-button" aria-label="菜单" id="mobile-menu-toggle">
|
234
|
-
<span class="menu-icon">☰</span>
|
235
|
-
</button>
|
236
|
-
</div>
|
237
|
-
</div>
|
238
|
-
</header>
|
239
|
-
|
240
|
-
<!-- 移动端导航菜单 -->
|
241
|
-
<div class="mobile-menu" id="mobile-menu">
|
242
|
-
<div class="mobile-menu-container">
|
243
|
-
<div class="mobile-menu-header">
|
244
|
-
<div class="brand">
|
245
|
-
{logoUrl ? (
|
246
|
-
<img src={logoUrl} alt={brandName} class="brand-logo" />
|
247
|
-
) : (
|
248
|
-
<span class="brand-name">{brandName}</span>
|
249
|
-
)}
|
250
|
-
</div>
|
251
|
-
<button class="close-menu-button" aria-label="关闭菜单" id="close-mobile-menu">
|
252
|
-
<span class="close-icon">✕</span>
|
253
|
-
</button>
|
254
|
-
</div>
|
255
|
-
|
256
|
-
<nav class="mobile-nav">
|
257
|
-
<ul class="mobile-nav-list">
|
258
|
-
{navItems.map((item: NavItem) => (
|
259
|
-
<li class="mobile-nav-item">
|
260
|
-
<a href={item.href} class="mobile-nav-link">
|
261
|
-
{item.label}
|
262
|
-
</a>
|
263
|
-
</li>
|
264
|
-
))}
|
265
|
-
</ul>
|
266
|
-
</nav>
|
267
|
-
</div>
|
268
|
-
</div>
|
269
|
-
|
270
|
-
<!-- 英雄区块 -->
|
271
|
-
<section class="hero-section">
|
272
|
-
<div class="container">
|
273
|
-
<slot name="hero" />
|
274
|
-
</div>
|
275
|
-
</section>
|
276
|
-
|
277
|
-
<!-- 主要内容 -->
|
278
|
-
<main class="main-content">
|
279
|
-
<slot />
|
280
|
-
</main>
|
281
|
-
|
282
|
-
<!-- 页脚 -->
|
283
|
-
<footer class="site-footer">
|
284
|
-
<div class="container">
|
285
|
-
<div class="footer-content">
|
286
|
-
<div class="footer-brand">
|
287
|
-
<div class="brand">
|
288
|
-
{logoUrl ? (
|
289
|
-
<img src={logoUrl} alt={brandName} class="brand-logo" />
|
290
|
-
) : (
|
291
|
-
<span class="brand-name">{brandName}</span>
|
292
|
-
)}
|
293
|
-
</div>
|
294
|
-
<p class="brand-tagline">
|
295
|
-
<slot name="footer-tagline">简短的品牌标语或描述</slot>
|
296
|
-
</p>
|
297
|
-
|
298
|
-
<div class="social-links">
|
299
|
-
{socialLinks.map((link: SocialLink) => (
|
300
|
-
<a href={link.href} class="social-link" aria-label={link.label} target="_blank" rel="noopener noreferrer">
|
301
|
-
<span class="social-icon">{socialIconMap[link.icon] || "🔗"}</span>
|
302
|
-
</a>
|
303
|
-
))}
|
304
|
-
</div>
|
305
|
-
</div>
|
306
|
-
|
307
|
-
<div class="footer-links">
|
308
|
-
{footerSections.map((section: FooterSection) => (
|
309
|
-
<div class="footer-section">
|
310
|
-
<h3 class="footer-title">{section.title}</h3>
|
311
|
-
<ul class="footer-list">
|
312
|
-
{section.links.map((link: FooterLink) => (
|
313
|
-
<li class="footer-item">
|
314
|
-
<a href={link.href} class="footer-link">{link.label}</a>
|
315
|
-
</li>
|
316
|
-
))}
|
317
|
-
</ul>
|
318
|
-
</div>
|
319
|
-
))}
|
320
|
-
</div>
|
321
|
-
</div>
|
322
|
-
|
323
|
-
<div class="footer-bottom">
|
324
|
-
<p class="copyright">{copyright}</p>
|
325
|
-
<slot name="footer-extra" />
|
326
|
-
</div>
|
327
|
-
</div>
|
328
|
-
</footer>
|
329
|
-
</BaseLayout>
|
330
|
-
|
331
|
-
<script>
|
332
|
-
// 移动端菜单功能
|
333
|
-
document.addEventListener('DOMContentLoaded', () => {
|
334
|
-
const mobileMenuToggle = document.getElementById('mobile-menu-toggle');
|
335
|
-
const closeMobileMenu = document.getElementById('close-mobile-menu');
|
336
|
-
const mobileMenu = document.getElementById('mobile-menu');
|
337
|
-
const mobileNavLinks = document.querySelectorAll('.mobile-nav-link');
|
338
|
-
|
339
|
-
if (mobileMenuToggle && mobileMenu) {
|
340
|
-
mobileMenuToggle.addEventListener('click', () => {
|
341
|
-
mobileMenu.classList.add('active');
|
342
|
-
document.body.style.overflow = 'hidden';
|
343
|
-
});
|
344
|
-
}
|
345
|
-
|
346
|
-
if (closeMobileMenu && mobileMenu) {
|
347
|
-
closeMobileMenu.addEventListener('click', () => {
|
348
|
-
mobileMenu.classList.remove('active');
|
349
|
-
document.body.style.overflow = '';
|
350
|
-
});
|
351
|
-
}
|
352
|
-
|
353
|
-
// 点击导航链接后关闭菜单
|
354
|
-
mobileNavLinks.forEach(link => {
|
355
|
-
link.addEventListener('click', () => {
|
356
|
-
if (mobileMenu) {
|
357
|
-
mobileMenu.classList.remove('active');
|
358
|
-
document.body.style.overflow = '';
|
359
|
-
}
|
360
|
-
});
|
361
|
-
});
|
362
|
-
|
363
|
-
// 页眉滚动效果
|
364
|
-
const header = document.querySelector('.site-header');
|
365
|
-
let lastScrollTop = 0;
|
366
|
-
|
367
|
-
window.addEventListener('scroll', () => {
|
368
|
-
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
369
|
-
|
370
|
-
if (header) {
|
371
|
-
if (scrollTop > 100) {
|
372
|
-
header.classList.add('scrolled');
|
373
|
-
|
374
|
-
if (scrollTop > lastScrollTop) {
|
375
|
-
header.classList.add('hidden');
|
376
|
-
} else {
|
377
|
-
header.classList.remove('hidden');
|
378
|
-
}
|
379
|
-
} else {
|
380
|
-
header.classList.remove('scrolled');
|
381
|
-
header.classList.remove('hidden');
|
382
|
-
}
|
383
|
-
}
|
384
|
-
|
385
|
-
lastScrollTop = scrollTop;
|
386
|
-
});
|
387
|
-
});
|
388
|
-
</script>
|