@milkdown/crepe 7.11.1 → 7.12.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 (187) hide show
  1. package/lib/cjs/builder.js +107 -0
  2. package/lib/cjs/builder.js.map +1 -0
  3. package/lib/cjs/{index-CtTpZYVe.js → feature/block-edit/index.js} +165 -61
  4. package/lib/cjs/feature/block-edit/index.js.map +1 -0
  5. package/lib/cjs/feature/code-mirror/index.js +161 -0
  6. package/lib/cjs/feature/code-mirror/index.js.map +1 -0
  7. package/lib/cjs/feature/cursor/index.js +57 -0
  8. package/lib/cjs/feature/cursor/index.js.map +1 -0
  9. package/lib/cjs/feature/image-block/index.js +123 -0
  10. package/lib/cjs/feature/image-block/index.js.map +1 -0
  11. package/lib/cjs/{index-2icTTGim.js → feature/latex/index.js} +111 -24
  12. package/lib/cjs/feature/latex/index.js.map +1 -0
  13. package/lib/cjs/feature/link-tooltip/index.js +124 -0
  14. package/lib/cjs/feature/link-tooltip/index.js.map +1 -0
  15. package/lib/cjs/{index-Dw6lXgs6.js → feature/list-item/index.js} +39 -8
  16. package/lib/cjs/feature/list-item/index.js.map +1 -0
  17. package/lib/cjs/{index-B91KhPew.js → feature/placeholder/index.js} +46 -6
  18. package/lib/cjs/feature/placeholder/index.js.map +1 -0
  19. package/lib/cjs/{index-DEs_IHHy.js → feature/table/index.js} +78 -16
  20. package/lib/cjs/feature/table/index.js.map +1 -0
  21. package/lib/cjs/{index-k3lGvKiX.js → feature/toolbar/index.js} +133 -31
  22. package/lib/cjs/feature/toolbar/index.js.map +1 -0
  23. package/lib/cjs/index.js +2461 -17
  24. package/lib/cjs/index.js.map +1 -1
  25. package/lib/esm/builder.js +105 -0
  26. package/lib/esm/builder.js.map +1 -0
  27. package/lib/esm/{index-BEe1TpeS.js → feature/block-edit/index.js} +161 -57
  28. package/lib/esm/feature/block-edit/index.js.map +1 -0
  29. package/lib/esm/feature/code-mirror/index.js +159 -0
  30. package/lib/esm/feature/code-mirror/index.js.map +1 -0
  31. package/lib/esm/feature/cursor/index.js +55 -0
  32. package/lib/esm/feature/cursor/index.js.map +1 -0
  33. package/lib/esm/feature/image-block/index.js +121 -0
  34. package/lib/esm/feature/image-block/index.js.map +1 -0
  35. package/lib/esm/{index-ZGfGszIQ.js → feature/latex/index.js} +107 -20
  36. package/lib/esm/feature/latex/index.js.map +1 -0
  37. package/lib/esm/feature/link-tooltip/index.js +122 -0
  38. package/lib/esm/feature/link-tooltip/index.js.map +1 -0
  39. package/lib/esm/{index-E8UgFLeN.js → feature/list-item/index.js} +39 -8
  40. package/lib/esm/feature/list-item/index.js.map +1 -0
  41. package/lib/esm/{index-BCvtgOeI.js → feature/placeholder/index.js} +45 -5
  42. package/lib/esm/feature/placeholder/index.js.map +1 -0
  43. package/lib/esm/{index-CwMVnVeI.js → feature/table/index.js} +78 -16
  44. package/lib/esm/feature/table/index.js.map +1 -0
  45. package/lib/esm/{index-CTBg0aec.js → feature/toolbar/index.js} +128 -26
  46. package/lib/esm/feature/toolbar/index.js.map +1 -0
  47. package/lib/esm/index.js +2457 -11
  48. package/lib/esm/index.js.map +1 -1
  49. package/lib/tsconfig.tsbuildinfo +1 -1
  50. package/lib/types/builder.d.ts +2 -0
  51. package/lib/types/builder.d.ts.map +1 -0
  52. package/lib/types/core/builder.d.ts +23 -0
  53. package/lib/types/core/builder.d.ts.map +1 -0
  54. package/lib/types/core/crepe.d.ts +4 -15
  55. package/lib/types/core/crepe.d.ts.map +1 -1
  56. package/lib/types/core/index.d.ts +2 -1
  57. package/lib/types/core/index.d.ts.map +1 -1
  58. package/lib/types/core/slice.d.ts +6 -4
  59. package/lib/types/core/slice.d.ts.map +1 -1
  60. package/lib/types/default-config/index.d.ts +3 -0
  61. package/lib/types/default-config/index.d.ts.map +1 -0
  62. package/lib/types/feature/block-edit/handle/component.d.ts +2 -3
  63. package/lib/types/feature/block-edit/handle/component.d.ts.map +1 -1
  64. package/lib/types/feature/block-edit/index.d.ts +20 -20
  65. package/lib/types/feature/block-edit/index.d.ts.map +1 -1
  66. package/lib/types/feature/code-mirror/index.d.ts +7 -7
  67. package/lib/types/feature/code-mirror/index.d.ts.map +1 -1
  68. package/lib/types/feature/cursor/index.d.ts +1 -1
  69. package/lib/types/feature/cursor/index.d.ts.map +1 -1
  70. package/lib/types/feature/image-block/index.d.ts +9 -9
  71. package/lib/types/feature/image-block/index.d.ts.map +1 -1
  72. package/lib/types/feature/index.d.ts +2 -4
  73. package/lib/types/feature/index.d.ts.map +1 -1
  74. package/lib/types/feature/latex/index.d.ts +3 -3
  75. package/lib/types/feature/latex/index.d.ts.map +1 -1
  76. package/lib/types/feature/link-tooltip/index.d.ts +6 -6
  77. package/lib/types/feature/link-tooltip/index.d.ts.map +1 -1
  78. package/lib/types/feature/list-item/index.d.ts +5 -5
  79. package/lib/types/feature/list-item/index.d.ts.map +1 -1
  80. package/lib/types/feature/loader.d.ts +4 -0
  81. package/lib/types/feature/loader.d.ts.map +1 -0
  82. package/lib/types/feature/placeholder/index.d.ts +2 -2
  83. package/lib/types/feature/placeholder/index.d.ts.map +1 -1
  84. package/lib/types/feature/shared.d.ts +1 -2
  85. package/lib/types/feature/shared.d.ts.map +1 -1
  86. package/lib/types/feature/table/index.d.ts +11 -11
  87. package/lib/types/feature/table/index.d.ts.map +1 -1
  88. package/lib/types/feature/toolbar/index.d.ts +8 -8
  89. package/lib/types/feature/toolbar/index.d.ts.map +1 -1
  90. package/lib/types/icons/index.d.ts +1 -0
  91. package/lib/types/icons/index.d.ts.map +1 -1
  92. package/lib/types/index.d.ts +1 -1
  93. package/lib/types/index.d.ts.map +1 -1
  94. package/lib/types/utils/index.d.ts +0 -1
  95. package/lib/types/utils/index.d.ts.map +1 -1
  96. package/package.json +60 -3
  97. package/src/builder.ts +1 -0
  98. package/src/core/builder.ts +143 -0
  99. package/src/core/crepe.ts +14 -130
  100. package/src/core/index.ts +2 -1
  101. package/src/core/slice.ts +37 -8
  102. package/src/default-config/index.ts +25 -0
  103. package/src/feature/block-edit/handle/component.tsx +6 -8
  104. package/src/feature/block-edit/handle/index.ts +2 -2
  105. package/src/feature/block-edit/index.ts +23 -20
  106. package/src/feature/block-edit/menu/config.ts +19 -19
  107. package/src/feature/code-mirror/index.ts +32 -28
  108. package/src/feature/cursor/index.ts +10 -6
  109. package/src/feature/image-block/index.ts +19 -16
  110. package/src/feature/index.ts +2 -53
  111. package/src/feature/latex/index.ts +8 -10
  112. package/src/feature/latex/inline-tooltip/component.tsx +1 -1
  113. package/src/feature/link-tooltip/index.ts +13 -10
  114. package/src/feature/list-item/index.ts +11 -8
  115. package/src/feature/loader.ts +52 -0
  116. package/src/feature/placeholder/index.ts +5 -2
  117. package/src/feature/shared.ts +1 -3
  118. package/src/feature/table/index.ts +23 -23
  119. package/src/feature/toolbar/component.tsx +9 -9
  120. package/src/feature/toolbar/index.ts +14 -11
  121. package/src/icons/index.ts +1 -0
  122. package/src/index.ts +1 -1
  123. package/src/utils/index.ts +0 -8
  124. package/lib/cjs/confirm-CNveM9QH.js +0 -26
  125. package/lib/cjs/confirm-CNveM9QH.js.map +0 -1
  126. package/lib/cjs/edit-BUtBJHpV.js +0 -24
  127. package/lib/cjs/edit-BUtBJHpV.js.map +0 -1
  128. package/lib/cjs/functions-BAY51plB.js +0 -39
  129. package/lib/cjs/functions-BAY51plB.js.map +0 -1
  130. package/lib/cjs/image-BXLkOVnO.js +0 -24
  131. package/lib/cjs/image-BXLkOVnO.js.map +0 -1
  132. package/lib/cjs/index-2icTTGim.js.map +0 -1
  133. package/lib/cjs/index-B91KhPew.js.map +0 -1
  134. package/lib/cjs/index-BsrJn8Jp.js +0 -41
  135. package/lib/cjs/index-BsrJn8Jp.js.map +0 -1
  136. package/lib/cjs/index-C2CAbC2F.js +0 -26
  137. package/lib/cjs/index-C2CAbC2F.js.map +0 -1
  138. package/lib/cjs/index-CtTpZYVe.js.map +0 -1
  139. package/lib/cjs/index-DEs_IHHy.js.map +0 -1
  140. package/lib/cjs/index-DLIudQKW.js +0 -126
  141. package/lib/cjs/index-DLIudQKW.js.map +0 -1
  142. package/lib/cjs/index-Dw6lXgs6.js.map +0 -1
  143. package/lib/cjs/index-k3lGvKiX.js.map +0 -1
  144. package/lib/cjs/index-urTgNBfI.js +0 -202
  145. package/lib/cjs/index-urTgNBfI.js.map +0 -1
  146. package/lib/cjs/index-xbwf60wt.js +0 -15
  147. package/lib/cjs/index-xbwf60wt.js.map +0 -1
  148. package/lib/cjs/index-xbxqAqH2.js +0 -52
  149. package/lib/cjs/index-xbxqAqH2.js.map +0 -1
  150. package/lib/cjs/inline-latex-D0G71cGk.js +0 -54
  151. package/lib/cjs/inline-latex-D0G71cGk.js.map +0 -1
  152. package/lib/cjs/plus-XLomtlXf.js +0 -24
  153. package/lib/cjs/plus-XLomtlXf.js.map +0 -1
  154. package/lib/cjs/remove-Ba-ypwBf.js +0 -17
  155. package/lib/cjs/remove-Ba-ypwBf.js.map +0 -1
  156. package/lib/esm/confirm-DtE-HkVd.js +0 -24
  157. package/lib/esm/confirm-DtE-HkVd.js.map +0 -1
  158. package/lib/esm/edit-D--t_JAb.js +0 -22
  159. package/lib/esm/edit-D--t_JAb.js.map +0 -1
  160. package/lib/esm/functions-DlJPkGmE.js +0 -36
  161. package/lib/esm/functions-DlJPkGmE.js.map +0 -1
  162. package/lib/esm/image-DoB1o1sl.js +0 -22
  163. package/lib/esm/image-DoB1o1sl.js.map +0 -1
  164. package/lib/esm/index-BCvtgOeI.js.map +0 -1
  165. package/lib/esm/index-BEe1TpeS.js.map +0 -1
  166. package/lib/esm/index-BPG8iO8t.js +0 -12
  167. package/lib/esm/index-BPG8iO8t.js.map +0 -1
  168. package/lib/esm/index-BUBXHhHG.js +0 -39
  169. package/lib/esm/index-BUBXHhHG.js.map +0 -1
  170. package/lib/esm/index-Bvz1Yyiz.js +0 -24
  171. package/lib/esm/index-Bvz1Yyiz.js.map +0 -1
  172. package/lib/esm/index-C1aVAv1l.js +0 -124
  173. package/lib/esm/index-C1aVAv1l.js.map +0 -1
  174. package/lib/esm/index-CTBg0aec.js.map +0 -1
  175. package/lib/esm/index-ChR5Qhyf.js +0 -50
  176. package/lib/esm/index-ChR5Qhyf.js.map +0 -1
  177. package/lib/esm/index-CshFzSt2.js +0 -197
  178. package/lib/esm/index-CshFzSt2.js.map +0 -1
  179. package/lib/esm/index-CwMVnVeI.js.map +0 -1
  180. package/lib/esm/index-E8UgFLeN.js.map +0 -1
  181. package/lib/esm/index-ZGfGszIQ.js.map +0 -1
  182. package/lib/esm/inline-latex-C9IGAXXQ.js +0 -51
  183. package/lib/esm/inline-latex-C9IGAXXQ.js.map +0 -1
  184. package/lib/esm/plus-lrX0Q75O.js +0 -22
  185. package/lib/esm/plus-lrX0Q75O.js.map +0 -1
  186. package/lib/esm/remove-D3g0Cd6_.js +0 -15
  187. package/lib/esm/remove-D3g0Cd6_.js.map +0 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@milkdown/crepe",
