@veltra/desktop 1.1.24 → 1.1.26

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 (250) hide show
  1. package/dist/components/action/action-group.vue.d.ts +2 -2
  2. package/dist/components/action/action.js.map +1 -1
  3. package/dist/components/action/action.vue.d.ts +1 -1
  4. package/dist/components/badge/badge.js.map +1 -1
  5. package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
  6. package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
  7. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  8. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  9. package/dist/components/button/button-group.js.map +1 -1
  10. package/dist/components/button/button.js.map +1 -1
  11. package/dist/components/calendar/calendar.js.map +1 -1
  12. package/dist/components/card/card-action.js.map +1 -1
  13. package/dist/components/card/card-content.js.map +1 -1
  14. package/dist/components/card/card-cover.js.map +1 -1
  15. package/dist/components/card/card.js.map +1 -1
  16. package/dist/components/cascade/cascade-panel-item.js.map +1 -1
  17. package/dist/components/cascade/cascade.js.map +1 -1
  18. package/dist/components/cascade/cascade.vue.d.ts +1 -1
  19. package/dist/components/check-tag/check-tag.js.map +1 -1
  20. package/dist/components/checkbox/checkbox-button.js.map +1 -1
  21. package/dist/components/checkbox/checkbox.js.map +1 -1
  22. package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
  23. package/dist/components/code-editor/code-editor.js.map +1 -1
  24. package/dist/components/collapse/collapse-item.js.map +1 -1
  25. package/dist/components/collapse/collapse.js.map +1 -1
  26. package/dist/components/condition-editor/components/condition-row.js.map +1 -1
  27. package/dist/components/condition-editor/condition-editor.js.map +1 -1
  28. package/dist/components/context-menu/context-menu-item.js.map +1 -1
  29. package/dist/components/context-menu/context-menu.js.map +1 -1
  30. package/dist/components/date-panel/date-panel.js.map +1 -1
  31. package/dist/components/date-panel/headers/day.js.map +1 -1
  32. package/dist/components/date-panel/headers/month.js.map +1 -1
  33. package/dist/components/date-panel/headers/year.js.map +1 -1
  34. package/dist/components/date-panel/panels/day.js.map +1 -1
  35. package/dist/components/date-panel/panels/month.js.map +1 -1
  36. package/dist/components/date-panel/panels/year.js.map +1 -1
  37. package/dist/components/date-picker/date-picker.js.map +1 -1
  38. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  39. package/dist/components/dialog/dialog.js.map +1 -1
  40. package/dist/components/drawer/drawer.js.map +1 -1
  41. package/dist/components/empty/empty.js.map +1 -1
  42. package/dist/components/expression-editor/components/path-preview.js.map +1 -1
  43. package/dist/components/expression-editor/components/variable-picker.js.map +1 -1
  44. package/dist/components/expression-editor/expression-editor.js.map +1 -1
  45. package/dist/components/file-picker/file-picker.js.map +1 -1
  46. package/dist/components/file-viewer/file-viewer.js.map +1 -1
  47. package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -1
  48. package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -1
  49. package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -1
  50. package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
  51. package/dist/components/float-button/float-button.js.map +1 -1
  52. package/dist/components/form/dynamic-form-model.d.ts +7 -5
  53. package/dist/components/form/dynamic-form-model.js +31 -12
  54. package/dist/components/form/dynamic-form-model.js.map +1 -1
  55. package/dist/components/form/form-model.d.ts +8 -8
  56. package/dist/components/form/form-model.js +17 -3
  57. package/dist/components/form/form-model.js.map +1 -1
  58. package/dist/components/form/form.js.map +1 -1
  59. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  60. package/dist/components/form/helper.d.ts +6 -1
  61. package/dist/components/form/helper.js +7 -1
  62. package/dist/components/form/helper.js.map +1 -1
  63. package/dist/components/form/index.d.ts +2 -2
  64. package/dist/components/gantt-chart/gantt-chart.js.map +1 -1
  65. package/dist/components/grid/grid-item.js.map +1 -1
  66. package/dist/components/grid/grid.js.map +1 -1
  67. package/dist/components/grid-input/grid-input.js.map +1 -1
  68. package/dist/components/group-input/group-input.js.map +1 -1
  69. package/dist/components/icon/icon.js.map +1 -1
  70. package/dist/components/index.d.ts +1 -1
  71. package/dist/components/index.js +2 -1
  72. package/dist/components/input/input.js.map +1 -1
  73. package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/layout/layout-resizer.js.map +1 -1
  75. package/dist/components/layout/layout.js.map +1 -1
  76. package/dist/components/list/list-item.js.map +1 -1
  77. package/dist/components/list/list.js.map +1 -1
  78. package/dist/components/loading/loading.js.map +1 -1
  79. package/dist/components/menu/menu-icon.js.map +1 -1
  80. package/dist/components/menu/menu-sub-collapsed.js.map +1 -1
  81. package/dist/components/menu/menu.js.map +1 -1
  82. package/dist/components/message/message-box.js.map +1 -1
  83. package/dist/components/message/message.js.map +1 -1
  84. package/dist/components/message-confirm/message-confirm.js.map +1 -1
  85. package/dist/components/multi-select/multi-select-option.js.map +1 -1
  86. package/dist/components/multi-select/multi-select.vue.d.ts +1 -1
  87. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +1 -1
  88. package/dist/components/notification/notification.js.map +1 -1
  89. package/dist/components/notification/notification.vue.d.ts +2 -2
  90. package/dist/components/number/number.js.map +1 -1
  91. package/dist/components/number-input/number-input.js.map +1 -1
  92. package/dist/components/number-range-input/number-range-input.js.map +1 -1
  93. package/dist/components/paginator/paginator.js.map +1 -1
  94. package/dist/components/palette/palette-alpha.js.map +1 -1
  95. package/dist/components/palette/palette-color-switch.js.map +1 -1
  96. package/dist/components/palette/palette-hue.js.map +1 -1
  97. package/dist/components/palette/palette-sv.js.map +1 -1
  98. package/dist/components/palette/palette.js.map +1 -1
  99. package/dist/components/pop-confirm/pop-confirm.js.map +1 -1
  100. package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
  101. package/dist/components/progress/progress.js.map +1 -1
  102. package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
  103. package/dist/components/radio/radio.js.map +1 -1
  104. package/dist/components/radio-group/radio-group.js.map +1 -1
  105. package/dist/components/scroll/scroll-bar.js.map +1 -1
  106. package/dist/components/scroll/scroll.js.map +1 -1
  107. package/dist/components/slider/slider-thumb.js.map +1 -1
  108. package/dist/components/slider/slider.js.map +1 -1
  109. package/dist/components/steps/steps.js.map +1 -1
  110. package/dist/components/switch/switch.js.map +1 -1
  111. package/dist/components/table/table-body.js.map +1 -1
  112. package/dist/components/table/table-cell.js.map +1 -1
  113. package/dist/components/table/table-foot.js.map +1 -1
  114. package/dist/components/table-editor/table-editor.js.map +1 -1
  115. package/dist/components/tabs/tabs-horizontal.js.map +1 -1
  116. package/dist/components/tabs/tabs-horizontal.vue.d.ts +4 -4
  117. package/dist/components/tabs/tabs-vertical.js.map +1 -1
  118. package/dist/components/tabs/tabs-vertical.vue.d.ts +3 -3
  119. package/dist/components/tabs/tabs.js.map +1 -1
  120. package/dist/components/tabs/tabs.vue.d.ts +4 -4
  121. package/dist/components/tag/tag.js.map +1 -1
  122. package/dist/components/text/text.js.map +1 -1
  123. package/dist/components/textarea/textarea.js.map +1 -1
  124. package/dist/components/textarea/textarea.vue.d.ts +1 -1
  125. package/dist/components/theme/theme.js.map +1 -1
  126. package/dist/components/tip/tip.js.map +1 -1
  127. package/dist/components/tip/tip.vue.d.ts +1 -1
  128. package/dist/components/tree/tree-node.js.map +1 -1
  129. package/dist/components/tree/tree.js.map +1 -1
  130. package/dist/components/tree-select/tree-select.vue.d.ts +1 -1
  131. package/dist/components/watermark/watermark.js.map +1 -1
  132. package/dist/index.d.ts +4 -4
  133. package/dist/index.js +2 -2
  134. package/dist/types/form.d.ts +12 -9
  135. package/dist/types/index.d.ts +2 -2
  136. package/package.json +6 -6
  137. package/src/components/action/action.vue +1 -4
  138. package/src/components/badge/badge.vue +3 -9
  139. package/src/components/batch-edit/batch-edit-form.vue +1 -5
  140. package/src/components/batch-edit/batch-edit-list.vue +2 -6
  141. package/src/components/batch-edit/batch-edit.vue +2 -12
  142. package/src/components/breadcrumb/breadcrumb.vue +4 -13
  143. package/src/components/button/button-group.vue +2 -6
  144. package/src/components/button/button.vue +3 -9
  145. package/src/components/calendar/calendar.vue +1 -3
  146. package/src/components/card/card-action.vue +1 -3
  147. package/src/components/card/card-content.vue +1 -6
  148. package/src/components/card/card-cover.vue +1 -3
  149. package/src/components/card/card.vue +2 -6
  150. package/src/components/cascade/cascade-panel-item.vue +2 -8
  151. package/src/components/cascade/cascade.vue +5 -37
  152. package/src/components/check-tag/check-tag.vue +1 -3
  153. package/src/components/checkbox/checkbox-button.vue +2 -6
  154. package/src/components/checkbox/checkbox.vue +1 -3
  155. package/src/components/checkbox-group/checkbox-group.vue +1 -3
  156. package/src/components/code-editor/code-editor.vue +4 -12
  157. package/src/components/collapse/collapse-item.vue +1 -3
  158. package/src/components/collapse/collapse.vue +2 -8
  159. package/src/components/condition-editor/components/condition-row.vue +2 -8
  160. package/src/components/condition-editor/condition-editor.vue +2 -6
  161. package/src/components/context-menu/context-menu-item.vue +3 -10
  162. package/src/components/context-menu/context-menu.vue +5 -17
  163. package/src/components/date-panel/date-panel.vue +3 -11
  164. package/src/components/date-panel/headers/day.vue +1 -3
  165. package/src/components/date-panel/headers/month.vue +1 -3
  166. package/src/components/date-panel/headers/year.vue +1 -3
  167. package/src/components/date-panel/panels/day.vue +1 -4
  168. package/src/components/date-panel/panels/month.vue +1 -3
  169. package/src/components/date-panel/panels/year.vue +1 -3
  170. package/src/components/date-picker/date-picker.vue +1 -3
  171. package/src/components/date-range-picker/date-range-picker.vue +1 -3
  172. package/src/components/dialog/dialog.vue +7 -24
  173. package/src/components/drawer/drawer.vue +3 -11
  174. package/src/components/empty/empty.vue +2 -7
  175. package/src/components/expression-editor/components/path-preview.vue +2 -6
  176. package/src/components/expression-editor/components/variable-picker.vue +1 -3
  177. package/src/components/expression-editor/expression-editor.vue +2 -6
  178. package/src/components/expression-editor/style.scss +1 -1
  179. package/src/components/file-picker/file-picker.vue +2 -7
  180. package/src/components/file-viewer/file-viewer.vue +4 -22
  181. package/src/components/file-viewer/previewers/pdf-previewer.vue +1 -5
  182. package/src/components/file-viewer/previewers/pdf-viewport-scroll.vue +1 -7
  183. package/src/components/file-viewer/previewers/pdf-zoom-bridge.vue +2 -7
  184. package/src/components/file-viewer/previewers/sheet-previewer.vue +4 -10
  185. package/src/components/float-button/float-button.vue +1 -3
  186. package/src/components/form/__test__/form-model.test.ts +190 -0
  187. package/src/components/form/dynamic-form-model.ts +47 -19
  188. package/src/components/form/form-model.ts +40 -28
  189. package/src/components/form/form.vue +3 -13
  190. package/src/components/form/helper.ts +9 -0
  191. package/src/components/form/index.ts +2 -1
  192. package/src/components/gantt-chart/gantt-chart.vue +1 -3
  193. package/src/components/grid/grid-item.vue +3 -9
  194. package/src/components/grid/grid.vue +5 -18
  195. package/src/components/grid-input/grid-input.vue +2 -6
  196. package/src/components/group-input/group-input.vue +2 -7
  197. package/src/components/icon/icon.vue +2 -6
  198. package/src/components/input/input.vue +2 -6
  199. package/src/components/layout/layout-resizer.vue +1 -3
  200. package/src/components/layout/layout.vue +3 -9
  201. package/src/components/list/list-item.vue +1 -3
  202. package/src/components/list/list.vue +2 -6
  203. package/src/components/loading/loading.vue +3 -9
  204. package/src/components/menu/menu-icon.vue +2 -6
  205. package/src/components/menu/menu-sub-collapsed.vue +2 -8
  206. package/src/components/menu/menu.vue +3 -9
  207. package/src/components/menu/style.scss +1 -1
  208. package/src/components/message/message-box.vue +3 -10
  209. package/src/components/message/message.vue +3 -9
  210. package/src/components/message-confirm/message-confirm.vue +2 -6
  211. package/src/components/multi-select/multi-select-option.vue +3 -9
  212. package/src/components/notification/notification.vue +3 -11
  213. package/src/components/number/number.vue +4 -14
  214. package/src/components/number-input/number-input.vue +7 -36
  215. package/src/components/number-range-input/number-range-input.vue +4 -17
  216. package/src/components/paginator/paginator.vue +7 -22
  217. package/src/components/palette/palette-alpha.vue +2 -6
  218. package/src/components/palette/palette-color-switch.vue +1 -3
  219. package/src/components/palette/palette-hue.vue +2 -6
  220. package/src/components/palette/palette-sv.vue +5 -17
  221. package/src/components/palette/palette.vue +2 -12
  222. package/src/components/pop-confirm/pop-confirm.vue +2 -6
  223. package/src/components/progress/progress.vue +2 -7
  224. package/src/components/progress-nodes/progress-nodes.vue +2 -7
  225. package/src/components/radio/radio.vue +2 -6
  226. package/src/components/radio-group/radio-group.vue +1 -3
  227. package/src/components/scroll/scroll-bar.vue +5 -17
  228. package/src/components/scroll/scroll.vue +5 -16
  229. package/src/components/slider/slider-thumb.vue +4 -12
  230. package/src/components/slider/slider.vue +3 -14
  231. package/src/components/steps/steps.vue +3 -10
  232. package/src/components/switch/switch.vue +2 -7
  233. package/src/components/table/table-body.vue +2 -8
  234. package/src/components/table/table-cell.vue +2 -7
  235. package/src/components/table/table-foot.vue +2 -9
  236. package/src/components/table-editor/table-editor.vue +1 -3
  237. package/src/components/tabs/tabs-horizontal.vue +2 -6
  238. package/src/components/tabs/tabs-vertical.vue +1 -3
  239. package/src/components/tabs/tabs.vue +1 -3
  240. package/src/components/tag/tag.vue +2 -6
  241. package/src/components/text/text.vue +3 -9
  242. package/src/components/textarea/textarea.vue +1 -3
  243. package/src/components/theme/group-item.vue +1 -3
  244. package/src/components/theme/group.vue +1 -3
  245. package/src/components/theme/theme.vue +6 -26
  246. package/src/components/tip/tip.vue +1 -3
  247. package/src/components/tree/tree-node.vue +1 -3
  248. package/src/components/tree/tree.vue +7 -30
  249. package/src/components/watermark/watermark.vue +4 -15
  250. package/src/types/form.ts +29 -11
