@meowdown/react 0.3.0 → 0.4.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.
package/README.md CHANGED
@@ -41,6 +41,15 @@ The Markdown editor component. Renders inside a `div.meowdown` wrapper that fill
41
41
  Imperative handle for the editor, attached via `ref`.
42
42
 
43
43
  - `getMarkdown(): string`: serializes the current document to Markdown. Can be expensive on large documents; call it on demand (e.g. throttled) instead of on every change.
44
+ - `setMarkdown(markdown: string): void`: replaces the whole document as a single undoable edit.
45
+ - `getState(): EditorStateSnapshot`: returns `[markdown, selection]`, where `selection` is a `SelectionJSON` (`{ anchor: number, head: number, type: string }`).
46
+ - `setState(markdown?: string, selection?: SelectionJSON | 'start' | 'end'): void`: replaces the document (if `markdown` is given) and restores `selection`: exactly when valid, otherwise clamped to the nearest text selection; out-of-range positions never throw. `'start'` and `'end'` jump to the document edges. Without a selection, the current one is mapped through the change. Restore a snapshot with `handle.setState(...handle.getState())`.
47
+ - `getSelection(): SelectionJSON`: returns the current selection.
48
+ - `setSelection(selection: SelectionJSON | 'start' | 'end'): void`: restores a selection with the same hint semantics as `setState`.
49
+ - `focus(): void`: focuses the editor.
50
+ - `scrollIntoView(): void`: scrolls the selection into view.
51
+
52
+ Selection positions are in the mounted editor's coordinate space: ProseMirror document positions in the rich modes, character offsets in source mode. They round-trip within one mode but are not portable across a mode switch.
44
53
 
45
54
  ## Keyboard shortcuts
46
55
 
@@ -55,13 +64,7 @@ In the rich modes (`focus` / `show` / `hide`), these toggle inline formatting on
55
64
 
56
65
  ## Styling
57
66
 