3
3
  "type": "module",
4
- "version": "7.11.1",
4
+ "version": "7.12.1",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -21,6 +21,61 @@
21
21
  "require": "./lib/cjs/index.js",
22
22
  "types": "./lib/types/index.d.ts"
23
23
  },
24
+ "./builder": {
25
+ "import": "./lib/esm/builder.js",
26
+ "require": "./lib/cjs/builder.js",
27
+ "types": "./lib/types/builder.d.ts"
28
+ },
29
+ "./feature/block-edit": {
30
+ "import": "./lib/esm/feature/block-edit/index.js",
31
+ "require": "./lib/cjs/feature/block-edit/index.js",
32
+ "types": "./lib/types/feature/block-edit/index.d.ts"
33
+ },
34
+ "./feature/code-mirror": {
35
+ "import": "./lib/esm/feature/code-mirror/index.js",
36
+ "require": "./lib/cjs/feature/code-mirror/index.js",
37
+ "types": "./lib/types/feature/code-mirror/index.d.ts"
38
+ },
39
+ "./feature/cursor": {
40
+ "import": "./lib/esm/feature/cursor/index.js",
41
+ "require": "./lib/cjs/feature/cursor/index.js",
42
+ "types": "./lib/types/feature/cursor/index.d.ts"
43
+ },
44
+ "./feature/image-block": {
45
+ "import": "./lib/esm/feature/image-block/index.js",
46
+ "require": "./lib/cjs/feature/image-block/index.js",
47
+ "types": "./lib/types/feature/image-block/index.d.ts"
48
+ },
49
+ "./feature/latex": {
50
+ "import": "./lib/esm/feature/latex/index.js",
51
+ "require": "./lib/cjs/feature/latex/index.js",
52
+ "types": "./lib/types/feature/latex/index.d.ts"
53
+ },
54
+ "./feature/link-tooltip": {
55
+ "import": "./lib/esm/feature/link-tooltip/index.js",
56
+ "require": "./lib/cjs/feature/link-tooltip/index.js",
57
+ "types": "./lib/types/feature/link-tooltip/index.d.ts"
58
+ },
59
+ "./feature/list-item": {
60
+ "import": "./lib/esm/feature/list-item/index.js",
61
+ "require": "./lib/cjs/feature/list-item/index.js",
62
+ "types": "./lib/types/feature/list-item/index.d.ts"
63
+ },
64
+ "./feature/placeholder": {
65
+ "import": "./lib/esm/feature/placeholder/index.js",
66
+ "require": "./lib/cjs/feature/placeholder/index.js",
67
+ "types": "./lib/types/feature/placeholder/index.d.ts"
68
+ },
69
+ "./feature/table": {
70
+ "import": "./lib/esm/feature/table/index.js",
71
+ "require": "./lib/cjs/feature/table/index.js",
72
+ "types": "./lib/types/feature/table/index.d.ts"
73
+ },
74
+ "./feature/toolbar": {
75
+ "import": "./lib/esm/feature/toolbar/index.js",
76
+ "require": "./lib/cjs/feature/toolbar/index.js",
77
+ "types": "./lib/types/feature/toolbar/index.d.ts"
78
+ },
24
79
  "./theme/common/*": "./lib/theme/common/*",
