@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
@@ -1,18 +1,18 @@
|
|
1
1
|
---
|
2
2
|
/**
|
3
3
|
* @component Grid
|
4
|
-
*
|
4
|
+
*
|
5
5
|
* @description
|
6
6
|
* Grid 组件是一个灵活的网格布局组件,用于创建响应式的多列布局。
|
7
7
|
* 它封装了 CSS Grid 的常用功能,提供简单易用的接口来控制网格的列数和间距。
|
8
|
-
*
|
8
|
+
*
|
9
9
|
* @design
|
10
10
|
* 设计理念:
|
11
11
|
* 1. 简单易用 - 通过简洁的 API 控制复杂的 Grid 布局
|
12
12
|
* 2. 响应式优先 - 内置响应式断点,轻松创建适应不同屏幕尺寸的布局
|
13
13
|
* 3. 灵活可配置 - 支持自定义列数和间距
|
14
14
|
* 4. 语义化属性 - 使用直观的属性名称,降低学习成本
|
15
|
-
*
|
15
|
+
*
|
16
16
|
* @usage
|
17
17
|
* 基本用法:
|
18
18
|
* ```astro
|
@@ -22,7 +22,7 @@
|
|
22
22
|
* <div>第三列</div>
|
23
23
|
* </Grid>
|
24
24
|
* ```
|
25
|
-
*
|
25
|
+
*
|
26
26
|
* 响应式网格:
|
27
27
|
* ```astro
|
28
28
|
* <Grid cols={{base: 1, md: 2, lg: 3}} gap="lg">
|
@@ -31,7 +31,7 @@
|
|
31
31
|
* <div>显示不同的列数</div>
|
32
32
|
* </Grid>
|
33
33
|
* ```
|
34
|
-
*
|
34
|
+
*
|
35
35
|
* 自定义行列间距:
|
36
36
|
* ```astro
|
37
37
|
* <Grid cols={2} rowGap="lg" colGap="sm">
|
@@ -41,7 +41,7 @@
|
|
41
41
|
* <div>第四项</div>
|
42
42
|
* </Grid>
|
43
43
|
* ```
|
44
|
-
*
|
44
|
+
*
|
45
45
|
* @props
|
46
46
|
* @prop {number | Object} [cols=1] - 网格列数,可以是固定值或响应式对象
|
47
47
|
* @prop {string} [gap="md"] - 网格间距,可选值:none, xs, sm, md, lg, xl
|
@@ -59,124 +59,132 @@ import type { HTMLAttributes } from 'astro/types';
|
|
59
59
|
type GapSize = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
60
60
|
type Breakpoint = 'base' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
61
61
|
|
62
|
-
type ResponsiveValue<T> =
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
type ResponsiveValue<T> =
|
63
|
+
| T
|
64
|
+
| {
|
65
|
+
base?: T;
|
66
|
+
sm?: T;
|
67
|
+
md?: T;
|
68
|
+
lg?: T;
|
69
|
+
xl?: T;
|
70
|
+
'2xl'?: T;
|
71
|
+
};
|
70
72
|
|
71
73
|
interface Props extends HTMLAttributes<'div'> {
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
74
|
+
/**
|
75
|
+
* 网格列数,可以是固定值或响应式对象
|
76
|
+
* @default 1
|
77
|
+
*/
|
78
|
+
cols?: ResponsiveValue<number>;
|
79
|
+
|
80
|
+
/**
|
81
|
+
* 网格间距
|
82
|
+
* @default "md"
|
83
|
+
*/
|
84
|
+
gap?: GapSize;
|
85
|
+
|
86
|
+
/**
|
87
|
+
* 行间距,默认与gap相同
|
88
|
+
*/
|
89
|
+
rowGap?: GapSize;
|
90
|
+
|
91
|
+
/**
|
92
|
+
* 列间距,默认与gap相同
|
93
|
+
*/
|
94
|
+
colGap?: GapSize;
|
95
|
+
|
96
|
+
/**
|
97
|
+
* 自定义类名
|
98
|
+
*/
|
99
|
+
class?: string;
|
100
|
+
|
101
|
+
/**
|
102
|
+
* 类名列表
|
103
|
+
*/
|
104
|
+
'class:list'?: any;
|
103
105
|
}
|
104
106
|
|
105
107
|
const {
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
108
|
+
cols = 1,
|
109
|
+
gap = 'md',
|
110
|
+
rowGap,
|
111
|
+
colGap,
|
112
|
+
class: className = '',
|
113
|
+
'class:list': classList,
|
114
|
+
...rest
|
113
115
|
} = Astro.props;
|
114
116
|
|
115
117
|
// 处理响应式列数
|
116
118
|
const getColsClasses = (cols: ResponsiveValue<number>) => {
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
119
|
+
if (typeof cols === 'number') {
|
120
|
+
return `cosy:grid-cols-${cols}`;
|
121
|
+
}
|
122
|
+
|
123
|
+
const breakpoints: Record<Breakpoint, string> = {
|
124
|
+
base: '',
|
125
|
+
sm: 'sm:',
|
126
|
+
md: 'md:',
|
127
|
+
lg: 'lg:',
|
128
|
+
xl: 'xl:',
|
129
|
+
'2xl': '2xl:',
|
130
|
+
};
|
131
|
+
|
132
|
+
return Object.entries(cols)
|
133
|
+
.map(([breakpoint, value]) => {
|
134
|
+
if (breakpoint === 'base') {
|
135
|
+
return `cosy:grid-cols-${value}`;
|
136
|
+
}
|
137
|
+
return `cosy:${breakpoints[breakpoint as Breakpoint]}grid-cols-${value}`;
|
138
|
+
})
|
139
|
+
.join(' ');
|
138
140
|
};
|
139
141
|
|
140
142
|
// 间距映射
|
141
143
|
const gapClasses: Record<GapSize, string> = {
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
144
|
+
none: 'cosy:gap-0',
|
145
|
+
xs: 'cosy:gap-2',
|
146
|
+
sm: 'cosy:gap-4',
|
147
|
+
md: 'cosy:gap-6',
|
148
|
+
lg: 'cosy:gap-8',
|
149
|
+
xl: 'cosy:gap-12',
|
148
150
|
};
|
149
151
|
|
150
152
|
// 行间距映射
|
151
153
|
const rowGapClasses: Record<GapSize, string> = {
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
154
|
+
none: 'cosy:row-gap-0',
|
155
|
+
xs: 'cosy:row-gap-2',
|
156
|
+
sm: 'cosy:row-gap-4',
|
157
|
+
md: 'cosy:row-gap-6',
|
158
|
+
lg: 'cosy:row-gap-8',
|
159
|
+
xl: 'cosy:row-gap-12',
|
158
160
|
};
|
159
161
|
|
160
162
|
// 列间距映射
|
161
163
|
const colGapClasses: Record<GapSize, string> = {
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
164
|
+
none: 'cosy:col-gap-0',
|
165
|
+
xs: 'cosy:col-gap-2',
|
166
|
+
sm: 'cosy:col-gap-4',
|
167
|
+
md: 'cosy:col-gap-6',
|
168
|
+
lg: 'cosy:col-gap-8',
|
169
|
+
xl: 'cosy:col-gap-12',
|
168
170
|
};
|
169
171
|
|
170
172
|
// 构建最终类名
|
171
173
|
const gridClasses = [
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
]
|
174
|
+
'cosy:grid',
|
175
|
+
getColsClasses(cols),
|
176
|
+
rowGap
|
177
|
+
? rowGapClasses[rowGap as GapSize]
|
178
|
+
: colGap
|
179
|
+
? gapClasses[gap as GapSize]
|
180
|
+
: gapClasses[gap as GapSize],
|
181
|
+
colGap ? colGapClasses[colGap as GapSize] : null,
|
182
|
+
className,
|
183
|
+
]
|
184
|
+
.filter(Boolean)
|
185
|
+
.join(' ');
|
178
186
|
---
|
179
187
|
|
180
188
|
<div class:list={[gridClasses, classList]} {...rest}>
|
181
|
-
|
189
|
+
<slot />
|
182
190
|
</div>
|
@@ -26,24 +26,27 @@
|
|
26
26
|
* />
|
27
27
|
* ```
|
28
28
|
*
|
29
|
-
*
|
29
|
+
* 自定义导航菜单位置:
|
30
30
|
* ```astro
|
31
31
|
* <Header
|
32
32
|
* logo={import("../assets/logo.png")}
|
33
|
-
*
|
34
|
-
*
|
35
|
-
* {
|
36
|
-
* {
|
33
|
+
* navPosition="start"
|
34
|
+
* navItems={[
|
35
|
+
* { href: "/docs", label: "文档", match: (path) => path.startsWith("/docs") },
|
36
|
+
* { href: "/components", label: "组件", match: (path) => path.startsWith("/components") }
|
37
37
|
* ]}
|
38
|
-
* currentLocale="zh-cn"
|
39
38
|
* />
|
40
39
|
* ```
|
40
|
+
* navPosition 可选值:
|
41
|
+
* - start: 导航菜单在左侧
|
42
|
+
* - center: 导航菜单在中间(默认)
|
43
|
+
* - end: 导航菜单在右侧
|
41
44
|
*
|
42
|
-
*
|
45
|
+
* 自定义语言选项:
|
43
46
|
* ```astro
|
44
47
|
* <Header
|
45
48
|
* logo={import("../assets/logo.png")}
|
46
|
-
*
|
49
|
+
* languages={["zh-cn", "en", "ja"]}
|
47
50
|
* />
|
48
51
|
* ```
|
49
52
|
*
|
@@ -57,54 +60,27 @@
|
|
57
60
|
import '../../app.css';
|
58
61
|
import Link from '../base/Link.astro';
|
59
62
|
import Image from '../base/Image.astro';
|
60
|
-
import type
|
63
|
+
import { LanguageSwitcher, LinkUtil, type HeaderProps, type NavItem } from '../../index';
|
61
64
|
import Logo from '../../assets/logo-rounded.png';
|
62
65
|
|
63
|
-
interface Props extends HeaderProps {
|
66
|
+
export interface Props extends HeaderProps {
|
67
|
+
debug?: boolean;
|
68
|
+
}
|
64
69
|
|
65
70
|
const {
|
66
|
-
basePath = '',
|
67
|
-
currentLocale = 'zh-cn',
|
68
71
|
height = 'md',
|
69
|
-
languages = [
|
70
|
-
{ code: 'zh-cn', name: '中文' },
|
71
|
-
{ code: 'en', name: 'English' },
|
72
|
-
],
|
72
|
+
languages = ['zh-cn', 'en'],
|
73
73
|
logo = Logo,
|
74
74
|
logoHref = '/',
|
75
75
|
navItems = [],
|
76
76
|
sticky = true,
|
77
|
+
debug = false,
|
78
|
+
rounded = 'none',
|
79
|
+
paddingHorizontal = 'none',
|
80
|
+
paddingVertical = 'none',
|
81
|
+
navPosition = 'center',
|
77
82
|
} = Astro.props;
|
78
83
|
|
79
|
-
type NavItem = { href: string; label: string; match: (path: string) => boolean };
|
80
|
-
|
81
|
-
// 获取当前路径
|
82
|
-
const currentPath = Astro.url.pathname;
|
83
|
-
|
84
|
-
// 处理基础路径
|
85
|
-
const basePathPattern = basePath ? new RegExp(`^${basePath}`) : null;
|
86
|
-
const pathWithoutBase = basePathPattern ? currentPath.replace(basePathPattern, '') : currentPath;
|
87
|
-
|
88
|
-
// 提取路径部分,排除语言代码
|
89
|
-
const pathWithoutLocale = pathWithoutBase.replace(/^\/(zh-cn|en)/, '');
|
90
|
-
|
91
|
-
// 生成语言切换链接
|
92
|
-
function getLanguageUrl(langCode: string) {
|
93
|
-
// 如果有基础路径,需要加上
|
94
|
-
return `${basePath}/${langCode}${pathWithoutLocale}`;
|
95
|
-
}
|
96
|
-
|
97
|
-
// 获取初始高度(优先使用localStorage中的值)
|
98
|
-
type HeightType = '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
99
|
-
|
100
|
-
let initialHeight: HeightType;
|
101
|
-
if (typeof window !== 'undefined') {
|
102
|
-
const storedHeight = localStorage.getItem('cosy-header-height');
|
103
|
-
initialHeight = (storedHeight as HeightType) || height;
|
104
|
-
} else {
|
105
|
-
initialHeight = height;
|
106
|
-
}
|
107
|
-
|
108
84
|
// 根据高度设置样式
|
109
85
|
const headerHeightClasses = {
|
110
86
|
'3xs': 'cosy:h-4',
|
@@ -116,7 +92,16 @@ const headerHeightClasses = {
|
|
116
92
|
xl: 'cosy:h-20',
|
117
93
|
};
|
118
94
|
|
119
|
-
const headerHeightClass = headerHeightClasses[
|
95
|
+
const headerHeightClass = headerHeightClasses[height];
|
96
|
+
const linkHeightClasses = {
|
97
|
+
'3xs': 'cosy:py-0',
|
98
|
+
'2xs': 'cosy:py-0',
|
99
|
+
xs: 'cosy:py-0',
|
100
|
+
sm: 'cosy:py-1',
|
101
|
+
md: 'cosy:py-1',
|
102
|
+
lg: 'cosy:py-2',
|
103
|
+
xl: 'cosy:py-3',
|
104
|
+
};
|
120
105
|
|
121
106
|
// 设置logo大小
|
122
107
|
const logoSizeClasses = {
|
@@ -129,101 +114,155 @@ const logoSizeClasses = {
|
|
129
114
|
xl: 'cosy:w-12 cosy:h-12',
|
130
115
|
};
|
131
116
|
|
132
|
-
const logoSizeClass = logoSizeClasses[
|
117
|
+
const logoSizeClass = logoSizeClasses[height];
|
118
|
+
const linkHeightClass = linkHeightClasses[height];
|
119
|
+
const currentPath = Astro.url.pathname;
|
120
|
+
const activeLink = LinkUtil.getActiveLink(
|
121
|
+
currentPath,
|
122
|
+
navItems.map((item: NavItem) => item.href)
|
123
|
+
);
|
133
124
|
---
|
134
125
|
|
135
126
|
<header
|
136
127
|
class:list={[
|
137
|
-
'cosy:
|
138
|
-
|
139
|
-
|
128
|
+
'cosy:w-full cosy:z-50',
|
129
|
+
{
|
130
|
+
'cosy:fixed cosy:top-0': sticky,
|
131
|
+
'cosy:border cosy:bg-amber-300 cosy:border-dashed cosy:border-green-500': debug,
|
132
|
+
},
|
133
|
+
{
|
134
|
+
'cosy:px-2': paddingHorizontal === 'sm',
|
135
|
+
'cosy:px-4': paddingHorizontal === 'md',
|
136
|
+
'cosy:px-6': paddingHorizontal === 'lg',
|
137
|
+
'cosy:px-8': paddingHorizontal === 'xl',
|
138
|
+
'cosy:px-12': paddingHorizontal === '2xl',
|
139
|
+
'cosy:px-16': paddingHorizontal === '3xl',
|
140
|
+
},
|
141
|
+
{
|
142
|
+
'cosy:py-2': paddingVertical === 'sm',
|
143
|
+
'cosy:py-4': paddingVertical === 'md',
|
144
|
+
'cosy:py-6': paddingVertical === 'lg',
|
145
|
+
'cosy:py-8': paddingVertical === 'xl',
|
146
|
+
'cosy:py-12': paddingVertical === '2xl',
|
147
|
+
'cosy:py-16': paddingVertical === '3xl',
|
148
|
+
},
|
140
149
|
]}>
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
<ul
|
159
|
-
class:list={[
|
160
|
-
'cosy:px-1 cosy:menu cosy:menu-horizontal',
|
161
|
-
initialHeight === 'xs' || initialHeight === '2xs' || initialHeight === '3xs'
|
162
|
-
? 'cosy:menu-xs'
|
163
|
-
: initialHeight === 'sm'
|
164
|
-
? 'cosy:menu-sm'
|
165
|
-
: '',
|
166
|
-
]}>
|
150
|
+
<!-- 背景 -->
|
151
|
+
<div
|
152
|
+
class:list={[
|
153
|
+
'cosy:bg-accent/70 cosy:flex cosy:flex-grow cosy:backdrop-blur not-prose cosy:border-base-200',
|
154
|
+
{
|
155
|
+
'cosy:rounded-none': rounded === 'none',
|
156
|
+
'cosy:rounded-sm': rounded === 'sm',
|
157
|
+
'cosy:rounded-md': rounded === 'md',
|
158
|
+
'cosy:rounded-lg': rounded === 'lg',
|
159
|
+
'cosy:rounded-xl': rounded === 'xl',
|
160
|
+
'cosy:rounded-full': rounded === 'full',
|
161
|
+
},
|
162
|
+
headerHeightClass,
|
163
|
+
{ 'cosy:border cosy:border-dashed cosy:border-red-500': debug },
|
164
|
+
]}>
|
165
|
+
<!-- 左侧 -->
|
166
|
+
<div class="cosy:navbar-start cosy:pl-1">
|
167
167
|
{
|
168
|
-
|
169
|
-
<
|
168
|
+
navPosition === 'start' ? (
|
169
|
+
<div class="cosy:flex cosy:items-center cosy:gap-4">
|
170
170
|
<Link
|
171
|
-
|
171
|
+
animation="none"
|
172
|
+
debug={debug}
|
173
|
+
href={logoHref}
|
174
|
+
class:list={['cosy:btn cosy:btn-ghost', linkHeightClass]}>
|
175
|
+
<Image
|
176
|
+
rounded="full"
|
177
|
+
showPlaceholder={false}
|
178
|
+
transition="none"
|
179
|
+
lazy={false}
|
180
|
+
src={logo}
|
181
|
+
alt="logo"
|
182
|
+
class={logoSizeClass}
|
183
|
+
/>
|
184
|
+
</Link>
|
185
|
+
<ul
|
172
186
|
class:list={[
|
173
|
-
|
174
|
-
|
175
|
-
: initialHeight === 'sm'
|
176
|
-
? 'cosy:py-1 cosy:min-h-6'
|
177
|
-
: '',
|
187
|
+
'cosy:hidden cosy:lg:flex cosy:px-1 cosy:menu cosy:menu-horizontal',
|
188
|
+
linkHeightClass,
|
178
189
|
]}>
|
179
|
-
{item
|
180
|
-
|
181
|
-
|
182
|
-
|
190
|
+
{navItems.map((item: NavItem) => (
|
191
|
+
<li>
|
192
|
+
<Link
|
193
|
+
variant={activeLink == item.href ? 'primary' : 'default'}
|
194
|
+
href={item.href}
|
195
|
+
class:list={[linkHeightClass]}>
|
196
|
+
{item.label}
|
197
|
+
</Link>
|
198
|
+
</li>
|
199
|
+
))}
|
200
|
+
</ul>
|
201
|
+
</div>
|
202
|
+
) : (
|
203
|
+
<Link
|
204
|
+
animation="none"
|
205
|
+
debug={debug}
|
206
|
+
href={logoHref}
|
207
|
+
class:list={['cosy:btn cosy:btn-ghost', linkHeightClass]}>
|
208
|
+
<Image
|
209
|
+
rounded="full"
|
210
|
+
showPlaceholder={false}
|
211
|
+
transition="none"
|
212
|
+
lazy={false}
|
213
|
+
src={logo}
|
214
|
+
alt="logo"
|
215
|
+
class={logoSizeClass}
|
216
|
+
/>
|
217
|
+
</Link>
|
218
|
+
)
|
183
219
|
}
|
184
|
-
</
|
185
|
-
</div>
|
220
|
+
</div>
|
186
221
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
222
|
+
<!-- 中间 -->
|
223
|
+
{
|
224
|
+
navPosition === 'center' && (
|
225
|
+
<div class="cosy:hidden cosy:lg:flex cosy:navbar-center">
|
226
|
+
<ul class:list={['cosy:px-1 cosy:menu cosy:menu-horizontal', linkHeightClass]}>
|
227
|
+
{navItems.map((item: NavItem) => (
|
228
|
+
<li>
|
229
|
+
<Link
|
230
|
+
variant={activeLink == item.href ? 'primary' : 'default'}
|
231
|
+
href={item.href}
|
232
|
+
class:list={[linkHeightClass]}>
|
233
|
+
{item.label}
|
234
|
+
</Link>
|
235
|
+
</li>
|
236
|
+
))}
|
237
|
+
</ul>
|
238
|
+
</div>
|
239
|
+
)
|
240
|
+
}
|
241
|
+
|
242
|
+
<!-- 右侧 -->
|
243
|
+
<div class="cosy:navbar-end cosy:pr-1">
|
244
|
+
{
|
245
|
+
navPosition === 'end' && (
|
246
|
+
<ul
|
247
|
+
class:list={[
|
248
|
+
'cosy:hidden cosy:lg:flex cosy:px-1 cosy:menu cosy:menu-horizontal',
|
249
|
+
linkHeightClass,
|
250
|
+
]}>
|
251
|
+
{navItems.map((item: NavItem) => (
|
252
|
+
<li>
|
253
|
+
<Link
|
254
|
+
variant={activeLink == item.href ? 'primary' : 'default'}
|
255
|
+
href={item.href}
|
256
|
+
class:list={[linkHeightClass]}>
|
257
|
+
{item.label}
|
258
|
+
</Link>
|
259
|
+
</li>
|
260
|
+
))}
|
261
|
+
</ul>
|
262
|
+
)
|
263
|
+
}
|
264
|
+
<!-- 语言切换 -->
|
265
|
+
<LanguageSwitcher languages={languages} />
|
227
266
|
</div>
|
228
267
|
</div>
|
229
268
|
</header>
|
@@ -73,7 +73,7 @@ function getVerticalMarginBottomClasses(marginBottom: string) {
|
|
73
73
|
|
74
74
|
// 获取当前活动的一级导航项
|
75
75
|
const currentSection = sidebarItems.find((section) =>
|
76
|
-
section.items
|
76
|
+
section.items?.some((item) => isPathMatch(currentPath, item.href))
|
77
77
|
);
|
78
78
|
---
|
79
79
|
|
@@ -90,16 +90,16 @@ const currentSection = sidebarItems.find((section) =>
|
|
90
90
|
data-modal-target="mobile-sidebar">
|
91
91
|
<MenuIcon class="cosy:w-5 cosy:h-5" />
|
92
92
|
</button>
|
93
|
-
<span class="cosy:font-medium cosy:text-sm">{currentSection?.
|
93
|
+
<span class="cosy:font-medium cosy:text-sm">{currentSection?.text || '导航'}</span>
|
94
94
|
</div>
|
95
|
-
</div
|
95
|
+
</div>
|
96
96
|
|
97
97
|
{/* 移动端侧边栏弹出层 */}
|
98
98
|
<Modal id="mobile-sidebar" class="cosy:mx-4 cosy:lg:w-80 cosy:w-[calc(100vw-2rem)] cosy:max-w-full">
|
99
99
|
<div class="cosy:h-[calc(100vh-8rem)] cosy:overflow-y-auto">
|
100
100
|
<SidebarNav sidebarItems={sidebarItems} currentPath={currentPath} debug={debug} />
|
101
101
|
</div>
|
102
|
-
</Modal
|
102
|
+
</Modal>
|
103
103
|
|
104
104
|
{/* 桌面端侧边栏 */}
|
105
105
|
<aside
|
@@ -116,4 +116,4 @@ const currentSection = sidebarItems.find((section) =>
|
|
116
116
|
<div class="cosy:top-16 cosy:sticky cosy:pb-48 cosy:h-[calc(100vh-0rem)] cosy:overflow-y-auto">
|
117
117
|
<SidebarNav sidebarItems={sidebarItems} currentPath={currentPath} debug={debug} />
|
118
118
|
</div>
|
119
|
-
</aside
|
119
|
+
</aside>
|