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,54 @@
1
+ # JhJsonEditor - JSON 可视化编辑器
2
+
3
+ JhJsonEditor 封装 JSONEditor 库,支持 Tree、Code 等多种视图,适用于复杂配置、数据调试场景。
4
+
5
+ ## 功能特性
6
+
7
+ - 🌲 **多模式切换**:支持 tree、code、form、text、view 等模式
8
+ - 🪄 **格式化能力**:输入字符串会自动尝试 `JSON.parse` 并在编辑器中格式化展示
9
+ - 📂 **展开控制**:`expandedOnStart` 搭配 tree/view 模式自动展开节点
10
+ - 🚨 **错误提示**:实时捕获解析错误并通过 `has-error` 通知外部
11
+ - 📏 **高度自定义**:`height` 属性可根据所在页面灵活设置
12
+
13
+ ## 基础用法
14
+
15
+ ```vue
16
+ <template>
17
+ <jh-json-editor
18
+ v-model="jsonValue"
19
+ mode="tree"
20
+ :expanded-on-start="true"
21
+ height="600px"
22
+ @has-error="handleError"
23
+ />
24
+ </template>
25
+ ```
26
+
27
+ ## API
28
+
29
+ ### Props
30
+
31
+ | 参数 | 说明 | 类型 | 默认值 |
32
+ | --- | --- | --- | --- |
33
+ | value | 双向绑定的 JSON 数据(对象或字符串) | string \| number \| object \| array | `{}` |
34
+ | expandedOnStart | 是否在 tree/view 模式自动展开全部节点 | boolean | false |
35
+ | mode | 默认模式 | string | `code` |
36
+ | modes | 可切换的模式数组 | string[] | `[tree, code, form, text, view]` |
37
+ | height | 编辑器容器高度 | string | `calc(100vh - 240px)` |
38
+
39
+ ### Events
40
+
41
+ | 事件名 | 说明 | 回调参数 |
42
+ | --- | --- | --- |
43
+ | input | `v-model` 更新事件 | (value: any) |
44
+ | has-error | JSON 解析错误状态 | (hasError: boolean) |
45
+
46
+ ### Slots
47
+
48
+ 组件无插槽。
49
+
50
+ ## 使用建议
51
+
52
+ - 在页面中引入 JSONEditor 静态资源(JS/CSS),否则组件会提示未加载
53
+ - 如果需要强制输出字符串,可在外部 watch `value` 并手动 `JSON.stringify`
54
+ - 当编辑大数据时建议设置合适的高度并启用 `expandedOnStart=false` 以提升性能
@@ -0,0 +1,157 @@
1
+ import JhJsonEditor from './JhJsonEditor.vue';
2
+
3
+ export default {
4
+ title: '基础组件/JhJsonEditor - JSON编辑器',
5
+ component: JhJsonEditor,
6
+ tags: ['autodocs'],
7
+ argTypes: {
8
+ value: {
9
+ control: 'object',
10
+ description: 'JSON 数据值,可以是字符串、对象或数组',
11
+ },
12
+ mode: {
13
+ control: 'select',
14
+ options: ['tree', 'code', 'form', 'text', 'view'],
15
+ description: '编辑器模式',
16
+ },
17
+ modes: {
18
+ control: 'object',
19
+ description: '可用的编辑器模式列表',
20
+ },
21
+ expandedOnStart: {
22
+ control: 'boolean',
23
+ description: '是否在启动时展开所有节点',
24
+ },
25
+ height: {
26
+ control: 'text',
27
+ description: '编辑器高度',
28
+ },
29
+ // 定义事件处理器
30
+ onInput: { action: 'input' },
31
+ onHasError: { action: 'has-error' },
32
+ },
33
+ parameters: {
34
+ docs: {
35
+ description: {
36
+ component: `
37
+
38
+ 基于 JSONEditor 的可视化 JSON 编辑器组件。
39
+
40
+ ## 使用前提
41
+
42
+ 需要在 HTML 中引入 JSONEditor 库:
43
+
44
+ \`\`\`html
45
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsoneditor@9.10.0/dist/jsoneditor.min.css">
46
+ <script src="https://cdn.jsdelivr.net/npm/jsoneditor@9.10.0/dist/jsoneditor.min.js"></script>
47
+ \`\`\`
48
+
49
+ ## 功能特性
50
+
51
+ - 支持多种编辑模式:树形、代码、表单、文本、预览
52
+ - 实时验证 JSON 格式
53
+ - 支持展开/折叠节点
54
+ - 支持搜索和过滤
55
+ - 自定义主题色
56
+
57
+ ## 事件
58
+
59
+ - \`@input\` - 内容变化时触发,返回更新后的 JSON 值
60
+ - \`@has-error\` - JSON 格式验证状态变化时触发,返回布尔值
61
+ `,
62
+ },
63
+ },
64
+ },
65
+ };
66
+
67
+ export const 基础示例 = {
68
+ args: {
69
+ value: {
70
+ name: 'JianghuJS',
71
+ version: '1.0.0',
72
+ features: ['Vue 2', 'Vuetify 2', 'Storybook'],
73
+ config: {
74
+ theme: 'light',
75
+ language: 'zh-CN',
76
+ },
77
+ },
78
+ mode: 'code',
79
+ modes: ['tree', 'code', 'form', 'text', 'view'],
80
+ expandedOnStart: false,
81
+ height: '400px',
82
+ },
83
+ };
84
+
85
+ export const 代码模式 = {
86
+ args: {
87
+ value: {
88
+ users: [
89
+ { id: 1, name: '张三', age: 25 },
90
+ { id: 2, name: '李四', age: 30 },
91
+ ],
92
+ total: 2,
93
+ },
94
+ mode: 'code',
95
+ modes: ['tree', 'code', 'form', 'text', 'view'],
96
+ expandedOnStart: false,
97
+ height: '400px',
98
+ },
99
+ };
100
+
101
+ export const 预览模式 = {
102
+ args: {
103
+ value: {
104
+ title: '只读预览模式',
105
+ description: '此模式下不可编辑',
106
+ data: {
107
+ readonly: true,
108
+ },
109
+ },
110
+ mode: 'view',
111
+ modes: ['view'],
112
+ expandedOnStart: true,
113
+ height: '400px',
114
+ },
115
+ };
116
+
117
+ export const 字符串值 = {
118
+ args: {
119
+ value: '{"message": "从字符串解析的 JSON", "timestamp": "2025-01-19"}',
120
+ mode: 'code',
121
+ modes: ['tree', 'code', 'form', 'text', 'view'],
122
+ expandedOnStart: true,
123
+ height: '400px',
124
+ },
125
+ };
126
+
127
+ export const 数组值 = {
128
+ args: {
129
+ value: [
130
+ { id: 1, name: '组件1', type: 'input' },
131
+ { id: 2, name: '组件2', type: 'select' },
132
+ { id: 3, name: '组件3', type: 'checkbox' },
133
+ ],
134
+ mode: 'code',
135
+ modes: ['tree', 'code', 'form', 'text', 'view'],
136
+ expandedOnStart: true,
137
+ height: '400px',
138
+ },
139
+ };
140
+
141
+ export const 初始展开 = {
142
+ args: {
143
+ value: {
144
+ level1: {
145
+ level2: {
146
+ level3: {
147
+ data: 'nested value',
148
+ },
149
+ },
150
+ },
151
+ },
152
+ mode: 'code',
153
+ modes: ['tree', 'code', 'form', 'text', 'view'],
154
+ expandedOnStart: true,
155
+ height: '400px',
156
+ },
157
+ };
@@ -0,0 +1,178 @@
1
+ <template>
2
+ <v-app>
3
+ <v-container fluid class="pa-0">
4
+ <div>
5
+ <div class="jsoneditor-vue" :style="{height}"></div>
6
+ </div>
7
+ </v-container>
8
+ </v-app>
9
+ </template>
10
+
11
+
12
+ <script>
13
+ export default {
14
+ name: 'JhJsonEditor',
15
+ props: {
16
+ // 编辑器绑定的 JSON 数据,可以是字符串或对象
17
+ value: {
18
+ type: [String, Number, Object, Array],
19
+ default: () => ({})
20
+ },
21
+ // 初始化时是否展开所有节点
22
+ expandedOnStart: {
23
+ type: Boolean,
24
+ default: false
25
+ },
26
+ // 默认模式 tree | code | form | text | view
27
+ mode: {
28
+ type: String,
29
+ default: "code"
30
+ },
31
+ // 可切换的模式集合
32
+ modes: {
33
+ type: Array,
34
+ default: function () {
35
+ return ["tree", "code", "form", "text", "view"];
36
+ }
37
+ },
38
+ // 编辑器容器高度
39
+ height: {
40
+ type: String,
41
+ default: 'calc(100vh - 240px)'
42
+ },
43
+ },
44
+ watch: {
45
+ value: {
46
+ immediate: true,
47
+ async handler(val) {
48
+ if (!this.internalChange) {
49
+ await this.setEditor();
50
+
51
+ this.error = false;
52
+ this.expandAll();
53
+ }
54
+ },
55
+ deep: true
56
+ }
57
+ },
58
+ data() {
59
+ return {
60
+ editor: null,
61
+ error: false,
62
+ internalChange: false,
63
+ expandedModes: ["tree", "view", "form"],
64
+ };
65
+ },
66
+ computed: {
67
+ valueType() {
68
+ return typeof this.value;
69
+ },
70
+ formatValue: {
71
+ get() {
72
+ // 如果值是字符串,并且值不为空,则返回JSON.parse(this.value)
73
+ if (this.valueType === "string" && this.value) {
74
+ try {
75
+ return JSON.parse(this.value);
76
+ } catch (e) {
77
+ return this.value;
78
+ }
79
+ }
80
+ return this.value;
81
+ },
82
+ set(val) {
83
+ if (this.valueType === "string" || !this.value) {
84
+ this.value = JSON.stringify(val);
85
+ } else {
86
+ this.value = val;
87
+ }
88
+ }
89
+ },
90
+ },
91
+ mounted() {
92
+ this.$emit("has-error", false);
93
+ // 延迟初始化,等待 JSONEditor 库加载
94
+ if (window.JSONEditor) {
95
+ this.init();
96
+ } else {
97
+ console.warn('JSONEditor is not loaded. Please include JSONEditor library.');
98
+ }
99
+ },
100
+ beforeDestroy() {
101
+ if (this.editor) {
102
+ this.editor.destroy();
103
+ }
104
+ },
105
+ methods: {
106
+ init() {
107
+ let _this = this;
108
+
109
+ let options = {
110
+ mode: this.mode,
111
+ modes: this.modes,
112
+ themeColor: "#4caf50",
113
+ onChange() {
114
+ try {
115
+ let json = _this.editor.get();
116
+ _this.formatValue = json;
117
+ _this.error = false;
118
+ _this.$emit("has-error", false);
119
+ _this.internalChange = true;
120
+ _this.$emit("input", _this.value);
121
+ _this.$nextTick(function () {
122
+ _this.internalChange = false;
123
+ });
124
+ } catch (e) {
125
+ _this.error = true;
126
+ _this.$emit("has-error", true);
127
+ }
128
+ },
129
+ onModeChange() {
130
+ _this.expandAll();
131
+ }
132
+ };
133
+
134
+ if (window.JSONEditor) {
135
+ this.editor = new window.JSONEditor(
136
+ _this.$el.querySelector(".jsoneditor-vue"),
137
+ options,
138
+ _this.formatValue
139
+ );
140
+ }
141
+ },
142
+ expandAll() {
143
+ if (
144
+ this.expandedOnStart &&
145
+ this.editor &&
146
+ this.expandedModes.includes(this.editor.getMode())
147
+ ) {
148
+ this.editor.expandAll();
149
+ }
150
+ },
151
+
152
+ async setEditor() {
153
+ if (this.editor) this.editor.set(this.formatValue);
154
+ }
155
+ }
156
+ };
157
+ </script>
158
+
159
+ <style scoped>
160
+ :deep(.jsoneditor-menu a.jsoneditor-poweredBy) {
161
+ display: none !important;
162
+ }
163
+ :deep(.jsoneditor-menu) {
164
+ background-color: #4caf50 !important;
165
+ border-bottom: 1px solid #4caf50 !important;
166
+ }
167
+ :deep(.jsoneditor) {
168
+ border: thin solid #4caf50 !important;
169
+ }
170
+ :deep(.jsoneditor-modal .pico-modal-header) {
171
+ background: #4caf50 !important;
172
+ }
173
+ :deep(.jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc),
174
+ :deep(.jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc) {
175
+ background: #4caf50 !important;
176
+ border-color: #4caf50 !important;
177
+ }
178
+ </style>