@@ -2,6 +2,16 @@ import { isReactive, reactive, shallowReactive, watch } from "vue";
2
2
  import { Validator } from "@veltra/utils";
3
3
  import { o } from "@cat-kit/core";
4
4
  //#region src/components/form/dynamic-form-model.ts
5
+ function flattenFields(fields, prefix = "") {
6
+ const result = {};
7
+ for (const key in fields) {
8
+ const item = fields[key];
9
+ const fullPath = prefix ? `${prefix}.${key}` : key;
10
+ if (item && typeof item === "object" && "__isNested" in item && item.__isNested) Object.assign(result, flattenFields(item.fields, fullPath));
11
+ else result[fullPath] = item;
12
+ }
13
+ return result;
14
+ }
5
15
  /**
6
16
  * 动态表单模型
7
17
  */
@@ -21,6 +31,7 @@ var DynamicFormModel = class {
21
31
  }
22
32
  /** 表单规则 */
23
33
  fields = shallowReactive({});
34
+ flatFields;
24
35
  validator;
25
36
  /**
26
37
  * 不同表单对应的key
@@ -37,8 +48,14 @@ var DynamicFormModel = class {
37
48
  get allKeys() {
38
49
  return this._allKeys;
39
50
  }
51
+ updateFlatFields() {
52
+ for (const key in this.flatFields) delete this.flatFields[key];
53
+ const flatted = flattenFields(this.fields);
54
+ Object.assign(this.flatFields, flatted);
55
+ this.getAllKeys();
56
+ }
40
57
  getAllKeys() {
41
- this._allKeys = Object.keys(this.fields);
58
+ this._allKeys = Object.keys(this.flatFields);
42
59
  }
43
60
  /** 初始数据 */
44
61
  initialData = {};
@@ -47,9 +64,9 @@ var DynamicFormModel = class {
47
64
  */
48
65
  oldData = {};
49
66
  constructor(fields) {
67
+ this.flatFields = shallowReactive({});
68
+ this.validator = new Validator(this.flatFields);
50
69
  this.append(fields ?? {});
51
- this.validator = new Validator(this.fields);
52
- this.getAllKeys();
53
70
  this.watchData();
54
71
  }
55
72
  watchData() {
@@ -70,7 +87,7 @@ var DynamicFormModel = class {
70
87
  });
71
88
  }
72
89
  append(fields) {
73
- for (const key in fields) this.add(key, fields[key] ?? {});
90
+ for (const key in fields) this.add(key, fields[key]);
74
91
  }
75
92
  /**
76
93
  * 添加字段
@@ -79,13 +96,15 @@ var DynamicFormModel = class {
79
96
  */
80
97
  add(field, item) {
81
98
  this.fields[field] = item;
82
- const { value } = item;
83
- const v = typeof value === "function" ? value() : value;
84
- /** 这是有bug的 */
85
- if (v !== void 0) this.initialData[field] = JSON.parse(JSON.stringify(v));
86
- o(this.data).set(field, v);
87
- o(this.oldData).set(field, v);
88
- this.getAllKeys();
99
+ const flatItem = flattenFields({ [field]: item });
100
+ for (const key in flatItem) {
101
+ const { value } = flatItem[key];
102
+ const v = typeof value === "function" ? value() : value;
103
+ if (v !== void 0) o(this.initialData).set(key, JSON.parse(JSON.stringify(v)));
104
+ o(this.data).set(key, v);
105
+ o(this.oldData).set(key, v);
106
+ }
107
+ this.updateFlatFields();
89
108
  }
90
109
  /**
91
110
  * 移除字段
@@ -93,7 +112,7 @@ var DynamicFormModel = class {
93
112
  */
94
113
  delete(field) {
95
114
  delete this.fields[field];
96
- this.getAllKeys();
115
+ this.updateFlatFields();
97
116
  }
