[HN Gopher] Lexical - a web text editor framework that powers Fa...
___________________________________________________________________
Lexical - a web text editor framework that powers Facebook
Author : trueadm
Score : 147 points
Date : 2022-06-20 18:08 UTC (4 hours ago)
(HTM) web link (playground.lexical.dev)
(TXT) w3m dump (playground.lexical.dev)
| a-priori wrote:
| How does this compare to Draft.js, another rich text editor
| created by Facebook?
|
| https://draftjs.org/
| trueadm wrote:
| Check out this answer I used in a previous HN thread:
|
| https://news.ycombinator.com/item?id=31020205
| rsstack wrote:
| I'd love to use Lexical to replace what we're using today. I've
| been checking in on the repository every few weeks. However,
| there are many features that are still pending
| https://github.com/facebook/lexical/projects/1 . We need several
| of the features that are "V1.0" and we obviously need the
| stability of a 1.0 SemVer release :)
|
| Is there a general timeline goal for the V1.0 release?
| trueadm wrote:
| What features in particular are you missing? We haven't really
| discussed a deadline for 1.0, as we've been trying to take our
| time making sure each release is impactful and correct.
| tester756 wrote:
| That's really good
|
| How do people search for jobs that work in this problem domains -
| parsers / editors / compilers?
| trueadm wrote:
| For Meta, or in general? For Meta, there are plenty of teams
| that require some infra knowledge around these common concepts.
| It's been fairly straightforward to find a team as a front-end
| engineer that allows you to excel in these areas at Meta (once
| you're successful in the interview loops).
| barbinbrad wrote:
| We're trying to choose between Lexical and Slate at work. Do you
| have any code examples that would be similar to this?
|
| Example: https://www.slatejs.org/examples/richtext
|
| Code:
| https://github.com/ianstormtaylor/slate/blob/main/site/examp...
| jitl wrote:
| <sarcasm>If you are planning to build a Notion competitor, I
| recommend Slate</sarcasm>. Seriously though, if you need to
| support Android or CJK, you should understand Slate's
| limitations before you buy into it. I think ProseMirror is the
| best choice today because it has been around for a long time
| and has battle-tested MutationObserver logic. Lexical is worth
| considering depending on your risk appetite. It also uses
| MutationObserver and appears to approach Android correctly. I
| haven't read enough of the code to recommend it yet. In Slate,
| Android is a second-class citizen with an extremely bare-bones
| MutationObserver reconciler. The main codebase only uses
| beforeInput.preventDefault which doesn't work on Android.
| trueadm wrote:
| ProseMirror is a great choice. Lexical might offer you more
| mileage if you're working with React (especially React 18 and
| the new concurrency features) and are happy to invest into a
| project that is still pre 1.0.
| jamesfisher wrote:
| Why the sarcasm?
| jitl wrote:
| I work at Notion and recently rebuilt much of the editor
| core, and I don't think Slate is a good choice because it
| considers nice, simple code more important than CJK or
| Android support. Notion doesn't use Slate or any other
| editor framework. I just study a lot of editor core code.
| nicce wrote:
| I don't understand the Android argument - these are
| mainly meant for browsers right?
| jitl wrote:
| 1. Android also has a browser. It is an important
| platform with many users.
|
| 2. Building an editor is so complicated that most
| organizations want to do it only once. They build a web
| editor, and wrap it in a native app. The shell like file
| browser, sharing screens, etc are "native" but the editor
| surface is a webview. This is how Quip, Dropbox Paper,
| Google Docs, Notion, etc work. Even iOS worked this way
| initially for all editable styled text (per https://twitt
| er.com/kocienda/status/1400484473540513792?s=21...)
|
| 3. If you are going to bet the core competency of your
| business on a framework, it's important to understand the
| motivations and limitations of said framework.
| jamesfisher wrote:
| Thanks, I see. I'm using Slate for TigYog.app, and fairly
| happy with it, but neither CJK nor Android are important
| there.
|
| Btw I'd love to see any public posts about the
| architecture of the Notion editor!
| jitl wrote:
| Slate has a nice, approachable API from a React
| perspective. I think depending on your project it could
| be an okay trade off.
|
| I co-wrote a post about our editor internals after
| finishing up the recent re-work but we decided not to
| publish it to conserve our Competitive Advantage.
| barbinbrad wrote:
| Thanks for the advice!
| trueadm wrote:
| The Lexical playground is one giant kitchen-sink example all
| written in React. You could check out the code for it locally
| and `npm run start` and play around with removing/adding
| plugins. You can also check out some examples on Codesandbox:
| https://codesandbox.io/s/lexical-rich-text-example-5tncvy
| barbinbrad wrote:
| Thanks! Very helpful.
| latchkey wrote:
| It is interesting (and cool) that this uses Typescript over Flow.
| It seems like Flow is still being developed too.
|
| Just looking at the top level package.json [1], I wonder at which
| point you abstract all those copy/pasted targets into a script
| that takes an argument.
|
| [1]
| https://github.com/facebook/lexical/blob/main/package.json#L...
| _the_inflator wrote:
| Even FB engineers can learn a thing or two. ;)
|
| Good tip.
| latchkey wrote:
| Thanks! I guess the last 20 years of writing code were not a
| waste after all. Heh. =)
| trueadm wrote:
| I'm the author of Lexical and one of the many engineers working
| on Lexical full-time at Meta. If you'd like to know anything, or
| ask any questions, please do!
|
| For those of you looking for the sourcecode for the playground,
| you can find it here:
|
| https://github.com/facebook/lexical/tree/main/packages/lexic...
|
| We also have a Discord channel you can check out:
|
| https://discord.gg/KmG4wQnnD9
| jjuliano wrote:
| Hi, I did (or somewhat invented/devised) a similar concept, but
| for visually programming UI design. See:
| https://jjuliano.github.io/markdown-ui/docs/container.html
| nehalem wrote:
| Thanks for the offer, let me take you up on this. Could you
| compare Lexical and Prosemirror from an architecture
| perspective? What motivated your decisions in that regard?
| trueadm wrote:
| Sure thing. I actually wrote up a really detailed response to
| this on ProseMirror's discussion board:
|
| https://discuss.prosemirror.net/t/differences-between-
| prosem...
|
| Ultimately though, there are many similarities between the
| two - intentionally so. We were inspired by ProseMirror and
| some of its APIs and approaches. I think the biggest
| underlying differences are in how we tackle things from a DX
| perspective. We tried to bring a more composable API to
| making text editors work - from the plugin patterns, how
| updates and reads work, to how you listen for changes and
| react to them. Much of this was inspired by my prior work
| working on the React core team and from creating Inferno.
| samwillis wrote:
| Interesting you say DX is a large aspect of what you are
| going for. ProseMirror is awesome but the API can be
| somewhat complex for simple things (but at the same time
| incredibly powerful when you get to understand it). I
| absolutely love TipTap[0] which is providing a much more
| user friendly API on top of ProseMirror, along with a clean
| Plugin system.
|
| Going to have to have a play with Lexical, excited to see
| Yjs support!
|
| [0]: http://tiptap.dev
| pixel_tracing wrote:
| Hey since you work at Meta can you find when code support /
| markdown will be added to text editing components?
|
| It's so frustrating posting code snippets to friends threads on
| FB
| trueadm wrote:
| Lexical supports code support / markdown. We actually use it
| a lot for Workplace, which is a kind of Facebook-like website
| for companies. It's really down to the product surfaces what
| features from Lexical they choose to use.
| jacobsimon wrote:
| Hey on my business's website we currently use draft.js for
| our user discussion product and we convert the user input
| to markdown for storing in our db. How hard would it be to
| switch to Lexical and does it support rendering from
| markdown syntax? Do you recommend any other approaches for
| safe storage and rendering of rich text? Thanks!
| trueadm wrote:
| Lexical has markdown support via `@lexical/markdown`. See
| https://lexical.dev/docs/api/lexical-markdown.
| acywatson wrote:
| I work at Meta on the Lexical team - yes, Lexical
| supports markdown and rendering from markdown syntax.
| Lexical isn't a drop-in replacement for Draft, but we're
| migrating all of our surfaces internally and it isn't
| particularly difficult, especially if you aren't storing
| in the DraftJS-specific format. As for alternatives, you
| can also consider storing it as JSON, which Lexical
| supports.
| hit8run wrote:
| How does it feel to work for one of the worst companies out
| there? Can you ignore it or does it bother you from time to
| time? Is it worth it?
| 8organicbits wrote:
| How is Facebook using this?
| trueadm wrote:
| It's used throughout Meta. The Post Composer, and Comment
| Composer on Facebook/Workplace, on Messenger, WhatsApp Web,
| Instagram Messenger, and many other surfaces too!
| pxeger1 wrote:
| In what sense does this "power" Facebook? Do you mean it's used
| for most or some specific text editing components of Facebook?
| trueadm wrote:
| It's replacing any previous web text editor UX components that
| we had in the past (likely DraftJS). We're also building
| Lexical for iOS which is slowly rolling out across iOS devices
| too.
| andrewshadura wrote:
| Well, I want the previous editor back. In fact, just give me
| a text area. The current editor breaks the selection and, in
| turn, the clipboard manager, it doesn't work well with
| Compose and dead keys, and it sometimes ties itself into a
| knot, and the text can't be edited anymore.
| danuker wrote:
| When pasting links stopped working for me is about when I
| stopped using Facebook.
|
| It's 2022 and we're reinventing every wheel, but in the
| browser.
|
| GitHub has a Markdown editor with a paste handler
| (converting tables and such). It once had a bug. I had to
| disable handlers in the browser to be able to paste.
| jitl wrote:
| How do you handle Android and multi-lingual input? Writing the
| state machine to deal with Chrome/Android's bananas selection
| bugs in Notion's editor gave me a lot of headaches. Do you add
| extra DOM nodes on Android? Any key insights that help deal with
| IME on Android?
| trueadm wrote:
| Android is indeed a headache to support. The biggest issue is
| how all keyboards force composition on all keystrokes, meaning
| you're constantly having to read the DOM input and work out
| what might have been entered. We don't use extra DOM nodes, but
| we do listen to `beforeinput`, `input` and use DOM
| MutationObserver to try and detect common Android patterns. I'd
| search this module for references to Android:
|
| https://github.com/facebook/lexical/blob/main/packages/lexic...
| pier25 wrote:
| It's currently a bit broken on Android.
|
| I select some text and then try to change the font size. The
| selection is lost when tapping on the font size menu.
|
| ProseMirror does keep the selection intact.
| jitl wrote:
| ANDROID!!!!!
| trueadm wrote:
| It's probably because we're using a native select element,
| which likes to steal selection on Android.
| jitl wrote:
| > event.timeStamp < lastKeyDownTimeStamp +
| ANDROID_COMPOSITION_LATENCY
|
| I tried so hard to avoid adding timeouts/timestamp logic for
| Android because it feels like a nondeterministic hack. In the
| end I gave up and did something similar.
|
| I also found beforeInput doesn't offer much solace on Android
| or with CJK language, because messing around with
| preventDefault or the DOM during composition disturbs the
| user.
|
| One weird thing I never figured out is that if the user puts
| the selection in an empty block, GBoard wants to jump to the
| nearest word in a different paragraph. We do some brutal
| hacks to get around that :-/
|
| I read your comment on ProseMirror forum about preventing
| interference from Granmarly, etc. Do you do this by reverting
| MutationRecords? Where is the code/docs for that?
| trueadm wrote:
| Yeah, I really wanted to avoid them too. There doesn't seem
| a good way. The issue you describe with selection jumping
| is a well known issue with GBoard. Here's the logic for the
| mutation handling:
|
| https://github.com/facebook/lexical/blob/main/packages/lexi
| c...
| jitl wrote:
| https://github.com/facebook/lexical/blob/5802651c24d88b2f
| 7d2...
|
| > // Check for any random auto-added <br> elements, and
| remove them.
|
| > // These get added by the browser when we undo the
| above mutations
|
| > // and this can lead to a broken UI.
|
| This made me laugh out loud. Browsers!
|
| Until here our approach looked quite similar. Leave the
| observer connected during reverts and avoiding double-
| peocessing using .takeRecords never occurred to me, I
| always disconnect it. Maybe some of these brs are causing
| chaos...
| trueadm wrote:
| Now thinking about it, I don't know why we didn't just do
| that. There must have been a reason, but I really can't
| recall what it was. If you're ever interested in
| contributing, this would be an epic contribution! :D
| canadiantim wrote:
| Does Lexical require react?
| thorncorona wrote:
| I realize this isn't probably your product surface but do you
| have any idea why FB messenger still has issues with double
| texting using the text box?
|
| Also, how do you guys design to reduce latency in Lexical? Esp
| considering the fluidity of modern chat clients ex. Telegram
| which are much more performant.
___________________________________________________________________
(page generated 2022-06-20 23:00 UTC)