jianghu-ui 1.0.1

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 (112) hide show
  1. package/README.md +376 -0
  2. package/dist/jianghu-ui.css +2318 -0
  3. package/dist/jianghu-ui.js +2 -0
  4. package/dist/jianghu-ui.js.LICENSE.txt +1 -0
  5. package/package.json +56 -0
  6. package/src/Design.stories.mdx +195 -0
  7. package/src/Introduction.stories.mdx +148 -0
  8. package/src/components/JhAddressSelect/JhAddressSelect.md +250 -0
  9. package/src/components/JhAddressSelect/JhAddressSelect.stories.js +282 -0
  10. package/src/components/JhAddressSelect/JhAddressSelect.vue +261 -0
  11. package/src/components/JhCard/JhCard.md +246 -0
  12. package/src/components/JhCard/JhCard.stories.js +688 -0
  13. package/src/components/JhCard/JhCard.vue +604 -0
  14. package/src/components/JhCheckCard/JhCheckCard.md +245 -0
  15. package/src/components/JhCheckCard/JhCheckCard.stories.js +750 -0
  16. package/src/components/JhCheckCard/JhCheckCard.vue +476 -0
  17. package/src/components/JhConfirmDialog/JhConfirmDialog.md +70 -0
  18. package/src/components/JhConfirmDialog/JhConfirmDialog.stories.js +550 -0
  19. package/src/components/JhConfirmDialog/JhConfirmDialog.vue +181 -0
  20. package/src/components/JhDateRangePicker/JhDateRangePicker.md +56 -0
  21. package/src/components/JhDateRangePicker/JhDateRangePicker.stories.js +320 -0
  22. package/src/components/JhDateRangePicker/JhDateRangePicker.vue +307 -0
  23. package/src/components/JhDescriptions/JhDescriptions.md +724 -0
  24. package/src/components/JhDescriptions/JhDescriptions.stories.js +858 -0
  25. package/src/components/JhDescriptions/JhDescriptions.vue +933 -0
  26. package/src/components/JhDraggable/JhDraggable.md +66 -0
  27. package/src/components/JhDraggable/JhDraggable.stories.js +161 -0
  28. package/src/components/JhDraggable/JhDraggable.vue +254 -0
  29. package/src/components/JhDrawer/JhDrawer.md +68 -0
  30. package/src/components/JhDrawer/JhDrawer.stories.js +478 -0
  31. package/src/components/JhDrawer/JhDrawer.vue +281 -0
  32. package/src/components/JhDrawerForm/JhDrawerForm.md +69 -0
  33. package/src/components/JhDrawerForm/JhDrawerForm.stories.js +492 -0
  34. package/src/components/JhDrawerForm/JhDrawerForm.vue +297 -0
  35. package/src/components/JhEditableTable/JhEditableTable.md +507 -0
  36. package/src/components/JhEditableTable/JhEditableTable.stories.js +615 -0
  37. package/src/components/JhEditableTable/JhEditableTable.vue +685 -0
  38. package/src/components/JhFileInput/JhFileInput.md +56 -0
  39. package/src/components/JhFileInput/JhFileInput.stories.js +103 -0
  40. package/src/components/JhFileInput/JhFileInput.vue +253 -0
  41. package/src/components/JhForm/JhForm.md +676 -0
  42. package/src/components/JhForm/JhForm.stories.js +1375 -0
  43. package/src/components/JhForm/JhForm.vue +657 -0
  44. package/src/components/JhFormField/JhFormField.stories.js +217 -0
  45. package/src/components/JhFormField/JhFormField.vue +439 -0
  46. package/src/components/JhFormFields/JhFormFields.md +647 -0
  47. package/src/components/JhFormFields/JhFormFields.stories.js +922 -0
  48. package/src/components/JhFormFields/JhFormFields.vue +998 -0
  49. package/src/components/JhFormList/JhFormList.md +303 -0
  50. package/src/components/JhFormList/JhFormList.stories.js +661 -0
  51. package/src/components/JhFormList/JhFormList.vue +1127 -0
  52. package/src/components/JhJsonEditor/JhJsonEditor.md +54 -0
  53. package/src/components/JhJsonEditor/JhJsonEditor.stories.js +157 -0
  54. package/src/components/JhJsonEditor/JhJsonEditor.vue +178 -0
  55. package/src/components/JhLayout/JhLayout.md +580 -0
  56. package/src/components/JhLayout/JhLayout.stories.js +414 -0
  57. package/src/components/JhLayout/JhLayout.vue +387 -0
  58. package/src/components/JhList/JhList.md +441 -0
  59. package/src/components/JhList/JhList.stories.js +524 -0
  60. package/src/components/JhList/JhList.vue +571 -0
  61. package/src/components/JhMarkdownEditor/JhMarkdownEditor.md +56 -0
  62. package/src/components/JhMarkdownEditor/JhMarkdownEditor.stories.js +191 -0
  63. package/src/components/JhMarkdownEditor/JhMarkdownEditor.vue +188 -0
  64. package/src/components/JhMask/JhMask.md +62 -0
  65. package/src/components/JhMask/JhMask.stories.js +270 -0
  66. package/src/components/JhMask/JhMask.vue +123 -0
  67. package/src/components/JhMenu/JhMenu.md +85 -0
  68. package/src/components/JhMenu/JhMenu.stories.js +384 -0
  69. package/src/components/JhMenu/JhMenu.vue +545 -0
  70. package/src/components/JhModal/JhModal.md +68 -0
  71. package/src/components/JhModal/JhModal.stories.js +562 -0
  72. package/src/components/JhModal/JhModal.vue +235 -0
  73. package/src/components/JhModalForm/JhModalForm.md +69 -0
  74. package/src/components/JhModalForm/JhModalForm.stories.js +592 -0
  75. package/src/components/JhModalForm/JhModalForm.vue +298 -0
  76. package/src/components/JhPageContainer/JhPageContainer.md +409 -0
  77. package/src/components/JhPageContainer/JhPageContainer.stories.js +209 -0
  78. package/src/components/JhPageContainer/JhPageContainer.vue +72 -0
  79. package/src/components/JhQueryFilter/JhQueryFilter.md +77 -0
  80. package/src/components/JhQueryFilter/JhQueryFilter.stories.js +684 -0
  81. package/src/components/JhQueryFilter/JhQueryFilter.vue +429 -0
  82. package/src/components/JhScene/JhScene.md +64 -0
  83. package/src/components/JhScene/JhScene.stories.js +317 -0
  84. package/src/components/JhScene/JhScene.vue +376 -0
  85. package/src/components/JhStatisticCard/JhStatisticCard.md +363 -0
  86. package/src/components/JhStatisticCard/JhStatisticCard.stories.js +847 -0
  87. package/src/components/JhStatisticCard/JhStatisticCard.vue +459 -0
  88. package/src/components/JhStepsForm/JhStepsForm.md +666 -0
  89. package/src/components/JhStepsForm/JhStepsForm.stories.js +1224 -0
  90. package/src/components/JhStepsForm/JhStepsForm.vue +749 -0
  91. package/src/components/JhTable/JhTable.md +730 -0
  92. package/src/components/JhTable/JhTable.stories.js +1444 -0
  93. package/src/components/JhTable/JhTable.vue +2298 -0
  94. package/src/components/JhTableAttachment/JhTableAttachment.md +70 -0
  95. package/src/components/JhTableAttachment/JhTableAttachment.stories.js +198 -0
  96. package/src/components/JhTableAttachment/JhTableAttachment.vue +264 -0
  97. package/src/components/JhToast/JhToast.md +67 -0
  98. package/src/components/JhToast/JhToast.stories.js +386 -0
  99. package/src/components/JhToast/JhToast.vue +239 -0
  100. package/src/components/JhTreeSelect/JhTreeSelect.md +82 -0
  101. package/src/components/JhTreeSelect/JhTreeSelect.stories.js +391 -0
  102. package/src/components/JhTreeSelect/JhTreeSelect.vue +727 -0
  103. package/src/components/JhWaterMark/JhWaterMark.md +190 -0
  104. package/src/components/JhWaterMark/JhWaterMark.stories.js +675 -0
  105. package/src/components/JhWaterMark/JhWaterMark.vue +351 -0
  106. package/src/components/README.md +52 -0
  107. package/src/index.js +135 -0
  108. package/src/style/globalCSSJHV4.css +348 -0
  109. package/src/style/globalCSSVuetifyV4.css +637 -0
  110. package/src/style/storybook.css +4 -0
  111. package/src/tailwind.css +3 -0
  112. package/src/utils/vuetify.js +31 -0