98
117
  /**
99
118
  * 监听值变更
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-form-model.js","names":[],"sources":["../../../src/components/form/dynamic-form-model.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { Validator } from '@veltra/utils'\nimport { isReactive, reactive, shallowReactive, watch } from 'vue'\n\nimport type { FormModelItem, DataSettingConfig } from '../../types'\n\n/**\n * 动态表单模型\n */\nexport class DynamicFormModel {\n /** 表单数据 */\n private _data: Record<string, any> = reactive({})\n\n set data(v: Record<string, any>) {\n if (!isReactive(v)) {\n console.error(`data不是一个响应式对象`)\n return\n }\n this._data = v\n this.watchData()\n }\n\n get data() {\n return this._data\n }\n\n /** 表单规则 */\n readonly fields: Record<string, FormModelItem> = shallowReactive(\n {} as Record<string, FormModelItem>\n )\n\n private validator: Validator\n\n /**\n * 不同表单对应的key\n */\n formKeys: Map<number, string[]> = new Map()\n\n readonly errors: Map<string, string[] | undefined> = shallowReactive(new Map())\n\n /**\n * 是否在表单值更新时校验\n */\n private validateOnFieldChange = true\n\n private modelChangeCallback: Set<(fields: string, val: any) => void> = new Set()\n\n private _allKeys: string[] = []\n\n /** 所有的键 */\n get allKeys(): string[] {\n return this._allKeys\n }\n\n private getAllKeys(): void {\n this._allKeys = Object.keys(this.fields)\n }\n\n /** 初始数据 */\n readonly initialData: Record<string, any> = {}\n\n /**\n * 变更前的值\n */\n private readonly oldData: Record<string, any> = {}\n\n constructor(fields?: Record<string, FormModelItem>) {\n this.append(fields ?? {})\n this.validator = new Validator(this.fields)\n this.getAllKeys()\n this.watchData()\n }\n\n private watchData(): void {\n const { oldData } = this\n watch(this.data, (data) => {\n let changedKeys: string[] = []\n\n this.allKeys.forEach((key) => {\n const oldVal = o(oldData).get(key)\n const newVal = o(data).get(key)\n if (oldVal !== newVal) {\n this.modelChangeCallback.forEach((cb) => cb(key, newVal))\n changedKeys.push(key)\n o(oldData).set(key, newVal)\n }\n })\n\n if (this.validateOnFieldChange) {\n this.validate(changedKeys)\n } else {\n this.validateOnFieldChange = true\n }\n })\n }\n\n append(fields: Record<string, FormModelItem>): void {\n for (const key in fields) {\n this.add(key, fields[key] ?? {})\n }\n }\n\n /**\n * 添加字段\n * @param field 字段\n * @param item 字段配置项\n */\n add(field: string, item: FormModelItem): void {\n this.fields[field] = item\n const { value } = item\n const v = typeof value === 'function' ? value() : value\n /** 这是有bug的 */\n if (v !== undefined) {\n this.initialData[field] = JSON.parse(JSON.stringify(v))\n }\n o(this.data).set(field, v)\n o(this.oldData).set(field, v)\n this.getAllKeys()\n }\n\n /**\n * 移除字段\n * @param field 字段\n */\n delete(field: string): void {\n delete this.fields[field]\n this.getAllKeys()\n }\n\n /**\n * 监听值变更\n * @param cb 回调\n */\n onChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.add(cb)\n }\n\n offChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.delete(cb)\n }\n\n async validate(fields?: string | string[]): Promise<boolean> {\n const { errors, validator, data } = this\n\n const results = await validator.validate(data, this.getValidateFields(fields))\n\n // 设置错误提示\n if (!fields) {\n errors.clear()\n for (const field in results) {\n errors.set(field, results[field])\n }\n } else {\n ~(Array.isArray(fields) ? fields : [fields]).forEach((field) => {\n const errs = results[field]\n if (errs?.length) {\n errors.set(field, errs)\n } else {\n errors.delete(field)\n }\n })\n }\n\n return errors.size === 0\n }\n\n private getValidateFields(fields?: string | string[]) {\n if (!fields) {\n if (this.formKeys.size) {\n let _fields: string[] = []\n this.formKeys.forEach((fields) => {\n _fields = _fields.concat(fields)\n })\n return _fields\n } else {\n return this.allKeys\n }\n }\n\n if (!Array.isArray(fields)) {\n return [fields]\n }\n return fields\n }\n\n /**\n * 重置数据\n * @param fields 需要重置的字段\n */\n resetData(keys?: string | string[]): void {\n if (typeof keys === 'string') {\n keys = [keys]\n } else if (Array.isArray(keys)) {\n } else {\n keys = this.allKeys\n }\n\n this.clearValidate()\n\n this.validateOnFieldChange = false\n\n keys.forEach((field) => {\n o(this.data).set(field as string, o(this.initialData).get(field as string))\n })\n }\n\n /**\n * 设置值\n * @param formData 表单值\n * @param options 配置\n */\n setData(formData: Record<string, any>, config?: DataSettingConfig): void {\n const { validate = true } = config || {}\n\n if (!validate) {\n this.validateOnFieldChange = false\n }\n\n this.allKeys.forEach((key) => {\n const value = o(formData).get(key)\n if (value !== undefined) {\n o(this.data).set(key, value)\n }\n })\n }\n\n clearValidate(): void {\n this.errors.clear()\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dynamic-form-model.js","names":[],"sources":["../../../src/components/form/dynamic-form-model.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { Validator } from '@veltra/utils'\nimport { isReactive, reactive, shallowReactive, watch } from 'vue'\n\nimport type { FormModelField, FormModelItem, DataSettingConfig } from '../../types'\n\nfunction flattenFields(fields: Record<string, any>, prefix = ''): Record<string, FormModelItem> {\n const result: Record<string, FormModelItem> = {}\n for (const key in fields) {\n const item = fields[key]\n const fullPath = prefix ? `${prefix}.${key}` : key\n if (item && typeof item === 'object' && '__isNested' in item && item.__isNested) {\n Object.assign(result, flattenFields((item as any).fields, fullPath))\n } else {\n result[fullPath] = item\n }\n }\n return result\n}\n\n/**\n * 动态表单模型\n */\nexport class DynamicFormModel {\n /** 表单数据 */\n private _data: Record<string, any> = reactive({})\n\n set data(v: Record<string, any>) {\n if (!isReactive(v)) {\n console.error(`data不是一个响应式对象`)\n return\n }\n this._data = v\n this.watchData()\n }\n\n get data() {\n return this._data\n }\n\n /** 表单规则 */\n readonly fields: Record<string, FormModelField> = shallowReactive(\n {} as Record<string, FormModelField>\n )\n\n private flatFields: Record<string, FormModelItem>\n\n private validator: Validator\n\n /**\n * 不同表单对应的key\n */\n formKeys: Map<number, string[]> = new Map()\n\n readonly errors: Map<string, string[] | undefined> = shallowReactive(new Map())\n\n /**\n * 是否在表单值更新时校验\n */\n private validateOnFieldChange = true\n\n private modelChangeCallback: Set<(fields: string, val: any) => void> = new Set()\n\n private _allKeys: string[] = []\n\n /** 所有的键 */\n get allKeys(): string[] {\n return this._allKeys\n }\n\n private updateFlatFields(): void {\n for (const key in this.flatFields) {\n delete this.flatFields[key]\n }\n const flatted = flattenFields(this.fields)\n Object.assign(this.flatFields, flatted)\n this.getAllKeys()\n }\n\n private getAllKeys(): void {\n this._allKeys = Object.keys(this.flatFields)\n }\n\n /** 初始数据 */\n readonly initialData: Record<string, any> = {}\n\n /**\n * 变更前的值\n */\n private readonly oldData: Record<string, any> = {}\n\n constructor(fields?: Record<string, FormModelField>) {\n this.flatFields = shallowReactive({} as Record<string, FormModelItem>)\n this.validator = new Validator(this.flatFields)\n this.append(fields ?? {})\n this.watchData()\n }\n\n private watchData(): void {\n const { oldData } = this\n watch(this.data, (data) => {\n let changedKeys: string[] = []\n\n this.allKeys.forEach((key) => {\n const oldVal = o(oldData).get(key)\n const newVal = o(data).get(key)\n if (oldVal !== newVal) {\n this.modelChangeCallback.forEach((cb) => cb(key, newVal))\n changedKeys.push(key)\n o(oldData).set(key, newVal)\n }\n })\n\n if (this.validateOnFieldChange) {\n this.validate(changedKeys)\n } else {\n this.validateOnFieldChange = true\n }\n })\n }\n\n append(fields: Record<string, FormModelField>): void {\n for (const key in fields) {\n this.add(key, fields[key]!)\n }\n }\n\n /**\n * 添加字段\n * @param field 字段\n * @param item 字段配置项\n */\n add(field: string, item: FormModelField): void {\n this.fields[field] = item\n const flatItem = flattenFields({ [field]: item })\n for (const key in flatItem) {\n const fieldItem = flatItem[key]!\n const { value } = fieldItem\n const v = typeof value === 'function' ? value() : value\n if (v !== undefined) {\n o(this.initialData).set(key, JSON.parse(JSON.stringify(v)))\n }\n o(this.data).set(key, v)\n o(this.oldData).set(key, v)\n }\n this.updateFlatFields()\n }\n\n /**\n * 移除字段\n * @param field 字段\n */\n delete(field: string): void {\n delete this.fields[field]\n this.updateFlatFields()\n }\n\n /**\n * 监听值变更\n * @param cb 回调\n */\n onChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.add(cb)\n }\n\n offChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.delete(cb)\n }\n\n async validate(fields?: string | string[]): Promise<boolean> {\n const { errors, validator, data } = this\n\n const results = await validator.validate(data, this.getValidateFields(fields))\n\n // 设置错误提示\n if (!fields) {\n errors.clear()\n for (const field in results) {\n errors.set(field, results[field])\n }\n } else {\n ~(Array.isArray(fields) ? fields : [fields]).forEach((field) => {\n const errs = results[field]\n if (errs?.length) {\n errors.set(field, errs)\n } else {\n errors.delete(field)\n }\n })\n }\n\n return errors.size === 0\n }\n\n private getValidateFields(fields?: string | string[]) {\n if (!fields) {\n if (this.formKeys.size) {\n let _fields: string[] = []\n this.formKeys.forEach((fields) => {\n _fields = _fields.concat(fields)\n })\n return _fields\n } else {\n return this.allKeys\n }\n }\n\n if (!Array.isArray(fields)) {\n return [fields]\n }\n return fields\n }\n\n /**\n * 重置数据\n * @param fields 需要重置的字段\n */\n resetData(keys?: string | string[]): void {\n if (typeof keys === 'string') {\n keys = [keys]\n } else if (Array.isArray(keys)) {\n } else {\n keys = this.allKeys\n }\n\n this.clearValidate()\n\n this.validateOnFieldChange = false\n\n keys.forEach((field) => {\n o(this.data).set(field as string, o(this.initialData).get(field as string))\n })\n }\n\n /**\n * 设置值\n * @param formData 表单值\n * @param options 配置\n */\n setData(formData: Record<string, any>, config?: DataSettingConfig): void {\n const { validate = true } = config || {}\n\n if (!validate) {\n this.validateOnFieldChange = false\n }\n\n this.allKeys.forEach((key) => {\n const value = o(formData).get(key)\n if (value !== undefined) {\n o(this.data).set(key, value)\n }\n })\n }\n\n clearValidate(): void {\n this.errors.clear()\n }\n}\n"],"mappings":";;;;AAMA,SAAS,cAAc,QAA6B,SAAS,IAAmC;CAC9F,MAAM,SAAwC,EAAE;CAChD,KAAK,MAAM,OAAO,QAAQ;EACxB,MAAM,OAAO,OAAO;EACpB,MAAM,WAAW,SAAS,GAAG,OAAO,GAAG,QAAQ;EAC/C,IAAI,QAAQ,OAAO,SAAS,YAAY,gBAAgB,QAAQ,KAAK,YACnE,OAAO,OAAO,QAAQ,cAAe,KAAa,QAAQ,SAAS,CAAC;OAEpE,OAAO,YAAY;;CAGvB,OAAO;;;;;AAMT,IAAa,mBAAb,MAA8B;;CAE5B,QAAqC,SAAS,EAAE,CAAC;CAEjD,IAAI,KAAK,GAAwB;EAC/B,IAAI,CAAC,WAAW,EAAE,EAAE;GAClB,QAAQ,MAAM,gBAAgB;GAC9B;;EAEF,KAAK,QAAQ;EACb,KAAK,WAAW;;CAGlB,IAAI,OAAO;EACT,OAAO,KAAK;;;CAId,SAAkD,gBAChD,EAAE,CACH;CAED;CAEA;;;;CAKA,2BAAkC,IAAI,KAAK;CAE3C,SAAqD,gCAAgB,IAAI,KAAK,CAAC;;;;CAK/E,wBAAgC;CAEhC,sCAAuE,IAAI,KAAK;CAEhF,WAA6B,EAAE;;CAG/B,IAAI,UAAoB;EACtB,OAAO,KAAK;;CAGd,mBAAiC;EAC/B,KAAK,MAAM,OAAO,KAAK,YACrB,OAAO,KAAK,WAAW;EAEzB,MAAM,UAAU,cAAc,KAAK,OAAO;EAC1C,OAAO,OAAO,KAAK,YAAY,QAAQ;EACvC,KAAK,YAAY;;CAGnB,aAA2B;EACzB,KAAK,WAAW,OAAO,KAAK,KAAK,WAAW;;;CAI9C,cAA4C,EAAE;;;;CAK9C,UAAgD,EAAE;CAElD,YAAY,QAAyC;EACnD,KAAK,aAAa,gBAAgB,EAAE,CAAkC;EACtE,KAAK,YAAY,IAAI,UAAU,KAAK,WAAW;EAC/C,KAAK,OAAO,UAAU,EAAE,CAAC;EACzB,KAAK,WAAW;;CAGlB,YAA0B;EACxB,MAAM,EAAE,YAAY;EACpB,MAAM,KAAK,OAAO,SAAS;GACzB,IAAI,cAAwB,EAAE;GAE9B,KAAK,QAAQ,SAAS,QAAQ;IAC5B,MAAM,SAAS,EAAE,QAAQ,CAAC,IAAI,IAAI;IAClC,MAAM,SAAS,EAAE,KAAK,CAAC,IAAI,IAAI;IAC/B,IAAI,WAAW,QAAQ;KACrB,KAAK,oBAAoB,SAAS,OAAO,GAAG,KAAK,OAAO,CAAC;KACzD,YAAY,KAAK,IAAI;KACrB,EAAE,QAAQ,CAAC,IAAI,KAAK,OAAO;;KAE7B;GAEF,IAAI,KAAK,uBACP,KAAK,SAAS,YAAY;QAE1B,KAAK,wBAAwB;IAE/B;;CAGJ,OAAO,QAA8C;EACnD,KAAK,MAAM,OAAO,QAChB,KAAK,IAAI,KAAK,OAAO,KAAM;;;;;;;CAS/B,IAAI,OAAe,MAA4B;EAC7C,KAAK,OAAO,SAAS;EACrB,MAAM,WAAW,cAAc,GAAG,QAAQ,MAAM,CAAC;EACjD,KAAK,MAAM,OAAO,UAAU;GAE1B,MAAM,EAAE,UADU,SAAS;GAE3B,MAAM,IAAI,OAAO,UAAU,aAAa,OAAO,GAAG;GAClD,IAAI,MAAM,KAAA,GACR,EAAE,KAAK,YAAY,CAAC,IAAI,KAAK,KAAK,MAAM,KAAK,UAAU,EAAE,CAAC,CAAC;GAE7D,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,EAAE;GACxB,EAAE,KAAK,QAAQ,CAAC,IAAI,KAAK,EAAE;;EAE7B,KAAK,kBAAkB;;;;;;CAOzB,OAAO,OAAqB;EAC1B,OAAO,KAAK,OAAO;EACnB,KAAK,kBAAkB;;;;;;CAOzB,SAAS,IAA6C;EACpD,KAAK,oBAAoB,IAAI,GAAG;;CAGlC,UAAU,IAA6C;EACrD,KAAK,oBAAoB,OAAO,GAAG;;CAGrC,MAAM,SAAS,QAA8C;EAC3D,MAAM,EAAE,QAAQ,WAAW,SAAS;EAEpC,MAAM,UAAU,MAAM,UAAU,SAAS,MAAM,KAAK,kBAAkB,OAAO,CAAC;EAG9E,IAAI,CAAC,QAAQ;GACX,OAAO,OAAO;GACd,KAAK,MAAM,SAAS,SAClB,OAAO,IAAI,OAAO,QAAQ,OAAO;SAGnC,EAAE,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,SAAS,UAAU;GAC9D,MAAM,OAAO,QAAQ;GACrB,IAAI,MAAM,QACR,OAAO,IAAI,OAAO,KAAK;QAEvB,OAAO,OAAO,MAAM;IAEtB;EAGJ,OAAO,OAAO,SAAS;;CAGzB,kBAA0B,QAA4B;EACpD,IAAI,CAAC,QACH,IAAI,KAAK,SAAS,MAAM;GACtB,IAAI,UAAoB,EAAE;GAC1B,KAAK,SAAS,SAAS,WAAW;IAChC,UAAU,QAAQ,OAAO,OAAO;KAChC;GACF,OAAO;SAEP,OAAO,KAAK;EAIhB,IAAI,CAAC,MAAM,QAAQ,OAAO,EACxB,OAAO,CAAC,OAAO;EAEjB,OAAO;;;;;;CAOT,UAAU,MAAgC;EACxC,IAAI,OAAO,SAAS,UAClB,OAAO,CAAC,KAAK;OACR,IAAI,MAAM,QAAQ,KAAK,EAAE,QAE9B,OAAO,KAAK;EAGd,KAAK,eAAe;EAEpB,KAAK,wBAAwB;EAE7B,KAAK,SAAS,UAAU;GACtB,EAAE,KAAK,KAAK,CAAC,IAAI,OAAiB,EAAE,KAAK,YAAY,CAAC,IAAI,MAAgB,CAAC;IAC3E;;;;;;;CAQJ,QAAQ,UAA+B,QAAkC;EACvE,MAAM,EAAE,WAAW,SAAS,UAAU,EAAE;EAExC,IAAI,CAAC,UACH,KAAK,wBAAwB;EAG/B,KAAK,QAAQ,SAAS,QAAQ;GAC5B,MAAM,QAAQ,EAAE,SAAS,CAAC,IAAI,IAAI;GAClC,IAAI,UAAU,KAAA,GACZ,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,MAAM;IAE9B;;CAGJ,gBAAsB;EACpB,KAAK,OAAO,OAAO"}
@@ -1,11 +1,11 @@
1
- import { DataSettingConfig, FormModelItem, IFormModel, ModelData } from "../../types/form.js";
1
+ import { AllKeys, DataSettingConfig, IFormModel, ModelData } from "../../types/form.js";
2
2
  import { Reactive } from "vue";
3
3
 
4
4
  //#region src/components/form/form-model.d.ts
5
5
  /**
6
6
  * 表单模型
7
7
  */
8
- declare class FormModel<Fields extends Record<string, FormModelItem> = Record<string, FormModelItem>> implements IFormModel<Fields> {
8
+ declare class FormModel<Fields extends Record<string, any> = Record<string, any>> implements IFormModel<Fields> {
9
9
  /** 表单数据 */
10
10
  data: ModelData<Fields>;
11
11
  /** 表单规则 */
@@ -17,10 +17,10 @@ declare class FormModel<Fields extends Record<string, FormModelItem> = Record<st
17
17
  * @description
18
18
  * 这个值会在表单组件渲染时由表单设置,因为只有真正渲染的组件才应该被校验
19
19
  */
20
- formKeys: Map<number, (keyof Fields)[]>;
20
+ formKeys: Map<number, AllKeys<Fields>[]>;
21
21
  /** 初始数据 */
22
22
  readonly initialData: ModelData<Fields>;
23
- readonly errors: Map<keyof Fields, string[] | undefined>;
23
+ readonly errors: Map<AllKeys<Fields>, string[] | undefined>;
24
24
  private validator;
25
25
  /**
26
26
  * 是否在表单值更新时校验
@@ -40,12 +40,12 @@ declare class FormModel<Fields extends Record<string, FormModelItem> = Record<st
40
40
  * @param fields 需要校验的字段, 不传则校验所有字段
41
41
  * @returns
42
42
  */
43
- validate(fields?: keyof Fields | (keyof Fields)[]): Promise<boolean>;
43
+ validate(fields?: AllKeys<Fields> | AllKeys<Fields>[]): Promise<boolean>;
44
44
  /**
45
45
  * 重置数据
46
46
  * @param fields 需要重置的字段
47
47
  */
48
- resetData(keys?: keyof Fields | (keyof Fields)[]): void;
48
+ resetData(keys?: AllKeys<Fields> | AllKeys<Fields>[]): void;
49
49
  /**
50
50
  * 设置值
51
51
  * @param formData 表单值
@@ -64,9 +64,9 @@ declare class FormModel<Fields extends Record<string, FormModelItem> = Record<st
64
64
  * 监听值变更
65
65
  * @param cb 回调
66
66
  */
67
- onChange(cb: (field: keyof Fields, val: any) => void): void;
67
+ onChange(cb: (field: AllKeys<Fields>, val: any) => void): void;
68
68
  /** 关闭监听值变更 */
69
- offChange(cb: (field: keyof Fields, val: any) => void): void;
69
+ offChange(cb: (field: AllKeys<Fields>, val: any) => void): void;
70
70
  }
71
71
  //#endregion
72
72
  export { FormModel };
@@ -3,6 +3,19 @@ import { Validator, middleProxy } from "@veltra/utils";
3
3
  import { o } from "@cat-kit/core";
4
4
  //#region src/components/form/form-model.ts
5
5
  /**
6
+ * 递归展平字段逻辑
7
+ */
8
+ function flattenFields(fields, prefix = "") {
9
+ const result = {};
10
+ for (const key in fields) {
11
+ const item = fields[key];
12
+ const fullPath = prefix ? `${prefix}.${key}` : key;
13
+ if (item && typeof item === "object" && "__isNested" in item && item.__isNested) Object.assign(result, flattenFields(item.fields, fullPath));
14
+ else result[fullPath] = item;
15
+ }
16
+ return result;
17
+ }
18
+ /**
6
19
  * 表单模型
7
20
  */
8
21
  var FormModel = class {
@@ -29,10 +42,11 @@ var FormModel = class {
29
42
  modelChangeCallback = /* @__PURE__ */ new Set();
30
43
  constructor(fields) {
31
44
  this.fields = fields;
45
+ const flatFields = flattenFields(fields);
32
46
  const rawData = {};
33
47
  const allKeys = [];
34
- for (const key in fields) {
35
- const fieldItem = fields[key];
48
+ for (const key in flatFields) {
49
+ const fieldItem = flatFields[key];
36
50
  allKeys.push(key);
37
51
  const { value } = fieldItem;
38
52
  let v = value;
@@ -47,7 +61,7 @@ var FormModel = class {
47
61
  this.allKeys = allKeys;
48
62
  this.initialData = JSON.parse(JSON.stringify(rawData));
49
63
  this.setProxyData(reactive(rawData));
50
- this.validator = new Validator(this.fields);
64
+ this.validator = new Validator(flatFields);
51
65
  return shallowReactive(this);
52
66
  }
53
67
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"form-model.js","names":[],"sources":["../../../src/components/form/form-model.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { middleProxy, Validator } from '@veltra/utils'\nimport { nextTick, reactive, shallowReactive, watch, type Reactive } from 'vue'\n\nimport type {\n FormModelItem,\n ModelData,\n ModelRules,\n DataSettingConfig,\n IFormModel\n} from '../../types'\n\n/**\n * 表单模型\n */\nexport class FormModel<\n Fields extends Record<string, FormModelItem> = Record<string, FormModelItem>\n> implements IFormModel<Fields> {\n /** 表单数据 */\n data!: ModelData<Fields>\n\n /** 表单规则 */\n readonly fields: Fields\n\n /** 所有的键 */\n readonly allKeys: string[]\n\n /**\n * 不同表单所需要校验的字段\n * @description\n * 这个值会在表单组件渲染时由表单设置,因为只有真正渲染的组件才应该被校验\n */\n formKeys: Map<number, (keyof Fields)[]> = new Map()\n\n /** 初始数据 */\n readonly initialData: ModelData<Fields>\n\n readonly errors: Map<keyof Fields, string[] | undefined> = shallowReactive(new Map())\n\n private validator: Validator<ModelRules<Fields>>\n\n /**\n * 是否在表单值更新时校验\n */\n private validateOnFieldChange = true\n\n private modelChangeCallback: Set<(fields: string, val: any) => void> = new Set()\n\n constructor(fields: Fields) {\n this.fields = fields\n const rawData = {} as ModelData<Fields>\n const allKeys: string[] = []\n\n for (const key in fields) {\n const fieldItem = fields[key]!\n allKeys.push(key)\n const { value } = fieldItem\n let v = value\n\n if (typeof value === 'function') {\n watch(value, (v) => {\n o(this.initialData).set(key, v)\n })\n v = value()\n }\n\n o(rawData).set(key, v)\n }\n\n this.allKeys = allKeys\n this.initialData = JSON.parse(JSON.stringify(rawData))\n\n this.setProxyData(reactive(rawData))\n\n this.validator = new Validator(this.fields)\n\n return shallowReactive(this)\n }\n\n /**\n * 设置响应式值, 替换掉原有的数据\n * @description 设置响应式值时,会自动监听值的变化,并进行校验\n * @param proxyData 响应式的值\n */\n setProxyData(proxyData: ModelData<Fields> | Reactive<ModelData<Fields>>): void {\n const data = middleProxy(proxyData, {\n set: (field, val) => {\n this.modelChangeCallback.forEach((cb) => cb(field, val))\n },\n\n changed: (fields) => {\n if (!this.validateOnFieldChange) {\n this.validateOnFieldChange = true\n return\n }\n this.validate(fields)\n }\n })\n\n this.data = data as ModelData<Fields>\n }\n\n private getValidateFields(fields?: keyof Fields | (keyof Fields)[]) {\n if (!fields) {\n if (this.formKeys.size) {\n let _fields: (keyof Fields)[] = []\n this.formKeys.forEach((fields) => {\n _fields = _fields.concat(fields)\n })\n return _fields\n } else {\n return this.allKeys\n }\n }\n\n if (!Array.isArray(fields)) {\n return [fields]\n }\n return fields\n }\n\n /**\n * 模型校验\n * @param fields 需要校验的字段, 不传则校验所有字段\n * @returns\n */\n async validate(fields?: keyof Fields | (keyof Fields)[]): Promise<boolean> {\n const { errors, validator, data } = this\n\n const results = await validator.validate(data, this.getValidateFields(fields))\n\n // 全量校验\n if (!fields) {\n errors.clear()\n\n for (const field in results) {\n errors.set(field, results[field])\n }\n }\n // 局部校验\n else {\n ~(Array.isArray(fields) ? fields : [fields]).forEach((field) => {\n const errs = results[field]\n if (errs?.length) {\n errors.set(field, errs)\n } else {\n errors.delete(field)\n }\n })\n }\n\n if (errors.size > 0) {\n if (!fields) {\n nextTick(() => {\n document.querySelector('.u-form-item.is-error')?.scrollIntoView({ block: 'nearest' })\n })\n }\n return Promise.reject(false)\n }\n\n return true\n }\n\n /**\n * 重置数据\n * @param fields 需要重置的字段\n */\n resetData(keys?: keyof Fields | (keyof Fields)[]): void {\n if (typeof keys === 'string') {\n keys = [keys]\n } else if (Array.isArray(keys)) {\n } else {\n keys = this.allKeys\n }\n\n this.clearValidate()\n\n this.validateOnFieldChange = false\n\n keys.forEach((field) => {\n o(this.data).set(field as string, o(this.initialData).get(field as string))\n })\n }\n\n /**\n * 设置值\n * @param formData 表单值\n * @param options 配置\n */\n setData(\n formData: Partial<ModelData<Fields> & Record<string, any>>,\n config?: DataSettingConfig\n ): FormModel<Fields> {\n const { validate = true } = config || {}\n\n if (!validate) {\n this.validateOnFieldChange = false\n }\n\n this.allKeys.forEach((key) => {\n const value = o(formData).get(key)\n if (value !== undefined) {\n o(this.data).set(key, value)\n }\n })\n\n return this\n }\n\n /**\n * 设置初始值\n * @description 初始值在重置数据和查看原始数据时会用到\n * @param data 初始值\n */\n setInitialData(data: Partial<ModelData<Fields>>): FormModel<Fields> {\n this.allKeys.forEach((key) => {\n o(this.initialData).set(key, o(data).get(key))\n })\n\n return this\n }\n\n /** 清除校验 */\n clearValidate(): void {\n this.errors.clear()\n }\n\n /**\n * 监听值变更\n * @param cb 回调\n */\n onChange(cb: (field: keyof Fields, val: any) => void): void {\n this.modelChangeCallback.add(cb)\n }\n\n /** 关闭监听值变更 */\n offChange(cb: (field: keyof Fields, val: any) => void): void {\n this.modelChangeCallback.delete(cb)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"form-model.js","names":[],"sources":["../../../src/components/form/form-model.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { middleProxy, Validator } from '@veltra/utils'\nimport { nextTick, reactive, shallowReactive, watch, type Reactive } from 'vue'\n\nimport type { ModelData, DataSettingConfig, IFormModel, AllKeys, FormModelItem } from '../../types'\n\n/**\n * 递归展平字段逻辑\n */\nfunction flattenFields(fields: Record<string, any>, prefix = ''): Record<string, FormModelItem> {\n const result: Record<string, FormModelItem> = {}\n for (const key in fields) {\n const item = fields[key]\n const fullPath = prefix ? `${prefix}.${key}` : key\n if (item && typeof item === 'object' && '__isNested' in item && item.__isNested) {\n Object.assign(result, flattenFields((item as any).fields, fullPath))\n } else {\n result[fullPath] = item\n }\n }\n return result\n}\n\n/**\n * 表单模型\n */\nexport class FormModel<\n Fields extends Record<string, any> = Record<string, any>\n> implements IFormModel<Fields> {\n /** 表单数据 */\n data!: ModelData<Fields>\n\n /** 表单规则 */\n readonly fields: Fields\n\n /** 所有的键 */\n readonly allKeys: string[]\n\n /**\n * 不同表单所需要校验的字段\n * @description\n * 这个值会在表单组件渲染时由表单设置,因为只有真正渲染的组件才应该被校验\n */\n formKeys: Map<number, AllKeys<Fields>[]> = new Map()\n\n /** 初始数据 */\n readonly initialData: ModelData<Fields>\n\n readonly errors: Map<AllKeys<Fields>, string[] | undefined> = shallowReactive(new Map())\n\n private validator: Validator<Record<string, FormModelItem>>\n\n /**\n * 是否在表单值更新时校验\n */\n private validateOnFieldChange = true\n\n private modelChangeCallback: Set<(fields: string, val: any) => void> = new Set()\n\n constructor(fields: Fields) {\n this.fields = fields\n const flatFields = flattenFields(fields)\n const rawData = {} as ModelData<Fields>\n const allKeys: string[] = []\n\n for (const key in flatFields) {\n const fieldItem = flatFields[key]!\n allKeys.push(key)\n const { value } = fieldItem\n let v = value\n\n if (typeof value === 'function') {\n watch(value, (v) => {\n o(this.initialData).set(key, v)\n })\n v = value()\n }\n\n o(rawData).set(key, v)\n }\n\n this.allKeys = allKeys\n this.initialData = JSON.parse(JSON.stringify(rawData))\n\n this.setProxyData(reactive(rawData))\n\n this.validator = new Validator(flatFields)\n\n return shallowReactive(this)\n }\n\n /**\n * 设置响应式值, 替换掉原有的数据\n * @description 设置响应式值时,会自动监听值的变化,并进行校验\n * @param proxyData 响应式的值\n */\n setProxyData(proxyData: ModelData<Fields> | Reactive<ModelData<Fields>>): void {\n const data = middleProxy(proxyData, {\n set: (field, val) => {\n this.modelChangeCallback.forEach((cb) => cb(field, val))\n },\n\n changed: (fields) => {\n if (!this.validateOnFieldChange) {\n this.validateOnFieldChange = true\n return\n }\n this.validate(fields as any)\n }\n })\n\n this.data = data as ModelData<Fields>\n }\n\n private getValidateFields(fields?: AllKeys<Fields> | AllKeys<Fields>[]) {\n if (!fields) {\n if (this.formKeys.size) {\n let _fields: AllKeys<Fields>[] = []\n this.formKeys.forEach((fields) => {\n _fields = _fields.concat(fields)\n })\n return _fields\n } else {\n return this.allKeys as AllKeys<Fields>[]\n }\n }\n\n if (!Array.isArray(fields)) {\n return [fields]\n }\n return fields\n }\n\n /**\n * 模型校验\n * @param fields 需要校验的字段, 不传则校验所有字段\n * @returns\n */\n async validate(fields?: AllKeys<Fields> | AllKeys<Fields>[]): Promise<boolean> {\n const { errors, validator, data } = this\n\n const results = await validator.validate(data, this.getValidateFields(fields) as any)\n\n // 全量校验\n if (!fields) {\n errors.clear()\n\n for (const field in results) {\n errors.set(field as any, results[field])\n }\n }\n // 局部校验\n else {\n ~(Array.isArray(fields) ? fields : [fields]).forEach((field) => {\n const errs = results[field as string]\n if (errs?.length) {\n errors.set(field, errs)\n } else {\n errors.delete(field)\n }\n })\n }\n\n if (errors.size > 0) {\n if (!fields) {\n nextTick(() => {\n document.querySelector('.u-form-item.is-error')?.scrollIntoView({ block: 'nearest' })\n })\n }\n return Promise.reject(false)\n }\n\n return true\n }\n\n /**\n * 重置数据\n * @param fields 需要重置的字段\n */\n resetData(keys?: AllKeys<Fields> | AllKeys<Fields>[]): void {\n if (typeof keys === 'string') {\n keys = [keys]\n } else if (Array.isArray(keys)) {\n } else {\n keys = this.allKeys as AllKeys<Fields>[]\n }\n\n this.clearValidate()\n\n this.validateOnFieldChange = false\n\n keys.forEach((field) => {\n o(this.data).set(field as string, o(this.initialData).get(field as string))\n })\n }\n\n /**\n * 设置值\n * @param formData 表单值\n * @param options 配置\n */\n setData(\n formData: Partial<ModelData<Fields> & Record<string, any>>,\n config?: DataSettingConfig\n ): FormModel<Fields> {\n const { validate = true } = config || {}\n\n if (!validate) {\n this.validateOnFieldChange = false\n }\n\n this.allKeys.forEach((key) => {\n const value = o(formData).get(key)\n if (value !== undefined) {\n o(this.data).set(key, value)\n }\n })\n\n return this\n }\n\n /**\n * 设置初始值\n * @description 初始值在重置数据和查看原始数据时会用到\n * @param data 初始值\n */\n setInitialData(data: Partial<ModelData<Fields>>): FormModel<Fields> {\n this.allKeys.forEach((key) => {\n o(this.initialData).set(key, o(data).get(key))\n })\n\n return this\n }\n\n /** 清除校验 */\n clearValidate(): void {\n this.errors.clear()\n }\n\n /**\n * 监听值变更\n * @param cb 回调\n */\n onChange(cb: (field: AllKeys<Fields>, val: any) => void): void {\n this.modelChangeCallback.add(cb as any)\n }\n\n /** 关闭监听值变更 */\n offChange(cb: (field: AllKeys<Fields>, val: any) => void): void {\n this.modelChangeCallback.delete(cb as any)\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"form.js","names":[],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"gridRef\"\n @submit.prevent\n :cols=\"cols || breakpointCols\"\n :class=\"[cls.b, bem.is('readonly', readonly)]\"\n >\n <template\n v-for=\"{ node, isFormItem, formItemProps, field, modelValue } of getSlotsNodes()\"\n :key=\"node.key\"\n >\n <component v-if=\"isFormItem || !field\" :is=\"node\" />\n\n <u-form-item v-else v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model?.data ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n\n <div :class=\"cls.e('data-before')\" v-if=\"showInitialNode(field)\">\n <i :class=\"cls.e('changed-tag')\">变更前:</i>\n\n <component :is=\"node\" readonly :model-value=\"o(model?.initialData ?? {}).get(field)\" />\n </div>\n </u-form-item>\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup generic=\"Model extends FormModel | DynamicFormModel\">\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { shallowRef, toRef } from 'vue'\n\nimport type { BreakCols, GridExposed, FormProps, _FormExposed } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport type { DynamicFormModel } from './dynamic-form-model'\nimport type { FormModel } from './form-model'\nimport { useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({\n name: 'Form'\n})\n\nconst props = defineProps<FormProps<Model>>()\n\ndefineSlots<{\n default(props: {\n /** 表单数据 */\n data: Model['data']\n /** 表单模型 */\n model: Model\n }): any\n}>()\n\nconst cls = bem('form')\n\nconst breakpointCols: BreakCols = {\n xs: 1,\n md: 2,\n lg: 3,\n xl: 4,\n default: 4\n}\n\nprovideFormContext(props)\n\nconst { getSlotsNodes } = useNodeInterceptor({ props })\n\nfunction handleUpdateValue(field: string, value: any) {\n const { model } = props\n if (!model) return\n o(model.data).set(field, value)\n}\n\nfunction showInitialNode(field: string) {\n const { data, initialData } = props.model || {}\n\n const currentValue = o(data ?? {}).get(field)\n const initialValue = o(initialData ?? {}).get(field)\n const notEqual = !(initialValue === currentValue || (!initialValue && !currentValue))\n\n return props.showInitialData && notEqual\n}\n\nconst gridRef = shallowRef<GridExposed>()\n\ndefineExpose<_FormExposed>({\n el: toRef(() => gridRef.value?.el)\n})\n</script>\n"],"mappings":""}
1
+ {"version":3,"file":"form.js","names":[],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"gridRef\"\n @submit.prevent\n :cols=\"cols || breakpointCols\"\n :class=\"[cls.b, bem.is('readonly', readonly)]\"\n >\n <template\n v-for=\"{ node, isFormItem, formItemProps, field, modelValue } of getSlotsNodes()\"\n :key=\"node.key\"\n >\n <component v-if=\"isFormItem || !field\" :is=\"node\" />\n\n <u-form-item v-else v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model?.data ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n\n <div :class=\"cls.e('data-before')\" v-if=\"showInitialNode(field)\">\n <i :class=\"cls.e('changed-tag')\">变更前:</i>\n\n <component :is=\"node\" readonly :model-value=\"o(model?.initialData ?? {}).get(field)\" />\n </div>\n </u-form-item>\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup generic=\"Model extends FormModel | DynamicFormModel\">\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { shallowRef, toRef } from 'vue'\n\nimport type { BreakCols, GridExposed, FormProps, _FormExposed } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport type { DynamicFormModel } from './dynamic-form-model'\nimport type { FormModel } from './form-model'\nimport { useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({ name: 'Form' })\n\nconst props = defineProps<FormProps<Model>>()\n\ndefineSlots<{\n default(props: {\n /** 表单数据 */\n data: Model['data']\n /** 表单模型 */\n model: Model\n }): any\n}>()\n\nconst cls = bem('form')\n\nconst breakpointCols: BreakCols = { xs: 1, md: 2, lg: 3, xl: 4, default: 4 }\n\nprovideFormContext(props)\n\nconst { getSlotsNodes } = useNodeInterceptor({ props })\n\nfunction handleUpdateValue(field: string, value: any) {\n const { model } = props\n if (!model) return\n o(model.data).set(field, value)\n}\n\nfunction showInitialNode(field: string) {\n const { data, initialData } = props.model || {}\n\n const currentValue = o(data ?? {}).get(field)\n const initialValue = o(initialData ?? {}).get(field)\n const notEqual = !(initialValue === currentValue || (!initialValue && !currentValue))\n\n return props.showInitialData && notEqual\n}\n\nconst gridRef = shallowRef<GridExposed>()\n\ndefineExpose<_FormExposed>({ el: toRef(() => gridRef.value?.el) })\n</script>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"form.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"gridRef\"\n @submit.prevent\n :cols=\"cols || breakpointCols\"\n :class=\"[cls.b, bem.is('readonly', readonly)]\"\n >\n <template\n v-for=\"{ node, isFormItem, formItemProps, field, modelValue } of getSlotsNodes()\"\n :key=\"node.key\"\n >\n <component v-if=\"isFormItem || !field\" :is=\"node\" />\n\n <u-form-item v-else v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model?.data ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n\n <div :class=\"cls.e('data-before')\" v-if=\"showInitialNode(field)\">\n <i :class=\"cls.e('changed-tag')\">变更前:</i>\n\n <component :is=\"node\" readonly :model-value=\"o(model?.initialData ?? {}).get(field)\" />\n </div>\n </u-form-item>\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup generic=\"Model extends FormModel | DynamicFormModel\">\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { shallowRef, toRef } from 'vue'\n\nimport type { BreakCols, GridExposed, FormProps, _FormExposed } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport type { DynamicFormModel } from './dynamic-form-model'\nimport type { FormModel } from './form-model'\nimport { useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({\n name: 'Form'\n})\n\nconst props = defineProps<FormProps<Model>>()\n\ndefineSlots<{\n default(props: {\n /** 表单数据 */\n data: Model['data']\n /** 表单模型 */\n model: Model\n }): any\n}>()\n\nconst cls = bem('form')\n\nconst breakpointCols: BreakCols = {\n xs: 1,\n md: 2,\n lg: 3,\n xl: 4,\n default: 4\n}\n\nprovideFormContext(props)\n\nconst { getSlotsNodes } = useNodeInterceptor({ props })\n\nfunction handleUpdateValue(field: string, value: any) {\n const { model } = props\n if (!model) return\n o(model.data).set(field, value)\n}\n\nfunction showInitialNode(field: string) {\n const { data, initialData } = props.model || {}\n\n const currentValue = o(data ?? {}).get(field)\n const initialValue = o(initialData ?? {}).get(field)\n const notEqual = !(initialValue === currentValue || (!initialValue && !currentValue))\n\n return props.showInitialData && notEqual\n}\n\nconst gridRef = shallowRef<GridExposed>()\n\ndefineExpose<_FormExposed>({\n el: toRef(() => gridRef.value?.el)\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAgDA,MAAM,QAAQ;EAWd,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,iBAA4B;GAChC,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,SAAS;GACX;EAEA,mBAAmB,MAAK;EAExB,MAAM,EAAE,kBAAkB,mBAAmB,EAAE,OAAO,CAAA;EAEtD,SAAS,kBAAkB,OAAe,OAAY;GACpD,MAAM,EAAE,UAAU;GAClB,IAAI,CAAC,OAAO;GACZ,EAAE,MAAM,KAAK,CAAC,IAAI,OAAO,MAAK;;EAGhC,SAAS,gBAAgB,OAAe;GACtC,MAAM,EAAE,MAAM,gBAAgB,MAAM,SAAS,EAAC;GAE9C,MAAM,eAAe,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,MAAK;GAC5C,MAAM,eAAe,EAAE,eAAe,EAAE,CAAC,CAAC,IAAI,MAAK;GACnD,MAAM,WAAW,EAAE,iBAAiB,gBAAiB,CAAC,gBAAgB,CAAC;GAEvE,OAAO,MAAM,mBAAmB;;EAGlC,MAAM,UAAU,YAAwB;EAExC,SAA2B,EACzB,IAAI,YAAY,QAAQ,OAAO,GAAE,EAClC,CAAA;;uBA5FC,YA2BS,MAAA,UAAA,EAAA;IA1BP,KAAI;aACA;IAAJ,KAAI;IACH,UAAM,OAAA,OAAA,OAAA,KAAA,oBAAP,IAAe,CAAA,UAAA,CAAA;IACd,MAAM,QAAA,QAAQ;IACd,OAAK,eAAA,CAAG,MAAA,IAAG,CAAC,GAAG,MAAA,IAAG,CAAC,GAAE,YAAa,QAAA,SAAQ,CAAA,CAAA;;2BAGwC,EAAA,UAAA,KAAA,EADnF,mBAmBW,UAAA,MAAA,WAlBwD,MAAA,cAAa,EAAA,GAAA,EAArE,MAAM,YAAY,eAAe,OAAO,iBAAU;6DACrD,KAAK,KAAA,EAAA,CAEM,cAAU,CAAK,SAAA,WAAA,EAAhC,YAAoD,wBAAR,KAAI,EAAA,EAAA,KAAA,GAAA,CAAA,KAAA,WAAA,EAEhD,YAYc,MAAA,kBAAA,EAZd,WAYc;;;QAZc,cAAa,EAAA;6BAKrC,EAAA,WAAA,EAJF,YAIE,wBAHK,KAAI,EAAA;OACR,eAAa,cAAc,MAAA,EAAC,CAAC,QAAA,OAAO,QAAI,EAAA,CAAA,CAAQ,IAAI,MAAK;OACzD,wBAAkB,WAAE,kBAAkB,OAAO,OAAM;4DAGb,gBAAgB,MAAK,IAAA,WAAA,EAA9D,mBAIM,OAAA;;OAJA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,cAAA,CAAA;UAChB,mBAAyC,KAAA,EAArC,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,cAAA,CAAA,EAAA,EAAiB,QAAI,EAAA,GAAA,WAAA,EAErC,YAAuF,wBAAvE,KAAI,EAAA;OAAE,UAAA;OAAU,eAAa,MAAA,EAAC,CAAC,QAAA,OAAO,eAAW,EAAA,CAAA,CAAQ,IAAI,MAAK"}
1
+ {"version":3,"file":"form.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"gridRef\"\n @submit.prevent\n :cols=\"cols || breakpointCols\"\n :class=\"[cls.b, bem.is('readonly', readonly)]\"\n >\n <template\n v-for=\"{ node, isFormItem, formItemProps, field, modelValue } of getSlotsNodes()\"\n :key=\"node.key\"\n >\n <component v-if=\"isFormItem || !field\" :is=\"node\" />\n\n <u-form-item v-else v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model?.data ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n\n <div :class=\"cls.e('data-before')\" v-if=\"showInitialNode(field)\">\n <i :class=\"cls.e('changed-tag')\">变更前:</i>\n\n <component :is=\"node\" readonly :model-value=\"o(model?.initialData ?? {}).get(field)\" />\n </div>\n </u-form-item>\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup generic=\"Model extends FormModel | DynamicFormModel\">\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { shallowRef, toRef } from 'vue'\n\nimport type { BreakCols, GridExposed, FormProps, _FormExposed } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport type { DynamicFormModel } from './dynamic-form-model'\nimport type { FormModel } from './form-model'\nimport { useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({ name: 'Form' })\n\nconst props = defineProps<FormProps<Model>>()\n\ndefineSlots<{\n default(props: {\n /** 表单数据 */\n data: Model['data']\n /** 表单模型 */\n model: Model\n }): any\n}>()\n\nconst cls = bem('form')\n\nconst breakpointCols: BreakCols = { xs: 1, md: 2, lg: 3, xl: 4, default: 4 }\n\nprovideFormContext(props)\n\nconst { getSlotsNodes } = useNodeInterceptor({ props })\n\nfunction handleUpdateValue(field: string, value: any) {\n const { model } = props\n if (!model) return\n o(model.data).set(field, value)\n}\n\nfunction showInitialNode(field: string) {\n const { data, initialData } = props.model || {}\n\n const currentValue = o(data ?? {}).get(field)\n const initialValue = o(initialData ?? {}).get(field)\n const notEqual = !(initialValue === currentValue || (!initialValue && !currentValue))\n\n return props.showInitialData && notEqual\n}\n\nconst gridRef = shallowRef<GridExposed>()\n\ndefineExpose<_FormExposed>({ el: toRef(() => gridRef.value?.el) })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EA8CA,MAAM,QAAQ;EAWd,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,iBAA4B;GAAE,IAAI;GAAG,IAAI;GAAG,IAAI;GAAG,IAAI;GAAG,SAAS;GAAE;EAE3E,mBAAmB,MAAK;EAExB,MAAM,EAAE,kBAAkB,mBAAmB,EAAE,OAAO,CAAA;EAEtD,SAAS,kBAAkB,OAAe,OAAY;GACpD,MAAM,EAAE,UAAU;GAClB,IAAI,CAAC,OAAO;GACZ,EAAE,MAAM,KAAK,CAAC,IAAI,OAAO,MAAK;;EAGhC,SAAS,gBAAgB,OAAe;GACtC,MAAM,EAAE,MAAM,gBAAgB,MAAM,SAAS,EAAC;GAE9C,MAAM,eAAe,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,MAAK;GAC5C,MAAM,eAAe,EAAE,eAAe,EAAE,CAAC,CAAC,IAAI,MAAK;GACnD,MAAM,WAAW,EAAE,iBAAiB,gBAAiB,CAAC,gBAAgB,CAAC;GAEvE,OAAO,MAAM,mBAAmB;;EAGlC,MAAM,UAAU,YAAwB;EAExC,SAA2B,EAAE,IAAI,YAAY,QAAQ,OAAO,GAAE,EAAG,CAAA;;uBAlF/D,YA2BS,MAAA,UAAA,EAAA;IA1BP,KAAI;aACA;IAAJ,KAAI;IACH,UAAM,OAAA,OAAA,OAAA,KAAA,oBAAP,IAAe,CAAA,UAAA,CAAA;IACd,MAAM,QAAA,QAAQ;IACd,OAAK,eAAA,CAAG,MAAA,IAAG,CAAC,GAAG,MAAA,IAAG,CAAC,GAAE,YAAa,QAAA,SAAQ,CAAA,CAAA;;2BAGwC,EAAA,UAAA,KAAA,EADnF,mBAmBW,UAAA,MAAA,WAlBwD,MAAA,cAAa,EAAA,GAAA,EAArE,MAAM,YAAY,eAAe,OAAO,iBAAU;6DACrD,KAAK,KAAA,EAAA,CAEM,cAAU,CAAK,SAAA,WAAA,EAAhC,YAAoD,wBAAR,KAAI,EAAA,EAAA,KAAA,GAAA,CAAA,KAAA,WAAA,EAEhD,YAYc,MAAA,kBAAA,EAZd,WAYc;;;QAZc,cAAa,EAAA;6BAKrC,EAAA,WAAA,EAJF,YAIE,wBAHK,KAAI,EAAA;OACR,eAAa,cAAc,MAAA,EAAC,CAAC,QAAA,OAAO,QAAI,EAAA,CAAA,CAAQ,IAAI,MAAK;OACzD,wBAAkB,WAAE,kBAAkB,OAAO,OAAM;4DAGb,gBAAgB,MAAK,IAAA,WAAA,EAA9D,mBAIM,OAAA;;OAJA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,cAAA,CAAA;UAChB,mBAAyC,KAAA,EAArC,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,cAAA,CAAA,EAAA,EAAiB,QAAI,EAAA,GAAA,WAAA,EAErC,YAAuF,wBAAvE,KAAI,EAAA;OAAE,UAAA;OAAU,eAAa,MAAA,EAAC,CAAC,QAAA,OAAO,eAAW,EAAA,CAAA,CAAQ,IAAI,MAAK"}
@@ -6,6 +6,11 @@ import { FormModelItem } from "../../types/form.js";
6
6
  * @returns
7
7
  */
8
8
  declare function formField<Val = unknown>(item?: FormModelItem<Val>): FormModelItem<Val>;
9
+ interface NestedFieldMarker<T extends Record<string, any> = Record<string, any>> {
10
+ __isNested: true;
11
+ fields: T;
12
+ }
13
+ declare function nestField<T extends Record<string, any>>(fields: T): NestedFieldMarker<T>;
9
14
  //#endregion
10
- export { formField };
15
+ export { NestedFieldMarker, formField, nestField };
11
16
  //# sourceMappingURL=helper.d.ts.map
@@ -8,7 +8,13 @@ function formField(item) {
8
8
  if (!item) return {};
9
9
  return item;
10
10
  }
11
+ function nestField(fields) {
12
+ return {
13
+ __isNested: true,
14
+ fields
15
+ };
16
+ }
11
17
  //#endregion
12
- export { formField };
18
+ export { formField, nestField };
13
19
 
14
20
  //# sourceMappingURL=helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/form/helper.ts"],"sourcesContent":["import type { FormModelItem } from '../../types'\n\n/**\n * 定义表单项\n * @param item 表单项\n * @returns\n */\nexport function formField<Val = unknown>(item?: FormModelItem<Val>): FormModelItem<Val> {\n if (!item) {\n return {}\n }\n\n return item\n}\n"],"mappings":";;;;;;AAOA,SAAgB,UAAyB,MAA+C;CACtF,IAAI,CAAC,MACH,OAAO,EAAE;CAGX,OAAO"}
1
+ {"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/form/helper.ts"],"sourcesContent":["import type { FormModelItem } from '../../types'\n\n/**\n * 定义表单项\n * @param item 表单项\n * @returns\n */\nexport function formField<Val = unknown>(item?: FormModelItem<Val>): FormModelItem<Val> {\n if (!item) {\n return {}\n }\n\n return item\n}\n\nexport interface NestedFieldMarker<T extends Record<string, any> = Record<string, any>> {\n __isNested: true\n fields: T\n}\n\nexport function nestField<T extends Record<string, any>>(fields: T): NestedFieldMarker<T> {\n return { __isNested: true, fields }\n}\n"],"mappings":";;;;;;AAOA,SAAgB,UAAyB,MAA+C;CACtF,IAAI,CAAC,MACH,OAAO,EAAE;CAGX,OAAO;;AAQT,SAAgB,UAAyC,QAAiC;CACxF,OAAO;EAAE,YAAY;EAAM;EAAQ"}
@@ -1,4 +1,4 @@
1
+ import { NestedFieldMarker, formField, nestField } from "./helper.js";
1
2
  import { DynamicFormModel } from "./dynamic-form-model.js";
2
3
  import { FormModel } from "./form-model.js";
3
- import { _default } from "./form.vue.js";
4
- import { formField } from "./helper.js";
4
+ import { _default } from "./form.vue.js";
@@ -1 +1 @@
1
- {"version":3,"file":"gantt-chart.js","names":[],"sources":["../../../src/components/gantt-chart/gantt-chart.vue"],"sourcesContent":["<template>\n <div :class=\"cls.b\"></div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\n\nimport type { GanttChartProps } from '../../types'\n\ndefineOptions({\n name: 'GanttChart'\n})\n\ndefineProps<GanttChartProps>()\n\nconst cls = bem('gantt-chart')\n</script>\n"],"mappings":";;;;;;;;EAeA,MAAM,MAAM,IAAI,cAAa;;uBAd3B,mBAA0B,OAAA,EAApB,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,EAAA,EAAA,MAAA,EAAA"}
1
+ {"version":3,"file":"gantt-chart.js","names":[],"sources":["../../../src/components/gantt-chart/gantt-chart.vue"],"sourcesContent":["<template>\n <div :class=\"cls.b\"></div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\n\nimport type { GanttChartProps } from '../../types'\n\ndefineOptions({ name: 'GanttChart' })\n\ndefineProps<GanttChartProps>()\n\nconst cls = bem('gantt-chart')\n</script>\n"],"mappings":";;;;;;;;EAaA,MAAM,MAAM,IAAI,cAAa;;uBAZ3B,mBAA0B,OAAA,EAApB,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,EAAA,EAAA,MAAA,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"grid-item.js","names":[],"sources":["../../../src/components/grid/grid-item.vue"],"sourcesContent":["<template>\n <component :is=\"tag\" :style=\"style\" :class=\"cls.b\" v-if=\"span !== 0\">\n <slot />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { computed, inject, type CSSProperties, watch } from 'vue'\n\nimport type { GridItemProps } from '../../types'\nimport { GridDIKey } from './di'\n\ndefineOptions({\n name: 'GridItem'\n})\n\nconst props = withDefaults(defineProps<GridItemProps>(), {\n tag: 'div'\n})\n\nconst cls = bem('grid-item')\n\nconst { currentBreakpoint, gridItemsProps } = inject(GridDIKey) ?? {}\n\nif (!currentBreakpoint) {\n console.error('GridItem组件仅能在Grid组件中使用')\n}\n\nconst span = computed<number | 'full'>(() => {\n let { span } = props\n if (span === undefined) return 1\n if (span === 'full') return 'full'\n\n if (typeof span === 'number') return span\n\n const breakpoint = currentBreakpoint?.value\n\n if (!breakpoint) return span.default\n return span[breakpoint.name] ?? span.default\n})\n\nconst style = computed<CSSProperties>(() => {\n return {\n gridColumn: span.value === 'full' ? '1 / -1' : `span ${span.value}`\n }\n})\n\nwatch(\n () => props.span,\n (span) => {\n if (typeof span === 'object') {\n gridItemsProps?.add(props)\n } else {\n gridItemsProps?.delete(props)\n }\n },\n { immediate: true }\n)\n</script>\n"],"mappings":";;;;;;;;;;;;EAiBA,MAAM,QAAQ;EAId,MAAM,MAAM,IAAI,YAAW;EAE3B,MAAM,EAAE,mBAAmB,mBAAmB,OAAO,UAAS,IAAK,EAAC;EAEpE,IAAI,CAAC,mBACH,QAAQ,MAAM,yBAAwB;EAGxC,MAAM,OAAO,eAAgC;GAC3C,IAAI,EAAE,SAAS;GACf,IAAI,SAAS,KAAA,GAAW,OAAO;GAC/B,IAAI,SAAS,QAAQ,OAAO;GAE5B,IAAI,OAAO,SAAS,UAAU,OAAO;GAErC,MAAM,aAAa,mBAAmB;GAEtC,IAAI,CAAC,YAAY,OAAO,KAAK;GAC7B,OAAO,KAAK,WAAW,SAAS,KAAK;IACtC;EAED,MAAM,QAAQ,eAA8B;GAC1C,OAAO,EACL,YAAY,KAAK,UAAU,SAAS,WAAW,QAAQ,KAAK,SAC9D;IACD;EAED,YACQ,MAAM,OACX,SAAS;GACR,IAAI,OAAO,SAAS,UAClB,gBAAgB,IAAI,MAAK;QAEzB,gBAAgB,OAAO,MAAK;KAGhC,EAAE,WAAW,MACf,CAAA;;UAzD2D,KAAA,UAAI,KAAA,WAAA,EAA7D,YAEY,wBAFI,QAAA,IAAG,EAAA;;IAAG,OAAK,eAAE,MAAA,MAAK;IAAG,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC;;2BACvC,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"grid-item.js","names":[],"sources":["../../../src/components/grid/grid-item.vue"],"sourcesContent":["<template>\n <component :is=\"tag\" :style=\"style\" :class=\"cls.b\" v-if=\"span !== 0\">\n <slot />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { computed, inject, type CSSProperties, watch } from 'vue'\n\nimport type { GridItemProps } from '../../types'\nimport { GridDIKey } from './di'\n\ndefineOptions({ name: 'GridItem' })\n\nconst props = withDefaults(defineProps<GridItemProps>(), { tag: 'div' })\n\nconst cls = bem('grid-item')\n\nconst { currentBreakpoint, gridItemsProps } = inject(GridDIKey) ?? {}\n\nif (!currentBreakpoint) {\n console.error('GridItem组件仅能在Grid组件中使用')\n}\n\nconst span = computed<number | 'full'>(() => {\n let { span } = props\n if (span === undefined) return 1\n if (span === 'full') return 'full'\n\n if (typeof span === 'number') return span\n\n const breakpoint = currentBreakpoint?.value\n\n if (!breakpoint) return span.default\n return span[breakpoint.name] ?? span.default\n})\n\nconst style = computed<CSSProperties>(() => {\n return { gridColumn: span.value === 'full' ? '1 / -1' : `span ${span.value}` }\n})\n\nwatch(\n () => props.span,\n (span) => {\n if (typeof span === 'object') {\n gridItemsProps?.add(props)\n } else {\n gridItemsProps?.delete(props)\n }\n },\n { immediate: true }\n)\n</script>\n"],"mappings":";;;;;;;;;;;;EAeA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,YAAW;EAE3B,MAAM,EAAE,mBAAmB,mBAAmB,OAAO,UAAS,IAAK,EAAC;EAEpE,IAAI,CAAC,mBACH,QAAQ,MAAM,yBAAwB;EAGxC,MAAM,OAAO,eAAgC;GAC3C,IAAI,EAAE,SAAS;GACf,IAAI,SAAS,KAAA,GAAW,OAAO;GAC/B,IAAI,SAAS,QAAQ,OAAO;GAE5B,IAAI,OAAO,SAAS,UAAU,OAAO;GAErC,MAAM,aAAa,mBAAmB;GAEtC,IAAI,CAAC,YAAY,OAAO,KAAK;GAC7B,OAAO,KAAK,WAAW,SAAS,KAAK;IACtC;EAED,MAAM,QAAQ,eAA8B;GAC1C,OAAO,EAAE,YAAY,KAAK,UAAU,SAAS,WAAW,QAAQ,KAAK,SAAQ;IAC9E;EAED,YACQ,MAAM,OACX,SAAS;GACR,IAAI,OAAO,SAAS,UAClB,gBAAgB,IAAI,MAAK;QAEzB,gBAAgB,OAAO,MAAK;KAGhC,EAAE,WAAW,MACf,CAAA;;UAnD2D,KAAA,UAAI,KAAA,WAAA,EAA7D,YAEY,wBAFI,QAAA,IAAG,EAAA;;IAAG,OAAK,eAAE,MAAA,MAAK;IAAG,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC;;2BACvC,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"grid.js","names":[],"sources":["../../../src/components/grid/grid.vue"],"sourcesContent":["<template>\n <component :is=\"tag\" :class=\"cls.b\" ref=\"grid\">\n <slot />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, removeStyles, setStyles, withUnit } from '@veltra/utils'\nimport { type CSSProperties, provide, watch, useTemplateRef, computed } from 'vue'\n\nimport type { GridProps, GridEmits, _GridExposed } from '../../types'\nimport { getBreakpointCols } from './breakpoint'\nimport { GridDIKey } from './di'\nimport { useResponsive } from './use-responsive'\n\ndefineOptions({\n name: 'Grid'\n})\n\nconst props = withDefaults(defineProps<GridProps>(), {\n tag: 'div'\n})\n\nconst emit = defineEmits<GridEmits>()\n\nconst cls = bem('grid')\n\nconst gridRef = useTemplateRef<HTMLElement>('grid')\n\nconst { currentBreakpoint, gridItemsProps } = useResponsive({\n props,\n emit,\n gridRef\n})\n\nconst styles = computed(() => {\n const { gap, cols } = props\n const result: CSSProperties = {}\n\n // 间距\n if (typeof gap === 'number') {\n if (gap > 0) {\n result.rowGap = result.columnGap = gap + 'px'\n }\n } else if (typeof gap === 'string') {\n const [rowGap, columnGap] = gap.split(' ')\n result.columnGap = withUnit(columnGap || rowGap, 'px')\n result.rowGap = withUnit(rowGap, 'px')\n }\n\n const breakpoint = currentBreakpoint.value\n\n switch (typeof cols) {\n case 'number':\n result.gridTemplateColumns = `repeat(${cols}, minmax(0px, 1fr))`\n break\n case 'function':\n if (breakpoint) {\n result.gridTemplateColumns = `repeat(${cols(breakpoint)}, minmax(0px, 1fr))`\n }\n break\n case 'object':\n if (breakpoint) {\n const amount = getBreakpointCols(cols, breakpoint)\n result.gridTemplateColumns = `repeat(${amount}, minmax(0px, 1fr))`\n }\n }\n\n return result\n})\n\nwatch([styles, gridRef], ([styles, dom]) => {\n if (!dom) return\n\n // 重置并移除样式\n removeStyles(dom, ['gridTemplateColumns', 'columnGap', 'rowGap'])\n setStyles(dom, styles)\n})\n\nprovide(GridDIKey, {\n currentBreakpoint,\n gridItemsProps\n})\n\ndefineExpose<_GridExposed>({\n el: gridRef\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;EAmBA,MAAM,QAAQ;EAId,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,UAAU,eAA4B,OAAM;EAElD,MAAM,EAAE,mBAAmB,mBAAmB,cAAc;GAC1D;GACA;GACA;GACD,CAAA;EAsCD,MAAM,CApCS,eAAe;GAC5B,MAAM,EAAE,KAAK,SAAS;GACtB,MAAM,SAAwB,EAAC;GAG/B,IAAI,OAAO,QAAQ;QACb,MAAM,GACR,OAAO,SAAS,OAAO,YAAY,MAAM;UAEtC,IAAI,OAAO,QAAQ,UAAU;IAClC,MAAM,CAAC,QAAQ,aAAa,IAAI,MAAM,IAAG;IACzC,OAAO,YAAY,SAAS,aAAa,QAAQ,KAAI;IACrD,OAAO,SAAS,SAAS,QAAQ,KAAI;;GAGvC,MAAM,aAAa,kBAAkB;GAErC,QAAQ,OAAO,MAAf;IACE,KAAK;KACH,OAAO,sBAAsB,UAAU,KAAK;KAC5C;IACF,KAAK;KACH,IAAI,YACF,OAAO,sBAAsB,UAAU,KAAK,WAAU,CAAE;KAE1D;IACF,KAAK,UACH,IAAI,YAEF,OAAO,sBAAsB,UADd,kBAAkB,MAAM,WACA,CAAO;;GAIpD,OAAO;IAGF,EAAQ,QAAO,GAAI,CAAC,QAAQ,SAAS;GAC1C,IAAI,CAAC,KAAK;GAGV,aAAa,KAAK;IAAC;IAAuB;IAAa;IAAS,CAAA;GAChE,UAAU,KAAK,OAAM;IACtB;EAED,QAAQ,WAAW;GACjB;GACA;GACD,CAAA;EAED,SAA2B,EACzB,IAAI,SACL,CAAA;;uBArFC,YAEY,wBAFI,QAAA,IAAG,EAAA;IAAG,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC;IAAE,KAAI;;2BAC9B,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"grid.js","names":[],"sources":["../../../src/components/grid/grid.vue"],"sourcesContent":["<template>\n <component :is=\"tag\" :class=\"cls.b\" ref=\"grid\">\n <slot />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, removeStyles, setStyles, withUnit } from '@veltra/utils'\nimport { type CSSProperties, provide, watch, useTemplateRef, computed } from 'vue'\n\nimport type { GridProps, GridEmits, _GridExposed } from '../../types'\nimport { getBreakpointCols } from './breakpoint'\nimport { GridDIKey } from './di'\nimport { useResponsive } from './use-responsive'\n\ndefineOptions({ name: 'Grid' })\n\nconst props = withDefaults(defineProps<GridProps>(), { tag: 'div' })\n\nconst emit = defineEmits<GridEmits>()\n\nconst cls = bem('grid')\n\nconst gridRef = useTemplateRef<HTMLElement>('grid')\n\nconst { currentBreakpoint, gridItemsProps } = useResponsive({ props, emit, gridRef })\n\nconst styles = computed(() => {\n const { gap, cols } = props\n const result: CSSProperties = {}\n\n // 间距\n if (typeof gap === 'number') {\n if (gap > 0) {\n result.rowGap = result.columnGap = gap + 'px'\n }\n } else if (typeof gap === 'string') {\n const [rowGap, columnGap] = gap.split(' ')\n result.columnGap = withUnit(columnGap || rowGap, 'px')\n result.rowGap = withUnit(rowGap, 'px')\n }\n\n const breakpoint = currentBreakpoint.value\n\n switch (typeof cols) {\n case 'number':\n result.gridTemplateColumns = `repeat(${cols}, minmax(0px, 1fr))`\n break\n case 'function':\n if (breakpoint) {\n result.gridTemplateColumns = `repeat(${cols(breakpoint)}, minmax(0px, 1fr))`\n }\n break\n case 'object':\n if (breakpoint) {\n const amount = getBreakpointCols(cols, breakpoint)\n result.gridTemplateColumns = `repeat(${amount}, minmax(0px, 1fr))`\n }\n }\n\n return result\n})\n\nwatch([styles, gridRef], ([styles, dom]) => {\n if (!dom) return\n\n // 重置并移除样式\n removeStyles(dom, ['gridTemplateColumns', 'columnGap', 'rowGap'])\n setStyles(dom, styles)\n})\n\nprovide(GridDIKey, { currentBreakpoint, gridItemsProps })\n\ndefineExpose<_GridExposed>({ el: gridRef })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;EAiBA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,UAAU,eAA4B,OAAM;EAElD,MAAM,EAAE,mBAAmB,mBAAmB,cAAc;GAAE;GAAO;GAAM;GAAS,CAAA;EAsCpF,MAAM,CApCS,eAAe;GAC5B,MAAM,EAAE,KAAK,SAAS;GACtB,MAAM,SAAwB,EAAC;GAG/B,IAAI,OAAO,QAAQ;QACb,MAAM,GACR,OAAO,SAAS,OAAO,YAAY,MAAM;UAEtC,IAAI,OAAO,QAAQ,UAAU;IAClC,MAAM,CAAC,QAAQ,aAAa,IAAI,MAAM,IAAG;IACzC,OAAO,YAAY,SAAS,aAAa,QAAQ,KAAI;IACrD,OAAO,SAAS,SAAS,QAAQ,KAAI;;GAGvC,MAAM,aAAa,kBAAkB;GAErC,QAAQ,OAAO,MAAf;IACE,KAAK;KACH,OAAO,sBAAsB,UAAU,KAAK;KAC5C;IACF,KAAK;KACH,IAAI,YACF,OAAO,sBAAsB,UAAU,KAAK,WAAU,CAAE;KAE1D;IACF,KAAK,UACH,IAAI,YAEF,OAAO,sBAAsB,UADd,kBAAkB,MAAM,WACA,CAAO;;GAIpD,OAAO;IAGF,EAAQ,QAAO,GAAI,CAAC,QAAQ,SAAS;GAC1C,IAAI,CAAC,KAAK;GAGV,aAAa,KAAK;IAAC;IAAuB;IAAa;IAAS,CAAA;GAChE,UAAU,KAAK,OAAM;IACtB;EAED,QAAQ,WAAW;GAAE;GAAmB;GAAgB,CAAA;EAExD,SAA2B,EAAE,IAAI,SAAS,CAAA;;uBAxExC,YAEY,wBAFI,QAAA,IAAG,EAAA;IAAG,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC;IAAE,KAAI;;2BAC9B,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"grid-input.js","names":[],"sources":["../../../src/components/grid-input/grid-input.vue"],"sourcesContent":["<template>\n <ul :class=\"[cls.b, cls.m(size)]\">\n <li\n v-for=\"(_, index) in length\"\n :key=\"index\"\n tabindex=\"0\"\n @keydown=\"onKeydown($event, valueArray[index]!, index)\"\n @focus=\"focus(index)\"\n @blur=\"index === position && (blur = true)\"\n ref=\"items\"\n :class=\"[cls.e('item'), bem.is('focus', index === position && !blur)]\"\n >\n <span :class=\"cls.em('item', 'text')\" v-if=\"valueArray[index]\">\n {{ valueArray[index] }}\n </span>\n\n <span :class=\"cls.em('item', 'cursor')\" v-else-if=\"index === position\"></span>\n </li>\n </ul>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, ref, getCurrentInstance } from 'vue'\n\nimport type { GridInputProps, GridInputEmits, GridInputExposed } from '../../types'\n\ndefineOptions({\n name: 'GridInput'\n})\n\nconst emit = defineEmits<GridInputEmits>()\n\nconst props = withDefaults(defineProps<GridInputProps>(), {\n length: 6,\n zero: false,\n separator: '-'\n})\n\nconst { size } = useFallbackProps([props], {\n size: 'default'\n})\n\nconst cls = bem('grid-input')\n\nconst _numberReg = computed(() => (props.zero ? /^[0-9]$/ : /^[1-9]$/))\n\nconst valueArray = ref<string[]>([])\n\nconst position = ref<number>(-1)\n\nconst blur = ref<boolean>(false)\n\nconst instance = getCurrentInstance()\n\nconst focus = async (index?: number) => {\n if (index === undefined) {\n focus(position.value)\n return\n }\n if (index !== 0 && index > valueArray.value.length) {\n index = valueArray.value.length\n }\n position.value = index\n const items = (instance?.refs as { items?: unknown })?.items as any\n let dom = items?.[index]\n dom?.focus()\n blur.value = false\n}\n\nconst changeValue = (value: string, index: number) => {\n if (position.value === props.length) return\n const currentValue = valueArray.value[index]\n\n if (currentValue) {\n valueArray.value.splice(index, 1, value)\n } else if (index === valueArray.value.length) {\n valueArray.value.push(value)\n } else {\n return\n }\n position.value++\n focus()\n\n emit('input', valueArray.value.filter((v) => v).join(props.separator))\n}\n\nconst baseOperation = {\n Backspace: (value: string, index: number) => {\n if (value) {\n valueArray.value.splice(index, 1)\n } else if (index - 1 >= 0) {\n valueArray.value.splice(index - 1, 1)\n }\n if (index !== 0) {\n focus(index - 1)\n }\n emit('input', valueArray.value.filter((v) => v).join(props.separator))\n },\n ArrowLeft: (value: string, index: number) => {\n if (index === 0) return\n focus(index - 1)\n },\n ArrowRight: (value: string, index: number) => {\n if (index === valueArray.value.length) return\n focus(index + 1)\n }\n}\n\nconst onKeydown = (e: any, value: string, index: number) => {\n if (_numberReg.value.test(e.key)) {\n changeValue(e.key, index)\n return\n }\n baseOperation[e.key](value, index)\n}\n\nconst clear = () => {\n while (valueArray.value.length) {\n valueArray.value.pop()\n }\n}\n\ndefineExpose<GridInputExposed>({ clear })\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"grid-input.js","names":[],"sources":["../../../src/components/grid-input/grid-input.vue"],"sourcesContent":["<template>\n <ul :class=\"[cls.b, cls.m(size)]\">\n <li\n v-for=\"(_, index) in length\"\n :key=\"index\"\n tabindex=\"0\"\n @keydown=\"onKeydown($event, valueArray[index]!, index)\"\n @focus=\"focus(index)\"\n @blur=\"index === position && (blur = true)\"\n ref=\"items\"\n :class=\"[cls.e('item'), bem.is('focus', index === position && !blur)]\"\n >\n <span :class=\"cls.em('item', 'text')\" v-if=\"valueArray[index]\">\n {{ valueArray[index] }}\n </span>\n\n <span :class=\"cls.em('item', 'cursor')\" v-else-if=\"index === position\"></span>\n </li>\n </ul>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, ref, getCurrentInstance } from 'vue'\n\nimport type { GridInputProps, GridInputEmits, GridInputExposed } from '../../types'\n\ndefineOptions({ name: 'GridInput' })\n\nconst emit = defineEmits<GridInputEmits>()\n\nconst props = withDefaults(defineProps<GridInputProps>(), {\n length: 6,\n zero: false,\n separator: '-'\n})\n\nconst { size } = useFallbackProps([props], { size: 'default' })\n\nconst cls = bem('grid-input')\n\nconst _numberReg = computed(() => (props.zero ? /^[0-9]$/ : /^[1-9]$/))\n\nconst valueArray = ref<string[]>([])\n\nconst position = ref<number>(-1)\n\nconst blur = ref<boolean>(false)\n\nconst instance = getCurrentInstance()\n\nconst focus = async (index?: number) => {\n if (index === undefined) {\n focus(position.value)\n return\n }\n if (index !== 0 && index > valueArray.value.length) {\n index = valueArray.value.length\n }\n position.value = index\n const items = (instance?.refs as { items?: unknown })?.items as any\n let dom = items?.[index]\n dom?.focus()\n blur.value = false\n}\n\nconst changeValue = (value: string, index: number) => {\n if (position.value === props.length) return\n const currentValue = valueArray.value[index]\n\n if (currentValue) {\n valueArray.value.splice(index, 1, value)\n } else if (index === valueArray.value.length) {\n valueArray.value.push(value)\n } else {\n return\n }\n position.value++\n focus()\n\n emit('input', valueArray.value.filter((v) => v).join(props.separator))\n}\n\nconst baseOperation = {\n Backspace: (value: string, index: number) => {\n if (value) {\n valueArray.value.splice(index, 1)\n } else if (index - 1 >= 0) {\n valueArray.value.splice(index - 1, 1)\n }\n if (index !== 0) {\n focus(index - 1)\n }\n emit('input', valueArray.value.filter((v) => v).join(props.separator))\n },\n ArrowLeft: (value: string, index: number) => {\n if (index === 0) return\n focus(index - 1)\n },\n ArrowRight: (value: string, index: number) => {\n if (index === valueArray.value.length) return\n focus(index + 1)\n }\n}\n\nconst onKeydown = (e: any, value: string, index: number) => {\n if (_numberReg.value.test(e.key)) {\n changeValue(e.key, index)\n return\n }\n baseOperation[e.key](value, index)\n}\n\nconst clear = () => {\n while (valueArray.value.length) {\n valueArray.value.pop()\n }\n}\n\ndefineExpose<GridInputExposed>({ clear })\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"group-input.js","names":[],"sources":["../../../src/components/group-input/group-input.vue"],"sourcesContent":["<template>\n <ul :class=\"[cls.b, cls.m(size)]\" v-if=\"!readonly\">\n <li v-if=\"isEmpty && creatable\">\n <u-button style=\"width: 100%\" :icon=\"Plus\" @click=\"handleAdd(0)\" :size=\"size\">\n 新增\n </u-button>\n </li>\n <li v-for=\"(item, index) of items\" :key=\"item.id\" :class=\"cls.e('item')\" :style=\"itemStyle\">\n <slot v-bind=\"{ item: item.data, index }\" />\n <span :class=\"cls.e('actions')\">\n <u-button\n :icon=\"Minus\"\n circle\n :disabled=\"disabled\"\n :size=\"size\"\n @click=\"handleRemove(index)\"\n />\n <u-button\n :icon=\"Plus\"\n circle\n :disabled=\"disabled\"\n :size=\"size\"\n type=\"primary\"\n @click=\"handleAdd(index)\"\n />\n </span>\n </li>\n </ul>\n\n <template v-else-if=\"items?.length\">\n <ul :class=\"[cls.b, cls.m(size)]\">\n <li v-for=\"item of items\" :key=\"item.id\" :class=\"cls.e('item')\">\n <span v-for=\"v in item.data\">{{ v }}</span>\n </li>\n </ul>\n </template>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup generic=\"GroupItem extends Record<string, any>\">\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { Minus, Plus } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { GroupInputEmits, GroupInputProps } from '../../types'\nimport { UButton } from '../button'\nimport { useGroupItems } from './use-group-items'\n\ndefineOptions({\n name: 'GroupInput'\n})\n\nconst props = withDefaults(defineProps<GroupInputProps<GroupItem>>(), {\n modelValue: () => [],\n disabled: undefined,\n readonly: undefined,\n creatable: true\n})\n\nconst emit = defineEmits<GroupInputEmits>()\n\nconst cls = bem('group-input')\n\nconst { formProps } = injectFormContext()\nconst { disabled, size, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst { items, createItem, runByEvent } = useGroupItems({\n props,\n emit\n})\n\nconst isEmpty = computed(() => {\n return !items.value.length\n})\n\nfunction handleAdd(index: number) {\n runByEvent(() => {\n items.value = [\n ...items.value.slice(0, index + 1),\n createItem({}),\n ...items.value.slice(index + 1)\n ]\n })\n}\n\nfunction handleRemove(index: number) {\n runByEvent(() => {\n items.value = [...items.value.slice(0, index), ...items.value.slice(index + 1)]\n })\n}\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"group-input.js","names":[],"sources":["../../../src/components/group-input/group-input.vue"],"sourcesContent":["<template>\n <ul :class=\"[cls.b, cls.m(size)]\" v-if=\"!readonly\">\n <li v-if=\"isEmpty && creatable\">\n <u-button style=\"width: 100%\" :icon=\"Plus\" @click=\"handleAdd(0)\" :size=\"size\">\n 新增\n </u-button>\n </li>\n <li v-for=\"(item, index) of items\" :key=\"item.id\" :class=\"cls.e('item')\" :style=\"itemStyle\">\n <slot v-bind=\"{ item: item.data, index }\" />\n <span :class=\"cls.e('actions')\">\n <u-button\n :icon=\"Minus\"\n circle\n :disabled=\"disabled\"\n :size=\"size\"\n @click=\"handleRemove(index)\"\n />\n <u-button\n :icon=\"Plus\"\n circle\n :disabled=\"disabled\"\n :size=\"size\"\n type=\"primary\"\n @click=\"handleAdd(index)\"\n />\n </span>\n </li>\n </ul>\n\n <template v-else-if=\"items?.length\">\n <ul :class=\"[cls.b, cls.m(size)]\">\n <li v-for=\"item of items\" :key=\"item.id\" :class=\"cls.e('item')\">\n <span v-for=\"v in item.data\">{{ v }}</span>\n </li>\n </ul>\n </template>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup generic=\"GroupItem extends Record<string, any>\">\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { Minus, Plus } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { GroupInputEmits, GroupInputProps } from '../../types'\nimport { UButton } from '../button'\nimport { useGroupItems } from './use-group-items'\n\ndefineOptions({ name: 'GroupInput' })\n\nconst props = withDefaults(defineProps<GroupInputProps<GroupItem>>(), {\n modelValue: () => [],\n disabled: undefined,\n readonly: undefined,\n creatable: true\n})\n\nconst emit = defineEmits<GroupInputEmits>()\n\nconst cls = bem('group-input')\n\nconst { formProps } = injectFormContext()\nconst { disabled, size, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst { items, createItem, runByEvent } = useGroupItems({ props, emit })\n\nconst isEmpty = computed(() => {\n return !items.value.length\n})\n\nfunction handleAdd(index: number) {\n runByEvent(() => {\n items.value = [\n ...items.value.slice(0, index + 1),\n createItem({}),\n ...items.value.slice(index + 1)\n ]\n })\n}\n\nfunction handleRemove(index: number) {\n runByEvent(() => {\n items.value = [...items.value.slice(0, index), ...items.value.slice(index + 1)]\n })\n}\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"icon.js","names":[],"sources":["../../../src/components/icon/icon.vue"],"sourcesContent":["<template>\n <i :class=\"cls.b\" :style=\"style\">\n <slot></slot>\n </i>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, withUnit } from '@veltra/utils'\nimport { type CSSProperties, computed } from 'vue'\n\nimport type { IconProps } from '../../types'\n\ndefineOptions({\n name: 'Icon'\n})\n\nconst props = defineProps<IconProps>()\n\nconst cls = bem('icon')\n\nconst style = computed<CSSProperties>(() => {\n return {\n fontSize: withUnit(props.size, 'px')\n }\n})\n</script>\n"],"mappings":";;;;;;;;EAgBA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,QAAQ,eAA8B;GAC1C,OAAO,EACL,UAAU,SAAS,MAAM,MAAM,KAAI,EACrC;IACD;;uBAvBC,mBAEI,KAAA;IAFA,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC;IAAG,OAAK,eAAE,MAAA,MAAK;OAC7B,WAAa,KAAA,QAAA,UAAA,CAAA,EAAA,EAAA"}
1
+ {"version":3,"file":"icon.js","names":[],"sources":["../../../src/components/icon/icon.vue"],"sourcesContent":["<template>\n <i :class=\"cls.b\" :style=\"style\">\n <slot></slot>\n </i>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, withUnit } from '@veltra/utils'\nimport { type CSSProperties, computed } from 'vue'\n\nimport type { IconProps } from '../../types'\n\ndefineOptions({ name: 'Icon' })\n\nconst props = defineProps<IconProps>()\n\nconst cls = bem('icon')\n\nconst style = computed<CSSProperties>(() => {\n return { fontSize: withUnit(props.size, 'px') }\n})\n</script>\n"],"mappings":";;;;;;;;EAcA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,QAAQ,eAA8B;GAC1C,OAAO,EAAE,UAAU,SAAS,MAAM,MAAM,KAAI,EAAE;IAC/C;;uBAnBC,mBAEI,KAAA;IAFA,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC;IAAG,OAAK,eAAE,MAAA,MAAK;OAC7B,WAAa,KAAA,QAAA,UAAA,CAAA,EAAA,EAAA"}
@@ -1,3 +1,4 @@
1
+ import { NestedFieldMarker, formField, nestField } from "./form/helper.js";
1
2
  import { _default } from "./condition-editor/condition-editor.vue.js";
2
3
  import { EvaluateOptions, createEmptyGroup, createEmptyLeaf, evaluate } from "./condition-editor/core/evaluator.js";
3
4
  import { _default as _default$1 } from "./tabs/tabs.vue.js";
@@ -11,7 +12,6 @@ import { _default as _default$8 } from "./drawer/drawer.vue.js";
11
12
  import { DynamicFormModel } from "./form/dynamic-form-model.js";
12
13
  import { FormModel } from "./form/form-model.js";
13
14
  import { _default as _default$9 } from "./form/form.vue.js";
14
- import { formField } from "./form/helper.js";
15
15
  import { _default as _default$10 } from "./message-confirm/message-confirm.vue.js";
16
16
  import { _default as _default$11 } from "./message-confirm/message-confirm.js";
17
17
  import { _default as _default$12 } from "./calendar/calendar.vue.js";
@@ -21,7 +21,7 @@ import _sfc_main$15 from "./grid/grid.js";
21
21
  import _sfc_main$16 from "./grid/grid-item.js";
22
22
  import form_item_default from "./form-item/form-item.js";
23
23
  import form_default from "./form/form.js";
24
- import { formField } from "./form/helper.js";
24
+ import { formField, nestField } from "./form/helper.js";
25
25
  import { FormModel } from "./form/form-model.js";
26
26
  import { DynamicFormModel } from "./form/dynamic-form-model.js";
27
27
  import _sfc_main$17 from "./button/button.js";
@@ -200,6 +200,7 @@ var components_exports = /* @__PURE__ */ __exportAll({
200
200
  evaluateConditionExpression: () => evaluate,
201
201
  formField: () => formField,
202
202
  message: () => message,
203
+ nestField: () => nestField,
203
204
  vLoading: () => vLoading
204
205
  });
205
206
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","names":[],"sources":["../../../src/components/input/input.vue"],"sourcesContent":["<template>\n <div\n :class=\"inputClass\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n v-if=\"!readonly\"\n >\n <span v-if=\"$slots.prefix || prefix\" :class=\"prefixClass\" @click=\"handlePrefixClick\">\n {{ prefix }}\n <slot name=\"prefix\"></slot>\n </span>\n\n <input\n :class=\"cls.e('native')\"\n :placeholder=\"props.placeholder\"\n type=\"text\"\n :value=\"model\"\n @input=\"handleInput\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @compositionstart=\"handleCompositionStart\"\n @compositionend=\"handleCompositionEnd\"\n autocomplete=\"off\"\n ref=\"el\"\n :disabled=\"disabled\"\n :readonly=\"nativeReadonly\"\n />\n\n <span :class=\"suffixClass\" v-if=\"hasSuffix\">\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <UIcon\n v-if=\"showClear\"\n :class=\"cls.e('clear')\"\n title=\"清除\"\n @click.stop=\"clearModelValue\"\n key=\"clear\"\n >\n <Close />\n </UIcon>\n\n <span v-else :class=\"cls.e('suffix-content')\" @click=\"handleSuffixClick\" key=\"suffix\">\n {{ suffix }}\n <slot name=\"suffix\"></slot>\n </span>\n </Transition>\n </span>\n </div>\n\n <template v-else>\n {{ generateModel || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { useFocus, useFormFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, getCurrentInstance, ref, shallowRef, nextTick } from 'vue'\n\nimport type { InputEmits, InputProps, _InputExposed } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({\n name: 'Input'\n})\n\nconst props = withDefaults(defineProps<InputProps>(), {\n placeholder: '请输入',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<InputEmits>()\n\nconst model = defineModel<string>()\n\nconst inst = getCurrentInstance()\n\nconst cls = bem('input')\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst { focus, handleBlur, handleFocus } = useFocus((focused) => {\n if (focused) {\n emit('focus')\n } else {\n emit('blur')\n }\n})\n\nconst inputClass = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('focus', focus.value)\n ]\n})\n\nconst prefixClass = [cls.e('prefix'), bem.is('clickable', !!inst?.vnode.props?.['onPrefix:click'])]\n\nconst suffixClass = [cls.e('suffix'), bem.is('clickable', !!inst?.vnode.props?.['onSuffix:click'])]\n\nlet isComposing = false\n\nfunction handleCompositionStart() {\n isComposing = true\n}\n\nfunction handleCompositionEnd(e: Event) {\n isComposing = false\n handleInput(e)\n}\n\nconst handleInput = (e: Event) => {\n if (isComposing) return\n\n const inputVal = (e.target as HTMLInputElement).value\n emit('native:input', e)\n\n const valid = props.pattern?.test(inputVal) ?? true\n\n if (!valid) return\n model.value = inputVal\n}\n\nconst handlePrefixClick = () => {\n emit('prefix:click', model.value)\n}\n\nconst handleSuffixClick = () => {\n emit('suffix:click', model.value)\n}\n\nconst clearModelValue = () => {\n model.value = ''\n emit('clear')\n}\n\nconst hovered = ref(false)\nconst handleMouseEnter = () => {\n hovered.value = true\n}\n\nconst handleMouseLeave = () => {\n hovered.value = false\n}\n\nconst showClear = computed(() => {\n return props.clearable && !disabled.value && !!model.value && hovered.value\n})\n\nconst hasSuffixContent = computed(() => {\n return !!inst?.slots.suffix || !!props.suffix\n})\n\nconst hasSuffix = computed(() => {\n return hasSuffixContent.value || showClear.value\n})\n\nconst handleChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n\n const valid = props.pattern?.test(target.value) ?? true\n\n if (valid) {\n emit('change', target.value)\n } else {\n nextTick(() => {\n target.value = model.value ?? ''\n })\n }\n}\n\nconst el = shallowRef<HTMLInputElement>()\n\nconst generateModel = computed(() => {\n if (!model.value) return ''\n\n return `${props.prefix ?? ''}${model.value}${props.suffix ?? ''}`\n})\n\ndefineExpose<_InputExposed>({\n el\n})\n</script>\n"],"mappings":""}
1
+ {"version":3,"file":"input.js","names":[],"sources":["../../../src/components/input/input.vue"],"sourcesContent":["<template>\n <div\n :class=\"inputClass\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n v-if=\"!readonly\"\n >\n <span v-if=\"$slots.prefix || prefix\" :class=\"prefixClass\" @click=\"handlePrefixClick\">\n {{ prefix }}\n <slot name=\"prefix\"></slot>\n </span>\n\n <input\n :class=\"cls.e('native')\"\n :placeholder=\"props.placeholder\"\n type=\"text\"\n :value=\"model\"\n @input=\"handleInput\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @compositionstart=\"handleCompositionStart\"\n @compositionend=\"handleCompositionEnd\"\n autocomplete=\"off\"\n ref=\"el\"\n :disabled=\"disabled\"\n :readonly=\"nativeReadonly\"\n />\n\n <span :class=\"suffixClass\" v-if=\"hasSuffix\">\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <UIcon\n v-if=\"showClear\"\n :class=\"cls.e('clear')\"\n title=\"清除\"\n @click.stop=\"clearModelValue\"\n key=\"clear\"\n >\n <Close />\n </UIcon>\n\n <span v-else :class=\"cls.e('suffix-content')\" @click=\"handleSuffixClick\" key=\"suffix\">\n {{ suffix }}\n <slot name=\"suffix\"></slot>\n </span>\n </Transition>\n </span>\n </div>\n\n <template v-else>\n {{ generateModel || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { useFocus, useFormFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, getCurrentInstance, ref, shallowRef, nextTick } from 'vue'\n\nimport type { InputEmits, InputProps, _InputExposed } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'Input' })\n\nconst props = withDefaults(defineProps<InputProps>(), {\n placeholder: '请输入',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<InputEmits>()\n\nconst model = defineModel<string>()\n\nconst inst = getCurrentInstance()\n\nconst cls = bem('input')\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst { focus, handleBlur, handleFocus } = useFocus((focused) => {\n if (focused) {\n emit('focus')\n } else {\n emit('blur')\n }\n})\n\nconst inputClass = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('focus', focus.value)\n ]\n})\n\nconst prefixClass = [cls.e('prefix'), bem.is('clickable', !!inst?.vnode.props?.['onPrefix:click'])]\n\nconst suffixClass = [cls.e('suffix'), bem.is('clickable', !!inst?.vnode.props?.['onSuffix:click'])]\n\nlet isComposing = false\n\nfunction handleCompositionStart() {\n isComposing = true\n}\n\nfunction handleCompositionEnd(e: Event) {\n isComposing = false\n handleInput(e)\n}\n\nconst handleInput = (e: Event) => {\n if (isComposing) return\n\n const inputVal = (e.target as HTMLInputElement).value\n emit('native:input', e)\n\n const valid = props.pattern?.test(inputVal) ?? true\n\n if (!valid) return\n model.value = inputVal\n}\n\nconst handlePrefixClick = () => {\n emit('prefix:click', model.value)\n}\n\nconst handleSuffixClick = () => {\n emit('suffix:click', model.value)\n}\n\nconst clearModelValue = () => {\n model.value = ''\n emit('clear')\n}\n\nconst hovered = ref(false)\nconst handleMouseEnter = () => {\n hovered.value = true\n}\n\nconst handleMouseLeave = () => {\n hovered.value = false\n}\n\nconst showClear = computed(() => {\n return props.clearable && !disabled.value && !!model.value && hovered.value\n})\n\nconst hasSuffixContent = computed(() => {\n return !!inst?.slots.suffix || !!props.suffix\n})\n\nconst hasSuffix = computed(() => {\n return hasSuffixContent.value || showClear.value\n})\n\nconst handleChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n\n const valid = props.pattern?.test(target.value) ?? true\n\n if (valid) {\n emit('change', target.value)\n } else {\n nextTick(() => {\n target.value = model.value ?? ''\n })\n }\n}\n\nconst el = shallowRef<HTMLInputElement>()\n\nconst generateModel = computed(() => {\n if (!model.value) return ''\n\n return `${props.prefix ?? ''}${model.value}${props.suffix ?? ''}`\n})\n\ndefineExpose<_InputExposed>({ el })\n</script>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"input.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/input/input.vue"],"sourcesContent":["<template>\n <div\n :class=\"inputClass\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n v-if=\"!readonly\"\n >\n <span v-if=\"$slots.prefix || prefix\" :class=\"prefixClass\" @click=\"handlePrefixClick\">\n {{ prefix }}\n <slot name=\"prefix\"></slot>\n </span>\n\n <input\n :class=\"cls.e('native')\"\n :placeholder=\"props.placeholder\"\n type=\"text\"\n :value=\"model\"\n @input=\"handleInput\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @compositionstart=\"handleCompositionStart\"\n @compositionend=\"handleCompositionEnd\"\n autocomplete=\"off\"\n ref=\"el\"\n :disabled=\"disabled\"\n :readonly=\"nativeReadonly\"\n />\n\n <span :class=\"suffixClass\" v-if=\"hasSuffix\">\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <UIcon\n v-if=\"showClear\"\n :class=\"cls.e('clear')\"\n title=\"清除\"\n @click.stop=\"clearModelValue\"\n key=\"clear\"\n >\n <Close />\n </UIcon>\n\n <span v-else :class=\"cls.e('suffix-content')\" @click=\"handleSuffixClick\" key=\"suffix\">\n {{ suffix }}\n <slot name=\"suffix\"></slot>\n </span>\n </Transition>\n </span>\n </div>\n\n <template v-else>\n {{ generateModel || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { useFocus, useFormFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, getCurrentInstance, ref, shallowRef, nextTick } from 'vue'\n\nimport type { InputEmits, InputProps, _InputExposed } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({\n name: 'Input'\n})\n\nconst props = withDefaults(defineProps<InputProps>(), {\n placeholder: '请输入',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<InputEmits>()\n\nconst model = defineModel<string>()\n\nconst inst = getCurrentInstance()\n\nconst cls = bem('input')\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst { focus, handleBlur, handleFocus } = useFocus((focused) => {\n if (focused) {\n emit('focus')\n } else {\n emit('blur')\n }\n})\n\nconst inputClass = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('focus', focus.value)\n ]\n})\n\nconst prefixClass = [cls.e('prefix'), bem.is('clickable', !!inst?.vnode.props?.['onPrefix:click'])]\n\nconst suffixClass = [cls.e('suffix'), bem.is('clickable', !!inst?.vnode.props?.['onSuffix:click'])]\n\nlet isComposing = false\n\nfunction handleCompositionStart() {\n isComposing = true\n}\n\nfunction handleCompositionEnd(e: Event) {\n isComposing = false\n handleInput(e)\n}\n\nconst handleInput = (e: Event) => {\n if (isComposing) return\n\n const inputVal = (e.target as HTMLInputElement).value\n emit('native:input', e)\n\n const valid = props.pattern?.test(inputVal) ?? true\n\n if (!valid) return\n model.value = inputVal\n}\n\nconst handlePrefixClick = () => {\n emit('prefix:click', model.value)\n}\n\nconst handleSuffixClick = () => {\n emit('suffix:click', model.value)\n}\n\nconst clearModelValue = () => {\n model.value = ''\n emit('clear')\n}\n\nconst hovered = ref(false)\nconst handleMouseEnter = () => {\n hovered.value = true\n}\n\nconst handleMouseLeave = () => {\n hovered.value = false\n}\n\nconst showClear = computed(() => {\n return props.clearable && !disabled.value && !!model.value && hovered.value\n})\n\nconst hasSuffixContent = computed(() => {\n return !!inst?.slots.suffix || !!props.suffix\n})\n\nconst hasSuffix = computed(() => {\n return hasSuffixContent.value || showClear.value\n})\n\nconst handleChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n\n const valid = props.pattern?.test(target.value) ?? true\n\n if (valid) {\n emit('change', target.value)\n } else {\n nextTick(() => {\n target.value = model.value ?? ''\n })\n }\n}\n\nconst el = shallowRef<HTMLInputElement>()\n\nconst generateModel = computed(() => {\n if (!model.value) return ''\n\n return `${props.prefix ?? ''}${model.value}${props.suffix ?? ''}`\n})\n\ndefineExpose<_InputExposed>({\n el\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"input.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/input/input.vue"],"sourcesContent":["<template>\n <div\n :class=\"inputClass\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n v-if=\"!readonly\"\n >\n <span v-if=\"$slots.prefix || prefix\" :class=\"prefixClass\" @click=\"handlePrefixClick\">\n {{ prefix }}\n <slot name=\"prefix\"></slot>\n </span>\n\n <input\n :class=\"cls.e('native')\"\n :placeholder=\"props.placeholder\"\n type=\"text\"\n :value=\"model\"\n @input=\"handleInput\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @compositionstart=\"handleCompositionStart\"\n @compositionend=\"handleCompositionEnd\"\n autocomplete=\"off\"\n ref=\"el\"\n :disabled=\"disabled\"\n :readonly=\"nativeReadonly\"\n />\n\n <span :class=\"suffixClass\" v-if=\"hasSuffix\">\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <UIcon\n v-if=\"showClear\"\n :class=\"cls.e('clear')\"\n title=\"清除\"\n @click.stop=\"clearModelValue\"\n key=\"clear\"\n >\n <Close />\n </UIcon>\n\n <span v-else :class=\"cls.e('suffix-content')\" @click=\"handleSuffixClick\" key=\"suffix\">\n {{ suffix }}\n <slot name=\"suffix\"></slot>\n </span>\n </Transition>\n </span>\n </div>\n\n <template v-else>\n {{ generateModel || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { useFocus, useFormFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, getCurrentInstance, ref, shallowRef, nextTick } from 'vue'\n\nimport type { InputEmits, InputProps, _InputExposed } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'Input' })\n\nconst props = withDefaults(defineProps<InputProps>(), {\n placeholder: '请输入',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<InputEmits>()\n\nconst model = defineModel<string>()\n\nconst inst = getCurrentInstance()\n\nconst cls = bem('input')\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst { focus, handleBlur, handleFocus } = useFocus((focused) => {\n if (focused) {\n emit('focus')\n } else {\n emit('blur')\n }\n})\n\nconst inputClass = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('focus', focus.value)\n ]\n})\n\nconst prefixClass = [cls.e('prefix'), bem.is('clickable', !!inst?.vnode.props?.['onPrefix:click'])]\n\nconst suffixClass = [cls.e('suffix'), bem.is('clickable', !!inst?.vnode.props?.['onSuffix:click'])]\n\nlet isComposing = false\n\nfunction handleCompositionStart() {\n isComposing = true\n}\n\nfunction handleCompositionEnd(e: Event) {\n isComposing = false\n handleInput(e)\n}\n\nconst handleInput = (e: Event) => {\n if (isComposing) return\n\n const inputVal = (e.target as HTMLInputElement).value\n emit('native:input', e)\n\n const valid = props.pattern?.test(inputVal) ?? true\n\n if (!valid) return\n model.value = inputVal\n}\n\nconst handlePrefixClick = () => {\n emit('prefix:click', model.value)\n}\n\nconst handleSuffixClick = () => {\n emit('suffix:click', model.value)\n}\n\nconst clearModelValue = () => {\n model.value = ''\n emit('clear')\n}\n\nconst hovered = ref(false)\nconst handleMouseEnter = () => {\n hovered.value = true\n}\n\nconst handleMouseLeave = () => {\n hovered.value = false\n}\n\nconst showClear = computed(() => {\n return props.clearable && !disabled.value && !!model.value && hovered.value\n})\n\nconst hasSuffixContent = computed(() => {\n return !!inst?.slots.suffix || !!props.suffix\n})\n\nconst hasSuffix = computed(() => {\n return hasSuffixContent.value || showClear.value\n})\n\nconst handleChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n\n const valid = props.pattern?.test(target.value) ?? true\n\n if (valid) {\n emit('change', target.value)\n } else {\n nextTick(() => {\n target.value = model.value ?? ''\n })\n }\n}\n\nconst el = shallowRef<HTMLInputElement>()\n\nconst generateModel = computed(() => {\n if (!model.value) return ''\n\n return `${props.prefix ?? ''}${model.value}${props.suffix ?? ''}`\n})\n\ndefineExpose<_InputExposed>({ el })\n</script>\n"],"mappings":"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"}