@coffic/cosy-ui 0.4.9 → 0.5.4
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/Image.astro +2 -4
- package/dist/components/errors/404.astro +10 -0
- package/dist/components/icons/ChevronDownIcon.astro +34 -0
- package/dist/components/layouts/AppLayout.astro +1 -17
- package/dist/components/layouts/Footer.astro +2 -2
- package/dist/components/layouts/Grid.astro +106 -98
- package/dist/components/layouts/Header.astro +169 -130
- package/dist/components/layouts/Sidebar.astro +5 -5
- package/dist/components/layouts/SidebarNav.astro +5 -5
- package/dist/components/navigation/LanguageSwitcher.astro +22 -68
- package/dist/components/navigation/TableOfContents.astro +2 -2
- package/dist/entities/SidebarItem.ts +20 -23
- package/dist/index.ts +3 -0
- package/dist/models/BaseDoc.ts +10 -10
- package/dist/types/header.ts +11 -12
- package/dist/types/sidebar.ts +4 -6
- package/dist/utils/language.ts +137 -133
- package/dist/utils/link.ts +28 -2
- package/package.json +1 -1
- package/dist/i18n/Language.ts +0 -25
- package/dist/i18n/ui.ts +0 -18
- package/dist/i18n/utils.ts +0 -54
@@ -7,13 +7,13 @@
|
|
7
7
|
|
8
8
|
import { isPathMatch } from '../../utils/path';
|
9
9
|
import '../../app.css';
|
10
|
-
import type {
|
10
|
+
import type { SidebarItem } from '../../types/sidebar';
|
11
11
|
|
12
12
|
interface Props {
|
13
13
|
/**
|
14
14
|
* 侧边栏项目
|
15
15
|
*/
|
16
|
-
sidebarItems:
|
16
|
+
sidebarItems: SidebarItem[];
|
17
17
|
|
18
18
|
/**
|
19
19
|
* 当前路径
|
@@ -39,13 +39,13 @@ const debugClass = debug ? 'cosy:border cosy:border-red-500' : '';
|
|
39
39
|
|
40
40
|
<nav class:list={['cosy:p-4', debugClass, className]}>
|
41
41
|
{
|
42
|
-
sidebarItems.map((section:
|
42
|
+
sidebarItems.map((section: SidebarItem) => (
|
43
43
|
<div class:list={['cosy:mb-6', debugClass]}>
|
44
44
|
<h3 class:list={['cosy:font-bold cosy:mb-2 cosy:text-base-content/70', debugClass]}>
|
45
|
-
{section.
|
45
|
+
{section.text}
|
46
46
|
</h3>
|
47
47
|
<ul class:list={['cosy:menu cosy:bg-base-200 cosy:rounded-box cosy:w-56', debugClass]}>
|
48
|
-
{section.items
|
48
|
+
{section.items?.map((item: SidebarItem) => {
|
49
49
|
const isActive = isPathMatch(currentPath, item.href);
|
50
50
|
return (
|
51
51
|
<li class:list={[debugClass]}>
|
@@ -22,88 +22,42 @@
|
|
22
22
|
* 自定义语言列表:
|
23
23
|
* ```astro
|
24
24
|
* <LanguageSwitcher
|
25
|
-
* languages={[
|
26
|
-
* { code: 'zh-cn', name: '简体中文' },
|
27
|
-
* { code: 'en', name: 'English' },
|
28
|
-
* { code: 'ja', name: '日本語' }
|
29
|
-
* ]}
|
30
|
-
* currentLocale="en"
|
25
|
+
* languages={['zh-cn', 'en']}
|
31
26
|
* />
|
32
27
|
* ```
|
33
28
|
*/
|
34
29
|
|
35
|
-
import
|
36
|
-
import Link from '../base/Link.astro';
|
30
|
+
import ChevronDownIcon from '../icons/ChevronDownIcon.astro';
|
37
31
|
import '../../app.css';
|
38
|
-
|
39
|
-
interface Language {
|
40
|
-
code: string;
|
41
|
-
name: string;
|
42
|
-
}
|
32
|
+
import { LanguageUtil } from '../../utils/language';
|
43
33
|
|
44
34
|
interface Props {
|
45
|
-
|
46
|
-
* 自定义类名
|
47
|
-
*/
|
48
|
-
class?: string;
|
49
|
-
|
50
|
-
/**
|
51
|
-
* 语言列表
|
52
|
-
* @default [{ code: 'zh-cn', name: '简体中文' }, { code: 'en', name: 'English' }]
|
53
|
-
*/
|
54
|
-
languages?: Language[];
|
55
|
-
|
56
|
-
/**
|
57
|
-
* 当前语言
|
58
|
-
* @default 'zh-cn'
|
59
|
-
*/
|
60
|
-
currentLocale?: string;
|
35
|
+
languages: string[];
|
61
36
|
}
|
62
37
|
|
63
|
-
const {
|
64
|
-
class: className,
|
65
|
-
languages = [
|
66
|
-
{ code: 'zh-cn', name: '简体中文' },
|
67
|
-
{ code: 'en', name: 'English' },
|
68
|
-
],
|
69
|
-
currentLocale = 'zh-cn',
|
70
|
-
} = Astro.props;
|
38
|
+
const { languages = ['zh-cn', 'en'] } = Astro.props;
|
71
39
|
|
72
|
-
const
|
73
|
-
|
74
|
-
|
75
|
-
// 为每个语言生成对应的URL
|
76
|
-
function generateLanguageUrl(langCode: string): string {
|
77
|
-
const currentPath = Astro.url.pathname;
|
78
|
-
const pathParts = currentPath.split('/').filter(Boolean);
|
79
|
-
const firstPathPart = pathParts[0];
|
80
|
-
const supportedLanguages = languages.map((lang: Language) => lang.code);
|
81
|
-
const isFirstPartLang = supportedLanguages.includes(firstPathPart);
|
82
|
-
|
83
|
-
if (isFirstPartLang) {
|
84
|
-
pathParts[0] = langCode;
|
85
|
-
return '/' + pathParts.join('/');
|
86
|
-
} else {
|
87
|
-
return '/' + langCode + (currentPath === '/' ? '' : currentPath);
|
88
|
-
}
|
89
|
-
}
|
40
|
+
const currentLocale = Astro.currentLocale;
|
41
|
+
const currentLanguageName = LanguageUtil.getLanguageName(currentLocale);
|
90
42
|
---
|
91
43
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
44
|
+
<!-- 语言切换按钮 -->
|
45
|
+
<div class="cosy:dropdown cosy:dropdown-end">
|
46
|
+
<div tabindex="0" role="button" class:list={['cosy:btn cosy:btn-ghost']}>
|
47
|
+
<span class="cosy:mr-1">{currentLanguageName}</span>
|
48
|
+
<ChevronDownIcon size="16px" class="cosy:w-4 cosy:h-4" />
|
49
|
+
</div>
|
96
50
|
<ul
|
97
|
-
tabindex=
|
98
|
-
class="cosy:
|
51
|
+
tabindex="0"
|
52
|
+
class="cosy:z-[1] cosy:bg-base-100 cosy:shadow cosy:p-2 cosy:rounded-box cosy:w-32 cosy:dropdown-content cosy:menu">
|
99
53
|
{
|
100
|
-
languages.map((lang
|
101
|
-
<li>
|
102
|
-
<
|
103
|
-
href={
|
104
|
-
class
|
105
|
-
{lang
|
106
|
-
</
|
54
|
+
languages.map((lang) => (
|
55
|
+
<li class={currentLocale === lang ? 'cosy:disabled' : ''}>
|
56
|
+
<a
|
57
|
+
href={LanguageUtil.getRelativeLink(lang, Astro)}
|
58
|
+
class={currentLocale === lang ? 'cosy:active' : ''}>
|
59
|
+
{LanguageUtil.getLanguageName(lang)}
|
60
|
+
</a>
|
107
61
|
</li>
|
108
62
|
))
|
109
63
|
}
|
@@ -54,8 +54,8 @@
|
|
54
54
|
|
55
55
|
// 导入样式
|
56
56
|
import '../../app.css';
|
57
|
-
import { getCurrentLanguage } from '../../utils/language';
|
58
57
|
import { createTextGetter } from '../../utils/i18n';
|
58
|
+
import { LanguageUtil } from '../../utils/language';
|
59
59
|
|
60
60
|
interface Props {
|
61
61
|
/**
|
@@ -111,7 +111,7 @@ const {
|
|
111
111
|
} = Astro.props;
|
112
112
|
|
113
113
|
// 获取当前语言
|
114
|
-
const langInfo = getCurrentLanguage(userLang);
|
114
|
+
const langInfo = LanguageUtil.getCurrentLanguage(userLang);
|
115
115
|
// 创建文本获取函数
|
116
116
|
const t = createTextGetter(langInfo, 'tableOfContents');
|
117
117
|
// 获取标题文本,如果用户提供了标题则使用用户提供的标题
|
@@ -1,24 +1,21 @@
|
|
1
|
-
|
2
|
-
* 侧边栏项目接口
|
3
|
-
*/
|
4
|
-
export interface SidebarItemProps {
|
5
|
-
label: string;
|
6
|
-
link?: string;
|
7
|
-
items?: SidebarItem[];
|
8
|
-
}
|
1
|
+
import { type SidebarItem } from '../types/sidebar';
|
9
2
|
|
10
3
|
/**
|
11
4
|
* 侧边栏项目类
|
12
5
|
* 用于构建网站的侧边栏导航
|
13
6
|
*/
|
14
|
-
export class SidebarItem {
|
15
|
-
|
16
|
-
|
7
|
+
export class SidebarItemEntity implements SidebarItem {
|
8
|
+
text: string;
|
9
|
+
href: string;
|
17
10
|
items: SidebarItem[];
|
18
11
|
|
19
|
-
constructor(props:
|
20
|
-
|
21
|
-
|
12
|
+
constructor(props: {
|
13
|
+
text: string;
|
14
|
+
link?: string;
|
15
|
+
items?: SidebarItem[];
|
16
|
+
}) {
|
17
|
+
this.text = props.text;
|
18
|
+
this.href = props.link || '';
|
22
19
|
this.items = props.items || [];
|
23
20
|
}
|
24
21
|
|
@@ -26,7 +23,7 @@ export class SidebarItem {
|
|
26
23
|
* 添加子项目
|
27
24
|
* @param item 要添加的子项目
|
28
25
|
*/
|
29
|
-
addItem(item:
|
26
|
+
addItem(item: SidebarItemEntity): void {
|
30
27
|
this.items.push(item);
|
31
28
|
}
|
32
29
|
|
@@ -34,8 +31,8 @@ export class SidebarItem {
|
|
34
31
|
* 获取所有子项目
|
35
32
|
* @returns 子项目数组
|
36
33
|
*/
|
37
|
-
getItems():
|
38
|
-
return this.items;
|
34
|
+
getItems(): SidebarItemEntity[] {
|
35
|
+
return this.items.map(item => new SidebarItemEntity(item));
|
39
36
|
}
|
40
37
|
|
41
38
|
/**
|
@@ -43,7 +40,7 @@ export class SidebarItem {
|
|
43
40
|
* @returns 项目标签
|
44
41
|
*/
|
45
42
|
getLabel(): string {
|
46
|
-
return this.
|
43
|
+
return this.text;
|
47
44
|
}
|
48
45
|
|
49
46
|
/**
|
@@ -51,14 +48,14 @@ export class SidebarItem {
|
|
51
48
|
* @returns 项目链接
|
52
49
|
*/
|
53
50
|
getLink(): string {
|
54
|
-
return this.
|
51
|
+
return this.href;
|
55
52
|
}
|
56
53
|
|
57
54
|
/**
|
58
55
|
* 获取包括自身在内的所有项目
|
59
56
|
* @returns 包括自身在内的所有项目
|
60
57
|
*/
|
61
|
-
getItemsIncludingSelf():
|
58
|
+
getItemsIncludingSelf(): SidebarItemEntity[] {
|
62
59
|
return [this, ...this.getItems()];
|
63
60
|
}
|
64
61
|
|
@@ -87,10 +84,10 @@ export interface SidebarProvider {
|
|
87
84
|
/**
|
88
85
|
* 转换为侧边栏项目
|
89
86
|
*/
|
90
|
-
toSidebarItem(): Promise<
|
87
|
+
toSidebarItem(): Promise<SidebarItemEntity>;
|
91
88
|
|
92
89
|
/**
|
93
90
|
* 获取顶级侧边栏项目
|
94
91
|
*/
|
95
|
-
getTopSidebarItem?(): Promise<
|
96
|
-
}
|
92
|
+
getTopSidebarItem?(): Promise<SidebarItemEntity>;
|
93
|
+
}
|
package/dist/index.ts
CHANGED
@@ -42,6 +42,9 @@ export { default as Article } from './components/typography/Article.astro';
|
|
42
42
|
export { default as Text } from './components/typography/Text.astro';
|
43
43
|
export { default as Heading } from './components/typography/Heading.astro';
|
44
44
|
|
45
|
+
// Errors Page
|
46
|
+
export { default as ErrorPage404 } from './components/errors/404.astro';
|
47
|
+
|
45
48
|
// Icons
|
46
49
|
export { default as SocialIcon } from './components/icons/SocialIcon.astro';
|
47
50
|
export { default as TwitterIcon } from './components/icons/TwitterIcon.astro';
|
package/dist/models/BaseDoc.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { render, type RenderResult, type CollectionEntry, type DataEntryMap } from "astro:content";
|
2
|
-
import {
|
2
|
+
import { SidebarItemEntity, type SidebarProvider } from "../entities/SidebarItem";
|
3
3
|
import { logger } from "../utils/logger";
|
4
4
|
|
5
5
|
/**
|
@@ -72,9 +72,9 @@ export abstract class BaseDoc<Collection extends keyof DataEntryMap, T extends C
|
|
72
72
|
* 转换为侧边栏项目
|
73
73
|
* 基本实现,只包含当前文档
|
74
74
|
*/
|
75
|
-
async toSidebarItem(): Promise<
|
76
|
-
return new
|
77
|
-
|
75
|
+
async toSidebarItem(): Promise<SidebarItemEntity> {
|
76
|
+
return new SidebarItemEntity({
|
77
|
+
text: this.getTitle(),
|
78
78
|
link: this.getLink(),
|
79
79
|
});
|
80
80
|
}
|
@@ -125,7 +125,7 @@ export abstract class HierarchicalDoc<Collection extends keyof DataEntryMap, T e
|
|
125
125
|
* 转换为侧边栏项目
|
126
126
|
* 如果文档有子文档,会包含子文档的侧边栏项目
|
127
127
|
*/
|
128
|
-
override async toSidebarItem(): Promise<
|
128
|
+
override async toSidebarItem(): Promise<SidebarItemEntity> {
|
129
129
|
const debug = false;
|
130
130
|
|
131
131
|
const children = await this.getChildren();
|
@@ -137,8 +137,8 @@ export abstract class HierarchicalDoc<Collection extends keyof DataEntryMap, T e
|
|
137
137
|
console.log(childItems);
|
138
138
|
}
|
139
139
|
|
140
|
-
return new
|
141
|
-
|
140
|
+
return new SidebarItemEntity({
|
141
|
+
text: this.getTitle(),
|
142
142
|
items: childItems,
|
143
143
|
link: this.getLink(),
|
144
144
|
});
|
@@ -149,14 +149,14 @@ export abstract class HierarchicalDoc<Collection extends keyof DataEntryMap, T e
|
|
149
149
|
* 如果有顶级文档,返回顶级文档的侧边栏项目
|
150
150
|
* 否则返回当前文档的侧边栏项目
|
151
151
|
*/
|
152
|
-
async getTopSidebarItem(): Promise<
|
152
|
+
async getTopSidebarItem(): Promise<SidebarItemEntity> {
|
153
153
|
const topDoc = await this.getTopDoc();
|
154
154
|
if (topDoc) {
|
155
155
|
return await topDoc.toSidebarItem();
|
156
156
|
}
|
157
157
|
|
158
|
-
return new
|
159
|
-
|
158
|
+
return new SidebarItemEntity({
|
159
|
+
text: this.getTitle(),
|
160
160
|
items: [],
|
161
161
|
link: this.getLink(),
|
162
162
|
});
|
package/dist/types/header.ts
CHANGED
@@ -1,10 +1,4 @@
|
|
1
1
|
export interface HeaderProps {
|
2
|
-
/**
|
3
|
-
* 基础路径,用于处理网站部署在二级目录的情况
|
4
|
-
* @default ""
|
5
|
-
*/
|
6
|
-
basePath?: string;
|
7
|
-
|
8
2
|
/**
|
9
3
|
* 当前语言代码
|
10
4
|
*/
|
@@ -25,7 +19,7 @@ export interface HeaderProps {
|
|
25
19
|
/**
|
26
20
|
* 语言选项列表
|
27
21
|
*/
|
28
|
-
languages?:
|
22
|
+
languages?: string[];
|
29
23
|
|
30
24
|
/**
|
31
25
|
* Logo图片元数据
|
@@ -41,11 +35,7 @@ export interface HeaderProps {
|
|
41
35
|
/**
|
42
36
|
* 导航菜单项
|
43
37
|
*/
|
44
|
-
navItems?:
|
45
|
-
href: string;
|
46
|
-
label: string;
|
47
|
-
match: (path: string) => boolean;
|
48
|
-
}>;
|
38
|
+
navItems?: NavItem[];
|
49
39
|
|
50
40
|
/**
|
51
41
|
* 是否显示侧边栏切换按钮
|
@@ -67,4 +57,13 @@ export interface HeaderProps {
|
|
67
57
|
* @default true
|
68
58
|
*/
|
69
59
|
sticky?: boolean;
|
60
|
+
|
61
|
+
rounded?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
62
|
+
|
63
|
+
paddingHorizontal?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
|
64
|
+
paddingVertical?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
|
65
|
+
|
66
|
+
navPosition?: 'start' | 'center' | 'end';
|
70
67
|
}
|
68
|
+
|
69
|
+
export type NavItem = { href: string; label: string; };
|
package/dist/types/sidebar.ts
CHANGED
@@ -1,19 +1,17 @@
|
|
1
|
+
/**
|
2
|
+
* 侧边栏项目
|
3
|
+
*/
|
1
4
|
export interface SidebarItem {
|
2
5
|
href: string;
|
3
6
|
text: string;
|
4
7
|
items?: SidebarItem[];
|
5
8
|
}
|
6
9
|
|
7
|
-
export interface SidebarSection {
|
8
|
-
title: string;
|
9
|
-
items: SidebarItem[];
|
10
|
-
}
|
11
|
-
|
12
10
|
export interface SidebarProps {
|
13
11
|
/**
|
14
12
|
* 侧边栏项目
|
15
13
|
*/
|
16
|
-
sidebarItems:
|
14
|
+
sidebarItems: SidebarItem[];
|
17
15
|
|
18
16
|
/**
|
19
17
|
* 桌面端类名
|