I wanted to take a quick stab at my own LLM chat interface, see how far I could get and how many little details I could squeeze in.
How about that cool new Codepen 2.0 editor?
I kept the demo minimal, no libraries, no frameworks, no build tools; just brick by brick, line by line, articulated details I wanted. Start with some core primitives, then start solving UX problems until the experience is good. There's still a lot more to do! The basic light/dark theme turned out pretty cool tho.
I used a real streaming LLM API, then used View Transitions and Scroll Driven Animations where applicable. I also wanted to learn ReadableStreams and have my own expression of how the UI could work.
The morph #
On submit, the textarea is given a view transition name with a unique incrementing index, then view transition is called and the same name is given to the new message element that's appended into the chat container.
This creates the morph effect since the old state is the textarea and the new state is the message bubble.
The shine #
The border shine effect animation draws the eye from the placeholder text to the submit button, while creating a nice sleek design aesthetic.
I used my own technique for it that was wayyy smaller than similar techniques done in popular libraries. The border radius makes the effect tricky to implement, but I've got a handy dandy notebook entry that's got all this laid out for me.
form {
border: 2px solid #0000;
border-radius: 20px;
background:
linear-gradient(var(--bg) 0 0) padding-box,
linear-gradient(130deg,
var(--bg) 45%,
color-mix(in srgb, Canvas, CanvasText 15%),
var(--bg) 55%
) border-box;
background-size: 300%;
animation: shine 6s infinite ease-in-out;
}
The trick is specifying which box on the node to paint into, like padding-box
or border-box
. While drawing a solid color over the middle / padding-box. Then as the background is animated, the 130deg shine gradient is shown only over the border-box.
There's also a neat little trick in there with color stop positions.
The cursor #
I thought the blinking cursor was cool. It's a throwback to the 80s and also just feels right since the machine is typing back to you.
It's probably been done other places, but of all the little loader thingies I made, this one was the simplest and most effective. High five to iteration.
Plenty more #
There's over 100 little decisions in the code that total up to this experience, and I could make 100 more! But… this was only meant to be a short sprint and not something I'm maintaining or looking to make 1000% fantastic.
Thought it was pretty cool for 2 short bursts of work with kids crawling all over me.