@veltra/desktop 1.0.12 → 1.0.14

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 (182) hide show
  1. package/dist/components/action/action-group.js +110 -3
  2. package/dist/components/action/action-group.js.map +1 -1
  3. package/dist/components/action/action-group.vue.d.ts +16 -3
  4. package/dist/components/action/action.js +26 -13
  5. package/dist/components/action/action.js.map +1 -1
  6. package/dist/components/action/action.vue.d.ts +1 -1
  7. package/dist/components/action/style.js +2 -1
  8. package/dist/components/action/style2.css +35 -7
  9. package/dist/components/auto-complete/auto-complete.vue.d.ts +2 -2
  10. package/dist/components/batch-edit/batch-edit-form.js +106 -42
  11. package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
  12. package/dist/components/batch-edit/batch-edit-list.js +84 -47
  13. package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
  14. package/dist/components/batch-edit/batch-edit.js +42 -10
  15. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  16. package/dist/components/batch-edit/style.js +2 -4
  17. package/dist/components/batch-edit/style2.css +202 -30
  18. package/dist/components/batch-edit/use-edit.js +45 -9
  19. package/dist/components/batch-edit/use-edit.js.map +1 -1
  20. package/dist/components/cascade/cascade.js +3 -1
  21. package/dist/components/cascade/cascade.js.map +1 -1
  22. package/dist/components/cascade/cascade.vue.d.ts +3 -3
  23. package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
  24. package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
  25. package/dist/components/code-editor/code-editor.js +145 -49
  26. package/dist/components/code-editor/code-editor.js.map +1 -1
  27. package/dist/components/code-editor/code-editor.vue.d.ts +2 -0
  28. package/dist/components/code-editor/style2.css +87 -19
  29. package/dist/components/collapse/collapse.js.map +1 -1
  30. package/dist/components/collapse/collapse.vue.d.ts +2 -10
  31. package/dist/components/date-picker/date-picker.vue.d.ts +2 -2
  32. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +2 -2
  33. package/dist/components/dialog/dialog.js +6 -2
  34. package/dist/components/dialog/dialog.js.map +1 -1
  35. package/dist/components/dialog/style2.css +2 -3
  36. package/dist/components/drawer/drawer.vue.d.ts +2 -2
  37. package/dist/components/expression-editor/components/path-preview.js +27 -0
  38. package/dist/components/expression-editor/components/path-preview.js.map +1 -0
  39. package/dist/components/expression-editor/components/variable-picker.js +199 -153
  40. package/dist/components/expression-editor/components/variable-picker.js.map +1 -1
  41. package/dist/components/expression-editor/core/chip.js +54 -0
  42. package/dist/components/expression-editor/core/chip.js.map +1 -0
  43. package/dist/components/expression-editor/core/editor.js +424 -0
  44. package/dist/components/expression-editor/core/editor.js.map +1 -0
  45. package/dist/components/expression-editor/core/mention.js +91 -0
  46. package/dist/components/expression-editor/core/mention.js.map +1 -0
  47. package/dist/components/expression-editor/core/model.js +64 -0
  48. package/dist/components/expression-editor/core/model.js.map +1 -0
  49. package/dist/components/expression-editor/di.js +4 -10
  50. package/dist/components/expression-editor/di.js.map +1 -1
  51. package/dist/components/expression-editor/expression-editor.js +168 -114
  52. package/dist/components/expression-editor/expression-editor.js.map +1 -1
  53. package/dist/components/expression-editor/expression-editor.vue.d.ts +2 -1
  54. package/dist/components/expression-editor/style.js +0 -2
  55. package/dist/components/expression-editor/style2.css +145 -219
  56. package/dist/components/index.js +54 -54
  57. package/dist/components/input/input.vue.d.ts +2 -2
  58. package/dist/components/layout/layout.js +12 -11
  59. package/dist/components/layout/layout.js.map +1 -1
  60. package/dist/components/multi-select/multi-select.vue.d.ts +3 -3
  61. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +3 -3
  62. package/dist/components/number/number.vue.d.ts +1 -1
  63. package/dist/components/number-input/number-input.js +4 -4
  64. package/dist/components/number-input/number-input.js.map +1 -1
  65. package/dist/components/number-input/number-input.vue.d.ts +2 -2
  66. package/dist/components/number-range-input/number-range-input.vue.d.ts +1 -1
  67. package/dist/components/password-input/password-input.vue.d.ts +1 -1
  68. package/dist/components/progress-nodes/progress-nodes.vue.d.ts +2 -2
  69. package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
  70. package/dist/components/rich-text-editor/rich-text-editor.js +1 -1
  71. package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +1 -1
  72. package/dist/components/rich-text-editor/toolbar.js +2 -2
  73. package/dist/components/select/select.vue.d.ts +2 -2
  74. package/dist/components/table/use-table.js +16 -0
  75. package/dist/components/table/use-table.js.map +1 -1
  76. package/dist/components/tabs/tabs-horizontal.vue.d.ts +2 -2
  77. package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
  78. package/dist/components/tabs/tabs.vue.d.ts +2 -2
  79. package/dist/components/textarea/textarea.vue.d.ts +2 -2
  80. package/dist/components/tree/style2.css +18 -12
  81. package/dist/components/tree/tree-node.js +7 -4
  82. package/dist/components/tree/tree-node.js.map +1 -1
  83. package/dist/components/tree-select/tree-select.vue.d.ts +3 -3
  84. package/dist/index.d.ts +3 -3
  85. package/dist/index.js +83 -83
  86. package/dist/style.js +3 -3
  87. package/dist/types/action.d.ts +38 -4
  88. package/dist/types/cascade.d.ts +2 -3
  89. package/dist/types/code-editor.d.ts +9 -2
  90. package/dist/types/collapse.d.ts +6 -5
  91. package/dist/types/expression-editor.d.ts +9 -1
  92. package/dist/types/index.d.ts +2 -2
  93. package/package.json +11 -12
  94. package/src/components/action/action-group.vue +126 -56
  95. package/src/components/action/action.vue +35 -12
  96. package/src/components/action/style.scss +46 -10
  97. package/src/components/action/style.ts +2 -1
  98. package/src/components/batch-edit/batch-edit-form.vue +121 -45
  99. package/src/components/batch-edit/batch-edit-list.vue +56 -39
  100. package/src/components/batch-edit/batch-edit.vue +57 -6
  101. package/src/components/batch-edit/style.scss +251 -37
  102. package/src/components/batch-edit/style.ts +5 -8
  103. package/src/components/batch-edit/use-edit.ts +58 -11
  104. package/src/components/cascade/cascade.vue +3 -1
  105. package/src/components/code-editor/code-editor.vue +198 -63
  106. package/src/components/code-editor/style.scss +110 -12
  107. package/src/components/collapse/collapse.vue +5 -24
  108. package/src/components/dialog/dialog.vue +6 -2
  109. package/src/components/dialog/style.scss +4 -4
  110. package/src/components/expression-editor/__test__/chip.test.ts +86 -0
  111. package/src/components/expression-editor/__test__/mention.test.ts +122 -0
  112. package/src/components/expression-editor/__test__/model.test.ts +127 -0
  113. package/src/components/expression-editor/components/path-preview.vue +32 -0
  114. package/src/components/expression-editor/components/variable-picker.vue +224 -219
  115. package/src/components/expression-editor/core/chip.ts +101 -0
  116. package/src/components/expression-editor/core/editor.ts +513 -0
  117. package/src/components/expression-editor/core/mention.ts +121 -0
  118. package/src/components/expression-editor/core/model.ts +109 -0
  119. package/src/components/expression-editor/di.ts +4 -32
  120. package/src/components/expression-editor/expression-editor.vue +184 -151
  121. package/src/components/expression-editor/style.scss +148 -220
  122. package/src/components/expression-editor/style.ts +0 -2
  123. package/src/components/layout/layout.vue +17 -19
  124. package/src/components/number-input/number-input.vue +4 -4
  125. package/src/components/table/use-table.ts +16 -0
  126. package/src/components/tree/style.scss +30 -33
  127. package/src/components/tree/tree-node.vue +4 -2
  128. package/src/types/action.ts +42 -4
  129. package/src/types/cascade.ts +4 -3
  130. package/src/types/code-editor.ts +9 -2
  131. package/src/types/collapse.ts +6 -6
  132. package/src/types/expression-editor.ts +9 -0
  133. package/dist/components/action/action-group.vue_vue_type_script_setup_true_lang.js +0 -65
  134. package/dist/components/action/action-group.vue_vue_type_script_setup_true_lang.js.map +0 -1
  135. package/dist/components/expression-editor/constants.js +0 -9
  136. package/dist/components/expression-editor/constants.js.map +0 -1
  137. package/dist/components/expression-editor/internal/editor-runtime/create-runtime.js +0 -47
  138. package/dist/components/expression-editor/internal/editor-runtime/create-runtime.js.map +0 -1
  139. package/dist/components/expression-editor/internal/editor-runtime/model-sync.js +0 -49
  140. package/dist/components/expression-editor/internal/editor-runtime/model-sync.js.map +0 -1
  141. package/dist/components/expression-editor/internal/features/commands/register-command-packs.js +0 -215
  142. package/dist/components/expression-editor/internal/features/commands/register-command-packs.js.map +0 -1
  143. package/dist/components/expression-editor/internal/features/drag-drop/drag-drop-service.js +0 -33
  144. package/dist/components/expression-editor/internal/features/drag-drop/drag-drop-service.js.map +0 -1
  145. package/dist/components/expression-editor/internal/features/insertion/insertion-service.js +0 -33
  146. package/dist/components/expression-editor/internal/features/insertion/insertion-service.js.map +0 -1
  147. package/dist/components/expression-editor/nodes/variable-node.js +0 -94
  148. package/dist/components/expression-editor/nodes/variable-node.js.map +0 -1
  149. package/dist/components/expression-editor/parser.js +0 -32
  150. package/dist/components/expression-editor/parser.js.map +0 -1
  151. package/dist/components/expression-editor/plain-text.js +0 -19
  152. package/dist/components/expression-editor/plain-text.js.map +0 -1
  153. package/dist/components/expression-editor/use-context.js +0 -69
  154. package/dist/components/expression-editor/use-context.js.map +0 -1
  155. package/dist/components/expression-editor/use-decorators.js +0 -27
  156. package/dist/components/expression-editor/use-decorators.js.map +0 -1
  157. package/dist/components/expression-editor/use-expression-drag-drop.js +0 -275
  158. package/dist/components/expression-editor/use-expression-drag-drop.js.map +0 -1
  159. package/src/components/batch-edit/batch-edit-new.vue +0 -168
  160. package/src/components/batch-edit/style-new.scss +0 -35
  161. package/src/components/batch-edit/use-edit-new.ts +0 -68
  162. package/src/components/batch-edit/use-tip.ts +0 -47
  163. package/src/components/expression-editor/__test__/architecture-boundaries.test.ts +0 -103
  164. package/src/components/expression-editor/__test__/architecture-compatibility.test.ts +0 -52
  165. package/src/components/expression-editor/__test__/drag-drop.test.ts +0 -171
  166. package/src/components/expression-editor/__test__/parser.test.ts +0 -62
  167. package/src/components/expression-editor/constants.ts +0 -6
  168. package/src/components/expression-editor/internal/contracts/editor-runtime.ts +0 -11
  169. package/src/components/expression-editor/internal/editor-runtime/create-runtime.ts +0 -64
  170. package/src/components/expression-editor/internal/editor-runtime/index.ts +0 -1
  171. package/src/components/expression-editor/internal/editor-runtime/model-sync.ts +0 -68
  172. package/src/components/expression-editor/internal/features/commands/register-command-packs.ts +0 -517
  173. package/src/components/expression-editor/internal/features/drag-drop/drag-drop-service.ts +0 -51
  174. package/src/components/expression-editor/internal/features/insertion/insertion-service.ts +0 -56
  175. package/src/components/expression-editor/nodes/variable-node.tsx +0 -118
  176. package/src/components/expression-editor/parser.ts +0 -46
  177. package/src/components/expression-editor/plain-text.ts +0 -25
  178. package/src/components/expression-editor/plan.md +0 -22
  179. package/src/components/expression-editor/use-context.ts +0 -134
  180. package/src/components/expression-editor/use-decorators.tsx +0 -29
  181. package/src/components/expression-editor/use-editor.ts +0 -12
  182. package/src/components/expression-editor/use-expression-drag-drop.ts +0 -396
