-
-
Notifications
You must be signed in to change notification settings - Fork 137
Markdown editor with Rich Text preview via MDAST - with cleanup #2676
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Markdown editor with Rich Text preview via MDAST - with cleanup #2676
Conversation
…nsible MDAST transformer for lossless conversions
… migration, debug 1-click migration; adapt interpolator to text -> lexicalState only
…and divide with line breaks; efficient transformer search by mdastType rather than blind-search; fix: set the code theme for every CodeNode instead of just the direct descendants; fix: insert default values from formik; add support for new editor item edits; tweaks to styling
…sing; changes to styling
…ponse time; cleanup
…row on unrecognized markdown, let it pass
…ooltip fade, improve structure and apply BEM convention to CSS
…ment truncated text for SNInput; fix: trim empty nodes in a separate editor update
…eblocks language interpretation, fix block elements not being spread inside listItem, fix spacing inside nodes that can't contain paragraphs; MDAST: enforce actions as sole transformations interface, remove redundant footnote exts, add exts to the Lexical->Markdown pipeline
… full border radius on preview mode
…contents; re-implement show-full-text if url has an hash
|
alternative pattern using context: import dynamic from "next/dynamic"
import { createContext, useContext } from "react"
import { useRouter } from "next/router"
const HtmlContext = createContext("")
function HtmlFallback() {
const html = useContext(HtmlContext)
return <div dangerouslySetInnerHTML={{ __html: html }} />
}
const Reader = dynamic(() => import("./reader"), {
ssr: false,
loading: () => <HtmlFallback />,
})
export function SNReader({ html, ...props }) {
const router = useRouter()
// optional: avoid query flicker on first render in some cases
const showDebugHtml = router.isReady && router.query.html != null
if (showDebugHtml) {
return <div dangerouslySetInnerHTML={{ __html: html }} />
}
return (
<HtmlContext.Provider value={html}>
<Reader {...props} />
</HtmlContext.Provider>
)
} |
|
This fits perfectly, thank you! |
…e heading slug link if heading is itself a link
| case 'TERRITORY_BILLING': | ||
| case 'TERRITORY_UNARCHIVE': | ||
| if (!payIn.payerPrivates.sub) return <small className='text-muted d-flex justify-content-center w-100'>N/A</small> | ||
| if (!payIn.payerPrivates?.sub) return <small className='text-muted d-flex justify-content-center w-100'>N/A</small> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this ? was conflicting with the new changes
|
This PR can be merged without the previous one as QA is being done here, and new changes and fixes are being pushed here. If it's better to do the original PR and then the cleanup PR, I can |
Description
Based on #2657
This is the first stage of the transition to a new Lexical-based editor.
Introduces a Lexical plain text editor with a rich text preview, using MDAST to map and transform Lexical nodes to markdown, aiming to provide lossless transformations.
This PR focuses on providing the same editor experience as before, while transitioning to Lexical.
cleanup: Removes unused text input code and legacy markdown-related code.
Screenshots
Refreshed reply editor style, same background as comments
Refreshed top-level editor style
Editor workings
Informations can be found here:
lib/lexical/README.mdlib/lexical/exts/README.mdlib/lexical/server/README.md-> TODOcomponents/editor/README.md-> TODORemoved
LegacyText(ReactMarkdown) -> Text (SNReader)Mention-> UserMentionNodeSub-> TerritoryMentionNodeItem-> ItemMentionNodeFootnote-> Reference, Definition, Section, Backref nodesMediaLink-> MediaNodeTable-> TableNode (handled by lexical)CodeSkeletonCode-> CodeNode (handled by lexical with Shiki)PremarkToc-> handled by MDAST and LexicalremarkUnicode-> not needed under KaTeXremarkMath-> extracted mdast-util-mathrehypeSN-> feature parity achieved via MDAST visitors and transformsrehypeMathjax-> replaced with KaTeXrehypeSNStyled-> superseded by MDASTremarkGfm-> not neededBundle analysis
tmi: Lexical post-removals is 0.03 MB heavier than master on first load (what matters for the client). I was expecting a much higher first-load and overall bundle from Lexical, considering all the things it handles and can handle, but it's instead marginal.
Master
_app

Lexical pre-removals
_app

Lexical post-removals
_app

Feature parity
parity list
HistoryPlugin)LexicalReader)new features
meta+P)MDAST
Lexical already supports markdown transformations via
@lexical/markdown, the problem with Lexical's native approach is that we're forced to do workarounds for proper markdown bi-directional transformations.By treating the Lexical tree as an MDAST tree we can be confident in creating lossless bi-directional markdown transformations. More informations can be found in
lib/lexical/mdast/README.mdAdditional Context
lib/lexical/server/headless.jsCreating a fake DOM for Lexical operations server-side pollutes the global environment
It is safely cleaned at the end of an operation with the finally block, but it's still something we should keep an eye on.
CLEANUP
The following removals have been postponed:
useDualAutocompleteremove-markdownChecklist
Are your changes backward compatible? Please answer below:
For example, a change is not backward compatible if you removed a GraphQL field or dropped a database column.
On a scale of 1-10 how well and how have you QA'd this change and any features it might affect? Please answer below:
For frontend changes: Tested on mobile, light and dark mode? Please answer below:
Did you introduce any new environment variables? If so, call them out explicitly here:
Did you use AI for this? If so, how much did it assist you?
Note
Replaces legacy markdown pipeline with a Lexical-based editor/reader, adds SSR lexical processing and HTML generation, updates GraphQL schema/resolvers, and refactors UI to use the new system.
components/editor/*(Lexical editor/reader, toolbar, plugins: upload, mentions, preview, code theme, etc.).MarkdownInputwithSNInputacross forms and switches rendering toTextusingSNReader.styles/text.scss.item.lexicalState/item.htmland passreaderRef.ItemandSubtypes withlexicalStateandhtmlfields.lexicalStateLoader,lexicalHTMLGenerator); wires context in SSR Apollo and API.MediaOrLink, ToC, and tooltips; addsuse-callback-ref.canvas.Written by Cursor Bugbot for commit 4fac5bb. This will update automatically on new commits. Configure here.