xto-fronted 0.4.5 → 0.4.7

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.
Files changed (83) hide show
  1. package/dist/index-54irhCHL.js +1830 -0
  2. package/dist/{index-CWRs4WMN.js → index-BzRf1eoJ.js} +1 -1
  3. package/dist/{index-Bn4ThpX9.js → index-DH4aoCZb.js} +1 -1
  4. package/dist/{index-BlRrngsc.js → index-Kqa7iZ9E.js} +1 -1
  5. package/dist/{index-B3PLzNB0.js → index-pxkZlvBw.js} +1 -1
  6. package/dist/index.es.js +1 -1
  7. package/dist/index.umd.js +1 -1
  8. package/dist/style.css +1 -1
  9. package/package.json +7 -8
  10. package/src/components/Layout/Sidebar.vue +100 -8
  11. package/src/views/login/index.vue +11 -5
  12. package/dist/index-B6DTsC6l.js +0 -1715
  13. package/dist/index-B7etKk33.js +0 -372
  14. package/dist/index-B7mpL6Zf.js +0 -475
  15. package/dist/index-BBqvHkzE.js +0 -475
  16. package/dist/index-BC2PGkkJ.js +0 -1644
  17. package/dist/index-BGgbfcmf.js +0 -475
  18. package/dist/index-BGmUwemj.js +0 -372
  19. package/dist/index-BQFfQj5Q.js +0 -142
  20. package/dist/index-BQqo0ZIb.js +0 -345
  21. package/dist/index-BkRneTya.js +0 -142
  22. package/dist/index-BmVvM7sm.js +0 -345
  23. package/dist/index-BwfjwDKr.js +0 -1477
  24. package/dist/index-BxIL2hrt.js +0 -475
  25. package/dist/index-C-3fhbN2.js +0 -1644
  26. package/dist/index-C0VN9nFF.js +0 -142
  27. package/dist/index-C0xyGOsz.js +0 -475
  28. package/dist/index-C3c8NAZq.js +0 -1477
  29. package/dist/index-C42VtP71.js +0 -142
  30. package/dist/index-C6Nm0r9k.js +0 -475
  31. package/dist/index-C6w0-8xN.js +0 -1648
  32. package/dist/index-CD364XjV.js +0 -142
  33. package/dist/index-CHww99-i.js +0 -345
  34. package/dist/index-CIgWYERJ.js +0 -1644
  35. package/dist/index-CTs6DTuQ.js +0 -345
  36. package/dist/index-Cb-SxHJp.js +0 -345
  37. package/dist/index-CeCysOnl.js +0 -345
  38. package/dist/index-Cg1UpC8D.js +0 -1644
  39. package/dist/index-Cgkqpyx2.js +0 -345
  40. package/dist/index-CiuDEfo-.js +0 -142
  41. package/dist/index-CmQfZC8r.js +0 -372
  42. package/dist/index-CmkjhpX_.js +0 -475
  43. package/dist/index-CpxpXTQX.js +0 -1462
  44. package/dist/index-CqXFk_ET.js +0 -345
  45. package/dist/index-CtvB5J9E.js +0 -372
  46. package/dist/index-Cu3Z2-PY.js +0 -345
  47. package/dist/index-CvDxK7Ab.js +0 -372
  48. package/dist/index-D-FER0vJ.js +0 -372
  49. package/dist/index-D2fQ8TK8.js +0 -475
  50. package/dist/index-D3xVcFvg.js +0 -372
  51. package/dist/index-D4crnrO6.js +0 -142
  52. package/dist/index-D7EzwTM5.js +0 -372
  53. package/dist/index-D7TZamyY.js +0 -1664
  54. package/dist/index-D88fiqXR.js +0 -475
  55. package/dist/index-DEbpF-M4.js +0 -1457
  56. package/dist/index-DFXuyPge.js +0 -1627
  57. package/dist/index-DLgimJYb.js +0 -1667
  58. package/dist/index-DPEVEyik.js +0 -475
  59. package/dist/index-DWy_UGhI.js +0 -345
  60. package/dist/index-DYVtddfw.js +0 -142
  61. package/dist/index-DYnXaqYf.js +0 -142
  62. package/dist/index-DcvRPHuy.js +0 -372
  63. package/dist/index-DdC1uV2v.js +0 -1700
  64. package/dist/index-Dga14ZN7.js +0 -1774
  65. package/dist/index-Dk2V44uP.js +0 -372
  66. package/dist/index-DnJ481u1.js +0 -475
  67. package/dist/index-Do1CBqg8.js +0 -345
  68. package/dist/index-Jb4VMHIS.js +0 -142
  69. package/dist/index-MC3wWjNt.js +0 -475
  70. package/dist/index-MG0JePmx.js +0 -142
  71. package/dist/index-QgkT42dc.js +0 -372
  72. package/dist/index-TrLCW5xL.js +0 -372
  73. package/dist/index-YDlNLFVk.js +0 -142
  74. package/dist/index-ZAJgA3XD.js +0 -475
  75. package/dist/index-a_ilWAvi.js +0 -345
  76. package/dist/index-bi1TMGid.js +0 -372
  77. package/dist/index-fyarVCog.js +0 -475
  78. package/dist/index-mnTZtPFa.js +0 -345
  79. package/dist/index-orZCyV6I.js +0 -345
  80. package/dist/index-p3TbK44c.js +0 -142
  81. package/dist/index-sRwZYbZ4.js +0 -372
  82. package/dist/index-wATqKEcF.js +0 -142
  83. package/dist/setup.d.ts +0 -17
@@ -6,8 +6,7 @@ import { useUserStore } from '@/stores/user'
6
6
  import { useAuthStore } from '@/stores/auth'
7
7
  import { useAppStore } from '@/stores/app'
8
8
  import { Menu, MenuItem, SubMenu } from '@xto/navigation'
9
- import { Button } from '@xto/base'
10
- import { Icon } from '@xto/base'
9
+ import { Button, Icon } from '@xto/base'
11
10
 
12
11
  const route = useRoute()
13
12
  const router = useRouter()
@@ -39,13 +38,54 @@ const handleLogout = () => {
39
38
  router.push('/login')
40
39
  }
41
40
 
41
+ // 已知的图标名称列表(来自 @xto/base/icons.ts)
42
+ const knownIcons = new Set([
43
+ 'arrow-up', 'arrow-down', 'arrow-left', 'arrow-right',
44
+ 'caret-down', 'caret-right', 'plus', 'minus', 'close', 'check',
45
+ 'edit', 'delete', 'copy', 'download', 'upload', 'refresh', 'search',
46
+ 'filter', 'more', 'setting', 'share', 'loading', 'info', 'success',
47
+ 'warning', 'error', 'question', 'user', 'user-add', 'user-group',
48
+ 'logout', 'login', 'file', 'folder', 'folder-open', 'document',
49
+ 'image', 'video', 'music', 'camera', 'mail', 'phone', 'chat',
50
+ 'bell', 'message', 'eye', 'eye-off', 'calendar', 'clock', 'history',
51
+ 'timer', 'location', 'map', 'globe', 'star', 'heart', 'thumb-up',
52
+ 'link', 'external-link', 'lock', 'unlock', 'key', 'home', 'menu',
53
+ 'menu-fold', 'menu-unfold', 'sidebar-fold', 'sidebar-expand',
54
+ 'sidebar-left', 'dashboard', 'chart', 'chart-pie', 'chart-line',
55
+ 'report', 'analytics', 'system', 'permission', 'role', 'user-manage',
56
+ 'log', 'notification', 'app', 'list', 'grid', 'fullscreen',
57
+ 'fullscreen-exit', 'zoom-in', 'zoom-out', 'print', 'bookmark',
58
+ 'tag', 'code', 'terminal', 'database', 'server', 'cloud', 'gift',
59
+ 'moon', 'sun', 'theme', 'skin'
60
+ ])
61
+
42
62
  // 获取菜单图标名称