@@ -32,23 +32,43 @@ function useEdit(options) {
32
32
  watch(() => state.visible, (v) => {
33
33
  if (!v) state.dataUpdated = false;
34
34
  });
35
- /** 是否是用户输入产生的值变更 */
36
- let changedByUserInput = true;
35
+ /**
36
+ * 「打开行 / 切换 type」时记录的基线快照
37
+ * @description
38
+ * 用于 changeCb 内部比对 — 若新值与基线相等(深比较)视为无改动,避免某些组件在 mount
39
+ * 阶段把规范化后的值再写回模型时被误判为「用户已修改」
40
+ */
41
+ let baselineSnapshot;
42
+ function snapshotModelData() {
43
+ return safeRun(() => JSON.parse(JSON.stringify(props.model?.data ?? {})), {});
44
+ }
37
45
  watch(() => state.row, (row) => {
38
46
  props.model?.resetData();
39
47
  if (row) {
40
48
  state.type = "update";
41
49
  state.visible = true;
42
- changedByUserInput = false;
43
50
  props.model?.setData(row.data);
44
- nextTick(() => {
45
- changedByUserInput = true;
46
- });
47
51
  } else state.visible = false;
48
- });
49
- const changeCb = (_field, _val) => {
50
- if (changedByUserInput) state.dataUpdated = true;
52
+ baselineSnapshot = snapshotModelData();
53
+ state.dataUpdated = false;
54
+ }, { flush: "sync" });
55
+ const changeCb = (field, val) => {
56
+ if (baselineSnapshot) {
57
+ if (isSameValue(o(baselineSnapshot).get(field), val)) return;
58
+ }
59
+ state.dataUpdated = true;
51
60
  };
61
+ function isSameValue(a, b) {
62
+ if (a === b) return true;
63
+ if (a == null && b == null) return true;
64
+ if (typeof a !== typeof b) return false;
65
+ if (typeof a === "object") try {
66
+ return JSON.stringify(a) === JSON.stringify(b);
67
+ } catch {
68
+ return false;
69
+ }
70
+ return false;
71
+ }
52
72
  watch(() => props.model, (model, oldModel) => {
53
73
  if (oldModel) oldModel.offChange(changeCb);
54
74
  if (model) model.onChange(changeCb);
@@ -114,6 +134,20 @@ function useEdit(options) {
114
134
  insertIndexes.value = [...row.indexes, row.children?.length ?? 0];
115
135
  });
116
136
  }
