feat(core): add renderCopyButton render prop to CodeBlock - #4795
Open
freddymeta wants to merge 1 commit into
Open
feat(core): add renderCopyButton render prop to CodeBlock#4795freddymeta wants to merge 1 commit into
freddymeta wants to merge 1 commit into
Conversation
CodeBlock's copy control was a bare, unstyleable <button> with no way to replace it — the component exposed only the root theme target, so consumers who needed a different copy control (e.g. one with a tooltip) had to disable hasCopyButton and re-implement placement, clipboard, and copied-state themselves. Add a renderCopyButton render prop: the block keeps ownership of placement (header, or floating corner when headerless), the clipboard write, the copied-state timer, and the polite copy announcement; the render prop only supplies the visual control, wired to copy/isCopied/label. Ignored when hasCopyButton is false.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
github-actions
Bot
requested review from
cvkxx,
ernestt,
kentonquatman and
rubyycheung
August 7, 2026 14:34
Contributor
PR Analysis Report📚 Storybook PreviewView Storybook for this PR 🧪 Sandbox PreviewView Sandbox for this PR Modified ComponentsCodeBlock (@astryxdesign/core) · View in Storybook
Bundle Size Summary
Accessibility AuditStatus: No accessibility violations detected. Generated by PR Enrichment workflow | Storybook | Sandbox | View full report |
rubyycheung
approved these changes
Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Adds a
renderCopyButtonrender prop toCodeBlock, letting a consumer supply its own copy control whileCodeBlockkeeps ownership of everything that isn't the button's appearance.Why
CodeBlock's copy control is a bare<button>with no tooltip, and there's no seam to restyle or replace it:hasCopyButtonis a plain boolean, and the component exposes a single theme target on the root<pre>. A design system consuming Astryx that wants its own copy control (e.g. its standard icon button with a "Copy" tooltip — a tooltip is DOM, so it can't be added via theming or CSS) is forced to sethasCopyButton={false}and then re-implement placement, the clipboard write, the copied-state timer, and the copy announcement, plus position the replacement with structural CSS against internal DOM. That's the "reach for an unsupported structural selector" signal that a sanctioned seam is missing.A paint/theme target is the wrong tier here (the need is a different control, not different paint on the same one), and an imperative
copy()ref was considered previously and set aside. A render prop is the right shape — it mirrors the existingrenderOption/renderItem/renderTokenconvention and hands back exactly the state a copy control needs.The seam
CodeBlockstill owns:onCopy.The render prop only supplies the visual control. Ignored when
hasCopyButtonisfalse.Scope
Additive and backward-compatible — the built-in button path is unchanged when
renderCopyButtonis omitted. No new theme target, no DOM change to existing usage.Tests
Extended
CodeBlock.test.tsxwith arenderCopyButtonblock: custom control replaces the built-in button,copy/isCopied/labeldrive the block's clipboard + copied flow, the announcement andonCopystill fire,hasCopyButton={false}suppresses it, and the custom control stays out of the collapsible header'srole="button".22/22CodeBlock tests, core typecheck, storybook typecheck, docsite (324), and strict lint all green. Added aCustomCopyButtonStorybook story.