25
80
  "./theme/classic.css": "./lib/theme/classic/style.css",
26
81
  "./theme/classic-dark.css": "./lib/theme/classic-dark/style.css",
@@ -41,21 +96,23 @@
41
96
  "@codemirror/state": "^6.4.1",
42
97
  "@codemirror/theme-one-dark": "^6.1.2",
43
98
  "@codemirror/view": "^6.16.0",
99
+ "@types/lodash-es": "^4.17.12",
44
100
  "clsx": "^2.0.0",
45
101
  "codemirror": "^6.0.1",
46
102
  "katex": "^0.16.0",
103
+ "lodash-es": "^4.17.21",
47
104
  "nanoid": "^5.0.9",
48
105
  "prosemirror-virtual-cursor": "^0.4.2",
49
106
  "remark-math": "^6.0.0",
50
107
  "tslib": "^2.8.1",
51
108
  "unist-util-visit": "^5.0.0",
52
109
  "vue": "^3.5.13",
53
- "@milkdown/kit": "7.11.1"
110
+ "@milkdown/kit": "7.12.1"
54
111
  },
55
112
  "scripts": {
56
113
  "build": "pnpm run build:es && pnpm run build:theme && echo",
57
114
  "build:es": "rollup -c",
58
- "build:theme": "postcss 'src/theme' --base 'src/theme' --dir 'lib/theme'"
115
+ "build:theme": "postcss src/theme --base src/theme --dir lib/theme"
59
116
  },
