@milkdown/crepe 7.8.0 → 7.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/lib/cjs/confirm-CNveM9QH.js +26 -0
  2. package/lib/cjs/confirm-CNveM9QH.js.map +1 -0
  3. package/lib/cjs/edit-BUtBJHpV.js +24 -0
  4. package/lib/cjs/edit-BUtBJHpV.js.map +1 -0
  5. package/lib/cjs/functions-BAY51plB.js +39 -0
  6. package/lib/cjs/functions-BAY51plB.js.map +1 -0
  7. package/lib/cjs/image-BXLkOVnO.js +24 -0
  8. package/lib/cjs/image-BXLkOVnO.js.map +1 -0
  9. package/lib/cjs/{index-DAiGM2G1.js → index-B7gqgc1H.js} +484 -204
  10. package/lib/cjs/index-B7gqgc1H.js.map +1 -0
  11. package/lib/cjs/{index-Dub20F3z.js → index-B91KhPew.js} +4 -4
  12. package/lib/cjs/index-B91KhPew.js.map +1 -0
  13. package/lib/cjs/{index-nrFkJeLW.js → index-BsrJn8Jp.js} +22 -7
  14. package/lib/cjs/index-BsrJn8Jp.js.map +1 -0
  15. package/lib/cjs/{index-BReSN-JQ.js → index-C2CAbC2F.js} +2 -2
  16. package/lib/cjs/{index-BReSN-JQ.js.map → index-C2CAbC2F.js.map} +1 -1
  17. package/lib/cjs/{index-CGies6Iv.js → index-CnyNb_OH.js} +45 -45
  18. package/lib/cjs/index-CnyNb_OH.js.map +1 -0
  19. package/lib/cjs/{index-CJdEvN3_.js → index-CoTb-QdE.js} +123 -105
  20. package/lib/cjs/index-CoTb-QdE.js.map +1 -0
  21. package/lib/cjs/index-DEs_IHHy.js +91 -0
  22. package/lib/cjs/index-DEs_IHHy.js.map +1 -0
  23. package/lib/cjs/index-DGAwtnNK.js +349 -0
  24. package/lib/cjs/index-DGAwtnNK.js.map +1 -0
  25. package/lib/cjs/index-DLIudQKW.js +126 -0
  26. package/lib/cjs/index-DLIudQKW.js.map +1 -0
  27. package/lib/cjs/index-Dw6lXgs6.js +81 -0
  28. package/lib/cjs/index-Dw6lXgs6.js.map +1 -0
  29. package/lib/cjs/{index-AlHHvSR_.js → index-xbwf60wt.js} +1 -6
  30. package/lib/cjs/{index-AlHHvSR_.js.map → index-xbwf60wt.js.map} +1 -1
  31. package/lib/cjs/{index-CvmlYYXX.js → index-xbxqAqH2.js} +21 -7
  32. package/lib/cjs/index-xbxqAqH2.js.map +1 -0
  33. package/lib/cjs/index.js +6 -6
  34. package/lib/cjs/plus-XLomtlXf.js +24 -0
  35. package/lib/cjs/plus-XLomtlXf.js.map +1 -0
  36. package/lib/cjs/remove-Ba-ypwBf.js +17 -0
  37. package/lib/cjs/remove-Ba-ypwBf.js.map +1 -0
  38. package/lib/esm/confirm-DtE-HkVd.js +24 -0
  39. package/lib/esm/confirm-DtE-HkVd.js.map +1 -0
  40. package/lib/esm/edit-D--t_JAb.js +22 -0
  41. package/lib/esm/edit-D--t_JAb.js.map +1 -0
  42. package/lib/esm/functions-DlJPkGmE.js +36 -0
  43. package/lib/esm/functions-DlJPkGmE.js.map +1 -0
  44. package/lib/esm/image-DoB1o1sl.js +22 -0
  45. package/lib/esm/image-DoB1o1sl.js.map +1 -0
  46. package/lib/esm/index-BAQT-9au.js +347 -0
  47. package/lib/esm/index-BAQT-9au.js.map +1 -0
  48. package/lib/esm/{index-DOrkOhki.js → index-BCvtgOeI.js} +4 -4
  49. package/lib/esm/index-BCvtgOeI.js.map +1 -0
  50. package/lib/esm/{index-x2oo_GmY.js → index-BDZ_pnSv.js} +122 -104
  51. package/lib/esm/index-BDZ_pnSv.js.map +1 -0
  52. package/lib/esm/{index-D6fLMv29.js → index-BPG8iO8t.js} +2 -6
  53. package/lib/esm/{index-D6fLMv29.js.map → index-BPG8iO8t.js.map} +1 -1
  54. package/lib/esm/{index-DcRgwPLd.js → index-BUBXHhHG.js} +18 -3
  55. package/lib/esm/index-BUBXHhHG.js.map +1 -0
  56. package/lib/esm/{index-CsYl2WR5.js → index-Bvz1Yyiz.js} +2 -2
  57. package/lib/esm/{index-CsYl2WR5.js.map → index-Bvz1Yyiz.js.map} +1 -1
  58. package/lib/esm/index-C1aVAv1l.js +124 -0
  59. package/lib/esm/index-C1aVAv1l.js.map +1 -0
  60. package/lib/esm/{index-CEOsxgzJ.js → index-CM4urRY9.js} +470 -190
  61. package/lib/esm/index-CM4urRY9.js.map +1 -0
  62. package/lib/esm/{index-BFsG6770.js → index-ChR5Qhyf.js} +17 -3
  63. package/lib/esm/index-ChR5Qhyf.js.map +1 -0
  64. package/lib/esm/index-CwMVnVeI.js +89 -0
  65. package/lib/esm/index-CwMVnVeI.js.map +1 -0
  66. package/lib/esm/{index-BwTxn2hs.js → index-Dc_wWopW.js} +46 -46
  67. package/lib/esm/index-Dc_wWopW.js.map +1 -0
  68. package/lib/esm/index-E8UgFLeN.js +79 -0
  69. package/lib/esm/index-E8UgFLeN.js.map +1 -0
  70. package/lib/esm/index.js +6 -6
  71. package/lib/esm/plus-lrX0Q75O.js +22 -0
  72. package/lib/esm/plus-lrX0Q75O.js.map +1 -0
  73. package/lib/esm/remove-D3g0Cd6_.js +15 -0
  74. package/lib/esm/remove-D3g0Cd6_.js.map +1 -0
  75. package/lib/theme/_internal/classic-common.css +6 -0
  76. package/lib/theme/common/block-edit.css +23 -23
  77. package/lib/theme/common/code-mirror.css +43 -44
  78. package/lib/theme/common/image-block.css +79 -81
  79. package/lib/theme/common/latex.css +6 -6
  80. package/lib/theme/common/link-tooltip.css +21 -21
  81. package/lib/theme/common/list-item.css +11 -10
  82. package/lib/theme/common/table.css +39 -39
  83. package/lib/theme/common/toolbar.css +8 -8
  84. package/lib/tsconfig.tsbuildinfo +1 -0
  85. package/lib/types/core/crepe.d.ts +6 -6
  86. package/lib/types/core/crepe.d.ts.map +1 -1
  87. package/lib/types/core/slice.d.ts.map +1 -1
  88. package/lib/types/feature/block-edit/handle/component.d.ts +4 -8
  89. package/lib/types/feature/block-edit/handle/component.d.ts.map +1 -1
  90. package/lib/types/feature/block-edit/handle/index.d.ts +1 -1
  91. package/lib/types/feature/block-edit/handle/index.d.ts.map +1 -1
  92. package/lib/types/feature/block-edit/index.d.ts.map +1 -1
  93. package/lib/types/feature/block-edit/menu/component.d.ts +8 -11
  94. package/lib/types/feature/block-edit/menu/component.d.ts.map +1 -1
  95. package/lib/types/feature/block-edit/menu/config.d.ts.map +1 -1
  96. package/lib/types/feature/block-edit/menu/index.d.ts.map +1 -1
  97. package/lib/types/feature/block-edit/menu/utils.d.ts +2 -3
  98. package/lib/types/feature/block-edit/menu/utils.d.ts.map +1 -1
  99. package/lib/types/feature/code-mirror/index.d.ts +3 -4
  100. package/lib/types/feature/code-mirror/index.d.ts.map +1 -1
  101. package/lib/types/feature/cursor/index.d.ts.map +1 -1
  102. package/lib/types/feature/image-block/index.d.ts.map +1 -1
  103. package/lib/types/feature/index.d.ts +4 -4
  104. package/lib/types/feature/index.d.ts.map +1 -1
  105. package/lib/types/feature/latex/index.d.ts.map +1 -1
  106. package/lib/types/feature/latex/inline-tooltip/component.d.ts +6 -10
  107. package/lib/types/feature/latex/inline-tooltip/component.d.ts.map +1 -1
  108. package/lib/types/feature/latex/inline-tooltip/view.d.ts.map +1 -1
  109. package/lib/types/feature/latex/input-rule.d.ts.map +1 -1
  110. package/lib/types/feature/latex/remark.d.ts.map +1 -1
  111. package/lib/types/feature/link-tooltip/index.d.ts.map +1 -1
  112. package/lib/types/feature/list-item/index.d.ts.map +1 -1
  113. package/lib/types/feature/placeholder/index.d.ts.map +1 -1
  114. package/lib/types/feature/shared.d.ts +1 -2
  115. package/lib/types/feature/shared.d.ts.map +1 -1
  116. package/lib/types/feature/table/index.d.ts.map +1 -1
  117. package/lib/types/feature/toolbar/component.d.ts +9 -12
  118. package/lib/types/feature/toolbar/component.d.ts.map +1 -1
  119. package/lib/types/feature/toolbar/index.d.ts.map +1 -1
  120. package/lib/types/icons/align-center.d.ts +1 -1
  121. package/lib/types/icons/align-center.d.ts.map +1 -1
  122. package/lib/types/icons/align-left.d.ts +1 -1
  123. package/lib/types/icons/align-left.d.ts.map +1 -1
  124. package/lib/types/icons/align-right.d.ts +1 -1
  125. package/lib/types/icons/align-right.d.ts.map +1 -1
  126. package/lib/types/icons/bold.d.ts +1 -1
  127. package/lib/types/icons/bold.d.ts.map +1 -1
  128. package/lib/types/icons/bullet-list.d.ts +1 -1
  129. package/lib/types/icons/bullet-list.d.ts.map +1 -1
  130. package/lib/types/icons/bullet.d.ts +1 -1
  131. package/lib/types/icons/bullet.d.ts.map +1 -1
  132. package/lib/types/icons/caption.d.ts +1 -1
  133. package/lib/types/icons/caption.d.ts.map +1 -1
  134. package/lib/types/icons/check-box-checked.d.ts +1 -1
  135. package/lib/types/icons/check-box-checked.d.ts.map +1 -1
  136. package/lib/types/icons/check-box-unchecked.d.ts +1 -1
  137. package/lib/types/icons/check-box-unchecked.d.ts.map +1 -1
  138. package/lib/types/icons/chevron-down.d.ts +1 -1
  139. package/lib/types/icons/chevron-down.d.ts.map +1 -1
  140. package/lib/types/icons/clear.d.ts +1 -1
  141. package/lib/types/icons/clear.d.ts.map +1 -1
  142. package/lib/types/icons/code.d.ts +1 -1
  143. package/lib/types/icons/code.d.ts.map +1 -1
  144. package/lib/types/icons/confirm.d.ts +1 -1
  145. package/lib/types/icons/confirm.d.ts.map +1 -1
  146. package/lib/types/icons/copy.d.ts +1 -1
  147. package/lib/types/icons/copy.d.ts.map +1 -1
  148. package/lib/types/icons/divider.d.ts +1 -1
  149. package/lib/types/icons/divider.d.ts.map +1 -1
  150. package/lib/types/icons/drag-handle.d.ts +1 -1
  151. package/lib/types/icons/drag-handle.d.ts.map +1 -1
  152. package/lib/types/icons/edit.d.ts +1 -1
  153. package/lib/types/icons/edit.d.ts.map +1 -1
  154. package/lib/types/icons/functions.d.ts +1 -1
  155. package/lib/types/icons/functions.d.ts.map +1 -1
  156. package/lib/types/icons/h1.d.ts +1 -1
  157. package/lib/types/icons/h1.d.ts.map +1 -1
  158. package/lib/types/icons/h2.d.ts +1 -1
  159. package/lib/types/icons/h2.d.ts.map +1 -1
  160. package/lib/types/icons/h3.d.ts +1 -1
  161. package/lib/types/icons/h3.d.ts.map +1 -1
  162. package/lib/types/icons/h4.d.ts +1 -1
  163. package/lib/types/icons/h4.d.ts.map +1 -1
  164. package/lib/types/icons/h5.d.ts +1 -1
  165. package/lib/types/icons/h5.d.ts.map +1 -1
  166. package/lib/types/icons/h6.d.ts +1 -1
  167. package/lib/types/icons/h6.d.ts.map +1 -1
  168. package/lib/types/icons/image.d.ts +1 -1
  169. package/lib/types/icons/image.d.ts.map +1 -1
  170. package/lib/types/icons/italic.d.ts +1 -1
  171. package/lib/types/icons/italic.d.ts.map +1 -1
  172. package/lib/types/icons/link.d.ts +1 -1
  173. package/lib/types/icons/link.d.ts.map +1 -1
  174. package/lib/types/icons/menu.d.ts +1 -1
  175. package/lib/types/icons/menu.d.ts.map +1 -1
  176. package/lib/types/icons/ordered-list.d.ts +1 -1
  177. package/lib/types/icons/ordered-list.d.ts.map +1 -1
  178. package/lib/types/icons/plus.d.ts +1 -1
  179. package/lib/types/icons/plus.d.ts.map +1 -1
  180. package/lib/types/icons/quote.d.ts +1 -1
  181. package/lib/types/icons/quote.d.ts.map +1 -1
  182. package/lib/types/icons/remove.d.ts +1 -1
  183. package/lib/types/icons/remove.d.ts.map +1 -1
  184. package/lib/types/icons/search.d.ts +1 -1
  185. package/lib/types/icons/search.d.ts.map +1 -1
  186. package/lib/types/icons/strikethrough.d.ts +1 -1
  187. package/lib/types/icons/strikethrough.d.ts.map +1 -1
  188. package/lib/types/icons/table.d.ts +1 -1
  189. package/lib/types/icons/table.d.ts.map +1 -1
  190. package/lib/types/icons/text.d.ts +1 -1
  191. package/lib/types/icons/text.d.ts.map +1 -1
  192. package/lib/types/icons/todo-list.d.ts +1 -1
  193. package/lib/types/icons/todo-list.d.ts.map +1 -1
  194. package/lib/types/icons/visibility-off.d.ts +1 -1
  195. package/lib/types/icons/visibility-off.d.ts.map +1 -1
  196. package/package.json +4 -26
  197. package/src/core/crepe.ts +13 -12
  198. package/src/core/slice.ts +2 -0
  199. package/src/feature/block-edit/handle/component.tsx +60 -0
  200. package/src/feature/block-edit/handle/index.ts +22 -14
  201. package/src/feature/block-edit/index.ts +3 -1
  202. package/src/feature/block-edit/menu/component.tsx +237 -0
  203. package/src/feature/block-edit/menu/config.ts +6 -3
  204. package/src/feature/block-edit/menu/index.ts +38 -18
  205. package/src/feature/block-edit/menu/utils.ts +3 -3
  206. package/src/feature/code-mirror/index.ts +20 -20
  207. package/src/feature/cursor/index.ts +1 -1
  208. package/src/feature/image-block/index.ts +3 -1
  209. package/src/feature/index.ts +5 -4
  210. package/src/feature/latex/index.ts +8 -8
  211. package/src/feature/latex/inline-tooltip/component.tsx +57 -0
  212. package/src/feature/latex/inline-tooltip/view.ts +30 -17
  213. package/src/feature/latex/input-rule.ts +4 -3
  214. package/src/feature/latex/remark.ts +3 -2
  215. package/src/feature/link-tooltip/index.ts +3 -1
  216. package/src/feature/list-item/index.ts +8 -16
  217. package/src/feature/placeholder/index.ts +6 -3
  218. package/src/feature/shared.ts +1 -2
  219. package/src/feature/table/index.ts +2 -0
  220. package/src/feature/toolbar/component.tsx +256 -0
  221. package/src/feature/toolbar/index.ts +34 -17
  222. package/src/icons/align-center.ts +1 -3
  223. package/src/icons/align-left.ts +1 -3
  224. package/src/icons/align-right.ts +1 -3
  225. package/src/icons/bold.ts +1 -3
  226. package/src/icons/bullet-list.ts +1 -3
  227. package/src/icons/bullet.ts +1 -3
  228. package/src/icons/caption.ts +1 -3
  229. package/src/icons/check-box-checked.ts +1 -3
  230. package/src/icons/check-box-unchecked.ts +1 -3
  231. package/src/icons/chevron-down.ts +1 -3
  232. package/src/icons/clear.ts +1 -3
  233. package/src/icons/code.ts +1 -3
  234. package/src/icons/confirm.ts +1 -3
  235. package/src/icons/copy.ts +1 -3
  236. package/src/icons/divider.ts +1 -3
  237. package/src/icons/drag-handle.ts +1 -3
  238. package/src/icons/edit.ts +1 -3
  239. package/src/icons/functions.ts +1 -3
  240. package/src/icons/h1.ts +1 -3
  241. package/src/icons/h2.ts +1 -3
  242. package/src/icons/h3.ts +1 -3
  243. package/src/icons/h4.ts +1 -3
  244. package/src/icons/h5.ts +1 -3
  245. package/src/icons/h6.ts +1 -3
  246. package/src/icons/image.ts +1 -3
  247. package/src/icons/italic.ts +1 -3
  248. package/src/icons/link.ts +1 -3
  249. package/src/icons/menu.ts +1 -3
  250. package/src/icons/ordered-list.ts +1 -3
  251. package/src/icons/plus.ts +1 -3
  252. package/src/icons/quote.ts +1 -3
  253. package/src/icons/remove.ts +1 -3
  254. package/src/icons/search.ts +1 -3
  255. package/src/icons/strikethrough.ts +1 -3
  256. package/src/icons/table.ts +1 -3
  257. package/src/icons/text.ts +1 -3
  258. package/src/icons/todo-list.ts +1 -3
  259. package/src/icons/visibility-off.ts +1 -3
  260. package/src/theme/_internal/classic-common.css +6 -0
  261. package/src/theme/common/block-edit.css +2 -2
  262. package/src/theme/common/code-mirror.css +5 -6
  263. package/src/theme/common/image-block.css +9 -11
  264. package/src/theme/common/latex.css +1 -1
  265. package/src/theme/common/link-tooltip.css +2 -2
  266. package/src/theme/common/list-item.css +3 -2
  267. package/src/theme/common/table.css +2 -2
  268. package/src/theme/common/toolbar.css +1 -1
  269. package/lib/cjs/functions-Dk90yOUc.js +0 -690
  270. package/lib/cjs/functions-Dk90yOUc.js.map +0 -1
  271. package/lib/cjs/index-CGies6Iv.js.map +0 -1
  272. package/lib/cjs/index-CJdEvN3_.js.map +0 -1
  273. package/lib/cjs/index-CvmlYYXX.js.map +0 -1
  274. package/lib/cjs/index-D3lu92SA.js +0 -39
  275. package/lib/cjs/index-D3lu92SA.js.map +0 -1
  276. package/lib/cjs/index-DAiGM2G1.js.map +0 -1
  277. package/lib/cjs/index-DKY_Kri2.js +0 -272
  278. package/lib/cjs/index-DKY_Kri2.js.map +0 -1
  279. package/lib/cjs/index-DQll67YS.js +0 -65
  280. package/lib/cjs/index-DQll67YS.js.map +0 -1
  281. package/lib/cjs/index-Dub20F3z.js.map +0 -1
  282. package/lib/cjs/index-hPk2gbSt.js +0 -35
  283. package/lib/cjs/index-hPk2gbSt.js.map +0 -1
  284. package/lib/cjs/index-nrFkJeLW.js.map +0 -1
  285. package/lib/esm/functions-Bsik6ikd.js +0 -652
  286. package/lib/esm/functions-Bsik6ikd.js.map +0 -1
  287. package/lib/esm/index-B3KiKTSt.js +0 -63
  288. package/lib/esm/index-B3KiKTSt.js.map +0 -1
  289. package/lib/esm/index-BFsG6770.js.map +0 -1
  290. package/lib/esm/index-BwTxn2hs.js.map +0 -1
  291. package/lib/esm/index-CBrOT1fW.js +0 -37
  292. package/lib/esm/index-CBrOT1fW.js.map +0 -1
  293. package/lib/esm/index-CEOsxgzJ.js.map +0 -1
  294. package/lib/esm/index-Cuk7cL-r.js +0 -33
  295. package/lib/esm/index-Cuk7cL-r.js.map +0 -1
  296. package/lib/esm/index-DOrkOhki.js.map +0 -1
  297. package/lib/esm/index-DcRgwPLd.js.map +0 -1
  298. package/lib/esm/index-H9uklzH0.js +0 -270
  299. package/lib/esm/index-H9uklzH0.js.map +0 -1
  300. package/lib/esm/index-x2oo_GmY.js.map +0 -1
  301. package/src/feature/block-edit/handle/component.ts +0 -54
  302. package/src/feature/block-edit/menu/component.ts +0 -241
  303. package/src/feature/latex/inline-tooltip/component.ts +0 -38
  304. package/src/feature/toolbar/component.ts +0 -236
@@ -0,0 +1,237 @@
1
+ import type { Ctx } from '@milkdown/kit/ctx'
2
+
3
+ import { Icon } from '@milkdown/kit/component'
4
+ import {
5
+ computed,
6
+ defineComponent,
7
+ onUnmounted,
8
+ ref,
9
+ watch,
10
+ watchEffect,
11
+ type Ref,
12
+ h,
13
+ } from 'vue'
14
+
15
+ import type { BlockEditFeatureConfig } from '..'
16
+
17
+ import { getGroups } from './config'
18
+
19
+ h
20
+
21
+ type MenuProps = {
22
+ ctx: Ctx
23
+ show: Ref<boolean>
24
+ filter: Ref<string>
25
+ hide: () => void
26
+ config?: BlockEditFeatureConfig
27
+ }
28
+
29
+ export const Menu = defineComponent<MenuProps>({
30
+ props: {
31
+ ctx: {
32
+ type: Object,
33
+ required: true,
34
+ },
35
+ show: {
36
+ type: Object,
37
+ required: true,
38
+ },
39
+ filter: {
40
+ type: Object,
41
+ required: true,
42
+ },
43
+ hide: {
44
+ type: Function,
45
+ required: true,
46
+ },
47
+ config: {
48
+ type: Object,
49
+ required: false,
50
+ },
51
+ },
52
+ setup({ ctx, show, filter, hide, config }) {
53
+ const host = ref<HTMLElement>()
54
+ const groupInfo = computed(() => getGroups(filter.value, config, ctx))
55
+ const hoverIndex = ref(0)
56
+ const prevMousePosition = ref({ x: -999, y: -999 })
57
+
58
+ const onPointerMove = (e: MouseEvent) => {
59
+ const { x, y } = e
60
+ prevMousePosition.value = { x, y }
61
+ }
62
+
63
+ watch([groupInfo, show], () => {
64
+ const { size } = groupInfo.value
65
+ if (size === 0 && show.value) hide()
66
+ else if (hoverIndex.value >= size) hoverIndex.value = 0
67
+ })
68
+
69
+ const onHover = (
70
+ index: number | ((prev: number) => number),
71
+ after?: (index: number) => void
72
+ ) => {
73
+ const prevHoverIndex = hoverIndex.value
74
+ const next = typeof index === 'function' ? index(prevHoverIndex) : index
75
+ after?.(next)
76
+ hoverIndex.value = next
77
+ }
78
+
79
+ const scrollToIndex = (index: number) => {
80
+ const target = host.value?.querySelector<HTMLElement>(
81
+ `[data-index="${index}"]`
82
+ )
83
+ const scrollRoot = host.value?.querySelector<HTMLElement>('.menu-groups')
84
+
85
+ if (!target || !scrollRoot) return
86
+
87
+ scrollRoot.scrollTop = target.offsetTop - scrollRoot.offsetTop
88
+ }
89
+
90
+ const runByIndex = (index: number) => {
91
+ const item = groupInfo.value.groups
92
+ .flatMap((group) => group.items)
93
+ .at(index)
94
+ if (item && ctx) item.onRun(ctx)
95
+
96
+ hide()
97
+ }
98
+
99
+ const onKeydown = (e: KeyboardEvent) => {
100
+ const { size, groups } = groupInfo.value
101
+ if (e.key === 'Escape') {
102
+ e.preventDefault()
103
+ hide?.()
104
+ return
105
+ }
106
+
107
+ if (e.key === 'ArrowDown') {
108
+ e.preventDefault()
109
+ return onHover(
110
+ (index) => (index < size - 1 ? index + 1 : index),
111
+ scrollToIndex
112
+ )
113
+ }
114
+
115
+ if (e.key === 'ArrowUp') {
116
+ e.preventDefault()
117
+ return onHover(
118
+ (index) => (index <= 0 ? index : index - 1),
119
+ scrollToIndex
120
+ )
121
+ }
122
+
123
+ if (e.key === 'ArrowLeft') {
124
+ e.preventDefault()
125
+ return onHover((index) => {
126
+ const group = groups.find(
127
+ (group) => group.range[0] <= index && group.range[1] > index
128
+ )
129
+ if (!group) return index
130
+
131
+ const prevGroup = groups[groups.indexOf(group) - 1]
132
+ if (!prevGroup) return index
133
+
134
+ return prevGroup.range[1] - 1
135
+ }, scrollToIndex)
136
+ }
137
+
138
+ if (e.key === 'ArrowRight') {
139
+ e.preventDefault()
140
+ return onHover((index) => {
141
+ const group = groups.find(
142
+ (group) => group.range[0] <= index && group.range[1] > index
143
+ )
144
+ if (!group) return index
145
+
146
+ const nextGroup = groups[groups.indexOf(group) + 1]
147
+ if (!nextGroup) return index
148
+
149
+ return nextGroup.range[0]
150
+ }, scrollToIndex)
151
+ }
152
+
153
+ if (e.key === 'Enter') {
154
+ e.preventDefault()
155
+ runByIndex(hoverIndex.value)
156
+ }
157
+ }
158
+
159
+ const getOnPointerEnter = (index: number) => (e: MouseEvent) => {
160
+ const prevPos = prevMousePosition.value
161
+ if (!prevPos) return
162
+
163
+ const { x, y } = e
164
+ if (x === prevPos.x && y === prevPos.y) return
165
+
166
+ onHover(index)
167
+ }
168
+
169
+ watchEffect(() => {
170
+ const isShown = show.value
171
+ if (isShown) {
172
+ window.addEventListener('keydown', onKeydown, { capture: true })
173
+ } else {
174
+ window.removeEventListener('keydown', onKeydown, { capture: true })
175
+ }
176
+ })
177
+ onUnmounted(() => {
178
+ window.removeEventListener('keydown', onKeydown, { capture: true })
179
+ })
180
+
181
+ return () => {
182
+ return (
183
+ <div ref={host} onPointerdown={(e) => e.preventDefault()}>
184
+ <nav class="tab-group">
185
+ <ul>
186
+ {groupInfo.value.groups.map((group) => (
187
+ <li
188
+ key={group.key}
189
+ onPointerdown={() => onHover(group.range[0], scrollToIndex)}
190
+ class={
191
+ hoverIndex.value >= group.range[0] &&
192
+ hoverIndex.value < group.range[1]
193
+ ? 'selected'
194
+ : ''
195
+ }
196
+ >
197
+ {group.label}
198
+ </li>
199
+ ))}
200
+ </ul>
201
+ </nav>
202
+ <div class="menu-groups" onPointermove={onPointerMove}>
203
+ {groupInfo.value.groups.map((group) => (
204
+ <div key={group.key} class="menu-group">
205
+ <h6>{group.label}</h6>
206
+ <ul>
207
+ {group.items.map((item) => (
208
+ <li
209
+ key={item.key}
210
+ data-index={item.index}
211
+ class={hoverIndex.value === item.index ? 'hover' : ''}
212
+ onPointerenter={getOnPointerEnter(item.index)}
213
+ onPointerdown={() => {
214
+ host.value
215
+ ?.querySelector(`[data-index="${item.index}"]`)
216
+ ?.classList.add('active')
217
+ }}
218
+ onPointerup={() => {
219
+ host.value
220
+ ?.querySelector(`[data-index="${item.index}"]`)
221
+ ?.classList.remove('active')
222
+ runByIndex(item.index)
223
+ }}
224
+ >
225
+ <Icon icon={item.icon} />
226
+ <span>{item.label}</span>
227
+ </li>
228
+ ))}
229
+ </ul>
230
+ </div>
231
+ ))}
232
+ </div>
233
+ </div>
234
+ )
235
+ }
236
+ },
237
+ })
@@ -1,6 +1,7 @@
1
+ import type { Ctx } from '@milkdown/kit/ctx'
2
+
1
3
  import { imageBlockSchema } from '@milkdown/kit/component/image-block'
