@meowdown/react 0.16.2 → 0.17.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.
- package/README.md +2 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +19 -175
- package/dist/style.css +3 -11
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ export function App() {
|
|
|
32
32
|
|
|
33
33
|
### `<MeowdownEditor>`
|
|
34
34
|
|
|
35
|
-
The Markdown editor component. Renders inside a `div.meowdown` wrapper that fills a flex parent. In rich modes, typing `/` opens a slash menu for inserting blocks (headings, blockquote, lists, code block, table). Hovering a block shows a handle to its left: the
|
|
35
|
+
The Markdown editor component. Renders inside a `div.meowdown` wrapper that fills a flex parent. In rich modes, typing `/` opens a slash menu for inserting blocks (headings, blockquote, lists, code block, table). Hovering a block shows a handle to its left: the grip selects the block and can be dragged to move it, with a drop indicator line marking the target.
|
|
36
36
|
|
|
37
37
|
- `mode?: 'focus' | 'show' | 'hide' | 'source'`: defaults to `'focus'`.
|
|
38
38
|
- `'focus'`: Markdown syntax is hidden, revealed around the cursor.
|
|
@@ -51,7 +51,7 @@ The Markdown editor component. Renders inside a `div.meowdown` wrapper that fill
|
|
|
51
51
|
- `onImageClick?: (payload: { src: string; alt: string; event: MouseEvent }) => void`: called when a rendered image is clicked, with its markdown `src`, `alt`, and the originating `MouseEvent`. Pass a stable function (e.g. from `useCallback`). Ignored in source mode.
|
|
52
52
|
- `embedPaste?: boolean`: auto-embeds a pasted tweet or YouTube link as a rich embed; one undo turns the embed back into the raw link. On by default; set `false` to disable. Only takes effect when `resolveImageUrl` is set, since embeds render through the image pipeline. Ignored in source mode.
|
|
53
53
|
- `bulletAfterHeading?: boolean`: pressing Enter at the end of the document's first heading (the title line) starts a fresh empty bullet on the next line instead of a plain paragraph. Off by default. Ignored in source mode.
|
|
54
|
-
- `blockHandle?: boolean`: shows the per-block gutter handle in the rich modes (a drag grip for reordering blocks
|
|
54
|
+
- `blockHandle?: boolean`: shows the per-block gutter handle in the rich modes (a drag grip for reordering blocks, plus the drop indicator). On by default; set `false` to hide the gutter affordance entirely, e.g. when the host does not want block reordering. Ignored in source mode and when `readOnly` is set.
|
|
55
55
|
- `placeholder?: string | ((state) => string)`: placeholder text shown when the whole document is empty. Pass a stable function. Ignored in source mode.
|
|
56
56
|
- `readOnly?: boolean`: makes the editor read-only, in both the rich and source modes.
|
|
57
57
|
- `spellCheck?: boolean`: toggles the browser's native spell checking in the rich modes. Defaults to the browser's behavior. Ignored in source mode.
|
package/dist/index.d.ts
CHANGED
|
@@ -155,6 +155,8 @@ interface EditorProps {
|
|
|
155
155
|
* Off by default. Ignored in source mode.
|
|
156
156
|
*/
|
|
157
157
|
bulletAfterHeading?: boolean;
|
|
158
|
+
/** Handles a leading `---` frontmatter block in the rich modes (off by default, ignored in source mode). */
|
|
159
|
+
frontmatter?: boolean;
|
|
158
160
|
/**
|
|
159
161
|
* Shows the per-block gutter handle in the rich modes: a drag grip for
|
|
160
162
|
* reordering blocks and a "+" add button, plus the drop indicator that
|
|
@@ -198,6 +200,7 @@ declare function MeowdownEditor({
|
|
|
198
200
|
onImageClick,
|
|
199
201
|
embedPaste,
|
|
200
202
|
bulletAfterHeading,
|
|
203
|
+
frontmatter,
|
|
201
204
|
blockHandle,
|
|
202
205
|
placeholder,
|
|
203
206
|
readOnly,
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,8 @@ import { canUseRegexLookbehind, createEditor, defineDocChangeHandler, union } fr
|
|
|
12
12
|
import { Selection, TextSelection } from "@prosekit/pm/state";
|
|
13
13
|
import { ProseKit, defineReactNodeView, useEditor, useEditor as useEditor$1, useEditorDerivedValue, useExtension, useExtension as useExtension$1, useKeymap } from "@prosekit/react";
|
|
14
14
|
import { Combobox } from "@base-ui/react/combobox";
|
|
15
|
-
import {
|
|
15
|
+
import { CheckIcon, ChevronsUpDownIcon, CopyIcon, GripHorizontalIcon, GripVerticalIcon } from "lucide-react";
|
|
16
|
+
import { BlockHandleDraggable, BlockHandlePopup, BlockHandlePositioner, BlockHandleRoot } from "@prosekit/react/block-handle";
|
|
16
17
|
import { DropIndicator } from "@prosekit/react/drop-indicator";
|
|
17
18
|
import { AutocompleteEmpty, AutocompleteItem, AutocompletePopup, AutocompletePositioner, AutocompleteRoot } from "@prosekit/react/autocomplete";
|
|
18
19
|
import { MenuItem, MenuPopup, MenuPositioner } from "@prosekit/react/menu";
|
|
@@ -152,58 +153,6 @@ var code_block_view_module_default = {
|
|
|
152
153
|
"TriggerIcon": "meow_TriggerIcon_D3j_9q"
|
|
153
154
|
};
|
|
154
155
|
|
|
155
|
-
//#endregion
|
|
156
|
-
//#region src/components/icons/check-icon.tsx
|
|
157
|
-
function CheckIcon() {
|
|
158
|
-
return /* @__PURE__ */ jsx("svg", {
|
|
159
|
-
viewBox: "0 0 24 24",
|
|
160
|
-
fill: "none",
|
|
161
|
-
stroke: "currentColor",
|
|
162
|
-
strokeWidth: 2,
|
|
163
|
-
strokeLinecap: "round",
|
|
164
|
-
strokeLinejoin: "round",
|
|
165
|
-
"aria-hidden": "true",
|
|
166
|
-
children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" })
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/components/icons/chevrons-up-down-icon.tsx
|
|
172
|
-
function ChevronsUpDownIcon() {
|
|
173
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
174
|
-
viewBox: "0 0 24 24",
|
|
175
|
-
fill: "none",
|
|
176
|
-
stroke: "currentColor",
|
|
177
|
-
strokeWidth: 2,
|
|
178
|
-
strokeLinecap: "round",
|
|
179
|
-
strokeLinejoin: "round",
|
|
180
|
-
"aria-hidden": "true",
|
|
181
|
-
children: [/* @__PURE__ */ jsx("path", { d: "m7 15 5 5 5-5" }), /* @__PURE__ */ jsx("path", { d: "m7 9 5-5 5 5" })]
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
//#endregion
|
|
186
|
-
//#region src/components/icons/copy-icon.tsx
|
|
187
|
-
function CopyIcon() {
|
|
188
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
189
|
-
viewBox: "0 0 24 24",
|
|
190
|
-
fill: "none",
|
|
191
|
-
stroke: "currentColor",
|
|
192
|
-
strokeWidth: 2,
|
|
193
|
-
strokeLinecap: "round",
|
|
194
|
-
strokeLinejoin: "round",
|
|
195
|
-
"aria-hidden": "true",
|
|
196
|
-
children: [/* @__PURE__ */ jsx("rect", {
|
|
197
|
-
width: "14",
|
|
198
|
-
height: "14",
|
|
199
|
-
x: "8",
|
|
200
|
-
y: "8",
|
|
201
|
-
rx: "2",
|
|
202
|
-
ry: "2"
|
|
203
|
-
}), /* @__PURE__ */ jsx("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })]
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
|
|
207
156
|
//#endregion
|
|
208
157
|
//#region src/components/code-block-view.tsx
|
|
209
158
|
const COPIED_RESET_MS = 1500;
|
|
@@ -333,90 +282,24 @@ function defineCodeBlockView() {
|
|
|
333
282
|
//#endregion
|
|
334
283
|
//#region src/components/block-handle.module.css
|
|
335
284
|
var block_handle_module_default = {
|
|
336
|
-
"Add": "meow_Add_EvUpOG",
|
|
337
285
|
"Draggable": "meow_Draggable_EvUpOG",
|
|
338
286
|
"Popup": "meow_Popup_EvUpOG",
|
|
339
287
|
"Positioner": "meow_Positioner_EvUpOG"
|
|
340
288
|
};
|
|
341
289
|
|
|
342
|
-
//#endregion
|
|
343
|
-
//#region src/components/icons/grip-vertical-icon.tsx
|
|
344
|
-
function GripVerticalIcon() {
|
|
345
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
346
|
-
viewBox: "0 0 24 24",
|
|
347
|
-
fill: "none",
|
|
348
|
-
stroke: "currentColor",
|
|
349
|
-
strokeWidth: 2,
|
|
350
|
-
strokeLinecap: "round",
|
|
351
|
-
strokeLinejoin: "round",
|
|
352
|
-
"aria-hidden": "true",
|
|
353
|
-
children: [
|
|
354
|
-
/* @__PURE__ */ jsx("circle", {
|
|
355
|
-
cx: "9",
|
|
356
|
-
cy: "5",
|
|
357
|
-
r: "1"
|
|
358
|
-
}),
|
|
359
|
-
/* @__PURE__ */ jsx("circle", {
|
|
360
|
-
cx: "9",
|
|
361
|
-
cy: "12",
|
|
362
|
-
r: "1"
|
|
363
|
-
}),
|
|
364
|
-
/* @__PURE__ */ jsx("circle", {
|
|
365
|
-
cx: "9",
|
|
366
|
-
cy: "19",
|
|
367
|
-
r: "1"
|
|
368
|
-
}),
|
|
369
|
-
/* @__PURE__ */ jsx("circle", {
|
|
370
|
-
cx: "15",
|
|
371
|
-
cy: "5",
|
|
372
|
-
r: "1"
|
|
373
|
-
}),
|
|
374
|
-
/* @__PURE__ */ jsx("circle", {
|
|
375
|
-
cx: "15",
|
|
376
|
-
cy: "12",
|
|
377
|
-
r: "1"
|
|
378
|
-
}),
|
|
379
|
-
/* @__PURE__ */ jsx("circle", {
|
|
380
|
-
cx: "15",
|
|
381
|
-
cy: "19",
|
|
382
|
-
r: "1"
|
|
383
|
-
})
|
|
384
|
-
]
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
//#endregion
|
|
389
|
-
//#region src/components/icons/plus-icon.tsx
|
|
390
|
-
function PlusIcon() {
|
|
391
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
392
|
-
viewBox: "0 0 24 24",
|
|
393
|
-
fill: "none",
|
|
394
|
-
stroke: "currentColor",
|
|
395
|
-
strokeWidth: 2,
|
|
396
|
-
strokeLinecap: "round",
|
|
397
|
-
strokeLinejoin: "round",
|
|
398
|
-
"aria-hidden": "true",
|
|
399
|
-
children: [/* @__PURE__ */ jsx("path", { d: "M5 12h14" }), /* @__PURE__ */ jsx("path", { d: "M12 5v14" })]
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
|
|
403
290
|
//#endregion
|
|
404
291
|
//#region src/components/block-handle.tsx
|
|
405
292
|
function BlockHandle() {
|
|
406
293
|
return /* @__PURE__ */ jsx(BlockHandleRoot, { children: /* @__PURE__ */ jsx(BlockHandlePositioner, {
|
|
407
294
|
className: block_handle_module_default.Positioner,
|
|
408
|
-
children: /* @__PURE__ */
|
|
295
|
+
children: /* @__PURE__ */ jsx(BlockHandlePopup, {
|
|
409
296
|
className: block_handle_module_default.Popup,
|
|
410
297
|
"data-testid": "block-handle",
|
|
411
|
-
children:
|
|
412
|
-
className: block_handle_module_default.Add,
|
|
413
|
-
"data-testid": "block-handle-add",
|
|
414
|
-
children: /* @__PURE__ */ jsx(PlusIcon, {})
|
|
415
|
-
}), /* @__PURE__ */ jsx(BlockHandleDraggable, {
|
|
298
|
+
children: /* @__PURE__ */ jsx(BlockHandleDraggable, {
|
|
416
299
|
className: block_handle_module_default.Draggable,
|
|
417
300
|
"data-testid": "block-handle-drag",
|
|
418
301
|
children: /* @__PURE__ */ jsx(GripVerticalIcon, {})
|
|
419
|
-
})
|
|
302
|
+
})
|
|
420
303
|
})
|
|
421
304
|
}) });
|
|
422
305
|
}
|
|
@@ -574,52 +457,6 @@ function SlashMenu() {
|
|
|
574
457
|
});
|
|
575
458
|
}
|
|
576
459
|
|
|
577
|
-
//#endregion
|
|
578
|
-
//#region src/components/icons/grip-horizontal-icon.tsx
|
|
579
|
-
function GripHorizontalIcon() {
|
|
580
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
581
|
-
viewBox: "0 0 24 24",
|
|
582
|
-
fill: "none",
|
|
583
|
-
stroke: "currentColor",
|
|
584
|
-
strokeWidth: 2,
|
|
585
|
-
strokeLinecap: "round",
|
|
586
|
-
strokeLinejoin: "round",
|
|
587
|
-
"aria-hidden": "true",
|
|
588
|
-
children: [
|
|
589
|
-
/* @__PURE__ */ jsx("circle", {
|
|
590
|
-
cx: "12",
|
|
591
|
-
cy: "9",
|
|
592
|
-
r: "1"
|
|
593
|
-
}),
|
|
594
|
-
/* @__PURE__ */ jsx("circle", {
|
|
595
|
-
cx: "19",
|
|
596
|
-
cy: "9",
|
|
597
|
-
r: "1"
|
|
598
|
-
}),
|
|
599
|
-
/* @__PURE__ */ jsx("circle", {
|
|
600
|
-
cx: "5",
|
|
601
|
-
cy: "9",
|
|
602
|
-
r: "1"
|
|
603
|
-
}),
|
|
604
|
-
/* @__PURE__ */ jsx("circle", {
|
|
605
|
-
cx: "12",
|
|
606
|
-
cy: "15",
|
|
607
|
-
r: "1"
|
|
608
|
-
}),
|
|
609
|
-
/* @__PURE__ */ jsx("circle", {
|
|
610
|
-
cx: "19",
|
|
611
|
-
cy: "15",
|
|
612
|
-
r: "1"
|
|
613
|
-
}),
|
|
614
|
-
/* @__PURE__ */ jsx("circle", {
|
|
615
|
-
cx: "5",
|
|
616
|
-
cy: "15",
|
|
617
|
-
r: "1"
|
|
618
|
-
})
|
|
619
|
-
]
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
|
-
|
|
623
460
|
//#endregion
|
|
624
461
|
//#region src/components/table-handle.module.css
|
|
625
462
|
var table_handle_module_default = {
|
|
@@ -926,16 +763,19 @@ function resolveSelection(doc, selection) {
|
|
|
926
763
|
return TextSelection.between(doc.resolve(anchor), doc.resolve(head));
|
|
927
764
|
}
|
|
928
765
|
}
|
|
929
|
-
function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTagSearch, onWikilinkSearch, onWikilinkClick, onLinkClick, resolveImageUrl, onImagePaste, onImageSaveError, onImageClick, embedPaste, bulletAfterHeading, blockHandle = true, placeholder, readOnly, spellCheck, editorClassName, ref, children }) {
|
|
766
|
+
function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTagSearch, onWikilinkSearch, onWikilinkClick, onLinkClick, resolveImageUrl, onImagePaste, onImageSaveError, onImageClick, embedPaste, bulletAfterHeading, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, editorClassName, ref, children }) {
|
|
930
767
|
const [editor] = useState(() => {
|
|
931
768
|
const editor = createEditor({ extension: union(defineEditorExtension(), defineCodeBlockView()) });
|
|
932
|
-
if (initialMarkdown) editor.setContent(markdownToDoc(initialMarkdown,
|
|
769
|
+
if (initialMarkdown) editor.setContent(markdownToDoc(initialMarkdown, {
|
|
770
|
+
nodes: editor.nodes,
|
|
771
|
+
frontmatter
|
|
772
|
+
}));
|
|
933
773
|
return editor;
|
|
934
774
|
});
|
|
935
775
|
const suppressDocChangeRef = useRef(false);
|
|
936
776
|
useImperativeHandle(ref, () => {
|
|
937
777
|
function getMarkdown() {
|
|
938
|
-
return docToMarkdown(editor.state.doc);
|
|
778
|
+
return docToMarkdown(editor.state.doc, { frontmatter });
|
|
939
779
|
}
|
|
940
780
|
function getSelection() {
|
|
941
781
|
return editor.state.selection.toJSON();
|
|
@@ -947,7 +787,10 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTa
|
|
|
947
787
|
if (markdown == null && !selection) return;
|
|
948
788
|
const transaction = editor.state.tr;
|
|
949
789
|
if (markdown != null) {
|
|
950
|
-
const doc = markdownToDoc(markdown,
|
|
790
|
+
const doc = markdownToDoc(markdown, {
|
|
791
|
+
nodes: editor.nodes,
|
|
792
|
+
frontmatter
|
|
793
|
+
});
|
|
951
794
|
transaction.replaceWith(0, transaction.doc.content.size, doc.content);
|
|
952
795
|
}
|
|
953
796
|
if (selection) transaction.setSelection(resolveSelection(transaction.doc, selection)).scrollIntoView();
|
|
@@ -981,7 +824,7 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTa
|
|
|
981
824
|
scrollIntoView,
|
|
982
825
|
editor
|
|
983
826
|
};
|
|
984
|
-
}, [editor]);
|
|
827
|
+
}, [editor, frontmatter]);
|
|
985
828
|
const handleDocChange = useMemo(() => {
|
|
986
829
|
if (!onDocChange) return;
|
|
987
830
|
return () => {
|
|
@@ -995,7 +838,7 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTa
|
|
|
995
838
|
/* @__PURE__ */ jsx("div", {
|
|
996
839
|
ref: editor.mount,
|
|
997
840
|
spellCheck,
|
|
998
|
-
className: editorClassName
|
|
841
|
+
className: clsx("meowdown-content", editorClassName)
|
|
999
842
|
}),
|
|
1000
843
|
/* @__PURE__ */ jsx(EditorExtensions, {
|
|
1001
844
|
markMode,
|
|
@@ -1024,7 +867,7 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTa
|
|
|
1024
867
|
|
|
1025
868
|
//#endregion
|
|
1026
869
|
//#region src/components/editor.tsx
|
|
1027
|
-
function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onTagSearch, onWikilinkSearch, onWikilinkClick, onLinkClick, resolveImageUrl, onImagePaste, onImageSaveError, onImageClick, embedPaste = true, bulletAfterHeading = false, blockHandle = true, placeholder, readOnly, spellCheck, editorClassName, wrapperClassName, handleRef, children }) {
|
|
870
|
+
function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onTagSearch, onWikilinkSearch, onWikilinkClick, onLinkClick, resolveImageUrl, onImagePaste, onImageSaveError, onImageClick, embedPaste = true, bulletAfterHeading = false, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, editorClassName, wrapperClassName, handleRef, children }) {
|
|
1028
871
|
const childRef = useRef(null);
|
|
1029
872
|
useImperativeHandle(handleRef, () => {
|
|
1030
873
|
function getMarkdown() {
|
|
@@ -1096,6 +939,7 @@ function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onTagSea
|
|
|
1096
939
|
onImageClick,
|
|
1097
940
|
embedPaste,
|
|
1098
941
|
bulletAfterHeading,
|
|
942
|
+
frontmatter,
|
|
1099
943
|
blockHandle,
|
|
1100
944
|
placeholder,
|
|
1101
945
|
readOnly,
|
package/dist/style.css
CHANGED
|
@@ -228,10 +228,12 @@
|
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
.
|
|
231
|
+
.meow_Draggable_EvUpOG {
|
|
232
232
|
box-sizing: border-box;
|
|
233
|
+
width: 1.25rem;
|
|
233
234
|
height: 1.5rem;
|
|
234
235
|
color: color-mix(in oklab, var(--meowdown-muted) 50%, transparent);
|
|
236
|
+
cursor: grab;
|
|
235
237
|
border-radius: .25rem;
|
|
236
238
|
justify-content: center;
|
|
237
239
|
align-items: center;
|
|
@@ -247,16 +249,6 @@
|
|
|
247
249
|
display: block;
|
|
248
250
|
}
|
|
249
251
|
}
|
|
250
|
-
|
|
251
|
-
.meow_Add_EvUpOG {
|
|
252
|
-
cursor: pointer;
|
|
253
|
-
width: 1.5rem;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
.meow_Draggable_EvUpOG {
|
|
257
|
-
cursor: grab;
|
|
258
|
-
width: 1.25rem;
|
|
259
|
-
}
|
|
260
252
|
.meow_DropIndicator_urNIwW {
|
|
261
253
|
z-index: 50;
|
|
262
254
|
background: var(--meowdown-accent);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meowdown/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.17.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -26,9 +26,10 @@
|
|
|
26
26
|
"@ocavue/utils": "^1.7.0",
|
|
27
27
|
"@prosekit/core": "^0.13.0-beta.3",
|
|
28
28
|
"@prosekit/pm": "^0.1.19-beta.0",
|
|
29
|
-
"@prosekit/react": "^0.8.0-beta.
|
|
29
|
+
"@prosekit/react": "^0.8.0-beta.7",
|
|
30
30
|
"clsx": "^2.1.1",
|
|
31
|
-
"
|
|
31
|
+
"lucide-react": "^1.21.0",
|
|
32
|
+
"@meowdown/core": "0.17.1"
|
|
32
33
|
},
|
|
33
34
|
"peerDependencies": {
|
|
34
35
|
"react": "^19.0.0",
|