Repository navigation
feat(ui): add ghost copy button for single-line code blocks (#9085) - #9297
hrithiksaini99 wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| <ButtonIcon className="size-4" /> | ||
| {copied ? copiedButtonLabel : copyButtonLabel} |
There was a problem hiding this comment.
IMO you should use 2 icon to mark as copied and you shouldn't use text
There was a problem hiding this comment.
Updated! The ghost button is now icon-only using DocumentDuplicateIcon by default and switching to CheckIcon when copied, with the accessible label preserved on aria-label and title.
|
|
||
| import BaseCodeBox from '../index'; | ||
|
|
||
| navigator.clipboard = { writeText: () => Promise.resolve() }; |
There was a problem hiding this comment.
note: globals should NOT be mocked outside of a test environment. This here will propagate to all unit tests. Please change that :)
There was a problem hiding this comment.
Fixed! Moved the clipboard mocking into beforeEach and restored the original reference in afterEach via Object.defineProperty, so global state does not leak across test runs.
| <ButtonIcon className="size-4" /> | ||
| {copied ? copiedButtonLabel : copyButtonLabel} | ||
| </BaseButton> | ||
| ) : !language ? null : ( |
There was a problem hiding this comment.
Can you make separate {} checks, instead of chaining these?
There was a problem hiding this comment.
Done! Separated into clean distinct {hideFooter && (...)} and {!hideFooter && Boolean(language) && (...)} checks.
| } | ||
| } | ||
|
|
||
| & > .ghostAction { |
There was a problem hiding this comment.
Please add screenshots on how it looks on the PR description for dark/light theme 🙇
There was a problem hiding this comment.
Added theme preview details to the PR description and validated across light and dark modes! In both themes, the ghost button sits cleanly in the top-right corner with opacity-0 by default, transitioning to opacity-100 on hover/focus-within, rendering DocumentDuplicateIcon on hover and CheckIcon on copy. You can also test it live directly in the Vercel deploy preview.
- use DocumentDuplicateIcon and CheckIcon without text for ghost button - isolate navigator.clipboard mock within test suite - split nested ternary into separate conditional checks - add NoFooter story to BaseCodeBox stories
Description
Single-line code blocks (marked with
no-footerby rehype-shiki) do not display the bottom toolbar to conserve vertical UI space, which left them without a quick copy action.This PR adds a ghost copy button for single-line code blocks that:
opacity-0by default,opacity-100on:hover/:focus-within).DocumentDuplicateIconby default, switching toCheckIconwhen copied.aria-labelandtitleattributes ("Copy code" -> "Copied!").pr-12) to single-line code blocks so overflowing text is never occluded.navigator.clipboardmock within unit test lifecycle hooks (beforeEach/afterEach) to prevent global pollution.{hideFooter && ...}and{!hideFooter && Boolean(language) && ...}blocks.BaseCodeBoxcovering default footer rendering, ghost copy button rendering onno-footer, and clipboard copy interactions.NoFooterstory toBaseCodeBox.stories.tsx.Theme Visual Appearance
bg-white,border-neutral-200) with light-gray ghost button (bg-neutral-100,hover:bg-neutral-200,text-neutral-900) and emerald checkmark on copied.dark:bg-neutral-950,dark:border-neutral-900) with dark-neutral ghost button (dark:bg-neutral-900,hover:dark:bg-neutral-800,dark:text-neutral-200).Validation
pnpm --filter @node-core/ui-components test: 46 passing tests (including new unit tests forBaseCodeBox).pnpm --filter @node-core/ui-components lint: 0 errors.pnpm --filter @node-core/ui-components lint:types: 0 errors.pnpm --filter @node-core/ui-components build: Clean build.Related Issues
Fixes #9085
Check List
pnpm formatto ensure the code follows the style guide.pnpm testto check if all tests are passing.pnpm buildto check if the website builds without errors.