60
117
  "types": "./lib/types/index.d.ts"
61
118
  }
package/src/builder.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './core/builder'
@@ -0,0 +1,143 @@
1
+ import {
2
+ type DefaultValue,
3
+ defaultValueCtx,
4
+ Editor,
5
+ EditorStatus,
6
+ editorViewCtx,
7
+ editorViewOptionsCtx,
8
+ rootCtx,
9
+ } from '@milkdown/kit/core'
10
+ import { clipboard } from '@milkdown/kit/plugin/clipboard'
11
+ import { history } from '@milkdown/kit/plugin/history'
12
+ import { indent, indentConfig } from '@milkdown/kit/plugin/indent'
13
+ import {
14
+ listener,
15
+ listenerCtx,
16
+ type ListenerManager,
17
+ } from '@milkdown/kit/plugin/listener'
18
+ import { trailing } from '@milkdown/kit/plugin/trailing'
19
+ import { commonmark } from '@milkdown/kit/preset/commonmark'
20
+ import { gfm } from '@milkdown/kit/preset/gfm'
21
+ import { getMarkdown } from '@milkdown/kit/utils'
22
+
23
+ import type { CrepeFeature, CrepeFeatureConfig } from '../feature'
24
+ import type { DefineFeature } from '../feature/shared'
25
+
26
+ import { CrepeCtx, FeaturesCtx } from './slice'
27
+
28
+ /// The crepe builder configuration.
29
+ export interface CrepeBuilderConfig {
30
+ /// The root element for the editor.
31
+ /// Supports both DOM nodes and CSS selectors,
32
+ /// If not provided, the editor will be appended to the body.
33
+ root?: Node | string | null
34
+
35
+ /// The default value for the editor.
36
+ defaultValue?: DefaultValue
37
+ }
38
+
39
+ /// The crepe builder class.
40
+ /// This class allows users to manually add features to the editor.
41
+ export class CrepeBuilder {
42
+ /// @internal
43
+ readonly #editor: Editor
44
+
45
+ /// @internal
46
+ readonly #rootElement: Node
47
+
48
+ /// @internal
49
+ #editable = true
50
+
51
+ /// The constructor of the crepe builder.
52
+ /// You can pass configs to the builder to configure the editor.
53
+ constructor({ root, defaultValue = '' }: CrepeBuilderConfig) {
54
+ this.#rootElement =
55
+ (typeof root === 'string' ? document.querySelector(root) : root) ??
56
+ document.body
57
+ this.#editor = Editor.make()
58
+ .config((ctx) => {
59
+ ctx.inject(CrepeCtx, this)
60
+ ctx.inject(FeaturesCtx, [])
61
+ })
62
+ .config((ctx) => {
63
+ ctx.set(rootCtx, this.#rootElement)
64
+ ctx.set(defaultValueCtx, defaultValue)
65
+ ctx.set(editorViewOptionsCtx, {
66
+ editable: () => this.#editable,
67
+ })
68
+ ctx.update(indentConfig.key, (value) => ({
69
+ ...value,
70
+ size: 4,
71
+ }))
72
+ })
73
+ .use(commonmark)
74
+ .use(listener)
75
+ .use(history)
76
+ .use(indent)
77
+ .use(trailing)
78
+ .use(clipboard)
79
+ .use(gfm)
80
+ }
81
+
82
+ /// Add a feature to the editor.
83
+ addFeature: {
84
+ <T extends CrepeFeature>(
85
+ feature: DefineFeature<CrepeFeatureConfig[T]>,
86
+ config?: CrepeFeatureConfig[T]
87
+ ): CrepeBuilder
88
+ <C>(feature: DefineFeature<C>, config?: C): CrepeBuilder
89
+ } = (feature: DefineFeature, config?: never) => {
90
+ feature(this.#editor, config)
91
+ return this
92
+ }
93
+
94
+ /// Create the editor.
95
+ create = () => {
96
+ return this.#editor.create()
97
+ }
98
+
99
+ /// Destroy the editor.
100
+ destroy = () => {
101
+ return this.#editor.destroy()
102
+ }
103
+
104
+ /// Get the milkdown editor instance.
105
+ get editor(): Editor {
106
+ return this.#editor
107
+ }
108
+
109
+ /// Set the readonly mode of the editor.
110
+ setReadonly = (value: boolean) => {
111
+ this.#editable = !value
112
+ this.#editor.action((ctx) => {
113
+ if (this.#editor.status === EditorStatus.Created) {
114
+ const view = ctx.get(editorViewCtx)
115
+ view.setProps({
116
+ editable: () => !value,
117
+ })
118
+ }
119
+ })
120
+ return this
121
+ }
122
+
123
+ /// Get the markdown content of the editor.
124
+ getMarkdown = () => {
125
+ return this.#editor.action(getMarkdown())
126
+ }
127
+
128
+ /// Register event listeners.
129
+ on = (fn: (api: ListenerManager) => void) => {
130
+ if (this.#editor.status !== EditorStatus.Created) {
131
+ this.#editor.config((ctx) => {
132
+ const listener = ctx.get(listenerCtx)
133
+ fn(listener)
134
+ })
135
+ return this
136
+ }
137
+ this.#editor.action((ctx) => {
138
+ const listener = ctx.get(listenerCtx)
139
+ fn(listener)
140
+ })
141
+ return this
142
+ }
143
+ }
package/src/core/crepe.ts CHANGED
@@ -1,71 +1,38 @@
1
- import type { DefaultValue } from '@milkdown/kit/core'
2
- import type { ListenerManager } from '@milkdown/kit/plugin/listener'
3
-
4
- import {
5
- Editor,
6
- EditorStatus,
7
- defaultValueCtx,
8
- editorViewCtx,
9
- editorViewOptionsCtx,
10
- rootCtx,
11
- } from '@milkdown/kit/core'
12
- import { clipboard } from '@milkdown/kit/plugin/clipboard'
13
- import { history } from '@milkdown/kit/plugin/history'
14
- import { indent, indentConfig } from '@milkdown/kit/plugin/indent'
15
- import { listener, listenerCtx } from '@milkdown/kit/plugin/listener'
16
- import { trailing } from '@milkdown/kit/plugin/trailing'
17
- import { commonmark } from '@milkdown/kit/preset/commonmark'
18
- import { gfm } from '@milkdown/kit/preset/gfm'
19
- import { getMarkdown } from '@milkdown/kit/utils'
1
+ import { defaultsDeep } from 'lodash-es'
20
2
 
