-
-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support markdown directives and custom editors
- Loading branch information
Showing
27 changed files
with
892 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import React from 'react' | ||
import type { LexicalEditor, LexicalNode, NodeKey, SerializedLexicalNode, Spread } from 'lexical' | ||
|
||
import { DecoratorNode } from 'lexical' | ||
import { ExtendedEditorConfig } from '../types/ExtendedEditorConfig' | ||
import { LeafDirective } from 'mdast-util-directive' | ||
|
||
/** | ||
* A serialized representation of an {@link LeafDirectiveNode}. | ||
*/ | ||
export type SerializedLeafDirectiveNode = Spread< | ||
{ | ||
mdastNode: LeafDirective | ||
type: 'leafDirective' | ||
version: 1 | ||
}, | ||
SerializedLexicalNode | ||
> | ||
|
||
/** | ||
* A lexical node that represents an image. Use {@link "$createLeafDirectiveNode"} to construct one. | ||
*/ | ||
export class LeafDirectiveNode extends DecoratorNode<JSX.Element> { | ||
__mdastNode: LeafDirective | ||
|
||
static getType(): string { | ||
return 'leafDirective' | ||
} | ||
|
||
static clone(node: LeafDirectiveNode): LeafDirectiveNode { | ||
return new LeafDirectiveNode(structuredClone(node.__mdastNode)) | ||
} | ||
|
||
static importJSON(serializedNode: SerializedLeafDirectiveNode): LeafDirectiveNode { | ||
return $createLeafDirectiveNode(serializedNode.mdastNode) | ||
} | ||
|
||
constructor(mdastNode: LeafDirective, key?: NodeKey) { | ||
super(key) | ||
this.__mdastNode = mdastNode | ||
} | ||
|
||
getMdastNode(): LeafDirective { | ||
return this.__mdastNode | ||
} | ||
|
||
exportJSON(): SerializedLeafDirectiveNode { | ||
return { | ||
mdastNode: this.getMdastNode(), | ||
type: 'leafDirective', | ||
version: 1 | ||
} | ||
} | ||
|
||
createDOM(): HTMLElement { | ||
return document.createElement('div') | ||
} | ||
|
||
updateDOM(): false { | ||
return false | ||
} | ||
|
||
setMdastNode(mdastNode: LeafDirective): void { | ||
this.getWritable().__mdastNode = mdastNode | ||
} | ||
|
||
decorate( | ||
parentEditor: LexicalEditor, | ||
{ | ||
theme: { | ||
nodeDecoratorComponents: { LeafDirectiveEditor } | ||
} | ||
}: ExtendedEditorConfig | ||
): JSX.Element { | ||
return <LeafDirectiveEditor leafDirective={this} mdastNode={this.getMdastNode()} parentEditor={parentEditor} /> | ||
} | ||
|
||
isInline(): boolean { | ||
return false | ||
} | ||
|
||
isKeyboardSelectable(): boolean { | ||
return true | ||
} | ||
} | ||
|
||
/** | ||
* Creates an {@link LeafDirectiveNode}. | ||
*/ | ||
export function $createLeafDirectiveNode(mdastNode: LeafDirective): LeafDirectiveNode { | ||
return new LeafDirectiveNode(mdastNode) | ||
} | ||
|
||
/** | ||
* Retruns true if the node is an {@link LeafDirectiveNode}. | ||
*/ | ||
export function $isLeafDirectiveNode(node: LexicalNode | null | undefined): node is LeafDirectiveNode { | ||
return node instanceof LeafDirectiveNode | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' | ||
import { $createParagraphNode, $insertNodes } from 'lexical' | ||
import { LeafDirective } from 'mdast-util-directive' | ||
import React from 'react' | ||
import { $createLeafDirectiveNode, MDXEditor, ToolbarComponents } from '../' | ||
|
||
const { | ||
BoldItalicUnderlineButtons, | ||
ToolbarSeparator, | ||
CodeFormattingButton, | ||
ListButtons, | ||
BlockTypeSelect, | ||
LinkButton, | ||
ImageButton, | ||
TableButton, | ||
HorizontalRuleButton, | ||
FrontmatterButton, | ||
CodeBlockButton, | ||
SandpackButton, | ||
DialogButton | ||
} = ToolbarComponents | ||
|
||
const YouTubeButton = () => { | ||
const [editor] = useLexicalComposerContext() | ||
return ( | ||
<DialogButton | ||
tooltipTitle="Insert Youtube video" | ||
submitButtonTitle="Insert video" | ||
dialogInputPlaceholder="Paste the youtube video URL" | ||
buttonContent="YT" | ||
onSubmit={(url) => { | ||
const videoId = new URL(url).searchParams.get('v') | ||
if (videoId) { | ||
editor.update(() => { | ||
const youtubeDirectiveMdastNode: LeafDirective = { | ||
type: 'leafDirective', | ||
name: 'youtube', | ||
attributes: { id: videoId }, | ||
children: [] | ||
} | ||
const lexicalNode = $createLeafDirectiveNode(youtubeDirectiveMdastNode) | ||
$insertNodes([lexicalNode]) | ||
|
||
if (lexicalNode.getParent()?.getLastChild() == lexicalNode) { | ||
lexicalNode.getParent()?.append($createParagraphNode()) | ||
} | ||
}) | ||
} else { | ||
alert('Invalid YouTube URL') | ||
} | ||
}} | ||
/> | ||
) | ||
} | ||
|
||
const toolbarComponents = [ | ||
BoldItalicUnderlineButtons, | ||
ToolbarSeparator, | ||
|
||
CodeFormattingButton, | ||
ToolbarSeparator, | ||
|
||
ListButtons, | ||
ToolbarSeparator, | ||
BlockTypeSelect, | ||
ToolbarSeparator, | ||
LinkButton, | ||
ImageButton, | ||
TableButton, | ||
HorizontalRuleButton, | ||
FrontmatterButton, | ||
|
||
ToolbarSeparator, | ||
|
||
CodeBlockButton, | ||
SandpackButton, | ||
ToolbarSeparator, | ||
YouTubeButton | ||
] | ||
|
||
export function Hello() { | ||
return ( | ||
<MDXEditor | ||
toolbarComponents={toolbarComponents} | ||
markdown={` | ||
This should be an youtube video: | ||
::youtube{#A5lXAKrttBU} | ||
::callout[there is some *markdown* in here] | ||
`} | ||
/> | ||
) | ||
} |
Oops, something went wrong.