43
63
  const getMenuIcon = (icon?: string): string => {
44
- if (!icon) return 'file'
64
+ // 无图标时返回空
65
+ if (!icon || icon === '') return ''
66
+
45
67
  // 处理 tineco-ui 的图标类名(如 tineco-icon-home)
46
68
  if (icon.startsWith('tineco-icon-')) {
47
- return icon.replace('tineco-icon-', '')
69
+ const iconName = icon.replace('tineco-icon-', '')
70
+ // 常见的 tineco icon 映射
71
+ const tinecoIconMap: Record<string, string> = {
72
+ home: 'home',
73
+ dashboard: 'dashboard',
74
+ system: 'system',
75
+ user: 'user',
76
+ role: 'role',
77
+ menu: 'list',
78
+ setting: 'setting',
79
+ file: 'file',
80
+ folder: 'folder',
81
+ chart: 'chart',
82
+ report: 'report',
83
+ analytics: 'analytics'
84
+ }
85
+ return tinecoIconMap[iconName] || iconName
48
86
  }
87
+
88
+ // 常见业务图标映射
49
89
  const iconMap: Record<string, string> = {
50
90
  dashboard: 'dashboard',
51
91
  system: 'system',
@@ -53,10 +93,31 @@ const getMenuIcon = (icon?: string): string => {
53
93
  role: 'role',
54
94
  menu: 'list',
55
95
  setting: 'setting',
56
- home: 'home'
96
+ home: 'home',
97
+ chart: 'chart',
98
+ report: 'report',
99
+ analytics: 'analytics',
100
+ permission: 'permission',
101
+ log: 'log',
102
+ notification: 'notification',
103
+ app: 'app',
104
+ list: 'list',
105
+ grid: 'grid'
57
106
  }
107
+
58
108
  return iconMap[icon] || icon
59
109
  }
110
+
111
+ // 获取菜单名称第一个字
112
+ const getFirstChar = (name?: string): string => {
113
+ if (!name) return ''
114
+ return name.charAt(0)
115
+ }
116
+
117
+ // 判断图标是否存在
118
+ const iconExists = (iconName: string): boolean => {
119
+ return knownIcons.has(iconName)
120
+ }
60
121
  </script>
61
122
 
62
123
  <template>
@@ -83,7 +144,10 @@ const getMenuIcon = (icon?: string): string => {
83
144
  <!-- 有子菜单 -->
84
145
  <SubMenu v-if="menu.children && menu.children.length > 0" :index="menu.menuUrl">
85
146
  <template #title>
86
- <Icon :name="getMenuIcon(menu.icon)" :size="16" />
147
+ <span class="sidebar__menu-icon">
148
+ <Icon v-if="iconExists(getMenuIcon(menu.icon))" :name="getMenuIcon(menu.icon)" :size="16" />
149
+ <span v-else class="sidebar__menu-char">{{ getFirstChar(menu.menuName) }}</span>
150
+ </span>
87
151
  <span>{{ menu.menuName }}</span>
88
152
  </template>
89
153
  <MenuItem
@@ -91,13 +155,19 @@ const getMenuIcon = (icon?: string): string => {
91
155
  :key="child.menuUrl"
92
156
  :index="child.menuUrl"
93
157
  >
94
- <Icon :name="getMenuIcon(child.icon)" :size="16" />
158
+ <span class="sidebar__menu-icon">
159
+ <Icon v-if="iconExists(getMenuIcon(child.icon))" :name="getMenuIcon(child.icon)" :size="16" />
160
+ <span v-else class="sidebar__menu-char">{{ getFirstChar(child.menuName) }}</span>
161
+ </span>
95
162
  <span>{{ child.menuName }}</span>
96
163
  </MenuItem>
97
164
  </SubMenu>
98
165
  <!-- 无子菜单 -->
99
166
  <MenuItem v-else :index="menu.menuUrl">
100
- <Icon :name="getMenuIcon(menu.icon)" :size="16" />
167
+ <span class="sidebar__menu-icon">
168
+ <Icon v-if="iconExists(getMenuIcon(menu.icon))" :name="getMenuIcon(menu.icon)" :size="16" />
169
+ <span v-else class="sidebar__menu-char">{{ getFirstChar(menu.menuName) }}</span>
170
+ </span>
101
171
  <span>{{ menu.menuName }}</span>
102
172
  </MenuItem>
103
173
  </template>
@@ -155,6 +225,28 @@ const getMenuIcon = (icon?: string): string => {
155
225
  overflow-y: auto;
156
226
  }
157
227
 
228
+ &__menu-icon {
229
+ display: inline-flex;
230
+ align-items: center;
231
+ justify-content: center;
232
+ width: 16px;
233
+ height: 16px;
234
+ margin-right: 8px;
235
+ }
236
+
237
+ &__menu-char {
238
+ display: inline-flex;
239
+ align-items: center;
240
+ justify-content: center;
241
+ width: 16px;
242
+ height: 16px;
243
+ font-size: 12px;
244
+ font-weight: 600;
245
+ color: var(--color-primary);
246
+ background-color: var(--color-primary-light-8);
247
+ border-radius: 4px;
248
+ }
249
+
158
250
  &__user {
159
251
  padding: 10px;
160
252
  border-top: 1px solid var(--color-border-lighter);
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import { ref, reactive } from 'vue'
3
3
  import { useRouter, useRoute } from 'vue-router'
4
- import { Button } from '@xto/base'
4
+ import { Button, Icon } from '@xto/base'
5
5
  import { Form, FormItem, Input, Checkbox } from '@xto/form'
6
6
  import { Message } from '@xto/feedback'
7
7
  import { login } from '@/api/auth'
@@ -84,9 +84,12 @@ const handleLogin = async () => {
84
84
  <Input
85
85
  v-model="formData.uid"
86
86
  placeholder="用户名"
87
- prefix-icon="👤"
88
87
  size="large"
89
- />
88
+ >
89
+ <template #prefix>
90
+ <Icon name="user" :size="18" />
91
+ </template>
92
+ </Input>
90
93
  </FormItem>
91
94
 
92
95
  <FormItem prop="password">
@@ -94,11 +97,14 @@ const handleLogin = async () => {
94
97
  v-model="formData.password"
95
98
  type="password"
96
99
  placeholder="密码"
97
- prefix-icon="🔒"
98
100
  size="large"
99
101
  show-password
100
102
  @keyup.enter="handleLogin"
101
- />
103
+ >
104
+ <template #prefix>
105
+ <Icon name="lock" :size="18" />
106
+ </template>
107
+ </Input>
102
108
  </FormItem>
103
109
 
104
110
  <FormItem>