I've been experimenting with a floating AI toolbar, designed for use in text
editors. When text is selected, an AI button will appear, which opens a dialog
for modifying your selection and generating new text. Try a demo of the UI
below.
When the height of a motion component changes, every element inside is
temporarily stretched into its new position. For example, this component will
animate and slightly distort when the contents of <p> grows taller.
This generally isn’t a problem, however when text is stretched during these
animations, it creates a poor reading experience. And because we’re generating
text word-by-word with AI, this will occur—try moving the sliders below to see
the effect.
To avoid this distortion, we can make the child a motion component, setting
its layout value to "position". This tells it to only animate its position,
not its size.
By doing this we can keep the animation without stretching the text—here’s what
it looks like.
This experience is preferable because the user is most likely reading this text
as it animates, watching a response being streamed in from AI. Without the
distortion it’s far easier to read.
I’ve set up AI generation using the
Vercel AI SDK. It’s very easy to get
started—once your Open AI API key is set up, we can create a server action named
continueConversation in Next.js, exactly like the following snippet.
Calling this action from the client, passing our prompt to content, will
return a stream of the results. Use the provided readStreamableValue function
with for await to read the result. You can see the expected console messages
below the snippet.
We can make this more useful by tracking every message received on the client,
and passing it back to the AI on every prompt. In this way the AI will have
memory of your previous prompts and its replies.
We can convert our AI setup into React code and place it inside a component,
creating an input to submit the user’s prompt, and returning the previous result
above it.
Tomatoes are a fruit despite their culinary usage.
I’m using Liveblocks Text Editor in my real application. The
editor is based on Lexical, and has
a number of features
such as real-time collaboration, comments, mentions, and notifications.
an exotic & nutriti
Natalie
fruit to your diet @Rachel then dragonfruit is|
Getting started is
simple, and because it’s a Lexical extension, you can extend your existing
editor with collaboration.
To integrate our AI solution into the text editor, we can modify our code
snippet from before, creating a button that submits a prompt to our queryAi
function. In this example we’re taking the currently selected text, asking the
AI to simplify it.
After the button’s been pressed, messages will update with the AI result.
However, we still haven’t added the message to the text editor yet. To do this,
we can create a button the replaces the current selection with the last result.
There’s still more work to be done, for example changing queryAi to add a
loading spinner, but you get the idea! Liveblocks Text Editor also enables a
number of other features out of the box, which are worth adding.
Being able to highlight text in your editor, and leave a comment, is a necessary
feature for modern editors. Liveblocks Text Editor allows you to do this—the
following snippet allows users to open a floating comment composer below their
highlighted text.
After the button has been pressed, a new thread and comment will be created,
which we can then render to the page. To do this, loop through each thread on
the page and pass it to a ready-made customisable component called
<Thread>.
Similarly, we can render a list of notifications using the
<InboxNotification>
component. Each notification is triggered when a user mentions you in a comment,
or when you’ve been mentioned inline in the editor.
Chris mentioned you in Untitled document
1h ago
How does this sound @Natalie?
Rachel invited you to My new document
2d ago
Accept
Decline
Rachel mentioned you in Untitled document
3d ago
You could try one of these alternatives?
You can also create fully custom notifications, and display those in your inbox
too, though we don’t need this now.
My final text editor will contain all the features listed above, and the source
will be open for anyone to use. Make sure to
follow me on Twitter if you’d like to try it!
I’ll be sharing it very soon.