@prosekit/extensions 0.10.1 → 0.11.0

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.
@@ -0,0 +1,239 @@
1
+ import { defineFacet, defineFacetPayload, pluginFacet } from "@prosekit/core";
2
+ import { NodeSelection, Plugin, PluginKey, TextSelection } from "@prosekit/pm/state";
3
+ import { isHTMLElement } from "@ocavue/utils";
4
+
5
+ //#region src/drop-indicator/drop-target.ts
6
+ function getTargetsByView(view) {
7
+ let stack = [[-1, view.state.doc]];
8
+ let targets = [];
9
+ while (stack.length > 0) {
10
+ const [pos, node] = stack.pop();
11
+ if (pos >= 0) {
12
+ let dom = view.nodeDOM(pos);
13
+ if (dom && isHTMLElement(dom)) {
14
+ let rect = dom.getBoundingClientRect();
15
+ let { top, bottom, left: x1, right: x2 } = rect;
16
+ targets.push([pos, [
17
+ x1,
18
+ top,
19
+ x2,
20
+ top
21
+ ]], [pos + node.nodeSize, [
22
+ x1,
23
+ bottom,
24
+ x2,
25
+ bottom
26
+ ]]);
27
+ }
28
+ }
29
+ if (node.isBlock && !node.isTextblock) {
30
+ let childPos = pos + 1;
31
+ for (let child of node.children) {
32
+ stack.push([childPos, child]);
33
+ childPos += child.nodeSize;
34
+ }
35
+ }
36
+ }
37
+ return targets;
38
+ }
39
+ /**
40
+ * @internal
41
+ */
42
+ function buildGetTarget(view, onDrag) {
43
+ let prevTargets = [];
44
+ let prevDoc;
45
+ let prevRect;
46
+ const getTargets = () => {
47
+ const rect = view.dom.getBoundingClientRect();
48
+ const doc = view.state.doc;
49
+ if (prevTargets && prevDoc && prevRect && rect.width === prevRect.width && rect.height === prevRect.height && rect.x === prevRect.x && rect.y === prevRect.y && prevDoc.eq(doc)) return prevTargets;
50
+ prevRect = rect;
51
+ prevDoc = doc;
52
+ prevTargets = getTargetsByView(view);
53
+ return prevTargets;
54
+ };
55
+ const getTarget = (point, event) => {
56
+ if (!view.editable || view.isDestroyed) return;
57
+ const compare = (p1, p2) => {
58
+ const [pos1, line1] = p1;
59
+ const [pos2, line2] = p2;
60
+ const p1Distance = pointLineDistance(point, line1);
61
+ const p2Distance = pointLineDistance(point, line2);
62
+ return p1Distance - p2Distance || pos1 - pos2;
63
+ };
64
+ const targets = getTargets();
65
+ targets.sort(compare);
66
+ const target = targets.find((target$1) => onDrag({
67
+ view,
68
+ pos: target$1[0],
69
+ event
70
+ }) !== false);
71
+ return target;
72
+ };
73
+ return getTarget;
74
+ }
75
+ function pointPointDistance(a, b) {
76
+ return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]);
77
+ }
78
+ function pointLineDistance(point, line) {
79
+ return Math.min(pointPointDistance(point, [line[0], line[1]]), pointPointDistance(point, [line[2], line[3]]));
80
+ }
81
+
82
+ //#endregion
83
+ //#region src/drop-indicator/drop-indicator-plugin.ts
84
+ /**
85
+ * @internal
86
+ */
87
+ function createDropIndicatorPlugin(options) {
88
+ let getTarget;
89
+ return new Plugin({
90
+ key: new PluginKey("prosekit-drop-indicator"),
91
+ view: (view) => {
92
+ getTarget = buildGetTarget(view, options.onDrag);
93
+ return createDropIndicatorView(view, getTarget, options);
94
+ },
95
+ props: { handleDrop(view, event, slice, move) {
96
+ if (!getTarget) return false;
97
+ const target = getTarget([event.clientX, event.clientY], event);
98
+ if (!target) return false;
99
+ event.preventDefault();
100
+ let insertPos = target[0];
101
+ let tr = view.state.tr;
102
+ if (move) {
103
+ let { node } = view.dragging || {};
104
+ if (node) node.replace(tr);
105
+ else tr.deleteSelection();
106
+ }
107
+ let pos = tr.mapping.map(insertPos);
108
+ let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1;
109
+ let beforeInsert = tr.doc;
110
+ if (isNode) tr.replaceRangeWith(pos, pos, slice.content.firstChild);
111
+ else tr.replaceRange(pos, pos, slice);
112
+ if (tr.doc.eq(beforeInsert)) return true;
113
+ let $pos = tr.doc.resolve(pos);
114
+ if (isNode && NodeSelection.isSelectable(slice.content.firstChild) && $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) tr.setSelection(new NodeSelection($pos));
115
+ else {
116
+ let end = tr.mapping.map(insertPos);
117
+ tr.mapping.maps[tr.mapping.maps.length - 1].forEach((_from, _to, _newFrom, newTo) => end = newTo);
118
+ tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(end)));
119
+ }
120
+ view.focus();
121
+ view.dispatch(tr.setMeta("uiEvent", "drop"));
122
+ return true;
123
+ } }
124
+ });
125
+ }
126
+ function selectionBetween(view, $anchor, $head, bias) {
127
+ return view.someProp("createSelectionBetween", (f) => f(view, $anchor, $head)) || TextSelection.between($anchor, $head, bias);
128
+ }
129
+ function createDropIndicatorView(view, getTarget, options) {
130
+ let dom = view.dom;
131
+ let hideId;
132
+ let prevX;
133
+ let prevY;
134
+ let hasDragOverEvent = false;
135
+ const scheduleHide = () => {
136
+ if (hideId) clearTimeout(hideId);
137
+ hasDragOverEvent = false;
138
+ hideId = setTimeout(() => {
139
+ if (hasDragOverEvent) return;
140
+ options.onHide();
141
+ }, 30);
142
+ };
143
+ const handleDragOver = (event) => {
144
+ hasDragOverEvent = true;
145
+ const { clientX, clientY } = event;
146
+ if (prevX === clientX && prevY === clientY) return;
147
+ prevX = clientX;
148
+ prevY = clientY;
149
+ let target = getTarget([clientX, clientY], event);
150
+ if (!target) {
151
+ scheduleHide();
152
+ return;
153
+ } else {
154
+ const [pos, [x1, y1, x2, y2]] = target;
155
+ const line = {
156
+ p1: {
157
+ x: x1,
158
+ y: y1
159
+ },
160
+ p2: {
161
+ x: x2,
162
+ y: y2
163
+ }
164
+ };
165
+ options.onShow({
166
+ view,
167
+ pos,
168
+ line
169
+ });
170
+ }
171
+ };
172
+ dom.addEventListener("dragover", handleDragOver);
173
+ dom.addEventListener("dragend", scheduleHide);
174
+ dom.addEventListener("drop", scheduleHide);
175
+ dom.addEventListener("dragleave", scheduleHide);
176
+ const destroy = () => {
177
+ dom.removeEventListener("dragover", handleDragOver);
178
+ dom.removeEventListener("dragend", scheduleHide);
179
+ dom.removeEventListener("drop", scheduleHide);
180
+ dom.removeEventListener("dragleave", scheduleHide);
181
+ };
182
+ return { destroy };
183
+ }
184
+
185
+ //#endregion
186
+ //#region src/drop-indicator/drop-indicator-facet.ts
187
+ /**
188
+ * @internal
189
+ */
190
+ function defineDropIndicatorPayload(payload) {
191
+ return defineFacetPayload(dropIndicatorFacet, [payload]);
192
+ }
193
+ const dropIndicatorFacet = defineFacet({
194
+ parent: pluginFacet,
195
+ singleton: true,
196
+ reducer: (payloads) => {
197
+ let showHandlers = payloads.map((p) => p.onShow).filter((x) => !!x);
198
+ let hideHandlers = payloads.map((p) => p.onHide).filter((x) => !!x);
199
+ let dragHandlers = payloads.map((p) => p.onDrag).filter((x) => !!x);
200
+ let showHandler = (options) => {
201
+ for (let fn of showHandlers) fn(options);
202
+ };
203
+ let hideHandler = () => {
204
+ for (let fn of hideHandlers) fn();
205
+ };
206
+ let dragHandler = (options) => {
207
+ for (let fn of dragHandlers) if (fn(options) === false) return false;
208
+ return true;
209
+ };
210
+ if (showHandlers.length === 0) return [];
211
+ return createDropIndicatorPlugin({
212
+ onDrag: dragHandler,
213
+ onShow: showHandler,
214
+ onHide: hideHandler
215
+ });
216
+ }
217
+ });
218
+
219
+ //#endregion
220
+ //#region src/drop-indicator/drop-indicator.ts
221
+ /**
222
+ * Defines an extension that controls the behavior of the drop indicator.
223
+ *
224
+ * This extension itself doesn't draw the drop indicator, but it provides the
225
+ * necessary callbacks to do so. You probably don't want to use this extension
226
+ * directly, but rather use the `<DropIndicator>` component.
227
+ *
228
+ * You can add this extension multiple times. If any extension has `onDrag`
229
+ * callback defined, and it returns `false`, then the drop point will be
230
+ * discarded.
231
+ *
232
+ * @public
233
+ */
234
+ function defineDropIndicator(options) {
235
+ return defineDropIndicatorPayload(options ?? {});
236
+ }
237
+
238
+ //#endregion
239
+ export { defineDropIndicator };
@@ -1,89 +1,129 @@
1
- /* src/style.css */
2
- .prosemirror-flat-list {
3
- padding: 0;
4
- margin-top: 0;
5
- margin-bottom: 0;
6
- margin-left: 32px;
7
- margin-bottom: 0;
8
- position: relative;
9
- display: list-item;
10
- list-style: none;
11
- }
12
- .prosemirror-flat-list.ProseMirror-selectednode {
13
- outline: none;
14
- }
15
- .prosemirror-flat-list.ProseMirror-selectednode:after {
16
- content: "";
17
- position: absolute;
18
- left: -32px;
19
- right: -2px;
20
- top: -2px;
21
- bottom: -2px;
22
- border: 2px solid #8cf;
23
- pointer-events: none;
24
- }
25
- .prosemirror-flat-list[data-list-kind=bullet] {
26
- list-style: disc;
27
- }
28
- .prosemirror-flat-list[data-list-kind=ordered] > * {
29
- contain: style;
30
- }
31
- .prosemirror-flat-list[data-list-kind=ordered]::before {
32
- position: absolute;
33
- right: 100%;
34
- font-variant-numeric: tabular-nums;
35
- content: counter(prosemirror-flat-list-counter, decimal) ". ";
1
+ :root {
2
+ --prosekit-list-bullet-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='2.5' fill='currentColor'/%3E%3C/svg%3E");
3
+ --prosekit-list-toggle-open-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpolygon points='8,10 12,14 16,10' fill='currentColor'/%3E%3C/svg%3E");
4
+ --prosekit-list-toggle-closed-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpolygon points='10,8 14,12 10,16' fill='currentColor'/%3E%3C/svg%3E");
36
5
  }
37
- .prosemirror-flat-list[data-list-kind=ordered] {
38
- counter-increment: prosemirror-flat-list-counter;
39
- }
40
- .prosemirror-flat-list[data-list-kind=ordered]:first-child,
41
- :not(.prosemirror-flat-list[data-list-kind=ordered]) + .prosemirror-flat-list[data-list-kind=ordered] {
42
- counter-reset: prosemirror-flat-list-counter;
43
- }
44
- @supports (counter-set: prosemirror-flat-list-counter 1) {
45
- [data-list-order]:is(.prosemirror-flat-list[data-list-kind=ordered]:first-child, :not(.prosemirror-flat-list[data-list-kind=ordered]) + .prosemirror-flat-list[data-list-kind=ordered]) {
46
- counter-set: prosemirror-flat-list-counter var(--prosemirror-flat-list-order);
6
+
7
+ .prosemirror-flat-list {
8
+ & {
9
+ position: relative;
10
+ margin: 0;
11
+ padding: 0;
12
+ list-style: none;
47
13
  }
48
- }
49
- @supports not (counter-set: prosemirror-flat-list-counter 1) {
50
- [data-list-order]:is(.prosemirror-flat-list[data-list-kind=ordered]:first-child, :not(.prosemirror-flat-list[data-list-kind=ordered]) + .prosemirror-flat-list[data-list-kind=ordered]) {
51
- counter-increment: prosemirror-flat-list-counter var(--prosemirror-flat-list-order);
14
+
15
+ & > .list-marker {
16
+ position: absolute;
17
+ left: 0;
18
+ width: 1.5em;
19
+ width: 1lh;
20
+ height: 1.5em;
21
+ height: 1lh;
22
+ text-align: center;
52
23
  }
53
- }
54
- .prosemirror-flat-list[data-list-kind=task] > .list-marker {
55
- position: absolute;
56
- right: 100%;
57
- text-align: center;
58
- width: 1.5em;
59
- width: 1lh;
60
- }
61
- :is(.prosemirror-flat-list[data-list-kind=task] > .list-marker),
62
- :is(.prosemirror-flat-list[data-list-kind=task] > .list-marker) * {
63
- cursor: pointer;
64
- }
65
- .prosemirror-flat-list[data-list-kind=toggle] > .list-marker {
66
- position: absolute;
67
- right: 100%;
68
- text-align: center;
69
- width: 1.5em;
70
- width: 1lh;
71
- }
72
- .prosemirror-flat-list[data-list-kind=toggle] > .list-marker::before {
73
- content: "\23f7";
74
- }
75
- .prosemirror-flat-list[data-list-kind=toggle][data-list-collapsable][data-list-collapsed] > .list-marker::before {
76
- content: "\23f5";
77
- }
78
- .prosemirror-flat-list[data-list-kind=toggle][data-list-collapsable] > .list-marker {
79
- cursor: pointer;
80
- }
81
- .prosemirror-flat-list[data-list-kind=toggle]:not([data-list-collapsable]) > .list-marker {
82
- opacity: 40%;
83
- pointer-events: none;
84
- }
85
- .prosemirror-flat-list[data-list-kind=toggle][data-list-collapsable][data-list-collapsed] > .list-content > *:nth-child(n+2) {
86
- display: none;
87
- }
88
24
 
25
+ & > .list-content {
26
+ margin-left: 1.5em;
27
+ margin-left: 1lh;
28
+ }
29
+
30
+ &[data-list-kind="bullet"] > .list-marker,
31
+ &[data-list-kind="toggle"] > .list-marker {
32
+ background-color: currentColor;
33
+ mask-position: center;
34
+ mask-repeat: no-repeat;
35
+ mask-size: contain;
36
+ }
37
+
38
+ &[data-list-kind="bullet"] {
39
+ & > .list-marker {
40
+ mask-image: var(--prosekit-list-bullet-icon);
41
+ }
42
+ }
43
+
44
+ &[data-list-kind="toggle"] {
45
+ & > .list-marker {
46
+ mask-image: var(--prosekit-list-toggle-open-icon);
47
+ }
48
+
49
+ &[data-list-collapsable][data-list-collapsed] > .list-marker {
50
+ mask-image: var(--prosekit-list-toggle-closed-icon);
51
+ }
52
+ }
53
+
54
+ &[data-list-kind="ordered"] {
55
+ /*
56
+ Ensure that the counters in children don't escape, so that the sub lists
57
+ won't affect the counter of the parent list.
58
+
59
+ See also https://github.com/ocavue/prosemirror-flat-list/issues/23
60
+ */
61
+ & > * {
62
+ contain: style;
63
+ }
64
+
65
+ &::before {
66
+ position: absolute;
67
+ right: calc(100% - 1.5em);
68
+ right: calc(100% - 1lh);
69
+ content: counter(prosemirror-flat-list-counter, decimal) ". ";
70
+ font-variant-numeric: tabular-nums;
71
+ }
72
+ counter-increment: prosemirror-flat-list-counter;
73
+
74
+ /*
75
+ Reset the counter for the first list node in the sequence.
76
+ */
77
+ &:first-child,
78
+ :not(&) + & {
79
+ counter-reset: prosemirror-flat-list-counter;
80
+
81
+ /*
82
+ If the first list node has a custom order number, set the counter to that value.
83
+ */
84
+ &[data-list-order] {
85
+ @supports (counter-set: prosemirror-flat-list-counter 1) {
86
+ counter-set: prosemirror-flat-list-counter var(--prosemirror-flat-list-order);
87
+ }
88
+
89
+ /*
90
+ Safari older than version 17.2 doesn't support `counter-set`
91
+ */
92
+ @supports not (counter-set: prosemirror-flat-list-counter 1) {
93
+ counter-increment: prosemirror-flat-list-counter var(--prosemirror-flat-list-order);
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ &[data-list-kind="task"] {
100
+ & > .list-marker {
101
+ &,
102
+ & * {
103
+ /* Make sure that the checkbox is at the center */
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: center;
107
+ margin: 0;
108
+ padding: 0;
109
+ cursor: pointer;
110
+ }
111
+ }
112
+ }
113
+
114
+ &[data-list-kind="toggle"] {
115
+ &[data-list-collapsable] > .list-marker {
116
+ cursor: pointer;
117
+ }
118
+ &:not([data-list-collapsable]) > .list-marker {
119
+ opacity: 40%;
120
+ pointer-events: none;
121
+ }
122
+
123
+ /* If collapsed, hide the second and futher children */
124
+ &[data-list-collapsable][data-list-collapsed] > .list-content > *:nth-child(n+2) {
125
+ display: none;
126
+ }
127
+ }
128
+ }
89
129
 
@@ -1,4 +1,4 @@
1
- import { ShikiHighlighterOptions } from "./shiki-highlighter-chunk-CZGvZlhf.js";
1
+ import { ShikiHighlighterOptions } from "./shiki-highlighter-chunk-NV2F_Qjl.js";
2
2
  import { Extension, PlainExtension, Union } from "@prosekit/core";
3
3
  import { Parser } from "prosemirror-highlight";
4
4
  import { BundledLanguage as ShikiBundledLanguage, BundledLanguageInfo as ShikiBundledLanguageInfo, BundledTheme as ShikiBundledTheme, BundledThemeInfo as ShikiBundledThemeInfo, SpecialLanguage, bundledLanguagesInfo as shikiBundledLanguagesInfo, bundledThemesInfo as shikiBundledThemesInfo } from "shiki";
@@ -28,6 +28,8 @@ type DropCursorExtension = PlainExtension;
28
28
  *
29
29
  * See [prosemirror-dropcursor](https://github.com/ProseMirror/prosemirror-dropcursor) for more information.
30
30
  *
31
+ * You probably want to use `<DropIndicator />` component instead of this extension.
32
+ *
31
33
  * @public
32
34
  */
33
35
  declare function defineDropCursor(options?: DropCursorOptions): DropCursorExtension;
@@ -7,6 +7,8 @@ import { dropCursor } from "prosemirror-dropcursor";
7
7
  *
8
8
  * See [prosemirror-dropcursor](https://github.com/ProseMirror/prosemirror-dropcursor) for more information.
9
9
  *
10
+ * You probably want to use `<DropIndicator />` component instead of this extension.
11
+ *
10
12
  * @public
11
13
  */
12
14
  function defineDropCursor(options) {
@@ -0,0 +1,120 @@
1
+ import { PlainExtension } from "@prosekit/core";
2
+ import { EditorView } from "@prosekit/pm/view";
3
+
4
+ //#region src/drop-indicator/types.d.ts
5
+
6
+ /**
7
+ * A function that will be called when the `dragover` event is fired. You can
8
+ * return `false` to disable the current drop point and thus hide the drop
9
+ * indicator.
10
+ *
11
+ * @public
12
+ */
13
+ type DragEventHandler = (options: DragEventHandlerOptions) => boolean;
14
+ /**
15
+ * Options for {@link DragEventHandler}.
16
+ *
17
+ * @public
18
+ */
19
+ interface DragEventHandlerOptions {
20
+ /**
21
+ * The editor's view.
22
+ */
23
+ view: EditorView;
24
+ /**
25
+ * The drop position in current document.
26
+ */
27
+ pos: number;
28
+ /**
29
+ * The `dragover` event.
30
+ */
31
+ event: DragEvent;
32
+ }
33
+ /**
34
+ * A function that will be called when the drop indicator should be shown.
35
+ *
36
+ * @public
37
+ */
38
+ type ShowHandler = (options: ShowHandlerOptions) => void;
39
+ /**
40
+ * Options for {@link ShowHandler}.
41
+ *
42
+ * @public
43
+ */
44
+ interface ShowHandlerOptions {
45
+ /**
46
+ * The editor's view.
47
+ */
48
+ view: EditorView;
49
+ /**
50
+ * The ProseMirror position that the drop indicator should be shown at.
51
+ */
52
+ pos: number;
53
+ /**
54
+ * The line that the drop indicator should be shown at.
55
+ */
56
+ line: Line;
57
+ }
58
+ /**
59
+ * @internal
60
+ */
61
+ interface Point {
62
+ readonly x: number;
63
+ readonly y: number;
64
+ }
65
+ /**
66
+ * @internal
67
+ */
68
+ interface Line {
69
+ readonly p1: Point;
70
+ readonly p2: Point;
71
+ }
72
+ //#endregion
73
+ //#region src/drop-indicator/drop-indicator-facet.d.ts
74
+ /**
75
+ * @internal
76
+ */
77
+ interface DropIndicatorPayload {
78
+ /**
79
+ * A callback that is called when the drop indicator should be shown.
80
+ */
81
+ onShow?: ShowHandler;
82
+ /**
83
+ * A callback that is called when the drop indicator should be hidden.
84
+ */
85
+ onHide?: VoidFunction;
86
+ /**
87
+ * A callback that is called when the `dragover` event is fired. You can
88
+ * return `false` to disable the current drop point and thus hide the drop
89
+ * indicator.
90
+ */
91
+ onDrag?: DragEventHandler;
92
+ }
93
+ //#endregion
94
+ //#region src/drop-indicator/drop-indicator.d.ts
95
+ /**
96
+ * @internal
97
+ */
98
+ type DropIndicatorExtension = PlainExtension;
99
+ /**
100
+ * Defines an extension that controls the behavior of the drop indicator.
101
+ *
102
+ * This extension itself doesn't draw the drop indicator, but it provides the
103
+ * necessary callbacks to do so. You probably don't want to use this extension
104
+ * directly, but rather use the `<DropIndicator>` component.
105
+ *
106
+ * You can add this extension multiple times. If any extension has `onDrag`
107
+ * callback defined, and it returns `false`, then the drop point will be
108
+ * discarded.
109
+ *
110
+ * @public
111
+ */
112
+ declare function defineDropIndicator(options?: DropIndicatorOptions): DropIndicatorExtension;
113
+ /**
114
+ * Options for {@link defineDropIndicator}.
115
+ *
116
+ * @public
117
+ */
118
+ interface DropIndicatorOptions extends DropIndicatorPayload {}
119
+ //#endregion
120
+ export { type DragEventHandler, type DragEventHandlerOptions, type DropIndicatorExtension, type DropIndicatorOptions, type Line, type Point, type ShowHandler, type ShowHandlerOptions, defineDropIndicator };
@@ -0,0 +1,3 @@
1
+ import { defineDropIndicator } from "./drop-indicator-CCCaHFvw.js";
2
+
3
+ export { defineDropIndicator };
@@ -1,6 +1,6 @@
1
1
  import { defineInputRule } from "./input-rule-Gji4N7Oe.js";
2
2
  import { defineEnterRule } from "./enter-rule-RdhEA900.js";
3
- import { defineMarkRule } from "./mark-rule-wEOcDt6i.js";
3
+ import { defineMarkRule } from "./mark-rule-D7zaa32n.js";
4
4
  import { addMark, defineCommands, defineMarkSpec, expandMark, removeMark, toggleMark, union } from "@prosekit/core";
5
5
  import { InputRule } from "@prosekit/pm/inputrules";
6
6
 
@@ -1,9 +1,10 @@
1
1
  import { defineInputRule } from "./input-rule-Gji4N7Oe.js";
2
+ import { defineDropIndicator } from "./drop-indicator-CCCaHFvw.js";
2
3
  import { defineClipboardSerializer, defineCommands, defineKeymap, defineNodeSpec, definePlugin, insertNode, union } from "@prosekit/core";
3
4
  import { Plugin } from "@prosekit/pm/state";
4
5
  import { chainCommands, deleteSelection } from "@prosekit/pm/commands";
5
- import { ListDOMSerializer, createDedentListCommand, createIndentListCommand, createListEventPlugin, createListRenderingPlugin, createListSpec, createMoveListCommand, createSafariInputMethodWorkaroundPlugin, createSplitListCommand, createToggleCollapsedCommand, createToggleListCommand, createUnwrapListCommand, createWrapInListCommand, deleteCommand, enterCommand, joinCollapsedListBackward, joinListElements, joinListUp, listInputRules, listToDOM, protectCollapsed, unwrapListSlice } from "prosemirror-flat-list";
6
6
  import { isElementLike } from "@ocavue/utils";
7
+ import { ListDOMSerializer, createDedentListCommand, createIndentListCommand, createListEventPlugin, createListRenderingPlugin, createListSpec, createMoveListCommand, createSafariInputMethodWorkaroundPlugin, createSplitListCommand, createToggleCollapsedCommand, createToggleListCommand, createUnwrapListCommand, createWrapInListCommand, deleteCommand, enterCommand, joinCollapsedListBackward, joinListElements, joinListUp, listInputRules, listToDOM, protectCollapsed, unwrapListSlice } from "prosemirror-flat-list";
7
8
 
8
9
  //#region src/list/list-commands.ts
9
10
  function insertList(attrs) {
@@ -31,6 +32,31 @@ function defineListCommands() {
31
32
  });
32
33
  }
33
34
 
35
+ //#endregion
36
+ //#region src/list/list-drop-indicator.ts
37
+ /**
38
+ * Configures drop indicator to avoid unexpected drop point.
39
+ *
40
+ * We don't want to drag a list node and drop it as the first
41
+ * child of another list node.
42
+ *
43
+ * @internal
44
+ */
45
+ function defineListDropIndicator() {
46
+ return defineDropIndicator({ onDrag });
47
+ }
48
+ const onDrag = ({ view, pos }) => {
49
+ const slice = view.dragging?.slice;
50
+ if (slice && slice.openStart === 0 && slice.openEnd === 0 && slice.content.childCount === 1) {
51
+ const node = slice.content.child(0);
52
+ if (node.type.name === "list") {
53
+ const $pos = view.state.doc.resolve(pos);
54
+ if ($pos.parent.type.name === "list" && $pos.index() === 0) return false;
55
+ }
56
+ }
57
+ return true;
58
+ };
59
+
34
60
  //#endregion
35
61
  //#region src/list/list-input-rules.ts
36
62
  /**
@@ -120,12 +146,29 @@ function defineListSerializer() {
120
146
 
121
147
  //#endregion
122
148
  //#region src/list/list-spec.ts
149
+ function getMarkers(node) {
150
+ const attrs = node.attrs;
151
+ switch (attrs.kind) {
152
+ case "task": return [["label", ["input", {
153
+ type: "checkbox",
154
+ checked: attrs.checked ? "" : void 0
155
+ }]]];
156
+ default: return [];
157
+ }
158
+ }
123
159
  /**
124
160
  * @internal
125
161
  */
126
162
  function defineListSpec() {
163
+ const spec = createListSpec();
127
164
  return defineNodeSpec({
128
- ...createListSpec(),
165
+ ...spec,
166
+ toDOM: (node) => {
167
+ return listToDOM({
168
+ node,
169
+ getMarkers
170
+ });
171
+ },
129
172
  name: "list"
130
173
  });
131
174
  }
@@ -136,7 +179,7 @@ function defineListSpec() {
136
179
  * @public
137
180
  */
138
181
  function defineList() {
139
- return union(defineListSpec(), defineListPlugins(), defineListKeymap(), defineListInputRules(), defineListCommands(), defineListSerializer());
182
+ return union(defineListSpec(), defineListPlugins(), defineListKeymap(), defineListInputRules(), defineListCommands(), defineListSerializer(), defineListDropIndicator());
140
183
  }
141
184
 
142
185
  //#endregion
@@ -1,3 +1,3 @@
1
- import { defineMarkRule } from "./mark-rule-wEOcDt6i.js";
1
+ import { defineMarkRule } from "./mark-rule-D7zaa32n.js";
2
2
 
3
3
  export { defineMarkRule };
@@ -1,4 +1,4 @@
1
- import { findTable } from "./table-dVQqzLlz.js";
1
+ import { findTable } from "./table-3rDWFyBH.js";
2
2
  import { definePlugin, isInCodeBlock, maybeRun } from "@prosekit/core";
3
3
  import { Plugin, PluginKey } from "@prosekit/pm/state";
4
4
  import { Decoration, DecorationSet } from "@prosekit/pm/view";
@@ -1,3 +1,3 @@
1
- import { defineTable, defineTableCellSpec, defineTableCommands, defineTableHeaderCellSpec, defineTablePlugins, defineTableRowSpec, defineTableSpec, exitTable, findTable, insertTable, isCellSelection, moveTableColumn, moveTableRow, selectTable, selectTableCell, selectTableColumn, selectTableRow } from "./table-dVQqzLlz.js";
1
+ import { defineTable, defineTableCellSpec, defineTableCommands, defineTableHeaderCellSpec, defineTablePlugins, defineTableRowSpec, defineTableSpec, exitTable, findTable, insertTable, isCellSelection, moveTableColumn, moveTableRow, selectTable, selectTableCell, selectTableColumn, selectTableRow } from "./table-3rDWFyBH.js";
2
2
 
3
3
  export { defineTable, defineTableCellSpec, defineTableCommands, defineTableHeaderCellSpec, defineTablePlugins, defineTableRowSpec, defineTableSpec, exitTable, findTable, insertTable, isCellSelection, moveTableColumn, moveTableRow, selectTable, selectTableCell, selectTableColumn, selectTableRow };
@@ -1,2 +1,2 @@
1
- import { HighlighterOptions, HighlighterResult, ShikiHighlighterOptions, createOrGetHighlighter } from "./shiki-highlighter-chunk-CZGvZlhf.js";
1
+ import { HighlighterOptions, HighlighterResult, ShikiHighlighterOptions, createOrGetHighlighter } from "./shiki-highlighter-chunk-NV2F_Qjl.js";
2
2
  export { HighlighterOptions, HighlighterResult, ShikiHighlighterOptions, createOrGetHighlighter };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/extensions",
3
3
  "type": "module",
4
- "version": "0.10.1",
4
+ "version": "0.11.0",
5
5
  "private": false,
6
6
  "description": "A collection of common extensions for ProseKit",
7
7
  "author": {
@@ -65,6 +65,10 @@
65
65
  "types": "./dist/prosekit-extensions-drop-cursor.d.ts",
66
66
  "default": "./dist/prosekit-extensions-drop-cursor.js"
67
67
  },
68
+ "./drop-indicator": {
69
+ "types": "./dist/prosekit-extensions-drop-indicator.d.ts",
70
+ "default": "./dist/prosekit-extensions-drop-indicator.js"
71
+ },
68
72
  "./enter-rule": {
69
73
  "types": "./dist/prosekit-extensions-enter-rule.d.ts",
70
74
  "default": "./dist/prosekit-extensions-enter-rule.js"
@@ -198,7 +202,7 @@
198
202
  "dist"
199
203
  ],
200
204
  "dependencies": {
201
- "@ocavue/utils": "^0.5.0",
205
+ "@ocavue/utils": "^0.6.0",
202
206
  "prosemirror-changeset": "^2.3.1",
203
207
  "prosemirror-dropcursor": "^1.8.2",
204
208
  "prosemirror-flat-list": "^0.5.5",
@@ -206,7 +210,7 @@
206
210
  "prosemirror-highlight": "^0.13.0",
207
211
  "prosemirror-search": "^1.1.0",
208
212
  "prosemirror-tables": "^1.7.1",
209
- "shiki": "^3.8.1",
213
+ "shiki": "^3.9.1",
210
214
  "@prosekit/core": "^0.8.3",
211
215
  "@prosekit/pm": "^0.1.11"
212
216
  },
@@ -242,7 +246,7 @@
242
246
  "remark-html": "^16.0.1",
243
247
  "remark-parse": "^11.0.0",
244
248
  "remark-stringify": "^11.0.0",
245
- "tsdown": "^0.13.0",
249
+ "tsdown": "^0.13.1",
246
250
  "type-fest": "^4.41.0",
247
251
  "typescript": "~5.8.3",
248
252
  "unified": "^11.0.5",
@@ -250,8 +254,8 @@
250
254
  "y-prosemirror": "^1.3.7",
251
255
  "y-protocols": "^1.0.6",
252
256
  "yjs": "^13.6.27",
253
- "@prosekit/config-tsdown": "0.0.0",
254
- "@prosekit/config-vitest": "0.0.0"
257
+ "@prosekit/config-vitest": "0.0.0",
258
+ "@prosekit/config-tsdown": "0.0.0"
255
259
  },
256
260
  "publishConfig": {
257
261
  "dev": {}
@@ -268,6 +272,7 @@
268
272
  "commit/style": "./src/commit/style.css",
269
273
  "prosekit-extensions-doc": "./src/doc/index.ts",
270
274
  "prosekit-extensions-drop-cursor": "./src/drop-cursor/index.ts",
275
+ "prosekit-extensions-drop-indicator": "./src/drop-indicator/index.ts",
271
276
  "prosekit-extensions-enter-rule": "./src/enter-rule/index.ts",
272
277
  "prosekit-extensions-file": "./src/file/index.ts",
273
278
  "prosekit-extensions-gap-cursor": "./src/gap-cursor/index.ts",
@@ -338,6 +343,9 @@
338
343
  "drop-cursor": [
339
344
  "./dist/prosekit-extensions-drop-cursor.d.ts"
340
345
  ],
346
+ "drop-indicator": [
347
+ "./dist/prosekit-extensions-drop-indicator.d.ts"
348
+ ],
341
349
  "enter-rule": [
342
350
  "./dist/prosekit-extensions-enter-rule.d.ts"
343
351
  ],
File without changes