2
4
  import { editorViewCtx } from '@milkdown/kit/core'
3
- import type { Ctx } from '@milkdown/kit/ctx'
4
5
  import {
5
6
  blockquoteSchema,
6
7
  bulletListSchema,
@@ -13,6 +14,10 @@ import {
13
14
  } from '@milkdown/kit/preset/commonmark'
14
15
  import { createTable } from '@milkdown/kit/preset/gfm'
15
16
  import { TextSelection } from '@milkdown/kit/prose/state'
17
+
18
+ import type { BlockEditFeatureConfig } from '../index'
19
+ import type { MenuItemGroup } from './utils'
20
+
16
21
  import { CrepeFeature } from '../../..'
17
22
  import { FeaturesCtx } from '../../../core/slice'
18
23
  import {
@@ -33,9 +38,7 @@ import {
33
38
  textIcon,
34
39
  todoListIcon,
35
40
  } from '../../../icons'
36
- import type { BlockEditFeatureConfig } from '../index'
37
41
  import { GroupBuilder } from './group-builder'
38
- import type { MenuItemGroup } from './utils'
39
42
  import {
40
43
  clearContentAndAddBlockType,
41
44
  clearContentAndSetBlockType,
@@ -1,17 +1,19 @@
1
+ import type { Ctx } from '@milkdown/kit/ctx'
2
+ import type { EditorView } from '@milkdown/kit/prose/view'
3
+
4
+ import { SlashProvider, slashFactory } from '@milkdown/kit/plugin/slash'
1
5
  import {
2
6
  TextSelection,
3
7
  type PluginView,
4
8
  type Selection,
5
9
  } from '@milkdown/kit/prose/state'
6
- import type { EditorView } from '@milkdown/kit/prose/view'
7
- import { SlashProvider, slashFactory } from '@milkdown/kit/plugin/slash'
8
- import type { Ctx } from '@milkdown/kit/ctx'
9
- import type { AtomicoThis } from 'atomico/types/dom'
10
10
  import { $ctx } from '@milkdown/kit/utils'
11
- import { defIfNotExists, isInCodeBlock, isInList } from '../../../utils'
11
+ import { createApp, ref, type App, type Ref } from 'vue'
12
+
12
13
  import type { BlockEditFeatureConfig } from '../index'
13
- import type { MenuProps } from './component'
14
- import { MenuElement } from './component'
14
+
15
+ import { isInCodeBlock, isInList } from '../../../utils'
16
+ import { Menu } from './component'
15
17
 
16
18
  export const menu = slashFactory('CREPE_MENU')
17
19
 
@@ -28,7 +30,6 @@ export const menuAPI = $ctx(
28
30
  'menuAPICtx'
29
31
  )
30
32
 
31
- defIfNotExists('milkdown-slash-menu', MenuElement)
32
33
  export function configureMenu(ctx: Ctx, config?: BlockEditFeatureConfig) {
33
34
  ctx.set(menu.key, {
34
35
  view: (view) => new MenuView(ctx, view, config),
@@ -36,16 +37,34 @@ export function configureMenu(ctx: Ctx, config?: BlockEditFeatureConfig) {
36
37
  }
37
38
 
38
39
  class MenuView implements PluginView {
39
- readonly #content: AtomicoThis<MenuProps, HTMLElement>
40
+ readonly #content: HTMLElement
41
+ readonly #app: App
42
+ readonly #filter: Ref<string>
40
43
  readonly #slashProvider: SlashProvider
41
44
  #programmaticallyPos: number | null = null
42
45
 
43
46
  constructor(ctx: Ctx, view: EditorView, config?: BlockEditFeatureConfig) {
44
- this.#content = new MenuElement()
45
- this.#content.hide = this.hide
46
- this.#content.ctx = ctx
47
- this.#content.config = config
48
- // eslint-disable-next-line ts/no-this-alias
47
+ const content = document.createElement('div')
48
+ content.classList.add('milkdown-slash-menu')
49
+ const show = ref(false)
50
+
51
+ const filter = ref('')
52
+ this.#filter = filter
53
+
54
+ const hide = this.hide
55
+
56
+ const app = createApp(Menu, {
57
+ ctx,
58
+ config,
59
+ show,
60
+ filter,
61
+ hide,
62
+ })
63
+ this.#app = app
64
+ app.mount(content)
65
+
66
+ this.#content = content
67
+ // oxlint-disable-next-line ts/no-this-alias
49
68
  const self = this
50
69
  this.#slashProvider = new SlashProvider({
51
70
  content: this.#content,
@@ -69,7 +88,7 @@ class MenuView implements PluginView {
69
88
 
70
89
  const pos = self.#programmaticallyPos
71
90
 
72
- self.#content.filter = currentText.startsWith('/')
91
+ filter.value = currentText.startsWith('/')
73
92
  ? currentText.slice(1)
74
93
  : currentText
75
94
 
@@ -94,10 +113,10 @@ class MenuView implements PluginView {
94
113
  })
95
114
 
96
115
  this.#slashProvider.onShow = () => {
97
- this.#content.show = true
116
+ show.value = true
98
117
  }
99
118
  this.#slashProvider.onHide = () => {
100
- this.#content.show = false
119
+ show.value = false
101
120
  }
102
121
  this.update(view)
103
122
 
@@ -113,7 +132,7 @@ class MenuView implements PluginView {
113
132
 
114
133
  show = (pos: number) => {
115
134
  this.#programmaticallyPos = pos
116
- this.#content.filter = ''
135
+ this.#filter.value = ''
117
136
  this.#slashProvider.show()
118
137
  }
119
138
 
@@ -124,6 +143,7 @@ class MenuView implements PluginView {
124
143
 
125
144
  destroy = () => {
126
145
  this.#slashProvider.destroy()
146
+ this.#app.unmount()
127
147
  this.#content.remove()
128
148
  }
129
149
  }
@@ -1,14 +1,14 @@
1
- import type { html } from 'atomico'
2
1
  import type { Ctx } from '@milkdown/kit/ctx'
3
- import type { Command, Transaction } from '@milkdown/kit/prose/state'
4
2
  import type { Attrs, NodeType } from '@milkdown/kit/prose/model'
3
+ import type { Command, Transaction } from '@milkdown/kit/prose/state'
4
+
5
5
  import { findWrapping } from '@milkdown/kit/prose/transform'
6
6
 
7
7
  export interface MenuItem {
8
8
  index: number
9
9
  key: string
10
10
  label: string
11
- icon: ReturnType<typeof html>
11
+ icon: string
12
12
  onRun: (ctx: Ctx) => void
13
13
  }
14
14
 
@@ -1,14 +1,16 @@
1
+ import type { LanguageDescription } from '@codemirror/language'
2
+ import type { Extension } from '@codemirror/state'
3
+
4
+ import { defaultKeymap, indentWithTab } from '@codemirror/commands'
5
+ import { keymap } from '@codemirror/view'
1
6
  import {
2
7
  codeBlockComponent,
3
8
  codeBlockConfig,
4
9
  } from '@milkdown/kit/component/code-block'
5
- import type { LanguageDescription } from '@codemirror/language'
6
- import type { Extension } from '@codemirror/state'
7
10
  import { basicSetup } from 'codemirror'
8
- import { keymap } from '@codemirror/view'
9
- import { defaultKeymap, indentWithTab } from '@codemirror/commands'
10
- import { html } from 'atomico'
11
+
11
12
  import type { DefineFeature, Icon } from '../shared'
13
+
12
14
  import { chevronDownIcon, clearIcon, editIcon, searchIcon } from '../../icons'
13
15
  import { visibilityOffIcon } from '../../icons/visibility-off'
14
16
 
@@ -24,10 +26,7 @@ interface CodeMirrorConfig {
24
26
  searchPlaceholder: string
25
27
  noResultText: string
26
28
 
27
- renderLanguage: (
28
- language: string,
29
- selected: boolean
30
- ) => ReturnType<typeof html> | string
29
+ renderLanguage: (language: string, selected: boolean) => string
31
30
 
32
31
  renderPreview: (
33
32
  language: string,
@@ -35,8 +34,8 @@ interface CodeMirrorConfig {
35
34
  ) => string | HTMLElement | null
36
35
 
37
36
  previewToggleIcon: (previewOnlyMode: boolean) => ReturnType<Icon>
38
- previewToggleText: (previewOnlyMode: boolean) => ReturnType<typeof html>
39
- previewLabel: () => ReturnType<typeof html>
37
+ previewToggleText: (previewOnlyMode: boolean) => string
38
+ previewLabel: () => string
40
39
  }
41
40
  export type CodeMirrorFeatureConfig = Partial<CodeMirrorConfig>
42
41
 
@@ -66,20 +65,21 @@ export const defineFeature: DefineFeature<CodeMirrorFeatureConfig> = (
66
65
  ],
67
66
  languages,
68
67
 
69
- expandIcon: config.expandIcon || (() => chevronDownIcon),
70
- searchIcon: config.searchIcon || (() => searchIcon),
71
- clearSearchIcon: config.clearSearchIcon || (() => clearIcon),
68
+ expandIcon: () => config.expandIcon?.() || chevronDownIcon,
69
+ searchIcon: () => config.searchIcon?.() || searchIcon,
70
+ clearSearchIcon: () => config.clearSearchIcon?.() || clearIcon,
72
71
  searchPlaceholder: config.searchPlaceholder || 'Search language',
73
72
  noResultText: config.noResultText || 'No result',
74
73
  renderLanguage: config.renderLanguage || defaultConfig.renderLanguage,
75
74
  renderPreview: config.renderPreview || defaultConfig.renderPreview,
76
75
  previewToggleButton: (previewOnlyMode) => {
77
- return html`
78
- ${config.previewToggleIcon?.(previewOnlyMode) ||
79
- (previewOnlyMode ? editIcon : visibilityOffIcon)}
80
- ${config.previewToggleText?.(previewOnlyMode) ||
81
- (previewOnlyMode ? 'Edit' : 'Hide')}
82
- `
76
+ const icon =
77
+ config.previewToggleIcon?.(previewOnlyMode) ||
78
+ (previewOnlyMode ? editIcon : visibilityOffIcon)
79
+ const text =
80
+ config.previewToggleText?.(previewOnlyMode) ||
81
+ (previewOnlyMode ? 'Edit' : 'Hide')
82
+ return [icon, text].map((v) => v.trim()).join(' ')
83
83
  },
84
84
  previewLabel: config.previewLabel || defaultConfig.previewLabel,
85
85
  }))
@@ -1,8 +1,8 @@
1
1
  import { cursor, dropCursorConfig } from '@milkdown/kit/plugin/cursor'
2
+ import { $prose } from '@milkdown/kit/utils'
2
3
  import { createVirtualCursor } from 'prosemirror-virtual-cursor'
3
4
 
4
5
  import type { DefineFeature } from '../shared'
5
- import { $prose } from '@milkdown/kit/utils'
6
6
 
7
7
  interface CursorConfig {
8
8
  color: string | false
@@ -6,8 +6,10 @@ import {
6
6
  imageInlineComponent,
7
7
  inlineImageConfig,
8
8
  } from '@milkdown/kit/component/image-inline'
9
+
9
10
  import type { DefineFeature, Icon } from '../shared'
10
- import { captionIcon, confirmIcon, imageIcon } from '../../icons'
11
+
12
+ import { captionIcon, imageIcon, confirmIcon } from '../../icons'
11
13
 
12
14
  interface ImageBlockConfig {
13
15
  onUpload: (file: File) => Promise<string>
@@ -1,14 +1,15 @@
1
1
  import type { Editor } from '@milkdown/kit/core'
2
- import type { PlaceHolderFeatureConfig } from './placeholder'
3
- import type { CodeMirrorFeatureConfig } from './code-mirror'
2
+
4
3
  import type { BlockEditFeatureConfig } from './block-edit'
4
+ import type { CodeMirrorFeatureConfig } from './code-mirror'
5
5
  import type { CursorFeatureConfig } from './cursor'
6
6
  import type { ImageBlockFeatureConfig } from './image-block'
7
+ import type { LatexFeatureConfig } from './latex'
7
8
  import type { LinkTooltipFeatureConfig } from './link-tooltip'
8
9
  import type { ListItemFeatureConfig } from './list-item'
9
- import type { ToolbarFeatureConfig } from './toolbar'
10
+ import type { PlaceHolderFeatureConfig } from './placeholder'
10
11
  import type { TableFeatureConfig } from './table'
11
- import type { LatexFeatureConfig } from './latex'
12
+ import type { ToolbarFeatureConfig } from './toolbar'
12
13
 
13
14
  export enum CrepeFeature {
14
15
  CodeMirror = 'code-mirror',
@@ -1,18 +1,19 @@
1
1
  import type { KatexOptions } from 'katex'
2
- import katex from 'katex'
2
+
3
3
  import { codeBlockConfig } from '@milkdown/kit/component/code-block'
4
+ import katex from 'katex'
5
+
6
+ import type { DefineFeature, Icon } from '../shared'
7
+
4
8
  import { CrepeFeature } from '../..'
5
9
  import { FeaturesCtx } from '../../core/slice'
6
- import type { DefineFeature, Icon } from '../shared'
7
- import { remarkMathBlockPlugin, remarkMathPlugin } from './remark'
10
+ import { confirmIcon } from '../../icons'
11
+ import { blockLatexSchema } from './block-latex'
8
12
  import { mathInlineSchema } from './inline-latex'
9
- import { defIfNotExists } from '../../utils'
10
- import { LatexInlineEditElement } from './inline-tooltip/component'
11
13
  import { inlineLatexTooltip } from './inline-tooltip/tooltip'
12
14
  import { LatexInlineTooltip } from './inline-tooltip/view'
13
- import { confirmIcon } from '../../icons'
14
15
  import { mathBlockInputRule, mathInlineInputRule } from './input-rule'
15
- import { blockLatexSchema } from './block-latex'
16
+ import { remarkMathBlockPlugin, remarkMathPlugin } from './remark'
16
17
 
17
18
  export interface LatexConfig {
18
19
  katexOptions: KatexOptions
@@ -21,7 +22,6 @@ export interface LatexConfig {
21
22
 
22
23
  export type LatexFeatureConfig = Partial<LatexConfig>
23
24
 
24
- defIfNotExists('milkdown-latex-inline-edit', LatexInlineEditElement)
25
25
  export const defineFeature: DefineFeature<LatexFeatureConfig> = (
26
26
  editor,
27
27
  config
@@ -0,0 +1,57 @@
1
+ import type { EditorView } from '@milkdown/kit/prose/view'
2
+
3
+ import { Icon } from '@milkdown/kit/component'
4
+ import { defineComponent, type ShallowRef, type VNodeRef, h } from 'vue'
5
+
6
+ import type { LatexConfig } from '..'
7
+
8
+ type LatexTooltipProps = {
9
+ config: Partial<LatexConfig>
10
+ innerView: ShallowRef<EditorView | null>
11
+ updateValue: ShallowRef<() => void>
12
+ }
13
+
14
+ h
15
+
16
+ export const LatexTooltip = defineComponent<LatexTooltipProps>({
17
+ props: {
18
+ config: {
19
+ type: Object,
20
+ required: true,
21
+ },
22
+ innerView: {
23
+ type: Object,
24
+ required: true,
25
+ },
26
+ updateValue: {
27
+ type: Object,
28
+ required: true,
29
+ },
30
+ },
31
+ setup(props) {
32
+ const innerViewRef: VNodeRef = (el) => {
33
+ if (!el || !(el instanceof HTMLElement)) return
34
+ while (el.firstChild) {
35
+ el.removeChild(el.firstChild)
36
+ }
37
+ if (props.innerView.value) {
38
+ el.appendChild(props.innerView.value.dom)
39
+ }
40
+ }
41
+ const onUpdate = (e: Event) => {
42
+ e.preventDefault()
43
+ props.updateValue.value()
44
+ }
45
+
46
+ return () => {
47
+ return (
48
+ <div class="container">
49
+ {props.innerView && <div ref={innerViewRef} />}
50
+ <button onPointerdown={onUpdate}>
51
+ <Icon icon={props.config.inlineEditConfirm?.()} />
52
+ </button>
53
+ </div>
54
+ )
55
+ }
56
+ },
57
+ })