@coffic/cosy-ui 0.8.11 → 0.8.12

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.
@@ -14,6 +14,7 @@
14
14
  * 4. 状态保持 - 记住用户的侧边栏折叠状态
15
15
  *
16
16
  * @usage
17
+ * 基本用法:
17
18
  * ```astro
18
19
  * ---
19
20
  * import { DashboardLayout } from '@coffic/cosy-ui';
@@ -24,12 +25,19 @@
24
25
  * { href: "/dashboard/settings", text: "系统设置" }, // 自动匹配 settings 图标
25
26
  * { href: "/dashboard/reports", icon: "chart", text: "报表" } // 手动指定图标
26
27
  * ];
28
+ *
29
+ * const userMenuItems = [
30
+ * { href: "/profile", text: "个人资料" }, // 自动匹配 user 图标
31
+ * { href: "/settings", text: "设置" }, // 自动匹配 settings 图标
32
+ * { href: "/logout", text: "退出登录" } // 自动匹配 logout 图标
33
+ * ];
27
34
  * ---
28
35
  *
29
36
  * <DashboardLayout
30
37
  * title="管理后台"
31
38
  * navItems={navItems}
32
39
  * userName="管理员"
40
+ * userMenuItems={userMenuItems}
33
41
  * sidebarSize="lg"
34
42
  * >
35
43
  * <h1>仪表盘内容</h1>
@@ -37,6 +45,45 @@
37
45
  * </DashboardLayout>
38
46
  * ```
39
47
  *
48
+ * 带有底部自定义内容的用法:
49
+ * ```astro
50
+ * <DashboardLayout
51
+ * title="管理后台"
52
+ * navItems={navItems}
53
+ * userName="管理员"
54
+ * >
55
+ * <h1>仪表盘内容</h1>
56
+ * <p>这是仪表盘的主要内容</p>
57
+ *
58
+ * <div slot="sidebar-footer" class="p-4">
59
+ * <div class="flex items-center gap-3">
60
+ * <div class="avatar">
61
+ * <div class="w-10 rounded-full">
62
+ * <img src="/avatar.jpg" alt="用户头像" />
63
+ * </div>
64
+ * </div>
65
+ * <div>
66
+ * <div class="font-semibold">张三</div>
67
+ * <div class="text-sm opacity-70">产品经理</div>
68
+ * </div>
69
+ * </div>
70
+ * </div>
71
+ * </DashboardLayout>
72
+ * ```
73
+ *
74
+ * 带有主内容区域背景的用法:
75
+ * ```astro
76
+ * <DashboardLayout
77
+ * title="管理后台"
78
+ * navItems={navItems}
79
+ * userName="管理员"
80
+ * mainBackgroundTheme="gradient-cool"
81
+ * >
82
+ * <h1>仪表盘内容</h1>
83
+ * <p>这是带有背景的主要内容</p>
84
+ * </DashboardLayout>
85
+ * ```
86
+ *
40
87
  * @props
41
88
  * - title: string - 页面标题
42
89
  * - description?: string - 页面描述
@@ -44,16 +91,19 @@
44
91
  * - navItems: NavItem[] - 导航项目
45
92
  * - userName?: string - 用户名
46
93
  * - userAvatar?: string - 用户头像
94
+ * - userMenuItems?: UserMenuItem[] - 用户菜单项,默认包含个人资料、设置、退出登录,图标会自动匹配
47
95
  * - sidebarCollapsed?: boolean - 是否折叠侧边栏,默认为false
48
96
  * - sidebarSize?: 'sm' | 'md' | 'lg' | 'xl' - 侧边栏尺寸,默认为"md"
49
97
  * - sidebarTheme?: SidebarTheme - 侧边栏主题,默认为"default"
50
- * - contentTheme?: ContentTheme - 内容区域主题,默认为"card"
98
+ * - mainBackgroundTheme?: MainBackgroundTheme - 主内容区域背景主题,默认为"transparent"
51
99
  * - head?: astroHTML.JSX.Element - 自定义头部内容
52
100
  * - class?: string - 页面类名
53
101
  * - class:list?: any - 类名列表
102
+ * - debug?: boolean - 调试模式,默认为false
54
103
  *
55
104
  * @slots
56
105
  * - default - 主要内容区域
106
+ * - sidebar-footer - 侧边栏底部自定义内容,可用于展示用户信息、版权信息等
57
107
  */