137
+ /** 编辑指定行(等同于点击行) */
138
+ function handleEdit(row) {
139
+ state.row = row;
140
+ state.depth = row.depth;
141
+ }
142
+ /** 复制指定行:在其下方以 create 模式打开表单,并预填副本数据 */
143
+ function handleCopy(row) {
144
+ runCreate(() => {
145
+ state.depth = row.depth;
146
+ insertIndexes.value = [...row.indexes.slice(0, -1), row.index + 1];
147
+ const cloned = safeRun(() => JSON.parse(JSON.stringify(row.data ?? {})), {});
148
+ props.model?.setData(cloned);
149
+ });
150
+ }
117
151
  function runWithLoading(fn) {
118
152
  return async (...args) => {
119
153
  state.loading = true;
@@ -183,6 +217,8 @@ function useEdit(options) {
183
217
  handleInsertToNext,
184
218
  handleInsertToPrev,
185
219
  handleCreate,
220
+ handleEdit,
221
+ handleCopy,
186
222
  handleClose,
187
223
  handleSave
188
224
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-edit.js","names":[],"sources":["../../../src/components/batch-edit/use-edit.ts"],"sourcesContent":["import { last, o, safeRun } from '@cat-kit/core'\nimport { computed, nextTick, shallowReactive, shallowRef, watch, type ShallowRef } from 'vue'\n\nimport type { TableRow, BatchEditEmits, BatchEditProps, TableExposed } from '../../types'\n\n/** 按索引路径在原始数据树中定位节点(等价于历史 Forest.visit 路径访问) */\nfunction visitDataByIndexPath<T extends Record<string, unknown>>(\n roots: T[],\n indexPath: number[],\n childrenKey: string\n): T | undefined {\n if (!indexPath.length) return undefined\n let currentList: T[] | undefined = roots\n let node: T | undefined\n for (let i = 0; i < indexPath.length; i++) {\n const idx = indexPath[i]!\n if (!currentList) return undefined\n node = currentList[idx]\n if (node === undefined) return undefined\n if (i < indexPath.length - 1) {\n const next = node[childrenKey]\n currentList = Array.isArray(next) ? (next as T[]) : undefined\n }\n }\n return node\n}\n\ninterface Options {\n props: BatchEditProps\n emit: BatchEditEmits\n tableRef: ShallowRef<TableExposed | undefined>\n}\n\nexport interface BatchEditStates {\n /** 层级 */\n depth?: number\n visible: boolean\n type: 'create' | 'update'\n loading: boolean\n row?: TableRow\n /** 父级,只在添加子级时会有值 */\n parentRow?: TableRow\n /** 数据是否已更新 */\n dataUpdated: boolean\n}\n\nexport interface EditReturned {\n state: BatchEditStates\n insertIndexes: ShallowRef<number[]>\n handleSave: () => Promise<void>\n handleClose: () => void\n handleCreate: () => void\n handleDelete: (row: TableRow) => Promise<void>\n handleInsertToNext: (row: TableRow) => void\n handleInsertToPrev: (row: TableRow) => void\n handleInsertChild: (row: TableRow) => void\n}\n\nexport function useEdit(options: Options): EditReturned {\n const { props, emit, tableRef } = options\n\n /** 组件状态 */\n const state = shallowReactive<BatchEditStates>({\n depth: undefined,\n visible: false,\n type: 'create',\n loading: false,\n dataUpdated: false\n })\n\n const insertIndexes = shallowRef<number[]>([])\n\n watch(\n () => state.visible,\n (v) => {\n if (!v) {\n state.dataUpdated = false\n }\n }\n )\n\n /** 是否是用户输入产生的值变更 */\n let changedByUserInput = true\n\n watch(\n () => state.row,\n (row) => {\n props.model?.resetData()\n if (row) {\n state.type = 'update'\n state.visible = true\n changedByUserInput = false\n props.model?.setData(row.data)\n nextTick(() => {\n changedByUserInput = true\n })\n } else {\n state.visible = false\n }\n }\n )\n\n const changeCb = (_field: string, _val: any) => {\n // 检测到为用户变更时,为数据添加一个已更改状态从而显示修改按钮\n if (changedByUserInput) {\n state.dataUpdated = true\n }\n }\n\n watch(\n () => props.model,\n (model, oldModel) => {\n if (oldModel) {\n oldModel.offChange(changeCb)\n }\n if (model) {\n model.onChange(changeCb)\n }\n },\n { immediate: true }\n )\n\n const childrenKey = computed(() => {\n return typeof props.tree === 'string' ? props.tree : 'children'\n })\n\n /**\n * 插入数据\n * @param item 数据\n */\n function insert(item: Record<string, any>) {\n const data = [...(props.data ?? [])]\n\n const parent = visitDataByIndexPath(\n data ?? [],\n insertIndexes.value.slice(0, -1),\n childrenKey.value\n )\n\n if (parent) {\n const children = parent[childrenKey.value]\n if (!children) {\n parent[childrenKey.value] = [item]\n } else {\n children.splice(last(insertIndexes.value), 0, item)\n }\n } else {\n data.splice(last(insertIndexes.value), 0, item)\n }\n\n emit('update:data', data)\n\n return item\n }\n\n function getInsertData(): Record<string, any> {\n return safeRun(() => JSON.parse(JSON.stringify(props.model?.data ?? {})), {})\n }\n\n async function runCreate(cb: () => void) {\n state.parentRow = undefined\n if (state.row) {\n state.row.isCurrent = false\n }\n state.row = undefined\n state.type = 'create'\n props.model?.resetData()\n cb()\n\n let item: Record<string, any> | undefined = undefined\n\n await nextTick()\n\n state.visible = true\n\n if (item) {\n const row = tableRef.value?.getRowByData(item)\n if (row) {\n state.row = row\n }\n }\n }\n\n /**\n * 点击新增按钮\n */\n function handleCreate() {\n const { data } = props\n runCreate(() => {\n state.depth = 1\n insertIndexes.value = [data?.length ?? 0]\n })\n }\n\n function handleInsertToPrev(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes]\n })\n }\n\n function handleInsertToNext(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes.slice(0, -1), row.index + 1]\n })\n }\n\n function handleInsertChild(row: TableRow) {\n runCreate(() => {\n state.parentRow = row\n state.depth = row.depth + 1\n row.expanded = true\n\n insertIndexes.value = [...row.indexes, row.children?.length ?? 0]\n })\n }\n\n function runWithLoading<Arg extends any[]>(fn: (...args: Arg) => Promise<void> | void) {\n return async (...args: Arg) => {\n state.loading = true\n if (state.row) {\n state.row.operating = true\n }\n try {\n await fn.apply(null, args)\n } catch (error) {\n console.error(error)\n }\n state.loading = false\n if (state.row) {\n state.row.operating = false\n }\n }\n }\n\n /** 保存 */\n const handleSave = runWithLoading(async () => {\n const { model, saveMethod } = props\n\n if (!model) return\n\n model.clearValidate()\n const valid = await model.validate()\n\n if (!valid) return\n\n let item = getInsertData()\n if (saveMethod) {\n const result = await saveMethod(item, state.type, state.parentRow)\n if (result) {\n item = result\n }\n }\n\n state.dataUpdated = false\n\n // 新增\n if (state.type === 'create') {\n insert(item)\n\n return model?.resetData()\n }\n // 更新\n if (state.type === 'update') {\n const { row } = state\n row &&\n model.allKeys.forEach((key) => {\n o(row.data).set(key, o(item).get(key))\n })\n }\n })\n\n const handleDelete = runWithLoading(async (row: TableRow) => {\n const { deleteMethod } = props\n\n if (deleteMethod) {\n await deleteMethod([row.data])\n }\n\n const data = [...(props.data ?? [])]\n\n const parent = visitDataByIndexPath(data, row.indexes.slice(0, -1), childrenKey.value)\n\n if (parent) {\n const children = parent[childrenKey.value]\n if (children) {\n children.splice(row.index, 1)\n } else {\n console.error('行路径不正确')\n }\n } else {\n data.splice(row.index, 1)\n }\n\n if (state.row === row) {\n state.row = undefined\n state.depth = undefined\n }\n\n emit('update:data', data)\n })\n\n function handleClose() {\n state.visible = false\n if (state.row) {\n state.row.isCurrent = false\n }\n state.row = undefined\n state.parentRow = undefined\n state.depth = undefined\n props.model?.resetData()\n insertIndexes.value = []\n }\n\n return {\n state,\n insertIndexes,\n handleDelete,\n handleInsertChild,\n handleInsertToNext,\n handleInsertToPrev,\n handleCreate,\n handleClose,\n handleSave\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-edit.js","names":[],"sources":["../../../src/components/batch-edit/use-edit.ts"],"sourcesContent":["import { last, o, safeRun } from '@cat-kit/core'\nimport { computed, nextTick, shallowReactive, shallowRef, watch, type ShallowRef } from 'vue'\n\nimport type { TableRow, BatchEditEmits, BatchEditProps, TableExposed } from '../../types'\n\n/** 按索引路径在原始数据树中定位节点(等价于历史 Forest.visit 路径访问) */\nfunction visitDataByIndexPath<T extends Record<string, unknown>>(\n roots: T[],\n indexPath: number[],\n childrenKey: string\n): T | undefined {\n if (!indexPath.length) return undefined\n let currentList: T[] | undefined = roots\n let node: T | undefined\n for (let i = 0; i < indexPath.length; i++) {\n const idx = indexPath[i]!\n if (!currentList) return undefined\n node = currentList[idx]\n if (node === undefined) return undefined\n if (i < indexPath.length - 1) {\n const next = node[childrenKey]\n currentList = Array.isArray(next) ? (next as T[]) : undefined\n }\n }\n return node\n}\n\ninterface Options {\n props: BatchEditProps\n emit: BatchEditEmits\n tableRef: ShallowRef<TableExposed | undefined>\n}\n\nexport interface BatchEditStates {\n /** 层级 */\n depth?: number\n visible: boolean\n type: 'create' | 'update'\n loading: boolean\n row?: TableRow\n /** 父级,只在添加子级时会有值 */\n parentRow?: TableRow\n /** 数据是否已更新 */\n dataUpdated: boolean\n}\n\nexport interface EditReturned {\n state: BatchEditStates\n insertIndexes: ShallowRef<number[]>\n handleSave: () => Promise<void>\n handleClose: () => void\n handleCreate: () => void\n handleEdit: (row: TableRow) => void\n handleCopy: (row: TableRow) => void\n handleDelete: (row: TableRow) => Promise<void>\n handleInsertToNext: (row: TableRow) => void\n handleInsertToPrev: (row: TableRow) => void\n handleInsertChild: (row: TableRow) => void\n}\n\nexport function useEdit(options: Options): EditReturned {\n const { props, emit, tableRef } = options\n\n /** 组件状态 */\n const state = shallowReactive<BatchEditStates>({\n depth: undefined,\n visible: false,\n type: 'create',\n loading: false,\n dataUpdated: false\n })\n\n const insertIndexes = shallowRef<number[]>([])\n\n watch(\n () => state.visible,\n (v) => {\n if (!v) {\n state.dataUpdated = false\n }\n }\n )\n\n /**\n * 「打开行 / 切换 type」时记录的基线快照\n * @description\n * 用于 changeCb 内部比对 — 若新值与基线相等(深比较)视为无改动,避免某些组件在 mount\n * 阶段把规范化后的值再写回模型时被误判为「用户已修改」\n */\n let baselineSnapshot: Record<string, any> | undefined\n\n function snapshotModelData() {\n return safeRun(() => JSON.parse(JSON.stringify(props.model?.data ?? {})), {})\n }\n\n watch(\n () => state.row,\n (row) => {\n props.model?.resetData()\n if (row) {\n state.type = 'update'\n state.visible = true\n props.model?.setData(row.data)\n } else {\n state.visible = false\n }\n baselineSnapshot = snapshotModelData()\n state.dataUpdated = false\n },\n // sync 保证 setData 完成后立刻取快照,避免 mount 期间组件回写值时丢基线\n { flush: 'sync' }\n )\n\n const changeCb = (field: string, val: any) => {\n // 与基线比较 — 同值(如组件 mount 时把当前值再写一次)不算\"用户修改\"\n if (baselineSnapshot) {\n const baseVal = o(baselineSnapshot).get(field)\n if (isSameValue(baseVal, val)) {\n return\n }\n }\n state.dataUpdated = true\n }\n\n function isSameValue(a: any, b: any) {\n if (a === b) return true\n if (a == null && b == null) return true\n if (typeof a !== typeof b) return false\n if (typeof a === 'object') {\n try {\n return JSON.stringify(a) === JSON.stringify(b)\n } catch {\n return false\n }\n }\n return false\n }\n\n watch(\n () => props.model,\n (model, oldModel) => {\n if (oldModel) {\n oldModel.offChange(changeCb)\n }\n if (model) {\n model.onChange(changeCb)\n }\n },\n { immediate: true }\n )\n\n const childrenKey = computed(() => {\n return typeof props.tree === 'string' ? props.tree : 'children'\n })\n\n /**\n * 插入数据\n * @param item 数据\n */\n function insert(item: Record<string, any>) {\n const data = [...(props.data ?? [])]\n\n const parent = visitDataByIndexPath(\n data ?? [],\n insertIndexes.value.slice(0, -1),\n childrenKey.value\n )\n\n if (parent) {\n const children = parent[childrenKey.value]\n if (!children) {\n parent[childrenKey.value] = [item]\n } else {\n children.splice(last(insertIndexes.value), 0, item)\n }\n } else {\n data.splice(last(insertIndexes.value), 0, item)\n }\n\n emit('update:data', data)\n\n return item\n }\n\n function getInsertData(): Record<string, any> {\n return safeRun(() => JSON.parse(JSON.stringify(props.model?.data ?? {})), {})\n }\n\n async function runCreate(cb: () => void) {\n state.parentRow = undefined\n if (state.row) {\n state.row.isCurrent = false\n }\n state.row = undefined\n state.type = 'create'\n props.model?.resetData()\n cb()\n\n let item: Record<string, any> | undefined = undefined\n\n await nextTick()\n\n state.visible = true\n\n if (item) {\n const row = tableRef.value?.getRowByData(item)\n if (row) {\n state.row = row\n }\n }\n }\n\n /**\n * 点击新增按钮\n */\n function handleCreate() {\n const { data } = props\n runCreate(() => {\n state.depth = 1\n insertIndexes.value = [data?.length ?? 0]\n })\n }\n\n function handleInsertToPrev(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes]\n })\n }\n\n function handleInsertToNext(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes.slice(0, -1), row.index + 1]\n })\n }\n\n function handleInsertChild(row: TableRow) {\n runCreate(() => {\n state.parentRow = row\n state.depth = row.depth + 1\n row.expanded = true\n\n insertIndexes.value = [...row.indexes, row.children?.length ?? 0]\n })\n }\n\n /** 编辑指定行(等同于点击行) */\n function handleEdit(row: TableRow) {\n state.row = row\n state.depth = row.depth\n }\n\n /** 复制指定行:在其下方以 create 模式打开表单,并预填副本数据 */\n function handleCopy(row: TableRow) {\n runCreate(() => {\n state.depth = row.depth\n insertIndexes.value = [...row.indexes.slice(0, -1), row.index + 1]\n const cloned = safeRun(() => JSON.parse(JSON.stringify(row.data ?? {})), {})\n props.model?.setData(cloned)\n })\n }\n\n function runWithLoading<Arg extends any[]>(fn: (...args: Arg) => Promise<void> | void) {\n return async (...args: Arg) => {\n state.loading = true\n if (state.row) {\n state.row.operating = true\n }\n try {\n await fn.apply(null, args)\n } catch (error) {\n console.error(error)\n }\n state.loading = false\n if (state.row) {\n state.row.operating = false\n }\n }\n }\n\n /** 保存 */\n const handleSave = runWithLoading(async () => {\n const { model, saveMethod } = props\n\n if (!model) return\n\n model.clearValidate()\n const valid = await model.validate()\n\n if (!valid) return\n\n let item = getInsertData()\n if (saveMethod) {\n const result = await saveMethod(item, state.type, state.parentRow)\n if (result) {\n item = result\n }\n }\n\n state.dataUpdated = false\n\n // 新增\n if (state.type === 'create') {\n insert(item)\n\n return model?.resetData()\n }\n // 更新\n if (state.type === 'update') {\n const { row } = state\n row &&\n model.allKeys.forEach((key) => {\n o(row.data).set(key, o(item).get(key))\n })\n }\n })\n\n const handleDelete = runWithLoading(async (row: TableRow) => {\n const { deleteMethod } = props\n\n if (deleteMethod) {\n await deleteMethod([row.data])\n }\n\n const data = [...(props.data ?? [])]\n\n const parent = visitDataByIndexPath(data, row.indexes.slice(0, -1), childrenKey.value)\n\n if (parent) {\n const children = parent[childrenKey.value]\n if (children) {\n children.splice(row.index, 1)\n } else {\n console.error('行路径不正确')\n }\n } else {\n data.splice(row.index, 1)\n }\n\n if (state.row === row) {\n state.row = undefined\n state.depth = undefined\n }\n\n emit('update:data', data)\n })\n\n function handleClose() {\n state.visible = false\n if (state.row) {\n state.row.isCurrent = false\n }\n state.row = undefined\n state.parentRow = undefined\n state.depth = undefined\n props.model?.resetData()\n insertIndexes.value = []\n }\n\n return {\n state,\n insertIndexes,\n handleDelete,\n handleInsertChild,\n handleInsertToNext,\n handleInsertToPrev,\n handleCreate,\n handleEdit,\n handleCopy,\n handleClose,\n handleSave\n }\n}\n"],"mappings":"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"}
@@ -141,7 +141,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
141
141
  watch([qs, forest], ([qs, forest]) => {
142
142
  const { filterable } = props;
143
143
  if (!filterable || !qs) {
144
- forest.dfs((node) => node.visible = true);
144
+ forest.dfs((node) => {
145
+ node.visible = true;
146
+ });
145
147
  getPanelItemList(forest.roots);
146
148
  return;
147
149
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cascade.js","names":[],"sources":["../../../src/components/cascade/cascade.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n :class=\"[cls.b, bem.is('disabled', disabled), bem.is('multiple', multiple), cls.m(size)]\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size)]\"\n trigger=\"click\"\n ref=\"dropdownRef\"\n :disabled=\"disabled\"\n width=\"auto\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n @update:visible=\"!$event && (qs = '')\"\n >\n <template #trigger>\n <!-- 单选展示 -->\n <u-input\n v-if=\"!multiple\"\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n native-readonly\n :model-value=\"displayedValue\"\n @clear=\"handleClear\"\n >\n <template #suffix>\n <u-icon :class=\"cls.e('arrow')\"><ArrowDown /></u-icon>\n </template>\n </u-input>\n\n <!-- 多选展示 -->\n <template v-if=\"multiple\">\n <span :class=\"cls.e('placeholder')\" v-show=\"!modelValue?.length\">\n {{ placeholder }}\n </span>\n\n <div v-if=\"modelValue?.length\" :class=\"cls.e('tags')\">\n <u-tag\n v-for=\"tag of tags\"\n :key=\"tag.value\"\n :closable=\"!disabled\"\n @close=\"handleCloseTag(tag)\"\n >\n {{ tag.label }}\n </u-tag>\n <u-tag v-if=\"restTag\"> {{ restTag }}+ </u-tag>\n </div>\n\n <transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon\n v-if=\"clearable && modelValue?.length && hovered && !disabled\"\n :class=\"cls.e('clear')\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </u-icon>\n\n <u-icon :class=\"cls.e('arrow')\" v-else><ArrowDown /></u-icon>\n </transition>\n </template>\n </template>\n\n <template #content>\n <!-- 过滤 -->\n <div v-if=\"filterable\" :class=\"cls.e('panel-filter')\">\n <u-input placeholder=\"输入关键字进行过滤\" v-model=\"qs\" :size=\"size\" clearable>\n <template #suffix>\n <u-icon><Search /></u-icon>\n </template>\n </u-input>\n </div>\n\n <div :class=\"cls.e('content')\" v-if=\"panelItemList.length\">\n <UCascadePanelItem\n v-for=\"({ nodes, key }, index) of panelItemList\"\n :data=\"nodes\"\n :key=\"key\"\n :panel-index=\"index\"\n :value=\"selectedNodeKeys[index]\"\n @click=\"handleClick\"\n @check=\"handleCheck\"\n />\n </div>\n\n <div :class=\"cls.e('empty')\" v-else>\n <UEmpty />\n </div>\n </template>\n </u-dropdown>\n\n <!-- 只读 -->\n <template v-else>\n <div :class=\"[cls.m(size)]\" v-if=\"multiple\">\n <div :class=\"cls.e('tags')\">\n <u-tag v-for=\"tag of tags\" :key=\"tag.value\">\n {{ tag.label }}\n </u-tag>\n </div>\n </div>\n <template v-else>\n {{ displayedValue || FORM_EMPTY_CONTENT }}\n </template>\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { Forest, o } from '@cat-kit/core'\nimport { useFormComponent, useFormFallbackProps, useUserAction } from '@veltra/compositions'\nimport { ArrowDown, Close, Search } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { computed, provide, shallowRef, triggerRef, watch } from 'vue'\n\nimport type { CascadeProps, CascadeEmits, DropdownExposed } from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UEmpty } from '../empty'\nimport { UIcon } from '../icon'\nimport { UInput } from '../input'\nimport { UTag } from '../tag'\nimport UCascadePanelItem from './cascade-panel-item.vue'\nimport { CascadeDIKey } from './di'\nimport { CascadeNode } from './node'\nimport { useCheck } from './use-check'\nimport { useDataMap } from './use-data-map'\nimport { useSelect } from './use-select'\n\ndefineOptions({\n name: 'Cascade'\n})\n\nconst props = withDefaults(defineProps<CascadeProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n separator: '/',\n clearable: true,\n disabled: undefined,\n readonly: undefined,\n childrenKey: 'children',\n filterable: false,\n data: () => [],\n visibilityLimit: 3\n})\n\nconst emit = defineEmits<CascadeEmits>()\n\nconst cls = bem('cascade')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\n\nconst forest = computed(() => {\n return new Forest<Record<string, unknown>, any>({\n data: (props.data ?? []) as Record<string, unknown>[],\n childrenKey: props.childrenKey,\n createNode: (data, index, depth, _forest, parent) => {\n if (!data) {\n return new CascadeNode({\n data,\n index,\n depth,\n value: '',\n label: '',\n parent\n })\n }\n\n return new CascadeNode({\n data,\n index,\n depth,\n value: o(data).get(props.valueKey) ?? '',\n label: o(data).get(props.labelKey) ?? '',\n parent\n })\n }\n })\n})\n\nconst { dataMap } = useDataMap({ props, forest })\n\nconst { userAction, isUserActive } = useUserAction()\n\nconst {\n displayedValue,\n selectItem,\n updateSingleValue,\n panelItemList,\n getPanelItemList,\n createPanelItem,\n selectedNodeKeys\n} = useSelect({\n props,\n emit,\n dataMap,\n forest,\n isUserActive,\n dropdownRef\n})\n\nconst { hovered, tags, restTag, updateMultipleValue, handleCloseTag, checkItem, checkedSet } =\n useCheck({\n props,\n forest,\n getPanelItemList,\n emit,\n dataMap,\n isUserActive,\n disabled,\n readonly\n })\n\nconst commitSingleSelect = userAction((item: CascadeNode) => {\n if (!props.strict) {\n updateSingleValue()\n } else if (!item.children?.length) {\n updateSingleValue()\n }\n})\n\nfunction handleClick(panelIndex: number, item: CascadeNode) {\n selectItem(panelIndex, item)\n\n if (!props.multiple) {\n commitSingleSelect(item)\n }\n}\n\nconst handleCheck = userAction((item: CascadeNode, checked: boolean) => {\n checkItem(item, checked)\n})\n\nfunction handleClear() {\n if (props.multiple) {\n checkedSet.value.clear()\n triggerRef(checkedSet)\n updateMultipleValue()\n } else {\n selectedNodeKeys.value = []\n updateSingleValue()\n }\n\n emit('clear')\n}\n\n// 过滤\nconst qs = shallowRef<string>('')\n\nwatch([qs, forest], ([qs, forest]) => {\n const { filterable } = props\n if (!filterable || !qs) {\n forest.dfs((node) => (node.visible = true))\n getPanelItemList(forest.roots)\n return\n }\n\n const cache = new Set<CascadeNode>()\n\n forest.dfs((node) => {\n if (node.label?.toLowerCase().includes(qs.toLowerCase())) {\n node.visible = true\n let parent = node.parent\n while (parent && !cache.has(parent)) {\n parent.visible = true\n cache.add(parent)\n parent = parent.parent\n }\n } else {\n node.visible = false\n }\n })\n\n panelItemList.value = [createPanelItem(forest.roots)]\n})\n\nprovide(CascadeDIKey, {\n cls,\n size,\n disabled,\n readonly,\n cascadeProps: props,\n checkedSet\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"cascade.js","names":[],"sources":["../../../src/components/cascade/cascade.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n :class=\"[cls.b, bem.is('disabled', disabled), bem.is('multiple', multiple), cls.m(size)]\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size)]\"\n trigger=\"click\"\n ref=\"dropdownRef\"\n :disabled=\"disabled\"\n width=\"auto\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n @update:visible=\"!$event && (qs = '')\"\n >\n <template #trigger>\n <!-- 单选展示 -->\n <u-input\n v-if=\"!multiple\"\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n native-readonly\n :model-value=\"displayedValue\"\n @clear=\"handleClear\"\n >\n <template #suffix>\n <u-icon :class=\"cls.e('arrow')\"><ArrowDown /></u-icon>\n </template>\n </u-input>\n\n <!-- 多选展示 -->\n <template v-if=\"multiple\">\n <span :class=\"cls.e('placeholder')\" v-show=\"!modelValue?.length\">\n {{ placeholder }}\n </span>\n\n <div v-if=\"modelValue?.length\" :class=\"cls.e('tags')\">\n <u-tag\n v-for=\"tag of tags\"\n :key=\"tag.value\"\n :closable=\"!disabled\"\n @close=\"handleCloseTag(tag)\"\n >\n {{ tag.label }}\n </u-tag>\n <u-tag v-if=\"restTag\"> {{ restTag }}+ </u-tag>\n </div>\n\n <transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon\n v-if=\"clearable && modelValue?.length && hovered && !disabled\"\n :class=\"cls.e('clear')\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </u-icon>\n\n <u-icon :class=\"cls.e('arrow')\" v-else><ArrowDown /></u-icon>\n </transition>\n </template>\n </template>\n\n <template #content>\n <!-- 过滤 -->\n <div v-if=\"filterable\" :class=\"cls.e('panel-filter')\">\n <u-input placeholder=\"输入关键字进行过滤\" v-model=\"qs\" :size=\"size\" clearable>\n <template #suffix>\n <u-icon><Search /></u-icon>\n </template>\n </u-input>\n </div>\n\n <div :class=\"cls.e('content')\" v-if=\"panelItemList.length\">\n <UCascadePanelItem\n v-for=\"({ nodes, key }, index) of panelItemList\"\n :data=\"nodes\"\n :key=\"key\"\n :panel-index=\"index\"\n :value=\"selectedNodeKeys[index]\"\n @click=\"handleClick\"\n @check=\"handleCheck\"\n />\n </div>\n\n <div :class=\"cls.e('empty')\" v-else>\n <UEmpty />\n </div>\n </template>\n </u-dropdown>\n\n <!-- 只读 -->\n <template v-else>\n <div :class=\"[cls.m(size)]\" v-if=\"multiple\">\n <div :class=\"cls.e('tags')\">\n <u-tag v-for=\"tag of tags\" :key=\"tag.value\">\n {{ tag.label }}\n </u-tag>\n </div>\n </div>\n <template v-else>\n {{ displayedValue || FORM_EMPTY_CONTENT }}\n </template>\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { Forest, o } from '@cat-kit/core'\nimport { useFormComponent, useFormFallbackProps, useUserAction } from '@veltra/compositions'\nimport { ArrowDown, Close, Search } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { computed, provide, shallowRef, triggerRef, watch } from 'vue'\n\nimport type { CascadeProps, CascadeEmits, DropdownExposed } from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UEmpty } from '../empty'\nimport { UIcon } from '../icon'\nimport { UInput } from '../input'\nimport { UTag } from '../tag'\nimport UCascadePanelItem from './cascade-panel-item.vue'\nimport { CascadeDIKey } from './di'\nimport { CascadeNode } from './node'\nimport { useCheck } from './use-check'\nimport { useDataMap } from './use-data-map'\nimport { useSelect } from './use-select'\n\ndefineOptions({\n name: 'Cascade'\n})\n\nconst props = withDefaults(defineProps<CascadeProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n separator: '/',\n clearable: true,\n disabled: undefined,\n readonly: undefined,\n childrenKey: 'children',\n filterable: false,\n data: () => [],\n visibilityLimit: 3\n})\n\nconst emit = defineEmits<CascadeEmits>()\n\nconst cls = bem('cascade')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\n\nconst forest = computed(() => {\n return new Forest<Record<string, unknown>, any>({\n data: (props.data ?? []) as Record<string, unknown>[],\n childrenKey: props.childrenKey,\n createNode: (data, index, depth, _forest, parent) => {\n if (!data) {\n return new CascadeNode({\n data,\n index,\n depth,\n value: '',\n label: '',\n parent\n })\n }\n\n return new CascadeNode({\n data,\n index,\n depth,\n value: o(data).get(props.valueKey) ?? '',\n label: o(data).get(props.labelKey) ?? '',\n parent\n })\n }\n })\n})\n\nconst { dataMap } = useDataMap({ props, forest })\n\nconst { userAction, isUserActive } = useUserAction()\n\nconst {\n displayedValue,\n selectItem,\n updateSingleValue,\n panelItemList,\n getPanelItemList,\n createPanelItem,\n selectedNodeKeys\n} = useSelect({\n props,\n emit,\n dataMap,\n forest,\n isUserActive,\n dropdownRef\n})\n\nconst { hovered, tags, restTag, updateMultipleValue, handleCloseTag, checkItem, checkedSet } =\n useCheck({\n props,\n forest,\n getPanelItemList,\n emit,\n dataMap,\n isUserActive,\n disabled,\n readonly\n })\n\nconst commitSingleSelect = userAction((item: CascadeNode) => {\n if (!props.strict) {\n updateSingleValue()\n } else if (!item.children?.length) {\n updateSingleValue()\n }\n})\n\nfunction handleClick(panelIndex: number, item: CascadeNode) {\n selectItem(panelIndex, item)\n\n if (!props.multiple) {\n commitSingleSelect(item)\n }\n}\n\nconst handleCheck = userAction((item: CascadeNode, checked: boolean) => {\n checkItem(item, checked)\n})\n\nfunction handleClear() {\n if (props.multiple) {\n checkedSet.value.clear()\n triggerRef(checkedSet)\n updateMultipleValue()\n } else {\n selectedNodeKeys.value = []\n updateSingleValue()\n }\n\n emit('clear')\n}\n\n// 过滤\nconst qs = shallowRef<string>('')\n\nwatch([qs, forest], ([qs, forest]) => {\n const { filterable } = props\n if (!filterable || !qs) {\n forest.dfs((node) => {\n node.visible = true\n })\n getPanelItemList(forest.roots)\n return\n }\n\n const cache = new Set<CascadeNode>()\n\n forest.dfs((node) => {\n if (node.label?.toLowerCase().includes(qs.toLowerCase())) {\n node.visible = true\n let parent = node.parent\n while (parent && !cache.has(parent)) {\n parent.visible = true\n cache.add(parent)\n parent = parent.parent\n }\n } else {\n node.visible = false\n }\n })\n\n panelItemList.value = [createPanelItem(forest.roots)]\n})\n\nprovide(CascadeDIKey, {\n cls,\n size,\n disabled,\n readonly,\n cascadeProps: props,\n checkedSet\n})\n</script>\n"],"mappings":"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"}
@@ -11,8 +11,6 @@ declare const __VLS_export: _$vue.DefineComponent<CascadeProps, {}, {}, {}, {},
11
11
  onClear?: (() => any) | undefined;
12
12
  onChange?: ((...args: [value?: string | undefined, label?: string | undefined, item?: Record<string, any> | undefined] | [value: string[], label: string[], data: Record<string, any>[]]) => any) | undefined;
13
13
  }>, {
14
- disabled: boolean;
15
- readonly: boolean;
16
14
  labelKey: string;
17
15
  valueKey: string;
18
16
  childrenKey: string;
@@ -20,8 +18,10 @@ declare const __VLS_export: _$vue.DefineComponent<CascadeProps, {}, {}, {}, {},
20
18
  placeholder: string;
21
19
  clearable: boolean;
22
20
  filterable: boolean;
23
- separator: string;
21
+ disabled: boolean;
22
+ readonly: boolean;
24
23
  visibilityLimit: number;
24
+ separator: string;
25
25
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
26
26
  declare const _default: typeof __VLS_export;
27
27
  //#endregion
@@ -20,8 +20,8 @@ declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {
20
20
  "onUpdate:modelValue"?: ((checked: boolean) => any) | undefined;
21
21
  onChange?: ((checked: boolean) => any) | undefined;
22
22
  }>, {
23
- disabled: boolean;
24
23
  type: _$_veltra_utils0.ColorType;
24
+ disabled: boolean;
25
25
  readonly: boolean;
26
26
  round: boolean;
27
27
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
@@ -14,10 +14,10 @@ declare const __VLS_export: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {},
14
14
  }, string, _$vue.PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
15
15
  "onUpdate:modelValue"?: ((value: any[]) => any) | undefined;
16
16
  }>, {
17
- disabled: boolean;
18
- readonly: boolean;
19
17
  labelKey: string;
20
18
  valueKey: string;
19
+ disabled: boolean;
20
+ readonly: boolean;
21
21
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
22
22
  declare const _default: typeof __VLS_export;
23
23
  //#endregion
@@ -1,18 +1,24 @@
1
1
  import _sfc_main$1 from "../scroll/scroll.js";
2
- import { computed, createBlock, createElementVNode, defineComponent, mergeModels, normalizeClass, onBeforeUnmount, openBlock, shallowRef, unref, useModel, useTemplateRef, watch, withCtx, withKeys, withModifiers } from "vue";
2
+ import { computed, createBlock, createElementVNode, defineComponent, mergeModels, normalizeClass, normalizeStyle, onBeforeUnmount, openBlock, shallowRef, unref, useModel, useTemplateRef, watch, withCtx, withKeys, withModifiers } from "vue";
3
3
  import { bem, zIndex } from "@veltra/utils";
4
4
  import { useFormComponent, useFormFallbackProps } from "@veltra/compositions";
5
- import { EditorState } from "@codemirror/state";
5
+ import { Compartment, EditorState } from "@codemirror/state";
6
6
  import { oneDark } from "@codemirror/theme-one-dark";
7
- import { tooltips } from "@codemirror/view";
7
+ import { ViewPlugin, tooltips } from "@codemirror/view";
8
8
  import { EditorView, basicSetup } from "codemirror";
9
9
  //#region src/components/code-editor/code-editor.vue
10
10
  const _hoisted_1 = { ref: "container" };
11
11
  const _sfc_main = /* @__PURE__ */ defineComponent({
12
+ name: "CodeEditor",
12
13
  __name: "code-editor",
13
14
  props: /* @__PURE__ */ mergeModels({
14
15
  modelValue: {},
15
16
  language: {},
17
+ dark: {
18
+ type: Boolean,
19
+ default: false
20
+ },
21
+ defaultLines: { default: 8 },
16
22
  tips: {},
17
23
  span: {},
18
24
  label: {},
@@ -24,8 +30,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
24
30
  readonly: {
25
31
  type: Boolean,
26
32
  default: void 0
27
- },
28
- size: {}
33
+ }
29
34
  }, {
30
35
  "modelValue": {},
31
36
  "modelModifiers": {}
@@ -36,15 +41,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
36
41
  const model = useModel(__props, "modelValue");
37
42
  const cls = bem("code-editor");
38
43
  const { formProps } = useFormComponent();
39
- const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props]);
40
- const className = computed(() => {
41
- return [
42
- cls.b,
43
- cls.m(size.value),
44
- bem.is("disabled", disabled.value),
45
- bem.is("readonly", readonly.value)
46
- ];
44
+ const { disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
45
+ disabled: false,
46
+ readonly: false
47
47
  });
48
+ const className = computed(() => [
49
+ cls.b,
50
+ bem.is("disabled", disabled.value),
51
+ bem.is("readonly", readonly.value),
52
+ bem.is("dark", props.dark)
53
+ ]);
54
+ const rootStyle = computed(() => ({ "--u-code-editor-default-lines": Math.max(1, props.defaultLines) }));
48
55
  const containerRef = useTemplateRef("container");
49
56
  const editor = shallowRef(null);
50
57
  const langLoaders = {
@@ -53,67 +60,156 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
53
60
  java: () => import("@codemirror/lang-java").then((m) => m.java()),
54
61
  json: () => import("@codemirror/lang-json").then((m) => m.json())
55
62
  };
56
- async function renderEditor() {
57
- if (!containerRef.value) return;
58
- editor.value?.destroy();
59
- const { language } = props;
60
- const extensions = [
63
+ const themeCompartment = new Compartment();
64
+ const editableCompartment = new Compartment();
65
+ const readOnlyCompartment = new Compartment();
66
+ const langCompartment = new Compartment();
67
+ let phantomGutter = null;
68
+ let phantomContainer = null;
69
+ let lastPhantomKey = "";
70
+ function resetPhantomCache() {
71
+ phantomGutter = null;
72
+ phantomContainer = null;
73
+ lastPhantomKey = "";
74
+ }
75
+ /**
76
+ * 在 .cm-lineNumbers 末尾追加占位行号 DOM,使可视行号数量补齐到 defaultLines。
77
+ * CodeMirror 的 lineNumbers() 仅为真实文档行渲染行号,超出部分由本逻辑补全。
78
+ */
79
+ function syncPhantomLineNumbers() {
80
+ const view = editor.value;
81
+ if (!view) return;
82
+ if (!phantomGutter || !phantomGutter.isConnected) phantomGutter = view.dom.querySelector(".cm-gutter.cm-lineNumbers");
83
+ if (!phantomGutter) return;
84
+ if (!phantomContainer) {
85
+ phantomContainer = document.createElement("div");
86
+ phantomContainer.className = "cm-phantom-lines";
87
+ }
88
+ if (phantomContainer.parentElement !== phantomGutter || phantomContainer !== phantomGutter.lastElementChild) phantomGutter.appendChild(phantomContainer);
89
+ const realLines = view.state.doc.lines;
90
+ const target = Math.max(0, Math.max(1, props.defaultLines) - realLines);
91
+ const lineHeight = view.defaultLineHeight;
92
+ const key = `${realLines}|${target}|${lineHeight}`;
93
+ if (key === lastPhantomKey) return;
94
+ lastPhantomKey = key;
95
+ while (phantomContainer.children.length > target) phantomContainer.lastElementChild.remove();
96
+ while (phantomContainer.children.length < target) {
97
+ const el = document.createElement("div");
98
+ el.className = "cm-gutterElement cm-gutterElement-phantom";
99
+ phantomContainer.appendChild(el);
100
+ }
101
+ for (let i = 0; i < target; i++) {
102
+ const el = phantomContainer.children[i];
103
+ const num = String(realLines + i + 1);
104
+ if (el.textContent !== num) el.textContent = num;
105
+ if (lineHeight && el.style.height !== `${lineHeight}px`) el.style.height = `${lineHeight}px`;
106
+ }
107
+ }
108
+ const phantomLineNumbersPlugin = ViewPlugin.fromClass(class {
109
+ update(update) {
110
+ if (update.docChanged || update.geometryChanged) syncPhantomLineNumbers();
111
+ }
112
+ });
113
+ function buildExtensions() {
114
+ return [
61
115
  basicSetup,
62
- oneDark,
63
116
  tooltips({ parent: document.body }),
64
- EditorView.theme({ ".cm-tooltip": { zIndex: zIndex() } })
117
+ EditorView.theme({ ".cm-tooltip": { zIndex: zIndex() } }),
118
+ themeCompartment.of(props.dark ? oneDark : []),
119
+ editableCompartment.of(EditorView.editable.of(!disabled.value)),
120
+ readOnlyCompartment.of(EditorState.readOnly.of(readonly.value)),
121
+ langCompartment.of([]),
122
+ phantomLineNumbersPlugin
65
123
  ];
66
- if (disabled.value) extensions.push(EditorView.editable.of(false));
67
- if (readonly.value) extensions.push(EditorState.readOnly.of(true));
68
- if (language) {
69
- const lang = await langLoaders[language]();
70
- extensions.push(lang);
71
- }
72
- editor.value = new EditorView({
124
+ }
125
+ let editorToken = 0;
126
+ let langToken = 0;
127
+ async function applyLanguage() {
128
+ const view = editor.value;
129
+ if (!view) return;
130
+ const myToken = ++langToken;
131
+ const { language } = props;
132
+ const ext = language ? await langLoaders[language]() : [];
133
+ if (myToken !== langToken || editor.value !== view) return;
134
+ view.dispatch({ effects: langCompartment.reconfigure(ext) });
135
+ }
136
+ function destroyEditor() {
137
+ ++editorToken;
138
+ ++langToken;
139
+ editor.value?.destroy();
140
+ editor.value = null;
141
+ resetPhantomCache();
142
+ }
143
+ function createEditor() {
144
+ destroyEditor();
145
+ const myToken = ++editorToken;
146
+ const parent = containerRef.value;
147
+ if (!parent) return;
148
+ const view = new EditorView({
73
149
  doc: model.value,
74
- extensions,
75
- parent: containerRef.value,
150
+ extensions: buildExtensions(),
151
+ parent,
76
152
  dispatch(tr) {
77
- editor.value?.update([tr]);
78
- if (tr.changes.empty || !tr.docChanged) return;
79
- model.value = tr.state.doc.toString();
153
+ view.update([tr]);
154
+ if (tr.docChanged) model.value = tr.state.doc.toString();
80
155
  }
81
156
  });
157
+ if (myToken !== editorToken) {
158
+ view.destroy();
159
+ return;
160
+ }
161
+ editor.value = view;
162
+ syncPhantomLineNumbers();
163
+ applyLanguage();
82
164
  }
83
- watch([
84
- containerRef,
85
- () => props.language,
86
- disabled,
87
- readonly
88
- ], renderEditor);
165
+ watch(containerRef, (el) => {
166
+ if (el) createEditor();
167
+ else destroyEditor();
168
+ }, {
169
+ immediate: true,
170
+ flush: "post"
171
+ });
172
+ watch(() => props.language, applyLanguage);
173
+ watch(() => props.dark, (dark) => {
174
+ editor.value?.dispatch({ effects: themeCompartment.reconfigure(dark ? oneDark : []) });
175
+ });
176
+ watch(disabled, (v) => {
177
+ editor.value?.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!v)) });
178
+ });
179
+ watch(readonly, (v) => {
180
+ editor.value?.dispatch({ effects: readOnlyCompartment.reconfigure(EditorState.readOnly.of(v)) });
181
+ });
182
+ watch(() => props.defaultLines, syncPhantomLineNumbers);
89
183
  watch([() => props.modelValue, editor], ([v, e]) => {
90
184
  if (!e) return;
91
- if (e.composing || e.state.doc.toJSON().join("\n") === v) return;
92
- const isSelectionOutOfRange = !e?.state.selection.ranges.every((range) => range.anchor < (v?.length ?? 0) && range.head < (v?.length ?? 0));
93
- e?.dispatch({
185
+ if (e.composing) return;
186
+ const next = v ?? "";
187
+ if (e.state.doc.toString() === next) return;
188
+ const valueLength = next.length;
189
+ const inRange = e.state.selection.ranges.every((range) => range.anchor <= valueLength && range.head <= valueLength);
190
+ e.dispatch({
94
191
  changes: {
95
192
  from: 0,
96
- to: e?.state.doc.length,
97
- insert: v
193
+ to: e.state.doc.length,
194
+ insert: next
98
195
  },
99
- selection: isSelectionOutOfRange ? {
196
+ selection: inRange ? e.state.selection : {
100
197
  anchor: 0,
101
198
  head: 0
102
- } : e?.state.selection,
199
+ },
103
200
  scrollIntoView: true
104
201
  });
105
202
  }, { immediate: true });
106
- onBeforeUnmount(() => {
107
- editor.value?.destroy();
108
- });
203
+ onBeforeUnmount(destroyEditor);
109
204
  return (_ctx, _cache) => {
110
205
  return openBlock(), createBlock(unref(_sfc_main$1), {
111
206
  class: normalizeClass(className.value),
207
+ style: normalizeStyle(rootStyle.value),
112
208
  onKeyup: _cache[0] || (_cache[0] = withKeys(withModifiers(() => {}, ["stop"]), ["enter"]))
113
209
  }, {
114
210
  default: withCtx(() => [createElementVNode("div", _hoisted_1, null, 512)]),
115
211
  _: 1
116
- }, 8, ["class"]);
212
+ }, 8, ["class", "style"]);
117
213
  };
118
214
  }
119
215
  });
@@ -1 +1 @@
1
- {"version":3,"file":"code-editor.js","names":[],"sources":["../../../src/components/code-editor/code-editor.vue"],"sourcesContent":["<template>\n <u-scroll :class=\"className\" @keyup.enter.stop>\n <div ref=\"container\"></div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { EditorState } from '@codemirror/state'\nimport { oneDark } from '@codemirror/theme-one-dark'\nimport { tooltips } from '@codemirror/view'\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { bem, zIndex } from '@veltra/utils'\nimport { EditorView, basicSetup } from 'codemirror'\nimport { computed, onBeforeUnmount, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { CodeEditorLang, CodeEditorProps } from '../../types'\nimport { UScroll } from '../scroll'\n\nconst props = withDefaults(defineProps<CodeEditorProps>(), {\n disabled: undefined,\n readonly: undefined\n})\n\nconst model = defineModel<string>()\n\nconst cls = bem('code-editor')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst className = computed<string[]>(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value)\n ]\n})\n\nconst containerRef = useTemplateRef('container')\n\nconst editor = shallowRef<EditorView | null>(null)\n\nconst langLoaders: Record<CodeEditorLang, () => Promise<any>> = {\n js: () => import('@codemirror/lang-javascript').then((m) => m.javascript({ typescript: true })),\n sql: () => import('@codemirror/lang-sql').then((m) => m.sql()),\n java: () => import('@codemirror/lang-java').then((m) => m.java()),\n json: () => import('@codemirror/lang-json').then((m) => m.json())\n}\n\nasync function renderEditor() {\n if (!containerRef.value) return\n editor.value?.destroy()\n\n const { language } = props\n\n const extensions = [\n basicSetup,\n oneDark,\n tooltips({\n parent: document.body\n }),\n EditorView.theme({\n '.cm-tooltip': {\n zIndex: zIndex()\n }\n })\n ]\n\n if (disabled.value) {\n extensions.push(EditorView.editable.of(false))\n }\n if (readonly.value) {\n extensions.push(EditorState.readOnly.of(true))\n }\n if (language) {\n const lang = await langLoaders[language]()\n\n extensions.push(lang)\n }\n\n editor.value = new EditorView({\n doc: model.value,\n extensions,\n parent: containerRef.value,\n\n dispatch(tr) {\n editor.value?.update([tr])\n if (tr.changes.empty || !tr.docChanged) {\n return\n }\n model.value = tr.state.doc.toString()\n }\n })\n}\n\nwatch([containerRef, () => props.language, disabled, readonly], renderEditor)\n\nwatch(\n [() => props.modelValue, editor],\n ([v, e]) => {\n if (!e) return\n\n if (e.composing || e.state.doc.toJSON().join('\\n') === v) {\n return\n }\n const isSelectionOutOfRange = !e?.state.selection.ranges.every(\n (range) => range.anchor < (v?.length ?? 0) && range.head < (v?.length ?? 0)\n )\n e?.dispatch({\n changes: {\n from: 0,\n to: e?.state.doc.length,\n insert: v\n },\n selection: isSelectionOutOfRange ? { anchor: 0, head: 0 } : e?.state.selection,\n scrollIntoView: true\n })\n },\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n editor.value?.destroy()\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBA,MAAM,QAAQ;EAKd,MAAM,QAAQ,SAAmB,SAAA,aAAC;EAElC,MAAM,MAAM,IAAI,cAAa;EAE7B,MAAM,EAAE,cAAc,kBAAiB;EAEvC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,EAAE,EAAE,MAAM,CAAA;EAElF,MAAM,YAAY,eAAyB;AACzC,UAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,MAAM;IACjB,IAAI,GAAG,YAAY,SAAS,MAAM;IAClC,IAAI,GAAG,YAAY,SAAS,MAAK;IACnC;IACD;EAED,MAAM,eAAe,eAAe,YAAW;EAE/C,MAAM,SAAS,WAA8B,KAAI;EAEjD,MAAM,cAA0D;GAC9D,UAAU,OAAO,+BAA+B,MAAM,MAAM,EAAE,WAAW,EAAE,YAAY,MAAM,CAAC,CAAC;GAC/F,WAAW,OAAO,wBAAwB,MAAM,MAAM,EAAE,KAAK,CAAC;GAC9D,YAAY,OAAO,yBAAyB,MAAM,MAAM,EAAE,MAAM,CAAC;GACjE,YAAY,OAAO,yBAAyB,MAAM,MAAM,EAAE,MAAM,CAAA;GAClE;EAEA,eAAe,eAAe;AAC5B,OAAI,CAAC,aAAa,MAAO;AACzB,UAAO,OAAO,SAAQ;GAEtB,MAAM,EAAE,aAAa;GAErB,MAAM,aAAa;IACjB;IACA;IACA,SAAS,EACP,QAAQ,SAAS,MAClB,CAAC;IACF,WAAW,MAAM,EACf,eAAe,EACb,QAAQ,QAAO,EACjB,EACD,CAAA;IACH;AAEA,OAAI,SAAS,MACX,YAAW,KAAK,WAAW,SAAS,GAAG,MAAM,CAAA;AAE/C,OAAI,SAAS,MACX,YAAW,KAAK,YAAY,SAAS,GAAG,KAAK,CAAA;AAE/C,OAAI,UAAU;IACZ,MAAM,OAAO,MAAM,YAAY,WAAU;AAEzC,eAAW,KAAK,KAAI;;AAGtB,UAAO,QAAQ,IAAI,WAAW;IAC5B,KAAK,MAAM;IACX;IACA,QAAQ,aAAa;IAErB,SAAS,IAAI;AACX,YAAO,OAAO,OAAO,CAAC,GAAG,CAAA;AACzB,SAAI,GAAG,QAAQ,SAAS,CAAC,GAAG,WAC1B;AAEF,WAAM,QAAQ,GAAG,MAAM,IAAI,UAAS;;IAEvC,CAAA;;AAGH,QAAM;GAAC;SAAoB,MAAM;GAAU;GAAU;GAAS,EAAE,aAAY;AAE5E,QACE,OAAO,MAAM,YAAY,OAAO,GAC/B,CAAC,GAAG,OAAO;AACV,OAAI,CAAC,EAAG;AAER,OAAI,EAAE,aAAa,EAAE,MAAM,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,EACrD;GAEF,MAAM,wBAAwB,CAAC,GAAG,MAAM,UAAU,OAAO,OACtD,UAAU,MAAM,UAAU,GAAG,UAAU,MAAM,MAAM,QAAQ,GAAG,UAAU,GAC3E;AACA,MAAG,SAAS;IACV,SAAS;KACP,MAAM;KACN,IAAI,GAAG,MAAM,IAAI;KACjB,QAAQ;KACT;IACD,WAAW,wBAAwB;KAAE,QAAQ;KAAG,MAAM;KAAG,GAAG,GAAG,MAAM;IACrE,gBAAgB;IACjB,CAAA;KAEH,EAAE,WAAW,MAAK,CACpB;AAEA,wBAAsB;AACpB,UAAO,OAAO,SAAQ;IACvB;;uBA5HC,YAEW,MAAA,YAAA,EAAA;IAFA,OAAK,eAAE,UAAA,MAAS;IAAG,SAAK,OAAA,OAAA,OAAA,KAAA,SAAA,oBAAN,IAAiB,CAAA,OAAA,CAAA,EAAA,CAAA,QAAA,CAAA;;2BACjB,CAA3B,mBAA2B,OAA3B,YAA2B,MAAA,IAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"code-editor.js","names":[],"sources":["../../../src/components/code-editor/code-editor.vue"],"sourcesContent":["<template>\n <u-scroll :class=\"className\" :style=\"rootStyle\" @keyup.enter.stop>\n <div ref=\"container\"></div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { Compartment, EditorState, type Extension } from '@codemirror/state'\nimport { oneDark } from '@codemirror/theme-one-dark'\nimport { ViewPlugin, tooltips, type ViewUpdate } from '@codemirror/view'\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { bem, zIndex } from '@veltra/utils'\nimport { EditorView, basicSetup } from 'codemirror'\nimport {\n computed,\n onBeforeUnmount,\n shallowRef,\n useTemplateRef,\n watch,\n type CSSProperties\n} from 'vue'\n\nimport type { CodeEditorLang, CodeEditorProps } from '../../types'\nimport { UScroll } from '../scroll'\n\ndefineOptions({ name: 'CodeEditor' })\n\nconst props = withDefaults(defineProps<CodeEditorProps>(), {\n disabled: undefined,\n readonly: undefined,\n dark: false,\n defaultLines: 8\n})\n\nconst model = defineModel<string>()\n\nconst cls = bem('code-editor')\n\nconst { formProps } = useFormComponent()\n\nconst { disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n disabled: false,\n readonly: false\n})\n\nconst className = computed<string[]>(() => [\n cls.b,\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('dark', props.dark)\n])\n\nconst rootStyle = computed<CSSProperties>(() => ({\n '--u-code-editor-default-lines': Math.max(1, props.defaultLines)\n}))\n\nconst containerRef = useTemplateRef('container')\nconst editor = shallowRef<EditorView | null>(null)\n\nconst langLoaders: Record<CodeEditorLang, () => Promise<Extension>> = {\n js: () => import('@codemirror/lang-javascript').then((m) => m.javascript({ typescript: true })),\n sql: () => import('@codemirror/lang-sql').then((m) => m.sql()),\n java: () => import('@codemirror/lang-java').then((m) => m.java()),\n json: () => import('@codemirror/lang-json').then((m) => m.json())\n}\n\nconst themeCompartment = new Compartment()\nconst editableCompartment = new Compartment()\nconst readOnlyCompartment = new Compartment()\nconst langCompartment = new Compartment()\n\nlet phantomGutter: HTMLElement | null = null\nlet phantomContainer: HTMLElement | null = null\nlet lastPhantomKey = ''\n\nfunction resetPhantomCache() {\n phantomGutter = null\n phantomContainer = null\n lastPhantomKey = ''\n}\n\n/**\n * 在 .cm-lineNumbers 末尾追加占位行号 DOM,使可视行号数量补齐到 defaultLines。\n * CodeMirror 的 lineNumbers() 仅为真实文档行渲染行号,超出部分由本逻辑补全。\n */\nfunction syncPhantomLineNumbers() {\n const view = editor.value\n if (!view) return\n\n if (!phantomGutter || !phantomGutter.isConnected) {\n phantomGutter = view.dom.querySelector<HTMLElement>('.cm-gutter.cm-lineNumbers')\n }\n if (!phantomGutter) return\n\n if (!phantomContainer) {\n phantomContainer = document.createElement('div')\n phantomContainer.className = 'cm-phantom-lines'\n }\n if (\n phantomContainer.parentElement !== phantomGutter ||\n phantomContainer !== phantomGutter.lastElementChild\n ) {\n phantomGutter.appendChild(phantomContainer)\n }\n\n const realLines = view.state.doc.lines\n const target = Math.max(0, Math.max(1, props.defaultLines) - realLines)\n const lineHeight = view.defaultLineHeight\n\n const key = `${realLines}|${target}|${lineHeight}`\n if (key === lastPhantomKey) return\n lastPhantomKey = key\n\n while (phantomContainer.children.length > target) {\n phantomContainer.lastElementChild!.remove()\n }\n while (phantomContainer.children.length < target) {\n const el = document.createElement('div')\n el.className = 'cm-gutterElement cm-gutterElement-phantom'\n phantomContainer.appendChild(el)\n }\n for (let i = 0; i < target; i++) {\n const el = phantomContainer.children[i] as HTMLElement\n const num = String(realLines + i + 1)\n if (el.textContent !== num) el.textContent = num\n if (lineHeight && el.style.height !== `${lineHeight}px`) {\n el.style.height = `${lineHeight}px`\n }\n }\n}\n\nconst phantomLineNumbersPlugin = ViewPlugin.fromClass(\n class {\n update(update: ViewUpdate) {\n if (update.docChanged || update.geometryChanged) {\n syncPhantomLineNumbers()\n }\n }\n }\n)\n\nfunction buildExtensions(): Extension[] {\n return [\n basicSetup,\n tooltips({ parent: document.body }),\n EditorView.theme({\n '.cm-tooltip': { zIndex: zIndex() }\n }),\n themeCompartment.of(props.dark ? oneDark : []),\n editableCompartment.of(EditorView.editable.of(!disabled.value)),\n readOnlyCompartment.of(EditorState.readOnly.of(readonly.value)),\n langCompartment.of([]),\n phantomLineNumbersPlugin\n ]\n}\n\nlet editorToken = 0\nlet langToken = 0\n\nasync function applyLanguage() {\n const view = editor.value\n if (!view) return\n const myToken = ++langToken\n const { language } = props\n const ext = language ? await langLoaders[language]() : []\n if (myToken !== langToken || editor.value !== view) return\n view.dispatch({ effects: langCompartment.reconfigure(ext) })\n}\n\nfunction destroyEditor() {\n ++editorToken\n ++langToken\n editor.value?.destroy()\n editor.value = null\n resetPhantomCache()\n}\n\nfunction createEditor() {\n destroyEditor()\n const myToken = ++editorToken\n const parent = containerRef.value\n if (!parent) return\n\n const view = new EditorView({\n doc: model.value,\n extensions: buildExtensions(),\n parent,\n dispatch(tr) {\n view.update([tr])\n if (tr.docChanged) {\n model.value = tr.state.doc.toString()\n }\n }\n })\n\n if (myToken !== editorToken) {\n view.destroy()\n return\n }\n\n editor.value = view\n syncPhantomLineNumbers()\n applyLanguage()\n}\n\nwatch(\n containerRef,\n (el) => {\n if (el) createEditor()\n else destroyEditor()\n },\n { immediate: true, flush: 'post' }\n)\n\nwatch(() => props.language, applyLanguage)\n\nwatch(\n () => props.dark,\n (dark) => {\n editor.value?.dispatch({\n effects: themeCompartment.reconfigure(dark ? oneDark : [])\n })\n }\n)\n\nwatch(disabled, (v) => {\n editor.value?.dispatch({\n effects: editableCompartment.reconfigure(EditorView.editable.of(!v))\n })\n})\n\nwatch(readonly, (v) => {\n editor.value?.dispatch({\n effects: readOnlyCompartment.reconfigure(EditorState.readOnly.of(v))\n })\n})\n\nwatch(() => props.defaultLines, syncPhantomLineNumbers)\n\nwatch(\n [() => props.modelValue, editor],\n ([v, e]) => {\n if (!e) return\n if (e.composing) return\n const next = v ?? ''\n if (e.state.doc.toString() === next) return\n\n const valueLength = next.length\n const inRange = e.state.selection.ranges.every(\n (range) => range.anchor <= valueLength && range.head <= valueLength\n )\n e.dispatch({\n changes: { from: 0, to: e.state.doc.length, insert: next },\n selection: inRange ? e.state.selection : { anchor: 0, head: 0 },\n scrollIntoView: true\n })\n },\n { immediate: true }\n)\n\nonBeforeUnmount(destroyEditor)\n</script>\n"],"mappings":"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"}
@@ -14,6 +14,8 @@ declare const __VLS_export: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {},
14
14
  }>, {
15
15
  disabled: boolean;
16
16
  readonly: boolean;
17
+ dark: boolean;
18
+ defaultLines: number;
17
19
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
18
20
  declare const _default: typeof __VLS_export;
19
21
  //#endregion