21
3
  import type { CrepeFeatureConfig } from '../feature'
22
4
 
23
- import { CrepeFeature, defaultFeatures, loadFeature } from '../feature'
24
- import { configureFeatures, crepeCtx } from './slice'
5
+ import { defaultConfig } from '../default-config'
6
+ import { CrepeFeature, defaultFeatures } from '../feature'
7
+ import { loadFeature } from '../feature/loader'
8
+ import { CrepeBuilder, type CrepeBuilderConfig } from './builder'
25
9
 
26
10
  /// The crepe editor configuration.
27
- export interface CrepeConfig {
11
+ export interface CrepeConfig extends CrepeBuilderConfig {
28
12
  /// Enable/disable specific features.
29
13
  features?: Partial<Record<CrepeFeature, boolean>>
30
14
 
31
15
  /// Configure individual features.
32
16
  featureConfigs?: CrepeFeatureConfig
33
-
34
- /// The root element for the editor.
35
- /// Supports both DOM nodes and CSS selectors,
36
- /// If not provided, the editor will be appended to the body.
37
- root?: Node | string | null
38
-
39
- /// The default value for the editor.
40
- defaultValue?: DefaultValue
41
17
  }
42
18
 
43
19
  /// The crepe editor class.
44
- export class Crepe {
20
+ export class Crepe extends CrepeBuilder {
45
21
  /// This is an alias for the `CrepeFeature` enum.
46
22
  static Feature = CrepeFeature
47
23
 
48
- /// @internal
49
- readonly #editor: Editor
50
-
51
- /// @internal
52
- readonly #initPromise: Promise<unknown>
53
-
54
- /// @internal
55
- readonly #rootElement: Node
56
-
57
- /// @internal
58
- #editable = true
59
-
60
24
  /// The constructor of the crepe editor.
61
25
  /// You can pass configs to the editor to configure the editor.
62
26
  /// Calling the constructor will not create the editor, you need to call `create` to create the editor.
63
27
  constructor({
64
- root,
65
28
  features = {},
66
29
  featureConfigs = {},
67
- defaultValue = '',
30
+ ...crepeBuilderConfig
68
31
  }: CrepeConfig) {
32
+ super(crepeBuilderConfig)
33
+
34
+ const finalConfigs = defaultsDeep(featureConfigs, defaultConfig)
35
+
69
36
  const enabledFeatures = Object.entries({
70
37
  ...defaultFeatures,
71
38
  ...features,
@@ -73,94 +40,11 @@ export class Crepe {
73
40
  .filter(([, enabled]) => enabled)
74
41
  .map(([feature]) => feature as CrepeFeature)
75
42
 
76
- this.#rootElement =
77
- (typeof root === 'string' ? document.querySelector(root) : root) ??
78
- document.body
79
- this.#editor = Editor.make()
80
- .config((ctx) => {
81
- ctx.inject(crepeCtx, this)
82
- })
83
- .config(configureFeatures(enabledFeatures))
84
- .config((ctx) => {
85
- ctx.set(rootCtx, this.#rootElement)
86
- ctx.set(defaultValueCtx, defaultValue)
87
- ctx.set(editorViewOptionsCtx, {
88
- editable: () => this.#editable,
89
- })
90
- ctx.update(indentConfig.key, (value) => ({
91
- ...value,
92
- size: 4,
93
- }))
94
- })
95
- .use(commonmark)
96
- .use(listener)
97
- .use(history)
98
- .use(indent)
99
- .use(trailing)
100
- .use(clipboard)
101
- .use(gfm)
102
-
103
- const promiseList: Promise<unknown>[] = []
104
-
105
43
  enabledFeatures.forEach((feature) => {
106
- const config = (featureConfigs as Partial<Record<CrepeFeature, never>>)[
44
+ const config = (finalConfigs as Partial<Record<CrepeFeature, never>>)[
107
45
  feature
108
46
  ]
109
- promiseList.push(loadFeature(feature, this.#editor, config))
110
- })
111
-
112
- this.#initPromise = Promise.all(promiseList)
113
- }
114
-
115
- /// Create the editor.
116
- create = async () => {
117
- await this.#initPromise
118
- return this.#editor.create()
119
- }
120
-
121
- /// Destroy the editor.
122
- destroy = async () => {
123
- await this.#initPromise
124
- return this.#editor.destroy()
125
- }
126
-
127
- /// Get the milkdown editor instance.
128
- get editor(): Editor {
129
- return this.#editor
130
- }
131
-
132
- /// Set the readonly mode of the editor.
133
- setReadonly = (value: boolean) => {
134
- this.#editable = !value
135
- this.#editor.action((ctx) => {
136
- if (this.#editor.status === EditorStatus.Created) {
137
- const view = ctx.get(editorViewCtx)
138
- view.setProps({
139
- editable: () => !value,
140
- })
141
- }
142
- })
143
- return this
144
- }
145
-
146
- /// Get the markdown content of the editor.
147
- getMarkdown = () => {
148
- return this.#editor.action(getMarkdown())
149
- }
150
-
151
- /// Register event listeners.
152
- on = (fn: (api: ListenerManager) => void) => {
153
- if (this.#editor.status !== EditorStatus.Created) {
154
- this.#editor.config((ctx) => {
155
- const listener = ctx.get(listenerCtx)
156
- fn(listener)
157
- })
158
- return this
159
- }
160
- this.#editor.action((ctx) => {
161
- const listener = ctx.get(listenerCtx)
162
- fn(listener)
47
+ loadFeature(feature, this.editor, config)
163
48
  })
164
- return this
165
49
  }
166
50
  }
package/src/core/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { Crepe, type CrepeConfig } from './crepe'
2
- export { crepeCtx } from './slice'
2
+ export { CrepeBuilder, type CrepeBuilderConfig } from './builder'
3
+ export { useCrepe, useCrepeFeatures } from './slice'
package/src/core/slice.ts CHANGED
@@ -1,27 +1,56 @@
1
- import type { Ctx } from '@milkdown/kit/ctx'
2
-
3
- import { createSlice } from '@milkdown/kit/ctx'
1
+ import { createSlice, type Ctx } from '@milkdown/kit/ctx'
4
2
 
5
3
  import type { CrepeFeature } from '../feature'
6
- import type { Crepe } from './crepe'
4
+ import type { CrepeBuilder } from './builder'
7
5
 
6
+ /// @internal
7
+ /// The feature flags context.
8
+ /// ⚠️ Most of the time, you should use `useCrepeFeatures` to get the features.
8
9
  export const FeaturesCtx = createSlice([] as CrepeFeature[], 'FeaturesCtx')
9
10
 
11
+ /// @internal
12
+ /// The crepe editor context.
13
+ /// ⚠️ Most of the time, you should use `useCrepe` to get the crepe editor instance.
14
+ export const CrepeCtx = createSlice({} as CrepeBuilder, 'CrepeCtx')
15
+
10
16
  /// The crepe editor context.
11
17
  /// You can use this context to access the crepe editor instance within Milkdown plugins.
12
18
  /// ```ts
13
19
  /// import { crepeCtx } from '@milkdown/crepe'
14
20
  /// const plugin = (ctx: Ctx) => {
15
21
  /// return () => {
16
- /// const crepe = ctx.get(crepeCtx)
22
+ /// const crepe = useCrepe(ctx)
17
23
  /// crepe.setReadonly(true)
18
24
  /// }
19
25
  /// }
20
26
  /// ```
21
- export const crepeCtx = createSlice({} as Crepe, 'CrepeCtx')
27
+ export function useCrepe(ctx: Ctx) {
28
+ // We should use string slice here to avoid the slice to be bundled in multiple entries
29
+ return ctx.get<CrepeBuilder, 'CrepeCtx'>('CrepeCtx')
30
+ }
31
+
32
+ /// Check the enabled FeatureFlags
33
+ /// ```ts
34
+ /// import { useCrepeFeatures } from '@milkdown/crepe'
35
+ /// const plugin = (ctx: Ctx) => {
36
+ /// const features = useCrepeFeatures(ctx)
37
+ /// if (features.get().includes(CrepeFeature.CodeMirror)) {
38
+ /// // Do something with CodeMirror
39
+ /// }
40
+ /// }
41
+ export function useCrepeFeatures(ctx: Ctx) {
42
+ // We should use string slice here to avoid the slice to be bundled in multiple entries
43
+ return ctx.use<CrepeFeature[], 'FeaturesCtx'>('FeaturesCtx')
44
+ }
22
45
 
23
- export function configureFeatures(features: CrepeFeature[]) {
46
+ /// @internal
47
+ export function crepeFeatureConfig(feature: CrepeFeature) {
24
48
  return (ctx: Ctx) => {
25
- ctx.inject(FeaturesCtx, features)
49
+ useCrepeFeatures(ctx).update((features) => {
50
+ if (features.includes(feature)) {
51
+ return features
52
+ }
53
+ return [...features, feature]
54
+ })
26
55
  }
27
56
  }
@@ -0,0 +1,25 @@
1
+ import { languages } from '@codemirror/language-data'
2
+ import { oneDark } from '@codemirror/theme-one-dark'
3
+
4
+ import { CrepeFeature, type CrepeFeatureConfig } from '../feature'
5
+ import {
6
+ chevronDownIcon,
7
+ clearIcon,
8
+ editIcon,
9
+ searchIcon,
10
+ visibilityOffIcon,
11
+ } from '../icons'
12
+
13
+ export const defaultConfig: CrepeFeatureConfig = {
14
+ [CrepeFeature.CodeMirror]: {
15
+ theme: oneDark,
16
+ languages,
17
+ expandIcon: chevronDownIcon,
18
+ searchIcon: searchIcon,
19
+ clearSearchIcon: clearIcon,
20
+ searchPlaceholder: 'Search language',
21
+ noResultText: 'No result',
22
+ previewToggleIcon: (previewOnlyMode) =>
23
+ previewOnlyMode ? editIcon : visibilityOffIcon,
24
+ },
25
+ }
@@ -1,15 +1,13 @@
1
1
  import { Icon } from '@milkdown/kit/component'
2
2
  import { defineComponent, ref, h, Fragment } from 'vue'
3
3
 
4
- import type { Icon as IconType } from '../../shared'
5
-
6
4
  h
7
5
  Fragment
8
6
 
9
7
  export interface BlockHandleProps {
10
8
  onAdd: () => void
11
- addIcon: IconType
12
- handleIcon: IconType
9
+ addIcon: string
10
+ handleIcon: string
13
11
  }
14
12
 
15
13
  export const BlockHandle = defineComponent<BlockHandleProps>({
@@ -19,11 +17,11 @@ export const BlockHandle = defineComponent<BlockHandleProps>({
19
17
  required: true,
20
18
  },
21
19
  addIcon: {
22
- type: Function,
20
+ type: String,
23
21
  required: true,
24
22
  },
25
23
  handleIcon: {
26
- type: Function,
24
+ type: String,
27
25
  required: true,
28
26
  },
29
27
  },
@@ -48,10 +46,10 @@ export const BlockHandle = defineComponent<BlockHandleProps>({
48
46
  props.onAdd()
49
47
  }}
50
48
  >
51
- <Icon icon={props.addIcon()} />
49
+ <Icon icon={props.addIcon} />
52
50
  </div>
53
51
  <div class="operation-item">
54
- <Icon icon={props.handleIcon()} />
52
+ <Icon icon={props.handleIcon} />
55
53
  </div>
56
54
  </>
57
55
  )
@@ -26,8 +26,8 @@ export class BlockHandleView implements PluginView {
26
26
  content.classList.add('milkdown-block-handle')
27
27
  const app = createApp(BlockHandle, {
28
28
  onAdd: this.onAdd,
29
- addIcon: config?.handleAddIcon ?? (() => plusIcon),
30
- handleIcon: config?.handleDragIcon ?? (() => menuIcon),
29
+ addIcon: config?.handleAddIcon ?? plusIcon,
30
+ handleIcon: config?.handleDragIcon ?? menuIcon,
31
31
  })
32
32
  app.mount(content)
33
33
  this.#app = app
@@ -1,62 +1,65 @@
1
1
  import { block } from '@milkdown/kit/plugin/block'
2
2
 
3
- import type { DefineFeature, Icon } from '../shared'
3
+ import type { DefineFeature } from '../shared'
4
4
  import type { GroupBuilder } from './menu/group-builder'
5
5
 
6
+ import { crepeFeatureConfig } from '../../core/slice'
7
+ import { CrepeFeature } from '../index'
6
8
  import { configureBlockHandle } from './handle'
7
9
  import { configureMenu, menu, menuAPI } from './menu'
8
10
 
9
11
  interface BlockEditConfig {
10
- handleAddIcon: Icon
11
- handleDragIcon: Icon
12
+ handleAddIcon: string
13
+ handleDragIcon: string
12
14
  buildMenu: (builder: GroupBuilder) => void
13
15
 
14
16
  slashMenuTextGroupLabel: string
15
- slashMenuTextIcon: Icon
17
+ slashMenuTextIcon: string
16
18
  slashMenuTextLabel: string
17
- slashMenuH1Icon: Icon
19
+ slashMenuH1Icon: string
18
20
  slashMenuH1Label: string
19
- slashMenuH2Icon: Icon
21
+ slashMenuH2Icon: string
20
22
  slashMenuH2Label: string
21
- slashMenuH3Icon: Icon
23
+ slashMenuH3Icon: string
22
24
  slashMenuH3Label: string
23
- slashMenuH4Icon: Icon
25
+ slashMenuH4Icon: string
24
26
  slashMenuH4Label: string
25
- slashMenuH5Icon: Icon
27
+ slashMenuH5Icon: string
26
28
  slashMenuH5Label: string
27
- slashMenuH6Icon: Icon
29
+ slashMenuH6Icon: string
28
30
  slashMenuH6Label: string
29
- slashMenuQuoteIcon: Icon
31
+ slashMenuQuoteIcon: string
30
32
  slashMenuQuoteLabel: string
31
- slashMenuDividerIcon: Icon
33
+ slashMenuDividerIcon: string
32
34
  slashMenuDividerLabel: string
33
35
 
34
36
  slashMenuListGroupLabel: string
35
- slashMenuBulletListIcon: Icon
37
+ slashMenuBulletListIcon: string
36
38
  slashMenuBulletListLabel: string
37
- slashMenuOrderedListIcon: Icon
39
+ slashMenuOrderedListIcon: string
38
40
  slashMenuOrderedListLabel: string
39
- slashMenuTaskListIcon: Icon
41
+ slashMenuTaskListIcon: string
40
42
  slashMenuTaskListLabel: string
41
43
 
42
44
  slashMenuAdvancedGroupLabel: string
43
- slashMenuImageIcon: Icon
45
+ slashMenuImageIcon: string
44
46
  slashMenuImageLabel: string
45
- slashMenuCodeBlockIcon: Icon
47
+ slashMenuCodeBlockIcon: string
46
48
  slashMenuCodeBlockLabel: string
47
- slashMenuTableIcon: Icon
49
+ slashMenuTableIcon: string
48
50
  slashMenuTableLabel: string
49
- slashMenuMathIcon: Icon
51
+ slashMenuMathIcon: string
50
52
  slashMenuMathLabel: string
51
53
  }
52
54
 
53
55
  export type BlockEditFeatureConfig = Partial<BlockEditConfig>
54
56
 
55
- export const defineFeature: DefineFeature<BlockEditFeatureConfig> = (
57
+ export const blockEdit: DefineFeature<BlockEditFeatureConfig> = (
56
58
  editor,
57
59
  config
58
60
  ) => {
59
61
  editor
62
+ .config(crepeFeatureConfig(CrepeFeature.BlockEdit))
60
63
  .config((ctx) => configureBlockHandle(ctx, config))
61
64
  .config((ctx) => configureMenu(ctx, config))
62
65
  .use(menuAPI)