58
108
 
59
109
  import { BaseLayout } from '../../index-astro';
@@ -64,8 +114,9 @@ import {
64
114
  type NavItem,
65
115
  type SidebarSize,
66
116
  type SidebarTheme,
67
- type ContentTheme,
68
- getContentTheme,
117
+ type MainBackgroundTheme,
118
+ type UserMenuItem,
119
+ getMainBackgroundTheme,
69
120
  } from './types';
70
121
 
71
122
  export interface Props {
@@ -100,6 +151,11 @@ export interface Props {
100
151
  */
101
152
  userAvatar?: string;
102
153
 
154
+ /**
155
+ * 用户菜单项
156
+ */
157
+ userMenuItems?: UserMenuItem[];
158
+
103
159
  /**
104
160
  * 是否折叠侧边栏
105
161
  * @default false
@@ -119,10 +175,10 @@ export interface Props {
119
175
  sidebarTheme?: SidebarTheme;
120
176
 
121
177
  /**
122
- * 内容区域主题
123
- * @default "card"
178
+ * 主内容区域背景主题
179
+ * @default "transparent"
124
180
  */
125
- contentTheme?: ContentTheme;
181
+ mainBackgroundTheme?: MainBackgroundTheme;
126
182
 
127
183
  /**
128
184
  * 自定义头部内容
@@ -138,6 +194,12 @@ export interface Props {
138
194
  * 类名列表
139
195
  */
140
196
  'class:list'?: any;
197
+
198
+ /**
199
+ * 调试模式
200
+ * @default false
201
+ */
202
+ debug?: boolean;
141
203
  }
142
204
 
143
205
  const {
@@ -147,18 +209,20 @@ const {
147
209
  navItems,
148
210
  userName,
149
211
  userAvatar,
212
+ userMenuItems,
150
213
  sidebarCollapsed = false,
151
214
  sidebarSize = 'md',
152
215
  sidebarTheme = 'default',
153
- contentTheme = 'card',
216
+ mainBackgroundTheme = 'transparent',
154
217
  head,
155
218
  class: className,
156
219
  'class:list': classList,
220
+ debug = false,
157
221
  ...rest
158
222
  } = Astro.props;
159
223
 
160
224
  const currentPath = Astro.url.pathname;
161
- const contentStyles = getContentTheme(contentTheme);
225
+ const mainBackgroundStyles = getMainBackgroundTheme(mainBackgroundTheme);
162
226
  ---
163
227
 
164
228
  <BaseLayout
@@ -168,6 +232,7 @@ const contentStyles = getContentTheme(contentTheme);
168
232
  keywords=""
169
233
  author=""
170
234
  robots=""
235
+ debug={debug}
171
236
  class:list={['cosy:min-h-screen cosy:bg-base-200', className, classList]}
172
237
  {...rest}>
173
238
  <div class:list={['cosy:drawer', { 'cosy:drawer-open': !sidebarCollapsed }]}>
@@ -184,8 +249,9 @@ const contentStyles = getContentTheme(contentTheme);
184
249
  navItems={navItems}
185
250
  currentPath={currentPath}
186
251
  size={sidebarSize}
187
- theme={sidebarTheme}
188
- />
252
+ theme={sidebarTheme}>
253
+ <slot name="sidebar-footer" slot="footer" />
254
+ </DashboardSidebar>
189
255
  </div>
190
256
 
191
257
  <!-- 主内容区 -->
@@ -195,21 +261,13 @@ const contentStyles = getContentTheme(contentTheme);
195
261
  title={title}
196
262
  userName={userName}
197
263
  userAvatar={userAvatar}
264
+ userMenuItems={userMenuItems}
198
265
  />
199
266
 
200
267
  <!-- 页面内容 -->
201
- <main class="cosy:flex-1 cosy:p-4 cosy:lg:p-6">
202
- {
203
- contentStyles.container ? (
204
- <div class={`${contentStyles.container} ${contentStyles.shadow}`}>
205
- <div class="cosy:card-body">
206
- <slot />
207
- </div>
208
- </div>
209
- ) : (
210
- <slot />
211
- )
212
- }
268
+ <main
269
+ class:list={['cosy:flex-1 cosy:p-4 cosy:lg:p-6', mainBackgroundStyles]}>
270
+ <slot />
213
271
  </main>
214
272
  </div>
215
273
  </div>
@@ -29,6 +29,9 @@
29
29
  * - currentPath?: string - 当前路径,用于高亮当前页面
30
30
  * - size?: 'sm' | 'md' | 'lg' | 'xl' - 侧边栏尺寸,默认为"md"
31
31
  * - theme?: SidebarTheme - 侧边栏主题,默认为"default"
32
+ *
33
+ * @slots
34
+ * - footer - 侧边栏底部自定义内容,可用于展示用户信息等
32
35
  */
33
36
 
34
37
  import '../../style.ts';
@@ -86,7 +89,7 @@ const themeStyles = getSidebarTheme(theme);
86
89
  <aside
87
90
  class:list={[
88
91
  getSidebarWidth(size),
89
- 'cosy:min-h-full',
92
+ 'cosy:min-h-full cosy:flex cosy:flex-col',
90
93
  themeStyles.bg,
91
94
  themeStyles.textColor,
92
95
  ]}>
@@ -113,69 +116,79 @@ const themeStyles = getSidebarTheme(theme);
113
116
  </div>
114
117
 
115
118
  <!-- 导航菜单 -->
116
- <ul
117
- class="cosy:menu cosy:p-4 cosy:space-y-1 cosy:list-none cosy:no-underline">
118
- {
119
- navItems.map((item: NavItem) => {
120
- const isActive =
121
- currentPath === item.href ||
122
- (item.items &&
123
- item.items.some(
124
- (subitem: NavItem) => currentPath === subitem.href
125
- ));
126
-
127
- return (
128
- <li>
129
- <a
130
- href={item.href}
131
- class:list={['cosy:no-underline', { active: isActive }]}>
132
- <AstroIcon
133
- name={getNavItemIcon(item)}
134
- size="16px"
135
- stroke="currentColor"
136
- />
137
- <span>{item.text}</span>
138
- {item.badge && (
139
- <span class="cosy:badge cosy:badge-primary cosy:badge-sm">
140
- {item.badge}
141
- </span>
119
+ <div class="cosy:flex-1 cosy:overflow-y-auto">
120
+ <ul
121
+ class="cosy:menu cosy:p-4 cosy:space-y-1 cosy:list-none cosy:no-underline">
122
+ {
123
+ navItems.map((item: NavItem) => {
124
+ const isActive =
125
+ currentPath === item.href ||
126
+ (item.items &&
127
+ item.items.some(
128
+ (subitem: NavItem) => currentPath === subitem.href
129
+ ));
130
+
131
+ return (
132
+ <li>
133
+ <a
134
+ href={item.href}
135
+ class:list={[
136
+ 'cosy:no-underline',
137
+ { 'cosy:menu-active': isActive },
138
+ ]}>
139
+ <AstroIcon
140
+ name={getNavItemIcon(item)}
141
+ size="16px"
142
+ stroke="currentColor"
143
+ />
144
+ <span>{item.text}</span>
145
+ {item.badge && (
146
+ <span class="cosy:badge cosy:badge-primary cosy:badge-sm">
147
+ {item.badge}
148
+ </span>
149
+ )}
150
+ </a>
151
+
152
+ {item.items && (
153
+ <ul class="cosy:ml-4 cosy:list-none cosy:no-underline">
154
+ {item.items.map((subitem: NavItem) => {
155
+ const isSubActive = currentPath === subitem.href;
156
+ return (
157
+ <li>
158
+ <a
159
+ href={subitem.href}
160
+ class:list={[
161
+ 'cosy:text-sm cosy:no-underline',
162
+ { 'cosy:menu-active': isSubActive },
163
+ ]}>
164
+ <AstroIcon
165
+ name={getNavItemIcon(subitem)}
166
+ size="14px"
167
+ stroke="currentColor"
168
+ />
169
+ <span>{subitem.text}</span>
170
+ {subitem.badge && (
171
+ <span class="cosy:badge cosy:badge-primary cosy:badge-xs">
172
+ {subitem.badge}
173
+ </span>
174
+ )}
175
+ </a>
176
+ </li>
177
+ );
178
+ })}
179
+ </ul>
142
180
  )}
143
- </a>
144
-
145
- {item.items && (
146
- <ul class="cosy:ml-4 cosy:list-none cosy:no-underline">
147
- {item.items.map((subitem: NavItem) => {
148
- const isSubActive = currentPath === subitem.href;
149
- return (
150
- <li>
151
- <a
152
- href={subitem.href}
153
- class:list={[
154
- 'cosy:text-sm cosy:no-underline',
155
- { active: isSubActive },
156
- ]}>
157
- <AstroIcon
158
- name={getNavItemIcon(subitem)}
159
- size="14px"
160
- stroke="currentColor"
161
- />
162
- <span>{subitem.text}</span>
163
- {subitem.badge && (
164
- <span class="cosy:badge cosy:badge-primary cosy:badge-xs">
165
- {subitem.badge}
166
- </span>
167
- )}
168
- </a>
169
- </li>
170
- );
171
- })}
172
- </ul>
173
- )}
174
- </li>
175
- );
176
- })
177
- }
178
- </ul>
181
+ </li>
182
+ );
183
+ })
184
+ }
185
+ </ul>
186
+ </div>
187
+
188
+ <!-- 侧边栏底部自定义内容 -->
189
+ <div class:list={['cosy:mt-auto cosy:border-t', themeStyles.borderColor]}>
190
+ <slot name="footer" />
191
+ </div>
179
192
  </aside>
180
193
 
181
194
  <script>
@@ -10,12 +10,20 @@
10
10
  * ```astro
11
11
  * ---
12
12
  * import { DashboardTopNavbar } from '@coffic/cosy-ui';
13
+ *
14
+ * const userMenuItems = [
15
+ * { href: '/profile', text: '个人资料' }, // 自动匹配 user 图标
16
+ * { href: '/settings', text: '设置' }, // 自动匹配 settings 图标
17
+ * { href: '/logout', text: '退出登录' }, // 自动匹配 logout 图标
18
+ * { href: '/help', text: '帮助中心', icon: 'help' } // 也可手动指定图标
19
+ * ];
13
20
  * ---
14
21
  *
15
22
  * <DashboardTopNavbar
16
23
  * title="仪表盘"
17
24
  * userName="管理员"
18
25
  * userAvatar="/avatar.jpg"
26
+ * userMenuItems={userMenuItems}
19
27
  * />
20
28
  * ```
21
29
  *
@@ -23,10 +31,13 @@
23
31
  * - title: string - 页面标题,用于面包屑导航
24
32
  * - userName?: string - 用户名
25
33
  * - userAvatar?: string - 用户头像
34
+ * - userMenuItems?: UserMenuItem[] - 用户菜单项,默认包含个人资料、设置、退出登录,图标会自动匹配
26
35
  */
27
36
 
28
37
  import '../../style.ts';
29
38
  import AstroIcon from '../icons/AstroIcon.astro';
39
+ import type { UserMenuItem } from './types';
40
+ import { getUserMenuItemIcon } from './types';
30
41
 
31
42
  export interface Props {
32
43
  /**
@@ -43,9 +54,23 @@ export interface Props {
43
54
  * 用户头像
44
55
  */
45
56
  userAvatar?: string;
57
+
58
+ /**
59
+ * 用户菜单项
60
+ */
61
+ userMenuItems?: UserMenuItem[];
46
62
  }
47
63
 
48
- const { title, userName, userAvatar } = Astro.props;
64
+ const { title, userName, userAvatar, userMenuItems } = Astro.props;
65
+
66
+ // 默认用户菜单项
67
+ const defaultUserMenuItems: UserMenuItem[] = [
68
+ { href: '/profile', text: '个人资料' }, // 自动匹配 user 图标
69
+ { href: '/settings', text: '设置' }, // 自动匹配 settings 图标
70
+ { href: '/logout', text: '退出登录' }, // 自动匹配 logout 图标
71
+ ];
72
+
73
+ const menuItems = userMenuItems || defaultUserMenuItems;
49
74
  ---
50
75
 
51
76
  <div class="cosy:navbar cosy:bg-base-100 cosy:shadow-sm">
@@ -53,13 +78,12 @@ const { title, userName, userAvatar } = Astro.props;
53
78
  <label
54
79
  for="dashboard-drawer"
55
80
  class="cosy:btn cosy:btn-square cosy:btn-ghost cosy:lg:hidden">
56
- <AstroIcon name="menu" size="18px" stroke="currentColor" />
81
+ <AstroIcon name="menu" size="16px" stroke="currentColor" />
57
82
  </label>
58
83
 
59
- <div class="cosy:breadcrumbs cosy:text-sm cosy:ml-4">
60
- <ul>
61
- <li><span class="cosy:text-base-content/70">{title}</span></li>
62
- </ul>
84
+ <div
85
+ class="cosy:text-base-content/70 cosy:flex cosy:items-center cosy:h-full cosy:text-lg cosy:font-medium cosy:px-4">
86
+ {title}
63
87
  </div>
64
88
  </div>
65
89
 
@@ -115,15 +139,23 @@ const { title, userName, userAvatar } = Astro.props;
115
139
  <ul
116
140
  tabindex="0"
117
141
  class="cosy:dropdown-content cosy:menu cosy:p-2 cosy:shadow cosy:bg-base-100 cosy:rounded-box cosy:w-52">
118
- <li>
119
- <a class="cosy:no-underline">个人资料</a>
120
- </li>
121
- <li>
122
- <a class="cosy:no-underline">设置</a>
123
- </li>
124
- <li>
125
- <a class="cosy:no-underline">退出登录</a>
126
- </li>
142
+ {menuItems.map((item) => {
143
+ const iconName = getUserMenuItemIcon(item);
144
+ return (
145
+ <li>
146
+ <a
147
+ href={item.href}
148
+ class="cosy:no-underline cosy:flex cosy:items-center cosy:gap-2">
149
+ <AstroIcon
150
+ name={iconName}
151
+ size="16px"
152
+ stroke="currentColor"
153
+ />
154
+ {item.text}
155
+ </a>
156
+ </li>
157
+ );
158
+ })}
127
159
  </ul>
128
160
  </div>
129
161
  )
@@ -10,6 +10,15 @@ export interface NavItem {
10
10
  items?: NavItem[];
11
11
  }
12
12
 
13
+ /**
14
+ * 用户菜单项接口
15
+ */
16
+ export interface UserMenuItem {
17
+ href: string;
18
+ text: string;
19
+ icon?: string;
20
+ }
21
+
13
22
  /**
14
23
  * 侧边栏尺寸类型
15
24
  */
@@ -115,67 +124,43 @@ export function getSidebarTheme(theme: SidebarTheme = 'default') {
115
124
  }
116
125
 
117
126
  /**
118
- * 内容区域背景色主题类型
127
+ * 主内容区域背景主题类型
119
128
  */
120
- export type ContentTheme = 'card' | 'transparent' | 'base' | 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error';
129
+ export type MainBackgroundTheme = 'transparent' | 'base-100' | 'base-200' | 'base-300' | 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'gradient-warm' | 'gradient-cool' | 'gradient-rainbow' | 'gradient-sunset' | 'gradient-ocean' | 'gradient-forest';
130
+
131
+
121
132
 
122
133
  /**
123
- * 内容区域背景色主题配置映射
134
+ * 主内容区域背景主题配置映射
124
135
  */
125
- export const contentThemeMap: Record<ContentTheme, { container: string; shadow: string }> = {
126
- 'card': {
127
- container: 'cosy:card cosy:bg-base-100',
128
- shadow: 'cosy:shadow-sm'
129
- },
130
- 'transparent': {
131
- container: '',
132
- shadow: ''
133
- },
134
- 'base': {
135
- container: 'cosy:card cosy:bg-base-200',
136
- shadow: 'cosy:shadow-sm'
137
- },
138
- 'neutral': {
139
- container: 'cosy:card cosy:bg-neutral',
140
- shadow: 'cosy:shadow-sm'
141
- },
142
- 'primary': {
143
- container: 'cosy:card cosy:bg-primary cosy:text-primary-content',
144
- shadow: 'cosy:shadow-sm'
145
- },
146
- 'secondary': {
147
- container: 'cosy:card cosy:bg-secondary cosy:text-secondary-content',
148
- shadow: 'cosy:shadow-sm'
149
- },
150
- 'accent': {
151
- container: 'cosy:card cosy:bg-accent cosy:text-accent-content',
152
- shadow: 'cosy:shadow-sm'
153
- },
154
- 'info': {
155
- container: 'cosy:card cosy:bg-info cosy:text-info-content',
156
- shadow: 'cosy:shadow-sm'
157
- },
158
- 'success': {
159
- container: 'cosy:card cosy:bg-success cosy:text-success-content',
160
- shadow: 'cosy:shadow-sm'
161
- },
162
- 'warning': {
163
- container: 'cosy:card cosy:bg-warning cosy:text-warning-content',
164
- shadow: 'cosy:shadow-sm'
165
- },
166
- 'error': {
167
- container: 'cosy:card cosy:bg-error cosy:text-error-content',
168
- shadow: 'cosy:shadow-sm'
169
- }
136
+ export const mainBackgroundThemeMap: Record<MainBackgroundTheme, string> = {
137
+ 'transparent': '',
138
+ 'base-100': 'cosy:bg-base-100',
139
+ 'base-200': 'cosy:bg-base-200',
140
+ 'base-300': 'cosy:bg-base-300',
141
+ 'neutral': 'cosy:bg-neutral',
142
+ 'primary': 'cosy:bg-primary',
143
+ 'secondary': 'cosy:bg-secondary',
144
+ 'accent': 'cosy:bg-accent',
145
+ 'info': 'cosy:bg-info',
146
+ 'success': 'cosy:bg-success',
147
+ 'warning': 'cosy:bg-warning',
148
+ 'error': 'cosy:bg-error',
149
+ 'gradient-warm': 'cosy:bg-gradient-to-br cosy:from-orange-100 cosy:via-red-50 cosy:to-pink-100',
150
+ 'gradient-cool': 'cosy:bg-gradient-to-br cosy:from-blue-100 cosy:via-cyan-50 cosy:to-green-100',
151
+ 'gradient-rainbow': 'cosy:bg-gradient-to-br cosy:from-purple-100 cosy:via-pink-50 cosy:to-blue-100',
152
+ 'gradient-sunset': 'cosy:bg-gradient-to-br cosy:from-yellow-100 cosy:via-orange-50 cosy:to-red-100',
153
+ 'gradient-ocean': 'cosy:bg-gradient-to-br cosy:from-blue-100 cosy:via-teal-50 cosy:to-cyan-100',
154
+ 'gradient-forest': 'cosy:bg-gradient-to-br cosy:from-green-100 cosy:via-emerald-50 cosy:to-teal-100'
170
155
  };
171
156
 
172
157
  /**
173
- * 获取内容区域主题样式类
174
- * @param theme 内容主题
175
- * @returns 对应的样式配置
158
+ * 获取主内容区域背景主题样式类
159
+ * @param theme 主内容区域背景主题
160
+ * @returns 对应的样式类名
176
161
  */
177
- export function getContentTheme(theme: ContentTheme = 'card') {
178
- return contentThemeMap[theme];
162
+ export function getMainBackgroundTheme(theme: MainBackgroundTheme = 'transparent'): string {
163
+ return mainBackgroundThemeMap[theme];
179
164
  }
180
165
 
181
166
  /**
@@ -268,6 +253,10 @@ const hrefToIconMap: Record<string, string> = {
268
253
  'download': 'download',
269
254
  'upload': 'upload',
270
255
  'refresh': 'refresh',
256
+ 'logout': 'logout',
257
+ 'signin': 'login',
258
+ 'signout': 'logout',
259
+ 'exit': 'logout',
271
260
 
272
261
  // 工具和实用程序
273
262
  'clipboard': 'clipboard',
@@ -275,6 +264,8 @@ const hrefToIconMap: Record<string, string> = {
275
264
  'menu': 'menu',
276
265
  'close': 'close',
277
266
  'check': 'check',
267
+ 'help': 'help',
268
+ 'support': 'help',
278
269
  };
279
270
 
280
271
  /**
@@ -310,4 +301,19 @@ export function getNavItemIcon(item: NavItem): string {
310
301
 
311
302
  // 否则根据 href 自动推断
312
303
  return getIconFromHref(item.href);
304
+ }
305
+
306
+ /**
307
+ * 根据 UserMenuItem 获取完整的图标信息
308
+ * @param item 用户菜单项
309
+ * @returns 图标名称
310
+ */
311
+ export function getUserMenuItemIcon(item: UserMenuItem): string {
312
+ // 如果显式指定了图标,优先使用
313
+ if (item.icon) {
314
+ return item.icon;
315
+ }
316
+
317
+ // 否则根据 href 自动推断,用户菜单默认图标为 'user'
318
+ return getIconFromHref(item.href, 'user');
313
319
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffic/cosy-ui",
3
- "version": "0.8.11",
3
+ "version": "0.8.12",
4
4
  "description": "An astro component library",
5
5
  "author": {
6
6
  "name": "nookery",