Uh oh!
There was an error while loading. Please reload this page.
Feat/code blocks with copy - #303
Conversation
…for enhanced code copying functionality; update styles to prevent italic in Shiki code blocks
@Krish-Parekh is attempting to deploy a commit to the kmkoushik's projects Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThis pull request introduces copy-to-clipboard functionality for code blocks across the application. A new CodeBlockWithCopy React component is added to the UI package that wraps code blocks with a copy button. The CodeExample component in the marketing app is updated to use this new wrapper component. Additionally, global CSS styling is modified to prevent italic formatting in Shiki code blocks by applying a consistent font-style reset. Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/ui/src/code-block-with-copy.tsx (1)
3-7: Solid copy-to-clipboard implementation with a few optional refinementsThe component correctly encapsulates copy-to-clipboard behavior for arbitrary code blocks: props are well-typed,
navigator.clipboard.writeText(code)is safely wrapped in try/catch, and theButtonis positioned and labeled appropriately for basic accessibility. No blocking issues here.A couple of small, optional tweaks you might consider:
Avoid state updates after unmount / manage repeated clicks
Right now each click schedules a new
setTimeoutwithout cleanup. It’s very low risk given the 2s window, but you can make this more robust by tracking and clearing the timeout:-import * as React from "react";+import * as React from "react"; @@ - const [isCopied, setIsCopied] = React.useState(false);+ const [isCopied, setIsCopied] = React.useState(false);+ const resetTimeoutRef = React.useRef<number | null>(null); const copyToClipboard = async () => { try { - await navigator.clipboard.writeText(code);- setIsCopied(true);- setTimeout(() => setIsCopied(false), 2000);+ await navigator.clipboard.writeText(code);+ setIsCopied(true);++ if (resetTimeoutRef.current) {+ window.clearTimeout(resetTimeoutRef.current);+ }++ resetTimeoutRef.current = window.setTimeout(() => {+ setIsCopied(false);+ resetTimeoutRef.current = null;+ }, 2000); } catch (err) { console.error("Failed to copy: ", err); } }; ++ React.useEffect(+ () => () => {+ if (resetTimeoutRef.current) {+ window.clearTimeout(resetTimeoutRef.current);+ }+ },+ []+ );
Minor import cleanup
You can consolidate the lucide-react imports for tidiness:
-import { CheckIcon } from "lucide-react";+import { CheckIcon, Copy } from "lucide-react"; @@ -import { Copy } from "lucide-react";
Optional discoverability/accessibility tweak
Since the button is
opacity-0untilgroup-hover, users on touch-only devices may not see it. If that’s a concern, you could default toopacity-100on small screens and only use hover-based fade on larger breakpoints, or also force visibility onfocus-visibleso keyboard users get a clear affordance.Also applies to: 19-29, 31-50
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/marketing/src/components/CodeExample.tsx(2 hunks)packages/ui/src/code-block-with-copy.tsx(1 hunks)packages/ui/styles/globals.css(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{tsx,ts,jsx,js}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Include all required imports and ensure proper naming of key components in React/NextJS code
Files:
apps/marketing/src/components/CodeExample.tsxpackages/ui/src/code-block-with-copy.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Use TypeScript-first approach with 2-space indent and semicolons enabled by Prettier in apps/web (Next.js), apps/marketing, apps/smtp-server, and all packages
Never use dynamic imports; always import on the top level
Run ESLint via @usesend/eslint-config and ensure no warnings remain before submitting PRs
Files:
apps/marketing/src/components/CodeExample.tsxpackages/ui/src/code-block-with-copy.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
React components must use PascalCase naming convention (e.g., AppSideBar.tsx)
Files:
apps/marketing/src/components/CodeExample.tsxpackages/ui/src/code-block-with-copy.tsx
**/*.{ts,tsx,md}
📄 CodeRabbit inference engine (AGENTS.md)
Run Prettier 3 for code formatting on TypeScript, TSX, and Markdown files
Files:
apps/marketing/src/components/CodeExample.tsxpackages/ui/src/code-block-with-copy.tsx
🧠 Learnings (1)
📚 Learning: 2025-11-28T21:13:56.758Z
Learnt from: CR
Repo: usesend/useSend PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-28T21:13:56.758Z
Learning: Applies to **/*.{tsx,ts,jsx,js} : Include all required imports and ensure proper naming of key components in React/NextJS code
Applied to files:
apps/marketing/src/components/CodeExample.tsx
🧬 Code graph analysis (1)
packages/ui/src/code-block-with-copy.tsx (2)
packages/email-editor/src/renderer.tsx (1)
code(740-756)packages/ui/src/button.tsx (1)
Button(80-80)
🔇 Additional comments (2)
packages/ui/styles/globals.css (1)
142-146: Shiki font-style reset aligns with the intended typography changeThe global
.shiki, .shiki span { font-style: normal !important; }cleanly enforces non-italic code tokens across themes while letting the dark-mode block still control colors and other text styling. This matches the PR goal and doesn’t introduce obvious regressions.apps/marketing/src/components/CodeExample.tsx (1)
3-3: CodeBlockWithCopy integration in CodeExample looks correctThe new import and the
CodeBlockWithCopywrapper both line up with the component’s API:code={l.code}is a string, and the innerCodeBlockstill receives the samelangand children, so highlighting behavior is preserved while adding copy-to-clipboard. Naming and top-level import usage also follow the repo’s TSX/React guidelines.Also applies to: 153-160
Summary by cubic
Adds a reusable code block with a copy button and integrates it into the marketing CodeExample for one‑click code copying with clear feedback. Also removes unintended italics in Shiki-rendered code for consistent readability.
New Features
Bug Fixes
Written for commit 9d5b547. Summary will update automatically on new commits.
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.