@@ -0,0 +1,387 @@
1
+ <template>
2
+ <v-app>
3
+ <!-- 使用 JhMenu 组件作为顶部导航 -->
4
+ <jh-menu
5
+ :app-title="title"
6
+ :menu-list="formattedMenuData"
7
+ :right-menu-list="rightMenuList"
8
+ :avatar-menu-list="formattedAvatarMenuList"
9
+ :user-info="userInfo"
10
+ :show-avatar="showAvatar"
11
+ :active-menu-index="currentMenuIndex"
12
+ :active-second-menu-id="currentSecondMenuId"
13
+ @menu-click="handleMenuClick"
14
+ @logout="handleLogout"
15
+ >
16
+ <template v-slot:title>
17
+ <slot name="logo">
18
+ <div class="d-flex align-center">
19
+ <v-icon v-if="logo" color="primary" class="mr-2">{{ logo }}</v-icon>
20
+ <span class="text-h6 font-weight-bold primary--text">{{ title }}</span>
21
+ </div>
22
+ </slot>
23
+ </template>
24
+ </jh-menu>
25
+
26
+
27
+ <!-- 主内容区域 -->
28
+ <v-main class="jh-layout-main">
29
+
30
+ <!-- 内容区域 -->
31
+ <div class="jh-layout-content" :style="{ backgroundColor: contentBackground }">
32
+ <slot></slot>
33
+ </div>
34
+
35
+ </v-main>
36
+
37
+ <!-- 设置抽屉 -->
38
+ <v-navigation-drawer
39
+ v-if="showSettings"
40
+ v-model="settingsDrawer"
41
+ app
42
+ right
43
+ temporary
44
+ width="320"
45
+ class="jh-layout-settings"
46
+ >
47
+ <v-toolbar flat color="primary" dark>
48
+ <v-toolbar-title>布局设置</v-toolbar-title>
49
+ <v-spacer></v-spacer>
50
+ <v-btn icon @click="settingsDrawer = false">
51
+ <v-icon>mdi-close</v-icon>
52
+ </v-btn>
53
+ </v-toolbar>
54
+
55
+ <v-list>
56
+ <!-- 内容背景色 -->
57
+ <v-list-item>
58
+ <v-list-item-content>
59
+ <v-list-item-title class="font-weight-bold mb-2">内容背景色</v-list-item-title>
60
+ <v-text-field
61
+ v-model="internalContentBackground"
62
+ dense
63
+ outlined
64
+ hide-details
65
+ placeholder="#f5f5f5"
66
+ >
67
+ <template v-slot:prepend-inner>
68
+ <div
69
+ :style="{ backgroundColor: internalContentBackground, width: '24px', height: '24px', borderRadius: '4px', border: '1px solid #ddd' }"
70
+ ></div>
71
+ </template>
72
+ </v-text-field>
73
+ </v-list-item-content>
74
+ </v-list-item>
75
+
76
+ <v-divider></v-divider>
77
+
78
+ <!-- 功能开关 -->
79
+ <v-list-item>
80
+ <v-list-item-content>
81
+ <v-list-item-title class="font-weight-bold mb-2">功能开关</v-list-item-title>
82
+ <v-switch
83
+ v-model="internalShowAvatar"
84
+ label="显示用户头像"
85
+ dense
86
+ hide-details
87
+ class="mt-2"
88
+ ></v-switch>
89
+ </v-list-item-content>
90
+ </v-list-item>
91
+
92
+ <v-divider></v-divider>
93
+
94
+ <!-- 快速预设 -->
95
+ <v-list-item>
96
+ <v-list-item-content>
97
+ <v-list-item-title class="font-weight-bold mb-3">快速预设</v-list-item-title>
98
+ <v-btn
99
+ block
100
+ outlined
101
+ small
102
+ class="mb-2"
103
+ @click="applyPreset('default')"
104
+ >
105
+ <v-icon left small>mdi-palette</v-icon>
106
+ 默认主题
107
+ </v-btn>
108
+ <v-btn
109
+ block
110
+ outlined
111
+ small
112
+ class="mb-2"
113
+ @click="applyPreset('dark')"
114
+ >
115
+ <v-icon left small>mdi-weather-night</v-icon>
116
+ 暗色主题
117
+ </v-btn>
118
+ <v-btn
119
+ block
120
+ outlined
121
+ small
122
+ @click="applyPreset('compact')"
123
+ >
124
+ <v-icon left small>mdi-arrow-collapse-vertical</v-icon>
125
+ 紧凑模式
126
+ </v-btn>
127
+ </v-list-item-content>
128
+ </v-list-item>
129
+
130
+ <v-divider></v-divider>
131
+
132
+ <!-- 重置按钮 -->
133
+ <v-list-item>
134
+ <v-list-item-content>
135
+ <v-btn
136
+ block
137
+ color="error"
138
+ outlined
139
+ @click="resetSettings"
140
+ >
141
+ <v-icon left>mdi-restore</v-icon>
142
+ 重置为默认
143
+ </v-btn>
144
+ </v-list-item-content>
145
+ </v-list-item>
146
+ </v-list>
147
+ </v-navigation-drawer>
148
+
149
+ <!-- 设置按钮 -->
150
+ <v-btn
151
+ v-if="showSettings"
152
+ fab
153
+ fixed
154
+ right
155
+ bottom
156
+ color="primary"
157
+ @click="settingsDrawer = true"
158
+ class="jh-layout-settings-btn"
159
+ elevation="4"
160
+ >
161
+ <v-icon>mdi-cog</v-icon>
162
+ </v-btn>
163
+ </v-app>
164
+ </template>
165
+
166
+ <script>
167
+ import JhMenu from '../JhMenu/JhMenu.vue';
168
+
169
+ export default {
170
+ name: 'JhLayout',
171
+ components: {
172
+ JhMenu
173
+ },
174
+ props: {
175
+ // 应用标题
176
+ title: {
177
+ type: String,
178
+ default: 'JianghuJS'
179
+ },
180
+ // Logo 图标
181
+ logo: {
182
+ type: String,
183
+ default: ''
184
+ },
185
+ // 菜单数据
186
+ menuData: {
187
+ type: Array,
188
+ default: () => []
189
+ },
190
+ // 右侧菜单列表
191
+ rightMenuList: {
192
+ type: Array,
193
+ default: () => []
194
+ },
195
+ // 当前路由路径
196
+ currentPath: {
197
+ type: String,
198
+ default: ''
199
+ },
200
+ // 内容区域背景色
201
+ contentBackground: {
202
+ type: String,
203
+ default: '#f5f5f5'
204
+ },
205
+ // 是否显示用户头像
206
+ showAvatar: {
207
+ type: Boolean,
208
+ default: true
209
+ },
210
+ // 用户信息
211
+ userInfo: {
212
+ type: Object,
213
+ default: () => ({
214
+ username: 'Guest',
215
+ userId: '',
216
+ roles: []
217
+ })
218
+ },
219
+ // 用户菜单列表
220
+ avatarMenuList: {
221
+ type: Array,
222
+ default: () => []
223
+ },
224
+ // 是否显示设置
225
+ showSettings: {
226
+ type: Boolean,
227
+ default: false
228
+ }
229
+ },
230
+ data() {
231
+ return {
232
+ settingsDrawer: false,
233
+ currentMenuIndex: -1,
234
+ currentSecondMenuId: null,
235
+ // 内部状态(用于设置面板)
236
+ internalContentBackground: this.contentBackground,
237
+ internalShowAvatar: this.showAvatar
238
+ };
239
+ },
240
+ computed: {
241
+ // 格式化菜单数据(将 name 转换为 title,path 转换为 id)
242
+ formattedMenuData() {
243
+ return this.formatMenuItems(this.menuData);
244
+ },
245
+ // 格式化用户菜单数据
246
+ formattedAvatarMenuList() {
247
+ return this.avatarMenuList.map(item => ({
248
+ ...item,
249
+ title: item.name || item.title,
250
+ id: item.path || item.id
251
+ }));
252
+ }
253
+ },
254
+ watch: {
255
+ // 监听设置变化并触发事件
256
+ internalContentBackground(val) {
257
+ this.$emit('update:contentBackground', val);
258
+ },
259
+ internalShowAvatar(val) {
260
+ this.$emit('update:showAvatar', val);
261
+ },
262
+ // 监听当前路径变化,更新激活菜单
263
+ currentPath: {
264
+ handler(newPath) {
265
+ this.updateActiveMenu(newPath);
266
+ },
267
+ immediate: true
268
+ }
269
+ },
270
+ methods: {
271
+ // 格式化菜单项
272
+ formatMenuItems(items) {
273
+ return items.map(item => ({
274
+ ...item,
275
+ title: item.name || item.title,
276
+ id: item.path || item.id,
277
+ children: item.children ? this.formatMenuItems(item.children) : undefined
278
+ }));
279
+ },
280
+ // 更新激活菜单
281
+ updateActiveMenu(path) {
282
+ if (!path) return;
283
+
284
+ // 查找匹配的菜单项
285
+ const findMenu = (items, targetPath, parentIndex = -1) => {
286
+ for (let i = 0; i < items.length; i++) {
287
+ const item = items[i];
288
+ const currentIndex = parentIndex === -1 ? i : parentIndex;
289
+
290
+ if (item.path === targetPath) {
291
+ this.currentMenuIndex = currentIndex;
292
+ this.currentSecondMenuId = item.id || item.path;
293
+ return true;
294
+ }
295
+
296
+ if (item.children) {
297
+ if (findMenu(item.children, targetPath, currentIndex)) {
298
+ return true;
299
+ }
300
+ }
301
+ }
302
+ return false;
303
+ };
304
+
305
+ findMenu(this.menuData, path);
306
+ },
307
+ // 菜单点击
308
+ handleMenuClick(menu, index) {
309
+ if (index !== undefined) {
310
+ this.currentMenuIndex = index;
311
+ }
312
+ if (menu.id) {
313
+ this.currentSecondMenuId = menu.id;
314
+ }
315
+ this.$emit('menu-click', menu);
316
+ },
317
+ // 退出登录
318
+ handleLogout() {
319
+ this.$emit('logout');
320
+ },
321
+ // 应用预设主题
322
+ applyPreset(preset) {
323
+ switch (preset) {
324
+ case 'default':
325
+ this.internalContentBackground = '#f5f5f5';
326
+ this.internalShowAvatar = true;
327
+ break;
328
+ case 'dark':
329
+ this.internalContentBackground = '#1e1e1e';
330
+ this.internalShowAvatar = true;
331
+ break;
332
+ case 'compact':
333
+ this.internalContentBackground = '#ffffff';
334
+ this.internalShowAvatar = true;
335
+ break;
336
+ }
337
+ },
338
+ // 重置设置
339
+ resetSettings() {
340
+ this.internalContentBackground = '#f5f5f5';
341
+ this.internalShowAvatar = true;
342
+ }
343
+ }
344
+ };
345
+ </script>
346
+
347
+ <style scoped>
348
+ .jh-layout-main {
349
+ min-height: 100vh;
350
+ }
351
+
352
+ .jh-layout-content {
353
+ min-height: calc(100vh - 52px);
354
+ transition: background-color 0.3s;
355
+ }
356
+
357
+ .jh-layout-settings-btn {
358
+ bottom: 24px !important;
359
+ z-index: 999;
360
+ }
361
+
362
+ .jh-layout-settings-btn:hover {
363
+ transform: rotate(90deg);
364
+ transition: transform 0.3s;
365
+ }
366
+
367
+ /* 设置抽屉样式优化 */
368
+ .jh-layout-settings >>> .v-list-item {
369
+ padding: 12px 16px;
370
+ }
371
+
372
+ .jh-layout-settings >>> .v-list-item__content {
373
+ padding: 0;
374
+ }
375
+
376
+ /* 响应式调整 */
377
+ @media (max-width: 600px) {
378
+ .jh-layout-content {
379
+ min-height: calc(100vh - 52px);
380
+ }
381
+
382
+ .jh-layout-settings-btn {
383
+ bottom: 16px !important;
384
+ right: 16px !important;
385
+ }
386
+ }
387
+ </style>