58
- `@meowdown/react/style.css` includes the default theme from [`@meowdown/core`](https://www.npmjs.com/package/@meowdown/core). Colors follow the page's `color-scheme`; customize via the `--meowdown-*` CSS variables documented there. The editor reserves a horizontal gutter (`--meowdown-gutter`) so the block handle has room to the left of the hovered block.
59
-
60
- Selection colors are standalone variables (independent from `--meowdown-accent`):
61
-
62
- - `--meowdown-node-outline`: outline of a selected node (e.g. a block grabbed by its handle).
63
- - `--meowdown-node-selection`: background wash of a selected node.
64
- - `--meowdown-selection`: text `::selection` background.
67
+ `@meowdown/react/style.css` includes the default theme from [`@meowdown/core`](https://www.npmjs.com/package/@meowdown/core).
65
68
 
66
69
  ## License
67
70
 
package/dist/index.d.ts CHANGED
@@ -1,13 +1,41 @@
1
1
  import { Ref } from "react";
2
2
  import { MarkMode, MarkMode as MarkMode$1, TypedEditor } from "@meowdown/core";
3
+ import { SelectionJSON, SelectionJSON as SelectionJSON$1 } from "@prosekit/core";
3
4
 
4
5
  //#region src/components/types.d.ts
6
+ /** A selection to restore: an exact JSON selection, or a document edge. */
7
+ type SelectionHint = SelectionJSON$1 | 'start' | 'end';
8
+ /**
9
+ * The current Markdown and selection. Selection positions are in the mounted
10
+ * editor's coordinate space: ProseMirror positions in the rich modes,
11
+ * character offsets in source mode. Not portable across a mode switch.
12
+ */
13
+ type EditorStateSnapshot = [markdown: string, selection: SelectionJSON$1];
5
14
  interface EditorHandle {
6
15
  /**
7
16
  * Serializes the current document to Markdown. Can be expensive on large
8
17
  * documents; call it on demand (e.g. throttled) instead of on every change.
9
18
  */
10
19
  getMarkdown: () => string;
20
+ /** Replaces the whole document as a single undoable edit. */
21
+ setMarkdown: (markdown: string) => void;
22
+ /** Returns the current Markdown and selection. */
23
+ getState: () => EditorStateSnapshot;
24
+ /**
25
+ * Replaces the document (if `markdown` is given) and restores `selection`:
26
+ * exactly when valid, otherwise clamped to the nearest text selection;
27
+ * out-of-range positions never throw. Without a selection, the current one
28
+ * is mapped through the change.
29
+ */
30
+ setState: (markdown?: string, selection?: SelectionHint) => void;
31
+ /** Returns the current selection. */
32
+ getSelection: () => SelectionJSON$1;
33
+ /** Restores a selection with the same hint semantics as `setState`. */
34
+ setSelection: (selection: SelectionHint) => void;
35
+ /** Focuses the editor. */
36
+ focus: () => void;
37
+ /** Scrolls the selection into view. */
38
+ scrollIntoView: () => void;
11
39
  }
12
40
  /**
13
41
  * Searches tags for the tag menu. Receives the query typed after `#`
@@ -68,4 +96,4 @@ declare function Editor({
68
96
  ref
69
97
  }: EditorProps): import("react").JSX.Element;
70
98
  //#endregion
71
- export { Editor, type EditorHandle, type EditorMode, type EditorProps, type MarkMode, type TagSearchHandler, type TypedEditor, type WikilinkSearchHandler };
99
+ export { Editor, type EditorHandle, type EditorMode, type EditorProps, type EditorStateSnapshot, type MarkMode, type SelectionHint, type SelectionJSON, type TagSearchHandler, type TypedEditor, type WikilinkSearchHandler };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{useCallback as e,useEffect as t,useImperativeHandle as n,useLayoutEffect as r,useMemo as i,useRef as a,useState as o}from"react";import{defaultKeymap as s,history as c,historyKeymap as l}from"@codemirror/commands";import{markdown as u,markdownLanguage as d}from"@codemirror/lang-markdown";import{defaultHighlightStyle as f,syntaxHighlighting as p}from"@codemirror/language";import{EditorState as m}from"@codemirror/state";import{EditorView as h,keymap as g}from"@codemirror/view";import{jsx as _,jsxs as v}from"react/jsx-runtime";import{defineEditorExtension as y,defineMarkMode as b,docToMarkdown as x,markdownToDoc as S}from"@meowdown/core";import{canUseRegexLookbehind as C,createEditor as w,defineDocChangeHandler as T}from"@prosekit/core";import{ProseKit as E,useEditor as D,useExtension as O}from"@prosekit/react";import{BlockHandleAdd as k,BlockHandleDraggable as A,BlockHandlePopup as j,BlockHandlePositioner as M,BlockHandleRoot as N}from"@prosekit/react/block-handle";import{DropIndicator as P}from"@prosekit/react/drop-indicator";import{AutocompleteEmpty as F,AutocompleteItem as I,AutocompletePopup as L,AutocompletePositioner as R,AutocompleteRoot as z}from"@prosekit/react/autocomplete";function B({initialMarkdown:e,onDocChange:t,ref:i}){let o=a(null),v=a(null),y=a(t);r(()=>{y.current=t},[t]);let b=a(e??``);return n(i,()=>({getMarkdown:()=>v.current?.state.doc.toString()??b.current}),[]),r(()=>{let e=o.current;if(!e)return;let t=new h({parent:e,state:m.create({doc:b.current,extensions:[c(),g.of([...s,...l]),u({base:d}),p(f,{fallback:!0}),h.lineWrapping,h.updateListener.of(e=>{e.docChanged&&y.current?.()})]})});return v.current=t,()=>{t.destroy(),v.current=null}},[]),_(`div`,{ref:o,"data-editor":`codemirror`})}function V(){return v(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[_(`circle`,{cx:`9`,cy:`5`,r:`1`}),_(`circle`,{cx:`9`,cy:`12`,r:`1`}),_(`circle`,{cx:`9`,cy:`19`,r:`1`}),_(`circle`,{cx:`15`,cy:`5`,r:`1`}),_(`circle`,{cx:`15`,cy:`12`,r:`1`}),_(`circle`,{cx:`15`,cy:`19`,r:`1`})]})}function H(){return v(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[_(`path`,{d:`M5 12h14`}),_(`path`,{d:`M12 5v14`})]})}function U(){return _(N,{children:_(M,{className:`meowdown-block-handle-positioner`,children:v(j,{className:`meowdown-block-handle`,"data-testid":`block-handle`,children:[_(k,{className:`meowdown-block-handle-add`,"data-testid":`block-handle-add`,children:_(H,{})}),_(A,{className:`meowdown-block-handle-drag`,"data-testid":`block-handle-drag`,children:_(V,{})})]})})})}function W(){return _(P,{className:`meowdown-drop-indicator`,"data-testid":`drop-indicator`})}const G=C()?/(?<!\S)\/(\S.*)?$/u:/\/(\S.*)?$/u;function K({label:e,kbd:t,onSelect:n}){return v(I,{className:`meowdown-autocomplete-menu-item`,onSelect:n,children:[_(`span`,{children:e}),t&&_(`kbd`,{children:t})]})}function q(){let e=D();return _(z,{regex:G,children:_(R,{className:`meowdown-autocomplete-menu-positioner`,children:v(L,{className:`meowdown-autocomplete-menu`,"data-testid":`slash-menu`,children:[_(K,{label:`Heading 1`,kbd:`#`,onSelect:()=>e.commands.setHeading({level:1})}),_(K,{label:`Heading 2`,kbd:`##`,onSelect:()=>e.commands.setHeading({level:2})}),_(K,{label:`Heading 3`,kbd:`###`,onSelect:()=>e.commands.setHeading({level:3})}),_(K,{label:`Heading 4`,kbd:`####`,onSelect:()=>e.commands.setHeading({level:4})}),_(K,{label:`Blockquote`,kbd:`>`,onSelect:()=>e.commands.setBlockquote()}),_(K,{label:`Bullet list`,kbd:`-`,onSelect:()=>e.commands.wrapInList({kind:`bullet`})}),_(K,{label:`Ordered list`,kbd:`1.`,onSelect:()=>e.commands.wrapInList({kind:`ordered`})}),_(K,{label:`Task list`,kbd:`[]`,onSelect:()=>e.commands.wrapInList({kind:`task`})}),_(K,{label:`Code block`,kbd:"```",onSelect:()=>e.commands.setCodeBlock()}),_(K,{label:`Table`,onSelect:()=>e.commands.insertTable({row:3,col:3})}),_(F,{className:`meowdown-autocomplete-menu-item`,children:`No results`})]})})})}function J(){return!0}const Y=C()?/(?<!\S)#[\da-z]+$/iu:/#[\da-z]+$/iu;function X({onTagSearch:n}){let r=D(),[i,a]=o(!1),[s,c]=o(``),[l,u]=o([]),[d,f]=o(!1),p=e(async(e,t)=>{if(t.aborted)return;f(!0);let r=await n(e);t.aborted||(u(r),f(!1))},[n]);return t(()=>{if(!i)return;let e=new AbortController;return queueMicrotask(()=>{p(s,e.signal)}),()=>{e.abort()}},[i,s,p]),_(z,{regex:Y,filter:J,onOpenChange:e=>a(e.detail),onQueryChange:e=>c(e.detail),children:_(R,{className:`meowdown-autocomplete-menu-positioner`,children:v(L,{className:`meowdown-autocomplete-menu`,"data-testid":`tag-menu`,children:[l.map(e=>v(I,{className:`meowdown-autocomplete-menu-item`,onSelect:()=>r.commands.insertText({text:`#${e} `}),children:[`#`,e]},e)),_(F,{className:`meowdown-autocomplete-menu-item`,children:d?`Loading...`:`No tags found`})]})})})}const Z=/\[\[[^[\]]*$/u;function Q({onWikilinkSearch:n}){let r=D(),[i,a]=o(!1),[s,c]=o(``),[l,u]=o([]),[d,f]=o(!1),p=e(async(e,t)=>{if(t.aborted)return;f(!0);let r=await n(e);t.aborted||(u(r),f(!1))},[n]);return t(()=>{if(!i)return;let e=new AbortController;return queueMicrotask(()=>{p(s,e.signal)}),()=>{e.abort()}},[i,s,p]),_(z,{regex:Z,filter:J,onOpenChange:e=>a(e.detail),onQueryChange:e=>c(e.detail),children:_(R,{className:`meowdown-autocomplete-menu-positioner`,children:v(L,{className:`meowdown-autocomplete-menu`,"data-testid":`wikilink-menu`,children:[l.map(e=>_(I,{className:`meowdown-autocomplete-menu-item`,onSelect:()=>r.commands.insertText({text:`[[${e}]]`}),children:e},e)),_(F,{className:`meowdown-autocomplete-menu-item`,children:d?`Loading...`:`No notes found`})]})})})}function $({markMode:e=`focus`,initialMarkdown:t,onDocChange:r,onTagSearch:a,onWikilinkSearch:s,ref:c}){let[l]=o(()=>{let e=w({extension:y()});return t&&e.setContent(S(e,t)),e});return n(c,()=>({getMarkdown:()=>x(l.state.doc)}),[l]),O(i(()=>b(e),[e]),{editor:l}),O(i(()=>r?T(()=>{r()}):null,[r]),{editor:l}),v(E,{editor:l,children:[_(`div`,{ref:l.mount}),_(U,{}),_(W,{}),_(q,{}),a&&_(X,{onTagSearch:a}),s&&_(Q,{onWikilinkSearch:s})]})}function ee({mode:e=`focus`,initialMarkdown:t,onDocChange:r,onTagSearch:i,onWikilinkSearch:o,ref:s}){let c=a(null);n(s,()=>({getMarkdown:()=>c.current?.getMarkdown()??``}),[]);let l=c.current?.getMarkdown()??t??``;return _(`div`,{className:`meowdown`,children:e===`source`?_(B,{ref:c,initialMarkdown:l,onDocChange:r}):_($,{ref:c,markMode:e,initialMarkdown:l,onDocChange:r,onTagSearch:i,onWikilinkSearch:o})})}export{ee as Editor};
1
+ import{useCallback as e,useEffect as t,useImperativeHandle as n,useLayoutEffect as r,useMemo as i,useRef as a,useState as o}from"react";import{defaultKeymap as s,history as c,historyKeymap as l}from"@codemirror/commands";import{markdown as u,markdownLanguage as d}from"@codemirror/lang-markdown";import{defaultHighlightStyle as f,syntaxHighlighting as p}from"@codemirror/language";import{EditorSelection as m,EditorState as h}from"@codemirror/state";import{EditorView as g,keymap as _}from"@codemirror/view";import{clamp as v}from"@ocavue/utils";import{jsx as y,jsxs as b}from"react/jsx-runtime";import{defineEditorExtension as x,defineMarkMode as S,docToMarkdown as C,markdownToDoc as w}from"@meowdown/core";import{canUseRegexLookbehind as T,createEditor as E,defineDocChangeHandler as D}from"@prosekit/core";import{Selection as O,TextSelection as k}from"@prosekit/pm/state";import{ProseKit as A,useEditor as j,useExtension as M}from"@prosekit/react";import{BlockHandleAdd as N,BlockHandleDraggable as P,BlockHandlePopup as F,BlockHandlePositioner as I,BlockHandleRoot as L}from"@prosekit/react/block-handle";import{DropIndicator as R}from"@prosekit/react/drop-indicator";import{AutocompleteEmpty as z,AutocompleteItem as B,AutocompletePopup as V,AutocompletePositioner as H,AutocompleteRoot as U}from"@prosekit/react/autocomplete";function W(e,t){return e===`start`?m.single(0):e===`end`?m.single(t):m.single(v(e.anchor,0,t),v(e.head,0,t))}function G({initialMarkdown:e,onDocChange:t,ref:i}){let o=a(null),m=a(null),v=a(t);r(()=>{v.current=t},[t]);let b=a(e??``);return n(i,()=>{function e(){return m.current?.state.doc.toString()??b.current}function t(){let e=m.current?.state.selection.main;return{type:`text`,anchor:e?.anchor??0,head:e?.head??0}}function n(){return[e(),t()]}function r(e,t){let n=m.current;if(!n){e!=null&&(b.current=e);return}if(e==null&&!t)return;let r=e==null?n.state.doc.length:e.length;n.dispatch({changes:e==null?void 0:{from:0,to:n.state.doc.length,insert:e},selection:t?W(t,r):void 0,scrollIntoView:!0})}function i(e){r(e)}function a(e){r(void 0,e)}function o(){m.current?.focus()}function s(){m.current?.dispatch({scrollIntoView:!0})}return{getMarkdown:e,setMarkdown:i,getState:n,setState:r,getSelection:t,setSelection:a,focus:o,scrollIntoView:s}},[]),r(()=>{let e=o.current;if(!e)return;let t=new g({parent:e,state:h.create({doc:b.current,extensions:[c(),_.of([...s,...l]),u({base:d}),p(f,{fallback:!0}),g.lineWrapping,g.updateListener.of(e=>{e.docChanged&&v.current?.()})]})});return m.current=t,()=>{t.destroy(),m.current=null}},[]),y(`div`,{ref:o,"data-editor":`codemirror`})}function K(){return b(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[y(`circle`,{cx:`9`,cy:`5`,r:`1`}),y(`circle`,{cx:`9`,cy:`12`,r:`1`}),y(`circle`,{cx:`9`,cy:`19`,r:`1`}),y(`circle`,{cx:`15`,cy:`5`,r:`1`}),y(`circle`,{cx:`15`,cy:`12`,r:`1`}),y(`circle`,{cx:`15`,cy:`19`,r:`1`})]})}function q(){return b(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[y(`path`,{d:`M5 12h14`}),y(`path`,{d:`M12 5v14`})]})}function J(){return y(L,{children:y(I,{className:`meowdown-block-handle-positioner`,children:b(F,{className:`meowdown-block-handle`,"data-testid":`block-handle`,children:[y(N,{className:`meowdown-block-handle-add`,"data-testid":`block-handle-add`,children:y(q,{})}),y(P,{className:`meowdown-block-handle-drag`,"data-testid":`block-handle-drag`,children:y(K,{})})]})})})}function Y(){return y(R,{className:`meowdown-drop-indicator`,"data-testid":`drop-indicator`})}const X=T()?/(?<!\S)\/(\S.*)?$/u:/\/(\S.*)?$/u;function Z({label:e,kbd:t,onSelect:n}){return b(B,{className:`meowdown-autocomplete-menu-item`,onSelect:n,children:[y(`span`,{children:e}),t&&y(`kbd`,{children:t})]})}function Q(){let e=j();return y(U,{regex:X,children:y(H,{className:`meowdown-autocomplete-menu-positioner`,children:b(V,{className:`meowdown-autocomplete-menu`,"data-testid":`slash-menu`,children:[y(Z,{label:`Heading 1`,kbd:`#`,onSelect:()=>e.commands.setHeading({level:1})}),y(Z,{label:`Heading 2`,kbd:`##`,onSelect:()=>e.commands.setHeading({level:2})}),y(Z,{label:`Heading 3`,kbd:`###`,onSelect:()=>e.commands.setHeading({level:3})}),y(Z,{label:`Heading 4`,kbd:`####`,onSelect:()=>e.commands.setHeading({level:4})}),y(Z,{label:`Blockquote`,kbd:`>`,onSelect:()=>e.commands.setBlockquote()}),y(Z,{label:`Bullet list`,kbd:`-`,onSelect:()=>e.commands.wrapInList({kind:`bullet`})}),y(Z,{label:`Ordered list`,kbd:`1.`,onSelect:()=>e.commands.wrapInList({kind:`ordered`})}),y(Z,{label:`Task list`,kbd:`[]`,onSelect:()=>e.commands.wrapInList({kind:`task`})}),y(Z,{label:`Code block`,kbd:"```",onSelect:()=>e.commands.setCodeBlock()}),y(Z,{label:`Table`,onSelect:()=>e.commands.insertTable({row:3,col:3})}),y(z,{className:`meowdown-autocomplete-menu-item`,children:`No results`})]})})})}function $(){return!0}const ee=T()?/(?<!\S)#[\da-z]+$/iu:/#[\da-z]+$/iu;function te({onTagSearch:n}){let r=j(),[i,a]=o(!1),[s,c]=o(``),[l,u]=o([]),[d,f]=o(!1),p=e(async(e,t)=>{if(t.aborted)return;f(!0);let r=await n(e);t.aborted||(u(r),f(!1))},[n]);return t(()=>{if(!i)return;let e=new AbortController;return queueMicrotask(()=>{p(s,e.signal)}),()=>{e.abort()}},[i,s,p]),y(U,{regex:ee,filter:$,onOpenChange:e=>a(e.detail),onQueryChange:e=>c(e.detail),children:y(H,{className:`meowdown-autocomplete-menu-positioner`,children:b(V,{className:`meowdown-autocomplete-menu`,"data-testid":`tag-menu`,children:[l.map(e=>b(B,{className:`meowdown-autocomplete-menu-item`,onSelect:()=>r.commands.insertText({text:`#${e} `}),children:[`#`,e]},e)),y(z,{className:`meowdown-autocomplete-menu-item`,children:d?`Loading...`:`No tags found`})]})})})}const ne=/\[\[[^[\]]*$/u;function re({onWikilinkSearch:n}){let r=j(),[i,a]=o(!1),[s,c]=o(``),[l,u]=o([]),[d,f]=o(!1),p=e(async(e,t)=>{if(t.aborted)return;f(!0);let r=await n(e);t.aborted||(u(r),f(!1))},[n]);return t(()=>{if(!i)return;let e=new AbortController;return queueMicrotask(()=>{p(s,e.signal)}),()=>{e.abort()}},[i,s,p]),y(U,{regex:ne,filter:$,onOpenChange:e=>a(e.detail),onQueryChange:e=>c(e.detail),children:y(H,{className:`meowdown-autocomplete-menu-positioner`,children:b(V,{className:`meowdown-autocomplete-menu`,"data-testid":`wikilink-menu`,children:[l.map(e=>y(B,{className:`meowdown-autocomplete-menu-item`,onSelect:()=>r.commands.insertText({text:`[[${e}]]`}),children:e},e)),y(z,{className:`meowdown-autocomplete-menu-item`,children:d?`Loading...`:`No notes found`})]})})})}function ie(e,t){if(t===`start`)return O.atStart(e);if(t===`end`)return O.atEnd(e);try{return O.fromJSON(e,t)}catch{let n=e.content.size,r=v(t.anchor??0,0,n),i=v(t.head??r,0,n);return k.between(e.resolve(r),e.resolve(i))}}function ae({markMode:e=`focus`,initialMarkdown:t,onDocChange:r,onTagSearch:a,onWikilinkSearch:s,ref:c}){let[l]=o(()=>{let e=E({extension:x()});return t&&e.setContent(w(e,t)),e});return n(c,()=>{function e(){return C(l.state.doc)}function t(){return l.state.selection.toJSON()}function n(){return[e(),t()]}function r(e,t){if(e==null&&!t)return;let n=l.state.tr;if(e!=null){let t=w(l,e);n.replaceWith(0,n.doc.content.size,t.content)}t&&n.setSelection(ie(n.doc,t)).scrollIntoView(),l.view.dispatch(n)}function i(e){r(e)}function a(e){r(void 0,e)}function o(){l.focus()}function s(){l.view.dispatch(l.state.tr.scrollIntoView())}return{getMarkdown:e,setMarkdown:i,getState:n,setState:r,getSelection:t,setSelection:a,focus:o,scrollIntoView:s}},[l]),M(i(()=>S(e),[e]),{editor:l}),M(i(()=>r?D(()=>{r()}):null,[r]),{editor:l}),b(A,{editor:l,children:[y(`div`,{ref:l.mount}),y(J,{}),y(Y,{}),y(Q,{}),a&&y(te,{onTagSearch:a}),s&&y(re,{onWikilinkSearch:s})]})}function oe({mode:e=`focus`,initialMarkdown:t,onDocChange:r,onTagSearch:i,onWikilinkSearch:o,ref:s}){let c=a(null);n(s,()=>{function e(){return c.current?.getMarkdown()??``}function t(e){c.current?.setMarkdown(e)}function n(){return c.current?.getState()??[``,{type:`text`,anchor:0,head:0}]}function r(e,t){c.current?.setState(e,t)}function i(){return c.current?.getSelection()??{type:`text`,anchor:0,head:0}}function a(e){c.current?.setSelection(e)}function o(){c.current?.focus()}function s(){c.current?.scrollIntoView()}return{getMarkdown:e,setMarkdown:t,getState:n,setState:r,getSelection:i,setSelection:a,focus:o,scrollIntoView:s}},[]);let l=c.current?.getMarkdown()??t??``;return y(`div`,{className:`meowdown`,children:e===`source`?y(G,{ref:c,initialMarkdown:l,onDocChange:r}):y(ae,{ref:c,markMode:e,initialMarkdown:l,onDocChange:r,onTagSearch:i,onWikilinkSearch:o})})}export{oe as Editor};
package/dist/style.css CHANGED
@@ -147,52 +147,6 @@ img.ProseMirror-separator {
147
147
  display: none;
148
148
  }
149
149
 
150
- .ProseMirror .tableWrapper {
151
- overflow-x: auto;
152
- }
153
-
154
- .ProseMirror table {
155
- border-collapse: collapse;
156
- table-layout: fixed;
157
- width: 100%;
158
- overflow: hidden;
159
- }
160
-
161
- .ProseMirror td, .ProseMirror th {
162
- box-sizing: border-box;
163
- vertical-align: top;
164
- border-width: 1px;
165
- padding-left: .75rem;
166
- padding-right: .75rem;
167
- position: relative;
168
- }
169
-
170
- prosekit-table-handle-drop-indicator {
171
- background-color: highlighttext;
172
- }
173
-
174
- .ProseMirror .column-resize-handle {
175
- z-index: 20;
176
- pointer-events: none;
177
- background-color: highlighttext;
178
- width: 4px;
179
- position: absolute;
180
- top: 0;
181
- bottom: 0;
182
- right: -2px;
183
- }
184
-
185
- .ProseMirror.resize-cursor {
186
- cursor: ew-resize;
187
- cursor: col-resize;
188
- }
189
-
190
- .ProseMirror .selectedCell {
191
- --color: 210, 100%, 56%;
192
- border: 1px double hsl(var(--color));
193
- background-color: hsla(var(--color), 20%);
194
- }
195
-
196
150
  :root {
197
151
  --meowdown-text: light-dark(#3f3f46, #d4d4d8);
198
152
  --meowdown-heading: light-dark(#18181b, #fafafa);
@@ -201,7 +155,11 @@ prosekit-table-handle-drop-indicator {
201
155
  --meowdown-mark: light-dark(#a78bfa, #8b5cf6);
202
156
  --meowdown-border: light-dark(#e4e4e7, #3f3f46);
203
157
  --meowdown-code-bg: light-dark(#f4f4f5, #18181b);
158
+ --meowdown-table-header-bg: light-dark(#fafafa, #27272a);
204
159
  --meowdown-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
160
+ --meowdown-node-outline: light-dark(#53f, #8870ff);
161
+ --meowdown-node-selection: light-dark(#5533ff1a, #8870ff1f);
162
+ --meowdown-selection: light-dark(#5533ff38, #8870ff4d);
205
163
  --meowdown-gutter: 3.5rem;
206
164
  }
207
165
 
@@ -312,6 +270,57 @@ prosekit-table-handle-drop-indicator {
312
270
  margin: 1.5em 0;
313
271
  }
314
272
 
273
+ .ProseMirror table {
274
+ border-collapse: collapse;
275
+ table-layout: fixed;
276
+ width: 100%;
277
+ overflow: hidden;
278
+ }
279
+
280
+ .ProseMirror td, .ProseMirror th {
281
+ box-sizing: border-box;
282
+ border: 1px solid var(--meowdown-border);
283
+ vertical-align: top;
284
+ text-align: left;
285
+ padding: .4rem .75rem;
286
+ }
287
+
288
+ .ProseMirror th {
289
+ color: var(--meowdown-heading);
290
+ background: var(--meowdown-table-header-bg);
291
+ font-weight: 600;
292
+ }
293
+
294
+ .ProseMirror table.ProseMirror-selectednode td, .ProseMirror table.ProseMirror-selectednode th {
295
+ border-color: var(--meowdown-node-outline);
296
+ }
297
+
298
+ .ProseMirror .selectedCell {
299
+ border: 1px double var(--meowdown-node-outline);
300
+ background: var(--meowdown-node-selection);
301
+ --meowdown-selection: transparent;
302
+ caret-color: #0000;
303
+ }
304
+
305
+ .ProseMirror ::selection {
306
+ background: var(--meowdown-selection);
307
+ }
308
+
309
+ .ProseMirror .ProseMirror-selectednode {
310
+ --meowdown-selection: transparent;
311
+ outline: 1px solid var(--meowdown-node-outline);
312
+ background: var(--meowdown-node-selection);
313
+ border-radius: 2px;
314
+ }
315
+
316
+ .ProseMirror pre.ProseMirror-selectednode {
317
+ border-radius: .6rem;
318
+ }
319
+
320
+ .ProseMirror.prosekit-dragging {
321
+ --meowdown-node-selection: transparent;
322
+ }
323
+
315
324
  .ProseMirror .md-tag {
316
325
  background: color-mix(in oklab, var(--meowdown-accent) 10%, transparent);
317
326
  color: color-mix(in oklab, var(--meowdown-accent) 80%, var(--meowdown-heading));
@@ -469,12 +478,6 @@ prosekit-table-handle-drop-indicator {
469
478
  }
470
479
  }
471
480
 
472
- :root {
473
- --meowdown-node-outline: light-dark(#53f, #8870ff);
474
- --meowdown-node-selection: light-dark(#5533ff1a, #8870ff1f);
475
- --meowdown-selection: light-dark(#5533ff38, #8870ff4d);
476
- }
477
-
478
481
  .meowdown {
479
482
  flex-direction: column;
480
483
  flex: 1 0 auto;
@@ -482,28 +485,6 @@ prosekit-table-handle-drop-indicator {
482
485
 
483
486
  & .ProseMirror {
484
487
  flex: 1 0 auto;
485
-
486
- & ::selection {
487
- background: var(--meowdown-selection);
488
- }
489
-
490
- & .ProseMirror-selectednode {
491
- outline: 1px solid var(--meowdown-node-outline);
492
- background: var(--meowdown-node-selection);
493
- border-radius: 2px;
494
- }
495
-
496
- & pre.ProseMirror-selectednode {
497
- border-radius: .6rem;
498
- }
499
-
500
- & .ProseMirror-selectednode {
501
- --meowdown-selection: transparent;
502
- }
503
-
504
- &.prosekit-dragging {
505
- --meowdown-node-selection: transparent;
506
- }
507
488
  }
508
489
 
509
490
  & [data-editor="codemirror"] {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/react",
3
3
  "type": "module",
4
- "version": "0.3.0",
4
+ "version": "0.4.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -22,13 +22,15 @@
22
22
  "@codemirror/language": "^6.12.3",
23
23
  "@codemirror/state": "^6.6.0",
24
24
  "@codemirror/view": "^6.43.1",
25
+ "@ocavue/utils": "^1.7.0",
25
26
  "@prosekit/core": "^0.12.3",
27
+ "@prosekit/pm": "^0.1.18",
26
28
  "@prosekit/react": "^0.7.6",
27
- "@meowdown/core": "0.3.0"
29
+ "@meowdown/core": "0.3.1"
28
30
  },
29
31
  "peerDependencies": {
30
- "react": "*",
31
- "react-dom": "*"
32
+ "react": "^19.0.0",
33
+ "react-dom": "^19.0.0"
32
34
  },
33
35
  "peerDependenciesMeta": {
34
36
  "react": {