Skip to content

Conversation

@eersnington
Copy link

Video Demo
https://github.com/user-attachments/assets/e81dd0a5-5ccf-4a14-ac9e-4cbc1da897a2

Hey, I was inspired by the Wrap and Collapsible buttons from Grok and T3 chat, and saw that the AI-elements version doesn't have them. So I went ahead and created a Wrap button and Collapse button that are composable, SSR-safe (doesn't flash on hydration).

  • CodeBlockCollapsibleButton: this shows only the first N lines of a long snippet, then expand/collapse it. This makes tall blocks easier to scan.
  • CodeBlockWrapButton: toggle long-line wrapping on and off, so horizontal scrolling is optional and user-driven.

Usage
image

Notes:
I've had to make some decisions on how the Collapsible prop is handled and create a new context too. This section is to layout my reasonings for why I've made them. Please do grill me if you think there're better ways to do it.

  • I made "Collapsible" as a prop on the main CodeBlock component and not for the Collapsible component: The initial collapsed/expanded state is decided at render time by the root, not by a child effect. That removes hydration flashes and avoids coupling the feature to a specific child being mounted.
  • I created two separate contexts, one for code and one for the UI state: The code string lives in a “code-only” context, and UI state (wrap/collapse) lives in a separate “UI” context. This makes is it so that toggling wrap/collapse doesn’t rerender children that only need the code (like the copy button). Large snippets of code are snappy.
  • The code value, the UI context value, and the collapsed “display code” are memoized (the code wasn't memoized before). This prevents unnecessary renders when flipping UI state and keeps interactions responsive even with big code blocks.

@vercel
Copy link
Contributor

vercel bot commented Oct 17, 2025

@eersnington is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

@haydenbleasel
Copy link
Member

@eersnington awesome work on this PR. unfortunately it's clashed with the previously merged #149 but ill see if we can rework and re-add it in another PR 👍

@eersnington
Copy link
Author

@eersnington awesome work on this PR. unfortunately it's clashed with the previously merged #149 but ill see if we can rework and re-add it in another PR 👍

no worries mate, the shiki rewrite was more important 🫡

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants