CodeBlock Component Showcase
- February 2, 2026
- February 3, 2026
Testing and showcasing all CodeBlock component configurations including bash/shell and markdown support
CodeBlock Component Showcase
Testing all possible CodeBlock configurations with the new filename and icon features.
Copy Button Hover Behavior
One of the most nuanced interactions I've implemented is the copy button's visibility logic. The goal was to create behavior that feels natural and provides clear feedback without being distracting or confusing.
The Requirements:
1. The copy button should only appear when hovering over a code block (reduces visual clutter)
2. When clicked, the button transforms into a checkmark to confirm the copy succeeded
3. The checkmark must remain visible even if you move your cursor away from the code block (otherwise the user never sees the confirmation)
4. After ~2 seconds, the checkmark transitions back to the copy button icon
5. Here's the tricky part: if your cursor is still on the code block when it transitions back, the copy button should remain visible. But if your cursor moved away, the copy button should immediately disappear without any flash or brief visibility.
The Technical Challenge:
CSS transitions create a problem here. When the button switches from checkmark back to copy icon, it needs different visibility behavior depending on hover state:
- If hovering: opacity should be 1 (visible)
- If not hovering: opacity should instantly snap to 0, with no transition
The issue is that a transition on opacity means there's a brief moment where the copy button fades out, creating a flash of visibility even when you're not hovering.
The Solution:
I used a combination of data attributes and conditional CSS transitions. The button has adata-copied attribute that tracks whether it's showing the checkmark or copy icon. Whendata-copied="false" (transitioning back to copy icon), I apply transition: none which makes the opacity change instant rather than animated. This means:
- Checkmark always fades in/out smoothly (better UX)
- Copy button appears smoothly when you hover (good)
- Copy button instantly disappears when switching from checkmark if not hovering (exactly what we want)
- Copy button stays visible if you're hovering during the transition (also exactly what we want)
Additionally, I render both SVG icons simultaneously with crossfading opacity transitions. This eliminates the jarring flash that happens when you conditionally render one or the other.
The result is an interaction that feels completely natural - the copy button never flashing briefly, and the checkmark confirmation is always visible long enough to register.
Transition Timing Details
Getting the timing right was critical for the feel of the interaction. The copy button uses:
Base transition: transition: opacity 0.25s ease 0.15s
This means when you hover over the code block, the button waits 0.15 seconds (delay) before starting to fade in, then takes 0.25 seconds to complete the fade. Total time from hover to fully visible: 0.4 seconds.
The instant-hide logic: &:not(:hover) button[data-copied="false"]
When the code block is NOT being hovered AND the button is in copy mode (not checkmark mode), we apply transition: none. This selector is key - it only matches when both conditions are true, which means:
- During hover: button fades in smoothly (base transition applies)
- During checkmark display: checkmark stays visible (data-copied="true", so this rule doesn't match)
- After checkmark → copy transition while not hovering: button instantly disappears (transition: none applies)
- After checkmark → copy transition while hovering: button stays visible (still hovering, so rule doesn't match)
The 0.15s delay prevents the button from flashing briefly as your cursor sweeps across the page. You have to intentionally hover on the code block for a moment before the button appears, which feels more deliberate and less distracting.
TypeScript Files
interface User {
id: string;
name: string;
email: string;
}
function getUser(id: string): User {
return { id, name: 'John', email: 'john@example.com' };
}TSX/React Files
export function Button({ children, onClick }: ButtonProps) {
return (
<button onClick={onClick} className="btn">
{children}
</button>
);
}JavaScript Files
function formatDate(date) {
return new Intl.DateTimeFormat('en-US').format(date);
}
module.exports = { formatDate };JSX Files
export function Card({ title, content }) {
return (
<div className="card">
<h3>{title}</h3>
<p>{content}</p>
</div>
);
}CSS Files
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.btn {
background: #007bff;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
}HTML Files
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example Page</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>Markdown Files
# Project Title
A brief description of the project.
## Features
- **Feature 1**: Does something amazing
- **Feature 2**: Does something else
- Feature 3
## Installation
```bash
npm install my-package
```
## Usage
Here's how to use it:
```typescript
import { MyComponent } from 'my-package';
const app = <MyComponent />;
```
## Links
- [Documentation](https://example.com/docs)
- [GitHub](https://github.com/example/repo)
> **Note:** This is an important callout.
---
Made with ❤️ by the teamUsing language="md":
# Contributing Guidelines
Thank you for contributing!
## Pull Request Process
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing`)
5. Open a Pull Request
### Code Style
- Use TypeScript
- Follow ESLint rules
- Write tests for new features
**Important:** All PRs must pass CI checks.Bash/Shell Scripts
Using language="bash":
#!/bin/bash
# Deploy script
echo "Starting deployment..."
npm install
npm run build
if [ $? -eq 0 ]; then
echo "Build successful!"
npm start
else
echo "Build failed!"
exit 1
fiUsing language="shell":
# Common shell commands
git add .
git commit -m "feat: add new feature"
git push origin main
# Environment setup
export NODE_ENV=production
export PORT=3000Using language="sh":
#!/bin/sh
# Minimal POSIX shell script
cd /usr/local/bin
ln -s /opt/app/cli ./app
chmod +x ./appWithout Filename (Language Fallback)
// No filename prop, should show "typescript"
const greeting: string = 'Hello, World!';
console.log(greeting);Without Header
// Header hidden completely
const result = 42;Edge Cases
No language specified (plain text):
Plain text code block
Should show "text" in headerUnknown file extension:
Text file with no icon
Should show filename without iconLong bash command (word wrapping test):
# Really long commands
docker run -d --name my-container --restart unless-stopped -p 8080:8080 -v /host/path:/container/path -e DATABASE_URL=postgresql://user:password@localhost:5432/dbname my-image:latest
# Piped commands
cat /var/log/syslog | grep -i error | awk '{print $1, $2, $3}' | sort | uniq -c | sort -rn | head -20